xref: /dpdk/examples/fips_validation/fips_validation_aes.c (revision 96db98db69f759cdb54c02ef72c4cae760b01ab3)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Intel Corporation
3  */
4 
5 #include <string.h>
6 #include <time.h>
7 #include <stdio.h>
8 
9 #include <rte_cryptodev.h>
10 #include <rte_malloc.h>
11 
12 #include "fips_validation.h"
13 
14 #define MODE_STR	"AESVS"
15 #define ALGO_STR	"test data for "
16 #define OP_STR		"State"
17 #define KEY_SIZE_STR	"Key Length : "
18 
19 
20 #define COUNT_STR	"COUNT = "
21 #define KEY_STR		"KEY = "
22 #define IV_STR		"IV = "
23 #define PT_STR		"PLAINTEXT = "
24 #define CT_STR		"CIPHERTEXT = "
25 
26 #define OP_ENC_STR	"ENCRYPT"
27 #define OP_DEC_STR	"DECRYPT"
28 
29 #define ALGO_JSON_STR		"algorithm"
30 #define TESTTYPE_JSON_STR	"testType"
31 #define DIR_JSON_STR		"direction"
32 #define KEYLEN_JSON_STR		"keyLen"
33 
34 #define KEY_JSON_STR	"key"
35 #define IV_JSON_STR	"iv"
36 #define PT_JSON_STR	"pt"
37 #define CT_JSON_STR	"ct"
38 
39 #define OP_ENC_JSON_STR	"encrypt"
40 #define OP_DEC_JSON_STR	"decrypt"
41 
42 struct {
43 	uint32_t type;
44 	const char *desc;
45 } aes_test_types[] = {
46 		{AESAVS_TYPE_GFXBOX, "GFSbox"},
47 		{AESAVS_TYPE_KEYSBOX, "KeySbox"},
48 		{AESAVS_TYPE_VARKEY, "VarKey"},
49 		{AESAVS_TYPE_VARTXT, "VarTxt"},
50 		{TDES_VARIABLE_TEXT, "VARIABLE PLAINTEXT/CIPHERTEXT"},
51 		{TDES_VARIABLE_TEXT, "KAT"},
52 		{AESAVS_TYPE_MMT, "MMT"},
53 		{AESAVS_TYPE_MCT, "MCT"},
54 		{AESAVS_TYPE_AFT, "AFT"},
55 };
56 
57 struct aes_test_algo {
58 	const char *name;
59 	enum rte_crypto_cipher_algorithm algo;
60 } const algo_con[] = {
61 		{"CBC", RTE_CRYPTO_CIPHER_AES_CBC},
62 		{"ECB", RTE_CRYPTO_CIPHER_AES_ECB},
63 };
64 
65 static int
66 parse_interim_enc_dec(const char *key,
67 		__rte_unused char *text,
68 		__rte_unused struct fips_val *val)
69 {
70 	if (strcmp(key, OP_ENC_STR) == 0)
71 		info.op = FIPS_TEST_ENC_AUTH_GEN;
72 	else if (strcmp(key, OP_DEC_STR) == 0)
73 		info.op = FIPS_TEST_DEC_AUTH_VERIF;
74 	else
75 		return -1;
76 
77 	return 0;
78 }
79 
80 struct fips_test_callback aes_tests_interim[] = {
81 		{OP_ENC_STR, parse_interim_enc_dec, NULL},
82 		{OP_DEC_STR, parse_interim_enc_dec, NULL},
83 		{NULL, NULL, NULL} /**< end pointer */
84 };
85 
86 struct fips_test_callback aes_tests_vectors[] = {
87 		{KEY_STR, parse_uint8_hex_str, &vec.cipher_auth.key},
88 		{IV_STR, parse_uint8_hex_str, &vec.iv},
89 		{PT_STR, parse_uint8_hex_str, &vec.pt},
90 		{CT_STR, parse_uint8_hex_str, &vec.ct},
91 		{NULL, NULL, NULL} /**< end pointer */
92 };
93 
94 struct fips_test_callback aes_tests_interim_vectors[] = {
95 		{OP_ENC_STR, parse_interim_enc_dec, NULL},
96 		{OP_DEC_STR, parse_interim_enc_dec, NULL},
97 		{NULL, NULL, NULL} /**< end pointer */
98 };
99 
100 struct fips_test_callback aes_writeback_callbacks[] = {
101 		/** First element is used to pass COUNT string */
102 		{COUNT_STR, NULL, NULL},
103 		{IV_STR, writeback_hex_str, &vec.iv},
104 		{KEY_STR, writeback_hex_str, &vec.cipher_auth.key},
105 		{PT_STR, writeback_hex_str, &vec.pt},
106 		{CT_STR, writeback_hex_str, &vec.ct},
107 		{NULL, NULL, NULL} /**< end pointer */
108 };
109 
110 #ifdef RTE_HAS_JANSSON
111 struct fips_test_callback aes_dec_json_vectors[] = {
112 		{KEY_JSON_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.key},
113 		{IV_JSON_STR, parse_uint8_hex_str, &vec.iv},
114 		{CT_JSON_STR, parse_uint8_hex_str, &vec.ct},
115 		{NULL, NULL, NULL} /**< end pointer */
116 };
117 
118 struct fips_test_callback aes_interim_json_vectors[] = {
119 		{KEYLEN_JSON_STR, parser_read_uint32_bit_val, &vec.cipher_auth.key},
120 		{NULL, NULL, NULL} /**< end pointer */
121 };
122 
123 struct fips_test_callback aes_enc_json_vectors[] = {
124 		{KEY_JSON_STR, parse_uint8_known_len_hex_str, &vec.cipher_auth.key},
125 		{IV_JSON_STR, parse_uint8_hex_str, &vec.iv},
126 		{PT_JSON_STR, parse_uint8_hex_str, &vec.pt},
127 		{NULL, NULL, NULL} /**< end pointer */
128 };
129 
130 static int
131 parse_test_aes_json_writeback(struct fips_val *val)
132 {
133 	struct fips_val tmp_val;
134 	json_t *tcId;
135 
136 	tcId = json_object_get(json_info.json_test_case, "tcId");
137 
138 	json_info.json_write_case = json_object();
139 	json_object_set(json_info.json_write_case, "tcId", tcId);
140 
141 	if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
142 		json_t *ct;
143 
144 		tmp_val.val = val->val;
145 		tmp_val.len = vec.pt.len;
146 
147 		writeback_hex_str("", info.one_line_text, &tmp_val);
148 		ct = json_string(info.one_line_text);
149 		json_object_set_new(json_info.json_write_case, CT_JSON_STR, ct);
150 
151 		tmp_val.val = val->val + vec.pt.len;
152 		tmp_val.len = val->len - vec.pt.len;
153 
154 		writeback_hex_str("", info.one_line_text, &tmp_val);
155 	} else {
156 		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
157 			tmp_val.val = val->val;
158 			tmp_val.len = vec.ct.len;
159 
160 			writeback_hex_str("", info.one_line_text, &tmp_val);
161 			json_object_set_new(json_info.json_write_case, PT_JSON_STR,
162 								json_string(info.one_line_text));
163 		} else {
164 			json_object_set_new(json_info.json_write_case, "testPassed", json_false());
165 		}
166 	}
167 
168 	return 0;
169 }
170 
171 static int
172 parse_test_aes_mct_json_writeback(struct fips_val *val)
173 {
174 	json_t *tcId, *resArr, *res, *ct, *pt, *key, *iv;
175 	struct fips_val tmp_val;
176 
177 	tcId = json_object_get(json_info.json_test_case, "tcId");
178 	if (json_info.json_write_case) {
179 		json_t *wcId;
180 
181 		wcId = json_object_get(json_info.json_write_case, "tcId");
182 		if (!json_equal(tcId, wcId)) {
183 			json_info.json_write_case = json_object();
184 			json_object_set(json_info.json_write_case, "tcId", tcId);
185 			json_object_set(json_info.json_write_case, "resultsArray", json_array());
186 		}
187 	} else {
188 		json_info.json_write_case = json_object();
189 		json_object_set(json_info.json_write_case, "tcId", tcId);
190 		json_object_set(json_info.json_write_case, "resultsArray", json_array());
191 	}
192 
193 	resArr = json_object_get(json_info.json_write_case, "resultsArray");
194 	if (!json_is_array(resArr))
195 		return -EINVAL;
196 
197 	res = json_object();
198 	if (info .op == FIPS_TEST_ENC_AUTH_GEN) {
199 		writeback_hex_str("", info.one_line_text, &vec.cipher_auth.key);
200 		key = json_string(info.one_line_text);
201 		json_object_set_new(res, KEY_JSON_STR, key);
202 
203 		writeback_hex_str("", info.one_line_text, &val[2]);
204 		iv = json_string(info.one_line_text);
205 		json_object_set_new(res, IV_JSON_STR, iv);
206 
207 		writeback_hex_str("", info.one_line_text, &val[1]);
208 		pt = json_string(info.one_line_text);
209 		json_object_set_new(res, PT_JSON_STR, pt);
210 
211 		tmp_val.val = val->val;
212 		tmp_val.len = vec.pt.len;
213 
214 		writeback_hex_str("", info.one_line_text, &tmp_val);
215 		ct = json_string(info.one_line_text);
216 		json_object_set_new(res, CT_JSON_STR, ct);
217 
218 		tmp_val.val = val->val + vec.pt.len;
219 		tmp_val.len = val->len - vec.pt.len;
220 
221 		writeback_hex_str("", info.one_line_text, &tmp_val);
222 	} else {
223 		if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
224 			writeback_hex_str("", info.one_line_text, &vec.cipher_auth.key);
225 			key = json_string(info.one_line_text);
226 			json_object_set_new(res, KEY_JSON_STR, key);
227 
228 			writeback_hex_str("", info.one_line_text, &val[2]);
229 			iv = json_string(info.one_line_text);
230 			json_object_set_new(res, IV_JSON_STR, iv);
231 
232 			tmp_val.val = val->val;
233 			tmp_val.len = vec.ct.len;
234 
235 			writeback_hex_str("", info.one_line_text, &tmp_val);
236 			pt = json_string(info.one_line_text);
237 			json_object_set_new(res, PT_JSON_STR, pt);
238 
239 			writeback_hex_str("", info.one_line_text, &val[1]);
240 			ct = json_string(info.one_line_text);
241 			json_object_set_new(res, CT_JSON_STR, ct);
242 		} else {
243 			json_object_set_new(json_info.json_write_case, "testPassed", json_false());
244 		}
245 	}
246 
247 	json_array_append_new(resArr, res);
248 	return 0;
249 }
250 
251 int
252 parse_test_aes_json_init(void)
253 {
254 	json_t *type_obj = json_object_get(json_info.json_test_group, TESTTYPE_JSON_STR);
255 	json_t *algo_obj = json_object_get(json_info.json_vector_set, ALGO_JSON_STR);
256 	const char *type_str = json_string_value(type_obj);
257 	const char *algo_str = json_string_value(algo_obj);
258 	uint32_t i;
259 
260 	if (json_info.json_test_group) {
261 		json_t *direction_obj;
262 		const char *direction_str;
263 
264 		direction_obj = json_object_get(json_info.json_test_group, DIR_JSON_STR);
265 		direction_str = json_string_value(direction_obj);
266 
267 		if (strcmp(direction_str, OP_ENC_JSON_STR) == 0) {
268 			info.op = FIPS_TEST_ENC_AUTH_GEN;
269 			info.callbacks = aes_enc_json_vectors;
270 
271 		} else if (strcmp(direction_str, OP_DEC_JSON_STR) == 0) {
272 			info.op = FIPS_TEST_DEC_AUTH_VERIF;
273 			info.callbacks = aes_dec_json_vectors;
274 		} else {
275 			return -EINVAL;
276 		}
277 		info.interim_callbacks = aes_interim_json_vectors;
278 	}
279 
280 	for (i = 0; i < RTE_DIM(aes_test_types); i++)
281 		if (strstr(type_str, aes_test_types[i].desc)) {
282 			info.interim_info.aes_data.test_type =
283 				aes_test_types[i].type;
284 			break;
285 		}
286 
287 	if (i >= RTE_DIM(aes_test_types))
288 		return -EINVAL;
289 
290 	switch (info.interim_info.aes_data.test_type) {
291 	case AESAVS_TYPE_MCT:
292 		info.parse_writeback = parse_test_aes_mct_json_writeback;
293 		break;
294 	case AESAVS_TYPE_AFT:
295 		info.parse_writeback = parse_test_aes_json_writeback;
296 		break;
297 	default:
298 		info.parse_writeback = NULL;
299 	}
300 
301 	if (!info.parse_writeback)
302 		return -EINVAL;
303 
304 	for (i = 0; i < RTE_DIM(algo_con); i++)
305 		if (strstr(algo_str, algo_con[i].name)) {
306 			info.interim_info.aes_data.cipher_algo =
307 				(uint32_t)algo_con[i].algo;
308 			break;
309 		}
310 
311 	if (i >= RTE_DIM(algo_con))
312 		return -EINVAL;
313 
314 	return 0;
315 }
316 #endif /* RTE_HAS_JANSSON */
317 
318 static int
319 parse_test_aes_writeback(struct fips_val *val)
320 {
321 	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
322 		fprintf(info.fp_wr, "%s", CT_STR);
323 	else
324 		fprintf(info.fp_wr, "%s", PT_STR);
325 
326 	parse_write_hex_str(val);
327 
328 	return 0;
329 }
330 
331 static int
332 rsp_test_aes_check(struct fips_val *val)
333 {
334 	struct fips_val *data;
335 
336 	if (info.op == FIPS_TEST_ENC_AUTH_GEN)
337 		data = &vec.ct;
338 	else
339 		data = &vec.pt;
340 
341 	if (memcmp(val->val, data->val, val->len) == 0)
342 		fprintf(info.fp_wr, "Success\n");
343 	else
344 		fprintf(info.fp_wr, "Failed\n");
345 
346 	return 0;
347 }
348 
349 int
350 parse_test_aes_init(void)
351 {
352 	char *tmp;
353 	uint32_t i, j;
354 
355 	for (i = 0; i < info.nb_vec_lines; i++) {
356 		char *line = info.vec[i];
357 
358 		tmp = strstr(line, MODE_STR);
359 		if (tmp) {
360 			for (j = 0; j < RTE_DIM(aes_test_types); j++)
361 				if (strstr(line, aes_test_types[j].desc)) {
362 					info.interim_info.aes_data.test_type =
363 							aes_test_types[j].type;
364 					break;
365 				}
366 
367 			if (j >= RTE_DIM(aes_test_types))
368 				return -EINVAL;
369 
370 			tmp = strstr(line, ALGO_STR);
371 			if (!tmp)
372 				return -EINVAL;
373 
374 			tmp += strlen(ALGO_STR);
375 			for (j = 0; j < RTE_DIM(algo_con); j++)
376 				if (strcmp(algo_con[j].name, tmp) == 0) {
377 					info.interim_info.aes_data.cipher_algo =
378 						(uint32_t)algo_con[j].algo;
379 					break;
380 				}
381 			if (j >= RTE_DIM(algo_con))
382 				return -EINVAL;
383 
384 			continue;
385 		}
386 
387 		tmp = strstr(line, OP_STR);
388 		if (tmp)
389 			continue;
390 
391 		tmp = strstr(line, KEY_SIZE_STR);
392 		if (tmp) {
393 			tmp += strlen(KEY_SIZE_STR);
394 			if (parser_read_uint32
395 					(&info.interim_info.aes_data.key_len,
396 							tmp) < 0)
397 				return -EINVAL;
398 
399 			info.interim_info.aes_data.key_len /= 8;
400 
401 			continue;
402 		}
403 	}
404 
405 	info.parse_writeback = parse_test_aes_writeback;
406 	info.callbacks = aes_tests_vectors;
407 	info.interim_callbacks = aes_tests_interim_vectors;
408 	info.writeback_callbacks = aes_writeback_callbacks;
409 	info.kat_check = rsp_test_aes_check;
410 
411 	return 0;
412 }
413