Add support to AES-CCM, for 128, 192 and 256-bit keys.

Signed-off-by: Pablo de Lara <pablo.de.lara.gua...@intel.com>
---
 doc/guides/cryptodevs/features/default.ini   |   3 +
 doc/guides/cryptodevs/features/openssl.ini   |   3 +
 doc/guides/cryptodevs/openssl.rst            |   1 +
 doc/guides/rel_notes/release_17_11.rst       |   6 +
 drivers/crypto/openssl/rte_openssl_pmd.c     | 178 ++++++++++++++++++++++++---
 drivers/crypto/openssl/rte_openssl_pmd_ops.c |  30 +++++
 lib/librte_cryptodev/rte_crypto_sym.h        |   9 +-
 test/test/test_cryptodev.c                   | 170 ++++++++++++++++++++-----
 test/test/test_cryptodev_aead_test_vectors.h | 136 ++++++++++++++++++++
 9 files changed, 482 insertions(+), 54 deletions(-)

diff --git a/doc/guides/cryptodevs/features/default.ini 
b/doc/guides/cryptodevs/features/default.ini
index 0926887..c98717a 100644
--- a/doc/guides/cryptodevs/features/default.ini
+++ b/doc/guides/cryptodevs/features/default.ini
@@ -68,3 +68,6 @@ ZUC EIA3     =
 AES GCM (128) =
 AES GCM (192) =
 AES GCM (256) =
+AES CCM (128) =
+AES CCM (192) =
+AES CCM (256) =
diff --git a/doc/guides/cryptodevs/features/openssl.ini 
b/doc/guides/cryptodevs/features/openssl.ini
index aeb2a50..385ec4e 100644
--- a/doc/guides/cryptodevs/features/openssl.ini
+++ b/doc/guides/cryptodevs/features/openssl.ini
@@ -45,3 +45,6 @@ AES GMAC     = Y
 AES GCM (128) = Y
 AES GCM (192) = Y
 AES GCM (256) = Y
+AES CCM (128) = Y
+AES CCM (192) = Y
+AES CCM (256) = Y
diff --git a/doc/guides/cryptodevs/openssl.rst 
b/doc/guides/cryptodevs/openssl.rst
index f18a456..243ea36 100644
--- a/doc/guides/cryptodevs/openssl.rst
+++ b/doc/guides/cryptodevs/openssl.rst
@@ -67,6 +67,7 @@ Supported authentication algorithms:
 
 Supported AEAD algorithms:
 * ``RTE_CRYPTO_AEAD_AES_GCM``
+* ``RTE_CRYPTO_AEAD_AES_CCM``
 
 
 Installation
diff --git a/doc/guides/rel_notes/release_17_11.rst 
b/doc/guides/rel_notes/release_17_11.rst
index 170f4f9..0d15046 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -41,6 +41,12 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
+* **Updated the OpenSSL PMD.**
+
+  The OpenSSL PMD has been updated with additional support for:
+
+  * AES-CCM algorithm.
+
 
 Resolved Issues
 ---------------
diff --git a/drivers/crypto/openssl/rte_openssl_pmd.c 
b/drivers/crypto/openssl/rte_openssl_pmd.c
index 780bf66..3119501 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd.c
@@ -267,6 +267,21 @@ get_aead_algo(enum rte_crypto_aead_algorithm sess_algo, 
size_t keylen,
                                res = -EINVAL;
                        }
                        break;
+               case RTE_CRYPTO_AEAD_AES_CCM:
+                       switch (keylen) {
+                       case 16:
+                               *algo = EVP_aes_128_ccm();
+                               break;
+                       case 24:
+                               *algo = EVP_aes_192_ccm();
+                               break;
+                       case 32:
+                               *algo = EVP_aes_256_ccm();
+                               break;
+                       default:
+                               res = -EINVAL;
+                       }
+                       break;
                default:
                        res = -EINVAL;
                        break;
