All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] New crypto software based device
@ 2016-08-26  7:21 Piotr Azarewicz
  2016-08-26  7:21 ` [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device Piotr Azarewicz
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Piotr Azarewicz @ 2016-08-26  7:21 UTC (permalink / raw)
  To: declan.doherty, dev; +Cc: Marcin Kerlin

From: Marcin Kerlin <marcinx.kerlin@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

Slawomir Mrozowicz (2):
  libcrypto_pmd: initial implementation of SW crypto device
  lib/cryptodev: added support to libcrypto PMD

Piotr Azarewicz (1)  
 app/test: added tests for libcrypto PMD

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

 MAINTAINERS                                        |    4 +
 app/test/Makefile                                  |    1 +
 app/test/test_cryptodev.c                          | 1245 +++++++++++++++-
 app/test/test_cryptodev.h                          |   24 +
 app/test/test_cryptodev_aes.c                      |   42 +-
 app/test/test_cryptodev_aes_test_vectors.h         |  887 +++++++++++
 app/test/test_cryptodev_des_test_vectors.h         |  754 ++++++++++
 app/test/test_cryptodev_hash_test_vectors.h        |  439 ++++++
 app/test/test_cryptodev_kasumi_test_vectors.h      |   12 +-
 app/test/test_cryptodev_operations.c               | 1576 ++++++++++++++++++++
 app/test/test_cryptodev_operations.h               |  141 ++
 app/test/test_cryptodev_perf.c                     |  699 ++++++++-
 config/common_base                                 |    6 +
 doc/guides/cryptodevs/index.rst                    |    1 +
 doc/guides/cryptodevs/libcrypto.rst                |  109 ++
 drivers/crypto/Makefile                            |    1 +
 drivers/crypto/libcrypto/Makefile                  |   60 +
 drivers/crypto/libcrypto/rte_libcrypto_pmd.c       |  936 ++++++++++++
 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c   |  638 ++++++++
 .../crypto/libcrypto/rte_libcrypto_pmd_private.h   |  189 +++
 .../crypto/libcrypto/rte_pmd_libcrypto_version.map |    3 +
 examples/l2fwd-crypto/main.c                       |   11 +
 lib/librte_cryptodev/rte_cryptodev.h               |    3 +
 mk/rte.app.mk                                      |    3 +-
 24 files changed, 7688 insertions(+), 96 deletions(-)
 create mode 100644 app/test/test_cryptodev_aes_test_vectors.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 app/test/test_cryptodev_operations.c
 create mode 100644 app/test/test_cryptodev_operations.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

-- 
1.9.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device
  2016-08-26  7:21 [PATCH 0/4] New crypto software based device Piotr Azarewicz
@ 2016-08-26  7:21 ` Piotr Azarewicz
       [not found]   ` <CAOysbxoNTyTkz2A9oteLj2LfExObqnjSSsQK=s6p0kVuaEcS9g@mail.gmail.com>
  2016-09-12 11:16   ` Akhil Goyal
  2016-08-26  7:21 ` [PATCH 2/4] lib/cryptodev: added support to libcrypto PMD Piotr Azarewicz
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 10+ messages in thread
From: Piotr Azarewicz @ 2016-08-26  7:21 UTC (permalink / raw)
  To: declan.doherty, dev
  Cc: Marcin Kerlin, Slawomir Mrozowicz, Michal Kobylinski,
	Tomasz Kulasek, Daniel Mrzyglod

From: Marcin Kerlin <marcinx.kerlin@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.

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

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.

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>
---
 MAINTAINERS                                        |   4 +
 config/common_base                                 |   6 +
 doc/guides/cryptodevs/index.rst                    |   1 +
 doc/guides/cryptodevs/libcrypto.rst                | 109 +++
 drivers/crypto/Makefile                            |   1 +
 drivers/crypto/libcrypto/Makefile                  |  60 ++
 drivers/crypto/libcrypto/rte_libcrypto_pmd.c       | 936 +++++++++++++++++++++
 drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c   | 638 ++++++++++++++
 .../crypto/libcrypto/rte_libcrypto_pmd_private.h   | 189 +++++
 .../crypto/libcrypto/rte_pmd_libcrypto_version.map |   3 +
 mk/rte.app.mk                                      |   3 +-
 11 files changed, 1949 insertions(+), 1 deletion(-)
 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 bc9aa02..9eeb841 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -431,6 +431,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 7830535..42d28dd 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 9616de1..adb6e98c 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..1c3dd07
--- /dev/null
+++ b/doc/guides/cryptodevs/libcrypto.rst
@@ -0,0 +1,109 @@
+..  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
+
+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:
+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.
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index dc4ef7f..11b0863 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..cfc5922
--- /dev/null
+++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c
@@ -0,0 +1,936 @@
+/*-
+ *   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 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;
+	sess->cipher.key.data = xform->cipher.key.data;
+
+	/* 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:
+		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;
+
+		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(sess->cipher.key.data,
+				sess->cipher.key.length, sess->cipher.key_ede) != 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;
+
+	/* Select auth algo */
+	switch (xform->auth.algo) {
+	case RTE_CRYPTO_AUTH_AES_GMAC:
+		sess->auth.mode = LIBCRYPTO_AUTH_AS_CIPHER;
+		if (get_cipher_algo(RTE_CRYPTO_CIPHER_AES_GCM, xform->auth.key.length,
+				&sess->auth.cipher.evp_algo) != 0)
+			return -EINVAL;
+		sess->auth.cipher.key.data = xform->auth.key.data;
+		sess->auth.cipher.key.length = xform->auth.key.length;
+		sess->auth.cipher.ctx = EVP_CIPHER_CTX_new();
+		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:
+		sess->auth.mode = LIBCRYPTO_AUTH_NULL;
+		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;
+	}
+
+	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_MD_CTX_destroy(sess->auth.hmac.ctx);
+		break;
+	case LIBCRYPTO_AUTH_AS_CIPHER:
+		EVP_CIPHER_CTX_free(sess->auth.cipher.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 (!unlikely(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 gmac algorithm */
+static int
+process_libcrypto_auth_gmac(uint8_t *src, uint8_t *dst,
+		uint8_t *iv, uint8_t *key, int srclen, int ivlen,
+		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
+{
+	int unused;
+
+	if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0)
+		goto process_auth_gmac_err;
+
+	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0)
+		goto process_auth_gmac_err;
+
+	if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0)
+		goto process_auth_gmac_err;
+
+	if (EVP_EncryptUpdate(ctx, NULL, &unused, src, srclen) <= 0)
+		goto process_auth_gmac_err;
+
+	if (EVP_EncryptFinal_ex(ctx, NULL, &unused) <= 0)
+		goto process_auth_gmac_err;
+
+	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, dst) <= 0)
+		goto process_auth_gmac_err;
+
+	return 0;
+
+process_auth_gmac_err:
+	LIBCRYPTO_LOG_ERR("Process libcrypto auth gmac failed");
+	return -EINVAL;
+}
+
+/** 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 cipher operation */
+static int
+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_ede, srclen, sess->cipher.ctx);
+
+	if (status == 0)
+		op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+	else
+		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
+
+	return status;
+}
+
+/** Process auth operation */
+static int
+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, *iv;
+	int srclen, ivlen, status = -1;
+
+	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_GENERATE) {
+		dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
+				op->sym->auth.data.offset +
+				op->sym->auth.data.length);
+	} else {
+		dst = (uint8_t *)rte_pktmbuf_append(mbuf_src,
+				op->sym->auth.digest.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;
+	case LIBCRYPTO_AUTH_AS_CIPHER:
+		iv = op->sym->cipher.iv.data;
+		ivlen = op->sym->cipher.iv.length;
+
+		status = process_libcrypto_auth_gmac(src, dst,
+				iv, sess->auth.cipher.key.data,	srclen, ivlen,
+				sess->auth.cipher.ctx, sess->auth.cipher.evp_algo);
+		break;
+	default:
+		break;
+	}
+
+	if (status == 0) {
+		op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
+
+		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;
+				status = -EINVAL;
+			}
+		}
+	} else
+		op->status = RTE_CRYPTO_OP_STATUS_ERROR;
+
+	return status;
+}
+
+/** 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 status;
+
+	msrc = op->sym->m_src;
+	mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
+
+	switch (sess->chain_order) {
+	case LIBCRYPTO_CHAIN_ONLY_CIPHER:
+		status = process_libcrypto_cipher_op(op, sess, msrc, mdst);
+		break;
+	case LIBCRYPTO_CHAIN_ONLY_AUTH:
+		status = process_libcrypto_auth_op(op, sess, msrc, mdst);
+		break;
+	case LIBCRYPTO_CHAIN_CIPHER_AUTH:
+		status = process_libcrypto_cipher_op(op, sess, msrc, mdst);
+		if (status == 0)
+			status = process_libcrypto_auth_op(op, sess, mdst, mdst);
+		break;
+	case LIBCRYPTO_CHAIN_AUTH_CIPHER:
+		status = process_libcrypto_auth_op(op, sess, msrc, mdst);
+		if (status == 0)
+			status = process_libcrypto_cipher_op(op, sess, msrc, mdst);
+		break;
+	default:
+		status = -1;
+		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 (status != 0)
+		return -1;
+
+	return rte_ring_enqueue(qp->processed_ops, (void *)op);
+}
+
+/*
+ *------------------------------------------------------------------------------
+ * 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..68c49c9
--- /dev/null
+++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c
@@ -0,0 +1,638 @@
+/*-
+ *   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 = 20,
+					.max = 20,
+					.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
+				}
+			}, }
+		}, }
+	},
+	{	/* 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_mb_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..b40a2d2
--- /dev/null
+++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h
@@ -0,0 +1,189 @@
+/*-
+ *   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_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,
+	LIBCRYPTO_AUTH_AS_CIPHER,
+	LIBCRYPTO_AUTH_NULL
+};
+
+/** 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;
+			/**< pointer to 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 */
+
+		uint8_t key_ede[24];
+		/**< key data storage to be used in ede process */
+	} cipher;
+
+	/** Authentication Parameters */
+	struct {
+		enum rte_crypto_auth_operation operation;
+		/**< auth operation generate or verify */
+		enum libcrypto_auth_mode mode;
+		/**< auth operation mode */
+
+		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;
+
+			struct {
+				struct {
+					uint8_t *data;
+					/**< pointer to 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;
+		};
+	} 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..58c4dea
--- /dev/null
+++ b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map
@@ -0,0 +1,3 @@
+DPDK_16.11 {
+	local: *;
+};
\ No newline at end of file
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 1a0095b..67c0aa9 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -135,7 +135,8 @@ _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_NULL_CRYPTO) += -lrte_pmd_null_crypto
+_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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/4] lib/cryptodev: added support to libcrypto PMD
  2016-08-26  7:21 [PATCH 0/4] New crypto software based device Piotr Azarewicz
  2016-08-26  7:21 ` [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device Piotr Azarewicz
@ 2016-08-26  7:21 ` Piotr Azarewicz
  2016-08-26  7:21 ` [PATCH 3/4] app/test: added tests for " Piotr Azarewicz
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Piotr Azarewicz @ 2016-08-26  7:21 UTC (permalink / raw)
  To: declan.doherty, dev; +Cc: Marcin Kerlin, Slawomir Mrozowicz

From: Marcin Kerlin <marcinx.kerlin@intel.com>

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

Signed-off-by: Slawomir Mrozowicz <slawomirx.mrozowicz@intel.com>
---
 lib/librte_cryptodev/rte_cryptodev.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index affbdec..7a87cc3 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -55,6 +55,8 @@ extern "C" {
 /**< AES-NI Multi buffer PMD device name */
 #define CRYPTODEV_NAME_AESNI_GCM_PMD	cryptodev_aesni_gcm_pmd
 /**< AES-NI GCM PMD device name */
+#define CRYPTODEV_NAME_LIBCRYPTO_PMD	cryptodev_libcrypto_pmd
+/**< Open SSL Crypto PMD device name */
 #define CRYPTODEV_NAME_QAT_SYM_PMD	cryptodev_qat_sym_pmd
 /**< Intel QAT Symmetric Crypto PMD device name */
 #define CRYPTODEV_NAME_SNOW3G_PMD	cryptodev_snow3g_pmd
@@ -70,6 +72,7 @@ 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_LIBCRYPTO_PMD,	/**<  LibCrypto PMD */
 };
 
 extern const char **rte_cyptodev_names;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/4] app/test: added tests for libcrypto PMD
  2016-08-26  7:21 [PATCH 0/4] New crypto software based device Piotr Azarewicz
  2016-08-26  7:21 ` [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device Piotr Azarewicz
  2016-08-26  7:21 ` [PATCH 2/4] lib/cryptodev: added support to libcrypto PMD Piotr Azarewicz
