2 * Copyright 1995-2021 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 "internal/cryptlib.h"
17 #include "internal/thread_once.h"
18 #include "crypto/rand.h"
19 #include "crypto/cryptlib.h"
20 #include "rand_local.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 "internal/e_os.h"
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
;
38 # ifndef OPENSSL_NO_DEPRECATED_3_0
39 static CRYPTO_RWLOCK
*rand_meth_lock
;
40 static const RAND_METHOD
*default_RAND_meth
;
42 static CRYPTO_ONCE rand_init
= CRYPTO_ONCE_STATIC_INIT
;
44 static int rand_inited
= 0;
46 DEFINE_RUN_ONCE_STATIC(do_rand_init
)
48 # ifndef OPENSSL_NO_ENGINE
49 rand_engine_lock
= CRYPTO_THREAD_lock_new();
50 if (rand_engine_lock
== NULL
)
54 # ifndef OPENSSL_NO_DEPRECATED_3_0
55 rand_meth_lock
= CRYPTO_THREAD_lock_new();
56 if (rand_meth_lock
== NULL
)
60 if (!ossl_rand_pool_init())
67 # ifndef OPENSSL_NO_DEPRECATED_3_0
68 CRYPTO_THREAD_lock_free(rand_meth_lock
);
69 rand_meth_lock
= NULL
;
71 # ifndef OPENSSL_NO_ENGINE
72 CRYPTO_THREAD_lock_free(rand_engine_lock
);
73 rand_engine_lock
= NULL
;
78 void ossl_rand_cleanup_int(void)
80 # ifndef OPENSSL_NO_DEPRECATED_3_0
81 const RAND_METHOD
*meth
= default_RAND_meth
;
86 if (meth
!= NULL
&& meth
->cleanup
!= NULL
)
88 RAND_set_rand_method(NULL
);
90 ossl_rand_pool_cleanup();
91 # ifndef OPENSSL_NO_ENGINE
92 CRYPTO_THREAD_lock_free(rand_engine_lock
);
93 rand_engine_lock
= NULL
;
95 # ifndef OPENSSL_NO_DEPRECATED_3_0
96 CRYPTO_THREAD_lock_free(rand_meth_lock
);
97 rand_meth_lock
= NULL
;
103 * RAND_close_seed_files() ensures that any seed file descriptors are
104 * closed after use. This only applies to libcrypto/default provider,
105 * it does not apply to other providers.
107 void RAND_keep_random_devices_open(int keep
)
109 if (RUN_ONCE(&rand_init
, do_rand_init
))
110 ossl_rand_pool_keep_random_devices_open(keep
);
114 * RAND_poll() reseeds the default RNG using random input
116 * The random input is obtained from polling various entropy
117 * sources which depend on the operating system and are
118 * configurable via the --with-rand-seed configure option.
122 # ifndef OPENSSL_NO_DEPRECATED_3_0
123 const RAND_METHOD
*meth
= RAND_get_rand_method();
124 int ret
= meth
== RAND_OpenSSL();
130 /* fill random pool and seed the current legacy RNG */
131 RAND_POOL
*pool
= ossl_rand_pool_new(RAND_DRBG_STRENGTH
, 1,
132 (RAND_DRBG_STRENGTH
+ 7) / 8,
133 RAND_POOL_MAX_LENGTH
);
138 if (ossl_pool_acquire_entropy(pool
) == 0)
141 if (meth
->add
== NULL
142 || meth
->add(ossl_rand_pool_buffer(pool
),
143 ossl_rand_pool_length(pool
),
144 (ossl_rand_pool_entropy(pool
) / 8.0)) == 0)
149 ossl_rand_pool_free(pool
);
153 static const char salt
[] = "polling";
155 RAND_seed(salt
, sizeof(salt
));
160 # ifndef OPENSSL_NO_DEPRECATED_3_0
161 static int rand_set_rand_method_internal(const RAND_METHOD
*meth
,
162 ossl_unused ENGINE
*e
)
164 if (!RUN_ONCE(&rand_init
, do_rand_init
))
167 if (!CRYPTO_THREAD_write_lock(rand_meth_lock
))
169 # ifndef OPENSSL_NO_ENGINE
170 ENGINE_finish(funct_ref
);
173 default_RAND_meth
= meth
;
174 CRYPTO_THREAD_unlock(rand_meth_lock
);
178 int RAND_set_rand_method(const RAND_METHOD
*meth
)
180 return rand_set_rand_method_internal(meth
, NULL
);
183 const RAND_METHOD
*RAND_get_rand_method(void)
185 const RAND_METHOD
*tmp_meth
= NULL
;
187 if (!RUN_ONCE(&rand_init
, do_rand_init
))
190 if (!CRYPTO_THREAD_write_lock(rand_meth_lock
))
192 if (default_RAND_meth
== NULL
) {
193 # ifndef OPENSSL_NO_ENGINE
196 /* If we have an engine that can do RAND, use it. */
197 if ((e
= ENGINE_get_default_RAND()) != NULL
198 && (tmp_meth
= ENGINE_get_RAND(e
)) != NULL
) {
200 default_RAND_meth
= tmp_meth
;
203 default_RAND_meth
= &ossl_rand_meth
;
206 default_RAND_meth
= &ossl_rand_meth
;
209 tmp_meth
= default_RAND_meth
;
210 CRYPTO_THREAD_unlock(rand_meth_lock
);
214 # if !defined(OPENSSL_NO_ENGINE)
215 int RAND_set_rand_engine(ENGINE
*engine
)
217 const RAND_METHOD
*tmp_meth
= NULL
;
219 if (!RUN_ONCE(&rand_init
, do_rand_init
))
222 if (engine
!= NULL
) {
223 if (!ENGINE_init(engine
))
225 tmp_meth
= ENGINE_get_RAND(engine
);
226 if (tmp_meth
== NULL
) {
227 ENGINE_finish(engine
);
231 if (!CRYPTO_THREAD_write_lock(rand_engine_lock
)) {
232 ENGINE_finish(engine
);
236 /* This function releases any prior ENGINE so call it first */
237 rand_set_rand_method_internal(tmp_meth
, engine
);
238 CRYPTO_THREAD_unlock(rand_engine_lock
);
242 # endif /* OPENSSL_NO_DEPRECATED_3_0 */
244 void RAND_seed(const void *buf
, int num
)
247 # ifndef OPENSSL_NO_DEPRECATED_3_0
248 const RAND_METHOD
*meth
= RAND_get_rand_method();
250 if (meth
!= NULL
&& meth
->seed
!= NULL
) {
251 meth
->seed(buf
, num
);
256 drbg
= RAND_get0_primary(NULL
);
257 if (drbg
!= NULL
&& num
> 0)
258 EVP_RAND_reseed(drbg
, 0, NULL
, 0, buf
, num
);
261 void RAND_add(const void *buf
, int num
, double randomness
)
264 # ifndef OPENSSL_NO_DEPRECATED_3_0
265 const RAND_METHOD
*meth
= RAND_get_rand_method();
267 if (meth
!= NULL
&& meth
->add
!= NULL
) {
268 meth
->add(buf
, num
, randomness
);
272 drbg
= RAND_get0_primary(NULL
);
273 if (drbg
!= NULL
&& num
> 0)
274 EVP_RAND_reseed(drbg
, 0, NULL
, 0, buf
, num
);
277 # if !defined(OPENSSL_NO_DEPRECATED_1_1_0)
278 int RAND_pseudo_bytes(unsigned char *buf
, int num
)
280 const RAND_METHOD
*meth
= RAND_get_rand_method();
282 if (meth
!= NULL
&& meth
->pseudorand
!= NULL
)
283 return meth
->pseudorand(buf
, num
);
284 ERR_raise(ERR_LIB_RAND
, RAND_R_FUNC_NOT_IMPLEMENTED
);
289 int RAND_status(void)
292 # ifndef OPENSSL_NO_DEPRECATED_3_0
293 const RAND_METHOD
*meth
= RAND_get_rand_method();
295 if (meth
!= NULL
&& meth
!= RAND_OpenSSL())
296 return meth
->status
!= NULL
? meth
->status() : 0;
299 if ((rand
= RAND_get0_primary(NULL
)) == NULL
)
301 return EVP_RAND_get_state(rand
) == EVP_RAND_STATE_READY
;
303 # else /* !FIPS_MODULE */
305 # ifndef OPENSSL_NO_DEPRECATED_3_0
306 const RAND_METHOD
*RAND_get_rand_method(void)
311 #endif /* !FIPS_MODULE */
314 * This function is not part of RAND_METHOD, so if we're not using
315 * the default method, then just call RAND_bytes(). Otherwise make
316 * sure we're instantiated and use the private DRBG.
318 int RAND_priv_bytes_ex(OSSL_LIB_CTX
*ctx
, unsigned char *buf
, size_t num
,
319 unsigned int strength
)
322 #if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE)
323 const RAND_METHOD
*meth
= RAND_get_rand_method();
325 if (meth
!= NULL
&& meth
!= RAND_OpenSSL()) {
326 if (meth
->bytes
!= NULL
)
327 return meth
->bytes(buf
, num
);
328 ERR_raise(ERR_LIB_RAND
, RAND_R_FUNC_NOT_IMPLEMENTED
);
333 rand
= RAND_get0_private(ctx
);
335 return EVP_RAND_generate(rand
, buf
, num
, strength
, 0, NULL
, 0);
340 int RAND_priv_bytes(unsigned char *buf
, int num
)
344 return RAND_priv_bytes_ex(NULL
, buf
, (size_t)num
, 0);
347 int RAND_bytes_ex(OSSL_LIB_CTX
*ctx
, unsigned char *buf
, size_t num
,
348 unsigned int strength
)
351 #if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE)
352 const RAND_METHOD
*meth
= RAND_get_rand_method();
354 if (meth
!= NULL
&& meth
!= RAND_OpenSSL()) {
355 if (meth
->bytes
!= NULL
)
356 return meth
->bytes(buf
, num
);
357 ERR_raise(ERR_LIB_RAND
, RAND_R_FUNC_NOT_IMPLEMENTED
);
362 rand
= RAND_get0_public(ctx
);
364 return EVP_RAND_generate(rand
, buf
, num
, strength
, 0, NULL
, 0);
369 int RAND_bytes(unsigned char *buf
, int num
)
373 return RAND_bytes_ex(NULL
, buf
, (size_t)num
, 0);
376 typedef struct rand_global_st
{
378 * The three shared DRBG instances
380 * There are three shared DRBG instances: <primary>, <public>, and
381 * <private>. The <public> and <private> DRBGs are secondary ones.
382 * These are used for non-secret (e.g. nonces) and secret
383 * (e.g. private keys) data respectively.
392 * Not used directly by the application, only for reseeding the two other
393 * DRBGs. It reseeds itself by pulling either randomness from os entropy
394 * sources or by consuming randomness which was added by RAND_add().
396 * The <primary> DRBG is a global instance which is accessed concurrently by
397 * all threads. The necessary locking is managed automatically by its child
398 * DRBG instances during reseeding.
400 EVP_RAND_CTX
*primary
;
405 * Used by default for generating random bytes using RAND_bytes().
407 * The <public> secondary DRBG is thread-local, i.e., there is one instance
410 CRYPTO_THREAD_LOCAL
public;
415 * Used by default for generating private keys using RAND_priv_bytes()
417 * The <private> secondary DRBG is thread-local, i.e., there is one
418 * instance per thread.
420 CRYPTO_THREAD_LOCAL
private;
422 /* Which RNG is being used by default and it's configuration settings */
428 /* Allow the randomness source to be changed */
434 * Initialize the OSSL_LIB_CTX global DRBGs on first use.
435 * Returns the allocated global data on success or NULL on failure.
437 static void *rand_ossl_ctx_new(OSSL_LIB_CTX
*libctx
)
439 RAND_GLOBAL
*dgbl
= OPENSSL_zalloc(sizeof(*dgbl
));
446 * We need to ensure that base libcrypto thread handling has been
449 OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY
, NULL
);
452 dgbl
->lock
= CRYPTO_THREAD_lock_new();
453 if (dgbl
->lock
== NULL
)
456 if (!CRYPTO_THREAD_init_local(&dgbl
->private, NULL
))
459 if (!CRYPTO_THREAD_init_local(&dgbl
->public, NULL
))
465 CRYPTO_THREAD_cleanup_local(&dgbl
->private);
467 CRYPTO_THREAD_lock_free(dgbl
->lock
);
472 static void rand_ossl_ctx_free(void *vdgbl
)
474 RAND_GLOBAL
*dgbl
= vdgbl
;
479 CRYPTO_THREAD_lock_free(dgbl
->lock
);
480 CRYPTO_THREAD_cleanup_local(&dgbl
->private);
481 CRYPTO_THREAD_cleanup_local(&dgbl
->public);
482 EVP_RAND_CTX_free(dgbl
->primary
);
483 EVP_RAND_CTX_free(dgbl
->seed
);
484 OPENSSL_free(dgbl
->rng_name
);
485 OPENSSL_free(dgbl
->rng_cipher
);
486 OPENSSL_free(dgbl
->rng_digest
);
487 OPENSSL_free(dgbl
->rng_propq
);
488 OPENSSL_free(dgbl
->seed_name
);
489 OPENSSL_free(dgbl
->seed_propq
);
494 static const OSSL_LIB_CTX_METHOD rand_drbg_ossl_ctx_method
= {
495 OSSL_LIB_CTX_METHOD_PRIORITY_2
,
500 static RAND_GLOBAL
*rand_get_global(OSSL_LIB_CTX
*libctx
)
502 return ossl_lib_ctx_get_data(libctx
, OSSL_LIB_CTX_DRBG_INDEX
,
503 &rand_drbg_ossl_ctx_method
);
506 static void rand_delete_thread_state(void *arg
)
508 OSSL_LIB_CTX
*ctx
= arg
;
509 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
515 rand
= CRYPTO_THREAD_get_local(&dgbl
->public);
516 CRYPTO_THREAD_set_local(&dgbl
->public, NULL
);
517 EVP_RAND_CTX_free(rand
);
519 rand
= CRYPTO_THREAD_get_local(&dgbl
->private);
520 CRYPTO_THREAD_set_local(&dgbl
->private, NULL
);
521 EVP_RAND_CTX_free(rand
);
525 static EVP_RAND_CTX
*rand_new_seed(OSSL_LIB_CTX
*libctx
)
528 RAND_GLOBAL
*dgbl
= rand_get_global(libctx
);
532 name
= dgbl
->seed_name
!= NULL
? dgbl
->seed_name
: "SEED-SRC";
533 rand
= EVP_RAND_fetch(libctx
, name
, dgbl
->seed_propq
);
535 ERR_raise(ERR_LIB_RAND
, RAND_R_UNABLE_TO_FETCH_DRBG
);
538 ctx
= EVP_RAND_CTX_new(rand
, NULL
);
541 ERR_raise(ERR_LIB_RAND
, RAND_R_UNABLE_TO_CREATE_DRBG
);
544 if (!EVP_RAND_instantiate(ctx
, 0, 0, NULL
, 0, NULL
)) {
545 ERR_raise(ERR_LIB_RAND
, RAND_R_ERROR_INSTANTIATING_DRBG
);
546 EVP_RAND_CTX_free(ctx
);
553 static EVP_RAND_CTX
*rand_new_drbg(OSSL_LIB_CTX
*libctx
, EVP_RAND_CTX
*parent
,
554 unsigned int reseed_interval
,
555 time_t reseed_time_interval
, int use_df
)
558 RAND_GLOBAL
*dgbl
= rand_get_global(libctx
);
560 OSSL_PARAM params
[8], *p
= params
;
561 const OSSL_PARAM
*settables
;
564 name
= dgbl
->rng_name
!= NULL
? dgbl
->rng_name
: "CTR-DRBG";
565 rand
= EVP_RAND_fetch(libctx
, name
, dgbl
->rng_propq
);
567 ERR_raise(ERR_LIB_RAND
, RAND_R_UNABLE_TO_FETCH_DRBG
);
570 ctx
= EVP_RAND_CTX_new(rand
, parent
);
573 ERR_raise(ERR_LIB_RAND
, RAND_R_UNABLE_TO_CREATE_DRBG
);
577 settables
= EVP_RAND_CTX_settable_params(ctx
);
578 if (OSSL_PARAM_locate_const(settables
, OSSL_DRBG_PARAM_CIPHER
)) {
579 cipher
= dgbl
->rng_cipher
!= NULL
? dgbl
->rng_cipher
: "AES-256-CTR";
580 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER
,
583 if (dgbl
->rng_digest
!= NULL
584 && OSSL_PARAM_locate_const(settables
, OSSL_DRBG_PARAM_DIGEST
))
585 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST
,
586 dgbl
->rng_digest
, 0);
587 if (dgbl
->rng_propq
!= NULL
)
588 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES
,
590 if (OSSL_PARAM_locate_const(settables
, OSSL_ALG_PARAM_MAC
))
591 *p
++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_MAC
, "HMAC", 0);
592 if (OSSL_PARAM_locate_const(settables
, OSSL_DRBG_PARAM_USE_DF
))
593 *p
++ = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_USE_DF
, &use_df
);
594 *p
++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS
,
596 *p
++ = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL
,
597 &reseed_time_interval
);
598 *p
= OSSL_PARAM_construct_end();
599 if (!EVP_RAND_instantiate(ctx
, 0, 0, NULL
, 0, params
)) {
600 ERR_raise(ERR_LIB_RAND
, RAND_R_ERROR_INSTANTIATING_DRBG
);
601 EVP_RAND_CTX_free(ctx
);
608 * Get the primary random generator.
609 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
612 EVP_RAND_CTX
*RAND_get0_primary(OSSL_LIB_CTX
*ctx
)
614 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
620 if (!CRYPTO_THREAD_read_lock(dgbl
->lock
))
624 CRYPTO_THREAD_unlock(dgbl
->lock
);
629 if (!CRYPTO_THREAD_write_lock(dgbl
->lock
))
634 CRYPTO_THREAD_unlock(dgbl
->lock
);
639 if (dgbl
->seed
== NULL
) {
641 dgbl
->seed
= rand_new_seed(ctx
);
646 ret
= dgbl
->primary
= rand_new_drbg(ctx
, dgbl
->seed
,
647 PRIMARY_RESEED_INTERVAL
,
648 PRIMARY_RESEED_TIME_INTERVAL
, 1);
650 * The primary DRBG may be shared between multiple threads so we must
653 if (ret
!= NULL
&& !EVP_RAND_enable_locking(ret
)) {
654 ERR_raise(ERR_LIB_EVP
, EVP_R_UNABLE_TO_ENABLE_LOCKING
);
655 EVP_RAND_CTX_free(ret
);
656 ret
= dgbl
->primary
= NULL
;
658 CRYPTO_THREAD_unlock(dgbl
->lock
);
664 * Get the public random generator.
665 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
667 EVP_RAND_CTX
*RAND_get0_public(OSSL_LIB_CTX
*ctx
)
669 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
670 EVP_RAND_CTX
*rand
, *primary
;
675 rand
= CRYPTO_THREAD_get_local(&dgbl
->public);
677 primary
= RAND_get0_primary(ctx
);
681 ctx
= ossl_lib_ctx_get_concrete(ctx
);
683 * If the private is also NULL then this is the first time we've
686 if (CRYPTO_THREAD_get_local(&dgbl
->private) == NULL
687 && !ossl_init_thread_start(NULL
, ctx
, rand_delete_thread_state
))
689 rand
= rand_new_drbg(ctx
, primary
, SECONDARY_RESEED_INTERVAL
,
690 SECONDARY_RESEED_TIME_INTERVAL
, 0);
691 CRYPTO_THREAD_set_local(&dgbl
->public, rand
);
697 * Get the private random generator.
698 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
700 EVP_RAND_CTX
*RAND_get0_private(OSSL_LIB_CTX
*ctx
)
702 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
703 EVP_RAND_CTX
*rand
, *primary
;
708 rand
= CRYPTO_THREAD_get_local(&dgbl
->private);
710 primary
= RAND_get0_primary(ctx
);
714 ctx
= ossl_lib_ctx_get_concrete(ctx
);
716 * If the public is also NULL then this is the first time we've
719 if (CRYPTO_THREAD_get_local(&dgbl
->public) == NULL
720 && !ossl_init_thread_start(NULL
, ctx
, rand_delete_thread_state
))
722 rand
= rand_new_drbg(ctx
, primary
, SECONDARY_RESEED_INTERVAL
,
723 SECONDARY_RESEED_TIME_INTERVAL
, 0);
724 CRYPTO_THREAD_set_local(&dgbl
->private, rand
);
730 static int random_set_string(char **p
, const char *s
)
735 d
= OPENSSL_strdup(s
);
737 ERR_raise(ERR_LIB_CRYPTO
, ERR_R_MALLOC_FAILURE
);
747 * Load the DRBG definitions from a configuration file.
749 static int random_conf_init(CONF_IMODULE
*md
, const CONF
*cnf
)
751 STACK_OF(CONF_VALUE
) *elist
;
753 RAND_GLOBAL
*dgbl
= rand_get_global(NCONF_get0_libctx((CONF
*)cnf
));
756 OSSL_TRACE1(CONF
, "Loading random module: section %s\n",
757 CONF_imodule_get_value(md
));
759 /* Value is a section containing RANDOM configuration */
760 elist
= NCONF_get_section(cnf
, CONF_imodule_get_value(md
));
762 ERR_raise(ERR_LIB_CRYPTO
, CRYPTO_R_RANDOM_SECTION_ERROR
);
766 for (i
= 0; i
< sk_CONF_VALUE_num(elist
); i
++) {
767 cval
= sk_CONF_VALUE_value(elist
, i
);
768 if (strcasecmp(cval
->name
, "random") == 0) {
769 if (!random_set_string(&dgbl
->rng_name
, cval
->value
))
771 } else if (strcasecmp(cval
->name
, "cipher") == 0) {
772 if (!random_set_string(&dgbl
->rng_cipher
, cval
->value
))
774 } else if (strcasecmp(cval
->name
, "digest") == 0) {
775 if (!random_set_string(&dgbl
->rng_digest
, cval
->value
))
777 } else if (strcasecmp(cval
->name
, "properties") == 0) {
778 if (!random_set_string(&dgbl
->rng_propq
, cval
->value
))
780 } else if (strcasecmp(cval
->name
, "seed") == 0) {
781 if (!random_set_string(&dgbl
->seed_name
, cval
->value
))
783 } else if (strcasecmp(cval
->name
, "seed_properties") == 0) {
784 if (!random_set_string(&dgbl
->seed_propq
, cval
->value
))
787 ERR_raise_data(ERR_LIB_CRYPTO
,
788 CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION
,
789 "name=%s, value=%s", cval
->name
, cval
->value
);
797 static void random_conf_deinit(CONF_IMODULE
*md
)
799 OSSL_TRACE(CONF
, "Cleaned up random\n");
802 void ossl_random_add_conf_module(void)
804 OSSL_TRACE(CONF
, "Adding config module 'random'\n");
805 CONF_module_add("random", random_conf_init
, random_conf_deinit
);
808 int RAND_set_DRBG_type(OSSL_LIB_CTX
*ctx
, const char *drbg
, const char *propq
,
809 const char *cipher
, const char *digest
)
811 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
815 if (dgbl
->primary
!= NULL
) {
816 ERR_raise(ERR_LIB_CRYPTO
, RAND_R_ALREADY_INSTANTIATED
);
819 return random_set_string(&dgbl
->rng_name
, drbg
)
820 && random_set_string(&dgbl
->rng_propq
, propq
)
821 && random_set_string(&dgbl
->rng_cipher
, cipher
)
822 && random_set_string(&dgbl
->rng_digest
, digest
);
825 int RAND_set_seed_source_type(OSSL_LIB_CTX
*ctx
, const char *seed
,
828 RAND_GLOBAL
*dgbl
= rand_get_global(ctx
);
832 if (dgbl
->primary
!= NULL
) {
833 ERR_raise(ERR_LIB_CRYPTO
, RAND_R_ALREADY_INSTANTIATED
);
836 return random_set_string(&dgbl
->seed_name
, seed
)
837 && random_set_string(&dgbl
->seed_propq
, propq
);