1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2018 Intel Corporation
3 */
4
5 #include <string.h>
6 #include <stdio.h>
7
8 #include <rte_malloc.h>
9 #include <rte_cryptodev.h>
10
11 #include "fips_validation.h"
12
13 #define NEW_LINE_STR "#"
14 #define TEST_TYPE_KEY " for CBC"
15 #define TEST_TYPE_ECB_KEY " for ECB"
16 #define TEST_CBCI_KEY " for CBCI"
17
18 #define ENC_STR "[ENCRYPT]"
19 #define DEC_STR "[DECRYPT]"
20
21 #define COUNT_STR "COUNT = "
22 #define KEY1_STR "KEY1 = "
23 #define KEY2_STR "KEY2 = "
24 #define KEY3_STR "KEY3 = "
25
26 #define KEYS_STR "KEYs = "
27 #define IV_STR "IV = "
28 #define PT_STR "PLAINTEXT = "
29 #define CT_STR "CIPHERTEXT = "
30 #define NK_STR "NumKeys = "
31
32 #define SET_STR " = "
33
34 #define PLAIN_TEXT 0
35 #define CIPHER_TEXT 1
36 #define KEY_TEXT 2
37 #define IV_TEXT 3
38
39 #define DEVICE_STR "# Config Info for : "
40
41 #define ALGO_JSON_STR "algorithm"
42 #define TESTTYPE_JSON_STR "testType"
43 #define DIR_JSON_STR "direction"
44 #define KEYOPT_JSON_STR "keyingOption"
45
46 #define PT_JSON_STR "pt"
47 #define CT_JSON_STR "ct"
48 #define IV_JSON_STR "iv"
49 #define KEY1_JSON_STR "key1"
50 #define KEY2_JSON_STR "key2"
51 #define KEY3_JSON_STR "key3"
52
53 #define OP_ENC_JSON_STR "encrypt"
54 #define OP_DEC_JSON_STR "decrypt"
55
56 struct {
57 uint32_t type;
58 const char *desc;
59 } test_types[] = {
60 {TDES_INVERSE_PERMUTATION, "INVERSE PERMUTATION"},
61 {TDES_PERMUTATION, "PERMUTATION OPERATION"},
62 {TDES_SUBSTITUTION_TABLE, "SUBSTITUTION TABLE"},
63 {TDES_VARIABLE_KEY, "VARIABLE KEY"},
64 {TDES_VARIABLE_TEXT, "VARIABLE PLAINTEXT/CIPHERTEXT"},
65 {TDES_VARIABLE_TEXT, "KAT"},
66 {TDES_AFT, "Functional Test"},
67 {TDES_MCT, "Monte Carlo (Modes) Test"},
68 {TDES_MMT, "Multi block Message Test"},
69 };
70
71 static int
72 writeback_tdes_hex_str(const char *key, char *dst, struct fips_val *val);
73
74 static int
75 parse_tdes_uint8_hex_str(const char *key, char *src, struct fips_val *val);
76
77 static int
78 parse_tdes_interim(const char *key, char *text, struct fips_val *val);
79
80 struct fips_test_callback tdes_tests_vectors[] = {
81 {KEYS_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key},
82 {KEY1_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key},
83 {KEY2_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key},
84 {KEY3_STR, parse_tdes_uint8_hex_str, &vec.cipher_auth.key},
85 {IV_STR, parse_uint8_hex_str, &vec.iv},
86 {PT_STR, parse_uint8_hex_str, &vec.pt},
87 {CT_STR, parse_uint8_hex_str, &vec.ct},
88 {NULL, NULL, NULL} /**< end pointer */
89 };
90
91 struct fips_test_callback tdes_tests_interim_vectors[] = {
92 {ENC_STR, parse_tdes_interim, NULL},
93 {DEC_STR, parse_tdes_interim, NULL},
94 {NK_STR, parse_tdes_interim, NULL},
95 {NULL, NULL, NULL} /**< end pointer */
96 };
97
98 struct fips_test_callback tdes_writeback_callbacks[] = {
99 /** First element is used to pass COUNT string */
100 {COUNT_STR, NULL, NULL},
101 {IV_STR, writeback_hex_str, &vec.iv},
102 {KEY1_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
103 {KEY2_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
104 {KEY3_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
105 {KEYS_STR, writeback_tdes_hex_str, &vec.cipher_auth.key},
106 {PT_STR, writeback_hex_str, &vec.pt},
107 {CT_STR, writeback_hex_str, &vec.ct},
108 {NULL, NULL, NULL} /**< end pointer */
109 };
110
111 #ifdef USE_JANSSON
112 static struct {
113 enum fips_tdes_test_types type;
114 const char *desc;
115 } const tdes_test_types[] = {
116 {TDES_AFT, "AFT"},
117 {TDES_MCT, "MCT"},
118 };
119
120 static struct {
121 enum fips_tdes_test_mode mode;
122 const char *desc;
123 } const tdes_test_modes[] = {
124 {TDES_MODE_CBC, "CBC"},
125 {TDES_MODE_ECB, "ECB"},
126 };
127
128 #define TDES_KEYS_TUPLE_LEN 24
129
130 static int
parser_tdes_read_key(const char * key,char * src,struct fips_val * val)131 parser_tdes_read_key(const char *key, char *src, struct fips_val *val)
132 {
133 uint8_t tmp_key[TDES_KEYS_TUPLE_LEN] = {0};
134 uint32_t len, i;
135
136 len = strlen(src) / 2;
137
138 if (val->val) {
139 memcpy(tmp_key, val->val, val->len);
140 rte_free(val->val);
141 }
142
143 val->val = rte_zmalloc(NULL, TDES_KEYS_TUPLE_LEN, 0);
144 if (!val->val)
145 return -1;
146
147 memcpy(val->val, tmp_key, TDES_KEYS_TUPLE_LEN);
148
149 if (strstr(key, KEY1_JSON_STR)) {
150 for (i = 0; i < len; i++) {
151 char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
152
153 if (parser_read_uint8_hex(&val->val[i], byte) < 0)
154 goto error_exit;
155 }
156
157 if (info.interim_info.tdes_data.nb_keys == 2)
158 memcpy(val->val + 16, val->val, 8);
159
160 } else if (strstr(key, KEY2_JSON_STR)) {
161 for (i = 0; i < len; i++) {
162 char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
163
164 if (parser_read_uint8_hex(&val->val[i + 8], byte) < 0)
165 goto error_exit;
166 }
167
168 } else if (strstr(key, KEY3_JSON_STR)) {
169 for (i = 0; i < len; i++) {
170 char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
171
172 if (parser_read_uint8_hex(&val->val[i + 16], byte) < 0)
173 goto error_exit;
174 }
175 } else
176 return -EINVAL;
177
178 val->len = TDES_KEYS_TUPLE_LEN;
179
180 return 0;
181
182 error_exit:
183 rte_free(val->val);
184 memset(val, 0, sizeof(*val));
185 return -EINVAL;
186 }
187
188 struct fips_test_callback tdes_dec_json_vectors[] = {
189 {KEY1_JSON_STR, parser_tdes_read_key, &vec.cipher_auth.key},
190 {KEY2_JSON_STR, parser_tdes_read_key, &vec.cipher_auth.key},
191 {KEY3_JSON_STR, parser_tdes_read_key, &vec.cipher_auth.key},
192 {IV_JSON_STR, parse_uint8_hex_str, &vec.iv},
193 {CT_JSON_STR, parse_uint8_hex_str, &vec.ct},
194 {NULL, NULL, NULL} /**< end pointer */
195 };
196
197 struct fips_test_callback tdes_enc_json_vectors[] = {
198 {KEY1_JSON_STR, parser_tdes_read_key, &vec.cipher_auth.key},
199 {KEY2_JSON_STR, parser_tdes_read_key, &vec.cipher_auth.key},
200 {KEY3_JSON_STR, parser_tdes_read_key, &vec.cipher_auth.key},
201 {IV_JSON_STR, parse_uint8_hex_str, &vec.iv},
202 {PT_JSON_STR, parse_uint8_hex_str, &vec.pt},
203 {NULL, NULL, NULL} /**< end pointer */
204 };
205
206 static int
parse_test_tdes_json_writeback(struct fips_val * val)207 parse_test_tdes_json_writeback(struct fips_val *val)
208 {
209 struct fips_val tmp_val;
210 json_t *tcId;
211
212 tcId = json_object_get(json_info.json_test_case, "tcId");
213
214 json_info.json_write_case = json_object();
215 json_object_set(json_info.json_write_case, "tcId", tcId);
216
217 if (info.op == FIPS_TEST_ENC_AUTH_GEN) {
218 json_t *ct;
219
220 tmp_val.val = val->val;
221 tmp_val.len = vec.pt.len;
222
223 writeback_hex_str("", info.one_line_text, &tmp_val);
224 ct = json_string(info.one_line_text);
225 json_object_set_new(json_info.json_write_case, CT_JSON_STR, ct);
226
227 tmp_val.val = val->val + vec.pt.len;
228 tmp_val.len = val->len - vec.pt.len;
229
230 writeback_hex_str("", info.one_line_text, &tmp_val);
231 } else {
232 if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
233 tmp_val.val = val->val;
234 tmp_val.len = vec.ct.len;
235
236 writeback_hex_str("", info.one_line_text, &tmp_val);
237 json_object_set_new(json_info.json_write_case, PT_JSON_STR,
238 json_string(info.one_line_text));
239 } else {
240 json_object_set_new(json_info.json_write_case, "testPassed", json_false());
241 }
242 }
243
244 return 0;
245 }
246
247 static int
parse_test_tdes_mct_json_writeback(struct fips_val * val)248 parse_test_tdes_mct_json_writeback(struct fips_val *val)
249 {
250 json_t *tcId, *resArr, *res, *ct, *pt, *key, *iv;
251 struct fips_val tmp_val;
252
253 tcId = json_object_get(json_info.json_test_case, "tcId");
254 if (json_info.json_write_case) {
255 json_t *wcId;
256
257 wcId = json_object_get(json_info.json_write_case, "tcId");
258 if (!json_equal(tcId, wcId)) {
259 json_info.json_write_case = json_object();
260 json_object_set(json_info.json_write_case, "tcId", tcId);
261 json_object_set(json_info.json_write_case, "resultsArray", json_array());
262 }
263 } else {
264 json_info.json_write_case = json_object();
265 json_object_set(json_info.json_write_case, "tcId", tcId);
266 json_object_set(json_info.json_write_case, "resultsArray", json_array());
267 }
268
269 resArr = json_object_get(json_info.json_write_case, "resultsArray");
270 if (!json_is_array(resArr))
271 return -EINVAL;
272
273 res = json_object();
274 if (info .op == FIPS_TEST_ENC_AUTH_GEN) {
275 tmp_val.len = 8;
276 tmp_val.val = vec.cipher_auth.key.val;
277 writeback_hex_str("", info.one_line_text, &tmp_val);
278 key = json_string(info.one_line_text);
279 json_object_set_new(res, KEY1_JSON_STR, key);
280
281 tmp_val.val = vec.cipher_auth.key.val + 8;
282 writeback_hex_str("", info.one_line_text, &tmp_val);
283 key = json_string(info.one_line_text);
284 json_object_set_new(res, KEY2_JSON_STR, key);
285
286 tmp_val.val = vec.cipher_auth.key.val + 16;
287 writeback_hex_str("", info.one_line_text, &tmp_val);
288 key = json_string(info.one_line_text);
289 json_object_set_new(res, KEY3_JSON_STR, key);
290
291 if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC) {
292 writeback_hex_str("", info.one_line_text, &val[2]);
293 iv = json_string(info.one_line_text);
294 json_object_set_new(res, IV_JSON_STR, iv);
295 }
296
297 writeback_hex_str("", info.one_line_text, &val[1]);
298 pt = json_string(info.one_line_text);
299 json_object_set_new(res, PT_JSON_STR, pt);
300
301 tmp_val.val = val->val;
302 tmp_val.len = vec.pt.len;
303
304 writeback_hex_str("", info.one_line_text, &tmp_val);
305 ct = json_string(info.one_line_text);
306 json_object_set_new(res, CT_JSON_STR, ct);
307
308 tmp_val.val = val->val + vec.pt.len;
309 tmp_val.len = val->len - vec.pt.len;
310
311 writeback_hex_str("", info.one_line_text, &tmp_val);
312 } else {
313 if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) {
314 tmp_val.len = 8;
315 tmp_val.val = vec.cipher_auth.key.val;
316 writeback_hex_str("", info.one_line_text, &tmp_val);
317 key = json_string(info.one_line_text);
318 json_object_set_new(res, KEY1_JSON_STR, key);
319
320 tmp_val.val = vec.cipher_auth.key.val + 8;
321 writeback_hex_str("", info.one_line_text, &tmp_val);
322 key = json_string(info.one_line_text);
323 json_object_set_new(res, KEY2_JSON_STR, key);
324
325 tmp_val.val = vec.cipher_auth.key.val + 16;
326 writeback_hex_str("", info.one_line_text, &tmp_val);
327 key = json_string(info.one_line_text);
328 json_object_set_new(res, KEY3_JSON_STR, key);
329
330 if (info.interim_info.tdes_data.test_mode == TDES_MODE_CBC) {
331 writeback_hex_str("", info.one_line_text, &val[2]);
332 iv = json_string(info.one_line_text);
333 json_object_set_new(res, IV_JSON_STR, iv);
334 }
335
336 tmp_val.val = val->val;
337 tmp_val.len = vec.ct.len;
338
339 writeback_hex_str("", info.one_line_text, &tmp_val);
340 pt = json_string(info.one_line_text);
341 json_object_set_new(res, PT_JSON_STR, pt);
342
343 writeback_hex_str("", info.one_line_text, &val[1]);
344 ct = json_string(info.one_line_text);
345 json_object_set_new(res, CT_JSON_STR, ct);
346 } else {
347 json_object_set_new(json_info.json_write_case, "testPassed", json_false());
348 }
349 }
350
351 json_array_append_new(resArr, res);
352
353 return 0;
354 }
355
parse_test_tdes_json_init(void)356 int parse_test_tdes_json_init(void)
357 {
358 json_t *type_obj = json_object_get(json_info.json_test_group, TESTTYPE_JSON_STR);
359 json_t *algo_obj = json_object_get(json_info.json_vector_set, ALGO_JSON_STR);
360 const char *type_str = json_string_value(type_obj);
361 const char *algo_str = json_string_value(algo_obj);
362 uint32_t i;
363
364 if (json_info.json_test_group) {
365 json_t *direction_obj, *opt_obj;
366 const char *direction_str;
367 int opt_val;
368
369 direction_obj = json_object_get(json_info.json_test_group, DIR_JSON_STR);
370 direction_str = json_string_value(direction_obj);
371
372 if (strcmp(direction_str, OP_ENC_JSON_STR) == 0) {
373 info.op = FIPS_TEST_ENC_AUTH_GEN;
374 info.callbacks = tdes_enc_json_vectors;
375 } else if (strcmp(direction_str, OP_DEC_JSON_STR) == 0) {
376 info.op = FIPS_TEST_DEC_AUTH_VERIF;
377 info.callbacks = tdes_dec_json_vectors;
378 } else {
379 return -EINVAL;
380 }
381
382 opt_obj = json_object_get(json_info.json_test_group, KEYOPT_JSON_STR);
383 opt_val = json_integer_value(opt_obj);
384 if (opt_val == 2)
385 info.interim_info.tdes_data.nb_keys = 2;
386 else
387 info.interim_info.tdes_data.nb_keys = 3;
388
389 info.interim_callbacks = NULL;
390 }
391
392 for (i = 0; i < RTE_DIM(tdes_test_types); i++)
393 if (strstr(type_str, tdes_test_types[i].desc)) {
394 info.interim_info.tdes_data.test_type =
395 tdes_test_types[i].type;
396 break;
397 }
398
399 if (i >= RTE_DIM(tdes_test_types))
400 return -EINVAL;
401
402 for (i = 0; RTE_DIM(tdes_test_modes); i++)
403 if (strstr(algo_str, tdes_test_modes[i].desc)) {
404 info.interim_info.tdes_data.test_mode =
405 tdes_test_modes[i].mode;
406 break;
407 }
408
409 if (i >= RTE_DIM(tdes_test_modes))
410 return -EINVAL;
411
412 switch (info.interim_info.tdes_data.test_type) {
413 case TDES_AFT:
414 info.parse_writeback = parse_test_tdes_json_writeback;
415 break;
416 case TDES_MCT:
417 info.parse_writeback = parse_test_tdes_mct_json_writeback;
418 break;
419 default:
420 info.parse_writeback = NULL;
421 };
422
423 if (info.parse_writeback == NULL)
424 return -EINVAL;
425
426 return 0;
427 }
428 #endif /* USE_JANSSON */
429
430 static int
parse_tdes_interim(const char * key,char * text,__rte_unused struct fips_val * val)431 parse_tdes_interim(const char *key, char *text,
432 __rte_unused struct fips_val *val)
433 {
434 if (strstr(key, ENC_STR))
435 info.op = FIPS_TEST_ENC_AUTH_GEN;
436 else if (strstr(key, DEC_STR))
437 info.op = FIPS_TEST_DEC_AUTH_VERIF;
438 else if (strstr(key, NK_STR)) {
439 if (strcmp(text, "NumKeys = 1") == 0)
440 info.interim_info.tdes_data.nb_keys = 1;
441 else if (strcmp(text, "NumKeys = 2") == 0)
442 info.interim_info.tdes_data.nb_keys = 2;
443 else if (strcmp(text, "NumKeys = 3") == 0)
444 info.interim_info.tdes_data.nb_keys = 3;
445 else
446 return -EINVAL;
447 } else
448 return -EINVAL;
449
450 return 0;
451 }
452
453 static int
parse_tdes_uint8_hex_str(const char * key,char * src,struct fips_val * val)454 parse_tdes_uint8_hex_str(const char *key, char *src, struct fips_val *val)
455 {
456 uint8_t tmp_key[24] = {0};
457 uint32_t len, i;
458
459 src += strlen(key);
460
461 len = strlen(src) / 2;
462
463 if (val->val) {
464 memcpy(tmp_key, val->val, val->len);
465 rte_free(val->val);
466 }
467
468 val->val = rte_zmalloc(NULL, 24, 0);
469 if (!val->val)
470 return -1;
471
472 memcpy(val->val, tmp_key, 24);
473
474 if (strstr(key, KEYS_STR)) {
475 for (i = 0; i < len; i++) {
476 char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
477
478 if (parser_read_uint8_hex(&val->val[i], byte) < 0)
479 goto error_exit;
480 }
481
482 memcpy(val->val + 8, val->val, 8);
483 memcpy(val->val + 16, val->val, 8);
484
485 } else if (strstr(key, KEY1_STR)) {
486 for (i = 0; i < len; i++) {
487 char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
488
489 if (parser_read_uint8_hex(&val->val[i], byte) < 0)
490 goto error_exit;
491 }
492
493 if (info.interim_info.tdes_data.nb_keys == 2)
494 memcpy(val->val + 16, val->val, 8);
495
496 } else if (strstr(key, KEY2_STR)) {
497 for (i = 0; i < len; i++) {
498 char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
499
500 if (parser_read_uint8_hex(&val->val[i + 8], byte) < 0)
501 goto error_exit;
502 }
503
504 } else if (strstr(key, KEY3_STR)) {
505 for (i = 0; i < len; i++) {
506 char byte[3] = {src[i * 2], src[i * 2 + 1], '\0'};
507
508 if (parser_read_uint8_hex(&val->val[i + 16], byte) < 0)
509 goto error_exit;
510 }
511 } else
512 return -EINVAL;
513
514 val->len = 24;
515
516 return 0;
517
518 error_exit:
519 rte_free(val->val);
520 memset(val, 0, sizeof(*val));
521 return -EINVAL;
522 }
523
524 static int
parse_test_tdes_writeback(struct fips_val * val)525 parse_test_tdes_writeback(struct fips_val *val)
526 {
527
528 if (info.op == FIPS_TEST_ENC_AUTH_GEN)
529 fprintf(info.fp_wr, "%s", CT_STR);
530 else
531 fprintf(info.fp_wr, "%s", PT_STR);
532
533 parse_write_hex_str(val);
534
535 return 0;
536
537 }
538
539 static int
writeback_tdes_hex_str(const char * key,char * dst,struct fips_val * val)540 writeback_tdes_hex_str(const char *key, char *dst, struct fips_val *val)
541 {
542 struct fips_val tmp_val = {0};
543
544 tmp_val.len = 8;
545
546 if (strstr(key, KEY1_STR))
547 tmp_val.val = val->val;
548 else if (strstr(key, KEY2_STR))
549 tmp_val.val = val->val + 8;
550 else if (strstr(key, KEY3_STR))
551 tmp_val.val = val->val + 16;
552 else
553 return -EINVAL;
554
555 return writeback_hex_str(key, dst, &tmp_val);
556 }
557
558 static int
rsp_test_tdes_check(struct fips_val * val)559 rsp_test_tdes_check(struct fips_val *val)
560 {
561 struct fips_val *data;
562
563 if (info.op == FIPS_TEST_ENC_AUTH_GEN)
564 data = &vec.ct;
565 else
566 data = &vec.pt;
567
568 if (memcmp(val->val, data->val, val->len) == 0)
569 fprintf(info.fp_wr, "Success\n");
570 else
571 fprintf(info.fp_wr, "Failed\n");
572
573 return 0;
574 }
575
576 int
parse_test_tdes_init(void)577 parse_test_tdes_init(void)
578 {
579 uint32_t i;
580
581 for (i = 0; i < info.nb_vec_lines; i++) {
582 char *line = info.vec[i];
583 uint32_t j;
584
585 if (strstr(line, TEST_CBCI_KEY))
586 return -EPERM;
587
588 for (j = 0; j < RTE_DIM(test_types); j++)
589 if (strstr(line, test_types[j].desc)) {
590 info.interim_info.tdes_data.test_type =
591 test_types[j].type;
592 if (strstr(line, TEST_TYPE_ECB_KEY))
593 info.interim_info.tdes_data.test_mode =
594 TDES_MODE_ECB;
595 else
596 info.interim_info.tdes_data.test_mode =
597 TDES_MODE_CBC;
598 break;
599 }
600 }
601
602 info.parse_writeback = parse_test_tdes_writeback;
603 info.callbacks = tdes_tests_vectors;
604 info.interim_callbacks = tdes_tests_interim_vectors;
605 info.writeback_callbacks = tdes_writeback_callbacks;
606 info.kat_check = rsp_test_tdes_check;
607
608 return 0;
609 }
610