summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPauli <pauli@openssl.org>2022-09-26 15:20:14 +1000
committerPauli <pauli@openssl.org>2022-11-02 08:41:05 +1100
commite30aad54159aeef15b6386d67d4724242d828d12 (patch)
treee83d6f8f17d3475800ff65686f2084bfba18e1bc
parent5e244a93778a59e756f626e3135455923ce29a22 (diff)
rand: add set0 calls for the private and public DRBGs
The FIPS 140-3 DSA and ECDSA tests need to be known answer tests which means the entropy needs to be cooked. This permits this. Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Tim Hudson <tjh@openssl.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> (Merged from https://github.com/openssl/openssl/pull/19486)
-rw-r--r--crypto/evp/evp_rand.c4
-rw-r--r--crypto/rand/rand_lib.c28
-rw-r--r--doc/man3/EVP_RAND.pod5
-rw-r--r--doc/man3/RAND_get0_primary.pod23
-rw-r--r--include/openssl/evp.h1
-rw-r--r--include/openssl/rand.h2
-rw-r--r--util/libcrypto.num3
7 files changed, 58 insertions, 8 deletions
diff --git a/crypto/evp/evp_rand.c b/crypto/evp/evp_rand.c
index c36dbdc56c..3031ecbcc0 100644
--- a/crypto/evp/evp_rand.c
+++ b/crypto/evp/evp_rand.c
@@ -320,7 +320,7 @@ int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[])
return 1;
}
-static int evp_rand_ctx_up_ref(EVP_RAND_CTX *ctx)
+int EVP_RAND_CTX_up_ref(EVP_RAND_CTX *ctx)
{
int ref = 0;
@@ -345,7 +345,7 @@ EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent)
return NULL;
}
if (parent != NULL) {
- if (!evp_rand_ctx_up_ref(parent)) {
+ if (!EVP_RAND_CTX_up_ref(parent)) {
ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
CRYPTO_THREAD_lock_free(ctx->refcnt_lock);
OPENSSL_free(ctx);
diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c
index c453d32261..50aa9226cb 100644
--- a/crypto/rand/rand_lib.c
+++ b/crypto/rand/rand_lib.c
@@ -726,6 +726,34 @@ EVP_RAND_CTX *RAND_get0_private(OSSL_LIB_CTX *ctx)
return rand;
}
+int RAND_set0_public(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand)
+{
+ RAND_GLOBAL *dgbl = rand_get_global(ctx);
+ EVP_RAND_CTX *old;
+ int r;
+
+ if (dgbl == NULL)
+ return 0;
+ old = CRYPTO_THREAD_get_local(&dgbl->public);
+ if ((r = CRYPTO_THREAD_set_local(&dgbl->public, rand)) > 0)
+ EVP_RAND_CTX_free(old);
+ return r;
+}
+
+int RAND_set0_private(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand)
+{
+ RAND_GLOBAL *dgbl = rand_get_global(ctx);
+ EVP_RAND_CTX *old;
+ int r;
+
+ if (dgbl == NULL)
+ return 0;
+ old = CRYPTO_THREAD_get_local(&dgbl->private);
+ if ((r = CRYPTO_THREAD_set_local(&dgbl->private, rand)) > 0)
+ EVP_RAND_CTX_free(old);
+ return r;
+}
+
#ifndef FIPS_MODULE
static int random_set_string(char **p, const char *s)
{
diff --git a/doc/man3/EVP_RAND.pod b/doc/man3/EVP_RAND.pod
index f21b2f69d7..d842fe70d1 100644
--- a/doc/man3/EVP_RAND.pod
+++ b/doc/man3/EVP_RAND.pod
@@ -3,7 +3,7 @@
=head1 NAME
EVP_RAND, EVP_RAND_fetch, EVP_RAND_free, EVP_RAND_up_ref, EVP_RAND_CTX,
-EVP_RAND_CTX_new, EVP_RAND_CTX_free, EVP_RAND_instantiate,
+EVP_RAND_CTX_new, EVP_RAND_CTX_free, EVP_RAND_CTX_up_ref, EVP_RAND_instantiate,
EVP_RAND_uninstantiate, EVP_RAND_generate, EVP_RAND_reseed, EVP_RAND_nonce,
EVP_RAND_enable_locking, EVP_RAND_verify_zeroization, EVP_RAND_get_strength,
EVP_RAND_get_state,
@@ -30,6 +30,7 @@ EVP_RAND_STATE_ERROR - EVP RAND routines
void EVP_RAND_free(EVP_RAND *rand);
EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent);
void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx);
+ int EVP_RAND_CTX_up_ref(EVP_RAND_CTX *ctx);
EVP_RAND *EVP_RAND_CTX_get0_rand(EVP_RAND_CTX *ctx);
int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[]);
int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[]);
@@ -367,6 +368,8 @@ B<EVP_RAND_CTX> structure or NULL if an error occurred.
EVP_RAND_CTX_free() does not return a value.
+EVP_RAND_CTX_up_ref() returns 1 on success, 0 on error.
+
EVP_RAND_nonce() returns the length of the nonce.
EVP_RAND_get_strength() returns the strength of the random number generator
diff --git a/doc/man3/RAND_get0_primary.pod b/doc/man3/RAND_get0_primary.pod
index 408d02077f..88a2f6c311 100644
--- a/doc/man3/RAND_get0_primary.pod
+++ b/doc/man3/RAND_get0_primary.pod
@@ -4,7 +4,9 @@
RAND_get0_primary,
RAND_get0_public,
-RAND_get0_private
+RAND_get0_private,
+RAND_set0_public,
+RAND_set0_private
- get access to the global EVP_RAND_CTX instances
=head1 SYNOPSIS
@@ -14,6 +16,8 @@ RAND_get0_private
EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx);
EVP_RAND_CTX *RAND_get0_public(OSSL_LIB_CTX *ctx);
EVP_RAND_CTX *RAND_get0_private(OSSL_LIB_CTX *ctx);
+ int RAND_set0_public(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand);
+ int RAND_set0_private(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand);
=head1 DESCRIPTION
@@ -25,7 +29,10 @@ by RAND_bytes() and RAND_priv_bytes(), respectively.
The I<primary> 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.
+The three get functions provide access to the shared DRBG instances.
+
+The two set functions allow the public and private DRBG instances to be
+replaced by another random number generator.
=head1 RETURN VALUES
@@ -38,8 +45,8 @@ for the given OSSL_LIB_CTX B<ctx>.
RAND_get0_private() returns a pointer to the I<private> DRBG instance
for the given OSSL_LIB_CTX B<ctx>.
-In all the above cases the B<ctx> parameter can
-be NULL in which case the default OSSL_LIB_CTX is used.
+RAND_set0_public() and RAND_set0_private() return 1 on success and 0
+on error.
=head1 NOTES
@@ -61,6 +68,10 @@ To set the type of DRBG that will be instantiated, use the
L<RAND_set_DRBG_type(3)> call before accessing the random number generation
infrastructure.
+The two set functions, operate on the the current thread. If you want to
+use the same random number generator across all threads, each thread
+must individually call the set functions.
+
=head1 SEE ALSO
L<EVP_RAND(3)>,
@@ -68,7 +79,9 @@ L<RAND_set_DRBG_type(3)>
=head1 HISTORY
-These functions were added in OpenSSL 3.0.
+RAND_set0_public() and RAND_set0_private() were added in OpenSSL 3.1.
+
+The remaining functions were added in OpenSSL 3.0.
=head1 COPYRIGHT
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 49e8e1df78..63c23dd941 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -1248,6 +1248,7 @@ const OSSL_PROVIDER *EVP_RAND_get0_provider(const EVP_RAND *rand);
int EVP_RAND_get_params(EVP_RAND *rand, OSSL_PARAM params[]);
EVP_RAND_CTX *EVP_RAND_CTX_new(EVP_RAND *rand, EVP_RAND_CTX *parent);
+int EVP_RAND_CTX_up_ref(EVP_RAND_CTX *ctx);
void EVP_RAND_CTX_free(EVP_RAND_CTX *ctx);
EVP_RAND *EVP_RAND_CTX_get0_rand(EVP_RAND_CTX *ctx);
int EVP_RAND_CTX_get_params(EVP_RAND_CTX *ctx, OSSL_PARAM params[]);
diff --git a/include/openssl/rand.h b/include/openssl/rand.h
index ad3054fd57..1fa1129e3c 100644
--- a/include/openssl/rand.h
+++ b/include/openssl/rand.h
@@ -82,6 +82,8 @@ OSSL_DEPRECATEDIN_1_1_0 int RAND_pseudo_bytes(unsigned char *buf, int num);
EVP_RAND_CTX *RAND_get0_primary(OSSL_LIB_CTX *ctx);
EVP_RAND_CTX *RAND_get0_public(OSSL_LIB_CTX *ctx);
EVP_RAND_CTX *RAND_get0_private(OSSL_LIB_CTX *ctx);
+int RAND_set0_public(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand);
+int RAND_set0_private(OSSL_LIB_CTX *ctx, EVP_RAND_CTX *rand);
int RAND_set_DRBG_type(OSSL_LIB_CTX *ctx, const char *drbg, const char *propq,
const char *cipher, const char *digest);
diff --git a/util/libcrypto.num b/util/libcrypto.num
index d9c040fb47..bd21027305 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -5427,3 +5427,6 @@ EVP_PKEY_get0_provider 5554 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_get0_provider 5555 3_0_0 EXIST::FUNCTION:
OPENSSL_strcasecmp 5556 3_0_3 EXIST::FUNCTION:
OPENSSL_strncasecmp 5557 3_0_3 EXIST::FUNCTION:
+EVP_RAND_CTX_up_ref ? 3_1_0 EXIST::FUNCTION:
+RAND_set0_public ? 3_1_0 EXIST::FUNCTION:
+RAND_set0_private ? 3_1_0 EXIST::FUNCTION: