rand: add set0 calls for the private and public DRBGs
authorPauli <pauli@openssl.org>
Mon, 26 Sep 2022 05:20:14 +0000 (15:20 +1000)
committerPauli <pauli@openssl.org>
Tue, 1 Nov 2022 21:42:46 +0000 (08:42 +1100)
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/19510)

crypto/evp/evp_rand.c
crypto/rand/rand_lib.c
doc/man3/EVP_RAND.pod
doc/man3/RAND_get0_primary.pod
include/openssl/evp.h
include/openssl/rand.h
util/libcrypto.num

index 40048ed603edffd4678adc90cba454da14291b68..ed7f213bd84653c7ae9c41c9a3fab564e9da775a 100644 (file)
@@ -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;
 
@@ -347,7 +347,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);
index c69fc4f2afba3d72d03d9bdcdabbeb81bede7171..7140729bd2f7b21507501e1a07beac93f1d45f08 100644 (file)
@@ -724,6 +724,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)
 {
index f21b2f69d73638193e1f54c4ee35b3ad3fa53497..6aae33b5fd949c09cb378a558e2aead37fef205c 100644 (file)
@@ -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
@@ -393,7 +396,9 @@ L<life_cycle-rand(7)>
 
 =head1 HISTORY
 
-This functionality was added to OpenSSL 3.0.
+EVP_RAND_CTX_up_ref() was added in OpenSSL 3.1.
+
+The remaining functions were added in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
index 408d02077f29a2fbe14e86944a9c9efb989f0643..88a2f6c311bc318b985c21ee80360ad7c7054d27 100644 (file)
@@ -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
 
index 8a9f61d73edc0d6e14cec0b51116f5ff74fb2678..b5f67fe492b26d7779d571f33d84e35859efe217 100644 (file)
@@ -1251,6 +1251,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[]);
index ad3054fd575f5370c85d09a3f4ab70c8110de92d..1fa1129e3cf7dbfc2ff5437838f86d9044fadbf6 100644 (file)
@@ -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);
index e6e9ecbe5f49be2f8a2ee97543b6dc8dc5a084ce..81d67b32e9530fb597057e53d369a33eea9f1b76 100644 (file)
@@ -5427,6 +5427,9 @@ 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:
 X509_PUBKEY_set0_public_key             ?      3_2_0   EXIST::FUNCTION:
 OSSL_STACK_OF_X509_free                 ?      3_2_0   EXIST::FUNCTION:
 EVP_MD_CTX_dup                          ?      3_2_0   EXIST::FUNCTION: