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