crypto/qat: add KASUMI
This patch add kasumi support in Intel(R) QuickAssist driver. Signed-off-by: Deepak Kumar Jain <deepak.k.jain@intel.com> Acked-by: Fiona Trahe <fiona.trahe@intel.com>
This commit is contained in:
parent
e66917150e
commit
d4f2745300
@ -50,6 +50,7 @@ Cipher algorithms:
|
||||
* ``RTE_CRYPTO_CIPHER_SNOW3G_UEA2``
|
||||
* ``RTE_CRYPTO_CIPHER_AES_GCM``
|
||||
* ``RTE_CRYPTO_CIPHER_NULL``
|
||||
* ``RTE_CRYPTO_CIPHER_KASUMI_F8``
|
||||
|
||||
Hash algorithms:
|
||||
|
||||
@ -62,18 +63,19 @@ Hash algorithms:
|
||||
* ``RTE_CRYPTO_AUTH_SNOW3G_UIA2``
|
||||
* ``RTE_CRYPTO_AUTH_MD5_HMAC``
|
||||
* ``RTE_CRYPTO_AUTH_NULL``
|
||||
* ``RTE_CRYPTO_AUTH_KASUMI_F9``
|
||||
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
* Chained mbufs are not supported.
|
||||
* Hash only is not supported except Snow3G UIA2.
|
||||
* Cipher only is not supported except Snow3G UEA2.
|
||||
* Hash only is not supported except Snow3G UIA2 and KASUMI F9.
|
||||
* Cipher only is not supported except Snow3G UEA2 and KASUMI F8.
|
||||
* Only supports the session-oriented API implementation (session-less APIs are not supported).
|
||||
* Not performance tuned.
|
||||
* Snow3g(UEA2) supported only if cipher length, cipher offset fields are byte-aligned.
|
||||
* Snow3g(UIA2) supported only if hash length, hash offset fields are byte-aligned.
|
||||
* Snow3g(UEA2) and KASUMI(F8) supported only if cipher length, cipher offset fields are byte-aligned.
|
||||
* Snow3g(UIA2) and KASUMI(F9) supported only if hash length, hash offset fields are byte-aligned.
|
||||
* No BSD support as BSD QAT kernel driver not available.
|
||||
|
||||
|
||||
|
@ -71,6 +71,7 @@ New Features
|
||||
* MD5_HMAC algorithm
|
||||
* SHA224-HMAC algorithm
|
||||
* SHA384-HMAC algorithm
|
||||
* KASUMI (F8 and F9) algorithm
|
||||
* NULL algorithm
|
||||
|
||||
|
||||
|
@ -51,6 +51,14 @@
|
||||
#include "icp_qat_fw.h"
|
||||
#include "icp_qat_fw_la.h"
|
||||
|
||||
/*
|
||||
* Key Modifier (KM) value used in Kasumi algorithm in F9 mode to XOR
|
||||
* Integrity Key (IK)
|
||||
*/
|
||||
#define KASUMI_F9_KEY_MODIFIER_4_BYTES 0xAAAAAAAA
|
||||
|
||||
#define KASUMI_F8_KEY_MODIFIER_4_BYTES 0x55555555
|
||||
|
||||
#define QAT_AES_HW_CONFIG_CBC_ENC(alg) \
|
||||
ICP_QAT_HW_CIPHER_CONFIG_BUILD(ICP_QAT_HW_CIPHER_CBC_MODE, alg, \
|
||||
ICP_QAT_HW_CIPHER_NO_CONVERT, \
|
||||
@ -130,5 +138,5 @@ void qat_alg_ablkcipher_init_dec(struct qat_alg_ablkcipher_cd *cd,
|
||||
|
||||
int qat_alg_validate_aes_key(int key_len, enum icp_qat_hw_cipher_algo *alg);
|
||||
int qat_alg_validate_snow3g_key(int key_len, enum icp_qat_hw_cipher_algo *alg);
|
||||
|
||||
int qat_alg_validate_kasumi_key(int key_len, enum icp_qat_hw_cipher_algo *alg);
|
||||
#endif
|
||||
|
@ -96,6 +96,9 @@ static int qat_hash_get_state1_size(enum icp_qat_hw_auth_algo qat_hash_alg)
|
||||
case ICP_QAT_HW_AUTH_ALGO_MD5:
|
||||
return QAT_HW_ROUND_UP(ICP_QAT_HW_MD5_STATE1_SZ,
|
||||
QAT_HW_DEFAULT_ALIGNMENT);
|
||||
case ICP_QAT_HW_AUTH_ALGO_KASUMI_F9:
|
||||
return QAT_HW_ROUND_UP(ICP_QAT_HW_KASUMI_F9_STATE1_SZ,
|
||||
QAT_HW_DEFAULT_ALIGNMENT);
|
||||
case ICP_QAT_HW_AUTH_ALGO_DELIMITER:
|
||||
/* return maximum state1 size in this case */
|
||||
return QAT_HW_ROUND_UP(ICP_QAT_HW_SHA512_STATE1_SZ,
|
||||
@ -453,7 +456,8 @@ int qat_alg_aead_session_create_content_desc_cipher(struct qat_session *cdesc,
|
||||
uint32_t total_key_size;
|
||||
uint16_t proto = ICP_QAT_FW_LA_NO_PROTO; /* no CCM/GCM/Snow3G */
|
||||
uint16_t cipher_offset, cd_size;
|
||||
|
||||
uint32_t wordIndex = 0;
|
||||
uint32_t *temp_key = NULL;
|
||||
PMD_INIT_FUNC_TRACE();
|
||||
|
||||
if (cdesc->qat_cmd == ICP_QAT_FW_LA_CMD_CIPHER) {
|
||||
@ -503,6 +507,11 @@ int qat_alg_aead_session_create_content_desc_cipher(struct qat_session *cdesc,
|
||||
cipher_cd_ctrl->cipher_state_sz =
|
||||
ICP_QAT_HW_SNOW_3G_UEA2_IV_SZ >> 3;
|
||||
proto = ICP_QAT_FW_LA_SNOW_3G_PROTO;
|
||||
} else if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_KASUMI) {
|
||||
total_key_size = ICP_QAT_HW_KASUMI_F8_KEY_SZ;
|
||||
cipher_cd_ctrl->cipher_state_sz = ICP_QAT_HW_KASUMI_BLK_SZ >> 3;
|
||||
cipher_cd_ctrl->cipher_padding_sz =
|
||||
(2 * ICP_QAT_HW_KASUMI_BLK_SZ) >> 3;
|
||||
} else {
|
||||
total_key_size = cipherkeylen;
|
||||
cipher_cd_ctrl->cipher_state_sz = ICP_QAT_HW_AES_BLK_SZ >> 3;
|
||||
@ -520,9 +529,27 @@ int qat_alg_aead_session_create_content_desc_cipher(struct qat_session *cdesc,
|
||||
ICP_QAT_HW_CIPHER_CONFIG_BUILD(cdesc->qat_mode,
|
||||
cdesc->qat_cipher_alg, key_convert,
|
||||
cdesc->qat_dir);
|
||||
memcpy(cipher->aes.key, cipherkey, cipherkeylen);
|
||||
cdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_cipher_config) +
|
||||
cipherkeylen;
|
||||
|
||||
if (cdesc->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_KASUMI) {
|
||||
temp_key = (uint32_t *)(cdesc->cd_cur_ptr +
|
||||
sizeof(struct icp_qat_hw_cipher_config)
|
||||
+ cipherkeylen);
|
||||
memcpy(cipher->aes.key, cipherkey, cipherkeylen);
|
||||
memcpy(temp_key, cipherkey, cipherkeylen);
|
||||
|
||||
/* XOR Key with KASUMI F8 key modifier at 4 bytes level */
|
||||
for (wordIndex = 0; wordIndex < (cipherkeylen >> 2);
|
||||
wordIndex++)
|
||||
temp_key[wordIndex] ^= KASUMI_F8_KEY_MODIFIER_4_BYTES;
|
||||
|
||||
cdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_cipher_config) +
|
||||
cipherkeylen + cipherkeylen;
|
||||
} else {
|
||||
memcpy(cipher->aes.key, cipherkey, cipherkeylen);
|
||||
cdesc->cd_cur_ptr += sizeof(struct icp_qat_hw_cipher_config) +
|
||||
cipherkeylen;
|
||||
}
|
||||
|
||||
if (total_key_size > cipherkeylen) {
|
||||
uint32_t padding_size = total_key_size-cipherkeylen;
|
||||
|
||||
@ -558,6 +585,8 @@ int qat_alg_aead_session_create_content_desc_auth(struct qat_session *cdesc,
|
||||
uint16_t state1_size = 0, state2_size = 0;
|
||||
uint16_t hash_offset, cd_size;
|
||||
uint32_t *aad_len = NULL;
|
||||
uint32_t wordIndex = 0;
|
||||
uint32_t *pTempKey;
|
||||
|
||||
PMD_INIT_FUNC_TRACE();
|
||||
|
||||
@ -604,7 +633,8 @@ int qat_alg_aead_session_create_content_desc_auth(struct qat_session *cdesc,
|
||||
ICP_QAT_HW_AUTH_CONFIG_BUILD(ICP_QAT_HW_AUTH_MODE1,
|
||||
cdesc->qat_hash_alg, digestsize);
|
||||
|
||||
if (cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_SNOW_3G_UIA2)
|
||||
if (cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_SNOW_3G_UIA2
|
||||
|| cdesc->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_KASUMI_F9)
|
||||
hash->auth_counter.counter = 0;
|
||||
else
|
||||
hash->auth_counter.counter = rte_bswap32(
|
||||
@ -721,6 +751,26 @@ int qat_alg_aead_session_create_content_desc_auth(struct qat_session *cdesc,
|
||||
break;
|
||||
case ICP_QAT_HW_AUTH_ALGO_NULL:
|
||||
break;
|
||||
case ICP_QAT_HW_AUTH_ALGO_KASUMI_F9:
|
||||
state1_size = qat_hash_get_state1_size(
|
||||
ICP_QAT_HW_AUTH_ALGO_KASUMI_F9);
|
||||
state2_size = ICP_QAT_HW_KASUMI_F9_STATE2_SZ;
|
||||
memset(cdesc->cd_cur_ptr, 0, state1_size + state2_size);
|
||||
pTempKey = (uint32_t *)(cdesc->cd_cur_ptr + state1_size
|
||||
+ authkeylen);
|
||||
/*
|
||||
* The Inner Hash Initial State2 block must contain IK
|
||||
* (Initialisation Key), followed by IK XOR-ed with KM
|
||||
* (Key Modifier): IK||(IK^KM).
|
||||
*/
|
||||
/* write the auth key */
|
||||
memcpy(cdesc->cd_cur_ptr + state1_size, authkey, authkeylen);
|
||||
/* initialise temp key with auth key */
|
||||
memcpy(pTempKey, authkey, authkeylen);
|
||||
/* XOR Key with KASUMI F9 key modifier at 4 bytes level */
|
||||
for (wordIndex = 0; wordIndex < (authkeylen >> 2); wordIndex++)
|
||||
pTempKey[wordIndex] ^= KASUMI_F9_KEY_MODIFIER_4_BYTES;
|
||||
break;
|
||||
default:
|
||||
PMD_DRV_LOG(ERR, "Invalid HASH alg %u", cdesc->qat_hash_alg);
|
||||
return -EFAULT;
|
||||
@ -832,3 +882,15 @@ int qat_alg_validate_snow3g_key(int key_len, enum icp_qat_hw_cipher_algo *alg)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int qat_alg_validate_kasumi_key(int key_len, enum icp_qat_hw_cipher_algo *alg)
|
||||
{
|
||||
switch (key_len) {
|
||||
case ICP_QAT_HW_KASUMI_KEY_SZ:
|
||||
*alg = ICP_QAT_HW_CIPHER_ALGO_KASUMI;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -386,6 +386,51 @@ static const struct rte_cryptodev_capabilities qat_pmd_capabilities[] = {
|
||||
}, },
|
||||
}, }
|
||||
},
|
||||
{ /* KASUMI (F8) */
|
||||
.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
|
||||
{.sym = {
|
||||
.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
|
||||
{.cipher = {
|
||||
.algo = RTE_CRYPTO_CIPHER_KASUMI_F8,
|
||||
.block_size = 8,
|
||||
.key_size = {
|
||||
.min = 16,
|
||||
.max = 16,
|
||||
.increment = 0
|
||||
},
|
||||
.iv_size = {
|
||||
.min = 8,
|
||||
.max = 8,
|
||||
.increment = 0
|
||||
}
|
||||
}, }
|
||||
}, }
|
||||
},
|
||||
{ /* KASUMI (F9) */
|
||||
.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
|
||||
{.sym = {
|
||||
.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
|
||||
{.auth = {
|
||||
.algo = RTE_CRYPTO_AUTH_KASUMI_F9,
|
||||
.block_size = 8,
|
||||
.key_size = {
|
||||
.min = 16,
|
||||
.max = 16,
|
||||
.increment = 0
|
||||
},
|
||||
.digest_size = {
|
||||
.min = 4,
|
||||
.max = 4,
|
||||
.increment = 0
|
||||
},
|
||||
.aad_size = {
|
||||
.min = 8,
|
||||
.max = 8,
|
||||
.increment = 0
|
||||
}
|
||||
}, }
|
||||
}, }
|
||||
},
|
||||
RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
|
||||
};
|
||||
|
||||
@ -511,11 +556,18 @@ qat_crypto_sym_configure_session_cipher(struct rte_cryptodev *dev,
|
||||
case RTE_CRYPTO_CIPHER_NULL:
|
||||
session->qat_mode = ICP_QAT_HW_CIPHER_ECB_MODE;
|
||||
break;
|
||||
case RTE_CRYPTO_CIPHER_KASUMI_F8:
|
||||
if (qat_alg_validate_kasumi_key(cipher_xform->key.length,
|
||||
&session->qat_cipher_alg) != 0) {
|
||||
PMD_DRV_LOG(ERR, "Invalid KASUMI cipher key size");
|
||||
goto error_out;
|
||||
}
|
||||
session->qat_mode = ICP_QAT_HW_CIPHER_F8_MODE;
|
||||
break;
|
||||
case RTE_CRYPTO_CIPHER_3DES_ECB:
|
||||
case RTE_CRYPTO_CIPHER_3DES_CBC:
|
||||
case RTE_CRYPTO_CIPHER_AES_ECB:
|
||||
case RTE_CRYPTO_CIPHER_AES_CCM:
|
||||
case RTE_CRYPTO_CIPHER_KASUMI_F8:
|
||||
PMD_DRV_LOG(ERR, "Crypto: Unsupported Cipher alg %u",
|
||||
cipher_xform->algo);
|
||||
goto error_out;
|
||||
@ -644,6 +696,9 @@ qat_crypto_sym_configure_session_auth(struct rte_cryptodev *dev,
|
||||
case RTE_CRYPTO_AUTH_NULL:
|
||||
session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_NULL;
|
||||
break;
|
||||
case RTE_CRYPTO_AUTH_KASUMI_F9:
|
||||
session->qat_hash_alg = ICP_QAT_HW_AUTH_ALGO_KASUMI_F9;
|
||||
break;
|
||||
case RTE_CRYPTO_AUTH_SHA1:
|
||||
case RTE_CRYPTO_AUTH_SHA256:
|
||||
case RTE_CRYPTO_AUTH_SHA512:
|
||||
@ -652,7 +707,6 @@ qat_crypto_sym_configure_session_auth(struct rte_cryptodev *dev,
|
||||
case RTE_CRYPTO_AUTH_MD5:
|
||||
case RTE_CRYPTO_AUTH_AES_CCM:
|
||||
case RTE_CRYPTO_AUTH_AES_GMAC:
|
||||
case RTE_CRYPTO_AUTH_KASUMI_F9:
|
||||
case RTE_CRYPTO_AUTH_AES_CMAC:
|
||||
case RTE_CRYPTO_AUTH_AES_CBC_MAC:
|
||||
case RTE_CRYPTO_AUTH_ZUC_EIA3:
|
||||
@ -856,11 +910,12 @@ qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t *out_msg)
|
||||
|
||||
cipher_param->cipher_length = op->sym->cipher.data.length;
|
||||
cipher_param->cipher_offset = op->sym->cipher.data.offset;
|
||||
if (ctx->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2) {
|
||||
if (ctx->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_SNOW_3G_UEA2 ||
|
||||
ctx->qat_cipher_alg == ICP_QAT_HW_CIPHER_ALGO_KASUMI) {
|
||||
if (unlikely((cipher_param->cipher_length % BYTE_LENGTH != 0) ||
|
||||
(cipher_param->cipher_offset
|
||||
% BYTE_LENGTH != 0))) {
|
||||
PMD_DRV_LOG(ERR, " For Snow3g, QAT PMD only "
|
||||
PMD_DRV_LOG(ERR, " For Snow3g/Kasumi, QAT PMD only "
|
||||
"supports byte aligned values");
|
||||
op->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
|
||||
return -EINVAL;
|
||||
@ -899,6 +954,22 @@ qat_write_hw_desc_entry(struct rte_crypto_op *op, uint8_t *out_msg)
|
||||
auth_param->auth_off >>= 3;
|
||||
auth_param->auth_len >>= 3;
|
||||
}
|
||||
if ((ctx->qat_cmd == ICP_QAT_FW_LA_CMD_HASH_CIPHER ||
|
||||
ctx->qat_cmd == ICP_QAT_FW_LA_CMD_CIPHER_HASH) &&
|
||||
ctx->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_KASUMI_F9) {
|
||||
auth_param->auth_len = (auth_param->auth_len >> 3)
|
||||
+ (auth_param->auth_off >> 3)
|
||||
+ (BYTE_LENGTH >> 3)
|
||||
- 8;
|
||||
auth_param->auth_off = 8;
|
||||
} else if (ctx->qat_cmd == ICP_QAT_FW_LA_CMD_AUTH
|
||||
&& ctx->qat_hash_alg ==
|
||||
ICP_QAT_HW_AUTH_ALGO_KASUMI_F9) {
|
||||
auth_param->auth_len = (auth_param->auth_len >> 3)
|
||||
+ (auth_param->auth_off >> 3)
|
||||
+ (BYTE_LENGTH >> 3);
|
||||
auth_param->auth_off = 0;
|
||||
}
|
||||
auth_param->u1.aad_adr = op->sym->auth.aad.phys_addr;
|
||||
|
||||
if (ctx->qat_hash_alg == ICP_QAT_HW_AUTH_ALGO_GALOIS_128 ||
|
||||
|
Loading…
Reference in New Issue
Block a user