[wpa_supplicant] cumilative patch from commit bb945b98f

Bug: 275651698
Test: Connect to open, WPA2, WPA3 and passpoint network
Test: Establish P2P connection
Test: Basic SoftAp tests
Test: Regression test (b/275948027)

BYPASS_INCLUSIVE_LANGUAGE_REASON=Merged from opne source
bb945b98f Add 40 and 80 MHz channels 165 and 173 for 5 GHz IBSS/mesh
0059fa5ba 6 GHz: Fix secondary channel setting
744295c8b Add 6 GHz channel validation during channel switching
5349a45d3 Set interface state as inactive if mesh bringup fails
a4af79624 Handle signal termination in hostapd_cli for all cases
cf8f13ac8 Add support to send 320 MHz bandwidth through vendor subcmd
a0403c023 EHT: Validate the puncturing bitmap for ACS
af0f60e7d EHT: Calculate puncturing bitmap for ACS
f3206fbe9 EHT: Configuration option for ACS puncturing threshold
e3621867c EHT: Process puncturing bitmap from channel switch event
e277e577c nl80211: Send EHT puncturing bitmap to the driver for switch command
29a882bed EHT: Configure puncturing bitmap during channel switch
4942b19ff EHT: Send puncturing bitmap to the driver for AP bring up
f9fc2eabb EHT: Add puncturing bitmap to EHT Operation element
46a5d989d EHT: Downgrade bandwidths for VHT and HE when using puncturing
7618269ec EHT: Validate puncturing bitmap
9102fda31 EHT: Add configuration option for puncturing in AP mode
9e79439fc nl80211: Retrieve driver support for EHT puncturing
507be376c Sync with wireless-next.git include/uapi/linux/nl80211.h
591256a8c FILS: 320 MHz support in FD frame
903e3a1e6 FILS: Fix maximum NSS calculation for FD frame
ecae45ff6 FILS: Make HE a requirement for FILS discovery
4e86692ff AP: Fix 6 GHz AP setup after disable-enable
a34b8477a ml80211: Put wiphy idx to obtain correct country code
1491fc64a Define QCA vendor per-enum 64-bit pad attributes
55e31699e qca-vendor: Add QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NF_CAL_VAL
b1f85957c Add QCA vendor commands to set and get MLO links state information
44b32a752 mesh: Add EHT support
c4cb62ca8 WPA_AUTH: MLO: Add functions to get the AA and SPA
cab963e9f AP: Split check_assoc_ies()
7a7a2256c common: Support parsing link specific association request
b39e35693 common: Add support for clearing elements
0b2fc4268 common: Split ieee8021_parse_elems()
df6561ec0 nl80211: AP MLD support for adding multi link stations
b8b4ceb8d nl80211: Properly stop and deinit MLO AP
2f8fc46ed nl80211: Provide link_id in EAPOL_RX and RX_MGMT events
821374d43 nl80211: Introduce and implement a callback to add an MLO link for AP MLD
47269be36 nl80211: Refactor i802_bss to support multiple links
eb146ee80 AP: Add some bridge port attribute settings
f628e6b30 nl80211: Make sure scan frequency debug buffer is NUL terminated
41d23254b nl80211: Fix frequencies array boundary check for scanned frequencies
a9012070a Android: Add wowlan_disconnect_on_deinit to template configuration
e2ea0fd70 EST: Write the RSA private key using the standard PRIVATE KEY format
bfd236df2 webkit2: Avoid deprecated function call
2c3202682 P2P: Filter out 6 GHz frequencies if not allowed for P2P connection
b2bf7e39e Update PMK in wpa_sm when roam+auth event indicated with authorized flag
6b9c86466 nl80211: Replace the channel flags for VHT support
6f63aca7b DPP: Allow both STA and AP configObject to be set
7292e30b7 DPP: Fix @CONF-OBJ-SEP@ parsing for multiple configs
c31600ce1 P2P: Allow GO BSSID to be specified for P2P_GROUP_ADD commands
0430756e6 P2P: Optimize join scan frequency
b3921db42 nl80211: Add frequency info in start AP command
40c139664 macsec_linux: Add support for MACsec hardware offload
6d24673ab mka: Allow configuration of MACsec hardware offload
3081a9cb6 hostapd: Output country_code and country3 when using STATUS
91ad7a309 FT: Store PTKSA entry for the correct BSSID in the FT protocol case
3f3e356fa Mark addr argument to storing PTKSA const
242c3ad99 FT: Store PTKSA from FT protocol
ba6954874 Mark wpa_auth_remove_ptksa() static
3b1ad1334 FT: Include KDK in FT specific PTK derivation on the AP
870a5bdc0 nl80211: Report guard interval and dual carrier modulation
edcad193a dbus: Add inactive time to D-Bus signal info
a678a510f dbus: Add D-Bus signal for PSK mismatch heuristics
691f729d5 P2P: Make invitation flow less aggressive
f4a7e2a07 Rework IBSS/mesh 80 MHz channel selection
f91f971bd Fix creating 6 GHz IBSS/mesh on 5/6 GHz-capable PHYs
c623cee42 Make arrays static const in ibss_mesh_select_*()
64043e615 Split ibss_mesh_setup_freq() into multiple functions
8085a7e65 wpa_supplicant: Add option to explicitly set 4addr mode
1ffc7d1c6 Apply bias towards 6 GHz in roaming
faa410292 WNM: Event report handling for BSS color collision and in-use
97405be96 Small textual improvements to wpa_supplicant man page
ec02a0e93 hostapd: Output hw_mode when using STATUS
390e24c6c EAP-TTLS server: Add Ident field to MS-CHAP-Error
4ae798a22 P2P: Pick the best driver pref freq for invitation process
6c75f1dfa Send broadcast Probe Response frames on the 6 GHz band
edfcb2f1a MLD STA: Indicate MLO support in NL80211_CMD_CONNECT
c91852044 MLD STA: Add support for SAE external authentication offload to userspace
575712450 qca-vendor: Add QCA_WLAN_VENDOR_MCC_QUOTA_TYPE_LOW_LATENCY
ba150059d FT: Store PMK-R0/PMK-R1 after EAPOL-Key msg 2/4 MIC validation
56662f36d Refine vendor subcmd QCA_NL80211_VENDOR_SUBCMD_ROAM_STATS
72b8193f4 MACsec: Remove EAP Session-Id length constraint
3915e8834 hostapd: Report error on unknown ACCEPT_ACL/DENY_ACL commands
2cff340d1 utils: Move log2pcap to python3
12de8112b Fix BSS age underflow
d31c2b43a Fix segfault in case of an invalid configuration
a32b424a3 MLD STA: Use AP MLD address in PMKSA cache attempts for driver-SME case
8c4790cef MLD STA: Store PMKSA with AP MLD address for MLO connection event
bf124a03d SAE: Update PT value at later point for SME cases, if needed
1aadcca0a P2P: Enable SAE-H2E for client when joining a 6 GHz group
37f8257c4 SAE: Extend automatic enabling of H2E on 6 GHz to additional cases
89377c6b9 OCV: Fix build without CONFIG_OCV=y
2e47ea22c P2P: Fix handling Service Discovery Response received by GO device
dc7e330e0 Set OCV capability based on Association Request frame RSNE
831be6514 WPS: Do not indicate incorrect PBC overlap based on partner link
c9fc12425 P2P: Make wpas_p2p_notif_pbc_overlap() static

