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