Cumulative patch from commit 128f6a98b3d4d6ed103db759707309f451db9682

128f6a98b mka: Fix the order of operations in secure channel deletion
213eb1885 dbus: Set mode to mesh in bss properties when mesh is supported
21fda4ee7 RSN: Fix pre-authentication EAPOL-Start startPeriod configuration
3f23260da nl80211: Notify reason for connection timeout failure
ca1ab9db2 hostapd: Get vendor HE capabilities
7785c70bb QCA vendor command for fetching HE capabilities
d512f406f hostapd: Add IEEE 802.11ax HE IEs into Beacon/Probe Response frames
94380cb40 hostapd: Initial IEEE 802.11ax (HE) definitions
5972dc73c mesh: Use correct rate in VHT and HT mixed environment
84ea61cff mesh: Use correct rate in HT and legacy mixed environment
025c6a47f VHT: Remove a redundant check
a7a638c2c hw_features: Move VHT capabilities checks to common
e01cf2afc Define eapol_sm_get_eap_proxy_imsi() only with CONFIG_EAP_PROXY=y
a8e25deeb FT: Merge similar error paths to use common steps
c6c41f6ea FT: Support addition of RIC elements into Reassociation Request frame
ecbdc1a1f Mark RSN msg 1/2 key data debug dump as key material
834c5d681 FILS: Fix PMK length for initial connection with FILS SHA384 AKM
e491389eb FILS: Fix ifdef for PTK derivation with SHA384-based AKM
62944f7d2 Add HMAC-SHA384 with internal crypto
aeecd4eae OpenSSL: Fix hmac_sha384_vector() implementation
5db32adc9 browser-wpadebug: Send HTTP response with HTTP/1.1 header
79329ae0a P2P: Verify local driver preferred frequencies for P2P use cases
3a7819f0a P2P: Add P2P_SET override_pref_op_chan to allow overriding preference
c06fca04f Add wpa_supplicant SET get_pref_freq_list_override
b4d56efb1 Use throughput estimate-based BSS selection with larger SNR difference
142041487 Drop GREAT_SNR definition from 30 to 25 dB
364c064a4 FT: Check key derivation results explicitly in AP operations
b5562a1a6 FILS: Remove CRC32 dependency from build
5cf0930f9 testS: Additional BSS TM error case coverage
885bbd4de WNM: Remove unused code from BSS TM Req generation
e7ddd86a9 WNM: Use a common error path in ieee802_11_send_wnmsleep_resp()
d6d5970e2 WNM: Fix WNM-Sleep Mode Request parsing for WNM-Sleep element
8492cc79c PeerKey: Remove dead code related to STSL negotiation state
e37c0aa5d OSU server: Remove invalid options from documentation
0d6056703 WMM: Fix estimated medium time calculation for some corner cases
ae26d3021 Fix "IEEE 802.11: Ignored Action frame" debug message
4ead4c7ec WMM: Remove obsolete TODO comments
577e794eb Sync android.config with wpa_supplicant defconfig changes
784710b7f Add bgscan options to wpa_supplicant defconfig
212a8f487 Fix wpa_supplicant defconfig copy-paste description
57c3a605c Add support to sched scan to report relatively better BSSs
20c846d9e nl80211: sched_scan relative RSSI parameters
37e9f511e mka: Send MKPDUs forever if mode is PSK
76aa31838 EAP: Call deinit_for_reauth() for Phase 2 EAP methods
02156b98b EAP-AKA: Don't use anonymous identity in phase2
9e2afe10e EAP-SIM: Don't use anonymous identity in phase2
ed9b1c16d EAP peer: Cache decrypted requests for EAP-SIM/AKA/AKA'
5f11880f6 SME: Remove null ie param from CTRL-EVENT-AUTH-REJECT
4d70b2a4e RRM: Fix a memory leak in beacon request handling
401243b73 RRM: Fix range request overriding
fb81c0a3d RRM: Merge similar error returns to a single one
13b30052d RRM: Fix Range Request max age parsing
bd6ec7f7c Fix MAC ACL query freeing on deinit
b4fd1f0ed Allow PNO scan also in connection completed state
4c6f450ca Add radio_work_is_connect() helper
85b6b6b6e Serialize scan/p2p-scan if already scheduled on the same interface
fcb303a57 P2P: Clear driver scan cache after BSS_FLUSH
0d6dc6830 FILS: Clean up HLP resize check
1d9d21f37 GAS: Add support to randomize transmitter address
8331c9b31 nl80211: Add support for mgmt_tx with random TA
14fa723a9 Sync with mac80211-next.git include/uapi/linux/nl80211.h
65ab7eb1f GAS: Fix OSU Providers List response with invalid configuration
f3e157057 VHT: Fill VHT capability with hardware capability
4bb9b674c Add a log message when GTK rekeying failed
41f140d38 Add hostapd options wpa_group_update_count and wpa_pairwise_update_count
e54691106 mka: Some bug fixes for MACsec in PSK mode
7faf403f9 mka: Fix an incorrect update of participant->to_use_sak
00e0f0b01 hs20-osu-client: Hide a trivial compiler warning
276e93654 hw_features: Clean center freq for falling back HT40 channels
f47f93617 P2P: Override P2P_PEER group_capab with 0 if no matching BSS entry found
bcf66493c Fix estimated throughput based skip-roam case
84bb12aa6 FILS: Fix send_assoc_resp() HLP extension to cover sta == NULL
275cc9428 FILS: Stop processing if fils_rmsk_to_pmk() fails
caab23f19 Set EAPOL-Key Key Length field to 0 for group message 1/2 in RSN
b0fb2be77 Do not send GNonce in EAPOL-Key group message 1/2
3bbc47050 Fix EAPOL-Key Install bit in Group Key 1/2 with FT and FILS auth
db5e53cb0 mesh: Fix struct hostapd_data initialization
9b170991a mesh: Fix mesh interface removal fix
945604a35 Update wpaspy.py to be python3 compatible
4d6e79f86 Use defines in hostapd_set_freq_params()
0217b8d87 eloop: Fix comments mismatch eloop_event/timeout_handler definitions
09a97eb27 Update the copyright notice years for QCA vendor definitions
841e9a8c7 QCA vendor command to set the trace levels for the specific QCA module
d77f33041 FILS: Fix AES-SIV AAD for (Re)Association Request frame decryption
7a6c3de23 ERP: Use macro for EMSKname length instead of hardcoded integer value
bb3ea71a2 ERP: Fix rIK derivation
124ddfa19 FILS: Parse and report received FILS HLP Containers from response
91d91abf6 FILS: DHCP relay for HLP requests
54b04d6f3 FILS: Move HLP request handling into a separate file
5a9d50493 ProxyARP: Use more robust DHCP option parsing
e64c13feb Move DHCP definitions into a common file
70407ee5c Add QCA vendor definitions for BSS transition status
53d171440 AP: Check ACL upon association request for 802.11ad
4cc61c386 GAS: Set temporary session timeout bigger than gas_comeback_delay

Test: Wifi Suite

Change-Id: Id597d7cba5d2b3875f2dbbeb9a10fd5e69a6a7c2
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index cceeee0..e1a6712 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -45,6 +45,7 @@
 #include "mbo_ap.h"
 #include "rrm.h"
 #include "taxonomy.h"
+#include "fils_hlp.h"
 
 
 u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
@@ -1301,6 +1302,89 @@
 #endif /* CONFIG_FILS */
 
 
+static int
+ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
+			   const u8 *msg, size_t len, u32 *session_timeout,
+			   u32 *acct_interim_interval,
+			   struct vlan_description *vlan_id,
+			   struct hostapd_sta_wpa_psk_short **psk,
+			   char **identity, char **radius_cui)
+{
+	int res;
+
+	os_memset(vlan_id, 0, sizeof(*vlan_id));
+	res = hostapd_allowed_address(hapd, addr, msg, len,
+				      session_timeout, acct_interim_interval,
+				      vlan_id, psk, identity, radius_cui);
+
+	if (res == HOSTAPD_ACL_REJECT) {
+		wpa_printf(MSG_INFO,
+			   "Station " MACSTR " not allowed to authenticate",
+			   MAC2STR(addr));
+		return HOSTAPD_ACL_REJECT;
+	}
+
+	if (res == HOSTAPD_ACL_PENDING) {
+		wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
+			   " waiting for an external authentication",
+			   MAC2STR(addr));
+		/* Authentication code will re-send the authentication frame
+		 * after it has received (and cached) information from the
+		 * external source. */
+		return HOSTAPD_ACL_PENDING;
+	}
+
+	return res;
+}
+
+
+static int
+ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
+			   int res, u32 session_timeout,
+			   u32 acct_interim_interval,
+			   struct vlan_description *vlan_id,
+			   struct hostapd_sta_wpa_psk_short **psk,
+			   char **identity, char **radius_cui)
+{
+	if (vlan_id->notempty &&
+	    !hostapd_vlan_valid(hapd->conf->vlan, vlan_id)) {
+		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
+			       HOSTAPD_LEVEL_INFO,
+			       "Invalid VLAN %d%s received from RADIUS server",
+			       vlan_id->untagged,
+			       vlan_id->tagged[0] ? "+" : "");
+		return -1;
+	}
+	if (ap_sta_set_vlan(hapd, sta, vlan_id) < 0)
+		return -1;
+	if (sta->vlan_id)
+		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
+			       HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
+
+	hostapd_free_psk_list(sta->psk);
+	if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
+		sta->psk = *psk;
+		*psk = NULL;
+	} else {
+		sta->psk = NULL;
+	}
+
+	sta->identity = *identity;
+	*identity = NULL;
+	sta->radius_cui = *radius_cui;
+	*radius_cui = NULL;
+
+	if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
+		sta->acct_interim_interval = acct_interim_interval;
+	if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
+		ap_sta_session_timeout(hapd, sta, session_timeout);
+	else
+		ap_sta_no_session_timeout(hapd, sta);
+
+	return 0;
+}
+
+
 static void handle_auth(struct hostapd_data *hapd,
 			const struct ieee80211_mgmt *mgmt, size_t len)
 {
@@ -1319,8 +1403,6 @@
 	char *radius_cui = NULL;
 	u16 seq_ctrl;
 
-	os_memset(&vlan_id, 0, sizeof(vlan_id));
-
 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
 		wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
 			   (unsigned long) len);
