[dpdk-dev] [PATCH 4/4] crypto/openssl: add AES-CCM support

Pablo de Lara pablo.de.lara.guarch at intel.com
Fri Aug 18 10:07:28 CEST 2017


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

Signed-off-by: Pablo de Lara <pablo.de.lara.guarch at 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



More information about the dev mailing list