@@ -285,6 +300,7 @@ openssl_set_sess_aead_enc_param(struct openssl_session 
*sess,
                uint8_t tag_len, uint8_t *key)
 {
        int iv_type = 0;
+       unsigned int do_ccm;
 
        sess->cipher.direction = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
        sess->auth.operation = RTE_CRYPTO_AUTH_OP_GENERATE;
@@ -295,6 +311,14 @@ openssl_set_sess_aead_enc_param(struct openssl_session 
*sess,
                iv_type = EVP_CTRL_GCM_SET_IVLEN;
                if (tag_len != 16)
                        return -EINVAL;
+               do_ccm = 0;
+               break;
+       case RTE_CRYPTO_AEAD_AES_CCM:
+               iv_type = EVP_CTRL_CCM_SET_IVLEN;
+               /* Digest size can be 4, 6, 8, 10, 12, 14 or 16 bytes */
+               if (tag_len < 4 || tag_len > 16 || (tag_len & 1) == 1)
+                       return -EINVAL;
+               do_ccm = 1;
                break;
        default:
                return -ENOTSUP;
@@ -319,6 +343,10 @@ openssl_set_sess_aead_enc_param(struct openssl_session 
*sess,
                        NULL) <= 0)
                return -EINVAL;
 
+       if (do_ccm)
+               EVP_CIPHER_CTX_ctrl(sess->cipher.ctx, EVP_CTRL_CCM_SET_TAG,
+                               tag_len, NULL);
+
        if (EVP_EncryptInit_ex(sess->cipher.ctx, NULL, NULL, key, NULL) <= 0)
                return -EINVAL;
 
@@ -332,6 +360,7 @@ openssl_set_sess_aead_dec_param(struct openssl_session 
*sess,
                uint8_t tag_len, uint8_t *key)
 {
        int iv_type = 0;
+       unsigned int do_ccm = 0;
 
        sess->cipher.direction = RTE_CRYPTO_CIPHER_OP_DECRYPT;
        sess->auth.operation = RTE_CRYPTO_AUTH_OP_VERIFY;
@@ -343,6 +372,13 @@ openssl_set_sess_aead_dec_param(struct openssl_session 
*sess,
                if (tag_len != 16)
                        return -EINVAL;
                break;
+       case RTE_CRYPTO_AEAD_AES_CCM:
+               iv_type = EVP_CTRL_CCM_SET_IVLEN;
+               /* Digest size can be 4, 6, 8, 10, 12, 14 or 16 bytes */
+               if (tag_len < 4 || tag_len > 16 || (tag_len & 1) == 1)
+                       return -EINVAL;
+               do_ccm = 1;
+               break;
        default:
                return -ENOTSUP;
        }
@@ -366,6 +402,10 @@ openssl_set_sess_aead_dec_param(struct openssl_session 
*sess,
                        sess->iv.length, NULL) <= 0)
                return -EINVAL;
 
+       if (do_ccm)
+               EVP_CIPHER_CTX_ctrl(sess->cipher.ctx, EVP_CTRL_CCM_SET_TAG,
+                               tag_len, NULL);
+
        if (EVP_DecryptInit_ex(sess->cipher.ctx, NULL, NULL, key, NULL) <= 0)
                return -EINVAL;
 
@@ -516,7 +556,16 @@ openssl_set_session_aead_parameters(struct openssl_session 
*sess,
        sess->cipher.key.length = xform->aead.key.length;
 
        /* Set IV parameters */
-       sess->iv.offset = xform->aead.iv.offset;
+       if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM)
+               /*
+                * For AES-CCM, the actual IV is placed
+                * one byte after the start of the IV field,
+                * according to the API.
+                */
+               sess->iv.offset = xform->aead.iv.offset + 1;
+       else
+               sess->iv.offset = xform->aead.iv.offset;
+
        sess->iv.length = xform->aead.iv.length;
 
        sess->auth.aad_length = xform->aead.aad_length;
@@ -891,7 +940,7 @@ process_openssl_cipher_des3ctr(struct rte_mbuf *mbuf_src, 
uint8_t *dst,
        return -EINVAL;
 }
 
-/** Process auth/encription aes-gcm algorithm */
+/** Process AES-GCM encrypt algorithm */
 static int
 process_openssl_auth_encryption_gcm(struct rte_mbuf *mbuf_src, int offset,
                int srclen, uint8_t *aad, int aadlen, uint8_t *iv,
@@ -929,6 +978,48 @@ process_openssl_auth_encryption_gcm(struct rte_mbuf 
*mbuf_src, int offset,
        return -EINVAL;
 }
 
+/** Process AES-CCM encrypt algorithm */
+static int
+process_openssl_auth_encryption_ccm(struct rte_mbuf *mbuf_src, int offset,
+               int srclen, uint8_t *aad, int aadlen, uint8_t *iv,
+               uint8_t *dst, uint8_t *tag, uint8_t taglen, EVP_CIPHER_CTX *ctx)
+{
+       int len = 0;
+
+       if (EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0)
+               goto process_auth_encryption_ccm_err;
+
+       if (EVP_EncryptUpdate(ctx, NULL, &len, NULL, srclen) <= 0)
+               goto process_auth_encryption_ccm_err;
+
+       if (aadlen > 0)
+               /*
+                * For AES-CCM, the actual AAD is placed
+                * 18 bytes after the start of the AAD field,
+                * according to the API.
+                */
+               if (EVP_EncryptUpdate(ctx, NULL, &len, aad + 18, aadlen) <= 0)
+                       goto process_auth_encryption_ccm_err;
+
+       if (srclen > 0)
+               if (process_openssl_encryption_update(mbuf_src, offset, &dst,
+                               srclen, ctx))
+                       goto process_auth_encryption_ccm_err;
+
+       if (EVP_EncryptFinal_ex(ctx, dst, &len) <= 0)
+               goto process_auth_encryption_ccm_err;
+
+       if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_GET_TAG, taglen, tag) <= 0)
+               goto process_auth_encryption_ccm_err;
+
+       return 0;
+
+process_auth_encryption_ccm_err:
+       OPENSSL_LOG_ERR("Process openssl auth encryption ccm failed");
+       return -EINVAL;
+}
+
+/** Process AES-GCM decrypt algorithm */
 static int
 process_openssl_auth_decryption_gcm(struct rte_mbuf *mbuf_src, int offset,
                int srclen, uint8_t *aad, int aadlen, uint8_t *iv,
@@ -957,16 +1048,52 @@ process_openssl_auth_decryption_gcm(struct rte_mbuf 
*mbuf_src, int offset,
                goto process_auth_decryption_gcm_err;
 
        if (EVP_DecryptFinal_ex(ctx, dst, &len) <= 0)
-               goto process_auth_decryption_gcm_final_err;
+               return -EFAULT;
 
        return 0;
 
 process_auth_decryption_gcm_err:
-       OPENSSL_LOG_ERR("Process openssl auth description gcm failed");
+       OPENSSL_LOG_ERR("Process openssl auth decryption gcm failed");
        return -EINVAL;
+}
 
-process_auth_decryption_gcm_final_err:
-       return -EFAULT;
+/** Process AES-CCM decrypt algorithm */
+static int
+process_openssl_auth_decryption_ccm(struct rte_mbuf *mbuf_src, int offset,
+               int srclen, uint8_t *aad, int aadlen, uint8_t *iv,
+               uint8_t *dst, uint8_t *tag, uint8_t tag_len,
+               EVP_CIPHER_CTX *ctx)
+{
+       int len = 0;
+
+       if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, tag_len, tag) <= 0)
+               goto process_auth_decryption_ccm_err;
+
+       if (EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, iv) <= 0)
+               goto process_auth_decryption_ccm_err;
+
+       if (EVP_DecryptUpdate(ctx, NULL, &len, NULL, srclen) <= 0)
+               goto process_auth_decryption_ccm_err;
+
+       if (aadlen > 0)
+               /*
+                * For AES-CCM, the actual AAD is placed
+                * 18 bytes after the start of the AAD field,
+                * according to the API.
+                */
+               if (EVP_DecryptUpdate(ctx, NULL, &len, aad + 18, aadlen) <= 0)
+                       goto process_auth_decryption_ccm_err;
+
+       if (srclen > 0)
+               if (process_openssl_decryption_update(mbuf_src, offset, &dst,
+                               srclen, ctx))
+                       return -EFAULT;
+
+       return 0;
+
+process_auth_decryption_ccm_err:
+       OPENSSL_LOG_ERR("Process openssl auth decryption ccm failed");
+       return -EINVAL;
 }
 
 /** Process standard openssl auth algorithms */
