2 * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved.
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
11 #include <openssl/crypto.h>
12 #include <openssl/err.h>
13 #include <openssl/rand.h>
14 #include <openssl/evp.h>
15 #include "crypto/rand.h"
16 #include "drbg_local.h"
17 #include "internal/thread_once.h"
18 #include "crypto/cryptlib.h"
19 #include "prov/seeding.h"
20 #include "prov/rand_pool.h"
21 #include "prov/provider_ctx.h"
22 #include "prov/providercommonerr.h"
25 * Support framework for NIST SP 800-90A DRBG
27 * See manual page PROV_DRBG(7) for a general overview.
29 * The OpenSSL model is to have new and free functions, and that new
30 * does all initialization. That is not the NIST model, which has
31 * instantiation and un-instantiate, and re-use within a new/free
32 * lifecycle. (No doubt this comes from the desire to support hardware
33 * DRBG, where allocation of resources on something like an HSM is
34 * a much bigger deal than just re-setting an allocated resource.)
37 /* NIST SP 800-90A DRBG recommends the use of a personalization string. */
38 static const char ossl_pers_string
[] = DRBG_DEFAULT_PERS_STRING
;
40 static const OSSL_DISPATCH
*find_call(const OSSL_DISPATCH
*dispatch
,
43 static int rand_drbg_restart(PROV_DRBG
*drbg
);
45 int drbg_lock(void *vctx
)
47 PROV_DRBG
*drbg
= vctx
;
49 if (drbg
== NULL
|| drbg
->lock
== NULL
)
51 return CRYPTO_THREAD_write_lock(drbg
->lock
);
54 void drbg_unlock(void *vctx
)
56 PROV_DRBG
*drbg
= vctx
;
58 if (drbg
!= NULL
&& drbg
->lock
!= NULL
)
59 CRYPTO_THREAD_unlock(drbg
->lock
);
62 static int drbg_lock_parent(PROV_DRBG
*drbg
)
64 void *parent
= drbg
->parent
;
67 && drbg
->parent_lock
!= NULL
68 && !drbg
->parent_lock(parent
)) {
69 ERR_raise(ERR_LIB_PROV
, PROV_R_PARENT_LOCKING_NOT_ENABLED
);
75 static void drbg_unlock_parent(PROV_DRBG
*drbg
)
77 void *parent
= drbg
->parent
;
79 if (parent
!= NULL
&& drbg
->parent_unlock
!= NULL
)
80 drbg
->parent_unlock(parent
);
83 static int get_parent_strength(PROV_DRBG
*drbg
, unsigned int *str
)
85 OSSL_PARAM params
[2] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
86 void *parent
= drbg
->parent
;
89 if (drbg
->parent_get_ctx_params
== NULL
) {
90 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH
);
94 *params
= OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH
, str
);
95 if (!drbg_lock_parent(drbg
)) {
96 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_LOCK_PARENT
);
99 res
= drbg
->parent_get_ctx_params(parent
, params
);
100 drbg_unlock_parent(drbg
);
102 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH
);
108 static unsigned int get_parent_reseed_count(PROV_DRBG
*drbg
)
110 OSSL_PARAM params
[2] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
111 void *parent
= drbg
->parent
;
114 *params
= OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_CTR
, &r
);
115 if (!drbg_lock_parent(drbg
)) {
116 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_LOCK_PARENT
);
119 if (!drbg
->parent_get_ctx_params(parent
, params
)) {
120 drbg_unlock_parent(drbg
);
121 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_GET_RESEED_PROP_CTR
);
124 drbg_unlock_parent(drbg
);
128 r
= tsan_load(&drbg
->reseed_counter
) - 2;
135 * Implements the get_entropy() callback (see RAND_DRBG_set_callbacks())
137 * If the DRBG has a parent, then the required amount of entropy input
138 * is fetched using the parent's RAND_DRBG_generate().
140 * Otherwise, the entropy is polled from the system entropy sources
141 * using prov_pool_acquire_entropy().
143 * If a random pool has been added to the DRBG using RAND_add(), then
144 * its entropy will be used up first.
146 static size_t prov_drbg_get_entropy(PROV_DRBG
*drbg
, unsigned char **pout
,
147 int entropy
, size_t min_len
,
148 size_t max_len
, int prediction_resistance
)
151 size_t entropy_available
= 0;
155 if (drbg
->parent
!= NULL
) {
156 if (!get_parent_strength(drbg
, &p_str
))
158 if (drbg
->strength
> p_str
) {
160 * We currently don't support the algorithm from NIST SP 800-90C
161 * 10.1.2 to use a weaker DRBG as source
163 RANDerr(0, PROV_R_PARENT_STRENGTH_TOO_WEAK
);
168 if (drbg
->seed_pool
!= NULL
) {
169 pool
= drbg
->seed_pool
;
170 pool
->entropy_requested
= entropy
;
172 pool
= rand_pool_new(entropy
, 1, min_len
, max_len
);
174 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
179 if (drbg
->parent
!= NULL
) {
180 size_t bytes_needed
= rand_pool_bytes_needed(pool
, 1 /*entropy_factor*/);
181 unsigned char *buffer
= rand_pool_add_begin(pool
, bytes_needed
);
183 if (buffer
!= NULL
) {
187 * Get random data from parent. Include our address as additional input,
188 * in order to provide some additional distinction between different
189 * DRBG child instances.
190 * Our lock is already held, but we need to lock our parent before
191 * generating bits from it. (Note: taking the lock will be a no-op
192 * if locking if drbg->parent->lock == NULL.)
194 if (drbg
->parent_generate
== NULL
)
196 drbg_lock_parent(drbg
);
197 if (drbg
->parent_generate(drbg
->parent
, buffer
, bytes_needed
,
198 drbg
->strength
, prediction_resistance
,
199 (unsigned char *)&drbg
,
201 bytes
= bytes_needed
;
202 drbg_unlock_parent(drbg
);
203 drbg
->parent_reseed_counter
= get_parent_reseed_count(drbg
);
205 rand_pool_add_end(pool
, bytes
, 8 * bytes
);
206 entropy_available
= rand_pool_entropy_available(pool
);
209 /* Get entropy by polling system entropy sources. */
210 entropy_available
= prov_pool_acquire_entropy(pool
);
213 if (entropy_available
> 0) {
214 ret
= rand_pool_length(pool
);
215 *pout
= rand_pool_detach(pool
);
219 if (drbg
->seed_pool
== NULL
)
220 rand_pool_free(pool
);
225 * Implements the cleanup_entropy() callback (see RAND_DRBG_set_callbacks())
228 static void prov_drbg_cleanup_entropy(PROV_DRBG
*drbg
,
229 unsigned char *out
, size_t outlen
)
231 if (drbg
->seed_pool
== NULL
) {
232 OPENSSL_secure_clear_free(out
, outlen
);
236 static size_t get_entropy(PROV_DRBG
*drbg
, unsigned char **pout
, int entropy
,
237 size_t min_len
, size_t max_len
,
238 int prediction_resistance
)
241 if (drbg
->parent
== NULL
)
242 return prov_crngt_get_entropy(drbg
, pout
, entropy
, min_len
, max_len
,
243 prediction_resistance
);
246 return prov_drbg_get_entropy(drbg
, pout
, entropy
, min_len
, max_len
,
247 prediction_resistance
);
250 static void cleanup_entropy(PROV_DRBG
*drbg
, unsigned char *out
, size_t outlen
)
253 if (drbg
->parent
== NULL
)
254 prov_crngt_cleanup_entropy(drbg
, out
, outlen
);
257 prov_drbg_cleanup_entropy(drbg
, out
, outlen
);
260 #ifndef PROV_RAND_GET_RANDOM_NONCE
261 typedef struct prov_drbg_nonce_global_st
{
262 CRYPTO_RWLOCK
*rand_nonce_lock
;
263 int rand_nonce_count
;
264 } PROV_DRBG_NONCE_GLOBAL
;
267 * drbg_ossl_ctx_new() calls drgb_setup() which calls rand_drbg_get_nonce()
268 * which needs to get the rand_nonce_lock out of the OPENSSL_CTX...but since
269 * drbg_ossl_ctx_new() hasn't finished running yet we need the rand_nonce_lock
270 * to be in a different global data object. Otherwise we will go into an
271 * infinite recursion loop.
273 static void *prov_drbg_nonce_ossl_ctx_new(OPENSSL_CTX
*libctx
)
275 PROV_DRBG_NONCE_GLOBAL
*dngbl
= OPENSSL_zalloc(sizeof(*dngbl
));
280 dngbl
->rand_nonce_lock
= CRYPTO_THREAD_lock_new();
281 if (dngbl
->rand_nonce_lock
== NULL
) {
289 static void prov_drbg_nonce_ossl_ctx_free(void *vdngbl
)
291 PROV_DRBG_NONCE_GLOBAL
*dngbl
= vdngbl
;
296 CRYPTO_THREAD_lock_free(dngbl
->rand_nonce_lock
);
301 static const OPENSSL_CTX_METHOD drbg_nonce_ossl_ctx_method
= {
302 prov_drbg_nonce_ossl_ctx_new
,
303 prov_drbg_nonce_ossl_ctx_free
,
306 /* Get a nonce from the operating system */
307 static size_t prov_drbg_get_nonce(PROV_DRBG
*drbg
,
308 unsigned char **pout
,
309 int entropy
, size_t min_len
, size_t max_len
)
313 unsigned char *buf
= NULL
;
314 OPENSSL_CTX
*libctx
= PROV_LIBRARY_CONTEXT_OF(drbg
->provctx
);
315 PROV_DRBG_NONCE_GLOBAL
*dngbl
316 = openssl_ctx_get_data(libctx
, OPENSSL_CTX_DRBG_NONCE_INDEX
,
317 &drbg_nonce_ossl_ctx_method
);
326 if (drbg
->parent
!= NULL
) {
327 if (drbg
->parent_nonce
!= NULL
) {
328 n
= drbg
->parent_nonce(drbg
->parent
, NULL
, 0, drbg
->min_noncelen
,
330 if (n
> 0 && (buf
= OPENSSL_malloc(n
)) != NULL
) {
331 ret
= drbg
->parent_nonce(drbg
->parent
, buf
, 0,
343 /* Use the built in nonce source */
344 memset(&data
, 0, sizeof(data
));
345 pool
= rand_pool_new(0, 0, min_len
, max_len
);
349 if (prov_pool_add_nonce_data(pool
) == 0)
352 data
.instance
= drbg
;
353 CRYPTO_atomic_add(&dngbl
->rand_nonce_count
, 1, &data
.count
,
354 dngbl
->rand_nonce_lock
);
356 if (rand_pool_add(pool
, (unsigned char *)&data
, sizeof(data
), 0) == 0)
359 ret
= rand_pool_length(pool
);
360 *pout
= rand_pool_detach(pool
);
363 rand_pool_free(pool
);
368 static void prov_drbg_clear_nonce(PROV_DRBG
*drbg
, unsigned char *nonce
,
371 OPENSSL_clear_free(nonce
, noncelen
);
374 # define prov_drbg_clear_nonce(drbg, nonce, len) \
375 OPENSSL_clear_free((nonce), (len))
376 #endif /* PROV_RAND_GET_RANDOM_NONCE */
379 * Instantiate |drbg|, after it has been initialized. Use |pers| and
380 * |perslen| as prediction-resistance input.
382 * Requires that drbg->lock is already locked for write, if non-null.
384 * Returns 1 on success, 0 on failure.
386 int PROV_DRBG_instantiate(PROV_DRBG
*drbg
, unsigned int strength
,
387 int prediction_resistance
,
388 const unsigned char *pers
, size_t perslen
)
390 unsigned char *nonce
= NULL
, *entropy
= NULL
;
391 size_t noncelen
= 0, entropylen
= 0;
392 size_t min_entropy
, min_entropylen
, max_entropylen
;
394 if (strength
> drbg
->strength
) {
395 PROVerr(0, PROV_R_INSUFFICIENT_DRBG_STRENGTH
);
398 min_entropy
= drbg
->strength
;
399 min_entropylen
= drbg
->min_entropylen
;
400 max_entropylen
= drbg
->max_entropylen
;
403 pers
= (const unsigned char *)ossl_pers_string
;
404 perslen
= sizeof(ossl_pers_string
);
406 if (perslen
> drbg
->max_perslen
) {
407 PROVerr(0, PROV_R_PERSONALISATION_STRING_TOO_LONG
);
411 if (drbg
->state
!= EVP_RAND_STATE_UNINITIALISED
) {
412 if (drbg
->state
== EVP_RAND_STATE_ERROR
)
413 PROVerr(0, PROV_R_IN_ERROR_STATE
);
415 PROVerr(0, PROV_R_ALREADY_INSTANTIATED
);
419 drbg
->state
= EVP_RAND_STATE_ERROR
;
421 if (drbg
->min_noncelen
> 0) {
422 if (drbg
->parent_nonce
!= NULL
) {
423 noncelen
= drbg
->parent_nonce(drbg
->parent
, NULL
, drbg
->strength
,
427 PROVerr(0, PROV_R_ERROR_RETRIEVING_NONCE
);
430 nonce
= OPENSSL_malloc(noncelen
);
432 PROVerr(0, PROV_R_ERROR_RETRIEVING_NONCE
);
435 if (noncelen
!= drbg
->parent_nonce(drbg
->parent
, nonce
,
438 drbg
->max_noncelen
)) {
439 PROVerr(0, PROV_R_ERROR_RETRIEVING_NONCE
);
442 #ifndef PROV_RAND_GET_RANDOM_NONCE
443 } else if (drbg
->parent
!= NULL
) {
446 * NIST SP800-90Ar1 section 9.1 says you can combine getting
447 * the entropy and nonce in 1 call by increasing the entropy
448 * with 50% and increasing the minimum length to accommodate
449 * the length of the nonce. We do this in case a nonce is
450 * required and there is no parental nonce capability.
452 min_entropy
+= drbg
->strength
/ 2;
453 min_entropylen
+= drbg
->min_noncelen
;
454 max_entropylen
+= drbg
->max_noncelen
;
456 #ifndef PROV_RAND_GET_RANDOM_NONCE
457 else { /* parent == NULL */
458 noncelen
= prov_drbg_get_nonce(drbg
, &nonce
, drbg
->strength
/ 2,
461 if (noncelen
< drbg
->min_noncelen
462 || noncelen
> drbg
->max_noncelen
) {
463 PROVerr(0, PROV_R_ERROR_RETRIEVING_NONCE
);
470 drbg
->reseed_next_counter
= tsan_load(&drbg
->reseed_counter
);
471 if (drbg
->reseed_next_counter
) {
472 drbg
->reseed_next_counter
++;
473 if (!drbg
->reseed_next_counter
)
474 drbg
->reseed_next_counter
= 1;
477 entropylen
= get_entropy(drbg
, &entropy
, min_entropy
,
478 min_entropylen
, max_entropylen
,
479 prediction_resistance
);
480 if (entropylen
< min_entropylen
481 || entropylen
> max_entropylen
) {
482 PROVerr(0, PROV_R_ERROR_RETRIEVING_ENTROPY
);
486 if (!drbg
->instantiate(drbg
, entropy
, entropylen
, nonce
, noncelen
,
488 PROVerr(0, PROV_R_ERROR_INSTANTIATING_DRBG
);
492 drbg
->state
= EVP_RAND_STATE_READY
;
493 drbg
->reseed_gen_counter
= 1;
494 drbg
->reseed_time
= time(NULL
);
495 tsan_store(&drbg
->reseed_counter
, drbg
->reseed_next_counter
);
499 cleanup_entropy(drbg
, entropy
, entropylen
);
500 prov_drbg_clear_nonce(drbg
, nonce
, noncelen
);
501 if (drbg
->state
== EVP_RAND_STATE_READY
)
507 * Uninstantiate |drbg|. Must be instantiated before it can be used.
509 * Requires that drbg->lock is already locked for write, if non-null.
511 * Returns 1 on success, 0 on failure.
513 int PROV_DRBG_uninstantiate(PROV_DRBG
*drbg
)
515 drbg
->state
= EVP_RAND_STATE_UNINITIALISED
;
520 * Reseed |drbg|, mixing in the specified data
522 * Requires that drbg->lock is already locked for write, if non-null.
524 * Returns 1 on success, 0 on failure.
526 int PROV_DRBG_reseed(PROV_DRBG
*drbg
, int prediction_resistance
,
527 const unsigned char *ent
, size_t ent_len
,
528 const unsigned char *adin
, size_t adinlen
)
530 unsigned char *entropy
= NULL
;
531 size_t entropylen
= 0;
533 if (drbg
->state
!= EVP_RAND_STATE_READY
) {
534 /* try to recover from previous errors */
535 rand_drbg_restart(drbg
);
537 if (drbg
->state
== EVP_RAND_STATE_ERROR
) {
538 PROVerr(0, PROV_R_IN_ERROR_STATE
);
541 if (drbg
->state
== EVP_RAND_STATE_UNINITIALISED
) {
542 PROVerr(0, PROV_R_NOT_INSTANTIATED
);
548 if (ent_len
< drbg
->min_entropylen
) {
549 RANDerr(0, RAND_R_ENTROPY_OUT_OF_RANGE
);
550 drbg
->state
= EVP_RAND_STATE_ERROR
;
553 if (ent_len
> drbg
->max_entropylen
) {
554 RANDerr(0, RAND_R_ENTROPY_INPUT_TOO_LONG
);
555 drbg
->state
= EVP_RAND_STATE_ERROR
;
562 } else if (adinlen
> drbg
->max_adinlen
) {
563 PROVerr(0, PROV_R_ADDITIONAL_INPUT_TOO_LONG
);
567 drbg
->state
= EVP_RAND_STATE_ERROR
;
569 drbg
->reseed_next_counter
= tsan_load(&drbg
->reseed_counter
);
570 if (drbg
->reseed_next_counter
) {
571 drbg
->reseed_next_counter
++;
572 if (!drbg
->reseed_next_counter
)
573 drbg
->reseed_next_counter
= 1;
579 * NIST SP-800-90A mandates that entropy *shall not* be provided
580 * by the consuming application. Instead the data is added as additional
583 * (NIST SP-800-90Ar1, Sections 9.1 and 9.2)
585 if (!drbg
->reseed(drbg
, NULL
, 0, ent
, ent_len
)) {
586 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_RESEED
);
590 if (!drbg
->reseed(drbg
, ent
, ent_len
, adin
, adinlen
)) {
591 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_RESEED
);
594 /* There isn't much point adding the same additional input twice */
600 /* Reseed using our sources in addition */
601 entropylen
= get_entropy(drbg
, &entropy
, drbg
->strength
,
602 drbg
->min_entropylen
, drbg
->max_entropylen
,
603 prediction_resistance
);
604 if (entropylen
< drbg
->min_entropylen
605 || entropylen
> drbg
->max_entropylen
) {
606 PROVerr(0, PROV_R_ERROR_RETRIEVING_ENTROPY
);
610 if (!drbg
->reseed(drbg
, entropy
, entropylen
, adin
, adinlen
))
613 drbg
->state
= EVP_RAND_STATE_READY
;
614 drbg
->reseed_gen_counter
= 1;
615 drbg
->reseed_time
= time(NULL
);
616 tsan_store(&drbg
->reseed_counter
, drbg
->reseed_next_counter
);
617 if (drbg
->parent
!= NULL
)
618 drbg
->parent_reseed_counter
= get_parent_reseed_count(drbg
);
621 cleanup_entropy(drbg
, entropy
, entropylen
);
622 if (drbg
->state
== EVP_RAND_STATE_READY
)
628 * Generate |outlen| bytes into the buffer at |out|. Reseed if we need
629 * to or if |prediction_resistance| is set. Additional input can be
630 * sent in |adin| and |adinlen|.
632 * Requires that drbg->lock is already locked for write, if non-null.
634 * Returns 1 on success, 0 on failure.
637 int PROV_DRBG_generate(PROV_DRBG
*drbg
, unsigned char *out
, size_t outlen
,
638 unsigned int strength
, int prediction_resistance
,
639 const unsigned char *adin
, size_t adinlen
)
642 int reseed_required
= 0;
644 if (drbg
->state
!= EVP_RAND_STATE_READY
) {
645 /* try to recover from previous errors */
646 rand_drbg_restart(drbg
);
648 if (drbg
->state
== EVP_RAND_STATE_ERROR
) {
649 PROVerr(0, PROV_R_IN_ERROR_STATE
);
652 if (drbg
->state
== EVP_RAND_STATE_UNINITIALISED
) {
653 PROVerr(0, PROV_R_NOT_INSTANTIATED
);
657 if (strength
> drbg
->strength
) {
658 PROVerr(0, PROV_R_INSUFFICIENT_DRBG_STRENGTH
);
662 if (outlen
> drbg
->max_request
) {
663 PROVerr(0, PROV_R_REQUEST_TOO_LARGE_FOR_DRBG
);
666 if (adinlen
> drbg
->max_adinlen
) {
667 PROVerr(0, PROV_R_ADDITIONAL_INPUT_TOO_LONG
);
671 fork_id
= openssl_get_fork_id();
673 if (drbg
->fork_id
!= fork_id
) {
674 drbg
->fork_id
= fork_id
;
678 if (drbg
->reseed_interval
> 0) {
679 if (drbg
->reseed_gen_counter
>= drbg
->reseed_interval
)
682 if (drbg
->reseed_time_interval
> 0) {
683 time_t now
= time(NULL
);
684 if (now
< drbg
->reseed_time
685 || now
- drbg
->reseed_time
>= drbg
->reseed_time_interval
)
688 if (drbg
->parent
!= NULL
689 && get_parent_reseed_count(drbg
) != drbg
->parent_reseed_counter
)
692 if (reseed_required
|| prediction_resistance
) {
693 if (!PROV_DRBG_reseed(drbg
, prediction_resistance
, NULL
, 0,
695 PROVerr(0, PROV_R_RESEED_ERROR
);
702 if (!drbg
->generate(drbg
, out
, outlen
, adin
, adinlen
)) {
703 drbg
->state
= EVP_RAND_STATE_ERROR
;
704 PROVerr(0, PROV_R_GENERATE_ERROR
);
708 drbg
->reseed_gen_counter
++;
714 * Restart |drbg|, using the specified entropy or additional input
716 * Tries its best to get the drbg instantiated by all means,
717 * regardless of its current state.
719 * Optionally, a |buffer| of |len| random bytes can be passed,
720 * which is assumed to contain at least |entropy| bits of entropy.
722 * If |entropy| > 0, the buffer content is used as entropy input.
724 * If |entropy| == 0, the buffer content is used as additional input
726 * Returns 1 on success, 0 on failure.
728 * This function is used internally only.
730 static int rand_drbg_restart(PROV_DRBG
*drbg
)
732 if (drbg
->seed_pool
!= NULL
) {
733 drbg
->state
= EVP_RAND_STATE_ERROR
;
734 rand_pool_free(drbg
->seed_pool
);
735 drbg
->seed_pool
= NULL
;
736 RANDerr(0, ERR_R_INTERNAL_ERROR
);
740 /* repair error state */
741 if (drbg
->state
== EVP_RAND_STATE_ERROR
)
742 drbg
->uninstantiate(drbg
);
744 /* repair uninitialized state */
745 if (drbg
->state
== EVP_RAND_STATE_UNINITIALISED
)
746 /* reinstantiate drbg */
747 PROV_DRBG_instantiate(drbg
, drbg
->strength
, 0, NULL
, 0);
749 rand_pool_free(drbg
->seed_pool
);
750 drbg
->seed_pool
= NULL
;
751 return drbg
->state
== EVP_RAND_STATE_READY
;
754 /* Provider support from here down */
755 static const OSSL_DISPATCH
*find_call(const OSSL_DISPATCH
*dispatch
,
758 if (dispatch
!= NULL
)
759 while (dispatch
->function_id
!= 0) {
760 if (dispatch
->function_id
== function
)
767 int drbg_enable_locking(void *vctx
)
769 PROV_DRBG
*drbg
= vctx
;
771 if (drbg
!= NULL
&& drbg
->lock
== NULL
) {
772 if (drbg
->parent_enable_locking
!= NULL
)
773 if (!drbg
->parent_enable_locking(drbg
->parent
)) {
774 ERR_raise(ERR_LIB_PROV
, PROV_R_PARENT_LOCKING_NOT_ENABLED
);
777 drbg
->lock
= CRYPTO_THREAD_lock_new();
778 if (drbg
->lock
== NULL
) {
779 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_CREATE_LOCK
);
787 * Allocate memory and initialize a new DRBG. The DRBG is allocated on
788 * the secure heap if |secure| is nonzero and the secure heap is enabled.
789 * The |parent|, if not NULL, will be used as random source for reseeding.
790 * This also requires the parent's provider context and the parent's lock.
792 * Returns a pointer to the new DRBG instance on success, NULL on failure.
794 PROV_DRBG
*prov_rand_drbg_new
795 (void *provctx
, void *parent
, const OSSL_DISPATCH
*p_dispatch
,
796 int (*dnew
)(PROV_DRBG
*ctx
),
797 int (*instantiate
)(PROV_DRBG
*drbg
,
798 const unsigned char *entropy
, size_t entropylen
,
799 const unsigned char *nonce
, size_t noncelen
,
800 const unsigned char *pers
, size_t perslen
),
801 int (*uninstantiate
)(PROV_DRBG
*ctx
),
802 int (*reseed
)(PROV_DRBG
*drbg
, const unsigned char *ent
, size_t ent_len
,
803 const unsigned char *adin
, size_t adin_len
),
804 int (*generate
)(PROV_DRBG
*, unsigned char *out
, size_t outlen
,
805 const unsigned char *adin
, size_t adin_len
))
807 PROV_DRBG
*drbg
= OPENSSL_zalloc(sizeof(*drbg
));
809 const OSSL_DISPATCH
*pfunc
;
812 ERR_raise(ERR_LIB_PROV
, ERR_R_MALLOC_FAILURE
);
816 drbg
->provctx
= provctx
;
817 drbg
->instantiate
= instantiate
;
818 drbg
->uninstantiate
= uninstantiate
;
819 drbg
->reseed
= reseed
;
820 drbg
->generate
= generate
;
821 drbg
->fork_id
= openssl_get_fork_id();
823 /* Extract parent's functions */
824 drbg
->parent
= parent
;
825 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_ENABLE_LOCKING
)) != NULL
)
826 drbg
->parent_enable_locking
= OSSL_FUNC_rand_enable_locking(pfunc
);
827 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_LOCK
)) != NULL
)
828 drbg
->parent_lock
= OSSL_FUNC_rand_lock(pfunc
);
829 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_UNLOCK
)) != NULL
)
830 drbg
->parent_unlock
= OSSL_FUNC_rand_unlock(pfunc
);
831 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_GET_CTX_PARAMS
)) != NULL
)
832 drbg
->parent_get_ctx_params
= OSSL_FUNC_rand_get_ctx_params(pfunc
);
833 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_GENERATE
)) != NULL
)
834 drbg
->parent_generate
= OSSL_FUNC_rand_generate(pfunc
);
835 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_NONCE
)) != NULL
)
836 drbg
->parent_nonce
= OSSL_FUNC_rand_nonce(pfunc
);
838 /* Set some default maximums up */
839 drbg
->max_entropylen
= DRBG_MAX_LENGTH
;
840 drbg
->max_noncelen
= DRBG_MAX_LENGTH
;
841 drbg
->max_perslen
= DRBG_MAX_LENGTH
;
842 drbg
->max_adinlen
= DRBG_MAX_LENGTH
;
843 drbg
->reseed_gen_counter
= 1;
844 drbg
->reseed_counter
= 1;
845 drbg
->reseed_interval
= RESEED_INTERVAL
;
846 drbg
->reseed_time_interval
= TIME_INTERVAL
;
851 if (parent
!= NULL
) {
852 if (!get_parent_strength(drbg
, &p_str
))
854 if (drbg
->strength
> p_str
) {
856 * We currently don't support the algorithm from NIST SP 800-90C
857 * 10.1.2 to use a weaker DRBG as source
859 ERR_raise(ERR_LIB_PROV
, PROV_R_PARENT_STRENGTH_TOO_WEAK
);
866 prov_rand_drbg_free(drbg
);
870 void prov_rand_drbg_free(PROV_DRBG
*drbg
)
875 rand_pool_free(drbg
->adin_pool
);
876 CRYPTO_THREAD_lock_free(drbg
->lock
);
880 int drbg_get_ctx_params(PROV_DRBG
*drbg
, OSSL_PARAM params
[])
884 p
= OSSL_PARAM_locate(params
, OSSL_RAND_PARAM_STATE
);
885 if (p
!= NULL
&& !OSSL_PARAM_set_int(p
, drbg
->state
))
888 p
= OSSL_PARAM_locate(params
, OSSL_RAND_PARAM_STRENGTH
);
889 if (p
!= NULL
&& !OSSL_PARAM_set_int(p
, drbg
->strength
))
892 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MAX_REQUEST
);
893 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->max_request
))
896 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MIN_ENTROPYLEN
);
897 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->min_entropylen
))
900 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MAX_ENTROPYLEN
);
901 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->max_entropylen
))
904 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MIN_NONCELEN
);
905 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->min_noncelen
))
908 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MAX_NONCELEN
);
909 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->max_noncelen
))
912 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MAX_PERSLEN
);
913 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->max_perslen
))
916 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MAX_ADINLEN
);
917 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->max_adinlen
))
920 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_RESEED_REQUESTS
);
921 if (p
!= NULL
&& !OSSL_PARAM_set_uint(p
, drbg
->reseed_interval
))
924 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_RESEED_TIME
);
925 if (p
!= NULL
&& !OSSL_PARAM_set_time_t(p
, drbg
->reseed_time
))
928 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL
);
929 if (p
!= NULL
&& !OSSL_PARAM_set_time_t(p
, drbg
->reseed_time_interval
))
932 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_RESEED_CTR
);
934 && !OSSL_PARAM_set_uint(p
, tsan_load(&drbg
->reseed_counter
)))
939 int drbg_set_ctx_params(PROV_DRBG
*drbg
, const OSSL_PARAM params
[])
943 p
= OSSL_PARAM_locate_const(params
, OSSL_DRBG_PARAM_RESEED_REQUESTS
);
944 if (p
!= NULL
&& !OSSL_PARAM_get_uint(p
, &drbg
->reseed_interval
))
947 p
= OSSL_PARAM_locate_const(params
, OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL
);
948 if (p
!= NULL
&& !OSSL_PARAM_get_time_t(p
, &drbg
->reseed_time_interval
))