X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=crypto%2Frand%2Fdrbg_lib.c;h=a695a5f7ddb462477540eb384ba3ace7bebca149;hp=79d986ef4805cb5fef6ee4031fcaeffe610eadf8;hb=09a4cb9ec7ea9ccb4885588ba3e138b9f5f606c7;hpb=242f84d06aca7030b2bd52043c39b0cb80c4fec6 diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c index 79d986ef48..a695a5f7dd 100644 --- a/crypto/rand/drbg_lib.c +++ b/crypto/rand/drbg_lib.c @@ -11,10 +11,10 @@ #include #include #include -#include "rand_lcl.h" +#include "rand_local.h" #include "internal/thread_once.h" -#include "internal/rand_int.h" -#include "internal/cryptlib_int.h" +#include "crypto/rand.h" +#include "crypto/cryptlib.h" /* * Support framework for NIST SP 800-90A DRBG @@ -191,6 +191,9 @@ static void drbg_ossl_ctx_free(void *vdgbl) { DRBG_GLOBAL *dgbl = vdgbl; + if (dgbl == NULL) + return; + RAND_DRBG_free(dgbl->master_drbg); CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg); CRYPTO_THREAD_cleanup_local(&dgbl->public_drbg); @@ -230,6 +233,9 @@ static void drbg_nonce_ossl_ctx_free(void *vdngbl) { DRBG_NONCE_GLOBAL *dngbl = vdngbl; + if (dngbl == NULL) + return; + CRYPTO_THREAD_lock_free(dngbl->rand_nonce_lock); OPENSSL_free(dngbl); @@ -265,7 +271,7 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg, return 0; memset(&data, 0, sizeof(data)); - pool = rand_pool_new(0, min_len, max_len); + pool = rand_pool_new(0, 0, min_len, max_len); if (pool == NULL) return 0; @@ -295,7 +301,7 @@ size_t rand_drbg_get_nonce(RAND_DRBG *drbg, void rand_drbg_cleanup_nonce(RAND_DRBG *drbg, unsigned char *out, size_t outlen) { - OPENSSL_secure_clear_free(out, outlen); + OPENSSL_clear_free(out, outlen); } /* @@ -409,7 +415,7 @@ static RAND_DRBG *rand_drbg_new(OPENSSL_CTX *ctx, drbg->libctx = ctx; drbg->secure = secure && CRYPTO_secure_allocated(drbg); - drbg->fork_count = rand_fork_count; + drbg->fork_id = openssl_get_fork_id(); drbg->parent = parent; if (parent == NULL) { @@ -497,7 +503,9 @@ void RAND_DRBG_free(RAND_DRBG *drbg) drbg->meth->uninstantiate(drbg); rand_pool_free(drbg->adin_pool); CRYPTO_THREAD_lock_free(drbg->lock); - CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data); +#ifndef FIPS_MODE + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RAND_DRBG, drbg, &drbg->ex_data); +#endif if (drbg->secure) OPENSSL_secure_clear_free(drbg, sizeof(*drbg)); @@ -535,9 +543,10 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg, } if (drbg->state != DRBG_UNINITIALISED) { - RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, - drbg->state == DRBG_ERROR ? RAND_R_IN_ERROR_STATE - : RAND_R_ALREADY_INSTANTIATED); + if (drbg->state == DRBG_ERROR) + RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_IN_ERROR_STATE); + else + RANDerr(RAND_F_RAND_DRBG_INSTANTIATE, RAND_R_ALREADY_INSTANTIATED); goto end; } @@ -546,7 +555,7 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg, /* * NIST SP800-90Ar1 section 9.1 says you can combine getting the entropy * and nonce in 1 call by increasing the entropy with 50% and increasing - * the minimum length to accomadate the length of the nonce. + * the minimum length to accommodate the length of the nonce. * We do this in case a nonce is require and get_nonce is NULL. */ if (drbg->min_noncelen > 0 && drbg->get_nonce == NULL) { @@ -823,6 +832,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, int prediction_resistance, const unsigned char *adin, size_t adinlen) { + int fork_id; int reseed_required = 0; if (drbg->state != DRBG_READY) { @@ -848,8 +858,10 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen, return 0; } - if (drbg->fork_count != rand_fork_count) { - drbg->fork_count = rand_fork_count; + fork_id = openssl_get_fork_id(); + + if (drbg->fork_id != fork_id) { + drbg->fork_id = fork_id; reseed_required = 1; } @@ -909,7 +921,7 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen) if (drbg->adin_pool == NULL) { if (drbg->type == 0) goto err; - drbg->adin_pool = rand_pool_new(0, 0, drbg->max_adinlen); + drbg->adin_pool = rand_pool_new(0, 0, 0, drbg->max_adinlen); if (drbg->adin_pool == NULL) goto err; } @@ -1088,6 +1100,7 @@ int rand_drbg_enable_locking(RAND_DRBG *drbg) return 1; } +#ifndef FIPS_MODE /* * Get and set the EXDATA */ @@ -1100,7 +1113,7 @@ void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx) { return CRYPTO_get_ex_data(&drbg->ex_data, idx); } - +#endif /* * The following functions provide a RAND_METHOD that works on the @@ -1145,8 +1158,9 @@ err: return NULL; } -static void drbg_delete_thread_state(OPENSSL_CTX *ctx) +static void drbg_delete_thread_state(void *arg) { + OPENSSL_CTX *ctx = arg; DRBG_GLOBAL *dgbl = drbg_get_global(ctx); RAND_DRBG *drbg; @@ -1338,7 +1352,13 @@ RAND_DRBG *OPENSSL_CTX_get0_public_drbg(OPENSSL_CTX *ctx) drbg = CRYPTO_THREAD_get_local(&dgbl->public_drbg); if (drbg == NULL) { - if (!ossl_init_thread_start(NULL, drbg_delete_thread_state)) + ctx = openssl_ctx_get_concrete(ctx); + /* + * If the private_drbg is also NULL then this is the first time we've + * used this thread. + */ + if (CRYPTO_THREAD_get_local(&dgbl->private_drbg) == NULL + && !ossl_init_thread_start(NULL, ctx, drbg_delete_thread_state)) return NULL; drbg = drbg_setup(ctx, dgbl->master_drbg, RAND_DRBG_TYPE_PUBLIC); CRYPTO_THREAD_set_local(&dgbl->public_drbg, drbg); @@ -1365,7 +1385,13 @@ RAND_DRBG *OPENSSL_CTX_get0_private_drbg(OPENSSL_CTX *ctx) drbg = CRYPTO_THREAD_get_local(&dgbl->private_drbg); if (drbg == NULL) { - if (!ossl_init_thread_start(NULL, drbg_delete_thread_state)) + ctx = openssl_ctx_get_concrete(ctx); + /* + * If the public_drbg is also NULL then this is the first time we've + * used this thread. + */ + if (CRYPTO_THREAD_get_local(&dgbl->public_drbg) == NULL + && !ossl_init_thread_start(NULL, ctx, drbg_delete_thread_state)) return NULL; drbg = drbg_setup(ctx, dgbl->master_drbg, RAND_DRBG_TYPE_PRIVATE); CRYPTO_THREAD_set_local(&dgbl->private_drbg, drbg);