diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index b511d1cc1..a565e658f 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -4621,6 +4621,7 @@ static void wpas_event_assoc_reject(struct wpa_supplicant *wpa_s, #ifdef CONFIG_FILS /* Update ERP next sequence number */ if (wpa_s->auth_alg == WPA_AUTH_ALG_FILS) { + fils_pmksa_cache_flush(wpa_s); eapol_sm_update_erp_next_seq_num( wpa_s->eapol, data->assoc_reject.fils_erp_next_seq_num); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 0d9b9caa5..9b8dca5bc 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -7537,6 +7537,35 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid) #ifdef CONFIG_FILS + +void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s) +{ + struct wpa_ssid *ssid = wpa_s->current_ssid; + const u8 *realm, *username, *rrk; + size_t realm_len, username_len, rrk_len; + u16 next_seq_num; + + /* Clear the PMKSA cache entry if FILS authentication was rejected. + * Check for ERP keys existing to limit when this can be done since + * the rejection response is not protected and such triggers should + * really not allow internal state to be modified unless required to + * avoid significant issues in functionality. In this case, this is + * needed to allow recovery from cases where the AP or authentication + * server has dropped PMKSAs and ERP keys. */ + if (!ssid || !ssid->eap.erp || !wpa_key_mgmt_fils(ssid->key_mgmt) || + eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap, + &username, &username_len, + &realm, &realm_len, &next_seq_num, + &rrk, &rrk_len) != 0 || + !realm) + return; + + wpa_dbg(wpa_s, MSG_DEBUG, "FILS: Drop PMKSA cache entry"); + wpa_sm_aborted_cached(wpa_s->wpa); + wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid); +} + + void fils_connection_failure(struct wpa_supplicant *wpa_s) { struct wpa_ssid *ssid = wpa_s->current_ssid; diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 6877f5a99..60acb53c5 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1501,6 +1501,7 @@ void wpa_supplicant_update_config(struct wpa_supplicant *wpa_s); void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s); void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid); void fils_connection_failure(struct wpa_supplicant *wpa_s); +void fils_pmksa_cache_flush(struct wpa_supplicant *wpa_s); int wpas_driver_bss_selection(struct wpa_supplicant *wpa_s); int wpas_is_p2p_prioritized(struct wpa_supplicant *wpa_s); void wpas_auth_failed(struct wpa_supplicant *wpa_s, char *reason);