[openssl-commits] [openssl] master update

matthias.st.pierre at ncp-e.com matthias.st.pierre at ncp-e.com
Tue Feb 13 16:35:35 UTC 2018


The branch master has been updated
       via  d7c402c4f2d9c311a91616fd75c24a15afabe2e5 (commit)
       via  8164d91d1802e6173291dee50923cc60fcd3bf72 (commit)
       via  4f9dabbfe30c3539dd6cb0bd861ddb0127c11c20 (commit)
       via  3ce1c27b56fa9856693e5c98331cebaa2a3accfa (commit)
      from  fcd21502737e96c031bff17fe6b6a432d07e3855 (commit)


- Log -----------------------------------------------------------------
commit d7c402c4f2d9c311a91616fd75c24a15afabe2e5
Author: Dr. Matthias St. Pierre <Matthias.St.Pierre at ncp-e.com>
Date:   Mon Feb 12 02:37:27 2018 +0100

    OPENSSL_cleanup: cleanup secure memory
    
    If the global DRBGs are allocated on the secure heap, then calling
    CRYPTO_secure_malloc_done() inside main() will have no effect, unless
    OPENSSL_cleanup() has been called explicitely before that, because
    otherwise the DRBGs will still be allocated. So it is better to cleanup
    the secure heap automatically at the end of OPENSSL_cleanup().
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5294)

commit 8164d91d1802e6173291dee50923cc60fcd3bf72
Author: Dr. Matthias St. Pierre <Matthias.St.Pierre at ncp-e.com>
Date:   Thu Feb 8 23:04:16 2018 +0100

    DRBG: make the derivation function the default for ctr_drbg
    
    The NIST standard presents two alternative ways for seeding the
    CTR DRBG, depending on whether a derivation function is used or not.
    In Section 10.2.1 of NIST SP800-90Ar1 the following is assessed:
    
      The use of the derivation function is optional if either an
      approved RBG or an entropy source provides full entropy output
      when entropy input is requested by the DRBG mechanism.
      Otherwise, the derivation function shall be used.
    
    Since the OpenSSL DRBG supports being reseeded from low entropy random
    sources (using RAND_POOL), the use of a derivation function is mandatory.
    For that reason we change the default and replace the opt-in flag
    RAND_DRBG_FLAG_CTR_USE_DF with an opt-out flag RAND_DRBG_FLAG_CTR_NO_DF.
    This change simplifies the RAND_DRBG_new() calls.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5294)

commit 4f9dabbfe30c3539dd6cb0bd861ddb0127c11c20
Author: Dr. Matthias St. Pierre <Matthias.St.Pierre at ncp-e.com>
Date:   Thu Feb 8 22:46:23 2018 +0100

    DRBG: unify initialization and cleanup code
    
    The functions drbg_setup() and drbg_cleanup() used to duplicate a lot of
    code from RAND_DRBG_new() and RAND_DRBG_free(). This duplication has been
    removed, which simplifies drbg_setup() and makes drbg_cleanup() obsolete.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5294)

commit 3ce1c27b56fa9856693e5c98331cebaa2a3accfa
Author: Dr. Matthias St. Pierre <Matthias.St.Pierre at ncp-e.com>
Date:   Thu Feb 8 16:40:32 2018 +0100

    DRBG: add locking api
    
    This commit adds three new accessors to the internal DRBG lock
    
       int RAND_DRBG_lock(RAND_DRBG *drbg)
       int RAND_DRBG_unlock(RAND_DRBG *drbg)
       int RAND_DRBG_enable_locking(RAND_DRBG *drbg)
    
    The three shared DRBGs are intended to be used concurrently, so they
    have locking enabled by default. It is the callers responsibility to
    guard access to the shared DRBGs by calls to RAND_DRBG_lock() and
    RAND_DRBG_unlock().
    
    All other DRBG instances don't have locking enabled by default, because
    they are intendended to be used by a single thread. If it is desired,
    locking can be enabled by using RAND_DRBG_enable_locking().
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/5294)

