1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(C) 2022 Marvell. 3 */ 4 5 #include <string.h> 6 #include <time.h> 7 #include <stdio.h> 8 #include <sys/types.h> 9 #include <unistd.h> 10 11 #ifdef USE_OPENSSL 12 #include <openssl/bn.h> 13 #include <openssl/rand.h> 14 #endif /* USE_OPENSSL */ 15 16 #include <rte_cryptodev.h> 17 #include <rte_malloc.h> 18 19 #include "fips_validation.h" 20 21 #define CONFORMANCE_JSON_STR "conformance" 22 #define TESTTYPE_JSON_STR "testType" 23 #define SIGTYPE_JSON_STR "sigType" 24 #define MOD_JSON_STR "modulo" 25 #define HASH_JSON_STR "hashAlg" 26 #define SALT_JSON_STR "saltLen" 27 #define RV_JSON_STR "randomValue" 28 #define E_JSON_STR "e" 29 #define N_JSON_STR "n" 30 31 #define SEED_JSON_STR "seed" 32 #define MSG_JSON_STR "message" 33 #define SIG_JSON_STR "signature" 34 35 36 #define RV_BUF_LEN (1024/8) 37 #define RV_BIT_LEN (256) 38 39 #ifdef USE_JANSSON 40 struct { 41 uint8_t type; 42 const char *desc; 43 } rsa_test_types[] = { 44 {RSA_AFT, "AFT"}, 45 {RSA_GDT, "GDT"}, 46 {RSA_KAT, "KAT"}, 47 }; 48 49 struct { 50 enum rte_crypto_auth_algorithm auth; 51 const char *desc; 52 } rsa_auth_algs[] = { 53 {RTE_CRYPTO_AUTH_SHA1, "SHA-1"}, 54 {RTE_CRYPTO_AUTH_SHA224, "SHA2-224"}, 55 {RTE_CRYPTO_AUTH_SHA256, "SHA2-256"}, 56 {RTE_CRYPTO_AUTH_SHA384, "SHA2-384"}, 57 {RTE_CRYPTO_AUTH_SHA512, "SHA2-512"}, 58 }; 59 60 struct { 61 enum rte_crypto_rsa_padding_type padding; 62 const char *desc; 63 } rsa_padding_types[] = { 64 {RTE_CRYPTO_RSA_PADDING_NONE, "none"}, 65 {RTE_CRYPTO_RSA_PADDING_PKCS1_5, "pkcs1v1.5"}, 66 {RTE_CRYPTO_RSA_PADDING_OAEP, "oaep"}, 67 {RTE_CRYPTO_RSA_PADDING_PSS, "pss"}, 68 }; 69 70 #ifdef USE_OPENSSL 71 static int 72 prepare_vec_rsa(void) 73 { 74 BIGNUM *p = NULL, *q = NULL, *n = NULL, *d = NULL, *e = NULL; 75 BIGNUM *dp = NULL, *dq = NULL, *qinv = NULL; 76 BIGNUM *r0, *r1, *r2, *r3, *r4; 77 BIGNUM *m = NULL, *r = NULL; 78 int bits, ret = -1, i; 79 char modbuf[8], *buf; 80 BN_CTX *ctx = NULL; 81 unsigned long pid; 82 83 /* Seed PRNG */ 84 if (vec.rsa.seed.val) { 85 writeback_hex_str("", info.one_line_text, &vec.rsa.seed); 86 RAND_seed((char *)info.one_line_text, strlen(info.one_line_text)); 87 } else { 88 pid = getpid(); 89 RAND_seed(&pid, sizeof(pid)); 90 } 91 92 if (!RAND_status()) 93 return -1; 94 95 /* Check if e is known already */ 96 if (vec.rsa.e.val) { 97 writeback_hex_str("", info.one_line_text, &vec.rsa.e); 98 ret = BN_hex2bn(&e, info.one_line_text); 99 if ((uint32_t)ret != strlen(info.one_line_text)) 100 goto err; 101 } 102 103 /* BN context initialization */ 104 ctx = BN_CTX_new(); 105 if (!ctx) 106 goto err; 107 108 BN_CTX_start(ctx); 109 r0 = BN_CTX_get(ctx); 110 r1 = BN_CTX_get(ctx); 111 r2 = BN_CTX_get(ctx); 112 r3 = BN_CTX_get(ctx); 113 r4 = BN_CTX_get(ctx); 114 if (!r4) 115 goto err; 116 117 /* Calculate bit length for prime numbers */ 118 m = BN_new(); 119 if (!m) 120 goto err; 121 122 snprintf(modbuf, sizeof(modbuf), "%d", info.interim_info.rsa_data.modulo); 123 if (!BN_dec2bn(&m, modbuf)) 124 goto err; 125 126 r = BN_new(); 127 if (!r) 128 goto err; 129 130 if (!BN_rshift1(r, m)) 131 goto err; 132 133 buf = BN_bn2dec(r); 134 bits = atoi(buf); 135 136 p = BN_new(); 137 if (!p) 138 goto err; 139 140 q = BN_new(); 141 if (!q) 142 goto err; 143 144 n = BN_new(); 145 if (!n) 146 goto err; 147 148 d = BN_new(); 149 if (!d) 150 goto err; 151 152 /* Generate p and q suitably for RSA */ 153 for (i = 0; i < 10; i++) { 154 uint8_t j = 0; 155 156 if (!BN_generate_prime_ex(p, bits, 0, NULL, NULL, NULL)) 157 goto err; 158 159 do { 160 RAND_add(&j, sizeof(j), 1); 161 if (!BN_generate_prime_ex(q, bits, 0, NULL, NULL, NULL)) 162 goto err; 163 164 } while ((BN_cmp(p, q) == 0) && (j++ < 100)); 165 166 if (j >= 100) { 167 RTE_LOG(ERR, USER1, "Error: insufficient %d retries to generate q", j); 168 goto err; 169 } 170 171 /* pq */ 172 if (!BN_mul(n, p, q, ctx)) 173 goto err; 174 175 /* p-1 */ 176 if (!BN_sub(r1, p, BN_value_one())) 177 goto err; 178 179 /* q-1 */ 180 if (!BN_sub(r2, q, BN_value_one())) 181 goto err; 182 183 /* (p-1 * q-1) */ 184 if (!BN_mul(r0, r1, r2, ctx)) 185 goto err; 186 187 /* gcd(p-1, q-1)*/ 188 if (!BN_gcd(r3, r1, r2, ctx)) 189 goto err; 190 191 /* lcm(p-1, q-1) */ 192 if (!BN_div(r4, r, r0, r3, ctx)) 193 goto err; 194 195 /* check if div and rem are non-zero */ 196 if (!r4 || !r) 197 goto err; 198 199 /* 0 < e < lcm */ 200 if (!e) { 201 int k = 0; 202 203 e = BN_new(); 204 do { 205 RAND_add(&k, sizeof(k), 1); 206 if (!BN_rand(e, 32, 1, 1)) 207 goto err; 208 209 if (!BN_gcd(r3, e, r4, ctx)) 210 goto err; 211 212 if (BN_is_one(r3)) 213 break; 214 } while (k++ < 10); 215 216 if (k >= 10) { 217 RTE_LOG(ERR, USER1, "Error: insufficient %d retries to generate e", 218 k); 219 goto err; 220 } 221 } 222 223 /* (de) mod lcm == 1 */ 224 if (!BN_mod_inverse(d, e, r4, ctx)) 225 goto err; 226 227 if (!BN_gcd(r3, r1, e, ctx)) 228 goto err; 229 230 if (!BN_gcd(r4, r2, e, ctx)) 231 goto err; 232 233 /* check if gcd(p-1, e) and gcd(q-1, e) are 1 */ 234 if (BN_is_one(r3) && BN_is_one(r4)) 235 break; 236 } 237 238 if (i >= 10) { 239 RTE_LOG(ERR, USER1, "Error: insufficient %d retries to generate p and q", i); 240 goto err; 241 } 242 243 /* d mod (p-1) */ 244 dp = BN_new(); 245 if (!dp) 246 goto err; 247 248 if (!BN_mod(dp, d, r1, ctx)) 249 goto err; 250 251 /* d mod (q-1) */ 252 dq = BN_new(); 253 if (!dq) 254 goto err; 255 256 if (!BN_mod(dq, d, r2, ctx)) 257 goto err; 258 259 /* modinv of q and p */ 260 qinv = BN_new(); 261 if (!qinv) 262 goto err; 263 264 if (!BN_mod_inverse(qinv, q, p, ctx)) 265 goto err; 266 267 if (info.interim_info.rsa_data.random_msg) { 268 if (!BN_generate_prime_ex(r, RV_BIT_LEN, 0, NULL, NULL, NULL)) 269 goto err; 270 271 parse_uint8_hex_str("", BN_bn2hex(r), &vec.rsa.seed); 272 } 273 274 parse_uint8_hex_str("", BN_bn2hex(e), &vec.rsa.e); 275 parse_uint8_hex_str("", BN_bn2hex(p), &vec.rsa.p); 276 parse_uint8_hex_str("", BN_bn2hex(q), &vec.rsa.q); 277 parse_uint8_hex_str("", BN_bn2hex(n), &vec.rsa.n); 278 parse_uint8_hex_str("", BN_bn2hex(d), &vec.rsa.d); 279 parse_uint8_hex_str("", BN_bn2hex(dp), &vec.rsa.dp); 280 parse_uint8_hex_str("", BN_bn2hex(dq), &vec.rsa.dq); 281 parse_uint8_hex_str("", BN_bn2hex(qinv), &vec.rsa.qinv); 282 283 ret = 0; 284 err: 285 BN_CTX_end(ctx); 286 BN_CTX_free(ctx); 287 BN_free(m); 288 BN_free(r); 289 BN_free(p); 290 BN_free(q); 291 BN_free(n); 292 BN_free(d); 293 BN_free(e); 294 return ret; 295 } 296 #else 297 static int 298 prepare_vec_rsa(void) 299 { 300 /* 301 * Generate RSA values. 302 */ 303 return -ENOTSUP; 304 } 305 #endif /* USE_OPENSSL */ 306 307 static int 308 parse_test_rsa_json_interim_writeback(struct fips_val *val) 309 { 310 RTE_SET_USED(val); 311 312 if (info.interim_info.rsa_data.random_msg) { 313 json_object_set_new(json_info.json_write_group, "conformance", 314 json_string("SP800-106")); 315 } 316 317 if (info.op == FIPS_TEST_ASYM_SIGGEN) { 318 json_t *obj; 319 320 /* For siggen tests, RSA values can be created soon after 321 * the test group data are parsed. 322 */ 323 if (vec.rsa.e.val) { 324 rte_free(vec.rsa.e.val); 325 vec.rsa.e.val = NULL; 326 } 327 328 if (prepare_vec_rsa() < 0) 329 return -1; 330 331 if (!vec.rsa.e.val) 332 return -1; 333 334 writeback_hex_str("", info.one_line_text, &vec.rsa.n); 335 obj = json_string(info.one_line_text); 336 json_object_set_new(json_info.json_write_group, "n", obj); 337 338 writeback_hex_str("", info.one_line_text, &vec.rsa.e); 339 obj = json_string(info.one_line_text); 340 json_object_set_new(json_info.json_write_group, "e", obj); 341 } 342 343 return 0; 344 } 345 346 static int 347 parse_test_rsa_json_writeback(struct fips_val *val) 348 { 349 json_t *tcId; 350 351 RTE_SET_USED(val); 352 353 tcId = json_object_get(json_info.json_test_case, "tcId"); 354 355 json_info.json_write_case = json_object(); 356 json_object_set(json_info.json_write_case, "tcId", tcId); 357 358 if (info.op == FIPS_TEST_ASYM_KEYGEN) { 359 json_t *obj; 360 361 writeback_hex_str("", info.one_line_text, &vec.rsa.seed); 362 obj = json_string(info.one_line_text); 363 json_object_set_new(json_info.json_write_case, "seed", obj); 364 365 writeback_hex_str("", info.one_line_text, &vec.rsa.n); 366 obj = json_string(info.one_line_text); 367 json_object_set_new(json_info.json_write_case, "n", obj); 368 369 writeback_hex_str("", info.one_line_text, &vec.rsa.e); 370 obj = json_string(info.one_line_text); 371 json_object_set_new(json_info.json_write_case, "e", obj); 372 373 writeback_hex_str("", info.one_line_text, &vec.rsa.p); 374 obj = json_string(info.one_line_text); 375 json_object_set_new(json_info.json_write_case, "p", obj); 376 377 writeback_hex_str("", info.one_line_text, &vec.rsa.q); 378 obj = json_string(info.one_line_text); 379 json_object_set_new(json_info.json_write_case, "q", obj); 380 381 writeback_hex_str("", info.one_line_text, &vec.rsa.d); 382 obj = json_string(info.one_line_text); 383 json_object_set_new(json_info.json_write_case, "d", obj); 384 } else if (info.op == FIPS_TEST_ASYM_SIGGEN) { 385 json_t *obj; 386 387 writeback_hex_str("", info.one_line_text, &vec.rsa.signature); 388 obj = json_string(info.one_line_text); 389 json_object_set_new(json_info.json_write_case, "signature", obj); 390 391 if (info.interim_info.rsa_data.random_msg) { 392 writeback_hex_str("", info.one_line_text, &vec.rsa.seed); 393 obj = json_string(info.one_line_text); 394 json_object_set_new(json_info.json_write_case, "randomValue", obj); 395 json_object_set_new(json_info.json_write_case, "randomValueLen", 396 json_integer(vec.rsa.seed.len * 8)); 397 } 398 } else if (info.op == FIPS_TEST_ASYM_SIGVER) { 399 if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) 400 json_object_set_new(json_info.json_write_case, "testPassed", json_true()); 401 else 402 json_object_set_new(json_info.json_write_case, "testPassed", json_false()); 403 } 404 405 return 0; 406 } 407 408 static int 409 parse_interim_str(const char *key, char *src, struct fips_val *val) 410 { 411 uint32_t i; 412 413 RTE_SET_USED(val); 414 415 if (strcmp(key, SIGTYPE_JSON_STR) == 0) { 416 for (i = 0; i < RTE_DIM(rsa_padding_types); i++) 417 if (strstr(src, rsa_padding_types[i].desc)) { 418 info.interim_info.rsa_data.padding = rsa_padding_types[i].padding; 419 break; 420 } 421 422 if (i >= RTE_DIM(rsa_padding_types)) 423 return -EINVAL; 424 425 } else if (strcmp(key, MOD_JSON_STR) == 0) { 426 info.interim_info.rsa_data.modulo = atoi(src); 427 } else if (strcmp(key, HASH_JSON_STR) == 0) { 428 for (i = 0; i < RTE_DIM(rsa_auth_algs); i++) 429 if (strstr(src, rsa_auth_algs[i].desc)) { 430 info.interim_info.rsa_data.auth = rsa_auth_algs[i].auth; 431 break; 432 } 433 434 if (i >= RTE_DIM(rsa_auth_algs)) 435 return -EINVAL; 436 437 } else if (strcmp(key, CONFORMANCE_JSON_STR) == 0) { 438 info.interim_info.rsa_data.random_msg = 1; 439 } else if (strcmp(key, SALT_JSON_STR) == 0) { 440 info.interim_info.rsa_data.saltlen = atoi(src); 441 } else if (strcmp(key, TESTTYPE_JSON_STR) == 0) { 442 for (i = 0; i < RTE_DIM(rsa_test_types); i++) 443 if (strstr(src, rsa_test_types[i].desc)) { 444 info.parse_writeback = parse_test_rsa_json_writeback; 445 break; 446 } 447 448 if (!info.parse_writeback || i >= RTE_DIM(rsa_test_types)) 449 return -EINVAL; 450 451 } else { 452 return -EINVAL; 453 } 454 455 return 0; 456 } 457 458 static int 459 parse_keygen_e_str(const char *key, char *src, struct fips_val *val) 460 { 461 parse_uint8_hex_str(key, src, val); 462 463 /* For keygen tests, key "e" can be the end of input data 464 * to generate RSA values. 465 */ 466 return prepare_vec_rsa(); 467 } 468 469 /* 470 * Message randomization function as per NIST SP 800-106. 471 */ 472 int 473 fips_test_randomize_message(struct fips_val *msg, struct fips_val *rand) 474 { 475 uint8_t m[FIPS_TEST_JSON_BUF_LEN], rv[RV_BUF_LEN]; 476 uint32_t m_bitlen, rv_bitlen, count, remain, i, j; 477 uint16_t rv_len; 478 479 if (!msg->val || !rand->val || rand->len > RV_BUF_LEN 480 || msg->len > (FIPS_TEST_JSON_BUF_LEN - 1)) 481 return -EINVAL; 482 483 memset(rv, 0, sizeof(rv)); 484 memcpy(rv, rand->val, rand->len); 485 rv_bitlen = rand->len * 8; 486 rv_len = rand->len; 487 488 memset(m, 0, sizeof(m)); 489 memcpy(m, msg->val, msg->len); 490 m_bitlen = msg->len * 8; 491 492 if (m_bitlen >= (rv_bitlen - 1)) { 493 m[msg->len] = 0x80; 494 m_bitlen += 8; 495 } else { 496 m[msg->len] = 0x80; 497 m_bitlen += (rv_bitlen - m_bitlen - 8); 498 } 499 500 count = m_bitlen / rv_bitlen; 501 remain = m_bitlen % rv_bitlen; 502 for (i = 0; i < count * rv_len; i++) 503 m[i] ^= rv[i % rv_len]; 504 505 for (j = 0; j < remain / 8; j++) 506 m[i + j] ^= rv[j]; 507 508 m[i + j] = ((uint8_t *)&rv_bitlen)[0]; 509 m[i + j + 1] = ((uint8_t *)&rv_bitlen)[1]; 510 511 rte_free(msg->val); 512 msg->len = (rv_bitlen + m_bitlen + 16) / 8; 513 msg->val = rte_zmalloc(NULL, msg->len, 0); 514 if (!msg->val) 515 return -EPERM; 516 517 memcpy(msg->val, rv, rv_len); 518 memcpy(&msg->val[rv_len], m, (m_bitlen + 16) / 8); 519 return 0; 520 } 521 522 static int 523 parse_siggen_message_str(const char *key, char *src, struct fips_val *val) 524 { 525 int ret = 0; 526 527 parse_uint8_hex_str(key, src, val); 528 if (info.interim_info.rsa_data.random_msg) 529 ret = fips_test_randomize_message(val, &vec.rsa.seed); 530 531 return ret; 532 } 533 534 static int 535 parse_sigver_randomvalue_str(const char *key, char *src, struct fips_val *val) 536 { 537 int ret = 0; 538 539 parse_uint8_hex_str(key, src, val); 540 if (info.interim_info.rsa_data.random_msg) 541 ret = fips_test_randomize_message(&vec.pt, val); 542 543 return ret; 544 } 545 546 struct fips_test_callback rsa_keygen_interim_json_vectors[] = { 547 {MOD_JSON_STR, parse_interim_str, NULL}, 548 {HASH_JSON_STR, parse_interim_str, NULL}, 549 {TESTTYPE_JSON_STR, parse_interim_str, NULL}, 550 {NULL, NULL, NULL} /**< end pointer */ 551 }; 552 553 struct fips_test_callback rsa_siggen_interim_json_vectors[] = { 554 {SIGTYPE_JSON_STR, parse_interim_str, NULL}, 555 {MOD_JSON_STR, parse_interim_str, NULL}, 556 {HASH_JSON_STR, parse_interim_str, NULL}, 557 {CONFORMANCE_JSON_STR, parse_interim_str, NULL}, 558 {SALT_JSON_STR, parse_interim_str, NULL}, 559 {TESTTYPE_JSON_STR, parse_interim_str, NULL}, 560 {NULL, NULL, NULL} /**< end pointer */ 561 }; 562 563 struct fips_test_callback rsa_sigver_interim_json_vectors[] = { 564 {SIGTYPE_JSON_STR, parse_interim_str, NULL}, 565 {MOD_JSON_STR, parse_interim_str, NULL}, 566 {HASH_JSON_STR, parse_interim_str, NULL}, 567 {CONFORMANCE_JSON_STR, parse_interim_str, NULL}, 568 {SALT_JSON_STR, parse_interim_str, NULL}, 569 {N_JSON_STR, parse_uint8_hex_str, &vec.rsa.n}, 570 {E_JSON_STR, parse_uint8_hex_str, &vec.rsa.e}, 571 {TESTTYPE_JSON_STR, parse_interim_str, NULL}, 572 {NULL, NULL, NULL} /**< end pointer */ 573 }; 574 575 struct fips_test_callback rsa_keygen_json_vectors[] = { 576 {SEED_JSON_STR, parse_uint8_hex_str, &vec.rsa.seed}, 577 {E_JSON_STR, parse_keygen_e_str, &vec.rsa.e}, 578 {NULL, NULL, NULL} /**< end pointer */ 579 }; 580 581 struct fips_test_callback rsa_siggen_json_vectors[] = { 582 {MSG_JSON_STR, parse_siggen_message_str, &vec.pt}, 583 {NULL, NULL, NULL} /**< end pointer */ 584 }; 585 586 struct fips_test_callback rsa_sigver_json_vectors[] = { 587 {MSG_JSON_STR, parse_uint8_hex_str, &vec.pt}, 588 {SIG_JSON_STR, parse_uint8_hex_str, &vec.rsa.signature}, 589 {RV_JSON_STR, parse_sigver_randomvalue_str, &vec.rsa.seed}, 590 {NULL, NULL, NULL} /**< end pointer */ 591 }; 592 593 int 594 parse_test_rsa_json_init(void) 595 { 596 json_t *keyfmt_obj = json_object_get(json_info.json_vector_set, "keyFormat"); 597 json_t *mode_obj = json_object_get(json_info.json_vector_set, "mode"); 598 const char *keyfmt_str = json_string_value(keyfmt_obj); 599 const char *mode_str = json_string_value(mode_obj); 600 601 info.callbacks = NULL; 602 info.parse_writeback = NULL; 603 info.interim_callbacks = NULL; 604 info.parse_interim_writeback = NULL; 605 info.interim_info.rsa_data.random_msg = 0; 606 607 if (strcmp(mode_str, "keyGen") == 0) { 608 info.op = FIPS_TEST_ASYM_KEYGEN; 609 info.callbacks = rsa_keygen_json_vectors; 610 info.interim_callbacks = rsa_keygen_interim_json_vectors; 611 } else if (strcmp(mode_str, "sigGen") == 0) { 612 info.op = FIPS_TEST_ASYM_SIGGEN; 613 info.callbacks = rsa_siggen_json_vectors; 614 info.interim_callbacks = rsa_siggen_interim_json_vectors; 615 info.parse_interim_writeback = parse_test_rsa_json_interim_writeback; 616 } else if (strcmp(mode_str, "sigVer") == 0) { 617 info.op = FIPS_TEST_ASYM_SIGVER; 618 info.callbacks = rsa_sigver_json_vectors; 619 info.interim_callbacks = rsa_sigver_interim_json_vectors; 620 info.parse_interim_writeback = parse_test_rsa_json_interim_writeback; 621 } else { 622 return -EINVAL; 623 } 624 625 info.interim_info.rsa_data.privkey = RTE_RSA_KEY_TYPE_QT; 626 if (keyfmt_str != NULL && strcmp(keyfmt_str, "standard") == 0) 627 info.interim_info.rsa_data.privkey = RTE_RSA_KEY_TYPE_EXP; 628 629 return 0; 630 } 631 632 #endif /* USE_JANSSON */ 633