[wpa_supplicant] Cumulative patch from fe468b071

Bug: 124017368
Test: Device boots up and connects to WPA3/OWE wifi networks, run traffic.
Test: Able to turn on/off softap, associate wifi STA, run traffic.
Test: DPP functional test.
Test: Regression test passed (Bug: 124301325)

fe468b071 HE: Fix set_he_cap() parsing of config options for MU EDCA Params
f3a841bbf Do not disassociate not-associated STA on timeout
91205c8eb OpenSSL: Fix uninitialized variable in CRL reloading corner case
092a19222 Use for_each_element() in ieee802_11_parse_elems()
b50a63896 common: Use for_each_element_id/_extid for get_ie/get_ie_ext/get_vendor_ie
b64479742 common: Use for_each_element_id() in mb_ies_info_by_ies()
9008048f0 common: Use for_each_element_id() in ieee802_11_vendor_ie_concat()
eb84238df common: Use for_each_element() in ieee802_11_ie_count()
0e0c31bdc common: Add strongly typed element iteration macros
525923b1d tests: EAPOL-Key fuzzing tool
02a0a2393 RSN: Do not start preauthentication timer without candidates
1e5506588 JSON: Fix string parsing when \\ escape is at the end of buffer
0dedcb315 JSON: Fix parsing of a number from the end of the buffer
79fa1b453 tests: JSON parser fuzzer
62269c8d8 TLS: Fix X.509 certificate name conversion into empty string
3eae9766b TLS: Fix ASN.1 parsing with no room for the header
fbc2123a1 TLS: Fix AlertDescription for missing partial processing case
1ac9c020b tests: TLS fuzzing tool
f3cca8b1e TLS server: Check credentials have been configured before using them
19dd7a736 TLS server: Local failure information on verify_data mismatch
f08ab18bf TLS server: Add internal callbacks get_failed, get_*_alerts
b642ab406 TLS server: More complete logging of ClientHello decode errors
fdd8a2f0b TLS client: Fix peer certificate event checking for probing
e5bffe1aa OpenSSL: Add more handshake message names to debug
21cd8f831 nl80211: Use wpa_ssid_txt() for debug messages more consistently
bbdb50146 Note HT overrides in debug log only if set
f2a6ac63e P2P: Update find_start timer only when p2p_scan is started.
c4e90da6d MBO: Move the WNM-Notification subtype definitions to common location
105b14f54 HS 2.0: Update the T&C Acceptance subtype value
65b487ae5 HS 2.0: Add QUIET=1 support for building hs20-osu-client
73f285dad Add FT-PSK to GET_CAPABILITY key_mgmt
6110753b1 nl80211: Clear PMKID add command message buffer
0fa33e05b nl80211: Clear connect command message buffer
b14e8ea1d nl80211: Request kernel to trim off payload of netlink requests from acks
789b48bb4 EAP peer: Clear temporary message buffers before freeing
8f99a3c26 Clear config item writing buffer before freeing it
a68e9b698 D-Bus: Fix P2P DeleteService dict iteration
0607346f1 D-Bus: Fix a memory leak in DeleteService handler
d05dda61d PEAP: Explicitly clear temporary keys from memory when using CMK
4e1cd3468 EAP-PEAP: Derive EMSK and use 128-octet derivation for MSK
d8c20ec59 DPP: Clear dpp_listen_freq on remain-on-channel failure
59fa20538 P2P: Allow the avoid channels for P2P discovery/negotiation
e34cd9f06 WNM: Fix WNM-Sleep Mode Request bounds checking
159a7fbde crl_reload_interval: Add CRL reloading support
83c860813 AP: Add wpa_psk_file reloading in runtime
ec5c39a55 AP: Allow identifying which passphrase station used with wpa_psk_file
b08c9ad0c AP: Expose PMK outside of wpa_auth module
89896c000 tests: Use python3 compatible print statement
bab493b90 tests: Use python3 compatible "except" statement
0dab47733 Write multi_ap_backhaul_sta to wpa_supplicant config
98251c6f2 dbus: Document more possible BSS/RSA/KeyMgmt values
1e591df06 Check supported types in wpas_mac_addr_rand_scan_set()
c85249aa1 Fix test compilation error related to sme_event_unprot_disconnect()
42d308635 SAE: Advertise Password Identifier use
59c693064 HS 2.0 server: Command line option to fetch the version information
2d1762fa4 HS 2.0 server: Alternative subrem updateNode for certificate credentials
d97cf2a11 HS 2.0 server: Use noMOUpdate in client certificate subrem
13a200a92 FILS: Remove notes about experimental implementation
86d4e0537 dbus: Expose support of SAE key management in BSS properties

