crypto/aesni_mb: support AES CMAC

Added support for AES CMAC hash algorithm with 128-bit key,
which has been added in the v0.49 of the IPSec Multi-buffer lib.

Signed-off-by: Marko Kovacevic <marko.kovacevic@intel.com>
Acked-by: Pablo de Lara <pablo.de.lara.guarch@intel.com>
This commit is contained in:
Marko Kovacevic 2018-03-27 13:15:32 +01:00 committed by Pablo de Lara
parent dad3736481
commit 6491dbbece
8 changed files with 141 additions and 15 deletions

View File

@ -38,6 +38,7 @@ Hash algorithms:
* RTE_CRYPTO_HASH_SHA384_HMAC * RTE_CRYPTO_HASH_SHA384_HMAC
* RTE_CRYPTO_HASH_SHA512_HMAC * RTE_CRYPTO_HASH_SHA512_HMAC
* RTE_CRYPTO_HASH_AES_XCBC_HMAC * RTE_CRYPTO_HASH_AES_XCBC_HMAC
* RTE_CRYPTO_HASH_AES_CMAC
AEAD algorithms: AEAD algorithms:

View File

@ -37,6 +37,7 @@ SHA256 HMAC = Y
SHA384 HMAC = Y SHA384 HMAC = Y
SHA512 HMAC = Y SHA512 HMAC = Y
AES XCBC MAC = Y AES XCBC MAC = Y
AES CMAC (128) = Y
; ;
; Supported AEAD algorithms of the 'aesni_mb' crypto driver. ; Supported AEAD algorithms of the 'aesni_mb' crypto driver.

View File

@ -62,6 +62,7 @@ AES GMAC =
SNOW3G UIA2 = SNOW3G UIA2 =
KASUMI F9 = KASUMI F9 =
ZUC EIA3 = ZUC EIA3 =
AES CMAC(128) =
; ;
; Supported AEAD algorithms of a default crypto driver. ; Supported AEAD algorithms of a default crypto driver.

View File

@ -96,6 +96,12 @@ New Features
including session creation/deletion handling and translating virtio-crypto including session creation/deletion handling and translating virtio-crypto
request into DPDK crypto operations. A sample application is also introduced. request into DPDK crypto operations. A sample application is also introduced.
* **Updated AESNI MB PMD.**
The AESNI MB PMD has been updated with additional support for:
* AES-CMAC (128-bit key).
* **Added the Event Timer Adapter Library.** * **Added the Event Timer Adapter Library.**
The Event Timer Adapter Library extends the event-based model by introducing The Event Timer Adapter Library extends the event-based model by introducing

View File

