2 * Copyright 2011-2022 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 <openssl/proverr.h>
17 #include "drbg_local.h"
18 #include "internal/thread_once.h"
19 #include "crypto/cryptlib.h"
20 #include "prov/seeding.h"
21 #include "crypto/rand_pool.h"
22 #include "prov/provider_ctx.h"
23 #include "prov/providercommon.h"
24 #include "crypto/context.h"
27 * Support framework for NIST SP 800-90A DRBG
29 * See manual page PROV_DRBG(7) for a general overview.
31 * The OpenSSL model is to have new and free functions, and that new
32 * does all initialization. That is not the NIST model, which has
33 * instantiation and un-instantiate, and re-use within a new/free
34 * lifecycle. (No doubt this comes from the desire to support hardware
35 * DRBG, where allocation of resources on something like an HSM is
36 * a much bigger deal than just re-setting an allocated resource.)
39 /* NIST SP 800-90A DRBG recommends the use of a personalization string. */
40 static const char ossl_pers_string
[] = DRBG_DEFAULT_PERS_STRING
;
42 static const OSSL_DISPATCH
*find_call(const OSSL_DISPATCH
*dispatch
,
45 static int rand_drbg_restart(PROV_DRBG
*drbg
);
47 int ossl_drbg_lock(void *vctx
)
49 PROV_DRBG
*drbg
= vctx
;
51 if (drbg
== NULL
|| drbg
->lock
== NULL
)
53 return CRYPTO_THREAD_write_lock(drbg
->lock
);
56 void ossl_drbg_unlock(void *vctx
)
58 PROV_DRBG
*drbg
= vctx
;
60 if (drbg
!= NULL
&& drbg
->lock
!= NULL
)
61 CRYPTO_THREAD_unlock(drbg
->lock
);
64 static int ossl_drbg_lock_parent(PROV_DRBG
*drbg
)
66 void *parent
= drbg
->parent
;
69 && drbg
->parent_lock
!= NULL
70 && !drbg
->parent_lock(parent
)) {
71 ERR_raise(ERR_LIB_PROV
, PROV_R_PARENT_LOCKING_NOT_ENABLED
);
77 static void ossl_drbg_unlock_parent(PROV_DRBG
*drbg
)
79 void *parent
= drbg
->parent
;
81 if (parent
!= NULL
&& drbg
->parent_unlock
!= NULL
)
82 drbg
->parent_unlock(parent
);
85 static int get_parent_strength(PROV_DRBG
*drbg
, unsigned int *str
)
87 OSSL_PARAM params
[2] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
88 void *parent
= drbg
->parent
;
91 if (drbg
->parent_get_ctx_params
== NULL
) {
92 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH
);
96 *params
= OSSL_PARAM_construct_uint(OSSL_RAND_PARAM_STRENGTH
, str
);
97 if (!ossl_drbg_lock_parent(drbg
)) {
98 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_LOCK_PARENT
);
101 res
= drbg
->parent_get_ctx_params(parent
, params
);
102 ossl_drbg_unlock_parent(drbg
);
104 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH
);
110 static unsigned int get_parent_reseed_count(PROV_DRBG
*drbg
)
112 OSSL_PARAM params
[2] = { OSSL_PARAM_END
, OSSL_PARAM_END
};
113 void *parent
= drbg
->parent
;
116 *params
= OSSL_PARAM_construct_uint(OSSL_DRBG_PARAM_RESEED_COUNTER
, &r
);
117 if (!ossl_drbg_lock_parent(drbg
)) {
118 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_LOCK_PARENT
);
121 if (!drbg
->parent_get_ctx_params(parent
, params
))
123 ossl_drbg_unlock_parent(drbg
);
127 r
= tsan_load(&drbg
->reseed_counter
) - 2;
134 * Implements the get_entropy() callback
136 * If the DRBG has a parent, then the required amount of entropy input
137 * is fetched using the parent's ossl_prov_drbg_generate().
139 * Otherwise, the entropy is polled from the system entropy sources
140 * using ossl_pool_acquire_entropy().
142 * If a random pool has been added to the DRBG using RAND_add(), then
143 * its entropy will be used up first.
145 size_t ossl_drbg_get_seed(void *vdrbg
, unsigned char **pout
,
146 int entropy
, size_t min_len
,
147 size_t max_len
, int prediction_resistance
,
148 const unsigned char *adin
, size_t adin_len
)
150 PROV_DRBG
*drbg
= (PROV_DRBG
*)vdrbg
;
152 unsigned char *buffer
;
154 /* Figure out how many bytes we need */
155 bytes_needed
= entropy
>= 0 ? (entropy
+ 7) / 8 : 0;
156 if (bytes_needed
< min_len
)
157 bytes_needed
= min_len
;
158 if (bytes_needed
> max_len
)
159 bytes_needed
= max_len
;
161 /* Allocate storage */
162 buffer
= OPENSSL_secure_malloc(bytes_needed
);
167 * Get random data. Include our DRBG address as
168 * additional input, in order to provide a distinction between
169 * different DRBG child instances.
171 * Note: using the sizeof() operator on a pointer triggers
172 * a warning in some static code analyzers, but it's
173 * intentional and correct here.
175 if (!ossl_prov_drbg_generate(drbg
, buffer
, bytes_needed
,
176 drbg
->strength
, prediction_resistance
,
177 (unsigned char *)&drbg
, sizeof(drbg
))) {
178 OPENSSL_secure_clear_free(buffer
, bytes_needed
);
179 ERR_raise(ERR_LIB_PROV
, PROV_R_GENERATE_ERROR
);
186 /* Implements the cleanup_entropy() callback */
187 void ossl_drbg_clear_seed(ossl_unused
void *vdrbg
,
188 unsigned char *out
, size_t outlen
)
190 OPENSSL_secure_clear_free(out
, outlen
);
193 static size_t get_entropy(PROV_DRBG
*drbg
, unsigned char **pout
, int entropy
,
194 size_t min_len
, size_t max_len
,
195 int prediction_resistance
)
200 if (drbg
->parent
== NULL
)
202 return ossl_crngt_get_entropy(drbg
, pout
, entropy
, min_len
, max_len
,
203 prediction_resistance
);
205 return ossl_prov_get_entropy(drbg
->provctx
, pout
, entropy
, min_len
,
209 if (drbg
->parent_get_seed
== NULL
) {
210 ERR_raise(ERR_LIB_PROV
, PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED
);
213 if (!get_parent_strength(drbg
, &p_str
))
215 if (drbg
->strength
> p_str
) {
217 * We currently don't support the algorithm from NIST SP 800-90C
218 * 10.1.2 to use a weaker DRBG as source
220 ERR_raise(ERR_LIB_PROV
, PROV_R_PARENT_STRENGTH_TOO_WEAK
);
225 * Our lock is already held, but we need to lock our parent before
226 * generating bits from it. Note: taking the lock will be a no-op
227 * if locking is not required (while drbg->parent->lock == NULL).
229 if (!ossl_drbg_lock_parent(drbg
))
232 * Get random data from parent. Include our DRBG address as
233 * additional input, in order to provide a distinction between
234 * different DRBG child instances.
236 * Note: using the sizeof() operator on a pointer triggers
237 * a warning in some static code analyzers, but it's
238 * intentional and correct here.
240 bytes
= drbg
->parent_get_seed(drbg
->parent
, pout
, drbg
->strength
,
241 min_len
, max_len
, prediction_resistance
,
242 (unsigned char *)&drbg
, sizeof(drbg
));
243 ossl_drbg_unlock_parent(drbg
);
247 static void cleanup_entropy(PROV_DRBG
*drbg
, unsigned char *out
, size_t outlen
)
249 if (drbg
->parent
== NULL
) {
251 ossl_crngt_cleanup_entropy(drbg
, out
, outlen
);
253 ossl_prov_cleanup_entropy(drbg
->provctx
, out
, outlen
);
255 } else if (drbg
->parent_clear_seed
!= NULL
) {
256 if (!ossl_drbg_lock_parent(drbg
))
258 drbg
->parent_clear_seed(drbg
, out
, outlen
);
259 ossl_drbg_unlock_parent(drbg
);
263 #ifndef PROV_RAND_GET_RANDOM_NONCE
264 typedef struct prov_drbg_nonce_global_st
{
265 CRYPTO_RWLOCK
*rand_nonce_lock
;
266 int rand_nonce_count
;
267 } PROV_DRBG_NONCE_GLOBAL
;
270 * drbg_ossl_ctx_new() calls drgb_setup() which calls rand_drbg_get_nonce()
271 * which needs to get the rand_nonce_lock out of the OSSL_LIB_CTX...but since
272 * drbg_ossl_ctx_new() hasn't finished running yet we need the rand_nonce_lock
273 * to be in a different global data object. Otherwise we will go into an
274 * infinite recursion loop.
276 void *ossl_prov_drbg_nonce_ctx_new(OSSL_LIB_CTX
*libctx
)
278 PROV_DRBG_NONCE_GLOBAL
*dngbl
= OPENSSL_zalloc(sizeof(*dngbl
));
283 dngbl
->rand_nonce_lock
= CRYPTO_THREAD_lock_new();
284 if (dngbl
->rand_nonce_lock
== NULL
) {
292 void ossl_prov_drbg_nonce_ctx_free(void *vdngbl
)
294 PROV_DRBG_NONCE_GLOBAL
*dngbl
= vdngbl
;
299 CRYPTO_THREAD_lock_free(dngbl
->rand_nonce_lock
);
304 /* Get a nonce from the operating system */
305 static size_t prov_drbg_get_nonce(PROV_DRBG
*drbg
, unsigned char **pout
,
306 size_t min_len
, size_t max_len
)
309 unsigned char *buf
= NULL
;
310 OSSL_LIB_CTX
*libctx
= ossl_prov_ctx_get0_libctx(drbg
->provctx
);
311 PROV_DRBG_NONCE_GLOBAL
*dngbl
312 = ossl_lib_ctx_get_data(libctx
, OSSL_LIB_CTX_DRBG_NONCE_INDEX
);
321 if (drbg
->parent
!= NULL
&& drbg
->parent_nonce
!= NULL
) {
322 n
= drbg
->parent_nonce(drbg
->parent
, NULL
, 0, drbg
->min_noncelen
,
324 if (n
> 0 && (buf
= OPENSSL_malloc(n
)) != NULL
) {
325 ret
= drbg
->parent_nonce(drbg
->parent
, buf
, 0,
326 drbg
->min_noncelen
, drbg
->max_noncelen
);
335 /* Use the built in nonce source plus some of our specifics */
336 memset(&data
, 0, sizeof(data
));
338 CRYPTO_atomic_add(&dngbl
->rand_nonce_count
, 1, &data
.count
,
339 dngbl
->rand_nonce_lock
);
340 return ossl_prov_get_nonce(drbg
->provctx
, pout
, min_len
, max_len
,
341 &data
, sizeof(data
));
343 #endif /* PROV_RAND_GET_RANDOM_NONCE */
346 * Instantiate |drbg|, after it has been initialized. Use |pers| and
347 * |perslen| as prediction-resistance input.
349 * Requires that drbg->lock is already locked for write, if non-null.
351 * Returns 1 on success, 0 on failure.
353 int ossl_prov_drbg_instantiate(PROV_DRBG
*drbg
, unsigned int strength
,
354 int prediction_resistance
,
355 const unsigned char *pers
, size_t perslen
)
357 unsigned char *nonce
= NULL
, *entropy
= NULL
;
358 size_t noncelen
= 0, entropylen
= 0;
359 size_t min_entropy
, min_entropylen
, max_entropylen
;
361 if (strength
> drbg
->strength
) {
362 ERR_raise(ERR_LIB_PROV
, PROV_R_INSUFFICIENT_DRBG_STRENGTH
);
365 min_entropy
= drbg
->strength
;
366 min_entropylen
= drbg
->min_entropylen
;
367 max_entropylen
= drbg
->max_entropylen
;
370 pers
= (const unsigned char *)ossl_pers_string
;
371 perslen
= sizeof(ossl_pers_string
);
373 if (perslen
> drbg
->max_perslen
) {
374 ERR_raise(ERR_LIB_PROV
, PROV_R_PERSONALISATION_STRING_TOO_LONG
);
378 if (drbg
->state
!= EVP_RAND_STATE_UNINITIALISED
) {
379 if (drbg
->state
== EVP_RAND_STATE_ERROR
)
380 ERR_raise(ERR_LIB_PROV
, PROV_R_IN_ERROR_STATE
);
382 ERR_raise(ERR_LIB_PROV
, PROV_R_ALREADY_INSTANTIATED
);
386 drbg
->state
= EVP_RAND_STATE_ERROR
;
388 if (drbg
->min_noncelen
> 0) {
389 if (drbg
->parent_nonce
!= NULL
) {
390 noncelen
= drbg
->parent_nonce(drbg
->parent
, NULL
, drbg
->strength
,
394 ERR_raise(ERR_LIB_PROV
, PROV_R_ERROR_RETRIEVING_NONCE
);
397 nonce
= OPENSSL_malloc(noncelen
);
399 ERR_raise(ERR_LIB_PROV
, PROV_R_ERROR_RETRIEVING_NONCE
);
402 if (noncelen
!= drbg
->parent_nonce(drbg
->parent
, nonce
,
405 drbg
->max_noncelen
)) {
406 ERR_raise(ERR_LIB_PROV
, PROV_R_ERROR_RETRIEVING_NONCE
);
409 #ifndef PROV_RAND_GET_RANDOM_NONCE
410 } else if (drbg
->parent
!= NULL
) {
413 * NIST SP800-90Ar1 section 9.1 says you can combine getting
414 * the entropy and nonce in 1 call by increasing the entropy
415 * with 50% and increasing the minimum length to accommodate
416 * the length of the nonce. We do this in case a nonce is
417 * required and there is no parental nonce capability.
419 min_entropy
+= drbg
->strength
/ 2;
420 min_entropylen
+= drbg
->min_noncelen
;
421 max_entropylen
+= drbg
->max_noncelen
;
423 #ifndef PROV_RAND_GET_RANDOM_NONCE
424 else { /* parent == NULL */
425 noncelen
= prov_drbg_get_nonce(drbg
, &nonce
, drbg
->min_noncelen
,
427 if (noncelen
< drbg
->min_noncelen
428 || noncelen
> drbg
->max_noncelen
) {
429 ERR_raise(ERR_LIB_PROV
, PROV_R_ERROR_RETRIEVING_NONCE
);
436 drbg
->reseed_next_counter
= tsan_load(&drbg
->reseed_counter
);
437 if (drbg
->reseed_next_counter
) {
438 drbg
->reseed_next_counter
++;
439 if (!drbg
->reseed_next_counter
)
440 drbg
->reseed_next_counter
= 1;
443 entropylen
= get_entropy(drbg
, &entropy
, min_entropy
,
444 min_entropylen
, max_entropylen
,
445 prediction_resistance
);
446 if (entropylen
< min_entropylen
447 || entropylen
> max_entropylen
) {
448 ERR_raise(ERR_LIB_PROV
, PROV_R_ERROR_RETRIEVING_ENTROPY
);
452 if (!drbg
->instantiate(drbg
, entropy
, entropylen
, nonce
, noncelen
,
454 cleanup_entropy(drbg
, entropy
, entropylen
);
455 ERR_raise(ERR_LIB_PROV
, PROV_R_ERROR_INSTANTIATING_DRBG
);
458 cleanup_entropy(drbg
, entropy
, entropylen
);
460 drbg
->state
= EVP_RAND_STATE_READY
;
461 drbg
->generate_counter
= 1;
462 drbg
->reseed_time
= time(NULL
);
463 tsan_store(&drbg
->reseed_counter
, drbg
->reseed_next_counter
);
467 ossl_prov_cleanup_nonce(drbg
->provctx
, nonce
, noncelen
);
468 if (drbg
->state
== EVP_RAND_STATE_READY
)
474 * Uninstantiate |drbg|. Must be instantiated before it can be used.
476 * Requires that drbg->lock is already locked for write, if non-null.
478 * Returns 1 on success, 0 on failure.
480 int ossl_prov_drbg_uninstantiate(PROV_DRBG
*drbg
)
482 drbg
->state
= EVP_RAND_STATE_UNINITIALISED
;
487 * Reseed |drbg|, mixing in the specified data
489 * Requires that drbg->lock is already locked for write, if non-null.
491 * Returns 1 on success, 0 on failure.
493 int ossl_prov_drbg_reseed(PROV_DRBG
*drbg
, int prediction_resistance
,
494 const unsigned char *ent
, size_t ent_len
,
495 const unsigned char *adin
, size_t adinlen
)
497 unsigned char *entropy
= NULL
;
498 size_t entropylen
= 0;
500 if (!ossl_prov_is_running())
503 if (drbg
->state
!= EVP_RAND_STATE_READY
) {
504 /* try to recover from previous errors */
505 rand_drbg_restart(drbg
);
507 if (drbg
->state
== EVP_RAND_STATE_ERROR
) {
508 ERR_raise(ERR_LIB_PROV
, PROV_R_IN_ERROR_STATE
);
511 if (drbg
->state
== EVP_RAND_STATE_UNINITIALISED
) {
512 ERR_raise(ERR_LIB_PROV
, PROV_R_NOT_INSTANTIATED
);
518 if (ent_len
< drbg
->min_entropylen
) {
519 ERR_raise(ERR_LIB_RAND
, RAND_R_ENTROPY_OUT_OF_RANGE
);
520 drbg
->state
= EVP_RAND_STATE_ERROR
;
523 if (ent_len
> drbg
->max_entropylen
) {
524 ERR_raise(ERR_LIB_RAND
, RAND_R_ENTROPY_INPUT_TOO_LONG
);
525 drbg
->state
= EVP_RAND_STATE_ERROR
;
532 } else if (adinlen
> drbg
->max_adinlen
) {
533 ERR_raise(ERR_LIB_PROV
, PROV_R_ADDITIONAL_INPUT_TOO_LONG
);
537 drbg
->state
= EVP_RAND_STATE_ERROR
;
539 drbg
->reseed_next_counter
= tsan_load(&drbg
->reseed_counter
);
540 if (drbg
->reseed_next_counter
) {
541 drbg
->reseed_next_counter
++;
542 if (!drbg
->reseed_next_counter
)
543 drbg
->reseed_next_counter
= 1;
549 * NIST SP-800-90A mandates that entropy *shall not* be provided
550 * by the consuming application. Instead the data is added as additional
553 * (NIST SP-800-90Ar1, Sections 9.1 and 9.2)
555 if (!drbg
->reseed(drbg
, NULL
, 0, ent
, ent_len
)) {
556 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_RESEED
);
560 if (!drbg
->reseed(drbg
, ent
, ent_len
, adin
, adinlen
)) {
561 ERR_raise(ERR_LIB_PROV
, PROV_R_UNABLE_TO_RESEED
);
564 /* There isn't much point adding the same additional input twice */
570 /* Reseed using our sources in addition */
571 entropylen
= get_entropy(drbg
, &entropy
, drbg
->strength
,
572 drbg
->min_entropylen
, drbg
->max_entropylen
,
573 prediction_resistance
);
574 if (entropylen
< drbg
->min_entropylen
575 || entropylen
> drbg
->max_entropylen
) {
576 ERR_raise(ERR_LIB_PROV
, PROV_R_ERROR_RETRIEVING_ENTROPY
);
580 if (!drbg
->reseed(drbg
, entropy
, entropylen
, adin
, adinlen
))
583 drbg
->state
= EVP_RAND_STATE_READY
;
584 drbg
->generate_counter
= 1;
585 drbg
->reseed_time
= time(NULL
);
586 tsan_store(&drbg
->reseed_counter
, drbg
->reseed_next_counter
);
587 if (drbg
->parent
!= NULL
)
588 drbg
->parent_reseed_counter
= get_parent_reseed_count(drbg
);
591 cleanup_entropy(drbg
, entropy
, entropylen
);
592 if (drbg
->state
== EVP_RAND_STATE_READY
)
598 * Generate |outlen| bytes into the buffer at |out|. Reseed if we need
599 * to or if |prediction_resistance| is set. Additional input can be
600 * sent in |adin| and |adinlen|.
602 * Requires that drbg->lock is already locked for write, if non-null.
604 * Returns 1 on success, 0 on failure.
607 int ossl_prov_drbg_generate(PROV_DRBG
*drbg
, unsigned char *out
, size_t outlen
,
608 unsigned int strength
, int prediction_resistance
,
609 const unsigned char *adin
, size_t adinlen
)
612 int reseed_required
= 0;
614 if (!ossl_prov_is_running())
617 if (drbg
->state
!= EVP_RAND_STATE_READY
) {
618 /* try to recover from previous errors */
619 rand_drbg_restart(drbg
);
621 if (drbg
->state
== EVP_RAND_STATE_ERROR
) {
622 ERR_raise(ERR_LIB_PROV
, PROV_R_IN_ERROR_STATE
);
625 if (drbg
->state
== EVP_RAND_STATE_UNINITIALISED
) {
626 ERR_raise(ERR_LIB_PROV
, PROV_R_NOT_INSTANTIATED
);
630 if (strength
> drbg
->strength
) {
631 ERR_raise(ERR_LIB_PROV
, PROV_R_INSUFFICIENT_DRBG_STRENGTH
);
635 if (outlen
> drbg
->max_request
) {
636 ERR_raise(ERR_LIB_PROV
, PROV_R_REQUEST_TOO_LARGE_FOR_DRBG
);
639 if (adinlen
> drbg
->max_adinlen
) {
640 ERR_raise(ERR_LIB_PROV
, PROV_R_ADDITIONAL_INPUT_TOO_LONG
);
644 fork_id
= openssl_get_fork_id();
646 if (drbg
->fork_id
!= fork_id
) {
647 drbg
->fork_id
= fork_id
;
651 if (drbg
->reseed_interval
> 0) {
652 if (drbg
->generate_counter
>= drbg
->reseed_interval
)
655 if (drbg
->reseed_time_interval
> 0) {
656 time_t now
= time(NULL
);
657 if (now
< drbg
->reseed_time
658 || now
- drbg
->reseed_time
>= drbg
->reseed_time_interval
)
661 if (drbg
->parent
!= NULL
662 && get_parent_reseed_count(drbg
) != drbg
->parent_reseed_counter
)
665 if (reseed_required
|| prediction_resistance
) {
666 if (!ossl_prov_drbg_reseed(drbg
, prediction_resistance
, NULL
, 0,
668 ERR_raise(ERR_LIB_PROV
, PROV_R_RESEED_ERROR
);
675 if (!drbg
->generate(drbg
, out
, outlen
, adin
, adinlen
)) {
676 drbg
->state
= EVP_RAND_STATE_ERROR
;
677 ERR_raise(ERR_LIB_PROV
, PROV_R_GENERATE_ERROR
);
681 drbg
->generate_counter
++;
687 * Restart |drbg|, using the specified entropy or additional input
689 * Tries its best to get the drbg instantiated by all means,
690 * regardless of its current state.
692 * Optionally, a |buffer| of |len| random bytes can be passed,
693 * which is assumed to contain at least |entropy| bits of entropy.
695 * If |entropy| > 0, the buffer content is used as entropy input.
697 * If |entropy| == 0, the buffer content is used as additional input
699 * Returns 1 on success, 0 on failure.
701 * This function is used internally only.
703 static int rand_drbg_restart(PROV_DRBG
*drbg
)
705 /* repair error state */
706 if (drbg
->state
== EVP_RAND_STATE_ERROR
)
707 drbg
->uninstantiate(drbg
);
709 /* repair uninitialized state */
710 if (drbg
->state
== EVP_RAND_STATE_UNINITIALISED
)
711 /* reinstantiate drbg */
712 ossl_prov_drbg_instantiate(drbg
, drbg
->strength
, 0, NULL
, 0);
714 return drbg
->state
== EVP_RAND_STATE_READY
;
717 /* Provider support from here down */
718 static const OSSL_DISPATCH
*find_call(const OSSL_DISPATCH
*dispatch
,
721 if (dispatch
!= NULL
)
722 while (dispatch
->function_id
!= 0) {
723 if (dispatch
->function_id
== function
)
730 int ossl_drbg_enable_locking(void *vctx
)
732 PROV_DRBG
*drbg
= vctx
;
734 if (drbg
!= NULL
&& drbg
->lock
== NULL
) {
735 if (drbg
->parent_enable_locking
!= NULL
)
736 if (!drbg
->parent_enable_locking(drbg
->parent
)) {
737 ERR_raise(ERR_LIB_PROV
, PROV_R_PARENT_LOCKING_NOT_ENABLED
);
740 drbg
->lock
= CRYPTO_THREAD_lock_new();
741 if (drbg
->lock
== NULL
) {
742 ERR_raise(ERR_LIB_PROV
, PROV_R_FAILED_TO_CREATE_LOCK
);
750 * Allocate memory and initialize a new DRBG. The DRBG is allocated on
751 * the secure heap if |secure| is nonzero and the secure heap is enabled.
752 * The |parent|, if not NULL, will be used as random source for reseeding.
753 * This also requires the parent's provider context and the parent's lock.
755 * Returns a pointer to the new DRBG instance on success, NULL on failure.
757 PROV_DRBG
*ossl_rand_drbg_new
758 (void *provctx
, void *parent
, const OSSL_DISPATCH
*p_dispatch
,
759 int (*dnew
)(PROV_DRBG
*ctx
),
760 int (*instantiate
)(PROV_DRBG
*drbg
,
761 const unsigned char *entropy
, size_t entropylen
,
762 const unsigned char *nonce
, size_t noncelen
,
763 const unsigned char *pers
, size_t perslen
),
764 int (*uninstantiate
)(PROV_DRBG
*ctx
),
765 int (*reseed
)(PROV_DRBG
*drbg
, const unsigned char *ent
, size_t ent_len
,
766 const unsigned char *adin
, size_t adin_len
),
767 int (*generate
)(PROV_DRBG
*, unsigned char *out
, size_t outlen
,
768 const unsigned char *adin
, size_t adin_len
))
772 const OSSL_DISPATCH
*pfunc
;
774 if (!ossl_prov_is_running())
777 drbg
= OPENSSL_zalloc(sizeof(*drbg
));
781 drbg
->provctx
= provctx
;
782 drbg
->instantiate
= instantiate
;
783 drbg
->uninstantiate
= uninstantiate
;
784 drbg
->reseed
= reseed
;
785 drbg
->generate
= generate
;
786 drbg
->fork_id
= openssl_get_fork_id();
788 /* Extract parent's functions */
789 drbg
->parent
= parent
;
790 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_ENABLE_LOCKING
)) != NULL
)
791 drbg
->parent_enable_locking
= OSSL_FUNC_rand_enable_locking(pfunc
);
792 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_LOCK
)) != NULL
)
793 drbg
->parent_lock
= OSSL_FUNC_rand_lock(pfunc
);
794 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_UNLOCK
)) != NULL
)
795 drbg
->parent_unlock
= OSSL_FUNC_rand_unlock(pfunc
);
796 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_GET_CTX_PARAMS
)) != NULL
)
797 drbg
->parent_get_ctx_params
= OSSL_FUNC_rand_get_ctx_params(pfunc
);
798 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_NONCE
)) != NULL
)
799 drbg
->parent_nonce
= OSSL_FUNC_rand_nonce(pfunc
);
800 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_GET_SEED
)) != NULL
)
801 drbg
->parent_get_seed
= OSSL_FUNC_rand_get_seed(pfunc
);
802 if ((pfunc
= find_call(p_dispatch
, OSSL_FUNC_RAND_CLEAR_SEED
)) != NULL
)
803 drbg
->parent_clear_seed
= OSSL_FUNC_rand_clear_seed(pfunc
);
805 /* Set some default maximums up */
806 drbg
->max_entropylen
= DRBG_MAX_LENGTH
;
807 drbg
->max_noncelen
= DRBG_MAX_LENGTH
;
808 drbg
->max_perslen
= DRBG_MAX_LENGTH
;
809 drbg
->max_adinlen
= DRBG_MAX_LENGTH
;
810 drbg
->generate_counter
= 1;
811 drbg
->reseed_counter
= 1;
812 drbg
->reseed_interval
= RESEED_INTERVAL
;
813 drbg
->reseed_time_interval
= TIME_INTERVAL
;
818 if (parent
!= NULL
) {
819 if (!get_parent_strength(drbg
, &p_str
))
821 if (drbg
->strength
> p_str
) {
823 * We currently don't support the algorithm from NIST SP 800-90C
824 * 10.1.2 to use a weaker DRBG as source
826 ERR_raise(ERR_LIB_PROV
, PROV_R_PARENT_STRENGTH_TOO_WEAK
);
830 #ifdef TSAN_REQUIRES_LOCKING
831 if (!ossl_drbg_enable_locking(drbg
))
837 ossl_rand_drbg_free(drbg
);
841 void ossl_rand_drbg_free(PROV_DRBG
*drbg
)
846 CRYPTO_THREAD_lock_free(drbg
->lock
);
850 int ossl_drbg_get_ctx_params(PROV_DRBG
*drbg
, OSSL_PARAM params
[])
854 p
= OSSL_PARAM_locate(params
, OSSL_RAND_PARAM_STATE
);
855 if (p
!= NULL
&& !OSSL_PARAM_set_int(p
, drbg
->state
))
858 p
= OSSL_PARAM_locate(params
, OSSL_RAND_PARAM_STRENGTH
);
859 if (p
!= NULL
&& !OSSL_PARAM_set_int(p
, drbg
->strength
))
862 p
= OSSL_PARAM_locate(params
, OSSL_RAND_PARAM_MAX_REQUEST
);
863 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->max_request
))
866 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MIN_ENTROPYLEN
);
867 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->min_entropylen
))
870 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MAX_ENTROPYLEN
);
871 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->max_entropylen
))
874 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MIN_NONCELEN
);
875 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->min_noncelen
))
878 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MAX_NONCELEN
);
879 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->max_noncelen
))
882 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MAX_PERSLEN
);
883 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->max_perslen
))
886 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_MAX_ADINLEN
);
887 if (p
!= NULL
&& !OSSL_PARAM_set_size_t(p
, drbg
->max_adinlen
))
890 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_RESEED_REQUESTS
);
891 if (p
!= NULL
&& !OSSL_PARAM_set_uint(p
, drbg
->reseed_interval
))
894 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_RESEED_TIME
);
895 if (p
!= NULL
&& !OSSL_PARAM_set_time_t(p
, drbg
->reseed_time
))
898 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL
);
899 if (p
!= NULL
&& !OSSL_PARAM_set_time_t(p
, drbg
->reseed_time_interval
))
902 p
= OSSL_PARAM_locate(params
, OSSL_DRBG_PARAM_RESEED_COUNTER
);
904 && !OSSL_PARAM_set_uint(p
, tsan_load(&drbg
->reseed_counter
)))
909 int ossl_drbg_set_ctx_params(PROV_DRBG
*drbg
, const OSSL_PARAM params
[])
916 p
= OSSL_PARAM_locate_const(params
, OSSL_DRBG_PARAM_RESEED_REQUESTS
);
917 if (p
!= NULL
&& !OSSL_PARAM_get_uint(p
, &drbg
->reseed_interval
))
920 p
= OSSL_PARAM_locate_const(params
, OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL
);
921 if (p
!= NULL
&& !OSSL_PARAM_get_time_t(p
, &drbg
->reseed_time_interval
))