@@ -1464,26 +1546,15 @@
 		}
 	}
 
-	res = hostapd_allowed_address(hapd, mgmt->sa, (u8 *) mgmt, len,
-				      &session_timeout,
-				      &acct_interim_interval, &vlan_id,
-				      &psk, &identity, &radius_cui);
-
+	res = ieee802_11_allowed_address(
+		hapd, mgmt->sa, (const u8 *) mgmt, len, &session_timeout,
+		&acct_interim_interval, &vlan_id, &psk, &identity, &radius_cui);
 	if (res == HOSTAPD_ACL_REJECT) {
-		wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate",
-			   MAC2STR(mgmt->sa));
 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
 		goto fail;
 	}
-	if (res == HOSTAPD_ACL_PENDING) {
-		wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
-			   " waiting for an external authentication",
-			   MAC2STR(mgmt->sa));
-		/* Authentication code will re-send the authentication frame
-		 * after it has received (and cached) information from the
-		 * external source. */
+	if (res == HOSTAPD_ACL_PENDING)
 		return;
-	}
 
 	sta = ap_get_sta(hapd, mgmt->sa);
 	if (sta) {
@@ -1536,47 +1607,17 @@
 	sta->last_seq_ctrl = seq_ctrl;
 	sta->last_subtype = WLAN_FC_STYPE_AUTH;
 
-	if (vlan_id.notempty &&
-	    !hostapd_vlan_valid(hapd->conf->vlan, &vlan_id)) {
-		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
-			       HOSTAPD_LEVEL_INFO,
-			       "Invalid VLAN %d%s received from RADIUS server",
-			       vlan_id.untagged,
-			       vlan_id.tagged[0] ? "+" : "");
+	res = ieee802_11_set_radius_info(
+		hapd, sta, res, session_timeout, acct_interim_interval,
+		&vlan_id, &psk, &identity, &radius_cui);
+	if (res) {
 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
 		goto fail;
 	}
-	if (ap_sta_set_vlan(hapd, sta, &vlan_id) < 0) {
-		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
-		goto fail;
-	}
-	if (sta->vlan_id)
-		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
-			       HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
-
-	hostapd_free_psk_list(sta->psk);
-	if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED) {
-		sta->psk = psk;
-		psk = NULL;
-	} else {
-		sta->psk = NULL;
-	}
-
-	sta->identity = identity;
-	identity = NULL;
-	sta->radius_cui = radius_cui;
-	radius_cui = NULL;
 
 	sta->flags &= ~WLAN_STA_PREAUTH;
 	ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
 
