summaryrefslogtreecommitdiffstats
path: root/providers
diff options
context:
space:
mode:
authorPauli <pauli@openssl.org>2023-09-05 12:51:05 +1000
committerPauli <pauli@openssl.org>2023-10-03 18:54:03 +1100
commit354053395fbd20e5efb584427b5da9be9231fd93 (patch)
tree609231a9dae7843a58166d8bf2b3cbc953af2b39 /providers
parentbc347a35d025b989abfeb8ef556f895cb1ee9381 (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.c8
-rw-r--r--providers/common/provider_seeding.c53
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);
}