1 /*
2  * Copyright 1995-2025 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 <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"
26 
27 #ifndef OPENSSL_DEFAULT_SEED_SRC
28 # define OPENSSL_DEFAULT_SEED_SRC SEED-SRC
29 #endif
30 
31 typedef struct rand_global_st {
32     /*
33      * The three shared DRBG instances
34      *
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.
39      */
40     CRYPTO_RWLOCK *lock;
41 
42     EVP_RAND_CTX *seed;
43 
44     /*
45      * The <primary> DRBG
46      *
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().
50      *
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.
54      */
55     EVP_RAND_CTX *primary;
56 
57     /*
58      * The provider which we'll use to generate randomness.
59      */
60 #ifndef FIPS_MODULE
61     OSSL_PROVIDER *random_provider;
62     char *random_provider_name;
63 #endif      /* !FIPS_MODULE */
64 
65     /* Which RNG is being used by default and it's configuration settings */
66     char *rng_name;
67     char *rng_cipher;
68     char *rng_digest;
69     char *rng_propq;
70 
71     /* Allow the randomness source to be changed */
72     char *seed_name;
73     char *seed_propq;
74 } RAND_GLOBAL;
75 
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);
79 
rand_get_global(OSSL_LIB_CTX * libctx)80 static RAND_GLOBAL *rand_get_global(OSSL_LIB_CTX *libctx)
81 {
82     return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DRBG_INDEX);
83 }
84 
85 #ifndef FIPS_MODULE
86 # include <stdio.h>
87 # include <time.h>
88 # include <limits.h>
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"
96 
97 /*
98  * The default name for the random provider.
99  * This ensures that the FIPS provider will supply libcrypto's random byte
100  * requirements.
101  */
102 static const char random_provider_fips_name[] = "fips";
103 
set_random_provider_name(RAND_GLOBAL * dgbl,const char * name)104 static int set_random_provider_name(RAND_GLOBAL *dgbl, const char *name)
105 {
106     if (dgbl->random_provider_name != NULL
107             && OPENSSL_strcasecmp(dgbl->random_provider_name, name) == 0)
108         return 1;
109 
110     OPENSSL_free(dgbl->random_provider_name);
111     dgbl->random_provider_name = OPENSSL_strdup(name);
112     return dgbl->random_provider_name != NULL;
113 }
114 
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;
125 
126 static int rand_inited = 0;
127 
DEFINE_RUN_ONCE_STATIC(do_rand_init)128 DEFINE_RUN_ONCE_STATIC(do_rand_init)
129 {
130 # ifndef OPENSSL_NO_ENGINE
131     rand_engine_lock = CRYPTO_THREAD_lock_new();
132     if (rand_engine_lock == NULL)
133         return 0;
134 # endif     /* !OPENSSL_NO_ENGINE */
135 
136 # ifndef OPENSSL_NO_DEPRECATED_3_0
137     rand_meth_lock = CRYPTO_THREAD_lock_new();
138     if (rand_meth_lock == NULL)
139         goto err;
140 # endif     /* !OPENSSL_NO_DEPRECATED_3_0 */
141 
142     if (!ossl_rand_pool_init())
143         goto err;
144 
145     rand_inited = 1;
146     return 1;
147 
148  err:
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 */
157     return 0;
158 }
159 
ossl_rand_cleanup_int(void)160 void ossl_rand_cleanup_int(void)
161 {
162 # ifndef OPENSSL_NO_DEPRECATED_3_0
163     const RAND_METHOD *meth = default_RAND_meth;
164 
165     if (!rand_inited)
166         return;
167 
168     if (meth != NULL && meth->cleanup != NULL)
169         meth->cleanup();
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();
182     rand_inited = 0;
183 }
184 
185 /*
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.
189  */
RAND_keep_random_devices_open(int keep)190 void RAND_keep_random_devices_open(int keep)
191 {
192     if (RUN_ONCE(&rand_init, do_rand_init))
193         ossl_rand_pool_keep_random_devices_open(keep);
194 }
195 
196 /*
197  * RAND_poll() reseeds the default RNG using random input
198  *
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.
202  */
RAND_poll(void)203 int RAND_poll(void)
204 {
205     static const char salt[] = "polling";
206 
207 # ifndef OPENSSL_NO_DEPRECATED_3_0
208     const RAND_METHOD *meth = RAND_get_rand_method();
209     int ret = meth == RAND_OpenSSL();
210 
211     if (meth == NULL)
212         return 0;
213 
214     if (!ret) {
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);
219 
220         if (pool == NULL)
221             return 0;
222 
223         if (ossl_pool_acquire_entropy(pool) == 0)
224             goto err;
225 
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)
230             goto err;
231 
232         ret = 1;
233      err:
234         ossl_rand_pool_free(pool);
235         return ret;
236     }
237 # endif     /* !OPENSSL_NO_DEPRECATED_3_0 */
238 
239     RAND_seed(salt, sizeof(salt));
240     return 1;
241 }
242 
243 # ifndef OPENSSL_NO_DEPRECATED_3_0
rand_set_rand_method_internal(const RAND_METHOD * meth,ossl_unused ENGINE * e)244 static int rand_set_rand_method_internal(const RAND_METHOD *meth,
245                                          ossl_unused ENGINE *e)
246 {
247     if (!RUN_ONCE(&rand_init, do_rand_init))
248         return 0;
249 
250     if (!CRYPTO_THREAD_write_lock(rand_meth_lock))
251         return 0;
252 #  ifndef OPENSSL_NO_ENGINE
253     ENGINE_finish(funct_ref);
254     funct_ref = e;
255 #  endif
256     default_RAND_meth = meth;
257     CRYPTO_THREAD_unlock(rand_meth_lock);
258     return 1;
259 }
260 
RAND_set_rand_method(const RAND_METHOD * meth)261 int RAND_set_rand_method(const RAND_METHOD *meth)
262 {
263     return rand_set_rand_method_internal(meth, NULL);
264 }
265 
RAND_get_rand_method(void)266 const RAND_METHOD *RAND_get_rand_method(void)
267 {
268     const RAND_METHOD *tmp_meth = NULL;
269 
270     if (!RUN_ONCE(&rand_init, do_rand_init))
271         return NULL;
272 
273     if (rand_meth_lock == NULL)
274         return NULL;
275 
276     if (!CRYPTO_THREAD_read_lock(rand_meth_lock))
277         return NULL;
278     tmp_meth = default_RAND_meth;
279     CRYPTO_THREAD_unlock(rand_meth_lock);
280     if (tmp_meth != NULL)
281         return tmp_meth;
282 
283     if (!CRYPTO_THREAD_write_lock(rand_meth_lock))
284         return NULL;
285     if (default_RAND_meth == NULL) {
286 #  ifndef OPENSSL_NO_ENGINE
287         ENGINE *e;
288 
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) {
292             funct_ref = e;
293             default_RAND_meth = tmp_meth;
294         } else {
295             ENGINE_finish(e);
296             default_RAND_meth = &ossl_rand_meth;
297         }
298 #  else
299         default_RAND_meth = &ossl_rand_meth;
300 #  endif
301     }
302     tmp_meth = default_RAND_meth;
303     CRYPTO_THREAD_unlock(rand_meth_lock);
304     return tmp_meth;
305 }
306 
307 #  if !defined(OPENSSL_NO_ENGINE)
RAND_set_rand_engine(ENGINE * engine)308 int RAND_set_rand_engine(ENGINE *engine)
309 {
310     const RAND_METHOD *tmp_meth = NULL;
311 
312     if (!RUN_ONCE(&rand_init, do_rand_init))
313         return 0;
314 
315     if (engine != NULL) {
316         if (!ENGINE_init(engine))
317             return 0;
318         tmp_meth = ENGINE_get_RAND(engine);
319         if (tmp_meth == NULL) {
320             ENGINE_finish(engine);
321             return 0;
322         }
323     }
324     if (!CRYPTO_THREAD_write_lock(rand_engine_lock)) {
325         ENGINE_finish(engine);
326         return 0;
327     }
328 
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);
332     return 1;
333 }
334 #  endif
335 # endif /* OPENSSL_NO_DEPRECATED_3_0 */
336 
RAND_seed(const void * buf,int num)337 void RAND_seed(const void *buf, int num)
338 {
339     EVP_RAND_CTX *drbg;
340 # ifndef OPENSSL_NO_DEPRECATED_3_0
341     const RAND_METHOD *meth = RAND_get_rand_method();
342 
343     if (meth != NULL && meth->seed != NULL) {
344         meth->seed(buf, num);
345         return;
346     }
347 # endif
348 
349     drbg = RAND_get0_primary(NULL);
350     if (drbg != NULL && num > 0)
351         EVP_RAND_reseed(drbg, 0, NULL, 0, buf, num);
352 }
353 
RAND_add(const void * buf,int num,double randomness)354 void RAND_add(const void *buf, int num, double randomness)
355 {
356     EVP_RAND_CTX *drbg;
357 # ifndef OPENSSL_NO_DEPRECATED_3_0
358     const RAND_METHOD *meth = RAND_get_rand_method();
359 
360     if (meth != NULL && meth->add != NULL) {
361         meth->add(buf, num, randomness);
362         return;
363     }
364 # endif
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);
370 # else
371         /* With an entropy source, we downgrade this to additional input */
372         EVP_RAND_reseed(drbg, 0, NULL, 0, buf, num);
373 # endif
374 }
375 
376 # if !defined(OPENSSL_NO_DEPRECATED_1_1_0)
RAND_pseudo_bytes(unsigned char * buf,int num)377 int RAND_pseudo_bytes(unsigned char *buf, int num)
378 {
379     const RAND_METHOD *meth = RAND_get_rand_method();
380 
381     if (meth != NULL && meth->pseudorand != NULL)
382         return meth->pseudorand(buf, num);
383     ERR_raise(ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED);
384     return -1;
385 }
386 # endif
387 
RAND_status(void)388 int RAND_status(void)
389 {
390     EVP_RAND_CTX *rand;
391 # ifndef OPENSSL_NO_DEPRECATED_3_0
392     const RAND_METHOD *meth = RAND_get_rand_method();
393 
394     if (meth != NULL && meth != RAND_OpenSSL())
395         return meth->status != NULL ? meth->status() : 0;
396 # endif
397 
398     if ((rand = RAND_get0_primary(NULL)) == NULL)
399         return 0;
400     return EVP_RAND_get_state(rand) == EVP_RAND_STATE_READY;
401 }
402 # else  /* !FIPS_MODULE */
403 
404 # ifndef OPENSSL_NO_DEPRECATED_3_0
RAND_get_rand_method(void)405 const RAND_METHOD *RAND_get_rand_method(void)
406 {
407     return NULL;
408 }
409 # endif
410 #endif /* !FIPS_MODULE */
411 
412 /*
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.
416  */
RAND_priv_bytes_ex(OSSL_LIB_CTX * ctx,unsigned char * buf,size_t num,unsigned int strength)417 int RAND_priv_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num,
418                        unsigned int strength)
419 {
420     RAND_GLOBAL *dgbl;
421     EVP_RAND_CTX *rand;
422 #if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE)
423     const RAND_METHOD *meth = RAND_get_rand_method();
424 
425     if (meth != NULL && meth != RAND_OpenSSL()) {
426         if (num > INT_MAX) {
427             ERR_raise(ERR_LIB_RAND, RAND_R_ARGUMENT_OUT_OF_RANGE);
428             return -1;
429         }
430         if (meth->bytes != NULL)
431             return meth->bytes(buf, (int)num);
432         ERR_raise(ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED);
433         return -1;
434     }
435 #endif
436 
437     dgbl = rand_get_global(ctx);
438     if (dgbl == NULL)
439         return 0;
440 #ifndef FIPS_MODULE
441     if (dgbl->random_provider != NULL)
442         return ossl_provider_random_bytes(dgbl->random_provider,
443                                           OSSL_PROV_RANDOM_PRIVATE,
444                                           buf, num, strength);
445 #endif      /* !FIPS_MODULE */
446     rand = rand_get0_private(ctx, dgbl);
447     if (rand != NULL)
448         return EVP_RAND_generate(rand, buf, num, strength, 0, NULL, 0);
449 
450     return 0;
451 }
452 
RAND_priv_bytes(unsigned char * buf,int num)453 int RAND_priv_bytes(unsigned char *buf, int num)
454 {
455     if (num < 0)
456         return 0;
457     return RAND_priv_bytes_ex(NULL, buf, (size_t)num, 0);
458 }
459 
RAND_bytes_ex(OSSL_LIB_CTX * ctx,unsigned char * buf,size_t num,unsigned int strength)460 int RAND_bytes_ex(OSSL_LIB_CTX *ctx, unsigned char *buf, size_t num,
461                   unsigned int strength)
462 {
463     RAND_GLOBAL *dgbl;
464     EVP_RAND_CTX *rand;
465 #if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE)
466     const RAND_METHOD *meth = RAND_get_rand_method();
467 
468     if (meth != NULL && meth != RAND_OpenSSL()) {
469         if (num > INT_MAX) {
470             ERR_raise(ERR_LIB_RAND, RAND_R_ARGUMENT_OUT_OF_RANGE);
471             return -1;
472         }
473         if (meth->bytes != NULL)
474             return meth->bytes(buf, (int)num);
475         ERR_raise(ERR_LIB_RAND, RAND_R_FUNC_NOT_IMPLEMENTED);
476         return -1;
477     }
478 #endif
479 
480     dgbl = rand_get_global(ctx);
481     if (dgbl == NULL)
482         return 0;
483 #ifndef FIPS_MODULE
484     if (dgbl->random_provider != NULL)
485         return ossl_provider_random_bytes(dgbl->random_provider,
486                                           OSSL_PROV_RANDOM_PUBLIC,
487                                           buf, num, strength);
488 #endif      /* !FIPS_MODULE */
489 
490     rand = rand_get0_public(ctx, dgbl);
491     if (rand != NULL)
492         return EVP_RAND_generate(rand, buf, num, strength, 0, NULL, 0);
493 
494     return 0;
495 }
496 
RAND_bytes(unsigned char * buf,int num)497 int RAND_bytes(unsigned char *buf, int num)
498 {
499     if (num < 0)
500         return 0;
501     return RAND_bytes_ex(NULL, buf, (size_t)num, 0);
502 }
503 
504 /*
505  * Initialize the OSSL_LIB_CTX global DRBGs on first use.
506  * Returns the allocated global data on success or NULL on failure.
507  */
ossl_rand_ctx_new(OSSL_LIB_CTX * libctx)508 void *ossl_rand_ctx_new(OSSL_LIB_CTX *libctx)
509 {
510     RAND_GLOBAL *dgbl = OPENSSL_zalloc(sizeof(*dgbl));
511 
512     if (dgbl == NULL)
513         return NULL;
514 
515 #ifndef FIPS_MODULE
516     /*
517      * We need to ensure that base libcrypto thread handling has been
518      * initialised.
519      */
520     OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL);
521 
522     /* Prepopulate the random provider name */
523     dgbl->random_provider_name = OPENSSL_strdup(random_provider_fips_name);
524     if (dgbl->random_provider_name == NULL)
525         goto err0;
526 #endif
527 
528     dgbl->lock = CRYPTO_THREAD_lock_new();
529     if (dgbl->lock == NULL)
530         goto err1;
531 
532     return dgbl;
533 
534  err1:
535     CRYPTO_THREAD_lock_free(dgbl->lock);
536 #ifndef FIPS_MODULE
537  err0:
538     OPENSSL_free(dgbl->random_provider_name);
539 #endif
540     OPENSSL_free(dgbl);
541     return NULL;
542 }
543 
ossl_rand_ctx_free(void * vdgbl)544 void ossl_rand_ctx_free(void *vdgbl)
545 {
546     RAND_GLOBAL *dgbl = vdgbl;
547 
548     if (dgbl == NULL)
549         return;
550 
551     CRYPTO_THREAD_lock_free(dgbl->lock);
552     EVP_RAND_CTX_free(dgbl->primary);
553     EVP_RAND_CTX_free(dgbl->seed);
554 #ifndef FIPS_MODULE
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);
563 
564     OPENSSL_free(dgbl);
565 }
566 
rand_delete_thread_state(void * arg)567 static void rand_delete_thread_state(void *arg)
568 {
569     OSSL_LIB_CTX *ctx = arg;
570     RAND_GLOBAL *dgbl = rand_get_global(ctx);
571     EVP_RAND_CTX *rand;
572 
573     if (dgbl == NULL)
574         return;
575 
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);
579 
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);
583 }
584 
585 #if !defined(FIPS_MODULE) || !defined(OPENSSL_NO_FIPS_JITTER)
rand_new_seed(OSSL_LIB_CTX * libctx)586 static EVP_RAND_CTX *rand_new_seed(OSSL_LIB_CTX *libctx)
587 {
588     EVP_RAND *rand;
589     const char *propq;
590     char *name;
591     EVP_RAND_CTX *ctx = NULL;
592 # ifdef OPENSSL_NO_FIPS_JITTER
593     RAND_GLOBAL *dgbl = rand_get_global(libctx);
594 
595     if (dgbl == NULL)
596         return NULL;
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 */
601     name = "JITTER";
602     propq = "";
603 # endif /* OPENSSL_NO_FIPS_JITTER */
604 
605     rand = EVP_RAND_fetch(libctx, name, propq);
606     if (rand == NULL) {
607         ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG);
608         goto err;
609     }
610     ctx = EVP_RAND_CTX_new(rand, NULL);
611     EVP_RAND_free(rand);
612     if (ctx == NULL) {
613         ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG);
614         goto err;
615     }
616     if (!EVP_RAND_instantiate(ctx, 0, 0, NULL, 0, NULL)) {
617         ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG);
618         goto err;
619     }
620     return ctx;
621  err:
622     EVP_RAND_CTX_free(ctx);
623     return NULL;
624 }
625 #endif  /* !FIPS_MODULE || !OPENSSL_NO_FIPS_JITTER */
626 
627 #ifndef FIPS_MODULE
ossl_rand_get0_seed_noncreating(OSSL_LIB_CTX * ctx)628 EVP_RAND_CTX *ossl_rand_get0_seed_noncreating(OSSL_LIB_CTX *ctx)
629 {
630     RAND_GLOBAL *dgbl = rand_get_global(ctx);
631     EVP_RAND_CTX *ret;
632 
633     if (dgbl == NULL)
634         return NULL;
635 
636     if (!CRYPTO_THREAD_read_lock(dgbl->lock))
637         return NULL;
638     ret = dgbl->seed;
639     CRYPTO_THREAD_unlock(dgbl->lock);
640     return ret;
641 }
642 #endif  /* !FIPS_MODULE */
643 
rand_new_drbg(OSSL_LIB_CTX * libctx,EVP_RAND_CTX * parent,unsigned int reseed_interval,time_t reseed_time_interval)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)
647 {
648     EVP_RAND *rand;
649     RAND_GLOBAL *dgbl = rand_get_global(libctx);
650     EVP_RAND_CTX *ctx;
651     OSSL_PARAM params[9], *p = params;
652     const OSSL_PARAM *settables;
653     const char *prov_name;
654     char *name, *cipher;
655     int use_df = 1;
656 
657     if (dgbl == NULL)
658         return NULL;
659     name = dgbl->rng_name != NULL ? dgbl->rng_name : "CTR-DRBG";
660     rand = EVP_RAND_fetch(libctx, name, dgbl->rng_propq);
661     if (rand == NULL) {
662         ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG);
663         return NULL;
664     }
665     prov_name = ossl_provider_name(EVP_RAND_get0_provider(rand));
666     ctx = EVP_RAND_CTX_new(rand, parent);
667     EVP_RAND_free(rand);
668     if (ctx == NULL) {
669         ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG);
670         return NULL;
671     }
672 
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,
677                                                 cipher, 0);
678     }
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,
688                                                 dgbl->rng_propq, 0);
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,
694                                      &reseed_interval);
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);
701         return NULL;
702     }
703     return ctx;
704 }
705 
706 #if defined(FIPS_MODULE)
rand_new_crngt(OSSL_LIB_CTX * libctx,EVP_RAND_CTX * parent)707 static EVP_RAND_CTX *rand_new_crngt(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent)
708 {
709     EVP_RAND *rand;
710     EVP_RAND_CTX *ctx;
711 
712     rand = EVP_RAND_fetch(libctx, "CRNG-TEST", "-fips");
713     if (rand == NULL) {
714         ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG);
715         return NULL;
716     }
717     ctx = EVP_RAND_CTX_new(rand, parent);
718     EVP_RAND_free(rand);
719     if (ctx == NULL) {
720         ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG);
721         return NULL;
722     }
723 
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);
727         return NULL;
728     }
729     return ctx;
730 }
731 #endif  /* FIPS_MODULE */
732 
733 /*
734  * Get the primary random generator.
735  * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
736  *
737  */
rand_get0_primary(OSSL_LIB_CTX * ctx,RAND_GLOBAL * dgbl)738 static EVP_RAND_CTX *rand_get0_primary(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
739 {
740     EVP_RAND_CTX *ret, *seed, *newseed = NULL, *primary;
741 
742     if (dgbl == NULL)
743         return NULL;
744 
745     if (!CRYPTO_THREAD_read_lock(dgbl->lock))
746         return NULL;
747 
748     ret = dgbl->primary;
749     seed = dgbl->seed;
750     CRYPTO_THREAD_unlock(dgbl->lock);
751 
752     if (ret != NULL)
753         return ret;
754 
755 #if !defined(FIPS_MODULE) || !defined(OPENSSL_NO_FIPS_JITTER)
756     /* Create a seed source for libcrypto or jitter enabled FIPS provider */
757     if (seed == NULL) {
758         ERR_set_mark();
759         seed = newseed = rand_new_seed(ctx);
760         ERR_pop_to_mark();
761     }
762 #endif  /* !FIPS_MODULE || !OPENSSL_NO_FIPS_JITTER */
763 
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 */
771 
772     /*
773      * The primary DRBG may be shared between multiple threads so we must
774      * enable locking.
775      */
776     if (ret == NULL || !EVP_RAND_enable_locking(ret)) {
777         if (ret != NULL) {
778             ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_LOCKING);
779             EVP_RAND_CTX_free(ret);
780         }
781         if (newseed == NULL)
782             return NULL;
783         /* else carry on and store seed */
784         ret = NULL;
785     }
786 
787     if (!CRYPTO_THREAD_write_lock(dgbl->lock))
788         return NULL;
789 
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);
795         return primary;
796     }
797     if (newseed != NULL)
798         dgbl->seed = newseed;
799     dgbl->primary = ret;
800     CRYPTO_THREAD_unlock(dgbl->lock);
801 
802     return ret;
803 }
804 
805 /*
806  * Get the primary random generator.
807  * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
808  *
809  */
RAND_get0_primary(OSSL_LIB_CTX * ctx)810 EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx)
811 {
812     RAND_GLOBAL *dgbl = rand_get_global(ctx);
813 
814     return dgbl == NULL ? NULL : rand_get0_primary(ctx, dgbl);
815 }
816 
rand_get0_public(OSSL_LIB_CTX * ctx,RAND_GLOBAL * dgbl)817 static EVP_RAND_CTX *rand_get0_public(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
818 {
819     EVP_RAND_CTX *rand, *primary;
820     OSSL_LIB_CTX *origctx = ctx;
821 
822     ctx = ossl_lib_ctx_get_concrete(ctx);
823 
824     if (ctx == NULL)
825         return NULL;
826 
827     if (dgbl == NULL)
828         return NULL;
829 
830     rand = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx);
831     if (rand == NULL) {
832         primary = rand_get0_primary(origctx, dgbl);
833         if (primary == NULL)
834             return NULL;
835 
836         /*
837          * If the private is also NULL then this is the first time we've
838          * used this thread.
839          */
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))
842             return NULL;
843         rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL,
844                              SECONDARY_RESEED_TIME_INTERVAL);
845         if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx, rand)) {
846             EVP_RAND_CTX_free(rand);
847             rand = NULL;
848         }
849     }
850     return rand;
851 }
852 
853 /*
854  * Get the public random generator.
855  * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
856  */
RAND_get0_public(OSSL_LIB_CTX * ctx)857 EVP_RAND_CTX *RAND_get0_public(OSSL_LIB_CTX *ctx)
858 {
859     RAND_GLOBAL *dgbl = rand_get_global(ctx);
860 
861     return dgbl == NULL ? NULL : rand_get0_public(ctx, dgbl);
862 }
863 
rand_get0_private(OSSL_LIB_CTX * ctx,RAND_GLOBAL * dgbl)864 static EVP_RAND_CTX *rand_get0_private(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
865 {
866     EVP_RAND_CTX *rand, *primary;
867     OSSL_LIB_CTX *origctx = ctx;
868 
869     ctx = ossl_lib_ctx_get_concrete(ctx);
870     if (ctx == NULL)
871         return NULL;
872 
873     rand = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx);
874     if (rand == NULL) {
875         primary = rand_get0_primary(origctx, dgbl);
876         if (primary == NULL)
877             return NULL;
878 
879         /*
880          * If the public is also NULL then this is the first time we've
881          * used this thread.
882          */
883         if (CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx) == NULL
884                 && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state))
885             return NULL;
886         rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL,
887                              SECONDARY_RESEED_TIME_INTERVAL);
888         if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx, rand)) {
889             EVP_RAND_CTX_free(rand);
890             rand = NULL;
891         }
892     }
893     return rand;
894 }
895 
896 /*
897  * Get the private random generator.
898  * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
899  */
RAND_get0_private(OSSL_LIB_CTX * ctx)900 EVP_RAND_CTX *RAND_get0_private(OSSL_LIB_CTX *ctx)
901 {
902     RAND_GLOBAL *dgbl = rand_get_global(ctx);
903 
904     return dgbl == NULL ? NULL : rand_get0_private(ctx, dgbl);
905 }
906 
907 #ifdef FIPS_MODULE
ossl_rand_get0_private_noncreating(OSSL_LIB_CTX * ctx)908 EVP_RAND_CTX *ossl_rand_get0_private_noncreating(OSSL_LIB_CTX *ctx)
909 {
910     RAND_GLOBAL *dgbl = rand_get_global(ctx);
911 
912     if (dgbl == NULL)
913         return NULL;
914 
915     return CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx);
916 }
917 #endif
918 
RAND_set0_public(OSSL_LIB_CTX * ctx,EVP_RAND_CTX * rand)919 int RAND_set0_public(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand)
920 {
921     RAND_GLOBAL *dgbl = rand_get_global(ctx);
922     EVP_RAND_CTX *old;
923     int r;
924 
925     if (dgbl == NULL)
926         return 0;
927     old = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx);
928     if ((r = CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx, rand)) > 0)
929         EVP_RAND_CTX_free(old);
930     return r;
931 }
932 
RAND_set0_private(OSSL_LIB_CTX * ctx,EVP_RAND_CTX * rand)933 int RAND_set0_private(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand)
934 {
935     RAND_GLOBAL *dgbl = rand_get_global(ctx);
936     EVP_RAND_CTX *old;
937     int r;
938 
939     if (dgbl == NULL)
940         return 0;
941     old = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx);
942     if ((r = CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx, rand)) > 0)
943         EVP_RAND_CTX_free(old);
944     return r;
945 }
946 
947 #ifndef FIPS_MODULE
random_set_string(char ** p,const char * s)948 static int random_set_string(char **p, const char *s)
949 {
950     char *d = NULL;
951 
952     if (s != NULL) {
953         d = OPENSSL_strdup(s);
954         if (d == NULL)
955             return 0;
956     }
957     OPENSSL_free(*p);
958     *p = d;
959     return 1;
960 }
961 
962 /*
963  * Load the DRBG definitions from a configuration file.
964  */
random_conf_init(CONF_IMODULE * md,const CONF * cnf)965 static int random_conf_init(CONF_IMODULE *md, const CONF *cnf)
966 {
967     STACK_OF(CONF_VALUE) *elist;
968     CONF_VALUE *cval;
969     OSSL_LIB_CTX *libctx = NCONF_get0_libctx((CONF *)cnf);
970     RAND_GLOBAL *dgbl = rand_get_global(libctx);
971     int i, r = 1;
972 
973     OSSL_TRACE1(CONF, "Loading random module: section %s\n",
974                 CONF_imodule_get_value(md));
975 
976     /* Value is a section containing RANDOM configuration */
977     elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
978     if (elist == NULL) {
979         ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_RANDOM_SECTION_ERROR);
980         return 0;
981     }
982 
983     if (dgbl == NULL)
984         return 0;
985 
986     for (i = 0; i < sk_CONF_VALUE_num(elist); i++) {
987         cval = sk_CONF_VALUE_value(elist, i);
988         if (OPENSSL_strcasecmp(cval->name, "random") == 0) {
989             if (!random_set_string(&dgbl->rng_name, cval->value))
990                 return 0;
991         } else if (OPENSSL_strcasecmp(cval->name, "cipher") == 0) {
992             if (!random_set_string(&dgbl->rng_cipher, cval->value))
993                 return 0;
994         } else if (OPENSSL_strcasecmp(cval->name, "digest") == 0) {
995             if (!random_set_string(&dgbl->rng_digest, cval->value))
996                 return 0;
997         } else if (OPENSSL_strcasecmp(cval->name, "properties") == 0) {
998             if (!random_set_string(&dgbl->rng_propq, cval->value))
999                 return 0;
1000         } else if (OPENSSL_strcasecmp(cval->name, "seed") == 0) {
1001             if (!random_set_string(&dgbl->seed_name, cval->value))
1002                 return 0;
1003         } else if (OPENSSL_strcasecmp(cval->name, "seed_properties") == 0) {
1004             if (!random_set_string(&dgbl->seed_propq, cval->value))
1005                 return 0;
1006         } else if (OPENSSL_strcasecmp(cval->name, "random_provider") == 0) {
1007 # ifndef FIPS_MODULE
1008             OSSL_PROVIDER *prov = ossl_provider_find(libctx, cval->value, 0);
1009 
1010             if (prov != NULL) {
1011                 if (!RAND_set1_random_provider(libctx, prov)) {
1012                     ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
1013                     OSSL_PROVIDER_unload(prov);
1014                     return 0;
1015                 }
1016                 /*
1017                  * We need to release the reference from ossl_provider_find because
1018                  * we don't want to keep a reference counted handle to the provider.
1019                  *
1020                  * The provider unload code checks for the random provider and,
1021                  * if present, our reference will be NULLed when it is fully freed.
1022                  * The provider load code, conversely, checks the provider name
1023                  * and re-hooks our reference if required.  This means that a load,
1024                  * hook random provider, use, unload, reload, reuse sequence will
1025                  * work as expected.
1026                  */
1027                 OSSL_PROVIDER_unload(prov);
1028             } else if (!set_random_provider_name(dgbl, cval->value))
1029                 return 0;
1030 # endif
1031         } else {
1032             ERR_raise_data(ERR_LIB_CRYPTO,
1033                            CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION,
1034                            "name=%s, value=%s", cval->name, cval->value);
1035             r = 0;
1036         }
1037     }
1038     return r;
1039 }
1040 
1041 
random_conf_deinit(CONF_IMODULE * md)1042 static void random_conf_deinit(CONF_IMODULE *md)
1043 {
1044     OSSL_TRACE(CONF, "Cleaned up random\n");
1045 }
1046 
ossl_random_add_conf_module(void)1047 void ossl_random_add_conf_module(void)
1048 {
1049     OSSL_TRACE(CONF, "Adding config module 'random'\n");
1050     CONF_module_add("random", random_conf_init, random_conf_deinit);
1051 }
1052 
RAND_set_DRBG_type(OSSL_LIB_CTX * ctx,const char * drbg,const char * propq,const char * cipher,const char * digest)1053 int RAND_set_DRBG_type(OSSL_LIB_CTX *ctx, const char *drbg, const char *propq,
1054                        const char *cipher, const char *digest)
1055 {
1056     RAND_GLOBAL *dgbl = rand_get_global(ctx);
1057 
1058     if (dgbl == NULL)
1059         return 0;
1060     if (dgbl->primary != NULL) {
1061         ERR_raise(ERR_LIB_CRYPTO, RAND_R_ALREADY_INSTANTIATED);
1062         return 0;
1063     }
1064     return random_set_string(&dgbl->rng_name, drbg)
1065         && random_set_string(&dgbl->rng_propq, propq)
1066         && random_set_string(&dgbl->rng_cipher, cipher)
1067         && random_set_string(&dgbl->rng_digest, digest);
1068 }
1069 
RAND_set_seed_source_type(OSSL_LIB_CTX * ctx,const char * seed,const char * propq)1070 int RAND_set_seed_source_type(OSSL_LIB_CTX *ctx, const char *seed,
1071                               const char *propq)
1072 {
1073     RAND_GLOBAL *dgbl = rand_get_global(ctx);
1074 
1075     if (dgbl == NULL)
1076         return 0;
1077     if (dgbl->seed != NULL) {
1078         ERR_raise(ERR_LIB_CRYPTO, RAND_R_ALREADY_INSTANTIATED);
1079         return 0;
1080     }
1081     return random_set_string(&dgbl->seed_name, seed)
1082         && random_set_string(&dgbl->seed_propq, propq);
1083 }
1084 
RAND_set1_random_provider(OSSL_LIB_CTX * ctx,OSSL_PROVIDER * prov)1085 int RAND_set1_random_provider(OSSL_LIB_CTX *ctx, OSSL_PROVIDER *prov)
1086 {
1087     RAND_GLOBAL *dgbl = rand_get_global(ctx);
1088 
1089     if (dgbl == NULL)
1090         return 0;
1091 
1092     if (prov == NULL) {
1093         OPENSSL_free(dgbl->random_provider_name);
1094         dgbl->random_provider_name = NULL;
1095         dgbl->random_provider = NULL;
1096         return 1;
1097     }
1098 
1099     if (dgbl->random_provider == prov)
1100         return 1;
1101 
1102     if (!set_random_provider_name(dgbl, OSSL_PROVIDER_get0_name(prov)))
1103         return 0;
1104 
1105     dgbl->random_provider = prov;
1106     return 1;
1107 }
1108 
1109 /*
1110  * When a new provider is loaded, we need to check to see if it is the
1111  * designated randomness provider and register it if it is.
1112  */
ossl_rand_check_random_provider_on_load(OSSL_LIB_CTX * ctx,OSSL_PROVIDER * prov)1113 int ossl_rand_check_random_provider_on_load(OSSL_LIB_CTX *ctx,
1114                                             OSSL_PROVIDER *prov)
1115 {
1116     RAND_GLOBAL *dgbl = rand_get_global(ctx);
1117 
1118     if (dgbl == NULL)
1119         return 0;
1120 
1121     /* No random provider name specified, or one is installed already */
1122     if (dgbl->random_provider_name == NULL || dgbl->random_provider != NULL)
1123         return 1;
1124 
1125     /* Does this provider match the name we're using? */
1126     if (strcmp(dgbl->random_provider_name, OSSL_PROVIDER_get0_name(prov)) != 0)
1127         return 1;
1128 
1129     dgbl->random_provider = prov;
1130     return 1;
1131 }
1132 
1133 /*
1134  * When a provider is being unloaded, if it is the randomness provider,
1135  * we need to deregister it.
1136  */
ossl_rand_check_random_provider_on_unload(OSSL_LIB_CTX * ctx,OSSL_PROVIDER * prov)1137 int ossl_rand_check_random_provider_on_unload(OSSL_LIB_CTX *ctx,
1138                                               OSSL_PROVIDER *prov)
1139 {
1140     RAND_GLOBAL *dgbl = rand_get_global(ctx);
1141 
1142     if (dgbl == NULL)
1143         return 0;
1144 
1145     if (dgbl->random_provider == prov)
1146         dgbl->random_provider = NULL;
1147     return 1;
1148 }
1149 
1150 #endif      /* !FIPS_MODULE */
1151