-	if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
-		sta->acct_interim_interval = acct_interim_interval;
-	if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT)
-		ap_sta_session_timeout(hapd, sta, session_timeout);
-	else
-		ap_sta_no_session_timeout(hapd, sta);
-
 	/*
 	 * If the driver supports full AP client state, add a station to the
 	 * driver before sending authentication reply to make sure the driver
@@ -2225,11 +2266,22 @@
 			   const u8 *ies, size_t ies_len)
 {
 	int send_len;
-	u8 buf[sizeof(struct ieee80211_mgmt) + 1024];
+	u8 *buf;
+	size_t buflen;
 	struct ieee80211_mgmt *reply;
 	u8 *p;
+	u16 res = WLAN_STATUS_SUCCESS;
 
-	os_memset(buf, 0, sizeof(buf));
+	buflen = sizeof(struct ieee80211_mgmt) + 1024;
+#ifdef CONFIG_FILS
+	if (sta && sta->fils_hlp_resp)
+		buflen += wpabuf_len(sta->fils_hlp_resp);
+#endif /* CONFIG_FILS */
+	buf = os_zalloc(buflen);
+	if (!buf) {
+		res = WLAN_STATUS_UNSPECIFIED_FAILURE;
+		goto done;
+	}
 	reply = (struct ieee80211_mgmt *) buf;
 	reply->frame_control =
 		IEEE80211_FC(WLAN_FC_TYPE_MGMT,
@@ -2257,7 +2309,7 @@
 		/* IEEE 802.11r: Mobility Domain Information, Fast BSS
 		 * Transition Information, RSN, [RIC Response] */
 		p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
-						buf + sizeof(buf) - p,
+						buf + buflen - p,
 						sta->auth_alg, ies, ies_len);
 	}
 #endif /* CONFIG_IEEE80211R_AP */
@@ -2359,10 +2411,10 @@
 		p = hostapd_eid_p2p_manage(hapd, p);
 #endif /* CONFIG_P2P_MANAGER */
 
-	p = hostapd_eid_mbo(hapd, p, buf + sizeof(buf) - p);
+	p = hostapd_eid_mbo(hapd, p, buf + buflen - p);
 
 	if (hapd->conf->assocresp_elements &&
-	    (size_t) (buf + sizeof(buf) - p) >=
+	    (size_t) (buf + buflen - p) >=
 	    wpabuf_len(hapd->conf->assocresp_elements)) {
 		os_memcpy(p, wpabuf_head(hapd->conf->assocresp_elements),
 			  wpabuf_len(hapd->conf->assocresp_elements));
@@ -2380,8 +2432,10 @@
 		struct ieee802_11_elems elems;
 
 		if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
-		    ParseFailed || !elems.fils_session)
-			return WLAN_STATUS_UNSPECIFIED_FAILURE;
+		    ParseFailed || !elems.fils_session) {
+			res = WLAN_STATUS_UNSPECIFIED_FAILURE;
+			goto done;
+		}
 
 		/* FILS Session */
 		*p++ = WLAN_EID_EXTENSION; /* Element ID */
@@ -2391,96 +2445,70 @@
 		send_len += 2 + 1 + FILS_SESSION_LEN;
 
 		send_len = fils_encrypt_assoc(sta->wpa_sm, buf, send_len,
-					      sizeof(buf));
-		if (send_len < 0)
-			return WLAN_STATUS_UNSPECIFIED_FAILURE;
+					      buflen, sta->fils_hlp_resp);
+		if (send_len < 0) {
+			res = WLAN_STATUS_UNSPECIFIED_FAILURE;
+			goto done;
+		}
 	}
 #endif /* CONFIG_FILS */
 
 	if (hostapd_drv_send_mlme(hapd, reply, send_len, 0) < 0) {
 		wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
 			   strerror(errno));
-		return WLAN_STATUS_UNSPECIFIED_FAILURE;
+		res = WLAN_STATUS_UNSPECIFIED_FAILURE;
 	}
 
-	return WLAN_STATUS_SUCCESS;
+done:
+	os_free(buf);
+	return res;
 }
 
 
 #ifdef CONFIG_FILS
 
-static void fils_process_hlp_req(struct hostapd_data *hapd,
-				 struct sta_info *sta,
-				 const u8 *pos, size_t len)
+void fils_hlp_finish_assoc(struct hostapd_data *hapd, struct sta_info *sta)
 {
-	const u8 *pkt, *end;
+	u16 reply_res;
 
-	wpa_printf(MSG_DEBUG, "FILS: HLP request from " MACSTR " (dst=" MACSTR
-		   " src=" MACSTR " len=%u)",
-		   MAC2STR(sta->addr), MAC2STR(pos), MAC2STR(pos + ETH_ALEN),
-		   (unsigned int) len);
-	if (os_memcmp(sta->addr, pos + ETH_ALEN, ETH_ALEN) != 0) {
-		wpa_printf(MSG_DEBUG,
-			   "FILS: Ignore HLP request with unexpected source address"
-			   MACSTR, MAC2STR(pos + ETH_ALEN));
+	wpa_printf(MSG_DEBUG, "FILS: Finish association with " MACSTR,
+		   MAC2STR(sta->addr));
+	eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
+	if (!sta->fils_pending_assoc_req)
 		return;
-	}
+	reply_res = send_assoc_resp(hapd, sta, sta->addr, WLAN_STATUS_SUCCESS,
+				    sta->fils_pending_assoc_is_reassoc,
+				    sta->fils_pending_assoc_req,
+				    sta->fils_pending_assoc_req_len);
+	os_free(sta->fils_pending_assoc_req);
+	sta->fils_pending_assoc_req = NULL;
+	sta->fils_pending_assoc_req_len = 0;
+	wpabuf_free(sta->fils_hlp_resp);
+	sta->fils_hlp_resp = NULL;
+	wpabuf_free(sta->hlp_dhcp_discover);
+	sta->hlp_dhcp_discover = NULL;
 
-	end = pos + len;
-	pkt = pos + 2 * ETH_ALEN;
-	if (end - pkt >= 6 &&
-	    os_memcmp(pkt, "\xaa\xaa\x03\x00\x00\x00", 6) == 0)
-		pkt += 6; /* Remove SNAP/LLC header */
-	wpa_hexdump(MSG_MSGDUMP, "FILS: HLP request packet", pkt, end - pkt);
+	/*
+	 * Remove the station in case tranmission of a success response fails
+	 * (the STA was added associated to the driver) or if the station was
+	 * previously added unassociated.
+	 */
+	if (reply_res != WLAN_STATUS_SUCCESS || sta->added_unassoc) {
+		hostapd_drv_sta_remove(hapd, sta->addr);
+		sta->added_unassoc = 0;
+	}
 }
 
 
-static void fils_process_hlp(struct hostapd_data *hapd, struct sta_info *sta,
-			     const u8 *pos, int left)
+void fils_hlp_timeout(void *eloop_ctx, void *eloop_data)
 {
-	const u8 *end = pos + left;
-	u8 *tmp, *tmp_pos;
+	struct hostapd_data *hapd = eloop_ctx;
+	struct sta_info *sta = eloop_data;
 
-	/* Check if there are any FILS HLP Container elements */
-	while (end - pos >= 2) {
-		if (2 + pos[1] > end - pos)
-			return;
-		if (pos[0] == WLAN_EID_EXTENSION &&
-		    pos[1] >= 1 + 2 * ETH_ALEN &&
-		    pos[2] == WLAN_EID_EXT_FILS_HLP_CONTAINER)
-			break;
-		pos += 2 + pos[1];
-	}
-	if (end - pos < 2)
-		return; /* No FILS HLP Container elements */
-
-	tmp = os_malloc(end - pos);
-	if (!tmp)
-		return;
-
-	while (end - pos >= 2) {
-		if (2 + pos[1] > end - pos ||
-		    pos[0] != WLAN_EID_EXTENSION ||
-		    pos[1] < 1 + 2 * ETH_ALEN ||
-		    pos[2] != WLAN_EID_EXT_FILS_HLP_CONTAINER)
-			break;
-		tmp_pos = tmp;
-		os_memcpy(tmp_pos, pos + 3, pos[1] - 1);
-		tmp_pos += pos[1] - 1;
-		pos += 2 + pos[1];
-
-		/* Add possible fragments */
-		while (end - pos >= 2 && pos[0] == WLAN_EID_FRAGMENT &&
-		       2 + pos[1] <= end - pos) {
-			os_memcpy(tmp_pos, pos + 2, pos[1]);
-			tmp_pos += pos[1];
-			pos += 2 + pos[1];
-		}
-
-		fils_process_hlp_req(hapd, sta, tmp, tmp_pos - tmp);
-	}
-
-	os_free(tmp);
+	wpa_printf(MSG_DEBUG,
+		   "FILS: HLP response timeout - continue with association response for "
+		   MACSTR, MAC2STR(sta->addr));
+	fils_hlp_finish_assoc(hapd, sta);
 }
 
 #endif /* CONFIG_FILS */
@@ -2496,6 +2524,12 @@
 	int left, i;
 	struct sta_info *sta;
 	u8 *tmp = NULL;
+	struct hostapd_sta_wpa_psk_short *psk = NULL;
+	char *identity = NULL;
+	char *radius_cui = NULL;
+#ifdef CONFIG_FILS
+	int delay_assoc = 0;
+#endif /* CONFIG_FILS */
 
 	if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
 				      sizeof(mgmt->u.assoc_req))) {
@@ -2571,6 +2605,21 @@
 		if (hapd->iface->current_mode &&
 		    hapd->iface->current_mode->mode ==
 			HOSTAPD_MODE_IEEE80211AD) {
+			int acl_res;
+			u32 session_timeout, acct_interim_interval;
+			struct vlan_description vlan_id;
+
+			acl_res = ieee802_11_allowed_address(
+				hapd, mgmt->sa, (const u8 *) mgmt, len,
+				&session_timeout, &acct_interim_interval,
+				&vlan_id, &psk, &identity, &radius_cui);
+			if (acl_res == HOSTAPD_ACL_REJECT) {
+				resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
+				goto fail;
+			}
+			if (acl_res == HOSTAPD_ACL_PENDING)
+				return;
+
 			/* DMG/IEEE 802.11ad does not use authentication.
 			 * Allocate sta entry upon association. */
 			sta = ap_sta_add(hapd, mgmt->sa);
@@ -2583,6 +2632,15 @@
 				goto fail;
 			}
 
+			acl_res = ieee802_11_set_radius_info(
+				hapd, sta, acl_res, session_timeout,
+				acct_interim_interval, &vlan_id, &psk,
+				&identity, &radius_cui);
+			if (acl_res) {
+				resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
+				goto fail;
+			}
+
 			hostapd_logger(hapd, sta->addr,
 				       HOSTAPD_MODULE_IEEE80211,
 				       HOSTAPD_LEVEL_DEBUG,
@@ -2760,11 +2818,17 @@
 #ifdef CONFIG_FILS
 	if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
 	    sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
-	    sta->auth_alg == WLAN_AUTH_FILS_PK)
-		fils_process_hlp(hapd, sta, pos, left);
+	    sta->auth_alg == WLAN_AUTH_FILS_PK) {
+		if (fils_process_hlp(hapd, sta, pos, left) > 0)
+			delay_assoc = 1;
+	}
 #endif /* CONFIG_FILS */
 
  fail:
+	os_free(identity);
+	os_free(radius_cui);
+	hostapd_free_psk_list(psk);
+
 	/*
 	 * In case of a successful response, add the station to the driver.
 	 * Otherwise, the kernel may ignore Data frames before we process the
@@ -2786,6 +2850,29 @@
 	if (resp == WLAN_STATUS_SUCCESS && sta && add_associated_sta(hapd, sta))
 		resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
 
+#ifdef CONFIG_FILS
+	if (sta) {
+		eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
+		os_free(sta->fils_pending_assoc_req);
+		sta->fils_pending_assoc_req = NULL;
+		sta->fils_pending_assoc_req_len = 0;
+		wpabuf_free(sta->fils_hlp_resp);
+		sta->fils_hlp_resp = NULL;
+	}
+	if (sta && delay_assoc && resp == WLAN_STATUS_SUCCESS) {
+		sta->fils_pending_assoc_req = tmp;
+		sta->fils_pending_assoc_req_len = left;
+		sta->fils_pending_assoc_is_reassoc = reassoc;
+		wpa_printf(MSG_DEBUG,
+			   "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
+			   MACSTR, MAC2STR(sta->addr));
+		eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
+		eloop_register_timeout(0, hapd->conf->fils_hlp_wait_time * 1024,
+				       fils_hlp_timeout, hapd, sta);
+		return;
+	}
+#endif /* CONFIG_FILS */
+
 	reply_res = send_assoc_resp(hapd, sta, mgmt->sa, resp, reassoc, pos,
 				    left);
 	os_free(tmp);
@@ -2975,7 +3062,7 @@
 	    (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
 		wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored Action "
 			   "frame (category=%u) from unassociated STA " MACSTR,
-			   MAC2STR(mgmt->sa), mgmt->u.action.category);
+			   mgmt->u.action.category, MAC2STR(mgmt->sa));
 		return 0;
 	}