Coverage Report

Created: 2025-12-08 06:22

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