xref: /dpdk/examples/fips_validation/main.c (revision 410d016961fa1950f34aeeb43992cf7b7127df52)
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 
16 #include "fips_validation.h"
17 #include "fips_dev_self_test.h"
18 
19 enum {
20 #define OPT_REQ_FILE_PATH           "req-file"
21 	OPT_REQ_FILE_PATH_NUM = 256,
22 #define OPT_RSP_FILE_PATH           "rsp-file"
23 	OPT_RSP_FILE_PATH_NUM,
24 #define OPT_MBUF_DATAROOM           "mbuf-dataroom"
25 	OPT_MBUF_DATAROOM_NUM,
26 #define OPT_FOLDER                  "path-is-folder"
27 	OPT_FOLDER_NUM,
28 #define OPT_CRYPTODEV               "cryptodev"
29 	OPT_CRYPTODEV_NUM,
30 #define OPT_CRYPTODEV_ID            "cryptodev-id"
31 	OPT_CRYPTODEV_ID_NUM,
32 #define OPT_CRYPTODEV_ST            "self-test"
33 	OPT_CRYPTODEV_ST_NUM,
34 #define OPT_CRYPTODEV_BK_ID         "broken-test-id"
35 	OPT_CRYPTODEV_BK_ID_NUM,
36 #define OPT_CRYPTODEV_BK_DIR_KEY    "broken-test-dir"
37 	OPT_CRYPTODEV_BK_DIR_KEY_NUM,
38 #define OPT_USE_JSON                "use-json"
39 	OPT_USE_JSON_NUM,
40 #define OPT_CRYPTODEV_ASYM          "asymmetric"
41 	OPT_CRYPTODEV_ASYM_NUM,
42 };
43 
44 struct fips_test_vector vec;
45 struct fips_test_interim_info info;
46 
47 #ifdef USE_JANSSON
48 struct fips_test_json_info json_info;
49 #endif /* USE_JANSSON */
50 
51 struct cryptodev_fips_validate_env {
52 	const char *req_path;
53 	const char *rsp_path;
54 	uint32_t is_path_folder;
55 	uint8_t dev_id;
56 	struct rte_mempool *mpool;
57 	struct fips_sym_env {
58 		struct rte_mempool *sess_mpool;
59 		struct rte_mempool *op_pool;
60 		struct rte_cryptodev_sym_session *sess;
61 		struct rte_crypto_op *op;
62 	} sym;
63 	struct fips_asym_env {
64 		struct rte_mempool *sess_mpool;
65 		struct rte_mempool *op_pool;
66 		struct rte_cryptodev_asym_session *sess;
67 		struct rte_crypto_op *op;
68 	} asym;
69 	struct rte_crypto_op *op;
70 	uint8_t dev_support_sgl;
71 	uint16_t mbuf_data_room;
72 	struct rte_mbuf *mbuf;
73 	uint8_t *digest;
74 	uint16_t digest_len;
75 	bool is_asym_test;
76 	uint16_t self_test;
77 	struct fips_dev_broken_test_config *broken_test_config;
78 } env;
79 
80 static int
81 cryptodev_fips_validate_app_sym_init(void)
82 {
83 	uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size(
84 							env.dev_id);
85 	struct rte_cryptodev_info dev_info;
86 	struct fips_sym_env *sym = &env.sym;
87 	int ret;
88 
89 	rte_cryptodev_info_get(env.dev_id, &dev_info);
90 	if (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)
91 		env.dev_support_sgl = 1;
92 	else
93 		env.dev_support_sgl = 0;
94 
95 	ret = -ENOMEM;
96 	sym->sess_mpool = rte_cryptodev_sym_session_pool_create(
97 			"FIPS_SYM_SESS_MEMPOOL", 16, sess_sz, 0, 0, rte_socket_id());
98 	if (!sym->sess_mpool)
99 		goto error_exit;
100 
101 	sym->op_pool = rte_crypto_op_pool_create(
102 			"FIPS_OP_SYM_POOL",
103 			RTE_CRYPTO_OP_TYPE_SYMMETRIC,
104 			1, 0,
105 			16,
106 			rte_socket_id());
107 	if (!sym->op_pool)
108 		goto error_exit;
109 
110 	sym->op = rte_crypto_op_alloc(sym->op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
111 	if (!sym->op)
112 		goto error_exit;
113 
114 	return 0;
115 
116 error_exit:
117 	rte_mempool_free(sym->sess_mpool);
118 	rte_mempool_free(sym->op_pool);
119 	return ret;
120 }
121 
122 static void
123 cryptodev_fips_validate_app_sym_uninit(void)
124 {
125 	struct fips_sym_env *sym = &env.sym;
126 
127 	rte_pktmbuf_free(env.mbuf);
128 	rte_crypto_op_free(sym->op);
129 	rte_cryptodev_sym_session_free(env.dev_id, sym->sess);
130 	rte_mempool_free(sym->sess_mpool);
131 	rte_mempool_free(sym->op_pool);
132 }
133 
134 static int
135 cryptodev_fips_validate_app_asym_init(void)
136 {
137 	struct fips_asym_env *asym = &env.asym;
138 	int ret;
139 
140 	ret = -ENOMEM;
141 	asym->sess_mpool = rte_cryptodev_asym_session_pool_create(
142 			"FIPS_ASYM_SESS_MEMPOOL", 16, 0, 0, rte_socket_id());
143 	if (!asym->sess_mpool)
144 		goto error_exit;
145 
146 	asym->op_pool = rte_crypto_op_pool_create(
147 			"FIPS_OP_ASYM_POOL",
148 			RTE_CRYPTO_OP_TYPE_ASYMMETRIC,
149 			1, 0,
150 			16,
151 			rte_socket_id());
152 	if (!asym->op_pool)
153 		goto error_exit;
154 
155 	asym->op = rte_crypto_op_alloc(asym->op_pool, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
156 	if (!asym->op)
157 		goto error_exit;
158 
159 	return 0;
160 
161 error_exit:
162 	rte_mempool_free(asym->sess_mpool);
163 	rte_mempool_free(asym->op_pool);
164 	return ret;
165 }
166 
167 static void
168 cryptodev_fips_validate_app_asym_uninit(void)
169 {
170 	struct fips_asym_env *asym = &env.asym;
171 
172 	rte_crypto_op_free(asym->op);
173 	rte_cryptodev_asym_session_free(env.dev_id, asym->sess);
174 	rte_mempool_free(asym->sess_mpool);
175 	rte_mempool_free(asym->op_pool);
176 }
177 
178 static int
179 cryptodev_fips_validate_app_init(void)
180 {
181 	struct rte_cryptodev_config conf = {rte_socket_id(), 1, 0};
182 	struct rte_cryptodev_qp_conf qp_conf = {128, NULL};
183 	uint32_t nb_mbufs = UINT16_MAX / env.mbuf_data_room + 1;
184 	int ret;
185 
186 	if (env.self_test) {
187 		ret = fips_dev_self_test(env.dev_id, env.broken_test_config);
188 		if (ret < 0) {
189 			rte_cryptodev_stop(env.dev_id);
190 			rte_cryptodev_close(env.dev_id);
191 
192 			return ret;
193 		}
194 	}
195 
196 	ret = rte_cryptodev_configure(env.dev_id, &conf);
197 	if (ret < 0)
198 		return ret;
199 
200 	ret = -ENOMEM;
201 	env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", nb_mbufs,
202 			0, 0, sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM +
203 			env.mbuf_data_room, rte_socket_id());
204 	if (!env.mpool)
205 		return ret;
206 
207 	ret = cryptodev_fips_validate_app_sym_init();
208 	if (ret < 0)
209 		goto error_exit;
210 
211 	if (env.is_asym_test) {
212 		ret = cryptodev_fips_validate_app_asym_init();
213 		if (ret < 0)
214 			goto error_exit;
215 	}
216 
217 	qp_conf.mp_session = env.sym.sess_mpool;
218 
219 	ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
220 			rte_socket_id());
221 	if (ret < 0)
222 		goto error_exit;
223 
224 	ret = rte_cryptodev_start(env.dev_id);
225 	if (ret < 0)
226 		goto error_exit;
227 
228 	return 0;
229 
230 error_exit:
231 	rte_mempool_free(env.mpool);
232 	return ret;
233 }
234 
235 static void
236 cryptodev_fips_validate_app_uninit(void)
237 {
238 	cryptodev_fips_validate_app_sym_uninit();
239 
240 	if (env.is_asym_test)
241 		cryptodev_fips_validate_app_asym_uninit();
242 
243 	rte_mempool_free(env.mpool);
244 	rte_cryptodev_stop(env.dev_id);
245 	rte_cryptodev_close(env.dev_id);
246 }
247 
248 static int
249 fips_test_one_file(void);
250 
251 #ifdef USE_JANSSON
252 static int
253 fips_test_one_json_file(void);
254 #endif /* USE_JANSSON */
255 
256 static int
257 parse_cryptodev_arg(char *arg)
258 {
259 	int id = rte_cryptodev_get_dev_id(arg);
260 
261 	if (id < 0) {
262 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev name %s\n",
263 				id, arg);
264 		return id;
265 	}
266 
267 	env.dev_id = (uint8_t)id;
268 
269 	return 0;
270 }
271 
272 static int
273 parse_cryptodev_id_arg(char *arg)
274 {
275 	uint32_t cryptodev_id;
276 
277 	if (parser_read_uint32(&cryptodev_id, arg) < 0) {
278 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n",
279 				-EINVAL, arg);
280 		return -1;
281 	}
282 
283 
284 	if (!rte_cryptodev_is_valid_dev(cryptodev_id)) {
285 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n",
286 				cryptodev_id, arg);
287 		return -1;
288 	}
289 
290 	env.dev_id = (uint8_t)cryptodev_id;
291 
292 	return 0;
293 }
294 
295 static void
296 cryptodev_fips_validate_usage(const char *prgname)
297 {
298 	uint32_t def_mbuf_seg_size = DEF_MBUF_SEG_SIZE;
299 	printf("%s [EAL options] --\n"
300 		"  --%s: REQUEST-FILE-PATH\n"
301 		"  --%s: RESPONSE-FILE-PATH\n"
302 		"  --%s: indicating both paths are folders\n"
303 		"  --%s: mbuf dataroom size (default %u bytes)\n"
304 		"  --%s: CRYPTODEV-NAME\n"
305 		"  --%s: CRYPTODEV-ID-NAME\n"
306 		"  --%s: self test indicator\n"
307 		"  --%s: self broken test ID\n"
308 		"  --%s: self broken test direction\n",
309 		prgname, OPT_REQ_FILE_PATH, OPT_RSP_FILE_PATH,
310 		OPT_FOLDER, OPT_MBUF_DATAROOM, def_mbuf_seg_size,
311 		OPT_CRYPTODEV, OPT_CRYPTODEV_ID, OPT_CRYPTODEV_ST,
312 		OPT_CRYPTODEV_BK_ID, OPT_CRYPTODEV_BK_DIR_KEY);
313 }
314 
315 static int
316 cryptodev_fips_validate_parse_args(int argc, char **argv)
317 {
318 	int opt, ret;
319 	char *prgname = argv[0];
320 	char **argvopt;
321 	int option_index;
322 	struct option lgopts[] = {
323 		{OPT_REQ_FILE_PATH, required_argument,
324 				NULL, OPT_REQ_FILE_PATH_NUM},
325 		{OPT_RSP_FILE_PATH, required_argument,
326 				NULL, OPT_RSP_FILE_PATH_NUM},
327 		{OPT_FOLDER, no_argument,
328 				NULL, OPT_FOLDER_NUM},
329 		{OPT_MBUF_DATAROOM, required_argument,
330 				NULL, OPT_MBUF_DATAROOM_NUM},
331 		{OPT_CRYPTODEV, required_argument,
332 				NULL, OPT_CRYPTODEV_NUM},
333 		{OPT_CRYPTODEV_ID, required_argument,
334 				NULL, OPT_CRYPTODEV_ID_NUM},
335 		{OPT_CRYPTODEV_ST, no_argument,
336 				NULL, OPT_CRYPTODEV_ST_NUM},
337 		{OPT_CRYPTODEV_BK_ID, required_argument,
338 				NULL, OPT_CRYPTODEV_BK_ID_NUM},
339 		{OPT_CRYPTODEV_BK_DIR_KEY, required_argument,
340 				NULL, OPT_CRYPTODEV_BK_DIR_KEY_NUM},
341 		{OPT_CRYPTODEV_ASYM, no_argument,
342 				NULL, OPT_CRYPTODEV_ASYM_NUM},
343 		{NULL, 0, 0, 0}
344 	};
345 
346 	argvopt = argv;
347 
348 	env.mbuf_data_room = DEF_MBUF_SEG_SIZE;
349 	if (rte_cryptodev_count())
350 		env.dev_id = 0;
351 	else {
352 		cryptodev_fips_validate_usage(prgname);
353 		return -EINVAL;
354 	}
355 
356 	while ((opt = getopt_long(argc, argvopt, "s:",
357 				  lgopts, &option_index)) != EOF) {
358 
359 		switch (opt) {
360 		case OPT_REQ_FILE_PATH_NUM:
361 			env.req_path = optarg;
362 			break;
363 
364 		case OPT_RSP_FILE_PATH_NUM:
365 			env.rsp_path = optarg;
366 			break;
367 
368 		case OPT_FOLDER_NUM:
369 			env.is_path_folder = 1;
370 			break;
371 
372 		case OPT_CRYPTODEV_NUM:
373 			ret = parse_cryptodev_arg(optarg);
374 			if (ret < 0) {
375 				cryptodev_fips_validate_usage(prgname);
376 				return -EINVAL;
377 			}
378 			break;
379 
380 		case OPT_CRYPTODEV_ID_NUM:
381 			ret = parse_cryptodev_id_arg(optarg);
382 			if (ret < 0) {
383 				cryptodev_fips_validate_usage(prgname);
384 				return -EINVAL;
385 			}
386 			break;
387 
388 		case OPT_CRYPTODEV_ST_NUM:
389 			env.self_test = 1;
390 			break;
391 
392 		case OPT_CRYPTODEV_BK_ID_NUM:
393 			if (!env.broken_test_config) {
394 				env.broken_test_config = rte_malloc(
395 					NULL,
396 					sizeof(*env.broken_test_config),
397 					0);
398 				if (!env.broken_test_config)
399 					return -ENOMEM;
400 
401 				env.broken_test_config->expect_fail_dir =
402 					self_test_dir_enc_auth_gen;
403 			}
404 
405 			if (parser_read_uint32(
406 				&env.broken_test_config->expect_fail_test_idx,
407 					optarg) < 0) {
408 				rte_free(env.broken_test_config);
409 				cryptodev_fips_validate_usage(prgname);
410 				return -EINVAL;
411 			}
412 			break;
413 
414 		case OPT_CRYPTODEV_BK_DIR_KEY_NUM:
415 			if (!env.broken_test_config) {
416 				env.broken_test_config = rte_malloc(
417 					NULL,
418 					sizeof(*env.broken_test_config),
419 					0);
420 				if (!env.broken_test_config)
421 					return -ENOMEM;
422 
423 				env.broken_test_config->expect_fail_test_idx =
424 					0;
425 			}
426 
427 			if (strcmp(optarg, "enc") == 0)
428 				env.broken_test_config->expect_fail_dir =
429 					self_test_dir_enc_auth_gen;
430 			else if (strcmp(optarg, "dec")
431 					== 0)
432 				env.broken_test_config->expect_fail_dir =
433 					self_test_dir_dec_auth_verify;
434 			else {
435 				rte_free(env.broken_test_config);
436 				cryptodev_fips_validate_usage(prgname);
437 				return -EINVAL;
438 			}
439 			break;
440 
441 
442 		case OPT_MBUF_DATAROOM_NUM:
443 			if (parser_read_uint16(&env.mbuf_data_room,
444 					optarg) < 0) {
445 				cryptodev_fips_validate_usage(prgname);
446 				return -EINVAL;
447 			}
448 
449 			if (env.mbuf_data_room == 0) {
450 				cryptodev_fips_validate_usage(prgname);
451 				return -EINVAL;
452 			}
453 			break;
454 
455 		case OPT_CRYPTODEV_ASYM_NUM:
456 			env.is_asym_test = true;
457 			break;
458 
459 		default:
460 			cryptodev_fips_validate_usage(prgname);
461 			return -EINVAL;
462 		}
463 	}
464 
465 	if ((env.req_path == NULL && env.rsp_path != NULL) ||
466 			(env.req_path != NULL && env.rsp_path == NULL)) {
467 		RTE_LOG(ERR, USER1, "Missing req path or rsp path\n");
468 		cryptodev_fips_validate_usage(prgname);
469 		return -EINVAL;
470 	}
471 
472 	if (env.req_path == NULL && env.self_test == 0) {
473 		RTE_LOG(ERR, USER1, "--self-test must be set if req path is missing\n");
474 		cryptodev_fips_validate_usage(prgname);
475 		return -EINVAL;
476 	}
477 
478 	return 0;
479 }
480 
481 int
482 main(int argc, char *argv[])
483 {
484 	int ret;
485 
486 	ret = rte_eal_init(argc, argv);
487 	if (ret < 0) {
488 		RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret);
489 		return -1;
490 	}
491 
492 	argc -= ret;
493 	argv += ret;
494 
495 	ret = cryptodev_fips_validate_parse_args(argc, argv);
496 	if (ret < 0)
497 		rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n");
498 
499 	ret = cryptodev_fips_validate_app_init();
500 	if (ret < 0) {
501 		RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret);
502 		return -1;
503 	}
504 
505 	if (env.req_path == NULL || env.rsp_path == NULL) {
506 		printf("No request, exit.\n");
507 		goto exit;
508 	}
509 
510 	if (!env.is_path_folder) {
511 		printf("Processing file %s... ", env.req_path);
512 
513 		ret = fips_test_init(env.req_path, env.rsp_path,
514 			rte_cryptodev_name_get(env.dev_id));
515 		if (ret < 0) {
516 			RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
517 					ret, env.req_path);
518 			goto exit;
519 		}
520 
521 #ifdef USE_JANSSON
522 		if (info.file_type == FIPS_TYPE_JSON) {
523 			ret = fips_test_one_json_file();
524 			json_decref(json_info.json_root);
525 		}  else {
526 			ret = fips_test_one_file();
527 		}
528 #else /* USE_JANSSON */
529 		ret = fips_test_one_file();
530 #endif /* USE_JANSSON */
531 
532 		if (ret < 0) {
533 			RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
534 					ret, env.req_path);
535 			goto exit;
536 		}
537 
538 		printf("Done\n");
539 
540 	} else {
541 		struct dirent *dir;
542 		DIR *d_req, *d_rsp;
543 		char req_path[1024];
544 		char rsp_path[1024];
545 
546 		d_req = opendir(env.req_path);
547 		if (!d_req) {
548 			RTE_LOG(ERR, USER1, "Error %i: Path %s not exist\n",
549 					-EINVAL, env.req_path);
550 			goto exit;
551 		}
552 
553 		d_rsp = opendir(env.rsp_path);
554 		if (!d_rsp) {
555 			ret = mkdir(env.rsp_path, 0700);
556 			if (ret == 0)
557 				d_rsp = opendir(env.rsp_path);
558 			else {
559 				RTE_LOG(ERR, USER1, "Error %i: Invalid %s\n",
560 						-EINVAL, env.rsp_path);
561 				goto exit;
562 			}
563 		}
564 		closedir(d_rsp);
565 
566 		while ((dir = readdir(d_req)) != NULL) {
567 			if (strstr(dir->d_name, "req") == NULL)
568 				continue;
569 
570 			snprintf(req_path, 1023, "%s/%s", env.req_path,
571 					dir->d_name);
572 			snprintf(rsp_path, 1023, "%s/%s", env.rsp_path,
573 					dir->d_name);
574 			strlcpy(strstr(rsp_path, "req"), "rsp", 4);
575 
576 			printf("Processing file %s... ", req_path);
577 
578 			ret = fips_test_init(req_path, rsp_path,
579 			rte_cryptodev_name_get(env.dev_id));
580 			if (ret < 0) {
581 				RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
582 						ret, req_path);
583 				break;
584 			}
585 
586 #ifdef USE_JANSSON
587 			if (info.file_type == FIPS_TYPE_JSON) {
588 				ret = fips_test_one_json_file();
589 				json_decref(json_info.json_root);
590 			} else {
591 				ret = fips_test_one_file();
592 			}
593 #else /* USE_JANSSON */
594 			ret = fips_test_one_file();
595 #endif /* USE_JANSSON */
596 
597 			if (ret < 0) {
598 				RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
599 						ret, req_path);
600 				break;
601 			}
602 
603 			printf("Done\n");
604 		}
605 
606 		closedir(d_req);
607 	}
608 
609 
610 exit:
611 	fips_test_clear();
612 	cryptodev_fips_validate_app_uninit();
613 
614 	/* clean up the EAL */
615 	rte_eal_cleanup();
616 
617 	return ret;
618 
619 }
620 
621 #define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
622 #define CRYPTODEV_FIPS_MAX_RETRIES	16
623 
624 struct fips_test_ops test_ops;
625 
626 static int
627 prepare_data_mbufs(struct fips_val *val)
628 {
629 	struct rte_mbuf *m, *head = 0;
630 	uint8_t *src = val->val;
631 	uint32_t total_len = val->len;
632 	uint16_t nb_seg;
633 	int ret = 0;
634 
635 	rte_pktmbuf_free(env.mbuf);
636 
637 	if (total_len > RTE_MBUF_MAX_NB_SEGS) {
638 		RTE_LOG(ERR, USER1, "Data len %u too big\n", total_len);
639 		return -EPERM;
640 	}
641 
642 	nb_seg = total_len / env.mbuf_data_room;
643 	if (total_len % env.mbuf_data_room)
644 		nb_seg++;
645 
646 	m = rte_pktmbuf_alloc(env.mpool);
647 	if (!m) {
648 		RTE_LOG(ERR, USER1, "Error %i: Not enough mbuf\n",
649 				-ENOMEM);
650 		return -ENOMEM;
651 	}
652 	head = m;
653 
654 	while (nb_seg) {
655 		uint16_t len = RTE_MIN(total_len, env.mbuf_data_room);
656 		uint8_t *dst = (uint8_t *)rte_pktmbuf_append(m, len);
657 
658 		if (!dst) {
659 			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
660 					-ENOMEM);
661 			ret = -ENOMEM;
662 			goto error_exit;
663 		}
664 
665 		memcpy(dst, src, len);
666 
667 		if (head != m) {
668 			ret = rte_pktmbuf_chain(head, m);
669 			if (ret) {
670 				rte_pktmbuf_free(m);
671 				RTE_LOG(ERR, USER1, "Error %i: SGL build\n",
672 						ret);
673 				goto error_exit;
674 			}
675 		}
676 		total_len -= len;
677 
678 		if (total_len) {
679 			if (!env.dev_support_sgl) {
680 				RTE_LOG(ERR, USER1, "SGL not supported\n");
681 				ret = -EPERM;
682 				goto error_exit;
683 			}
684 
685 			m = rte_pktmbuf_alloc(env.mpool);
686 			if (!m) {
687 				RTE_LOG(ERR, USER1, "Error %i: No memory\n",
688 						-ENOMEM);
689 				goto error_exit;
690 			}
691 		} else
692 			break;
693 
694 		src += len;
695 		nb_seg--;
696 	}
697 
698 	if (total_len) {
699 		RTE_LOG(ERR, USER1, "Error %i: Failed to store all data\n",
700 				-ENOMEM);
701 		goto error_exit;
702 	}
703 
704 	env.mbuf = head;
705 
706 	return 0;
707 
708 error_exit:
709 	rte_pktmbuf_free(head);
710 	return ret;
711 }
712 
713 static int
714 prepare_cipher_op(void)
715 {
716 	struct rte_crypto_sym_op *sym = env.op->sym;
717 	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
718 	int ret;
719 
720 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
721 
722 	memcpy(iv, vec.iv.val, vec.iv.len);
723 
724 	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
725 		ret = prepare_data_mbufs(&vec.pt);
726 		if (ret < 0)
727 			return ret;
728 
729 		sym->cipher.data.length = vec.pt.len;
730 	} else {
731 		ret = prepare_data_mbufs(&vec.ct);
732 		if (ret < 0)
733 			return ret;
734 
735 		sym->cipher.data.length = vec.ct.len;
736 	}
737 
738 	rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
739 
740 	sym->m_src = env.mbuf;
741 	sym->cipher.data.offset = 0;
742 
743 	return 0;
744 }
745 
746 int
747 prepare_auth_op(void)
748 {
749 	struct rte_crypto_sym_op *sym = env.op->sym;
750 	int ret;
751 
752 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
753 
754 	if (info.interim_info.gcm_data.gen_iv == 1) {
755 		uint32_t i;
756 
757 		if (!vec.iv.val) {
758 			vec.iv.val = rte_malloc(0, vec.iv.len, 0);
759 			if (!vec.iv.val)
760 				return -ENOMEM;
761 		}
762 
763 		for (i = 0; i < vec.iv.len; i++) {
764 			int random = rand();
765 			vec.iv.val[i] = (uint8_t)random;
766 		}
767 	}
768 
769 	if (vec.iv.len) {
770 		uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *,
771 				IV_OFF);
772 		memset(iv, 0, vec.iv.len);
773 		if (vec.iv.val)
774 			memcpy(iv, vec.iv.val, vec.iv.len);
775 	}
776 
777 	ret = prepare_data_mbufs(&vec.pt);
778 	if (ret < 0)
779 		return ret;
780 
781 	rte_free(env.digest);
782 
783 	env.digest = rte_zmalloc(NULL, vec.cipher_auth.digest.len,
784 			RTE_CACHE_LINE_SIZE);
785 	if (!env.digest) {
786 		RTE_LOG(ERR, USER1, "Not enough memory\n");
787 		return -ENOMEM;
788 	}
789 	env.digest_len = vec.cipher_auth.digest.len;
790 
791 	sym->m_src = env.mbuf;
792 	sym->auth.data.offset = 0;
793 	sym->auth.data.length = vec.pt.len;
794 	sym->auth.digest.data = env.digest;
795 	sym->auth.digest.phys_addr = rte_malloc_virt2iova(env.digest);
796 
797 	if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
798 		memcpy(env.digest, vec.cipher_auth.digest.val,
799 				vec.cipher_auth.digest.len);
800 
801 	rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
802 
803 	return 0;
804 }
805 
806 int
807 prepare_aead_op(void)
808 {
809 	struct rte_crypto_sym_op *sym = env.op->sym;
810 	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
811 	int ret;
812 
813 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
814 
815 	if (info.algo == FIPS_TEST_ALGO_AES_CCM)
816 		iv++;
817 
818 	if (vec.iv.val)
819 		memcpy(iv, vec.iv.val, vec.iv.len);
820 	else
821 		/* if REQ file has iv length but not data, default as all 0 */
822 		memset(iv, 0, vec.iv.len);
823 
824 	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
825 		ret = prepare_data_mbufs(&vec.pt);
826 		if (ret < 0)
827 			return ret;
828 
829 		rte_free(env.digest);
830 		env.digest = rte_zmalloc(NULL, vec.aead.digest.len,
831 				RTE_CACHE_LINE_SIZE);
832 		if (!env.digest) {
833 			RTE_LOG(ERR, USER1, "Not enough memory\n");
834 			return -ENOMEM;
835 		}
836 		env.digest_len = vec.cipher_auth.digest.len;
837 
838 		sym->aead.data.length = vec.pt.len;
839 		sym->aead.digest.data = env.digest;
840 		sym->aead.digest.phys_addr = rte_malloc_virt2iova(env.digest);
841 	} else {
842 		ret = prepare_data_mbufs(&vec.ct);
843 		if (ret < 0)
844 			return ret;
845 
846 		sym->aead.data.length = vec.ct.len;
847 		sym->aead.digest.data = vec.aead.digest.val;
848 		sym->aead.digest.phys_addr = rte_malloc_virt2iova(
849 				sym->aead.digest.data);
850 	}
851 
852 	sym->m_src = env.mbuf;
853 	sym->aead.data.offset = 0;
854 	sym->aead.aad.data = vec.aead.aad.val;
855 	sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data);
856 
857 	rte_crypto_op_attach_sym_session(env.op, env.sym.sess);
858 
859 	return 0;
860 }
861 
862 static int
863 get_hash_oid(enum rte_crypto_auth_algorithm hash, uint8_t *buf)
864 {
865 	uint8_t id_sha512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
866 				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
867 				  0x04, 0x02, 0x03, 0x05, 0x00, 0x04,
868 				  0x40};
869 	uint8_t id_sha384[] = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
870 				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
871 				  0x04, 0x02, 0x02, 0x05, 0x00, 0x04,
872 				  0x30};
873 	uint8_t id_sha256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
874 				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
875 				  0x04, 0x02, 0x01, 0x05, 0x00, 0x04,
876 				  0x20};
877 	uint8_t id_sha224[] = {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
878 				  0x60, 0x86, 0x48, 0x01, 0x65, 0x03,
879 				  0x04, 0x02, 0x04, 0x05, 0x00, 0x04,
880 				  0x1c};
881 	uint8_t id_sha1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
882 				0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05,
883 				0x00, 0x04, 0x14};
884 	uint8_t *id = NULL;
885 	int id_len = 0;
886 
887 	switch (hash) {
888 	case RTE_CRYPTO_AUTH_SHA1:
889 		id = id_sha1;
890 		id_len = sizeof(id_sha1);
891 		break;
892 	case RTE_CRYPTO_AUTH_SHA224:
893 		id = id_sha224;
894 		id_len = sizeof(id_sha224);
895 		break;
896 	case RTE_CRYPTO_AUTH_SHA256:
897 		id = id_sha256;
898 		id_len = sizeof(id_sha256);
899 		break;
900 	case RTE_CRYPTO_AUTH_SHA384:
901 		id = id_sha384;
902 		id_len = sizeof(id_sha384);
903 		break;
904 	case RTE_CRYPTO_AUTH_SHA512:
905 		id = id_sha512;
906 		id_len = sizeof(id_sha512);
907 		break;
908 	default:
909 		id_len = -1;
910 		break;
911 	}
912 
913 	if (id != NULL)
914 		rte_memcpy(buf, id, id_len);
915 
916 	return id_len;
917 }
918 
919 static int
920 prepare_rsa_op(void)
921 {
922 	struct rte_crypto_asym_op *asym;
923 	struct fips_val msg;
924 
925 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
926 
927 	asym = env.op->asym;
928 	asym->rsa.padding.type = info.interim_info.rsa_data.padding;
929 	asym->rsa.padding.hash = info.interim_info.rsa_data.auth;
930 
931 	if (env.digest) {
932 		if (asym->rsa.padding.type == RTE_CRYPTO_RSA_PADDING_PKCS1_5) {
933 			int b_len = 0;
934 			uint8_t b[32];
935 
936 			b_len = get_hash_oid(asym->rsa.padding.hash, b);
937 			if (b_len < 0) {
938 				RTE_LOG(ERR, USER1, "Failed to get digest info for hash %d\n",
939 					asym->rsa.padding.hash);
940 				return -EINVAL;
941 			}
942 
943 			if (b_len) {
944 				msg.len = env.digest_len + b_len;
945 				msg.val = rte_zmalloc(NULL, msg.len, 0);
946 				rte_memcpy(msg.val, b, b_len);
947 				rte_memcpy(msg.val + b_len, env.digest, env.digest_len);
948 				rte_free(env.digest);
949 				env.digest = msg.val;
950 				env.digest_len = msg.len;
951 			}
952 		}
953 		msg.val = env.digest;
954 		msg.len = env.digest_len;
955 	} else {
956 		msg.val = vec.pt.val;
957 		msg.len = vec.pt.len;
958 	}
959 
960 	if (info.op == FIPS_TEST_ASYM_SIGGEN) {
961 		asym->rsa.op_type = RTE_CRYPTO_ASYM_OP_SIGN;
962 		asym->rsa.message.data = msg.val;
963 		asym->rsa.message.length = msg.len;
964 
965 		if (vec.rsa.signature.val)
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_aes_xform(struct rte_crypto_sym_xform *xform)
990 {
991 	const struct rte_cryptodev_symmetric_capability *cap;
992 	struct rte_cryptodev_sym_capability_idx cap_idx;
993 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
994 
995 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
996 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC)
997 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC;
998 	else if (info.interim_info.aes_data.cipher_algo ==
999 			RTE_CRYPTO_CIPHER_AES_CTR)
1000 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CTR;
1001 	else
1002 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB;
1003 
1004 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1005 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1006 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1007 	cipher_xform->key.data = vec.cipher_auth.key.val;
1008 	cipher_xform->key.length = vec.cipher_auth.key.len;
1009 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC ||
1010 			cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CTR) {
1011 		cipher_xform->iv.length = vec.iv.len;
1012 		cipher_xform->iv.offset = IV_OFF;
1013 	} else {
1014 		cipher_xform->iv.length = 0;
1015 		cipher_xform->iv.offset = 0;
1016 	}
1017 	cap_idx.algo.cipher = cipher_xform->algo;
1018 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1019 
1020 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1021 	if (!cap) {
1022 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1023 				env.dev_id);
1024 		return -EINVAL;
1025 	}
1026 
1027 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1028 			cipher_xform->key.length,
1029 			cipher_xform->iv.length) != 0) {
1030 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1031 				info.device_name, cipher_xform->key.length,
1032 				cipher_xform->iv.length);
1033 		return -EPERM;
1034 	}
1035 
1036 	return 0;
1037 }
1038 
1039 static int
1040 prepare_tdes_xform(struct rte_crypto_sym_xform *xform)
1041 {
1042 	const struct rte_cryptodev_symmetric_capability *cap;
1043 	struct rte_cryptodev_sym_capability_idx cap_idx;
1044 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1045 
1046 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1047 
1048 	if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC)
1049 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC;
1050 	else
1051 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB;
1052 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1053 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1054 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1055 	cipher_xform->key.data = vec.cipher_auth.key.val;
1056 	cipher_xform->key.length = vec.cipher_auth.key.len;
1057 
1058 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
1059 		cipher_xform->iv.length = vec.iv.len;
1060 		cipher_xform->iv.offset = IV_OFF;
1061 	} else {
1062 		cipher_xform->iv.length = 0;
1063 		cipher_xform->iv.offset = 0;
1064 	}
1065 	cap_idx.algo.cipher = cipher_xform->algo;
1066 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1067 
1068 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1069 	if (!cap) {
1070 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1071 				env.dev_id);
1072 		return -EINVAL;
1073 	}
1074 
1075 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1076 			cipher_xform->key.length,
1077 			cipher_xform->iv.length) != 0) {
1078 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1079 				info.device_name, cipher_xform->key.length,
1080 				cipher_xform->iv.length);
1081 		return -EPERM;
1082 	}
1083 
1084 	return 0;
1085 }
1086 
1087 static int
1088 prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
1089 {
1090 	const struct rte_cryptodev_symmetric_capability *cap;
1091 	struct rte_cryptodev_sym_capability_idx cap_idx;
1092 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1093 
1094 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1095 
1096 	auth_xform->algo = info.interim_info.hmac_data.algo;
1097 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
1098 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1099 	auth_xform->key.data = vec.cipher_auth.key.val;
1100 	auth_xform->key.length = vec.cipher_auth.key.len;
1101 
1102 	cap_idx.algo.auth = auth_xform->algo;
1103 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1104 
1105 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1106 	if (!cap) {
1107 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1108 				env.dev_id);
1109 		return -EINVAL;
1110 	}
1111 
1112 	if (rte_cryptodev_sym_capability_check_auth(cap,
1113 			auth_xform->key.length,
1114 			auth_xform->digest_length, 0) != 0) {
1115 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1116 				info.device_name, auth_xform->key.length,
1117 				auth_xform->digest_length);
1118 		return -EPERM;
1119 	}
1120 
1121 	return 0;
1122 }
1123 
1124 int
1125 prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
1126 {
1127 	const struct rte_cryptodev_symmetric_capability *cap;
1128 	struct rte_cryptodev_sym_capability_idx cap_idx;
1129 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
1130 
1131 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
1132 
1133 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
1134 	aead_xform->aad_length = vec.aead.aad.len;
1135 	aead_xform->digest_length = vec.aead.digest.len;
1136 	aead_xform->iv.offset = IV_OFF;
1137 	aead_xform->iv.length = vec.iv.len;
1138 	aead_xform->key.data = vec.aead.key.val;
1139 	aead_xform->key.length = vec.aead.key.len;
1140 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1141 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
1142 			RTE_CRYPTO_AEAD_OP_DECRYPT;
1143 
1144 	cap_idx.algo.aead = aead_xform->algo;
1145 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
1146 
1147 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1148 	if (!cap) {
1149 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1150 				env.dev_id);
1151 		return -EINVAL;
1152 	}
1153 
1154 	if (rte_cryptodev_sym_capability_check_aead(cap,
1155 			aead_xform->key.length,
1156 			aead_xform->digest_length, aead_xform->aad_length,
1157 			aead_xform->iv.length) != 0) {
1158 		RTE_LOG(ERR, USER1,
1159 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
1160 				info.device_name, aead_xform->key.length,
1161 				aead_xform->digest_length,
1162 				aead_xform->aad_length,
1163 				aead_xform->iv.length);
1164 		return -EPERM;
1165 	}
1166 
1167 	return 0;
1168 }
1169 
1170 int
1171 prepare_gmac_xform(struct rte_crypto_sym_xform *xform)
1172 {
1173 	const struct rte_cryptodev_symmetric_capability *cap;
1174 	struct rte_cryptodev_sym_capability_idx cap_idx;
1175 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1176 
1177 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1178 
1179 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC;
1180 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1181 			RTE_CRYPTO_AUTH_OP_GENERATE :
1182 			RTE_CRYPTO_AUTH_OP_VERIFY;
1183 	auth_xform->iv.offset = IV_OFF;
1184 	auth_xform->iv.length = vec.iv.len;
1185 	auth_xform->digest_length = vec.aead.digest.len;
1186 	auth_xform->key.data = vec.aead.key.val;
1187 	auth_xform->key.length = vec.aead.key.len;
1188 
1189 	cap_idx.algo.auth = auth_xform->algo;
1190 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1191 
1192 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1193 	if (!cap) {
1194 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1195 				env.dev_id);
1196 		return -EINVAL;
1197 	}
1198 
1199 	if (rte_cryptodev_sym_capability_check_auth(cap,
1200 			auth_xform->key.length,
1201 			auth_xform->digest_length,
1202 			auth_xform->iv.length) != 0) {
1203 
1204 		RTE_LOG(ERR, USER1,
1205 			"PMD %s key length %u Digest length %u IV length %u\n",
1206 				info.device_name, auth_xform->key.length,
1207 				auth_xform->digest_length,
1208 				auth_xform->iv.length);
1209 		return -EPERM;
1210 	}
1211 
1212 	return 0;
1213 }
1214 
1215 static int
1216 prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
1217 {
1218 	const struct rte_cryptodev_symmetric_capability *cap;
1219 	struct rte_cryptodev_sym_capability_idx cap_idx;
1220 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1221 
1222 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1223 
1224 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC;
1225 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1226 			RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY;
1227 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1228 	auth_xform->key.data = vec.cipher_auth.key.val;
1229 	auth_xform->key.length = vec.cipher_auth.key.len;
1230 
1231 	cap_idx.algo.auth = auth_xform->algo;
1232 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1233 
1234 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1235 	if (!cap) {
1236 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1237 				env.dev_id);
1238 		return -EINVAL;
1239 	}
1240 
1241 	if (rte_cryptodev_sym_capability_check_auth(cap,
1242 			auth_xform->key.length,
1243 			auth_xform->digest_length, 0) != 0) {
1244 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1245 				info.device_name, auth_xform->key.length,
1246 				auth_xform->digest_length);
1247 		return -EPERM;
1248 	}
1249 
1250 	return 0;
1251 }
1252 
1253 static int
1254 prepare_ccm_xform(struct rte_crypto_sym_xform *xform)
1255 {
1256 	const struct rte_cryptodev_symmetric_capability *cap;
1257 	struct rte_cryptodev_sym_capability_idx cap_idx;
1258 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
1259 
1260 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
1261 
1262 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM;
1263 	aead_xform->aad_length = vec.aead.aad.len;
1264 	aead_xform->digest_length = vec.aead.digest.len;
1265 	aead_xform->iv.offset = IV_OFF;
1266 	aead_xform->iv.length = vec.iv.len;
1267 	aead_xform->key.data = vec.aead.key.val;
1268 	aead_xform->key.length = vec.aead.key.len;
1269 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1270 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
1271 			RTE_CRYPTO_AEAD_OP_DECRYPT;
1272 
1273 	cap_idx.algo.aead = aead_xform->algo;
1274 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
1275 
1276 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1277 	if (!cap) {
1278 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1279 				env.dev_id);
1280 		return -EINVAL;
1281 	}
1282 
1283 	if (rte_cryptodev_sym_capability_check_aead(cap,
1284 			aead_xform->key.length,
1285 			aead_xform->digest_length, aead_xform->aad_length,
1286 			aead_xform->iv.length) != 0) {
1287 		RTE_LOG(ERR, USER1,
1288 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
1289 				info.device_name, aead_xform->key.length,
1290 				aead_xform->digest_length,
1291 				aead_xform->aad_length,
1292 				aead_xform->iv.length);
1293 		return -EPERM;
1294 	}
1295 
1296 	return 0;
1297 }
1298 
1299 static int
1300 prepare_sha_xform(struct rte_crypto_sym_xform *xform)
1301 {
1302 	const struct rte_cryptodev_symmetric_capability *cap;
1303 	struct rte_cryptodev_sym_capability_idx cap_idx;
1304 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1305 
1306 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1307 
1308 	auth_xform->algo = info.interim_info.sha_data.algo;
1309 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
1310 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1311 
1312 	cap_idx.algo.auth = auth_xform->algo;
1313 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1314 
1315 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1316 	if (!cap) {
1317 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1318 				env.dev_id);
1319 		return -EINVAL;
1320 	}
1321 
1322 	if (rte_cryptodev_sym_capability_check_auth(cap,
1323 			auth_xform->key.length,
1324 			auth_xform->digest_length, 0) != 0) {
1325 		RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n",
1326 				info.device_name, auth_xform->key.length,
1327 				auth_xform->digest_length);
1328 		return -EPERM;
1329 	}
1330 
1331 	return 0;
1332 }
1333 
1334 static int
1335 prepare_xts_xform(struct rte_crypto_sym_xform *xform)
1336 {
1337 	const struct rte_cryptodev_symmetric_capability *cap;
1338 	struct rte_cryptodev_sym_capability_idx cap_idx;
1339 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1340 
1341 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1342 
1343 	cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS;
1344 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1345 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1346 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1347 	cipher_xform->key.data = vec.cipher_auth.key.val;
1348 	cipher_xform->key.length = vec.cipher_auth.key.len;
1349 	cipher_xform->iv.length = vec.iv.len;
1350 	cipher_xform->iv.offset = IV_OFF;
1351 
1352 	cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS;
1353 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1354 
1355 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1356 	if (!cap) {
1357 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1358 				env.dev_id);
1359 		return -EINVAL;
1360 	}
1361 
1362 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1363 			cipher_xform->key.length,
1364 			cipher_xform->iv.length) != 0) {
1365 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1366 				info.device_name, cipher_xform->key.length,
1367 				cipher_xform->iv.length);
1368 		return -EPERM;
1369 	}
1370 
1371 	return 0;
1372 }
1373 
1374 static int
1375 prepare_rsa_xform(struct rte_crypto_asym_xform *xform)
1376 {
1377 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1378 	struct rte_cryptodev_asym_capability_idx cap_idx;
1379 	struct rte_cryptodev_info dev_info;
1380 
1381 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_RSA;
1382 	xform->next = NULL;
1383 
1384 	cap_idx.type = xform->xform_type;
1385 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1386 	if (!cap) {
1387 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1388 				env.dev_id);
1389 		return -EINVAL;
1390 	}
1391 
1392 	switch (info.op) {
1393 	case FIPS_TEST_ASYM_SIGGEN:
1394 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1395 			RTE_CRYPTO_ASYM_OP_SIGN)) {
1396 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1397 				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
1398 			return -EPERM;
1399 		}
1400 		break;
1401 	case FIPS_TEST_ASYM_SIGVER:
1402 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1403 			RTE_CRYPTO_ASYM_OP_VERIFY)) {
1404 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1405 				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
1406 			return -EPERM;
1407 		}
1408 		break;
1409 	case FIPS_TEST_ASYM_KEYGEN:
1410 		break;
1411 	default:
1412 		break;
1413 	}
1414 
1415 	rte_cryptodev_info_get(env.dev_id, &dev_info);
1416 	xform->rsa.key_type = info.interim_info.rsa_data.privkey;
1417 	switch (xform->rsa.key_type) {
1418 	case RTE_RSA_KEY_TYPE_QT:
1419 		if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT)) {
1420 			RTE_LOG(ERR, USER1, "PMD %s does not support QT key type\n",
1421 				info.device_name);
1422 			return -EPERM;
1423 		}
1424 		xform->rsa.qt.p.data = vec.rsa.p.val;
1425 		xform->rsa.qt.p.length = vec.rsa.p.len;
1426 		xform->rsa.qt.q.data = vec.rsa.q.val;
1427 		xform->rsa.qt.q.length = vec.rsa.q.len;
1428 		xform->rsa.qt.dP.data = vec.rsa.dp.val;
1429 		xform->rsa.qt.dP.length = vec.rsa.dp.len;
1430 		xform->rsa.qt.dQ.data = vec.rsa.dq.val;
1431 		xform->rsa.qt.dQ.length = vec.rsa.dq.len;
1432 		xform->rsa.qt.qInv.data = vec.rsa.qinv.val;
1433 		xform->rsa.qt.qInv.length = vec.rsa.qinv.len;
1434 		break;
1435 	case RTE_RSA_KEY_TYPE_EXP:
1436 		if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP)) {
1437 			RTE_LOG(ERR, USER1, "PMD %s does not support EXP key type\n",
1438 				info.device_name);
1439 			return -EPERM;
1440 		}
1441 		xform->rsa.d.data = vec.rsa.d.val;
1442 		xform->rsa.d.length = vec.rsa.d.len;
1443 		break;
1444 	default:
1445 		break;
1446 	}
1447 
1448 	xform->rsa.e.data = vec.rsa.e.val;
1449 	xform->rsa.e.length = vec.rsa.e.len;
1450 	xform->rsa.n.data = vec.rsa.n.val;
1451 	xform->rsa.n.length = vec.rsa.n.len;
1452 	return 0;
1453 }
1454 
1455 static int
1456 get_writeback_data(struct fips_val *val)
1457 {
1458 	struct rte_mbuf *m = env.mbuf;
1459 	uint16_t data_len = rte_pktmbuf_pkt_len(m);
1460 	uint16_t total_len = data_len + env.digest_len;
1461 	uint8_t *src, *dst, *wb_data;
1462 
1463 	/* in case val is reused for MCT test, try to free the buffer first */
1464 	if (val->val) {
1465 		free(val->val);
1466 		val->val = NULL;
1467 	}
1468 
1469 	wb_data = dst = calloc(1, total_len);
1470 	if (!dst) {
1471 		RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM);
1472 		return -ENOMEM;
1473 	}
1474 
1475 	while (m && data_len) {
1476 		uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len);
1477 
1478 		src = rte_pktmbuf_mtod(m, uint8_t *);
1479 		memcpy(dst, src, seg_len);
1480 		m = m->next;
1481 		data_len -= seg_len;
1482 		dst += seg_len;
1483 	}
1484 
1485 	if (data_len) {
1486 		RTE_LOG(ERR, USER1, "Error -1: write back data\n");
1487 		free(wb_data);
1488 		return -1;
1489 	}
1490 
1491 	if (env.digest)
1492 		memcpy(dst, env.digest, env.digest_len);
1493 
1494 	val->val = wb_data;
1495 	val->len = total_len;
1496 
1497 	return 0;
1498 }
1499 
1500 static int
1501 fips_run_sym_test(void)
1502 {
1503 	struct rte_crypto_sym_xform xform = {0};
1504 	uint16_t n_deqd;
1505 	int ret;
1506 
1507 	if (!test_ops.prepare_sym_xform || !test_ops.prepare_sym_op)
1508 		return -EINVAL;
1509 
1510 	ret = test_ops.prepare_sym_xform(&xform);
1511 	if (ret < 0)
1512 		return ret;
1513 
1514 	env.sym.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform,
1515 						env.sym.sess_mpool);
1516 	if (!env.sym.sess)
1517 		return -ENOMEM;
1518 
1519 	ret = test_ops.prepare_sym_op();
1520 	if (ret < 0) {
1521 		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n",
1522 				ret);
1523 		goto exit;
1524 	}
1525 
1526 	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
1527 		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
1528 		ret = -1;
1529 		goto exit;
1530 	}
1531 
1532 	do {
1533 		struct rte_crypto_op *deqd_op;
1534 
1535 		n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1);
1536 	} while (n_deqd == 0);
1537 
1538 	vec.status = env.op->status;
1539 
1540 exit:
1541 	rte_cryptodev_sym_session_free(env.dev_id, env.sym.sess);
1542 	env.sym.sess = NULL;
1543 	return ret;
1544 }
1545 
1546 static int
1547 fips_run_asym_test(void)
1548 {
1549 	struct rte_crypto_asym_xform xform = {0};
1550 	struct rte_crypto_asym_op *asym;
1551 	struct rte_crypto_op *deqd_op;
1552 	int ret;
1553 
1554 	if (info.op == FIPS_TEST_ASYM_KEYGEN) {
1555 		RTE_SET_USED(asym);
1556 		ret = 0;
1557 		goto exit;
1558 	}
1559 
1560 	if (!test_ops.prepare_asym_xform || !test_ops.prepare_asym_op)
1561 		return -EINVAL;
1562 
1563 	asym = env.op->asym;
1564 	ret = test_ops.prepare_asym_xform(&xform);
1565 	if (ret < 0)
1566 		return ret;
1567 
1568 	ret = rte_cryptodev_asym_session_create(env.dev_id, &xform, env.asym.sess_mpool,
1569 			(void *)&env.asym.sess);
1570 	if (ret < 0)
1571 		return ret;
1572 
1573 	ret = test_ops.prepare_asym_op();
1574 	if (ret < 0) {
1575 		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", ret);
1576 		goto exit;
1577 	}
1578 
1579 	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
1580 		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
1581 		ret = -1;
1582 		goto exit;
1583 	}
1584 
1585 	while (rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1) == 0)
1586 		rte_pause();
1587 
1588 	vec.status = env.op->status;
1589 
1590  exit:
1591 	if (env.asym.sess)
1592 		rte_cryptodev_asym_session_free(env.dev_id, env.asym.sess);
1593 
1594 	env.asym.sess = NULL;
1595 	return ret;
1596 }
1597 
1598 static int
1599 fips_run_test(void)
1600 {
1601 	int ret;
1602 
1603 	env.op = env.sym.op;
1604 	if (env.is_asym_test) {
1605 		vec.cipher_auth.digest.len = parse_test_sha_hash_size(
1606 						info.interim_info.rsa_data.auth);
1607 		test_ops.prepare_sym_xform = prepare_sha_xform;
1608 		test_ops.prepare_sym_op = prepare_auth_op;
1609 		ret = fips_run_sym_test();
1610 		if (ret < 0)
1611 			return ret;
1612 	} else {
1613 		return fips_run_sym_test();
1614 	}
1615 
1616 	env.op = env.asym.op;
1617 	return fips_run_asym_test();
1618 }
1619 
1620 static int
1621 fips_generic_test(void)
1622 {
1623 	struct fips_val val = {NULL, 0};
1624 	int ret;
1625 
1626 	if (info.file_type != FIPS_TYPE_JSON)
1627 		fips_test_write_one_case();
1628 
1629 	ret = fips_run_test();
1630 	if (ret < 0) {
1631 		if (ret == -EPERM || ret == -ENOTSUP) {
1632 			if (info.file_type == FIPS_TYPE_JSON)
1633 				return ret;
1634 
1635 			fprintf(info.fp_wr, "Bypass\n\n");
1636 			return 0;
1637 		}
1638 
1639 		return ret;
1640 	}
1641 
1642 	if (!env.is_asym_test) {
1643 		ret = get_writeback_data(&val);
1644 		if (ret < 0)
1645 			return ret;
1646 	}
1647 
1648 	switch (info.file_type) {
1649 	case FIPS_TYPE_REQ:
1650 	case FIPS_TYPE_RSP:
1651 	case FIPS_TYPE_JSON:
1652 		if (info.parse_writeback == NULL)
1653 			return -EPERM;
1654 		ret = info.parse_writeback(&val);
1655 		if (ret < 0)
1656 			return ret;
1657 		break;
1658 	case FIPS_TYPE_FAX:
1659 		if (info.kat_check == NULL)
1660 			return -EPERM;
1661 		ret = info.kat_check(&val);
1662 		if (ret < 0)
1663 			return ret;
1664 		break;
1665 	default:
1666 		break;
1667 	}
1668 
1669 	if (info.file_type != FIPS_TYPE_JSON)
1670 		fprintf(info.fp_wr, "\n");
1671 	free(val.val);
1672 
1673 	return 0;
1674 }
1675 
1676 static int
1677 fips_mct_tdes_test(void)
1678 {
1679 #define TDES_BLOCK_SIZE		8
1680 #define TDES_EXTERN_ITER	400
1681 #define TDES_INTERN_ITER	10000
1682 	struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv;
1683 	uint8_t prev_out[TDES_BLOCK_SIZE] = {0};
1684 	uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0};
1685 	uint8_t prev_in[TDES_BLOCK_SIZE] = {0};
1686 	uint32_t i, j, k;
1687 	int ret;
1688 	int test_mode = info.interim_info.tdes_data.test_mode;
1689 
1690 	pt.len = vec.pt.len;
1691 	pt.val = calloc(1, pt.len);
1692 	ct.len = vec.ct.len;
1693 	ct.val = calloc(1, ct.len);
1694 	iv.len = vec.iv.len;
1695 	iv.val = calloc(1, iv.len);
1696 
1697 	for (i = 0; i < TDES_EXTERN_ITER; i++) {
1698 		if (info.file_type != FIPS_TYPE_JSON) {
1699 			if ((i == 0) && (info.version == 21.4f)) {
1700 				if (!(strstr(info.vec[0], "COUNT")))
1701 					fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0);
1702 			}
1703 
1704 			if (i != 0)
1705 				update_info_vec(i);
1706 
1707 			fips_test_write_one_case();
1708 		}
1709 
1710 		for (j = 0; j < TDES_INTERN_ITER; j++) {
1711 			ret = fips_run_test();
1712 			if (ret < 0) {
1713 				if (ret == -EPERM) {
1714 					if (info.file_type == FIPS_TYPE_JSON)
1715 						return ret;
1716 
1717 					fprintf(info.fp_wr, "Bypass\n");
1718 					return 0;
1719 				}
1720 				return ret;
1721 			}
1722 
1723 			ret = get_writeback_data(&val[0]);
1724 			if (ret < 0)
1725 				return ret;
1726 
1727 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
1728 				memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE);
1729 
1730 			if (j == 0) {
1731 				memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
1732 				memcpy(pt.val, vec.pt.val, pt.len);
1733 				memcpy(ct.val, vec.ct.val, ct.len);
1734 				memcpy(iv.val, vec.iv.val, iv.len);
1735 
1736 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1737 					if (test_mode == TDES_MODE_ECB) {
1738 						memcpy(vec.pt.val, val[0].val,
1739 							   TDES_BLOCK_SIZE);
1740 					} else {
1741 						memcpy(vec.pt.val, vec.iv.val,
1742 							   TDES_BLOCK_SIZE);
1743 						memcpy(vec.iv.val, val[0].val,
1744 							   TDES_BLOCK_SIZE);
1745 					}
1746 					val[1].val = pt.val;
1747 					val[1].len = pt.len;
1748 					val[2].val = iv.val;
1749 					val[2].len = iv.len;
1750 				} else {
1751 					if (test_mode == TDES_MODE_ECB) {
1752 						memcpy(vec.ct.val, val[0].val,
1753 							   TDES_BLOCK_SIZE);
1754 					} else {
1755 						memcpy(vec.iv.val, vec.ct.val,
1756 							   TDES_BLOCK_SIZE);
1757 						memcpy(vec.ct.val, val[0].val,
1758 							   TDES_BLOCK_SIZE);
1759 					}
1760 					val[1].val = ct.val;
1761 					val[1].len = ct.len;
1762 					val[2].val = iv.val;
1763 					val[2].len = iv.len;
1764 				}
1765 				continue;
1766 			}
1767 
1768 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1769 				if (test_mode == TDES_MODE_ECB) {
1770 					memcpy(vec.pt.val, val[0].val,
1771 						   TDES_BLOCK_SIZE);
1772 				} else {
1773 					memcpy(vec.iv.val, val[0].val,
1774 						   TDES_BLOCK_SIZE);
1775 					memcpy(vec.pt.val, prev_out,
1776 						   TDES_BLOCK_SIZE);
1777 				}
1778 			} else {
1779 				if (test_mode == TDES_MODE_ECB) {
1780 					memcpy(vec.ct.val, val[0].val,
1781 						   TDES_BLOCK_SIZE);
1782 				} else {
1783 					memcpy(vec.iv.val, vec.ct.val,
1784 						   TDES_BLOCK_SIZE);
1785 					memcpy(vec.ct.val, val[0].val,
1786 						   TDES_BLOCK_SIZE);
1787 				}
1788 			}
1789 
1790 			if (j == TDES_INTERN_ITER - 1)
1791 				continue;
1792 
1793 			memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
1794 
1795 			if (j == TDES_INTERN_ITER - 3)
1796 				memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE);
1797 		}
1798 
1799 		info.parse_writeback(val);
1800 		if (info.file_type != FIPS_TYPE_JSON)
1801 			fprintf(info.fp_wr, "\n");
1802 
1803 		if (i == TDES_EXTERN_ITER - 1)
1804 			continue;
1805 
1806 		/** update key */
1807 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
1808 
1809 		if (info.interim_info.tdes_data.nb_keys == 0) {
1810 			if (memcmp(val_key.val, val_key.val + 8, 8) == 0)
1811 				info.interim_info.tdes_data.nb_keys = 1;
1812 			else if (memcmp(val_key.val, val_key.val + 16, 8) == 0)
1813 				info.interim_info.tdes_data.nb_keys = 2;
1814 			else
1815 				info.interim_info.tdes_data.nb_keys = 3;
1816 
1817 		}
1818 
1819 		for (k = 0; k < TDES_BLOCK_SIZE; k++) {
1820 
1821 			switch (info.interim_info.tdes_data.nb_keys) {
1822 			case 3:
1823 				val_key.val[k] ^= val[0].val[k];
1824 				val_key.val[k + 8] ^= prev_out[k];
1825 				val_key.val[k + 16] ^= prev_prev_out[k];
1826 				break;
1827 			case 2:
1828 				val_key.val[k] ^= val[0].val[k];
1829 				val_key.val[k + 8] ^= prev_out[k];
1830 				val_key.val[k + 16] ^= val[0].val[k];
1831 				break;
1832 			default: /* case 1 */
1833 				val_key.val[k] ^= val[0].val[k];
1834 				val_key.val[k + 8] ^= val[0].val[k];
1835 				val_key.val[k + 16] ^= val[0].val[k];
1836 				break;
1837 			}
1838 
1839 		}
1840 
1841 		for (k = 0; k < 24; k++)
1842 			val_key.val[k] = (__builtin_popcount(val_key.val[k]) &
1843 					0x1) ?
1844 					val_key.val[k] : (val_key.val[k] ^ 0x1);
1845 
1846 		if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1847 			if (test_mode == TDES_MODE_ECB) {
1848 				memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE);
1849 			} else {
1850 				memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE);
1851 				memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
1852 			}
1853 		} else {
1854 			if (test_mode == TDES_MODE_ECB) {
1855 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
1856 			} else {
1857 				memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE);
1858 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
1859 			}
1860 		}
1861 	}
1862 
1863 	free(val[0].val);
1864 	free(pt.val);
1865 	free(ct.val);
1866 	free(iv.val);
1867 
1868 	return 0;
1869 }
1870 
1871 static int
1872 fips_mct_aes_ecb_test(void)
1873 {
1874 #define AES_BLOCK_SIZE	16
1875 #define AES_EXTERN_ITER	100
1876 #define AES_INTERN_ITER	1000
1877 	struct fips_val val = {NULL, 0}, val_key;
1878 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
1879 	uint32_t i, j, k;
1880 	int ret;
1881 
1882 	for (i = 0; i < AES_EXTERN_ITER; i++) {
1883 		if (i != 0)
1884 			update_info_vec(i);
1885 
1886 		fips_test_write_one_case();
1887 
1888 		for (j = 0; j < AES_INTERN_ITER; j++) {
1889 			ret = fips_run_test();
1890 			if (ret < 0) {
1891 				if (ret == -EPERM) {
1892 					if (info.file_type == FIPS_TYPE_JSON)
1893 						return ret;
1894 
1895 					fprintf(info.fp_wr, "Bypass\n");
1896 					return 0;
1897 				}
1898 
1899 				return ret;
1900 			}
1901 
1902 			ret = get_writeback_data(&val);
1903 			if (ret < 0)
1904 				return ret;
1905 
1906 			if (info.op == FIPS_TEST_ENC_AUTH_GEN)
1907 				memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE);
1908 			else
1909 				memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE);
1910 
1911 			if (j == AES_INTERN_ITER - 1)
1912 				continue;
1913 
1914 			memcpy(prev_out, val.val, AES_BLOCK_SIZE);
1915 		}
1916 
1917 		info.parse_writeback(&val);
1918 		fprintf(info.fp_wr, "\n");
1919 
1920 		if (i == AES_EXTERN_ITER - 1)
1921 			continue;
1922 
1923 		/** update key */
1924 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
1925 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
1926 			switch (vec.cipher_auth.key.len) {
1927 			case 16:
1928 				val_key.val[k] ^= val.val[k];
1929 				break;
1930 			case 24:
1931 				if (k < 8)
1932 					val_key.val[k] ^= prev_out[k + 8];
1933 				else
1934 					val_key.val[k] ^= val.val[k - 8];
1935 				break;
1936 			case 32:
1937 				if (k < 16)
1938 					val_key.val[k] ^= prev_out[k];
1939 				else
1940 					val_key.val[k] ^= val.val[k - 16];
1941 				break;
1942 			default:
1943 				return -1;
1944 			}
1945 		}
1946 	}
1947 
1948 	free(val.val);
1949 
1950 	return 0;
1951 }
1952 static int
1953 fips_mct_aes_test(void)
1954 {
1955 #define AES_BLOCK_SIZE	16
1956 #define AES_EXTERN_ITER	100
1957 #define AES_INTERN_ITER	1000
1958 	struct fips_val val[3] = {{NULL, 0},}, val_key,  pt, ct, iv;
1959 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
1960 	uint8_t prev_in[AES_BLOCK_SIZE] = {0};
1961 	uint32_t i, j, k;
1962 	int ret;
1963 
1964 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB)
1965 		return fips_mct_aes_ecb_test();
1966 
1967 	pt.len = vec.pt.len;
1968 	pt.val = calloc(1, pt.len);
1969 	ct.len = vec.ct.len;
1970 	ct.val = calloc(1, ct.len);
1971 	iv.len = vec.iv.len;
1972 	iv.val = calloc(1, iv.len);
1973 	for (i = 0; i < AES_EXTERN_ITER; i++) {
1974 		if (info.file_type != FIPS_TYPE_JSON) {
1975 			if (i != 0)
1976 				update_info_vec(i);
1977 
1978 			fips_test_write_one_case();
1979 		}
1980 
1981 		for (j = 0; j < AES_INTERN_ITER; j++) {
1982 			ret = fips_run_test();
1983 			if (ret < 0) {
1984 				if (ret == -EPERM) {
1985 					if (info.file_type == FIPS_TYPE_JSON)
1986 						return ret;
1987 
1988 					fprintf(info.fp_wr, "Bypass\n");
1989 					return 0;
1990 				}
1991 
1992 				return ret;
1993 			}
1994 
1995 			ret = get_writeback_data(&val[0]);
1996 			if (ret < 0)
1997 				return ret;
1998 
1999 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2000 				memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE);
2001 
2002 			if (j == 0) {
2003 				memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
2004 				memcpy(pt.val, vec.pt.val, pt.len);
2005 				memcpy(ct.val, vec.ct.val, ct.len);
2006 				memcpy(iv.val, vec.iv.val, iv.len);
2007 
2008 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2009 					memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE);
2010 					memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2011 					val[1].val = pt.val;
2012 					val[1].len = pt.len;
2013 					val[2].val = iv.val;
2014 					val[2].len = iv.len;
2015 				} else {
2016 					memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE);
2017 					memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
2018 					val[1].val = ct.val;
2019 					val[1].len = ct.len;
2020 					val[2].val = iv.val;
2021 					val[2].len = iv.len;
2022 				}
2023 				continue;
2024 			}
2025 
2026 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2027 				memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2028 				memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE);
2029 			} else {
2030 				memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
2031 				memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE);
2032 			}
2033 
2034 			if (j == AES_INTERN_ITER - 1)
2035 				continue;
2036 
2037 			memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
2038 		}
2039 
2040 		info.parse_writeback(val);
2041 		if (info.file_type != FIPS_TYPE_JSON)
2042 			fprintf(info.fp_wr, "\n");
2043 
2044 		if (i == AES_EXTERN_ITER - 1)
2045 			continue;
2046 
2047 		/** update key */
2048 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2049 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
2050 			switch (vec.cipher_auth.key.len) {
2051 			case 16:
2052 				val_key.val[k] ^= val[0].val[k];
2053 				break;
2054 			case 24:
2055 				if (k < 8)
2056 					val_key.val[k] ^= prev_out[k + 8];
2057 				else
2058 					val_key.val[k] ^= val[0].val[k - 8];
2059 				break;
2060 			case 32:
2061 				if (k < 16)
2062 					val_key.val[k] ^= prev_out[k];
2063 				else
2064 					val_key.val[k] ^= val[0].val[k - 16];
2065 				break;
2066 			default:
2067 				return -1;
2068 			}
2069 		}
2070 
2071 		if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2072 			memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2073 	}
2074 
2075 	free(val[0].val);
2076 	free(pt.val);
2077 	free(ct.val);
2078 	free(iv.val);
2079 
2080 	return 0;
2081 }
2082 
2083 static int
2084 fips_mct_sha_test(void)
2085 {
2086 #define SHA_EXTERN_ITER	100
2087 #define SHA_INTERN_ITER	1000
2088 #define SHA_MD_BLOCK	3
2089 	/* val[0] is op result and other value is for parse_writeback callback */
2090 	struct fips_val val[2] = {{NULL, 0},};
2091 	struct fips_val  md[SHA_MD_BLOCK], msg;
2092 	int ret;
2093 	uint32_t i, j;
2094 
2095 	msg.len = SHA_MD_BLOCK * vec.cipher_auth.digest.len;
2096 	msg.val = calloc(1, msg.len);
2097 	if (vec.pt.val)
2098 		memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len);
2099 
2100 	for (i = 0; i < SHA_MD_BLOCK; i++)
2101 		md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0);
2102 
2103 	rte_free(vec.pt.val);
2104 	vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0);
2105 
2106 	if (info.file_type != FIPS_TYPE_JSON) {
2107 		fips_test_write_one_case();
2108 		fprintf(info.fp_wr, "\n");
2109 	}
2110 
2111 	for (j = 0; j < SHA_EXTERN_ITER; j++) {
2112 
2113 		memcpy(md[0].val, vec.cipher_auth.digest.val,
2114 			vec.cipher_auth.digest.len);
2115 		md[0].len = vec.cipher_auth.digest.len;
2116 		memcpy(md[1].val, vec.cipher_auth.digest.val,
2117 			vec.cipher_auth.digest.len);
2118 		md[1].len = vec.cipher_auth.digest.len;
2119 		memcpy(md[2].val, vec.cipher_auth.digest.val,
2120 			vec.cipher_auth.digest.len);
2121 		md[2].len = vec.cipher_auth.digest.len;
2122 
2123 		for (i = 0; i < SHA_MD_BLOCK; i++)
2124 			memcpy(&msg.val[i * md[i].len], md[i].val, md[i].len);
2125 
2126 		for (i = 0; i < (SHA_INTERN_ITER); i++) {
2127 
2128 			memcpy(vec.pt.val, md[0].val,
2129 				(size_t)md[0].len);
2130 			memcpy((vec.pt.val + md[0].len), md[1].val,
2131 				(size_t)md[1].len);
2132 			memcpy((vec.pt.val + md[0].len + md[1].len),
2133 				md[2].val,
2134 				(size_t)md[2].len);
2135 			vec.pt.len = md[0].len + md[1].len + md[2].len;
2136 
2137 			ret = fips_run_test();
2138 			if (ret < 0) {
2139 				if (ret == -EPERM || ret == -ENOTSUP) {
2140 					if (info.file_type == FIPS_TYPE_JSON)
2141 						return ret;
2142 
2143 					fprintf(info.fp_wr, "Bypass\n\n");
2144 					return 0;
2145 				}
2146 				return ret;
2147 			}
2148 
2149 			ret = get_writeback_data(&val[0]);
2150 			if (ret < 0)
2151 				return ret;
2152 
2153 			memcpy(md[0].val, md[1].val, md[1].len);
2154 			md[0].len = md[1].len;
2155 			memcpy(md[1].val, md[2].val, md[2].len);
2156 			md[1].len = md[2].len;
2157 
2158 			memcpy(md[2].val, (val[0].val + vec.pt.len),
2159 				vec.cipher_auth.digest.len);
2160 			md[2].len = vec.cipher_auth.digest.len;
2161 		}
2162 
2163 		memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len);
2164 		vec.cipher_auth.digest.len = md[2].len;
2165 
2166 		if (info.file_type != FIPS_TYPE_JSON)
2167 			fprintf(info.fp_wr, "COUNT = %u\n", j);
2168 
2169 		val[1].val = msg.val;
2170 		val[1].len = msg.len;
2171 		info.parse_writeback(val);
2172 
2173 		if (info.file_type != FIPS_TYPE_JSON)
2174 			fprintf(info.fp_wr, "\n");
2175 	}
2176 
2177 	for (i = 0; i < (SHA_MD_BLOCK); i++)
2178 		rte_free(md[i].val);
2179 
2180 	rte_free(vec.pt.val);
2181 
2182 	free(val[0].val);
2183 	free(msg.val);
2184 
2185 	return 0;
2186 }
2187 
2188 
2189 static int
2190 init_test_ops(void)
2191 {
2192 	switch (info.algo) {
2193 	case FIPS_TEST_ALGO_AES_CBC:
2194 	case FIPS_TEST_ALGO_AES_CTR:
2195 	case FIPS_TEST_ALGO_AES:
2196 		test_ops.prepare_sym_op = prepare_cipher_op;
2197 		test_ops.prepare_sym_xform  = prepare_aes_xform;
2198 		if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)
2199 			test_ops.test = fips_mct_aes_test;
2200 		else
2201 			test_ops.test = fips_generic_test;
2202 		break;
2203 	case FIPS_TEST_ALGO_HMAC:
2204 		test_ops.prepare_sym_op = prepare_auth_op;
2205 		test_ops.prepare_sym_xform = prepare_hmac_xform;
2206 		test_ops.test = fips_generic_test;
2207 		break;
2208 	case FIPS_TEST_ALGO_TDES:
2209 		test_ops.prepare_sym_op = prepare_cipher_op;
2210 		test_ops.prepare_sym_xform = prepare_tdes_xform;
2211 		if (info.interim_info.tdes_data.test_type == TDES_MCT)
2212 			test_ops.test = fips_mct_tdes_test;
2213 		else
2214 			test_ops.test = fips_generic_test;
2215 		break;
2216 	case FIPS_TEST_ALGO_AES_GMAC:
2217 		test_ops.prepare_sym_op = prepare_auth_op;
2218 		test_ops.prepare_sym_xform = prepare_gmac_xform;
2219 		test_ops.test = fips_generic_test;
2220 		break;
2221 	case FIPS_TEST_ALGO_AES_GCM:
2222 		test_ops.prepare_sym_op = prepare_aead_op;
2223 		test_ops.prepare_sym_xform = prepare_gcm_xform;
2224 		test_ops.test = fips_generic_test;
2225 		break;
2226 	case FIPS_TEST_ALGO_AES_CMAC:
2227 		test_ops.prepare_sym_op = prepare_auth_op;
2228 		test_ops.prepare_sym_xform = prepare_cmac_xform;
2229 		test_ops.test = fips_generic_test;
2230 		break;
2231 	case FIPS_TEST_ALGO_AES_CCM:
2232 		test_ops.prepare_sym_op = prepare_aead_op;
2233 		test_ops.prepare_sym_xform = prepare_ccm_xform;
2234 		test_ops.test = fips_generic_test;
2235 		break;
2236 	case FIPS_TEST_ALGO_SHA:
2237 		test_ops.prepare_sym_op = prepare_auth_op;
2238 		test_ops.prepare_sym_xform = prepare_sha_xform;
2239 		if (info.interim_info.sha_data.test_type == SHA_MCT)
2240 			test_ops.test = fips_mct_sha_test;
2241 		else
2242 			test_ops.test = fips_generic_test;
2243 		break;
2244 	case FIPS_TEST_ALGO_AES_XTS:
2245 		test_ops.prepare_sym_op = prepare_cipher_op;
2246 		test_ops.prepare_sym_xform = prepare_xts_xform;
2247 		test_ops.test = fips_generic_test;
2248 		break;
2249 	case FIPS_TEST_ALGO_RSA:
2250 		test_ops.prepare_asym_op = prepare_rsa_op;
2251 		test_ops.prepare_asym_xform = prepare_rsa_xform;
2252 		test_ops.test = fips_generic_test;
2253 		break;
2254 	default:
2255 		if (strstr(info.file_name, "TECB") ||
2256 				strstr(info.file_name, "TCBC")) {
2257 			info.algo = FIPS_TEST_ALGO_TDES;
2258 			test_ops.prepare_sym_op = prepare_cipher_op;
2259 			test_ops.prepare_sym_xform = prepare_tdes_xform;
2260 			if (info.interim_info.tdes_data.test_type == TDES_MCT)
2261 				test_ops.test = fips_mct_tdes_test;
2262 			else
2263 				test_ops.test = fips_generic_test;
2264 			break;
2265 		}
2266 		return -1;
2267 	}
2268 
2269 	return 0;
2270 }
2271 
2272 static void
2273 print_test_block(void)
2274 {
2275 	uint32_t i;
2276 
2277 	for (i = 0; i < info.nb_vec_lines; i++)
2278 		printf("%s\n", info.vec[i]);
2279 
2280 	printf("\n");
2281 }
2282 
2283 static int
2284 fips_test_one_file(void)
2285 {
2286 	int fetch_ret = 0, ret;
2287 
2288 	ret = init_test_ops();
2289 	if (ret < 0) {
2290 		RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret);
2291 		return ret;
2292 	}
2293 
2294 	while (ret >= 0 && fetch_ret == 0) {
2295 		fetch_ret = fips_test_fetch_one_block();
2296 		if (fetch_ret < 0) {
2297 			RTE_LOG(ERR, USER1, "Error %i: Fetch block\n",
2298 					fetch_ret);
2299 			ret = fetch_ret;
2300 			goto error_one_case;
2301 		}
2302 
2303 		if (info.nb_vec_lines == 0) {
2304 			if (fetch_ret == -EOF)
2305 				break;
2306 
2307 			fprintf(info.fp_wr, "\n");
2308 			continue;
2309 		}
2310 
2311 		ret = fips_test_parse_one_case();
2312 		switch (ret) {
2313 		case 0:
2314 			ret = test_ops.test();
2315 			if (ret == 0)
2316 				break;
2317 			RTE_LOG(ERR, USER1, "Error %i: test block\n",
2318 					ret);
2319 			goto error_one_case;
2320 		case 1:
2321 			break;
2322 		default:
2323 			RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
2324 					ret);
2325 			goto error_one_case;
2326 		}
2327 
2328 		continue;
2329 error_one_case:
2330 		print_test_block();
2331 	}
2332 
2333 	fips_test_clear();
2334 
2335 	if (env.digest) {
2336 		rte_free(env.digest);
2337 		env.digest = NULL;
2338 	}
2339 	rte_pktmbuf_free(env.mbuf);
2340 
2341 	return ret;
2342 }
2343 
2344 #ifdef USE_JANSSON
2345 static int
2346 fips_test_json_init_writeback(void)
2347 {
2348 	json_t *session_info, *session_write;
2349 	session_info = json_array_get(json_info.json_root, 0);
2350 	session_write = json_object();
2351 	json_info.json_write_root = json_array();
2352 
2353 	json_object_set(session_write, "jwt",
2354 		json_object_get(session_info, "jwt"));
2355 	json_object_set(session_write, "url",
2356 		json_object_get(session_info, "url"));
2357 	json_object_set(session_write, "isSample",
2358 		json_object_get(session_info, "isSample"));
2359 
2360 	json_info.is_sample = json_boolean_value(
2361 		json_object_get(session_info, "isSample"));
2362 
2363 	json_array_append_new(json_info.json_write_root, session_write);
2364 	return 0;
2365 }
2366 
2367 static int
2368 fips_test_one_test_case(void)
2369 {
2370 	int ret;
2371 
2372 	ret = fips_test_parse_one_json_case();
2373 
2374 	switch (ret) {
2375 	case 0:
2376 		ret = test_ops.test();
2377 		if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP))
2378 			break;
2379 		RTE_LOG(ERR, USER1, "Error %i: test block\n",
2380 				ret);
2381 		break;
2382 	default:
2383 		RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
2384 				ret);
2385 	}
2386 	return ret;
2387 }
2388 
2389 static int
2390 fips_test_one_test_group(void)
2391 {
2392 	int ret;
2393 	json_t *tests, *write_tests;
2394 	size_t test_idx, tests_size;
2395 
2396 	write_tests = json_array();
2397 	json_info.json_write_group = json_object();
2398 	json_object_set(json_info.json_write_group, "tgId",
2399 		json_object_get(json_info.json_test_group, "tgId"));
2400 	json_object_set_new(json_info.json_write_group, "tests", write_tests);
2401 
2402 	switch (info.algo) {
2403 	case FIPS_TEST_ALGO_AES_GMAC:
2404 	case FIPS_TEST_ALGO_AES_GCM:
2405 		ret = parse_test_gcm_json_init();
2406 		break;
2407 	case FIPS_TEST_ALGO_HMAC:
2408 		ret = parse_test_hmac_json_init();
2409 		break;
2410 	case FIPS_TEST_ALGO_AES_CMAC:
2411 		ret = parse_test_cmac_json_init();
2412 		break;
2413 	case FIPS_TEST_ALGO_AES_XTS:
2414 		ret = parse_test_xts_json_init();
2415 		break;
2416 	case FIPS_TEST_ALGO_AES_CBC:
2417 	case FIPS_TEST_ALGO_AES_CTR:
2418 	case FIPS_TEST_ALGO_AES:
2419 		ret = parse_test_aes_json_init();
2420 		break;
2421 	case FIPS_TEST_ALGO_SHA:
2422 		ret = parse_test_sha_json_init();
2423 		break;
2424 	case FIPS_TEST_ALGO_TDES:
2425 		ret = parse_test_tdes_json_init();
2426 		break;
2427 	case FIPS_TEST_ALGO_RSA:
2428 		ret = parse_test_rsa_json_init();
2429 		break;
2430 	default:
2431 		return -EINVAL;
2432 	}
2433 
2434 	if (ret < 0)
2435 		return ret;
2436 
2437 	ret = fips_test_parse_one_json_group();
2438 	if (ret < 0)
2439 		return ret;
2440 
2441 	ret = init_test_ops();
2442 	if (ret < 0)
2443 		return ret;
2444 
2445 	tests = json_object_get(json_info.json_test_group, "tests");
2446 	tests_size = json_array_size(tests);
2447 	for (test_idx = 0; test_idx < tests_size; test_idx++) {
2448 		json_info.json_test_case = json_array_get(tests, test_idx);
2449 		if (fips_test_one_test_case() == 0)
2450 			json_array_append_new(write_tests, json_info.json_write_case);
2451 	}
2452 
2453 	return 0;
2454 }
2455 
2456 static int
2457 fips_test_one_vector_set(void)
2458 {
2459 	int ret;
2460 	json_t *test_groups, *write_groups, *write_version, *write_set;
2461 	size_t group_idx, num_groups;
2462 
2463 	test_groups = json_object_get(json_info.json_vector_set, "testGroups");
2464 	num_groups = json_array_size(test_groups);
2465 
2466 	json_info.json_write_set = json_array();
2467 	write_version = json_object();
2468 	json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION));
2469 	json_array_append_new(json_info.json_write_set, write_version);
2470 
2471 	write_set = json_object();
2472 	json_array_append(json_info.json_write_set, write_set);
2473 	write_groups = json_array();
2474 
2475 	json_object_set(write_set, "vsId",
2476 		json_object_get(json_info.json_vector_set, "vsId"));
2477 	json_object_set(write_set, "algorithm",
2478 		json_object_get(json_info.json_vector_set, "algorithm"));
2479 	json_object_set(write_set, "revision",
2480 		json_object_get(json_info.json_vector_set, "revision"));
2481 	json_object_set_new(write_set, "isSample",
2482 		json_boolean(json_info.is_sample));
2483 	json_object_set_new(write_set, "testGroups", write_groups);
2484 
2485 	ret = fips_test_parse_one_json_vector_set();
2486 	if (ret < 0) {
2487 		RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n",
2488 			json_string_value(json_object_get(json_info.json_vector_set, "algorithm")));
2489 		return ret;
2490 	}
2491 
2492 	for (group_idx = 0; group_idx < num_groups; group_idx++) {
2493 		json_info.json_test_group = json_array_get(test_groups, group_idx);
2494 		ret = fips_test_one_test_group();
2495 		json_array_append_new(write_groups, json_info.json_write_group);
2496 	}
2497 
2498 	return 0;
2499 }
2500 
2501 static int
2502 fips_test_one_json_file(void)
2503 {
2504 	size_t vector_set_idx, root_size;
2505 
2506 	root_size = json_array_size(json_info.json_root);
2507 	fips_test_json_init_writeback();
2508 
2509 	for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) {
2510 		/* Vector set index starts at 1, the 0th index contains test session
2511 		 * information.
2512 		 */
2513 		json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx);
2514 		fips_test_one_vector_set();
2515 		json_array_append_new(json_info.json_write_root, json_info.json_write_set);
2516 		json_incref(json_info.json_write_set);
2517 	}
2518 
2519 	json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4));
2520 	json_decref(json_info.json_write_root);
2521 
2522 	return 0;
2523 }
2524 #endif /* USE_JANSSON */
2525