summaryrefslogtreecommitdiffstats
path: root/crypto/rand
diff options
context:
space:
mode:
authorRich Salz <rsalz@openssl.org>2017-08-02 14:00:52 -0400
committerRich Salz <rsalz@openssl.org>2017-08-03 10:45:17 -0400
commitddc6a5c8f5900959bdbdfee79e1625a3f7808acd (patch)
tree3121037aca10793706bbc4b8800b40ba305a1c06 /crypto/rand
parentae3947de09522206d61c0206a733517b10a910f8 (diff)
Add RAND_priv_bytes() for private keys
Add a new global DRBG for private keys used by RAND_priv_bytes. Add BN_priv_rand() and BN_priv_rand_range() which use RAND_priv_bytes(). Change callers to use the appropriate BN_priv... function. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/4076)
Diffstat (limited to 'crypto/rand')
-rw-r--r--crypto/rand/drbg_lib.c10
-rw-r--r--crypto/rand/rand_lcl.h1
-rw-r--r--crypto/rand/rand_lib.c71
3 files changed, 58 insertions, 24 deletions
diff --git a/crypto/rand/drbg_lib.c b/crypto/rand/drbg_lib.c
index a24ec8e2e4..935d5c8fd7 100644
--- a/crypto/rand/drbg_lib.c
+++ b/crypto/rand/drbg_lib.c
@@ -365,13 +365,6 @@ err:
return ret;
}
-static void drbg_cleanup(void)
-{
- CRYPTO_THREAD_write_lock(rand_drbg.lock);
- RAND_DRBG_uninstantiate(&rand_drbg);
- CRYPTO_THREAD_unlock(rand_drbg.lock);
-}
-
static int drbg_add(const void *buf, int num, double randomness)
{
unsigned char *in = (unsigned char *)buf;
@@ -411,11 +404,12 @@ static int drbg_status(void)
}
RAND_DRBG rand_drbg; /* The default global DRBG. */
+RAND_DRBG priv_drbg; /* The global private-key DRBG. */
RAND_METHOD rand_meth = {
drbg_seed,
drbg_bytes,
- drbg_cleanup,
+ NULL,
drbg_add,
drbg_bytes,
drbg_status
diff --git a/crypto/rand/rand_lcl.h b/crypto/rand/rand_lcl.h
index e5944f975f..5c7087c977 100644
--- a/crypto/rand/rand_lcl.h
+++ b/crypto/rand/rand_lcl.h
@@ -125,6 +125,7 @@ struct rand_drbg_st {
extern RAND_METHOD rand_meth;
extern RAND_BYTES_BUFFER rand_bytes;
extern RAND_DRBG rand_drbg;
+extern RAND_DRBG priv_drbg;
/* Hardware-based seeding functions. */
void rand_read_tsc(RAND_poll_fn cb, void *arg);
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index 059bd55796..d6cb717489 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -169,7 +169,35 @@ size_t drbg_entropy_from_parent(RAND_DRBG *drbg,
void drbg_release_entropy(RAND_DRBG *drbg, unsigned char *out)
{
drbg->filled = 0;
- OPENSSL_cleanse(drbg->randomness, sizeof(drbg->randomness));
+ OPENSSL_cleanse(drbg->randomness, drbg->size);
+}
+
+
+/*
+ * Set up a global DRBG.
+ */
+static int setup_drbg(RAND_DRBG *drbg)
+{
+ int ret = 1;
+
+ drbg->lock = CRYPTO_THREAD_lock_new();
+ ret &= drbg->lock != NULL;
+ drbg->size = RANDOMNESS_NEEDED;
+ drbg->randomness = OPENSSL_malloc(drbg->size);
+ ret &= drbg->randomness != NULL;
+ /* If you change these parameters, see RANDOMNESS_NEEDED */
+ ret &= RAND_DRBG_set(drbg,
+ NID_aes_128_ctr, RAND_DRBG_FLAG_CTR_USE_DF) == 1;
+ ret &= RAND_DRBG_set_callbacks(drbg, drbg_entropy_from_system,
+ drbg_release_entropy, NULL, NULL) == 1;
+ return ret;
+}
+
+static void free_drbg(RAND_DRBG *drbg)
+{
+ CRYPTO_THREAD_lock_free(drbg->lock);
+ OPENSSL_clear_free(drbg->randomness, drbg->size);
+ RAND_DRBG_uninstantiate(drbg);
}
DEFINE_RUN_ONCE_STATIC(do_rand_init)
@@ -189,22 +217,14 @@ DEFINE_RUN_ONCE_STATIC(do_rand_init)
rand_bytes.size = MAX_RANDOMNESS_HELD;
/* TODO: Should this be secure malloc? */
rand_bytes.buff = malloc(rand_bytes.size);
- ret &= rand_bytes.buff != NULL;
- rand_drbg.lock = CRYPTO_THREAD_lock_new();
- ret &= rand_drbg.lock != NULL;
- rand_drbg.size = RANDOMNESS_NEEDED;
- rand_drbg.randomness = OPENSSL_malloc(rand_drbg.size);
- ret &= rand_drbg.randomness != NULL;
- /* If you change these parameters, see RANDOMNESS_NEEDED */
- ret &= RAND_DRBG_set(&rand_drbg,
- NID_aes_128_ctr, RAND_DRBG_FLAG_CTR_USE_DF) == 1;
- ret &= RAND_DRBG_set_callbacks(&rand_drbg, drbg_entropy_from_system,
- drbg_release_entropy,
- NULL, NULL) == 1;
+ ret &= rand_bytes.buff != NULL;
+ ret &= setup_drbg(&rand_drbg);
+ ret &= setup_drbg(&priv_drbg);
return ret;
}
+
void rand_cleanup_int(void)
{
const RAND_METHOD *meth = default_RAND_meth;
@@ -217,9 +237,9 @@ void rand_cleanup_int(void)
#endif
CRYPTO_THREAD_lock_free(rand_meth_lock);
CRYPTO_THREAD_lock_free(rand_bytes.lock);
- OPENSSL_clear_free(rand_drbg.randomness, rand_drbg.size);
- CRYPTO_THREAD_lock_free(rand_drbg.lock);
- RAND_DRBG_uninstantiate(&rand_drbg);
+ OPENSSL_clear_free(rand_bytes.buff, rand_bytes.size);
+ free_drbg(&rand_drbg);
+ free_drbg(&priv_drbg);
}
/*
@@ -323,6 +343,25 @@ void RAND_add(const void *buf, int num, double randomness)
meth->add(buf, num, randomness);
}
+/*
+ * This function is not part of RAND_METHOD, so if we're not using
+ * the default method, then just call RAND_bytes(). Otherwise make
+ * sure we're instantiated and use the private DRBG.
+ */
+int RAND_priv_bytes(unsigned char *buf, int num)
+{
+ const RAND_METHOD *meth = RAND_get_rand_method();
+
+ if (meth != RAND_OpenSSL())
+ return RAND_bytes(buf, num);
+
+ if (priv_drbg.state == DRBG_UNINITIALISED
+ && RAND_DRBG_instantiate(&priv_drbg, NULL, 0) == 0)
+ return 0;
+ return RAND_DRBG_generate(&priv_drbg, buf, num, 0, NULL, 0);
+
+}
+
int RAND_bytes(unsigned char *buf, int num)
{
const RAND_METHOD *meth = RAND_get_rand_method();