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