Coverage Report

Created: 2026-09-17 06:47

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