Cumulative patch from commit a9491695b30a7f750dc45cb563d813b03f1d4b8d

a9491695b QCA vendor command to set/get NUD statistics
f593b6c11 nl80211: Do not reset vendor_scan_cookie after scan timeout
f2bc34480 wpa_supplicant: Fix global control interface for STA/STA-FIRST/STA-NEXT
cc3dae85b hostapd: Add possibility to send debug messages to syslog
0da355235 FST: Remove WPA_ASSERT from wpas_fst_send_action_cb()
968dce9b1 FST: Silence compiler warning on WPA_ASSERT
17e20b1e2 FST: Remove a bogus WPA_ASSERT()
6a5425fd6 Increase delayed EAPOL RX frame timeout
cef8fac04 wpa_auth: Make struct wpa_auth_callbacks const
30eddf352 Fix or supress various sparse warnings
b301f54e5 IBSS/mesh: Skip VHT channel setup with vht_disabled=1
adc6a5d81 mesh: Check remote peer HT Operation element
9eb5757a8 Define helper function set_disable_ht40()
7813b7c34 nl80211: Fix a memory leak on deinit with HT enabled mesh
6b585f420 mesh: Fix crash on removing virtual mesh interface
5208160b4 FILS: Parse received FILS HLP requests
5732b770f FILS: Allow FILS HLP requests to be added
a1aa2aebc Remove unused WLAN_CIPHER_SUITE_* definitions
a042e39ac nl80211: Use RSN_CIPHER_SUITE_* instead of WLAN_CIPHER_SUITE_*
2373a3117 Define all RSN_CIPHER_SUITE_* values
89ba101e1 Remove unused WLAN_AKM_SUITE_* definitions
bf9f8a052 Use RSN_AUTH_KEY_MGMT_* instead of WLAN_AKM_SUITE_* for wpa_akm_to_suite()
3aa24db95 nl80211: Use RSN_AUTH_KEY_MGMT_* instead of WLAN_AKM_SUITE_*
a1343fa6b Remove unnecessary ifdef from RSN_AUTH_KEY_MGMT_* definitions
afe731004 Fix CONFIG_SAE build without CONFIG_SME
34e8bfd7a Skip EVENT_ACS_CHANNEL_SELECTED also without CONFIG_AP
510fc2dfc Fix AKM suite selectors for FILS and Suite B
d7d0f909f QCA vendor command to carry the reason for power save failure
53b38209f GAS: Cancel gas_query_timeout when AP responds with comeback delay
d5bd94133 MBO: Silence a compiler warning when building without CONFIG_MBO
4c4070005 QCA vendor command to enable host driver offload ACS to user space
4d77d80ed mesh: Add MESH_PMKSA_GET/ADD commands
117875db3 D-Bus: Add GroupMgmt entry into the interface Capabilities dict
3cdb4ac07 D-Bus: Add pmf to global capabilities
adf8f45f8 D-Bus: Implement Pmf property
b98706c14 RSN IBSS: Fix TK clearing on Authentication frame RX
fa67debf4 Fix duplicate Reassociation Request frame dropping
6ff92677a wext: Cancel send_rfkill timeout in deinit
fcd3d6ce3 FILS: Fix PMK and PMKID derivation from ERP
ef495c78d OpenSSL: Implement sha384_vector()
a70cd0db8 nl80211: Don't register for Beacon frames for IEEE 802.11ad AP
a2aa21a3b Assign additional vendor specific elements for early HE testing
f09095d57 wpa_supplicant: Clarify group_rekey documentation
c85dfc6f8 nl80211: Set NL80211_ATTR_IFACE_SOCKET_OWNER for connect and associate
d07f450da Sync with mac80211-next.git include/uapi/linux/nl80211.h
8f315d050 Fix country code in wpa_supplicant AP mode Country element
29065686a D-Bus: Fix BSS Mode getter for invalid DMG BSS
b2442f256 nl80211: Debug prints for TDLS_OPER command and result
2901bc272 bgscan: Remove unnecessary NULL check
9d6eaad6b bgscan: Remove unnecessary NULL check
0f9b4a0f1 bgscan: Deliver beacon loss event to bgscan modules
688556722 nl80211: More complete processing of connection quality monitor events
54736d835 Store FST parameters to configuration file
35c78f7b9 Store osu_dir to configuration file
1f539c78f Store autoscan to configuration file
58ed9e31d Store filter_rssi to configuration file
1fb1bf99d Write sec_device_type to configuration file
b4bdeadfa Make "SET" behavior more consistent for dot11RSNA parameters
e3394c0e2 Make "SET non_pref_chan .." behavior more consistent
f8c201862 Fix cert_in_cb parsing in wpa_supplicant.conf
9284418d0 Fix writing of wpa_supplicant sae_groups configuration parameter
167f78a5e Send BEACON-REQ-TX-STATUS event only for beacon reports
7ba94fc4b RRM: Use wpa_hexdump_buf() instead of wpa_hexdump()
e4ec6bbfd nl80211: Register for Link Measurement Report frames in AP mode
33468e532 RRM: Document Link Measurement Report frame construction steps
40e9a3f32 RRM: Fix beacon report scan channels for VHT 80, 80+80, 160 MHz cases
5cda35089 RRM: Move wpabuf_resize() call into wpas_rrm_report_elem()
f2058f4af RRM: Remove unnecessary cb check

Bug: 34681709
Test: Wifi Suite

Change-Id: Ib7ab577a02a9c499ef6e78a222bb93d811f29d36
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 43e3558..69e3a5d 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -75,8 +75,8 @@
 static inline int wpa_auth_mic_failure_report(
 	struct wpa_authenticator *wpa_auth, const u8 *addr)
 {
-	if (wpa_auth->cb.mic_failure_report)
-		return wpa_auth->cb.mic_failure_report(wpa_auth->cb.ctx, addr);
+	if (wpa_auth->cb->mic_failure_report)
+		return wpa_auth->cb->mic_failure_report(wpa_auth->cb_ctx, addr);
 	return 0;
 }
 
@@ -84,8 +84,8 @@
 static inline void wpa_auth_psk_failure_report(
 	struct wpa_authenticator *wpa_auth, const u8 *addr)
 {
-	if (wpa_auth->cb.psk_failure_report)
-		wpa_auth->cb.psk_failure_report(wpa_auth->cb.ctx, addr);
+	if (wpa_auth->cb->psk_failure_report)
+		wpa_auth->cb->psk_failure_report(wpa_auth->cb_ctx, addr);
 }
 
 
@@ -93,17 +93,17 @@
 				      const u8 *addr, wpa_eapol_variable var,
 				      int value)
 {
-	if (wpa_auth->cb.set_eapol)
-		wpa_auth->cb.set_eapol(wpa_auth->cb.ctx, addr, var, value);
+	if (wpa_auth->cb->set_eapol)
+		wpa_auth->cb->set_eapol(wpa_auth->cb_ctx, addr, var, value);
 }
 
 
 static inline int wpa_auth_get_eapol(struct wpa_authenticator *wpa_auth,
 				     const u8 *addr, wpa_eapol_variable var)
 {
-	if (wpa_auth->cb.get_eapol == NULL)
+	if (wpa_auth->cb->get_eapol == NULL)
 		return -1;
-	return wpa_auth->cb.get_eapol(wpa_auth->cb.ctx, addr, var);
+	return wpa_auth->cb->get_eapol(wpa_auth->cb_ctx, addr, var);
 }
 
 
@@ -112,19 +112,19 @@
 					  const u8 *p2p_dev_addr,
 					  const u8 *prev_psk)
 {
-	if (wpa_auth->cb.get_psk == NULL)
+	if (wpa_auth->cb->get_psk == NULL)
 		return NULL;
-	return wpa_auth->cb.get_psk(wpa_auth->cb.ctx, addr, p2p_dev_addr,
-				    prev_psk);
+	return wpa_auth->cb->get_psk(wpa_auth->cb_ctx, addr, p2p_dev_addr,
+				     prev_psk);
 }
 
 
 static inline int wpa_auth_get_msk(struct wpa_authenticator *wpa_auth,
 				   const u8 *addr, u8 *msk, size_t *len)
 {
-	if (wpa_auth->cb.get_msk == NULL)
+	if (wpa_auth->cb->get_msk == NULL)
 		return -1;
-	return wpa_auth->cb.get_msk(wpa_auth->cb.ctx, addr, msk, len);
+	return wpa_auth->cb->get_msk(wpa_auth->cb_ctx, addr, msk, len);
 }
 
 
@@ -133,19 +133,19 @@
 				   enum wpa_alg alg, const u8 *addr, int idx,
 				   u8 *key, size_t key_len)
 {
-	if (wpa_auth->cb.set_key == NULL)
+	if (wpa_auth->cb->set_key == NULL)
 		return -1;
-	return wpa_auth->cb.set_key(wpa_auth->cb.ctx, vlan_id, alg, addr, idx,
-				    key, key_len);
+	return wpa_auth->cb->set_key(wpa_auth->cb_ctx, vlan_id, alg, addr, idx,
+				     key, key_len);
 }
 
 
 static inline int wpa_auth_get_seqnum(struct wpa_authenticator *wpa_auth,
 				      const u8 *addr, int idx, u8 *seq)
 {
-	if (wpa_auth->cb.get_seqnum == NULL)
+	if (wpa_auth->cb->get_seqnum == NULL)
 		return -1;
-	return wpa_auth->cb.get_seqnum(wpa_auth->cb.ctx, addr, idx, seq);
+	return wpa_auth->cb->get_seqnum(wpa_auth->cb_ctx, addr, idx, seq);
 }
 
 
@@ -153,10 +153,10 @@
 wpa_auth_send_eapol(struct wpa_authenticator *wpa_auth, const u8 *addr,
 		    const u8 *data, size_t data_len, int encrypt)
 {
-	if (wpa_auth->cb.send_eapol == NULL)
+	if (wpa_auth->cb->send_eapol == NULL)
 		return -1;
-	return wpa_auth->cb.send_eapol(wpa_auth->cb.ctx, addr, data, data_len,
-				       encrypt);
+	return wpa_auth->cb->send_eapol(wpa_auth->cb_ctx, addr, data, data_len,
+					encrypt);
 }
 
 
@@ -164,9 +164,9 @@
 static inline int wpa_auth_start_ampe(struct wpa_authenticator *wpa_auth,
 				      const u8 *addr)
 {
-	if (wpa_auth->cb.start_ampe == NULL)
+	if (wpa_auth->cb->start_ampe == NULL)
 		return -1;
-	return wpa_auth->cb.start_ampe(wpa_auth->cb.ctx, addr);
+	return wpa_auth->cb->start_ampe(wpa_auth->cb_ctx, addr);
 }
 #endif /* CONFIG_MESH */
 
@@ -175,9 +175,9 @@
 			  int (*cb)(struct wpa_state_machine *sm, void *ctx),
 			  void *cb_ctx)
 {
-	if (wpa_auth->cb.for_each_sta == NULL)
+	if (wpa_auth->cb->for_each_sta == NULL)
 		return 0;
-	return wpa_auth->cb.for_each_sta(wpa_auth->cb.ctx, cb, cb_ctx);
+	return wpa_auth->cb->for_each_sta(wpa_auth->cb_ctx, cb, cb_ctx);
 }
 
 
@@ -185,18 +185,18 @@
 			   int (*cb)(struct wpa_authenticator *a, void *ctx),
 			   void *cb_ctx)
 {
-	if (wpa_auth->cb.for_each_auth == NULL)
+	if (wpa_auth->cb->for_each_auth == NULL)
 		return 0;
-	return wpa_auth->cb.for_each_auth(wpa_auth->cb.ctx, cb, cb_ctx);
+	return wpa_auth->cb->for_each_auth(wpa_auth->cb_ctx, cb, cb_ctx);
 }
 
 
 void wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr,
 		     logger_level level, const char *txt)
 {
-	if (wpa_auth->cb.logger == NULL)
+	if (wpa_auth->cb->logger == NULL)
 		return;
-	wpa_auth->cb.logger(wpa_auth->cb.ctx, addr, level, txt);
+	wpa_auth->cb->logger(wpa_auth->cb_ctx, addr, level, txt);
 }
 
 
@@ -207,7 +207,7 @@
 	int maxlen;
 	va_list ap;
 
-	if (wpa_auth->cb.logger == NULL)
+	if (wpa_auth->cb->logger == NULL)
 		return;
 
 	maxlen = os_strlen(fmt) + 100;
