From 831d8c9cf583e5c655cba50ad1472b441d8b4557 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 22 May 2019 17:26:55 +0300 Subject: [PATCH] FILS: Add RSNE into (Re)Association Response frame This AP behavior was missing from IEEE Std 802.11ai-2016, but it is needed for the RSNE validation to work correctly and for a FILS STA to be able to perform the mandatory check for RSNE matching when processing the (Re)Association Response frame (as described in 802.11ai). REVmd will be updating the standard to cover this AP case, so prepare the implementation to match that. Without this, a FILS STA might reject association whenever using FILS authentication. Signed-off-by: Jouni Malinen --- src/ap/ieee802_11.c | 11 +++++++++++ src/ap/wpa_auth.h | 3 +++ src/ap/wpa_auth_ie.c | 20 ++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 56f6363a3..a759f7f27 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3332,6 +3332,8 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, #ifdef CONFIG_FILS if (sta && sta->fils_hlp_resp) buflen += wpabuf_len(sta->fils_hlp_resp); + if (sta) + buflen += 150; #endif /* CONFIG_FILS */ #ifdef CONFIG_OWE if (sta && (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE)) @@ -3393,6 +3395,15 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta, } } #endif /* CONFIG_IEEE80211R_AP */ +#ifdef CONFIG_FILS + if (sta && status_code == WLAN_STATUS_SUCCESS && + (sta->auth_alg == WLAN_AUTH_FILS_SK || + sta->auth_alg == WLAN_AUTH_FILS_SK_PFS || + sta->auth_alg == WLAN_AUTH_FILS_PK)) + p = wpa_auth_write_assoc_resp_fils(sta->wpa_sm, p, + buf + buflen - p, + ies, ies_len); +#endif /* CONFIG_FILS */ #ifdef CONFIG_OWE if (sta && status_code == WLAN_STATUS_SUCCESS && diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index df1e17a00..a348bc25a 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -475,6 +475,9 @@ void wpa_auth_add_fils_pmk_pmkid(struct wpa_state_machine *sm, const u8 *pmk, 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); +u8 * wpa_auth_write_assoc_resp_fils(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); void wpa_auth_set_dpp_z(struct wpa_state_machine *sm, const struct wpabuf *z); diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c index 8580a5a69..2e5c9160d 100644 --- a/src/ap/wpa_auth_ie.c +++ b/src/ap/wpa_auth_ie.c @@ -1176,3 +1176,23 @@ u8 * wpa_auth_write_assoc_resp_owe(struct wpa_state_machine *sm, return pos + res; } #endif /* CONFIG_OWE */ + + +#ifdef CONFIG_FILS +u8 * wpa_auth_write_assoc_resp_fils(struct wpa_state_machine *sm, + u8 *pos, size_t max_len, + const u8 *req_ies, size_t req_ies_len) +{ + int res; + + if (!sm || + sm->wpa_key_mgmt & (WPA_KEY_MGMT_FT_FILS_SHA256 | + WPA_KEY_MGMT_FT_FILS_SHA384)) + return pos; + + res = wpa_write_rsn_ie(&sm->wpa_auth->conf, pos, max_len, NULL); + if (res < 0) + return pos; + return pos + res; +} +#endif /* CONFIG_FILS */