1 /* 2 * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 /* We need to use some engine deprecated APIs */ 11 #define OPENSSL_SUPPRESS_DEPRECATED 12 13 #include <openssl/err.h> 14 #include <openssl/opensslconf.h> 15 #include <openssl/core_names.h> 16 #include "internal/cryptlib.h" 17 #include "internal/thread_once.h" 18 #include "crypto/rand.h" 19 #include "crypto/cryptlib.h" 20 #include "rand_local.h" 21 22 #ifndef FIPS_MODULE 23 # include <stdio.h> 24 # include <time.h> 25 # include <limits.h> 26 # include <openssl/conf.h> 27 # include <openssl/trace.h> 28 # include <openssl/engine.h> 29 # include "crypto/rand_pool.h" 30 # include "prov/seeding.h" 31 # include "e_os.h" 32 33 # ifndef OPENSSL_NO_ENGINE 34 /* non-NULL if default_RAND_meth is ENGINE-provided */ 35 static ENGINE *funct_ref; 36 static CRYPTO_RWLOCK *rand_engine_lock; 37 # endif 38 # ifndef OPENSSL_NO_DEPRECATED_3_0 39 static CRYPTO_RWLOCK *rand_meth_lock; 40 static const RAND_METHOD *default_RAND_meth; 41 # endif 42 static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT; 43 44 static int rand_inited = 0; 45 46 DEFINE_RUN_ONCE_STATIC(do_rand_init) 47 { 48 # ifndef OPENSSL_NO_ENGINE 49 rand_engine_lock = CRYPTO_THREAD_lock_new(); 50 if (rand_engine_lock == NULL) 51 return 0; 52 # endif 53 54 # ifndef OPENSSL_NO_DEPRECATED_3_0 55 rand_meth_lock = CRYPTO_THREAD_lock_new(); 56 if (rand_meth_lock == NULL) 57 goto err; 58 # endif 59 60 if (!ossl_rand_pool_init()) 61 goto err; 62 63 rand_inited = 1; 64 return 1; 65 66 err: 67 # ifndef OPENSSL_NO_DEPRECATED_3_0 68 CRYPTO_THREAD_lock_free(rand_meth_lock); 69 rand_meth_lock = NULL; 70 # endif 71 # ifndef OPENSSL_NO_ENGINE 72 CRYPTO_THREAD_lock_free(rand_engine_lock); 73 rand_engine_lock = NULL; 74 # endif 75 return 0; 76 } 77 78 void ossl_rand_cleanup_int(void) 79 { 80 # ifndef OPENSSL_NO_DEPRECATED_3_0 81 const RAND_METHOD *meth = default_RAND_meth; 82 83 if (!rand_inited) 84 return; 85 86 if (meth != NULL && meth->cleanup != NULL) 87 meth->cleanup(); 88 RAND_set_rand_method(NULL); 89 # endif 90 ossl_rand_pool_cleanup(); 91 # ifndef OPENSSL_NO_ENGINE 92 CRYPTO_THREAD_lock_free(rand_engine_lock); 93 rand_engine_lock = NULL; 94 # endif 95 # ifndef OPENSSL_NO_DEPRECATED_3_0 96 CRYPTO_THREAD_lock_free(rand_meth_lock); 97 rand_meth_lock = NULL; 98 # endif 99 ossl_release_default_drbg_ctx(); 100 rand_inited = 0; 101 } 102 103 /* 104 * RAND_close_seed_files() ensures that any seed file descriptors are 105 * closed after use. This only applies to libcrypto/default provider, 106 * it does not apply to other providers. 107 */ 108 void RAND_keep_random_devices_open(int keep) 109 { 110 if (RUN_ONCE(&rand_init, do_rand_init)) 111 ossl_rand_pool_keep_random_devices_open(keep); 112 } 113 114 /* 115 * RAND_poll() reseeds the default RNG using random input 116 * 117 * The random input is obtained from polling various entropy 118 * sources which depend on the operating system and are 119 * configurable via the --with-rand-seed configure option. 120 */ 121 int RAND_poll(void) 122 { 123 static const char salt[] = "polling"; 124 125 # ifndef OPENSSL_NO_DEPRECATED_3_0 126 const RAND_METHOD *meth = RAND_get_rand_method(); 127 int ret = meth == RAND_OpenSSL(); 128 129 if (meth == NULL) 130 return 0; 131 132 if (!ret) { 133 /* fill random pool and seed the current legacy RNG */ 134 RAND_POOL *pool = ossl_rand_pool_new(RAND_DRBG_STRENGTH, 1, 135 (RAND_DRBG_STRENGTH + 7) / 8, 136 RAND_POOL_MAX_LENGTH); 137 138 if (pool == NULL) 139 return 0; 140 141 if (ossl_pool_acquire_entropy(pool) == 0) 142 goto err; 143 144 if (meth->add == NULL 145 || meth->add(ossl_rand_pool_buffer(pool), 146 ossl_rand_pool_length(pool), 147 (ossl_rand_pool_entropy(pool) / 8.0)) == 0) 148 goto err; 149 150 ret = 1; 151 err: 152 ossl_rand_pool_free(pool); 153 return ret; 154 } 155 # endif 156 157 RAND_seed(salt, sizeof(salt)); 158 return 1; 159 } 160 161 # ifndef OPENSSL_NO_DEPRECATED_3_0 162 static int rand_set_rand_method_internal(const RAND_METHOD *meth, 163 ossl_unused ENGINE *e) 164 { 165 if (!RUN_ONCE(&rand_init, do_rand_init)) 166 return 0; 167 168 if (!CRYPTO_THREAD_write_lock(rand_meth_lock)) 169 return 0; 170 # ifndef OPENSSL_NO_ENGINE 171 ENGINE_finish(funct_ref); 172 funct_ref = e; 173 # endif 174 default_RAND_meth = meth; 175 CRYPTO_THREAD_unlock(rand_meth_lock); 176 return 1; 177 } 178 179 int RAND_set_rand_method(const RAND_METHOD *meth) 180 { 181 return rand_set_rand_method_internal(meth, NULL); 182 } 183 184 const RAND_METHOD *RAND_get_rand_method(void) 185 { 186 const RAND_METHOD *tmp_meth = NULL; 187 188 if (!RUN_ONCE(&rand_init, do_rand_init)) 189 return NULL; 190 191 if (!CRYPTO_THREAD_write_lock(rand_meth_lock)) 192 return NULL; 193 if (default_RAND_meth == NULL) { 194 # ifndef OPENSSL_NO_ENGINE 195 ENGINE *e; 196 197 /* If we have an engine that can do RAND, use it. */ 198 if ((e = ENGINE_get_default_RAND()) != NULL 199 && (tmp_meth = ENGINE_get_RAND(e)) != NULL) { 200 funct_ref = e; 201 default_RAND_meth = tmp_meth; 202 } else { 203 ENGINE_finish(e); 204 default_RAND_meth = &ossl_rand_meth; 205 } 206 # else 207 default_RAND_meth = &ossl_rand_meth; 208 # endif 209 } 210 tmp_meth = default_RAND_meth; 211 CRYPTO_THREAD_unlock(rand_meth_lock); 212 return tmp_meth; 213 } 214 215 # if !defined(OPENSSL_NO_ENGINE) 216 int RAND_set_rand_engine(ENGINE *engine) 217 { 218 const RAND_METHOD *tmp_meth = NULL; 219 220 if (!RUN_ONCE(&rand_init, do_rand_init)) 221 return 0; 222 223 if (engine != NULL) { 224 if (!ENGINE_init(engine)) 225 return 0; 226 tmp_meth = ENGINE_get_RAND(engine); 227 if (tmp_meth == NULL) { 228 ENGINE_finish(engine); 229 return 0; 230 } 231 } 232 if (!CRYPTO_THREAD_write_lock(rand_engine_lock)) { 233 ENGINE_finish(engine); 234 return 0; 235 } 236 237 /* This function releases any prior ENGINE so call it first */ 238 rand_set_rand_method_internal(tmp_meth, engine); 239 CRYPTO_THREAD_unlock(rand_engine_lock); 240 return 1; 241 } 242 # endif 243 # endif /* OPENSSL_NO_DEPRECATED_3_0 */ 244 245 void RAND_seed(const void *buf, int num) 246 { 247 EVP_RAND_CTX *drbg; 248 # ifndef OPENSSL_NO_DEPRECATED_3_0 249 const RAND_METHOD *meth = RAND_get_rand_method(); 250 251 if (meth != NULL && meth->seed != NULL) { 252 meth->seed(buf, num); 253 return; 254 } 255 # endif 256 257 drbg = RAND_get0_primary(NULL); 258 if (drbg != NULL && num > 0) 259 EVP_RAND_reseed(drbg, 0, NULL, 0, buf, num); 260 } 261 262 void RAND_add(const void *buf, int num, double randomness) 263 { 264 EVP_RAND_CTX *drbg; 265 # ifndef OPENSSL_NO_DEPRECATED_3_0 266 const RAND_METHOD *meth = RAND_get_rand_method(); 267 268 if (meth != NULL && meth->add != NULL) { 269 meth->add(buf, num, randomness); 270 return; 271 } 272 # endif 273 drbg = RAND_get0_primary(NULL); 274 if (drbg != NULL && num > 0) 275 # ifdef OPENSSL_RAND_SEED_NONE 276 /* Without an entropy source, we have to rely on the user */ 277 EVP_RAND_reseed(drbg, 0, buf, num, NULL, 0); 278 # else 279 /* With an entropy source, we downgrade this to additional input */ 280 EVP_RAND_reseed(drbg, 0, NULL, 0, buf, num); 281 # endif 282 } 283 284 # if !defined(OPENSSL_NO_DEPRECATED_1_1_0) 285 int RAND_pseudo_bytes(unsigned char *buf, int num) 286 { 287 const RAND_METHOD *meth = RAND_get_rand_method(); 288 289 if (meth != NULL && meth->pseudorand != NULL) 290 return meth->pseudorand(buf, num); 291 ERR_raise(ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED); 292 return -1; 293 } 294 # endif 295 296 int RAND_status(void) 297 { 298 EVP_RAND_CTX *rand; 299 # ifndef OPENSSL_NO_DEPRECATED_3_0 300 const RAND_METHOD *meth = RAND_get_rand_method(); 301 302 if (meth != NULL && meth != RAND_OpenSSL()) 303 return meth->status != NULL ? meth->status() : 0; 304 # endif 305 306 if ((rand = RAND_get0_primary(NULL)) == NULL) 307 return 0; 308 return EVP_RAND_get_state(rand) == EVP_RAND_STATE_READY; 309 } 310 # else /* !FIPS_MODULE */ 311 312 # ifndef OPENSSL_NO_DEPRECATED_3_0 313 const RAND_METHOD *RAND_get_rand_method(void) 314 { 315 return NULL; 316 } 317 # endif 318 #endif /* !FIPS_MODULE */ 319 320 /* 321 * This function is not part of RAND_METHOD, so if we're not using 322 * the default method, then just call RAND_bytes(). Otherwise make 323 * sure we're instantiated and use the private DRBG. 324 */ 325 int RAND_priv_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num, 326 unsigned int strength) 327 { 328 EVP_RAND_CTX *rand; 329 #if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE) 330 const RAND_METHOD *meth = RAND_get_rand_method(); 331 332 if (meth != NULL && meth != RAND_OpenSSL()) { 333 if (meth->bytes != NULL) 334 return meth->bytes(buf, num); 335 ERR_raise(ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED); 336 return -1; 337 } 338 #endif 339 340 rand = RAND_get0_private(ctx); 341 if (rand != NULL) 342 return EVP_RAND_generate(rand, buf, num, strength, 0, NULL, 0); 343 344 return 0; 345 } 346 347 int RAND_priv_bytes(unsigned char *buf, int num) 348 { 349 if (num < 0) 350 return 0; 351 return RAND_priv_bytes_ex(NULL, buf, (size_t)num, 0); 352 } 353 354 int RAND_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num, 355 unsigned int strength) 356 { 357 EVP_RAND_CTX *rand; 358 #if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE) 359 const RAND_METHOD *meth = RAND_get_rand_method(); 360 361 if (meth != NULL && meth != RAND_OpenSSL()) { 362 if (meth->bytes != NULL) 363 return meth->bytes(buf, num); 364 ERR_raise(ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED); 365 return -1; 366 } 367 #endif 368 369 rand = RAND_get0_public(ctx); 370 if (rand != NULL) 371 return EVP_RAND_generate(rand, buf, num, strength, 0, NULL, 0); 372 373 return 0; 374 } 375 376 int RAND_bytes(unsigned char *buf, int num) 377 { 378 if (num < 0) 379 return 0; 380 return RAND_bytes_ex(NULL, buf, (size_t)num, 0); 381 } 382 383 typedef struct rand_global_st { 384 /* 385 * The three shared DRBG instances 386 * 387 * There are three shared DRBG instances: <primary>, <public>, and 388 * <private>. The <public> and <private> DRBGs are secondary ones. 389 * These are used for non-secret (e.g. nonces) and secret 390 * (e.g. private keys) data respectively. 391 */ 392 CRYPTO_RWLOCK *lock; 393 394 EVP_RAND_CTX *seed; 395 396 /* 397 * The <primary> DRBG 398 * 399 * Not used directly by the application, only for reseeding the two other 400 * DRBGs. It reseeds itself by pulling either randomness from os entropy 401 * sources or by consuming randomness which was added by RAND_add(). 402 * 403 * The <primary> DRBG is a global instance which is accessed concurrently by 404 * all threads. The necessary locking is managed automatically by its child 405 * DRBG instances during reseeding. 406 */ 407 EVP_RAND_CTX *primary; 408 409 /* 410 * The <public> DRBG 411 * 412 * Used by default for generating random bytes using RAND_bytes(). 413 * 414 * The <public> secondary DRBG is thread-local, i.e., there is one instance 415 * per thread. 416 */ 417 CRYPTO_THREAD_LOCAL public; 418 419 /* 420 * The <private> DRBG 421 * 422 * Used by default for generating private keys using RAND_priv_bytes() 423 * 424 * The <private> secondary DRBG is thread-local, i.e., there is one 425 * instance per thread. 426 */ 427 CRYPTO_THREAD_LOCAL private; 428 429 /* Which RNG is being used by default and it's configuration settings */ 430 char *rng_name; 431 char *rng_cipher; 432 char *rng_digest; 433 char *rng_propq; 434 435 /* Allow the randomness source to be changed */ 436 char *seed_name; 437 char *seed_propq; 438 } RAND_GLOBAL; 439 440 /* 441 * Initialize the OSSL_LIB_CTX global DRBGs on first use. 442 * Returns the allocated global data on success or NULL on failure. 443 */ 444 static void *rand_ossl_ctx_new(OSSL_LIB_CTX *libctx) 445 { 446 RAND_GLOBAL *dgbl = OPENSSL_zalloc(sizeof(*dgbl)); 447 448 if (dgbl == NULL) 449 return NULL; 450 451 #ifndef FIPS_MODULE 452 /* 453 * We need to ensure that base libcrypto thread handling has been 454 * initialised. 455 */ 456 OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL); 457 #endif 458 459 dgbl->lock = CRYPTO_THREAD_lock_new(); 460 if (dgbl->lock == NULL) 461 goto err1; 462 463 if (!CRYPTO_THREAD_init_local(&dgbl->private, NULL)) 464 goto err1; 465 466 if (!CRYPTO_THREAD_init_local(&dgbl->public, NULL)) 467 goto err2; 468 469 return dgbl; 470 471 err2: 472 CRYPTO_THREAD_cleanup_local(&dgbl->private); 473 err1: 474 CRYPTO_THREAD_lock_free(dgbl->lock); 475 OPENSSL_free(dgbl); 476 return NULL; 477 } 478 479 void ossl_rand_ctx_free(void *vdgbl) 480 { 481 RAND_GLOBAL *dgbl = vdgbl; 482 483 if (dgbl == NULL) 484 return; 485 486 CRYPTO_THREAD_lock_free(dgbl->lock); 487 CRYPTO_THREAD_cleanup_local(&dgbl->private); 488 CRYPTO_THREAD_cleanup_local(&dgbl->public); 489 EVP_RAND_CTX_free(dgbl->primary); 490 EVP_RAND_CTX_free(dgbl->seed); 491 OPENSSL_free(dgbl->rng_name); 492 OPENSSL_free(dgbl->rng_cipher); 493 OPENSSL_free(dgbl->rng_digest); 494 OPENSSL_free(dgbl->rng_propq); 495 OPENSSL_free(dgbl->seed_name); 496 OPENSSL_free(dgbl->seed_propq); 497 498 OPENSSL_free(dgbl); 499 } 500 501 static const OSSL_LIB_CTX_METHOD rand_drbg_ossl_ctx_method = { 502 OSSL_LIB_CTX_METHOD_PRIORITY_2, 503 rand_ossl_ctx_new, 504 ossl_rand_ctx_free, 505 }; 506 507 static RAND_GLOBAL *rand_get_global(OSSL_LIB_CTX *libctx) 508 { 509 return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DRBG_INDEX, 510 &rand_drbg_ossl_ctx_method); 511 } 512 513 static void rand_delete_thread_state(void *arg) 514 { 515 OSSL_LIB_CTX *ctx = arg; 516 RAND_GLOBAL *dgbl = rand_get_global(ctx); 517 EVP_RAND_CTX *rand; 518 519 if (dgbl == NULL) 520 return; 521 522 rand = CRYPTO_THREAD_get_local(&dgbl->public); 523 CRYPTO_THREAD_set_local(&dgbl->public, NULL); 524 EVP_RAND_CTX_free(rand); 525 526 rand = CRYPTO_THREAD_get_local(&dgbl->private); 527 CRYPTO_THREAD_set_local(&dgbl->private, NULL); 528 EVP_RAND_CTX_free(rand); 529 } 530 531 #ifndef FIPS_MODULE 532 static EVP_RAND_CTX *rand_new_seed(OSSL_LIB_CTX *libctx) 533 { 534 EVP_RAND *rand; 535 RAND_GLOBAL *dgbl = rand_get_global(libctx); 536 EVP_RAND_CTX *ctx; 537 char *name; 538 539 if (dgbl == NULL) 540 return NULL; 541 name = dgbl->seed_name != NULL ? dgbl->seed_name : "SEED-SRC"; 542 rand = EVP_RAND_fetch(libctx, name, dgbl->seed_propq); 543 if (rand == NULL) { 544 ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG); 545 return NULL; 546 } 547 ctx = EVP_RAND_CTX_new(rand, NULL); 548 EVP_RAND_free(rand); 549 if (ctx == NULL) { 550 ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG); 551 return NULL; 552 } 553 if (!EVP_RAND_instantiate(ctx, 0, 0, NULL, 0, NULL)) { 554 ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG); 555 EVP_RAND_CTX_free(ctx); 556 return NULL; 557 } 558 return ctx; 559 } 560 #endif 561 562 static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent, 563 unsigned int reseed_interval, 564 time_t reseed_time_interval) 565 { 566 EVP_RAND *rand; 567 RAND_GLOBAL *dgbl = rand_get_global(libctx); 568 EVP_RAND_CTX *ctx; 569 OSSL_PARAM params[7], *p = params; 570 char *name, *cipher; 571 572 if (dgbl == NULL) 573 return NULL; 574 name = dgbl->rng_name != NULL ? dgbl->rng_name : "CTR-DRBG"; 575 rand = EVP_RAND_fetch(libctx, name, dgbl->rng_propq); 576 if (rand == NULL) { 577 ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG); 578 return NULL; 579 } 580 ctx = EVP_RAND_CTX_new(rand, parent); 581 EVP_RAND_free(rand); 582 if (ctx == NULL) { 583 ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG); 584 return NULL; 585 } 586 587 /* 588 * Rather than trying to decode the DRBG settings, just pass them through 589 * and rely on the other end to ignore those it doesn't care about. 590 */ 591 cipher = dgbl->rng_cipher != NULL ? dgbl->rng_cipher : "AES-256-CTR"; 592 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER, 593 cipher, 0); 594 if (dgbl->rng_digest != NULL) 595 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST, 596 dgbl->rng_digest, 0); 597 if (dgbl->rng_propq != NULL) 598 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, 599 dgbl->rng_propq, 0); 600 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_MAC, "HMAC", 0); 601 *p++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS, 602 &reseed_interval); 603 *p++ = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL, 604 &reseed_time_interval); 605 *p = OSSL_PARAM_construct_end(); 606 if (!EVP_RAND_instantiate(ctx, 0, 0, NULL, 0, params)) { 607 ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG); 608 EVP_RAND_CTX_free(ctx); 609 return NULL; 610 } 611 return ctx; 612 } 613 614 /* 615 * Get the primary random generator. 616 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure. 617 * 618 */ 619 EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx) 620 { 621 RAND_GLOBAL *dgbl = rand_get_global(ctx); 622 EVP_RAND_CTX *ret; 623 624 if (dgbl == NULL) 625 return NULL; 626 627 if (!CRYPTO_THREAD_read_lock(dgbl->lock)) 628 return NULL; 629 630 ret = dgbl->primary; 631 CRYPTO_THREAD_unlock(dgbl->lock); 632 633 if (ret != NULL) 634 return ret; 635 636 if (!CRYPTO_THREAD_write_lock(dgbl->lock)) 637 return NULL; 638 639 ret = dgbl->primary; 640 if (ret != NULL) { 641 CRYPTO_THREAD_unlock(dgbl->lock); 642 return ret; 643 } 644 645 #ifndef FIPS_MODULE 646 if (dgbl->seed == NULL) { 647 ERR_set_mark(); 648 dgbl->seed = rand_new_seed(ctx); 649 ERR_pop_to_mark(); 650 } 651 #endif 652 653 ret = dgbl->primary = rand_new_drbg(ctx, dgbl->seed, 654 PRIMARY_RESEED_INTERVAL, 655 PRIMARY_RESEED_TIME_INTERVAL); 656 /* 657 * The primary DRBG may be shared between multiple threads so we must 658 * enable locking. 659 */ 660 if (ret != NULL && !EVP_RAND_enable_locking(ret)) { 661 ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_LOCKING); 662 EVP_RAND_CTX_free(ret); 663 ret = dgbl->primary = NULL; 664 } 665 CRYPTO_THREAD_unlock(dgbl->lock); 666 667 return ret; 668 } 669 670 /* 671 * Get the public random generator. 672 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure. 673 */ 674 EVP_RAND_CTX *RAND_get0_public(OSSL_LIB_CTX *ctx) 675 { 676 RAND_GLOBAL *dgbl = rand_get_global(ctx); 677 EVP_RAND_CTX *rand, *primary; 678 679 if (dgbl == NULL) 680 return NULL; 681 682 rand = CRYPTO_THREAD_get_local(&dgbl->public); 683 if (rand == NULL) { 684 primary = RAND_get0_primary(ctx); 685 if (primary == NULL) 686 return NULL; 687 688 ctx = ossl_lib_ctx_get_concrete(ctx); 689 /* 690 * If the private is also NULL then this is the first time we've 691 * used this thread. 692 */ 693 if (CRYPTO_THREAD_get_local(&dgbl->private) == NULL 694 && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state)) 695 return NULL; 696 rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL, 697 SECONDARY_RESEED_TIME_INTERVAL); 698 CRYPTO_THREAD_set_local(&dgbl->public, rand); 699 } 700 return rand; 701 } 702 703 /* 704 * Get the private random generator. 705 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure. 706 */ 707 EVP_RAND_CTX *RAND_get0_private(OSSL_LIB_CTX *ctx) 708 { 709 RAND_GLOBAL *dgbl = rand_get_global(ctx); 710 EVP_RAND_CTX *rand, *primary; 711 712 if (dgbl == NULL) 713 return NULL; 714 715 rand = CRYPTO_THREAD_get_local(&dgbl->private); 716 if (rand == NULL) { 717 primary = RAND_get0_primary(ctx); 718 if (primary == NULL) 719 return NULL; 720 721 ctx = ossl_lib_ctx_get_concrete(ctx); 722 /* 723 * If the public is also NULL then this is the first time we've 724 * used this thread. 725 */ 726 if (CRYPTO_THREAD_get_local(&dgbl->public) == NULL 727 && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state)) 728 return NULL; 729 rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL, 730 SECONDARY_RESEED_TIME_INTERVAL); 731 CRYPTO_THREAD_set_local(&dgbl->private, rand); 732 } 733 return rand; 734 } 735 736 #ifndef FIPS_MODULE 737 static int random_set_string(char **p, const char *s) 738 { 739 char *d = NULL; 740 741 if (s != NULL) { 742 d = OPENSSL_strdup(s); 743 if (d == NULL) { 744 ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 745 return 0; 746 } 747 } 748 OPENSSL_free(*p); 749 *p = d; 750 return 1; 751 } 752 753 /* 754 * Load the DRBG definitions from a configuration file. 755 */ 756 static int random_conf_init(CONF_IMODULE *md, const CONF *cnf) 757 { 758 STACK_OF(CONF_VALUE) *elist; 759 CONF_VALUE *cval; 760 RAND_GLOBAL *dgbl = rand_get_global(NCONF_get0_libctx((CONF *)cnf)); 761 int i, r = 1; 762 763 OSSL_TRACE1(CONF, "Loading random module: section %s\n", 764 CONF_imodule_get_value(md)); 765 766 /* Value is a section containing RANDOM configuration */ 767 elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); 768 if (elist == NULL) { 769 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_RANDOM_SECTION_ERROR); 770 return 0; 771 } 772 773 if (dgbl == NULL) 774 return 0; 775 776 for (i = 0; i < sk_CONF_VALUE_num(elist); i++) { 777 cval = sk_CONF_VALUE_value(elist, i); 778 if (OPENSSL_strcasecmp(cval->name, "random") == 0) { 779 if (!random_set_string(&dgbl->rng_name, cval->value)) 780 return 0; 781 } else if (OPENSSL_strcasecmp(cval->name, "cipher") == 0) { 782 if (!random_set_string(&dgbl->rng_cipher, cval->value)) 783 return 0; 784 } else if (OPENSSL_strcasecmp(cval->name, "digest") == 0) { 785 if (!random_set_string(&dgbl->rng_digest, cval->value)) 786 return 0; 787 } else if (OPENSSL_strcasecmp(cval->name, "properties") == 0) { 788 if (!random_set_string(&dgbl->rng_propq, cval->value)) 789 return 0; 790 } else if (OPENSSL_strcasecmp(cval->name, "seed") == 0) { 791 if (!random_set_string(&dgbl->seed_name, cval->value)) 792 return 0; 793 } else if (OPENSSL_strcasecmp(cval->name, "seed_properties") == 0) { 794 if (!random_set_string(&dgbl->seed_propq, cval->value)) 795 return 0; 796 } else { 797 ERR_raise_data(ERR_LIB_CRYPTO, 798 CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION, 799 "name=%s, value=%s", cval->name, cval->value); 800 r = 0; 801 } 802 } 803 return r; 804 } 805 806 807 static void random_conf_deinit(CONF_IMODULE *md) 808 { 809 OSSL_TRACE(CONF, "Cleaned up random\n"); 810 } 811 812 void ossl_random_add_conf_module(void) 813 { 814 OSSL_TRACE(CONF, "Adding config module 'random'\n"); 815 CONF_module_add("random", random_conf_init, random_conf_deinit); 816 } 817 818 int RAND_set_DRBG_type(OSSL_LIB_CTX *ctx, const char *drbg, const char *propq, 819 const char *cipher, const char *digest) 820 { 821 RAND_GLOBAL *dgbl = rand_get_global(ctx); 822 823 if (dgbl == NULL) 824 return 0; 825 if (dgbl->primary != NULL) { 826 ERR_raise(ERR_LIB_CRYPTO, RAND_R_ALREADY_INSTANTIATED); 827 return 0; 828 } 829 return random_set_string(&dgbl->rng_name, drbg) 830 && random_set_string(&dgbl->rng_propq, propq) 831 && random_set_string(&dgbl->rng_cipher, cipher) 832 && random_set_string(&dgbl->rng_digest, digest); 833 } 834 835 int RAND_set_seed_source_type(OSSL_LIB_CTX *ctx, const char *seed, 836 const char *propq) 837 { 838 RAND_GLOBAL *dgbl = rand_get_global(ctx); 839 840 if (dgbl == NULL) 841 return 0; 842 if (dgbl->primary != NULL) { 843 ERR_raise(ERR_LIB_CRYPTO, RAND_R_ALREADY_INSTANTIATED); 844 return 0; 845 } 846 return random_set_string(&dgbl->seed_name, seed) 847 && random_set_string(&dgbl->seed_propq, propq); 848 } 849 850 #endif 851