DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH 0/7] Fix build with gcc-16
@ 2025-12-28 18:40 Stephen Hemminger
  2025-12-28 18:40 ` [PATCH 1/7] pcapng: use alloca instead of fixed buffer Stephen Hemminger
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Stephen Hemminger @ 2025-12-28 18:40 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger

This is a collection of previous patches and a couple of new
ones which allow building DPDK with latesg Gcc 16.

Stephen Hemminger (7):
  pcapng: use alloca instead of fixed buffer
  pcapng: add additional mbuf if space required on copy
  test: add more tests for comments in pcapng
  test: vary size of packets in pcapng test
  net/bnxt: fix uninitialized warning
  common/cnxk: fix array out of bounds
  examples/fips_validation: avoid rte_memcpy alignment restriction

 app/test/test_pcapng.c                   |  116 +-
 drivers/common/cnxk/roc_nix_inl_dev.c    |   10 +-
 drivers/net/bnxt/tf_ulp/ulp_mapper.c     |    5 +
 drivers/net/bnxt/tf_ulp/ulp_mapper_tfc.c |    4 +
 examples/fips_validation/#main.c#        | 3082 ++++++++++++++++++++++
 examples/fips_validation/main.c          |   14 +-
 lib/pcapng/rte_pcapng.c                  |   38 +-
 7 files changed, 3212 insertions(+), 57 deletions(-)
 create mode 100644 examples/fips_validation/#main.c#

-- 
2.51.0


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

* [PATCH 1/7] pcapng: use alloca instead of fixed buffer
  2025-12-28 18:40 [PATCH 0/7] Fix build with gcc-16 Stephen Hemminger
@ 2025-12-28 18:40 ` Stephen Hemminger
  2025-12-28 18:40 ` [PATCH 2/7] pcapng: add additional mbuf if space required on copy Stephen Hemminger
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2025-12-28 18:40 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Reshma Pattan

This is an API that accepts strings as options, and user could
potentially ask for very large string as comment.
The dynamic way to fix is to use alloca() to allocate the buffer
used to hold options.

Bugzilla ID: 1820

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/pcapng/rte_pcapng.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/lib/pcapng/rte_pcapng.c b/lib/pcapng/rte_pcapng.c
index 21bc94cea1..3067033e89 100644
--- a/lib/pcapng/rte_pcapng.c
+++ b/lib/pcapng/rte_pcapng.c
@@ -34,9 +34,6 @@
 /* conversion from DPDK speed to PCAPNG */
 #define PCAPNG_MBPS_SPEED 1000000ull
 
-/* upper bound for section, stats and interface blocks (in uint32_t) */
-#define PCAPNG_BLKSIZ	(2048 / sizeof(uint32_t))
-
 /* Format of the capture file handle */
 struct rte_pcapng {
 	int  outfd;		/* output file */
@@ -145,7 +142,7 @@ pcapng_section_block(rte_pcapng_t *self,
 {
 	struct pcapng_section_header *hdr;
 	struct pcapng_option *opt;
-	uint32_t buf[PCAPNG_BLKSIZ];
+	uint32_t *buf;
 	uint32_t len;
 
 	len = sizeof(*hdr);
@@ -162,7 +159,8 @@ pcapng_section_block(rte_pcapng_t *self,
 	len += pcapng_optlen(0);
 	len += sizeof(uint32_t);
 
-	if (len > sizeof(buf))
+	buf = alloca(len);
+	if (buf == NULL)
 		return -1;
 
 	hdr = (struct pcapng_section_header *)buf;
@@ -214,7 +212,7 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port, uint16_t link_type,
 	struct pcapng_option *opt;
 	const uint8_t tsresol = 9;	/* nanosecond resolution */
 	uint32_t len;
-	uint32_t buf[PCAPNG_BLKSIZ];
+	uint32_t *buf;
 	char ifname_buf[IF_NAMESIZE];
 	char ifhw[256];
 	uint64_t speed = 0;
@@ -268,7 +266,8 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port, uint16_t link_type,
 	len += pcapng_optlen(0);
 	len += sizeof(uint32_t);
 
-	if (len > sizeof(buf))
+	buf = alloca(len);
+	if (buf == NULL)
 		return -1;
 
 	hdr = (struct pcapng_interface_block *)buf;
@@ -333,7 +332,7 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
 	uint64_t start_time = self->offset_ns;
 	uint64_t sample_time;
 	uint32_t optlen, len;
-	uint32_t buf[PCAPNG_BLKSIZ];
+	uint32_t *buf;
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
 
@@ -353,7 +352,9 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
 		optlen += pcapng_optlen(0);
 
 	len = sizeof(*hdr) + optlen + sizeof(uint32_t);
-	if (len > sizeof(buf))
+
+	buf = alloca(len);
+	if (buf == NULL)
 		return -1;
 
 	hdr = (struct pcapng_statistics *)buf;
-- 
2.51.0


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

* [PATCH 2/7] pcapng: add additional mbuf if space required on copy
  2025-12-28 18:40 [PATCH 0/7] Fix build with gcc-16 Stephen Hemminger
  2025-12-28 18:40 ` [PATCH 1/7] pcapng: use alloca instead of fixed buffer Stephen Hemminger
@ 2025-12-28 18:40 ` Stephen Hemminger
  2025-12-28 18:40 ` [PATCH 3/7] test: add more tests for comments in pcapng Stephen Hemminger
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2025-12-28 18:40 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Reshma Pattan

If comment is passed to rte_pcapng_copy(), additional space
maybe needed at the end of the mbuf. To handle this case generate
a segmented mbuf with additional space for the options.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/pcapng/rte_pcapng.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/lib/pcapng/rte_pcapng.c b/lib/pcapng/rte_pcapng.c
index 3067033e89..7c3c400c71 100644
--- a/lib/pcapng/rte_pcapng.c
+++ b/lib/pcapng/rte_pcapng.c
@@ -540,11 +540,24 @@ rte_pcapng_copy(uint16_t port_id, uint32_t queue,
 	if (comment)
 		optlen += pcapng_optlen(strlen(comment));
 
-	/* reserve trailing options and block length */
+	/*
+	 * Try to put options at the end of this mbuf.
+	 * If not use an mbuf chain.
+	 */
 	opt = (struct pcapng_option *)
 		rte_pktmbuf_append(mc, optlen + sizeof(uint32_t));
-	if (unlikely(opt == NULL))
-		goto fail;
+	if (unlikely(opt == NULL)) {
+		struct rte_mbuf *ml = rte_pktmbuf_alloc(mp);
+
+		if (unlikely(ml == NULL))
+			goto fail;
+
+		opt = (struct pcapng_option *)rte_pktmbuf_append(ml, optlen + sizeof(uint32_t));
+		if (unlikely(opt == NULL || rte_pktmbuf_chain(mc, ml) != 0)) {
+			rte_pktmbuf_free(ml);
+			goto fail;
+		}
+	}
 
 	switch (direction) {
 	case RTE_PCAPNG_DIRECTION_IN:
-- 
2.51.0


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

* [PATCH 3/7] test: add more tests for comments in pcapng
  2025-12-28 18:40 [PATCH 0/7] Fix build with gcc-16 Stephen Hemminger
  2025-12-28 18:40 ` [PATCH 1/7] pcapng: use alloca instead of fixed buffer Stephen Hemminger
  2025-12-28 18:40 ` [PATCH 2/7] pcapng: add additional mbuf if space required on copy Stephen Hemminger
@ 2025-12-28 18:40 ` Stephen Hemminger
  2025-12-28 18:40 ` [PATCH 4/7] test: vary size of packets in pcapng test Stephen Hemminger
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2025-12-28 18:40 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Reshma Pattan

Add some more cases where comment is set in pcapng file.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test/test_pcapng.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/app/test/test_pcapng.c b/app/test/test_pcapng.c
index bcf99724fa..f2b49c31c7 100644
--- a/app/test/test_pcapng.c
+++ b/app/test/test_pcapng.c
@@ -125,8 +125,7 @@ test_setup(void)
 
 	/* Make a pool for cloned packets */
 	mp = rte_pktmbuf_pool_create_by_ops("pcapng_test_pool",
-					    MAX_BURST * 32, 0, 0,
-					    rte_pcapng_mbuf_size(pkt_len) + 128,
+					    MAX_BURST * 32, 0, 0, rte_pcapng_mbuf_size(pkt_len),
 					    SOCKET_ID_ANY, "ring_mp_sc");
 	if (mp == NULL) {
 		fprintf(stderr, "Cannot create mempool\n");
@@ -149,6 +148,13 @@ fill_pcapng_file(rte_pcapng_t *pcapng, unsigned int num_packets)
 	unsigned int burst_size;
 	unsigned int count;
 	ssize_t len;
+	const char *examples[] = {
+		"EAL init complete. May the cores be ever in your favor.",
+		"No packets were harmed in the making of this burst.",
+		"rte_eth_dev_start(): crossing fingers and enabling queues...",
+		"Congratulations, you’ve reached the end of the RX path. Please collect your free cache miss.",
+		"Lockless and fearless — that’s how we roll in userspace."
+	};
 
 	/* make a dummy packet */
 	mbuf1_prepare(&mbfs, pkt_len);
@@ -162,9 +168,14 @@ fill_pcapng_file(rte_pcapng_t *pcapng, unsigned int num_packets)
 		burst_size = rte_rand_max(MAX_BURST) + 1;
 		for (i = 0; i < burst_size; i++) {
 			struct rte_mbuf *mc;
+			const char *comment = NULL;
+
+			/* Put comment on occasional packets */
+			if ((count + i) % 42 == 0)
+				comment = examples[rte_rand_max(RTE_DIM(examples))];
 
 			mc = rte_pcapng_copy(port_id, 0, orig, mp, rte_pktmbuf_pkt_len(orig),
-					     RTE_PCAPNG_DIRECTION_IN, NULL);
+					     RTE_PCAPNG_DIRECTION_IN, comment);
 			if (mc == NULL) {
 				fprintf(stderr, "Cannot copy packet\n");
 				return -1;
@@ -386,7 +397,7 @@ static int
 test_write_packets(void)
 {
 	char file_name[] = "/tmp/pcapng_test_XXXXXX.pcapng";
-	static rte_pcapng_t *pcapng;
+	rte_pcapng_t *pcapng = NULL;
 	int ret, tmp_fd, count;
 	uint64_t now = current_timestamp();
 
@@ -413,6 +424,13 @@ test_write_packets(void)
 		goto fail;
 	}
 
+	/* write a statistics block */
+	ret = rte_pcapng_write_stats(pcapng, port_id, 0, 0, NULL);
+	if (ret <= 0) {
+		fprintf(stderr, "Write of statistics failed\n");
+		goto fail;
+	}
+
 	count = fill_pcapng_file(pcapng, TOTAL_PACKETS);
 	if (count < 0)
 		goto fail;
-- 
2.51.0


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

* [PATCH 4/7] test: vary size of packets in pcapng test
  2025-12-28 18:40 [PATCH 0/7] Fix build with gcc-16 Stephen Hemminger
                   ` (2 preceding siblings ...)
  2025-12-28 18:40 ` [PATCH 3/7] test: add more tests for comments in pcapng Stephen Hemminger
@ 2025-12-28 18:40 ` Stephen Hemminger
  2025-12-28 18:40 ` [PATCH 5/7] net/bnxt: fix uninitialized warning Stephen Hemminger
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2025-12-28 18:40 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, Reshma Pattan

In order exercise more logic in pcapng, vary the size
of the packets.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 app/test/test_pcapng.c | 94 +++++++++++++++++++++++++++++-------------
 1 file changed, 65 insertions(+), 29 deletions(-)

diff --git a/app/test/test_pcapng.c b/app/test/test_pcapng.c
index f2b49c31c7..5010355df5 100644
--- a/app/test/test_pcapng.c
+++ b/app/test/test_pcapng.c
@@ -28,10 +28,9 @@
 #define TOTAL_PACKETS	4096
 #define MAX_BURST	64
 #define MAX_GAP_US	100000
-#define DUMMY_MBUF_NUM	3
+#define DUMMY_MBUF_NUM	2
 
 static struct rte_mempool *mp;
-static const uint32_t pkt_len = 200;
 static uint16_t port_id;
 static const char null_dev[] = "net_null0";
 
@@ -41,13 +40,36 @@ struct dummy_mbuf {
 	uint8_t buf[DUMMY_MBUF_NUM][RTE_MBUF_DEFAULT_BUF_SIZE];
 };
 
+#define MAX_DATA_SIZE (RTE_MBUF_DEFAULT_BUF_SIZE - RTE_PKTMBUF_HEADROOM)
+
+/* RFC 864 chargen pattern used for comment testing */
+#define FILL_LINE_LENGTH 72
+#define FILL_START	0x21 /* ! */
+#define FILL_END	0x7e /* ~ */
+#define FILL_RANGE	(FILL_END - FILL_START)
+
 static void
-dummy_mbuf_prep(struct rte_mbuf *mb, uint8_t buf[], uint32_t buf_len,
-	uint32_t data_len)
+fill_mbuf(struct rte_mbuf *mb)
 {
-	uint32_t i;
-	uint8_t *db;
+	unsigned int len = rte_pktmbuf_tailroom(mb);
+	char *buf = rte_pktmbuf_append(mb, len);
+	unsigned int n = 0;
+
+	while (n < len - 1) {
+		char ch = FILL_START + (n % FILL_LINE_LENGTH) % FILL_RANGE;
+		for (unsigned int i = 0; i < FILL_LINE_LENGTH && n < len - 1; i++) {
+			buf[n++] = ch;
+			if (++ch == FILL_END)
+				ch = FILL_START;
+		}
+		if (n < len - 1)
+			buf[n++] = '\n';
+	}
+}
 
+static void
+dummy_mbuf_prep(struct rte_mbuf *mb, uint8_t buf[], uint32_t buf_len)
+{
 	mb->buf_addr = buf;
 	rte_mbuf_iova_set(mb, (uintptr_t)buf);
 	mb->buf_len = buf_len;
@@ -57,15 +79,11 @@ dummy_mbuf_prep(struct rte_mbuf *mb, uint8_t buf[], uint32_t buf_len,
 	mb->pool = (void *)buf;
 
 	rte_pktmbuf_reset(mb);
-	db = (uint8_t *)rte_pktmbuf_append(mb, data_len);
-
-	for (i = 0; i != data_len; i++)
-		db[i] = i;
 }
 
 /* Make an IP packet consisting of chain of one packets */
 static void
-mbuf1_prepare(struct dummy_mbuf *dm, uint32_t plen)
+mbuf1_prepare(struct dummy_mbuf *dm)
 {
 	struct {
 		struct rte_ether_hdr eth;
@@ -84,32 +102,47 @@ mbuf1_prepare(struct dummy_mbuf *dm, uint32_t plen)
 			.dst_addr = rte_cpu_to_be_32(RTE_IPV4_BROADCAST),
 		},
 		.udp = {
+			.src_port = rte_cpu_to_be_16(19), /* Chargen port */
 			.dst_port = rte_cpu_to_be_16(9), /* Discard port */
 		},
 	};
 
 	memset(dm, 0, sizeof(*dm));
-	dummy_mbuf_prep(&dm->mb[0], dm->buf[0], sizeof(dm->buf[0]), plen);
+	dummy_mbuf_prep(&dm->mb[0], dm->buf[0], sizeof(dm->buf[0]));
+	dummy_mbuf_prep(&dm->mb[1], dm->buf[1], sizeof(dm->buf[1]));
 
 	rte_eth_random_addr(pkt.eth.src_addr.addr_bytes);
-	plen -= sizeof(struct rte_ether_hdr);
+	memcpy(rte_pktmbuf_append(&dm->mb[0], sizeof(pkt)), &pkt, sizeof(pkt));
+
+	fill_mbuf(&dm->mb[1]);
+	rte_pktmbuf_chain(&dm->mb[0], &dm->mb[1]);
+
+	rte_mbuf_sanity_check(&dm->mb[0], 1);
+	rte_mbuf_sanity_check(&dm->mb[1], 0);
+}
 
-	pkt.ip.total_length = rte_cpu_to_be_16(plen);
-	pkt.ip.hdr_checksum = rte_ipv4_cksum(&pkt.ip);
+static void
+mbuf1_resize(struct dummy_mbuf *dm, uint16_t len)
+{
+	struct {
+		struct rte_ether_hdr eth;
+		struct rte_ipv4_hdr ip;
+		struct rte_udp_hdr udp;
+	} *pkt = rte_pktmbuf_mtod(&dm->mb[0], void *);
 
-	plen -= sizeof(struct rte_ipv4_hdr);
-	pkt.udp.src_port = rte_rand();
-	pkt.udp.dgram_len = rte_cpu_to_be_16(plen);
+	dm->mb[1].data_len = len;
+	dm->mb[0].pkt_len = dm->mb[0].data_len + dm->mb[1].data_len;
 
-	memcpy(rte_pktmbuf_mtod(dm->mb, void *), &pkt, sizeof(pkt));
+	len += sizeof(struct rte_udp_hdr);
+	pkt->udp.dgram_len = rte_cpu_to_be_16(len);
 
-	/* Idea here is to create mbuf chain big enough that after mbuf deep copy they won't be
-	 * compressed into single mbuf to properly test store of chained mbufs
-	 */
-	dummy_mbuf_prep(&dm->mb[1], dm->buf[1], sizeof(dm->buf[1]), pkt_len);
-	dummy_mbuf_prep(&dm->mb[2], dm->buf[2], sizeof(dm->buf[2]), pkt_len);
-	rte_pktmbuf_chain(&dm->mb[0], &dm->mb[1]);
-	rte_pktmbuf_chain(&dm->mb[0], &dm->mb[2]);
+	len += sizeof(struct rte_ipv4_hdr);
+	pkt->ip.total_length = rte_cpu_to_be_16(len);
+	pkt->ip.hdr_checksum = 0;
+	pkt->ip.hdr_checksum = rte_ipv4_cksum(&pkt->ip);
+
+	rte_mbuf_sanity_check(&dm->mb[0], 1);
+	rte_mbuf_sanity_check(&dm->mb[1], 0);
 }
 
 static int
@@ -125,7 +158,8 @@ test_setup(void)
 
 	/* Make a pool for cloned packets */
 	mp = rte_pktmbuf_pool_create_by_ops("pcapng_test_pool",
-					    MAX_BURST * 32, 0, 0, rte_pcapng_mbuf_size(pkt_len),
+					    MAX_BURST * 32, 0, 0,
+					    rte_pcapng_mbuf_size(MAX_DATA_SIZE),
 					    SOCKET_ID_ANY, "ring_mp_sc");
 	if (mp == NULL) {
 		fprintf(stderr, "Cannot create mempool\n");
@@ -156,8 +190,7 @@ fill_pcapng_file(rte_pcapng_t *pcapng, unsigned int num_packets)
 		"Lockless and fearless — that’s how we roll in userspace."
 	};
 
-	/* make a dummy packet */
-	mbuf1_prepare(&mbfs, pkt_len);
+	mbuf1_prepare(&mbfs);
 	orig  = &mbfs.mb[0];
 
 	for (count = 0; count < num_packets; count += burst_size) {
@@ -174,6 +207,9 @@ fill_pcapng_file(rte_pcapng_t *pcapng, unsigned int num_packets)
 			if ((count + i) % 42 == 0)
 				comment = examples[rte_rand_max(RTE_DIM(examples))];
 
+			/* Vary the size of the packets */
+			mbuf1_resize(&mbfs, rte_rand_max(MAX_DATA_SIZE));
+
 			mc = rte_pcapng_copy(port_id, 0, orig, mp, rte_pktmbuf_pkt_len(orig),
 					     RTE_PCAPNG_DIRECTION_IN, comment);
 			if (mc == NULL) {
-- 
2.51.0


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

* [PATCH 5/7] net/bnxt: fix uninitialized warning
  2025-12-28 18:40 [PATCH 0/7] Fix build with gcc-16 Stephen Hemminger
                   ` (3 preceding siblings ...)
  2025-12-28 18:40 ` [PATCH 4/7] test: vary size of packets in pcapng test Stephen Hemminger
@ 2025-12-28 18:40 ` Stephen Hemminger
  2025-12-28 18:40 ` [PATCH 6/7] common/cnxk: fix array out of bounds Stephen Hemminger
  2025-12-28 18:40 ` [PATCH 7/7] examples/fips_validation: avoid rte_memcpy alignment restriction Stephen Hemminger
  6 siblings, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2025-12-28 18:40 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, stable, Ajit Khaparde, Somnath Kotur,
	Kishore Padmanabha, Venkat Duvvuru, Mike Baucom

With gcc-16 it inlines a lot more code and creates a warnings
where it thinks it might be manipulating bits that are not set.
It looks like this is because the bits in control word (cword)
in theory could be larger than the variable. Should not
be possible because wc_ctl_size_bits is only set to 3, 16, or 32
but that happens outside of the scope of these functions.

Resolve by adding bounds check which compiler sees and knows
the loop will only see those bits.

In function ‘ulp_bs_push_msb’,
    inlined from ‘ulp_blob_push’ at ../drivers/net/bnxt/tf_ulp/ulp_utils.h:407:8,
    inlined from ‘ulp_blob_push_32’ at ../drivers/net/bnxt/tf_ulp/ulp_utils.h:551:7,
    inlined from ‘ulp_mapper_wc_tcam_tbl_dyn_post_process’ at ../drivers/net/bnxt/tf_ulp/ulp_mapper.c:2487:9:
../drivers/net/bnxt/tf_ulp/ulp_utils.h:336:17: warning: ‘cword’ may be used uninitialized [-Wmaybe-uninitialized]
  336 |                 ulp_bs_put_msb(bs, pos, 8, val[i]);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../drivers/net/bnxt/tf_ulp/ulp_mapper.c: In function ‘ulp_mapper_wc_tcam_tbl_dyn_post_process’:
../drivers/net/bnxt/tf_ulp/ulp_mapper.c:2443:18: note: ‘cword’ declared here
 2443 |         uint32_t cword, i, rc;
      |                  ^~~~~

Bugzilla ID: 1821
Fixes: 3fe124d2536c ("net/bnxt: support Thor platform")
Cc: stable@dpdk.org

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/net/bnxt/tf_ulp/ulp_mapper.c     | 5 +++++
 drivers/net/bnxt/tf_ulp/ulp_mapper_tfc.c | 4 ++++
 2 files changed, 9 insertions(+)

diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper.c b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
index 0ff952950b..960cdda311 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper.c
@@ -2446,6 +2446,11 @@ ulp_mapper_wc_tcam_tbl_dyn_post_process(struct bnxt_ulp_device_params *dparms,
 
 	slice_width = dparms->wc_slice_width;
 	clen = dparms->wc_ctl_size_bits;
+	if (clen > 32) {
+		BNXT_DRV_DBG(ERR, "Key size bits %d too large\n", clen);
+		return -EINVAL;
+	}
+
 	max_slices = dparms->wc_max_slices;
 	blen = ulp_blob_data_len_get(key);
 
diff --git a/drivers/net/bnxt/tf_ulp/ulp_mapper_tfc.c b/drivers/net/bnxt/tf_ulp/ulp_mapper_tfc.c
index f99698a1d8..2d89f10d5e 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_mapper_tfc.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_mapper_tfc.c
@@ -90,6 +90,10 @@ ulp_mapper_tfc_wc_tcam_post_process(struct bnxt_ulp_device_params *dparms,
 
 	slice_width = dparms->wc_slice_width;
 	clen = dparms->wc_ctl_size_bits;
+	if (clen > 32) {
+		BNXT_DRV_DBG(ERR, "Key size bits %d too large\n", clen);
+		return -EINVAL;
+	}
 	max_slices = dparms->wc_max_slices;
 	blen = ulp_blob_data_len_get(key);
 
-- 
2.51.0


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

* [PATCH 6/7] common/cnxk: fix array out of bounds
  2025-12-28 18:40 [PATCH 0/7] Fix build with gcc-16 Stephen Hemminger
                   ` (4 preceding siblings ...)
  2025-12-28 18:40 ` [PATCH 5/7] net/bnxt: fix uninitialized warning Stephen Hemminger
@ 2025-12-28 18:40 ` Stephen Hemminger
  2025-12-28 18:40 ` [PATCH 7/7] examples/fips_validation: avoid rte_memcpy alignment restriction Stephen Hemminger
  6 siblings, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2025-12-28 18:40 UTC (permalink / raw)
  To: dev
  Cc: Stephen Hemminger, vattunuru, Nithin Dabilpuram, Kiran Kumar K,
	Sunil Kumar Kori, Satha Rao, Harman Kalra, Jerin Jacob

Gcc-16 detects out of bounds reference in this code.
In function ‘nix_inl_selftest_work_cb’,
    inlined from ‘inl_outb_soft_exp_poll’ at ../drivers/common/cnxk/roc_nix_inl_dev.c:1173:4,
    inlined from ‘nix_inl_outb_poll_thread’ at ../drivers/common/cnxk/roc_nix_inl_dev.c:1201:6:
../drivers/common/cnxk/roc_nix_inl_dev.c:43:19: warning: array subscript 1 is outside array bounds of ‘uint64_t[1]’ {aka ‘long unsigned int[1]’} [-Warray-bounds=]
   43 |         uintptr_t work = gw[1];
      |                   ^~~~
../drivers/common/cnxk/roc_nix_inl_dev.c: In function ‘nix_inl_outb_poll_thread’:
../drivers/common/cnxk/roc_nix_inl_dev.c:1172:34: note: at offset 8 into object ‘tmp’ of size 8
 1172 |                         uint64_t tmp = ~(uint32_t)0x0;
      |                                  ^~~

Fixes: bea5d990a93b ("net/cnxk: support outbound soft expiry notification")
Cc: vattunuru@marvell.com
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 drivers/common/cnxk/roc_nix_inl_dev.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/common/cnxk/roc_nix_inl_dev.c b/drivers/common/cnxk/roc_nix_inl_dev.c
index 1eb96f913a..3a4f1ac1e7 100644
--- a/drivers/common/cnxk/roc_nix_inl_dev.c
+++ b/drivers/common/cnxk/roc_nix_inl_dev.c
@@ -1169,12 +1169,10 @@ inl_outb_soft_exp_poll(struct nix_inl_dev *inl_dev, uint32_t ring_idx)
 						     (entry.s.data0 << 7));
 
 		if (sa != NULL) {
-			uint64_t tmp = ~(uint32_t)0x0;
-			inl_dev->work_cb(&tmp, sa, NIX_INL_SOFT_EXPIRY_THRD, NULL, port_id);
-			__atomic_store_n(ring_base + tail_l + 1, 0ULL,
-					 __ATOMIC_RELAXED);
-			__atomic_fetch_add((uint32_t *)ring_base, 1,
-					   __ATOMIC_ACQ_REL);
+			uint64_t tmp[2];
+			inl_dev->work_cb(tmp, sa, NIX_INL_SOFT_EXPIRY_THRD, NULL, port_id);
+			__atomic_store_n(ring_base + tail_l + 1, 0ULL, __ATOMIC_RELAXED);
+			__atomic_fetch_add((uint32_t *)ring_base, 1, __ATOMIC_ACQ_REL);
 		} else
 			plt_err("Invalid SA");
 
-- 
2.51.0


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

* [PATCH 7/7] examples/fips_validation: avoid rte_memcpy alignment restriction
  2025-12-28 18:40 [PATCH 0/7] Fix build with gcc-16 Stephen Hemminger
                   ` (5 preceding siblings ...)
  2025-12-28 18:40 ` [PATCH 6/7] common/cnxk: fix array out of bounds Stephen Hemminger
@ 2025-12-28 18:40 ` Stephen Hemminger
  6 siblings, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2025-12-28 18:40 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, gmuthukrishn

The code for copying example hash key values was calling rte_memcpy
but rte_memcpy has alignment problems with this size which causes:

In function ‘get_hash_oid’,
    inlined from ‘prepare_rsa_xform’ at ../examples/fips_validation/main.c:1607:12:
../examples/fips_validation/main.c:890:20: warning: array subscript ‘__m128i_u[0]’ is partly outside array bounds of ‘uint8_t[15]’ {aka ‘unsigned char[15]’} [-Warray-bounds=]
  890 |                 id = id_sha1;
      |                 ~~~^~~~~~~~~
../examples/fips_validation/main.c: In function ‘prepare_rsa_xform’:
../examples/fips_validation/main.c:882:17: note: object ‘id_sha1’ of size 15
  882 |         uint8_t id_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05,

There is no reason to use rte_memcpy() in these examples.

Fixes: ae5ae3bf5996 ("examples/fips_validation: encode digest with hash OID")
Cc: gmuthukrishn@marvell.com

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 examples/fips_validation/#main.c# | 3082 +++++++++++++++++++++++++++++
 examples/fips_validation/main.c   |   14 +-
 2 files changed, 3088 insertions(+), 8 deletions(-)
 create mode 100644 examples/fips_validation/#main.c#

diff --git a/examples/fips_validation/#main.c# b/examples/fips_validation/#main.c#
new file mode 100644
index 0000000000..1eb6593db1
--- /dev/null
+++ b/examples/fips_validation/#main.c#
@@ -0,0 +1,3082 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#include <sys/stat.h>
+#include <getopt.h>
+#include <dirent.h>
+#include <stdlib.h>
+
+#include <rte_cryptodev.h>
+#include <rte_malloc.h>
+#include <rte_mempool.h>
+#include <rte_mbuf.h>
+#include <rte_string_fns.h>
+#include <rte_random.h>
+
+#include "fips_validation.h"
+#include "fips_dev_self_test.h"
+
+enum {
+#define OPT_REQ_FILE_PATH           "req-file"
+	OPT_REQ_FILE_PATH_NUM = 256,
+#define OPT_RSP_FILE_PATH           "rsp-file"
+	OPT_RSP_FILE_PATH_NUM,
+#define OPT_MBUF_DATAROOM           "mbuf-dataroom"
+	OPT_MBUF_DATAROOM_NUM,
+#define OPT_FOLDER                  "path-is-folder"
+	OPT_FOLDER_NUM,
+#define OPT_CRYPTODEV               "cryptodev"
+	OPT_CRYPTODEV_NUM,
+#define OPT_CRYPTODEV_ID            "cryptodev-id"
+	OPT_CRYPTODEV_ID_NUM,
+#define OPT_CRYPTODEV_ST            "self-test"
+	OPT_CRYPTODEV_ST_NUM,
+#define OPT_CRYPTODEV_BK_ID         "broken-test-id"
+	OPT_CRYPTODEV_BK_ID_NUM,
+#define OPT_CRYPTODEV_BK_DIR_KEY    "broken-test-dir"
+	OPT_CRYPTODEV_BK_DIR_KEY_NUM,
+#define OPT_USE_JSON                "use-json"
+	OPT_USE_JSON_NUM,
+#define OPT_CRYPTODEV_ASYM          "asymmetric"
+	OPT_CRYPTODEV_ASYM_NUM,
+};
+
+struct fips_test_vector vec;
+struct fips_test_interim_info info;
+
+#ifdef USE_JANSSON
+struct fips_test_json_info json_info;
+#endif /* USE_JANSSON */
+
+struct cryptodev_fips_validate_env {
+	const char *req_path;
+	const char *rsp_path;
+	uint32_t is_path_folder;
+	uint8_t dev_id;
+	struct rte_mempool *mpool;
+	struct fips_sym_env {
+		struct rte_mempool *sess_mpool;
+		struct rte_mempool *op_pool;
+		struct rte_cryptodev_sym_session *sess;
+		struct rte_crypto_op *op;
+	} sym;
+	struct fips_asym_env {
+		struct rte_mempool *sess_mpool;
+		struct rte_mempool *op_pool;
+		struct rte_cryptodev_asym_session *sess;
+		struct rte_crypto_op *op;
+	} asym;
+	struct rte_crypto_op *op;
+	uint8_t dev_support_sgl;
+	uint16_t mbuf_data_room;
+	struct rte_mbuf *mbuf;
+	uint8_t *digest;
+	uint16_t digest_len;
+	bool is_asym_test;
+	uint16_t self_test;
+	struct fips_dev_broken_test_config *broken_test_config;
+} env;
+
+static int
+cryptodev_fips_validate_app_sym_init(void)
+{
+	uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size(
+							env.dev_id);
+	struct rte_cryptodev_info dev_info;
+	struct fips_sym_env *sym = &env.sym;
+	int ret;
+
+	rte_cryptodev_info_get(env.dev_id, &dev_info);
+	if (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)
+		env.dev_support_sgl = 1;
+	else
+		env.dev_support_sgl = 0;
+
+	ret = -ENOMEM;
+	sym->sess_mpool = rte_cryptodev_sym_session_pool_create(
+			"FIPS_SYM_SESS_MEMPOOL", 16, sess_sz, 0, 0, rte_socket_id());
+	if (!sym->sess_mpool)
+		goto error_exit;
+
+	sym->op_pool = rte_crypto_op_pool_create(
+			"FIPS_OP_SYM_POOL",
+			RTE_CRYPTO_OP_TYPE_SYMMETRIC,
+			1, 0,
+			16,
+			rte_socket_id());
+	if (!sym->op_pool)
+		goto error_exit;
+
+	sym->op = rte_crypto_op_alloc(sym->op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+	if (!sym->op)
+		goto error_exit;
+
+	return 0;
+
+error_exit:
+	rte_mempool_free(sym->sess_mpool);
+	rte_mempool_free(sym->op_pool);
+	return ret;
+}
+
+static void
+cryptodev_fips_validate_app_sym_uninit(void)
+{
+	struct fips_sym_env *sym = &env.sym;
+
+	rte_pktmbuf_free(env.mbuf);
+	rte_crypto_op_free(sym->op);
+	rte_cryptodev_sym_session_free(env.dev_id, sym->sess);
+	rte_mempool_free(sym->sess_mpool);
+	rte_mempool_free(sym->op_pool);
+}
+
+static int
+cryptodev_fips_validate_app_asym_init(void)
+{
+	struct fips_asym_env *asym = &env.asym;
+	int ret;
+
+	ret = -ENOMEM;
+	asym->sess_mpool = rte_cryptodev_asym_session_pool_create(
+			"FIPS_ASYM_SESS_MEMPOOL", 16, 0, 0, rte_socket_id());
+	if (!asym->sess_mpool)
+		goto error_exit;
+
+	asym->op_pool = rte_crypto_op_pool_create(
+			"FIPS_OP_ASYM_POOL",
+			RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
+			1, 0,
+			16,
+			rte_socket_id());
+	if (!asym->op_pool)
+		goto error_exit;
+
+	asym->op = rte_crypto_op_alloc(asym->op_pool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+	if (!asym->op)
+		goto error_exit;
+
+	return 0;
+
+error_exit:
+	rte_mempool_free(asym->sess_mpool);
+	rte_mempool_free(asym->op_pool);
+	return ret;
+}
+
+static void
+cryptodev_fips_validate_app_asym_uninit(void)
+{
+	struct fips_asym_env *asym = &env.asym;
+
+	rte_crypto_op_free(asym->op);
+	rte_cryptodev_asym_session_free(env.dev_id, asym->sess);
+	rte_mempool_free(asym->sess_mpool);
+	rte_mempool_free(asym->op_pool);
+}
+
+static int
+cryptodev_fips_validate_app_init(void)
+{
+	struct rte_cryptodev_config conf = {rte_socket_id(), 1, 0};
+	struct rte_cryptodev_qp_conf qp_conf = {128, NULL};
+	uint32_t nb_mbufs = UINT16_MAX / env.mbuf_data_room + 1;
+	int ret;
+
+	if (env.self_test) {
+		ret = fips_dev_self_test(env.dev_id, env.broken_test_config);
+		if (ret < 0) {
+			rte_cryptodev_stop(env.dev_id);
+			rte_cryptodev_close(env.dev_id);
+
+			return ret;
+		}
+	}
+
+	ret = rte_cryptodev_configure(env.dev_id, &conf);
+	if (ret < 0)
+		return ret;
+
+	ret = -ENOMEM;
+	env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", nb_mbufs,
+			0, 0, sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM +
+			env.mbuf_data_room, rte_socket_id());
+	if (!env.mpool)
+		return ret;
+
+	ret = cryptodev_fips_validate_app_sym_init();
+	if (ret < 0)
+		goto error_exit;
+
+	if (env.is_asym_test) {
+		ret = cryptodev_fips_validate_app_asym_init();
+		if (ret < 0)
+			goto error_exit;
+	}
+
+	qp_conf.mp_session = env.sym.sess_mpool;
+
+	ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
+			rte_socket_id());
+	if (ret < 0)
+		goto error_exit;
+
+	ret = rte_cryptodev_start(env.dev_id);
+	if (ret < 0)
+		goto error_exit;
+
+	return 0;
+
+error_exit:
+	rte_mempool_free(env.mpool);
+	return ret;
+}
+
+static void
+cryptodev_fips_validate_app_uninit(void)
+{
+	cryptodev_fips_validate_app_sym_uninit();
+
+	if (env.is_asym_test)
+		cryptodev_fips_validate_app_asym_uninit();
+
+	rte_mempool_free(env.mpool);
+	rte_cryptodev_stop(env.dev_id);
+	rte_cryptodev_close(env.dev_id);
+}
+
+static int
+fips_test_one_file(void);
+
+#ifdef USE_JANSSON
+static int
+fips_test_one_json_file(void);
+#endif /* USE_JANSSON */
+
+static int
+parse_cryptodev_arg(char *arg)
+{
+	int id = rte_cryptodev_get_dev_id(arg);
+
+	if (id < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev name %s\n",
+				id, arg);
+		return id;
+	}
+
+	env.dev_id = (uint8_t)id;
+
+	return 0;
+}
+
+static int
+parse_cryptodev_id_arg(char *arg)
+{
+	uint32_t cryptodev_id;
+
+	if (parser_read_uint32(&cryptodev_id, arg) < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n",
+				-EINVAL, arg);
+		return -1;
+	}
+
+
+	if (!rte_cryptodev_is_valid_dev(cryptodev_id)) {
+		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n",
+				cryptodev_id, arg);
+		return -1;
+	}
+
+	env.dev_id = (uint8_t)cryptodev_id;
+
+	return 0;
+}
+
+static void
+cryptodev_fips_validate_usage(const char *prgname)
+{
+	uint32_t def_mbuf_seg_size = DEF_MBUF_SEG_SIZE;
+	printf("%s [EAL options] --\n"
+		"  --%s: REQUEST-FILE-PATH\n"
+		"  --%s: RESPONSE-FILE-PATH\n"
+		"  --%s: indicating both paths are folders\n"
+		"  --%s: mbuf dataroom size (default %u bytes)\n"
+		"  --%s: CRYPTODEV-NAME\n"
+		"  --%s: CRYPTODEV-ID-NAME\n"
+		"  --%s: self test indicator\n"
+		"  --%s: self broken test ID\n"
+		"  --%s: self broken test direction\n",
+		prgname, OPT_REQ_FILE_PATH, OPT_RSP_FILE_PATH,
+		OPT_FOLDER, OPT_MBUF_DATAROOM, def_mbuf_seg_size,
+		OPT_CRYPTODEV, OPT_CRYPTODEV_ID, OPT_CRYPTODEV_ST,
+		OPT_CRYPTODEV_BK_ID, OPT_CRYPTODEV_BK_DIR_KEY);
+}
+
+static int
+cryptodev_fips_validate_parse_args(int argc, char **argv)
+{
+	int opt, ret;
+	char *prgname = argv[0];
+	char **argvopt;
+	int option_index;
+	struct option lgopts[] = {
+		{OPT_REQ_FILE_PATH, required_argument,
+				NULL, OPT_REQ_FILE_PATH_NUM},
+		{OPT_RSP_FILE_PATH, required_argument,
+				NULL, OPT_RSP_FILE_PATH_NUM},
+		{OPT_FOLDER, no_argument,
+				NULL, OPT_FOLDER_NUM},
+		{OPT_MBUF_DATAROOM, required_argument,
+				NULL, OPT_MBUF_DATAROOM_NUM},
+		{OPT_CRYPTODEV, required_argument,
+				NULL, OPT_CRYPTODEV_NUM},
+		{OPT_CRYPTODEV_ID, required_argument,
+				NULL, OPT_CRYPTODEV_ID_NUM},
+		{OPT_CRYPTODEV_ST, no_argument,
+				NULL, OPT_CRYPTODEV_ST_NUM},
+		{OPT_CRYPTODEV_BK_ID, required_argument,
+				NULL, OPT_CRYPTODEV_BK_ID_NUM},
+		{OPT_CRYPTODEV_BK_DIR_KEY, required_argument,
+				NULL, OPT_CRYPTODEV_BK_DIR_KEY_NUM},
+		{OPT_CRYPTODEV_ASYM, no_argument,
+				NULL, OPT_CRYPTODEV_ASYM_NUM},
+		{NULL, 0, 0, 0}
+	};
+
+	argvopt = argv;
+
+	env.mbuf_data_room = DEF_MBUF_SEG_SIZE;
+	if (rte_cryptodev_count())
+		env.dev_id = 0;
+	else {
+		cryptodev_fips_validate_usage(prgname);
+		return -EINVAL;
+	}
+
+	while ((opt = getopt_long(argc, argvopt, "s:",
+				  lgopts, &option_index)) != EOF) {
+
+		switch (opt) {
+		case OPT_REQ_FILE_PATH_NUM:
+			env.req_path = optarg;
+			break;
+
+		case OPT_RSP_FILE_PATH_NUM:
+			env.rsp_path = optarg;
+			break;
+
+		case OPT_FOLDER_NUM:
+			env.is_path_folder = 1;
+			break;
+
+		case OPT_CRYPTODEV_NUM:
+			ret = parse_cryptodev_arg(optarg);
+			if (ret < 0) {
+				cryptodev_fips_validate_usage(prgname);
+				return -EINVAL;
+			}
+			break;
+
+		case OPT_CRYPTODEV_ID_NUM:
+			ret = parse_cryptodev_id_arg(optarg);
+			if (ret < 0) {
+				cryptodev_fips_validate_usage(prgname);
+				return -EINVAL;
+			}
+			break;
+
+		case OPT_CRYPTODEV_ST_NUM:
+			env.self_test = 1;
+			break;
+
+		case OPT_CRYPTODEV_BK_ID_NUM:
+			if (!env.broken_test_config) {
+				env.broken_test_config = rte_malloc(
+					NULL,
+					sizeof(*env.broken_test_config),
+					0);
+				if (!env.broken_test_config)
+					return -ENOMEM;
+
+				env.broken_test_config->expect_fail_dir =
+					self_test_dir_enc_auth_gen;
+			}
+
+			if (parser_read_uint32(
+				&env.broken_test_config->expect_fail_test_idx,
+					optarg) < 0) {
+				rte_free(env.broken_test_config);
+				cryptodev_fips_validate_usage(prgname);
+				return -EINVAL;
+			}
+			break;
+
+		case OPT_CRYPTODEV_BK_DIR_KEY_NUM:
+			if (!env.broken_test_config) {
+				env.broken_test_config = rte_malloc(
+					NULL,
+					sizeof(*env.broken_test_config),
+					0);
+				if (!env.broken_test_config)
+					return -ENOMEM;
+
+				env.broken_test_config->expect_fail_test_idx =
+					0;
+			}
+
+			if (strcmp(optarg, "enc") == 0)
+				env.broken_test_config->expect_fail_dir =
+					self_test_dir_enc_auth_gen;
+			else if (strcmp(optarg, "dec")
+					== 0)
+				env.broken_test_config->expect_fail_dir =
+					self_test_dir_dec_auth_verify;
+			else {
+				rte_free(env.broken_test_config);
+				cryptodev_fips_validate_usage(prgname);
+				return -EINVAL;
+			}
+			break;
+
+
+		case OPT_MBUF_DATAROOM_NUM:
+			if (parser_read_uint16(&env.mbuf_data_room,
+					optarg) < 0) {
+				cryptodev_fips_validate_usage(prgname);
+				return -EINVAL;
+			}
+
+			if (env.mbuf_data_room == 0) {
+				cryptodev_fips_validate_usage(prgname);
+				return -EINVAL;
+			}
+			break;
+
+		case OPT_CRYPTODEV_ASYM_NUM:
+			env.is_asym_test = true;
+			break;
+
+		default:
+			cryptodev_fips_validate_usage(prgname);
+			return -EINVAL;
+		}
+	}
+
+	if ((env.req_path == NULL && env.rsp_path != NULL) ||
+			(env.req_path != NULL && env.rsp_path == NULL)) {
+		RTE_LOG(ERR, USER1, "Missing req path or rsp path\n");
+		cryptodev_fips_validate_usage(prgname);
+		return -EINVAL;
+	}
+
+	if (env.req_path == NULL && env.self_test == 0) {
+		RTE_LOG(ERR, USER1, "--self-test must be set if req path is missing\n");
+		cryptodev_fips_validate_usage(prgname);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+	int ret;
+
+	ret = rte_eal_init(argc, argv);
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret);
+		return -1;
+	}
+
+	argc -= ret;
+	argv += ret;
+
+	ret = cryptodev_fips_validate_parse_args(argc, argv);
+	if (ret < 0)
+		rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n");
+
+	ret = cryptodev_fips_validate_app_init();
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret);
+		return -1;
+	}
+
+	if (env.req_path == NULL || env.rsp_path == NULL) {
+		printf("No request, exit.\n");
+		goto exit;
+	}
+
+	if (!env.is_path_folder) {
+		printf("Processing file %s... ", env.req_path);
+
+		ret = fips_test_init(env.req_path, env.rsp_path,
+			rte_cryptodev_name_get(env.dev_id));
+		if (ret < 0) {
+			RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
+					ret, env.req_path);
+			goto exit;
+		}
+
+#ifdef USE_JANSSON
+		if (info.file_type == FIPS_TYPE_JSON) {
+			ret = fips_test_one_json_file();
+			json_decref(json_info.json_root);
+		}  else {
+			ret = fips_test_one_file();
+		}
+#else /* USE_JANSSON */
+		ret = fips_test_one_file();
+#endif /* USE_JANSSON */
+
+		if (ret < 0) {
+			RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
+					ret, env.req_path);
+			goto exit;
+		}
+
+		printf("Done\n");
+
+	} else {
+		struct dirent *dir;
+		DIR *d_req, *d_rsp;
+		char req_path[1024];
+		char rsp_path[1024];
+
+		d_req = opendir(env.req_path);
+		if (!d_req) {
+			RTE_LOG(ERR, USER1, "Error %i: Path %s not exist\n",
+					-EINVAL, env.req_path);
+			goto exit;
+		}
+
+		d_rsp = opendir(env.rsp_path);
+		if (!d_rsp) {
+			ret = mkdir(env.rsp_path, 0700);
+			if (ret == 0)
+				d_rsp = opendir(env.rsp_path);
+			else {
+				RTE_LOG(ERR, USER1, "Error %i: Invalid %s\n",
+						-EINVAL, env.rsp_path);
+				goto exit;
+			}
+		}
+		closedir(d_rsp);
+
+		while ((dir = readdir(d_req)) != NULL) {
+			if (strstr(dir->d_name, "req") == NULL)
+				continue;
+
+			snprintf(req_path, 1023, "%s/%s", env.req_path,
+					dir->d_name);
+			snprintf(rsp_path, 1023, "%s/%s", env.rsp_path,
+					dir->d_name);
+			strlcpy(strstr(rsp_path, "req"), "rsp", 4);
+
+			printf("Processing file %s... ", req_path);
+
+			ret = fips_test_init(req_path, rsp_path,
+			rte_cryptodev_name_get(env.dev_id));
+			if (ret < 0) {
+				RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
+						ret, req_path);
+				break;
+			}
+
+#ifdef USE_JANSSON
+			if (info.file_type == FIPS_TYPE_JSON) {
+				ret = fips_test_one_json_file();
+				json_decref(json_info.json_root);
+			} else {
+				ret = fips_test_one_file();
+			}
+#else /* USE_JANSSON */
+			ret = fips_test_one_file();
+#endif /* USE_JANSSON */
+
+			if (ret < 0) {
+				RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
+						ret, req_path);
+				break;
+			}
+
+			printf("Done\n");
+		}
+
+		closedir(d_req);
+	}
+
+
+exit:
+	fips_test_clear();
+	cryptodev_fips_validate_app_uninit();
+
+	/* clean up the EAL */
+	rte_eal_cleanup();
+
+	return ret;
+
+}
+
+#define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
+#define CRYPTODEV_FIPS_MAX_RETRIES	16
+
+struct fips_test_ops test_ops;
+
+static int
+prepare_data_mbufs(struct fips_val *val)
+{
+	struct rte_mbuf *m, *head = 0;
+	uint8_t *src = val->val;
+	uint32_t total_len = val->len;
+	uint16_t nb_seg;
+	int ret = 0;
+
+	rte_pktmbuf_free(env.mbuf);
+
+	if (total_len > RTE_MBUF_MAX_NB_SEGS) {
+		RTE_LOG(ERR, USER1, "Data len %u too big\n", total_len);
+		return -EPERM;
+	}
+
+	nb_seg = total_len / env.mbuf_data_room;
+	if (total_len % env.mbuf_data_room)
+		nb_seg++;
+
+	m = rte_pktmbuf_alloc(env.mpool);
+	if (!m) {
+		RTE_LOG(ERR, USER1, "Error %i: Not enough mbuf\n",
+				-ENOMEM);
+		return -ENOMEM;
+	}
+	head = m;
+
+	while (nb_seg) {
+		uint16_t len = RTE_MIN(total_len, env.mbuf_data_room);
+		uint8_t *dst = (uint8_t *)rte_pktmbuf_append(m, len);
+
+		if (!dst) {
+			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
+					-ENOMEM);
+			ret = -ENOMEM;
+			goto error_exit;
+		}
+
+		memcpy(dst, src, len);
+
+		if (head != m) {
+			ret = rte_pktmbuf_chain(head, m);
+			if (ret) {
+				rte_pktmbuf_free(m);
+				RTE_LOG(ERR, USER1, "Error %i: SGL build\n",
+						ret);
+				goto error_exit;
+			}
+		}
+		total_len -= len;
+
+		if (total_len) {
+			if (!env.dev_support_sgl) {
+				RTE_LOG(ERR, USER1, "SGL not supported\n");
+				ret = -EPERM;
+				goto error_exit;
+			}
+
+			m = rte_pktmbuf_alloc(env.mpool);
+			if (!m) {
+				RTE_LOG(ERR, USER1, "Error %i: No memory\n",
+						-ENOMEM);
+				goto error_exit;
+			}
+		} else
+			break;
+
+		src += len;
+		nb_seg--;
+	}
+
+	if (total_len) {
+		RTE_LOG(ERR, USER1, "Error %i: Failed to store all data\n",
+				-ENOMEM);
+		goto error_exit;
+	}
+
+	env.mbuf = head;
+
+	return 0;
+
+error_exit:
+	rte_pktmbuf_free(head);
+	return ret;
+}
+
+static int
+prepare_cipher_op(void)
+{
+	struct rte_crypto_sym_op *sym = env.op->sym;
+	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
+	int ret;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+
+	memcpy(iv, vec.iv.val, vec.iv.len);
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		ret = prepare_data_mbufs(&vec.pt);
+		if (ret < 0)
+			return ret;
+
+		sym->cipher.data.length = vec.pt.len;
+	} else {
+		ret = prepare_data_mbufs(&vec.ct);
+		if (ret < 0)
+			return ret;
+
+		sym->cipher.data.length = vec.ct.len;
+	}
+
+	rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
+
+	sym->m_src = env.mbuf;
+	sym->cipher.data.offset = 0;
+
+	return 0;
+}
+
+int
+prepare_auth_op(void)
+{
+	struct rte_crypto_sym_op *sym = env.op->sym;
+	int ret;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+
+	if (info.interim_info.gcm_data.gen_iv == 1) {
+		uint32_t i;
+
+		if (!vec.iv.val) {
+			vec.iv.val = rte_malloc(0, vec.iv.len, 0);
+			if (!vec.iv.val)
+				return -ENOMEM;
+		}
+
+		for (i = 0; i < vec.iv.len; i++) {
+			int random = rte_rand();
+			vec.iv.val[i] = (uint8_t)random;
+		}
+	}
+
+	if (vec.iv.len) {
+		uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *,
+				IV_OFF);
+		memset(iv, 0, vec.iv.len);
+		if (vec.iv.val)
+			memcpy(iv, vec.iv.val, vec.iv.len);
+	}
+
+	ret = prepare_data_mbufs(&vec.pt);
+	if (ret < 0)
+		return ret;
+
+	rte_free(env.digest);
+
+	env.digest = rte_zmalloc(NULL, vec.cipher_auth.digest.len,
+			RTE_CACHE_LINE_SIZE);
+	if (!env.digest) {
+		RTE_LOG(ERR, USER1, "Not enough memory\n");
+		return -ENOMEM;
+	}
+	env.digest_len = vec.cipher_auth.digest.len;
+
+	sym->m_src = env.mbuf;
+	sym->auth.data.offset = 0;
+	sym->auth.data.length = vec.pt.len;
+	sym->auth.digest.data = env.digest;
+	sym->auth.digest.phys_addr = rte_malloc_virt2iova(env.digest);
+
+	if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
+		memcpy(env.digest, vec.cipher_auth.digest.val,
+				vec.cipher_auth.digest.len);
+
+	rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
+
+	return 0;
+}
+
+int
+prepare_aead_op(void)
+{
+	struct rte_crypto_sym_op *sym = env.op->sym;
+	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
+	int ret;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
+
+	if (info.algo == FIPS_TEST_ALGO_AES_CCM)
+		iv++;
+
+	if (vec.iv.val)
+		memcpy(iv, vec.iv.val, vec.iv.len);
+	else
+		/* if REQ file has iv length but not data, default as all 0 */
+		memset(iv, 0, vec.iv.len);
+
+	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+		ret = prepare_data_mbufs(&vec.pt);
+		if (ret < 0)
+			return ret;
+
+		rte_free(env.digest);
+		env.digest = rte_zmalloc(NULL, vec.aead.digest.len,
+				RTE_CACHE_LINE_SIZE);
+		if (!env.digest) {
+			RTE_LOG(ERR, USER1, "Not enough memory\n");
+			return -ENOMEM;
+		}
+		env.digest_len = vec.aead.digest.len;
+
+		sym->aead.data.length = vec.pt.len;
+		sym->aead.digest.data = env.digest;
+		sym->aead.digest.phys_addr = rte_malloc_virt2iova(env.digest);
+	} else {
+		ret = prepare_data_mbufs(&vec.ct);
+		if (ret < 0)
+			return ret;
+		env.digest_len = vec.aead.digest.len;
+		sym->aead.data.length = vec.ct.len;
+		sym->aead.digest.data = vec.aead.digest.val;
+		sym->aead.digest.phys_addr = rte_malloc_virt2iova(
+				sym->aead.digest.data);
+	}
+
+	sym->m_src = env.mbuf;
+	sym->aead.data.offset = 0;
+	sym->aead.aad.data = vec.aead.aad.val;
+	sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data);
+
+	rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
+
+	return 0;
+}
+
+static int
+get_hash_oid(enum rte_crypto_auth_algorithm hash, uint8_t *buf)
+{
+	uint8_t id_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
+				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+				  0x04, 0x02, 0x03, 0x05, 0x00, 0x04,
+				  0x40};
+	uint8_t id_sha384[] = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
+				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+				  0x04, 0x02, 0x02, 0x05, 0x00, 0x04,
+				  0x30};
+	uint8_t id_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
+				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+				  0x04, 0x02, 0x01, 0x05, 0x00, 0x04,
+				  0x20};
+	uint8_t id_sha224[] = {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
+				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
+				  0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
+				  0x1c};
+	uint8_t id_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+				0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
+				0x00, 0x04, 0x14};
+	const uint8_t *id;
+	sizeo_t id_len;
+
+	switch (hash) {
+	case RTE_CRYPTO_AUTH_SHA1:
+		id = id_sha1;
+		id_len = sizeof(id_sha1);
+		break;
+	case RTE_CRYPTO_AUTH_SHA224:
+		id = id_sha224;
+		id_len = sizeof(id_sha224);
+		break;
+	case RTE_CRYPTO_AUTH_SHA256:
+		id = id_sha256;
+		id_len = sizeof(id_sha256);
+		break;
+	case RTE_CRYPTO_AUTH_SHA384:
+		id = id_sha384;
+		id_len = sizeof(id_sha384);
+		break;
+	case RTE_CRYPTO_AUTH_SHA512:
+		id = id_sha512;
+		id_len = sizeof(id_sha512);
+		break;
+	default:
+		id_len = -1;
+		break;
+	}
+
+	if (id != NULL)
+		memcpy(buf, id, id_len);
+
+	return id_len;
+}
+
+static int
+prepare_rsa_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+	struct fips_val msg;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	if (env.digest) {
+		msg.val = env.digest;
+		msg.len = env.digest_len;
+	} else {
+		msg.val = vec.pt.val;
+		msg.len = vec.pt.len;
+	}
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		asym->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+		asym->rsa.message.data = msg.val;
+		asym->rsa.message.length = msg.len;
+
+		rte_free(vec.rsa.signature.val);
+
+		vec.rsa.signature.val = rte_zmalloc(NULL, vec.rsa.n.len, 0);
+		vec.rsa.signature.len = vec.rsa.n.len;
+		asym->rsa.sign.data = vec.rsa.signature.val;
+		asym->rsa.sign.length = 0;
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		asym->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+		asym->rsa.message.data = msg.val;
+		asym->rsa.message.length = msg.len;
+		asym->rsa.sign.data = vec.rsa.signature.val;
+		asym->rsa.sign.length = vec.rsa.signature.len;
+	} else {
+		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
+		return -EINVAL;
+	}
+
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
+static int
+prepare_ecdsa_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+	struct fips_val msg;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	if (env.digest) {
+		msg.val = env.digest;
+		msg.len = env.digest_len;
+	} else {
+		msg.val = vec.pt.val;
+		msg.len = vec.pt.len;
+	}
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+		asym->ecdsa.message.data = msg.val;
+		asym->ecdsa.message.length = msg.len;
+		asym->ecdsa.k.data = vec.ecdsa.k.val;
+		asym->ecdsa.k.length = vec.ecdsa.k.len;
+
+		rte_free(vec.ecdsa.r.val);
+
+		rte_free(vec.ecdsa.s.val);
+
+		vec.ecdsa.r.len = info.interim_info.ecdsa_data.curve_len;
+		vec.ecdsa.r.val = rte_zmalloc(NULL, vec.ecdsa.r.len, 0);
+
+		vec.ecdsa.s.len = vec.ecdsa.r.len;
+		vec.ecdsa.s.val = rte_zmalloc(NULL, vec.ecdsa.s.len, 0);
+
+		asym->ecdsa.r.data = vec.ecdsa.r.val;
+		asym->ecdsa.r.length = 0;
+		asym->ecdsa.s.data = vec.ecdsa.s.val;
+		asym->ecdsa.s.length = 0;
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+		asym->ecdsa.message.data = msg.val;
+		asym->ecdsa.message.length = msg.len;
+		asym->ecdsa.r.data = vec.ecdsa.r.val;
+		asym->ecdsa.r.length = vec.ecdsa.r.len;
+		asym->ecdsa.s.data = vec.ecdsa.s.val;
+		asym->ecdsa.s.length = vec.ecdsa.s.len;
+	} else {
+		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
+		return -EINVAL;
+	}
+
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
+static int
+prepare_eddsa_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+	struct fips_val msg;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	if (env.digest) {
+		msg.val = env.digest;
+		msg.len = env.digest_len;
+	} else {
+		msg.val = vec.pt.val;
+		msg.len = vec.pt.len;
+	}
+
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.context.data = vec.eddsa.ctx.val;
+		asym->eddsa.context.length = vec.eddsa.ctx.len;
+
+		rte_free(vec.eddsa.sign.val);
+
+		vec.eddsa.sign.len = info.interim_info.eddsa_data.curve_len;
+		vec.eddsa.sign.val = rte_zmalloc(NULL, vec.eddsa.sign.len, 0);
+
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = 0;
+	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
+		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
+		asym->eddsa.message.data = msg.val;
+		asym->eddsa.message.length = msg.len;
+		asym->eddsa.sign.data = vec.eddsa.sign.val;
+		asym->eddsa.sign.length = vec.eddsa.sign.len;
+	} else {
+		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
+		return -EINVAL;
+	}
+
+	if (info.interim_info.eddsa_data.curve_id == RTE_CRYPTO_EC_GROUP_ED25519) {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519PH;
+		if (vec.eddsa.ctx.len > 0)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519CTX;
+	} else {
+		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448;
+		if (info.interim_info.eddsa_data.prehash)
+			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448PH;
+	}
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
+static int
+prepare_ecfpm_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	asym->ecpm.scalar.data = vec.ecdsa.pkey.val;
+	asym->ecpm.scalar.length = vec.ecdsa.pkey.len;
+
+	rte_free(vec.ecdsa.qx.val);
+
+	rte_free(vec.ecdsa.qy.val);
+
+	vec.ecdsa.qx.len = info.interim_info.ecdsa_data.curve_len;
+	vec.ecdsa.qx.val = rte_zmalloc(NULL, vec.ecdsa.qx.len, 0);
+
+	vec.ecdsa.qy.len = vec.ecdsa.qx.len;
+	vec.ecdsa.qy.val = rte_zmalloc(NULL, vec.ecdsa.qy.len, 0);
+
+	asym->ecpm.r.x.data = vec.ecdsa.qx.val;
+	asym->ecpm.r.x.length = 0;
+	asym->ecpm.r.y.data = vec.ecdsa.qy.val;
+	asym->ecpm.r.y.length = 0;
+
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
+static int
+prepare_edfpm_op(void)
+{
+	struct rte_crypto_asym_op *asym;
+
+	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
+
+	asym = env.op->asym;
+	asym->ecpm.scalar.data = vec.eddsa.pkey.val;
+	asym->ecpm.scalar.length = vec.eddsa.pkey.len;
+
+	rte_free(vec.eddsa.q.val);
+
+	vec.eddsa.q.len = info.interim_info.eddsa_data.curve_len;
+	vec.eddsa.q.val = rte_zmalloc(NULL, vec.eddsa.q.len, 0);
+
+	asym->ecpm.r.x.data = vec.eddsa.q.val;
+	asym->ecpm.r.x.length = 0;
+	asym->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
+
+	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
+
+	return 0;
+}
+
+static int
+prepare_aes_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC)
+		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC;
+	else if (info.interim_info.aes_data.cipher_algo ==
+			RTE_CRYPTO_CIPHER_AES_CTR)
+		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CTR;
+	else
+		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB;
+
+	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+			RTE_CRYPTO_CIPHER_OP_DECRYPT;
+	cipher_xform->key.data = vec.cipher_auth.key.val;
+	cipher_xform->key.length = vec.cipher_auth.key.len;
+	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC ||
+			cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CTR) {
+		cipher_xform->iv.length = vec.iv.len;
+		cipher_xform->iv.offset = IV_OFF;
+	} else {
+		cipher_xform->iv.length = 0;
+		cipher_xform->iv.offset = 0;
+	}
+	cap_idx.algo.cipher = cipher_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_cipher(cap,
+			cipher_xform->key.length,
+			cipher_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, cipher_xform->key.length,
+				cipher_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int
+prepare_tdes_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC)
+		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC;
+	else
+		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB;
+	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+			RTE_CRYPTO_CIPHER_OP_DECRYPT;
+	cipher_xform->key.data = vec.cipher_auth.key.val;
+	cipher_xform->key.length = vec.cipher_auth.key.len;
+
+	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
+		cipher_xform->iv.length = vec.iv.len;
+		cipher_xform->iv.offset = IV_OFF;
+	} else {
+		cipher_xform->iv.length = 0;
+		cipher_xform->iv.offset = 0;
+	}
+	cap_idx.algo.cipher = cipher_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_cipher(cap,
+			cipher_xform->key.length,
+			cipher_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, cipher_xform->key.length,
+				cipher_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int
+prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	auth_xform->algo = info.interim_info.hmac_data.algo;
+	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
+	auth_xform->digest_length = vec.cipher_auth.digest.len;
+	auth_xform->key.data = vec.cipher_auth.key.val;
+	auth_xform->key.length = vec.cipher_auth.key.len;
+
+	cap_idx.algo.auth = auth_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_auth(cap,
+			auth_xform->key.length,
+			auth_xform->digest_length, 0) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n",
+				info.device_name, auth_xform->key.length,
+				auth_xform->digest_length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+int
+prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
+	aead_xform->aad_length = vec.aead.aad.len;
+	aead_xform->digest_length = vec.aead.digest.len;
+	aead_xform->iv.offset = IV_OFF;
+	aead_xform->iv.length = vec.iv.len;
+	aead_xform->key.data = vec.aead.key.val;
+	aead_xform->key.length = vec.aead.key.len;
+	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_AEAD_OP_ENCRYPT :
+			RTE_CRYPTO_AEAD_OP_DECRYPT;
+
+	cap_idx.algo.aead = aead_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_aead(cap,
+			aead_xform->key.length,
+			aead_xform->digest_length, aead_xform->aad_length,
+			aead_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1,
+			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
+				info.device_name, aead_xform->key.length,
+				aead_xform->digest_length,
+				aead_xform->aad_length,
+				aead_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+int
+prepare_gmac_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC;
+	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_AUTH_OP_GENERATE :
+			RTE_CRYPTO_AUTH_OP_VERIFY;
+	auth_xform->iv.offset = IV_OFF;
+	auth_xform->iv.length = vec.iv.len;
+	auth_xform->digest_length = vec.aead.digest.len;
+	auth_xform->key.data = vec.aead.key.val;
+	auth_xform->key.length = vec.aead.key.len;
+
+	cap_idx.algo.auth = auth_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_auth(cap,
+			auth_xform->key.length,
+			auth_xform->digest_length,
+			auth_xform->iv.length) != 0) {
+
+		RTE_LOG(ERR, USER1,
+			"PMD %s key length %u Digest length %u IV length %u\n",
+				info.device_name, auth_xform->key.length,
+				auth_xform->digest_length,
+				auth_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int
+prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC;
+	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY;
+	auth_xform->digest_length = vec.cipher_auth.digest.len;
+	auth_xform->key.data = vec.cipher_auth.key.val;
+	auth_xform->key.length = vec.cipher_auth.key.len;
+
+	cap_idx.algo.auth = auth_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_auth(cap,
+			auth_xform->key.length,
+			auth_xform->digest_length, 0) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n",
+				info.device_name, auth_xform->key.length,
+				auth_xform->digest_length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int
+prepare_ccm_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM;
+	aead_xform->aad_length = vec.aead.aad.len;
+	aead_xform->digest_length = vec.aead.digest.len;
+	aead_xform->iv.offset = IV_OFF;
+	aead_xform->iv.length = vec.iv.len;
+	aead_xform->key.data = vec.aead.key.val;
+	aead_xform->key.length = vec.aead.key.len;
+	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_AEAD_OP_ENCRYPT :
+			RTE_CRYPTO_AEAD_OP_DECRYPT;
+
+	cap_idx.algo.aead = aead_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_aead(cap,
+			aead_xform->key.length,
+			aead_xform->digest_length, aead_xform->aad_length,
+			aead_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1,
+			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
+				info.device_name, aead_xform->key.length,
+				aead_xform->digest_length,
+				aead_xform->aad_length,
+				aead_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int
+prepare_sha_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	auth_xform->algo = info.interim_info.sha_data.algo;
+	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
+	auth_xform->digest_length = vec.cipher_auth.digest.len;
+
+	cap_idx.algo.auth = auth_xform->algo;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_auth(cap,
+			auth_xform->key.length,
+			auth_xform->digest_length, 0) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n",
+				info.device_name, auth_xform->key.length,
+				auth_xform->digest_length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int
+prepare_xts_xform(struct rte_crypto_sym_xform *xform)
+{
+	const struct rte_cryptodev_symmetric_capability *cap;
+	struct rte_cryptodev_sym_capability_idx cap_idx;
+	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
+
+	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS;
+	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
+			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
+			RTE_CRYPTO_CIPHER_OP_DECRYPT;
+	cipher_xform->key.data = vec.cipher_auth.key.val;
+	cipher_xform->key.length = vec.cipher_auth.key.len;
+	cipher_xform->iv.length = vec.iv.len;
+	cipher_xform->iv.offset = IV_OFF;
+
+	cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS;
+	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
+
+	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	if (rte_cryptodev_sym_capability_check_cipher(cap,
+			cipher_xform->key.length,
+			cipher_xform->iv.length) != 0) {
+		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
+				info.device_name, cipher_xform->key.length,
+				cipher_xform->iv.length);
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int
+prepare_rsa_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+	struct rte_cryptodev_info dev_info;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_RSA;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	switch (info.op) {
+	case FIPS_TEST_ASYM_SIGGEN:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_SIGN)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
+			return -EPERM;
+		}
+		break;
+	case FIPS_TEST_ASYM_SIGVER:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_VERIFY)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
+			return -EPERM;
+		}
+		break;
+	case FIPS_TEST_ASYM_KEYGEN:
+		break;
+	default:
+		break;
+	}
+
+	rte_cryptodev_info_get(env.dev_id, &dev_info);
+	xform->rsa.key_type = info.interim_info.rsa_data.privkey;
+	switch (xform->rsa.key_type) {
+	case RTE_RSA_KEY_TYPE_QT:
+		if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT)) {
+			RTE_LOG(ERR, USER1, "PMD %s does not support QT key type\n",
+				info.device_name);
+			return -EPERM;
+		}
+		xform->rsa.qt.p.data = vec.rsa.p.val;
+		xform->rsa.qt.p.length = vec.rsa.p.len;
+		xform->rsa.qt.q.data = vec.rsa.q.val;
+		xform->rsa.qt.q.length = vec.rsa.q.len;
+		xform->rsa.qt.dP.data = vec.rsa.dp.val;
+		xform->rsa.qt.dP.length = vec.rsa.dp.len;
+		xform->rsa.qt.dQ.data = vec.rsa.dq.val;
+		xform->rsa.qt.dQ.length = vec.rsa.dq.len;
+		xform->rsa.qt.qInv.data = vec.rsa.qinv.val;
+		xform->rsa.qt.qInv.length = vec.rsa.qinv.len;
+		break;
+	case RTE_RSA_KEY_TYPE_EXP:
+		if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP)) {
+			RTE_LOG(ERR, USER1, "PMD %s does not support EXP key type\n",
+				info.device_name);
+			return -EPERM;
+		}
+		xform->rsa.d.data = vec.rsa.d.val;
+		xform->rsa.d.length = vec.rsa.d.len;
+		break;
+	default:
+		break;
+	}
+
+	xform->rsa.e.data = vec.rsa.e.val;
+	xform->rsa.e.length = vec.rsa.e.len;
+	xform->rsa.n.data = vec.rsa.n.val;
+	xform->rsa.n.length = vec.rsa.n.len;
+
+	xform->rsa.padding.type = info.interim_info.rsa_data.padding;
+	xform->rsa.padding.hash = info.interim_info.rsa_data.auth;
+	if (env.digest) {
+		if (xform->rsa.padding.type == RTE_CRYPTO_RSA_PADDING_PKCS1_5) {
+			struct fips_val msg;
+			int b_len = 0;
+			uint8_t b[32];
+
+			b_len = get_hash_oid(xform->rsa.padding.hash, b);
+			if (b_len < 0) {
+				RTE_LOG(ERR, USER1, "Failed to get digest info for hash %d\n",
+					xform->rsa.padding.hash);
+				return -EINVAL;
+			}
+
+			if (b_len) {
+				msg.len = env.digest_len + b_len;
+				msg.val = rte_zmalloc(NULL, msg.len, 0);
+				rte_memcpy(msg.val, b, b_len);
+				rte_memcpy(msg.val + b_len, env.digest, env.digest_len);
+				rte_free(env.digest);
+				env.digest = msg.val;
+				env.digest_len = msg.len;
+			}
+		}
+	}
+
+	return 0;
+}
+
+static int
+prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	switch (info.op) {
+	case FIPS_TEST_ASYM_SIGGEN:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_SIGN)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
+			return -EPERM;
+		}
+
+		xform->ec.pkey.data = vec.ecdsa.pkey.val;
+		xform->ec.pkey.length = vec.ecdsa.pkey.len;
+		break;
+	case FIPS_TEST_ASYM_SIGVER:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_VERIFY)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
+			return -EPERM;
+		}
+
+		xform->ec.q.x.data = vec.ecdsa.qx.val;
+		xform->ec.q.x.length = vec.ecdsa.qx.len;
+		xform->ec.q.y.data = vec.ecdsa.qy.val;
+		xform->ec.q.y.length = vec.ecdsa.qy.len;
+		break;
+	default:
+		break;
+	}
+
+	xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id;
+	return 0;
+}
+
+static int
+prepare_eddsa_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	switch (info.op) {
+	case FIPS_TEST_ASYM_SIGGEN:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_SIGN)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
+			return -EPERM;
+		}
+
+		xform->ec.pkey.data = vec.eddsa.pkey.val;
+		xform->ec.pkey.length = vec.eddsa.pkey.len;
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	case FIPS_TEST_ASYM_SIGVER:
+		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
+			RTE_CRYPTO_ASYM_OP_VERIFY)) {
+			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
+				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
+			return -EPERM;
+		}
+
+		xform->ec.q.x.data = vec.eddsa.q.val;
+		xform->ec.q.x.length = vec.eddsa.q.len;
+		break;
+	default:
+		break;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
+static int
+prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id;
+	return 0;
+}
+
+static int
+prepare_edfpm_xform(struct rte_crypto_asym_xform *xform)
+{
+	const struct rte_cryptodev_asymmetric_xform_capability *cap;
+	struct rte_cryptodev_asym_capability_idx cap_idx;
+
+	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
+	xform->next = NULL;
+
+	cap_idx.type = xform->xform_type;
+	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+	if (!cap) {
+		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+				env.dev_id);
+		return -EINVAL;
+	}
+
+	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
+	return 0;
+}
+
+static int
+get_writeback_data(struct fips_val *val)
+{
+	struct rte_mbuf *m = env.mbuf;
+	uint16_t data_len = rte_pktmbuf_pkt_len(m);
+	uint16_t total_len = data_len + env.digest_len;
+	uint8_t *src, *dst, *wb_data;
+
+	/* in case val is reused for MCT test, try to free the buffer first */
+	if (val->val) {
+		rte_free(val->val);
+		val->val = NULL;
+	}
+
+	wb_data = dst = rte_malloc(NULL, total_len, 0);
+	if (!dst) {
+		RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM);
+		return -ENOMEM;
+	}
+
+	while (m && data_len) {
+		uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len);
+
+		src = rte_pktmbuf_mtod(m, uint8_t *);
+		memcpy(dst, src, seg_len);
+		m = m->next;
+		data_len -= seg_len;
+		dst += seg_len;
+	}
+
+	if (data_len) {
+		RTE_LOG(ERR, USER1, "Error -1: write back data\n");
+		rte_free(wb_data);
+		return -1;
+	}
+
+	if (env.digest)
+		memcpy(dst, env.digest, env.digest_len);
+
+	val->val = wb_data;
+	val->len = total_len;
+
+	return 0;
+}
+
+static int
+fips_run_sym_test(void)
+{
+	struct rte_crypto_sym_xform xform = {0};
+	uint16_t n_deqd;
+	int ret;
+
+	if (!test_ops.prepare_sym_xform || !test_ops.prepare_sym_op)
+		return -EINVAL;
+
+	ret = test_ops.prepare_sym_xform(&xform);
+	if (ret < 0)
+		return ret;
+
+	env.sym.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform,
+						env.sym.sess_mpool);
+	if (!env.sym.sess)
+		return -ENOMEM;
+
+	ret = test_ops.prepare_sym_op();
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n",
+				ret);
+		goto exit;
+	}
+
+	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
+		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
+		ret = -1;
+		goto exit;
+	}
+
+	do {
+		struct rte_crypto_op *deqd_op;
+
+		n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1);
+	} while (n_deqd == 0);
+
+	vec.status = env.op->status;
+
+exit:
+	rte_cryptodev_sym_session_free(env.dev_id, env.sym.sess);
+	env.sym.sess = NULL;
+	return ret;
+}
+
+static int
+fips_run_asym_test(void)
+{
+	struct rte_crypto_asym_xform xform = {0};
+	struct rte_crypto_asym_op *asym;
+	struct rte_crypto_op *deqd_op;
+	int ret;
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN &&
+		(info.algo != FIPS_TEST_ALGO_ECDSA &&
+		 info.algo != FIPS_TEST_ALGO_EDDSA)) {
+		RTE_SET_USED(asym);
+		ret = 0;
+		goto exit;
+	}
+
+	if (!test_ops.prepare_asym_xform || !test_ops.prepare_asym_op)
+		return -EINVAL;
+
+	asym = env.op->asym;
+	ret = test_ops.prepare_asym_xform(&xform);
+	if (ret < 0)
+		return ret;
+
+	ret = rte_cryptodev_asym_session_create(env.dev_id, &xform, env.asym.sess_mpool,
+			(void *)&env.asym.sess);
+	if (ret < 0)
+		return ret;
+
+	ret = test_ops.prepare_asym_op();
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", ret);
+		goto exit;
+	}
+
+	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
+		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
+		ret = -1;
+		goto exit;
+	}
+
+	while (rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1) == 0)
+		rte_pause();
+
+	vec.status = env.op->status;
+
+ exit:
+	if (env.asym.sess)
+		rte_cryptodev_asym_session_free(env.dev_id, env.asym.sess);
+
+	env.asym.sess = NULL;
+	return ret;
+}
+
+static int
+fips_run_test(void)
+{
+	int ret;
+
+	env.op = NULL;
+	if (!env.is_asym_test) {
+		env.op = env.sym.op;
+		return fips_run_sym_test();
+	}
+
+	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+		if (info.algo == FIPS_TEST_ALGO_ECDSA) {
+			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
+			test_ops.prepare_asym_op = prepare_ecfpm_op;
+			info.interim_info.ecdsa_data.pubkey_gen = 0;
+
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA) {
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			info.interim_info.eddsa_data.pubkey_gen = 0;
+		}
+
+		env.op = env.asym.op;
+		return fips_run_asym_test();
+	}
+
+	if (info.algo == FIPS_TEST_ALGO_ECDSA ||
+	    info.algo == FIPS_TEST_ALGO_RSA) {
+		vec.cipher_auth.digest.len =
+			parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth);
+		test_ops.prepare_sym_xform = prepare_sha_xform;
+		test_ops.prepare_sym_op = prepare_auth_op;
+
+		env.op = env.sym.op;
+		ret = fips_run_sym_test();
+		if (ret < 0)
+			return ret;
+	}
+
+	env.op = env.asym.op;
+	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
+		fips_prepare_asym_xform_t old_xform;
+		fips_prepare_op_t old_op;
+
+		old_xform = test_ops.prepare_asym_xform;
+		old_op = test_ops.prepare_asym_op;
+
+		if (info.algo == FIPS_TEST_ALGO_ECDSA &&
+		    info.interim_info.ecdsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
+			test_ops.prepare_asym_op = prepare_ecfpm_op;
+
+			ret = fips_run_asym_test();
+			if (ret < 0)
+				return ret;
+
+			info.post_interim_writeback(NULL);
+			info.interim_info.ecdsa_data.pubkey_gen = 0;
+
+		} else if (info.algo == FIPS_TEST_ALGO_EDDSA &&
+				   info.interim_info.eddsa_data.pubkey_gen == 1) {
+			info.op = FIPS_TEST_ASYM_KEYGEN;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+
+			const struct rte_cryptodev_asymmetric_xform_capability *cap;
+			struct rte_cryptodev_asym_capability_idx cap_idx;
+
+			cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
+			cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
+			if (!cap) {
+				RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
+						env.dev_id);
+				return -EINVAL;
+			}
+
+			if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) {
+				ret = fips_run_asym_test();
+				if (ret < 0)
+					return ret;
+			} else {
+				/* Below is only a workaround by using known keys. */
+				struct rte_crypto_asym_xform xform = {0};
+
+				prepare_edfpm_xform(&xform);
+				prepare_edfpm_op();
+				uint8_t pkey25519[] = {
+					0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
+					0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
+					0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
+					0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
+				};
+				uint8_t q25519[] = {
+					0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
+					0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
+					0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
+					0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
+				};
+				uint8_t pkey448[] = {
+					0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
+					0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
+					0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
+					0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
+					0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
+					0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
+					0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
+					0x01
+				};
+				uint8_t q448[] = {
+					0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
+					0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
+					0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
+					0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
+					0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
+					0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
+					0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
+					0x00
+				};
+				if (info.interim_info.eddsa_data.curve_id ==
+					RTE_CRYPTO_EC_GROUP_ED25519) {
+					memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519));
+					vec.eddsa.q.len = 32;
+				} else {
+					memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448));
+					vec.eddsa.pkey.len = 32;
+					memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448));
+					vec.eddsa.q.len = 32;
+				}
+			}
+			info.post_interim_writeback(NULL);
+			info.interim_info.eddsa_data.pubkey_gen = 0;
+
+		}
+
+		test_ops.prepare_asym_xform = old_xform;
+		test_ops.prepare_asym_op = old_op;
+		info.op = FIPS_TEST_ASYM_SIGGEN;
+		ret = fips_run_asym_test();
+	} else {
+		ret = fips_run_asym_test();
+	}
+
+	return ret;
+}
+
+static int
+fips_generic_test(void)
+{
+	struct fips_val val = {NULL, 0};
+	int ret;
+
+	if (info.file_type != FIPS_TYPE_JSON)
+		fips_test_write_one_case();
+
+	ret = fips_run_test();
+	if (ret < 0) {
+		if (ret == -EPERM || ret == -ENOTSUP) {
+			if (info.file_type == FIPS_TYPE_JSON)
+				return ret;
+
+			fprintf(info.fp_wr, "Bypass\n\n");
+			return 0;
+		}
+
+		return ret;
+	}
+
+	if (!env.is_asym_test) {
+		ret = get_writeback_data(&val);
+		if (ret < 0)
+			return ret;
+	}
+
+	switch (info.file_type) {
+	case FIPS_TYPE_REQ:
+	case FIPS_TYPE_RSP:
+	case FIPS_TYPE_JSON:
+		if (info.parse_writeback == NULL)
+			return -EPERM;
+		ret = info.parse_writeback(&val);
+		if (ret < 0)
+			return ret;
+		break;
+	case FIPS_TYPE_FAX:
+		if (info.kat_check == NULL)
+			return -EPERM;
+		ret = info.kat_check(&val);
+		if (ret < 0)
+			return ret;
+		break;
+	default:
+		break;
+	}
+
+	if (info.file_type != FIPS_TYPE_JSON)
+		fprintf(info.fp_wr, "\n");
+	rte_free(val.val);
+
+	return 0;
+}
+
+static int
+fips_mct_tdes_test(void)
+{
+#define TDES_BLOCK_SIZE		8
+#define TDES_EXTERN_ITER	400
+#define TDES_INTERN_ITER	10000
+	struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv;
+	uint8_t prev_out[TDES_BLOCK_SIZE] = {0};
+	uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0};
+	uint8_t prev_in[TDES_BLOCK_SIZE] = {0};
+	uint32_t i, j, k;
+	int ret;
+	int test_mode = info.interim_info.tdes_data.test_mode;
+
+	pt.len = vec.pt.len;
+	pt.val = rte_malloc(NULL, pt.len, 0);
+	ct.len = vec.ct.len;
+	ct.val = rte_malloc(NULL, ct.len, 0);
+	iv.len = vec.iv.len;
+	iv.val = rte_malloc(NULL, iv.len, 0);
+
+	for (i = 0; i < TDES_EXTERN_ITER; i++) {
+		if (info.file_type != FIPS_TYPE_JSON) {
+			if ((i == 0) && (info.version == 21.4f)) {
+				if (!(strstr(info.vec[0], "COUNT")))
+					fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0);
+			}
+
+			if (i != 0)
+				update_info_vec(i);
+
+			fips_test_write_one_case();
+		}
+
+		for (j = 0; j < TDES_INTERN_ITER; j++) {
+			ret = fips_run_test();
+			if (ret < 0) {
+				if (ret == -EPERM) {
+					if (info.file_type == FIPS_TYPE_JSON)
+						return ret;
+
+					fprintf(info.fp_wr, "Bypass\n");
+					return 0;
+				}
+				return ret;
+			}
+
+			ret = get_writeback_data(&val[0]);
+			if (ret < 0)
+				return ret;
+
+			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
+				memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE);
+
+			if (j == 0) {
+				memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
+				memcpy(pt.val, vec.pt.val, pt.len);
+				memcpy(ct.val, vec.ct.val, ct.len);
+				memcpy(iv.val, vec.iv.val, iv.len);
+
+				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+					if (test_mode == TDES_MODE_ECB) {
+						memcpy(vec.pt.val, val[0].val,
+							   TDES_BLOCK_SIZE);
+					} else {
+						memcpy(vec.pt.val, vec.iv.val,
+							   TDES_BLOCK_SIZE);
+						memcpy(vec.iv.val, val[0].val,
+							   TDES_BLOCK_SIZE);
+					}
+					val[1].val = pt.val;
+					val[1].len = pt.len;
+					val[2].val = iv.val;
+					val[2].len = iv.len;
+				} else {
+					if (test_mode == TDES_MODE_ECB) {
+						memcpy(vec.ct.val, val[0].val,
+							   TDES_BLOCK_SIZE);
+					} else {
+						memcpy(vec.iv.val, vec.ct.val,
+							   TDES_BLOCK_SIZE);
+						memcpy(vec.ct.val, val[0].val,
+							   TDES_BLOCK_SIZE);
+					}
+					val[1].val = ct.val;
+					val[1].len = ct.len;
+					val[2].val = iv.val;
+					val[2].len = iv.len;
+				}
+				continue;
+			}
+
+			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+				if (test_mode == TDES_MODE_ECB) {
+					memcpy(vec.pt.val, val[0].val,
+						   TDES_BLOCK_SIZE);
+				} else {
+					memcpy(vec.iv.val, val[0].val,
+						   TDES_BLOCK_SIZE);
+					memcpy(vec.pt.val, prev_out,
+						   TDES_BLOCK_SIZE);
+				}
+			} else {
+				if (test_mode == TDES_MODE_ECB) {
+					memcpy(vec.ct.val, val[0].val,
+						   TDES_BLOCK_SIZE);
+				} else {
+					memcpy(vec.iv.val, vec.ct.val,
+						   TDES_BLOCK_SIZE);
+					memcpy(vec.ct.val, val[0].val,
+						   TDES_BLOCK_SIZE);
+				}
+			}
+
+			if (j == TDES_INTERN_ITER - 1)
+				continue;
+
+			memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
+
+			if (j == TDES_INTERN_ITER - 3)
+				memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE);
+		}
+
+		info.parse_writeback(val);
+		if (info.file_type != FIPS_TYPE_JSON)
+			fprintf(info.fp_wr, "\n");
+
+		if (i == TDES_EXTERN_ITER - 1)
+			continue;
+
+		/** update key */
+		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
+
+		if (info.interim_info.tdes_data.nb_keys == 0) {
+			if (memcmp(val_key.val, val_key.val + 8, 8) == 0)
+				info.interim_info.tdes_data.nb_keys = 1;
+			else if (memcmp(val_key.val, val_key.val + 16, 8) == 0)
+				info.interim_info.tdes_data.nb_keys = 2;
+			else
+				info.interim_info.tdes_data.nb_keys = 3;
+
+		}
+
+		for (k = 0; k < TDES_BLOCK_SIZE; k++) {
+
+			switch (info.interim_info.tdes_data.nb_keys) {
+			case 3:
+				val_key.val[k] ^= val[0].val[k];
+				val_key.val[k + 8] ^= prev_out[k];
+				val_key.val[k + 16] ^= prev_prev_out[k];
+				break;
+			case 2:
+				val_key.val[k] ^= val[0].val[k];
+				val_key.val[k + 8] ^= prev_out[k];
+				val_key.val[k + 16] ^= val[0].val[k];
+				break;
+			default: /* case 1 */
+				val_key.val[k] ^= val[0].val[k];
+				val_key.val[k + 8] ^= val[0].val[k];
+				val_key.val[k + 16] ^= val[0].val[k];
+				break;
+			}
+
+		}
+
+		for (k = 0; k < 24; k++)
+			val_key.val[k] = (rte_popcount32(val_key.val[k]) &
+					0x1) ?
+					val_key.val[k] : (val_key.val[k] ^ 0x1);
+
+		if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+			if (test_mode == TDES_MODE_ECB) {
+				memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE);
+			} else {
+				memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE);
+				memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
+			}
+		} else {
+			if (test_mode == TDES_MODE_ECB) {
+				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
+			} else {
+				memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE);
+				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
+			}
+		}
+	}
+
+	rte_free(val[0].val);
+	rte_free(pt.val);
+	rte_free(ct.val);
+	rte_free(iv.val);
+
+	return 0;
+}
+
+static int
+fips_mct_aes_ecb_test(void)
+{
+#define AES_BLOCK_SIZE	16
+#define AES_EXTERN_ITER	100
+#define AES_INTERN_ITER	1000
+	struct fips_val val = {NULL, 0}, val_key;
+	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
+	uint32_t i, j, k;
+	int ret;
+
+	for (i = 0; i < AES_EXTERN_ITER; i++) {
+		if (i != 0)
+			update_info_vec(i);
+
+		fips_test_write_one_case();
+
+		for (j = 0; j < AES_INTERN_ITER; j++) {
+			ret = fips_run_test();
+			if (ret < 0) {
+				if (ret == -EPERM) {
+					if (info.file_type == FIPS_TYPE_JSON)
+						return ret;
+
+					fprintf(info.fp_wr, "Bypass\n");
+					return 0;
+				}
+
+				return ret;
+			}
+
+			ret = get_writeback_data(&val);
+			if (ret < 0)
+				return ret;
+
+			if (info.op == FIPS_TEST_ENC_AUTH_GEN)
+				memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE);
+			else
+				memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE);
+
+			if (j == AES_INTERN_ITER - 1)
+				continue;
+
+			memcpy(prev_out, val.val, AES_BLOCK_SIZE);
+		}
+
+		info.parse_writeback(&val);
+		fprintf(info.fp_wr, "\n");
+
+		if (i == AES_EXTERN_ITER - 1)
+			continue;
+
+		/** update key */
+		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
+		for (k = 0; k < vec.cipher_auth.key.len; k++) {
+			switch (vec.cipher_auth.key.len) {
+			case 16:
+				val_key.val[k] ^= val.val[k];
+				break;
+			case 24:
+				if (k < 8)
+					val_key.val[k] ^= prev_out[k + 8];
+				else
+					val_key.val[k] ^= val.val[k - 8];
+				break;
+			case 32:
+				if (k < 16)
+					val_key.val[k] ^= prev_out[k];
+				else
+					val_key.val[k] ^= val.val[k - 16];
+				break;
+			default:
+				return -1;
+			}
+		}
+	}
+
+	rte_free(val.val);
+
+	return 0;
+}
+static int
+fips_mct_aes_test(void)
+{
+#define AES_BLOCK_SIZE	16
+#define AES_EXTERN_ITER	100
+#define AES_INTERN_ITER	1000
+	struct fips_val val[3] = {{NULL, 0},}, val_key,  pt, ct, iv;
+	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
+	uint8_t prev_in[AES_BLOCK_SIZE] = {0};
+	uint32_t i, j, k;
+	int ret;
+
+	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB)
+		return fips_mct_aes_ecb_test();
+
+	pt.len = vec.pt.len;
+	pt.val = rte_malloc(NULL, pt.len, 0);
+	ct.len = vec.ct.len;
+	ct.val = rte_malloc(NULL, ct.len, 0);
+	iv.len = vec.iv.len;
+	iv.val = rte_malloc(NULL, iv.len, 0);
+	for (i = 0; i < AES_EXTERN_ITER; i++) {
+		if (info.file_type != FIPS_TYPE_JSON) {
+			if (i != 0)
+				update_info_vec(i);
+
+			fips_test_write_one_case();
+		}
+
+		for (j = 0; j < AES_INTERN_ITER; j++) {
+			ret = fips_run_test();
+			if (ret < 0) {
+				if (ret == -EPERM) {
+					if (info.file_type == FIPS_TYPE_JSON)
+						return ret;
+
+					fprintf(info.fp_wr, "Bypass\n");
+					return 0;
+				}
+
+				return ret;
+			}
+
+			ret = get_writeback_data(&val[0]);
+			if (ret < 0)
+				return ret;
+
+			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
+				memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE);
+
+			if (j == 0) {
+				memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
+				memcpy(pt.val, vec.pt.val, pt.len);
+				memcpy(ct.val, vec.ct.val, ct.len);
+				memcpy(iv.val, vec.iv.val, iv.len);
+
+				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+					memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE);
+					memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
+					val[1].val = pt.val;
+					val[1].len = pt.len;
+					val[2].val = iv.val;
+					val[2].len = iv.len;
+				} else {
+					memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE);
+					memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
+					val[1].val = ct.val;
+					val[1].len = ct.len;
+					val[2].val = iv.val;
+					val[2].len = iv.len;
+				}
+				continue;
+			}
+
+			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
+				memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
+				memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE);
+			} else {
+				memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
+				memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE);
+			}
+
+			if (j == AES_INTERN_ITER - 1)
+				continue;
+
+			memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
+		}
+
+		info.parse_writeback(val);
+		if (info.file_type != FIPS_TYPE_JSON)
+			fprintf(info.fp_wr, "\n");
+
+		if (i == AES_EXTERN_ITER - 1)
+			continue;
+
+		/** update key */
+		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
+		for (k = 0; k < vec.cipher_auth.key.len; k++) {
+			switch (vec.cipher_auth.key.len) {
+			case 16:
+				val_key.val[k] ^= val[0].val[k];
+				break;
+			case 24:
+				if (k < 8)
+					val_key.val[k] ^= prev_out[k + 8];
+				else
+					val_key.val[k] ^= val[0].val[k - 8];
+				break;
+			case 32:
+				if (k < 16)
+					val_key.val[k] ^= prev_out[k];
+				else
+					val_key.val[k] ^= val[0].val[k - 16];
+				break;
+			default:
+				return -1;
+			}
+		}
+
+		if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
+			memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
+	}
+
+	rte_free(val[0].val);
+	rte_free(pt.val);
+	rte_free(ct.val);
+	rte_free(iv.val);
+
+	return 0;
+}
+
+static int
+fips_mct_sha_test(void)
+{
+#define SHA_EXTERN_ITER	100
+#define SHA_INTERN_ITER	1000
+	uint8_t md_blocks = info.interim_info.sha_data.md_blocks;
+	struct fips_val val = {NULL, 0};
+	struct fips_val  md[md_blocks];
+	int ret;
+	uint32_t i, j, k, offset, max_outlen;
+
+	max_outlen = md_blocks * vec.cipher_auth.digest.len;
+
+	rte_free(vec.cipher_auth.digest.val);
+	vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0);
+
+	if (vec.pt.val)
+		memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len);
+
+	rte_free(vec.pt.val);
+	vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*md_blocks), 0);
+
+	for (i = 0; i < md_blocks; i++)
+		md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0);
+
+	if (info.file_type != FIPS_TYPE_JSON) {
+		fips_test_write_one_case();
+		fprintf(info.fp_wr, "\n");
+	}
+
+	for (j = 0; j < SHA_EXTERN_ITER; j++) {
+		for (i = 0; i < md_blocks; i++) {
+			memcpy(md[i].val, vec.cipher_auth.digest.val,
+				vec.cipher_auth.digest.len);
+			md[i].len = vec.cipher_auth.digest.len;
+		}
+
+		for (i = 0; i < (SHA_INTERN_ITER); i++) {
+			offset = 0;
+			for (k = 0; k < md_blocks; k++) {
+				memcpy(vec.pt.val + offset, md[k].val, (size_t)md[k].len);
+				offset += md[k].len;
+			}
+			vec.pt.len = offset;
+
+			ret = fips_run_test();
+			if (ret < 0) {
+				if (ret == -EPERM || ret == -ENOTSUP) {
+					if (info.file_type == FIPS_TYPE_JSON)
+						return ret;
+
+					fprintf(info.fp_wr, "Bypass\n\n");
+					return 0;
+				}
+				return ret;
+			}
+
+			ret = get_writeback_data(&val);
+			if (ret < 0)
+				return ret;
+
+			for (k = 1; k < md_blocks; k++) {
+				memcpy(md[k-1].val, md[k].val, md[k].len);
+				md[k-1].len = md[k].len;
+			}
+
+			memcpy(md[md_blocks-1].val, (val.val + vec.pt.len),
+				vec.cipher_auth.digest.len);
+			md[md_blocks-1].len = vec.cipher_auth.digest.len;
+		}
+
+		memcpy(vec.cipher_auth.digest.val, md[md_blocks-1].val, md[md_blocks-1].len);
+		vec.cipher_auth.digest.len = md[md_blocks-1].len;
+
+		if (info.file_type != FIPS_TYPE_JSON)
+			fprintf(info.fp_wr, "COUNT = %u\n", j);
+
+		info.parse_writeback(&val);
+
+		if (info.file_type != FIPS_TYPE_JSON)
+			fprintf(info.fp_wr, "\n");
+	}
+
+	for (i = 0; i < (md_blocks); i++)
+		rte_free(md[i].val);
+
+	rte_free(vec.pt.val);
+
+	rte_free(val.val);
+	return 0;
+}
+
+static int
+fips_mct_shake_test(void)
+{
+#define SHAKE_EXTERN_ITER	100
+#define SHAKE_INTERN_ITER	1000
+	uint32_t i, j, range, outlen, max_outlen;
+	struct fips_val val = {NULL, 0}, md;
+	uint8_t rightmost[2];
+	uint16_t *rightptr;
+	int ret;
+
+	max_outlen = vec.cipher_auth.digest.len;
+
+	rte_free(vec.cipher_auth.digest.val);
+	vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0);
+
+	if (vec.pt.val)
+		memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.pt.len);
+
+	rte_free(vec.pt.val);
+	vec.pt.val = rte_malloc(NULL, 16, 0);
+	vec.pt.len = 16;
+
+	md.val = rte_malloc(NULL, max_outlen, 0);
+	md.len = max_outlen;
+
+	if (info.file_type != FIPS_TYPE_JSON) {
+		fips_test_write_one_case();
+		fprintf(info.fp_wr, "\n");
+	}
+
+	range = max_outlen - info.interim_info.sha_data.min_outlen + 1;
+	outlen = max_outlen;
+	for (j = 0; j < SHAKE_EXTERN_ITER; j++) {
+		memset(md.val, 0, max_outlen);
+		memcpy(md.val, vec.cipher_auth.digest.val,
+			vec.cipher_auth.digest.len);
+
+		for (i = 0; i < (SHAKE_INTERN_ITER); i++) {
+			memset(vec.pt.val, 0, vec.pt.len);
+			memcpy(vec.pt.val, md.val, vec.pt.len);
+			vec.cipher_auth.digest.len = outlen;
+			ret = fips_run_test();
+			if (ret < 0) {
+				if (ret == -EPERM || ret == -ENOTSUP) {
+					if (info.file_type == FIPS_TYPE_JSON)
+						return ret;
+
+					fprintf(info.fp_wr, "Bypass\n\n");
+					return 0;
+				}
+				return ret;
+			}
+
+			ret = get_writeback_data(&val);
+			if (ret < 0)
+				return ret;
+
+			memset(md.val, 0, max_outlen);
+			memcpy(md.val, (val.val + vec.pt.len),
+				vec.cipher_auth.digest.len);
+			md.len = outlen;
+			rightmost[0] = md.val[md.len-1];
+			rightmost[1] = md.val[md.len-2];
+			rightptr = (uint16_t *)rightmost;
+			outlen = info.interim_info.sha_data.min_outlen +
+				(*rightptr % range);
+		}
+
+		memcpy(vec.cipher_auth.digest.val, md.val, md.len);
+		vec.cipher_auth.digest.len = md.len;
+
+		if (info.file_type != FIPS_TYPE_JSON)
+			fprintf(info.fp_wr, "COUNT = %u\n", j);
+
+		info.parse_writeback(&val);
+
+		if (info.file_type != FIPS_TYPE_JSON)
+			fprintf(info.fp_wr, "\n");
+	}
+
+	rte_free(md.val);
+	rte_free(vec.pt.val);
+	rte_free(val.val);
+	return 0;
+}
+
+static int
+init_test_ops(void)
+{
+	switch (info.algo) {
+	case FIPS_TEST_ALGO_AES_CBC:
+	case FIPS_TEST_ALGO_AES_CTR:
+	case FIPS_TEST_ALGO_AES:
+		test_ops.prepare_sym_op = prepare_cipher_op;
+		test_ops.prepare_sym_xform  = prepare_aes_xform;
+		if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)
+			test_ops.test = fips_mct_aes_test;
+		else
+			test_ops.test = fips_generic_test;
+		break;
+	case FIPS_TEST_ALGO_HMAC:
+		test_ops.prepare_sym_op = prepare_auth_op;
+		test_ops.prepare_sym_xform = prepare_hmac_xform;
+		test_ops.test = fips_generic_test;
+		break;
+	case FIPS_TEST_ALGO_TDES:
+		test_ops.prepare_sym_op = prepare_cipher_op;
+		test_ops.prepare_sym_xform = prepare_tdes_xform;
+		if (info.interim_info.tdes_data.test_type == TDES_MCT)
+			test_ops.test = fips_mct_tdes_test;
+		else
+			test_ops.test = fips_generic_test;
+		break;
+	case FIPS_TEST_ALGO_AES_GMAC:
+		test_ops.prepare_sym_op = prepare_auth_op;
+		test_ops.prepare_sym_xform = prepare_gmac_xform;
+		test_ops.test = fips_generic_test;
+		break;
+	case FIPS_TEST_ALGO_AES_GCM:
+		test_ops.prepare_sym_op = prepare_aead_op;
+		test_ops.prepare_sym_xform = prepare_gcm_xform;
+		test_ops.test = fips_generic_test;
+		break;
+	case FIPS_TEST_ALGO_AES_CMAC:
+		test_ops.prepare_sym_op = prepare_auth_op;
+		test_ops.prepare_sym_xform = prepare_cmac_xform;
+		test_ops.test = fips_generic_test;
+		break;
+	case FIPS_TEST_ALGO_AES_CCM:
+		test_ops.prepare_sym_op = prepare_aead_op;
+		test_ops.prepare_sym_xform = prepare_ccm_xform;
+		test_ops.test = fips_generic_test;
+		break;
+	case FIPS_TEST_ALGO_SHA:
+		test_ops.prepare_sym_op = prepare_auth_op;
+		test_ops.prepare_sym_xform = prepare_sha_xform;
+		if (info.interim_info.sha_data.test_type == SHA_MCT)
+			if (info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_128 ||
+				info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_256)
+				test_ops.test = fips_mct_shake_test;
+			else
+				test_ops.test = fips_mct_sha_test;
+		else
+			test_ops.test = fips_generic_test;
+		break;
+	case FIPS_TEST_ALGO_AES_XTS:
+		test_ops.prepare_sym_op = prepare_cipher_op;
+		test_ops.prepare_sym_xform = prepare_xts_xform;
+		test_ops.test = fips_generic_test;
+		break;
+	case FIPS_TEST_ALGO_RSA:
+		test_ops.prepare_asym_op = prepare_rsa_op;
+		test_ops.prepare_asym_xform = prepare_rsa_xform;
+		test_ops.test = fips_generic_test;
+		break;
+	case FIPS_TEST_ALGO_ECDSA:
+		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+			test_ops.prepare_asym_op = prepare_ecfpm_op;
+			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
+			test_ops.test = fips_generic_test;
+		} else {
+			test_ops.prepare_asym_op = prepare_ecdsa_op;
+			test_ops.prepare_asym_xform = prepare_ecdsa_xform;
+			test_ops.test = fips_generic_test;
+		}
+		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
+			test_ops.prepare_asym_op = prepare_edfpm_op;
+			test_ops.prepare_asym_xform = prepare_edfpm_xform;
+			test_ops.test = fips_generic_test;
+		} else {
+			test_ops.prepare_asym_op = prepare_eddsa_op;
+			test_ops.prepare_asym_xform = prepare_eddsa_xform;
+			test_ops.test = fips_generic_test;
+		}
+		break;
+	default:
+		if (strstr(info.file_name, "TECB") ||
+				strstr(info.file_name, "TCBC")) {
+			info.algo = FIPS_TEST_ALGO_TDES;
+			test_ops.prepare_sym_op = prepare_cipher_op;
+			test_ops.prepare_sym_xform = prepare_tdes_xform;
+			if (info.interim_info.tdes_data.test_type == TDES_MCT)
+				test_ops.test = fips_mct_tdes_test;
+			else
+				test_ops.test = fips_generic_test;
+			break;
+		}
+		return -1;
+	}
+
+	return 0;
+}
+
+static void
+print_test_block(void)
+{
+	uint32_t i;
+
+	for (i = 0; i < info.nb_vec_lines; i++)
+		printf("%s\n", info.vec[i]);
+
+	printf("\n");
+}
+
+static int
+fips_test_one_file(void)
+{
+	int fetch_ret = 0, ret;
+
+	ret = init_test_ops();
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret);
+		return ret;
+	}
+
+	while (ret >= 0 && fetch_ret == 0) {
+		fetch_ret = fips_test_fetch_one_block();
+		if (fetch_ret < 0) {
+			RTE_LOG(ERR, USER1, "Error %i: Fetch block\n",
+					fetch_ret);
+			ret = fetch_ret;
+			goto error_one_case;
+		}
+
+		if (info.nb_vec_lines == 0) {
+			if (fetch_ret == -EOF)
+				break;
+
+			fprintf(info.fp_wr, "\n");
+			continue;
+		}
+
+		ret = fips_test_parse_one_case();
+		switch (ret) {
+		case 0:
+			ret = test_ops.test();
+			if (ret == 0)
+				break;
+			RTE_LOG(ERR, USER1, "Error %i: test block\n",
+					ret);
+			goto error_one_case;
+		case 1:
+			break;
+		default:
+			RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
+					ret);
+			goto error_one_case;
+		}
+
+		continue;
+error_one_case:
+		print_test_block();
+	}
+
+	fips_test_clear();
+
+	if (env.digest) {
+		rte_free(env.digest);
+		env.digest = NULL;
+		env.digest_len = 0;
+	}
+	rte_pktmbuf_free(env.mbuf);
+
+	return ret;
+}
+
+#ifdef USE_JANSSON
+static int
+fips_test_json_init_writeback(void)
+{
+	json_t *session_info, *session_write;
+	session_info = json_array_get(json_info.json_root, 0);
+	session_write = json_object();
+	json_info.json_write_root = json_array();
+
+	json_object_set(session_write, "jwt",
+		json_object_get(session_info, "jwt"));
+	json_object_set(session_write, "url",
+		json_object_get(session_info, "url"));
+	json_object_set(session_write, "isSample",
+		json_object_get(session_info, "isSample"));
+
+	json_info.is_sample = json_boolean_value(
+		json_object_get(session_info, "isSample"));
+
+	json_array_append_new(json_info.json_write_root, session_write);
+	return 0;
+}
+
+static int
+fips_test_one_test_case(void)
+{
+	int ret;
+
+	ret = fips_test_parse_one_json_case();
+
+	switch (ret) {
+	case 0:
+		ret = test_ops.test();
+		if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP))
+			break;
+		RTE_LOG(ERR, USER1, "Error %i: test block\n",
+				ret);
+		break;
+	default:
+		RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
+				ret);
+	}
+	return ret;
+}
+
+static int
+fips_test_one_test_group(void)
+{
+	int ret;
+	json_t *tests, *write_tests;
+	size_t test_idx, tests_size;
+
+	write_tests = json_array();
+	json_info.json_write_group = json_object();
+	json_object_set(json_info.json_write_group, "tgId",
+		json_object_get(json_info.json_test_group, "tgId"));
+	json_object_set_new(json_info.json_write_group, "tests", write_tests);
+
+	switch (info.algo) {
+	case FIPS_TEST_ALGO_AES_GMAC:
+	case FIPS_TEST_ALGO_AES_GCM:
+		ret = parse_test_gcm_json_init();
+		break;
+	case FIPS_TEST_ALGO_AES_CCM:
+		ret = parse_test_ccm_json_init();
+		break;
+	case FIPS_TEST_ALGO_HMAC:
+		ret = parse_test_hmac_json_init();
+		break;
+	case FIPS_TEST_ALGO_AES_CMAC:
+		ret = parse_test_cmac_json_init();
+		break;
+	case FIPS_TEST_ALGO_AES_XTS:
+		ret = parse_test_xts_json_init();
+		break;
+	case FIPS_TEST_ALGO_AES_CBC:
+	case FIPS_TEST_ALGO_AES_CTR:
+	case FIPS_TEST_ALGO_AES:
+		ret = parse_test_aes_json_init();
+		break;
+	case FIPS_TEST_ALGO_SHA:
+		ret = parse_test_sha_json_init();
+		break;
+	case FIPS_TEST_ALGO_TDES:
+		ret = parse_test_tdes_json_init();
+		break;
+	case FIPS_TEST_ALGO_RSA:
+		ret = parse_test_rsa_json_init();
+		break;
+	case FIPS_TEST_ALGO_ECDSA:
+		ret = parse_test_ecdsa_json_init();
+		break;
+	case FIPS_TEST_ALGO_EDDSA:
+		ret = parse_test_eddsa_json_init();
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (ret < 0)
+		return ret;
+
+	ret = fips_test_parse_one_json_group();
+	if (ret < 0)
+		return ret;
+
+	ret = init_test_ops();
+	if (ret < 0)
+		return ret;
+
+	tests = json_object_get(json_info.json_test_group, "tests");
+	tests_size = json_array_size(tests);
+	for (test_idx = 0; test_idx < tests_size; test_idx++) {
+		json_info.json_test_case = json_array_get(tests, test_idx);
+		if (fips_test_one_test_case() == 0)
+			json_array_append_new(write_tests, json_info.json_write_case);
+	}
+
+	return 0;
+}
+
+static int
+fips_test_one_vector_set(void)
+{
+	int ret;
+	json_t *test_groups, *write_groups, *write_version, *write_set, *mode;
+	size_t group_idx, num_groups;
+
+	test_groups = json_object_get(json_info.json_vector_set, "testGroups");
+	num_groups = json_array_size(test_groups);
+
+	json_info.json_write_set = json_array();
+	write_version = json_object();
+	json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION));
+	json_array_append_new(json_info.json_write_set, write_version);
+
+	write_set = json_object();
+	json_array_append(json_info.json_write_set, write_set);
+	write_groups = json_array();
+
+	json_object_set(write_set, "vsId",
+		json_object_get(json_info.json_vector_set, "vsId"));
+	json_object_set(write_set, "algorithm",
+		json_object_get(json_info.json_vector_set, "algorithm"));
+	mode = json_object_get(json_info.json_vector_set, "mode");
+	if (mode != NULL)
+		json_object_set_new(write_set, "mode", mode);
+
+	json_object_set(write_set, "revision",
+		json_object_get(json_info.json_vector_set, "revision"));
+	json_object_set_new(write_set, "isSample",
+		json_boolean(json_info.is_sample));
+	json_object_set_new(write_set, "testGroups", write_groups);
+
+	ret = fips_test_parse_one_json_vector_set();
+	if (ret < 0) {
+		RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n",
+			json_string_value(json_object_get(json_info.json_vector_set, "algorithm")));
+		return ret;
+	}
+
+	for (group_idx = 0; group_idx < num_groups; group_idx++) {
+		json_info.json_test_group = json_array_get(test_groups, group_idx);
+		ret = fips_test_one_test_group();
+		json_array_append_new(write_groups, json_info.json_write_group);
+	}
+
+	return 0;
+}
+
+static int
+fips_test_one_json_file(void)
+{
+	size_t vector_set_idx, root_size;
+
+	root_size = json_array_size(json_info.json_root);
+	fips_test_json_init_writeback();
+
+	for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) {
+		/* Vector set index starts at 1, the 0th index contains test session
+		 * information.
+		 */
+		json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx);
+		fips_test_one_vector_set();
+		json_array_append_new(json_info.json_write_root, json_info.json_write_set);
+		json_incref(json_info.json_write_set);
+	}
+
+	json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4));
+	json_decref(json_info.json_write_root);
+
+	return 0;
+}
+#endif /* USE_JANSSON */
diff --git a/examples/fips_validation/main.c b/examples/fips_validation/main.c
index f21826e9d7..daf273bc85 100644
--- a/examples/fips_validation/main.c
+++ b/examples/fips_validation/main.c
@@ -882,8 +882,8 @@ get_hash_oid(enum rte_crypto_auth_algorithm hash, uint8_t *buf)
 	uint8_t id_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
 				0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
 				0x00, 0x04, 0x14};
-	uint8_t *id = NULL;
-	int id_len = 0;
+	const uint8_t *id;
+	size_t id_len;
 
 	switch (hash) {
 	case RTE_CRYPTO_AUTH_SHA1:
@@ -907,12 +907,10 @@ get_hash_oid(enum rte_crypto_auth_algorithm hash, uint8_t *buf)
 		id_len = sizeof(id_sha512);
 		break;
 	default:
-		id_len = -1;
-		break;
+		return -1;
 	}
 
-	if (id != NULL)
-		rte_memcpy(buf, id, id_len);
+	memcpy(buf, id, id_len);
 
 	return id_len;
 }
@@ -1614,8 +1612,8 @@ prepare_rsa_xform(struct rte_crypto_asym_xform *xform)
 			if (b_len) {
 				msg.len = env.digest_len + b_len;
 				msg.val = rte_zmalloc(NULL, msg.len, 0);
-				rte_memcpy(msg.val, b, b_len);
-				rte_memcpy(msg.val + b_len, env.digest, env.digest_len);
+				memcpy(msg.val, b, b_len);
+				memcpy(msg.val + b_len, env.digest, env.digest_len);
 				rte_free(env.digest);
 				env.digest = msg.val;
 				env.digest_len = msg.len;
-- 
2.51.0


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

end of thread, other threads:[~2025-12-28 18:46 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-28 18:40 [PATCH 0/7] Fix build with gcc-16 Stephen Hemminger
2025-12-28 18:40 ` [PATCH 1/7] pcapng: use alloca instead of fixed buffer Stephen Hemminger
2025-12-28 18:40 ` [PATCH 2/7] pcapng: add additional mbuf if space required on copy Stephen Hemminger
2025-12-28 18:40 ` [PATCH 3/7] test: add more tests for comments in pcapng Stephen Hemminger
2025-12-28 18:40 ` [PATCH 4/7] test: vary size of packets in pcapng test Stephen Hemminger
2025-12-28 18:40 ` [PATCH 5/7] net/bnxt: fix uninitialized warning Stephen Hemminger
2025-12-28 18:40 ` [PATCH 6/7] common/cnxk: fix array out of bounds Stephen Hemminger
2025-12-28 18:40 ` [PATCH 7/7] examples/fips_validation: avoid rte_memcpy alignment restriction Stephen Hemminger

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).