From 6694e51dbaecc7b331a6f0fa484d77008367c59c Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Fri, 28 Jun 2019 11:23:46 +0100 Subject: [PATCH] Provide rand_bytes_ex and rand_priv_bytes_ex 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 (Merged from https://github.com/openssl/openssl/pull/9193) --- crypto/err/openssl.txt | 1 + crypto/include/internal/rand_int.h | 6 +++++ crypto/rand/rand_err.c | 1 + crypto/rand/rand_lib.c | 39 ++++++++++++++++++++------- doc/internal/man3/rand_bytes_ex.pod | 41 +++++++++++++++++++++++++++++ include/openssl/randerr.h | 1 + 6 files changed, 80 insertions(+), 9 deletions(-) create mode 100644 doc/internal/man3/rand_bytes_ex.pod diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 5a19bdc2cb..4d717e3605 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -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 diff --git a/crypto/include/internal/rand_int.h b/crypto/include/internal/rand_int.h index c1e5e033bb..d964a1d407 100644 --- a/crypto/include/internal/rand_int.h +++ b/crypto/include/internal/rand_int.h @@ -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 diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c index 5c0dc3d8e5..d729441ef4 100644 --- a/crypto/rand/rand_err.c +++ b/crypto/rand/rand_err.c @@ -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), diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 07d2362b04..7768ade8b7 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -749,16 +749,42 @@ 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; + + ret = RAND_DRBG_bytes(drbg, buf, num); + return ret; +} + +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 != 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; @@ -768,12 +794,7 @@ int RAND_priv_bytes(unsigned char *buf, int num) int RAND_bytes(unsigned char *buf, int num) { - 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; + 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 index 0000000000..740607310c --- /dev/null +++ b/doc/internal/man3/rand_bytes_ex.pod @@ -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 parameter. +The DRBG used for the operation is the public or private DRBG associated with +the specified B. 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. + +=cut diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h index bc1c06395b..28dd59a2c1 100644 --- a/include/openssl/randerr.h +++ b/include/openssl/randerr.h @@ -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