Coverage Report

Created: 2026-10-28 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl41/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
2.60M
{
88
2.60M
    return ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_DRBG_INDEX);
89
2.60M
}
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
52
{
131
52
#ifndef OPENSSL_NO_DEPRECATED_3_0
132
52
    rand_meth_lock = CRYPTO_THREAD_lock_new();
133
52
    if (rand_meth_lock == NULL)
134
0
        goto err;
135
52
#endif /* !OPENSSL_NO_DEPRECATED_3_0 */
136
137
52
    if (!ossl_rand_pool_init())
138
0
        goto err;
139
140
52
    rand_inited = 1;
141
52
    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
52
}
150
151
void ossl_rand_cleanup_int(void)
152
154
{
153
154
#ifndef OPENSSL_NO_DEPRECATED_3_0
154
154
    const RAND_METHOD *meth = default_RAND_meth;
155
156
154
    if (!rand_inited)
157
110
        return;
158
159
44
    if (meth != NULL && meth->cleanup != NULL)
160
0
        meth->cleanup();
161
44
    RAND_set_rand_method(NULL);
162
44
#endif /* !OPENSSL_NO_DEPRECATED_3_0 */
163
44
    ossl_rand_pool_cleanup();
164
44
#ifndef OPENSSL_NO_DEPRECATED_3_0
165
44
    CRYPTO_THREAD_lock_free(rand_meth_lock);
166
44
    rand_meth_lock = NULL;
167
44
#endif /* !OPENSSL_NO_DEPRECATED_3_0 */
168
44
    ossl_release_default_drbg_ctx();
169
44
    rand_inited = 0;
170
44
}
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
0
{
192
0
    static const char salt[] = "polling";
193
194
0
#ifndef OPENSSL_NO_DEPRECATED_3_0
195
0
    const RAND_METHOD *meth = RAND_get_rand_method();
196
0
    int ret = meth == RAND_OpenSSL();
197
198
0
    if (meth == NULL)
199
0
        return 0;
200
201
0
    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
0
#endif /* !OPENSSL_NO_DEPRECATED_3_0 */
226
227
0
    RAND_seed(salt, sizeof(salt));
228
0
    return 1;
229
0
}
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
44
{
247
44
    return rand_set_rand_method_internal(meth, NULL);
248
44
}
249
250
const RAND_METHOD *RAND_get_rand_method(void)
251
977k
{
252
977k
    const RAND_METHOD *tmp_meth = NULL;
253
977k
    int lock_failed;
254
255
977k
    if (!RUN_ONCE(&rand_init, do_rand_init))
256
0
        goto end;
257
258
977k
    if (CRYPTO_atomic_load_ptr((void **)&default_RAND_meth, (void **)&tmp_meth,
259
977k
            rand_meth_lock)) {
260
977k
        if (tmp_meth != NULL)
261
977k
            return tmp_meth;
262
977k
    } 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
37
    if (CRYPTO_atomic_cmp_exch_ptr((void **)&default_RAND_meth, (void **)&tmp_meth,
275
37
            (void *)&ossl_rand_meth, rand_meth_lock, &lock_failed)) {
276
37
        tmp_meth = &ossl_rand_meth;
277
37
    } else {
278
0
        if (lock_failed == 1)
279
0
            return NULL;
280
0
    }
281
37
end:
282
37
    return tmp_meth;
283
37
}
284
#endif /* OPENSSL_NO_DEPRECATED_3_0 */
285
286
void RAND_seed(const void *buf, int num)
287
0
{
288
0
    EVP_RAND_CTX *drbg;
289
0
#ifndef OPENSSL_NO_DEPRECATED_3_0
290
0
    const RAND_METHOD *meth = RAND_get_rand_method();
291
292
0
    if (meth != NULL && meth->seed != NULL) {
293
0
        meth->seed(buf, num);
294
0
        return;
295
0
    }
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
0
{
339
0
    EVP_RAND_CTX *rand;
340
0
#ifndef OPENSSL_NO_DEPRECATED_3_0
341
0
    const RAND_METHOD *meth = RAND_get_rand_method();
342
343
0
    if (meth != NULL && meth != RAND_OpenSSL())
344
0
        return meth->status != NULL ? meth->status() : 0;
345
0
#endif
346
347
0
    if ((rand = RAND_get0_primary(NULL)) == NULL)
348
0
        return 0;
349
0
    return EVP_RAND_get_state(rand) == EVP_RAND_STATE_READY;
350
0
}
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
1.23M
{
369
1.23M
    RAND_GLOBAL *dgbl;
370
1.23M
    EVP_RAND_CTX *rand;
371
1.23M
#if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE)
372
1.23M
    const RAND_METHOD *meth = RAND_get_rand_method();
373
374
1.23M
    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
1.23M
#endif
385
386
1.23M
    dgbl = rand_get_global(ctx);
387
1.23M
    if (dgbl == NULL)
388
0
        return 0;
389
1.23M
#ifndef FIPS_MODULE
390
1.23M
    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
1.23M
#endif /* !FIPS_MODULE */
395
1.23M
    rand = rand_get0_private(ctx, dgbl);
396
1.23M
    if (rand != NULL)
397
1.23M
        return EVP_RAND_generate(rand, buf, num, strength, 0, NULL, 0);
398
399
0
    return 0;
400
1.23M
}
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
520k
{
412
520k
    RAND_GLOBAL *dgbl;
413
520k
    EVP_RAND_CTX *rand;
414
520k
#if !defined(OPENSSL_NO_DEPRECATED_3_0) && !defined(FIPS_MODULE)
415
520k
    const RAND_METHOD *meth = RAND_get_rand_method();
416
417
520k
    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
520k
#endif
428
429
520k
    dgbl = rand_get_global(ctx);
430
520k
    if (dgbl == NULL)
431
0
        return 0;
432
520k
#ifndef FIPS_MODULE
433
520k
    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
520k
#endif /* !FIPS_MODULE */
438
439
520k
    rand = rand_get0_public(ctx, dgbl);
440
520k
    if (rand != NULL)
441
520k
        return EVP_RAND_generate(rand, buf, num, strength, 0, NULL, 0);
442
443
0
    return 0;
444
520k
}
445
446
int RAND_bytes(unsigned char *buf, int num)
447
1.22k
{
448
1.22k
    if (num < 0)
449
0
        return 0;
450
1.22k
    return RAND_bytes_ex(NULL, buf, (size_t)num, 0);
451
1.22k
}
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
322
{
459
322
    RAND_GLOBAL *dgbl = OPENSSL_zalloc(sizeof(*dgbl));
460
461
322
    if (dgbl == NULL)
462
0
        return NULL;
463
464
322
    dgbl->seed_strict = -1;
465
466
322
#ifndef FIPS_MODULE
467
    /*
468
     * We need to ensure that base libcrypto thread handling has been
469
     * initialised.
470
     */
471
322
    OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL);
472
473
    /* Prepopulate the random provider name */
474
322
    dgbl->random_provider_name = OPENSSL_strdup(random_provider_fips_name);
475
322
    if (dgbl->random_provider_name == NULL)
476
0
        goto err0;
477
322
#endif
478
479
322
    dgbl->lock = CRYPTO_THREAD_lock_new();
480
322
    if (dgbl->lock == NULL)
481
0
        goto err1;
482
483
322
    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
154
{
497
154
    RAND_GLOBAL *dgbl = vdgbl;
498
499
154
    if (dgbl == NULL)
500
0
        return;
501
502
154
    CRYPTO_THREAD_lock_free(dgbl->lock);
503
154
    EVP_RAND_CTX_free(dgbl->primary);
504
154
    EVP_RAND_CTX_free(dgbl->seed);
505
154
#ifndef FIPS_MODULE
506
154
    OPENSSL_free(dgbl->random_provider_name);
507
154
#endif /* !FIPS_MODULE */
508
154
    OPENSSL_free(dgbl->rng_name);
509
154
    OPENSSL_free(dgbl->rng_cipher);
510
154
    OPENSSL_free(dgbl->rng_digest);
511
154
    OPENSSL_free(dgbl->rng_propq);
512
154
    OPENSSL_free(dgbl->seed_name);
513
154
    OPENSSL_free(dgbl->seed_propq);
514
515
154
    OPENSSL_free(dgbl);
516
154
}
517
518
static void rand_delete_thread_state(void *arg)
519
44
{
520
44
    OSSL_LIB_CTX *ctx = arg;
521
44
    RAND_GLOBAL *dgbl = rand_get_global(ctx);
522
44
    EVP_RAND_CTX *rand;
523
524
44
    if (dgbl == NULL)
525
0
        return;
526
527
44
    rand = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx);
528
44
    CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx, NULL);
529
44
    EVP_RAND_CTX_free(rand);
530
531
44
    rand = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx);
532
44
    CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx, NULL);
533
44
    EVP_RAND_CTX_free(rand);
534
44
}
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
980
{
546
980
#ifdef OPENSSL_NO_FIPS_JITTER
547
980
    const char *name;
548
549
980
    if (dgbl->seed_strict >= 0)
550
0
        return dgbl->seed_strict;
551
980
    name = dgbl->seed_name != NULL ? dgbl->seed_name : OPENSSL_SEED_SRC_NAME;
552
980
    return OPENSSL_strcasecmp(name, "JITTER") == 0;
553
#else /* !OPENSSL_NO_FIPS_JITTER */
554
    return 1;
555
#endif /* OPENSSL_NO_FIPS_JITTER */
556
980
}
557
558
static EVP_RAND_CTX *rand_new_seed(OSSL_LIB_CTX *libctx)
559
37
{
560
37
    EVP_RAND *rand;
561
37
    const char *propq;
562
37
    char *name;
563
37
    EVP_RAND_CTX *ctx = NULL;
564
37
    int fallback = 0;
565
37
#ifdef OPENSSL_NO_FIPS_JITTER
566
37
    RAND_GLOBAL *dgbl = rand_get_global(libctx);
567
568
37
    if (dgbl == NULL)
569
0
        return NULL;
570
37
    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
37
    if (dgbl->seed_name != NULL) {
576
0
        name = dgbl->seed_name;
577
37
    } else {
578
37
        fallback = !rand_seed_source_strict(dgbl);
579
37
        name = OPENSSL_SEED_SRC_NAME;
580
37
    }
581
#else /* !OPENSSL_NO_FIPS_JITTER */
582
    name = OPENSSL_SEED_SRC_NAME;
583
    propq = "";
584
#endif /* OPENSSL_NO_FIPS_JITTER */
585
586
37
    ERR_set_mark();
587
37
    rand = EVP_RAND_fetch(libctx, name, propq);
588
37
    ERR_pop_to_mark();
589
37
    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
37
    ctx = EVP_RAND_CTX_new(rand, NULL);
595
37
    EVP_RAND_free(rand);
596
37
    if (ctx == NULL) {
597
0
        ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG);
598
0
        goto err;
599
0
    }