Change-Id: Id507b73f1f4a2e356cbcd3bfcfb9dcd23c8fd9e0
diff --git a/wpa_supplicant/mesh.c b/wpa_supplicant/mesh.c
index 38b9fb3..e9457f0 100644
--- a/wpa_supplicant/mesh.c
+++ b/wpa_supplicant/mesh.c
@@ -34,6 +34,8 @@
 	wpa_s->current_ssid = NULL;
 	os_free(wpa_s->mesh_rsn);
 	wpa_s->mesh_rsn = NULL;
+	os_free(wpa_s->mesh_params);
+	wpa_s->mesh_params = NULL;
 	/* TODO: leave mesh (stop beacon). This will happen on link down
 	 * anyway, so it's not urgent */
 }
@@ -93,6 +95,9 @@
 			conf->ieee80211w = NO_MGMT_FRAME_PROTECTION;
 	}
 #endif /* CONFIG_IEEE80211W */
+#ifdef CONFIG_OCV
+	conf->ocv = ssid->ocv;
+#endif /* CONFIG_OCV */
 
 	cipher = wpa_pick_pairwise_cipher(ssid->pairwise_cipher, 0);
 	if (cipher < 0 || cipher == WPA_CIPHER_TKIP) {
@@ -147,6 +152,95 @@
 }
 
 
+static int wpas_mesh_init_rsn(struct wpa_supplicant *wpa_s)
+{
+	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
+	struct wpa_ssid *ssid = wpa_s->current_ssid;
+	struct hostapd_data *bss = ifmsh->bss[0];
+	static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
+	const char *password;
+	size_t len;
+
+	password = ssid->sae_password;
+	if (!password)
+		password = ssid->passphrase;
+	if (!password) {
+		wpa_printf(MSG_ERROR,
+			   "mesh: Passphrase for SAE not configured");
+		return -1;
+	}
+
+	bss->conf->wpa = ssid->proto;
+	bss->conf->wpa_key_mgmt = ssid->key_mgmt;
+
+	if (wpa_s->conf->sae_groups && wpa_s->conf->sae_groups[0] > 0) {
+		wpas_mesh_copy_groups(bss, wpa_s);
+	} else {
+		bss->conf->sae_groups = os_memdup(default_groups,
+						  sizeof(default_groups));
+		if (!bss->conf->sae_groups)
+			return -1;
+	}
+
+	len = os_strlen(password);
+	bss->conf->ssid.wpa_passphrase = dup_binstr(password, len);
+
+	wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, ifmsh->mconf);
+	return !wpa_s->mesh_rsn ? -1 : 0;
+}
+
+
+static int wpas_mesh_complete(struct wpa_supplicant *wpa_s)
+{
+	struct hostapd_iface *ifmsh = wpa_s->ifmsh;
+	struct wpa_driver_mesh_join_params *params = wpa_s->mesh_params;
+	struct wpa_ssid *ssid = wpa_s->current_ssid;
+	int ret;
+
+	if (!params || !ssid) {
+		wpa_printf(MSG_ERROR, "mesh: %s called without active mesh",
+			   __func__);
+		return -1;
+	}
+
+	if (ifmsh->mconf->security != MESH_CONF_SEC_NONE &&
+	    wpas_mesh_init_rsn(wpa_s)) {
+		wpa_printf(MSG_ERROR,
+			   "mesh: RSN initialization failed - deinit mesh");
+		wpa_supplicant_mesh_deinit(wpa_s);
+		return -1;
+	}
+
+	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
+		wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
+		wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
+		wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
+	}
+
+	if (ifmsh) {
+		params->ies = ifmsh->mconf->rsn_ie;
+		params->ie_len = ifmsh->mconf->rsn_ie_len;
+		params->basic_rates = ifmsh->basic_rates;
+		params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
+		params->conf.ht_opmode = ifmsh->bss[0]->iface->ht_op_mode;
+	}
+
+	wpa_msg(wpa_s, MSG_INFO, "joining mesh %s",
+		wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
+	ret = wpa_drv_join_mesh(wpa_s, params);
+	if (ret)
+		wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret);
+
+	/* hostapd sets the interface down until we associate */
+	wpa_drv_set_operstate(wpa_s, 1);
+
+	if (!ret)
+		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+
+	return ret;
+}
+
+
 static int wpa_supplicant_mesh_init(struct wpa_supplicant *wpa_s,
 				    struct wpa_ssid *ssid,
 				    struct hostapd_freq_params *freq)
