From 03bede0cc8418e056d4ac551fbdc2283e0e9491f Mon Sep 17 00:00:00 2001 From: Pauli Date: Fri, 30 Oct 2020 15:53:22 +1000 Subject: [PATCH] rand: move the entropy source out of the FIPS provider Reviewed-by: Matt Caswell Reviewed-by: Matthias St. Pierre (Merged from https://github.com/openssl/openssl/pull/13226) --- crypto/err/openssl.txt | 5 +- crypto/evp/evp_rand.c | 2 +- crypto/provider_core.c | 8 +- crypto/rand/build.info | 2 +- crypto/rand/prov_seed.c | 76 +++++++++++++++++++ crypto/rand/rand_err.c | 4 +- crypto/rand/rand_lib.c | 2 +- crypto/rand/rand_pool.c | 2 +- include/crypto/rand.h | 21 +++++ include/openssl/core_dispatch.h | 17 +++++ include/openssl/core_names.h | 2 +- include/openssl/randerr.h | 2 +- .../common/include/prov/providercommonerr.h | 1 - providers/common/provider_err.c | 2 - 14 files changed, 131 insertions(+), 15 deletions(-) create mode 100644 crypto/rand/prov_seed.c diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 7bb83593a6..690bd197cd 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2944,6 +2944,8 @@ PROV_R_NO_PARAMETERS_SET:177:no parameters set PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE:178:\ operation not supported for this keytype PROV_R_OUTPUT_BUFFER_TOO_SMALL:106:output buffer too small +PROV_R_PARENT_CANNOT_GENERATE_RANDOM_NUMBERS:228:\ + parent cannot generate random numbers PROV_R_PARENT_LOCKING_NOT_ENABLED:182:parent locking not enabled PROV_R_PARENT_STRENGTH_TOO_WEAK:194:parent strength too weak PROV_R_PATH_MUST_BE_ABSOLUTE:219:path must be absolute @@ -2965,7 +2967,6 @@ PROV_R_UNABLE_TO_GET_NONCE:203:unable to get nonce PROV_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER:198:\ unable to get parent reseed prop counter PROV_R_UNABLE_TO_GET_PARENT_STRENGTH:199:unable to get parent strength -PROV_R_UNABLE_TO_GET_RESEED_PROP_CTR:200:unable to get reseed prop ctr PROV_R_UNABLE_TO_INITIALISE_CIPHERS:208:unable to initialise ciphers PROV_R_UNABLE_TO_LOAD_SHA1:143:unable to load sha1 PROV_R_UNABLE_TO_LOAD_SHA256:147:unable to load sha256 @@ -3027,7 +3028,7 @@ RAND_R_UNABLE_TO_FETCH_DRBG:144:unable to fetch drbg RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER:141:\ unable to get parent reseed prop counter RAND_R_UNABLE_TO_GET_PARENT_STRENGTH:138:unable to get parent strength -RAND_R_UNABLE_TO_GET_RESEED_PROP_CTR:142:unable to get reseed prop ctr +RAND_R_UNABLE_TO_GET_RESEED_COUNTER :142:unable to get reseed counter RAND_R_UNABLE_TO_LOCK_PARENT:140:unable to lock parent RAND_R_UNSUPPORTED_DRBG_FLAGS:132:unsupported drbg flags RAND_R_UNSUPPORTED_DRBG_TYPE:120:unsupported drbg type diff --git a/crypto/evp/evp_rand.c b/crypto/evp/evp_rand.c index 07d1ad9db2..6a4f57414c 100644 --- a/crypto/evp/evp_rand.c +++ b/crypto/evp/evp_rand.c @@ -511,7 +511,7 @@ static int evp_rand_generate_locked(EVP_RAND_CTX *ctx, unsigned char *out, size_t chunk, max_request = 0; OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; - params[0] = OSSL_PARAM_construct_size_t(OSSL_DRBG_PARAM_MAX_REQUEST, + params[0] = OSSL_PARAM_construct_size_t(OSSL_RAND_PARAM_MAX_REQUEST, &max_request); if (!evp_rand_get_ctx_params_locked(ctx, params) || max_request == 0) { diff --git a/crypto/provider_core.c b/crypto/provider_core.c index d919a95b40..954befd4a2 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -15,6 +15,7 @@ #include #include "crypto/cryptlib.h" #include "crypto/evp.h" /* evp_method_store_flush */ +#include "crypto/rand.h" #include "internal/nelem.h" #include "internal/thread_once.h" #include "internal/provider.h" @@ -1074,8 +1075,7 @@ static int core_pop_error_to_mark(const OSSL_CORE_HANDLE *handle) #endif /* FIPS_MODULE */ /* - * Functions provided by the core. Blank line separates "families" of related - * functions. + * Functions provided by the core. */ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_CORE_GETTABLE_PARAMS, (void (*)(void))core_gettable_params }, @@ -1101,6 +1101,10 @@ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))BIO_vprintf }, { OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf }, { OSSL_FUNC_SELF_TEST_CB, (void (*)(void))OSSL_SELF_TEST_get_callback }, + { OSSL_FUNC_GET_ENTROPY, (void (*)(void))ossl_rand_get_entropy }, + { OSSL_FUNC_CLEANUP_ENTROPY, (void (*)(void))ossl_rand_cleanup_entropy }, + { OSSL_FUNC_GET_NONCE, (void (*)(void))ossl_rand_get_nonce }, + { OSSL_FUNC_CLEANUP_NONCE, (void (*)(void))ossl_rand_cleanup_nonce }, #endif { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc }, { OSSL_FUNC_CRYPTO_ZALLOC, (void (*)(void))CRYPTO_zalloc }, diff --git a/crypto/rand/build.info b/crypto/rand/build.info index f58a026f3b..b9dc16a6c7 100644 --- a/crypto/rand/build.info +++ b/crypto/rand/build.info @@ -1,7 +1,7 @@ LIBS=../../libcrypto $COMMON=rand_lib.c rand_meth.c -$CRYPTO=randfile.c rand_err.c rand_deprecated.c +$CRYPTO=randfile.c rand_err.c rand_deprecated.c prov_seed.c rand_pool.c IF[{- !$disabled{'egd'} -}] $CRYPTO=$CRYPTO rand_egd.c diff --git a/crypto/rand/prov_seed.c b/crypto/rand/prov_seed.c new file mode 100644 index 0000000000..f79955180a --- /dev/null +++ b/crypto/rand/prov_seed.c @@ -0,0 +1,76 @@ +/* + * Copyright 2020 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 + * https://www.openssl.org/source/license.html + */ + +#include "crypto/rand.h" +#include "crypto/rand_pool.h" +#include +#include + +size_t ossl_rand_get_entropy(ossl_unused OSSL_CORE_HANDLE *handle, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len) +{ + size_t ret = 0; + size_t entropy_available; + RAND_POOL *pool; + + pool = rand_pool_new(entropy, 1, min_len, max_len); + if (pool == NULL) { + ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* Get entropy by polling system entropy sources. */ + entropy_available = ossl_pool_acquire_entropy(pool); + + if (entropy_available > 0) { + ret = rand_pool_length(pool); + *pout = rand_pool_detach(pool); + } + + rand_pool_free(pool); + return ret; +} + +void ossl_rand_cleanup_entropy(ossl_unused OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len) +{ + OPENSSL_secure_clear_free(buf, len); +} + +size_t ossl_rand_get_nonce(ossl_unused OSSL_CORE_HANDLE *handle, + unsigned char **pout, size_t min_len, size_t max_len, + const void *salt, size_t salt_len) +{ + size_t ret = 0; + RAND_POOL *pool; + + pool = rand_pool_new(0, 0, min_len, max_len); + if (pool == NULL) { + ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!ossl_pool_add_nonce_data(pool)) + goto err; + + if (salt != NULL && !rand_pool_add(pool, salt, salt_len, 0)) + goto err; + ret = rand_pool_length(pool); + *pout = rand_pool_detach(pool); + err: + rand_pool_free(pool); + return ret; +} + +void ossl_rand_cleanup_nonce(ossl_unused OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len) +{ + OPENSSL_clear_free(buf, len); +} diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c index b70cc4cb9f..ecf7cb2e59 100644 --- a/crypto/rand/rand_err.c +++ b/crypto/rand/rand_err.c @@ -87,8 +87,8 @@ static const ERR_STRING_DATA RAND_str_reasons[] = { "unable to get parent reseed prop counter"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_STRENGTH), "unable to get parent strength"}, - {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_RESEED_PROP_CTR), - "unable to get reseed prop ctr"}, + {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_RESEED_COUNTER), + "unable to get reseed counter"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_LOCK_PARENT), "unable to lock parent"}, {ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_FLAGS), diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 9790b21646..73d509a8dc 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -27,7 +27,7 @@ #include "e_os.h" #ifndef FIPS_MODULE -# include "prov/rand_pool.h" +# include "crypto/rand_pool.h" # include "prov/seeding.h" # ifndef OPENSSL_NO_ENGINE diff --git a/crypto/rand/rand_pool.c b/crypto/rand/rand_pool.c index c66c0e3fa8..ebb9078ce6 100644 --- a/crypto/rand/rand_pool.c +++ b/crypto/rand/rand_pool.c @@ -14,7 +14,7 @@ #include "crypto/rand.h" #include #include "internal/thread_once.h" -#include "prov/rand_pool.h" +#include "crypto/rand_pool.h" /* * Allocate memory and initialize a new random pool diff --git a/include/crypto/rand.h b/include/crypto/rand.h index a437565fe8..c870245521 100644 --- a/include/crypto/rand.h +++ b/include/crypto/rand.h @@ -19,6 +19,7 @@ # define OSSL_CRYPTO_RAND_H # include +# include "crypto/rand_pool.h" /* * Defines related to seed sources @@ -93,4 +94,24 @@ void rand_pool_keep_random_devices_open(int keep); */ void ossl_random_add_conf_module(void); +/* + * Get and cleanup random seed material. + */ +size_t ossl_rand_get_entropy(ossl_unused OSSL_CORE_HANDLE *handle, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len); +void ossl_rand_cleanup_entropy(ossl_unused OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len); +size_t ossl_rand_get_nonce(ossl_unused OSSL_CORE_HANDLE *handle, + unsigned char **pout, size_t min_len, size_t max_len, + const void *salt, size_t salt_len); +void ossl_rand_cleanup_nonce(ossl_unused OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len); + +/* + * Get seeding material from the operating system sources. + */ +size_t ossl_pool_acquire_entropy(RAND_POOL *pool); +int ossl_pool_add_nonce_data(RAND_POOL *pool); + #endif diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index d4d581df57..bbd0429718 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -161,6 +161,23 @@ OSSL_CORE_MAKE_FUNC(int, BIO_ctrl, (OSSL_CORE_BIO *bio, OSSL_CORE_MAKE_FUNC(void, self_test_cb, (OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK **cb, void **cbarg)) +/* Functions to get seed material from the operating system */ +#define OSSL_FUNC_GET_ENTROPY 101 +#define OSSL_FUNC_CLEANUP_ENTROPY 102 +#define OSSL_FUNC_GET_NONCE 103 +#define OSSL_FUNC_CLEANUP_NONCE 104 +OSSL_CORE_MAKE_FUNC(size_t, get_entropy, (const OSSL_CORE_HANDLE *handle, + unsigned char **pout, int entropy, + size_t min_len, size_t max_len)) +OSSL_CORE_MAKE_FUNC(void, cleanup_entropy, (const OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len)) +OSSL_CORE_MAKE_FUNC(size_t, get_nonce, (const OSSL_CORE_HANDLE *handle, + unsigned char **pout, size_t min_len, + size_t max_len, const void *salt, + size_t salt_len)) +OSSL_CORE_MAKE_FUNC(void, cleanup_nonce, (const OSSL_CORE_HANDLE *handle, + unsigned char *buf, size_t len)) + /* Functions provided by the provider to the Core, reserved numbers 1024-1535 */ # define OSSL_FUNC_PROVIDER_TEARDOWN 1024 OSSL_CORE_MAKE_FUNC(void,provider_teardown,(void *provctx)) diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h index f0b0cd0163..d41feeb144 100644 --- a/include/openssl/core_names.h +++ b/include/openssl/core_names.h @@ -219,13 +219,13 @@ extern "C" { /* Known RAND names */ #define OSSL_RAND_PARAM_STATE "state" #define OSSL_RAND_PARAM_STRENGTH "strength" +#define OSSL_RAND_PARAM_MAX_REQUEST "max_request" #define OSSL_RAND_PARAM_TEST_ENTROPY "test_entropy" #define OSSL_RAND_PARAM_TEST_NONCE "test_nonce" /* RAND/DRBG names */ #define OSSL_DRBG_PARAM_RESEED_REQUESTS "reseed_requests" #define OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL "reseed_time_interval" -#define OSSL_DRBG_PARAM_MAX_REQUEST "max_request" #define OSSL_DRBG_PARAM_MIN_ENTROPYLEN "min_entropylen" #define OSSL_DRBG_PARAM_MAX_ENTROPYLEN "max_entropylen" #define OSSL_DRBG_PARAM_MIN_NONCELEN "min_noncelen" diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h index 3eef9afdd2..40e5787308 100644 --- a/include/openssl/randerr.h +++ b/include/openssl/randerr.h @@ -102,7 +102,7 @@ int ERR_load_RAND_strings(void); # define RAND_R_UNABLE_TO_FETCH_DRBG 144 # define RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER 141 # define RAND_R_UNABLE_TO_GET_PARENT_STRENGTH 138 -# define RAND_R_UNABLE_TO_GET_RESEED_PROP_CTR 142 +# define RAND_R_UNABLE_TO_GET_RESEED_COUNTER 142 # define RAND_R_UNABLE_TO_LOCK_PARENT 140 # define RAND_R_UNSUPPORTED_DRBG_FLAGS 132 # define RAND_R_UNSUPPORTED_DRBG_TYPE 120 diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h index d972a819e2..05ca8abef0 100644 --- a/providers/common/include/prov/providercommonerr.h +++ b/providers/common/include/prov/providercommonerr.h @@ -160,7 +160,6 @@ int ERR_load_PROV_strings(void); # define PROV_R_UNABLE_TO_GET_NONCE 203 # define PROV_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER 198 # define PROV_R_UNABLE_TO_GET_PARENT_STRENGTH 199 -# define PROV_R_UNABLE_TO_GET_RESEED_PROP_CTR 200 # define PROV_R_UNABLE_TO_INITIALISE_CIPHERS 208 # define PROV_R_UNABLE_TO_LOAD_SHA1 143 # define PROV_R_UNABLE_TO_LOAD_SHA256 147 diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index 606d78cc57..2b65903a31 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -186,8 +186,6 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "unable to get parent reseed prop counter"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH), "unable to get parent strength"}, - {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_GET_RESEED_PROP_CTR), - "unable to get reseed prop ctr"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_INITIALISE_CIPHERS), "unable to initialise ciphers"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_LOAD_SHA1), -- 2.39.5