crypto/aesni_mb: support AES CMAC
authorMarko Kovacevic <marko.kovacevic@intel.com>
Tue, 27 Mar 2018 12:15:32 +0000 (13:15 +0100)
committerPablo de Lara <pablo.de.lara.guarch@intel.com>
Mon, 23 Apr 2018 16:01:48 +0000 (17:01 +0100)
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>
doc/guides/cryptodevs/aesni_mb.rst
doc/guides/cryptodevs/features/aesni_mb.ini
doc/guides/cryptodevs/features/default.ini
doc/guides/rel_notes/release_18_05.rst
drivers/crypto/aesni_mb/aesni_mb_ops.h
drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c
drivers/crypto/aesni_mb/rte_aesni_mb_pmd_private.h
test/test/test_cryptodev_hash_test_vectors.h

index 1680c4a..236828c 100644 (file)
@@ -38,6 +38,7 @@ Hash algorithms:
 * RTE_CRYPTO_HASH_SHA384_HMAC
 * RTE_CRYPTO_HASH_SHA512_HMAC
 * RTE_CRYPTO_HASH_AES_XCBC_HMAC
+* RTE_CRYPTO_HASH_AES_CMAC
 
 AEAD algorithms:
 
index a5a45a6..1e263c2 100644 (file)
@@ -37,6 +37,7 @@ SHA256 HMAC  = Y
 SHA384 HMAC  = Y
 SHA512 HMAC  = Y
 AES XCBC MAC = Y
+AES CMAC (128)  = Y
 
 ;
 ; Supported AEAD algorithms of the 'aesni_mb' crypto driver.
index 728ce3b..243ac76 100644 (file)
@@ -62,6 +62,7 @@ AES GMAC     =
 SNOW3G UIA2  =
 KASUMI F9    =
 ZUC EIA3     =
+AES CMAC(128) =
 
 ;
 ; Supported AEAD algorithms of a default crypto driver.
index 290fa09..99a08a9 100644 (file)
@@ -96,6 +96,12 @@ New Features
   including session creation/deletion handling and translating virtio-crypto
   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.**
 
   The Event Timer Adapter Library extends the event-based model by introducing
index 56fd829..5a1cba6 100644 (file)
@@ -33,9 +33,12 @@ typedef void (*aes_keyexp_192_t)
                (const void *key, void *enc_exp_keys, void *dec_exp_keys);
 typedef void (*aes_keyexp_256_t)
                (const void *key, void *enc_exp_keys, void *dec_exp_keys);
-
 typedef void (*aes_xcbc_expand_key_t)
                (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 */
 struct aesni_mb_op_fns {
@@ -77,9 +80,12 @@ struct aesni_mb_op_fns {
                        /**< AES192 key expansions */
                        aes_keyexp_256_t aes256;
                        /**< AES256 key expansions */
-
                        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;
                /**< Key expansion functions */
        } aux;
@@ -122,7 +128,9 @@ static const struct aesni_mb_op_fns job_ops[] = {
                                        aes_keyexp_128_sse,
                                        aes_keyexp_192_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_192_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_192_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_192_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
                                }
                        }
                }
index 6f06ec4..2e50078 100644 (file)
@@ -124,6 +124,17 @@ aesni_mb_set_session_auth_parameters(const struct aesni_mb_op_fns *mb_ops,
                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) {
        case RTE_CRYPTO_AUTH_MD5_HMAC:
                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;
                auth_xform = xform;
                cipher_xform = xform->next;
+               sess->auth.digest_len = xform->auth.digest_length;
                break;
        case AESNI_MB_OP_CIPHER_HASH:
                sess->chain_order = CIPHER_HASH;
                auth_xform = xform->next;
                cipher_xform = xform;
+               sess->auth.digest_len = xform->auth.digest_length;
                break;
        case AESNI_MB_OP_HASH_ONLY:
                sess->chain_order = HASH_CIPHER;
                auth_xform = xform;
                cipher_xform = NULL;
+               sess->auth.digest_len = xform->auth.digest_length;
                break;
        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:
                sess->chain_order = CIPHER_HASH;
                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;
                break;
        case AESNI_MB_OP_AEAD_HASH_CIPHER:
                sess->chain_order = HASH_CIPHER;
                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;
                break;
        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) {
                job->u.CCM.aad = op->sym->aead.aad.data + 18;
                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 {
                job->u.HMAC._hashed_auth_key_xor_ipad = session->auth.pads.inner;
                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
         * 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 =
                                get_truncated_digest_byte_length(job->hash_alg);
        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 */
index 948e091..a33b2f6 100644 (file)
@@ -66,8 +66,9 @@ static const unsigned auth_truncated_digest_byte_lengths[] = {
                [SHA_384]       = 24,
                [SHA_512]       = 32,
                [AES_XCBC]      = 12,
+               [AES_CMAC]      = 16,
                [AES_CCM]       = 8,
-               [NULL_HASH]     = 0
+               [NULL_HASH]     = 0
 };
 
 /**
@@ -91,7 +92,8 @@ static const unsigned auth_digest_byte_lengths[] = {
                [SHA_384]       = 48,
                [SHA_512]       = 64,
                [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);
                            /**< k3. */
                        } 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 */
                };
+       /** digest size */
+       uint16_t digest_len;
+
        } auth;
        struct {
                /** AAD data length */
                uint16_t aad_len;
-               /** digest size */
-               uint16_t digest_len;
        } aead;
 } __rte_cache_aligned;
 
index df9202f..d4858ff 100644 (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[] = {
        {
                .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_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_ */