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