[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/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 28aca46..5cd2562 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -701,6 +701,21 @@
 }
 
 
+static void sae_sme_send_external_auth_status(struct hostapd_data *hapd,
+					      struct sta_info *sta, u16 status)
+{
+	struct external_auth params;
+
+	os_memset(&params, 0, sizeof(params));
+	params.status = status;
+	params.bssid = sta->addr;
+	if (status == WLAN_STATUS_SUCCESS && sta->sae)
+		params.pmkid = sta->sae->pmkid;
+
+	hostapd_drv_send_external_auth_status(hapd, &params);
+}
+
+
 void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
 {
 #ifndef CONFIG_NO_VLAN
@@ -739,14 +754,18 @@
 	sae_set_state(sta, SAE_ACCEPTED, "Accept Confirm");
 	wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
 			       sta->sae->pmk, sta->sae->pmkid);
+	sae_sme_send_external_auth_status(hapd, sta, WLAN_STATUS_SUCCESS);
 }
 
 
 static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
-		       const u8 *bssid, u8 auth_transaction, int allow_reuse)
+		       const u8 *bssid, u8 auth_transaction, int allow_reuse,
+		       int *sta_removed)
 {
 	int ret;
 
+	*sta_removed = 0;
+
 	if (auth_transaction != 1 && auth_transaction != 2)
 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
 
@@ -847,7 +866,7 @@
 			 * additional events.
 			 */
 			return sae_sm_step(hapd, sta, bssid, auth_transaction,
-					   0);
+					   0, sta_removed);
 		}
 		break;
 	case SAE_CONFIRMED:
@@ -880,8 +899,9 @@
 			wpa_printf(MSG_DEBUG, "SAE: remove the STA (" MACSTR
 				   ") doing reauthentication",
 				   MAC2STR(sta->addr));
-			ap_free_sta(hapd, sta);
 			wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
+			ap_free_sta(hapd, sta);
+			*sta_removed = 1;
 		} else if (auth_transaction == 1) {
 			wpa_printf(MSG_DEBUG, "SAE: Start reauthentication");
 			ret = auth_sae_send_commit(hapd, sta, bssid, 1);
@@ -963,6 +983,7 @@
 	int *groups = hapd->conf->sae_groups;
 	int default_groups[] = { 19, 0 };
 	const u8 *pos, *end;
+	int sta_removed = 0;
 
 	if (!groups)
 		groups = default_groups;
@@ -1157,7 +1178,7 @@
 		}
 
 		resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction,
-				   allow_reuse);
+				   allow_reuse, &sta_removed);
 	} else if (auth_transaction == 2) {
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_DEBUG,
@@ -1198,7 +1219,8 @@
 			}
 			sta->sae->rc = peer_send_confirm;
 		}
-		resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction, 0);
+		resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction, 0,
+			&sta_removed);
 	} else {
 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
 			       HOSTAPD_LEVEL_DEBUG,
@@ -1210,7 +1232,7 @@
 	}
 
 reply:
-	if (resp != WLAN_STATUS_SUCCESS) {
+	if (!sta_removed && resp != WLAN_STATUS_SUCCESS) {
 		pos = mgmt->u.auth.variable;
 		end = ((const u8 *) mgmt) + len;
 
@@ -1220,6 +1242,7 @@
 		    !data && end - pos >= 2)
 			data = wpabuf_alloc_copy(pos, 2);
 
+		sae_sme_send_external_auth_status(hapd, sta, resp);
 		send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
 				auth_transaction, resp,
 				data ? wpabuf_head(data) : (u8 *) "",
@@ -1227,8 +1250,9 @@
 	}
 
 remove_sta:
-	if (sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
-				   status_code != WLAN_STATUS_SUCCESS)) {
+	if (!sta_removed && sta->added_unassoc &&
+	    (resp != WLAN_STATUS_SUCCESS ||
+	     status_code != WLAN_STATUS_SUCCESS)) {
 		hostapd_drv_sta_remove(hapd, sta->addr);
 		sta->added_unassoc = 0;
 	}