[v2,2/2] examples/crypto: crypto test application
diff mbox series

Message ID 20200122105222.3758-2-ssardar@amd.com
State Rejected
Delegated to: akhil goyal
Headers show
Series
  • [v2,1/2] crypto/ccp: sha3 support enabling in ccp
Related show

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/travis-robot success Travis build: passed
ci/checkpatch success coding style OK

Commit Message

ssardar@amd.com Jan. 22, 2020, 10:52 a.m. UTC
From: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>

test application to test Cipher/Authentication/AEAD in AMD CCP
a crypto controller. This test application can be used as
reference to develop/test crypto algo.

Signed-off-by: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>
---
 doc/guides/sample_app_ug/ccp_crypto.rst | 114 +++
 examples/crypto/Makefile                |  63 ++
 examples/crypto/main.c                  | 899 ++++++++++++++++++++++++
 3 files changed, 1076 insertions(+)
 create mode 100644 doc/guides/sample_app_ug/ccp_crypto.rst
 create mode 100644 examples/crypto/Makefile
 create mode 100644 examples/crypto/main.c

Comments

Akhil Goyal Jan. 28, 2020, 6:35 a.m. UTC | #1
Hi,
> 
> From: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>
> 
> test application to test Cipher/Authentication/AEAD in AMD CCP
> a crypto controller. This test application can be used as
> reference to develop/test crypto algo.
> 
> Signed-off-by: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>
> ---
Why do you need a separate example application to test an algo. 
Is it not possible to test it with app/test/test_cryptodev.c and 
Examples/l2fwd-crypto?

-Akhil
Sardar, Shamsher singh Jan. 30, 2020, 8:45 a.m. UTC | #2
Hi Akhil,
Our app has been developed to do standalone test.
The L2fwd test need the network ports.
Therefore, this test app has been developed for quick development in standalone mode.
Is there anyway to do standalone test?

Thanks & regards
S. Shamsher Singh

-----Original Message-----
From: Akhil Goyal <akhil.goyal@nxp.com> 
Sent: Tuesday, January 28, 2020 12:05 PM
To: Sardar, Shamsher singh <Shamshersingh.Sardar@amd.com>; dev@dpdk.org
Cc: Kumar, Ravi1 <Ravi1.Kumar@amd.com>
Subject: RE: [dpdk-dev] [PATCH v2 2/2] examples/crypto: crypto test application

[CAUTION: External Email]

Hi,
>
> From: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>
>
> test application to test Cipher/Authentication/AEAD in AMD CCP a 
> crypto controller. This test application can be used as reference to 
> develop/test crypto algo.
>
> Signed-off-by: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>
> ---
Why do you need a separate example application to test an algo.
Is it not possible to test it with app/test/test_cryptodev.c and Examples/l2fwd-crypto?

-Akhil
Akhil Goyal Jan. 30, 2020, 8:52 a.m. UTC | #3
Hi Shamsher,
> 
> Hi Akhil,
> Our app has been developed to do standalone test.
> The L2fwd test need the network ports.
> Therefore, this test app has been developed for quick development in
> standalone mode.
> Is there anyway to do standalone test?
> 
As I mentioned below, you can use app/test/test_cryptodev.c to add your
PMD in the unit test framework of DPDK and it is without network interface.
This test app is for functional testing for all the supported algos.
If you need to get performance data, you can add in app/test-crypto-perf

Both these are standalone applications without ethernet.

Regards,
Akhil


> Hi,
> >
> > From: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>
> >
> > test application to test Cipher/Authentication/AEAD in AMD CCP a
> > crypto controller. This test application can be used as reference to
> > develop/test crypto algo.
> >
> > Signed-off-by: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>
> > ---
> Why do you need a separate example application to test an algo.
> Is it not possible to test it with app/test/test_cryptodev.c and Examples/l2fwd-
> crypto?
> 
> -Akhil
Sardar, Shamsher singh Jan. 30, 2020, 9:08 a.m. UTC | #4
Hi Akhil,
Thanks. I was not aware of this app so developed new one.
Will explore more on this.

Thanks & regards
S Shamsher Singh

-----Original Message-----
From: Akhil Goyal <akhil.goyal@nxp.com> 
Sent: Thursday, January 30, 2020 2:22 PM
To: Sardar, Shamsher singh <Shamshersingh.Sardar@amd.com>; dev@dpdk.org
Cc: Kumar, Ravi1 <Ravi1.Kumar@amd.com>
Subject: RE: [dpdk-dev] [PATCH v2 2/2] examples/crypto: crypto test application

[CAUTION: External Email]

Hi Shamsher,
>
> Hi Akhil,
> Our app has been developed to do standalone test.
> The L2fwd test need the network ports.
> Therefore, this test app has been developed for quick development in 
> standalone mode.
> Is there anyway to do standalone test?
>
As I mentioned below, you can use app/test/test_cryptodev.c to add your PMD in the unit test framework of DPDK and it is without network interface.
This test app is for functional testing for all the supported algos.
If you need to get performance data, you can add in app/test-crypto-perf

Both these are standalone applications without ethernet.

Regards,
Akhil


> Hi,
> >
> > From: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>
> >
> > test application to test Cipher/Authentication/AEAD in AMD CCP a 
> > crypto controller. This test application can be used as reference to 
> > develop/test crypto algo.
> >
> > Signed-off-by: Sardar Shamsher Singh <Shamshersingh.Sardar@amd.com>
> > ---
> Why do you need a separate example application to test an algo.
> Is it not possible to test it with app/test/test_cryptodev.c and 
> Examples/l2fwd- crypto?
>
> -Akhil

Patch
diff mbox series

diff --git a/doc/guides/sample_app_ug/ccp_crypto.rst b/doc/guides/sample_app_ug/ccp_crypto.rst
new file mode 100644
index 000000000..0f56b444b
--- /dev/null
+++ b/doc/guides/sample_app_ug/ccp_crypto.rst
@@ -0,0 +1,114 @@ 
+.. SPDX-License-Identifier: BSD-3-Clause
+   Copyright(c) 2018 Advanced Micro Devices, Inc. All rights reserved.
+
+
+.. _crypto_app:
+
+Crypto Sample Application
+============================================
+
+The Crypto sample application is a simple example to test Crypto algorithm using
+CCP, the Data Plane Development Kit (DPDK), in conjunction with the Cryptodev library.
+
+Overview
+--------
+
+The Crypto sample application performs a Crypto operation (Cipher/Auth) specified by the user
+from command line, with a Crypto device (like CCP) capable of doing that operation.
+
+Compiling the Application
+-------------------------
+
+To compile the sample application see :doc:`compiling`.
+
+The application is located in the `examples/crypto` sub-directory.
+
+Running the Application
+-----------------------
+
+The application requires a number of command line options:
+
+.. code-block:: console
+
+	./build/crypto [EAL options] -- [-l core list] [-n number of channels] /
+	[--vdev "crypto_ccp"] [--cdev_type HW/SW/ANY] [--cipher_op ENCRYPT / DECRYPT] /
+	[--cipher_algo ALGO] [--plain_text ] [--cipher_key KEY] [--cipher_iv IV] /
+	[--auth_op GENERATE / VERIFY] [ --auth_algo ALGO] [--auth_key KEY] /
+	[--aead_algo ALGO] [--aead_op ENCRYPT / DECRYPT] [--aead_key KEY] [--aead_iv IV] /
+	[--aad AAD] [ --digest]
+
+
+where,
+
+* l <core list>  	: List of cores to run on
+
+* n NUM      		: Number of memory channels
+
+* vdev             : Add a virtual device
+
+* cdev_type: select preferred crypto device type: HW, SW or anything (ANY)
+
+* cipher_op: select the ciphering operation to perform: ENCRYPT or DECRYPT
+
+* cipher_algo: select the ciphering algorithm (EX: aes-cbc/aes-ecb/aes-ctr/)
+
+* cipher_key: set the ciphering key to be used. Bytes has to be separated with ":"
+
+* cipher_iv: set the cipher IV to be used. Bytes has to be separated with ":"
+
+* plain_text: set the plain text to be operated. Bytes has to be separated with ":"
+
+* auth_op: select the authentication operation to perform: GENERATE or VERIFY
+
+* auth_algo: select the authentication algorithm
+
+* auth_key: set the authentication key to be used. Bytes has to be separated with ":"
+
+* aead_algo: select the AEAD algorithm
+
+* aead_op: select the AEAD operation to perform: ENCRYPT or DECRYPT
+
+* aead_key: set the AEAD key to be used. Bytes has to be separated with ":"
+
+* aead_iv: set the AEAD IV to be used. Bytes has to be separated with ":"
+
+* aad: set the AAD to be used. Bytes has to be separated with ":"
+
+* digest : set the DIGEST values to be used. Bytes has to be separated with ":"
+
+
+The application requires that crypto devices capable of performing
+the specified crypto operation are available on application initialization.
+This means that HW crypto device/s must be bound to a DPDK driver or
+a SW crypto device/s (virtual crypto PMD) must be created (using --vdev).
+
+Below are few example to run the application in linux environment with 2 lcores,
+	4 Memory channel and 1 crypto device, issue the command:
+
+.. code-block:: console
+
+    Example 1:
+	$sudo ./build/crypto -l1,2 -n 4 --vdev "crypto_ccp" -- --cipher_op ENCRYPT \
+	--cipher_algo aes-cbc --plain_text f3:44:81:ec:3c:c6:27:ba:cd:5d:c3:fb:08:f2:73:e6 \
+	--cipher_key 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 \
+	--cipher_iv 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
+
+    Example 2:
+	$sudo ./build/crypto -l1,2 -n 4 --vdev "crypto_ccp" -- --auth_op GENERATE \
+	--auth_algo sha3-224 --plain_text 01
+
+    Example 3:
+	$sudo ./build/crypto -l1,2 -n 4 --vdev "crypto_ccp" \
+	-- --aead_op ENCRYPT --aead_algo aes-gcm \
+	--plain_text c3:b3:c4:1f:11:3a:31:b7:3d:9a:5c:d4:32:10:30:69 \
+	--aead_key c9:39:cc:13:39:7c:1d:37:de:6a:e0:e1:cb:7c:42:3c \
+	--aead_iv 01:00:00:00:e2:67:0f:9e:b3:89:bb:7c:01:cc:d8:b3 \
+	--aad 24:82:56:02:bd:12:a9:84:e0:09:2d:3e:44:8e:da:5f \
+	--digest 00:00:00:00:00:00:00:80:00:00:00:00:00:00:00:80
+
+Refer to the *DPDK Getting Started Guide* for general information on running applications
+and the Environment Abstraction Layer (EAL) options.
+
+.. Note::
+
+    * All crypto devices shall use the same session.
diff --git a/examples/crypto/Makefile b/examples/crypto/Makefile
new file mode 100644
index 000000000..9b1be69ef
--- /dev/null
+++ b/examples/crypto/Makefile
@@ -0,0 +1,63 @@ 
+#SPDX-License-Identifier: BSD-3-Clause
+#Copyright(c) 2019 Advanced Micro Devices, Inc. All rights reserved.
+
+# binary name
+APP = crypto
+
+SRCS-y := main.c
+
+# Build using pkg-config variables if possible
+$(shell pkg-config --exists libdpdk)
+ifeq ($(shell pkg-config --exists libdpdk && echo 0),0)
+
+#ifeq ($(.SHELLSTATUS),0)
+
+all: shared
+.PHONY: shared static
+shared: build/$(APP)-shared
+	ln -sf $(APP)-shared build/$(APP)
+static: build/$(APP)-static
+	ln -sf $(APP)-static build/$(APP)
+
+PC_FILE := $(shell pkg-config --path libdpdk)
+CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
+LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
+LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
+
+build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
+	$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
+
+build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
+	$(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
+
+build:
+	@mkdir -p $@
+
+.PHONY: clean
+clean:
+	rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
+	rmdir --ignore-fail-on-non-empty build
+
+else # Build using legacy build system
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overridden by command line or environment
+RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config)))))
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
+ifeq ($(CONFIG_RTE_LIBRTE_PMD_CRYPTO_SCHEDULER),y)
+LDLIBS += -lrte_pmd_crypto_scheduler
+endif
+endif
+
+include $(RTE_SDK)/mk/rte.extapp.mk
+endif
diff --git a/examples/crypto/main.c b/examples/crypto/main.c
new file mode 100644
index 000000000..47a53fbac
--- /dev/null
+++ b/examples/crypto/main.c
@@ -0,0 +1,899 @@ 
+/*   SPDX-License-Identifier: BSD-3-Clause
+ *   Copyright(c) 2019 Advanced Micro Devices, Inc. All rights reserved.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <time.h>
+#include <inttypes.h>
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <netinet/in.h>
+#include <setjmp.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <errno.h>
+#include <getopt.h>
+#include <fcntl.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_common.h>
+#include <rte_cryptodev.h>
+#include <rte_cycles.h>
+#include <rte_debug.h>
+#include <rte_eal.h>
+#include <rte_interrupts.h>
+#include <rte_launch.h>
+#include <rte_lcore.h>
+#include <rte_log.h>
+#include <rte_malloc.h>
+#include <rte_mbuf.h>
+#include <rte_memcpy.h>
+#include <rte_memory.h>
+#include <rte_mempool.h>
+#include <rte_per_lcore.h>
+#include <rte_prefetch.h>
+#ifdef RTE_LIBRTE_PMD_CRYPTO_SCHEDULER
+#include <rte_cryptodev_scheduler.h>
+#endif
+
+#define MAX_STR_LEN 32
+#define MAX_KEY_SIZE 512
+#define MAX_PT_SIZE 65535
+#define MAX_IV_SIZE 256
+#define MAX_AAD_SIZE 65535
+#define MAX_DIGEST_SIZE 16
+#define SESSION_POOL_CACHE_SIZE 0
+#define IV_OFFSET		(sizeof(struct rte_crypto_op) + \
+				sizeof(struct rte_crypto_sym_op))
+#define BURST_SIZE           1
+#define BUFFER_SIZE          64
+#define NUM_MBUFS            1024
+#define POOL_CACHE_SIZE      128
+
+#define AES_CBC_IV_LENGTH    16
+#define AES_CBC_KEY_LENGTH   16
+
+#define SHA_DIGEST_LENGTH 20
+#define SHA224_DIGEST_LENGTH    28
+#define SHA256_DIGEST_LENGTH    32
+#define SHA384_DIGEST_LENGTH    48
+#define SHA512_DIGEST_LENGTH    64
+
+
+enum cdev_type {
+	CDEV_TYPE_ANY,
+	CDEV_TYPE_HW,
+	CDEV_TYPE_SW
+};
+
+struct cdev_iv {
+	uint8_t *data;
+	uint16_t length;
+};
+struct cdev_aad_key {
+	uint8_t *data;
+	uint16_t length;
+};
+struct cdev_aad_digest {
+	uint8_t *data;
+	uint16_t length;
+};
+
+/** crypto application command line options */
+struct ccp_crypto_options {
+	enum cdev_type type;
+	unsigned int crypto_op_private_data;
+
+	struct rte_crypto_sym_xform cipher_xform;
+	struct cdev_iv cipher_iv;
+	uint8_t cipher_key[MAX_KEY_SIZE];
+
+	struct rte_crypto_sym_xform auth_xform;
+	uint8_t auth_key[MAX_KEY_SIZE];
+
+	struct rte_crypto_sym_xform aead_xform;
+	struct cdev_iv aead_iv;
+	struct cdev_aad_key aad;
+	uint8_t aead_key[MAX_KEY_SIZE];
+	struct cdev_aad_digest aad_digest;
+	int digest_size;
+
+	char string_type[MAX_STR_LEN];
+};
+uint8_t *pt;
+int pt_length;
+struct rte_mempool *session_pool_socket[RTE_MAX_NUMA_NODES] = { 0 };
+int buffer_size = BUFFER_SIZE;
+
+/* Display command line arguments usage */
+static void
+ccp_crypto_usage(const char *prgname)
+{
+	printf("%s [EAL options] --\n"
+	"  --cdev_type HW / SW / ANY\n"
+	"  --cipher_op ENCRYPT / DECRYPT\n"
+	"  --cipher_algo ALGO\n"
+	"  --plain_text  (bytes separated with \":\")\n"
+	"  --cipher_key KEY (bytes separated with \":\")\n"
+	"  --cipher_iv  (bytes separated with \":\")\n"
+	"  --auth_op GENERATE / VERIFY\n"
+	"  --auth_algo ALGO\n"
+	"  --auth_key KEY (bytes separated with \":\")\n"
+	"  --aead_algo ALGO\n"
+	"  --aead_op ENCRYPT / DECRYPT\n"
+	"  --aead_key KEY (bytes separated with \":\")\n"
+	"  --aead_iv IV (bytes separated with \":\")\n"
+	"  --aad AAD (bytes separated with \":\")\n"
+	"  --digest (16-bytes separated with \":\")\n",
+	prgname);
+}
+
+/** Parse crypto device type command line argument */
+static int
+parse_cryptodev_type(enum cdev_type *type, char *optarg)
+{
+	if (strcmp("HW", optarg) == 0) {
+		*type = CDEV_TYPE_HW;
+		return 0;
+	} else if (strcmp("SW", optarg) == 0) {
+		*type = CDEV_TYPE_SW;
+		return 0;
+	} else if (strcmp("ANY", optarg) == 0) {
+		*type = CDEV_TYPE_ANY;
+		return 0;
+	}
+	return -1;
+}
+
+/** Parse crypto cipher operation command line argument */
+static int
+parse_cipher_op(enum rte_crypto_cipher_operation *op, char *optarg)
+{
+	if (strcmp("ENCRYPT", optarg) == 0) {
+		*op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
+		return 0;
+	} else if (strcmp("DECRYPT", optarg) == 0) {
+		*op = RTE_CRYPTO_CIPHER_OP_DECRYPT;
+		return 0;
+	}
+	printf("Cipher operation not supported!\n");
+	return -1;
+}
+
+/** Parse crypto cipher algo option command line argument */
+static int
+parse_cipher_algo(enum rte_crypto_cipher_algorithm *algo, char *optarg)
+{
+	if (rte_cryptodev_get_cipher_algo_enum(algo, optarg) < 0) {
+		printf("Cipher algorithm specified not supported!\n");
+	return -1;
+	}
+	return 0;
+}
+/** Parse bytes from command line argument */
+static int
+parse_bytes(uint8_t *data, char *input_arg, uint16_t max_size)
+{
+	int byte_count;
+	char *token;
+
+	errno = 0;
+	for (byte_count = 0, token = strtok(input_arg, ":");
+		(byte_count < max_size) && (token != NULL);
+		token = strtok(NULL, ":")) {
+		int number = (int)strtol(token, NULL, 16);
+		if (errno == EINVAL || errno == ERANGE || number > 0xFF)
+			return -1;
+		data[byte_count++] = (uint8_t)number;
+	}
+	return byte_count;
+}
+
+/** Parse crypto cipher operation command line argument */
+static int
+parse_auth_algo(enum rte_crypto_auth_algorithm *algo, char *optarg)
+{
+	if (rte_cryptodev_get_auth_algo_enum(algo, optarg) < 0) {
+		printf("Authentication algorithm specified not supported!\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int
+parse_auth_op(enum rte_crypto_auth_operation *op, char *optarg)
+{
+	if (strcmp("VERIFY", optarg) == 0) {
+		*op = RTE_CRYPTO_AUTH_OP_VERIFY;
+		return 0;
+	} else if (strcmp("GENERATE", optarg) == 0) {
+		*op = RTE_CRYPTO_AUTH_OP_GENERATE;
+		return 0;
+	}
+	printf("Authentication operation specified not supported!\n");
+	return -1;
+}
+
+static int
+parse_aead_algo(enum rte_crypto_aead_algorithm *algo, char *optarg)
+{
+	if (rte_cryptodev_get_aead_algo_enum(algo, optarg) < 0) {
+		printf("AEAD algorithm specified not supported!\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int
+parse_aead_op(enum rte_crypto_aead_operation *op, char *optarg)
+{
+	if (strcmp("ENCRYPT", optarg) == 0) {
+		*op = RTE_CRYPTO_AEAD_OP_ENCRYPT;
+		return 0;
+	} else if (strcmp("DECRYPT", optarg) == 0) {
+		*op = RTE_CRYPTO_AEAD_OP_DECRYPT;
+		return 0;
+	}
+	printf("AEAD operation specified not supported!\n");
+	return -1;
+}
+
+/** Parse long options */
+static int
+ccp_crypto_parse_args_long_options(struct ccp_crypto_options *options,
+		struct option *lgopts, int option_index)
+{
+	int retval;
+
+	if (strcmp(lgopts[option_index].name, "cdev_type") == 0) {
+		retval = parse_cryptodev_type(&options->type, optarg);
+		if (retval == 0)
+			snprintf(options->string_type, MAX_STR_LEN,
+				"%s", optarg);
+		return retval;
+	} else if (strcmp(lgopts[option_index].name, "plain_text") == 0) {
+		pt_length =
+			parse_bytes(pt, optarg, MAX_PT_SIZE);
+		buffer_size = pt_length;
+		if (pt_length > 0)
+			return 0;
+		else
+			return -1;
+	} else if (strcmp(lgopts[option_index].name, "cipher_op") == 0)
+		return parse_cipher_op(&options->cipher_xform.cipher.op,
+			optarg);
+	else if (strcmp(lgopts[option_index].name, "cipher_algo") == 0)
+		return parse_cipher_algo(&options->cipher_xform.cipher.algo,
+			optarg);
+	else if (strcmp(lgopts[option_index].name, "cipher_key") == 0) {
+		options->cipher_xform.cipher.key.length =
+		parse_bytes(options->cipher_key, optarg, MAX_KEY_SIZE);
+		if (options->cipher_xform.cipher.key.length > 0)
+			return 0;
+		else
+			return -1;
+	} else if (strcmp(lgopts[option_index].name, "cipher_iv") == 0) {
+		options->cipher_iv.length =
+			parse_bytes(options->cipher_iv.data,
+					optarg, MAX_IV_SIZE);
+		options->cipher_xform.cipher.iv.length =
+			options->cipher_iv.length;
+		options->cipher_xform.cipher.iv.offset =  IV_OFFSET;
+		if (options->cipher_iv.length > 0)
+			return 0;
+		else
+			return -1;
+	}
+
+	/* Authentication options */
+	else if (strcmp(lgopts[option_index].name, "auth_op") == 0)
+		return parse_auth_op(&options->auth_xform.auth.op,
+					optarg);
+	else if (strcmp(lgopts[option_index].name, "auth_algo") == 0) {
+		return parse_auth_algo(&options->auth_xform.auth.algo,
+					optarg);
+	} else if (strcmp(lgopts[option_index].name, "auth_key") == 0) {
+		options->auth_xform.auth.key.length =
+			parse_bytes(options->auth_key, optarg, MAX_KEY_SIZE);
+		if (options->auth_xform.auth.key.length > 0)
+			return 0;
+		else
+			return -1;
+	}
+	/* AEAD options */
+	else if (strcmp(lgopts[option_index].name, "aead_algo") == 0) {
+		return parse_aead_algo(&options->aead_xform.aead.algo,
+					optarg);
+	} else if (strcmp(lgopts[option_index].name, "aead_op") == 0)
+		return parse_aead_op(&options->aead_xform.aead.op,
+					optarg);
+	else if (strcmp(lgopts[option_index].name, "aead_key") == 0) {
+		options->aead_xform.aead.key.length =
+			parse_bytes(options->aead_key, optarg, MAX_KEY_SIZE);
+		if (options->aead_xform.aead.key.length > 0)
+			return 0;
+		else
+			return -1;
+	} else if (strcmp(lgopts[option_index].name, "aead_iv") == 0) {
+		options->aead_iv.length =
+			parse_bytes(options->aead_iv.data,
+					optarg, MAX_IV_SIZE);
+		options->aead_xform.aead.iv.length = options->aead_iv.length;
+		options->aead_xform.aead.iv.offset =  IV_OFFSET;
+		if (options->aead_xform.aead.iv.length > 0)
+			return 0;
+		else
+			return -1;
+	} else if (strcmp(lgopts[option_index].name, "aad") == 0) {
+		options->aad.length =
+			parse_bytes(options->aad.data, optarg, MAX_AAD_SIZE);
+		options->aead_xform.aead.aad_length = options->aad.length;
+		if (options->aad.length > 0)
+			return 0;
+		else
+			return -1;
+	} else if (strcmp(lgopts[option_index].name, "digest") == 0) {
+		options->digest_size =
+			parse_bytes(options->aad_digest.data,
+					optarg, MAX_DIGEST_SIZE);
+		options->aead_xform.aead.digest_length = options->digest_size;
+		if (options->digest_size > 0)
+			return 0;
+		else
+			return -1;
+	}
+	return -1;
+}
+
+static void
+ccp_crypto_default_options(struct ccp_crypto_options *options)
+{
+	options->type = CDEV_TYPE_ANY;
+	options->crypto_op_private_data = AES_CBC_IV_LENGTH;
+
+	/* Cipher Data */
+	options->cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+	options->cipher_xform.next = NULL;
+	options->cipher_xform.cipher.key.length = 0;
+	options->cipher_xform.cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC;
+	options->cipher_xform.cipher.op = -1;
+	options->cipher_xform.cipher.iv.offset = IV_OFFSET;
+	options->cipher_xform.cipher.iv.length = AES_CBC_IV_LENGTH;
+
+	 /* Authentication Data */
+	options->auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+	options->auth_xform.next = NULL;
+	options->auth_xform.auth.key.length = 20;
+	options->auth_xform.auth.digest_length = 20;
+	options->auth_xform.auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC;
+	options->auth_xform.auth.op = -1;
+
+	/* AEAD Data */
+	options->aead_xform.type = RTE_CRYPTO_SYM_XFORM_AEAD;
+	options->aead_xform.next = NULL;
+	options->aead_xform.aead.key.length = 0;
+	options->aead_xform.aead.digest_length = 0;
+	options->aead_iv.length = 16;
+	options->aead_xform.aead.iv.offset =  IV_OFFSET;
+	options->aead_xform.aead.algo = RTE_CRYPTO_AEAD_AES_GCM;
+	options->aead_xform.aead.op = -1;
+	options->aad.length = 0;
+	options->digest_size = -1;
+}
+
+static int
+ccp_crypto_parse_args(struct ccp_crypto_options *options,
+	int argc, char **argv)
+{
+	int opt, retval, option_index;
+	char **argvopt = argv, *prgname = argv[0];
+
+	static struct option lgopts[] = {
+		{ "cdev_type", required_argument, 0, 0 },
+		{ "cipher_op", required_argument, 0, 0 },
+		{ "cipher_algo", required_argument, 0, 0 },
+		{ "plain_text", required_argument, 0, 0 },
+		{ "cipher_key", required_argument, 0, 0 },
+		{ "cipher_iv", required_argument, 0, 0 },
+
+		{ "auth_op", required_argument, 0, 0 },
+		{ "auth_algo", required_argument, 0, 0 },
+		{ "auth_key", required_argument, 0, 0 },
+
+		{ "aead_algo", required_argument, 0, 0 },
+		{ "aead_op", required_argument, 0, 0 },
+		{ "aead_key", required_argument, 0, 0 },
+		{ "aead_iv", required_argument, 0, 0 },
+		{ "aad", required_argument, 0, 0 },
+		{ "digest", required_argument, 0, 0 },
+
+		{ NULL, 0, 0, 0 }
+	};
+
+	ccp_crypto_default_options(options);
+
+	while ((opt = getopt_long(argc, argvopt, "ac:", lgopts,
+			&option_index)) != EOF) {
+		switch (opt) {
+		case 0:
+			retval = ccp_crypto_parse_args_long_options(options,
+						lgopts, option_index);
+			if (retval < 0) {
+				ccp_crypto_usage(prgname);
+				return -1;
+			}
+		break;
+		default:
+			ccp_crypto_usage(prgname);
+			return -1;
+		}
+	}
+	if (optind >= 0)
+		argv[optind-1] = prgname;
+
+	retval = optind-1;
+	optind = 1;
+
+	return retval;
+}
+
+static void
+reserve_key_memory(struct ccp_crypto_options *options)
+{
+	pt = rte_malloc("plain_text", MAX_PT_SIZE, 0);
+	if (pt == NULL)
+		rte_exit(EXIT_FAILURE,
+			       "Failed to allocate memory for plain text");
+
+	options->cipher_xform.cipher.key.data = options->cipher_key;
+
+	options->cipher_iv.data = rte_malloc("cipher iv", MAX_IV_SIZE, 0);
+	if (options->cipher_iv.data == NULL)
+		rte_exit(EXIT_FAILURE,
+			       "Failed to allocate memory for cipher IV");
+
+	options->auth_xform.auth.key.data = options->auth_key;
+
+	options->aead_iv.data = rte_malloc("aead_iv", MAX_IV_SIZE, 0);
+	if (options->aead_iv.data == NULL)
+		rte_exit(EXIT_FAILURE, "Failed to allocate memory for AEAD iv");
+
+	options->aead_xform.aead.key.data = options->aead_key;
+	options->aad.data = rte_malloc("aad", MAX_AAD_SIZE, 0);
+	if (options->aad.data == NULL)
+		rte_exit(EXIT_FAILURE, "Failed to allocate memory for AAD");
+
+	options->aad_digest.data = rte_malloc("digest", MAX_DIGEST_SIZE, 0);
+	if (options->aad_digest.data == NULL)
+		rte_exit(EXIT_FAILURE, "Failed to allocate memory for Digest");
+}
+
+static struct rte_cryptodev_sym_session *
+initialize_crypto_session(struct ccp_crypto_options *options,
+			struct rte_mempool *sess_mp,
+			struct rte_mempool *sess_mp_priv,
+			uint8_t cdev_id)
+{
+	struct rte_crypto_sym_xform *xform;
+	struct rte_cryptodev_sym_session *session;
+	int retval = rte_cryptodev_socket_id(cdev_id);
+
+	if (retval < 0)
+		return NULL;
+
+	if (options->cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT ||
+		options->cipher_xform.cipher.op ==
+			RTE_CRYPTO_CIPHER_OP_DECRYPT) {
+		xform = &options->cipher_xform;
+	} else if (options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_GENERATE ||
+		options->auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) {
+		xform = &options->auth_xform;
+	} else if (options->aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT ||
+		options->aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_DECRYPT) {
+		xform = &options->aead_xform;
+	} else {
+		xform = &options->cipher_xform;
+	}
+
+	session = rte_cryptodev_sym_session_create(sess_mp);
+
+	if (session == NULL) {
+		printf("session NULL\n");
+		return NULL;
+	}
+
+	if (rte_cryptodev_sym_session_init(cdev_id, session,
+			xform, sess_mp_priv) < 0) {
+		printf("sym session init fails");
+		return NULL;
+	}
+	return session;
+}
+
+int
+main(int argc, char **argv)
+{
+	int ret, save_file = 1;
+	uint8_t  cdev_id = 0, cdev_count;
+	unsigned int sess_sz;
+
+	struct rte_cryptodev_qp_conf qp_conf;
+	struct rte_cryptodev_info dev_info;
+	struct rte_cryptodev_sym_session *session;
+	struct rte_mempool *mbuf_pool, *crypto_op_pool;
+	struct ccp_crypto_options options;
+
+	char mp_name[RTE_MEMPOOL_NAMESIZE], mp_name2[RTE_MEMPOOL_NAMESIZE];
+	struct rte_mempool *sess_mp, *sess_mp_priv;
+	int retval = rte_cryptodev_socket_id(cdev_id);
+	uint8_t socket_id = (uint8_t) retval;
+	uint8_t *input_file = NULL;
+	long flen = 0;
+	unsigned int crypto_op_private_data = AES_CBC_IV_LENGTH;
+	struct rte_crypto_op *crypto_ops[BURST_SIZE];
+	struct rte_mbuf *mbufs[BURST_SIZE];
+	unsigned int i;
+	int buff_size;
+	int md_size;
+	int log_size;
+	int loop = 0;
+
+	ret = rte_eal_init(argc, argv);
+	if (ret < 0)
+		rte_panic("Cannot init EAL\n");
+	argc -= ret;
+	argv += ret;
+
+	/* reserve memory for Plain_text/Cipher/Auth key/IV and AEAD*/
+	reserve_key_memory(&options);
+
+	/* parse application arguments (after the EAL ones) */
+	ret = ccp_crypto_parse_args(&options, argc, argv);
+	if (ret < 0)
+		rte_exit(EXIT_FAILURE, "Invalid CCP-CRYPTO arguments\n");
+
+	cdev_count = rte_cryptodev_count();
+	printf("cdev_count: %d\n", cdev_count);
+
+	sess_sz = rte_cryptodev_sym_get_private_session_size(cdev_id);
+
+	rte_cryptodev_info_get(cdev_id, &dev_info);
+	printf("crypto dev name: %s\n", dev_info.driver_name);
+
+	retval = rte_cryptodev_socket_id(cdev_id);
+	socket_id = (uint8_t) retval;
+
+	snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, "sess_mp_%u", socket_id);
+	snprintf(mp_name2, RTE_MEMPOOL_NAMESIZE, "sess_mp_priv%u", socket_id);
+
+	sess_mp = rte_cryptodev_sym_session_pool_create(mp_name,
+				sess_sz, 0, 0, 0, socket_id);
+	if (sess_mp == NULL) {
+		printf("Cannot create session pool on socket %d\n", socket_id);
+				return -ENOMEM;
+	}
+	sess_mp_priv = rte_mempool_create(mp_name2, 2, sess_sz,
+					SESSION_POOL_CACHE_SIZE,
+					0, NULL, NULL, NULL,
+					NULL, socket_id, 0);
+	if (sess_mp == NULL) {
+		printf("Cannot create session pool on socket %d\n", socket_id);
+		return -ENOMEM;
+	}
+
+	struct rte_cryptodev_config conf = {
+			.nb_queue_pairs = 1,
+			.socket_id = socket_id,
+	};
+	retval = rte_cryptodev_configure(cdev_id, &conf);
+	qp_conf.nb_descriptors = 2048;
+	qp_conf.mp_session = sess_mp;
+	qp_conf.mp_session_private = sess_mp_priv;
+
+	retval = rte_cryptodev_queue_pair_setup(cdev_id, 0, &qp_conf,
+			socket_id);
+	if (retval < 0) {
+		printf("Failed to setup queue pair %u on cryptodev %u",
+				0, cdev_id);
+		return -1;
+	}
+
+	retval = rte_cryptodev_start(cdev_id);
+	if (retval < 0) {
+		printf("Failed to start device %u: error %d\n",
+			cdev_id, retval);
+		return -1;
+	}
+	/* Create crypto operation pool. */
+	crypto_op_pool = rte_crypto_op_pool_create("crypto_op_pool",
+						RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+						NUM_MBUFS,
+						POOL_CACHE_SIZE,
+						crypto_op_private_data,
+						socket_id);
+
+	if (options.cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT
+		|| options.aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_DECRYPT) {
+		FILE *f = fopen("encoded.data", "rb");
+		fseek(f, 0L, SEEK_END);
+		flen = ftell(f);
+		input_file = malloc(flen);
+		rewind(f);
+		size_t result = fread(input_file, flen, 1, f);
+		if (!result) {
+			fputs("Reading error", stderr); exit(3);
+		}
+		fclose(f);
+	}
+
+	if (options.auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) {
+		FILE *f = fopen("sha.data", "rb");
+		fseek(f, 0L, SEEK_END);
+		flen = ftell(f);
+		input_file = malloc(flen);
+		rewind(f);
+		size_t result = fread(input_file, flen, 1, f);
+		if (!result) {
+			fputs("Reading error", stderr); exit(3);
+		}
+		fclose(f);
+	}
+	if ((options.auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY)
+		|| (options.auth_xform.auth.op ==
+		       RTE_CRYPTO_AUTH_OP_GENERATE)) {
+		switch (options.auth_xform.auth.algo) {
+		case RTE_CRYPTO_AUTH_SHA1:
+		case RTE_CRYPTO_AUTH_SHA1_HMAC:
+			md_size = SHA_DIGEST_LENGTH;
+			break;
+		case RTE_CRYPTO_AUTH_SHA224:
+		case RTE_CRYPTO_AUTH_SHA224_HMAC:
+		case RTE_CRYPTO_AUTH_SHA3_224:
+		case RTE_CRYPTO_AUTH_SHA3_224_HMAC:
+			md_size = SHA224_DIGEST_LENGTH;
+			break;
+		case RTE_CRYPTO_AUTH_SHA256:
+		case RTE_CRYPTO_AUTH_SHA256_HMAC:
+		case RTE_CRYPTO_AUTH_SHA3_256:
+		case RTE_CRYPTO_AUTH_SHA3_256_HMAC:
+			md_size = SHA256_DIGEST_LENGTH;
+			break;
+		case RTE_CRYPTO_AUTH_SHA384:
+		case RTE_CRYPTO_AUTH_SHA384_HMAC:
+		case RTE_CRYPTO_AUTH_SHA3_384:
+		case RTE_CRYPTO_AUTH_SHA3_384_HMAC:
+			md_size = SHA384_DIGEST_LENGTH;
+			break;
+		case RTE_CRYPTO_AUTH_SHA512:
+		case RTE_CRYPTO_AUTH_SHA512_HMAC:
+		case RTE_CRYPTO_AUTH_SHA3_512:
+		case RTE_CRYPTO_AUTH_SHA3_512_HMAC:
+			md_size = SHA512_DIGEST_LENGTH;
+			break;
+		default:
+			md_size = 20;
+			printf("Non-supported mode !!!\n");
+			break;
+		}
+		options.auth_xform.auth.digest_length = md_size;
+	}
+
+	session = initialize_crypto_session(&options,
+				sess_mp, sess_mp_priv, cdev_id);
+	if (session == NULL) {
+		printf("session NULL\n");
+		return 0;
+	}
+
+	/* Get a burst of crypto operations. */
+	if (rte_crypto_op_bulk_alloc(crypto_op_pool,
+					RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+					crypto_ops, BURST_SIZE) == 0)
+		rte_exit(EXIT_FAILURE,
+				"Not enough crypto operations available\n");
+
+	/* Create the mbuf pool. */
+	mbuf_pool = rte_pktmbuf_pool_create("mbuf_pool", NUM_MBUFS,
+				POOL_CACHE_SIZE, 0,
+				(RTE_MBUF_DEFAULT_BUF_SIZE+1024*60), socket_id);
+	if (mbuf_pool == NULL)
+		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
+
+	buff_size = buffer_size;
+	if (options.auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY)
+		buff_size = flen;
+
+	if (rte_pktmbuf_alloc_bulk(mbuf_pool, mbufs, BURST_SIZE) < 0)
+		rte_exit(EXIT_FAILURE, "Not enough mbufs available");
+
+	/* Initialize the mbufs and append them to the crypto operations. */
+	for (i = 0; i < BURST_SIZE; i++) {
+		if (rte_pktmbuf_append(mbufs[i], buff_size) == NULL)
+			rte_exit(EXIT_FAILURE, "Not enough room in the mbuf\n");
+		crypto_ops[i]->sym->m_src = mbufs[i];
+	}
+	/* Set up the crypto operations. */
+	for (i = 0; i < BURST_SIZE; i++) {
+		struct rte_crypto_op *op = crypto_ops[i];
+		if ((options.cipher_xform.cipher.op ==
+			RTE_CRYPTO_CIPHER_OP_DECRYPT) ||
+			(options.cipher_xform.cipher.op
+				== RTE_CRYPTO_CIPHER_OP_ENCRYPT)) {
+			op->sym->cipher.data.offset = 0;
+			op->sym->cipher.data.length = buffer_size;
+			if ((options.cipher_xform.cipher.algo !=
+				RTE_CRYPTO_CIPHER_3DES_ECB) ||
+				(options.cipher_xform.cipher.algo !=
+					RTE_CRYPTO_CIPHER_AES_ECB)) {
+				uint8_t *iv_ptr =
+					rte_crypto_op_ctod_offset(op,
+							uint8_t *, IV_OFFSET);
+				rte_memcpy(iv_ptr, options.cipher_iv.data,
+						options.cipher_iv.length);
+			}
+		}
+		op->sym->auth.data.offset = 0;
+		if (options.aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT) {
+			uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op,
+					uint8_t *, IV_OFFSET);
+			rte_memcpy(iv_ptr, options.aead_iv.data,
+					options.aead_iv.length);
+			op->sym->aead.data.offset = 0;
+			op->sym->aead.data.length = buffer_size;
+			op->sym->aead.aad.data = options.aad.data;
+			op->sym->aead.digest.data =
+			       (uint8_t *)rte_pktmbuf_append(mbufs[i],
+						options.digest_size);
+			rte_memcpy(op->sym->aead.digest.data,
+					options.aad_digest.data,
+					options.aead_xform.aead.digest_length);
+		}
+		if (options.aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_DECRYPT) {
+			uint8_t *iv_ptr = rte_crypto_op_ctod_offset(op,
+							uint8_t *, IV_OFFSET);
+			rte_memcpy(iv_ptr, options.aead_iv.data,
+					options.aead_iv.length);
+			op->sym->aead.data.offset = 0;
+			op->sym->aead.data.length = flen;
+			op->sym->aead.aad.data = options.aad.data;
+			op->sym->aead.digest.data =
+				(uint8_t *)rte_pktmbuf_mtod(mbufs[i], uint8_t *)
+					+flen - options.digest_size;
+		}
+		if (options.auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_GENERATE) {
+			op->sym->auth.data.length = buffer_size;
+			op->sym->auth.digest.data =
+			  (uint8_t *)rte_pktmbuf_append(mbufs[i], md_size);
+		}
+		if (options.auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY) {
+			op->sym->auth.data.length = flen-md_size;
+			op->sym->auth.digest.data =
+				rte_pktmbuf_mtod(mbufs[i], uint8_t *)
+				  + (rte_pktmbuf_data_len(mbufs[i])-md_size);
+		}
+		/* Attach the crypto session to the operation */
+		rte_crypto_op_attach_sym_session(op, session);
+	}
+	while (loop < 1) {
+		if ((options.cipher_xform.cipher.op ==
+				RTE_CRYPTO_CIPHER_OP_ENCRYPT)
+			|| (options.auth_xform.auth.op ==
+				RTE_CRYPTO_AUTH_OP_GENERATE)
+			|| (options.aead_xform.aead.op ==
+				RTE_CRYPTO_AEAD_OP_ENCRYPT)) {
+			char *ch;
+			for (int j = 0; j < BURST_SIZE; j++) {
+				ch  = rte_pktmbuf_mtod(mbufs[j], char *);
+				for (int k = 0; k < pt_length; k++)
+					memset(ch+k, pt[k], sizeof(char));
+			}
+			printf("I/P =\n");
+			ch  = rte_pktmbuf_mtod(mbufs[0], char *);
+			for (int k = 1;
+				k <= crypto_ops[0]->sym->m_src->data_len;
+					k++) {
+				printf("%02x", ch[k-1] & 0xff);
+				if (k%16 == 0)
+					printf("\n");
+			}
+			printf("\n");
+		}
+		if ((options.cipher_xform.cipher.op ==
+					RTE_CRYPTO_CIPHER_OP_DECRYPT)
+			|| (options.auth_xform.auth.op ==
+				RTE_CRYPTO_AUTH_OP_VERIFY)
+			|| (options.aead_xform.aead.op ==
+				RTE_CRYPTO_AEAD_OP_DECRYPT)) {
+			char *ch;
+			for (int j = 0; j < BURST_SIZE; j++) {
+				ch  = rte_pktmbuf_mtod(mbufs[j], char *);
+				rte_memcpy(ch, input_file, flen);
+			}
+			printf("I/P =\n");
+			ch  = rte_pktmbuf_mtod(mbufs[0], char *);
+			for (int k = 1;
+				k <= crypto_ops[0]->sym->m_src->data_len; k++) {
+				printf("%02x", ch[k-1] & 0xff);
+				if (k%16 == 0)
+					printf("\n");
+			}
+			printf("\n");
+		}
+		/* Enqueue the crypto operations in the crypto device. */
+		uint16_t num_enqueued_ops =
+				rte_cryptodev_enqueue_burst(cdev_id,
+						0, crypto_ops, BURST_SIZE);
+		if (num_enqueued_ops == 0) {
+			printf("continuing\n");
+			continue;
+		}
+		uint16_t num_dequeued_ops, total_num_dequeued_ops = 0;
+
+		do {
+			num_dequeued_ops = rte_cryptodev_dequeue_burst(cdev_id,
+						0, crypto_ops, BURST_SIZE);
+			total_num_dequeued_ops += num_dequeued_ops;
+			/* Check if operation was processed successfully */
+			for (i = 0; i < num_dequeued_ops; i++) {
+				if (crypto_ops[i]->status !=
+						RTE_CRYPTO_OP_STATUS_SUCCESS) {
+					printf("error @ i: %d\n", i);
+				}
+			}
+			printf("%s",
+				(char *)crypto_ops[0]->sym->m_src->buf_addr);
+			rte_mempool_put_bulk(crypto_op_pool,
+					(void **)crypto_ops, num_dequeued_ops);
+		} while (total_num_dequeued_ops < num_enqueued_ops);
+		char *ch;
+		ch  = rte_pktmbuf_mtod(crypto_ops[0]->sym->m_src, char *);
+		printf("O/P =\n");
+		if (options.auth_xform.auth.op == RTE_CRYPTO_AUTH_OP_VERIFY)
+			log_size = crypto_ops[0]->sym->m_src->data_len-md_size;
+		else
+			log_size = crypto_ops[0]->sym->m_src->data_len;
+		for (int k = 1; k <= log_size; k++) {
+			printf("%02x", ch[k-1] & 0xff);
+			if (k%16 == 0)
+				printf("\n");
+		}
+		printf("\n");
+		if (options.auth_xform.auth.op ==
+				RTE_CRYPTO_AUTH_OP_GENERATE) {
+			if (save_file) {
+				char *ch;
+				ch  = rte_pktmbuf_mtod(
+					crypto_ops[0]->sym->m_src, char *);
+				FILE *f = fopen("sha.data", "wb");
+				fwrite(ch, sizeof(char),
+					crypto_ops[0]->sym->m_src->data_len, f);
+				fclose(f);
+				printf("\n sha buff:\n");
+				ch  = rte_pktmbuf_mtod(
+					crypto_ops[0]->sym->m_src, char *);
+				for (int i = 0; i < md_size; i++)
+					printf("%02x",
+						ch[buffer_size+i] & 0xff);
+				printf("\n");
+			}
+	}
+	if (options.cipher_xform.cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT
+		||  options.aead_xform.aead.op == RTE_CRYPTO_AEAD_OP_ENCRYPT) {
+		if (save_file) {
+			char *ch;
+			ch  = rte_pktmbuf_mtod(
+					crypto_ops[0]->sym->m_src, char *);
+			FILE *f = fopen("encoded.data", "wb");
+			fwrite(ch, sizeof(char),
+				crypto_ops[0]->sym->m_src->data_len, f);
+			fclose(f);
+		}
+	}
+	loop++;
+	}
+	return 0;
+}