* [PATCH v3 1/4] crypto: fips: add fips_exception kernel boot parameter and fips_allows_exception() helper
2026-10-09 6:54 [PATCH v3 0/4] wifi: add opt-in FIPS exception for iwlwifi Jose Ignacio Tornos Martinez
@ 2026-10-09 6:54 ` Jose Ignacio Tornos Martinez
2026-10-09 6:54 ` [PATCH v3 2/4] wifi: iwlwifi: enable MFP_CAPABLE in FIPS mode Jose Ignacio Tornos Martinez
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Jose Ignacio Tornos Martinez @ 2026-10-09 6:54 UTC (permalink / raw)
To: herbert, davem, johannes, miriam.rachel.korenblit
Cc: ilan.peer, emmanuel.grumbach, linux-crypto, linux-wireless,
linux-kernel, Jose Ignacio Tornos Martinez
Add a new kernel boot parameter fips_exception=<bitmap> to allow
documented exceptions to strict FIPS compliance when full compliance
is not achievable due to hardware/firmware limitations but
functionality is required.
The parameter is stored in a static variable and accessed through the
exported fips_allows_exception() helper function, which returns true
when FIPS is enabled and the requested exception bit is set. This
makes fips_allows_exception() an explicit "is this FIPS exception
active?" check, only meaningful when FIPS mode is on.
For !CONFIG_CRYPTO_FIPS, fips_allows_exception() is a trivial static
inline returning false (no FIPS means no FIPS exceptions).
The parameter is exposed as a read-only sysctl at
/proc/sys/crypto/fips_exception for runtime inspection. As with
fips_enabled, it is intentionally not writable at runtime so that
enabling exceptions requires a deliberate boot-time decision,
visible in /proc/cmdline.
The bitmap design allows individual subsystem exceptions to be
defined independently. Currently defined bits:
- Bit 0 (FIPS_EXCEPTION_WIFI_MFP): Allow WiFi MFP (802.11w)
in FIPS mode despite firmware sending some unprotected
management frames on TX
Without this parameter (or with fips_exception=0), all existing
FIPS restrictions remain in effect.
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v3: rename fips_allows() to fips_allows_exception(), change semantics
to fips_enabled && exception (was !fips_enabled || exception)
v2: https://lore.kernel.org/all/20260930120829.383408-2-jtornosm@redhat.com/
crypto/fips.c | 27 +++++++++++++++++++++++++++
include/linux/fips.h | 14 ++++++++++++++
2 files changed, 41 insertions(+)
diff --git a/crypto/fips.c b/crypto/fips.c
index c59711248d95..0f075e61a657 100644
--- a/crypto/fips.c
+++ b/crypto/fips.c
@@ -21,6 +21,15 @@ EXPORT_SYMBOL_GPL(fips_enabled);
ATOMIC_NOTIFIER_HEAD(fips_fail_notif_chain);
EXPORT_SYMBOL_GPL(fips_fail_notif_chain);
+static unsigned long fips_exception;
+
+int fips_allows_exception(unsigned long feature)
+{
+ return fips_enabled &&
+ (fips_exception & feature);
+}
+EXPORT_SYMBOL_GPL(fips_allows_exception);
+
/* Process kernel command-line parameter at boot time. fips=0 or fips=1 */
static int __init fips_enable(char *str)
{
@@ -34,6 +43,17 @@ static int __init fips_enable(char *str)
__setup("fips=", fips_enable);
+static int __init fips_exception_setup(char *str)
+{
+ if (kstrtoul(str, 0, &fips_exception))
+ return 0;
+
+ pr_info("fips exceptions: 0x%lx\n", fips_exception);
+ return 1;
+}
+
+__setup("fips_exception=", fips_exception_setup);
+
#define FIPS_MODULE_NAME CONFIG_CRYPTO_FIPS_NAME
#ifdef CONFIG_CRYPTO_FIPS_CUSTOM_VERSION
#define FIPS_MODULE_VERSION CONFIG_CRYPTO_FIPS_VERSION
@@ -52,6 +72,13 @@ static const struct ctl_table crypto_sysctl_table[] = {
.mode = 0444,
.proc_handler = proc_dointvec
},
+ {
+ .procname = "fips_exception",
+ .data = &fips_exception,
+ .maxlen = sizeof(unsigned long),
+ .mode = 0444,
+ .proc_handler = proc_doulongvec_minmax
+ },
{
.procname = "fips_name",
.data = &fips_name,
diff --git a/include/linux/fips.h b/include/linux/fips.h
index c6961e932fef..61fe58b0762c 100644
--- a/include/linux/fips.h
+++ b/include/linux/fips.h
@@ -2,17 +2,31 @@
#ifndef _FIPS_H
#define _FIPS_H
+#include <linux/bits.h>
+
#ifdef CONFIG_CRYPTO_FIPS
extern int fips_enabled;
extern struct atomic_notifier_head fips_fail_notif_chain;
void fips_fail_notify(void);
+/*
+ * fips_allows_exception - check if a FIPS exception is active
+ * Returns true when FIPS is enabled and the requested exception
+ * bit is set via the fips_exception= boot parameter.
+ */
+int fips_allows_exception(unsigned long feature);
#else
#define fips_enabled 0
static inline void fips_fail_notify(void) {}
+static inline int fips_allows_exception(unsigned long feature)
+{
+ return 0;
+}
#endif
+#define FIPS_EXCEPTION_WIFI_MFP BIT(0)
+
#endif
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v3 2/4] wifi: iwlwifi: enable MFP_CAPABLE in FIPS mode
2026-10-09 6:54 [PATCH v3 0/4] wifi: add opt-in FIPS exception for iwlwifi Jose Ignacio Tornos Martinez
2026-10-09 6:54 ` [PATCH v3 1/4] crypto: fips: add fips_exception kernel boot parameter and fips_allows_exception() helper Jose Ignacio Tornos Martinez
@ 2026-10-09 6:54 ` Jose Ignacio Tornos Martinez
2026-10-09 6:54 ` [PATCH v3 3/4] wifi: iwlwifi: fix RX AMPDU and A-MSDU " Jose Ignacio Tornos Martinez
2026-10-09 6:54 ` [PATCH v3 4/4] wifi: iwlwifi: reduce encryption error message to debug level " Jose Ignacio Tornos Martinez
3 siblings, 0 replies; 5+ messages in thread
From: Jose Ignacio Tornos Martinez @ 2026-10-09 6:54 UTC (permalink / raw)
To: herbert, davem, johannes, miriam.rachel.korenblit
Cc: ilan.peer, emmanuel.grumbach, linux-crypto, linux-wireless,
linux-kernel, Jose Ignacio Tornos Martinez
Re-enable MFP_CAPABLE flag in FIPS mode for iwlwifi to allow Management
Frame Protection (802.11w) to work with mac80211 software crypto.
Commit 0636800c8ee1f ("wifi: iwlwifi: disable certain features for
fips_enabled") disabled MFP_CAPABLE when fips_enabled=1.
The original concern about "some frames need to be handled in
firmware" applies to firmware-offloaded features like WoWLAN and beacon
protection, which remain correctly disabled by the commented commit.
For normal STA mode operation, management frames are processed in
software. And MFP can function in FIPS mode for normal STA operation
when mac80211 software crypto handles IGTK encryption/decryption using
FIPS-approved AES-CMAC/GMAC algorithms.
Other major WiFi drivers (ath11k, rtlwifi, mt76, ...) set MFP_CAPABLE
unconditionally, suggesting this approach is viable for FIPS mode
operation with software crypto.
When FIPS_EXCEPTION_WIFI_MFP is set via the fips_exception boot
parameter, use fips_allows_exception() to restore MFP_CAPABLE.
Without fips_exception set, the behavior remains exactly as commit
0636800c8ee1 implemented.
Testing on Intel WiFi 6E AX210 with fips=1 fips_exception=1 shows:
- IGTK ciphers (CMAC, GMAC-128, GMAC-256) are properly advertised
- WPA3-SAE connections with MFP required succeed
- iw station dump confirms "MFP: yes"
Firmware logs "Unhandled alg: 0x707" (SEC_ENC_ERR) during operation,
confirming that firmware does not have the keys and frames are being
handled by software crypto as expected.
Fixes: 0636800c8ee1f ("wifi: iwlwifi: disable certain features for fips_enabled")
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v3: reuse v1 1/2 idea plus fips_allows_exception() helper from patch 1/4
v2: https://lore.kernel.org/all/20260930120829.383408-1-jtornosm@redhat.com/
v1: https://lore.kernel.org/all/20260629121213.597038-2-jtornosm@redhat.com/
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 5bd246e37943..144a19a4015c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -462,7 +462,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
IWL_ERR(mvm,
"iwlmvm doesn't allow to disable BT Coex, check bt_coex_active module parameter\n");
- if (!fips_enabled)
+ if (!fips_enabled || fips_allows_exception(FIPS_EXCEPTION_WIFI_MFP))
ieee80211_hw_set(hw, MFP_CAPABLE);
mvm->ciphers[hw->wiphy->n_cipher_suites] = WLAN_CIPHER_SUITE_AES_CMAC;
--
2.49.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v3 3/4] wifi: iwlwifi: fix RX AMPDU and A-MSDU in FIPS mode
2026-10-09 6:54 [PATCH v3 0/4] wifi: add opt-in FIPS exception for iwlwifi Jose Ignacio Tornos Martinez
2026-10-09 6:54 ` [PATCH v3 1/4] crypto: fips: add fips_exception kernel boot parameter and fips_allows_exception() helper Jose Ignacio Tornos Martinez
2026-10-09 6:54 ` [PATCH v3 2/4] wifi: iwlwifi: enable MFP_CAPABLE in FIPS mode Jose Ignacio Tornos Martinez
@ 2026-10-09 6:54 ` Jose Ignacio Tornos Martinez
2026-10-09 6:54 ` [PATCH v3 4/4] wifi: iwlwifi: reduce encryption error message to debug level " Jose Ignacio Tornos Martinez
3 siblings, 0 replies; 5+ messages in thread
From: Jose Ignacio Tornos Martinez @ 2026-10-09 6:54 UTC (permalink / raw)
To: herbert, davem, johannes, miriam.rachel.korenblit
Cc: ilan.peer, emmanuel.grumbach, linux-crypto, linux-wireless,
linux-kernel, Jose Ignacio Tornos Martinez
In FIPS mode with the WiFi MFP exception active, firmware has no
encryption keys installed (mac80211 handles all crypto in software).
This causes two RX-path issues that severely limit downlink
throughput:
1) Firmware reports SEC_UNKNOWN for all received data frames because
it has no keys to decrypt them. iwl_mvm_rx_crypto() drops these
frames when they arrive inside an AMPDU, mistaking them for a
security error. In FIPS SW-crypto mode this is expected -- the
frames are encrypted and will be decrypted by mac80211. Skip
the drop when the FIPS exception is active, same as already done
for monitor mode.
2) Firmware clears the A-MSDU present bit in the QoS header for
frames it processes. When firmware has no keys, it still strips
this bit even though it cannot de-aggregate the A-MSDU. mac80211
then treats the A-MSDU as a regular MSDU, delivering a malformed
frame. Preserve the A-MSDU bit when the FIPS exception is active
so mac80211 can properly de-aggregate after SW decryption.
Without these fixes (in my scenario), RX throughput is limited to
non-aggregated rates (~25 Mbps). With both fixes, RX AMPDU works
normally and throughput reaches ~450 Mbps.
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v3: new
v2: https://lore.kernel.org/all/20260930120829.383408-1-jtornosm@redhat.com/
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 7f0b4f5daa21..1ebca0323a89 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -5,6 +5,7 @@
* Copyright (C) 2015-2017 Intel Deutschland GmbH
*/
#include <linux/etherdevice.h>
+#include <linux/fips.h>
#include <linux/skbuff.h>
#include "iwl-trans.h"
#include "mvm.h"
@@ -421,14 +422,15 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
/*
* Drop UNKNOWN frames in aggregation, unless in monitor mode
- * (where we don't have the keys).
+ * (where we don't have the keys) or FIPS SW-crypto mode.
* We limit this to aggregation because in TKIP this is a valid
* scenario, since we may not have the (correct) TTAK (phase 1
* key) in the firmware.
*/
if (phy_info & IWL_RX_MPDU_PHY_AMPDU &&
(status & IWL_RX_MPDU_STATUS_SEC_MASK) ==
- IWL_RX_MPDU_STATUS_SEC_UNKNOWN && !mvm->monitor_on) {
+ IWL_RX_MPDU_STATUS_SEC_UNKNOWN && !mvm->monitor_on &&
+ !fips_allows_exception(FIPS_EXCEPTION_WIFI_MFP)) {
IWL_DEBUG_DROP(mvm, "Dropping packets, bad enc status\n");
return -1;
}
@@ -2357,7 +2359,8 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
!WARN_ON(!ieee80211_is_data_qos(hdr->frame_control))) {
u8 *qc = ieee80211_get_qos_ctl(hdr);
- *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
+ if (!fips_allows_exception(FIPS_EXCEPTION_WIFI_MFP))
+ *qc &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT;
if (mvm->trans->mac_cfg->device_family ==
IWL_DEVICE_FAMILY_9000) {
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH v3 4/4] wifi: iwlwifi: reduce encryption error message to debug level in FIPS mode
2026-10-09 6:54 [PATCH v3 0/4] wifi: add opt-in FIPS exception for iwlwifi Jose Ignacio Tornos Martinez
` (2 preceding siblings ...)
2026-10-09 6:54 ` [PATCH v3 3/4] wifi: iwlwifi: fix RX AMPDU and A-MSDU " Jose Ignacio Tornos Martinez
@ 2026-10-09 6:54 ` Jose Ignacio Tornos Martinez
3 siblings, 0 replies; 5+ messages in thread
From: Jose Ignacio Tornos Martinez @ 2026-10-09 6:54 UTC (permalink / raw)
To: herbert, davem, johannes, miriam.rachel.korenblit
Cc: ilan.peer, emmanuel.grumbach, linux-crypto, linux-wireless,
linux-kernel, Jose Ignacio Tornos Martinez
In FIPS mode, the firmware may report
RX_MPDU_RES_STATUS_SEC_ENC_ERR (0x707) for frames received
before keys are installed. This triggers the warning:
"iwlwifi: Unhandled alg: 0x707"
This is expected behavior -- mac80211 software crypto handles
decryption on the host CPU. Reduce the message from IWL_WARN to
IWL_DEBUG_RX in FIPS mode to avoid false-positive warnings
during normal operation, while preserving warnings for actual
unexpected conditions.
Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
---
v3: No modification
v2: https://lore.kernel.org/all/20260930120829.383408-6-jtornosm@redhat.com/
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 1ebca0323a89..e59876b7a1fa 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -496,6 +496,14 @@ static int iwl_mvm_rx_crypto(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
return 0;
case RX_MPDU_RES_STATUS_SEC_CMAC_GMAC_ENC:
break;
+ case RX_MPDU_RES_STATUS_SEC_ENC_ERR:
+ if (fips_enabled) {
+ IWL_DEBUG_RX(mvm,
+ "FIPS mode: firmware cannot decrypt, status: 0x%x\n",
+ status);
+ break;
+ }
+ fallthrough;
default:
/*
* Sometimes we can get frames that were not decrypted
--
2.55.0
^ permalink raw reply [flat|nested] 5+ messages in thread