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