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