]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Check for own address (SPA) match when finding PMKSA entries
authorJouni Malinen <quic_jouni@quicinc.com>
Thu, 10 Nov 2022 12:10:55 +0000 (14:10 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 10 Nov 2022 19:13:05 +0000 (21:13 +0200)
This prevents attempts of trying to use PMKSA caching when the existing
entry was created using a different MAC address than the one that is
currently being used. This avoids exposing the longer term PMKID value
when using random MAC addresses for connections.

In practice, similar restriction was already done by flushing the PMKSA
cache entries whenever wpas_update_random_addr() changed the local
address or when the interface was marked down (e.g., for an external
operation to change the MAC address).

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/pasn/pasn_initiator.c
src/rsn_supp/pmksa_cache.c
src/rsn_supp/pmksa_cache.h
src/rsn_supp/preauth.c
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
wpa_supplicant/dpp_supplicant.c
wpa_supplicant/events.c

index 280575405dd2393c0623ab0dc5f7fef4f836c7d4..c96e6eb43da0b034344f2c02861a90eacab1e828 100644 (file)
@@ -553,7 +553,7 @@ static struct wpabuf * wpas_pasn_build_auth_1(struct pasn_data *pasn,
                struct rsn_pmksa_cache_entry *pmksa;
 
                pmksa = pmksa_cache_get(pasn->pmksa, pasn->peer_addr,
-                                       NULL, NULL, pasn->akmp);
+                                       pasn->own_addr, NULL, NULL, pasn->akmp);
                if (pmksa && pasn->custom_pmkid_valid)
                        pmkid = pasn->custom_pmkid;
                else if (pmksa)
@@ -795,6 +795,7 @@ static int wpas_pasn_set_pmk(struct pasn_data *pasn,
                }
 
                pmksa = pmksa_cache_get(pasn->pmksa, pasn->peer_addr,
+                                       pasn->own_addr,
                                        pmkid, NULL, pasn->akmp);
                if (pmksa) {
                        wpa_printf(MSG_DEBUG, "PASN: Using PMKSA");
index 07f64a18d31c55c736a7c5507b734f0bd53b99a6..257d3444f12c9c3ff274560431e2829bc0baa993 100644 (file)
@@ -148,7 +148,7 @@ static void pmksa_cache_set_expiration(struct rsn_pmksa_cache *pmksa)
                return;
 
        entry = pmksa->sm->cur_pmksa ? pmksa->sm->cur_pmksa :
-               pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL, 0);
+               pmksa_cache_get(pmksa, pmksa->sm->bssid, NULL, NULL, NULL, 0);
        if (entry && !wpa_key_mgmt_sae(entry->akmp)) {
                sec = pmksa->pmksa->reauth_time - now.sec;
                if (sec < 0)
@@ -419,13 +419,15 @@ void pmksa_cache_deinit(struct rsn_pmksa_cache *pmksa)
  * 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,
                                               int akmp)
 {
        struct rsn_pmksa_cache_entry *entry = pmksa->pmksa;
        while (entry) {
                if ((aa == NULL || os_memcmp(entry->aa, aa, ETH_ALEN) == 0) &&
+                   (!spa || os_memcmp(entry->spa, spa, ETH_ALEN) == 0) &&
                    (pmkid == NULL ||
                     os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0) &&
                    (!akmp || akmp == entry->akmp) &&
@@ -601,11 +603,11 @@ 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, akmp);
+               sm->cur_pmksa = pmksa_cache_get(pmksa, NULL, sm->own_addr,
+                                               pmkid, network_ctx, akmp);
        if (sm->cur_pmksa == NULL && bssid)
-               sm->cur_pmksa = pmksa_cache_get(pmksa, bssid, NULL,
-                                               network_ctx, akmp);
+               sm->cur_pmksa = pmksa_cache_get(pmksa, bssid, sm->own_addr,
+                                               NULL, network_ctx, akmp);
        if (sm->cur_pmksa == NULL && try_opportunistic && bssid)
                sm->cur_pmksa = pmksa_cache_get_opportunistic(pmksa,
                                                              network_ctx,
index 55b0d71220929b186b09157ba0a627afbf0ea0cd..b34532c0ac8d26257881f1d97fa5f7b4da334748 100644 (file)
@@ -65,7 +65,8 @@ 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 akmp);
 int pmksa_cache_list(struct rsn_pmksa_cache *pmksa, char *buf, size_t len);
index a96655f7786e98e4baf021d4cf05b80d9ea84365..8f86820a768a986b7494b5190190107ba72612fe 100644 (file)
@@ -330,7 +330,8 @@ 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, 0);
+               p = pmksa_cache_get(sm->pmksa, candidate->bssid, sm->own_addr,
+                                   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 "
@@ -491,7 +492,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, 0);
+       pmksa = pmksa_cache_get(sm->pmksa, bssid, sm->own_addr, NULL, NULL, 0);
        if (pmksa && (!pmksa->opportunistic ||
                      !(ie.capabilities & WPA_CAPABILITY_PREAUTH)))
                return;
index 74ea660883f8af2e4891af51beb3336a3b971cbe..666a63a1a73219adc0b0481cb7116a4a196619ad 100644 (file)
@@ -318,7 +318,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,
+               sm->cur_pmksa = pmksa_cache_get(sm->pmksa, src_addr,
+                                               sm->own_addr, pmkid,
                                                NULL, 0);
                if (sm->cur_pmksa) {
                        wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
@@ -434,8 +435,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,
-                                   0)) {
+                           pmksa_cache_get(sm->pmksa, src_addr, sm->own_addr,
+                                           pmkid, NULL, 0)) {
                                wpa_dbg(sm->ctx->msg_ctx, MSG_DEBUG,
                                        "RSN: the new PMK matches with the "
                                        "PMKID");
@@ -4731,10 +4732,11 @@ 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,
+int wpa_sm_pmksa_exists(struct wpa_sm *sm, const u8 *bssid, const u8 *own_addr,
                        const void *network_ctx)
 {
-       return pmksa_cache_get(sm->pmksa, bssid, NULL, network_ctx, 0) != NULL;
+       return pmksa_cache_get(sm->pmksa, bssid, own_addr, NULL, network_ctx,
+                              0) != NULL;
 }
 
 
@@ -4744,7 +4746,8 @@ struct rsn_pmksa_cache_entry * wpa_sm_pmksa_cache_get(struct wpa_sm *sm,
                                                      const void *network_ctx,
                                                      int akmp)
 {
-       return pmksa_cache_get(sm->pmksa, aa, pmkid, network_ctx, akmp);
+       return pmksa_cache_get(sm->pmksa, aa, sm->own_addr, pmkid, network_ctx,
+                              akmp);
 }
 
 
index f8854078a05c0f9b261d1da40fe5a21dedd1eb1f..c8456469978d92f64ed9eefb4e8a17207087ed4d 100644 (file)
@@ -221,7 +221,7 @@ wpa_sm_pmksa_cache_add_entry(struct wpa_sm *sm,
 void wpa_sm_pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
                            const u8 *pmkid, const u8 *bssid,
                            const u8 *fils_cache_id);
-int wpa_sm_pmksa_exists(struct wpa_sm *sm, const u8 *bssid,
+int wpa_sm_pmksa_exists(struct wpa_sm *sm, const u8 *bssid, const u8 *own_addr,
                        const void *network_ctx);
 void wpa_sm_drop_sa(struct wpa_sm *sm);
 struct rsn_pmksa_cache_entry * wpa_sm_pmksa_cache_get(struct wpa_sm *sm,
index e5be5ba133382b21b2c90b6d2a2fb153b8c13aa6..6d0cd27cb01a9ab3eabde6545ce2de490b4ffa45 100644 (file)
@@ -4358,7 +4358,7 @@ int wpas_dpp_check_connect(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
        if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
            !(ied.key_mgmt & WPA_KEY_MGMT_DPP))
                return 0; /* AP does not support DPP AKM - continue */
-       if (wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, ssid))
+       if (wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, wpa_s->own_addr, ssid))
                return 0; /* PMKSA exists for DPP AKM - continue */
 
        if (!ssid->dpp_connector || !ssid->dpp_netaccesskey ||
index 0356c809a635c1a7a3482916d1aa6c1b0442488c..5af3b61770dd1265216c9b36656859823c53ccab 100644 (file)
@@ -1515,7 +1515,8 @@ skip_assoc_disallow:
 
 #ifdef CONFIG_DPP
        if ((ssid->key_mgmt & WPA_KEY_MGMT_DPP) &&
-           !wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, ssid) &&
+           !wpa_sm_pmksa_exists(wpa_s->wpa, bss->bssid, wpa_s->own_addr,
+                                ssid) &&
            (!ssid->dpp_connector || !ssid->dpp_netaccesskey ||
             !ssid->dpp_csign)) {
                if (debug_print)