diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 70e73df16..4b16f62df 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -2821,8 +2821,10 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, } else { res = wpa_write_rsnxe(&sm->wpa_auth->conf, rsnxe, sizeof(rsnxe_buf)); - if (res < 0) - return NULL; + if (res < 0) { + pos = NULL; + goto fail; + } rsnxe_len = res; } #ifdef CONFIG_TESTING_OPTIONS @@ -2854,15 +2856,20 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, NULL, fte_mic) < 0) { wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC"); - return NULL; + pos = NULL; + goto fail; } os_free(sm->assoc_resp_ftie); sm->assoc_resp_ftie = os_malloc(ftie_len); - if (!sm->assoc_resp_ftie) - return NULL; + if (!sm->assoc_resp_ftie) { + pos = NULL; + goto fail; + } os_memcpy(sm->assoc_resp_ftie, ftie, ftie_len); +fail: + wpa_ft_parse_ies_free(&parse); return pos; } @@ -3174,6 +3181,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, const u8 *identity, *radius_cui; size_t identity_len = 0, radius_cui_len = 0; size_t pmk_r1_len, kdk_len, len; + int retval = WLAN_STATUS_UNSPECIFIED_FAILURE; *resp_ies = NULL; *resp_ies_len = 0; @@ -3195,17 +3203,20 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, sm->wpa_auth->conf.mobility_domain, MOBILITY_DOMAIN_ID_LEN) != 0) { wpa_printf(MSG_DEBUG, "FT: Invalid MDIE"); - return WLAN_STATUS_INVALID_MDIE; + retval = WLAN_STATUS_INVALID_MDIE; + goto out; } if (!parse.ftie || parse.ftie_len < sizeof(struct rsn_ftie)) { wpa_printf(MSG_DEBUG, "FT: Invalid FTIE"); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } if (parse.r0kh_id == NULL) { wpa_printf(MSG_DEBUG, "FT: Invalid FTIE - no R0KH-ID"); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } wpa_hexdump(MSG_DEBUG, "FT: STA R0KH-ID", @@ -3215,11 +3226,12 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, if (parse.rsn_pmkid == NULL) { wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE"); - return WLAN_STATUS_INVALID_PMKID; + retval = WLAN_STATUS_INVALID_PMKID; + goto out; } if (wpa_ft_set_key_mgmt(sm, &parse) < 0) - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; wpa_hexdump(MSG_DEBUG, "FT: Requested PMKR0Name", parse.rsn_pmkid, WPA_PMK_NAME_LEN); @@ -3229,12 +3241,14 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, if (wpa_derive_pmk_r1_name(parse.rsn_pmkid, sm->wpa_auth->conf.r1_key_holder, sm->addr, pmk_r1_name, PMK_LEN) < 0) - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; if (wpa_ft_psk_pmk_r1(sm, pmk_r1_name, pmk_r1, &pairwise, &vlan, &identity, &identity_len, &radius_cui, &radius_cui_len, - &session_timeout) < 0) - return WLAN_STATUS_INVALID_PMKID; + &session_timeout) < 0) { + retval = WLAN_STATUS_INVALID_PMKID; + goto out; + } pmk_r1_len = PMK_LEN; wpa_printf(MSG_DEBUG, "FT: Generated PMK-R1 for FT-PSK locally"); @@ -3285,10 +3299,12 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, if (wpa_ft_pull_pmk_r1(sm, ies, ies_len, parse.rsn_pmkid) < 0) { wpa_printf(MSG_DEBUG, "FT: Did not have matching PMK-R1 and either unknown or blocked R0KH-ID or NAK from R0KH"); - return WLAN_STATUS_INVALID_PMKID; + retval = WLAN_STATUS_INVALID_PMKID; + goto out; } - return -1; /* Status pending */ + retval = -1; /* Status pending */ + goto out; pmk_r1_derived: wpa_hexdump_key(MSG_DEBUG, "FT: Selected PMK-R1", pmk_r1, pmk_r1_len); @@ -3300,7 +3316,7 @@ pmk_r1_derived: if (random_get_bytes(sm->ANonce, WPA_NONCE_LEN)) { wpa_printf(MSG_DEBUG, "FT: Failed to get random data for " "ANonce"); - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; } /* Now that we know the correct PMK-R1 length and as such, the length @@ -3311,7 +3327,8 @@ pmk_r1_derived: ftie = (const struct rsn_ftie_sha512 *) parse.ftie; if (!ftie || parse.ftie_len < sizeof(*ftie)) { wpa_printf(MSG_DEBUG, "FT: Invalid FTIE"); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN); @@ -3321,7 +3338,8 @@ pmk_r1_derived: ftie = (const struct rsn_ftie_sha384 *) parse.ftie; if (!ftie || parse.ftie_len < sizeof(*ftie)) { wpa_printf(MSG_DEBUG, "FT: Invalid FTIE"); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN); @@ -3331,7 +3349,8 @@ pmk_r1_derived: ftie = (const struct rsn_ftie *) parse.ftie; if (!ftie || parse.ftie_len < sizeof(*ftie)) { wpa_printf(MSG_DEBUG, "FT: Invalid FTIE"); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } os_memcpy(sm->SNonce, ftie->snonce, WPA_NONCE_LEN); @@ -3353,14 +3372,14 @@ pmk_r1_derived: sm->addr, sm->wpa_auth->addr, pmk_r1_name, &sm->PTK, ptk_name, parse.key_mgmt, pairwise, kdk_len) < 0) - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; #ifdef CONFIG_PASN if (sm->wpa_auth->conf.secure_ltf && ieee802_11_rsnx_capab(sm->rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF) && wpa_ltf_keyseed(&sm->PTK, parse.key_mgmt, pairwise)) { wpa_printf(MSG_DEBUG, "FT: Failed to derive LTF keyseed"); - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; } #endif /* CONFIG_PASN */ @@ -3371,14 +3390,14 @@ pmk_r1_derived: if (wpa_ft_set_vlan(sm->wpa_auth, sm->addr, &vlan) < 0) { wpa_printf(MSG_DEBUG, "FT: Failed to configure VLAN"); - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; } if (wpa_ft_set_identity(sm->wpa_auth, sm->addr, identity, identity_len) < 0 || wpa_ft_set_radius_cui(sm->wpa_auth, sm->addr, radius_cui, radius_cui_len) < 0) { wpa_printf(MSG_DEBUG, "FT: Failed to configure identity/CUI"); - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; } wpa_ft_set_session_timeout(sm->wpa_auth, sm->addr, session_timeout); @@ -3411,11 +3430,14 @@ pmk_r1_derived: *resp_ies_len = pos - *resp_ies; - return WLAN_STATUS_SUCCESS; + retval = WLAN_STATUS_SUCCESS; + goto out; fail: os_free(*resp_ies); *resp_ies = NULL; - return WLAN_STATUS_UNSPECIFIED_FAILURE; +out: + wpa_ft_parse_ies_free(&parse); + return retval; } @@ -3474,6 +3496,7 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, const u8 *kck; size_t kck_len; struct wpa_auth_config *conf; + int retval = WLAN_STATUS_UNSPECIFIED_FAILURE; if (sm == NULL) return WLAN_STATUS_UNSPECIFIED_FAILURE; @@ -3490,19 +3513,21 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, if (parse.rsn == NULL) { wpa_printf(MSG_DEBUG, "FT: No RSNIE in Reassoc Req"); - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; } if (parse.rsn_pmkid == NULL) { wpa_printf(MSG_DEBUG, "FT: No PMKID in RSNIE"); - return WLAN_STATUS_INVALID_PMKID; + retval = WLAN_STATUS_INVALID_PMKID; + goto out; } if (os_memcmp_const(parse.rsn_pmkid, sm->pmk_r1_name, WPA_PMK_NAME_LEN) != 0) { wpa_printf(MSG_DEBUG, "FT: PMKID in Reassoc Req did not match " "with the PMKR1Name derived from auth request"); - return WLAN_STATUS_INVALID_PMKID; + retval = WLAN_STATUS_INVALID_PMKID; + goto out; } mdie = (struct rsn_mdie *) parse.mdie; @@ -3510,7 +3535,8 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, os_memcmp(mdie->mobility_domain, conf->mobility_domain, MOBILITY_DOMAIN_ID_LEN) != 0) { wpa_printf(MSG_DEBUG, "FT: Invalid MDIE"); - return WLAN_STATUS_INVALID_MDIE; + retval = WLAN_STATUS_INVALID_MDIE; + goto out; } if (sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY && @@ -3528,7 +3554,8 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, wpa_printf(MSG_DEBUG, "FT: Invalid FTE (fte_mic_len=%zu mic_len=%zu)", parse.fte_mic_len, mic_len); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } if (os_memcmp(parse.fte_snonce, sm->SNonce, WPA_NONCE_LEN) != 0) { @@ -3537,7 +3564,8 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, parse.fte_snonce, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce", sm->SNonce, WPA_NONCE_LEN); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } if (os_memcmp(parse.fte_anonce, sm->ANonce, WPA_NONCE_LEN) != 0) { @@ -3546,12 +3574,14 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, parse.fte_anonce, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce", sm->ANonce, WPA_NONCE_LEN); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } if (parse.r0kh_id == NULL) { wpa_printf(MSG_DEBUG, "FT: No R0KH-ID subelem in FTIE"); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } if (parse.r0kh_id_len != sm->r0kh_id_len || @@ -3563,12 +3593,14 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, parse.r0kh_id, parse.r0kh_id_len); wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID", sm->r0kh_id, sm->r0kh_id_len); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } if (parse.r1kh_id == NULL) { wpa_printf(MSG_DEBUG, "FT: No R1KH-ID subelem in FTIE"); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } if (os_memcmp_const(parse.r1kh_id, conf->r1_key_holder, @@ -3579,7 +3611,8 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, parse.r1kh_id, FT_R1KH_ID_LEN); wpa_hexdump(MSG_DEBUG, "FT: Expected R1KH-ID", conf->r1_key_holder, FT_R1KH_ID_LEN); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } if (parse.rsn_pmkid == NULL || @@ -3587,7 +3620,8 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, { wpa_printf(MSG_DEBUG, "FT: No matching PMKR1Name (PMKID) in " "RSNIE (pmkid=%d)", !!parse.rsn_pmkid); - return WLAN_STATUS_INVALID_PMKID; + retval = WLAN_STATUS_INVALID_PMKID; + goto out; } count = 3; @@ -3599,7 +3633,7 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC " "Control: received %u expected %u", parse.fte_elem_count, count); - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; } if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) { @@ -3620,7 +3654,7 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, NULL, mic) < 0) { wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC"); - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; } if (os_memcmp_const(mic, parse.fte_mic, mic_len) != 0) { @@ -3639,7 +3673,8 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, wpa_hexdump(MSG_MSGDUMP, "FT: RSNXE", parse.rsnxe ? parse.rsnxe - 2 : NULL, parse.rsnxe ? parse.rsnxe_len + 2 : 0); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } if (parse.fte_rsnxe_used && @@ -3648,7 +3683,8 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, !parse.rsnxe) { wpa_printf(MSG_INFO, "FT: FTE indicated that STA uses RSNXE, but RSNXE was not included"); - return -1; /* discard request */ + retval = -1; /* discard request */ + goto out; } #ifdef CONFIG_OCV @@ -3661,14 +3697,14 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, if (wpa_channel_info(sm->wpa_auth, &ci) != 0) { wpa_printf(MSG_WARNING, "Failed to get channel info to validate received OCI in (Re)Assoc Request"); - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; } if (get_sta_tx_parameters(sm, channel_width_to_int(ci.chanwidth), ci.seg1_idx, &tx_chanwidth, &tx_seg1_idx) < 0) - return WLAN_STATUS_UNSPECIFIED_FAILURE; + goto out; res = ocv_verify_tx_params(parse.oci, parse.oci_len, &ci, tx_chanwidth, tx_seg1_idx); @@ -3684,12 +3720,16 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, OCV_FAILURE "addr=" MACSTR " frame=ft-reassoc-req error=%s", MAC2STR(sm->addr), ocv_errorstr); - return WLAN_STATUS_INVALID_FTIE; + retval = WLAN_STATUS_INVALID_FTIE; + goto out; } } #endif /* CONFIG_OCV */ - return WLAN_STATUS_SUCCESS; + retval = WLAN_STATUS_SUCCESS; +out: + wpa_ft_parse_ies_free(&parse); + return retval; } diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index c11b461eb..1e7a2bd1a 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -1222,7 +1222,7 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse, if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) == ParseFailed) { wpa_printf(MSG_DEBUG, "FT: Failed to parse elements"); - return -1; + goto fail; } pos = ies; @@ -1250,7 +1250,7 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse, if (ret < 0) { wpa_printf(MSG_DEBUG, "FT: Failed to parse " "RSN IE: %d", ret); - return -1; + goto fail; } parse->rsn_capab = data.capabilities; if (data.num_pmkid == 1 && data.pmkid) @@ -1270,7 +1270,7 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse, case WLAN_EID_MOBILITY_DOMAIN: wpa_hexdump(MSG_DEBUG, "FT: MDE", pos, len); if (len < sizeof(struct rsn_mdie)) - return -1; + goto fail; parse->mdie = pos; parse->mdie_len = len; break; @@ -1284,7 +1284,7 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse, * using the struct rsn_ftie* definitions. */ if (len < 2) - return -1; + goto fail; prot_ie_count = pos[1]; /* Element Count field in * MIC Control */ is_fte = true; @@ -1321,17 +1321,17 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse, if (fte_len < 255) { res = wpa_ft_parse_fte(key_mgmt, fte, fte_len, parse); } else { - struct wpabuf *buf; - - buf = ieee802_11_defrag_data(fte, fte_len, false); - if (!buf) - return -1; - res = wpa_ft_parse_fte(key_mgmt, wpabuf_head(buf), - wpabuf_len(buf), parse); - wpabuf_free(buf); + parse->fte_buf = ieee802_11_defrag_data(fte, fte_len, + false); + if (!parse->fte_buf) + goto fail; + res = wpa_ft_parse_fte(key_mgmt, + wpabuf_head(parse->fte_buf), + wpabuf_len(parse->fte_buf), + parse); } if (res < 0) - return -1; + goto fail; } if (prot_ie_count == 0) @@ -1367,13 +1367,13 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse, if (prot_ie_count < 0) { wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in " "the protected IE count"); - return -1; + goto fail; } if (prot_ie_count == 0 && parse->ric) { wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not " "included in protected IE count"); - return -1; + goto fail; } /* Determine the end of the RIC IE(s) */ @@ -1389,11 +1389,25 @@ int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse, if (prot_ie_count) { wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from " "frame", (int) prot_ie_count); - return -1; + goto fail; } return 0; + +fail: + wpa_ft_parse_ies_free(parse); + return -1; } + + +void wpa_ft_parse_ies_free(struct wpa_ft_ies *parse) +{ + if (!parse) + return; + wpabuf_free(parse->fte_buf); + parse->fte_buf = NULL; +} + #endif /* CONFIG_IEEE80211R */ diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index bfcd71781..80c7d324f 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -604,6 +604,8 @@ struct wpa_ft_ies { u16 valid_mlo_bigtks; /* bitmap of valid link BIGTK subelements */ const u8 *mlo_bigtk[MAX_NUM_MLO_LINKS]; size_t mlo_bigtk_len[MAX_NUM_MLO_LINKS]; + + struct wpabuf *fte_buf; }; /* IEEE P802.11az/D2.6 - 9.4.2.303 PASN Parameters element */ @@ -640,6 +642,7 @@ struct wpa_pasn_params_data { int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse, int key_mgmt, bool reassoc_resp); +void wpa_ft_parse_ies_free(struct wpa_ft_ies *parse); struct wpa_eapol_ie_parse { const u8 *wpa_ie; diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index fcd8ede3b..7294a15bc 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -5372,6 +5372,11 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data, const u8 *g_ap = NULL; size_t g_ap_len = 0, kdk_len; struct wpabuf *pub = NULL; +#ifdef CONFIG_IEEE80211R + struct wpa_ft_ies parse; + + os_memset(&parse, 0, sizeof(parse)); +#endif /* CONFIG_IEEE80211R */ os_memcpy(sm->bssid, bssid, ETH_ALEN); @@ -5450,8 +5455,6 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data, #ifdef CONFIG_IEEE80211R if (wpa_key_mgmt_ft(sm->key_mgmt)) { - struct wpa_ft_ies parse; - if (!elems.mdie || !elems.ftie) { wpa_printf(MSG_DEBUG, "FILS+FT: No MDE or FTE"); goto fail; @@ -5662,10 +5665,16 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data, &sm->fils_key_auth_len); wpabuf_free(pub); forced_memzero(ick, sizeof(ick)); +#ifdef CONFIG_IEEE80211R + wpa_ft_parse_ies_free(&parse); +#endif /* CONFIG_IEEE80211R */ return res; fail: wpabuf_free(pub); wpabuf_clear_free(dh_ss); +#ifdef CONFIG_IEEE80211R + wpa_ft_parse_ies_free(&parse); +#endif /* CONFIG_IEEE80211R */ return -1; } diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index b88f1d2c6..69de046c0 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -130,8 +130,10 @@ int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len) 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) + if (ft.mdie_len < MOBILITY_DOMAIN_ID_LEN + 1) { + wpa_ft_parse_ies_free(&ft); return -1; + } wpa_hexdump(MSG_DEBUG, "FT: Mobility domain", ft.mdie, MOBILITY_DOMAIN_ID_LEN); @@ -179,6 +181,7 @@ int wpa_sm_set_ft_params(struct wpa_sm *sm, const u8 *ies, size_t ies_len) sm->assoc_resp_ies, sm->assoc_resp_ies_len); } + wpa_ft_parse_ies_free(&ft); return 0; } @@ -587,11 +590,13 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, struct wpa_ft_ies parse; struct rsn_mdie *mdie; u8 ptk_name[WPA_PMK_NAME_LEN]; - int ret; + int ret = -1, res; const u8 *bssid; const u8 *kck; size_t kck_len, kdk_len; + os_memset(&parse, 0, sizeof(parse)); + wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len); wpa_hexdump(MSG_DEBUG, "FT: RIC IEs", ric_ies, ric_ies_len); @@ -599,27 +604,27 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, if (!sm->over_the_ds_in_progress) { wpa_printf(MSG_DEBUG, "FT: No over-the-DS in progress " "- drop FT Action Response"); - return -1; + goto fail; } if (os_memcmp(target_ap, sm->target_ap, ETH_ALEN) != 0) { wpa_printf(MSG_DEBUG, "FT: No over-the-DS in progress " "with this Target AP - drop FT Action " "Response"); - return -1; + goto fail; } } if (!wpa_key_mgmt_ft(sm->key_mgmt)) { wpa_printf(MSG_DEBUG, "FT: Reject FT IEs since FT is not " "enabled for this connection"); - return -1; + goto fail; } 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; + goto fail; } mdie = (struct rsn_mdie *) parse.mdie; @@ -627,12 +632,12 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, os_memcmp(mdie->mobility_domain, sm->mobility_domain, MOBILITY_DOMAIN_ID_LEN) != 0) { wpa_printf(MSG_DEBUG, "FT: Invalid MDIE"); - return -1; + goto fail; } if (!parse.ftie || !parse.fte_anonce || !parse.fte_snonce) { wpa_printf(MSG_DEBUG, "FT: Invalid FTE"); - return -1; + goto fail; } if (os_memcmp(parse.fte_snonce, sm->snonce, WPA_NONCE_LEN) != 0) { @@ -641,12 +646,12 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, parse.fte_snonce, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce", sm->snonce, WPA_NONCE_LEN); - return -1; + goto fail; } if (parse.r0kh_id == NULL) { wpa_printf(MSG_DEBUG, "FT: No R0KH-ID subelem in FTIE"); - return -1; + goto fail; } if (parse.r0kh_id_len != sm->r0kh_id_len || @@ -658,12 +663,12 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, parse.r0kh_id, parse.r0kh_id_len); wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID", sm->r0kh_id, sm->r0kh_id_len); - return -1; + goto fail; } if (parse.r1kh_id == NULL) { wpa_printf(MSG_DEBUG, "FT: No R1KH-ID subelem in FTIE"); - return -1; + goto fail; } if (parse.rsn_pmkid == NULL || @@ -671,13 +676,13 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, { wpa_printf(MSG_DEBUG, "FT: No matching PMKR0Name (PMKID) in " "RSNIE"); - return -1; + goto fail; } if (sm->mfp == 2 && !(parse.rsn_capab & WPA_CAPABILITY_MFPC)) { wpa_printf(MSG_INFO, "FT: Target AP does not support PMF, but local configuration requires that"); - return -1; + goto fail; } os_memcpy(sm->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN); @@ -688,7 +693,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, if (wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_len, sm->pmk_r0_name, sm->r1kh_id, sm->own_addr, sm->pmk_r1, sm->pmk_r1_name) < 0) - return -1; + goto fail; sm->pmk_r1_len = sm->pmk_r0_len; bssid = target_ap; @@ -708,7 +713,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, sm->pmk_r1_name, &sm->ptk, ptk_name, sm->key_mgmt, sm->pairwise_cipher, kdk_len) < 0) - return -1; + goto fail; os_memcpy(sm->key_mobility_domain, sm->mobility_domain, MOBILITY_DOMAIN_ID_LEN); @@ -718,7 +723,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, ieee802_11_rsnx_capab(sm->ap_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF) && wpa_ltf_keyseed(&sm->ptk, sm->key_mgmt, sm->pairwise_cipher)) { wpa_printf(MSG_DEBUG, "FT: Failed to derive LTF keyseed"); - return -1; + goto fail; } #endif /* CONFIG_PASN */ @@ -742,8 +747,8 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, } wpa_sm_mark_authenticated(sm, bssid); - ret = wpa_ft_install_ptk(sm, bssid); - if (ret) { + res = wpa_ft_install_ptk(sm, bssid); + if (res) { /* * Some drivers do not support key configuration when we are * not associated with the target AP. Work around this by @@ -765,7 +770,10 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, os_memcpy(sm->bssid, target_ap, ETH_ALEN); } - return 0; + ret = 0; +fail: + wpa_ft_parse_ies_free(&parse); + return ret; } @@ -1021,13 +1029,16 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, size_t kck_len; int own_rsnxe_used; size_t mic_len; + int ret = -1; + + os_memset(&parse, 0, sizeof(parse)); wpa_hexdump(MSG_DEBUG, "FT: Response IEs", ies, ies_len); if (!wpa_key_mgmt_ft(sm->key_mgmt)) { wpa_printf(MSG_DEBUG, "FT: Reject FT IEs since FT is not " "enabled for this connection"); - return -1; + goto fail; } if (sm->ft_reassoc_completed) { @@ -1037,7 +1048,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, 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; + goto fail; } mdie = (struct rsn_mdie *) parse.mdie; @@ -1045,7 +1056,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, os_memcmp(mdie->mobility_domain, sm->mobility_domain, MOBILITY_DOMAIN_ID_LEN) != 0) { wpa_printf(MSG_DEBUG, "FT: Invalid MDIE"); - return -1; + goto fail; } if (sm->key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY && @@ -1063,7 +1074,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, wpa_printf(MSG_DEBUG, "FT: Invalid FTE (fte_mic_len=%zu mic_len=%zu)", parse.fte_mic_len, mic_len); - return -1; + goto fail; } if (os_memcmp(parse.fte_snonce, sm->snonce, WPA_NONCE_LEN) != 0) { @@ -1072,7 +1083,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, parse.fte_snonce, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce", sm->snonce, WPA_NONCE_LEN); - return -1; + goto fail; } if (os_memcmp(parse.fte_anonce, sm->anonce, WPA_NONCE_LEN) != 0) { @@ -1081,12 +1092,12 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, parse.fte_anonce, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce", sm->anonce, WPA_NONCE_LEN); - return -1; + goto fail; } if (parse.r0kh_id == NULL) { wpa_printf(MSG_DEBUG, "FT: No R0KH-ID subelem in FTIE"); - return -1; + goto fail; } if (parse.r0kh_id_len != sm->r0kh_id_len || @@ -1098,18 +1109,18 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, parse.r0kh_id, parse.r0kh_id_len); wpa_hexdump(MSG_DEBUG, "FT: The current R0KH-ID", sm->r0kh_id, sm->r0kh_id_len); - return -1; + goto fail; } if (parse.r1kh_id == NULL) { wpa_printf(MSG_DEBUG, "FT: No R1KH-ID subelem in FTIE"); - return -1; + goto fail; } if (os_memcmp_const(parse.r1kh_id, sm->r1kh_id, FT_R1KH_ID_LEN) != 0) { wpa_printf(MSG_DEBUG, "FT: Unknown R1KH-ID used in " "ReassocResp"); - return -1; + goto fail; } if (parse.rsn_pmkid == NULL || @@ -1117,7 +1128,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, { wpa_printf(MSG_DEBUG, "FT: No matching PMKR1Name (PMKID) in " "RSNIE (pmkid=%d)", !!parse.rsn_pmkid); - return -1; + goto fail; } count = 3; @@ -1129,7 +1140,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, wpa_printf(MSG_DEBUG, "FT: Unexpected IE count in MIC " "Control: received %u expected %u", parse.fte_elem_count, count); - return -1; + goto fail; } if (wpa_key_mgmt_fils(sm->key_mgmt)) { @@ -1150,7 +1161,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, NULL, mic) < 0) { wpa_printf(MSG_DEBUG, "FT: Failed to calculate MIC"); - return -1; + goto fail; } if (os_memcmp_const(mic, parse.fte_mic, mic_len) != 0) { @@ -1158,13 +1169,13 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, wpa_hexdump(MSG_MSGDUMP, "FT: Received MIC", parse.fte_mic, mic_len); wpa_hexdump(MSG_MSGDUMP, "FT: Calculated MIC", mic, mic_len); - return -1; + goto fail; } if (parse.fte_rsnxe_used && !sm->ap_rsnxe) { wpa_printf(MSG_INFO, "FT: FTE indicated that AP uses RSNXE, but RSNXE was not included in Beacon/Probe Response frames"); - return -1; + goto fail; } if (!sm->ap_rsn_ie) { @@ -1173,7 +1184,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, if (wpa_sm_get_beacon_ie(sm) < 0) { wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "FT: Could not find AP from the scan results"); - return -1; + goto fail; } wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "FT: Found the current AP from updated scan results"); @@ -1191,7 +1202,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, "RSNE in FT protocol Reassociation Response frame", parse.rsn ? parse.rsn - 2 : NULL, parse.rsn ? parse.rsn_len + 2 : 0); - return -1; + goto fail; } own_rsnxe_used = wpa_key_mgmt_sae(sm->key_mgmt) && @@ -1211,7 +1222,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, "RSNXE in FT protocol Reassociation Response frame", parse.rsnxe ? parse.rsnxe - 2 : NULL, parse.rsnxe ? parse.rsnxe_len + 2 : 0); - return -1; + goto fail; } #ifdef CONFIG_OCV @@ -1221,7 +1232,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, if (wpa_sm_channel_info(sm, &ci) != 0) { wpa_printf(MSG_WARNING, "Failed to get channel info to validate received OCI in (Re)Assoc Response"); - return -1; + goto fail; } if (ocv_verify_tx_params(parse.oci, parse.oci_len, &ci, @@ -1230,7 +1241,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, wpa_msg(sm->ctx->msg_ctx, MSG_INFO, OCV_FAILURE "addr=" MACSTR " frame=ft-assoc error=%s", MAC2STR(src_addr), ocv_errorstr); - return -1; + goto fail; } } #endif /* CONFIG_OCV */ @@ -1240,13 +1251,13 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, if (wpa_ft_process_gtk_subelem(sm, parse.gtk, parse.gtk_len) < 0 || wpa_ft_process_igtk_subelem(sm, parse.igtk, parse.igtk_len) < 0 || wpa_ft_process_bigtk_subelem(sm, parse.bigtk, parse.bigtk_len) < 0) - return -1; + goto fail; if (sm->set_ptk_after_assoc) { wpa_printf(MSG_DEBUG, "FT: Try to set PTK again now that we " "are associated"); if (wpa_ft_install_ptk(sm, src_addr) < 0) - return -1; + goto fail; sm->set_ptk_after_assoc = 0; } @@ -1259,7 +1270,10 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, wpa_printf(MSG_DEBUG, "FT: Completed successfully"); - return 0; + ret = 0; +fail: + wpa_ft_parse_ies_free(&parse); + return ret; } diff --git a/wlantest/rx_mgmt.c b/wlantest/rx_mgmt.c index 461679e5e..137ff89b2 100644 --- a/wlantest/rx_mgmt.c +++ b/wlantest/rx_mgmt.c @@ -537,11 +537,11 @@ static void process_ft_auth(struct wlantest *wt, struct wlantest_bss *bss, if (trans == 1) { sta->key_mgmt = parse.key_mgmt; sta->pairwise_cipher = parse.pairwise_cipher; - return; + goto out; } if (trans != 2) - return; + goto out; /* TODO: Should find the latest updated PMK-R0 value here instead * copying the one from the first found matching old STA entry. */ @@ -553,7 +553,7 @@ static void process_ft_auth(struct wlantest *wt, struct wlantest_bss *bss, break; } if (!old_sta) - return; + goto out; os_memcpy(sta->pmk_r0, old_sta->pmk_r0, old_sta->pmk_r0_len); sta->pmk_r0_len = old_sta->pmk_r0_len; @@ -566,7 +566,7 @@ static void process_ft_auth(struct wlantest *wt, struct wlantest_bss *bss, if (wpa_derive_pmk_r1(sta->pmk_r0, sta->pmk_r0_len, sta->pmk_r0_name, bss->r1kh_id, sta->addr, sta->pmk_r1, sta->pmk_r1_name) < 0) - return; + goto out; sta->pmk_r1_len = sta->pmk_r0_len; if (!parse.fte_anonce || !parse.fte_snonce || @@ -574,9 +574,11 @@ static void process_ft_auth(struct wlantest *wt, struct wlantest_bss *bss, parse.fte_anonce, sta->addr, bss->bssid, sta->pmk_r1_name, &ptk, ptk_name, sta->key_mgmt, sta->pairwise_cipher, 0) < 0) - return; + goto out; sta_new_ptk(wt, sta, &ptk); +out: + wpa_ft_parse_ies_free(&parse); } @@ -1143,6 +1145,7 @@ static void rx_mgmt_assoc_resp(struct wlantest *wt, const u8 *data, size_t len) } if (parse.r1kh_id) os_memcpy(bss->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN); + wpa_ft_parse_ies_free(&parse); } if (elems.owe_dh && elems.owe_dh_len >= 2) { @@ -1310,12 +1313,12 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, if (!parse.rsn) { add_note(wt, MSG_INFO, "FT: No RSNE in Reassoc Req"); - return; + goto out; } if (!parse.rsn_pmkid) { add_note(wt, MSG_INFO, "FT: No PMKID in RSNE"); - return; + goto out; } if (os_memcmp_const(parse.rsn_pmkid, sta->pmk_r1_name, @@ -1328,7 +1331,7 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, wpa_hexdump(MSG_DEBUG, "FT: Previously derived PMKR1Name", sta->pmk_r1_name, WPA_PMK_NAME_LEN); - return; + goto out; } mde = (struct rsn_mdie *) parse.mdie; @@ -1344,7 +1347,7 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, fte = (struct rsn_ftie_sha384 *) parse.ftie; if (!fte || parse.ftie_len < sizeof(*fte)) { add_note(wt, MSG_INFO, "FT: Invalid FTE"); - return; + goto out; } anonce = fte->anonce; @@ -1357,7 +1360,7 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, fte = (struct rsn_ftie *) parse.ftie; if (!fte || parse.ftie_len < sizeof(*fte)) { add_note(wt, MSG_INFO, "FT: Invalid FTIE"); - return; + goto out; } anonce = fte->anonce; @@ -1372,7 +1375,7 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, snonce, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce", sta->snonce, WPA_NONCE_LEN); - return; + goto out; } if (os_memcmp(anonce, sta->anonce, WPA_NONCE_LEN) != 0) { @@ -1381,19 +1384,19 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, anonce, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce", sta->anonce, WPA_NONCE_LEN); - return; + goto out; } if (!parse.r0kh_id) { add_note(wt, MSG_INFO, "FT: No R0KH-ID subelem in FTE"); - return; + goto out; } os_memcpy(bss->r0kh_id, parse.r0kh_id, parse.r0kh_id_len); bss->r0kh_id_len = parse.r0kh_id_len; if (!parse.r1kh_id) { add_note(wt, MSG_INFO, "FT: No R1KH-ID subelem in FTE"); - return; + goto out; } os_memcpy(bss->r1kh_id, parse.r1kh_id, FT_R1KH_ID_LEN); @@ -1404,7 +1407,7 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, add_note(wt, MSG_INFO, "FT: No matching PMKR1Name (PMKID) in RSNE (pmkid=%d)", !!parse.rsn_pmkid); - return; + goto out; } count = 3; @@ -1416,7 +1419,7 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, add_note(wt, MSG_INFO, "FT: Unexpected IE count in MIC Control: received %u expected %u", fte_elem_count, count); - return; + goto out; } if (wpa_key_mgmt_fils(sta->key_mgmt)) { @@ -1432,7 +1435,7 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, extra = wpabuf_alloc(MAX_NUM_MLO_LINKS * ETH_ALEN); if (!extra) - return; + goto out; for (i = 0; i < MAX_NUM_MLO_LINKS; i++) { if (!is_zero_ether_addr(sta->link_addr[i])) wpabuf_put_data(extra, @@ -1453,7 +1456,7 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, mic) < 0) { wpabuf_free(extra); add_note(wt, MSG_INFO, "FT: Failed to calculate MIC"); - return; + goto out; } wpabuf_free(extra); @@ -1486,10 +1489,12 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, link_id, MAC2STR(sta->link_addr[link_id])); } - return; + goto out; } add_note(wt, MSG_INFO, "FT: Valid FTE MIC"); + out: + wpa_ft_parse_ies_free(&parse); } } @@ -1839,12 +1844,12 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, if (!parse.rsn) { add_note(wt, MSG_INFO, "FT: No RSNE in Reassoc Resp"); - return; + goto out; } if (!parse.rsn_pmkid) { add_note(wt, MSG_INFO, "FT: No PMKID in RSNE"); - return; + goto out; } if (os_memcmp_const(parse.rsn_pmkid, sta->pmk_r1_name, @@ -1857,7 +1862,7 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, wpa_hexdump(MSG_DEBUG, "FT: Previously derived PMKR1Name", sta->pmk_r1_name, WPA_PMK_NAME_LEN); - return; + goto out; } mde = (struct rsn_mdie *) parse.mdie; @@ -1873,7 +1878,7 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, fte = (struct rsn_ftie_sha384 *) parse.ftie; if (!fte || parse.ftie_len < sizeof(*fte)) { add_note(wt, MSG_INFO, "FT: Invalid FTE"); - return; + goto out; } anonce = fte->anonce; @@ -1886,7 +1891,7 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, fte = (struct rsn_ftie *) parse.ftie; if (!fte || parse.ftie_len < sizeof(*fte)) { add_note(wt, MSG_INFO, "FT: Invalid FTIE"); - return; + goto out; } anonce = fte->anonce; @@ -1901,7 +1906,7 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, snonce, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "FT: Expected SNonce", sta->snonce, WPA_NONCE_LEN); - return; + goto out; } if (os_memcmp(anonce, sta->anonce, WPA_NONCE_LEN) != 0) { @@ -1910,12 +1915,12 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, anonce, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "FT: Expected ANonce", sta->anonce, WPA_NONCE_LEN); - return; + goto out; } if (!parse.r0kh_id) { add_note(wt, MSG_INFO, "FT: No R0KH-ID subelem in FTE"); - return; + goto out; } if (parse.r0kh_id_len != bss->r0kh_id_len || @@ -1934,7 +1939,7 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, if (!parse.r1kh_id) { add_note(wt, MSG_INFO, "FT: No R1KH-ID subelem in FTE"); - return; + goto out; } if (os_memcmp_const(parse.r1kh_id, bss->r1kh_id, @@ -1953,7 +1958,7 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, add_note(wt, MSG_INFO, "FT: Unexpected IE count in MIC Control: received %u expected %u", fte_elem_count, count); - return; + goto out; } if (wpa_key_mgmt_fils(sta->key_mgmt)) { @@ -1978,7 +1983,7 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, NULL, mic) < 0) { add_note(wt, MSG_INFO, "FT: Failed to calculate MIC"); - return; + goto out; } if (os_memcmp_const(mic, fte_mic, mic_len) != 0) { @@ -2000,7 +2005,7 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, wpa_hexdump(MSG_MSGDUMP, "FT: RSNXE", parse.rsnxe ? parse.rsnxe - 2 : NULL, parse.rsnxe ? parse.rsnxe_len + 2 : 0); - return; + goto out; } add_note(wt, MSG_INFO, "FT: Valid FTE MIC"); @@ -2024,6 +2029,9 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, parse.igtk, parse.igtk_len); process_bigtk_subelem(wt, bss, sta, kek, kek_len, parse.bigtk, parse.bigtk_len); + + out: + wpa_ft_parse_ies_free(&parse); } if (elems.owe_dh && elems.owe_dh_len >= 2) { @@ -2165,18 +2173,20 @@ static void rx_mgmt_action_ft_request(struct wlantest *wt, bss = bss_get(wt, aa); if (!bss) { add_note(wt, MSG_INFO, "No BSS entry for Target AP"); - return; + goto out; } sta = sta_find_mlo(wt, bss, spa); if (!sta) sta = sta_get(bss, spa); if (!sta) - return; + goto out; sta->ft_over_ds = true; sta->key_mgmt = parse.key_mgmt; sta->pairwise_cipher = parse.pairwise_cipher; +out: + wpa_ft_parse_ies_free(&parse); } @@ -2227,7 +2237,7 @@ static void rx_mgmt_action_ft_response(struct wlantest *wt, if (!bss) { add_note(wt, MSG_INFO, "No BSS entry for Target AP"); - return; + goto out; } if (parse.r1kh_id) @@ -2236,14 +2246,14 @@ static void rx_mgmt_action_ft_response(struct wlantest *wt, if (wpa_derive_pmk_r1(sta->pmk_r0, sta->pmk_r0_len, sta->pmk_r0_name, bss->r1kh_id, spa, sta->pmk_r1, sta->pmk_r1_name) < 0) - return; + goto out; sta->pmk_r1_len = sta->pmk_r0_len; new_sta = sta_find_mlo(wt, bss, spa); if (!new_sta) new_sta = sta_get(bss, spa); if (!new_sta) - return; + goto out; os_memcpy(new_sta->pmk_r0, sta->pmk_r0, sta->pmk_r0_len); new_sta->pmk_r0_len = sta->pmk_r0_len; os_memcpy(new_sta->pmk_r0_name, sta->pmk_r0_name, @@ -2258,11 +2268,13 @@ static void rx_mgmt_action_ft_response(struct wlantest *wt, sta->pmk_r1_name, &ptk, ptk_name, new_sta->key_mgmt, new_sta->pairwise_cipher, 0) < 0) - return; + goto out; sta_new_ptk(wt, new_sta, &ptk); os_memcpy(new_sta->snonce, parse.fte_snonce, WPA_NONCE_LEN); os_memcpy(new_sta->anonce, parse.fte_anonce, WPA_NONCE_LEN); +out: + wpa_ft_parse_ies_free(&parse); }