feat(wpa_supplicant): Match SPA when searching PMKSA cache

Store the supplicant address (SPA) in PMKSA cache entries and match
it when looking up the PMKSA cache.

(partially picked from commit 18cbdbf2b1)
This commit is contained in:
Aditi
2026-09-11 14:24:58 +08:00
committed by BOT
parent d8b677db7e
commit 03b3e0217c
3 changed files with 20 additions and 13 deletions
@@ -136,6 +136,7 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
entry->reauth_time = now.sec + dot11RSNAConfigPMKLifetime / 100 * dot11RSNAConfigPMKReauthThreshold;
entry->akmp = akmp;
os_memcpy(entry->aa, aa, ETH_ALEN);
os_memcpy(entry->spa, spa, ETH_ALEN);
entry->network_ctx = network_ctx;
return pmksa_cache_add_entry(pmksa, entry);
@@ -306,17 +307,20 @@ void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa)
* pmksa_cache_get - Fetch a PMKSA cache entry
* @pmksa: Pointer to PMKSA cache data from pmksa_cache_init()
* @aa: Authenticator address or %NULL to match any
* @spa: Supplicant address or %NULL to skip SPA matching (not recommended)
* @pmkid: PMKID or %NULL to match any
* @network_ctx: Network context or %NULL to match any
* Returns: Pointer to PMKSA cache entry or %NULL if no match was found
*/
struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
const u8 *aa, const u8 *pmkid,
const u8 *aa, const u8 *spa, const u8 *pmkid,
const void *network_ctx)
{
struct rsn_pmksa_cache_entry *entry = pmksa->pmksa;
while (entry) {
if ((aa == NULL || os_memcmp(entry->aa, aa, ETH_ALEN) == 0) &&
(spa == NULL ||
os_memcmp(entry->spa, spa, ETH_ALEN) == 0) &&
(pmkid == NULL ||
os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0) &&
(network_ctx == NULL || network_ctx == entry->network_ctx))
@@ -435,10 +439,10 @@ int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid,
sm->cur_pmksa = NULL;
if (pmkid)
sm->cur_pmksa = pmksa_cache_get(pmksa, NULL, pmkid,
sm->cur_pmksa = pmksa_cache_get(pmksa, NULL, sm->own_addr, pmkid,
network_ctx);
if (sm->cur_pmksa == NULL && bssid)
sm->cur_pmksa = pmksa_cache_get(pmksa, bssid, NULL,
sm->cur_pmksa = pmksa_cache_get(pmksa, bssid, sm->own_addr, NULL,
network_ctx);
if (sm->cur_pmksa == NULL && try_opportunistic && bssid)
sm->cur_pmksa = pmksa_cache_get_opportunistic(pmksa,
@@ -471,7 +475,7 @@ int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len)
struct rsn_pmksa_cache_entry *entry;
struct os_reltime now;
ret = os_snprintf(pos, buf + len - pos,
"Index / AA / PMKID / expiration (in seconds) / "
"Index / AA / SPA / PMKID / expiration (in seconds) / "
"opportunistic\n");
if (os_snprintf_error(buf + len - pos, ret))
return pos - buf;
@@ -481,8 +485,8 @@ int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len)
os_get_reltime(&now);
while (entry) {
i++;
ret = os_snprintf(pos, buf + len - pos, "%d " MACSTR " ",
i, MAC2STR(entry->aa));
ret = os_snprintf(pos, buf + len - pos, "%d " MACSTR " " MACSTR " ",
i, MAC2STR(entry->aa), MAC2STR(entry->spa));
if (os_snprintf_error(buf + len - pos, ret))
return pos - buf;
pos += ret;
@@ -20,6 +20,8 @@ struct rsn_pmksa_cache_entry {
os_time_t expiration;
int akmp; /* WPA_KEY_MGMT_* */
u8 aa[ETH_ALEN];
/** Supplicant MAC (SPA) this PMKSA was created for; used when matching cache */
u8 spa[ETH_ALEN];
os_time_t reauth_time;
@@ -52,7 +54,7 @@ pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry,
void *ctx, struct wpa_sm *sm);
void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa);
struct rsn_pmksa_cache_entry * pmksa_cache_get(struct rsn_pmksa_cache *pmksa,
const u8 *aa, const u8 *pmkid,
const u8 *aa, const u8 *spa, const u8 *pmkid,
const void *network_ctx);
int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len);
struct rsn_pmksa_cache_entry *
@@ -88,8 +90,8 @@ static inline void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa)
}
static inline struct rsn_pmksa_cache_entry *
pmksa_cache_get(struct rsn_pmksa_cache *pmksa, const u8 *aa, const u8 *pmkid,
const void *network_ctx)
pmksa_cache_get(struct rsn_pmksa_cache *pmksa, const u8 *aa, const u8 *spa,
const u8 *pmkid, const void *network_ctx)
{
return NULL;
}
+5 -4
View File
@@ -404,8 +404,8 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
* not have enough time to get the association information
* event before receiving this 1/4 message, so try to find a
* matching PMKSA cache entry here. */
sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, pmkid,
NULL);
sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr, sm->own_addr,
pmkid, NULL);
if (sm->cur_pmksa) {
wpa_printf(MSG_DEBUG,
"RSN: found matching PMKID from PMKSA cache");
@@ -454,7 +454,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm,
sm->network_ctx, sm->key_mgmt);
}
if (!sm->cur_pmksa && pmkid &&
pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL))
pmksa_cache_get(sm->pmksa, src_addr, sm->own_addr, pmkid, NULL))
{
wpa_printf( MSG_DEBUG,
"RSN: the new PMK matches with the "
@@ -2377,7 +2377,8 @@ int wpa_set_bss(char *macddr, char * bssid, u8 pairwise_cipher, u8 group_cipher,
struct rsn_pmksa_cache_entry *pmksa = NULL;
if (use_pmk_cache) {
pmksa = pmksa_cache_get(sm->pmksa, (const u8 *)bssid, NULL, NULL);
pmksa = pmksa_cache_get(sm->pmksa, (const u8 *)bssid, sm->own_addr,
NULL, NULL);
if (pmksa && (pmksa->akmp != sm->key_mgmt)) {
use_pmk_cache = false;
}