]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FTE protected element check for MLO Reassociation Response frame
authorJouni Malinen <quic_jouni@quicinc.com>
Tue, 8 Aug 2023 10:32:32 +0000 (13:32 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 10 Aug 2023 09:14:31 +0000 (12:14 +0300)
The set of protected elements in the FTE in Reassociation Response frame
is different for MLO. Count RSNE and RSNXE separately for each link.
This implementation uses the number of links for which a GTK was
provided which does not fully match the standard ("requested link") and
a more accurate implementation is likely needed, but that will require
some more complexity and state information.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/ap/wpa_auth_ft.c
src/common/wpa_common.c
src/common/wpa_common.h
src/rsn_supp/wpa.c
src/rsn_supp/wpa_ft.c
wlantest/rx_mgmt.c

index 2402ad922672b1bf3d50b4927eea736b35b88baf..8b91b822c6e250a43ac598791632284c4bb44847 100644 (file)
@@ -2805,7 +2805,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
 
        ric_start = pos;
        if (wpa_ft_parse_ies(req_ies, req_ies_len, &parse,
-                            sm->wpa_key_mgmt) == 0 && parse.ric) {
+                            sm->wpa_key_mgmt, false) == 0 && parse.ric) {
                pos = wpa_ft_process_ric(sm, pos, end, parse.ric,
                                         parse.ric_len);
                if (auth_alg == WLAN_AUTH_FT)
@@ -3183,7 +3183,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
        wpa_hexdump(MSG_DEBUG, "FT: Received authentication frame IEs",
                    ies, ies_len);
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse, 0)) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, 0, false)) {
                wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
                return WLAN_STATUS_UNSPECIFIED_FAILURE;
        }
@@ -3481,7 +3481,8 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies,
 
        wpa_hexdump(MSG_DEBUG, "FT: Reassoc Req IEs", ies, ies_len);
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->wpa_key_mgmt) < 0) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->wpa_key_mgmt,
+                            false) < 0) {
                wpa_printf(MSG_DEBUG, "FT: Failed to parse FT IEs");
                return WLAN_STATUS_UNSPECIFIED_FAILURE;
        }
index dc77368dfec113791540baa55f8c4ba1af85346c..88b6bbe15f616469ddf3a438aa7f58c80ef08020 100644 (file)
@@ -1198,7 +1198,7 @@ static int wpa_ft_parse_fte(int key_mgmt, const u8 *ie, size_t len,
 
 
 int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
-                    int key_mgmt)
+                    int key_mgmt, bool reassoc_resp)
 {
        const u8 *end, *pos;
        struct wpa_ie_data data;
@@ -1207,11 +1207,17 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
        const u8 *fte = NULL;
        size_t fte_len = 0;
        bool is_fte = false;
+       struct ieee802_11_elems elems;
 
        os_memset(parse, 0, sizeof(*parse));
        if (ies == NULL)
                return 0;
 
+       if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) == ParseFailed) {
+               wpa_printf(MSG_DEBUG, "FT: Failed to parse elements");
+               return -1;
+       }
+
        pos = ies;
        end = ies + ies_len;
        while (end - pos >= 2) {
@@ -1328,14 +1334,29 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
         * Check that the protected IE count matches with IEs included in the
         * frame.
         */
-       if (parse->rsn)
-               prot_ie_count--;
+       if (reassoc_resp && elems.basic_mle) {
+               unsigned int link_id;
+
+               /* TODO: This count should be done based on all _requested_,
+                * not _accepted_ links. */
+               for (link_id = 0; link_id < MAX_NUM_MLO_LINKS; link_id++) {
+                       if (parse->mlo_gtk[link_id]) {
+                               if (parse->rsn)
+                                       prot_ie_count--;
+                               if (parse->rsnxe)
+                                       prot_ie_count--;
+                       }
+               }
+       } else {
+               if (parse->rsn)
+                       prot_ie_count--;
+               if (parse->rsnxe)
+                       prot_ie_count--;
+       }
        if (parse->mdie)
                prot_ie_count--;
        if (parse->ftie)
                prot_ie_count--;
-       if (parse->rsnxe)
-               prot_ie_count--;
        if (prot_ie_count < 0) {
                wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
                           "the protected IE count");
index 9e87b9a2650ad3beabd4ee7fd8376bec16eef4f2..f503e9095868dd84ed6056096324ad2959d21074 100644 (file)
@@ -638,7 +638,7 @@ struct wpa_pasn_params_data {
 #define WPA_PASN_PUBKEY_UNCOMPRESSED 0x04
 
 int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse,
-                    int key_mgmt);
+                    int key_mgmt, bool reassoc_resp);
 
 struct wpa_eapol_ie_parse {
        const u8 *wpa_ie;
index 9c7c526fc0d64220ce301fcf79304fe8a12279c9..fcd8ede3b5a99137c7e79348d9aae2be91b6d33c 100644 (file)
@@ -5458,7 +5458,7 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
                }
 
                if (wpa_ft_parse_ies(pos, end - pos, &parse,
-                                    sm->key_mgmt) < 0) {
+                                    sm->key_mgmt, false) < 0) {
                        wpa_printf(MSG_DEBUG, "FILS+FT: Failed to parse IEs");
                        goto fail;
                }