Change-Id: I1eb61fc82b98b937a2ff37a30e60e28129fe143d
Merged-In: I1eb61fc82b98b937a2ff37a30e60e28129fe143d
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 406e357..ea4023c 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -198,6 +198,9 @@
 	if (wpa_key_mgmt_sae_ext_key(key_mgmt) &&
 	    wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK)
 		use_pt = 1;
+	if (bss && is_6ghz_freq(bss->freq) &&
+	    wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK)
+		use_pt = 1;
 #ifdef CONFIG_SAE_PK
 	if ((rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) &&
 	    ssid->sae_pk != SAE_PK_MODE_DISABLED &&
@@ -231,6 +234,8 @@
 		}
 	}
 
+	if (use_pt && !ssid->pt)
+		wpa_s_setup_sae_pt(wpa_s->conf, ssid, true);
 	if (use_pt &&
 	    sae_prepare_commit_pt(&wpa_s->sme.sae, ssid->pt,
 				  wpa_s->own_addr, addr,
@@ -1301,11 +1306,30 @@
 
 #ifdef CONFIG_SAE
 
+#define WPA_AUTH_FRAME_ML_IE_LEN	(6 + ETH_ALEN)
+
+static void wpa_auth_ml_ie(struct wpabuf *buf, const u8 *mld_addr)
+{
+
+	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
+	wpabuf_put_u8(buf, 4 + ETH_ALEN);
+	wpabuf_put_u8(buf, WLAN_EID_EXT_MULTI_LINK);
+
+	/* Basic Multi-Link element Control field */
+	wpabuf_put_u8(buf, 0x0);
+	wpabuf_put_u8(buf, 0x0);
+
+	/* Common Info */
+	wpabuf_put_u8(buf, 0x7); /* length = Length field + MLD MAC address */
+	wpabuf_put_data(buf, mld_addr, ETH_ALEN);
+}
+
+
 static int sme_external_auth_build_buf(struct wpabuf *buf,
 				       struct wpabuf *params,
 				       const u8 *sa, const u8 *da,
 				       u16 auth_transaction, u16 seq_num,
-				       u16 status_code)
+				       u16 status_code, const u8 *mld_addr)
 {
 	struct ieee80211_mgmt *resp;
 
@@ -1324,6 +1348,9 @@
 	if (params)
 		wpabuf_put_buf(buf, params);
 
+	if (mld_addr)
+		wpa_auth_ml_ie(buf, mld_addr);
+
 	return 0;
 }
 
@@ -1337,7 +1364,9 @@
 	bool use_pk;
 	u16 status;
 
-	resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, NULL,
+	resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid,
+					 wpa_s->sme.ext_ml_auth ?
+					 wpa_s->sme.ext_auth_ap_mld_addr : NULL,
 					 1, 0, &use_pt, &use_pk);
 	if (!resp) {
 		wpa_printf(MSG_DEBUG, "SAE: Failed to build SAE commit");
@@ -1345,7 +1374,9 @@
 	}
 
 	wpa_s->sme.sae.state = SAE_COMMITTED;
