xref: /dpdk/examples/fips_validation/main.c (revision 733c7861492d67eb5fba8ee50fb08d7db82a176d)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation
3  */
4 
5 #include <sys/stat.h>
6 #include <getopt.h>
7 #include <dirent.h>
8 #include <stdlib.h>
9 
10 #include <rte_cryptodev.h>
11 #include <rte_malloc.h>
12 #include <rte_mempool.h>
13 #include <rte_mbuf.h>
14 #include <rte_string_fns.h>
15 #include <rte_random.h>
16 
17 #include "fips_validation.h"
18 #include "fips_dev_self_test.h"
19 
20 enum {
21 #define OPT_REQ_FILE_PATH           "req-file"
22 	OPT_REQ_FILE_PATH_NUM = 256,
23 #define OPT_RSP_FILE_PATH           "rsp-file"
24 	OPT_RSP_FILE_PATH_NUM,
25 #define OPT_MBUF_DATAROOM           "mbuf-dataroom"
26 	OPT_MBUF_DATAROOM_NUM,
27 #define OPT_FOLDER                  "path-is-folder"
28 	OPT_FOLDER_NUM,
29 #define OPT_CRYPTODEV               "cryptodev"
30 	OPT_CRYPTODEV_NUM,
31 #define OPT_CRYPTODEV_ID            "cryptodev-id"
32 	OPT_CRYPTODEV_ID_NUM,
33 #define OPT_CRYPTODEV_ST            "self-test"
34 	OPT_CRYPTODEV_ST_NUM,
35 #define OPT_CRYPTODEV_BK_ID         "broken-test-id"
36 	OPT_CRYPTODEV_BK_ID_NUM,
37 #define OPT_CRYPTODEV_BK_DIR_KEY    "broken-test-dir"
38 	OPT_CRYPTODEV_BK_DIR_KEY_NUM,
39 #define OPT_USE_JSON                "use-json"
40 	OPT_USE_JSON_NUM,
41 #define OPT_CRYPTODEV_ASYM          "asymmetric"
42 	OPT_CRYPTODEV_ASYM_NUM,
43 };
44 
45 struct fips_test_vector vec;
46 struct fips_test_interim_info info;
47 
48 #ifdef USE_JANSSON
49 struct fips_test_json_info json_info;
50 #endif /* USE_JANSSON */
51 
52 struct cryptodev_fips_validate_env {
53 	const char *req_path;
54 	const char *rsp_path;
55 	uint32_t is_path_folder;
56 	uint8_t dev_id;
57 	struct rte_mempool *mpool;
58 	struct fips_sym_env {
59 		struct rte_mempool *sess_mpool;
60 		struct rte_mempool *op_pool;
61 		struct rte_cryptodev_sym_session *sess;
62 		struct rte_crypto_op *op;
63 	} sym;
64 	struct fips_asym_env {
65 		struct rte_mempool *sess_mpool;
66 		struct rte_mempool *op_pool;
67 		struct rte_cryptodev_asym_session *sess;
68 		struct rte_crypto_op *op;
69 	} asym;
70 	struct rte_crypto_op *op;
71 	uint8_t dev_support_sgl;
72 	uint16_t mbuf_data_room;
73 	struct rte_mbuf *mbuf;
74 	uint8_t *digest;
75 	uint16_t digest_len;
76 	bool is_asym_test;
77 	uint16_t self_test;
78 	struct fips_dev_broken_test_config *broken_test_config;
79 } env;
80 
81 static int
82 cryptodev_fips_validate_app_sym_init(void)
83 {
84 	uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size(
85 							env.dev_id);
86 	struct rte_cryptodev_info dev_info;
87 	struct fips_sym_env *sym = &env.sym;
88 	int ret;
89 
90 	rte_cryptodev_info_get(env.dev_id, &dev_info);
91 	if (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)
92 		env.dev_support_sgl = 1;
93 	else
94 		env.dev_support_sgl = 0;
95 
96 	ret = -ENOMEM;
97 	sym->sess_mpool = rte_cryptodev_sym_session_pool_create(
98 			"FIPS_SYM_SESS_MEMPOOL", 16, sess_sz, 0, 0, rte_socket_id());
99 	if (!sym->sess_mpool)
100 		goto error_exit;
101 
102 	sym->op_pool = rte_crypto_op_pool_create(
103 			"FIPS_OP_SYM_POOL",
104 			RTE_CRYPTO_OP_TYPE_SYMMETRIC,
105 			1, 0,
106 			16,
107 			rte_socket_id());
108 	if (!sym->op_pool)
109 		goto error_exit;
110 
111 	sym->op = rte_crypto_op_alloc(sym->op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
112 	if (!sym->op)
113 		goto error_exit;
114 
115 	return 0;
116 
117 error_exit:
118 	rte_mempool_free(sym->sess_mpool);
119 	rte_mempool_free(sym->op_pool);
120 	return ret;
121 }
122 
123 static void
124 cryptodev_fips_validate_app_sym_uninit(void)
125 {
126 	struct fips_sym_env *sym = &env.sym;
127 
128 	rte_pktmbuf_free(env.mbuf);
129 	rte_crypto_op_free(sym->op);
130 	rte_cryptodev_sym_session_free(env.dev_id, sym->sess);
131 	rte_mempool_free(sym->sess_mpool);
132 	rte_mempool_free(sym->op_pool);
133 }
134 
135 static int
136 cryptodev_fips_validate_app_asym_init(void)
137 {
138 	struct fips_asym_env *asym = &env.asym;
139 	int ret;
140 
141 	ret = -ENOMEM;
142 	asym->sess_mpool = rte_cryptodev_asym_session_pool_create(
143 			"FIPS_ASYM_SESS_MEMPOOL", 16, 0, 0, rte_socket_id());
144 	if (!asym->sess_mpool)
145 		goto error_exit;
146 
147 	asym->op_pool = rte_crypto_op_pool_create(
148 			"FIPS_OP_ASYM_POOL",
149 			RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
150 			1, 0,
151 			16,
152 			rte_socket_id());
153 	if (!asym->op_pool)
154 		goto error_exit;
155 
156 	asym->op = rte_crypto_op_alloc(asym->op_pool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
157 	if (!asym->op)
158 		goto error_exit;
159 
160 	return 0;
161 
162 error_exit:
163 	rte_mempool_free(asym->sess_mpool);
164 	rte_mempool_free(asym->op_pool);
165 	return ret;
166 }
167 
168 static void
169 cryptodev_fips_validate_app_asym_uninit(void)
170 {
171 	struct fips_asym_env *asym = &env.asym;
172 
173 	rte_crypto_op_free(asym->op);
174 	rte_cryptodev_asym_session_free(env.dev_id, asym->sess);
175 	rte_mempool_free(asym->sess_mpool);
176 	rte_mempool_free(asym->op_pool);
177 }
178 
179 static int
180 cryptodev_fips_validate_app_init(void)
181 {
182 	struct rte_cryptodev_config conf = {rte_socket_id(), 1, 0};
183 	struct rte_cryptodev_qp_conf qp_conf = {128, NULL};
184 	uint32_t nb_mbufs = UINT16_MAX / env.mbuf_data_room + 1;
185 	int ret;
186 
187 	if (env.self_test) {
188 		ret = fips_dev_self_test(env.dev_id, env.broken_test_config);
189 		if (ret < 0) {
190 			rte_cryptodev_stop(env.dev_id);
191 			rte_cryptodev_close(env.dev_id);
192 
193 			return ret;
194 		}
195 	}
196 
197 	ret = rte_cryptodev_configure(env.dev_id, &conf);
198 	if (ret < 0)
199 		return ret;
200 
201 	ret = -ENOMEM;
202 	env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", nb_mbufs,
203 			0, 0, sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM +
204 			env.mbuf_data_room, rte_socket_id());
205 	if (!env.mpool)
206 		return ret;
207 
208 	ret = cryptodev_fips_validate_app_sym_init();
209 	if (ret < 0)
210 		goto error_exit;
211 
212 	if (env.is_asym_test) {
213 		ret = cryptodev_fips_validate_app_asym_init();
214 		if (ret < 0)
215 			goto error_exit;
216 	}
217 
218 	qp_conf.mp_session = env.sym.sess_mpool;
219 
220 	ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
221 			rte_socket_id());
222 	if (ret < 0)
223 		goto error_exit;
224 
225 	ret = rte_cryptodev_start(env.dev_id);
226 	if (ret < 0)
227 		goto error_exit;
228 
229 	return 0;
230 
231 error_exit:
232 	rte_mempool_free(env.mpool);
233 	return ret;
234 }
235 
236 static void
237 cryptodev_fips_validate_app_uninit(void)
238 {
239 	cryptodev_fips_validate_app_sym_uninit();
240 
241 	if (env.is_asym_test)
242 		cryptodev_fips_validate_app_asym_uninit();
243 
244 	rte_mempool_free(env.mpool);
245 	rte_cryptodev_stop(env.dev_id);
246 	rte_cryptodev_close(env.dev_id);
247 }
248 
249 static int
250 fips_test_one_file(void);
251 
252 #ifdef USE_JANSSON
253 static int
254 fips_test_one_json_file(void);
255 #endif /* USE_JANSSON */
256 
257 static int
258 parse_cryptodev_arg(char *arg)
259 {
260 	int id = rte_cryptodev_get_dev_id(arg);
261 
262 	if (id < 0) {
263 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev name %s\n",
264 				id, arg);
265 		return id;
266 	}
267 
268 	env.dev_id = (uint8_t)id;
269 
270 	return 0;
271 }
272 
273 static int
274 parse_cryptodev_id_arg(char *arg)
275 {
276 	uint32_t cryptodev_id;
277 
278 	if (parser_read_uint32(&cryptodev_id, arg) < 0) {
279 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n",
280 				-EINVAL, arg);
281 		return -1;
282 	}
283 
284 
285 	if (!rte_cryptodev_is_valid_dev(cryptodev_id)) {
286 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n",
287 				cryptodev_id, arg);
288 		return -1;
289 	}
290 
291 	env.dev_id = (uint8_t)cryptodev_id;
292 
293 	return 0;
294 }
295 
296 static void
297 cryptodev_fips_validate_usage(const char *prgname)
298 {
299 	uint32_t def_mbuf_seg_size = DEF_MBUF_SEG_SIZE;
300 	printf("%s [EAL options] --\n"
301 		"  --%s: REQUEST-FILE-PATH\n"
302 		"  --%s: RESPONSE-FILE-PATH\n"
303 		"  --%s: indicating both paths are folders\n"
304 		"  --%s: mbuf dataroom size (default %u bytes)\n"
305 		"  --%s: CRYPTODEV-NAME\n"
306 		"  --%s: CRYPTODEV-ID-NAME\n"
307 		"  --%s: self test indicator\n"
308 		"  --%s: self broken test ID\n"
309 		"  --%s: self broken test direction\n",
310 		prgname, OPT_REQ_FILE_PATH, OPT_RSP_FILE_PATH,
311 		OPT_FOLDER, OPT_MBUF_DATAROOM, def_mbuf_seg_size,
312 		OPT_CRYPTODEV, OPT_CRYPTODEV_ID, OPT_CRYPTODEV_ST,
313 		OPT_CRYPTODEV_BK_ID, OPT_CRYPTODEV_BK_DIR_KEY);
314 }
315 
316 static int
317 cryptodev_fips_validate_parse_args(int argc, char **argv)
318 {
319 	int opt, ret;
320 	char *prgname = argv[0];
321 	char **argvopt;
322 	int option_index;
323 	struct option lgopts[] = {
324 		{OPT_REQ_FILE_PATH, required_argument,
325 				NULL, OPT_REQ_FILE_PATH_NUM},
326 		{OPT_RSP_FILE_PATH, required_argument,
327 				NULL, OPT_RSP_FILE_PATH_NUM},
328 		{OPT_FOLDER, no_argument,
329 				NULL, OPT_FOLDER_NUM},
330 		{OPT_MBUF_DATAROOM, required_argument,
331 				NULL, OPT_MBUF_DATAROOM_NUM},
332 		{OPT_CRYPTODEV, required_argument,
333 				NULL, OPT_CRYPTODEV_NUM},
334 		{OPT_CRYPTODEV_ID, required_argument,
335 				NULL, OPT_CRYPTODEV_ID_NUM},
336 		{OPT_CRYPTODEV_ST, no_argument,
337 				NULL, OPT_CRYPTODEV_ST_NUM},
338 		{OPT_CRYPTODEV_BK_ID, required_argument,
339 				NULL, OPT_CRYPTODEV_BK_ID_NUM},
340 		{OPT_CRYPTODEV_BK_DIR_KEY, required_argument,
341 				NULL, OPT_CRYPTODEV_BK_DIR_KEY_NUM},
342 		{OPT_CRYPTODEV_ASYM, no_argument,
343 				NULL, OPT_CRYPTODEV_ASYM_NUM},
344 		{NULL, 0, 0, 0}
345 	};
346 
347 	argvopt = argv;
348 
349 	env.mbuf_data_room = DEF_MBUF_SEG_SIZE;
350 	if (rte_cryptodev_count())
351 		env.dev_id = 0;
352 	else {
353 		cryptodev_fips_validate_usage(prgname);
354 		return -EINVAL;
355 	}
356 
357 	while ((opt = getopt_long(argc, argvopt, "s:",
358 				  lgopts, &option_index)) != EOF) {
359 
360 		switch (opt) {
361 		case OPT_REQ_FILE_PATH_NUM:
362 			env.req_path = optarg;
363 			break;
364 
365 		case OPT_RSP_FILE_PATH_NUM:
366 			env.rsp_path = optarg;
367 			break;
368 
369 		case OPT_FOLDER_NUM:
370 			env.is_path_folder = 1;
371 			break;
372 
373 		case OPT_CRYPTODEV_NUM:
374 			ret = parse_cryptodev_arg(optarg);
375 			if (ret < 0) {
376 				cryptodev_fips_validate_usage(prgname);
377 				return -EINVAL;
378 			}
379 			break;
380 
381 		case OPT_CRYPTODEV_ID_NUM:
382 			ret = parse_cryptodev_id_arg(optarg);
383 			if (ret < 0) {
384 				cryptodev_fips_validate_usage(prgname);
385 				return -EINVAL;
386 			}
387 			break;
388 
389 		case OPT_CRYPTODEV_ST_NUM:
390 			env.self_test = 1;
391 			break;
392 
393 		case OPT_CRYPTODEV_BK_ID_NUM:
394 			if (!env.broken_test_config) {
395 				env.broken_test_config = rte_malloc(
396 					NULL,
397 					sizeof(*env.broken_test_config),
398 					0);
399 				if (!env.broken_test_config)
400 					return -ENOMEM;
401 
402 				env.broken_test_config->expect_fail_dir =
403 					self_test_dir_enc_auth_gen;
404 			}
405 
406 			if (parser_read_uint32(
407 				&env.broken_test_config->expect_fail_test_idx,
408 					optarg) < 0) {
409 				rte_free(env.broken_test_config);
410 				cryptodev_fips_validate_usage(prgname);
411 				return -EINVAL;
412 			}
413 			break;
414 
415 		case OPT_CRYPTODEV_BK_DIR_KEY_NUM:
416 			if (!env.broken_test_config) {
417 				env.broken_test_config = rte_malloc(
418 					NULL,
419 					sizeof(*env.broken_test_config),
420 					0);
421 				if (!env.broken_test_config)
422 					return -ENOMEM;
423 
424 				env.broken_test_config->expect_fail_test_idx =
425 					0;
426 			}
427 
428 			if (strcmp(optarg, "enc") == 0)
429 				env.broken_test_config->expect_fail_dir =
430 					self_test_dir_enc_auth_gen;
431 			else if (strcmp(optarg, "dec")
432 					== 0)
433 				env.broken_test_config->expect_fail_dir =
434 					self_test_dir_dec_auth_verify;
435 			else {
436 				rte_free(env.broken_test_config);
437 				cryptodev_fips_validate_usage(prgname);
438 				return -EINVAL;
439 			}
440 			break;
441 
442 
443 		case OPT_MBUF_DATAROOM_NUM:
444 			if (parser_read_uint16(&env.mbuf_data_room,
445 					optarg) < 0) {
446 				cryptodev_fips_validate_usage(prgname);
447 				return -EINVAL;
448 			}
449 
450 			if (env.mbuf_data_room == 0) {
451 				cryptodev_fips_validate_usage(prgname);
452 				return -EINVAL;
453 			}
454 			break;
455 
456 		case OPT_CRYPTODEV_ASYM_NUM:
457 			env.is_asym_test = true;
458 			break;
459 
460 		default:
461 			cryptodev_fips_validate_usage(prgname);
462 			return -EINVAL;
463 		}
464 	}
465 
466 	if ((env.req_path == NULL && env.rsp_path != NULL) ||
467 			(env.req_path != NULL && env.rsp_path == NULL)) {
468 		RTE_LOG(ERR, USER1, "Missing req path or rsp path\n");
469 		cryptodev_fips_validate_usage(prgname);
470 		return -EINVAL;
471 	}
472 
473 	if (env.req_path == NULL && env.self_test == 0) {
474 		RTE_LOG(ERR, USER1, "--self-test must be set if req path is missing\n");
475 		cryptodev_fips_validate_usage(prgname);
476 		return -EINVAL;
477 	}
478 
479 	return 0;
480 }
481 
482 int
483 main(int argc, char *argv[])
484 {
485 	int ret;
486 
487 	ret = rte_eal_init(argc, argv);
488 	if (ret < 0) {
489 		RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret);
490 		return -1;
491 	}
492 
493 	argc -= ret;
494 	argv += ret;
495 
496 	ret = cryptodev_fips_validate_parse_args(argc, argv);
497 	if (ret < 0)
498 		rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n");
499 
500 	ret = cryptodev_fips_validate_app_init();
501 	if (ret < 0) {
502 		RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret);
503 		return -1;
504 	}
505 
506 	if (env.req_path == NULL || env.rsp_path == NULL) {
507 		printf("No request, exit.\n");
508 		goto exit;
509 	}
510 
511 	if (!env.is_path_folder) {
512 		printf("Processing file %s... ", env.req_path);
513 
514 		ret = fips_test_init(env.req_path, env.rsp_path,
515 			rte_cryptodev_name_get(env.dev_id));
516 		if (ret < 0) {
517 			RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
518 					ret, env.req_path);
519 			goto exit;
520 		}
521 
522 #ifdef USE_JANSSON
523 		if (info.file_type == FIPS_TYPE_JSON) {
524 			ret = fips_test_one_json_file();
525 			json_decref(json_info.json_root);
526 		}  else {
527 			ret = fips_test_one_file();
528 		}
529 #else /* USE_JANSSON */
530 		ret = fips_test_one_file();
531 #endif /* USE_JANSSON */
532 
533 		if (ret < 0) {
534 			RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
535 					ret, env.req_path);
536 			goto exit;
537 		}
538 
539 		printf("Done\n");
540 
541 	} else {
542 		struct dirent *dir;
543 		DIR *d_req, *d_rsp;
544 		char req_path[1024];
545 		char rsp_path[1024];
546 
547 		d_req = opendir(env.req_path);
548 		if (!d_req) {
549 			RTE_LOG(ERR, USER1, "Error %i: Path %s not exist\n",
550 					-EINVAL, env.req_path);
551 			goto exit;
552 		}
553 
554 		d_rsp = opendir(env.rsp_path);
555 		if (!d_rsp) {
556 			ret = mkdir(env.rsp_path, 0700);
557 			if (ret == 0)
558 				d_rsp = opendir(env.rsp_path);
559 			else {
560 				RTE_LOG(ERR, USER1, "Error %i: Invalid %s\n",
561 						-EINVAL, env.rsp_path);
562 				goto exit;
563 			}
564 		}
565 		closedir(d_rsp);
566 
567 		while ((dir = readdir(d_req)) != NULL) {
568 			if (strstr(dir->d_name, "req") == NULL)
569 				continue;
570 
571 			snprintf(req_path, 1023, "%s/%s", env.req_path,
572 					dir->d_name);
573 			snprintf(rsp_path, 1023, "%s/%s", env.rsp_path,
574 					dir->d_name);
575 			strlcpy(strstr(rsp_path, "req"), "rsp", 4);
576 
577 			printf("Processing file %s... ", req_path);
578 
579 			ret = fips_test_init(req_path, rsp_path,
580 			rte_cryptodev_name_get(env.dev_id));
581 			if (ret < 0) {
582 				RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
583 						ret, req_path);
584 				break;
585 			}
586 
587 #ifdef USE_JANSSON
588 			if (info.file_type == FIPS_TYPE_JSON) {
589 				ret = fips_test_one_json_file();
590 				json_decref(json_info.json_root);
591 			} else {
592 				ret = fips_test_one_file();
593 			}
594 #else /* USE_JANSSON */
595 			ret = fips_test_one_file();
596 #endif /* USE_JANSSON */
597 
598 			if (ret < 0) {
599 				RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
600 						ret, req_path);
601 				break;
602 			}
603 
604 			printf("Done\n");
605 		}
606 
607 		closedir(d_req);
608 	}
609 
610 
611 exit:
612 	fips_test_clear();
613 	cryptodev_fips_validate_app_uninit();
614 
615 	/* clean up the EAL */
616 	rte_eal_cleanup();
617 
618 	return ret;
619 
620 }
621 
622 #define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
623 #define CRYPTODEV_FIPS_MAX_RETRIES	16
624 
625 struct fips_test_ops test_ops;
626 
627 static int
628 prepare_data_mbufs(struct fips_val *val)
629 {
630 	struct rte_mbuf *m, *head = 0;
631 	uint8_t *src = val->val;
632 	uint32_t total_len = val->len;
633 	uint16_t nb_seg;
634 	int ret = 0;
635 
636 	rte_pktmbuf_free(env.mbuf);
637 
638 	if (total_len > RTE_MBUF_MAX_NB_SEGS) {
639 		RTE_LOG(ERR, USER1, "Data len %u too big\n", total_len);
640 		return -EPERM;
641 	}
642 
643 	nb_seg = total_len / env.mbuf_data_room;
644 	if (total_len % env.mbuf_data_room)
645 		nb_seg++;
646 
647 	m = rte_pktmbuf_alloc(env.mpool);
648 	if (!m) {
649 		RTE_LOG(ERR, USER1, "Error %i: Not enough mbuf\n",
650 				-ENOMEM);
651 		return -ENOMEM;
652 	}
653 	head = m;
654 
655 	while (nb_seg) {
656 		uint16_t len = RTE_MIN(total_len, env.mbuf_data_room);
657 		uint8_t *dst = (uint8_t *)rte_pktmbuf_append(m, len);
658 
659 		if (!dst) {
660 			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
661 					-ENOMEM);
662 			ret = -ENOMEM;
663 			goto error_exit;
664 		}
665 
666 		memcpy(dst, src, len);
667 
668 		if (head != m) {
669 			ret = rte_pktmbuf_chain(head, m);
670 			if (ret) {
671 				rte_pktmbuf_free(m);
672 				RTE_LOG(ERR, USER1, "Error %i: SGL build\n",
673 						ret);
674 				goto error_exit;
675 			}
676 		}
677 		total_len -= len;
678 
679 		if (total_len) {
680 			if (!env.dev_support_sgl) {
681 				RTE_LOG(ERR, USER1, "SGL not supported\n");
682 				ret = -EPERM;
683 				goto error_exit;
684 			}
685 
686 			m = rte_pktmbuf_alloc(env.mpool);
687 			if (!m) {
688 				RTE_LOG(ERR, USER1, "Error %i: No memory\n",
689 						-ENOMEM);
690 				goto error_exit;
691 			}
692 		} else
693 			break;
694 
695 		src += len;
696 		nb_seg--;
697 	}
698 
699 	if (total_len) {
700 		RTE_LOG(ERR, USER1, "Error %i: Failed to store all data\n",
701 				-ENOMEM);
702 		goto error_exit;
703 	}
704 
705 	env.mbuf = head;
706 
707 	return 0;
708 
709 error_exit:
710 	rte_pktmbuf_free(head);
711 	return ret;
712 }
713 
714 static int
715 prepare_cipher_op(void)
716 {
717 	struct rte_crypto_sym_op *sym = env.op->sym;
718 	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
719 	int ret;
720 
721 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
722 
723 	memcpy(iv, vec.iv.val, vec.iv.len);
724 
725 	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
726 		ret = prepare_data_mbufs(&vec.pt);
727 		if (ret < 0)
728 			return ret;
729 
730 		sym->cipher.data.length = vec.pt.len;
731 	} else {
732 		ret = prepare_data_mbufs(&vec.ct);
733 		if (ret < 0)
734 			return ret;
735 
736 		sym->cipher.data.length = vec.ct.len;
737 	}
738 
739 	rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
740 
741 	sym->m_src = env.mbuf;
742 	sym->cipher.data.offset = 0;
743 
744 	return 0;
745 }
746 
747 int
748 prepare_auth_op(void)
749 {
750 	struct rte_crypto_sym_op *sym = env.op->sym;
751 	int ret;
752 
753 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
754 
755 	if (info.interim_info.gcm_data.gen_iv == 1) {
756 		uint32_t i;
757 
758 		if (!vec.iv.val) {
759 			vec.iv.val = rte_malloc(0, vec.iv.len, 0);
760 			if (!vec.iv.val)
761 				return -ENOMEM;
762 		}
763 
764 		for (i = 0; i < vec.iv.len; i++) {
765 			int random = rte_rand();
766 			vec.iv.val[i] = (uint8_t)random;
767 		}
768 	}
769 
770 	if (vec.iv.len) {
771 		uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *,
772 				IV_OFF);
773 		memset(iv, 0, vec.iv.len);
774 		if (vec.iv.val)
775 			memcpy(iv, vec.iv.val, vec.iv.len);
776 	}
777 
778 	ret = prepare_data_mbufs(&vec.pt);
779 	if (ret < 0)
780 		return ret;
781 
782 	rte_free(env.digest);
783 
784 	env.digest = rte_zmalloc(NULL, vec.cipher_auth.digest.len,
785 			RTE_CACHE_LINE_SIZE);
786 	if (!env.digest) {
787 		RTE_LOG(ERR, USER1, "Not enough memory\n");
788 		return -ENOMEM;
789 	}
790 	env.digest_len = vec.cipher_auth.digest.len;
791 
792 	sym->m_src = env.mbuf;
793 	sym->auth.data.offset = 0;
794 	sym->auth.data.length = vec.pt.len;
795 	sym->auth.digest.data = env.digest;
796 	sym->auth.digest.phys_addr = rte_malloc_virt2iova(env.digest);
797 
798 	if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
799 		memcpy(env.digest, vec.cipher_auth.digest.val,
800 				vec.cipher_auth.digest.len);
801 
802 	rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
803 
804 	return 0;
805 }
806 
807 int
808 prepare_aead_op(void)
809 {
810 	struct rte_crypto_sym_op *sym = env.op->sym;
811 	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
812 	int ret;
813 
814 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
815 
816 	if (info.algo == FIPS_TEST_ALGO_AES_CCM)
817 		iv++;
818 
819 	if (vec.iv.val)
820 		memcpy(iv, vec.iv.val, vec.iv.len);
821 	else
822 		/* if REQ file has iv length but not data, default as all 0 */
823 		memset(iv, 0, vec.iv.len);
824 
825 	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
826 		ret = prepare_data_mbufs(&vec.pt);
827 		if (ret < 0)
828 			return ret;
829 
830 		rte_free(env.digest);
831 		env.digest = rte_zmalloc(NULL, vec.aead.digest.len,
832 				RTE_CACHE_LINE_SIZE);
833 		if (!env.digest) {
834 			RTE_LOG(ERR, USER1, "Not enough memory\n");
835 			return -ENOMEM;
836 		}
837 		env.digest_len = vec.aead.digest.len;
838 
839 		sym->aead.data.length = vec.pt.len;
840 		sym->aead.digest.data = env.digest;
841 		sym->aead.digest.phys_addr = rte_malloc_virt2iova(env.digest);
842 	} else {
843 		ret = prepare_data_mbufs(&vec.ct);
844 		if (ret < 0)
845 			return ret;
846 		env.digest_len = vec.aead.digest.len;
847 		sym->aead.data.length = vec.ct.len;
848 		sym->aead.digest.data = vec.aead.digest.val;
849 		sym->aead.digest.phys_addr = rte_malloc_virt2iova(
850 				sym->aead.digest.data);
851 	}
852 
853 	sym->m_src = env.mbuf;
854 	sym->aead.data.offset = 0;
855 	sym->aead.aad.data = vec.aead.aad.val;
856 	sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data);
857 
858 	rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
859 
860 	return 0;
861 }
862 
863 static int
864 get_hash_oid(enum rte_crypto_auth_algorithm hash, uint8_t *buf)
865 {
866 	uint8_t id_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
867 				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
868 				  0x04, 0x02, 0x03, 0x05, 0x00, 0x04,
869 				  0x40};
870 	uint8_t id_sha384[] = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
871 				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
872 				  0x04, 0x02, 0x02, 0x05, 0x00, 0x04,
873 				  0x30};
874 	uint8_t id_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
875 				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
876 				  0x04, 0x02, 0x01, 0x05, 0x00, 0x04,
877 				  0x20};
878 	uint8_t id_sha224[] = {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
879 				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
880 				  0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
881 				  0x1c};
882 	uint8_t id_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
883 				0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
884 				0x00, 0x04, 0x14};
885 	uint8_t *id = NULL;
886 	int id_len = 0;
887 
888 	switch (hash) {
889 	case RTE_CRYPTO_AUTH_SHA1:
890 		id = id_sha1;
891 		id_len = sizeof(id_sha1);
892 		break;
893 	case RTE_CRYPTO_AUTH_SHA224:
894 		id = id_sha224;
895 		id_len = sizeof(id_sha224);
896 		break;
897 	case RTE_CRYPTO_AUTH_SHA256:
898 		id = id_sha256;
899 		id_len = sizeof(id_sha256);
900 		break;
901 	case RTE_CRYPTO_AUTH_SHA384:
902 		id = id_sha384;
903 		id_len = sizeof(id_sha384);
904 		break;
905 	case RTE_CRYPTO_AUTH_SHA512:
906 		id = id_sha512;
907 		id_len = sizeof(id_sha512);
908 		break;
909 	default:
910 		id_len = -1;
911 		break;
912 	}
913 
914 	if (id != NULL)
915 		rte_memcpy(buf, id, id_len);
916 
917 	return id_len;
918 }
919 
920 static int
921 prepare_rsa_op(void)
922 {
923 	struct rte_crypto_asym_op *asym;
924 	struct fips_val msg;
925 
926 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
927 
928 	asym = env.op->asym;
929 	if (env.digest) {
930 		msg.val = env.digest;
931 		msg.len = env.digest_len;
932 	} else {
933 		msg.val = vec.pt.val;
934 		msg.len = vec.pt.len;
935 	}
936 
937 	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
938 		asym->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
939 		asym->rsa.message.data = msg.val;
940 		asym->rsa.message.length = msg.len;
941 
942 		rte_free(vec.rsa.signature.val);
943 
944 		vec.rsa.signature.val = rte_zmalloc(NULL, vec.rsa.n.len, 0);
945 		vec.rsa.signature.len = vec.rsa.n.len;
946 		asym->rsa.sign.data = vec.rsa.signature.val;
947 		asym->rsa.sign.length = 0;
948 	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
949 		asym->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
950 		asym->rsa.message.data = msg.val;
951 		asym->rsa.message.length = msg.len;
952 		asym->rsa.sign.data = vec.rsa.signature.val;
953 		asym->rsa.sign.length = vec.rsa.signature.len;
954 	} else {
955 		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
956 		return -EINVAL;
957 	}
958 
959 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
960 
961 	return 0;
962 }
963 
964 static int
965 prepare_ecdsa_op(void)
966 {
967 	struct rte_crypto_asym_op *asym;
968 	struct fips_val msg;
969 
970 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
971 
972 	asym = env.op->asym;
973 	if (env.digest) {
974 		msg.val = env.digest;
975 		msg.len = env.digest_len;
976 	} else {
977 		msg.val = vec.pt.val;
978 		msg.len = vec.pt.len;
979 	}
980 
981 	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
982 		asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
983 		asym->ecdsa.message.data = msg.val;
984 		asym->ecdsa.message.length = msg.len;
985 		asym->ecdsa.k.data = vec.ecdsa.k.val;
986 		asym->ecdsa.k.length = vec.ecdsa.k.len;
987 
988 		rte_free(vec.ecdsa.r.val);
989 
990 		rte_free(vec.ecdsa.s.val);
991 
992 		vec.ecdsa.r.len = info.interim_info.ecdsa_data.curve_len;
993 		vec.ecdsa.r.val = rte_zmalloc(NULL, vec.ecdsa.r.len, 0);
994 
995 		vec.ecdsa.s.len = vec.ecdsa.r.len;
996 		vec.ecdsa.s.val = rte_zmalloc(NULL, vec.ecdsa.s.len, 0);
997 
998 		asym->ecdsa.r.data = vec.ecdsa.r.val;
999 		asym->ecdsa.r.length = 0;
1000 		asym->ecdsa.s.data = vec.ecdsa.s.val;
1001 		asym->ecdsa.s.length = 0;
1002 	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
1003 		asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
1004 		asym->ecdsa.message.data = msg.val;
1005 		asym->ecdsa.message.length = msg.len;
1006 		asym->ecdsa.r.data = vec.ecdsa.r.val;
1007 		asym->ecdsa.r.length = vec.ecdsa.r.len;
1008 		asym->ecdsa.s.data = vec.ecdsa.s.val;
1009 		asym->ecdsa.s.length = vec.ecdsa.s.len;
1010 	} else {
1011 		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
1012 		return -EINVAL;
1013 	}
1014 
1015 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
1016 
1017 	return 0;
1018 }
1019 
1020 static int
1021 prepare_eddsa_op(void)
1022 {
1023 	struct rte_crypto_asym_op *asym;
1024 	struct fips_val msg;
1025 
1026 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1027 
1028 	asym = env.op->asym;
1029 	if (env.digest) {
1030 		msg.val = env.digest;
1031 		msg.len = env.digest_len;
1032 	} else {
1033 		msg.val = vec.pt.val;
1034 		msg.len = vec.pt.len;
1035 	}
1036 
1037 	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
1038 		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
1039 		asym->eddsa.message.data = msg.val;
1040 		asym->eddsa.message.length = msg.len;
1041 		asym->eddsa.context.data = vec.eddsa.ctx.val;
1042 		asym->eddsa.context.length = vec.eddsa.ctx.len;
1043 
1044 		rte_free(vec.eddsa.sign.val);
1045 
1046 		vec.eddsa.sign.len = info.interim_info.eddsa_data.curve_len;
1047 		vec.eddsa.sign.val = rte_zmalloc(NULL, vec.eddsa.sign.len, 0);
1048 
1049 		asym->eddsa.sign.data = vec.eddsa.sign.val;
1050 		asym->eddsa.sign.length = 0;
1051 	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
1052 		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
1053 		asym->eddsa.message.data = msg.val;
1054 		asym->eddsa.message.length = msg.len;
1055 		asym->eddsa.sign.data = vec.eddsa.sign.val;
1056 		asym->eddsa.sign.length = vec.eddsa.sign.len;
1057 	} else {
1058 		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
1059 		return -EINVAL;
1060 	}
1061 
1062 	if (info.interim_info.eddsa_data.curve_id == RTE_CRYPTO_EC_GROUP_ED25519) {
1063 		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519;
1064 		if (info.interim_info.eddsa_data.prehash)
1065 			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519PH;
1066 		if (vec.eddsa.ctx.len > 0)
1067 			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519CTX;
1068 	} else {
1069 		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448;
1070 		if (info.interim_info.eddsa_data.prehash)
1071 			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448PH;
1072 	}
1073 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
1074 
1075 	return 0;
1076 }
1077 
1078 static int
1079 prepare_ecfpm_op(void)
1080 {
1081 	struct rte_crypto_asym_op *asym;
1082 
1083 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1084 
1085 	asym = env.op->asym;
1086 	asym->ecpm.scalar.data = vec.ecdsa.pkey.val;
1087 	asym->ecpm.scalar.length = vec.ecdsa.pkey.len;
1088 
1089 	rte_free(vec.ecdsa.qx.val);
1090 
1091 	rte_free(vec.ecdsa.qy.val);
1092 
1093 	vec.ecdsa.qx.len = info.interim_info.ecdsa_data.curve_len;
1094 	vec.ecdsa.qx.val = rte_zmalloc(NULL, vec.ecdsa.qx.len, 0);
1095 
1096 	vec.ecdsa.qy.len = vec.ecdsa.qx.len;
1097 	vec.ecdsa.qy.val = rte_zmalloc(NULL, vec.ecdsa.qy.len, 0);
1098 
1099 	asym->ecpm.r.x.data = vec.ecdsa.qx.val;
1100 	asym->ecpm.r.x.length = 0;
1101 	asym->ecpm.r.y.data = vec.ecdsa.qy.val;
1102 	asym->ecpm.r.y.length = 0;
1103 
1104 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
1105 
1106 	return 0;
1107 }
1108 
1109 static int
1110 prepare_edfpm_op(void)
1111 {
1112 	struct rte_crypto_asym_op *asym;
1113 
1114 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1115 
1116 	asym = env.op->asym;
1117 	asym->ecpm.scalar.data = vec.eddsa.pkey.val;
1118 	asym->ecpm.scalar.length = vec.eddsa.pkey.len;
1119 
1120 	rte_free(vec.eddsa.q.val);
1121 
1122 	vec.eddsa.q.len = info.interim_info.eddsa_data.curve_len;
1123 	vec.eddsa.q.val = rte_zmalloc(NULL, vec.eddsa.q.len, 0);
1124 
1125 	asym->ecpm.r.x.data = vec.eddsa.q.val;
1126 	asym->ecpm.r.x.length = 0;
1127 	asym->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
1128 
1129 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
1130 
1131 	return 0;
1132 }
1133 
1134 static int
1135 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
1136 {
1137 	const struct rte_cryptodev_symmetric_capability *cap;
1138 	struct rte_cryptodev_sym_capability_idx cap_idx;
1139 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1140 
1141 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1142 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC)
1143 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC;
1144 	else if (info.interim_info.aes_data.cipher_algo ==
1145 			RTE_CRYPTO_CIPHER_AES_CTR)
1146 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CTR;
1147 	else
1148 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB;
1149 
1150 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1151 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1152 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1153 	cipher_xform->key.data = vec.cipher_auth.key.val;
1154 	cipher_xform->key.length = vec.cipher_auth.key.len;
1155 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC ||
1156 			cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CTR) {
1157 		cipher_xform->iv.length = vec.iv.len;
1158 		cipher_xform->iv.offset = IV_OFF;
1159 	} else {
1160 		cipher_xform->iv.length = 0;
1161 		cipher_xform->iv.offset = 0;
1162 	}
1163 	cap_idx.algo.cipher = cipher_xform->algo;
1164 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1165 
1166 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1167 	if (!cap) {
1168 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1169 				env.dev_id);
1170 		return -EINVAL;
1171 	}
1172 
1173 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1174 			cipher_xform->key.length,
1175 			cipher_xform->iv.length) != 0) {
1176 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1177 				info.device_name, cipher_xform->key.length,
1178 				cipher_xform->iv.length);
1179 		return -EPERM;
1180 	}
1181 
1182 	return 0;
1183 }
1184 
1185 static int
1186 prepare_tdes_xform(struct rte_crypto_sym_xform *xform)
1187 {
1188 	const struct rte_cryptodev_symmetric_capability *cap;
1189 	struct rte_cryptodev_sym_capability_idx cap_idx;
1190 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1191 
1192 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1193 
1194 	if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC)
1195 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC;
1196 	else
1197 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB;
1198 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1199 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1200 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1201 	cipher_xform->key.data = vec.cipher_auth.key.val;
1202 	cipher_xform->key.length = vec.cipher_auth.key.len;
1203 
1204 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
1205 		cipher_xform->iv.length = vec.iv.len;
1206 		cipher_xform->iv.offset = IV_OFF;
1207 	} else {
1208 		cipher_xform->iv.length = 0;
1209 		cipher_xform->iv.offset = 0;
1210 	}
1211 	cap_idx.algo.cipher = cipher_xform->algo;
1212 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1213 
1214 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1215 	if (!cap) {
1216 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1217 				env.dev_id);
1218 		return -EINVAL;
1219 	}
1220 
1221 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1222 			cipher_xform->key.length,
1223 			cipher_xform->iv.length) != 0) {
1224 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1225 				info.device_name, cipher_xform->key.length,
1226 				cipher_xform->iv.length);
1227 		return -EPERM;
1228 	}
1229 
1230 	return 0;
1231 }
1232 
1233 static int
1234 prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
1235 {
1236 	const struct rte_cryptodev_symmetric_capability *cap;
1237 	struct rte_cryptodev_sym_capability_idx cap_idx;
1238 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1239 
1240 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1241 
1242 	auth_xform->algo = info.interim_info.hmac_data.algo;
1243 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
1244 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1245 	auth_xform->key.data = vec.cipher_auth.key.val;
1246 	auth_xform->key.length = vec.cipher_auth.key.len;
1247 
1248 	cap_idx.algo.auth = auth_xform->algo;
1249 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1250 
1251 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1252 	if (!cap) {
1253 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1254 				env.dev_id);
1255 		return -EINVAL;
1256 	}
1257 
1258 	if (rte_cryptodev_sym_capability_check_auth(cap,
1259 			auth_xform->key.length,
1260 			auth_xform->digest_length, 0) != 0) {
1261 		RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n",
1262 				info.device_name, auth_xform->key.length,
1263 				auth_xform->digest_length);
1264 		return -EPERM;
1265 	}
1266 
1267 	return 0;
1268 }
1269 
1270 int
1271 prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
1272 {
1273 	const struct rte_cryptodev_symmetric_capability *cap;
1274 	struct rte_cryptodev_sym_capability_idx cap_idx;
1275 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
1276 
1277 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
1278 
1279 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
1280 	aead_xform->aad_length = vec.aead.aad.len;
1281 	aead_xform->digest_length = vec.aead.digest.len;
1282 	aead_xform->iv.offset = IV_OFF;
1283 	aead_xform->iv.length = vec.iv.len;
1284 	aead_xform->key.data = vec.aead.key.val;
1285 	aead_xform->key.length = vec.aead.key.len;
1286 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1287 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
1288 			RTE_CRYPTO_AEAD_OP_DECRYPT;
1289 
1290 	cap_idx.algo.aead = aead_xform->algo;
1291 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
1292 
1293 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1294 	if (!cap) {
1295 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1296 				env.dev_id);
1297 		return -EINVAL;
1298 	}
1299 
1300 	if (rte_cryptodev_sym_capability_check_aead(cap,
1301 			aead_xform->key.length,
1302 			aead_xform->digest_length, aead_xform->aad_length,
1303 			aead_xform->iv.length) != 0) {
1304 		RTE_LOG(ERR, USER1,
1305 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
1306 				info.device_name, aead_xform->key.length,
1307 				aead_xform->digest_length,
1308 				aead_xform->aad_length,
1309 				aead_xform->iv.length);
1310 		return -EPERM;
1311 	}
1312 
1313 	return 0;
1314 }
1315 
1316 int
1317 prepare_gmac_xform(struct rte_crypto_sym_xform *xform)
1318 {
1319 	const struct rte_cryptodev_symmetric_capability *cap;
1320 	struct rte_cryptodev_sym_capability_idx cap_idx;
1321 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1322 
1323 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1324 
1325 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC;
1326 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1327 			RTE_CRYPTO_AUTH_OP_GENERATE :
1328 			RTE_CRYPTO_AUTH_OP_VERIFY;
1329 	auth_xform->iv.offset = IV_OFF;
1330 	auth_xform->iv.length = vec.iv.len;
1331 	auth_xform->digest_length = vec.aead.digest.len;
1332 	auth_xform->key.data = vec.aead.key.val;
1333 	auth_xform->key.length = vec.aead.key.len;
1334 
1335 	cap_idx.algo.auth = auth_xform->algo;
1336 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1337 
1338 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1339 	if (!cap) {
1340 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1341 				env.dev_id);
1342 		return -EINVAL;
1343 	}
1344 
1345 	if (rte_cryptodev_sym_capability_check_auth(cap,
1346 			auth_xform->key.length,
1347 			auth_xform->digest_length,
1348 			auth_xform->iv.length) != 0) {
1349 
1350 		RTE_LOG(ERR, USER1,
1351 			"PMD %s key length %u Digest length %u IV length %u\n",
1352 				info.device_name, auth_xform->key.length,
1353 				auth_xform->digest_length,
1354 				auth_xform->iv.length);
1355 		return -EPERM;
1356 	}
1357 
1358 	return 0;
1359 }
1360 
1361 static int
1362 prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
1363 {
1364 	const struct rte_cryptodev_symmetric_capability *cap;
1365 	struct rte_cryptodev_sym_capability_idx cap_idx;
1366 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1367 
1368 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1369 
1370 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC;
1371 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1372 			RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY;
1373 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1374 	auth_xform->key.data = vec.cipher_auth.key.val;
1375 	auth_xform->key.length = vec.cipher_auth.key.len;
1376 
1377 	cap_idx.algo.auth = auth_xform->algo;
1378 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1379 
1380 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1381 	if (!cap) {
1382 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1383 				env.dev_id);
1384 		return -EINVAL;
1385 	}
1386 
1387 	if (rte_cryptodev_sym_capability_check_auth(cap,
1388 			auth_xform->key.length,
1389 			auth_xform->digest_length, 0) != 0) {
1390 		RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n",
1391 				info.device_name, auth_xform->key.length,
1392 				auth_xform->digest_length);
1393 		return -EPERM;
1394 	}
1395 
1396 	return 0;
1397 }
1398 
1399 static int
1400 prepare_ccm_xform(struct rte_crypto_sym_xform *xform)
1401 {
1402 	const struct rte_cryptodev_symmetric_capability *cap;
1403 	struct rte_cryptodev_sym_capability_idx cap_idx;
1404 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
1405 
1406 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
1407 
1408 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM;
1409 	aead_xform->aad_length = vec.aead.aad.len;
1410 	aead_xform->digest_length = vec.aead.digest.len;
1411 	aead_xform->iv.offset = IV_OFF;
1412 	aead_xform->iv.length = vec.iv.len;
1413 	aead_xform->key.data = vec.aead.key.val;
1414 	aead_xform->key.length = vec.aead.key.len;
1415 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1416 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
1417 			RTE_CRYPTO_AEAD_OP_DECRYPT;
1418 
1419 	cap_idx.algo.aead = aead_xform->algo;
1420 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
1421 
1422 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1423 	if (!cap) {
1424 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1425 				env.dev_id);
1426 		return -EINVAL;
1427 	}
1428 
1429 	if (rte_cryptodev_sym_capability_check_aead(cap,
1430 			aead_xform->key.length,
1431 			aead_xform->digest_length, aead_xform->aad_length,
1432 			aead_xform->iv.length) != 0) {
1433 		RTE_LOG(ERR, USER1,
1434 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
1435 				info.device_name, aead_xform->key.length,
1436 				aead_xform->digest_length,
1437 				aead_xform->aad_length,
1438 				aead_xform->iv.length);
1439 		return -EPERM;
1440 	}
1441 
1442 	return 0;
1443 }
1444 
1445 static int
1446 prepare_sha_xform(struct rte_crypto_sym_xform *xform)
1447 {
1448 	const struct rte_cryptodev_symmetric_capability *cap;
1449 	struct rte_cryptodev_sym_capability_idx cap_idx;
1450 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1451 
1452 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1453 
1454 	auth_xform->algo = info.interim_info.sha_data.algo;
1455 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
1456 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1457 
1458 	cap_idx.algo.auth = auth_xform->algo;
1459 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1460 
1461 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1462 	if (!cap) {
1463 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1464 				env.dev_id);
1465 		return -EINVAL;
1466 	}
1467 
1468 	if (rte_cryptodev_sym_capability_check_auth(cap,
1469 			auth_xform->key.length,
1470 			auth_xform->digest_length, 0) != 0) {
1471 		RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n",
1472 				info.device_name, auth_xform->key.length,
1473 				auth_xform->digest_length);
1474 		return -EPERM;
1475 	}
1476 
1477 	return 0;
1478 }
1479 
1480 static int
1481 prepare_xts_xform(struct rte_crypto_sym_xform *xform)
1482 {
1483 	const struct rte_cryptodev_symmetric_capability *cap;
1484 	struct rte_cryptodev_sym_capability_idx cap_idx;
1485 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1486 
1487 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1488 
1489 	cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS;
1490 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1491 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1492 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1493 	cipher_xform->key.data = vec.cipher_auth.key.val;
1494 	cipher_xform->key.length = vec.cipher_auth.key.len;
1495 	cipher_xform->iv.length = vec.iv.len;
1496 	cipher_xform->iv.offset = IV_OFF;
1497 
1498 	cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS;
1499 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1500 
1501 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1502 	if (!cap) {
1503 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1504 				env.dev_id);
1505 		return -EINVAL;
1506 	}
1507 
1508 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1509 			cipher_xform->key.length,
1510 			cipher_xform->iv.length) != 0) {
1511 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1512 				info.device_name, cipher_xform->key.length,
1513 				cipher_xform->iv.length);
1514 		return -EPERM;
1515 	}
1516 
1517 	return 0;
1518 }
1519 
1520 static int
1521 prepare_rsa_xform(struct rte_crypto_asym_xform *xform)
1522 {
1523 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1524 	struct rte_cryptodev_asym_capability_idx cap_idx;
1525 	struct rte_cryptodev_info dev_info;
1526 
1527 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_RSA;
1528 	xform->next = NULL;
1529 
1530 	cap_idx.type = xform->xform_type;
1531 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1532 	if (!cap) {
1533 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1534 				env.dev_id);
1535 		return -EINVAL;
1536 	}
1537 
1538 	switch (info.op) {
1539 	case FIPS_TEST_ASYM_SIGGEN:
1540 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1541 			RTE_CRYPTO_ASYM_OP_SIGN)) {
1542 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1543 				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
1544 			return -EPERM;
1545 		}
1546 		break;
1547 	case FIPS_TEST_ASYM_SIGVER:
1548 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1549 			RTE_CRYPTO_ASYM_OP_VERIFY)) {
1550 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1551 				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
1552 			return -EPERM;
1553 		}
1554 		break;
1555 	case FIPS_TEST_ASYM_KEYGEN:
1556 		break;
1557 	default:
1558 		break;
1559 	}
1560 
1561 	rte_cryptodev_info_get(env.dev_id, &dev_info);
1562 	xform->rsa.key_type = info.interim_info.rsa_data.privkey;
1563 	switch (xform->rsa.key_type) {
1564 	case RTE_RSA_KEY_TYPE_QT:
1565 		if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT)) {
1566 			RTE_LOG(ERR, USER1, "PMD %s does not support QT key type\n",
1567 				info.device_name);
1568 			return -EPERM;
1569 		}
1570 		xform->rsa.qt.p.data = vec.rsa.p.val;
1571 		xform->rsa.qt.p.length = vec.rsa.p.len;
1572 		xform->rsa.qt.q.data = vec.rsa.q.val;
1573 		xform->rsa.qt.q.length = vec.rsa.q.len;
1574 		xform->rsa.qt.dP.data = vec.rsa.dp.val;
1575 		xform->rsa.qt.dP.length = vec.rsa.dp.len;
1576 		xform->rsa.qt.dQ.data = vec.rsa.dq.val;
1577 		xform->rsa.qt.dQ.length = vec.rsa.dq.len;
1578 		xform->rsa.qt.qInv.data = vec.rsa.qinv.val;
1579 		xform->rsa.qt.qInv.length = vec.rsa.qinv.len;
1580 		break;
1581 	case RTE_RSA_KEY_TYPE_EXP:
1582 		if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP)) {
1583 			RTE_LOG(ERR, USER1, "PMD %s does not support EXP key type\n",
1584 				info.device_name);
1585 			return -EPERM;
1586 		}
1587 		xform->rsa.d.data = vec.rsa.d.val;
1588 		xform->rsa.d.length = vec.rsa.d.len;
1589 		break;
1590 	default:
1591 		break;
1592 	}
1593 
1594 	xform->rsa.e.data = vec.rsa.e.val;
1595 	xform->rsa.e.length = vec.rsa.e.len;
1596 	xform->rsa.n.data = vec.rsa.n.val;
1597 	xform->rsa.n.length = vec.rsa.n.len;
1598 
1599 	xform->rsa.padding.type = info.interim_info.rsa_data.padding;
1600 	xform->rsa.padding.hash = info.interim_info.rsa_data.auth;
1601 	if (env.digest) {
1602 		if (xform->rsa.padding.type == RTE_CRYPTO_RSA_PADDING_PKCS1_5) {
1603 			struct fips_val msg;
1604 			int b_len = 0;
1605 			uint8_t b[32];
1606 
1607 			b_len = get_hash_oid(xform->rsa.padding.hash, b);
1608 			if (b_len < 0) {
1609 				RTE_LOG(ERR, USER1, "Failed to get digest info for hash %d\n",
1610 					xform->rsa.padding.hash);
1611 				return -EINVAL;
1612 			}
1613 
1614 			if (b_len) {
1615 				msg.len = env.digest_len + b_len;
1616 				msg.val = rte_zmalloc(NULL, msg.len, 0);
1617 				rte_memcpy(msg.val, b, b_len);
1618 				rte_memcpy(msg.val + b_len, env.digest, env.digest_len);
1619 				rte_free(env.digest);
1620 				env.digest = msg.val;
1621 				env.digest_len = msg.len;
1622 			}
1623 		}
1624 	}
1625 
1626 	return 0;
1627 }
1628 
1629 static int
1630 prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform)
1631 {
1632 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1633 	struct rte_cryptodev_asym_capability_idx cap_idx;
1634 
1635 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA;
1636 	xform->next = NULL;
1637 
1638 	cap_idx.type = xform->xform_type;
1639 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1640 	if (!cap) {
1641 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1642 				env.dev_id);
1643 		return -EINVAL;
1644 	}
1645 
1646 	switch (info.op) {
1647 	case FIPS_TEST_ASYM_SIGGEN:
1648 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1649 			RTE_CRYPTO_ASYM_OP_SIGN)) {
1650 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1651 				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
1652 			return -EPERM;
1653 		}
1654 
1655 		xform->ec.pkey.data = vec.ecdsa.pkey.val;
1656 		xform->ec.pkey.length = vec.ecdsa.pkey.len;
1657 		break;
1658 	case FIPS_TEST_ASYM_SIGVER:
1659 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1660 			RTE_CRYPTO_ASYM_OP_VERIFY)) {
1661 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1662 				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
1663 			return -EPERM;
1664 		}
1665 
1666 		xform->ec.q.x.data = vec.ecdsa.qx.val;
1667 		xform->ec.q.x.length = vec.ecdsa.qx.len;
1668 		xform->ec.q.y.data = vec.ecdsa.qy.val;
1669 		xform->ec.q.y.length = vec.ecdsa.qy.len;
1670 		break;
1671 	default:
1672 		break;
1673 	}
1674 
1675 	xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id;
1676 	return 0;
1677 }
1678 
1679 static int
1680 prepare_eddsa_xform(struct rte_crypto_asym_xform *xform)
1681 {
1682 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1683 	struct rte_cryptodev_asym_capability_idx cap_idx;
1684 
1685 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
1686 	xform->next = NULL;
1687 
1688 	cap_idx.type = xform->xform_type;
1689 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1690 	if (!cap) {
1691 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1692 				env.dev_id);
1693 		return -EINVAL;
1694 	}
1695 
1696 	switch (info.op) {
1697 	case FIPS_TEST_ASYM_SIGGEN:
1698 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1699 			RTE_CRYPTO_ASYM_OP_SIGN)) {
1700 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1701 				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
1702 			return -EPERM;
1703 		}
1704 
1705 		xform->ec.pkey.data = vec.eddsa.pkey.val;
1706 		xform->ec.pkey.length = vec.eddsa.pkey.len;
1707 		xform->ec.q.x.data = vec.eddsa.q.val;
1708 		xform->ec.q.x.length = vec.eddsa.q.len;
1709 		break;
1710 	case FIPS_TEST_ASYM_SIGVER:
1711 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1712 			RTE_CRYPTO_ASYM_OP_VERIFY)) {
1713 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1714 				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
1715 			return -EPERM;
1716 		}
1717 
1718 		xform->ec.q.x.data = vec.eddsa.q.val;
1719 		xform->ec.q.x.length = vec.eddsa.q.len;
1720 		break;
1721 	default:
1722 		break;
1723 	}
1724 
1725 	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
1726 	return 0;
1727 }
1728 
1729 static int
1730 prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
1731 {
1732 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1733 	struct rte_cryptodev_asym_capability_idx cap_idx;
1734 
1735 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
1736 	xform->next = NULL;
1737 
1738 	cap_idx.type = xform->xform_type;
1739 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1740 	if (!cap) {
1741 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1742 				env.dev_id);
1743 		return -EINVAL;
1744 	}
1745 
1746 	xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id;
1747 	return 0;
1748 }
1749 
1750 static int
1751 prepare_edfpm_xform(struct rte_crypto_asym_xform *xform)
1752 {
1753 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1754 	struct rte_cryptodev_asym_capability_idx cap_idx;
1755 
1756 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
1757 	xform->next = NULL;
1758 
1759 	cap_idx.type = xform->xform_type;
1760 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1761 	if (!cap) {
1762 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1763 				env.dev_id);
1764 		return -EINVAL;
1765 	}
1766 
1767 	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
1768 	return 0;
1769 }
1770 
1771 static int
1772 get_writeback_data(struct fips_val *val)
1773 {
1774 	struct rte_mbuf *m = env.mbuf;
1775 	uint16_t data_len = rte_pktmbuf_pkt_len(m);
1776 	uint16_t total_len = data_len + env.digest_len;
1777 	uint8_t *src, *dst, *wb_data;
1778 
1779 	/* in case val is reused for MCT test, try to free the buffer first */
1780 	if (val->val) {
1781 		rte_free(val->val);
1782 		val->val = NULL;
1783 	}
1784 
1785 	wb_data = dst = rte_malloc(NULL, total_len, 0);
1786 	if (!dst) {
1787 		RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM);
1788 		return -ENOMEM;
1789 	}
1790 
1791 	while (m && data_len) {
1792 		uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len);
1793 
1794 		src = rte_pktmbuf_mtod(m, uint8_t *);
1795 		memcpy(dst, src, seg_len);
1796 		m = m->next;
1797 		data_len -= seg_len;
1798 		dst += seg_len;
1799 	}
1800 
1801 	if (data_len) {
1802 		RTE_LOG(ERR, USER1, "Error -1: write back data\n");
1803 		rte_free(wb_data);
1804 		return -1;
1805 	}
1806 
1807 	if (env.digest)
1808 		memcpy(dst, env.digest, env.digest_len);
1809 
1810 	val->val = wb_data;
1811 	val->len = total_len;
1812 
1813 	return 0;
1814 }
1815 
1816 static int
1817 fips_run_sym_test(void)
1818 {
1819 	struct rte_crypto_sym_xform xform = {0};
1820 	uint16_t n_deqd;
1821 	int ret;
1822 
1823 	if (!test_ops.prepare_sym_xform || !test_ops.prepare_sym_op)
1824 		return -EINVAL;
1825 
1826 	ret = test_ops.prepare_sym_xform(&xform);
1827 	if (ret < 0)
1828 		return ret;
1829 
1830 	env.sym.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform,
1831 						env.sym.sess_mpool);
1832 	if (!env.sym.sess)
1833 		return -ENOMEM;
1834 
1835 	ret = test_ops.prepare_sym_op();
1836 	if (ret < 0) {
1837 		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n",
1838 				ret);
1839 		goto exit;
1840 	}
1841 
1842 	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
1843 		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
1844 		ret = -1;
1845 		goto exit;
1846 	}
1847 
1848 	do {
1849 		struct rte_crypto_op *deqd_op;
1850 
1851 		n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1);
1852 	} while (n_deqd == 0);
1853 
1854 	vec.status = env.op->status;
1855 
1856 exit:
1857 	rte_cryptodev_sym_session_free(env.dev_id, env.sym.sess);
1858 	env.sym.sess = NULL;
1859 	return ret;
1860 }
1861 
1862 static int
1863 fips_run_asym_test(void)
1864 {
1865 	struct rte_crypto_asym_xform xform = {0};
1866 	struct rte_crypto_asym_op *asym;
1867 	struct rte_crypto_op *deqd_op;
1868 	int ret;
1869 
1870 	if (info.op == FIPS_TEST_ASYM_KEYGEN &&
1871 		(info.algo != FIPS_TEST_ALGO_ECDSA &&
1872 		 info.algo != FIPS_TEST_ALGO_EDDSA)) {
1873 		RTE_SET_USED(asym);
1874 		ret = 0;
1875 		goto exit;
1876 	}
1877 
1878 	if (!test_ops.prepare_asym_xform || !test_ops.prepare_asym_op)
1879 		return -EINVAL;
1880 
1881 	asym = env.op->asym;
1882 	ret = test_ops.prepare_asym_xform(&xform);
1883 	if (ret < 0)
1884 		return ret;
1885 
1886 	ret = rte_cryptodev_asym_session_create(env.dev_id, &xform, env.asym.sess_mpool,
1887 			(void *)&env.asym.sess);
1888 	if (ret < 0)
1889 		return ret;
1890 
1891 	ret = test_ops.prepare_asym_op();
1892 	if (ret < 0) {
1893 		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", ret);
1894 		goto exit;
1895 	}
1896 
1897 	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
1898 		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
1899 		ret = -1;
1900 		goto exit;
1901 	}
1902 
1903 	while (rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1) == 0)
1904 		rte_pause();
1905 
1906 	vec.status = env.op->status;
1907 
1908  exit:
1909 	if (env.asym.sess)
1910 		rte_cryptodev_asym_session_free(env.dev_id, env.asym.sess);
1911 
1912 	env.asym.sess = NULL;
1913 	return ret;
1914 }
1915 
1916 static int
1917 fips_run_test(void)
1918 {
1919 	int ret;
1920 
1921 	env.op = NULL;
1922 	if (!env.is_asym_test) {
1923 		env.op = env.sym.op;
1924 		return fips_run_sym_test();
1925 	}
1926 
1927 	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
1928 		if (info.algo == FIPS_TEST_ALGO_ECDSA) {
1929 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
1930 			test_ops.prepare_asym_op = prepare_ecfpm_op;
1931 			info.interim_info.ecdsa_data.pubkey_gen = 0;
1932 
1933 		} else if (info.algo == FIPS_TEST_ALGO_EDDSA) {
1934 			test_ops.prepare_asym_xform = prepare_edfpm_xform;
1935 			test_ops.prepare_asym_op = prepare_edfpm_op;
1936 			info.interim_info.eddsa_data.pubkey_gen = 0;
1937 		}
1938 
1939 		env.op = env.asym.op;
1940 		return fips_run_asym_test();
1941 	}
1942 
1943 	if (info.algo == FIPS_TEST_ALGO_ECDSA ||
1944 	    info.algo == FIPS_TEST_ALGO_RSA) {
1945 		vec.cipher_auth.digest.len =
1946 			parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth);
1947 		test_ops.prepare_sym_xform = prepare_sha_xform;
1948 		test_ops.prepare_sym_op = prepare_auth_op;
1949 
1950 		env.op = env.sym.op;
1951 		ret = fips_run_sym_test();
1952 		if (ret < 0)
1953 			return ret;
1954 	}
1955 
1956 	env.op = env.asym.op;
1957 	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
1958 		fips_prepare_asym_xform_t old_xform;
1959 		fips_prepare_op_t old_op;
1960 
1961 		old_xform = test_ops.prepare_asym_xform;
1962 		old_op = test_ops.prepare_asym_op;
1963 
1964 		if (info.algo == FIPS_TEST_ALGO_ECDSA &&
1965 		    info.interim_info.ecdsa_data.pubkey_gen == 1) {
1966 			info.op = FIPS_TEST_ASYM_KEYGEN;
1967 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
1968 			test_ops.prepare_asym_op = prepare_ecfpm_op;
1969 
1970 			ret = fips_run_asym_test();
1971 			if (ret < 0)
1972 				return ret;
1973 
1974 			info.post_interim_writeback(NULL);
1975 			info.interim_info.ecdsa_data.pubkey_gen = 0;
1976 
1977 		} else if (info.algo == FIPS_TEST_ALGO_EDDSA &&
1978 				   info.interim_info.eddsa_data.pubkey_gen == 1) {
1979 			info.op = FIPS_TEST_ASYM_KEYGEN;
1980 			test_ops.prepare_asym_xform = prepare_edfpm_xform;
1981 			test_ops.prepare_asym_op = prepare_edfpm_op;
1982 
1983 			const struct rte_cryptodev_asymmetric_xform_capability *cap;
1984 			struct rte_cryptodev_asym_capability_idx cap_idx;
1985 
1986 			cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
1987 			cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1988 			if (!cap) {
1989 				RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1990 						env.dev_id);
1991 				return -EINVAL;
1992 			}
1993 
1994 			if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) {
1995 				ret = fips_run_asym_test();
1996 				if (ret < 0)
1997 					return ret;
1998 			} else {
1999 				/* Below is only a workaround by using known keys. */
2000 				struct rte_crypto_asym_xform xform = {0};
2001 
2002 				prepare_edfpm_xform(&xform);
2003 				prepare_edfpm_op();
2004 				uint8_t pkey25519[] = {
2005 					0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
2006 					0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
2007 					0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
2008 					0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
2009 				};
2010 				uint8_t q25519[] = {
2011 					0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
2012 					0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
2013 					0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
2014 					0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
2015 				};
2016 				uint8_t pkey448[] = {
2017 					0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
2018 					0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
2019 					0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
2020 					0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
2021 					0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
2022 					0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
2023 					0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
2024 					0x01
2025 				};
2026 				uint8_t q448[] = {
2027 					0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
2028 					0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
2029 					0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
2030 					0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
2031 					0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
2032 					0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
2033 					0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
2034 					0x00
2035 				};
2036 				if (info.interim_info.eddsa_data.curve_id ==
2037 					RTE_CRYPTO_EC_GROUP_ED25519) {
2038 					memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519));
2039 					vec.eddsa.pkey.len = 32;
2040 					memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519));
2041 					vec.eddsa.q.len = 32;
2042 				} else {
2043 					memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448));
2044 					vec.eddsa.pkey.len = 32;
2045 					memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448));
2046 					vec.eddsa.q.len = 32;
2047 				}
2048 			}
2049 			info.post_interim_writeback(NULL);
2050 			info.interim_info.eddsa_data.pubkey_gen = 0;
2051 
2052 		}
2053 
2054 		test_ops.prepare_asym_xform = old_xform;
2055 		test_ops.prepare_asym_op = old_op;
2056 		info.op = FIPS_TEST_ASYM_SIGGEN;
2057 		ret = fips_run_asym_test();
2058 	} else {
2059 		ret = fips_run_asym_test();
2060 	}
2061 
2062 	return ret;
2063 }
2064 
2065 static int
2066 fips_generic_test(void)
2067 {
2068 	struct fips_val val = {NULL, 0};
2069 	int ret;
2070 
2071 	if (info.file_type != FIPS_TYPE_JSON)
2072 		fips_test_write_one_case();
2073 
2074 	ret = fips_run_test();
2075 	if (ret < 0) {
2076 		if (ret == -EPERM || ret == -ENOTSUP) {
2077 			if (info.file_type == FIPS_TYPE_JSON)
2078 				return ret;
2079 
2080 			fprintf(info.fp_wr, "Bypass\n\n");
2081 			return 0;
2082 		}
2083 
2084 		return ret;
2085 	}
2086 
2087 	if (!env.is_asym_test) {
2088 		ret = get_writeback_data(&val);
2089 		if (ret < 0)
2090 			return ret;
2091 	}
2092 
2093 	switch (info.file_type) {
2094 	case FIPS_TYPE_REQ:
2095 	case FIPS_TYPE_RSP:
2096 	case FIPS_TYPE_JSON:
2097 		if (info.parse_writeback == NULL)
2098 			return -EPERM;
2099 		ret = info.parse_writeback(&val);
2100 		if (ret < 0)
2101 			return ret;
2102 		break;
2103 	case FIPS_TYPE_FAX:
2104 		if (info.kat_check == NULL)
2105 			return -EPERM;
2106 		ret = info.kat_check(&val);
2107 		if (ret < 0)
2108 			return ret;
2109 		break;
2110 	default:
2111 		break;
2112 	}
2113 
2114 	if (info.file_type != FIPS_TYPE_JSON)
2115 		fprintf(info.fp_wr, "\n");
2116 	rte_free(val.val);
2117 
2118 	return 0;
2119 }
2120 
2121 static int
2122 fips_mct_tdes_test(void)
2123 {
2124 #define TDES_BLOCK_SIZE		8
2125 #define TDES_EXTERN_ITER	400
2126 #define TDES_INTERN_ITER	10000
2127 	struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv;
2128 	uint8_t prev_out[TDES_BLOCK_SIZE] = {0};
2129 	uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0};
2130 	uint8_t prev_in[TDES_BLOCK_SIZE] = {0};
2131 	uint32_t i, j, k;
2132 	int ret;
2133 	int test_mode = info.interim_info.tdes_data.test_mode;
2134 
2135 	pt.len = vec.pt.len;
2136 	pt.val = rte_malloc(NULL, pt.len, 0);
2137 	ct.len = vec.ct.len;
2138 	ct.val = rte_malloc(NULL, ct.len, 0);
2139 	iv.len = vec.iv.len;
2140 	iv.val = rte_malloc(NULL, iv.len, 0);
2141 
2142 	for (i = 0; i < TDES_EXTERN_ITER; i++) {
2143 		if (info.file_type != FIPS_TYPE_JSON) {
2144 			if ((i == 0) && (info.version == 21.4f)) {
2145 				if (!(strstr(info.vec[0], "COUNT")))
2146 					fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0);
2147 			}
2148 
2149 			if (i != 0)
2150 				update_info_vec(i);
2151 
2152 			fips_test_write_one_case();
2153 		}
2154 
2155 		for (j = 0; j < TDES_INTERN_ITER; j++) {
2156 			ret = fips_run_test();
2157 			if (ret < 0) {
2158 				if (ret == -EPERM) {
2159 					if (info.file_type == FIPS_TYPE_JSON)
2160 						return ret;
2161 
2162 					fprintf(info.fp_wr, "Bypass\n");
2163 					return 0;
2164 				}
2165 				return ret;
2166 			}
2167 
2168 			ret = get_writeback_data(&val[0]);
2169 			if (ret < 0)
2170 				return ret;
2171 
2172 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2173 				memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE);
2174 
2175 			if (j == 0) {
2176 				memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
2177 				memcpy(pt.val, vec.pt.val, pt.len);
2178 				memcpy(ct.val, vec.ct.val, ct.len);
2179 				memcpy(iv.val, vec.iv.val, iv.len);
2180 
2181 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2182 					if (test_mode == TDES_MODE_ECB) {
2183 						memcpy(vec.pt.val, val[0].val,
2184 							   TDES_BLOCK_SIZE);
2185 					} else {
2186 						memcpy(vec.pt.val, vec.iv.val,
2187 							   TDES_BLOCK_SIZE);
2188 						memcpy(vec.iv.val, val[0].val,
2189 							   TDES_BLOCK_SIZE);
2190 					}
2191 					val[1].val = pt.val;
2192 					val[1].len = pt.len;
2193 					val[2].val = iv.val;
2194 					val[2].len = iv.len;
2195 				} else {
2196 					if (test_mode == TDES_MODE_ECB) {
2197 						memcpy(vec.ct.val, val[0].val,
2198 							   TDES_BLOCK_SIZE);
2199 					} else {
2200 						memcpy(vec.iv.val, vec.ct.val,
2201 							   TDES_BLOCK_SIZE);
2202 						memcpy(vec.ct.val, val[0].val,
2203 							   TDES_BLOCK_SIZE);
2204 					}
2205 					val[1].val = ct.val;
2206 					val[1].len = ct.len;
2207 					val[2].val = iv.val;
2208 					val[2].len = iv.len;
2209 				}
2210 				continue;
2211 			}
2212 
2213 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2214 				if (test_mode == TDES_MODE_ECB) {
2215 					memcpy(vec.pt.val, val[0].val,
2216 						   TDES_BLOCK_SIZE);
2217 				} else {
2218 					memcpy(vec.iv.val, val[0].val,
2219 						   TDES_BLOCK_SIZE);
2220 					memcpy(vec.pt.val, prev_out,
2221 						   TDES_BLOCK_SIZE);
2222 				}
2223 			} else {
2224 				if (test_mode == TDES_MODE_ECB) {
2225 					memcpy(vec.ct.val, val[0].val,
2226 						   TDES_BLOCK_SIZE);
2227 				} else {
2228 					memcpy(vec.iv.val, vec.ct.val,
2229 						   TDES_BLOCK_SIZE);
2230 					memcpy(vec.ct.val, val[0].val,
2231 						   TDES_BLOCK_SIZE);
2232 				}
2233 			}
2234 
2235 			if (j == TDES_INTERN_ITER - 1)
2236 				continue;
2237 
2238 			memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
2239 
2240 			if (j == TDES_INTERN_ITER - 3)
2241 				memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE);
2242 		}
2243 
2244 		info.parse_writeback(val);
2245 		if (info.file_type != FIPS_TYPE_JSON)
2246 			fprintf(info.fp_wr, "\n");
2247 
2248 		if (i == TDES_EXTERN_ITER - 1)
2249 			continue;
2250 
2251 		/** update key */
2252 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2253 
2254 		if (info.interim_info.tdes_data.nb_keys == 0) {
2255 			if (memcmp(val_key.val, val_key.val + 8, 8) == 0)
2256 				info.interim_info.tdes_data.nb_keys = 1;
2257 			else if (memcmp(val_key.val, val_key.val + 16, 8) == 0)
2258 				info.interim_info.tdes_data.nb_keys = 2;
2259 			else
2260 				info.interim_info.tdes_data.nb_keys = 3;
2261 
2262 		}
2263 
2264 		for (k = 0; k < TDES_BLOCK_SIZE; k++) {
2265 
2266 			switch (info.interim_info.tdes_data.nb_keys) {
2267 			case 3:
2268 				val_key.val[k] ^= val[0].val[k];
2269 				val_key.val[k + 8] ^= prev_out[k];
2270 				val_key.val[k + 16] ^= prev_prev_out[k];
2271 				break;
2272 			case 2:
2273 				val_key.val[k] ^= val[0].val[k];
2274 				val_key.val[k + 8] ^= prev_out[k];
2275 				val_key.val[k + 16] ^= val[0].val[k];
2276 				break;
2277 			default: /* case 1 */
2278 				val_key.val[k] ^= val[0].val[k];
2279 				val_key.val[k + 8] ^= val[0].val[k];
2280 				val_key.val[k + 16] ^= val[0].val[k];
2281 				break;
2282 			}
2283 
2284 		}
2285 
2286 		for (k = 0; k < 24; k++)
2287 			val_key.val[k] = (rte_popcount32(val_key.val[k]) &
2288 					0x1) ?
2289 					val_key.val[k] : (val_key.val[k] ^ 0x1);
2290 
2291 		if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2292 			if (test_mode == TDES_MODE_ECB) {
2293 				memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE);
2294 			} else {
2295 				memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE);
2296 				memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
2297 			}
2298 		} else {
2299 			if (test_mode == TDES_MODE_ECB) {
2300 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
2301 			} else {
2302 				memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE);
2303 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
2304 			}
2305 		}
2306 	}
2307 
2308 	rte_free(val[0].val);
2309 	rte_free(pt.val);
2310 	rte_free(ct.val);
2311 	rte_free(iv.val);
2312 
2313 	return 0;
2314 }
2315 
2316 static int
2317 fips_mct_aes_ecb_test(void)
2318 {
2319 #define AES_BLOCK_SIZE	16
2320 #define AES_EXTERN_ITER	100
2321 #define AES_INTERN_ITER	1000
2322 	struct fips_val val = {NULL, 0}, val_key;
2323 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
2324 	uint32_t i, j, k;
2325 	int ret;
2326 
2327 	for (i = 0; i < AES_EXTERN_ITER; i++) {
2328 		if (i != 0)
2329 			update_info_vec(i);
2330 
2331 		fips_test_write_one_case();
2332 
2333 		for (j = 0; j < AES_INTERN_ITER; j++) {
2334 			ret = fips_run_test();
2335 			if (ret < 0) {
2336 				if (ret == -EPERM) {
2337 					if (info.file_type == FIPS_TYPE_JSON)
2338 						return ret;
2339 
2340 					fprintf(info.fp_wr, "Bypass\n");
2341 					return 0;
2342 				}
2343 
2344 				return ret;
2345 			}
2346 
2347 			ret = get_writeback_data(&val);
2348 			if (ret < 0)
2349 				return ret;
2350 
2351 			if (info.op == FIPS_TEST_ENC_AUTH_GEN)
2352 				memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE);
2353 			else
2354 				memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE);
2355 
2356 			if (j == AES_INTERN_ITER - 1)
2357 				continue;
2358 
2359 			memcpy(prev_out, val.val, AES_BLOCK_SIZE);
2360 		}
2361 
2362 		info.parse_writeback(&val);
2363 		fprintf(info.fp_wr, "\n");
2364 
2365 		if (i == AES_EXTERN_ITER - 1)
2366 			continue;
2367 
2368 		/** update key */
2369 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2370 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
2371 			switch (vec.cipher_auth.key.len) {
2372 			case 16:
2373 				val_key.val[k] ^= val.val[k];
2374 				break;
2375 			case 24:
2376 				if (k < 8)
2377 					val_key.val[k] ^= prev_out[k + 8];
2378 				else
2379 					val_key.val[k] ^= val.val[k - 8];
2380 				break;
2381 			case 32:
2382 				if (k < 16)
2383 					val_key.val[k] ^= prev_out[k];
2384 				else
2385 					val_key.val[k] ^= val.val[k - 16];
2386 				break;
2387 			default:
2388 				return -1;
2389 			}
2390 		}
2391 	}
2392 
2393 	rte_free(val.val);
2394 
2395 	return 0;
2396 }
2397 static int
2398 fips_mct_aes_test(void)
2399 {
2400 #define AES_BLOCK_SIZE	16
2401 #define AES_EXTERN_ITER	100
2402 #define AES_INTERN_ITER	1000
2403 	struct fips_val val[3] = {{NULL, 0},}, val_key,  pt, ct, iv;
2404 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
2405 	uint8_t prev_in[AES_BLOCK_SIZE] = {0};
2406 	uint32_t i, j, k;
2407 	int ret;
2408 
2409 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB)
2410 		return fips_mct_aes_ecb_test();
2411 
2412 	pt.len = vec.pt.len;
2413 	pt.val = rte_malloc(NULL, pt.len, 0);
2414 	ct.len = vec.ct.len;
2415 	ct.val = rte_malloc(NULL, ct.len, 0);
2416 	iv.len = vec.iv.len;
2417 	iv.val = rte_malloc(NULL, iv.len, 0);
2418 	for (i = 0; i < AES_EXTERN_ITER; i++) {
2419 		if (info.file_type != FIPS_TYPE_JSON) {
2420 			if (i != 0)
2421 				update_info_vec(i);
2422 
2423 			fips_test_write_one_case();
2424 		}
2425 
2426 		for (j = 0; j < AES_INTERN_ITER; j++) {
2427 			ret = fips_run_test();
2428 			if (ret < 0) {
2429 				if (ret == -EPERM) {
2430 					if (info.file_type == FIPS_TYPE_JSON)
2431 						return ret;
2432 
2433 					fprintf(info.fp_wr, "Bypass\n");
2434 					return 0;
2435 				}
2436 
2437 				return ret;
2438 			}
2439 
2440 			ret = get_writeback_data(&val[0]);
2441 			if (ret < 0)
2442 				return ret;
2443 
2444 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2445 				memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE);
2446 
2447 			if (j == 0) {
2448 				memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
2449 				memcpy(pt.val, vec.pt.val, pt.len);
2450 				memcpy(ct.val, vec.ct.val, ct.len);
2451 				memcpy(iv.val, vec.iv.val, iv.len);
2452 
2453 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2454 					memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE);
2455 					memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2456 					val[1].val = pt.val;
2457 					val[1].len = pt.len;
2458 					val[2].val = iv.val;
2459 					val[2].len = iv.len;
2460 				} else {
2461 					memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE);
2462 					memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
2463 					val[1].val = ct.val;
2464 					val[1].len = ct.len;
2465 					val[2].val = iv.val;
2466 					val[2].len = iv.len;
2467 				}
2468 				continue;
2469 			}
2470 
2471 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2472 				memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2473 				memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE);
2474 			} else {
2475 				memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
2476 				memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE);
2477 			}
2478 
2479 			if (j == AES_INTERN_ITER - 1)
2480 				continue;
2481 
2482 			memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
2483 		}
2484 
2485 		info.parse_writeback(val);
2486 		if (info.file_type != FIPS_TYPE_JSON)
2487 			fprintf(info.fp_wr, "\n");
2488 
2489 		if (i == AES_EXTERN_ITER - 1)
2490 			continue;
2491 
2492 		/** update key */
2493 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2494 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
2495 			switch (vec.cipher_auth.key.len) {
2496 			case 16:
2497 				val_key.val[k] ^= val[0].val[k];
2498 				break;
2499 			case 24:
2500 				if (k < 8)
2501 					val_key.val[k] ^= prev_out[k + 8];
2502 				else
2503 					val_key.val[k] ^= val[0].val[k - 8];
2504 				break;
2505 			case 32:
2506 				if (k < 16)
2507 					val_key.val[k] ^= prev_out[k];
2508 				else
2509 					val_key.val[k] ^= val[0].val[k - 16];
2510 				break;
2511 			default:
2512 				return -1;
2513 			}
2514 		}
2515 
2516 		if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2517 			memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2518 	}
2519 
2520 	rte_free(val[0].val);
2521 	rte_free(pt.val);
2522 	rte_free(ct.val);
2523 	rte_free(iv.val);
2524 
2525 	return 0;
2526 }
2527 
2528 static int
2529 fips_mct_sha_test(void)
2530 {
2531 #define SHA_EXTERN_ITER	100
2532 #define SHA_INTERN_ITER	1000
2533 	uint8_t md_blocks = info.interim_info.sha_data.md_blocks;
2534 	struct fips_val val = {NULL, 0};
2535 	struct fips_val  md[md_blocks];
2536 	int ret;
2537 	uint32_t i, j, k, offset, max_outlen;
2538 
2539 	max_outlen = md_blocks * vec.cipher_auth.digest.len;
2540 
2541 	rte_free(vec.cipher_auth.digest.val);
2542 	vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0);
2543 
2544 	if (vec.pt.val)
2545 		memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len);
2546 
2547 	rte_free(vec.pt.val);
2548 	vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*md_blocks), 0);
2549 
2550 	for (i = 0; i < md_blocks; i++)
2551 		md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0);
2552 
2553 	if (info.file_type != FIPS_TYPE_JSON) {
2554 		fips_test_write_one_case();
2555 		fprintf(info.fp_wr, "\n");
2556 	}
2557 
2558 	for (j = 0; j < SHA_EXTERN_ITER; j++) {
2559 		for (i = 0; i < md_blocks; i++) {
2560 			memcpy(md[i].val, vec.cipher_auth.digest.val,
2561 				vec.cipher_auth.digest.len);
2562 			md[i].len = vec.cipher_auth.digest.len;
2563 		}
2564 
2565 		for (i = 0; i < (SHA_INTERN_ITER); i++) {
2566 			offset = 0;
2567 			for (k = 0; k < md_blocks; k++) {
2568 				memcpy(vec.pt.val + offset, md[k].val, (size_t)md[k].len);
2569 				offset += md[k].len;
2570 			}
2571 			vec.pt.len = offset;
2572 
2573 			ret = fips_run_test();
2574 			if (ret < 0) {
2575 				if (ret == -EPERM || ret == -ENOTSUP) {
2576 					if (info.file_type == FIPS_TYPE_JSON)
2577 						return ret;
2578 
2579 					fprintf(info.fp_wr, "Bypass\n\n");
2580 					return 0;
2581 				}
2582 				return ret;
2583 			}
2584 
2585 			ret = get_writeback_data(&val);
2586 			if (ret < 0)
2587 				return ret;
2588 
2589 			for (k = 1; k < md_blocks; k++) {
2590 				memcpy(md[k-1].val, md[k].val, md[k].len);
2591 				md[k-1].len = md[k].len;
2592 			}
2593 
2594 			memcpy(md[md_blocks-1].val, (val.val + vec.pt.len),
2595 				vec.cipher_auth.digest.len);
2596 			md[md_blocks-1].len = vec.cipher_auth.digest.len;
2597 		}
2598 
2599 		memcpy(vec.cipher_auth.digest.val, md[md_blocks-1].val, md[md_blocks-1].len);
2600 		vec.cipher_auth.digest.len = md[md_blocks-1].len;
2601 
2602 		if (info.file_type != FIPS_TYPE_JSON)
2603 			fprintf(info.fp_wr, "COUNT = %u\n", j);
2604 
2605 		info.parse_writeback(&val);
2606 
2607 		if (info.file_type != FIPS_TYPE_JSON)
2608 			fprintf(info.fp_wr, "\n");
2609 	}
2610 
2611 	for (i = 0; i < (md_blocks); i++)
2612 		rte_free(md[i].val);
2613 
2614 	rte_free(vec.pt.val);
2615 
2616 	rte_free(val.val);
2617 	return 0;
2618 }
2619 
2620 static int
2621 fips_mct_shake_test(void)
2622 {
2623 #define SHAKE_EXTERN_ITER	100
2624 #define SHAKE_INTERN_ITER	1000
2625 	uint32_t i, j, range, outlen, max_outlen;
2626 	struct fips_val val = {NULL, 0}, md;
2627 	uint8_t rightmost[2];
2628 	uint16_t *rightptr;
2629 	int ret;
2630 
2631 	max_outlen = vec.cipher_auth.digest.len;
2632 
2633 	rte_free(vec.cipher_auth.digest.val);
2634 	vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0);
2635 
2636 	if (vec.pt.val)
2637 		memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.pt.len);
2638 
2639 	rte_free(vec.pt.val);
2640 	vec.pt.val = rte_malloc(NULL, 16, 0);
2641 	vec.pt.len = 16;
2642 
2643 	md.val = rte_malloc(NULL, max_outlen, 0);
2644 	md.len = max_outlen;
2645 
2646 	if (info.file_type != FIPS_TYPE_JSON) {
2647 		fips_test_write_one_case();
2648 		fprintf(info.fp_wr, "\n");
2649 	}
2650 
2651 	range = max_outlen - info.interim_info.sha_data.min_outlen + 1;
2652 	outlen = max_outlen;
2653 	for (j = 0; j < SHAKE_EXTERN_ITER; j++) {
2654 		memset(md.val, 0, max_outlen);
2655 		memcpy(md.val, vec.cipher_auth.digest.val,
2656 			vec.cipher_auth.digest.len);
2657 
2658 		for (i = 0; i < (SHAKE_INTERN_ITER); i++) {
2659 			memset(vec.pt.val, 0, vec.pt.len);
2660 			memcpy(vec.pt.val, md.val, vec.pt.len);
2661 			vec.cipher_auth.digest.len = outlen;
2662 			ret = fips_run_test();
2663 			if (ret < 0) {
2664 				if (ret == -EPERM || ret == -ENOTSUP) {
2665 					if (info.file_type == FIPS_TYPE_JSON)
2666 						return ret;
2667 
2668 					fprintf(info.fp_wr, "Bypass\n\n");
2669 					return 0;
2670 				}
2671 				return ret;
2672 			}
2673 
2674 			ret = get_writeback_data(&val);
2675 			if (ret < 0)
2676 				return ret;
2677 
2678 			memset(md.val, 0, max_outlen);
2679 			memcpy(md.val, (val.val + vec.pt.len),
2680 				vec.cipher_auth.digest.len);
2681 			md.len = outlen;
2682 			rightmost[0] = md.val[md.len-1];
2683 			rightmost[1] = md.val[md.len-2];
2684 			rightptr = (uint16_t *)rightmost;
2685 			outlen = info.interim_info.sha_data.min_outlen +
2686 				(*rightptr % range);
2687 		}
2688 
2689 		memcpy(vec.cipher_auth.digest.val, md.val, md.len);
2690 		vec.cipher_auth.digest.len = md.len;
2691 
2692 		if (info.file_type != FIPS_TYPE_JSON)
2693 			fprintf(info.fp_wr, "COUNT = %u\n", j);
2694 
2695 		info.parse_writeback(&val);
2696 
2697 		if (info.file_type != FIPS_TYPE_JSON)
2698 			fprintf(info.fp_wr, "\n");
2699 	}
2700 
2701 	rte_free(md.val);
2702 	rte_free(vec.pt.val);
2703 	rte_free(val.val);
2704 	return 0;
2705 }
2706 
2707 static int
2708 init_test_ops(void)
2709 {
2710 	switch (info.algo) {
2711 	case FIPS_TEST_ALGO_AES_CBC:
2712 	case FIPS_TEST_ALGO_AES_CTR:
2713 	case FIPS_TEST_ALGO_AES:
2714 		test_ops.prepare_sym_op = prepare_cipher_op;
2715 		test_ops.prepare_sym_xform  = prepare_aes_xform;
2716 		if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)
2717 			test_ops.test = fips_mct_aes_test;
2718 		else
2719 			test_ops.test = fips_generic_test;
2720 		break;
2721 	case FIPS_TEST_ALGO_HMAC:
2722 		test_ops.prepare_sym_op = prepare_auth_op;
2723 		test_ops.prepare_sym_xform = prepare_hmac_xform;
2724 		test_ops.test = fips_generic_test;
2725 		break;
2726 	case FIPS_TEST_ALGO_TDES:
2727 		test_ops.prepare_sym_op = prepare_cipher_op;
2728 		test_ops.prepare_sym_xform = prepare_tdes_xform;
2729 		if (info.interim_info.tdes_data.test_type == TDES_MCT)
2730 			test_ops.test = fips_mct_tdes_test;
2731 		else
2732 			test_ops.test = fips_generic_test;
2733 		break;
2734 	case FIPS_TEST_ALGO_AES_GMAC:
2735 		test_ops.prepare_sym_op = prepare_auth_op;
2736 		test_ops.prepare_sym_xform = prepare_gmac_xform;
2737 		test_ops.test = fips_generic_test;
2738 		break;
2739 	case FIPS_TEST_ALGO_AES_GCM:
2740 		test_ops.prepare_sym_op = prepare_aead_op;
2741 		test_ops.prepare_sym_xform = prepare_gcm_xform;
2742 		test_ops.test = fips_generic_test;
2743 		break;
2744 	case FIPS_TEST_ALGO_AES_CMAC:
2745 		test_ops.prepare_sym_op = prepare_auth_op;
2746 		test_ops.prepare_sym_xform = prepare_cmac_xform;
2747 		test_ops.test = fips_generic_test;
2748 		break;
2749 	case FIPS_TEST_ALGO_AES_CCM:
2750 		test_ops.prepare_sym_op = prepare_aead_op;
2751 		test_ops.prepare_sym_xform = prepare_ccm_xform;
2752 		test_ops.test = fips_generic_test;
2753 		break;
2754 	case FIPS_TEST_ALGO_SHA:
2755 		test_ops.prepare_sym_op = prepare_auth_op;
2756 		test_ops.prepare_sym_xform = prepare_sha_xform;
2757 		if (info.interim_info.sha_data.test_type == SHA_MCT)
2758 			if (info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_128 ||
2759 				info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_256)
2760 				test_ops.test = fips_mct_shake_test;
2761 			else
2762 				test_ops.test = fips_mct_sha_test;
2763 		else
2764 			test_ops.test = fips_generic_test;
2765 		break;
2766 	case FIPS_TEST_ALGO_AES_XTS:
2767 		test_ops.prepare_sym_op = prepare_cipher_op;
2768 		test_ops.prepare_sym_xform = prepare_xts_xform;
2769 		test_ops.test = fips_generic_test;
2770 		break;
2771 	case FIPS_TEST_ALGO_RSA:
2772 		test_ops.prepare_asym_op = prepare_rsa_op;
2773 		test_ops.prepare_asym_xform = prepare_rsa_xform;
2774 		test_ops.test = fips_generic_test;
2775 		break;
2776 	case FIPS_TEST_ALGO_ECDSA:
2777 		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
2778 			test_ops.prepare_asym_op = prepare_ecfpm_op;
2779 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
2780 			test_ops.test = fips_generic_test;
2781 		} else {
2782 			test_ops.prepare_asym_op = prepare_ecdsa_op;
2783 			test_ops.prepare_asym_xform = prepare_ecdsa_xform;
2784 			test_ops.test = fips_generic_test;
2785 		}
2786 		break;
2787 	case FIPS_TEST_ALGO_EDDSA:
2788 		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
2789 			test_ops.prepare_asym_op = prepare_edfpm_op;
2790 			test_ops.prepare_asym_xform = prepare_edfpm_xform;
2791 			test_ops.test = fips_generic_test;
2792 		} else {
2793 			test_ops.prepare_asym_op = prepare_eddsa_op;
2794 			test_ops.prepare_asym_xform = prepare_eddsa_xform;
2795 			test_ops.test = fips_generic_test;
2796 		}
2797 		break;
2798 	default:
2799 		if (strstr(info.file_name, "TECB") ||
2800 				strstr(info.file_name, "TCBC")) {
2801 			info.algo = FIPS_TEST_ALGO_TDES;
2802 			test_ops.prepare_sym_op = prepare_cipher_op;
2803 			test_ops.prepare_sym_xform = prepare_tdes_xform;
2804 			if (info.interim_info.tdes_data.test_type == TDES_MCT)
2805 				test_ops.test = fips_mct_tdes_test;
2806 			else
2807 				test_ops.test = fips_generic_test;
2808 			break;
2809 		}
2810 		return -1;
2811 	}
2812 
2813 	return 0;
2814 }
2815 
2816 static void
2817 print_test_block(void)
2818 {
2819 	uint32_t i;
2820 
2821 	for (i = 0; i < info.nb_vec_lines; i++)
2822 		printf("%s\n", info.vec[i]);
2823 
2824 	printf("\n");
2825 }
2826 
2827 static int
2828 fips_test_one_file(void)
2829 {
2830 	int fetch_ret = 0, ret;
2831 
2832 	ret = init_test_ops();
2833 	if (ret < 0) {
2834 		RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret);
2835 		return ret;
2836 	}
2837 
2838 	while (ret >= 0 && fetch_ret == 0) {
2839 		fetch_ret = fips_test_fetch_one_block();
2840 		if (fetch_ret < 0) {
2841 			RTE_LOG(ERR, USER1, "Error %i: Fetch block\n",
2842 					fetch_ret);
2843 			ret = fetch_ret;
2844 			goto error_one_case;
2845 		}
2846 
2847 		if (info.nb_vec_lines == 0) {
2848 			if (fetch_ret == -EOF)
2849 				break;
2850 
2851 			fprintf(info.fp_wr, "\n");
2852 			continue;
2853 		}
2854 
2855 		ret = fips_test_parse_one_case();
2856 		switch (ret) {
2857 		case 0:
2858 			ret = test_ops.test();
2859 			if (ret == 0)
2860 				break;
2861 			RTE_LOG(ERR, USER1, "Error %i: test block\n",
2862 					ret);
2863 			goto error_one_case;
2864 		case 1:
2865 			break;
2866 		default:
2867 			RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
2868 					ret);
2869 			goto error_one_case;
2870 		}
2871 
2872 		continue;
2873 error_one_case:
2874 		print_test_block();
2875 	}
2876 
2877 	fips_test_clear();
2878 
2879 	if (env.digest) {
2880 		rte_free(env.digest);
2881 		env.digest = NULL;
2882 		env.digest_len = 0;
2883 	}
2884 	rte_pktmbuf_free(env.mbuf);
2885 
2886 	return ret;
2887 }
2888 
2889 #ifdef USE_JANSSON
2890 static int
2891 fips_test_json_init_writeback(void)
2892 {
2893 	json_t *session_info, *session_write;
2894 	session_info = json_array_get(json_info.json_root, 0);
2895 	session_write = json_object();
2896 	json_info.json_write_root = json_array();
2897 
2898 	json_object_set(session_write, "jwt",
2899 		json_object_get(session_info, "jwt"));
2900 	json_object_set(session_write, "url",
2901 		json_object_get(session_info, "url"));
2902 	json_object_set(session_write, "isSample",
2903 		json_object_get(session_info, "isSample"));
2904 
2905 	json_info.is_sample = json_boolean_value(
2906 		json_object_get(session_info, "isSample"));
2907 
2908 	json_array_append_new(json_info.json_write_root, session_write);
2909 	return 0;
2910 }
2911 
2912 static int
2913 fips_test_one_test_case(void)
2914 {
2915 	int ret;
2916 
2917 	ret = fips_test_parse_one_json_case();
2918 
2919 	switch (ret) {
2920 	case 0:
2921 		ret = test_ops.test();
2922 		if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP))
2923 			break;
2924 		RTE_LOG(ERR, USER1, "Error %i: test block\n",
2925 				ret);
2926 		break;
2927 	default:
2928 		RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
2929 				ret);
2930 	}
2931 	return ret;
2932 }
2933 
2934 static int
2935 fips_test_one_test_group(void)
2936 {
2937 	int ret;
2938 	json_t *tests, *write_tests;
2939 	size_t test_idx, tests_size;
2940 
2941 	write_tests = json_array();
2942 	json_info.json_write_group = json_object();
2943 	json_object_set(json_info.json_write_group, "tgId",
2944 		json_object_get(json_info.json_test_group, "tgId"));
2945 	json_object_set_new(json_info.json_write_group, "tests", write_tests);
2946 
2947 	switch (info.algo) {
2948 	case FIPS_TEST_ALGO_AES_GMAC:
2949 	case FIPS_TEST_ALGO_AES_GCM:
2950 		ret = parse_test_gcm_json_init();
2951 		break;
2952 	case FIPS_TEST_ALGO_AES_CCM:
2953 		ret = parse_test_ccm_json_init();
2954 		break;
2955 	case FIPS_TEST_ALGO_HMAC:
2956 		ret = parse_test_hmac_json_init();
2957 		break;
2958 	case FIPS_TEST_ALGO_AES_CMAC:
2959 		ret = parse_test_cmac_json_init();
2960 		break;
2961 	case FIPS_TEST_ALGO_AES_XTS:
2962 		ret = parse_test_xts_json_init();
2963 		break;
2964 	case FIPS_TEST_ALGO_AES_CBC:
2965 	case FIPS_TEST_ALGO_AES_CTR:
2966 	case FIPS_TEST_ALGO_AES:
2967 		ret = parse_test_aes_json_init();
2968 		break;
2969 	case FIPS_TEST_ALGO_SHA:
2970 		ret = parse_test_sha_json_init();
2971 		break;
2972 	case FIPS_TEST_ALGO_TDES:
2973 		ret = parse_test_tdes_json_init();
2974 		break;
2975 	case FIPS_TEST_ALGO_RSA:
2976 		ret = parse_test_rsa_json_init();
2977 		break;
2978 	case FIPS_TEST_ALGO_ECDSA:
2979 		ret = parse_test_ecdsa_json_init();
2980 		break;
2981 	case FIPS_TEST_ALGO_EDDSA:
2982 		ret = parse_test_eddsa_json_init();
2983 		break;
2984 	default:
2985 		return -EINVAL;
2986 	}
2987 
2988 	if (ret < 0)
2989 		return ret;
2990 
2991 	ret = fips_test_parse_one_json_group();
2992 	if (ret < 0)
2993 		return ret;
2994 
2995 	ret = init_test_ops();
2996 	if (ret < 0)
2997 		return ret;
2998 
2999 	tests = json_object_get(json_info.json_test_group, "tests");
3000 	tests_size = json_array_size(tests);
3001 	for (test_idx = 0; test_idx < tests_size; test_idx++) {
3002 		json_info.json_test_case = json_array_get(tests, test_idx);
3003 		if (fips_test_one_test_case() == 0)
3004 			json_array_append_new(write_tests, json_info.json_write_case);
3005 	}
3006 
3007 	return 0;
3008 }
3009 
3010 static int
3011 fips_test_one_vector_set(void)
3012 {
3013 	int ret;
3014 	json_t *test_groups, *write_groups, *write_version, *write_set, *mode;
3015 	size_t group_idx, num_groups;
3016 
3017 	test_groups = json_object_get(json_info.json_vector_set, "testGroups");
3018 	num_groups = json_array_size(test_groups);
3019 
3020 	json_info.json_write_set = json_array();
3021 	write_version = json_object();
3022 	json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION));
3023 	json_array_append_new(json_info.json_write_set, write_version);
3024 
3025 	write_set = json_object();
3026 	json_array_append(json_info.json_write_set, write_set);
3027 	write_groups = json_array();
3028 
3029 	json_object_set(write_set, "vsId",
3030 		json_object_get(json_info.json_vector_set, "vsId"));
3031 	json_object_set(write_set, "algorithm",
3032 		json_object_get(json_info.json_vector_set, "algorithm"));
3033 	mode = json_object_get(json_info.json_vector_set, "mode");
3034 	if (mode != NULL)
3035 		json_object_set_new(write_set, "mode", mode);
3036 
3037 	json_object_set(write_set, "revision",
3038 		json_object_get(json_info.json_vector_set, "revision"));
3039 	json_object_set_new(write_set, "isSample",
3040 		json_boolean(json_info.is_sample));
3041 	json_object_set_new(write_set, "testGroups", write_groups);
3042 
3043 	ret = fips_test_parse_one_json_vector_set();
3044 	if (ret < 0) {
3045 		RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n",
3046 			json_string_value(json_object_get(json_info.json_vector_set, "algorithm")));
3047 		return ret;
3048 	}
3049 
3050 	for (group_idx = 0; group_idx < num_groups; group_idx++) {
3051 		json_info.json_test_group = json_array_get(test_groups, group_idx);
3052 		ret = fips_test_one_test_group();
3053 		json_array_append_new(write_groups, json_info.json_write_group);
3054 	}
3055 
3056 	return 0;
3057 }
3058 
3059 static int
3060 fips_test_one_json_file(void)
3061 {
3062 	size_t vector_set_idx, root_size;
3063 
3064 	root_size = json_array_size(json_info.json_root);
3065 	fips_test_json_init_writeback();
3066 
3067 	for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) {
3068 		/* Vector set index starts at 1, the 0th index contains test session
3069 		 * information.
3070 		 */
3071 		json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx);
3072 		fips_test_one_vector_set();
3073 		json_array_append_new(json_info.json_write_root, json_info.json_write_set);
3074 		json_incref(json_info.json_write_set);
3075 	}
3076 
3077 	json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4));
3078 	json_decref(json_info.json_write_root);
3079 
3080 	return 0;
3081 }
3082 #endif /* USE_JANSSON */
3083