@@ -1088,6 +1215,7 @@ process_openssl_combined_op
        uint8_t *dst = NULL, *iv, *tag, *aad;
        int srclen, aadlen, status = -1;
        uint32_t offset;
+       uint8_t taglen;
 
        /*
         * Segmented destination buffer is not supported for
@@ -1123,16 +1251,34 @@ process_openssl_combined_op
                                offset + srclen);
        }
 
-       if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
-               status = process_openssl_auth_encryption_gcm(
-                               mbuf_src, offset, srclen,
-                               aad, aadlen, iv,
-                               dst, tag, sess->cipher.ctx);
-       else
-               status = process_openssl_auth_decryption_gcm(
-                               mbuf_src, offset, srclen,
-                               aad, aadlen, iv,
-                               dst, tag, sess->cipher.ctx);
+       taglen = sess->auth.digest_length;
+
+       if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
+               if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC ||
+                               sess->aead_algo == RTE_CRYPTO_AEAD_AES_GCM)
+                       status = process_openssl_auth_encryption_gcm(
+                                       mbuf_src, offset, srclen,
+                                       aad, aadlen, iv,
+                                       dst, tag, sess->cipher.ctx);
+               else
+                       status = process_openssl_auth_encryption_ccm(
+                                       mbuf_src, offset, srclen,
+                                       aad, aadlen, iv,
+                                       dst, tag, taglen, sess->cipher.ctx);
+
+       } else {
+               if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC ||
+                               sess->aead_algo == RTE_CRYPTO_AEAD_AES_GCM)
+                       status = process_openssl_auth_decryption_gcm(
+                                       mbuf_src, offset, srclen,
+                                       aad, aadlen, iv,
+                                       dst, tag, sess->cipher.ctx);
+               else
+                       status = process_openssl_auth_decryption_ccm(
+                                       mbuf_src, offset, srclen,
+                                       aad, aadlen, iv,
+                                       dst, tag, taglen, sess->cipher.ctx);
+       }
 
        if (status != 0) {
                if (status == (-EFAULT) &&
diff --git a/drivers/crypto/openssl/rte_openssl_pmd_ops.c 
b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
index 8cdd0b2..cccb7ca 100644
--- a/drivers/crypto/openssl/rte_openssl_pmd_ops.c
+++ b/drivers/crypto/openssl/rte_openssl_pmd_ops.c
@@ -362,6 +362,36 @@ static const struct rte_cryptodev_capabilities 
openssl_pmd_capabilities[] = {
                        }, }
                }, }
        },
+       {       /* AES CCM */
+               .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+               {.sym = {
+                       .xform_type = RTE_CRYPTO_SYM_XFORM_AEAD,
+                       {.aead = {
+                               .algo = RTE_CRYPTO_AEAD_AES_CCM,
+                               .block_size = 16,
+                               .key_size = {
+                                       .min = 16,
+                                       .max = 32,
+                                       .increment = 8
+                               },
+                               .digest_size = {
+                                       .min = 4,
+                                       .max = 16,
+                                       .increment = 2
+                               },
+                               .aad_size = {
+                                       .min = 0,
+                                       .max = 65535,
+                                       .increment = 1
+                               },
+                               .iv_size = {
+                                       .min = 7,
+                                       .max = 13,
+                                       .increment = 1
+                               },
+                       }, }
+               }, }
+       },
        {       /* AES GMAC (AUTH) */
                .op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
                {.sym = {
diff --git a/lib/librte_cryptodev/rte_crypto_sym.h 
b/lib/librte_cryptodev/rte_crypto_sym.h
index 0ceaa91..880ebf7 100644
--- a/lib/librte_cryptodev/rte_crypto_sym.h
+++ b/lib/librte_cryptodev/rte_crypto_sym.h
@@ -160,9 +160,6 @@ struct rte_crypto_cipher_xform {
         * Cipher key length is in bytes. For AES it can be 128 bits (16 bytes),
         * 192 bits (24 bytes) or 256 bits (32 bytes).
         *
-        * For the CCM mode of operation, the only supported key length is 128
-        * bits (16 bytes).
-        *
         * For the RTE_CRYPTO_CIPHER_AES_F8 mode of operation, key.length
         * should be set to the combined length of the encryption key and the
         * keymask. Since the keymask and the encryption key are the same size,
@@ -427,7 +424,11 @@ struct rte_crypto_aead_xform {
        uint16_t digest_length;
 
        uint16_t aad_length;
-       /**< The length of the additional authenticated data (AAD) in bytes. */
+       /**< The length of the additional authenticated data (AAD) in bytes.
+        * For CCM mode, this is the length of the actual AAD, even though
+        * it is required to reserve 18 bytes before the AAD and padding
+        * at the end of it, so a multiple of 16 bytes is allocated.
+        */
 };
 
 /** Crypto transformation types */
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 0b7ca47..b5a2885 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -4876,25 +4876,49 @@ create_aead_operation(enum rte_crypto_aead_operation op,
        struct rte_crypto_sym_op *sym_op = ut_params->op->sym;
 
        /* Append aad data */
-       aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16);
-       sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
-                       aad_pad_len);
-       TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data,
-                       "no room to append aad");
-
-       sym_op->aead.aad.phys_addr =
-                       rte_pktmbuf_mtophys(ut_params->ibuf);
-       memcpy(sym_op->aead.aad.data, tdata->aad.data, tdata->aad.len);
-       TEST_HEXDUMP(stdout, "aad:", sym_op->aead.aad.data,
-               tdata->aad.len);
-
-       /* Append IV at the end of the crypto operation*/
-       uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op,
-                       uint8_t *, IV_OFFSET);
-
-       rte_memcpy(iv_ptr, tdata->iv.data, tdata->iv.len);
-       TEST_HEXDUMP(stdout, "iv:", iv_ptr,
-               tdata->iv.len);
+       if (tdata->algo == RTE_CRYPTO_AEAD_AES_CCM) {
+               aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len + 18, 16);
+               sym_op->aead.aad.data = (uint8_t 
*)rte_pktmbuf_append(ut_params->ibuf,
+                               aad_pad_len);
+               TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data,
+                               "no room to append aad");
+
+               sym_op->aead.aad.phys_addr =
+                               rte_pktmbuf_mtophys(ut_params->ibuf);
+               /* Copy AAD 18 bytes after the AAD pointer, according to the 
API */
+               memcpy(sym_op->aead.aad.data + 18, tdata->aad.data, 
tdata->aad.len);
+               TEST_HEXDUMP(stdout, "aad:", sym_op->aead.aad.data,
+                       tdata->aad.len);
+
+               /* Append IV at the end of the crypto operation*/
+               uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op,
+                               uint8_t *, IV_OFFSET);
+
+               /* Copy IV 1 byte after the IV pointer, according to the API */
+               rte_memcpy(iv_ptr + 1, tdata->iv.data, tdata->iv.len);
+               TEST_HEXDUMP(stdout, "iv:", iv_ptr,
+                       tdata->iv.len);
+       } else {
+               aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16);
+               sym_op->aead.aad.data = (uint8_t 
*)rte_pktmbuf_append(ut_params->ibuf,
+                               aad_pad_len);
+               TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data,
+                               "no room to append aad");
+
+               sym_op->aead.aad.phys_addr =
+                               rte_pktmbuf_mtophys(ut_params->ibuf);
+               memcpy(sym_op->aead.aad.data, tdata->aad.data, tdata->aad.len);
+               TEST_HEXDUMP(stdout, "aad:", sym_op->aead.aad.data,
+                       tdata->aad.len);
+
+               /* Append IV at the end of the crypto operation*/
+               uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op,
+                               uint8_t *, IV_OFFSET);
+
+               rte_memcpy(iv_ptr, tdata->iv.data, tdata->iv.len);
+               TEST_HEXDUMP(stdout, "iv:", iv_ptr,
+                       tdata->iv.len);
+       }
 
        /* Append plaintext/ciphertext */
        if (op == RTE_CRYPTO_AEAD_OP_ENCRYPT) {
@@ -5710,6 +5734,42 @@ 
test_AES_GCM_authenticated_decryption_sessionless_test_case_1(void)
 }
 
 static int
