SAE: Remove current PMKSA from driver after reauth threshold is passed

wpa_supplicant postpones expired PMKSA deletion untillassociation is
lost for SAE to avoid forced disconnection. But during this time the
driver may use the expired PMKSA for reassociation with the current
connected AP.

Remove the current PMKSA for SAE from the driver after reauth threshold
is passed when the driver takes care of BSS selection.

Signed-off-by: Veerendranath Jakkam <quic_vjakkam@quicinc.com>
This commit is contained in:
Veerendranath Jakkam 2023-09-27 11:27:13 +05:30 committed by Jouni Malinen
parent 2d4be0019d
commit 2f911fb155
6 changed files with 42 additions and 1 deletions

View file

@ -132,6 +132,23 @@ static void pmksa_cache_reauth(void *eloop_ctx, void *timeout_ctx)
if (!pmksa->sm)
return;
if (pmksa->sm->driver_bss_selection) {
struct rsn_pmksa_cache_entry *entry;
entry = pmksa->sm->cur_pmksa ?
pmksa->sm->cur_pmksa :
pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL,
NULL, 0);
if (entry && wpa_key_mgmt_sae(entry->akmp)) {
wpa_printf(MSG_DEBUG,
"RSN: remove reauth threshold passed PMKSA from the driver for SAE");
entry->sae_reauth_scheduled = true;
wpa_sm_remove_pmkid(pmksa->sm, entry->network_ctx,
entry->aa, entry->pmkid, NULL);
return;
}
}
pmksa->sm->cur_pmksa = NULL;
eapol_sm_request_reauth(pmksa->sm->eapol);
}
@ -178,7 +195,10 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa)
entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa :
pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL, NULL, 0);
if (entry && !wpa_key_mgmt_sae(entry->akmp)) {
if (entry &&
(!wpa_key_mgmt_sae(entry->akmp) ||
(pmksa->sm->driver_bss_selection &&
!entry->sae_reauth_scheduled))) {
sec = pmksa->pmksa->reauth_time - now.sec;
if (sec < 0)
sec = 0;

View file

@ -45,6 +45,13 @@ struct rsn_pmksa_cache_entry {
void *network_ctx;
int opportunistic;
bool external;
/**
* This field is used to avoid duplicate pmksa_cache_reauth() calls for
* every 10 minutes during the periodic expiration check of the current
* PMKSA for SAE.
*/
bool sae_reauth_scheduled;
};
struct rsn_pmksa_cache;

View file

@ -6511,3 +6511,11 @@ void wpa_sm_set_cur_pmksa(struct wpa_sm *sm,
if (sm)
sm->cur_pmksa = entry;
}
void wpa_sm_set_driver_bss_selection(struct wpa_sm *sm,
bool driver_bss_selection)
{
if (sm)
sm->driver_bss_selection = driver_bss_selection;
}

View file

@ -611,5 +611,7 @@ struct rsn_pmksa_cache * wpa_sm_get_pmksa_cache(struct wpa_sm *sm);
void wpa_sm_set_cur_pmksa(struct wpa_sm *sm,
struct rsn_pmksa_cache_entry *entry);
const u8 * wpa_sm_get_auth_addr(struct wpa_sm *sm);
void wpa_sm_set_driver_bss_selection(struct wpa_sm *sm,
bool driver_bss_selection);
#endif /* WPA_H */

View file

@ -222,6 +222,7 @@ struct wpa_sm {
struct wpa_sm_mlo mlo;
bool wmm_enabled;
bool driver_bss_selection;
};

View file

@ -7161,6 +7161,9 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
#ifdef CONFIG_PASN
wpa_pasn_sm_set_caps(wpa_s->wpa, wpa_s->drv_flags2);
#endif /* CONFIG_PASN */
wpa_sm_set_driver_bss_selection(wpa_s->wpa,
!!(wpa_s->drv_flags &
WPA_DRIVER_FLAGS_BSS_SELECTION));
if (wpa_s->max_remain_on_chan == 0)
wpa_s->max_remain_on_chan = 1000;