2 * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
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
10 /* We need to use some engine deprecated APIs */
11 #define OPENSSL_SUPPRESS_DEPRECATED
13 #include <openssl/err.h>
14 #include <openssl/opensslconf.h>
15 #include <openssl/core_names.h>
16 #include <openssl/provider.h>
17 #include "internal/cryptlib.h"
18 #include "internal/provider.h"
19 #include "internal/thread_once.h"
20 #include "internal/threads_common.h"
21 #include "crypto/rand.h"
22 #include "crypto/cryptlib.h"
23 #include "rand_local.h"
24 #include "crypto/context.h"
25 #include "internal/provider.h"
27 #ifndef OPENSSL_DEFAULT_SEED_SRC
28 # define OPENSSL_DEFAULT_SEED_SRC SEED-SRC
31 typedef struct rand_global_st
{
33 * The three shared DRBG instances
35 * There are three shared DRBG instances: <primary>, <public>, and
36 * <private>. The <public> and <private> DRBGs are secondary ones.
37 * These are used for non-secret (e.g. nonces) and secret
38 * (e.g. private keys) data respectively.
47 * Not used directly by the application, only for reseeding the two other
48 * DRBGs. It reseeds itself by pulling either randomness from os entropy
49 * sources or by consuming randomness which was added by RAND_add().
51 * The <primary> DRBG is a global instance which is accessed concurrently by
52 * all threads. The necessary locking is managed automatically by its child
53 * DRBG instances during reseeding.
55 EVP_RAND_CTX
*primary
;
58 * The provider which we'll use to generate randomness.
61 OSSL_PROVIDER
*random_provider
;
62 char *random_provider_name
;
63 #endif /* !FIPS_MODULE */
65 /* Which RNG is being used by default and it's configuration settings */
71 /* Allow the randomness source to be changed */
76 static EVP_RAND_CTX
*rand_get0_primary(OSSL_LIB_CTX
*ctx
, RAND_GLOBAL
*dgbl
);
77 static EVP_RAND_CTX
*rand_get0_public(OSSL_LIB_CTX
*ctx
, RAND_GLOBAL
*dgbl
);
78 static EVP_RAND_CTX
*rand_get0_private(OSSL_LIB_CTX
*ctx
, RAND_GLOBAL
*dgbl
);
80 static RAND_GLOBAL
*rand_get_global(OSSL_LIB_CTX
*libctx
)
82 return ossl_lib_ctx_get_data(libctx
, OSSL_LIB_CTX_DRBG_INDEX
);
89 # include <openssl/conf.h>
90 # include <openssl/trace.h>
91 # include <openssl/engine.h>
92 # include "crypto/rand_pool.h"
93 # include "prov/seeding.h"
94 # include "internal/e_os.h"
95 # include "internal/property.h"
98 * The default name for the random provider.
99 * This ensures that the FIPS provider will supply libcrypto's random byte
102 static const char random_provider_fips_name
[] = "fips";
104 static int set_random_provider_name(RAND_GLOBAL
*dgbl
, const char *name
)
106 if (dgbl
->random_provider_name
!= NULL
107 && OPENSSL_strcasecmp(dgbl
->random_provider_name
, name
) == 0)
110 OPENSSL_free(dgbl
->random_provider_name
);
111 dgbl
->random_provider_name
= OPENSSL_strdup(name
);
112 return dgbl
->random_provider_name
!= NULL
;
115 # ifndef OPENSSL_NO_ENGINE
116 /* non-NULL if default_RAND_meth is ENGINE-provided */
117 static ENGINE
*funct_ref
;
118 static CRYPTO_RWLOCK
*rand_engine_lock
;
119 # endif /* !OPENSSL_NO_ENGINE */
120 # ifndef OPENSSL_NO_DEPRECATED_3_0
121 static CRYPTO_RWLOCK
*rand_meth_lock
;
122 static const RAND_METHOD
*default_RAND_meth
;
123 # endif /* !OPENSSL_NO_DEPRECATED_3_0 */
124 static CRYPTO_ONCE rand_init
= CRYPTO_ONCE_STATIC_INIT
;
126 static int rand_inited
= 0;
128 DEFINE_RUN_ONCE_STATIC(do_rand_init
)
130 # ifndef OPENSSL_NO_ENGINE
131 rand_engine_lock
= CRYPTO_THREAD_lock_new();
132 if (rand_engine_lock
== NULL
)
134 # endif /* !OPENSSL_NO_ENGINE */
136 # ifndef OPENSSL_NO_DEPRECATED_3_0
137 rand_meth_lock
= CRYPTO_THREAD_lock_new();
138 if (rand_meth_lock
== NULL
)
140 # endif /* !OPENSSL_NO_DEPRECATED_3_0 */
142 if (!ossl_rand_pool_init())
149 # ifndef OPENSSL_NO_DEPRECATED_3_0
150 CRYPTO_THREAD_lock_free(rand_meth_lock
);
151 rand_meth_lock
= NULL
;
152 # endif /* !OPENSSL_NO_DEPRECATED_3_0 */
153 # ifndef OPENSSL_NO_ENGINE
154 CRYPTO_THREAD_lock_free(rand_engine_lock
);
155 rand_engine_lock
= NULL
;
156 # endif /* !OPENSSL_NO_ENGINE */
160 void ossl_rand_cleanup_int(void)
162 # ifndef OPENSSL_NO_DEPRECATED_3_0
163 const RAND_METHOD
*meth
= default_RAND_meth
;
168 if (meth
!= NULL
&& meth
->cleanup
!= NULL
)
170 RAND_set_rand_method(NULL
);
171 # endif /* !OPENSSL_NO_DEPRECATED_3_0 */
172 ossl_rand_pool_cleanup();
173 # ifndef OPENSSL_NO_ENGINE
174 CRYPTO_THREAD_lock_free(rand_engine_lock
);
175 rand_engine_lock
= NULL
;
176 # endif /* !OPENSSL_NO_ENGINE */
177 # ifndef OPENSSL_NO_DEPRECATED_3_0
178 CRYPTO_THREAD_lock_free(rand_meth_lock
);
179 rand_meth_lock
= NULL
;
180 # endif /* !OPENSSL_NO_DEPRECATED_3_0 */
181 ossl_release_default_drbg_ctx();
186 * RAND_close_seed_files() ensures that any seed file descriptors are
187 * closed after use. This only applies to libcrypto/default provider,
188 * it does not apply to other providers.
190 void RAND_keep_random_devices_open(int keep
)
192 if (RUN_ONCE(&rand_init
, do_rand_init
))
193 ossl_rand_pool_keep_random_devices_open(keep
);
197 * RAND_poll() reseeds the default RNG using random input
199 * The random input is obtained from polling various entropy
200 * sources which depend on the operating system and are
201 * configurable via the --with-rand-seed configure option.
205 static const char salt
[] = "polling";
207 # ifndef OPENSSL_NO_DEPRECATED_3_0
208 const RAND_METHOD
*meth
= RAND_get_rand_method();
209 int ret
= meth
== RAND_OpenSSL();
215 /* fill random pool and seed the current legacy RNG */
216 RAND_POOL
*pool
= ossl_rand_pool_new(RAND_DRBG_STRENGTH
, 1,
217 (RAND_DRBG_STRENGTH
+ 7) / 8,
218 RAND_POOL_MAX_LENGTH
);
223 if (ossl_pool_acquire_entropy(pool
) == 0)
226 if (meth
->add
== NULL
227 || meth
->add(ossl_rand_pool_buffer(pool
),
228 (int)ossl_rand_pool_length(pool
),
229 (ossl_rand_pool_entropy(pool
) / 8.0)) == 0)
234 ossl_rand_pool_free(pool
);
237 # endif /* !OPENSSL_NO_DEPRECATED_3_0 */
239 RAND_seed(salt
, sizeof(salt
));
243 # ifndef OPENSSL_NO_DEPRECATED_3_0
244 static int rand_set_rand_method_internal(const RAND_METHOD
*meth
,
245 ossl_unused ENGINE
*e
)
247 if (!RUN_ONCE(&rand_init
, do_rand_init
))
250 if (!CRYPTO_THREAD_write_lock(rand_meth_lock
))
252 # ifndef OPENSSL_NO_ENGINE
253 ENGINE_finish(funct_ref
);
256 default_RAND_meth
= meth
;
257 CRYPTO_THREAD_unlock(rand_meth_lock
);
261 int RAND_set_rand_method(const RAND_METHOD
*meth
)
263 return rand_set_rand_method_internal(meth
, NULL
);
266 const RAND_METHOD
*RAND_get_rand_method(void)
268 const RAND_METHOD
*tmp_meth
= NULL
;
270 if (!RUN_ONCE(&rand_init
, do_rand_init
))
273 if (rand_meth_lock
== NULL
)
276 if (!CRYPTO_THREAD_read_lock(rand_meth_lock
))
278 tmp_meth
= default_RAND_meth
;
279 CRYPTO_THREAD_unlock(rand_meth_lock
);
280 if (tmp_meth
!= NULL
)
283 if (!CRYPTO_THREAD_write_lock(rand_meth_lock
))
285 if (default_RAND_meth
== NULL
) {
286 # ifndef OPENSSL_NO_ENGINE
289 /* If we have an engine that can do RAND, use it. */
290 if ((e
= ENGINE_get_default_RAND()) != NULL
291 && (tmp_meth
= ENGINE_get_RAND(e
)) != NULL
) {
293 default_RAND_meth
= tmp_meth
;
296 default_RAND_meth
= &ossl_rand_meth
;
299 default_RAND_meth
= &ossl_rand_meth
;
302 tmp_meth
= default_RAND_meth
;
303 CRYPTO_THREAD_unlock(rand_meth_lock
);
307 # if !defined(OPENSSL_NO_ENGINE)
308 int RAND_set_rand_engine(ENGINE
*engine
)
310 const RAND_METHOD
*tmp_meth
= NULL
;
312 if (!RUN_ONCE(&rand_init
, do_rand_init
))
315 if (engine
!= NULL
) {
316 if (!ENGINE_init(engine
))
318 tmp_meth
= ENGINE_get_RAND(engine
);
319 if (tmp_meth
== NULL
) {
320 ENGINE_finish(engine
);
324 if (!CRYPTO_THREAD_write_lock(rand_engine_lock
)) {
325 ENGINE_finish(engine
);
329 /* This function releases any prior ENGINE so call it first */
330 rand_set_rand_method_internal(tmp_meth
, engine
);
331 CRYPTO_THREAD_unlock(rand_engine_lock
);
335 # endif /* OPENSSL_NO_DEPRECATED_3_0 */
337 void RAND_seed(const void *buf
, int num
)
340 # ifndef OPENSSL_NO_DEPRECATED_3_0
341 const RAND_METHOD
*meth
= RAND_get_rand_method();
343 if (meth
!= NULL
&& meth
->seed
!= NULL
) {
344 meth
->seed(buf
, num
);
349 drbg
= RAND_get0_primary(NULL
);
350 if (drbg
!= NULL
&& num
> 0)
351 EVP_RAND_reseed(drbg
, 0, NULL
, 0, buf
, num
);
354 void RAND_add(const void *buf
, int num
, double randomness
)
357 # ifndef OPENSSL_NO_DEPRECATED_3_0
358 const RAND_METHOD
*meth
= RAND_get_rand_method();
360 if (meth
!= NULL
&& meth
->add
!= NULL
) {
361 meth
->add(buf
, num
, randomness
);
365 drbg
= RAND_get0_primary(NULL
);
366 if (drbg
!= NULL
&& num
> 0)
367 # ifdef OPENSSL_RAND_SEED_NONE
368 /* Without an entropy source, we have to rely on the user */
369 EVP_RAND_reseed(drbg
, 0, buf
, num
, NULL
, 0);
371 /* With an entropy source, we downgrade this to additional input */
372 EVP_RAND_reseed(drbg
, 0, NULL
, 0, buf
, num
);
376 # if !defined(OPENSSL_NO_DEPRECATED_1_1_0)
377 int RAND_pseudo_bytes(unsigned char *buf
, int num
)
379 const RAND_METHOD
*meth
= RAND_get_rand_method();
381 if (meth
!= NULL
&& meth
->pseudorand
!= NULL
)
382 return meth
->pseudorand(buf
, num
);
383 ERR_raise(ERR_LIB_RAND
, RAND_R_FUNC_NOT_IMPLEMENTED
);
388 int RAND_status(void)
391 # ifndef OPENSSL_NO_DEPRECATED_3_0
392 const RAND_METHOD
*meth
= RAND_get_rand_method();
394 if (meth
!= NULL
&& meth
!= RAND_OpenSSL())
395 return meth
->status
!= NULL
? meth
->status() : 0;
398 if ((rand
= RAND_get0_primary(NULL
)) == NULL
)
400 return EVP_RAND_get_state(rand
) == EVP_RAND_STATE_READY
;
402 # else /* !FIPS_MODULE */
404 # ifndef OPENSSL_NO_DEPRECATED_3_0
405 const RAND_METHOD
*RAND_get_rand_method(void)
410 #endif /* !FIPS_MODULE */
413 * This function is not part of RAND_METHOD, so if we're not using
414 * the default method, then just call RAND_bytes(). Otherwise make
415 * sure we're instantiated and use the private DRBG.
417 int RAND_priv_bytes_ex(OSSL_LIB_CTX
*ctx
, unsigned char *buf
, size_t num
,
418 unsigned int strength
)
422 #if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE)
423 const RAND_METHOD
*meth
= RAND_get_rand_method();
425 if (meth
!= NULL
&& meth
!= RAND_OpenSSL()) {
427 ERR_raise(ERR_LIB_RAND
, RAND_R_ARGUMENT_OUT_OF_RANGE
);
430 if (meth
->bytes
!= NULL
)
431 return meth
->bytes(buf
, (int)num
);
432 ERR_raise(ERR_LIB_RAND
, RAND_R_FUNC_NOT_IMPLEMENTED
);
437 dgbl
= rand_get_global(ctx
);
441 if (dgbl
->random_provider
!= NULL
)
442 return ossl_provider_random_bytes(dgbl
->random_provider
,
443 OSSL_PROV_RANDOM_PRIVATE
,
445 #endif /* !FIPS_MODULE */
446 rand
= rand_get0_private(ctx
, dgbl
);
448 return EVP_RAND_generate(rand
, buf
, num
, strength
, 0, NULL
, 0);
453 int RAND_priv_bytes(unsigned char *buf
, int num
)
457 return RAND_priv_bytes_ex(NULL
, buf
, (size_t)num
, 0);
460 int RAND_bytes_ex(OSSL_LIB_CTX
*ctx
, unsigned char *buf
, size_t num
,
461 unsigned int strength
)
465 #if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE)
466 const RAND_METHOD
*meth
= RAND_get_rand_method();
468 if (meth
!= NULL
&& meth
!= RAND_OpenSSL()) {
470 ERR_raise(ERR_LIB_RAND
, RAND_R_ARGUMENT_OUT_OF_RANGE
);
473 if (meth
->bytes
!= NULL
)
474 return meth
->bytes(buf
, (int)num
);
475 ERR_raise(ERR_LIB_RAND
, RAND_R_FUNC_NOT_IMPLEMENTED
);
480 dgbl
= rand_get_global(ctx
);
484 if (dgbl
->random_provider
!= NULL
)
485 return ossl_provider_random_bytes(dgbl
->random_provider
,
486 OSSL_PROV_RANDOM_PUBLIC
,
488 #endif /* !FIPS_MODULE */
490 rand
= rand_get0_public(ctx
, dgbl
);
492 return EVP_RAND_generate(rand
, buf
, num
, strength
, 0, NULL
, 0);
497 int RAND_bytes(unsigned char *buf
, int num
)
501 return RAND_bytes_ex(NULL
, buf
, (size_t)num
, 0);
505 * Initialize the OSSL_LIB_CTX global DRBGs on first use.
506 * Returns the allocated global data on success or NULL on failure.
508 void *ossl_rand_ctx_new(OSSL_LIB_CTX
*libctx
)
510 RAND_GLOBAL
*dgbl
= OPENSSL_zalloc(sizeof(*dgbl
));
517 * We need to ensure that base libcrypto thread handling has been
520 OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY
, NULL
);
522 /* Prepopulate the random provider name */
523 dgbl
->random_provider_name
= OPENSSL_strdup(random_provider_fips_name
);
524 if (dgbl
->random_provider_name
== NULL
)
528 dgbl
->lock
= CRYPTO_THREAD_lock_new();
529 if (dgbl
->lock
== NULL
)
535 CRYPTO_THREAD_lock_free(dgbl
->lock
);
538 OPENSSL_free(dgbl
->random_provider_name
);
544 void ossl_rand_ctx_free(void *vdgbl
)
546 RAND_GLOBAL
*dgbl
= vdgbl
;
551 CRYPTO_THREAD_lock_free(dgbl
->lock
);
552 EVP_RAND_CTX_free(dgbl
->primary
);
553 EVP_RAND_CTX_free(dgbl
->seed
);
555 OPENSSL_free(dgbl
->random_provider_name
);
556 #endif /* !FIPS_MODULE */
557 OPENSSL_free(dgbl
->rng_name
);
558 OPENSSL_free(dgbl
->rng_cipher
);
559 OPENSSL_free(dgbl
->rng_digest
);
560 OPENSSL_free(dgbl
->rng_propq
);
561 OPENSSL_free(dgbl
->seed_name
);
562 OPENSSL_free(dgbl
->seed_propq
);
567 static void rand_delete_thread_state(void *arg
)
569 OSSL_LIB_CTX
*ctx
= arg
;
570 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
576 rand
= CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY
, ctx
);
577 CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY
, ctx
, NULL
);
578 EVP_RAND_CTX_free(rand
);
580 rand
= CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY
, ctx
);
581 CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY
, ctx
, NULL
);
582 EVP_RAND_CTX_free(rand
);
585 #if !defined(FIPS_MODULE) || !defined(OPENSSL_NO_FIPS_JITTER)
586 static EVP_RAND_CTX
*rand_new_seed(OSSL_LIB_CTX
*libctx
)
591 EVP_RAND_CTX
*ctx
= NULL
;
592 # ifdef OPENSSL_NO_FIPS_JITTER
593 RAND_GLOBAL
*dgbl
= rand_get_global(libctx
);
597 propq
= dgbl
->seed_propq
;
598 name
= dgbl
->seed_name
!= NULL
? dgbl
->seed_name
599 : OPENSSL_MSTR(OPENSSL_DEFAULT_SEED_SRC
);
600 # else /* !OPENSSL_NO_FIPS_JITTER */
603 # endif /* OPENSSL_NO_FIPS_JITTER */
605 rand
= EVP_RAND_fetch(libctx
, name
, propq
);
607 ERR_raise(ERR_LIB_RAND
, RAND_R_UNABLE_TO_FETCH_DRBG
);
610 ctx
= EVP_RAND_CTX_new(rand
, NULL
);
613 ERR_raise(ERR_LIB_RAND
, RAND_R_UNABLE_TO_CREATE_DRBG
);
616 if (!EVP_RAND_instantiate(ctx
, 0, 0, NULL
, 0, NULL
)) {
617 ERR_raise(ERR_LIB_RAND
, RAND_R_ERROR_INSTANTIATING_DRBG
);
622 EVP_RAND_CTX_free(ctx
);
625 #endif /* !FIPS_MODULE || !OPENSSL_NO_FIPS_JITTER */
628 EVP_RAND_CTX
*ossl_rand_get0_seed_noncreating(OSSL_LIB_CTX
*ctx
)
630 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
636 if (!CRYPTO_THREAD_read_lock(dgbl
->lock
))
639 CRYPTO_THREAD_unlock(dgbl
->lock
);
642 #endif /* !FIPS_MODULE */
644 static EVP_RAND_CTX
*rand_new_drbg(OSSL_LIB_CTX
*libctx
, EVP_RAND_CTX
*parent
,
645 unsigned int reseed_interval
,
646 time_t reseed_time_interval
)
649 RAND_GLOBAL
*dgbl
= rand_get_global(libctx
);
651 OSSL_PARAM params
[9], *p
= params
;
652 const OSSL_PARAM
*settables
;
653 const char *prov_name
;
659 name
= dgbl
->rng_name
!= NULL
? dgbl
->rng_name
: "CTR-DRBG";
660 rand
= EVP_RAND_fetch(libctx
, name
, dgbl
->rng_propq
);
662 ERR_raise(ERR_LIB_RAND
, RAND_R_UNABLE_TO_FETCH_DRBG
);
665 prov_name
= ossl_provider_name(EVP_RAND_get0_provider(rand
));
666 ctx
= EVP_RAND_CTX_new(rand
, parent
);
669 ERR_raise(ERR_LIB_RAND
, RAND_R_UNABLE_TO_CREATE_DRBG
);
673 settables
= EVP_RAND_CTX_settable_params(ctx
);
674 if (OSSL_PARAM_locate_const(settables
, OSSL_DRBG_PARAM_CIPHER
)) {
675 cipher
= dgbl
->rng_cipher
!= NULL
? dgbl
->rng_cipher
: "AES-256-CTR";
676 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER
,
679 if (dgbl
->rng_digest
!= NULL
680 && OSSL_PARAM_locate_const(settables
, OSSL_DRBG_PARAM_DIGEST
))
681 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST
,
682 dgbl
->rng_digest
, 0);
683 if (prov_name
!= NULL
)
684 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_CORE_PROV_NAME
,
685 (char *)prov_name
, 0);
686 if (dgbl
->rng_propq
!= NULL
)
687 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES
,
689 if (OSSL_PARAM_locate_const(settables
, OSSL_ALG_PARAM_MAC
))
690 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_MAC
, "HMAC", 0);
691 if (OSSL_PARAM_locate_const(settables
, OSSL_DRBG_PARAM_USE_DF
))
692 *p
++ = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_USE_DF
, &use_df
);
693 *p
++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS
,
695 *p
++ = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL
,
696 &reseed_time_interval
);
697 *p
= OSSL_PARAM_construct_end();
698 if (!EVP_RAND_instantiate(ctx
, 0, 0, NULL
, 0, params
)) {
699 ERR_raise(ERR_LIB_RAND
, RAND_R_ERROR_INSTANTIATING_DRBG
);
700 EVP_RAND_CTX_free(ctx
);
706 #if defined(FIPS_MODULE)
707 static EVP_RAND_CTX
*rand_new_crngt(OSSL_LIB_CTX
*libctx
, EVP_RAND_CTX
*parent
)
712 rand
= EVP_RAND_fetch(libctx
, "CRNG-TEST", "-fips");
714 ERR_raise(ERR_LIB_RAND
, RAND_R_UNABLE_TO_FETCH_DRBG
);
717 ctx
= EVP_RAND_CTX_new(rand
, parent
);
720 ERR_raise(ERR_LIB_RAND
, RAND_R_UNABLE_TO_CREATE_DRBG
);
724 if (!EVP_RAND_instantiate(ctx
, 0, 0, NULL
, 0, NULL
)) {
725 ERR_raise(ERR_LIB_RAND
, RAND_R_ERROR_INSTANTIATING_DRBG
);
726 EVP_RAND_CTX_free(ctx
);
731 #endif /* FIPS_MODULE */
734 * Get the primary random generator.
735 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
738 static EVP_RAND_CTX
*rand_get0_primary(OSSL_LIB_CTX
*ctx
, RAND_GLOBAL
*dgbl
)
740 EVP_RAND_CTX
*ret
, *seed
, *newseed
= NULL
, *primary
;
745 if (!CRYPTO_THREAD_read_lock(dgbl
->lock
))
750 CRYPTO_THREAD_unlock(dgbl
->lock
);
755 #if !defined(FIPS_MODULE) || !defined(OPENSSL_NO_FIPS_JITTER)
756 /* Create a seed source for libcrypto or jitter enabled FIPS provider */
759 seed
= newseed
= rand_new_seed(ctx
);
762 #endif /* !FIPS_MODULE || !OPENSSL_NO_FIPS_JITTER */
764 #if defined(FIPS_MODULE)
765 /* The FIPS provider has entropy health tests instead of the primary */
766 ret
= rand_new_crngt(ctx
, seed
);
767 #else /* FIPS_MODULE */
768 ret
= rand_new_drbg(ctx
, seed
, PRIMARY_RESEED_INTERVAL
,
769 PRIMARY_RESEED_TIME_INTERVAL
);
770 #endif /* FIPS_MODULE */
773 * The primary DRBG may be shared between multiple threads so we must
776 if (ret
== NULL
|| !EVP_RAND_enable_locking(ret
)) {
778 ERR_raise(ERR_LIB_EVP
, EVP_R_UNABLE_TO_ENABLE_LOCKING
);
779 EVP_RAND_CTX_free(ret
);
783 /* else carry on and store seed */
787 if (!CRYPTO_THREAD_write_lock(dgbl
->lock
))
790 primary
= dgbl
->primary
;
791 if (primary
!= NULL
) {
792 CRYPTO_THREAD_unlock(dgbl
->lock
);
793 EVP_RAND_CTX_free(ret
);
794 EVP_RAND_CTX_free(newseed
);
798 dgbl
->seed
= newseed
;
800 CRYPTO_THREAD_unlock(dgbl
->lock
);
806 * Get the primary random generator.
807 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
810 EVP_RAND_CTX
*RAND_get0_primary(OSSL_LIB_CTX
*ctx
)
812 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
814 return dgbl
== NULL
? NULL
: rand_get0_primary(ctx
, dgbl
);
817 static EVP_RAND_CTX
*rand_get0_public(OSSL_LIB_CTX
*ctx
, RAND_GLOBAL
*dgbl
)
819 EVP_RAND_CTX
*rand
, *primary
;
820 OSSL_LIB_CTX
*origctx
= ctx
;
822 ctx
= ossl_lib_ctx_get_concrete(ctx
);
830 rand
= CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY
, ctx
);
832 primary
= rand_get0_primary(origctx
, dgbl
);
837 * If the private is also NULL then this is the first time we've
840 if (CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY
, ctx
) == NULL
841 && !ossl_init_thread_start(NULL
, ctx
, rand_delete_thread_state
))
843 rand
= rand_new_drbg(ctx
, primary
, SECONDARY_RESEED_INTERVAL
,
844 SECONDARY_RESEED_TIME_INTERVAL
);
845 CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY
, ctx
, rand
);
851 * Get the public random generator.
852 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
854 EVP_RAND_CTX
*RAND_get0_public(OSSL_LIB_CTX
*ctx
)
856 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
858 return dgbl
== NULL
? NULL
: rand_get0_public(ctx
, dgbl
);
861 static EVP_RAND_CTX
*rand_get0_private(OSSL_LIB_CTX
*ctx
, RAND_GLOBAL
*dgbl
)
863 EVP_RAND_CTX
*rand
, *primary
;
864 OSSL_LIB_CTX
*origctx
= ctx
;
866 ctx
= ossl_lib_ctx_get_concrete(ctx
);
870 rand
= CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY
, ctx
);
872 primary
= rand_get0_primary(origctx
, dgbl
);
877 * If the public is also NULL then this is the first time we've
880 if (CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY
, ctx
) == NULL
881 && !ossl_init_thread_start(NULL
, ctx
, rand_delete_thread_state
))
883 rand
= rand_new_drbg(ctx
, primary
, SECONDARY_RESEED_INTERVAL
,
884 SECONDARY_RESEED_TIME_INTERVAL
);
885 CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY
, ctx
, rand
);
891 * Get the private random generator.
892 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
894 EVP_RAND_CTX
*RAND_get0_private(OSSL_LIB_CTX
*ctx
)
896 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
898 return dgbl
== NULL
? NULL
: rand_get0_private(ctx
, dgbl
);
902 EVP_RAND_CTX
*ossl_rand_get0_private_noncreating(OSSL_LIB_CTX
*ctx
)
904 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
909 return CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY
, ctx
);
913 int RAND_set0_public(OSSL_LIB_CTX
*ctx
, EVP_RAND_CTX
*rand
)
915 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
921 old
= CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY
, ctx
);
922 if ((r
= CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY
, ctx
, rand
)) > 0)
923 EVP_RAND_CTX_free(old
);
927 int RAND_set0_private(OSSL_LIB_CTX
*ctx
, EVP_RAND_CTX
*rand
)
929 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
935 old
= CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY
, ctx
);
936 if ((r
= CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY
, ctx
, rand
)) > 0)
937 EVP_RAND_CTX_free(old
);
942 static int random_set_string(char **p
, const char *s
)
947 d
= OPENSSL_strdup(s
);
957 * Load the DRBG definitions from a configuration file.
959 static int random_conf_init(CONF_IMODULE
*md
, const CONF
*cnf
)
961 STACK_OF(CONF_VALUE
) *elist
;
963 OSSL_LIB_CTX
*libctx
= NCONF_get0_libctx((CONF
*)cnf
);
964 RAND_GLOBAL
*dgbl
= rand_get_global(libctx
);
967 OSSL_TRACE1(CONF
, "Loading random module: section %s\n",
968 CONF_imodule_get_value(md
));
970 /* Value is a section containing RANDOM configuration */
971 elist
= NCONF_get_section(cnf
, CONF_imodule_get_value(md
));
973 ERR_raise(ERR_LIB_CRYPTO
, CRYPTO_R_RANDOM_SECTION_ERROR
);
980 for (i
= 0; i
< sk_CONF_VALUE_num(elist
); i
++) {
981 cval
= sk_CONF_VALUE_value(elist
, i
);
982 if (OPENSSL_strcasecmp(cval
->name
, "random") == 0) {
983 if (!random_set_string(&dgbl
->rng_name
, cval
->value
))
985 } else if (OPENSSL_strcasecmp(cval
->name
, "cipher") == 0) {
986 if (!random_set_string(&dgbl
->rng_cipher
, cval
->value
))
988 } else if (OPENSSL_strcasecmp(cval
->name
, "digest") == 0) {
989 if (!random_set_string(&dgbl
->rng_digest
, cval
->value
))
991 } else if (OPENSSL_strcasecmp(cval
->name
, "properties") == 0) {
992 if (!random_set_string(&dgbl
->rng_propq
, cval
->value
))
994 } else if (OPENSSL_strcasecmp(cval
->name
, "seed") == 0) {
995 if (!random_set_string(&dgbl
->seed_name
, cval
->value
))
997 } else if (OPENSSL_strcasecmp(cval
->name
, "seed_properties") == 0) {
998 if (!random_set_string(&dgbl
->seed_propq
, cval
->value
))
1000 } else if (OPENSSL_strcasecmp(cval
->name
, "random_provider") == 0) {
1001 # ifndef FIPS_MODULE
1002 OSSL_PROVIDER
*prov
= ossl_provider_find(libctx
, cval
->value
, 0);
1005 if (!RAND_set1_random_provider(libctx
, prov
)) {
1006 ERR_raise(ERR_LIB_CRYPTO
, ERR_R_INTERNAL_ERROR
);
1007 OSSL_PROVIDER_unload(prov
);
1011 * We need to release the reference from ossl_provider_find because
1012 * we don't want to keep a reference counted handle to the provider.
1014 * The provider unload code checks for the random provider and,
1015 * if present, our reference will be NULLed when it is fully freed.
1016 * The provider load code, conversely, checks the provider name
1017 * and re-hooks our reference if required. This means that a load,
1018 * hook random provider, use, unload, reload, reuse sequence will
1021 OSSL_PROVIDER_unload(prov
);
1022 } else if (!set_random_provider_name(dgbl
, cval
->value
))
1026 ERR_raise_data(ERR_LIB_CRYPTO
,
1027 CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION
,
1028 "name=%s, value=%s", cval
->name
, cval
->value
);
1036 static void random_conf_deinit(CONF_IMODULE
*md
)
1038 OSSL_TRACE(CONF
, "Cleaned up random\n");
1041 void ossl_random_add_conf_module(void)
1043 OSSL_TRACE(CONF
, "Adding config module 'random'\n");
1044 CONF_module_add("random", random_conf_init
, random_conf_deinit
);
1047 int RAND_set_DRBG_type(OSSL_LIB_CTX
*ctx
, const char *drbg
, const char *propq
,
1048 const char *cipher
, const char *digest
)
1050 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
1054 if (dgbl
->primary
!= NULL
) {
1055 ERR_raise(ERR_LIB_CRYPTO
, RAND_R_ALREADY_INSTANTIATED
);
1058 return random_set_string(&dgbl
->rng_name
, drbg
)
1059 && random_set_string(&dgbl
->rng_propq
, propq
)
1060 && random_set_string(&dgbl
->rng_cipher
, cipher
)
1061 && random_set_string(&dgbl
->rng_digest
, digest
);
1064 int RAND_set_seed_source_type(OSSL_LIB_CTX
*ctx
, const char *seed
,
1067 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
1071 if (dgbl
->seed
!= NULL
) {
1072 ERR_raise(ERR_LIB_CRYPTO
, RAND_R_ALREADY_INSTANTIATED
);
1075 return random_set_string(&dgbl
->seed_name
, seed
)
1076 && random_set_string(&dgbl
->seed_propq
, propq
);
1079 int RAND_set1_random_provider(OSSL_LIB_CTX
*ctx
, OSSL_PROVIDER
*prov
)
1081 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
1087 OPENSSL_free(dgbl
->random_provider_name
);
1088 dgbl
->random_provider_name
= NULL
;
1089 dgbl
->random_provider
= NULL
;
1093 if (dgbl
->random_provider
== prov
)
1096 if (!set_random_provider_name(dgbl
, OSSL_PROVIDER_get0_name(prov
)))
1099 dgbl
->random_provider
= prov
;
1104 * When a new provider is loaded, we need to check to see if it is the
1105 * designated randomness provider and register it if it is.
1107 int ossl_rand_check_random_provider_on_load(OSSL_LIB_CTX
*ctx
,
1108 OSSL_PROVIDER
*prov
)
1110 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
1115 /* No random provider name specified, or one is installed already */
1116 if (dgbl
->random_provider_name
== NULL
|| dgbl
->random_provider
!= NULL
)
1119 /* Does this provider match the name we're using? */
1120 if (strcmp(dgbl
->random_provider_name
, OSSL_PROVIDER_get0_name(prov
)) != 0)
1123 dgbl
->random_provider
= prov
;
1128 * When a provider is being unloaded, if it is the randomness provider,
1129 * we need to deregister it.
1131 int ossl_rand_check_random_provider_on_unload(OSSL_LIB_CTX
*ctx
,
1132 OSSL_PROVIDER
*prov
)
1134 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
1139 if (dgbl
->random_provider
== prov
)
1140 dgbl
->random_provider
= NULL
;
1144 #endif /* !FIPS_MODULE */