[v2,1/1] test/crypto: add tests for encrypted digest AES CTR+CMAC

Message ID 20191021112955.9579-2-adamx.dybkowski@intel.com (mailing list archive)
State Accepted, archived
Delegated to: akhil goyal
Headers
Series test/crypto: add tests for encrypted digest AES CTR+CMAC |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/iol-intel-Performance success Performance Testing PASS
ci/Intel-compilation success Compilation OK
ci/iol-compilation success Compile Testing PASS
ci/iol-mellanox-Performance success Performance Testing PASS
ci/travis-robot success Travis build: passed

Commit Message

Dybkowski, AdamX Oct. 21, 2019, 11:29 a.m. UTC
  This patch adds tests for encrypted digest AES-CTR + AES CMAC using
mixed auth-cipher algorithm functions. Tests allow easy
extending with new cases, check in-place and
out-of-place operations and use linear and sgl
buffers as input/output.

Signed-off-by: Adam Dybkowski <adamx.dybkowski@intel.com>
---
 app/test/test_cryptodev.c                    | 487 ++++++++++++++++++-
 app/test/test_cryptodev_mixed_test_vectors.h | 172 +++++++
 2 files changed, 655 insertions(+), 4 deletions(-)
 create mode 100644 app/test/test_cryptodev_mixed_test_vectors.h
  

Comments

Arkadiusz Kusztal Oct. 21, 2019, 11:32 a.m. UTC | #1
> -----Original Message-----
> From: Dybkowski, AdamX
> Sent: Monday, October 21, 2019 1:30 PM
> To: dev@dpdk.org; Trahe, Fiona <fiona.trahe@intel.com>; Kusztal,
> ArkadiuszX <arkadiuszx.kusztal@intel.com>; akhil.goyal@nxp.com
> Cc: Dybkowski, AdamX <adamx.dybkowski@intel.com>
> Subject: [PATCH v2 1/1] test/crypto: add tests for encrypted digest AES
> CTR+CMAC
> 
> This patch adds tests for encrypted digest AES-CTR + AES CMAC using mixed
> auth-cipher algorithm functions. Tests allow easy extending with new cases,
> check in-place and out-of-place operations and use linear and sgl buffers as
> input/output.
> 
> Signed-off-by: Adam Dybkowski <adamx.dybkowski@intel.com>
> ---
>  app/test/test_cryptodev.c                    | 487 ++++++++++++++++++-
>  app/test/test_cryptodev_mixed_test_vectors.h | 172 +++++++
>  2 files changed, 655 insertions(+), 4 deletions(-)  create mode 100644
> app/test/test_cryptodev_mixed_test_vectors.h
> 
> +
> +#endif /* TEST_CRYPTODEV_MIXED_TEST_VECTORS_H_ */
> --
> 2.17.1


Acked-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
  
Akhil Goyal Oct. 21, 2019, 11:53 a.m. UTC | #2
Hi All,

The test_cryptodev.c is getting bloated with a lot of duplicated code.
We should plan to consolidate the code so that it is scalable and whenever
a new PMD is added, a new testsuite is built and the file gets bloated.

In this release we are allowing these type of changes but going forward(post 19.11)
No duplicate code will be accepted. We should develop a way to check PMDs
Capabilities and execute the test cases accordingly. I would request all the PMD owners
Who test their PMDs with this application to contribute and start a thread to clean up 
this mess.

I also see that there is some common code while adding a new algorithm.

Thanks,
Akhil

> 
> This patch adds tests for encrypted digest AES-CTR + AES CMAC using
> mixed auth-cipher algorithm functions. Tests allow easy
> extending with new cases, check in-place and
> out-of-place operations and use linear and sgl
> buffers as input/output.
> 
> Signed-off-by: Adam Dybkowski <adamx.dybkowski@intel.com>
> ---
  
Akhil Goyal Oct. 23, 2019, 2:03 p.m. UTC | #3
> >
> > This patch adds tests for encrypted digest AES-CTR + AES CMAC using mixed
> > auth-cipher algorithm functions. Tests allow easy extending with new cases,
> > check in-place and out-of-place operations and use linear and sgl buffers as
> > input/output.
> >
> > Signed-off-by: Adam Dybkowski <adamx.dybkowski@intel.com>
> > ---
> >  app/test/test_cryptodev.c                    | 487 ++++++++++++++++++-
> >  app/test/test_cryptodev_mixed_test_vectors.h | 172 +++++++
> >  2 files changed, 655 insertions(+), 4 deletions(-)  create mode 100644
> > app/test/test_cryptodev_mixed_test_vectors.h
> >
> > +
> > +#endif /* TEST_CRYPTODEV_MIXED_TEST_VECTORS_H_ */
> > --
> > 2.17.1
> 
> 
> Acked-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>

Applied to dpdk-next-crypto

Thanks.
  

Patch

diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index 65d80837a..35738a40d 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -38,6 +38,7 @@ 
 #include "test_cryptodev_zuc_test_vectors.h"
 #include "test_cryptodev_aead_test_vectors.h"
 #include "test_cryptodev_hmac_test_vectors.h"
+#include "test_cryptodev_mixed_test_vectors.h"
 #ifdef RTE_LIBRTE_SECURITY
 #include "test_cryptodev_security_pdcp_test_vectors.h"
 #include "test_cryptodev_security_pdcp_test_func.h"
@@ -3021,6 +3022,11 @@  create_wireless_algo_auth_cipher_operation(unsigned int auth_tag_len,
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
 	struct crypto_unittest_params *ut_params = &unittest_params;
 
+	enum rte_crypto_cipher_algorithm cipher_algo =
+			ut_params->cipher_xform.cipher.algo;
+	enum rte_crypto_auth_algorithm auth_algo =
+			ut_params->auth_xform.auth.algo;
+
 	/* Generate Crypto op data structure */
 	ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
 			RTE_CRYPTO_OP_TYPE_SYMMETRIC);
@@ -3076,11 +3082,25 @@  create_wireless_algo_auth_cipher_operation(unsigned int auth_tag_len,
 	iv_ptr += cipher_iv_len;
 	rte_memcpy(iv_ptr, auth_iv, auth_iv_len);
 
-	sym_op->cipher.data.length = cipher_len;
-	sym_op->cipher.data.offset = cipher_offset;
+	if (cipher_algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ||
+		cipher_algo == RTE_CRYPTO_CIPHER_KASUMI_F8 ||
+		cipher_algo == RTE_CRYPTO_CIPHER_ZUC_EEA3) {
+		sym_op->cipher.data.length = cipher_len;
+		sym_op->cipher.data.offset = cipher_offset;
+	} else {
+		sym_op->cipher.data.length = cipher_len >> 3;
+		sym_op->cipher.data.offset = cipher_offset >> 3;
+	}
 
-	sym_op->auth.data.length = auth_len;
-	sym_op->auth.data.offset = auth_offset;
+	if (auth_algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2 ||
+		auth_algo == RTE_CRYPTO_AUTH_KASUMI_F9 ||
+		auth_algo == RTE_CRYPTO_AUTH_ZUC_EIA3) {
+		sym_op->auth.data.length = auth_len;
+		sym_op->auth.data.offset = auth_offset;
+	} else {
+		sym_op->auth.data.length = auth_len >> 3;
+		sym_op->auth.data.offset = auth_offset >> 3;
+	}
 
 	return 0;
 }
@@ -6511,6 +6531,446 @@  test_zuc_auth_cipher_verify_test_case_1_oop_sgl(void)
 		&zuc_auth_cipher_test_case_1, OUT_OF_PLACE, 1);
 }
 
+static int
+test_mixed_check_if_unsupported(const struct mixed_cipher_auth_test_data *tdata)
+{
+	uint8_t dev_id = testsuite_params.valid_devs[0];
+
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+
+	/* Check if device supports particular cipher algorithm */
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+	cap_idx.algo.cipher = tdata->cipher_algo;
+	if (rte_cryptodev_sym_capability_get(dev_id, &cap_idx) == NULL)
+		return -ENOTSUP;
+
+	/* Check if device supports particular hash algorithm */
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+	cap_idx.algo.auth = tdata->auth_algo;
+	if (rte_cryptodev_sym_capability_get(dev_id, &cap_idx) == NULL)
+		return -ENOTSUP;
+
+	return 0;
+}
+
+static int
+test_mixed_auth_cipher(const struct mixed_cipher_auth_test_data *tdata,
+	uint8_t op_mode, uint8_t verify)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_unittest_params *ut_params = &unittest_params;
+
+	int retval;
+
+	uint8_t *plaintext = NULL, *ciphertext = NULL;
+	unsigned int plaintext_pad_len;
+	unsigned int plaintext_len;
+	unsigned int ciphertext_pad_len;
+	unsigned int ciphertext_len;
+
+	struct rte_cryptodev_info dev_info;
+
+	/* Check if device supports particular algorithms */
+	if (test_mixed_check_if_unsupported(tdata))
+		return -ENOTSUP;
+
+	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
+
+	uint64_t feat_flags = dev_info.feature_flags;
+
+	if (op_mode == OUT_OF_PLACE) {
+		if (!(feat_flags & RTE_CRYPTODEV_FF_DIGEST_ENCRYPTED)) {
+			printf("Device doesn't support digest encrypted.\n");
+			return -ENOTSUP;
+		}
+	}
+
+	/* Create the session */
+	retval = create_wireless_algo_auth_cipher_session(
+			ts_params->valid_devs[0],
+			(verify ? RTE_CRYPTO_CIPHER_OP_DECRYPT
+					: RTE_CRYPTO_CIPHER_OP_ENCRYPT),
+			(verify ? RTE_CRYPTO_AUTH_OP_VERIFY
+					: RTE_CRYPTO_AUTH_OP_GENERATE),
+			tdata->auth_algo,
+			tdata->cipher_algo,
+			tdata->auth_key.data, tdata->auth_key.len,
+			tdata->auth_iv.len, tdata->digest_enc.len,
+			tdata->cipher_iv.len);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+	if (op_mode == OUT_OF_PLACE)
+		ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+
+	/* clear mbuf payload */
+	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+		rte_pktmbuf_tailroom(ut_params->ibuf));
+	if (op_mode == OUT_OF_PLACE)
+		memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0,
+				rte_pktmbuf_tailroom(ut_params->obuf));
+
+	ciphertext_len = ceil_byte_length(tdata->ciphertext.len_bits);
+	plaintext_len = ceil_byte_length(tdata->plaintext.len_bits);
+	ciphertext_pad_len = RTE_ALIGN_CEIL(ciphertext_len, 16);
+	plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16);
+
+	if (verify) {
+		ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+				ciphertext_pad_len);
+		memcpy(ciphertext, tdata->ciphertext.data, ciphertext_len);
+		if (op_mode == OUT_OF_PLACE)
+			rte_pktmbuf_append(ut_params->obuf, ciphertext_pad_len);
+		debug_hexdump(stdout, "ciphertext:", ciphertext,
+				ciphertext_len);
+	} else {
+		plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+				plaintext_pad_len);
+		memcpy(plaintext, tdata->plaintext.data, plaintext_len);
+		if (op_mode == OUT_OF_PLACE)
+			rte_pktmbuf_append(ut_params->obuf, plaintext_pad_len);
+		debug_hexdump(stdout, "plaintext:", plaintext, plaintext_len);
+	}
+
+	/* Create the operation */
+	retval = create_wireless_algo_auth_cipher_operation(
+			tdata->digest_enc.len,
+			tdata->cipher_iv.data, tdata->cipher_iv.len,
+			tdata->auth_iv.data, tdata->auth_iv.len,
+			(tdata->digest_enc.offset == 0 ?
+			(verify ? ciphertext_pad_len : plaintext_pad_len)
+				: tdata->digest_enc.offset),
+			tdata->validCipherLen.len_bits,
+			tdata->cipher.offset_bits,
+			tdata->validAuthLen.len_bits,
+			tdata->auth.offset_bits,
+			op_mode, 0);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf");
+
+	ut_params->obuf = (op_mode == IN_PLACE ?
+			ut_params->op->sym->m_src : ut_params->op->sym->m_dst);
+
+	if (verify) {
+		if (ut_params->obuf)
+			plaintext = rte_pktmbuf_mtod(ut_params->obuf,
+							uint8_t *);
+		else
+			plaintext = ciphertext +
+					(tdata->cipher.offset_bits >> 3);
+
+		debug_hexdump(stdout, "plaintext:", plaintext,
+				(tdata->plaintext.len_bits >> 3) -
+				tdata->digest_enc.len);
+		debug_hexdump(stdout, "plaintext expected:",
+				tdata->plaintext.data,
+				(tdata->plaintext.len_bits >> 3) -
+				tdata->digest_enc.len);
+	} else {
+		if (ut_params->obuf)
+			ciphertext = rte_pktmbuf_mtod(ut_params->obuf,
+					uint8_t *);
+		else
+			ciphertext = plaintext;
+
+		debug_hexdump(stdout, "ciphertext:", ciphertext,
+				ciphertext_len);
+		debug_hexdump(stdout, "ciphertext expected:",
+				tdata->ciphertext.data,
+				tdata->ciphertext.len_bits >> 3);
+
+		ut_params->digest = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *)
+				+ (tdata->digest_enc.offset == 0 ?
+		plaintext_pad_len : tdata->digest_enc.offset);
+
+		debug_hexdump(stdout, "digest:", ut_params->digest,
+				tdata->digest_enc.len);
+		debug_hexdump(stdout, "digest expected:",
+				tdata->digest_enc.data,
+				tdata->digest_enc.len);
+	}
+
+	/* Validate obuf */
+	if (verify) {
+		TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(
+				plaintext,
+				tdata->plaintext.data,
+				tdata->plaintext.len_bits >> 3,
+				"Plaintext data not as expected");
+	} else {
+		TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(
+				ciphertext,
+				tdata->ciphertext.data,
+				tdata->validDataLen.len_bits,
+				"Ciphertext data not as expected");
+
+		TEST_ASSERT_BUFFERS_ARE_EQUAL(
+				ut_params->digest,
+				tdata->digest_enc.data,
+				DIGEST_BYTE_LENGTH_SNOW3G_UIA2,
+				"Generated auth tag not as expected");
+	}
+	return 0;
+}
+
+static int
+test_mixed_auth_cipher_sgl(const struct mixed_cipher_auth_test_data *tdata,
+	uint8_t op_mode, uint8_t verify)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_unittest_params *ut_params = &unittest_params;
+
+	int retval;
+
+	const uint8_t *plaintext = NULL;
+	const uint8_t *ciphertext = NULL;
+	const uint8_t *digest = NULL;
+	unsigned int plaintext_pad_len;
+	unsigned int plaintext_len;
+	unsigned int ciphertext_pad_len;
+	unsigned int ciphertext_len;
+	uint8_t buffer[10000];
+	uint8_t digest_buffer[10000];
+
+	struct rte_cryptodev_info dev_info;
+
+	/* Check if device supports particular algorithms */
+	if (test_mixed_check_if_unsupported(tdata))
+		return -ENOTSUP;
+
+	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
+
+	uint64_t feat_flags = dev_info.feature_flags;
+
+	if (op_mode == IN_PLACE) {
+		if (!(feat_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)) {
+			printf("Device doesn't support in-place scatter-gather "
+					"in both input and output mbufs.\n");
+			return -ENOTSUP;
+		}
+	} else {
+		if (!(feat_flags & RTE_CRYPTODEV_FF_OOP_SGL_IN_SGL_OUT)) {
+			printf("Device doesn't support out-of-place scatter-gather "
+					"in both input and output mbufs.\n");
+			return -ENOTSUP;
+		}
+		if (!(feat_flags & RTE_CRYPTODEV_FF_DIGEST_ENCRYPTED)) {
+			printf("Device doesn't support digest encrypted.\n");
+			return -ENOTSUP;
+		}
+	}
+
+	/* Create the session */
+	retval = create_wireless_algo_auth_cipher_session(
+			ts_params->valid_devs[0],
+			(verify ? RTE_CRYPTO_CIPHER_OP_DECRYPT
+					: RTE_CRYPTO_CIPHER_OP_ENCRYPT),
+			(verify ? RTE_CRYPTO_AUTH_OP_VERIFY
+					: RTE_CRYPTO_AUTH_OP_GENERATE),
+			tdata->auth_algo,
+			tdata->cipher_algo,
+			tdata->auth_key.data, tdata->auth_key.len,
+			tdata->auth_iv.len, tdata->digest_enc.len,
+			tdata->cipher_iv.len);
+
+	if (retval < 0)
+		return retval;
+
+	ciphertext_len = ceil_byte_length(tdata->ciphertext.len_bits);
+	plaintext_len = ceil_byte_length(tdata->plaintext.len_bits);
+	ciphertext_pad_len = RTE_ALIGN_CEIL(ciphertext_len, 16);
+	plaintext_pad_len = RTE_ALIGN_CEIL(plaintext_len, 16);
+
+	ut_params->ibuf = create_segmented_mbuf(ts_params->mbuf_pool,
+			plaintext_pad_len, 15, 0);
+	TEST_ASSERT_NOT_NULL(ut_params->ibuf,
+			"Failed to allocate input buffer in mempool");
+
+	if (op_mode == OUT_OF_PLACE) {
+		ut_params->obuf = create_segmented_mbuf(ts_params->mbuf_pool,
+				plaintext_pad_len, 15, 0);
+		TEST_ASSERT_NOT_NULL(ut_params->obuf,
+				"Failed to allocate output buffer in mempool");
+	}
+
+	if (verify) {
+		pktmbuf_write(ut_params->ibuf, 0, ciphertext_len,
+			tdata->ciphertext.data);
+		ciphertext = rte_pktmbuf_read(ut_params->ibuf, 0,
+					ciphertext_len, buffer);
+		debug_hexdump(stdout, "ciphertext:", ciphertext,
+			ciphertext_len);
+	} else {
+		pktmbuf_write(ut_params->ibuf, 0, plaintext_len,
+			tdata->plaintext.data);
+		plaintext = rte_pktmbuf_read(ut_params->ibuf, 0,
+					plaintext_len, buffer);
+		debug_hexdump(stdout, "plaintext:", plaintext,
+			plaintext_len);
+	}
+	memset(buffer, 0, sizeof(buffer));
+
+	/* Create the operation */
+	retval = create_wireless_algo_auth_cipher_operation(
+			tdata->digest_enc.len,
+			tdata->cipher_iv.data, tdata->cipher_iv.len,
+			tdata->auth_iv.data, tdata->auth_iv.len,
+			(tdata->digest_enc.offset == 0 ?
+			(verify ? ciphertext_pad_len : plaintext_pad_len)
+				: tdata->digest_enc.offset),
+			tdata->validCipherLen.len_bits,
+			tdata->cipher.offset_bits,
+			tdata->validAuthLen.len_bits,
+			tdata->auth.offset_bits,
+			op_mode, 1);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed to retrieve obuf");
+
+	ut_params->obuf = (op_mode == IN_PLACE ?
+			ut_params->op->sym->m_src : ut_params->op->sym->m_dst);
+
+	if (verify) {
+		if (ut_params->obuf)
+			plaintext = rte_pktmbuf_read(ut_params->obuf, 0,
+					plaintext_len, buffer);
+		else
+			plaintext = rte_pktmbuf_read(ut_params->ibuf, 0,
+					plaintext_len, buffer);
+
+		debug_hexdump(stdout, "plaintext:", plaintext,
+				(tdata->plaintext.len_bits >> 3) -
+				tdata->digest_enc.len);
+		debug_hexdump(stdout, "plaintext expected:",
+				tdata->plaintext.data,
+				(tdata->plaintext.len_bits >> 3) -
+				tdata->digest_enc.len);
+	} else {
+		if (ut_params->obuf)
+			ciphertext = rte_pktmbuf_read(ut_params->obuf, 0,
+					ciphertext_len, buffer);
+		else
+			ciphertext = rte_pktmbuf_read(ut_params->ibuf, 0,
+					ciphertext_len, buffer);
+
+		debug_hexdump(stdout, "ciphertext:", ciphertext,
+			ciphertext_len);
+		debug_hexdump(stdout, "ciphertext expected:",
+			tdata->ciphertext.data,
+			tdata->ciphertext.len_bits >> 3);
+
+		if (ut_params->obuf)
+			digest = rte_pktmbuf_read(ut_params->obuf,
+					(tdata->digest_enc.offset == 0 ?
+						plaintext_pad_len :
+						tdata->digest_enc.offset),
+					tdata->digest_enc.len, digest_buffer);
+		else
+			digest = rte_pktmbuf_read(ut_params->ibuf,
+					(tdata->digest_enc.offset == 0 ?
+						plaintext_pad_len :
+						tdata->digest_enc.offset),
+					tdata->digest_enc.len, digest_buffer);
+
+		debug_hexdump(stdout, "digest:", digest,
+				tdata->digest_enc.len);
+		debug_hexdump(stdout, "digest expected:",
+				tdata->digest_enc.data, tdata->digest_enc.len);
+	}
+
+	/* Validate obuf */
+	if (verify) {
+		TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(
+				plaintext,
+				tdata->plaintext.data,
+				tdata->plaintext.len_bits >> 3,
+				"Plaintext data not as expected");
+	} else {
+		TEST_ASSERT_BUFFERS_ARE_EQUAL_BIT(
+				ciphertext,
+				tdata->ciphertext.data,
+				tdata->validDataLen.len_bits,
+				"Ciphertext data not as expected");
+		TEST_ASSERT_BUFFERS_ARE_EQUAL(
+				digest,
+				tdata->digest_enc.data,
+				tdata->digest_enc.len,
+				"Generated auth tag not as expected");
+	}
+	return 0;
+}
+
+/** AUTH AES CMAC + CIPHER AES CTR */
+
+static int
+test_aes_cmac_aes_ctr_digest_enc_test_case_1(void)
+{
+	return test_mixed_auth_cipher(
+		&auth_aes_cmac_cipher_aes_ctr_test_case_1, IN_PLACE, 0);
+}
+
+static int
+test_aes_cmac_aes_ctr_digest_enc_test_case_1_oop(void)
+{
+	return test_mixed_auth_cipher(
+		&auth_aes_cmac_cipher_aes_ctr_test_case_1, OUT_OF_PLACE, 0);
+}
+
+static int
+test_aes_cmac_aes_ctr_digest_enc_test_case_1_sgl(void)
+{
+	return test_mixed_auth_cipher_sgl(
+		&auth_aes_cmac_cipher_aes_ctr_test_case_1, IN_PLACE, 0);
+}
+
+static int
+test_aes_cmac_aes_ctr_digest_enc_test_case_1_oop_sgl(void)
+{
+	return test_mixed_auth_cipher_sgl(
+		&auth_aes_cmac_cipher_aes_ctr_test_case_1, OUT_OF_PLACE, 0);
+}
+
+static int
+test_verify_aes_cmac_aes_ctr_digest_enc_test_case_1(void)
+{
+	return test_mixed_auth_cipher(
+		&auth_aes_cmac_cipher_aes_ctr_test_case_1, IN_PLACE, 1);
+}
+
+static int
+test_verify_aes_cmac_aes_ctr_digest_enc_test_case_1_oop(void)
+{
+	return test_mixed_auth_cipher(
+		&auth_aes_cmac_cipher_aes_ctr_test_case_1, OUT_OF_PLACE, 1);
+}
+
+static int
+test_verify_aes_cmac_aes_ctr_digest_enc_test_case_1_sgl(void)
+{
+	return test_mixed_auth_cipher_sgl(
+		&auth_aes_cmac_cipher_aes_ctr_test_case_1, IN_PLACE, 1);
+}
+
+static int
+test_verify_aes_cmac_aes_ctr_digest_enc_test_case_1_oop_sgl(void)
+{
+	return test_mixed_auth_cipher_sgl(
+		&auth_aes_cmac_cipher_aes_ctr_test_case_1, OUT_OF_PLACE, 1);
+}
+
 static int
 test_3DES_chain_qat_all(void)
 {
@@ -11802,6 +12262,25 @@  static struct unit_test_suite cryptodev_qat_testsuite  = {
 		TEST_CASE_ST(ut_setup, ut_teardown,
 			auth_decryption_AES128CBC_HMAC_SHA1_fail_tag_corrupt),
 
+		/** Mixed CIPHER + HASH algorithms */
+		/** AUTH AES CMAC + CIPHER AES CTR */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_aes_cmac_aes_ctr_digest_enc_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_aes_cmac_aes_ctr_digest_enc_test_case_1_oop),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_aes_cmac_aes_ctr_digest_enc_test_case_1_sgl),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_aes_cmac_aes_ctr_digest_enc_test_case_1_oop_sgl),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_verify_aes_cmac_aes_ctr_digest_enc_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+		       test_verify_aes_cmac_aes_ctr_digest_enc_test_case_1_oop),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+		       test_verify_aes_cmac_aes_ctr_digest_enc_test_case_1_sgl),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+		   test_verify_aes_cmac_aes_ctr_digest_enc_test_case_1_oop_sgl),
+
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
 };
diff --git a/app/test/test_cryptodev_mixed_test_vectors.h b/app/test/test_cryptodev_mixed_test_vectors.h
new file mode 100644
index 000000000..bca47c05c
--- /dev/null
+++ b/app/test/test_cryptodev_mixed_test_vectors.h
@@ -0,0 +1,172 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2019 Intel Corporation
+ */
+
+#ifndef TEST_CRYPTODEV_MIXED_TEST_VECTORS_H_
+#define TEST_CRYPTODEV_MIXED_TEST_VECTORS_H_
+
+struct mixed_cipher_auth_test_data {
+
+	enum rte_crypto_auth_algorithm auth_algo;
+
+	struct {
+		uint8_t data[64];
+		unsigned int len; /* length must be in Bytes */
+	} auth_key;
+
+	struct {
+		uint8_t data[64];
+		unsigned int len; /* length must be in Bytes */
+	} auth_iv;
+
+	struct {
+		unsigned int len_bits;
+		unsigned int offset_bits;
+	} auth;
+
+	enum rte_crypto_cipher_algorithm cipher_algo;
+
+	struct {
+		uint8_t data[64];
+		unsigned int len; /* length must be in Bytes */
+	} cipher_key;
+
+	struct {
+		uint8_t data[64] __rte_aligned(16);
+		unsigned int len; /* length must be in Bytes */
+	} cipher_iv;
+
+	struct {
+		unsigned int len_bits;
+		unsigned int offset_bits;
+	} cipher;
+
+	struct {
+		uint8_t data[1024];
+		unsigned int len_bits;
+	} plaintext;
+
+	struct {
+		uint8_t data[1024];
+		unsigned int len_bits;
+	} ciphertext;
+
+	struct {
+		uint8_t data[64];
+		unsigned int len; /* length must be in Bytes */
+		unsigned int offset; /* offset must be in Bytes */
+	} digest_enc;
+
+	struct {
+		unsigned int len_bits;
+	} validDataLen;
+
+	struct {
+		unsigned int len_bits;
+	} validCipherLen;
+
+	struct {
+		unsigned int len_bits;
+	} validAuthLen;
+};
+
+struct mixed_cipher_auth_test_data auth_aes_cmac_cipher_aes_ctr_test_case_1 = {
+	.auth_algo = RTE_CRYPTO_AUTH_AES_CMAC,
+	.auth_key = {
+		.data = {
+			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+			0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
+		},
+		.len = 16,
+	},
+	.auth_iv = {
+		.data = {
+			 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+			 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		},
+		.len = 16,
+	},
+	.auth = {
+		.len_bits = 124 << 3,
+		.offset_bits = 0,
+	},
+	.cipher_algo = RTE_CRYPTO_CIPHER_AES_CTR,
+	.cipher_key = {
+		.data = {
+			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+			0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
+		},
+		.len = 16,
+	},
+	.cipher_iv = {
+		.data = {
+			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		},
+		.len = 16,
+	},
+	.cipher = {
+		.len_bits = 126 << 3,
+		.offset_bits = 2 << 3,
+	},
+	.plaintext = {
+		.data = {
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+			0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A,
+		},
+		.len_bits = 128 << 3,
+	},
+	.ciphertext = {
+		.data = {
+			0x5A, 0x5A, 0xC9, 0x79, 0xCA, 0xCB, 0xDF, 0x96,
+			0x97, 0xA5, 0xB0, 0xFC, 0x56, 0xE9, 0xC4, 0xB4,
+			0x32, 0x5F, 0x55, 0x59, 0xCF, 0x1A, 0xA5, 0xB5,
+			0x63, 0xAC, 0x94, 0x87, 0x6F, 0xFB, 0x5A, 0x54,
+			0x4E, 0xE2, 0x2B, 0x32, 0x04, 0x0C, 0xDF, 0x7D,
+			0x58, 0x73, 0xCE, 0x64, 0x71, 0xEA, 0x31, 0x19,
+			0xE1, 0x37, 0x9E, 0x89, 0x15, 0x1F, 0xDE, 0x99,
+			0x17, 0x80, 0x2A, 0x95, 0xAB, 0x37, 0xDF, 0x01,
+			0x7F, 0x3B, 0x17, 0x07, 0xFA, 0x93, 0xC9, 0xC8,
+			0x6A, 0x1C, 0xE2, 0x34, 0x2F, 0x33, 0x59, 0xE4,
+			0xE2, 0x56, 0x1A, 0x23, 0xCC, 0xCE, 0x29, 0x33,
+			0xC7, 0xAF, 0x92, 0x28, 0x86, 0x5B, 0x91, 0x5B,
+			0x0E, 0x4E, 0xFB, 0x3B, 0x9D, 0x9F, 0xDF, 0x16,
+			0x79, 0x90, 0x86, 0xBA, 0x70, 0xD9, 0xF7, 0x9B,
+			0xEC, 0x46, 0xA9, 0x98, 0x5A, 0xF1, 0x5A, 0x05,
+			0x3E, 0xD9, 0xE5, 0x03, 0x5D, 0x41, 0xB4, 0xDF
+		},
+		.len_bits = 128 << 3,
+	},
+	.digest_enc = {
+		.data = {
+			0x5D, 0x41, 0xB4, 0xDF,
+		},
+		.len = 4,
+		.offset = 124,
+	},
+	.validDataLen = {
+		.len_bits = 128 << 3,
+	},
+	.validCipherLen = {
+		.len_bits = 126 << 3,
+	},
+	.validAuthLen = {
+		.len_bits = 124 << 3,
+	}
+};
+
+#endif /* TEST_CRYPTODEV_MIXED_TEST_VECTORS_H_ */