@@ -156,9 +250,6 @@
 	struct hostapd_config *conf;
 	struct mesh_conf *mconf;
 	int basic_rates_erp[] = { 10, 20, 55, 60, 110, 120, 240, -1 };
-	static int default_groups[] = { 19, 20, 21, 25, 26, -1 };
-	const char *password;
-	size_t len;
 	int rate_len;
 	int frequency;
 
@@ -208,6 +299,16 @@
 	bss->conf->start_disabled = 1;
 	bss->conf->mesh = MESH_ENABLED;
 	bss->conf->ap_max_inactivity = wpa_s->conf->mesh_max_inactivity;
+
+	if (ieee80211_is_dfs(ssid->frequency, wpa_s->hw.modes,
+			     wpa_s->hw.num_modes) && wpa_s->conf->country[0]) {
+		conf->ieee80211h = 1;
+		conf->ieee80211d = 1;
+		conf->country[0] = wpa_s->conf->country[0];
+		conf->country[1] = wpa_s->conf->country[1];
+		conf->country[2] = ' ';
+	}
+
 	bss->iconf = conf;
 	ifmsh->conf = conf;
 
@@ -231,7 +332,8 @@
 	if (ssid->ht40)
 		conf->secondary_channel = ssid->ht40;
 	if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A && ssid->vht) {
-		conf->vht_oper_chwidth = ssid->max_oper_chwidth;
+		if (ssid->max_oper_chwidth != DEFAULT_MAX_OPER_CHWIDTH)
+			conf->vht_oper_chwidth = ssid->max_oper_chwidth;
 		switch (conf->vht_oper_chwidth) {
 		case VHT_CHANWIDTH_80MHZ:
 		case VHT_CHANWIDTH_80P80MHZ:
@@ -281,48 +383,15 @@
 		conf->basic_rates[rate_len] = -1;
 	}
 
-	if (hostapd_setup_interface(ifmsh)) {
-		wpa_printf(MSG_ERROR,
-			   "Failed to initialize hostapd interface for mesh");
-		return -1;
-	}
-
 	if (wpa_drv_init_mesh(wpa_s)) {
 		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh in driver");
 		return -1;
 	}
 
-	if (mconf->security != MESH_CONF_SEC_NONE) {
-		password = ssid->sae_password;
-		if (!password)
-			password = ssid->passphrase;
-		if (!password) {
-			wpa_printf(MSG_ERROR,
-				   "mesh: Passphrase for SAE not configured");
-			goto out_free;
-		}
-
-		bss->conf->wpa = ssid->proto;
-		bss->conf->wpa_key_mgmt = ssid->key_mgmt;
-
-		if (wpa_s->conf->sae_groups &&
-		    wpa_s->conf->sae_groups[0] > 0) {
-			wpas_mesh_copy_groups(bss, wpa_s);
-		} else {
-			bss->conf->sae_groups =
-				os_memdup(default_groups,
-					  sizeof(default_groups));
-			if (!bss->conf->sae_groups)
-				goto out_free;
-		}
-
-		len = os_strlen(password);
-		bss->conf->ssid.wpa_passphrase =
-			dup_binstr(password, len);
-
-		wpa_s->mesh_rsn = mesh_rsn_auth_init(wpa_s, mconf);
-		if (!wpa_s->mesh_rsn)
-			goto out_free;
+	if (hostapd_setup_interface(ifmsh)) {
+		wpa_printf(MSG_ERROR,
+			   "Failed to initialize hostapd interface for mesh");
+		return -1;
 	}
 
 	wpa_supplicant_conf_ap_ht(wpa_s, ssid, conf);
@@ -367,11 +436,13 @@
 int wpa_supplicant_join_mesh(struct wpa_supplicant *wpa_s,
 			     struct wpa_ssid *ssid)
 {
-	struct wpa_driver_mesh_join_params params;
+	struct wpa_driver_mesh_join_params *params = os_zalloc(sizeof(*params));
 	int ret = 0;
 
-	if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency) {
+	if (!ssid || !ssid->ssid || !ssid->ssid_len || !ssid->frequency ||
+	    !params) {
 		ret = -ENOENT;
+		os_free(params);
 		goto out;
 	}
 
@@ -381,22 +452,23 @@
 	wpa_s->group_cipher = WPA_CIPHER_NONE;
 	wpa_s->mgmt_group_cipher = 0;
 
-	os_memset(&params, 0, sizeof(params));
-	params.meshid = ssid->ssid;
-	params.meshid_len = ssid->ssid_len;
-	ibss_mesh_setup_freq(wpa_s, ssid, &params.freq);
-	wpa_s->mesh_ht_enabled = !!params.freq.ht_enabled;
-	wpa_s->mesh_vht_enabled = !!params.freq.vht_enabled;
-	if (params.freq.ht_enabled && params.freq.sec_channel_offset)
-		ssid->ht40 = params.freq.sec_channel_offset;
+	params->meshid = ssid->ssid;
+	params->meshid_len = ssid->ssid_len;
+	ibss_mesh_setup_freq(wpa_s, ssid, &params->freq);
+	wpa_s->mesh_ht_enabled = !!params->freq.ht_enabled;
+	wpa_s->mesh_vht_enabled = !!params->freq.vht_enabled;
+	if (params->freq.ht_enabled && params->freq.sec_channel_offset)
+		ssid->ht40 = params->freq.sec_channel_offset;
+
 	if (wpa_s->mesh_vht_enabled) {
 		ssid->vht = 1;
-		switch (params.freq.bandwidth) {
+		ssid->vht_center_freq1 = params->freq.center_freq1;
+		switch (params->freq.bandwidth) {
 		case 80:
-			if (params.freq.center_freq2) {
+			if (params->freq.center_freq2) {
 				ssid->max_oper_chwidth = VHT_CHANWIDTH_80P80MHZ;
 				ssid->vht_center_freq2 =
-					params.freq.center_freq2;
+					params->freq.center_freq2;
 			} else {
 				ssid->max_oper_chwidth = VHT_CHANWIDTH_80MHZ;
 			}
@@ -410,67 +482,44 @@
 		}
 	}
 	if (ssid->beacon_int > 0)
-		params.beacon_int = ssid->beacon_int;
+		params->beacon_int = ssid->beacon_int;
 	else if (wpa_s->conf->beacon_int > 0)
-		params.beacon_int = wpa_s->conf->beacon_int;
+		params->beacon_int = wpa_s->conf->beacon_int;
 	if (ssid->dtim_period > 0)
-		params.dtim_period = ssid->dtim_period;
+		params->dtim_period = ssid->dtim_period;
 	else if (wpa_s->conf->dtim_period > 0)
-		params.dtim_period = wpa_s->conf->dtim_period;
-	params.conf.max_peer_links = wpa_s->conf->max_peer_links;
+		params->dtim_period = wpa_s->conf->dtim_period;
+	params->conf.max_peer_links = wpa_s->conf->max_peer_links;
 	if (ssid->mesh_rssi_threshold < DEFAULT_MESH_RSSI_THRESHOLD) {
-		params.conf.rssi_threshold = ssid->mesh_rssi_threshold;
-		params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD;
+		params->conf.rssi_threshold = ssid->mesh_rssi_threshold;
+		params->conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_RSSI_THRESHOLD;
 	}
 
 	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
-		params.flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH;
-		params.flags |= WPA_DRIVER_MESH_FLAG_AMPE;
+		params->flags |= WPA_DRIVER_MESH_FLAG_SAE_AUTH;
+		params->flags |= WPA_DRIVER_MESH_FLAG_AMPE;
 		wpa_s->conf->user_mpm = 1;
 	}
 
 	if (wpa_s->conf->user_mpm) {
-		params.flags |= WPA_DRIVER_MESH_FLAG_USER_MPM;
-		params.conf.auto_plinks = 0;
+		params->flags |= WPA_DRIVER_MESH_FLAG_USER_MPM;
+		params->conf.auto_plinks = 0;
 	} else {
-		params.flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM;
-		params.conf.auto_plinks = 1;
+		params->flags |= WPA_DRIVER_MESH_FLAG_DRIVER_MPM;
+		params->conf.auto_plinks = 1;
 	}
-	params.conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
+	params->conf.peer_link_timeout = wpa_s->conf->mesh_max_inactivity;
 
-	if (wpa_supplicant_mesh_init(wpa_s, ssid, &params.freq)) {
+	os_free(wpa_s->mesh_params);
+	wpa_s->mesh_params = params;
+	if (wpa_supplicant_mesh_init(wpa_s, ssid, &params->freq)) {
 		wpa_msg(wpa_s, MSG_ERROR, "Failed to init mesh");
 		wpa_drv_leave_mesh(wpa_s);
 		ret = -1;
 		goto out;
 	}
 
-	if (ssid->key_mgmt & WPA_KEY_MGMT_SAE) {
-		wpa_s->pairwise_cipher = wpa_s->mesh_rsn->pairwise_cipher;
-		wpa_s->group_cipher = wpa_s->mesh_rsn->group_cipher;
-		wpa_s->mgmt_group_cipher = wpa_s->mesh_rsn->mgmt_group_cipher;
-	}
-
-	if (wpa_s->ifmsh) {
-		params.ies = wpa_s->ifmsh->mconf->rsn_ie;
-		params.ie_len = wpa_s->ifmsh->mconf->rsn_ie_len;
-		params.basic_rates = wpa_s->ifmsh->basic_rates;
-		params.conf.flags |= WPA_DRIVER_MESH_CONF_FLAG_HT_OP_MODE;
-		params.conf.ht_opmode = wpa_s->ifmsh->bss[0]->iface->ht_op_mode;
-	}
-
-	wpa_msg(wpa_s, MSG_INFO, "joining mesh %s",
-		wpa_ssid_txt(ssid->ssid, ssid->ssid_len));
-	ret = wpa_drv_join_mesh(wpa_s, &params);
-	if (ret)
-		wpa_msg(wpa_s, MSG_ERROR, "mesh join error=%d", ret);
-
-	/* hostapd sets the interface down until we associate */
-	wpa_drv_set_operstate(wpa_s, 1);
-
-	if (!ret)
-		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
-
+	ret = wpas_mesh_complete(wpa_s);
 out:
 	return ret;
 }