@ 2016-08-26  7:21 ` Piotr Azarewicz
  2016-08-26  7:21 ` [PATCH 4/4] examples/l2fwd-crypto: updated example " Piotr Azarewicz
  2016-09-07 18:52 ` [PATCH 0/4] New crypto software based device De Lara Guarch, Pablo
  4 siblings, 0 replies; 10+ messages in thread
From: Piotr Azarewicz @ 2016-08-26  7:21 UTC (permalink / raw)
  To: declan.doherty, dev; +Cc: Marcin Kerlin, Daniel Mrzyglod

From: Marcin Kerlin <marcinx.kerlin@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: Daniel Mrzyglod <danielx.t.mrzyglod@intel.com>
Signed-off-by: Marcin Kerlin <marcinx.kerlin@intel.com>
---
 app/test/Makefile                             |    1 +
 app/test/test_cryptodev.c                     | 1245 ++++++++++++++++++-
 app/test/test_cryptodev.h                     |   24 +
 app/test/test_cryptodev_aes.c                 |   42 +-
 app/test/test_cryptodev_aes_test_vectors.h    |  887 ++++++++++++++
 app/test/test_cryptodev_des_test_vectors.h    |  754 ++++++++++++
 app/test/test_cryptodev_hash_test_vectors.h   |  439 +++++++
 app/test/test_cryptodev_kasumi_test_vectors.h |   12 +-
 app/test/test_cryptodev_operations.c          | 1576 +++++++++++++++++++++++++
 app/test/test_cryptodev_operations.h          |  141 +++
 app/test/test_cryptodev_perf.c                |  699 ++++++++++-
 11 files changed, 5725 insertions(+), 95 deletions(-)
 create mode 100644 app/test/test_cryptodev_aes_test_vectors.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 app/test/test_cryptodev_operations.c
 create mode 100644 app/test/test_cryptodev_operations.h

diff --git a/app/test/Makefile b/app/test/Makefile
index 611d77a..0ee32a8 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -193,6 +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_operations.c
 SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_aes.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 647787d..b7559b7 100644
--- a/app/test/test_cryptodev.c
+++ b/app/test/test_cryptodev.c
@@ -43,7 +43,11 @@
 #include "test.h"
 #include "test_cryptodev.h"
 
+#include "test_cryptodev_operations.h"
 #include "test_cryptodev_aes.h"
+#include "test_cryptodev_hash_test_vectors.h"
+#include "test_cryptodev_aes_test_vectors.h"
+#include "test_cryptodev_des_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"
@@ -52,29 +56,6 @@
 
 static enum rte_cryptodev_type gbl_cryptodev_type;
 
-struct crypto_testsuite_params {
-	struct rte_mempool *mbuf_pool;
-	struct rte_mempool *op_mpool;
-	struct rte_cryptodev_config conf;
-	struct rte_cryptodev_qp_conf qp_conf;
-
-	uint8_t valid_devs[RTE_CRYPTO_MAX_DEVS];
-	uint8_t valid_dev_count;
-};
-
-struct crypto_unittest_params {
-	struct rte_crypto_sym_xform cipher_xform;
-	struct rte_crypto_sym_xform auth_xform;
-
-	struct rte_cryptodev_sym_session *sess;
-
-	struct rte_crypto_op *op;
-
-	struct rte_mbuf *obuf, *ibuf;
-
-	uint8_t *digest;
-};
-
 #define ALIGN_POW2_ROUNDUP(num, align) \
 	(((num) + (align) - 1) & ~((align) - 1))
 
@@ -83,12 +64,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,
@@ -196,6 +181,23 @@ testsuite_setup(void)
 		}
 	}
 
+	/* Create 2 LIBCRYPTO devices if required */
+	if (gbl_cryptodev_type == RTE_CRYPTODEV_LIBCRYPTO_PMD) {
+		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));
+			}
+		}
+	}
+
 	/* Create 2 AESNI GCM devices if required */
 	if (gbl_cryptodev_type == RTE_CRYPTODEV_AESNI_GCM_PMD) {
 		nb_devs = rte_cryptodev_count_devtype(
@@ -821,6 +823,314 @@ static const uint8_t catch_22_quote_2_512_bytes_AES_CBC_HMAC_SHA1_digest[] = {
 };
 
 
+/* 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)
 {
@@ -951,17 +1261,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 */
@@ -970,7 +1287,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 */
@@ -979,7 +1296,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;
 
@@ -990,12 +1307,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,
@@ -1003,7 +1323,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 */
@@ -1033,7 +1353,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;
@@ -1078,6 +1398,21 @@ test_AES_mb_all(void)
 }
 
 static int
+test_AES_libcrypto_all(void)
+{
+	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	int status;
+
+	status = test_AES_all_tests(ts_params->mbuf_pool,
+		ts_params->op_mpool, ts_params->valid_devs[0],
+		RTE_CRYPTODEV_LIBCRYPTO_PMD);
+
+	TEST_ASSERT_EQUAL(status, 0, "Test failed");
+
+	return TEST_SUCCESS;
+}
+
+static int
 test_AES_qat_all(void)
 {
 	struct crypto_testsuite_params *ts_params = &testsuite_params;
@@ -2983,6 +3318,589 @@ test_snow3g_encrypted_authentication_test_case_1(void)
 	return test_snow3g_encrypted_authentication(&snow3g_test_case_6);
 }
 
+/* ***** HASH Tests ***** */
+static int
+authentication_MD5(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&md5_test_vector);
+}
+
+static int
+authentication_verify_MD5(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&md5_test_vector);
+}
+
+static int
+authentication_HMAC_MD5(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&hmac_md5_test_vector);
+}
+
+static int
+authentication_verify_HMAC_MD5(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&hmac_md5_test_vector);
+}
+
+static int
+authentication_SHA1(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&sha1_test_vector);
+}
+
+static int
+authentication_verify_SHA1(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&sha1_test_vector);
+}
+
+static int
+authentication_HMAC_SHA1(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&hmac_sha1_test_vector);
+}
+
+static int
+authentication_verify_HMAC_SHA1(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&hmac_sha1_test_vector);
+}
+
+static int
+authentication_SHA224(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&sha224_test_vector);
+}
+
+static int
+authentication_verify_SHA224(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&sha224_test_vector);
+}
+
+static int
+authentication_HMAC_SHA224(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&hmac_sha224_test_vector);
+}
+
+static int
+authentication_verify_HMAC_SHA224(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&hmac_sha224_test_vector);
+}
+
+static int
+authentication_SHA256(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&sha256_test_vector);
+}
+
+static int
+authentication_verify_SHA256(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&sha256_test_vector);
+}
+
+static int
+authentication_HMAC_SHA256(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&hmac_sha256_test_vector);
+}
+
+static int
+authentication_verify_HMAC_SHA256(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&hmac_sha256_test_vector);
+}
+
+static int
+authentication_SHA384(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&sha384_test_vector);
+}
+
+static int
+authentication_verify_SHA384(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&sha384_test_vector);
+}
+
+static int
+authentication_HMAC_SHA384(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&hmac_sha384_test_vector);
+}
+
+static int
+authentication_verify_HMAC_SHA384(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&hmac_sha384_test_vector);
+}
+
+static int
+authentication_SHA512(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&sha512_test_vector);
+}
+
+static int
+authentication_verify_SHA512(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&sha512_test_vector);
+}
+
+static int
+authentication_HMAC_SHA512(void)
+{
+	return test_authentication(&testsuite_params, &unittest_params,
+			&hmac_sha512_test_vector);
+}
+
+static int
+authentication_verify_HMAC_SHA512(void)
+{
+	return test_authentication_verify(&testsuite_params, &unittest_params,
+			&hmac_sha512_test_vector);
+}
+
+static int
+authentication_AES128_GMAC(void)
+{
+	return test_authentication_GMAC(&testsuite_params, &unittest_params,
+			&aes128_gmac_test_vector);
+}
+
+static int
+authentication_verify_AES128_GMAC(void)
+{
+	return test_authentication_verify_GMAC(&testsuite_params, &unittest_params,
+			&aes128_gmac_test_vector);
+}
+
+static int
+authentication_AES192_GMAC(void)
+{
+	return test_authentication_GMAC(&testsuite_params, &unittest_params,
+			&aes192_gmac_test_vector);
+}
+
+static int
+authentication_verify_AES192_GMAC(void)
+{
+	return test_authentication_verify_GMAC(&testsuite_params, &unittest_params,
+			&aes192_gmac_test_vector);
+}
+
+static int
+authentication_AES256_GMAC(void)
+{
+	return test_authentication_GMAC(&testsuite_params, &unittest_params,
+			&aes256_gmac_test_vector);
+}
+
+static int
+authentication_verify_AES256_GMAC(void)
+{
+	return test_authentication_verify_GMAC(&testsuite_params, &unittest_params,
+			&aes256_gmac_test_vector);
+}
+
+/* ***** AES Tests ***** */
+static int
+encryption_AES128CTR(void)
+{
+	return test_encryption(&testsuite_params, &unittest_params,
+			&aes128ctr_test_vector);
+}
+
+static int
+decryption_AES128CTR(void)
+{
+	return test_decryption(&testsuite_params, &unittest_params,
+			&aes128ctr_test_vector);
+}
+
+static int
+encryption_AES192CTR(void)
+{
+	return test_encryption(&testsuite_params, &unittest_params,
+			&aes192ctr_test_vector);
+}
+
+static int
+decryption_AES192CTR(void)
+{
+	return test_decryption(&testsuite_params, &unittest_params,
+			&aes192ctr_test_vector);
+}
+
+static int
+encryption_AES256CTR(void)
+{
+	return test_encryption(&testsuite_params, &unittest_params,
+			&aes256ctr_test_vector);
+}
+
+static int
+decryption_AES256CTR(void)
+{
+	return test_decryption(&testsuite_params, &unittest_params,
+			&aes256ctr_test_vector);
+}
+
+static int
+authenticated_encryption_AES128CTR_HMAC_SHA1(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&aes128ctr_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_AES128CTR_HMAC_SHA1(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&aes128ctr_hmac_sha1_test_vector);
+}
+
+static int
+encryption_AES128CBC(void)
+{
+	return test_encryption(&testsuite_params, &unittest_params,
+			&aes128cbc_test_vector);
+}
+
+static int
+decryption_AES128CBC(void)
+{
+	return test_decryption(&testsuite_params, &unittest_params,
+			&aes128cbc_test_vector);
+}
+
+static int
+encryption_AES192CBC(void)
+{
+	return test_encryption(&testsuite_params, &unittest_params,
+			&aes192cbc_test_vector);
+}
+
+static int
+decryption_AES192CBC(void)
+{
+	return test_decryption(&testsuite_params, &unittest_params,
+			&aes192cbc_test_vector);
+}
+
+static int
+encryption_AES256CBC(void)
+{
+	return test_encryption(&testsuite_params, &unittest_params,
+			&aes256cbc_test_vector);
+}
+
+static int
+decryption_AES256CBC(void)
+{
+	return test_decryption(&testsuite_params, &unittest_params,
+			&aes256cbc_test_vector);
+}
+
+static int
+authenticated_encryption_AES128CBC_HMAC_SHA1(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&aes128cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_AES128CBC_HMAC_SHA1(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&aes128cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_encryption_AES128CBC_HMAC_SHA1_sessionless(void)
+{
+	return test_authenticated_encryption_sessionless(&testsuite_params,
+			&unittest_params,
+			&aes128cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_AES128CBC_HMAC_SHA1_sessionless(void)
+{
+	return test_authenticated_decryption_sessionless(&testsuite_params,
+			&unittest_params,
+			&aes128cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_encryption_AES128CBC_AES128_GMAC(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&aes128cbc_aes128_gmac_test_vector);
+}
+
+static int
+authenticated_decryption_AES128CBC_AES128_GMAC(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&aes128cbc_aes128_gmac_test_vector);
+}
+
+static int
+authenticated_encryption_AES128CBC_AES192_GMAC(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&aes128cbc_aes192_gmac_test_vector);
+}
+
+static int
+authenticated_decryption_AES128CBC_AES192_GMAC(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&aes128cbc_aes192_gmac_test_vector);
+}
+
+static int
+authenticated_encryption_AES128CBC_AES256_GMAC(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&aes128cbc_aes256_gmac_test_vector);
+}
+
+static int
+authenticated_decryption_AES128CBC_AES256_GMAC(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&aes128cbc_aes256_gmac_test_vector);
+}
+
+/* ***** DES Tests ***** */
+static int
+encryption_3DES128CBC(void)
+{
+	return test_encryption(&testsuite_params, &unittest_params,
+			&triple_des128cbc_test_vector);
+}
+
+static int
+decryption_3DES128CBC(void)
+{
+	return test_decryption(&testsuite_params, &unittest_params,
+			&triple_des128cbc_test_vector);
+}
+
+static int
+encryption_3DES192CBC(void)
+{
+	return test_encryption(&testsuite_params, &unittest_params,
+			&triple_des192cbc_test_vector);
+}
+
+static int
+decryption_3DES192CBC(void)
+{
+	return test_decryption(&testsuite_params, &unittest_params,
+			&triple_des192cbc_test_vector);
+}
+
+static int
+encryption_3DES128CTR(void)
+{
+	return test_encryption(&testsuite_params, &unittest_params,
+			&triple_des128ctr_test_vector);
+}
+
+static int
+decryption_3DES128CTR(void)
+{
+	return test_decryption(&testsuite_params, &unittest_params,
+			&triple_des128ctr_test_vector);
+}
+
+static int
+encryption_3DES192CTR(void)
+{
+	return test_encryption(&testsuite_params, &unittest_params,
+			&triple_des192ctr_test_vector);
+}
+
+static int
+decryption_3DES192CTR(void)
+{
+	return test_decryption(&testsuite_params, &unittest_params,
+			&triple_des192ctr_test_vector);
+}
+
+static int
+authenticated_encryption_3DES128CBC_SHA1(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&triple_des128cbc_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_3DES128CBC_SHA1(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&triple_des128cbc_sha1_test_vector);
+}
+
+static int
+authenticated_encryption_3DES128CBC_HMAC_SHA1(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&triple_des128cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_3DES128CBC_HMAC_SHA1(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&triple_des128cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_encryption_3DES128CBC_HMAC_SHA1_sessionless(void)
+{
+	return test_authenticated_encryption_sessionless(&testsuite_params,
+			&unittest_params,
+			&triple_des128cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_3DES128CBC_HMAC_SHA1_sessionless(void)
+{
+	return test_authenticated_decryption_sessionless(&testsuite_params,
+			&unittest_params,
+			&triple_des128cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_encryption_3DES128CBC_HMAC_SHA1_out_of_place(void)
+{
+	return test_authenticated_encryption_out_of_place(&testsuite_params,
+			&unittest_params,
+			&triple_des128cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_3DES128CBC_HMAC_SHA1_out_of_place(void)
+{
+	return test_authenticated_decryption_out_of_place(&testsuite_params,
+			&unittest_params,
+			&triple_des128cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_encryption_3DES192CBC_SHA1(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&triple_des192cbc_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_3DES192CBC_SHA1(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&triple_des192cbc_sha1_test_vector);
+}
+
+static int
+authenticated_encryption_3DES192CBC_HMAC_SHA1(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&triple_des192cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_3DES192CBC_HMAC_SHA1(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&triple_des192cbc_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_encryption_3DES128CTR_SHA1(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&triple_des128ctr_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_3DES128CTR_SHA1(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&triple_des128ctr_sha1_test_vector);
+}
+
+static int
+authenticated_encryption_3DES128CTR_HMAC_SHA1(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&triple_des128ctr_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_3DES128CTR_HMAC_SHA1(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&triple_des128ctr_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_encryption_3DES192CTR_SHA1(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&triple_des192ctr_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_3DES192CTR_SHA1(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&triple_des192ctr_sha1_test_vector);
+}
+
+static int
+authenticated_encryption_3DES192CTR_HMAC_SHA1(void)
+{
+	return test_authenticated_encryption(&testsuite_params, &unittest_params,
+			&triple_des192ctr_hmac_sha1_test_vector);
+}
+
+static int
+authenticated_decryption_3DES192CTR_HMAC_SHA1(void)
+{
+	return test_authenticated_decryption(&testsuite_params, &unittest_params,
+			&triple_des192ctr_hmac_sha1_test_vector);
+}
+
 /* ***** AES-GCM Tests ***** */
 
 static int
@@ -3443,7 +4361,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);
@@ -3462,10 +4381,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);
@@ -3502,6 +4424,113 @@ 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)
 {
@@ -3966,6 +4995,135 @@ 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_libcrypto_all),
+		TEST_CASE_ST(ut_setup, ut_teardown,	authentication_MD5),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_MD5),
+		TEST_CASE_ST(ut_setup, ut_teardown,	authentication_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,	authentication_SHA224),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_SHA224),
+		TEST_CASE_ST(ut_setup, ut_teardown,	authentication_SHA256),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_SHA256),
+		TEST_CASE_ST(ut_setup, ut_teardown,	authentication_SHA384),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_SHA384),
+		TEST_CASE_ST(ut_setup, ut_teardown,	authentication_SHA512),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_SHA512),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_HMAC_MD5),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_HMAC_MD5),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_HMAC_SHA224),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_HMAC_SHA224),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_HMAC_SHA256),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_HMAC_SHA256),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_HMAC_SHA384),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_HMAC_SHA384),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_HMAC_SHA512),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_HMAC_SHA512),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_AES128_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_AES128_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_AES192_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_AES192_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_AES256_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown, authentication_verify_AES256_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown, encryption_AES128CBC),
+		TEST_CASE_ST(ut_setup, ut_teardown, decryption_AES128CBC),
+		TEST_CASE_ST(ut_setup, ut_teardown, encryption_AES192CBC),
+		TEST_CASE_ST(ut_setup, ut_teardown, decryption_AES192CBC),
+		TEST_CASE_ST(ut_setup, ut_teardown, encryption_AES256CBC),
+		TEST_CASE_ST(ut_setup, ut_teardown, decryption_AES256CBC),
+		TEST_CASE_ST(ut_setup, ut_teardown, encryption_AES128CTR),
+		TEST_CASE_ST(ut_setup, ut_teardown, decryption_AES128CTR),
+		TEST_CASE_ST(ut_setup, ut_teardown, encryption_AES192CTR),
+		TEST_CASE_ST(ut_setup, ut_teardown, decryption_AES192CTR),
+		TEST_CASE_ST(ut_setup, ut_teardown, encryption_AES256CTR),
+		TEST_CASE_ST(ut_setup, ut_teardown, decryption_AES256CTR),
+		TEST_CASE_ST(ut_setup, ut_teardown, encryption_3DES128CBC),
+		TEST_CASE_ST(ut_setup, ut_teardown, decryption_3DES128CBC),
+		TEST_CASE_ST(ut_setup, ut_teardown, encryption_3DES192CBC),
+		TEST_CASE_ST(ut_setup, ut_teardown, decryption_3DES192CBC),
+		TEST_CASE_ST(ut_setup, ut_teardown, encryption_3DES128CTR),
+		TEST_CASE_ST(ut_setup, ut_teardown, decryption_3DES128CTR),
+		TEST_CASE_ST(ut_setup, ut_teardown, encryption_3DES192CTR),
+		TEST_CASE_ST(ut_setup, ut_teardown, decryption_3DES192CTR),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_AES128CBC_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_AES128CBC_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_AES128CBC_AES128_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_AES128CBC_AES128_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_AES128CBC_AES192_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_AES128CBC_AES192_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_AES128CBC_AES256_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_AES128CBC_AES256_GMAC),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_AES128CTR_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_AES128CTR_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_3DES128CBC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_3DES128CBC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_3DES128CBC_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_3DES128CBC_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_3DES192CBC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_3DES192CBC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_3DES192CBC_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_3DES192CBC_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_3DES128CTR_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_3DES128CTR_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_3DES128CTR_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_3DES128CTR_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_3DES192CTR_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_3DES192CTR_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_3DES192CTR_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_3DES192CTR_HMAC_SHA1),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_AES128CBC_HMAC_SHA1_sessionless),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_AES128CBC_HMAC_SHA1_sessionless),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_3DES128CBC_HMAC_SHA1_sessionless),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_3DES128CBC_HMAC_SHA1_sessionless),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_encryption_3DES128CBC_HMAC_SHA1_out_of_place),
+		TEST_CASE_ST(ut_setup, ut_teardown,
+			authenticated_decryption_3DES128CBC_HMAC_SHA1_out_of_place),
+
+		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,
@@ -4174,6 +5332,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;
@@ -4207,6 +5373,7 @@ test_cryptodev_sw_kasumi(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..51f7975 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_GMAC		(BYTE_LENGTH(128))
 
 #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA1		(12)
 #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA224		(16)
@@ -70,4 +71,27 @@
 #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA384		(24)
 #define TRUNCATED_DIGEST_BYTE_LENGTH_SHA512		(32)
 
+struct crypto_testsuite_params {
+	struct rte_mempool *mbuf_pool;
+	struct rte_mempool *op_mpool;
+	struct rte_cryptodev_config conf;
+	struct rte_cryptodev_qp_conf qp_conf;
+
+	uint8_t valid_devs[RTE_CRYPTO_MAX_DEVS];
+	uint8_t valid_dev_count;
+};
+
+struct crypto_unittest_params {
+	struct rte_crypto_sym_xform cipher_xform;
+	struct rte_crypto_sym_xform auth_xform;
+
+	struct rte_cryptodev_sym_session *sess;
+
+	struct rte_crypto_op *op;
+
+	struct rte_mbuf *obuf, *ibuf;
+
+	uint8_t *digest;
+};
+
 #endif /* TEST_CRYPTODEV_H_ */
diff --git a/app/test/test_cryptodev_aes.c b/app/test/test_cryptodev_aes.c
index bf832b6..b6283f8 100644
--- a/app/test/test_cryptodev_aes.c
+++ b/app/test/test_cryptodev_aes.c
@@ -56,8 +56,9 @@
 #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_TARGET_PMD_MB			0x0001 /* Multi-buffer flag */
+#define AES_TEST_TARGET_PMD_QAT			0x0002 /* QAT flag */
+#define AES_TEST_TARGET_PMD_LIBCRYPTO	0x0004 /* SW LIBCRYPTO flag */
 
 #define AES_TEST_OP_CIPHER		(AES_TEST_OP_ENCRYPT |		\
 					AES_TEST_OP_DECRYPT)
@@ -85,6 +86,7 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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_LIBCRYPTO |
 			AES_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -93,6 +95,7 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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_LIBCRYPTO |
 			AES_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -114,6 +117,7 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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_LIBCRYPTO |
 			AES_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -122,6 +126,7 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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_LIBCRYPTO |
 			AES_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -129,6 +134,7 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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_LIBCRYPTO |
 			AES_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -137,6 +143,7 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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_LIBCRYPTO |
 			AES_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -144,6 +151,7 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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_LIBCRYPTO |
 			AES_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -152,6 +160,7 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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_LIBCRYPTO |
 			AES_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -159,6 +168,7 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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_LIBCRYPTO |
 			AES_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -167,7 +177,8 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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
+		.pmd_mask = AES_TEST_TARGET_PMD_MB |
+			AES_TEST_TARGET_PMD_LIBCRYPTO
 	},
 	{
 		.test_descr = "AES-128-CBC HMAC-SHA512 Decryption Digest "
@@ -175,6 +186,7 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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_LIBCRYPTO |
 			AES_TEST_TARGET_PMD_QAT
 	},
 	{
@@ -197,7 +209,8 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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
+		.pmd_mask = AES_TEST_TARGET_PMD_QAT |
+			AES_TEST_TARGET_PMD_LIBCRYPTO
 	},
 	{
 		.test_descr = "AES-128-CBC HMAC-SHA1 Decryption Digest "
@@ -205,33 +218,38 @@ static const struct aes_test_case aes_test_cases[] = {
 		.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
+		.pmd_mask = AES_TEST_TARGET_PMD_QAT |
+			AES_TEST_TARGET_PMD_LIBCRYPTO
 	},
 	{
 		.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
+		.pmd_mask = AES_TEST_TARGET_PMD_MB |
+			AES_TEST_TARGET_PMD_LIBCRYPTO
 	},
 	{
 		.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
+		.pmd_mask = AES_TEST_TARGET_PMD_MB |
+			AES_TEST_TARGET_PMD_LIBCRYPTO
 	},
 	{
 		.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
+		.pmd_mask = AES_TEST_TARGET_PMD_MB |
+			AES_TEST_TARGET_PMD_LIBCRYPTO
 	},
 	{
 		.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
+		.pmd_mask = AES_TEST_TARGET_PMD_MB |
+			AES_TEST_TARGET_PMD_LIBCRYPTO
 	},
 };
 
@@ -270,6 +288,7 @@ test_AES_one_case(const struct aes_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:
@@ -653,8 +672,11 @@ test_AES_all_tests(struct rte_mempool *mbuf_pool,
 	case RTE_CRYPTODEV_QAT_SYM_PMD:
 		target_pmd_mask = AES_TEST_TARGET_PMD_QAT;
 		break;
+	case RTE_CRYPTODEV_LIBCRYPTO_PMD:
+		target_pmd_mask = AES_TEST_TARGET_PMD_LIBCRYPTO;
+		break;
 	default:
-		TEST_ASSERT(-1, "Unrecognized cryptodev type");
+		TEST_ASSERT(0, "Unrecognized cryptodev type");
 		break;
 	}
 
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..5e7c24a
--- /dev/null
+++ b/app/test/test_cryptodev_aes_test_vectors.h
@@ -0,0 +1,887 @@
+/*
+ *   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_
+
+static const uint8_t plaintext_aes[] =
+		"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 ciphertext_aes128ctr[] = {
+		0x01, 0xE4, 0xCF, 0xF7, 0x02, 0x6F, 0xCD, 0xA6,
+		0x46, 0x80, 0x23, 0x39, 0x67, 0x8E, 0x0C, 0x01,
+		0x60, 0x9B, 0x31, 0xCA, 0xF1, 0xED, 0x80, 0xBA,
+		0x0B, 0x57, 0x48, 0xAF, 0x60, 0xD1, 0x01, 0x42,
+		0xCD, 0x4E, 0x0E, 0xB1, 0x54, 0x4B, 0x19, 0xC9,
+		0x31, 0x53, 0x75, 0x4B, 0x8C, 0xBB, 0xA6, 0xB2,
+		0x18, 0x0B, 0xD4, 0xEC, 0xB3, 0x0B, 0x9F, 0x7C,
+		0x92, 0xC2, 0x38, 0x14, 0xC2, 0x2D, 0xDD, 0x65,
+		0x87, 0x96, 0x3F, 0x99, 0x47, 0x1A, 0x34, 0x08,
+		0x3E, 0xAC, 0xC0, 0x57, 0x46, 0x33, 0x32, 0x1E,
+		0x27, 0x21, 0x7A, 0xCC, 0xF9, 0x67, 0x77, 0x10,
+		0x74, 0xF6, 0x8B, 0x05, 0x79, 0x1F, 0xC5, 0xA9,
+		0xAD, 0xAF, 0x78, 0x54, 0x37, 0x20, 0x8A, 0xCF,
+		0x8E, 0x80, 0x9A, 0x42, 0xEA, 0x5A, 0x01, 0xA6,
+		0x78, 0x56, 0x53, 0x92, 0x76, 0xEF, 0x72, 0x54,
+		0xF3, 0xFA, 0xF1, 0x54, 0x05, 0x94, 0x99, 0x98,
+		0x70, 0xE4, 0x82, 0xCC, 0x17, 0xD2, 0xA3, 0xED,
+		0x66, 0x0F, 0x9D, 0x4B, 0x7C, 0x65, 0x31, 0xF1,
+		0x04, 0x4D, 0x7E, 0x8D, 0x80, 0xEB, 0x1E, 0xDA,
+		0x4F, 0x0A, 0xBC, 0xF6, 0x5C, 0xCF, 0xE4, 0x32,
+		0x44, 0xDC, 0x24, 0xF0, 0xBF, 0xB8, 0x6E, 0x16,
+		0x0C, 0x8F, 0xEF, 0xEF, 0xB3, 0xD6, 0xE3, 0xA4,
+		0x1C, 0x11, 0xB3, 0x95, 0x79, 0xC5, 0x16, 0xC2,
+		0xE6, 0xDC, 0xFB, 0x30, 0x1B, 0xC8, 0x91, 0xEF,
+		0x56, 0xB7, 0x65, 0x6B, 0xCB, 0x05, 0x99, 0xBB,
+		0x2A, 0xB1, 0x4B, 0xF4, 0x25, 0x9F, 0x0C, 0x50,
+		0x0D, 0x9C, 0x23, 0x15, 0x68, 0x2D, 0x71, 0x8E,
+		0x9F, 0xE8, 0xAC, 0xA9, 0xE1, 0x94, 0xA6, 0xF0,
+		0x1F, 0x00, 0x94, 0x3D, 0xF6, 0x01, 0x9B, 0xBB,
+		0x63, 0x3C, 0x9A, 0xCE, 0xF4, 0x76, 0x32, 0x14,
+		0x30, 0x93, 0x76, 0x99, 0xB7, 0xEB, 0xED, 0x56,
+		0x80, 0x26, 0xC5, 0x5C, 0x33, 0xDD, 0x80, 0x23,
+		0x10, 0xA1, 0x9F, 0xAD, 0x54, 0x89, 0xBD, 0x49,
+		0x5E, 0x06, 0x5F, 0x7A, 0x4A, 0x27, 0x61, 0x4D,
+		0xD9, 0xC7, 0x5D, 0x3A, 0x86, 0xE7, 0x42, 0x4A,
+		0xF4, 0x80, 0x0C, 0x8F, 0x1C, 0x8D, 0xDB, 0x7F,
+		0xE2, 0xFC, 0x64, 0x86, 0x08, 0x42, 0x7A, 0xD8,
+		0x75, 0x47, 0x32, 0xDB, 0xF7, 0x6B, 0xF4, 0xD5,
+		0x07, 0xB9, 0x6B, 0x5A, 0x80, 0x8E, 0x6A, 0x85,
+		0x4E, 0x09, 0x5C, 0xCA, 0x58, 0x02, 0x4B, 0xC9,
+		0xE4, 0xFF, 0x2E, 0x62, 0x68, 0x87, 0xE8, 0xC3,
+		0x11, 0xC1, 0xEA, 0x2B, 0x9D, 0xA3, 0x58, 0x56,
+		0x3A, 0x31, 0x04, 0x0C, 0xBC, 0x7A, 0x0B, 0x06,
+		0x18, 0x88, 0xAD, 0x68, 0xE3, 0xD2, 0x8B, 0x04,
+		0x29, 0xA5, 0xFD, 0xD4, 0x59, 0xD8, 0x2E, 0x25,
+		0xA7, 0xA3, 0x0E, 0x7E, 0x7F, 0xB4, 0x28, 0xD4,
+		0x93, 0xB5, 0x88, 0x09, 0x42, 0xEF, 0xD6, 0x12,
+		0xCD, 0x01, 0xAD, 0xEA, 0x14, 0x58, 0x53, 0xE0,
+		0x15, 0xC0, 0xEC, 0xCA, 0x05, 0x4F, 0xE7, 0xD8,
+		0xB5, 0x95, 0x7C, 0x8D, 0x76, 0xA1, 0x64, 0xBB,
+		0xB6, 0x55, 0x0D, 0xC4, 0xC6, 0xD2, 0x92, 0x3A,
+		0x4B, 0x85, 0x3A, 0x05, 0x25, 0x65, 0x62, 0x15,
+		0x05, 0x98, 0x3A, 0x8D, 0x70, 0x7C, 0xD1, 0x6B,
+		0x48, 0x50, 0xBC, 0xF6, 0x53, 0xE6, 0x0C, 0x9C,
+		0xE5, 0x4A, 0x04, 0x31, 0x29, 0x51, 0x66, 0x12,
+		0x18, 0xD4, 0x1F, 0x40, 0x5D, 0xDC, 0x04, 0xD8,
+		0x0E, 0x1E, 0xFB, 0x07, 0xDD, 0xAE, 0x9E, 0xD6,
+		0xE4, 0xA3, 0x44, 0xC8, 0x61, 0x39, 0x0F, 0x74,
+		0x61, 0x2D, 0x60, 0x61, 0x0D, 0x91, 0x91, 0x50,
+		0x6A, 0x3E, 0x8B, 0xE5, 0x3E, 0x2B, 0xCD, 0xA1,
+		0x54, 0x1A, 0x56, 0xF9, 0xB8, 0x5D, 0x46, 0xE0,
+		0x82, 0x47, 0x3B, 0xB1, 0x21, 0x32, 0xA0, 0x8E,
+		0x7F, 0x79, 0x04, 0x09, 0x43, 0xC6, 0xA0, 0xFA,
+		0x86, 0x1B, 0xE1, 0x07, 0x95, 0x2B, 0xE2, 0x7A
+};
+
+static const struct test_crypto_vector
+aes128ctr_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_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,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_aes128ctr,
+		.len = 512
+	}
+};
+
+static const struct test_crypto_vector
+aes128ctr_hmac_sha1_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_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,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_aes128ctr,
+		.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 = {
+			0xCC, 0x7D, 0x3C, 0x5E, 0xE0, 0x0B, 0x50, 0xA9,
+			0x9B, 0x57, 0x0B, 0x63, 0xCE, 0xD0, 0xCA, 0x6B,
+			0x84, 0xA9, 0xC2, 0x1E
+		},
+		.len = 20
+	}
+};
+
+static const uint8_t ciphertext_aes192ctr[] = {
+		0x06, 0xA4, 0x49, 0x2A, 0x53, 0x60, 0x1E, 0x4C,
+		0x9B, 0xED, 0x6D, 0xB8, 0xA4, 0x5E, 0x8B, 0x3E,
+		0xCF, 0x77, 0xD5, 0xB2, 0xD7, 0xF7, 0xBF, 0xC4,
+		0xF9, 0x87, 0xC1, 0xB9, 0xE2, 0xF9, 0x13, 0x60,
+		0xB0, 0x3E, 0x90, 0xA3, 0x24, 0x11, 0xC9, 0x13,
+		0x35, 0xB6, 0x92, 0xBE, 0xC7, 0x04, 0x5E, 0x5B,
+		0x04, 0x91, 0xE1, 0x2C, 0x3E, 0x0E, 0x95, 0x53,
+		0xF1, 0x50, 0x39, 0x83, 0xEE, 0xC4, 0xF3, 0x85,
+		0x92, 0x2B, 0xC6, 0xFC, 0xAB, 0xF3, 0x1F, 0x0B,
+		0x20, 0x24, 0x4D, 0x9B, 0xB8, 0x79, 0x5B, 0x3C,
+		0x5A, 0x88, 0x4D, 0x4D, 0x32, 0xC8, 0x9D, 0x95,
+		0x52, 0xCC, 0xFC, 0x1F, 0xD3, 0x4E, 0x20, 0xB2,
+		0xC0, 0x9E, 0x4D, 0xE5, 0x95, 0xB1, 0xCA, 0xA3,
+		0x57, 0x59, 0xDC, 0x49, 0x23, 0x42, 0x25, 0x9B,
+		0x0C, 0xF6, 0x95, 0x0A, 0x08, 0x09, 0xC8, 0xD8,
+		0xDC, 0xC0, 0x00, 0x71, 0x49, 0x21, 0x5F, 0x9F,
+		0x39, 0x80, 0x3A, 0x30, 0x23, 0x85, 0xAA, 0x9D,
+		0x44, 0xB2, 0xD4, 0x83, 0x5D, 0x61, 0xA7, 0xA9,
+		0xE0, 0x55, 0x2F, 0x8E, 0x30, 0x23, 0x09, 0x55,
+		0x9F, 0x33, 0xB9, 0x32, 0xF3, 0x8C, 0x2B, 0xFA,
+		0xEF, 0xF3, 0x8B, 0x8A, 0x78, 0x5E, 0x69, 0x47,
+		0xE8, 0xEA, 0x0A, 0x73, 0x51, 0x33, 0x12, 0x6D,
+		0x80, 0xCB, 0xCE, 0xEF, 0x08, 0xCF, 0xF0, 0xDB,
+		0xFF, 0xF2, 0x4B, 0x5B, 0x85, 0x35, 0x71, 0x54,
+		0x3F, 0x73, 0x6A, 0x72, 0xC2, 0x85, 0x35, 0x4E,
+		0xBE, 0x20, 0x6F, 0xA8, 0xCC, 0x12, 0xFF, 0x3C,
+		0x10, 0xCF, 0xDC, 0x3D, 0xC9, 0x4D, 0x16, 0x45,
+		0xB3, 0x41, 0xC1, 0x8E, 0x22, 0x0E, 0x52, 0xD8,
+		0x68, 0xE7, 0x1C, 0x6F, 0x6E, 0x13, 0xF8, 0x6B,
+		0xD4, 0x66, 0xAB, 0x69, 0x7A, 0x53, 0x48, 0x95,
+		0x7D, 0x6A, 0x3B, 0x94, 0x14, 0xA0, 0x2D, 0x09,
+		0x75, 0x05, 0x5B, 0xF8, 0xDA, 0x94, 0x15, 0x1B,
+		0x35, 0xC3, 0xCF, 0x05, 0xD8, 0xCC, 0x31, 0x56,
+		0x27, 0xB4, 0xEA, 0x25, 0x98, 0x7C, 0xBE, 0x44,
+		0x5D, 0x73, 0x0D, 0x42, 0xBF, 0xF7, 0x4B, 0x35,
+		0x37, 0x4D, 0x90, 0xBF, 0x73, 0xC0, 0xDD, 0x79,
+		0x8C, 0x77, 0x0D, 0x20, 0x08, 0x95, 0x23, 0xEA,
+		0x90, 0x47, 0x3E, 0x06, 0x74, 0x1D, 0x8E, 0x33,
+		0x6E, 0x0F, 0xD1, 0xFD, 0xD0, 0x8E, 0x28, 0x55,
+		0x0B, 0xC1, 0x2B, 0x56, 0x1D, 0x72, 0x3F, 0xC5,
+		0xD1, 0xB3, 0x0D, 0xC7, 0x43, 0x27, 0x40, 0x0D,
+		0x2D, 0x6A, 0xF4, 0x08, 0xEF, 0x68, 0xE3, 0x12,
+		0x37, 0x44, 0xE9, 0xCA, 0xBB, 0xD0, 0xD7, 0x53,
+		0x42, 0x6C, 0xCF, 0xAA, 0xAA, 0x06, 0x51, 0xAB,
+		0x26, 0xF4, 0xD6, 0x74, 0xE4, 0x5E, 0x71, 0x3F,
+		0xFC, 0x9E, 0x32, 0xEB, 0x93, 0x1B, 0x10, 0x33,
+		0xF2, 0x36, 0x93, 0xAE, 0xDC, 0xFC, 0xC5, 0x5E,
+		0x19, 0x7B, 0xFE, 0x48, 0xE8, 0x9F, 0x64, 0xB6,
+		0xCB, 0xD7, 0xA9, 0xB7, 0xA3, 0x10, 0x1A, 0x5A,
+		0x43, 0xD1, 0x91, 0x1E, 0x4C, 0x9B, 0x86, 0xDE,
+		0x40, 0x5D, 0xD1, 0x94, 0x1F, 0x70, 0xA2, 0x70,
+		0xD4, 0x48, 0x83, 0xB0, 0xC4, 0x83, 0x7A, 0x63,
+		0x7E, 0x35, 0x5D, 0x56, 0x12, 0x85, 0x00, 0x9D,
+		0x24, 0x22, 0x3C, 0x53, 0x73, 0xFD, 0xD7, 0x5D,
+		0x85, 0x30, 0x7C, 0x59, 0x73, 0xDA, 0x5A, 0xDB,
+		0x55, 0xD2, 0x35, 0x27, 0xFB, 0x07, 0x9A, 0x3F,
+		0x3A, 0xBF, 0x43, 0x27, 0x26, 0x09, 0x22, 0xF1,
+		0x20, 0xC2, 0xDB, 0x82, 0xAA, 0xB6, 0xDD, 0x42,
+		0x26, 0x1F, 0xB0, 0x9D, 0x28, 0xE5, 0x74, 0xF0,
+		0x52, 0xE3, 0xBA, 0x5F, 0x87, 0x4A, 0xAE, 0xAA,
+		0xB0, 0xCA, 0xC1, 0x05, 0x14, 0x98, 0xA1, 0x78,
+		0x52, 0x83, 0x4F, 0xCC, 0xCB, 0x6C, 0xF2, 0xCE,
+		0x17, 0xE3, 0x71, 0x30, 0x63, 0x2C, 0xAE, 0xDE,
+		0x61, 0xBC, 0xA8, 0x9A, 0xFA, 0xFD, 0xF2, 0x0C
+};
+
+static const struct test_crypto_vector
+aes192ctr_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_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,
+			0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+		},
+		.len = 16
+	},
+	.plaintext = {
+		.data = plaintext_aes,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_aes192ctr,
+		.len = 512
+	}
+};
+
+static const uint8_t ciphertext_aes256ctr[] = {
+		0xD6, 0xCA, 0xD5, 0xA9, 0x99, 0x8A, 0x90, 0xE2,
+		0x08, 0x9A, 0x19, 0x6D, 0x8C, 0xF5, 0x8C, 0x31,
+		0xDA, 0x78, 0xF7, 0xAE, 0x99, 0x1A, 0x72, 0x36,
+		0xBC, 0x44, 0x77, 0x76, 0x23, 0x54, 0x6E, 0x4B,
+		0xD8, 0x29, 0x40, 0x07, 0x7F, 0x03, 0x39, 0x52,
+		0xC0, 0xA0, 0xA3, 0xF0, 0xB6, 0x1A, 0xED, 0xCB,
+		0x19, 0x1C, 0x9A, 0x6A, 0x80, 0xE0, 0x61, 0x93,
+		0xA9, 0xFC, 0x76, 0x28, 0x82, 0x99, 0xAC, 0x67,
+		0x55, 0x2C, 0x8F, 0x53, 0x41, 0xAA, 0x19, 0x5D,
+		0xDA, 0xFB, 0x8B, 0x45, 0x81, 0x73, 0xEC, 0x22,
+		0x01, 0xED, 0xED, 0x57, 0xF3, 0x2E, 0x9D, 0xCF,
+		0x07, 0x72, 0xCC, 0x3E, 0x32, 0x22, 0x1C, 0xDF,
+		0x3A, 0xC3, 0x5F, 0xE5, 0x65, 0xFB, 0x8F, 0x5D,
+		0xC7, 0xBE, 0xEC, 0x9C, 0xC0, 0x8F, 0x8A, 0x28,
+		0xE7, 0x9E, 0x95, 0xCC, 0xE6, 0xAD, 0x60, 0x3B,
+		0xF6, 0x9C, 0x30, 0x69, 0xEE, 0xA8, 0xF3, 0x7D,
+		0x39, 0x95, 0x81, 0x1D, 0x24, 0xE3, 0x53, 0xD3,
+		0x46, 0x2C, 0x20, 0x79, 0xFE, 0x51, 0x58, 0x59,
+		0x46, 0xAF, 0xE8, 0xB7, 0x08, 0x73, 0xFF, 0xE6,
+		0x59, 0x9B, 0x3C, 0xF7, 0x5B, 0xD0, 0xDF, 0x81,
+		0x16, 0xD6, 0x97, 0xD4, 0xA8, 0x05, 0x1D, 0x0E,
+		0x75, 0xE6, 0xE6, 0xA2, 0xA1, 0x47, 0x16, 0x8D,
+		0x12, 0x6D, 0xFD, 0xAB, 0x8F, 0xAE, 0x0A, 0xD9,
+		0x59, 0x29, 0x69, 0x6D, 0x33, 0xC9, 0xEA, 0x28,
+		0x4C, 0x7D, 0xEF, 0x7E, 0x44, 0x1A, 0x76, 0xF1,
+		0xC1, 0xDB, 0xE3, 0x0F, 0x4F, 0xD7, 0xAE, 0x3A,
+		0x28, 0x7B, 0x9C, 0xA6, 0x8C, 0xD8, 0x19, 0x86,
+		0x81, 0x8B, 0xC6, 0x38, 0xCB, 0x17, 0x46, 0x2B,
+		0x22, 0x8E, 0x7A, 0xB2, 0xC0, 0xF9, 0x9A, 0x5F,
+		0xA2, 0x2F, 0x75, 0x1B, 0x9F, 0x86, 0x7A, 0x9C,
+		0x69, 0x0F, 0xA1, 0x71, 0xCB, 0x71, 0x18, 0x1B,
+		0x5C, 0xF7, 0xD4, 0x64, 0x09, 0x58, 0x90, 0xDC,
+		0x82, 0xA8, 0x31, 0xBB, 0x4D, 0x38, 0xE3, 0x97,
+		0x32, 0x4C, 0xD7, 0x26, 0x29, 0x61, 0x9D, 0x8C,
+		0x26, 0x42, 0x82, 0x0C, 0x7A, 0xE4, 0xEB, 0x7F,
+		0x26, 0xE1, 0xD1, 0x35, 0x88, 0x4F, 0xBE, 0xDC,
+		0xA6, 0x0C, 0xCE, 0xB4, 0xFF, 0x85, 0x31, 0x07,
+		0x93, 0xFD, 0xA3, 0x98, 0xFA, 0x44, 0x3C, 0x91,
+		0xED, 0x15, 0x3E, 0x76, 0x06, 0xDE, 0xC9, 0x43,
+		0xA5, 0x95, 0x5B, 0xB4, 0xF5, 0xD9, 0x16, 0x8E,
+		0x18, 0x76, 0xAD, 0x62, 0x93, 0xFB, 0xF6, 0x3D,
+		0xB1, 0x3F, 0xAE, 0xE0, 0x98, 0xD4, 0xA4, 0xF0,
+		0x6D, 0x1B, 0x39, 0x36, 0x91, 0x49, 0x5E, 0x42,
+		0x7D, 0xAB, 0x84, 0xA6, 0x3C, 0xD4, 0x6B, 0xF9,
+		0xAA, 0x1F, 0x2E, 0x07, 0xC1, 0xA9, 0x5F, 0xC9,
+		0x00, 0xCC, 0x0F, 0x19, 0xD9, 0xB5, 0x49, 0x06,
+		0x81, 0x05, 0x78, 0xE8, 0x49, 0x02, 0xCC, 0x31,
+		0x52, 0x01, 0x17, 0x76, 0xFB, 0xEF, 0x0E, 0x99,
+		0xA2, 0x71, 0x22, 0xEB, 0x78, 0x48, 0xBB, 0xF5,
+		0x6B, 0x50, 0x2A, 0x39, 0xA0, 0x66, 0xC1, 0x72,
+		0xBD, 0x40, 0x99, 0x86, 0xFE, 0x80, 0xE4, 0x69,
+		0x30, 0x05, 0x7A, 0xD7, 0xFD, 0x6E, 0x1A, 0x73,
+		0xA4, 0x54, 0x5F, 0x61, 0xF2, 0x4B, 0x6B, 0x6C,
+		0x90, 0x9C, 0x50, 0x7F, 0xDA, 0xA1, 0x5C, 0x8D,
+		0x06, 0x29, 0x37, 0x55, 0x88, 0xAD, 0xAB, 0x3F,
+		0x03, 0x62, 0x7C, 0x35, 0xB5, 0x30, 0xAA, 0x04,
+		0xC5, 0xBD, 0x87, 0x20, 0x29, 0xA3, 0xAD, 0x65,
+		0x00, 0x5D, 0x04, 0xA3, 0x6F, 0x2C, 0x23, 0x23,
+		0xBA, 0x89, 0x40, 0x0B, 0x2B, 0x7E, 0x68, 0x96,
+		0x18, 0xEC, 0x53, 0x0F, 0x9C, 0x05, 0x4B, 0xA1,
+		0xE7, 0x10, 0x52, 0x7B, 0xEA, 0xD1, 0x17, 0x05,
+		0xD0, 0x5E, 0x35, 0xC6, 0x4C, 0x8A, 0xE3, 0xBF,
+		0x73, 0x5B, 0x5A, 0x4E, 0xB1, 0x78, 0xE0, 0x13,
+		0xF0, 0x3F, 0x06, 0xDC, 0x28, 0x2A, 0xBD, 0x45
+};
+
+static const struct test_crypto_vector
+aes256ctr_test_vector = {
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_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,
+			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,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_aes256ctr,
+		.len = 512
+	}
+};
+
+static const uint8_t ciphertext_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
+};
+
+static const struct test_crypto_vector
+aes128cbc_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_aes,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_aes128cbc,
+		.len = 512
+	},
+};
+
+static const struct test_crypto_vector
+aes128cbc_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_aes,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_aes128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1,
+	.digest = {
+		.data = {
+			0x61, 0xe6, 0x29, 0x3c, 0x1a, 0x93, 0x73, 0x26,
+			0xb3, 0x35, 0xdd, 0x4b, 0x23, 0xef, 0x19, 0x6f,
+			0x6e, 0x4f, 0x0e, 0xfd
+		},
+		.len = 20
+	}
+};
+
+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_aes,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_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 const struct test_crypto_vector
+aes128cbc_aes128_gmac_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_aes,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_aes128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_AES_GMAC,
+	.auth_key = {
+		.data = {
+			0x42, 0x1A, 0x7D, 0x3D, 0xF5, 0x82, 0x80, 0xF1,
+			0xF1, 0x35, 0x5C, 0x3B, 0xDD, 0x9A, 0x65, 0xBA
+		},
+		.len = 16
+	},
+	.digest = {
+		.data = {
+			0x6B, 0x5B, 0xDF, 0xDA, 0x75, 0x18, 0x72, 0xD5,
+			0x67, 0x59, 0xA6, 0xCC, 0x3E, 0x74, 0x62, 0xFF
+		},
+		.len = 16
+	}
+};
+
+static const struct test_crypto_vector
+aes128cbc_aes192_gmac_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_aes,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_aes128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_AES_GMAC,
+	.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
+		},
+		.len = 24
+	},
+	.digest = {
+		.data = {
+			0xE8, 0x56, 0xFE, 0x75, 0x94, 0x64, 0xC9, 0x51,
+			0xDD, 0x97, 0x74, 0xEE, 0xB6, 0x2D, 0x3F, 0x12
+		},
+		.len = 16
+	}
+};
+
+static const struct test_crypto_vector
+aes128cbc_aes256_gmac_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_aes,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_aes128cbc,
+		.len = 512
+	},
+	.auth_algo = RTE_CRYPTO_AUTH_AES_GMAC,
+	.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 = {
+			0x9A, 0x98, 0x04, 0x7E, 0x30, 0xF7, 0x03, 0x79,
+			0x54, 0xAF, 0x2D, 0x7B, 0x35, 0xBA, 0x65, 0xE9
+		},
+		.len = 16
+	}
+};
+
+static const uint8_t ciphertext_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
+};
+
+static const struct test_crypto_vector
+aes192cbc_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,
+			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,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_aes192cbc,
+		.len = 512
+	}
+};
+
+static const uint8_t ciphertext_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
+};
+
+static const struct test_crypto_vector
+aes256cbc_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,
+			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,
+		.len = 512
+	},
+	.ciphertext = {
+		.data = ciphertext_aes256cbc,
+		.len = 512
+	}
+};
+
+#endif /* TEST_CRYPTODEV_AES_TEST_VECTORS_H_ */
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..5fc5402
--- /dev/null
+++ b/app/test/test_cryptodev_des_test_vectors.h
@@ -0,0 +1,754 @@
+/*
+ *   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 ciphertext_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 test_crypto_vector
+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 = ciphertext_des128ctr,
+		.len = 512
+	}
+};
+
+static const struct test_crypto_vector
+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 = ciphertext_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 test_crypto_vector
+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 = ciphertext_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 ciphertext_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 test_crypto_vector
+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 = ciphertext_des192ctr,
+		.len = 512
+	}
+};
+
+static const struct test_crypto_vector
+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 = ciphertext_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 test_crypto_vector
+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 = ciphertext_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 ciphertext_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 test_crypto_vector
+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 = ciphertext_des128cbc,
+		.len = 512
+	}
+};
+
+static const struct test_crypto_vector
+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 = ciphertext_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 test_crypto_vector
+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 = ciphertext_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 ciphertext_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 test_crypto_vector
+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 = ciphertext_des192cbc,
+		.len = 512
+	},
+};
+
+static const struct test_crypto_vector
+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 = ciphertext_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 test_crypto_vector
+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 = ciphertext_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
+	}
+};
+
+#endif /* TEST_CRYPTODEV_DES_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..f1ce14f
--- /dev/null
+++ b/app/test/test_cryptodev_hash_test_vectors.h
@@ -0,0 +1,439 @@
+/*
+ *   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 test_crypto_vector
+md5_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_MD5,
+	.plaintext = {
+		.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 test_crypto_vector
+hmac_md5_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_MD5_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
+		},
+		.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 test_crypto_vector
+sha1_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA1,
+	.plaintext = {
+		.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 test_crypto_vector
+hmac_sha1_test_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
+sha224_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA224,
+	.plaintext = {
+		.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 test_crypto_vector
+hmac_sha224_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA224_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, 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 test_crypto_vector
+sha256_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA256,
+	.plaintext = {
+		.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 test_crypto_vector
+hmac_sha256_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA256_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, 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 test_crypto_vector
+sha384_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA384,
+	.plaintext = {
+		.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 test_crypto_vector
+hmac_sha384_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA384_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, 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 test_crypto_vector
+sha512_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA512,
+	.plaintext = {
+		.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 test_crypto_vector
+hmac_sha512_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_SHA512_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, 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 test_crypto_vector
+aes128_gmac_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_AES_GMAC,
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_GCM,
+	.plaintext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B
+		},
+		.len = 12
+	},
+	.auth_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
+aes192_gmac_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_AES_GMAC,
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_GCM,
+	.plaintext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B
+		},
+		.len = 12
+	},
+	.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
+		},
+		.len = 24
+	},
+	.digest = {
+		.data = {
+			0x71, 0x74, 0x5B, 0xB1, 0xE4, 0xCA, 0x27, 0xD3,
+			0x89, 0xF2, 0x8C, 0x5F, 0x55, 0xEE, 0x80, 0x0F
+		},
+		.len = 16
+	}
+};
+
+static const struct test_crypto_vector
+aes256_gmac_test_vector = {
+	.auth_algo = RTE_CRYPTO_AUTH_AES_GMAC,
+	.crypto_algo = RTE_CRYPTO_CIPHER_AES_GCM,
+	.plaintext = {
+		.data = plaintext_hash,
+		.len = 512
+	},
+	.iv = {
+		.data = {
+			0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+			0x08, 0x09, 0x0A, 0x0B
+		},
+		.len = 12
+	},
+	.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 = {
+			0x82, 0x09, 0xF7, 0x5F, 0x3C, 0xEB, 0xB7, 0xE6,
+			0xC3, 0x6F, 0x9C, 0xB7, 0x40, 0xDD, 0xBD, 0xE8
+		},
+		.len = 16
+	}
+};
+
+#endif /* TEST_CRYPTODEV_HASH_TEST_VECTORS_H_ */
diff --git a/app/test/test_cryptodev_kasumi_test_vectors.h b/app/test/test_cryptodev_kasumi_test_vectors.h
index 9163d7c..d49942a 100644
--- a/app/test/test_cryptodev_kasumi_test_vectors.h
+++ b/app/test/test_cryptodev_kasumi_test_vectors.h
@@ -36,30 +36,30 @@
 struct kasumi_test_data {
 	struct {
 		uint8_t data[64];
-		unsigned len;
+		unsigned int len;
 	} key;
 
 	struct {
 		uint8_t data[64] __rte_aligned(16);
-		unsigned len;
+		unsigned int len;
 	} iv;
 
 	struct {
 		uint8_t data[1024];
-		unsigned len; /* length must be in Bits */
+		unsigned int len; /* length must be in Bits */
 	} plaintext;
 
 	struct {
 		uint8_t data[1024];
-		unsigned len; /* length must be in Bits */
+		unsigned int len; /* length must be in Bits */
 	} ciphertext;
 
 	struct {
-		unsigned len;
+		unsigned int len;
 	} validCipherLenInBits;
 
 	struct {
-		unsigned len;
+		unsigned int len;
 	} validCipherOffsetLenInBits;
 };
 
diff --git a/app/test/test_cryptodev_operations.c b/app/test/test_cryptodev_operations.c
new file mode 100644
index 0000000..0e707c1
--- /dev/null
+++ b/app/test/test_cryptodev_operations.c
@@ -0,0 +1,1576 @@
+/*
+ *   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_mbuf.h>
+#include <rte_malloc.h>
+
+#include <rte_crypto.h>
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
+
+#include "test.h"
+#include "test_cryptodev.h"
+#include "test_cryptodev_operations.h"
+
+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)
+{
+	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_cipher_session(struct crypto_unittest_params *ut_params,
+		uint8_t dev_id,
+		const struct test_crypto_vector *reference,
+		enum rte_crypto_cipher_operation cipher_op,
+		uint8_t *cipher_key)
+{
+	memcpy(cipher_key, reference->cipher_key.data, reference->cipher_key.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->cipher_xform);
+
+	TEST_ASSERT_NOT_NULL(ut_params->sess, "Session creation failed");
+
+	return 0;
+}
+
+static int
+create_cipher_auth_session(struct crypto_unittest_params *ut_params,
+		uint8_t dev_id,
+		const struct test_crypto_vector *reference,
+		enum rte_crypto_cipher_operation cipher_op,
+		enum rte_crypto_auth_operation auth_op,
+		uint8_t *cipher_key,
+		uint8_t *auth_key)
+{
+	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 = 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;
+
+	/* Setup Cipher Parameters */
+	ut_params->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+	ut_params->cipher_xform.next = &ut_params->auth_xform;
+	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->cipher_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 *auth_key,
+		uint8_t *cipher_key)
+{
+	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_cipher_auth_xforms(struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference,
+		enum rte_crypto_cipher_operation cipher_op,
+		enum rte_crypto_auth_operation auth_op,
+		uint8_t *cipher_key,
+		uint8_t *auth_key)
+{
+	memcpy(cipher_key, reference->cipher_key.data, reference->cipher_key.len);
+	memcpy(auth_key, reference->auth_key.data, reference->auth_key.len);
+
+	TEST_ASSERT_NOT_NULL(rte_crypto_op_sym_xforms_alloc(ut_params->op, 2),
+			"failed to allocate space for crypto transforms");
+
+	struct rte_crypto_sym_op *sym_op = ut_params->op->sym;
+
+	/* Setup Authentication Parameters */
+	sym_op->xform->next->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+	sym_op->xform->next->auth.op = auth_op;
+	sym_op->xform->next->auth.algo = reference->auth_algo;
+	sym_op->xform->next->auth.key.length = reference->auth_key.len;
+	sym_op->xform->next->auth.key.data = auth_key;
+	sym_op->xform->next->auth.digest_length = reference->digest.len;
+	sym_op->xform->next->auth.add_auth_data_length = reference->aad.len;
+
+	/* Setup Cipher Parameters */
+	sym_op->xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+	sym_op->xform->cipher.algo = reference->crypto_algo;
+	sym_op->xform->cipher.op = cipher_op;
+	sym_op->xform->cipher.key.data = cipher_key;
+	sym_op->xform->cipher.key.length = reference->cipher_key.len;
+
+	return 0;
+}
+
+static int
+create_auth_cipher_xforms(struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference,
+		enum rte_crypto_auth_operation auth_op,
+		enum rte_crypto_cipher_operation cipher_op,
+		uint8_t *auth_key,
+		uint8_t *cipher_key)
+{
+	memcpy(cipher_key, reference->cipher_key.data, reference->cipher_key.len);
+	memcpy(auth_key, reference->auth_key.data, reference->auth_key.len);
+
+	TEST_ASSERT_NOT_NULL(rte_crypto_op_sym_xforms_alloc(ut_params->op, 2),
+			"failed to allocate space for crypto transforms");
+
+	struct rte_crypto_sym_op *sym_op = ut_params->op->sym;
+
+	/* Setup Authentication Parameters */
+	sym_op->xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+	sym_op->xform->auth.op = auth_op;
+	sym_op->xform->auth.algo = reference->auth_algo;
+	sym_op->xform->auth.key.length = reference->auth_key.len;
+	sym_op->xform->auth.key.data = auth_key;
+	sym_op->xform->auth.digest_length = reference->digest.len;
+	sym_op->xform->auth.add_auth_data_length = reference->aad.len;
+
+	/* Setup Cipher Parameters */
+	sym_op->xform->next->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+	sym_op->xform->next->cipher.algo = reference->crypto_algo;
+	sym_op->xform->next->cipher.op = cipher_op;
+	sym_op->xform->next->cipher.key.data = cipher_key;
+	sym_op->xform->next->cipher.key.length = reference->cipher_key.len;
+
+	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_generate_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, 1);
+}
+
+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_cipher_operation(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	/* 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;
+
+	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;
+
+	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_cipher_auth_generate_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, 1);
+}
+
+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
+create_cipher_auth_sessionless_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");
+
+	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_cipher_auth_generate_sessionless_operation(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return create_cipher_auth_sessionless_operation(
+			ts_params, ut_params, reference, 1);
+}
+
+static int
+create_cipher_auth_verify_sessionless_operation(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return create_cipher_auth_sessionless_operation(
+			ts_params, ut_params, reference, 0);
+}
+
+static int
+create_cipher_auth_out_of_place_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;
+
+	/* set crypto operation destination mbuf */
+	sym_op->m_dst = ut_params->obuf;
+
+	/* digest */
+	if (auth_generate) {
+		sym_op->auth.digest.data = (uint8_t *)rte_pktmbuf_append(
+				ut_params->obuf, 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->obuf, reference->ciphertext.len);
+		sym_op->auth.digest.length = reference->digest.len;
+		memset(sym_op->auth.digest.data, 0, reference->digest.len);
+	} else {
+		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;
+		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 input iv");
+
+	TEST_ASSERT_NOT_NULL(
+			rte_pktmbuf_prepend(ut_params->obuf, reference->iv.len),
+			"no room to prepend output 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_cipher_auth_generate_out_of_place_operation(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return create_cipher_auth_out_of_place_operation(
+			ts_params, ut_params, reference, 1);
+}
+
+static int
+create_cipher_auth_verify_out_of_place_operation(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	return create_cipher_auth_out_of_place_operation(
+			ts_params, ut_params, reference, 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;
+
+	/* 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 = reference->plaintext.len;
+	sym_op->auth.data.offset = reference->iv.len;
+
+	return 0;
+}
+
+static int
+create_auth_generate_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, 1);
+}
+
+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 struct rte_crypto_op *
+process_crypto_request(uint8_t dev_id, struct rte_crypto_op *op)
+{
+	if (rte_cryptodev_enqueue_burst(dev_id, 0, &op, 1) != 1) {
+		printf("Error sending packet for encryption");
+		return NULL;
+	}
+
+	op = NULL;
+
+	while (rte_cryptodev_dequeue_burst(dev_id, 0, &op, 1) == 0)
+		rte_pause();
+
+	return op;
+}
+
+int
+test_authentication(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext, *digest;
+	uint8_t auth_key[reference->auth_key.len + 1];
+
+	/* Create session */
+	retval = create_auth_session(ut_params,
+			ts_params->valid_devs[0],
+			reference,
+			RTE_CRYPTO_AUTH_OP_GENERATE,
+			auth_key);
+	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_generate_operation(ts_params, ut_params, reference);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *);
+
+	digest = plaintext + reference->plaintext.len;
+
+	TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+			plaintext,
+		reference->plaintext.data,
+		reference->plaintext.len,
+		"Plaintext data not as expected");
+
+	TEST_HEXDUMP(stdout, "digest:", digest, reference->digest.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		digest,
+		reference->digest.data,
+		reference->digest.len,
+		"Generated auth tag not as expected");
+
+	return 0;
+}
+
+int
+test_authentication_verify(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext;
+	uint8_t auth_key[reference->auth_key.len + 1];
+
+	/* Create session */
+	retval = create_auth_session(ut_params,
+			ts_params->valid_devs[0],
+			reference,
+			RTE_CRYPTO_AUTH_OP_VERIFY,
+			auth_key);
+	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;
+
+	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_NOT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_AUTH_FAILED,
+			"authentication failed");
+	TEST_ASSERT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *);
+
+	TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		plaintext,
+		reference->plaintext.data,
+		reference->plaintext.len,
+		"Plaintext data not as expected");
+
+	return 0;
+}
+
+int
+test_encryption(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext, *ciphertext;
+	uint8_t cipher_key[reference->cipher_key.len + 1];
+
+	/* Create session */
+	retval = create_cipher_session(ut_params,
+			ts_params->valid_devs[0],
+			reference,
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+			cipher_key);
+	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_cipher_operation(ts_params, ut_params, reference);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *)
+			+ reference->iv.len;
+
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, reference->ciphertext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		ciphertext,
+		reference->ciphertext.data,
+		reference->ciphertext.len,
+		"Ciphertext data not as expected");
+
+	return 0;
+}
+
+int
+test_decryption(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext, *ciphertext;
+	uint8_t cipher_key[reference->cipher_key.len + 1];
+
+	/* Create session */
+	retval = create_cipher_session(ut_params,
+			ts_params->valid_devs[0],
+			reference,
+			RTE_CRYPTO_CIPHER_OP_DECRYPT,
+			cipher_key);
+	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);
+
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, reference->ciphertext.len);
+
+	/* Create operation */
+	retval = create_cipher_operation(ts_params, ut_params, reference);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *)
+			+ reference->iv.len;
+
+	TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		plaintext,
+		reference->plaintext.data,
+		reference->plaintext.len,
+		"Plaintext data not as expected");
+
+	return 0;
+}
+
+int
+test_authenticated_encryption(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext, *ciphertext, *digest;
+	uint8_t cipher_key[reference->cipher_key.len + 1];
+	uint8_t auth_key[reference->auth_key.len + 1];
+
+	/* Create session */
+	retval = create_cipher_auth_session(ut_params,
+			ts_params->valid_devs[0],
+			reference,
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+			RTE_CRYPTO_AUTH_OP_GENERATE,
+			cipher_key,
+			auth_key);
+	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_cipher_auth_generate_operation(ts_params,
+			ut_params,
+			reference);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *)
+			+ reference->iv.len;
+
+	digest = ciphertext + reference->ciphertext.len;
+
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, reference->ciphertext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		ciphertext,
+		reference->ciphertext.data,
+		reference->ciphertext.len,
+		"Ciphertext data not as expected");
+
+	TEST_HEXDUMP(stdout, "digest:", digest, reference->digest.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		digest,
+		reference->digest.data,
+		reference->digest.len,
+		"Generated auth tag not as expected");
+
+	return 0;
+}
+
+int
+test_authenticated_decryption(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext, *ciphertext;
+	uint8_t auth_key[reference->auth_key.len + 1];
+	uint8_t cipher_key[reference->cipher_key.len + 1];
+
+	/* 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,
+			auth_key,
+			cipher_key);
+	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);
+
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, reference->ciphertext.len);
+
+	/* Create operation */
+	retval = create_cipher_auth_verify_operation(ts_params,
+			ut_params,
+			reference);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_NOT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_AUTH_FAILED,
+			"authentication failed");
+	TEST_ASSERT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *)
+			+ reference->iv.len;
+
+	TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		plaintext,
+		reference->plaintext.data,
+		reference->plaintext.len,
+		"Plaintext data not as expected");
+
+	return 0;
+}
+
+int
+test_authenticated_encryption_sessionless(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext, *ciphertext, *digest;
+	uint8_t cipher_key[reference->cipher_key.len + 1];
+	uint8_t auth_key[reference->auth_key.len + 1];
+
+	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_cipher_auth_generate_sessionless_operation(ts_params,
+			ut_params,
+			reference);
+	if (retval < 0)
+		return retval;
+
+	/* Create xforms */
+	retval = create_cipher_auth_xforms(ut_params,
+			reference,
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+			RTE_CRYPTO_AUTH_OP_GENERATE,
+			cipher_key,
+			auth_key);
+	if (retval < 0)
+		return retval;
+
+	TEST_ASSERT_EQUAL(ut_params->op->sym->sess_type,
+			RTE_CRYPTO_SYM_OP_SESSIONLESS,
+			"crypto op session type not sessionless");
+
+	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_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *)
+			+ reference->iv.len;
+
+	digest = ciphertext + reference->ciphertext.len;
+
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, reference->ciphertext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		ciphertext,
+		reference->ciphertext.data,
+		reference->ciphertext.len,
+		"Ciphertext data not as expected");
+
+	TEST_HEXDUMP(stdout, "digest:", digest, reference->digest.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		digest,
+		reference->digest.data,
+		reference->digest.len,
+		"Generated auth tag not as expected");
+
+	return 0;
+}
+
+int
+test_authenticated_decryption_sessionless(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext, *ciphertext;
+	uint8_t auth_key[reference->auth_key.len + 1];
+	uint8_t cipher_key[reference->cipher_key.len + 1];
+
+	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);
+
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, reference->ciphertext.len);
+
+	/* Create operation */
+	retval = create_cipher_auth_verify_sessionless_operation(ts_params,
+			ut_params,
+			reference);
+	if (retval < 0)
+		return retval;
+
+	/* Create xforms */
+	retval = create_auth_cipher_xforms(ut_params,
+			reference,
+			RTE_CRYPTO_AUTH_OP_VERIFY,
+			RTE_CRYPTO_CIPHER_OP_DECRYPT,
+			auth_key,
+			cipher_key);
+	if (retval < 0)
+		return retval;
+
+	TEST_ASSERT_EQUAL(ut_params->op->sym->sess_type,
+			RTE_CRYPTO_SYM_OP_SESSIONLESS,
+			"crypto op session type not sessionless");
+
+	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_NOT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_AUTH_FAILED,
+			"authentication failed");
+	TEST_ASSERT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *)
+			+ reference->iv.len;
+
+	TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		plaintext,
+		reference->plaintext.data,
+		reference->plaintext.len,
+		"Plaintext data not as expected");
+
+	return 0;
+}
+
+int
+test_authenticated_encryption_out_of_place(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext, *ciphertext, *digest;
+	uint8_t cipher_key[reference->cipher_key.len + 1];
+	uint8_t auth_key[reference->auth_key.len + 1];
+
+	/* Create session */
+	retval = create_cipher_auth_session(ut_params,
+			ts_params->valid_devs[0],
+			reference,
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT,
+			RTE_CRYPTO_AUTH_OP_GENERATE,
+			cipher_key,
+			auth_key);
+	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");
+	ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+	TEST_ASSERT_NOT_NULL(ut_params->obuf,
+			"Failed to allocate output buffer in mempool");
+
+	/* clear mbufs payload */
+	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->ibuf));
+	memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->obuf));
+
+	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);
+
+	ciphertext = (uint8_t *)rte_pktmbuf_append(ut_params->obuf,
+			reference->ciphertext.len);
+	TEST_ASSERT_NOT_NULL(ciphertext, "no room to append ciphertext");
+	memset(ciphertext, 0, reference->ciphertext.len);
+
+	/* Create operation */
+	retval = create_cipher_auth_generate_out_of_place_operation(ts_params,
+			ut_params,
+			reference);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_dst;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	ciphertext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *)
+			+ reference->iv.len;
+
+	digest = ciphertext + reference->ciphertext.len;
+
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, reference->ciphertext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		ciphertext,
+		reference->ciphertext.data,
+		reference->ciphertext.len,
+		"Ciphertext data not as expected");
+
+	TEST_HEXDUMP(stdout, "digest:", digest, reference->digest.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		digest,
+		reference->digest.data,
+		reference->digest.len,
+		"Generated auth tag not as expected");
+
+	return 0;
+}
+
+int
+test_authenticated_decryption_out_of_place(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext, *ciphertext;
+	uint8_t auth_key[reference->auth_key.len + 1];
+	uint8_t cipher_key[reference->cipher_key.len + 1];
+
+	/* 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,
+			auth_key,
+			cipher_key);
+	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");
+	ut_params->obuf = rte_pktmbuf_alloc(ts_params->mbuf_pool);
+	TEST_ASSERT_NOT_NULL(ut_params->obuf,
+			"Failed to allocate output buffer in mempool");
+
+	/* clear mbufs payload */
+	memset(rte_pktmbuf_mtod(ut_params->ibuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->ibuf));
+	memset(rte_pktmbuf_mtod(ut_params->obuf, uint8_t *), 0,
+			rte_pktmbuf_tailroom(ut_params->obuf));
+
+	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);
+
+	TEST_HEXDUMP(stdout, "ciphertext:", ciphertext, reference->ciphertext.len);
+
+	plaintext = (uint8_t *)rte_pktmbuf_append(ut_params->obuf,
+			reference->plaintext.len);
+	TEST_ASSERT_NOT_NULL(plaintext, "no room to append plaintext");
+	memset(plaintext, 0, reference->plaintext.len);
+
+	/* Create operation */
+	retval = create_cipher_auth_verify_out_of_place_operation(ts_params,
+			ut_params,
+			reference);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_NOT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_AUTH_FAILED,
+			"authentication failed");
+	TEST_ASSERT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_dst;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *)
+			+ reference->iv.len;
+
+	TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		plaintext,
+		reference->plaintext.data,
+		reference->plaintext.len,
+		"Plaintext data not as expected");
+
+	return 0;
+}
+
+int
+test_authentication_GMAC(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext, *digest;
+	uint8_t auth_key[reference->auth_key.len + 1];
+
+	/* Create session */
+	retval = create_auth_session(ut_params,
+			ts_params->valid_devs[0],
+			reference,
+			RTE_CRYPTO_AUTH_OP_GENERATE,
+			auth_key);
+	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_generate_GMAC_operation(ts_params,
+			ut_params,
+			reference);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_EQUAL(ut_params->op->status, RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *)
+			+ reference->iv.len;
+
+	digest = plaintext + reference->plaintext.len;
+
+	TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		plaintext,
+		reference->plaintext.data,
+		reference->plaintext.len,
+		"Plaintext data not as expected");
+
+	TEST_HEXDUMP(stdout, "digest:", digest, reference->digest.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		digest,
+		reference->digest.data,
+		reference->digest.len,
+		"Generated auth tag not as expected");
+
+	return 0;
+}
+
+int
+test_authentication_verify_GMAC(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference)
+{
+	int retval;
+
+	uint8_t *plaintext;
+	uint8_t auth_key[reference->auth_key.len + 1];
+
+	/* Create session */
+	retval = create_auth_session(ut_params,
+			ts_params->valid_devs[0],
+			reference,
+			RTE_CRYPTO_AUTH_OP_VERIFY,
+			auth_key);
+	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_GMAC_operation(ts_params,
+			ut_params,
+			reference);
+
+	if (retval < 0)
+		return retval;
+
+	ut_params->op = process_crypto_request(ts_params->valid_devs[0],
+			ut_params->op);
+	TEST_ASSERT_NOT_NULL(ut_params->op, "failed crypto process");
+	TEST_ASSERT_NOT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_AUTH_FAILED,
+			"authentication failed");
+	TEST_ASSERT_EQUAL(ut_params->op->status,
+			RTE_CRYPTO_OP_STATUS_SUCCESS,
+			"crypto op status not success");
+
+	ut_params->obuf = ut_params->op->sym->m_src;
+	TEST_ASSERT_NOT_NULL(ut_params->obuf, "failed to retrieve obuf");
+
+	plaintext = rte_pktmbuf_mtod(ut_params->obuf, uint8_t *)
+			+ reference->iv.len;
+
+	TEST_HEXDUMP(stdout, "plaintext:", plaintext, reference->plaintext.len);
+
+	TEST_ASSERT_BUFFERS_ARE_EQUAL(
+		plaintext,
+		reference->plaintext.data,
+		reference->plaintext.len,
+		"Plaintext data not as expected");
+
+	return 0;
+}
diff --git a/app/test/test_cryptodev_operations.h b/app/test/test_cryptodev_operations.h
new file mode 100644
index 0000000..8db1daf
--- /dev/null
+++ b/app/test/test_cryptodev_operations.h
@@ -0,0 +1,141 @@
+/*
+ *   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_OPERATIONS_H_
+#define TEST_CRYPTODEV_OPERATIONS_H_
+
+struct test_crypto_vector {
+	enum rte_crypto_cipher_algorithm crypto_algo;
+
+	struct {
+		uint8_t data[64];
+		unsigned int len;
+	} cipher_key;
+
+	struct {
+		uint8_t data[64];
+		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[64];
+		unsigned int len;
+	} aad;
+
+	struct {
+		uint8_t data[128];
+		unsigned int len;
+	} digest;
+};
+
+int
+test_authentication(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+int
+test_authentication_verify(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+int
+test_encryption(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+int
+test_decryption(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+int
+test_authenticated_encryption(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+int
+test_authenticated_decryption(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+int
+test_authenticated_encryption_sessionless(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+int
+test_authenticated_decryption_sessionless(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+int
+test_authenticated_encryption_out_of_place(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+int
+test_authenticated_decryption_out_of_place(
+		struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+int
+test_authentication_GMAC(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+int
+test_authentication_verify_GMAC(struct crypto_testsuite_params *ts_params,
+		struct crypto_unittest_params *ut_params,
+		const struct test_crypto_vector *reference);
+
+#endif /* TEST_CRYPTODEV_OPERATIONS_H_ */
diff --git a/app/test/test_cryptodev_perf.c b/app/test/test_cryptodev_perf.c
index 2398d84..8e87ec2 100644
--- a/app/test/test_cryptodev_perf.c
+++ b/app/test/test_cryptodev_perf.c
@@ -46,7 +46,7 @@
 #define PERF_NUM_OPS_INFLIGHT		(128)
 #define DEFAULT_NUM_REQS_TO_SUBMIT	(10000000)
 
-struct crypto_testsuite_params {
+struct crypto_perf_testsuite_params {
 	struct rte_mempool *mbuf_mp;
 	struct rte_mempool *op_mpool;
 
@@ -66,20 +66,20 @@ enum chain_mode {
 
 struct perf_test_params {
 
-	unsigned total_operations;
-	unsigned burst_size;
-	unsigned buf_size;
+	unsigned int total_operations;
+	unsigned int burst_size;
+	unsigned int buf_size;
 
 	enum chain_mode chain;
 
 	enum rte_crypto_cipher_algorithm cipher_algo;
-	unsigned cipher_key_length;
+	unsigned int cipher_key_length;
 	enum rte_crypto_auth_algorithm auth_algo;
 };
 
 #define MAX_NUM_OF_OPS_PER_UT	(128)
 
-struct crypto_unittest_params {
+struct crypto_perf_unittest_params {
 	struct rte_crypto_sym_xform cipher_xform;
 	struct rte_crypto_sym_xform auth_xform;
 
@@ -95,14 +95,29 @@ struct crypto_unittest_params {
 
 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);
+		enum rte_crypto_cipher_algorithm cipher_algo,
+		unsigned int 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);
+
+test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned int 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,
+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 digest_len);
+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 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);
 
 
@@ -205,14 +220,14 @@ setup_test_string(struct rte_mempool *mpool,
 	return m;
 }
 
-static struct crypto_testsuite_params testsuite_params = { NULL };
-static struct crypto_unittest_params unittest_params;
+static struct crypto_perf_testsuite_params testsuite_params = { NULL };
+static struct crypto_perf_unittest_params unittest_params;
 static enum rte_cryptodev_type gbl_cryptodev_perftest_devtype;
 
 static int
 testsuite_setup(void)
 {
-	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_perf_testsuite_params *ts_params = &testsuite_params;
 	struct rte_cryptodev_info info;
 	unsigned i, nb_devs, valid_dev_id = 0;
 	int ret;
@@ -231,7 +246,6 @@ testsuite_setup(void)
 		}
 	}
 
-
 	ts_params->op_mpool = rte_crypto_op_pool_create("CRYPTO_OP_POOL",
 			RTE_CRYPTO_OP_TYPE_SYMMETRIC,
 			NUM_MBUFS, MBUF_CACHE_SIZE,
@@ -273,9 +287,24 @@ testsuite_setup(void)
 		}
 	}
 
+	/* Create 2 LIBCRYPTO devices if required */
+	if (gbl_cryptodev_perftest_devtype == RTE_CRYPTODEV_LIBCRYPTO_PMD) {
+		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));
+			}
+		}
+	}
+
 	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;
 	}
 
@@ -339,7 +368,7 @@ testsuite_setup(void)
 static void
 testsuite_teardown(void)
 {
-	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_perf_testsuite_params *ts_params = &testsuite_params;
 
 	if (ts_params->mbuf_mp != NULL)
 		RTE_LOG(DEBUG, USER1, "CRYPTO_PERF_MBUFPOOL count %u\n",
@@ -352,8 +381,8 @@ testsuite_teardown(void)
 static int
 ut_setup(void)
 {
-	struct crypto_testsuite_params *ts_params = &testsuite_params;
-	struct crypto_unittest_params *ut_params = &unittest_params;
+	struct crypto_perf_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_perf_unittest_params *ut_params = &unittest_params;
 
 	/* Clear unit test parameters before running test */
 	memset(ut_params, 0, sizeof(*ut_params));
@@ -371,8 +400,8 @@ ut_setup(void)
 static void
 ut_teardown(void)
 {
-	struct crypto_testsuite_params *ts_params = &testsuite_params;
-	struct crypto_unittest_params *ut_params = &unittest_params;
+	struct crypto_perf_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_perf_unittest_params *ut_params = &unittest_params;
 	struct rte_cryptodev_stats stats;
 
 	unsigned i;
@@ -1829,8 +1858,8 @@ test_perf_crypto_qp_vary_burst_size(uint16_t dev_num)
 	uint64_t failed_polls, retries, start_cycles, end_cycles, total_cycles = 0;
 	uint32_t burst_sent, burst_received;
 	uint32_t i, burst_size, num_sent, num_received;
-	struct crypto_testsuite_params *ts_params = &testsuite_params;
-	struct crypto_unittest_params *ut_params = &unittest_params;
+	struct crypto_perf_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_perf_unittest_params *ut_params = &unittest_params;
 	struct crypto_data_params *data_params = aes_cbc_hmac_sha256_output;
 
 	if (rte_cryptodev_count() == 0) {
@@ -1991,7 +2020,7 @@ test_perf_snow3G_optimise_cyclecount(struct perf_test_params *pparams)
 	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;
+	struct crypto_perf_testsuite_params *ts_params = &testsuite_params;
 	static struct rte_cryptodev_sym_session *sess;
 
 	if (rte_cryptodev_count() == 0) {
@@ -2149,6 +2178,148 @@ 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_perf_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;
+		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) {
@@ -2164,6 +2335,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_GMAC:
+		return 32;
 	default:
 		return 0;
 	}
@@ -2184,23 +2357,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_GMAC:
+		return DIGEST_BYTE_LENGTH_AES_GMAC;
 	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,
@@ -2220,6 +2405,13 @@ static uint8_t hmac_sha_key[] = {
 		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 };
 
+static uint8_t gmac_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 snow3g_cipher_key[] = {
 		0x2B, 0xD6, 0x45, 0x9F, 0x82, 0xC5, 0xB3, 0x00,
 		0x95, 0x2C, 0x49, 0x10, 0x48, 0x81, 0xFF, 0x48
@@ -2250,7 +2442,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 */
@@ -2328,12 +2520,80 @@ 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:
+		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_GMAC:
+		auth_xform.auth.key.data = gmac_key;
+		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 *
-test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned buf_sz)
+test_perf_create_pktmbuf(struct rte_mempool *mpool, unsigned int buf_sz)
 {
 	struct rte_mbuf *m = rte_pktmbuf_alloc(mpool);
 
@@ -2348,7 +2608,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)
 {
@@ -2362,19 +2622,19 @@ 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;
 
@@ -2415,7 +2675,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
@@ -2441,7 +2733,7 @@ test_perf_aes_sha(uint8_t dev_id, uint16_t queue_id,
 
 	struct rte_mbuf *mbufs[pparams->burst_size * 8];
 
-	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_perf_testsuite_params *ts_params = &testsuite_params;
 
 	static struct rte_cryptodev_sym_session *sess;
 
@@ -2486,7 +2778,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);
@@ -2568,7 +2860,7 @@ test_perf_snow3g(uint8_t dev_id, uint16_t queue_id,
 
 	struct rte_mbuf *mbufs[pparams->burst_size * NUM_MBUF_SETS];
 
-	struct crypto_testsuite_params *ts_params = &testsuite_params;
+	struct crypto_perf_testsuite_params *ts_params = &testsuite_params;
 
 	static struct rte_cryptodev_sym_session *sess;
 
@@ -2697,6 +2989,151 @@ 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_perf_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;
+	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);
@@ -2844,6 +3281,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_CBC,
+			.cipher_key_length = 16,
+			.auth_algo = RTE_CRYPTO_AUTH_AES_GMAC
+		},
+	};
+
+	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_CBC,
+			.cipher_key_length = 16,
+			.auth_algo = RTE_CRYPTO_AUTH_AES_GMAC
+		},
+	};
+
+	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);
@@ -2887,6 +3484,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_mb_cryptodev(void /*argv __rte_unused, int argc __rte_unused*/)
 {
@@ -2919,7 +3529,16 @@ 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_libcrypto_perftest, perftest_libcrypto_cryptodev);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 4/4] examples/l2fwd-crypto: updated example for libcrypto PMD
  2016-08-26  7:21 [PATCH 0/4] New crypto software based device Piotr Azarewicz
                   ` (2 preceding siblings ...)
  2016-08-26  7:21 ` [PATCH 3/4] app/test: added tests for " Piotr Azarewicz
@ 2016-08-26  7:21 ` Piotr Azarewicz
  2016-09-07 18:52 ` [PATCH 0/4] New crypto software based device De Lara Guarch, Pablo
  4 siblings, 0 replies; 10+ messages in thread
From: Piotr Azarewicz @ 2016-08-26  7:21 UTC (permalink / raw)
  To: declan.doherty, dev; +Cc: Marcin Kerlin, Daniel Mrzyglod

From: Marcin Kerlin <marcinx.kerlin@intel.com>

To verify real traffic l2fwd-crypto example can be used with this command:
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.

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

diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index 66397a0..d912c23 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -341,18 +341,27 @@ 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_KASUMI_F9], "KASUMI_F9");
 
+
+
 	for (i = 0; i < RTE_CRYPTO_CIPHER_LIST_END; i++)
 		strcpy(supported_cipher_algo[i], "NOT_SUPPORTED");
 
@@ -362,6 +371,8 @@ fill_supported_algorithm_tables(void)
 	strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_NULL], "NULL");
 	strcpy(supported_cipher_algo[RTE_CRYPTO_CIPHER_SNOW3G_UEA2], "SNOW3G_UEA2");
 	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");
 }
 
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 0/4] New crypto software based device
  2016-08-26  7:21 [PATCH 0/4] New crypto software based device Piotr Azarewicz
                   ` (3 preceding siblings ...)
  2016-08-26  7:21 ` [PATCH 4/4] examples/l2fwd-crypto: updated example " Piotr Azarewicz
@ 2016-09-07 18:52 ` De Lara Guarch, Pablo
  4 siblings, 0 replies; 10+ messages in thread
From: De Lara Guarch, Pablo @ 2016-09-07 18:52 UTC (permalink / raw)
  To: Azarewicz, PiotrX T, Doherty, Declan, dev; +Cc: Kerlin, MarcinX

Hi Piotr,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Piotr Azarewicz
> Sent: Friday, August 26, 2016 12:22 AM
> To: Doherty, Declan; dev@dpdk.org
> Cc: Kerlin, MarcinX
> Subject: [dpdk-dev] [PATCH 0/4] New crypto software based device
> 
> From: Marcin Kerlin <marcinx.kerlin@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
> 
> Slawomir Mrozowicz (2):
>   libcrypto_pmd: initial implementation of SW crypto device
>   lib/cryptodev: added support to libcrypto PMD
> 
> Piotr Azarewicz (1)
>  app/test: added tests for libcrypto PMD
> 
> Daniel Mrzyglod (1)
>  examples/l2fwd-crypto: updated example for libcrypto PMD
> 
>  MAINTAINERS                                        |    4 +
>  app/test/Makefile                                  |    1 +
>  app/test/test_cryptodev.c                          | 1245 +++++++++++++++-
>  app/test/test_cryptodev.h                          |   24 +
>  app/test/test_cryptodev_aes.c                      |   42 +-
>  app/test/test_cryptodev_aes_test_vectors.h         |  887 +++++++++++
>  app/test/test_cryptodev_des_test_vectors.h         |  754 ++++++++++
>  app/test/test_cryptodev_hash_test_vectors.h        |  439 ++++++
>  app/test/test_cryptodev_kasumi_test_vectors.h      |   12 +-
>  app/test/test_cryptodev_operations.c               | 1576
> ++++++++++++++++++++
>  app/test/test_cryptodev_operations.h               |  141 ++
>  app/test/test_cryptodev_perf.c                     |  699 ++++++++-
>  config/common_base                                 |    6 +
>  doc/guides/cryptodevs/index.rst                    |    1 +
>  doc/guides/cryptodevs/libcrypto.rst                |  109 ++
>  drivers/crypto/Makefile                            |    1 +
>  drivers/crypto/libcrypto/Makefile                  |   60 +
>  drivers/crypto/libcrypto/rte_libcrypto_pmd.c       |  936 ++++++++++++
>  drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c   |  638 ++++++++
>  .../crypto/libcrypto/rte_libcrypto_pmd_private.h   |  189 +++
>  .../crypto/libcrypto/rte_pmd_libcrypto_version.map |    3 +
>  examples/l2fwd-crypto/main.c                       |   11 +
>  lib/librte_cryptodev/rte_cryptodev.h               |    3 +
>  mk/rte.app.mk                                      |    3 +-
>  24 files changed, 7688 insertions(+), 96 deletions(-)
>  create mode 100644 app/test/test_cryptodev_aes_test_vectors.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 app/test/test_cryptodev_operations.c
>  create mode 100644 app/test/test_cryptodev_operations.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
> 
> --
> 1.9.1

Could you send a v2 with a release notes update?

Thanks,
Pablo

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device
       [not found]   ` <CAOysbxoNTyTkz2A9oteLj2LfExObqnjSSsQK=s6p0kVuaEcS9g@mail.gmail.com>
@ 2016-09-08 15:50     ` Zbigniew Bodek
  0 siblings, 0 replies; 10+ messages in thread
From: Zbigniew Bodek @ 2016-09-08 15:50 UTC (permalink / raw)
  To: piotrx.t.azarewicz
  Cc: declan.doherty, marcinx.kerlin, slawomirx.mrozowicz,
	michalx.kobylinski, tomaszx.kulasek, danielx.t.mrzyglod, dev

Hello,

I hope this message will get formatted correctly as it is a forwarded
e-mail.
Please see my question in-line.

Kind regards
Zbigniew (zbb)


> From: Marcin Kerlin <marcinx.kerlin@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.
>
> 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
>
> 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.
>
> 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>
> ---
>  MAINTAINERS                                        |   4 +
>  config/common_base                                 |   6 +
>  doc/guides/cryptodevs/index.rst                    |   1 +
>  doc/guides/cryptodevs/libcrypto.rst                | 109 +++
>  drivers/crypto/Makefile                            |   1 +
>  drivers/crypto/libcrypto/Makefile                  |  60 ++
>  drivers/crypto/libcrypto/rte_libcrypto_pmd.c       | 936
> +++++++++++++++++++++
>  drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c   | 638 ++++++++++++++
>  .../crypto/libcrypto/rte_libcrypto_pmd_private.h   | 189 +++++
>  .../crypto/libcrypto/rte_pmd_libcrypto_version.map |   3 +
>  mk/rte.app.mk                                      |   3 +-
>  11 files changed, 1949 insertions(+), 1 deletion(-)
>  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 bc9aa02..9eeb841 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -431,6 +431,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 7830535..42d28dd 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 9616de1..adb6e98c 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..1c3dd07
> --- /dev/null
> +++ b/doc/guides/cryptodevs/libcrypto.rst
> @@ -0,0 +1,109 @@
> +..  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
> +
> +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:
> +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.
> diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
> index dc4ef7f..11b0863 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..cfc5922
> --- /dev/null
> +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd.c
> @@ -0,0 +1,936 @@
> +/*-
> + *   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 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;
> +       sess->cipher.key.data = xform->cipher.key.data;
> +
> +       /* 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:
> +               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;
> +
> +               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(sess->cipher.key.data,
> +                               sess->cipher.key.length,
> sess->cipher.key_ede) != 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;
> +
> +       /* Select auth algo */
> +       switch (xform->auth.algo) {
> +       case RTE_CRYPTO_AUTH_AES_GMAC:
> +               sess->auth.mode = LIBCRYPTO_AUTH_AS_CIPHER;
> +               if (get_cipher_algo(RTE_CRYPTO_CIPHER_AES_GCM,
> xform->auth.key.length,
> +                               &sess->auth.cipher.evp_algo) != 0)
> +                       return -EINVAL;
> +               sess->auth.cipher.key.data = xform->auth.key.data;
> +               sess->auth.cipher.key.length = xform->auth.key.length;
> +               sess->auth.cipher.ctx = EVP_CIPHER_CTX_new();
> +               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:
> +               sess->auth.mode = LIBCRYPTO_AUTH_NULL;
> +               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;
> +       }
> +
> +       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_MD_CTX_destroy(sess->auth.hmac.ctx);
> +               break;
> +       case LIBCRYPTO_AUTH_AS_CIPHER:
> +               EVP_CIPHER_CTX_free(sess->auth.cipher.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 (!unlikely(op->sym->session == NULL ||
> +                               op->sym->session->dev_type !=
> +                               RTE_CRYPTODEV_LIBCRYPTO_PMD))
>

[ZBB] What is the intention behind such construct? Wouldn't be more clear
and reasonable in terms of __builtin_expect() to use:

               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 gmac algorithm */
> +static int
> +process_libcrypto_auth_gmac(uint8_t *src, uint8_t *dst,
> +               uint8_t *iv, uint8_t *key, int srclen, int ivlen,
> +               EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
> +{
> +       int unused;
> +
> +       if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0)
> +               goto process_auth_gmac_err;
> +
> +       if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL)
> <= 0)
> +               goto process_auth_gmac_err;
> +
> +       if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0)
> +               goto process_auth_gmac_err;
> +
> +       if (EVP_EncryptUpdate(ctx, NULL, &unused, src, srclen) <= 0)
> +               goto process_auth_gmac_err;
> +
> +       if (EVP_EncryptFinal_ex(ctx, NULL, &unused) <= 0)
> +               goto process_auth_gmac_err;
> +
> +       if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, dst) <= 0)
> +               goto process_auth_gmac_err;
> +
> +       return 0;
> +
> +process_auth_gmac_err:
> +       LIBCRYPTO_LOG_ERR("Process libcrypto auth gmac failed");
> +       return -EINVAL;
> +}
> +
> +/** 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 cipher operation */
> +static int
> +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_ede, srclen,
> sess->cipher.ctx);
> +
> +       if (status == 0)
> +               op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
> +       else
> +               op->status = RTE_CRYPTO_OP_STATUS_ERROR;
> +
> +       return status;
> +}
> +
> +/** Process auth operation */
> +static int
> +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, *iv;
> +       int srclen, ivlen, status = -1;
> +
> +       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_GENERATE) {
> +               dst = rte_pktmbuf_mtod_offset(mbuf_dst, uint8_t *,
> +                               op->sym->auth.data.offset +
> +                               op->sym->auth.data.length);
> +       } else {
> +               dst = (uint8_t *)rte_pktmbuf_append(mbuf_src,
> +                               op->sym->auth.digest.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;
> +       case LIBCRYPTO_AUTH_AS_CIPHER:
> +               iv = op->sym->cipher.iv.data;
> +               ivlen = op->sym->cipher.iv.length;
> +
> +               status = process_libcrypto_auth_gmac(src, dst,
> +                               iv, sess->auth.cipher.key.data, srclen,
> ivlen,
> +                               sess->auth.cipher.ctx,
> sess->auth.cipher.evp_algo);
> +               break;
> +       default:
> +               break;
> +       }
> +
> +       if (status == 0) {
> +               op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
> +
> +               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;
> +                               status = -EINVAL;
> +                       }
> +               }
> +       } else
> +               op->status = RTE_CRYPTO_OP_STATUS_ERROR;
> +
> +       return status;
> +}
> +
> +/** 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 status;
> +
> +       msrc = op->sym->m_src;
> +       mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
> +
> +       switch (sess->chain_order) {
> +       case LIBCRYPTO_CHAIN_ONLY_CIPHER:
> +               status = process_libcrypto_cipher_op(op, sess, msrc,
> mdst);
> +               break;
> +       case LIBCRYPTO_CHAIN_ONLY_AUTH:
> +               status = process_libcrypto_auth_op(op, sess, msrc, mdst);
> +               break;
> +       case LIBCRYPTO_CHAIN_CIPHER_AUTH:
> +               status = process_libcrypto_cipher_op(op, sess, msrc,
> mdst);
> +               if (status == 0)
> +                       status = process_libcrypto_auth_op(op, sess,
> mdst, mdst);
> +               break;
> +       case LIBCRYPTO_CHAIN_AUTH_CIPHER:
> +               status = process_libcrypto_auth_op(op, sess, msrc, mdst);
> +               if (status == 0)
> +                       status = process_libcrypto_cipher_op(op, sess,
> msrc, mdst);
> +               break;
> +       default:
> +               status = -1;
> +               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 (status != 0)
> +               return -1;
> +
> +       return rte_ring_enqueue(qp->processed_ops, (void *)op);
> +}
> +
> +/*
> + *-----------------------------------------------------------
> -------------------
> + * 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..68c49c9
> --- /dev/null
> +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_ops.c
> @@ -0,0 +1,638 @@
> +/*-
> + *   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 = 20,
> +                                       .max = 20,
> +                                       .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
> +                               }
> +                       }, }
> +               }, }
> +       },
> +       {       /* 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_mb_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..b40a2d2
> --- /dev/null
> +++ b/drivers/crypto/libcrypto/rte_libcrypto_pmd_private.h
> @@ -0,0 +1,189 @@
> +/*-
> + *   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_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,
> +       LIBCRYPTO_AUTH_AS_CIPHER,
> +       LIBCRYPTO_AUTH_NULL
> +};
> +
> +/** 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;
> +                       /**< pointer to 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 */
> +
> +               uint8_t key_ede[24];
> +               /**< key data storage to be used in ede process */
> +       } cipher;
> +
> +       /** Authentication Parameters */
> +       struct {
> +               enum rte_crypto_auth_operation operation;
> +               /**< auth operation generate or verify */
> +               enum libcrypto_auth_mode mode;
> +               /**< auth operation mode */
> +
> +               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;
> +
> +                       struct {
> +                               struct {
> +                                       uint8_t *data;
> +                                       /**< pointer to 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;
> +               };
> +       } 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..58c4dea
> --- /dev/null
> +++ b/drivers/crypto/libcrypto/rte_pmd_libcrypto_version.map
> @@ -0,0 +1,3 @@
> +DPDK_16.11 {
> +       local: *;
> +};
> \ No newline at end of file
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index 1a0095b..67c0aa9 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -135,7 +135,8 @@ _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_NULL_CRYPTO) += -lrte_pmd_null_crypto
> +_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
> --
> 1.9.1
>
>
>
> --
> Andriy Berestovskyy
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device
  2016-08-26  7:21 ` [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device Piotr Azarewicz
       [not found]   ` <CAOysbxoNTyTkz2A9oteLj2LfExObqnjSSsQK=s6p0kVuaEcS9g@mail.gmail.com>
@ 2016-09-12 11:16   ` Akhil Goyal
  2016-09-14  8:48     ` Jastrzebski, MichalX K
  1 sibling, 1 reply; 10+ messages in thread
From: Akhil Goyal @ 2016-09-12 11:16 UTC (permalink / raw)
  To: Piotr Azarewicz, declan.doherty, dev
  Cc: Marcin Kerlin, Slawomir Mrozowicz, Michal Kobylinski,
	Tomasz Kulasek, Daniel Mrzyglod

On 8/26/2016 12:51 PM, Piotr Azarewicz wrote:

> +/** 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 (!unlikely(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;
[Akhil] this EVP_EncryptInit_ex() can be done for each session instead 
of each packet. This will improve the performance. Also if there is some 
change in the parameters later then it can be called again here with the 
updated parameters only.
Same comment is for all cases (hmac, auth, etc)
> +
> +	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 gmac algorithm */
> +static int
> +process_libcrypto_auth_gmac(uint8_t *src, uint8_t *dst,
> +		uint8_t *iv, uint8_t *key, int srclen, int ivlen,
> +		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
> +{
> +	int unused;
> +
> +	if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0)
> +		goto process_auth_gmac_err;
> +
> +	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL) <= 0)
> +		goto process_auth_gmac_err;
> +
> +	if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0)
> +		goto process_auth_gmac_err;
> +
> +	if (EVP_EncryptUpdate(ctx, NULL, &unused, src, srclen) <= 0)
> +		goto process_auth_gmac_err;
> +
> +	if (EVP_EncryptFinal_ex(ctx, NULL, &unused) <= 0)
> +		goto process_auth_gmac_err;
> +
> +	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, dst) <= 0)
> +		goto process_auth_gmac_err;
> +
> +	return 0;
> +
> +process_auth_gmac_err:
> +	LIBCRYPTO_LOG_ERR("Process libcrypto auth gmac failed");
> +	return -EINVAL;
> +}
> +
> +/** 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;
> +}
> +
> +/*----------------------------------------------------------------------------*/
> +

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device
  2016-09-12 11:16   ` Akhil Goyal
@ 2016-09-14  8:48     ` Jastrzebski, MichalX K
  2016-10-11  9:50       ` Mrozowicz, SlawomirX
  0 siblings, 1 reply; 10+ messages in thread
From: Jastrzebski, MichalX K @ 2016-09-14  8:48 UTC (permalink / raw)
  To: Akhil Goyal, Azarewicz, PiotrX T, Doherty, Declan, dev
  Cc: Kerlin, MarcinX, Mrozowicz, SlawomirX, Kobylinski, MichalX,
	Kulasek, TomaszX, Mrzyglod, DanielX T

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Akhil Goyal
> Sent: Monday, September 12, 2016 1:17 PM
> To: Azarewicz, PiotrX T <piotrx.t.azarewicz@intel.com>; Doherty, Declan
> <declan.doherty@intel.com>; dev@dpdk.org
> Cc: Kerlin, MarcinX <marcinx.kerlin@intel.com>; Mrozowicz, SlawomirX
> <slawomirx.mrozowicz@intel.com>; Kobylinski, MichalX
> <michalx.kobylinski@intel.com>; Kulasek, TomaszX
> <tomaszx.kulasek@intel.com>; Mrzyglod, DanielX T
> <danielx.t.mrzyglod@intel.com>
> Subject: Re: [dpdk-dev] [PATCH 1/4] libcrypto_pmd: initial implementation
> of SW crypto device
> 
> On 8/26/2016 12:51 PM, Piotr Azarewicz wrote:
> 
> > +/** 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 (!unlikely(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;
> [Akhil] this EVP_EncryptInit_ex() can be done for each session instead
> of each packet. This will improve the performance. Also if there is some
> change in the parameters later then it can be called again here with the
> updated parameters only.
> Same comment is for all cases (hmac, auth, etc)

Hi Akhil,
Thank You for this comment. We will check if this is possible.

Michal

> > +
> > +	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 gmac algorithm */
> > +static int
> > +process_libcrypto_auth_gmac(uint8_t *src, uint8_t *dst,
> > +		uint8_t *iv, uint8_t *key, int srclen, int ivlen,
> > +		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo)
> > +{
> > +	int unused;
> > +
> > +	if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0)
> > +		goto process_auth_gmac_err;
> > +
> > +	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen,
> NULL) <= 0)
> > +		goto process_auth_gmac_err;
> > +
> > +	if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0)
> > +		goto process_auth_gmac_err;
> > +
> > +	if (EVP_EncryptUpdate(ctx, NULL, &unused, src, srclen) <= 0)
> > +		goto process_auth_gmac_err;
> > +
> > +	if (EVP_EncryptFinal_ex(ctx, NULL, &unused) <= 0)
> > +		goto process_auth_gmac_err;
> > +
> > +	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, dst) <=
> 0)
> > +		goto process_auth_gmac_err;
> > +
> > +	return 0;
> > +
> > +process_auth_gmac_err:
> > +	LIBCRYPTO_LOG_ERR("Process libcrypto auth gmac failed");
> > +	return -EINVAL;
> > +}
> > +
> > +/** 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;
> > +}
> > +
> > +/*----------------------------------------------------------------------------*/
> > +
> 
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device
  2016-09-14  8:48     ` Jastrzebski, MichalX K
@ 2016-10-11  9:50       ` Mrozowicz, SlawomirX
  0 siblings, 0 replies; 10+ messages in thread
From: Mrozowicz, SlawomirX @ 2016-10-11  9:50 UTC (permalink / raw)
  To: Jastrzebski, MichalX K, Akhil Goyal, Azarewicz, PiotrX T,
	Doherty, Declan, dev
  Cc: Kerlin, MarcinX, Kobylinski, MichalX, Kulasek, TomaszX, Mrzyglod,
	DanielX T



>-----Original Message-----
>From: Jastrzebski, MichalX K
>Sent: Wednesday, September 14, 2016 10:48 AM
>To: Akhil Goyal <akhil.goyal@nxp.com>; Azarewicz, PiotrX T
><piotrx.t.azarewicz@intel.com>; Doherty, Declan
><declan.doherty@intel.com>; dev@dpdk.org
>Cc: Kerlin, MarcinX <marcinx.kerlin@intel.com>; Mrozowicz, SlawomirX
><slawomirx.mrozowicz@intel.com>; Kobylinski, MichalX
><michalx.kobylinski@intel.com>; Kulasek, TomaszX
><tomaszx.kulasek@intel.com>; Mrzyglod, DanielX T
><danielx.t.mrzyglod@intel.com>
>Subject: RE: [dpdk-dev] [PATCH 1/4] libcrypto_pmd: initial implementation of
>SW crypto device
>
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Akhil Goyal
>> Sent: Monday, September 12, 2016 1:17 PM
>> To: Azarewicz, PiotrX T <piotrx.t.azarewicz@intel.com>; Doherty,
>> Declan <declan.doherty@intel.com>; dev@dpdk.org
>> Cc: Kerlin, MarcinX <marcinx.kerlin@intel.com>; Mrozowicz, SlawomirX
>> <slawomirx.mrozowicz@intel.com>; Kobylinski, MichalX
>> <michalx.kobylinski@intel.com>; Kulasek, TomaszX
>> <tomaszx.kulasek@intel.com>; Mrzyglod, DanielX T
>> <danielx.t.mrzyglod@intel.com>
>> Subject: Re: [dpdk-dev] [PATCH 1/4] libcrypto_pmd: initial
>> implementation of SW crypto device
>>
>> On 8/26/2016 12:51 PM, Piotr Azarewicz wrote:
>>
>> > +/** 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 (!unlikely(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;
>> [Akhil] this EVP_EncryptInit_ex() can be done for each session instead
>> of each packet. This will improve the performance. Also if there is
>> some change in the parameters later then it can be called again here
>> with the updated parameters only.
>> Same comment is for all cases (hmac, auth, etc)
>
>Hi Akhil,
>Thank You for this comment. We will check if this is possible.
>
>Michal
>

[Sławomir]
We have done some investigation:
- At first glance it is valuable to call this kind of function
only once per session.
- We done test: just remove the functions like EVP_XXXInitXXX
and we reduce packet processing time between 1% to 10%
depending of processed algorithm.
- We analyzed calling only once per session also functions 
like EVP_XXXFinalXXX but it is not possible because 
this kind of functions finalize cipher or authenticate process 
and return result.
- The functions like EVP_XXXFinalXXX change context and
It is not possible to proper continue processing without
reinitialize the context. So after call functions EVP_XXXFinalXXX
we need to call EVP_XXXInitXXX for next operation.
In sum we can't do the proposed performance improvement.

>> > +
>> > +	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 gmac algorithm */
>> > +static int
>> > +process_libcrypto_auth_gmac(uint8_t *src, uint8_t *dst,
>> > +		uint8_t *iv, uint8_t *key, int srclen, int ivlen,
>> > +		EVP_CIPHER_CTX *ctx, const EVP_CIPHER *algo) {
>> > +	int unused;
>> > +
>> > +	if (EVP_EncryptInit_ex(ctx, algo, NULL, NULL, NULL) <= 0)
>> > +		goto process_auth_gmac_err;
>> > +
>> > +	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, ivlen,
>> NULL) <= 0)
>> > +		goto process_auth_gmac_err;
>> > +
>> > +	if (EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv) <= 0)
>> > +		goto process_auth_gmac_err;
>> > +
>> > +	if (EVP_EncryptUpdate(ctx, NULL, &unused, src, srclen) <= 0)
>> > +		goto process_auth_gmac_err;
>> > +
>> > +	if (EVP_EncryptFinal_ex(ctx, NULL, &unused) <= 0)
>> > +		goto process_auth_gmac_err;
>> > +
>> > +	if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, dst) <=
>> 0)
>> > +		goto process_auth_gmac_err;
>> > +
>> > +	return 0;
>> > +
>> > +process_auth_gmac_err:
>> > +	LIBCRYPTO_LOG_ERR("Process libcrypto auth gmac failed");
>> > +	return -EINVAL;
>> > +}
>> > +
>> > +/** 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;
>> > +}
>> > +
>> > +/*-----------------------------------------------------------------
>> > +-----------*/
>> > +
>>
>>

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-10-11  9:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-26  7:21 [PATCH 0/4] New crypto software based device Piotr Azarewicz
2016-08-26  7:21 ` [PATCH 1/4] libcrypto_pmd: initial implementation of SW crypto device Piotr Azarewicz
     [not found]   ` <CAOysbxoNTyTkz2A9oteLj2LfExObqnjSSsQK=s6p0kVuaEcS9g@mail.gmail.com>
2016-09-08 15:50     ` Zbigniew Bodek
2016-09-12 11:16   ` Akhil Goyal
2016-09-14  8:48     ` Jastrzebski, MichalX K
2016-10-11  9:50       ` Mrozowicz, SlawomirX
2016-08-26  7:21 ` [PATCH 2/4] lib/cryptodev: added support to libcrypto PMD Piotr Azarewicz
2016-08-26  7:21 ` [PATCH 3/4] app/test: added tests for " Piotr Azarewicz
2016-08-26  7:21 ` [PATCH 4/4] examples/l2fwd-crypto: updated example " Piotr Azarewicz
2016-09-07 18:52 ` [PATCH 0/4] New crypto software based device De Lara Guarch, Pablo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.