summaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2018-10-14 12:35:19 +0200
committerBernd Edlinger <bernd.edlinger@hotmail.de>2018-10-26 15:33:37 +0200
commita83dc59afa2e0207180d7218efed19b20d48de95 (patch)
tree494f338c85bd609e77ffaceae2f6f7806c7e067d /crypto
parentf1358634af5b84be22cb20fff3dcb613f5f8c978 (diff)
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)
Diffstat (limited to 'crypto')
-rw-r--r--crypto/rand/drbg_lib.c41
-rw-r--r--crypto/rand/rand_lcl.h4
-rw-r--r--crypto/rand/rand_lib.c2
3 files changed, 30 insertions, 17 deletions
diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c
index 9d920cb39a..ec4aa69db5 100644
--- a/crypto/rand/drbg_lib.c
+++ b/crypto/rand/drbg_lib.c
@@ -374,6 +374,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);
@@ -401,12 +408,7 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
drbg->state = DRBG_READY;
drbg->reseed_gen_counter = 1;
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)
@@ -498,6 +500,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,
@@ -515,12 +525,7 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
drbg->state = DRBG_READY;
drbg->reseed_gen_counter = 1;
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)
@@ -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)
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;
}
@@ -764,7 +772,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;
@@ -942,7 +951,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent, int drbg_type)
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.
diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h
index 9004809a8b..8abca4c290 100644
--- a/crypto/rand/rand_lcl.h
+++ b/crypto/rand/rand_lcl.h
@@ -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"
@@ -258,7 +259,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;
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index 29d93a829b..440c19c287 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -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);