-----------------------------------------------------------------------

Summary of changes:
 crypto/err/openssl.txt    |   3 +
 crypto/init.c             |   2 +
 crypto/rand/drbg_ctr.c    |   6 +-
 crypto/rand/drbg_lib.c    | 167 +++++++++++++++++++++++++++++++++++-----------
 crypto/rand/rand_err.c    |   6 ++
 crypto/rand/rand_lcl.h    |   1 +
 crypto/rand/rand_lib.c    |  17 +++--
 include/internal/rand.h   |   9 ++-
 include/openssl/randerr.h |   3 +
 ssl/ssl_lib.c             |   3 +-
 test/drbgtest.c           |  19 +++---
 util/libcrypto.num        |   4 ++
 12 files changed, 176 insertions(+), 64 deletions(-)

diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 3ed71fe..8d00463 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -890,6 +890,7 @@ RAND_F_DRBG_GET_ENTROPY:105:drbg_get_entropy
 RAND_F_DRBG_SETUP:117:drbg_setup
 RAND_F_GET_ENTROPY:106:get_entropy
 RAND_F_RAND_BYTES:100:RAND_bytes
+RAND_F_RAND_DRBG_ENABLE_LOCKING:119:RAND_DRBG_enable_locking
 RAND_F_RAND_DRBG_GENERATE:107:RAND_DRBG_generate
 RAND_F_RAND_DRBG_INSTANTIATE:108:RAND_DRBG_instantiate
 RAND_F_RAND_DRBG_NEW:109:RAND_DRBG_new
@@ -2256,6 +2257,7 @@ RAND_R_ADDITIONAL_INPUT_TOO_LONG:102:additional input too long
 RAND_R_ALREADY_INSTANTIATED:103:already instantiated
 RAND_R_ARGUMENT_OUT_OF_RANGE:105:argument out of range
 RAND_R_CANNOT_OPEN_FILE:121:Cannot open file
+RAND_R_DRBG_ALREADY_INITIALIZED:129:drbg already initialized
 RAND_R_DRBG_NOT_INITIALISED:104:drbg not initialised
 RAND_R_ENTROPY_INPUT_TOO_LONG:106:entropy input too long
 RAND_R_ENTROPY_OUT_OF_RANGE:124:entropy out of range
@@ -2274,6 +2276,7 @@ RAND_R_IN_ERROR_STATE:114:in error state
 RAND_R_NOT_A_REGULAR_FILE:122:Not a regular file
 RAND_R_NOT_INSTANTIATED:115:not instantiated
 RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED:128:no drbg implementation selected
+RAND_R_PARENT_LOCKING_NOT_ENABLED:130:parent locking not enabled
 RAND_R_PERSONALISATION_STRING_TOO_LONG:116:personalisation string too long
 RAND_R_PRNG_NOT_SEEDED:100:PRNG not seeded
 RAND_R_RANDOM_POOL_OVERFLOW:125:random pool overflow
diff --git a/crypto/init.c b/crypto/init.c
index 1b94d07..4a88e9c 100644
--- a/crypto/init.c
+++ b/crypto/init.c
@@ -502,6 +502,8 @@ void OPENSSL_cleanup(void)
     obj_cleanup_int();
     err_cleanup();
 
+    CRYPTO_secure_malloc_done();
+
     base_inited = 0;
 }
 
diff --git a/crypto/rand/drbg_ctr.c b/crypto/rand/drbg_ctr.c
index 883c585..99cd997 100644
--- a/crypto/rand/drbg_ctr.c
+++ b/crypto/rand/drbg_ctr.c
@@ -221,7 +221,7 @@ static void ctr_update(RAND_DRBG *drbg,
         memcpy(ctr->V, ctr->K + 24, 8);
     }
 
