diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index fe3dee30d..5d276bf83 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -3203,11 +3203,15 @@ static void handle_assoc_cb(struct hostapd_data *hapd, new_assoc = 0; sta->flags |= WLAN_STA_ASSOC; sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE; - if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa && !hapd->conf->osen) || + if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa && + !hapd->conf->osen) || + sta->auth_alg == WLAN_AUTH_FILS_SK || + sta->auth_alg == WLAN_AUTH_FILS_SK_PFS || + sta->auth_alg == WLAN_AUTH_FILS_PK || sta->auth_alg == WLAN_AUTH_FT) { /* - * Open, static WEP, or FT protocol; no separate authorization - * step. + * Open, static WEP, FT protocol, or FILS; no separate + * authorization step. */ ap_sta_set_authorized(hapd, sta, 1); } diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 48d80de4c..6367ff104 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -617,6 +617,16 @@ int wpa_auth_sta_associated(struct wpa_authenticator *wpa_auth, } #endif /* CONFIG_IEEE80211R */ +#ifdef CONFIG_FILS + if (sm->fils_completed) { + wpa_auth_logger(wpa_auth, sm->addr, LOGGER_DEBUG, + "FILS authentication already completed - do not start 4-way handshake"); + /* Go to PTKINITDONE state to allow GTK rekeying */ + sm->wpa_ptk_state = WPA_PTK_PTKINITDONE; + return 0; + } +#endif /* CONFIG_FILS */ + if (sm->started) { os_memset(&sm->key_replay, 0, sizeof(sm->key_replay)); sm->ReAuthenticationRequest = TRUE; @@ -2380,6 +2390,8 @@ int fils_encrypt_assoc(struct wpa_state_machine *sm, u8 *buf, current_len += wpabuf_len(plain) + AES_BLOCK_SIZE; wpabuf_free(plain); + sm->fils_completed = 1; + return current_len; } diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h index bc5048fe5..baa6ed960 100644 --- a/src/ap/wpa_auth_i.h +++ b/src/ap/wpa_auth_i.h @@ -143,6 +143,7 @@ struct wpa_state_machine { u8 fils_key_auth_sta[FILS_MAX_KEY_AUTH_LEN]; u8 fils_key_auth_ap[FILS_MAX_KEY_AUTH_LEN]; size_t fils_key_auth_len; + unsigned int fils_completed:1; #endif /* CONFIG_FILS */ };