xref: /dpdk/examples/fips_validation/main.c (revision f9dfb59edbccae50e7c5508348aa2b4b84413048)
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 };
41 
42 struct fips_test_vector vec;
43 struct fips_test_interim_info info;
44 
45 #ifdef USE_JANSSON
46 struct fips_test_json_info json_info;
47 #endif /* USE_JANSSON */
48 
49 struct cryptodev_fips_validate_env {
50 	const char *req_path;
51 	const char *rsp_path;
52 	uint32_t is_path_folder;
53 	uint8_t dev_id;
54 	uint8_t dev_support_sgl;
55 	uint16_t mbuf_data_room;
56 	struct rte_mempool *mpool;
57 	struct rte_mempool *sess_mpool;
58 	struct rte_mempool *op_pool;
59 	struct rte_mbuf *mbuf;
60 	uint8_t *digest;
61 	uint16_t digest_len;
62 	struct rte_crypto_op *op;
63 	void *sess;
64 	uint16_t self_test;
65 	struct fips_dev_broken_test_config *broken_test_config;
66 } env;
67 
68 static int
69 cryptodev_fips_validate_app_int(void)
70 {
71 	struct rte_cryptodev_config conf = {rte_socket_id(), 1, 0};
72 	struct rte_cryptodev_qp_conf qp_conf = {128, NULL};
73 	struct rte_cryptodev_info dev_info;
74 	uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size(
75 			env.dev_id);
76 	uint32_t nb_mbufs = UINT16_MAX / env.mbuf_data_room + 1;
77 	int ret;
78 
79 	if (env.self_test) {
80 		ret = fips_dev_self_test(env.dev_id, env.broken_test_config);
81 		if (ret < 0) {
82 			rte_cryptodev_close(env.dev_id);
83 
84 			return ret;
85 		}
86 	}
87 
88 	ret = rte_cryptodev_configure(env.dev_id, &conf);
89 	if (ret < 0)
90 		return ret;
91 
92 	rte_cryptodev_info_get(env.dev_id, &dev_info);
93 	if (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)
94 		env.dev_support_sgl = 1;
95 	else
96 		env.dev_support_sgl = 0;
97 
98 	env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", nb_mbufs,
99 			0, 0, sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM +
100 			env.mbuf_data_room, rte_socket_id());
101 	if (!env.mpool)
102 		return ret;
103 
104 	ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
105 			rte_socket_id());
106 	if (ret < 0)
107 		return ret;
108 
109 	ret = -ENOMEM;
110 
111 	env.sess_mpool = rte_cryptodev_sym_session_pool_create(
112 			"FIPS_SESS_MEMPOOL", 16, sess_sz, 0, 0,
113 			rte_socket_id());
114 	if (!env.sess_mpool)
115 		goto error_exit;
116 
117 	env.op_pool = rte_crypto_op_pool_create(
118 			"FIPS_OP_POOL",
119 			RTE_CRYPTO_OP_TYPE_SYMMETRIC,
120 			1, 0,
121 			16,
122 			rte_socket_id());
123 	if (!env.op_pool)
124 		goto error_exit;
125 
126 	env.op = rte_crypto_op_alloc(env.op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
127 	if (!env.op)
128 		goto error_exit;
129 
130 	qp_conf.mp_session = env.sess_mpool;
131 
132 	ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
133 			rte_socket_id());
134 	if (ret < 0)
135 		goto error_exit;
136 
137 	ret = rte_cryptodev_start(env.dev_id);
138 	if (ret < 0)
139 		goto error_exit;
140 
141 	return 0;
142 
143 error_exit:
144 
145 	rte_mempool_free(env.mpool);
146 	rte_mempool_free(env.sess_mpool);
147 	rte_mempool_free(env.op_pool);
148 
149 	return ret;
150 }
151 
152 static void
153 cryptodev_fips_validate_app_uninit(void)
154 {
155 	rte_pktmbuf_free(env.mbuf);
156 	rte_crypto_op_free(env.op);
157 	rte_cryptodev_sym_session_free(env.dev_id, env.sess);
158 	rte_mempool_free(env.mpool);
159 	rte_mempool_free(env.sess_mpool);
160 	rte_mempool_free(env.op_pool);
161 }
162 
163 static int
164 fips_test_one_file(void);
165 
166 #ifdef USE_JANSSON
167 static int
168 fips_test_one_json_file(void);
169 #endif /* USE_JANSSON */
170 
171 static int
172 parse_cryptodev_arg(char *arg)
173 {
174 	int id = rte_cryptodev_get_dev_id(arg);
175 
176 	if (id < 0) {
177 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev name %s\n",
178 				id, arg);
179 		return id;
180 	}
181 
182 	env.dev_id = (uint8_t)id;
183 
184 	return 0;
185 }
186 
187 static int
188 parse_cryptodev_id_arg(char *arg)
189 {
190 	uint32_t cryptodev_id;
191 
192 	if (parser_read_uint32(&cryptodev_id, arg) < 0) {
193 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n",
194 				-EINVAL, arg);
195 		return -1;
196 	}
197 
198 
199 	if (!rte_cryptodev_is_valid_dev(cryptodev_id)) {
200 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n",
201 				cryptodev_id, arg);
202 		return -1;
203 	}
204 
205 	env.dev_id = (uint8_t)cryptodev_id;
206 
207 	return 0;
208 }
209 
210 static void
211 cryptodev_fips_validate_usage(const char *prgname)
212 {
213 	uint32_t def_mbuf_seg_size = DEF_MBUF_SEG_SIZE;
214 	printf("%s [EAL options] --\n"
215 		"  --%s: REQUEST-FILE-PATH\n"
216 		"  --%s: RESPONSE-FILE-PATH\n"
217 		"  --%s: indicating both paths are folders\n"
218 		"  --%s: mbuf dataroom size (default %u bytes)\n"
219 		"  --%s: CRYPTODEV-NAME\n"
220 		"  --%s: CRYPTODEV-ID-NAME\n"
221 		"  --%s: self test indicator\n"
222 		"  --%s: self broken test ID\n"
223 		"  --%s: self broken test direction\n",
224 		prgname, OPT_REQ_FILE_PATH, OPT_RSP_FILE_PATH,
225 		OPT_FOLDER, OPT_MBUF_DATAROOM, def_mbuf_seg_size,
226 		OPT_CRYPTODEV, OPT_CRYPTODEV_ID, OPT_CRYPTODEV_ST,
227 		OPT_CRYPTODEV_BK_ID, OPT_CRYPTODEV_BK_DIR_KEY);
228 }
229 
230 static int
231 cryptodev_fips_validate_parse_args(int argc, char **argv)
232 {
233 	int opt, ret;
234 	char *prgname = argv[0];
235 	char **argvopt;
236 	int option_index;
237 	struct option lgopts[] = {
238 		{OPT_REQ_FILE_PATH, required_argument,
239 				NULL, OPT_REQ_FILE_PATH_NUM},
240 		{OPT_RSP_FILE_PATH, required_argument,
241 				NULL, OPT_RSP_FILE_PATH_NUM},
242 		{OPT_FOLDER, no_argument,
243 				NULL, OPT_FOLDER_NUM},
244 		{OPT_MBUF_DATAROOM, required_argument,
245 				NULL, OPT_MBUF_DATAROOM_NUM},
246 		{OPT_CRYPTODEV, required_argument,
247 				NULL, OPT_CRYPTODEV_NUM},
248 		{OPT_CRYPTODEV_ID, required_argument,
249 				NULL, OPT_CRYPTODEV_ID_NUM},
250 		{OPT_CRYPTODEV_ST, no_argument,
251 				NULL, OPT_CRYPTODEV_ST_NUM},
252 		{OPT_CRYPTODEV_BK_ID, required_argument,
253 				NULL, OPT_CRYPTODEV_BK_ID_NUM},
254 		{OPT_CRYPTODEV_BK_DIR_KEY, required_argument,
255 				NULL, OPT_CRYPTODEV_BK_DIR_KEY_NUM},
256 		{NULL, 0, 0, 0}
257 	};
258 
259 	argvopt = argv;
260 
261 	env.mbuf_data_room = DEF_MBUF_SEG_SIZE;
262 	if (rte_cryptodev_count())
263 		env.dev_id = 0;
264 	else {
265 		cryptodev_fips_validate_usage(prgname);
266 		return -EINVAL;
267 	}
268 
269 	while ((opt = getopt_long(argc, argvopt, "s:",
270 				  lgopts, &option_index)) != EOF) {
271 
272 		switch (opt) {
273 		case OPT_REQ_FILE_PATH_NUM:
274 			env.req_path = optarg;
275 			break;
276 
277 		case OPT_RSP_FILE_PATH_NUM:
278 			env.rsp_path = optarg;
279 			break;
280 
281 		case OPT_FOLDER_NUM:
282 			env.is_path_folder = 1;
283 			break;
284 
285 		case OPT_CRYPTODEV_NUM:
286 			ret = parse_cryptodev_arg(optarg);
287 			if (ret < 0) {
288 				cryptodev_fips_validate_usage(prgname);
289 				return -EINVAL;
290 			}
291 			break;
292 
293 		case OPT_CRYPTODEV_ID_NUM:
294 			ret = parse_cryptodev_id_arg(optarg);
295 			if (ret < 0) {
296 				cryptodev_fips_validate_usage(prgname);
297 				return -EINVAL;
298 			}
299 			break;
300 
301 		case OPT_CRYPTODEV_ST_NUM:
302 			env.self_test = 1;
303 			break;
304 
305 		case OPT_CRYPTODEV_BK_ID_NUM:
306 			if (!env.broken_test_config) {
307 				env.broken_test_config = rte_malloc(
308 					NULL,
309 					sizeof(*env.broken_test_config),
310 					0);
311 				if (!env.broken_test_config)
312 					return -ENOMEM;
313 
314 				env.broken_test_config->expect_fail_dir =
315 					self_test_dir_enc_auth_gen;
316 			}
317 
318 			if (parser_read_uint32(
319 				&env.broken_test_config->expect_fail_test_idx,
320 					optarg) < 0) {
321 				rte_free(env.broken_test_config);
322 				cryptodev_fips_validate_usage(prgname);
323 				return -EINVAL;
324 			}
325 			break;
326 
327 		case OPT_CRYPTODEV_BK_DIR_KEY_NUM:
328 			if (!env.broken_test_config) {
329 				env.broken_test_config = rte_malloc(
330 					NULL,
331 					sizeof(*env.broken_test_config),
332 					0);
333 				if (!env.broken_test_config)
334 					return -ENOMEM;
335 
336 				env.broken_test_config->expect_fail_test_idx =
337 					0;
338 			}
339 
340 			if (strcmp(optarg, "enc") == 0)
341 				env.broken_test_config->expect_fail_dir =
342 					self_test_dir_enc_auth_gen;
343 			else if (strcmp(optarg, "dec")
344 					== 0)
345 				env.broken_test_config->expect_fail_dir =
346 					self_test_dir_dec_auth_verify;
347 			else {
348 				rte_free(env.broken_test_config);
349 				cryptodev_fips_validate_usage(prgname);
350 				return -EINVAL;
351 			}
352 			break;
353 
354 
355 		case OPT_MBUF_DATAROOM_NUM:
356 			if (parser_read_uint16(&env.mbuf_data_room,
357 					optarg) < 0) {
358 				cryptodev_fips_validate_usage(prgname);
359 				return -EINVAL;
360 			}
361 
362 			if (env.mbuf_data_room == 0) {
363 				cryptodev_fips_validate_usage(prgname);
364 				return -EINVAL;
365 			}
366 			break;
367 
368 		default:
369 			cryptodev_fips_validate_usage(prgname);
370 			return -EINVAL;
371 		}
372 	}
373 
374 	if ((env.req_path == NULL && env.rsp_path != NULL) ||
375 			(env.req_path != NULL && env.rsp_path == NULL)) {
376 		RTE_LOG(ERR, USER1, "Missing req path or rsp path\n");
377 		cryptodev_fips_validate_usage(prgname);
378 		return -EINVAL;
379 	}
380 
381 	if (env.req_path == NULL && env.self_test == 0) {
382 		RTE_LOG(ERR, USER1, "--self-test must be set if req path is missing\n");
383 		cryptodev_fips_validate_usage(prgname);
384 		return -EINVAL;
385 	}
386 
387 	return 0;
388 }
389 
390 int
391 main(int argc, char *argv[])
392 {
393 	int ret;
394 
395 	ret = rte_eal_init(argc, argv);
396 	if (ret < 0) {
397 		RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret);
398 		return -1;
399 	}
400 
401 	argc -= ret;
402 	argv += ret;
403 
404 	ret = cryptodev_fips_validate_parse_args(argc, argv);
405 	if (ret < 0)
406 		rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n");
407 
408 	ret = cryptodev_fips_validate_app_int();
409 	if (ret < 0) {
410 		RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret);
411 		return -1;
412 	}
413 
414 	if (env.req_path == NULL || env.rsp_path == NULL) {
415 		printf("No request, exit.\n");
416 		goto exit;
417 	}
418 
419 	if (!env.is_path_folder) {
420 		printf("Processing file %s... ", env.req_path);
421 
422 		ret = fips_test_init(env.req_path, env.rsp_path,
423 			rte_cryptodev_name_get(env.dev_id));
424 		if (ret < 0) {
425 			RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
426 					ret, env.req_path);
427 			goto exit;
428 		}
429 
430 #ifdef USE_JANSSON
431 		if (info.file_type == FIPS_TYPE_JSON) {
432 			ret = fips_test_one_json_file();
433 			json_decref(json_info.json_root);
434 		}  else {
435 			ret = fips_test_one_file();
436 		}
437 #else /* USE_JANSSON */
438 		ret = fips_test_one_file();
439 #endif /* USE_JANSSON */
440 
441 		if (ret < 0) {
442 			RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
443 					ret, env.req_path);
444 			goto exit;
445 		}
446 
447 		printf("Done\n");
448 
449 	} else {
450 		struct dirent *dir;
451 		DIR *d_req, *d_rsp;
452 		char req_path[1024];
453 		char rsp_path[1024];
454 
455 		d_req = opendir(env.req_path);
456 		if (!d_req) {
457 			RTE_LOG(ERR, USER1, "Error %i: Path %s not exist\n",
458 					-EINVAL, env.req_path);
459 			goto exit;
460 		}
461 
462 		d_rsp = opendir(env.rsp_path);
463 		if (!d_rsp) {
464 			ret = mkdir(env.rsp_path, 0700);
465 			if (ret == 0)
466 				d_rsp = opendir(env.rsp_path);
467 			else {
468 				RTE_LOG(ERR, USER1, "Error %i: Invalid %s\n",
469 						-EINVAL, env.rsp_path);
470 				goto exit;
471 			}
472 		}
473 		closedir(d_rsp);
474 
475 		while ((dir = readdir(d_req)) != NULL) {
476 			if (strstr(dir->d_name, "req") == NULL)
477 				continue;
478 
479 			snprintf(req_path, 1023, "%s/%s", env.req_path,
480 					dir->d_name);
481 			snprintf(rsp_path, 1023, "%s/%s", env.rsp_path,
482 					dir->d_name);
483 			strlcpy(strstr(rsp_path, "req"), "rsp", 4);
484 
485 			printf("Processing file %s... ", req_path);
486 
487 			ret = fips_test_init(req_path, rsp_path,
488 			rte_cryptodev_name_get(env.dev_id));
489 			if (ret < 0) {
490 				RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
491 						ret, req_path);
492 				break;
493 			}
494 
495 #ifdef USE_JANSSON
496 			if (info.file_type == FIPS_TYPE_JSON) {
497 				ret = fips_test_one_json_file();
498 				json_decref(json_info.json_root);
499 			} else {
500 				ret = fips_test_one_file();
501 			}
502 #else /* USE_JANSSON */
503 			ret = fips_test_one_file();
504 #endif /* USE_JANSSON */
505 
506 			if (ret < 0) {
507 				RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
508 						ret, req_path);
509 				break;
510 			}
511 
512 			printf("Done\n");
513 		}
514 
515 		closedir(d_req);
516 	}
517 
518 
519 exit:
520 	fips_test_clear();
521 	cryptodev_fips_validate_app_uninit();
522 
523 	/* clean up the EAL */
524 	rte_eal_cleanup();
525 
526 	return ret;
527 
528 }
529 
530 #define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
531 #define CRYPTODEV_FIPS_MAX_RETRIES	16
532 
533 struct fips_test_ops test_ops;
534 
535 static int
536 prepare_data_mbufs(struct fips_val *val)
537 {
538 	struct rte_mbuf *m, *head = 0;
539 	uint8_t *src = val->val;
540 	uint32_t total_len = val->len;
541 	uint16_t nb_seg;
542 	int ret = 0;
543 
544 	rte_pktmbuf_free(env.mbuf);
545 
546 	if (total_len > RTE_MBUF_MAX_NB_SEGS) {
547 		RTE_LOG(ERR, USER1, "Data len %u too big\n", total_len);
548 		return -EPERM;
549 	}
550 
551 	nb_seg = total_len / env.mbuf_data_room;
552 	if (total_len % env.mbuf_data_room)
553 		nb_seg++;
554 
555 	m = rte_pktmbuf_alloc(env.mpool);
556 	if (!m) {
557 		RTE_LOG(ERR, USER1, "Error %i: Not enough mbuf\n",
558 				-ENOMEM);
559 		return -ENOMEM;
560 	}
561 	head = m;
562 
563 	while (nb_seg) {
564 		uint16_t len = RTE_MIN(total_len, env.mbuf_data_room);
565 		uint8_t *dst = (uint8_t *)rte_pktmbuf_append(m, len);
566 
567 		if (!dst) {
568 			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
569 					-ENOMEM);
570 			ret = -ENOMEM;
571 			goto error_exit;
572 		}
573 
574 		memcpy(dst, src, len);
575 
576 		if (head != m) {
577 			ret = rte_pktmbuf_chain(head, m);
578 			if (ret) {
579 				rte_pktmbuf_free(m);
580 				RTE_LOG(ERR, USER1, "Error %i: SGL build\n",
581 						ret);
582 				goto error_exit;
583 			}
584 		}
585 		total_len -= len;
586 
587 		if (total_len) {
588 			if (!env.dev_support_sgl) {
589 				RTE_LOG(ERR, USER1, "SGL not supported\n");
590 				ret = -EPERM;
591 				goto error_exit;
592 			}
593 
594 			m = rte_pktmbuf_alloc(env.mpool);
595 			if (!m) {
596 				RTE_LOG(ERR, USER1, "Error %i: No memory\n",
597 						-ENOMEM);
598 				goto error_exit;
599 			}
600 		} else
601 			break;
602 
603 		src += len;
604 		nb_seg--;
605 	}
606 
607 	if (total_len) {
608 		RTE_LOG(ERR, USER1, "Error %i: Failed to store all data\n",
609 				-ENOMEM);
610 		goto error_exit;
611 	}
612 
613 	env.mbuf = head;
614 
615 	return 0;
616 
617 error_exit:
618 	rte_pktmbuf_free(head);
619 	return ret;
620 }
621 
622 static int
623 prepare_cipher_op(void)
624 {
625 	struct rte_crypto_sym_op *sym = env.op->sym;
626 	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
627 	int ret;
628 
629 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
630 
631 	memcpy(iv, vec.iv.val, vec.iv.len);
632 
633 	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
634 		ret = prepare_data_mbufs(&vec.pt);
635 		if (ret < 0)
636 			return ret;
637 
638 		sym->cipher.data.length = vec.pt.len;
639 	} else {
640 		ret = prepare_data_mbufs(&vec.ct);
641 		if (ret < 0)
642 			return ret;
643 
644 		sym->cipher.data.length = vec.ct.len;
645 	}
646 
647 	rte_crypto_op_attach_sym_session(env.op, env.sess);
648 
649 	sym->m_src = env.mbuf;
650 	sym->cipher.data.offset = 0;
651 
652 	return 0;
653 }
654 
655 int
656 prepare_auth_op(void)
657 {
658 	struct rte_crypto_sym_op *sym = env.op->sym;
659 	int ret;
660 
661 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
662 
663 	if (info.interim_info.gcm_data.gen_iv == 1) {
664 		uint32_t i;
665 
666 		if (!vec.iv.val) {
667 			vec.iv.val = rte_malloc(0, vec.iv.len, 0);
668 			if (!vec.iv.val)
669 				return -ENOMEM;
670 		}
671 
672 		for (i = 0; i < vec.iv.len; i++) {
673 			int random = rand();
674 			vec.iv.val[i] = (uint8_t)random;
675 		}
676 	}
677 
678 	if (vec.iv.len) {
679 		uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *,
680 				IV_OFF);
681 		memset(iv, 0, vec.iv.len);
682 		if (vec.iv.val)
683 			memcpy(iv, vec.iv.val, vec.iv.len);
684 	}
685 
686 	ret = prepare_data_mbufs(&vec.pt);
687 	if (ret < 0)
688 		return ret;
689 
690 	rte_free(env.digest);
691 
692 	env.digest = rte_zmalloc(NULL, vec.cipher_auth.digest.len,
693 			RTE_CACHE_LINE_SIZE);
694 	if (!env.digest) {
695 		RTE_LOG(ERR, USER1, "Not enough memory\n");
696 		return -ENOMEM;
697 	}
698 	env.digest_len = vec.cipher_auth.digest.len;
699 
700 	sym->m_src = env.mbuf;
701 	sym->auth.data.offset = 0;
702 	sym->auth.data.length = vec.pt.len;
703 	sym->auth.digest.data = env.digest;
704 	sym->auth.digest.phys_addr = rte_malloc_virt2iova(env.digest);
705 
706 	if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
707 		memcpy(env.digest, vec.cipher_auth.digest.val,
708 				vec.cipher_auth.digest.len);
709 
710 	rte_crypto_op_attach_sym_session(env.op, env.sess);
711 
712 	return 0;
713 }
714 
715 int
716 prepare_aead_op(void)
717 {
718 	struct rte_crypto_sym_op *sym = env.op->sym;
719 	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
720 	int ret;
721 
722 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
723 
724 	if (info.algo == FIPS_TEST_ALGO_AES_CCM)
725 		iv++;
726 
727 	if (vec.iv.val)
728 		memcpy(iv, vec.iv.val, vec.iv.len);
729 	else
730 		/* if REQ file has iv length but not data, default as all 0 */
731 		memset(iv, 0, vec.iv.len);
732 
733 	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
734 		ret = prepare_data_mbufs(&vec.pt);
735 		if (ret < 0)
736 			return ret;
737 
738 		rte_free(env.digest);
739 		env.digest = rte_zmalloc(NULL, vec.aead.digest.len,
740 				RTE_CACHE_LINE_SIZE);
741 		if (!env.digest) {
742 			RTE_LOG(ERR, USER1, "Not enough memory\n");
743 			return -ENOMEM;
744 		}
745 		env.digest_len = vec.cipher_auth.digest.len;
746 
747 		sym->aead.data.length = vec.pt.len;
748 		sym->aead.digest.data = env.digest;
749 		sym->aead.digest.phys_addr = rte_malloc_virt2iova(env.digest);
750 	} else {
751 		ret = prepare_data_mbufs(&vec.ct);
752 		if (ret < 0)
753 			return ret;
754 
755 		sym->aead.data.length = vec.ct.len;
756 		sym->aead.digest.data = vec.aead.digest.val;
757 		sym->aead.digest.phys_addr = rte_malloc_virt2iova(
758 				sym->aead.digest.data);
759 	}
760 
761 	sym->m_src = env.mbuf;
762 	sym->aead.data.offset = 0;
763 	sym->aead.aad.data = vec.aead.aad.val;
764 	sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data);
765 
766 	rte_crypto_op_attach_sym_session(env.op, env.sess);
767 
768 	return 0;
769 }
770 
771 static int
772 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
773 {
774 	const struct rte_cryptodev_symmetric_capability *cap;
775 	struct rte_cryptodev_sym_capability_idx cap_idx;
776 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
777 
778 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
779 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC)
780 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC;
781 	else if (info.interim_info.aes_data.cipher_algo ==
782 			RTE_CRYPTO_CIPHER_AES_CTR)
783 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CTR;
784 	else
785 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB;
786 
787 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
788 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
789 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
790 	cipher_xform->key.data = vec.cipher_auth.key.val;
791 	cipher_xform->key.length = vec.cipher_auth.key.len;
792 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC ||
793 			cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CTR) {
794 		cipher_xform->iv.length = vec.iv.len;
795 		cipher_xform->iv.offset = IV_OFF;
796 	} else {
797 		cipher_xform->iv.length = 0;
798 		cipher_xform->iv.offset = 0;
799 	}
800 	cap_idx.algo.cipher = cipher_xform->algo;
801 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
802 
803 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
804 	if (!cap) {
805 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
806 				env.dev_id);
807 		return -EINVAL;
808 	}
809 
810 	if (rte_cryptodev_sym_capability_check_cipher(cap,
811 			cipher_xform->key.length,
812 			cipher_xform->iv.length) != 0) {
813 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
814 				info.device_name, cipher_xform->key.length,
815 				cipher_xform->iv.length);
816 		return -EPERM;
817 	}
818 
819 	return 0;
820 }
821 
822 static int
823 prepare_tdes_xform(struct rte_crypto_sym_xform *xform)
824 {
825 	const struct rte_cryptodev_symmetric_capability *cap;
826 	struct rte_cryptodev_sym_capability_idx cap_idx;
827 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
828 
829 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
830 
831 	if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC)
832 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC;
833 	else
834 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB;
835 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
836 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
837 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
838 	cipher_xform->key.data = vec.cipher_auth.key.val;
839 	cipher_xform->key.length = vec.cipher_auth.key.len;
840 
841 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
842 		cipher_xform->iv.length = vec.iv.len;
843 		cipher_xform->iv.offset = IV_OFF;
844 	} else {
845 		cipher_xform->iv.length = 0;
846 		cipher_xform->iv.offset = 0;
847 	}
848 	cap_idx.algo.cipher = cipher_xform->algo;
849 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
850 
851 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
852 	if (!cap) {
853 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
854 				env.dev_id);
855 		return -EINVAL;
856 	}
857 
858 	if (rte_cryptodev_sym_capability_check_cipher(cap,
859 			cipher_xform->key.length,
860 			cipher_xform->iv.length) != 0) {
861 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
862 				info.device_name, cipher_xform->key.length,
863 				cipher_xform->iv.length);
864 		return -EPERM;
865 	}
866 
867 	return 0;
868 }
869 
870 static int
871 prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
872 {
873 	const struct rte_cryptodev_symmetric_capability *cap;
874 	struct rte_cryptodev_sym_capability_idx cap_idx;
875 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
876 
877 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
878 
879 	auth_xform->algo = info.interim_info.hmac_data.algo;
880 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
881 	auth_xform->digest_length = vec.cipher_auth.digest.len;
882 	auth_xform->key.data = vec.cipher_auth.key.val;
883 	auth_xform->key.length = vec.cipher_auth.key.len;
884 
885 	cap_idx.algo.auth = auth_xform->algo;
886 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
887 
888 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
889 	if (!cap) {
890 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
891 				env.dev_id);
892 		return -EINVAL;
893 	}
894 
895 	if (rte_cryptodev_sym_capability_check_auth(cap,
896 			auth_xform->key.length,
897 			auth_xform->digest_length, 0) != 0) {
898 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
899 				info.device_name, auth_xform->key.length,
900 				auth_xform->digest_length);
901 		return -EPERM;
902 	}
903 
904 	return 0;
905 }
906 
907 int
908 prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
909 {
910 	const struct rte_cryptodev_symmetric_capability *cap;
911 	struct rte_cryptodev_sym_capability_idx cap_idx;
912 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
913 
914 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
915 
916 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
917 	aead_xform->aad_length = vec.aead.aad.len;
918 	aead_xform->digest_length = vec.aead.digest.len;
919 	aead_xform->iv.offset = IV_OFF;
920 	aead_xform->iv.length = vec.iv.len;
921 	aead_xform->key.data = vec.aead.key.val;
922 	aead_xform->key.length = vec.aead.key.len;
923 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
924 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
925 			RTE_CRYPTO_AEAD_OP_DECRYPT;
926 
927 	cap_idx.algo.aead = aead_xform->algo;
928 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
929 
930 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
931 	if (!cap) {
932 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
933 				env.dev_id);
934 		return -EINVAL;
935 	}
936 
937 	if (rte_cryptodev_sym_capability_check_aead(cap,
938 			aead_xform->key.length,
939 			aead_xform->digest_length, aead_xform->aad_length,
940 			aead_xform->iv.length) != 0) {
941 		RTE_LOG(ERR, USER1,
942 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
943 				info.device_name, aead_xform->key.length,
944 				aead_xform->digest_length,
945 				aead_xform->aad_length,
946 				aead_xform->iv.length);
947 		return -EPERM;
948 	}
949 
950 	return 0;
951 }
952 
953 int
954 prepare_gmac_xform(struct rte_crypto_sym_xform *xform)
955 {
956 	const struct rte_cryptodev_symmetric_capability *cap;
957 	struct rte_cryptodev_sym_capability_idx cap_idx;
958 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
959 
960 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
961 
962 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC;
963 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
964 			RTE_CRYPTO_AUTH_OP_GENERATE :
965 			RTE_CRYPTO_AUTH_OP_VERIFY;
966 	auth_xform->iv.offset = IV_OFF;
967 	auth_xform->iv.length = vec.iv.len;
968 	auth_xform->digest_length = vec.aead.digest.len;
969 	auth_xform->key.data = vec.aead.key.val;
970 	auth_xform->key.length = vec.aead.key.len;
971 
972 	cap_idx.algo.auth = auth_xform->algo;
973 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
974 
975 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
976 	if (!cap) {
977 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
978 				env.dev_id);
979 		return -EINVAL;
980 	}
981 
982 	if (rte_cryptodev_sym_capability_check_auth(cap,
983 			auth_xform->key.length,
984 			auth_xform->digest_length,
985 			auth_xform->iv.length) != 0) {
986 
987 		RTE_LOG(ERR, USER1,
988 			"PMD %s key length %u Digest length %u IV length %u\n",
989 				info.device_name, auth_xform->key.length,
990 				auth_xform->digest_length,
991 				auth_xform->iv.length);
992 		return -EPERM;
993 	}
994 
995 	return 0;
996 }
997 
998 static int
999 prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
1000 {
1001 	const struct rte_cryptodev_symmetric_capability *cap;
1002 	struct rte_cryptodev_sym_capability_idx cap_idx;
1003 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1004 
1005 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1006 
1007 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC;
1008 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1009 			RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY;
1010 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1011 	auth_xform->key.data = vec.cipher_auth.key.val;
1012 	auth_xform->key.length = vec.cipher_auth.key.len;
1013 
1014 	cap_idx.algo.auth = auth_xform->algo;
1015 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1016 
1017 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1018 	if (!cap) {
1019 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1020 				env.dev_id);
1021 		return -EINVAL;
1022 	}
1023 
1024 	if (rte_cryptodev_sym_capability_check_auth(cap,
1025 			auth_xform->key.length,
1026 			auth_xform->digest_length, 0) != 0) {
1027 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1028 				info.device_name, auth_xform->key.length,
1029 				auth_xform->digest_length);
1030 		return -EPERM;
1031 	}
1032 
1033 	return 0;
1034 }
1035 
1036 static int
1037 prepare_ccm_xform(struct rte_crypto_sym_xform *xform)
1038 {
1039 	const struct rte_cryptodev_symmetric_capability *cap;
1040 	struct rte_cryptodev_sym_capability_idx cap_idx;
1041 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
1042 
1043 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
1044 
1045 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM;
1046 	aead_xform->aad_length = vec.aead.aad.len;
1047 	aead_xform->digest_length = vec.aead.digest.len;
1048 	aead_xform->iv.offset = IV_OFF;
1049 	aead_xform->iv.length = vec.iv.len;
1050 	aead_xform->key.data = vec.aead.key.val;
1051 	aead_xform->key.length = vec.aead.key.len;
1052 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1053 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
1054 			RTE_CRYPTO_AEAD_OP_DECRYPT;
1055 
1056 	cap_idx.algo.aead = aead_xform->algo;
1057 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
1058 
1059 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1060 	if (!cap) {
1061 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1062 				env.dev_id);
1063 		return -EINVAL;
1064 	}
1065 
1066 	if (rte_cryptodev_sym_capability_check_aead(cap,
1067 			aead_xform->key.length,
1068 			aead_xform->digest_length, aead_xform->aad_length,
1069 			aead_xform->iv.length) != 0) {
1070 		RTE_LOG(ERR, USER1,
1071 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
1072 				info.device_name, aead_xform->key.length,
1073 				aead_xform->digest_length,
1074 				aead_xform->aad_length,
1075 				aead_xform->iv.length);
1076 		return -EPERM;
1077 	}
1078 
1079 	return 0;
1080 }
1081 
1082 static int
1083 prepare_sha_xform(struct rte_crypto_sym_xform *xform)
1084 {
1085 	const struct rte_cryptodev_symmetric_capability *cap;
1086 	struct rte_cryptodev_sym_capability_idx cap_idx;
1087 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
1088 
1089 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
1090 
1091 	auth_xform->algo = info.interim_info.sha_data.algo;
1092 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
1093 	auth_xform->digest_length = vec.cipher_auth.digest.len;
1094 
1095 	cap_idx.algo.auth = auth_xform->algo;
1096 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
1097 
1098 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1099 	if (!cap) {
1100 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1101 				env.dev_id);
1102 		return -EINVAL;
1103 	}
1104 
1105 	if (rte_cryptodev_sym_capability_check_auth(cap,
1106 			auth_xform->key.length,
1107 			auth_xform->digest_length, 0) != 0) {
1108 		RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n",
1109 				info.device_name, auth_xform->key.length,
1110 				auth_xform->digest_length);
1111 		return -EPERM;
1112 	}
1113 
1114 	return 0;
1115 }
1116 
1117 static int
1118 prepare_xts_xform(struct rte_crypto_sym_xform *xform)
1119 {
1120 	const struct rte_cryptodev_symmetric_capability *cap;
1121 	struct rte_cryptodev_sym_capability_idx cap_idx;
1122 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1123 
1124 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1125 
1126 	cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS;
1127 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1128 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1129 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1130 	cipher_xform->key.data = vec.cipher_auth.key.val;
1131 	cipher_xform->key.length = vec.cipher_auth.key.len;
1132 	cipher_xform->iv.length = vec.iv.len;
1133 	cipher_xform->iv.offset = IV_OFF;
1134 
1135 	cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS;
1136 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1137 
1138 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1139 	if (!cap) {
1140 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1141 				env.dev_id);
1142 		return -EINVAL;
1143 	}
1144 
1145 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1146 			cipher_xform->key.length,
1147 			cipher_xform->iv.length) != 0) {
1148 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1149 				info.device_name, cipher_xform->key.length,
1150 				cipher_xform->iv.length);
1151 		return -EPERM;
1152 	}
1153 
1154 	return 0;
1155 }
1156 
1157 static int
1158 get_writeback_data(struct fips_val *val)
1159 {
1160 	struct rte_mbuf *m = env.mbuf;
1161 	uint16_t data_len = rte_pktmbuf_pkt_len(m);
1162 	uint16_t total_len = data_len + env.digest_len;
1163 	uint8_t *src, *dst, *wb_data;
1164 
1165 	/* in case val is reused for MCT test, try to free the buffer first */
1166 	if (val->val) {
1167 		free(val->val);
1168 		val->val = NULL;
1169 	}
1170 
1171 	wb_data = dst = calloc(1, total_len);
1172 	if (!dst) {
1173 		RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM);
1174 		return -ENOMEM;
1175 	}
1176 
1177 	while (m && data_len) {
1178 		uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len);
1179 
1180 		src = rte_pktmbuf_mtod(m, uint8_t *);
1181 		memcpy(dst, src, seg_len);
1182 		m = m->next;
1183 		data_len -= seg_len;
1184 		dst += seg_len;
1185 	}
1186 
1187 	if (data_len) {
1188 		RTE_LOG(ERR, USER1, "Error -1: write back data\n");
1189 		free(wb_data);
1190 		return -1;
1191 	}
1192 
1193 	if (env.digest)
1194 		memcpy(dst, env.digest, env.digest_len);
1195 
1196 	val->val = wb_data;
1197 	val->len = total_len;
1198 
1199 	return 0;
1200 }
1201 
1202 static int
1203 fips_run_test(void)
1204 {
1205 	struct rte_crypto_sym_xform xform = {0};
1206 	uint16_t n_deqd;
1207 	int ret;
1208 
1209 	ret = test_ops.prepare_xform(&xform);
1210 	if (ret < 0)
1211 		return ret;
1212 
1213 	env.sess = rte_cryptodev_sym_session_create(env.dev_id, &xform,
1214 			env.sess_mpool);
1215 	if (!env.sess) {
1216 		RTE_LOG(ERR, USER1, "Error %i: Init session\n",
1217 				ret);
1218 		goto exit;
1219 	}
1220 
1221 	ret = test_ops.prepare_op();
1222 	if (ret < 0) {
1223 		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n",
1224 				ret);
1225 		goto exit;
1226 	}
1227 
1228 	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
1229 		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
1230 		ret = -1;
1231 		goto exit;
1232 	}
1233 
1234 	do {
1235 		struct rte_crypto_op *deqd_op;
1236 
1237 		n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op,
1238 				1);
1239 	} while (n_deqd == 0);
1240 
1241 	vec.status = env.op->status;
1242 
1243 exit:
1244 	if (env.sess) {
1245 		rte_cryptodev_sym_session_free(env.dev_id, env.sess);
1246 		env.sess = NULL;
1247 	}
1248 
1249 	return ret;
1250 }
1251 
1252 static int
1253 fips_generic_test(void)
1254 {
1255 	struct fips_val val = {NULL, 0};
1256 	int ret;
1257 
1258 	if (info.file_type != FIPS_TYPE_JSON)
1259 		fips_test_write_one_case();
1260 
1261 	ret = fips_run_test();
1262 	if (ret < 0) {
1263 		if (ret == -EPERM || ret == -ENOTSUP) {
1264 			if (info.file_type == FIPS_TYPE_JSON)
1265 				return ret;
1266 
1267 			fprintf(info.fp_wr, "Bypass\n\n");
1268 			return 0;
1269 		}
1270 
1271 		return ret;
1272 	}
1273 
1274 	ret = get_writeback_data(&val);
1275 	if (ret < 0)
1276 		return ret;
1277 
1278 	switch (info.file_type) {
1279 	case FIPS_TYPE_REQ:
1280 	case FIPS_TYPE_RSP:
1281 	case FIPS_TYPE_JSON:
1282 		if (info.parse_writeback == NULL)
1283 			return -EPERM;
1284 		ret = info.parse_writeback(&val);
1285 		if (ret < 0)
1286 			return ret;
1287 		break;
1288 	case FIPS_TYPE_FAX:
1289 		if (info.kat_check == NULL)
1290 			return -EPERM;
1291 		ret = info.kat_check(&val);
1292 		if (ret < 0)
1293 			return ret;
1294 		break;
1295 	default:
1296 		break;
1297 	}
1298 
1299 	if (info.file_type != FIPS_TYPE_JSON)
1300 		fprintf(info.fp_wr, "\n");
1301 	free(val.val);
1302 
1303 	return 0;
1304 }
1305 
1306 static int
1307 fips_mct_tdes_test(void)
1308 {
1309 #define TDES_BLOCK_SIZE		8
1310 #define TDES_EXTERN_ITER	400
1311 #define TDES_INTERN_ITER	10000
1312 	struct fips_val val[3] = {{NULL, 0},}, val_key, pt, ct, iv;
1313 	uint8_t prev_out[TDES_BLOCK_SIZE] = {0};
1314 	uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0};
1315 	uint8_t prev_in[TDES_BLOCK_SIZE] = {0};
1316 	uint32_t i, j, k;
1317 	int ret;
1318 	int test_mode = info.interim_info.tdes_data.test_mode;
1319 
1320 	pt.len = vec.pt.len;
1321 	pt.val = calloc(1, pt.len);
1322 	ct.len = vec.ct.len;
1323 	ct.val = calloc(1, ct.len);
1324 	iv.len = vec.iv.len;
1325 	iv.val = calloc(1, iv.len);
1326 
1327 	for (i = 0; i < TDES_EXTERN_ITER; i++) {
1328 		if (info.file_type != FIPS_TYPE_JSON) {
1329 			if ((i == 0) && (info.version == 21.4f)) {
1330 				if (!(strstr(info.vec[0], "COUNT")))
1331 					fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0);
1332 			}
1333 
1334 			if (i != 0)
1335 				update_info_vec(i);
1336 
1337 			fips_test_write_one_case();
1338 		}
1339 
1340 		for (j = 0; j < TDES_INTERN_ITER; j++) {
1341 			ret = fips_run_test();
1342 			if (ret < 0) {
1343 				if (ret == -EPERM) {
1344 					if (info.file_type == FIPS_TYPE_JSON)
1345 						return ret;
1346 
1347 					fprintf(info.fp_wr, "Bypass\n");
1348 					return 0;
1349 				}
1350 				return ret;
1351 			}
1352 
1353 			ret = get_writeback_data(&val[0]);
1354 			if (ret < 0)
1355 				return ret;
1356 
1357 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
1358 				memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE);
1359 
1360 			if (j == 0) {
1361 				memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
1362 				memcpy(pt.val, vec.pt.val, pt.len);
1363 				memcpy(ct.val, vec.ct.val, ct.len);
1364 				memcpy(iv.val, vec.iv.val, iv.len);
1365 
1366 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1367 					if (test_mode == TDES_MODE_ECB) {
1368 						memcpy(vec.pt.val, val[0].val,
1369 							   TDES_BLOCK_SIZE);
1370 					} else {
1371 						memcpy(vec.pt.val, vec.iv.val,
1372 							   TDES_BLOCK_SIZE);
1373 						memcpy(vec.iv.val, val[0].val,
1374 							   TDES_BLOCK_SIZE);
1375 					}
1376 					val[1].val = pt.val;
1377 					val[1].len = pt.len;
1378 					val[2].val = iv.val;
1379 					val[2].len = iv.len;
1380 				} else {
1381 					if (test_mode == TDES_MODE_ECB) {
1382 						memcpy(vec.ct.val, val[0].val,
1383 							   TDES_BLOCK_SIZE);
1384 					} else {
1385 						memcpy(vec.iv.val, vec.ct.val,
1386 							   TDES_BLOCK_SIZE);
1387 						memcpy(vec.ct.val, val[0].val,
1388 							   TDES_BLOCK_SIZE);
1389 					}
1390 					val[1].val = ct.val;
1391 					val[1].len = ct.len;
1392 					val[2].val = iv.val;
1393 					val[2].len = iv.len;
1394 				}
1395 				continue;
1396 			}
1397 
1398 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1399 				if (test_mode == TDES_MODE_ECB) {
1400 					memcpy(vec.pt.val, val[0].val,
1401 						   TDES_BLOCK_SIZE);
1402 				} else {
1403 					memcpy(vec.iv.val, val[0].val,
1404 						   TDES_BLOCK_SIZE);
1405 					memcpy(vec.pt.val, prev_out,
1406 						   TDES_BLOCK_SIZE);
1407 				}
1408 			} else {
1409 				if (test_mode == TDES_MODE_ECB) {
1410 					memcpy(vec.ct.val, val[0].val,
1411 						   TDES_BLOCK_SIZE);
1412 				} else {
1413 					memcpy(vec.iv.val, vec.ct.val,
1414 						   TDES_BLOCK_SIZE);
1415 					memcpy(vec.ct.val, val[0].val,
1416 						   TDES_BLOCK_SIZE);
1417 				}
1418 			}
1419 
1420 			if (j == TDES_INTERN_ITER - 1)
1421 				continue;
1422 
1423 			memcpy(prev_out, val[0].val, TDES_BLOCK_SIZE);
1424 
1425 			if (j == TDES_INTERN_ITER - 3)
1426 				memcpy(prev_prev_out, val[0].val, TDES_BLOCK_SIZE);
1427 		}
1428 
1429 		info.parse_writeback(val);
1430 		if (info.file_type != FIPS_TYPE_JSON)
1431 			fprintf(info.fp_wr, "\n");
1432 
1433 		if (i == TDES_EXTERN_ITER - 1)
1434 			continue;
1435 
1436 		/** update key */
1437 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
1438 
1439 		if (info.interim_info.tdes_data.nb_keys == 0) {
1440 			if (memcmp(val_key.val, val_key.val + 8, 8) == 0)
1441 				info.interim_info.tdes_data.nb_keys = 1;
1442 			else if (memcmp(val_key.val, val_key.val + 16, 8) == 0)
1443 				info.interim_info.tdes_data.nb_keys = 2;
1444 			else
1445 				info.interim_info.tdes_data.nb_keys = 3;
1446 
1447 		}
1448 
1449 		for (k = 0; k < TDES_BLOCK_SIZE; k++) {
1450 
1451 			switch (info.interim_info.tdes_data.nb_keys) {
1452 			case 3:
1453 				val_key.val[k] ^= val[0].val[k];
1454 				val_key.val[k + 8] ^= prev_out[k];
1455 				val_key.val[k + 16] ^= prev_prev_out[k];
1456 				break;
1457 			case 2:
1458 				val_key.val[k] ^= val[0].val[k];
1459 				val_key.val[k + 8] ^= prev_out[k];
1460 				val_key.val[k + 16] ^= val[0].val[k];
1461 				break;
1462 			default: /* case 1 */
1463 				val_key.val[k] ^= val[0].val[k];
1464 				val_key.val[k + 8] ^= val[0].val[k];
1465 				val_key.val[k + 16] ^= val[0].val[k];
1466 				break;
1467 			}
1468 
1469 		}
1470 
1471 		for (k = 0; k < 24; k++)
1472 			val_key.val[k] = (__builtin_popcount(val_key.val[k]) &
1473 					0x1) ?
1474 					val_key.val[k] : (val_key.val[k] ^ 0x1);
1475 
1476 		if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1477 			if (test_mode == TDES_MODE_ECB) {
1478 				memcpy(vec.pt.val, val[0].val, TDES_BLOCK_SIZE);
1479 			} else {
1480 				memcpy(vec.iv.val, val[0].val, TDES_BLOCK_SIZE);
1481 				memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
1482 			}
1483 		} else {
1484 			if (test_mode == TDES_MODE_ECB) {
1485 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
1486 			} else {
1487 				memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE);
1488 				memcpy(vec.ct.val, val[0].val, TDES_BLOCK_SIZE);
1489 			}
1490 		}
1491 	}
1492 
1493 	free(val[0].val);
1494 	free(pt.val);
1495 	free(ct.val);
1496 	free(iv.val);
1497 
1498 	return 0;
1499 }
1500 
1501 static int
1502 fips_mct_aes_ecb_test(void)
1503 {
1504 #define AES_BLOCK_SIZE	16
1505 #define AES_EXTERN_ITER	100
1506 #define AES_INTERN_ITER	1000
1507 	struct fips_val val = {NULL, 0}, val_key;
1508 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
1509 	uint32_t i, j, k;
1510 	int ret;
1511 
1512 	for (i = 0; i < AES_EXTERN_ITER; i++) {
1513 		if (i != 0)
1514 			update_info_vec(i);
1515 
1516 		fips_test_write_one_case();
1517 
1518 		for (j = 0; j < AES_INTERN_ITER; j++) {
1519 			ret = fips_run_test();
1520 			if (ret < 0) {
1521 				if (ret == -EPERM) {
1522 					if (info.file_type == FIPS_TYPE_JSON)
1523 						return ret;
1524 
1525 					fprintf(info.fp_wr, "Bypass\n");
1526 					return 0;
1527 				}
1528 
1529 				return ret;
1530 			}
1531 
1532 			ret = get_writeback_data(&val);
1533 			if (ret < 0)
1534 				return ret;
1535 
1536 			if (info.op == FIPS_TEST_ENC_AUTH_GEN)
1537 				memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE);
1538 			else
1539 				memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE);
1540 
1541 			if (j == AES_INTERN_ITER - 1)
1542 				continue;
1543 
1544 			memcpy(prev_out, val.val, AES_BLOCK_SIZE);
1545 		}
1546 
1547 		info.parse_writeback(&val);
1548 		fprintf(info.fp_wr, "\n");
1549 
1550 		if (i == AES_EXTERN_ITER - 1)
1551 			continue;
1552 
1553 		/** update key */
1554 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
1555 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
1556 			switch (vec.cipher_auth.key.len) {
1557 			case 16:
1558 				val_key.val[k] ^= val.val[k];
1559 				break;
1560 			case 24:
1561 				if (k < 8)
1562 					val_key.val[k] ^= prev_out[k + 8];
1563 				else
1564 					val_key.val[k] ^= val.val[k - 8];
1565 				break;
1566 			case 32:
1567 				if (k < 16)
1568 					val_key.val[k] ^= prev_out[k];
1569 				else
1570 					val_key.val[k] ^= val.val[k - 16];
1571 				break;
1572 			default:
1573 				return -1;
1574 			}
1575 		}
1576 	}
1577 
1578 	free(val.val);
1579 
1580 	return 0;
1581 }
1582 static int
1583 fips_mct_aes_test(void)
1584 {
1585 #define AES_BLOCK_SIZE	16
1586 #define AES_EXTERN_ITER	100
1587 #define AES_INTERN_ITER	1000
1588 	struct fips_val val[3] = {{NULL, 0},}, val_key,  pt, ct, iv;
1589 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
1590 	uint8_t prev_in[AES_BLOCK_SIZE] = {0};
1591 	uint32_t i, j, k;
1592 	int ret;
1593 
1594 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB)
1595 		return fips_mct_aes_ecb_test();
1596 
1597 	pt.len = vec.pt.len;
1598 	pt.val = calloc(1, pt.len);
1599 	ct.len = vec.ct.len;
1600 	ct.val = calloc(1, ct.len);
1601 	iv.len = vec.iv.len;
1602 	iv.val = calloc(1, iv.len);
1603 	for (i = 0; i < AES_EXTERN_ITER; i++) {
1604 		if (info.file_type != FIPS_TYPE_JSON) {
1605 			if (i != 0)
1606 				update_info_vec(i);
1607 
1608 			fips_test_write_one_case();
1609 		}
1610 
1611 		for (j = 0; j < AES_INTERN_ITER; j++) {
1612 			ret = fips_run_test();
1613 			if (ret < 0) {
1614 				if (ret == -EPERM) {
1615 					if (info.file_type == FIPS_TYPE_JSON)
1616 						return ret;
1617 
1618 					fprintf(info.fp_wr, "Bypass\n");
1619 					return 0;
1620 				}
1621 
1622 				return ret;
1623 			}
1624 
1625 			ret = get_writeback_data(&val[0]);
1626 			if (ret < 0)
1627 				return ret;
1628 
1629 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
1630 				memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE);
1631 
1632 			if (j == 0) {
1633 				memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
1634 				memcpy(pt.val, vec.pt.val, pt.len);
1635 				memcpy(ct.val, vec.ct.val, ct.len);
1636 				memcpy(iv.val, vec.iv.val, iv.len);
1637 
1638 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1639 					memcpy(vec.pt.val, vec.iv.val, AES_BLOCK_SIZE);
1640 					memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
1641 					val[1].val = pt.val;
1642 					val[1].len = pt.len;
1643 					val[2].val = iv.val;
1644 					val[2].len = iv.len;
1645 				} else {
1646 					memcpy(vec.ct.val, vec.iv.val, AES_BLOCK_SIZE);
1647 					memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
1648 					val[1].val = ct.val;
1649 					val[1].len = ct.len;
1650 					val[2].val = iv.val;
1651 					val[2].len = iv.len;
1652 				}
1653 				continue;
1654 			}
1655 
1656 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1657 				memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
1658 				memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE);
1659 			} else {
1660 				memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
1661 				memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE);
1662 			}
1663 
1664 			if (j == AES_INTERN_ITER - 1)
1665 				continue;
1666 
1667 			memcpy(prev_out, val[0].val, AES_BLOCK_SIZE);
1668 		}
1669 
1670 		info.parse_writeback(val);
1671 		if (info.file_type != FIPS_TYPE_JSON)
1672 			fprintf(info.fp_wr, "\n");
1673 
1674 		if (i == AES_EXTERN_ITER - 1)
1675 			continue;
1676 
1677 		/** update key */
1678 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
1679 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
1680 			switch (vec.cipher_auth.key.len) {
1681 			case 16:
1682 				val_key.val[k] ^= val[0].val[k];
1683 				break;
1684 			case 24:
1685 				if (k < 8)
1686 					val_key.val[k] ^= prev_out[k + 8];
1687 				else
1688 					val_key.val[k] ^= val[0].val[k - 8];
1689 				break;
1690 			case 32:
1691 				if (k < 16)
1692 					val_key.val[k] ^= prev_out[k];
1693 				else
1694 					val_key.val[k] ^= val[0].val[k - 16];
1695 				break;
1696 			default:
1697 				return -1;
1698 			}
1699 		}
1700 
1701 		if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
1702 			memcpy(vec.iv.val, val[0].val, AES_BLOCK_SIZE);
1703 	}
1704 
1705 	free(val[0].val);
1706 	free(pt.val);
1707 	free(ct.val);
1708 	free(iv.val);
1709 
1710 	return 0;
1711 }
1712 
1713 static int
1714 fips_mct_sha_test(void)
1715 {
1716 #define SHA_EXTERN_ITER	100
1717 #define SHA_INTERN_ITER	1000
1718 #define SHA_MD_BLOCK	3
1719 	/* val[0] is op result and other value is for parse_writeback callback */
1720 	struct fips_val val[2] = {{NULL, 0},};
1721 	struct fips_val  md[SHA_MD_BLOCK], msg;
1722 	int ret;
1723 	uint32_t i, j;
1724 
1725 	msg.len = SHA_MD_BLOCK * vec.cipher_auth.digest.len;
1726 	msg.val = calloc(1, msg.len);
1727 	if (vec.pt.val)
1728 		memcpy(vec.cipher_auth.digest.val, vec.pt.val, vec.cipher_auth.digest.len);
1729 
1730 	for (i = 0; i < SHA_MD_BLOCK; i++)
1731 		md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0);
1732 
1733 	rte_free(vec.pt.val);
1734 	vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0);
1735 
1736 	if (info.file_type != FIPS_TYPE_JSON) {
1737 		fips_test_write_one_case();
1738 		fprintf(info.fp_wr, "\n");
1739 	}
1740 
1741 	for (j = 0; j < SHA_EXTERN_ITER; j++) {
1742 
1743 		memcpy(md[0].val, vec.cipher_auth.digest.val,
1744 			vec.cipher_auth.digest.len);
1745 		md[0].len = vec.cipher_auth.digest.len;
1746 		memcpy(md[1].val, vec.cipher_auth.digest.val,
1747 			vec.cipher_auth.digest.len);
1748 		md[1].len = vec.cipher_auth.digest.len;
1749 		memcpy(md[2].val, vec.cipher_auth.digest.val,
1750 			vec.cipher_auth.digest.len);
1751 		md[2].len = vec.cipher_auth.digest.len;
1752 
1753 		for (i = 0; i < SHA_MD_BLOCK; i++)
1754 			memcpy(&msg.val[i * md[i].len], md[i].val, md[i].len);
1755 
1756 		for (i = 0; i < (SHA_INTERN_ITER); i++) {
1757 
1758 			memcpy(vec.pt.val, md[0].val,
1759 				(size_t)md[0].len);
1760 			memcpy((vec.pt.val + md[0].len), md[1].val,
1761 				(size_t)md[1].len);
1762 			memcpy((vec.pt.val + md[0].len + md[1].len),
1763 				md[2].val,
1764 				(size_t)md[2].len);
1765 			vec.pt.len = md[0].len + md[1].len + md[2].len;
1766 
1767 			ret = fips_run_test();
1768 			if (ret < 0) {
1769 				if (ret == -EPERM || ret == -ENOTSUP) {
1770 					if (info.file_type == FIPS_TYPE_JSON)
1771 						return ret;
1772 
1773 					fprintf(info.fp_wr, "Bypass\n\n");
1774 					return 0;
1775 				}
1776 				return ret;
1777 			}
1778 
1779 			ret = get_writeback_data(&val[0]);
1780 			if (ret < 0)
1781 				return ret;
1782 
1783 			memcpy(md[0].val, md[1].val, md[1].len);
1784 			md[0].len = md[1].len;
1785 			memcpy(md[1].val, md[2].val, md[2].len);
1786 			md[1].len = md[2].len;
1787 
1788 			memcpy(md[2].val, (val[0].val + vec.pt.len),
1789 				vec.cipher_auth.digest.len);
1790 			md[2].len = vec.cipher_auth.digest.len;
1791 		}
1792 
1793 		memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len);
1794 		vec.cipher_auth.digest.len = md[2].len;
1795 
1796 		if (info.file_type != FIPS_TYPE_JSON)
1797 			fprintf(info.fp_wr, "COUNT = %u\n", j);
1798 
1799 		val[1].val = msg.val;
1800 		val[1].len = msg.len;
1801 		info.parse_writeback(val);
1802 
1803 		if (info.file_type != FIPS_TYPE_JSON)
1804 			fprintf(info.fp_wr, "\n");
1805 	}
1806 
1807 	for (i = 0; i < (SHA_MD_BLOCK); i++)
1808 		rte_free(md[i].val);
1809 
1810 	rte_free(vec.pt.val);
1811 
1812 	free(val[0].val);
1813 	free(msg.val);
1814 
1815 	return 0;
1816 }
1817 
1818 
1819 static int
1820 init_test_ops(void)
1821 {
1822 	switch (info.algo) {
1823 	case FIPS_TEST_ALGO_AES_CBC:
1824 	case FIPS_TEST_ALGO_AES_CTR:
1825 	case FIPS_TEST_ALGO_AES:
1826 		test_ops.prepare_op = prepare_cipher_op;
1827 		test_ops.prepare_xform  = prepare_aes_xform;
1828 		if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)
1829 			test_ops.test = fips_mct_aes_test;
1830 		else
1831 			test_ops.test = fips_generic_test;
1832 		break;
1833 	case FIPS_TEST_ALGO_HMAC:
1834 		test_ops.prepare_op = prepare_auth_op;
1835 		test_ops.prepare_xform = prepare_hmac_xform;
1836 		test_ops.test = fips_generic_test;
1837 		break;
1838 	case FIPS_TEST_ALGO_TDES:
1839 		test_ops.prepare_op = prepare_cipher_op;
1840 		test_ops.prepare_xform  = prepare_tdes_xform;
1841 		if (info.interim_info.tdes_data.test_type == TDES_MCT)
1842 			test_ops.test = fips_mct_tdes_test;
1843 		else
1844 			test_ops.test = fips_generic_test;
1845 		break;
1846 	case FIPS_TEST_ALGO_AES_GMAC:
1847 		test_ops.prepare_op = prepare_auth_op;
1848 		test_ops.prepare_xform = prepare_gmac_xform;
1849 		test_ops.test = fips_generic_test;
1850 		break;
1851 	case FIPS_TEST_ALGO_AES_GCM:
1852 		test_ops.prepare_op = prepare_aead_op;
1853 		test_ops.prepare_xform = prepare_gcm_xform;
1854 		test_ops.test = fips_generic_test;
1855 		break;
1856 	case FIPS_TEST_ALGO_AES_CMAC:
1857 		test_ops.prepare_op = prepare_auth_op;
1858 		test_ops.prepare_xform = prepare_cmac_xform;
1859 		test_ops.test = fips_generic_test;
1860 		break;
1861 	case FIPS_TEST_ALGO_AES_CCM:
1862 		test_ops.prepare_op = prepare_aead_op;
1863 		test_ops.prepare_xform = prepare_ccm_xform;
1864 		test_ops.test = fips_generic_test;
1865 		break;
1866 	case FIPS_TEST_ALGO_SHA:
1867 		test_ops.prepare_op = prepare_auth_op;
1868 		test_ops.prepare_xform = prepare_sha_xform;
1869 		if (info.interim_info.sha_data.test_type == SHA_MCT)
1870 			test_ops.test = fips_mct_sha_test;
1871 		else
1872 			test_ops.test = fips_generic_test;
1873 		break;
1874 	case FIPS_TEST_ALGO_AES_XTS:
1875 		test_ops.prepare_op = prepare_cipher_op;
1876 		test_ops.prepare_xform = prepare_xts_xform;
1877 		test_ops.test = fips_generic_test;
1878 		break;
1879 	default:
1880 		if (strstr(info.file_name, "TECB") ||
1881 				strstr(info.file_name, "TCBC")) {
1882 			info.algo = FIPS_TEST_ALGO_TDES;
1883 			test_ops.prepare_op = prepare_cipher_op;
1884 			test_ops.prepare_xform	= prepare_tdes_xform;
1885 			if (info.interim_info.tdes_data.test_type == TDES_MCT)
1886 				test_ops.test = fips_mct_tdes_test;
1887 			else
1888 				test_ops.test = fips_generic_test;
1889 			break;
1890 		}
1891 		return -1;
1892 	}
1893 
1894 	return 0;
1895 }
1896 
1897 static void
1898 print_test_block(void)
1899 {
1900 	uint32_t i;
1901 
1902 	for (i = 0; i < info.nb_vec_lines; i++)
1903 		printf("%s\n", info.vec[i]);
1904 
1905 	printf("\n");
1906 }
1907 
1908 static int
1909 fips_test_one_file(void)
1910 {
1911 	int fetch_ret = 0, ret;
1912 
1913 	ret = init_test_ops();
1914 	if (ret < 0) {
1915 		RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret);
1916 		return ret;
1917 	}
1918 
1919 	while (ret >= 0 && fetch_ret == 0) {
1920 		fetch_ret = fips_test_fetch_one_block();
1921 		if (fetch_ret < 0) {
1922 			RTE_LOG(ERR, USER1, "Error %i: Fetch block\n",
1923 					fetch_ret);
1924 			ret = fetch_ret;
1925 			goto error_one_case;
1926 		}
1927 
1928 		if (info.nb_vec_lines == 0) {
1929 			if (fetch_ret == -EOF)
1930 				break;
1931 
1932 			fprintf(info.fp_wr, "\n");
1933 			continue;
1934 		}
1935 
1936 		ret = fips_test_parse_one_case();
1937 		switch (ret) {
1938 		case 0:
1939 			ret = test_ops.test();
1940 			if (ret == 0)
1941 				break;
1942 			RTE_LOG(ERR, USER1, "Error %i: test block\n",
1943 					ret);
1944 			goto error_one_case;
1945 		case 1:
1946 			break;
1947 		default:
1948 			RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
1949 					ret);
1950 			goto error_one_case;
1951 		}
1952 
1953 		continue;
1954 error_one_case:
1955 		print_test_block();
1956 	}
1957 
1958 	fips_test_clear();
1959 
1960 	if (env.digest) {
1961 		rte_free(env.digest);
1962 		env.digest = NULL;
1963 	}
1964 	rte_pktmbuf_free(env.mbuf);
1965 
1966 	return ret;
1967 }
1968 
1969 #ifdef USE_JANSSON
1970 static int
1971 fips_test_json_init_writeback(void)
1972 {
1973 	json_t *session_info, *session_write;
1974 	session_info = json_array_get(json_info.json_root, 0);
1975 	session_write = json_object();
1976 	json_info.json_write_root = json_array();
1977 
1978 	json_object_set(session_write, "jwt",
1979 		json_object_get(session_info, "jwt"));
1980 	json_object_set(session_write, "url",
1981 		json_object_get(session_info, "url"));
1982 	json_object_set(session_write, "isSample",
1983 		json_object_get(session_info, "isSample"));
1984 
1985 	json_info.is_sample = json_boolean_value(
1986 		json_object_get(session_info, "isSample"));
1987 
1988 	json_array_append_new(json_info.json_write_root, session_write);
1989 	return 0;
1990 }
1991 
1992 static int
1993 fips_test_one_test_case(void)
1994 {
1995 	int ret;
1996 
1997 	ret = fips_test_parse_one_json_case();
1998 
1999 	switch (ret) {
2000 	case 0:
2001 		ret = test_ops.test();
2002 		if ((ret == 0) || (ret == -EPERM || ret == -ENOTSUP))
2003 			break;
2004 		RTE_LOG(ERR, USER1, "Error %i: test block\n",
2005 				ret);
2006 		break;
2007 	default:
2008 		RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
2009 				ret);
2010 	}
2011 	return ret;
2012 }
2013 
2014 static int
2015 fips_test_one_test_group(void)
2016 {
2017 	int ret;
2018 	json_t *tests, *write_tests;
2019 	size_t test_idx, tests_size;
2020 
2021 	write_tests = json_array();
2022 	json_info.json_write_group = json_object();
2023 	json_object_set(json_info.json_write_group, "tgId",
2024 		json_object_get(json_info.json_test_group, "tgId"));
2025 	json_object_set_new(json_info.json_write_group, "tests", write_tests);
2026 
2027 	switch (info.algo) {
2028 	case FIPS_TEST_ALGO_AES_GMAC:
2029 	case FIPS_TEST_ALGO_AES_GCM:
2030 		ret = parse_test_gcm_json_init();
2031 		break;
2032 	case FIPS_TEST_ALGO_HMAC:
2033 		ret = parse_test_hmac_json_init();
2034 		break;
2035 	case FIPS_TEST_ALGO_AES_CMAC:
2036 		ret = parse_test_cmac_json_init();
2037 		break;
2038 	case FIPS_TEST_ALGO_AES_XTS:
2039 		ret = parse_test_xts_json_init();
2040 		break;
2041 	case FIPS_TEST_ALGO_AES_CBC:
2042 	case FIPS_TEST_ALGO_AES_CTR:
2043 	case FIPS_TEST_ALGO_AES:
2044 		ret = parse_test_aes_json_init();
2045 		break;
2046 	case FIPS_TEST_ALGO_SHA:
2047 		ret = parse_test_sha_json_init();
2048 		break;
2049 	case FIPS_TEST_ALGO_TDES:
2050 		ret = parse_test_tdes_json_init();
2051 		break;
2052 	default:
2053 		return -EINVAL;
2054 	}
2055 
2056 	if (ret < 0)
2057 		return ret;
2058 
2059 	ret = fips_test_parse_one_json_group();
2060 	if (ret < 0)
2061 		return ret;
2062 
2063 	ret = init_test_ops();
2064 	if (ret < 0)
2065 		return ret;
2066 
2067 	tests = json_object_get(json_info.json_test_group, "tests");
2068 	tests_size = json_array_size(tests);
2069 	for (test_idx = 0; test_idx < tests_size; test_idx++) {
2070 		json_info.json_test_case = json_array_get(tests, test_idx);
2071 		if (fips_test_one_test_case() == 0)
2072 			json_array_append_new(write_tests, json_info.json_write_case);
2073 	}
2074 
2075 	return 0;
2076 }
2077 
2078 static int
2079 fips_test_one_vector_set(void)
2080 {
2081 	int ret;
2082 	json_t *test_groups, *write_groups, *write_version, *write_set;
2083 	size_t group_idx, num_groups;
2084 
2085 	test_groups = json_object_get(json_info.json_vector_set, "testGroups");
2086 	num_groups = json_array_size(test_groups);
2087 
2088 	json_info.json_write_set = json_array();
2089 	write_version = json_object();
2090 	json_object_set_new(write_version, "acvVersion", json_string(ACVVERSION));
2091 	json_array_append_new(json_info.json_write_set, write_version);
2092 
2093 	write_set = json_object();
2094 	json_array_append(json_info.json_write_set, write_set);
2095 	write_groups = json_array();
2096 
2097 	json_object_set(write_set, "vsId",
2098 		json_object_get(json_info.json_vector_set, "vsId"));
2099 	json_object_set(write_set, "algorithm",
2100 		json_object_get(json_info.json_vector_set, "algorithm"));
2101 	json_object_set(write_set, "revision",
2102 		json_object_get(json_info.json_vector_set, "revision"));
2103 	json_object_set_new(write_set, "isSample",
2104 		json_boolean(json_info.is_sample));
2105 	json_object_set_new(write_set, "testGroups", write_groups);
2106 
2107 	ret = fips_test_parse_one_json_vector_set();
2108 	if (ret < 0) {
2109 		RTE_LOG(ERR, USER1, "Error: Unsupported or invalid vector set algorithm: %s\n",
2110 			json_string_value(json_object_get(json_info.json_vector_set, "algorithm")));
2111 		return ret;
2112 	}
2113 
2114 	for (group_idx = 0; group_idx < num_groups; group_idx++) {
2115 		json_info.json_test_group = json_array_get(test_groups, group_idx);
2116 		ret = fips_test_one_test_group();
2117 		json_array_append_new(write_groups, json_info.json_write_group);
2118 	}
2119 
2120 	return 0;
2121 }
2122 
2123 static int
2124 fips_test_one_json_file(void)
2125 {
2126 	size_t vector_set_idx, root_size;
2127 
2128 	root_size = json_array_size(json_info.json_root);
2129 	fips_test_json_init_writeback();
2130 
2131 	for (vector_set_idx = 1; vector_set_idx < root_size; vector_set_idx++) {
2132 		/* Vector set index starts at 1, the 0th index contains test session
2133 		 * information.
2134 		 */
2135 		json_info.json_vector_set = json_array_get(json_info.json_root, vector_set_idx);
2136 		fips_test_one_vector_set();
2137 		json_array_append_new(json_info.json_write_root, json_info.json_write_set);
2138 		json_incref(json_info.json_write_set);
2139 	}
2140 
2141 	json_dumpf(json_info.json_write_root, info.fp_wr, JSON_INDENT(4));
2142 	json_decref(json_info.json_write_root);
2143 
2144 	return 0;
2145 }
2146 #endif /* USE_JANSSON */
2147