diff --git a/.gitignore b/.gitignore
index b38f19ce..f24529d1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,7 +23,6 @@
/include/config.h.in
/include/config.h
/include/config.h.in~
-/include/wolfprovider/version.h
/config.status
/include.am
/libtool
@@ -100,6 +99,18 @@ IDE/Android/wolfssl-source/
IDE/Android/wolfssl-install/
IDE/Android/wolfProvider/
+# Visual Studio build output. The configuration names appear both under
+# IDE/WINVS/ (artifacts) and under each project directory (intermediates).
+IDE/WINVS/**/DLL Release/
+IDE/WINVS/**/DLL Debug/
+IDE/WINVS/**/Static Release/
+IDE/WINVS/**/Static Debug/
+IDE/WINVS/*.VC.db
+IDE/WINVS/*.VC.opendb
+IDE/WINVS/.vs/
+IDE/WINVS/**/*.user
+IDE/WINVS/**/*.vcxproj.filters
+
examples/openssl_example
cscope.out
@@ -108,6 +119,7 @@ tags
# Debian build files
libwolfprov*.tar.gz
+wolfprov-*.tar.gz
debian/tmp
debian/*.dch
debian/autoreconf*
diff --git a/IDE/WINVS/README.md b/IDE/WINVS/README.md
new file mode 100644
index 00000000..68d42656
--- /dev/null
+++ b/IDE/WINVS/README.md
@@ -0,0 +1,153 @@
+Visual Studio solution for wolfProvider
+=======================================
+
+`wolfprovider.sln` builds **`libwolfprov.dll`**, an OpenSSL 3.x provider backed
+by wolfSSL. The filename matters: `-provider libwolfprov` resolves to
+`libwolfprov.dll`.
+
+Four configurations, x64 only:
+
+| Configuration | Purpose |
+|---|---|
+| `DLL Release\|x64` | the shipped provider |
+| `DLL Debug\|x64` | same, debug CRT |
+| `Static Release\|x64` | builds `unit-test.exe`. Not for distribution. |
+| `Static Debug\|x64` | same, debug CRT |
+
+The static library exists only so the unit tests can link wolfProvider
+internals. A `.lib` cannot act as a provider: OpenSSL loads one with
+`LoadLibraryA` followed by a lookup of `OSSL_provider_init`.
+
+
+Prerequisites
+-------------
+
+- Visual Studio 2022 with the C++ toolset (v143) and MASM (`ml64.exe`).
+- Perl, NASM and git, to build OpenSSL. Strawberry Perl includes NASM.
+
+No `configure` step is involved anywhere on Windows.
+
+
+Directory layout
+----------------
+
+wolfProvider, wolfSSL and OpenSSL sit side by side:
+
+ C:\src\
+ openssl\
+ wolfProvider\
+ wolfssl\
+
+`wolfprovider.props` expresses this as `..\..\..\..\wolfssl` and
+`..\..\..\..\openssl`, relative to each project directory. Override any macro on
+the command line, e.g. `/p:wolfCryptDir=D:\wolfssl`.
+
+
+Building
+--------
+
+**1. OpenSSL**, shared, release CRT:
+
+ cd C:\src\openssl
+ perl Configure VC-WIN64A shared no-tests --prefix=C:\out\openssl --openssldir=C:\out\openssl\ssl
+ nmake
+ nmake install_sw
+
+Two paths come out of this and they are not interchangeable. The **build tree**
+(`C:\src\openssl`) is `openSslDir` and must hold `libcrypto.lib` directly. The
+**install prefix** (`C:\out\openssl`) is what you run. Pointing `openSslDir` at
+the prefix fails later with `LNK1104`.
+
+For a Debug wolfProvider, build a second OpenSSL with `--debug` into
+`C:\src\openssl-debug`. `Configure` writes into the source tree, so release and
+debug cannot share one checkout.
+
+**2. wolfSSL**, as a DLL, using the `user_settings.h` in this directory:
+
+ copy IDE\WINVS\user_settings.h C:\src\wolfssl\IDE\WIN\user_settings.h
+ cd C:\src\wolfssl
+ msbuild wolfssl64.sln /t:wolfssl /p:Configuration="DLL Release" /p:Platform=x64
+
+**3. wolfProvider**:
+
+ cd C:\src\wolfProvider
+ msbuild IDE\WINVS\wolfprovider.sln /p:Configuration="DLL Release" /p:Platform=x64
+
+Output is `IDE\WINVS\DLL Release\x64\libwolfprov.dll`.
+
+The Debug configurations link `/MDd` and need a `/MDd` OpenSSL and wolfSSL
+`DLL Debug|x64`. Never mix runtimes: `/MD` against `/MDd` links cleanly and then
+corrupts the heap.
+
+
+Running
+-------
+
+`libwolfprov.dll` imports `wolfssl.dll`, and the process that searches for it is
+the application loading the provider. OpenSSL uses a bare `LoadLibraryA`, which
+does not add the module's own directory to the search path, so **putting
+`wolfssl.dll` beside `libwolfprov.dll` does not work.** Put it on the loading
+process's `PATH`:
+
+ $env:PATH = "C:\src\wolfssl\DLL Release\x64;$env:PATH"
+ openssl list -providers -provider-path "C:\src\wolfProvider\IDE\WINVS\DLL Release\x64" -provider libwolfprov
+
+
+User macros
+-----------
+
+Set in `wolfprovider.props`, overridable with `/p:`:
+
+| Macro | Default |
+|---|---|
+| `wolfCryptDir` | `..\..\..\..\wolfssl` |
+| `openSslDir` | `..\..\..\..\openssl` (build tree, holds `libcrypto.lib`) |
+| `openSslDirDebug` | `..\..\..\..\openssl-debug` |
+| `userSettingsDir` | `..` (this directory) |
+| `wolfSslLib` | `wolfssl.lib` |
+
+plus `wolfCryptDllRelease64` and friends for the wolfSSL output directories.
+
+
+FIPS
+----
+
+A FIPS build is wolfSSL's standard Windows FIPS procedure, then wolfProvider
+pointed at the bundle. wolfSSL is linked **shared**, including FIPS; the module
+passes its in-core integrity check that way.
+
+ msbuild IDE\WINVS\wolfprovider.sln /p:Configuration="DLL Release" /p:Platform=x64 ^
+ /p:wolfCryptDir="C:\src\wolfssl-fips" ^
+ /p:userSettingsDir="C:\src\wolfssl-fips\IDE\WIN10" ^
+ /p:wolfCryptDllRelease64="C:\src\wolfssl-fips\IDE\WIN10\DLL Release\x64" ^
+ /p:wolfSslLib=wolfssl-fips.lib
+
+wolfSSL and wolfProvider must compile against the **same** `user_settings.h`, so
+`userSettingsDir` points at the bundle's copy. A layout-changing macro going
+asymmetric between the two builds is silent and fatal.
+
+
+Unit tests
+----------
+
+Build `Static Release|x64` and run `IDE\WINVS\Static Release\x64\unit-test.exe`
+with the wolfSSL and OpenSSL DLL directories on `PATH`. `WP_UNIT_STATIC_PROVIDER`
+is defined in the Static configurations only, so the test registers the linked-in
+provider instead of loading the DLL; defining it elsewhere would put two copies
+of wolfProvider in one process.
+
+Building `unit-test.vcxproj` in a DLL configuration fails at link with ten
+unresolved externals. That is correct: the DLL exports one symbol and the tests
+reach internals. Do not widen `wolfprovider.def` to fix it.
+
+
+Known limitations
+-----------------
+
+- `USE_INTEL_SPEEDUP` is unavailable: wolfSSL ships 15 x86-64 features as GAS
+ `.S` but only 6 as MASM `.asm`. AES-NI and the SP big-integer paths are still
+ enabled.
+- SEED-SRC is not supported on Windows.
+- A `WOLFPROV_DEBUG` unit-test build does not compile; `test_logging.c` uses
+ `setenv()`.
+- No automated Windows CI yet.
diff --git a/IDE/WINVS/include.am b/IDE/WINVS/include.am
new file mode 100644
index 00000000..5c7ae370
--- /dev/null
+++ b/IDE/WINVS/include.am
@@ -0,0 +1,11 @@
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+EXTRA_DIST+= IDE/WINVS/README.md
+EXTRA_DIST+= IDE/WINVS/user_settings.h
+EXTRA_DIST+= IDE/WINVS/wolfprovider.sln
+EXTRA_DIST+= IDE/WINVS/wolfprovider.props
+EXTRA_DIST+= IDE/WINVS/wolfprovider/wolfprovider.vcxproj
+EXTRA_DIST+= IDE/WINVS/wolfprovider/wolfprovider.def
+EXTRA_DIST+= IDE/WINVS/unit-test/unit-test.vcxproj
diff --git a/IDE/WINVS/unit-test/unit-test.vcxproj b/IDE/WINVS/unit-test/unit-test.vcxproj
new file mode 100644
index 00000000..0b7bf991
--- /dev/null
+++ b/IDE/WINVS/unit-test/unit-test.vcxproj
@@ -0,0 +1,231 @@
+
+
+
+
+
+ DLL Debug
+ x64
+
+
+ DLL Release
+ x64
+
+
+ Static Debug
+ x64
+
+
+ Static Release
+ x64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {9b1f3c0a-6d48-4e27-8a55-c3e7d2140f6b}
+
+
+
+ {2E5D8B47-91FA-4C63-B0D2-6F14A3C97E85}
+ Win32Proj
+ unittest
+ 10.0
+
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ Unicode
+
+
+ Application
+ true
+ v143
+ Unicode
+
+
+ Application
+ false
+ v143
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ $(Configuration)\$(Platform)\$(ProjectName)_obj\
+ false
+
+
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ $(Configuration)\$(Platform)\$(ProjectName)_obj\
+ false
+
+
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ $(Configuration)\$(Platform)\$(ProjectName)_obj\
+ false
+
+
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ $(Configuration)\$(Platform)\$(ProjectName)_obj\
+ false
+
+
+
+
+
+ Level3
+
+
+ Disabled
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ stdc11
+ CERTS_DIR="$([System.String]::Copy('$(MSBuildThisFileDirectory)').Replace('\','/'))../../../certs";WOLFSSL_USER_SETTINGS;WOLFSSL_DLL;WIN32;_CONSOLE;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ $(userSettingsDir);..;..\..\..\include;..\..\..\test;$(wolfCryptDir);$(openSslDirDebug)\include;%(AdditionalIncludeDirectories)
+ ProgramDatabase
+
+
+ Console
+ true
+ libssl.lib;libcrypto.lib;$(wolfSslLib);ws2_32.lib;advapi32.lib;crypt32.lib;%(AdditionalDependencies)
+ $(openSslDirDebug);$(wolfCryptDllDebug64);%(AdditionalLibraryDirectories)
+ /IGNORE:4221 %(AdditionalOptions)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ MultiThreadedDLL
+ stdc11
+ CERTS_DIR="$([System.String]::Copy('$(MSBuildThisFileDirectory)').Replace('\','/'))../../../certs";WOLFSSL_USER_SETTINGS;WOLFSSL_DLL;WIN32;_CONSOLE;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ $(userSettingsDir);..;..\..\..\include;..\..\..\test;$(wolfCryptDir);$(openSslDir)\include;%(AdditionalIncludeDirectories)
+ ProgramDatabase
+
+
+ Console
+ true
+ true
+ true
+ libssl.lib;libcrypto.lib;$(wolfSslLib);ws2_32.lib;advapi32.lib;crypt32.lib;%(AdditionalDependencies)
+ $(openSslDir);$(wolfCryptDllRelease64);%(AdditionalLibraryDirectories)
+ /IGNORE:4221 %(AdditionalOptions)
+
+
+
+
+ Level3
+
+
+ Disabled
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ stdc11
+ CERTS_DIR="$([System.String]::Copy('$(MSBuildThisFileDirectory)').Replace('\','/'))../../../certs";WP_UNIT_STATIC_PROVIDER;WOLFSSL_USER_SETTINGS;WOLFSSL_DLL;WIN32;_CONSOLE;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ $(userSettingsDir);..;..\..\..\include;..\..\..\test;$(wolfCryptDir);$(openSslDirDebug)\include;%(AdditionalIncludeDirectories)
+ ProgramDatabase
+
+
+ Console
+ true
+ libssl.lib;libcrypto.lib;$(wolfSslLib);ws2_32.lib;advapi32.lib;crypt32.lib;%(AdditionalDependencies)
+ $(openSslDirDebug);$(wolfCryptDllDebug64);%(AdditionalLibraryDirectories)
+ /IGNORE:4221 %(AdditionalOptions)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ MultiThreadedDLL
+ stdc11
+ CERTS_DIR="$([System.String]::Copy('$(MSBuildThisFileDirectory)').Replace('\','/'))../../../certs";WP_UNIT_STATIC_PROVIDER;WOLFSSL_USER_SETTINGS;WOLFSSL_DLL;WIN32;_CONSOLE;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ $(userSettingsDir);..;..\..\..\include;..\..\..\test;$(wolfCryptDir);$(openSslDir)\include;%(AdditionalIncludeDirectories)
+ ProgramDatabase
+
+
+ Console
+ true
+ true
+ true
+ libssl.lib;libcrypto.lib;$(wolfSslLib);ws2_32.lib;advapi32.lib;crypt32.lib;%(AdditionalDependencies)
+ $(openSslDir);$(wolfCryptDllRelease64);%(AdditionalLibraryDirectories)
+ /IGNORE:4221 %(AdditionalOptions)
+
+
+
+
+
+
diff --git a/IDE/WINVS/user_settings.h b/IDE/WINVS/user_settings.h
new file mode 100644
index 00000000..78d0b40d
--- /dev/null
+++ b/IDE/WINVS/user_settings.h
@@ -0,0 +1,606 @@
+/* user_settings.h
+ *
+ * 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 .
+ */
+
+/* wolfSSL configuration for wolfProvider on Windows / Visual Studio, x64.
+ * wolfSSL and wolfProvider must both be built against this same file; a
+ * divergent copy is an ABI mismatch, not a build error. */
+
+#ifndef _WIN_USER_SETTINGS_H_
+#define _WIN_USER_SETTINGS_H_
+
+/* Verify this is Windows */
+#ifndef _WIN32
+#error This user_settings.h header is only designed for Windows
+#endif
+
+/* Deliberately absent: HAVE___UINT128_T, HAVE_GETPID, HAVE_C___ATOMIC and
+ * WOLFSSL_HAVE_ATOMIC_H are autotools probe results that are wrong under MSVC
+ * and change struct WC_RNG and the atomic int type. Do not restore them. */
+
+#undef HAVE_LIMITS_H
+#define HAVE_LIMITS_H 1
+
+#undef WOLFSSL_HAVE_ASSERT_H
+#define WOLFSSL_HAVE_ASSERT_H
+
+#undef WOLFSSL_WOLFSSH
+#define WOLFSSL_WOLFSSH
+
+#undef HAVE_THREAD_LS
+#define HAVE_THREAD_LS
+
+#undef NO_DO178
+#define NO_DO178
+
+/* Also selects SP_INT_BITS 8192; without it FFDHE-8192 breaks at run time. */
+
+#undef WOLFSSL_X86_64_BUILD
+#define WOLFSSL_X86_64_BUILD
+
+/* --- Algorithm and feature enables ---------------------------------------- */
+
+#undef WOLFSSL_ASN_TEMPLATE
+#define WOLFSSL_ASN_TEMPLATE
+
+#undef HAVE_ECC_CDH
+#define HAVE_ECC_CDH
+
+#undef HAVE_ECC_KOBLITZ
+#define HAVE_ECC_KOBLITZ
+
+#undef HAVE_ECC_SECPR2
+#define HAVE_ECC_SECPR2
+
+#undef HAVE_ECC_SECPR3
+#define HAVE_ECC_SECPR3
+
+#undef WOLFSSL_DES_ECB
+#define WOLFSSL_DES_ECB
+
+#undef HAVE_AES_DECRYPT
+#define HAVE_AES_DECRYPT
+
+#undef HAVE_AES_ECB
+#define HAVE_AES_ECB
+
+#undef WOLFSSL_ALT_NAMES
+#define WOLFSSL_ALT_NAMES
+
+#undef HAVE_FFDHE_2048
+#define HAVE_FFDHE_2048
+
+#undef HAVE_FFDHE_3072
+#define HAVE_FFDHE_3072
+
+#undef WOLFSSL_ASN_ALL
+#define WOLFSSL_ASN_ALL
+
+#undef WOLFSSL_DH_EXTRA
+#define WOLFSSL_DH_EXTRA
+
+#undef WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT
+#define WOLFSSL_ECDSA_DETERMINISTIC_K_VARIANT
+
+#undef WOLFSSL_HAVE_ISSUER_NAMES
+#define WOLFSSL_HAVE_ISSUER_NAMES
+
+#undef WC_KDF_NIST_SP_800_56C
+#define WC_KDF_NIST_SP_800_56C
+
+#undef WC_RNG_BANK_SUPPORT
+#define WC_RNG_BANK_SUPPORT
+
+#undef NO_OLD_WC_NAMES
+#define NO_OLD_WC_NAMES
+
+#undef NO_OLD_SSL_NAMES
+#define NO_OLD_SSL_NAMES
+
+#undef NO_OLD_SHA_NAMES
+#define NO_OLD_SHA_NAMES
+
+#undef NO_OLD_MD5_NAME
+#define NO_OLD_MD5_NAME
+
+#undef OPENSSL_COEXIST
+#define OPENSSL_COEXIST
+
+/* --- Side-channel hardening and threading --------------------------------- */
+
+#undef ERROR_QUEUE_PER_THREAD
+#define ERROR_QUEUE_PER_THREAD
+
+#undef TFM_TIMING_RESISTANT
+#define TFM_TIMING_RESISTANT
+
+#undef ECC_TIMING_RESISTANT
+#define ECC_TIMING_RESISTANT
+
+#undef WC_RSA_BLINDING
+#define WC_RSA_BLINDING
+
+#undef ATOMIC_USER
+#define ATOMIC_USER
+
+#undef HAVE_PK_CALLBACKS
+#define HAVE_PK_CALLBACKS
+
+#undef HAVE_AES_ECB
+#define HAVE_AES_ECB
+
+#undef WOLFSSL_AES_CBC_LENGTH_CHECKS
+#define WOLFSSL_AES_CBC_LENGTH_CHECKS
+
+#undef HAVE_AESCCM
+#define HAVE_AESCCM
+
+#undef WOLFSSL_AES_EAX
+#define WOLFSSL_AES_EAX
+
+#undef WOLFSSL_AES_OFB
+#define WOLFSSL_AES_OFB
+
+#undef WOLFSSL_AES_DIRECT
+#define WOLFSSL_AES_DIRECT
+
+#undef WOLFSSL_AES_CFB
+#define WOLFSSL_AES_CFB
+
+#undef WOLFSSL_ARMASM_NO_HW_CRYPTO
+#define WOLFSSL_ARMASM_NO_HW_CRYPTO
+
+/* USE_INTEL_SPEEDUP is omitted: MASM coverage is a subset of GAS coverage, so
+ * the AVX2 paths do not link. */
+
+#undef WOLFSSL_AESNI
+#define WOLFSSL_AESNI
+
+#undef WOLFSSL_USE_ALIGN
+#define WOLFSSL_USE_ALIGN
+
+/* --- Ciphers and digests -------------------------------------------------- */
+
+#undef HAVE_CAMELLIA
+#define HAVE_CAMELLIA
+
+#undef WOLFSSL_MD2
+#define WOLFSSL_MD2
+
+#undef HAVE_NULL_CIPHER
+#define HAVE_NULL_CIPHER
+
+#undef WOLFSSL_RIPEMD
+#define WOLFSSL_RIPEMD
+
+#undef HAVE_BLAKE2B
+#define HAVE_BLAKE2B
+
+#undef HAVE_BLAKE2S
+#define HAVE_BLAKE2S
+
+#undef WOLFSSL_SHA224
+#define WOLFSSL_SHA224
+
+#undef WOLFSSL_SHA512
+#define WOLFSSL_SHA512
+
+#undef WOLFSSL_SHA384
+#define WOLFSSL_SHA384
+
+#undef SESSION_CERTS
+#define SESSION_CERTS
+
+#undef WOLFSSL_SEP
+#define WOLFSSL_SEP
+
+#undef KEEP_PEER_CERT
+#define KEEP_PEER_CERT
+
+#undef HAVE_HKDF
+#define HAVE_HKDF
+
+#undef HAVE_X963_KDF
+#define HAVE_X963_KDF
+
+/* --- ECC ------------------------------------------------------------------ */
+
+#undef HAVE_ECC
+#define HAVE_ECC
+
+#undef ECC_SHAMIR
+#define ECC_SHAMIR
+
+#undef ECC_MIN_KEY_SZ
+#define ECC_MIN_KEY_SZ 192
+
+#undef HAVE_ECC_BRAINPOOL
+#define HAVE_ECC_BRAINPOOL
+
+#undef FP_ECC
+#define FP_ECC
+
+#undef HAVE_ECC_ENCRYPT
+#define HAVE_ECC_ENCRYPT
+
+#undef WOLFCRYPT_HAVE_ECCSI
+#define WOLFCRYPT_HAVE_ECCSI
+
+#undef WOLFSSL_PUBLIC_MP
+#define WOLFSSL_PUBLIC_MP
+
+#undef WOLFCRYPT_HAVE_SAKKE
+#define WOLFCRYPT_HAVE_SAKKE
+
+/* --- RSA, encodings, MACs ------------------------------------------------- */
+
+#undef NO_OLD_TLS
+#define NO_OLD_TLS
+
+#undef WC_RSA_PSS
+#define WC_RSA_PSS
+
+#undef WOLFSSL_PSS_LONG_SALT
+#define WOLFSSL_PSS_LONG_SALT
+
+#undef HAVE_ANON
+#define HAVE_ANON
+
+#undef WOLFSSL_ASN_PRINT
+#define WOLFSSL_ASN_PRINT
+
+#undef WOLFSSL_BASE64_ENCODE
+#define WOLFSSL_BASE64_ENCODE
+
+#undef WOLFSSL_BASE16
+#define WOLFSSL_BASE16
+
+#undef WOLFSSL_SIPHASH
+#define WOLFSSL_SIPHASH
+
+#undef HAVE_CMAC_KDF
+#define HAVE_CMAC_KDF
+
+#undef WOLFSSL_CMAC
+#define WOLFSSL_CMAC
+
+#undef WOLFSSL_AES_DIRECT
+#define WOLFSSL_AES_DIRECT
+
+#undef WOLFSSL_AES_XTS
+#define WOLFSSL_AES_XTS
+
+#undef WOLFSSL_AES_DIRECT
+#define WOLFSSL_AES_DIRECT
+
+#undef WOLFSSL_CUSTOM_CURVES
+#define WOLFSSL_CUSTOM_CURVES
+
+#undef HAVE_CURVE448
+#define HAVE_CURVE448
+
+#undef HAVE_ED448
+#define HAVE_ED448
+
+#undef WOLFSSL_ED448_STREAMING_VERIFY
+#define WOLFSSL_ED448_STREAMING_VERIFY
+
+#undef WC_SRTP_KDF
+#define WC_SRTP_KDF
+
+#undef HAVE_AES_ECB
+#define HAVE_AES_ECB
+
+#undef WOLFSSL_AES_DIRECT
+#define WOLFSSL_AES_DIRECT
+
+/* --- SHA-3, ML-KEM, ChaCha/Poly, DRBG ------------------------------------- */
+
+#undef WOLFSSL_SHA3
+#define WOLFSSL_SHA3
+
+#undef WOLFSSL_SHAKE128
+#define WOLFSSL_SHAKE128
+
+#undef WOLFSSL_SHAKE256
+#define WOLFSSL_SHAKE256
+
+#undef WOLFSSL_HAVE_MLKEM
+#define WOLFSSL_HAVE_MLKEM
+
+#undef WOLFSSL_TLS_NO_MLKEM_STANDALONE
+#define WOLFSSL_TLS_NO_MLKEM_STANDALONE
+
+#undef WOLFSSL_PQC_HYBRIDS
+#define WOLFSSL_PQC_HYBRIDS
+
+#undef HAVE_POLY1305
+#define HAVE_POLY1305
+
+#undef HAVE_CHACHA
+#define HAVE_CHACHA
+
+#undef HAVE_XCHACHA
+#define HAVE_XCHACHA
+
+#undef HAVE_HASHDRBG
+#define HAVE_HASHDRBG
+
+#undef WOLFSSL_DRBG_SHA512
+#define WOLFSSL_DRBG_SHA512
+
+/* --- TLS extensions, OCSP, CRL -------------------------------------------- */
+
+#undef HAVE_TLS_EXTENSIONS
+#define HAVE_TLS_EXTENSIONS
+
+#undef HAVE_CERTIFICATE_STATUS_REQUEST
+#define HAVE_CERTIFICATE_STATUS_REQUEST
+
+#undef HAVE_TLS_EXTENSIONS
+#define HAVE_TLS_EXTENSIONS
+
+#undef HAVE_CERTIFICATE_STATUS_REQUEST_V2
+#define HAVE_CERTIFICATE_STATUS_REQUEST_V2
+
+#undef HAVE_CRL
+#define HAVE_CRL
+
+#undef HAVE_TLS_EXTENSIONS
+#define HAVE_TLS_EXTENSIONS
+
+#undef HAVE_SNI
+#define HAVE_SNI
+
+#undef HAVE_TLS_EXTENSIONS
+#define HAVE_TLS_EXTENSIONS
+
+#undef HAVE_SUPPORTED_CURVES
+#define HAVE_SUPPORTED_CURVES
+
+#undef HAVE_FFDHE_2048
+#define HAVE_FFDHE_2048
+
+#undef HAVE_SUPPORTED_CURVES
+#define HAVE_SUPPORTED_CURVES
+
+#undef WOLFSSL_TLS13
+#define WOLFSSL_TLS13
+
+#undef HAVE_TLS_EXTENSIONS
+#define HAVE_TLS_EXTENSIONS
+
+#undef HAVE_EXTENDED_MASTER
+#define HAVE_EXTENDED_MASTER
+
+#undef HAVE_TLS_EXTENSIONS
+#define HAVE_TLS_EXTENSIONS
+
+#undef HAVE_SNI
+#define HAVE_SNI
+
+#undef HAVE_MAX_FRAGMENT
+#define HAVE_MAX_FRAGMENT
+
+#undef HAVE_TRUNCATED_HMAC
+#define HAVE_TRUNCATED_HMAC
+
+#undef HAVE_ALPN
+#define HAVE_ALPN
+
+#undef HAVE_TRUSTED_CA
+#define HAVE_TRUSTED_CA
+
+#undef HAVE_SUPPORTED_CURVES
+#define HAVE_SUPPORTED_CURVES
+
+#undef WOLFCRYPT_HAVE_SRP
+#define WOLFCRYPT_HAVE_SRP
+
+#undef ASN_BER_TO_DER
+#define ASN_BER_TO_DER
+
+#undef HAVE_ENCRYPT_THEN_MAC
+#define HAVE_ENCRYPT_THEN_MAC
+
+#undef WOLFSSL_ENCRYPTED_KEYS
+#define WOLFSSL_ENCRYPTED_KEYS
+
+#undef HAVE_SCRYPT
+#define HAVE_SCRYPT
+
+/* --- Single-precision (SP) math, x86-64 assembly -------------------------- */
+
+#undef WOLFSSL_HAVE_SP_RSA
+#define WOLFSSL_HAVE_SP_RSA
+
+#undef WOLFSSL_HAVE_SP_DH
+#define WOLFSSL_HAVE_SP_DH
+
+#undef WOLFSSL_SP_4096
+#define WOLFSSL_SP_4096
+
+#undef WOLFSSL_SP_LARGE_CODE
+#define WOLFSSL_SP_LARGE_CODE
+
+#undef WOLFSSL_HAVE_SP_ECC
+#define WOLFSSL_HAVE_SP_ECC
+
+#undef HAVE_ECC384
+#define HAVE_ECC384
+
+#undef WOLFSSL_SP_384
+#define WOLFSSL_SP_384
+
+#undef HAVE_ECC521
+#define HAVE_ECC521
+
+#undef WOLFSSL_SP_521
+#define WOLFSSL_SP_521
+
+#undef WOLFSSL_SP_1024
+#define WOLFSSL_SP_1024
+
+#undef WOLFSSL_SP_MATH_ALL
+#define WOLFSSL_SP_MATH_ALL
+
+#undef WOLFSSL_SP_X86_64
+#define WOLFSSL_SP_X86_64
+
+#undef WOLFSSL_SP_ASM
+#define WOLFSSL_SP_ASM
+
+#undef WOLFSSL_SP_X86_64_ASM
+#define WOLFSSL_SP_X86_64_ASM
+
+#undef WOLF_CRYPTO_CB
+#define WOLF_CRYPTO_CB
+
+#undef WC_NO_ASYNC_THREADING
+#define WC_NO_ASYNC_THREADING
+
+#undef HAVE_AES_KEYWRAP
+#define HAVE_AES_KEYWRAP
+
+#undef WOLFSSL_AES_DIRECT
+#define WOLFSSL_AES_DIRECT
+
+#undef WOLFSSL_HASH_FLAGS
+#define WOLFSSL_HASH_FLAGS
+
+#undef HAVE_DH_DEFAULT_PARAMS
+#define HAVE_DH_DEFAULT_PARAMS
+
+#undef RSA_MAX_SIZE
+#define RSA_MAX_SIZE 4096
+
+#undef MAX_ECC_BITS
+#define MAX_ECC_BITS 1024
+
+/* --- Certificate generation, key generation, misc ------------------------- */
+
+#undef HAVE_CURVE25519
+#define HAVE_CURVE25519
+
+#undef HAVE_ED25519
+#define HAVE_ED25519
+
+#undef WOLFSSL_SYS_CA_CERTS
+#define WOLFSSL_SYS_CA_CERTS
+
+#undef WOLFSSL_KEY_GEN
+#define WOLFSSL_KEY_GEN
+
+#undef WOLFSSL_CERT_REQ
+#define WOLFSSL_CERT_REQ
+
+#undef WOLFSSL_CERT_GEN
+#define WOLFSSL_CERT_GEN
+
+#undef WOLFSSL_CERT_EXT
+#define WOLFSSL_CERT_EXT
+
+#undef HAVE_OCSP
+#define HAVE_OCSP
+
+#undef HAVE_OPENSSL_CMD
+#define HAVE_OPENSSL_CMD
+
+#undef WOLFSSL_ED25519_STREAMING_VERIFY
+#define WOLFSSL_ED25519_STREAMING_VERIFY
+
+#undef WOLFSSL_AES_SIV
+#define WOLFSSL_AES_SIV
+
+#undef WOLFSSL_AES_COUNTER
+#define WOLFSSL_AES_COUNTER
+
+#undef WOLFSSL_AES_DIRECT
+#define WOLFSSL_AES_DIRECT
+
+#undef HAVE_PKCS7
+#define HAVE_PKCS7
+
+#undef NO_DES3_TLS_SUITES
+#define NO_DES3_TLS_SUITES
+
+#undef GCM_TABLE_4BIT
+#define GCM_TABLE_4BIT
+
+#undef HAVE_AESGCM
+#define HAVE_AESGCM
+
+#undef WOLFSSL_AESGCM_STREAM
+#define WOLFSSL_AESGCM_STREAM
+
+#undef WOLFSSL_AESXTS_STREAM
+#define WOLFSSL_AESXTS_STREAM
+
+#undef WOLFSSL_PUBLIC_MP
+#define WOLFSSL_PUBLIC_MP
+
+#undef HAVE_TLS_EXTENSIONS
+#define HAVE_TLS_EXTENSIONS
+
+#undef HAVE_SERVER_RENEGOTIATION_INFO
+#define HAVE_SERVER_RENEGOTIATION_INFO
+
+#undef HAVE_COMP_KEY
+#define HAVE_COMP_KEY
+
+#undef WOLFSSL_ALLOW_RC4
+#define WOLFSSL_ALLOW_RC4
+
+#undef WOLFSSL_TLS_OCSP_MULTI
+#define WOLFSSL_TLS_OCSP_MULTI
+
+#undef HAVE_WC_INTROSPECTION
+#define HAVE_WC_INTROSPECTION
+
+#undef WC_RSA_NO_PADDING
+#define WC_RSA_NO_PADDING
+
+#undef WOLFSSL_PUBLIC_MP
+#define WOLFSSL_PUBLIC_MP
+
+#undef HAVE_PUBLIC_FFDHE
+#define HAVE_PUBLIC_FFDHE
+
+#undef HAVE_FFDHE_6144
+#define HAVE_FFDHE_6144
+
+#undef HAVE_FFDHE_8192
+#define HAVE_FFDHE_8192
+
+#undef WOLFSSL_PSS_LONG_SALT
+#define WOLFSSL_PSS_LONG_SALT
+
+#undef WOLFSSL_PSS_SALT_LEN_DISCOVER
+#define WOLFSSL_PSS_SALT_LEN_DISCOVER
+
+#undef RSA_MIN_SIZE
+#define RSA_MIN_SIZE 1024
+
+#undef WOLFSSL_OLD_OID_SUM
+#define WOLFSSL_OLD_OID_SUM
+
+#undef WC_RNG_SEED_CB
+#define WC_RNG_SEED_CB
+
+#endif /* _WIN_USER_SETTINGS_H_ */
diff --git a/IDE/WINVS/wolfprovider.props b/IDE/WINVS/wolfprovider.props
new file mode 100644
index 00000000..eee708c7
--- /dev/null
+++ b/IDE/WINVS/wolfprovider.props
@@ -0,0 +1,67 @@
+
+
+
+
+
+ ..
+ wolfssl.lib
+ ..\..\..\..\wolfssl
+ ..\..\..\..\openssl
+
+ ..\..\..\..\openssl-debug
+ $(wolfCryptDir)\Debug\Win32
+ $(wolfCryptDir)\Release\Win32
+ $(wolfCryptDir)\Debug\x64
+ $(wolfCryptDir)\Release\x64
+ $(wolfCryptDir)\DLL Debug\Win32
+ $(wolfCryptDir)\DLL Release\Win32
+ $(wolfCryptDir)\DLL Debug\x64
+ $(wolfCryptDir)\DLL Release\x64
+
+
+
+
+ $(userSettingsDir)
+
+
+ $(wolfSslLib)
+
+
+ $(wolfCryptDir)
+
+
+ $(openSslDir)
+
+
+ $(openSslDirDebug)
+
+
+ $(wolfCryptDebug32)
+
+
+ $(wolfCryptRelease32)
+
+
+ $(wolfCryptDebug64)
+
+
+ $(wolfCryptRelease64)
+
+
+ $(wolfCryptDllDebug32)
+
+
+ $(wolfCryptDllRelease32)
+
+
+ $(wolfCryptDllDebug64)
+
+
+ $(wolfCryptDllRelease64)
+
+
+
diff --git a/IDE/WINVS/wolfprovider.sln b/IDE/WINVS/wolfprovider.sln
new file mode 100644
index 00000000..8ed188d4
--- /dev/null
+++ b/IDE/WINVS/wolfprovider.sln
@@ -0,0 +1,42 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+# Four configurations. DLL Release|x64 is the customer artifact;
+# the two Static configurations exist only so unit-test can link
+# wolfProvider internals and are never shipped. unit-test therefore
+# gets Build.0 in the Static configurations only, and its ActiveCfg
+# in the DLL configurations points at the Static counterpart.
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wolfprovider", "wolfprovider\wolfprovider.vcxproj", "{9B1F3C0A-6D48-4E27-8A55-C3E7D2140F6B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit-test", "unit-test\unit-test.vcxproj", "{2E5D8B47-91FA-4C63-B0D2-6F14A3C97E85}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ DLL Debug|x64 = DLL Debug|x64
+ DLL Release|x64 = DLL Release|x64
+ Static Debug|x64 = Static Debug|x64
+ Static Release|x64 = Static Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {9B1F3C0A-6D48-4E27-8A55-C3E7D2140F6B}.DLL Debug|x64.ActiveCfg = DLL Debug|x64
+ {9B1F3C0A-6D48-4E27-8A55-C3E7D2140F6B}.DLL Debug|x64.Build.0 = DLL Debug|x64
+ {9B1F3C0A-6D48-4E27-8A55-C3E7D2140F6B}.DLL Release|x64.ActiveCfg = DLL Release|x64
+ {9B1F3C0A-6D48-4E27-8A55-C3E7D2140F6B}.DLL Release|x64.Build.0 = DLL Release|x64
+ {9B1F3C0A-6D48-4E27-8A55-C3E7D2140F6B}.Static Debug|x64.ActiveCfg = Static Debug|x64
+ {9B1F3C0A-6D48-4E27-8A55-C3E7D2140F6B}.Static Debug|x64.Build.0 = Static Debug|x64
+ {9B1F3C0A-6D48-4E27-8A55-C3E7D2140F6B}.Static Release|x64.ActiveCfg = Static Release|x64
+ {9B1F3C0A-6D48-4E27-8A55-C3E7D2140F6B}.Static Release|x64.Build.0 = Static Release|x64
+ {2E5D8B47-91FA-4C63-B0D2-6F14A3C97E85}.DLL Debug|x64.ActiveCfg = Static Debug|x64
+ {2E5D8B47-91FA-4C63-B0D2-6F14A3C97E85}.DLL Release|x64.ActiveCfg = Static Release|x64
+ {2E5D8B47-91FA-4C63-B0D2-6F14A3C97E85}.Static Debug|x64.ActiveCfg = Static Debug|x64
+ {2E5D8B47-91FA-4C63-B0D2-6F14A3C97E85}.Static Debug|x64.Build.0 = Static Debug|x64
+ {2E5D8B47-91FA-4C63-B0D2-6F14A3C97E85}.Static Release|x64.ActiveCfg = Static Release|x64
+ {2E5D8B47-91FA-4C63-B0D2-6F14A3C97E85}.Static Release|x64.Build.0 = Static Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {4C7A0E91-2B36-4D58-9F1C-7A08B5E3D62F}
+ EndGlobalSection
+EndGlobal
diff --git a/IDE/WINVS/wolfprovider/wolfprovider.def b/IDE/WINVS/wolfprovider/wolfprovider.def
new file mode 100644
index 00000000..5b9b9113
--- /dev/null
+++ b/IDE/WINVS/wolfprovider/wolfprovider.def
@@ -0,0 +1,26 @@
+; wolfProvider module exports.
+;
+; A provider module loaded by stock libcrypto needs exactly one symbol:
+; crypto/provider_core.c:1026-1027 does
+; DSO_bind_func(prov->module, "OSSL_provider_init")
+; and that is the only name-based lookup performed against a provider
+; module. Exporting it from a .def keeps wolfProvider's sources free of
+; __declspec annotations (PORT-DESIGN Decision 5).
+;
+; This file applies to the DLL configurations ONLY.
+; appears in the DLL Debug|x64 and DLL Release|x64 ItemDefinitionGroups of
+; wolfprovider.vcxproj and nowhere else: a static library has no export table,
+; and the Link task that consumes this file does not run for a StaticLibrary
+; configuration. The unit test reaches wolfProvider internals by linking the
+; Static Release|x64 library, never by widening this list -- growing it would
+; invite customers to ship a DLL with internal crypto symbols exposed.
+;
+; No LIBRARY statement: it is optional, and a LIBRARY name that does not
+; match the linker's output name produces LNK4102. The output name is set
+; by libwolfprov in wolfprovider.vcxproj.
+;
+; Requires WP_NO_DYNAMIC_PROVIDER to be undefined -- it guards
+; OSSL_provider_init at src/wp_wolfprov.c:1578-1592. None of the four
+; configurations defines it.
+EXPORTS
+ OSSL_provider_init
diff --git a/IDE/WINVS/wolfprovider/wolfprovider.vcxproj b/IDE/WINVS/wolfprovider/wolfprovider.vcxproj
new file mode 100644
index 00000000..dab92529
--- /dev/null
+++ b/IDE/WINVS/wolfprovider/wolfprovider.vcxproj
@@ -0,0 +1,241 @@
+
+
+
+
+
+ DLL Debug
+ x64
+
+
+ DLL Release
+ x64
+
+
+ Static Debug
+ x64
+
+
+ Static Release
+ x64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {9B1F3C0A-6D48-4E27-8A55-C3E7D2140F6B}
+ Win32Proj
+ wolfprovider
+ 10.0
+
+
+
+ DynamicLibrary
+ true
+ v143
+ Unicode
+
+
+ DynamicLibrary
+ false
+ v143
+ true
+ Unicode
+
+
+ StaticLibrary
+ true
+ v143
+ Unicode
+
+
+ StaticLibrary
+ false
+ v143
+
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ $(Configuration)\$(Platform)\$(ProjectName)_obj\
+ libwolfprov
+
+
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ $(Configuration)\$(Platform)\$(ProjectName)_obj\
+ libwolfprov
+
+
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ $(Configuration)\$(Platform)\$(ProjectName)_obj\
+ libwolfprov
+
+
+ $(SolutionDir)$(Configuration)\$(Platform)\
+ $(Configuration)\$(Platform)\$(ProjectName)_obj\
+ libwolfprov
+
+
+
+ Level3
+
+
+ Disabled
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ stdc11
+ WOLFSSL_USER_SETTINGS;WOLFSSL_DLL;WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ $(userSettingsDir);..;..\..\..\include;$(wolfCryptDir);$(openSslDirDebug)\include;%(AdditionalIncludeDirectories)
+ ProgramDatabase
+
+
+ Windows
+ true
+
+ wolfprovider.def
+ libcrypto.lib;$(wolfSslLib);ws2_32.lib;advapi32.lib;crypt32.lib;%(AdditionalDependencies)
+ $(openSslDirDebug);$(wolfCryptDllDebug64);%(AdditionalLibraryDirectories)
+ /IGNORE:4221 %(AdditionalOptions)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ MultiThreadedDLL
+ stdc11
+ WOLFSSL_USER_SETTINGS;WOLFSSL_DLL;WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ $(userSettingsDir);..;..\..\..\include;$(wolfCryptDir);$(openSslDir)\include;%(AdditionalIncludeDirectories)
+ ProgramDatabase
+
+
+ Windows
+ true
+ true
+ true
+ wolfprovider.def
+ libcrypto.lib;$(wolfSslLib);ws2_32.lib;advapi32.lib;crypt32.lib;%(AdditionalDependencies)
+ $(openSslDir);$(wolfCryptDllRelease64);%(AdditionalLibraryDirectories)
+ /IGNORE:4221 %(AdditionalOptions)
+
+
+
+
+ Level3
+
+
+ Disabled
+ EnableFastChecks
+ MultiThreadedDebugDLL
+ stdc11
+ WOLFSSL_USER_SETTINGS;WOLFSSL_DLL;WIN32;_WINDOWS;_DEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ $(userSettingsDir);..;..\..\..\include;$(wolfCryptDir);$(openSslDirDebug)\include;%(AdditionalIncludeDirectories)
+ ProgramDatabase
+
+
+ /IGNORE:4221 %(AdditionalOptions)
+
+
+
+
+ Level3
+
+
+ MaxSpeed
+ true
+ true
+ MultiThreadedDLL
+ stdc11
+ WOLFSSL_USER_SETTINGS;WOLFSSL_DLL;WIN32;_WINDOWS;NDEBUG;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)
+ $(userSettingsDir);..;..\..\..\include;$(wolfCryptDir);$(openSslDir)\include;%(AdditionalIncludeDirectories)
+ ProgramDatabase
+
+
+ /IGNORE:4221 %(AdditionalOptions)
+
+
+
+
+
+
diff --git a/IDE/include.am b/IDE/include.am
new file mode 100644
index 00000000..6500d7e8
--- /dev/null
+++ b/IDE/include.am
@@ -0,0 +1,19 @@
+# vim:ft=automake
+# included from Top Level Makefile.am
+# All paths should be given relative to the root
+
+include IDE/WINVS/include.am
+
+# Files not directories: EXTRA_DIST copies a directory whole, .gitignore and all.
+EXTRA_DIST += IDE/XCODE/README.md
+EXTRA_DIST += IDE/XCODE/build-all.sh
+EXTRA_DIST += IDE/XCODE/build-openssl-framework.sh
+EXTRA_DIST += IDE/XCODE/build-wolfprovider-framework.sh
+EXTRA_DIST += IDE/XCODE/build-wolfssl-framework.sh
+EXTRA_DIST += IDE/XCODE/run_openssl.sh
+
+EXTRA_DIST += IDE/Android/README.md
+EXTRA_DIST += IDE/Android/build.sh
+EXTRA_DIST += IDE/Android/run.sh
+EXTRA_DIST += IDE/Android/run_helper.sh
+EXTRA_DIST += IDE/Android/run_openssl.sh
diff --git a/Makefile.am b/Makefile.am
index 0e1ad9aa..4d35df0f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -16,19 +16,21 @@ lib_LTLIBRARIES = libwolfprov.la
EXTRA_DIST+=ChangeLog.md
EXTRA_DIST+=README.md
-EXTRA_DIST+=IDE
EXTRA_DIST+=examples
EXTRA_DIST+=docs
EXTRA_DIST+=patches
EXTRA_DIST+=provider.conf
EXTRA_DIST+=provider-fips.conf
+# Not EXTRA_DIST+=IDE: that is recursive and not .gitignore-aware, and both
+# IDE/WINVS and IDE/Android are built into.
include src/include.am
include include/include.am
include test/include.am
include certs/include.am
include scripts/include.am
include examples/include.am
+include IDE/include.am
#noinst_PROGRAMS += bench
#bench_SOURCES = bench.c
diff --git a/include/wolfprovider/alg_funcs.h b/include/wolfprovider/alg_funcs.h
index 3d35d115..90c070b4 100644
--- a/include/wolfprovider/alg_funcs.h
+++ b/include/wolfprovider/alg_funcs.h
@@ -338,8 +338,18 @@ extern const OSSL_DISPATCH wp_sha224_functions[];
extern const OSSL_DISPATCH wp_sha256_functions[];
extern const OSSL_DISPATCH wp_sha384_functions[];
extern const OSSL_DISPATCH wp_sha512_functions[];
+/* SHA-512/224 and SHA-512/256 are outside the FIPS module boundary. Guards must
+ * match the IMPLEMENT_DIGEST() guards in wp_digests.c. */
+#if LIBWOLFSSL_VERSION_HEX >= 0x05000000
+#if !defined(WOLFSSL_NOSHA512_224) && \
+ !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
extern const OSSL_DISPATCH wp_sha512_224_functions[];
+#endif /* !WOLFSSL_NOSHA512_224 && !HAVE_FIPS && !HAVE_SELFTEST */
+#if !defined(WOLFSSL_NOSHA512_256) && \
+ !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
extern const OSSL_DISPATCH wp_sha512_256_functions[];
+#endif /* !WOLFSSL_NOSHA512_256 && !HAVE_FIPS && !HAVE_SELFTEST */
+#endif /* LIBWOLFSSL_VERSION_HEX >= 0x05000000 */
extern const OSSL_DISPATCH wp_sha3_224_functions[];
extern const OSSL_DISPATCH wp_sha3_256_functions[];
diff --git a/include/wolfprovider/internal.h b/include/wolfprovider/internal.h
index 2d43b02a..6cf8cd0d 100644
--- a/include/wolfprovider/internal.h
+++ b/include/wolfprovider/internal.h
@@ -26,7 +26,9 @@
#ifdef WOLFENGINE_USER_SETTINGS
#include "user_settings.h"
#endif
-#include
+#ifndef WOLFSSL_USER_SETTINGS
+ #include
+#endif
#include
#include
#include
@@ -199,6 +201,8 @@ void wp_provctx_unlock_rng(WOLFPROV_CTX* provCtx);
#define WP_CAST_ALGO_DH 6
#define WP_CAST_ALGO_COUNT 7
+int wp_init_cast_mutexes(void);
+
int wp_init_cast(int algo);
/**
diff --git a/include/wolfprovider/settings.h b/include/wolfprovider/settings.h
index 438d5812..ef17c89a 100644
--- a/include/wolfprovider/settings.h
+++ b/include/wolfprovider/settings.h
@@ -21,7 +21,9 @@
#ifndef WOLFPROV_SETTINGS_H
#define WOLFPROV_SETTINGS_H
-#include
+#ifndef WOLFSSL_USER_SETTINGS
+ #include
+#endif
#ifdef WOLFPROV_USER_SETTINGS
#include "user_settings.h"
#endif
diff --git a/include/wolfprovider/version.h b/include/wolfprovider/version.h
new file mode 100644
index 00000000..cbff3296
--- /dev/null
+++ b/include/wolfprovider/version.h
@@ -0,0 +1,39 @@
+/* version.h.in
+ *
+ * Copyright (C) 2006-2025 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 .
+ */
+
+
+#ifndef WOLFPROV_VERSION_H
+#define WOLFPROV_VERSION_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LIBWOLFPROV_VERSION_STRING "1.2.1"
+#define LIBWOLFPROV_VERSION_HEX 0x01002001
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* WOLFPROV_VERSION_H */
+
diff --git a/include/wolfprovider/wp_fips.h b/include/wolfprovider/wp_fips.h
index 359482b8..22e2fc9a 100644
--- a/include/wolfprovider/wp_fips.h
+++ b/include/wolfprovider/wp_fips.h
@@ -25,7 +25,13 @@
#include "user_settings.h"
#endif
-#include
+#ifndef WOLFSSL_USER_SETTINGS
+ #include
+#endif
+/* Not redundant with the above: a WOLFSSL_USER_SETTINGS build has no options.h,
+ * and WP_FIPS_CHECKS_DEFAULT silently becomes 0 unless HAVE_FIPS is visible in
+ * this header - wp_fips.c includes nothing else. */
+#include
enum wolfProvider_FipsCheck {
/* check that RSA key size is valid */
diff --git a/include/wolfprovider/wp_params.h b/include/wolfprovider/wp_params.h
index f78885fa..ee390469 100644
--- a/include/wolfprovider/wp_params.h
+++ b/include/wolfprovider/wp_params.h
@@ -25,7 +25,9 @@
#ifdef WOLFENGINE_USER_SETTINGS
#include "user_settings.h"
#endif
-#include
+#ifndef WOLFSSL_USER_SETTINGS
+ #include
+#endif
#include
#ifndef WP_PARAMS_H
diff --git a/src/wp_dh_kmgmt.c b/src/wp_dh_kmgmt.c
index 81b099e5..442f1c40 100644
--- a/src/wp_dh_kmgmt.c
+++ b/src/wp_dh_kmgmt.c
@@ -189,7 +189,7 @@ static int wp_dh_map_group_name(wp_Dh* dh, const char* name)
WOLFPROV_ENTER(WP_LOG_COMP_DH, "wp_dh_map_group_name");
for (i = 0; i < WP_DH_GROUP_MAP_SZ; i++) {
- if (strcasecmp(wp_dh_group_map[i].name, name) == 0) {
+ if (XSTRCASECMP(wp_dh_group_map[i].name, name) == 0) {
#ifdef HAVE_PUBLIC_FFDHE
const DhParams* params;
#endif
diff --git a/src/wp_ecc_kmgmt.c b/src/wp_ecc_kmgmt.c
index f566f0fa..f691060d 100644
--- a/src/wp_ecc_kmgmt.c
+++ b/src/wp_ecc_kmgmt.c
@@ -157,7 +157,7 @@ static int wp_ecc_map_group_name(wp_Ecc* ecc, const char* name)
WOLFPROV_ENTER(WP_LOG_COMP_ECC, "wp_ecc_map_group_name");
for (i = 0; i < WP_ECC_GROUP_MAP_SZ; i++) {
- if (strcasecmp(wp_ecc_group_map[i].name, name) == 0) {
+ if (XSTRCASECMP(wp_ecc_group_map[i].name, name) == 0) {
ecc->curveId = wp_ecc_group_map[i].curveId;
ecc->bits = wp_ecc_group_map[i].bits;
break;
diff --git a/src/wp_ecdsa_sig.c b/src/wp_ecdsa_sig.c
index 624d7612..992eaef7 100644
--- a/src/wp_ecdsa_sig.c
+++ b/src/wp_ecdsa_sig.c
@@ -549,7 +549,7 @@ static int wp_ecdsa_digest_signverify_init(wp_EcdsaSigCtx *ctx,
ok = wp_ecdsa_signverify_init(ctx, ecc, params, op);
if (ok) {
if ((mdName != NULL) && ((mdName[0] == '\0') ||
- (strcasecmp(ctx->mdName, mdName) != 0))) {
+ (XSTRCASECMP(ctx->mdName, mdName) != 0))) {
ok = wp_ecdsa_setup_md(ctx, mdName, ctx->propQuery, op);
}
}
diff --git a/src/wp_hkdf.c b/src/wp_hkdf.c
index e2721972..1f6c1b09 100644
--- a/src/wp_hkdf.c
+++ b/src/wp_hkdf.c
@@ -361,13 +361,13 @@ static int wp_hkdf_base_get_mode(const OSSL_PARAM params[], int* mode)
int n;
if (p->data_type == OSSL_PARAM_UTF8_STRING) {
- if (strcasecmp(p->data, "EXTRACT_AND_EXPAND") == 0) {
+ if (XSTRCASECMP(p->data, "EXTRACT_AND_EXPAND") == 0) {
*mode = EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND;
}
- else if (strcasecmp(p->data, "EXTRACT_ONLY") == 0) {
+ else if (XSTRCASECMP(p->data, "EXTRACT_ONLY") == 0) {
*mode = EVP_KDF_HKDF_MODE_EXTRACT_ONLY;
}
- else if (strcasecmp(p->data, "EXPAND_ONLY") == 0) {
+ else if (XSTRCASECMP(p->data, "EXPAND_ONLY") == 0) {
*mode = EVP_KDF_HKDF_MODE_EXPAND_ONLY;
}
else {
diff --git a/src/wp_internal.c b/src/wp_internal.c
index 513b7349..3e82a717 100644
--- a/src/wp_internal.c
+++ b/src/wp_internal.c
@@ -23,6 +23,7 @@
#include
#include
#include
+#include
#include
#include
@@ -94,14 +95,13 @@ typedef struct wp_cast_algo_state {
static wp_cast_algo_state castAlgos[WP_CAST_ALGO_COUNT];
+static CRYPTO_ONCE castAlgosOnce = CRYPTO_ONCE_STATIC_INIT;
+
/**
- * Initialize the cast mutexes on library load.
+ * Initialize the CAST self-test state of every algorithm.
*
- * This constructor runs when libwolfprov.so is loaded via dlopen() or at
- * program startup. It ensures the castAlgos are initialized before any
- * wolfProvider functions are called.
+ * Run once, through wp_init_cast_mutexes().
*/
-__attribute__((constructor))
static void wolfprov_init_cast_mutex(void)
{
int i;
@@ -111,6 +111,16 @@ static void wolfprov_init_cast_mutex(void)
}
}
+/**
+ * Initialize the cast mutexes. Runs once.
+ * @return 1 on success.
+ * @return 0 on failure.
+ */
+int wp_init_cast_mutexes(void)
+{
+ return CRYPTO_THREAD_run_once(&castAlgosOnce, wolfprov_init_cast_mutex);
+}
+
/**
* Initialize a CAST self-test for a specific algorithm.
*
@@ -1555,6 +1565,24 @@ byte wp_ct_byte_mask_sel(byte mask, byte a, byte b)
* them here. Consumed by SSHKDF (mpint length decode) and KBKDF
* (counter / length encode). */
+#if !defined(WOLFSSL_USE_ALIGN) && defined(LITTLE_ENDIAN_ORDER)
+/**
+ * Reverse the byte order of a 32-bit value.
+ *
+ * wolfSSL's ByteReverseWord32() is not exported.
+ *
+ * @param [in] value Value to reverse the byte order of.
+ * @return Value with byte order reversed.
+ */
+static word32 wp_byte_reverse_word32(word32 value)
+{
+ return ((value & 0x000000ffU) << 24) |
+ ((value & 0x0000ff00U) << 8) |
+ ((value & 0x00ff0000U) >> 8) |
+ ((value & 0xff000000U) >> 24);
+}
+#endif /* !WOLFSSL_USE_ALIGN && LITTLE_ENDIAN_ORDER */
+
void wp_c32toa(word32 wc_u32, byte* c) {
#ifdef WOLFSSL_USE_ALIGN
c[0] = (byte)((wc_u32 >> 24) & 0xff);
@@ -1562,7 +1590,7 @@ void wp_c32toa(word32 wc_u32, byte* c) {
c[2] = (byte)((wc_u32 >> 8) & 0xff);
c[3] = (byte) (wc_u32 & 0xff);
#elif defined(LITTLE_ENDIAN_ORDER)
- *(word32*)c = ByteReverseWord32(wc_u32);
+ *(word32*)c = wp_byte_reverse_word32(wc_u32);
#else
*(word32*)c = wc_u32;
#endif
@@ -1573,7 +1601,7 @@ word32 wp_atoc32(const byte* c) {
return ((word32)c[0] << 24) | ((word32)c[1] << 16)
| ((word32)c[2] << 8) | (word32)c[3];
#elif defined(LITTLE_ENDIAN_ORDER)
- return ByteReverseWord32(*(const word32*)c);
+ return wp_byte_reverse_word32(*(const word32*)c);
#else
return *(const word32*)c;
#endif
diff --git a/src/wp_logging.c b/src/wp_logging.c
index 74fc0155..a9103f97 100644
--- a/src/wp_logging.c
+++ b/src/wp_logging.c
@@ -468,18 +468,18 @@ static void wolfProv_LogLevelToMask(const char* level, size_t len, void* ctx) {
size_t len;
uint32_t mask;
} log_levels[] = {
- { "WP_LOG_LEVEL_ERROR", XSTRLEN("WP_LOG_LEVEL_ERROR"), WP_LOG_LEVEL_ERROR },
- { "WP_LOG_LEVEL_ENTER", XSTRLEN("WP_LOG_LEVEL_ENTER"), WP_LOG_LEVEL_ENTER },
- { "WP_LOG_LEVEL_LEAVE", XSTRLEN("WP_LOG_LEVEL_LEAVE"), WP_LOG_LEVEL_LEAVE },
- { "WP_LOG_LEVEL_INFO", XSTRLEN("WP_LOG_LEVEL_INFO"), WP_LOG_LEVEL_INFO },
- { "WP_LOG_LEVEL_VERBOSE", XSTRLEN("WP_LOG_LEVEL_VERBOSE"),WP_LOG_LEVEL_VERBOSE },
- { "WP_LOG_LEVEL_DEBUG", XSTRLEN("WP_LOG_LEVEL_DEBUG"), WP_LOG_LEVEL_DEBUG },
- { "WP_LOG_LEVEL_TRACE", XSTRLEN("WP_LOG_LEVEL_TRACE"), WP_LOG_LEVEL_TRACE },
+ { "WP_LOG_LEVEL_ERROR", sizeof("WP_LOG_LEVEL_ERROR") - 1, WP_LOG_LEVEL_ERROR },
+ { "WP_LOG_LEVEL_ENTER", sizeof("WP_LOG_LEVEL_ENTER") - 1, WP_LOG_LEVEL_ENTER },
+ { "WP_LOG_LEVEL_LEAVE", sizeof("WP_LOG_LEVEL_LEAVE") - 1, WP_LOG_LEVEL_LEAVE },
+ { "WP_LOG_LEVEL_INFO", sizeof("WP_LOG_LEVEL_INFO") - 1, WP_LOG_LEVEL_INFO },
+ { "WP_LOG_LEVEL_VERBOSE", sizeof("WP_LOG_LEVEL_VERBOSE") - 1,WP_LOG_LEVEL_VERBOSE },
+ { "WP_LOG_LEVEL_DEBUG", sizeof("WP_LOG_LEVEL_DEBUG") - 1, WP_LOG_LEVEL_DEBUG },
+ { "WP_LOG_LEVEL_TRACE", sizeof("WP_LOG_LEVEL_TRACE") - 1, WP_LOG_LEVEL_TRACE },
{ "WP_LOG_LEVEL_DEFAULT",
- XSTRLEN("WP_LOG_LEVEL_DEFAULT"),
+ sizeof("WP_LOG_LEVEL_DEFAULT") - 1,
WP_LOG_LEVEL_DEFAULT },
{ "WP_LOG_LEVEL_ALL",
- XSTRLEN("WP_LOG_LEVEL_ALL"),
+ sizeof("WP_LOG_LEVEL_ALL") - 1,
WP_LOG_LEVEL_ALL },
};
static const size_t num_levels = sizeof(log_levels) / sizeof(log_levels[0]);
@@ -502,42 +502,42 @@ static void wolfProv_LogComponentToMask(const char* level, size_t len, void* ctx
size_t len;
uint32_t mask;
} log_components[] = {
- { "WP_LOG_COMP_RNG", XSTRLEN("WP_LOG_COMP_RNG"), WP_LOG_COMP_RNG },
- { "WP_LOG_COMP_DIGEST", XSTRLEN("WP_LOG_COMP_DIGEST"), WP_LOG_COMP_DIGEST },
- { "WP_LOG_COMP_MAC", XSTRLEN("WP_LOG_COMP_MAC"), WP_LOG_COMP_MAC },
- { "WP_LOG_COMP_CIPHER", XSTRLEN("WP_LOG_COMP_CIPHER"), WP_LOG_COMP_CIPHER },
- { "WP_LOG_COMP_PK", XSTRLEN("WP_LOG_COMP_PK"), WP_LOG_COMP_PK },
- { "WP_LOG_COMP_KE", XSTRLEN("WP_LOG_COMP_KE"), WP_LOG_COMP_KE },
- { "WP_LOG_COMP_KDF", XSTRLEN("WP_LOG_COMP_KDF"), WP_LOG_COMP_KDF },
- { "WP_LOG_COMP_PROVIDER", XSTRLEN("WP_LOG_COMP_PROVIDER"), WP_LOG_COMP_PROVIDER },
- { "WP_LOG_COMP_RSA", XSTRLEN("WP_LOG_COMP_RSA"), WP_LOG_COMP_RSA },
- { "WP_LOG_COMP_ECC", XSTRLEN("WP_LOG_COMP_ECC"), WP_LOG_COMP_ECC },
- { "WP_LOG_COMP_DH", XSTRLEN("WP_LOG_COMP_DH"), WP_LOG_COMP_DH },
- { "WP_LOG_COMP_AES", XSTRLEN("WP_LOG_COMP_AES"), WP_LOG_COMP_AES },
- { "WP_LOG_COMP_DES", XSTRLEN("WP_LOG_COMP_DES"), WP_LOG_COMP_DES },
- { "WP_LOG_COMP_SHA", XSTRLEN("WP_LOG_COMP_SHA"), WP_LOG_COMP_SHA },
- { "WP_LOG_COMP_MD5", XSTRLEN("WP_LOG_COMP_MD5"), WP_LOG_COMP_MD5 },
- { "WP_LOG_COMP_HMAC", XSTRLEN("WP_LOG_COMP_HMAC"), WP_LOG_COMP_HMAC },
- { "WP_LOG_COMP_CMAC", XSTRLEN("WP_LOG_COMP_CMAC"), WP_LOG_COMP_CMAC },
- { "WP_LOG_COMP_HKDF", XSTRLEN("WP_LOG_COMP_HKDF"), WP_LOG_COMP_HKDF },
- { "WP_LOG_COMP_PBKDF2", XSTRLEN("WP_LOG_COMP_PBKDF2"), WP_LOG_COMP_PBKDF2 },
- { "WP_LOG_COMP_KRB5KDF", XSTRLEN("WP_LOG_COMP_KRB5KDF"), WP_LOG_COMP_KRB5KDF },
- { "WP_LOG_COMP_DRBG", XSTRLEN("WP_LOG_COMP_DRBG"), WP_LOG_COMP_DRBG },
- { "WP_LOG_COMP_ECDSA", XSTRLEN("WP_LOG_COMP_ECDSA"), WP_LOG_COMP_ECDSA },
- { "WP_LOG_COMP_ECDH", XSTRLEN("WP_LOG_COMP_ECDH"), WP_LOG_COMP_ECDH },
- { "WP_LOG_COMP_ED25519", XSTRLEN("WP_LOG_COMP_ED25519"), WP_LOG_COMP_ED25519 },
- { "WP_LOG_COMP_ED448", XSTRLEN("WP_LOG_COMP_ED448"), WP_LOG_COMP_ED448 },
- { "WP_LOG_COMP_X25519", XSTRLEN("WP_LOG_COMP_X25519"), WP_LOG_COMP_X25519 },
- { "WP_LOG_COMP_X448", XSTRLEN("WP_LOG_COMP_X448"), WP_LOG_COMP_X448 },
- { "WP_LOG_COMP_QUERY", XSTRLEN("WP_LOG_COMP_QUERY"), WP_LOG_COMP_QUERY },
- { "WP_LOG_COMP_TLS1_PRF", XSTRLEN("WP_LOG_COMP_TLS1_PRF"), WP_LOG_COMP_TLS1_PRF },
- { "WP_LOG_COMP_SSHKDF", XSTRLEN("WP_LOG_COMP_SSHKDF"), WP_LOG_COMP_SSHKDF },
- { "WP_LOG_COMP_PQC", XSTRLEN("WP_LOG_COMP_PQC"), WP_LOG_COMP_PQC },
+ { "WP_LOG_COMP_RNG", sizeof("WP_LOG_COMP_RNG") - 1, WP_LOG_COMP_RNG },
+ { "WP_LOG_COMP_DIGEST", sizeof("WP_LOG_COMP_DIGEST") - 1, WP_LOG_COMP_DIGEST },
+ { "WP_LOG_COMP_MAC", sizeof("WP_LOG_COMP_MAC") - 1, WP_LOG_COMP_MAC },
+ { "WP_LOG_COMP_CIPHER", sizeof("WP_LOG_COMP_CIPHER") - 1, WP_LOG_COMP_CIPHER },
+ { "WP_LOG_COMP_PK", sizeof("WP_LOG_COMP_PK") - 1, WP_LOG_COMP_PK },
+ { "WP_LOG_COMP_KE", sizeof("WP_LOG_COMP_KE") - 1, WP_LOG_COMP_KE },
+ { "WP_LOG_COMP_KDF", sizeof("WP_LOG_COMP_KDF") - 1, WP_LOG_COMP_KDF },
+ { "WP_LOG_COMP_PROVIDER", sizeof("WP_LOG_COMP_PROVIDER") - 1, WP_LOG_COMP_PROVIDER },
+ { "WP_LOG_COMP_RSA", sizeof("WP_LOG_COMP_RSA") - 1, WP_LOG_COMP_RSA },
+ { "WP_LOG_COMP_ECC", sizeof("WP_LOG_COMP_ECC") - 1, WP_LOG_COMP_ECC },
+ { "WP_LOG_COMP_DH", sizeof("WP_LOG_COMP_DH") - 1, WP_LOG_COMP_DH },
+ { "WP_LOG_COMP_AES", sizeof("WP_LOG_COMP_AES") - 1, WP_LOG_COMP_AES },
+ { "WP_LOG_COMP_DES", sizeof("WP_LOG_COMP_DES") - 1, WP_LOG_COMP_DES },
+ { "WP_LOG_COMP_SHA", sizeof("WP_LOG_COMP_SHA") - 1, WP_LOG_COMP_SHA },
+ { "WP_LOG_COMP_MD5", sizeof("WP_LOG_COMP_MD5") - 1, WP_LOG_COMP_MD5 },
+ { "WP_LOG_COMP_HMAC", sizeof("WP_LOG_COMP_HMAC") - 1, WP_LOG_COMP_HMAC },
+ { "WP_LOG_COMP_CMAC", sizeof("WP_LOG_COMP_CMAC") - 1, WP_LOG_COMP_CMAC },
+ { "WP_LOG_COMP_HKDF", sizeof("WP_LOG_COMP_HKDF") - 1, WP_LOG_COMP_HKDF },
+ { "WP_LOG_COMP_PBKDF2", sizeof("WP_LOG_COMP_PBKDF2") - 1, WP_LOG_COMP_PBKDF2 },
+ { "WP_LOG_COMP_KRB5KDF", sizeof("WP_LOG_COMP_KRB5KDF") - 1, WP_LOG_COMP_KRB5KDF },
+ { "WP_LOG_COMP_DRBG", sizeof("WP_LOG_COMP_DRBG") - 1, WP_LOG_COMP_DRBG },
+ { "WP_LOG_COMP_ECDSA", sizeof("WP_LOG_COMP_ECDSA") - 1, WP_LOG_COMP_ECDSA },
+ { "WP_LOG_COMP_ECDH", sizeof("WP_LOG_COMP_ECDH") - 1, WP_LOG_COMP_ECDH },
+ { "WP_LOG_COMP_ED25519", sizeof("WP_LOG_COMP_ED25519") - 1, WP_LOG_COMP_ED25519 },
+ { "WP_LOG_COMP_ED448", sizeof("WP_LOG_COMP_ED448") - 1, WP_LOG_COMP_ED448 },
+ { "WP_LOG_COMP_X25519", sizeof("WP_LOG_COMP_X25519") - 1, WP_LOG_COMP_X25519 },
+ { "WP_LOG_COMP_X448", sizeof("WP_LOG_COMP_X448") - 1, WP_LOG_COMP_X448 },
+ { "WP_LOG_COMP_QUERY", sizeof("WP_LOG_COMP_QUERY") - 1, WP_LOG_COMP_QUERY },
+ { "WP_LOG_COMP_TLS1_PRF", sizeof("WP_LOG_COMP_TLS1_PRF") - 1, WP_LOG_COMP_TLS1_PRF },
+ { "WP_LOG_COMP_SSHKDF", sizeof("WP_LOG_COMP_SSHKDF") - 1, WP_LOG_COMP_SSHKDF },
+ { "WP_LOG_COMP_PQC", sizeof("WP_LOG_COMP_PQC") - 1, WP_LOG_COMP_PQC },
{ "WP_LOG_COMP_ALL",
- XSTRLEN("WP_LOG_COMP_ALL"),
+ sizeof("WP_LOG_COMP_ALL") - 1,
WP_LOG_COMP_ALL },
{ "WP_LOG_COMP_DEFAULT",
- XSTRLEN("WP_LOG_COMP_DEFAULT"),
+ sizeof("WP_LOG_COMP_DEFAULT") - 1,
WP_LOG_COMP_DEFAULT },
};
static const size_t num_components =
diff --git a/src/wp_tls_capa.c b/src/wp_tls_capa.c
index 5d8e0f87..0dce7a44 100644
--- a/src/wp_tls_capa.c
+++ b/src/wp_tls_capa.c
@@ -304,11 +304,11 @@ int wolfssl_prov_get_capabilities(void *provCtx, const char *capability,
(void)provCtx;
- if (strcasecmp(capability, "TLS-GROUP") == 0) {
+ if (XSTRCASECMP(capability, "TLS-GROUP") == 0) {
ok = wp_tls_group_capability(cb, arg);
}
#ifdef WP_HAVE_MLDSA
- else if (strcasecmp(capability, "TLS-SIGALG") == 0) {
+ else if (XSTRCASECMP(capability, "TLS-SIGALG") == 0) {
ok = wp_tls_sigalg_capability(cb, arg);
}
#endif
diff --git a/src/wp_wolfprov.c b/src/wp_wolfprov.c
index f09c5607..f65bd19a 100644
--- a/src/wp_wolfprov.c
+++ b/src/wp_wolfprov.c
@@ -35,6 +35,7 @@
#include "wolfprovider/alg_funcs.h"
#include "wolfssl/wolfcrypt/logging.h"
+#include "wolfssl/wolfcrypt/wc_port.h"
#ifdef HAVE_FIPS
#include
@@ -431,16 +432,18 @@ static const OSSL_ALGORITHM wolfprov_digests[] = {
{ WP_NAMES_SHA2_512, WOLFPROV_PROPERTIES, wp_sha512_functions,
"" },
#if LIBWOLFSSL_VERSION_HEX >= 0x05000000
-#ifndef WOLFSSL_NOSHA512_224
+#if !defined(WOLFSSL_NOSHA512_224) && \
+ !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
{ WP_NAMES_SHA2_512_224, WOLFPROV_PROPERTIES,
wp_sha512_224_functions,
"" },
-#endif /* !WOLFSSL_NOSHA512_224 */
-#ifndef WOLFSSL_NOSHA512_256
+#endif /* !WOLFSSL_NOSHA512_224 && !HAVE_FIPS && !HAVE_SELFTEST */
+#if !defined(WOLFSSL_NOSHA512_256) && \
+ !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
{ WP_NAMES_SHA2_512_256, WOLFPROV_PROPERTIES,
wp_sha512_256_functions,
"" },
-#endif /* !WOLFSSL_NOSHA512_256 */
+#endif /* !WOLFSSL_NOSHA512_256 && !HAVE_FIPS && !HAVE_SELFTEST */
#endif
#endif /* WP_HAVE_SHA512 */
@@ -1352,6 +1355,8 @@ static const OSSL_ALGORITHM* wolfprov_query(void* provCtx, int id,
static void wolfprov_teardown(void* provCtx)
{
wolfssl_prov_ctx_free(provCtx);
+
+ wolfCrypt_Cleanup();
}
/* Table of functions the core will invoke. */
@@ -1406,6 +1411,8 @@ int wolfssl_provider_init(const OSSL_CORE_HANDLE* handle,
{
int ok = 1;
const OSSL_DISPATCH* origIn = in;
+ int wcInited = 0;
+ int rc;
wolfProv_LogInit();
@@ -1430,6 +1437,18 @@ int wolfssl_provider_init(const OSSL_CORE_HANDLE* handle,
wolfCrypt_SetCb_fips(wp_fipsCb);
#endif
+ if (ok) {
+ /* Reference counted, so a host that already initialized is unaffected. */
+ rc = wolfCrypt_Init();
+ if (rc != 0) {
+ WOLFPROV_ERROR_FUNC(WP_LOG_COMP_PROVIDER, "wolfCrypt_Init", rc);
+ ok = 0;
+ }
+ else {
+ wcInited = 1;
+ }
+ }
+
#ifdef WP_CHECK_FORCE_FAIL
char *forceFailEnv = NULL;
#if defined(XGETENV) && !defined(NO_GETENV)
@@ -1484,7 +1503,15 @@ int wolfssl_provider_init(const OSSL_CORE_HANDLE* handle,
* wc_InitRng() in wolfssl_prov_ctx_new() would fail DRBG_NO_SEED_CB. */
wc_SetSeed_Cb(wc_GenerateSeed);
#endif
- /* FIPS CAST tests are now run lazily per-algorithm via wp_init_cast() */
+#if defined(HAVE_FIPS) && !defined(WP_SINGLE_THREADED)
+ /* FIPS CAST tests are run lazily per-algorithm via wp_init_cast();
+ * their mutexes must exist before the first one runs. */
+ if (!wp_init_cast_mutexes()) {
+ WOLFPROV_ERROR_MSG(WP_LOG_COMP_PROVIDER,
+ "Failed to initialize FIPS CAST mutexes");
+ ok = 0;
+ }
+#endif
}
if (ok) {
@@ -1507,6 +1534,11 @@ int wolfssl_provider_init(const OSSL_CORE_HANDLE* handle,
*out = wolfprov_dispatch_table;
}
+ if (!ok && wcInited) {
+ /* The core does not call teardown when init fails. */
+ wolfCrypt_Cleanup();
+ }
+
WOLFPROV_LEAVE(WP_LOG_COMP_PROVIDER, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
return ok;
}
diff --git a/test/test_ecc.c b/test/test_ecc.c
index 03a0d8bf..06337585 100644
--- a/test/test_ecc.c
+++ b/test/test_ecc.c
@@ -1364,6 +1364,14 @@ static const unsigned char x25519_shared_secret[] = {
*/
int test_ecdh_x25519_vector(void *data)
{
+#ifdef WOLFSSL_CURVE25519_BLINDING
+ /* Blinded curve25519 needs an RNG attached with wc_curve25519_set_rng(),
+ * which wolfProvider does not do yet. Gated on the macro rather than
+ * _WIN32 so builds without blinding keep the coverage. */
+ PRINT_MSG("X25519 ECDH KAT skipped - curve25519 blinding enabled");
+ (void)data;
+ return 0;
+#else
int err = 0;
EVP_PKEY *keyA = NULL;
EVP_PKEY *keyB = NULL;
@@ -1405,6 +1413,7 @@ int test_ecdh_x25519_vector(void *data)
EVP_PKEY_free(keyA);
return err;
+#endif
}
#endif /* WP_HAVE_X25519 */
diff --git a/test/test_ecx.c b/test/test_ecx.c
index c8e278f7..50977f8b 100644
--- a/test/test_ecx.c
+++ b/test/test_ecx.c
@@ -821,6 +821,14 @@ int test_ecx_x25519_raw_priv_roundtrip(void *data)
* size query; using it would truncate or fail the export. */
int test_ecx_x25519_get_params_stale_ret(void *data)
{
+#ifdef WOLFSSL_CURVE25519_BLINDING
+ /* Blinded curve25519 needs an RNG attached with wc_curve25519_set_rng(),
+ * which wolfProvider does not do yet. Gated on the macro rather than
+ * _WIN32 so builds without blinding keep the coverage. */
+ PRINT_MSG("X25519 get_params test skipped - curve25519 blinding enabled");
+ (void)data;
+ return 0;
+#else
int err = 0;
EVP_PKEY *pkey = NULL;
static const unsigned char privKey[] = {
@@ -917,6 +925,7 @@ int test_ecx_x25519_get_params_stale_ret(void *data)
EVP_PKEY_free(pkey);
return err;
+#endif
}
/* A zero-length private key octet string must be rejected without an
diff --git a/test/unit.c b/test/unit.c
index ff45167c..87152438 100644
--- a/test/unit.c
+++ b/test/unit.c
@@ -967,13 +967,24 @@ int main(int argc, char* argv[])
if (err == 0 && runTests) {
printf("\n");
- (void)staticTest;
- printf("Running tests using dynamic provider.\n");
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
wpLibCtx = OSSL_LIB_CTX_new();
+ (void)staticTest;
+#ifdef WP_UNIT_STATIC_PROVIDER
+ /* Linked into this executable, so there is no module to load. Loading
+ * it here would put a second copy of wolfProvider in the process. */
+ printf("Running tests using built-in (statically linked) provider.\n");
+ if (!OSSL_PROVIDER_add_builtin(wpLibCtx, name,
+ wolfssl_provider_init)) {
+ PRINT_ERR_MSG("Failed to add built-in wolf provider!\n");
+ err = 1;
+ }
+#else
+ printf("Running tests using dynamic provider.\n");
OSSL_PROVIDER_set_default_search_path(wpLibCtx, dir);
+#endif
wpProv = OSSL_PROVIDER_load(wpLibCtx, name);
if (wpProv == NULL) {
PRINT_ERR_MSG("Failed to find wolf provider!\n");
diff --git a/test/unit.h b/test/unit.h
index 83cd1419..a023ee21 100644
--- a/test/unit.h
+++ b/test/unit.h
@@ -30,7 +30,9 @@
#ifdef WOLFPROV_USER_SETTINGS
#include
#endif
+#ifndef WOLFSSL_USER_SETTINGS
#include
+#endif
#include
#include