diff options
author | Jouni Malinen <quic_jouni@quicinc.com> | 2023-04-12 18:46:53 +0300 |
---|---|---|
committer | Jouni Malinen <j@w1.fi> | 2023-04-18 11:40:10 +0300 |
commit | 07a7bcd7eab748f924dabe7b6ae8e0edecad7586 (patch) | |
tree | eb7380ec33f0b666120578cbbfee62796f093ebf | |
parent | ac54b612739751c4d9548cca9ce86aa670477279 (diff) | |
download | hostap-07a7bcd7eab748f924dabe7b6ae8e0edecad7586.tar.gz |
WMM: Advertise support for 16 PTKSA replay counters for non-AP STA
In theory, each device that supports WMM (or the IEEE 802.11 QoS for
that matter) is expected to advertise how many replay counters it
supports and the peer device is supposed to use that information to
restrict the total number of different MSDU priorities (AC/UP) that
might be used. In practice, this is not really done in deployed devices
and instead, it is just assumed that everyone supports the eight
different replay counters so that there is no need to restrict which
MSDU priorities can be used.
hostapd implementation of WMM has advertised support for 16 PTKSA replay
counters from the beginning while wpa_supplicant has not had any code
for setting the supported replay counter fields in RSNE, i.e., has left
the value to 0 which implies that only a single replay counter is
supported. While this does not really result in any real issues with
deployed devices, this is not really correct behavior based on the
current IEEE 802.11 standard and the WMM specification.
Update wpa_supplicant to use similar design to the hostapd RSNE
generation by setting the number of supported PTKSA replay counters to
16 whenever WMM is enabled. For now, this is done based on the
association being for HT/VHT/HE/EHT and also based on the AP supporting
WMM since it is much more likely for the local device to support WMM and
eight replay counters (which can be indicated only with the value that
implies support for 16 counters since there is no separate value for 8).
Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
-rw-r--r-- | src/rsn_supp/wpa.c | 3 | ||||
-rw-r--r-- | src/rsn_supp/wpa.h | 1 | ||||
-rw-r--r-- | src/rsn_supp/wpa_i.h | 2 | ||||
-rw-r--r-- | src/rsn_supp/wpa_ie.c | 4 | ||||
-rw-r--r-- | tests/hwsim/test_ap_psk.py | 2 | ||||
-rw-r--r-- | tests/hwsim/test_ocv.py | 4 | ||||
-rw-r--r-- | tests/hwsim/test_sae.py | 4 | ||||
-rw-r--r-- | wpa_supplicant/wpa_supplicant.c | 17 |
8 files changed, 32 insertions, 5 deletions
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)) { |