- Register a callback with wolfCrypt_SetCb_fips to inform the user of errors in the wolfCrypt FIPS module
- Some API is not available when using FIPS. We need to allocate memory and initialize the structs directly.
Signed-off-by: Juliusz Sosinowicz <juliusz@xxxxxxxxxxx>
---
src/crypto/crypto_wolfssl.c | 30 +++++++++++++++++++++++++++++-
src/crypto/tls_wolfssl.c | 28 +++++++++++++++++++++++++++-
2 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/src/crypto/crypto_wolfssl.c b/src/crypto/crypto_wolfssl.c
index 336e59a0c6..7a5b410694 100644
--- a/src/crypto/crypto_wolfssl.c
+++ b/src/crypto/crypto_wolfssl.c
@@ -1736,7 +1736,7 @@ struct crypto_ecdh * crypto_ecdh_init(int group)
if (ret < 0)
goto fail;
-#ifdef ECC_TIMING_RESISTANT
+#if defined(ECC_TIMING_RESISTANT) && !defined(CONFIG_FIPS)
ret = wc_ecc_set_rng(&ecdh->ec->key, &ecdh->rng);
if (ret < 0)
goto fail;
@@ -1858,7 +1858,11 @@ static struct crypto_ec_key* crypto_ec_key_init(void)
wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_init starting");
key = os_zalloc(sizeof(struct crypto_ec_key));
if (key) {
+#ifndef CONFIG_FIPS
key->eckey = wc_ecc_key_new(NULL);
+#else
+ key->eckey = os_zalloc(sizeof(ecc_key));
+#endif
/* Omit key->rng initialization because it seeds itself and thus
* consumes entropy that may never be used. Lazy initialize when
* necessary. */
@@ -1867,6 +1871,13 @@ static struct crypto_ec_key* crypto_ec_key_init(void)
crypto_ec_key_deinit(key);
key = NULL;
}
+#ifdef CONFIG_FIPS
+ else if (wc_ecc_init_ex(key->eckey, NULL, INVALID_DEVID) != 0) {
+ wpa_printf(MSG_ERROR, "wolfSSL: wc_ecc_init_ex failed");
+ crypto_ec_key_deinit(key);
+ key = NULL;
+ }
+#endif
}
return key;
}
@@ -1875,8 +1886,15 @@ void crypto_ec_key_deinit(struct crypto_ec_key *key)
{
wpa_printf(MSG_DEBUG, "wolfSSL: crypto_ec_key_deinit starting");
if (key) {
+#ifndef CONFIG_FIPS
wc_rng_free(key->rng);
wc_ecc_key_free(key->eckey);
+#else
+ if (key->rng)
+ os_free(key->rng);
+ if (key->eckey)
+ os_free(key->eckey);
+#endif
os_free(key);
}
}
@@ -2037,11 +2055,21 @@ struct wpabuf * crypto_ec_key_sign(struct crypto_ec_key *key, const u8 *data,
if (!key->rng) {
/* Lazy init key->rng */
+#ifndef CONFIG_FIPS
key->rng = wc_rng_new(NULL, 0, NULL);
+#else
+ key->rng = os_zalloc(sizeof(WC_RNG));
+#endif
if (!key->rng) {
wpa_printf(MSG_ERROR, "wolfSSL: wc_rng_new failed");
goto fail;
}
+#ifdef CONFIG_FIPS
+ if (wc_InitRng(key->rng) != 0) {
+ wpa_printf(MSG_ERROR, "wolfSSL: wc_InitRng failed");
+ goto fail;
+ }
+#endif
}
derLen = wc_ecc_sig_size(key->eckey);
diff --git a/src/crypto/tls_wolfssl.c b/src/crypto/tls_wolfssl.c
index 04e1e0e810..91299befe9 100644
--- a/src/crypto/tls_wolfssl.c
+++ b/src/crypto/tls_wolfssl.c
@@ -26,6 +26,10 @@
#include <wolfssl/wolfcrypt/aes.h>
#endif
+#if defined(CONFIG_FIPS)
+#include <wolfssl/wolfcrypt/fips_test.h>
+#endif
+
#if !defined(CONFIG_FIPS) && \
(defined(EAP_FAST) || defined(EAP_FAST_DYNAMIC) || \
defined(EAP_SERVER_FAST))
@@ -191,6 +195,21 @@ static void remove_session_cb(WOLFSSL_CTX *ctx, WOLFSSL_SESSION *sess)
wolfSSL_SESSION_set_ex_data(sess, tls_ex_idx_session, NULL);
}
+#if defined(CONFIG_FIPS) && defined(HAVE_FIPS)
+static void wcFipsCb(int ok, int err, const char* hash)
+{
+ wpa_printf(MSG_ERROR, "wolfFIPS: wolfCrypt Fips error callback, ok = %d, "
+ "err = %d\n", ok, err);
+ wpa_printf(MSG_ERROR, "wolfFIPS: message = %s\n", wc_GetErrorString(err));
+ wpa_printf(MSG_ERROR, "wolfFIPS: hash = %s\n", hash);
+ if (err == IN_CORE_FIPS_E) {
+ wpa_printf(MSG_ERROR, "wolfFIPS: In core integrity hash check failure, "
+ "copy above hash\n");
+ wpa_printf(MSG_ERROR, "wolfFIPS: into verifyCore[] in fips_test.c and "
+ "rebuild\n");
+ }
+}
+#endif
#ifdef DEBUG_WOLFSSL
static void wolfSSL_logging_cb(const int log_level,
@@ -222,7 +241,9 @@ void * tls_init(const struct tls_config *conf)
if (wolfSSL_Init() < 0)
return NULL;
- /* wolfSSL_Debugging_ON(); */
+#if defined(CONFIG_FIPS) && defined(HAVE_FIPS)
+ wolfCrypt_SetCb_fips(wcFipsCb);
+#endif
}
tls_ref_count++;
@@ -2059,9 +2080,14 @@ int tls_connection_get_eap_fast_key(void *tls_ctx, struct tls_connection *conn,
_out, skip + out_len);
ret = 0;
} else {
+#ifndef CONFIG_FIPS
ret = tls_prf_sha1_md5(master_key, master_key_len,
"key expansion", seed, sizeof(seed),
_out, skip + out_len);
+#else
+ wpa_printf(MSG_ERROR, "wolfSSL: Can't use sha1_md5 in FIPS build");
+ ret = -1;
+#endif
}
forced_memzero(master_key, master_key_len);