@@ -228,11 +228,11 @@
 static void wpa_sta_disconnect(struct wpa_authenticator *wpa_auth,
 			       const u8 *addr)
 {
-	if (wpa_auth->cb.disconnect == NULL)
+	if (wpa_auth->cb->disconnect == NULL)
 		return;
 	wpa_printf(MSG_DEBUG, "wpa_sta_disconnect STA " MACSTR, MAC2STR(addr));
-	wpa_auth->cb.disconnect(wpa_auth->cb.ctx, addr,
-				WLAN_REASON_PREV_AUTH_NOT_VALID);
+	wpa_auth->cb->disconnect(wpa_auth->cb_ctx, addr,
+				 WLAN_REASON_PREV_AUTH_NOT_VALID);
 }
 
 
@@ -416,7 +416,8 @@
  */
 struct wpa_authenticator * wpa_init(const u8 *addr,
 				    struct wpa_auth_config *conf,
-				    struct wpa_auth_callbacks *cb)
+				    const struct wpa_auth_callbacks *cb,
+				    void *cb_ctx)
 {
 	struct wpa_authenticator *wpa_auth;
 
@@ -425,7 +426,8 @@
 		return NULL;
 	os_memcpy(wpa_auth->addr, addr, ETH_ALEN);
 	os_memcpy(&wpa_auth->conf, conf, sizeof(*conf));
-	os_memcpy(&wpa_auth->cb, cb, sizeof(*cb));
+	wpa_auth->cb = cb;
+	wpa_auth->cb_ctx = cb_ctx;
 
 	if (wpa_auth_gen_wpa_ie(wpa_auth)) {
 		wpa_printf(MSG_ERROR, "Could not generate WPA IE.");
@@ -1949,7 +1951,7 @@
 #endif /* CONFIG_IEEE80211R_AP */
 	} else {
 		wpa_printf(MSG_DEBUG, "WPA: Could not get PMK, get_msk: %p",
-			   sm->wpa_auth->cb.get_msk);
+			   sm->wpa_auth->cb->get_msk);
 		sm->Disconnect = TRUE;
 		return;
 	}
@@ -3850,6 +3852,58 @@
 }
 
 
+#ifdef CONFIG_PMKSA_CACHE_EXTERNAL
+#ifdef CONFIG_MESH
+
+int wpa_auth_pmksa_list_mesh(struct wpa_authenticator *wpa_auth, const u8 *addr,
+			     char *buf, size_t len)
+{
+	if (!wpa_auth || !wpa_auth->pmksa)
+		return 0;
+
+	return pmksa_cache_auth_list_mesh(wpa_auth->pmksa, addr, buf, len);
+}
+
+
+struct rsn_pmksa_cache_entry *
+wpa_auth_pmksa_create_entry(const u8 *aa, const u8 *spa, const u8 *pmk,
+			    const u8 *pmkid, int expiration)
+{
+	struct rsn_pmksa_cache_entry *entry;
+	struct os_reltime now;
+
+	entry = pmksa_cache_auth_create_entry(pmk, PMK_LEN, pmkid, NULL, 0, aa,
+					      spa, 0, NULL, WPA_KEY_MGMT_SAE);
+	if (!entry)
+		return NULL;
+
+	os_get_reltime(&now);
+	entry->expiration = now.sec + expiration;
+	return entry;
+}
+
+
+int wpa_auth_pmksa_add_entry(struct wpa_authenticator *wpa_auth,
+			     struct rsn_pmksa_cache_entry *entry)
+{
+	int ret;
+
+	if (!wpa_auth || !wpa_auth->pmksa)
+		return -1;
+
+	ret = pmksa_cache_auth_add_entry(wpa_auth->pmksa, entry);
+	if (ret < 0)
+		wpa_printf(MSG_DEBUG,
+			   "RSN: Failed to store external PMKSA cache for "
+			   MACSTR, MAC2STR(entry->spa));
+
+	return ret;
+}
+
+#endif /* CONFIG_MESH */
+#endif /* CONFIG_PMKSA_CACHE_EXTERNAL */
+
+
 struct rsn_pmksa_cache_entry *
 wpa_auth_pmksa_get(struct wpa_authenticator *wpa_auth, const u8 *sta_addr,
 		   const u8 *pmkid)