diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 2402ad922..8b91b822c 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -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; } diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index dc77368df..88b6bbe15 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -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"); diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index 9e87b9a26..f503e9095 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -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; diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 9c7c526fc..fcd8ede3b 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -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; } diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index 497d91e6d..35fad9f1d 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -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; } diff --git a/wlantest/rx_mgmt.c b/wlantest/rx_mgmt.c index ba98034bd..8f7d220b8 100644 --- a/wlantest/rx_mgmt.c +++ b/wlantest/rx_mgmt.c @@ -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;