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 */ 35static ENGINE *funct_ref; 36static CRYPTO_RWLOCK *rand_engine_lock; 37# endif 38# ifndef OPENSSL_NO_DEPRECATED_3_0 39static CRYPTO_RWLOCK *rand_meth_lock; 40static const RAND_METHOD *default_RAND_meth; 41# endif 42static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT; 43 44static int rand_inited = 0; 45 46DEFINE_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 78void 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 */ 108void 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 */ 121int RAND_poll(void) 122{ 123# ifndef OPENSSL_NO_DEPRECATED_3_0 124 const RAND_METHOD *meth = RAND_get_rand_method(); 125 int ret = meth == RAND_OpenSSL(); 126 127 if (meth == NULL) 128 return 0; 129 130 if (!ret) { 131 /* fill random pool and seed the current legacy RNG */ 132 RAND_POOL *pool = ossl_rand_pool_new(RAND_DRBG_STRENGTH, 1, 133 (RAND_DRBG_STRENGTH + 7) / 8, 134 RAND_POOL_MAX_LENGTH); 135 136 if (pool == NULL) 137 return 0; 138 139 if (ossl_pool_acquire_entropy(pool) == 0) 140 goto err; 141 142 if (meth->add == NULL 143 || meth->add(ossl_rand_pool_buffer(pool), 144 ossl_rand_pool_length(pool), 145 (ossl_rand_pool_entropy(pool) / 8.0)) == 0) 146 goto err; 147 148 ret = 1; 149 err: 150 ossl_rand_pool_free(pool); 151 } 152 return ret; 153# else 154 static const char salt[] = "polling"; 155 156 RAND_seed(salt, sizeof(salt)); 157 return 1; 158# endif 159} 160 161# ifndef OPENSSL_NO_DEPRECATED_3_0 162static 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 179int RAND_set_rand_method(const RAND_METHOD *meth) 180{ 181 return rand_set_rand_method_internal(meth, NULL); 182} 183 184const 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) 216int 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 245void 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 262void 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) 285int 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 296int 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 313const 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 */ 325int 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 347int 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 354int 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 376int 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 383typedef 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 */ 444static 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 479void 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 501static 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 507static 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 513static 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 532static 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 562static 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 */ 619EVP_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 */ 674EVP_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 */ 707EVP_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 737static 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 */ 756static 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 807static void random_conf_deinit(CONF_IMODULE *md) 808{ 809 OSSL_TRACE(CONF, "Cleaned up random\n"); 810} 811 812void 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 818int 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 835int 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