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 <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 const char *prov_name;
678 char *name, *cipher;
679 int use_df = 1;
680
681 if (dgbl == NULL)
682 return NULL;
683 name = dgbl->rng_name != NULL ? dgbl->rng_name : "CTR-DRBG";
684 rand = EVP_RAND_fetch(libctx, name, dgbl->rng_propq);
685 if (rand == NULL) {
686 ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG);
687 return NULL;
688 }
689 prov_name = ossl_provider_name(EVP_RAND_get0_provider(rand));
690 ctx = EVP_RAND_CTX_new(rand, parent);
691 EVP_RAND_free(rand);
692 if (ctx == NULL) {
693 ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG);
694 return NULL;
695 }
696
697 settables = EVP_RAND_CTX_settable_params(ctx);
698 if (OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_CIPHER)) {
699 cipher = dgbl->rng_cipher != NULL ? dgbl->rng_cipher : "AES-256-CTR";
700 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER,
701 cipher, 0);
702 }
703 if (dgbl->rng_digest != NULL
704 && OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_DIGEST))
705 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST,
706 dgbl->rng_digest, 0);
707 if (prov_name != NULL)
708 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_CORE_PROV_NAME,
709 (char *)prov_name, 0);
710 if (dgbl->rng_propq != NULL)
711 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES,
712 dgbl->rng_propq, 0);
713 if (OSSL_PARAM_locate_const(settables, OSSL_ALG_PARAM_MAC))
714 *p++ = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_MAC, "HMAC", 0);
715 if (OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_USE_DF))
716 *p++ = OSSL_PARAM_construct_int(OSSL_DRBG_PARAM_USE_DF, &use_df);
717 *p++ = OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_REQUESTS,
718 &reseed_interval);
719 *p++ = OSSL_PARAM_construct_time_t(OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL,
720 &reseed_time_interval);
721 *p = OSSL_PARAM_construct_end();
722 if (!EVP_RAND_instantiate(ctx, 0, 0, NULL, 0, params)) {
723 ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG);
724 EVP_RAND_CTX_free(ctx);
725 return NULL;
726 }
727 return ctx;
728 }
729
730 #if defined(FIPS_MODULE)
rand_new_crngt(OSSL_LIB_CTX * libctx,EVP_RAND_CTX * parent)731 static EVP_RAND_CTX *rand_new_crngt(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent)
732 {
733 EVP_RAND *rand;
734 EVP_RAND_CTX *ctx;
735
736 rand = EVP_RAND_fetch(libctx, "CRNG-TEST", "-fips");
737 if (rand == NULL) {
738 ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG);
739 return NULL;
740 }
741 ctx = EVP_RAND_CTX_new(rand, parent);
742 EVP_RAND_free(rand);
743 if (ctx == NULL) {
744 ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG);
745 return NULL;
746 }
747
748 if (!EVP_RAND_instantiate(ctx, 0, 0, NULL, 0, NULL)) {
749 ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG);
750 EVP_RAND_CTX_free(ctx);
751 return NULL;
752 }
753 return ctx;
754 }
755 #endif /* FIPS_MODULE */
756
757 /*
758 * Get the primary random generator.
759 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
760 *
761 */
rand_get0_primary(OSSL_LIB_CTX * ctx,RAND_GLOBAL * dgbl)762 static EVP_RAND_CTX *rand_get0_primary(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
763 {
764 EVP_RAND_CTX *ret, *seed, *newseed = NULL, *primary;
765
766 if (dgbl == NULL)
767 return NULL;
768
769 if (!CRYPTO_THREAD_read_lock(dgbl->lock))
770 return NULL;
771
772 ret = dgbl->primary;
773 seed = dgbl->seed;
774 CRYPTO_THREAD_unlock(dgbl->lock);
775
776 if (ret != NULL)
777 return ret;
778
779 #if !defined(FIPS_MODULE) || !defined(OPENSSL_NO_FIPS_JITTER)
780 /* Create a seed source for libcrypto or jitter enabled FIPS provider */
781 if (seed == NULL) {
782 ERR_set_mark();
783 seed = newseed = rand_new_seed(ctx);
784 ERR_pop_to_mark();
785 }
786 #endif /* !FIPS_MODULE || !OPENSSL_NO_FIPS_JITTER */
787
788 #if defined(FIPS_MODULE)
789 /* The FIPS provider has entropy health tests instead of the primary */
790 ret = rand_new_crngt(ctx, seed);
791 #else /* FIPS_MODULE */
792 ret = rand_new_drbg(ctx, seed, PRIMARY_RESEED_INTERVAL,
793 PRIMARY_RESEED_TIME_INTERVAL);
794 #endif /* FIPS_MODULE */
795
796 /*
797 * The primary DRBG may be shared between multiple threads so we must
798 * enable locking.
799 */
800 if (ret == NULL || !EVP_RAND_enable_locking(ret)) {
801 if (ret != NULL) {
802 ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_LOCKING);
803 EVP_RAND_CTX_free(ret);
804 }
805 if (newseed == NULL)
806 return NULL;
807 /* else carry on and store seed */
808 ret = NULL;
809 }
810
811 if (!CRYPTO_THREAD_write_lock(dgbl->lock))
812 return NULL;
813
814 primary = dgbl->primary;
815 if (primary != NULL) {
816 CRYPTO_THREAD_unlock(dgbl->lock);
817 EVP_RAND_CTX_free(ret);
818 EVP_RAND_CTX_free(newseed);
819 return primary;
820 }
821 if (newseed != NULL)
822 dgbl->seed = newseed;
823 dgbl->primary = ret;
824 CRYPTO_THREAD_unlock(dgbl->lock);
825
826 return ret;
827 }
828
829 /*
830 * Get the primary random generator.
831 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
832 *
833 */
RAND_get0_primary(OSSL_LIB_CTX * ctx)834 EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx)
835 {
836 RAND_GLOBAL *dgbl = rand_get_global(ctx);
837
838 return dgbl == NULL ? NULL : rand_get0_primary(ctx, dgbl);
839 }
840
rand_get0_public(OSSL_LIB_CTX * ctx,RAND_GLOBAL * dgbl)841 static EVP_RAND_CTX *rand_get0_public(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
842 {
843 EVP_RAND_CTX *rand, *primary;
844
845 if (dgbl == NULL)
846 return NULL;
847
848 rand = CRYPTO_THREAD_get_local(&dgbl->public);
849 if (rand == NULL) {
850 primary = rand_get0_primary(ctx, dgbl);
851 if (primary == NULL)
852 return NULL;
853
854 ctx = ossl_lib_ctx_get_concrete(ctx);
855
856 if (ctx == NULL)
857 return NULL;
858 /*
859 * If the private is also NULL then this is the first time we've
860 * used this thread.
861 */
862 if (CRYPTO_THREAD_get_local(&dgbl->private) == NULL
863 && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state))
864 return NULL;
865 rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL,
866 SECONDARY_RESEED_TIME_INTERVAL);
867 CRYPTO_THREAD_set_local(&dgbl->public, rand);
868 }
869 return rand;
870 }
871
872 /*
873 * Get the public random generator.
874 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
875 */
RAND_get0_public(OSSL_LIB_CTX * ctx)876 EVP_RAND_CTX *RAND_get0_public(OSSL_LIB_CTX *ctx)
877 {
878 RAND_GLOBAL *dgbl = rand_get_global(ctx);
879
880 return dgbl == NULL ? NULL : rand_get0_public(ctx, dgbl);
881 }
882
rand_get0_private(OSSL_LIB_CTX * ctx,RAND_GLOBAL * dgbl)883 static EVP_RAND_CTX *rand_get0_private(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl)
884 {
885 EVP_RAND_CTX *rand, *primary;
886
887 rand = CRYPTO_THREAD_get_local(&dgbl->private);
888 if (rand == NULL) {
889 primary = rand_get0_primary(ctx, dgbl);
890 if (primary == NULL)
891 return NULL;
892
893 ctx = ossl_lib_ctx_get_concrete(ctx);
894
895 if (ctx == NULL)
896 return NULL;
897 /*
898 * If the public is also NULL then this is the first time we've
899 * used this thread.
900 */
901 if (CRYPTO_THREAD_get_local(&dgbl->public) == NULL
902 && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state))
903 return NULL;
904 rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL,
905 SECONDARY_RESEED_TIME_INTERVAL);
906 CRYPTO_THREAD_set_local(&dgbl->private, rand);
907 }
908 return rand;
909 }
910
911 /*
912 * Get the private random generator.
913 * Returns pointer to its EVP_RAND_CTX on success, NULL on failure.
914 */
RAND_get0_private(OSSL_LIB_CTX * ctx)915 EVP_RAND_CTX *RAND_get0_private(OSSL_LIB_CTX *ctx)
916 {
917 RAND_GLOBAL *dgbl = rand_get_global(ctx);
918
919 return dgbl == NULL ? NULL : rand_get0_private(ctx, dgbl);
920 }
921
922 #ifdef FIPS_MODULE
ossl_rand_get0_private_noncreating(OSSL_LIB_CTX * ctx)923 EVP_RAND_CTX *ossl_rand_get0_private_noncreating(OSSL_LIB_CTX *ctx)
924 {
925 RAND_GLOBAL *dgbl = rand_get_global(ctx);
926
927 if (dgbl == NULL)
928 return NULL;
929
930 return CRYPTO_THREAD_get_local(&dgbl->private);
931 }
932 #endif
933
RAND_set0_public(OSSL_LIB_CTX * ctx,EVP_RAND_CTX * rand)934 int RAND_set0_public(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand)
935 {
936 RAND_GLOBAL *dgbl = rand_get_global(ctx);
937 EVP_RAND_CTX *old;
938 int r;
939
940 if (dgbl == NULL)
941 return 0;
942 old = CRYPTO_THREAD_get_local(&dgbl->public);
943 if ((r = CRYPTO_THREAD_set_local(&dgbl->public, rand)) > 0)
944 EVP_RAND_CTX_free(old);
945 return r;
946 }
947
RAND_set0_private(OSSL_LIB_CTX * ctx,EVP_RAND_CTX * rand)948 int RAND_set0_private(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand)
949 {
950 RAND_GLOBAL *dgbl = rand_get_global(ctx);
951 EVP_RAND_CTX *old;
952 int r;
953
954 if (dgbl == NULL)
955 return 0;
956 old = CRYPTO_THREAD_get_local(&dgbl->private);
957 if ((r = CRYPTO_THREAD_set_local(&dgbl->private, rand)) > 0)
958 EVP_RAND_CTX_free(old);
959 return r;
960 }
961
962 #ifndef FIPS_MODULE
random_set_string(char ** p,const char * s)963 static int random_set_string(char **p, const char *s)
964 {
965 char *d = NULL;
966
967 if (s != NULL) {
968 d = OPENSSL_strdup(s);
969 if (d == NULL)
970 return 0;
971 }
972 OPENSSL_free(*p);
973 *p = d;
974 return 1;
975 }
976
977 /*
978 * Load the DRBG definitions from a configuration file.
979 */
random_conf_init(CONF_IMODULE * md,const CONF * cnf)980 static int random_conf_init(CONF_IMODULE *md, const CONF *cnf)
981 {
982 STACK_OF(CONF_VALUE) *elist;
983 CONF_VALUE *cval;
984 OSSL_LIB_CTX *libctx = NCONF_get0_libctx((CONF *)cnf);
985 RAND_GLOBAL *dgbl = rand_get_global(libctx);
986 int i, r = 1;
987
988 OSSL_TRACE1(CONF, "Loading random module: section %s\n",
989 CONF_imodule_get_value(md));
990
991 /* Value is a section containing RANDOM configuration */
992 elist = NCONF_get_section(cnf, CONF_imodule_get_value(md));
993 if (elist == NULL) {
994 ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_RANDOM_SECTION_ERROR);
995 return 0;
996 }
997
998 if (dgbl == NULL)
999 return 0;
1000
1001 for (i = 0; i < sk_CONF_VALUE_num(elist); i++) {
1002 cval = sk_CONF_VALUE_value(elist, i);
1003 if (OPENSSL_strcasecmp(cval->name, "random") == 0) {
1004 if (!random_set_string(&dgbl->rng_name, cval->value))
1005 return 0;
1006 } else if (OPENSSL_strcasecmp(cval->name, "cipher") == 0) {
1007 if (!random_set_string(&dgbl->rng_cipher, cval->value))
1008 return 0;
1009 } else if (OPENSSL_strcasecmp(cval->name, "digest") == 0) {
1010 if (!random_set_string(&dgbl->rng_digest, cval->value))
1011 return 0;
1012 } else if (OPENSSL_strcasecmp(cval->name, "properties") == 0) {
1013 if (!random_set_string(&dgbl->rng_propq, cval->value))
1014 return 0;
1015 } else if (OPENSSL_strcasecmp(cval->name, "seed") == 0) {
1016 if (!random_set_string(&dgbl->seed_name, cval->value))
1017 return 0;
1018 } else if (OPENSSL_strcasecmp(cval->name, "seed_properties") == 0) {
1019 if (!random_set_string(&dgbl->seed_propq, cval->value))
1020 return 0;
1021 } else if (OPENSSL_strcasecmp(cval->name, "random_provider") == 0) {
1022 #ifndef FIPS_MODULE
1023 OSSL_PROVIDER *prov = ossl_provider_find(libctx, cval->value, 0);
1024
1025 if (prov != NULL) {
1026 if (!RAND_set1_random_provider(libctx, prov)) {
1027 ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR);
1028 OSSL_PROVIDER_unload(prov);
1029 return 0;
1030 }
1031 /*
1032 * We need to release the reference from ossl_provider_find because
1033 * we don't want to keep a reference counted handle to the provider.
1034 *
1035 * The provider unload code checks for the random provider and,
1036 * if present, our reference will be NULLed when it is fully freed.
1037 * The provider load code, conversely, checks the provider name
1038 * and re-hooks our reference if required. This means that a load,
1039 * hook random provider, use, unload, reload, reuse sequence will
1040 * work as expected.
1041 */
1042 OSSL_PROVIDER_unload(prov);
1043 } else if (!set_random_provider_name(dgbl, cval->value))
1044 return 0;
1045 #endif
1046 } else {
1047 ERR_raise_data(ERR_LIB_CRYPTO,
1048 CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION,
1049 "name=%s, value=%s", cval->name, cval->value);
1050 r = 0;
1051 }
1052 }
1053 return r;
1054 }
1055
random_conf_deinit(CONF_IMODULE * md)1056 static void random_conf_deinit(CONF_IMODULE *md)
1057 {
1058 OSSL_TRACE(CONF, "Cleaned up random\n");
1059 }
1060
ossl_random_add_conf_module(void)1061 void ossl_random_add_conf_module(void)
1062 {
1063 OSSL_TRACE(CONF, "Adding config module 'random'\n");
1064 CONF_module_add("random", random_conf_init, random_conf_deinit);
1065 }
1066
RAND_set_DRBG_type(OSSL_LIB_CTX * ctx,const char * drbg,const char * propq,const char * cipher,const char * digest)1067 int RAND_set_DRBG_type(OSSL_LIB_CTX *ctx, const char *drbg, const char *propq,
1068 const char *cipher, const char *digest)
1069 {
1070 RAND_GLOBAL *dgbl = rand_get_global(ctx);
1071
1072 if (dgbl == NULL)
1073 return 0;
1074 if (dgbl->primary != NULL) {
1075 ERR_raise(ERR_LIB_RAND, RAND_R_ALREADY_INSTANTIATED);
1076 return 0;
1077 }
1078 return random_set_string(&dgbl->rng_name, drbg)
1079 && random_set_string(&dgbl->rng_propq, propq)
1080 && random_set_string(&dgbl->rng_cipher, cipher)
1081 && random_set_string(&dgbl->rng_digest, digest);
1082 }
1083
RAND_set_seed_source_type(OSSL_LIB_CTX * ctx,const char * seed,const char * propq)1084 int RAND_set_seed_source_type(OSSL_LIB_CTX *ctx, const char *seed,
1085 const char *propq)
1086 {
1087 RAND_GLOBAL *dgbl = rand_get_global(ctx);
1088
1089 if (dgbl == NULL)
1090 return 0;
1091 if (dgbl->seed != NULL) {
1092 ERR_raise(ERR_LIB_RAND, RAND_R_ALREADY_INSTANTIATED);
1093 return 0;
1094 }
1095 return random_set_string(&dgbl->seed_name, seed)
1096 && random_set_string(&dgbl->seed_propq, propq);
1097 }
1098
RAND_set1_random_provider(OSSL_LIB_CTX * ctx,OSSL_PROVIDER * prov)1099 int RAND_set1_random_provider(OSSL_LIB_CTX *ctx, OSSL_PROVIDER *prov)
1100 {
1101 RAND_GLOBAL *dgbl = rand_get_global(ctx);
1102
1103 if (dgbl == NULL)
1104 return 0;
1105
1106 if (prov == NULL) {
1107 OPENSSL_free(dgbl->random_provider_name);
1108 dgbl->random_provider_name = NULL;
1109 dgbl->random_provider = NULL;
1110 return 1;
1111 }
1112
1113 if (dgbl->random_provider == prov)
1114 return 1;
1115
1116 if (!set_random_provider_name(dgbl, OSSL_PROVIDER_get0_name(prov)))
1117 return 0;
1118
1119 dgbl->random_provider = prov;
1120 return 1;
1121 }
1122
1123 /*
1124 * When a new provider is loaded, we need to check to see if it is the
1125 * designated randomness provider and register it if it is.
1126 */
ossl_rand_check_random_provider_on_load(OSSL_LIB_CTX * ctx,OSSL_PROVIDER * prov)1127 int ossl_rand_check_random_provider_on_load(OSSL_LIB_CTX *ctx,
1128 OSSL_PROVIDER *prov)
1129 {
1130 RAND_GLOBAL *dgbl = rand_get_global(ctx);
1131
1132 if (dgbl == NULL)
1133 return 0;
1134
1135 /* No random provider name specified, or one is installed already */
1136 if (dgbl->random_provider_name == NULL || dgbl->random_provider != NULL)
1137 return 1;
1138
1139 /* Does this provider match the name we're using? */
1140 if (strcmp(dgbl->random_provider_name, OSSL_PROVIDER_get0_name(prov)) != 0)
1141 return 1;
1142
1143 dgbl->random_provider = prov;
1144 return 1;
1145 }
1146
1147 /*
1148 * When a provider is being unloaded, if it is the randomness provider,
1149 * we need to deregister it.
1150 */
ossl_rand_check_random_provider_on_unload(OSSL_LIB_CTX * ctx,OSSL_PROVIDER * prov)1151 int ossl_rand_check_random_provider_on_unload(OSSL_LIB_CTX *ctx,
1152 OSSL_PROVIDER *prov)
1153 {
1154 RAND_GLOBAL *dgbl = rand_get_global(ctx);
1155
1156 if (dgbl == NULL)
1157 return 0;
1158
1159 if (dgbl->random_provider == prov)
1160 dgbl->random_provider = NULL;
1161 return 1;
1162 }
1163
1164 #endif /* !FIPS_MODULE */
1165