Add support to reconfigure or flush PMKSA cache on interface enable

Update PMKSA cache when interface is disabled and then enabled based on
the new MAC address. If the new MAC address is same as the previous MAC
address, the PMKSA cache entries are valid and hence update the PMKSA
cache entries to the driver. If the new MAC address is not same as the
previous MAC address, the PMKSA cache entries will not be valid anymore
and hence delete the PMKSA cache entries.

Signed-off-by: Veerendranath Jakkam <vjakkam@codeaurora.org>
This commit is contained in:
Veerendranath Jakkam 2021-10-07 19:46:04 +05:30 committed by Jouni Malinen
parent 6f634b0032
commit 4775a5f827
5 changed files with 58 additions and 0 deletions

View file

@ -667,4 +667,37 @@ pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
return pmksa; return pmksa;
} }
void pmksa_cache_reconfig(struct rsn_pmksa_cache *pmksa)
{
struct rsn_pmksa_cache_entry *entry;
struct os_reltime now;
if (!pmksa || !pmksa->pmksa)
return;
os_get_reltime(&now);
for (entry = pmksa->pmksa; entry; entry = entry->next) {
u32 life_time;
u8 reauth_threshold;
if (entry->expiration - now.sec < 1 ||
entry->reauth_time - now.sec < 1)
continue;
life_time = entry->expiration - now.sec;
reauth_threshold = (entry->reauth_time - now.sec) * 100 /
life_time;
if (!reauth_threshold)
continue;
wpa_sm_add_pmkid(pmksa->sm, entry->network_ctx, entry->aa,
entry->pmkid,
entry->fils_cache_id_set ?
entry->fils_cache_id : NULL,
entry->pmk, entry->pmk_len, life_time,
reauth_threshold, entry->akmp);
}
}
#endif /* IEEE8021X_EAPOL */ #endif /* IEEE8021X_EAPOL */

View file

@ -86,6 +86,7 @@ pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa,
void *network_ctx, const u8 *aa, int akmp); void *network_ctx, const u8 *aa, int akmp);
void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx, void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx,
const u8 *pmk, size_t pmk_len, bool external_only); const u8 *pmk, size_t pmk_len, bool external_only);
void pmksa_cache_reconfig(struct rsn_pmksa_cache *pmksa);
#else /* IEEE8021X_EAPOL */ #else /* IEEE8021X_EAPOL */
@ -163,6 +164,10 @@ static inline void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa,
{ {
} }
static inline void pmksa_cache_reconfig(struct rsn_pmksa_cache *pmksa)
{
}
#endif /* IEEE8021X_EAPOL */ #endif /* IEEE8021X_EAPOL */
#endif /* PMKSA_CACHE_H */ #endif /* PMKSA_CACHE_H */

View file

@ -5246,3 +5246,10 @@ void wpa_pasn_pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
key_mgmt, 0); key_mgmt, 0);
} }
#endif /* CONFIG_PASN */ #endif /* CONFIG_PASN */
void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm)
{
if (sm)
pmksa_cache_reconfig(sm->pmksa);
}

View file

@ -216,6 +216,7 @@ void wpa_sm_set_ptk_kck_kek(struct wpa_sm *sm,
const u8 *ptk_kck, size_t ptk_kck_len, const u8 *ptk_kck, size_t ptk_kck_len,
const u8 *ptk_kek, size_t ptk_kek_len); const u8 *ptk_kek, size_t ptk_kek_len);
int wpa_fils_is_completed(struct wpa_sm *sm); int wpa_fils_is_completed(struct wpa_sm *sm);
void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm);
#else /* CONFIG_NO_WPA */ #else /* CONFIG_NO_WPA */
@ -425,6 +426,10 @@ static inline int wpa_fils_is_completed(struct wpa_sm *sm)
return 0; return 0;
} }
static inline void wpa_sm_pmksa_cache_reconfig(struct wpa_sm *sm)
{
}
#endif /* CONFIG_NO_WPA */ #endif /* CONFIG_NO_WPA */
#ifdef CONFIG_IEEE80211R #ifdef CONFIG_IEEE80211R

View file

@ -5344,13 +5344,21 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
break; break;
case EVENT_INTERFACE_MAC_CHANGED: case EVENT_INTERFACE_MAC_CHANGED:
wpa_supplicant_update_mac_addr(wpa_s); wpa_supplicant_update_mac_addr(wpa_s);
wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
break; break;
case EVENT_INTERFACE_ENABLED: case EVENT_INTERFACE_ENABLED:
wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled"); wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled");
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
u8 addr[ETH_ALEN];
eloop_cancel_timeout(wpas_clear_disabled_interface, eloop_cancel_timeout(wpas_clear_disabled_interface,
wpa_s, NULL); wpa_s, NULL);
os_memcpy(addr, wpa_s->own_addr, ETH_ALEN);
wpa_supplicant_update_mac_addr(wpa_s); wpa_supplicant_update_mac_addr(wpa_s);
if (os_memcmp(addr, wpa_s->own_addr, ETH_ALEN) != 0)
wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
else
wpa_sm_pmksa_cache_reconfig(wpa_s->wpa);
wpa_supplicant_set_default_scan_ies(wpa_s); wpa_supplicant_set_default_scan_ies(wpa_s);
if (wpa_s->p2p_mgmt) { if (wpa_s->p2p_mgmt) {
wpa_supplicant_set_state(wpa_s, wpa_supplicant_set_state(wpa_s,