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