From: Neil Horman Date: Thu, 12 Jun 2025 17:14:47 +0000 (-0400) Subject: Adjust rand_lib to use new thread-local mgmt api X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=ce990ce83b55754df70b5abcb82e738fe3fc5c06;p=thirdparty%2Fopenssl.git Adjust rand_lib to use new thread-local mgmt api Rand instances create a thread-local storage key per context, so we need to move them to the new api to avoid exhausting our thread-local storage space at the Os level Reviewed-by: Saša Nedvědický Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/27794) --- diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 5b9713eda62..7cc434c71cb 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -17,6 +17,7 @@ #include "internal/cryptlib.h" #include "internal/provider.h" #include "internal/thread_once.h" +#include "internal/threads_common.h" #include "crypto/rand.h" #include "crypto/cryptlib.h" #include "rand_local.h" @@ -61,26 +62,6 @@ typedef struct rand_global_st { char *random_provider_name; #endif /* !FIPS_MODULE */ - /* - * The DRBG - * - * Used by default for generating random bytes using RAND_bytes(). - * - * The secondary DRBG is thread-local, i.e., there is one instance - * per thread. - */ - CRYPTO_THREAD_LOCAL public; - - /* - * The DRBG - * - * Used by default for generating private keys using RAND_priv_bytes() - * - * The secondary DRBG is thread-local, i.e., there is one - * instance per thread. - */ - CRYPTO_THREAD_LOCAL private; - /* Which RNG is being used by default and it's configuration settings */ char *rng_name; char *rng_cipher; @@ -540,16 +521,8 @@ void *ossl_rand_ctx_new(OSSL_LIB_CTX *libctx) if (dgbl->lock == NULL) goto err1; - if (!CRYPTO_THREAD_init_local(&dgbl->private, NULL)) - goto err1; - - if (!CRYPTO_THREAD_init_local(&dgbl->public, NULL)) - goto err2; - return dgbl; - err2: - CRYPTO_THREAD_cleanup_local(&dgbl->private); err1: CRYPTO_THREAD_lock_free(dgbl->lock); #ifndef FIPS_MODULE @@ -568,8 +541,6 @@ void ossl_rand_ctx_free(void *vdgbl) return; CRYPTO_THREAD_lock_free(dgbl->lock); - CRYPTO_THREAD_cleanup_local(&dgbl->private); - CRYPTO_THREAD_cleanup_local(&dgbl->public); EVP_RAND_CTX_free(dgbl->primary); EVP_RAND_CTX_free(dgbl->seed); #ifndef FIPS_MODULE @@ -594,12 +565,12 @@ static void rand_delete_thread_state(void *arg) if (dgbl == NULL) return; - rand = CRYPTO_THREAD_get_local(&dgbl->public); - CRYPTO_THREAD_set_local(&dgbl->public, NULL); + rand = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx); + CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx, NULL); EVP_RAND_CTX_free(rand); - rand = CRYPTO_THREAD_get_local(&dgbl->private); - CRYPTO_THREAD_set_local(&dgbl->private, NULL); + rand = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx); + CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx, NULL); EVP_RAND_CTX_free(rand); } @@ -838,30 +809,32 @@ EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx) static EVP_RAND_CTX *rand_get0_public(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl) { EVP_RAND_CTX *rand, *primary; + OSSL_LIB_CTX *origctx = ctx; + + ctx = ossl_lib_ctx_get_concrete(ctx); + + if (ctx == NULL) + return NULL; if (dgbl == NULL) return NULL; - rand = CRYPTO_THREAD_get_local(&dgbl->public); + rand = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx); if (rand == NULL) { - primary = rand_get0_primary(ctx, dgbl); + primary = rand_get0_primary(origctx, dgbl); if (primary == NULL) return NULL; - ctx = ossl_lib_ctx_get_concrete(ctx); - - if (ctx == NULL) - return NULL; /* * If the private is also NULL then this is the first time we've * used this thread. */ - if (CRYPTO_THREAD_get_local(&dgbl->private) == NULL + if (CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx) == NULL && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state)) return NULL; rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL, SECONDARY_RESEED_TIME_INTERVAL); - CRYPTO_THREAD_set_local(&dgbl->public, rand); + CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx, rand); } return rand; } @@ -880,27 +853,28 @@ EVP_RAND_CTX *RAND_get0_public(OSSL_LIB_CTX *ctx) static EVP_RAND_CTX *rand_get0_private(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl) { EVP_RAND_CTX *rand, *primary; + OSSL_LIB_CTX *origctx = ctx; + + ctx = ossl_lib_ctx_get_concrete(ctx); + if (ctx == NULL) + return NULL; - rand = CRYPTO_THREAD_get_local(&dgbl->private); + rand = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx); if (rand == NULL) { - primary = rand_get0_primary(ctx, dgbl); + primary = rand_get0_primary(origctx, dgbl); if (primary == NULL) return NULL; - ctx = ossl_lib_ctx_get_concrete(ctx); - - if (ctx == NULL) - return NULL; /* * If the public is also NULL then this is the first time we've * used this thread. */ - if (CRYPTO_THREAD_get_local(&dgbl->public) == NULL + if (CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx) == NULL && !ossl_init_thread_start(NULL, ctx, rand_delete_thread_state)) return NULL; rand = rand_new_drbg(ctx, primary, SECONDARY_RESEED_INTERVAL, SECONDARY_RESEED_TIME_INTERVAL); - CRYPTO_THREAD_set_local(&dgbl->private, rand); + CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx, rand); } return rand; } @@ -924,7 +898,7 @@ EVP_RAND_CTX *ossl_rand_get0_private_noncreating(OSSL_LIB_CTX *ctx) if (dgbl == NULL) return NULL; - return CRYPTO_THREAD_get_local(&dgbl->private); + return CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx); } #endif @@ -936,8 +910,8 @@ int RAND_set0_public(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand) if (dgbl == NULL) return 0; - old = CRYPTO_THREAD_get_local(&dgbl->public); - if ((r = CRYPTO_THREAD_set_local(&dgbl->public, rand)) > 0) + old = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx); + if ((r = CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PUB_KEY, ctx, rand)) > 0) EVP_RAND_CTX_free(old); return r; } @@ -950,8 +924,8 @@ int RAND_set0_private(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand) if (dgbl == NULL) return 0; - old = CRYPTO_THREAD_get_local(&dgbl->private); - if ((r = CRYPTO_THREAD_set_local(&dgbl->private, rand)) > 0) + old = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx); + if ((r = CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_DRBG_PRIV_KEY, ctx, rand)) > 0) EVP_RAND_CTX_free(old); return r; }