Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions IDE/WINVS/unit-test/unit-test.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
<ClCompile Include="..\..\..\test\test_rand_seed.c" />
<ClCompile Include="..\..\..\test\test_ecc.c" />
<ClCompile Include="..\..\..\test\test_ecx.c" />
<ClCompile Include="..\..\..\test\test_fips_policy.c" />
<ClCompile Include="..\..\..\test\test_gmac.c" />
<ClCompile Include="..\..\..\test\test_krb5kdf.c" />
<ClCompile Include="..\..\..\test\test_sshkdf.c" />
Expand Down
22 changes: 21 additions & 1 deletion docs/FIPS_INTEGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,32 @@ Always use `--distclean` when switching between production and testing builds:

| Category | Algorithms |
|----------|------------|
| Digests | MD5, SHA-1 (signing), BLAKE2, SM3 |
| Digests | MD5, MD5-SHA1, SHA-1 (signing), BLAKE2, SM3 |
| Symmetric | DES, 3DES, ChaCha20, RC4 |
| Asymmetric | RSA < 2048, DSA, Ed25519/Ed448 |
| Key Exchange | X25519/X448, DH (MODP) |
| Curves | P-192 |

In a default FIPS build, wolfProvider registers MD5, MD5-SHA1, and
DES-EDE3-CBC (3DES), including their aliases, with `fips=yes`. Fetches and
metadata queries succeed, but cryptographic use raises an error. These entries
claim the names for rejection; they do not provide approved cryptographic
services. The MD5 restriction also applies to wolfProvider KDF paths.

Encrypted-key import is restricted to PBES2/PBKDF2 with AES-CBC and a SHA-based
PRF. Keys encrypted with DES/3DES, MD5-based password schemes, and traditional
encrypted PEM are rejected before decryption. Traditional encrypted PEM uses
MD5 for key derivation even when its cipher is AES.

A successful fetch is therefore not a capability check for these algorithms.
Configure applications for TLS 1.2 or later and exclude 3DES cipher suites.
Legacy TLS availability checks can accept the metadata and fail later when
the handshake attempts to use a denied algorithm.

Defining `WP_ALLOW_NON_FIPS` when building wolfProvider explicitly opts out of
these restrictions, provided the underlying wolfCrypt algorithms are compiled
in. This override is disabled by default and permits non-FIPS operations.

---

## Troubleshooting
Expand Down
3 changes: 3 additions & 0 deletions include/wolfprovider/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ int wp_encrypt_key_pkcs8(WOLFPROV_CTX* provCtx, int cipher,
OSSL_PASSPHRASE_CALLBACK* pwCb, void* pwCbArg);
int wp_decrypt_key_pkcs8(unsigned char* data, word32* len,
OSSL_PASSPHRASE_CALLBACK* pwCb, void* pwCbArg);
#ifdef WP_FIPS_DENY_LEGACY
int wp_check_fips_pkcs8(const unsigned char* data, word32 len);
#endif

int wp_read_der_bio(WOLFPROV_CTX* provCtx, OSSL_CORE_BIO *coreBio, unsigned char** data, word32* len);
int wp_read_pem_bio(WOLFPROV_CTX *provctx, OSSL_CORE_BIO *coreBio,
Expand Down
9 changes: 9 additions & 0 deletions include/wolfprovider/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@
#define WP_HAVE_PKCS8_ENC
#endif

/* This is the intended FIPS design: claim MD5, MD5-SHA1 and 3DES with
* fips=yes, return valid metadata, and fail loudly on attempts to use them.
* Do not drop legacy algorithm registration in FIPS builds, even when
* wolfCrypt compiles them out. WP_ALLOW_NON_FIPS is the explicit opt-in
* override. */
#if defined(HAVE_FIPS) && !defined(WP_ALLOW_NON_FIPS)
#define WP_FIPS_DENY_LEGACY
#endif

#define WP_HAVE_DIGEST
#if !defined(NO_MD5)
#define WP_HAVE_MD5
Expand Down
5 changes: 5 additions & 0 deletions src/wp_dec_epki2pki.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ static int wp_epki2pki_decode(wp_Epki2Pki* ctx, OSSL_CORE_BIO* coreBio,
if ((!done) && ok && !wp_epki2pki_is_epki(data, len)) {
done = 1;
}
#ifdef WP_FIPS_DENY_LEGACY
if ((!done) && ok && !wp_check_fips_pkcs8(data, len)) {
ok = 0;
}
#endif
if ((!done) && ok && ((pwCb == NULL) ||
(!pwCb(password, sizeof(password), &passwordLen, NULL,
pwCbArg)))) {
Expand Down
28 changes: 26 additions & 2 deletions src/wp_dec_pem2der.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ static int wp_pem2der_convert(const char* data, word32 len, DerBuffer** pDer,
const char* footer;
const char* base64Data;
size_t base64Len;
size_t i;

WOLFPROV_ENTER(WP_LOG_COMP_PK, "wp_pem2der_convert");

Expand All @@ -167,7 +168,14 @@ static int wp_pem2der_convert(const char* data, word32 len, DerBuffer** pDer,
if (ok) {
base64Data = data + 16 + nameLen + 1;
base64Len = len - (16 + nameLen + 1);
footer = XSTRSTR(base64Data, "-----END ");
/* Older wolfSSL builds do not export the XSTRNSTR helper. */
footer = NULL;
for (i = 0; (base64Len >= 9) && (i <= base64Len - 9); i++) {
if (XMEMCMP(base64Data + i, "-----END ", 9) == 0) {
footer = base64Data + i;
break;
}
}
if (footer == NULL) {
info->consumed = len;
ok = 0;
Expand Down Expand Up @@ -325,7 +333,7 @@ static int wp_pem2der_decode_data(const unsigned char* data, word32 len,
dataType = NULL;
obj = OSSL_OBJECT_PKEY;

#ifdef WOLFSSL_ENCRYPTED_KEYS
#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(WP_FIPS_DENY_LEGACY)
/* wc_PemToDer decrypts in place through the password callback. */
dataFormat = "PrivateKeyInfo";
info.passwd_cb = wp_pem_password_cb;
Expand All @@ -344,6 +352,22 @@ static int wp_pem2der_decode_data(const unsigned char* data, word32 len,
ok = 0;
}

#ifdef WP_FIPS_DENY_LEGACY
/* Traditional encrypted PEM derives its key with MD5, even for AES.
* Reject its encryption headers before wc_PemToDer can decrypt it. */
if (ok && (obj == OSSL_OBJECT_PKEY)) {
word32 i;
for (i = 0; i <= len - 8; i++) {
if (XMEMCMP(data + i, "DEK-Info", 8) == 0) {
ERR_raise_data(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED,
"Traditional encrypted PEM is disabled in FIPS mode");
ok = 0;
break;
}
}
}
#endif

if (ok && !done) {
/* Decode the PEM to DER using wolfSSL. */
rc = wc_PemToDer(data, len, type, &der, NULL, &info, &algoId);
Expand Down
Loading
Loading