[wpa_supplicant] Cumulative patch from 6151c9b90

Bug: 130813391
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 test: act.py -c ../WifiDppConfig.json -tc WifiDppTest
Test: Regression test passed (Bug: 130831127)

6151c9b90 EAP-pwd server: Remove unused srandom() call
d2d1a324c EAP-pwd peer: Fix reassembly buffer handling
fe76f487e EAP-pwd server: Fix reassembly buffer handling
a9d224f56 EAP-pwd server: Fix a memory leak on error path
90ee1bf5f EAP-MSCHAPv2: Propagate GetAsymetricStartKey() failures up from getKey()
824cb5a53 RSN: Ignore IGTK configuration errors with swapped KeyID values
dfdabd917 RSN: Report completion only after IGTK configuration
bce3d4f70 autoscan: Disable when we move above WPA_SCANNING state
eb3234c07 SAE: Use open authentication to reassociate for PMKSA caching
fe01cd006 Fix FILS ERP association event with 4-way HS offload drivers
323a51cc0 nl80211: Handle NL80211_CMD_PROBE_CLIENT command response
28f19a3ae nl80211: More detailed PROBE_CLIENT debug print
31cf52bf2 Do not clear FT IEs twice in sme_deinit()
01ac337b3 Stop SA Query on disconnection
7a206c504 Add debug print on stopping SA Query procedure
710c69238 P2PS: Cleanup pending_p2ps_group flag
0be8b9238 mka: Avoid memory leak in unexpected case in RECEIVE
984d5b7e1 mesh: Fix random llid generation in an error case
10cf866ba mesh: Fix operations after SAE state machine removing the STA
153d4c501 mesh: Fix SAE reauthentication processing
2f6805139 Fix hostapd BSS_TM_REQ handling of bss_term parameter
e6ac47b47 Fix debug print in GET_PREF_FREQ_LIST handler
2e70e807c D-Bus: Fix P2P GroupStarted signal not to use uninitialized IP buffer
c5fff8bbd nl80211: Update assoc_freq and bss->freq based on real association info
091c22771 nl80211: Clear bss->freq on station mode disconnection
cb5db189e Remove the unused crypto_ec_cofactor() function
8b093db2c EAP-pwd: Remove unused checks for cofactor > 1 cases
92e1b96c2 EAP-pwd: Disallow ECC groups with a prime under 256 bits
6fe3ee722 tests: EAP-pwd local failure in crypto_bignum_rand()
6570949b2 OpenSSL: Fix server side openssl_ecdh_curves configuration with 1.0.2
52b1cb5d7 tests: crypto_hash_finish() failure in eap_pwd_kdf()
56ac1f9df RRM: Set last beacon report indication in the last element only
6f484978f Document BSS expiration configurables
8f36c84a2 bsd: Fix a typo in error message
dd1a8cef4 Remove unnecessary copying of SSID and BSSID for external_auth
4ffb0fefe hostapd: Support external authentication offload in AP mode
236e793e7 nl80211: External authentication in driver-based AP SME mode
2ab19f4be Reset beacon_set_done on disabling interface

Change-Id: I5642b46d79aee83dd4f4307bf781d57b318831bd
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 564f32b..198ac56 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -7715,7 +7715,7 @@
 
 	wpa_printf(MSG_DEBUG,
 		   "CTRL_IFACE: GET_PREF_FREQ_LIST iface_type=%d (%s)",
-		   iface_type, buf);
+		   iface_type, cmd);
 
 	ret = wpa_drv_get_pref_freq_list(wpa_s, iface_type, &num, freq_list);
 	if (ret)
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index 632252c..815b994 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2859,8 +2859,17 @@
 	}
 	wpa_supplicant_cancel_scan(wpa_s);
 
-	if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
-	    wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
+	if (ft_completed) {
+		/*
+		 * FT protocol completed - make sure EAPOL state machine ends
+		 * up in authenticated.
+		 */
+		wpa_supplicant_cancel_auth_timeout(wpa_s);
+		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
+		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
+		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
+	} else if ((wpa_s->drv_flags & WPA_DRIVER_FLAGS_4WAY_HANDSHAKE_PSK) &&
+		   wpa_key_mgmt_wpa_psk(wpa_s->key_mgmt)) {
 		/*
 		 * We are done; the driver will take care of RSN 4-way
 		 * handshake.
@@ -2877,15 +2886,6 @@
 		 * waiting for WPA supplicant.
 		 */
 		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
-	} else if (ft_completed) {
-		/*
-		 * FT protocol completed - make sure EAPOL state machine ends
-		 * up in authenticated.
-		 */
-		wpa_supplicant_cancel_auth_timeout(wpa_s);
-		wpa_supplicant_set_state(wpa_s, WPA_COMPLETED);
-		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
-		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
 	}
 
 	wpa_s->last_eapol_matches_bssid = 0;
diff --git a/wpa_supplicant/mesh_mpm.c b/wpa_supplicant/mesh_mpm.c
index 4485939..9d6ab8d 100644
--- a/wpa_supplicant/mesh_mpm.c
+++ b/wpa_supplicant/mesh_mpm.c
@@ -189,7 +189,7 @@
 
 	do {
 		if (os_get_random((u8 *) &llid, sizeof(llid)) < 0)
-			continue;
+			llid = 0; /* continue */
 	} while (!llid || llid_in_use(wpa_s, llid));
 
 	sta->my_lid = llid;
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 562caad..70b61d6 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -4198,6 +4198,9 @@
 		return;
 	}
 
+	wpa_s->global->pending_p2ps_group = 0;
+	wpa_s->global->pending_p2ps_group_freq = 0;
+
 	if (conncap == P2PS_SETUP_GROUP_OWNER) {
 		/*
 		 * We need to copy the interface name. Simply saving a
@@ -4208,8 +4211,10 @@
 
 		go_ifname[0] = '\0';
 		if (!go_wpa_s) {
-			wpa_s->global->pending_p2ps_group = 1;
-			wpa_s->global->pending_p2ps_group_freq = freq;
+			if (!response_done) {
+				wpa_s->global->pending_p2ps_group = 1;
+				wpa_s->global->pending_p2ps_group_freq = freq;
+			}
 
 			if (!wpas_p2p_create_iface(wpa_s))
 				os_memcpy(go_ifname, wpa_s->ifname,
@@ -7223,7 +7228,7 @@
 	u8 go_dev_addr[ETH_ALEN];
 	int persistent;
 	int freq;
-	u8 ip[3 * 4];
+	u8 ip[3 * 4], *ip_ptr = NULL;
 	char ip_addr[100];
 
 	if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GROUP_FORMATION) {
@@ -7270,6 +7275,7 @@
 				  ip[8], ip[9], ip[10], ip[11]);
 		if (os_snprintf_error(sizeof(ip_addr), res))
 			ip_addr[0] = '\0';
+		ip_ptr = ip;
 	}
 
 	wpas_p2p_group_started(wpa_s, 0, ssid, freq,
@@ -7282,7 +7288,7 @@
 		wpas_p2p_store_persistent_group(wpa_s->p2pdev,
 						ssid, go_dev_addr);
 
-	wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 1, ip);
+	wpas_notify_p2p_group_started(wpa_s, ssid, persistent, 1, ip_ptr);
 }
 
 
diff --git a/wpa_supplicant/rrm.c b/wpa_supplicant/rrm.c
index ab5e6db..cb3c6c9 100644
--- a/wpa_supplicant/rrm.c
+++ b/wpa_supplicant/rrm.c
@@ -397,7 +397,10 @@
 	struct rrm_measurement_report_element *msr_rep;
 	u8 *end = pos + len;
 	u8 *msr_rep_end;
+	struct rrm_measurement_beacon_report *rep = NULL;
+	u8 *subelem;
 
+	/* Find the last beacon report element */
 	while (end - pos >= (int) sizeof(*msr_rep)) {
 		msr_rep = (struct rrm_measurement_report_element *) pos;
 		msr_rep_end = pos + msr_rep->len + 2;
@@ -410,30 +413,27 @@
 			return -1;
 		}
 
-		if (msr_rep->type == MEASURE_TYPE_BEACON) {
-			struct rrm_measurement_beacon_report *rep;
-			u8 *subelem;
-
+		if (msr_rep->type == MEASURE_TYPE_BEACON)
 			rep = (struct rrm_measurement_beacon_report *)
 				msr_rep->variable;
-			subelem = rep->variable;
-			while (subelem + 2 < msr_rep_end &&
-			       subelem[0] !=
-			       WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION)
-				subelem += 2 + subelem[1];
-
-			if (subelem + 2 < msr_rep_end &&
-			    subelem[0] ==
-			    WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION &&
-			    subelem[1] == 1 &&
-			    subelem +
-			    BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN <= end)
-				subelem[2] = 1;
-		}
 
 		pos += pos[1] + 2;
 	}
 
+	if (!rep)
+		return 0;
+
+	subelem = rep->variable;
+	while (subelem + 2 < msr_rep_end &&
+	       subelem[0] != WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION)
+		subelem += 2 + subelem[1];
+
+	if (subelem + 2 < msr_rep_end &&
+	    subelem[0] == WLAN_BEACON_REPORT_SUBELEM_LAST_INDICATION &&
+	    subelem[1] == 1 &&
+	    subelem + BEACON_REPORT_LAST_INDICATION_SUBELEM_LEN <= end)
+		subelem[2] = 1;
+
 	return 0;
 }
 
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 4bb5f3a..17a984d 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -965,10 +965,9 @@
 
 	os_memset(&params, 0, sizeof(params));
 	params.status = status;
-	os_memcpy(params.ssid, wpa_s->sme.ext_auth.ssid,
-		  wpa_s->sme.ext_auth.ssid_len);
+	params.ssid = wpa_s->sme.ext_auth.ssid;
 	params.ssid_len = wpa_s->sme.ext_auth.ssid_len;
