Coverage Report

Created: 2025-12-31 06:58

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