[PATCH 1/2] SME: Fall back from PMKSA caching if the AP rejects it with deauthentication
Jouni Malinen
j at w1.fi
Tue Jul 28 02:33:58 PDT 2026
On Thu, Jul 09, 2026 at 10:56:34PM +0200, Louis Kotze wrote:
> When an association attempt uses SAE PMKSA caching, an AP that does not
> accept the cached PMKSA is expected to respond to the Association
> Request frame with an error status code, which makes wpa_supplicant
> drop the PMKSA cache entry and fall back to a full SAE authentication.
> However, some APs reject such an association attempt by
> deauthenticating the STA (e.g., with reason code 9) instead of sending
> an Association Response frame. That path did not drop the PMKSA cache
> entry, so every subsequent connection attempt found the same entry
> again, retried PMKSA caching, and was deauthenticated again. The
> connection kept failing in a loop without ever falling back to SAE
> authentication.
>
> Observed with a TP-Link Deco BE65 AP MLD deauthenticating with reason
> code 9 in response to an Association Request frame that used PMKSA
> caching after a previous association attempt had failed.
That's quite unfortunate AP behavior. Reason code 9 is completely
incorrect in this case since there is an authentication from the Open
System authentication exchange that happens just before this association
attempt. Is that AP not sending Association Response frame at all? If
so, it feels like it is just not moving the STA into authenticated state
based on the (admittedly pointless) Authentication frame exchange for
the PMKSA caching case with SAE.
> Drop the PMKSA cache entry when the AP deauthenticates the STA during
> an association attempt that used PMKSA caching, so that the next
> attempt falls back to a full SAE authentication.
While I try to avoid dropping PMKSA cache entries based on unprotected
frames from APs, this might need to be done in this case as well.
However, this should be more constraint than what the patch is doing.
> diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
> +void sme_event_deauth(struct wpa_supplicant *wpa_s,
> + struct deauth_info *info)
> +{
> +#ifdef CONFIG_SAE
> + /* Some APs reject an association attempt that tries to use PMKSA
> + * caching by deauthenticating the STA (e.g., with reason code 9)
> + * instead of responding to the Association Request frame with an
> + * error status code. Drop the PMKSA cache entry in that case so that
> + * the next attempt uses a full SAE authentication instead of finding
> + * the same PMKSA cache entry again and repeating the same failure. */
> + if (wpa_s->sme.sae_pmksa_caching && info && !info->locally_generated &&
> + (wpa_s->wpa_state == WPA_AUTHENTICATING ||
> + wpa_s->wpa_state == WPA_ASSOCIATING) &&
> + wpa_s->current_ssid &&
> + wpa_key_mgmt_sae(wpa_s->current_ssid->key_mgmt)) {
> + const u8 *aa;
Are there any known deployed APs using a different reason code value or
could this be made applicable only with that value 9?
Why does this include WPA_AUTHENTICATING state? I would like to do this
only for the known sequence of (Re)Association Request frame getting
rejected with a Deauthentication frame using reason code 9.
> + if (wpa_s->valid_links)
> + aa = wpa_s->ap_mld_addr;
> + else if (wpa_s->current_bss)
> + aa = wpa_s->current_bss->bssid;
> + else
> + aa = NULL;
> + wpa_sm_pmksa_cache_flush_addr(wpa_s->wpa, wpa_s->current_ssid,
> + aa);
That aa == NULL case must not be included since that would flush PMKSA
cache entries for all BSSs in the ESS based on a single unprotected
frame from one AP.
--
Jouni Malinen PGP id EFC895FA
More information about the Hostap
mailing list