+test_AES_CCM_authenticated_encryption_test_case_1(void)
+{
+       return test_authenticated_encryption(&ccm_test_case_1);
+}
+
+static int
+test_AES_CCM_authenticated_encryption_test_case_2(void)
+{
+       return test_authenticated_encryption(&ccm_test_case_2);
+}
+
+static int
+test_AES_CCM_authenticated_encryption_test_case_3(void)
+{
+       return test_authenticated_encryption(&ccm_test_case_3);
+}
+
+static int
+test_AES_CCM_authenticated_decryption_test_case_1(void)
+{
+       return test_authenticated_decryption(&ccm_test_case_1);
+}
+
+static int
+test_AES_CCM_authenticated_decryption_test_case_2(void)
+{
+       return test_authenticated_decryption(&ccm_test_case_2);
+}
+
+static int
+test_AES_CCM_authenticated_decryption_test_case_3(void)
+{
+       return test_authenticated_decryption(&ccm_test_case_3);
+}
+
+static int
 test_stats(void)
 {
        struct crypto_testsuite_params *ts_params = &testsuite_params;
@@ -7423,7 +7483,7 @@ create_aead_operation_SGL(enum rte_crypto_aead_operation 
op,
 
        const unsigned int auth_tag_len = tdata->auth_tag.len;
        const unsigned int iv_len = tdata->iv.len;
-       const unsigned int aad_len = tdata->aad.len;
+       unsigned int aad_len = tdata->aad.len;
 
        /* Generate Crypto op data structure */
        ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
@@ -7448,24 +7508,50 @@ create_aead_operation_SGL(enum 
rte_crypto_aead_operation op,
                                auth_tag_len);
        }
 
-       uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op,
-                       uint8_t *, IV_OFFSET);
+       /* Append aad data */
+       if (tdata->algo == RTE_CRYPTO_AEAD_AES_CCM) {
+               uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op,
+                               uint8_t *, IV_OFFSET);
 
