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 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 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 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 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 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 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 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 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 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 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