Make the predictable numbers start from 1
[openssl.git] / crypto / rand / md_rand.c
index 9d39831cf231c5643bd16ff94bca8ad2c068987e..88820bbb917674e18644d308d862c6ec30d612e2 100644 (file)
 
 #include <openssl/err.h>
 
+#include <internal/thread_once.h>
+
 #ifdef OPENSSL_FIPS
 # include <openssl/fips.h>
 #endif
 
-#ifdef BN_DEBUG
+#if defined(BN_DEBUG) || defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
 # define PREDICT
 #endif
 
@@ -85,10 +87,12 @@ static RAND_METHOD rand_meth = {
     rand_status
 };
 
-static void do_rand_lock_init(void)
+DEFINE_RUN_ONCE_STATIC(do_rand_lock_init)
 {
+    OPENSSL_init_crypto(0, NULL);
     rand_lock = CRYPTO_THREAD_lock_new();
     rand_tmp_lock = CRYPTO_THREAD_lock_new();
+    return rand_lock != NULL && rand_tmp_lock != NULL;
 }
 
 RAND_METHOD *RAND_OpenSSL(void)
@@ -141,7 +145,8 @@ static int rand_add(const void *buf, int num, double add)
     if (m == NULL)
         goto err;
 
-    CRYPTO_THREAD_run_once(&rand_lock_init, do_rand_lock_init);
+    if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
+        goto err;
 
     /* check if we already have the lock */
     if (crypto_lock_rand) {
@@ -302,7 +307,7 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
 
 #ifdef PREDICT
     if (rand_predictable) {
-        static unsigned char val = 0;
+        unsigned char val = 1;
 
         for (i = 0; i < num; i++)
             buf[i] = val++;
@@ -339,7 +344,9 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
      * global 'md'.
      */
 
-    CRYPTO_THREAD_run_once(&rand_lock_init, do_rand_lock_init);
+    if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
+        goto err_mem;
+
     CRYPTO_THREAD_write_lock(rand_lock);
     /*
      * We could end up in an async engine while holding this lock so ensure
@@ -534,7 +541,9 @@ static int rand_status(void)
     int ret;
     int do_not_lock;
 
-    CRYPTO_THREAD_run_once(&rand_lock_init, do_rand_lock_init);
+    if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
+        return 0;
+
     cur = CRYPTO_THREAD_get_current_id();
     /*
      * check if we already have the lock (could happen if a RAND_poll()