Store own MAC address (SPA) in supplicant PMKSA cache entries

This is needed to be able to determine whether a PMKSA cache entry is
valid when using changing MAC addresses. This could also be used to
implement a mechanism to restore a previously used MAC address instead
of a new random MAC address.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
This commit is contained in:
Jouni Malinen 2022-11-10 14:09:29 +02:00 committed by Jouni Malinen
parent f1f796a39f
commit 9f04a9c8dd
4 changed files with 9 additions and 2 deletions

View file

@ -224,6 +224,7 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
os_memcpy(entry->fils_cache_id, cache_id, FILS_CACHE_ID_LEN); os_memcpy(entry->fils_cache_id, cache_id, FILS_CACHE_ID_LEN);
} }
os_memcpy(entry->aa, aa, ETH_ALEN); os_memcpy(entry->aa, aa, ETH_ALEN);
os_memcpy(entry->spa, spa, ETH_ALEN);
entry->network_ctx = network_ctx; entry->network_ctx = network_ctx;
return pmksa_cache_add_entry(pmksa, entry); return pmksa_cache_add_entry(pmksa, entry);
@ -241,7 +242,8 @@ pmksa_cache_add_entry(struct rsn_pmksa_cache *pmksa,
pos = pmksa->pmksa; pos = pmksa->pmksa;
prev = NULL; prev = NULL;
while (pos) { while (pos) {
if (os_memcmp(entry->aa, pos->aa, ETH_ALEN) == 0) { if (os_memcmp(entry->aa, pos->aa, ETH_ALEN) == 0 &&
os_memcmp(entry->spa, pos->spa, ETH_ALEN) == 0) {
if (pos->pmk_len == entry->pmk_len && if (pos->pmk_len == entry->pmk_len &&
os_memcmp_const(pos->pmk, entry->pmk, os_memcmp_const(pos->pmk, entry->pmk,
entry->pmk_len) == 0 && entry->pmk_len) == 0 &&
@ -323,7 +325,8 @@ pmksa_cache_add_entry(struct rsn_pmksa_cache *pmksa,
} }
pmksa->pmksa_count++; pmksa->pmksa_count++;
wpa_printf(MSG_DEBUG, "RSN: Added PMKSA cache entry for " MACSTR wpa_printf(MSG_DEBUG, "RSN: Added PMKSA cache entry for " MACSTR
" network_ctx=%p akmp=0x%x", MAC2STR(entry->aa), " spa=" MACSTR " network_ctx=%p akmp=0x%x",
MAC2STR(entry->aa), MAC2STR(entry->spa),
entry->network_ctx, entry->akmp); entry->network_ctx, entry->akmp);
if (!pmksa->sm) if (!pmksa->sm)

View file

@ -20,6 +20,7 @@ struct rsn_pmksa_cache_entry {
os_time_t expiration; os_time_t expiration;
int akmp; /* WPA_KEY_MGMT_* */ int akmp; /* WPA_KEY_MGMT_* */
u8 aa[ETH_ALEN]; u8 aa[ETH_ALEN];
u8 spa[ETH_ALEN];
/* /*
* If FILS Cache Identifier is included (fils_cache_id_set), this PMKSA * If FILS Cache Identifier is included (fils_cache_id_set), this PMKSA

View file

@ -10700,6 +10700,7 @@ static int wpas_ctrl_iface_pmksa_add(struct wpa_supplicant *wpa_s,
entry->reauth_time = now.sec + reauth_time; entry->reauth_time = now.sec + reauth_time;
entry->network_ctx = ssid; entry->network_ctx = ssid;
os_memcpy(entry->spa, wpa_s->own_addr, ETH_ALEN);
entry->external = true; entry->external = true;

View file

@ -2691,6 +2691,7 @@ static void wpas_dpp_rx_peer_disc_resp(struct wpa_supplicant *wpa_s,
if (!entry) if (!entry)
goto fail; goto fail;
os_memcpy(entry->aa, src, ETH_ALEN); os_memcpy(entry->aa, src, ETH_ALEN);
os_memcpy(entry->spa, wpa_s->own_addr, ETH_ALEN);
os_memcpy(entry->pmkid, intro.pmkid, PMKID_LEN); os_memcpy(entry->pmkid, intro.pmkid, PMKID_LEN);
os_memcpy(entry->pmk, intro.pmk, intro.pmk_len); os_memcpy(entry->pmk, intro.pmk, intro.pmk_len);
entry->pmk_len = intro.pmk_len; entry->pmk_len = intro.pmk_len;
@ -3853,6 +3854,7 @@ wpas_dpp_rx_priv_peer_intro_notify(struct wpa_supplicant *wpa_s,
goto fail; goto fail;
entry->dpp_pfs = peer_version >= 2; entry->dpp_pfs = peer_version >= 2;
os_memcpy(entry->aa, src, ETH_ALEN); os_memcpy(entry->aa, src, ETH_ALEN);
os_memcpy(entry->spa, wpa_s->own_addr, ETH_ALEN);
os_memcpy(entry->pmkid, intro.pmkid, PMKID_LEN); os_memcpy(entry->pmkid, intro.pmkid, PMKID_LEN);
os_memcpy(entry->pmk, intro.pmk, intro.pmk_len); os_memcpy(entry->pmk, intro.pmk, intro.pmk_len);
entry->pmk_len = intro.pmk_len; entry->pmk_len = intro.pmk_len;