600
37
    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
37
    return ctx;
605
0
err:
606
0
    EVP_RAND_CTX_free(ctx);
607
0
    return NULL;
608
37
}
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
37
{
620
37
    RAND_SEED_CONSTRUCTION *current, *head;
621
37
#ifndef FIPS_MODULE
622
37
    ASYNC_JOB *job = ASYNC_get_current_job();
623
37
#endif
624
625
37
    head = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_RAND_SEED_KEY, ctx);
626
37
    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
37
#ifndef FIPS_MODULE
636
37
    marker->job = job;
637
37
#endif
638
37
    marker->next = head;
639
37
    if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_RAND_SEED_KEY, ctx,
640
37
            marker)) {
641
0
        ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR);
642
0
        return 0;
643
0
    }
644
37
    return 1;
645
37
}
646
647
static int rand_seed_construction_end(OSSL_LIB_CTX *ctx,
648
    RAND_SEED_CONSTRUCTION *marker)
649
37
{
650
37
    RAND_SEED_CONSTRUCTION *current, *head;
651
652
37
    head = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_RAND_SEED_KEY, ctx);
653
37
    if (head == marker) {
654
37
        if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_RAND_SEED_KEY,
655
37
                ctx, marker->next)) {
656
0
            ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR);
657
0
            return 0;
658
0
        }
659
37
        return 1;
