diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 2b3349d8c..9c7c526fc 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -4560,6 +4560,9 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param, sm->dpp_pfs = value; break; #endif /* CONFIG_DPP2 */ + case WPA_PARAM_WMM_ENABLED: + sm->wmm_enabled = value; + break; default: break; } diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 76d603138..b3c8b6a7d 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -123,6 +123,7 @@ enum wpa_sm_conf_params { WPA_PARAM_USE_EXT_KEY_ID, WPA_PARAM_FT_RSNXE_USED, WPA_PARAM_DPP_PFS, + WPA_PARAM_WMM_ENABLED, WPA_PARAM_OCI_FREQ_EAPOL, WPA_PARAM_OCI_FREQ_EAPOL_G2, WPA_PARAM_OCI_FREQ_FT_ASSOC, diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index a3c13b116..300ef547d 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -220,6 +220,8 @@ struct wpa_sm { int dpp_pfs; #endif /* CONFIG_DPP2 */ struct wpa_sm_mlo mlo; + + bool wmm_enabled; }; diff --git a/src/rsn_supp/wpa_ie.c b/src/rsn_supp/wpa_ie.c index 50bd2b276..2a6c79b26 100644 --- a/src/rsn_supp/wpa_ie.c +++ b/src/rsn_supp/wpa_ie.c @@ -109,6 +109,10 @@ u16 rsn_supp_capab(struct wpa_sm *sm) { u16 capab = 0; + if (sm->wmm_enabled) { + /* Advertise 16 PTKSA replay counters when using WMM */ + capab |= RSN_NUM_REPLAY_COUNTERS_16 << 2; + } if (sm->mfp) capab |= WPA_CAPABILITY_MFPC; if (sm->mfp == 2) diff --git a/tests/hwsim/test_ap_psk.py b/tests/hwsim/test_ap_psk.py index b035c6ee2..aac104bb7 100644 --- a/tests/hwsim/test_ap_psk.py +++ b/tests/hwsim/test_ap_psk.py @@ -1533,7 +1533,7 @@ def eapol_test(apdev, dev, wpa2=True, ieee80211w=0): if ieee80211w == 2: rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac02cc00') else: - rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac020000') + rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00') else: rsne = binascii.unhexlify('dd160050f20101000050f20201000050f20201000050f202') snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111') diff --git a/tests/hwsim/test_ocv.py b/tests/hwsim/test_ocv.py index 20f6600a9..cf19eeaf0 100644 --- a/tests/hwsim/test_ocv.py +++ b/tests/hwsim/test_ocv.py @@ -388,9 +388,9 @@ class APConnection: pmk = binascii.unhexlify("c2c6c255af836bed1b3f2f1ded98e052f5ad618bb554e2836757b55854a0eab7") if sta_ocv != "0": - self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac0280400000000fac06") + self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac028c400000000fac06") else: - self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac0280000000000fac06") + self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac028c000000000fac06") self.snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111') dev.connect(self.ssid, raw_psk=self.psk, scan_freq=freq, ocv=sta_ocv, diff --git a/tests/hwsim/test_sae.py b/tests/hwsim/test_sae.py index f330ce395..ff58598b0 100644 --- a/tests/hwsim/test_sae.py +++ b/tests/hwsim/test_sae.py @@ -2370,7 +2370,7 @@ def test_sae_rsne_mismatch(dev, apdev): # First, test with matching RSNE to confirm testing capability dev[0].set("rsne_override_eapol", - "30140100000fac040100000fac040100000fac080000") + "30140100000fac040100000fac040100000fac080c00") dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", scan_freq="2412") dev[0].request("REMOVE_NETWORK all") @@ -2378,7 +2378,7 @@ def test_sae_rsne_mismatch(dev, apdev): dev[0].dump_monitor() # Then, test with modified RSNE - tests = ["30140100000fac040100000fac040100000fac080010", "0000"] + tests = ["30140100000fac040100000fac040100000fac080c10", "0000"] for ie in tests: dev[0].set("rsne_override_eapol", ie) dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE", diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 93629e1f7..651c0ce9e 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1582,6 +1582,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, int sel, proto; enum sae_pwe sae_pwe; const u8 *bss_wpa, *bss_rsn, *bss_rsnx, *bss_osen; + bool wmm; if (bss) { bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE); @@ -1978,6 +1979,22 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s, wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_USE_EXT_KEY_ID, 0); } + /* Mark WMM enabled for any HT/VHT/HE/EHT association to get more + * appropriate advertisement of the supported number of PTKSA receive + * counters. In theory, this could be based on a driver capability, but + * in practice all cases using WMM support at least eight replay + * counters, so use a hardcoded value for now since there is no explicit + * driver capability indication for this. + * + * In addition, claim WMM to be enabled if the AP supports it since it + * is far more likely for any current device to support WMM. */ + wmm = wpa_s->connection_set && + (wpa_s->connection_ht || wpa_s->connection_vht || + wpa_s->connection_he || wpa_s->connection_eht); + if (!wmm && bss) + wmm = wpa_bss_get_vendor_ie(bss, WMM_IE_VENDOR_TYPE); + wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_WMM_ENABLED, wmm); + if (!skip_default_rsne) { if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {