]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WMM: Advertise support for 16 PTKSA replay counters for non-AP STA
authorJouni Malinen <quic_jouni@quicinc.com>
Wed, 12 Apr 2023 15:46:53 +0000 (18:46 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 18 Apr 2023 08:40:10 +0000 (11:40 +0300)
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>
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_i.h
src/rsn_supp/wpa_ie.c
tests/hwsim/test_ap_psk.py
tests/hwsim/test_ocv.py
tests/hwsim/test_sae.py
wpa_supplicant/wpa_supplicant.c

index 2b3349d8cbe0cfb4a83f09fe2f88c6867f578a6d..9c7c526fc0d64220ce301fcf79304fe8a12279c9 100644 (file)
@@ -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;
        }
index 76d6031380c8cc646ce50304f280b6cd6270982d..b3c8b6a7de8e020bf2abb790f3c006751fbcd002 100644 (file)
@@ -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,
index a3c13b116b114680c5cf15a88c50ca72d0ace5f0..300ef547d2550a5cb1f2accde553f2877fc99910 100644 (file)
@@ -220,6 +220,8 @@ struct wpa_sm {
        int dpp_pfs;
 #endif /* CONFIG_DPP2 */
        struct wpa_sm_mlo mlo;
+
+       bool wmm_enabled;
 };
 
 
index 50bd2b276e83fb90ae9a3b815cc35d05b3092304..2a6c79b2639a986410da66f9b6029e7043f69d67 100644 (file)
@@ -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)
index b035c6ee2fccf12ad1503457699c3bb57e48dd23..aac104bb7cd697ea0cb368a8418eaafdba00ec18 100644 (file)
@@ -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')
index 20f6600a9d3cf44033eba98828eeef15ea0736ae..cf19eeaf0696ff3eeefc400cef83b72c84f4d5f9 100644 (file)
@@ -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,
index f330ce3958a90fbdb23c50287f629e9b668541ca..ff58598b009e95d2a8150328da932ebf24242813 100644 (file)
@@ -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",
index 93629e1f76ff8e65e034ccfe8202127a8a7bf2ef..651c0ce9e208127494455a91e8f5adfcdfdae946 100644 (file)
@@ -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)) {