xref: /dpdk/examples/fips_validation/main.c (revision 100711af824af73900bbcb84442a5dee1de4a9b7)
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.cipher_auth.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 
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.pkey.data = vec.ecdsa.pkey.val;
1010 		asym->ecdsa.pkey.length = vec.ecdsa.pkey.len;
1011 		asym->ecdsa.k.data = vec.ecdsa.k.val;
1012 		asym->ecdsa.k.length = vec.ecdsa.k.len;
1013 
1014 		rte_free(vec.ecdsa.r.val);
1015 
1016 		rte_free(vec.ecdsa.s.val);
1017 
1018 		vec.ecdsa.r.len = info.interim_info.ecdsa_data.curve_len;
1019 		vec.ecdsa.r.val = rte_zmalloc(NULL, vec.ecdsa.r.len, 0);
1020 
1021 		vec.ecdsa.s.len = vec.ecdsa.r.len;
1022 		vec.ecdsa.s.val = rte_zmalloc(NULL, vec.ecdsa.s.len, 0);
1023 
1024 		asym->ecdsa.r.data = vec.ecdsa.r.val;
1025 		asym->ecdsa.r.length = 0;
1026 		asym->ecdsa.s.data = vec.ecdsa.s.val;
1027 		asym->ecdsa.s.length = 0;
1028 	} else if (info.op == FIPS_TEST_ASYM_SIGVER) {
1029 		asym->ecdsa.op_type = RTE_CRYPTO_ASYM_OP_VERIFY;
1030 		asym->ecdsa.message.data = msg.val;
1031 		asym->ecdsa.message.length = msg.len;
1032 		asym->ecdsa.q.x.data = vec.ecdsa.qx.val;
1033 		asym->ecdsa.q.x.length = vec.ecdsa.qx.len;
1034 		asym->ecdsa.q.y.data = vec.ecdsa.qy.val;
1035 		asym->ecdsa.q.y.length = vec.ecdsa.qy.len;
1036 		asym->ecdsa.r.data = vec.ecdsa.r.val;
1037 		asym->ecdsa.r.length = vec.ecdsa.r.len;
1038 		asym->ecdsa.s.data = vec.ecdsa.s.val;
1039 		asym->ecdsa.s.length = vec.ecdsa.s.len;
1040 	} else {
1041 		RTE_LOG(ERR, USER1, "Invalid op %d\n", info.op);
1042 		return -EINVAL;
1043 	}
1044 
1045 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
1046 
1047 	return 0;
1048 }
1049 
1050 static int
1051 prepare_ecfpm_op(void)
1052 {
1053 	struct rte_crypto_asym_op *asym;
1054 
1055 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_ASYMMETRIC);
1056 
1057 	asym = env.op->asym;
1058 	asym->ecpm.scalar.data = vec.ecdsa.pkey.val;
1059 	asym->ecpm.scalar.length = vec.ecdsa.pkey.len;
1060 
1061 	rte_free(vec.ecdsa.qx.val);
1062 
1063 	rte_free(vec.ecdsa.qy.val);
1064 
1065 	vec.ecdsa.qx.len = info.interim_info.ecdsa_data.curve_len;
1066 	vec.ecdsa.qx.val = rte_zmalloc(NULL, vec.ecdsa.qx.len, 0);
1067 
1068 	vec.ecdsa.qy.len = vec.ecdsa.qx.len;
1069 	vec.ecdsa.qy.val = rte_zmalloc(NULL, vec.ecdsa.qy.len, 0);
1070 
1071 	asym->ecpm.r.x.data = vec.ecdsa.qx.val;
1072 	asym->ecpm.r.x.length = 0;
1073 	asym->ecpm.r.y.data = vec.ecdsa.qy.val;
1074 	asym->ecpm.r.y.length = 0;
1075 
1076 	rte_crypto_op_attach_asym_session(env.op, env.asym.sess);
1077 
1078 	return 0;
1079 }
1080 
1081 static int
1082 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
1083 {
1084 	const struct rte_cryptodev_symmetric_capability *cap;
1085 	struct rte_cryptodev_sym_capability_idx cap_idx;
1086 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1087 
1088 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1089 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC)
1090 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC;
1091 	else if (info.interim_info.aes_data.cipher_algo ==
1092 			RTE_CRYPTO_CIPHER_AES_CTR)
1093 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CTR;
1094 	else
1095 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB;
1096 
1097 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1098 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1099 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1100 	cipher_xform->key.data = vec.cipher_auth.key.val;
1101 	cipher_xform->key.length = vec.cipher_auth.key.len;
1102 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC ||
1103 			cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CTR) {
1104 		cipher_xform->iv.length = vec.iv.len;
1105 		cipher_xform->iv.offset = IV_OFF;
1106 	} else {
1107 		cipher_xform->iv.length = 0;
1108 		cipher_xform->iv.offset = 0;
1109 	}
1110 	cap_idx.algo.cipher = cipher_xform->algo;
1111 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1112 
1113 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1114 	if (!cap) {
1115 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1116 				env.dev_id);
1117 		return -EINVAL;
1118 	}
1119 
1120 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1121 			cipher_xform->key.length,
1122 			cipher_xform->iv.length) != 0) {
1123 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1124 				info.device_name, cipher_xform->key.length,
1125 				cipher_xform->iv.length);
1126 		return -EPERM;
1127 	}
1128 
1129 	return 0;
1130 }
1131 
1132 static int
1133 prepare_tdes_xform(struct rte_crypto_sym_xform *xform)
1134 {
1135 	const struct rte_cryptodev_symmetric_capability *cap;
1136 	struct rte_cryptodev_sym_capability_idx cap_idx;
1137 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1138 
1139 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1140 
1141 	if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC)
1142 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC;
1143 	else
1144 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB;
1145 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1146 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1147 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1148 	cipher_xform->key.data = vec.cipher_auth.key.val;
1149 	cipher_xform->key.length = vec.cipher_auth.key.len;
1150 
1151 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
1152 		cipher_xform->iv.length = vec.iv.len;
1153 		cipher_xform->iv.offset = IV_OFF;
1154 	} else {
1155 		cipher_xform->iv.length = 0;
1156 		cipher_xform->iv.offset = 0;
1157 	}
1158 	cap_idx.algo.cipher = cipher_xform->algo;
1159 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1160 
1161 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1162 	if (!cap) {
1163 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1164 				env.dev_id);
1165 		return -EINVAL;
1166 	}
1167 
1168 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1169 			cipher_xform->key.length,
1170 			cipher_xform->iv.length) != 0) {
1171 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1172 				info.device_name, cipher_xform->key.length,
1173 				cipher_xform->iv.length);
1174 		return -EPERM;
1175 	}
1176 
1177 	return 0;
1178 }
1179 
1180 static int
1181 prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
1182 {
1183 	const struct rte_cryptodev_symmetric_capability *cap;
1184 	struct rte_cryptodev_sym_capability_idx cap_idx;
1185 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1186 
1187 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1188 
1189 	auth_xform->algo = info.interim_info.hmac_data.algo;
1190 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
1191 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1192 	auth_xform->key.data = vec.cipher_auth.key.val;
1193 	auth_xform->key.length = vec.cipher_auth.key.len;
1194 
1195 	cap_idx.algo.auth = auth_xform->algo;
1196 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1197 
1198 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1199 	if (!cap) {
1200 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1201 				env.dev_id);
1202 		return -EINVAL;
1203 	}
1204 
1205 	if (rte_cryptodev_sym_capability_check_auth(cap,
1206 			auth_xform->key.length,
1207 			auth_xform->digest_length, 0) != 0) {
1208 		RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n",
1209 				info.device_name, auth_xform->key.length,
1210 				auth_xform->digest_length);
1211 		return -EPERM;
1212 	}
1213 
1214 	return 0;
1215 }
1216 
1217 int
1218 prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
1219 {
1220 	const struct rte_cryptodev_symmetric_capability *cap;
1221 	struct rte_cryptodev_sym_capability_idx cap_idx;
1222 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
1223 
1224 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
1225 
1226 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
1227 	aead_xform->aad_length = vec.aead.aad.len;
1228 	aead_xform->digest_length = vec.aead.digest.len;
1229 	aead_xform->iv.offset = IV_OFF;
1230 	aead_xform->iv.length = vec.iv.len;
1231 	aead_xform->key.data = vec.aead.key.val;
1232 	aead_xform->key.length = vec.aead.key.len;
1233 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1234 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
1235 			RTE_CRYPTO_AEAD_OP_DECRYPT;
1236 
1237 	cap_idx.algo.aead = aead_xform->algo;
1238 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
1239 
1240 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1241 	if (!cap) {
1242 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1243 				env.dev_id);
1244 		return -EINVAL;
1245 	}
1246 
1247 	if (rte_cryptodev_sym_capability_check_aead(cap,
1248 			aead_xform->key.length,
1249 			aead_xform->digest_length, aead_xform->aad_length,
1250 			aead_xform->iv.length) != 0) {
1251 		RTE_LOG(ERR, USER1,
1252 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
1253 				info.device_name, aead_xform->key.length,
1254 				aead_xform->digest_length,
1255 				aead_xform->aad_length,
1256 				aead_xform->iv.length);
1257 		return -EPERM;
1258 	}
1259 
1260 	return 0;
1261 }
1262 
1263 int
1264 prepare_gmac_xform(struct rte_crypto_sym_xform *xform)
1265 {
1266 	const struct rte_cryptodev_symmetric_capability *cap;
1267 	struct rte_cryptodev_sym_capability_idx cap_idx;
1268 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1269 
1270 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1271 
1272 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC;
1273 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1274 			RTE_CRYPTO_AUTH_OP_GENERATE :
1275 			RTE_CRYPTO_AUTH_OP_VERIFY;
1276 	auth_xform->iv.offset = IV_OFF;
1277 	auth_xform->iv.length = vec.iv.len;
1278 	auth_xform->digest_length = vec.aead.digest.len;
1279 	auth_xform->key.data = vec.aead.key.val;
1280 	auth_xform->key.length = vec.aead.key.len;
1281 
1282 	cap_idx.algo.auth = auth_xform->algo;
1283 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1284 
1285 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1286 	if (!cap) {
1287 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1288 				env.dev_id);
1289 		return -EINVAL;
1290 	}
1291 
1292 	if (rte_cryptodev_sym_capability_check_auth(cap,
1293 			auth_xform->key.length,
1294 			auth_xform->digest_length,
1295 			auth_xform->iv.length) != 0) {
1296 
1297 		RTE_LOG(ERR, USER1,
1298 			"PMD %s key length %u Digest length %u IV length %u\n",
1299 				info.device_name, auth_xform->key.length,
1300 				auth_xform->digest_length,
1301 				auth_xform->iv.length);
1302 		return -EPERM;
1303 	}
1304 
1305 	return 0;
1306 }
1307 
1308 static int
1309 prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
1310 {
1311 	const struct rte_cryptodev_symmetric_capability *cap;
1312 	struct rte_cryptodev_sym_capability_idx cap_idx;
1313 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1314 
1315 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1316 
1317 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC;
1318 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1319 			RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY;
1320 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1321 	auth_xform->key.data = vec.cipher_auth.key.val;
1322 	auth_xform->key.length = vec.cipher_auth.key.len;
1323 
1324 	cap_idx.algo.auth = auth_xform->algo;
1325 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1326 
1327 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1328 	if (!cap) {
1329 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1330 				env.dev_id);
1331 		return -EINVAL;
1332 	}
1333 
1334 	if (rte_cryptodev_sym_capability_check_auth(cap,
1335 			auth_xform->key.length,
1336 			auth_xform->digest_length, 0) != 0) {
1337 		RTE_LOG(ERR, USER1, "PMD %s key length %u Digest length %u\n",
1338 				info.device_name, auth_xform->key.length,
1339 				auth_xform->digest_length);
1340 		return -EPERM;
1341 	}
1342 
1343 	return 0;
1344 }
1345 
1346 static int
1347 prepare_ccm_xform(struct rte_crypto_sym_xform *xform)
1348 {
1349 	const struct rte_cryptodev_symmetric_capability *cap;
1350 	struct rte_cryptodev_sym_capability_idx cap_idx;
1351 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
1352 
1353 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
1354 
1355 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM;
1356 	aead_xform->aad_length = vec.aead.aad.len;
1357 	aead_xform->digest_length = vec.aead.digest.len;
1358 	aead_xform->iv.offset = IV_OFF;
1359 	aead_xform->iv.length = vec.iv.len;
1360 	aead_xform->key.data = vec.aead.key.val;
1361 	aead_xform->key.length = vec.aead.key.len;
1362 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1363 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
1364 			RTE_CRYPTO_AEAD_OP_DECRYPT;
1365 
1366 	cap_idx.algo.aead = aead_xform->algo;
1367 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
1368 
1369 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1370 	if (!cap) {
1371 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1372 				env.dev_id);
1373 		return -EINVAL;
1374 	}
1375 
1376 	if (rte_cryptodev_sym_capability_check_aead(cap,
1377 			aead_xform->key.length,
1378 			aead_xform->digest_length, aead_xform->aad_length,
1379 			aead_xform->iv.length) != 0) {
1380 		RTE_LOG(ERR, USER1,
1381 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
1382 				info.device_name, aead_xform->key.length,
1383 				aead_xform->digest_length,
1384 				aead_xform->aad_length,
1385 				aead_xform->iv.length);
1386 		return -EPERM;
1387 	}
1388 
1389 	return 0;
1390 }
1391 
1392 static int
1393 prepare_sha_xform(struct rte_crypto_sym_xform *xform)
1394 {
1395 	const struct rte_cryptodev_symmetric_capability *cap;
1396 	struct rte_cryptodev_sym_capability_idx cap_idx;
1397 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1398 
1399 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1400 
1401 	auth_xform->algo = info.interim_info.sha_data.algo;
1402 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
1403 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1404 
1405 	cap_idx.algo.auth = auth_xform->algo;
1406 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1407 
1408 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1409 	if (!cap) {
1410 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1411 				env.dev_id);
1412 		return -EINVAL;
1413 	}
1414 
1415 	if (rte_cryptodev_sym_capability_check_auth(cap,
1416 			auth_xform->key.length,
1417 			auth_xform->digest_length, 0) != 0) {
1418 		RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n",
1419 				info.device_name, auth_xform->key.length,
1420 				auth_xform->digest_length);
1421 		return -EPERM;
1422 	}
1423 
1424 	return 0;
1425 }
1426 
1427 static int
1428 prepare_xts_xform(struct rte_crypto_sym_xform *xform)
1429 {
1430 	const struct rte_cryptodev_symmetric_capability *cap;
1431 	struct rte_cryptodev_sym_capability_idx cap_idx;
1432 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1433 
1434 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1435 
1436 	cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS;
1437 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1438 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1439 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1440 	cipher_xform->key.data = vec.cipher_auth.key.val;
1441 	cipher_xform->key.length = vec.cipher_auth.key.len;
1442 	cipher_xform->iv.length = vec.iv.len;
1443 	cipher_xform->iv.offset = IV_OFF;
1444 
1445 	cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS;
1446 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1447 
1448 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1449 	if (!cap) {
1450 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1451 				env.dev_id);
1452 		return -EINVAL;
1453 	}
1454 
1455 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1456 			cipher_xform->key.length,
1457 			cipher_xform->iv.length) != 0) {
1458 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1459 				info.device_name, cipher_xform->key.length,
1460 				cipher_xform->iv.length);
1461 		return -EPERM;
1462 	}
1463 
1464 	return 0;
1465 }
1466 
1467 static int
1468 prepare_rsa_xform(struct rte_crypto_asym_xform *xform)
1469 {
1470 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1471 	struct rte_cryptodev_asym_capability_idx cap_idx;
1472 	struct rte_cryptodev_info dev_info;
1473 
1474 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_RSA;
1475 	xform->next = NULL;
1476 
1477 	cap_idx.type = xform->xform_type;
1478 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1479 	if (!cap) {
1480 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1481 				env.dev_id);
1482 		return -EINVAL;
1483 	}
1484 
1485 	switch (info.op) {
1486 	case FIPS_TEST_ASYM_SIGGEN:
1487 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1488 			RTE_CRYPTO_ASYM_OP_SIGN)) {
1489 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1490 				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
1491 			return -EPERM;
1492 		}
1493 		break;
1494 	case FIPS_TEST_ASYM_SIGVER:
1495 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1496 			RTE_CRYPTO_ASYM_OP_VERIFY)) {
1497 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1498 				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
1499 			return -EPERM;
1500 		}
1501 		break;
1502 	case FIPS_TEST_ASYM_KEYGEN:
1503 		break;
1504 	default:
1505 		break;
1506 	}
1507 
1508 	rte_cryptodev_info_get(env.dev_id, &dev_info);
1509 	xform->rsa.key_type = info.interim_info.rsa_data.privkey;
1510 	switch (xform->rsa.key_type) {
1511 	case RTE_RSA_KEY_TYPE_QT:
1512 		if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_QT)) {
1513 			RTE_LOG(ERR, USER1, "PMD %s does not support QT key type\n",
1514 				info.device_name);
1515 			return -EPERM;
1516 		}
1517 		xform->rsa.qt.p.data = vec.rsa.p.val;
1518 		xform->rsa.qt.p.length = vec.rsa.p.len;
1519 		xform->rsa.qt.q.data = vec.rsa.q.val;
1520 		xform->rsa.qt.q.length = vec.rsa.q.len;
1521 		xform->rsa.qt.dP.data = vec.rsa.dp.val;
1522 		xform->rsa.qt.dP.length = vec.rsa.dp.len;
1523 		xform->rsa.qt.dQ.data = vec.rsa.dq.val;
1524 		xform->rsa.qt.dQ.length = vec.rsa.dq.len;
1525 		xform->rsa.qt.qInv.data = vec.rsa.qinv.val;
1526 		xform->rsa.qt.qInv.length = vec.rsa.qinv.len;
1527 		break;
1528 	case RTE_RSA_KEY_TYPE_EXP:
1529 		if (!(dev_info.feature_flags & RTE_CRYPTODEV_FF_RSA_PRIV_OP_KEY_EXP)) {
1530 			RTE_LOG(ERR, USER1, "PMD %s does not support EXP key type\n",
1531 				info.device_name);
1532 			return -EPERM;
1533 		}
1534 		xform->rsa.d.data = vec.rsa.d.val;
1535 		xform->rsa.d.length = vec.rsa.d.len;
1536 		break;
1537 	default:
1538 		break;
1539 	}
1540 
1541 	xform->rsa.e.data = vec.rsa.e.val;
1542 	xform->rsa.e.length = vec.rsa.e.len;
1543 	xform->rsa.n.data = vec.rsa.n.val;
1544 	xform->rsa.n.length = vec.rsa.n.len;
1545 	return 0;
1546 }
1547 
1548 static int
1549 prepare_ecdsa_xform(struct rte_crypto_asym_xform *xform)
1550 {
1551 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1552 	struct rte_cryptodev_asym_capability_idx cap_idx;
1553 
1554 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECDSA;
1555 	xform->next = NULL;
1556 
1557 	cap_idx.type = xform->xform_type;
1558 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1559 	if (!cap) {
1560 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1561 				env.dev_id);
1562 		return -EINVAL;
1563 	}
1564 
1565 	switch (info.op) {
1566 	case FIPS_TEST_ASYM_SIGGEN:
1567 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1568 			RTE_CRYPTO_ASYM_OP_SIGN)) {
1569 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1570 				info.device_name, RTE_CRYPTO_ASYM_OP_SIGN);
1571 			return -EPERM;
1572 		}
1573 		break;
1574 	case FIPS_TEST_ASYM_SIGVER:
1575 		if (!rte_cryptodev_asym_xform_capability_check_optype(cap,
1576 			RTE_CRYPTO_ASYM_OP_VERIFY)) {
1577 			RTE_LOG(ERR, USER1, "PMD %s xform_op %u\n",
1578 				info.device_name, RTE_CRYPTO_ASYM_OP_VERIFY);
1579 			return -EPERM;
1580 		}
1581 		break;
1582 	default:
1583 		break;
1584 	}
1585 
1586 	xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id;
1587 	return 0;
1588 }
1589 
1590 static int
1591 prepare_ecfpm_xform(struct rte_crypto_asym_xform *xform)
1592 {
1593 	const struct rte_cryptodev_asymmetric_xform_capability *cap;
1594 	struct rte_cryptodev_asym_capability_idx cap_idx;
1595 
1596 	xform->xform_type = RTE_CRYPTO_ASYM_XFORM_ECFPM;
1597 	xform->next = NULL;
1598 
1599 	cap_idx.type = xform->xform_type;
1600 	cap = rte_cryptodev_asym_capability_get(env.dev_id, &cap_idx);
1601 	if (!cap) {
1602 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1603 				env.dev_id);
1604 		return -EINVAL;
1605 	}
1606 
1607 	xform->ec.curve_id = info.interim_info.ecdsa_data.curve_id;
1608 	return 0;
1609 }
1610 
1611 static int
1612 get_writeback_data(struct fips_val *val)
1613 {
1614 	struct rte_mbuf *m = env.mbuf;
1615 	uint16_t data_len = rte_pktmbuf_pkt_len(m);
1616 	uint16_t total_len = data_len + env.digest_len;
1617 	uint8_t *src, *dst, *wb_data;
1618 
1619 	/* in case val is reused for MCT test, try to free the buffer first */
1620 	if (val->val) {
1621 		free(val->val);
1622 		val->val = NULL;
1623 	}
1624 
1625 	wb_data = dst = calloc(1, total_len);
1626 	if (!dst) {
1627 		RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM);
1628 		return -ENOMEM;
1629 	}
1630 
1631 	while (m && data_len) {
1632 		uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len);
1633 
1634 		src = rte_pktmbuf_mtod(m, uint8_t *);
1635 		memcpy(dst, src, seg_len);
1636 		m = m->next;
1637 		data_len -= seg_len;
1638 		dst += seg_len;
1639 	}
1640 
1641 	if (data_len) {
1642 		RTE_LOG(ERR, USER1, "Error -1: write back data\n");
1643 		free(wb_data);
1644 		return -1;
1645 	}
1646 
1647 	if (env.digest)
1648 		memcpy(dst, env.digest, env.digest_len);
1649 
1650 	val->val = wb_data;
1651 	val->len = total_len;
1652 
1653 	return 0;
1654 }
1655 
1656 static int
1657 fips_run_sym_test(void)
1658 {
1659 	struct rte_crypto_sym_xform xform = {0};
1660 	uint16_t n_deqd;
1661 	int ret;
1662 
1663 	if (!test_ops.prepare_sym_xform || !test_ops.prepare_sym_op)
1664 		return -EINVAL;
1665 
1666 	ret = test_ops.prepare_sym_xform(&xform);
1667 	if (ret < 0)
1668 		return ret;
1669 
1670 	env.sym.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform,
1671 						env.sym.sess_mpool);
1672 	if (!env.sym.sess)
1673 		return -ENOMEM;
1674 
1675 	ret = test_ops.prepare_sym_op();
1676 	if (ret < 0) {
1677 		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n",
1678 				ret);
1679 		goto exit;
1680 	}
1681 
1682 	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
1683 		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
1684 		ret = -1;
1685 		goto exit;
1686 	}
1687 
1688 	do {
1689 		struct rte_crypto_op *deqd_op;
1690 
1691 		n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1);
1692 	} while (n_deqd == 0);
1693 
1694 	vec.status = env.op->status;
1695 
1696 exit:
1697 	rte_cryptodev_sym_session_free(env.dev_id, env.sym.sess);
1698 	env.sym.sess = NULL;
1699 	return ret;
1700 }
1701 
1702 static int
1703 fips_run_asym_test(void)
1704 {
1705 	struct rte_crypto_asym_xform xform = {0};
1706 	struct rte_crypto_asym_op *asym;
1707 	struct rte_crypto_op *deqd_op;
1708 	int ret;
1709 
1710 	if (info.op == FIPS_TEST_ASYM_KEYGEN && info.algo != FIPS_TEST_ALGO_ECDSA) {
1711 		RTE_SET_USED(asym);
1712 		ret = 0;
1713 		goto exit;
1714 	}
1715 
1716 	if (!test_ops.prepare_asym_xform || !test_ops.prepare_asym_op)
1717 		return -EINVAL;
1718 
1719 	asym = env.op->asym;
1720 	ret = test_ops.prepare_asym_xform(&xform);
1721 	if (ret < 0)
1722 		return ret;
1723 
1724 	ret = rte_cryptodev_asym_session_create(env.dev_id, &xform, env.asym.sess_mpool,
1725 			(void *)&env.asym.sess);
1726 	if (ret < 0)
1727 		return ret;
1728 
1729 	ret = test_ops.prepare_asym_op();
1730 	if (ret < 0) {
1731 		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n", ret);
1732 		goto exit;
1733 	}
1734 
1735 	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
1736 		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
1737 		ret = -1;
1738 		goto exit;
1739 	}
1740 
1741 	while (rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op, 1) == 0)
1742 		rte_pause();
1743 
1744 	vec.status = env.op->status;
1745 
1746  exit:
1747 	if (env.asym.sess)
1748 		rte_cryptodev_asym_session_free(env.dev_id, env.asym.sess);
1749 
1750 	env.asym.sess = NULL;
1751 	return ret;
1752 }
1753 
1754 static int
1755 fips_run_test(void)
1756 {
1757 	int ret;
1758 
1759 	env.op = env.sym.op;
1760 	if (env.is_asym_test) {
1761 		vec.cipher_auth.digest.len = parse_test_sha_hash_size(
1762 						info.interim_info.rsa_data.auth);
1763 		test_ops.prepare_sym_xform = prepare_sha_xform;
1764 		test_ops.prepare_sym_op = prepare_auth_op;
1765 		ret = fips_run_sym_test();
1766 		if (ret < 0)
1767 			return ret;
1768 	} else {
1769 		return fips_run_sym_test();
1770 	}
1771 
1772 	env.op = env.asym.op;
1773 	if (info.op == FIPS_TEST_ASYM_SIGGEN &&
1774 		info.algo == FIPS_TEST_ALGO_ECDSA &&
1775 		info.interim_info.ecdsa_data.pubkey_gen == 1) {
1776 		fips_prepare_asym_xform_t ecdsa_xform;
1777 		fips_prepare_op_t ecdsa_op;
1778 
1779 		ecdsa_xform = test_ops.prepare_asym_xform;
1780 		ecdsa_op = test_ops.prepare_asym_op;
1781 		info.op = FIPS_TEST_ASYM_KEYGEN;
1782 		test_ops.prepare_asym_xform = prepare_ecfpm_xform;
1783 		test_ops.prepare_asym_op = prepare_ecfpm_op;
1784 		ret = fips_run_asym_test();
1785 		if (ret < 0)
1786 			return ret;
1787 
1788 		info.post_interim_writeback(NULL);
1789 		info.interim_info.ecdsa_data.pubkey_gen = 0;
1790 
1791 		test_ops.prepare_asym_xform = ecdsa_xform;
1792 		test_ops.prepare_asym_op = ecdsa_op;
1793 		info.op = FIPS_TEST_ASYM_SIGGEN;
1794 		ret = fips_run_asym_test();
1795 	} else {
1796 		ret = fips_run_asym_test();
1797 	}
1798 
1799 	return ret;
1800 }
1801 
1802 static int
1803 fips_generic_test(void)
1804 {
1805 	struct fips_val val = {NULL, 0};
1806 	int ret;
1807 
1808 	if (info.file_type != FIPS_TYPE_JSON)
1809 		fips_test_write_one_case();
1810 
1811 	ret = fips_run_test();
1812 	if (ret < 0) {
1813 		if (ret == -EPERM || ret == -ENOTSUP) {
1814 			if (info.file_type == FIPS_TYPE_JSON)
1815 				return ret;
1816 
1817 			fprintf(info.fp_wr, "Bypass\n\n");
1818 			return 0;
1819 		}
1820 
1821 		return ret;
1822 	}
1823 
1824 	if (!env.is_asym_test) {
1825 		ret = get_writeback_data(&val);
1826 		if (ret < 0)
1827 			return ret;
1828 	}
1829 
1830 	switch (info.file_type) {
1831 	case FIPS_TYPE_REQ:
1832 	case FIPS_TYPE_RSP:
1833 	case FIPS_TYPE_JSON:
1834 		if (info.parse_writeback == NULL)
1835 			return -EPERM;
1836 		ret = info.parse_writeback(&val);
1837 		if (ret < 0)
1838 			return ret;
1839 		break;
1840 	case FIPS_TYPE_FAX:
1841 		if (info.kat_check == NULL)
1842 			return -EPERM;
1843 		ret = info.kat_check(&val);
1844 		if (ret < 0)
1845 			return ret;
1846 		break;
1847 	default:
1848 		break;
1849 	}
1850 
1851 	if (info.file_type != FIPS_TYPE_JSON)
1852 		fprintf(info.fp_wr, "\n");
1853 	free(val.val);
1854 
1855 	return 0;
1856 }
1857 
1858 static int
1859 fips_mct_tdes_test(void)
1860 {
1861 #define TDES_BLOCK_SIZE		8
1862 #define TDES_EXTERN_ITER	400
1863 #define TDES_INTERN_ITER	10000
1864 	struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv;
1865 	uint8_t prev_out[TDES_BLOCK_SIZE] = {0};
1866 	uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0};
1867 	uint8_t prev_in[TDES_BLOCK_SIZE] = {0};
1868 	uint32_t i, j, k;
1869 	int ret;
1870 	int test_mode = info.interim_info.tdes_data.test_mode;
1871 
1872 	pt.len = vec.pt.len;
1873 	pt.val = calloc(1, pt.len);
1874 	ct.len = vec.ct.len;
1875 	ct.val = calloc(1, ct.len);
1876 	iv.len = vec.iv.len;
1877 	iv.val = calloc(1, iv.len);
1878 
1879 	for (i = 0; i < TDES_EXTERN_ITER; i++) {
1880 		if (info.file_type != FIPS_TYPE_JSON) {
1881 			if ((i == 0) && (info.version == 21.4f)) {
1882 				if (!(strstr(info.vec[0], "COUNT")))
1883 					fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0);
1884 			}
1885 
1886 			if (i != 0)
1887 				update_info_vec(i);
1888 
1889 			fips_test_write_one_case();
1890 		}
1891 
1892 		for (j = 0; j < TDES_INTERN_ITER; j++) {
1893 			ret = fips_run_test();
1894 			if (ret < 0) {
1895 				if (ret == -EPERM) {
1896 					if (info.file_type == FIPS_TYPE_JSON)
1897 						return ret;
1898 
1899 					fprintf(info.fp_wr, "Bypass\n");
1900 					return 0;
1901 				}
1902 				return ret;
1903 			}
1904 
1905 			ret = get_writeback_data(&val[0]);
1906 			if (ret < 0)
1907 				return ret;
1908 
1909 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
1910 				memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE);
1911 
1912 			if (j == 0) {
1913 				memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
1914 				memcpy(pt.val, vec.pt.val, pt.len);
1915 				memcpy(ct.val, vec.ct.val, ct.len);
1916 				memcpy(iv.val, vec.iv.val, iv.len);
1917 
1918 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1919 					if (test_mode == TDES_MODE_ECB) {
1920 						memcpy(vec.pt.val, val[0].val,
1921 							   TDES_BLOCK_SIZE);
1922 					} else {
1923 						memcpy(vec.pt.val, vec.iv.val,
1924 							   TDES_BLOCK_SIZE);
1925 						memcpy(vec.iv.val, val[0].val,
1926 							   TDES_BLOCK_SIZE);
1927 					}
1928 					val[1].val = pt.val;
1929 					val[1].len = pt.len;
1930 					val[2].val = iv.val;
1931 					val[2].len = iv.len;
1932 				} else {
1933 					if (test_mode == TDES_MODE_ECB) {
1934 						memcpy(vec.ct.val, val[0].val,
1935 							   TDES_BLOCK_SIZE);
1936 					} else {
1937 						memcpy(vec.iv.val, vec.ct.val,
1938 							   TDES_BLOCK_SIZE);
1939 						memcpy(vec.ct.val, val[0].val,
1940 							   TDES_BLOCK_SIZE);
1941 					}
1942 					val[1].val = ct.val;
1943 					val[1].len = ct.len;
1944 					val[2].val = iv.val;
1945 					val[2].len = iv.len;
1946 				}
1947 				continue;
1948 			}
1949 
1950 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1951 				if (test_mode == TDES_MODE_ECB) {
1952 					memcpy(vec.pt.val, val[0].val,
1953 						   TDES_BLOCK_SIZE);
1954 				} else {
1955 					memcpy(vec.iv.val, val[0].val,
1956 						   TDES_BLOCK_SIZE);
1957 					memcpy(vec.pt.val, prev_out,
1958 						   TDES_BLOCK_SIZE);
1959 				}
1960 			} else {
1961 				if (test_mode == TDES_MODE_ECB) {
1962 					memcpy(vec.ct.val, val[0].val,
1963 						   TDES_BLOCK_SIZE);
1964 				} else {
1965 					memcpy(vec.iv.val, vec.ct.val,
1966 						   TDES_BLOCK_SIZE);
1967 					memcpy(vec.ct.val, val[0].val,
1968 						   TDES_BLOCK_SIZE);
1969 				}
1970 			}
1971 
1972 			if (j == TDES_INTERN_ITER - 1)
1973 				continue;
1974 
1975 			memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
1976 
1977 			if (j == TDES_INTERN_ITER - 3)
1978 				memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE);
1979 		}
1980 
1981 		info.parse_writeback(val);
1982 		if (info.file_type != FIPS_TYPE_JSON)
1983 			fprintf(info.fp_wr, "\n");
1984 
1985 		if (i == TDES_EXTERN_ITER - 1)
1986 			continue;
1987 
1988 		/** update key */
1989 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
1990 
1991 		if (info.interim_info.tdes_data.nb_keys == 0) {
1992 			if (memcmp(val_key.val, val_key.val + 8, 8) == 0)
1993 				info.interim_info.tdes_data.nb_keys = 1;
1994 			else if (memcmp(val_key.val, val_key.val + 16, 8) == 0)
1995 				info.interim_info.tdes_data.nb_keys = 2;
1996 			else
1997 				info.interim_info.tdes_data.nb_keys = 3;
1998 
1999 		}
2000 
2001 		for (k = 0; k < TDES_BLOCK_SIZE; k++) {
2002 
2003 			switch (info.interim_info.tdes_data.nb_keys) {
2004 			case 3:
2005 				val_key.val[k] ^= val[0].val[k];
2006 				val_key.val[k + 8] ^= prev_out[k];
2007 				val_key.val[k + 16] ^= prev_prev_out[k];
2008 				break;
2009 			case 2:
2010 				val_key.val[k] ^= val[0].val[k];
2011 				val_key.val[k + 8] ^= prev_out[k];
2012 				val_key.val[k + 16] ^= val[0].val[k];
2013 				break;
2014 			default: /* case 1 */
2015 				val_key.val[k] ^= val[0].val[k];
2016 				val_key.val[k + 8] ^= val[0].val[k];
2017 				val_key.val[k + 16] ^= val[0].val[k];
2018 				break;
2019 			}
2020 
2021 		}
2022 
2023 		for (k = 0; k < 24; k++)
2024 			val_key.val[k] = (__builtin_popcount(val_key.val[k]) &
2025 					0x1) ?
2026 					val_key.val[k] : (val_key.val[k] ^ 0x1);
2027 
2028 		if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2029 			if (test_mode == TDES_MODE_ECB) {
2030 				memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE);
2031 			} else {
2032 				memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE);
2033 				memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
2034 			}
2035 		} else {
2036 			if (test_mode == TDES_MODE_ECB) {
2037 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
2038 			} else {
2039 				memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE);
2040 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
2041 			}
2042 		}
2043 	}
2044 
2045 	free(val[0].val);
2046 	free(pt.val);
2047 	free(ct.val);
2048 	free(iv.val);
2049 
2050 	return 0;
2051 }
2052 
2053 static int
2054 fips_mct_aes_ecb_test(void)
2055 {
2056 #define AES_BLOCK_SIZE	16
2057 #define AES_EXTERN_ITER	100
2058 #define AES_INTERN_ITER	1000
2059 	struct fips_val val = {NULL, 0}, val_key;
2060 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
2061 	uint32_t i, j, k;
2062 	int ret;
2063 
2064 	for (i = 0; i < AES_EXTERN_ITER; i++) {
2065 		if (i != 0)
2066 			update_info_vec(i);
2067 
2068 		fips_test_write_one_case();
2069 
2070 		for (j = 0; j < AES_INTERN_ITER; j++) {
2071 			ret = fips_run_test();
2072 			if (ret < 0) {
2073 				if (ret == -EPERM) {
2074 					if (info.file_type == FIPS_TYPE_JSON)
2075 						return ret;
2076 
2077 					fprintf(info.fp_wr, "Bypass\n");
2078 					return 0;
2079 				}
2080 
2081 				return ret;
2082 			}
2083 
2084 			ret = get_writeback_data(&val);
2085 			if (ret < 0)
2086 				return ret;
2087 
2088 			if (info.op == FIPS_TEST_ENC_AUTH_GEN)
2089 				memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE);
2090 			else
2091 				memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE);
2092 
2093 			if (j == AES_INTERN_ITER - 1)
2094 				continue;
2095 
2096 			memcpy(prev_out, val.val, AES_BLOCK_SIZE);
2097 		}
2098 
2099 		info.parse_writeback(&val);
2100 		fprintf(info.fp_wr, "\n");
2101 
2102 		if (i == AES_EXTERN_ITER - 1)
2103 			continue;
2104 
2105 		/** update key */
2106 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2107 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
2108 			switch (vec.cipher_auth.key.len) {
2109 			case 16:
2110 				val_key.val[k] ^= val.val[k];
2111 				break;
2112 			case 24:
2113 				if (k < 8)
2114 					val_key.val[k] ^= prev_out[k + 8];
2115 				else
2116 					val_key.val[k] ^= val.val[k - 8];
2117 				break;
2118 			case 32:
2119 				if (k < 16)
2120 					val_key.val[k] ^= prev_out[k];
2121 				else
2122 					val_key.val[k] ^= val.val[k - 16];
2123 				break;
2124 			default:
2125 				return -1;
2126 			}
2127 		}
2128 	}
2129 
2130 	free(val.val);
2131 
2132 	return 0;
2133 }
2134 static int
2135 fips_mct_aes_test(void)
2136 {
2137 #define AES_BLOCK_SIZE	16
2138 #define AES_EXTERN_ITER	100
2139 #define AES_INTERN_ITER	1000
2140 	struct fips_val val[3] = {{NULL, 0},}, val_key,  pt, ct, iv;
2141 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
2142 	uint8_t prev_in[AES_BLOCK_SIZE] = {0};
2143 	uint32_t i, j, k;
2144 	int ret;
2145 
2146 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB)
2147 		return fips_mct_aes_ecb_test();
2148 
2149 	pt.len = vec.pt.len;
2150 	pt.val = calloc(1, pt.len);
2151 	ct.len = vec.ct.len;
2152 	ct.val = calloc(1, ct.len);
2153 	iv.len = vec.iv.len;
2154 	iv.val = calloc(1, iv.len);
2155 	for (i = 0; i < AES_EXTERN_ITER; i++) {
2156 		if (info.file_type != FIPS_TYPE_JSON) {
2157 			if (i != 0)
2158 				update_info_vec(i);
2159 
2160 			fips_test_write_one_case();
2161 		}
2162 
2163 		for (j = 0; j < AES_INTERN_ITER; j++) {
2164 			ret = fips_run_test();
2165 			if (ret < 0) {
2166 				if (ret == -EPERM) {
2167 					if (info.file_type == FIPS_TYPE_JSON)
2168 						return ret;
2169 
2170 					fprintf(info.fp_wr, "Bypass\n");
2171 					return 0;
2172 				}
2173 
2174 				return ret;
2175 			}
2176 
2177 			ret = get_writeback_data(&val[0]);
2178 			if (ret < 0)
2179 				return ret;
2180 
2181 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2182 				memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE);
2183 
2184 			if (j == 0) {
2185 				memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
2186 				memcpy(pt.val, vec.pt.val, pt.len);
2187 				memcpy(ct.val, vec.ct.val, ct.len);
2188 				memcpy(iv.val, vec.iv.val, iv.len);
2189 
2190 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
2191 					memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE);
2192 					memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2193 					val[1].val = pt.val;
2194 					val[1].len = pt.len;
2195 					val[2].val = iv.val;
2196 					val[2].len = iv.len;
2197 				} else {
2198 					memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE);
2199 					memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
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 				memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2210 				memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE);
2211 			} else {
2212 				memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
2213 				memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE);
2214 			}
2215 
2216 			if (j == AES_INTERN_ITER - 1)
2217 				continue;
2218 
2219 			memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
2220 		}
2221 
2222 		info.parse_writeback(val);
2223 		if (info.file_type != FIPS_TYPE_JSON)
2224 			fprintf(info.fp_wr, "\n");
2225 
2226 		if (i == AES_EXTERN_ITER - 1)
2227 			continue;
2228 
2229 		/** update key */
2230 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
2231 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
2232 			switch (vec.cipher_auth.key.len) {
2233 			case 16:
2234 				val_key.val[k] ^= val[0].val[k];
2235 				break;
2236 			case 24:
2237 				if (k < 8)
2238 					val_key.val[k] ^= prev_out[k + 8];
2239 				else
2240 					val_key.val[k] ^= val[0].val[k - 8];
2241 				break;
2242 			case 32:
2243 				if (k < 16)
2244 					val_key.val[k] ^= prev_out[k];
2245 				else
2246 					val_key.val[k] ^= val[0].val[k - 16];
2247 				break;
2248 			default:
2249 				return -1;
2250 			}
2251 		}
2252 
2253 		if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
2254 			memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
2255 	}
2256 
2257 	free(val[0].val);
2258 	free(pt.val);
2259 	free(ct.val);
2260 	free(iv.val);
2261 
2262 	return 0;
2263 }
2264 
2265 static int
2266 fips_mct_sha_test(void)
2267 {
2268 #define SHA_EXTERN_ITER	100
2269 #define SHA_INTERN_ITER	1000
2270 #define SHA_MD_BLOCK	3
2271 	/* val[0] is op result and other value is for parse_writeback callback */
2272 	struct fips_val val[2] = {{NULL, 0},};
2273 	struct fips_val  md[SHA_MD_BLOCK], msg;
2274 	int ret;
2275 	uint32_t i, j;
2276 
2277 	msg.len = SHA_MD_BLOCK * vec.cipher_auth.digest.len;
2278 	msg.val = calloc(1, msg.len);
2279 	if (vec.pt.val)
2280 		memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len);
2281 
2282 	for (i = 0; i < SHA_MD_BLOCK; i++)
2283 		md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0);
2284 
2285 	rte_free(vec.pt.val);
2286 	vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0);
2287 
2288 	if (info.file_type != FIPS_TYPE_JSON) {
2289 		fips_test_write_one_case();
2290 		fprintf(info.fp_wr, "\n");
2291 	}
2292 
2293 	for (j = 0; j < SHA_EXTERN_ITER; j++) {
2294 
2295 		memcpy(md[0].val, vec.cipher_auth.digest.val,
2296 			vec.cipher_auth.digest.len);
2297 		md[0].len = vec.cipher_auth.digest.len;
2298 		memcpy(md[1].val, vec.cipher_auth.digest.val,
2299 			vec.cipher_auth.digest.len);
2300 		md[1].len = vec.cipher_auth.digest.len;
2301 		memcpy(md[2].val, vec.cipher_auth.digest.val,
2302 			vec.cipher_auth.digest.len);
2303 		md[2].len = vec.cipher_auth.digest.len;
2304 
2305 		for (i = 0; i < SHA_MD_BLOCK; i++)
2306 			memcpy(&msg.val[i * md[i].len], md[i].val, md[i].len);
2307 
2308 		for (i = 0; i < (SHA_INTERN_ITER); i++) {
2309 
2310 			memcpy(vec.pt.val, md[0].val,
2311 				(size_t)md[0].len);
2312 			memcpy((vec.pt.val + md[0].len), md[1].val,
2313 				(size_t)md[1].len);
2314 			memcpy((vec.pt.val + md[0].len + md[1].len),
2315 				md[2].val,
2316 				(size_t)md[2].len);
2317 			vec.pt.len = md[0].len + md[1].len + md[2].len;
2318 
2319 			ret = fips_run_test();
2320 			if (ret < 0) {
2321 				if (ret == -EPERM || ret == -ENOTSUP) {
2322 					if (info.file_type == FIPS_TYPE_JSON)
2323 						return ret;
2324 
2325 					fprintf(info.fp_wr, "Bypass\n\n");
2326 					return 0;
2327 				}
2328 				return ret;
2329 			}
2330 
2331 			ret = get_writeback_data(&val[0]);
2332 			if (ret < 0)
2333 				return ret;
2334 
2335 			memcpy(md[0].val, md[1].val, md[1].len);
2336 			md[0].len = md[1].len;
2337 			memcpy(md[1].val, md[2].val, md[2].len);
2338 			md[1].len = md[2].len;
2339 
2340 			memcpy(md[2].val, (val[0].val + vec.pt.len),
2341 				vec.cipher_auth.digest.len);
2342 			md[2].len = vec.cipher_auth.digest.len;
2343 		}
2344 
2345 		memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len);
2346 		vec.cipher_auth.digest.len = md[2].len;
2347 
2348 		if (info.file_type != FIPS_TYPE_JSON)
2349 			fprintf(info.fp_wr, "COUNT = %u\n", j);
2350 
2351 		val[1].val = msg.val;
2352 		val[1].len = msg.len;
2353 		info.parse_writeback(val);
2354 
2355 		if (info.file_type != FIPS_TYPE_JSON)
2356 			fprintf(info.fp_wr, "\n");
2357 	}
2358 
2359 	for (i = 0; i < (SHA_MD_BLOCK); i++)
2360 		rte_free(md[i].val);
2361 
2362 	rte_free(vec.pt.val);
2363 
2364 	free(val[0].val);
2365 	free(msg.val);
2366 
2367 	return 0;
2368 }
2369 
2370 
2371 static int
2372 init_test_ops(void)
2373 {
2374 	switch (info.algo) {
2375 	case FIPS_TEST_ALGO_AES_CBC:
2376 	case FIPS_TEST_ALGO_AES_CTR:
2377 	case FIPS_TEST_ALGO_AES:
2378 		test_ops.prepare_sym_op = prepare_cipher_op;
2379 		test_ops.prepare_sym_xform  = prepare_aes_xform;
2380 		if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)
2381 			test_ops.test = fips_mct_aes_test;
2382 		else
2383 			test_ops.test = fips_generic_test;
2384 		break;
2385 	case FIPS_TEST_ALGO_HMAC:
2386 		test_ops.prepare_sym_op = prepare_auth_op;
2387 		test_ops.prepare_sym_xform = prepare_hmac_xform;
2388 		test_ops.test = fips_generic_test;
2389 		break;
2390 	case FIPS_TEST_ALGO_TDES:
2391 		test_ops.prepare_sym_op = prepare_cipher_op;
2392 		test_ops.prepare_sym_xform = prepare_tdes_xform;
2393 		if (info.interim_info.tdes_data.test_type == TDES_MCT)
2394 			test_ops.test = fips_mct_tdes_test;
2395 		else
2396 			test_ops.test = fips_generic_test;
2397 		break;
2398 	case FIPS_TEST_ALGO_AES_GMAC:
2399 		test_ops.prepare_sym_op = prepare_auth_op;
2400 		test_ops.prepare_sym_xform = prepare_gmac_xform;
2401 		test_ops.test = fips_generic_test;
2402 		break;
2403 	case FIPS_TEST_ALGO_AES_GCM:
2404 		test_ops.prepare_sym_op = prepare_aead_op;
2405 		test_ops.prepare_sym_xform = prepare_gcm_xform;
2406 		test_ops.test = fips_generic_test;
2407 		break;
2408 	case FIPS_TEST_ALGO_AES_CMAC:
2409 		test_ops.prepare_sym_op = prepare_auth_op;
2410 		test_ops.prepare_sym_xform = prepare_cmac_xform;
2411 		test_ops.test = fips_generic_test;
2412 		break;
2413 	case FIPS_TEST_ALGO_AES_CCM:
2414 		test_ops.prepare_sym_op = prepare_aead_op;
2415 		test_ops.prepare_sym_xform = prepare_ccm_xform;
2416 		test_ops.test = fips_generic_test;
2417 		break;
2418 	case FIPS_TEST_ALGO_SHA:
2419 		test_ops.prepare_sym_op = prepare_auth_op;
2420 		test_ops.prepare_sym_xform = prepare_sha_xform;
2421 		if (info.interim_info.sha_data.test_type == SHA_MCT)
2422 			test_ops.test = fips_mct_sha_test;
2423 		else
2424 			test_ops.test = fips_generic_test;
2425 		break;
2426 	case FIPS_TEST_ALGO_AES_XTS:
2427 		test_ops.prepare_sym_op = prepare_cipher_op;
2428 		test_ops.prepare_sym_xform = prepare_xts_xform;
2429 		test_ops.test = fips_generic_test;
2430 		break;
2431 	case FIPS_TEST_ALGO_RSA:
2432 		test_ops.prepare_asym_op = prepare_rsa_op;
2433 		test_ops.prepare_asym_xform = prepare_rsa_xform;
2434 		test_ops.test = fips_generic_test;
2435 		break;
2436 	case FIPS_TEST_ALGO_ECDSA:
2437 		if (info.op == FIPS_TEST_ASYM_KEYGEN) {
2438 			test_ops.prepare_asym_op = prepare_ecfpm_op;
2439 			test_ops.prepare_asym_xform = prepare_ecfpm_xform;
2440 			test_ops.test = fips_generic_test;
2441 		} else {
2442 			test_ops.prepare_asym_op = prepare_ecdsa_op;
2443 			test_ops.prepare_asym_xform = prepare_ecdsa_xform;
2444 			test_ops.test = fips_generic_test;
2445 		}
2446 		break;
2447 	default:
2448 		if (strstr(info.file_name, "TECB") ||
2449 				strstr(info.file_name, "TCBC")) {
2450 			info.algo = FIPS_TEST_ALGO_TDES;
2451 			test_ops.prepare_sym_op = prepare_cipher_op;
2452 			test_ops.prepare_sym_xform = prepare_tdes_xform;
2453 			if (info.interim_info.tdes_data.test_type == TDES_MCT)
2454 				test_ops.test = fips_mct_tdes_test;
2455 			else
2456 				test_ops.test = fips_generic_test;
2457 			break;
2458 		}
2459 		return -1;
2460 	}
2461 
2462 	return 0;
2463 }
2464 
2465 static void
2466 print_test_block(void)
2467 {
2468 	uint32_t i;
2469 
2470 	for (i = 0; i < info.nb_vec_lines; i++)
2471 		printf("%s\n", info.vec[i]);
2472 
2473 	printf("\n");
2474 }
2475 
2476 static int
2477 fips_test_one_file(void)
2478 {
2479 	int fetch_ret = 0, ret;
2480 
2481 	ret = init_test_ops();
2482 	if (ret < 0) {
2483 		RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret);
2484 		return ret;
2485 	}
2486 
2487 	while (ret >= 0 && fetch_ret == 0) {
2488 		fetch_ret = fips_test_fetch_one_block();
2489 		if (fetch_ret < 0) {
2490 			RTE_LOG(ERR, USER1, "Error %i: Fetch block\n",
2491 					fetch_ret);
2492 			ret = fetch_ret;
2493 			goto error_one_case;
2494 		}
2495 
2496 		if (info.nb_vec_lines == 0) {
2497 			if (fetch_ret == -EOF)
2498 				break;
2499 
2500 			fprintf(info.fp_wr, "\n");
2501 			continue;
2502 		}
2503 
2504 		ret = fips_test_parse_one_case();
2505 		switch (ret) {
2506 		case 0:
2507 			ret = test_ops.test();
2508 			if (ret == 0)
2509 				break;
2510 			RTE_LOG(ERR, USER1, "Error %i: test block\n",
2511 					ret);
2512 			goto error_one_case;
2513 		case 1:
2514 			break;
2515 		default:
2516 			RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
2517 					ret);
2518 			goto error_one_case;
2519 		}
2520 
2521 		continue;
2522 error_one_case:
2523 		print_test_block();
2524 	}
2525 
2526 	fips_test_clear();
2527 
2528 	if (env.digest) {
2529 		rte_free(env.digest);
2530 		env.digest = NULL;
2531 	}
2532 	rte_pktmbuf_free(env.mbuf);
2533 
2534 	return ret;
2535 }
2536 
2537 #ifdef USE_JANSSON
2538 static int
2539 fips_test_json_init_writeback(void)
2540 {
2541 	json_t *session_info, *session_write;
2542 	session_info = json_array_get(json_info.json_root, 0);
2543 	session_write = json_object();
2544 	json_info.json_write_root = json_array();
2545 
2546 	json_object_set(session_write, "jwt",
2547 		json_object_get(session_info, "jwt"));
2548 	json_object_set(session_write, "url",
2549 		json_object_get(session_info, "url"));
2550 	json_object_set(session_write, "isSample",
2551 		json_object_get(session_info, "isSample"));
2552 
2553 	json_info.is_sample = json_boolean_value(
2554 		json_object_get(session_info, "isSample"));
2555 
2556 	json_array_append_new(json_info.json_write_root, session_write);
2557 	return 0;
2558 }
2559 
2560 static int
2561 fips_test_one_test_case(void)
2562 {
2563 	int ret;
2564 
2565 	ret = fips_test_parse_one_json_case();
2566 
2567 	switch (ret) {
2568 	case 0:
2569 		ret = test_ops.test();
2570 		if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP))
2571 			break;
2572 		RTE_LOG(ERR, USER1, "Error %i: test block\n",
2573 				ret);
2574 		break;
2575 	default:
2576 		RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
2577 				ret);
2578 	}
2579 	return ret;
2580 }
2581 
2582 static int
2583 fips_test_one_test_group(void)
2584 {
2585 	int ret;
2586 	json_t *tests, *write_tests;
2587 	size_t test_idx, tests_size;
2588 
2589 	write_tests = json_array();
2590 	json_info.json_write_group = json_object();
2591 	json_object_set(json_info.json_write_group, "tgId",
2592 		json_object_get(json_info.json_test_group, "tgId"));
2593 	json_object_set_new(json_info.json_write_group, "tests", write_tests);
2594 
2595 	switch (info.algo) {
2596 	case FIPS_TEST_ALGO_AES_GMAC:
2597 	case FIPS_TEST_ALGO_AES_GCM:
2598 		ret = parse_test_gcm_json_init();
2599 		break;
2600 	case FIPS_TEST_ALGO_HMAC:
2601 		ret = parse_test_hmac_json_init();
2602 		break;
2603 	case FIPS_TEST_ALGO_AES_CMAC:
2604 		ret = parse_test_cmac_json_init();
2605 		break;
2606 	case FIPS_TEST_ALGO_AES_XTS:
2607 		ret = parse_test_xts_json_init();
2608 		break;
2609 	case FIPS_TEST_ALGO_AES_CBC:
2610 	case FIPS_TEST_ALGO_AES_CTR:
2611 	case FIPS_TEST_ALGO_AES:
2612 		ret = parse_test_aes_json_init();
2613 		break;
2614 	case FIPS_TEST_ALGO_SHA:
2615 		ret = parse_test_sha_json_init();
2616 		break;
2617 	case FIPS_TEST_ALGO_TDES:
2618 		ret = parse_test_tdes_json_init();
2619 		break;
2620 	case FIPS_TEST_ALGO_RSA:
2621 		ret = parse_test_rsa_json_init();
2622 		break;
2623 	case FIPS_TEST_ALGO_ECDSA:
2624 		ret = parse_test_ecdsa_json_init();
2625 		break;
2626 	default:
2627 		return -EINVAL;
2628 	}
2629 
2630 	if (ret < 0)
2631 		return ret;
2632 
2633 	ret = fips_test_parse_one_json_group();
2634 	if (ret < 0)
2635 		return ret;
2636 
2637 	ret = init_test_ops();
2638 	if (ret < 0)
2639 		return ret;
2640 
2641 	tests = json_object_get(json_info.json_test_group, "tests");
2642 	tests_size = json_array_size(tests);
2643 	for (test_idx = 0; test_idx < tests_size; test_idx++) {
2644 		json_info.json_test_case = json_array_get(tests, test_idx);
2645 		if (fips_test_one_test_case() == 0)
2646 			json_array_append_new(write_tests, json_info.json_write_case);
2647 	}
2648 
2649 	return 0;
2650 }
2651 
2652 static int
2653 fips_test_one_vector_set(void)
2654 {
2655 	int ret;
2656 	json_t *test_groups, *write_groups, *write_version, *write_set, *mode;
2657 	size_t group_idx, num_groups;
2658 
2659 	test_groups = json_object_get(json_info.json_vector_set, "testGroups");
2660 	num_groups = json_array_size(test_groups);
2661 
2662 	json_info.json_write_set = json_array();
2663 	write_version = json_object();
2664 	json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION));
2665 	json_array_append_new(json_info.json_write_set, write_version);
2666 
2667 	write_set = json_object();
2668 	json_array_append(json_info.json_write_set, write_set);
2669 	write_groups = json_array();
2670 
2671 	json_object_set(write_set, "vsId",
2672 		json_object_get(json_info.json_vector_set, "vsId"));
2673 	json_object_set(write_set, "algorithm",
2674 		json_object_get(json_info.json_vector_set, "algorithm"));
2675 	mode = json_object_get(json_info.json_vector_set, "mode");
2676 	if (mode != NULL)
2677 		json_object_set_new(write_set, "mode", mode);
2678 
2679 	json_object_set(write_set, "revision",
2680 		json_object_get(json_info.json_vector_set, "revision"));
2681 	json_object_set_new(write_set, "isSample",
2682 		json_boolean(json_info.is_sample));
2683 	json_object_set_new(write_set, "testGroups", write_groups);
2684 
2685 	ret = fips_test_parse_one_json_vector_set();
2686 	if (ret < 0) {
2687 		RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n",
2688 			json_string_value(json_object_get(json_info.json_vector_set, "algorithm")));
2689 		return ret;
2690 	}
2691 
2692 	for (group_idx = 0; group_idx < num_groups; group_idx++) {
2693 		json_info.json_test_group = json_array_get(test_groups, group_idx);
2694 		ret = fips_test_one_test_group();
2695 		json_array_append_new(write_groups, json_info.json_write_group);
2696 	}
2697 
2698 	return 0;
2699 }
2700 
2701 static int
2702 fips_test_one_json_file(void)
2703 {
2704 	size_t vector_set_idx, root_size;
2705 
2706 	root_size = json_array_size(json_info.json_root);
2707 	fips_test_json_init_writeback();
2708 
2709 	for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) {
2710 		/* Vector set index starts at 1, the 0th index contains test session
2711 		 * information.
2712 		 */
2713 		json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx);
2714 		fips_test_one_vector_set();
2715 		json_array_append_new(json_info.json_write_root, json_info.json_write_set);
2716 		json_incref(json_info.json_write_set);
2717 	}
2718 
2719 	json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4));
2720 	json_decref(json_info.json_write_root);
2721 
2722 	return 0;
2723 }
2724 #endif /* USE_JANSSON */
2725