[openssl] master update
Matt Caswell
matt at openssl.org
Fri Jun 7 11:57:51 UTC 2019
The branch master has been updated
via 37ca204b96b036f949b8bc8389c1f8e806e1cbec (commit)
via a2f27fd750b9ae62a571a9212c7154889100bdb0 (commit)
via 4e297b7441a070f9dd557445665365b4377e9498 (commit)
via da0d114cd962e89b2614f4707902c404acab7ebd (commit)
from bab6046146c4fc8f088c1aaca11598ede7609c04 (commit)
- Log -----------------------------------------------------------------
commit 37ca204b96b036f949b8bc8389c1f8e806e1cbec
Author: Matt Caswell <matt at openssl.org>
Date: Wed May 29 16:03:57 2019 +0100
Add documentation for new functions taking an OPENSSL_CTX parameter
Various functions have been added that take an OPENSSL_CTX parameter as
a result of moving the RAND code into the FIPS module. We document all of
those functions.
Reviewed-by: Richard Levitte <levitte at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9039)
commit a2f27fd750b9ae62a571a9212c7154889100bdb0
Author: Matt Caswell <matt at openssl.org>
Date: Fri May 24 16:36:44 2019 +0100
Move the rand_nonce_lock code into drbg_lib.c
It was previously rand_lib but it makes more sense in drbg_lib.c since
all the functions that use this lock are only ever called from drbg_lib.c
We add some FIPS_MODE defines in preparation for later moving this code
into the FIPS module.
Reviewed-by: Richard Levitte <levitte at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9039)
commit 4e297b7441a070f9dd557445665365b4377e9498
Author: Matt Caswell <matt at openssl.org>
Date: Thu May 23 16:51:55 2019 +0100
Make the rand_crng code OPENSSL_CTX aware
This is in preparation for moving this code inside the FIPS module.
Reviewed-by: Richard Levitte <levitte at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9039)
commit da0d114cd962e89b2614f4707902c404acab7ebd
Author: Matt Caswell <matt at openssl.org>
Date: Thu May 23 14:35:31 2019 +0100
Convert drbg_lib to use OPENSSL_CTX for its global data
In preparation for moving the RAND code into the FIPS module we make
drbg_lib.c OPENSSL_CTX aware.
Reviewed-by: Richard Levitte <levitte at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9039)
-----------------------------------------------------------------------
Summary of changes:
crypto/include/internal/rand_int.h | 1 -
crypto/init.c | 4 +-
crypto/rand/drbg_lib.c | 358 ++++++++++++++++++++++++++-----------
crypto/rand/rand_crng_test.c | 105 ++++++-----
crypto/rand/rand_lcl.h | 18 +-
crypto/rand/rand_lib.c | 125 ++++---------
doc/man3/RAND_DRBG_get0_master.pod | 34 +++-
doc/man3/RAND_DRBG_new.pod | 25 ++-
include/internal/cryptlib.h | 5 +-
include/openssl/rand_drbg.h | 7 +
test/drbgtest.c | 15 +-
util/libcrypto.num | 5 +
12 files changed, 426 insertions(+), 276 deletions(-)
diff --git a/crypto/include/internal/rand_int.h b/crypto/include/internal/rand_int.h
index b745393..53896ce 100644
--- a/crypto/include/internal/rand_int.h
+++ b/crypto/include/internal/rand_int.h
@@ -24,7 +24,6 @@
typedef struct rand_pool_st RAND_POOL;
void rand_cleanup_int(void);
-void rand_drbg_cleanup_int(void);
void drbg_delete_thread_state(void);
void rand_fork(void);
diff --git a/crypto/init.c b/crypto/init.c
index 58fff70..e73c9ba 100644
--- a/crypto/init.c
+++ b/crypto/init.c
@@ -560,9 +560,6 @@ void OPENSSL_cleanup(void)
OSSL_TRACE(INIT, "OPENSSL_cleanup: rand_cleanup_int()\n");
rand_cleanup_int();
- OSSL_TRACE(INIT, "OPENSSL_cleanup: rand_drbg_cleanup_int()\n");
- rand_drbg_cleanup_int();
-
OSSL_TRACE(INIT, "OPENSSL_cleanup: conf_modules_free_int()\n");
conf_modules_free_int();
@@ -855,5 +852,6 @@ void OPENSSL_fork_parent(void)
void OPENSSL_fork_child(void)
{
rand_fork();
+ /* TODO(3.0): Inform all providers about a fork event */
}
#endif
diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c
index fbe75e6..26e2ccb 100644
--- a/crypto/rand/drbg_lib.c
+++ b/crypto/rand/drbg_lib.c
@@ -29,49 +29,54 @@
* a much bigger deal than just re-setting an allocated resource.)
*/
-/*
- * The three shared DRBG instances
- *
- * There are three shared DRBG instances: <master>, <public>, and <private>.
- */
-/*
- * The <master> DRBG
- *
- * Not used directly by the application, only for reseeding the two other
- * DRBGs. It reseeds itself by pulling either randomness from os entropy
- * sources or by consuming randomness which was added by RAND_add().
- *
- * The <master> DRBG is a global instance which is accessed concurrently by
- * all threads. The necessary locking is managed automatically by its child
- * DRBG instances during reseeding.
- */
-static RAND_DRBG *master_drbg;
-/*
- * The <public> DRBG
- *
- * Used by default for generating random bytes using RAND_bytes().
- *
- * The <public> DRBG is thread-local, i.e., there is one instance per thread.
- */
-static CRYPTO_THREAD_LOCAL public_drbg;
-/*
- * The <private> DRBG
- *
- * Used by default for generating private keys using RAND_priv_bytes()
- *
- * The <private> DRBG is thread-local, i.e., there is one instance per thread.
- */
-static CRYPTO_THREAD_LOCAL private_drbg;
+typedef struct drbg_global_st {
+ /*
+ * The three shared DRBG instances
+ *
+ * There are three shared DRBG instances: <master>, <public>, and <private>.
+ */
+ /*
+ * The <master> DRBG
+ *
+ * Not used directly by the application, only for reseeding the two other
+ * DRBGs. It reseeds itself by pulling either randomness from os entropy
+ * sources or by consuming randomness which was added by RAND_add().
+ *
+ * The <master> DRBG is a global instance which is accessed concurrently by
+ * all threads. The necessary locking is managed automatically by its child
+ * DRBG instances during reseeding.
+ */
+ RAND_DRBG *master_drbg;
+ /*
+ * The <public> DRBG
+ *
+ * Used by default for generating random bytes using RAND_bytes().
+ *
+ * The <public> DRBG is thread-local, i.e., there is one instance per
+ * thread.
+ */
+ CRYPTO_THREAD_LOCAL public_drbg;
+ /*
+ * The <private> DRBG
+ *
+ * Used by default for generating private keys using RAND_priv_bytes()
+ *
+ * The <private> DRBG is thread-local, i.e., there is one instance per
+ * thread.
+ */
+ CRYPTO_THREAD_LOCAL private_drbg;
+} DRBG_GLOBAL;
+typedef struct drbg_nonce_global_st {
+ CRYPTO_RWLOCK *rand_nonce_lock;
+ int rand_nonce_count;
+} DRBG_NONCE_GLOBAL;
/* NIST SP 800-90A DRBG recommends the use of a personalization string. */
static const char ossl_pers_string[] = DRBG_DEFAULT_PERS_STRING;
-static CRYPTO_ONCE rand_drbg_init = CRYPTO_ONCE_STATIC_INIT;
-
-
#define RAND_DRBG_TYPE_FLAGS ( \
RAND_DRBG_FLAG_MASTER | RAND_DRBG_FLAG_PUBLIC | RAND_DRBG_FLAG_PRIVATE )
@@ -102,9 +107,10 @@ static const unsigned int rand_drbg_used_flags =
RAND_DRBG_FLAG_CTR_NO_DF | RAND_DRBG_FLAG_HMAC | RAND_DRBG_TYPE_FLAGS;
-static RAND_DRBG *drbg_setup(RAND_DRBG *parent, int drbg_type);
+static RAND_DRBG *drbg_setup(OPENSSL_CTX *ctx, RAND_DRBG *parent, int drbg_type);
-static RAND_DRBG *rand_drbg_new(int secure,
+static RAND_DRBG *rand_drbg_new(OPENSSL_CTX *ctx,
+ int secure,
int type,
unsigned int flags,
RAND_DRBG *parent);
@@ -142,6 +148,149 @@ static int is_digest(int type)
}
/*
+ * Initialize the OPENSSL_CTX global DRBGs on first use.
+ * Returns the allocated global data on success or NULL on failure.
+ */
+static void *drbg_ossl_ctx_new(OPENSSL_CTX *libctx)
+{
+ DRBG_GLOBAL *dgbl = OPENSSL_zalloc(sizeof(*dgbl));
+
+ if (dgbl == NULL)
+ return NULL;
+
+ if (!CRYPTO_THREAD_init_local(&dgbl->private_drbg, NULL))
+ goto err1;
+
+ if (!CRYPTO_THREAD_init_local(&dgbl->public_drbg, NULL))
+ goto err2;
+
+ dgbl->master_drbg = drbg_setup(libctx, NULL, RAND_DRBG_TYPE_MASTER);
+ if (dgbl->master_drbg == NULL)
+ goto err3;
+
+ return dgbl;
+
+ err3:
+ CRYPTO_THREAD_cleanup_local(&dgbl->public_drbg);
+ err2:
+ CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg);
+ err1:
+ OPENSSL_free(dgbl);
+ return NULL;
+}
+
+static void drbg_ossl_ctx_free(void *vdgbl)
+{
+ DRBG_GLOBAL *dgbl = vdgbl;
+
+ RAND_DRBG_free(dgbl->master_drbg);
+ CRYPTO_THREAD_cleanup_local(&dgbl->private_drbg);
+ CRYPTO_THREAD_cleanup_local(&dgbl->public_drbg);
+
+ OPENSSL_free(dgbl);
+}
+
+static const OPENSSL_CTX_METHOD drbg_ossl_ctx_method = {
+ drbg_ossl_ctx_new,
+ drbg_ossl_ctx_free,
+};
+
+/*
+ * drbg_ossl_ctx_new() calls drgb_setup() which calls rand_drbg_get_nonce()
+ * which needs to get the rand_nonce_lock out of the OPENSSL_CTX...but since
+ * drbg_ossl_ctx_new() hasn't finished running yet we need the rand_nonce_lock
+ * to be in a different global data object. Otherwise we will go into an
+ * infinite recursion loop.
+ */
+static void *drbg_nonce_ossl_ctx_new(OPENSSL_CTX *libctx)
+{
+ DRBG_NONCE_GLOBAL *dngbl = OPENSSL_zalloc(sizeof(*dngbl));
+
+ if (dngbl == NULL)
+ return NULL;
+
+ dngbl->rand_nonce_lock = CRYPTO_THREAD_lock_new();
+ if (dngbl->rand_nonce_lock == NULL) {
+ OPENSSL_free(dngbl);
+ return NULL;
+ }
+
+ return dngbl;
+}
+
+static void drbg_nonce_ossl_ctx_free(void *vdngbl)
+{
+ DRBG_NONCE_GLOBAL *dngbl = vdngbl;
+
+ CRYPTO_THREAD_lock_free(dngbl->rand_nonce_lock);
+
+ OPENSSL_free(dngbl);
+}
+
+static const OPENSSL_CTX_METHOD drbg_nonce_ossl_ctx_method = {
+ drbg_nonce_ossl_ctx_new,
+ drbg_nonce_ossl_ctx_free,
+};
+
+static DRBG_GLOBAL *drbg_get_global(OPENSSL_CTX *libctx)
+{
+ return openssl_ctx_get_data(libctx, OPENSSL_CTX_DRBG_INDEX,
+ &drbg_ossl_ctx_method);
+}
+
+/* Implements the get_nonce() callback (see RAND_DRBG_set_callbacks()) */
+size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
+ unsigned char **pout,
+ int entropy, size_t min_len, size_t max_len)
+{
+ size_t ret = 0;
+ RAND_POOL *pool;
+ DRBG_NONCE_GLOBAL *dngbl
+ = openssl_ctx_get_data(drbg->libctx, OPENSSL_CTX_DRBG_NONCE_INDEX,
+ &drbg_nonce_ossl_ctx_method);
+ struct {
+ void *instance;
+ int count;
+ } data;
+
+ if (dngbl == NULL)
+ return 0;
+
+ memset(&data, 0, sizeof(data));
+ pool = rand_pool_new(0, min_len, max_len);
+ if (pool == NULL)
+ return 0;
+
+ if (rand_pool_add_nonce_data(pool) == 0)
+ goto err;
+
+ data.instance = drbg;
+ CRYPTO_atomic_add(&dngbl->rand_nonce_count, 1, &data.count,
+ dngbl->rand_nonce_lock);
+
+ if (rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0) == 0)
+ goto err;
+
+ ret = rand_pool_length(pool);
+ *pout = rand_pool_detach(pool);
+
+ err:
+ rand_pool_free(pool);
+
+ return ret;
+}
+
+/*
+ * Implements the cleanup_nonce() callback (see RAND_DRBG_set_callbacks())
+ *
+ */
+void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
+ unsigned char *out, size_t outlen)
+{
+ OPENSSL_secure_clear_free(out, outlen);
+}
+
+/*
* Set/initialize |drbg| to be of type |type|, with optional |flags|.
*
* If |type| and |flags| are zero, use the defaults
@@ -236,7 +385,8 @@ int RAND_DRBG_set_defaults(int type, unsigned int flags)
*
* Returns a pointer to the new DRBG instance on success, NULL on failure.
*/
-static RAND_DRBG *rand_drbg_new(int secure,
+static RAND_DRBG *rand_drbg_new(OPENSSL_CTX *ctx,
+ int secure,
int type,
unsigned int flags,
RAND_DRBG *parent)
@@ -249,6 +399,7 @@ static RAND_DRBG *rand_drbg_new(int secure,
return NULL;
}
+ drbg->libctx = ctx;
drbg->secure = secure && CRYPTO_secure_allocated(drbg);
drbg->fork_count = rand_fork_count;
drbg->parent = parent;
@@ -305,16 +456,27 @@ static RAND_DRBG *rand_drbg_new(int secure,
return NULL;
}
+RAND_DRBG *RAND_DRBG_new_ex(OPENSSL_CTX *ctx, int type, unsigned int flags,
+ RAND_DRBG *parent)
+{
+ return rand_drbg_new(ctx, 0, type, flags, parent);
+}
+
RAND_DRBG *RAND_DRBG_new(int type, unsigned int flags, RAND_DRBG *parent)
{
- return rand_drbg_new(0, type, flags, parent);
+ return RAND_DRBG_new_ex(NULL, type, flags, parent);
}
-RAND_DRBG *RAND_DRBG_secure_new(int type, unsigned int flags, RAND_DRBG *parent)
+RAND_DRBG *RAND_DRBG_secure_new_ex(OPENSSL_CTX *ctx, int type,
+ unsigned int flags, RAND_DRBG *parent)
{
- return rand_drbg_new(1, type, flags, parent);
+ return rand_drbg_new(ctx, 1, type, flags, parent);
}
+RAND_DRBG *RAND_DRBG_secure_new(int type, unsigned int flags, RAND_DRBG *parent)
+{
+ return RAND_DRBG_secure_new_ex(NULL, type, flags, parent);
+}
/*
* Uninstantiate |drbg| and free all memory.
*/
@@ -943,12 +1105,12 @@ void *RAND_DRBG_get_ex_data(const RAND_DRBG *drbg, int idx)
*
* Returns a pointer to the new DRBG instance on success, NULL on failure.
*/
-static RAND_DRBG *drbg_setup(RAND_DRBG *parent, int drbg_type)
+static RAND_DRBG *drbg_setup(OPENSSL_CTX *ctx, RAND_DRBG *parent, int drbg_type)
{
RAND_DRBG *drbg;
- drbg = RAND_DRBG_secure_new(rand_drbg_type[drbg_type],
- rand_drbg_flags[drbg_type], parent);
+ drbg = RAND_DRBG_secure_new_ex(ctx, rand_drbg_type[drbg_type],
+ rand_drbg_flags[drbg_type], parent);
if (drbg == NULL)
return NULL;
@@ -975,60 +1137,21 @@ err:
return NULL;
}
-/*
- * Initialize the global DRBGs on first use.
- * Returns 1 on success, 0 on failure.
- */
-DEFINE_RUN_ONCE_STATIC(do_rand_drbg_init)
-{
- /*
- * ensure that libcrypto is initialized, otherwise the
- * DRBG locks are not cleaned up properly
- */
- if (!OPENSSL_init_crypto(0, NULL))
- return 0;
-
- if (!CRYPTO_THREAD_init_local(&private_drbg, NULL))
- return 0;
-
- if (!CRYPTO_THREAD_init_local(&public_drbg, NULL))
- goto err1;
-
- master_drbg = drbg_setup(NULL, RAND_DRBG_TYPE_MASTER);
- 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 */
-void rand_drbg_cleanup_int(void)
-{
- if (master_drbg != NULL) {
- RAND_DRBG_free(master_drbg);
- master_drbg = NULL;
-
- CRYPTO_THREAD_cleanup_local(&private_drbg);
- CRYPTO_THREAD_cleanup_local(&public_drbg);
- }
-}
-
void drbg_delete_thread_state(void)
{
+ /* TODO(3.0): Other PRs will pass the ctx as a param to this function */
+ OPENSSL_CTX *ctx = NULL;
+ DRBG_GLOBAL *dgbl = drbg_get_global(ctx);
RAND_DRBG *drbg;
- drbg = CRYPTO_THREAD_get_local(&public_drbg);
- CRYPTO_THREAD_set_local(&public_drbg, NULL);
+ if (dgbl == NULL)
+ return;
+ drbg = CRYPTO_THREAD_get_local(&dgbl->public_drbg);
+ CRYPTO_THREAD_set_local(&dgbl->public_drbg, NULL);
RAND_DRBG_free(drbg);
- drbg = CRYPTO_THREAD_get_local(&private_drbg);
- CRYPTO_THREAD_set_local(&private_drbg, NULL);
+ drbg = CRYPTO_THREAD_get_local(&dgbl->private_drbg);
+ CRYPTO_THREAD_set_local(&dgbl->private_drbg, NULL);
RAND_DRBG_free(drbg);
}
@@ -1180,56 +1303,75 @@ static int drbg_status(void)
* Returns pointer to the DRBG on success, NULL on failure.
*
*/
-RAND_DRBG *RAND_DRBG_get0_master(void)
+RAND_DRBG *OPENSSL_CTX_get0_master_drbg(OPENSSL_CTX *ctx)
{
- if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init))
+ DRBG_GLOBAL *dgbl = drbg_get_global(ctx);
+
+ if (dgbl == NULL)
return NULL;
- return master_drbg;
+ return dgbl->master_drbg;
+}
+
+RAND_DRBG *RAND_DRBG_get0_master(void)
+{
+ return OPENSSL_CTX_get0_master_drbg(NULL);
}
/*
* Get the public DRBG.
* Returns pointer to the DRBG on success, NULL on failure.
*/
-RAND_DRBG *RAND_DRBG_get0_public(void)
+RAND_DRBG *OPENSSL_CTX_get0_public_drbg(OPENSSL_CTX *ctx)
{
+ DRBG_GLOBAL *dgbl = drbg_get_global(ctx);
RAND_DRBG *drbg;
- if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init))
+ if (dgbl == NULL)
return NULL;
- drbg = CRYPTO_THREAD_get_local(&public_drbg);
+ drbg = CRYPTO_THREAD_get_local(&dgbl->public_drbg);
if (drbg == NULL) {
if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND))
return NULL;
- drbg = drbg_setup(master_drbg, RAND_DRBG_TYPE_PUBLIC);
- CRYPTO_THREAD_set_local(&public_drbg, drbg);
+ drbg = drbg_setup(ctx, dgbl->master_drbg, RAND_DRBG_TYPE_PUBLIC);
+ CRYPTO_THREAD_set_local(&dgbl->public_drbg, drbg);
}
return drbg;
}
+RAND_DRBG *RAND_DRBG_get0_public(void)
+{
+ return OPENSSL_CTX_get0_public_drbg(NULL);
+}
+
/*
* Get the private DRBG.
* Returns pointer to the DRBG on success, NULL on failure.
*/
-RAND_DRBG *RAND_DRBG_get0_private(void)
+RAND_DRBG *OPENSSL_CTX_get0_private_drbg(OPENSSL_CTX *ctx)
{
+ DRBG_GLOBAL *dgbl = drbg_get_global(ctx);
RAND_DRBG *drbg;
- if (!RUN_ONCE(&rand_drbg_init, do_rand_drbg_init))
+ if (dgbl == NULL)
return NULL;
- drbg = CRYPTO_THREAD_get_local(&private_drbg);
+ drbg = CRYPTO_THREAD_get_local(&dgbl->private_drbg);
if (drbg == NULL) {
if (!ossl_init_thread_start(OPENSSL_INIT_THREAD_RAND))
return NULL;
- drbg = drbg_setup(master_drbg, RAND_DRBG_TYPE_PRIVATE);
- CRYPTO_THREAD_set_local(&private_drbg, drbg);
+ drbg = drbg_setup(ctx, dgbl->master_drbg, RAND_DRBG_TYPE_PRIVATE);
+ CRYPTO_THREAD_set_local(&dgbl->private_drbg, drbg);
}
return drbg;
}
+RAND_DRBG *RAND_DRBG_get0_private(void)
+{
+ return OPENSSL_CTX_get0_private_drbg(NULL);
+}
+
RAND_METHOD rand_meth = {
drbg_seed,
drbg_bytes,
@@ -1241,5 +1383,9 @@ RAND_METHOD rand_meth = {
RAND_METHOD *RAND_OpenSSL(void)
{
+#ifndef FIPS_MODE
return &rand_meth;
+#else
+ return NULL;
+#endif
}
diff --git a/crypto/rand/rand_crng_test.c b/crypto/rand/rand_crng_test.c
index 1b4f167..11d85f3 100644
--- a/crypto/rand/rand_crng_test.c
+++ b/crypto/rand/rand_crng_test.c
@@ -16,64 +16,78 @@
#include <openssl/evp.h>
#include "internal/rand_int.h"
#include "internal/thread_once.h"
+#include "internal/cryptlib.h"
#include "rand_lcl.h"
-static RAND_POOL *crngt_pool;
-static unsigned char crngt_prev[EVP_MAX_MD_SIZE];
+typedef struct crng_test_global_st {
+ unsigned char crngt_prev[EVP_MAX_MD_SIZE];
+ RAND_POOL *crngt_pool;
+} CRNG_TEST_GLOBAL;
-int (*crngt_get_entropy)(unsigned char *, unsigned char *, unsigned int *)
+int (*crngt_get_entropy)(OPENSSL_CTX *, unsigned char *, unsigned char *,
+ unsigned int *)
= &rand_crngt_get_entropy_cb;
-int rand_crngt_get_entropy_cb(unsigned char *buf, unsigned char *md,
- unsigned int *md_size)
+static void rand_crng_ossl_ctx_free(void *vcrngt_glob)
{
- int r;
- size_t n;
- unsigned char *p;
+ CRNG_TEST_GLOBAL *crngt_glob = vcrngt_glob;
- n = rand_pool_acquire_entropy(crngt_pool);
- if (n >= CRNGT_BUFSIZ) {
- p = rand_pool_detach(crngt_pool);
- r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, EVP_sha256(), NULL);
- if (r != 0)
- memcpy(buf, p, CRNGT_BUFSIZ);
- rand_pool_reattach(crngt_pool, p);
- return r;
- }
- return 0;
-}
-
-void rand_crngt_cleanup(void)
-{
- rand_pool_free(crngt_pool);
- crngt_pool = NULL;
+ rand_pool_free(crngt_glob->crngt_pool);
+ OPENSSL_free(crngt_glob);
}
-int rand_crngt_init(void)
+static void *rand_crng_ossl_ctx_new(OPENSSL_CTX *ctx)
{
unsigned char buf[CRNGT_BUFSIZ];
+ CRNG_TEST_GLOBAL *crngt_glob = OPENSSL_zalloc(sizeof(*crngt_glob));
- if ((crngt_pool = rand_pool_new(0, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL)
- return 0;
- if (crngt_get_entropy(buf, crngt_prev, NULL)) {
+ if (crngt_glob == NULL)
+ return NULL;
+
+ if ((crngt_glob->crngt_pool
+ = rand_pool_new(0, CRNGT_BUFSIZ, CRNGT_BUFSIZ)) == NULL) {
+ OPENSSL_free(crngt_glob);
+ return NULL;
+ }
+ if (crngt_get_entropy(ctx, buf, crngt_glob->crngt_prev, NULL)) {
OPENSSL_cleanse(buf, sizeof(buf));
- return 1;
+ return crngt_glob;
}
- rand_crngt_cleanup();
- return 0;
+ rand_pool_free(crngt_glob->crngt_pool);
+ OPENSSL_free(crngt_glob);
+ return NULL;
}
-static CRYPTO_ONCE rand_crngt_init_flag = CRYPTO_ONCE_STATIC_INIT;
-DEFINE_RUN_ONCE_STATIC(do_rand_crngt_init)
-{
- return OPENSSL_init_crypto(0, NULL)
- && rand_crngt_init()
- && OPENSSL_atexit(&rand_crngt_cleanup);
-}
+static const OPENSSL_CTX_METHOD rand_crng_ossl_ctx_method = {
+ rand_crng_ossl_ctx_new,
+ rand_crng_ossl_ctx_free,
+};
-int rand_crngt_single_init(void)
+int rand_crngt_get_entropy_cb(OPENSSL_CTX *ctx,
+ unsigned char *buf,
+ unsigned char *md,
+ unsigned int *md_size)
{
- return RUN_ONCE(&rand_crngt_init_flag, do_rand_crngt_init);
+ int r;
+ size_t n;
+ unsigned char *p;
+ CRNG_TEST_GLOBAL *crngt_glob
+ = openssl_ctx_get_data(ctx, OPENSSL_CTX_RAND_CRNGT_INDEX,
+ &rand_crng_ossl_ctx_method);
+
+ if (crngt_glob == NULL)
+ return 0;
+
+ n = rand_pool_acquire_entropy(crngt_glob->crngt_pool);
+ if (n >= CRNGT_BUFSIZ) {
+ p = rand_pool_detach(crngt_glob->crngt_pool);
+ r = EVP_Digest(p, CRNGT_BUFSIZ, md, md_size, EVP_sha256(), NULL);
+ if (r != 0)
+ memcpy(buf, p, CRNGT_BUFSIZ);
+ rand_pool_reattach(crngt_glob->crngt_pool, p);
+ return r;
+ }
+ return 0;
}
size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
@@ -86,8 +100,11 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
RAND_POOL *pool;
size_t q, r = 0, s, t = 0;
int attempts = 3;
+ CRNG_TEST_GLOBAL *crngt_glob
+ = openssl_ctx_get_data(drbg->libctx, OPENSSL_CTX_RAND_CRNGT_INDEX,
+ &rand_crng_ossl_ctx_method);
- if (!RUN_ONCE(&rand_crngt_init_flag, do_rand_crngt_init))
+ if (crngt_glob == NULL)
return 0;
if ((pool = rand_pool_new(entropy, min_len, max_len)) == NULL)
@@ -95,11 +112,11 @@ size_t rand_crngt_get_entropy(RAND_DRBG *drbg,
while ((q = rand_pool_bytes_needed(pool, 1)) > 0 && attempts-- > 0) {
s = q > sizeof(buf) ? sizeof(buf) : q;
- if (!crngt_get_entropy(buf, md, &sz)
- || memcmp(crngt_prev, md, sz) == 0
+ if (!crngt_get_entropy(drbg->libctx, buf, md, &sz)
+ || memcmp(crngt_glob->crngt_prev, md, sz) == 0
|| !rand_pool_add(pool, buf, s, s * 8))
goto err;
- memcpy(crngt_prev, md, sz);
+ memcpy(crngt_glob->crngt_prev, md, sz);
t += s;
attempts++;
}
diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h
index 3ce5f7a..97126bc 100644
--- a/crypto/rand/rand_lcl.h
+++ b/crypto/rand/rand_lcl.h
@@ -192,6 +192,8 @@ struct rand_pool_st {
*/
struct rand_drbg_st {
CRYPTO_RWLOCK *lock;
+ /* The library context this DRBG is associated with, if any */
+ OPENSSL_CTX *libctx;
RAND_DRBG *parent;
int secure; /* 1: allocated on the secure heap, 0: otherwise */
int type; /* the nid of the underlying algorithm */
@@ -334,18 +336,10 @@ int drbg_hmac_init(RAND_DRBG *drbg);
* Entropy call back for the FIPS 140-2 section 4.9.2 Conditional Tests.
* These need to be exposed for the unit tests.
*/
-int rand_crngt_get_entropy_cb(unsigned char *buf, unsigned char *md,
- unsigned int *md_size);
-extern int (*crngt_get_entropy)(unsigned char *buf, unsigned char *md,
+int rand_crngt_get_entropy_cb(OPENSSL_CTX *ctx, unsigned char *buf,
+ unsigned char *md, unsigned int *md_size);
+extern int (*crngt_get_entropy)(OPENSSL_CTX *ctx, unsigned char *buf,
+ unsigned char *md,
unsigned int *md_size);
-int rand_crngt_init(void);
-void rand_crngt_cleanup(void);
-
-/*
- * Expose the run once initialisation function for the unit tests because.
- * they need to restart from scratch to validate the first block is skipped
- * properly.
- */
-int rand_crngt_single_init(void);
#endif
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index 2b77960..45742f5 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -17,21 +17,20 @@
#include "rand_lcl.h"
#include "e_os.h"
-#ifndef OPENSSL_NO_ENGINE
+#ifndef FIPS_MODE
+# ifndef OPENSSL_NO_ENGINE
/* non-NULL if default_RAND_meth is ENGINE-provided */
static ENGINE *funct_ref;
static CRYPTO_RWLOCK *rand_engine_lock;
-#endif
+# endif
static CRYPTO_RWLOCK *rand_meth_lock;
static const RAND_METHOD *default_RAND_meth;
static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT;
-int rand_fork_count;
-
-static CRYPTO_RWLOCK *rand_nonce_lock;
-static int rand_nonce_count;
-
static int rand_inited = 0;
+#endif /* FIPS_MODE */
+
+int rand_fork_count;
#ifdef OPENSSL_RAND_SEED_RDTSC
/*
@@ -208,56 +207,6 @@ void rand_drbg_cleanup_entropy(RAND_DRBG *drbg,
OPENSSL_secure_clear_free(out, outlen);
}
-
-/*
- * Implements the get_nonce() callback (see RAND_DRBG_set_callbacks())
- *
- */
-size_t rand_drbg_get_nonce(RAND_DRBG *drbg,
- unsigned char **pout,
- int entropy, size_t min_len, size_t max_len)
-{
- size_t ret = 0;
- RAND_POOL *pool;
-
- struct {
- void * instance;
- int count;
- } data;
-
- memset(&data, 0, sizeof(data));
- pool = rand_pool_new(0, min_len, max_len);
- if (pool == NULL)
- return 0;
-
- if (rand_pool_add_nonce_data(pool) == 0)
- goto err;
-
- data.instance = drbg;
- CRYPTO_atomic_add(&rand_nonce_count, 1, &data.count, rand_nonce_lock);
-
- if (rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0) == 0)
- goto err;
-
- ret = rand_pool_length(pool);
- *pout = rand_pool_detach(pool);
-
- err:
- rand_pool_free(pool);
-
- return ret;
-}
-
-/*
- * Implements the cleanup_nonce() callback (see RAND_DRBG_set_callbacks())
- *
- */
-void rand_drbg_cleanup_nonce(RAND_DRBG *drbg,
- unsigned char *out, size_t outlen)
-{
- OPENSSL_secure_clear_free(out, outlen);
-}
-
/*
* Generate additional data that can be used for the drbg. The data does
* not need to contain entropy, but it's useful if it contains at least
@@ -292,39 +241,32 @@ void rand_fork(void)
rand_fork_count++;
}
+#ifndef FIPS_MODE
DEFINE_RUN_ONCE_STATIC(do_rand_init)
{
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
rand_engine_lock = CRYPTO_THREAD_lock_new();
if (rand_engine_lock == NULL)
return 0;
-#endif
+# endif
rand_meth_lock = CRYPTO_THREAD_lock_new();
if (rand_meth_lock == NULL)
- goto err1;
-
- rand_nonce_lock = CRYPTO_THREAD_lock_new();
- if (rand_nonce_lock == NULL)
- goto err2;
+ goto err;
if (!rand_pool_init())
- goto err3;
+ goto err;
rand_inited = 1;
return 1;
-err3:
- CRYPTO_THREAD_lock_free(rand_nonce_lock);
- rand_nonce_lock = NULL;
-err2:
+ err:
CRYPTO_THREAD_lock_free(rand_meth_lock);
rand_meth_lock = NULL;
-err1:
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
CRYPTO_THREAD_lock_free(rand_engine_lock);
rand_engine_lock = NULL;
-#endif
+# endif
return 0;
}
@@ -339,17 +281,16 @@ void rand_cleanup_int(void)
meth->cleanup();
RAND_set_rand_method(NULL);
rand_pool_cleanup();
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
CRYPTO_THREAD_lock_free(rand_engine_lock);
rand_engine_lock = NULL;
-#endif
+# endif
CRYPTO_THREAD_lock_free(rand_meth_lock);
rand_meth_lock = NULL;
- CRYPTO_THREAD_lock_free(rand_nonce_lock);
- rand_nonce_lock = NULL;
rand_inited = 0;
}
+/* TODO(3.0): Do we need to handle this somehow in the FIPS module? */
/*
* RAND_close_seed_files() ensures that any seed file decriptors are
* closed after use.
@@ -371,8 +312,6 @@ int RAND_poll(void)
{
int ret = 0;
- RAND_POOL *pool = NULL;
-
const RAND_METHOD *meth = RAND_get_rand_method();
if (meth == RAND_OpenSSL()) {
@@ -389,6 +328,8 @@ int RAND_poll(void)
return ret;
} else {
+ RAND_POOL *pool = NULL;
+
/* fill random pool and seed the current legacy RNG */
pool = rand_pool_new(RAND_DRBG_STRENGTH,
(RAND_DRBG_STRENGTH + 7) / 8,
@@ -406,12 +347,14 @@ int RAND_poll(void)
goto err;
ret = 1;
+
+ err:
+ rand_pool_free(pool);
}
-err:
- rand_pool_free(pool);
return ret;
}
+#endif /* FIPS_MODE */
/*
* Allocate memory and initialize a new random pool
@@ -708,23 +651,28 @@ int rand_pool_add_end(RAND_POOL *pool, size_t len, size_t entropy)
return 1;
}
+#ifndef FIPS_MODE
int RAND_set_rand_method(const RAND_METHOD *meth)
{
if (!RUN_ONCE(&rand_init, do_rand_init))
return 0;
CRYPTO_THREAD_write_lock(rand_meth_lock);
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
ENGINE_finish(funct_ref);
funct_ref = NULL;
-#endif
+# endif
default_RAND_meth = meth;
CRYPTO_THREAD_unlock(rand_meth_lock);
return 1;
}
+#endif
const RAND_METHOD *RAND_get_rand_method(void)
{
+#ifdef FIPS_MODE
+ return NULL;
+#else
const RAND_METHOD *tmp_meth = NULL;
if (!RUN_ONCE(&rand_init, do_rand_init))
@@ -732,7 +680,7 @@ const RAND_METHOD *RAND_get_rand_method(void)
CRYPTO_THREAD_write_lock(rand_meth_lock);
if (default_RAND_meth == NULL) {
-#ifndef OPENSSL_NO_ENGINE
+# ifndef OPENSSL_NO_ENGINE
ENGINE *e;
/* If we have an engine that can do RAND, use it. */
@@ -744,16 +692,17 @@ const RAND_METHOD *RAND_get_rand_method(void)
ENGINE_finish(e);
default_RAND_meth = &rand_meth;
}
-#else
+# else
default_RAND_meth = &rand_meth;
-#endif
+# endif
}
tmp_meth = default_RAND_meth;
CRYPTO_THREAD_unlock(rand_meth_lock);
return tmp_meth;
+#endif
}
-#ifndef OPENSSL_NO_ENGINE
+#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODE)
int RAND_set_rand_engine(ENGINE *engine)
{
const RAND_METHOD *tmp_meth = NULL;
@@ -802,9 +751,9 @@ void RAND_add(const void *buf, int num, double randomness)
*/
int RAND_priv_bytes(unsigned char *buf, int num)
{
- const RAND_METHOD *meth = RAND_get_rand_method();
RAND_DRBG *drbg;
int ret;
+ const RAND_METHOD *meth = RAND_get_rand_method();
if (meth != RAND_OpenSSL())
return RAND_bytes(buf, num);
@@ -827,7 +776,7 @@ int RAND_bytes(unsigned char *buf, int num)
return -1;
}
-#if !OPENSSL_API_1_1_0
+#if !OPENSSL_API_1_1_0 && !defined(FIPS_MODE)
int RAND_pseudo_bytes(unsigned char *buf, int num)
{
const RAND_METHOD *meth = RAND_get_rand_method();
diff --git a/doc/man3/RAND_DRBG_get0_master.pod b/doc/man3/RAND_DRBG_get0_master.pod
index 62f6fdb..77d0ab7 100644
--- a/doc/man3/RAND_DRBG_get0_master.pod
+++ b/doc/man3/RAND_DRBG_get0_master.pod
@@ -2,6 +2,9 @@
=head1 NAME
+OPENSSL_CTX_get0_master_drbg,
+OPENSSL_CTX_get0_public_drbg,
+OPENSSL_CTX_get0_private_drbg,
RAND_DRBG_get0_master,
RAND_DRBG_get0_public,
RAND_DRBG_get0_private
@@ -11,6 +14,9 @@ RAND_DRBG_get0_private
#include <openssl/rand_drbg.h>
+ RAND_DRBG *OPENSSL_CTX_get0_master_drbg(OPENSSL_CTX *ctx);
+ RAND_DRBG *OPENSSL_CTX_get0_public_drbg(OPENSSL_CTX *ctx);
+ RAND_DRBG *OPENSSL_CTX_get0_private_drbg(OPENSSL_CTX *ctx);
RAND_DRBG *RAND_DRBG_get0_master(void);
RAND_DRBG *RAND_DRBG_get0_public(void);
RAND_DRBG *RAND_DRBG_get0_private(void);
@@ -21,26 +27,35 @@ RAND_DRBG_get0_private
The default RAND API implementation (RAND_OpenSSL()) utilizes three
shared DRBG instances which are accessed via the RAND API:
-The <public> and <private> DRBG are thread-local instances, which are used
+The I<public> and I<private> DRBG are thread-local instances, which are used
by RAND_bytes() and RAND_priv_bytes(), respectively.
-The <master> DRBG is a global instance, which is not intended to be used
+The I<master> DRBG is a global instance, which is not intended to be used
directly, but is used internally to reseed the other two instances.
These functions here provide access to the shared DRBG instances.
=head1 RETURN VALUES
-RAND_DRBG_get0_master() returns a pointer to the <master> DRBG instance.
+OPENSSL_CTX_get0_master_drbg() returns a pointer to the I<master> DRBG instance
+for the given OPENSSL_CTX B<ctx>.
-RAND_DRBG_get0_public() returns a pointer to the <public> DRBG instance.
+OPENSSL_CTX_get0_public_drbg() returns a pointer to the I<public> DRBG instance
+for the given OPENSSL_CTX B<ctx>.
-RAND_DRBG_get0_private() returns a pointer to the <private> DRBG instance.
+OPENSSL_CTX_get0_private_drbg() returns a pointer to the I<private> DRBG instance
+for the given OPENSSL_CTX B<ctx>.
+In all the above cases the B<ctx> parameter can
+be NULL in which case the default OPENSSL_CTX is used. RAND_DRBG_get0_master(),
+RAND_DRBG_get0_public() and RAND_DRBG_get0_private() are the same as
+OPENSSL_CTX_get0_master_drbg(), OPENSSL_CTX_get0_public_drbg() and
+OPENSSL_CTX_get0_private_drbg() respectively except that the default OPENSSL_CTX
+is always used.
=head1 NOTES
-It is not thread-safe to access the <master> DRBG instance.
-The <public> and <private> DRBG instance can be accessed safely, because
+It is not thread-safe to access the I<master> DRBG instance.
+The I<public> and I<private> DRBG instance can be accessed safely, because
they are thread-local. Note however, that changes to these two instances
apply only to the current thread.
@@ -65,7 +80,10 @@ L<RAND_DRBG(7)>
=head1 HISTORY
-The RAND_DRBG functions were added in OpenSSL 1.1.1.
+The OPENSSL_CTX_get0_master_drbg(), OPENSSL_CTX_get0_public_drbg() and
+OPENSSL_CTX_get0_private_drbg() functions were added in OpenSSL 3.0.
+
+All other RAND_DRBG functions were added in OpenSSL 1.1.1.
=head1 COPYRIGHT
diff --git a/doc/man3/RAND_DRBG_new.pod b/doc/man3/RAND_DRBG_new.pod
index 8b73840..3ff98ae 100644
--- a/doc/man3/RAND_DRBG_new.pod
+++ b/doc/man3/RAND_DRBG_new.pod
@@ -2,7 +2,9 @@
=head1 NAME
+RAND_DRBG_new_ex,
RAND_DRBG_new,
+RAND_DRBG_secure_new_ex,
RAND_DRBG_secure_new,
RAND_DRBG_set,
RAND_DRBG_set_defaults,
@@ -15,11 +17,20 @@ RAND_DRBG_free
#include <openssl/rand_drbg.h>
+ RAND_DRBG *RAND_DRBG_new_ex(OPENSSL_CTX *ctx,
+ int type,
+ unsigned int flags,
+ RAND_DRBG *parent);
RAND_DRBG *RAND_DRBG_new(int type,
unsigned int flags,
RAND_DRBG *parent);
+ RAND_DRBG *RAND_DRBG_secure_new_ex(OPENSSL_CTX *ctx,
+ int type,
+ unsigned int flags,
+ RAND_DRBG *parent);
+
RAND_DRBG *RAND_DRBG_secure_new(int type,
unsigned int flags,
RAND_DRBG *parent);
@@ -39,10 +50,13 @@ RAND_DRBG_free
=head1 DESCRIPTION
-RAND_DRBG_new() and RAND_DRBG_secure_new()
+RAND_DRBG_new_ex() and RAND_DRBG_secure_new_ex()
create a new DRBG instance of the given B<type>, allocated from the heap resp.
-the secure heap
-(using OPENSSL_zalloc() resp. OPENSSL_secure_zalloc()).
+the secure heap, for the given OPENSSL_CTX <ctx>
+(using OPENSSL_zalloc() resp. OPENSSL_secure_zalloc()). The <ctx> parameter can
+be NULL in which case the default OPENSSL_CTX is used. RAND_DRBG_new() and
+RAND_DRBG_secure_new() are the same as RAND_DRBG_new_ex() and
+RAND_DRBG_secure_new_ex() except that the default OPENSSL_CTX is always used.
RAND_DRBG_set() initializes the B<drbg> with the given B<type> and B<flags>.
@@ -108,8 +122,9 @@ uninstantiated state.
=head1 RETURN VALUES
-RAND_DRBG_new() and RAND_DRBG_secure_new() return a pointer to a DRBG
-instance allocated on the heap, resp. secure heap.
+RAND_DRBG_new_ex(), RAND_DRBG_new(), RAND_DRBG_secure_new_ex() and
+RAND_DRBG_secure_new() return a pointer to a DRBG instance allocated on the
+heap, resp. secure heap.
RAND_DRBG_set(),
RAND_DRBG_instantiate(), and
diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h
index 1ce822d..d76f9e1 100644
--- a/include/internal/cryptlib.h
+++ b/include/internal/cryptlib.h
@@ -146,7 +146,10 @@ typedef struct ossl_ex_data_global_st {
# define OPENSSL_CTX_PROPERTY_DEFN_INDEX 2
# define OPENSSL_CTX_PROPERTY_STRING_INDEX 3
# define OPENSSL_CTX_NAMEMAP_INDEX 4
-# define OPENSSL_CTX_MAX_INDEXES 5
+# define OPENSSL_CTX_DRBG_INDEX 5
+# define OPENSSL_CTX_DRBG_NONCE_INDEX 6
+# define OPENSSL_CTX_RAND_CRNGT_INDEX 7
+# define OPENSSL_CTX_MAX_INDEXES 8
typedef struct openssl_ctx_method {
void *(*new_func)(OPENSSL_CTX *ctx);
diff --git a/include/openssl/rand_drbg.h b/include/openssl/rand_drbg.h
index 32c6dcf..4e99d71 100644
--- a/include/openssl/rand_drbg.h
+++ b/include/openssl/rand_drbg.h
@@ -72,6 +72,10 @@ extern "C" {
/*
* Object lifetime functions.
*/
+RAND_DRBG *RAND_DRBG_new_ex(OPENSSL_CTX *ctx, int type, unsigned int flags,
+ RAND_DRBG *parent);
+RAND_DRBG *RAND_DRBG_secure_new_ex(OPENSSL_CTX *ctx, int type,
+ unsigned int flags, RAND_DRBG *parent);
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);
@@ -102,6 +106,9 @@ int RAND_DRBG_set_reseed_defaults(
time_t slave_reseed_time_interval
);
+RAND_DRBG *OPENSSL_CTX_get0_master_drbg(OPENSSL_CTX *ctx);
+RAND_DRBG *OPENSSL_CTX_get0_public_drbg(OPENSSL_CTX *ctx);
+RAND_DRBG *OPENSSL_CTX_get0_private_drbg(OPENSSL_CTX *ctx);
RAND_DRBG *RAND_DRBG_get0_master(void);
RAND_DRBG *RAND_DRBG_get0_public(void);
RAND_DRBG *RAND_DRBG_get0_private(void);
diff --git a/test/drbgtest.c b/test/drbgtest.c
index 9e0aba8..618403f 100644
--- a/test/drbgtest.c
+++ b/test/drbgtest.c
@@ -1264,7 +1264,8 @@ static const size_t crngt_num_cases = 6;
static size_t crngt_case, crngt_idx;
-static int crngt_entropy_cb(unsigned char *buf, unsigned char *md,
+static int crngt_entropy_cb(OPENSSL_CTX *ctx, unsigned char *buf,
+ unsigned char *md,
unsigned int *md_size)
{
size_t i, z;
@@ -1288,19 +1289,16 @@ static int test_crngt(int n)
size_t ent;
int res = 0;
int expect;
+ OPENSSL_CTX *ctx = OPENSSL_CTX_new();
- if (!TEST_true(rand_crngt_single_init()))
- return 0;
- rand_crngt_cleanup();
-
- if (!TEST_ptr(drbg = RAND_DRBG_new(dt->nid, dt->flags, NULL)))
+ if (!TEST_ptr(ctx))
return 0;
+ if (!TEST_ptr(drbg = RAND_DRBG_new_ex(ctx, dt->nid, dt->flags, NULL)))
+ goto err;
ent = (drbg->min_entropylen + CRNGT_BUFSIZ - 1) / CRNGT_BUFSIZ;
crngt_case = n % crngt_num_cases;
crngt_idx = 0;
crngt_get_entropy = &crngt_entropy_cb;
- if (!TEST_true(rand_crngt_init()))
- goto err;
#ifndef FIPS_MODE
if (!TEST_true(RAND_DRBG_set_callbacks(drbg, &rand_crngt_get_entropy,
&rand_crngt_cleanup_entropy,
@@ -1333,6 +1331,7 @@ err:
uninstantiate(drbg);
RAND_DRBG_free(drbg);
crngt_get_entropy = &rand_crngt_get_entropy_cb;
+ OPENSSL_CTX_free(ctx);
return res;
}
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 28b6bb9..af17aba 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4824,3 +4824,8 @@ OSSL_CMP_MSG_dup 4768 3_0_0 EXIST::FUNCTION:CMP
ERR_load_CMP_strings 4769 3_0_0 EXIST::FUNCTION:CMP
EVP_MD_CTX_set_params 4770 3_0_0 EXIST::FUNCTION:
EVP_MD_CTX_get_params 4771 3_0_0 EXIST::FUNCTION:
+RAND_DRBG_new_ex 4772 3_0_0 EXIST::FUNCTION:
+RAND_DRBG_secure_new_ex 4773 3_0_0 EXIST::FUNCTION:
+OPENSSL_CTX_get0_master_drbg 4774 3_0_0 EXIST::FUNCTION:
+OPENSSL_CTX_get0_public_drbg 4775 3_0_0 EXIST::FUNCTION:
+OPENSSL_CTX_get0_private_drbg 4776 3_0_0 EXIST::FUNCTION:
More information about the openssl-commits
mailing list