DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH v1 0/4] Generalize PCI specific EAL function/structures
From: Thomas Monjalon @ 2016-10-03 13:36 UTC (permalink / raw)
  To: Shreyansh Jain; +Cc: David Marchand, dev, Jan Viktorin
In-Reply-To: <4e8b181f-8d46-f4b4-3821-a19f5c622ec1@nxp.com>

2016-10-03 11:07, Shreyansh Jain:
> Hi David,
> 
> On Friday 30 September 2016 09:01 PM, David Marchand wrote:
> > On Tue, Sep 27, 2016 at 4:12 PM, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:
> >> (I rebased these over HEAD 7b3c4f3)
> >>
> >> These patches were initially part of Jan's original series on SoC
> >> Framework ([1],[2]). An update to that series, without these patches,
> >> was posted here [3].
> >>
> >> Main motivation for these is aim of introducing a non-PCI centric
> >> subsystem in EAL. As of now the first usecase is SoC, but not limited to
> >> it.
> >>
> >> 4 patches in this series are independent of each other, as well as SoC
> >> framework. All these focus on generalizing some structure or functions
> >> present with the PCI specific code to EAL Common area (or splitting a
> >> function to be more userful).
> >
> > Those patches move linux specifics (binding pci devices using sysfs)
> > to common infrastucture.
> > We have no proper hotplug support on bsd, but if we had some common
> > code we should at least try to make the apis generic.
> >
> 
> I am not sure if I understood your point well. Just to confirm - you are 
> stating that the movement done in the patches might not suit BSD. 
> Probably you are talking about (Patch 3/4 and 4/4).
> Is my understanding correct?
> 
> So, movement to just Linux area is not enough?
> I am not well versed with BSD way of doing something similar so if 
> someone can point it out, I can integrate that. (I will investigate it 
> at my end as well).
> 
> This patchset makes the PCI->EAL movement *only* for Linux for sysfs 
> bind/unbind. (I should add this to cover letter, at the least).

The concern is about function declarations in
	lib/librte_eal/common/eal_private.h
We cannot be sure it can be applicable to something else than Linux.
As it is implemented in Linux only, it should not be in a common header.

^ permalink raw reply

* [PATCH v5 4/4] examples/l2fwd-crypto: updated example for libcrypto PMD
From: Slawomir Mrozowicz @ 2016-10-03 15:28 UTC (permalink / raw)
  To: dev; +Cc: Slawomir Mrozowicz, Daniel Mrzyglod
In-Reply-To: <1475504792-31557-1-git-send-email-slawomirx.mrozowicz@intel.com>

Libcrypto PMD has support for:

Supported cipher algorithms:
RTE_CRYPTO_CIPHER_3DES_CBC
RTE_CRYPTO_CIPHER_AES_CBC
RTE_CRYPTO_CIPHER_AES_CTR
RTE_CRYPTO_CIPHER_3DES_CTR
RTE_CRYPTO_CIPHER_AES_GCM

Supported authentication algorithms:
RTE_CRYPTO_AUTH_AES_GMAC
RTE_CRYPTO_AUTH_MD5
RTE_CRYPTO_AUTH_SHA1
RTE_CRYPTO_AUTH_SHA224
RTE_CRYPTO_AUTH_SHA256
RTE_CRYPTO_AUTH_SHA384
RTE_CRYPTO_AUTH_SHA512
RTE_CRYPTO_AUTH_MD5_HMAC
RTE_CRYPTO_AUTH_SHA1_HMAC
RTE_CRYPTO_AUTH_SHA224_HMAC
RTE_CRYPTO_AUTH_SHA256_HMAC
RTE_CRYPTO_AUTH_SHA384_HMAC
RTE_CRYPTO_AUTH_SHA512_HMAC

Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com>
---
v3:
- change description
---
 examples/l2fwd-crypto/main.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 0593734..dae45f5 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -340,15 +340,22 @@ fill_supported_algorithm_tables(void)
 		strcpy(supported_auth_algo[i], "NOT_SUPPORTED");
 
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GCM], "AES_GCM");
+	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_GMAC], "AES_GMAC");
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5_HMAC], "MD5_HMAC");
+	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_MD5], "MD5");
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_NULL], "NULL");
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_AES_XCBC_MAC],
 		"AES_XCBC_MAC");
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1_HMAC], "SHA1_HMAC");
+	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA1], "SHA1");
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224_HMAC], "SHA224_HMAC");
+	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA224], "SHA224");
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256_HMAC], "SHA256_HMAC");
+	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA256], "SHA256");
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384_HMAC], "SHA384_HMAC");
+	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA384], "SHA384");
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512_HMAC], "SHA512_HMAC");
+	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SHA512], "SHA512");
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_SNOW3G_UIA2], "SNOW3G_UIA2");
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_ZUC_EIA3], "ZUC_EIA3");
 	strcpy(supported_auth_algo[RTE_CRYPTO_AUTH_KASUMI_F9], "KASUMI_F9");
@@ -363,6 +370,8 @@ fill_supported_algorithm_tables(void)
 	strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_SNOW3G_UEA2], "SNOW3G_UEA2");
 	strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_ZUC_EEA3], "ZUC_EEA3");
 	strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_KASUMI_F8], "KASUMI_F8");
+	strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CTR], "3DES_CTR");
+	strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_3DES_CBC], "3DES_CBC");
 }
 
 
-- 
2.5.0

^ permalink raw reply related

* Re: [PATCH 1/1 v2] eal: Fix misleading error messages, errno can't be trusted.
From: Sergio Gonzalez Monroy @ 2016-10-03 13:25 UTC (permalink / raw)
  To: jean.tourrilhes, dev
In-Reply-To: <20160921211049.GA27472@labs.hpe.com>

Hi Jean,

There are some format issues with the patch:

You can run scripts/check-git-log.sh to check them:
Wrong headline format:
         eal: Fix misleading error messages, errno can't be trusted.
Wrong headline uppercase:
         eal: Fix misleading error messages, errno can't be trusted.
Missing 'Fixes' tag:
         eal: Fix misleading error messages, errno can't be trusted.

The script's output highlights the different issues.


On 21/09/2016 22:10, Jean Tourrilhes wrote:
>   lib/librte_eal/linuxapp/eal/eal.c        | 14 +++++++++++---
>   lib/librte_eal/linuxapp/eal/eal_memory.c | 16 ++++++++++++----
>   2 files changed, 23 insertions(+), 7 deletions(-)
>
> diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
> index 3fb2188..5df9f6a 100644
> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -238,7 +238,8 @@ rte_eal_config_attach(void)
>   	mem_config = (struct rte_mem_config *) mmap(NULL, sizeof(*mem_config),
>   			PROT_READ, MAP_SHARED, mem_cfg_fd, 0);
>   	if (mem_config == MAP_FAILED)
> -		rte_panic("Cannot mmap memory for rte_config\n");
> +		rte_panic("Cannot mmap memory for rte_config! error %i (%s)\n",
> +			  errno, strerror(errno));
>   
>   	rte_config.mem_config = mem_config;
>   }
> @@ -263,9 +264,16 @@ rte_eal_config_reattach(void)
>   	mem_config = (struct rte_mem_config *) mmap(rte_mem_cfg_addr,
>   			sizeof(*mem_config), PROT_READ | PROT_WRITE, MAP_SHARED,
>   			mem_cfg_fd, 0);
> +	if (mem_config == MAP_FAILED || mem_config != rte_mem_cfg_addr) {
> +		if (mem_config != MAP_FAILED)
> +			/* errno is stale, don't use */
> +			rte_panic("Cannot mmap memory for rte_config at [%p], got [%p] - please use '--base-virtaddr' option\n",
> +				  rte_mem_cfg_addr, mem_config);
> +		else
> +			rte_panic("Cannot mmap memory for rte_config! error %i (%s)\n",
> +				  errno, strerror(errno));
> +	}
>   	close(mem_cfg_fd);
> -	if (mem_config == MAP_FAILED || mem_config != rte_mem_cfg_addr)
> -		rte_panic("Cannot mmap memory for rte_config\n");
>   

NIT but any reason you moved the check before closing the file 
descriptor? (not that it matters with current code as we panic anyway)

Thanks,
Sergio

>   	rte_config.mem_config = mem_config;
>   }
> diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
> index 41e0a92..b036ffc 100644
> --- a/lib/librte_eal/linuxapp/eal/eal_memory.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
> @@ -1615,10 +1615,18 @@ rte_eal_hugepage_attach(void)
>   				 PROT_READ, MAP_PRIVATE, fd_zero, 0);
>   		if (base_addr == MAP_FAILED ||
>   		    base_addr != mcfg->memseg[s].addr) {
> -			RTE_LOG(ERR, EAL, "Could not mmap %llu bytes "
> -				"in /dev/zero to requested address [%p]: '%s'\n",
> -				(unsigned long long)mcfg->memseg[s].len,
> -				mcfg->memseg[s].addr, strerror(errno));
> +			if (base_addr != MAP_FAILED)
> +				/* errno is stale, don't use */
> +				RTE_LOG(ERR, EAL, "Could not mmap %llu bytes "
> +					"in /dev/zero at [%p], got [%p] - "
> +					"please use '--base-virtaddr' option\n",
> +					(unsigned long long)mcfg->memseg[s].len,
> +					mcfg->memseg[s].addr, base_addr);
> +			else
> +				RTE_LOG(ERR, EAL, "Could not mmap %llu bytes "
> +					"in /dev/zero at [%p]: '%s'\n",
> +					(unsigned long long)mcfg->memseg[s].len,
> +					mcfg->memseg[s].addr, strerror(errno));
>   			if (aslr_enabled() > 0) {
>   				RTE_LOG(ERR, EAL, "It is recommended to "
>   					"disable ASLR in the kernel "

^ permalink raw reply

* [PATCH v5 3/4] app/test: added tests for libcrypto PMD
From: Slawomir Mrozowicz @ 2016-10-03 15:17 UTC (permalink / raw)
  To: dev; +Cc: Slawomir Mrozowicz, Piotr Azarewicz, Marcin Kerlin,
	Daniel Mrzyglod
In-Reply-To: <1475504792-31557-1-git-send-email-slawomirx.mrozowicz@intel.com>

This patch containes unit tests for libcrypto PMD. User can
use app/test application to check how to use this pmd and to
verify crypto processing.

Test name is cryptodev_libcrypto_autotest.
For performance test cryptodev_libcrypto_perftest can be used.

Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com>
Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com>
---
v2:
- rename AES-named functions to blockcipher
- replace different test cases with blockcipher functions pattern
- add 3DES tests into QuickAssist PMD testsuite

v3:
- add nagative verification tests
- add big data test

v4:
- move aes test rework to another patch
- move big data test to another patch
- checking if libcrypto pmd is available

v5:
- add reduced big data test
---
 app/test/test_cryptodev.c                   | 1495 +++++++++++++++++++++++++--
 app/test/test_cryptodev.h                   |    1 +
 app/test/test_cryptodev_aes_test_vectors.h  |  304 +++++-
 app/test/test_cryptodev_blockcipher.c       |   22 +
 app/test/test_cryptodev_blockcipher.h       |    1 +
 app/test/test_cryptodev_des_test_vectors.h  |  952 +++++++++++++++++
 app/test/test_cryptodev_gcm_test_vectors.h  |   36 +-
 app/test/test_cryptodev_hash_test_vectors.h |  491 +++++++++
 app/test/test_cryptodev_perf.c              |  689 +++++++++++-
 9 files changed, 3911 insertions(+), 80 deletions(-)
 create mode 100644 app/test/test_cryptodev_des_test_vectors.h
 create mode 100644 app/test/test_cryptodev_hash_test_vectors.h

diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index c46db94..54982d2 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -45,6 +45,8 @@
 
 #include "test_cryptodev_blockcipher.h"
 #include "test_cryptodev_aes_test_vectors.h"
+#include "test_cryptodev_des_test_vectors.h"
+#include "test_cryptodev_hash_test_vectors.h"
 #include "test_cryptodev_kasumi_test_vectors.h"
 #include "test_cryptodev_kasumi_hash_test_vectors.h"
 #include "test_cryptodev_snow3g_test_vectors.h"
@@ -167,7 +169,7 @@ testsuite_setup(void)
 		/* Not already created so create */
 		ts_params->mbuf_pool = rte_pktmbuf_pool_create(
 				"CRYPTO_MBUFPOOL",
-				NUM_MBUFS, MBUF_CACHE_SIZE, 0, MBUF_SIZE,
+				NUM_MBUFS, MBUF_CACHE_SIZE, 0, UINT16_MAX,
 				rte_socket_id());
 		if (ts_params->mbuf_pool == NULL) {
 			RTE_LOG(ERR, USER1, "Can't create CRYPTO_MBUFPOOL\n");
@@ -308,6 +310,26 @@ testsuite_setup(void)
 		}
 	}
 
+	/* Create 2 LIBCRYPTO devices if required */
+	if (gbl_cryptodev_type == RTE_CRYPTODEV_LIBCRYPTO_PMD) {
+#ifndef RTE_LIBRTE_PMD_LIBCRYPTO
+		RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO must be"
+			" enabled in config file to run this testsuite.\n");
+		return TEST_FAILED;
+#endif
+		nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_LIBCRYPTO_PMD);
+		if (nb_devs < 2) {
+			for (i = nb_devs; i < 2; i++) {
+				ret = rte_eal_vdev_init(
+					RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), NULL);
+
+				TEST_ASSERT(ret == 0,
+					"Failed to create instance %u of pmd : %s",
+					i, RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD));
+			}
+		}
+	}
+
 #ifndef RTE_LIBRTE_PMD_QAT
 	if (gbl_cryptodev_type == RTE_CRYPTODEV_QAT_SYM_PMD) {
 		RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled "
@@ -877,6 +899,315 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = {
 	0x18, 0x8c, 0x1d, 0x32
 };
 
+
+/* Multisession Vector context Test */
+/*Begin Session 0 */
+static uint8_t ms_aes_cbc_key0[] = {
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+static uint8_t ms_aes_cbc_iv0[] = {
+	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+static const uint8_t ms_aes_cbc_cipher0[] = {
+		0x3C, 0xE4, 0xEE, 0x42, 0xB6, 0x9B, 0xC3, 0x38,
+		0x5F, 0xAD, 0x54, 0xDC, 0xA8, 0x32, 0x81, 0xDC,
+		0x7A, 0x6F, 0x85, 0x58, 0x07, 0x35, 0xED, 0xEB,
+		0xAD, 0x79, 0x79, 0x96, 0xD3, 0x0E, 0xA6, 0xD9,
+		0xAA, 0x86, 0xA4, 0x8F, 0xB5, 0xD6, 0x6E, 0x6D,
+		0x0C, 0x91, 0x2F, 0xC4, 0x67, 0x98, 0x0E, 0xC4,
+		0x8D, 0x83, 0x68, 0x69, 0xC4, 0xD3, 0x94, 0x34,
+		0xC4, 0x5D, 0x60, 0x55, 0x22, 0x87, 0x8F, 0x6F,
+		0x17, 0x8E, 0x75, 0xE4, 0x02, 0xF5, 0x1B, 0x99,
+		0xC8, 0x39, 0xA9, 0xAB, 0x23, 0x91, 0x12, 0xED,
+		0x08, 0xE7, 0xD9, 0x25, 0x89, 0x24, 0x4F, 0x8D,
+		0x68, 0xF3, 0x10, 0x39, 0x0A, 0xEE, 0x45, 0x24,
+		0xDF, 0x7A, 0x9D, 0x00, 0x25, 0xE5, 0x35, 0x71,
+		0x4E, 0x40, 0x59, 0x6F, 0x0A, 0x13, 0xB3, 0x72,
+		0x1D, 0x98, 0x63, 0x94, 0x89, 0xA5, 0x39, 0x8E,
+		0xD3, 0x9C, 0x8A, 0x7F, 0x71, 0x2F, 0xC7, 0xCD,
+		0x81, 0x05, 0xDC, 0xC0, 0x8D, 0xCE, 0x6D, 0x18,
+		0x30, 0xC4, 0x72, 0x51, 0xF0, 0x27, 0xC8, 0xF6,
+		0x60, 0x5B, 0x7C, 0xB2, 0xE3, 0x49, 0x0C, 0x29,
+		0xC6, 0x9F, 0x39, 0x57, 0x80, 0x55, 0x24, 0x2C,
+		0x9B, 0x0F, 0x5A, 0xB3, 0x89, 0x55, 0x31, 0x96,
+		0x0D, 0xCD, 0xF6, 0x51, 0x03, 0x2D, 0x89, 0x26,
+		0x74, 0x44, 0xD6, 0xE8, 0xDC, 0xEA, 0x44, 0x55,
+		0x64, 0x71, 0x9C, 0x9F, 0x5D, 0xBA, 0x39, 0x46,
+		0xA8, 0x17, 0xA1, 0x9C, 0x52, 0x9D, 0xBC, 0x6B,
+		0x4A, 0x98, 0xE6, 0xEA, 0x33, 0xEC, 0x58, 0xB4,
+		0x43, 0xF0, 0x32, 0x45, 0xA4, 0xC1, 0x55, 0xB7,
+		0x5D, 0xB5, 0x59, 0xB2, 0xE3, 0x96, 0xFF, 0xA5,
+		0xAF, 0xE1, 0x86, 0x1B, 0x42, 0xE6, 0x3B, 0xA0,
+		0x90, 0x4A, 0xE8, 0x8C, 0x21, 0x7F, 0x36, 0x1E,
+		0x5B, 0x65, 0x25, 0xD1, 0xC1, 0x5A, 0xCA, 0x3D,
+		0x10, 0xED, 0x2D, 0x79, 0xD0, 0x0F, 0x58, 0x44,
+		0x69, 0x81, 0xF5, 0xD4, 0xC9, 0x0F, 0x90, 0x76,
+		0x1F, 0x54, 0xD2, 0xD5, 0x97, 0xCE, 0x2C, 0xE3,
+		0xEF, 0xF4, 0xB7, 0xC6, 0x3A, 0x87, 0x7F, 0x83,
+		0x2A, 0xAF, 0xCD, 0x90, 0x12, 0xA7, 0x7D, 0x85,
+		0x1D, 0x62, 0xD3, 0x85, 0x25, 0x05, 0xDB, 0x45,
+		0x92, 0xA3, 0xF6, 0xA2, 0xA8, 0x41, 0xE4, 0x25,
+		0x86, 0x87, 0x67, 0x24, 0xEC, 0x89, 0x23, 0x2A,
+		0x9B, 0x20, 0x4D, 0x93, 0xEE, 0xE2, 0x2E, 0xC1,
+		0x0B, 0x15, 0x33, 0xCF, 0x00, 0xD1, 0x1A, 0xDA,
+		0x93, 0xFD, 0x28, 0x21, 0x5B, 0xCF, 0xD1, 0xF3,
+		0x5A, 0x81, 0xBA, 0x82, 0x5E, 0x2F, 0x61, 0xB4,
+		0x05, 0x71, 0xB5, 0xF4, 0x39, 0x3C, 0x1F, 0x60,
+		0x00, 0x7A, 0xC4, 0xF8, 0x35, 0x20, 0x6C, 0x3A,
+		0xCC, 0x03, 0x8F, 0x7B, 0xA2, 0xB6, 0x65, 0x8A,
+		0xB6, 0x5F, 0xFD, 0x25, 0xD3, 0x5F, 0x92, 0xF9,
+		0xAE, 0x17, 0x9B, 0x5E, 0x6E, 0x9A, 0xE4, 0x55,
+		0x10, 0x25, 0x07, 0xA4, 0xAF, 0x21, 0x69, 0x13,
+		0xD8, 0xFA, 0x31, 0xED, 0xF7, 0xA7, 0xA7, 0x3B,
+		0xB8, 0x96, 0x8E, 0x10, 0x86, 0x74, 0xD8, 0xB1,
+		0x34, 0x9E, 0x9B, 0x6A, 0x26, 0xA8, 0xD4, 0xD0,
+		0xB5, 0xF6, 0xDE, 0xE7, 0xCA, 0x06, 0xDC, 0xA3,
+		0x6F, 0xEE, 0x6B, 0x1E, 0xB5, 0x30, 0x99, 0x23,
+		0xF9, 0x76, 0xF0, 0xA0, 0xCF, 0x3B, 0x94, 0x7B,
+		0x19, 0x8D, 0xA5, 0x0C, 0x18, 0xA6, 0x1D, 0x07,
+		0x89, 0xBE, 0x5B, 0x61, 0xE5, 0xF1, 0x42, 0xDB,
+		0xD4, 0x2E, 0x02, 0x1F, 0xCE, 0xEF, 0x92, 0xB1,
+		0x1B, 0x56, 0x50, 0xF2, 0x16, 0xE5, 0xE7, 0x4F,
+		0xFD, 0xBB, 0x3E, 0xD2, 0xFC, 0x3C, 0xC6, 0x0F,
+		0xF9, 0x12, 0x4E, 0xCB, 0x1E, 0x0C, 0x15, 0x84,
+		0x2A, 0x14, 0x8A, 0x02, 0xE4, 0x7E, 0x95, 0x5B,
+		0x86, 0xDB, 0x9B, 0x62, 0x5B, 0x19, 0xD2, 0x17,
+		0xFA, 0x13, 0xBB, 0x6B, 0x3F, 0x45, 0x9F, 0xBF
+};
+
+
+static  uint8_t ms_hmac_key0[] = {
+		0xFF, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+		0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
+		0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76,
+		0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60,
+		0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1,
+		0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0,
+		0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76,
+		0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60
+};
+
+static const uint8_t ms_hmac_digest0[] = {
+		0x43, 0x52, 0xED, 0x34, 0xAB, 0x36, 0xB2, 0x51,
+		0xFB, 0xA3, 0xA6, 0x7C, 0x38, 0xFC, 0x42, 0x8F,
+		0x57, 0x64, 0xAB, 0x81, 0xA7, 0x89, 0xB7, 0x6C,
+		0xA0, 0xDC, 0xB9, 0x4D, 0xC4, 0x30, 0xF9, 0xD4,
+		0x10, 0x82, 0x55, 0xD0, 0xAB, 0x32, 0xFB, 0x56,
+		0x0D, 0xE4, 0x68, 0x3D, 0x76, 0xD0, 0x7B, 0xE4,
+		0xA6, 0x2C, 0x34, 0x9E, 0x8C, 0x41, 0xF8, 0x23,
+		0x28, 0x1B, 0x3A, 0x90, 0x26, 0x34, 0x47, 0x90
+		};
+
+/* End Session 0 */
+/* Begin session 1 */
+
+static  uint8_t ms_aes_cbc_key1[] = {
+		0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+		0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+static  uint8_t ms_aes_cbc_iv1[] = {
+	0xf1, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+	0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+static const uint8_t ms_aes_cbc_cipher1[] = {
+		0x5A, 0x7A, 0x67, 0x5D, 0xB8, 0xE1, 0xDC, 0x71,
+		0x39, 0xA8, 0x74, 0x93, 0x9C, 0x4C, 0xFE, 0x23,
+		0x61, 0xCD, 0xA4, 0xB3, 0xD9, 0xCE, 0x99, 0x09,
+		0x2A, 0x23, 0xF3, 0x29, 0xBF, 0x4C, 0xB4, 0x6A,
+		0x1B, 0x6B, 0x73, 0x4D, 0x48, 0x0C, 0xCF, 0x6C,
+		0x5E, 0x34, 0x9E, 0x7F, 0xBC, 0x8F, 0xCC, 0x8F,
+		0x75, 0x1D, 0x3D, 0x77, 0x10, 0x76, 0xC8, 0xB9,
+		0x99, 0x6F, 0xD6, 0x56, 0x75, 0xA9, 0xB2, 0x66,
+		0xC2, 0x24, 0x2B, 0x9C, 0xFE, 0x40, 0x8E, 0x43,
+		0x20, 0x97, 0x1B, 0xFA, 0xD0, 0xCF, 0x04, 0xAB,
+		0xBB, 0xF6, 0x5D, 0xF5, 0xA0, 0x19, 0x7C, 0x23,
+		0x5D, 0x80, 0x8C, 0x49, 0xF6, 0x76, 0x88, 0x29,
+		0x27, 0x4C, 0x59, 0x2B, 0x43, 0xA6, 0xB2, 0x26,
+		0x27, 0x78, 0xBE, 0x1B, 0xE1, 0x4F, 0x5A, 0x1F,
+		0xFC, 0x68, 0x08, 0xE7, 0xC4, 0xD1, 0x34, 0x68,
+		0xB7, 0x13, 0x14, 0x41, 0x62, 0x6B, 0x1F, 0x77,
+		0x0C, 0x68, 0x1D, 0x0D, 0xED, 0x89, 0xAA, 0xD8,
+		0x97, 0x02, 0xBA, 0x5E, 0xD4, 0x84, 0x25, 0x97,
+		0x03, 0xA5, 0xA6, 0x13, 0x66, 0x02, 0xF4, 0xC3,
+		0xF3, 0xD3, 0xCC, 0x95, 0xC3, 0x87, 0x46, 0x90,
+		0x1F, 0x6E, 0x14, 0xA8, 0x00, 0xF2, 0x6F, 0xD5,
+		0xA1, 0xAD, 0xD5, 0x40, 0xA2, 0x0F, 0x32, 0x7E,
+		0x99, 0xA3, 0xF5, 0x53, 0xC3, 0x26, 0xA1, 0x45,
+		0x01, 0x88, 0x57, 0x84, 0x3E, 0x7B, 0x4E, 0x0B,
+		0x3C, 0xB5, 0x3E, 0x9E, 0xE9, 0x78, 0x77, 0xC5,
+		0xC0, 0x89, 0xA8, 0xF8, 0xF1, 0xA5, 0x2D, 0x5D,
+		0xF9, 0xC6, 0xFB, 0xCB, 0x05, 0x23, 0xBD, 0x6E,
+		0x5E, 0x14, 0xC6, 0x57, 0x73, 0xCF, 0x98, 0xBD,
+		0x10, 0x8B, 0x18, 0xA6, 0x01, 0x5B, 0x13, 0xAE,
+		0x8E, 0xDE, 0x1F, 0xB5, 0xB7, 0x40, 0x6C, 0xC1,
+		0x1E, 0xA1, 0x19, 0x20, 0x9E, 0x95, 0xE0, 0x2F,
+		0x1C, 0xF5, 0xD9, 0xD0, 0x2B, 0x1E, 0x82, 0x25,
+		0x62, 0xB4, 0xEB, 0xA1, 0x1F, 0xCE, 0x44, 0xA1,
+		0xCB, 0x92, 0x01, 0x6B, 0xE4, 0x26, 0x23, 0xE3,
+		0xC5, 0x67, 0x35, 0x55, 0xDA, 0xE5, 0x27, 0xEE,
+		0x8D, 0x12, 0x84, 0xB7, 0xBA, 0xA7, 0x1C, 0xD6,
+		0x32, 0x3F, 0x67, 0xED, 0xFB, 0x5B, 0x8B, 0x52,
+		0x46, 0x8C, 0xF9, 0x69, 0xCD, 0xAE, 0x79, 0xAA,
+		0x37, 0x78, 0x49, 0xEB, 0xC6, 0x8E, 0x76, 0x63,
+		0x84, 0xFF, 0x9D, 0x22, 0x99, 0x51, 0xB7, 0x5E,
+		0x83, 0x4C, 0x8B, 0xDF, 0x5A, 0x07, 0xCC, 0xBA,
+		0x42, 0xA5, 0x98, 0xB6, 0x47, 0x0E, 0x66, 0xEB,
+		0x23, 0x0E, 0xBA, 0x44, 0xA8, 0xAA, 0x20, 0x71,
+		0x79, 0x9C, 0x77, 0x5F, 0xF5, 0xFE, 0xEC, 0xEF,
+		0xC6, 0x64, 0x3D, 0x84, 0xD0, 0x2B, 0xA7, 0x0A,
+		0xC3, 0x72, 0x5B, 0x9C, 0xFA, 0xA8, 0x87, 0x95,
+		0x94, 0x11, 0x38, 0xA7, 0x1E, 0x58, 0xE3, 0x73,
+		0xC6, 0xC9, 0xD1, 0x7B, 0x92, 0xDB, 0x0F, 0x49,
+		0x74, 0xC2, 0xA2, 0x0E, 0x35, 0x57, 0xAC, 0xDB,
+		0x9A, 0x1C, 0xCF, 0x5A, 0x32, 0x3E, 0x26, 0x9B,
+		0xEC, 0xB3, 0xEF, 0x9C, 0xFE, 0xBE, 0x52, 0xAC,
+		0xB1, 0x29, 0xDD, 0xFD, 0x07, 0xE2, 0xEE, 0xED,
+		0xE4, 0x46, 0x37, 0xFE, 0xD1, 0xDC, 0xCD, 0x02,
+		0xF9, 0x31, 0xB0, 0xFB, 0x36, 0xB7, 0x34, 0xA4,
+		0x76, 0xE8, 0x57, 0xBF, 0x99, 0x92, 0xC7, 0xAF,
+		0x98, 0x10, 0xE2, 0x70, 0xCA, 0xC9, 0x2B, 0x82,
+		0x06, 0x96, 0x88, 0x0D, 0xB3, 0xAC, 0x9E, 0x6D,
+		0x43, 0xBC, 0x5B, 0x31, 0xCF, 0x65, 0x8D, 0xA6,
+		0xC7, 0xFE, 0x73, 0xE1, 0x54, 0xF7, 0x10, 0xF9,
+		0x86, 0xF7, 0xDF, 0xA1, 0xA1, 0xD8, 0xAE, 0x35,
+		0xB3, 0x90, 0xDC, 0x6F, 0x43, 0x7A, 0x8B, 0xE0,
+		0xFE, 0x8F, 0x33, 0x4D, 0x29, 0x6C, 0x45, 0x53,
+		0x73, 0xDD, 0x21, 0x0B, 0x85, 0x30, 0xB5, 0xA5,
+		0xF3, 0x5D, 0xEC, 0x79, 0x61, 0x9D, 0x9E, 0xB3
+
+};
+
+static uint8_t ms_hmac_key1[] = {
+		0xFE, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+		0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
+		0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76,
+		0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60,
+		0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1,
+		0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0,
+		0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76,
+		0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60
+};
+
+static const uint8_t ms_hmac_digest1[] = {
+		0xCE, 0x6E, 0x5F, 0x77, 0x96, 0x9A, 0xB1, 0x69,
+		0x2D, 0x5E, 0xF3, 0x2F, 0x32, 0x10, 0xCB, 0x50,
+		0x0E, 0x09, 0x56, 0x25, 0x07, 0x34, 0xC9, 0x20,
+		0xEC, 0x13, 0x43, 0x23, 0x5C, 0x08, 0x8B, 0xCD,
+		0xDC, 0x86, 0x8C, 0xEE, 0x0A, 0x95, 0x2E, 0xB9,
+		0x8C, 0x7B, 0x02, 0x7A, 0xD4, 0xE1, 0x49, 0xB4,
+		0x45, 0xB5, 0x52, 0x37, 0xC6, 0xFF, 0xFE, 0xAA,
+		0x0A, 0x87, 0xB8, 0x51, 0xF9, 0x2A, 0x01, 0x8F
+};
+/* End Session 1  */
+/* Begin Session 2 */
+static  uint8_t ms_aes_cbc_key2[] = {
+		0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+		0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+static  uint8_t ms_aes_cbc_iv2[] = {
+		0xff, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+		0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+static const uint8_t ms_aes_cbc_cipher2[] = {
+		0xBB, 0x3C, 0x68, 0x25, 0xFD, 0xB6, 0xA2, 0x91,
+		0x20, 0x56, 0xF6, 0x30, 0x35, 0xFC, 0x9E, 0x97,
+		0xF2, 0x90, 0xFC, 0x7E, 0x3E, 0x0A, 0x75, 0xC8,
+		0x4C, 0xF2, 0x2D, 0xAC, 0xD3, 0x93, 0xF0, 0xC5,
+		0x14, 0x88, 0x8A, 0x23, 0xC2, 0x59, 0x9A, 0x98,
+		0x4B, 0xD5, 0x2C, 0xDA, 0x43, 0xA9, 0x34, 0x69,
+		0x7C, 0x6D, 0xDB, 0xDC, 0xCB, 0xC0, 0xA0, 0x09,
+		0xA7, 0x86, 0x16, 0x4B, 0xBF, 0xA8, 0xB6, 0xCF,
+		0x7F, 0x74, 0x1F, 0x22, 0xF0, 0xF6, 0xBB, 0x44,
+		0x8B, 0x4C, 0x9E, 0x23, 0xF8, 0x9F, 0xFC, 0x5B,
+		0x9E, 0x9C, 0x2A, 0x79, 0x30, 0x8F, 0xBF, 0xA9,
+		0x68, 0xA1, 0x20, 0x71, 0x7C, 0x77, 0x22, 0x34,
+		0x07, 0xCD, 0xC6, 0xF6, 0x50, 0x0A, 0x08, 0x99,
+		0x17, 0x98, 0xE3, 0x93, 0x8A, 0xB0, 0xEE, 0xDF,
+		0xC2, 0xBA, 0x3B, 0x44, 0x73, 0xDF, 0xDD, 0xDC,
+		0x14, 0x4D, 0x3B, 0xBB, 0x5E, 0x58, 0xC1, 0x26,
+		0xA7, 0xAE, 0x47, 0xF3, 0x24, 0x6D, 0x4F, 0xD3,
+		0x6E, 0x3E, 0x33, 0xE6, 0x7F, 0xCA, 0x50, 0xAF,
+		0x5D, 0x3D, 0xA0, 0xDD, 0xC9, 0xF3, 0x30, 0xD3,
+		0x6E, 0x8B, 0x2E, 0x12, 0x24, 0x34, 0xF0, 0xD3,
+		0xC7, 0x8D, 0x23, 0x29, 0xAA, 0x05, 0xE1, 0xFA,
+		0x2E, 0xF6, 0x8D, 0x37, 0x86, 0xC0, 0x6D, 0x13,
+		0x2D, 0x98, 0xF3, 0x52, 0x39, 0x22, 0xCE, 0x38,
+		0xC2, 0x1A, 0x72, 0xED, 0xFB, 0xCC, 0xE4, 0x71,
+		0x5A, 0x0C, 0x0D, 0x09, 0xF8, 0xE8, 0x1B, 0xBC,
+		0x53, 0xC8, 0xD8, 0x8F, 0xE5, 0x98, 0x5A, 0xB1,
+		0x06, 0xA6, 0x5B, 0xE6, 0xA2, 0x88, 0x21, 0x9E,
+		0x36, 0xC0, 0x34, 0xF9, 0xFB, 0x3B, 0x0A, 0x22,
+		0x00, 0x00, 0x39, 0x48, 0x8D, 0x23, 0x74, 0x62,
+		0x72, 0x91, 0xE6, 0x36, 0xAA, 0x77, 0x9C, 0x72,
+		0x9D, 0xA8, 0xC3, 0xA9, 0xD5, 0x44, 0x72, 0xA6,
+		0xB9, 0x28, 0x8F, 0x64, 0x4C, 0x8A, 0x64, 0xE6,
+		0x4E, 0xFA, 0xEF, 0x87, 0xDE, 0x7B, 0x22, 0x44,
+		0xB0, 0xDF, 0x2E, 0x5F, 0x0B, 0xA5, 0xF2, 0x24,
+		0x07, 0x5C, 0x2D, 0x39, 0xB7, 0x3D, 0x8A, 0xE5,
+		0x0E, 0x9D, 0x4E, 0x50, 0xED, 0x03, 0x99, 0x8E,
+		0xF0, 0x06, 0x55, 0x4E, 0xA2, 0x24, 0xE7, 0x17,
+		0x46, 0xDF, 0x6C, 0xCD, 0xC6, 0x44, 0xE8, 0xF9,
+		0xB9, 0x1B, 0x36, 0xF6, 0x7F, 0x10, 0xA4, 0x7D,
+		0x90, 0xBD, 0xE4, 0xAA, 0xD6, 0x9E, 0x18, 0x9D,
+		0x22, 0x35, 0xD6, 0x55, 0x54, 0xAA, 0xF7, 0x22,
+		0xA3, 0x3E, 0xEF, 0xC8, 0xA2, 0x34, 0x8D, 0xA9,
+		0x37, 0x63, 0xA6, 0xC3, 0x57, 0xCB, 0x0C, 0x49,
+		0x7D, 0x02, 0xBE, 0xAA, 0x13, 0x75, 0xB7, 0x4E,
+		0x52, 0x62, 0xA5, 0xC2, 0x33, 0xC7, 0x6C, 0x1B,
+		0xF6, 0x34, 0xF6, 0x09, 0xA5, 0x0C, 0xC7, 0xA2,
+		0x61, 0x48, 0x62, 0x7D, 0x17, 0x15, 0xE3, 0x95,
+		0xC8, 0x63, 0xD2, 0xA4, 0x43, 0xA9, 0x49, 0x07,
+		0xB2, 0x3B, 0x2B, 0x62, 0x7D, 0xCB, 0x51, 0xB3,
+		0x25, 0x33, 0x47, 0x0E, 0x14, 0x67, 0xDC, 0x6A,
+		0x9B, 0x51, 0xAC, 0x9D, 0x8F, 0xA2, 0x2B, 0x57,
+		0x8C, 0x5C, 0x5F, 0x76, 0x23, 0x92, 0x0F, 0x84,
+		0x46, 0x0E, 0x40, 0x85, 0x38, 0x60, 0xFA, 0x61,
+		0x20, 0xC5, 0xE3, 0xF1, 0x70, 0xAC, 0x1B, 0xBF,
+		0xC4, 0x2B, 0xC5, 0x67, 0xD1, 0x43, 0xC5, 0x17,
+		0x74, 0x71, 0x69, 0x6F, 0x82, 0x89, 0x19, 0x8A,
+		0x70, 0x43, 0x92, 0x01, 0xC4, 0x63, 0x7E, 0xB1,
+		0x59, 0x4E, 0xCD, 0xEA, 0x93, 0xA4, 0x52, 0x53,
+		0x9B, 0x61, 0x5B, 0xD2, 0x3E, 0x19, 0x39, 0xB7,
+		0x32, 0xEA, 0x8E, 0xF8, 0x1D, 0x76, 0x5C, 0xB2,
+		0x73, 0x2D, 0x91, 0xC0, 0x18, 0xED, 0x25, 0x2A,
+		0x53, 0x64, 0xF0, 0x92, 0x31, 0x55, 0x21, 0xA8,
+		0x24, 0xA9, 0xD1, 0x02, 0xF6, 0x6C, 0x2B, 0x70,
+		0xA9, 0x59, 0xC1, 0xD6, 0xC3, 0x57, 0x5B, 0x92
+};
+
+static  uint8_t ms_hmac_key2[] = {
+		0xFC, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+		0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
+		0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76,
+		0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60,
+		0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1,
+		0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0,
+		0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76,
+		0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60
+};
+
+static const uint8_t ms_hmac_digest2[] = {
+		0xA5, 0x0F, 0x9C, 0xFB, 0x08, 0x62, 0x59, 0xFF,
+		0x80, 0x2F, 0xEB, 0x4B, 0xE1, 0x46, 0x21, 0xD6,
+		0x02, 0x98, 0xF2, 0x8E, 0xF4, 0xEC, 0xD4, 0x77,
+		0x86, 0x4C, 0x31, 0x28, 0xC8, 0x25, 0x80, 0x27,
+		0x3A, 0x72, 0x5D, 0x6A, 0x56, 0x8A, 0xD3, 0x82,
+		0xB0, 0xEC, 0x31, 0x6D, 0x8B, 0x6B, 0xB4, 0x24,
+		0xE7, 0x62, 0xC1, 0x52, 0xBC, 0x14, 0x1B, 0x8E,
+		0xEC, 0x9A, 0xF1, 0x47, 0x80, 0xD2, 0xB0, 0x59
+};
+
+/* End Session 2 */
+
+
 static int
 test_AES_CBC_HMAC_SHA1_encrypt_digest(void)
 {
@@ -1145,6 +1476,38 @@ test_AES_chain_mb_all(void)
 }
 
 static int
+test_AES_chain_libcrypto_all(void)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	int status;
+
+	status = test_blockcipher_all_tests(ts_params->mbuf_pool,
+		ts_params->op_mpool, ts_params->valid_devs[0],
+		RTE_CRYPTODEV_LIBCRYPTO_PMD,
+		BLKCIPHER_AES_CHAIN_TYPE);
+
+	TEST_ASSERT_EQUAL(status, 0, "Test failed");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_AES_cipheronly_libcrypto_all(void)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	int status;
+
+	status = test_blockcipher_all_tests(ts_params->mbuf_pool,
+		ts_params->op_mpool, ts_params->valid_devs[0],
+		RTE_CRYPTODEV_LIBCRYPTO_PMD,
+		BLKCIPHER_AES_CIPHERONLY_TYPE);
+
+	TEST_ASSERT_EQUAL(status, 0, "Test failed");
+
+	return TEST_SUCCESS;
+}
+
+static int
 test_AES_chain_qat_all(void)
 {
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
@@ -1160,6 +1523,22 @@ test_AES_chain_qat_all(void)
 	return TEST_SUCCESS;
 }
 
+static int
+test_authonly_libcrypto_all(void)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	int status;
+
+	status = test_blockcipher_all_tests(ts_params->mbuf_pool,
+		ts_params->op_mpool, ts_params->valid_devs[0],
+		RTE_CRYPTODEV_LIBCRYPTO_PMD,
+		BLKCIPHER_AUTHONLY_TYPE);
+
+	TEST_ASSERT_EQUAL(status, 0, "Test failed");
+
+	return TEST_SUCCESS;
+}
+
 /* ***** SNOW 3G Tests ***** */
 static int
 create_wireless_algo_hash_session(uint8_t dev_id,
@@ -3411,6 +3790,70 @@ test_zuc_hash_generate_test_case_5(void)
 	return test_zuc_authentication(&zuc_hash_test_case_5);
 }
 
+static int
+test_3DES_chain_qat_all(void)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	int status;
+
+	status = test_blockcipher_all_tests(ts_params->mbuf_pool,
+		ts_params->op_mpool, ts_params->valid_devs[0],
+		RTE_CRYPTODEV_QAT_SYM_PMD,
+		BLKCIPHER_3DES_CHAIN_TYPE);
+
+	TEST_ASSERT_EQUAL(status, 0, "Test failed");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_3DES_cipheronly_qat_all(void)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	int status;
+
+	status = test_blockcipher_all_tests(ts_params->mbuf_pool,
+		ts_params->op_mpool, ts_params->valid_devs[0],
+		RTE_CRYPTODEV_QAT_SYM_PMD,
+		BLKCIPHER_3DES_CIPHERONLY_TYPE);
+
+	TEST_ASSERT_EQUAL(status, 0, "Test failed");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_3DES_chain_libcrypto_all(void)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	int status;
+
+	status = test_blockcipher_all_tests(ts_params->mbuf_pool,
+		ts_params->op_mpool, ts_params->valid_devs[0],
+		RTE_CRYPTODEV_LIBCRYPTO_PMD,
+		BLKCIPHER_3DES_CHAIN_TYPE);
+
+	TEST_ASSERT_EQUAL(status, 0, "Test failed");
+
+	return TEST_SUCCESS;
+}
+
+static int
+test_3DES_cipheronly_libcrypto_all(void)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	int status;
+
+	status = test_blockcipher_all_tests(ts_params->mbuf_pool,
+		ts_params->op_mpool, ts_params->valid_devs[0],
+		RTE_CRYPTODEV_LIBCRYPTO_PMD,
+		BLKCIPHER_3DES_CIPHERONLY_TYPE);
+
+	TEST_ASSERT_EQUAL(status, 0, "Test failed");
+
+	return TEST_SUCCESS;
+}
+
 /* ***** AES-GCM Tests ***** */
 
 static int
@@ -4103,6 +4546,112 @@ test_multi_session(void)
 	return TEST_SUCCESS;
 }
 
+struct multi_session_params {
+	struct crypto_unittest_params ut_params;
+	uint8_t *cipher_key;
+	uint8_t *hmac_key;
+	const uint8_t *cipher;
+	const uint8_t *digest;
+	uint8_t *iv;
+};
+
+#define MB_SESSION_NUMBER 3
+
+static int
+test_multi_session_random_usage(void)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct rte_cryptodev_info dev_info;
+	struct rte_cryptodev_sym_session **sessions;
+	uint32_t i, j;
+	struct multi_session_params ut_paramz[] = {
+
+		{
+			.cipher_key = ms_aes_cbc_key0,
+			.hmac_key = ms_hmac_key0,
+			.cipher = ms_aes_cbc_cipher0,
+			.digest = ms_hmac_digest0,
+			.iv = ms_aes_cbc_iv0
+		},
+		{
+			.cipher_key = ms_aes_cbc_key1,
+			.hmac_key = ms_hmac_key1,
+			.cipher = ms_aes_cbc_cipher1,
+			.digest = ms_hmac_digest1,
+			.iv = ms_aes_cbc_iv1
+		},
+		{
+			.cipher_key = ms_aes_cbc_key2,
+			.hmac_key = ms_hmac_key2,
+			.cipher = ms_aes_cbc_cipher2,
+			.digest = ms_hmac_digest2,
+			.iv = ms_aes_cbc_iv2
+		},
+
+	};
+
+	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
+
+	sessions = rte_malloc(NULL,
+			(sizeof(struct rte_cryptodev_sym_session *)
+					* dev_info.sym.max_nb_sessions) + 1, 0);
+
+	for (i = 0; i < MB_SESSION_NUMBER; i++) {
+		rte_memcpy(&ut_paramz[i].ut_params, &testsuite_params,
+				sizeof(struct crypto_unittest_params));
+
+		test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(
+				&ut_paramz[i].ut_params, ut_paramz[i].cipher_key,
+				ut_paramz[i].hmac_key);
+
+		/* Create multiple crypto sessions*/
+		sessions[i] = rte_cryptodev_sym_session_create(ts_params->valid_devs[0],
+				&ut_paramz[i].ut_params.auth_xform);
+
+		TEST_ASSERT_NOT_NULL(sessions[i],
+				"Session creation failed at session number %u", i);
+
+	}
+
+	srand(time(NULL));
+	for (i = 0; i < 40000; i++) {
+
+		j = rand() % MB_SESSION_NUMBER;
+
+		TEST_ASSERT_SUCCESS(
+				test_AES_CBC_HMAC_SHA512_decrypt_perform(sessions[j],
+						&ut_paramz[j].ut_params, ts_params, ut_paramz[j].cipher,
+						ut_paramz[j].digest, ut_paramz[j].iv),
+				"Failed to perform decrypt on request number %u.", i);
+
+		if (ut_paramz[j].ut_params.op)
+			rte_crypto_op_free(ut_paramz[j].ut_params.op);
+
+		/*
+		 * free mbuf - both obuf and ibuf are usually the same,
+		 * so check if they point at the same address is necessary,
+		 * to avoid freeing the mbuf twice.
+		 */
+		if (ut_paramz[j].ut_params.obuf) {
+			rte_pktmbuf_free(ut_paramz[j].ut_params.obuf);
+			if (ut_paramz[j].ut_params.ibuf == ut_paramz[j].ut_params.obuf)
+				ut_paramz[j].ut_params.ibuf = 0;
+			ut_paramz[j].ut_params.obuf = 0;
+		}
+		if (ut_paramz[j].ut_params.ibuf) {
+			rte_pktmbuf_free(ut_paramz[j].ut_params.ibuf);
+			ut_paramz[j].ut_params.ibuf = 0;
+		}
+	}
+
+	for (i = 0; i < MB_SESSION_NUMBER; i++)
+		rte_cryptodev_sym_session_free(ts_params->valid_devs[0], sessions[i]);
+
+	rte_free(sessions);
+
+	return TEST_SUCCESS;
+}
+
 static int
 test_null_cipher_only_operation(void)
 {
@@ -4456,6 +5005,15 @@ test_null_burst_operation(void)
 	return TEST_SUCCESS;
 }
 
+static void
+generate_gmac_large_plaintext(uint8_t *data)
+{
+	uint16_t i;
+
+	for (i = 32; i < GMAC_LARGE_PLAINTEXT_LENGTH; i += 32)
+		memcpy(&data[i], &data[0], 32);
+}
+
 static int
 create_gmac_operation(enum rte_crypto_auth_operation op,
 		const struct gmac_test_data *tdata)
@@ -4470,6 +5028,9 @@ create_gmac_operation(enum rte_crypto_auth_operation op,
 	iv_pad_len = RTE_ALIGN_CEIL(tdata->iv.len, 16);
 	aad_pad_len = RTE_ALIGN_CEIL(tdata->aad.len, 16);
 
+	if (tdata->aad.len == GMAC_LARGE_PLAINTEXT_LENGTH)
+		generate_gmac_large_plaintext(tdata->aad.data);
+
 	/* Generate Crypto op data structure */
 	ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
 			RTE_CRYPTO_OP_TYPE_SYMMETRIC);
@@ -4647,6 +5208,12 @@ test_AES_GMAC_authentication_test_case_3(void)
 }
 
 static int
+test_AES_GMAC_authentication_test_case_4(void)
+{
+	return test_AES_GMAC_authentication(&gmac_test_case_4);
+}
+
+static int
 test_AES_GMAC_authentication_verify(const struct gmac_test_data *tdata)
 {
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
@@ -4706,72 +5273,786 @@ test_AES_GMAC_authentication_verify_test_case_3(void)
 	return test_AES_GMAC_authentication_verify(&gmac_test_case_3);
 }
 
-static struct unit_test_suite cryptodev_qat_testsuite  = {
-	.suite_name = "Crypto QAT Unit Test Suite",
-	.setup = testsuite_setup,
-	.teardown = testsuite_teardown,
-	.unit_test_cases = {
-		TEST_CASE_ST(ut_setup, ut_teardown,
-				test_device_configure_invalid_dev_id),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-				test_device_configure_invalid_queue_pair_ids),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-				test_queue_pair_descriptor_setup),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-				test_multi_session),
+static int
+test_AES_GMAC_authentication_verify_test_case_4(void)
+{
+	return test_AES_GMAC_authentication_verify(&gmac_test_case_4);
+}
 
-		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all),
-		TEST_CASE_ST(ut_setup, ut_teardown, test_stats),
+struct test_crypto_vector {
+	enum rte_crypto_cipher_algorithm crypto_algo;
 
-		/** AES GCM Authenticated Encryption */
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_encryption_test_case_1),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_encryption_test_case_2),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_encryption_test_case_3),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_encryption_test_case_4),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_encryption_test_case_5),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_encryption_test_case_6),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_encryption_test_case_7),
+	struct {
+		uint8_t data[64];
+		unsigned int len;
+	} cipher_key;
 
-		/** AES GCM Authenticated Decryption */
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_decryption_test_case_1),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_decryption_test_case_2),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_decryption_test_case_3),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_decryption_test_case_4),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_decryption_test_case_5),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_decryption_test_case_6),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_mb_AES_GCM_authenticated_decryption_test_case_7),
+	struct {
+		uint8_t data[64];
+		unsigned int len;
+	} iv;
 
-		/** AES GMAC Authentication */
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_AES_GMAC_authentication_test_case_1),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_AES_GMAC_authentication_verify_test_case_1),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_AES_GMAC_authentication_test_case_2),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_AES_GMAC_authentication_verify_test_case_2),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_AES_GMAC_authentication_test_case_3),
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_AES_GMAC_authentication_verify_test_case_3),
+	struct {
+		const uint8_t *data;
+		unsigned int len;
+	} plaintext;
 
-		/** SNOW 3G encrypt only (UEA2) */
-		TEST_CASE_ST(ut_setup, ut_teardown,
-			test_snow3g_encryption_test_case_1),
+	struct {
+		const uint8_t *data;
+		unsigned int len;
+	} ciphertext;
+
+	enum rte_crypto_auth_algorithm auth_algo;
+
+	struct {
+		uint8_t data[128];
+		unsigned int len;
+	} auth_key;
+
+	struct {
+		const uint8_t *data;
+		unsigned int len;
+	} aad;
+
+	struct {
+		uint8_t data[128];
+		unsigned int len;
+	} digest;
+};
+
+static const struct test_crypto_vector
+hmac_sha1_test_crypto_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.plaintext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD
+		},
+		.len = 20
+	},
+	.digest = {
+		.data = {
+			0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77,
+			0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17,
+			0x3F, 0x91, 0x64, 0x59
+		},
+		.len = 20
+	}
+};
+
+static const struct test_crypto_vector
+aes128_gmac_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_AES_GMAC,
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_GCM,
+	.aad = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B
+		},
+		.len = 12
+	},
+	.cipher_key = {
+		.data = {
+			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA
+		},
+		.len = 16
+	},
+	.digest = {
+		.data = {
+			0xCA, 0x00, 0x99, 0x8B, 0x30, 0x7E, 0x74, 0x56,
+			0x32, 0xA7, 0x87, 0xB5, 0xE9, 0xB2, 0x34, 0x5A
+		},
+		.len = 16
+	}
+};
+
+static const struct test_crypto_vector
+aes128cbc_hmac_sha1_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_aes128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD
+		},
+		.len = 20
+	},
+	.digest = {
+		.data = {
+			0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60,
+			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+			0x18, 0x8C, 0x1D, 0x32
+		},
+		.len = 20
+	}
+};
+
+static void
+data_corruption(uint8_t *data)
+{
+	data[0] += 1;
+}
+
+static void
+tag_corruption(uint8_t *data, unsigned int tag_offset)
+{
+	data[tag_offset] += 1;
+}
+
+static int
+create_auth_session(struct crypto_unittest_params *ut_params,
+		uint8_t dev_id,
+		const struct test_crypto_vector *reference,
+		enum rte_crypto_auth_operation auth_op)
+{
+	uint8_t auth_key[reference->auth_key.len + 1];
+
+	memcpy(auth_key, reference->auth_key.data, reference->auth_key.len);
+
+	/* Setup Authentication Parameters */
+	ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+	ut_params->auth_xform.auth.op = auth_op;
+	ut_params->auth_xform.next = NULL;
+	ut_params->auth_xform.auth.algo = reference->auth_algo;
+	ut_params->auth_xform.auth.key.length = reference->auth_key.len;
+	ut_params->auth_xform.auth.key.data = auth_key;
+	ut_params->auth_xform.auth.digest_length = reference->digest.len;
+	ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len;
+
+	/* Create Crypto session*/
+	ut_params->sess = rte_cryptodev_sym_session_create(dev_id,
+				&ut_params->auth_xform);
+
+	TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
+
+	return 0;
+}
+
+static int
+create_auth_cipher_session(struct crypto_unittest_params *ut_params,
+		uint8_t dev_id,
+		const struct test_crypto_vector *reference,
+		enum rte_crypto_auth_operation auth_op,
+		enum rte_crypto_cipher_operation cipher_op)
+{
+	uint8_t cipher_key[reference->cipher_key.len + 1];
+	uint8_t auth_key[reference->auth_key.len + 1];
+
+	memcpy(cipher_key, reference->cipher_key.data, reference->cipher_key.len);
+	memcpy(auth_key, reference->auth_key.data, reference->auth_key.len);
+
+	/* Setup Authentication Parameters */
+	ut_params->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+	ut_params->auth_xform.auth.op = auth_op;
+	ut_params->auth_xform.next = &ut_params->cipher_xform;
+	ut_params->auth_xform.auth.algo = reference->auth_algo;
+	ut_params->auth_xform.auth.key.length = reference->auth_key.len;
+	ut_params->auth_xform.auth.key.data = auth_key;
+	ut_params->auth_xform.auth.digest_length = reference->digest.len;
+	ut_params->auth_xform.auth.add_auth_data_length = reference->aad.len;
+
+	/* Setup Cipher Parameters */
+	ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+	ut_params->cipher_xform.next = NULL;
+	ut_params->cipher_xform.cipher.algo = reference->crypto_algo;
+	ut_params->cipher_xform.cipher.op = cipher_op;
+	ut_params->cipher_xform.cipher.key.data = cipher_key;
+	ut_params->cipher_xform.cipher.key.length = reference->cipher_key.len;
+
+	/* Create Crypto session*/
+	ut_params->sess = rte_cryptodev_sym_session_create(dev_id,
+				&ut_params->auth_xform);
+
+	TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
+
+	return 0;
+}
+
+static int
+create_auth_operation(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference,
+		unsigned int auth_generate)
+{
+	/* Generate Crypto op data structure */
+	ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
+			RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	TEST_ASSERT_NOT_NULL(ut_params->op,
+			"Failed to allocate pktmbuf offload");
+
+	/* Set crypto operation data parameters */
+	rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess);
+
+	struct rte_crypto_sym_op *sym_op = ut_params->op->sym;
+
+	/* set crypto operation source mbuf */
+	sym_op->m_src = ut_params->ibuf;
+
+	/* digest */
+	sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
+			ut_params->ibuf, reference->digest.len);
+
+	TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
+			"no room to append auth tag");
+
+	sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(
+			ut_params->ibuf, reference->plaintext.len);
+	sym_op->auth.digest.length = reference->digest.len;
+
+	if (auth_generate)
+		memset(sym_op->auth.digest.data, 0, reference->digest.len);
+	else
+		memcpy(sym_op->auth.digest.data,
+				reference->digest.data,
+				reference->digest.len);
+
+	TEST_HEXDUMP(stdout, "digest:",
+			sym_op->auth.digest.data,
+			sym_op->auth.digest.length);
+
+	sym_op->auth.data.length = reference->plaintext.len;
+	sym_op->auth.data.offset = 0;
+
+	return 0;
+}
+
+static int
+create_auth_GMAC_operation(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference,
+		unsigned int auth_generate)
+{
+	/* Generate Crypto op data structure */
+	ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
+			RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	TEST_ASSERT_NOT_NULL(ut_params->op,
+			"Failed to allocate pktmbuf offload");
+
+	/* Set crypto operation data parameters */
+	rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess);
+
+	struct rte_crypto_sym_op *sym_op = ut_params->op->sym;
+
+	/* set crypto operation source mbuf */
+	sym_op->m_src = ut_params->ibuf;
+
+	/* aad */
+	sym_op->auth.aad.data = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+			reference->aad.len);
+	TEST_ASSERT_NOT_NULL(sym_op->auth.aad.data, "no room to append AAD");
+	memcpy(sym_op->auth.aad.data, reference->aad.data, reference->aad.len);
+
+	TEST_HEXDUMP(stdout, "AAD:", sym_op->auth.aad.data, reference->aad.len);
+
+	sym_op->auth.aad.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf);
+	sym_op->auth.aad.length = reference->aad.len;
+
+	/* digest */
+	sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
+			ut_params->ibuf, reference->digest.len);
+
+	TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
+			"no room to append auth tag");
+
+	sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(
+			ut_params->ibuf, reference->ciphertext.len);
+	sym_op->auth.digest.length = reference->digest.len;
+
+	if (auth_generate)
+		memset(sym_op->auth.digest.data, 0, reference->digest.len);
+	else
+		memcpy(sym_op->auth.digest.data,
+				reference->digest.data,
+				reference->digest.len);
+
+	TEST_HEXDUMP(stdout, "digest:",
+			sym_op->auth.digest.data,
+			sym_op->auth.digest.length);
+
+	sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(
+		ut_params->ibuf, reference->iv.len);
+	TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv");
+
+	sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf);
+	sym_op->cipher.iv.length = reference->iv.len;
+
+	memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len);
+
+	sym_op->cipher.data.length = 0;
+	sym_op->cipher.data.offset = 0;
+
+	sym_op->auth.data.length = 0;
+	sym_op->auth.data.offset = 0;
+
+	return 0;
+}
+
+static int
+create_cipher_auth_operation(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference,
+		unsigned int auth_generate)
+{
+	/* Generate Crypto op data structure */
+	ut_params->op = rte_crypto_op_alloc(ts_params->op_mpool,
+			RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	TEST_ASSERT_NOT_NULL(ut_params->op,
+			"Failed to allocate pktmbuf offload");
+
+	/* Set crypto operation data parameters */
+	rte_crypto_op_attach_sym_session(ut_params->op, ut_params->sess);
+
+	struct rte_crypto_sym_op *sym_op = ut_params->op->sym;
+
+	/* set crypto operation source mbuf */
+	sym_op->m_src = ut_params->ibuf;
+
+	/* digest */
+	sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
+			ut_params->ibuf, reference->digest.len);
+
+	TEST_ASSERT_NOT_NULL(sym_op->auth.digest.data,
+			"no room to append auth tag");
+
+	sym_op->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(
+			ut_params->ibuf, reference->ciphertext.len);
+	sym_op->auth.digest.length = reference->digest.len;
+
+	if (auth_generate)
+		memset(sym_op->auth.digest.data, 0, reference->digest.len);
+	else
+		memcpy(sym_op->auth.digest.data,
+				reference->digest.data,
+				reference->digest.len);
+
+	TEST_HEXDUMP(stdout, "digest:",
+			sym_op->auth.digest.data,
+			sym_op->auth.digest.length);
+
+	sym_op->cipher.iv.data = (uint8_t *)rte_pktmbuf_prepend(
+		ut_params->ibuf, reference->iv.len);
+	TEST_ASSERT_NOT_NULL(sym_op->cipher.iv.data, "no room to prepend iv");
+
+	sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(ut_params->ibuf);
+	sym_op->cipher.iv.length = reference->iv.len;
+
+	memcpy(sym_op->cipher.iv.data, reference->iv.data, reference->iv.len);
+
+	sym_op->cipher.data.length = reference->ciphertext.len;
+	sym_op->cipher.data.offset = reference->iv.len;
+
+	sym_op->auth.data.length = reference->ciphertext.len;
+	sym_op->auth.data.offset = reference->iv.len;
+
+	return 0;
+}
+
+static int
+create_auth_verify_operation(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return create_auth_operation(ts_params, ut_params, reference, 0);
+}
+
+static int
+create_auth_verify_GMAC_operation(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return create_auth_GMAC_operation(ts_params, ut_params, reference, 0);
+}
+
+static int
+create_cipher_auth_verify_operation(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return create_cipher_auth_operation(ts_params, ut_params, reference, 0);
+}
+
+static int
+test_authentication_verify_fail_when_data_corruption(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference,
+		unsigned int data_corrupted)
+{
+	int retval;
+
+	uint8_t *plaintext;
+
+	/* Create session */
+	retval = create_auth_session(ut_params,
+			ts_params->valid_devs[0],
+			reference,
+			RTE_CRYPTO_AUTH_OP_VERIFY);
+	if (retval < 0)
+		return retval;
+
+	ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+	TEST_ASSERT_NOT_NULL(ut_params->ibuf,
+			"Failed to allocate input buffer in mempool");
+
+	/* clear mbuf payload */
+	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->ibuf));
+
+	plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+			reference->plaintext.len);
+	TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext");
+	memcpy(plaintext, reference->plaintext.data, reference->plaintext.len);
+
+	TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len);
+
+	/* Create operation */
+	retval = create_auth_verify_operation(ts_params, ut_params, reference);
+
+	if (retval < 0)
+		return retval;
+
+	if (data_corrupted)
+		data_corruption(plaintext);
+	else
+		tag_corruption(plaintext, reference->plaintext.len);
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_AUTH_FAILED,
+			"authentication not failed");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	return 0;
+}
+
+static int
+test_authentication_verify_GMAC_fail_when_corruption(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference,
+		unsigned int data_corrupted)
+{
+	int retval;
+
+	/* Create session */
+	retval = create_auth_cipher_session(ut_params,
+			ts_params->valid_devs[0],
+			reference,
+			RTE_CRYPTO_AUTH_OP_VERIFY,
+			RTE_CRYPTO_CIPHER_OP_DECRYPT);
+	if (retval < 0)
+		return retval;
+
+	ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+	TEST_ASSERT_NOT_NULL(ut_params->ibuf,
+			"Failed to allocate input buffer in mempool");
+
+	/* clear mbuf payload */
+	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->ibuf));
+
+	/* Create operation */
+	retval = create_auth_verify_GMAC_operation(ts_params,
+			ut_params,
+			reference);
+
+	if (retval < 0)
+		return retval;
+
+	if (data_corrupted)
+		data_corruption(ut_params->op->sym->auth.aad.data);
+	else
+		tag_corruption(ut_params->op->sym->auth.aad.data, reference->aad.len);
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_AUTH_FAILED,
+			"authentication not failed");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	return 0;
+}
+
+static int
+test_authenticated_decryption_fail_when_corruption(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference,
+		unsigned int data_corrupted)
+{
+	int retval;
+
+	uint8_t *ciphertext;
+
+	/* Create session */
+	retval = create_auth_cipher_session(ut_params,
+			ts_params->valid_devs[0],
+			reference,
+			RTE_CRYPTO_AUTH_OP_VERIFY,
+			RTE_CRYPTO_CIPHER_OP_DECRYPT);
+	if (retval < 0)
+		return retval;
+
+	ut_params->ibuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+	TEST_ASSERT_NOT_NULL(ut_params->ibuf,
+			"Failed to allocate input buffer in mempool");
+
+	/* clear mbuf payload */
+	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->ibuf));
+
+	ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
+			reference->ciphertext.len);
+	TEST_ASSERT_NOT_NULL(ciphertext, "no room to append ciphertext");
+	memcpy(ciphertext, reference->ciphertext.data, reference->ciphertext.len);
+
+	/* Create operation */
+	retval = create_cipher_auth_verify_operation(ts_params,
+			ut_params,
+			reference);
+
+	if (retval < 0)
+		return retval;
+
+	if (data_corrupted)
+		data_corruption(ciphertext);
+	else
+		tag_corruption(ciphertext, reference->ciphertext.len);
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_AUTH_FAILED,
+			"authentication not failed");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	return 0;
+}
+
+static int
+test_authentication_verify_fail_when_data_corrupted(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return test_authentication_verify_fail_when_data_corruption(
+			ts_params, ut_params, reference, 1);
+}
+
+static int
+test_authentication_verify_fail_when_tag_corrupted(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return test_authentication_verify_fail_when_data_corruption(
+			ts_params, ut_params, reference, 0);
+}
+
+static int
+test_authentication_verify_GMAC_fail_when_data_corrupted(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return test_authentication_verify_GMAC_fail_when_corruption(
+			ts_params, ut_params, reference, 1);
+}
+
+static int
+test_authentication_verify_GMAC_fail_when_tag_corrupted(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return test_authentication_verify_GMAC_fail_when_corruption(
+			ts_params, ut_params, reference, 0);
+}
+
+static int
+test_authenticated_decryption_fail_when_data_corrupted(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return test_authenticated_decryption_fail_when_corruption(
+			ts_params, ut_params, reference, 1);
+}
+
+static int
+test_authenticated_decryption_fail_when_tag_corrupted(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return test_authenticated_decryption_fail_when_corruption(
+			ts_params, ut_params, reference, 0);
+}
+
+static int
+authentication_verify_HMAC_SHA1_fail_when_data_corrupted(void)
+{
+	return test_authentication_verify_fail_when_data_corrupted(
+			&testsuite_params, &unittest_params,
+			&hmac_sha1_test_crypto_vector);
+}
+
+static int
+authentication_verify_HMAC_SHA1_fail_when_tag_corrupted(void)
+{
+	return test_authentication_verify_fail_when_tag_corrupted(
+			&testsuite_params, &unittest_params,
+			&hmac_sha1_test_crypto_vector);
+}
+
+static int
+authentication_verify_AES128_GMAC_fail_when_data_corrupted(void)
+{
+	return test_authentication_verify_GMAC_fail_when_data_corrupted(
+			&testsuite_params, &unittest_params,
+			&aes128_gmac_test_vector);
+}
+
+static int
+authentication_verify_AES128_GMAC_fail_when_tag_corrupted(void)
+{
+	return test_authentication_verify_GMAC_fail_when_tag_corrupted(
+			&testsuite_params, &unittest_params,
+			&aes128_gmac_test_vector);
+}
+
+static int
+auth_decryption_AES128CBC_HMAC_SHA1_fail_when_data_corrupted(void)
+{
+	return test_authenticated_decryption_fail_when_data_corrupted(
+			&testsuite_params,
+			&unittest_params,
+			&aes128cbc_hmac_sha1_test_vector);
+}
+
+static int
+auth_decryption_AES128CBC_HMAC_SHA1_fail_when_tag_corrupted(void)
+{
+	return test_authenticated_decryption_fail_when_tag_corrupted(
+			&testsuite_params,
+			&unittest_params,
+			&aes128cbc_hmac_sha1_test_vector);
+}
+
+static struct unit_test_suite cryptodev_qat_testsuite  = {
+	.suite_name = "Crypto QAT Unit Test Suite",
+	.setup = testsuite_setup,
+	.teardown = testsuite_teardown,
+	.unit_test_cases = {
+		TEST_CASE_ST(ut_setup, ut_teardown,
+				test_device_configure_invalid_dev_id),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+				test_device_configure_invalid_queue_pair_ids),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+				test_queue_pair_descriptor_setup),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+				test_multi_session),
+
+		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_qat_all),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_cipheronly_qat_all),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_stats),
+
+		/** AES GCM Authenticated Encryption */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_2),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_3),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_4),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_5),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_6),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_7),
+
+		/** AES GCM Authenticated Decryption */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_2),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_3),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_4),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_5),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_6),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_7),
+
+		/** AES GMAC Authentication */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_verify_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_test_case_2),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_verify_test_case_2),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_test_case_3),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_verify_test_case_3),
+
+		/** SNOW 3G encrypt only (UEA2) */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_snow3g_encryption_test_case_1),
 		TEST_CASE_ST(ut_setup, ut_teardown,
 			test_snow3g_encryption_test_case_2),
 		TEST_CASE_ST(ut_setup, ut_teardown,
@@ -4862,6 +6143,87 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite  = {
 	}
 };
 
+static struct unit_test_suite cryptodev_libcrypto_testsuite  = {
+	.suite_name = "Crypto Device LIBCRYPTO Unit Test Suite",
+	.setup = testsuite_setup,
+	.teardown = testsuite_teardown,
+	.unit_test_cases = {
+		TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_multi_session_random_usage),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_libcrypto_all),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_cipheronly_libcrypto_all),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_chain_libcrypto_all),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_3DES_cipheronly_libcrypto_all),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_authonly_libcrypto_all),
+
+		/** AES GCM Authenticated Encryption */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_2),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_3),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_4),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_5),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_6),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_encryption_test_case_7),
+
+		/** AES GCM Authenticated Decryption */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_2),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_3),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_4),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_5),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_6),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_mb_AES_GCM_authenticated_decryption_test_case_7),
+
+		/** AES GMAC Authentication */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_verify_test_case_1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_test_case_2),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_verify_test_case_2),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_test_case_3),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_verify_test_case_3),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_test_case_4),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			test_AES_GMAC_authentication_verify_test_case_4),
+
+		/** Negative tests */
+		TEST_CASE_ST(ut_setup, ut_teardown,
+				authentication_verify_HMAC_SHA1_fail_when_data_corrupted),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+				authentication_verify_HMAC_SHA1_fail_when_tag_corrupted),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+				authentication_verify_AES128_GMAC_fail_when_data_corrupted),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+					authentication_verify_AES128_GMAC_fail_when_tag_corrupted),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			auth_decryption_AES128CBC_HMAC_SHA1_fail_when_data_corrupted),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			auth_decryption_AES128CBC_HMAC_SHA1_fail_when_tag_corrupted),
+
+		TEST_CASES_END() /**< NULL terminate unit test array */
+	}
+};
+
 static struct unit_test_suite cryptodev_aesni_gcm_testsuite  = {
 	.suite_name = "Crypto Device AESNI GCM Unit Test Suite",
 	.setup = testsuite_setup,
@@ -5105,6 +6467,14 @@ test_cryptodev_aesni_mb(void /*argv __rte_unused, int argc __rte_unused*/)
 }
 
 static int
+test_cryptodev_libcrypto(void)
+{
+	gbl_cryptodev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD;
+
+	return unit_test_suite_runner(&cryptodev_libcrypto_testsuite);
+}
+
+static int
 test_cryptodev_aesni_gcm(void)
 {
 	gbl_cryptodev_type = RTE_CRYPTODEV_AESNI_GCM_PMD;
@@ -5146,6 +6516,7 @@ test_cryptodev_sw_zuc(void /*argv __rte_unused, int argc __rte_unused*/)
 
 REGISTER_TEST_COMMAND(cryptodev_qat_autotest, test_cryptodev_qat);
 REGISTER_TEST_COMMAND(cryptodev_aesni_mb_autotest, test_cryptodev_aesni_mb);
+REGISTER_TEST_COMMAND(cryptodev_libcrypto_autotest, test_cryptodev_libcrypto);
 REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_autotest, test_cryptodev_aesni_gcm);
 REGISTER_TEST_COMMAND(cryptodev_null_autotest, test_cryptodev_null);
 REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_autotest, test_cryptodev_sw_snow3g);
diff --git a/app/test/test_cryptodev.h b/app/test/test_cryptodev.h
index 3c37c32..a9089aa 100644
--- a/app/test/test_cryptodev.h
+++ b/app/test/test_cryptodev.h
@@ -63,6 +63,7 @@
 #define DIGEST_BYTE_LENGTH_SNOW3G_UIA2		(BYTE_LENGTH(32))
 #define DIGEST_BYTE_LENGTH_KASUMI_F9		(BYTE_LENGTH(32))
 #define AES_XCBC_MAC_KEY_SZ			(16)
+#define DIGEST_BYTE_LENGTH_AES_GCM		(BYTE_LENGTH(128))
 
 #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA1		(12)
 #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA224		(16)
diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h
index 92c0cc2..ee46f9f 100644
--- a/app/test/test_cryptodev_aes_test_vectors.h
+++ b/app/test/test_cryptodev_aes_test_vectors.h
@@ -634,12 +634,204 @@ static const struct blockcipher_test_data aes_test_data_9 = {
 	}
 };
 
+static const uint8_t ciphertext512_aes192cbc[] = {
+	0x45, 0xEE, 0x9A, 0xEA, 0x3C, 0x03, 0xFC, 0x4C,
+	0x84, 0x36, 0xB0, 0xDA, 0xB0, 0xDC, 0xF3, 0x5B,
+	0x75, 0xA7, 0xBE, 0x0E, 0xC0, 0x8D, 0x6C, 0xF8,
+	0xC1, 0x0F, 0xD0, 0x35, 0x1D, 0x82, 0xAE, 0x7C,
+	0x57, 0xC5, 0x7A, 0x55, 0x87, 0x1B, 0xD4, 0x03,
+	0x0A, 0x64, 0xC9, 0xE0, 0xF4, 0xC7, 0x6F, 0x57,
+	0x52, 0xC6, 0x73, 0xBA, 0x84, 0x0B, 0x5B, 0x89,
+	0x21, 0xD2, 0x9B, 0x88, 0x68, 0xF5, 0xA9, 0x7F,
+	0x3F, 0x49, 0xEB, 0xF4, 0xD4, 0x52, 0xD2, 0x64,
+	0x80, 0xB2, 0x53, 0xDA, 0x19, 0xF6, 0x10, 0x24,
+	0x23, 0x26, 0x7A, 0x7C, 0x07, 0x57, 0x4B, 0x0E,
+	0x58, 0x49, 0x61, 0xD1, 0xDC, 0x9A, 0x32, 0x6B,
+	0x0F, 0x43, 0x9E, 0x4D, 0xB4, 0x07, 0x4E, 0xB3,
+	0x51, 0x74, 0xDE, 0x29, 0xBC, 0x98, 0xF9, 0xDF,
+	0x78, 0x9A, 0x18, 0x9C, 0xD6, 0x7A, 0x55, 0x7C,
+	0xE6, 0x1D, 0x5C, 0x1A, 0x99, 0xD2, 0xC3, 0x7B,
+	0x9F, 0x96, 0x74, 0x2D, 0xE0, 0xEF, 0xD1, 0xE3,
+	0x08, 0x9F, 0xAF, 0xE6, 0xED, 0xCA, 0xE1, 0xEA,
+	0x23, 0x6F, 0x7C, 0x81, 0xA8, 0xC0, 0x5B, 0x8B,
+	0x53, 0x90, 0x51, 0x2D, 0x0F, 0xF6, 0x7D, 0xA7,
+	0x1C, 0xBD, 0x83, 0x84, 0x54, 0xA4, 0x15, 0xFB,
+	0x3E, 0x25, 0xA7, 0x3A, 0x0A, 0x73, 0xD9, 0x88,
+	0x6F, 0x80, 0x78, 0x95, 0x7F, 0x60, 0xAA, 0x86,
+	0x8A, 0xFC, 0xDF, 0xC1, 0xCB, 0xDE, 0xBB, 0x25,
+	0x52, 0x20, 0xC6, 0x79, 0xD4, 0x0F, 0x25, 0xE7,
+	0xDB, 0xB2, 0x17, 0xA4, 0x6F, 0x3C, 0x6F, 0x91,
+	0xF6, 0x44, 0x1E, 0xB6, 0x85, 0xBC, 0x7A, 0x14,
+	0x10, 0x72, 0xBD, 0x16, 0x63, 0x39, 0x9E, 0x7B,
+	0x84, 0x5B, 0x17, 0x61, 0xB1, 0x5D, 0x82, 0x0B,
+	0x6D, 0x37, 0xD7, 0x79, 0xB8, 0x24, 0x91, 0x30,
+	0x82, 0x91, 0x02, 0xB1, 0x18, 0x4B, 0xE0, 0xF4,
+	0x13, 0x1B, 0xB2, 0x4C, 0xDA, 0xB8, 0x99, 0x96,
+	0x83, 0x2F, 0xBE, 0x53, 0x8D, 0xDE, 0xFA, 0xAD,
+	0xF6, 0x5C, 0xDB, 0xE5, 0x66, 0x26, 0x8F, 0x13,
+	0x2B, 0x76, 0x47, 0x73, 0xDE, 0x1A, 0x74, 0xA6,
+	0x30, 0xAF, 0x42, 0xA0, 0xE5, 0xD2, 0x8F, 0xC2,
+	0xED, 0x3E, 0x9E, 0x29, 0x54, 0x3C, 0xDE, 0x9F,
+	0x5D, 0x30, 0x2B, 0x63, 0xFB, 0xE3, 0xB1, 0x07,
+	0xEE, 0x74, 0x4A, 0xAF, 0xB1, 0x20, 0x8D, 0xEC,
+	0xE6, 0x78, 0x16, 0x8D, 0xA4, 0x6E, 0x34, 0x7D,
+	0x47, 0xFB, 0x0B, 0xC1, 0x32, 0xD7, 0x0D, 0x6C,
+	0x6F, 0x93, 0x9C, 0x5E, 0xEF, 0x1F, 0x9C, 0x45,
+	0x80, 0x6B, 0x74, 0xA6, 0x81, 0xF2, 0xF6, 0xFA,
+	0xAA, 0x9D, 0x4F, 0xCA, 0xB5, 0x90, 0x59, 0xB0,
+	0x3B, 0xF2, 0xF0, 0x75, 0xFD, 0x8A, 0xD8, 0x97,
+	0x65, 0x88, 0x56, 0x4C, 0x44, 0xDF, 0x73, 0xF7,
+	0x56, 0x9C, 0x48, 0x7E, 0xB0, 0x1F, 0x1D, 0x7D,
+	0x6A, 0x11, 0xF5, 0xC2, 0xF4, 0x17, 0xEF, 0x58,
+	0xD8, 0x2A, 0xAF, 0x56, 0x2F, 0xCF, 0xEC, 0xA4,
+	0x58, 0x8B, 0x60, 0xCE, 0xD4, 0x0F, 0x9C, 0x21,
+	0xEC, 0x3E, 0x74, 0x7B, 0x81, 0x3D, 0x69, 0xC6,
+	0x5E, 0x12, 0x83, 0xE9, 0xEF, 0x81, 0x58, 0x36,
+	0x6A, 0x60, 0x0F, 0x54, 0x28, 0x11, 0xF9, 0x64,
+	0x36, 0xAD, 0x79, 0xF5, 0x1C, 0x74, 0xD0, 0xC3,
+	0x7B, 0x61, 0xE1, 0x92, 0xB0, 0x13, 0x91, 0x87,
+	0x32, 0x1F, 0xF2, 0x5A, 0xDA, 0x25, 0x69, 0xEB,
+	0xD7, 0x32, 0x7F, 0xF5, 0x23, 0x21, 0x54, 0x47,
+	0x7B, 0x1B, 0x33, 0xB0, 0x3D, 0xF6, 0xE2, 0x7E,
+	0x3E, 0xA2, 0x9E, 0xCA, 0x48, 0x0B, 0x4A, 0x29,
+	0x81, 0xD4, 0x4E, 0xD5, 0x69, 0xFB, 0xCD, 0x37,
+	0x8A, 0xC1, 0x5B, 0x50, 0xFF, 0xB5, 0x7D, 0x43,
+	0x0F, 0xAE, 0xA6, 0xC2, 0xE5, 0x8F, 0x45, 0xB2,
+	0x85, 0x99, 0x02, 0xA2, 0x9B, 0xBE, 0x90, 0x43,
+	0x4F, 0x2F, 0x50, 0xE2, 0x77, 0x62, 0xD9, 0xCC
+};
+
+/** AES-192-CBC test vector */
+static const struct blockcipher_test_data aes_test_data_10 = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A,
+			0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0
+		},
+		.len = 24
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes_common,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_aes192cbc,
+		.len = 512
+	}
+};
+
+static const uint8_t ciphertext512_aes256cbc[] = {
+	0xF3, 0xDD, 0xF0, 0x0B, 0xFF, 0xA2, 0x6A, 0x04,
+	0xBE, 0xDA, 0x52, 0xA6, 0xFE, 0x6B, 0xA6, 0xA7,
+	0x48, 0x1D, 0x7D, 0x98, 0x65, 0xDB, 0xEF, 0x06,
+	0x26, 0xB5, 0x8E, 0xEB, 0x05, 0x0E, 0x77, 0x98,
+	0x17, 0x8E, 0xD0, 0xD4, 0x7B, 0x92, 0x8F, 0x5C,
+	0xD0, 0x74, 0x5C, 0xA8, 0x4B, 0x54, 0xB6, 0x2F,
+	0x83, 0x72, 0x2C, 0xFF, 0x72, 0xE9, 0xE4, 0x15,
+	0x4C, 0x32, 0xAF, 0xC8, 0xC9, 0x89, 0x3C, 0x6E,
+	0x31, 0xD5, 0xC0, 0x16, 0xC0, 0x31, 0x7D, 0x11,
+	0xAB, 0xCB, 0xDE, 0xD2, 0xD6, 0xAA, 0x76, 0x5E,
+	0xBA, 0xF6, 0xE2, 0x92, 0xCB, 0x86, 0x07, 0xFA,
+	0xD4, 0x9E, 0x83, 0xED, 0xFD, 0xB8, 0x70, 0x54,
+	0x6B, 0xBE, 0xEC, 0x72, 0xDD, 0x28, 0x5E, 0x95,
+	0x78, 0xA5, 0x28, 0x43, 0x3D, 0x6D, 0xB1, 0xD9,
+	0x69, 0x1F, 0xC9, 0x66, 0x0E, 0x32, 0x44, 0x08,
+	0xD2, 0xAE, 0x2C, 0x43, 0xF2, 0xD0, 0x7D, 0x26,
+	0x70, 0xE5, 0xA1, 0xCA, 0x37, 0xE9, 0x7D, 0xC7,
+	0xA3, 0xFA, 0x81, 0x91, 0x64, 0xAA, 0x64, 0x91,
+	0x9A, 0x95, 0x2D, 0xC9, 0xF9, 0xCE, 0xFE, 0x9F,
+	0xC4, 0xD8, 0x81, 0xBE, 0x57, 0x84, 0xC5, 0x02,
+	0xDB, 0x30, 0xC1, 0xD9, 0x0E, 0xA0, 0xA6, 0x00,
+	0xD6, 0xF3, 0x52, 0x7E, 0x0D, 0x23, 0x6B, 0x2B,
+	0x34, 0x99, 0x1F, 0x70, 0x27, 0x6D, 0x58, 0x84,
+	0x93, 0x77, 0xB8, 0x3E, 0xF1, 0x71, 0x58, 0x42,
+	0x8B, 0x2B, 0xC8, 0x6D, 0x05, 0x84, 0xFF, 0x4E,
+	0x85, 0xEF, 0x4A, 0x9D, 0x91, 0x6A, 0xD5, 0xE1,
+	0xAF, 0x01, 0xEB, 0x83, 0x8F, 0x23, 0x7C, 0x7F,
+	0x12, 0x91, 0x05, 0xF0, 0x4E, 0xD9, 0x17, 0x62,
+	0x75, 0xBB, 0xAC, 0x97, 0xEE, 0x3B, 0x4E, 0xC7,
+	0xE5, 0x92, 0xF8, 0x9D, 0x4C, 0xF9, 0xEE, 0x55,
+	0x18, 0xBB, 0xCC, 0xB4, 0xF2, 0x59, 0xB9, 0xFC,
+	0x7A, 0x0F, 0x98, 0xD4, 0x8B, 0xFE, 0xF7, 0x83,
+	0x46, 0xE2, 0x83, 0x33, 0x3E, 0x95, 0x8D, 0x17,
+	0x1E, 0x85, 0xF8, 0x8C, 0x51, 0xB0, 0x6C, 0xB5,
+	0x5E, 0x95, 0xBA, 0x4B, 0x69, 0x1B, 0x48, 0x69,
+	0x0B, 0x8F, 0xA5, 0x18, 0x13, 0xB9, 0x77, 0xD1,
+	0x80, 0x32, 0x32, 0x6D, 0x53, 0xA1, 0x95, 0x40,
+	0x96, 0x8A, 0xCC, 0xA3, 0x69, 0xF8, 0x9F, 0xB5,
+	0x8E, 0xD2, 0x68, 0x07, 0x4F, 0xA7, 0xEC, 0xF8,
+	0x20, 0x21, 0x58, 0xF8, 0xD8, 0x9E, 0x5F, 0x40,
+	0xBA, 0xB9, 0x76, 0x57, 0x3B, 0x17, 0xAD, 0xEE,
+	0xCB, 0xDF, 0x07, 0xC1, 0xDF, 0x66, 0xA8, 0x0D,
+	0xC2, 0xCE, 0x8F, 0x79, 0xC3, 0x32, 0xE0, 0x8C,
+	0xFE, 0x5A, 0xF3, 0x55, 0x27, 0x73, 0x6F, 0xA1,
+	0x54, 0xC6, 0xFC, 0x28, 0x9D, 0xBE, 0x97, 0xB9,
+	0x54, 0x97, 0x72, 0x3A, 0x61, 0xAF, 0x6F, 0xDE,
+	0xF8, 0x0E, 0xBB, 0x6B, 0x96, 0x84, 0xDD, 0x9B,
+	0x62, 0xBA, 0x47, 0xB5, 0xC9, 0x3B, 0x4E, 0x8C,
+	0x78, 0x2A, 0xCC, 0x0A, 0x69, 0x54, 0x25, 0x5E,
+	0x8B, 0xAC, 0x56, 0xD9, 0xFE, 0x48, 0xBA, 0xCE,
+	0xA9, 0xCE, 0xA6, 0x1D, 0xBF, 0x3E, 0x3C, 0x66,
+	0x40, 0x71, 0x79, 0xAD, 0x5B, 0x26, 0xAD, 0xBE,
+	0x58, 0x13, 0x64, 0x60, 0x7C, 0x05, 0xFC, 0xE3,
+	0x51, 0x7A, 0xF2, 0xCC, 0x54, 0x16, 0x2C, 0xA4,
+	0xCE, 0x5F, 0x59, 0x12, 0x77, 0xEB, 0xD9, 0x23,
+	0xE3, 0x86, 0xFB, 0xD7, 0x48, 0x76, 0x9D, 0xE3,
+	0x89, 0x87, 0x39, 0xFA, 0x7B, 0x21, 0x0B, 0x76,
+	0xB2, 0xED, 0x1C, 0x27, 0x4B, 0xD5, 0x27, 0x05,
+	0x8C, 0x7D, 0x58, 0x6C, 0xCA, 0xA5, 0x54, 0x9A,
+	0x0F, 0xCB, 0xE9, 0x88, 0x31, 0xAD, 0x49, 0xEE,
+	0x38, 0xFB, 0xC9, 0xFB, 0xB4, 0x7A, 0x00, 0x58,
+	0x20, 0x32, 0xD3, 0x53, 0x5A, 0xDD, 0x74, 0x95,
+	0x60, 0x59, 0x09, 0xAE, 0x7E, 0xEC, 0x74, 0xA3,
+	0xB7, 0x1C, 0x6D, 0xF2, 0xAE, 0x79, 0xA4, 0x7C
+};
+
+/** AES-256-CBC test vector */
+static const struct blockcipher_test_data aes_test_data_11 = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A,
+			0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0,
+			0x37, 0x07, 0xB8, 0x23, 0xA2, 0xA3, 0xB5, 0x8D
+		},
+		.len = 32
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes_common,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_aes256cbc,
+		.len = 512
+	}
+};
+
 static const struct blockcipher_test_case aes_chain_test_cases[] = {
 	{
 		.test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest",
 		.test_data = &aes_test_data_1,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -648,6 +840,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_1,
 		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -669,6 +862,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_3,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -677,6 +871,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_3,
 		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -684,6 +879,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_4,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -692,6 +888,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_4,
 		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -699,6 +896,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_5,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -707,6 +905,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_5,
 		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -714,6 +913,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_6,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -722,7 +922,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_6,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
 		.feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS,
-		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
 	},
 	{
 		.test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest "
@@ -730,6 +931,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_6,
 		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -752,7 +954,8 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_4,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
 		.feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP,
-		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
 	},
 	{
 		.test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest "
@@ -760,13 +963,15 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_4,
 		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
 		.feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP,
-		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
 	},
 	{
 		.test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest",
 		.test_data = &aes_test_data_8,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -775,6 +980,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_8,
 		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -782,6 +988,7 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_9,
 		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -790,8 +997,99 @@ static const struct blockcipher_test_case aes_chain_test_cases[] = {
 		.test_data = &aes_test_data_9,
 		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
 		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
 			BLOCKCIPHER_TEST_TARGET_PMD_QAT
 	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest Sessionless",
+		.test_data = &aes_test_data_4,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr =
+				"AES-128-CBC HMAC-SHA1 Decryption Digest Verify Sessionless",
+		.test_data = &aes_test_data_4,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+};
+
+static const struct blockcipher_test_case aes_cipheronly_test_cases[] = {
+	{
+		.test_descr = "AES-128-CBC Encryption",
+		.test_data = &aes_test_data_4,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "AES-128-CBC Decryption",
+		.test_data = &aes_test_data_4,
+		.op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "AES-192-CBC Encryption",
+		.test_data = &aes_test_data_10,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "AES-192-CBC Decryption",
+		.test_data = &aes_test_data_10,
+		.op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "AES-256-CBC Encryption",
+		.test_data = &aes_test_data_11,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "AES-256-CBC Decryption",
+		.test_data = &aes_test_data_11,
+		.op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "AES-128-CTR Encryption",
+		.test_data = &aes_test_data_1,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "AES-128-CTR Decryption",
+		.test_data = &aes_test_data_1,
+		.op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "AES-192-CTR Encryption",
+		.test_data = &aes_test_data_2,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "AES-192-CTR Decryption",
+		.test_data = &aes_test_data_2,
+		.op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "AES-256-CTR Encryption",
+		.test_data = &aes_test_data_3,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "AES-256-CTR Decryption",
+		.test_data = &aes_test_data_3,
+		.op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
 };
 
 #endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */
diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c
index 6661859..6649080 100644
--- a/app/test/test_cryptodev_blockcipher.c
+++ b/app/test/test_cryptodev_blockcipher.c
@@ -43,6 +43,8 @@
 #include "test.h"
 #include "test_cryptodev_blockcipher.h"
 #include "test_cryptodev_aes_test_vectors.h"
+#include "test_cryptodev_des_test_vectors.h"
+#include "test_cryptodev_hash_test_vectors.h"
 
 static int
 test_blockcipher_one_case(const struct blockcipher_test_case *t,
@@ -79,6 +81,7 @@ test_blockcipher_one_case(const struct blockcipher_test_case *t,
 
 	switch (cryptodev_type) {
 	case RTE_CRYPTODEV_QAT_SYM_PMD:
+	case RTE_CRYPTODEV_LIBCRYPTO_PMD:
 		digest_len = tdata->digest.len;
 		break;
 	case RTE_CRYPTODEV_AESNI_MB_PMD:
@@ -465,9 +468,25 @@ test_blockcipher_all_tests(struct rte_mempool *mbuf_pool,
 		tcs = aes_chain_test_cases;
 		break;
 	case BLKCIPHER_AES_CIPHERONLY_TYPE:
+		n_test_cases = sizeof(aes_cipheronly_test_cases) /
+		sizeof(aes_cipheronly_test_cases[0]);
+		tcs = aes_cipheronly_test_cases;
+		break;
 	case BLKCIPHER_3DES_CHAIN_TYPE:
+		n_test_cases = sizeof(triple_des_chain_test_cases) /
+		sizeof(triple_des_chain_test_cases[0]);
+		tcs = triple_des_chain_test_cases;
+		break;
 	case BLKCIPHER_3DES_CIPHERONLY_TYPE:
+		n_test_cases = sizeof(triple_des_cipheronly_test_cases) /
+		sizeof(triple_des_cipheronly_test_cases[0]);
+		tcs = triple_des_cipheronly_test_cases;
+		break;
 	case BLKCIPHER_AUTHONLY_TYPE:
+		n_test_cases = sizeof(hash_test_cases) /
+		sizeof(hash_test_cases[0]);
+		tcs = hash_test_cases;
+		break;
 	default:
 		break;
 	}
@@ -479,6 +498,9 @@ test_blockcipher_all_tests(struct rte_mempool *mbuf_pool,
 	case RTE_CRYPTODEV_QAT_SYM_PMD:
 		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT;
 		break;
+	case RTE_CRYPTODEV_LIBCRYPTO_PMD:
+		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO;
+		break;
 	default:
 		TEST_ASSERT(0, "Unrecognized cryptodev type");
 		break;
diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h
index 686e6fb..3232a86 100644
--- a/app/test/test_cryptodev_blockcipher.h
+++ b/app/test/test_cryptodev_blockcipher.h
@@ -48,6 +48,7 @@
 
 #define BLOCKCIPHER_TEST_TARGET_PMD_MB			0x0001 /* Multi-buffer flag */
 #define BLOCKCIPHER_TEST_TARGET_PMD_QAT			0x0002 /* QAT flag */
+#define BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO	0x0004 /* SW LIBCRYPTO flag */
 
 #define BLOCKCIPHER_TEST_OP_CIPHER		(BLOCKCIPHER_TEST_OP_ENCRYPT |		\
 					BLOCKCIPHER_TEST_OP_DECRYPT)
diff --git a/app/test/test_cryptodev_des_test_vectors.h b/app/test/test_cryptodev_des_test_vectors.h
new file mode 100644
index 0000000..f3144fe
--- /dev/null
+++ b/app/test/test_cryptodev_des_test_vectors.h
@@ -0,0 +1,952 @@
+/*
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *	 * Redistributions of source code must retain the above copyright
+ *	   notice, this list of conditions and the following disclaimer.
+ *	 * Redistributions in binary form must reproduce the above copyright
+ *	   notice, this list of conditions and the following disclaimer in
+ *	   the documentation and/or other materials provided with the
+ *	   distribution.
+ *	 * Neither the name of Intel Corporation nor the names of its
+ *	   contributors may be used to endorse or promote products derived
+ *	   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEST_CRYPTODEV_DES_TEST_VECTORS_H_
+#define TEST_CRYPTODEV_DES_TEST_VECTORS_H_
+
+static const uint8_t plaintext_des[] = {
+	"What a lousy earth! He wondered how many people "
+	"were destitute that same night even in his own "
+	"prosperous country, how many homes were "
+	"shanties, how many husbands were drunk and "
+	"wives socked, and how many children were "
+	"bullied, abused, or abandoned. How many "
+	"families hungered for food they could not "
+	"afford to buy? How many hearts were broken? How "
+	"many suicides would take place that same night, "
+	"how many people would go insane? How many "
+	"cockroaches and landlords would triumph? How "
+	"many winners were losers, successes failures, "
+	"and rich men poor men? How many wise guys were "
+	"stupid? How many happy endings were unhappy "
+	"endings? How many honest men were liars, brave "
+	"men cowards, loyal men traitors, how many "
+	"sainted men were corrupt, how many people in "
+	"positions of trust had sold their souls to "
+	"bodyguards, how many had never had souls? How "
+	"many straight-and-narrow paths were crooked "
+	"paths? How many best families were worst "
+	"families and how many good people were bad "
+	"people? When you added them all up and then "
+	"subtracted, you might be left with only the "
+	"children, and perhaps with Albert Einstein and "
+	"an old violinist or sculptor somewhere."
+};
+
+static const uint8_t ciphertext512_des128ctr[] = {
+	0x13, 0x39, 0x3B, 0xBC, 0x1D, 0xE3, 0x23, 0x09,
+	0x9B, 0x08, 0xD1, 0x09, 0x52, 0x93, 0x78, 0x29,
+	0x11, 0x21, 0xBA, 0x01, 0x15, 0xCD, 0xEC, 0xAA,
+	0x79, 0x77, 0x58, 0xAE, 0xAE, 0xBC, 0x97, 0x33,
+	0x94, 0xA9, 0x2D, 0xC0, 0x0A, 0xA9, 0xA4, 0x4B,
+	0x19, 0x07, 0x88, 0x06, 0x7E, 0x81, 0x0F, 0xB5,
+	0x60, 0xCF, 0xA7, 0xC3, 0x2A, 0x43, 0xFF, 0x16,
+	0x3A, 0x5F, 0x11, 0x2D, 0x11, 0x38, 0x37, 0x94,
+	0x2A, 0xC8, 0x3D, 0x20, 0xBB, 0x93, 0x95, 0x54,
+	0x12, 0xFF, 0x0C, 0x47, 0x89, 0x7D, 0x73, 0xD1,
+	0x2E, 0x3A, 0x80, 0x52, 0xA8, 0x92, 0x93, 0x99,
+	0x16, 0xB8, 0x12, 0x1B, 0x8B, 0xA8, 0xC1, 0x81,
+	0x95, 0x18, 0x82, 0xD6, 0x5A, 0xA7, 0xFE, 0xCF,
+	0xC4, 0xAC, 0x85, 0x91, 0x0C, 0x2F, 0x1D, 0x10,
+	0x9A, 0x65, 0x07, 0xB0, 0x2E, 0x5A, 0x2D, 0x48,
+	0x26, 0xF8, 0x17, 0x7A, 0x53, 0xD6, 0xB8, 0xDF,
+	0xB1, 0x10, 0x48, 0x7E, 0x8F, 0xBE, 0x2E, 0xA1,
+	0x0D, 0x9E, 0xA9, 0xF1, 0x3B, 0x3B, 0x33, 0xCD,
+	0xDC, 0x52, 0x7E, 0xC0, 0x0E, 0xA0, 0xD8, 0xA7,
+	0xC6, 0x34, 0x5A, 0xAA, 0x29, 0x8B, 0xA9, 0xAC,
+	0x1F, 0x78, 0xAD, 0xEE, 0x34, 0x59, 0x30, 0xFB,
+	0x2A, 0x20, 0x3D, 0x4D, 0x30, 0xA7, 0x7D, 0xD8,
+	0xA0, 0xC6, 0xA2, 0xD3, 0x9A, 0xFB, 0x50, 0x97,
+	0x4D, 0x25, 0xA2, 0x37, 0x51, 0x54, 0xB7, 0xEB,
+	0xED, 0x77, 0xDB, 0x94, 0x35, 0x8B, 0x70, 0x95,
+	0x4A, 0x00, 0xA7, 0xF1, 0x8A, 0x66, 0x0E, 0xC6,
+	0x05, 0x7B, 0x69, 0x05, 0x42, 0x03, 0x96, 0x2C,
+	0x55, 0x00, 0x1B, 0xC0, 0x19, 0x4D, 0x0D, 0x2E,
+	0xF5, 0x81, 0x11, 0x64, 0xCA, 0xBB, 0xF2, 0x0F,
+	0x9C, 0x60, 0xE2, 0xCC, 0x02, 0x6E, 0x83, 0xD5,
+	0x24, 0xF4, 0x12, 0x0E, 0x6A, 0xEA, 0x4F, 0x6C,
+	0x79, 0x69, 0x65, 0x67, 0xDB, 0xF7, 0xEA, 0x98,
+	0x5D, 0x56, 0x98, 0xB7, 0x88, 0xE7, 0x23, 0xC9,
+	0x17, 0x32, 0x92, 0x33, 0x5A, 0x0C, 0x15, 0x20,
+	0x3B, 0x1C, 0xF9, 0x0F, 0x4D, 0xD1, 0xE8, 0xE6,
+	0x9E, 0x5E, 0x24, 0x1B, 0xA4, 0xB8, 0xB9, 0xE9,
+	0x2F, 0xFC, 0x89, 0xB4, 0xB9, 0xF4, 0xA6, 0xAD,
+	0x55, 0xF4, 0xDF, 0x58, 0x63, 0x25, 0xE3, 0x41,
+	0x70, 0xDF, 0x10, 0xE7, 0x13, 0x87, 0x8D, 0xB3,
+	0x62, 0x4F, 0xF5, 0x86, 0x85, 0x8F, 0x59, 0xF0,
+	0x21, 0x0E, 0x8F, 0x11, 0xAD, 0xBF, 0xDD, 0x61,
+	0x68, 0x3F, 0x54, 0x57, 0x49, 0x38, 0xC8, 0x24,
+	0x8E, 0x0A, 0xAC, 0xCA, 0x2C, 0x36, 0x3E, 0x5F,
+	0x0A, 0xCE, 0xFD, 0x1A, 0x60, 0x63, 0x5A, 0xE6,
+	0x06, 0x64, 0xB5, 0x94, 0x3C, 0xC9, 0xAF, 0x7C,
+	0xCD, 0x49, 0x10, 0xCF, 0xAF, 0x0E, 0x2E, 0x79,
+	0x27, 0xB2, 0x67, 0x02, 0xED, 0xEE, 0x80, 0x77,
+	0x7C, 0x6D, 0x4B, 0xDB, 0xCF, 0x8D, 0x68, 0x00,
+	0x2E, 0xD9, 0xF0, 0x8E, 0x08, 0xBF, 0xA6, 0x9B,
+	0xFE, 0xA4, 0xFB, 0x19, 0x46, 0xAF, 0x1B, 0xA9,
+	0xF8, 0x22, 0x81, 0x21, 0x97, 0xFC, 0xC0, 0x8A,
+	0x26, 0x58, 0x13, 0x29, 0xB6, 0x69, 0x94, 0x4B,
+	0xAB, 0xB3, 0x88, 0x0D, 0xA9, 0x48, 0x0E, 0xE8,
+	0x70, 0xFC, 0xA1, 0x21, 0xC4, 0x2C, 0xE5, 0x99,
+	0xB4, 0xF1, 0x6F, 0xB2, 0x4B, 0x4B, 0xCD, 0x48,
+	0x15, 0x47, 0x2D, 0x72, 0x39, 0x99, 0x9D, 0x24,
+	0x0C, 0x8B, 0xDC, 0xA1, 0xEE, 0xF6, 0xF4, 0x73,
+	0xC3, 0xB8, 0x0C, 0x23, 0x0D, 0xA7, 0xC4, 0x7D,
+	0x27, 0xE2, 0x14, 0x11, 0x53, 0x19, 0xE7, 0xCA,
+	0x94, 0x4E, 0x0D, 0x2C, 0xF7, 0x36, 0x47, 0xDB,
+	0x77, 0x3C, 0x22, 0xAC, 0xBE, 0xE1, 0x06, 0x55,
+	0xE5, 0xDD, 0x8B, 0x65, 0xE8, 0xE9, 0x91, 0x52,
+	0x59, 0x97, 0xFC, 0x8C, 0xEE, 0x96, 0x22, 0x60,
+	0xEE, 0xBF, 0x82, 0xF0, 0xCA, 0x14, 0xF9, 0xD3
+};
+
+static const struct blockcipher_test_data
+triple_des128ctr_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des128ctr,
+		.len = 512
+	}
+};
+
+static const struct blockcipher_test_data
+triple_des128ctr_sha1_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des128ctr,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1,
+	.digest = {
+		.data = {
+			0xC3, 0x40, 0xD5, 0xD9, 0x8F, 0x8A, 0xC0, 0xF0,
+			0x46, 0x28, 0x02, 0x01, 0xB5, 0xC1, 0x87, 0x4D,
+			0xAC, 0xFE, 0x48, 0x76
+		},
+		.len = 20
+	}
+};
+
+static const struct blockcipher_test_data
+triple_des128ctr_hmac_sha1_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des128ctr,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD
+		},
+		.len = 20
+	},
+	.digest = {
+		.data = {
+			0xF1, 0xC1, 0xDB, 0x4D, 0xFA, 0x7F, 0x2F, 0xE5,
+			0xF8, 0x49, 0xEA, 0x1D, 0x7F, 0xCB, 0x42, 0x59,
+			0xC4, 0x1E, 0xB1, 0x18
+		},
+		.len = 20
+	}
+};
+
+static const uint8_t ciphertext512_des192ctr[] = {
+	0xFF, 0x32, 0x52, 0x97, 0x10, 0xBF, 0x0B, 0x10,
+	0x68, 0x0F, 0x4F, 0x56, 0x8B, 0x2C, 0x7B, 0x8E,
+	0x39, 0x1E, 0x1A, 0x2F, 0x83, 0xDE, 0x5E, 0x35,
+	0xC8, 0x4B, 0xDF, 0xD5, 0xBC, 0x84, 0x50, 0x1A,
+	0x02, 0xDF, 0xB3, 0x11, 0xE4, 0xDA, 0xB8, 0x0E,
+	0x47, 0xC6, 0x0C, 0x51, 0x09, 0x62, 0x9C, 0x5D,
+	0x71, 0x40, 0x49, 0xD8, 0x55, 0xBD, 0x7D, 0x90,
+	0x71, 0xC5, 0xF7, 0x07, 0x6F, 0x08, 0x71, 0x2A,
+	0xB1, 0x77, 0x9B, 0x0F, 0xA1, 0xB0, 0xD6, 0x10,
+	0xB2, 0xE5, 0x31, 0xEC, 0x21, 0x13, 0x89, 0x2A,
+	0x09, 0x7E, 0x30, 0xDB, 0xA0, 0xF0, 0xDC, 0xE4,
+	0x74, 0x64, 0x39, 0xA3, 0xB0, 0xB1, 0x80, 0x66,
+	0x52, 0xD4, 0x4E, 0xC9, 0x5A, 0x52, 0x6A, 0xC7,
+	0xB5, 0x2B, 0x61, 0xD5, 0x17, 0xD5, 0xF3, 0xCC,
+	0x41, 0x61, 0xD2, 0xA6, 0xF4, 0x51, 0x24, 0x3A,
+	0x63, 0x5D, 0x23, 0xB1, 0xF0, 0x22, 0xE7, 0x45,
+	0xFA, 0x5F, 0x7E, 0x99, 0x00, 0x11, 0x28, 0x35,
+	0xA3, 0xF4, 0x61, 0x94, 0x0E, 0x98, 0xCE, 0x35,
+	0xDD, 0x91, 0x1B, 0x0B, 0x4D, 0xEE, 0xFF, 0xFF,
+	0x0B, 0xD4, 0xDC, 0x56, 0xFC, 0x71, 0xE9, 0xEC,
+	0xE8, 0x36, 0x51, 0xF8, 0x8B, 0x6A, 0xE1, 0x8C,
+	0x2B, 0x25, 0x91, 0x91, 0x9B, 0x92, 0x76, 0xB5,
+	0x3D, 0x26, 0xA8, 0x53, 0xEA, 0x30, 0x5B, 0x4D,
+	0xDA, 0x16, 0xDA, 0x7D, 0x04, 0x88, 0xF5, 0x22,
+	0xA8, 0x0C, 0xB9, 0x41, 0xC7, 0x91, 0x64, 0x86,
+	0x99, 0x7D, 0x18, 0xB9, 0x67, 0xA2, 0x6E, 0x05,
+	0x1A, 0x82, 0x8F, 0xA2, 0xEB, 0x4D, 0x0B, 0x8C,
+	0x88, 0x2D, 0xBA, 0x77, 0x87, 0x32, 0x50, 0x3C,
+	0x4C, 0xD8, 0xD3, 0x50, 0x39, 0xFA, 0xDF, 0x48,
+	0x3E, 0x30, 0xF5, 0x76, 0x06, 0xB0, 0x1A, 0x05,
+	0x60, 0x2C, 0xD3, 0xA0, 0x63, 0x1A, 0x19, 0x2D,
+	0x6B, 0x76, 0xF2, 0x31, 0x4C, 0xA7, 0xE6, 0x5C,
+	0x1B, 0x23, 0x20, 0x41, 0x32, 0xE5, 0x83, 0x47,
+	0x04, 0xB6, 0x3E, 0xE0, 0xFD, 0x49, 0x1E, 0x1B,
+	0x75, 0x10, 0x11, 0x46, 0xE9, 0xF9, 0x96, 0x9A,
+	0xD7, 0x59, 0xFE, 0x38, 0x31, 0xFE, 0x79, 0xC4,
+	0xC8, 0x46, 0x88, 0xDE, 0x2E, 0xAE, 0x20, 0xED,
+	0x77, 0x50, 0x40, 0x38, 0x26, 0xD3, 0x35, 0xF6,
+	0x29, 0x55, 0x6A, 0x6B, 0x38, 0x69, 0xFE, 0x90,
+	0x5B, 0xA7, 0xFA, 0x6B, 0x73, 0x4F, 0xB9, 0x5D,
+	0xDC, 0x6F, 0x98, 0xC3, 0x6A, 0xC4, 0xB5, 0x09,
+	0xC5, 0x84, 0xA5, 0x6A, 0x84, 0xA4, 0xB3, 0x8A,
+	0x5F, 0xCA, 0x92, 0x64, 0x9E, 0xC3, 0x0F, 0x84,
+	0x8B, 0x2D, 0x48, 0xC6, 0x67, 0xAE, 0x07, 0xE0,
+	0x28, 0x38, 0x6D, 0xC4, 0x4D, 0x13, 0x87, 0xE0,
+	0xB2, 0x2F, 0xAA, 0xC0, 0xCF, 0x68, 0xD7, 0x9C,
+	0xB8, 0x07, 0xE4, 0x51, 0xD7, 0x75, 0x86, 0xFA,
+	0x0C, 0x50, 0x74, 0x68, 0x00, 0x64, 0x2A, 0x27,
+	0x59, 0xE9, 0x80, 0xEB, 0xC2, 0xA3, 0xFA, 0x58,
+	0xCC, 0x03, 0xE7, 0x7B, 0x66, 0x53, 0xFF, 0x90,
+	0xA0, 0x85, 0xE2, 0xF8, 0x82, 0xFE, 0xC6, 0x2B,
+	0xFF, 0x5E, 0x70, 0x85, 0x34, 0xB7, 0x22, 0x38,
+	0xDB, 0xBC, 0x15, 0x30, 0x59, 0xC1, 0x48, 0x42,
+	0xE5, 0x38, 0x8D, 0x37, 0x59, 0xDB, 0xA3, 0x20,
+	0x17, 0x36, 0x1D, 0x4B, 0xBF, 0x4E, 0xA4, 0x35,
+	0xCC, 0xFE, 0xF5, 0x7A, 0x73, 0xB4, 0x6D, 0x20,
+	0x1D, 0xC0, 0xE5, 0x21, 0x5C, 0xD2, 0x8A, 0x65,
+	0x08, 0xB6, 0x63, 0xAC, 0x9A, 0x1E, 0x3F, 0x3C,
+	0xAB, 0xB6, 0x6D, 0x34, 0xB2, 0x3A, 0x08, 0xDA,
+	0x29, 0x63, 0xD1, 0xA4, 0x83, 0x52, 0xB0, 0x63,
+	0x1B, 0x89, 0x35, 0x57, 0x59, 0x2C, 0x0F, 0x72,
+	0x72, 0xFD, 0xA0, 0xAC, 0xDB, 0xB4, 0xA3, 0xA1,
+	0x18, 0x10, 0x12, 0x97, 0x99, 0x63, 0x38, 0x98,
+	0x96, 0xB5, 0x16, 0x07, 0x4E, 0xE9, 0x2C, 0x97
+};
+
+static const struct blockcipher_test_data
+triple_des192ctr_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A,
+			0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0
+		},
+		.len = 24
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des192ctr,
+		.len = 512
+	}
+};
+
+static const struct blockcipher_test_data
+triple_des192ctr_sha1_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A,
+			0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0
+		},
+		.len = 24
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des192ctr,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1,
+	.digest = {
+		.data = {
+			0xEA, 0x62, 0xB9, 0xB2, 0x78, 0x6C, 0x8E, 0xDB,
+			0xA3, 0xB6, 0xFF, 0x23, 0x3A, 0x47, 0xD8, 0xC8,
+			0xED, 0x5E, 0x20, 0x1D
+		},
+		.len = 20
+	}
+};
+
+static const struct blockcipher_test_data
+triple_des192ctr_hmac_sha1_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CTR,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A,
+			0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0
+		},
+		.len = 24
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des192ctr,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD
+		},
+		.len = 20
+	},
+	.digest = {
+		.data = {
+			0x32, 0xD5, 0x19, 0x8F, 0x79, 0x3A, 0xAA, 0x7B,
+			0x70, 0x67, 0x4E, 0x63, 0x88, 0xA3, 0x9A, 0x82,
+			0x07, 0x33, 0x12, 0x94
+		},
+		.len = 20
+	}
+};
+
+static const uint8_t ciphertext512_des128cbc[] = {
+	0x28, 0x2a, 0xff, 0x15, 0x5c, 0xdf, 0xd9, 0x6b,
+	0x54, 0xbc, 0x7b, 0xfb, 0xc5, 0x64, 0x4d, 0xdd,
+	0x3e, 0xf2, 0x9e, 0xb7, 0x53, 0x65, 0x37, 0x05,
+	0xe0, 0xdf, 0xae, 0xf7, 0xc9, 0x27, 0xe4, 0xec,
+	0x11, 0x27, 0xc2, 0x9e, 0x02, 0x4e, 0x03, 0x3b,
+	0x33, 0xf2, 0x66, 0x08, 0x24, 0x5f, 0xab, 0xc2,
+	0x7e, 0x21, 0x19, 0x5d, 0x51, 0xc3, 0xe2, 0x97,
+	0x6f, 0x2e, 0xb4, 0xaa, 0x34, 0x70, 0x88, 0x78,
+	0x4e, 0xe7, 0x3d, 0xe1, 0x9f, 0x87, 0x1c, 0x8b,
+	0xac, 0x8d, 0xa1, 0x1a, 0xcd, 0xb0, 0xf8, 0xb6,
+	0x24, 0x36, 0xe3, 0x8c, 0x07, 0xe7, 0xe4, 0x92,
+	0x13, 0x86, 0x6f, 0x13, 0xec, 0x04, 0x5c, 0xe9,
+	0xb9, 0xca, 0x45, 0x8a, 0x2c, 0x46, 0xda, 0x54,
+	0x1d, 0xb5, 0x81, 0xb1, 0xcd, 0xf3, 0x7d, 0x11,
+	0x6b, 0xb3, 0x0a, 0x45, 0xe5, 0x6e, 0x51, 0x3e,
+	0x2c, 0xac, 0x7c, 0xbc, 0xa7, 0x7e, 0x22, 0x4d,
+	0xe6, 0x02, 0xe3, 0x3f, 0x77, 0xd7, 0x73, 0x72,
+	0x0e, 0xfb, 0x42, 0x85, 0x80, 0xdf, 0xa8, 0x91,
+	0x60, 0x40, 0x48, 0xcd, 0x1b, 0xd9, 0xbf, 0x2f,
+	0xf2, 0xdf, 0xd0, 0xbd, 0x3f, 0x82, 0xce, 0x15,
+	0x9d, 0x6e, 0xc6, 0x59, 0x6f, 0x27, 0x0d, 0xf9,
+	0x26, 0xe2, 0x11, 0x29, 0x50, 0xc3, 0x0a, 0xb7,
+	0xde, 0x9d, 0xe9, 0x55, 0xa1, 0xe9, 0x01, 0x33,
+	0x56, 0x51, 0xa7, 0x3a, 0x9e, 0x63, 0xc5, 0x08,
+	0x01, 0x3b, 0x03, 0x4b, 0xc6, 0xc4, 0xa1, 0xc0,
+	0xc0, 0xd0, 0x0e, 0x48, 0xe5, 0x4c, 0x55, 0x6b,
+	0x4a, 0xc1, 0x0a, 0x24, 0x4b, 0xd0, 0x02, 0xf4,
+	0x31, 0x63, 0x11, 0xbd, 0xa6, 0x1f, 0xf4, 0xae,
+	0x23, 0x5a, 0x40, 0x7e, 0x0e, 0x4e, 0x63, 0x8b,
+	0x66, 0x3d, 0x55, 0x46, 0x6e, 0x5c, 0x76, 0xa7,
+	0x68, 0x31, 0xce, 0x5d, 0xca, 0xe2, 0xb4, 0xb0,
+	0xc1, 0x1f, 0x66, 0x18, 0x75, 0x64, 0x73, 0xa9,
+	0x9e, 0xd5, 0x0e, 0x0e, 0xf7, 0x77, 0x61, 0xf8,
+	0x89, 0xc6, 0xcf, 0x0c, 0x41, 0xd3, 0x8f, 0xfd,
+	0x22, 0x52, 0x4f, 0x94, 0x5c, 0x19, 0x11, 0x3a,
+	0xb5, 0x63, 0xe8, 0x81, 0x33, 0x13, 0x54, 0x3c,
+	0x93, 0x36, 0xb5, 0x5b, 0x51, 0xaf, 0x51, 0xa2,
+	0x08, 0xae, 0x83, 0x15, 0x77, 0x07, 0x28, 0x0d,
+	0x98, 0xe1, 0x2f, 0x69, 0x0e, 0xfb, 0x9a, 0x2e,
+	0x27, 0x27, 0xb0, 0xd5, 0xce, 0xf8, 0x16, 0x55,
+	0xfd, 0xaa, 0xd7, 0x1a, 0x1b, 0x2e, 0x4c, 0x86,
+	0x7a, 0x6a, 0x90, 0xf7, 0x0a, 0x07, 0xd3, 0x81,
+	0x4b, 0x75, 0x6a, 0x79, 0xdb, 0x63, 0x45, 0x0f,
+	0x31, 0x7e, 0xd0, 0x2a, 0x14, 0xff, 0xee, 0xcc,
+	0x97, 0x8a, 0x7d, 0x74, 0xbd, 0x9d, 0xaf, 0x00,
+	0xdb, 0x7e, 0xf3, 0xe6, 0x22, 0x76, 0x77, 0x58,
+	0xba, 0x1c, 0x06, 0x96, 0xfb, 0x6f, 0x41, 0x71,
+	0x66, 0x98, 0xae, 0x31, 0x7d, 0x29, 0x18, 0x71,
+	0x0e, 0xe4, 0x98, 0x7e, 0x59, 0x5a, 0xc9, 0x78,
+	0x9c, 0xfb, 0x6c, 0x81, 0x44, 0xb4, 0x0f, 0x5e,
+	0x18, 0x53, 0xb8, 0x6f, 0xbc, 0x3b, 0x15, 0xf0,
+	0x10, 0xdd, 0x0d, 0x4b, 0x0a, 0x36, 0x0e, 0xb4,
+	0x76, 0x0f, 0x16, 0xa7, 0x5c, 0x9d, 0xcf, 0xb0,
+	0x6d, 0x38, 0x02, 0x07, 0x05, 0xe9, 0xe9, 0x46,
+	0x08, 0xb8, 0x52, 0xd6, 0xd9, 0x4c, 0x81, 0x63,
+	0x1d, 0xe2, 0x5b, 0xd0, 0xf6, 0x5e, 0x1e, 0x81,
+	0x48, 0x08, 0x66, 0x3a, 0x85, 0xed, 0x65, 0xfe,
+	0xe8, 0x05, 0x7a, 0xe1, 0xe6, 0x12, 0xf2, 0x52,
+	0x83, 0xdd, 0x82, 0xbe, 0xf6, 0x34, 0x8a, 0x6f,
+	0xc5, 0x83, 0xcd, 0x3f, 0xbe, 0x58, 0x8b, 0x11,
+	0x78, 0xdc, 0x0c, 0x83, 0x72, 0x5d, 0x05, 0x2a,
+	0x01, 0x29, 0xee, 0x48, 0x9a, 0x67, 0x00, 0x6e,
+	0x14, 0x60, 0x2d, 0x00, 0x52, 0x87, 0x98, 0x5e,
+	0x43, 0xfe, 0xf1, 0x10, 0x14, 0xf1, 0x91, 0xcc
+};
+
+static const struct blockcipher_test_data
+triple_des128cbc_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des128cbc,
+		.len = 512
+	}
+};
+
+static const struct blockcipher_test_data
+triple_des128cbc_sha1_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1,
+	.digest = {
+		.data = {
+			0x94, 0x45, 0x7B, 0xDF, 0xFE, 0x80, 0xB9, 0xA6,
+			0xA0, 0x7A, 0xE8, 0x93, 0x40, 0x7B, 0x85, 0x02,
+			0x1C, 0xD7, 0xE8, 0x87
+		},
+		.len = 20
+	}
+};
+
+static const struct blockcipher_test_data
+triple_des128cbc_hmac_sha1_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD
+		},
+		.len = 20
+	},
+	.digest = {
+		.data = {
+			0x7E, 0xBA, 0xFF, 0x86, 0x8D, 0x65, 0xCD, 0x08,
+			0x76, 0x34, 0x94, 0xE9, 0x9A, 0xCD, 0xB2, 0xBB,
+			0xBF, 0x65, 0xF5, 0x42
+		},
+		.len = 20
+	}
+};
+
+static const uint8_t ciphertext512_des192cbc[] = {
+	0xd0, 0xc9, 0xdc, 0x51, 0x29, 0x97, 0x03, 0x64,
+	0xcd, 0x22, 0xba, 0x3d, 0x2b, 0xbc, 0x21, 0x37,
+	0x7b, 0x1e, 0x29, 0x23, 0xeb, 0x51, 0x6e, 0xac,
+	0xbe, 0x5b, 0xd3, 0x67, 0xe0, 0x3f, 0xc3, 0xb5,
+	0xe3, 0x04, 0x17, 0x42, 0x2b, 0xaa, 0xdd, 0xd6,
+	0x0e, 0x69, 0xd0, 0x8f, 0x8a, 0xfc, 0xb4, 0x55,
+	0x67, 0x06, 0x51, 0xbb, 0x00, 0x57, 0xee, 0x95,
+	0x28, 0x79, 0x3f, 0xd9, 0x97, 0x2b, 0xb0, 0x02,
+	0x35, 0x08, 0xce, 0x7a, 0xc3, 0x43, 0x2c, 0x87,
+	0xaa, 0x97, 0x6a, 0xad, 0xf0, 0x26, 0xea, 0x1d,
+	0xbb, 0x08, 0xe9, 0x52, 0x11, 0xd3, 0xaf, 0x36,
+	0x17, 0x14, 0x21, 0xb2, 0xbc, 0x42, 0x51, 0x33,
+	0x27, 0x8c, 0xd8, 0x45, 0xb9, 0x76, 0xa0, 0x11,
+	0x24, 0x34, 0xde, 0x4d, 0x13, 0x67, 0x1b, 0xc3,
+	0x31, 0x12, 0x66, 0x56, 0x59, 0xd2, 0xb1, 0x8f,
+	0xec, 0x1e, 0xc0, 0x10, 0x7a, 0x86, 0xb1, 0x60,
+	0xc3, 0x01, 0xd6, 0xa8, 0x55, 0xad, 0x58, 0x63,
+	0xca, 0x68, 0xa9, 0x33, 0xe3, 0x93, 0x90, 0x7d,
+	0x8f, 0xca, 0xf8, 0x1c, 0xc2, 0x9e, 0xfb, 0xde,
+	0x9c, 0xc7, 0xf2, 0x6c, 0xff, 0xcc, 0x39, 0x17,
+	0x49, 0x33, 0x0d, 0x7c, 0xed, 0x07, 0x99, 0x91,
+	0x91, 0x6c, 0x5f, 0x3f, 0x02, 0x09, 0xdc, 0x70,
+	0xf9, 0x3b, 0x8d, 0xaa, 0xf4, 0xbc, 0x0e, 0xec,
+	0xf2, 0x26, 0xfb, 0xb2, 0x1c, 0x31, 0xae, 0xc6,
+	0x72, 0xe8, 0x0b, 0x75, 0x05, 0x57, 0x58, 0x98,
+	0x92, 0x37, 0x27, 0x8e, 0x3b, 0x0c, 0x25, 0xfb,
+	0xcf, 0x82, 0x02, 0xd5, 0x0b, 0x1f, 0x89, 0x49,
+	0xcd, 0x0f, 0xa1, 0xa7, 0x08, 0x63, 0x56, 0xa7,
+	0x1f, 0x80, 0x3a, 0xef, 0x24, 0x89, 0x57, 0x1a,
+	0x02, 0xdc, 0x2e, 0x51, 0xbd, 0x4a, 0x10, 0x23,
+	0xfc, 0x02, 0x1a, 0x3f, 0x34, 0xbf, 0x1c, 0x98,
+	0x1a, 0x40, 0x0a, 0x96, 0x8e, 0x41, 0xd5, 0x09,
+	0x55, 0x37, 0xe9, 0x25, 0x11, 0x83, 0xf8, 0xf3,
+	0xd4, 0xb0, 0xdb, 0x16, 0xd7, 0x51, 0x7e, 0x94,
+	0xf7, 0xb4, 0x26, 0xe0, 0xf4, 0x80, 0x01, 0x65,
+	0x51, 0xeb, 0xbc, 0xb0, 0x65, 0x8f, 0xdd, 0xb5,
+	0xf7, 0x00, 0xec, 0x40, 0xab, 0x7d, 0x96, 0xcc,
+	0x8d, 0xec, 0x89, 0x80, 0x31, 0x39, 0xa2, 0x5c,
+	0xb0, 0x55, 0x4c, 0xee, 0xdd, 0x15, 0x2b, 0xa9,
+	0x86, 0x4e, 0x23, 0x14, 0x36, 0xc5, 0x57, 0xf5,
+	0xe3, 0xe8, 0x89, 0xc9, 0xb7, 0xf8, 0xeb, 0x08,
+	0xe5, 0x93, 0x12, 0x5c, 0x0f, 0x79, 0xa1, 0x86,
+	0xe4, 0xc2, 0xeb, 0xa6, 0xa0, 0x50, 0x6a, 0xec,
+	0xd3, 0xce, 0x50, 0x78, 0x4e, 0x4f, 0x93, 0xd8,
+	0xdc, 0xb4, 0xec, 0x02, 0xe9, 0xbd, 0x17, 0x99,
+	0x1e, 0x16, 0x4e, 0xd7, 0xb0, 0x07, 0x02, 0x55,
+	0x63, 0x24, 0x4f, 0x7b, 0x8f, 0xc5, 0x7a, 0x12,
+	0x29, 0xff, 0x5d, 0xc1, 0xe7, 0xae, 0x48, 0xc8,
+	0x57, 0x53, 0xe7, 0xcd, 0x10, 0x6c, 0x19, 0xfc,
+	0xcc, 0xb9, 0xb1, 0xbe, 0x48, 0x9f, 0x2d, 0x3f,
+	0x39, 0x2e, 0xdd, 0x71, 0xde, 0x1b, 0x54, 0xee,
+	0x7d, 0x94, 0x8f, 0x27, 0x23, 0xe9, 0x74, 0x92,
+	0x14, 0x93, 0x84, 0x65, 0xc9, 0x22, 0x7c, 0xa8,
+	0x1b, 0x72, 0x73, 0xb1, 0x23, 0xa0, 0x6b, 0xcc,
+	0xb5, 0x22, 0x06, 0x15, 0xe5, 0x96, 0x03, 0x4a,
+	0x52, 0x8d, 0x1d, 0xbf, 0x3e, 0x82, 0x45, 0x9c,
+	0x75, 0x9e, 0xa9, 0x3a, 0x97, 0xb6, 0x5d, 0xc4,
+	0x75, 0x67, 0xa1, 0xf3, 0x0f, 0x7a, 0xfd, 0x71,
+	0x58, 0x04, 0xf9, 0xa7, 0xc2, 0x56, 0x74, 0x04,
+	0x74, 0x68, 0x6d, 0x8a, 0xf6, 0x6c, 0x5d, 0xd8,
+	0xb5, 0xed, 0x70, 0x23, 0x32, 0x4d, 0x75, 0x92,
+	0x88, 0x7b, 0x39, 0x37, 0x02, 0x4b, 0xb2, 0x1c,
+	0x1f, 0x7e, 0x5b, 0x1b, 0x10, 0xfc, 0x17, 0x21,
+	0x66, 0x62, 0x63, 0xc2, 0xcd, 0x16, 0x96, 0x3e
+};
+
+static const struct blockcipher_test_data
+triple_des192cbc_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A,
+			0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0
+		},
+		.len = 24
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des192cbc,
+		.len = 512
+	}
+};
+
+static const struct blockcipher_test_data
+triple_des192cbc_sha1_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A,
+			0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0
+		},
+		.len = 24
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des192cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1,
+	.digest = {
+		.data = {
+			0x53, 0x27, 0xC0, 0xE6, 0xD6, 0x1B, 0xD6, 0x45,
+			0x94, 0x2D, 0xCE, 0x8B, 0x29, 0xA3, 0x52, 0x14,
+			0xC1, 0x6B, 0x87, 0x99
+		},
+		.len = 20
+	}
+};
+
+static const struct blockcipher_test_data
+triple_des192cbc_hmac_sha1_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_3DES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A,
+			0xD4, 0xC3, 0xA3, 0xAA, 0x33, 0x62, 0x61, 0xE0
+		},
+		.len = 24
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
+		},
+		.len = 8
+	},
+	.plaintext = {
+		.data = plaintext_des,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_des192cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD
+		},
+		.len = 20
+	},
+	.digest = {
+		.data = {
+			0xBA, 0xAC, 0x74, 0x19, 0x43, 0xB0, 0x72, 0xB8,
+			0x08, 0xF5, 0x24, 0xC4, 0x09, 0xBD, 0x48, 0xC1,
+			0x3C, 0x50, 0x1C, 0xDD
+		},
+		.len = 20
+	}
+};
+
+static const struct blockcipher_test_case triple_des_chain_test_cases[] = {
+	{
+		.test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest",
+		.test_data = &triple_des128cbc_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify",
+		.test_data = &triple_des128cbc_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-128-CBC SHA1 Encryption Digest",
+		.test_data = &triple_des128cbc_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "3DES-128-CBC SHA1 Decryption Digest Verify",
+		.test_data = &triple_des128cbc_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "3DES-192-CBC HMAC-SHA1 Encryption Digest",
+		.test_data = &triple_des192cbc_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-192-CBC HMAC-SHA1 Decryption Digest Verify",
+		.test_data = &triple_des192cbc_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-192-CBC SHA1 Encryption Digest",
+		.test_data = &triple_des192cbc_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "3DES-192-CBC SHA1 Decryption Digest Verify",
+		.test_data = &triple_des192cbc_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "3DES-128-CTR HMAC-SHA1 Encryption Digest",
+		.test_data = &triple_des128ctr_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-128-CTR HMAC-SHA1 Decryption Digest Verify",
+		.test_data = &triple_des128ctr_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-128-CTR SHA1 Encryption Digest",
+		.test_data = &triple_des128ctr_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "3DES-128-CTR SHA1 Decryption Digest Verify",
+		.test_data = &triple_des128ctr_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "3DES-192-CTR HMAC-SHA1 Encryption Digest",
+		.test_data = &triple_des192ctr_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-192-CTR HMAC-SHA1 Decryption Digest Verify",
+		.test_data = &triple_des192ctr_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-192-CTR SHA1 Encryption Digest",
+		.test_data = &triple_des192ctr_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "3DES-192-CTR SHA1 Decryption Digest Verify",
+		.test_data = &triple_des192ctr_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest OOP",
+		.test_data = &triple_des128cbc_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-128-CBC HMAC-SHA1 Decryption Digest Verify OOP",
+		.test_data = &triple_des128cbc_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-128-CBC HMAC-SHA1 Encryption Digest Sessionless",
+		.test_data = &triple_des128cbc_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr =
+				"3DES-128-CBC HMAC-SHA1 Decryption Digest Verify Sessionless",
+		.test_data = &triple_des128cbc_hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+};
+
+static const struct blockcipher_test_case triple_des_cipheronly_test_cases[] = {
+	{
+		.test_descr = "3DES-128-CBC Encryption",
+		.test_data = &triple_des128cbc_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-128-CBC Decryption",
+		.test_data = &triple_des128cbc_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-192-CBC Encryption",
+		.test_data = &triple_des192cbc_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-192-CBC Decryption",
+		.test_data = &triple_des192cbc_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-128-CTR Encryption",
+		.test_data = &triple_des128ctr_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-128-CTR Decryption",
+		.test_data = &triple_des128ctr_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-192-CTR Encryption",
+		.test_data = &triple_des192ctr_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENCRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "3DES-192-CTR Decryption",
+		.test_data = &triple_des192ctr_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_DECRYPT,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	}
+};
+
+#endif /* TEST_CRYPTODEV_DES_TEST_VECTORS_H_ */
diff --git a/app/test/test_cryptodev_gcm_test_vectors.h b/app/test/test_cryptodev_gcm_test_vectors.h
index deca09d..b404242 100644
--- a/app/test/test_cryptodev_gcm_test_vectors.h
+++ b/app/test/test_cryptodev_gcm_test_vectors.h
@@ -33,6 +33,8 @@
 #ifndef TEST_CRYPTODEV_GCM_TEST_VECTORS_H_
 #define TEST_CRYPTODEV_GCM_TEST_VECTORS_H_
 
+#define GMAC_LARGE_PLAINTEXT_LENGTH		65376
+
 struct gcm_test_data {
 	struct {
 		uint8_t data[64];
@@ -449,7 +451,7 @@ static const struct gcm_test_data gcm_test_case_7 = {
 };
 
 /** GMAC Test Vectors */
-static uint8_t gmac_plaintext[] = {
+static uint8_t gmac_plaintext[GMAC_LARGE_PLAINTEXT_LENGTH] = {
 			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
 			0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
 			0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
@@ -1201,4 +1203,36 @@ static const struct cryptodev_perf_test_data AES_GCM_128_12IV_0AAD = {
 	},
 };
 
+static const struct gmac_test_data gmac_test_case_4 = {
+	.key = {
+		.data = {
+			0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
+			0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
+			0xde, 0xca, 0xf8, 0x88
+		},
+		.len = 12
+	},
+	.aad = {
+		.data = gmac_plaintext,
+		.len = GMAC_LARGE_PLAINTEXT_LENGTH
+	},
+	.plaintext = {
+		.data = NULL,
+		.len = 0
+	},
+	.gmac_tag = {
+		.data = {
+			0x88, 0x82, 0xb4, 0x93, 0x8f, 0x04, 0xcd, 0x06,
+			0xfd, 0xac, 0x6d, 0x8b, 0x9c, 0x9e, 0x8f, 0xec
+		},
+		.len = 16
+	}
+};
+
 #endif /* TEST_CRYPTODEV_GCM_TEST_VECTORS_H_ */
diff --git a/app/test/test_cryptodev_hash_test_vectors.h b/app/test/test_cryptodev_hash_test_vectors.h
new file mode 100644
index 0000000..dfc84db
--- /dev/null
+++ b/app/test/test_cryptodev_hash_test_vectors.h
@@ -0,0 +1,491 @@
+/*
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *	 * Redistributions of source code must retain the above copyright
+ *	   notice, this list of conditions and the following disclaimer.
+ *	 * Redistributions in binary form must reproduce the above copyright
+ *	   notice, this list of conditions and the following disclaimer in
+ *	   the documentation and/or other materials provided with the
+ *	   distribution.
+ *	 * Neither the name of Intel Corporation nor the names of its
+ *	   contributors may be used to endorse or promote products derived
+ *	   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEST_CRYPTODEV_HASH_TEST_VECTORS_H_
+#define TEST_CRYPTODEV_HASH_TEST_VECTORS_H_
+
+static const uint8_t plaintext_hash[] = {
+	"What a lousy earth! He wondered how many people "
+	"were destitute that same night even in his own "
+	"prosperous country, how many homes were "
+	"shanties, how many husbands were drunk and "
+	"wives socked, and how many children were "
+	"bullied, abused, or abandoned. How many "
+	"families hungered for food they could not "
+	"afford to buy? How many hearts were broken? How "
+	"many suicides would take place that same night, "
+	"how many people would go insane? How many "
+	"cockroaches and landlords would triumph? How "
+	"many winners were losers, successes failures, "
+	"and rich men poor men? How many wise guys were "
+	"stupid? How many happy endings were unhappy "
+	"endings? How many honest men were liars, brave "
+	"men cowards, loyal men traitors, how many "
+	"sainted men were corrupt, how many people in "
+	"positions of trust had sold their souls to "
+	"bodyguards, how many had never had souls? How "
+	"many straight-and-narrow paths were crooked "
+	"paths? How many best families were worst "
+	"families and how many good people were bad "
+	"people? When you added them all up and then "
+	"subtracted, you might be left with only the "
+	"children, and perhaps with Albert Einstein and "
+	"an old violinist or sculptor somewhere."
+};
+
+static const struct blockcipher_test_data
+md5_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_MD5,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.digest = {
+		.data = {
+			0xB3, 0xE6, 0xBB, 0x50, 0x41, 0x35, 0x3C, 0x6B,
+			0x7A, 0xFF, 0xD2, 0x64, 0xAF, 0xD5, 0x1C, 0xB2
+		},
+		.len = 16
+	}
+};
+
+static const struct blockcipher_test_data
+hmac_md5_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_MD5_HMAC,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD
+		},
+		.len = 16
+	},
+	.digest = {
+		.data = {
+			0x50, 0xE8, 0xDE, 0xC5, 0xC1, 0x76, 0xAC, 0xAE,
+			0x15, 0x4A, 0xF1, 0x7F, 0x7E, 0x04, 0x42, 0x9B
+		},
+		.len = 16
+	}
+};
+
+static const struct blockcipher_test_data
+sha1_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.digest = {
+		.data = {
+			0xA2, 0x8D, 0x40, 0x78, 0xDD, 0x9F, 0xBB, 0xD5,
+			0x35, 0x62, 0xFB, 0xFA, 0x93, 0xFD, 0x7D, 0x70,
+			0xA6, 0x7D, 0x45, 0xCA
+		},
+		.len = 20
+	}
+};
+
+static const struct blockcipher_test_data
+hmac_sha1_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD
+		},
+		.len = 20
+	},
+	.digest = {
+		.data = {
+			0xC4, 0xB7, 0x0E, 0x6B, 0xDE, 0xD1, 0xE7, 0x77,
+			0x7E, 0x2E, 0x8F, 0xFC, 0x48, 0x39, 0x46, 0x17,
+			0x3F, 0x91, 0x64, 0x59
+		},
+		.len = 20
+	}
+};
+
+static const struct blockcipher_test_data
+sha224_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA224,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.digest = {
+		.data = {
+			0x91, 0xE7, 0xCD, 0x75, 0x14, 0x9C, 0xA9, 0xE9,
+			0x2E, 0x46, 0x12, 0x20, 0x22, 0xF9, 0x68, 0x28,
+			0x39, 0x26, 0xDF, 0xB5, 0x78, 0x62, 0xB2, 0x6E,
+			0x5E, 0x8F, 0x25, 0x84
+		},
+		.len = 28
+	}
+};
+
+static const struct blockcipher_test_data
+hmac_sha224_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92,
+			0xFB, 0xBF, 0xB0, 0x8C
+		},
+		.len = 28
+	},
+	.digest = {
+		.data = {
+			0x70, 0x0F, 0x04, 0x4D, 0x22, 0x02, 0x7D, 0x31,
+			0x36, 0xDA, 0x77, 0x19, 0xB9, 0x66, 0x37, 0x7B,
+			0xF1, 0x8A, 0x63, 0xBB, 0x5D, 0x1D, 0xE3, 0x9F,
+			0x92, 0xF6, 0xAA, 0x19
+		},
+		.len = 28
+	}
+};
+
+static const struct blockcipher_test_data
+sha256_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA256,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.digest = {
+		.data = {
+			0x7F, 0xF1, 0x0C, 0xF5, 0x90, 0x97, 0x19, 0x0F,
+			0x00, 0xE4, 0x83, 0x01, 0xCA, 0x59, 0x00, 0x2E,
+			0x1F, 0xC7, 0x84, 0xEE, 0x76, 0xA6, 0x39, 0x15,
+			0x76, 0x2F, 0x87, 0xF9, 0x01, 0x06, 0xF3, 0xB7
+		},
+		.len = 32
+	}
+};
+
+static const struct blockcipher_test_data
+hmac_sha256_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92,
+			0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC
+		},
+		.len = 32
+	},
+	.digest = {
+		.data = {
+			0xAF, 0x8F, 0x70, 0x1B, 0x4B, 0xAF, 0x34, 0xCB,
+			0x02, 0x24, 0x48, 0x45, 0x83, 0x52, 0x8F, 0x22,
+			0x06, 0x4D, 0x64, 0x09, 0x0A, 0xCC, 0x02, 0x77,
+			0x71, 0x83, 0x48, 0x71, 0x07, 0x02, 0x25, 0x17
+		},
+		.len = 32
+	}
+};
+
+static const struct blockcipher_test_data
+sha384_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA384,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.digest = {
+		.data = {
+			0x1D, 0xE7, 0x3F, 0x55, 0x86, 0xFE, 0x48, 0x9F,
+			0xAC, 0xC6, 0x85, 0x32, 0xFA, 0x8E, 0xA6, 0x77,
+			0x25, 0x84, 0xA5, 0x98, 0x8D, 0x0B, 0x80, 0xF4,
+			0xEB, 0x2C, 0xFB, 0x6C, 0xEA, 0x7B, 0xFD, 0xD5,
+			0xAD, 0x41, 0xAB, 0x15, 0xB0, 0x03, 0x15, 0xEC,
+			0x9E, 0x3D, 0xED, 0xCB, 0x80, 0x7B, 0xF4, 0xB6
+		},
+		.len = 48
+	}
+};
+
+static const struct blockcipher_test_data
+hmac_sha384_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92,
+			0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC,
+			0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05,
+			0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89
+		},
+		.len = 48
+	},
+	.digest = {
+		.data = {
+			0xE2, 0x83, 0x18, 0x55, 0xB5, 0x8D, 0x94, 0x9B,
+			0x01, 0xB6, 0xE2, 0x57, 0x7A, 0x62, 0xF5, 0xF4,
+			0xAB, 0x39, 0xF3, 0x3C, 0x28, 0xA0, 0x0F, 0xCC,
+			0xEE, 0x1C, 0xF1, 0xF8, 0x69, 0xF1, 0x24, 0x3B,
+			0x10, 0x90, 0x0A, 0xE3, 0xF0, 0x59, 0xDD, 0xC0,
+			0x6F, 0xE6, 0x8C, 0x84, 0xD5, 0x03, 0xF8, 0x9E
+		},
+		.len = 48
+	}
+};
+
+static const struct blockcipher_test_data
+sha512_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA512,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.digest = {
+		.data = {
+			0xB9, 0xBA, 0x28, 0x48, 0x3C, 0xC2, 0xD3, 0x65,
+			0x4A, 0xD6, 0x00, 0x1D, 0xCE, 0x61, 0x64, 0x54,
+			0x45, 0x8C, 0x64, 0x0E, 0xED, 0x0E, 0xD8, 0x1C,
+			0x72, 0xCE, 0xD2, 0x44, 0x91, 0xC8, 0xEB, 0xC7,
+			0x99, 0xC5, 0xCA, 0x89, 0x72, 0x64, 0x96, 0x41,
+			0xC8, 0xEA, 0xB2, 0x4E, 0xD1, 0x21, 0x13, 0x49,
+			0x64, 0x4E, 0x15, 0x68, 0x12, 0x67, 0x26, 0x0F,
+			0x2C, 0x3C, 0x83, 0x25, 0x27, 0x86, 0xF0, 0xDB
+		},
+		.len = 64
+	}
+};
+
+static const struct blockcipher_test_data
+hmac_sha512_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC,
+	.ciphertext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD, 0x26, 0xEB, 0xAB, 0x92,
+			0xFB, 0xBF, 0xB0, 0x8C, 0x29, 0x87, 0x90, 0xAC,
+			0x39, 0x8B, 0x5C, 0x49, 0x68, 0x1E, 0x3A, 0x05,
+			0xCC, 0x68, 0x5C, 0x76, 0xCB, 0x3C, 0x71, 0x89,
+			0xDE, 0xAA, 0x36, 0x44, 0x98, 0x93, 0x97, 0x1E,
+			0x6D, 0x53, 0x83, 0x87, 0xB3, 0xB7, 0x56, 0x41
+		},
+		.len = 64
+	},
+	.digest = {
+		.data = {
+			0xB8, 0x0B, 0x35, 0x97, 0x3F, 0x24, 0x3F, 0x05,
+			0x2A, 0x7F, 0x2F, 0xD8, 0xD7, 0x56, 0x58, 0xAD,
+			0x6F, 0x8D, 0x1F, 0x4C, 0x30, 0xF9, 0xA8, 0x29,
+			0x7A, 0xE0, 0x8D, 0x88, 0xF5, 0x2E, 0x94, 0xF5,
+			0x06, 0xF7, 0x5D, 0x57, 0x32, 0xA8, 0x49, 0x29,
+			0xEA, 0x6B, 0x6D, 0x95, 0xBD, 0x76, 0xF5, 0x79,
+			0x97, 0x37, 0x0F, 0xBE, 0xC2, 0x45, 0xA0, 0x87,
+			0xAF, 0x24, 0x27, 0x0C, 0x78, 0xBA, 0xBE, 0x20
+		},
+		.len = 64
+	}
+};
+
+static const struct blockcipher_test_case hash_test_cases[] = {
+	{
+		.test_descr = "MD5 Digest",
+		.test_data = &md5_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "MD5 Digest Verify",
+		.test_data = &md5_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-MD5 Digest",
+		.test_data = &hmac_md5_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-MD5 Digest Verify",
+		.test_data = &hmac_md5_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "SHA1 Digest",
+		.test_data = &sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "SHA1 Digest Verify",
+		.test_data = &sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-SHA1 Digest",
+		.test_data = &hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-SHA1 Digest Verify",
+		.test_data = &hmac_sha1_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "SHA224 Digest",
+		.test_data = &sha224_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "SHA224 Digest Verify",
+		.test_data = &sha224_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-SHA224 Digest",
+		.test_data = &hmac_sha224_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-SHA224 Digest Verify",
+		.test_data = &hmac_sha224_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "SHA256 Digest",
+		.test_data = &sha256_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "SHA256 Digest Verify",
+		.test_data = &sha256_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-SHA256 Digest",
+		.test_data = &hmac_sha256_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-SHA256 Digest Verify",
+		.test_data = &hmac_sha256_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "SHA384 Digest",
+		.test_data = &sha384_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "SHA384 Digest Verify",
+		.test_data = &sha384_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-SHA384 Digest",
+		.test_data = &hmac_sha384_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-SHA384 Digest Verify",
+		.test_data = &hmac_sha384_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "SHA512 Digest",
+		.test_data = &sha512_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "SHA512 Digest Verify",
+		.test_data = &sha512_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-SHA512 Digest",
+		.test_data = &hmac_sha512_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+	{
+		.test_descr = "HMAC-SHA512 Digest Verify",
+		.test_data = &hmac_sha512_test_vector,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_LIBCRYPTO
+	},
+};
+
+#endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */
diff --git a/app/test/test_cryptodev_perf.c b/app/test/test_cryptodev_perf.c
index 6af0896..6d6b4a1 100644
--- a/app/test/test_cryptodev_perf.c
+++ b/app/test/test_cryptodev_perf.c
@@ -151,12 +151,28 @@ static struct rte_cryptodev_sym_session *
 test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain,
 		enum rte_crypto_cipher_algorithm cipher_algo, unsigned cipher_key_len,
 		enum rte_crypto_auth_algorithm auth_algo);
+static struct rte_cryptodev_sym_session *
+test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain,
+		enum rte_crypto_cipher_algorithm cipher_algo,
+		unsigned int cipher_key_len, enum rte_crypto_auth_algorithm auth_algo);
 static struct rte_mbuf *
 test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz);
 static inline struct rte_crypto_op *
 test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m,
 		struct rte_cryptodev_sym_session *sess, unsigned data_len,
 		unsigned digest_len);
+static inline struct rte_crypto_op *
+test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m,
+		struct rte_cryptodev_sym_session *sess, unsigned int data_len,
+		unsigned int digest_len);
+static inline struct rte_crypto_op *
+test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m,
+		struct rte_cryptodev_sym_session *sess, unsigned int data_len,
+		unsigned int digest_len);
+static inline struct rte_crypto_op *
+test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m,
+		struct rte_cryptodev_sym_session *sess, unsigned int data_len,
+		unsigned int digest_len);
 static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo);
 
 
@@ -357,6 +373,26 @@ testsuite_setup(void)
 		}
 	}
 
+	/* Create 2 LIBCRYPTO devices if required */
+	if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_LIBCRYPTO_PMD) {
+#ifndef RTE_LIBRTE_PMD_LIBCRYPTO
+		RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO must be"
+			" enabled in config file to run this testsuite.\n");
+		return TEST_FAILED;
+#endif
+		nb_devs = rte_cryptodev_count_devtype(RTE_CRYPTODEV_LIBCRYPTO_PMD);
+		if (nb_devs < 2) {
+			for (i = nb_devs; i < 2; i++) {
+				ret = rte_eal_vdev_init(
+					RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), NULL);
+
+				TEST_ASSERT(ret == 0,
+					"Failed to create instance %u of pmd : %s",
+					i, RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD));
+			}
+		}
+	}
+
 #ifndef RTE_LIBRTE_PMD_QAT
 	if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_QAT_SYM_PMD) {
 		RTE_LOG(ERR, USER1, "CONFIG_RTE_LIBRTE_PMD_QAT must be enabled "
@@ -367,7 +403,7 @@ testsuite_setup(void)
 
 	nb_devs = rte_cryptodev_count();
 	if (nb_devs < 1) {
-		RTE_LOG(ERR, USER1, "No crypto devices found?");
+		RTE_LOG(ERR, USER1, "No crypto devices found?\n");
 		return TEST_FAILED;
 	}
 
@@ -2242,6 +2278,151 @@ test_perf_snow3G_vary_burst_size(void)
 	return 0;
 }
 
+static int
+test_perf_libcrypto_optimise_cyclecount(struct perf_test_params *pparams)
+{
+	uint32_t num_to_submit = pparams->total_operations;
+	struct rte_crypto_op *c_ops[num_to_submit];
+	struct rte_crypto_op *proc_ops[num_to_submit];
+	uint64_t failed_polls, retries, start_cycles, end_cycles, total_cycles = 0;
+	uint32_t burst_sent = 0, burst_received = 0;
+	uint32_t i, burst_size, num_sent, num_ops_received;
+
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+
+	static struct rte_cryptodev_sym_session *sess;
+
+	static struct rte_crypto_op *(*test_perf_set_crypto_op)
+			(struct rte_crypto_op *, struct rte_mbuf *,
+					struct rte_cryptodev_sym_session *, unsigned int,
+					unsigned int);
+
+	unsigned int digest_length = get_auth_digest_length(pparams->auth_algo);
+
+	if (rte_cryptodev_count() == 0) {
+		printf("\nNo crypto devices found. Is PMD build configured?\n");
+		return TEST_FAILED;
+	}
+
+	/* Create Crypto session*/
+	sess = test_perf_create_libcrypto_session(ts_params->dev_id,
+			pparams->chain, pparams->cipher_algo,
+			pparams->cipher_key_length, pparams->auth_algo);
+	TEST_ASSERT_NOT_NULL(sess, "Session creation failed");
+
+	/* Generate Crypto op data structure(s)*/
+	for (i = 0; i < num_to_submit ; i++) {
+		struct rte_mbuf *m = test_perf_create_pktmbuf(
+						ts_params->mbuf_mp,
+						pparams->buf_size);
+		TEST_ASSERT_NOT_NULL(m, "Failed to allocate tx_buf");
+
+		struct rte_crypto_op *op =
+				rte_crypto_op_alloc(ts_params->op_mpool,
+						RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+		TEST_ASSERT_NOT_NULL(op, "Failed to allocate op");
+
+		switch (pparams->cipher_algo) {
+		case RTE_CRYPTO_CIPHER_3DES_CBC:
+		case RTE_CRYPTO_CIPHER_3DES_CTR:
+			test_perf_set_crypto_op = test_perf_set_crypto_op_3des;
+			break;
+		case RTE_CRYPTO_CIPHER_AES_CBC:
+		case RTE_CRYPTO_CIPHER_AES_CTR:
+			test_perf_set_crypto_op = test_perf_set_crypto_op_aes;
+			break;
+		case RTE_CRYPTO_CIPHER_AES_GCM:
+			test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm;
+			break;
+		default:
+			return TEST_FAILED;
+		}
+
+		op = test_perf_set_crypto_op(op, m, sess, pparams->buf_size,
+				digest_length);
+		TEST_ASSERT_NOT_NULL(op, "Failed to attach op to session");
+
+		c_ops[i] = op;
+	}
+
+	printf("\nOn %s dev%u qp%u, %s, cipher algo:%s, cipher key length:%u, "
+			"auth_algo:%s, Packet Size %u bytes",
+			pmd_name(gbl_cryptodev_perftest_devtype),
+			ts_params->dev_id, 0,
+			chain_mode_name(pparams->chain),
+			cipher_algo_name(pparams->cipher_algo),
+			pparams->cipher_key_length,
+			auth_algo_name(pparams->auth_algo),
+			pparams->buf_size);
+	printf("\nOps Tx\tOps Rx\tOps/burst  ");
+	printf("Retries  EmptyPolls\tIACycles/CyOp\tIACycles/Burst\tIACycles/Byte");
+
+	for (i = 2; i <= 128 ; i *= 2) {
+		num_sent = 0;
+		num_ops_received = 0;
+		retries = 0;
+		failed_polls = 0;
+		burst_size = i;
+		total_cycles = 0;
+		while (num_sent < num_to_submit) {
+			start_cycles = rte_rdtsc_precise();
+			burst_sent = rte_cryptodev_enqueue_burst(ts_params->dev_id,
+					0, &c_ops[num_sent],
+					((num_to_submit - num_sent) < burst_size) ?
+					num_to_submit - num_sent : burst_size);
+			end_cycles = rte_rdtsc_precise();
+			if (burst_sent == 0)
+				retries++;
+			num_sent += burst_sent;
+			total_cycles += (end_cycles - start_cycles);
+
+			/* Wait until requests have been sent. */
+			rte_delay_ms(1);
+
+			start_cycles = rte_rdtsc_precise();
+			burst_received = rte_cryptodev_dequeue_burst(
+					ts_params->dev_id, 0, proc_ops, burst_size);
+			end_cycles = rte_rdtsc_precise();
+			if (burst_received < burst_sent)
+				failed_polls++;
+			num_ops_received += burst_received;
+
+			total_cycles += end_cycles - start_cycles;
+		}
+
+		while (num_ops_received != num_to_submit) {
+			/* Sending 0 length burst to flush sw crypto device */
+			rte_cryptodev_enqueue_burst(ts_params->dev_id, 0, NULL, 0);
+
+			start_cycles = rte_rdtsc_precise();
+			burst_received = rte_cryptodev_dequeue_burst(
+					ts_params->dev_id, 0, proc_ops, burst_size);
+			end_cycles = rte_rdtsc_precise();
+
+			total_cycles += end_cycles - start_cycles;
+			if (burst_received == 0)
+				failed_polls++;
+			num_ops_received += burst_received;
+		}
+
+		printf("\n%u\t%u\t%u", num_sent, num_ops_received, burst_size);
+		printf("\t\t%"PRIu64, retries);
+		printf("\t%"PRIu64, failed_polls);
+		printf("\t\t%"PRIu64, total_cycles/num_ops_received);
+		printf("\t\t%"PRIu64, (total_cycles/num_ops_received)*burst_size);
+		printf("\t\t%"PRIu64,
+				total_cycles/(num_ops_received*pparams->buf_size));
+	}
+	printf("\n");
+
+	for (i = 0; i < num_to_submit ; i++) {
+		rte_pktmbuf_free(c_ops[i]->sym->m_src);
+		rte_crypto_op_free(c_ops[i]);
+	}
+
+	return TEST_SUCCESS;
+}
+
 static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo)
 {
 	switch (algo) {
@@ -2257,6 +2438,8 @@ static uint32_t get_auth_key_max_length(enum rte_crypto_auth_algorithm algo)
 		return 128;
 	case RTE_CRYPTO_AUTH_SHA512_HMAC:
 		return 128;
+	case RTE_CRYPTO_AUTH_AES_GCM:
+		return 0;
 	default:
 		return 0;
 	}
@@ -2277,23 +2460,35 @@ static uint32_t get_auth_digest_length(enum rte_crypto_auth_algorithm algo)
 		return TRUNCATED_DIGEST_BYTE_LENGTH_SHA384;
 	case RTE_CRYPTO_AUTH_SHA512_HMAC:
 		return TRUNCATED_DIGEST_BYTE_LENGTH_SHA512;
+	case RTE_CRYPTO_AUTH_AES_GCM:
+		return DIGEST_BYTE_LENGTH_AES_GCM;
 	default:
 		return 0;
 	}
 }
 
-static uint8_t aes_cbc_key[] = {
+static uint8_t aes_key[] = {
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
-static uint8_t aes_cbc_iv[] = {
+static uint8_t aes_iv[] = {
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
+static uint8_t triple_des_key[] = {
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static uint8_t triple_des_iv[] = {
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
 static uint8_t hmac_sha_key[] = {
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -2343,7 +2538,7 @@ test_perf_create_aes_sha_session(uint8_t dev_id, enum chain_mode chain,
 	cipher_xform.cipher.algo = cipher_algo;
 	cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
 
-	cipher_xform.cipher.key.data = aes_cbc_key;
+	cipher_xform.cipher.key.data = aes_key;
 	cipher_xform.cipher.key.length = cipher_key_len;
 
 	/* Setup HMAC Parameters */
@@ -2421,8 +2616,77 @@ test_perf_create_snow3g_session(uint8_t dev_id, enum chain_mode chain,
 	}
 }
 
-#define AES_CBC_BLOCK_SIZE 16
-#define AES_CBC_CIPHER_IV_LENGTH 16
+static struct rte_cryptodev_sym_session *
+test_perf_create_libcrypto_session(uint8_t dev_id, enum chain_mode chain,
+		enum rte_crypto_cipher_algorithm cipher_algo,
+		unsigned int cipher_key_len,
+		enum rte_crypto_auth_algorithm auth_algo)
+{
+	struct rte_crypto_sym_xform cipher_xform = { 0 };
+	struct rte_crypto_sym_xform auth_xform = { 0 };
+
+	/* Setup Cipher Parameters */
+	cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+	cipher_xform.cipher.algo = cipher_algo;
+	cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
+
+	switch (cipher_algo) {
+	case RTE_CRYPTO_CIPHER_3DES_CBC:
+	case RTE_CRYPTO_CIPHER_3DES_CTR:
+		cipher_xform.cipher.key.data = triple_des_key;
+		break;
+	case RTE_CRYPTO_CIPHER_AES_CBC:
+	case RTE_CRYPTO_CIPHER_AES_CTR:
+	case RTE_CRYPTO_CIPHER_AES_GCM:
+		cipher_xform.cipher.key.data = aes_key;
+		break;
+	default:
+		return NULL;
+	}
+
+	cipher_xform.cipher.key.length = cipher_key_len;
+
+	/* Setup Auth Parameters */
+	auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+	auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
+	auth_xform.auth.algo = auth_algo;
+
+	switch (auth_algo) {
+	case RTE_CRYPTO_AUTH_SHA1_HMAC:
+		auth_xform.auth.key.data = hmac_sha_key;
+		break;
+	case RTE_CRYPTO_AUTH_AES_GCM:
+		auth_xform.auth.key.data = NULL;
+		break;
+	default:
+		return NULL;
+	}
+
+	auth_xform.auth.key.length =  get_auth_key_max_length(auth_algo);
+	auth_xform.auth.digest_length = get_auth_digest_length(auth_algo);
+
+	switch (chain) {
+	case CIPHER_HASH:
+		cipher_xform.next = &auth_xform;
+		auth_xform.next = NULL;
+		/* Create Crypto session*/
+		return rte_cryptodev_sym_session_create(dev_id,	&cipher_xform);
+	case HASH_CIPHER:
+		auth_xform.next = &cipher_xform;
+		cipher_xform.next = NULL;
+		/* Create Crypto session*/
+		return rte_cryptodev_sym_session_create(dev_id,	&auth_xform);
+	default:
+		return NULL;
+	}
+}
+
+#define AES_BLOCK_SIZE 16
+#define AES_CIPHER_IV_LENGTH 16
+
+#define TRIPLE_DES_BLOCK_SIZE 8
+#define TRIPLE_DES_CIPHER_IV_LENGTH 8
+
 #define SNOW3G_CIPHER_IV_LENGTH 16
 
 static struct rte_mbuf *
@@ -2441,7 +2705,7 @@ test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz)
 }
 
 static inline struct rte_crypto_op *
-test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m,
+test_perf_set_crypto_op_aes(struct rte_crypto_op *op, struct rte_mbuf *m,
 		struct rte_cryptodev_sym_session *sess, unsigned data_len,
 		unsigned digest_len)
 {
@@ -2455,19 +2719,53 @@ test_perf_set_crypto_op(struct rte_crypto_op *op, struct rte_mbuf *m,
 					(m->data_off + data_len);
 	op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len);
 	op->sym->auth.digest.length = digest_len;
-	op->sym->auth.aad.data = aes_cbc_iv;
-	op->sym->auth.aad.length = AES_CBC_CIPHER_IV_LENGTH;
+	op->sym->auth.aad.data = aes_iv;
+	op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH;
 
 	/* Cipher Parameters */
-	op->sym->cipher.iv.data = aes_cbc_iv;
-	op->sym->cipher.iv.length = AES_CBC_CIPHER_IV_LENGTH;
+	op->sym->cipher.iv.data = aes_iv;
+	op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH;
 
 	/* Data lengths/offsets Parameters */
 	op->sym->auth.data.offset = 0;
 	op->sym->auth.data.length = data_len;
 
-	op->sym->cipher.data.offset = AES_CBC_BLOCK_SIZE;
-	op->sym->cipher.data.length = data_len - AES_CBC_BLOCK_SIZE;
+	op->sym->cipher.data.offset = AES_BLOCK_SIZE;
+	op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE;
+
+	op->sym->m_src = m;
+
+	return op;
+}
+
+static inline struct rte_crypto_op *
+test_perf_set_crypto_op_aes_gcm(struct rte_crypto_op *op, struct rte_mbuf *m,
+		struct rte_cryptodev_sym_session *sess, unsigned int data_len,
+		unsigned int digest_len)
+{
+	if (rte_crypto_op_attach_sym_session(op, sess) != 0) {
+		rte_crypto_op_free(op);
+		return NULL;
+	}
+
+	/* Authentication Parameters */
+	op->sym->auth.digest.data = (uint8_t *)m->buf_addr +
+					(m->data_off + data_len);
+	op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len);
+	op->sym->auth.digest.length = digest_len;
+	op->sym->auth.aad.data = aes_iv;
+	op->sym->auth.aad.length = AES_CIPHER_IV_LENGTH;
+
+	/* Cipher Parameters */
+	op->sym->cipher.iv.data = aes_iv;
+	op->sym->cipher.iv.length = AES_CIPHER_IV_LENGTH;
+
+	/* Data lengths/offsets Parameters */
+	op->sym->auth.data.offset = AES_BLOCK_SIZE;
+	op->sym->auth.data.length = data_len - AES_BLOCK_SIZE;
+
+	op->sym->cipher.data.offset = AES_BLOCK_SIZE;
+	op->sym->cipher.data.length = data_len - AES_BLOCK_SIZE;
 
 	op->sym->m_src = m;
 
@@ -2508,7 +2806,39 @@ test_perf_set_crypto_op_snow3g(struct rte_crypto_op *op, struct rte_mbuf *m,
 	return op;
 }
 
+static inline struct rte_crypto_op *
+test_perf_set_crypto_op_3des(struct rte_crypto_op *op, struct rte_mbuf *m,
+		struct rte_cryptodev_sym_session *sess, unsigned int data_len,
+		unsigned int digest_len)
+{
+	if (rte_crypto_op_attach_sym_session(op, sess) != 0) {
+		rte_crypto_op_free(op);
+		return NULL;
+	}
+
+	/* Authentication Parameters */
+	op->sym->auth.digest.data = (uint8_t *)m->buf_addr +
+					(m->data_off + data_len);
+	op->sym->auth.digest.phys_addr = rte_pktmbuf_mtophys_offset(m, data_len);
+	op->sym->auth.digest.length = digest_len;
+	op->sym->auth.aad.data = triple_des_iv;
+	op->sym->auth.aad.length = TRIPLE_DES_CIPHER_IV_LENGTH;
+
+	/* Cipher Parameters */
+	op->sym->cipher.iv.data = triple_des_iv;
+	op->sym->cipher.iv.length = TRIPLE_DES_CIPHER_IV_LENGTH;
+
+	/* Data lengths/offsets Parameters */
+	op->sym->auth.data.offset = 0;
+	op->sym->auth.data.length = data_len;
 
+	op->sym->cipher.data.offset = TRIPLE_DES_BLOCK_SIZE;
+	op->sym->cipher.data.length = data_len - TRIPLE_DES_BLOCK_SIZE;
+
+	op->sym->m_src = m;
+
+	return op;
+}
 
 /* An mbuf set is used in each burst. An mbuf can be used by multiple bursts at
  * same time, i.e. as they're not dereferenced there's no need to wait until
@@ -2579,7 +2909,7 @@ test_perf_aes_sha(uint8_t dev_id, uint16_t queue_id,
 				"and free ops below.");
 		} else {
 			for (i = 0; i < ops_needed; i++)
-				ops[i] = test_perf_set_crypto_op(ops[i],
+				ops[i] = test_perf_set_crypto_op_aes(ops[i],
 					mbufs[i + (pparams->burst_size *
 						(j % NUM_MBUF_SETS))],
 					sess, pparams->buf_size, digest_length);
@@ -2790,6 +3120,154 @@ test_perf_snow3g(uint8_t dev_id, uint16_t queue_id,
 	return TEST_SUCCESS;
 }
 
+static int
+test_perf_libcrypto(uint8_t dev_id, uint16_t queue_id,
+		struct perf_test_params *pparams)
+{
+	uint16_t i, k, l, m;
+	uint16_t j = 0;
+	uint16_t ops_unused = 0;
+
+	uint64_t burst_enqueued = 0, total_enqueued = 0, burst_dequeued = 0;
+	uint64_t processed = 0, failed_polls = 0, retries = 0;
+	uint64_t tsc_start = 0, tsc_end = 0;
+
+	unsigned int digest_length = get_auth_digest_length(pparams->auth_algo);
+
+	struct rte_crypto_op *ops[pparams->burst_size];
+	struct rte_crypto_op *proc_ops[pparams->burst_size];
+
+	struct rte_mbuf *mbufs[pparams->burst_size * NUM_MBUF_SETS];
+
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+
+	static struct rte_cryptodev_sym_session *sess;
+
+	static struct rte_crypto_op *(*test_perf_set_crypto_op)
+			(struct rte_crypto_op *, struct rte_mbuf *,
+					struct rte_cryptodev_sym_session *, unsigned int,
+					unsigned int);
+
+	switch (pparams->cipher_algo) {
+	case RTE_CRYPTO_CIPHER_3DES_CBC:
+	case RTE_CRYPTO_CIPHER_3DES_CTR:
+		test_perf_set_crypto_op = test_perf_set_crypto_op_3des;
+		break;
+	case RTE_CRYPTO_CIPHER_AES_CBC:
+	case RTE_CRYPTO_CIPHER_AES_CTR:
+		test_perf_set_crypto_op = test_perf_set_crypto_op_aes;
+		break;
+	case RTE_CRYPTO_CIPHER_AES_GCM:
+		test_perf_set_crypto_op = test_perf_set_crypto_op_aes_gcm;
+		break;
+	default:
+		return TEST_FAILED;
+	}
+
+	if (rte_cryptodev_count() == 0) {
+		printf("\nNo crypto devices found. Is PMD build configured?\n");
+		return TEST_FAILED;
+	}
+
+	/* Create Crypto session*/
+	sess = test_perf_create_libcrypto_session(ts_params->dev_id,
+			pparams->chain, pparams->cipher_algo,
+			pparams->cipher_key_length, pparams->auth_algo);
+	TEST_ASSERT_NOT_NULL(sess, "Session creation failed");
+
+	/* Generate a burst of crypto operations */
+	for (i = 0; i < (pparams->burst_size * NUM_MBUF_SETS); i++) {
+		mbufs[i] = test_perf_create_pktmbuf(
+				ts_params->mbuf_mp,
+				pparams->buf_size);
+
+		if (mbufs[i] == NULL) {
+			printf("\nFailed to get mbuf - freeing the rest.\n");
+			for (k = 0; k < i; k++)
+				rte_pktmbuf_free(mbufs[k]);
+			return -1;
+		}
+	}
+
+	tsc_start = rte_rdtsc_precise();
+
+	while (total_enqueued < pparams->total_operations) {
+		uint16_t burst_size =
+		total_enqueued + pparams->burst_size <= pparams->total_operations ?
+		pparams->burst_size : pparams->total_operations - total_enqueued;
+		uint16_t ops_needed = burst_size - ops_unused;
+
+		if (ops_needed != rte_crypto_op_bulk_alloc(ts_params->op_mpool,
+				RTE_CRYPTO_OP_TYPE_SYMMETRIC, ops, ops_needed)){
+			printf("\nFailed to alloc enough ops, finish dequeuing "
+				"and free ops below.");
+		} else {
+			for (i = 0; i < ops_needed; i++)
+				ops[i] = test_perf_set_crypto_op(ops[i],
+					mbufs[i + (pparams->burst_size *
+						(j % NUM_MBUF_SETS))],
+					sess, pparams->buf_size, digest_length);
+
+			/* enqueue burst */
+			burst_enqueued = rte_cryptodev_enqueue_burst(dev_id,
+					queue_id, ops, burst_size);
+
+			if (burst_enqueued < burst_size)
+				retries++;
+
+			ops_unused = burst_size - burst_enqueued;
+			total_enqueued += burst_enqueued;
+		}
+
+		/* dequeue burst */
+		burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id,
+				proc_ops, pparams->burst_size);
+		if (burst_dequeued == 0)
+			failed_polls++;
+		else {
+			processed += burst_dequeued;
+
+			for (l = 0; l < burst_dequeued; l++)
+				rte_crypto_op_free(proc_ops[l]);
+		}
+		j++;
+	}
+
+	/* Dequeue any operations still in the crypto device */
+	while (processed < pparams->total_operations) {
+		/* Sending 0 length burst to flush sw crypto device */
+		rte_cryptodev_enqueue_burst(dev_id, queue_id, NULL, 0);
+
+		/* dequeue burst */
+		burst_dequeued = rte_cryptodev_dequeue_burst(dev_id, queue_id,
+				proc_ops, pparams->burst_size);
+		if (burst_dequeued == 0)
+			failed_polls++;
+		else {
+			processed += burst_dequeued;
+
+			for (m = 0; m < burst_dequeued; m++)
+				rte_crypto_op_free(proc_ops[m]);
+		}
+	}
+
+	tsc_end = rte_rdtsc_precise();
+
+	double ops_s = ((double)processed / (tsc_end - tsc_start))
+					* rte_get_tsc_hz();
+	double throughput = (ops_s * pparams->buf_size * NUM_MBUF_SETS)
+					/ 1000000000;
+
+	printf("\t%u\t%6.2f\t%10.2f\t%8"PRIu64"\t%8"PRIu64, pparams->buf_size,
+			ops_s / 1000000, throughput, retries, failed_polls);
+
+	for (i = 0; i < pparams->burst_size * NUM_MBUF_SETS; i++)
+		rte_pktmbuf_free(mbufs[i]);
+
+	printf("\n");
+	return TEST_SUCCESS;
+}
+
 /*
 
     perf_test_aes_sha("avx2", HASH_CIPHER, 16, CBC, SHA1);
@@ -2937,6 +3415,166 @@ test_perf_snow3G_vary_pkt_size(void)
 }
 
 static int
+test_perf_libcrypto_vary_pkt_size(void)
+{
+	unsigned int total_operations = 1000000;
+	unsigned int burst_size = { 64 };
+	unsigned int buf_lengths[] = { 64, 128, 256, 512, 768, 1024, 1280, 1536,
+			1792, 2048 };
+	uint8_t i, j;
+
+	struct perf_test_params params_set[] = {
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_3DES_CBC,
+			.cipher_key_length = 16,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_3DES_CBC,
+			.cipher_key_length = 24,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_AES_CTR,
+			.cipher_key_length = 16,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_AES_CTR,
+			.cipher_key_length = 32,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_3DES_CTR,
+			.cipher_key_length = 16,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_3DES_CTR,
+			.cipher_key_length = 24,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_AES_GCM,
+			.cipher_key_length = 16,
+			.auth_algo = RTE_CRYPTO_AUTH_AES_GCM
+		},
+	};
+
+	for (i = 0; i < RTE_DIM(params_set); i++) {
+		params_set[i].total_operations = total_operations;
+		params_set[i].burst_size = burst_size;
+		printf("\n%s. cipher algo: %s auth algo: %s cipher key size=%u."
+				" burst_size: %d ops\n",
+				chain_mode_name(params_set[i].chain),
+				cipher_algo_name(params_set[i].cipher_algo),
+				auth_algo_name(params_set[i].auth_algo),
+				params_set[i].cipher_key_length,
+				burst_size);
+		printf("\nBuffer Size(B)\tOPS(M)\tThroughput(Gbps)\tRetries\t"
+				"EmptyPolls\n");
+		for (j = 0; j < RTE_DIM(buf_lengths); j++) {
+			params_set[i].buf_size = buf_lengths[j];
+			test_perf_libcrypto(testsuite_params.dev_id, 0, &params_set[i]);
+		}
+	}
+
+	return 0;
+}
+
+static int
+test_perf_libcrypto_vary_burst_size(void)
+{
+	unsigned int total_operations = 4096;
+	uint16_t buf_lengths[] = { 40 };
+	uint8_t i, j;
+
+	struct perf_test_params params_set[] = {
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_3DES_CBC,
+			.cipher_key_length = 16,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_3DES_CBC,
+			.cipher_key_length = 24,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_AES_CTR,
+			.cipher_key_length = 16,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_AES_CTR,
+			.cipher_key_length = 32,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_3DES_CTR,
+			.cipher_key_length = 16,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_3DES_CTR,
+			.cipher_key_length = 24,
+			.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC
+		},
+		{
+			.chain = CIPHER_HASH,
+
+			.cipher_algo  = RTE_CRYPTO_CIPHER_AES_GCM,
+			.cipher_key_length = 16,
+			.auth_algo = RTE_CRYPTO_AUTH_AES_GCM
+		},
+	};
+
+	printf("\n\nStart %s.", __func__);
+	printf("\nThis Test measures the average IA cycle cost using a "
+			"constant request(packet) size. ");
+	printf("Cycle cost is only valid when indicators show device is not busy,"
+			" i.e. Retries and EmptyPolls = 0");
+
+	for (i = 0; i < RTE_DIM(params_set); i++) {
+		printf("\n");
+		params_set[i].total_operations = total_operations;
+
+	for (j = 0; j < RTE_DIM(buf_lengths); j++) {
+		params_set[i].buf_size = buf_lengths[j];
+		test_perf_libcrypto_optimise_cyclecount(&params_set[i]);
+		}
+	}
+
+	return 0;
+}
+
+static int
 test_perf_aes_cbc_vary_burst_size(void)
 {
 	return test_perf_crypto_qp_vary_burst_size(testsuite_params.dev_id);
@@ -3377,6 +4015,19 @@ static struct unit_test_suite cryptodev_snow3g_testsuite  = {
 	}
 };
 
+static struct unit_test_suite cryptodev_libcrypto_testsuite  = {
+	.suite_name = "Crypto Device LIBCRYPTO Unit Test Suite",
+	.setup = testsuite_setup,
+	.teardown = testsuite_teardown,
+	.unit_test_cases = {
+		TEST_CASE_ST(ut_setup, ut_teardown,
+				test_perf_libcrypto_vary_pkt_size),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+				test_perf_libcrypto_vary_burst_size),
+		TEST_CASES_END() /**< NULL terminate unit test array */
+	}
+};
+
 static int
 perftest_aesni_gcm_cryptodev(void)
 {
@@ -3417,8 +4068,18 @@ perftest_qat_snow3g_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/)
 	return unit_test_suite_runner(&cryptodev_snow3g_testsuite);
 }
 
+static int
+perftest_libcrypto_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/)
+{
+	gbl_cryptodev_perftest_devtype = RTE_CRYPTODEV_LIBCRYPTO_PMD;
+
+	return unit_test_suite_runner(&cryptodev_libcrypto_testsuite);
+}
+
 REGISTER_TEST_COMMAND(cryptodev_aesni_mb_perftest, perftest_aesni_mb_cryptodev);
 REGISTER_TEST_COMMAND(cryptodev_qat_perftest, perftest_qat_cryptodev);
 REGISTER_TEST_COMMAND(cryptodev_sw_snow3g_perftest, perftest_sw_snow3g_cryptodev);
 REGISTER_TEST_COMMAND(cryptodev_qat_snow3g_perftest, perftest_qat_snow3g_cryptodev);
 REGISTER_TEST_COMMAND(cryptodev_aesni_gcm_perftest, perftest_aesni_gcm_cryptodev);
+REGISTER_TEST_COMMAND(cryptodev_libcrypto_perftest,
+		perftest_libcrypto_cryptodev);
-- 
2.5.0

^ permalink raw reply related

* Re: [PATCH v1 0/4] Generalize PCI specific EAL function/structures
From: Jan Viktorin @ 2016-10-03 13:12 UTC (permalink / raw)
  To: David Marchand; +Cc: Shreyansh Jain, dev@dpdk.org, Thomas Monjalon
In-Reply-To: <4e8b181f-8d46-f4b4-3821-a19f5c622ec1@nxp.com>

On Mon, 3 Oct 2016 11:07:43 +0530
Shreyansh Jain <shreyansh.jain@nxp.com> wrote:

> Hi David,
> 
> On Friday 30 September 2016 09:01 PM, David Marchand wrote:
> > On Tue, Sep 27, 2016 at 4:12 PM, Shreyansh Jain <shreyansh.jain@nxp.com> wrote:  
> >> (I rebased these over HEAD 7b3c4f3)
> >>
> >> These patches were initially part of Jan's original series on SoC
> >> Framework ([1],[2]). An update to that series, without these patches,
> >> was posted here [3].
> >>
> >> Main motivation for these is aim of introducing a non-PCI centric
> >> subsystem in EAL. As of now the first usecase is SoC, but not limited to
> >> it.
> >>
> >> 4 patches in this series are independent of each other, as well as SoC
> >> framework. All these focus on generalizing some structure or functions
> >> present with the PCI specific code to EAL Common area (or splitting a
> >> function to be more userful).  
> >
> > Those patches move linux specifics (binding pci devices using sysfs)
> > to common infrastucture.
> > We have no proper hotplug support on bsd, but if we had some common
> > code we should at least try to make the apis generic.
> >  
> 
> I am not sure if I understood your point well. Just to confirm - you are 

I don't clearly see the point, either.

Jan

> stating that the movement done in the patches might not suit BSD. 
> Probably you are talking about (Patch 3/4 and 4/4).
> Is my understanding correct?
> 
> So, movement to just Linux area is not enough?
> I am not well versed with BSD way of doing something similar so if 
> someone can point it out, I can integrate that. (I will investigate it 
> at my end as well).
> 
> This patchset makes the PCI->EAL movement *only* for Linux for sysfs 
> bind/unbind. (I should add this to cover letter, at the least).
> 
> -
> Shreyansh



-- 
   Jan Viktorin                  E-mail: Viktorin@RehiveTech.com
   System Architect              Web:    www.RehiveTech.com
   RehiveTech
   Brno, Czech Republic

^ permalink raw reply

* Re: [PATCH] eal: fix crash on mmap error in rte_eal_hugepage_attach()
From: Sergio Gonzalez Monroy @ 2016-10-03 13:04 UTC (permalink / raw)
  To: maciej.czekaj, david.marchand; +Cc: dev
In-Reply-To: <1475059977-27370-1-git-send-email-maciej.czekaj@caviumnetworks.com>

On 28/09/2016 11:52, maciej.czekaj@caviumnetworks.com wrote:
> From: Maciej Czekaj <maciej.czekaj@caviumnetworks.com>
>
> In ASLR-enabled system, it is possible that selected
> virtual space is occupied by program segments. Therefore,
> error path should not blindly unmap all memmory segments
> but only those already mapped.
>
> Steps that lead to crash:
> 1. memeseg 0 in secondary process overlaps
>     with libc.so
> 2. mmap of /dev/zero fails for virtual space of memseg 0
> 3. munmap of memseg 0 leads to unmapping libc.so itself
> 4. app gets SIGSEGV after returning from syscall to libc
>
> Fixes: ea329d7f8e34 ("mem: fix leak after mapping failure")
>
> Signed-off-by: Maciej Czekaj <maciej.czekaj@caviumnetworks.com>
> ---
>   lib/librte_eal/linuxapp/eal/eal_memory.c | 11 ++++++-----
>   1 file changed, 6 insertions(+), 5 deletions(-)

Acked-by: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>

^ permalink raw reply

* [PATCH v5 2/4] app/test: cryptodev AES tests rework
From: Slawomir Mrozowicz @ 2016-10-03 15:02 UTC (permalink / raw)
  To: dev; +Cc: Slawomir Mrozowicz, Piotr Azarewicz, Fiona Trahe
In-Reply-To: <1475504792-31557-1-git-send-email-slawomirx.mrozowicz@intel.com>

This patch rework AES tests .
In general - rename AES-named functions to blockcipher functions pattern.

Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Signed-off-by: Fiona Trahe <fiona.trahe@intel.com>
---
 app/test/Makefile                          |    2 +-
 app/test/test_cryptodev.c                  |   74 +-
 app/test/test_cryptodev_aes.c              |  687 -----------------
 app/test/test_cryptodev_aes.h              | 1124 ----------------------------
 app/test/test_cryptodev_aes_test_vectors.h |  797 ++++++++++++++++++++
 app/test/test_cryptodev_blockcipher.c      |  509 +++++++++++++
 app/test/test_cryptodev_blockcipher.h      |  124 +++
 7 files changed, 1478 insertions(+), 1839 deletions(-)
 delete mode 100644 app/test/test_cryptodev_aes.c
 delete mode 100644 app/test/test_cryptodev_aes.h
 create mode 100644 app/test/test_cryptodev_aes_test_vectors.h
 create mode 100644 app/test/test_cryptodev_blockcipher.c
 create mode 100644 app/test/test_cryptodev_blockcipher.h

diff --git a/app/test/Makefile b/app/test/Makefile
index 611d77a..5be023a 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -193,7 +193,7 @@ endif
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring.c
 SRCS-$(CONFIG_RTE_LIBRTE_PMD_RING) += test_pmd_ring_perf.c
 
-SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_aes.c
+SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_blockcipher.c
 SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_perf.c
 SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c
 
diff --git a/app/test/test_cryptodev.c b/app/test/test_cryptodev.c
index 9d7caba..c46db94 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -43,7 +43,8 @@
 #include "test.h"
 #include "test_cryptodev.h"
 
-#include "test_cryptodev_aes.h"
+#include "test_cryptodev_blockcipher.h"
+#include "test_cryptodev_aes_test_vectors.h"
 #include "test_cryptodev_kasumi_test_vectors.h"
 #include "test_cryptodev_kasumi_hash_test_vectors.h"
 #include "test_cryptodev_snow3g_test_vectors.h"
@@ -86,12 +87,16 @@ struct crypto_unittest_params {
  */
 static int
 test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(
-		struct crypto_unittest_params *ut_params);
+		struct crypto_unittest_params *ut_params, uint8_t *cipher_key,
+		uint8_t *hmac_key);
 
 static int
 test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess,
 		struct crypto_unittest_params *ut_params,
-		struct crypto_testsuite_params *ts_param);
+		struct crypto_testsuite_params *ts_param,
+		const uint8_t *cipher,
+		const uint8_t *digest,
+		const uint8_t *iv);
 
 static struct rte_mbuf *
 setup_test_string(struct rte_mempool *mpool,
@@ -313,7 +318,7 @@ testsuite_setup(void)
 
 	nb_devs = rte_cryptodev_count();
 	if (nb_devs < 1) {
-		RTE_LOG(ERR, USER1, "No crypto devices found?");
+		RTE_LOG(ERR, USER1, "No crypto devices found?\n");
 		return TEST_FAILED;
 	}
 
@@ -872,7 +877,6 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = {
 	0x18, 0x8c, 0x1d, 0x32
 };
 
-
 static int
 test_AES_CBC_HMAC_SHA1_encrypt_digest(void)
 {
@@ -1003,17 +1007,24 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest[] = {
 
 static int
 test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(
-		struct crypto_unittest_params *ut_params);
+		struct crypto_unittest_params *ut_params,
+		uint8_t *cipher_key,
+		uint8_t *hmac_key);
 
 static int
 test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess,
 		struct crypto_unittest_params *ut_params,
-		struct crypto_testsuite_params *ts_params);
+		struct crypto_testsuite_params *ts_params,
+		const uint8_t *cipher,
+		const uint8_t *digest,
+		const uint8_t *iv);
 
 
 static int
 test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(
-		struct crypto_unittest_params *ut_params)
+		struct crypto_unittest_params *ut_params,
+		uint8_t *cipher_key,
+		uint8_t *hmac_key)
 {
 
 	/* Setup Cipher Parameters */
@@ -1022,7 +1033,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(
 
 	ut_params->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC;
 	ut_params->cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT;
-	ut_params->cipher_xform.cipher.key.data = aes_cbc_key;
+	ut_params->cipher_xform.cipher.key.data = cipher_key;
 	ut_params->cipher_xform.cipher.key.length = CIPHER_KEY_LENGTH_AES_CBC;
 
 	/* Setup HMAC Parameters */
@@ -1031,7 +1042,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(
 
 	ut_params->auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
 	ut_params->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA512_HMAC;
-	ut_params->auth_xform.auth.key.data = hmac_sha512_key;
+	ut_params->auth_xform.auth.key.data = hmac_key;
 	ut_params->auth_xform.auth.key.length = HMAC_KEY_LENGTH_SHA512;
 	ut_params->auth_xform.auth.digest_length = DIGEST_BYTE_LENGTH_SHA512;
 
@@ -1042,12 +1053,15 @@ test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(
 static int
 test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess,
 		struct crypto_unittest_params *ut_params,
-		struct crypto_testsuite_params *ts_params)
+		struct crypto_testsuite_params *ts_params,
+		const uint8_t *cipher,
+		const uint8_t *digest,
+		const uint8_t *iv)
 {
 	/* Generate test mbuf data and digest */
 	ut_params->ibuf = setup_test_string(ts_params->mbuf_pool,
 			(const char *)
-			catch_22_quote_2_512_bytes_AES_CBC_ciphertext,
+			cipher,
 			QUOTE_512_BYTES, 0);
 
 	ut_params->digest = (uint8_t *)rte_pktmbuf_append(ut_params->ibuf,
@@ -1055,7 +1069,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess,
 	TEST_ASSERT_NOT_NULL(ut_params->digest, "no room to append digest");
 
 	rte_memcpy(ut_params->digest,
-			catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest,
+			digest,
 			DIGEST_BYTE_LENGTH_SHA512);
 
 	/* Generate Crypto op data structure */
@@ -1085,7 +1099,7 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess,
 			ut_params->ibuf, 0);
 	sym_op->cipher.iv.length = CIPHER_IV_LENGTH_AES_CBC;
 
-	rte_memcpy(sym_op->cipher.iv.data, aes_cbc_iv,
+	rte_memcpy(sym_op->cipher.iv.data, iv,
 			CIPHER_IV_LENGTH_AES_CBC);
 
 	sym_op->cipher.data.offset = CIPHER_IV_LENGTH_AES_CBC;
@@ -1115,14 +1129,15 @@ test_AES_CBC_HMAC_SHA512_decrypt_perform(struct rte_cryptodev_sym_session *sess,
 }
 
 static int
-test_AES_mb_all(void)
+test_AES_chain_mb_all(void)
 {
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
 	int status;
 
-	status = test_AES_all_tests(ts_params->mbuf_pool,
+	status = test_blockcipher_all_tests(ts_params->mbuf_pool,
 		ts_params->op_mpool, ts_params->valid_devs[0],
-		RTE_CRYPTODEV_AESNI_MB_PMD);
+		RTE_CRYPTODEV_AESNI_MB_PMD,
+		BLKCIPHER_AES_CHAIN_TYPE);
 
 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
 
@@ -1130,14 +1145,15 @@ test_AES_mb_all(void)
 }
 
 static int
-test_AES_qat_all(void)
+test_AES_chain_qat_all(void)
 {
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
 	int status;
 
-	status = test_AES_all_tests(ts_params->mbuf_pool,
+	status = test_blockcipher_all_tests(ts_params->mbuf_pool,
 		ts_params->op_mpool, ts_params->valid_devs[0],
-		RTE_CRYPTODEV_QAT_SYM_PMD);
+		RTE_CRYPTODEV_QAT_SYM_PMD,
+		BLKCIPHER_AES_CHAIN_TYPE);
 
 	TEST_ASSERT_EQUAL(status, 0, "Test failed");
 
@@ -4024,7 +4040,8 @@ test_multi_session(void)
 
 	uint16_t i;
 
-	test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params);
+	test_AES_CBC_HMAC_SHA512_decrypt_create_session_params(ut_params,
+			aes_cbc_key, hmac_sha512_key);
 
 
 	rte_cryptodev_info_get(ts_params->valid_devs[0], &dev_info);
@@ -4043,10 +4060,13 @@ test_multi_session(void)
 				i);
 
 		/* Attempt to send a request on each session */
-		TEST_ASSERT_SUCCESS(test_AES_CBC_HMAC_SHA512_decrypt_perform(
-				sessions[i], ut_params, ts_params),
-				"Failed to perform decrypt on request "
-				"number %u.", i);
+		TEST_ASSERT_SUCCESS(
+				test_AES_CBC_HMAC_SHA512_decrypt_perform(sessions[i], ut_params,
+						ts_params,
+						catch_22_quote_2_512_bytes_AES_CBC_ciphertext,
+						catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA512_digest,
+						aes_cbc_iv),
+				"Failed to perform decrypt on request number %u.", i);
 		/* free crypto operation structure */
 		if (ut_params->op)
 			rte_crypto_op_free(ut_params->op);
@@ -4700,7 +4720,7 @@ static struct unit_test_suite cryptodev_qat_testsuite  = {
 		TEST_CASE_ST(ut_setup, ut_teardown,
 				test_multi_session),
 
-		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_qat_all),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_qat_all),
 		TEST_CASE_ST(ut_setup, ut_teardown, test_stats),
 
 		/** AES GCM Authenticated Encryption */
@@ -4836,7 +4856,7 @@ static struct unit_test_suite cryptodev_aesni_mb_testsuite  = {
 	.setup = testsuite_setup,
 	.teardown = testsuite_teardown,
 	.unit_test_cases = {
-		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_mb_all),
+		TEST_CASE_ST(ut_setup, ut_teardown, test_AES_chain_mb_all),
 
 		TEST_CASES_END() /**< NULL terminate unit test array */
 	}
diff --git a/app/test/test_cryptodev_aes.c b/app/test/test_cryptodev_aes.c
deleted file mode 100644
index e19c45b..0000000
--- a/app/test/test_cryptodev_aes.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *	 * Redistributions of source code must retain the above copyright
- *	   notice, this list of conditions and the following disclaimer.
- *	 * Redistributions in binary form must reproduce the above copyright
- *	   notice, this list of conditions and the following disclaimer in
- *	   the documentation and/or other materials provided with the
- *	   distribution.
- *	 * Neither the name of Intel Corporation nor the names of its
- *	   contributors may be used to endorse or promote products derived
- *	   from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <rte_common.h>
-#include <rte_hexdump.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-
-#include <rte_crypto.h>
-#include <rte_cryptodev.h>
-#include <rte_cryptodev_pmd.h>
-
-#include "test.h"
-#include "test_cryptodev_aes.h"
-
-#ifndef AES_TEST_MSG_LEN
-#define AES_TEST_MSG_LEN		256
-#endif
-
-#define AES_TEST_OP_ENCRYPT		0x01
-#define AES_TEST_OP_DECRYPT		0x02
-#define AES_TEST_OP_AUTH_GEN		0x04
-#define AES_TEST_OP_AUTH_VERIFY		0x08
-
-#define AES_TEST_FEATURE_OOP		0x01
-#define AES_TEST_FEATURE_SESSIONLESS	0x02
-#define AES_TEST_FEATURE_STOPPER	0x04 /* stop upon failing */
-
-#define AES_TEST_TARGET_PMD_MB		0x0001 /* Multi-buffer flag */
-#define AES_TEST_TARGET_PMD_QAT		0x0002 /* QAT flag */
-
-#define AES_TEST_OP_CIPHER		(AES_TEST_OP_ENCRYPT |		\
-					AES_TEST_OP_DECRYPT)
-
-#define AES_TEST_OP_AUTH		(AES_TEST_OP_AUTH_GEN |		\
-					AES_TEST_OP_AUTH_VERIFY)
-
-#define AES_TEST_OP_ENC_AUTH_GEN	(AES_TEST_OP_ENCRYPT |		\
-					AES_TEST_OP_AUTH_GEN)
-
-#define AES_TEST_OP_AUTH_VERIFY_DEC	(AES_TEST_OP_DECRYPT |		\
-					AES_TEST_OP_AUTH_VERIFY)
-
-struct aes_test_case {
-	const char *test_descr; /* test description */
-	const struct aes_test_data *test_data;
-	uint8_t op_mask; /* operation mask */
-	uint8_t feature_mask;
-	uint32_t pmd_mask;
-};
-
-static const struct aes_test_case aes_test_cases[] = {
-	{
-		.test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest",
-		.test_data = &aes_test_data_1,
-		.op_mask = AES_TEST_OP_ENC_AUTH_GEN,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest "
-			"Verify",
-		.test_data = &aes_test_data_1,
-		.op_mask = AES_TEST_OP_AUTH_VERIFY_DEC,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-192-CTR XCBC Encryption Digest",
-		.test_data = &aes_test_data_2,
-		.op_mask = AES_TEST_OP_ENC_AUTH_GEN,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-192-CTR XCBC Decryption Digest Verify",
-		.test_data = &aes_test_data_2,
-		.op_mask = AES_TEST_OP_AUTH_VERIFY_DEC,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest",
-		.test_data = &aes_test_data_3,
-		.op_mask = AES_TEST_OP_ENC_AUTH_GEN,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest "
-			"Verify",
-		.test_data = &aes_test_data_3,
-		.op_mask = AES_TEST_OP_AUTH_VERIFY_DEC,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest",
-		.test_data = &aes_test_data_4,
-		.op_mask = AES_TEST_OP_ENC_AUTH_GEN,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest "
-			"Verify",
-		.test_data = &aes_test_data_4,
-		.op_mask = AES_TEST_OP_AUTH_VERIFY_DEC,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest",
-		.test_data = &aes_test_data_5,
-		.op_mask = AES_TEST_OP_ENC_AUTH_GEN,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest "
-			"Verify",
-		.test_data = &aes_test_data_5,
-		.op_mask = AES_TEST_OP_AUTH_VERIFY_DEC,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest",
-		.test_data = &aes_test_data_6,
-		.op_mask = AES_TEST_OP_ENC_AUTH_GEN,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest "
-			"Sessionless",
-		.test_data = &aes_test_data_6,
-		.op_mask = AES_TEST_OP_ENC_AUTH_GEN,
-		.feature_mask = AES_TEST_FEATURE_SESSIONLESS,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest "
-			"Verify",
-		.test_data = &aes_test_data_6,
-		.op_mask = AES_TEST_OP_AUTH_VERIFY_DEC,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC XCBC Encryption Digest",
-		.test_data = &aes_test_data_7,
-		.op_mask = AES_TEST_OP_ENC_AUTH_GEN,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC XCBC Decryption Digest Verify",
-		.test_data = &aes_test_data_7,
-		.op_mask = AES_TEST_OP_AUTH_VERIFY_DEC,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest "
-			"OOP",
-		.test_data = &aes_test_data_4,
-		.op_mask = AES_TEST_OP_ENC_AUTH_GEN,
-		.feature_mask = AES_TEST_FEATURE_OOP,
-		.pmd_mask = AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest "
-			"Verify OOP",
-		.test_data = &aes_test_data_4,
-		.op_mask = AES_TEST_OP_AUTH_VERIFY_DEC,
-		.feature_mask = AES_TEST_FEATURE_OOP,
-		.pmd_mask = AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest",
-		.test_data = &aes_test_data_8,
-		.op_mask = AES_TEST_OP_ENC_AUTH_GEN,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest "
-			"Verify",
-		.test_data = &aes_test_data_8,
-		.op_mask = AES_TEST_OP_AUTH_VERIFY_DEC,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest",
-		.test_data = &aes_test_data_9,
-		.op_mask = AES_TEST_OP_ENC_AUTH_GEN,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-	{
-		.test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest "
-			"Verify",
-		.test_data = &aes_test_data_9,
-		.op_mask = AES_TEST_OP_AUTH_VERIFY_DEC,
-		.pmd_mask = AES_TEST_TARGET_PMD_MB |
-			AES_TEST_TARGET_PMD_QAT
-	},
-};
-
-static int
-test_AES_one_case(const struct aes_test_case *t,
-	struct rte_mempool *mbuf_pool,
-	struct rte_mempool *op_mpool,
-	uint8_t dev_id,
-	enum rte_cryptodev_type cryptodev_type,
-	char *test_msg)
-{
-	struct rte_mbuf *ibuf = NULL;
-	struct rte_mbuf *obuf = NULL;
-	struct rte_mbuf *iobuf;
-	struct rte_crypto_sym_xform *cipher_xform = NULL;
-	struct rte_crypto_sym_xform *auth_xform = NULL;
-	struct rte_crypto_sym_xform *init_xform = NULL;
-	struct rte_crypto_sym_op *sym_op = NULL;
-	struct rte_crypto_op *op = NULL;
-	struct rte_cryptodev_sym_session *sess = NULL;
-
-	int status = TEST_SUCCESS;
-	const struct aes_test_data *tdata = t->test_data;
-	uint8_t cipher_key[tdata->cipher_key.len];
-	uint8_t auth_key[tdata->auth_key.len];
-	uint32_t buf_len = tdata->ciphertext.len;
-	uint32_t digest_len = 0;
-	char *buf_p = NULL;
-
-	if (tdata->cipher_key.len)
-		memcpy(cipher_key, tdata->cipher_key.data,
-			tdata->cipher_key.len);
-	if (tdata->auth_key.len)
-		memcpy(auth_key, tdata->auth_key.data,
-			tdata->auth_key.len);
-
-	switch (cryptodev_type) {
-	case RTE_CRYPTODEV_QAT_SYM_PMD:
-		digest_len = tdata->digest.len;
-		break;
-	case RTE_CRYPTODEV_AESNI_MB_PMD:
-		digest_len = tdata->digest.truncated_len;
-		break;
-	default:
-		snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s",
-			__LINE__, "Unsupported PMD type");
-		status = TEST_FAILED;
-		goto error_exit;
-	}
-
-	/* preparing data */
-	ibuf = rte_pktmbuf_alloc(mbuf_pool);
-	if (!ibuf) {
-		snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s",
-			__LINE__, "Allocation of rte_mbuf failed");
-		status = TEST_FAILED;
-		goto error_exit;
-	}
-
-	if (t->op_mask & AES_TEST_OP_CIPHER)
-		buf_len += tdata->iv.len;
-	if (t->op_mask & AES_TEST_OP_AUTH)
-		buf_len += digest_len;
-
-	buf_p = rte_pktmbuf_append(ibuf, buf_len);
-	if (!buf_p) {
-		snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s",
-			__LINE__, "No room to append mbuf");
-		status = TEST_FAILED;
-		goto error_exit;
-	}
-
-	if (t->op_mask & AES_TEST_OP_CIPHER) {
-		rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len);
-		buf_p += tdata->iv.len;
-	}
-
-	/* only encryption requires plaintext.data input,
-	 * decryption/(digest gen)/(digest verify) use ciphertext.data
-	 * to be computed */
-	if (t->op_mask & AES_TEST_OP_ENCRYPT) {
-		rte_memcpy(buf_p, tdata->plaintext.data,
-			tdata->plaintext.len);
-		buf_p += tdata->plaintext.len;
-	} else {
-		rte_memcpy(buf_p, tdata->ciphertext.data,
-			tdata->ciphertext.len);
-		buf_p += tdata->ciphertext.len;
-	}
-
-	if (t->op_mask & AES_TEST_OP_AUTH_VERIFY)
-		rte_memcpy(buf_p, tdata->digest.data, digest_len);
-	else
-		memset(buf_p, 0, digest_len);
-
-	if (t->feature_mask & AES_TEST_FEATURE_OOP) {
-		obuf = rte_pktmbuf_alloc(mbuf_pool);
-		if (!obuf) {
-			snprintf(test_msg, AES_TEST_MSG_LEN, "line %u "
-				"FAILED: %s", __LINE__,
-				"Allocation of rte_mbuf failed");
-			status = TEST_FAILED;
-			goto error_exit;
-		}
-
-		buf_p = rte_pktmbuf_append(obuf, buf_len);
-		if (!buf_p) {
-			snprintf(test_msg, AES_TEST_MSG_LEN, "line %u "
-				"FAILED: %s", __LINE__,
-				"No room to append mbuf");
-			status = TEST_FAILED;
-			goto error_exit;
-		}
-		memset(buf_p, 0, buf_len);
-	}
-
-	/* Generate Crypto op data structure */
-	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
-	if (!op) {
-		snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s",
-			__LINE__, "Failed to allocate symmetric crypto "
-			"operation struct");
-		status = TEST_FAILED;
-		goto error_exit;
-	}
-
-	sym_op = op->sym;
-
-	sym_op->m_src = ibuf;
-
-	if (t->feature_mask & AES_TEST_FEATURE_OOP) {
-		sym_op->m_dst = obuf;
-		iobuf = obuf;
-	} else {
-		sym_op->m_dst = NULL;
-		iobuf = ibuf;
-	}
-
-	/* sessionless op requires allocate xform using
-	 * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc()
-	 * is used */
-	if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) {
-		uint32_t n_xforms = 0;
-
-		if (t->op_mask & AES_TEST_OP_CIPHER)
-			n_xforms++;
-		if (t->op_mask & AES_TEST_OP_AUTH)
-			n_xforms++;
-
-		if (rte_crypto_op_sym_xforms_alloc(op, n_xforms)
-			== NULL) {
-			snprintf(test_msg, AES_TEST_MSG_LEN, "line %u "
-				"FAILED: %s", __LINE__, "Failed to "
-				"allocate space for crypto transforms");
-			status = TEST_FAILED;
-			goto error_exit;
-		}
-	} else {
-		cipher_xform = rte_zmalloc(NULL,
-			sizeof(struct rte_crypto_sym_xform), 0);
-
-		auth_xform = rte_zmalloc(NULL,
-			sizeof(struct rte_crypto_sym_xform), 0);
-
-		if (!cipher_xform || !auth_xform) {
-			snprintf(test_msg, AES_TEST_MSG_LEN, "line %u "
-				"FAILED: %s", __LINE__, "Failed to "
-				"allocate memory for crypto transforms");
-			status = TEST_FAILED;
-			goto error_exit;
-		}
-	}
-
-	/* preparing xform, for sessioned op, init_xform is initialized
-	 * here and later as param in rte_cryptodev_sym_session_create()
-	 * call */
-	if (t->op_mask == AES_TEST_OP_ENC_AUTH_GEN) {
-		if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) {
-			cipher_xform = op->sym->xform;
-			auth_xform = cipher_xform->next;
-			auth_xform->next = NULL;
-		} else {
-			cipher_xform->next = auth_xform;
-			auth_xform->next = NULL;
-			init_xform = cipher_xform;
-		}
-	} else if (t->op_mask == AES_TEST_OP_AUTH_VERIFY_DEC) {
-		if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS) {
-			auth_xform = op->sym->xform;
-			cipher_xform = auth_xform->next;
-			cipher_xform->next = NULL;
-		} else {
-			auth_xform->next = cipher_xform;
-			cipher_xform->next = NULL;
-			init_xform = auth_xform;
-		}
-	} else if ((t->op_mask == AES_TEST_OP_ENCRYPT) ||
-			(t->op_mask == AES_TEST_OP_DECRYPT)) {
-		if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)
-			cipher_xform = op->sym->xform;
-		else
-			init_xform = cipher_xform;
-		cipher_xform->next = NULL;
-	} else if ((t->op_mask == AES_TEST_OP_AUTH_GEN) ||
-			(t->op_mask == AES_TEST_OP_AUTH_VERIFY)) {
-		if (t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)
-			auth_xform = op->sym->xform;
-		else
-			init_xform = auth_xform;
-		auth_xform->next = NULL;
-	} else {
-		snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s",
-			__LINE__, "Unrecognized operation");
-		status = TEST_FAILED;
-		goto error_exit;
-	}
-
-	/*configure xforms & sym_op cipher and auth data*/
-	if (t->op_mask & AES_TEST_OP_CIPHER) {
-		cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
-		cipher_xform->cipher.algo = tdata->crypto_algo;
-		if (t->op_mask & AES_TEST_OP_ENCRYPT)
-			cipher_xform->cipher.op =
-				RTE_CRYPTO_CIPHER_OP_ENCRYPT;
-		else
-			cipher_xform->cipher.op =
-				RTE_CRYPTO_CIPHER_OP_DECRYPT;
-		cipher_xform->cipher.key.data = cipher_key;
-		cipher_xform->cipher.key.length = tdata->cipher_key.len;
-
-		sym_op->cipher.data.offset = tdata->iv.len;
-		sym_op->cipher.data.length = tdata->ciphertext.len;
-		sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src,
-			uint8_t *);
-		sym_op->cipher.iv.length = tdata->iv.len;
-		sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(
-			sym_op->m_src);
-	}
-
-	if (t->op_mask & AES_TEST_OP_AUTH) {
-		uint32_t auth_data_offset = 0;
-		uint32_t digest_offset = tdata->ciphertext.len;
-
-		if (t->op_mask & AES_TEST_OP_CIPHER) {
-			digest_offset += tdata->iv.len;
-			auth_data_offset += tdata->iv.len;
-		}
-
-		auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
-		auth_xform->auth.algo = tdata->auth_algo;
-		auth_xform->auth.key.length = tdata->auth_key.len;
-		auth_xform->auth.key.data = auth_key;
-		auth_xform->auth.digest_length = digest_len;
-
-		if (t->op_mask & AES_TEST_OP_AUTH_GEN) {
-			auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
-			sym_op->auth.digest.data = rte_pktmbuf_mtod_offset
-				(iobuf, uint8_t *, digest_offset);
-			sym_op->auth.digest.phys_addr =
-				rte_pktmbuf_mtophys_offset(iobuf,
-					digest_offset);
-		} else {
-			auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
-			sym_op->auth.digest.data = rte_pktmbuf_mtod_offset
-				(sym_op->m_src, uint8_t *, digest_offset);
-			sym_op->auth.digest.phys_addr =
-				rte_pktmbuf_mtophys_offset(sym_op->m_src,
-					digest_offset);
-		}
-
-		sym_op->auth.data.offset = auth_data_offset;
-		sym_op->auth.data.length = tdata->ciphertext.len;
-		sym_op->auth.digest.length = digest_len;
-	}
-
-	/* create session for sessioned op */
-	if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) {
-		sess = rte_cryptodev_sym_session_create(dev_id,
-			init_xform);
-		if (!sess) {
-			snprintf(test_msg, AES_TEST_MSG_LEN, "line %u "
-				"FAILED: %s", __LINE__,
-				"Session creation failed");
-			status = TEST_FAILED;
-			goto error_exit;
-		}
-
-		/* attach symmetric crypto session to crypto operations */
-		rte_crypto_op_attach_sym_session(op, sess);
-	}
-
-	/* Process crypto operation */
-	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
-		snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s",
-			__LINE__, "Error sending packet for encryption");
-		status = TEST_FAILED;
-		goto error_exit;
-	}
-
-	op = NULL;
-
-	while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0)
-		rte_pause();
-
-	if (!op) {
-		snprintf(test_msg, AES_TEST_MSG_LEN, "line %u FAILED: %s",
-			__LINE__, "Failed to process sym crypto op");
-		status = TEST_FAILED;
-		goto error_exit;
-	}
-
-	TEST_HEXDUMP(stdout, "m_src:",
-		rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len);
-	if (t->feature_mask & AES_TEST_FEATURE_OOP)
-		TEST_HEXDUMP(stdout, "m_dst:",
-			rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *),
-			buf_len);
-
-	/* Verify results */
-	if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
-		if (t->op_mask & AES_TEST_OP_AUTH_VERIFY)
-			snprintf(test_msg, AES_TEST_MSG_LEN, "line %u "
-				"FAILED: Digest verification failed "
-				"(0x%X)", __LINE__, op->status);
-		else
-			snprintf(test_msg, AES_TEST_MSG_LEN, "line %u "
-				"FAILED: Digest verification failed "
-				"(0x%X)", __LINE__, op->status);
-		status = TEST_FAILED;
-		goto error_exit;
-	}
-
-	if (t->op_mask & AES_TEST_OP_CIPHER) {
-		uint8_t *crypto_res;
-		const uint8_t *compare_ref;
-		uint32_t compare_len;
-
-		crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *,
-			tdata->iv.len);
-
-		if (t->op_mask & AES_TEST_OP_ENCRYPT) {
-			compare_ref = tdata->ciphertext.data;
-			compare_len = tdata->ciphertext.len;
-		} else {
-			compare_ref = tdata->plaintext.data;
-			compare_len = tdata->plaintext.len;
-		}
-
-		if (memcmp(crypto_res, compare_ref, compare_len)) {
-			snprintf(test_msg, AES_TEST_MSG_LEN, "line %u "
-				"FAILED: %s", __LINE__,
-				"Crypto data not as expected");
-			status = TEST_FAILED;
-			goto error_exit;
-		}
-	}
-
-	if (t->op_mask & AES_TEST_OP_AUTH_GEN) {
-		uint8_t *auth_res;
-
-		if (t->op_mask & AES_TEST_OP_CIPHER)
-			auth_res = rte_pktmbuf_mtod_offset(iobuf,
-				uint8_t *,
-				tdata->iv.len + tdata->ciphertext.len);
-		else
-			auth_res = rte_pktmbuf_mtod_offset(iobuf,
-				uint8_t *, tdata->ciphertext.len);
-
-		if (memcmp(auth_res, tdata->digest.data, digest_len)) {
-			snprintf(test_msg, AES_TEST_MSG_LEN, "line %u "
-				"FAILED: %s", __LINE__, "Generated "
-				"digest data not as expected");
-			status = TEST_FAILED;
-			goto error_exit;
-		}
-	}
-
-	snprintf(test_msg, AES_TEST_MSG_LEN, "PASS");
-
-error_exit:
-	if (!(t->feature_mask & AES_TEST_FEATURE_SESSIONLESS)) {
-		if (sess)
-			rte_cryptodev_sym_session_free(dev_id, sess);
-		if (cipher_xform)
-			rte_free(cipher_xform);
-		if (auth_xform)
-			rte_free(auth_xform);
-	}
-
-	if (op)
-		rte_crypto_op_free(op);
-
-	if (obuf)
-		rte_pktmbuf_free(obuf);
-
-	if (ibuf)
-		rte_pktmbuf_free(ibuf);
-
-	return status;
-}
-
-int
-test_AES_all_tests(struct rte_mempool *mbuf_pool,
-	struct rte_mempool *op_mpool,
-	uint8_t dev_id,
-	enum rte_cryptodev_type cryptodev_type)
-{
-	int status, overall_status = TEST_SUCCESS;
-	uint32_t i, test_index = 0;
-	char test_msg[AES_TEST_MSG_LEN + 1];
-	uint32_t n_test_cases = sizeof(aes_test_cases) /
-			sizeof(aes_test_cases[0]);
-	uint32_t target_pmd_mask = 0;
-
-	switch (cryptodev_type) {
-	case RTE_CRYPTODEV_AESNI_MB_PMD:
-		target_pmd_mask = AES_TEST_TARGET_PMD_MB;
-		break;
-	case RTE_CRYPTODEV_QAT_SYM_PMD:
-		target_pmd_mask = AES_TEST_TARGET_PMD_QAT;
-		break;
-	default:
-		TEST_ASSERT(-1, "Unrecognized cryptodev type");
-		break;
-	}
-
-	for (i = 0; i < n_test_cases; i++) {
-		const struct aes_test_case *tc = &aes_test_cases[i];
-
-		if (!(tc->pmd_mask & target_pmd_mask))
-			continue;
-
-		status = test_AES_one_case(tc, mbuf_pool, op_mpool,
-			dev_id, cryptodev_type, test_msg);
-
-		printf("  %u) TestCase %s %s\n", test_index ++,
-			tc->test_descr, test_msg);
-
-		if (status != TEST_SUCCESS) {
-			if (overall_status == TEST_SUCCESS)
-				overall_status = status;
-
-			if (tc->feature_mask & AES_TEST_FEATURE_STOPPER)
-				break;
-		}
-	}
-
-	return overall_status;
-}
diff --git a/app/test/test_cryptodev_aes.h b/app/test/test_cryptodev_aes.h
deleted file mode 100644
index ef518e0..0000000
--- a/app/test/test_cryptodev_aes.h
+++ /dev/null
@@ -1,1124 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2016 Intel Corporation. All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *	 * Redistributions of source code must retain the above copyright
- *	   notice, this list of conditions and the following disclaimer.
- *	 * Redistributions in binary form must reproduce the above copyright
- *	   notice, this list of conditions and the following disclaimer in
- *	   the documentation and/or other materials provided with the
- *	   distribution.
- *	 * Neither the name of Intel Corporation nor the names of its
- *	   contributors may be used to endorse or promote products derived
- *	   from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef TEST_CRYPTODEV_AES_H_
-#define TEST_CRYPTODEV_AES_H_
-
-struct aes_test_data {
-	enum rte_crypto_cipher_algorithm crypto_algo;
-
-	struct {
-		uint8_t data[64];
-		unsigned len;
-	} cipher_key;
-
-	struct {
-		uint8_t data[64] __rte_aligned(16);
-		unsigned len;
-	} iv;
-
-	struct {
-		uint8_t data[2048];
-		unsigned len;
-	} plaintext;
-
-	struct {
-		uint8_t data[2048];
-		unsigned len;
-	} ciphertext;
-
-	enum rte_crypto_auth_algorithm auth_algo;
-
-	struct {
-		uint8_t data[128];
-		unsigned len;
-	} auth_key;
-
-	struct {
-		uint8_t data[128];
-		unsigned len;		/* for qat */
-		unsigned truncated_len;	/* for mb */
-	} digest;
-};
-
-int
-test_AES_all_tests(struct rte_mempool *mbuf_pool,
-	struct rte_mempool *op_mpool,
-	uint8_t dev_id,
-	enum rte_cryptodev_type cryptodev_type);
-
-/* test vectors */
-/* AES128-CTR-SHA1 test vector */
-static const struct aes_test_data aes_test_data_1 = {
-	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR,
-	.cipher_key = {
-		.data = {
-			0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
-			0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
-		},
-		.len = 16
-	},
-	.iv = {
-		.data = {
-			0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
-			0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
-		},
-		.len = 16
-	},
-	.plaintext = {
-		.data = {
-			0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
-			0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
-			0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
-			0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
-			0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
-			0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
-			0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
-			0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
-		},
-		.len = 64
-	},
-	.ciphertext = {
-		.data = {
-			0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26,
-			0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE,
-			0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF,
-			0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF,
-			0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E,
-			0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB,
-			0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1,
-			0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE
-		},
-		.len = 64
-	},
-	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
-	.auth_key = {
-		.data = {
-			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
-			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
-			0xDE, 0xF4, 0xDE, 0xAD
-		},
-		.len = 20
-	},
-	.digest = {
-		.data = {
-			0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0,
-			0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2,
-			0x56, 0x20, 0xFB, 0xFE
-		},
-		.len = 20,
-		.truncated_len = 12
-	}
-};
-
-/** AES-192-CTR XCBC test vector */
-static const struct aes_test_data aes_test_data_2 = {
-	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR,
-	.cipher_key = {
-		.data = {
-			0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C,
-			0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F,
-			0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4
-		},
-		.len = 24
-	},
-	.iv = {
-		.data = {
-			0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40,
-			0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57
-		},
-		.len = 16
-	},
-	.plaintext = {
-		.data = {
-			0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8,
-			0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B,
-			0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55,
-			0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC,
-			0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86,
-			0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B,
-			0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29,
-			0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96,
-		},
-		.len = 64
-	},
-	.ciphertext = {
-		.data = {
-			0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84,
-			0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2,
-			0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37,
-			0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E,
-			0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34,
-			0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29,
-			0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1,
-			0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0
-		},
-		.len = 64
-	},
-	.auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC,
-	.auth_key = {
-		.data = {
-			0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51,
-			0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59
-		},
-		.len = 16
-	},
-	.digest = {
-		.data = {
-			0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55,
-			0x36, 0x6B, 0x45, 0x46
-		},
-		.len = 12,
-		.truncated_len = 12
-	}
-};
-
-/** AES-256-CTR SHA1 test vector */
-static const struct aes_test_data aes_test_data_3 = {
-	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR,
-	.cipher_key = {
-		.data = {
-			0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
-			0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
-			0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
-			0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4
-		},
-		.len = 32
-	},
-	.iv = {
-		.data = {
-			0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
-			0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
-		},
-		.len = 16
-	},
-	.plaintext = {
-		.data = {
-			0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
-			0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
-			0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
-			0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
-			0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
-			0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
-			0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
-			0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
-		},
-		.len = 64
-	},
-	.ciphertext = {
-		.data = {
-			0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5,
-			0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28,
-			0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A,
-			0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5,
-			0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C,
-			0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D,
-			0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6,
-			0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6
-		},
-		.len = 64
-	},
-	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
-	.auth_key = {
-		.data = {
-			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
-			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
-			0xDE, 0xF4, 0xDE, 0xAD
-		},
-		.len = 20
-	},
-	.digest = {
-		.data = {
-			0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64,
-			0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16,
-			0xE7, 0x87, 0xA3, 0xEF
-		},
-		.len = 20,
-		.truncated_len = 12
-	}
-};
-
-/** AES-128-CBC SHA1 test vector */
-static const struct aes_test_data aes_test_data_4 = {
-	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
-	.cipher_key = {
-		.data = {
-			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
-			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
-		},
-		.len = 16
-	},
-	.iv = {
-		.data = {
-			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
-		},
-		.len = 16
-	},
-	.plaintext = {
-		.data = {
-			"What a lousy earth! He wondered how many people "
-			"were destitute that same night even in his own "
-			"prosperous country, how many homes were "
-			"shanties, how many husbands were drunk and "
-			"wives socked, and how many children were "
-			"bullied, abused, or abandoned. How many "
-			"families hungered for food they could not "
-			"afford to buy? How many hearts were broken? How "
-			"many suicides would take place that same night, "
-			"how many people would go insane? How many "
-			"cockroaches and landlords would triumph? How "
-			"many winners were losers, successes failures, "
-			"and rich men poor men? How many wise guys were "
-			"stupid? How many happy endings were unhappy "
-			"endings? How many honest men were liars, brave "
-			"men cowards, loyal men traitors, how many "
-			"sainted men were corrupt, how many people in "
-			"positions of trust had sold their souls to "
-			"bodyguards, how many had never had souls? How "
-			"many straight-and-narrow paths were crooked "
-			"paths? How many best families were worst "
-			"families and how many good people were bad "
-			"people? When you added them all up and then "
-			"subtracted, you might be left with only the "
-			"children, and perhaps with Albert Einstein and "
-			"an old violinist or sculptor somewhere."
-		},
-		.len = 512
-	},
-	.ciphertext = {
-		.data = {
-			0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31,
-			0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76,
-			0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E,
-			0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A,
-			0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E,
-			0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08,
-			0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0,
-			0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01,
-			0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57,
-			0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE,
-			0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9,
-			0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9,
-			0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D,
-			0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3,
-			0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46,
-			0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3,
-			0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80,
-			0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92,
-			0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5,
-			0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5,
-			0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2,
-			0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5,
-			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
-			0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76,
-			0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4,
-			0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62,
-			0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4,
-			0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4,
-			0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54,
-			0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61,
-			0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91,
-			0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A,
-			0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF,
-			0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F,
-			0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28,
-			0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E,
-			0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7,
-			0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76,
-			0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6,
-			0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03,
-			0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C,
-			0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2,
-			0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6,
-			0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96,
-			0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6,
-			0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA,
-			0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87,
-			0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55,
-			0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B,
-			0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98,
-			0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53,
-			0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A,
-			0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26,
-			0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36,
-			0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36,
-			0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D,
-			0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E,
-			0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E,
-			0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A,
-			0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6,
-			0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4,
-			0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7,
-			0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1,
-			0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C
-		},
-		.len = 512
-	},
-	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
-	.auth_key = {
-		.data = {
-			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
-			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
-			0xDE, 0xF4, 0xDE, 0xAD
-		},
-		.len = 20
-	},
-	.digest = {
-		.data = {
-			0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60,
-			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
-			0x18, 0x8C, 0x1D, 0x32
-		},
-		.len = 20,
-		.truncated_len = 12
-	}
-};
-
-/** AES-128-CBC SHA256 test vector */
-static const struct aes_test_data aes_test_data_5 = {
-	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
-	.cipher_key = {
-		.data = {
-			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
-			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
-		},
-		.len = 16
-	},
-	.iv = {
-		.data = {
-			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
-		},
-		.len = 16
-	},
-	.plaintext = {
-		.data = {
-			"What a lousy earth! He wondered how many people "
-			"were destitute that same night even in his own "
-			"prosperous country, how many homes were "
-			"shanties, how many husbands were drunk and "
-			"wives socked, and how many children were "
-			"bullied, abused, or abandoned. How many "
-			"families hungered for food they could not "
-			"afford to buy? How many hearts were broken? How "
-			"many suicides would take place that same night, "
-			"how many people would go insane? How many "
-			"cockroaches and landlords would triumph? How "
-			"many winners were losers, successes failures, "
-			"and rich men poor men? How many wise guys were "
-			"stupid? How many happy endings were unhappy "
-			"endings? How many honest men were liars, brave "
-			"men cowards, loyal men traitors, how many "
-			"sainted men were corrupt, how many people in "
-			"positions of trust had sold their souls to "
-			"bodyguards, how many had never had souls? How "
-			"many straight-and-narrow paths were crooked "
-			"paths? How many best families were worst "
-			"families and how many good people were bad "
-			"people? When you added them all up and then "
-			"subtracted, you might be left with only the "
-			"children, and perhaps with Albert Einstein and "
-			"an old violinist or sculptor somewhere."
-		},
-		.len = 512
-	},
-	.ciphertext = {
-		.data = {
-			0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31,
-			0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76,
-			0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E,
-			0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A,
-			0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E,
-			0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08,
-			0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0,
-			0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01,
-			0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57,
-			0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE,
-			0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9,
-			0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9,
-			0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D,
-			0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3,
-			0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46,
-			0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3,
-			0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80,
-			0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92,
-			0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5,
-			0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5,
-			0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2,
-			0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5,
-			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
-			0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76,
-			0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4,
-			0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62,
-			0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4,
-			0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4,
-			0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54,
-			0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61,
-			0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91,
-			0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A,
-			0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF,
-			0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F,
-			0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28,
-			0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E,
-			0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7,
-			0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76,
-			0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6,
-			0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03,
-			0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C,
-			0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2,
-			0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6,
-			0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96,
-			0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6,
-			0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA,
-			0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87,
-			0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55,
-			0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B,
-			0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98,
-			0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53,
-			0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A,
-			0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26,
-			0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36,
-			0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36,
-			0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D,
-			0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E,
-			0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E,
-			0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A,
-			0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6,
-			0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4,
-			0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7,
-			0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1,
-			0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C
-		},
-		.len = 512
-	},
-	.auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC,
-	.auth_key = {
-		.data = {
-			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
-			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
-			0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76,
-			0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60
-		},
-		.len = 32
-	},
-	.digest = {
-		.data = {
-			0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55,
-			0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A,
-			0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4,
-			0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15
-		},
-		.len = 32,
-		.truncated_len = 16
-	}
-};
-
-/** AES-128-CBC SHA512 test vector */
-static const struct aes_test_data aes_test_data_6 = {
-	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
-	.cipher_key = {
-		.data = {
-			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
-			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
-		},
-		.len = 16
-	},
-	.iv = {
-		.data = {
-			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
-		},
-		.len = 16
-	},
-	.plaintext = {
-		.data = {
-			"What a lousy earth! He wondered how many people "
-			"were destitute that same night even in his own "
-			"prosperous country, how many homes were "
-			"shanties, how many husbands were drunk and "
-			"wives socked, and how many children were "
-			"bullied, abused, or abandoned. How many "
-			"families hungered for food they could not "
-			"afford to buy? How many hearts were broken? How "
-			"many suicides would take place that same night, "
-			"how many people would go insane? How many "
-			"cockroaches and landlords would triumph? How "
-			"many winners were losers, successes failures, "
-			"and rich men poor men? How many wise guys were "
-			"stupid? How many happy endings were unhappy "
-			"endings? How many honest men were liars, brave "
-			"men cowards, loyal men traitors, how many "
-			"sainted men were corrupt, how many people in "
-			"positions of trust had sold their souls to "
-			"bodyguards, how many had never had souls? How "
-			"many straight-and-narrow paths were crooked "
-			"paths? How many best families were worst "
-			"families and how many good people were bad "
-			"people? When you added them all up and then "
-			"subtracted, you might be left with only the "
-			"children, and perhaps with Albert Einstein and "
-			"an old violinist or sculptor somewhere."
-		},
-		.len = 512
-	},
-	.ciphertext = {
-		.data = {
-			0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31,
-			0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76,
-			0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E,
-			0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A,
-			0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E,
-			0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08,
-			0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0,
-			0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01,
-			0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57,
-			0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE,
-			0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9,
-			0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9,
-			0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D,
-			0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3,
-			0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46,
-			0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3,
-			0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80,
-			0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92,
-			0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5,
-			0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5,
-			0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2,
-			0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5,
-			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
-			0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76,
-			0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4,
-			0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62,
-			0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4,
-			0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4,
-			0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54,
-			0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61,
-			0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91,
-			0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A,
-			0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF,
-			0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F,
-			0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28,
-			0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E,
-			0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7,
-			0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76,
-			0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6,
-			0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03,
-			0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C,
-			0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2,
-			0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6,
-			0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96,
-			0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6,
-			0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA,
-			0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87,
-			0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55,
-			0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B,
-			0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98,
-			0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53,
-			0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A,
-			0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26,
-			0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36,
-			0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36,
-			0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D,
-			0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E,
-			0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E,
-			0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A,
-			0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6,
-			0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4,
-			0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7,
-			0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1,
-			0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C
-		},
-		.len = 512
-	},
-	.auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC,
-	.auth_key = {
-		.data = {
-			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
-			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
-			0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76,
-			0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60,
-			0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1,
-			0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0,
-			0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76,
-			0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60
-		},
-		.len = 64
-	},
-	.digest = {
-		.data = {
-			0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8,
-			0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48,
-			0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8,
-			0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70,
-			0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8,
-			0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E,
-			0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D,
-			0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A
-		},
-		.len = 64,
-		.truncated_len = 32
-	}
-};
-
-/** AES-128-CBC XCBC test vector */
-static const struct aes_test_data aes_test_data_7 = {
-	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
-	.cipher_key = {
-		.data = {
-			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
-			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
-		},
-		.len = 16
-	},
-	.iv = {
-		.data = {
-			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
-		},
-		.len = 16
-	},
-	.plaintext = {
-		.data = {
-			"What a lousy earth! He wondered how many people "
-			"were destitute that same night even in his own "
-			"prosperous country, how many homes were "
-			"shanties, how many husbands were drunk and "
-			"wives socked, and how many children were "
-			"bullied, abused, or abandoned. How many "
-			"families hungered for food they could not "
-			"afford to buy? How many hearts were broken? How "
-			"many suicides would take place that same night, "
-			"how many people would go insane? How many "
-			"cockroaches and landlords would triumph? How "
-			"many winners were losers, successes failures, "
-			"and rich men poor men? How many wise guys were "
-			"stupid? How many happy endings were unhappy "
-			"endings? How many honest men were liars, brave "
-			"men cowards, loyal men traitors, how many "
-			"sainted men were corrupt, how many people in "
-			"positions of trust had sold their souls to "
-			"bodyguards, how many had never had souls? How "
-			"many straight-and-narrow paths were crooked "
-			"paths? How many best families were worst "
-			"families and how many good people were bad "
-			"people? When you added them all up and then "
-			"subtracted, you might be left with only the "
-			"children, and perhaps with Albert Einstein and "
-			"an old violinist or sculptor somewhere."
-		},
-		.len = 512
-	},
-	.ciphertext = {
-		.data = {
-			0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31,
-			0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76,
-			0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E,
-			0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A,
-			0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E,
-			0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08,
-			0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0,
-			0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01,
-			0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57,
-			0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE,
-			0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9,
-			0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9,
-			0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D,
-			0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3,
-			0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46,
-			0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3,
-			0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80,
-			0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92,
-			0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5,
-			0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5,
-			0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2,
-			0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5,
-			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
-			0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76,
-			0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4,
-			0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62,
-			0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4,
-			0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4,
-			0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54,
-			0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61,
-			0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91,
-			0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A,
-			0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF,
-			0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F,
-			0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28,
-			0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E,
-			0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7,
-			0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76,
-			0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6,
-			0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03,
-			0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C,
-			0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2,
-			0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6,
-			0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96,
-			0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6,
-			0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA,
-			0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87,
-			0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55,
-			0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B,
-			0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98,
-			0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53,
-			0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A,
-			0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26,
-			0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36,
-			0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36,
-			0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D,
-			0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E,
-			0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E,
-			0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A,
-			0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6,
-			0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4,
-			0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7,
-			0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1,
-			0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C
-		},
-		.len = 512
-	},
-	.auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC,
-	.auth_key = {
-		.data = {
-			0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51,
-			0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59
-		},
-		.len = 16
-	},
-	.digest = {
-		.data = {
-			0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89,
-			0x77, 0x1D, 0x8B, 0x75
-		},
-		.len = 12,
-		.truncated_len = 12
-	}
-};
-
-/** AES-128-CBC SHA224 test vector */
-static const struct aes_test_data aes_test_data_8 = {
-	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
-	.cipher_key = {
-		.data = {
-			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
-			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
-		},
-		.len = 16
-	},
-	.iv = {
-		.data = {
-			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
-		},
-		.len = 16
-	},
-	.plaintext = {
-		.data = {
-			"What a lousy earth! He wondered how many people "
-			"were destitute that same night even in his own "
-			"prosperous country, how many homes were "
-			"shanties, how many husbands were drunk and "
-			"wives socked, and how many children were "
-			"bullied, abused, or abandoned. How many "
-			"families hungered for food they could not "
-			"afford to buy? How many hearts were broken? How "
-			"many suicides would take place that same night, "
-			"how many people would go insane? How many "
-			"cockroaches and landlords would triumph? How "
-			"many winners were losers, successes failures, "
-			"and rich men poor men? How many wise guys were "
-			"stupid? How many happy endings were unhappy "
-			"endings? How many honest men were liars, brave "
-			"men cowards, loyal men traitors, how many "
-			"sainted men were corrupt, how many people in "
-			"positions of trust had sold their souls to "
-			"bodyguards, how many had never had souls? How "
-			"many straight-and-narrow paths were crooked "
-			"paths? How many best families were worst "
-			"families and how many good people were bad "
-			"people? When you added them all up and then "
-			"subtracted, you might be left with only the "
-			"children, and perhaps with Albert Einstein and "
-			"an old violinist or sculptor somewhere."
-		},
-		.len = 512
-	},
-	.ciphertext = {
-		.data = {
-			0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31,
-			0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76,
-			0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E,
-			0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A,
-			0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E,
-			0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08,
-			0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0,
-			0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01,
-			0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57,
-			0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE,
-			0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9,
-			0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9,
-			0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D,
-			0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3,
-			0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46,
-			0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3,
-			0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80,
-			0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92,
-			0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5,
-			0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5,
-			0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2,
-			0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5,
-			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
-			0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76,
-			0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4,
-			0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62,
-			0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4,
-			0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4,
-			0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54,
-			0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61,
-			0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91,
-			0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A,
-			0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF,
-			0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F,
-			0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28,
-			0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E,
-			0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7,
-			0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76,
-			0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6,
-			0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03,
-			0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C,
-			0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2,
-			0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6,
-			0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96,
-			0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6,
-			0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA,
-			0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87,
-			0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55,
-			0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B,
-			0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98,
-			0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53,
-			0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A,
-			0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26,
-			0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36,
-			0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36,
-			0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D,
-			0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E,
-			0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E,
-			0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A,
-			0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6,
-			0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4,
-			0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7,
-			0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1,
-			0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C
-		},
-		.len = 512
-	},
-	.auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC,
-	.auth_key = {
-		.data = {
-			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
-			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
-			0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76,
-			0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60,
-			0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1,
-			0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0,
-			0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76,
-			0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60
-		},
-		.len = 64
-	},
-	.digest = {
-		.data = {
-			0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98,
-			0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34,
-			0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F,
-			0x63, 0x7C, 0xDD, 0xB7
-		},
-		.len = 28,
-		.truncated_len = 14
-	}
-};
-
-/** AES-128-CBC SHA384 test vector */
-static const struct aes_test_data aes_test_data_9 = {
-	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
-	.cipher_key = {
-		.data = {
-			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
-			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
-		},
-		.len = 16
-	},
-	.iv = {
-		.data = {
-			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
-		},
-		.len = 16
-	},
-	.plaintext = {
-		.data = {
-			"What a lousy earth! He wondered how many people "
-			"were destitute that same night even in his own "
-			"prosperous country, how many homes were "
-			"shanties, how many husbands were drunk and "
-			"wives socked, and how many children were "
-			"bullied, abused, or abandoned. How many "
-			"families hungered for food they could not "
-			"afford to buy? How many hearts were broken? How "
-			"many suicides would take place that same night, "
-			"how many people would go insane? How many "
-			"cockroaches and landlords would triumph? How "
-			"many winners were losers, successes failures, "
-			"and rich men poor men? How many wise guys were "
-			"stupid? How many happy endings were unhappy "
-			"endings? How many honest men were liars, brave "
-			"men cowards, loyal men traitors, how many "
-			"sainted men were corrupt, how many people in "
-			"positions of trust had sold their souls to "
-			"bodyguards, how many had never had souls? How "
-			"many straight-and-narrow paths were crooked "
-			"paths? How many best families were worst "
-			"families and how many good people were bad "
-			"people? When you added them all up and then "
-			"subtracted, you might be left with only the "
-			"children, and perhaps with Albert Einstein and "
-			"an old violinist or sculptor somewhere."
-		},
-		.len = 512
-	},
-	.ciphertext = {
-		.data = {
-			0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31,
-			0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76,
-			0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E,
-			0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A,
-			0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E,
-			0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08,
-			0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0,
-			0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01,
-			0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57,
-			0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE,
-			0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9,
-			0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9,
-			0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D,
-			0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3,
-			0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46,
-			0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3,
-			0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80,
-			0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92,
-			0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5,
-			0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5,
-			0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2,
-			0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5,
-			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
-			0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76,
-			0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4,
-			0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62,
-			0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4,
-			0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4,
-			0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54,
-			0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61,
-			0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91,
-			0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A,
-			0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF,
-			0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F,
-			0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28,
-			0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E,
-			0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7,
-			0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76,
-			0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6,
-			0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03,
-			0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C,
-			0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2,
-			0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6,
-			0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96,
-			0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6,
-			0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA,
-			0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87,
-			0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55,
-			0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B,
-			0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98,
-			0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53,
-			0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A,
-			0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26,
-			0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36,
-			0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36,
-			0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D,
-			0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E,
-			0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E,
-			0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A,
-			0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6,
-			0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4,
-			0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7,
-			0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1,
-			0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C
-		},
-		.len = 512
-	},
-	.auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC,
-	.auth_key = {
-		.data = {
-			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
-			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
-			0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76,
-			0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60,
-			0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1,
-			0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0,
-			0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76,
-			0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60,
-			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
-			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
-			0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76,
-			0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60,
-			0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1,
-			0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0,
-			0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76,
-			0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60
-		},
-		.len = 128
-	},
-	.digest = {
-		.data = {
-			0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72,
-			0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C,
-			0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D,
-			0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D,
-			0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F,
-			0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B
-		},
-		.len = 48,
-		.truncated_len = 24
-	}
-};
-
-#endif /* TEST_CRYPTODEV_AES_H_ */
diff --git a/app/test/test_cryptodev_aes_test_vectors.h b/app/test/test_cryptodev_aes_test_vectors.h
new file mode 100644
index 0000000..92c0cc2
--- /dev/null
+++ b/app/test/test_cryptodev_aes_test_vectors.h
@@ -0,0 +1,797 @@
+/*
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *	 * Redistributions of source code must retain the above copyright
+ *	   notice, this list of conditions and the following disclaimer.
+ *	 * Redistributions in binary form must reproduce the above copyright
+ *	   notice, this list of conditions and the following disclaimer in
+ *	   the documentation and/or other materials provided with the
+ *	   distribution.
+ *	 * Neither the name of Intel Corporation nor the names of its
+ *	   contributors may be used to endorse or promote products derived
+ *	   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEST_CRYPTODEV_AES_TEST_VECTORS_H_
+#define TEST_CRYPTODEV_AES_TEST_VECTORS_H_
+
+/* test vectors */
+static const uint8_t plaintext_aes128ctr[] = {
+	0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
+	0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
+	0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
+	0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
+	0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
+	0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
+	0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
+	0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
+};
+
+static const uint8_t ciphertext64_aes128ctr[] = {
+	0x87, 0x4D, 0x61, 0x91, 0xB6, 0x20, 0xE3, 0x26,
+	0x1B, 0xEF, 0x68, 0x64, 0x99, 0x0D, 0xB6, 0xCE,
+	0x98, 0x06, 0xF6, 0x6B, 0x79, 0x70, 0xFD, 0xFF,
+	0x86, 0x17, 0x18, 0x7B, 0xB9, 0xFF, 0xFD, 0xFF,
+	0x5A, 0xE4, 0xDF, 0x3E, 0xDB, 0xD5, 0xD3, 0x5E,
+	0x5B, 0x4F, 0x09, 0x02, 0x0D, 0xB0, 0x3E, 0xAB,
+	0x1E, 0x03, 0x1D, 0xDA, 0x2F, 0xBE, 0x03, 0xD1,
+	0x79, 0x21, 0x70, 0xA0, 0xF3, 0x00, 0x9C, 0xEE
+};
+
+static const uint8_t plaintext_aes192ctr[] = {
+	0x01, 0x0F, 0x10, 0x1F, 0x20, 0x1C, 0x0E, 0xB8,
+	0xFB, 0x5C, 0xCD, 0xCC, 0x1F, 0xF9, 0xAF, 0x0B,
+	0x95, 0x03, 0x74, 0x99, 0x49, 0xE7, 0x62, 0x55,
+	0xDA, 0xEA, 0x13, 0x20, 0x1D, 0xC6, 0xCC, 0xCC,
+	0xD1, 0x70, 0x75, 0x47, 0x02, 0x2F, 0xFB, 0x86,
+	0xBB, 0x6B, 0x23, 0xD2, 0xC9, 0x74, 0xD7, 0x7B,
+	0x08, 0x03, 0x3B, 0x79, 0x39, 0xBB, 0x91, 0x29,
+	0xDA, 0x14, 0x39, 0x8D, 0xFF, 0x81, 0x50, 0x96,
+};
+
+static const uint8_t ciphertext64_aes192ctr[] = {
+	0x4A, 0x6C, 0xC8, 0xCC, 0x96, 0x2A, 0x13, 0x84,
+	0x1C, 0x36, 0x88, 0xE9, 0xE5, 0x94, 0x70, 0xB2,
+	0x14, 0x5B, 0x13, 0x80, 0xEA, 0xD8, 0x8D, 0x37,
+	0xFD, 0x70, 0xA8, 0x83, 0xE8, 0x2B, 0x88, 0x1E,
+	0xBA, 0x94, 0x3F, 0xF6, 0xB3, 0x1F, 0xDE, 0x34,
+	0xF3, 0x5B, 0x80, 0xE9, 0xAB, 0xF5, 0x1C, 0x29,
+	0xB6, 0xD9, 0x76, 0x2B, 0x06, 0xC6, 0x74, 0xF1,
+	0x59, 0x5E, 0x9E, 0xA5, 0x7B, 0x2D, 0xD7, 0xF0
+};
+
+static const uint8_t plaintext_aes256ctr[] = {
+	0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
+	0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
+	0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
+	0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
+	0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
+	0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
+	0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
+	0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
+};
+
+static const uint8_t ciphertext64_aes256ctr[] = {
+	0x60, 0x1E, 0xC3, 0x13, 0x77, 0x57, 0x89, 0xA5,
+	0xB7, 0xA7, 0xF5, 0x04, 0xBB, 0xF3, 0xD2, 0x28,
+	0xF4, 0x43, 0xE3, 0xCA, 0x4D, 0x62, 0xB5, 0x9A,
+	0xCA, 0x84, 0xE9, 0x90, 0xCA, 0xCA, 0xF5, 0xC5,
+	0x2B, 0x09, 0x30, 0xDA, 0xA2, 0x3D, 0xE9, 0x4C,
+	0xE8, 0x70, 0x17, 0xBA, 0x2D, 0x84, 0x98, 0x8D,
+	0xDF, 0xC9, 0xC5, 0x8D, 0xB6, 0x7A, 0xAD, 0xA6,
+	0x13, 0xC2, 0xDD, 0x08, 0x45, 0x79, 0x41, 0xA6
+};
+
+static const uint8_t plaintext_aes_common[] = {
+	"What a lousy earth! He wondered how many people "
+	"were destitute that same night even in his own "
+	"prosperous country, how many homes were "
+	"shanties, how many husbands were drunk and "
+	"wives socked, and how many children were "
+	"bullied, abused, or abandoned. How many "
+	"families hungered for food they could not "
+	"afford to buy? How many hearts were broken? How "
+	"many suicides would take place that same night, "
+	"how many people would go insane? How many "
+	"cockroaches and landlords would triumph? How "
+	"many winners were losers, successes failures, "
+	"and rich men poor men? How many wise guys were "
+	"stupid? How many happy endings were unhappy "
+	"endings? How many honest men were liars, brave "
+	"men cowards, loyal men traitors, how many "
+	"sainted men were corrupt, how many people in "
+	"positions of trust had sold their souls to "
+	"bodyguards, how many had never had souls? How "
+	"many straight-and-narrow paths were crooked "
+	"paths? How many best families were worst "
+	"families and how many good people were bad "
+	"people? When you added them all up and then "
+	"subtracted, you might be left with only the "
+	"children, and perhaps with Albert Einstein and "
+	"an old violinist or sculptor somewhere."
+};
+
+static const uint8_t ciphertext512_aes128cbc[] = {
+	0x8B, 0x4D, 0xDA, 0x1B, 0xCF, 0x04, 0xA0, 0x31,
+	0xB4, 0xBF, 0xBD, 0x68, 0x43, 0x20, 0x7E, 0x76,
+	0xB1, 0x96, 0x8B, 0xA2, 0x7C, 0xA2, 0x83, 0x9E,
+	0x39, 0x5A, 0x2F, 0x7E, 0x92, 0xB4, 0x48, 0x1A,
+	0x3F, 0x6B, 0x5D, 0xDF, 0x52, 0x85, 0x5F, 0x8E,
+	0x42, 0x3C, 0xFB, 0xE9, 0x1A, 0x24, 0xD6, 0x08,
+	0xDD, 0xFD, 0x16, 0xFB, 0xE9, 0x55, 0xEF, 0xF0,
+	0xA0, 0x8D, 0x13, 0xAB, 0x81, 0xC6, 0x90, 0x01,
+	0xB5, 0x18, 0x84, 0xB3, 0xF6, 0xE6, 0x11, 0x57,
+	0xD6, 0x71, 0xC6, 0x3C, 0x3F, 0x2F, 0x33, 0xEE,
+	0x24, 0x42, 0x6E, 0xAC, 0x0B, 0xCA, 0xEC, 0xF9,
+	0x84, 0xF8, 0x22, 0xAA, 0x60, 0xF0, 0x32, 0xA9,
+	0x75, 0x75, 0x3B, 0xCB, 0x70, 0x21, 0x0A, 0x8D,
+	0x0F, 0xE0, 0xC4, 0x78, 0x2B, 0xF8, 0x97, 0xE3,
+	0xE4, 0x26, 0x4B, 0x29, 0xDA, 0x88, 0xCD, 0x46,
+	0xEC, 0xAA, 0xF9, 0x7F, 0xF1, 0x15, 0xEA, 0xC3,
+	0x87, 0xE6, 0x31, 0xF2, 0xCF, 0xDE, 0x4D, 0x80,
+	0x70, 0x91, 0x7E, 0x0C, 0xF7, 0x26, 0x3A, 0x92,
+	0x4F, 0x18, 0x83, 0xC0, 0x8F, 0x59, 0x01, 0xA5,
+	0x88, 0xD1, 0xDB, 0x26, 0x71, 0x27, 0x16, 0xF5,
+	0xEE, 0x10, 0x82, 0xAC, 0x68, 0x26, 0x9B, 0xE2,
+	0x6D, 0xD8, 0x9A, 0x80, 0xDF, 0x04, 0x31, 0xD5,
+	0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
+	0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76,
+	0x73, 0x02, 0x42, 0xC9, 0x23, 0x18, 0x8E, 0xB4,
+	0x6F, 0xB4, 0xA3, 0x54, 0x6E, 0x88, 0x3B, 0x62,
+	0x7C, 0x02, 0x8D, 0x4C, 0x9F, 0xC8, 0x45, 0xF4,
+	0xC9, 0xDE, 0x4F, 0xEB, 0x22, 0x83, 0x1B, 0xE4,
+	0x49, 0x37, 0xE4, 0xAD, 0xE7, 0xCD, 0x21, 0x54,
+	0xBC, 0x1C, 0xC2, 0x04, 0x97, 0xB4, 0x10, 0x61,
+	0xF0, 0xE4, 0xEF, 0x27, 0x63, 0x3A, 0xDA, 0x91,
+	0x41, 0x25, 0x62, 0x1C, 0x5C, 0xB6, 0x38, 0x4A,
+	0x88, 0x71, 0x59, 0x5A, 0x8D, 0xA0, 0x09, 0xAF,
+	0x72, 0x94, 0xD7, 0x79, 0x5C, 0x60, 0x7C, 0x8F,
+	0x4C, 0xF5, 0xD9, 0xA1, 0x39, 0x6D, 0x81, 0x28,
+	0xEF, 0x13, 0x28, 0xDF, 0xF5, 0x3E, 0xF7, 0x8E,
+	0x09, 0x9C, 0x78, 0x18, 0x79, 0xB8, 0x68, 0xD7,
+	0xA8, 0x29, 0x62, 0xAD, 0xDE, 0xE1, 0x61, 0x76,
+	0x1B, 0x05, 0x16, 0xCD, 0xBF, 0x02, 0x8E, 0xA6,
+	0x43, 0x6E, 0x92, 0x55, 0x4F, 0x60, 0x9C, 0x03,
+	0xB8, 0x4F, 0xA3, 0x02, 0xAC, 0xA8, 0xA7, 0x0C,
+	0x1E, 0xB5, 0x6B, 0xF8, 0xC8, 0x4D, 0xDE, 0xD2,
+	0xB0, 0x29, 0x6E, 0x40, 0xE6, 0xD6, 0xC9, 0xE6,
+	0xB9, 0x0F, 0xB6, 0x63, 0xF5, 0xAA, 0x2B, 0x96,
+	0xA7, 0x16, 0xAC, 0x4E, 0x0A, 0x33, 0x1C, 0xA6,
+	0xE6, 0xBD, 0x8A, 0xCF, 0x40, 0xA9, 0xB2, 0xFA,
+	0x63, 0x27, 0xFD, 0x9B, 0xD9, 0xFC, 0xD5, 0x87,
+	0x8D, 0x4C, 0xB6, 0xA4, 0xCB, 0xE7, 0x74, 0x55,
+	0xF4, 0xFB, 0x41, 0x25, 0xB5, 0x4B, 0x0A, 0x1B,
+	0xB1, 0xD6, 0xB7, 0xD9, 0x47, 0x2A, 0xC3, 0x98,
+	0x6A, 0xC4, 0x03, 0x73, 0x1F, 0x93, 0x6E, 0x53,
+	0x19, 0x25, 0x64, 0x15, 0x83, 0xF9, 0x73, 0x2A,
+	0x74, 0xB4, 0x93, 0x69, 0xC4, 0x72, 0xFC, 0x26,
+	0xA2, 0x9F, 0x43, 0x45, 0xDD, 0xB9, 0xEF, 0x36,
+	0xC8, 0x3A, 0xCD, 0x99, 0x9B, 0x54, 0x1A, 0x36,
+	0xC1, 0x59, 0xF8, 0x98, 0xA8, 0xCC, 0x28, 0x0D,
+	0x73, 0x4C, 0xEE, 0x98, 0xCB, 0x7C, 0x58, 0x7E,
+	0x20, 0x75, 0x1E, 0xB7, 0xC9, 0xF8, 0xF2, 0x0E,
+	0x63, 0x9E, 0x05, 0x78, 0x1A, 0xB6, 0xA8, 0x7A,
+	0xF9, 0x98, 0x6A, 0xA6, 0x46, 0x84, 0x2E, 0xF6,
+	0x4B, 0xDC, 0x9B, 0x8F, 0x9B, 0x8F, 0xEE, 0xB4,
+	0xAA, 0x3F, 0xEE, 0xC0, 0x37, 0x27, 0x76, 0xC7,
+	0x95, 0xBB, 0x26, 0x74, 0x69, 0x12, 0x7F, 0xF1,
+	0xBB, 0xFF, 0xAE, 0xB5, 0x99, 0x6E, 0xCB, 0x0C
+};
+
+/* AES128-CTR-SHA1 test vector */
+static const struct blockcipher_test_data aes_test_data_1 = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR,
+	.cipher_key = {
+		.data = {
+			0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
+			0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+			0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes128ctr,
+		.len = 64
+	},
+	.ciphertext = {
+		.data = ciphertext64_aes128ctr,
+		.len = 64
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD
+		},
+		.len = 20
+	},
+	.digest = {
+		.data = {
+			0x9B, 0x6F, 0x0C, 0x43, 0xF5, 0xC1, 0x3E, 0xB0,
+			0xB1, 0x70, 0xB8, 0x2B, 0x33, 0x09, 0xD2, 0xB2,
+			0x56, 0x20, 0xFB, 0xFE
+		},
+		.len = 20,
+		.truncated_len = 12
+	}
+};
+
+/** AES-192-CTR XCBC test vector */
+static const struct blockcipher_test_data aes_test_data_2 = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR,
+	.cipher_key = {
+		.data = {
+			0xCB, 0xC5, 0xED, 0x5B, 0xE7, 0x7C, 0xBD, 0x8C,
+			0x50, 0xD9, 0x30, 0xF2, 0xB5, 0x6A, 0x0E, 0x5F,
+			0xAA, 0xAE, 0xAD, 0xA2, 0x1F, 0x49, 0x52, 0xD4
+		},
+		.len = 24
+	},
+	.iv = {
+		.data = {
+			0x3F, 0x69, 0xA8, 0xCD, 0xE8, 0xF0, 0xEF, 0x40,
+			0xB8, 0x7A, 0x4B, 0xED, 0x2B, 0xAF, 0xBF, 0x57
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes192ctr,
+		.len = 64
+	},
+	.ciphertext = {
+		.data = ciphertext64_aes192ctr,
+		.len = 64
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC,
+	.auth_key = {
+		.data = {
+			0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51,
+			0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59
+		},
+		.len = 16
+	},
+	.digest = {
+		.data = {
+			0xCA, 0x33, 0xB3, 0x3B, 0x16, 0x94, 0xAA, 0x55,
+			0x36, 0x6B, 0x45, 0x46
+		},
+		.len = 12,
+		.truncated_len = 12
+	}
+};
+
+/** AES-256-CTR SHA1 test vector */
+static const struct blockcipher_test_data aes_test_data_3 = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CTR,
+	.cipher_key = {
+		.data = {
+			0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
+			0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
+			0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
+			0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4
+		},
+		.len = 32
+	},
+	.iv = {
+		.data = {
+			0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+			0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes256ctr,
+		.len = 64
+	},
+	.ciphertext = {
+		.data = ciphertext64_aes256ctr,
+		.len = 64
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD
+		},
+		.len = 20
+	},
+	.digest = {
+		.data = {
+			0x3B, 0x1A, 0x9D, 0x82, 0x35, 0xD5, 0xDD, 0x64,
+			0xCC, 0x1B, 0xA9, 0xC0, 0xEB, 0xE9, 0x42, 0x16,
+			0xE7, 0x87, 0xA3, 0xEF
+		},
+		.len = 20,
+		.truncated_len = 12
+	}
+};
+
+/** AES-128-CBC SHA1 test vector */
+static const struct blockcipher_test_data aes_test_data_4 = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes_common,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_aes128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+	.auth_key = {
+		.data = {
+			0xF8, 0x2A, 0xC7, 0x54, 0xDB, 0x96, 0x18, 0xAA,
+			0xC3, 0xA1, 0x53, 0xF6, 0x1F, 0x17, 0x60, 0xBD,
+			0xDE, 0xF4, 0xDE, 0xAD
+		},
+		.len = 20
+	},
+	.digest = {
+		.data = {
+			0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60,
+			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+			0x18, 0x8C, 0x1D, 0x32
+		},
+		.len = 20,
+		.truncated_len = 12
+	}
+};
+
+/** AES-128-CBC SHA256 test vector */
+static const struct blockcipher_test_data aes_test_data_5 = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes_common,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_aes128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA256_HMAC,
+	.auth_key = {
+		.data = {
+			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
+			0x58, 0x34, 0x85, 0x61, 0x1C, 0x42, 0x10, 0x76,
+			0x9A, 0x4F, 0x88, 0x1B, 0xB6, 0x8F, 0xD8, 0x60
+		},
+		.len = 32
+	},
+	.digest = {
+		.data = {
+			0xC8, 0x57, 0x57, 0x31, 0x03, 0xE0, 0x03, 0x55,
+			0x07, 0xC8, 0x9E, 0x7F, 0x48, 0x9A, 0x61, 0x9A,
+			0x68, 0xEE, 0x03, 0x0E, 0x71, 0x75, 0xC7, 0xF4,
+			0x2E, 0x45, 0x26, 0x32, 0x7C, 0x12, 0x15, 0x15
+		},
+		.len = 32,
+		.truncated_len = 16
+	}
+};
+
+/** AES-128-CBC SHA512 test vector */
+static const struct blockcipher_test_data aes_test_data_6 = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes_common,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_aes128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA512_HMAC,
+	.auth_key = {
+		.data = {
+			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
+			0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76,
+			0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60,
+			0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1,
+			0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0,
+			0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76,
+			0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60
+		},
+		.len = 64
+	},
+	.digest = {
+		.data = {
+			0x5D, 0x54, 0x66, 0xC1, 0x6E, 0xBC, 0x04, 0xB8,
+			0x46, 0xB8, 0x08, 0x6E, 0xE0, 0xF0, 0x43, 0x48,
+			0x37, 0x96, 0x9C, 0xC6, 0x9C, 0xC2, 0x1E, 0xE8,
+			0xF2, 0x0C, 0x0B, 0xEF, 0x86, 0xA2, 0xE3, 0x70,
+			0x95, 0xC8, 0xB3, 0x06, 0x47, 0xA9, 0x90, 0xE8,
+			0xA0, 0xC6, 0x72, 0x69, 0x05, 0xC0, 0x0D, 0x0E,
+			0x21, 0x96, 0x65, 0x93, 0x74, 0x43, 0x2A, 0x1D,
+			0x2E, 0xBF, 0xC2, 0xC2, 0xEE, 0xCC, 0x2F, 0x0A
+		},
+		.len = 64,
+		.truncated_len = 32
+	}
+};
+
+/** AES-128-CBC XCBC test vector */
+static const struct blockcipher_test_data aes_test_data_7 = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes_common,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_aes128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_AES_XCBC_MAC,
+	.auth_key = {
+		.data = {
+			0x87, 0x61, 0x54, 0x53, 0xC4, 0x6D, 0xDD, 0x51,
+			0xE1, 0x9F, 0x86, 0x64, 0x39, 0x0A, 0xE6, 0x59
+		},
+		.len = 16
+	},
+	.digest = {
+		.data = {
+			0xE0, 0xAC, 0x9A, 0xC4, 0x22, 0x64, 0x35, 0x89,
+			0x77, 0x1D, 0x8B, 0x75
+		},
+		.len = 12,
+		.truncated_len = 12
+	}
+};
+
+/** AES-128-CBC SHA224 test vector */
+static const struct blockcipher_test_data aes_test_data_8 = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes_common,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_aes128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA224_HMAC,
+	.auth_key = {
+		.data = {
+			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
+			0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76,
+			0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60,
+			0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1,
+			0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0,
+			0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76,
+			0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60
+		},
+		.len = 64
+	},
+	.digest = {
+		.data = {
+			0xA3, 0xCA, 0xC7, 0x1D, 0xA8, 0x61, 0x30, 0x98,
+			0x3B, 0x8F, 0x01, 0x19, 0xAE, 0x8D, 0xBD, 0x34,
+			0x40, 0x63, 0xA8, 0x2F, 0xDF, 0x85, 0x2B, 0x7F,
+			0x63, 0x7C, 0xDD, 0xB7
+		},
+		.len = 28,
+		.truncated_len = 14
+	}
+};
+
+/** AES-128-CBC SHA384 test vector */
+static const struct blockcipher_test_data aes_test_data_9 = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_CBC,
+	.cipher_key = {
+		.data = {
+			0xE4, 0x23, 0x33, 0x8A, 0x35, 0x64, 0x61, 0xE2,
+			0x49, 0x03, 0xDD, 0xC6, 0xB8, 0xCA, 0x55, 0x7A
+		},
+		.len = 16
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes_common,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext512_aes128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA384_HMAC,
+	.auth_key = {
+		.data = {
+			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
+			0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76,
+			0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60,
+			0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1,
+			0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0,
+			0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76,
+			0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60,
+			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA,
+			0x58, 0x34, 0x85, 0x65, 0x1C, 0x42, 0x50, 0x76,
+			0x9A, 0xAF, 0x88, 0x1B, 0xB6, 0x8F, 0xF8, 0x60,
+			0xA2, 0x5A, 0x7F, 0x3F, 0xF4, 0x72, 0x70, 0xF1,
+			0xF5, 0x35, 0x4C, 0x3B, 0xDD, 0x90, 0x65, 0xB0,
+			0x47, 0x3A, 0x75, 0x61, 0x5C, 0xA2, 0x10, 0x76,
+			0x9A, 0xAF, 0x77, 0x5B, 0xB6, 0x7F, 0xF7, 0x60
+		},
+		.len = 128
+	},
+	.digest = {
+		.data = {
+			0x23, 0x60, 0xC8, 0xB1, 0x2D, 0x6C, 0x1E, 0x72,
+			0x25, 0xAB, 0xF9, 0xC3, 0x9A, 0xA9, 0x4F, 0x8C,
+			0x56, 0x38, 0x65, 0x0E, 0x74, 0xD5, 0x45, 0x9D,
+			0xA3, 0xFD, 0x7E, 0x6D, 0x9E, 0x74, 0x88, 0x9D,
+			0xA7, 0x12, 0x9D, 0xD8, 0x81, 0x3C, 0x86, 0x2F,
+			0x4D, 0xF9, 0x6F, 0x0A, 0xB0, 0xC9, 0xEB, 0x0B
+		},
+		.len = 48,
+		.truncated_len = 24
+	}
+};
+
+static const struct blockcipher_test_case aes_chain_test_cases[] = {
+	{
+		.test_descr = "AES-128-CTR HMAC-SHA1 Encryption Digest",
+		.test_data = &aes_test_data_1,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CTR HMAC-SHA1 Decryption Digest "
+			"Verify",
+		.test_data = &aes_test_data_1,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-192-CTR XCBC Encryption Digest",
+		.test_data = &aes_test_data_2,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-192-CTR XCBC Decryption Digest Verify",
+		.test_data = &aes_test_data_2,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-256-CTR HMAC-SHA1 Encryption Digest",
+		.test_data = &aes_test_data_3,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-256-CTR HMAC-SHA1 Decryption Digest "
+			"Verify",
+		.test_data = &aes_test_data_3,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest",
+		.test_data = &aes_test_data_4,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest "
+			"Verify",
+		.test_data = &aes_test_data_4,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA256 Encryption Digest",
+		.test_data = &aes_test_data_5,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA256 Decryption Digest "
+			"Verify",
+		.test_data = &aes_test_data_5,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest",
+		.test_data = &aes_test_data_6,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA512 Encryption Digest "
+			"Sessionless",
+		.test_data = &aes_test_data_6,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_SESSIONLESS,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest "
+			"Verify",
+		.test_data = &aes_test_data_6,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC XCBC Encryption Digest",
+		.test_data = &aes_test_data_7,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC XCBC Decryption Digest Verify",
+		.test_data = &aes_test_data_7,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest "
+			"OOP",
+		.test_data = &aes_test_data_4,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest "
+			"Verify OOP",
+		.test_data = &aes_test_data_4,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.feature_mask = BLOCKCIPHER_TEST_FEATURE_OOP,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA224 Encryption Digest",
+		.test_data = &aes_test_data_8,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA224 Decryption Digest "
+			"Verify",
+		.test_data = &aes_test_data_8,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA384 Encryption Digest",
+		.test_data = &aes_test_data_9,
+		.op_mask = BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+	{
+		.test_descr = "AES-128-CBC HMAC-SHA384 Decryption Digest "
+			"Verify",
+		.test_data = &aes_test_data_9,
+		.op_mask = BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC,
+		.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB |
+			BLOCKCIPHER_TEST_TARGET_PMD_QAT
+	},
+};
+
+#endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */
diff --git a/app/test/test_cryptodev_blockcipher.c b/app/test/test_cryptodev_blockcipher.c
new file mode 100644
index 0000000..6661859
--- /dev/null
+++ b/app/test/test_cryptodev_blockcipher.c
@@ -0,0 +1,509 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *	 * Redistributions of source code must retain the above copyright
+ *	   notice, this list of conditions and the following disclaimer.
+ *	 * Redistributions in binary form must reproduce the above copyright
+ *	   notice, this list of conditions and the following disclaimer in
+ *	   the documentation and/or other materials provided with the
+ *	   distribution.
+ *	 * Neither the name of Intel Corporation nor the names of its
+ *	   contributors may be used to endorse or promote products derived
+ *	   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_common.h>
+#include <rte_hexdump.h>
+#include <rte_mbuf.h>
+#include <rte_malloc.h>
+#include <rte_memcpy.h>
+
+#include <rte_crypto.h>
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
+
+#include "test.h"
+#include "test_cryptodev_blockcipher.h"
+#include "test_cryptodev_aes_test_vectors.h"
+
+static int
+test_blockcipher_one_case(const struct blockcipher_test_case *t,
+	struct rte_mempool *mbuf_pool,
+	struct rte_mempool *op_mpool,
+	uint8_t dev_id,
+	enum rte_cryptodev_type cryptodev_type,
+	char *test_msg)
+{
+	struct rte_mbuf *ibuf = NULL;
+	struct rte_mbuf *obuf = NULL;
+	struct rte_mbuf *iobuf;
+	struct rte_crypto_sym_xform *cipher_xform = NULL;
+	struct rte_crypto_sym_xform *auth_xform = NULL;
+	struct rte_crypto_sym_xform *init_xform = NULL;
+	struct rte_crypto_sym_op *sym_op = NULL;
+	struct rte_crypto_op *op = NULL;
+	struct rte_cryptodev_sym_session *sess = NULL;
+
+	int status = TEST_SUCCESS;
+	const struct blockcipher_test_data *tdata = t->test_data;
+	uint8_t cipher_key[tdata->cipher_key.len];
+	uint8_t auth_key[tdata->auth_key.len];
+	uint32_t buf_len = tdata->ciphertext.len;
+	uint32_t digest_len = 0;
+	char *buf_p = NULL;
+
+	if (tdata->cipher_key.len)
+		memcpy(cipher_key, tdata->cipher_key.data,
+			tdata->cipher_key.len);
+	if (tdata->auth_key.len)
+		memcpy(auth_key, tdata->auth_key.data,
+			tdata->auth_key.len);
+
+	switch (cryptodev_type) {
+	case RTE_CRYPTODEV_QAT_SYM_PMD:
+		digest_len = tdata->digest.len;
+		break;
+	case RTE_CRYPTODEV_AESNI_MB_PMD:
+		digest_len = tdata->digest.truncated_len;
+		break;
+	default:
+		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s",
+			__LINE__, "Unsupported PMD type");
+		status = TEST_FAILED;
+		goto error_exit;
+	}
+
+	/* preparing data */
+	ibuf = rte_pktmbuf_alloc(mbuf_pool);
+	if (!ibuf) {
+		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s",
+			__LINE__, "Allocation of rte_mbuf failed");
+		status = TEST_FAILED;
+		goto error_exit;
+	}
+
+	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
+		buf_len += tdata->iv.len;
+	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
+		buf_len += digest_len;
+
+	buf_p = rte_pktmbuf_append(ibuf, buf_len);
+	if (!buf_p) {
+		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s",
+			__LINE__, "No room to append mbuf");
+		status = TEST_FAILED;
+		goto error_exit;
+	}
+
+	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
+		rte_memcpy(buf_p, tdata->iv.data, tdata->iv.len);
+		buf_p += tdata->iv.len;
+	}
+
+	/* only encryption requires plaintext.data input,
+	 * decryption/(digest gen)/(digest verify) use ciphertext.data
+	 * to be computed
+	 */
+	if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {
+		rte_memcpy(buf_p, tdata->plaintext.data,
+			tdata->plaintext.len);
+		buf_p += tdata->plaintext.len;
+	} else {
+		rte_memcpy(buf_p, tdata->ciphertext.data,
+			tdata->ciphertext.len);
+		buf_p += tdata->ciphertext.len;
+	}
+
+	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
+		rte_memcpy(buf_p, tdata->digest.data, digest_len);
+	else
+		memset(buf_p, 0, digest_len);
+
+	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
+		obuf = rte_pktmbuf_alloc(mbuf_pool);
+		if (!obuf) {
+			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
+				"FAILED: %s", __LINE__,
+				"Allocation of rte_mbuf failed");
+			status = TEST_FAILED;
+			goto error_exit;
+		}
+
+		buf_p = rte_pktmbuf_append(obuf, buf_len);
+		if (!buf_p) {
+			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
+				"FAILED: %s", __LINE__,
+				"No room to append mbuf");
+			status = TEST_FAILED;
+			goto error_exit;
+		}
+		memset(buf_p, 0, buf_len);
+	}
+
+	/* Generate Crypto op data structure */
+	op = rte_crypto_op_alloc(op_mpool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	if (!op) {
+		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s",
+			__LINE__, "Failed to allocate symmetric crypto "
+			"operation struct");
+		status = TEST_FAILED;
+		goto error_exit;
+	}
+
+	sym_op = op->sym;
+
+	sym_op->m_src = ibuf;
+
+	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP) {
+		sym_op->m_dst = obuf;
+		iobuf = obuf;
+	} else {
+		sym_op->m_dst = NULL;
+		iobuf = ibuf;
+	}
+
+	/* sessionless op requires allocate xform using
+	 * rte_crypto_op_sym_xforms_alloc(), otherwise rte_zmalloc()
+	 * is used
+	 */
+	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
+		uint32_t n_xforms = 0;
+
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
+			n_xforms++;
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH)
+			n_xforms++;
+
+		if (rte_crypto_op_sym_xforms_alloc(op, n_xforms)
+			== NULL) {
+			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
+				"FAILED: %s", __LINE__, "Failed to "
+				"allocate space for crypto transforms");
+			status = TEST_FAILED;
+			goto error_exit;
+		}
+	} else {
+		cipher_xform = rte_zmalloc(NULL,
+			sizeof(struct rte_crypto_sym_xform), 0);
+
+		auth_xform = rte_zmalloc(NULL,
+			sizeof(struct rte_crypto_sym_xform), 0);
+
+		if (!cipher_xform || !auth_xform) {
+			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
+				"FAILED: %s", __LINE__, "Failed to "
+				"allocate memory for crypto transforms");
+			status = TEST_FAILED;
+			goto error_exit;
+		}
+	}
+
+	/* preparing xform, for sessioned op, init_xform is initialized
+	 * here and later as param in rte_cryptodev_sym_session_create() call
+	 */
+	if (t->op_mask == BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN) {
+		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
+			cipher_xform = op->sym->xform;
+			auth_xform = cipher_xform->next;
+			auth_xform->next = NULL;
+		} else {
+			cipher_xform->next = auth_xform;
+			auth_xform->next = NULL;
+			init_xform = cipher_xform;
+		}
+	} else if (t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC) {
+		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS) {
+			auth_xform = op->sym->xform;
+			cipher_xform = auth_xform->next;
+			cipher_xform->next = NULL;
+		} else {
+			auth_xform->next = cipher_xform;
+			cipher_xform->next = NULL;
+			init_xform = auth_xform;
+		}
+	} else if ((t->op_mask == BLOCKCIPHER_TEST_OP_ENCRYPT) ||
+			(t->op_mask == BLOCKCIPHER_TEST_OP_DECRYPT)) {
+		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
+			cipher_xform = op->sym->xform;
+		else
+			init_xform = cipher_xform;
+		cipher_xform->next = NULL;
+	} else if ((t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_GEN) ||
+			(t->op_mask == BLOCKCIPHER_TEST_OP_AUTH_VERIFY)) {
+		if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)
+			auth_xform = op->sym->xform;
+		else
+			init_xform = auth_xform;
+		auth_xform->next = NULL;
+	} else {
+		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s",
+			__LINE__, "Unrecognized operation");
+		status = TEST_FAILED;
+		goto error_exit;
+	}
+
+	/*configure xforms & sym_op cipher and auth data*/
+	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
+		cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+		cipher_xform->cipher.algo = tdata->crypto_algo;
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT)
+			cipher_xform->cipher.op =
+				RTE_CRYPTO_CIPHER_OP_ENCRYPT;
+		else
+			cipher_xform->cipher.op =
+				RTE_CRYPTO_CIPHER_OP_DECRYPT;
+		cipher_xform->cipher.key.data = cipher_key;
+		cipher_xform->cipher.key.length = tdata->cipher_key.len;
+
+		sym_op->cipher.data.offset = tdata->iv.len;
+		sym_op->cipher.data.length = tdata->ciphertext.len;
+		sym_op->cipher.iv.data = rte_pktmbuf_mtod(sym_op->m_src,
+			uint8_t *);
+		sym_op->cipher.iv.length = tdata->iv.len;
+		sym_op->cipher.iv.phys_addr = rte_pktmbuf_mtophys(
+			sym_op->m_src);
+	}
+
+	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH) {
+		uint32_t auth_data_offset = 0;
+		uint32_t digest_offset = tdata->ciphertext.len;
+
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
+			digest_offset += tdata->iv.len;
+			auth_data_offset += tdata->iv.len;
+		}
+
+		auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+		auth_xform->auth.algo = tdata->auth_algo;
+		auth_xform->auth.key.length = tdata->auth_key.len;
+		auth_xform->auth.key.data = auth_key;
+		auth_xform->auth.digest_length = digest_len;
+
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
+			auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
+			sym_op->auth.digest.data = rte_pktmbuf_mtod_offset
+				(iobuf, uint8_t *, digest_offset);
+			sym_op->auth.digest.phys_addr =
+				rte_pktmbuf_mtophys_offset(iobuf,
+					digest_offset);
+		} else {
+			auth_xform->auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
+			sym_op->auth.digest.data = rte_pktmbuf_mtod_offset
+				(sym_op->m_src, uint8_t *, digest_offset);
+			sym_op->auth.digest.phys_addr =
+				rte_pktmbuf_mtophys_offset(sym_op->m_src,
+					digest_offset);
+		}
+
+		sym_op->auth.data.offset = auth_data_offset;
+		sym_op->auth.data.length = tdata->ciphertext.len;
+		sym_op->auth.digest.length = digest_len;
+	}
+
+	/* create session for sessioned op */
+	if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) {
+		sess = rte_cryptodev_sym_session_create(dev_id,
+			init_xform);
+		if (!sess) {
+			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
+				"FAILED: %s", __LINE__,
+				"Session creation failed");
+			status = TEST_FAILED;
+			goto error_exit;
+		}
+
+		/* attach symmetric crypto session to crypto operations */
+		rte_crypto_op_attach_sym_session(op, sess);
+	}
+
+	/* Process crypto operation */
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s",
+			__LINE__, "Error sending packet for encryption");
+		status = TEST_FAILED;
+		goto error_exit;
+	}
+
+	op = NULL;
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0)
+		rte_pause();
+
+	if (!op) {
+		snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u FAILED: %s",
+			__LINE__, "Failed to process sym crypto op");
+		status = TEST_FAILED;
+		goto error_exit;
+	}
+
+	TEST_HEXDUMP(stdout, "m_src:",
+		rte_pktmbuf_mtod(sym_op->m_src, uint8_t *), buf_len);
+	if (t->feature_mask & BLOCKCIPHER_TEST_FEATURE_OOP)
+		TEST_HEXDUMP(stdout, "m_dst:",
+			rte_pktmbuf_mtod(sym_op->m_dst, uint8_t *),
+			buf_len);
+
+	/* Verify results */
+	if (op->status != RTE_CRYPTO_OP_STATUS_SUCCESS) {
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
+			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
+				"FAILED: Digest verification failed "
+				"(0x%X)", __LINE__, op->status);
+		else
+			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
+				"FAILED: Digest verification failed "
+				"(0x%X)", __LINE__, op->status);
+		status = TEST_FAILED;
+		goto error_exit;
+	}
+
+	if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER) {
+		uint8_t *crypto_res;
+		const uint8_t *compare_ref;
+		uint32_t compare_len;
+
+		crypto_res = rte_pktmbuf_mtod_offset(iobuf, uint8_t *,
+			tdata->iv.len);
+
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_ENCRYPT) {
+			compare_ref = tdata->ciphertext.data;
+			compare_len = tdata->ciphertext.len;
+		} else {
+			compare_ref = tdata->plaintext.data;
+			compare_len = tdata->plaintext.len;
+		}
+
+		if (memcmp(crypto_res, compare_ref, compare_len)) {
+			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
+				"FAILED: %s", __LINE__,
+				"Crypto data not as expected");
+			status = TEST_FAILED;
+			goto error_exit;
+		}
+	}
+
+	if (t->op_mask & BLOCKCIPHER_TEST_OP_AUTH_GEN) {
+		uint8_t *auth_res;
+
+		if (t->op_mask & BLOCKCIPHER_TEST_OP_CIPHER)
+			auth_res = rte_pktmbuf_mtod_offset(iobuf,
+				uint8_t *,
+				tdata->iv.len + tdata->ciphertext.len);
+		else
+			auth_res = rte_pktmbuf_mtod_offset(iobuf,
+				uint8_t *, tdata->ciphertext.len);
+
+		if (memcmp(auth_res, tdata->digest.data, digest_len)) {
+			snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "line %u "
+				"FAILED: %s", __LINE__, "Generated "
+				"digest data not as expected");
+			status = TEST_FAILED;
+			goto error_exit;
+		}
+	}
+
+	snprintf(test_msg, BLOCKCIPHER_TEST_MSG_LEN, "PASS");
+
+error_exit:
+	if (!(t->feature_mask & BLOCKCIPHER_TEST_FEATURE_SESSIONLESS)) {
+		if (sess)
+			rte_cryptodev_sym_session_free(dev_id, sess);
+		if (cipher_xform)
+			rte_free(cipher_xform);
+		if (auth_xform)
+			rte_free(auth_xform);
+	}
+
+	if (op)
+		rte_crypto_op_free(op);
+
+	if (obuf)
+		rte_pktmbuf_free(obuf);
+
+	if (ibuf)
+		rte_pktmbuf_free(ibuf);
+
+	return status;
+}
+
+int
+test_blockcipher_all_tests(struct rte_mempool *mbuf_pool,
+	struct rte_mempool *op_mpool,
+	uint8_t dev_id,
+	enum rte_cryptodev_type cryptodev_type,
+	enum blockcipher_test_type test_type)
+{
+	int status, overall_status = TEST_SUCCESS;
+	uint32_t i, test_index = 0;
+	char test_msg[BLOCKCIPHER_TEST_MSG_LEN + 1];
+	uint32_t n_test_cases = 0;
+	uint32_t target_pmd_mask = 0;
+	const struct blockcipher_test_case *tcs = NULL;
+
+	switch (test_type) {
+	case BLKCIPHER_AES_CHAIN_TYPE:
+		n_test_cases = sizeof(aes_chain_test_cases) /
+		sizeof(aes_chain_test_cases[0]);
+		tcs = aes_chain_test_cases;
+		break;
+	case BLKCIPHER_AES_CIPHERONLY_TYPE:
+	case BLKCIPHER_3DES_CHAIN_TYPE:
+	case BLKCIPHER_3DES_CIPHERONLY_TYPE:
+	case BLKCIPHER_AUTHONLY_TYPE:
+	default:
+		break;
+	}
+
+	switch (cryptodev_type) {
+	case RTE_CRYPTODEV_AESNI_MB_PMD:
+		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MB;
+		break;
+	case RTE_CRYPTODEV_QAT_SYM_PMD:
+		target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_QAT;
+		break;
+	default:
+		TEST_ASSERT(0, "Unrecognized cryptodev type");
+		break;
+	}
+
+	for (i = 0; i < n_test_cases; i++) {
+		const struct blockcipher_test_case *tc = &tcs[i];
+
+		if (!(tc->pmd_mask & target_pmd_mask))
+			continue;
+
+		status = test_blockcipher_one_case(tc, mbuf_pool, op_mpool,
+			dev_id, cryptodev_type, test_msg);
+
+		printf("  %u) TestCase %s %s\n", test_index ++,
+			tc->test_descr, test_msg);
+
+		if (status != TEST_SUCCESS) {
+			if (overall_status == TEST_SUCCESS)
+				overall_status = status;
+
+			if (tc->feature_mask & BLOCKCIPHER_TEST_FEATURE_STOPPER)
+				break;
+		}
+	}
+
+	return overall_status;
+}
diff --git a/app/test/test_cryptodev_blockcipher.h b/app/test/test_cryptodev_blockcipher.h
new file mode 100644
index 0000000..686e6fb
--- /dev/null
+++ b/app/test/test_cryptodev_blockcipher.h
@@ -0,0 +1,124 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *	 * Redistributions of source code must retain the above copyright
+ *	   notice, this list of conditions and the following disclaimer.
+ *	 * Redistributions in binary form must reproduce the above copyright
+ *	   notice, this list of conditions and the following disclaimer in
+ *	   the documentation and/or other materials provided with the
+ *	   distribution.
+ *	 * Neither the name of Intel Corporation nor the names of its
+ *	   contributors may be used to endorse or promote products derived
+ *	   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TEST_CRYPTODEV_BLOCKCIPHER_H_
+#define TEST_CRYPTODEV_BLOCKCIPHER_H_
+
+#ifndef BLOCKCIPHER_TEST_MSG_LEN
+#define BLOCKCIPHER_TEST_MSG_LEN		256
+#endif
+
+#define BLOCKCIPHER_TEST_OP_ENCRYPT		0x01
+#define BLOCKCIPHER_TEST_OP_DECRYPT		0x02
+#define BLOCKCIPHER_TEST_OP_AUTH_GEN	0x04
+#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY	0x08
+
+#define BLOCKCIPHER_TEST_FEATURE_OOP			0x01
+#define BLOCKCIPHER_TEST_FEATURE_SESSIONLESS	0x02
+#define BLOCKCIPHER_TEST_FEATURE_STOPPER		0x04 /* stop upon failing */
+
+#define BLOCKCIPHER_TEST_TARGET_PMD_MB			0x0001 /* Multi-buffer flag */
+#define BLOCKCIPHER_TEST_TARGET_PMD_QAT			0x0002 /* QAT flag */
+
+#define BLOCKCIPHER_TEST_OP_CIPHER		(BLOCKCIPHER_TEST_OP_ENCRYPT |		\
+					BLOCKCIPHER_TEST_OP_DECRYPT)
+
+#define BLOCKCIPHER_TEST_OP_AUTH		(BLOCKCIPHER_TEST_OP_AUTH_GEN |		\
+					BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
+
+#define BLOCKCIPHER_TEST_OP_ENC_AUTH_GEN	(BLOCKCIPHER_TEST_OP_ENCRYPT |	\
+					BLOCKCIPHER_TEST_OP_AUTH_GEN)
+
+#define BLOCKCIPHER_TEST_OP_AUTH_VERIFY_DEC	(BLOCKCIPHER_TEST_OP_DECRYPT |	\
+					BLOCKCIPHER_TEST_OP_AUTH_VERIFY)
+
+enum blockcipher_test_type {
+	BLKCIPHER_AES_CHAIN_TYPE,		/* use aes_chain_test_cases[] */
+	BLKCIPHER_AES_CIPHERONLY_TYPE,	/* use aes_cipheronly_test_cases[] */
+	BLKCIPHER_3DES_CHAIN_TYPE,		/* use triple_des_chain_test_cases[] */
+	BLKCIPHER_3DES_CIPHERONLY_TYPE,	/* triple_des_cipheronly_test_cases[] */
+	BLKCIPHER_AUTHONLY_TYPE			/* use hash_test_cases[] */
+};
+
+struct blockcipher_test_case {
+	const char *test_descr; /* test description */
+	const struct blockcipher_test_data *test_data;
+	uint8_t op_mask; /* operation mask */
+	uint8_t feature_mask;
+	uint32_t pmd_mask;
+};
+
+struct blockcipher_test_data {
+	enum rte_crypto_cipher_algorithm crypto_algo;
+
+	struct {
+		uint8_t data[64];
+		unsigned int len;
+	} cipher_key;
+
+	struct {
+		uint8_t data[64] __rte_aligned(16);
+		unsigned int len;
+	} iv;
+
+	struct {
+		const uint8_t *data;
+		unsigned int len;
+	} plaintext;
+
+	struct {
+		const uint8_t *data;
+		unsigned int len;
+	} ciphertext;
+
+	enum rte_crypto_auth_algorithm auth_algo;
+
+	struct {
+		uint8_t data[128];
+		unsigned int len;
+	} auth_key;
+
+	struct {
+		uint8_t data[128];
+		unsigned int len;		/* for qat */
+		unsigned int truncated_len;	/* for mb */
+	} digest;
+};
+
+int
+test_blockcipher_all_tests(struct rte_mempool *mbuf_pool,
+	struct rte_mempool *op_mpool,
+	uint8_t dev_id,
+	enum rte_cryptodev_type cryptodev_type,
+	enum blockcipher_test_type test_type);
+
+#endif /* TEST_CRYPTODEV_BLOCKCIPHER_H_ */
-- 
2.5.0

^ permalink raw reply related

* Re: [PATCH v2 09/12] virtio: add Rx checksum offload support
From: Maxime Coquelin @ 2016-10-03 12:51 UTC (permalink / raw)
  To: Olivier Matz, dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-10-git-send-email-olivier.matz@6wind.com>

Hi Olivier,


On 10/03/2016 11:00 AM, Olivier Matz wrote:
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
>  drivers/net/virtio/virtio_ethdev.c | 14 ++++----
>  drivers/net/virtio/virtio_ethdev.h |  2 +-
>  drivers/net/virtio/virtio_rxtx.c   | 69 ++++++++++++++++++++++++++++++++++++++
>  drivers/net/virtio/virtqueue.h     |  1 +
>  4 files changed, 78 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
> index fa56032..43cb096 100644
> --- a/drivers/net/virtio/virtio_ethdev.c
> +++ b/drivers/net/virtio/virtio_ethdev.c
> @@ -1262,7 +1262,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
>  	eth_dev->data->dev_flags = dev_flags;
>
>  	/* reset device and negotiate default features */
> -	ret = virtio_init_device(eth_dev, VIRTIO_PMD_GUEST_FEATURES);
> +	ret = virtio_init_device(eth_dev, VIRTIO_PMD_DEFAULT_GUEST_FEATURES);
>  	if (ret < 0)
>  		return ret;
>
> @@ -1351,13 +1351,10 @@ virtio_dev_configure(struct rte_eth_dev *dev)
>  	int ret;
>
>  	PMD_INIT_LOG(DEBUG, "configure");
> +	req_features = VIRTIO_PMD_DEFAULT_GUEST_FEATURES;
> +	if (rxmode->hw_ip_checksum)
> +		req_features |= (1ULL << VIRTIO_NET_F_GUEST_CSUM);
>
> -	if (rxmode->hw_ip_checksum) {
> -		PMD_DRV_LOG(ERR, "HW IP checksum not supported");
> -		return -EINVAL;
> -	}
> -
> -	req_features = VIRTIO_PMD_GUEST_FEATURES;
>  	/* if request features changed, reinit the device */
>  	if (req_features != hw->req_guest_features) {
>  		ret = virtio_init_device(dev, req_features);
> @@ -1578,6 +1575,9 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>  	dev_info->default_txconf = (struct rte_eth_txconf) {
>  		.txq_flags = ETH_TXQ_FLAGS_NOOFFLOADS
>  	};
> +	dev_info->rx_offload_capa =
> +		DEV_RX_OFFLOAD_TCP_CKSUM |
> +		DEV_RX_OFFLOAD_UDP_CKSUM;
>  }
>
>  /*
> diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
> index 5d5e788..2fc9218 100644
> --- a/drivers/net/virtio/virtio_ethdev.h
> +++ b/drivers/net/virtio/virtio_ethdev.h
> @@ -54,7 +54,7 @@
>  #define VIRTIO_MAX_RX_PKTLEN  9728
>
>  /* Features desired/implemented by this driver. */
> -#define VIRTIO_PMD_GUEST_FEATURES		\
> +#define VIRTIO_PMD_DEFAULT_GUEST_FEATURES	\
>  	(1u << VIRTIO_NET_F_MAC		  |	\
>  	 1u << VIRTIO_NET_F_STATUS	  |	\
>  	 1u << VIRTIO_NET_F_MQ		  |	\
> diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
> index 724517e..eda678a 100644
> --- a/drivers/net/virtio/virtio_rxtx.c
> +++ b/drivers/net/virtio/virtio_rxtx.c
> @@ -50,6 +50,7 @@
>  #include <rte_string_fns.h>
>  #include <rte_errno.h>
>  #include <rte_byteorder.h>
> +#include <rte_net.h>
>
>  #include "virtio_logs.h"
>  #include "virtio_ethdev.h"
> @@ -627,6 +628,56 @@ virtio_update_packet_stats(struct virtnet_stats *stats, struct rte_mbuf *mbuf)
>  	}
>  }
>
> +/* Optionally fill offload information in structure */
> +static int
> +virtio_rx_offload(struct rte_mbuf *m, struct virtio_net_hdr *hdr)
> +{
> +	struct rte_net_hdr_lens hdr_lens;
> +	uint32_t hdrlen, ptype;
> +	int l4_supported = 0;
> +
> +	/* nothing to do */
> +	if (hdr->flags == 0 && hdr->gso_type == VIRTIO_NET_HDR_GSO_NONE)
> +		return 0;
Maybe we could first check whether offload features were negotiated?
Doing this, we could return before accessing the header and so avoid a
cache miss.

Maxime

^ permalink raw reply

* [PATCH v5 1/4] libcrypto_pmd: initial implementation of SW crypto device
From: Slawomir Mrozowicz @ 2016-10-03 14:45 UTC (permalink / raw)
  To: dev; +Cc: Slawomir Mrozowicz, Michal Kobylinski, Tomasz Kulasek,
	Daniel Mrzyglod
In-Reply-To: <1475504792-31557-1-git-send-email-slawomirx.mrozowicz@intel.com>

This code provides the initial implementation of the libcrypto
poll mode driver. All cryptography operations are using Openssl
library crypto API. Each algorithm uses EVP_ interface from
openssl API - which is recommended by Openssl maintainers.

This patch adds libcrypto poll mode driver support to librte_cryptodev
library.

Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com>
Signed-off-by: Michal Kobylinski <michalx.kobylinski@intel.com>
Signed-off-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Signed-off-by: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com>
---
v2:
- add gcm crypto cipher and authentication algorithm
- rework gmac crypto authentication algorithm

v3:
- fix pmd according to negative verification tests
- change gmac aad max size
- update documentation
---
 MAINTAINERS                                        |    4 +
 config/common_base                                 |    6 +
 doc/guides/cryptodevs/index.rst                    |    1 +
 doc/guides/cryptodevs/libcrypto.rst                |  116 +++
 doc/guides/rel_notes/release_16_11.rst             |   23 +-
 drivers/crypto/Makefile                            |    1 +
 drivers/crypto/libcrypto/Makefile                  |   60 ++
 drivers/crypto/libcrypto/rte_libcrypto_pmd.c       | 1051 ++++++++++++++++++++
 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c   |  708 +++++++++++++
 .../crypto/libcrypto/rte_libcrypto_pmd_private.h   |  174 ++++
 .../crypto/libcrypto/rte_pmd_libcrypto_version.map |    3 +
 lib/librte_cryptodev/rte_cryptodev.h               |    5 +-
 mk/rte.app.mk                                      |   23 +-
 13 files changed, 2162 insertions(+), 13 deletions(-)
 create mode 100644 doc/guides/cryptodevs/libcrypto.rst
 create mode 100644 drivers/crypto/libcrypto/Makefile
 create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c
 create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c
 create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h
 create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 58a10b8..1e9d1f8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -439,6 +439,10 @@ M: Declan Doherty <declan.doherty@intel.com>
 F: drivers/crypto/null/
 F: doc/guides/cryptodevs/null.rst
 
+LibCrypto Crypto PMD
+M: Declan Doherty <declan.doherty@intel.com>
+F: drivers/crypto/libcrypto/
+F: doc/guides/cryptodevs/libcrypto.rst
 
 Packet processing
 -----------------
diff --git a/config/common_base b/config/common_base
index 3a412ee..87b8646 100644
--- a/config/common_base
+++ b/config/common_base
@@ -376,6 +376,12 @@ CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n
 CONFIG_RTE_LIBRTE_PMD_AESNI_MB_DEBUG=n
 
 #
+# Compile PMD for Software backed device
+#
+CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO=n
+CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO_DEBUG=n
+
+#
 # Compile PMD for AESNI GCM device
 #
 CONFIG_RTE_LIBRTE_PMD_AESNI_GCM=n
diff --git a/doc/guides/cryptodevs/index.rst b/doc/guides/cryptodevs/index.rst
index 906f1b4..bae8e53 100644
--- a/doc/guides/cryptodevs/index.rst
+++ b/doc/guides/cryptodevs/index.rst
@@ -39,6 +39,7 @@ Crypto Device Drivers
     aesni_mb
     aesni_gcm
     kasumi
+    libcrypto
     null
     snow3g
     qat
diff --git a/doc/guides/cryptodevs/libcrypto.rst b/doc/guides/cryptodevs/libcrypto.rst
new file mode 100644
index 0000000..77eff95
--- /dev/null
+++ b/doc/guides/cryptodevs/libcrypto.rst
@@ -0,0 +1,116 @@
+..  BSD LICENSE
+    Copyright(c) 2016 Intel Corporation. All rights reserved.
+
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+
+    * Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in
+    the documentation and/or other materials provided with the
+    distribution.
+    * Neither the name of Intel Corporation nor the names of its
+    contributors may be used to endorse or promote products derived
+    from this software without specific prior written permission.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+LibCrypto Crypto Poll Mode Driver
+
+This code provides the initial implementation of the libcrypto poll mode
+driver. All cryptography operations are using Openssl library crypto API.
+Each algorithm uses EVP_ interface from openssl API - which is recommended
+by Openssl maintainers.
+
+For more details about openssl library please visit openssl webpage:
+https://www.openssl.org/
+
+Features
+--------
+
+LibCrypto PMD has support for:
+
+Supported cipher algorithms:
+* ``RTE_CRYPTO_CIPHER_3DES_CBC``
+* ``RTE_CRYPTO_CIPHER_AES_CBC``
+* ``RTE_CRYPTO_CIPHER_AES_CTR``
+* ``RTE_CRYPTO_CIPHER_3DES_CTR``
+* ``RTE_CRYPTO_CIPHER_AES_GCM``
+
+Supported authentication algorithms:
+* ``RTE_CRYPTO_AUTH_AES_GMAC``
+* ``RTE_CRYPTO_AUTH_MD5``
+* ``RTE_CRYPTO_AUTH_SHA1``
+* ``RTE_CRYPTO_AUTH_SHA224``
+* ``RTE_CRYPTO_AUTH_SHA256``
+* ``RTE_CRYPTO_AUTH_SHA384``
+* ``RTE_CRYPTO_AUTH_SHA512``
+* ``RTE_CRYPTO_AUTH_MD5_HMAC``
+* ``RTE_CRYPTO_AUTH_SHA1_HMAC``
+* ``RTE_CRYPTO_AUTH_SHA224_HMAC``
+* ``RTE_CRYPTO_AUTH_SHA256_HMAC``
+* ``RTE_CRYPTO_AUTH_SHA384_HMAC``
+* ``RTE_CRYPTO_AUTH_SHA512_HMAC``
+
+
+Installation
+------------
+
+To compile libcrypto PMD, it has to be enabled in the config/common_base file
+and appropriate openssl packages have to be installed in the build environment.
+
+The newest openssl library version is supported:
+* 1.0.2h-fips  3 May 2016.
+Older versions that were also verified:
+* 1.0.1f 6 Jan 2014
+* 1.0.1 14 Mar 2012
+
+For Ubuntu 14.04 LTS these packages have to be installed in the build system:
+sudo apt-get install openssl
+sudo apt-get install libc6-dev-i386 (for i686-native-linuxapp-gcc target)
+
+This code was also verified on Fedora 24.
+This code was NOT yet verified on FreeBSD.
+
+Initialization
+--------------
+
+User can use app/test application to check how to use this pmd and to verify
+crypto processing.
+
+Test name is cryptodev_libcrypto_autotest.
+For performance test cryptodev_libcrypto_perftest can be used.
+
+To verify real traffic l2fwd-crypto example can be used with this command:
+
+.. code-block:: console
+
+sudo ./build/l2fwd-crypto -c 0x3 -n 4 --vdev "cryptodev_libcrypto_pmd"
+--vdev "cryptodev_libcrypto_pmd"-- -p 0x3 --chain CIPHER_HASH
+--cipher_op ENCRYPT --cipher_algo AES_CBC
+--cipher_key 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f
+--iv 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:ff
+--auth_op GENERATE --auth_algo SHA1_HMAC
+--auth_key 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
+:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
+:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11
+
+Limitations
+-----------
+
+* Maximum number of sessions is 2048.
+* Chained mbufs are not supported.
+* Hash only is not supported for GCM and GMAC.
+* Cipher only is not supported for GCM and GMAC.
diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst
index cc507a9..6e92966 100644
--- a/doc/guides/rel_notes/release_16_11.rst
+++ b/doc/guides/rel_notes/release_16_11.rst
@@ -34,7 +34,28 @@ New Features
 
      Refer to the previous release notes for examples.
 
-     This section is a comment. Make sure to start the actual text at the margin.
+* **Added libcrypto PMD.**
+
+  A new crypto PMD has been added, which provides several ciphering and hashing.
+  All cryptography operations are using Openssl library crypto API.
+
+* ** Added support of C3xxx Device in QAT PMD.**
+  Support for Device c3xxx has been enabled in QAT PMD.
+
+* ** Added support of C62XX Device in QAT PMD.**
+  Support for Device c62xx has been enabled in QAT PMD.
+
+
+* **Updated the QAT PMD.**
+  The QAT PMD was updated with changes including the following:
+
+  * Added support for MD5_HMAC algorithm.
+  * Added support for SHA224-HMAC algorithm.
+  * Added support for SHA384-HMAC algorithm.
+  * Added support for NULL algorithm.
+  * Added support for KASUMI (F8 and F9) algorithm.
+  * Added support for GMAC algorithm.
+  * Added support for 3DES block cipher algorithm.
 
 * ** Added support of C3xxx Device in QAT PMD.**
   Support for Device c3xxx has been enabled in QAT PMD.
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 17d74fc..b452ea6 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -33,6 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += aesni_gcm
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += aesni_mb
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += libcrypto
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += qat
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += snow3g
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += kasumi
diff --git a/drivers/crypto/libcrypto/Makefile b/drivers/crypto/libcrypto/Makefile
new file mode 100644
index 0000000..c5f8cf2
--- /dev/null
+++ b/drivers/crypto/libcrypto/Makefile
@@ -0,0 +1,60 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2016 Intel Corporation. All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in
+#       the documentation and/or other materials provided with the
+#       distribution.
+#     * Neither the name of Intel Corporation nor the names of its
+#       contributors may be used to endorse or promote products derived
+#       from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# library name
+LIB = librte_pmd_libcrypto.a
+
+# build flags
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# library version
+LIBABIVER := 1
+
+# versioning export map
+EXPORT_MAP := rte_pmd_libcrypto_version.map
+
+# external library dependencies
+LDLIBS += -lcrypto
+
+# library source files
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += rte_libcrypto_pmd_ops.c
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_mempool
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_ring
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO) += lib/librte_cryptodev
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c
new file mode 100644
index 0000000..d9a60d0
--- /dev/null
+++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c
@@ -0,0 +1,1051 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rte_common.h>
+#include <rte_hexdump.h>
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
+#include <rte_dev.h>
+#include <rte_malloc.h>
+#include <rte_cpuflags.h>
+
+#include <openssl/evp.h>
+
+#include "rte_libcrypto_pmd_private.h"
+
+static int cryptodev_libcrypto_uninit(const char *name);
+
+/*----------------------------------------------------------------------------*/
+
+/**
+ * Global static parameter used to create a unique name for each
+ * LIBCRYPTO crypto device.
+ */
+static unsigned int unique_name_id;
+
+static inline int
+create_unique_device_name(char *name, size_t size)
+{
+	int ret;
+
+	if (name == NULL)
+		return -EINVAL;
+
+	ret = snprintf(name, size, "%s_%u", RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD),
+			unique_name_id++);
+	if (ret < 0)
+		return ret;
+	return 0;
+}
+
+/**
+ * Increment counter by 1
+ * Counter is 64 bit array, big-endian
+ */
+static void
+ctr_inc(uint8_t *ctr)
+{
+	uint64_t *ctr64 = (uint64_t *)ctr;
+
+	*ctr64 = __builtin_bswap64(*ctr64);
+	(*ctr64)++;
+	*ctr64 = __builtin_bswap64(*ctr64);
+}
+
+/*
+ *------------------------------------------------------------------------------
+ * Session Prepare
+ *------------------------------------------------------------------------------
+ */
+
+/** Get xform chain order */
+static enum libcrypto_chain_order
+libcrypto_get_chain_order(const struct rte_crypto_sym_xform *xform)
+{
+	enum libcrypto_chain_order res = LIBCRYPTO_CHAIN_NOT_SUPPORTED;
+
+	if (xform != NULL) {
+		if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
+			if (xform->next == NULL)
+				res =  LIBCRYPTO_CHAIN_ONLY_AUTH;
+			else if (xform->next->type ==
+					RTE_CRYPTO_SYM_XFORM_CIPHER)
+				res =  LIBCRYPTO_CHAIN_AUTH_CIPHER;
+		}
+		if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
+			if (xform->next == NULL)
+				res =  LIBCRYPTO_CHAIN_ONLY_CIPHER;
+			else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
+				res =  LIBCRYPTO_CHAIN_CIPHER_AUTH;
+		}
+	}
+
+	return res;
+}
+
+/** Get session cipher key from input cipher key */
+static void
+get_cipher_key(uint8_t *input_key, int keylen, uint8_t *session_key)
+{
+	memcpy(session_key, input_key, keylen);
+}
+
+/** Get key ede 24 bytes standard from input key */
+static int
+get_cipher_key_ede(uint8_t *key, int keylen, uint8_t *key_ede)
+{
+	int res = 0;
+
+	/* Initialize keys - 24 bytes: [key1-key2-key3] */
+	switch (keylen) {
+	case 24:
+		memcpy(key_ede, key, 24);
+		break;
+	case 16:
+		/* K3 = K1 */
+		memcpy(key_ede, key, 16);
+		memcpy(key_ede + 16, key, 8);
+		break;
+	case 8:
+		/* K1 = K2 = K3 (DES compatibility) */
+		memcpy(key_ede, key, 8);
+		memcpy(key_ede + 8, key, 8);
+		memcpy(key_ede + 16, key, 8);
+		break;
+	default:
+		LIBCRYPTO_LOG_ERR("Unsupported key size");
+		res = -EINVAL;
+	}
+
+	return res;
+}
+
+/** Get adequate libcrypto function for input cipher algorithm */
+static uint8_t
+get_cipher_algo(enum rte_crypto_cipher_algorithm sess_algo, size_t keylen,
+		const EVP_CIPHER **algo)
+{
+	int res = 0;
+
+	if (algo != NULL) {
+		switch (sess_algo) {
+		case RTE_CRYPTO_CIPHER_3DES_CBC:
+			switch (keylen) {
+			case 16:
+				*algo = EVP_des_ede_cbc();
+				break;
+			case 24:
+				*algo = EVP_des_ede3_cbc();
+				break;
+			default:
+				res = -EINVAL;
+			}
+			break;
+		case RTE_CRYPTO_CIPHER_3DES_CTR:
+			break;
+		case RTE_CRYPTO_CIPHER_AES_CBC:
+			switch (keylen) {
+			case 16:
+				*algo = EVP_aes_128_cbc();
+				break;
+			case 24:
+				*algo = EVP_aes_192_cbc();
+				break;
+			case 32:
+				*algo = EVP_aes_256_cbc();
+				break;
+			default:
+				res = -EINVAL;
+			}
+			break;
+		case RTE_CRYPTO_CIPHER_AES_CTR:
+			switch (keylen) {
+			case 16:
+				*algo = EVP_aes_128_ctr();
+				break;
+			case 24:
+				*algo = EVP_aes_192_ctr();
+				break;
+			case 32:
+				*algo = EVP_aes_256_ctr();
+				break;
+			default:
+				res = -EINVAL;
+			}
+			break;
+		case RTE_CRYPTO_CIPHER_AES_GCM:
+			switch (keylen) {
+			case 16:
+				*algo = EVP_aes_128_gcm();
+				break;
+			case 24:
+				*algo = EVP_aes_192_gcm();
+				break;
+			case 32:
+				*algo = EVP_aes_256_gcm();
+				break;
+			default:
+				res = -EINVAL;
+			}
+			break;
+		default:
+			res = -EINVAL;
+			break;
+		}
+	} else {
+		res = -EINVAL;
+	}
+
+	return res;
+}
+
+/** Get adequate libcrypto function for input auth algorithm */
+static uint8_t
+get_auth_algo(enum rte_crypto_auth_algorithm sessalgo,
+		const EVP_MD **algo)
+{
+	int res = 0;
+
+	if (algo != NULL) {
+		switch (sessalgo) {
+		case RTE_CRYPTO_AUTH_MD5:
+		case RTE_CRYPTO_AUTH_MD5_HMAC:
+			*algo = EVP_md5();
+			break;
+		case RTE_CRYPTO_AUTH_SHA1:
+		case RTE_CRYPTO_AUTH_SHA1_HMAC:
+			*algo = EVP_sha1();
+			break;
+		case RTE_CRYPTO_AUTH_SHA224:
+		case RTE_CRYPTO_AUTH_SHA224_HMAC:
+			*algo = EVP_sha224();
+			break;
+		case RTE_CRYPTO_AUTH_SHA256:
+		case RTE_CRYPTO_AUTH_SHA256_HMAC:
+			*algo = EVP_sha256();
+			break;
+		case RTE_CRYPTO_AUTH_SHA384:
+		case RTE_CRYPTO_AUTH_SHA384_HMAC:
+			*algo = EVP_sha384();
+			break;
+		case RTE_CRYPTO_AUTH_SHA512:
+		case RTE_CRYPTO_AUTH_SHA512_HMAC:
+			*algo = EVP_sha512();
+			break;
+		default:
+			res = -EINVAL;
+			break;
+		}
+	} else {
+		res = -EINVAL;
+	}
+
+	return res;
+}
+
+/** Set session cipher parameters */
+static int
+libcrypto_set_session_cipher_parameters(struct libcrypto_session *sess,
+		const struct rte_crypto_sym_xform *xform)
+{
+	/* Select cipher direction */
+	sess->cipher.direction = xform->cipher.op;
+	/* Select cipher key */
+	sess->cipher.key.length = xform->cipher.key.length;
+
+	/* Select cipher algo */
+	switch (xform->cipher.algo) {
+	case RTE_CRYPTO_CIPHER_3DES_CBC:
+	case RTE_CRYPTO_CIPHER_AES_CBC:
+	case RTE_CRYPTO_CIPHER_AES_CTR:
+	case RTE_CRYPTO_CIPHER_AES_GCM:
+		sess->cipher.mode = LIBCRYPTO_CIPHER_LIB;
+		sess->cipher.algo = xform->cipher.algo;
+		sess->cipher.ctx = EVP_CIPHER_CTX_new();
+
+		if (get_cipher_algo(sess->cipher.algo, sess->cipher.key.length,
+				&sess->cipher.evp_algo) != 0)
+			return -EINVAL;
+
+		get_cipher_key(xform->cipher.key.data, sess->cipher.key.length,
+			sess->cipher.key.data);
+
+		break;
+
+	case RTE_CRYPTO_CIPHER_3DES_CTR:
+		sess->cipher.mode = LIBCRYPTO_CIPHER_DES3CTR;
+		sess->cipher.ctx = EVP_CIPHER_CTX_new();
+
+		if (get_cipher_key_ede(xform->cipher.key.data,
+				sess->cipher.key.length, sess->cipher.key.data) != 0)
+			return -EINVAL;
+		break;
+
+	default:
+		sess->cipher.algo = RTE_CRYPTO_CIPHER_NULL;
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/* Set session auth parameters */
+static int
+libcrypto_set_session_auth_parameters(struct libcrypto_session *sess,
+		const struct rte_crypto_sym_xform *xform)
+{
+	/* Select auth generate/verify */
+	sess->auth.operation = xform->auth.op;
+	sess->auth.algo = xform->auth.algo;
+
+	/* Select auth algo */
+	switch (xform->auth.algo) {
+	case RTE_CRYPTO_AUTH_AES_GMAC:
+	case RTE_CRYPTO_AUTH_AES_GCM:
+		/* Check additional condition for AES_GMAC/GCM */
+		if (sess->cipher.algo != RTE_CRYPTO_CIPHER_AES_GCM)
+			return -EINVAL;
+		sess->chain_order = LIBCRYPTO_CHAIN_COMBINED;
+		break;
+
+	case RTE_CRYPTO_AUTH_MD5:
+	case RTE_CRYPTO_AUTH_SHA1:
+	case RTE_CRYPTO_AUTH_SHA224:
+	case RTE_CRYPTO_AUTH_SHA256:
+	case RTE_CRYPTO_AUTH_SHA384:
+	case RTE_CRYPTO_AUTH_SHA512:
+		sess->auth.mode = LIBCRYPTO_AUTH_AS_AUTH;
+		if (get_auth_algo(xform->auth.algo, &sess->auth.auth.evp_algo) != 0)
+			return -EINVAL;
+		sess->auth.auth.ctx = EVP_MD_CTX_create();
+		break;
+
+	case RTE_CRYPTO_AUTH_MD5_HMAC:
+	case RTE_CRYPTO_AUTH_SHA1_HMAC:
+	case RTE_CRYPTO_AUTH_SHA224_HMAC:
+	case RTE_CRYPTO_AUTH_SHA256_HMAC:
+	case RTE_CRYPTO_AUTH_SHA384_HMAC:
+	case RTE_CRYPTO_AUTH_SHA512_HMAC:
+		sess->auth.mode = LIBCRYPTO_AUTH_AS_HMAC;
+		sess->auth.hmac.ctx = EVP_MD_CTX_create();
+		if (get_auth_algo(xform->auth.algo, &sess->auth.hmac.evp_algo) != 0)
+			return -EINVAL;
+		sess->auth.hmac.pkey = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
+				xform->auth.key.data, xform->auth.key.length);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/** Parse crypto xform chain and set private session parameters */
+int
+libcrypto_set_session_parameters(struct libcrypto_session *sess,
+		const struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_crypto_sym_xform *cipher_xform = NULL;
+	const struct rte_crypto_sym_xform *auth_xform = NULL;
+
+	sess->chain_order = libcrypto_get_chain_order(xform);
+	switch (sess->chain_order) {
+	case LIBCRYPTO_CHAIN_ONLY_CIPHER:
+		cipher_xform = xform;
+		break;
+	case LIBCRYPTO_CHAIN_ONLY_AUTH:
+		auth_xform = xform;
+		break;
+	case LIBCRYPTO_CHAIN_CIPHER_AUTH:
+		cipher_xform = xform;
+		auth_xform = xform->next;
+		break;
+	case LIBCRYPTO_CHAIN_AUTH_CIPHER:
+		auth_xform = xform;
+		cipher_xform = xform->next;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* cipher_xform must be check before auth_xform */
+	if (cipher_xform) {
+		if (libcrypto_set_session_cipher_parameters(sess, cipher_xform)) {
+			LIBCRYPTO_LOG_ERR(
+				"Invalid/unsupported cipher parameters");
+			return -EINVAL;
+		}
+	}
+
+	if (auth_xform) {
+		if (libcrypto_set_session_auth_parameters(sess, auth_xform)) {
+			LIBCRYPTO_LOG_ERR(
+				"Invalid/unsupported auth parameters");
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
+/** Reset private session parameters */
+void
+libcrypto_reset_session(struct libcrypto_session *sess)
+{
+	EVP_CIPHER_CTX_free(sess->cipher.ctx);
+
+	switch (sess->auth.mode) {
+	case LIBCRYPTO_AUTH_AS_AUTH:
+		EVP_MD_CTX_destroy(sess->auth.auth.ctx);
+		break;
+	case LIBCRYPTO_AUTH_AS_HMAC:
+		EVP_PKEY_free(sess->auth.hmac.pkey);
+		EVP_MD_CTX_destroy(sess->auth.hmac.ctx);
+		break;
+	default:
+		break;
+	}
+}
+
+/** Provide session for operation */
+static struct libcrypto_session *
+get_session(struct libcrypto_qp *qp, struct rte_crypto_op *op)
+{
+	struct libcrypto_session *sess = NULL;
+
+	if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_WITH_SESSION) {
+		/* get existing session */
+		if (likely(op->sym->session != NULL &&
+				op->sym->session->dev_type ==
+				RTE_CRYPTODEV_LIBCRYPTO_PMD))
+			sess = (struct libcrypto_session *)
+				op->sym->session->_private;
+	} else  {
+		/* provide internal session */
+		void *_sess = NULL;
+
+		if (!rte_mempool_get(qp->sess_mp, (void **)&_sess)) {
+			sess = (struct libcrypto_session *)
+				((struct rte_cryptodev_sym_session *)_sess)
+				->_private;
+
+			if (unlikely(libcrypto_set_session_parameters(
+					sess, op->sym->xform) != 0)) {
+				rte_mempool_put(qp->sess_mp, _sess);
+				sess = NULL;
+			} else
+				op->sym->session = _sess;
+		}
+	}
+
+	if (sess == NULL)
+		op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
+
+	return sess;
+}
+
+/*
+ *------------------------------------------------------------------------------
+ * Process Operations
+ *------------------------------------------------------------------------------
+ */
+
+/** Process standard libcrypto cipher encryption */
+static int
+process_libcrypto_cipher_encrypt(uint8_t *src, uint8_t *dst,
+		uint8_t *iv, uint8_t *key, int srclen,
+		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
+{
+	int dstlen, totlen;
+
+	if (EVP_EncryptInit_ex(ctx, algo, NULL, key, iv) <= 0)
+		goto process_cipher_encrypt_err;
+
+	if (EVP_EncryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0)
+		goto process_cipher_encrypt_err;
+
+	if (EVP_EncryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0)
+		goto process_cipher_encrypt_err;
+
+	return 0;
+
+process_cipher_encrypt_err:
+	LIBCRYPTO_LOG_ERR("Process libcrypto cipher encrypt failed");
+	return -EINVAL;
+}
+
+/** Process standard libcrypto cipher decryption */
+static int
+process_libcrypto_cipher_decrypt(uint8_t *src, uint8_t *dst,
+		uint8_t *iv, uint8_t *key, int srclen,
+		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
+{
+	int dstlen, totlen;
+
+	if (EVP_DecryptInit_ex(ctx, algo, NULL, key, iv) <= 0)
+		goto process_cipher_decrypt_err;
+
+	if (EVP_CIPHER_CTX_set_padding(ctx, 0) <= 0)
+		goto process_cipher_decrypt_err;
+
+	if (EVP_DecryptUpdate(ctx, dst, &dstlen, src, srclen) <= 0)
+		goto process_cipher_decrypt_err;
+
+	if (EVP_DecryptFinal_ex(ctx, dst + dstlen, &totlen) <= 0)
+		goto process_cipher_decrypt_err;
+
+	return 0;
+
+process_cipher_decrypt_err:
+	LIBCRYPTO_LOG_ERR("Process libcrypto cipher decrypt failed");
+	return -EINVAL;
+}
+
+/** Process cipher des 3 ctr encryption, decryption algorithm */
+static int
+process_libcrypto_cipher_des3ctr(uint8_t *src, uint8_t *dst,
+		uint8_t *iv, uint8_t *key, int srclen, EVP_CIPHER_CTX *ctx)
+{
+	uint8_t ebuf[8], ctr[8];
+	int unused, n;
+
+	/* We use 3DES encryption also for decryption.
+	 * IV is not important for 3DES ecb
+	 */
+	if (EVP_EncryptInit_ex(ctx, EVP_des_ede3_ecb(), NULL, key, NULL) <= 0)
+		goto process_cipher_des3ctr_err;
+
+	memcpy(ctr, iv, 8);
+	n = 0;
+
+	while (n < srclen) {
+		if (n % 8 == 0) {
+			if (EVP_EncryptUpdate(ctx, (unsigned char *)&ebuf, &unused,
+					(const unsigned char *)&ctr, 8) <= 0)
+				goto process_cipher_des3ctr_err;
+			ctr_inc(ctr);
+		}
+		dst[n] = src[n] ^ ebuf[n % 8];
+		n++;
+	}
+
+	return 0;
+
+process_cipher_des3ctr_err:
+	LIBCRYPTO_LOG_ERR("Process libcrypto cipher des 3 ede ctr failed");
+	return -EINVAL;
+}
+
+/** Process auth/encription aes-gcm algorithm */
+static int
+process_libcrypto_auth_encryption_gcm(uint8_t *src, int srclen,
+		uint8_t *aad, int aadlen, uint8_t *iv, int ivlen,
+		uint8_t *key, uint8_t *dst,	uint8_t *tag,
+		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
+{
+	int len = 0, unused = 0;
+	uint8_t empty[] = {};
+
+	if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0)
+		goto process_auth_encryption_gcm_err;
+
+	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0)
+		goto process_auth_encryption_gcm_err;
+
+	if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0)
+		goto process_auth_encryption_gcm_err;
+
+	if (aadlen > 0) {
+		if (EVP_EncryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0)
+			goto process_auth_encryption_gcm_err;
+
+		/* Workaround open ssl bug in version less then 1.0.1f */
+		if (EVP_EncryptUpdate(ctx, empty, &unused, empty, 0) <= 0)
+			goto process_auth_encryption_gcm_err;
+	}
+
+	if (srclen > 0)
+		if (EVP_EncryptUpdate(ctx, dst, &len, src, srclen) <= 0)
+			goto process_auth_encryption_gcm_err;
+
+	if (EVP_EncryptFinal_ex(ctx, dst + len, &len) <= 0)
+		goto process_auth_encryption_gcm_err;
+
+	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, tag) <= 0)
+		goto process_auth_encryption_gcm_err;
+
+	return 0;
+
+process_auth_encryption_gcm_err:
+	LIBCRYPTO_LOG_ERR("Process libcrypto auth encryption gcm failed");
+	return -EINVAL;
+}
+
+static int
+process_libcrypto_auth_decryption_gcm(uint8_t *src, int srclen,
+		uint8_t *aad, int aadlen, uint8_t *iv, int ivlen,
+		uint8_t *key, uint8_t *dst, uint8_t *tag,
+		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
+{
+	int len = 0, unused = 0;
+	uint8_t empty[] = {};
+
+	if (EVP_DecryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0)
+		goto process_auth_decryption_gcm_err;
+
+	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0)
+		goto process_auth_decryption_gcm_err;
+
+	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, tag) <= 0)
+		goto process_auth_decryption_gcm_err;
+
+	if (EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv) <= 0)
+		goto process_auth_decryption_gcm_err;
+
+	if (aadlen > 0) {
+		if (EVP_DecryptUpdate(ctx, NULL, &len, aad, aadlen) <= 0)
+			goto process_auth_decryption_gcm_err;
+
+		/* Workaround open ssl bug in version less then 1.0.1f */
+		if (EVP_DecryptUpdate(ctx, empty, &unused, empty, 0) <= 0)
+			goto process_auth_decryption_gcm_err;
+	}
+
+	if (srclen > 0)
+		if (EVP_DecryptUpdate(ctx, dst, &len, src, srclen) <= 0)
+			goto process_auth_decryption_gcm_err;
+
+	if (EVP_DecryptFinal_ex(ctx, dst + len, &len) <= 0)
+		goto process_auth_decryption_gcm_final_err;
+
+	return 0;
+
+process_auth_decryption_gcm_err:
+	LIBCRYPTO_LOG_ERR("Process libcrypto auth decription gcm failed");
+	return -EINVAL;
+
+process_auth_decryption_gcm_final_err:
+	return -EFAULT;
+}
+
+/** Process standard libcrypto auth algorithms */
+static int
+process_libcrypto_auth(uint8_t *src, uint8_t *dst,
+		__rte_unused uint8_t *iv, __rte_unused EVP_PKEY * pkey,
+		int srclen, EVP_MD_CTX *ctx, const EVP_MD *algo)
+{
+	size_t dstlen;
+
+	if (EVP_DigestInit_ex(ctx, algo, NULL) <= 0)
+		goto process_auth_err;
+
+	if (EVP_DigestUpdate(ctx, (char *)src, srclen) <= 0)
+		goto process_auth_err;
+
+	if (EVP_DigestFinal_ex(ctx, dst, (unsigned int *)&dstlen) <= 0)
+		goto process_auth_err;
+
+	return 0;
+
+process_auth_err:
+	LIBCRYPTO_LOG_ERR("Process libcrypto auth failed");
+	return -EINVAL;
+}
+
+/** Process standard libcrypto auth algorithms with hmac */
+static int
+process_libcrypto_auth_hmac(uint8_t *src, uint8_t *dst,
+		__rte_unused uint8_t *iv, EVP_PKEY *pkey,
+		int srclen,	EVP_MD_CTX *ctx, const EVP_MD *algo)
+{
+	size_t dstlen;
+
+	if (EVP_DigestSignInit(ctx, NULL, algo, NULL, pkey) <= 0)
+		goto process_auth_err;
+
+	if (EVP_DigestSignUpdate(ctx, (char *)src, srclen) <= 0)
+		goto process_auth_err;
+
+	if (EVP_DigestSignFinal(ctx, dst, &dstlen) <= 0)
+		goto process_auth_err;
+
+	return 0;
+
+process_auth_err:
+	LIBCRYPTO_LOG_ERR("Process libcrypto auth failed");
+	return -EINVAL;
+}
+
+/*----------------------------------------------------------------------------*/
+
+/** Process auth/cipher combined operation */
+static void
+process_libcrypto_combined_op
+		(struct rte_crypto_op *op, struct libcrypto_session *sess,
+		struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
+{
+	/* cipher */
+	uint8_t *src = NULL, *dst = NULL, *iv, *tag, *aad;
+	int srclen, ivlen, aadlen, status = -1;
+
+	iv = op->sym->cipher.iv.data;
+	ivlen = op->sym->cipher.iv.length;
+	aad = op->sym->auth.aad.data;
+	aadlen = op->sym->auth.aad.length;
+
+	tag = op->sym->auth.digest.data;
+	if (tag == NULL)
+		tag = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
+				op->sym->cipher.data.offset +
+				op->sym->cipher.data.length);
+
+	if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC)
+		srclen = 0;
+	else {
+		srclen = op->sym->cipher.data.length;
+		src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
+				op->sym->cipher.data.offset);
+		dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
+				op->sym->cipher.data.offset);
+	}
+
+	if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+		status = process_libcrypto_auth_encryption_gcm(
+				src, srclen, aad, aadlen, iv, ivlen,
+				sess->cipher.key.data, dst, tag,
+				sess->cipher.ctx, sess->cipher.evp_algo);
+	else
+		status = process_libcrypto_auth_decryption_gcm(
+				src, srclen, aad, aadlen, iv, ivlen,
+				sess->cipher.key.data, dst, tag,
+				sess->cipher.ctx, sess->cipher.evp_algo);
+
+	if (status != 0) {
+		if (status == (-EFAULT) &&
+				sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY)
+			op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
+		else
+			op->status = RTE_CRYPTO_OP_STATUS_ERROR;
+	}
+}
+
+/** Process cipher operation */
+static void
+process_libcrypto_cipher_op
+		(struct rte_crypto_op *op, struct libcrypto_session *sess,
+		struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
+{
+	uint8_t *src, *dst, *iv;
+	int srclen, status;
+
+	srclen = op->sym->cipher.data.length;
+	src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
+			op->sym->cipher.data.offset);
+	dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
+			op->sym->cipher.data.offset);
+
+	iv = op->sym->cipher.iv.data;
+
+	if (sess->cipher.mode == LIBCRYPTO_CIPHER_LIB)
+		if (sess->cipher.direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+			status = process_libcrypto_cipher_encrypt(src, dst, iv,
+					sess->cipher.key.data, srclen,
+					sess->cipher.ctx, sess->cipher.evp_algo);
+		else
+			status = process_libcrypto_cipher_decrypt(src, dst, iv,
+					sess->cipher.key.data, srclen,
+					sess->cipher.ctx, sess->cipher.evp_algo);
+	else
+		status = process_libcrypto_cipher_des3ctr(src, dst, iv,
+				sess->cipher.key.data, srclen, sess->cipher.ctx);
+
+	if (status != 0)
+		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
+}
+
+/** Process auth operation */
+static void
+process_libcrypto_auth_op
+		(struct rte_crypto_op *op, struct libcrypto_session *sess,
+		struct rte_mbuf *mbuf_src, struct rte_mbuf *mbuf_dst)
+{
+	uint8_t *src, *dst;
+	int srclen, status;
+
+	srclen = op->sym->auth.data.length;
+	src = rte_pktmbuf_mtod_offset(mbuf_src, uint8_t *,
+			op->sym->auth.data.offset);
+
+	if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY)
+		dst = (uint8_t *)rte_pktmbuf_append(mbuf_src,
+				op->sym->auth.digest.length);
+	else {
+		dst = op->sym->auth.digest.data;
+		if (dst == NULL)
+			dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
+					op->sym->auth.data.offset +
+					op->sym->auth.data.length);
+	}
+
+	switch (sess->auth.mode) {
+	case LIBCRYPTO_AUTH_AS_AUTH:
+		status = process_libcrypto_auth(src, dst,
+				NULL, NULL,	srclen,
+				sess->auth.auth.ctx, sess->auth.auth.evp_algo);
+		break;
+	case LIBCRYPTO_AUTH_AS_HMAC:
+		status = process_libcrypto_auth_hmac(src, dst,
+				NULL, sess->auth.hmac.pkey, srclen,
+				sess->auth.hmac.ctx, sess->auth.hmac.evp_algo);
+		break;
+	default:
+		status = -1;
+		break;
+	}
+
+	if (sess->auth.operation == RTE_CRYPTO_AUTH_OP_VERIFY) {
+		if (memcmp(dst, op->sym->auth.digest.data,
+				op->sym->auth.digest.length) != 0) {
+			op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
+		}
+		/* Trim area used for digest from mbuf. */
+		rte_pktmbuf_trim(mbuf_src,
+				op->sym->auth.digest.length);
+	}
+
+	if (status != 0)
+		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
+}
+
+/** Process crypto operation for mbuf */
+static int
+process_op(const struct libcrypto_qp *qp, struct rte_crypto_op *op,
+		struct libcrypto_session *sess)
+{
+	struct rte_mbuf *msrc, *mdst;
+	int retval;
+
+	msrc = op->sym->m_src;
+	mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
+
+	op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
+
+	switch (sess->chain_order) {
+	case LIBCRYPTO_CHAIN_ONLY_CIPHER:
+		process_libcrypto_cipher_op(op, sess, msrc, mdst);
+		break;
+	case LIBCRYPTO_CHAIN_ONLY_AUTH:
+		process_libcrypto_auth_op(op, sess, msrc, mdst);
+		break;
+	case LIBCRYPTO_CHAIN_CIPHER_AUTH:
+		process_libcrypto_cipher_op(op, sess, msrc, mdst);
+		process_libcrypto_auth_op(op, sess, mdst, mdst);
+		break;
+	case LIBCRYPTO_CHAIN_AUTH_CIPHER:
+		process_libcrypto_auth_op(op, sess, msrc, mdst);
+		process_libcrypto_cipher_op(op, sess, msrc, mdst);
+		break;
+	case LIBCRYPTO_CHAIN_COMBINED:
+		process_libcrypto_combined_op(op, sess, msrc, mdst);
+		break;
+	default:
+		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
+		break;
+	}
+
+	/* Free session if a session-less crypto op */
+	if (op->sym->sess_type == RTE_CRYPTO_SYM_OP_SESSIONLESS) {
+		libcrypto_reset_session(sess);
+		memset(sess, 0, sizeof(struct libcrypto_session));
+		rte_mempool_put(qp->sess_mp, op->sym->session);
+		op->sym->session = NULL;
+	}
+
+
+	if (op->status == RTE_CRYPTO_OP_STATUS_NOT_PROCESSED)
+		op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+
+	if (op->status != RTE_CRYPTO_OP_STATUS_ERROR)
+		retval = rte_ring_enqueue(qp->processed_ops, (void *)op);
+	else
+		retval = -1;
+
+	return retval;
+}
+
+/*
+ *------------------------------------------------------------------------------
+ * PMD Framework
+ *------------------------------------------------------------------------------
+ */
+
+/** Enqueue burst */
+static uint16_t
+libcrypto_pmd_enqueue_burst(void *queue_pair, struct rte_crypto_op **ops,
+		uint16_t nb_ops)
+{
+	struct libcrypto_session *sess;
+	struct libcrypto_qp *qp = queue_pair;
+	int i, retval;
+
+	for (i = 0; i < nb_ops; i++) {
+		sess = get_session(qp, ops[i]);
+		if (unlikely(sess == NULL))
+			goto enqueue_err;
+
+		retval = process_op(qp, ops[i], sess);
+		if (unlikely(retval < 0))
+			goto enqueue_err;
+	}
+
+	qp->stats.enqueued_count += i;
+	return i;
+
+enqueue_err:
+	qp->stats.enqueue_err_count++;
+	return i;
+}
+
+/** Dequeue burst */
+static uint16_t
+libcrypto_pmd_dequeue_burst(void *queue_pair, struct rte_crypto_op **ops,
+		uint16_t nb_ops)
+{
+	struct libcrypto_qp *qp = queue_pair;
+
+	unsigned int nb_dequeued = 0;
+
+	nb_dequeued = rte_ring_dequeue_burst(qp->processed_ops,
+			(void **)ops, nb_ops);
+	qp->stats.dequeued_count += nb_dequeued;
+
+	return nb_dequeued;
+}
+
+/** Create LIBCRYPTO crypto device */
+static int
+cryptodev_libcrypto_create(const char *name,
+		struct rte_crypto_vdev_init_params *init_params)
+{
+	struct rte_cryptodev *dev;
+	char crypto_dev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+	struct libcrypto_private *internals;
+
+	/* create a unique device name */
+	if (create_unique_device_name(crypto_dev_name,
+			RTE_CRYPTODEV_NAME_MAX_LEN) != 0) {
+		LIBCRYPTO_LOG_ERR("failed to create unique cryptodev name");
+		return -EINVAL;
+	}
+
+	dev = rte_cryptodev_pmd_virtual_dev_init(crypto_dev_name,
+			sizeof(struct libcrypto_private), init_params->socket_id);
+	if (dev == NULL) {
+		LIBCRYPTO_LOG_ERR("failed to create cryptodev vdev");
+		goto init_error;
+	}
+
+	dev->dev_type = RTE_CRYPTODEV_LIBCRYPTO_PMD;
+	dev->dev_ops = rte_libcrypto_pmd_ops;
+
+	/* register rx/tx burst functions for data path */
+	dev->dequeue_burst = libcrypto_pmd_dequeue_burst;
+	dev->enqueue_burst = libcrypto_pmd_enqueue_burst;
+
+	dev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
+			RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING |
+			RTE_CRYPTODEV_FF_CPU_AESNI;
+
+	/* Set vector instructions mode supported */
+	internals = dev->data->dev_private;
+
+	internals->max_nb_qpairs = init_params->max_nb_queue_pairs;
+	internals->max_nb_sessions = init_params->max_nb_sessions;
+
+	return 0;
+
+init_error:
+	LIBCRYPTO_LOG_ERR("driver %s: cryptodev_libcrypto_create failed", name);
+
+	cryptodev_libcrypto_uninit(crypto_dev_name);
+	return -EFAULT;
+}
+
+/** Initialise LIBCRYPTO crypto device */
+static int
+cryptodev_libcrypto_init(const char *name,
+		const char *input_args)
+{
+	struct rte_crypto_vdev_init_params init_params = {
+		RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_QUEUE_PAIRS,
+		RTE_CRYPTODEV_VDEV_DEFAULT_MAX_NB_SESSIONS,
+		rte_socket_id()
+	};
+
+	rte_cryptodev_parse_vdev_init_params(&init_params, input_args);
+
+	RTE_LOG(INFO, PMD, "Initialising %s on NUMA node %d\n", name,
+			init_params.socket_id);
+	RTE_LOG(INFO, PMD, "  Max number of queue pairs = %d\n",
+			init_params.max_nb_queue_pairs);
+	RTE_LOG(INFO, PMD, "  Max number of sessions = %d\n",
+			init_params.max_nb_sessions);
+
+	return cryptodev_libcrypto_create(name, &init_params);
+}
+
+/** Uninitialise LIBCRYPTO crypto device */
+static int
+cryptodev_libcrypto_uninit(const char *name)
+{
+	if (name == NULL)
+		return -EINVAL;
+
+	RTE_LOG(INFO, PMD,
+		"Closing LIBCRYPTO crypto device %s on numa socket %u\n",
+		name, rte_socket_id());
+
+	return 0;
+}
+
+static struct rte_driver cryptodev_libcrypto_pmd_drv = {
+	.type = PMD_VDEV,
+	.init = cryptodev_libcrypto_init,
+	.uninit = cryptodev_libcrypto_uninit
+};
+
+PMD_REGISTER_DRIVER(cryptodev_libcrypto_pmd_drv, CRYPTODEV_NAME_LIBCRYPTO_PMD);
+DRIVER_REGISTER_PARAM_STRING(CRYPTODEV_NAME_LIBCRYPTO_PMD,
+	"max_nb_queue_pairs=<int> "
+	"max_nb_sessions=<int> "
+	"socket_id=<int>");
diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c
new file mode 100644
index 0000000..b5d7bd5
--- /dev/null
+++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c
@@ -0,0 +1,708 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+#include <rte_common.h>
+#include <rte_malloc.h>
+#include <rte_cryptodev_pmd.h>
+
+#include "rte_libcrypto_pmd_private.h"
+
+
+static const struct rte_cryptodev_capabilities libcrypto_pmd_capabilities[] = {
+	{	/* MD5 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_MD5_HMAC,
+				.block_size = 64,
+				.key_size = {
+					.min = 64,
+					.max = 64,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* MD5 */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_MD5,
+				.block_size = 64,
+				.key_size = {
+					.min = 0,
+					.max = 0,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA1 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA1_HMAC,
+				.block_size = 64,
+				.key_size = {
+					.min = 64,
+					.max = 64,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 20,
+					.max = 20,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA1 */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA1,
+				.block_size = 64,
+				.key_size = {
+					.min = 0,
+					.max = 0,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 20,
+					.max = 20,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA224 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA224_HMAC,
+				.block_size = 64,
+				.key_size = {
+					.min = 64,
+					.max = 64,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 28,
+					.max = 28,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA224 */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA224,
+				.block_size = 64,
+				.key_size = {
+					.min = 0,
+					.max = 0,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 28,
+					.max = 28,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA256 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA256_HMAC,
+				.block_size = 64,
+				.key_size = {
+					.min = 64,
+					.max = 64,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 32,
+					.max = 32,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA256 */
+			.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+			{.sym = {
+				.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+				{.auth = {
+					.algo = RTE_CRYPTO_AUTH_SHA256,
+					.block_size = 64,
+					.key_size = {
+						.min = 0,
+						.max = 0,
+						.increment = 0
+					},
+					.digest_size = {
+						.min = 32,
+						.max = 32,
+						.increment = 0
+					},
+					.aad_size = { 0 }
+				}, }
+			}, }
+		},
+	{	/* SHA384 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA384_HMAC,
+				.block_size = 128,
+				.key_size = {
+					.min = 128,
+					.max = 128,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 48,
+					.max = 48,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA384 */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA384,
+				.block_size = 128,
+				.key_size = {
+					.min = 0,
+					.max = 0,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 48,
+					.max = 48,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA512 HMAC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA512_HMAC,
+				.block_size = 128,
+				.key_size = {
+					.min = 128,
+					.max = 128,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 64,
+					.max = 64,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* SHA512  */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_SHA512,
+				.block_size = 128,
+				.key_size = {
+					.min = 0,
+					.max = 0,
+					.increment = 0
+				},
+				.digest_size = {
+					.min = 64,
+					.max = 64,
+					.increment = 0
+				},
+				.aad_size = { 0 }
+			}, }
+		}, }
+	},
+	{	/* AES CBC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_AES_CBC,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 8
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* AES CTR */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_AES_CTR,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 8
+				},
+				.iv_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* AES GCM (AUTH) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_AES_GCM,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 8
+				},
+				.digest_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.aad_size = {
+					.min = 8,
+					.max = 12,
+					.increment = 4
+				}
+			}, }
+		}, }
+	},
+	{	/* AES GCM (CIPHER) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_AES_GCM,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.iv_size = {
+					.min = 12,
+					.max = 16,
+					.increment = 4
+				}
+			}, }
+		}, }
+	},
+	{	/* AES GMAC (AUTH) */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH,
+			{.auth = {
+				.algo = RTE_CRYPTO_AUTH_AES_GMAC,
+				.block_size = 16,
+				.key_size = {
+					.min = 16,
+					.max = 32,
+					.increment = 8
+				},
+				.digest_size = {
+					.min = 16,
+					.max = 16,
+					.increment = 0
+				},
+				.aad_size = {
+					.min = 8,
+					.max = 65532,
+					.increment = 4
+				}
+			}, }
+		}, }
+	},
+	{	/* 3DES CBC */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_3DES_CBC,
+				.block_size = 8,
+				.key_size = {
+					.min = 16,
+					.max = 24,
+					.increment = 8
+				},
+				.iv_size = {
+					.min = 8,
+					.max = 8,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+	{	/* 3DES CTR */
+		.op = RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+		{.sym = {
+			.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER,
+			{.cipher = {
+				.algo = RTE_CRYPTO_CIPHER_3DES_CTR,
+				.block_size = 8,
+				.key_size = {
+					.min = 16,
+					.max = 24,
+					.increment = 8
+				},
+				.iv_size = {
+					.min = 8,
+					.max = 8,
+					.increment = 0
+				}
+			}, }
+		}, }
+	},
+
+	RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
+};
+
+
+/** Configure device */
+static int
+libcrypto_pmd_config(__rte_unused struct rte_cryptodev *dev)
+{
+	return 0;
+}
+
+/** Start device */
+static int
+libcrypto_pmd_start(__rte_unused struct rte_cryptodev *dev)
+{
+	return 0;
+}
+
+/** Stop device */
+static void
+libcrypto_pmd_stop(__rte_unused struct rte_cryptodev *dev)
+{
+}
+
+/** Close device */
+static int
+libcrypto_pmd_close(__rte_unused struct rte_cryptodev *dev)
+{
+	return 0;
+}
+
+
+/** Get device statistics */
+static void
+libcrypto_pmd_stats_get(struct rte_cryptodev *dev,
+		struct rte_cryptodev_stats *stats)
+{
+	int qp_id;
+
+	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
+		struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id];
+
+		stats->enqueued_count += qp->stats.enqueued_count;
+		stats->dequeued_count += qp->stats.dequeued_count;
+
+		stats->enqueue_err_count += qp->stats.enqueue_err_count;
+		stats->dequeue_err_count += qp->stats.dequeue_err_count;
+	}
+}
+
+/** Reset device statistics */
+static void
+libcrypto_pmd_stats_reset(struct rte_cryptodev *dev)
+{
+	int qp_id;
+
+	for (qp_id = 0; qp_id < dev->data->nb_queue_pairs; qp_id++) {
+		struct libcrypto_qp *qp = dev->data->queue_pairs[qp_id];
+
+		memset(&qp->stats, 0, sizeof(qp->stats));
+	}
+}
+
+
+/** Get device info */
+static void
+libcrypto_pmd_info_get(struct rte_cryptodev *dev,
+		struct rte_cryptodev_info *dev_info)
+{
+	struct libcrypto_private *internals = dev->data->dev_private;
+
+	if (dev_info != NULL) {
+		dev_info->dev_type = dev->dev_type;
+		dev_info->feature_flags = dev->feature_flags;
+		dev_info->capabilities = libcrypto_pmd_capabilities;
+		dev_info->max_nb_queue_pairs = internals->max_nb_qpairs;
+		dev_info->sym.max_nb_sessions = internals->max_nb_sessions;
+	}
+}
+
+/** Release queue pair */
+static int
+libcrypto_pmd_qp_release(struct rte_cryptodev *dev, uint16_t qp_id)
+{
+	if (dev->data->queue_pairs[qp_id] != NULL) {
+		rte_free(dev->data->queue_pairs[qp_id]);
+		dev->data->queue_pairs[qp_id] = NULL;
+	}
+	return 0;
+}
+
+/** set a unique name for the queue pair based on it's name, dev_id and qp_id */
+static int
+libcrypto_pmd_qp_set_unique_name(struct rte_cryptodev *dev,
+		struct libcrypto_qp *qp)
+{
+	unsigned int n = snprintf(qp->name, sizeof(qp->name),
+			"libcrypto_pmd_%u_qp_%u",
+			dev->data->dev_id, qp->id);
+
+	if (n > sizeof(qp->name))
+		return -1;
+
+	return 0;
+}
+
+
+/** Create a ring to place processed operations on */
+static struct rte_ring *
+libcrypto_pmd_qp_create_processed_ops_ring(struct libcrypto_qp *qp,
+		unsigned int ring_size, int socket_id)
+{
+	struct rte_ring *r;
+
+	r = rte_ring_lookup(qp->name);
+	if (r) {
+		if (r->prod.size >= ring_size) {
+			LIBCRYPTO_LOG_INFO(
+				"Reusing existing ring %s for processed ops",
+				 qp->name);
+			return r;
+		}
+
+		LIBCRYPTO_LOG_ERR(
+			"Unable to reuse existing ring %s for processed ops",
+			 qp->name);
+		return NULL;
+	}
+
+	return rte_ring_create(qp->name, ring_size, socket_id,
+			RING_F_SP_ENQ | RING_F_SC_DEQ);
+}
+
+
+/** Setup a queue pair */
+static int
+libcrypto_pmd_qp_setup(struct rte_cryptodev *dev, uint16_t qp_id,
+		const struct rte_cryptodev_qp_conf *qp_conf,
+		 int socket_id)
+{
+	struct libcrypto_qp *qp = NULL;
+
+	/* Free memory prior to re-allocation if needed. */
+	if (dev->data->queue_pairs[qp_id] != NULL)
+		libcrypto_pmd_qp_release(dev, qp_id);
+
+	/* Allocate the queue pair data structure. */
+	qp = rte_zmalloc_socket("LIBCRYPTO PMD Queue Pair", sizeof(*qp),
+					RTE_CACHE_LINE_SIZE, socket_id);
+	if (qp == NULL)
+		return -ENOMEM;
+
+	qp->id = qp_id;
+	dev->data->queue_pairs[qp_id] = qp;
+
+	if (libcrypto_pmd_qp_set_unique_name(dev, qp))
+		goto qp_setup_cleanup;
+
+	qp->processed_ops = libcrypto_pmd_qp_create_processed_ops_ring(qp,
+			qp_conf->nb_descriptors, socket_id);
+	if (qp->processed_ops == NULL)
+		goto qp_setup_cleanup;
+
+	qp->sess_mp = dev->data->session_pool;
+
+	memset(&qp->stats, 0, sizeof(qp->stats));
+
+	return 0;
+
+qp_setup_cleanup:
+	if (qp)
+		rte_free(qp);
+
+	return -1;
+}
+
+/** Start queue pair */
+static int
+libcrypto_pmd_qp_start(__rte_unused struct rte_cryptodev *dev,
+		__rte_unused uint16_t queue_pair_id)
+{
+	return -ENOTSUP;
+}
+
+/** Stop queue pair */
+static int
+libcrypto_pmd_qp_stop(__rte_unused struct rte_cryptodev *dev,
+		__rte_unused uint16_t queue_pair_id)
+{
+	return -ENOTSUP;
+}
+
+/** Return the number of allocated queue pairs */
+static uint32_t
+libcrypto_pmd_qp_count(struct rte_cryptodev *dev)
+{
+	return dev->data->nb_queue_pairs;
+}
+
+/** Returns the size of the session structure */
+static unsigned
+libcrypto_pmd_session_get_size(struct rte_cryptodev *dev __rte_unused)
+{
+	return sizeof(struct libcrypto_session);
+}
+
+/** Configure the session from a crypto xform chain */
+static void *
+libcrypto_pmd_session_configure(struct rte_cryptodev *dev __rte_unused,
+		struct rte_crypto_sym_xform *xform,	void *sess)
+{
+	if (unlikely(sess == NULL)) {
+		LIBCRYPTO_LOG_ERR("invalid session struct");
+		return NULL;
+	}
+
+	if (libcrypto_set_session_parameters(
+			sess, xform) != 0) {
+		LIBCRYPTO_LOG_ERR("failed configure session parameters");
+		return NULL;
+	}
+
+	return sess;
+}
+
+
+/** Clear the memory of session so it doesn't leave key material behind */
+static void
+libcrypto_pmd_session_clear(struct rte_cryptodev *dev __rte_unused, void *sess)
+{
+	/*
+	 * Current just resetting the whole data structure, need to investigate
+	 * whether a more selective reset of key would be more performant
+	 */
+	if (sess) {
+		libcrypto_reset_session(sess);
+		memset(sess, 0, sizeof(struct libcrypto_session));
+	}
+}
+
+struct rte_cryptodev_ops libcrypto_pmd_ops = {
+		.dev_configure		= libcrypto_pmd_config,
+		.dev_start		= libcrypto_pmd_start,
+		.dev_stop		= libcrypto_pmd_stop,
+		.dev_close		= libcrypto_pmd_close,
+
+		.stats_get		= libcrypto_pmd_stats_get,
+		.stats_reset		= libcrypto_pmd_stats_reset,
+
+		.dev_infos_get		= libcrypto_pmd_info_get,
+
+		.queue_pair_setup	= libcrypto_pmd_qp_setup,
+		.queue_pair_release	= libcrypto_pmd_qp_release,
+		.queue_pair_start	= libcrypto_pmd_qp_start,
+		.queue_pair_stop	= libcrypto_pmd_qp_stop,
+		.queue_pair_count	= libcrypto_pmd_qp_count,
+
+		.session_get_size	= libcrypto_pmd_session_get_size,
+		.session_configure	= libcrypto_pmd_session_configure,
+		.session_clear		= libcrypto_pmd_session_clear
+};
+
+struct rte_cryptodev_ops *rte_libcrypto_pmd_ops = &libcrypto_pmd_ops;
diff --git a/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h
new file mode 100644
index 0000000..dbef57f
--- /dev/null
+++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h
@@ -0,0 +1,174 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _LIBCRYPTO_PMD_PRIVATE_H_
+#define _LIBCRYPTO_PMD_PRIVATE_H_
+
+#include <openssl/evp.h>
+#include <openssl/des.h>
+
+
+#define LIBCRYPTO_LOG_ERR(fmt, args...) \
+	RTE_LOG(ERR, CRYPTODEV, "[%s] %s() line %u: " fmt "\n",  \
+			RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \
+			__func__, __LINE__, ## args)
+
+#ifdef RTE_LIBRTE_LIBCRYPTO_DEBUG
+#define LIBCRYPTO_LOG_INFO(fmt, args...) \
+	RTE_LOG(INFO, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \
+			RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \
+			__func__, __LINE__, ## args)
+
+#define LIBCRYPTO_LOG_DBG(fmt, args...) \
+	RTE_LOG(DEBUG, CRYPTODEV, "[%s] %s() line %u: " fmt "\n", \
+			RTE_STR(CRYPTODEV_NAME_LIBCRYPTO_PMD), \
+			__func__, __LINE__, ## args)
+#else
+#define LIBCRYPTO_LOG_INFO(fmt, args...)
+#define LIBCRYPTO_LOG_DBG(fmt, args...)
+#endif
+
+
+/** LIBCRYPTO operation order mode enumerator */
+enum libcrypto_chain_order {
+	LIBCRYPTO_CHAIN_ONLY_CIPHER,
+	LIBCRYPTO_CHAIN_ONLY_AUTH,
+	LIBCRYPTO_CHAIN_CIPHER_AUTH,
+	LIBCRYPTO_CHAIN_AUTH_CIPHER,
+	LIBCRYPTO_CHAIN_COMBINED,
+	LIBCRYPTO_CHAIN_NOT_SUPPORTED
+};
+
+/** LIBCRYPTO cipher mode enumerator */
+enum libcrypto_cipher_mode {
+	LIBCRYPTO_CIPHER_LIB,
+	LIBCRYPTO_CIPHER_DES3CTR,
+};
+
+/** LIBCRYPTO auth mode enumerator */
+enum libcrypto_auth_mode {
+	LIBCRYPTO_AUTH_AS_AUTH,
+	LIBCRYPTO_AUTH_AS_HMAC,
+};
+
+/** private data structure for each LIBCRYPTO crypto device */
+struct libcrypto_private {
+	unsigned int max_nb_qpairs;
+	/**< Max number of queue pairs */
+	unsigned int max_nb_sessions;
+	/**< Max number of sessions */
+};
+
+/** LIBCRYPTO crypto queue pair */
+struct libcrypto_qp {
+	uint16_t id;
+	/**< Queue Pair Identifier */
+	char name[RTE_CRYPTODEV_NAME_LEN];
+	/**< Unique Queue Pair Name */
+	struct rte_ring *processed_ops;
+	/**< Ring for placing process packets */
+	struct rte_mempool *sess_mp;
+	/**< Session Mempool */
+	struct rte_cryptodev_stats stats;
+	/**< Queue pair statistics */
+} __rte_cache_aligned;
+
+/** LIBCRYPTO crypto private session structure */
+struct libcrypto_session {
+	enum libcrypto_chain_order chain_order;
+	/**< chain order mode */
+
+	/** Cipher Parameters */
+	struct {
+		enum rte_crypto_cipher_operation direction;
+		/**< cipher operation direction */
+		enum libcrypto_cipher_mode mode;
+		/**< cipher operation mode */
+		enum rte_crypto_cipher_algorithm algo;
+		/**< cipher algorithm */
+
+		struct {
+			uint8_t data[32];
+			/**< key data */
+			size_t length;
+			/**< key length in bytes */
+		} key;
+
+		const EVP_CIPHER *evp_algo;
+		/**< pointer to EVP algorithm function */
+		EVP_CIPHER_CTX *ctx;
+		/**< pointer to EVP context structure */
+	} cipher;
+
+	/** Authentication Parameters */
+	struct {
+		enum rte_crypto_auth_operation operation;
+		/**< auth operation generate or verify */
+		enum libcrypto_auth_mode mode;
+		/**< auth operation mode */
+		enum rte_crypto_auth_algorithm algo;
+		/**< cipher algorithm */
+
+		union {
+			struct {
+				const EVP_MD *evp_algo;
+				/**< pointer to EVP algorithm function */
+				EVP_MD_CTX *ctx;
+				/**< pointer to EVP context structure */
+			} auth;
+
+			struct {
+				EVP_PKEY *pkey;
+				/**< pointer to EVP key */
+				const EVP_MD *evp_algo;
+				/**< pointer to EVP algorithm function */
+				EVP_MD_CTX *ctx;
+				/**< pointer to EVP context structure */
+			} hmac;
+		};
+	} auth;
+
+} __rte_cache_aligned;
+
+/** Set and validate LIBCRYPTO crypto session parameters */
+extern int
+libcrypto_set_session_parameters(struct libcrypto_session *sess,
+		const struct rte_crypto_sym_xform *xform);
+
+/** Reset LIBCRYPTO crypto session parameters */
+extern void
+libcrypto_reset_session(struct libcrypto_session *sess);
+
+/** device specific operations function pointer structure */
+extern struct rte_cryptodev_ops *rte_libcrypto_pmd_ops;
+
+#endif /* _LIBCRYPTO_PMD_PRIVATE_H_ */
diff --git a/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map
new file mode 100644
index 0000000..cc5829e
--- /dev/null
+++ b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map
@@ -0,0 +1,3 @@
+DPDK_16.11 {
+	local: *;
+};
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index b1658eb..311fd78 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -56,6 +56,8 @@ extern "C" {
 /**< AES-NI Multi buffer PMD device name */
 #define CRYPTODEV_NAME_AESNI_GCM_PMD	crypto_aesni_gcm
 /**< AES-NI GCM PMD device name */
+#define CRYPTODEV_NAME_LIBCRYPTO_PMD	cryptodev_libcrypto
+/**< Open SSL Crypto PMD device name */
 #define CRYPTODEV_NAME_QAT_SYM_PMD	crypto_qat
 /**< Intel QAT Symmetric Crypto PMD device name */
 #define CRYPTODEV_NAME_SNOW3G_PMD	crypto_snow3g
@@ -73,7 +75,8 @@ enum rte_cryptodev_type {
 	RTE_CRYPTODEV_QAT_SYM_PMD,	/**< QAT PMD Symmetric Crypto */
 	RTE_CRYPTODEV_SNOW3G_PMD,	/**< SNOW 3G PMD */
 	RTE_CRYPTODEV_KASUMI_PMD,	/**< KASUMI PMD */
-	RTE_CRYPTODEV_ZUC_PMD		/**< ZUC PMD */
+	RTE_CRYPTODEV_ZUC_PMD,		/**< ZUC PMD */
+	RTE_CRYPTODEV_LIBCRYPTO_PMD,    /**<  LibCrypto PMD */
 };
 
 extern const char **rte_cyptodev_names;
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 440bf83..43ea1c1 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -131,18 +131,19 @@ endif # $(CONFIG_RTE_LIBRTE_VHOST)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD)    += -lrte_pmd_vmxnet3_uio
 
 ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)   += -lrte_pmd_aesni_mb
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)   += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM)  += -lrte_pmd_aesni_gcm -lcrypto
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM)  += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)    += -lrte_pmd_aesni_mb
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)    += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM)   += -lrte_pmd_aesni_gcm -lcrypto
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM)   += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_LIBCRYPTO)   += -lrte_pmd_libcrypto -lcrypto
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += -lrte_pmd_null_crypto
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT)        += -lrte_pmd_qat -lcrypto
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G)     += -lrte_pmd_snow3g
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G)     += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI)     += -lrte_pmd_kasumi
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI)     += -L$(LIBSSO_KASUMI_PATH)/build -lsso_kasumi
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC)        += -lrte_pmd_zuc
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC)        += -L$(LIBSSO_ZUC_PATH)/build -lsso_zuc
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT)         += -lrte_pmd_qat -lcrypto
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G)      += -lrte_pmd_snow3g
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G)      += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI)      += -lrte_pmd_kasumi
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI)      += -L$(LIBSSO_KASUMI_PATH)/build -lsso_kasumi
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC)         += -lrte_pmd_zuc
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC)         += -L$(LIBSSO_ZUC_PATH)/build -lsso_zuc
 endif # CONFIG_RTE_LIBRTE_CRYPTODEV
 
 endif # !CONFIG_RTE_BUILD_SHARED_LIBS
-- 
2.5.0

^ permalink raw reply related

* [PATCH v5 0/4] new crypto software based device
From: Slawomir Mrozowicz @ 2016-10-03 14:26 UTC (permalink / raw)
  To: dev; +Cc: Slawomir Mrozowicz
In-Reply-To: <1475252242-29684-1-git-send-email-slawomirx.mrozowicz@intel.com>

This code provides the initial implementation of the libcrypto poll mode driver.
All cryptography operations are using Openssl library crypto API.
Each algorithm uses EVP_ interface from openssl API - which is recommended by
Openssl maintainers.

For more information about how to use this driver, go to:
doc/guides/cryptodevs/libcrypto.rst

Changes in V5:
- reduce source of big data test

Changes in V4:
- move aes test rework to another patch
- move big data test to another patch
- checking if libcrypto pmd is available

Changes in V3:
- add nagative verification tests
- add big data test
- fix pmd according to negative verification tests
- change gmac aad max size
- update documentation and commits comments

Changes in V2:
- add gcm/gmac algorithm correction
- unit test rework

Slawomir Mrozowicz (1):
  libcrypto_pmd: initial implementation of SW crypto device

Piotr Azarewicz (2)
  app/test: cryptodev AES tests rework
  app/test: added tests for libcrypto PMD

Daniel Mrzyglod (1)
  examples/l2fwd-crypto: updated example for libcrypto PMD

 MAINTAINERS                                        |    4 +
 app/test/Makefile                                  |    2 +-
 app/test/test_cryptodev.c                          | 1581 ++++++++++++++++++--
 app/test/test_cryptodev.h                          |    1 +
 app/test/test_cryptodev_aes.c                      |  687 ---------
 app/test/test_cryptodev_aes.h                      | 1124 --------------
 app/test/test_cryptodev_aes_test_vectors.h         | 1095 ++++++++++++++
 app/test/test_cryptodev_blockcipher.c              |  531 +++++++
 app/test/test_cryptodev_blockcipher.h              |  125 ++
 app/test/test_cryptodev_des_test_vectors.h         |  952 ++++++++++++
 app/test/test_cryptodev_gcm_test_vectors.h         |   36 +-
 app/test/test_cryptodev_hash_test_vectors.h        |  491 ++++++
 app/test/test_cryptodev_perf.c                     |  689 ++++++++-
 config/common_base                                 |    6 +
 doc/guides/cryptodevs/index.rst                    |    1 +
 doc/guides/cryptodevs/libcrypto.rst                |  116 ++
 doc/guides/rel_notes/release_16_11.rst             |   23 +-
 drivers/crypto/Makefile                            |    1 +
 drivers/crypto/libcrypto/Makefile                  |   60 +
 drivers/crypto/libcrypto/rte_libcrypto_pmd.c       | 1051 +++++++++++++
 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c   |  708 +++++++++
 .../crypto/libcrypto/rte_libcrypto_pmd_private.h   |  174 +++
 .../crypto/libcrypto/rte_pmd_libcrypto_version.map |    3 +
 examples/l2fwd-crypto/main.c                       |    9 +
 lib/librte_cryptodev/rte_cryptodev.h               |    5 +-
 mk/rte.app.mk                                      |   23 +-
 26 files changed, 7563 insertions(+), 1935 deletions(-)
 delete mode 100644 app/test/test_cryptodev_aes.c
 delete mode 100644 app/test/test_cryptodev_aes.h
 create mode 100644 app/test/test_cryptodev_aes_test_vectors.h
 create mode 100644 app/test/test_cryptodev_blockcipher.c
 create mode 100644 app/test/test_cryptodev_blockcipher.h
 create mode 100644 app/test/test_cryptodev_des_test_vectors.h
 create mode 100644 app/test/test_cryptodev_hash_test_vectors.h
 create mode 100644 doc/guides/cryptodevs/libcrypto.rst
 create mode 100644 drivers/crypto/libcrypto/Makefile
 create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd.c
 create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c
 create mode 100644 drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h
 create mode 100644 drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map

-- 
2.5.0

^ permalink raw reply

* Re: [PATCH v4 0/4] Cuckoo hash enhancements
From: Bruce Richardson @ 2016-10-03  9:59 UTC (permalink / raw)
  To: Pablo de Lara; +Cc: dev
In-Reply-To: <1475221136-213246-1-git-send-email-pablo.de.lara.guarch@intel.com>

On Fri, Sep 30, 2016 at 08:38:52AM +0100, Pablo de Lara wrote:
> This patchset improves lookup performance on the current hash library
> by changing the existing lookup bulk pipeline, with an improved pipeline,
> based on a loop-and-jump model, instead of the current 4-stage 2-entry pipeline.
> Also, x86 vectorized intrinsics are used to improve performance when comparing signatures.
> 
> First patch reorganizes the order of the hash structure.
> The structure takes more than one 64-byte cache line, but not all
> the fields are used in the lookup operation (the most common operation).
> Therefore, all these fields have been moved to the first part of the structure,
> so they all fit in one cache line, improving slightly the performance in some
> scenarios.
> 
> Second patch modifies the order of the bucket structure.
> Currently, the buckets store all the signatures together (current and alternative).
> In order to be able to perform a vectorized signature comparison,
> all current signatures have to be together, so the order of the bucket has been changed,
> having separated all the current signatures from the alternative signatures.
> 
> Third patch introduces x86 vectorized intrinsics.
> When performing a lookup bulk operation, all current signatures in a bucket
> are compared against the signature of the key being looked up.
> Now that they all are together, a vectorized comparison can be performed,
> which takes less instructions to be carried out.
> In case of having a machine with AVX2, number of entries per bucket are
> increased from 4 to 8, as AVX2 allows comparing two 256-bit values, with 8x32-bit integers,
> which are the 8 signatures on the bucket.
> 
> Fourth (and last) patch modifies the current pipeline of the lookup bulk function.
> The new pipeline is based on a loop-and-jump model. The two key improvements are:
> 
> - Better prefetching: in this case, first 4 keys to be looked up are prefetched,
>   and after that, the rest of the keys are prefetched at the time the calculation
>   of the signatures are being performed. This gives more time for the CPU to
>   prefetch the data requesting before actually need it, which result in less
>   cache misses and therefore, higher throughput.
> 
> - Lower performance penalty when using fallback: the lookup bulk algorithm
>   assumes that most times there will not be a collision in a bucket, but it might
>   happen that two or more signatures are equal, which means that more than one
>   key comparison might be necessary. In that case, only the key of the first hit is prefetched,
>   like in the current implementation. The difference now is that if this comparison
>   results in a miss, the information of the other keys to be compared has been stored,
>   unlike the current implementation, which needs to perform an entire simple lookup again.
> 
> Changes in v4:
> - Reordered hash structure, so alt signature is at the start
>   of the next cache line, and explain in the commit message
>   why it has been moved
> - Reordered hash structure, so name field is on top of the structure,
>   leaving all the fields used in lookup in the next cache line
>   (instead of the first cache line)
> 
> Changes in v3:
> - Corrected the cover letter (wrong number of patches)
> 
> Changes in v2:
> - Increased entries per bucket from 4 to 8 for all cases,
>   so it is not architecture dependent any longer.
> - Replaced compile-time signature comparison function election
>   with run-time election, so best optimization available
>   will be used from a single binary.
> - Reordered the hash structure, so all the fields used by lookup
>   are in the same cache line (first).
> 
> Byron Marohn (3):
>   hash: reorganize bucket structure
>   hash: add vectorized comparison
>   hash: modify lookup bulk pipeline
> 

Hi,

Firstly, checkpatches is reporting some style errors in these patches.

Secondly, when I run the "hash_multiwriter_autotest" I get what I assume to be
an error after applying this patchset. Before this set is applied, running
that test shows the cycles per insert with/without lock elision. Now, though
I'm getting an error about a key being dropped or failing to insert in the lock
elision case, e.g. 

  Core #2 inserting 1572864: 0 - 1,572,864
  key 1497087 is lost
  1 key lost

I've run the test a number of times, and there is a single key lost each time.
Please check on this, is it expected or is it a problem?

Thanks,
/Bruce

^ permalink raw reply

* Re: [PATCH v2 0/8] Misc enhancements in testpmd
From: Olivier Matz @ 2016-10-03  9:02 UTC (permalink / raw)
  To: dev, pablo.de.lara.guarch
In-Reply-To: <1473407734-11253-1-git-send-email-olivier.matz@6wind.com>

Hello,

On 09/09/2016 09:55 AM, Olivier Matz wrote:
> This patchset introduces several enhancements or minor fixes
> in testpmd. It is targetted for v16.11, and applies on top of
> software ptype v2 patchset [1].
> 
> These patches are useful to validate the virtio offload
> patchset [2] (to be rebased).
> 
> [1] http://dpdk.org/ml/archives/dev/2016-August/045876.html
> [2] http://dpdk.org/ml/archives/dev/2016-July/044404.html
> 
> changes v1 -> v2:
> - rebase on top of sw ptype v2 patch

Any comment on this patchset?


Thanks,
Olivier

^ permalink raw reply

* [PATCH v2 11/12] virtio: add Lro support
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 drivers/net/virtio/virtio_ethdev.c |  7 ++++++-
 drivers/net/virtio/virtio_ethdev.h |  9 ---------
 drivers/net/virtio/virtio_rxtx.c   | 21 +++++++++++++++++++++
 3 files changed, 27 insertions(+), 10 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 55024cd..fd33364 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1354,6 +1354,10 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 	req_features = VIRTIO_PMD_DEFAULT_GUEST_FEATURES;
 	if (rxmode->hw_ip_checksum)
 		req_features |= (1ULL << VIRTIO_NET_F_GUEST_CSUM);
+	if (rxmode->enable_lro)
+		req_features |=
+			(1ULL << VIRTIO_NET_F_GUEST_TSO4) |
+			(1ULL << VIRTIO_NET_F_GUEST_TSO6);
 
 	/* if request features changed, reinit the device */
 	if (req_features != hw->req_guest_features) {
@@ -1577,7 +1581,8 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	};
 	dev_info->rx_offload_capa =
 		DEV_RX_OFFLOAD_TCP_CKSUM |
-		DEV_RX_OFFLOAD_UDP_CKSUM;
+		DEV_RX_OFFLOAD_UDP_CKSUM |
+		DEV_RX_OFFLOAD_TCP_LRO;
 	dev_info->tx_offload_capa = 0;
 
 	if (hw->guest_features & (1ULL << VIRTIO_NET_F_CSUM)) {
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index 202aa2e..daa6bff 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -116,13 +116,4 @@ uint16_t virtio_xmit_pkts_simple(void *tx_queue, struct rte_mbuf **tx_pkts,
 
 int eth_virtio_dev_init(struct rte_eth_dev *eth_dev);
 
-/*
- * The VIRTIO_NET_F_GUEST_TSO[46] features permit the host to send us
- * frames larger than 1514 bytes. We do not yet support software LRO
- * via tcp_lro_rx().
- */
-#define VTNET_LRO_FEATURES (VIRTIO_NET_F_GUEST_TSO4 | \
-			    VIRTIO_NET_F_GUEST_TSO6 | VIRTIO_NET_F_GUEST_ECN)
-
-
 #endif /* _VIRTIO_ETHDEV_H_ */
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 4ae11e7..0464bd1 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -692,6 +692,27 @@ virtio_rx_offload(struct rte_mbuf *m, struct virtio_net_hdr *hdr)
 		m->ol_flags |= PKT_RX_L4_CKSUM_GOOD;
 	}
 
+	/* GSO request, save required information in mbuf */
+	if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+		/* Check unsupported modes */
+		if ((hdr->gso_type & VIRTIO_NET_HDR_GSO_ECN) ||
+		    (hdr->gso_size == 0)) {
+			return -EINVAL;
+		}
+
+		/* Update mss lengthes in mbuf */
+		m->tso_segsz = hdr->gso_size;
+		switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+			case VIRTIO_NET_HDR_GSO_TCPV4:
+			case VIRTIO_NET_HDR_GSO_TCPV6:
+				m->ol_flags |= PKT_RX_LRO | \
+					PKT_RX_L4_CKSUM_NONE;
+				break;
+			default:
+				return -EINVAL;
+		}
+	}
+
 	return 0;
 }
 
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 12/12] virtio: add Tso support
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 drivers/net/virtio/virtio_ethdev.c |   6 ++
 drivers/net/virtio/virtio_ethdev.h |   2 +
 drivers/net/virtio/virtio_rxtx.c   | 129 ++++++++++++++++++++++++++++++++++++-
 3 files changed, 134 insertions(+), 3 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index fd33364..5728ca1 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1563,6 +1563,7 @@ virtio_dev_link_update(struct rte_eth_dev *dev, __rte_unused int wait_to_complet
 static void
 virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
+	uint64_t tso_mask;
 	struct virtio_hw *hw = dev->data->dev_private;
 
 	if (dev->pci_dev)
@@ -1590,6 +1591,11 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 			DEV_TX_OFFLOAD_UDP_CKSUM |
 			DEV_TX_OFFLOAD_TCP_CKSUM;
 	}
+
+	tso_mask = (1ULL << VIRTIO_NET_F_HOST_TSO4) |
+		(1ULL << VIRTIO_NET_F_HOST_TSO6);
+	if ((hw->guest_features & tso_mask) == tso_mask)
+		dev_info->tx_offload_capa |= DEV_TX_OFFLOAD_TCP_TSO;
 }
 
 /*
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index daa6bff..ab3b138 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -63,6 +63,8 @@
 	 1u << VIRTIO_NET_F_CTRL_RX	  |	\
 	 1u << VIRTIO_NET_F_CTRL_VLAN	  |	\
 	 1u << VIRTIO_NET_F_CSUM	  |	\
+	 1u << VIRTIO_NET_F_HOST_TSO4	  |	\
+	 1u << VIRTIO_NET_F_HOST_TSO6	  |	\
 	 1u << VIRTIO_NET_F_MRG_RXBUF	  |	\
 	 1ULL << VIRTIO_F_VERSION_1)
 
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 0464bd1..134995e 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -51,6 +51,8 @@
 #include <rte_errno.h>
 #include <rte_byteorder.h>
 #include <rte_net.h>
+#include <rte_ip.h>
+#include <rte_tcp.h>
 
 #include "virtio_logs.h"
 #include "virtio_ethdev.h"
@@ -209,6 +211,111 @@ virtqueue_enqueue_recv_refill(struct virtqueue *vq, struct rte_mbuf *cookie)
 	return 0;
 }
 
+/* When doing TSO, the IP length is not included in the pseudo header
+ * checksum of the packet given to the PMD, but for virtio it is
+ * expected.
+ */
+static void
+virtio_tso_fix_cksum(struct rte_mbuf *m)
+{
+	/* common case: header is not fragmented */
+	if (likely(rte_pktmbuf_data_len(m) >= m->l2_len + m->l3_len +
+			m->l4_len)) {
+		struct ipv4_hdr *iph;
+		struct ipv6_hdr *ip6h;
+		struct tcp_hdr *th;
+		uint16_t prev_cksum, new_cksum, ip_len, ip_paylen;
+		uint32_t tmp;
+
+		iph = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *, m->l2_len);
+		th = RTE_PTR_ADD(iph, m->l3_len);
+		if ((iph->version_ihl >> 4) == 4) {
+			iph->hdr_checksum = 0;
+			iph->hdr_checksum = rte_ipv4_cksum(iph);
+			ip_len = iph->total_length;
+			ip_paylen = rte_cpu_to_be_16(rte_be_to_cpu_16(ip_len) -
+				m->l3_len);
+		} else {
+			ip6h = (struct ipv6_hdr *)iph;
+			ip_paylen = ip6h->payload_len;
+		}
+
+		/* calculate the new phdr checksum not including ip_paylen */
+		prev_cksum = th->cksum;
+		tmp = prev_cksum;
+		tmp += ip_paylen;
+		tmp = (tmp & 0xffff) + (tmp >> 16);
+		new_cksum = tmp;
+
+		/* replace it in the packet */
+		th->cksum = new_cksum;
+	} else {
+		const struct ipv4_hdr *iph;
+		struct ipv4_hdr iph_copy;
+		union {
+			uint16_t u16;
+			uint8_t u8[2];
+		} prev_cksum, new_cksum, ip_len, ip_paylen, ip_csum;
+		uint32_t tmp;
+
+		/* Same code than above, but we use rte_pktmbuf_read()
+		 * or we read/write in mbuf data one byte at a time to
+		 * avoid issues if the packet is multi segmented.
+		 */
+
+		uint8_t ip_version;
+
+		ip_version = *rte_pktmbuf_mtod_offset(m, uint8_t *,
+			m->l2_len) >> 4;
+
+		/* calculate ip checksum (API imposes to set it to 0)
+		 * and get ip payload len */
+		if (ip_version == 4) {
+			*rte_pktmbuf_mtod_offset(m, uint8_t *,
+				m->l2_len + 10) = 0;
+			*rte_pktmbuf_mtod_offset(m, uint8_t *,
+				m->l2_len + 11) = 0;
+			iph = rte_pktmbuf_read(m, m->l2_len,
+				sizeof(*iph), &iph_copy);
+			ip_csum.u16 = rte_ipv4_cksum(iph);
+			*rte_pktmbuf_mtod_offset(m, uint8_t *,
+				m->l2_len + 10) = ip_csum.u8[0];
+			*rte_pktmbuf_mtod_offset(m, uint8_t *,
+				m->l2_len + 11) = ip_csum.u8[1];
+
+			ip_len.u8[0] = *rte_pktmbuf_mtod_offset(m, uint8_t *,
+				m->l2_len + 2);
+			ip_len.u8[1] = *rte_pktmbuf_mtod_offset(m, uint8_t *,
+				m->l2_len + 3);
+
+			ip_paylen.u16 = rte_cpu_to_be_16(
+				rte_be_to_cpu_16(ip_len.u16) - m->l3_len);
+		} else {
+			ip_paylen.u8[0] = *rte_pktmbuf_mtod_offset(m, uint8_t *,
+				m->l2_len + 4);
+			ip_paylen.u8[1] = *rte_pktmbuf_mtod_offset(m, uint8_t *,
+				m->l2_len + 5);
+		}
+
+		/* calculate the new phdr checksum not including ip_paylen */
+		/* get phdr cksum at offset 16 of TCP header */
+		prev_cksum.u8[0] = *rte_pktmbuf_mtod_offset(m, uint8_t *,
+			m->l2_len + m->l3_len + 16);
+		prev_cksum.u8[1] = *rte_pktmbuf_mtod_offset(m, uint8_t *,
+			m->l2_len + m->l3_len + 17);
+		tmp = prev_cksum.u16;
+		tmp += ip_paylen.u16;
+		tmp = (tmp & 0xffff) + (tmp >> 16);
+		new_cksum.u16 = tmp;
+
+		/* replace it in the packet */
+		*rte_pktmbuf_mtod_offset(m, uint8_t *,
+			m->l2_len + m->l3_len + 16) = new_cksum.u8[0];
+		*rte_pktmbuf_mtod_offset(m, uint8_t *,
+			m->l2_len + m->l3_len + 17) = new_cksum.u8[1];
+	}
+}
+
 static inline void
 virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
 		       uint16_t needed, int use_indirect, int can_push)
@@ -264,6 +371,9 @@ virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
 	}
 
 	/* Checksum Offload */
+	if (cookie->ol_flags & PKT_TX_TCP_SEG)
+		cookie->ol_flags |= PKT_TX_TCP_CKSUM;
+
 	switch (cookie->ol_flags & PKT_TX_L4_MASK) {
 	case PKT_TX_UDP_CKSUM:
 		hdr->csum_start = cookie->l2_len + cookie->l3_len;
@@ -284,9 +394,22 @@ virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
 		break;
 	}
 
-	hdr->gso_type = 0;
-	hdr->gso_size = 0;
-	hdr->hdr_len = 0;
+	/* TCP Segmentation Offload */
+	if (cookie->ol_flags & PKT_TX_TCP_SEG) {
+		virtio_tso_fix_cksum(cookie);
+		hdr->gso_type = (cookie->ol_flags & PKT_TX_IPV6) ?
+			VIRTIO_NET_HDR_GSO_TCPV6 :
+			VIRTIO_NET_HDR_GSO_TCPV4;
+		hdr->gso_size = cookie->tso_segsz;
+		hdr->hdr_len =
+			cookie->l2_len +
+			cookie->l3_len +
+			cookie->l4_len;
+	} else {
+		hdr->gso_type = 0;
+		hdr->gso_size = 0;
+		hdr->hdr_len = 0;
+	}
 
 	do {
 		start_dp[idx].addr  = VIRTIO_MBUF_DATA_DMA_ADDR(cookie, vq);
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 10/12] virtio: add Tx checksum offload support
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 drivers/net/virtio/virtio_ethdev.c |  7 +++++
 drivers/net/virtio/virtio_ethdev.h |  1 +
 drivers/net/virtio/virtio_rxtx.c   | 57 +++++++++++++++++++++++++-------------
 3 files changed, 45 insertions(+), 20 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 43cb096..55024cd 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1578,6 +1578,13 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->rx_offload_capa =
 		DEV_RX_OFFLOAD_TCP_CKSUM |
 		DEV_RX_OFFLOAD_UDP_CKSUM;
+	dev_info->tx_offload_capa = 0;
+
+	if (hw->guest_features & (1ULL << VIRTIO_NET_F_CSUM)) {
+		dev_info->tx_offload_capa |=
+			DEV_TX_OFFLOAD_UDP_CKSUM |
+			DEV_TX_OFFLOAD_TCP_CKSUM;
+	}
 }
 
 /*
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index 2fc9218..202aa2e 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -62,6 +62,7 @@
 	 1u << VIRTIO_NET_F_CTRL_VQ	  |	\
 	 1u << VIRTIO_NET_F_CTRL_RX	  |	\
 	 1u << VIRTIO_NET_F_CTRL_VLAN	  |	\
+	 1u << VIRTIO_NET_F_CSUM	  |	\
 	 1u << VIRTIO_NET_F_MRG_RXBUF	  |	\
 	 1ULL << VIRTIO_F_VERSION_1)
 
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index eda678a..4ae11e7 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -213,13 +213,14 @@ static inline void
 virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
 		       uint16_t needed, int use_indirect, int can_push)
 {
+	struct virtio_tx_region *txr = txvq->virtio_net_hdr_mz->addr;
 	struct vq_desc_extra *dxp;
 	struct virtqueue *vq = txvq->vq;
 	struct vring_desc *start_dp;
 	uint16_t seg_num = cookie->nb_segs;
 	uint16_t head_idx, idx;
 	uint16_t head_size = vq->hw->vtnet_hdr_size;
-	unsigned long offs;
+	struct virtio_net_hdr *hdr;
 
 	head_idx = vq->vq_desc_head_idx;
 	idx = head_idx;
@@ -230,10 +231,9 @@ virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
 	start_dp = vq->vq_ring.desc;
 
 	if (can_push) {
-		/* put on zero'd transmit header (no offloads) */
-		void *hdr = rte_pktmbuf_prepend(cookie, head_size);
-
-		memset(hdr, 0, head_size);
+		/* prepend cannot fail, checked by caller */
+		hdr = (struct virtio_net_hdr *)
+			rte_pktmbuf_prepend(cookie, head_size);
 	} else if (use_indirect) {
 		/* setup tx ring slot to point to indirect
 		 * descriptor list stored in reserved region.
@@ -241,14 +241,11 @@ virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
 		 * the first slot in indirect ring is already preset
 		 * to point to the header in reserved region
 		 */
-		struct virtio_tx_region *txr = txvq->virtio_net_hdr_mz->addr;
-
-		offs = idx * sizeof(struct virtio_tx_region)
-			+ offsetof(struct virtio_tx_region, tx_indir);
-
-		start_dp[idx].addr  = txvq->virtio_net_hdr_mem + offs;
+		start_dp[idx].addr  = txvq->virtio_net_hdr_mem +
+			RTE_PTR_DIFF(&txr[idx].tx_indir, txr);
 		start_dp[idx].len   = (seg_num + 1) * sizeof(struct vring_desc);
 		start_dp[idx].flags = VRING_DESC_F_INDIRECT;
+		hdr = (struct virtio_net_hdr *)&txr[idx].tx_hdr;
 
 		/* loop below will fill in rest of the indirect elements */
 		start_dp = txr[idx].tx_indir;
@@ -257,15 +254,40 @@ virtqueue_enqueue_xmit(struct virtnet_tx *txvq, struct rte_mbuf *cookie,
 		/* setup first tx ring slot to point to header
 		 * stored in reserved region.
 		 */
-		offs = idx * sizeof(struct virtio_tx_region)
-			+ offsetof(struct virtio_tx_region, tx_hdr);
-
-		start_dp[idx].addr  = txvq->virtio_net_hdr_mem + offs;
+		start_dp[idx].addr  = txvq->virtio_net_hdr_mem +
+			RTE_PTR_DIFF(&txr[idx].tx_hdr, txr);
 		start_dp[idx].len   = vq->hw->vtnet_hdr_size;
 		start_dp[idx].flags = VRING_DESC_F_NEXT;
+		hdr = (struct virtio_net_hdr *)&txr[idx].tx_hdr;
+
 		idx = start_dp[idx].next;
 	}
 
+	/* Checksum Offload */
+	switch (cookie->ol_flags & PKT_TX_L4_MASK) {
+	case PKT_TX_UDP_CKSUM:
+		hdr->csum_start = cookie->l2_len + cookie->l3_len;
+		hdr->csum_offset = 6;
+		hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+		break;
+
+	case PKT_TX_TCP_CKSUM:
+		hdr->csum_start = cookie->l2_len + cookie->l3_len;
+		hdr->csum_offset = 16;
+		hdr->flags = VIRTIO_NET_HDR_F_NEEDS_CSUM;
+		break;
+
+	default:
+		hdr->csum_start = 0;
+		hdr->csum_offset = 0;
+		hdr->flags = 0;
+		break;
+	}
+
+	hdr->gso_type = 0;
+	hdr->gso_size = 0;
+	hdr->hdr_len = 0;
+
 	do {
 		start_dp[idx].addr  = VIRTIO_MBUF_DATA_DMA_ADDR(cookie, vq);
 		start_dp[idx].len   = cookie->data_len;
@@ -512,11 +534,6 @@ virtio_dev_tx_queue_setup(struct rte_eth_dev *dev,
 
 	PMD_INIT_FUNC_TRACE();
 
-	if ((tx_conf->txq_flags & ETH_TXQ_FLAGS_NOXSUMS)
-	    != ETH_TXQ_FLAGS_NOXSUMS) {
-		PMD_INIT_LOG(ERR, "TX checksum offload not supported\n");
-		return -EINVAL;
-	}
 
 #ifdef RTE_MACHINE_CPUFLAG_SSSE3
 	/* Use simple rx/tx func if single segment and no offloads */
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 09/12] virtio: add Rx checksum offload support
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 drivers/net/virtio/virtio_ethdev.c | 14 ++++----
 drivers/net/virtio/virtio_ethdev.h |  2 +-
 drivers/net/virtio/virtio_rxtx.c   | 69 ++++++++++++++++++++++++++++++++++++++
 drivers/net/virtio/virtqueue.h     |  1 +
 4 files changed, 78 insertions(+), 8 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index fa56032..43cb096 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1262,7 +1262,7 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->data->dev_flags = dev_flags;
 
 	/* reset device and negotiate default features */
-	ret = virtio_init_device(eth_dev, VIRTIO_PMD_GUEST_FEATURES);
+	ret = virtio_init_device(eth_dev, VIRTIO_PMD_DEFAULT_GUEST_FEATURES);
 	if (ret < 0)
 		return ret;
 
@@ -1351,13 +1351,10 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 	int ret;
 
 	PMD_INIT_LOG(DEBUG, "configure");
+	req_features = VIRTIO_PMD_DEFAULT_GUEST_FEATURES;
+	if (rxmode->hw_ip_checksum)
+		req_features |= (1ULL << VIRTIO_NET_F_GUEST_CSUM);
 
-	if (rxmode->hw_ip_checksum) {
-		PMD_DRV_LOG(ERR, "HW IP checksum not supported");
-		return -EINVAL;
-	}
-
-	req_features = VIRTIO_PMD_GUEST_FEATURES;
 	/* if request features changed, reinit the device */
 	if (req_features != hw->req_guest_features) {
 		ret = virtio_init_device(dev, req_features);
@@ -1578,6 +1575,9 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->default_txconf = (struct rte_eth_txconf) {
 		.txq_flags = ETH_TXQ_FLAGS_NOOFFLOADS
 	};
+	dev_info->rx_offload_capa =
+		DEV_RX_OFFLOAD_TCP_CKSUM |
+		DEV_RX_OFFLOAD_UDP_CKSUM;
 }
 
 /*
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index 5d5e788..2fc9218 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -54,7 +54,7 @@
 #define VIRTIO_MAX_RX_PKTLEN  9728
 
 /* Features desired/implemented by this driver. */
-#define VIRTIO_PMD_GUEST_FEATURES		\
+#define VIRTIO_PMD_DEFAULT_GUEST_FEATURES	\
 	(1u << VIRTIO_NET_F_MAC		  |	\
 	 1u << VIRTIO_NET_F_STATUS	  |	\
 	 1u << VIRTIO_NET_F_MQ		  |	\
diff --git a/drivers/net/virtio/virtio_rxtx.c b/drivers/net/virtio/virtio_rxtx.c
index 724517e..eda678a 100644
--- a/drivers/net/virtio/virtio_rxtx.c
+++ b/drivers/net/virtio/virtio_rxtx.c
@@ -50,6 +50,7 @@
 #include <rte_string_fns.h>
 #include <rte_errno.h>
 #include <rte_byteorder.h>
+#include <rte_net.h>
 
 #include "virtio_logs.h"
 #include "virtio_ethdev.h"
@@ -627,6 +628,56 @@ virtio_update_packet_stats(struct virtnet_stats *stats, struct rte_mbuf *mbuf)
 	}
 }
 
+/* Optionally fill offload information in structure */
+static int
+virtio_rx_offload(struct rte_mbuf *m, struct virtio_net_hdr *hdr)
+{
+	struct rte_net_hdr_lens hdr_lens;
+	uint32_t hdrlen, ptype;
+	int l4_supported = 0;
+
+	/* nothing to do */
+	if (hdr->flags == 0 && hdr->gso_type == VIRTIO_NET_HDR_GSO_NONE)
+		return 0;
+
+	m->ol_flags |= PKT_RX_IP_CKSUM_UNKNOWN;
+
+	ptype = rte_net_get_ptype(m, &hdr_lens, RTE_PTYPE_ALL_MASK);
+	m->packet_type = ptype;
+	if ((ptype & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_TCP ||
+	    (ptype & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_UDP ||
+	    (ptype & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_SCTP)
+		l4_supported = 1;
+
+	if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
+		hdrlen = hdr_lens.l2_len + hdr_lens.l3_len + hdr_lens.l4_len;
+		if (hdr->csum_start <= hdrlen && l4_supported) {
+			m->ol_flags |= PKT_RX_L4_CKSUM_NONE;
+		} else {
+			/* Unknown proto or tunnel, do sw cksum. We can assume
+			 * the cksum field is in the first segment since the
+			 * buffers we provided to the host are large enough.
+			 * In case of SCTP, this will be wrong since it's a CRC
+			 * but there's nothing we can do.
+			 */
+			uint16_t csum, off;
+
+			csum = rte_raw_cksum_mbuf(m, hdr->csum_start,
+				rte_pktmbuf_pkt_len(m) - hdr->csum_start);
+			if (csum != 0xffff)
+				csum = ~csum;
+			off = hdr->csum_offset + hdr->csum_start;
+			if (rte_pktmbuf_data_len(m) >= off + 1)
+				*rte_pktmbuf_mtod_offset(m, uint16_t *,
+					off) = csum;
+		}
+	} else if (hdr->flags & VIRTIO_NET_HDR_F_DATA_VALID && l4_supported) {
+		m->ol_flags |= PKT_RX_L4_CKSUM_GOOD;
+	}
+
+	return 0;
+}
+
 #define VIRTIO_MBUF_BURST_SZ 64
 #define DESC_PER_CACHELINE (RTE_CACHE_LINE_SIZE / sizeof(struct vring_desc))
 uint16_t
@@ -642,6 +693,7 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	int error;
 	uint32_t i, nb_enqueued;
 	uint32_t hdr_size;
+	struct virtio_net_hdr *hdr;
 
 	nb_used = VIRTQUEUE_NUSED(vq);
 
@@ -683,9 +735,19 @@ virtio_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		rxm->pkt_len = (uint32_t)(len[i] - hdr_size);
 		rxm->data_len = (uint16_t)(len[i] - hdr_size);
 
+		hdr = (struct virtio_net_hdr *)((char *)rxm->buf_addr +
+			RTE_PKTMBUF_HEADROOM - hdr_size);
+
 		if (hw->vlan_strip)
 			rte_vlan_strip(rxm);
 
+		/* Update offload features */
+		if (virtio_rx_offload(rxm, hdr) < 0) {
+			virtio_discard_rxbuf(vq, rxm);
+			rxvq->stats.errors++;
+			continue;
+		}
+
 		VIRTIO_DUMP_PACKET(rxm, rxm->data_len);
 
 		rx_pkts[nb_rx++] = rxm;
@@ -805,6 +867,13 @@ virtio_recv_mergeable_pkts(void *rx_queue,
 		rx_pkts[nb_rx] = rxm;
 		prev = rxm;
 
+		/* Update offload features */
+		if (virtio_rx_offload(rxm, &header->hdr) < 0) {
+			virtio_discard_rxbuf(vq, rxm);
+			rxvq->stats.errors++;
+			continue;
+		}
+
 		seg_res = seg_num - 1;
 
 		while (seg_res != 0) {
diff --git a/drivers/net/virtio/virtqueue.h b/drivers/net/virtio/virtqueue.h
index 6737b81..ef0027b 100644
--- a/drivers/net/virtio/virtqueue.h
+++ b/drivers/net/virtio/virtqueue.h
@@ -223,6 +223,7 @@ struct virtqueue {
  */
 struct virtio_net_hdr {
 #define VIRTIO_NET_HDR_F_NEEDS_CSUM 1    /**< Use csum_start,csum_offset*/
+#define VIRTIO_NET_HDR_F_DATA_VALID 2    /**< Checksum is valid */
 	uint8_t flags;
 #define VIRTIO_NET_HDR_GSO_NONE     0    /**< Not a GSO frame */
 #define VIRTIO_NET_HDR_GSO_TCPV4    1    /**< GSO frame, IPv4 TCP (TSO) */
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 08/12] app/testpmd: display lro segment size
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

In csumonly engine, display the value of LRO segment if the
LRO flag is set.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test-pmd/csumonly.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index 8c88ee8..3f71595 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -792,6 +792,8 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 				"l4_proto=%d l4_len=%d flags=%s\n",
 				info.l2_len, rte_be_to_cpu_16(info.ethertype),
 				info.l3_len, info.l4_proto, info.l4_len, buf);
+			if (rx_ol_flags & PKT_RX_LRO)
+				printf("rx: m->lro_segsz=%u\n", m->tso_segsz);
 			if (info.is_tunnel == 1)
 				printf("rx: outer_l2_len=%d outer_ethertype=%x "
 					"outer_l3_len=%d\n", info.outer_l2_len,
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 06/12] app/testpmd: fix checksum stats in csum engine
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

---
 app/test-pmd/csumonly.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c
index d5eb260..8c88ee8 100644
--- a/app/test-pmd/csumonly.c
+++ b/app/test-pmd/csumonly.c
@@ -679,8 +679,10 @@ pkt_burst_checksum_forward(struct fwd_stream *fs)
 		rx_ol_flags = m->ol_flags;
 
 		/* Update the L3/L4 checksum error packet statistics */
-		rx_bad_ip_csum += ((rx_ol_flags & PKT_RX_IP_CKSUM_BAD) != 0);
-		rx_bad_l4_csum += ((rx_ol_flags & PKT_RX_L4_CKSUM_BAD) != 0);
+		if ((rx_ol_flags & PKT_RX_IP_CKSUM_MASK) == PKT_RX_IP_CKSUM_BAD)
+			rx_bad_ip_csum += 1;
+		if ((rx_ol_flags & PKT_RX_L4_CKSUM_MASK) == PKT_RX_L4_CKSUM_BAD)
+			rx_bad_l4_csum += 1;
 
 		/* step 1: dissect packet, parsing optional vlan, ip4/ip6, vxlan
 		 * and inner headers */
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 07/12] mbuf: new flag for LRO
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

When receiving coalesced packets in virtio, the original size of the
segments is provided. This is a useful information because it allows to
resegment with the same size.

Add a RX new flag in mbuf, that can be set when packets are coalesced by
a hardware or virtual driver when the m->tso_segsz field is valid and is
set to the segment size of original packets.

This flag is used in next commits in the virtio pmd.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 doc/guides/rel_notes/release_16_11.rst | 5 +++++
 lib/librte_mbuf/rte_mbuf.c             | 2 ++
 lib/librte_mbuf/rte_mbuf.h             | 7 +++++++
 3 files changed, 14 insertions(+)

diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst
index 2aff84c..a8ad9ab 100644
--- a/doc/guides/rel_notes/release_16_11.rst
+++ b/doc/guides/rel_notes/release_16_11.rst
@@ -66,6 +66,11 @@ New Features
   good, bad, or not present (useful for virtual drivers). This modification
   was done for IP and L4.
 
+* **Added a LRO mbuf flag.**
+
+  Added a new RX LRO mbuf flag, used when packets are coalesced. This
+  flag indicates that the segment size of original packets is known.
+
 Resolved Issues
 ---------------
 
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index c55cb57..61bcd7e 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -317,6 +317,7 @@ const char *rte_get_rx_ol_flag_name(uint64_t mask)
 	case PKT_RX_IEEE1588_PTP: return "PKT_RX_IEEE1588_PTP";
 	case PKT_RX_IEEE1588_TMST: return "PKT_RX_IEEE1588_TMST";
 	case PKT_RX_QINQ_STRIPPED: return "PKT_RX_QINQ_STRIPPED";
+	case PKT_RX_LRO: return "PKT_RX_LRO";
 	default: return NULL;
 	}
 }
@@ -349,6 +350,7 @@ int rte_get_rx_ol_flag_list(uint64_t mask, char *buf, size_t buflen)
 		{ PKT_RX_IEEE1588_PTP, PKT_RX_IEEE1588_PTP, NULL },
 		{ PKT_RX_IEEE1588_TMST, PKT_RX_IEEE1588_TMST, NULL },
 		{ PKT_RX_QINQ_STRIPPED, PKT_RX_QINQ_STRIPPED, NULL },
+		{ PKT_RX_LRO, PKT_RX_LRO, NULL },
 	};
 	const char *name;
 	unsigned int i;
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 7061cfc..f9d7bfa 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -170,6 +170,13 @@ extern "C" {
  */
 #define PKT_RX_QINQ_PKT      PKT_RX_QINQ_STRIPPED
 
+/**
+ * When packets are coalesced by a hardware or virtual driver, this flag
+ * can be set in the RX mbuf, meaning that the m->tso_segsz field is
+ * valid and is set to the segment size of original packets.
+ */
+#define PKT_RX_LRO           (1ULL << 16)
+
 /* add new RX flags here */
 
 /* add new TX flags here */
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 05/12] mbuf: add new Rx checksum mbuf flags
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

Following discussions in [1] and [2], introduce a new bit to
describe the Rx checksum status in mbuf.

Before this patch, only one flag was available:
  PKT_RX_L4_CKSUM_BAD: L4 cksum of RX pkt. is not OK.

And same for L3:
  PKT_RX_IP_CKSUM_BAD: IP cksum of RX pkt. is not OK.

This had 2 issues:
- it was not possible to differentiate "checksum good" from
  "checksum unknown".
- it was not possible for a virtual driver to say "the checksum
  in packet may be wrong, but data integrity is valid".

This patch tries to solve this issue by having 4 states (2 bits)
for the IP and L4 Rx checksums. New values are:

 - PKT_RX_L4_CKSUM_UNKNOWN: no information about the RX L4 checksum
   -> the application should verify the checksum by sw
 - PKT_RX_L4_CKSUM_BAD: the L4 checksum in the packet is wrong
   -> the application can drop the packet without additional check
 - PKT_RX_L4_CKSUM_GOOD: the L4 checksum in the packet is valid
   -> the application can accept the packet without verifying the
      checksum by sw
 - PKT_RX_L4_CKSUM_NONE: the L4 checksum is not correct in the packet
   data, but the integrity of the L4 data is verified.
   -> the application can process the packet but must not verify the
      checksum by sw. It has to take care to recalculate the cksum
      if the packet is transmitted (either by sw or using tx offload)

  And same for L3 (replace L4 by IP in description above).

This commit tries to be compatible with existing applications that
only check the existing flag (CKSUM_BAD).

[1] http://dpdk.org/ml/archives/dev/2016-May/039920.html
[2] http://dpdk.org/ml/archives/dev/2016-June/040007.html

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 doc/guides/rel_notes/release_16_11.rst |  6 ++++
 lib/librte_mbuf/rte_mbuf.c             | 16 +++++++++--
 lib/librte_mbuf/rte_mbuf.h             | 51 ++++++++++++++++++++++++++++++++--
 3 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst
index f29b44c..2aff84c 100644
--- a/doc/guides/rel_notes/release_16_11.rst
+++ b/doc/guides/rel_notes/release_16_11.rst
@@ -60,6 +60,12 @@ New Features
   Added a new function ``rte_raw_cksum_mbuf()`` to process the checksum of
   data embedded in an mbuf chain.
 
+* **Added new Rx checksum mbuf flags.**
+
+  Added new Rx checksum flags in mbufs to described more states: unknown,
+  good, bad, or not present (useful for virtual drivers). This modification
+  was done for IP and L4.
+
 Resolved Issues
 ---------------
 
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index bd5bd48..c55cb57 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -307,7 +307,11 @@ const char *rte_get_rx_ol_flag_name(uint64_t mask)
 	case PKT_RX_RSS_HASH: return "PKT_RX_RSS_HASH";
 	case PKT_RX_FDIR: return "PKT_RX_FDIR";
 	case PKT_RX_L4_CKSUM_BAD: return "PKT_RX_L4_CKSUM_BAD";
+	case PKT_RX_L4_CKSUM_GOOD: return "PKT_RX_L4_CKSUM_GOOD";
+	case PKT_RX_L4_CKSUM_NONE: return "PKT_RX_L4_CKSUM_NONE";
 	case PKT_RX_IP_CKSUM_BAD: return "PKT_RX_IP_CKSUM_BAD";
+	case PKT_RX_IP_CKSUM_GOOD: return "PKT_RX_IP_CKSUM_GOOD";
+	case PKT_RX_IP_CKSUM_NONE: return "PKT_RX_IP_CKSUM_NONE";
 	case PKT_RX_EIP_CKSUM_BAD: return "PKT_RX_EIP_CKSUM_BAD";
 	case PKT_RX_VLAN_STRIPPED: return "PKT_RX_VLAN_STRIPPED";
 	case PKT_RX_IEEE1588_PTP: return "PKT_RX_IEEE1588_PTP";
@@ -330,8 +334,16 @@ int rte_get_rx_ol_flag_list(uint64_t mask, char *buf, size_t buflen)
 		{ PKT_RX_VLAN_PKT, PKT_RX_VLAN_PKT, NULL },
 		{ PKT_RX_RSS_HASH, PKT_RX_RSS_HASH, NULL },
 		{ PKT_RX_FDIR, PKT_RX_FDIR, NULL },
-		{ PKT_RX_L4_CKSUM_BAD, PKT_RX_L4_CKSUM_BAD, NULL },
-		{ PKT_RX_IP_CKSUM_BAD, PKT_RX_IP_CKSUM_BAD, NULL },
+		{ PKT_RX_L4_CKSUM_BAD, PKT_RX_L4_CKSUM_MASK, NULL },
+		{ PKT_RX_L4_CKSUM_GOOD, PKT_RX_L4_CKSUM_MASK, NULL },
+		{ PKT_RX_L4_CKSUM_NONE, PKT_RX_L4_CKSUM_MASK, NULL },
+		{ PKT_RX_L4_CKSUM_UNKNOWN, PKT_RX_L4_CKSUM_MASK,
+		  "PKT_RX_L4_CKSUM_UNKNOWN" },
+		{ PKT_RX_IP_CKSUM_BAD, PKT_RX_IP_CKSUM_MASK, NULL },
+		{ PKT_RX_IP_CKSUM_GOOD, PKT_RX_IP_CKSUM_MASK, NULL },
+		{ PKT_RX_IP_CKSUM_NONE, PKT_RX_IP_CKSUM_MASK, NULL },
+		{ PKT_RX_IP_CKSUM_UNKNOWN, PKT_RX_IP_CKSUM_MASK,
+		  "PKT_RX_IP_CKSUM_UNKNOWN" },
 		{ PKT_RX_EIP_CKSUM_BAD, PKT_RX_EIP_CKSUM_BAD, NULL },
 		{ PKT_RX_VLAN_STRIPPED, PKT_RX_VLAN_STRIPPED, NULL },
 		{ PKT_RX_IEEE1588_PTP, PKT_RX_IEEE1588_PTP, NULL },
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index 5e349e7..7061cfc 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -91,8 +91,25 @@ extern "C" {
 
 #define PKT_RX_RSS_HASH      (1ULL << 1)  /**< RX packet with RSS hash result. */
 #define PKT_RX_FDIR          (1ULL << 2)  /**< RX packet with FDIR match indicate. */
-#define PKT_RX_L4_CKSUM_BAD  (1ULL << 3)  /**< L4 cksum of RX pkt. is not OK. */
-#define PKT_RX_IP_CKSUM_BAD  (1ULL << 4)  /**< IP cksum of RX pkt. is not OK. */
+
+/**
+ * Deprecated.
+ * Checking this flag alone is deprecated: check the 2 bits of
+ * PKT_RX_L4_CKSUM_MASK.
+ * This flag was set when the L4 checksum of a packet was detected as
+ * wrong by the hardware.
+ */
+#define PKT_RX_L4_CKSUM_BAD  (1ULL << 3)
+
+/**
+ * Deprecated.
+ * Checking this flag alone is deprecated: check the 2 bits of
+ * PKT_RX_IP_CKSUM_MASK.
+ * This flag was set when the IP checksum of a packet was detected as
+ * wrong by the hardware.
+ */
+#define PKT_RX_IP_CKSUM_BAD  (1ULL << 4)
+
 #define PKT_RX_EIP_CKSUM_BAD (1ULL << 5)  /**< External IP header checksum error. */
 
 /**
@@ -102,7 +119,35 @@ extern "C" {
  */
 #define PKT_RX_VLAN_STRIPPED (1ULL << 6)
 
-/* hole, some bits can be reused here  */
+/**
+ * Mask of bits used to determine the status of RX IP checksum.
+ * - PKT_RX_IP_CKSUM_UNKNOWN: no information about the RX IP checksum
+ * - PKT_RX_IP_CKSUM_BAD: the IP checksum in the packet is wrong
+ * - PKT_RX_IP_CKSUM_GOOD: the IP checksum in the packet is valid
+ * - PKT_RX_IP_CKSUM_NONE: the IP checksum is not correct in the packet
+ *   data, but the integrity of the IP header is verified.
+ */
+#define PKT_RX_IP_CKSUM_MASK ((1ULL << 4) | (1ULL << 7))
+
+#define PKT_RX_IP_CKSUM_UNKNOWN 0
+#define PKT_RX_IP_CKSUM_BAD     (1ULL << 4)
+#define PKT_RX_IP_CKSUM_GOOD    (1ULL << 7)
+#define PKT_RX_IP_CKSUM_NONE    ((1ULL << 4) | (1ULL << 7))
+
+/**
+ * Mask of bits used to determine the status of RX L4 checksum.
+ * - PKT_RX_L4_CKSUM_UNKNOWN: no information about the RX L4 checksum
+ * - PKT_RX_L4_CKSUM_BAD: the L4 checksum in the packet is wrong
+ * - PKT_RX_L4_CKSUM_GOOD: the L4 checksum in the packet is valid
+ * - PKT_RX_L4_CKSUM_NONE: the L4 checksum is not correct in the packet
+ *   data, but the integrity of the L4 data is verified.
+ */
+#define PKT_RX_L4_CKSUM_MASK ((1ULL << 3) | (1ULL << 8))
+
+#define PKT_RX_L4_CKSUM_UNKNOWN 0
+#define PKT_RX_L4_CKSUM_BAD     (1ULL << 3)
+#define PKT_RX_L4_CKSUM_GOOD    (1ULL << 8)
+#define PKT_RX_L4_CKSUM_NONE    ((1ULL << 3) | (1ULL << 8))
 
 #define PKT_RX_IEEE1588_PTP  (1ULL << 9)  /**< RX IEEE1588 L2 Ethernet PT Packet. */
 #define PKT_RX_IEEE1588_TMST (1ULL << 10) /**< RX IEEE1588 L2/L4 timestamped packet.*/
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 03/12] virtio: reinitialize the device in configure callback
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

Add the ability to reset the virtio device in the configure callback
if the features flag changed since previous reset. This will be possible
with the introduction of offload support in next commits.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 drivers/net/virtio/virtio_ethdev.c | 26 +++++++++++++++++++-------
 drivers/net/virtio/virtio_pci.h    |  1 +
 2 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index b1056a1..fa56032 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1045,14 +1045,13 @@ virtio_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 }
 
 static int
-virtio_negotiate_features(struct virtio_hw *hw)
+virtio_negotiate_features(struct virtio_hw *hw, uint64_t req_features)
 {
 	uint64_t host_features;
 
 	/* Prepare guest_features: feature that driver wants to support */
-	hw->guest_features = VIRTIO_PMD_GUEST_FEATURES;
 	PMD_INIT_LOG(DEBUG, "guest_features before negotiate = %" PRIx64,
-		hw->guest_features);
+		req_features);
 
 	/* Read device(host) feature bits */
 	host_features = hw->vtpci_ops->get_features(hw);
@@ -1063,6 +1062,7 @@ virtio_negotiate_features(struct virtio_hw *hw)
 	 * Negotiate features: Subset of device feature bits are written back
 	 * guest feature bits.
 	 */
+	hw->guest_features = req_features;
 	hw->guest_features = vtpci_negotiate_features(hw, host_features);
 	PMD_INIT_LOG(DEBUG, "features after negotiate = %" PRIx64,
 		hw->guest_features);
@@ -1081,6 +1081,8 @@ virtio_negotiate_features(struct virtio_hw *hw)
 		}
 	}
 
+	hw->req_guest_features = req_features;
+
 	return 0;
 }
 
@@ -1121,8 +1123,9 @@ rx_func_get(struct rte_eth_dev *eth_dev)
 		eth_dev->rx_pkt_burst = &virtio_recv_pkts;
 }
 
+/* reset device and renegotiate features if needed */
 static int
-virtio_init_device(struct rte_eth_dev *eth_dev)
+virtio_init_device(struct rte_eth_dev *eth_dev, uint64_t req_features)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
 	struct virtio_net_config *config;
@@ -1137,7 +1140,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev)
 
 	/* Tell the host we've known how to drive the device. */
 	vtpci_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
-	if (virtio_negotiate_features(hw) < 0)
+	if (virtio_negotiate_features(hw, req_features) < 0)
 		return -1;
 
 	/* If host does not support status then disable LSC */
@@ -1258,8 +1261,8 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 
 	eth_dev->data->dev_flags = dev_flags;
 
-	/* reset device and negotiate features */
-	ret = virtio_init_device(eth_dev);
+	/* reset device and negotiate default features */
+	ret = virtio_init_device(eth_dev, VIRTIO_PMD_GUEST_FEATURES);
 	if (ret < 0)
 		return ret;
 
@@ -1344,6 +1347,7 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 {
 	const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
 	struct virtio_hw *hw = dev->data->dev_private;
+	uint64_t req_features;
 	int ret;
 
 	PMD_INIT_LOG(DEBUG, "configure");
@@ -1353,6 +1357,14 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
+	req_features = VIRTIO_PMD_GUEST_FEATURES;
+	/* if request features changed, reinit the device */
+	if (req_features != hw->req_guest_features) {
+		ret = virtio_init_device(dev, req_features);
+		if (ret < 0)
+			return ret;
+	}
+
 	/* Setup and start control queue */
 	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
 		ret = virtio_dev_cq_queue_setup(dev,
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index 552166d..d1a7d1e 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -245,6 +245,7 @@ struct virtio_net_config;
 struct virtio_hw {
 	struct virtnet_ctl *cvq;
 	struct rte_pci_ioport io;
+	uint64_t    req_guest_features;
 	uint64_t    guest_features;
 	uint32_t    max_queue_pairs;
 	uint16_t    vtnet_hdr_size;
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 02/12] virtio: setup and start cq in configure callback
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

Move the configuration of control queue in the configure callback.
This is needed by next commit, which introduces the reinitialization
of the device in the configure callback to change the feature flags.
Therefore, the control queue will have to be restarted at the same
place.

As virtio_dev_cq_queue_setup() is called from a place where
config->max_virtqueue_pairs is not available, we need to store this in
the private structure. It replaces max_rx_queues and max_tx_queues which
have the same value. The log showing the value of max_rx_queues and
max_tx_queues is also removed since config->max_virtqueue_pairs is
already displayed above.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 drivers/net/virtio/virtio_ethdev.c | 43 +++++++++++++++++++-------------------
 drivers/net/virtio/virtio_ethdev.h |  4 ++--
 drivers/net/virtio/virtio_pci.h    |  3 +--
 3 files changed, 24 insertions(+), 26 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 21ed945..b1056a1 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -552,6 +552,9 @@ virtio_dev_close(struct rte_eth_dev *dev)
 	if (hw->started == 1)
 		virtio_dev_stop(dev);
 
+	if (hw->cvq)
+		virtio_dev_queue_release(hw->cvq->vq);
+
 	/* reset the NIC */
 	if (dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
 		vtpci_irq_config(hw, VIRTIO_MSI_NO_VECTOR);
@@ -1191,16 +1194,7 @@ virtio_init_device(struct rte_eth_dev *eth_dev)
 			config->max_virtqueue_pairs = 1;
 		}
 
-		hw->max_rx_queues =
-			(VIRTIO_MAX_RX_QUEUES < config->max_virtqueue_pairs) ?
-			VIRTIO_MAX_RX_QUEUES : config->max_virtqueue_pairs;
-		hw->max_tx_queues =
-			(VIRTIO_MAX_TX_QUEUES < config->max_virtqueue_pairs) ?
-			VIRTIO_MAX_TX_QUEUES : config->max_virtqueue_pairs;
-
-		virtio_dev_cq_queue_setup(eth_dev,
-					config->max_virtqueue_pairs * 2,
-					SOCKET_ID_ANY);
+		hw->max_queue_pairs = config->max_virtqueue_pairs;
 
 		PMD_INIT_LOG(DEBUG, "config->max_virtqueue_pairs=%d",
 				config->max_virtqueue_pairs);
@@ -1211,19 +1205,15 @@ virtio_init_device(struct rte_eth_dev *eth_dev)
 				config->mac[2], config->mac[3],
 				config->mac[4], config->mac[5]);
 	} else {
-		hw->max_rx_queues = 1;
-		hw->max_tx_queues = 1;
+		PMD_INIT_LOG(DEBUG, "config->max_virtqueue_pairs=1");
+		hw->max_queue_pairs = 1;
 	}
 
-	PMD_INIT_LOG(DEBUG, "hw->max_rx_queues=%d   hw->max_tx_queues=%d",
-			hw->max_rx_queues, hw->max_tx_queues);
 	if (pci_dev)
 		PMD_INIT_LOG(DEBUG, "port %d vendorID=0x%x deviceID=0x%x",
 			eth_dev->data->port_id, pci_dev->id.vendor_id,
 			pci_dev->id.device_id);
 
-	virtio_dev_cq_start(eth_dev);
-
 	return 0;
 }
 
@@ -1285,7 +1275,6 @@ static int
 eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 {
 	struct rte_pci_device *pci_dev;
-	struct virtio_hw *hw = eth_dev->data->dev_private;
 
 	PMD_INIT_FUNC_TRACE();
 
@@ -1301,9 +1290,6 @@ eth_virtio_dev_uninit(struct rte_eth_dev *eth_dev)
 	eth_dev->tx_pkt_burst = NULL;
 	eth_dev->rx_pkt_burst = NULL;
 
-	if (hw->cvq)
-		virtio_dev_queue_release(hw->cvq->vq);
-
 	rte_free(eth_dev->data->mac_addrs);
 	eth_dev->data->mac_addrs = NULL;
 
@@ -1358,6 +1344,7 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 {
 	const struct rte_eth_rxmode *rxmode = &dev->data->dev_conf.rxmode;
 	struct virtio_hw *hw = dev->data->dev_private;
+	int ret;
 
 	PMD_INIT_LOG(DEBUG, "configure");
 
@@ -1366,6 +1353,16 @@ virtio_dev_configure(struct rte_eth_dev *dev)
 		return -EINVAL;
 	}
 
+	/* Setup and start control queue */
+	if (vtpci_with_feature(hw, VIRTIO_NET_F_CTRL_VQ)) {
+		ret = virtio_dev_cq_queue_setup(dev,
+			hw->max_queue_pairs * 2,
+			SOCKET_ID_ANY);
+		if (ret < 0)
+			return ret;
+		virtio_dev_cq_start(dev);
+	}
+
 	hw->vlan_strip = rxmode->hw_vlan_strip;
 
 	if (rxmode->hw_vlan_filter
@@ -1559,8 +1556,10 @@ virtio_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 		dev_info->driver_name = dev->driver->pci_drv.name;
 	else
 		dev_info->driver_name = "virtio_user PMD";
-	dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
-	dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
+	dev_info->max_rx_queues =
+		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_RX_QUEUES);
+	dev_info->max_tx_queues =
+		RTE_MIN(hw->max_queue_pairs, VIRTIO_MAX_TX_QUEUES);
 	dev_info->min_rx_bufsize = VIRTIO_MIN_RX_BUFSIZE;
 	dev_info->max_rx_pktlen = VIRTIO_MAX_RX_PKTLEN;
 	dev_info->max_mac_addrs = VIRTIO_MAX_MAC_ADDRS;
diff --git a/drivers/net/virtio/virtio_ethdev.h b/drivers/net/virtio/virtio_ethdev.h
index 2ecec6e..5d5e788 100644
--- a/drivers/net/virtio/virtio_ethdev.h
+++ b/drivers/net/virtio/virtio_ethdev.h
@@ -47,8 +47,8 @@
 #define PAGE_SIZE 4096
 #endif
 
-#define VIRTIO_MAX_RX_QUEUES 128
-#define VIRTIO_MAX_TX_QUEUES 128
+#define VIRTIO_MAX_RX_QUEUES 128U
+#define VIRTIO_MAX_TX_QUEUES 128U
 #define VIRTIO_MAX_MAC_ADDRS 64
 #define VIRTIO_MIN_RX_BUFSIZE 64
 #define VIRTIO_MAX_RX_PKTLEN  9728
diff --git a/drivers/net/virtio/virtio_pci.h b/drivers/net/virtio/virtio_pci.h
index dd7693f..552166d 100644
--- a/drivers/net/virtio/virtio_pci.h
+++ b/drivers/net/virtio/virtio_pci.h
@@ -246,8 +246,7 @@ struct virtio_hw {
 	struct virtnet_ctl *cvq;
 	struct rte_pci_ioport io;
 	uint64_t    guest_features;
-	uint32_t    max_tx_queues;
-	uint32_t    max_rx_queues;
+	uint32_t    max_queue_pairs;
 	uint16_t    vtnet_hdr_size;
 	uint8_t	    vlan_strip;
 	uint8_t	    use_msix;
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 04/12] net: add function to calculate a checksum in a mbuf
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

This function can be used to calculate the checksum of data embedded in
mbuf, that can be composed of several segments.

This function will be used by the virtio pmd in next commits to calculate
the checksum in software in case the protocol is not recognized.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 doc/guides/rel_notes/release_16_11.rst |  5 +++
 lib/librte_net/rte_ip.h                | 60 ++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git a/doc/guides/rel_notes/release_16_11.rst b/doc/guides/rel_notes/release_16_11.rst
index 3d3c417..f29b44c 100644
--- a/doc/guides/rel_notes/release_16_11.rst
+++ b/doc/guides/rel_notes/release_16_11.rst
@@ -55,6 +55,11 @@ New Features
   Added two new functions ``rte_get_rx_ol_flag_list()`` and
   ``rte_get_tx_ol_flag_list()`` to dump offload flags as a string.
 
+* **Added a functions to calculate the checksum of data in a mbuf.**
+
+  Added a new function ``rte_raw_cksum_mbuf()`` to process the checksum of
+  data embedded in an mbuf chain.
+
 Resolved Issues
 ---------------
 
diff --git a/lib/librte_net/rte_ip.h b/lib/librte_net/rte_ip.h
index 5b7554a..8499356 100644
--- a/lib/librte_net/rte_ip.h
+++ b/lib/librte_net/rte_ip.h
@@ -230,6 +230,66 @@ rte_raw_cksum(const void *buf, size_t len)
 }
 
 /**
+ * Compute the raw (non complemented) checksum of a packet.
+ *
+ * @param m
+ *   The pointer to the mbuf.
+ * @param off
+ *   The offset in bytes to start the checksum.
+ * @param len
+ *   The length in bytes of the data to ckecksum.
+ */
+static inline uint16_t
+rte_raw_cksum_mbuf(const struct rte_mbuf *m, uint32_t off, uint32_t len)
+{
+	const struct rte_mbuf *seg;
+	const char *buf;
+	uint32_t sum, tmp;
+	uint32_t seglen, done;
+
+	/* easy case: all data in the first segment */
+	if (off + len <= rte_pktmbuf_data_len(m))
+		return rte_raw_cksum(rte_pktmbuf_mtod_offset(m,
+				const char *, off), len);
+
+	if (off + len > rte_pktmbuf_pkt_len(m))
+		return 0; /* invalid params, return a dummy value */
+
+	/* else browse the segment to find offset */
+	seglen = 0;
+	for (seg = m; seg != NULL; seg = seg->next) {
+		seglen = rte_pktmbuf_data_len(seg);
+		if (off < seglen)
+			break;
+		off -= seglen;
+	}
+	seglen -= off;
+	buf = rte_pktmbuf_mtod_offset(seg, const char *, off);
+	if (seglen >= len) /* all in one segment */
+		return rte_raw_cksum(buf, len);
+
+	/* hard case: process checksum of several segments */
+	sum = 0;
+	done = 0;
+	for (;;) {
+		tmp = __rte_raw_cksum(buf, seglen, 0);
+		if (done & 1)
+			tmp = rte_bswap16(tmp);
+		sum += tmp;
+		done += seglen;
+		if (done == len)
+			break;
+		seg = seg->next;
+		buf = rte_pktmbuf_mtod(seg, const char *);
+		seglen = rte_pktmbuf_data_len(seg);
+		if (seglen > len - done)
+			seglen = len - done;
+	}
+
+	return __rte_raw_cksum_reduce(sum);
+}
+
+/**
  * Process the IPv4 checksum of an IPv4 header.
  *
  * The checksum field must be set to 0 by the caller.
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 01/12] virtio: move device initialization in a function
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1475485223-30566-1-git-send-email-olivier.matz@6wind.com>

Move all code related to device initialization in a new function
virtio_init_device().

This commit brings no functional change, it prepares the next commits
that will add the offload support. For that, it will be needed to
reinitialize the device from ethdev->configure(), using this new
function.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 drivers/net/virtio/virtio_ethdev.c | 99 ++++++++++++++++++++++----------------
 1 file changed, 58 insertions(+), 41 deletions(-)

diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index ef0d6ee..21ed945 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1118,46 +1118,13 @@ rx_func_get(struct rte_eth_dev *eth_dev)
 		eth_dev->rx_pkt_burst = &virtio_recv_pkts;
 }
 
-/*
- * This function is based on probe() function in virtio_pci.c
- * It returns 0 on success.
- */
-int
-eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
+static int
+virtio_init_device(struct rte_eth_dev *eth_dev)
 {
 	struct virtio_hw *hw = eth_dev->data->dev_private;
 	struct virtio_net_config *config;
 	struct virtio_net_config local_config;
-	struct rte_pci_device *pci_dev;
-	uint32_t dev_flags = RTE_ETH_DEV_DETACHABLE;
-	int ret;
-
-	RTE_BUILD_BUG_ON(RTE_PKTMBUF_HEADROOM < sizeof(struct virtio_net_hdr_mrg_rxbuf));
-
-	eth_dev->dev_ops = &virtio_eth_dev_ops;
-	eth_dev->tx_pkt_burst = &virtio_xmit_pkts;
-
-	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
-		rx_func_get(eth_dev);
-		return 0;
-	}
-
-	/* Allocate memory for storing MAC addresses */
-	eth_dev->data->mac_addrs = rte_zmalloc("virtio", VIRTIO_MAX_MAC_ADDRS * ETHER_ADDR_LEN, 0);
-	if (eth_dev->data->mac_addrs == NULL) {
-		PMD_INIT_LOG(ERR,
-			"Failed to allocate %d bytes needed to store MAC addresses",
-			VIRTIO_MAX_MAC_ADDRS * ETHER_ADDR_LEN);
-		return -ENOMEM;
-	}
-
-	pci_dev = eth_dev->pci_dev;
-
-	if (pci_dev) {
-		ret = vtpci_init(pci_dev, hw, &dev_flags);
-		if (ret)
-			return ret;
-	}
+	struct rte_pci_device *pci_dev = eth_dev->pci_dev;
 
 	/* Reset the device although not necessary at startup */
 	vtpci_reset(hw);
@@ -1172,10 +1139,11 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 
 	/* If host does not support status then disable LSC */
 	if (!vtpci_with_feature(hw, VIRTIO_NET_F_STATUS))
-		dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
+		eth_dev->data->dev_flags &= ~RTE_ETH_DEV_INTR_LSC;
+	else
+		eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
-	eth_dev->data->dev_flags = dev_flags;
 
 	rx_func_get(eth_dev);
 
@@ -1254,12 +1222,61 @@ eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
 			eth_dev->data->port_id, pci_dev->id.vendor_id,
 			pci_dev->id.device_id);
 
+	virtio_dev_cq_start(eth_dev);
+
+	return 0;
+}
+
+/*
+ * This function is based on probe() function in virtio_pci.c
+ * It returns 0 on success.
+ */
+int
+eth_virtio_dev_init(struct rte_eth_dev *eth_dev)
+{
+	struct virtio_hw *hw = eth_dev->data->dev_private;
+	struct rte_pci_device *pci_dev;
+	uint32_t dev_flags = RTE_ETH_DEV_DETACHABLE;
+	int ret;
+
+	RTE_BUILD_BUG_ON(RTE_PKTMBUF_HEADROOM < sizeof(struct virtio_net_hdr_mrg_rxbuf));
+
+	eth_dev->dev_ops = &virtio_eth_dev_ops;
+	eth_dev->tx_pkt_burst = &virtio_xmit_pkts;
+
+	if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+		rx_func_get(eth_dev);
+		return 0;
+	}
+
+	/* Allocate memory for storing MAC addresses */
+	eth_dev->data->mac_addrs = rte_zmalloc("virtio", VIRTIO_MAX_MAC_ADDRS * ETHER_ADDR_LEN, 0);
+	if (eth_dev->data->mac_addrs == NULL) {
+		PMD_INIT_LOG(ERR,
+			"Failed to allocate %d bytes needed to store MAC addresses",
+			VIRTIO_MAX_MAC_ADDRS * ETHER_ADDR_LEN);
+		return -ENOMEM;
+	}
+
+	pci_dev = eth_dev->pci_dev;
+
+	if (pci_dev) {
+		ret = vtpci_init(pci_dev, hw, &dev_flags);
+		if (ret)
+			return ret;
+	}
+
+	eth_dev->data->dev_flags = dev_flags;
+
+	/* reset device and negotiate features */
+	ret = virtio_init_device(eth_dev);
+	if (ret < 0)
+		return ret;
+
 	/* Setup interrupt callback  */
 	if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC)
 		rte_intr_callback_register(&pci_dev->intr_handle,
-				   virtio_interrupt_handler, eth_dev);
-
-	virtio_dev_cq_start(eth_dev);
+			virtio_interrupt_handler, eth_dev);
 
 	return 0;
 }
-- 
2.8.1

^ permalink raw reply related

* [PATCH v2 00/12] net/virtio: add offload support
From: Olivier Matz @ 2016-10-03  9:00 UTC (permalink / raw)
  To: dev, yuanhan.liu
  Cc: konstantin.ananyev, sugesh.chandran, bruce.richardson,
	jianfeng.tan, helin.zhang, adrien.mazarguil, stephen, dprovan,
	xiao.w.wang
In-Reply-To: <1469088510-7552-1-git-send-email-olivier.matz@6wind.com>

This patchset, targetted for 16.11, introduces the support of rx and tx
offload in virtio pmd.  To achieve this, some new mbuf flags must be
introduced, as discussed in [1].

It applies on top of:
- software packet type [2]
- testpmd enhancements [3]

The new mbuf checksum flags are backward compatible for current
applications that assume that unknown_csum = good_cum (since there
was only a bad_csum flag). But it the patchset is integrated, we
should consider updating the PMDs to match the new API for 16.11.

[1] http://dpdk.org/ml/archives/dev/2016-May/039920.html
[2] http://dpdk.org/ml/archives/dev/2016-October/048073.html
[3] http://dpdk.org/ml/archives/dev/2016-September/046443.html

changes v1 -> v2
- change mbuf checksum calculation static inline
- fix checksum calculation for protocol where csum=0 means no csum
- move mbuf checksum calculation in librte_net
- use RTE_MIN() to set max rx/tx queue
- rebase on top of head

Olivier Matz (12):
  virtio: move device initialization in a function
  virtio: setup and start cq in configure callback
  virtio: reinitialize the device in configure callback
  net: add function to calculate a checksum in a mbuf
  mbuf: add new Rx checksum mbuf flags
  app/testpmd: fix checksum stats in csum engine
  mbuf: new flag for LRO
  app/testpmd: display lro segment size
  virtio: add Rx checksum offload support
  virtio: add Tx checksum offload support
  virtio: add Lro support
  virtio: add Tso support

 app/test-pmd/csumonly.c                |   8 +-
 doc/guides/rel_notes/release_16_11.rst |  16 ++
 drivers/net/virtio/virtio_ethdev.c     | 182 +++++++++++++---------
 drivers/net/virtio/virtio_ethdev.h     |  18 +--
 drivers/net/virtio/virtio_pci.h        |   4 +-
 drivers/net/virtio/virtio_rxtx.c       | 270 ++++++++++++++++++++++++++++++---
 drivers/net/virtio/virtqueue.h         |   1 +
 lib/librte_mbuf/rte_mbuf.c             |  18 ++-
 lib/librte_mbuf/rte_mbuf.h             |  58 ++++++-
 lib/librte_net/rte_ip.h                |  60 ++++++++
 10 files changed, 526 insertions(+), 109 deletions(-)

Test plan
=========

(not fully replayed on v2, but no major change)

Platform description
--------------------

  guest (dpdk)
  +----------------+
  |                |
  |                |
  |         port0  +-----<---+
  |       ixgbe /  |         |
  |       directio |         |
  |                |         |
  |    port1       |         ^ flow1
  +----------------+         | (flow2 is the reverse)
         |                   |
         | virtio            |
         v                   |
  +----------------+         |
  |     tap0   /   |         |
  |1.1.1.1   /     |         |
  |ns-tap  /       |         |
  |      /         |         |
  |    /   ixgbe2  +------>--+
  |  /    1.1.1.2  |
  |/      ns-ixgbe |
  +----------------+
  host (linux, vhost-net)


flow1:
  host -(ixgbe)-> guest -(virtio)-> host
  1.1.1.2 -> 1.1.1.1

flow2:
  host -(virtio)-> guest -(ixgbe)-> host
  1.1.1.2 -> 1.1.1.1

Host configuration
------------------

Start qemu with:

- a ne2k management interface to avoi any conflict with dpdk
- 2 ixgbe interfaces given to with vm through vfio
- a virtio net device, connected to a tap interface through vhost-net

  /usr/bin/qemu-system-x86_64 -k fr -daemonize --enable-kvm -m 1G -cpu host \
    -smp 3 -serial telnet::40564,server,nowait -serial null \
    -qmp tcp::44340,server,nowait -monitor telnet::49229,server,nowait \
    -device ne2k_pci,mac=de:ad:de:01:02:03,netdev=user.0,addr=03 \
    -netdev user,id=user.0,hostfwd=tcp::34965-:22 \
    -device vfio-pci,host=0000:04:00.0 -device vfio-pci,host=0000:04:00.1 \
    -netdev type=tap,id=vhostnet0,script=no,vhost=on,queues=8 \
    -device virtio-net-pci,netdev=vhostnet0,ioeventfd=on,mq=on,vectors=17 \
    -hda "/path/to/ubuntu-14.04-template.qcow2" \
    -snapshot -vga none -display none

Move the tap interface in a netns, and configure it:

  ip netns add ns-tap
  ip netns exec ns-tap ip l set lo up
  ip link set tap0 netns ns-tap
  ip netns exec ns-tap ip l set tap0 down
  ip netns exec ns-tap ip l set addr 02:00:00:00:00:01 dev tap0
  ip netns exec ns-tap ip l set tap0 up
  ip netns exec ns-tap ip a a 1.1.1.1/24 dev tap0
  ip netns exec ns-tap arp -s 1.1.1.2 02:00:00:00:00:00
  ip netns exec ns-tap ip a

Move the ixgbe interface in a netns, and configure it:

  IXGBE=ixgbe2
  ip netns add ns-ixgbe
  ip netns exec ns-ixgbe ip l set lo up
  ip link set ${IXGBE} netns ns-ixgbe
  ip netns exec ns-ixgbe ip l set ${IXGBE} down
  ip netns exec ns-ixgbe ip l set addr 02:00:00:00:00:00 dev ${IXGBE}
  ip netns exec ns-ixgbe ip l set ${IXGBE} up
  ip netns exec ns-ixgbe ip a a 1.1.1.2/24 dev ${IXGBE}
  ip netns exec ns-ixgbe arp -s 1.1.1.1 02:00:00:00:00:01
  ip netns exec ns-ixgbe ip a

Guest configuration
-------------------

List of pci devices:

  00:02.0 Ethernet controller [0200]: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection [8086:10fb] (rev 01)
  00:03.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL-8029(AS) [10ec:8029]
  00:04.0 Ethernet controller [0200]: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection [8086:10fb] (rev 01)
  00:05.0 Ethernet controller [0200]: Red Hat, Inc Virtio network device [1af4:1000]

Compile dpdk:

  cd dpdk.org
  make config T=x86_64-native-linuxapp-gcc
  make -j4

Prepare environment:

  mkdir -p /mnt/huge
  mount -t hugetlbfs nodev /mnt/huge
  echo 256 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
  modprobe uio_pci_generic
  python tools/dpdk_nic_bind.py -b uio_pci_generic 0000:00:02.0
  python tools/dpdk_nic_bind.py -b uio_pci_generic 0000:00:05.0

Run test
========

The test uses iperf to validate connectivity between the 2 netns of the
host and trough the guest.

Iperf is run with:

  # flow1: host -(ixgbe)-> guest -(virtio)-> host
  ip netns exec ns-tap iperf -s
  ip netns exec ns-ixgbe iperf -c 1.1.1.1 -t 10

  # flow2: host -(virtio)-> guest -(ixgbe)-> host
  ip netns exec ns-ixgbe iperf -s
  ip netns exec ns-tap iperf -c 1.1.1.2 -t 10

The guest runs testpmd with csum forward engine, its configuration
depends on the test case.

test1: large packets (lro/tso)
------------------------------

Configuration of testpmd:

  ./build/app/testpmd -l 0,1 --log-level 8 -- --total-num-mbufs=16384 \
    -i --port-topology=chained --disable-hw-vlan-filter \
    --disable-hw-vlan-strip --enable-rx-cksum --enable-lro \
    --crc-strip --txqflags=0

  set fwd csum
  tso set 1440 0
  csum set ip hw 0
  csum set tcp hw 0
  tso set 1440 1
  #csum set ip hw 1 # not supported by virtio
  csum set tcp hw 1
  start

Iperf log:

  root@ubuntu1404:~# ip netns exec ns-ixgbe iperf -c 1.1.1.1 -t 10
  ------------------------------------------------------------
  Client connecting to 1.1.1.1, TCP port 5001
  TCP window size: 85.0 KByte (default)
  ------------------------------------------------------------
  [  3] local 1.1.1.2 port 54460 connected with 1.1.1.1 port 5001
  [ ID] Interval       Transfer     Bandwidth
  [  3]  0.0-10.0 sec  6.14 GBytes  5.27 Gbits/sec
  root@ubuntu1404:~# ip netns exec ns-tap iperf -c 1.1.1.2 -t 10
  ------------------------------------------------------------
  Client connecting to 1.1.1.2, TCP port 5001
  TCP window size: 85.0 KByte (default)
  ------------------------------------------------------------
  [  3] local 1.1.1.1 port 58312 connected with 1.1.1.2 port 5001
  [ ID] Interval       Transfer     Bandwidth
  [  3]  0.0-10.0 sec  6.70 GBytes  5.76 Gbits/sec

Example of what we see with "set verbose 1" in testpmd:

  -- flow1: ixgbe2 -> port0 (ixgbe) -> testpmd -> port1 (virtio) <-> tap0
  port=0, mbuf=0x7f968ad9fdc0, pkt_len=24682, nb_segs=13:
  rx: l2_len=14 ethertype=800 l3_len=20 l4_proto=6 l4_len=32 flags=PKT_RX_L4_CKSUM_UNKNOWN PKT_RX_IP_CKSUM_UNKNOWN
  tx: m->l2_len=14 m->l3_len=20 m->l4_len=32
  tx: m->tso_segsz=1440
  tx: flags=PKT_TX_IP_CKSUM PKT_TX_L4_NO_CKSUM PKT_TX_TCP_SEG PKT_TX_IPV4

  -- flow2: tap0 -> port1 (virtio)-> testpmd -> port0 (ixgbe) -> ixgbe2
  port=1, mbuf=0x7f968acc9f40, pkt_len=42058, nb_segs=21:
  rx: l2_len=14 ethertype=800 l3_len=20 l4_proto=6 l4_len=32 flags=PKT_RX_L4_CKSUM_NONE PKT_RX_IP_CKSUM_UNKNOWN PKT_RX_LRO
  rx: m->lro_segsz=1440
  tx: m->l2_len=14 m->l3_len=20 m->l4_len=32
  tx: m->tso_segsz=1440
  tx: flags=PKT_TX_IP_CKSUM PKT_TX_L4_NO_CKSUM PKT_TX_TCP_SEG PKT_TX_IPV4

test2: hardware checksum only
-----------------------------

Configuration of testpmd:

  ./build/app/testpmd -l 0,1 --log-level 8 -- --total-num-mbufs=16384 \
    -i --port-topology=chained --disable-hw-vlan-filter \
    --disable-hw-vlan-strip --enable-rx-cksum --crc-strip --txqflags=0

  set fwd csum
  csum set ip hw 0
  csum set tcp hw 0
  csum set tcp hw 1
  start

Iperf log:

  root@ubuntu1404:~# ip netns exec ns-ixgbe iperf -c 1.1.1.1 -t 10
  ------------------------------------------------------------
  Client connecting to 1.1.1.1, TCP port 5001
  TCP window size: 85.0 KByte (default)
  ------------------------------------------------------------
  [  3] local 1.1.1.2 port 54462 connected with 1.1.1.1 port 5001
  [ ID] Interval       Transfer     Bandwidth
  [  3]  0.0-10.0 sec  4.49 GBytes  3.86 Gbits/sec
  root@ubuntu1404:~# ip netns exec ns-tap iperf -c 1.1.1.2 -t 10
  ------------------------------------------------------------
  Client connecting to 1.1.1.2, TCP port 5001
  TCP window size: 85.0 KByte (default)
  ------------------------------------------------------------
  [  3] local 1.1.1.1 port 58314 connected with 1.1.1.2 port 5001
  [ ID] Interval       Transfer     Bandwidth
  [  3]  0.0-10.0 sec  6.66 GBytes  5.72 Gbits/sec

Example of what we see with "set verbose 1" in testpmd:

  -- flow1: ixgbe2 -> port0 (ixgbe) -> testpmd -> port1 (virtio) <-> tap0
  port=0, mbuf=0x7f0adca89b40, pkt_len=1514, nb_segs=1:
  rx: l2_len=14 ethertype=800 l3_len=20 l4_proto=6 l4_len=32 flags=PKT_RX_L4_CKSUM_UNKNOWN PKT_RX_IP_CKSUM_UNKNOWN
  tx: m->l2_len=14 m->l3_len=20 m->l4_len=32
  tx: flags=PKT_TX_TCP_CKSUM PKT_TX_IPV4

  -- flow2: tap0 -> port1 (virtio)-> testpmd -> port0 (ixgbe) -> ixgbe2
  port=1, mbuf=0x7f0adcb98d80, pkt_len=1514, nb_segs=1:
  rx: l2_len=14 ethertype=800 l3_len=20 l4_proto=6 l4_len=32 flags=PKT_RX_L4_CKSUM_NONE PKT_RX_IP_CKSUM_UNKNOWN
  tx: m->l2_len=14 m->l3_len=20 m->l4_len=32
  tx: flags=PKT_TX_IP_CKSUM PKT_TX_TCP_CKSUM PKT_TX_IPV4

test3: no offload
-----------------

Configuration of testpmd:

  ./build/app/testpmd -l 0,1 --log-level 8 -- --total-num-mbufs=16384 \
    -i --port-topology=chained --disable-hw-vlan-filter --disable-hw-vlan-strip

  set fwd csum
  start

Iperf log:

  root@ubuntu1404:~# ip netns exec ns-ixgbe iperf -c 1.1.1.1 -t 10
  ------------------------------------------------------------
  Client connecting to 1.1.1.1, TCP port 5001
  TCP window size: 85.0 KByte (default)
  ------------------------------------------------------------
  [  3] local 1.1.1.2 port 54466 connected with 1.1.1.1 port 5001
  [ ID] Interval       Transfer     Bandwidth
  [  3]  0.0-10.0 sec  4.29 GBytes  3.68 Gbits/sec
  root@ubuntu1404:~# ip netns exec ns-tap iperf -c 1.1.1.2 -t 10
  ------------------------------------------------------------
  Client connecting to 1.1.1.2, TCP port 5001
  TCP window size: 85.0 KByte (default)
  ------------------------------------------------------------
  [  3] local 1.1.1.1 port 58316 connected with 1.1.1.2 port 5001
  [ ID] Interval       Transfer     Bandwidth
  [  3]  0.0-10.0 sec  6.66 GBytes  5.72 Gbits/sec

Example of what we see with "set verbose 1" in testpmd:

  -- flow1: ixgbe2 -> port0 (ixgbe) -> testpmd -> port1 (virtio) <-> tap0
  port=0, mbuf=0x7faf38b3e700, pkt_len=1514, nb_segs=1:
  rx: l2_len=14 ethertype=800 l3_len=20 l4_proto=6 l4_len=32 flags=PKT_RX_L4_CKSUM_UNKNOWN PKT_RX_IP_CKSUM_UNKNOWN
  tx: flags=PKT_TX_L4_NO_CKSUM PKT_TX_IPV4

  -- flow2: tap0 -> port1 (virtio)-> testpmd -> port0 (ixgbe) -> ixgbe2
  port=1, mbuf=0x7faf38b71500, pkt_len=1514, nb_segs=1:
  rx: l2_len=14 ethertype=800 l3_len=20 l4_proto=6 l4_len=32 flags=PKT_RX_L4_CKSUM_UNKNOWN PKT_RX_IP_CKSUM_UNKNOWN
  tx: flags=PKT_TX_L4_NO_CKSUM PKT_TX_IPV4

-- 
2.8.1

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox