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 writeback_hex_str("", info.one_line_text, &vec.rsa.n); 332 obj = json_string(info.one_line_text); 333 json_object_set_new(json_info.json_write_group, "n", obj); 334 335 writeback_hex_str("", info.one_line_text, &vec.rsa.e); 336 obj = json_string(info.one_line_text); 337 json_object_set_new(json_info.json_write_group, "e", obj); 338 } 339 340 return 0; 341 } 342 343 static int 344 parse_test_rsa_json_writeback(struct fips_val *val) 345 { 346 json_t *tcId; 347 348 RTE_SET_USED(val); 349 350 tcId = json_object_get(json_info.json_test_case, "tcId"); 351 352 json_info.json_write_case = json_object(); 353 json_object_set(json_info.json_write_case, "tcId", tcId); 354 355 if (info.op == FIPS_TEST_ASYM_KEYGEN) { 356 json_t *obj; 357 358 writeback_hex_str("", info.one_line_text, &vec.rsa.seed); 359 obj = json_string(info.one_line_text); 360 json_object_set_new(json_info.json_write_case, "seed", obj); 361 362 writeback_hex_str("", info.one_line_text, &vec.rsa.n); 363 obj = json_string(info.one_line_text); 364 json_object_set_new(json_info.json_write_case, "n", obj); 365 366 writeback_hex_str("", info.one_line_text, &vec.rsa.e); 367 obj = json_string(info.one_line_text); 368 json_object_set_new(json_info.json_write_case, "e", obj); 369 370 writeback_hex_str("", info.one_line_text, &vec.rsa.p); 371 obj = json_string(info.one_line_text); 372 json_object_set_new(json_info.json_write_case, "p", obj); 373 374 writeback_hex_str("", info.one_line_text, &vec.rsa.q); 375 obj = json_string(info.one_line_text); 376 json_object_set_new(json_info.json_write_case, "q", obj); 377 378 writeback_hex_str("", info.one_line_text, &vec.rsa.d); 379 obj = json_string(info.one_line_text); 380 json_object_set_new(json_info.json_write_case, "d", obj); 381 } else if (info.op == FIPS_TEST_ASYM_SIGGEN) { 382 json_t *obj; 383 384 writeback_hex_str("", info.one_line_text, &vec.rsa.signature); 385 obj = json_string(info.one_line_text); 386 json_object_set_new(json_info.json_write_case, "signature", obj); 387 388 if (info.interim_info.rsa_data.random_msg) { 389 writeback_hex_str("", info.one_line_text, &vec.rsa.seed); 390 obj = json_string(info.one_line_text); 391 json_object_set_new(json_info.json_write_case, "randomValue", obj); 392 json_object_set_new(json_info.json_write_case, "randomValueLen", 393 json_integer(vec.rsa.seed.len * 8)); 394 } 395 } else if (info.op == FIPS_TEST_ASYM_SIGVER) { 396 if (vec.status == RTE_CRYPTO_OP_STATUS_SUCCESS) 397 json_object_set_new(json_info.json_write_case, "testPassed", json_true()); 398 else 399 json_object_set_new(json_info.json_write_case, "testPassed", json_false()); 400 } 401 402 return 0; 403 } 404 405 static int 406 parse_interim_str(const char *key, char *src, struct fips_val *val) 407 { 408 uint32_t i; 409 410 RTE_SET_USED(val); 411 412 if (strcmp(key, SIGTYPE_JSON_STR) == 0) { 413 for (i = 0; i < RTE_DIM(rsa_padding_types); i++) 414 if (strstr(src, rsa_padding_types[i].desc)) { 415 info.interim_info.rsa_data.padding = rsa_padding_types[i].padding; 416 break; 417 } 418 419 if (i >= RTE_DIM(rsa_padding_types)) 420 return -EINVAL; 421 422 } else if (strcmp(key, MOD_JSON_STR) == 0) { 423 info.interim_info.rsa_data.modulo = atoi(src); 424 } else if (strcmp(key, HASH_JSON_STR) == 0) { 425 for (i = 0; i < RTE_DIM(rsa_auth_algs); i++) 426 if (strstr(src, rsa_auth_algs[i].desc)) { 427 info.interim_info.rsa_data.auth = rsa_auth_algs[i].auth; 428 break; 429 } 430 431 if (i >= RTE_DIM(rsa_auth_algs)) 432 return -EINVAL; 433 434 } else if (strcmp(key, CONFORMANCE_JSON_STR) == 0) { 435 info.interim_info.rsa_data.random_msg = 1; 436 } else if (strcmp(key, SALT_JSON_STR) == 0) { 437 info.interim_info.rsa_data.saltlen = atoi(src); 438 } else if (strcmp(key, TESTTYPE_JSON_STR) == 0) { 439 for (i = 0; i < RTE_DIM(rsa_test_types); i++) 440 if (strstr(src, rsa_test_types[i].desc)) { 441 info.parse_writeback = parse_test_rsa_json_writeback; 442 break; 443 } 444 445 if (!info.parse_writeback || i >= RTE_DIM(rsa_test_types)) 446 return -EINVAL; 447 448 } else { 449 return -EINVAL; 450 } 451 452 return 0; 453 } 454 455 static int 456 parse_keygen_e_str(const char *key, char *src, struct fips_val *val) 457 { 458 parse_uint8_hex_str(key, src, val); 459 460 /* For keygen tests, key "e" can be the end of input data 461 * to generate RSA values. 462 */ 463 return prepare_vec_rsa(); 464 } 465 466 /* 467 * Message randomization function as per NIST SP 800-106. 468 */ 469 int 470 fips_test_randomize_message(struct fips_val *msg, struct fips_val *rand) 471 { 472 uint8_t m[FIPS_TEST_JSON_BUF_LEN], rv[RV_BUF_LEN]; 473 uint32_t m_bitlen, rv_bitlen, count, remain, i, j; 474 uint16_t rv_len; 475 476 if (!msg->val || !rand->val || rand->len > RV_BUF_LEN 477 || msg->len > FIPS_TEST_JSON_BUF_LEN) 478 return -EINVAL; 479 480 memset(rv, 0, sizeof(rv)); 481 memcpy(rv, rand->val, rand->len); 482 rv_bitlen = rand->len * 8; 483 rv_len = rand->len; 484 485 memset(m, 0, sizeof(m)); 486 memcpy(m, msg->val, msg->len); 487 m_bitlen = msg->len * 8; 488 489 if (m_bitlen >= (rv_bitlen - 1)) { 490 m[msg->len] = 0x80; 491 m_bitlen += 8; 492 } else { 493 m[msg->len] = 0x80; 494 m_bitlen += (rv_bitlen - m_bitlen - 8); 495 } 496 497 count = m_bitlen / rv_bitlen; 498 remain = m_bitlen % rv_bitlen; 499 for (i = 0; i < count * rv_len; i++) 500 m[i] ^= rv[i % rv_len]; 501 502 for (j = 0; j < remain / 8; j++) 503 m[i + j] ^= rv[j]; 504 505 m[i + j] = ((uint8_t *)&rv_bitlen)[0]; 506 m[i + j + 1] = (((uint8_t *)&rv_bitlen)[1] >> 8) & 0xFF; 507 508 rte_free(msg->val); 509 msg->len = (rv_bitlen + m_bitlen + 16) / 8; 510 msg->val = rte_zmalloc(NULL, msg->len, 0); 511 if (!msg->val) 512 return -EPERM; 513 514 memcpy(msg->val, rv, rv_len); 515 memcpy(&msg->val[rv_len], m, (m_bitlen + 16) / 8); 516 return 0; 517 } 518 519 static int 520 parse_siggen_message_str(const char *key, char *src, struct fips_val *val) 521 { 522 int ret = 0; 523 524 parse_uint8_hex_str(key, src, val); 525 if (info.interim_info.rsa_data.random_msg) 526 ret = fips_test_randomize_message(val, &vec.rsa.seed); 527 528 return ret; 529 } 530 531 static int 532 parse_sigver_randomvalue_str(const char *key, char *src, struct fips_val *val) 533 { 534 int ret = 0; 535 536 parse_uint8_hex_str(key, src, val); 537 if (info.interim_info.rsa_data.random_msg) 538 ret = fips_test_randomize_message(&vec.pt, val); 539 540 return ret; 541 } 542 543 struct fips_test_callback rsa_keygen_interim_json_vectors[] = { 544 {MOD_JSON_STR, parse_interim_str, NULL}, 545 {HASH_JSON_STR, parse_interim_str, NULL}, 546 {TESTTYPE_JSON_STR, parse_interim_str, NULL}, 547 {NULL, NULL, NULL} /**< end pointer */ 548 }; 549 550 struct fips_test_callback rsa_siggen_interim_json_vectors[] = { 551 {SIGTYPE_JSON_STR, parse_interim_str, NULL}, 552 {MOD_JSON_STR, parse_interim_str, NULL}, 553 {HASH_JSON_STR, parse_interim_str, NULL}, 554 {CONFORMANCE_JSON_STR, parse_interim_str, NULL}, 555 {SALT_JSON_STR, parse_interim_str, NULL}, 556 {TESTTYPE_JSON_STR, parse_interim_str, NULL}, 557 {NULL, NULL, NULL} /**< end pointer */ 558 }; 559 560 struct fips_test_callback rsa_sigver_interim_json_vectors[] = { 561 {SIGTYPE_JSON_STR, parse_interim_str, NULL}, 562 {MOD_JSON_STR, parse_interim_str, NULL}, 563 {HASH_JSON_STR, parse_interim_str, NULL}, 564 {CONFORMANCE_JSON_STR, parse_interim_str, NULL}, 565 {SALT_JSON_STR, parse_interim_str, NULL}, 566 {N_JSON_STR, parse_uint8_hex_str, &vec.rsa.n}, 567 {E_JSON_STR, parse_uint8_hex_str, &vec.rsa.e}, 568 {TESTTYPE_JSON_STR, parse_interim_str, NULL}, 569 {NULL, NULL, NULL} /**< end pointer */ 570 }; 571 572 struct fips_test_callback rsa_keygen_json_vectors[] = { 573 {SEED_JSON_STR, parse_uint8_hex_str, &vec.rsa.seed}, 574 {E_JSON_STR, parse_keygen_e_str, &vec.rsa.e}, 575 {NULL, NULL, NULL} /**< end pointer */ 576 }; 577 578 struct fips_test_callback rsa_siggen_json_vectors[] = { 579 {MSG_JSON_STR, parse_siggen_message_str, &vec.pt}, 580 {NULL, NULL, NULL} /**< end pointer */ 581 }; 582 583 struct fips_test_callback rsa_sigver_json_vectors[] = { 584 {MSG_JSON_STR, parse_uint8_hex_str, &vec.pt}, 585 {SIG_JSON_STR, parse_uint8_hex_str, &vec.rsa.signature}, 586 {RV_JSON_STR, parse_sigver_randomvalue_str, &vec.rsa.seed}, 587 {NULL, NULL, NULL} /**< end pointer */ 588 }; 589 590 int 591 parse_test_rsa_json_init(void) 592 { 593 json_t *keyfmt_obj = json_object_get(json_info.json_vector_set, "keyFormat"); 594 json_t *mode_obj = json_object_get(json_info.json_vector_set, "mode"); 595 const char *keyfmt_str = json_string_value(keyfmt_obj); 596 const char *mode_str = json_string_value(mode_obj); 597 598 info.callbacks = NULL; 599 info.parse_writeback = NULL; 600 info.interim_callbacks = NULL; 601 info.parse_interim_writeback = NULL; 602 info.interim_info.rsa_data.random_msg = 0; 603 604 if (strcmp(mode_str, "keyGen") == 0) { 605 info.op = FIPS_TEST_ASYM_KEYGEN; 606 info.callbacks = rsa_keygen_json_vectors; 607 info.interim_callbacks = rsa_keygen_interim_json_vectors; 608 } else if (strcmp(mode_str, "sigGen") == 0) { 609 info.op = FIPS_TEST_ASYM_SIGGEN; 610 info.callbacks = rsa_siggen_json_vectors; 611 info.interim_callbacks = rsa_siggen_interim_json_vectors; 612 info.parse_interim_writeback = parse_test_rsa_json_interim_writeback; 613 } else if (strcmp(mode_str, "sigVer") == 0) { 614 info.op = FIPS_TEST_ASYM_SIGVER; 615 info.callbacks = rsa_sigver_json_vectors; 616 info.interim_callbacks = rsa_sigver_interim_json_vectors; 617 info.parse_interim_writeback = parse_test_rsa_json_interim_writeback; 618 } else { 619 return -EINVAL; 620 } 621 622 info.interim_info.rsa_data.privkey = RTE_RSA_KEY_TYPE_QT; 623 if (keyfmt_str != NULL && strcmp(keyfmt_str, "standard") == 0) 624 info.interim_info.rsa_data.privkey = RTE_RSA_KEY_TYPE_EXP; 625 626 return 0; 627 } 628 629 #endif /* USE_JANSSON */ 630