Coverage Report

Created: 2025-06-13 06:56

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