Fix data race in RAND_DRBG_generate
Fixes #7394
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/7399)
(cherry picked from commit a83dc59afa
)
This commit is contained in:
parent
d597a9a877
commit
1f98527659
3 changed files with 30 additions and 17 deletions
|
@ -316,6 +316,13 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
|||
max_entropylen += drbg->max_noncelen;
|
||||
}
|
||||
|
||||
drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
|
||||
if (drbg->reseed_next_counter) {
|
||||
drbg->reseed_next_counter++;
|
||||
if(!drbg->reseed_next_counter)
|
||||
drbg->reseed_next_counter = 1;
|
||||
}
|
||||
|
||||
if (drbg->get_entropy != NULL)
|
||||
entropylen = drbg->get_entropy(drbg, &entropy, min_entropy,
|
||||
min_entropylen, max_entropylen, 0);
|
||||
|
@ -343,12 +350,7 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
|||
drbg->state = DRBG_READY;
|
||||
drbg->reseed_gen_counter = 0;
|
||||
drbg->reseed_time = time(NULL);
|
||||
if (drbg->reseed_prop_counter > 0) {
|
||||
if (drbg->parent == NULL)
|
||||
drbg->reseed_prop_counter++;
|
||||
else
|
||||
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
|
||||
}
|
||||
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
|
||||
|
||||
end:
|
||||
if (entropy != NULL && drbg->cleanup_entropy != NULL)
|
||||
|
@ -423,6 +425,14 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
|
|||
}
|
||||
|
||||
drbg->state = DRBG_ERROR;
|
||||
|
||||
drbg->reseed_next_counter = tsan_load(&drbg->reseed_prop_counter);
|
||||
if (drbg->reseed_next_counter) {
|
||||
drbg->reseed_next_counter++;
|
||||
if(!drbg->reseed_next_counter)
|
||||
drbg->reseed_next_counter = 1;
|
||||
}
|
||||
|
||||
if (drbg->get_entropy != NULL)
|
||||
entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength,
|
||||
drbg->min_entropylen,
|
||||
|
@ -440,12 +450,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
|
|||
drbg->state = DRBG_READY;
|
||||
drbg->reseed_gen_counter = 0;
|
||||
drbg->reseed_time = time(NULL);
|
||||
if (drbg->reseed_prop_counter > 0) {
|
||||
if (drbg->parent == NULL)
|
||||
drbg->reseed_prop_counter++;
|
||||
else
|
||||
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
|
||||
}
|
||||
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
|
||||
|
||||
end:
|
||||
if (entropy != NULL && drbg->cleanup_entropy != NULL)
|
||||
|
@ -616,8 +621,11 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
|
|||
|| now - drbg->reseed_time >= drbg->reseed_time_interval)
|
||||
reseed_required = 1;
|
||||
}
|
||||
if (drbg->reseed_prop_counter > 0 && drbg->parent != NULL) {
|
||||
if (drbg->reseed_prop_counter != drbg->parent->reseed_prop_counter)
|
||||
if (drbg->parent != NULL) {
|
||||
unsigned int reseed_counter = tsan_load(&drbg->reseed_prop_counter);
|
||||
if (reseed_counter > 0
|
||||
&& tsan_load(&drbg->parent->reseed_prop_counter)
|
||||
!= reseed_counter)
|
||||
reseed_required = 1;
|
||||
}
|
||||
|
||||
|
@ -689,7 +697,8 @@ int RAND_DRBG_set_callbacks(RAND_DRBG *drbg,
|
|||
RAND_DRBG_get_nonce_fn get_nonce,
|
||||
RAND_DRBG_cleanup_nonce_fn cleanup_nonce)
|
||||
{
|
||||
if (drbg->state != DRBG_UNINITIALISED)
|
||||
if (drbg->state != DRBG_UNINITIALISED
|
||||
|| drbg->parent != NULL)
|
||||
return 0;
|
||||
drbg->get_entropy = get_entropy;
|
||||
drbg->cleanup_entropy = cleanup_entropy;
|
||||
|
@ -866,7 +875,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent)
|
|||
goto err;
|
||||
|
||||
/* enable seed propagation */
|
||||
drbg->reseed_prop_counter = 1;
|
||||
tsan_store(&drbg->reseed_prop_counter, 1);
|
||||
|
||||
/*
|
||||
* Ignore instantiation error to support just-in-time instantiation.
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
# include <openssl/hmac.h>
|
||||
# include <openssl/ec.h>
|
||||
# include <openssl/rand_drbg.h>
|
||||
# include "internal/tsan_assist.h"
|
||||
|
||||
# include "internal/numbers.h"
|
||||
|
||||
|
@ -231,7 +232,8 @@ struct rand_drbg_st {
|
|||
* is added by RAND_add() or RAND_seed() will have an immediate effect on
|
||||
* the output of RAND_bytes() resp. RAND_priv_bytes().
|
||||
*/
|
||||
unsigned int reseed_prop_counter;
|
||||
TSAN_QUALIFIER unsigned int reseed_prop_counter;
|
||||
unsigned int reseed_next_counter;
|
||||
|
||||
size_t seedlen;
|
||||
DRBG_STATUS state;
|
||||
|
|
|
@ -174,6 +174,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
|||
prediction_resistance,
|
||||
NULL, 0) != 0)
|
||||
bytes = bytes_needed;
|
||||
drbg->reseed_next_counter
|
||||
= tsan_load(&drbg->parent->reseed_prop_counter);
|
||||
rand_drbg_unlock(drbg->parent);
|
||||
|
||||
rand_pool_add_end(pool, bytes, 8 * bytes);
|
||||
|
|
Loading…
Reference in a new issue