-    if (drbg->flags & RAND_DRBG_FLAG_CTR_USE_DF) {
+    if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) {
         /* If no input reuse existing derived value */
         if (in1 != NULL || nonce != NULL || in2 != NULL)
             ctr_df(ctr, in1, in1len, nonce, noncelen, in2, in2len);
@@ -272,7 +272,7 @@ static int drbg_ctr_generate(RAND_DRBG *drbg,
     if (adin != NULL && adinlen != 0) {
         ctr_update(drbg, adin, adinlen, NULL, 0, NULL, 0);
         /* This means we reuse derived value */
-        if (drbg->flags & RAND_DRBG_FLAG_CTR_USE_DF) {
+        if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) {
             adin = NULL;
             adinlen = 1;
         }
@@ -338,7 +338,7 @@ int drbg_ctr_init(RAND_DRBG *drbg)
     drbg->strength = keylen * 8;
     drbg->seedlen = keylen + 16;
 
-    if (drbg->flags & RAND_DRBG_FLAG_CTR_USE_DF) {
+    if ((drbg->flags & RAND_DRBG_FLAG_CTR_NO_DF) == 0) {
         /* df initialisation */
         static unsigned char df_key[32] = {
             0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c
index 4404e4f..c592a7b 100644
--- a/crypto/rand/drbg_lib.c
+++ b/crypto/rand/drbg_lib.c
@@ -90,6 +90,21 @@ static RAND_DRBG *drbg_private;
  * |randomness| argument). This will immediately reseed the <master> DRBG.
  * The <public> and <private> DRBG will detect this on their next generate
  * call and reseed, pulling randomness from <master>.
+ *
+ * LOCKING
+ *
+ * The three shared DRBGs are intended to be used concurrently, so they
+ * support locking by default. It is the callers responsibility to wrap
+ * calls to functions like RAND_DRBG_generate() which modify the DRBGs
+ * internal state with calls to RAND_DRBG_lock() and RAND_DRBG_unlock().
+ * The functions RAND_bytes() and RAND_priv_bytes() take the locks
+ * automatically, so using the RAND api is thread safe as before.
+ *
+ * All other DRBG instances don't have locking enabled by default, because
+ * they are intendended to be used by a single thread. If it is desired,
+ * locking can be enabled using RAND_DRBG_enable_locking(). However, instead
+ * of accessing a single DRBG instance concurrently from different threads,
+ * it is recommended to instantiate a separate DRBG instance per thread.
  */
 
 
@@ -99,7 +114,11 @@ static const char ossl_pers_string[] = "OpenSSL NIST SP 800-90A DRBG";
 static CRYPTO_ONCE rand_drbg_init = CRYPTO_ONCE_STATIC_INIT;
 
 static RAND_DRBG *drbg_setup(RAND_DRBG *parent);
-static void drbg_cleanup(RAND_DRBG *drbg);
+
+static RAND_DRBG *rand_drbg_new(int secure,
+                                int type,
+                                unsigned int flags,
+                                RAND_DRBG *parent);
 
 /*
  * Set/initialize |drbg| to be of type |nid|, with optional |flags|.
@@ -134,19 +153,26 @@ int RAND_DRBG_set(RAND_DRBG *drbg, int nid, unsigned int flags)
 }
 
 /*
- * Allocate memory and initialize a new DRBG.  The |parent|, if not
- * NULL, will be used to auto-seed this RAND_DRBG as needed.
+ * Allocate memory and initialize a new DRBG. The DRBG is allocated on
+ * the secure heap if |secure| is nonzero and the secure heap is enabled.
+ * The |parent|, if not NULL, will be used as random source for reseeding.
  *
  * Returns a pointer to the new DRBG instance on success, NULL on failure.
  */
-RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent)
+static RAND_DRBG *rand_drbg_new(int secure,
+                                int type,
+                                unsigned int flags,
+                                RAND_DRBG *parent)
 {
-    RAND_DRBG *drbg = OPENSSL_zalloc(sizeof(*drbg));
+    RAND_DRBG *drbg = secure ?
+        OPENSSL_secure_zalloc(sizeof(*drbg)) : OPENSSL_zalloc(sizeof(*drbg));
 
     if (drbg == NULL) {
         RANDerr(RAND_F_RAND_DRBG_NEW, ERR_R_MALLOC_FAILURE);
         goto err;
     }
+
+    drbg->secure = secure && CRYPTO_secure_allocated(drbg);
     drbg->fork_count = rand_fork_count;
     drbg->parent = parent;
     if (RAND_DRBG_set(drbg, type, flags) == 0)
@@ -160,10 +186,24 @@ RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent)
     return drbg;
 
 err:
-    OPENSSL_free(drbg);
+    if (drbg->secure)
+        OPENSSL_secure_free(drbg);
+    else
+        OPENSSL_free(drbg);
+
     return NULL;
 }
 
+RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent)
+{
+    return rand_drbg_new(0, type, flags, parent);
+}
+
+RAND_DRBG *RAND_DRBG_secure_new(int type, unsigned int flags, RAND_DRBG *parent)
+{
+    return rand_drbg_new(1, type, flags, parent);
+}
+
 /*
  * Uninstantiate |drbg| and free all memory.
  */
@@ -174,8 +214,13 @@ void RAND_DRBG_free(RAND_DRBG *drbg)
 
     if (drbg->meth != NULL)
         drbg->meth->uninstantiate(drbg);
+    CRYPTO_THREAD_lock_free(drbg->lock);
     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
-    OPENSSL_clear_free(drbg, sizeof(*drbg));
+
+    if (drbg->secure)
+        OPENSSL_secure_clear_free(drbg, sizeof(*drbg));
+    else
+        OPENSSL_clear_free(drbg, sizeof(*drbg));
 }
 
 /*
@@ -656,6 +701,69 @@ int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval)
     return 1;
 }
 
+
+/*
+ * Locks the given drbg. Locking a drbg which does not have locking
+ * enabled is considered a successful no-op.
+ *
+ * Returns 1 on success, 0 on failure.
+ */
+int RAND_DRBG_lock(RAND_DRBG *drbg)
+{
+    if (drbg->lock != NULL)
+        return CRYPTO_THREAD_write_lock(drbg->lock);
+
+    return 1;
+}
+
+/*
+ * Unlocks the given drbg. Unlocking a drbg which does not have locking
+ * enabled is considered a successful no-op.
+ *
+ * Returns 1 on success, 0 on failure.
+ */
+int RAND_DRBG_unlock(RAND_DRBG *drbg)
+{
+    if (drbg->lock != NULL)
+        return CRYPTO_THREAD_unlock(drbg->lock);
+
+    return 1;
+}
+
+/*
+ * Enables locking for the given drbg
+ *
+ * Locking can only be enabled if the random generator
+ * is in the uninitialized state.
+ *
+ * Returns 1 on success, 0 on failure.
+ */
+int RAND_DRBG_enable_locking(RAND_DRBG *drbg)
+{
+    if (drbg->state != DRBG_UNINITIALISED) {
+        RANDerr(RAND_F_RAND_DRBG_ENABLE_LOCKING,
+                RAND_R_DRBG_ALREADY_INITIALIZED);
+        return 0;
+    }
+
+    if (drbg->lock == NULL) {
+        if (drbg->parent != NULL && drbg->parent->lock == NULL) {
+            RANDerr(RAND_F_RAND_DRBG_ENABLE_LOCKING,
+                    RAND_R_PARENT_LOCKING_NOT_ENABLED);
+            return 0;
+        }
+
+        drbg->lock = CRYPTO_THREAD_lock_new();
+        if (drbg->lock == NULL) {
+            RANDerr(RAND_F_RAND_DRBG_ENABLE_LOCKING,
+                    RAND_R_FAILED_TO_CREATE_LOCK);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
 /*
  * Get and set the EXDATA
  */
@@ -685,28 +793,17 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent)
 {
     RAND_DRBG *drbg;
 
-    drbg = OPENSSL_secure_zalloc(sizeof(RAND_DRBG));
+    drbg = RAND_DRBG_secure_new(RAND_DRBG_NID, 0, parent);
     if (drbg == NULL)
         return NULL;
 
-    drbg->lock = CRYPTO_THREAD_lock_new();
-    if (drbg->lock == NULL) {
-        RANDerr(RAND_F_DRBG_SETUP, RAND_R_FAILED_TO_CREATE_LOCK);
-        goto err;
-    }
-
-    if (RAND_DRBG_set(drbg,
-                      RAND_DRBG_NID, RAND_DRBG_FLAG_CTR_USE_DF) != 1)
-        goto err;
-    if (RAND_DRBG_set_callbacks(drbg, rand_drbg_get_entropy,
-                                rand_drbg_cleanup_entropy, NULL, NULL) != 1)
+    if (RAND_DRBG_enable_locking(drbg) == 0)
         goto err;
 
     if (parent == NULL) {
         drbg->reseed_interval = MASTER_RESEED_INTERVAL;
         drbg->reseed_time_interval = MASTER_RESEED_TIME_INTERVAL;
     } else {
-        drbg->parent = parent;
         drbg->reseed_interval = SLAVE_RESEED_INTERVAL;
         drbg->reseed_time_interval = SLAVE_RESEED_TIME_INTERVAL;
     }
@@ -726,7 +823,7 @@ static RAND_DRBG *drbg_setup(RAND_DRBG *parent)
     return drbg;
 
 err:
-    drbg_cleanup(drbg);
+    RAND_DRBG_free(drbg);
     return NULL;
 }
 
@@ -753,22 +850,12 @@ DEFINE_RUN_ONCE_STATIC(do_rand_drbg_init)
     return 1;
 }
 
-/* Cleans up the given global DRBG  */
-static void drbg_cleanup(RAND_DRBG *drbg)
-{
-    if (drbg != NULL) {
-        RAND_DRBG_uninstantiate(drbg);
-        CRYPTO_THREAD_lock_free(drbg->lock);
-        OPENSSL_secure_clear_free(drbg, sizeof(RAND_DRBG));
-    }
-}
-
 /* Clean up the global DRBGs before exit */
 void rand_drbg_cleanup_int(void)
 {
-    drbg_cleanup(drbg_private);
-    drbg_cleanup(drbg_public);
-    drbg_cleanup(drbg_master);
+    RAND_DRBG_free(drbg_private);
+    RAND_DRBG_free(drbg_public);
+    RAND_DRBG_free(drbg_master);
 
     drbg_private = drbg_public = drbg_master = NULL;
 }
@@ -782,9 +869,9 @@ static int drbg_bytes(unsigned char *out, int count)
     if (drbg == NULL)
         return 0;
 
-    CRYPTO_THREAD_write_lock(drbg->lock);
+    RAND_DRBG_lock(drbg);
     ret = RAND_DRBG_bytes(drbg, out, count);
-    CRYPTO_THREAD_unlock(drbg->lock);
+    RAND_DRBG_unlock(drbg);
 
     return ret;
 }
@@ -811,11 +898,11 @@ static int drbg_add(const void *buf, int num, double randomness)
         return 0;
     }
 
-    CRYPTO_THREAD_write_lock(drbg->lock);
+    RAND_DRBG_lock(drbg);
     ret = rand_drbg_restart(drbg, buf,
                             (size_t)(unsigned int)num,
                             (size_t)(8*randomness));
-    CRYPTO_THREAD_unlock(drbg->lock);
+    RAND_DRBG_unlock(drbg);
 
     return ret;
 }
@@ -835,9 +922,9 @@ static int drbg_status(void)
     if (drbg == NULL)
         return 0;
 
-    CRYPTO_THREAD_write_lock(drbg->lock);
+    RAND_DRBG_lock(drbg);
     ret = drbg->state == DRBG_READY ? 1 : 0;
-    CRYPTO_THREAD_unlock(drbg->lock);
+    RAND_DRBG_unlock(drbg);
     return ret;
 }
 
diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c
index 9eadbf9..e8ec44a 100644
--- a/crypto/rand/rand_err.c
+++ b/crypto/rand/rand_err.c
@@ -19,6 +19,8 @@ static const ERR_STRING_DATA RAND_str_functs[] = {
     {ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_SETUP, 0), "drbg_setup"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_GET_ENTROPY, 0), "get_entropy"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_BYTES, 0), "RAND_bytes"},
+    {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_ENABLE_LOCKING, 0),
+     "RAND_DRBG_enable_locking"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GENERATE, 0),
      "RAND_DRBG_generate"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_INSTANTIATE, 0),
@@ -49,6 +51,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = {
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ARGUMENT_OUT_OF_RANGE),
     "argument out of range"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_CANNOT_OPEN_FILE), "Cannot open file"},
+    {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_DRBG_ALREADY_INITIALIZED),
+    "drbg already initialized"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_DRBG_NOT_INITIALISED),
     "drbg not initialised"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ENTROPY_INPUT_TOO_LONG),
@@ -80,6 +84,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = {
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NOT_INSTANTIATED), "not instantiated"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED),
     "no drbg implementation selected"},
+    {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PARENT_LOCKING_NOT_ENABLED),
+    "parent locking not enabled"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PERSONALISATION_STRING_TOO_LONG),
     "personalisation string too long"},
     {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"},
diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h
index e3c0b76..a63b28b 100644
--- a/crypto/rand/rand_lcl.h
+++ b/crypto/rand/rand_lcl.h
@@ -115,6 +115,7 @@ typedef struct rand_drbg_ctr_st {
 struct rand_drbg_st {
     CRYPTO_RWLOCK *lock;
     RAND_DRBG *parent;
+    int secure; /* 1: allocated on the secure heap, 0: otherwise */
     int nid; /* the underlying algorithm */
     int fork_count;
     unsigned short flags; /* various external flags */
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index faec18d..289acf3 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -200,17 +200,16 @@ size_t rand_drbg_get_entropy(RAND_DRBG *drbg,
             /*
              * Get random from parent, include our state as additional input.
              * Our lock is already held, but we need to lock our parent before
-             * generating bits from it.
+             * generating bits from it. (Note: taking the lock will be a no-op
+             * if locking if drbg->parent->lock == NULL.)
              */
-            if (drbg->parent->lock)
-                CRYPTO_THREAD_write_lock(drbg->parent->lock);
+            RAND_DRBG_lock(drbg->parent);
             if (RAND_DRBG_generate(drbg->parent,
                                    buffer, bytes_needed,
                                    0,
                                    (unsigned char *)drbg, sizeof(*drbg)) != 0)
                 bytes = bytes_needed;
-            if (drbg->parent->lock)
-                CRYPTO_THREAD_unlock(drbg->parent->lock);
+            RAND_DRBG_unlock(drbg->parent);
 
             entropy_available = RAND_POOL_add_end(pool, bytes, 8 * bytes);
         }
@@ -406,9 +405,9 @@ int RAND_poll(void)
         if (drbg == NULL)
             return 0;
 
-        CRYPTO_THREAD_write_lock(drbg->lock);
+        RAND_DRBG_lock(drbg);
         ret = rand_drbg_restart(drbg, NULL, 0, 0);
-        CRYPTO_THREAD_unlock(drbg->lock);
+        RAND_DRBG_unlock(drbg);
 
         return ret;
 
@@ -798,9 +797,9 @@ int RAND_priv_bytes(unsigned char *buf, int num)
         return 0;
 
     /* We have to lock the DRBG before generating bits from it. */
-    CRYPTO_THREAD_write_lock(drbg->lock);
+    RAND_DRBG_lock(drbg);
     ret = RAND_DRBG_bytes(drbg, buf, num);
-    CRYPTO_THREAD_unlock(drbg->lock);
+    RAND_DRBG_unlock(drbg);
     return ret;
 }
 
diff --git a/include/internal/rand.h b/include/internal/rand.h
index 575e6ca..8d3e452 100644
--- a/include/internal/rand.h
+++ b/include/internal/rand.h
@@ -10,8 +10,8 @@
 #ifndef HEADER_DRBG_RAND_H
 # define HEADER_DRBG_RAND_H
 
-/* In CTR mode, use derivation function ctr_df */
-#define RAND_DRBG_FLAG_CTR_USE_DF            0x2
+/* In CTR mode, disable derivation function ctr_df */
+#define RAND_DRBG_FLAG_CTR_NO_DF            0x1
 
 /*
  * Default security strength (in the sense of [NIST SP 800-90Ar1])
@@ -28,6 +28,7 @@
  * Object lifetime functions.
  */
 RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent);
+RAND_DRBG *RAND_DRBG_secure_new(int type, unsigned int flags, RAND_DRBG *parent);
 int RAND_DRBG_set(RAND_DRBG *drbg, int type, unsigned int flags);
 int RAND_DRBG_instantiate(RAND_DRBG *drbg,
                           const unsigned char *pers, size_t perslen);
@@ -47,6 +48,10 @@ int RAND_DRBG_bytes(RAND_DRBG *drbg, unsigned char *out, size_t outlen);
 int RAND_DRBG_set_reseed_interval(RAND_DRBG *drbg, unsigned int interval);
 int RAND_DRBG_set_reseed_time_interval(RAND_DRBG *drbg, time_t interval);
 
+int RAND_DRBG_lock(RAND_DRBG *drbg);
+int RAND_DRBG_unlock(RAND_DRBG *drbg);
+int RAND_DRBG_enable_locking(RAND_DRBG *drbg);
+
 RAND_DRBG *RAND_DRBG_get0_master(void);
 RAND_DRBG *RAND_DRBG_get0_public(void);
 RAND_DRBG *RAND_DRBG_get0_private(void);
diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h
index ae5a2ea..4cfc06d 100644
--- a/include/openssl/randerr.h
+++ b/include/openssl/randerr.h
@@ -24,6 +24,7 @@ int ERR_load_RAND_strings(void);
 # define RAND_F_DRBG_SETUP                                117
 # define RAND_F_GET_ENTROPY                               106
 # define RAND_F_RAND_BYTES                                100
+# define RAND_F_RAND_DRBG_ENABLE_LOCKING                  119
 # define RAND_F_RAND_DRBG_GENERATE                        107
 # define RAND_F_RAND_DRBG_INSTANTIATE                     108
 # define RAND_F_RAND_DRBG_NEW                             109
@@ -46,6 +47,7 @@ int ERR_load_RAND_strings(void);
 # define RAND_R_ALREADY_INSTANTIATED                      103
 # define RAND_R_ARGUMENT_OUT_OF_RANGE                     105
 # define RAND_R_CANNOT_OPEN_FILE                          121
+# define RAND_R_DRBG_ALREADY_INITIALIZED                  129
 # define RAND_R_DRBG_NOT_INITIALISED                      104
 # define RAND_R_ENTROPY_INPUT_TOO_LONG                    106
 # define RAND_R_ENTROPY_OUT_OF_RANGE                      124
@@ -64,6 +66,7 @@ int ERR_load_RAND_strings(void);
 # define RAND_R_NOT_A_REGULAR_FILE                        122
 # define RAND_R_NOT_INSTANTIATED                          115
 # define RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED           128
+# define RAND_R_PARENT_LOCKING_NOT_ENABLED                130
 # define RAND_R_PERSONALISATION_STRING_TOO_LONG           116
 # define RAND_R_PRNG_NOT_SEEDED                           100
 # define RAND_R_RANDOM_POOL_OVERFLOW                      125
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 6a5c03d..00e02f4 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -694,8 +694,7 @@ SSL *SSL_new(SSL_CTX *ctx)
      */
     if (RAND_get_rand_method() == RAND_OpenSSL()) {
         s->drbg =
-            RAND_DRBG_new(RAND_DRBG_NID, RAND_DRBG_FLAG_CTR_USE_DF,
-                          RAND_DRBG_get0_public());
+            RAND_DRBG_new(RAND_DRBG_NID, 0, RAND_DRBG_get0_public());
         if (s->drbg == NULL
             || RAND_DRBG_instantiate(s->drbg,
                                      (const unsigned char *) SSL_version_str,
diff --git a/test/drbgtest.c b/test/drbgtest.c
index 6e916c4..c64628a 100644
--- a/test/drbgtest.c
+++ b/test/drbgtest.c
@@ -88,16 +88,19 @@ typedef struct drbg_selftest_data_st {
     pr##_pr_returnedbits, sizeof(pr##_pr_returnedbits) \
     }
 
-#define make_drbg_test_data_df(nid, pr, p) \
-    make_drbg_test_data(nid, RAND_DRBG_FLAG_CTR_USE_DF, pr, p)
+#define make_drbg_test_data_use_df(nid, pr, p) \
+    make_drbg_test_data(nid, 0, pr, p)
+
+#define make_drbg_test_data_no_df(nid, pr, p)                      \
+    make_drbg_test_data(nid, RAND_DRBG_FLAG_CTR_NO_DF, pr, p)
 
 static DRBG_SELFTEST_DATA drbg_test[] = {
-    make_drbg_test_data   (NID_aes_128_ctr, 0, aes_128_no_df, 0),
-    make_drbg_test_data   (NID_aes_192_ctr, 0, aes_192_no_df, 0),
-    make_drbg_test_data   (NID_aes_256_ctr, 0, aes_256_no_df, 1),
-    make_drbg_test_data_df(NID_aes_128_ctr,    aes_128_use_df, 0),
-    make_drbg_test_data_df(NID_aes_192_ctr,    aes_192_use_df, 0),
-    make_drbg_test_data_df(NID_aes_256_ctr,    aes_256_use_df, 1),
+    make_drbg_test_data_no_df (NID_aes_128_ctr, aes_128_no_df,  0),
+    make_drbg_test_data_no_df (NID_aes_192_ctr, aes_192_no_df,  0),
+    make_drbg_test_data_no_df (NID_aes_256_ctr, aes_256_no_df,  1),
+    make_drbg_test_data_use_df(NID_aes_128_ctr, aes_128_use_df, 0),
+    make_drbg_test_data_use_df(NID_aes_192_ctr, aes_192_use_df, 0),
+    make_drbg_test_data_use_df(NID_aes_256_ctr, aes_256_use_df, 1),
 };
 
 static int app_data_index;
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 5005d9a..c7be540 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4501,3 +4501,7 @@ EVP_sha512_256                          4442	1_1_1	EXIST::FUNCTION:
 EVP_sha512_224                          4443	1_1_1	EXIST::FUNCTION:
 OCSP_basic_sign_ctx                     4444	1_1_1	EXIST::FUNCTION:OCSP
 RAND_DRBG_bytes                         4445	1_1_1	EXIST::FUNCTION:
+RAND_DRBG_lock                          4446	1_1_1	EXIST::FUNCTION:
+RAND_DRBG_unlock                        4447	1_1_1	EXIST::FUNCTION:
+RAND_DRBG_enable_locking                4448	1_1_1	EXIST::FUNCTION:
+RAND_DRBG_secure_new                    4449	1_1_1	EXIST::FUNCTION:


More information about the openssl-commits mailing list