index 497d91e6dc7cf8cfb966a78b7128313647383bb3..35fad9f1d3fc2f365cbe18dd32f523ec9ea85c32 100644 (file)
@@ -127,7 +127,7 @@ int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len)
                return 0;
        }
 
-       if (wpa_ft_parse_ies(ies, ies_len, &ft, sm->key_mgmt) < 0)
+       if (wpa_ft_parse_ies(ies, ies_len, &ft, sm->key_mgmt, false) < 0)
                return -1;
 
        if (ft.mdie_len < MOBILITY_DOMAIN_ID_LEN + 1)
@@ -615,7 +615,8 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
                return -1;
        }
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->key_mgmt) < 0) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->key_mgmt,
+                            !ft_action) < 0) {
                wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs");
                return -1;
        }
@@ -1033,7 +1034,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies,
                return 0;
        }
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->key_mgmt) < 0) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, sm->key_mgmt, true) < 0) {
                wpa_printf(MSG_DEBUG, "FT: Failed to parse IEs");
                return -1;
        }
index ba98034bd9facbf6fd0ac6dd36c3b4372ca74d99..8f7d220b82cda97b88336f323a56f8457a8e0fa3 100644 (file)
@@ -515,7 +515,7 @@ static void process_ft_auth(struct wlantest *wt, struct wlantest_bss *bss,
 
        if (wpa_ft_parse_ies(mgmt->u.auth.variable,
                             len - IEEE80211_HDRLEN - sizeof(mgmt->u.auth),
-                            &parse, 0)) {
+                            &parse, 0, false)) {
                add_note(wt, MSG_INFO,
                         "Could not parse FT Authentication Response frame");
                return;
@@ -1111,7 +1111,7 @@ static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len)
                sta->state = STATE3;
        }
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse, 0) == 0) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, 0, false) == 0) {
                if (parse.r0kh_id) {
                        os_memcpy(bss->r0kh_id, parse.r0kh_id,
                                  parse.r0kh_id_len);
@@ -1224,7 +1224,8 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data,
 
                use_sha384 = wpa_key_mgmt_sha384(sta->key_mgmt);
 
-               if (wpa_ft_parse_ies(ie, ie_len, &parse, sta->key_mgmt) < 0) {
+               if (wpa_ft_parse_ies(ie, ie_len, &parse, sta->key_mgmt,
+                                    false) < 0) {
                        add_note(wt, MSG_INFO, "FT: Failed to parse FT IEs");
                        return;
                }
@@ -1722,7 +1723,8 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data,
 
                use_sha384 = wpa_key_mgmt_sha384(sta->key_mgmt);
 
-               if (wpa_ft_parse_ies(ies, ies_len, &parse, sta->key_mgmt) < 0) {
+               if (wpa_ft_parse_ies(ies, ies_len, &parse, sta->key_mgmt,
+                                    true) < 0) {
                        add_note(wt, MSG_INFO, "FT: Failed to parse FT IEs");
                        return;
                }
@@ -2037,7 +2039,7 @@ static void rx_mgmt_action_ft_request(struct wlantest *wt,
        ies_len = len - (24 + 2 + 2 * ETH_ALEN);
        wpa_hexdump(MSG_DEBUG, "FT Request frame body", ies, ies_len);
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse, 0)) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, 0, false)) {
                add_note(wt, MSG_INFO, "Could not parse FT Request frame body");
                return;
        }
@@ -2086,7 +2088,7 @@ static void rx_mgmt_action_ft_response(struct wlantest *wt,
        ies_len = len - (24 + 2 + 2 * ETH_ALEN);
        wpa_hexdump(MSG_DEBUG, "FT Response frame body", ies, ies_len);
 
-       if (wpa_ft_parse_ies(ies, ies_len, &parse, 0)) {
+       if (wpa_ft_parse_ies(ies, ies_len, &parse, 0, false)) {
                add_note(wt, MSG_INFO,
                         "Could not parse FT Response frame body");
                return;