xref: /dpdk/examples/fips_validation/main.c (revision 1e472b5746aeb6189fa254ab82ce4cd27999f868)
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 		vec.cipher_auth.digest.len =
1945 			parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth);
1946 		test_ops.prepare_sym_xform = prepare_sha_xform;
1947 		test_ops.prepare_sym_op = prepare_auth_op;
1948 
1949 		env.op = env.sym.op;
1950 		ret = fips_run_sym_test();
1951 		if (ret < 0)
1952 			return ret;
1953 	}
1954 
1955 	env.op = env.asym.op;
1956 	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
1957 		fips_prepare_asym_xform_t old_xform;
1958 		fips_prepare_op_t old_op;
1959 
1960 		old_xform = test_ops.prepare_asym_xform;
1961 		old_op = test_ops.prepare_asym_op;
1962 
1963 		if (info.algo == FIPS_TEST_ALGO_ECDSA &&
1964 		    info.interim_info.ecdsa_data.pubkey_gen == 1) {
1965 			info.op = FIPS_TEST_ASYM_KEYGEN;
1966 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
1967 			test_ops.prepare_asym_op = prepare_ecfpm_op;
1968 
1969 			ret = fips_run_asym_test();
1970 			if (ret < 0)
1971 				return ret;
1972 
1973 			info.post_interim_writeback(NULL);
1974 			info.interim_info.ecdsa_data.pubkey_gen = 0;
1975 
1976 		} else if (info.algo == FIPS_TEST_ALGO_EDDSA &&
1977 				   info.interim_info.eddsa_data.pubkey_gen == 1) {
1978 			info.op = FIPS_TEST_ASYM_KEYGEN;
1979 			test_ops.prepare_asym_xform = prepare_edfpm_xform;
1980 			test_ops.prepare_asym_op = prepare_edfpm_op;
1981 
1982 			const struct rte_cryptodev_asymmetric_xform_capability *cap;
1983 			struct rte_cryptodev_asym_capability_idx cap_idx;
1984 
1985 			cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
1986 			cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1987 			if (!cap) {
1988 				RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1989 						env.dev_id);
1990 				return -EINVAL;
1991 			}
1992 
1993 			if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) {
1994 				ret = fips_run_asym_test();
1995 				if (ret < 0)
1996 					return ret;
1997 			} else {
1998 				/* Below is only a workaround by using known keys. */
1999 				struct rte_crypto_asym_xform xform = {0};
2000 
2001 				prepare_edfpm_xform(&xform);
2002 				prepare_edfpm_op();
2003 				uint8_t pkey25519[] = {
2004 					0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
2005 					0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
2006 					0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
2007 					0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
2008 				};
2009 				uint8_t q25519[] = {
2010 					0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
2011 					0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
2012 					0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
2013 					0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
2014 				};
2015 				uint8_t pkey448[] = {
2016 					0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
2017 					0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
2018 					0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
2019 					0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
2020 					0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
2021 					0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
2022 					0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
2023 					0x01
2024 				};
2025 				uint8_t q448[] = {
2026 					0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
2027 					0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
2028 					0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
2029 					0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
2030 					0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
2031 					0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
2032 					0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
2033 					0x00
2034 				};
2035 				if (info.interim_info.eddsa_data.curve_id ==
2036 					RTE_CRYPTO_EC_GROUP_ED25519) {
2037 					memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519));
2038 					vec.eddsa.pkey.len = 32;
2039 					memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519));
2040 					vec.eddsa.q.len = 32;
2041 				} else {
2042 					memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448));
2043 					vec.eddsa.pkey.len = 32;
2044 					memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448));
2045 					vec.eddsa.q.len = 32;
2046 				}
2047 			}
2048 			info.post_interim_writeback(NULL);
2049 			info.interim_info.eddsa_data.pubkey_gen = 0;
2050 
2051 		}
2052 
2053 		test_ops.prepare_asym_xform = old_xform;
2054 		test_ops.prepare_asym_op = old_op;
2055 		info.op = FIPS_TEST_ASYM_SIGGEN;
2056 		ret = fips_run_asym_test();
2057 	} else {
2058 		ret = fips_run_asym_test();
2059 	}
2060 
2061 	return ret;
2062 }
2063 
2064 static int
2065 fips_generic_test(void)
2066 {
2067 	struct fips_val val = {NULL, 0};
2068 	int ret;
2069 
2070 	if (info.file_type != FIPS_TYPE_JSON)
2071 		fips_test_write_one_case();
2072 
2073 	ret = fips_run_test();
2074 	if (ret < 0) {
2075 		if (ret == -EPERM || ret == -ENOTSUP) {
2076 			if (info.file_type == FIPS_TYPE_JSON)
2077 				return ret;
2078 
2079 			fprintf(info.fp_wr, "Bypass\n\n");
2080 			return 0;
2081 		}
2082 
2083 		return ret;
2084 	}
2085 
2086 	if (!env.is_asym_test) {
2087 		ret = get_writeback_data(&val);
2088 		if (ret < 0)
2089 			return ret;
2090 	}
2091 
2092 	switch (info.file_type) {
2093 	case FIPS_TYPE_REQ:
2094 	case FIPS_TYPE_RSP:
2095 	case FIPS_TYPE_JSON:
2096 		if (info.parse_writeback == NULL)
2097 			return -EPERM;
2098 		ret = info.parse_writeback(&val);
2099 		if (ret < 0)
2100 			return ret;
2101 		break;
2102 	case FIPS_TYPE_FAX:
2103 		if (info.kat_check == NULL)
2104 			return -EPERM;
2105 		ret = info.kat_check(&val);
2106 		if (ret < 0)
2107 			return ret;
2108 		break;
2109 	default:
2110 		break;
2111 	}
2112 
2113 	if (info.file_type != FIPS_TYPE_JSON)
2114 		fprintf(info.fp_wr, "\n");
2115 	rte_free(val.val);
2116 
2117 	return 0;
2118 }
2119 
2120 static int
2121 fips_mct_tdes_test(void)
2122 {
2123 #define TDES_BLOCK_SIZE		8
2124 #define TDES_EXTERN_ITER	400
2125 #define TDES_INTERN_ITER	10000
2126 	struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv;
2127 	uint8_t prev_out[TDES_BLOCK_SIZE] = {0};
2128 	uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0};
2129 	uint8_t prev_in[TDES_BLOCK_SIZE] = {0};
2130 	uint32_t i, j, k;
2131 	int ret;
2132 	int test_mode = info.interim_info.tdes_data.test_mode;
2133 
2134 	pt.len = vec.pt.len;
2135 	pt.val = rte_malloc(NULL, pt.len, 0);
2136 	ct.len = vec.ct.len;
2137 	ct.val = rte_malloc(NULL, ct.len, 0);
2138 	iv.len = vec.iv.len;
2139 	iv.val = rte_malloc(NULL, iv.len, 0);
2140 
2141 	for (i = 0; i < TDES_EXTERN_ITER; i++) {
2142 		if (info.file_type != FIPS_TYPE_JSON) {
2143 			if ((i == 0) && (info.version == 21.4f)) {
2144 				if (!(strstr(info.vec[0], "COUNT")))
2145 					fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0);
2146 			}
2147 
2148 			if (i != 0)
2149 				update_info_vec(i);
2150 
2151 			fips_test_write_one_case();
2152 		}
2153 
2154 		for (j = 0; j < TDES_INTERN_ITER; j++) {
2155 			ret = fips_run_test();
2156 			if (ret < 0) {
2157 				if (ret == -EPERM) {
2158 					if (info.file_type == FIPS_TYPE_JSON)
2159 						return ret;
2160 
2161 					fprintf(info.fp_wr, "Bypass\n");
2162 					return 0;
2163 				}
2164 				return ret;
2165 			}
2166 
2167 			ret = get_writeback_data(&val[0]);
2168 			if (ret < 0)
2169 				return ret;
2170 
2171 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2172 				memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE);
2173 
2174 			if (j == 0) {
2175 				memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
2176 				memcpy(pt.val, vec.pt.val, pt.len);
2177 				memcpy(ct.val, vec.ct.val, ct.len);
2178 				memcpy(iv.val, vec.iv.val, iv.len);
2179 
2180 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2181 					if (test_mode == TDES_MODE_ECB) {
2182 						memcpy(vec.pt.val, val[0].val,
2183 							   TDES_BLOCK_SIZE);
2184 					} else {
2185 						memcpy(vec.pt.val, vec.iv.val,
2186 							   TDES_BLOCK_SIZE);
2187 						memcpy(vec.iv.val, val[0].val,
2188 							   TDES_BLOCK_SIZE);
2189 					}
2190 					val[1].val = pt.val;
2191 					val[1].len = pt.len;
2192 					val[2].val = iv.val;
2193 					val[2].len = iv.len;
2194 				} else {
2195 					if (test_mode == TDES_MODE_ECB) {
2196 						memcpy(vec.ct.val, val[0].val,
2197 							   TDES_BLOCK_SIZE);
2198 					} else {
2199 						memcpy(vec.iv.val, vec.ct.val,
2200 							   TDES_BLOCK_SIZE);
2201 						memcpy(vec.ct.val, val[0].val,
2202 							   TDES_BLOCK_SIZE);
2203 					}
2204 					val[1].val = ct.val;
2205 					val[1].len = ct.len;
2206 					val[2].val = iv.val;
2207 					val[2].len = iv.len;
2208 				}
2209 				continue;
2210 			}
2211 
2212 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2213 				if (test_mode == TDES_MODE_ECB) {
2214 					memcpy(vec.pt.val, val[0].val,
2215 						   TDES_BLOCK_SIZE);
2216 				} else {
2217 					memcpy(vec.iv.val, val[0].val,
2218 						   TDES_BLOCK_SIZE);
2219 					memcpy(vec.pt.val, prev_out,
2220 						   TDES_BLOCK_SIZE);
2221 				}
2222 			} else {
2223 				if (test_mode == TDES_MODE_ECB) {
2224 					memcpy(vec.ct.val, val[0].val,
2225 						   TDES_BLOCK_SIZE);
2226 				} else {
2227 					memcpy(vec.iv.val, vec.ct.val,
2228 						   TDES_BLOCK_SIZE);
2229 					memcpy(vec.ct.val, val[0].val,
2230 						   TDES_BLOCK_SIZE);
2231 				}
2232 			}
2233 
2234 			if (j == TDES_INTERN_ITER - 1)
2235 				continue;
2236 
2237 			memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
2238 
2239 			if (j == TDES_INTERN_ITER - 3)
2240 				memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE);
2241 		}
2242 
2243 		info.parse_writeback(val);
2244 		if (info.file_type != FIPS_TYPE_JSON)
2245 			fprintf(info.fp_wr, "\n");
2246 
2247 		if (i == TDES_EXTERN_ITER - 1)
2248 			continue;
2249 
2250 		/** update key */
2251 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2252 
2253 		if (info.interim_info.tdes_data.nb_keys == 0) {
2254 			if (memcmp(val_key.val, val_key.val + 8, 8) == 0)
2255 				info.interim_info.tdes_data.nb_keys = 1;
2256 			else if (memcmp(val_key.val, val_key.val + 16, 8) == 0)
2257 				info.interim_info.tdes_data.nb_keys = 2;
2258 			else
2259 				info.interim_info.tdes_data.nb_keys = 3;
2260 
2261 		}
2262 
2263 		for (k = 0; k < TDES_BLOCK_SIZE; k++) {
2264 
2265 			switch (info.interim_info.tdes_data.nb_keys) {
2266 			case 3:
2267 				val_key.val[k] ^= val[0].val[k];
2268 				val_key.val[k + 8] ^= prev_out[k];
2269 				val_key.val[k + 16] ^= prev_prev_out[k];
2270 				break;
2271 			case 2:
2272 				val_key.val[k] ^= val[0].val[k];
2273 				val_key.val[k + 8] ^= prev_out[k];
2274 				val_key.val[k + 16] ^= val[0].val[k];
2275 				break;
2276 			default: /* case 1 */
2277 				val_key.val[k] ^= val[0].val[k];
2278 				val_key.val[k + 8] ^= val[0].val[k];
2279 				val_key.val[k + 16] ^= val[0].val[k];
2280 				break;
2281 			}
2282 
2283 		}
2284 
2285 		for (k = 0; k < 24; k++)
2286 			val_key.val[k] = (rte_popcount32(val_key.val[k]) &
2287 					0x1) ?
2288 					val_key.val[k] : (val_key.val[k] ^ 0x1);
2289 
2290 		if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2291 			if (test_mode == TDES_MODE_ECB) {
2292 				memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE);
2293 			} else {
2294 				memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE);
2295 				memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
2296 			}
2297 		} else {
2298 			if (test_mode == TDES_MODE_ECB) {
2299 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
2300 			} else {
2301 				memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE);
2302 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
2303 			}
2304 		}
2305 	}
2306 
2307 	rte_free(val[0].val);
2308 	rte_free(pt.val);
2309 	rte_free(ct.val);
2310 	rte_free(iv.val);
2311 
2312 	return 0;
2313 }
2314 
2315 static int
2316 fips_mct_aes_ecb_test(void)
2317 {
2318 #define AES_BLOCK_SIZE	16
2319 #define AES_EXTERN_ITER	100
2320 #define AES_INTERN_ITER	1000
2321 	struct fips_val val = {NULL, 0}, val_key;
2322 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
2323 	uint32_t i, j, k;
2324 	int ret;
2325 
2326 	for (i = 0; i < AES_EXTERN_ITER; i++) {
2327 		if (i != 0)
2328 			update_info_vec(i);
2329 
2330 		fips_test_write_one_case();
2331 
2332 		for (j = 0; j < AES_INTERN_ITER; j++) {
2333 			ret = fips_run_test();
2334 			if (ret < 0) {
2335 				if (ret == -EPERM) {
2336 					if (info.file_type == FIPS_TYPE_JSON)
2337 						return ret;
2338 
2339 					fprintf(info.fp_wr, "Bypass\n");
2340 					return 0;
2341 				}
2342 
2343 				return ret;
2344 			}
2345 
2346 			ret = get_writeback_data(&val);
2347 			if (ret < 0)
2348 				return ret;
2349 
2350 			if (info.op == FIPS_TEST_ENC_AUTH_GEN)
2351 				memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE);
2352 			else
2353 				memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE);
2354 
2355 			if (j == AES_INTERN_ITER - 1)
2356 				continue;
2357 
2358 			memcpy(prev_out, val.val, AES_BLOCK_SIZE);
2359 		}
2360 
2361 		info.parse_writeback(&val);
2362 		fprintf(info.fp_wr, "\n");
2363 
2364 		if (i == AES_EXTERN_ITER - 1)
2365 			continue;
2366 
2367 		/** update key */
2368 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2369 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
2370 			switch (vec.cipher_auth.key.len) {
2371 			case 16:
2372 				val_key.val[k] ^= val.val[k];
2373 				break;
2374 			case 24:
2375 				if (k < 8)
2376 					val_key.val[k] ^= prev_out[k + 8];
2377 				else
2378 					val_key.val[k] ^= val.val[k - 8];
2379 				break;
2380 			case 32:
2381 				if (k < 16)
2382 					val_key.val[k] ^= prev_out[k];
2383 				else
2384 					val_key.val[k] ^= val.val[k - 16];
2385 				break;
2386 			default:
2387 				return -1;
2388 			}
2389 		}
2390 	}
2391 
2392 	rte_free(val.val);
2393 
2394 	return 0;
2395 }
2396 static int
2397 fips_mct_aes_test(void)
2398 {
2399 #define AES_BLOCK_SIZE	16
2400 #define AES_EXTERN_ITER	100
2401 #define AES_INTERN_ITER	1000
2402 	struct fips_val val[3] = {{NULL, 0},}, val_key,  pt, ct, iv;
2403 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
2404 	uint8_t prev_in[AES_BLOCK_SIZE] = {0};
2405 	uint32_t i, j, k;
2406 	int ret;
2407 
2408 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB)
2409 		return fips_mct_aes_ecb_test();
2410 
2411 	pt.len = vec.pt.len;
2412 	pt.val = rte_malloc(NULL, pt.len, 0);
2413 	ct.len = vec.ct.len;
2414 	ct.val = rte_malloc(NULL, ct.len, 0);
2415 	iv.len = vec.iv.len;
2416 	iv.val = rte_malloc(NULL, iv.len, 0);
2417 	for (i = 0; i < AES_EXTERN_ITER; i++) {
2418 		if (info.file_type != FIPS_TYPE_JSON) {
2419 			if (i != 0)
2420 				update_info_vec(i);
2421 
2422 			fips_test_write_one_case();
2423 		}
2424 
2425 		for (j = 0; j < AES_INTERN_ITER; j++) {
2426 			ret = fips_run_test();
2427 			if (ret < 0) {
2428 				if (ret == -EPERM) {
2429 					if (info.file_type == FIPS_TYPE_JSON)
2430 						return ret;
2431 
2432 					fprintf(info.fp_wr, "Bypass\n");
2433 					return 0;
2434 				}
2435 
2436 				return ret;
2437 			}
2438 
2439 			ret = get_writeback_data(&val[0]);
2440 			if (ret < 0)
2441 				return ret;
2442 
2443 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2444 				memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE);
2445 
2446 			if (j == 0) {
2447 				memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
2448 				memcpy(pt.val, vec.pt.val, pt.len);
2449 				memcpy(ct.val, vec.ct.val, ct.len);
2450 				memcpy(iv.val, vec.iv.val, iv.len);
2451 
2452 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2453 					memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE);
2454 					memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2455 					val[1].val = pt.val;
2456 					val[1].len = pt.len;
2457 					val[2].val = iv.val;
2458 					val[2].len = iv.len;
2459 				} else {
2460 					memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE);
2461 					memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
2462 					val[1].val = ct.val;
2463 					val[1].len = ct.len;
2464 					val[2].val = iv.val;
2465 					val[2].len = iv.len;
2466 				}
2467 				continue;
2468 			}
2469 
2470 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2471 				memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2472 				memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE);
2473 			} else {
2474 				memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
2475 				memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE);
2476 			}
2477 
2478 			if (j == AES_INTERN_ITER - 1)
2479 				continue;
2480 
2481 			memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
2482 		}
2483 
2484 		info.parse_writeback(val);
2485 		if (info.file_type != FIPS_TYPE_JSON)
2486 			fprintf(info.fp_wr, "\n");
2487 
2488 		if (i == AES_EXTERN_ITER - 1)
2489 			continue;
2490 
2491 		/** update key */
2492 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2493 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
2494 			switch (vec.cipher_auth.key.len) {
2495 			case 16:
2496 				val_key.val[k] ^= val[0].val[k];
2497 				break;
2498 			case 24:
2499 				if (k < 8)
2500 					val_key.val[k] ^= prev_out[k + 8];
2501 				else
2502 					val_key.val[k] ^= val[0].val[k - 8];
2503 				break;
2504 			case 32:
2505 				if (k < 16)
2506 					val_key.val[k] ^= prev_out[k];
2507 				else
2508 					val_key.val[k] ^= val[0].val[k - 16];
2509 				break;
2510 			default:
2511 				return -1;
2512 			}
2513 		}
2514 
2515 		if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2516 			memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2517 	}
2518 
2519 	rte_free(val[0].val);
2520 	rte_free(pt.val);
2521 	rte_free(ct.val);
2522 	rte_free(iv.val);
2523 
2524 	return 0;
2525 }
2526 
2527 static int
2528 fips_mct_sha_test(void)
2529 {
2530 #define SHA_EXTERN_ITER	100
2531 #define SHA_INTERN_ITER	1000
2532 	uint8_t md_blocks = info.interim_info.sha_data.md_blocks;
2533 	struct fips_val val = {NULL, 0};
2534 	struct fips_val  md[md_blocks];
2535 	int ret;
2536 	uint32_t i, j, k, offset, max_outlen;
2537 
2538 	max_outlen = md_blocks * vec.cipher_auth.digest.len;
2539 
2540 	rte_free(vec.cipher_auth.digest.val);
2541 	vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0);
2542 
2543 	if (vec.pt.val)
2544 		memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len);
2545 
2546 	rte_free(vec.pt.val);
2547 	vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*md_blocks), 0);
2548 
2549 	for (i = 0; i < md_blocks; i++)
2550 		md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0);
2551 
2552 	if (info.file_type != FIPS_TYPE_JSON) {
2553 		fips_test_write_one_case();
2554 		fprintf(info.fp_wr, "\n");
2555 	}
2556 
2557 	for (j = 0; j < SHA_EXTERN_ITER; j++) {
2558 		for (i = 0; i < md_blocks; i++) {
2559 			memcpy(md[i].val, vec.cipher_auth.digest.val,
2560 				vec.cipher_auth.digest.len);
2561 			md[i].len = vec.cipher_auth.digest.len;
2562 		}
2563 
2564 		for (i = 0; i < (SHA_INTERN_ITER); i++) {
2565 			offset = 0;
2566 			for (k = 0; k < md_blocks; k++) {
2567 				memcpy(vec.pt.val + offset, md[k].val, (size_t)md[k].len);
2568 				offset += md[k].len;
2569 			}
2570 			vec.pt.len = offset;
2571 
2572 			ret = fips_run_test();
2573 			if (ret < 0) {
2574 				if (ret == -EPERM || ret == -ENOTSUP) {
2575 					if (info.file_type == FIPS_TYPE_JSON)
2576 						return ret;
2577 
2578 					fprintf(info.fp_wr, "Bypass\n\n");
2579 					return 0;
2580 				}
2581 				return ret;
2582 			}
2583 
2584 			ret = get_writeback_data(&val);
2585 			if (ret < 0)
2586 				return ret;
2587 
2588 			for (k = 1; k < md_blocks; k++) {
2589 				memcpy(md[k-1].val, md[k].val, md[k].len);
2590 				md[k-1].len = md[k].len;
2591 			}
2592 
2593 			memcpy(md[md_blocks-1].val, (val.val + vec.pt.len),
2594 				vec.cipher_auth.digest.len);
2595 			md[md_blocks-1].len = vec.cipher_auth.digest.len;
2596 		}
2597 
2598 		memcpy(vec.cipher_auth.digest.val, md[md_blocks-1].val, md[md_blocks-1].len);
2599 		vec.cipher_auth.digest.len = md[md_blocks-1].len;
2600 
2601 		if (info.file_type != FIPS_TYPE_JSON)
2602 			fprintf(info.fp_wr, "COUNT = %u\n", j);
2603 
2604 		info.parse_writeback(&val);
2605 
2606 		if (info.file_type != FIPS_TYPE_JSON)
2607 			fprintf(info.fp_wr, "\n");
2608 	}
2609 
2610 	for (i = 0; i < (md_blocks); i++)
2611 		rte_free(md[i].val);
2612 
2613 	rte_free(vec.pt.val);
2614 
2615 	rte_free(val.val);
2616 	return 0;
2617 }
2618 
2619 static int
2620 fips_mct_shake_test(void)
2621 {
2622 #define SHAKE_EXTERN_ITER	100
2623 #define SHAKE_INTERN_ITER	1000
2624 	uint32_t i, j, range, outlen, max_outlen;
2625 	struct fips_val val = {NULL, 0}, md;
2626 	uint8_t rightmost[2];
2627 	uint16_t *rightptr;
2628 	int ret;
2629 
2630 	max_outlen = vec.cipher_auth.digest.len;
2631 
2632 	rte_free(vec.cipher_auth.digest.val);
2633 	vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0);
2634 
2635 	if (vec.pt.val)
2636 		memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.pt.len);
2637 
2638 	rte_free(vec.pt.val);
2639 	vec.pt.val = rte_malloc(NULL, 16, 0);
2640 	vec.pt.len = 16;
2641 
2642 	md.val = rte_malloc(NULL, max_outlen, 0);
2643 	md.len = max_outlen;
2644 
2645 	if (info.file_type != FIPS_TYPE_JSON) {
2646 		fips_test_write_one_case();
2647 		fprintf(info.fp_wr, "\n");
2648 	}
2649 
2650 	range = max_outlen - info.interim_info.sha_data.min_outlen + 1;
2651 	outlen = max_outlen;
2652 	for (j = 0; j < SHAKE_EXTERN_ITER; j++) {
2653 		memset(md.val, 0, max_outlen);
2654 		memcpy(md.val, vec.cipher_auth.digest.val,
2655 			vec.cipher_auth.digest.len);
2656 
2657 		for (i = 0; i < (SHAKE_INTERN_ITER); i++) {
2658 			memset(vec.pt.val, 0, vec.pt.len);
2659 			memcpy(vec.pt.val, md.val, vec.pt.len);
2660 			vec.cipher_auth.digest.len = outlen;
2661 			ret = fips_run_test();
2662 			if (ret < 0) {
2663 				if (ret == -EPERM || ret == -ENOTSUP) {
2664 					if (info.file_type == FIPS_TYPE_JSON)
2665 						return ret;
2666 
2667 					fprintf(info.fp_wr, "Bypass\n\n");
2668 					return 0;
2669 				}
2670 				return ret;
2671 			}
2672 
2673 			ret = get_writeback_data(&val);
2674 			if (ret < 0)
2675 				return ret;
2676 
2677 			memset(md.val, 0, max_outlen);
2678 			memcpy(md.val, (val.val + vec.pt.len),
2679 				vec.cipher_auth.digest.len);
2680 			md.len = outlen;
2681 			rightmost[0] = md.val[md.len-1];
2682 			rightmost[1] = md.val[md.len-2];
2683 			rightptr = (uint16_t *)rightmost;
2684 			outlen = info.interim_info.sha_data.min_outlen +
2685 				(*rightptr % range);
2686 		}
2687 
2688 		memcpy(vec.cipher_auth.digest.val, md.val, md.len);
2689 		vec.cipher_auth.digest.len = md.len;
2690 
2691 		if (info.file_type != FIPS_TYPE_JSON)
2692 			fprintf(info.fp_wr, "COUNT = %u\n", j);
2693 
2694 		info.parse_writeback(&val);
2695 
2696 		if (info.file_type != FIPS_TYPE_JSON)
2697 			fprintf(info.fp_wr, "\n");
2698 	}
2699 
2700 	rte_free(md.val);
2701 	rte_free(vec.pt.val);
2702 	rte_free(val.val);
2703 	return 0;
2704 }
2705 
2706 static int
2707 init_test_ops(void)
2708 {
2709 	switch (info.algo) {
2710 	case FIPS_TEST_ALGO_AES_CBC:
2711 	case FIPS_TEST_ALGO_AES_CTR:
2712 	case FIPS_TEST_ALGO_AES:
2713 		test_ops.prepare_sym_op = prepare_cipher_op;
2714 		test_ops.prepare_sym_xform  = prepare_aes_xform;
2715 		if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)
2716 			test_ops.test = fips_mct_aes_test;
2717 		else
2718 			test_ops.test = fips_generic_test;
2719 		break;
2720 	case FIPS_TEST_ALGO_HMAC:
2721 		test_ops.prepare_sym_op = prepare_auth_op;
2722 		test_ops.prepare_sym_xform = prepare_hmac_xform;
2723 		test_ops.test = fips_generic_test;
2724 		break;
2725 	case FIPS_TEST_ALGO_TDES:
2726 		test_ops.prepare_sym_op = prepare_cipher_op;
2727 		test_ops.prepare_sym_xform = prepare_tdes_xform;
2728 		if (info.interim_info.tdes_data.test_type == TDES_MCT)
2729 			test_ops.test = fips_mct_tdes_test;
2730 		else
2731 			test_ops.test = fips_generic_test;
2732 		break;
2733 	case FIPS_TEST_ALGO_AES_GMAC:
2734 		test_ops.prepare_sym_op = prepare_auth_op;
2735 		test_ops.prepare_sym_xform = prepare_gmac_xform;
2736 		test_ops.test = fips_generic_test;
2737 		break;
2738 	case FIPS_TEST_ALGO_AES_GCM:
2739 		test_ops.prepare_sym_op = prepare_aead_op;
2740 		test_ops.prepare_sym_xform = prepare_gcm_xform;
2741 		test_ops.test = fips_generic_test;
2742 		break;
2743 	case FIPS_TEST_ALGO_AES_CMAC:
2744 		test_ops.prepare_sym_op = prepare_auth_op;
2745 		test_ops.prepare_sym_xform = prepare_cmac_xform;
2746 		test_ops.test = fips_generic_test;
2747 		break;
2748 	case FIPS_TEST_ALGO_AES_CCM:
2749 		test_ops.prepare_sym_op = prepare_aead_op;
2750 		test_ops.prepare_sym_xform = prepare_ccm_xform;
2751 		test_ops.test = fips_generic_test;
2752 		break;
2753 	case FIPS_TEST_ALGO_SHA:
2754 		test_ops.prepare_sym_op = prepare_auth_op;
2755 		test_ops.prepare_sym_xform = prepare_sha_xform;
2756 		if (info.interim_info.sha_data.test_type == SHA_MCT)
2757 			if (info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_128 ||
2758 				info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_256)
2759 				test_ops.test = fips_mct_shake_test;
2760 			else
2761 				test_ops.test = fips_mct_sha_test;
2762 		else
2763 			test_ops.test = fips_generic_test;
2764 		break;
2765 	case FIPS_TEST_ALGO_AES_XTS:
2766 		test_ops.prepare_sym_op = prepare_cipher_op;
2767 		test_ops.prepare_sym_xform = prepare_xts_xform;
2768 		test_ops.test = fips_generic_test;
2769 		break;
2770 	case FIPS_TEST_ALGO_RSA:
2771 		test_ops.prepare_asym_op = prepare_rsa_op;
2772 		test_ops.prepare_asym_xform = prepare_rsa_xform;
2773 		test_ops.test = fips_generic_test;
2774 		break;
2775 	case FIPS_TEST_ALGO_ECDSA:
2776 		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
2777 			test_ops.prepare_asym_op = prepare_ecfpm_op;
2778 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
2779 			test_ops.test = fips_generic_test;
2780 		} else {
2781 			test_ops.prepare_asym_op = prepare_ecdsa_op;
2782 			test_ops.prepare_asym_xform = prepare_ecdsa_xform;
2783 			test_ops.test = fips_generic_test;
2784 		}
2785 		break;
2786 	case FIPS_TEST_ALGO_EDDSA:
2787 		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
2788 			test_ops.prepare_asym_op = prepare_edfpm_op;
2789 			test_ops.prepare_asym_xform = prepare_edfpm_xform;
2790 			test_ops.test = fips_generic_test;
2791 		} else {
2792 			test_ops.prepare_asym_op = prepare_eddsa_op;
2793 			test_ops.prepare_asym_xform = prepare_eddsa_xform;
2794 			test_ops.test = fips_generic_test;
2795 		}
2796 		break;
2797 	default:
2798 		if (strstr(info.file_name, "TECB") ||
2799 				strstr(info.file_name, "TCBC")) {
2800 			info.algo = FIPS_TEST_ALGO_TDES;
2801 			test_ops.prepare_sym_op = prepare_cipher_op;
2802 			test_ops.prepare_sym_xform = prepare_tdes_xform;
2803 			if (info.interim_info.tdes_data.test_type == TDES_MCT)
2804 				test_ops.test = fips_mct_tdes_test;
2805 			else
2806 				test_ops.test = fips_generic_test;
2807 			break;
2808 		}
2809 		return -1;
2810 	}
2811 
2812 	return 0;
2813 }
2814 
2815 static void
2816 print_test_block(void)
2817 {
2818 	uint32_t i;
2819 
2820 	for (i = 0; i < info.nb_vec_lines; i++)
2821 		printf("%s\n", info.vec[i]);
2822 
2823 	printf("\n");
2824 }
2825 
2826 static int
2827 fips_test_one_file(void)
2828 {
2829 	int fetch_ret = 0, ret;
2830 
2831 	ret = init_test_ops();
2832 	if (ret < 0) {
2833 		RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret);
2834 		return ret;
2835 	}
2836 
2837 	while (ret >= 0 && fetch_ret == 0) {
2838 		fetch_ret = fips_test_fetch_one_block();
2839 		if (fetch_ret < 0) {
2840 			RTE_LOG(ERR, USER1, "Error %i: Fetch block\n",
2841 					fetch_ret);
2842 			ret = fetch_ret;
2843 			goto error_one_case;
2844 		}
2845 
2846 		if (info.nb_vec_lines == 0) {
2847 			if (fetch_ret == -EOF)
2848 				break;
2849 
2850 			fprintf(info.fp_wr, "\n");
2851 			continue;
2852 		}
2853 
2854 		ret = fips_test_parse_one_case();
2855 		switch (ret) {
2856 		case 0:
2857 			ret = test_ops.test();
2858 			if (ret == 0)
2859 				break;
2860 			RTE_LOG(ERR, USER1, "Error %i: test block\n",
2861 					ret);
2862 			goto error_one_case;
2863 		case 1:
2864 			break;
2865 		default:
2866 			RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
2867 					ret);
2868 			goto error_one_case;
2869 		}
2870 
2871 		continue;
2872 error_one_case:
2873 		print_test_block();
2874 	}
2875 
2876 	fips_test_clear();
2877 
2878 	if (env.digest) {
2879 		rte_free(env.digest);
2880 		env.digest = NULL;
2881 		env.digest_len = 0;
2882 	}
2883 	rte_pktmbuf_free(env.mbuf);
2884 
2885 	return ret;
2886 }
2887 
2888 #ifdef USE_JANSSON
2889 static int
2890 fips_test_json_init_writeback(void)
2891 {
2892 	json_t *session_info, *session_write;
2893 	session_info = json_array_get(json_info.json_root, 0);
2894 	session_write = json_object();
2895 	json_info.json_write_root = json_array();
2896 
2897 	json_object_set(session_write, "jwt",
2898 		json_object_get(session_info, "jwt"));
2899 	json_object_set(session_write, "url",
2900 		json_object_get(session_info, "url"));
2901 	json_object_set(session_write, "isSample",
2902 		json_object_get(session_info, "isSample"));
2903 
2904 	json_info.is_sample = json_boolean_value(
2905 		json_object_get(session_info, "isSample"));
2906 
2907 	json_array_append_new(json_info.json_write_root, session_write);
2908 	return 0;
2909 }
2910 
2911 static int
2912 fips_test_one_test_case(void)
2913 {
2914 	int ret;
2915 
2916 	ret = fips_test_parse_one_json_case();
2917 
2918 	switch (ret) {
2919 	case 0:
2920 		ret = test_ops.test();
2921 		if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP))
2922 			break;
2923 		RTE_LOG(ERR, USER1, "Error %i: test block\n",
2924 				ret);
2925 		break;
2926 	default:
2927 		RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
2928 				ret);
2929 	}
2930 	return ret;
2931 }
2932 
2933 static int
2934 fips_test_one_test_group(void)
2935 {
2936 	int ret;
2937 	json_t *tests, *write_tests;
2938 	size_t test_idx, tests_size;
2939 
2940 	write_tests = json_array();
2941 	json_info.json_write_group = json_object();
2942 	json_object_set(json_info.json_write_group, "tgId",
2943 		json_object_get(json_info.json_test_group, "tgId"));
2944 	json_object_set_new(json_info.json_write_group, "tests", write_tests);
2945 
2946 	switch (info.algo) {
2947 	case FIPS_TEST_ALGO_AES_GMAC:
2948 	case FIPS_TEST_ALGO_AES_GCM:
2949 		ret = parse_test_gcm_json_init();
2950 		break;
2951 	case FIPS_TEST_ALGO_AES_CCM:
2952 		ret = parse_test_ccm_json_init();
2953 		break;
2954 	case FIPS_TEST_ALGO_HMAC:
2955 		ret = parse_test_hmac_json_init();
2956 		break;
2957 	case FIPS_TEST_ALGO_AES_CMAC:
2958 		ret = parse_test_cmac_json_init();
2959 		break;
2960 	case FIPS_TEST_ALGO_AES_XTS:
2961 		ret = parse_test_xts_json_init();
2962 		break;
2963 	case FIPS_TEST_ALGO_AES_CBC:
2964 	case FIPS_TEST_ALGO_AES_CTR:
2965 	case FIPS_TEST_ALGO_AES:
2966 		ret = parse_test_aes_json_init();
2967 		break;
2968 	case FIPS_TEST_ALGO_SHA:
2969 		ret = parse_test_sha_json_init();
2970 		break;
2971 	case FIPS_TEST_ALGO_TDES:
2972 		ret = parse_test_tdes_json_init();
2973 		break;
2974 	case FIPS_TEST_ALGO_RSA:
2975 		ret = parse_test_rsa_json_init();
2976 		break;
2977 	case FIPS_TEST_ALGO_ECDSA:
2978 		ret = parse_test_ecdsa_json_init();
2979 		break;
2980 	case FIPS_TEST_ALGO_EDDSA:
2981 		ret = parse_test_eddsa_json_init();
2982 		break;
2983 	default:
2984 		return -EINVAL;
2985 	}
2986 
2987 	if (ret < 0)
2988 		return ret;
2989 
2990 	ret = fips_test_parse_one_json_group();
2991 	if (ret < 0)
2992 		return ret;
2993 
2994 	ret = init_test_ops();
2995 	if (ret < 0)
2996 		return ret;
2997 
2998 	tests = json_object_get(json_info.json_test_group, "tests");
2999 	tests_size = json_array_size(tests);
3000 	for (test_idx = 0; test_idx < tests_size; test_idx++) {
3001 		json_info.json_test_case = json_array_get(tests, test_idx);
3002 		if (fips_test_one_test_case() == 0)
3003 			json_array_append_new(write_tests, json_info.json_write_case);
3004 	}
3005 
3006 	return 0;
3007 }
3008 
3009 static int
3010 fips_test_one_vector_set(void)
3011 {
3012 	int ret;
3013 	json_t *test_groups, *write_groups, *write_version, *write_set, *mode;
3014 	size_t group_idx, num_groups;
3015 
3016 	test_groups = json_object_get(json_info.json_vector_set, "testGroups");
3017 	num_groups = json_array_size(test_groups);
3018 
3019 	json_info.json_write_set = json_array();
3020 	write_version = json_object();
3021 	json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION));
3022 	json_array_append_new(json_info.json_write_set, write_version);
3023 
3024 	write_set = json_object();
3025 	json_array_append(json_info.json_write_set, write_set);
3026 	write_groups = json_array();
3027 
3028 	json_object_set(write_set, "vsId",
3029 		json_object_get(json_info.json_vector_set, "vsId"));
3030 	json_object_set(write_set, "algorithm",
3031 		json_object_get(json_info.json_vector_set, "algorithm"));
3032 	mode = json_object_get(json_info.json_vector_set, "mode");
3033 	if (mode != NULL)
3034 		json_object_set_new(write_set, "mode", mode);
3035 
3036 	json_object_set(write_set, "revision",
3037 		json_object_get(json_info.json_vector_set, "revision"));
3038 	json_object_set_new(write_set, "isSample",
3039 		json_boolean(json_info.is_sample));
3040 	json_object_set_new(write_set, "testGroups", write_groups);
3041 
3042 	ret = fips_test_parse_one_json_vector_set();
3043 	if (ret < 0) {
3044 		RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n",
3045 			json_string_value(json_object_get(json_info.json_vector_set, "algorithm")));
3046 		return ret;
3047 	}
3048 
3049 	for (group_idx = 0; group_idx < num_groups; group_idx++) {
3050 		json_info.json_test_group = json_array_get(test_groups, group_idx);
3051 		ret = fips_test_one_test_group();
3052 		json_array_append_new(write_groups, json_info.json_write_group);
3053 	}
3054 
3055 	return 0;
3056 }
3057 
3058 static int
3059 fips_test_one_json_file(void)
3060 {
3061 	size_t vector_set_idx, root_size;
3062 
3063 	root_size = json_array_size(json_info.json_root);
3064 	fips_test_json_init_writeback();
3065 
3066 	for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) {
3067 		/* Vector set index starts at 1, the 0th index contains test session
3068 		 * information.
3069 		 */
3070 		json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx);
3071 		fips_test_one_vector_set();
3072 		json_array_append_new(json_info.json_write_root, json_info.json_write_set);
3073 		json_incref(json_info.json_write_set);
3074 	}
3075 
3076 	json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4));
3077 	json_decref(json_info.json_write_root);
3078 
3079 	return 0;
3080 }
3081 #endif /* USE_JANSSON */
3082