Provide rand_bytes_ex and rand_priv_bytes_ex
authorMatt Caswell <matt@openssl.org>
Fri, 28 Jun 2019 10:23:46 +0000 (11:23 +0100)
committerMatt Caswell <matt@openssl.org>
Tue, 2 Jul 2019 15:49:18 +0000 (16:49 +0100)
We provider internal versions of RAND_bytes() and RAND_priv_bytes() which
have the addition of taking an OPENSSL_CTX as a parameter.

Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
(Merged from https://github.com/openssl/openssl/pull/9193)

crypto/err/openssl.txt
crypto/include/internal/rand_int.h
crypto/rand/rand_err.c
crypto/rand/rand_lib.c
doc/internal/man3/rand_bytes_ex.pod [new file with mode: 0644]
include/openssl/randerr.h

index 5a19bdc..4d717e3 100644 (file)
@@ -1140,6 +1140,7 @@ RAND_F_DRBG_GET_ENTROPY:105:drbg_get_entropy
 RAND_F_DRBG_SETUP:117:drbg_setup
 RAND_F_GET_ENTROPY:106:get_entropy
 RAND_F_RAND_BYTES:100:RAND_bytes
+RAND_F_RAND_BYTES_EX:126:rand_bytes_ex
 RAND_F_RAND_DRBG_ENABLE_LOCKING:119:rand_drbg_enable_locking
 RAND_F_RAND_DRBG_GENERATE:107:RAND_DRBG_generate
 RAND_F_RAND_DRBG_GET_ENTROPY:120:rand_drbg_get_entropy
index c1e5e03..d964a1d 100644 (file)
@@ -137,4 +137,10 @@ void rand_pool_cleanup(void);
  */
 void rand_pool_keep_random_devices_open(int keep);
 
+/* Equivalent of RAND_priv_bytes() but additionally taking an OPENSSL_CTX */
+int rand_priv_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num);
+
+/* Equivalent of RAND_bytes() but additionally taking an OPENSSL_CTX */
+int rand_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num);
+
 #endif
index 5c0dc3d..d729441 100644 (file)
@@ -20,6 +20,7 @@ static const ERR_STRING_DATA RAND_str_functs[] = {
     {ERR_PACK(ERR_LIB_RAND, RAND_F_DRBG_SETUP, 0), "drbg_setup"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_GET_ENTROPY, 0), "get_entropy"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_BYTES, 0), "RAND_bytes"},
+    {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_BYTES_EX, 0), "rand_bytes_ex"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_ENABLE_LOCKING, 0),
      "rand_drbg_enable_locking"},
     {ERR_PACK(ERR_LIB_RAND, RAND_F_RAND_DRBG_GENERATE, 0),
index 07d2362..7768ade 100644 (file)
@@ -749,16 +749,16 @@ void RAND_add(const void *buf, int num, double randomness)
  * 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)
+int rand_priv_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num)
 {
     RAND_DRBG *drbg;
     int ret;
     const RAND_METHOD *meth = RAND_get_rand_method();
 
     if (meth != RAND_OpenSSL())
-        return RAND_bytes(buf, num);
+        return meth->bytes(buf, num);
 
-    drbg = RAND_DRBG_get0_private();
+    drbg = OPENSSL_CTX_get0_private_drbg(ctx);
     if (drbg == NULL)
         return 0;
 
@@ -766,14 +766,35 @@ int RAND_priv_bytes(unsigned char *buf, int num)
     return ret;
 }
 
-int RAND_bytes(unsigned char *buf, int num)
+int RAND_priv_bytes(unsigned char *buf, int num)
 {
+    return rand_priv_bytes_ex(NULL, buf, num);
+}
+
+int rand_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num)
+{
+    RAND_DRBG *drbg;
+    int ret;
     const RAND_METHOD *meth = RAND_get_rand_method();
 
-    if (meth->bytes != NULL)
-        return meth->bytes(buf, num);
-    RANDerr(RAND_F_RAND_BYTES, RAND_R_FUNC_NOT_IMPLEMENTED);
-    return -1;
+    if (meth != RAND_OpenSSL()) {
+        if (meth->bytes != NULL)
+            return meth->bytes(buf, num);
+        RANDerr(RAND_F_RAND_BYTES_EX, RAND_R_FUNC_NOT_IMPLEMENTED);
+        return -1;
+    }
+
+    drbg = OPENSSL_CTX_get0_public_drbg(ctx);
+    if (drbg == NULL)
+        return 0;
+
+    ret = RAND_DRBG_bytes(drbg, buf, num);
+    return ret;
+}
+
+int RAND_bytes(unsigned char *buf, int num)
+{
+    return rand_bytes_ex(NULL, buf, num);
 }
 
 #if !OPENSSL_API_1_1_0 && !defined(FIPS_MODE)
diff --git a/doc/internal/man3/rand_bytes_ex.pod b/doc/internal/man3/rand_bytes_ex.pod
new file mode 100644 (file)
index 0000000..7406073
--- /dev/null
@@ -0,0 +1,41 @@
+=pod
+
+=head1 NAME
+
+rand_bytes_ex, rand_priv_bytes_ex
+- internal random number routines
+
+=head1 SYNOPSIS
+
+ #include "internal/rand_int.h"
+
+ int rand_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num);
+ int rand_priv_bytes_ex(OPENSSL_CTX *ctx, unsigned char *buf, int num);
+
+=head1 DESCRIPTION
+
+rand_bytes_ex() and rand_priv_bytes_ex() are the equivalent of RAND_bytes() and
+RAND_priv_bytes() in the public API except that they both take an additional
+B<ctx> parameter.
+The DRBG used for the operation is the public or private DRBG associated with
+the specified B<ctx>. The parameter can be NULL, in which case
+the default library ctx is used.
+If the default RAND_METHOD has been changed then for compatibility reasons the
+RAND_METHOD will be used in preference and the DRBG of the library context
+ignored.
+
+=head1 RETURN VALUES
+
+rand_bytes_ex() and rand_bytes_priv_ex() return 0 or less on error or 1 on
+success.
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
index bc1c063..28dd59a 100644 (file)
@@ -29,6 +29,7 @@ int ERR_load_RAND_strings(void);
 # define RAND_F_DRBG_SETUP                                117
 # define RAND_F_GET_ENTROPY                               106
 # define RAND_F_RAND_BYTES                                100
+# define RAND_F_RAND_BYTES_EX                             126
 # define RAND_F_RAND_DRBG_ENABLE_LOCKING                  119
 # define RAND_F_RAND_DRBG_GENERATE                        107
 # define RAND_F_RAND_DRBG_GET_ENTROPY                     120