@ -33,9 +33,12 @@ typedef void (*aes_keyexp_192_t)
(const void *key, void *enc_exp_keys, void *dec_exp_keys); (const void *key, void *enc_exp_keys, void *dec_exp_keys);
typedef void (*aes_keyexp_256_t) typedef void (*aes_keyexp_256_t)
(const void *key, void *enc_exp_keys, void *dec_exp_keys); (const void *key, void *enc_exp_keys, void *dec_exp_keys);
typedef void (*aes_xcbc_expand_key_t) typedef void (*aes_xcbc_expand_key_t)
(const void *key, void *exp_k1, void *k2, void *k3); (const void *key, void *exp_k1, void *k2, void *k3);
typedef void (*aes_cmac_sub_key_gen_t)
(const void *exp_key, void *k2, void *k3);
typedef void (*aes_cmac_keyexp_t)
(const void *key, void *keyexp);
/** Multi-buffer library function pointer table */ /** Multi-buffer library function pointer table */
struct aesni_mb_op_fns { struct aesni_mb_op_fns {
@ -77,9 +80,12 @@ struct aesni_mb_op_fns {
/**< AES192 key expansions */ /**< AES192 key expansions */
aes_keyexp_256_t aes256; aes_keyexp_256_t aes256;
/**< AES256 key expansions */ /**< AES256 key expansions */
aes_xcbc_expand_key_t aes_xcbc; aes_xcbc_expand_key_t aes_xcbc;
/**< AES XCBC key expansions */ /**< AES XCBC key epansions */
aes_cmac_sub_key_gen_t aes_cmac_subkey;
/**< AES CMAC subkey expansions */
aes_cmac_keyexp_t aes_cmac_expkey;
/**< AES CMAC key expansions */
} keyexp; } keyexp;
/**< Key expansion functions */ /**< Key expansion functions */
} aux; } aux;
@ -122,7 +128,9 @@ static const struct aesni_mb_op_fns job_ops[] = {
aes_keyexp_128_sse, aes_keyexp_128_sse,
aes_keyexp_192_sse, aes_keyexp_192_sse,
aes_keyexp_256_sse, aes_keyexp_256_sse,
aes_xcbc_expand_key_sse aes_xcbc_expand_key_sse,
aes_cmac_subkey_gen_sse,
aes_keyexp_128_enc_sse
} }
} }
}, },
@ -147,7 +155,9 @@ static const struct aesni_mb_op_fns job_ops[] = {
aes_keyexp_128_avx, aes_keyexp_128_avx,
aes_keyexp_192_avx, aes_keyexp_192_avx,
aes_keyexp_256_avx, aes_keyexp_256_avx,
aes_xcbc_expand_key_avx aes_xcbc_expand_key_avx,
aes_cmac_subkey_gen_avx,
aes_keyexp_128_enc_avx
} }
} }
}, },
@ -172,7 +182,9 @@ static const struct aesni_mb_op_fns job_ops[] = {
aes_keyexp_128_avx2, aes_keyexp_128_avx2,
aes_keyexp_192_avx2, aes_keyexp_192_avx2,
aes_keyexp_256_avx2, aes_keyexp_256_avx2,
aes_xcbc_expand_key_avx2 aes_xcbc_expand_key_avx2,
aes_cmac_subkey_gen_avx2,
aes_keyexp_128_enc_avx2
} }
} }
}, },
@ -197,7 +209,9 @@ static const struct aesni_mb_op_fns job_ops[] = {
aes_keyexp_128_avx512, aes_keyexp_128_avx512,
aes_keyexp_192_avx512, aes_keyexp_192_avx512,
aes_keyexp_256_avx512, aes_keyexp_256_avx512,
aes_xcbc_expand_key_avx512 aes_xcbc_expand_key_avx512,
aes_cmac_subkey_gen_avx512,
aes_keyexp_128_enc_avx512
} }
} }
} }

View File

@ -124,6 +124,17 @@ aesni_mb_set_session_auth_parameters(const struct aesni_mb_op_fns *mb_ops,
return 0; return 0;
} }
if (xform->auth.algo == RTE_CRYPTO_AUTH_AES_CMAC) {
sess->auth.algo = AES_CMAC;
(*mb_ops->aux.keyexp.aes_cmac_expkey)(xform->auth.key.data,
sess->auth.cmac.expkey);
(*mb_ops->aux.keyexp.aes_cmac_subkey)(sess->auth.cmac.expkey,
sess->auth.cmac.skey1, sess->auth.cmac.skey2);
return 0;
}
switch (xform->auth.algo) { switch (xform->auth.algo) {
case RTE_CRYPTO_AUTH_MD5_HMAC: case RTE_CRYPTO_AUTH_MD5_HMAC:
sess->auth.algo = MD5; sess->auth.algo = MD5;
@ -338,16 +349,19 @@ aesni_mb_set_session_parameters(const struct aesni_mb_op_fns *mb_ops,
sess->chain_order = HASH_CIPHER; sess->chain_order = HASH_CIPHER;
auth_xform = xform; auth_xform = xform;
cipher_xform = xform->next; cipher_xform = xform->next;
sess->auth.digest_len = xform->auth.digest_length;
break; break;
case AESNI_MB_OP_CIPHER_HASH: case AESNI_MB_OP_CIPHER_HASH:
sess->chain_order = CIPHER_HASH; sess->chain_order = CIPHER_HASH;
auth_xform = xform->next; auth_xform = xform->next;
cipher_xform = xform; cipher_xform = xform;
sess->auth.digest_len = xform->auth.digest_length;
break; break;
case AESNI_MB_OP_HASH_ONLY: case AESNI_MB_OP_HASH_ONLY:
sess->chain_order = HASH_CIPHER; sess->chain_order = HASH_CIPHER;
auth_xform = xform; auth_xform = xform;
cipher_xform = NULL; cipher_xform = NULL;
sess->auth.digest_len = xform->auth.digest_length;
break; break;
case AESNI_MB_OP_CIPHER_ONLY: case AESNI_MB_OP_CIPHER_ONLY:
/* /*
@ -366,13 +380,13 @@ aesni_mb_set_session_parameters(const struct aesni_mb_op_fns *mb_ops,
case AESNI_MB_OP_AEAD_CIPHER_HASH: case AESNI_MB_OP_AEAD_CIPHER_HASH:
sess->chain_order = CIPHER_HASH; sess->chain_order = CIPHER_HASH;
sess->aead.aad_len = xform->aead.aad_length; sess->aead.aad_len = xform->aead.aad_length;
sess->aead.digest_len = xform->aead.digest_length; sess->auth.digest_len = xform->aead.digest_length;
aead_xform = xform; aead_xform = xform;
break; break;
case AESNI_MB_OP_AEAD_HASH_CIPHER: case AESNI_MB_OP_AEAD_HASH_CIPHER:
sess->chain_order = HASH_CIPHER; sess->chain_order = HASH_CIPHER;
sess->aead.aad_len = xform->aead.aad_length; sess->aead.aad_len = xform->aead.aad_length;
sess->aead.digest_len = xform->aead.digest_length; sess->auth.digest_len = xform->aead.digest_length;
aead_xform = xform; aead_xform = xform;
break; break;
case AESNI_MB_OP_NOT_SUPPORTED: case AESNI_MB_OP_NOT_SUPPORTED:
@ -523,6 +537,11 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp,
} else if (job->hash_alg == AES_CCM) { } else if (job->hash_alg == AES_CCM) {
job->u.CCM.aad = op->sym->aead.aad.data + 18; job->u.CCM.aad = op->sym->aead.aad.data + 18;
job->u.CCM.aad_len_in_bytes = session->aead.aad_len; job->u.CCM.aad_len_in_bytes = session->aead.aad_len;
} else if (job->hash_alg == AES_CMAC) {
job->u.CMAC._key_expanded = session->auth.cmac.expkey;
job->u.CMAC._skey1 = session->auth.cmac.skey1;
job->u.CMAC._skey2 = session->auth.cmac.skey2;
} else { } else {
job->u.HMAC._hashed_auth_key_xor_ipad = session->auth.pads.inner; job->u.HMAC._hashed_auth_key_xor_ipad = session->auth.pads.inner;
job->u.HMAC._hashed_auth_key_xor_opad = session->auth.pads.outer; job->u.HMAC._hashed_auth_key_xor_opad = session->auth.pads.outer;
@ -568,11 +587,11 @@ set_mb_job_params(JOB_AES_HMAC *job, struct aesni_mb_qp *qp,
* Multi-buffer library current only support returning a truncated * Multi-buffer library current only support returning a truncated
* digest length as specified in the relevant IPsec RFCs * digest length as specified in the relevant IPsec RFCs
*/ */
if (job->hash_alg != AES_CCM) if (job->hash_alg != AES_CCM && job->hash_alg != AES_CMAC)
job->auth_tag_output_len_in_bytes = job->auth_tag_output_len_in_bytes =
get_truncated_digest_byte_length(job->hash_alg); get_truncated_digest_byte_length(job->hash_alg);
else else
job->auth_tag_output_len_in_bytes = session->aead.digest_len; job->auth_tag_output_len_in_bytes = session->auth.digest_len;
/* Set IV parameters */ /* Set IV parameters */

View File

@ -66,8 +66,9 @@ static const unsigned auth_truncated_digest_byte_lengths[] = {
[SHA_384] = 24, [SHA_384] = 24,
[SHA_512] = 32, [SHA_512] = 32,
[AES_XCBC] = 12, [AES_XCBC] = 12,
[AES_CMAC] = 16,
[AES_CCM] = 8, [AES_CCM] = 8,
[NULL_HASH] = 0 [NULL_HASH] = 0
}; };
/** /**
@ -91,7 +92,8 @@ static const unsigned auth_digest_byte_lengths[] = {
[SHA_384] = 48, [SHA_384] = 48,
[SHA_512] = 64, [SHA_512] = 64,
[AES_XCBC] = 16, [AES_XCBC] = 16,
[NULL_HASH] = 0 [AES_CMAC] = 16,
[NULL_HASH] = 0
}; };
/** /**
@ -211,14 +213,24 @@ struct aesni_mb_session {
uint8_t k3[16] __rte_aligned(16); uint8_t k3[16] __rte_aligned(16);
/**< k3. */ /**< k3. */
} xcbc; } xcbc;
struct {
uint32_t expkey[60] __rte_aligned(16);
/**< k1 (expanded key). */
uint32_t skey1[4] __rte_aligned(16);
/**< k2. */
uint32_t skey2[4] __rte_aligned(16);
/**< k3. */
} cmac;
/**< Expanded XCBC authentication keys */ /**< Expanded XCBC authentication keys */
}; };
/** digest size */
uint16_t digest_len;
} auth; } auth;
struct { struct {
/** AAD data length */ /** AAD data length */
uint16_t aad_len; uint16_t aad_len;
/** digest size */
uint16_t digest_len;
} aead; } aead;
} __rte_cache_aligned; } __rte_cache_aligned;

View File

@ -319,6 +319,54 @@ hmac_sha512_test_vector = {
} }
}; };
static const struct blockcipher_test_data
cmac_test_vector = {
.auth_algo = RTE_CRYPTO_AUTH_AES_CMAC,
.ciphertext = {
.data = plaintext_hash,
.len = 512
},
.auth_key = {
.data = {
0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
},
.len = 16
},
.digest = {
.data = {
0x4C, 0x77, 0x87, 0xA0, 0x78, 0x8E, 0xEA, 0x96,
0xC1, 0xEB, 0x1E, 0x4E, 0x95, 0x8F, 0xED, 0x27
},
.len = 16,
.truncated_len = 16
}
};
static const struct blockcipher_test_data
cmac_test_vector_12 = {
.auth_algo = RTE_CRYPTO_AUTH_AES_CMAC,
.ciphertext = {
.data = plaintext_hash,
.len = 512
},
.auth_key = {
.data = {
0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
},
.len = 16
},
.digest = {
.data = {
0x4C, 0x77, 0x87, 0xA0, 0x78, 0x8E, 0xEA, 0x96,
0xC1, 0xEB, 0x1E, 0x4E, 0x95, 0x8F, 0xED, 0x27
},
.len = 12,
.truncated_len = 12
}
};
static const struct blockcipher_test_case hash_test_cases[] = { static const struct blockcipher_test_case hash_test_cases[] = {
{ {
.test_descr = "MD5 Digest", .test_descr = "MD5 Digest",
@ -562,6 +610,30 @@ static const struct blockcipher_test_case hash_test_cases[] = {
BLOCKCIPHER_TEST_TARGET_PMD_QAT | BLOCKCIPHER_TEST_TARGET_PMD_QAT |
BLOCKCIPHER_TEST_TARGET_PMD_MRVL BLOCKCIPHER_TEST_TARGET_PMD_MRVL
}, },
{
.test_descr = "CMAC Digest 12B",
.test_data = &cmac_test_vector_12,
.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB
},
{
.test_descr = "CMAC Digest Verify 12B",
.test_data = &cmac_test_vector_12,
.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB
},
{
.test_descr = "CMAC Digest 16B",
.test_data = &cmac_test_vector,
.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB
},
{
.test_descr = "CMAC Digest Verify 16B",
.test_data = &cmac_test_vector,
.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB
}
}; };
#endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */ #endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */