xref: /dpdk/examples/fips_validation/main.c (revision 0e3b2fc18c6b9bae9c6d51779bcd2b057ba0e300)
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 	asym->rsa.padding.type = info.interim_info.rsa_data.padding;
930 	asym->rsa.padding.hash = info.interim_info.rsa_data.auth;
931 
932 	if (env.digest) {
933 		if (asym->rsa.padding.type == RTE_CRYPTO_RSA_PADDING_PKCS1_5) {
934 			int b_len = 0;
935 			uint8_t b[32];
936 
937 			b_len = get_hash_oid(asym->rsa.padding.hash, b);
938 			if (b_len < 0) {
939 				RTE_LOG(ERR, USER1, "Failed to get digest info for hash %d\n",
940 					asym->rsa.padding.hash);
941 				return -EINVAL;
942 			}
943 
944 			if (b_len) {
945 				msg.len = env.digest_len + b_len;
946 				msg.val = rte_zmalloc(NULL, msg.len, 0);
947 				rte_memcpy(msg.val, b, b_len);
948 				rte_memcpy(msg.val + b_len, env.digest, env.digest_len);
949 				rte_free(env.digest);
950 				env.digest = msg.val;
951 				env.digest_len = msg.len;
952 			}
953 		}
954 		msg.val = env.digest;
955 		msg.len = env.digest_len;
956 	} else {
957 		msg.val = vec.pt.val;
958 		msg.len = vec.pt.len;
959 	}
960 
961 	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
962 		asym->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
963 		asym->rsa.message.data = msg.val;
964 		asym->rsa.message.length = msg.len;
965 
966 		rte_free(vec.rsa.signature.val);
967 
968 		vec.rsa.signature.val = rte_zmalloc(NULL, vec.rsa.n.len, 0);
969 		vec.rsa.signature.len = vec.rsa.n.len;
970 		asym->rsa.sign.data = vec.rsa.signature.val;
971 		asym->rsa.sign.length = 0;
972 	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
973 		asym->rsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
974 		asym->rsa.message.data = msg.val;
975 		asym->rsa.message.length = msg.len;
976 		asym->rsa.sign.data = vec.rsa.signature.val;
977 		asym->rsa.sign.length = vec.rsa.signature.len;
978 	} else {
979 		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
980 		return -EINVAL;
981 	}
982 
983 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
984 
985 	return 0;
986 }
987 
988 static int
989 prepare_ecdsa_op(void)
990 {
991 	struct rte_crypto_asym_op *asym;
992 	struct fips_val msg;
993 
994 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
995 
996 	asym = env.op->asym;
997 	if (env.digest) {
998 		msg.val = env.digest;
999 		msg.len = env.digest_len;
1000 	} else {
1001 		msg.val = vec.pt.val;
1002 		msg.len = vec.pt.len;
1003 	}
1004 
1005 	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
1006 		asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
1007 		asym->ecdsa.message.data = msg.val;
1008 		asym->ecdsa.message.length = msg.len;
1009 		asym->ecdsa.k.data = vec.ecdsa.k.val;
1010 		asym->ecdsa.k.length = vec.ecdsa.k.len;
1011 
1012 		rte_free(vec.ecdsa.r.val);
1013 
1014 		rte_free(vec.ecdsa.s.val);
1015 
1016 		vec.ecdsa.r.len = info.interim_info.ecdsa_data.curve_len;
1017 		vec.ecdsa.r.val = rte_zmalloc(NULL, vec.ecdsa.r.len, 0);
1018 
1019 		vec.ecdsa.s.len = vec.ecdsa.r.len;
1020 		vec.ecdsa.s.val = rte_zmalloc(NULL, vec.ecdsa.s.len, 0);
1021 
1022 		asym->ecdsa.r.data = vec.ecdsa.r.val;
1023 		asym->ecdsa.r.length = 0;
1024 		asym->ecdsa.s.data = vec.ecdsa.s.val;
1025 		asym->ecdsa.s.length = 0;
1026 	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
1027 		asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
1028 		asym->ecdsa.message.data = msg.val;
1029 		asym->ecdsa.message.length = msg.len;
1030 		asym->ecdsa.r.data = vec.ecdsa.r.val;
1031 		asym->ecdsa.r.length = vec.ecdsa.r.len;
1032 		asym->ecdsa.s.data = vec.ecdsa.s.val;
1033 		asym->ecdsa.s.length = vec.ecdsa.s.len;
1034 	} else {
1035 		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
1036 		return -EINVAL;
1037 	}
1038 
1039 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
1040 
1041 	return 0;
1042 }
1043 
1044 static int
1045 prepare_eddsa_op(void)
1046 {
1047 	struct rte_crypto_asym_op *asym;
1048 	struct fips_val msg;
1049 
1050 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1051 
1052 	asym = env.op->asym;
1053 	if (env.digest) {
1054 		msg.val = env.digest;
1055 		msg.len = env.digest_len;
1056 	} else {
1057 		msg.val = vec.pt.val;
1058 		msg.len = vec.pt.len;
1059 	}
1060 
1061 	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
1062 		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
1063 		asym->eddsa.message.data = msg.val;
1064 		asym->eddsa.message.length = msg.len;
1065 		asym->eddsa.context.data = vec.eddsa.ctx.val;
1066 		asym->eddsa.context.length = vec.eddsa.ctx.len;
1067 
1068 		rte_free(vec.eddsa.sign.val);
1069 
1070 		vec.eddsa.sign.len = info.interim_info.eddsa_data.curve_len;
1071 		vec.eddsa.sign.val = rte_zmalloc(NULL, vec.eddsa.sign.len, 0);
1072 
1073 		asym->eddsa.sign.data = vec.eddsa.sign.val;
1074 		asym->eddsa.sign.length = 0;
1075 	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
1076 		asym->eddsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
1077 		asym->eddsa.message.data = msg.val;
1078 		asym->eddsa.message.length = msg.len;
1079 		asym->eddsa.sign.data = vec.eddsa.sign.val;
1080 		asym->eddsa.sign.length = vec.eddsa.sign.len;
1081 	} else {
1082 		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
1083 		return -EINVAL;
1084 	}
1085 
1086 	if (info.interim_info.eddsa_data.curve_id == RTE_CRYPTO_EC_GROUP_ED25519) {
1087 		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519;
1088 		if (info.interim_info.eddsa_data.prehash)
1089 			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519PH;
1090 		if (vec.eddsa.ctx.len > 0)
1091 			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_25519CTX;
1092 	} else {
1093 		asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448;
1094 		if (info.interim_info.eddsa_data.prehash)
1095 			asym->eddsa.instance = RTE_CRYPTO_EDCURVE_448PH;
1096 	}
1097 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
1098 
1099 	return 0;
1100 }
1101 
1102 static int
1103 prepare_ecfpm_op(void)
1104 {
1105 	struct rte_crypto_asym_op *asym;
1106 
1107 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1108 
1109 	asym = env.op->asym;
1110 	asym->ecpm.scalar.data = vec.ecdsa.pkey.val;
1111 	asym->ecpm.scalar.length = vec.ecdsa.pkey.len;
1112 
1113 	rte_free(vec.ecdsa.qx.val);
1114 
1115 	rte_free(vec.ecdsa.qy.val);
1116 
1117 	vec.ecdsa.qx.len = info.interim_info.ecdsa_data.curve_len;
1118 	vec.ecdsa.qx.val = rte_zmalloc(NULL, vec.ecdsa.qx.len, 0);
1119 
1120 	vec.ecdsa.qy.len = vec.ecdsa.qx.len;
1121 	vec.ecdsa.qy.val = rte_zmalloc(NULL, vec.ecdsa.qy.len, 0);
1122 
1123 	asym->ecpm.r.x.data = vec.ecdsa.qx.val;
1124 	asym->ecpm.r.x.length = 0;
1125 	asym->ecpm.r.y.data = vec.ecdsa.qy.val;
1126 	asym->ecpm.r.y.length = 0;
1127 
1128 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
1129 
1130 	return 0;
1131 }
1132 
1133 static int
1134 prepare_edfpm_op(void)
1135 {
1136 	struct rte_crypto_asym_op *asym;
1137 
1138 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1139 
1140 	asym = env.op->asym;
1141 	asym->ecpm.scalar.data = vec.eddsa.pkey.val;
1142 	asym->ecpm.scalar.length = vec.eddsa.pkey.len;
1143 
1144 	rte_free(vec.eddsa.q.val);
1145 
1146 	vec.eddsa.q.len = info.interim_info.eddsa_data.curve_len;
1147 	vec.eddsa.q.val = rte_zmalloc(NULL, vec.eddsa.q.len, 0);
1148 
1149 	asym->ecpm.r.x.data = vec.eddsa.q.val;
1150 	asym->ecpm.r.x.length = 0;
1151 	asym->flags |= RTE_CRYPTO_ASYM_FLAG_PUB_KEY_COMPRESSED;
1152 
1153 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
1154 
1155 	return 0;
1156 }
1157 
1158 static int
1159 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
1160 {
1161 	const struct rte_cryptodev_symmetric_capability *cap;
1162 	struct rte_cryptodev_sym_capability_idx cap_idx;
1163 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1164 
1165 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1166 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC)
1167 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC;
1168 	else if (info.interim_info.aes_data.cipher_algo ==
1169 			RTE_CRYPTO_CIPHER_AES_CTR)
1170 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CTR;
1171 	else
1172 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB;
1173 
1174 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1175 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1176 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1177 	cipher_xform->key.data = vec.cipher_auth.key.val;
1178 	cipher_xform->key.length = vec.cipher_auth.key.len;
1179 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC ||
1180 			cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CTR) {
1181 		cipher_xform->iv.length = vec.iv.len;
1182 		cipher_xform->iv.offset = IV_OFF;
1183 	} else {
1184 		cipher_xform->iv.length = 0;
1185 		cipher_xform->iv.offset = 0;
1186 	}
1187 	cap_idx.algo.cipher = cipher_xform->algo;
1188 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1189 
1190 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1191 	if (!cap) {
1192 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1193 				env.dev_id);
1194 		return -EINVAL;
1195 	}
1196 
1197 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1198 			cipher_xform->key.length,
1199 			cipher_xform->iv.length) != 0) {
1200 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1201 				info.device_name, cipher_xform->key.length,
1202 				cipher_xform->iv.length);
1203 		return -EPERM;
1204 	}
1205 
1206 	return 0;
1207 }
1208 
1209 static int
1210 prepare_tdes_xform(struct rte_crypto_sym_xform *xform)
1211 {
1212 	const struct rte_cryptodev_symmetric_capability *cap;
1213 	struct rte_cryptodev_sym_capability_idx cap_idx;
1214 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1215 
1216 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1217 
1218 	if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC)
1219 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC;
1220 	else
1221 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB;
1222 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1223 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1224 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1225 	cipher_xform->key.data = vec.cipher_auth.key.val;
1226 	cipher_xform->key.length = vec.cipher_auth.key.len;
1227 
1228 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
1229 		cipher_xform->iv.length = vec.iv.len;
1230 		cipher_xform->iv.offset = IV_OFF;
1231 	} else {
1232 		cipher_xform->iv.length = 0;
1233 		cipher_xform->iv.offset = 0;
1234 	}
1235 	cap_idx.algo.cipher = cipher_xform->algo;
1236 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1237 
1238 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1239 	if (!cap) {
1240 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1241 				env.dev_id);
1242 		return -EINVAL;
1243 	}
1244 
1245 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1246 			cipher_xform->key.length,
1247 			cipher_xform->iv.length) != 0) {
1248 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1249 				info.device_name, cipher_xform->key.length,
1250 				cipher_xform->iv.length);
1251 		return -EPERM;
1252 	}
1253 
1254 	return 0;
1255 }
1256 
1257 static int
1258 prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
1259 {
1260 	const struct rte_cryptodev_symmetric_capability *cap;
1261 	struct rte_cryptodev_sym_capability_idx cap_idx;
1262 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1263 
1264 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1265 
1266 	auth_xform->algo = info.interim_info.hmac_data.algo;
1267 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
1268 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1269 	auth_xform->key.data = vec.cipher_auth.key.val;
1270 	auth_xform->key.length = vec.cipher_auth.key.len;
1271 
1272 	cap_idx.algo.auth = auth_xform->algo;
1273 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1274 
1275 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1276 	if (!cap) {
1277 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1278 				env.dev_id);
1279 		return -EINVAL;
1280 	}
1281 
1282 	if (rte_cryptodev_sym_capability_check_auth(cap,
1283 			auth_xform->key.length,
1284 			auth_xform->digest_length, 0) != 0) {
1285 		RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n",
1286 				info.device_name, auth_xform->key.length,
1287 				auth_xform->digest_length);
1288 		return -EPERM;
1289 	}
1290 
1291 	return 0;
1292 }
1293 
1294 int
1295 prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
1296 {
1297 	const struct rte_cryptodev_symmetric_capability *cap;
1298 	struct rte_cryptodev_sym_capability_idx cap_idx;
1299 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
1300 
1301 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
1302 
1303 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
1304 	aead_xform->aad_length = vec.aead.aad.len;
1305 	aead_xform->digest_length = vec.aead.digest.len;
1306 	aead_xform->iv.offset = IV_OFF;
1307 	aead_xform->iv.length = vec.iv.len;
1308 	aead_xform->key.data = vec.aead.key.val;
1309 	aead_xform->key.length = vec.aead.key.len;
1310 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1311 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
1312 			RTE_CRYPTO_AEAD_OP_DECRYPT;
1313 
1314 	cap_idx.algo.aead = aead_xform->algo;
1315 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
1316 
1317 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1318 	if (!cap) {
1319 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1320 				env.dev_id);
1321 		return -EINVAL;
1322 	}
1323 
1324 	if (rte_cryptodev_sym_capability_check_aead(cap,
1325 			aead_xform->key.length,
1326 			aead_xform->digest_length, aead_xform->aad_length,
1327 			aead_xform->iv.length) != 0) {
1328 		RTE_LOG(ERR, USER1,
1329 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
1330 				info.device_name, aead_xform->key.length,
1331 				aead_xform->digest_length,
1332 				aead_xform->aad_length,
1333 				aead_xform->iv.length);
1334 		return -EPERM;
1335 	}
1336 
1337 	return 0;
1338 }
1339 
1340 int
1341 prepare_gmac_xform(struct rte_crypto_sym_xform *xform)
1342 {
1343 	const struct rte_cryptodev_symmetric_capability *cap;
1344 	struct rte_cryptodev_sym_capability_idx cap_idx;
1345 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1346 
1347 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1348 
1349 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC;
1350 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1351 			RTE_CRYPTO_AUTH_OP_GENERATE :
1352 			RTE_CRYPTO_AUTH_OP_VERIFY;
1353 	auth_xform->iv.offset = IV_OFF;
1354 	auth_xform->iv.length = vec.iv.len;
1355 	auth_xform->digest_length = vec.aead.digest.len;
1356 	auth_xform->key.data = vec.aead.key.val;
1357 	auth_xform->key.length = vec.aead.key.len;
1358 
1359 	cap_idx.algo.auth = auth_xform->algo;
1360 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1361 
1362 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1363 	if (!cap) {
1364 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1365 				env.dev_id);
1366 		return -EINVAL;
1367 	}
1368 
1369 	if (rte_cryptodev_sym_capability_check_auth(cap,
1370 			auth_xform->key.length,
1371 			auth_xform->digest_length,
1372 			auth_xform->iv.length) != 0) {
1373 
1374 		RTE_LOG(ERR, USER1,
1375 			"PMD %s key length %u Digest length %u IV length %u\n",
1376 				info.device_name, auth_xform->key.length,
1377 				auth_xform->digest_length,
1378 				auth_xform->iv.length);
1379 		return -EPERM;
1380 	}
1381 
1382 	return 0;
1383 }
1384 
1385 static int
1386 prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
1387 {
1388 	const struct rte_cryptodev_symmetric_capability *cap;
1389 	struct rte_cryptodev_sym_capability_idx cap_idx;
1390 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1391 
1392 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1393 
1394 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC;
1395 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1396 			RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY;
1397 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1398 	auth_xform->key.data = vec.cipher_auth.key.val;
1399 	auth_xform->key.length = vec.cipher_auth.key.len;
1400 
1401 	cap_idx.algo.auth = auth_xform->algo;
1402 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1403 
1404 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1405 	if (!cap) {
1406 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1407 				env.dev_id);
1408 		return -EINVAL;
1409 	}
1410 
1411 	if (rte_cryptodev_sym_capability_check_auth(cap,
1412 			auth_xform->key.length,
1413 			auth_xform->digest_length, 0) != 0) {
1414 		RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n",
1415 				info.device_name, auth_xform->key.length,
1416 				auth_xform->digest_length);
1417 		return -EPERM;
1418 	}
1419 
1420 	return 0;
1421 }
1422 
1423 static int
1424 prepare_ccm_xform(struct rte_crypto_sym_xform *xform)
1425 {
1426 	const struct rte_cryptodev_symmetric_capability *cap;
1427 	struct rte_cryptodev_sym_capability_idx cap_idx;
1428 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
1429 
1430 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
1431 
1432 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM;
1433 	aead_xform->aad_length = vec.aead.aad.len;
1434 	aead_xform->digest_length = vec.aead.digest.len;
1435 	aead_xform->iv.offset = IV_OFF;
1436 	aead_xform->iv.length = vec.iv.len;
1437 	aead_xform->key.data = vec.aead.key.val;
1438 	aead_xform->key.length = vec.aead.key.len;
1439 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1440 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
1441 			RTE_CRYPTO_AEAD_OP_DECRYPT;
1442 
1443 	cap_idx.algo.aead = aead_xform->algo;
1444 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
1445 
1446 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1447 	if (!cap) {
1448 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1449 				env.dev_id);
1450 		return -EINVAL;
1451 	}
1452 
1453 	if (rte_cryptodev_sym_capability_check_aead(cap,
1454 			aead_xform->key.length,
1455 			aead_xform->digest_length, aead_xform->aad_length,
1456 			aead_xform->iv.length) != 0) {
1457 		RTE_LOG(ERR, USER1,
1458 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
1459 				info.device_name, aead_xform->key.length,
1460 				aead_xform->digest_length,
1461 				aead_xform->aad_length,
1462 				aead_xform->iv.length);
1463 		return -EPERM;
1464 	}
1465 
1466 	return 0;
1467 }
1468 
1469 static int
1470 prepare_sha_xform(struct rte_crypto_sym_xform *xform)
1471 {
1472 	const struct rte_cryptodev_symmetric_capability *cap;
1473 	struct rte_cryptodev_sym_capability_idx cap_idx;
1474 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1475 
1476 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1477 
1478 	auth_xform->algo = info.interim_info.sha_data.algo;
1479 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
1480 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1481 
1482 	cap_idx.algo.auth = auth_xform->algo;
1483 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1484 
1485 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1486 	if (!cap) {
1487 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1488 				env.dev_id);
1489 		return -EINVAL;
1490 	}
1491 
1492 	if (rte_cryptodev_sym_capability_check_auth(cap,
1493 			auth_xform->key.length,
1494 			auth_xform->digest_length, 0) != 0) {
1495 		RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n",
1496 				info.device_name, auth_xform->key.length,
1497 				auth_xform->digest_length);
1498 		return -EPERM;
1499 	}
1500 
1501 	return 0;
1502 }
1503 
1504 static int
1505 prepare_xts_xform(struct rte_crypto_sym_xform *xform)
1506 {
1507 	const struct rte_cryptodev_symmetric_capability *cap;
1508 	struct rte_cryptodev_sym_capability_idx cap_idx;
1509 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1510 
1511 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1512 
1513 	cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS;
1514 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1515 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1516 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1517 	cipher_xform->key.data = vec.cipher_auth.key.val;
1518 	cipher_xform->key.length = vec.cipher_auth.key.len;
1519 	cipher_xform->iv.length = vec.iv.len;
1520 	cipher_xform->iv.offset = IV_OFF;
1521 
1522 	cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS;
1523 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1524 
1525 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1526 	if (!cap) {
1527 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1528 				env.dev_id);
1529 		return -EINVAL;
1530 	}
1531 
1532 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1533 			cipher_xform->key.length,
1534 			cipher_xform->iv.length) != 0) {
1535 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1536 				info.device_name, cipher_xform->key.length,
1537 				cipher_xform->iv.length);
1538 		return -EPERM;
1539 	}
1540 
1541 	return 0;
1542 }
1543 
1544 static int
1545 prepare_rsa_xform(struct rte_crypto_asym_xform *xform)
1546 {
1547 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1548 	struct rte_cryptodev_asym_capability_idx cap_idx;
1549 	struct rte_cryptodev_info dev_info;
1550 
1551 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_RSA;
1552 	xform->next = NULL;
1553 
1554 	cap_idx.type = xform->xform_type;
1555 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1556 	if (!cap) {
1557 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1558 				env.dev_id);
1559 		return -EINVAL;
1560 	}
1561 
1562 	switch (info.op) {
1563 	case FIPS_TEST_ASYM_SIGGEN:
1564 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1565 			RTE_CRYPTO_ASYM_OP_SIGN)) {
1566 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1567 				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
1568 			return -EPERM;
1569 		}
1570 		break;
1571 	case FIPS_TEST_ASYM_SIGVER:
1572 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1573 			RTE_CRYPTO_ASYM_OP_VERIFY)) {
1574 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1575 				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
1576 			return -EPERM;
1577 		}
1578 		break;
1579 	case FIPS_TEST_ASYM_KEYGEN:
1580 		break;
1581 	default:
1582 		break;
1583 	}
1584 
1585 	rte_cryptodev_info_get(env.dev_id, &dev_info);
1586 	xform->rsa.key_type = info.interim_info.rsa_data.privkey;
1587 	switch (xform->rsa.key_type) {
1588 	case RTE_RSA_KEY_TYPE_QT:
1589 		if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT)) {
1590 			RTE_LOG(ERR, USER1, "PMD %s does not support QT key type\n",
1591 				info.device_name);
1592 			return -EPERM;
1593 		}
1594 		xform->rsa.qt.p.data = vec.rsa.p.val;
1595 		xform->rsa.qt.p.length = vec.rsa.p.len;
1596 		xform->rsa.qt.q.data = vec.rsa.q.val;
1597 		xform->rsa.qt.q.length = vec.rsa.q.len;
1598 		xform->rsa.qt.dP.data = vec.rsa.dp.val;
1599 		xform->rsa.qt.dP.length = vec.rsa.dp.len;
1600 		xform->rsa.qt.dQ.data = vec.rsa.dq.val;
1601 		xform->rsa.qt.dQ.length = vec.rsa.dq.len;
1602 		xform->rsa.qt.qInv.data = vec.rsa.qinv.val;
1603 		xform->rsa.qt.qInv.length = vec.rsa.qinv.len;
1604 		break;
1605 	case RTE_RSA_KEY_TYPE_EXP:
1606 		if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP)) {
1607 			RTE_LOG(ERR, USER1, "PMD %s does not support EXP key type\n",
1608 				info.device_name);
1609 			return -EPERM;
1610 		}
1611 		xform->rsa.d.data = vec.rsa.d.val;
1612 		xform->rsa.d.length = vec.rsa.d.len;
1613 		break;
1614 	default:
1615 		break;
1616 	}
1617 
1618 	xform->rsa.e.data = vec.rsa.e.val;
1619 	xform->rsa.e.length = vec.rsa.e.len;
1620 	xform->rsa.n.data = vec.rsa.n.val;
1621 	xform->rsa.n.length = vec.rsa.n.len;
1622 	return 0;
1623 }
1624 
1625 static int
1626 prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform)
1627 {
1628 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1629 	struct rte_cryptodev_asym_capability_idx cap_idx;
1630 
1631 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA;
1632 	xform->next = NULL;
1633 
1634 	cap_idx.type = xform->xform_type;
1635 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1636 	if (!cap) {
1637 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1638 				env.dev_id);
1639 		return -EINVAL;
1640 	}
1641 
1642 	switch (info.op) {
1643 	case FIPS_TEST_ASYM_SIGGEN:
1644 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1645 			RTE_CRYPTO_ASYM_OP_SIGN)) {
1646 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1647 				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
1648 			return -EPERM;
1649 		}
1650 
1651 		xform->ec.pkey.data = vec.ecdsa.pkey.val;
1652 		xform->ec.pkey.length = vec.ecdsa.pkey.len;
1653 		break;
1654 	case FIPS_TEST_ASYM_SIGVER:
1655 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1656 			RTE_CRYPTO_ASYM_OP_VERIFY)) {
1657 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1658 				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
1659 			return -EPERM;
1660 		}
1661 
1662 		xform->ec.q.x.data = vec.ecdsa.qx.val;
1663 		xform->ec.q.x.length = vec.ecdsa.qx.len;
1664 		xform->ec.q.y.data = vec.ecdsa.qy.val;
1665 		xform->ec.q.y.length = vec.ecdsa.qy.len;
1666 		break;
1667 	default:
1668 		break;
1669 	}
1670 
1671 	xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id;
1672 	return 0;
1673 }
1674 
1675 static int
1676 prepare_eddsa_xform(struct rte_crypto_asym_xform *xform)
1677 {
1678 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1679 	struct rte_cryptodev_asym_capability_idx cap_idx;
1680 
1681 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
1682 	xform->next = NULL;
1683 
1684 	cap_idx.type = xform->xform_type;
1685 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1686 	if (!cap) {
1687 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1688 				env.dev_id);
1689 		return -EINVAL;
1690 	}
1691 
1692 	switch (info.op) {
1693 	case FIPS_TEST_ASYM_SIGGEN:
1694 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1695 			RTE_CRYPTO_ASYM_OP_SIGN)) {
1696 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1697 				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
1698 			return -EPERM;
1699 		}
1700 
1701 		xform->ec.pkey.data = vec.eddsa.pkey.val;
1702 		xform->ec.pkey.length = vec.eddsa.pkey.len;
1703 		xform->ec.q.x.data = vec.eddsa.q.val;
1704 		xform->ec.q.x.length = vec.eddsa.q.len;
1705 		break;
1706 	case FIPS_TEST_ASYM_SIGVER:
1707 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1708 			RTE_CRYPTO_ASYM_OP_VERIFY)) {
1709 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1710 				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
1711 			return -EPERM;
1712 		}
1713 
1714 		xform->ec.q.x.data = vec.eddsa.q.val;
1715 		xform->ec.q.x.length = vec.eddsa.q.len;
1716 		break;
1717 	default:
1718 		break;
1719 	}
1720 
1721 	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
1722 	return 0;
1723 }
1724 
1725 static int
1726 prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
1727 {
1728 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1729 	struct rte_cryptodev_asym_capability_idx cap_idx;
1730 
1731 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
1732 	xform->next = NULL;
1733 
1734 	cap_idx.type = xform->xform_type;
1735 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1736 	if (!cap) {
1737 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1738 				env.dev_id);
1739 		return -EINVAL;
1740 	}
1741 
1742 	xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id;
1743 	return 0;
1744 }
1745 
1746 static int
1747 prepare_edfpm_xform(struct rte_crypto_asym_xform *xform)
1748 {
1749 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1750 	struct rte_cryptodev_asym_capability_idx cap_idx;
1751 
1752 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
1753 	xform->next = NULL;
1754 
1755 	cap_idx.type = xform->xform_type;
1756 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1757 	if (!cap) {
1758 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1759 				env.dev_id);
1760 		return -EINVAL;
1761 	}
1762 
1763 	xform->ec.curve_id = info.interim_info.eddsa_data.curve_id;
1764 	return 0;
1765 }
1766 
1767 static int
1768 get_writeback_data(struct fips_val *val)
1769 {
1770 	struct rte_mbuf *m = env.mbuf;
1771 	uint16_t data_len = rte_pktmbuf_pkt_len(m);
1772 	uint16_t total_len = data_len + env.digest_len;
1773 	uint8_t *src, *dst, *wb_data;
1774 
1775 	/* in case val is reused for MCT test, try to free the buffer first */
1776 	if (val->val) {
1777 		rte_free(val->val);
1778 		val->val = NULL;
1779 	}
1780 
1781 	wb_data = dst = rte_malloc(NULL, total_len, 0);
1782 	if (!dst) {
1783 		RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM);
1784 		return -ENOMEM;
1785 	}
1786 
1787 	while (m && data_len) {
1788 		uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len);
1789 
1790 		src = rte_pktmbuf_mtod(m, uint8_t *);
1791 		memcpy(dst, src, seg_len);
1792 		m = m->next;
1793 		data_len -= seg_len;
1794 		dst += seg_len;
1795 	}
1796 
1797 	if (data_len) {
1798 		RTE_LOG(ERR, USER1, "Error -1: write back data\n");
1799 		rte_free(wb_data);
1800 		return -1;
1801 	}
1802 
1803 	if (env.digest)
1804 		memcpy(dst, env.digest, env.digest_len);
1805 
1806 	val->val = wb_data;
1807 	val->len = total_len;
1808 
1809 	return 0;
1810 }
1811 
1812 static int
1813 fips_run_sym_test(void)
1814 {
1815 	struct rte_crypto_sym_xform xform = {0};
1816 	uint16_t n_deqd;
1817 	int ret;
1818 
1819 	if (!test_ops.prepare_sym_xform || !test_ops.prepare_sym_op)
1820 		return -EINVAL;
1821 
1822 	ret = test_ops.prepare_sym_xform(&xform);
1823 	if (ret < 0)
1824 		return ret;
1825 
1826 	env.sym.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform,
1827 						env.sym.sess_mpool);
1828 	if (!env.sym.sess)
1829 		return -ENOMEM;
1830 
1831 	ret = test_ops.prepare_sym_op();
1832 	if (ret < 0) {
1833 		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n",
1834 				ret);
1835 		goto exit;
1836 	}
1837 
1838 	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
1839 		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
1840 		ret = -1;
1841 		goto exit;
1842 	}
1843 
1844 	do {
1845 		struct rte_crypto_op *deqd_op;
1846 
1847 		n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1);
1848 	} while (n_deqd == 0);
1849 
1850 	vec.status = env.op->status;
1851 
1852 exit:
1853 	rte_cryptodev_sym_session_free(env.dev_id, env.sym.sess);
1854 	env.sym.sess = NULL;
1855 	return ret;
1856 }
1857 
1858 static int
1859 fips_run_asym_test(void)
1860 {
1861 	struct rte_crypto_asym_xform xform = {0};
1862 	struct rte_crypto_asym_op *asym;
1863 	struct rte_crypto_op *deqd_op;
1864 	int ret;
1865 
1866 	if (info.op == FIPS_TEST_ASYM_KEYGEN &&
1867 		(info.algo != FIPS_TEST_ALGO_ECDSA &&
1868 		 info.algo != FIPS_TEST_ALGO_EDDSA)) {
1869 		RTE_SET_USED(asym);
1870 		ret = 0;
1871 		goto exit;
1872 	}
1873 
1874 	if (!test_ops.prepare_asym_xform || !test_ops.prepare_asym_op)
1875 		return -EINVAL;
1876 
1877 	asym = env.op->asym;
1878 	ret = test_ops.prepare_asym_xform(&xform);
1879 	if (ret < 0)
1880 		return ret;
1881 
1882 	ret = rte_cryptodev_asym_session_create(env.dev_id, &xform, env.asym.sess_mpool,
1883 			(void *)&env.asym.sess);
1884 	if (ret < 0)
1885 		return ret;
1886 
1887 	ret = test_ops.prepare_asym_op();
1888 	if (ret < 0) {
1889 		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", ret);
1890 		goto exit;
1891 	}
1892 
1893 	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
1894 		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
1895 		ret = -1;
1896 		goto exit;
1897 	}
1898 
1899 	while (rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1) == 0)
1900 		rte_pause();
1901 
1902 	vec.status = env.op->status;
1903 
1904  exit:
1905 	if (env.asym.sess)
1906 		rte_cryptodev_asym_session_free(env.dev_id, env.asym.sess);
1907 
1908 	env.asym.sess = NULL;
1909 	return ret;
1910 }
1911 
1912 static int
1913 fips_run_test(void)
1914 {
1915 	int ret;
1916 
1917 	env.op = NULL;
1918 	if (!env.is_asym_test) {
1919 		env.op = env.sym.op;
1920 		return fips_run_sym_test();
1921 	}
1922 
1923 	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
1924 		if (info.algo == FIPS_TEST_ALGO_ECDSA) {
1925 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
1926 			test_ops.prepare_asym_op = prepare_ecfpm_op;
1927 			info.interim_info.ecdsa_data.pubkey_gen = 0;
1928 
1929 		} else if (info.algo == FIPS_TEST_ALGO_EDDSA) {
1930 			test_ops.prepare_asym_xform = prepare_edfpm_xform;
1931 			test_ops.prepare_asym_op = prepare_edfpm_op;
1932 			info.interim_info.eddsa_data.pubkey_gen = 0;
1933 		}
1934 
1935 		env.op = env.asym.op;
1936 		return fips_run_asym_test();
1937 	}
1938 
1939 	if (info.algo == FIPS_TEST_ALGO_ECDSA) {
1940 		vec.cipher_auth.digest.len =
1941 			parse_test_sha_hash_size(info.interim_info.ecdsa_data.auth);
1942 		test_ops.prepare_sym_xform = prepare_sha_xform;
1943 		test_ops.prepare_sym_op = prepare_auth_op;
1944 
1945 		env.op = env.sym.op;
1946 		ret = fips_run_sym_test();
1947 		if (ret < 0)
1948 			return ret;
1949 	}
1950 
1951 	env.op = env.asym.op;
1952 	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
1953 		fips_prepare_asym_xform_t old_xform;
1954 		fips_prepare_op_t old_op;
1955 
1956 		old_xform = test_ops.prepare_asym_xform;
1957 		old_op = test_ops.prepare_asym_op;
1958 
1959 		if (info.algo == FIPS_TEST_ALGO_ECDSA &&
1960 		    info.interim_info.ecdsa_data.pubkey_gen == 1) {
1961 			info.op = FIPS_TEST_ASYM_KEYGEN;
1962 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
1963 			test_ops.prepare_asym_op = prepare_ecfpm_op;
1964 
1965 			ret = fips_run_asym_test();
1966 			if (ret < 0)
1967 				return ret;
1968 
1969 			info.post_interim_writeback(NULL);
1970 			info.interim_info.ecdsa_data.pubkey_gen = 0;
1971 
1972 		} else if (info.algo == FIPS_TEST_ALGO_EDDSA &&
1973 				   info.interim_info.eddsa_data.pubkey_gen == 1) {
1974 			info.op = FIPS_TEST_ASYM_KEYGEN;
1975 			test_ops.prepare_asym_xform = prepare_edfpm_xform;
1976 			test_ops.prepare_asym_op = prepare_edfpm_op;
1977 
1978 			const struct rte_cryptodev_asymmetric_xform_capability *cap;
1979 			struct rte_cryptodev_asym_capability_idx cap_idx;
1980 
1981 			cap_idx.type = RTE_CRYPTO_ASYM_XFORM_EDDSA;
1982 			cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1983 			if (!cap) {
1984 				RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1985 						env.dev_id);
1986 				return -EINVAL;
1987 			}
1988 
1989 			if (cap->op_types & (1 << RTE_CRYPTO_ASYM_KE_PUB_KEY_GENERATE)) {
1990 				ret = fips_run_asym_test();
1991 				if (ret < 0)
1992 					return ret;
1993 			} else {
1994 				/* Below is only a workaround by using known keys. */
1995 				struct rte_crypto_asym_xform xform = {0};
1996 
1997 				prepare_edfpm_xform(&xform);
1998 				prepare_edfpm_op();
1999 				uint8_t pkey25519[] = {
2000 					0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d,
2001 					0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e,
2002 					0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b,
2003 					0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42
2004 				};
2005 				uint8_t q25519[] = {
2006 					0xec, 0x17, 0x2b, 0x93, 0xad, 0x5e, 0x56, 0x3b,
2007 					0xf4, 0x93, 0x2c, 0x70, 0xe1, 0x24, 0x50, 0x34,
2008 					0xc3, 0x54, 0x67, 0xef, 0x2e, 0xfd, 0x4d, 0x64,
2009 					0xeb, 0xf8, 0x19, 0x68, 0x34, 0x67, 0xe2, 0xbf
2010 				};
2011 				uint8_t pkey448[] = {
2012 					0xd6, 0x5d, 0xf3, 0x41, 0xad, 0x13, 0xe0, 0x08,
2013 					0x56, 0x76, 0x88, 0xba, 0xed, 0xda, 0x8e, 0x9d,
2014 					0xcd, 0xc1, 0x7d, 0xc0, 0x24, 0x97, 0x4e, 0xa5,
2015 					0xb4, 0x22, 0x7b, 0x65, 0x30, 0xe3, 0x39, 0xbf,
2016 					0xf2, 0x1f, 0x99, 0xe6, 0x8c, 0xa6, 0x96, 0x8f,
2017 					0x3c, 0xca, 0x6d, 0xfe, 0x0f, 0xb9, 0xf4, 0xfa,
2018 					0xb4, 0xfa, 0x13, 0x5d, 0x55, 0x42, 0xea, 0x3f,
2019 					0x01
2020 				};
2021 				uint8_t q448[] = {
2022 					0xdf, 0x97, 0x05, 0xf5, 0x8e, 0xdb, 0xab, 0x80,
2023 					0x2c, 0x7f, 0x83, 0x63, 0xcf, 0xe5, 0x56, 0x0a,
2024 					0xb1, 0xc6, 0x13, 0x2c, 0x20, 0xa9, 0xf1, 0xdd,
2025 					0x16, 0x34, 0x83, 0xa2, 0x6f, 0x8a, 0xc5, 0x3a,
2026 					0x39, 0xd6, 0x80, 0x8b, 0xf4, 0xa1, 0xdf, 0xbd,
2027 					0x26, 0x1b, 0x09, 0x9b, 0xb0, 0x3b, 0x3f, 0xb5,
2028 					0x09, 0x06, 0xcb, 0x28, 0xbd, 0x8a, 0x08, 0x1f,
2029 					0x00
2030 				};
2031 				if (info.interim_info.eddsa_data.curve_id ==
2032 					RTE_CRYPTO_EC_GROUP_ED25519) {
2033 					memcpy(vec.eddsa.pkey.val, pkey25519, RTE_DIM(pkey25519));
2034 					vec.eddsa.pkey.len = 32;
2035 					memcpy(vec.eddsa.q.val, q25519, RTE_DIM(q25519));
2036 					vec.eddsa.q.len = 32;
2037 				} else {
2038 					memcpy(vec.eddsa.pkey.val, pkey448, RTE_DIM(pkey448));
2039 					vec.eddsa.pkey.len = 32;
2040 					memcpy(vec.eddsa.q.val, q448, RTE_DIM(q448));
2041 					vec.eddsa.q.len = 32;
2042 				}
2043 			}
2044 			info.post_interim_writeback(NULL);
2045 			info.interim_info.eddsa_data.pubkey_gen = 0;
2046 
2047 		}
2048 
2049 		test_ops.prepare_asym_xform = old_xform;
2050 		test_ops.prepare_asym_op = old_op;
2051 		info.op = FIPS_TEST_ASYM_SIGGEN;
2052 		ret = fips_run_asym_test();
2053 	} else {
2054 		ret = fips_run_asym_test();
2055 	}
2056 
2057 	return ret;
2058 }
2059 
2060 static int
2061 fips_generic_test(void)
2062 {
2063 	struct fips_val val = {NULL, 0};
2064 	int ret;
2065 
2066 	if (info.file_type != FIPS_TYPE_JSON)
2067 		fips_test_write_one_case();
2068 
2069 	ret = fips_run_test();
2070 	if (ret < 0) {
2071 		if (ret == -EPERM || ret == -ENOTSUP) {
2072 			if (info.file_type == FIPS_TYPE_JSON)
2073 				return ret;
2074 
2075 			fprintf(info.fp_wr, "Bypass\n\n");
2076 			return 0;
2077 		}
2078 
2079 		return ret;
2080 	}
2081 
2082 	if (!env.is_asym_test) {
2083 		ret = get_writeback_data(&val);
2084 		if (ret < 0)
2085 			return ret;
2086 	}
2087 
2088 	switch (info.file_type) {
2089 	case FIPS_TYPE_REQ:
2090 	case FIPS_TYPE_RSP:
2091 	case FIPS_TYPE_JSON:
2092 		if (info.parse_writeback == NULL)
2093 			return -EPERM;
2094 		ret = info.parse_writeback(&val);
2095 		if (ret < 0)
2096 			return ret;
2097 		break;
2098 	case FIPS_TYPE_FAX:
2099 		if (info.kat_check == NULL)
2100 			return -EPERM;
2101 		ret = info.kat_check(&val);
2102 		if (ret < 0)
2103 			return ret;
2104 		break;
2105 	default:
2106 		break;
2107 	}
2108 
2109 	if (info.file_type != FIPS_TYPE_JSON)
2110 		fprintf(info.fp_wr, "\n");
2111 	rte_free(val.val);
2112 
2113 	return 0;
2114 }
2115 
2116 static int
2117 fips_mct_tdes_test(void)
2118 {
2119 #define TDES_BLOCK_SIZE		8
2120 #define TDES_EXTERN_ITER	400
2121 #define TDES_INTERN_ITER	10000
2122 	struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv;
2123 	uint8_t prev_out[TDES_BLOCK_SIZE] = {0};
2124 	uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0};
2125 	uint8_t prev_in[TDES_BLOCK_SIZE] = {0};
2126 	uint32_t i, j, k;
2127 	int ret;
2128 	int test_mode = info.interim_info.tdes_data.test_mode;
2129 
2130 	pt.len = vec.pt.len;
2131 	pt.val = rte_malloc(NULL, pt.len, 0);
2132 	ct.len = vec.ct.len;
2133 	ct.val = rte_malloc(NULL, ct.len, 0);
2134 	iv.len = vec.iv.len;
2135 	iv.val = rte_malloc(NULL, iv.len, 0);
2136 
2137 	for (i = 0; i < TDES_EXTERN_ITER; i++) {
2138 		if (info.file_type != FIPS_TYPE_JSON) {
2139 			if ((i == 0) && (info.version == 21.4f)) {
2140 				if (!(strstr(info.vec[0], "COUNT")))
2141 					fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0);
2142 			}
2143 
2144 			if (i != 0)
2145 				update_info_vec(i);
2146 
2147 			fips_test_write_one_case();
2148 		}
2149 
2150 		for (j = 0; j < TDES_INTERN_ITER; j++) {
2151 			ret = fips_run_test();
2152 			if (ret < 0) {
2153 				if (ret == -EPERM) {
2154 					if (info.file_type == FIPS_TYPE_JSON)
2155 						return ret;
2156 
2157 					fprintf(info.fp_wr, "Bypass\n");
2158 					return 0;
2159 				}
2160 				return ret;
2161 			}
2162 
2163 			ret = get_writeback_data(&val[0]);
2164 			if (ret < 0)
2165 				return ret;
2166 
2167 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2168 				memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE);
2169 
2170 			if (j == 0) {
2171 				memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
2172 				memcpy(pt.val, vec.pt.val, pt.len);
2173 				memcpy(ct.val, vec.ct.val, ct.len);
2174 				memcpy(iv.val, vec.iv.val, iv.len);
2175 
2176 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2177 					if (test_mode == TDES_MODE_ECB) {
2178 						memcpy(vec.pt.val, val[0].val,
2179 							   TDES_BLOCK_SIZE);
2180 					} else {
2181 						memcpy(vec.pt.val, vec.iv.val,
2182 							   TDES_BLOCK_SIZE);
2183 						memcpy(vec.iv.val, val[0].val,
2184 							   TDES_BLOCK_SIZE);
2185 					}
2186 					val[1].val = pt.val;
2187 					val[1].len = pt.len;
2188 					val[2].val = iv.val;
2189 					val[2].len = iv.len;
2190 				} else {
2191 					if (test_mode == TDES_MODE_ECB) {
2192 						memcpy(vec.ct.val, val[0].val,
2193 							   TDES_BLOCK_SIZE);
2194 					} else {
2195 						memcpy(vec.iv.val, vec.ct.val,
2196 							   TDES_BLOCK_SIZE);
2197 						memcpy(vec.ct.val, val[0].val,
2198 							   TDES_BLOCK_SIZE);
2199 					}
2200 					val[1].val = ct.val;
2201 					val[1].len = ct.len;
2202 					val[2].val = iv.val;
2203 					val[2].len = iv.len;
2204 				}
2205 				continue;
2206 			}
2207 
2208 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2209 				if (test_mode == TDES_MODE_ECB) {
2210 					memcpy(vec.pt.val, val[0].val,
2211 						   TDES_BLOCK_SIZE);
2212 				} else {
2213 					memcpy(vec.iv.val, val[0].val,
2214 						   TDES_BLOCK_SIZE);
2215 					memcpy(vec.pt.val, prev_out,
2216 						   TDES_BLOCK_SIZE);
2217 				}
2218 			} else {
2219 				if (test_mode == TDES_MODE_ECB) {
2220 					memcpy(vec.ct.val, val[0].val,
2221 						   TDES_BLOCK_SIZE);
2222 				} else {
2223 					memcpy(vec.iv.val, vec.ct.val,
2224 						   TDES_BLOCK_SIZE);
2225 					memcpy(vec.ct.val, val[0].val,
2226 						   TDES_BLOCK_SIZE);
2227 				}
2228 			}
2229 
2230 			if (j == TDES_INTERN_ITER - 1)
2231 				continue;
2232 
2233 			memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
2234 
2235 			if (j == TDES_INTERN_ITER - 3)
2236 				memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE);
2237 		}
2238 
2239 		info.parse_writeback(val);
2240 		if (info.file_type != FIPS_TYPE_JSON)
2241 			fprintf(info.fp_wr, "\n");
2242 
2243 		if (i == TDES_EXTERN_ITER - 1)
2244 			continue;
2245 
2246 		/** update key */
2247 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2248 
2249 		if (info.interim_info.tdes_data.nb_keys == 0) {
2250 			if (memcmp(val_key.val, val_key.val + 8, 8) == 0)
2251 				info.interim_info.tdes_data.nb_keys = 1;
2252 			else if (memcmp(val_key.val, val_key.val + 16, 8) == 0)
2253 				info.interim_info.tdes_data.nb_keys = 2;
2254 			else
2255 				info.interim_info.tdes_data.nb_keys = 3;
2256 
2257 		}
2258 
2259 		for (k = 0; k < TDES_BLOCK_SIZE; k++) {
2260 
2261 			switch (info.interim_info.tdes_data.nb_keys) {
2262 			case 3:
2263 				val_key.val[k] ^= val[0].val[k];
2264 				val_key.val[k + 8] ^= prev_out[k];
2265 				val_key.val[k + 16] ^= prev_prev_out[k];
2266 				break;
2267 			case 2:
2268 				val_key.val[k] ^= val[0].val[k];
2269 				val_key.val[k + 8] ^= prev_out[k];
2270 				val_key.val[k + 16] ^= val[0].val[k];
2271 				break;
2272 			default: /* case 1 */
2273 				val_key.val[k] ^= val[0].val[k];
2274 				val_key.val[k + 8] ^= val[0].val[k];
2275 				val_key.val[k + 16] ^= val[0].val[k];
2276 				break;
2277 			}
2278 
2279 		}
2280 
2281 		for (k = 0; k < 24; k++)
2282 			val_key.val[k] = (rte_popcount32(val_key.val[k]) &
2283 					0x1) ?
2284 					val_key.val[k] : (val_key.val[k] ^ 0x1);
2285 
2286 		if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2287 			if (test_mode == TDES_MODE_ECB) {
2288 				memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE);
2289 			} else {
2290 				memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE);
2291 				memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
2292 			}
2293 		} else {
2294 			if (test_mode == TDES_MODE_ECB) {
2295 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
2296 			} else {
2297 				memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE);
2298 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
2299 			}
2300 		}
2301 	}
2302 
2303 	rte_free(val[0].val);
2304 	rte_free(pt.val);
2305 	rte_free(ct.val);
2306 	rte_free(iv.val);
2307 
2308 	return 0;
2309 }
2310 
2311 static int
2312 fips_mct_aes_ecb_test(void)
2313 {
2314 #define AES_BLOCK_SIZE	16
2315 #define AES_EXTERN_ITER	100
2316 #define AES_INTERN_ITER	1000
2317 	struct fips_val val = {NULL, 0}, val_key;
2318 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
2319 	uint32_t i, j, k;
2320 	int ret;
2321 
2322 	for (i = 0; i < AES_EXTERN_ITER; i++) {
2323 		if (i != 0)
2324 			update_info_vec(i);
2325 
2326 		fips_test_write_one_case();
2327 
2328 		for (j = 0; j < AES_INTERN_ITER; j++) {
2329 			ret = fips_run_test();
2330 			if (ret < 0) {
2331 				if (ret == -EPERM) {
2332 					if (info.file_type == FIPS_TYPE_JSON)
2333 						return ret;
2334 
2335 					fprintf(info.fp_wr, "Bypass\n");
2336 					return 0;
2337 				}
2338 
2339 				return ret;
2340 			}
2341 
2342 			ret = get_writeback_data(&val);
2343 			if (ret < 0)
2344 				return ret;
2345 
2346 			if (info.op == FIPS_TEST_ENC_AUTH_GEN)
2347 				memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE);
2348 			else
2349 				memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE);
2350 
2351 			if (j == AES_INTERN_ITER - 1)
2352 				continue;
2353 
2354 			memcpy(prev_out, val.val, AES_BLOCK_SIZE);
2355 		}
2356 
2357 		info.parse_writeback(&val);
2358 		fprintf(info.fp_wr, "\n");
2359 
2360 		if (i == AES_EXTERN_ITER - 1)
2361 			continue;
2362 
2363 		/** update key */
2364 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2365 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
2366 			switch (vec.cipher_auth.key.len) {
2367 			case 16:
2368 				val_key.val[k] ^= val.val[k];
2369 				break;
2370 			case 24:
2371 				if (k < 8)
2372 					val_key.val[k] ^= prev_out[k + 8];
2373 				else
2374 					val_key.val[k] ^= val.val[k - 8];
2375 				break;
2376 			case 32:
2377 				if (k < 16)
2378 					val_key.val[k] ^= prev_out[k];
2379 				else
2380 					val_key.val[k] ^= val.val[k - 16];
2381 				break;
2382 			default:
2383 				return -1;
2384 			}
2385 		}
2386 	}
2387 
2388 	rte_free(val.val);
2389 
2390 	return 0;
2391 }
2392 static int
2393 fips_mct_aes_test(void)
2394 {
2395 #define AES_BLOCK_SIZE	16
2396 #define AES_EXTERN_ITER	100
2397 #define AES_INTERN_ITER	1000
2398 	struct fips_val val[3] = {{NULL, 0},}, val_key,  pt, ct, iv;
2399 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
2400 	uint8_t prev_in[AES_BLOCK_SIZE] = {0};
2401 	uint32_t i, j, k;
2402 	int ret;
2403 
2404 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB)
2405 		return fips_mct_aes_ecb_test();
2406 
2407 	pt.len = vec.pt.len;
2408 	pt.val = rte_malloc(NULL, pt.len, 0);
2409 	ct.len = vec.ct.len;
2410 	ct.val = rte_malloc(NULL, ct.len, 0);
2411 	iv.len = vec.iv.len;
2412 	iv.val = rte_malloc(NULL, iv.len, 0);
2413 	for (i = 0; i < AES_EXTERN_ITER; i++) {
2414 		if (info.file_type != FIPS_TYPE_JSON) {
2415 			if (i != 0)
2416 				update_info_vec(i);
2417 
2418 			fips_test_write_one_case();
2419 		}
2420 
2421 		for (j = 0; j < AES_INTERN_ITER; j++) {
2422 			ret = fips_run_test();
2423 			if (ret < 0) {
2424 				if (ret == -EPERM) {
2425 					if (info.file_type == FIPS_TYPE_JSON)
2426 						return ret;
2427 
2428 					fprintf(info.fp_wr, "Bypass\n");
2429 					return 0;
2430 				}
2431 
2432 				return ret;
2433 			}
2434 
2435 			ret = get_writeback_data(&val[0]);
2436 			if (ret < 0)
2437 				return ret;
2438 
2439 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2440 				memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE);
2441 
2442 			if (j == 0) {
2443 				memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
2444 				memcpy(pt.val, vec.pt.val, pt.len);
2445 				memcpy(ct.val, vec.ct.val, ct.len);
2446 				memcpy(iv.val, vec.iv.val, iv.len);
2447 
2448 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2449 					memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE);
2450 					memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2451 					val[1].val = pt.val;
2452 					val[1].len = pt.len;
2453 					val[2].val = iv.val;
2454 					val[2].len = iv.len;
2455 				} else {
2456 					memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE);
2457 					memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
2458 					val[1].val = ct.val;
2459 					val[1].len = ct.len;
2460 					val[2].val = iv.val;
2461 					val[2].len = iv.len;
2462 				}
2463 				continue;
2464 			}
2465 
2466 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2467 				memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2468 				memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE);
2469 			} else {
2470 				memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
2471 				memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE);
2472 			}
2473 
2474 			if (j == AES_INTERN_ITER - 1)
2475 				continue;
2476 
2477 			memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
2478 		}
2479 
2480 		info.parse_writeback(val);
2481 		if (info.file_type != FIPS_TYPE_JSON)
2482 			fprintf(info.fp_wr, "\n");
2483 
2484 		if (i == AES_EXTERN_ITER - 1)
2485 			continue;
2486 
2487 		/** update key */
2488 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2489 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
2490 			switch (vec.cipher_auth.key.len) {
2491 			case 16:
2492 				val_key.val[k] ^= val[0].val[k];
2493 				break;
2494 			case 24:
2495 				if (k < 8)
2496 					val_key.val[k] ^= prev_out[k + 8];
2497 				else
2498 					val_key.val[k] ^= val[0].val[k - 8];
2499 				break;
2500 			case 32:
2501 				if (k < 16)
2502 					val_key.val[k] ^= prev_out[k];
2503 				else
2504 					val_key.val[k] ^= val[0].val[k - 16];
2505 				break;
2506 			default:
2507 				return -1;
2508 			}
2509 		}
2510 
2511 		if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2512 			memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2513 	}
2514 
2515 	rte_free(val[0].val);
2516 	rte_free(pt.val);
2517 	rte_free(ct.val);
2518 	rte_free(iv.val);
2519 
2520 	return 0;
2521 }
2522 
2523 static int
2524 fips_mct_sha_test(void)
2525 {
2526 #define SHA_EXTERN_ITER	100
2527 #define SHA_INTERN_ITER	1000
2528 	uint8_t md_blocks = info.interim_info.sha_data.md_blocks;
2529 	struct fips_val val = {NULL, 0};
2530 	struct fips_val  md[md_blocks];
2531 	int ret;
2532 	uint32_t i, j, k, offset, max_outlen;
2533 
2534 	max_outlen = md_blocks * vec.cipher_auth.digest.len;
2535 
2536 	rte_free(vec.cipher_auth.digest.val);
2537 	vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0);
2538 
2539 	if (vec.pt.val)
2540 		memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len);
2541 
2542 	rte_free(vec.pt.val);
2543 	vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*md_blocks), 0);
2544 
2545 	for (i = 0; i < md_blocks; i++)
2546 		md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0);
2547 
2548 	if (info.file_type != FIPS_TYPE_JSON) {
2549 		fips_test_write_one_case();
2550 		fprintf(info.fp_wr, "\n");
2551 	}
2552 
2553 	for (j = 0; j < SHA_EXTERN_ITER; j++) {
2554 		for (i = 0; i < md_blocks; i++) {
2555 			memcpy(md[i].val, vec.cipher_auth.digest.val,
2556 				vec.cipher_auth.digest.len);
2557 			md[i].len = vec.cipher_auth.digest.len;
2558 		}
2559 
2560 		for (i = 0; i < (SHA_INTERN_ITER); i++) {
2561 			offset = 0;
2562 			for (k = 0; k < md_blocks; k++) {
2563 				memcpy(vec.pt.val + offset, md[k].val, (size_t)md[k].len);
2564 				offset += md[k].len;
2565 			}
2566 			vec.pt.len = offset;
2567 
2568 			ret = fips_run_test();
2569 			if (ret < 0) {
2570 				if (ret == -EPERM || ret == -ENOTSUP) {
2571 					if (info.file_type == FIPS_TYPE_JSON)
2572 						return ret;
2573 
2574 					fprintf(info.fp_wr, "Bypass\n\n");
2575 					return 0;
2576 				}
2577 				return ret;
2578 			}
2579 
2580 			ret = get_writeback_data(&val);
2581 			if (ret < 0)
2582 				return ret;
2583 
2584 			for (k = 1; k < md_blocks; k++) {
2585 				memcpy(md[k-1].val, md[k].val, md[k].len);
2586 				md[k-1].len = md[k].len;
2587 			}
2588 
2589 			memcpy(md[md_blocks-1].val, (val.val + vec.pt.len),
2590 				vec.cipher_auth.digest.len);
2591 			md[md_blocks-1].len = vec.cipher_auth.digest.len;
2592 		}
2593 
2594 		memcpy(vec.cipher_auth.digest.val, md[md_blocks-1].val, md[md_blocks-1].len);
2595 		vec.cipher_auth.digest.len = md[md_blocks-1].len;
2596 
2597 		if (info.file_type != FIPS_TYPE_JSON)
2598 			fprintf(info.fp_wr, "COUNT = %u\n", j);
2599 
2600 		info.parse_writeback(&val);
2601 
2602 		if (info.file_type != FIPS_TYPE_JSON)
2603 			fprintf(info.fp_wr, "\n");
2604 	}
2605 
2606 	for (i = 0; i < (md_blocks); i++)
2607 		rte_free(md[i].val);
2608 
2609 	rte_free(vec.pt.val);
2610 
2611 	rte_free(val.val);
2612 	return 0;
2613 }
2614 
2615 static int
2616 fips_mct_shake_test(void)
2617 {
2618 #define SHAKE_EXTERN_ITER	100
2619 #define SHAKE_INTERN_ITER	1000
2620 	uint32_t i, j, range, outlen, max_outlen;
2621 	struct fips_val val = {NULL, 0}, md;
2622 	uint8_t rightmost[2];
2623 	uint16_t *rightptr;
2624 	int ret;
2625 
2626 	max_outlen = vec.cipher_auth.digest.len;
2627 
2628 	rte_free(vec.cipher_auth.digest.val);
2629 	vec.cipher_auth.digest.val = rte_malloc(NULL, max_outlen, 0);
2630 
2631 	if (vec.pt.val)
2632 		memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.pt.len);
2633 
2634 	rte_free(vec.pt.val);
2635 	vec.pt.val = rte_malloc(NULL, 16, 0);
2636 	vec.pt.len = 16;
2637 
2638 	md.val = rte_malloc(NULL, max_outlen, 0);
2639 	md.len = max_outlen;
2640 
2641 	if (info.file_type != FIPS_TYPE_JSON) {
2642 		fips_test_write_one_case();
2643 		fprintf(info.fp_wr, "\n");
2644 	}
2645 
2646 	range = max_outlen - info.interim_info.sha_data.min_outlen + 1;
2647 	outlen = max_outlen;
2648 	for (j = 0; j < SHAKE_EXTERN_ITER; j++) {
2649 		memset(md.val, 0, max_outlen);
2650 		memcpy(md.val, vec.cipher_auth.digest.val,
2651 			vec.cipher_auth.digest.len);
2652 
2653 		for (i = 0; i < (SHAKE_INTERN_ITER); i++) {
2654 			memset(vec.pt.val, 0, vec.pt.len);
2655 			memcpy(vec.pt.val, md.val, vec.pt.len);
2656 			vec.cipher_auth.digest.len = outlen;
2657 			ret = fips_run_test();
2658 			if (ret < 0) {
2659 				if (ret == -EPERM || ret == -ENOTSUP) {
2660 					if (info.file_type == FIPS_TYPE_JSON)
2661 						return ret;
2662 
2663 					fprintf(info.fp_wr, "Bypass\n\n");
2664 					return 0;
2665 				}
2666 				return ret;
2667 			}
2668 
2669 			ret = get_writeback_data(&val);
2670 			if (ret < 0)
2671 				return ret;
2672 
2673 			memset(md.val, 0, max_outlen);
2674 			memcpy(md.val, (val.val + vec.pt.len),
2675 				vec.cipher_auth.digest.len);
2676 			md.len = outlen;
2677 			rightmost[0] = md.val[md.len-1];
2678 			rightmost[1] = md.val[md.len-2];
2679 			rightptr = (uint16_t *)rightmost;
2680 			outlen = info.interim_info.sha_data.min_outlen +
2681 				(*rightptr % range);
2682 		}
2683 
2684 		memcpy(vec.cipher_auth.digest.val, md.val, md.len);
2685 		vec.cipher_auth.digest.len = md.len;
2686 
2687 		if (info.file_type != FIPS_TYPE_JSON)
2688 			fprintf(info.fp_wr, "COUNT = %u\n", j);
2689 
2690 		info.parse_writeback(&val);
2691 
2692 		if (info.file_type != FIPS_TYPE_JSON)
2693 			fprintf(info.fp_wr, "\n");
2694 	}
2695 
2696 	rte_free(md.val);
2697 	rte_free(vec.pt.val);
2698 	rte_free(val.val);
2699 	return 0;
2700 }
2701 
2702 static int
2703 init_test_ops(void)
2704 {
2705 	switch (info.algo) {
2706 	case FIPS_TEST_ALGO_AES_CBC:
2707 	case FIPS_TEST_ALGO_AES_CTR:
2708 	case FIPS_TEST_ALGO_AES:
2709 		test_ops.prepare_sym_op = prepare_cipher_op;
2710 		test_ops.prepare_sym_xform  = prepare_aes_xform;
2711 		if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)
2712 			test_ops.test = fips_mct_aes_test;
2713 		else
2714 			test_ops.test = fips_generic_test;
2715 		break;
2716 	case FIPS_TEST_ALGO_HMAC:
2717 		test_ops.prepare_sym_op = prepare_auth_op;
2718 		test_ops.prepare_sym_xform = prepare_hmac_xform;
2719 		test_ops.test = fips_generic_test;
2720 		break;
2721 	case FIPS_TEST_ALGO_TDES:
2722 		test_ops.prepare_sym_op = prepare_cipher_op;
2723 		test_ops.prepare_sym_xform = prepare_tdes_xform;
2724 		if (info.interim_info.tdes_data.test_type == TDES_MCT)
2725 			test_ops.test = fips_mct_tdes_test;
2726 		else
2727 			test_ops.test = fips_generic_test;
2728 		break;
2729 	case FIPS_TEST_ALGO_AES_GMAC:
2730 		test_ops.prepare_sym_op = prepare_auth_op;
2731 		test_ops.prepare_sym_xform = prepare_gmac_xform;
2732 		test_ops.test = fips_generic_test;
2733 		break;
2734 	case FIPS_TEST_ALGO_AES_GCM:
2735 		test_ops.prepare_sym_op = prepare_aead_op;
2736 		test_ops.prepare_sym_xform = prepare_gcm_xform;
2737 		test_ops.test = fips_generic_test;
2738 		break;
2739 	case FIPS_TEST_ALGO_AES_CMAC:
2740 		test_ops.prepare_sym_op = prepare_auth_op;
2741 		test_ops.prepare_sym_xform = prepare_cmac_xform;
2742 		test_ops.test = fips_generic_test;
2743 		break;
2744 	case FIPS_TEST_ALGO_AES_CCM:
2745 		test_ops.prepare_sym_op = prepare_aead_op;
2746 		test_ops.prepare_sym_xform = prepare_ccm_xform;
2747 		test_ops.test = fips_generic_test;
2748 		break;
2749 	case FIPS_TEST_ALGO_SHA:
2750 		test_ops.prepare_sym_op = prepare_auth_op;
2751 		test_ops.prepare_sym_xform = prepare_sha_xform;
2752 		if (info.interim_info.sha_data.test_type == SHA_MCT)
2753 			if (info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_128 ||
2754 				info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_256)
2755 				test_ops.test = fips_mct_shake_test;
2756 			else
2757 				test_ops.test = fips_mct_sha_test;
2758 		else
2759 			test_ops.test = fips_generic_test;
2760 		break;
2761 	case FIPS_TEST_ALGO_AES_XTS:
2762 		test_ops.prepare_sym_op = prepare_cipher_op;
2763 		test_ops.prepare_sym_xform = prepare_xts_xform;
2764 		test_ops.test = fips_generic_test;
2765 		break;
2766 	case FIPS_TEST_ALGO_RSA:
2767 		test_ops.prepare_asym_op = prepare_rsa_op;
2768 		test_ops.prepare_asym_xform = prepare_rsa_xform;
2769 		test_ops.test = fips_generic_test;
2770 		break;
2771 	case FIPS_TEST_ALGO_ECDSA:
2772 		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
2773 			test_ops.prepare_asym_op = prepare_ecfpm_op;
2774 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
2775 			test_ops.test = fips_generic_test;
2776 		} else {
2777 			test_ops.prepare_asym_op = prepare_ecdsa_op;
2778 			test_ops.prepare_asym_xform = prepare_ecdsa_xform;
2779 			test_ops.test = fips_generic_test;
2780 		}
2781 		break;
2782 	case FIPS_TEST_ALGO_EDDSA:
2783 		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
2784 			test_ops.prepare_asym_op = prepare_edfpm_op;
2785 			test_ops.prepare_asym_xform = prepare_edfpm_xform;
2786 			test_ops.test = fips_generic_test;
2787 		} else {
2788 			test_ops.prepare_asym_op = prepare_eddsa_op;
2789 			test_ops.prepare_asym_xform = prepare_eddsa_xform;
2790 			test_ops.test = fips_generic_test;
2791 		}
2792 		break;
2793 	default:
2794 		if (strstr(info.file_name, "TECB") ||
2795 				strstr(info.file_name, "TCBC")) {
2796 			info.algo = FIPS_TEST_ALGO_TDES;
2797 			test_ops.prepare_sym_op = prepare_cipher_op;
2798 			test_ops.prepare_sym_xform = prepare_tdes_xform;
2799 			if (info.interim_info.tdes_data.test_type == TDES_MCT)
2800 				test_ops.test = fips_mct_tdes_test;
2801 			else
2802 				test_ops.test = fips_generic_test;
2803 			break;
2804 		}
2805 		return -1;
2806 	}
2807 
2808 	return 0;
2809 }
2810 
2811 static void
2812 print_test_block(void)
2813 {
2814 	uint32_t i;
2815 
2816 	for (i = 0; i < info.nb_vec_lines; i++)
2817 		printf("%s\n", info.vec[i]);
2818 
2819 	printf("\n");
2820 }
2821 
2822 static int
2823 fips_test_one_file(void)
2824 {
2825 	int fetch_ret = 0, ret;
2826 
2827 	ret = init_test_ops();
2828 	if (ret < 0) {
2829 		RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret);
2830 		return ret;
2831 	}
2832 
2833 	while (ret >= 0 && fetch_ret == 0) {
2834 		fetch_ret = fips_test_fetch_one_block();
2835 		if (fetch_ret < 0) {
2836 			RTE_LOG(ERR, USER1, "Error %i: Fetch block\n",
2837 					fetch_ret);
2838 			ret = fetch_ret;
2839 			goto error_one_case;
2840 		}
2841 
2842 		if (info.nb_vec_lines == 0) {
2843 			if (fetch_ret == -EOF)
2844 				break;
2845 
2846 			fprintf(info.fp_wr, "\n");
2847 			continue;
2848 		}
2849 
2850 		ret = fips_test_parse_one_case();
2851 		switch (ret) {
2852 		case 0:
2853 			ret = test_ops.test();
2854 			if (ret == 0)
2855 				break;
2856 			RTE_LOG(ERR, USER1, "Error %i: test block\n",
2857 					ret);
2858 			goto error_one_case;
2859 		case 1:
2860 			break;
2861 		default:
2862 			RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
2863 					ret);
2864 			goto error_one_case;
2865 		}
2866 
2867 		continue;
2868 error_one_case:
2869 		print_test_block();
2870 	}
2871 
2872 	fips_test_clear();
2873 
2874 	if (env.digest) {
2875 		rte_free(env.digest);
2876 		env.digest = NULL;
2877 		env.digest_len = 0;
2878 	}
2879 	rte_pktmbuf_free(env.mbuf);
2880 
2881 	return ret;
2882 }
2883 
2884 #ifdef USE_JANSSON
2885 static int
2886 fips_test_json_init_writeback(void)
2887 {
2888 	json_t *session_info, *session_write;
2889 	session_info = json_array_get(json_info.json_root, 0);
2890 	session_write = json_object();
2891 	json_info.json_write_root = json_array();
2892 
2893 	json_object_set(session_write, "jwt",
2894 		json_object_get(session_info, "jwt"));
2895 	json_object_set(session_write, "url",
2896 		json_object_get(session_info, "url"));
2897 	json_object_set(session_write, "isSample",
2898 		json_object_get(session_info, "isSample"));
2899 
2900 	json_info.is_sample = json_boolean_value(
2901 		json_object_get(session_info, "isSample"));
2902 
2903 	json_array_append_new(json_info.json_write_root, session_write);
2904 	return 0;
2905 }
2906 
2907 static int
2908 fips_test_one_test_case(void)
2909 {
2910 	int ret;
2911 
2912 	ret = fips_test_parse_one_json_case();
2913 
2914 	switch (ret) {
2915 	case 0:
2916 		ret = test_ops.test();
2917 		if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP))
2918 			break;
2919 		RTE_LOG(ERR, USER1, "Error %i: test block\n",
2920 				ret);
2921 		break;
2922 	default:
2923 		RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
2924 				ret);
2925 	}
2926 	return ret;
2927 }
2928 
2929 static int
2930 fips_test_one_test_group(void)
2931 {
2932 	int ret;
2933 	json_t *tests, *write_tests;
2934 	size_t test_idx, tests_size;
2935 
2936 	write_tests = json_array();
2937 	json_info.json_write_group = json_object();
2938 	json_object_set(json_info.json_write_group, "tgId",
2939 		json_object_get(json_info.json_test_group, "tgId"));
2940 	json_object_set_new(json_info.json_write_group, "tests", write_tests);
2941 
2942 	switch (info.algo) {
2943 	case FIPS_TEST_ALGO_AES_GMAC:
2944 	case FIPS_TEST_ALGO_AES_GCM:
2945 		ret = parse_test_gcm_json_init();
2946 		break;
2947 	case FIPS_TEST_ALGO_AES_CCM:
2948 		ret = parse_test_ccm_json_init();
2949 		break;
2950 	case FIPS_TEST_ALGO_HMAC:
2951 		ret = parse_test_hmac_json_init();
2952 		break;
2953 	case FIPS_TEST_ALGO_AES_CMAC:
2954 		ret = parse_test_cmac_json_init();
2955 		break;
2956 	case FIPS_TEST_ALGO_AES_XTS:
2957 		ret = parse_test_xts_json_init();
2958 		break;
2959 	case FIPS_TEST_ALGO_AES_CBC:
2960 	case FIPS_TEST_ALGO_AES_CTR:
2961 	case FIPS_TEST_ALGO_AES:
2962 		ret = parse_test_aes_json_init();
2963 		break;
2964 	case FIPS_TEST_ALGO_SHA:
2965 		ret = parse_test_sha_json_init();
2966 		break;
2967 	case FIPS_TEST_ALGO_TDES:
2968 		ret = parse_test_tdes_json_init();
2969 		break;
2970 	case FIPS_TEST_ALGO_RSA:
2971 		ret = parse_test_rsa_json_init();
2972 		break;
2973 	case FIPS_TEST_ALGO_ECDSA:
2974 		ret = parse_test_ecdsa_json_init();
2975 		break;
2976 	case FIPS_TEST_ALGO_EDDSA:
2977 		ret = parse_test_eddsa_json_init();
2978 		break;
2979 	default:
2980 		return -EINVAL;
2981 	}
2982 
2983 	if (ret < 0)
2984 		return ret;
2985 
2986 	ret = fips_test_parse_one_json_group();
2987 	if (ret < 0)
2988 		return ret;
2989 
2990 	ret = init_test_ops();
2991 	if (ret < 0)
2992 		return ret;
2993 
2994 	tests = json_object_get(json_info.json_test_group, "tests");
2995 	tests_size = json_array_size(tests);
2996 	for (test_idx = 0; test_idx < tests_size; test_idx++) {
2997 		json_info.json_test_case = json_array_get(tests, test_idx);
2998 		if (fips_test_one_test_case() == 0)
2999 			json_array_append_new(write_tests, json_info.json_write_case);
3000 	}
3001 
3002 	return 0;
3003 }
3004 
3005 static int
3006 fips_test_one_vector_set(void)
3007 {
3008 	int ret;
3009 	json_t *test_groups, *write_groups, *write_version, *write_set, *mode;
3010 	size_t group_idx, num_groups;
3011 
3012 	test_groups = json_object_get(json_info.json_vector_set, "testGroups");
3013 	num_groups = json_array_size(test_groups);
3014 
3015 	json_info.json_write_set = json_array();
3016 	write_version = json_object();
3017 	json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION));
3018 	json_array_append_new(json_info.json_write_set, write_version);
3019 
3020 	write_set = json_object();
3021 	json_array_append(json_info.json_write_set, write_set);
3022 	write_groups = json_array();
3023 
3024 	json_object_set(write_set, "vsId",
3025 		json_object_get(json_info.json_vector_set, "vsId"));
3026 	json_object_set(write_set, "algorithm",
3027 		json_object_get(json_info.json_vector_set, "algorithm"));
3028 	mode = json_object_get(json_info.json_vector_set, "mode");
3029 	if (mode != NULL)
3030 		json_object_set_new(write_set, "mode", mode);
3031 
3032 	json_object_set(write_set, "revision",
3033 		json_object_get(json_info.json_vector_set, "revision"));
3034 	json_object_set_new(write_set, "isSample",
3035 		json_boolean(json_info.is_sample));
3036 	json_object_set_new(write_set, "testGroups", write_groups);
3037 
3038 	ret = fips_test_parse_one_json_vector_set();
3039 	if (ret < 0) {
3040 		RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n",
3041 			json_string_value(json_object_get(json_info.json_vector_set, "algorithm")));
3042 		return ret;
3043 	}
3044 
3045 	for (group_idx = 0; group_idx < num_groups; group_idx++) {
3046 		json_info.json_test_group = json_array_get(test_groups, group_idx);
3047 		ret = fips_test_one_test_group();
3048 		json_array_append_new(write_groups, json_info.json_write_group);
3049 	}
3050 
3051 	return 0;
3052 }
3053 
3054 static int
3055 fips_test_one_json_file(void)
3056 {
3057 	size_t vector_set_idx, root_size;
3058 
3059 	root_size = json_array_size(json_info.json_root);
3060 	fips_test_json_init_writeback();
3061 
3062 	for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) {
3063 		/* Vector set index starts at 1, the 0th index contains test session
3064 		 * information.
3065 		 */
3066 		json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx);
3067 		fips_test_one_vector_set();
3068 		json_array_append_new(json_info.json_write_root, json_info.json_write_set);
3069 		json_incref(json_info.json_write_set);
3070 	}
3071 
3072 	json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4));
3073 	json_decref(json_info.json_write_root);
3074 
3075 	return 0;
3076 }
3077 #endif /* USE_JANSSON */
3078