[PATCH v4 12/13] MLD STA: Add PMKSA entries with both AP MLD address and AP link addresses

Veerendranath Jakkam quic_vjakkam at quicinc.com
Thu Nov 3 01:08:55 PDT 2022


Add PMKSA entries with both AP MLD address and AP link addresse for MLO
connection. Per-BSSID PMKSA entries could be used in case the station
wants to associate with one of the BSSs without enabling MLO capability
later.

Signed-off-by: Veerendranath Jakkam <quic_vjakkam at quicinc.com>
---
 src/rsn_supp/wpa.c              | 46 ++++++++++++++++++++++++++++-----
 src/rsn_supp/wpa.h              |  4 +--
 wpa_supplicant/events.c         |  7 +++--
 wpa_supplicant/sme.c            | 26 ++++++++++++++++---
 wpa_supplicant/wpa_supplicant.c |  6 ++++-
 5 files changed, 75 insertions(+), 14 deletions(-)

diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index bab4e3920..19c85bea1 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -2271,6 +2271,25 @@ static int wpa_validate_mlo_ieee80211w_kdes(struct wpa_sm *sm,
 }
 
 
+static void mlo_links_pmksa_cache_add(struct wpa_sm *sm, const u8 *pmk,
+				      size_t pmk_len, const u8 *pmkid,
+				      const u8 *kck, size_t kck_len,
+				      void *network_ctx, int akmp,
+				      const u8 *cache_id)
+{
+	int i;
+
+	for (i = 0; i < MAX_NUM_MLO_LINKS; i++) {
+		if (!(sm->mlo.valid_links & BIT(i)))
+			continue;
+
+		pmksa_cache_add(sm->pmksa, pmk, pmk_len, pmkid, kck, kck_len,
+				sm->mlo.links[i].bssid, sm->own_addr,
+				network_ctx, akmp, cache_id);
+	}
+}
+
+
 static void wpa_supplicant_process_mlo_3_of_4(struct wpa_sm *sm,
 					      const struct wpa_eapol_key *key,
 					      u16 ver, const u8 *key_data,
@@ -2412,6 +2431,10 @@ static void wpa_supplicant_process_mlo_3_of_4(struct wpa_sm *sm,
 				     sm->network_ctx, sm->key_mgmt, NULL);
 		if (!sm->cur_pmksa)
 			sm->cur_pmksa = sa;
+
+		mlo_links_pmksa_cache_add(sm, sm->pmk, sm->pmk_len, NULL,
+					  sm->ptk.kck, sm->ptk.kck_len,
+					  sm->network_ctx, sm->key_mgmt, NULL);
 	}
 
 	if (ie.transition_disable)
@@ -3998,12 +4021,12 @@ void wpa_sm_notify_disassoc(struct wpa_sm *sm)
  * @pmk: The new PMK
  * @pmk_len: The length of the new PMK in bytes
  * @pmkid: Calculated PMKID
- * @bssid: AA to add into PMKSA cache or %NULL to not cache the PMK
+ * @auth_addr: AA to add into PMKSA cache or %NULL to not cache the PMK
  *
  * Configure the PMK for WPA state machine.
  */
 void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
-		    const u8 *pmkid, const u8 *bssid)
+		    const u8 *pmkid, const u8 *auth_addr)
 {
 	if (sm == NULL)
 		return;
@@ -4019,12 +4042,17 @@ void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
 	os_memcpy(sm->xxkey, pmk, pmk_len);
 #endif /* CONFIG_IEEE80211R */
 
-	if (bssid) {
+	if (auth_addr) {
 		sm->cur_pmksa = pmksa_cache_add(sm->pmksa, pmk, pmk_len,
-						pmkid, NULL, 0, bssid,
+						pmkid, NULL, 0, auth_addr,
 						sm->own_addr,
 						sm->network_ctx, sm->key_mgmt,
 						NULL);
+		if (sm->mlo.valid_links &&
+		    os_memcmp(auth_addr, sm->mlo.ap_mld_addr, ETH_ALEN) == 0)
+			mlo_links_pmksa_cache_add(sm, pmk, pmk_len, pmkid, NULL,
+						  0, sm->network_ctx,
+						  sm->key_mgmt, NULL);
 	}
 }
 
@@ -6059,7 +6087,7 @@ fail:
 }
 
 
-int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *bssid,
+int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *auth_addr,
 			   const u8 *resp_ies, size_t resp_ies_len)
 {
 	struct ieee802_11_elems elems;
@@ -6210,9 +6238,15 @@ int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *bssid,
 	wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sm->pmk, sm->pmk_len);
 	wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, PMKID_LEN);
 	pmksa_cache_add(sm->pmksa, sm->pmk, sm->pmk_len, pmkid, NULL, 0,
-			bssid, sm->own_addr, sm->network_ctx, sm->key_mgmt,
+			auth_addr, sm->own_addr, sm->network_ctx, sm->key_mgmt,
 			NULL);
 
+	if (sm->mlo.valid_links &&
+	    os_memcmp(auth_addr, sm->mlo.ap_mld_addr, ETH_ALEN) == 0)
+		mlo_links_pmksa_cache_add(sm, sm->pmk, sm->pmk_len, pmkid, NULL,
+					  0, sm->network_ctx, sm->key_mgmt,
+					  NULL);
+
 	return 0;
 }
 
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index b97edd551..287864e5a 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -153,7 +153,7 @@ void wpa_sm_deinit(struct wpa_sm *sm);
 void wpa_sm_notify_assoc(struct wpa_sm *sm, const u8 *bssid);
 void wpa_sm_notify_disassoc(struct wpa_sm *sm);
 void wpa_sm_set_pmk(struct wpa_sm *sm, const u8 *pmk, size_t pmk_len,
-		    const u8 *pmkid, const u8 *bssid);
+		    const u8 *pmkid, const u8 *auth_addr);
 void wpa_sm_set_pmk_from_pmksa(struct wpa_sm *sm);
 void wpa_sm_set_fast_reauth(struct wpa_sm *sm, int fast_reauth);
 void wpa_sm_set_scard_ctx(struct wpa_sm *sm, void *scard_ctx);
@@ -568,7 +568,7 @@ struct wpabuf * fils_build_assoc_req(struct wpa_sm *sm, const u8 **kek,
 int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len);
 
 struct wpabuf * owe_build_assoc_req(struct wpa_sm *sm, u16 group);
-int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *bssid,
+int owe_process_assoc_resp(struct wpa_sm *sm, const u8 *auth_addr,
 			   const u8 *resp_ies, size_t resp_ies_len);
 
 void wpa_sm_set_reset_fils_completed(struct wpa_sm *sm, int set);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 046d8c489..5a1a3d881 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -3113,7 +3113,8 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
 #ifdef CONFIG_OWE
 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_OWE &&
 	    (!bssid_known ||
-	     owe_process_assoc_resp(wpa_s->wpa, bssid,
+	     owe_process_assoc_resp(wpa_s->wpa,
+				    wpa_s->valid_links ? wpa_s->ap_mld_addr : bssid,
 				    data->assoc_info.resp_ies,
 				    data->assoc_info.resp_ies_len) < 0)) {
 		wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_UNSPECIFIED);
@@ -4898,7 +4899,9 @@ static void wpa_supplicant_event_assoc_auth(struct wpa_supplicant *wpa_s,
 					       data->assoc_info.fils_pmk,
 					       data->assoc_info.fils_pmk_len,
 					       data->assoc_info.fils_pmkid,
-					       wpa_s->bssid, fils_cache_id);
+					       wpa_s->valid_links ?
+					       wpa_s->ap_mld_addr : wpa_s->bssid,
+					       fils_cache_id);
 		} else if (data->assoc_info.fils_pmkid) {
 			/* Update the current PMKSA used for this connection */
 			pmksa_cache_set_current(wpa_s->wpa,
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index e6e39c4c3..83269968b 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -1548,12 +1548,12 @@ static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
 }
 
 
-static int sme_sae_set_pmk(struct wpa_supplicant *wpa_s, const u8 *bssid)
+static int sme_sae_set_pmk(struct wpa_supplicant *wpa_s, const u8 *auth_addr)
 {
 	wpa_printf(MSG_DEBUG,
 		   "SME: SAE completed - setting PMK for 4-way handshake");
 	wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, wpa_s->sme.sae.pmk_len,
-		       wpa_s->sme.sae.pmkid, bssid);
+		       wpa_s->sme.sae.pmkid, auth_addr);
 	if (wpa_s->conf->sae_pmkid_in_assoc) {
 		/* Update the own RSNE contents now that we have set the PMK
 		 * and added a PMKSA cache entry based on the successfully
@@ -1597,6 +1597,8 @@ void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s,
 
 	if (le_to_host16(header->u.auth.auth_alg) == WLAN_AUTH_SAE) {
 		int res;
+		struct wpa_bss *bss;
+		const u8 *auth_addr;
 
 		res = sme_sae_auth(
 			wpa_s, le_to_host16(header->u.auth.auth_transaction),
@@ -1615,7 +1617,25 @@ void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s,
 		if (res != 1)
 			return;
 
-		if (sme_sae_set_pmk(wpa_s, wpa_s->sme.ext_auth_bssid) < 0)
+		auth_addr = wpa_s->sme.ext_auth_bssid;
+		if (wpa_s->sme.ext_ml_auth) {
+			bss = wpa_bss_get_bssid_latest(
+				wpa_s, wpa_s->sme.ext_auth_bssid);
+			if (!bss) {
+				wpa_printf(MSG_INFO,
+					   "MLO SAE: BSS not available, update scan result to get BSS");
+				wpa_supplicant_update_scan_results(wpa_s);
+				bss = wpa_bss_get_bssid_latest(
+					wpa_s, wpa_s->sme.ext_auth_bssid);
+			}
+			if (bss && !is_zero_ether_addr(bss->mld_addr))
+				auth_addr = bss->mld_addr;
+			else
+				wpa_printf(MSG_INFO,
+					   "MLO SAE: AP MLD address fetch failed");
+		}
+
+		if (sme_sae_set_pmk(wpa_s, auth_addr) < 0)
 			return;
 	}
 }
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index c7e9fd37c..d1e5bcc3a 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3101,6 +3101,10 @@ static u8 * wpas_populate_assoc_ies(
 	    wpa_key_mgmt_wpa(ssid->key_mgmt)) {
 		int try_opportunistic;
 		const u8 *cache_id = NULL;
+		const u8 *auth_addr = bss->bssid;
+
+		if (!is_zero_ether_addr(bss->mld_addr))
+			auth_addr = bss->mld_addr;
 
 		try_opportunistic = (ssid->proactive_key_caching < 0 ?
 				     wpa_s->conf->okc :
@@ -3110,7 +3114,7 @@ static u8 * wpas_populate_assoc_ies(
 		if (wpa_key_mgmt_fils(ssid->key_mgmt))
 			cache_id = wpa_bss_get_fils_cache_id(bss);
 #endif /* CONFIG_FILS */
-		if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
+		if (pmksa_cache_set_current(wpa_s->wpa, NULL, auth_addr,
 					    ssid, try_opportunistic,
 					    cache_id, 0) == 0) {
 			eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
-- 
2.25.1




More information about the Hostap mailing list