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>
This commit is contained in:
parent
ac54b61273
commit
07a7bcd7ea
8 changed files with 32 additions and 5 deletions
|
@ -4560,6 +4560,9 @@ int wpa_sm_set_param(struct wpa_sm *sm, enum wpa_sm_conf_params param,
|
||||||
sm->dpp_pfs = value;
|
sm->dpp_pfs = value;
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_DPP2 */
|
#endif /* CONFIG_DPP2 */
|
||||||
|
case WPA_PARAM_WMM_ENABLED:
|
||||||
|
sm->wmm_enabled = value;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,7 @@ enum wpa_sm_conf_params {
|
||||||
WPA_PARAM_USE_EXT_KEY_ID,
|
WPA_PARAM_USE_EXT_KEY_ID,
|
||||||
WPA_PARAM_FT_RSNXE_USED,
|
WPA_PARAM_FT_RSNXE_USED,
|
||||||
WPA_PARAM_DPP_PFS,
|
WPA_PARAM_DPP_PFS,
|
||||||
|
WPA_PARAM_WMM_ENABLED,
|
||||||
WPA_PARAM_OCI_FREQ_EAPOL,
|
WPA_PARAM_OCI_FREQ_EAPOL,
|
||||||
WPA_PARAM_OCI_FREQ_EAPOL_G2,
|
WPA_PARAM_OCI_FREQ_EAPOL_G2,
|
||||||
WPA_PARAM_OCI_FREQ_FT_ASSOC,
|
WPA_PARAM_OCI_FREQ_FT_ASSOC,
|
||||||
|
|
|
@ -220,6 +220,8 @@ struct wpa_sm {
|
||||||
int dpp_pfs;
|
int dpp_pfs;
|
||||||
#endif /* CONFIG_DPP2 */
|
#endif /* CONFIG_DPP2 */
|
||||||
struct wpa_sm_mlo mlo;
|
struct wpa_sm_mlo mlo;
|
||||||
|
|
||||||
|
bool wmm_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,10 @@ u16 rsn_supp_capab(struct wpa_sm *sm)
|
||||||
{
|
{
|
||||||
u16 capab = 0;
|
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)
|
if (sm->mfp)
|
||||||
capab |= WPA_CAPABILITY_MFPC;
|
capab |= WPA_CAPABILITY_MFPC;
|
||||||
if (sm->mfp == 2)
|
if (sm->mfp == 2)
|
||||||
|
|
|
@ -1533,7 +1533,7 @@ def eapol_test(apdev, dev, wpa2=True, ieee80211w=0):
|
||||||
if ieee80211w == 2:
|
if ieee80211w == 2:
|
||||||
rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac02cc00')
|
rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac02cc00')
|
||||||
else:
|
else:
|
||||||
rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac020000')
|
rsne = binascii.unhexlify('30140100000fac040100000fac040100000fac020c00')
|
||||||
else:
|
else:
|
||||||
rsne = binascii.unhexlify('dd160050f20101000050f20201000050f20201000050f202')
|
rsne = binascii.unhexlify('dd160050f20101000050f20201000050f20201000050f202')
|
||||||
snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111')
|
snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111')
|
||||||
|
|
|
@ -388,9 +388,9 @@ class APConnection:
|
||||||
pmk = binascii.unhexlify("c2c6c255af836bed1b3f2f1ded98e052f5ad618bb554e2836757b55854a0eab7")
|
pmk = binascii.unhexlify("c2c6c255af836bed1b3f2f1ded98e052f5ad618bb554e2836757b55854a0eab7")
|
||||||
|
|
||||||
if sta_ocv != "0":
|
if sta_ocv != "0":
|
||||||
self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac0280400000000fac06")
|
self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac028c400000000fac06")
|
||||||
else:
|
else:
|
||||||
self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac0280000000000fac06")
|
self.rsne = binascii.unhexlify("301a0100000fac040100000fac040100000fac028c000000000fac06")
|
||||||
self.snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111')
|
self.snonce = binascii.unhexlify('1111111111111111111111111111111111111111111111111111111111111111')
|
||||||
|
|
||||||
dev.connect(self.ssid, raw_psk=self.psk, scan_freq=freq, ocv=sta_ocv,
|
dev.connect(self.ssid, raw_psk=self.psk, scan_freq=freq, ocv=sta_ocv,
|
||||||
|
|
|
@ -2370,7 +2370,7 @@ def test_sae_rsne_mismatch(dev, apdev):
|
||||||
|
|
||||||
# First, test with matching RSNE to confirm testing capability
|
# First, test with matching RSNE to confirm testing capability
|
||||||
dev[0].set("rsne_override_eapol",
|
dev[0].set("rsne_override_eapol",
|
||||||
"30140100000fac040100000fac040100000fac080000")
|
"30140100000fac040100000fac040100000fac080c00")
|
||||||
dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
|
dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
|
||||||
scan_freq="2412")
|
scan_freq="2412")
|
||||||
dev[0].request("REMOVE_NETWORK all")
|
dev[0].request("REMOVE_NETWORK all")
|
||||||
|
@ -2378,7 +2378,7 @@ def test_sae_rsne_mismatch(dev, apdev):
|
||||||
dev[0].dump_monitor()
|
dev[0].dump_monitor()
|
||||||
|
|
||||||
# Then, test with modified RSNE
|
# Then, test with modified RSNE
|
||||||
tests = ["30140100000fac040100000fac040100000fac080010", "0000"]
|
tests = ["30140100000fac040100000fac040100000fac080c10", "0000"]
|
||||||
for ie in tests:
|
for ie in tests:
|
||||||
dev[0].set("rsne_override_eapol", ie)
|
dev[0].set("rsne_override_eapol", ie)
|
||||||
dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
|
dev[0].connect("sae-pwe", psk="12345678", key_mgmt="SAE",
|
||||||
|
|
|
@ -1582,6 +1582,7 @@ int wpa_supplicant_set_suites(struct wpa_supplicant *wpa_s,
|
||||||
int sel, proto;
|
int sel, proto;
|
||||||
enum sae_pwe sae_pwe;
|
enum sae_pwe sae_pwe;
|
||||||
const u8 *bss_wpa, *bss_rsn, *bss_rsnx, *bss_osen;
|
const u8 *bss_wpa, *bss_rsn, *bss_rsnx, *bss_osen;
|
||||||
|
bool wmm;
|
||||||
|
|
||||||
if (bss) {
|
if (bss) {
|
||||||
bss_wpa = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
|
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);
|
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 (!skip_default_rsne) {
|
||||||
if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie,
|
if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie,
|
||||||
wpa_ie_len)) {
|
wpa_ie_len)) {
|
||||||
|
|
Loading…
Reference in a new issue