diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index eee468396..78f01dfa5 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -2865,6 +2865,7 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta, "state machine"); return WLAN_STATUS_UNSPECIFIED_FAILURE; } + wpa_auth_set_auth_alg(sta->wpa_sm, sta->auth_alg); res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm, hapd->iface->freq, wpa_ie, wpa_ie_len, diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index cc77acb1b..1cb8113d0 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -2210,6 +2210,16 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk, pmk_r0_name, WPA_PMK_NAME_LEN); wpa_ft_store_pmk_fils(sm, pmk_r0, pmk_r0_name); os_memset(fils_ft, 0, sizeof(fils_ft)); + + res = wpa_derive_pmk_r1_name(pmk_r0_name, conf->r1_key_holder, + sm->addr, sm->pmk_r1_name, + use_sha384); + os_memset(pmk_r0, 0, PMK_LEN_MAX); + if (res < 0) + return -1; + wpa_hexdump(MSG_DEBUG, "FILS+FT: PMKR1Name", sm->pmk_r1_name, + WPA_PMK_NAME_LEN); + sm->pmk_r1_name_valid = 1; } #endif /* CONFIG_IEEE80211R_AP */ @@ -4812,6 +4822,13 @@ void wpa_auth_get_fils_aead_params(struct wpa_state_machine *sm, #endif /* CONFIG_FILS */ +void wpa_auth_set_auth_alg(struct wpa_state_machine *sm, u16 auth_alg) +{ + if (sm) + sm->auth_alg = auth_alg; +} + + #ifdef CONFIG_TESTING_OPTIONS int wpa_auth_resend_m1(struct wpa_state_machine *sm, int change_anonce, diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 1d57dcae7..50a8d1743 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -473,6 +473,7 @@ void wpa_auth_get_fils_aead_params(struct wpa_state_machine *sm, u8 * wpa_auth_write_assoc_resp_owe(struct wpa_state_machine *sm, u8 *pos, size_t max_len, const u8 *req_ies, size_t req_ies_len); +void wpa_auth_set_auth_alg(struct wpa_state_machine *sm, u16 auth_alg); int wpa_auth_resend_m1(struct wpa_state_machine *sm, int change_anonce, void (*cb)(void *ctx1, void *ctx2), diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 31ca4e5d0..1fb6a0d86 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -2386,10 +2386,24 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, end = pos + max_len; - if (auth_alg == WLAN_AUTH_FT) { + if (auth_alg == WLAN_AUTH_FT || + ((auth_alg == WLAN_AUTH_FILS_SK || + auth_alg == WLAN_AUTH_FILS_SK_PFS || + auth_alg == WLAN_AUTH_FILS_PK) && + (sm->wpa_key_mgmt & (WPA_KEY_MGMT_FT_FILS_SHA256 | + WPA_KEY_MGMT_FT_FILS_SHA384)))) { + if (!sm->pmk_r1_name_valid) { + wpa_printf(MSG_ERROR, + "FT: PMKR1Name is not valid for Assoc Resp RSNE"); + return NULL; + } + wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name for Assoc Resp RSNE", + sm->pmk_r1_name, WPA_PMK_NAME_LEN); /* * RSN (only present if this is a Reassociation Response and - * part of a fast BSS transition) + * part of a fast BSS transition; or if this is a + * (Re)Association Response frame during an FT initial mobility + * domain association using FILS) */ res = wpa_write_rsn_ie(conf, pos, end - pos, sm->pmk_r1_name); if (res < 0) diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h index a349304d5..a3164d265 100644 --- a/src/ap/wpa_auth_i.h +++ b/src/ap/wpa_auth_i.h @@ -22,6 +22,7 @@ struct wpa_state_machine { u8 addr[ETH_ALEN]; u8 p2p_dev_addr[ETH_ALEN]; + u16 auth_alg; enum { WPA_PTK_INITIALIZE, WPA_PTK_DISCONNECT, WPA_PTK_DISCONNECTED, diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c index 4a96008c1..791c5a01b 100644 --- a/src/ap/wpa_auth_ie.c +++ b/src/ap/wpa_auth_ie.c @@ -852,6 +852,21 @@ int wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth, else sm->wpa = WPA_VERSION_WPA; +#if defined(CONFIG_IEEE80211R_AP) && defined(CONFIG_FILS) + if ((sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_FILS_SHA256 || + sm->wpa_key_mgmt == WPA_KEY_MGMT_FT_FILS_SHA384) && + (sm->auth_alg == WLAN_AUTH_FILS_SK || + sm->auth_alg == WLAN_AUTH_FILS_SK_PFS || + sm->auth_alg == WLAN_AUTH_FILS_PK) && + (data.num_pmkid != 1 || !data.pmkid || !sm->pmk_r1_name_valid || + os_memcmp_const(data.pmkid, sm->pmk_r1_name, + WPA_PMK_NAME_LEN) != 0)) { + wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG, + "No PMKR1Name match for FILS+FT"); + return WPA_INVALID_PMKID; + } +#endif /* CONFIG_IEEE80211R_AP && CONFIG_FILS */ + sm->pmksa = NULL; for (i = 0; i < data.num_pmkid; i++) { wpa_hexdump(MSG_DEBUG, "RSN IE: STA PMKID",