-	os_memcpy(params.bssid, wpa_s->sme.ext_auth.bssid, ETH_ALEN);
+	params.bssid = wpa_s->sme.ext_auth.bssid;
 	wpa_drv_send_external_auth_status(wpa_s, &params);
 }
 
@@ -978,7 +977,7 @@
 {
 	struct wpa_ssid *ssid;
 	size_t ssid_str_len = data->external_auth.ssid_len;
-	u8 *ssid_str = data->external_auth.ssid;
+	const u8 *ssid_str = data->external_auth.ssid;
 
 	/* Get the SSID conf from the ssid string obtained */
 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
@@ -1986,17 +1985,14 @@
 	if (wpa_s->sme.ft_ies || wpa_s->sme.ft_used)
 		sme_update_ft_ies(wpa_s, NULL, NULL, 0);
 #endif /* CONFIG_IEEE80211R */
+#ifdef CONFIG_IEEE80211W
+	sme_stop_sa_query(wpa_s);
+#endif /* CONFIG_IEEE80211W */
 }
 
 
 void sme_deinit(struct wpa_supplicant *wpa_s)
 {
-	os_free(wpa_s->sme.ft_ies);
-	wpa_s->sme.ft_ies = NULL;
-	wpa_s->sme.ft_ies_len = 0;
-#ifdef CONFIG_IEEE80211W
-	sme_stop_sa_query(wpa_s);
-#endif /* CONFIG_IEEE80211W */
 	sme_clear_on_disassoc(wpa_s);
 
 	eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
@@ -2401,6 +2397,8 @@
 
 static void sme_stop_sa_query(struct wpa_supplicant *wpa_s)
 {
+	if (wpa_s->sme.sa_query_trans_id)
+		wpa_dbg(wpa_s, MSG_DEBUG, "SME: Stop SA Query");
 	eloop_cancel_timeout(sme_sa_query_timer, wpa_s, NULL);
 	os_free(wpa_s->sme.sa_query_trans_id);
 	wpa_s->sme.sa_query_trans_id = NULL;
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 0f7b85d..be8efb4 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -962,7 +962,7 @@
 		wpa_supplicant_stop_bgscan(wpa_s);
 #endif /* CONFIG_BGSCAN */
 
-	if (state == WPA_AUTHENTICATING)
+	if (state > WPA_SCANNING)
 		wpa_supplicant_stop_autoscan(wpa_s);
 
 	if (state == WPA_DISCONNECTED || state == WPA_INACTIVE)
@@ -2522,6 +2522,9 @@
 #ifdef CONFIG_MBO
 	const u8 *mbo_ie;
 #endif
+#ifdef CONFIG_SAE
+	int sae_pmksa_cached = 0;
+#endif /* CONFIG_SAE */
 #ifdef CONFIG_FILS
 	const u8 *realm, *username, *rrk;
 	size_t realm_len, username_len, rrk_len;
@@ -2559,8 +2562,12 @@
 #endif /* CONFIG_FILS */
 		if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
 					    ssid, try_opportunistic,
-					    cache_id, 0) == 0)
+					    cache_id, 0) == 0) {
 			eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
+#ifdef CONFIG_SAE
+			sae_pmksa_cached = 1;
+#endif /* CONFIG_SAE */
+		}
 		wpa_ie_len = max_wpa_ie_len;
 		if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
 					      wpa_ie, &wpa_ie_len)) {
@@ -2673,6 +2680,14 @@
 			"Overriding auth_alg selection: 0x%x", algs);
 	}
 
+#ifdef CONFIG_SAE
+	if (sae_pmksa_cached && algs == WPA_AUTH_ALG_SAE) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"SAE: Use WPA_AUTH_ALG_OPEN for PMKSA caching attempt");
+		algs = WPA_AUTH_ALG_OPEN;
+	}
+#endif /* CONFIG_SAE */
+
 #ifdef CONFIG_P2P
 	if (wpa_s->global->p2p) {
 		u8 *pos;
diff --git a/wpa_supplicant/wpa_supplicant.conf b/wpa_supplicant/wpa_supplicant.conf
index a66253f..a9205f0 100644
--- a/wpa_supplicant/wpa_supplicant.conf
+++ b/wpa_supplicant/wpa_supplicant.conf
@@ -318,6 +318,15 @@
 # of APs when using ap_scan=1 mode.
 #bss_max_count=200
 
+# BSS expiration age in seconds. A BSS will be removed from the local cache
+# if it is not in use and has not been seen for this time. Default is 180.
+#bss_expiration_age=180
+
+# BSS expiration after number of scans. A BSS will be removed from the local
+# cache if it is not seen in this number of scans.
+# Default is 2.
+#bss_expiration_scan_count=2
+
 # Automatic scan
 # This is an optional set of parameters for automatic scanning
 # within an interface in following format: