diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 771f6dd12..a599be225 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -2418,6 +2418,8 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, u8 *end, *mdie, *ftie, *rsnie = NULL, *r0kh_id, *subelem = NULL; u8 *fte_mic, *elem_count; size_t mdie_len, ftie_len, rsnie_len = 0, r0kh_id_len, subelem_len = 0; + u8 rsnxe[10]; + size_t rsnxe_len; int res; struct wpa_auth_config *conf; struct wpa_ft_ies parse; @@ -2580,6 +2582,13 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, if (ric_start == pos) ric_start = NULL; + res = wpa_write_rsnxe(&sm->wpa_auth->conf, rsnxe, sizeof(rsnxe)); + if (res < 0) + return NULL; + rsnxe_len = res; + if (auth_alg == WLAN_AUTH_FT && rsnxe_len) + *elem_count += 1; + if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) { kck = sm->PTK.kck2; kck_len = sm->PTK.kck2_len; @@ -2592,6 +2601,7 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, mdie, mdie_len, ftie, ftie_len, rsnie, rsnie_len, ric_start, ric_start ? pos - ric_start : 0, + rsnxe_len ? rsnxe : NULL, rsnxe_len, fte_mic) < 0) { wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC"); return NULL; @@ -3249,6 +3259,8 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, count = 3; if (parse.ric) count += ieee802_11_ie_count(parse.ric, parse.ric_len); + if (parse.rsnxe) + count++; if (fte_elem_count != count) { wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC " "Control: received %u expected %u", @@ -3268,6 +3280,8 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, parse.ftie - 2, parse.ftie_len + 2, parse.rsn - 2, parse.rsn_len + 2, parse.ric, parse.ric_len, + parse.rsnxe ? parse.rsnxe - 2 : NULL, + parse.rsnxe ? parse.rsnxe_len + 2 : 0, mic) < 0) { wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC"); return WLAN_STATUS_UNSPECIFIED_FAILURE; @@ -3286,6 +3300,9 @@ u16 wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, parse.ftie - 2, parse.ftie_len + 2); wpa_hexdump(MSG_MSGDUMP, "FT: RSN", parse.rsn - 2, parse.rsn_len + 2); + wpa_hexdump(MSG_MSGDUMP, "FT: RSNXE", + parse.rsnxe ? parse.rsnxe - 2 : NULL, + parse.rsnxe ? parse.rsnxe_len + 2 : 0); return WLAN_STATUS_INVALID_FTIE; } diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index 1f8f18e90..e0f3599eb 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -750,10 +750,12 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr, const u8 *mdie, size_t mdie_len, const u8 *ftie, size_t ftie_len, const u8 *rsnie, size_t rsnie_len, - const u8 *ric, size_t ric_len, u8 *mic) + const u8 *ric, size_t ric_len, + const u8 *rsnxe, size_t rsnxe_len, + u8 *mic) { - const u8 *addr[9]; - size_t len[9]; + const u8 *addr[10]; + size_t len[10]; size_t i, num_elem = 0; u8 zero_mic[24]; size_t mic_len, fte_fixed_len; @@ -820,6 +822,12 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr, num_elem++; } + if (rsnxe) { + addr[num_elem] = rsnxe; + len[num_elem] = rsnxe_len; + num_elem++; + } + for (i = 0; i < num_elem; i++) wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", addr[i], len[i]); #ifdef CONFIG_SHA384 @@ -961,6 +969,13 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, update_use_sha384 = 0; } break; + case WLAN_EID_RSNX: + wpa_hexdump(MSG_DEBUG, "FT: RSNXE", pos, len); + if (len < 1) + break; + parse->rsnxe = pos; + parse->rsnxe_len = len; + break; case WLAN_EID_MOBILITY_DOMAIN: wpa_hexdump(MSG_DEBUG, "FT: MDE", pos, len); if (len < sizeof(struct rsn_mdie)) @@ -1043,6 +1058,8 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, 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 c7711f168..beb1ecd5e 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -364,7 +364,9 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr, const u8 *mdie, size_t mdie_len, const u8 *ftie, size_t ftie_len, const u8 *rsnie, size_t rsnie_len, - const u8 *ric, size_t ric_len, u8 *mic); + const u8 *ric, size_t ric_len, + const u8 *rsnxe, size_t rsnxe_len, + u8 *mic); int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len, const u8 *ssid, size_t ssid_len, const u8 *mdid, const u8 *r0kh_id, size_t r0kh_id_len, @@ -461,6 +463,8 @@ struct wpa_ft_ies { size_t ric_len; int key_mgmt; int pairwise_cipher; + const u8 *rsnxe; + size_t rsnxe_len; }; int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse, diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index a6da3471a..2b8b41fa5 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -18,6 +18,7 @@ #include "drivers/driver.h" #include "wpa.h" #include "wpa_i.h" +#include "wpa_ie.h" #include "pmksa_cache.h" #ifdef CONFIG_IEEE80211R @@ -171,6 +172,9 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len, struct rsn_ie_hdr *rsnie; u16 capab; int mdie_len; + u8 rsnxe[10]; + size_t rsnxe_len; + int res; sm->ft_completed = 0; sm->ft_reassoc_completed = 0; @@ -359,6 +363,13 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len, pos += ric_ies_len; } + res = wpa_gen_rsnxe(sm, rsnxe, sizeof(rsnxe)); + if (res < 0) { + os_free(buf); + return NULL; + } + rsnxe_len = res; + if (kck) { /* * IEEE Std 802.11r-2008, 11A.8.4 @@ -370,14 +381,18 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len, * MDIE * FTIE (with MIC field set to 0) * RIC-Request (if present) + * RSNXE (if present) */ /* Information element count */ *elem_count = 3 + ieee802_11_ie_count(ric_ies, ric_ies_len); + if (rsnxe_len) + *elem_count += 1; if (wpa_ft_mic(kck, kck_len, sm->own_addr, target_ap, 5, ((u8 *) mdie) - 2, 2 + sizeof(*mdie), ftie_pos, 2 + *ftie_len, (u8 *) rsnie, 2 + rsnie->len, ric_ies, - ric_ies_len, fte_mic) < 0) { + ric_ies_len, rsnxe_len ? rsnxe : NULL, rsnxe_len, + fte_mic) < 0) { wpa_printf(MSG_INFO, "FT: Failed to calculate MIC"); os_free(buf); return NULL; @@ -961,6 +976,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, count = 3; if (parse.ric) count += ieee802_11_ie_count(parse.ric, parse.ric_len); + if (parse.rsnxe) + count++; if (fte_elem_count != count) { wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC " "Control: received %u expected %u", @@ -981,6 +998,8 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, parse.ftie - 2, parse.ftie_len + 2, parse.rsn - 2, parse.rsn_len + 2, parse.ric, parse.ric_len, + parse.rsnxe ? parse.rsnxe - 2 : NULL, + parse.rsnxe ? parse.rsnxe_len + 2 : 0, mic) < 0) { wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC"); return -1;