-	buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + wpabuf_len(resp));
+	buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + wpabuf_len(resp) +
+			   (wpa_s->sme.ext_ml_auth ? WPA_AUTH_FRAME_ML_IE_LEN :
+			    0));
 	if (!buf) {
 		wpabuf_free(resp);
 		return -1;
@@ -1359,7 +1390,11 @@
 	else
 		status = WLAN_STATUS_SUCCESS;
 	sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
-				    bssid, 1, wpa_s->sme.seq_num, status);
+				    wpa_s->sme.ext_ml_auth ?
+				    wpa_s->sme.ext_auth_ap_mld_addr : bssid, 1,
+				    wpa_s->sme.seq_num, status,
+				    wpa_s->sme.ext_ml_auth ?
+				    wpa_s->own_addr : NULL);
 	wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0, 0);
 	wpabuf_free(resp);
 	wpabuf_free(buf);
@@ -1400,7 +1435,7 @@
 		    os_memcmp(ssid_str, ssid->ssid, ssid_str_len) == 0 &&
 		    wpa_key_mgmt_sae(ssid->key_mgmt)) {
 			/* Make sure PT is derived */
-			wpa_s_setup_sae_pt(wpa_s->conf, ssid);
+			wpa_s_setup_sae_pt(wpa_s->conf, ssid, false);
 			wpa_s->sme.ext_auth_wpa_ssid = ssid;
 			break;
 		}
@@ -1426,7 +1461,9 @@
 	}
 
 	wpa_s->sme.sae.state = SAE_CONFIRMED;
-	buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN + wpabuf_len(resp));
+	buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN + wpabuf_len(resp) +
+			   (wpa_s->sme.ext_ml_auth ? WPA_AUTH_FRAME_ML_IE_LEN :
+			    0));
 	if (!buf) {
 		wpa_printf(MSG_DEBUG, "SAE: Auth Confirm buf alloc failure");
 		wpabuf_free(resp);
@@ -1435,7 +1472,10 @@
 	wpa_s->sme.seq_num++;
 	sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
 				    da, 2, wpa_s->sme.seq_num,
-				    WLAN_STATUS_SUCCESS);
+				    WLAN_STATUS_SUCCESS,
+				    wpa_s->sme.ext_ml_auth ?
+				    wpa_s->own_addr : NULL);
+
 	wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0, 0);
 	wpabuf_free(resp);
 	wpabuf_free(buf);
@@ -1487,6 +1527,13 @@
 		os_memcpy(wpa_s->sme.ext_auth_ssid, data->external_auth.ssid,
 			  data->external_auth.ssid_len);
 		wpa_s->sme.ext_auth_ssid_len = data->external_auth.ssid_len;
+		if (data->external_auth.mld_addr) {
+			wpa_s->sme.ext_ml_auth = true;
+			os_memcpy(wpa_s->sme.ext_auth_ap_mld_addr,
+				  data->external_auth.mld_addr, ETH_ALEN);
+		} else {
+			wpa_s->sme.ext_ml_auth = false;
+		}
 		wpa_s->sme.seq_num = 0;
 		wpa_s->sme.sae.state = SAE_NOTHING;
 		wpa_s->sme.sae.send_confirm = 0;
@@ -1548,6 +1595,42 @@
 }
 
 
+static int sme_external_ml_auth(struct wpa_supplicant *wpa_s,
+				const u8 *data, size_t len, int ie_offset)
+{
+	struct ieee802_11_elems elems;
+	const u8 *mld_addr;
+
+	if (ieee802_11_parse_elems(data + ie_offset, len - ie_offset,
+				   &elems, 0) != ParseOK) {
+		wpa_printf(MSG_DEBUG, "MLD: Failed parsing elements");
+		return -1;
+	}
+
+	if (!elems.basic_mle || !elems.basic_mle_len) {
+		wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication");
+		return -1;
+	}
+
+	mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
+	if (!mld_addr) {
+		wpa_printf(MSG_DEBUG, "MLD: No MLD address in ML element");
+		return -1;
+	}
+
+	wpa_printf(MSG_DEBUG, "MLD: mld_address=" MACSTR, MAC2STR(mld_addr));
+
+	if (os_memcmp(wpa_s->sme.ext_auth_ap_mld_addr, mld_addr, ETH_ALEN) !=
+	    0) {
+		wpa_printf(MSG_DEBUG, "MLD: Unexpected MLD address (expected "
+			   MACSTR ")", MAC2STR(wpa_s->ap_mld_addr));
+		return -1;
+	}
+
+	return 0;
+}
+
+
 static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
 			u16 status_code, const u8 *data, size_t len,
 			int external, const u8 *sa, int *ie_offset)
@@ -1615,8 +1698,7 @@
 			token_len = elen - 1;
 		}
 
