xref: /dpdk/examples/fips_validation/fips_validation.c (revision 3d0fad56b74a02fe6c1bb2b3ee752646c34cfbc5)
1*3d0fad56SMarko Kovacevic /* SPDX-License-Identifier: BSD-3-Clause
2*3d0fad56SMarko Kovacevic  * Copyright(c) 2018 Intel Corporation
3*3d0fad56SMarko Kovacevic  */
4*3d0fad56SMarko Kovacevic 
5*3d0fad56SMarko Kovacevic #include <stdio.h>
6*3d0fad56SMarko Kovacevic #include <string.h>
7*3d0fad56SMarko Kovacevic 
8*3d0fad56SMarko Kovacevic #include <rte_string_fns.h>
9*3d0fad56SMarko Kovacevic #include <rte_cryptodev.h>
10*3d0fad56SMarko Kovacevic #include <rte_malloc.h>
11*3d0fad56SMarko Kovacevic 
12*3d0fad56SMarko Kovacevic #include "fips_validation.h"
13*3d0fad56SMarko Kovacevic 
14*3d0fad56SMarko Kovacevic #define skip_white_spaces(pos)			\
15*3d0fad56SMarko Kovacevic ({						\
16*3d0fad56SMarko Kovacevic 	__typeof__(pos) _p = (pos);		\
17*3d0fad56SMarko Kovacevic 	for ( ; isspace(*_p); _p++)		\
18*3d0fad56SMarko Kovacevic 		;				\
19*3d0fad56SMarko Kovacevic 	_p;					\
20*3d0fad56SMarko Kovacevic })
21*3d0fad56SMarko Kovacevic 
22*3d0fad56SMarko Kovacevic static int
23*3d0fad56SMarko Kovacevic get_file_line(void)
24*3d0fad56SMarko Kovacevic {
25*3d0fad56SMarko Kovacevic 	FILE *fp = info.fp_rd;
26*3d0fad56SMarko Kovacevic 	char *line = info.one_line_text;
27*3d0fad56SMarko Kovacevic 	int ret;
28*3d0fad56SMarko Kovacevic 	uint32_t loc = 0;
29*3d0fad56SMarko Kovacevic 
30*3d0fad56SMarko Kovacevic 	memset(line, 0, MAX_LINE_CHAR);
31*3d0fad56SMarko Kovacevic 	while ((ret = fgetc(fp)) != EOF) {
32*3d0fad56SMarko Kovacevic 		char c = (char)ret;
33*3d0fad56SMarko Kovacevic 
34*3d0fad56SMarko Kovacevic 		if (loc >= MAX_LINE_CHAR - 1)
35*3d0fad56SMarko Kovacevic 			return -ENOMEM;
36*3d0fad56SMarko Kovacevic 		if (c == '\n')
37*3d0fad56SMarko Kovacevic 			break;
38*3d0fad56SMarko Kovacevic 		line[loc++] = c;
39*3d0fad56SMarko Kovacevic 	}
40*3d0fad56SMarko Kovacevic 
41*3d0fad56SMarko Kovacevic 	if (ret == EOF)
42*3d0fad56SMarko Kovacevic 		return -EOF;
43*3d0fad56SMarko Kovacevic 
44*3d0fad56SMarko Kovacevic 	return 0;
45*3d0fad56SMarko Kovacevic }
46*3d0fad56SMarko Kovacevic 
47*3d0fad56SMarko Kovacevic int
48*3d0fad56SMarko Kovacevic fips_test_fetch_one_block(void)
49*3d0fad56SMarko Kovacevic {
50*3d0fad56SMarko Kovacevic 	size_t size;
51*3d0fad56SMarko Kovacevic 	int ret = 0;
52*3d0fad56SMarko Kovacevic 	uint32_t i;
53*3d0fad56SMarko Kovacevic 
54*3d0fad56SMarko Kovacevic 	for (i = 0; i < info.nb_vec_lines; i++) {
55*3d0fad56SMarko Kovacevic 		free(info.vec[i]);
56*3d0fad56SMarko Kovacevic 		info.vec[i] = NULL;
57*3d0fad56SMarko Kovacevic 	}
58*3d0fad56SMarko Kovacevic 
59*3d0fad56SMarko Kovacevic 	i = 0;
60*3d0fad56SMarko Kovacevic 	do {
61*3d0fad56SMarko Kovacevic 		if (i >= MAX_LINE_PER_VECTOR) {
62*3d0fad56SMarko Kovacevic 			ret = -ENOMEM;
63*3d0fad56SMarko Kovacevic 			goto error_exit;
64*3d0fad56SMarko Kovacevic 		}
65*3d0fad56SMarko Kovacevic 
66*3d0fad56SMarko Kovacevic 		ret = get_file_line();
67*3d0fad56SMarko Kovacevic 		size = strlen(info.one_line_text);
68*3d0fad56SMarko Kovacevic 		if (size == 0)
69*3d0fad56SMarko Kovacevic 			break;
70*3d0fad56SMarko Kovacevic 
71*3d0fad56SMarko Kovacevic 		info.vec[i] = calloc(1, size + 5);
72*3d0fad56SMarko Kovacevic 		if (info.vec[i] == NULL)
73*3d0fad56SMarko Kovacevic 			goto error_exit;
74*3d0fad56SMarko Kovacevic 
75*3d0fad56SMarko Kovacevic 		strlcpy(info.vec[i], info.one_line_text, size + 1);
76*3d0fad56SMarko Kovacevic 		i++;
77*3d0fad56SMarko Kovacevic 	} while (ret == 0);
78*3d0fad56SMarko Kovacevic 
79*3d0fad56SMarko Kovacevic 	info.nb_vec_lines = i;
80*3d0fad56SMarko Kovacevic 
81*3d0fad56SMarko Kovacevic 	return ret;
82*3d0fad56SMarko Kovacevic 
83*3d0fad56SMarko Kovacevic error_exit:
84*3d0fad56SMarko Kovacevic 	for (i = 0; i < MAX_LINE_PER_VECTOR; i++)
85*3d0fad56SMarko Kovacevic 		if (info.vec[i] != NULL) {
86*3d0fad56SMarko Kovacevic 			free(info.vec[i]);
87*3d0fad56SMarko Kovacevic 			info.vec[i] = NULL;
88*3d0fad56SMarko Kovacevic 		}
89*3d0fad56SMarko Kovacevic 
90*3d0fad56SMarko Kovacevic 	info.nb_vec_lines = 0;
91*3d0fad56SMarko Kovacevic 
92*3d0fad56SMarko Kovacevic 	return -ENOMEM;
93*3d0fad56SMarko Kovacevic }
94*3d0fad56SMarko Kovacevic 
95*3d0fad56SMarko Kovacevic static int
96*3d0fad56SMarko Kovacevic fips_test_parse_header(void)
97*3d0fad56SMarko Kovacevic {
98*3d0fad56SMarko Kovacevic 	uint32_t i;
99*3d0fad56SMarko Kovacevic 	char *tmp;
100*3d0fad56SMarko Kovacevic 	int ret;
101*3d0fad56SMarko Kovacevic 	time_t t = time(NULL);
102*3d0fad56SMarko Kovacevic 	struct tm *tm_now = localtime(&t);
103*3d0fad56SMarko Kovacevic 
104*3d0fad56SMarko Kovacevic 	ret = fips_test_fetch_one_block();
105*3d0fad56SMarko Kovacevic 	if (ret < 0)
106*3d0fad56SMarko Kovacevic 		return ret;
107*3d0fad56SMarko Kovacevic 
108*3d0fad56SMarko Kovacevic 	for (i = 0; i < info.nb_vec_lines; i++) {
109*3d0fad56SMarko Kovacevic 
110*3d0fad56SMarko Kovacevic 		tmp = strstr(info.vec[i], "# Config info for ");
111*3d0fad56SMarko Kovacevic 		if (tmp != NULL) {
112*3d0fad56SMarko Kovacevic 			fprintf(info.fp_wr, "%s%s\n", "# Config info for DPDK Cryptodev ",
113*3d0fad56SMarko Kovacevic 					info.device_name);
114*3d0fad56SMarko Kovacevic 			continue;
115*3d0fad56SMarko Kovacevic 		}
116*3d0fad56SMarko Kovacevic 
117*3d0fad56SMarko Kovacevic 		tmp = strstr(info.vec[i], "#  HMAC information for ");
118*3d0fad56SMarko Kovacevic 		if (tmp != NULL) {
119*3d0fad56SMarko Kovacevic 			fprintf(info.fp_wr, "%s%s\n", "#  HMAC information for "
120*3d0fad56SMarko Kovacevic 				"DPDK Cryptodev ",
121*3d0fad56SMarko Kovacevic 				info.device_name);
122*3d0fad56SMarko Kovacevic 			continue;
123*3d0fad56SMarko Kovacevic 		}
124*3d0fad56SMarko Kovacevic 
125*3d0fad56SMarko Kovacevic 		tmp = strstr(info.vec[i], "# Config Info for : ");
126*3d0fad56SMarko Kovacevic 		if (tmp != NULL) {
127*3d0fad56SMarko Kovacevic 
128*3d0fad56SMarko Kovacevic 			fprintf(info.fp_wr, "%s%s\n", "# Config Info for DPDK Cryptodev : ",
129*3d0fad56SMarko Kovacevic 					info.device_name);
130*3d0fad56SMarko Kovacevic 			continue;
131*3d0fad56SMarko Kovacevic 		}
132*3d0fad56SMarko Kovacevic 
133*3d0fad56SMarko Kovacevic 		tmp = strstr(info.vec[i], "# information for ");
134*3d0fad56SMarko Kovacevic 		if (tmp != NULL) {
135*3d0fad56SMarko Kovacevic 
136*3d0fad56SMarko Kovacevic 			char tmp_output[128] = {0};
137*3d0fad56SMarko Kovacevic 
138*3d0fad56SMarko Kovacevic 			strlcpy(tmp_output, info.vec[i], tmp - info.vec[i] + 1);
139*3d0fad56SMarko Kovacevic 
140*3d0fad56SMarko Kovacevic 			fprintf(info.fp_wr, "%s%s%s\n", tmp_output,
141*3d0fad56SMarko Kovacevic 					"information for DPDK Cryptodev ",
142*3d0fad56SMarko Kovacevic 					info.device_name);
143*3d0fad56SMarko Kovacevic 			continue;
144*3d0fad56SMarko Kovacevic 		}
145*3d0fad56SMarko Kovacevic 
146*3d0fad56SMarko Kovacevic 		tmp = strstr(info.vec[i], " test information for ");
147*3d0fad56SMarko Kovacevic 		if (tmp != NULL) {
148*3d0fad56SMarko Kovacevic 			char tmp_output[128] = {0};
149*3d0fad56SMarko Kovacevic 
150*3d0fad56SMarko Kovacevic 			strlcpy(tmp_output, info.vec[i], tmp - info.vec[i] + 1);
151*3d0fad56SMarko Kovacevic 
152*3d0fad56SMarko Kovacevic 			fprintf(info.fp_wr, "%s%s%s\n", tmp_output,
153*3d0fad56SMarko Kovacevic 					"test information for DPDK Cryptodev ",
154*3d0fad56SMarko Kovacevic 					info.device_name);
155*3d0fad56SMarko Kovacevic 			continue;
156*3d0fad56SMarko Kovacevic 		}
157*3d0fad56SMarko Kovacevic 
158*3d0fad56SMarko Kovacevic 		if (i == info.nb_vec_lines - 1) {
159*3d0fad56SMarko Kovacevic 			/** update the time as current time, write to file */
160*3d0fad56SMarko Kovacevic 			fprintf(info.fp_wr, "%s%s\n", "# Generated on ",
161*3d0fad56SMarko Kovacevic 					asctime(tm_now));
162*3d0fad56SMarko Kovacevic 			continue;
163*3d0fad56SMarko Kovacevic 		}
164*3d0fad56SMarko Kovacevic 
165*3d0fad56SMarko Kovacevic 		/* to this point, no field need to update,
166*3d0fad56SMarko Kovacevic 		 *  only copy to rsp file
167*3d0fad56SMarko Kovacevic 		 */
168*3d0fad56SMarko Kovacevic 		fprintf(info.fp_wr, "%s\n", info.vec[i]);
169*3d0fad56SMarko Kovacevic 	}
170*3d0fad56SMarko Kovacevic 
171*3d0fad56SMarko Kovacevic 	return 0;
172*3d0fad56SMarko Kovacevic }
173*3d0fad56SMarko Kovacevic 
174*3d0fad56SMarko Kovacevic static int
175*3d0fad56SMarko Kovacevic parse_file_type(const char *path)
176*3d0fad56SMarko Kovacevic {
177*3d0fad56SMarko Kovacevic 	const char *tmp = path + strlen(path) - 3;
178*3d0fad56SMarko Kovacevic 
179*3d0fad56SMarko Kovacevic 	if (strstr(tmp, REQ_FILE_PERFIX))
180*3d0fad56SMarko Kovacevic 		info.file_type = FIPS_TYPE_REQ;
181*3d0fad56SMarko Kovacevic 	else if (strstr(tmp, RSP_FILE_PERFIX))
182*3d0fad56SMarko Kovacevic 		info.file_type = FIPS_TYPE_RSP;
183*3d0fad56SMarko Kovacevic 	else if (strstr(path, FAX_FILE_PERFIX))
184*3d0fad56SMarko Kovacevic 		info.file_type = FIPS_TYPE_FAX;
185*3d0fad56SMarko Kovacevic 	else
186*3d0fad56SMarko Kovacevic 		return -EINVAL;
187*3d0fad56SMarko Kovacevic 
188*3d0fad56SMarko Kovacevic 	return 0;
189*3d0fad56SMarko Kovacevic }
190*3d0fad56SMarko Kovacevic 
191*3d0fad56SMarko Kovacevic int
192*3d0fad56SMarko Kovacevic fips_test_init(const char *req_file_path, const char *rsp_file_path,
193*3d0fad56SMarko Kovacevic 		const char *device_name)
194*3d0fad56SMarko Kovacevic {
195*3d0fad56SMarko Kovacevic 	if (strcmp(req_file_path, rsp_file_path) == 0) {
196*3d0fad56SMarko Kovacevic 		RTE_LOG(ERR, USER1, "File paths cannot be the same\n");
197*3d0fad56SMarko Kovacevic 		return -EINVAL;
198*3d0fad56SMarko Kovacevic 	}
199*3d0fad56SMarko Kovacevic 
200*3d0fad56SMarko Kovacevic 	fips_test_clear();
201*3d0fad56SMarko Kovacevic 
202*3d0fad56SMarko Kovacevic 	info.algo = FIPS_TEST_ALGO_MAX;
203*3d0fad56SMarko Kovacevic 	if (parse_file_type(req_file_path) < 0) {
204*3d0fad56SMarko Kovacevic 		RTE_LOG(ERR, USER1, "File %s type not supported\n",
205*3d0fad56SMarko Kovacevic 				req_file_path);
206*3d0fad56SMarko Kovacevic 		return -EINVAL;
207*3d0fad56SMarko Kovacevic 	}
208*3d0fad56SMarko Kovacevic 
209*3d0fad56SMarko Kovacevic 	info.fp_rd = fopen(req_file_path, "r");
210*3d0fad56SMarko Kovacevic 	if (!info.fp_rd) {
211*3d0fad56SMarko Kovacevic 		RTE_LOG(ERR, USER1, "Cannot open file %s\n", req_file_path);
212*3d0fad56SMarko Kovacevic 		return -EINVAL;
213*3d0fad56SMarko Kovacevic 	}
214*3d0fad56SMarko Kovacevic 
215*3d0fad56SMarko Kovacevic 	info.fp_wr = fopen(rsp_file_path, "w");
216*3d0fad56SMarko Kovacevic 	if (!info.fp_wr) {
217*3d0fad56SMarko Kovacevic 		RTE_LOG(ERR, USER1, "Cannot open file %s\n", rsp_file_path);
218*3d0fad56SMarko Kovacevic 		return -EINVAL;
219*3d0fad56SMarko Kovacevic 	}
220*3d0fad56SMarko Kovacevic 
221*3d0fad56SMarko Kovacevic 	info.one_line_text = calloc(1, MAX_LINE_CHAR);
222*3d0fad56SMarko Kovacevic 	if (!info.one_line_text) {
223*3d0fad56SMarko Kovacevic 		RTE_LOG(ERR, USER1, "Insufficient memory\n");
224*3d0fad56SMarko Kovacevic 		return -ENOMEM;
225*3d0fad56SMarko Kovacevic 	}
226*3d0fad56SMarko Kovacevic 
227*3d0fad56SMarko Kovacevic 	strlcpy(info.device_name, device_name, sizeof(info.device_name));
228*3d0fad56SMarko Kovacevic 
229*3d0fad56SMarko Kovacevic 	if (fips_test_parse_header() < 0) {
230*3d0fad56SMarko Kovacevic 		RTE_LOG(ERR, USER1, "Failed parsing header\n");
231*3d0fad56SMarko Kovacevic 		return -1;
232*3d0fad56SMarko Kovacevic 	}
233*3d0fad56SMarko Kovacevic 
234*3d0fad56SMarko Kovacevic 	return 0;
235*3d0fad56SMarko Kovacevic }
236*3d0fad56SMarko Kovacevic 
237*3d0fad56SMarko Kovacevic void
238*3d0fad56SMarko Kovacevic fips_test_clear(void)
239*3d0fad56SMarko Kovacevic {
240*3d0fad56SMarko Kovacevic 	if (info.fp_rd)
241*3d0fad56SMarko Kovacevic 		fclose(info.fp_rd);
242*3d0fad56SMarko Kovacevic 	if (info.fp_wr)
243*3d0fad56SMarko Kovacevic 		fclose(info.fp_wr);
244*3d0fad56SMarko Kovacevic 	if (info.one_line_text)
245*3d0fad56SMarko Kovacevic 		free(info.one_line_text);
246*3d0fad56SMarko Kovacevic 	if (info.nb_vec_lines) {
247*3d0fad56SMarko Kovacevic 		uint32_t i;
248*3d0fad56SMarko Kovacevic 
249*3d0fad56SMarko Kovacevic 		for (i = 0; i < info.nb_vec_lines; i++)
250*3d0fad56SMarko Kovacevic 			free(info.vec[i]);
251*3d0fad56SMarko Kovacevic 	}
252*3d0fad56SMarko Kovacevic 
253*3d0fad56SMarko Kovacevic 	memset(&info, 0, sizeof(info));
254*3d0fad56SMarko Kovacevic }
255*3d0fad56SMarko Kovacevic 
256*3d0fad56SMarko Kovacevic int
257*3d0fad56SMarko Kovacevic fips_test_parse_one_case(void)
258*3d0fad56SMarko Kovacevic {
259*3d0fad56SMarko Kovacevic 	uint32_t i, j = 0;
260*3d0fad56SMarko Kovacevic 	uint32_t is_interim = 0;
261*3d0fad56SMarko Kovacevic 	int ret;
262*3d0fad56SMarko Kovacevic 
263*3d0fad56SMarko Kovacevic 	if (info.interim_callbacks) {
264*3d0fad56SMarko Kovacevic 		for (i = 0; i < info.nb_vec_lines; i++) {
265*3d0fad56SMarko Kovacevic 			for (j = 0; info.interim_callbacks[j].key != NULL; j++)
266*3d0fad56SMarko Kovacevic 				if (strstr(info.vec[i],
267*3d0fad56SMarko Kovacevic 					info.interim_callbacks[j].key)) {
268*3d0fad56SMarko Kovacevic 					is_interim = 1;
269*3d0fad56SMarko Kovacevic 
270*3d0fad56SMarko Kovacevic 					ret = info.interim_callbacks[j].cb(
271*3d0fad56SMarko Kovacevic 						info.interim_callbacks[j].key,
272*3d0fad56SMarko Kovacevic 						info.vec[i],
273*3d0fad56SMarko Kovacevic 						info.interim_callbacks[j].val);
274*3d0fad56SMarko Kovacevic 					if (ret < 0)
275*3d0fad56SMarko Kovacevic 						return ret;
276*3d0fad56SMarko Kovacevic 				}
277*3d0fad56SMarko Kovacevic 		}
278*3d0fad56SMarko Kovacevic 	}
279*3d0fad56SMarko Kovacevic 
280*3d0fad56SMarko Kovacevic 	if (is_interim) {
281*3d0fad56SMarko Kovacevic 		for (i = 0; i < info.nb_vec_lines; i++)
282*3d0fad56SMarko Kovacevic 			fprintf(info.fp_wr, "%s\n", info.vec[i]);
283*3d0fad56SMarko Kovacevic 		fprintf(info.fp_wr, "\n");
284*3d0fad56SMarko Kovacevic 		return 1;
285*3d0fad56SMarko Kovacevic 	}
286*3d0fad56SMarko Kovacevic 
287*3d0fad56SMarko Kovacevic 	for (i = 0; i < info.nb_vec_lines; i++) {
288*3d0fad56SMarko Kovacevic 		for (j = 0; info.callbacks[j].key != NULL; j++)
289*3d0fad56SMarko Kovacevic 			if (strstr(info.vec[i], info.callbacks[j].key)) {
290*3d0fad56SMarko Kovacevic 				ret = info.callbacks[j].cb(
291*3d0fad56SMarko Kovacevic 					info.callbacks[j].key,
292*3d0fad56SMarko Kovacevic 					info.vec[i], info.callbacks[j].val);
293*3d0fad56SMarko Kovacevic 				if (ret < 0)
294*3d0fad56SMarko Kovacevic 					return ret;
295*3d0fad56SMarko Kovacevic 				break;
296*3d0fad56SMarko Kovacevic 			}
297*3d0fad56SMarko Kovacevic 	}
298*3d0fad56SMarko Kovacevic 
299*3d0fad56SMarko Kovacevic 	return 0;
300*3d0fad56SMarko Kovacevic }
301*3d0fad56SMarko Kovacevic 
302*3d0fad56SMarko Kovacevic void
303*3d0fad56SMarko Kovacevic fips_test_write_one_case(void)
304*3d0fad56SMarko Kovacevic {
305*3d0fad56SMarko Kovacevic 	uint32_t i;
306*3d0fad56SMarko Kovacevic 
307*3d0fad56SMarko Kovacevic 	for (i = 0; i < info.nb_vec_lines; i++)
308*3d0fad56SMarko Kovacevic 		fprintf(info.fp_wr, "%s\n", info.vec[i]);
309*3d0fad56SMarko Kovacevic }
310*3d0fad56SMarko Kovacevic 
311*3d0fad56SMarko Kovacevic static int
312*3d0fad56SMarko Kovacevic parser_read_uint64_hex(uint64_t *value, const char *p)
313*3d0fad56SMarko Kovacevic {
314*3d0fad56SMarko Kovacevic 	char *next;
315*3d0fad56SMarko Kovacevic 	uint64_t val;
316*3d0fad56SMarko Kovacevic 
317*3d0fad56SMarko Kovacevic 	p = skip_white_spaces(p);
318*3d0fad56SMarko Kovacevic 
319*3d0fad56SMarko Kovacevic 	val = strtoul(p, &next, 16);
320*3d0fad56SMarko Kovacevic 	if (p == next)
321*3d0fad56SMarko Kovacevic 		return -EINVAL;
322*3d0fad56SMarko Kovacevic 
323*3d0fad56SMarko Kovacevic 	p = skip_white_spaces(next);
324*3d0fad56SMarko Kovacevic 	if (*p != '\0')
325*3d0fad56SMarko Kovacevic 		return -EINVAL;
326*3d0fad56SMarko Kovacevic 
327*3d0fad56SMarko Kovacevic 	*value = val;
328*3d0fad56SMarko Kovacevic 	return 0;
329*3d0fad56SMarko Kovacevic }
330*3d0fad56SMarko Kovacevic 
331*3d0fad56SMarko Kovacevic int
332*3d0fad56SMarko Kovacevic parser_read_uint8_hex(uint8_t *value, const char *p)
333*3d0fad56SMarko Kovacevic {
334*3d0fad56SMarko Kovacevic 	uint64_t val = 0;
335*3d0fad56SMarko Kovacevic 	int ret = parser_read_uint64_hex(&val, p);
336*3d0fad56SMarko Kovacevic 
337*3d0fad56SMarko Kovacevic 	if (ret < 0)
338*3d0fad56SMarko Kovacevic 		return ret;
339*3d0fad56SMarko Kovacevic 
340*3d0fad56SMarko Kovacevic 	if (val > UINT8_MAX)
341*3d0fad56SMarko Kovacevic 		return -ERANGE;
342*3d0fad56SMarko Kovacevic 
343*3d0fad56SMarko Kovacevic 	*value = val;
344*3d0fad56SMarko Kovacevic 	return 0;
345*3d0fad56SMarko Kovacevic }
346*3d0fad56SMarko Kovacevic 
347*3d0fad56SMarko Kovacevic int
348*3d0fad56SMarko Kovacevic parse_uint8_known_len_hex_str(const char *key, char *src, struct fips_val *val)
349*3d0fad56SMarko Kovacevic {
350*3d0fad56SMarko Kovacevic 	struct fips_val tmp_val = {0};
351*3d0fad56SMarko Kovacevic 	uint32_t len = val->len;
352*3d0fad56SMarko Kovacevic 	int ret;
353*3d0fad56SMarko Kovacevic 
354*3d0fad56SMarko Kovacevic 	if (len == 0) {
355*3d0fad56SMarko Kovacevic 		if (val->val != NULL) {
356*3d0fad56SMarko Kovacevic 			rte_free(val->val);
357*3d0fad56SMarko Kovacevic 			val->val = NULL;
358*3d0fad56SMarko Kovacevic 		}
359*3d0fad56SMarko Kovacevic 
360*3d0fad56SMarko Kovacevic 		return 0;
361*3d0fad56SMarko Kovacevic 	}
362*3d0fad56SMarko Kovacevic 
363*3d0fad56SMarko Kovacevic 	ret = parse_uint8_hex_str(key, src, &tmp_val);
364*3d0fad56SMarko Kovacevic 	if (ret < 0)
365*3d0fad56SMarko Kovacevic 		return ret;
366*3d0fad56SMarko Kovacevic 
367*3d0fad56SMarko Kovacevic 	if (tmp_val.len == val->len) {
368*3d0fad56SMarko Kovacevic 		val->val = tmp_val.val;
369*3d0fad56SMarko Kovacevic 		return 0;
370*3d0fad56SMarko Kovacevic 	}
371*3d0fad56SMarko Kovacevic 
372*3d0fad56SMarko Kovacevic 	if (tmp_val.len < val->len) {
373*3d0fad56SMarko Kovacevic 		rte_free(tmp_val.val);
374*3d0fad56SMarko Kovacevic 		return -EINVAL;
375*3d0fad56SMarko Kovacevic 	}
376*3d0fad56SMarko Kovacevic 
377*3d0fad56SMarko Kovacevic 	val->val = rte_zmalloc(NULL, val->len, 0);
378*3d0fad56SMarko Kovacevic 	if (!val->val) {
379*3d0fad56SMarko Kovacevic 		rte_free(tmp_val.val);
380*3d0fad56SMarko Kovacevic 		memset(val, 0, sizeof(*val));
381*3d0fad56SMarko Kovacevic 		return -ENOMEM;
382*3d0fad56SMarko Kovacevic 	}
383*3d0fad56SMarko Kovacevic 
384*3d0fad56SMarko Kovacevic 	memcpy(val->val, tmp_val.val, val->len);
385*3d0fad56SMarko Kovacevic 	rte_free(tmp_val.val);
386*3d0fad56SMarko Kovacevic 
387*3d0fad56SMarko Kovacevic 	return 0;
388*3d0fad56SMarko Kovacevic }
389*3d0fad56SMarko Kovacevic 
390*3d0fad56SMarko Kovacevic int
391*3d0fad56SMarko Kovacevic parse_uint8_hex_str(const char *key, char *src, struct fips_val *val)
392*3d0fad56SMarko Kovacevic {
393*3d0fad56SMarko Kovacevic 	uint32_t len, j;
394*3d0fad56SMarko Kovacevic 
395*3d0fad56SMarko Kovacevic 	src += strlen(key);
396*3d0fad56SMarko Kovacevic 
397*3d0fad56SMarko Kovacevic 	len = strlen(src) / 2;
398*3d0fad56SMarko Kovacevic 
399*3d0fad56SMarko Kovacevic 	if (val->val) {
400*3d0fad56SMarko Kovacevic 		rte_free(val->val);
401*3d0fad56SMarko Kovacevic 		val->val = NULL;
402*3d0fad56SMarko Kovacevic 	}
403*3d0fad56SMarko Kovacevic 
404*3d0fad56SMarko Kovacevic 	val->val = rte_zmalloc(NULL, len, 0);
405*3d0fad56SMarko Kovacevic 	if (!val->val)
406*3d0fad56SMarko Kovacevic 		return -ENOMEM;
407*3d0fad56SMarko Kovacevic 
408*3d0fad56SMarko Kovacevic 	for (j = 0; j < len; j++) {
409*3d0fad56SMarko Kovacevic 		char byte[3] = {src[j * 2], src[j * 2 + 1], '\0'};
410*3d0fad56SMarko Kovacevic 
411*3d0fad56SMarko Kovacevic 		if (parser_read_uint8_hex(&val->val[j], byte) < 0) {
412*3d0fad56SMarko Kovacevic 			rte_free(val->val);
413*3d0fad56SMarko Kovacevic 			memset(val, 0, sizeof(*val));
414*3d0fad56SMarko Kovacevic 			return -EINVAL;
415*3d0fad56SMarko Kovacevic 		}
416*3d0fad56SMarko Kovacevic 	}
417*3d0fad56SMarko Kovacevic 
418*3d0fad56SMarko Kovacevic 	val->len = len;
419*3d0fad56SMarko Kovacevic 
420*3d0fad56SMarko Kovacevic 	return 0;
421*3d0fad56SMarko Kovacevic }
422*3d0fad56SMarko Kovacevic 
423*3d0fad56SMarko Kovacevic int
424*3d0fad56SMarko Kovacevic parser_read_uint32_val(const char *key, char *src, struct fips_val *val)
425*3d0fad56SMarko Kovacevic {
426*3d0fad56SMarko Kovacevic 	char *data = src + strlen(key);
427*3d0fad56SMarko Kovacevic 	size_t data_len = strlen(data);
428*3d0fad56SMarko Kovacevic 	int ret;
429*3d0fad56SMarko Kovacevic 
430*3d0fad56SMarko Kovacevic 	if (data[data_len - 1] == ']') {
431*3d0fad56SMarko Kovacevic 		char *tmp_data = calloc(1, data_len + 1);
432*3d0fad56SMarko Kovacevic 
433*3d0fad56SMarko Kovacevic 		if (tmp_data == NULL)
434*3d0fad56SMarko Kovacevic 			return -ENOMEM;
435*3d0fad56SMarko Kovacevic 
436*3d0fad56SMarko Kovacevic 		strlcpy(tmp_data, data, data_len);
437*3d0fad56SMarko Kovacevic 
438*3d0fad56SMarko Kovacevic 		ret = parser_read_uint32(&val->len, tmp_data);
439*3d0fad56SMarko Kovacevic 
440*3d0fad56SMarko Kovacevic 		free(tmp_data);
441*3d0fad56SMarko Kovacevic 	} else
442*3d0fad56SMarko Kovacevic 		ret = parser_read_uint32(&val->len, data);
443*3d0fad56SMarko Kovacevic 
444*3d0fad56SMarko Kovacevic 	return ret;
445*3d0fad56SMarko Kovacevic }
446*3d0fad56SMarko Kovacevic 
447*3d0fad56SMarko Kovacevic int
448*3d0fad56SMarko Kovacevic parser_read_uint32_bit_val(const char *key, char *src, struct fips_val *val)
449*3d0fad56SMarko Kovacevic {
450*3d0fad56SMarko Kovacevic 	int ret;
451*3d0fad56SMarko Kovacevic 
452*3d0fad56SMarko Kovacevic 	ret = parser_read_uint32_val(key, src, val);
453*3d0fad56SMarko Kovacevic 
454*3d0fad56SMarko Kovacevic 	if (ret < 0)
455*3d0fad56SMarko Kovacevic 		return ret;
456*3d0fad56SMarko Kovacevic 
457*3d0fad56SMarko Kovacevic 	val->len /= 8;
458*3d0fad56SMarko Kovacevic 
459*3d0fad56SMarko Kovacevic 	return 0;
460*3d0fad56SMarko Kovacevic }
461*3d0fad56SMarko Kovacevic 
462*3d0fad56SMarko Kovacevic int
463*3d0fad56SMarko Kovacevic writeback_hex_str(const char *key, char *dst, struct fips_val *val)
464*3d0fad56SMarko Kovacevic {
465*3d0fad56SMarko Kovacevic 	char *str = dst;
466*3d0fad56SMarko Kovacevic 	uint32_t len;
467*3d0fad56SMarko Kovacevic 
468*3d0fad56SMarko Kovacevic 	str += strlen(key);
469*3d0fad56SMarko Kovacevic 
470*3d0fad56SMarko Kovacevic 	for (len = 0; len < val->len; len++)
471*3d0fad56SMarko Kovacevic 		snprintf(str + len * 2, 255, "%02x", val->val[len]);
472*3d0fad56SMarko Kovacevic 
473*3d0fad56SMarko Kovacevic 	return 0;
474*3d0fad56SMarko Kovacevic }
475*3d0fad56SMarko Kovacevic 
476*3d0fad56SMarko Kovacevic static int
477*3d0fad56SMarko Kovacevic parser_read_uint64(uint64_t *value, const char *p)
478*3d0fad56SMarko Kovacevic {
479*3d0fad56SMarko Kovacevic 	char *next;
480*3d0fad56SMarko Kovacevic 	uint64_t val;
481*3d0fad56SMarko Kovacevic 
482*3d0fad56SMarko Kovacevic 	p = skip_white_spaces(p);
483*3d0fad56SMarko Kovacevic 	if (!isdigit(*p))
484*3d0fad56SMarko Kovacevic 		return -EINVAL;
485*3d0fad56SMarko Kovacevic 
486*3d0fad56SMarko Kovacevic 	val = strtoul(p, &next, 10);
487*3d0fad56SMarko Kovacevic 	if (p == next)
488*3d0fad56SMarko Kovacevic 		return -EINVAL;
489*3d0fad56SMarko Kovacevic 
490*3d0fad56SMarko Kovacevic 	p = next;
491*3d0fad56SMarko Kovacevic 	switch (*p) {
492*3d0fad56SMarko Kovacevic 	case 'T':
493*3d0fad56SMarko Kovacevic 		val *= 1024ULL;
494*3d0fad56SMarko Kovacevic 		/* fall through */
495*3d0fad56SMarko Kovacevic 	case 'G':
496*3d0fad56SMarko Kovacevic 		val *= 1024ULL;
497*3d0fad56SMarko Kovacevic 		/* fall through */
498*3d0fad56SMarko Kovacevic 	case 'M':
499*3d0fad56SMarko Kovacevic 		val *= 1024ULL;
500*3d0fad56SMarko Kovacevic 		/* fall through */
501*3d0fad56SMarko Kovacevic 	case 'k':
502*3d0fad56SMarko Kovacevic 	case 'K':
503*3d0fad56SMarko Kovacevic 		val *= 1024ULL;
504*3d0fad56SMarko Kovacevic 		p++;
505*3d0fad56SMarko Kovacevic 		break;
506*3d0fad56SMarko Kovacevic 	}
507*3d0fad56SMarko Kovacevic 
508*3d0fad56SMarko Kovacevic 	p = skip_white_spaces(p);
509*3d0fad56SMarko Kovacevic 	if (*p != '\0')
510*3d0fad56SMarko Kovacevic 		return -EINVAL;
511*3d0fad56SMarko Kovacevic 
512*3d0fad56SMarko Kovacevic 	*value = val;
513*3d0fad56SMarko Kovacevic 	return 0;
514*3d0fad56SMarko Kovacevic }
515*3d0fad56SMarko Kovacevic 
516*3d0fad56SMarko Kovacevic int
517*3d0fad56SMarko Kovacevic parser_read_uint32(uint32_t *value, char *p)
518*3d0fad56SMarko Kovacevic {
519*3d0fad56SMarko Kovacevic 	uint64_t val = 0;
520*3d0fad56SMarko Kovacevic 	int ret = parser_read_uint64(&val, p);
521*3d0fad56SMarko Kovacevic 
522*3d0fad56SMarko Kovacevic 	if (ret < 0)
523*3d0fad56SMarko Kovacevic 		return ret;
524*3d0fad56SMarko Kovacevic 
525*3d0fad56SMarko Kovacevic 	if (val > UINT32_MAX)
526*3d0fad56SMarko Kovacevic 		return -EINVAL;
527*3d0fad56SMarko Kovacevic 
528*3d0fad56SMarko Kovacevic 	*value = val;
529*3d0fad56SMarko Kovacevic 	return 0;
530*3d0fad56SMarko Kovacevic }
531*3d0fad56SMarko Kovacevic 
532*3d0fad56SMarko Kovacevic void
533*3d0fad56SMarko Kovacevic parse_write_hex_str(struct fips_val *src)
534*3d0fad56SMarko Kovacevic {
535*3d0fad56SMarko Kovacevic 	writeback_hex_str("", info.one_line_text, src);
536*3d0fad56SMarko Kovacevic 
537*3d0fad56SMarko Kovacevic 	fprintf(info.fp_wr, "%s\n", info.one_line_text);
538*3d0fad56SMarko Kovacevic }
539*3d0fad56SMarko Kovacevic 
540*3d0fad56SMarko Kovacevic int
541*3d0fad56SMarko Kovacevic update_info_vec(uint32_t count)
542*3d0fad56SMarko Kovacevic {
543*3d0fad56SMarko Kovacevic 	const struct fips_test_callback *cb;
544*3d0fad56SMarko Kovacevic 	uint32_t i, j;
545*3d0fad56SMarko Kovacevic 
546*3d0fad56SMarko Kovacevic 	if (!info.writeback_callbacks)
547*3d0fad56SMarko Kovacevic 		return -1;
548*3d0fad56SMarko Kovacevic 
549*3d0fad56SMarko Kovacevic 	cb = &info.writeback_callbacks[0];
550*3d0fad56SMarko Kovacevic 
551*3d0fad56SMarko Kovacevic 	snprintf(info.vec[0], strlen(info.vec[0]) + 4, "%s%u", cb->key, count);
552*3d0fad56SMarko Kovacevic 
553*3d0fad56SMarko Kovacevic 	for (i = 1; i < info.nb_vec_lines; i++) {
554*3d0fad56SMarko Kovacevic 		for (j = 1; info.writeback_callbacks[j].key != NULL; j++) {
555*3d0fad56SMarko Kovacevic 			cb = &info.writeback_callbacks[j];
556*3d0fad56SMarko Kovacevic 			if (strstr(info.vec[i], cb->key)) {
557*3d0fad56SMarko Kovacevic 				cb->cb(cb->key, info.vec[i], cb->val);
558*3d0fad56SMarko Kovacevic 				break;
559*3d0fad56SMarko Kovacevic 			}
560*3d0fad56SMarko Kovacevic 		}
561*3d0fad56SMarko Kovacevic 	}
562*3d0fad56SMarko Kovacevic 
563*3d0fad56SMarko Kovacevic 	return 0;
564*3d0fad56SMarko Kovacevic }
565