xref: /dpdk/examples/fips_validation/fips_validation_sha.c (revision 3d3408dd5a1d3afc30fac3497871da1d53ffc481)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4 
5 #include <string.h>
6 #include <time.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 
10 #include <rte_malloc.h>
11 #include <rte_cryptodev.h>
12 
13 #include "fips_validation.h"
14 
15 #define ALGO_PREFIX	"[L = "
16 #define MSGLEN_STR	"Len = "
17 #define MSG_STR		"Msg = "
18 #define MD_STR		"MD = "
19 #define SEED_STR	"Seed = "
20 #define MCT_STR		"Monte"
21 
22 #define ALGO_JSON_STR	"algorithm"
23 #define TESTTYPE_JSON_STR	"testType"
24 
25 #define PT_JSON_STR		"msg"
26 #define OUTLEN_JSON_STR	"outLen"
27 #define MINOUTLEN_JSON_STR	"minOutLen"
28 #define MAXOUTLEN_JSON_STR	"maxOutLen"
29 
30 struct plain_hash_size_conversion {
31 	const char *str;
32 	uint8_t md_blocks;
33 	enum rte_crypto_auth_algorithm algo;
34 } phsc[] = {
35 		{"20", 3, RTE_CRYPTO_AUTH_SHA1},
36 		{"28", 3, RTE_CRYPTO_AUTH_SHA224},
37 		{"32", 3, RTE_CRYPTO_AUTH_SHA256},
38 		{"48", 3, RTE_CRYPTO_AUTH_SHA384},
39 		{"64", 3, RTE_CRYPTO_AUTH_SHA512},
40 		{"28", 1, RTE_CRYPTO_AUTH_SHA3_224},
41 		{"32", 1, RTE_CRYPTO_AUTH_SHA3_256},
42 		{"48", 1, RTE_CRYPTO_AUTH_SHA3_384},
43 		{"64", 1, RTE_CRYPTO_AUTH_SHA3_512},
44 		{"16", 1, RTE_CRYPTO_AUTH_SHAKE_128},
45 		{"32", 1, RTE_CRYPTO_AUTH_SHAKE_256},
46 };
47 
48 int
parse_test_sha_hash_size(enum rte_crypto_auth_algorithm algo)49 parse_test_sha_hash_size(enum rte_crypto_auth_algorithm algo)
50 {
51 	int ret = -EINVAL;
52 	uint8_t i;
53 
54 	for (i = 0; i < RTE_DIM(phsc); i++) {
55 		if (phsc[i].algo == algo) {
56 			ret = atoi(phsc[i].str);
57 			break;
58 		}
59 	}
60 
61 	return ret;
62 }
63 
64 static int
parse_interim_algo(__rte_unused const char * key,char * text,__rte_unused struct fips_val * val)65 parse_interim_algo(__rte_unused const char *key,
66 		char *text,
67 		__rte_unused struct fips_val *val)
68 {
69 	uint32_t i;
70 
71 	for (i = 0; i < RTE_DIM(phsc); i++) {
72 		if (strstr(text, phsc[i].str)) {
73 			info.interim_info.sha_data.algo = phsc[i].algo;
74 			info.interim_info.sha_data.md_blocks = phsc[i].md_blocks;
75 			parser_read_uint32_val(ALGO_PREFIX,
76 				text, &vec.cipher_auth.digest);
77 			break;
78 		}
79 	}
80 
81 	if (i == RTE_DIM(phsc))
82 		return -1;
83 
84 	return 0;
85 }
86 
87 struct fips_test_callback sha_tests_vectors[] = {
88 		{MSGLEN_STR, parser_read_uint32_bit_val, &vec.pt},
89 		{MSG_STR, parse_uint8_known_len_hex_str, &vec.pt},
90 		{SEED_STR, parse_uint8_hex_str, &vec.pt},
91 		{NULL, NULL, NULL} /**< end pointer */
92 };
93 
94 struct fips_test_callback sha_tests_interim_vectors[] = {
95 		{ALGO_PREFIX, parse_interim_algo, NULL},
96 		{NULL, NULL, NULL} /**< end pointer */
97 };
98 
99 #ifdef USE_JANSSON
100 static int
parse_interim_str(const char * key,char * src,struct fips_val * val)101 parse_interim_str(const char *key, char *src, struct fips_val *val)
102 {
103 	RTE_SET_USED(val);
104 
105 	if (strcmp(key, MINOUTLEN_JSON_STR) == 0)
106 		info.interim_info.sha_data.min_outlen = atoi(src) / 8;
107 	else if (strcmp(key, MAXOUTLEN_JSON_STR) == 0)
108 		vec.cipher_auth.digest.len = atoi(src) / 8;
109 
110 	return 0;
111 }
112 
113 static struct {
114 	uint32_t type;
115 	const char *desc;
116 } sha_test_types[] = {
117 		{SHA_MCT, "MCT"},
118 		{SHA_AFT, "AFT"},
119 		{SHAKE_VOT, "VOT"},
120 };
121 
122 static struct plain_hash_algorithms {
123 	const char *str;
124 	enum rte_crypto_auth_algorithm algo;
125 	uint8_t md_blocks;
126 } json_algorithms[] = {
127 		{"SHA-1", RTE_CRYPTO_AUTH_SHA1, 3},
128 		{"SHA2-224", RTE_CRYPTO_AUTH_SHA224, 3},
129 		{"SHA2-256", RTE_CRYPTO_AUTH_SHA256, 3},
130 		{"SHA2-384", RTE_CRYPTO_AUTH_SHA384, 3},
131 		{"SHA2-512", RTE_CRYPTO_AUTH_SHA512, 3},
132 		{"SHA3-224", RTE_CRYPTO_AUTH_SHA3_224, 1},
133 		{"SHA3-256", RTE_CRYPTO_AUTH_SHA3_256, 1},
134 		{"SHA3-384", RTE_CRYPTO_AUTH_SHA3_384, 1},
135 		{"SHA3-512", RTE_CRYPTO_AUTH_SHA3_512, 1},
136 		{"SHAKE-128", RTE_CRYPTO_AUTH_SHAKE_128, 1},
137 		{"SHAKE-256", RTE_CRYPTO_AUTH_SHAKE_256, 1},
138 };
139 
140 struct fips_test_callback sha_tests_json_vectors[] = {
141 		{PT_JSON_STR, parse_uint8_hex_str, &vec.pt},
142 		{OUTLEN_JSON_STR, parser_read_uint32_bit_val, &vec.cipher_auth.digest},
143 		{NULL, NULL, NULL} /**< end pointer */
144 };
145 
146 struct fips_test_callback sha_tests_interim_json_vectors[] = {
147 		{MINOUTLEN_JSON_STR, parse_interim_str, NULL},
148 		{MAXOUTLEN_JSON_STR, parse_interim_str, NULL},
149 		{NULL, NULL, NULL} /**< end pointer */
150 };
151 #endif /* USE_JANSSON */
152 
153 static int
parse_test_sha_writeback(struct fips_val * val)154 parse_test_sha_writeback(struct fips_val *val) // !
155 {
156 	struct fips_val val_local;
157 
158 	fprintf(info.fp_wr, "%s", MD_STR);
159 
160 	val_local.val = val->val + vec.pt.len;
161 	val_local.len = vec.cipher_auth.digest.len;
162 
163 	parse_write_hex_str(&val_local);
164 	return 0;
165 }
166 
167 static int
rsp_test_sha_check(struct fips_val * val)168 rsp_test_sha_check(struct fips_val *val)
169 {
170 	if (memcmp(val->val + vec.pt.len, vec.cipher_auth.digest.val,
171 			vec.cipher_auth.digest.len) == 0)
172 		fprintf(info.fp_wr, "Success\n");
173 	else
174 		fprintf(info.fp_wr, "Failed\n");
175 
176 	return 0;
177 }
178 
179 int
parse_test_sha_init(void)180 parse_test_sha_init(void)
181 {
182 	uint32_t i;
183 
184 	info.interim_info.sha_data.test_type = SHA_KAT;
185 	for (i = 0; i < info.nb_vec_lines; i++) {
186 		char *line = info.vec[i];
187 		if (strstr(line, MCT_STR))
188 			info.interim_info.sha_data.test_type = SHA_MCT;
189 	}
190 
191 	info.op = FIPS_TEST_ENC_AUTH_GEN;
192 	info.parse_writeback = parse_test_sha_writeback;
193 	info.callbacks = sha_tests_vectors;
194 	info.interim_callbacks = sha_tests_interim_vectors;
195 	info.writeback_callbacks = NULL;
196 	info.kat_check = rsp_test_sha_check;
197 	return 0;
198 }
199 
200 #ifdef USE_JANSSON
201 static int
parse_test_sha_json_writeback(struct fips_val * val)202 parse_test_sha_json_writeback(struct fips_val *val)
203 {
204 	struct fips_val val_local;
205 	json_t *tcId, *md;
206 
207 	tcId = json_object_get(json_info.json_test_case, "tcId");
208 
209 	json_info.json_write_case = json_object();
210 	json_object_set_new(json_info.json_write_case, "tcId", tcId);
211 
212 	val_local.val = val->val + vec.pt.len;
213 	val_local.len = vec.cipher_auth.digest.len;
214 
215 	writeback_hex_str("", info.one_line_text, &val_local);
216 	md = json_string(info.one_line_text);
217 	json_object_set_new(json_info.json_write_case, "md", md);
218 
219 	if (info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_128 ||
220 		info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_256)
221 		json_object_set_new(json_info.json_write_case, "outLen",
222 			json_integer(vec.cipher_auth.digest.len * 8));
223 
224 	return 0;
225 }
226 
227 static int
parse_test_sha_mct_json_writeback(struct fips_val * val)228 parse_test_sha_mct_json_writeback(struct fips_val *val)
229 {
230 	json_t *tcId, *md, *resArr, *res;
231 	struct fips_val val_local;
232 	bool is_shake = false;
233 
234 	if (info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_128 ||
235 		info.interim_info.sha_data.algo == RTE_CRYPTO_AUTH_SHAKE_256)
236 		is_shake = true;
237 
238 	tcId = json_object_get(json_info.json_test_case, "tcId");
239 	if (json_info.json_write_case) {
240 		json_t *wcId;
241 
242 		wcId = json_object_get(json_info.json_write_case, "tcId");
243 		if (!json_equal(tcId, wcId)) {
244 			json_info.json_write_case = json_object();
245 			json_object_set_new(json_info.json_write_case, "tcId", tcId);
246 			json_object_set_new(json_info.json_write_case, "resultsArray",
247 								json_array());
248 			if (is_shake)
249 				json_object_set_new(json_info.json_write_case, "outLen",
250 									json_integer(0));
251 		}
252 	} else {
253 		json_info.json_write_case = json_object();
254 		json_object_set_new(json_info.json_write_case, "tcId", tcId);
255 		json_object_set_new(json_info.json_write_case, "resultsArray", json_array());
256 		if (is_shake)
257 			json_object_set_new(json_info.json_write_case, "outLen",
258 								json_integer(0));
259 	}
260 
261 	resArr = json_object_get(json_info.json_write_case, "resultsArray");
262 	if (!json_is_array(resArr))
263 		return -EINVAL;
264 
265 	res = json_object();
266 
267 	val_local.val = val->val + vec.pt.len;
268 	val_local.len = vec.cipher_auth.digest.len;
269 
270 	writeback_hex_str("", info.one_line_text, &val_local);
271 	md = json_string(info.one_line_text);
272 	json_object_set_new(res, "md", md);
273 
274 	if (is_shake)
275 		json_object_set_new(res, "outLen", json_integer(vec.cipher_auth.digest.len * 8));
276 
277 	json_array_append_new(resArr, res);
278 	return 0;
279 }
280 
281 int
parse_test_sha_json_algorithm(void)282 parse_test_sha_json_algorithm(void)
283 {
284 	json_t *algorithm_object;
285 	const char *algorithm_str;
286 	uint32_t i;
287 	int sz;
288 
289 	algorithm_object = json_object_get(json_info.json_vector_set, "algorithm");
290 	algorithm_str = json_string_value(algorithm_object);
291 
292 	for (i = 0; i < RTE_DIM(json_algorithms); i++) {
293 		if (strstr(algorithm_str, json_algorithms[i].str)) {
294 			info.interim_info.sha_data.algo = json_algorithms[i].algo;
295 			info.interim_info.sha_data.md_blocks = json_algorithms[i].md_blocks;
296 			break;
297 		}
298 	}
299 
300 	if (i == RTE_DIM(json_algorithms))
301 		return -1;
302 
303 	if (info.interim_info.sha_data.test_type == SHAKE_VOT) {
304 		sz = vec.cipher_auth.digest.len;
305 	} else {
306 		sz = parse_test_sha_hash_size(info.interim_info.sha_data.algo);
307 		vec.cipher_auth.digest.len = sz;
308 	}
309 
310 	if (sz < 0)
311 		return -1;
312 
313 	rte_free(vec.cipher_auth.digest.val);
314 	vec.cipher_auth.digest.val = rte_malloc(NULL, sz, 0);
315 	if (vec.cipher_auth.digest.val == NULL)
316 		return -1;
317 
318 	return 0;
319 }
320 
321 int
parse_test_sha_json_test_type(void)322 parse_test_sha_json_test_type(void)
323 {
324 	json_t *type_object;
325 	const char *type_str;
326 	uint32_t i;
327 
328 	type_object = json_object_get(json_info.json_test_group, TESTTYPE_JSON_STR);
329 	type_str = json_string_value(type_object);
330 
331 	for (i = 0; i < RTE_DIM(sha_test_types); i++)
332 		if (strstr(type_str, sha_test_types[i].desc)) {
333 			info.interim_info.sha_data.test_type =
334 				sha_test_types[i].type;
335 			break;
336 		}
337 
338 	if (i == RTE_DIM(sha_test_types))
339 		return -1;
340 
341 	switch (info.interim_info.sha_data.test_type) {
342 	case SHA_MCT:
343 		info.parse_writeback = parse_test_sha_mct_json_writeback;
344 		break;
345 	case SHA_AFT:
346 	case SHAKE_VOT:
347 		info.parse_writeback = parse_test_sha_json_writeback;
348 		break;
349 	default:
350 		info.parse_writeback = NULL;
351 	}
352 
353 	if (!info.parse_writeback)
354 		return -1;
355 
356 	return 0;
357 }
358 
359 int
parse_test_sha_json_init(void)360 parse_test_sha_json_init(void)
361 {
362 	info.op = FIPS_TEST_ENC_AUTH_GEN;
363 	info.parse_writeback = parse_test_sha_json_writeback;
364 	info.callbacks = sha_tests_json_vectors;
365 	info.writeback_callbacks = NULL;
366 	info.kat_check = rsp_test_sha_check;
367 	info.interim_callbacks = sha_tests_interim_json_vectors;
368 
369 	if (parse_test_sha_json_test_type() < 0)
370 		return -1;
371 
372 	if (parse_test_sha_json_algorithm() < 0)
373 		return -1;
374 
375 	return 0;
376 }
377 #endif /* USE_JANSSON */
378