-		if (ie_offset)
-			*ie_offset = token_pos + token_len - data;
+		*ie_offset = token_pos + token_len - data;
 
 		wpa_s->sme.sae_token = wpabuf_alloc_copy(token_pos, token_len);
 		if (!wpa_s->sme.sae_token) {
@@ -1627,13 +1709,18 @@
 
 		wpa_hexdump_buf(MSG_DEBUG, "SME: Requested anti-clogging token",
 				wpa_s->sme.sae_token);
-		if (!external)
+		if (!external) {
 			sme_send_authentication(wpa_s, wpa_s->current_bss,
 						wpa_s->current_ssid, 2);
-		else
+		} else {
+			if (wpa_s->sme.ext_ml_auth &&
+			    sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+				return -1;
+
 			sme_external_auth_send_sae_commit(
 				wpa_s, wpa_s->sme.ext_auth_bssid,
 				wpa_s->sme.ext_auth_wpa_ssid);
+		}
 		return 0;
 	}
 
@@ -1649,13 +1736,18 @@
 		if (sme_set_sae_group(wpa_s, external) < 0)
 			return -1; /* no other groups enabled */
 		wpa_dbg(wpa_s, MSG_DEBUG, "SME: Try next enabled SAE group");
-		if (!external)
+		if (!external) {
 			sme_send_authentication(wpa_s, wpa_s->current_bss,
 						wpa_s->current_ssid, 1);
-		else
+		} else {
+			if (wpa_s->sme.ext_ml_auth &&
+			    sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+				return -1;
+
 			sme_external_auth_send_sae_commit(
 				wpa_s, wpa_s->sme.ext_auth_bssid,
 				wpa_s->sme.ext_auth_wpa_ssid);
+		}
 		return 0;
 	}
 
@@ -1743,11 +1835,16 @@
 
 		wpabuf_free(wpa_s->sme.sae_token);
 		wpa_s->sme.sae_token = NULL;
-		if (!external)
+		if (!external) {
 			sme_send_authentication(wpa_s, wpa_s->current_bss,
 						wpa_s->current_ssid, 0);
-		else
+		} else {
+			if (wpa_s->sme.ext_ml_auth &&
+			    sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+				return -1;
+
 			sme_external_auth_send_sae_confirm(wpa_s, sa);
+		}
 		return 0;
 	} else if (auth_transaction == 2) {
 		if (status_code != WLAN_STATUS_SUCCESS)
@@ -1758,6 +1855,10 @@
 		if (sae_check_confirm(&wpa_s->sme.sae, data, len,
 				      ie_offset) < 0)
 			return -1;
+		if (external && wpa_s->sme.ext_ml_auth &&
+		    sme_external_ml_auth(wpa_s, data, len, *ie_offset))
+			return -1;
+
 		wpa_s->sme.sae.state = SAE_ACCEPTED;
 		sae_clear_temp_data(&wpa_s->sme.sae);
 
@@ -1823,12 +1924,13 @@
 
 	if (le_to_host16(header->u.auth.auth_alg) == WLAN_AUTH_SAE) {
 		int res;
+		int ie_offset = 0;
 
 		res = sme_sae_auth(
 			wpa_s, le_to_host16(header->u.auth.auth_transaction),
 			le_to_host16(header->u.auth.status_code),
 			header->u.auth.variable,
-			len - auth_length, 1, header->sa, NULL);
+			len - auth_length, 1, header->sa, &ie_offset);
 		if (res < 0) {
 			/* Notify failure to the driver */
 			sme_send_external_auth_status(
@@ -1841,7 +1943,10 @@
 		if (res != 1)
 			return;
 
-		if (sme_sae_set_pmk(wpa_s, wpa_s->sme.ext_auth_bssid) < 0)
+		if (sme_sae_set_pmk(wpa_s,
+				    wpa_s->sme.ext_ml_auth ?
+				    wpa_s->sme.ext_auth_ap_mld_addr :
+				    wpa_s->sme.ext_auth_bssid) < 0)
 			return;
 	}
 }