aboutsummaryrefslogtreecommitdiff
path: root/providers/implementations/rands
diff options
context:
space:
mode:
authorPauli <ppzgs1@gmail.com>2021-02-12 12:54:59 +1000
committerPauli <ppzgs1@gmail.com>2021-02-17 13:10:49 +1000
commit335e85f54246cec8b58cb43dd2263ab9d506d622 (patch)
tree4b7a790738bce8a881076f254c47b9645ce271fa /providers/implementations/rands
parent78436fd146313b31151252576c4e523eac55c47c (diff)
downloadopenssl-335e85f54246cec8b58cb43dd2263ab9d506d622.zip
openssl-335e85f54246cec8b58cb43dd2263ab9d506d622.tar.gz
openssl-335e85f54246cec8b58cb43dd2263ab9d506d622.tar.bz2
rand: update DRBGs to use the get_entropy call for seeding
Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/14162)
Diffstat (limited to 'providers/implementations/rands')
-rw-r--r--providers/implementations/rands/drbg.c107
-rw-r--r--providers/implementations/rands/drbg_ctr.c2
-rw-r--r--providers/implementations/rands/drbg_hash.c2
-rw-r--r--providers/implementations/rands/drbg_hmac.c2
-rw-r--r--providers/implementations/rands/drbg_local.h7
5 files changed, 73 insertions, 47 deletions
diff --git a/providers/implementations/rands/drbg.c b/providers/implementations/rands/drbg.c
index bdc980e..239000e 100644
--- a/providers/implementations/rands/drbg.c
+++ b/providers/implementations/rands/drbg.c
@@ -141,30 +141,15 @@ static unsigned int get_parent_reseed_count(PROV_DRBG *drbg)
* If a random pool has been added to the DRBG using RAND_add(), then
* its entropy will be used up first.
*/
-static size_t prov_drbg_get_entropy(PROV_DRBG *drbg, unsigned char **pout,
- int entropy, size_t min_len,
- size_t max_len, int prediction_resistance)
+size_t ossl_drbg_get_seed(void *vdrbg, unsigned char **pout,
+ int entropy, size_t min_len,
+ size_t max_len, int prediction_resistance,
+ const unsigned char *adin, size_t adin_len)
{
- unsigned int p_str;
- size_t r, bytes_needed;
+ PROV_DRBG *drbg = (PROV_DRBG *)vdrbg;
+ size_t bytes_needed;
unsigned char *buffer;
- if (!get_parent_strength(drbg, &p_str))
- return 0;
- if (drbg->strength > p_str) {
- /*
- * We currently don't support the algorithm from NIST SP 800-90C
- * 10.1.2 to use a weaker DRBG as source
- */
- ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_STRENGTH_TOO_WEAK);
- return 0;
- }
-
- if (drbg->parent_generate == NULL) {
- ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_CANNOT_GENERATE_RANDOM_NUMBERS);
- return 0;
- }
-
/* Figure out how many bytes we need */
bytes_needed = entropy >= 0 ? (entropy + 7) / 8 : 0;
if (bytes_needed < min_len)
@@ -180,13 +165,7 @@ static size_t prov_drbg_get_entropy(PROV_DRBG *drbg, unsigned char **pout,
}
/*
- * Our lock is already held, but we need to lock our parent before
- * generating bits from it. Note: taking the lock will be a no-op
- * if locking is not required (while drbg->parent->lock == NULL).
- */
- ossl_drbg_lock_parent(drbg);
- /*
- * Get random data from parent. Include our DRBG address as
+ * Get random data. Include our DRBG address as
* additional input, in order to provide a distinction between
* different DRBG child instances.
*
@@ -194,12 +173,9 @@ static size_t prov_drbg_get_entropy(PROV_DRBG *drbg, unsigned char **pout,
* a warning in some static code analyzers, but it's
* intentional and correct here.
*/
- r = drbg->parent_generate(drbg->parent, buffer, bytes_needed,
- drbg->strength, prediction_resistance,
- (unsigned char *)&drbg,
- sizeof(drbg));
- ossl_drbg_unlock_parent(drbg);
- if (r == 0) {
+ if (!ossl_prov_drbg_generate(drbg, buffer, bytes_needed,
+ drbg->strength, prediction_resistance,
+ (unsigned char *)&drbg, sizeof(drbg))) {
OPENSSL_secure_clear_free(buffer, bytes_needed);
ERR_raise(ERR_LIB_PROV, PROV_R_GENERATE_ERROR);
return 0;
@@ -208,12 +184,9 @@ static size_t prov_drbg_get_entropy(PROV_DRBG *drbg, unsigned char **pout,
return bytes_needed;
}
-/*
- * Implements the cleanup_entropy() callback
- *
- */
-static void prov_drbg_cleanup_entropy(ossl_unused PROV_DRBG *drbg,
- unsigned char *out, size_t outlen)
+/* Implements the cleanup_entropy() callback */
+void ossl_drbg_clear_seed(ossl_unused void *vdrbg,
+ unsigned char *out, size_t outlen)
{
OPENSSL_secure_clear_free(out, outlen);
}
@@ -222,6 +195,9 @@ static size_t get_entropy(PROV_DRBG *drbg, unsigned char **pout, int entropy,
size_t min_len, size_t max_len,
int prediction_resistance)
{
+ size_t bytes;
+ unsigned int p_str;
+
if (drbg->parent == NULL)
#ifdef FIPS_MODULE
return ossl_crngt_get_entropy(drbg, pout, entropy, min_len, max_len,
@@ -231,8 +207,42 @@ static size_t get_entropy(PROV_DRBG *drbg, unsigned char **pout, int entropy,
max_len);
#endif
- return prov_drbg_get_entropy(drbg, pout, entropy, min_len, max_len,
- prediction_resistance);
+ if (drbg->parent_get_seed == NULL) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED);
+ return 0;
+ }
+ if (!get_parent_strength(drbg, &p_str))
+ return 0;
+ if (drbg->strength > p_str) {
+ /*
+ * We currently don't support the algorithm from NIST SP 800-90C
+ * 10.1.2 to use a weaker DRBG as source
+ */
+ ERR_raise(ERR_LIB_PROV, PROV_R_PARENT_STRENGTH_TOO_WEAK);
+ return 0;
+ }
+
+ /*
+ * Our lock is already held, but we need to lock our parent before
+ * generating bits from it. Note: taking the lock will be a no-op
+ * if locking is not required (while drbg->parent->lock == NULL).
+ */
+ if (!ossl_drbg_lock_parent(drbg))
+ return 0;
+ /*
+ * Get random data from parent. Include our DRBG address as
+ * additional input, in order to provide a distinction between
+ * different DRBG child instances.
+ *
+ * Note: using the sizeof() operator on a pointer triggers
+ * a warning in some static code analyzers, but it's
+ * intentional and correct here.
+ */
+ bytes = drbg->parent_get_seed(drbg->parent, pout, drbg->strength,
+ min_len, max_len, prediction_resistance,
+ (unsigned char *)&drbg, sizeof(drbg));
+ ossl_drbg_unlock_parent(drbg);
+ return bytes;
}
static void cleanup_entropy(PROV_DRBG *drbg, unsigned char *out, size_t outlen)
@@ -243,8 +253,11 @@ static void cleanup_entropy(PROV_DRBG *drbg, unsigned char *out, size_t outlen)
#else
ossl_prov_cleanup_entropy(drbg->provctx, out, outlen);
#endif
- } else {
- prov_drbg_cleanup_entropy(drbg, out, outlen);
+ } else if (drbg->parent_clear_seed != NULL) {
+ if (!ossl_drbg_lock_parent(drbg))
+ return;
+ drbg->parent_clear_seed(drbg, out, outlen);
+ ossl_drbg_unlock_parent(drbg);
}
}
@@ -794,10 +807,12 @@ PROV_DRBG *ossl_rand_drbg_new
drbg->parent_unlock = OSSL_FUNC_rand_unlock(pfunc);
if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_GET_CTX_PARAMS)) != NULL)
drbg->parent_get_ctx_params = OSSL_FUNC_rand_get_ctx_params(pfunc);
- if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_GENERATE)) != NULL)
- drbg->parent_generate = OSSL_FUNC_rand_generate(pfunc);
if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_NONCE)) != NULL)
drbg->parent_nonce = OSSL_FUNC_rand_nonce(pfunc);
+ if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_GET_SEED)) != NULL)
+ drbg->parent_get_seed = OSSL_FUNC_rand_get_seed(pfunc);
+ if ((pfunc = find_call(p_dispatch, OSSL_FUNC_RAND_CLEAR_SEED)) != NULL)
+ drbg->parent_clear_seed = OSSL_FUNC_rand_clear_seed(pfunc);
/* Set some default maximums up */
drbg->max_entropylen = DRBG_MAX_LENGTH;
diff --git a/providers/implementations/rands/drbg_ctr.c b/providers/implementations/rands/drbg_ctr.c
index caf885c..1f5b142 100644
--- a/providers/implementations/rands/drbg_ctr.c
+++ b/providers/implementations/rands/drbg_ctr.c
@@ -755,5 +755,7 @@ const OSSL_DISPATCH ossl_drbg_ctr_functions[] = {
{ OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_ctr_get_ctx_params },
{ OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
(void(*)(void))drbg_ctr_verify_zeroization },
+ { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed },
+ { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed },
{ 0, NULL }
};
diff --git a/providers/implementations/rands/drbg_hash.c b/providers/implementations/rands/drbg_hash.c
index 9c44c0b..c799ef1 100644
--- a/providers/implementations/rands/drbg_hash.c
+++ b/providers/implementations/rands/drbg_hash.c
@@ -518,5 +518,7 @@ const OSSL_DISPATCH ossl_drbg_hash_functions[] = {
{ OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_hash_get_ctx_params },
{ OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
(void(*)(void))drbg_hash_verify_zeroization },
+ { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed },
+ { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed },
{ 0, NULL }
};
diff --git a/providers/implementations/rands/drbg_hmac.c b/providers/implementations/rands/drbg_hmac.c
index 314243d..f166d69 100644
--- a/providers/implementations/rands/drbg_hmac.c
+++ b/providers/implementations/rands/drbg_hmac.c
@@ -432,5 +432,7 @@ const OSSL_DISPATCH ossl_drbg_ossl_hmac_functions[] = {
{ OSSL_FUNC_RAND_GET_CTX_PARAMS, (void(*)(void))drbg_hmac_get_ctx_params },
{ OSSL_FUNC_RAND_VERIFY_ZEROIZATION,
(void(*)(void))drbg_hmac_verify_zeroization },
+ { OSSL_FUNC_RAND_GET_SEED, (void(*)(void))ossl_drbg_get_seed },
+ { OSSL_FUNC_RAND_CLEAR_SEED, (void(*)(void))ossl_drbg_clear_seed },
{ 0, NULL }
};
diff --git a/providers/implementations/rands/drbg_local.h b/providers/implementations/rands/drbg_local.h
index fbae882..ab8ad95 100644
--- a/providers/implementations/rands/drbg_local.h
+++ b/providers/implementations/rands/drbg_local.h
@@ -91,8 +91,9 @@ struct prov_drbg_st {
OSSL_FUNC_rand_lock_fn *parent_lock;
OSSL_FUNC_rand_unlock_fn *parent_unlock;
OSSL_FUNC_rand_get_ctx_params_fn *parent_get_ctx_params;
- OSSL_FUNC_rand_generate_fn *parent_generate;
OSSL_FUNC_rand_nonce_fn *parent_nonce;
+ OSSL_FUNC_rand_get_seed_fn *parent_get_seed;
+ OSSL_FUNC_rand_clear_seed_fn *parent_clear_seed;
const OSSL_DISPATCH *parent_dispatch;
@@ -205,6 +206,10 @@ int ossl_prov_drbg_generate(PROV_DRBG *drbg, unsigned char *out, size_t outlen,
unsigned int strength, int prediction_resistance,
const unsigned char *adin, size_t adinlen);
+/* Seeding api */
+OSSL_FUNC_rand_get_seed_fn ossl_drbg_get_seed;
+OSSL_FUNC_rand_clear_seed_fn ossl_drbg_clear_seed;
+
/* Verify that an array of numeric values is all zero */
#define PROV_DRBG_VERYIFY_ZEROIZATION(v) \
{ \