-       rte_memcpy(iv_ptr, tdata->iv.data, iv_len);
+               /* Copy IV 1 byte after the IV pointer, according to the API */
+               rte_memcpy(iv_ptr + 1, tdata->iv.data, iv_len);
 
-       sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_prepend(
-                       ut_params->ibuf, aad_len);
-       TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data,
-                       "no room to prepend aad");
-       sym_op->aead.aad.phys_addr = rte_pktmbuf_mtophys(
-                       ut_params->ibuf);
+               aad_len = RTE_ALIGN_CEIL(aad_len + 18, 16);
 
-       memset(sym_op->aead.aad.data, 0, aad_len);
-       rte_memcpy(sym_op->aead.aad.data, tdata->aad.data, aad_len);
+               sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_prepend(
+                               ut_params->ibuf, aad_len);
+               TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data,
+                               "no room to prepend aad");
+               sym_op->aead.aad.phys_addr = rte_pktmbuf_mtophys(
+                               ut_params->ibuf);
+
+               memset(sym_op->aead.aad.data, 0, aad_len);
+               /* Copy AAD 18 bytes after the AAD pointer, according to the 
API */
+               rte_memcpy(sym_op->aead.aad.data, tdata->aad.data, aad_len);
+
+               TEST_HEXDUMP(stdout, "iv:", iv_ptr, iv_len);
+               TEST_HEXDUMP(stdout, "aad:",
+                               sym_op->aead.aad.data, aad_len);
+       } else {
+               uint8_t *iv_ptr = rte_crypto_op_ctod_offset(ut_params->op,
+                               uint8_t *, IV_OFFSET);
 
-       TEST_HEXDUMP(stdout, "iv:", iv_ptr, iv_len);
-       TEST_HEXDUMP(stdout, "aad:",
-                       sym_op->aead.aad.data, aad_len);
+               rte_memcpy(iv_ptr, tdata->iv.data, iv_len);
+
+               sym_op->aead.aad.data = (uint8_t *)rte_pktmbuf_prepend(
+                               ut_params->ibuf, aad_len);
+               TEST_ASSERT_NOT_NULL(sym_op->aead.aad.data,
+                               "no room to prepend aad");
+               sym_op->aead.aad.phys_addr = rte_pktmbuf_mtophys(
+                               ut_params->ibuf);
+
+               memset(sym_op->aead.aad.data, 0, aad_len);
+               rte_memcpy(sym_op->aead.aad.data, tdata->aad.data, aad_len);
+
+               TEST_HEXDUMP(stdout, "iv:", iv_ptr, iv_len);
+               TEST_HEXDUMP(stdout, "aad:",
+                               sym_op->aead.aad.data, aad_len);
+       }
 
        sym_op->aead.data.length = tdata->plaintext.len;
        sym_op->aead.data.offset = aad_len;
@@ -8439,6 +8525,22 @@ static struct unit_test_suite 
cryptodev_openssl_testsuite  = {
                TEST_CASE_ST(ut_setup, ut_teardown,
                        test_AES_GMAC_authentication_verify_test_case_4),
 
+               /** AES CCM Authenticated Encryption */
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                       test_AES_CCM_authenticated_encryption_test_case_1),
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                       test_AES_CCM_authenticated_encryption_test_case_2),
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                       test_AES_CCM_authenticated_encryption_test_case_3),
+
+               /** AES CCM Authenticated Decryption */
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                       test_AES_CCM_authenticated_decryption_test_case_1),
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                       test_AES_CCM_authenticated_decryption_test_case_2),
+               TEST_CASE_ST(ut_setup, ut_teardown,
+                       test_AES_CCM_authenticated_decryption_test_case_3),
+
                /** Scatter-Gather */
                TEST_CASE_ST(ut_setup, ut_teardown,
                        test_AES_GCM_auth_encrypt_SGL_out_of_place_400B_1seg),
diff --git a/test/test/test_cryptodev_aead_test_vectors.h 
b/test/test/test_cryptodev_aead_test_vectors.h
index e9f13dd..3eccd69 100644
--- a/test/test/test_cryptodev_aead_test_vectors.h
+++ b/test/test/test_cryptodev_aead_test_vectors.h
@@ -45,6 +45,15 @@ static uint8_t gcm_aad_text[MAX_AAD_LENGTH] = {
                0x00, 0xf1, 0xe2, 0xd3, 0xc4, 0xb5, 0xa6, 0x97,
                0x88, 0x79, 0x6a, 0x5b, 0x4c, 0x3d, 0x2e, 0x1f };
 
+static uint8_t ccm_aad_test_1[8] = {
+               0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+};
+
+static uint8_t ccm_aad_test_2[22] = {
+               0x08, 0x40, 0x0F, 0xD2, 0xE1, 0x28, 0xA5, 0x7C,
+               0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xAB, 0xAE,
+               0xA5, 0xB8, 0xFC, 0xBA, 0x00, 0x00
+};
 
 struct aead_test_data {
        enum rte_crypto_aead_algorithm algo;
@@ -3399,4 +3408,131 @@ static const struct aead_test_data gcm_test_case_SGL_1 
= {
        }
 };
 
+/** AES-CCM-128 Test Vectors */
+static const struct aead_test_data ccm_test_case_1 = {
+       .algo = RTE_CRYPTO_AEAD_AES_CCM,
+       .key = {
+               .data = {
+                       0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+                       0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
+               },
+               .len = 16
+       },
+       .iv = {
+               .data = {
+                       0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16
+               },
+               .len = 7
+       },
+       .aad = {
+               .data = ccm_aad_test_1,
+               .len = 8
+       },
+       .plaintext = {
+               .data = {
+                       0x20, 0x21, 0x22, 0x23
+               },
+               .len = 4
+       },
+       .ciphertext = {
+               .data = {
+                       0x71, 0x62, 0x01, 0x5b
+               },
+               .len = 4
+       },
+       .auth_tag = {
+               .data = {
+                       0x4d, 0xac, 0x25, 0x5d
+               },
+               .len = 4
+       }
+};
+
+static const struct aead_test_data ccm_test_case_2 = {
+       .algo = RTE_CRYPTO_AEAD_AES_CCM,
+       .key = {
+               .data = {
+                       0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85,
+                       0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F
+               },
+               .len = 16
+       },
+       .iv = {
+               .data = {
+                       0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5,
+                       0x03, 0x97, 0x76, 0xE7, 0x0C
+               },
+               .len = 13
+       },
+       .aad = {
+               .data = ccm_aad_test_2,
+               .len = 22
+       },
+       .plaintext = {
+               .data = {
+                       0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE,
+                       0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB,
+                       0x7E, 0x78, 0xA0, 0x50
+               },
+               .len = 20
+       },
+       .ciphertext = {
+               .data = {
+                       0xF3, 0xD0, 0xA2, 0xFE, 0x9A, 0x3D, 0xBF, 0x23,
+                       0x42, 0xA6, 0x43, 0xE4, 0x32, 0x46, 0xE8, 0x0C,
+                       0x3C, 0x04, 0xD0, 0x19
+               },
+               .len = 20
+       },
+       .auth_tag = {
+               .data = {
+                       0x78, 0x45, 0xCE, 0x0B, 0x16, 0xF9, 0x76, 0x23
+               },
+               .len = 8
+       }
+};
+
+static const struct aead_test_data ccm_test_case_3 = {
+       .algo = RTE_CRYPTO_AEAD_AES_CCM,
+       .key = {
+               .data = {
+                       0xC9, 0x7C, 0x1F, 0x67, 0xCE, 0x37, 0x11, 0x85,
+                       0x51, 0x4A, 0x8A, 0x19, 0xF2, 0xBD, 0xD5, 0x2F
+               },
+               .len = 16
+       },
+       .iv = {
+               .data = {
+                       0x00, 0x50, 0x30, 0xF1, 0x84, 0x44, 0x08, 0xB5,
+                       0x03, 0x97, 0x76, 0xE7, 0x0C
+               },
+               .len = 13
+       },
+       .aad = {
+               .data = gcm_aad_zero_text,
+               .len = 0
+       },
+       .plaintext = {
+               .data = {
+                       0xF8, 0xBA, 0x1A, 0x55, 0xD0, 0x2F, 0x85, 0xAE,
+                       0x96, 0x7B, 0xB6, 0x2F, 0xB6, 0xCD, 0xA8, 0xEB,
+                       0x7E, 0x78, 0xA0, 0x50
+               },
+               .len = 20
+       },
+       .ciphertext = {
+               .data = {
+                       0xF3, 0xD0, 0xA2, 0xFE, 0x9A, 0x3D, 0xBF, 0x23,
+                       0x42, 0xA6, 0x43, 0xE4, 0x32, 0x46, 0xE8, 0x0C,
+                       0x3C, 0x04, 0xD0, 0x19
+               },
+               .len = 20
+       },
+       .auth_tag = {
+               .data = {
+                       0x41, 0x83, 0x21, 0x89, 0xA3, 0xD3, 0x1B, 0x43
+               },
+               .len = 8
+       }
+};
 #endif /* TEST_CRYPTODEV_AEAD_TEST_VECTORS_H_ */
-- 
2.9.4

Reply via email to