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