660
37
    }
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
37
{
680
37
    EVP_RAND_CTX *ret, *seed;
681
37
    RAND_SEED_CONSTRUCTION marker;
682
683
37
    if (!CRYPTO_THREAD_read_lock(dgbl->lock))
684
0
        return NULL;
685
37
    ret = dgbl->seed;
686
37
    CRYPTO_THREAD_unlock(dgbl->lock);
687
37
    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
37
    if (!rand_seed_construction_begin(ctx, &marker))
695
0
        return NULL;
696
697
37
    seed = rand_new_seed(ctx);
698
37
    if (!rand_seed_construction_end(ctx, &marker)) {
699
0
        EVP_RAND_CTX_free(seed);
700
0
        return NULL;
701
0
    }
702
37
    if (seed == NULL)
703
0
        return NULL;
704
705
37
    if (!CRYPTO_THREAD_write_lock(dgbl->lock)) {
706
0
        EVP_RAND_CTX_free(seed);
707
0
        return NULL;
708
0
    }
709
37
    if (dgbl->seed == NULL) {
710
37
        dgbl->seed = seed;
711
37
        seed = NULL;
712
37
    }
713
37
    ret = dgbl->seed;
714
37
    CRYPTO_THREAD_unlock(dgbl->lock);
715
    /* Free the instance that lost a creation race */
716
37
    EVP_RAND_CTX_free(seed);
717
37
    return ret;
718
37
}
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
3.29k
{
724
3.29k
    RAND_GLOBAL *dgbl = rand_get_global(ctx);
725
3.29k
    EVP_RAND_CTX *ret;
726
727
3.29k
    if (dgbl == NULL)
728
0
        return NULL;
729
730
3.29k
    if (!CRYPTO_THREAD_read_lock(dgbl->lock))
731
0
        return NULL;
732
3.29k
    ret = dgbl->seed;
733
3.29k
    CRYPTO_THREAD_unlock(dgbl->lock);
734
3.29k
    return ret;
735
3.29k
}
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
943
{
748
943
    RAND_GLOBAL *dgbl = rand_get_global(ctx);
749
750
943
    return dgbl != NULL && rand_seed_source_strict(dgbl);
751
943
}
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
252
{
758
252
    EVP_RAND *rand;
759
252
    RAND_GLOBAL *dgbl = rand_get_global(libctx);
760
252
    EVP_RAND_CTX *ctx;
761
252
    OSSL_PARAM params[9], *p = params;
762
252
    const OSSL_PARAM *settables;
763
252
    char *name, *cipher;
764
252
    int use_df = 1;
765
766
252
    if (dgbl == NULL)
767
0
        return NULL;
768
252
    name = dgbl->rng_name != NULL ? dgbl->rng_name : "CTR-DRBG";
769
252
    rand = EVP_RAND_fetch(libctx, name, dgbl->rng_propq);
770
252
    if (rand == NULL) {
771
0
        ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG);
772
0
        return NULL;
773
0
    }
774
252
    ctx = EVP_RAND_CTX_new(rand, parent);
775
252
    EVP_RAND_free(rand);
776
252
    if (ctx == NULL) {
777
0
        ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG);
778
0
        return NULL;
779
0
    }
780
781
252
    settables = EVP_RAND_CTX_settable_params(ctx);
782
252
    if (OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_CIPHER)) {
783
68
        cipher = dgbl->rng_cipher != NULL ? dgbl->rng_cipher : "AES-256-CTR";
784
68
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER,
785
68
            cipher, 0);
786
68
    }
787
252
    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
252
    if (dgbl->rng_propq != NULL)
792
0
        *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES,
793
0
            dgbl->rng_propq, 0);
794
252
    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
252
    if (OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_USE_DF))
797
68
        *p++ = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_USE_DF, &use_df);
798
252
    *p++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS,
799
252
        &reseed_interval);
800
252
    *p++ = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL,
801
252
        &reseed_time_interval);
802
252
    *p = OSSL_PARAM_construct_end();
803
252
    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
252
    return ctx;
809
252
}
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
85
{
845
85
    EVP_RAND_CTX *ret, *seed = NULL, *primary;
846
847
85
    if (dgbl == NULL)
848
0
        return NULL;
849
850
85
    if (!CRYPTO_THREAD_read_lock(dgbl->lock))
851
0
        return NULL;
852
853
85
    ret = dgbl->primary;
854
85
    CRYPTO_THREAD_unlock(dgbl->lock);
855
856
85
    if (ret != NULL)
857
33
        return ret;
858
859
52
#if !defined(FIPS_MODULE) || !defined(OPENSSL_NO_FIPS_JITTER)
860
    /* Create a seed source for libcrypto or jitter enabled FIPS provider */
861
52
    ERR_set_mark();
862
52
    seed = rand_get0_seed(ctx, dgbl);
863
52
    if (seed == NULL && ERR_count_to_mark() > 0) {
864
0
        ERR_clear_last_mark();
865
0
        return NULL;
866
0
    }
867
52
    ERR_pop_to_mark();
868
52
#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
52
    ret = rand_new_drbg(ctx, seed, PRIMARY_RESEED_INTERVAL,
875
52
        PRIMARY_RESEED_TIME_INTERVAL);
876
52
#endif /* FIPS_MODULE */
877
878
52
    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
52
    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
52
    if (!CRYPTO_THREAD_write_lock(dgbl->lock)) {
892
0
        EVP_RAND_CTX_free(ret);
893
0
        return NULL;
894
0
    }
895
896
52
    primary = dgbl->primary;
897
52
    if (primary != NULL) {
898
0
        CRYPTO_THREAD_unlock(dgbl->lock);
899
0
        EVP_RAND_CTX_free(ret);
900
0
        return primary;
901
0
    }
902
52
    dgbl->primary = ret;
903
52
    CRYPTO_THREAD_unlock(dgbl->lock);
904
905
52
    return ret;
906
52
}
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
0
{
915
0
    RAND_GLOBAL *dgbl = rand_get_global(ctx);
916
917
0
    return dgbl == NULL ? NULL : rand_get0_primary(ctx, dgbl);
918
0
}
919
920
static EVP_RAND_CTX *rand_get0_public(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
921
520k
{
922
520k
    EVP_RAND_CTX *rand, *primary;
923
520k
    OSSL_LIB_CTX *origctx = ctx;
924
925
520k
    ctx = ossl_lib_ctx_get_concrete(ctx);
926
927
520k
    if (ctx == NULL)
928
0
        return NULL;
929
930
520k
    if (dgbl == NULL)
931
0
        return NULL;
932
933
520k
    rand = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx);
934
520k
    if (rand == NULL) {
935
48
        primary = rand_get0_primary(origctx, dgbl);
936
48
        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
48
        if (CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx) == NULL
944
38
            && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state))
945
0
            return NULL;
946
48
        rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL,
947
48
            SECONDARY_RESEED_TIME_INTERVAL);
948
48
        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
48
    }
953
520k
    return rand;
954
520k
}
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
{
962
    RAND_GLOBAL *dgbl = rand_get_global(ctx);
963
964
    return dgbl == NULL ? NULL : rand_get0_public(ctx, dgbl);
965
}
966
967
static EVP_RAND_CTX *rand_get0_private(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
968
1.23M
{
969
1.23M
    EVP_RAND_CTX *rand, *primary;
970
1.23M
    OSSL_LIB_CTX *origctx = ctx;
971
972
1.23M
    ctx = ossl_lib_ctx_get_concrete(ctx);
973
1.23M
    if (ctx == NULL)
974
0
        return NULL;
975
976
1.23M
    rand = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx);
977
1.23M
    if (rand == NULL) {
978
63
        primary = rand_get0_primary(origctx, dgbl);
979
63
        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
63
        if (CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx) == NULL
987
30
            && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state))
988
0
            return NULL;
989
63
        rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL,
990
63
            SECONDARY_RESEED_TIME_INTERVAL);
991
63
        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
63
    }
996
1.23M
    return rand;
997
1.23M
}
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
{
1005
    RAND_GLOBAL *dgbl = rand_get_global(ctx);
1006
1007
    return dgbl == NULL ? NULL : rand_get0_private(ctx, dgbl);
1008
}
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
616
{
1053
616
    char *d = NULL;
1054
1055
616
    if (s != NULL) {
1056
154
        d = OPENSSL_strdup(s);
1057
154
        if (d == NULL)
1058
0
            return 0;
1059
154
    }
1060
616
    OPENSSL_free(*p);
1061
616
    *p = d;
1062
616
    return 1;
1063
616
}
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
154
{
1171
154
    RAND_GLOBAL *dgbl = rand_get_global(ctx);
1172
1173
154
    if (dgbl == NULL)
1174
0
        return 0;
1175
154
    if (dgbl->primary != NULL) {
1176
0
        ERR_raise(ERR_LIB_RAND, RAND_R_ALREADY_INSTANTIATED);
1177
0
        return 0;
1178
0
    }
1179
154
    return random_set_string(&dgbl->rng_name, drbg)
1180
154
        && random_set_string(&dgbl->rng_propq, propq)
1181
154
        && random_set_string(&dgbl->rng_cipher, cipher)
1182
154
        && random_set_string(&dgbl->rng_digest, digest);
1183
154
}
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 */