diff --git a/src/rsn_supp/pmksa_cache.c b/src/rsn_supp/pmksa_cache.c index f5024f20f..fdd522087 100644 --- a/src/rsn_supp/pmksa_cache.c +++ b/src/rsn_supp/pmksa_cache.c @@ -96,7 +96,7 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa) eloop_register_timeout(sec + 1, 0, pmksa_cache_expire, pmksa, NULL); entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa : - pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL); + pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL, 0); if (entry) { sec = pmksa->pmksa->reauth_time - now.sec; if (sec < 0) @@ -341,17 +341,20 @@ void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa) * @aa: Authenticator address or %NULL to match any * @pmkid: PMKID or %NULL to match any * @network_ctx: Network context or %NULL to match any + * @akmp: Specific AKMP to search for or 0 for 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 void *network_ctx) + const void *network_ctx, + int akmp) { struct rsn_pmksa_cache_entry *entry = pmksa->pmksa; while (entry) { if ((aa == NULL || os_memcmp(entry->aa, aa, ETH_ALEN) == 0) && (pmkid == NULL || os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0) && + (!akmp || akmp == entry->akmp) && (network_ctx == NULL || network_ctx == entry->network_ctx)) return entry; entry = entry->next; @@ -390,6 +393,7 @@ pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa, * @pmksa: Pointer to PMKSA cache data from pmksa_cache_init() * @network_ctx: Network configuration context * @aa: Authenticator address for the new AP + * @akmp: Specific AKMP to search for or 0 for any * Returns: Pointer to a new PMKSA cache entry or %NULL if not available * * Try to create a new PMKSA cache entry opportunistically by guessing that the @@ -398,7 +402,7 @@ pmksa_cache_clone_entry(struct rsn_pmksa_cache *pmksa, */ struct rsn_pmksa_cache_entry * pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa, void *network_ctx, - const u8 *aa) + const u8 *aa, int akmp) { struct rsn_pmksa_cache_entry *entry = pmksa->pmksa; @@ -406,7 +410,8 @@ pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa, void *network_ctx, if (network_ctx == NULL) return NULL; while (entry) { - if (entry->network_ctx == network_ctx) { + if (entry->network_ctx == network_ctx && + (!akmp || entry->akmp == akmp)) { entry = pmksa_cache_clone_entry(pmksa, entry, aa); if (entry) { wpa_printf(MSG_DEBUG, "RSN: added " @@ -476,11 +481,13 @@ void pmksa_cache_clear_current(struct wpa_sm *sm) */ int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid, const u8 *bssid, void *network_ctx, - int try_opportunistic, const u8 *fils_cache_id) + int try_opportunistic, const u8 *fils_cache_id, + int akmp) { struct rsn_pmksa_cache *pmksa = sm->pmksa; wpa_printf(MSG_DEBUG, "RSN: PMKSA cache search - network_ctx=%p " - "try_opportunistic=%d", network_ctx, try_opportunistic); + "try_opportunistic=%d akmp=0x%x", + network_ctx, try_opportunistic, akmp); if (pmkid) wpa_hexdump(MSG_DEBUG, "RSN: Search for PMKID", pmkid, PMKID_LEN); @@ -495,14 +502,14 @@ 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, - network_ctx); + network_ctx, akmp); if (sm->cur_pmksa == NULL && bssid) sm->cur_pmksa = pmksa_cache_get(pmksa, bssid, NULL, - network_ctx); + network_ctx, akmp); if (sm->cur_pmksa == NULL && try_opportunistic && bssid) sm->cur_pmksa = pmksa_cache_get_opportunistic(pmksa, network_ctx, - bssid); + bssid, akmp); if (sm->cur_pmksa == NULL && fils_cache_id) sm->cur_pmksa = pmksa_cache_get_fils_cache_id(pmksa, network_ctx, diff --git a/src/rsn_supp/pmksa_cache.h b/src/rsn_supp/pmksa_cache.h index f9a72a6f6..626761dea 100644 --- a/src/rsn_supp/pmksa_cache.h +++ b/src/rsn_supp/pmksa_cache.h @@ -61,7 +61,8 @@ pmksa_cache_init(void (*free_cb)(struct rsn_pmksa_cache_entry *entry, 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 void *network_ctx); + const void *network_ctx, + int akmp); int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len); struct rsn_pmksa_cache_entry * pmksa_cache_head(struct rsn_pmksa_cache *pmksa); struct rsn_pmksa_cache_entry * @@ -76,10 +77,11 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get_current(struct wpa_sm *sm); void pmksa_cache_clear_current(struct wpa_sm *sm); int pmksa_cache_set_current(struct wpa_sm *sm, const u8 *pmkid, const u8 *bssid, void *network_ctx, - int try_opportunistic, const u8 *fils_cache_id); + int try_opportunistic, const u8 *fils_cache_id, + int akmp); struct rsn_pmksa_cache_entry * pmksa_cache_get_opportunistic(struct rsn_pmksa_cache *pmksa, - void *network_ctx, const u8 *aa); + void *network_ctx, const u8 *aa, int akmp); void pmksa_cache_flush(struct rsn_pmksa_cache *pmksa, void *network_ctx, const u8 *pmk, size_t pmk_len); diff --git a/src/rsn_supp/preauth.c b/src/rsn_supp/preauth.c index d4276b953..d0c43f464 100644 --- a/src/rsn_supp/preauth.c +++ b/src/rsn_supp/preauth.c @@ -323,7 +323,7 @@ void rsn_preauth_candidate_process(struct wpa_sm *sm) dl_list_for_each_safe(candidate, n, &sm->pmksa_candidates, struct rsn_pmksa_candidate, list) { struct rsn_pmksa_cache_entry *p = NULL; - p = pmksa_cache_get(sm->pmksa, candidate->bssid, NULL, NULL); + p = pmksa_cache_get(sm->pmksa, candidate->bssid, NULL, NULL, 0); if (os_memcmp(sm->bssid, candidate->bssid, ETH_ALEN) != 0 && (p == NULL || p->opportunistic)) { wpa_msg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: PMKSA " @@ -372,7 +372,7 @@ void pmksa_candidate_add(struct wpa_sm *sm, const u8 *bssid, if (sm->network_ctx && sm->proactive_key_caching) pmksa_cache_get_opportunistic(sm->pmksa, sm->network_ctx, - bssid); + bssid, 0); if (!preauth) { wpa_printf(MSG_DEBUG, "RSN: Ignored PMKID candidate without " @@ -483,7 +483,7 @@ void rsn_preauth_scan_result(struct wpa_sm *sm, const u8 *bssid, if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ie)) return; - pmksa = pmksa_cache_get(sm->pmksa, bssid, NULL, NULL); + pmksa = pmksa_cache_get(sm->pmksa, bssid, NULL, NULL, 0); if (pmksa && (!pmksa->opportunistic || !(ie.capabilities & WPA_CAPABILITY_PREAUTH))) return; diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index f84d7d01c..da01494a3 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -268,7 +268,7 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm, * 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); + NULL, 0); if (sm->cur_pmksa) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: found matching PMKID from PMKSA cache"); @@ -354,8 +354,8 @@ static int wpa_supplicant_get_pmk(struct wpa_sm *sm, fils_cache_id); } if (!sm->cur_pmksa && pmkid && - pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL)) - { + pmksa_cache_get(sm->pmksa, src_addr, pmkid, NULL, + 0)) { wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG, "RSN: the new PMK matches with the " "PMKID"); @@ -3130,7 +3130,7 @@ void wpa_sm_pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len, int wpa_sm_pmksa_exists(struct wpa_sm *sm, const u8 *bssid, const void *network_ctx) { - return pmksa_cache_get(sm->pmksa, bssid, NULL, network_ctx) != NULL; + return pmksa_cache_get(sm->pmksa, bssid, NULL, network_ctx, 0) != NULL; } diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 19c8475b6..7c5452802 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -335,7 +335,7 @@ static void wpa_find_assoc_pmkid(struct wpa_supplicant *wpa_s) for (i = 0; i < ie.num_pmkid; i++) { pmksa_set = pmksa_cache_set_current(wpa_s->wpa, ie.pmkid + i * PMKID_LEN, - NULL, NULL, 0, NULL); + NULL, NULL, 0, NULL, 0); if (pmksa_set == 0) { eapol_sm_notify_pmkid_attempt(wpa_s->eapol); break; @@ -3805,7 +3805,7 @@ static void wpa_supplicant_event_assoc_auth(struct wpa_supplicant *wpa_s, /* Update the current PMKSA used for this connection */ pmksa_cache_set_current(wpa_s->wpa, data->assoc_info.fils_pmkid, - NULL, NULL, 0, NULL); + NULL, NULL, 0, NULL, 0); } } #endif /* CONFIG_FILS */ diff --git a/wpa_supplicant/preauth_test.c b/wpa_supplicant/preauth_test.c index a213a30f1..f2fff550a 100644 --- a/wpa_supplicant/preauth_test.c +++ b/wpa_supplicant/preauth_test.c @@ -348,7 +348,7 @@ int main(int argc, char *argv[]) ret = -2; else { ret = pmksa_cache_set_current(wpa_s.wpa, NULL, bssid, NULL, 0, - NULL) ? 0 : -3; + NULL, 0) ? 0 : -3; } test_eapol_clean(&wpa_s); diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 460e4e6a7..8481b9aab 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -333,7 +333,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, #endif /* CONFIG_FILS */ if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, wpa_s->current_ssid, - try_opportunistic, cache_id) == 0) + try_opportunistic, cache_id, + 0) == 0) eapol_sm_notify_pmkid_attempt(wpa_s->eapol); wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie); if (wpa_supplicant_set_suites(wpa_s, bss, ssid, @@ -548,7 +549,7 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, #ifdef CONFIG_SAE if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE && pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, ssid, 0, - NULL) == 0) { + NULL, WPA_KEY_MGMT_SAE) == 0) { wpa_dbg(wpa_s, MSG_DEBUG, "PMKSA cache entry found - try to use PMKSA caching instead of new SAE authentication"); wpa_sm_set_pmk_from_pmksa(wpa_s->wpa); @@ -616,8 +617,8 @@ static void sme_send_authentication(struct wpa_supplicant *wpa_s, if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, ssid, 0, - wpa_bss_get_fils_cache_id(bss)) == - 0) + wpa_bss_get_fils_cache_id(bss), + 0) == 0) wpa_printf(MSG_DEBUG, "SME: Try to use FILS with PMKSA caching"); resp = fils_build_auth(wpa_s->wpa, ssid->fils_dh_group, md); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 9808640ea..9ee099613 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2427,7 +2427,7 @@ static u8 * wpas_populate_assoc_ies( #endif /* CONFIG_FILS */ if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, ssid, try_opportunistic, - cache_id) == 0) + cache_id, 0) == 0) eapol_sm_notify_pmkid_attempt(wpa_s->eapol); wpa_ie_len = max_wpa_ie_len; if (wpa_supplicant_set_suites(wpa_s, bss, ssid,