]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Adjust rand_lib to use new thread-local mgmt api
authorNeil Horman <nhorman@openssl.org>
Thu, 12 Jun 2025 17:14:47 +0000 (13:14 -0400)
committerNeil Horman <nhorman@openssl.org>
Fri, 20 Jun 2025 17:01:39 +0000 (13:01 -0400)
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ý <sashan@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/27794)

crypto/rand/rand_lib.c

index 5b9713eda629e327d71acbb0f77272e7095925d1..7cc434c71cb720bb893d242cbc13e7e2c2f63c45 100644 (file)
@@ -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 <public> DRBG
-     *
-     * Used by default for generating random bytes using RAND_bytes().
-     *
-     * The <public> secondary DRBG is thread-local, i.e., there is one instance
-     * per thread.
-     */
-    CRYPTO_THREAD_LOCAL public;
-
-    /*
-     * The <private> DRBG
-     *
-     * Used by default for generating private keys using RAND_priv_bytes()
-     *
-     * The <private> 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;
 }