diff options
author | Pauli <pauli@openssl.org> | 2023-09-05 12:51:05 +1000 |
---|---|---|
committer | Pauli <pauli@openssl.org> | 2023-10-03 18:54:03 +1100 |
commit | 354053395fbd20e5efb584427b5da9be9231fd93 (patch) | |
tree | 609231a9dae7843a58166d8bf2b3cbc953af2b39 /providers | |
parent | bc347a35d025b989abfeb8ef556f895cb1ee9381 (diff) |
fips: use seed source requested
Fixes #21909
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22210)
Diffstat (limited to 'providers')
-rw-r--r-- | providers/baseprov.c | 8 | ||||
-rw-r--r-- | providers/common/provider_seeding.c | 53 |
2 files changed, 51 insertions, 10 deletions
diff --git a/providers/baseprov.c b/providers/baseprov.c index 2e5e0b3849..9c1d9a4ed9 100644 --- a/providers/baseprov.c +++ b/providers/baseprov.c @@ -19,6 +19,7 @@ #include "prov/providercommon.h" #include "prov/implementations.h" #include "prov/provider_util.h" +#include "prov/names.h" /* * Forward declarations to ensure that interface functions are correctly @@ -90,6 +91,11 @@ static const OSSL_ALGORITHM base_store[] = { #undef STORE }; +static const OSSL_ALGORITHM base_rands[] = { + { PROV_NAMES_SEED_SRC, "provider=base", ossl_seed_src_functions }, + { NULL, NULL, NULL } +}; + static const OSSL_ALGORITHM *base_query(void *provctx, int operation_id, int *no_cache) { @@ -101,6 +107,8 @@ static const OSSL_ALGORITHM *base_query(void *provctx, int operation_id, return base_decoder; case OSSL_OP_STORE: return base_store; + case OSSL_OP_RAND: + return base_rands; } return NULL; } diff --git a/providers/common/provider_seeding.c b/providers/common/provider_seeding.c index 0edbb87630..55fcd2d625 100644 --- a/providers/common/provider_seeding.c +++ b/providers/common/provider_seeding.c @@ -9,12 +9,33 @@ #include <openssl/core_dispatch.h> #include "prov/seeding.h" +#include "prov/providercommon.h" static OSSL_FUNC_get_entropy_fn *c_get_entropy = NULL; +static OSSL_FUNC_get_user_entropy_fn *c_get_user_entropy = NULL; static OSSL_FUNC_cleanup_entropy_fn *c_cleanup_entropy = NULL; static OSSL_FUNC_get_nonce_fn *c_get_nonce = NULL; +static OSSL_FUNC_get_user_nonce_fn *c_get_user_nonce = NULL; static OSSL_FUNC_cleanup_nonce_fn *c_cleanup_nonce = NULL; +#ifdef FIPS_MODULE +/* + * The FIPS provider uses an internal library context which is what the + * passed provider context references. Since the seed source is external + * to the FIPS provider, this is the wrong one. We need to convert this + * to the correct core handle before up-calling libcrypto. + */ +# define CORE_HANDLE(provctx) \ + FIPS_get_core_handle(ossl_prov_ctx_get0_libctx(provctx)) +#else +/* + * The non-FIPS path *should* be unused because the full DRBG chain including + * seed source is instantiated. However, that might not apply for third + * party providers, so this is retained for compatibility. + */ +# define CORE_HANDLE(provctx) ossl_prov_ctx_get0_handle(provctx) +#endif + int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns) { for (; fns->function_id != 0; fns++) { @@ -29,12 +50,18 @@ int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns) case OSSL_FUNC_GET_ENTROPY: set_func(c_get_entropy, OSSL_FUNC_get_entropy(fns)); break; + case OSSL_FUNC_GET_USER_ENTROPY: + set_func(c_get_user_entropy, OSSL_FUNC_get_user_entropy(fns)); + break; case OSSL_FUNC_CLEANUP_ENTROPY: set_func(c_cleanup_entropy, OSSL_FUNC_cleanup_entropy(fns)); break; case OSSL_FUNC_GET_NONCE: set_func(c_get_nonce, OSSL_FUNC_get_nonce(fns)); break; + case OSSL_FUNC_GET_USER_NONCE: + set_func(c_get_user_nonce, OSSL_FUNC_get_user_nonce(fns)); + break; case OSSL_FUNC_CLEANUP_NONCE: set_func(c_cleanup_nonce, OSSL_FUNC_cleanup_nonce(fns)); break; @@ -47,31 +74,37 @@ int ossl_prov_seeding_from_dispatch(const OSSL_DISPATCH *fns) size_t ossl_prov_get_entropy(PROV_CTX *prov_ctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { - if (c_get_entropy == NULL) - return 0; - return c_get_entropy(ossl_prov_ctx_get0_handle(prov_ctx), - pout, entropy, min_len, max_len); + const OSSL_CORE_HANDLE *handle = CORE_HANDLE(prov_ctx); + + if (c_get_user_entropy != NULL) + return c_get_user_entropy(handle, pout, entropy, min_len, max_len); + if (c_get_entropy != NULL) + return c_get_entropy(handle, pout, entropy, min_len, max_len); + return 0; } void ossl_prov_cleanup_entropy(PROV_CTX *prov_ctx, unsigned char *buf, size_t len) { if (c_cleanup_entropy != NULL) - c_cleanup_entropy(ossl_prov_ctx_get0_handle(prov_ctx), buf, len); + c_cleanup_entropy(CORE_HANDLE(prov_ctx), buf, len); } size_t ossl_prov_get_nonce(PROV_CTX *prov_ctx, unsigned char **pout, size_t min_len, size_t max_len, const void *salt,size_t salt_len) { - if (c_get_nonce == NULL) - return 0; - return c_get_nonce(ossl_prov_ctx_get0_handle(prov_ctx), pout, - min_len, max_len, salt, salt_len); + const OSSL_CORE_HANDLE *handle = CORE_HANDLE(prov_ctx); + + if (c_get_user_nonce != NULL) + return c_get_user_nonce(handle, pout, min_len, max_len, salt, salt_len); + if (c_get_nonce != NULL) + return c_get_nonce(handle, pout, min_len, max_len, salt, salt_len); + return 0; } void ossl_prov_cleanup_nonce(PROV_CTX *prov_ctx, unsigned char *buf, size_t len) { if (c_cleanup_nonce != NULL) - c_cleanup_nonce(ossl_prov_ctx_get0_handle(prov_ctx), buf, len); + c_cleanup_nonce(CORE_HANDLE(prov_ctx), buf, len); } |