[PATCH] RSN: Do not advertise MFPC=1 to an AP that does not support PMF

Xinping Zhang zhangxp1998 at gmail.com
Mon Oct 12 22:58:52 PDT 2026


From: Kelvin Zhang <zhangxp1998 at gmail.com>

When PMF is optional for a network (ieee80211w=1, or the global pmf=1
default that NetworkManager also uses), the STA advertises MFPC=1 in the
RSNE of the (Re)Association Request frame even if the selected AP does
not advertise MFPC=1. PMF cannot be negotiated with such an AP, so this
does not provide any benefit for the association.

It can, however, be harmful with deployed APs. A Comcast XB7 gateway
(Technicolor CGM4331COM, Broadcom based; WPA2-PSK without PMF, RSN
Capabilities 0x000c) acknowledges, but then silently discards, all
unprotected Block Ack Action frames from a STA that advertised MFPC=1.
The AP keeps sending a new unprotected ADDBA Request frame about once
per second, ignoring the STA's ADDBA Response frames, and it never
responds to ADDBA Request frames from the STA. As such, the AP never
completes the Block Ack agreements that the STA accepts, no agreement is
established for frames sent by the STA, and A-MPDU aggregation is not
used in either direction. On an 80 MHz HE link, this limited download
throughput to 26-65 Mbps while the same devices reached 350-466 Mbps
with ieee80211w=0. This was reproduced with rtw89, mt76, and iwlwifi
based STAs, and not advertising MFPC=1 was the only change needed to fix
it in all cases.

Not advertising MFPC=1 to such APs was proposed in 2014 ("[PATCH] Verify
MFPC/MFPR capability setting of WPA SM") and not accepted since MFPC
reflects the local dot11RSNAProtectedManagementFramesActivated value
rather than what the target AP advertises, and the AP issue in that case
could be worked around in a more targeted manner. That is not possible
here: the AP misbehavior is in Block Ack frame processing after the
association has been completed, wpa_supplicant cannot detect it, and the
only symptom is silently reduced throughput, so users have no indication
that ieee80211w=0 would help. Deciding per association whether optional
PMF is activated is a local policy choice, and wpa_supplicant already
adjusts the advertised PMF capability based on the selected BSS (MFPR=1
is forced on the 6 GHz band).

Treat optional PMF as disabled for an association with an AP that
advertises neither MFPC nor MFPR. This does not change the security
properties of the association since PMF could not be negotiated with the
AP anyway. Limit this to the case where the SME is in wpa_supplicant so
that the RSNE is generated for the selected BSS and is not reused by
driver-based roaming to an AP that might support PMF. Disable OCV in the
same case since it requires PMF.

Tested with an RTL8852CE (rtw89) STA against that AP (80 MHz HE, two
spatial streams, signal -27 dBm). Without this patch, the RSN
Capabilities field in the STA's RSNE was 0x008c (MFPC=1), none of the
eight ADDBA Request frames sent by the STA resulted in a Block Ack
agreement, and downloads ran at 53-57 Mbps. With this patch, the RSN
Capabilities field was 0x000c (MFPC=0), Block Ack agreements for TIDs 0
and 7 were established in both directions on the first attempt, and
downloads ran at 477-490 Mbps.

Signed-off-by: Kelvin Zhang <zhangxp1998 at gmail.com>
---
 tests/hwsim/test_ap_pmf.py      |  1 +
 wpa_supplicant/wpa_supplicant.c | 24 ++++++++++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/tests/hwsim/test_ap_pmf.py b/tests/hwsim/test_ap_pmf.py
index 06e93d4d2..da897d328 100644
--- a/tests/hwsim/test_ap_pmf.py
+++ b/tests/hwsim/test_ap_pmf.py
@@ -223,6 +223,7 @@ def test_ap_pmf_negative(dev, apdev):
                    key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
                    scan_freq="2412")
     hwsim_utils.test_connectivity(dev[0], hapd)
+    wt.require_sta_no_pmf(apdev[0]['bssid'], dev[0].own_addr())
     try:
         dev[1].connect(ssid, psk="12345678", ieee80211w="2",
                        key_mgmt="WPA-PSK WPA-PSK-SHA256", proto="WPA2",
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index aa455c204..d5075276d 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2611,6 +2611,30 @@ int wpa_supplicant_set_suites(struct
wpa_supplicant *wpa_s,
 	    (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_OCV))
 		wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, ssid->ocv);
 #endif /* CONFIG_OCV */
+
+	if (bss && proto == WPA_PROTO_RSN &&
+	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) &&
+	    !(ie.capabilities & (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) &&
+	    wpas_get_ssid_pmf(wpa_s, ssid) == MGMT_FRAME_PROTECTION_OPTIONAL) {
+		/*
+		 * PMF cannot be negotiated with an AP that does not advertise
+		 * MFPC=1, so advertising MFPC=1 would not provide any benefit
+		 * for this association. Some deployed APs do not handle that
+		 * correctly and silently discard unprotected Block Ack Action
+		 * frames from the STA, which prevents A-MPDU aggregation. The
+		 * RSNE is generated for the selected BSS when the SME is in
+		 * wpa_supplicant, so treat optional PMF as disabled for this
+		 * association instead.
+		 */
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"RSN: Selected AP does not support PMF - do not advertise MFPC");
+		wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_MFP,
+				 NO_MGMT_FRAME_PROTECTION);
+#ifdef CONFIG_OCV
+		/* OCV cannot be used without PMF */
+		wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, 0);
+#endif /* CONFIG_OCV */
+	}
 #ifdef CONFIG_SAE
 	sae_pwe = wpas_get_ssid_sae_pwe(wpa_s, ssid);
 	if ((ssid->sae_password_id ||
-- 
2.53.0



More information about the Hostap mailing list