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)
This commit is contained in:
parent
f1358634af
commit
a83dc59afa
3 changed files with 30 additions and 17 deletions
|
@ -374,6 +374,13 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
||||||
max_entropylen += drbg->max_noncelen;
|
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)
|
if (drbg->get_entropy != NULL)
|
||||||
entropylen = drbg->get_entropy(drbg, &entropy, min_entropy,
|
entropylen = drbg->get_entropy(drbg, &entropy, min_entropy,
|
||||||
min_entropylen, max_entropylen, 0);
|
min_entropylen, max_entropylen, 0);
|
||||||
|
@ -401,12 +408,7 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
|
||||||
drbg->state = DRBG_READY;
|
drbg->state = DRBG_READY;
|
||||||
drbg->reseed_gen_counter = 1;
|
drbg->reseed_gen_counter = 1;
|
||||||
drbg->reseed_time = time(NULL);
|
drbg->reseed_time = time(NULL);
|
||||||
if (drbg->reseed_prop_counter > 0) {
|
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
|
||||||
if (drbg->parent == NULL)
|
|
||||||
drbg->reseed_prop_counter++;
|
|
||||||
else
|
|
||||||
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (entropy != NULL && drbg->cleanup_entropy != NULL)
|
if (entropy != NULL && drbg->cleanup_entropy != NULL)
|
||||||
|
@ -498,6 +500,14 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
|
||||||
}
|
}
|
||||||
|
|
||||||
drbg->state = DRBG_ERROR;
|
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)
|
if (drbg->get_entropy != NULL)
|
||||||
entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength,
|
entropylen = drbg->get_entropy(drbg, &entropy, drbg->strength,
|
||||||
drbg->min_entropylen,
|
drbg->min_entropylen,
|
||||||
|
@ -515,12 +525,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
|
||||||
drbg->state = DRBG_READY;
|
drbg->state = DRBG_READY;
|
||||||
drbg->reseed_gen_counter = 1;
|
drbg->reseed_gen_counter = 1;
|
||||||
drbg->reseed_time = time(NULL);
|
drbg->reseed_time = time(NULL);
|
||||||
if (drbg->reseed_prop_counter > 0) {
|
tsan_store(&drbg->reseed_prop_counter, drbg->reseed_next_counter);
|
||||||
if (drbg->parent == NULL)
|
|
||||||
drbg->reseed_prop_counter++;
|
|
||||||
else
|
|
||||||
drbg->reseed_prop_counter = drbg->parent->reseed_prop_counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (entropy != NULL && drbg->cleanup_entropy != NULL)
|
if (entropy != NULL && drbg->cleanup_entropy != NULL)
|
||||||
|
@ -691,8 +696,11 @@ int RAND_DRBG_generate(RAND_DRBG *drbg, unsigned char *out, size_t outlen,
|
||||||
|| now - drbg->reseed_time >= drbg->reseed_time_interval)
|
|| now - drbg->reseed_time >= drbg->reseed_time_interval)
|
||||||
reseed_required = 1;
|
reseed_required = 1;
|
||||||
}
|
}
|
||||||
if (drbg->reseed_prop_counter > 0 && drbg->parent != NULL) {
|
if (drbg->parent != NULL) {
|
||||||
if (drbg->reseed_prop_counter != drbg->parent->reseed_prop_counter)
|
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;
|
reseed_required = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -764,7 +772,8 @@ int RAND_DRBG_set_callbacks(RAND_DRBG *drbg,
|
||||||
RAND_DRBG_get_nonce_fn get_nonce,
|
RAND_DRBG_get_nonce_fn get_nonce,
|
||||||
RAND_DRBG_cleanup_nonce_fn cleanup_nonce)
|
RAND_DRBG_cleanup_nonce_fn cleanup_nonce)
|
||||||
{
|
{
|
||||||
if (drbg->state != DRBG_UNINITIALISED)
|
if (drbg->state != DRBG_UNINITIALISED
|
||||||
|
|| drbg->parent != NULL)
|
||||||
return 0;
|
return 0;
|
||||||
drbg->get_entropy = get_entropy;
|
drbg->get_entropy = get_entropy;
|
||||||
drbg->cleanup_entropy = cleanup_entropy;
|
drbg->cleanup_entropy = cleanup_entropy;
|
||||||
|
@ -942,7 +951,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent, int drbg_type)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* enable seed propagation */
|
/* enable seed propagation */
|
||||||
drbg->reseed_prop_counter = 1;
|
tsan_store(&drbg->reseed_prop_counter, 1);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ignore instantiation error to support just-in-time instantiation.
|
* Ignore instantiation error to support just-in-time instantiation.
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
# include <openssl/hmac.h>
|
# include <openssl/hmac.h>
|
||||||
# include <openssl/ec.h>
|
# include <openssl/ec.h>
|
||||||
# include <openssl/rand_drbg.h>
|
# include <openssl/rand_drbg.h>
|
||||||
|
# include "internal/tsan_assist.h"
|
||||||
|
|
||||||
# include "internal/numbers.h"
|
# include "internal/numbers.h"
|
||||||
|
|
||||||
|
@ -258,7 +259,8 @@ struct rand_drbg_st {
|
||||||
* is added by RAND_add() or RAND_seed() will have an immediate effect on
|
* is added by RAND_add() or RAND_seed() will have an immediate effect on
|
||||||
* the output of RAND_bytes() resp. RAND_priv_bytes().
|
* 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;
|
size_t seedlen;
|
||||||
DRBG_STATUS state;
|
DRBG_STATUS state;
|
||||||
|
|
|
@ -174,6 +174,8 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
|
||||||
prediction_resistance,
|
prediction_resistance,
|
||||||
NULL, 0) != 0)
|
NULL, 0) != 0)
|
||||||
bytes = bytes_needed;
|
bytes = bytes_needed;
|
||||||
|
drbg->reseed_next_counter
|
||||||
|
= tsan_load(&drbg->parent->reseed_prop_counter);
|
||||||
rand_drbg_unlock(drbg->parent);
|
rand_drbg_unlock(drbg->parent);
|
||||||
|
|
||||||
rand_pool_add_end(pool, bytes, 8 * bytes);
|
rand_pool_add_end(pool, bytes, 8 * bytes);
|
||||||
|
|
Loading…
Reference in a new issue