1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606  * Copyright(c) 2018 Intel Corporation
3d30ea906Sjfb8856606  */
4d30ea906Sjfb8856606 
5d30ea906Sjfb8856606 #include <sys/stat.h>
6d30ea906Sjfb8856606 #include <getopt.h>
7d30ea906Sjfb8856606 #include <dirent.h>
8d30ea906Sjfb8856606 
9d30ea906Sjfb8856606 #include <rte_cryptodev.h>
10d30ea906Sjfb8856606 #include <rte_cryptodev_pmd.h>
11d30ea906Sjfb8856606 #include <rte_mempool.h>
12d30ea906Sjfb8856606 #include <rte_mbuf.h>
13d30ea906Sjfb8856606 #include <rte_string_fns.h>
14d30ea906Sjfb8856606 
15d30ea906Sjfb8856606 #include "fips_validation.h"
164418919fSjohnjiang #include "fips_dev_self_test.h"
17d30ea906Sjfb8856606 
18d30ea906Sjfb8856606 #define REQ_FILE_PATH_KEYWORD	"req-file"
19d30ea906Sjfb8856606 #define RSP_FILE_PATH_KEYWORD	"rsp-file"
20*2d9fd380Sjfb8856606 #define MBUF_DATAROOM_KEYWORD	"mbuf-dataroom"
21d30ea906Sjfb8856606 #define FOLDER_KEYWORD		"path-is-folder"
22d30ea906Sjfb8856606 #define CRYPTODEV_KEYWORD	"cryptodev"
23d30ea906Sjfb8856606 #define CRYPTODEV_ID_KEYWORD	"cryptodev-id"
244418919fSjohnjiang #define CRYPTODEV_ST_KEYWORD	"self-test"
254418919fSjohnjiang #define CRYPTODEV_BK_ID_KEYWORD	"broken-test-id"
264418919fSjohnjiang #define CRYPTODEV_BK_DIR_KEY	"broken-test-dir"
274418919fSjohnjiang #define CRYPTODEV_ENC_KEYWORD	"enc"
284418919fSjohnjiang #define CRYPTODEV_DEC_KEYWORD	"dec"
29d30ea906Sjfb8856606 
30d30ea906Sjfb8856606 struct fips_test_vector vec;
31d30ea906Sjfb8856606 struct fips_test_interim_info info;
32d30ea906Sjfb8856606 
33d30ea906Sjfb8856606 struct cryptodev_fips_validate_env {
34d30ea906Sjfb8856606 	const char *req_path;
35d30ea906Sjfb8856606 	const char *rsp_path;
36d30ea906Sjfb8856606 	uint32_t is_path_folder;
37*2d9fd380Sjfb8856606 	uint8_t dev_id;
38*2d9fd380Sjfb8856606 	uint8_t dev_support_sgl;
39*2d9fd380Sjfb8856606 	uint16_t mbuf_data_room;
40d30ea906Sjfb8856606 	struct rte_mempool *mpool;
414418919fSjohnjiang 	struct rte_mempool *sess_mpool;
424418919fSjohnjiang 	struct rte_mempool *sess_priv_mpool;
43d30ea906Sjfb8856606 	struct rte_mempool *op_pool;
44d30ea906Sjfb8856606 	struct rte_mbuf *mbuf;
45*2d9fd380Sjfb8856606 	uint8_t *digest;
46*2d9fd380Sjfb8856606 	uint16_t digest_len;
47d30ea906Sjfb8856606 	struct rte_crypto_op *op;
48d30ea906Sjfb8856606 	struct rte_cryptodev_sym_session *sess;
49*2d9fd380Sjfb8856606 	uint16_t self_test;
504418919fSjohnjiang 	struct fips_dev_broken_test_config *broken_test_config;
51d30ea906Sjfb8856606 } env;
52d30ea906Sjfb8856606 
53d30ea906Sjfb8856606 static int
cryptodev_fips_validate_app_int(void)54d30ea906Sjfb8856606 cryptodev_fips_validate_app_int(void)
55d30ea906Sjfb8856606 {
564418919fSjohnjiang 	struct rte_cryptodev_config conf = {rte_socket_id(), 1, 0};
574418919fSjohnjiang 	struct rte_cryptodev_qp_conf qp_conf = {128, NULL, NULL};
58*2d9fd380Sjfb8856606 	struct rte_cryptodev_info dev_info;
594418919fSjohnjiang 	uint32_t sess_sz = rte_cryptodev_sym_get_private_session_size(
604418919fSjohnjiang 			env.dev_id);
61*2d9fd380Sjfb8856606 	uint32_t nb_mbufs = UINT16_MAX / env.mbuf_data_room + 1;
62d30ea906Sjfb8856606 	int ret;
63d30ea906Sjfb8856606 
644418919fSjohnjiang 	if (env.self_test) {
654418919fSjohnjiang 		ret = fips_dev_self_test(env.dev_id, env.broken_test_config);
664418919fSjohnjiang 		if (ret < 0) {
674418919fSjohnjiang 			struct rte_cryptodev *cryptodev =
684418919fSjohnjiang 					rte_cryptodev_pmd_get_dev(env.dev_id);
694418919fSjohnjiang 
704418919fSjohnjiang 			rte_cryptodev_pmd_destroy(cryptodev);
714418919fSjohnjiang 
724418919fSjohnjiang 			return ret;
734418919fSjohnjiang 		}
744418919fSjohnjiang 	}
754418919fSjohnjiang 
76d30ea906Sjfb8856606 	ret = rte_cryptodev_configure(env.dev_id, &conf);
77d30ea906Sjfb8856606 	if (ret < 0)
78d30ea906Sjfb8856606 		return ret;
79d30ea906Sjfb8856606 
80*2d9fd380Sjfb8856606 	rte_cryptodev_info_get(env.dev_id, &dev_info);
81*2d9fd380Sjfb8856606 	if (dev_info.feature_flags & RTE_CRYPTODEV_FF_IN_PLACE_SGL)
82*2d9fd380Sjfb8856606 		env.dev_support_sgl = 1;
83*2d9fd380Sjfb8856606 	else
84*2d9fd380Sjfb8856606 		env.dev_support_sgl = 0;
85*2d9fd380Sjfb8856606 
86*2d9fd380Sjfb8856606 	env.mpool = rte_pktmbuf_pool_create("FIPS_MEMPOOL", nb_mbufs,
87*2d9fd380Sjfb8856606 			0, 0, sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM +
88*2d9fd380Sjfb8856606 			env.mbuf_data_room, rte_socket_id());
89d30ea906Sjfb8856606 	if (!env.mpool)
90d30ea906Sjfb8856606 		return ret;
91d30ea906Sjfb8856606 
92d30ea906Sjfb8856606 	ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
934418919fSjohnjiang 			rte_socket_id());
94d30ea906Sjfb8856606 	if (ret < 0)
95d30ea906Sjfb8856606 		return ret;
96d30ea906Sjfb8856606 
97d30ea906Sjfb8856606 	ret = -ENOMEM;
98d30ea906Sjfb8856606 
994418919fSjohnjiang 	env.sess_mpool = rte_cryptodev_sym_session_pool_create(
1004418919fSjohnjiang 			"FIPS_SESS_MEMPOOL", 16, 0, 0, 0, rte_socket_id());
1014418919fSjohnjiang 	if (!env.sess_mpool)
1024418919fSjohnjiang 		goto error_exit;
1034418919fSjohnjiang 
1044418919fSjohnjiang 	env.sess_priv_mpool = rte_mempool_create("FIPS_SESS_PRIV_MEMPOOL",
1054418919fSjohnjiang 			16, sess_sz, 0, 0, NULL, NULL, NULL,
1064418919fSjohnjiang 			NULL, rte_socket_id(), 0);
1074418919fSjohnjiang 	if (!env.sess_priv_mpool)
1084418919fSjohnjiang 		goto error_exit;
1094418919fSjohnjiang 
110d30ea906Sjfb8856606 	env.op_pool = rte_crypto_op_pool_create(
111d30ea906Sjfb8856606 			"FIPS_OP_POOL",
112d30ea906Sjfb8856606 			RTE_CRYPTO_OP_TYPE_SYMMETRIC,
113d30ea906Sjfb8856606 			1, 0,
114d30ea906Sjfb8856606 			16,
115d30ea906Sjfb8856606 			rte_socket_id());
116d30ea906Sjfb8856606 	if (!env.op_pool)
117d30ea906Sjfb8856606 		goto error_exit;
118d30ea906Sjfb8856606 
119d30ea906Sjfb8856606 	env.op = rte_crypto_op_alloc(env.op_pool, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
120d30ea906Sjfb8856606 	if (!env.op)
121d30ea906Sjfb8856606 		goto error_exit;
122d30ea906Sjfb8856606 
1234418919fSjohnjiang 	qp_conf.mp_session = env.sess_mpool;
1244418919fSjohnjiang 	qp_conf.mp_session_private = env.sess_priv_mpool;
1254418919fSjohnjiang 
1264418919fSjohnjiang 	ret = rte_cryptodev_queue_pair_setup(env.dev_id, 0, &qp_conf,
1274418919fSjohnjiang 			rte_socket_id());
1284418919fSjohnjiang 	if (ret < 0)
1294418919fSjohnjiang 		goto error_exit;
1304418919fSjohnjiang 
131d30ea906Sjfb8856606 	return 0;
132d30ea906Sjfb8856606 
133d30ea906Sjfb8856606 error_exit:
1344418919fSjohnjiang 
135d30ea906Sjfb8856606 	rte_mempool_free(env.mpool);
1364418919fSjohnjiang 	if (env.sess_mpool)
1374418919fSjohnjiang 		rte_mempool_free(env.sess_mpool);
1384418919fSjohnjiang 	if (env.sess_priv_mpool)
1394418919fSjohnjiang 		rte_mempool_free(env.sess_priv_mpool);
140d30ea906Sjfb8856606 	if (env.op_pool)
141d30ea906Sjfb8856606 		rte_mempool_free(env.op_pool);
142d30ea906Sjfb8856606 
143d30ea906Sjfb8856606 	return ret;
144d30ea906Sjfb8856606 }
145d30ea906Sjfb8856606 
146d30ea906Sjfb8856606 static void
cryptodev_fips_validate_app_uninit(void)147d30ea906Sjfb8856606 cryptodev_fips_validate_app_uninit(void)
148d30ea906Sjfb8856606 {
149d30ea906Sjfb8856606 	rte_pktmbuf_free(env.mbuf);
150d30ea906Sjfb8856606 	rte_crypto_op_free(env.op);
151d30ea906Sjfb8856606 	rte_cryptodev_sym_session_clear(env.dev_id, env.sess);
152d30ea906Sjfb8856606 	rte_cryptodev_sym_session_free(env.sess);
153d30ea906Sjfb8856606 	rte_mempool_free(env.mpool);
1544418919fSjohnjiang 	rte_mempool_free(env.sess_mpool);
1554418919fSjohnjiang 	rte_mempool_free(env.sess_priv_mpool);
156d30ea906Sjfb8856606 	rte_mempool_free(env.op_pool);
157d30ea906Sjfb8856606 }
158d30ea906Sjfb8856606 
159d30ea906Sjfb8856606 static int
160d30ea906Sjfb8856606 fips_test_one_file(void);
161d30ea906Sjfb8856606 
162d30ea906Sjfb8856606 static int
parse_cryptodev_arg(char * arg)163d30ea906Sjfb8856606 parse_cryptodev_arg(char *arg)
164d30ea906Sjfb8856606 {
165d30ea906Sjfb8856606 	int id = rte_cryptodev_get_dev_id(arg);
166d30ea906Sjfb8856606 
167d30ea906Sjfb8856606 	if (id < 0) {
168d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev name %s\n",
169d30ea906Sjfb8856606 				id, arg);
170d30ea906Sjfb8856606 		return id;
171d30ea906Sjfb8856606 	}
172d30ea906Sjfb8856606 
173*2d9fd380Sjfb8856606 	env.dev_id = (uint8_t)id;
174d30ea906Sjfb8856606 
175d30ea906Sjfb8856606 	return 0;
176d30ea906Sjfb8856606 }
177d30ea906Sjfb8856606 
178d30ea906Sjfb8856606 static int
parse_cryptodev_id_arg(char * arg)179d30ea906Sjfb8856606 parse_cryptodev_id_arg(char *arg)
180d30ea906Sjfb8856606 {
181d30ea906Sjfb8856606 	uint32_t cryptodev_id;
182d30ea906Sjfb8856606 
183d30ea906Sjfb8856606 	if (parser_read_uint32(&cryptodev_id, arg) < 0) {
184d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n",
185d30ea906Sjfb8856606 				-EINVAL, arg);
186d30ea906Sjfb8856606 		return -1;
187d30ea906Sjfb8856606 	}
188d30ea906Sjfb8856606 
189d30ea906Sjfb8856606 
190d30ea906Sjfb8856606 	if (!rte_cryptodev_pmd_is_valid_dev(cryptodev_id)) {
191d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Error %i: invalid cryptodev id %s\n",
192d30ea906Sjfb8856606 				cryptodev_id, arg);
193d30ea906Sjfb8856606 		return -1;
194d30ea906Sjfb8856606 	}
195d30ea906Sjfb8856606 
196*2d9fd380Sjfb8856606 	env.dev_id = (uint8_t)cryptodev_id;
197d30ea906Sjfb8856606 
198d30ea906Sjfb8856606 	return 0;
199d30ea906Sjfb8856606 }
200d30ea906Sjfb8856606 
201d30ea906Sjfb8856606 static void
cryptodev_fips_validate_usage(const char * prgname)202d30ea906Sjfb8856606 cryptodev_fips_validate_usage(const char *prgname)
203d30ea906Sjfb8856606 {
204*2d9fd380Sjfb8856606 	uint32_t def_mbuf_seg_size = DEF_MBUF_SEG_SIZE;
205d30ea906Sjfb8856606 	printf("%s [EAL options] --\n"
206d30ea906Sjfb8856606 		"  --%s: REQUEST-FILE-PATH\n"
207d30ea906Sjfb8856606 		"  --%s: RESPONSE-FILE-PATH\n"
208d30ea906Sjfb8856606 		"  --%s: indicating both paths are folders\n"
209*2d9fd380Sjfb8856606 		"  --%s: mbuf dataroom size (default %u bytes)\n"
210d30ea906Sjfb8856606 		"  --%s: CRYPTODEV-NAME\n"
2114418919fSjohnjiang 		"  --%s: CRYPTODEV-ID-NAME\n"
2124418919fSjohnjiang 		"  --%s: self test indicator\n"
2134418919fSjohnjiang 		"  --%s: self broken test ID\n"
2144418919fSjohnjiang 		"  --%s: self broken test direction\n",
215d30ea906Sjfb8856606 		prgname, REQ_FILE_PATH_KEYWORD, RSP_FILE_PATH_KEYWORD,
216*2d9fd380Sjfb8856606 		FOLDER_KEYWORD, MBUF_DATAROOM_KEYWORD, def_mbuf_seg_size,
217*2d9fd380Sjfb8856606 		CRYPTODEV_KEYWORD, CRYPTODEV_ID_KEYWORD, CRYPTODEV_ST_KEYWORD,
218*2d9fd380Sjfb8856606 		CRYPTODEV_BK_ID_KEYWORD, CRYPTODEV_BK_DIR_KEY);
219d30ea906Sjfb8856606 }
220d30ea906Sjfb8856606 
221d30ea906Sjfb8856606 static int
cryptodev_fips_validate_parse_args(int argc,char ** argv)222d30ea906Sjfb8856606 cryptodev_fips_validate_parse_args(int argc, char **argv)
223d30ea906Sjfb8856606 {
224d30ea906Sjfb8856606 	int opt, ret;
225d30ea906Sjfb8856606 	char *prgname = argv[0];
226d30ea906Sjfb8856606 	char **argvopt;
227d30ea906Sjfb8856606 	int option_index;
228d30ea906Sjfb8856606 	struct option lgopts[] = {
229d30ea906Sjfb8856606 			{REQ_FILE_PATH_KEYWORD, required_argument, 0, 0},
230d30ea906Sjfb8856606 			{RSP_FILE_PATH_KEYWORD, required_argument, 0, 0},
231d30ea906Sjfb8856606 			{FOLDER_KEYWORD, no_argument, 0, 0},
232*2d9fd380Sjfb8856606 			{MBUF_DATAROOM_KEYWORD, required_argument, 0, 0},
233d30ea906Sjfb8856606 			{CRYPTODEV_KEYWORD, required_argument, 0, 0},
234d30ea906Sjfb8856606 			{CRYPTODEV_ID_KEYWORD, required_argument, 0, 0},
2354418919fSjohnjiang 			{CRYPTODEV_ST_KEYWORD, no_argument, 0, 0},
2364418919fSjohnjiang 			{CRYPTODEV_BK_ID_KEYWORD, required_argument, 0, 0},
2374418919fSjohnjiang 			{CRYPTODEV_BK_DIR_KEY, required_argument, 0, 0},
238d30ea906Sjfb8856606 			{NULL, 0, 0, 0}
239d30ea906Sjfb8856606 	};
240d30ea906Sjfb8856606 
241d30ea906Sjfb8856606 	argvopt = argv;
242d30ea906Sjfb8856606 
243*2d9fd380Sjfb8856606 	env.mbuf_data_room = DEF_MBUF_SEG_SIZE;
244*2d9fd380Sjfb8856606 	if (rte_cryptodev_count())
245*2d9fd380Sjfb8856606 		env.dev_id = 0;
246*2d9fd380Sjfb8856606 	else {
247*2d9fd380Sjfb8856606 		cryptodev_fips_validate_usage(prgname);
248*2d9fd380Sjfb8856606 		return -EINVAL;
249*2d9fd380Sjfb8856606 	}
250*2d9fd380Sjfb8856606 
251d30ea906Sjfb8856606 	while ((opt = getopt_long(argc, argvopt, "s:",
252d30ea906Sjfb8856606 				  lgopts, &option_index)) != EOF) {
253d30ea906Sjfb8856606 
254d30ea906Sjfb8856606 		switch (opt) {
255d30ea906Sjfb8856606 		case 0:
256d30ea906Sjfb8856606 			if (strcmp(lgopts[option_index].name,
257d30ea906Sjfb8856606 					REQ_FILE_PATH_KEYWORD) == 0)
258d30ea906Sjfb8856606 				env.req_path = optarg;
259d30ea906Sjfb8856606 			else if (strcmp(lgopts[option_index].name,
260d30ea906Sjfb8856606 					RSP_FILE_PATH_KEYWORD) == 0)
261d30ea906Sjfb8856606 				env.rsp_path = optarg;
262d30ea906Sjfb8856606 			else if (strcmp(lgopts[option_index].name,
263d30ea906Sjfb8856606 					FOLDER_KEYWORD) == 0)
264d30ea906Sjfb8856606 				env.is_path_folder = 1;
265d30ea906Sjfb8856606 			else if (strcmp(lgopts[option_index].name,
266d30ea906Sjfb8856606 					CRYPTODEV_KEYWORD) == 0) {
267d30ea906Sjfb8856606 				ret = parse_cryptodev_arg(optarg);
268d30ea906Sjfb8856606 				if (ret < 0) {
269d30ea906Sjfb8856606 					cryptodev_fips_validate_usage(prgname);
270d30ea906Sjfb8856606 					return -EINVAL;
271d30ea906Sjfb8856606 				}
272d30ea906Sjfb8856606 			} else if (strcmp(lgopts[option_index].name,
273d30ea906Sjfb8856606 					CRYPTODEV_ID_KEYWORD) == 0) {
274d30ea906Sjfb8856606 				ret = parse_cryptodev_id_arg(optarg);
275d30ea906Sjfb8856606 				if (ret < 0) {
276d30ea906Sjfb8856606 					cryptodev_fips_validate_usage(prgname);
277d30ea906Sjfb8856606 					return -EINVAL;
278d30ea906Sjfb8856606 				}
2794418919fSjohnjiang 			} else if (strcmp(lgopts[option_index].name,
2804418919fSjohnjiang 					CRYPTODEV_ST_KEYWORD) == 0) {
2814418919fSjohnjiang 				env.self_test = 1;
2824418919fSjohnjiang 			} else if (strcmp(lgopts[option_index].name,
2834418919fSjohnjiang 					CRYPTODEV_BK_ID_KEYWORD) == 0) {
2844418919fSjohnjiang 				if (!env.broken_test_config) {
2854418919fSjohnjiang 					env.broken_test_config = rte_malloc(
2864418919fSjohnjiang 						NULL,
2874418919fSjohnjiang 						sizeof(*env.broken_test_config),
2884418919fSjohnjiang 						0);
2894418919fSjohnjiang 					if (!env.broken_test_config)
2904418919fSjohnjiang 						return -ENOMEM;
2914418919fSjohnjiang 
2924418919fSjohnjiang 					env.broken_test_config->expect_fail_dir =
2934418919fSjohnjiang 						self_test_dir_enc_auth_gen;
2944418919fSjohnjiang 				}
2954418919fSjohnjiang 
2964418919fSjohnjiang 				if (parser_read_uint32(
2974418919fSjohnjiang 					&env.broken_test_config->expect_fail_test_idx,
2984418919fSjohnjiang 						optarg) < 0) {
2994418919fSjohnjiang 					rte_free(env.broken_test_config);
3004418919fSjohnjiang 					cryptodev_fips_validate_usage(prgname);
3014418919fSjohnjiang 					return -EINVAL;
3024418919fSjohnjiang 				}
3034418919fSjohnjiang 			} else if (strcmp(lgopts[option_index].name,
3044418919fSjohnjiang 					CRYPTODEV_BK_DIR_KEY) == 0) {
3054418919fSjohnjiang 				if (!env.broken_test_config) {
3064418919fSjohnjiang 					env.broken_test_config = rte_malloc(
3074418919fSjohnjiang 						NULL,
3084418919fSjohnjiang 						sizeof(*env.broken_test_config),
3094418919fSjohnjiang 						0);
3104418919fSjohnjiang 					if (!env.broken_test_config)
3114418919fSjohnjiang 						return -ENOMEM;
3124418919fSjohnjiang 
3134418919fSjohnjiang 					env.broken_test_config->
3144418919fSjohnjiang 						expect_fail_test_idx = 0;
3154418919fSjohnjiang 				}
3164418919fSjohnjiang 
3174418919fSjohnjiang 				if (strcmp(optarg, CRYPTODEV_ENC_KEYWORD) == 0)
3184418919fSjohnjiang 					env.broken_test_config->expect_fail_dir =
3194418919fSjohnjiang 						self_test_dir_enc_auth_gen;
3204418919fSjohnjiang 				else if (strcmp(optarg, CRYPTODEV_DEC_KEYWORD)
3214418919fSjohnjiang 						== 0)
3224418919fSjohnjiang 					env.broken_test_config->expect_fail_dir =
3234418919fSjohnjiang 						self_test_dir_dec_auth_verify;
3244418919fSjohnjiang 				else {
3254418919fSjohnjiang 					rte_free(env.broken_test_config);
3264418919fSjohnjiang 					cryptodev_fips_validate_usage(prgname);
3274418919fSjohnjiang 					return -EINVAL;
3284418919fSjohnjiang 				}
329*2d9fd380Sjfb8856606 			} else if (strcmp(lgopts[option_index].name,
330*2d9fd380Sjfb8856606 					MBUF_DATAROOM_KEYWORD) == 0) {
331*2d9fd380Sjfb8856606 				uint32_t data_room_size;
332*2d9fd380Sjfb8856606 
333*2d9fd380Sjfb8856606 				if (parser_read_uint32(&data_room_size,
334*2d9fd380Sjfb8856606 						optarg) < 0) {
335*2d9fd380Sjfb8856606 					cryptodev_fips_validate_usage(prgname);
336*2d9fd380Sjfb8856606 					return -EINVAL;
337*2d9fd380Sjfb8856606 				}
338*2d9fd380Sjfb8856606 
339*2d9fd380Sjfb8856606 				if (data_room_size == 0 ||
340*2d9fd380Sjfb8856606 						data_room_size > UINT16_MAX) {
341*2d9fd380Sjfb8856606 					cryptodev_fips_validate_usage(prgname);
342*2d9fd380Sjfb8856606 					return -EINVAL;
343*2d9fd380Sjfb8856606 				}
344*2d9fd380Sjfb8856606 
345*2d9fd380Sjfb8856606 				env.mbuf_data_room = data_room_size;
346d30ea906Sjfb8856606 			} else {
347d30ea906Sjfb8856606 				cryptodev_fips_validate_usage(prgname);
348d30ea906Sjfb8856606 				return -EINVAL;
349d30ea906Sjfb8856606 			}
350d30ea906Sjfb8856606 			break;
351d30ea906Sjfb8856606 		default:
352d30ea906Sjfb8856606 			return -1;
353d30ea906Sjfb8856606 		}
354d30ea906Sjfb8856606 	}
355d30ea906Sjfb8856606 
356*2d9fd380Sjfb8856606 	if ((env.req_path == NULL && env.rsp_path != NULL) ||
357*2d9fd380Sjfb8856606 			(env.req_path != NULL && env.rsp_path == NULL)) {
358*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "Missing req path or rsp path\n");
359*2d9fd380Sjfb8856606 		cryptodev_fips_validate_usage(prgname);
360*2d9fd380Sjfb8856606 		return -EINVAL;
361*2d9fd380Sjfb8856606 	}
362*2d9fd380Sjfb8856606 
363*2d9fd380Sjfb8856606 	if (env.req_path == NULL && env.self_test == 0) {
364*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "--self-test must be set if req path is missing\n");
365d30ea906Sjfb8856606 		cryptodev_fips_validate_usage(prgname);
366d30ea906Sjfb8856606 		return -EINVAL;
367d30ea906Sjfb8856606 	}
368d30ea906Sjfb8856606 
369d30ea906Sjfb8856606 	return 0;
370d30ea906Sjfb8856606 }
371d30ea906Sjfb8856606 
372d30ea906Sjfb8856606 int
main(int argc,char * argv[])373d30ea906Sjfb8856606 main(int argc, char *argv[])
374d30ea906Sjfb8856606 {
375d30ea906Sjfb8856606 	int ret;
376d30ea906Sjfb8856606 
377d30ea906Sjfb8856606 	ret = rte_eal_init(argc, argv);
378d30ea906Sjfb8856606 	if (ret < 0) {
379d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret);
380d30ea906Sjfb8856606 		return -1;
381d30ea906Sjfb8856606 	}
382d30ea906Sjfb8856606 
383d30ea906Sjfb8856606 	argc -= ret;
384d30ea906Sjfb8856606 	argv += ret;
385d30ea906Sjfb8856606 
386d30ea906Sjfb8856606 	ret = cryptodev_fips_validate_parse_args(argc, argv);
387d30ea906Sjfb8856606 	if (ret < 0)
388d30ea906Sjfb8856606 		rte_exit(EXIT_FAILURE, "Failed to parse arguments!\n");
389d30ea906Sjfb8856606 
390d30ea906Sjfb8856606 	ret = cryptodev_fips_validate_app_int();
391d30ea906Sjfb8856606 	if (ret < 0) {
392d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Error %i: Failed init\n", ret);
393d30ea906Sjfb8856606 		return -1;
394d30ea906Sjfb8856606 	}
395d30ea906Sjfb8856606 
396*2d9fd380Sjfb8856606 	if (env.req_path == NULL || env.rsp_path == NULL) {
397*2d9fd380Sjfb8856606 		printf("No request, exit.\n");
398*2d9fd380Sjfb8856606 		goto exit;
399*2d9fd380Sjfb8856606 	}
400*2d9fd380Sjfb8856606 
401d30ea906Sjfb8856606 	if (!env.is_path_folder) {
402d30ea906Sjfb8856606 		printf("Processing file %s... ", env.req_path);
403d30ea906Sjfb8856606 
404d30ea906Sjfb8856606 		ret = fips_test_init(env.req_path, env.rsp_path,
405d30ea906Sjfb8856606 			rte_cryptodev_name_get(env.dev_id));
406d30ea906Sjfb8856606 		if (ret < 0) {
407d30ea906Sjfb8856606 			RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
408d30ea906Sjfb8856606 					ret, env.req_path);
409d30ea906Sjfb8856606 			goto exit;
410d30ea906Sjfb8856606 		}
411d30ea906Sjfb8856606 
412d30ea906Sjfb8856606 
413d30ea906Sjfb8856606 		ret = fips_test_one_file();
414d30ea906Sjfb8856606 		if (ret < 0) {
415d30ea906Sjfb8856606 			RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
416d30ea906Sjfb8856606 					ret, env.req_path);
417d30ea906Sjfb8856606 			goto exit;
418d30ea906Sjfb8856606 		}
419d30ea906Sjfb8856606 
420d30ea906Sjfb8856606 		printf("Done\n");
421d30ea906Sjfb8856606 
422d30ea906Sjfb8856606 	} else {
423d30ea906Sjfb8856606 		struct dirent *dir;
424d30ea906Sjfb8856606 		DIR *d_req, *d_rsp;
425d30ea906Sjfb8856606 		char req_path[1024];
426d30ea906Sjfb8856606 		char rsp_path[1024];
427d30ea906Sjfb8856606 
428d30ea906Sjfb8856606 		d_req = opendir(env.req_path);
429d30ea906Sjfb8856606 		if (!d_req) {
430d30ea906Sjfb8856606 			RTE_LOG(ERR, USER1, "Error %i: Path %s not exist\n",
431d30ea906Sjfb8856606 					-EINVAL, env.req_path);
432d30ea906Sjfb8856606 			goto exit;
433d30ea906Sjfb8856606 		}
434d30ea906Sjfb8856606 
435d30ea906Sjfb8856606 		d_rsp = opendir(env.rsp_path);
436d30ea906Sjfb8856606 		if (!d_rsp) {
437d30ea906Sjfb8856606 			ret = mkdir(env.rsp_path, 0700);
438d30ea906Sjfb8856606 			if (ret == 0)
439d30ea906Sjfb8856606 				d_rsp = opendir(env.rsp_path);
440d30ea906Sjfb8856606 			else {
441d30ea906Sjfb8856606 				RTE_LOG(ERR, USER1, "Error %i: Invalid %s\n",
442d30ea906Sjfb8856606 						-EINVAL, env.rsp_path);
443d30ea906Sjfb8856606 				goto exit;
444d30ea906Sjfb8856606 			}
445d30ea906Sjfb8856606 		}
446d30ea906Sjfb8856606 		closedir(d_rsp);
447d30ea906Sjfb8856606 
448d30ea906Sjfb8856606 		while ((dir = readdir(d_req)) != NULL) {
449d30ea906Sjfb8856606 			if (strstr(dir->d_name, "req") == NULL)
450d30ea906Sjfb8856606 				continue;
451d30ea906Sjfb8856606 
452d30ea906Sjfb8856606 			snprintf(req_path, 1023, "%s/%s", env.req_path,
453d30ea906Sjfb8856606 					dir->d_name);
454d30ea906Sjfb8856606 			snprintf(rsp_path, 1023, "%s/%s", env.rsp_path,
455d30ea906Sjfb8856606 					dir->d_name);
456d30ea906Sjfb8856606 			strlcpy(strstr(rsp_path, "req"), "rsp", 4);
457d30ea906Sjfb8856606 
458d30ea906Sjfb8856606 			printf("Processing file %s... ", req_path);
459d30ea906Sjfb8856606 
460d30ea906Sjfb8856606 			ret = fips_test_init(req_path, rsp_path,
461d30ea906Sjfb8856606 			rte_cryptodev_name_get(env.dev_id));
462d30ea906Sjfb8856606 			if (ret < 0) {
463d30ea906Sjfb8856606 				RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
464d30ea906Sjfb8856606 						ret, req_path);
465d30ea906Sjfb8856606 				break;
466d30ea906Sjfb8856606 			}
467d30ea906Sjfb8856606 
468d30ea906Sjfb8856606 			ret = fips_test_one_file();
469d30ea906Sjfb8856606 			if (ret < 0) {
470d30ea906Sjfb8856606 				RTE_LOG(ERR, USER1, "Error %i: Failed test %s\n",
471d30ea906Sjfb8856606 						ret, req_path);
472d30ea906Sjfb8856606 				break;
473d30ea906Sjfb8856606 			}
474d30ea906Sjfb8856606 
475d30ea906Sjfb8856606 			printf("Done\n");
476d30ea906Sjfb8856606 		}
477d30ea906Sjfb8856606 
478d30ea906Sjfb8856606 		closedir(d_req);
479d30ea906Sjfb8856606 	}
480d30ea906Sjfb8856606 
481d30ea906Sjfb8856606 
482d30ea906Sjfb8856606 exit:
483d30ea906Sjfb8856606 	fips_test_clear();
484d30ea906Sjfb8856606 	cryptodev_fips_validate_app_uninit();
485d30ea906Sjfb8856606 
486d30ea906Sjfb8856606 	return ret;
487d30ea906Sjfb8856606 
488d30ea906Sjfb8856606 }
489d30ea906Sjfb8856606 
490d30ea906Sjfb8856606 #define IV_OFF (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
491d30ea906Sjfb8856606 #define CRYPTODEV_FIPS_MAX_RETRIES	16
492d30ea906Sjfb8856606 
493*2d9fd380Sjfb8856606 struct fips_test_ops test_ops;
494d30ea906Sjfb8856606 
495*2d9fd380Sjfb8856606 static int
prepare_data_mbufs(struct fips_val * val)496*2d9fd380Sjfb8856606 prepare_data_mbufs(struct fips_val *val)
497*2d9fd380Sjfb8856606 {
498*2d9fd380Sjfb8856606 	struct rte_mbuf *m, *head = 0;
499*2d9fd380Sjfb8856606 	uint8_t *src = val->val;
500*2d9fd380Sjfb8856606 	uint32_t total_len = val->len;
501*2d9fd380Sjfb8856606 	uint16_t nb_seg;
502*2d9fd380Sjfb8856606 	int ret = 0;
503*2d9fd380Sjfb8856606 
504*2d9fd380Sjfb8856606 	if (env.mbuf)
505*2d9fd380Sjfb8856606 		rte_pktmbuf_free(env.mbuf);
506*2d9fd380Sjfb8856606 
507*2d9fd380Sjfb8856606 	if (total_len > RTE_MBUF_MAX_NB_SEGS) {
508*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "Data len %u too big\n", total_len);
509*2d9fd380Sjfb8856606 		return -EPERM;
510*2d9fd380Sjfb8856606 	}
511*2d9fd380Sjfb8856606 
512*2d9fd380Sjfb8856606 	nb_seg = total_len / env.mbuf_data_room;
513*2d9fd380Sjfb8856606 	if (total_len % env.mbuf_data_room)
514*2d9fd380Sjfb8856606 		nb_seg++;
515*2d9fd380Sjfb8856606 
516*2d9fd380Sjfb8856606 	m = rte_pktmbuf_alloc(env.mpool);
517*2d9fd380Sjfb8856606 	if (!m) {
518*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "Error %i: Not enough mbuf\n",
519*2d9fd380Sjfb8856606 				-ENOMEM);
520*2d9fd380Sjfb8856606 		return -ENOMEM;
521*2d9fd380Sjfb8856606 	}
522*2d9fd380Sjfb8856606 	head = m;
523*2d9fd380Sjfb8856606 
524*2d9fd380Sjfb8856606 	while (nb_seg) {
525*2d9fd380Sjfb8856606 		uint16_t len = RTE_MIN(total_len, env.mbuf_data_room);
526*2d9fd380Sjfb8856606 		uint8_t *dst = (uint8_t *)rte_pktmbuf_append(m, len);
527*2d9fd380Sjfb8856606 
528*2d9fd380Sjfb8856606 		if (!dst) {
529*2d9fd380Sjfb8856606 			RTE_LOG(ERR, USER1, "Error %i: MBUF too small\n",
530*2d9fd380Sjfb8856606 					-ENOMEM);
531*2d9fd380Sjfb8856606 			ret = -ENOMEM;
532*2d9fd380Sjfb8856606 			goto error_exit;
533*2d9fd380Sjfb8856606 		}
534*2d9fd380Sjfb8856606 
535*2d9fd380Sjfb8856606 		memcpy(dst, src, len);
536*2d9fd380Sjfb8856606 
537*2d9fd380Sjfb8856606 		if (head != m) {
538*2d9fd380Sjfb8856606 			ret = rte_pktmbuf_chain(head, m);
539*2d9fd380Sjfb8856606 			if (ret) {
540*2d9fd380Sjfb8856606 				rte_pktmbuf_free(m);
541*2d9fd380Sjfb8856606 				RTE_LOG(ERR, USER1, "Error %i: SGL build\n",
542*2d9fd380Sjfb8856606 						ret);
543*2d9fd380Sjfb8856606 				goto error_exit;
544*2d9fd380Sjfb8856606 			}
545*2d9fd380Sjfb8856606 		}
546*2d9fd380Sjfb8856606 		total_len -= len;
547*2d9fd380Sjfb8856606 
548*2d9fd380Sjfb8856606 		if (total_len) {
549*2d9fd380Sjfb8856606 			if (!env.dev_support_sgl) {
550*2d9fd380Sjfb8856606 				RTE_LOG(ERR, USER1, "SGL not supported\n");
551*2d9fd380Sjfb8856606 				ret = -EPERM;
552*2d9fd380Sjfb8856606 				goto error_exit;
553*2d9fd380Sjfb8856606 			}
554*2d9fd380Sjfb8856606 
555*2d9fd380Sjfb8856606 			m = rte_pktmbuf_alloc(env.mpool);
556*2d9fd380Sjfb8856606 			if (!m) {
557*2d9fd380Sjfb8856606 				RTE_LOG(ERR, USER1, "Error %i: No memory\n",
558*2d9fd380Sjfb8856606 						-ENOMEM);
559*2d9fd380Sjfb8856606 				goto error_exit;
560*2d9fd380Sjfb8856606 			}
561*2d9fd380Sjfb8856606 		} else
562*2d9fd380Sjfb8856606 			break;
563*2d9fd380Sjfb8856606 
564*2d9fd380Sjfb8856606 		src += len;
565*2d9fd380Sjfb8856606 		nb_seg--;
566*2d9fd380Sjfb8856606 	}
567*2d9fd380Sjfb8856606 
568*2d9fd380Sjfb8856606 	if (total_len) {
569*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "Error %i: Failed to store all data\n",
570*2d9fd380Sjfb8856606 				-ENOMEM);
571*2d9fd380Sjfb8856606 		goto error_exit;
572*2d9fd380Sjfb8856606 	}
573*2d9fd380Sjfb8856606 
574*2d9fd380Sjfb8856606 	env.mbuf = head;
575*2d9fd380Sjfb8856606 
576*2d9fd380Sjfb8856606 	return 0;
577*2d9fd380Sjfb8856606 
578*2d9fd380Sjfb8856606 error_exit:
579*2d9fd380Sjfb8856606 	if (head)
580*2d9fd380Sjfb8856606 		rte_pktmbuf_free(head);
581*2d9fd380Sjfb8856606 	return ret;
582*2d9fd380Sjfb8856606 }
583d30ea906Sjfb8856606 
584d30ea906Sjfb8856606 static int
prepare_cipher_op(void)585d30ea906Sjfb8856606 prepare_cipher_op(void)
586d30ea906Sjfb8856606 {
587d30ea906Sjfb8856606 	struct rte_crypto_sym_op *sym = env.op->sym;
588d30ea906Sjfb8856606 	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
589*2d9fd380Sjfb8856606 	int ret;
590d30ea906Sjfb8856606 
591d30ea906Sjfb8856606 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
592d30ea906Sjfb8856606 
593d30ea906Sjfb8856606 	memcpy(iv, vec.iv.val, vec.iv.len);
594d30ea906Sjfb8856606 
595d30ea906Sjfb8856606 	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
596*2d9fd380Sjfb8856606 		ret = prepare_data_mbufs(&vec.pt);
597*2d9fd380Sjfb8856606 		if (ret < 0)
598*2d9fd380Sjfb8856606 			return ret;
599d30ea906Sjfb8856606 
600d30ea906Sjfb8856606 		sym->cipher.data.length = vec.pt.len;
601d30ea906Sjfb8856606 	} else {
602*2d9fd380Sjfb8856606 		ret = prepare_data_mbufs(&vec.ct);
603*2d9fd380Sjfb8856606 		if (ret < 0)
604*2d9fd380Sjfb8856606 			return ret;
605d30ea906Sjfb8856606 
606d30ea906Sjfb8856606 		sym->cipher.data.length = vec.ct.len;
607d30ea906Sjfb8856606 	}
608d30ea906Sjfb8856606 
609d30ea906Sjfb8856606 	rte_crypto_op_attach_sym_session(env.op, env.sess);
610d30ea906Sjfb8856606 
611*2d9fd380Sjfb8856606 	sym->m_src = env.mbuf;
612*2d9fd380Sjfb8856606 	sym->cipher.data.offset = 0;
613*2d9fd380Sjfb8856606 
614d30ea906Sjfb8856606 	return 0;
615d30ea906Sjfb8856606 }
616d30ea906Sjfb8856606 
617*2d9fd380Sjfb8856606 int
prepare_auth_op(void)618d30ea906Sjfb8856606 prepare_auth_op(void)
619d30ea906Sjfb8856606 {
620d30ea906Sjfb8856606 	struct rte_crypto_sym_op *sym = env.op->sym;
621*2d9fd380Sjfb8856606 	int ret;
622d30ea906Sjfb8856606 
623d30ea906Sjfb8856606 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
624*2d9fd380Sjfb8856606 
625*2d9fd380Sjfb8856606 	if (vec.iv.len) {
626*2d9fd380Sjfb8856606 		uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *,
627*2d9fd380Sjfb8856606 				IV_OFF);
628*2d9fd380Sjfb8856606 		memset(iv, 0, vec.iv.len);
629*2d9fd380Sjfb8856606 		if (vec.iv.val)
630*2d9fd380Sjfb8856606 			memcpy(iv, vec.iv.val, vec.iv.len);
631*2d9fd380Sjfb8856606 	}
632*2d9fd380Sjfb8856606 
633*2d9fd380Sjfb8856606 	ret = prepare_data_mbufs(&vec.pt);
634*2d9fd380Sjfb8856606 	if (ret < 0)
635*2d9fd380Sjfb8856606 		return ret;
636*2d9fd380Sjfb8856606 
637*2d9fd380Sjfb8856606 	if (env.digest)
638*2d9fd380Sjfb8856606 		rte_free(env.digest);
639*2d9fd380Sjfb8856606 
640*2d9fd380Sjfb8856606 	env.digest = rte_zmalloc(NULL, vec.cipher_auth.digest.len,
641*2d9fd380Sjfb8856606 			RTE_CACHE_LINE_SIZE);
642*2d9fd380Sjfb8856606 	if (!env.digest) {
643*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "Not enough memory\n");
644*2d9fd380Sjfb8856606 		return -ENOMEM;
645*2d9fd380Sjfb8856606 	}
646*2d9fd380Sjfb8856606 	env.digest_len = vec.cipher_auth.digest.len;
647d30ea906Sjfb8856606 
648d30ea906Sjfb8856606 	sym->m_src = env.mbuf;
649d30ea906Sjfb8856606 	sym->auth.data.offset = 0;
650d30ea906Sjfb8856606 	sym->auth.data.length = vec.pt.len;
651*2d9fd380Sjfb8856606 	sym->auth.digest.data = env.digest;
652*2d9fd380Sjfb8856606 	sym->auth.digest.phys_addr = rte_malloc_virt2iova(env.digest);
653d30ea906Sjfb8856606 
6544418919fSjohnjiang 	if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
655*2d9fd380Sjfb8856606 		memcpy(env.digest, vec.cipher_auth.digest.val,
6564418919fSjohnjiang 				vec.cipher_auth.digest.len);
657d30ea906Sjfb8856606 
658d30ea906Sjfb8856606 	rte_crypto_op_attach_sym_session(env.op, env.sess);
659d30ea906Sjfb8856606 
660d30ea906Sjfb8856606 	return 0;
661d30ea906Sjfb8856606 }
662d30ea906Sjfb8856606 
663*2d9fd380Sjfb8856606 int
prepare_aead_op(void)664d30ea906Sjfb8856606 prepare_aead_op(void)
665d30ea906Sjfb8856606 {
666d30ea906Sjfb8856606 	struct rte_crypto_sym_op *sym = env.op->sym;
667d30ea906Sjfb8856606 	uint8_t *iv = rte_crypto_op_ctod_offset(env.op, uint8_t *, IV_OFF);
668*2d9fd380Sjfb8856606 	int ret;
669d30ea906Sjfb8856606 
670d30ea906Sjfb8856606 	__rte_crypto_op_reset(env.op, RTE_CRYPTO_OP_TYPE_SYMMETRIC);
671d30ea906Sjfb8856606 
672d30ea906Sjfb8856606 	if (info.algo == FIPS_TEST_ALGO_AES_CCM)
673*2d9fd380Sjfb8856606 		iv++;
674d30ea906Sjfb8856606 
675*2d9fd380Sjfb8856606 	if (vec.iv.val)
676*2d9fd380Sjfb8856606 		memcpy(iv, vec.iv.val, vec.iv.len);
677*2d9fd380Sjfb8856606 	else
678*2d9fd380Sjfb8856606 		/* if REQ file has iv length but not data, default as all 0 */
679*2d9fd380Sjfb8856606 		memset(iv, 0, vec.iv.len);
680d30ea906Sjfb8856606 
681d30ea906Sjfb8856606 	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
682*2d9fd380Sjfb8856606 		ret = prepare_data_mbufs(&vec.pt);
683*2d9fd380Sjfb8856606 		if (ret < 0)
684*2d9fd380Sjfb8856606 			return ret;
685d30ea906Sjfb8856606 
686*2d9fd380Sjfb8856606 		if (env.digest)
687*2d9fd380Sjfb8856606 			rte_free(env.digest);
688*2d9fd380Sjfb8856606 		env.digest = rte_zmalloc(NULL, vec.aead.digest.len,
689*2d9fd380Sjfb8856606 				RTE_CACHE_LINE_SIZE);
690*2d9fd380Sjfb8856606 		if (!env.digest) {
691*2d9fd380Sjfb8856606 			RTE_LOG(ERR, USER1, "Not enough memory\n");
692d30ea906Sjfb8856606 			return -ENOMEM;
693d30ea906Sjfb8856606 		}
694*2d9fd380Sjfb8856606 		env.digest_len = vec.cipher_auth.digest.len;
695d30ea906Sjfb8856606 
696d30ea906Sjfb8856606 		sym->aead.data.length = vec.pt.len;
697*2d9fd380Sjfb8856606 		sym->aead.digest.data = env.digest;
698*2d9fd380Sjfb8856606 		sym->aead.digest.phys_addr = rte_malloc_virt2iova(env.digest);
699d30ea906Sjfb8856606 	} else {
700*2d9fd380Sjfb8856606 		ret = prepare_data_mbufs(&vec.ct);
701*2d9fd380Sjfb8856606 		if (ret < 0)
702*2d9fd380Sjfb8856606 			return ret;
703d30ea906Sjfb8856606 
704d30ea906Sjfb8856606 		sym->aead.data.length = vec.ct.len;
705d30ea906Sjfb8856606 		sym->aead.digest.data = vec.aead.digest.val;
706d30ea906Sjfb8856606 		sym->aead.digest.phys_addr = rte_malloc_virt2iova(
707d30ea906Sjfb8856606 				sym->aead.digest.data);
708d30ea906Sjfb8856606 	}
709d30ea906Sjfb8856606 
710*2d9fd380Sjfb8856606 	sym->m_src = env.mbuf;
711*2d9fd380Sjfb8856606 	sym->aead.data.offset = 0;
712*2d9fd380Sjfb8856606 	sym->aead.aad.data = vec.aead.aad.val;
713*2d9fd380Sjfb8856606 	sym->aead.aad.phys_addr = rte_malloc_virt2iova(sym->aead.aad.data);
714*2d9fd380Sjfb8856606 
715d30ea906Sjfb8856606 	rte_crypto_op_attach_sym_session(env.op, env.sess);
716d30ea906Sjfb8856606 
717d30ea906Sjfb8856606 	return 0;
718d30ea906Sjfb8856606 }
719d30ea906Sjfb8856606 
720d30ea906Sjfb8856606 static int
prepare_aes_xform(struct rte_crypto_sym_xform * xform)721d30ea906Sjfb8856606 prepare_aes_xform(struct rte_crypto_sym_xform *xform)
722d30ea906Sjfb8856606 {
723d30ea906Sjfb8856606 	const struct rte_cryptodev_symmetric_capability *cap;
724d30ea906Sjfb8856606 	struct rte_cryptodev_sym_capability_idx cap_idx;
725d30ea906Sjfb8856606 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
726d30ea906Sjfb8856606 
727d30ea906Sjfb8856606 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
728d30ea906Sjfb8856606 
7294418919fSjohnjiang 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_CBC)
730d30ea906Sjfb8856606 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_CBC;
7314418919fSjohnjiang 	else
7324418919fSjohnjiang 		cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_ECB;
7334418919fSjohnjiang 
734d30ea906Sjfb8856606 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
735d30ea906Sjfb8856606 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
736d30ea906Sjfb8856606 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
737d30ea906Sjfb8856606 	cipher_xform->key.data = vec.cipher_auth.key.val;
738d30ea906Sjfb8856606 	cipher_xform->key.length = vec.cipher_auth.key.len;
7394418919fSjohnjiang 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_AES_CBC) {
740d30ea906Sjfb8856606 		cipher_xform->iv.length = vec.iv.len;
741d30ea906Sjfb8856606 		cipher_xform->iv.offset = IV_OFF;
7424418919fSjohnjiang 	} else {
7434418919fSjohnjiang 		cipher_xform->iv.length = 0;
7444418919fSjohnjiang 		cipher_xform->iv.offset = 0;
7454418919fSjohnjiang 	}
7464418919fSjohnjiang 	cap_idx.algo.cipher = cipher_xform->algo;
747d30ea906Sjfb8856606 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
748d30ea906Sjfb8856606 
749d30ea906Sjfb8856606 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
750d30ea906Sjfb8856606 	if (!cap) {
751d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
752d30ea906Sjfb8856606 				env.dev_id);
753d30ea906Sjfb8856606 		return -EINVAL;
754d30ea906Sjfb8856606 	}
755d30ea906Sjfb8856606 
756d30ea906Sjfb8856606 	if (rte_cryptodev_sym_capability_check_cipher(cap,
757d30ea906Sjfb8856606 			cipher_xform->key.length,
758d30ea906Sjfb8856606 			cipher_xform->iv.length) != 0) {
759d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
760d30ea906Sjfb8856606 				info.device_name, cipher_xform->key.length,
761d30ea906Sjfb8856606 				cipher_xform->iv.length);
762d30ea906Sjfb8856606 		return -EPERM;
763d30ea906Sjfb8856606 	}
764d30ea906Sjfb8856606 
765d30ea906Sjfb8856606 	return 0;
766d30ea906Sjfb8856606 }
767d30ea906Sjfb8856606 
768d30ea906Sjfb8856606 static int
prepare_tdes_xform(struct rte_crypto_sym_xform * xform)769d30ea906Sjfb8856606 prepare_tdes_xform(struct rte_crypto_sym_xform *xform)
770d30ea906Sjfb8856606 {
771d30ea906Sjfb8856606 	const struct rte_cryptodev_symmetric_capability *cap;
772d30ea906Sjfb8856606 	struct rte_cryptodev_sym_capability_idx cap_idx;
773d30ea906Sjfb8856606 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
774d30ea906Sjfb8856606 
775d30ea906Sjfb8856606 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
776d30ea906Sjfb8856606 
7774418919fSjohnjiang 	if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC)
778d30ea906Sjfb8856606 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_CBC;
7794418919fSjohnjiang 	else
7804418919fSjohnjiang 		cipher_xform->algo = RTE_CRYPTO_CIPHER_3DES_ECB;
781d30ea906Sjfb8856606 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
782d30ea906Sjfb8856606 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
783d30ea906Sjfb8856606 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
784d30ea906Sjfb8856606 	cipher_xform->key.data = vec.cipher_auth.key.val;
785d30ea906Sjfb8856606 	cipher_xform->key.length = vec.cipher_auth.key.len;
7864418919fSjohnjiang 
7874418919fSjohnjiang 	if (cipher_xform->algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
788d30ea906Sjfb8856606 		cipher_xform->iv.length = vec.iv.len;
789d30ea906Sjfb8856606 		cipher_xform->iv.offset = IV_OFF;
7904418919fSjohnjiang 	} else {
7914418919fSjohnjiang 		cipher_xform->iv.length = 0;
7924418919fSjohnjiang 		cipher_xform->iv.offset = 0;
7934418919fSjohnjiang 	}
7944418919fSjohnjiang 	cap_idx.algo.cipher = cipher_xform->algo;
795d30ea906Sjfb8856606 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
796d30ea906Sjfb8856606 
797d30ea906Sjfb8856606 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
798d30ea906Sjfb8856606 	if (!cap) {
799d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
800d30ea906Sjfb8856606 				env.dev_id);
801d30ea906Sjfb8856606 		return -EINVAL;
802d30ea906Sjfb8856606 	}
803d30ea906Sjfb8856606 
804d30ea906Sjfb8856606 	if (rte_cryptodev_sym_capability_check_cipher(cap,
805d30ea906Sjfb8856606 			cipher_xform->key.length,
806d30ea906Sjfb8856606 			cipher_xform->iv.length) != 0) {
807d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
808d30ea906Sjfb8856606 				info.device_name, cipher_xform->key.length,
809d30ea906Sjfb8856606 				cipher_xform->iv.length);
810d30ea906Sjfb8856606 		return -EPERM;
811d30ea906Sjfb8856606 	}
812d30ea906Sjfb8856606 
813d30ea906Sjfb8856606 	return 0;
814d30ea906Sjfb8856606 }
815d30ea906Sjfb8856606 
816d30ea906Sjfb8856606 static int
prepare_hmac_xform(struct rte_crypto_sym_xform * xform)817d30ea906Sjfb8856606 prepare_hmac_xform(struct rte_crypto_sym_xform *xform)
818d30ea906Sjfb8856606 {
819d30ea906Sjfb8856606 	const struct rte_cryptodev_symmetric_capability *cap;
820d30ea906Sjfb8856606 	struct rte_cryptodev_sym_capability_idx cap_idx;
821d30ea906Sjfb8856606 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
822d30ea906Sjfb8856606 
823d30ea906Sjfb8856606 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
824d30ea906Sjfb8856606 
825d30ea906Sjfb8856606 	auth_xform->algo = info.interim_info.hmac_data.algo;
826d30ea906Sjfb8856606 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
827d30ea906Sjfb8856606 	auth_xform->digest_length = vec.cipher_auth.digest.len;
828d30ea906Sjfb8856606 	auth_xform->key.data = vec.cipher_auth.key.val;
829d30ea906Sjfb8856606 	auth_xform->key.length = vec.cipher_auth.key.len;
830d30ea906Sjfb8856606 
831d30ea906Sjfb8856606 	cap_idx.algo.auth = auth_xform->algo;
832d30ea906Sjfb8856606 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
833d30ea906Sjfb8856606 
834d30ea906Sjfb8856606 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
835d30ea906Sjfb8856606 	if (!cap) {
836d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
837d30ea906Sjfb8856606 				env.dev_id);
838d30ea906Sjfb8856606 		return -EINVAL;
839d30ea906Sjfb8856606 	}
840d30ea906Sjfb8856606 
841d30ea906Sjfb8856606 	if (rte_cryptodev_sym_capability_check_auth(cap,
842d30ea906Sjfb8856606 			auth_xform->key.length,
843d30ea906Sjfb8856606 			auth_xform->digest_length, 0) != 0) {
844d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
845d30ea906Sjfb8856606 				info.device_name, auth_xform->key.length,
846d30ea906Sjfb8856606 				auth_xform->digest_length);
847d30ea906Sjfb8856606 		return -EPERM;
848d30ea906Sjfb8856606 	}
849d30ea906Sjfb8856606 
850d30ea906Sjfb8856606 	return 0;
851d30ea906Sjfb8856606 }
852d30ea906Sjfb8856606 
853*2d9fd380Sjfb8856606 int
prepare_gcm_xform(struct rte_crypto_sym_xform * xform)854d30ea906Sjfb8856606 prepare_gcm_xform(struct rte_crypto_sym_xform *xform)
855d30ea906Sjfb8856606 {
856d30ea906Sjfb8856606 	const struct rte_cryptodev_symmetric_capability *cap;
857d30ea906Sjfb8856606 	struct rte_cryptodev_sym_capability_idx cap_idx;
858d30ea906Sjfb8856606 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
859d30ea906Sjfb8856606 
860d30ea906Sjfb8856606 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
861d30ea906Sjfb8856606 
862d30ea906Sjfb8856606 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_GCM;
863d30ea906Sjfb8856606 	aead_xform->aad_length = vec.aead.aad.len;
864d30ea906Sjfb8856606 	aead_xform->digest_length = vec.aead.digest.len;
865d30ea906Sjfb8856606 	aead_xform->iv.offset = IV_OFF;
866d30ea906Sjfb8856606 	aead_xform->iv.length = vec.iv.len;
867d30ea906Sjfb8856606 	aead_xform->key.data = vec.aead.key.val;
868d30ea906Sjfb8856606 	aead_xform->key.length = vec.aead.key.len;
869d30ea906Sjfb8856606 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
870d30ea906Sjfb8856606 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
871d30ea906Sjfb8856606 			RTE_CRYPTO_AEAD_OP_DECRYPT;
872d30ea906Sjfb8856606 
873d30ea906Sjfb8856606 	cap_idx.algo.aead = aead_xform->algo;
874d30ea906Sjfb8856606 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
875d30ea906Sjfb8856606 
876d30ea906Sjfb8856606 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
877d30ea906Sjfb8856606 	if (!cap) {
878d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
879d30ea906Sjfb8856606 				env.dev_id);
880d30ea906Sjfb8856606 		return -EINVAL;
881d30ea906Sjfb8856606 	}
882d30ea906Sjfb8856606 
883d30ea906Sjfb8856606 	if (rte_cryptodev_sym_capability_check_aead(cap,
884d30ea906Sjfb8856606 			aead_xform->key.length,
885d30ea906Sjfb8856606 			aead_xform->digest_length, aead_xform->aad_length,
886d30ea906Sjfb8856606 			aead_xform->iv.length) != 0) {
887d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1,
888d30ea906Sjfb8856606 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
889d30ea906Sjfb8856606 				info.device_name, aead_xform->key.length,
890d30ea906Sjfb8856606 				aead_xform->digest_length,
891d30ea906Sjfb8856606 				aead_xform->aad_length,
892d30ea906Sjfb8856606 				aead_xform->iv.length);
893d30ea906Sjfb8856606 		return -EPERM;
894d30ea906Sjfb8856606 	}
895d30ea906Sjfb8856606 
896d30ea906Sjfb8856606 	return 0;
897d30ea906Sjfb8856606 }
898d30ea906Sjfb8856606 
899*2d9fd380Sjfb8856606 int
prepare_gmac_xform(struct rte_crypto_sym_xform * xform)900*2d9fd380Sjfb8856606 prepare_gmac_xform(struct rte_crypto_sym_xform *xform)
901*2d9fd380Sjfb8856606 {
902*2d9fd380Sjfb8856606 	const struct rte_cryptodev_symmetric_capability *cap;
903*2d9fd380Sjfb8856606 	struct rte_cryptodev_sym_capability_idx cap_idx;
904*2d9fd380Sjfb8856606 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
905*2d9fd380Sjfb8856606 
906*2d9fd380Sjfb8856606 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
907*2d9fd380Sjfb8856606 
908*2d9fd380Sjfb8856606 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_GMAC;
909*2d9fd380Sjfb8856606 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
910*2d9fd380Sjfb8856606 			RTE_CRYPTO_AUTH_OP_GENERATE :
911*2d9fd380Sjfb8856606 			RTE_CRYPTO_AUTH_OP_VERIFY;
912*2d9fd380Sjfb8856606 	auth_xform->iv.offset = IV_OFF;
913*2d9fd380Sjfb8856606 	auth_xform->iv.length = vec.iv.len;
914*2d9fd380Sjfb8856606 	auth_xform->digest_length = vec.aead.digest.len;
915*2d9fd380Sjfb8856606 	auth_xform->key.data = vec.aead.key.val;
916*2d9fd380Sjfb8856606 	auth_xform->key.length = vec.aead.key.len;
917*2d9fd380Sjfb8856606 
918*2d9fd380Sjfb8856606 	cap_idx.algo.auth = auth_xform->algo;
919*2d9fd380Sjfb8856606 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
920*2d9fd380Sjfb8856606 
921*2d9fd380Sjfb8856606 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
922*2d9fd380Sjfb8856606 	if (!cap) {
923*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
924*2d9fd380Sjfb8856606 				env.dev_id);
925*2d9fd380Sjfb8856606 		return -EINVAL;
926*2d9fd380Sjfb8856606 	}
927*2d9fd380Sjfb8856606 
928*2d9fd380Sjfb8856606 	if (rte_cryptodev_sym_capability_check_auth(cap,
929*2d9fd380Sjfb8856606 			auth_xform->key.length,
930*2d9fd380Sjfb8856606 			auth_xform->digest_length,
931*2d9fd380Sjfb8856606 			auth_xform->iv.length) != 0) {
932*2d9fd380Sjfb8856606 
933*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1,
934*2d9fd380Sjfb8856606 			"PMD %s key length %u Digest length %u IV length %u\n",
935*2d9fd380Sjfb8856606 				info.device_name, auth_xform->key.length,
936*2d9fd380Sjfb8856606 				auth_xform->digest_length,
937*2d9fd380Sjfb8856606 				auth_xform->iv.length);
938*2d9fd380Sjfb8856606 		return -EPERM;
939*2d9fd380Sjfb8856606 	}
940*2d9fd380Sjfb8856606 
941*2d9fd380Sjfb8856606 	return 0;
942*2d9fd380Sjfb8856606 }
943*2d9fd380Sjfb8856606 
944d30ea906Sjfb8856606 static int
prepare_cmac_xform(struct rte_crypto_sym_xform * xform)945d30ea906Sjfb8856606 prepare_cmac_xform(struct rte_crypto_sym_xform *xform)
946d30ea906Sjfb8856606 {
947d30ea906Sjfb8856606 	const struct rte_cryptodev_symmetric_capability *cap;
948d30ea906Sjfb8856606 	struct rte_cryptodev_sym_capability_idx cap_idx;
949d30ea906Sjfb8856606 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
950d30ea906Sjfb8856606 
951d30ea906Sjfb8856606 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
952d30ea906Sjfb8856606 
953d30ea906Sjfb8856606 	auth_xform->algo = RTE_CRYPTO_AUTH_AES_CMAC;
954d30ea906Sjfb8856606 	auth_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
955d30ea906Sjfb8856606 			RTE_CRYPTO_AUTH_OP_GENERATE : RTE_CRYPTO_AUTH_OP_VERIFY;
956d30ea906Sjfb8856606 	auth_xform->digest_length = vec.cipher_auth.digest.len;
957d30ea906Sjfb8856606 	auth_xform->key.data = vec.cipher_auth.key.val;
958d30ea906Sjfb8856606 	auth_xform->key.length = vec.cipher_auth.key.len;
959d30ea906Sjfb8856606 
960d30ea906Sjfb8856606 	cap_idx.algo.auth = auth_xform->algo;
961d30ea906Sjfb8856606 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
962d30ea906Sjfb8856606 
963d30ea906Sjfb8856606 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
964d30ea906Sjfb8856606 	if (!cap) {
965d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
966d30ea906Sjfb8856606 				env.dev_id);
967d30ea906Sjfb8856606 		return -EINVAL;
968d30ea906Sjfb8856606 	}
969d30ea906Sjfb8856606 
970d30ea906Sjfb8856606 	if (rte_cryptodev_sym_capability_check_auth(cap,
971d30ea906Sjfb8856606 			auth_xform->key.length,
972d30ea906Sjfb8856606 			auth_xform->digest_length, 0) != 0) {
973d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
974d30ea906Sjfb8856606 				info.device_name, auth_xform->key.length,
975d30ea906Sjfb8856606 				auth_xform->digest_length);
976d30ea906Sjfb8856606 		return -EPERM;
977d30ea906Sjfb8856606 	}
978d30ea906Sjfb8856606 
979d30ea906Sjfb8856606 	return 0;
980d30ea906Sjfb8856606 }
981d30ea906Sjfb8856606 
982d30ea906Sjfb8856606 static int
prepare_ccm_xform(struct rte_crypto_sym_xform * xform)983d30ea906Sjfb8856606 prepare_ccm_xform(struct rte_crypto_sym_xform *xform)
984d30ea906Sjfb8856606 {
985d30ea906Sjfb8856606 	const struct rte_cryptodev_symmetric_capability *cap;
986d30ea906Sjfb8856606 	struct rte_cryptodev_sym_capability_idx cap_idx;
987d30ea906Sjfb8856606 	struct rte_crypto_aead_xform *aead_xform = &xform->aead;
988d30ea906Sjfb8856606 
989d30ea906Sjfb8856606 	xform->type = RTE_CRYPTO_SYM_XFORM_AEAD;
990d30ea906Sjfb8856606 
991d30ea906Sjfb8856606 	aead_xform->algo = RTE_CRYPTO_AEAD_AES_CCM;
992d30ea906Sjfb8856606 	aead_xform->aad_length = vec.aead.aad.len;
993d30ea906Sjfb8856606 	aead_xform->digest_length = vec.aead.digest.len;
994d30ea906Sjfb8856606 	aead_xform->iv.offset = IV_OFF;
995d30ea906Sjfb8856606 	aead_xform->iv.length = vec.iv.len;
996d30ea906Sjfb8856606 	aead_xform->key.data = vec.aead.key.val;
997d30ea906Sjfb8856606 	aead_xform->key.length = vec.aead.key.len;
998d30ea906Sjfb8856606 	aead_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
999d30ea906Sjfb8856606 			RTE_CRYPTO_AEAD_OP_ENCRYPT :
1000d30ea906Sjfb8856606 			RTE_CRYPTO_AEAD_OP_DECRYPT;
1001d30ea906Sjfb8856606 
1002d30ea906Sjfb8856606 	cap_idx.algo.aead = aead_xform->algo;
1003d30ea906Sjfb8856606 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AEAD;
1004d30ea906Sjfb8856606 
1005d30ea906Sjfb8856606 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1006d30ea906Sjfb8856606 	if (!cap) {
1007d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1008d30ea906Sjfb8856606 				env.dev_id);
1009d30ea906Sjfb8856606 		return -EINVAL;
1010d30ea906Sjfb8856606 	}
1011d30ea906Sjfb8856606 
1012d30ea906Sjfb8856606 	if (rte_cryptodev_sym_capability_check_aead(cap,
1013d30ea906Sjfb8856606 			aead_xform->key.length,
1014d30ea906Sjfb8856606 			aead_xform->digest_length, aead_xform->aad_length,
1015d30ea906Sjfb8856606 			aead_xform->iv.length) != 0) {
1016d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1,
1017d30ea906Sjfb8856606 			"PMD %s key_len %u tag_len %u aad_len %u iv_len %u\n",
1018d30ea906Sjfb8856606 				info.device_name, aead_xform->key.length,
1019d30ea906Sjfb8856606 				aead_xform->digest_length,
1020d30ea906Sjfb8856606 				aead_xform->aad_length,
1021d30ea906Sjfb8856606 				aead_xform->iv.length);
1022d30ea906Sjfb8856606 		return -EPERM;
1023d30ea906Sjfb8856606 	}
1024d30ea906Sjfb8856606 
1025d30ea906Sjfb8856606 	return 0;
1026d30ea906Sjfb8856606 }
1027d30ea906Sjfb8856606 
10284418919fSjohnjiang static int
prepare_sha_xform(struct rte_crypto_sym_xform * xform)10294418919fSjohnjiang prepare_sha_xform(struct rte_crypto_sym_xform *xform)
10304418919fSjohnjiang {
10314418919fSjohnjiang 	const struct rte_cryptodev_symmetric_capability *cap;
10324418919fSjohnjiang 	struct rte_cryptodev_sym_capability_idx cap_idx;
10334418919fSjohnjiang 	struct rte_crypto_auth_xform *auth_xform = &xform->auth;
10344418919fSjohnjiang 
10354418919fSjohnjiang 	xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
10364418919fSjohnjiang 
10374418919fSjohnjiang 	auth_xform->algo = info.interim_info.sha_data.algo;
10384418919fSjohnjiang 	auth_xform->op = RTE_CRYPTO_AUTH_OP_GENERATE;
10394418919fSjohnjiang 	auth_xform->digest_length = vec.cipher_auth.digest.len;
10404418919fSjohnjiang 
10414418919fSjohnjiang 	cap_idx.algo.auth = auth_xform->algo;
10424418919fSjohnjiang 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_AUTH;
10434418919fSjohnjiang 
10444418919fSjohnjiang 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
10454418919fSjohnjiang 	if (!cap) {
10464418919fSjohnjiang 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
10474418919fSjohnjiang 				env.dev_id);
10484418919fSjohnjiang 		return -EINVAL;
10494418919fSjohnjiang 	}
10504418919fSjohnjiang 
10514418919fSjohnjiang 	if (rte_cryptodev_sym_capability_check_auth(cap,
10524418919fSjohnjiang 			auth_xform->key.length,
10534418919fSjohnjiang 			auth_xform->digest_length, 0) != 0) {
10544418919fSjohnjiang 		RTE_LOG(ERR, USER1, "PMD %s key length %u digest length %u\n",
10554418919fSjohnjiang 				info.device_name, auth_xform->key.length,
10564418919fSjohnjiang 				auth_xform->digest_length);
10574418919fSjohnjiang 		return -EPERM;
10584418919fSjohnjiang 	}
10594418919fSjohnjiang 
10604418919fSjohnjiang 	return 0;
10614418919fSjohnjiang }
10624418919fSjohnjiang 
1063*2d9fd380Sjfb8856606 static int
prepare_xts_xform(struct rte_crypto_sym_xform * xform)1064*2d9fd380Sjfb8856606 prepare_xts_xform(struct rte_crypto_sym_xform *xform)
1065*2d9fd380Sjfb8856606 {
1066*2d9fd380Sjfb8856606 	const struct rte_cryptodev_symmetric_capability *cap;
1067*2d9fd380Sjfb8856606 	struct rte_cryptodev_sym_capability_idx cap_idx;
1068*2d9fd380Sjfb8856606 	struct rte_crypto_cipher_xform *cipher_xform = &xform->cipher;
1069*2d9fd380Sjfb8856606 
1070*2d9fd380Sjfb8856606 	xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1071*2d9fd380Sjfb8856606 
1072*2d9fd380Sjfb8856606 	cipher_xform->algo = RTE_CRYPTO_CIPHER_AES_XTS;
1073*2d9fd380Sjfb8856606 	cipher_xform->op = (info.op == FIPS_TEST_ENC_AUTH_GEN) ?
1074*2d9fd380Sjfb8856606 			RTE_CRYPTO_CIPHER_OP_ENCRYPT :
1075*2d9fd380Sjfb8856606 			RTE_CRYPTO_CIPHER_OP_DECRYPT;
1076*2d9fd380Sjfb8856606 	cipher_xform->key.data = vec.cipher_auth.key.val;
1077*2d9fd380Sjfb8856606 	cipher_xform->key.length = vec.cipher_auth.key.len;
1078*2d9fd380Sjfb8856606 	cipher_xform->iv.length = vec.iv.len;
1079*2d9fd380Sjfb8856606 	cipher_xform->iv.offset = IV_OFF;
1080*2d9fd380Sjfb8856606 
1081*2d9fd380Sjfb8856606 	cap_idx.algo.cipher = RTE_CRYPTO_CIPHER_AES_XTS;
1082*2d9fd380Sjfb8856606 	cap_idx.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1083*2d9fd380Sjfb8856606 
1084*2d9fd380Sjfb8856606 	cap = rte_cryptodev_sym_capability_get(env.dev_id, &cap_idx);
1085*2d9fd380Sjfb8856606 	if (!cap) {
1086*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "Failed to get capability for cdev %u\n",
1087*2d9fd380Sjfb8856606 				env.dev_id);
1088*2d9fd380Sjfb8856606 		return -EINVAL;
1089*2d9fd380Sjfb8856606 	}
1090*2d9fd380Sjfb8856606 
1091*2d9fd380Sjfb8856606 	if (rte_cryptodev_sym_capability_check_cipher(cap,
1092*2d9fd380Sjfb8856606 			cipher_xform->key.length,
1093*2d9fd380Sjfb8856606 			cipher_xform->iv.length) != 0) {
1094*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "PMD %s key length %u IV length %u\n",
1095*2d9fd380Sjfb8856606 				info.device_name, cipher_xform->key.length,
1096*2d9fd380Sjfb8856606 				cipher_xform->iv.length);
1097*2d9fd380Sjfb8856606 		return -EPERM;
1098*2d9fd380Sjfb8856606 	}
1099*2d9fd380Sjfb8856606 
1100*2d9fd380Sjfb8856606 	return 0;
1101*2d9fd380Sjfb8856606 }
1102*2d9fd380Sjfb8856606 
1103*2d9fd380Sjfb8856606 static int
get_writeback_data(struct fips_val * val)1104d30ea906Sjfb8856606 get_writeback_data(struct fips_val *val)
1105d30ea906Sjfb8856606 {
1106*2d9fd380Sjfb8856606 	struct rte_mbuf *m = env.mbuf;
1107*2d9fd380Sjfb8856606 	uint16_t data_len = rte_pktmbuf_pkt_len(m);
1108*2d9fd380Sjfb8856606 	uint16_t total_len = data_len + env.digest_len;
1109*2d9fd380Sjfb8856606 	uint8_t *src, *dst, *wb_data;
1110*2d9fd380Sjfb8856606 
1111*2d9fd380Sjfb8856606 	/* in case val is reused for MCT test, try to free the buffer first */
1112*2d9fd380Sjfb8856606 	if (val->val) {
1113*2d9fd380Sjfb8856606 		free(val->val);
1114*2d9fd380Sjfb8856606 		val->val = NULL;
1115*2d9fd380Sjfb8856606 	}
1116*2d9fd380Sjfb8856606 
1117*2d9fd380Sjfb8856606 	wb_data = dst = calloc(1, total_len);
1118*2d9fd380Sjfb8856606 	if (!dst) {
1119*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "Error %i: Not enough memory\n", -ENOMEM);
1120*2d9fd380Sjfb8856606 		return -ENOMEM;
1121*2d9fd380Sjfb8856606 	}
1122*2d9fd380Sjfb8856606 
1123*2d9fd380Sjfb8856606 	while (m && data_len) {
1124*2d9fd380Sjfb8856606 		uint16_t seg_len = RTE_MIN(rte_pktmbuf_data_len(m), data_len);
1125*2d9fd380Sjfb8856606 
1126*2d9fd380Sjfb8856606 		src = rte_pktmbuf_mtod(m, uint8_t *);
1127*2d9fd380Sjfb8856606 		memcpy(dst, src, seg_len);
1128*2d9fd380Sjfb8856606 		m = m->next;
1129*2d9fd380Sjfb8856606 		data_len -= seg_len;
1130*2d9fd380Sjfb8856606 		dst += seg_len;
1131*2d9fd380Sjfb8856606 	}
1132*2d9fd380Sjfb8856606 
1133*2d9fd380Sjfb8856606 	if (data_len) {
1134*2d9fd380Sjfb8856606 		RTE_LOG(ERR, USER1, "Error -1: write back data\n");
1135*2d9fd380Sjfb8856606 		free(wb_data);
1136*2d9fd380Sjfb8856606 		return -1;
1137*2d9fd380Sjfb8856606 	}
1138*2d9fd380Sjfb8856606 
1139*2d9fd380Sjfb8856606 	if (env.digest)
1140*2d9fd380Sjfb8856606 		memcpy(dst, env.digest, env.digest_len);
1141*2d9fd380Sjfb8856606 
1142*2d9fd380Sjfb8856606 	val->val = wb_data;
1143*2d9fd380Sjfb8856606 	val->len = total_len;
1144*2d9fd380Sjfb8856606 
1145*2d9fd380Sjfb8856606 	return 0;
1146d30ea906Sjfb8856606 }
1147d30ea906Sjfb8856606 
1148d30ea906Sjfb8856606 static int
fips_run_test(void)1149d30ea906Sjfb8856606 fips_run_test(void)
1150d30ea906Sjfb8856606 {
1151d30ea906Sjfb8856606 	struct rte_crypto_sym_xform xform = {0};
1152d30ea906Sjfb8856606 	uint16_t n_deqd;
1153d30ea906Sjfb8856606 	int ret;
1154d30ea906Sjfb8856606 
1155d30ea906Sjfb8856606 	ret = test_ops.prepare_xform(&xform);
1156d30ea906Sjfb8856606 	if (ret < 0)
1157d30ea906Sjfb8856606 		return ret;
1158d30ea906Sjfb8856606 
11594418919fSjohnjiang 	env.sess = rte_cryptodev_sym_session_create(env.sess_mpool);
1160d30ea906Sjfb8856606 	if (!env.sess)
1161d30ea906Sjfb8856606 		return -ENOMEM;
1162d30ea906Sjfb8856606 
1163d30ea906Sjfb8856606 	ret = rte_cryptodev_sym_session_init(env.dev_id,
11644418919fSjohnjiang 			env.sess, &xform, env.sess_priv_mpool);
1165d30ea906Sjfb8856606 	if (ret < 0) {
1166d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Error %i: Init session\n",
1167d30ea906Sjfb8856606 				ret);
11681646932aSjfb8856606 		goto exit;
1169d30ea906Sjfb8856606 	}
1170d30ea906Sjfb8856606 
1171d30ea906Sjfb8856606 	ret = test_ops.prepare_op();
1172d30ea906Sjfb8856606 	if (ret < 0) {
1173d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Error %i: Prepare op\n",
1174d30ea906Sjfb8856606 				ret);
11751646932aSjfb8856606 		goto exit;
1176d30ea906Sjfb8856606 	}
1177d30ea906Sjfb8856606 
1178d30ea906Sjfb8856606 	if (rte_cryptodev_enqueue_burst(env.dev_id, 0, &env.op, 1) < 1) {
1179d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Error: Failed enqueue\n");
11801646932aSjfb8856606 		ret = -1;
11811646932aSjfb8856606 		goto exit;
1182d30ea906Sjfb8856606 	}
1183d30ea906Sjfb8856606 
1184d30ea906Sjfb8856606 	do {
1185d30ea906Sjfb8856606 		struct rte_crypto_op *deqd_op;
1186d30ea906Sjfb8856606 
1187d30ea906Sjfb8856606 		n_deqd = rte_cryptodev_dequeue_burst(env.dev_id, 0, &deqd_op,
1188d30ea906Sjfb8856606 				1);
1189d30ea906Sjfb8856606 	} while (n_deqd == 0);
1190d30ea906Sjfb8856606 
1191d30ea906Sjfb8856606 	vec.status = env.op->status;
1192d30ea906Sjfb8856606 
11931646932aSjfb8856606 exit:
1194d30ea906Sjfb8856606 	rte_cryptodev_sym_session_clear(env.dev_id, env.sess);
1195d30ea906Sjfb8856606 	rte_cryptodev_sym_session_free(env.sess);
1196d30ea906Sjfb8856606 	env.sess = NULL;
1197d30ea906Sjfb8856606 
1198d30ea906Sjfb8856606 	return ret;
1199d30ea906Sjfb8856606 }
1200d30ea906Sjfb8856606 
1201d30ea906Sjfb8856606 static int
fips_generic_test(void)1202d30ea906Sjfb8856606 fips_generic_test(void)
1203d30ea906Sjfb8856606 {
1204*2d9fd380Sjfb8856606 	struct fips_val val = {NULL, 0};
1205d30ea906Sjfb8856606 	int ret;
1206d30ea906Sjfb8856606 
1207d30ea906Sjfb8856606 	fips_test_write_one_case();
1208d30ea906Sjfb8856606 
1209d30ea906Sjfb8856606 	ret = fips_run_test();
1210d30ea906Sjfb8856606 	if (ret < 0) {
1211*2d9fd380Sjfb8856606 		if (ret == -EPERM || ret == -ENOTSUP) {
1212d30ea906Sjfb8856606 			fprintf(info.fp_wr, "Bypass\n\n");
1213d30ea906Sjfb8856606 			return 0;
1214d30ea906Sjfb8856606 		}
1215d30ea906Sjfb8856606 
1216d30ea906Sjfb8856606 		return ret;
1217d30ea906Sjfb8856606 	}
1218d30ea906Sjfb8856606 
1219*2d9fd380Sjfb8856606 	ret = get_writeback_data(&val);
1220*2d9fd380Sjfb8856606 	if (ret < 0)
1221*2d9fd380Sjfb8856606 		return ret;
1222d30ea906Sjfb8856606 
1223d30ea906Sjfb8856606 	switch (info.file_type) {
1224d30ea906Sjfb8856606 	case FIPS_TYPE_REQ:
1225d30ea906Sjfb8856606 	case FIPS_TYPE_RSP:
1226d30ea906Sjfb8856606 		if (info.parse_writeback == NULL)
1227d30ea906Sjfb8856606 			return -EPERM;
1228d30ea906Sjfb8856606 		ret = info.parse_writeback(&val);
1229d30ea906Sjfb8856606 		if (ret < 0)
1230d30ea906Sjfb8856606 			return ret;
1231d30ea906Sjfb8856606 		break;
1232d30ea906Sjfb8856606 	case FIPS_TYPE_FAX:
1233d30ea906Sjfb8856606 		if (info.kat_check == NULL)
1234d30ea906Sjfb8856606 			return -EPERM;
1235d30ea906Sjfb8856606 		ret = info.kat_check(&val);
1236d30ea906Sjfb8856606 		if (ret < 0)
1237d30ea906Sjfb8856606 			return ret;
1238d30ea906Sjfb8856606 		break;
1239d30ea906Sjfb8856606 	}
1240d30ea906Sjfb8856606 
1241d30ea906Sjfb8856606 	fprintf(info.fp_wr, "\n");
1242*2d9fd380Sjfb8856606 	free(val.val);
1243d30ea906Sjfb8856606 
1244d30ea906Sjfb8856606 	return 0;
1245d30ea906Sjfb8856606 }
1246d30ea906Sjfb8856606 
1247d30ea906Sjfb8856606 static int
fips_mct_tdes_test(void)1248d30ea906Sjfb8856606 fips_mct_tdes_test(void)
1249d30ea906Sjfb8856606 {
1250d30ea906Sjfb8856606 #define TDES_BLOCK_SIZE		8
1251d30ea906Sjfb8856606 #define TDES_EXTERN_ITER	400
1252d30ea906Sjfb8856606 #define TDES_INTERN_ITER	10000
1253*2d9fd380Sjfb8856606 	struct fips_val val = {NULL, 0}, val_key;
1254d30ea906Sjfb8856606 	uint8_t prev_out[TDES_BLOCK_SIZE] = {0};
1255d30ea906Sjfb8856606 	uint8_t prev_prev_out[TDES_BLOCK_SIZE] = {0};
1256d30ea906Sjfb8856606 	uint8_t prev_in[TDES_BLOCK_SIZE] = {0};
1257d30ea906Sjfb8856606 	uint32_t i, j, k;
1258d30ea906Sjfb8856606 	int ret;
12594418919fSjohnjiang 	int test_mode = info.interim_info.tdes_data.test_mode;
1260d30ea906Sjfb8856606 
1261d30ea906Sjfb8856606 	for (i = 0; i < TDES_EXTERN_ITER; i++) {
12620c6bd470Sfengbojiang 		if ((i == 0) && (info.version == 21.4f)) {
12630c6bd470Sfengbojiang 			if (!(strstr(info.vec[0], "COUNT")))
12640c6bd470Sfengbojiang 				fprintf(info.fp_wr, "%s%u\n", "COUNT = ", 0);
12650c6bd470Sfengbojiang 		}
12660c6bd470Sfengbojiang 
1267d30ea906Sjfb8856606 		if (i != 0)
1268d30ea906Sjfb8856606 			update_info_vec(i);
1269d30ea906Sjfb8856606 
1270d30ea906Sjfb8856606 		fips_test_write_one_case();
1271d30ea906Sjfb8856606 
1272d30ea906Sjfb8856606 		for (j = 0; j < TDES_INTERN_ITER; j++) {
1273d30ea906Sjfb8856606 			ret = fips_run_test();
1274d30ea906Sjfb8856606 			if (ret < 0) {
1275d30ea906Sjfb8856606 				if (ret == -EPERM) {
1276d30ea906Sjfb8856606 					fprintf(info.fp_wr, "Bypass\n");
1277d30ea906Sjfb8856606 					return 0;
1278d30ea906Sjfb8856606 				}
1279d30ea906Sjfb8856606 				return ret;
1280d30ea906Sjfb8856606 			}
1281d30ea906Sjfb8856606 
1282*2d9fd380Sjfb8856606 			ret = get_writeback_data(&val);
1283*2d9fd380Sjfb8856606 			if (ret < 0)
1284*2d9fd380Sjfb8856606 				return ret;
1285d30ea906Sjfb8856606 
1286d30ea906Sjfb8856606 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
1287d30ea906Sjfb8856606 				memcpy(prev_in, vec.ct.val, TDES_BLOCK_SIZE);
1288d30ea906Sjfb8856606 
1289d30ea906Sjfb8856606 			if (j == 0) {
1290d30ea906Sjfb8856606 				memcpy(prev_out, val.val, TDES_BLOCK_SIZE);
1291d30ea906Sjfb8856606 
1292d30ea906Sjfb8856606 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
12934418919fSjohnjiang 					if (test_mode == TDES_MODE_ECB) {
12944418919fSjohnjiang 						memcpy(vec.pt.val, val.val,
12954418919fSjohnjiang 							   TDES_BLOCK_SIZE);
12964418919fSjohnjiang 					} else {
1297d30ea906Sjfb8856606 						memcpy(vec.pt.val, vec.iv.val,
1298d30ea906Sjfb8856606 							   TDES_BLOCK_SIZE);
1299d30ea906Sjfb8856606 						memcpy(vec.iv.val, val.val,
1300d30ea906Sjfb8856606 							   TDES_BLOCK_SIZE);
13014418919fSjohnjiang 					}
13024418919fSjohnjiang 
13034418919fSjohnjiang 				} else {
13044418919fSjohnjiang 					if (test_mode == TDES_MODE_ECB) {
13054418919fSjohnjiang 						memcpy(vec.ct.val, val.val,
13064418919fSjohnjiang 							   TDES_BLOCK_SIZE);
1307d30ea906Sjfb8856606 					} else {
1308d30ea906Sjfb8856606 						memcpy(vec.iv.val, vec.ct.val,
1309d30ea906Sjfb8856606 							   TDES_BLOCK_SIZE);
1310d30ea906Sjfb8856606 						memcpy(vec.ct.val, val.val,
1311d30ea906Sjfb8856606 							   TDES_BLOCK_SIZE);
1312d30ea906Sjfb8856606 					}
13134418919fSjohnjiang 				}
1314d30ea906Sjfb8856606 				continue;
1315d30ea906Sjfb8856606 			}
1316d30ea906Sjfb8856606 
1317d30ea906Sjfb8856606 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
13184418919fSjohnjiang 				if (test_mode == TDES_MODE_ECB) {
13194418919fSjohnjiang 					memcpy(vec.pt.val, val.val,
13204418919fSjohnjiang 						   TDES_BLOCK_SIZE);
1321d30ea906Sjfb8856606 				} else {
13224418919fSjohnjiang 					memcpy(vec.iv.val, val.val,
13234418919fSjohnjiang 						   TDES_BLOCK_SIZE);
13244418919fSjohnjiang 					memcpy(vec.pt.val, prev_out,
13254418919fSjohnjiang 						   TDES_BLOCK_SIZE);
13264418919fSjohnjiang 				}
13274418919fSjohnjiang 			} else {
13284418919fSjohnjiang 				if (test_mode == TDES_MODE_ECB) {
13294418919fSjohnjiang 					memcpy(vec.ct.val, val.val,
13304418919fSjohnjiang 						   TDES_BLOCK_SIZE);
13314418919fSjohnjiang 				} else {
13324418919fSjohnjiang 					memcpy(vec.iv.val, vec.ct.val,
13334418919fSjohnjiang 						   TDES_BLOCK_SIZE);
13344418919fSjohnjiang 					memcpy(vec.ct.val, val.val,
13354418919fSjohnjiang 						   TDES_BLOCK_SIZE);
13364418919fSjohnjiang 				}
1337d30ea906Sjfb8856606 			}
1338d30ea906Sjfb8856606 
1339d30ea906Sjfb8856606 			if (j == TDES_INTERN_ITER - 1)
1340d30ea906Sjfb8856606 				continue;
1341d30ea906Sjfb8856606 
1342d30ea906Sjfb8856606 			memcpy(prev_out, val.val, TDES_BLOCK_SIZE);
1343d30ea906Sjfb8856606 
1344d30ea906Sjfb8856606 			if (j == TDES_INTERN_ITER - 3)
1345d30ea906Sjfb8856606 				memcpy(prev_prev_out, val.val, TDES_BLOCK_SIZE);
1346d30ea906Sjfb8856606 		}
1347d30ea906Sjfb8856606 
1348d30ea906Sjfb8856606 		info.parse_writeback(&val);
1349d30ea906Sjfb8856606 		fprintf(info.fp_wr, "\n");
1350d30ea906Sjfb8856606 
1351d30ea906Sjfb8856606 		if (i == TDES_EXTERN_ITER - 1)
1352d30ea906Sjfb8856606 			continue;
1353d30ea906Sjfb8856606 
1354d30ea906Sjfb8856606 		/** update key */
1355d30ea906Sjfb8856606 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
1356d30ea906Sjfb8856606 
1357d30ea906Sjfb8856606 		if (info.interim_info.tdes_data.nb_keys == 0) {
1358d30ea906Sjfb8856606 			if (memcmp(val_key.val, val_key.val + 8, 8) == 0)
1359d30ea906Sjfb8856606 				info.interim_info.tdes_data.nb_keys = 1;
1360d30ea906Sjfb8856606 			else if (memcmp(val_key.val, val_key.val + 16, 8) == 0)
1361d30ea906Sjfb8856606 				info.interim_info.tdes_data.nb_keys = 2;
1362d30ea906Sjfb8856606 			else
1363d30ea906Sjfb8856606 				info.interim_info.tdes_data.nb_keys = 3;
1364d30ea906Sjfb8856606 
1365d30ea906Sjfb8856606 		}
1366d30ea906Sjfb8856606 
1367d30ea906Sjfb8856606 		for (k = 0; k < TDES_BLOCK_SIZE; k++) {
1368d30ea906Sjfb8856606 
1369d30ea906Sjfb8856606 			switch (info.interim_info.tdes_data.nb_keys) {
1370d30ea906Sjfb8856606 			case 3:
1371d30ea906Sjfb8856606 				val_key.val[k] ^= val.val[k];
1372d30ea906Sjfb8856606 				val_key.val[k + 8] ^= prev_out[k];
1373d30ea906Sjfb8856606 				val_key.val[k + 16] ^= prev_prev_out[k];
1374d30ea906Sjfb8856606 				break;
1375d30ea906Sjfb8856606 			case 2:
1376d30ea906Sjfb8856606 				val_key.val[k] ^= val.val[k];
1377d30ea906Sjfb8856606 				val_key.val[k + 8] ^= prev_out[k];
1378d30ea906Sjfb8856606 				val_key.val[k + 16] ^= val.val[k];
1379d30ea906Sjfb8856606 				break;
1380d30ea906Sjfb8856606 			default: /* case 1 */
1381d30ea906Sjfb8856606 				val_key.val[k] ^= val.val[k];
1382d30ea906Sjfb8856606 				val_key.val[k + 8] ^= val.val[k];
1383d30ea906Sjfb8856606 				val_key.val[k + 16] ^= val.val[k];
1384d30ea906Sjfb8856606 				break;
1385d30ea906Sjfb8856606 			}
1386d30ea906Sjfb8856606 
1387d30ea906Sjfb8856606 		}
1388d30ea906Sjfb8856606 
1389d30ea906Sjfb8856606 		for (k = 0; k < 24; k++)
1390d30ea906Sjfb8856606 			val_key.val[k] = (__builtin_popcount(val_key.val[k]) &
1391d30ea906Sjfb8856606 					0x1) ?
1392d30ea906Sjfb8856606 					val_key.val[k] : (val_key.val[k] ^ 0x1);
1393d30ea906Sjfb8856606 
1394d30ea906Sjfb8856606 		if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
13954418919fSjohnjiang 			if (test_mode == TDES_MODE_ECB) {
13964418919fSjohnjiang 				memcpy(vec.pt.val, val.val, TDES_BLOCK_SIZE);
13974418919fSjohnjiang 			} else {
1398d30ea906Sjfb8856606 				memcpy(vec.iv.val, val.val, TDES_BLOCK_SIZE);
1399d30ea906Sjfb8856606 				memcpy(vec.pt.val, prev_out, TDES_BLOCK_SIZE);
14004418919fSjohnjiang 			}
14014418919fSjohnjiang 		} else {
14024418919fSjohnjiang 			if (test_mode == TDES_MODE_ECB) {
14034418919fSjohnjiang 				memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE);
1404d30ea906Sjfb8856606 			} else {
1405d30ea906Sjfb8856606 				memcpy(vec.iv.val, prev_out, TDES_BLOCK_SIZE);
1406d30ea906Sjfb8856606 				memcpy(vec.ct.val, val.val, TDES_BLOCK_SIZE);
1407d30ea906Sjfb8856606 			}
1408d30ea906Sjfb8856606 		}
14094418919fSjohnjiang 	}
1410d30ea906Sjfb8856606 
1411*2d9fd380Sjfb8856606 	if (val.val)
1412*2d9fd380Sjfb8856606 		free(val.val);
1413*2d9fd380Sjfb8856606 
1414d30ea906Sjfb8856606 	return 0;
1415d30ea906Sjfb8856606 }
1416d30ea906Sjfb8856606 
1417d30ea906Sjfb8856606 static int
fips_mct_aes_ecb_test(void)14184418919fSjohnjiang fips_mct_aes_ecb_test(void)
14194418919fSjohnjiang {
14204418919fSjohnjiang #define AES_BLOCK_SIZE	16
14214418919fSjohnjiang #define AES_EXTERN_ITER	100
14224418919fSjohnjiang #define AES_INTERN_ITER	1000
1423*2d9fd380Sjfb8856606 	struct fips_val val = {NULL, 0}, val_key;
14244418919fSjohnjiang 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
14254418919fSjohnjiang 	uint32_t i, j, k;
14264418919fSjohnjiang 	int ret;
14274418919fSjohnjiang 
14284418919fSjohnjiang 	for (i = 0; i < AES_EXTERN_ITER; i++) {
14294418919fSjohnjiang 		if (i != 0)
14304418919fSjohnjiang 			update_info_vec(i);
14314418919fSjohnjiang 
14324418919fSjohnjiang 		fips_test_write_one_case();
14334418919fSjohnjiang 
14344418919fSjohnjiang 		for (j = 0; j < AES_INTERN_ITER; j++) {
14354418919fSjohnjiang 			ret = fips_run_test();
14364418919fSjohnjiang 			if (ret < 0) {
14374418919fSjohnjiang 				if (ret == -EPERM) {
14384418919fSjohnjiang 					fprintf(info.fp_wr, "Bypass\n");
14394418919fSjohnjiang 					return 0;
14404418919fSjohnjiang 				}
14414418919fSjohnjiang 
14424418919fSjohnjiang 				return ret;
14434418919fSjohnjiang 			}
14444418919fSjohnjiang 
1445*2d9fd380Sjfb8856606 			ret = get_writeback_data(&val);
1446*2d9fd380Sjfb8856606 			if (ret < 0)
1447*2d9fd380Sjfb8856606 				return ret;
14484418919fSjohnjiang 
14494418919fSjohnjiang 			if (info.op == FIPS_TEST_ENC_AUTH_GEN)
14504418919fSjohnjiang 				memcpy(vec.pt.val, val.val, AES_BLOCK_SIZE);
14514418919fSjohnjiang 			else
14524418919fSjohnjiang 				memcpy(vec.ct.val, val.val, AES_BLOCK_SIZE);
14534418919fSjohnjiang 
14544418919fSjohnjiang 			if (j == AES_INTERN_ITER - 1)
14554418919fSjohnjiang 				continue;
14564418919fSjohnjiang 
14574418919fSjohnjiang 			memcpy(prev_out, val.val, AES_BLOCK_SIZE);
14584418919fSjohnjiang 		}
14594418919fSjohnjiang 
14604418919fSjohnjiang 		info.parse_writeback(&val);
14614418919fSjohnjiang 		fprintf(info.fp_wr, "\n");
14624418919fSjohnjiang 
14634418919fSjohnjiang 		if (i == AES_EXTERN_ITER - 1)
14644418919fSjohnjiang 			continue;
14654418919fSjohnjiang 
14664418919fSjohnjiang 		/** update key */
14674418919fSjohnjiang 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
14684418919fSjohnjiang 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
14694418919fSjohnjiang 			switch (vec.cipher_auth.key.len) {
14704418919fSjohnjiang 			case 16:
14714418919fSjohnjiang 				val_key.val[k] ^= val.val[k];
14724418919fSjohnjiang 				break;
14734418919fSjohnjiang 			case 24:
14744418919fSjohnjiang 				if (k < 8)
14754418919fSjohnjiang 					val_key.val[k] ^= prev_out[k + 8];
14764418919fSjohnjiang 				else
14774418919fSjohnjiang 					val_key.val[k] ^= val.val[k - 8];
14784418919fSjohnjiang 				break;
14794418919fSjohnjiang 			case 32:
14804418919fSjohnjiang 				if (k < 16)
14814418919fSjohnjiang 					val_key.val[k] ^= prev_out[k];
14824418919fSjohnjiang 				else
14834418919fSjohnjiang 					val_key.val[k] ^= val.val[k - 16];
14844418919fSjohnjiang 				break;
14854418919fSjohnjiang 			default:
14864418919fSjohnjiang 				return -1;
14874418919fSjohnjiang 			}
14884418919fSjohnjiang 		}
14894418919fSjohnjiang 	}
14904418919fSjohnjiang 
1491*2d9fd380Sjfb8856606 	if (val.val)
1492*2d9fd380Sjfb8856606 		free(val.val);
1493*2d9fd380Sjfb8856606 
14944418919fSjohnjiang 	return 0;
14954418919fSjohnjiang }
14964418919fSjohnjiang static int
fips_mct_aes_test(void)1497d30ea906Sjfb8856606 fips_mct_aes_test(void)
1498d30ea906Sjfb8856606 {
1499d30ea906Sjfb8856606 #define AES_BLOCK_SIZE	16
1500d30ea906Sjfb8856606 #define AES_EXTERN_ITER	100
1501d30ea906Sjfb8856606 #define AES_INTERN_ITER	1000
1502*2d9fd380Sjfb8856606 	struct fips_val val = {NULL, 0}, val_key;
1503d30ea906Sjfb8856606 	uint8_t prev_out[AES_BLOCK_SIZE] = {0};
1504d30ea906Sjfb8856606 	uint8_t prev_in[AES_BLOCK_SIZE] = {0};
1505d30ea906Sjfb8856606 	uint32_t i, j, k;
1506d30ea906Sjfb8856606 	int ret;
1507d30ea906Sjfb8856606 
15084418919fSjohnjiang 	if (info.interim_info.aes_data.cipher_algo == RTE_CRYPTO_CIPHER_AES_ECB)
15094418919fSjohnjiang 		return fips_mct_aes_ecb_test();
15104418919fSjohnjiang 
1511d30ea906Sjfb8856606 	for (i = 0; i < AES_EXTERN_ITER; i++) {
1512d30ea906Sjfb8856606 		if (i != 0)
1513d30ea906Sjfb8856606 			update_info_vec(i);
1514d30ea906Sjfb8856606 
1515d30ea906Sjfb8856606 		fips_test_write_one_case();
1516d30ea906Sjfb8856606 
1517d30ea906Sjfb8856606 		for (j = 0; j < AES_INTERN_ITER; j++) {
1518d30ea906Sjfb8856606 			ret = fips_run_test();
1519d30ea906Sjfb8856606 			if (ret < 0) {
1520d30ea906Sjfb8856606 				if (ret == -EPERM) {
1521d30ea906Sjfb8856606 					fprintf(info.fp_wr, "Bypass\n");
1522d30ea906Sjfb8856606 					return 0;
1523d30ea906Sjfb8856606 				}
1524d30ea906Sjfb8856606 
1525d30ea906Sjfb8856606 				return ret;
1526d30ea906Sjfb8856606 			}
1527d30ea906Sjfb8856606 
1528*2d9fd380Sjfb8856606 			ret = get_writeback_data(&val);
1529*2d9fd380Sjfb8856606 			if (ret < 0)
1530*2d9fd380Sjfb8856606 				return ret;
1531d30ea906Sjfb8856606 
1532d30ea906Sjfb8856606 			if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
1533d30ea906Sjfb8856606 				memcpy(prev_in, vec.ct.val, AES_BLOCK_SIZE);
1534d30ea906Sjfb8856606 
1535d30ea906Sjfb8856606 			if (j == 0) {
1536d30ea906Sjfb8856606 				memcpy(prev_out, val.val, AES_BLOCK_SIZE);
1537d30ea906Sjfb8856606 
1538d30ea906Sjfb8856606 				if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1539d30ea906Sjfb8856606 					memcpy(vec.pt.val, vec.iv.val,
1540d30ea906Sjfb8856606 							AES_BLOCK_SIZE);
1541d30ea906Sjfb8856606 					memcpy(vec.iv.val, val.val,
1542d30ea906Sjfb8856606 							AES_BLOCK_SIZE);
1543d30ea906Sjfb8856606 				} else {
1544d30ea906Sjfb8856606 					memcpy(vec.ct.val, vec.iv.val,
1545d30ea906Sjfb8856606 							AES_BLOCK_SIZE);
1546d30ea906Sjfb8856606 					memcpy(vec.iv.val, prev_in,
1547d30ea906Sjfb8856606 							AES_BLOCK_SIZE);
1548d30ea906Sjfb8856606 				}
1549d30ea906Sjfb8856606 				continue;
1550d30ea906Sjfb8856606 			}
1551d30ea906Sjfb8856606 
1552d30ea906Sjfb8856606 			if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
1553d30ea906Sjfb8856606 				memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE);
1554d30ea906Sjfb8856606 				memcpy(vec.pt.val, prev_out, AES_BLOCK_SIZE);
1555d30ea906Sjfb8856606 			} else {
1556d30ea906Sjfb8856606 				memcpy(vec.iv.val, prev_in, AES_BLOCK_SIZE);
1557d30ea906Sjfb8856606 				memcpy(vec.ct.val, prev_out, AES_BLOCK_SIZE);
1558d30ea906Sjfb8856606 			}
1559d30ea906Sjfb8856606 
1560d30ea906Sjfb8856606 			if (j == AES_INTERN_ITER - 1)
1561d30ea906Sjfb8856606 				continue;
1562d30ea906Sjfb8856606 
1563d30ea906Sjfb8856606 			memcpy(prev_out, val.val, AES_BLOCK_SIZE);
1564d30ea906Sjfb8856606 		}
1565d30ea906Sjfb8856606 
1566d30ea906Sjfb8856606 		info.parse_writeback(&val);
1567d30ea906Sjfb8856606 		fprintf(info.fp_wr, "\n");
1568d30ea906Sjfb8856606 
1569d30ea906Sjfb8856606 		if (i == AES_EXTERN_ITER - 1)
1570d30ea906Sjfb8856606 			continue;
1571d30ea906Sjfb8856606 
1572d30ea906Sjfb8856606 		/** update key */
1573d30ea906Sjfb8856606 		memcpy(&val_key, &vec.cipher_auth.key, sizeof(val_key));
1574d30ea906Sjfb8856606 		for (k = 0; k < vec.cipher_auth.key.len; k++) {
1575d30ea906Sjfb8856606 			switch (vec.cipher_auth.key.len) {
1576d30ea906Sjfb8856606 			case 16:
1577d30ea906Sjfb8856606 				val_key.val[k] ^= val.val[k];
1578d30ea906Sjfb8856606 				break;
1579d30ea906Sjfb8856606 			case 24:
1580d30ea906Sjfb8856606 				if (k < 8)
1581d30ea906Sjfb8856606 					val_key.val[k] ^= prev_out[k + 8];
1582d30ea906Sjfb8856606 				else
1583d30ea906Sjfb8856606 					val_key.val[k] ^= val.val[k - 8];
1584d30ea906Sjfb8856606 				break;
1585d30ea906Sjfb8856606 			case 32:
1586d30ea906Sjfb8856606 				if (k < 16)
1587d30ea906Sjfb8856606 					val_key.val[k] ^= prev_out[k];
1588d30ea906Sjfb8856606 				else
1589d30ea906Sjfb8856606 					val_key.val[k] ^= val.val[k - 16];
1590d30ea906Sjfb8856606 				break;
1591d30ea906Sjfb8856606 			default:
1592d30ea906Sjfb8856606 				return -1;
1593d30ea906Sjfb8856606 			}
1594d30ea906Sjfb8856606 		}
1595d30ea906Sjfb8856606 
1596d30ea906Sjfb8856606 		if (info.op == FIPS_TEST_DEC_AUTH_VERIF)
1597d30ea906Sjfb8856606 			memcpy(vec.iv.val, val.val, AES_BLOCK_SIZE);
1598d30ea906Sjfb8856606 	}
1599d30ea906Sjfb8856606 
1600*2d9fd380Sjfb8856606 	if (val.val)
1601*2d9fd380Sjfb8856606 		free(val.val);
1602*2d9fd380Sjfb8856606 
1603d30ea906Sjfb8856606 	return 0;
1604d30ea906Sjfb8856606 }
1605d30ea906Sjfb8856606 
1606d30ea906Sjfb8856606 static int
fips_mct_sha_test(void)16074418919fSjohnjiang fips_mct_sha_test(void)
16084418919fSjohnjiang {
16094418919fSjohnjiang #define SHA_EXTERN_ITER	100
16104418919fSjohnjiang #define SHA_INTERN_ITER	1000
16114418919fSjohnjiang #define SHA_MD_BLOCK	3
1612*2d9fd380Sjfb8856606 	struct fips_val val = {NULL, 0}, md[SHA_MD_BLOCK];
16134418919fSjohnjiang 	char temp[MAX_DIGEST_SIZE*2];
16144418919fSjohnjiang 	int ret;
16154418919fSjohnjiang 	uint32_t i, j;
16164418919fSjohnjiang 
16174418919fSjohnjiang 	val.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0);
16184418919fSjohnjiang 	for (i = 0; i < SHA_MD_BLOCK; i++)
16194418919fSjohnjiang 		md[i].val = rte_malloc(NULL, (MAX_DIGEST_SIZE*2), 0);
16204418919fSjohnjiang 
16214418919fSjohnjiang 	rte_free(vec.pt.val);
16224418919fSjohnjiang 	vec.pt.val = rte_malloc(NULL, (MAX_DIGEST_SIZE*SHA_MD_BLOCK), 0);
16234418919fSjohnjiang 
16244418919fSjohnjiang 	fips_test_write_one_case();
16254418919fSjohnjiang 	fprintf(info.fp_wr, "\n");
16264418919fSjohnjiang 
16274418919fSjohnjiang 	for (j = 0; j < SHA_EXTERN_ITER; j++) {
16284418919fSjohnjiang 
16294418919fSjohnjiang 		memcpy(md[0].val, vec.cipher_auth.digest.val,
16304418919fSjohnjiang 			vec.cipher_auth.digest.len);
16314418919fSjohnjiang 		md[0].len = vec.cipher_auth.digest.len;
16324418919fSjohnjiang 		memcpy(md[1].val, vec.cipher_auth.digest.val,
16334418919fSjohnjiang 			vec.cipher_auth.digest.len);
16344418919fSjohnjiang 		md[1].len = vec.cipher_auth.digest.len;
16354418919fSjohnjiang 		memcpy(md[2].val, vec.cipher_auth.digest.val,
16364418919fSjohnjiang 			vec.cipher_auth.digest.len);
16374418919fSjohnjiang 		md[2].len = vec.cipher_auth.digest.len;
16384418919fSjohnjiang 
16394418919fSjohnjiang 		for (i = 0; i < (SHA_INTERN_ITER); i++) {
16404418919fSjohnjiang 
16414418919fSjohnjiang 			memcpy(vec.pt.val, md[0].val,
16424418919fSjohnjiang 				(size_t)md[0].len);
16434418919fSjohnjiang 			memcpy((vec.pt.val + md[0].len), md[1].val,
16444418919fSjohnjiang 				(size_t)md[1].len);
16454418919fSjohnjiang 			memcpy((vec.pt.val + md[0].len + md[1].len),
16464418919fSjohnjiang 				md[2].val,
16474418919fSjohnjiang 				(size_t)md[2].len);
16484418919fSjohnjiang 			vec.pt.len = md[0].len + md[1].len + md[2].len;
16494418919fSjohnjiang 
16504418919fSjohnjiang 			ret = fips_run_test();
16514418919fSjohnjiang 			if (ret < 0) {
1652*2d9fd380Sjfb8856606 				if (ret == -EPERM || ret == -ENOTSUP) {
16534418919fSjohnjiang 					fprintf(info.fp_wr, "Bypass\n\n");
16544418919fSjohnjiang 					return 0;
16554418919fSjohnjiang 				}
16564418919fSjohnjiang 				return ret;
16574418919fSjohnjiang 			}
16584418919fSjohnjiang 
1659*2d9fd380Sjfb8856606 			ret = get_writeback_data(&val);
1660*2d9fd380Sjfb8856606 			if (ret < 0)
1661*2d9fd380Sjfb8856606 				return ret;
16624418919fSjohnjiang 
16634418919fSjohnjiang 			memcpy(md[0].val, md[1].val, md[1].len);
16644418919fSjohnjiang 			md[0].len = md[1].len;
16654418919fSjohnjiang 			memcpy(md[1].val, md[2].val, md[2].len);
16664418919fSjohnjiang 			md[1].len = md[2].len;
16674418919fSjohnjiang 
16684418919fSjohnjiang 			memcpy(md[2].val, (val.val + vec.pt.len),
16694418919fSjohnjiang 				vec.cipher_auth.digest.len);
16704418919fSjohnjiang 			md[2].len = vec.cipher_auth.digest.len;
16714418919fSjohnjiang 		}
16724418919fSjohnjiang 
16734418919fSjohnjiang 		memcpy(vec.cipher_auth.digest.val, md[2].val, md[2].len);
16744418919fSjohnjiang 		vec.cipher_auth.digest.len = md[2].len;
16754418919fSjohnjiang 
16764418919fSjohnjiang 		fprintf(info.fp_wr, "COUNT = %u\n", j);
16774418919fSjohnjiang 
16784418919fSjohnjiang 		writeback_hex_str("", temp, &vec.cipher_auth.digest);
16794418919fSjohnjiang 
16804418919fSjohnjiang 		fprintf(info.fp_wr, "MD = %s\n\n", temp);
16814418919fSjohnjiang 	}
16824418919fSjohnjiang 
16834418919fSjohnjiang 	for (i = 0; i < (SHA_MD_BLOCK); i++)
16844418919fSjohnjiang 		rte_free(md[i].val);
16854418919fSjohnjiang 
16864418919fSjohnjiang 	rte_free(vec.pt.val);
16874418919fSjohnjiang 
1688*2d9fd380Sjfb8856606 	if (val.val)
1689*2d9fd380Sjfb8856606 		free(val.val);
1690*2d9fd380Sjfb8856606 
16914418919fSjohnjiang 	return 0;
16924418919fSjohnjiang }
16934418919fSjohnjiang 
16944418919fSjohnjiang 
16954418919fSjohnjiang static int
init_test_ops(void)1696d30ea906Sjfb8856606 init_test_ops(void)
1697d30ea906Sjfb8856606 {
1698d30ea906Sjfb8856606 	switch (info.algo) {
1699d30ea906Sjfb8856606 	case FIPS_TEST_ALGO_AES:
1700d30ea906Sjfb8856606 		test_ops.prepare_op = prepare_cipher_op;
1701d30ea906Sjfb8856606 		test_ops.prepare_xform  = prepare_aes_xform;
1702d30ea906Sjfb8856606 		if (info.interim_info.aes_data.test_type == AESAVS_TYPE_MCT)
1703d30ea906Sjfb8856606 			test_ops.test = fips_mct_aes_test;
1704d30ea906Sjfb8856606 		else
1705d30ea906Sjfb8856606 			test_ops.test = fips_generic_test;
1706d30ea906Sjfb8856606 		break;
1707d30ea906Sjfb8856606 	case FIPS_TEST_ALGO_HMAC:
1708d30ea906Sjfb8856606 		test_ops.prepare_op = prepare_auth_op;
1709d30ea906Sjfb8856606 		test_ops.prepare_xform = prepare_hmac_xform;
1710d30ea906Sjfb8856606 		test_ops.test = fips_generic_test;
1711d30ea906Sjfb8856606 		break;
1712d30ea906Sjfb8856606 	case FIPS_TEST_ALGO_TDES:
1713d30ea906Sjfb8856606 		test_ops.prepare_op = prepare_cipher_op;
1714d30ea906Sjfb8856606 		test_ops.prepare_xform  = prepare_tdes_xform;
1715d30ea906Sjfb8856606 		if (info.interim_info.tdes_data.test_type == TDES_MCT)
1716d30ea906Sjfb8856606 			test_ops.test = fips_mct_tdes_test;
1717d30ea906Sjfb8856606 		else
1718d30ea906Sjfb8856606 			test_ops.test = fips_generic_test;
1719d30ea906Sjfb8856606 		break;
1720d30ea906Sjfb8856606 	case FIPS_TEST_ALGO_AES_GCM:
1721d30ea906Sjfb8856606 		test_ops.prepare_op = prepare_aead_op;
1722d30ea906Sjfb8856606 		test_ops.prepare_xform = prepare_gcm_xform;
1723d30ea906Sjfb8856606 		test_ops.test = fips_generic_test;
1724d30ea906Sjfb8856606 		break;
1725d30ea906Sjfb8856606 	case FIPS_TEST_ALGO_AES_CMAC:
1726d30ea906Sjfb8856606 		test_ops.prepare_op = prepare_auth_op;
1727d30ea906Sjfb8856606 		test_ops.prepare_xform = prepare_cmac_xform;
1728d30ea906Sjfb8856606 		test_ops.test = fips_generic_test;
1729d30ea906Sjfb8856606 		break;
1730d30ea906Sjfb8856606 	case FIPS_TEST_ALGO_AES_CCM:
1731d30ea906Sjfb8856606 		test_ops.prepare_op = prepare_aead_op;
1732d30ea906Sjfb8856606 		test_ops.prepare_xform = prepare_ccm_xform;
1733d30ea906Sjfb8856606 		test_ops.test = fips_generic_test;
1734d30ea906Sjfb8856606 		break;
17354418919fSjohnjiang 	case FIPS_TEST_ALGO_SHA:
17364418919fSjohnjiang 		test_ops.prepare_op = prepare_auth_op;
17374418919fSjohnjiang 		test_ops.prepare_xform = prepare_sha_xform;
17384418919fSjohnjiang 		if (info.interim_info.sha_data.test_type == SHA_MCT)
17394418919fSjohnjiang 			test_ops.test = fips_mct_sha_test;
17404418919fSjohnjiang 		else
17414418919fSjohnjiang 			test_ops.test = fips_generic_test;
17424418919fSjohnjiang 		break;
1743*2d9fd380Sjfb8856606 	case FIPS_TEST_ALGO_AES_XTS:
1744*2d9fd380Sjfb8856606 		test_ops.prepare_op = prepare_cipher_op;
1745*2d9fd380Sjfb8856606 		test_ops.prepare_xform = prepare_xts_xform;
1746*2d9fd380Sjfb8856606 		test_ops.test = fips_generic_test;
1747*2d9fd380Sjfb8856606 		break;
1748d30ea906Sjfb8856606 	default:
17494418919fSjohnjiang 		if (strstr(info.file_name, "TECB") ||
17504418919fSjohnjiang 				strstr(info.file_name, "TCBC")) {
17514418919fSjohnjiang 			info.algo = FIPS_TEST_ALGO_TDES;
17524418919fSjohnjiang 			test_ops.prepare_op = prepare_cipher_op;
17534418919fSjohnjiang 			test_ops.prepare_xform	= prepare_tdes_xform;
17544418919fSjohnjiang 			if (info.interim_info.tdes_data.test_type == TDES_MCT)
17554418919fSjohnjiang 				test_ops.test = fips_mct_tdes_test;
17564418919fSjohnjiang 			else
17574418919fSjohnjiang 				test_ops.test = fips_generic_test;
17584418919fSjohnjiang 			break;
17594418919fSjohnjiang 		}
1760d30ea906Sjfb8856606 		return -1;
1761d30ea906Sjfb8856606 	}
1762d30ea906Sjfb8856606 
1763d30ea906Sjfb8856606 	return 0;
1764d30ea906Sjfb8856606 }
1765d30ea906Sjfb8856606 
1766d30ea906Sjfb8856606 static void
print_test_block(void)1767d30ea906Sjfb8856606 print_test_block(void)
1768d30ea906Sjfb8856606 {
1769d30ea906Sjfb8856606 	uint32_t i;
1770d30ea906Sjfb8856606 
1771d30ea906Sjfb8856606 	for (i = 0; i < info.nb_vec_lines; i++)
1772d30ea906Sjfb8856606 		printf("%s\n", info.vec[i]);
1773d30ea906Sjfb8856606 
1774d30ea906Sjfb8856606 	printf("\n");
1775d30ea906Sjfb8856606 }
1776d30ea906Sjfb8856606 
1777d30ea906Sjfb8856606 static int
fips_test_one_file(void)1778d30ea906Sjfb8856606 fips_test_one_file(void)
1779d30ea906Sjfb8856606 {
1780d30ea906Sjfb8856606 	int fetch_ret = 0, ret;
1781d30ea906Sjfb8856606 
1782d30ea906Sjfb8856606 	ret = init_test_ops();
1783d30ea906Sjfb8856606 	if (ret < 0) {
1784d30ea906Sjfb8856606 		RTE_LOG(ERR, USER1, "Error %i: Init test op\n", ret);
1785d30ea906Sjfb8856606 		return ret;
1786d30ea906Sjfb8856606 	}
1787d30ea906Sjfb8856606 
1788d30ea906Sjfb8856606 	while (ret >= 0 && fetch_ret == 0) {
1789d30ea906Sjfb8856606 		fetch_ret = fips_test_fetch_one_block();
1790d30ea906Sjfb8856606 		if (fetch_ret < 0) {
1791d30ea906Sjfb8856606 			RTE_LOG(ERR, USER1, "Error %i: Fetch block\n",
1792d30ea906Sjfb8856606 					fetch_ret);
1793d30ea906Sjfb8856606 			ret = fetch_ret;
1794d30ea906Sjfb8856606 			goto error_one_case;
1795d30ea906Sjfb8856606 		}
1796d30ea906Sjfb8856606 
1797d30ea906Sjfb8856606 		if (info.nb_vec_lines == 0) {
1798d30ea906Sjfb8856606 			if (fetch_ret == -EOF)
1799d30ea906Sjfb8856606 				break;
1800d30ea906Sjfb8856606 
1801d30ea906Sjfb8856606 			fprintf(info.fp_wr, "\n");
1802d30ea906Sjfb8856606 			continue;
1803d30ea906Sjfb8856606 		}
1804d30ea906Sjfb8856606 
1805d30ea906Sjfb8856606 		ret = fips_test_parse_one_case();
1806d30ea906Sjfb8856606 		switch (ret) {
1807d30ea906Sjfb8856606 		case 0:
1808d30ea906Sjfb8856606 			ret = test_ops.test();
1809d30ea906Sjfb8856606 			if (ret == 0)
1810d30ea906Sjfb8856606 				break;
1811d30ea906Sjfb8856606 			RTE_LOG(ERR, USER1, "Error %i: test block\n",
1812d30ea906Sjfb8856606 					ret);
1813d30ea906Sjfb8856606 			goto error_one_case;
1814d30ea906Sjfb8856606 		case 1:
1815d30ea906Sjfb8856606 			break;
1816d30ea906Sjfb8856606 		default:
1817d30ea906Sjfb8856606 			RTE_LOG(ERR, USER1, "Error %i: Parse block\n",
1818d30ea906Sjfb8856606 					ret);
1819d30ea906Sjfb8856606 			goto error_one_case;
1820d30ea906Sjfb8856606 		}
1821d30ea906Sjfb8856606 
1822d30ea906Sjfb8856606 		continue;
1823d30ea906Sjfb8856606 error_one_case:
1824d30ea906Sjfb8856606 		print_test_block();
1825d30ea906Sjfb8856606 	}
1826d30ea906Sjfb8856606 
1827d30ea906Sjfb8856606 	fips_test_clear();
1828d30ea906Sjfb8856606 
1829*2d9fd380Sjfb8856606 	if (env.digest)
1830*2d9fd380Sjfb8856606 		rte_free(env.digest);
1831*2d9fd380Sjfb8856606 	if (env.mbuf)
1832*2d9fd380Sjfb8856606 		rte_pktmbuf_free(env.mbuf);
1833d30ea906Sjfb8856606 
1834*2d9fd380Sjfb8856606 	return ret;
1835d30ea906Sjfb8856606 }
1836