aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/rand
diff options
context:
space:
mode:
authorPauli <paul.dale@oracle.com>2020-11-20 08:45:34 +1000
committerPauli <paul.dale@oracle.com>2020-12-09 12:20:32 +1000
commit81aef6ba720971c09ad68f89d418c8d3d3f904f7 (patch)
tree9fc56b7a13bdf242e4b1683cc4002ee66ab5c878 /crypto/rand
parentd8975dec0c3f41a491345f8a3c02612eaf8b30f7 (diff)
downloadopenssl-81aef6ba720971c09ad68f89d418c8d3d3f904f7.tar.gz
rand: add a provider side seed source.
This allows the operating system sources that OpenSSL supports to be used directly as RNGs. It also allows DRBG seeding to be explicitly specified rather than being left to a fall back case. Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/13455)
Diffstat (limited to 'crypto/rand')
-rw-r--r--crypto/rand/rand_lib.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index 73d509a8dc..2ad3cf776f 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -325,6 +325,8 @@ typedef struct rand_global_st {
*/
CRYPTO_RWLOCK *lock;
+ EVP_RAND_CTX *seed;
+
/*
* The <primary> DRBG
*
@@ -363,6 +365,10 @@ typedef struct rand_global_st {
char *rng_cipher;
char *rng_digest;
char *rng_propq;
+
+ /* Allow the randomness source to be changed */
+ char *seed_name;
+ char *seed_propq;
} RAND_GLOBAL;
/*
@@ -412,13 +418,16 @@ static void rand_ossl_ctx_free(void *vdgbl)
return;
CRYPTO_THREAD_lock_free(dgbl->lock);
- EVP_RAND_CTX_free(dgbl->primary);
CRYPTO_THREAD_cleanup_local(&dgbl->private);
CRYPTO_THREAD_cleanup_local(&dgbl->public);
+ EVP_RAND_CTX_free(dgbl->primary);
+ EVP_RAND_CTX_free(dgbl->seed);
OPENSSL_free(dgbl->rng_name);
OPENSSL_free(dgbl->rng_cipher);
OPENSSL_free(dgbl->rng_digest);
OPENSSL_free(dgbl->rng_propq);
+ OPENSSL_free(dgbl->seed_name);
+ OPENSSL_free(dgbl->seed_propq);
OPENSSL_free(dgbl);
}
@@ -452,6 +461,35 @@ static void rand_delete_thread_state(void *arg)
EVP_RAND_CTX_free(rand);
}
+#ifndef FIPS_MODULE
+static EVP_RAND_CTX *rand_new_seed(OSSL_LIB_CTX *libctx)
+{
+ EVP_RAND *rand;
+ RAND_GLOBAL *dgbl = rand_get_global(libctx);
+ EVP_RAND_CTX *ctx;
+ char *name;
+
+ name = dgbl->seed_name != NULL ? dgbl->seed_name : "SEED-SRC";
+ rand = EVP_RAND_fetch(libctx, name, dgbl->seed_propq);
+ if (rand == NULL) {
+ ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG);
+ return NULL;
+ }
+ ctx = EVP_RAND_CTX_new(rand, NULL);
+ EVP_RAND_free(rand);
+ if (ctx == NULL) {
+ ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_CREATE_DRBG);
+ return NULL;
+ }
+ if (!EVP_RAND_instantiate(ctx, 0, 0, NULL, 0)) {
+ ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG);
+ EVP_RAND_CTX_free(ctx);
+ return NULL;
+ }
+ return ctx;
+}
+#endif
+
static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent,
unsigned int reseed_interval,
time_t reseed_time_interval)
@@ -522,8 +560,13 @@ EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx)
if (dgbl->primary == NULL) {
if (!CRYPTO_THREAD_write_lock(dgbl->lock))
return NULL;
+#ifndef FIPS_MODULE
+ if (dgbl->seed == NULL)
+ dgbl->seed = rand_new_seed(ctx);
+#endif
if (dgbl->primary == NULL)
- dgbl->primary = rand_new_drbg(ctx, NULL, PRIMARY_RESEED_INTERVAL,
+ dgbl->primary = rand_new_drbg(ctx, dgbl->seed,
+ PRIMARY_RESEED_INTERVAL,
PRIMARY_RESEED_TIME_INTERVAL);
CRYPTO_THREAD_unlock(dgbl->lock);
}
@@ -644,6 +687,12 @@ static int random_conf_init(CONF_IMODULE *md, const CONF *cnf)
} else if (strcasecmp(cval->name, "properties") == 0) {
if (!random_set_string(&dgbl->rng_propq, cval->value))
return 0;
+ } else if (strcasecmp(cval->name, "seed") == 0) {
+ if (!random_set_string(&dgbl->seed_name, cval->value))
+ return 0;
+ } else if (strcasecmp(cval->name, "seed_properties") == 0) {
+ if (!random_set_string(&dgbl->seed_propq, cval->value))
+ return 0;
} else {
ERR_raise_data(ERR_LIB_CRYPTO,
CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION,