]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
wlantest: Use AP's RSNXOE for capabilities when RSNO is used
authorJouni Malinen <quic_jouni@quicinc.com>
Wed, 20 Nov 2024 10:30:05 +0000 (12:30 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 20 Nov 2024 10:30:05 +0000 (12:30 +0200)
If an association uses RSN overriding and the AP advertises an RSNXOE,
use the RSNXOE instead of the RSNXE when determining AP's RSN
capabilities. In particular, this is needed to determine the correct KDK
length for PTK derivation in a case where the RSNXOE advertises support
for secure ranging while the RSNXE does not.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/common/ieee802_11_common.c
src/common/ieee802_11_common.h
wlantest/rx_eapol.c
wlantest/rx_mgmt.c
wlantest/wlantest.h

index e859fbe211230dfac193031f696a8c0605b0ac39..f8e85296167099f124e17c74f1f433858db54ae6 100644 (file)
@@ -152,6 +152,10 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen,
                        elems->rsne_override_2 = pos;
                        elems->rsne_override_2_len = elen;
                        break;
+               case WFA_RSNXE_OVERRIDE_OUI_TYPE:
+                       elems->rsnxe_override = pos;
+                       elems->rsnxe_override_len = elen;
+                       break;
                case WFA_RSN_SELECTION_OUI_TYPE:
                        if (elen < 4 + 1) {
                                wpa_printf(MSG_DEBUG,
index 689a8f889d35378c66c11f01f02c9127814a65ea..e22138c7d72fc15136b2d52b678f7120bef8748b 100644 (file)
@@ -120,6 +120,7 @@ struct ieee802_11_elems {
        const u8 *mbssid;
        const u8 *rsne_override;
        const u8 *rsne_override_2;
+       const u8 *rsnxe_override;
        const u8 *rsn_selection;
        const u8 *wfa_capab;
 
@@ -189,6 +190,7 @@ struct ieee802_11_elems {
        u8 mbssid_len;
        size_t rsne_override_len;
        size_t rsne_override_2_len;
+       size_t rsnxe_override_len;
        size_t rsn_selection_len;
        u8 wfa_capab_len;
 
index 51b7c42fa851941c107b6a240260a54ad606c1f7..b2427279482502fcf20bcc9ae66510254de12078 100644 (file)
@@ -183,13 +183,24 @@ static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
        const u8 *sa, *aa;
        bool mlo;
        size_t kdk_len;
+       const u8 *rsnxe;
+       size_t rsnxe_len;
 
        mlo = !is_zero_ether_addr(sta->mld_mac_addr) &&
                !is_zero_ether_addr(bss->mld_mac_addr);
        sa = mlo ? sta->mld_mac_addr : sta->addr;
        aa = mlo ? bss->mld_mac_addr : bss->bssid;
 
-       if (ieee802_11_rsnx_capab_len(bss->rsnxe, bss->rsnxe_len,
+       if ((sta->rsn_selection == RSN_SELECTION_RSNE_OVERRIDE ||
+            sta->rsn_selection == RSN_SELECTION_RSNE_OVERRIDE_2) &&
+           bss->rsnxoe_len) {
+               rsnxe = bss->rsnxoe;
+               rsnxe_len = bss->rsnxoe_len;
+       } else {
+               rsnxe = bss->rsnxe;
+               rsnxe_len = bss->rsnxe_len;
+       }
+       if (ieee802_11_rsnx_capab_len(rsnxe, rsnxe_len,
                                      WLAN_RSNX_CAPAB_SECURE_LTF) &&
            ieee802_11_rsnx_capab_len(sta->rsnxe, sta->rsnxe_len,
                                      WLAN_RSNX_CAPAB_SECURE_LTF))
index ecb56e2c91ab8532a693cadb5215e8da8522c8a5..0f00a883499ff09ddfe6c513979c4a9d498630c9 100644 (file)
@@ -437,6 +437,14 @@ static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len)
                bss->rsnxe_len = 0;
        }
 
+       if (elems.rsnxe_override) {
+               os_memcpy(bss->rsnxoe, elems.rsnxe_override + 4,
+                         elems.rsnxe_override_len - 4);
+               bss->rsnxoe_len = elems.rsnxe_override_len;
+       } else {
+               bss->rsnxoe_len = 0;
+       }
+
        if (!bss->proberesp_seen)
                bss_update(wt, bss, &elems, 1);
 
@@ -535,6 +543,11 @@ static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len)
                                merged.rsnxe = m_elems.rsnxe;
                                merged.rsnxe_len = m_elems.rsnxe_len;
                        }
+                       if (m_elems.rsnxe_override) {
+                               merged.rsnxe_override = m_elems.rsnxe_override;
+                               merged.rsnxe_override_len =
+                                       m_elems.rsnxe_override_len;
+                       }
 
                        if (merged.rsnxe) {
                                os_memcpy(m_bss->rsnxe, merged.rsnxe,
@@ -544,6 +557,16 @@ static void rx_mgmt_beacon(struct wlantest *wt, const u8 *data, size_t len)
                                m_bss->rsnxe_len = 0;
                        }
 
+                       if (merged.rsnxe_override) {
+                               os_memcpy(m_bss->rsnxoe,
+                                         merged.rsnxe_override + 4,
+                                         merged.rsnxe_override_len - 4);
+                               m_bss->rsnxoe_len =
+                                       merged.rsnxe_override_len - 4;
+                       } else {
+                               m_bss->rsnxoe_len = 0;
+                       }
+
                        if (!m_bss->proberesp_seen)
                                bss_update(wt, m_bss, &merged, 1);
                }
@@ -706,6 +729,8 @@ static void process_ft_auth(struct wlantest *wt, struct wlantest_bss *bss,
        struct ieee802_11_elems elems;
        const u8 *ie;
        size_t ie_len, kdk_len;
+       const u8 *rsnxe;
+       size_t rsnxe_len;
 
        if (sta->auth_alg != WLAN_AUTH_FT ||
            len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth))
@@ -785,7 +810,16 @@ static void process_ft_auth(struct wlantest *wt, struct wlantest_bss *bss,
                goto out;
        sta->pmk_r1_len = sta->pmk_r0_len;
 
-       if (ieee802_11_rsnx_capab_len(bss->rsnxe, bss->rsnxe_len,
+       if ((sta->rsn_selection == RSN_SELECTION_RSNE_OVERRIDE ||
+            sta->rsn_selection == RSN_SELECTION_RSNE_OVERRIDE_2) &&
+           bss->rsnxoe_len) {
+               rsnxe = bss->rsnxoe;
+               rsnxe_len = bss->rsnxoe_len;
+       } else {
+               rsnxe = bss->rsnxe;
+               rsnxe_len = bss->rsnxe_len;
+       }
+       if (ieee802_11_rsnx_capab_len(rsnxe, rsnxe_len,
                                      WLAN_RSNX_CAPAB_SECURE_LTF) &&
            ieee802_11_rsnx_capab_len(sta->rsnxe, sta->rsnxe_len,
                                      WLAN_RSNX_CAPAB_SECURE_LTF))
@@ -1195,6 +1229,14 @@ static void rx_mgmt_assoc_req(struct wlantest *wt, const u8 *data, size_t len)
                return;
        }
 
+       if (elems.rsn_selection) {
+               sta->rsn_selection = elems.rsn_selection[0];
+               wpa_printf(MSG_DEBUG, "RSNO: RSN Selection %u",
+                          sta->rsn_selection);
+       } else {
+               sta->rsn_selection = RSN_SELECTION_RSNE;
+       }
+
        if (elems.rsnxe) {
                os_memcpy(sta->rsnxe, elems.rsnxe, elems.rsnxe_len);
                sta->rsnxe_len = elems.rsnxe_len;
@@ -2636,6 +2678,8 @@ static void rx_mgmt_action_ft_response(struct wlantest *wt,
        struct wpa_ft_ies parse;
        struct wpa_ptk ptk;
        u8 ptk_name[WPA_PMK_NAME_LEN];
+       const u8 *rsnxe;
+       size_t rsnxe_len;
 
        if (len < 24 + 2 + 2 * ETH_ALEN + 2) {
                add_note(wt, MSG_INFO, "Too short FT Response frame from "
@@ -2696,7 +2740,16 @@ static void rx_mgmt_action_ft_response(struct wlantest *wt,
        os_memcpy(new_sta->pmk_r1_name, sta->pmk_r1_name,
                  sizeof(sta->pmk_r1_name));
 
-       if (ieee802_11_rsnx_capab_len(bss->rsnxe, bss->rsnxe_len,
+       if ((sta->rsn_selection == RSN_SELECTION_RSNE_OVERRIDE ||
+            sta->rsn_selection == RSN_SELECTION_RSNE_OVERRIDE_2) &&
+           bss->rsnxoe_len) {
+               rsnxe = bss->rsnxoe;
+               rsnxe_len = bss->rsnxoe_len;
+       } else {
+               rsnxe = bss->rsnxe;
+               rsnxe_len = bss->rsnxe_len;
+       }
+       if (ieee802_11_rsnx_capab_len(rsnxe, rsnxe_len,
                                      WLAN_RSNX_CAPAB_SECURE_LTF) &&
            ieee802_11_rsnx_capab_len(sta->rsnxe, sta->rsnxe_len,
                                      WLAN_RSNX_CAPAB_SECURE_LTF))
index 30dc123dc66e9a99a736bfe67e2d749cb0579be0..516e341df540f8bb795bef1f8998a925b6e5325a 100644 (file)
@@ -121,6 +121,8 @@ struct wlantest_sta {
 
        u16 sae_group;
        u16 owe_group;
+
+       enum rsn_selection_variant rsn_selection;
 };
 
 struct wlantest_tdls {
@@ -158,6 +160,8 @@ struct wlantest_bss {
        u8 rsnie[257];
        u8 rsnxe[254]; /* RSNXE data */
        size_t rsnxe_len;
+       u8 rsnxoe[251]; /* RSNXOE data */
+       size_t rsnxoe_len;
        u8 osenie[257];
        int proto;
        int pairwise_cipher;