diff --git a/IDE/WINVS/unit-test/unit-test.vcxproj b/IDE/WINVS/unit-test/unit-test.vcxproj
index 0b7bf991..f94d6b84 100644
--- a/IDE/WINVS/unit-test/unit-test.vcxproj
+++ b/IDE/WINVS/unit-test/unit-test.vcxproj
@@ -31,6 +31,7 @@
+
diff --git a/src/wp_des.c b/src/wp_des.c
index be9f8d37..57c6ba12 100644
--- a/src/wp_des.c
+++ b/src/wp_des.c
@@ -914,32 +914,5 @@ IMPLEMENT_DES3_BLOCK_DISPATCH(lcmode, kBits, ivBits)
/** wp_des3cbc_functions_functions */
IMPLEMENT_DES3_BLOCK(cbc, CBC, 192, 64)
-#else /* defined(HAVE_FIPS) && !defined(WP_ALLOW_NON_FIPS */
-
-#define IMPLEMENT_DES3_BLOCK_NULL(mode) \
-const OSSL_DISPATCH wp_des3##mode##_functions[] = { \
- { OSSL_FUNC_CIPHER_NEWCTX, (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_FREECTX, (DFUNC)wp_des3_void }, \
- { OSSL_FUNC_CIPHER_DUPCTX, (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_DECRYPT_INIT, (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_UPDATE, (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_FINAL, (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_CIPHER, (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_GET_PARAMS, (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \
- (DFUNC)wp_des3_null }, \
- { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \
- (DFUNC)wp_des3_null }, \
- { 0, NULL } \
-};
-static int wp_des3_null(void) { return 0; }
-static void wp_des3_void(void) {}
-
-IMPLEMENT_DES3_BLOCK_NULL(cbc)
-
-#endif
+#endif /* !HAVE_FIPS || WP_ALLOW_NON_FIPS */
#endif /* WP_HAVE_DES3CBC */
diff --git a/src/wp_digests.c b/src/wp_digests.c
index fb027688..240fddba 100644
--- a/src/wp_digests.c
+++ b/src/wp_digests.c
@@ -231,22 +231,6 @@ const OSSL_DISPATCH name##_functions[] = { \
{ 0, NULL } \
};
-#define IMPLEMENT_DIGEST_NULL(name) \
-/** Dispatch table for digest_null algorithms. */ \
-static int name##_digest_null(void) { return 0; } \
-static void name##_digest_void(void) {} \
-const OSSL_DISPATCH name##_functions[] = { \
- { OSSL_FUNC_DIGEST_NEWCTX, (DFUNC)name##_digest_null }, \
- { OSSL_FUNC_DIGEST_INIT, (DFUNC)name##_digest_null }, \
- { OSSL_FUNC_DIGEST_UPDATE, (DFUNC)name##_digest_null }, \
- { OSSL_FUNC_DIGEST_FINAL, (DFUNC)name##_digest_null }, \
- { OSSL_FUNC_DIGEST_FREECTX, (DFUNC)name##_digest_void }, \
- { OSSL_FUNC_DIGEST_DUPCTX, (DFUNC)name##_digest_null }, \
- { OSSL_FUNC_DIGEST_GET_PARAMS, (DFUNC)name##_digest_null }, \
- { OSSL_FUNC_DIGEST_GETTABLE_PARAMS, (DFUNC)name##_digest_null }, \
- { 0, NULL } \
-};
-
/**
* Get parameters of a digest algorithm.
*
@@ -320,15 +304,13 @@ static const OSSL_PARAM* wp_digest_gettable_params(void* provCtx)
******************************************************************************/
#ifdef WP_HAVE_MD5
-#if defined(HAVE_FIPS) && !defined(WP_ALLOW_NON_FIPS)
-IMPLEMENT_DIGEST_NULL(wp_md5)
-#else
+#if !defined(HAVE_FIPS) || defined(WP_ALLOW_NON_FIPS)
IMPLEMENT_DIGEST(wp_md5, wc_Md5,
WC_MD5_BLOCK_SIZE, WC_MD5_DIGEST_SIZE,
0,
wc_InitMd5_ex, wc_Md5Update, wc_Md5Final,
wc_Md5Copy, wc_Md5Free)
-#endif
+#endif /* !HAVE_FIPS || WP_ALLOW_NON_FIPS */
#endif
/*******************************************************************************
@@ -472,9 +454,7 @@ IMPLEMENT_DIGEST(wp_md5_sha1, wp_Md5Sha,
0,
wp_InitMd5Sha_ex, wp_Md5ShaUpdate, wp_Md5ShaFinal,
wp_Md5ShaCopy, wp_Md5ShaFree)
-#else /* defined(HAVE_FIPS) && !defined(WP_ALLOW_NON_FIPS) */
-IMPLEMENT_DIGEST_NULL(wp_md5_sha1)
-#endif
+#endif /* !HAVE_FIPS || WP_ALLOW_NON_FIPS */
#endif
/*******************************************************************************
diff --git a/src/wp_wolfprov.c b/src/wp_wolfprov.c
index 69446838..25460640 100644
--- a/src/wp_wolfprov.c
+++ b/src/wp_wolfprov.c
@@ -404,16 +404,18 @@ static int wolfprov_get_params(void* provCtx, OSSL_PARAM params[])
/* List of digest algorithm implementations available in wolfSSL provider. */
static const OSSL_ALGORITHM wolfprov_digests[] = {
-#ifdef WP_HAVE_MD5
+#if defined(WP_HAVE_MD5) && \
+ (!defined(HAVE_FIPS) || defined(WP_ALLOW_NON_FIPS))
/* MD5 */
{ WP_NAMES_MD5, WOLFPROV_PROPERTIES, wp_md5_functions,
"" },
-#endif
-#ifdef WP_HAVE_MD5_SHA1
+#endif /* WP_HAVE_MD5 && (!HAVE_FIPS || WP_ALLOW_NON_FIPS) */
+#if defined(WP_HAVE_MD5_SHA1) && \
+ (!defined(HAVE_FIPS) || defined(WP_ALLOW_NON_FIPS))
/* MD5-SHA1 */
{ WP_NAMES_MD5_SHA1, WOLFPROV_PROPERTIES, wp_md5_sha1_functions,
"" },
-#endif
+#endif /* WP_HAVE_MD5_SHA1 && (!HAVE_FIPS || WP_ALLOW_NON_FIPS) */
#ifdef WP_HAVE_SHA1
/* SHA-1 */
{ WP_NAMES_SHA1, WOLFPROV_PROPERTIES, wp_sha1_functions,
@@ -551,10 +553,11 @@ static const OSSL_ALGORITHM wolfprov_ciphers[] = {
"" },
#endif
-#ifdef WP_HAVE_DES3CBC
+#if defined(WP_HAVE_DES3CBC) && \
+ (!defined(HAVE_FIPS) || defined(WP_ALLOW_NON_FIPS))
{ WP_NAMES_DES_EDE3_CBC, WOLFPROV_PROPERTIES, wp_des3cbc_functions,
"" },
-#endif
+#endif /* WP_HAVE_DES3CBC && (!HAVE_FIPS || WP_ALLOW_NON_FIPS) */
{ NULL, NULL, NULL, NULL }
};
diff --git a/test/include.am b/test/include.am
index cab0700f..47d268e5 100644
--- a/test/include.am
+++ b/test/include.am
@@ -21,6 +21,7 @@ test_unit_test_SOURCES = \
test/test_rand_seed.c \
test/test_ecc.c \
test/test_ecx.c \
+ test/test_fetch.c \
test/test_gmac.c \
test/test_krb5kdf.c \
test/test_sshkdf.c \
diff --git a/test/test_fetch.c b/test/test_fetch.c
new file mode 100644
index 00000000..fb64edc0
--- /dev/null
+++ b/test/test_fetch.c
@@ -0,0 +1,89 @@
+/* test_fetch.c
+ *
+ * Copyright (C) 2006-2026 wolfSSL Inc.
+ *
+ * This file is part of wolfProvider.
+ *
+ * wolfProvider is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * wolfProvider is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with wolfProvider. If not, see .
+ */
+
+#include "unit.h"
+
+static int test_fetch_alg(int op, const char *name)
+{
+ int ok = 0;
+
+ if (op == OSSL_OP_DIGEST) {
+ EVP_MD *md = EVP_MD_fetch(wpLibCtx, name, "provider=wolfprov");
+ ok = (md != NULL);
+ EVP_MD_free(md);
+ }
+ else {
+ EVP_CIPHER *cipher = EVP_CIPHER_fetch(wpLibCtx, name,
+ "provider=wolfprov");
+ ok = (cipher != NULL);
+ EVP_CIPHER_free(cipher);
+ }
+
+ return ok;
+}
+
+/* Every registered digest and cipher must be fetchable through OpenSSL. */
+int test_fetch_registered(void *data)
+{
+ static const int ops[] = { OSSL_OP_DIGEST, OSSL_OP_CIPHER };
+ int err = 0;
+ size_t i;
+
+ (void)data;
+
+ PRINT_MSG("Testing fetch of every registered digest and cipher");
+
+ for (i = 0; (err == 0) && (i < sizeof(ops) / sizeof(ops[0])); i++) {
+ const OSSL_ALGORITHM *algs;
+ const OSSL_ALGORITHM *alg;
+ int noCache = 0;
+
+ algs = OSSL_PROVIDER_query_operation(wpProv, ops[i], &noCache);
+ if (algs == NULL) {
+ PRINT_ERR_MSG("No algorithms for operation %d", ops[i]);
+ err = 1;
+ }
+ for (alg = algs; (err == 0) && (alg->algorithm_names != NULL);
+ alg++) {
+ char name[64];
+ size_t len = strcspn(alg->algorithm_names, ":");
+
+ if (len >= sizeof(name)) {
+ PRINT_ERR_MSG("Algorithm name too long: %s",
+ alg->algorithm_names);
+ err = 1;
+ }
+ else {
+ memcpy(name, alg->algorithm_names, len);
+ name[len] = '\0';
+ if (!test_fetch_alg(ops[i], name)) {
+ PRINT_ERR_MSG("Failed to fetch registered algorithm: %s",
+ name);
+ err = 1;
+ }
+ }
+ }
+ if (algs != NULL) {
+ OSSL_PROVIDER_unquery_operation(wpProv, ops[i], algs);
+ }
+ }
+
+ return err;
+}
diff --git a/test/unit.c b/test/unit.c
index be7f72a2..249ffe44 100644
--- a/test/unit.c
+++ b/test/unit.c
@@ -182,6 +182,7 @@ static unsigned long flags = 0;
TEST_CASE test_case[] = {
TEST_DECL(test_logging, &debug),
TEST_DECL(test_ct_masks, NULL),
+ TEST_DECL(test_fetch_registered, NULL),
#ifdef WP_HAVE_SHA1
TEST_DECL(test_sha, NULL),
#endif
diff --git a/test/unit.h b/test/unit.h
index 35bc245b..e8acd949 100644
--- a/test/unit.h
+++ b/test/unit.h
@@ -117,6 +117,7 @@ typedef struct TEST_CASE {
int test_logging(void *data);
int test_ct_masks(void *data);
+int test_fetch_registered(void *data);
#define WP_VALGRIND_TEST 0x1