summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBernd Edlinger <bernd.edlinger@hotmail.de>2018-04-26 10:14:14 +0200
committerBernd Edlinger <bernd.edlinger@hotmail.de>2018-04-27 14:07:42 +0200
commit272c0df8e1aa549da9060bf70b34c9aabb3bcb0d (patch)
treeca3b00a421ea9b0d20d667153d027148e4965916
parentddba302a0fa3b11d8cfa01d590ace853229e8f35 (diff)
Fix drbg thread cleanup and error handling
Fixes: #6081 Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/6089)
-rw-r--r--crypto/rand/drbg_lib.c40
1 files changed, 23 insertions, 17 deletions
diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c
index 16ac03b8b6..c6397b22c6 100644
--- a/crypto/rand/drbg_lib.c
+++ b/crypto/rand/drbg_lib.c
@@ -285,8 +285,7 @@ int RAND_DRBG_instantiate(RAND_DRBG *drbg,
goto end;
}
- if (drbg->meth == NULL)
- {
+ if (drbg->meth == NULL) {
RANDerr(RAND_F_RAND_DRBG_INSTANTIATE,
RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
goto end;
@@ -375,8 +374,7 @@ end:
*/
int RAND_DRBG_uninstantiate(RAND_DRBG *drbg)
{
- if (drbg->meth == NULL)
- {
+ if (drbg->meth == NULL) {
RANDerr(RAND_F_RAND_DRBG_UNINSTANTIATE,
RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED);
return 0;
@@ -413,9 +411,9 @@ int RAND_DRBG_reseed(RAND_DRBG *drbg,
return 0;
}
- if (adin == NULL)
+ if (adin == NULL) {
adinlen = 0;
- else if (adinlen > drbg->max_adinlen) {
+ } else if (adinlen > drbg->max_adinlen) {
RANDerr(RAND_F_RAND_DRBG_RESEED, RAND_R_ADDITIONAL_INPUT_TOO_LONG);
return 0;
}
@@ -885,8 +883,6 @@ err:
*/
DEFINE_RUN_ONCE_STATIC(do_rand_drbg_init)
{
- int ret = 1;
-
/*
* ensure that libcrypto is initialized, otherwise the
* DRBG locks are not cleaned up properly
@@ -894,17 +890,23 @@ DEFINE_RUN_ONCE_STATIC(do_rand_drbg_init)
if (!OPENSSL_init_crypto(0, NULL))
return 0;
- ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND);
-
- master_drbg = drbg_setup(NULL);
+ if (!CRYPTO_THREAD_init_local(&private_drbg, NULL))
+ return 0;
- ret &= CRYPTO_THREAD_init_local(&private_drbg, NULL);
- ret &= CRYPTO_THREAD_init_local(&public_drbg, NULL);
+ if (!CRYPTO_THREAD_init_local(&public_drbg, NULL))
+ goto err1;
- if (master_drbg == NULL || ret == 0)
- return 0;
+ master_drbg = drbg_setup(NULL);
+ if (master_drbg == NULL)
+ goto err2;
return 1;
+
+err2:
+ CRYPTO_THREAD_cleanup_local(&public_drbg);
+err1:
+ CRYPTO_THREAD_cleanup_local(&private_drbg);
+ return 0;
}
/* Clean up the global DRBGs before exit */
@@ -922,9 +924,11 @@ void drbg_delete_thread_state()
RAND_DRBG *drbg;
drbg = CRYPTO_THREAD_get_local(&public_drbg);
+ CRYPTO_THREAD_set_local(&public_drbg, NULL);
RAND_DRBG_free(drbg);
drbg = CRYPTO_THREAD_get_local(&private_drbg);
+ CRYPTO_THREAD_set_local(&private_drbg, NULL);
RAND_DRBG_free(drbg);
}
@@ -1020,7 +1024,8 @@ RAND_DRBG *RAND_DRBG_get0_public(void)
drbg = CRYPTO_THREAD_get_local(&public_drbg);
if (drbg == NULL) {
- ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND);
+ if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND))
+ return NULL;
drbg = drbg_setup(master_drbg);
CRYPTO_THREAD_set_local(&public_drbg, drbg);
}
@@ -1040,7 +1045,8 @@ RAND_DRBG *RAND_DRBG_get0_private(void)
drbg = CRYPTO_THREAD_get_local(&private_drbg);
if (drbg == NULL) {
- ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND);
+ if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND))
+ return NULL;
drbg = drbg_setup(master_drbg);
CRYPTO_THREAD_set_local(&private_drbg, drbg);
}