The branch master has been updated via eba3ebd7beaab865e92e4853881433aaa855392f (commit) via ee1d4f3db4e8963c6472420d0256c2bfd6525137 (commit) via 6694e51dbaecc7b331a6f0fa484d77008367c59c (commit) from f690ef151c0c3becc234daebf0418e04ff80580e (commit)
- Log ----------------------------------------------------------------- commit eba3ebd7beaab865e92e4853881433aaa855392f Author: Matt Caswell <m...@openssl.org> Date: Wed Jun 19 15:20:03 2019 +0100 Add a dummy call to BN_rand_ex() in the FIPS provider The previous commit made BIGNUM RAND operations available from within the FIPS provider. We test this out by making a dummy call to check it completes successfully. Reviewed-by: Matthias St. Pierre <matthias.st.pie...@ncp-e.com> (Merged from https://github.com/openssl/openssl/pull/9193) commit ee1d4f3db4e8963c6472420d0256c2bfd6525137 Author: Matt Caswell <m...@openssl.org> Date: Fri Jun 28 11:24:51 2019 +0100 Make BIGNUM rand functions available within the FIPS module The BIGNUM rand functions were previously disabled for the FIPS module. We can now re-enable them. Reviewed-by: Matthias St. Pierre <matthias.st.pie...@ncp-e.com> (Merged from https://github.com/openssl/openssl/pull/9193) commit 6694e51dbaecc7b331a6f0fa484d77008367c59c Author: Matt Caswell <m...@openssl.org> Date: Fri Jun 28 11:23:46 2019 +0100 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 <matthias.st.pie...@ncp-e.com> (Merged from https://github.com/openssl/openssl/pull/9193) ----------------------------------------------------------------------- Summary of changes: crypto/bn/bn_ctx.c | 2 + crypto/bn/bn_rand.c | 84 +++++++++++++++++-------------------- crypto/err/openssl.txt | 1 + crypto/include/internal/rand_int.h | 6 +++ crypto/rand/rand_err.c | 1 + crypto/rand/rand_lib.c | 37 ++++++++++++---- doc/internal/man3/rand_bytes_ex.pod | 41 ++++++++++++++++++ doc/man3/BN_rand.pod | 37 ++++++++++++---- include/openssl/bn.h | 4 ++ include/openssl/randerr.h | 1 + providers/fips/fipsprov.c | 3 ++ util/libcrypto.num | 4 ++ 12 files changed, 160 insertions(+), 61 deletions(-) create mode 100644 doc/internal/man3/rand_bytes_ex.pod diff --git a/crypto/bn/bn_ctx.c b/crypto/bn/bn_ctx.c index 4762114..cc3c303 100644 --- a/crypto/bn/bn_ctx.c +++ b/crypto/bn/bn_ctx.c @@ -247,6 +247,8 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx) OPENSSL_CTX *bn_get_lib_ctx(BN_CTX *ctx) { + if (ctx == NULL) + return NULL; return ctx->libctx; } diff --git a/crypto/bn/bn_rand.c b/crypto/bn/bn_rand.c index 6967627..a71e7d4 100644 --- a/crypto/bn/bn_rand.c +++ b/crypto/bn/bn_rand.c @@ -10,9 +10,9 @@ #include <stdio.h> #include <time.h> #include "internal/cryptlib.h" +#include "internal/rand_int.h" #include "bn_lcl.h" #include <openssl/rand.h> -#include <openssl/rand_drbg.h> #include <openssl/sha.h> #include <openssl/evp.h> @@ -20,10 +20,12 @@ typedef enum bnrand_flag_e { NORMAL, TESTING, PRIVATE } BNRAND_FLAG; -static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom) +static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom, + BN_CTX *ctx) { unsigned char *buf = NULL; int b, ret = 0, bit, bytes, mask; + OPENSSL_CTX *libctx = bn_get_lib_ctx(ctx); if (bits == 0) { if (top != BN_RAND_TOP_ANY || bottom != BN_RAND_BOTTOM_ANY) @@ -45,16 +47,8 @@ static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom) } /* make a random number and set the top and bottom bits */ - /* - * TODO(3.0): Temporarily disable RAND code in the FIPS module until we - * have made it available there. - */ -#if defined(FIPS_MODE) - BNerr(BN_F_BNRAND, ERR_R_INTERNAL_ERROR); - goto err; -#else - b = flag == NORMAL ? RAND_bytes(buf, bytes) : RAND_priv_bytes(buf, bytes); -#endif + b = flag == NORMAL ? rand_bytes_ex(libctx, buf, bytes) + : rand_priv_bytes_ex(libctx, buf, bytes); if (b <= 0) goto err; @@ -66,14 +60,8 @@ static int bnrand(BNRAND_FLAG flag, BIGNUM *rnd, int bits, int top, int bottom) unsigned char c; for (i = 0; i < bytes; i++) { - /* - * TODO(3.0): Temporarily disable RAND code in the FIPS module until we - * have made it available there. - */ -#if !defined(FIPS_MODE) - if (RAND_bytes(&c, 1) <= 0) + if (rand_bytes_ex(libctx, &c, 1) <= 0) goto err; -#endif if (c >= 128 && i > 0) buf[i] = buf[i - 1]; else if (c < 42) @@ -111,23 +99,33 @@ toosmall: return 0; } +int BN_rand_ex(BIGNUM *rnd, int bits, int top, int bottom, BN_CTX *ctx) +{ + return bnrand(NORMAL, rnd, bits, top, bottom, ctx); +} int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) { - return bnrand(NORMAL, rnd, bits, top, bottom); + return bnrand(NORMAL, rnd, bits, top, bottom, NULL); } int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom) { - return bnrand(TESTING, rnd, bits, top, bottom); + return bnrand(TESTING, rnd, bits, top, bottom, NULL); +} + +int BN_priv_rand_ex(BIGNUM *rnd, int bits, int top, int bottom, BN_CTX *ctx) +{ + return bnrand(PRIVATE, rnd, bits, top, bottom, ctx); } int BN_priv_rand(BIGNUM *rnd, int bits, int top, int bottom) { - return bnrand(PRIVATE, rnd, bits, top, bottom); + return bnrand(PRIVATE, rnd, bits, top, bottom, NULL); } /* random number r: 0 <= r < range */ -static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range) +static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range, + BN_CTX *ctx) { int n; int count = 100; @@ -149,7 +147,8 @@ static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range) * than range */ do { - if (!bnrand(flag, r, n + 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) + if (!bnrand(flag, r, n + 1, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, + ctx)) return 0; /* @@ -176,7 +175,7 @@ static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range) } else { do { /* range = 11..._2 or range = 101..._2 */ - if (!bnrand(flag, r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY)) + if (!bnrand(flag, r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, ctx)) return 0; if (!--count) { @@ -191,14 +190,24 @@ static int bnrand_range(BNRAND_FLAG flag, BIGNUM *r, const BIGNUM *range) return 1; } +int BN_rand_range_ex(BIGNUM *r, const BIGNUM *range, BN_CTX *ctx) +{ + return bnrand_range(NORMAL, r, range, ctx); +} + int BN_rand_range(BIGNUM *r, const BIGNUM *range) { - return bnrand_range(NORMAL, r, range); + return bnrand_range(NORMAL, r, range, NULL); +} + +int BN_priv_rand_range_ex(BIGNUM *r, const BIGNUM *range, BN_CTX *ctx) +{ + return bnrand_range(PRIVATE, r, range, ctx); } int BN_priv_rand_range(BIGNUM *r, const BIGNUM *range) { - return bnrand_range(PRIVATE, r, range); + return bnrand_range(PRIVATE, r, range, NULL); } int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) @@ -237,18 +246,9 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, unsigned char *k_bytes = NULL; int ret = 0; EVP_MD *md = NULL; - OPENSSL_CTX *libctx = (ctx != NULL) ? bn_get_lib_ctx(ctx) : NULL; - /* - * TODO(3.0): Temporarily disable RAND code in the FIPS module until we - * have made it available there. - */ -#ifdef FIPS_MODE - RAND_DRBG *privdrbg = NULL; -#else - RAND_DRBG *privdrbg = OPENSSL_CTX_get0_private_drbg(libctx); -#endif + OPENSSL_CTX *libctx = bn_get_lib_ctx(ctx); - if (mdctx == NULL || privdrbg == NULL) + if (mdctx == NULL) goto err; k_bytes = OPENSSL_malloc(num_k_bytes); @@ -275,14 +275,8 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, goto err; } for (done = 0; done < num_k_bytes;) { - /* - * TODO(3.0): Temporarily disable RAND code in the FIPS module until we - * have made it available there. - */ -#if !defined(FIPS_MODE) - if (!RAND_DRBG_bytes(privdrbg, random_bytes, sizeof(random_bytes))) + if (!rand_priv_bytes_ex(libctx, random_bytes, sizeof(random_bytes))) goto err; -#endif if (!EVP_DigestInit_ex(mdctx, md, NULL) || !EVP_DigestUpdate(mdctx, &done, sizeof(done)) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 5a19bdc..4d717e3 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 c1e5e03..d964a1d 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 5c0dc3d..d729441 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 07d2362..7768ade 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -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 index 0000000..7406073 --- /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<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 diff --git a/doc/man3/BN_rand.pod b/doc/man3/BN_rand.pod index 93e8c3f..fc41322 100644 --- a/doc/man3/BN_rand.pod +++ b/doc/man3/BN_rand.pod @@ -2,30 +2,37 @@ =head1 NAME -BN_rand, BN_priv_rand, BN_pseudo_rand, -BN_rand_range, BN_priv_rand_range, BN_pseudo_rand_range +BN_rand_ex, BN_rand, BN_priv_rand_ex, BN_priv_rand, BN_pseudo_rand, +BN_rand_range_ex, BN_rand_range, BN_priv_rand_range_ex, BN_priv_rand_range, +BN_pseudo_rand_range - generate pseudo-random number =head1 SYNOPSIS #include <openssl/bn.h> + int BN_rand_ex(BIGNUM *rnd, int bits, int top, int bottom, BN_CTX *ctx); int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); + int BN_priv_rand_ex(BIGNUM *rnd, int bits, int top, int bottom, BN_CTX *ctx); int BN_priv_rand(BIGNUM *rnd, int bits, int top, int bottom); int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); + int BN_rand_range_ex(BIGNUM *rnd, BIGNUM *range, BN_CTX *ctx); int BN_rand_range(BIGNUM *rnd, BIGNUM *range); + int BN_priv_rand_range_ex(BIGNUM *rnd, BIGNUM *range, BN_CTX *ctx); int BN_priv_rand_range(BIGNUM *rnd, BIGNUM *range); int BN_pseudo_rand_range(BIGNUM *rnd, BIGNUM *range); =head1 DESCRIPTION -BN_rand() generates a cryptographically strong pseudo-random number of -B<bits> in length and stores it in B<rnd>. +BN_rand_ex() generate a cryptographically strong pseudo-random +number of B<bits> in length and stores it in B<rnd> using the random number +generator for the library context associated with B<ctx>. The parameter B<ctx> +may be NULL in which case the default library context is used. If B<bits> is less than zero, or too small to accommodate the requirements specified by the B<top> and B<bottom> parameters, an error is returned. @@ -40,11 +47,20 @@ If B<bottom> is B<BN_RAND_BOTTOM_ODD>, the number will be odd; if it is B<BN_RAND_BOTTOM_ANY> it can be odd or even. If B<bits> is 1 then B<top> cannot also be B<BN_RAND_FLG_TOPTWO>. -BN_rand_range() generates a cryptographically strong pseudo-random -number B<rnd> in the range 0 E<lt>= B<rnd> E<lt> B<range>. +BN_rand() is the same as BN_rand_ex() except that the default library context +is always used. -BN_priv_rand() and BN_priv_rand_range() have the same semantics as -BN_rand() and BN_rand_range() respectively. They are intended to be +BN_rand_range_ex() generates a cryptographically strong pseudo-random +number B<rnd> in the range 0 E<lt>= B<rnd> E<lt> B<range> using the random number +generator for the library context associated with B<ctx>. The parameter B<ctx> +may be NULL in which case the default library context is used. + +BN_rand_range() is the same as BN_rand_range_ex() except that the default +library context is always used. + +BN_priv_rand_ex(), BN_priv_rand(), BN_priv_rand_rand_ex() and +BN_priv_rand_range() have the same semantics as BN_rand_ex(), BN_rand(), +BN_rand_range_ex() and BN_rand_range() respectively. They are intended to be used for generating values that should remain private, and mirror the same difference between L<RAND_bytes(3)> and L<RAND_priv_bytes(3)>. @@ -85,6 +101,11 @@ a future release. The BN_priv_rand() and BN_priv_rand_range() functions were added in OpenSSL 1.1.1. +=item * + +The BN_rand_ex(), BN_priv_rand_ex(), BN_rand_range_ex() and +BN_priv_rand_range_ex() functions were added in OpenSSL 3.0. + =back =head1 COPYRIGHT diff --git a/include/openssl/bn.h b/include/openssl/bn.h index 3770160..5c645d5 100644 --- a/include/openssl/bn.h +++ b/include/openssl/bn.h @@ -206,9 +206,13 @@ void BN_CTX_free(BN_CTX *c); void BN_CTX_start(BN_CTX *ctx); BIGNUM *BN_CTX_get(BN_CTX *ctx); void BN_CTX_end(BN_CTX *ctx); +int BN_rand_ex(BIGNUM *rnd, int bits, int top, int bottom, BN_CTX *ctx); int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_priv_rand_ex(BIGNUM *rnd, int bits, int top, int bottom, BN_CTX *ctx); int BN_priv_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_rand_range_ex(BIGNUM *r, const BIGNUM *range, BN_CTX *ctx); int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_priv_rand_range_ex(BIGNUM *r, const BIGNUM *range, BN_CTX *ctx); int BN_priv_rand_range(BIGNUM *rnd, const BIGNUM *range); int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h index bc1c063..28dd59a 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 diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index eb2a0c4..0f0a962 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -120,6 +120,9 @@ static int dummy_evp_call(void *provctx) if (RAND_DRBG_bytes(drbg, randbuf, sizeof(randbuf)) <= 0) goto err; + if (!BN_rand_ex(a, 256, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, bnctx)) + goto err; + ret = 1; err: BN_CTX_end(bnctx); diff --git a/util/libcrypto.num b/util/libcrypto.num index d003124..49d2f22 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4674,3 +4674,7 @@ OPENSSL_thread_stop_ex 4779 3_0_0 EXIST::FUNCTION: OSSL_PARAM_locate_const 4780 3_0_0 EXIST::FUNCTION: X509_REQ_set0_sm2_id 4781 3_0_0 EXIST::FUNCTION:SM2 X509_REQ_get0_sm2_id 4782 3_0_0 EXIST::FUNCTION:SM2 +BN_rand_ex 4783 3_0_0 EXIST::FUNCTION: +BN_priv_rand_ex 4784 3_0_0 EXIST::FUNCTION: +BN_rand_range_ex 4785 3_0_0 EXIST::FUNCTION: +BN_priv_rand_range_ex 4786 3_0_0 EXIST::FUNCTION: