• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hostapd / IEEE 802.11 Management
3  * Copyright (c) 2002-2017, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "utils/includes.h"
10 
11 #ifndef CONFIG_NATIVE_WINDOWS
12 
13 #include "utils/common.h"
14 #include "utils/eloop.h"
15 #include "crypto/crypto.h"
16 #include "crypto/sha256.h"
17 #ifdef CONFIG_OWE
18 #include "crypto/sha384.h"
19 #include "crypto/sha512.h"
20 #endif /* CONFIG_OWE */
21 #include "crypto/random.h"
22 #include "common/ieee802_11_defs.h"
23 #include "common/ieee802_11_common.h"
24 #include "common/wpa_ctrl.h"
25 #include "common/sae.h"
26 #include "common/dpp.h"
27 #include "common/ocv.h"
28 #include "common/wpa_common.h"
29 #include "common/wpa_ctrl.h"
30 #include "common/ptksa_cache.h"
31 #ifndef EXT_CODE_CROP
32 #include "radius/radius.h"
33 #include "radius/radius_client.h"
34 #endif /* EXT_CODE_CROP */
35 #include "p2p/p2p.h"
36 #include "wps/wps.h"
37 #include "fst/fst.h"
38 #include "hostapd.h"
39 #include "beacon.h"
40 #ifndef EXT_CODE_CROP
41 #include "ieee802_11_auth.h"
42 #endif
43 #include "sta_info.h"
44 #include "ieee802_1x.h"
45 #include "wpa_auth.h"
46 #include "pmksa_cache_auth.h"
47 #include "wmm.h"
48 #include "ap_list.h"
49 #include "accounting.h"
50 #include "ap_config.h"
51 #include "ap_mlme.h"
52 #include "p2p_hostapd.h"
53 #include "ap_drv_ops.h"
54 #include "wnm_ap.h"
55 #include "hw_features.h"
56 #include "ieee802_11.h"
57 #include "dfs.h"
58 #include "mbo_ap.h"
59 #include "rrm.h"
60 #include "taxonomy.h"
61 #ifdef LOS_CONFIG_MESH
62 #include "soc_mesh.h"
63 #endif /* LOS_CONFIG_MESH */
64 #ifndef EXT_CODE_CROP
65 #include "fils_hlp.h"
66 #include "dpp_hostapd.h"
67 #include "gas_query_ap.h"
68 #endif /* EXT_CODE_CROP */
69 
70 #ifdef CONFIG_FILS
71 static struct wpabuf *
72 prepare_auth_resp_fils(struct hostapd_data *hapd,
73 		       struct sta_info *sta, u16 *resp,
74 		       struct rsn_pmksa_cache_entry *pmksa,
75 		       struct wpabuf *erp_resp,
76 		       const u8 *msk, size_t msk_len,
77 		       int *is_pub);
78 #endif /* CONFIG_FILS */
79 
80 #ifdef CONFIG_PASN
81 
82 static int handle_auth_pasn_resp(struct hostapd_data *hapd,
83 				 struct sta_info *sta,
84 				 struct rsn_pmksa_cache_entry *pmksa,
85 				 u16 status);
86 #ifdef CONFIG_FILS
87 
88 static void pasn_fils_auth_resp(struct hostapd_data *hapd,
89 				struct sta_info *sta, u16 status,
90 				struct wpabuf *erp_resp,
91 				const u8 *msk, size_t msk_len);
92 
93 #endif /* CONFIG_FILS */
94 #endif /* CONFIG_PASN */
95 #ifdef LOS_CONFIG_HOSTAPD_MGMT
96 static void handle_auth(struct hostapd_data *hapd,
97 			const struct ieee80211_mgmt *mgmt, size_t len,
98 			int rssi, int from_queue);
99 #endif /* LOS_CONFIG_HOSTAPD_MGMT */
100 
101 #ifdef CONFIG_MULTI_AP
hostapd_eid_multi_ap(struct hostapd_data * hapd,u8 * eid)102 u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid)
103 {
104 	u8 multi_ap_val = 0;
105 
106 	if (!hapd->conf->multi_ap)
107 		return eid;
108 	if (hapd->conf->multi_ap & BACKHAUL_BSS)
109 		multi_ap_val |= MULTI_AP_BACKHAUL_BSS;
110 	if (hapd->conf->multi_ap & FRONTHAUL_BSS)
111 		multi_ap_val |= MULTI_AP_FRONTHAUL_BSS;
112 
113 	return eid + add_multi_ap_ie(eid, 9, multi_ap_val);
114 }
115 #endif /* CONFIG_MULTI_AP */
116 
117 
hostapd_eid_supp_rates(struct hostapd_data * hapd,u8 * eid)118 u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
119 {
120 	u8 *pos = eid;
121 	int i, num, count;
122 	int h2e_required;
123 
124 	if (hapd->iface->current_rates == NULL)
125 		return eid;
126 
127 	*pos++ = WLAN_EID_SUPP_RATES;
128 	num = hapd->iface->num_rates;
129 #ifndef EXT_CODE_CROP
130 	if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
131 		num++;
132 	if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
133 		num++;
134 	h2e_required = (hapd->conf->sae_pwe == 1 ||
135 			hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&
136 		hapd->conf->sae_pwe != 3 &&
137 		wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt);
138 	if (h2e_required)
139 		num++;
140 #endif /* EXT_CODE_CROP */
141 	if (num > 8) {
142 		/* rest of the rates are encoded in Extended supported
143 		 * rates element */
144 		num = 8;
145 	}
146 
147 	*pos++ = num;
148 	for (i = 0, count = 0; i < hapd->iface->num_rates && count < num;
149 	     i++) {
150 		count++;
151 		*pos = hapd->iface->current_rates[i].rate / 5;
152 		if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
153 			*pos |= 0x80;
154 		pos++;
155 	}
156 
157 #ifndef EXT_CODE_CROP
158 	if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && count < 8) {
159 		count++;
160 		*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
161 	}
162 
163 	if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht && count < 8) {
164 		count++;
165 		*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
166 	}
167 
168 	if (h2e_required && count < 8) {
169 		count++;
170 		*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
171 	}
172 #endif /* EXT_CODE_CROP */
173 	return pos;
174 }
175 
176 
hostapd_eid_ext_supp_rates(struct hostapd_data * hapd,u8 * eid)177 u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
178 {
179 	u8 *pos = eid;
180 	int i, num, count;
181 	int h2e_required;
182 
183 	if (hapd->iface->current_rates == NULL)
184 		return eid;
185 
186 	num = hapd->iface->num_rates;
187 #ifndef EXT_CODE_CROP
188 	if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
189 		num++;
190 	if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
191 		num++;
192 	h2e_required = (hapd->conf->sae_pwe == 1 ||
193 			hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&
194 		hapd->conf->sae_pwe != 3 &&
195 		wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt);
196 	if (h2e_required)
197 		num++;
198 #endif /* EXT_CODE_CROP */
199 	if (num <= 8)
200 		return eid;
201 	num -= 8;
202 
203 	*pos++ = WLAN_EID_EXT_SUPP_RATES;
204 	*pos++ = num;
205 	for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8;
206 	     i++) {
207 		count++;
208 		if (count <= 8)
209 			continue; /* already in SuppRates IE */
210 		*pos = hapd->iface->current_rates[i].rate / 5;
211 		if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
212 			*pos |= 0x80;
213 		pos++;
214 	}
215 
216 #ifndef EXT_CODE_CROP
217 	if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) {
218 		count++;
219 		if (count > 8)
220 			*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
221 	}
222 
223 	if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht) {
224 		count++;
225 		if (count > 8)
226 			*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
227 	}
228 #endif /* EXT_CODE_CROP */
229 	if (h2e_required) {
230 		count++;
231 		if (count > 8)
232 			*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
233 	}
234 
235 	return pos;
236 }
237 
238 
hostapd_eid_rm_enabled_capab(struct hostapd_data * hapd,u8 * eid,size_t len)239 u8 * hostapd_eid_rm_enabled_capab(struct hostapd_data *hapd, u8 *eid,
240 				  size_t len)
241 {
242 	size_t i;
243 
244 	for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
245 		if (hapd->conf->radio_measurements[i])
246 			break;
247 	}
248 
249 	if (i == RRM_CAPABILITIES_IE_LEN || len < 2 + RRM_CAPABILITIES_IE_LEN)
250 		return eid;
251 
252 	*eid++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
253 	*eid++ = RRM_CAPABILITIES_IE_LEN;
254 	os_memcpy(eid, hapd->conf->radio_measurements, RRM_CAPABILITIES_IE_LEN);
255 
256 	return eid + RRM_CAPABILITIES_IE_LEN;
257 }
258 
259 
hostapd_own_capab_info(struct hostapd_data * hapd)260 u16 hostapd_own_capab_info(struct hostapd_data *hapd)
261 {
262 	int capab = WLAN_CAPABILITY_ESS;
263 	int privacy = 0;
264 #ifndef EXT_CODE_CROP
265 	int dfs;
266 	int i;
267 
268 	/* Check if any of configured channels require DFS */
269 	dfs = hostapd_is_dfs_required(hapd->iface);
270 	if (dfs < 0) {
271 		wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
272 			   dfs);
273 		dfs = 0;
274 	}
275 
276 	if (hapd->iface->num_sta_no_short_preamble == 0 &&
277 	    hapd->iconf->preamble == SHORT_PREAMBLE)
278 		capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
279 #endif /* EXT_CODE_CROP */
280 #ifdef CONFIG_WEP
281 	privacy = hapd->conf->ssid.wep.keys_set;
282 
283 	if (hapd->conf->ieee802_1x &&
284 	    (hapd->conf->default_wep_key_len ||
285 	     hapd->conf->individual_wep_key_len))
286 		privacy = 1;
287 #endif /* CONFIG_WEP */
288 
289 	if (hapd->conf->wpa)
290 		privacy = 1;
291 
292 #ifdef CONFIG_HS20
293 	if (hapd->conf->osen)
294 		privacy = 1;
295 #endif /* CONFIG_HS20 */
296 
297 	if (privacy)
298 		capab |= WLAN_CAPABILITY_PRIVACY;
299 
300 #ifndef EXT_CODE_CROP
301 	if (hapd->iface->current_mode &&
302 	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
303 	    hapd->iface->num_sta_no_short_slot_time == 0)
304 		capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
305 
306 	/*
307 	 * Currently, Spectrum Management capability bit is set when directly
308 	 * requested in configuration by spectrum_mgmt_required or when AP is
309 	 * running on DFS channel.
310 	 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
311 	 */
312 	if (hapd->iface->current_mode &&
313 	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
314 	    (hapd->iconf->spectrum_mgmt_required || dfs))
315 		capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
316 
317 	for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
318 		if (hapd->conf->radio_measurements[i]) {
319 			capab |= IEEE80211_CAP_RRM;
320 			break;
321 		}
322 	}
323 #endif /* EXT_CODE_CROP */
324 
325 	return capab;
326 }
327 
328 #if (defined(LOS_CONFIG_HOSTAPD_MGMT) && defined(CONFIG_SAE))
329 #ifdef CONFIG_WEP
330 #ifndef CONFIG_NO_RC4
auth_shared_key(struct hostapd_data * hapd,struct sta_info * sta,u16 auth_transaction,const u8 * challenge,int iswep)331 static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
332 			   u16 auth_transaction, const u8 *challenge,
333 			   int iswep)
334 {
335 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
336 		       HOSTAPD_LEVEL_DEBUG,
337 		       "authentication (shared key, transaction %d)",
338 		       auth_transaction);
339 
340 	if (auth_transaction == 1) {
341 		if (!sta->challenge) {
342 			/* Generate a pseudo-random challenge */
343 			u8 key[8];
344 
345 			sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
346 			if (sta->challenge == NULL)
347 				return WLAN_STATUS_UNSPECIFIED_FAILURE;
348 
349 			if (os_get_random(key, sizeof(key)) < 0) {
350 				os_free(sta->challenge);
351 				sta->challenge = NULL;
352 				return WLAN_STATUS_UNSPECIFIED_FAILURE;
353 			}
354 
355 			rc4_skip(key, sizeof(key), 0,
356 				 sta->challenge, WLAN_AUTH_CHALLENGE_LEN);
357 		}
358 		return 0;
359 	}
360 
361 	if (auth_transaction != 3)
362 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
363 
364 	/* Transaction 3 */
365 	if (!iswep || !sta->challenge || !challenge ||
366 	    os_memcmp_const(sta->challenge, challenge,
367 			    WLAN_AUTH_CHALLENGE_LEN)) {
368 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
369 			       HOSTAPD_LEVEL_INFO,
370 			       "shared key authentication - invalid "
371 			       "challenge-response");
372 		return WLAN_STATUS_CHALLENGE_FAIL;
373 	}
374 
375 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
376 		       HOSTAPD_LEVEL_DEBUG,
377 		       "authentication OK (shared key)");
378 	sta->flags |= WLAN_STA_AUTH;
379 	wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
380 	os_free(sta->challenge);
381 	sta->challenge = NULL;
382 
383 	return 0;
384 }
385 #endif /* CONFIG_NO_RC4 */
386 #endif /* CONFIG_WEP */
387 
388 
send_auth_reply(struct hostapd_data * hapd,struct sta_info * sta,const u8 * dst,const u8 * bssid,u16 auth_alg,u16 auth_transaction,u16 resp,const u8 * ies,size_t ies_len,const char * dbg)389 static int send_auth_reply(struct hostapd_data *hapd, struct sta_info *sta,
390 			   const u8 *dst, const u8 *bssid,
391 			   u16 auth_alg, u16 auth_transaction, u16 resp,
392 			   const u8 *ies, size_t ies_len, const char *dbg)
393 {
394 	struct ieee80211_mgmt *reply;
395 	u8 *buf;
396 	size_t rlen;
397 	int reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
398 
399 	rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
400 	buf = os_zalloc(rlen);
401 	if (buf == NULL)
402 		return -1;
403 
404 	reply = (struct ieee80211_mgmt *) buf;
405 	reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
406 					    WLAN_FC_STYPE_AUTH);
407 	os_memcpy(reply->da, dst, ETH_ALEN);
408 	os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
409 	os_memcpy(reply->bssid, bssid, ETH_ALEN);
410 
411 	reply->u.auth.auth_alg = host_to_le16(auth_alg);
412 	reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
413 	reply->u.auth.status_code = host_to_le16(resp);
414 
415 	if (ies && ies_len)
416 		os_memcpy(reply->u.auth.variable, ies, ies_len);
417 
418 	wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
419 		   " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu) (dbg=%s)",
420 		   MAC2STR(dst), auth_alg, auth_transaction,
421 		   resp, (unsigned long) ies_len, dbg);
422 #ifdef CONFIG_TESTING_OPTIONS
423 #ifdef CONFIG_SAE
424 	if (hapd->conf->sae_confirm_immediate == 2 &&
425 	    auth_alg == WLAN_AUTH_SAE) {
426 		if (auth_transaction == 1 && sta &&
427 		    (resp == WLAN_STATUS_SUCCESS ||
428 		     resp == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
429 		     resp == WLAN_STATUS_SAE_PK)) {
430 			wpa_printf(MSG_DEBUG,
431 				   "TESTING: Postpone SAE Commit transmission until Confirm is ready");
432 			os_free(sta->sae_postponed_commit);
433 			sta->sae_postponed_commit = buf;
434 			sta->sae_postponed_commit_len = rlen;
435 			return WLAN_STATUS_SUCCESS;
436 		}
437 
438 		if (auth_transaction == 2 && sta && sta->sae_postponed_commit) {
439 			wpa_printf(MSG_DEBUG,
440 				   "TESTING: Send postponed SAE Commit first, immediately followed by SAE Confirm");
441 			if (hostapd_drv_send_mlme(hapd,
442 						  sta->sae_postponed_commit,
443 						  sta->sae_postponed_commit_len,
444 						  0, NULL, 0, 0) < 0)
445 				wpa_printf(MSG_INFO, "send_auth_reply: send failed");
446 			os_free(sta->sae_postponed_commit);
447 			sta->sae_postponed_commit = NULL;
448 			sta->sae_postponed_commit_len = 0;
449 		}
450 	}
451 #endif /* CONFIG_SAE */
452 #endif /* CONFIG_TESTING_OPTIONS */
453 	if (hostapd_drv_send_mlme(hapd, reply, rlen, 0, NULL, 0, 0) < 0)
454 		wpa_printf(MSG_INFO, "send_auth_reply: send failed");
455 	else
456 		reply_res = WLAN_STATUS_SUCCESS;
457 
458 	os_free(buf);
459 
460 	return reply_res;
461 }
462 #endif /* LOS_CONFIG_HOSTAPD_MGMT && CONFIG_SAE */
463 
464 #ifdef CONFIG_IEEE80211R_AP
handle_auth_ft_finish(void * ctx,const u8 * dst,const u8 * bssid,u16 auth_transaction,u16 status,const u8 * ies,size_t ies_len)465 static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
466 				  u16 auth_transaction, u16 status,
467 				  const u8 *ies, size_t ies_len)
468 {
469 	struct hostapd_data *hapd = ctx;
470 	struct sta_info *sta;
471 	int reply_res;
472 
473 	reply_res = send_auth_reply(hapd, NULL, dst, bssid, WLAN_AUTH_FT,
474 				    auth_transaction, status, ies, ies_len,
475 				    "auth-ft-finish");
476 
477 	sta = ap_get_sta(hapd, dst);
478 	if (sta == NULL)
479 		return;
480 
481 	if (sta->added_unassoc && (reply_res != WLAN_STATUS_SUCCESS ||
482 				   status != WLAN_STATUS_SUCCESS)) {
483 		hostapd_drv_sta_remove(hapd, sta->addr);
484 		sta->added_unassoc = 0;
485 		return;
486 	}
487 
488 	if (status != WLAN_STATUS_SUCCESS)
489 		return;
490 
491 	hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
492 		       HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
493 	sta->flags |= WLAN_STA_AUTH;
494 	mlme_authenticate_indication(hapd, sta);
495 }
496 #endif /* CONFIG_IEEE80211R_AP */
497 
498 
499 #if (defined(LOS_CONFIG_HOSTAPD_MGMT) && defined(CONFIG_SAE))
500 #ifdef CONFIG_SAE
501 #ifndef CONFIG_SAE_CROP
sae_set_state(struct sta_info * sta,enum sae_state state,const char * reason)502 static void sae_set_state(struct sta_info *sta, enum sae_state state,
503 			  const char *reason)
504 {
505 	wpa_printf(MSG_DEBUG, "SAE: State %s -> %s for peer " MACSTR " (%s)",
506 		   sae_state_txt(sta->sae->state), sae_state_txt(state),
507 		   MAC2STR(sta->addr), reason);
508 	sta->sae->state = state;
509 }
510 #endif
511 
sae_get_password(struct hostapd_data * hapd,struct sta_info * sta,const char * rx_id,struct sae_password_entry ** pw_entry,struct sae_pt ** s_pt,const struct sae_pk ** s_pk)512 static const char * sae_get_password(struct hostapd_data *hapd,
513 				     struct sta_info *sta,
514 				     const char *rx_id,
515 				     struct sae_password_entry **pw_entry,
516 				     struct sae_pt **s_pt,
517 				     const struct sae_pk **s_pk)
518 {
519 	const char *password = NULL;
520 	struct sae_password_entry *pw;
521 	struct sae_pt *pt = NULL;
522 	const struct sae_pk *pk = NULL;
523 
524 	for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) {
525 		if (!is_broadcast_ether_addr(pw->peer_addr) &&
526 		    os_memcmp(pw->peer_addr, sta->addr, ETH_ALEN) != 0)
527 			continue;
528 		if ((rx_id && !pw->identifier) || (!rx_id && pw->identifier))
529 			continue;
530 		if (rx_id && pw->identifier &&
531 		    os_strcmp(rx_id, pw->identifier) != 0)
532 			continue;
533 		password = pw->password;
534 		pt = pw->pt;
535 		if (!(hapd->conf->mesh & MESH_ENABLED))
536 			pk = pw->pk;
537 		break;
538 	}
539 	if (!password) {
540 		password = hapd->conf->ssid.wpa_passphrase;
541 		pt = hapd->conf->ssid.pt;
542 	}
543 
544 	if (pw_entry)
545 		*pw_entry = pw;
546 	if (s_pt)
547 		*s_pt = pt;
548 	if (s_pk)
549 		*s_pk = pk;
550 
551 	return password;
552 }
553 
554 
auth_build_sae_commit(struct hostapd_data * hapd,struct sta_info * sta,int update,int status_code)555 static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
556 					     struct sta_info *sta, int update,
557 					     int status_code)
558 {
559 	struct wpabuf *buf;
560 	const char *password = NULL;
561 #ifndef CONFIG_SAE_NO_PW_ID
562 	struct sae_password_entry *pw;
563 	const char *rx_id = NULL;
564 	int use_pt = 0;
565 	struct sae_pt *pt = NULL;
566 	const struct sae_pk *pk = NULL;
567 
568 	if (sta->sae->tmp) {
569 		rx_id = sta->sae->tmp->pw_id;
570 		use_pt = sta->sae->h2e;
571 #ifdef CONFIG_SAE_PK
572 		os_memcpy(sta->sae->tmp->own_addr, hapd->own_addr, ETH_ALEN);
573 		os_memcpy(sta->sae->tmp->peer_addr, sta->addr, ETH_ALEN);
574 #endif /* CONFIG_SAE_PK */
575 	}
576 
577 	if (rx_id && hapd->conf->sae_pwe != 3)
578 		use_pt = 1;
579 	else if (status_code == WLAN_STATUS_SUCCESS)
580 		use_pt = 0;
581 	else if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
582 		 status_code == WLAN_STATUS_SAE_PK)
583 		use_pt = 1;
584 
585 	password = sae_get_password(hapd, sta, rx_id, &pw, &pt, &pk);
586 	if (!password || (use_pt && !pt)) {
587 		wpa_printf(MSG_DEBUG, "SAE: No password available");
588 		return NULL;
589 	}
590 
591 	if (update && use_pt &&
592 	    sae_prepare_commit_pt(sta->sae, pt, hapd->own_addr, sta->addr,
593 				  NULL, pk) < 0)
594 		return NULL;
595 
596 	if (update && !use_pt &&
597 	    sae_prepare_commit(hapd->own_addr, sta->addr,
598 			       (u8 *) password, os_strlen(password),
599 			       sta->sae) < 0) {
600 		wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
601 		return NULL;
602 	}
603 #ifndef LOS_CONFIG_NO_VLAN
604 	if (pw && pw->vlan_id) {
605 		if (!sta->sae->tmp) {
606 			wpa_printf(MSG_INFO,
607 				   "SAE: No temporary data allocated - cannot store VLAN ID");
608 			return NULL;
609 		}
610 		sta->sae->tmp->vlan_id = pw->vlan_id;
611 	}
612 #endif
613 	buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN +
614 			   (rx_id ? 3 + os_strlen(rx_id) : 0));
615 	if (buf &&
616 	    sae_write_commit(sta->sae, buf, sta->sae->tmp ?
617 			     sta->sae->tmp->anti_clogging_token : NULL,
618 			     rx_id) < 0) {
619 		wpabuf_free(buf);
620 		buf = NULL;
621 	}
622 #else
623 	password = hapd->conf->ssid.wpa_passphrase;
624 	if (update &&
625 	    sae_prepare_commit(hapd->own_addr, sta->addr,
626 			       (u8 *) password, os_strlen(password),
627 			       sta->sae) < 0) {
628 		wpa_warning_log0(MSG_DEBUG, "SAE: Could not pick PWE");
629 		return NULL;
630 	}
631 	buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN);
632 	if (buf == NULL)
633 		return NULL;
634 	sae_write_commit(sta->sae, buf, sta->sae->tmp ?
635 			 sta->sae->tmp->anti_clogging_token : NULL, NULL);
636 #endif
637 	return buf;
638 }
639 
640 
auth_build_sae_confirm(struct hostapd_data * hapd,struct sta_info * sta)641 static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
642 					      struct sta_info *sta)
643 {
644 	struct wpabuf *buf;
645 
646 	buf = wpabuf_alloc(SAE_CONFIRM_MAX_LEN);
647 	if (buf == NULL)
648 		return NULL;
649 
650 #ifdef CONFIG_SAE_PK
651 #ifdef CONFIG_TESTING_OPTIONS
652 	if (sta->sae->tmp)
653 		sta->sae->tmp->omit_pk_elem = hapd->conf->sae_pk_omit;
654 #endif /* CONFIG_TESTING_OPTIONS */
655 #endif /* CONFIG_SAE_PK */
656 
657 	if (sae_write_confirm(sta->sae, buf) < 0) {
658 		wpabuf_free(buf);
659 		return NULL;
660 	}
661 
662 	return buf;
663 }
664 
665 
auth_sae_send_commit(struct hostapd_data * hapd,struct sta_info * sta,const u8 * bssid,int update,int status_code)666 static int auth_sae_send_commit(struct hostapd_data *hapd,
667 				struct sta_info *sta,
668 				const u8 *bssid, int update, int status_code)
669 {
670 	struct wpabuf *data;
671 	int reply_res;
672 	u16 status;
673 
674 	data = auth_build_sae_commit(hapd, sta, update, status_code);
675 #ifndef CONFIG_SAE_NO_PW_ID
676 	if (!data && sta->sae->tmp && sta->sae->tmp->pw_id)
677 		return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER;
678 #endif
679 	if (data == NULL)
680 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
681 
682 	if (sta->sae->tmp && sta->sae->pk)
683 		status = WLAN_STATUS_SAE_PK;
684 	else if (sta->sae->tmp && sta->sae->h2e)
685 		status = WLAN_STATUS_SAE_HASH_TO_ELEMENT;
686 	else
687 		status = WLAN_STATUS_SUCCESS;
688 #ifdef CONFIG_TESTING_OPTIONS
689 	if (hapd->conf->sae_commit_status >= 0 &&
690 	    hapd->conf->sae_commit_status != status) {
691 		wpa_printf(MSG_INFO,
692 			   "TESTING: Override SAE commit status code %u --> %d",
693 			   status, hapd->conf->sae_commit_status);
694 		status = hapd->conf->sae_commit_status;
695 	}
696 #endif /* CONFIG_TESTING_OPTIONS */
697 	reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
698 				    WLAN_AUTH_SAE, 1,
699 				    status, wpabuf_head(data),
700 				    wpabuf_len(data), "sae-send-commit");
701 
702 	wpabuf_free(data);
703 
704 	return reply_res;
705 }
706 
707 
auth_sae_send_confirm(struct hostapd_data * hapd,struct sta_info * sta,const u8 * bssid)708 static int auth_sae_send_confirm(struct hostapd_data *hapd,
709 				 struct sta_info *sta,
710 				 const u8 *bssid)
711 {
712 	struct wpabuf *data;
713 	int reply_res;
714 
715 	data = auth_build_sae_confirm(hapd, sta);
716 	if (data == NULL)
717 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
718 
719 	reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
720 				    WLAN_AUTH_SAE, 2,
721 				    WLAN_STATUS_SUCCESS, wpabuf_head(data),
722 				    wpabuf_len(data), "sae-send-confirm");
723 
724 	wpabuf_free(data);
725 
726 	return reply_res;
727 }
728 
729 #endif /* CONFIG_SAE */
730 
731 
732 #if defined(CONFIG_SAE) || defined(CONFIG_PASN)
733 
use_anti_clogging(struct hostapd_data * hapd)734 static int use_anti_clogging(struct hostapd_data *hapd)
735 {
736 	struct sta_info *sta;
737 	unsigned int open = 0;
738 
739 #ifndef CONFIG_SAE_CROP
740 	if (hapd->conf->anti_clogging_threshold == 0)
741 		return 1;
742 #endif
743 	for (sta = hapd->sta_list; sta; sta = sta->next) {
744 #ifdef CONFIG_SAE
745 		if (sta->sae &&
746 		    (sta->sae->state == SAE_COMMITTED ||
747 		     sta->sae->state == SAE_CONFIRMED))
748 			open++;
749 #endif /* CONFIG_SAE */
750 #ifdef CONFIG_PASN
751 		if (sta->pasn && sta->pasn->ecdh)
752 			open++;
753 #endif /* CONFIG_PASN */
754 		if (open >= hapd->conf->anti_clogging_threshold)
755 			return 1;
756 	}
757 
758 #ifdef CONFIG_SAE
759 	/* In addition to already existing open SAE sessions, check whether
760 	 * there are enough pending commit messages in the processing queue to
761 	 * potentially result in too many open sessions. */
762 	if (open + dl_list_len(&hapd->sae_commit_queue) >=
763 	    hapd->conf->anti_clogging_threshold)
764 		return 1;
765 #endif /* CONFIG_SAE */
766 
767 	return 0;
768 }
769 
770 
comeback_token_hash(struct hostapd_data * hapd,const u8 * addr,u8 * idx)771 static int comeback_token_hash(struct hostapd_data *hapd, const u8 *addr,
772 			       u8 *idx)
773 {
774 	u8 hash[SHA256_MAC_LEN];
775 
776 	if (hmac_sha256(hapd->comeback_key, sizeof(hapd->comeback_key),
777 			addr, ETH_ALEN, hash) < 0)
778 		return -1;
779 	*idx = hash[0];
780 	return 0;
781 }
782 
783 
check_comeback_token(struct hostapd_data * hapd,const u8 * addr,const u8 * token,size_t token_len)784 static int check_comeback_token(struct hostapd_data *hapd, const u8 *addr,
785 				const u8 *token, size_t token_len)
786 {
787 	u8 mac[SHA256_MAC_LEN];
788 	const u8 *addrs[2];
789 	size_t len[2];
790 	u16 token_idx;
791 	u8 idx;
792 
793 	if (token_len != SHA256_MAC_LEN ||
794 	    comeback_token_hash(hapd, addr, &idx) < 0)
795 		return -1;
796 	token_idx = hapd->comeback_pending_idx[idx];
797 	if (token_idx == 0 || token_idx != WPA_GET_BE16(token)) {
798 		wpa_printf(MSG_DEBUG,
799 			   "Comeback: Invalid anti-clogging token from "
800 			   MACSTR " - token_idx 0x%04x, expected 0x%04x",
801 			   MAC2STR(addr), WPA_GET_BE16(token), token_idx);
802 		return -1;
803 	}
804 
805 	addrs[0] = addr;
806 	len[0] = ETH_ALEN;
807 	addrs[1] = token;
808 	len[1] = 2;
809 	if (hmac_sha256_vector(hapd->comeback_key, sizeof(hapd->comeback_key),
810 			       2, addrs, len, mac) < 0 ||
811 	    os_memcmp_const(token + 2, &mac[2], SHA256_MAC_LEN - 2) != 0)
812 		return -1;
813 
814 	hapd->comeback_pending_idx[idx] = 0; /* invalidate used token */
815 
816 	return 0;
817 }
818 
819 
auth_build_token_req(struct hostapd_data * hapd,int group,const u8 * addr,int h2e)820 static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
821 					    int group, const u8 *addr, int h2e)
822 {
823 	struct wpabuf *buf;
824 	u8 *token;
825 	struct os_reltime now;
826 	u8 idx[2];
827 	const u8 *addrs[2];
828 	size_t len[2];
829 	u8 p_idx;
830 	u16 token_idx;
831 
832 	os_get_reltime(&now);
833 	if (!os_reltime_initialized(&hapd->last_comeback_key_update) ||
834 	    os_reltime_expired(&now, &hapd->last_comeback_key_update, 60) ||
835 	    hapd->comeback_idx == 0xffff) {
836 		if (random_get_bytes(hapd->comeback_key,
837 				     sizeof(hapd->comeback_key)) < 0)
838 			return NULL;
839 		wpa_hexdump(MSG_DEBUG, "Comeback: Updated token key",
840 			    hapd->comeback_key, sizeof(hapd->comeback_key));
841 		hapd->last_comeback_key_update = now;
842 		hapd->comeback_idx = 0;
843 		os_memset(hapd->comeback_pending_idx, 0,
844 			  sizeof(hapd->comeback_pending_idx));
845 	}
846 
847 	buf = wpabuf_alloc(sizeof(le16) + 3 + SHA256_MAC_LEN);
848 	if (buf == NULL)
849 		return NULL;
850 
851 	if (group)
852 		wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
853 
854 	if (h2e) {
855 		/* Encapsulate Anti-clogging Token field in a container IE */
856 		wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
857 		wpabuf_put_u8(buf, 1 + SHA256_MAC_LEN);
858 		wpabuf_put_u8(buf, WLAN_EID_EXT_ANTI_CLOGGING_TOKEN);
859 	}
860 
861 	if (comeback_token_hash(hapd, addr, &p_idx) < 0) {
862 		wpabuf_free(buf);
863 		return NULL;
864 	}
865 
866 	token_idx = hapd->comeback_pending_idx[p_idx];
867 	if (!token_idx) {
868 		hapd->comeback_idx++;
869 		token_idx = hapd->comeback_idx;
870 		hapd->comeback_pending_idx[p_idx] = token_idx;
871 	}
872 	WPA_PUT_BE16(idx, token_idx);
873 	token = wpabuf_put(buf, SHA256_MAC_LEN);
874 	addrs[0] = addr;
875 	len[0] = ETH_ALEN;
876 	addrs[1] = idx;
877 	len[1] = sizeof(idx);
878 	if (hmac_sha256_vector(hapd->comeback_key, sizeof(hapd->comeback_key),
879 			       2, addrs, len, token) < 0) {
880 		wpabuf_free(buf);
881 		return NULL;
882 	}
883 	WPA_PUT_BE16(token, token_idx);
884 
885 	return buf;
886 }
887 
888 #endif /* defined(CONFIG_SAE) || defined(CONFIG_PASN) */
889 
890 
891 #ifdef CONFIG_SAE
892 
sae_check_big_sync(struct hostapd_data * hapd,struct sta_info * sta)893 static int sae_check_big_sync(struct hostapd_data *hapd, struct sta_info *sta)
894 {
895 #ifndef CONFIG_SAE_CROP
896 	if (sta->sae->sync > hapd->conf->sae_sync) {
897 #else
898 	if (sta->sae->sync > 1) { /* 2: default sae_sync */
899 #endif
900 		wpa_warning_log2(MSG_DEBUG, "Sync (%d) > dot11RSNASAESync(%d)", sta->sae->sync, hapd->conf->sae_sync);
901 #ifndef CONFIG_SAE_CROP
902 		sae_set_state(sta, SAE_NOTHING, "Sync > dot11RSNASAESync");
903 #else
904 		sta->sae->state = SAE_NOTHING;
905 #endif
906 		sta->sae->sync = 0;
907 		return -1;
908 	}
909 	return 0;
910 }
911 
912 
913 static void auth_sae_retransmit_timer(void *eloop_ctx, void *eloop_data)
914 {
915 	struct hostapd_data *hapd = eloop_ctx;
916 	struct sta_info *sta = eloop_data;
917 	int ret;
918 
919 	if (sae_check_big_sync(hapd, sta))
920 		return;
921 	sta->sae->sync++;
922 #ifndef CONFIG_SAE_CROP
923 	wpa_warning_log4(MSG_DEBUG, "SAE: Auth SAE retransmit timer for " "%02x:xx:xx:%02x:%02x:%02x",
924 		   (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
925 	wpa_warning_log1(MSG_DEBUG, "SAE: Auth SAE retransmit timer for "
926 		   " (sync=%d)", sta->sae->sync);
927 	wpa_warning_buf(MSG_DEBUG, "SAE: Auth SAE retransmit timer for "
928 		   " (state=%s)",
929 		   sae_state_txt(sta->sae->state), strlen(sae_state_txt(sta->sae->state)));
930 #endif
931 	switch (sta->sae->state) {
932 	case SAE_COMMITTED:
933 		ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0, -1);
934 		eloop_register_timeout(0,
935 				       hapd->dot11RSNASAERetransPeriod * 1000,
936 				       auth_sae_retransmit_timer, hapd, sta);
937 		break;
938 	case SAE_CONFIRMED:
939 		ret = auth_sae_send_confirm(hapd, sta, hapd->own_addr);
940 		eloop_register_timeout(0,
941 				       hapd->dot11RSNASAERetransPeriod * 1000,
942 				       auth_sae_retransmit_timer, hapd, sta);
943 		break;
944 	default:
945 		ret = -1;
946 		break;
947 	}
948 
949 	if (ret != WLAN_STATUS_SUCCESS)
950 		wpa_warning_log1(MSG_INFO, "SAE: Failed to retransmit: ret=%d", ret);
951 }
952 
953 
954 void sae_clear_retransmit_timer(struct hostapd_data *hapd, struct sta_info *sta)
955 {
956 	eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
957 }
958 
959 
960 static void sae_set_retransmit_timer(struct hostapd_data *hapd,
961 				     struct sta_info *sta)
962 {
963 	if (!(hapd->conf->mesh & MESH_ENABLED))
964 		return;
965 
966 	eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
967 	eloop_register_timeout(0, hapd->dot11RSNASAERetransPeriod * 1000,
968 			       auth_sae_retransmit_timer, hapd, sta);
969 }
970 
971 #ifdef CONFIG_HOSTAPD_WPA3
972 #ifdef CONFIG_SAE
973 static void sae_sme_send_external_auth_status(struct hostapd_data *hapd,
974 					      struct sta_info *sta, u16 status)
975 {
976 	struct external_auth params;
977 
978 	os_memset(&params, 0, sizeof(params));
979 	params.status = status;
980 	params.bssid = sta->addr;
981 	if (status == WLAN_STATUS_SUCCESS && sta->sae &&
982 	    !hapd->conf->disable_pmksa_caching)
983 		params.pmkid = sta->sae->pmkid;
984 
985 	hostapd_drv_send_external_auth_status(hapd, &params);
986 }
987 #endif /* CONFIG_SAE */
988 #endif /* CONFIG_HOSTAPD_WPA3 */
989 
990 void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
991 {
992 #ifndef CONFIG_NO_VLAN
993 	struct vlan_description vlan_desc;
994 
995 	if (sta->sae->tmp && sta->sae->tmp->vlan_id > 0) {
996 		wpa_warning_log1(MSG_DEBUG, "SAE: Assign STA to VLAN ID %d",
997 			   sta->sae->tmp->vlan_id);
998 		wpa_warning_log4(MSG_DEBUG, "mac %02x:xx:xx:%02x:%02x:%02x",
999 				(sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]));
1000 		os_memset(&vlan_desc, 0, sizeof(vlan_desc));
1001 		vlan_desc.notempty = 1;
1002 		vlan_desc.untagged = sta->sae->tmp->vlan_id;
1003 		if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) {
1004 			wpa_warning_log1(MSG_INFO,
1005 				   "Invalid VLAN ID %d in sae_password",
1006 				   sta->sae->tmp->vlan_id);
1007 			wpa_warning_log4(MSG_DEBUG, "mac %02x:xx:xx:%02x:%02x:%02x",
1008 					(sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]));
1009 			return;
1010 		}
1011 
1012 		if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0 ||
1013 		    ap_sta_bind_vlan(hapd, sta) < 0) {
1014 			wpa_warning_log1(MSG_INFO,
1015 				   "Failed to assign VLAN ID %d from sae_password to "
1016 				   sta->sae->tmp->vlan_id);
1017 			return;
1018 		}
1019 	}
1020 #endif /* CONFIG_NO_VLAN */
1021 
1022 	sta->flags |= WLAN_STA_AUTH;
1023 	sta->auth_alg = WLAN_AUTH_SAE;
1024 	mlme_authenticate_indication(hapd, sta);
1025 	wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
1026 #ifndef CONFIG_SAE_CROP
1027 	sae_set_state(sta, SAE_ACCEPTED, "Accept Confirm");
1028 #else
1029 	sta->sae->state = SAE_ACCEPTED;
1030 #endif
1031 	crypto_bignum_deinit(sta->sae->peer_commit_scalar_accepted, 0);
1032 #ifndef LOS_CONFIG_HOSTAPD_PMKSA_CROP
1033 #ifdef LOS_CONFIG_MESH
1034 	if (hapd->conf->mesh & MESH_ENABLED)
1035 		wpa_auth_pmksa_add_sae(hapd->wpa_mesh_auth, sta->addr, sta->sae->pmk, sta->sae->pmkid);
1036 #endif /* LOS_CONFIG_MESH */
1037 #endif /* LOS_CONFIG_HOSTAPD_PMKSA_CROP */
1038 	sta->sae->peer_commit_scalar_accepted = sta->sae->peer_commit_scalar;
1039 	sta->sae->peer_commit_scalar = NULL;
1040 #if defined(CONFIG_HOSTAPD_WPA3) && defined(CONFIG_HOSTAPD_WPA3_PMKSA)
1041 	wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
1042 			       sta->sae->pmk, sta->sae->pmkid);
1043 #endif /* CONFIG_HOSTAPD_WPA3 && CONFIG_HOSTAPD_WPA3_PMKSA */
1044 	sae_sme_send_external_auth_status(hapd, sta, WLAN_STATUS_SUCCESS);
1045 }
1046 
1047 
1048 static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
1049 		       const u8 *bssid, u16 auth_transaction, u16 status_code,
1050 		       int allow_reuse, int *sta_removed)
1051 {
1052 	int ret;
1053 
1054 	*sta_removed = 0;
1055 
1056 	if (auth_transaction != 1 && auth_transaction != 2)
1057 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1058 #ifndef CONFIG_SAE_CROP
1059 	wpa_warning_log4(MSG_DEBUG, "SAE: Peer " "%02x:xx:xx:%02x:%02x:%02x",
1060 		   (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
1061 	wpa_warning_buf(MSG_DEBUG, "SAE: Peer " " state=%s",
1062 		   sae_state_txt(sta->sae->state), strlen(sae_state_txt(sta->sae->state)));
1063 	wpa_warning_log1(MSG_DEBUG, "SAE: Peer " " auth_trans=%u", auth_transaction);
1064 #endif
1065 	switch (sta->sae->state) {
1066 	case SAE_NOTHING:
1067 		if (auth_transaction == 1) {
1068 			if (sta->sae->tmp) {
1069 				sta->sae->h2e =
1070 					(status_code ==
1071 					 WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1072 					 status_code == WLAN_STATUS_SAE_PK);
1073 				sta->sae->pk =
1074 					status_code == WLAN_STATUS_SAE_PK;
1075 			}
1076 			ret = auth_sae_send_commit(hapd, sta, bssid,
1077 						   !allow_reuse, status_code);
1078 			if (ret)
1079 				return ret;
1080 #ifndef CONFIG_SAE_CROP
1081 			sae_set_state(sta, SAE_COMMITTED, "Sent Commit");
1082 #else
1083 			sta->sae->state = SAE_COMMITTED;
1084 #endif
1085 			if (sae_process_commit(sta->sae) < 0)
1086 				return WLAN_STATUS_UNSPECIFIED_FAILURE;
1087 
1088 			/*
1089 			 * In mesh case, both Commit and Confirm are sent
1090 			 * immediately. In infrastructure BSS, by default, only
1091 			 * a single Authentication frame (Commit) is expected
1092 			 * from the AP here and the second one (Confirm) will
1093 			 * be sent once the STA has sent its second
1094 			 * Authentication frame (Confirm). This behavior can be
1095 			 * overridden with explicit configuration so that the
1096 			 * infrastructure BSS case sends both frames together.
1097 			 */
1098 			if ((hapd->conf->mesh & MESH_ENABLED) ||
1099 			    hapd->conf->sae_confirm_immediate) {
1100 				/*
1101 				 * Send both Commit and Confirm immediately
1102 				 * based on SAE finite state machine
1103 				 * Nothing -> Confirm transition.
1104 				 */
1105 				ret = auth_sae_send_confirm(hapd, sta, bssid);
1106 				if (ret)
1107 					return ret;
1108 #ifndef CONFIG_SAE_CROP
1109 				sae_set_state(sta, SAE_CONFIRMED,
1110 					      "Sent Confirm (mesh)");
1111 #else
1112 				sta->sae->state = SAE_CONFIRMED;
1113 #endif
1114 			} else {
1115 				/*
1116 				 * For infrastructure BSS, send only the Commit
1117 				 * message now to get alternating sequence of
1118 				 * Authentication frames between the AP and STA.
1119 				 * Confirm will be sent in
1120 				 * Committed -> Confirmed/Accepted transition
1121 				 * when receiving Confirm from STA.
1122 				 */
1123 			}
1124 			sta->sae->sync = 0;
1125 			sae_set_retransmit_timer(hapd, sta);
1126 		} else {
1127 			hostapd_logger(hapd, sta->addr,
1128 				       HOSTAPD_MODULE_IEEE80211,
1129 				       HOSTAPD_LEVEL_DEBUG,
1130 				       "SAE confirm before commit");
1131 		}
1132 		break;
1133 	case SAE_COMMITTED:
1134 		sae_clear_retransmit_timer(hapd, sta);
1135 		if (auth_transaction == 1) {
1136 			if (sae_process_commit(sta->sae) < 0)
1137 				return WLAN_STATUS_UNSPECIFIED_FAILURE;
1138 
1139 			ret = auth_sae_send_confirm(hapd, sta, bssid);
1140 			if (ret)
1141 				return ret;
1142 #ifndef CONFIG_SAE_CROP
1143 			sae_set_state(sta, SAE_CONFIRMED, "Sent Confirm");
1144 #else
1145 			sta->sae->state = SAE_CONFIRMED;
1146 #endif
1147 			sta->sae->sync = 0;
1148 			sae_set_retransmit_timer(hapd, sta);
1149 		} else if (hapd->conf->mesh & MESH_ENABLED) {
1150 			/*
1151 			 * In mesh case, follow SAE finite state machine and
1152 			 * send Commit now, if sync count allows.
1153 			 */
1154 			if (sae_check_big_sync(hapd, sta))
1155 				return WLAN_STATUS_SUCCESS;
1156 			sta->sae->sync++;
1157 
1158 			ret = auth_sae_send_commit(hapd, sta, bssid, 0,
1159 						   status_code);
1160 			if (ret)
1161 				return ret;
1162 
1163 			sae_set_retransmit_timer(hapd, sta);
1164 		} else {
1165 			/*
1166 			 * For instructure BSS, send the postponed Confirm from
1167 			 * Nothing -> Confirmed transition that was reduced to
1168 			 * Nothing -> Committed above.
1169 			 */
1170 			ret = auth_sae_send_confirm(hapd, sta, bssid);
1171 			if (ret)
1172 				return ret;
1173 #ifndef CONFIG_SAE_CROP
1174 			sae_set_state(sta, SAE_CONFIRMED, "Sent Confirm");
1175 #else
1176 			sta->sae->state = SAE_CONFIRMED;
1177 #endif
1178 			/*
1179 			 * Since this was triggered on Confirm RX, run another
1180 			 * step to get to Accepted without waiting for
1181 			 * additional events.
1182 			 */
1183 			return sae_sm_step(hapd, sta, bssid, auth_transaction,
1184 					   WLAN_STATUS_SUCCESS, 0, sta_removed);
1185 		}
1186 		break;
1187 	case SAE_CONFIRMED:
1188 		sae_clear_retransmit_timer(hapd, sta);
1189 		if (auth_transaction == 1) {
1190 			if (sae_check_big_sync(hapd, sta))
1191 				return WLAN_STATUS_SUCCESS;
1192 			sta->sae->sync++;
1193 
1194 			ret = auth_sae_send_commit(hapd, sta, bssid, 1,
1195 						   status_code);
1196 			if (ret)
1197 				return ret;
1198 
1199 			if (sae_process_commit(sta->sae) < 0)
1200 				return WLAN_STATUS_UNSPECIFIED_FAILURE;
1201 
1202 			ret = auth_sae_send_confirm(hapd, sta, bssid);
1203 			if (ret)
1204 				return ret;
1205 
1206 			sae_set_retransmit_timer(hapd, sta);
1207 		} else {
1208 			sta->sae->send_confirm = 0xffff;
1209 			sae_accept_sta(hapd, sta);
1210 		}
1211 		break;
1212 	case SAE_ACCEPTED:
1213 		if (auth_transaction == 1 &&
1214 		    (hapd->conf->mesh & MESH_ENABLED)) {
1215 			wpa_warning_log4(MSG_DEBUG, "SAE: remove the STA (" "%02x:xx:xx:%02x:%02x:%02x"
1216 				   ") doing reauthentication",
1217 				   (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
1218 
1219 #ifndef LOS_CONFIG_HOSTAPD_PMKSA_CROP
1220 			wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
1221 #endif /* LOS_CONFIG_HOSTAPD_PMKSA_CROP */
1222 			ap_free_sta(hapd, sta);
1223 #ifndef LOS_CONFIG_HOSTAPD_PMKSA_CROP
1224 			*sta_removed = 1;
1225 #endif /* LOS_CONFIG_HOSTAPD_PMKSA_CROP */
1226 		} else if (auth_transaction == 1) {
1227 			wpa_warning_log0(MSG_DEBUG, "SAE: Start reauthentication");
1228 			ret = auth_sae_send_commit(hapd, sta, bssid, 1,
1229 						   status_code);
1230 			if (ret)
1231 				return ret;
1232 #ifndef CONFIG_SAE_CROP
1233 			sae_set_state(sta, SAE_COMMITTED, "Sent Commit");
1234 #else
1235 			sta->sae->state = SAE_COMMITTED;
1236 #endif
1237 			if (sae_process_commit(sta->sae) < 0)
1238 				return WLAN_STATUS_UNSPECIFIED_FAILURE;
1239 			sta->sae->sync = 0;
1240 			sae_set_retransmit_timer(hapd, sta);
1241 		} else {
1242 			if (sae_check_big_sync(hapd, sta))
1243 				return WLAN_STATUS_SUCCESS;
1244 			sta->sae->sync++;
1245 
1246 			ret = auth_sae_send_confirm(hapd, sta, bssid);
1247 			sae_clear_temp_data(sta->sae);
1248 			if (ret)
1249 				return ret;
1250 		}
1251 		break;
1252 	default:
1253 		wpa_error_log1(MSG_ERROR, "SAE: invalid state %d",
1254 			   sta->sae->state);
1255 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1256 	}
1257 	return WLAN_STATUS_SUCCESS;
1258 }
1259 
1260 #ifndef CONFIG_SAE_ONE_ECC_CURVE
1261 static void sae_pick_next_group(struct hostapd_data *hapd, struct sta_info *sta)
1262 {
1263 	struct sae_data *sae = sta->sae;
1264 	int i, *groups = hapd->conf->sae_groups;
1265 	int default_groups[] = { 19, 0 };
1266 
1267 	if (sae->state != SAE_COMMITTED)
1268 		return;
1269 
1270 	wpa_warning_log1(MSG_DEBUG, "SAE: Previously selected group: %d", sae->group);
1271 
1272 	if (!groups)
1273 		groups = default_groups;
1274 	for (i = 0; groups[i] > 0; i++) {
1275 		if (sae->group == groups[i])
1276 			break;
1277 	}
1278 
1279 	if (groups[i] <= 0) {
1280 		wpa_warning_log0(MSG_DEBUG,
1281 			   "SAE: Previously selected group not found from the current configuration");
1282 		return;
1283 	}
1284 
1285 	for (;;) {
1286 		i++;
1287 		if (groups[i] <= 0) {
1288 			wpa_warning_log0(MSG_DEBUG,
1289 				   "SAE: No alternative group enabled");
1290 			return;
1291 		}
1292 
1293 		if (sae_set_group(sae, groups[i]) < 0)
1294 			continue;
1295 
1296 		break;
1297 	}
1298 	wpa_warning_log1(MSG_DEBUG, "SAE: Selected new group: %d", groups[i]);
1299 }
1300 #endif /* CONFIG_SAE_ONE_ECC_CURVE */
1301 
1302 static int sae_status_success(struct hostapd_data *hapd, u16 status_code)
1303 {
1304 	int sae_pwe = hapd->conf->sae_pwe;
1305 	int id_in_use;
1306 	bool sae_pk = false;
1307 
1308 	id_in_use = hostapd_sae_pw_id_in_use(hapd->conf);
1309 	if (id_in_use == 2 && sae_pwe != 3)
1310 		sae_pwe = 1;
1311 	else if (id_in_use == 1 && sae_pwe == 0)
1312 		sae_pwe = 2;
1313 #ifdef CONFIG_SAE_PK
1314 	sae_pk = hostapd_sae_pk_in_use(hapd->conf);
1315 	if (sae_pwe == 0 && sae_pk)
1316 		sae_pwe = 2;
1317 #endif /* CONFIG_SAE_PK */
1318 
1319 	return ((sae_pwe == 0 || sae_pwe == 3) &&
1320 		status_code == WLAN_STATUS_SUCCESS) ||
1321 		(sae_pwe == 1 &&
1322 		 (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1323 		  (sae_pk && status_code == WLAN_STATUS_SAE_PK))) ||
1324 		(sae_pwe == 2 &&
1325 		 (status_code == WLAN_STATUS_SUCCESS ||
1326 		  status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1327 		  (sae_pk && status_code == WLAN_STATUS_SAE_PK)));
1328 }
1329 
1330 
1331 static int sae_is_group_enabled(struct hostapd_data *hapd, int group)
1332 {
1333 	int *groups = hapd->conf->sae_groups;
1334 	int default_groups[] = { 19, 0 };
1335 	int i;
1336 
1337 	if (!groups)
1338 		groups = default_groups;
1339 
1340 	for (i = 0; groups[i] > 0; i++) {
1341 		if (groups[i] == group)
1342 			return 1;
1343 	}
1344 
1345 	return 0;
1346 }
1347 
1348 
1349 static int check_sae_rejected_groups(struct hostapd_data *hapd,
1350 				     struct sae_data *sae)
1351 {
1352 	const struct wpabuf *groups;
1353 	size_t i, count;
1354 	const u8 *pos;
1355 
1356 	if (!sae->tmp)
1357 		return 0;
1358 	groups = sae->tmp->peer_rejected_groups;
1359 	if (!groups)
1360 		return 0;
1361 
1362 	pos = wpabuf_head(groups);
1363 	count = wpabuf_len(groups) / 2;
1364 	for (i = 0; i < count; i++) {
1365 		int enabled;
1366 		u16 group;
1367 
1368 		group = WPA_GET_LE16(pos);
1369 		pos += 2;
1370 		enabled = sae_is_group_enabled(hapd, group);
1371 		wpa_printf(MSG_DEBUG, "SAE: Rejected group %u is %s",
1372 			   group, enabled ? "enabled" : "disabled");
1373 		if (enabled)
1374 			return 1;
1375 	}
1376 
1377 	return 0;
1378 }
1379 
1380 
1381 static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
1382 			    const struct ieee80211_mgmt *mgmt, size_t len,
1383 			    u16 auth_transaction, u16 status_code)
1384 {
1385 	int resp = WLAN_STATUS_SUCCESS;
1386 	struct wpabuf *data = NULL;
1387 	int *groups = hapd->conf->sae_groups;
1388 	int default_groups[] = { 19, 0 };
1389 	const u8 *pos, *end;
1390 	int sta_removed = 0;
1391 	bool success_status;
1392 #ifndef CONFIG_SAE_ONE_ECC_CURVE
1393 	if (!groups)
1394 #endif /* CONFIG_SAE_ONE_ECC_CURVE */
1395 		groups = default_groups;
1396 
1397 #ifdef CONFIG_TESTING_OPTIONS
1398 	if (hapd->conf->sae_reflection_attack && auth_transaction == 1) {
1399 		wpa_warning_log0(MSG_DEBUG, "SAE: TESTING - reflection attack");
1400 		pos = mgmt->u.auth.variable;
1401 		end = ((const u8 *) mgmt) + len;
1402 		resp = status_code;
1403 		send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
1404 				auth_transaction, resp, pos, end - pos,
1405 				"auth-sae-reflection-attack");
1406 		goto remove_sta;
1407 	}
1408 
1409 	if (hapd->conf->sae_commit_override && auth_transaction == 1) {
1410 		wpa_printf(MSG_DEBUG, "SAE: TESTING - commit override");
1411 		send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
1412 				auth_transaction, resp,
1413 				wpabuf_head(hapd->conf->sae_commit_override),
1414 				wpabuf_len(hapd->conf->sae_commit_override),
1415 				"sae-commit-override");
1416 		goto remove_sta;
1417 	}
1418 #endif /* CONFIG_TESTING_OPTIONS */
1419 	if (!sta->sae) {
1420 		if (auth_transaction != 1 ||
1421 		    !sae_status_success(hapd, status_code)) {
1422 			wpa_printf(MSG_DEBUG, "SAE: Unexpected Status Code %u",
1423 				   status_code);
1424 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1425 			goto reply;
1426 		}
1427 		sta->sae = os_zalloc(sizeof(*sta->sae));
1428 		if (!sta->sae) {
1429 			resp = -1;
1430 			goto remove_sta;
1431 		}
1432 #ifndef CONFIG_SAE_CROP
1433 		sae_set_state(sta, SAE_NOTHING, "Init");
1434 #else
1435 		sta->sae->state = SAE_NOTHING;
1436 #endif
1437 		sta->sae->sync = 0;
1438 	}
1439 
1440 #ifndef LOS_CONFIG_HOSTAPD_PMKSA_CROP
1441 	if (sta->mesh_sae_pmksa_caching) {
1442 		wpa_warning_log0(MSG_DEBUG,
1443 			   "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
1444 		wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
1445 		sta->mesh_sae_pmksa_caching = 0;
1446 	}
1447 #endif /* LOS_CONFIG_HOSTAPD_PMKSA_CROP */
1448 
1449 	if (auth_transaction == 1) {
1450 		const u8 *token = NULL;
1451 		size_t token_len = 0;
1452 		int allow_reuse = 0;
1453 
1454 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1455 			       HOSTAPD_LEVEL_DEBUG,
1456 			       "start SAE authentication (RX commit, status=%u (%s))",
1457 			       status_code, status2str(status_code));
1458 
1459 		if ((hapd->conf->mesh & MESH_ENABLED) &&
1460 		    status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
1461 		    sta->sae->tmp) {
1462 			pos = mgmt->u.auth.variable;
1463 			end = ((const u8 *) mgmt) + len;
1464 			if (pos + sizeof(le16) > end) {
1465 				wpa_error_log0(MSG_ERROR,
1466 					   "SAE: Too short anti-clogging token request");
1467 				resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1468 				goto reply;
1469 			}
1470 			resp = sae_group_allowed(sta->sae, groups,
1471 						 WPA_GET_LE16(pos));
1472 			if (resp != WLAN_STATUS_SUCCESS) {
1473 				wpa_error_log0(MSG_ERROR,
1474 					   "SAE: Invalid group in anti-clogging token request");
1475 				goto reply;
1476 			}
1477 			pos += sizeof(le16);
1478 
1479 			wpabuf_free(sta->sae->tmp->anti_clogging_token);
1480 			sta->sae->tmp->anti_clogging_token =
1481 				wpabuf_alloc_copy(pos, end - pos);
1482 			if (sta->sae->tmp->anti_clogging_token == NULL) {
1483 				wpa_error_log0(MSG_ERROR,
1484 					   "SAE: Failed to alloc for anti-clogging token");
1485 				resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1486 				goto remove_sta;
1487 			}
1488 
1489 			/*
1490 			 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
1491 			 * is 76, a new Commit Message shall be constructed
1492 			 * with the Anti-Clogging Token from the received
1493 			 * Authentication frame, and the commit-scalar and
1494 			 * COMMIT-ELEMENT previously sent.
1495 			 */
1496 			resp = auth_sae_send_commit(hapd, sta, mgmt->bssid, 0,
1497 						    status_code);
1498 			if (resp != WLAN_STATUS_SUCCESS) {
1499 				wpa_error_log0(MSG_ERROR,
1500 					   "SAE: Failed to send commit message");
1501 				goto remove_sta;
1502 			}
1503 #ifndef CONFIG_SAE_CROP
1504 			sae_set_state(sta, SAE_COMMITTED,
1505 				      "Sent Commit (anti-clogging token case in mesh)");
1506 #else
1507 			sta->sae->state = SAE_COMMITTED;
1508 #endif
1509 			sta->sae->sync = 0;
1510 			sae_set_retransmit_timer(hapd, sta);
1511 			return;
1512 		}
1513 
1514 		if ((hapd->conf->mesh & MESH_ENABLED) &&
1515 		    status_code ==
1516 		    WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
1517 		    sta->sae->tmp) {
1518 			wpa_warning_log0(MSG_DEBUG,
1519 				   "SAE: Peer did not accept our SAE group");
1520 #ifndef CONFIG_SAE_ONE_ECC_CURVE
1521 			sae_pick_next_group(hapd, sta);
1522 #endif
1523 			goto remove_sta;
1524 		}
1525 
1526 		if (!sae_status_success(hapd, status_code))
1527 			goto remove_sta;
1528 
1529 		if (!(hapd->conf->mesh & MESH_ENABLED) &&
1530 		    sta->sae->state == SAE_COMMITTED) {
1531 			/* This is needed in the infrastructure BSS case to
1532 			 * address a sequence where a STA entry may remain in
1533 			 * hostapd across two attempts to do SAE authentication
1534 			 * by the same STA. The second attempt may end up trying
1535 			 * to use a different group and that would not be
1536 			 * allowed if we remain in Committed state with the
1537 			 * previously set parameters. */
1538 			pos = mgmt->u.auth.variable;
1539 			end = ((const u8 *) mgmt) + len;
1540 			if (end - pos >= (int) sizeof(le16) &&
1541 			    sae_group_allowed(sta->sae, groups,
1542 					      WPA_GET_LE16(pos)) ==
1543 			    WLAN_STATUS_SUCCESS) {
1544 				/* Do not waste resources deriving the same PWE
1545 				 * again since the same group is reused. */
1546 #ifndef CONFIG_SAE_CROP
1547 				sae_set_state(sta, SAE_NOTHING,
1548 					      "Allow previous PWE to be reused");
1549 #else
1550 				sta->sae->state = SAE_NOTHING;
1551 #endif
1552 				allow_reuse = 1;
1553 			} else {
1554 #ifndef CONFIG_SAE_CROP
1555 				sae_set_state(sta, SAE_NOTHING,
1556 					      "Clear existing state to allow restart");
1557 #else
1558 				sta->sae->state = SAE_NOTHING;
1559 #endif
1560 				sae_clear_data(sta->sae);
1561 			}
1562 		}
1563 
1564 		resp = sae_parse_commit(sta->sae, mgmt->u.auth.variable,
1565 					((const u8 *) mgmt) + len -
1566 					mgmt->u.auth.variable, &token,
1567 					&token_len, groups, status_code ==
1568 					WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1569 					status_code == WLAN_STATUS_SAE_PK);
1570 		if (resp == SAE_SILENTLY_DISCARD) {
1571 			wpa_warning_log4(MSG_DEBUG,
1572 				   "SAE: Drop commit message from " "%02x:xx:xx:%02x:%02x:%02x" " due to reflection attack",
1573 				   (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
1574 			goto remove_sta;
1575 		}
1576 #ifndef CONFIG_SAE_NO_PW_ID
1577 		if (resp == WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER) {
1578 			wpa_msg(hapd->msg_ctx, MSG_INFO,
1579 				WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER
1580 				MACSTR, MAC2STR(sta->addr));
1581 			sae_clear_retransmit_timer(hapd, sta);
1582 #ifndef CONFIG_SAE_CROP
1583 			sae_set_state(sta, SAE_NOTHING,
1584 				      "Unknown Password Identifier");
1585 #else
1586 			sta->sae->state = SAE_NOTHING;
1587 #endif
1588 			goto remove_sta;
1589 		}
1590 #endif
1591 		if (token &&
1592 		    check_comeback_token(hapd, sta->addr, token, token_len)
1593 		    < 0) {
1594 			wpa_warning_log4(MSG_DEBUG, "SAE: Drop commit message with "
1595 				   "incorrect token from " "%02x:xx:xx:%02x:%02x:%02x",
1596 				   (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
1597 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1598 			goto remove_sta;
1599 		}
1600 
1601 		if (resp != WLAN_STATUS_SUCCESS)
1602 			goto reply;
1603 
1604 		if (check_sae_rejected_groups(hapd, sta->sae)) {
1605 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1606 			goto reply;
1607 		}
1608 
1609 		if (!token && use_anti_clogging(hapd) && !allow_reuse) {
1610 			int h2e = 0;
1611 
1612 			wpa_warning_log4(MSG_DEBUG,
1613 				   "SAE: Request anti-clogging token from "
1614 				   "%02x:xx:xx:%02x:%02x:%02x", (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
1615 
1616 			if (sta->sae->tmp)
1617 				h2e = sta->sae->h2e;
1618 			if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1619 			    status_code == WLAN_STATUS_SAE_PK)
1620 				h2e = 1;
1621 			data = auth_build_token_req(hapd, sta->sae->group,
1622 						    sta->addr, h2e);
1623 			resp = WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ;
1624 			if (hapd->conf->mesh & MESH_ENABLED)
1625 #ifndef CONFIG_SAE_CROP
1626 				sae_set_state(sta, SAE_NOTHING,
1627 					      "Request anti-clogging token case in mesh");
1628 #else
1629 				sta->sae->state = SAE_NOTHING;
1630 #endif
1631 			goto reply;
1632 		}
1633 
1634 		resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction,
1635 				   status_code, allow_reuse, &sta_removed);
1636 	} else if (auth_transaction == 2) {
1637 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1638 			       HOSTAPD_LEVEL_DEBUG,
1639 			       "SAE authentication (RX confirm, status=%u (%s))",
1640 			       status_code, status2str(status_code));
1641 		if (status_code != WLAN_STATUS_SUCCESS)
1642 			goto remove_sta;
1643 		if (sta->sae->state >= SAE_CONFIRMED ||
1644 		    !(hapd->conf->mesh & MESH_ENABLED)) {
1645 			const u8 *var;
1646 			size_t var_len;
1647 			u16 peer_send_confirm;
1648 
1649 			var = mgmt->u.auth.variable;
1650 			var_len = ((u8 *) mgmt) + len - mgmt->u.auth.variable;
1651 			if (var_len < 2) {
1652 				resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1653 				goto reply;
1654 			}
1655 
1656 			peer_send_confirm = WPA_GET_LE16(var);
1657 
1658 			if (sta->sae->state == SAE_ACCEPTED &&
1659 			    (peer_send_confirm <= sta->sae->rc ||
1660 			     peer_send_confirm == 0xffff)) {
1661 				wpa_warning_log4(MSG_DEBUG,
1662 					   "SAE: Silently ignore unexpected Confirm from peer "
1663 					   "%02x:xx:xx:%02x:%02x:%02x",
1664 					   (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
1665 				wpa_warning_log2(MSG_DEBUG,
1666 					   " (peer-send-confirm=%u Rc=%u)",
1667 					   peer_send_confirm, sta->sae->rc);
1668 				return;
1669 			}
1670 
1671 			if (sae_check_confirm(sta->sae, var, var_len) < 0) {
1672 				resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1673 				goto reply;
1674 			}
1675 			sta->sae->rc = peer_send_confirm;
1676 		}
1677 		resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction,
1678 				   status_code, 0, &sta_removed);
1679 	} else {
1680 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1681 			       HOSTAPD_LEVEL_DEBUG,
1682 			       "unexpected SAE authentication transaction %u (status=%u (%s))",
1683 			       auth_transaction, status_code,
1684 			       status2str(status_code));
1685 		if (status_code != WLAN_STATUS_SUCCESS)
1686 			goto remove_sta;
1687 		resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1688 	}
1689 
1690 reply:
1691 	if (!sta_removed && resp != WLAN_STATUS_SUCCESS) {
1692 		pos = mgmt->u.auth.variable;
1693 		end = ((const u8 *) mgmt) + len;
1694 
1695 		/* Copy the Finite Cyclic Group field from the request if we
1696 		 * rejected it as unsupported group. */
1697 		if (resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
1698 		    !data && end - pos >= 2)
1699 			data = wpabuf_alloc_copy(pos, 2);
1700 
1701 #ifdef CONFIG_HOSTAPD_WPA3
1702 #ifdef CONFIG_SAE
1703 		sae_sme_send_external_auth_status(hapd, sta, resp);
1704 #endif /* CONFIG_SAE */
1705 #endif /* CONFIG_HOSTAPD_WPA3 */
1706 		send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
1707 				auth_transaction, resp,
1708 				data ? wpabuf_head(data) : (u8 *) "",
1709 				data ? wpabuf_len(data) : 0, "auth-sae");
1710 	}
1711 
1712 remove_sta:
1713 	if (auth_transaction == 1)
1714 		success_status = sae_status_success(hapd, status_code);
1715 	else
1716 		success_status = status_code == WLAN_STATUS_SUCCESS;
1717 	if (!sta_removed && sta->added_unassoc &&
1718 	    (resp != WLAN_STATUS_SUCCESS || !success_status)) {
1719 		hostapd_drv_sta_remove(hapd, sta->addr);
1720 		sta->added_unassoc = 0;
1721 	}
1722 	wpabuf_free(data);
1723 }
1724 
1725 
1726 /**
1727  * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1728  * @hapd: BSS data for the device initiating the authentication
1729  * @sta: the peer to which commit authentication frame is sent
1730  *
1731  * This function implements Init event handling (IEEE Std 802.11-2012,
1732  * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1733  * sta->sae structure should be initialized appropriately via a call to
1734  * sae_prepare_commit().
1735  */
1736 int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta)
1737 {
1738 	int ret;
1739 
1740 	if (!sta->sae || !sta->sae->tmp)
1741 		return -1;
1742 
1743 	if (sta->sae->state != SAE_NOTHING)
1744 		return -1;
1745 
1746 	ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0, -1);
1747 	if (ret)
1748 		return -1;
1749 #ifndef CONFIG_SAE_CROP
1750 	sae_set_state(sta, SAE_COMMITTED, "Init and sent commit");
1751 #else
1752 	sta->sae->state = SAE_COMMITTED;
1753 #endif
1754 	sta->sae->sync = 0;
1755 	sae_set_retransmit_timer(hapd, sta);
1756 
1757 	return 0;
1758 }
1759 
1760 
1761 void auth_sae_process_commit(void *eloop_ctx, void *user_ctx)
1762 {
1763 	struct hostapd_data *hapd = eloop_ctx;
1764 	struct hostapd_sae_commit_queue *q;
1765 	unsigned int queue_len;
1766 
1767 	q = dl_list_first(&hapd->sae_commit_queue,
1768 			  struct hostapd_sae_commit_queue, list);
1769 	if (!q)
1770 		return;
1771 	wpa_warning_log0(MSG_DEBUG,
1772 		   "SAE: Process next available message from queue");
1773 	dl_list_del(&q->list);
1774 	handle_auth(hapd, (const struct ieee80211_mgmt *) q->msg, q->len,
1775 		    q->rssi, 1);
1776 	os_free(q);
1777 
1778 	if (eloop_is_timeout_registered(auth_sae_process_commit, hapd, NULL))
1779 		return;
1780 	queue_len = dl_list_len(&hapd->sae_commit_queue);
1781 	eloop_register_timeout(0, queue_len * 10000, auth_sae_process_commit,
1782 			       hapd, NULL);
1783 }
1784 
1785 
1786 static void auth_sae_queue(struct hostapd_data *hapd,
1787 			   const struct ieee80211_mgmt *mgmt, size_t len,
1788 			   int rssi)
1789 {
1790 	struct hostapd_sae_commit_queue *q, *q2;
1791 	unsigned int queue_len;
1792 	const struct ieee80211_mgmt *mgmt2;
1793 
1794 	queue_len = dl_list_len(&hapd->sae_commit_queue);
1795 	if (queue_len >= 15) {
1796 		wpa_warning_log4(MSG_DEBUG,
1797 			   "SAE: No more room in message queue - drop the new frame from %02x:xx:xx:%02x:%02x:%02x",
1798 			   mgmt->sa[0], mgmt->sa[3], mgmt->sa[4], mgmt->sa[5]);
1799 		return;
1800 	}
1801 
1802 	wpa_warning_log1(MSG_DEBUG, "SAE: Queue Authentication message from mac for processing (queue_len %u)",
1803 		   queue_len);
1804 	wpa_warning_log4(MSG_DEBUG, "mac %02x:xx:xx:%02x:%02x:%02x",
1805 		   			mgmt->sa[0], mgmt->sa[3], mgmt->sa[4], mgmt->sa[5]);
1806 	q = os_zalloc(sizeof(*q) + len);
1807 	if (!q)
1808 		return;
1809 	q->rssi = rssi;
1810 	q->len = len;
1811 	os_memcpy(q->msg, mgmt, len);
1812 
1813 	/* Check whether there is already a queued Authentication frame from the
1814 	 * same station with the same transaction number and if so, replace that
1815 	 * queue entry with the new one. This avoids issues with a peer that
1816 	 * sends multiple times (e.g., due to frequent SAE retries). There is no
1817 	 * point in us trying to process the old attempts after a new one has
1818 	 * obsoleted them. */
1819 	dl_list_for_each(q2, &hapd->sae_commit_queue,
1820 			 struct hostapd_sae_commit_queue, list) {
1821 		mgmt2 = (const struct ieee80211_mgmt *) q2->msg;
1822 		if (os_memcmp(mgmt->sa, mgmt2->sa, ETH_ALEN) == 0 &&
1823 		    mgmt->u.auth.auth_transaction ==
1824 		    mgmt2->u.auth.auth_transaction) {
1825 			wpa_warning_log0(MSG_DEBUG,
1826 				   "SAE: Replace queued message from same STA with same transaction number");
1827 			dl_list_add(&q2->list, &q->list);
1828 			dl_list_del(&q2->list);
1829 			os_free(q2);
1830 			goto queued;
1831 		}
1832 	}
1833 
1834 	/* No pending identical entry, so add to the end of the queue */
1835 	dl_list_add_tail(&hapd->sae_commit_queue, &q->list);
1836 
1837 queued:
1838 	if (eloop_is_timeout_registered(auth_sae_process_commit, hapd, NULL))
1839 		return;
1840 	eloop_register_timeout(0, queue_len * 10000, auth_sae_process_commit,
1841 			       hapd, NULL);
1842 }
1843 
1844 
1845 static int auth_sae_queued_addr(struct hostapd_data *hapd, const u8 *addr)
1846 {
1847 	struct hostapd_sae_commit_queue *q;
1848 	const struct ieee80211_mgmt *mgmt;
1849 
1850 	dl_list_for_each(q, &hapd->sae_commit_queue,
1851 			 struct hostapd_sae_commit_queue, list) {
1852 		mgmt = (const struct ieee80211_mgmt *) q->msg;
1853 		if (os_memcmp(addr, mgmt->sa, ETH_ALEN) == 0)
1854 			return 1;
1855 	}
1856 
1857 	return 0;
1858 }
1859 #endif /* CONFIG_SAE */
1860 #endif /* LOS_CONFIG_HOSTAPD_MGMT && CONFIG_SAE */
1861 
1862 #ifdef CONFIG_OWE
1863 static u16 wpa_res_to_status_code(enum wpa_validate_result res)
1864 {
1865 	switch (res) {
1866 	case WPA_IE_OK:
1867 		return WLAN_STATUS_SUCCESS;
1868 	case WPA_INVALID_IE:
1869 		return WLAN_STATUS_INVALID_IE;
1870 	case WPA_INVALID_GROUP:
1871 		return WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1872 	case WPA_INVALID_PAIRWISE:
1873 		return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1874 	case WPA_INVALID_AKMP:
1875 		return WLAN_STATUS_AKMP_NOT_VALID;
1876 	case WPA_NOT_ENABLED:
1877 		return WLAN_STATUS_INVALID_IE;
1878 	case WPA_ALLOC_FAIL:
1879 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1880 	case WPA_MGMT_FRAME_PROTECTION_VIOLATION:
1881 		return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
1882 	case WPA_INVALID_MGMT_GROUP_CIPHER:
1883 		return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
1884 	case WPA_INVALID_MDIE:
1885 		return WLAN_STATUS_INVALID_MDIE;
1886 	case WPA_INVALID_PROTO:
1887 		return WLAN_STATUS_INVALID_IE;
1888 	case WPA_INVALID_PMKID:
1889 		return WLAN_STATUS_INVALID_PMKID;
1890 	case WPA_DENIED_OTHER_REASON:
1891 		return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
1892 	}
1893 	return WLAN_STATUS_INVALID_IE;
1894 }
1895 #endif /* CONFIG_OWE */
1896 
1897 
1898 #ifndef EXT_CODE_CROP
1899 #ifdef CONFIG_FILS
1900 
1901 static void handle_auth_fils_finish(struct hostapd_data *hapd,
1902 				    struct sta_info *sta, u16 resp,
1903 				    struct wpabuf *data, int pub);
1904 
1905 void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
1906 		      const u8 *pos, size_t len, u16 auth_alg,
1907 		      u16 auth_transaction, u16 status_code,
1908 		      void (*cb)(struct hostapd_data *hapd,
1909 				 struct sta_info *sta, u16 resp,
1910 				 struct wpabuf *data, int pub))
1911 {
1912 	u16 resp = WLAN_STATUS_SUCCESS;
1913 	const u8 *end;
1914 	struct ieee802_11_elems elems;
1915 	enum wpa_validate_result res;
1916 	struct wpa_ie_data rsn;
1917 	struct rsn_pmksa_cache_entry *pmksa = NULL;
1918 
1919 	if (auth_transaction != 1 || status_code != WLAN_STATUS_SUCCESS)
1920 		return;
1921 
1922 	end = pos + len;
1923 
1924 	wpa_hexdump(MSG_DEBUG, "FILS: Authentication frame fields",
1925 		    pos, end - pos);
1926 
1927 	/* TODO: FILS PK */
1928 #ifdef CONFIG_FILS_SK_PFS
1929 	if (auth_alg == WLAN_AUTH_FILS_SK_PFS) {
1930 		u16 group;
1931 		struct wpabuf *pub;
1932 		size_t elem_len;
1933 
1934 		/* Using FILS PFS */
1935 
1936 		/* Finite Cyclic Group */
1937 		if (end - pos < 2) {
1938 			wpa_printf(MSG_DEBUG,
1939 				   "FILS: No room for Finite Cyclic Group");
1940 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1941 			goto fail;
1942 		}
1943 		group = WPA_GET_LE16(pos);
1944 		pos += 2;
1945 		if (group != hapd->conf->fils_dh_group) {
1946 			wpa_printf(MSG_DEBUG,
1947 				   "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1948 				   group, hapd->conf->fils_dh_group);
1949 			resp = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
1950 			goto fail;
1951 		}
1952 
1953 		crypto_ecdh_deinit(sta->fils_ecdh);
1954 		sta->fils_ecdh = crypto_ecdh_init(group);
1955 		if (!sta->fils_ecdh) {
1956 			wpa_printf(MSG_INFO,
1957 				   "FILS: Could not initialize ECDH with group %d",
1958 				   group);
1959 			resp = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
1960 			goto fail;
1961 		}
1962 
1963 		pub = crypto_ecdh_get_pubkey(sta->fils_ecdh, 1);
1964 		if (!pub) {
1965 			wpa_printf(MSG_DEBUG,
1966 				   "FILS: Failed to derive ECDH public key");
1967 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1968 			goto fail;
1969 		}
1970 		elem_len = wpabuf_len(pub);
1971 		wpabuf_free(pub);
1972 
1973 		/* Element */
1974 		if ((size_t) (end - pos) < elem_len) {
1975 			wpa_printf(MSG_DEBUG, "FILS: No room for Element");
1976 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1977 			goto fail;
1978 		}
1979 
1980 		wpabuf_free(sta->fils_g_sta);
1981 		sta->fils_g_sta = wpabuf_alloc_copy(pos, elem_len);
1982 		wpabuf_clear_free(sta->fils_dh_ss);
1983 		sta->fils_dh_ss = crypto_ecdh_set_peerkey(sta->fils_ecdh, 1,
1984 							  pos, elem_len);
1985 		if (!sta->fils_dh_ss) {
1986 			wpa_printf(MSG_DEBUG, "FILS: ECDH operation failed");
1987 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1988 			goto fail;
1989 		}
1990 		wpa_hexdump_buf_key(MSG_DEBUG, "FILS: DH_SS", sta->fils_dh_ss);
1991 		pos += elem_len;
1992 	} else {
1993 		crypto_ecdh_deinit(sta->fils_ecdh);
1994 		sta->fils_ecdh = NULL;
1995 		wpabuf_clear_free(sta->fils_dh_ss);
1996 		sta->fils_dh_ss = NULL;
1997 	}
1998 #endif /* CONFIG_FILS_SK_PFS */
1999 
2000 	wpa_hexdump(MSG_DEBUG, "FILS: Remaining IEs", pos, end - pos);
2001 	if (ieee802_11_parse_elems(pos, end - pos, &elems, 1) == ParseFailed) {
2002 		wpa_printf(MSG_DEBUG, "FILS: Could not parse elements");
2003 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2004 		goto fail;
2005 	}
2006 
2007 	/* RSNE */
2008 	wpa_hexdump(MSG_DEBUG, "FILS: RSN element",
2009 		    elems.rsn_ie, elems.rsn_ie_len);
2010 	if (!elems.rsn_ie ||
2011 	    wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
2012 				 &rsn) < 0) {
2013 		wpa_printf(MSG_DEBUG, "FILS: No valid RSN element");
2014 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2015 		goto fail;
2016 	}
2017 
2018 	if (!sta->wpa_sm)
2019 		sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr,
2020 						NULL);
2021 	if (!sta->wpa_sm) {
2022 		wpa_printf(MSG_DEBUG,
2023 			   "FILS: Failed to initialize RSN state machine");
2024 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2025 		goto fail;
2026 	}
2027 
2028 	res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
2029 				  hapd->iface->freq,
2030 				  elems.rsn_ie - 2, elems.rsn_ie_len + 2,
2031 				  elems.rsnxe ? elems.rsnxe - 2 : NULL,
2032 				  elems.rsnxe ? elems.rsnxe_len + 2 : 0,
2033 				  elems.mdie, elems.mdie_len, NULL, 0);
2034 	resp = wpa_res_to_status_code(res);
2035 	if (resp != WLAN_STATUS_SUCCESS)
2036 		goto fail;
2037 
2038 	if (!elems.fils_nonce) {
2039 		wpa_printf(MSG_DEBUG, "FILS: No FILS Nonce field");
2040 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2041 		goto fail;
2042 	}
2043 	wpa_hexdump(MSG_DEBUG, "FILS: SNonce", elems.fils_nonce,
2044 		    FILS_NONCE_LEN);
2045 	os_memcpy(sta->fils_snonce, elems.fils_nonce, FILS_NONCE_LEN);
2046 
2047 	/* PMKID List */
2048 	if (rsn.pmkid && rsn.num_pmkid > 0) {
2049 		u8 num;
2050 		const u8 *pmkid;
2051 
2052 		wpa_hexdump(MSG_DEBUG, "FILS: PMKID List",
2053 			    rsn.pmkid, rsn.num_pmkid * PMKID_LEN);
2054 
2055 		pmkid = rsn.pmkid;
2056 		num = rsn.num_pmkid;
2057 		while (num) {
2058 			wpa_hexdump(MSG_DEBUG, "FILS: PMKID", pmkid, PMKID_LEN);
2059 			pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr,
2060 						   pmkid);
2061 			if (pmksa)
2062 				break;
2063 			pmksa = wpa_auth_pmksa_get_fils_cache_id(hapd->wpa_auth,
2064 								 sta->addr,
2065 								 pmkid);
2066 			if (pmksa)
2067 				break;
2068 			pmkid += PMKID_LEN;
2069 			num--;
2070 		}
2071 	}
2072 	if (pmksa && wpa_auth_sta_key_mgmt(sta->wpa_sm) != pmksa->akmp) {
2073 		wpa_printf(MSG_DEBUG,
2074 			   "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
2075 			   wpa_auth_sta_key_mgmt(sta->wpa_sm), pmksa->akmp);
2076 		pmksa = NULL;
2077 	}
2078 	if (pmksa)
2079 		wpa_printf(MSG_DEBUG, "FILS: Found matching PMKSA cache entry");
2080 
2081 	/* FILS Session */
2082 	if (!elems.fils_session) {
2083 		wpa_printf(MSG_DEBUG, "FILS: No FILS Session element");
2084 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2085 		goto fail;
2086 	}
2087 	wpa_hexdump(MSG_DEBUG, "FILS: FILS Session", elems.fils_session,
2088 		    FILS_SESSION_LEN);
2089 	os_memcpy(sta->fils_session, elems.fils_session, FILS_SESSION_LEN);
2090 
2091 	/* Wrapped Data */
2092 	if (elems.wrapped_data) {
2093 		wpa_hexdump(MSG_DEBUG, "FILS: Wrapped Data",
2094 			    elems.wrapped_data,
2095 			    elems.wrapped_data_len);
2096 		if (!pmksa) {
2097 #ifndef CONFIG_NO_RADIUS
2098 			if (!sta->eapol_sm) {
2099 				sta->eapol_sm =
2100 					ieee802_1x_alloc_eapol_sm(hapd, sta);
2101 			}
2102 			wpa_printf(MSG_DEBUG,
2103 				   "FILS: Forward EAP-Initiate/Re-auth to authentication server");
2104 			ieee802_1x_encapsulate_radius(
2105 				hapd, sta, elems.wrapped_data,
2106 				elems.wrapped_data_len);
2107 			sta->fils_pending_cb = cb;
2108 			wpa_printf(MSG_DEBUG,
2109 				   "FILS: Will send Authentication frame once the response from authentication server is available");
2110 			sta->flags |= WLAN_STA_PENDING_FILS_ERP;
2111 			/* Calculate pending PMKID here so that we do not need
2112 			 * to maintain a copy of the EAP-Initiate/Reauth
2113 			 * message. */
2114 			if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta->wpa_sm),
2115 					   elems.wrapped_data,
2116 					   elems.wrapped_data_len,
2117 					   sta->fils_erp_pmkid) == 0)
2118 				sta->fils_erp_pmkid_set = 1;
2119 			return;
2120 #else /* CONFIG_NO_RADIUS */
2121 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2122 			goto fail;
2123 #endif /* CONFIG_NO_RADIUS */
2124 		}
2125 	}
2126 
2127 fail:
2128 	if (cb) {
2129 		struct wpabuf *data;
2130 		int pub = 0;
2131 
2132 		data = prepare_auth_resp_fils(hapd, sta, &resp, pmksa, NULL,
2133 					      NULL, 0, &pub);
2134 		if (!data) {
2135 			wpa_printf(MSG_DEBUG,
2136 				   "%s: prepare_auth_resp_fils() returned failure",
2137 				   __func__);
2138 		}
2139 
2140 		cb(hapd, sta, resp, data, pub);
2141 	}
2142 }
2143 
2144 
2145 static struct wpabuf *
2146 prepare_auth_resp_fils(struct hostapd_data *hapd,
2147 		       struct sta_info *sta, u16 *resp,
2148 		       struct rsn_pmksa_cache_entry *pmksa,
2149 		       struct wpabuf *erp_resp,
2150 		       const u8 *msk, size_t msk_len,
2151 		       int *is_pub)
2152 {
2153 	u8 fils_nonce[FILS_NONCE_LEN];
2154 	size_t ielen;
2155 	struct wpabuf *data = NULL;
2156 	const u8 *ie;
2157 	u8 *ie_buf = NULL;
2158 	const u8 *pmk = NULL;
2159 	size_t pmk_len = 0;
2160 	u8 pmk_buf[PMK_LEN_MAX];
2161 	struct wpabuf *pub = NULL;
2162 
2163 	if (*resp != WLAN_STATUS_SUCCESS)
2164 		goto fail;
2165 
2166 	ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen);
2167 	if (!ie) {
2168 		*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2169 		goto fail;
2170 	}
2171 
2172 	if (pmksa) {
2173 		/* Add PMKID of the selected PMKSA into RSNE */
2174 		ie_buf = os_malloc(ielen + 2 + 2 + PMKID_LEN);
2175 		if (!ie_buf) {
2176 			*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2177 			goto fail;
2178 		}
2179 
2180 		os_memcpy(ie_buf, ie, ielen);
2181 		if (wpa_insert_pmkid(ie_buf, &ielen, pmksa->pmkid) < 0) {
2182 			*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2183 			goto fail;
2184 		}
2185 		ie = ie_buf;
2186 	}
2187 
2188 	if (random_get_bytes(fils_nonce, FILS_NONCE_LEN) < 0) {
2189 		*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2190 		goto fail;
2191 	}
2192 	wpa_hexdump(MSG_DEBUG, "RSN: Generated FILS Nonce",
2193 		    fils_nonce, FILS_NONCE_LEN);
2194 
2195 #ifdef CONFIG_FILS_SK_PFS
2196 	if (sta->fils_dh_ss && sta->fils_ecdh) {
2197 		pub = crypto_ecdh_get_pubkey(sta->fils_ecdh, 1);
2198 		if (!pub) {
2199 			*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2200 			goto fail;
2201 		}
2202 	}
2203 #endif /* CONFIG_FILS_SK_PFS */
2204 
2205 	data = wpabuf_alloc(1000 + ielen + (pub ? wpabuf_len(pub) : 0));
2206 	if (!data) {
2207 		*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2208 		goto fail;
2209 	}
2210 
2211 	/* TODO: FILS PK */
2212 #ifdef CONFIG_FILS_SK_PFS
2213 	if (pub) {
2214 		/* Finite Cyclic Group */
2215 		wpabuf_put_le16(data, hapd->conf->fils_dh_group);
2216 
2217 		/* Element */
2218 		wpabuf_put_buf(data, pub);
2219 	}
2220 #endif /* CONFIG_FILS_SK_PFS */
2221 
2222 	/* RSNE */
2223 	wpabuf_put_data(data, ie, ielen);
2224 
2225 	/* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
2226 
2227 #ifdef CONFIG_IEEE80211R_AP
2228 	if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta->wpa_sm))) {
2229 		/* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
2230 		int res;
2231 		int use_sha384 = wpa_key_mgmt_sha384(
2232 			wpa_auth_sta_key_mgmt(sta->wpa_sm));
2233 
2234 		res = wpa_auth_write_fte(hapd->wpa_auth, use_sha384,
2235 					 wpabuf_put(data, 0),
2236 					 wpabuf_tailroom(data));
2237 		if (res < 0) {
2238 			*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2239 			goto fail;
2240 		}
2241 		wpabuf_put(data, res);
2242 	}
2243 #endif /* CONFIG_IEEE80211R_AP */
2244 
2245 	/* FILS Nonce */
2246 	wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
2247 	wpabuf_put_u8(data, 1 + FILS_NONCE_LEN); /* Length */
2248 	/* Element ID Extension */
2249 	wpabuf_put_u8(data, WLAN_EID_EXT_FILS_NONCE);
2250 	wpabuf_put_data(data, fils_nonce, FILS_NONCE_LEN);
2251 
2252 	/* FILS Session */
2253 	wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
2254 	wpabuf_put_u8(data, 1 + FILS_SESSION_LEN); /* Length */
2255 	/* Element ID Extension */
2256 	wpabuf_put_u8(data, WLAN_EID_EXT_FILS_SESSION);
2257 	wpabuf_put_data(data, sta->fils_session, FILS_SESSION_LEN);
2258 
2259 	/* Wrapped Data */
2260 	if (!pmksa && erp_resp) {
2261 		wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
2262 		wpabuf_put_u8(data, 1 + wpabuf_len(erp_resp)); /* Length */
2263 		/* Element ID Extension */
2264 		wpabuf_put_u8(data, WLAN_EID_EXT_WRAPPED_DATA);
2265 		wpabuf_put_buf(data, erp_resp);
2266 
2267 		if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta->wpa_sm),
2268 				     msk, msk_len, sta->fils_snonce, fils_nonce,
2269 				     sta->fils_dh_ss ?
2270 				     wpabuf_head(sta->fils_dh_ss) : NULL,
2271 				     sta->fils_dh_ss ?
2272 				     wpabuf_len(sta->fils_dh_ss) : 0,
2273 				     pmk_buf, &pmk_len)) {
2274 			wpa_printf(MSG_DEBUG, "FILS: Failed to derive PMK");
2275 			*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2276 			wpabuf_free(data);
2277 			data = NULL;
2278 			goto fail;
2279 		}
2280 		pmk = pmk_buf;
2281 
2282 		/* Don't use DHss in PTK derivation if PMKSA caching is not
2283 		 * used. */
2284 		wpabuf_clear_free(sta->fils_dh_ss);
2285 		sta->fils_dh_ss = NULL;
2286 
2287 		if (sta->fils_erp_pmkid_set) {
2288 			/* TODO: get PMKLifetime from WPA parameters */
2289 			unsigned int dot11RSNAConfigPMKLifetime = 43200;
2290 			int session_timeout;
2291 
2292 			session_timeout = dot11RSNAConfigPMKLifetime;
2293 			if (sta->session_timeout_set) {
2294 				struct os_reltime now, diff;
2295 
2296 				os_get_reltime(&now);
2297 				os_reltime_sub(&sta->session_timeout, &now,
2298 					       &diff);
2299 				session_timeout = diff.sec;
2300 			}
2301 
2302 			sta->fils_erp_pmkid_set = 0;
2303 			wpa_auth_add_fils_pmk_pmkid(sta->wpa_sm, pmk, pmk_len,
2304 						    sta->fils_erp_pmkid);
2305 			if (!hapd->conf->disable_pmksa_caching &&
2306 			    wpa_auth_pmksa_add2(
2307 				    hapd->wpa_auth, sta->addr,
2308 				    pmk, pmk_len,
2309 				    sta->fils_erp_pmkid,
2310 				    session_timeout,
2311 				    wpa_auth_sta_key_mgmt(sta->wpa_sm)) < 0) {
2312 				wpa_printf(MSG_ERROR,
2313 					   "FILS: Failed to add PMKSA cache entry based on ERP");
2314 			}
2315 		}
2316 	} else if (pmksa) {
2317 		pmk = pmksa->pmk;
2318 		pmk_len = pmksa->pmk_len;
2319 	}
2320 
2321 	if (!pmk) {
2322 		wpa_printf(MSG_DEBUG, "FILS: No PMK available");
2323 		*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2324 		wpabuf_free(data);
2325 		data = NULL;
2326 		goto fail;
2327 	}
2328 
2329 	if (fils_auth_pmk_to_ptk(sta->wpa_sm, pmk, pmk_len,
2330 				 sta->fils_snonce, fils_nonce,
2331 				 sta->fils_dh_ss ?
2332 				 wpabuf_head(sta->fils_dh_ss) : NULL,
2333 				 sta->fils_dh_ss ?
2334 				 wpabuf_len(sta->fils_dh_ss) : 0,
2335 				 sta->fils_g_sta, pub) < 0) {
2336 		*resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2337 		wpabuf_free(data);
2338 		data = NULL;
2339 		goto fail;
2340 	}
2341 
2342 fail:
2343 	if (is_pub)
2344 		*is_pub = pub != NULL;
2345 	os_free(ie_buf);
2346 	wpabuf_free(pub);
2347 	wpabuf_clear_free(sta->fils_dh_ss);
2348 	sta->fils_dh_ss = NULL;
2349 #ifdef CONFIG_FILS_SK_PFS
2350 	crypto_ecdh_deinit(sta->fils_ecdh);
2351 	sta->fils_ecdh = NULL;
2352 #endif /* CONFIG_FILS_SK_PFS */
2353 	return data;
2354 }
2355 
2356 
2357 static void handle_auth_fils_finish(struct hostapd_data *hapd,
2358 				    struct sta_info *sta, u16 resp,
2359 				    struct wpabuf *data, int pub)
2360 {
2361 	u16 auth_alg;
2362 
2363 	auth_alg = (pub ||
2364 		    resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) ?
2365 		WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
2366 	send_auth_reply(hapd, sta, sta->addr, hapd->own_addr, auth_alg, 2, resp,
2367 			data ? wpabuf_head(data) : (u8 *) "",
2368 			data ? wpabuf_len(data) : 0, "auth-fils-finish");
2369 	wpabuf_free(data);
2370 
2371 	if (resp == WLAN_STATUS_SUCCESS) {
2372 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2373 			       HOSTAPD_LEVEL_DEBUG,
2374 			       "authentication OK (FILS)");
2375 		sta->flags |= WLAN_STA_AUTH;
2376 		wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
2377 		sta->auth_alg = pub ? WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
2378 		mlme_authenticate_indication(hapd, sta);
2379 	}
2380 }
2381 
2382 
2383 void ieee802_11_finish_fils_auth(struct hostapd_data *hapd,
2384 				 struct sta_info *sta, int success,
2385 				 struct wpabuf *erp_resp,
2386 				 const u8 *msk, size_t msk_len)
2387 {
2388 	u16 resp;
2389 	u32 flags = sta->flags;
2390 
2391 	sta->flags &= ~(WLAN_STA_PENDING_FILS_ERP |
2392 			WLAN_STA_PENDING_PASN_FILS_ERP);
2393 
2394 	resp = success ? WLAN_STATUS_SUCCESS : WLAN_STATUS_UNSPECIFIED_FAILURE;
2395 
2396 	if (flags & WLAN_STA_PENDING_FILS_ERP) {
2397 		struct wpabuf *data;
2398 		int pub = 0;
2399 
2400 		if (!sta->fils_pending_cb)
2401 			return;
2402 
2403 		data = prepare_auth_resp_fils(hapd, sta, &resp, NULL, erp_resp,
2404 					      msk, msk_len, &pub);
2405 		if (!data) {
2406 			wpa_printf(MSG_DEBUG,
2407 				   "%s: prepare_auth_resp_fils() failure",
2408 				   __func__);
2409 		}
2410 		sta->fils_pending_cb(hapd, sta, resp, data, pub);
2411 #ifdef CONFIG_PASN
2412 	} else if (flags & WLAN_STA_PENDING_PASN_FILS_ERP) {
2413 		pasn_fils_auth_resp(hapd, sta, resp, erp_resp,
2414 				    msk, msk_len);
2415 #endif /* CONFIG_PASN */
2416 	}
2417 }
2418 
2419 #endif /* CONFIG_FILS */
2420 
2421 
2422 static int ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
2423 				      const u8 *msg, size_t len,
2424 				      struct radius_sta *info)
2425 {
2426 	int res;
2427 
2428 	res = hostapd_allowed_address(hapd, addr, msg, len, info, 0);
2429 
2430 	if (res == HOSTAPD_ACL_REJECT) {
2431 		wpa_printf(MSG_DEBUG, "Station " MACSTR
2432 			   " not allowed to authenticate",
2433 			   MAC2STR(addr));
2434 		return HOSTAPD_ACL_REJECT;
2435 	}
2436 
2437 	if (res == HOSTAPD_ACL_PENDING) {
2438 		wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
2439 			   " waiting for an external authentication",
2440 			   MAC2STR(addr));
2441 		/* Authentication code will re-send the authentication frame
2442 		 * after it has received (and cached) information from the
2443 		 * external source. */
2444 		return HOSTAPD_ACL_PENDING;
2445 	}
2446 
2447 	return res;
2448 }
2449 
2450 
2451 static int
2452 ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
2453 			   int res, struct radius_sta *info)
2454 {
2455 	u32 session_timeout = info->session_timeout;
2456 	u32 acct_interim_interval = info->acct_interim_interval;
2457 	struct vlan_description *vlan_id = &info->vlan_id;
2458 	struct hostapd_sta_wpa_psk_short *psk = info->psk;
2459 	char *identity = info->identity;
2460 	char *radius_cui = info->radius_cui;
2461 
2462 	if (vlan_id->notempty &&
2463 	    !hostapd_vlan_valid(hapd->conf->vlan, vlan_id)) {
2464 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
2465 			       HOSTAPD_LEVEL_INFO,
2466 			       "Invalid VLAN %d%s received from RADIUS server",
2467 			       vlan_id->untagged,
2468 			       vlan_id->tagged[0] ? "+" : "");
2469 		return -1;
2470 	}
2471 	if (ap_sta_set_vlan(hapd, sta, vlan_id) < 0)
2472 		return -1;
2473 	if (sta->vlan_id)
2474 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
2475 			       HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
2476 
2477 	hostapd_free_psk_list(sta->psk);
2478 	if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED)
2479 		hostapd_copy_psk_list(&sta->psk, psk);
2480 	else
2481 		sta->psk = NULL;
2482 
2483 	os_free(sta->identity);
2484 	if (identity)
2485 		sta->identity = os_strdup(identity);
2486 	else
2487 		sta->identity = NULL;
2488 
2489 	os_free(sta->radius_cui);
2490 	if (radius_cui)
2491 		sta->radius_cui = os_strdup(radius_cui);
2492 	else
2493 		sta->radius_cui = NULL;
2494 
2495 	if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
2496 		sta->acct_interim_interval = acct_interim_interval;
2497 	if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT) {
2498 		sta->session_timeout_set = 1;
2499 		os_get_reltime(&sta->session_timeout);
2500 		sta->session_timeout.sec += session_timeout;
2501 		ap_sta_session_timeout(hapd, sta, session_timeout);
2502 	} else {
2503 		sta->session_timeout_set = 0;
2504 		ap_sta_no_session_timeout(hapd, sta);
2505 	}
2506 
2507 	return 0;
2508 }
2509 #endif /* EXT_CODE_CROP */
2510 
2511 #ifdef CONFIG_PASN
2512 #ifdef CONFIG_SAE
2513 
2514 static int pasn_wd_handle_sae_commit(struct hostapd_data *hapd,
2515 				     struct sta_info *sta,
2516 				     struct wpabuf *wd)
2517 {
2518 	struct pasn_data *pasn = sta->pasn;
2519 	const char *password;
2520 	const u8 *data;
2521 	size_t buf_len;
2522 	u16 res, alg, seq, status;
2523 	int groups[] = { pasn->group, 0 };
2524 	struct sae_pt *pt = NULL;
2525 	int ret;
2526 
2527 	if (!wd)
2528 		return -1;
2529 
2530 	data = wpabuf_head_u8(wd);
2531 	buf_len = wpabuf_len(wd);
2532 
2533 	if (buf_len < 6) {
2534 		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
2535 			   buf_len);
2536 		return -1;
2537 	}
2538 
2539 	alg = WPA_GET_LE16(data);
2540 	seq = WPA_GET_LE16(data + 2);
2541 	status = WPA_GET_LE16(data + 4);
2542 
2543 	wpa_printf(MSG_DEBUG, "PASN: SAE commit: alg=%u, seq=%u, status=%u",
2544 		   alg, seq, status);
2545 
2546 	if (alg != WLAN_AUTH_SAE || seq != 1 ||
2547 	    status != WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
2548 		wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE commit");
2549 		return -1;
2550 	}
2551 
2552 	sae_clear_data(&pasn->sae);
2553 	pasn->sae.state = SAE_NOTHING;
2554 
2555 	ret = sae_set_group(&pasn->sae, pasn->group);
2556 	if (ret) {
2557 		wpa_printf(MSG_DEBUG, "PASN: Failed to set SAE group");
2558 		return -1;
2559 	}
2560 
2561 	password = sae_get_password(hapd, sta, NULL, NULL, &pt, NULL);
2562 	if (!password || !pt) {
2563 		wpa_printf(MSG_DEBUG, "PASN: No SAE PT found");
2564 		return -1;
2565 	}
2566 
2567 	ret = sae_prepare_commit_pt(&pasn->sae, pt, hapd->own_addr, sta->addr,
2568 				    NULL, NULL);
2569 	if (ret) {
2570 		wpa_printf(MSG_DEBUG, "PASN: Failed to prepare SAE commit");
2571 		return -1;
2572 	}
2573 
2574 	res = sae_parse_commit(&pasn->sae, data + 6, buf_len - 6, NULL, 0,
2575 			       groups, 0);
2576 	if (res != WLAN_STATUS_SUCCESS) {
2577 		wpa_printf(MSG_DEBUG, "PASN: Failed parsing SAE commit");
2578 		return -1;
2579 	}
2580 
2581 	/* Process the commit message and derive the PMK */
2582 	ret = sae_process_commit(&pasn->sae);
2583 	if (ret) {
2584 		wpa_printf(MSG_DEBUG, "SAE: Failed to process peer commit");
2585 		return -1;
2586 	}
2587 
2588 	pasn->sae.state = SAE_COMMITTED;
2589 
2590 	return 0;
2591 }
2592 
2593 
2594 static int pasn_wd_handle_sae_confirm(struct hostapd_data *hapd,
2595 				      struct sta_info *sta,
2596 				      struct wpabuf *wd)
2597 {
2598 	struct pasn_data *pasn = sta->pasn;
2599 	const u8 *data;
2600 	size_t buf_len;
2601 	u16 res, alg, seq, status;
2602 
2603 	if (!wd)
2604 		return -1;
2605 
2606 	data = wpabuf_head_u8(wd);
2607 	buf_len = wpabuf_len(wd);
2608 
2609 	if (buf_len < 6) {
2610 		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
2611 			   buf_len);
2612 		return -1;
2613 	}
2614 
2615 	alg = WPA_GET_LE16(data);
2616 	seq = WPA_GET_LE16(data + 2);
2617 	status = WPA_GET_LE16(data + 4);
2618 
2619 	wpa_printf(MSG_DEBUG, "PASN: SAE confirm: alg=%u, seq=%u, status=%u",
2620 		   alg, seq, status);
2621 
2622 	if (alg != WLAN_AUTH_SAE || seq != 2 || status != WLAN_STATUS_SUCCESS) {
2623 		wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE confirm");
2624 		return -1;
2625 	}
2626 
2627 	res = sae_check_confirm(&pasn->sae, data + 6, buf_len - 6);
2628 	if (res != WLAN_STATUS_SUCCESS) {
2629 		wpa_printf(MSG_DEBUG, "PASN: SAE failed checking confirm");
2630 		return -1;
2631 	}
2632 
2633 	pasn->sae.state = SAE_ACCEPTED;
2634 
2635 	/*
2636 	 * TODO: Based on on IEEE P802.11az/D2.6, the PMKSA derived with
2637 	 * PASN/SAE should only be allowed with future PASN only. For now do not
2638 	 * restrict this only for PASN.
2639 	 */
2640 	wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
2641 			       pasn->sae.pmk, pasn->sae.pmkid);
2642 	return 0;
2643 }
2644 
2645 
2646 static struct wpabuf * pasn_get_sae_wd(struct hostapd_data *hapd,
2647 				       struct sta_info *sta)
2648 {
2649 	struct pasn_data *pasn = sta->pasn;
2650 	struct wpabuf *buf = NULL;
2651 	u8 *len_ptr;
2652 	size_t len;
2653 
2654 	/* Need to add the entire Authentication frame body */
2655 	buf = wpabuf_alloc(8 + SAE_COMMIT_MAX_LEN + 8 + SAE_CONFIRM_MAX_LEN);
2656 	if (!buf) {
2657 		wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
2658 		return NULL;
2659 	}
2660 
2661 	/* Need to add the entire authentication frame body for the commit */
2662 	len_ptr = wpabuf_put(buf, 2);
2663 	wpabuf_put_le16(buf, WLAN_AUTH_SAE);
2664 	wpabuf_put_le16(buf, 1);
2665 	wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
2666 
2667 	/* Write the actual commit and update the length accordingly */
2668 	sae_write_commit(&pasn->sae, buf, NULL, 0);
2669 	len = wpabuf_len(buf);
2670 	WPA_PUT_LE16(len_ptr, len - 2);
2671 
2672 	/* Need to add the entire Authentication frame body for the confirm */
2673 	len_ptr = wpabuf_put(buf, 2);
2674 	wpabuf_put_le16(buf, WLAN_AUTH_SAE);
2675 	wpabuf_put_le16(buf, 2);
2676 	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
2677 
2678 	sae_write_confirm(&pasn->sae, buf);
2679 	WPA_PUT_LE16(len_ptr, wpabuf_len(buf) - len - 2);
2680 
2681 	pasn->sae.state = SAE_CONFIRMED;
2682 
2683 	return buf;
2684 }
2685 
2686 #endif /* CONFIG_SAE */
2687 
2688 
2689 #ifdef CONFIG_FILS
2690 
2691 static struct wpabuf * pasn_get_fils_wd(struct hostapd_data *hapd,
2692 					struct sta_info *sta)
2693 {
2694 	struct pasn_data *pasn = sta->pasn;
2695 	struct pasn_fils_data *fils = &pasn->fils;
2696 	struct wpabuf *buf = NULL;
2697 
2698 	if (!fils->erp_resp) {
2699 		wpa_printf(MSG_DEBUG, "PASN: FILS: Missing erp_resp");
2700 		return NULL;
2701 	}
2702 
2703 	buf = wpabuf_alloc(1500);
2704 	if (!buf)
2705 		return NULL;
2706 
2707 	/* Add the authentication algorithm */
2708 	wpabuf_put_le16(buf, WLAN_AUTH_FILS_SK);
2709 
2710 	/* Authentication Transaction seq# */
2711 	wpabuf_put_le16(buf, 2);
2712 
2713 	/* Status Code */
2714 	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
2715 
2716 	/* Own RSNE */
2717 	wpa_pasn_add_rsne(buf, NULL, pasn->akmp, pasn->cipher);
2718 
2719 	/* FILS Nonce */
2720 	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
2721 	wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN);
2722 	wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
2723 	wpabuf_put_data(buf, fils->anonce, FILS_NONCE_LEN);
2724 
2725 	/* FILS Session */
2726 	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
2727 	wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN);
2728 	wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
2729 	wpabuf_put_data(buf, fils->session, FILS_SESSION_LEN);
2730 
2731 	/* Wrapped Data */
2732 	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
2733 	wpabuf_put_u8(buf, 1 + wpabuf_len(fils->erp_resp));
2734 	wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
2735 	wpabuf_put_buf(buf, fils->erp_resp);
2736 
2737 	return buf;
2738 }
2739 
2740 
2741 static void pasn_fils_auth_resp(struct hostapd_data *hapd,
2742 				struct sta_info *sta, u16 status,
2743 				struct wpabuf *erp_resp,
2744 				const u8 *msk, size_t msk_len)
2745 {
2746 	struct pasn_data *pasn = sta->pasn;
2747 	struct pasn_fils_data *fils = &pasn->fils;
2748 	u8 pmk[PMK_LEN_MAX];
2749 	size_t pmk_len;
2750 	int ret;
2751 
2752 	wpa_printf(MSG_DEBUG, "PASN: FILS: Handle AS response - status=%u",
2753 		   status);
2754 
2755 	if (status != WLAN_STATUS_SUCCESS)
2756 		goto fail;
2757 
2758 	if (!pasn->secret) {
2759 		wpa_printf(MSG_DEBUG, "PASN: FILS: Missing secret");
2760 		goto fail;
2761 	}
2762 
2763 	if (random_get_bytes(fils->anonce, FILS_NONCE_LEN) < 0) {
2764 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to get ANonce");
2765 		goto fail;
2766 	}
2767 
2768 	wpa_hexdump(MSG_DEBUG, "RSN: Generated FILS ANonce",
2769 		    fils->anonce, FILS_NONCE_LEN);
2770 
2771 	ret = fils_rmsk_to_pmk(pasn->akmp, msk, msk_len, fils->nonce,
2772 			       fils->anonce, NULL, 0, pmk, &pmk_len);
2773 	if (ret) {
2774 		wpa_printf(MSG_DEBUG, "FILS: Failed to derive PMK");
2775 		goto fail;
2776 	}
2777 
2778 	ret = pasn_pmk_to_ptk(pmk, pmk_len, sta->addr, hapd->own_addr,
2779 			      wpabuf_head(pasn->secret),
2780 			      wpabuf_len(pasn->secret),
2781 			      &sta->pasn->ptk, sta->pasn->akmp,
2782 			      sta->pasn->cipher, sta->pasn->kdk_len);
2783 	if (ret) {
2784 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to derive PTK");
2785 		goto fail;
2786 	}
2787 
2788 	wpa_printf(MSG_DEBUG, "PASN: PTK successfully derived");
2789 
2790 	wpabuf_free(pasn->secret);
2791 	pasn->secret = NULL;
2792 
2793 	fils->erp_resp = erp_resp;
2794 	ret = handle_auth_pasn_resp(hapd, sta, NULL, WLAN_STATUS_SUCCESS);
2795 	fils->erp_resp = NULL;
2796 
2797 	if (ret) {
2798 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to send response");
2799 		goto fail;
2800 	}
2801 
2802 	fils->state = PASN_FILS_STATE_COMPLETE;
2803 	return;
2804 fail:
2805 	ap_free_sta(hapd, sta);
2806 }
2807 
2808 
2809 static int pasn_wd_handle_fils(struct hostapd_data *hapd, struct sta_info *sta,
2810 			       struct wpabuf *wd)
2811 {
2812 #ifdef CONFIG_NO_RADIUS
2813 	wpa_printf(MSG_DEBUG, "PASN: FILS: RADIUS is not configured. Fail");
2814 	return -1;
2815 #else /* CONFIG_NO_RADIUS */
2816 	struct pasn_data *pasn = sta->pasn;
2817 	struct pasn_fils_data *fils = &pasn->fils;
2818 	struct ieee802_11_elems elems;
2819 	struct wpa_ie_data rsne_data;
2820 	struct wpabuf *fils_wd;
2821 	const u8 *data;
2822 	size_t buf_len;
2823 	u16 alg, seq, status;
2824 	int ret;
2825 
2826 	if (fils->state != PASN_FILS_STATE_NONE) {
2827 		wpa_printf(MSG_DEBUG, "PASN: FILS: Not expecting wrapped data");
2828 		return -1;
2829 	}
2830 
2831 	if (!wd) {
2832 		wpa_printf(MSG_DEBUG, "PASN: FILS: No wrapped data");
2833 		return -1;
2834 	}
2835 
2836 	data = wpabuf_head_u8(wd);
2837 	buf_len = wpabuf_len(wd);
2838 
2839 	if (buf_len < 6) {
2840 		wpa_printf(MSG_DEBUG, "PASN: FILS: Buffer too short. len=%zu",
2841 			   buf_len);
2842 		return -1;
2843 	}
2844 
2845 	alg = WPA_GET_LE16(data);
2846 	seq = WPA_GET_LE16(data + 2);
2847 	status = WPA_GET_LE16(data + 4);
2848 
2849 	wpa_printf(MSG_DEBUG, "PASN: FILS: alg=%u, seq=%u, status=%u",
2850 		   alg, seq, status);
2851 
2852 	if (alg != WLAN_AUTH_FILS_SK || seq != 1 ||
2853 	    status != WLAN_STATUS_SUCCESS) {
2854 		wpa_printf(MSG_DEBUG,
2855 			   "PASN: FILS: Dropping peer authentication");
2856 		return -1;
2857 	}
2858 
2859 	data += 6;
2860 	buf_len -= 6;
2861 
2862 	if (ieee802_11_parse_elems(data, buf_len, &elems, 1) == ParseFailed) {
2863 		wpa_printf(MSG_DEBUG, "PASN: FILS: Could not parse elements");
2864 		return -1;
2865 	}
2866 
2867 	if (!elems.rsn_ie || !elems.fils_nonce || !elems.fils_nonce ||
2868 	    !elems.wrapped_data) {
2869 		wpa_printf(MSG_DEBUG, "PASN: FILS: Missing IEs");
2870 		return -1;
2871 	}
2872 
2873 	ret = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
2874 				   &rsne_data);
2875 	if (ret) {
2876 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed parsing RNSE");
2877 		return -1;
2878 	}
2879 
2880 	ret = wpa_pasn_validate_rsne(&rsne_data);
2881 	if (ret) {
2882 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed validating RSNE");
2883 		return -1;
2884 	}
2885 
2886 	if (rsne_data.num_pmkid) {
2887 		wpa_printf(MSG_DEBUG,
2888 			   "PASN: FILS: Not expecting PMKID in RSNE");
2889 		return -1;
2890 	}
2891 
2892 	wpa_hexdump(MSG_DEBUG, "PASN: FILS: Nonce", elems.fils_nonce,
2893 		    FILS_NONCE_LEN);
2894 	os_memcpy(fils->nonce, elems.fils_nonce, FILS_NONCE_LEN);
2895 
2896 	wpa_hexdump(MSG_DEBUG, "PASN: FILS: Session", elems.fils_session,
2897 		    FILS_SESSION_LEN);
2898 	os_memcpy(fils->session, elems.fils_session, FILS_SESSION_LEN);
2899 
2900 	fils_wd = ieee802_11_defrag(&elems, WLAN_EID_EXTENSION,
2901 				    WLAN_EID_EXT_WRAPPED_DATA);
2902 
2903 	if (!fils_wd) {
2904 		wpa_printf(MSG_DEBUG, "PASN: FILS: Missing wrapped data");
2905 		return -1;
2906 	}
2907 
2908 	if (!sta->eapol_sm)
2909 		sta->eapol_sm = ieee802_1x_alloc_eapol_sm(hapd, sta);
2910 
2911 	wpa_printf(MSG_DEBUG,
2912 		   "PASN: FILS: Forward EAP-Initiate/Re-auth to AS");
2913 
2914 	ieee802_1x_encapsulate_radius(hapd, sta, wpabuf_head(fils_wd),
2915 				      wpabuf_len(fils_wd));
2916 
2917 	sta->flags |= WLAN_STA_PENDING_PASN_FILS_ERP;
2918 
2919 	fils->state = PASN_FILS_STATE_PENDING_AS;
2920 
2921 	/*
2922 	 * Calculate pending PMKID here so that we do not need to maintain a
2923 	 * copy of the EAP-Initiate/Reautt message.
2924 	 */
2925 	fils_pmkid_erp(pasn->akmp, wpabuf_head(fils_wd), wpabuf_len(fils_wd),
2926 		       fils->erp_pmkid);
2927 
2928 	wpabuf_free(fils_wd);
2929 	return 0;
2930 #endif /* CONFIG_NO_RADIUS */
2931 }
2932 
2933 #endif /* CONFIG_FILS */
2934 
2935 
2936 static struct wpabuf * pasn_get_wrapped_data(struct hostapd_data *hapd,
2937 					     struct sta_info *sta)
2938 {
2939 	switch (sta->pasn->akmp) {
2940 	case WPA_KEY_MGMT_PASN:
2941 		/* no wrapped data */
2942 		return NULL;
2943 	case WPA_KEY_MGMT_SAE:
2944 #ifdef CONFIG_SAE
2945 		return pasn_get_sae_wd(hapd, sta);
2946 #else /* CONFIG_SAE */
2947 		wpa_printf(MSG_ERROR,
2948 			   "PASN: SAE: Cannot derive wrapped data");
2949 		return NULL;
2950 #endif /* CONFIG_SAE */
2951 	case WPA_KEY_MGMT_FILS_SHA256:
2952 	case WPA_KEY_MGMT_FILS_SHA384:
2953 #ifdef CONFIG_FILS
2954 		return pasn_get_fils_wd(hapd, sta);
2955 #endif /* CONFIG_FILS */
2956 		/* fall through */
2957 	case WPA_KEY_MGMT_FT_PSK:
2958 	case WPA_KEY_MGMT_FT_IEEE8021X:
2959 	case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
2960 	default:
2961 		wpa_printf(MSG_ERROR,
2962 			   "PASN: TODO: Wrapped data for akmp=0x%x",
2963 			   sta->pasn->akmp);
2964 		return NULL;
2965 	}
2966 }
2967 
2968 
2969 static int
2970 pasn_derive_keys(struct hostapd_data *hapd, struct sta_info *sta,
2971 		 const u8 *cached_pmk, size_t cached_pmk_len,
2972 		 struct wpa_pasn_params_data *pasn_data,
2973 		 struct wpabuf *wrapped_data,
2974 		 struct wpabuf *secret)
2975 {
2976 	static const u8 pasn_default_pmk[] = {'P', 'M', 'K', 'z'};
2977 	u8 pmk[PMK_LEN_MAX];
2978 	u8 pmk_len;
2979 	int ret;
2980 
2981 	os_memset(pmk, 0, sizeof(pmk));
2982 	pmk_len = 0;
2983 
2984 	if (!cached_pmk || !cached_pmk_len)
2985 		wpa_printf(MSG_DEBUG, "PASN: No valid PMKSA entry");
2986 
2987 	if (sta->pasn->akmp == WPA_KEY_MGMT_PASN) {
2988 		wpa_printf(MSG_DEBUG, "PASN: Using default PMK");
2989 
2990 		pmk_len = WPA_PASN_PMK_LEN;
2991 		os_memcpy(pmk, pasn_default_pmk, sizeof(pasn_default_pmk));
2992 	} else if (cached_pmk && cached_pmk_len) {
2993 		wpa_printf(MSG_DEBUG, "PASN: Using PMKSA entry");
2994 
2995 		pmk_len = cached_pmk_len;
2996 		os_memcpy(pmk, cached_pmk, cached_pmk_len);
2997 	} else {
2998 		switch (sta->pasn->akmp) {
2999 #ifdef CONFIG_SAE
3000 		case WPA_KEY_MGMT_SAE:
3001 			if (sta->pasn->sae.state == SAE_COMMITTED) {
3002 				pmk_len = PMK_LEN;
3003 				os_memcpy(pmk, sta->pasn->sae.pmk, PMK_LEN);
3004 				break;
3005 			}
3006 #endif /* CONFIG_SAE */
3007 			/* fall through */
3008 		default:
3009 			/* TODO: Derive PMK based on wrapped data */
3010 			wpa_printf(MSG_DEBUG,
3011 				   "PASN: Missing PMK derivation");
3012 			return -1;
3013 		}
3014 	}
3015 
3016 	ret = pasn_pmk_to_ptk(pmk, pmk_len, sta->addr, hapd->own_addr,
3017 			      wpabuf_head(secret), wpabuf_len(secret),
3018 			      &sta->pasn->ptk, sta->pasn->akmp,
3019 			      sta->pasn->cipher, sta->pasn->kdk_len);
3020 	if (ret) {
3021 		wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
3022 		return -1;
3023 	}
3024 
3025 	wpa_printf(MSG_DEBUG, "PASN: PTK successfully derived");
3026 	return 0;
3027 }
3028 
3029 
3030 static void handle_auth_pasn_comeback(struct hostapd_data *hapd,
3031 				      struct sta_info *sta, u16 group)
3032 {
3033 	struct wpabuf *buf, *comeback;
3034 	int ret;
3035 
3036 	wpa_printf(MSG_DEBUG,
3037 		   "PASN: Building comeback frame 2. Comeback after=%u",
3038 		   hapd->conf->pasn_comeback_after);
3039 
3040 	buf = wpabuf_alloc(1500);
3041 	if (!buf)
3042 		return;
3043 
3044 	wpa_pasn_build_auth_header(buf, hapd->own_addr, hapd->own_addr,
3045 				   sta->addr, 2,
3046 				   WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY);
3047 
3048 	/*
3049 	 * Do not include the group as a part of the token since it is not going
3050 	 * to be used.
3051 	 */
3052 	comeback = auth_build_token_req(hapd, 0, sta->addr, 0);
3053 	if (!comeback) {
3054 		wpa_printf(MSG_DEBUG,
3055 			   "PASN: Failed sending auth with comeback");
3056 		wpabuf_free(buf);
3057 		return;
3058 	}
3059 
3060 	wpa_pasn_add_parameter_ie(buf, group,
3061 				  WPA_PASN_WRAPPED_DATA_NO,
3062 				  NULL, 0, comeback,
3063 				  hapd->conf->pasn_comeback_after);
3064 	wpabuf_free(comeback);
3065 
3066 	wpa_printf(MSG_DEBUG,
3067 		   "PASN: comeback: STA=" MACSTR, MAC2STR(sta->addr));
3068 
3069 	ret = hostapd_drv_send_mlme(hapd, wpabuf_head(buf), wpabuf_len(buf), 0,
3070 				    NULL, 0, 0);
3071 	if (ret)
3072 		wpa_printf(MSG_INFO, "PASN: Failed to send comeback frame 2");
3073 
3074 	wpabuf_free(buf);
3075 }
3076 
3077 
3078 static int handle_auth_pasn_resp(struct hostapd_data *hapd,
3079 				 struct sta_info *sta,
3080 				 struct rsn_pmksa_cache_entry *pmksa,
3081 				 u16 status)
3082 {
3083 	struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL;
3084 	u8 mic[WPA_PASN_MAX_MIC_LEN];
3085 	u8 mic_len;
3086 	u8 *ptr;
3087 	const u8 *frame, *data, *rsn_ie, *rsnxe_ie;
3088 	u8 *data_buf = NULL;
3089 	size_t rsn_ie_len, frame_len, data_len;
3090 	int ret;
3091 	const u8 *pmkid = NULL;
3092 
3093 	wpa_printf(MSG_DEBUG, "PASN: Building frame 2: status=%u", status);
3094 
3095 	buf = wpabuf_alloc(1500);
3096 	if (!buf)
3097 		goto fail;
3098 
3099 	wpa_pasn_build_auth_header(buf, hapd->own_addr, hapd->own_addr,
3100 				   sta->addr, 2, status);
3101 
3102 	if (status != WLAN_STATUS_SUCCESS)
3103 		goto done;
3104 
3105 	if (pmksa) {
3106 		pmkid = pmksa->pmkid;
3107 #ifdef CONFIG_SAE
3108 	} else if (sta->pasn->akmp == WPA_KEY_MGMT_SAE) {
3109 		wpa_printf(MSG_DEBUG, "PASN: Use SAE PMKID");
3110 		pmkid = sta->pasn->sae.pmkid;
3111 #endif /* CONFIG_SAE */
3112 #ifdef CONFIG_FILS
3113 	} else if (sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
3114 		   sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
3115 		wpa_printf(MSG_DEBUG, "PASN: Use FILS ERP PMKID");
3116 		pmkid = sta->pasn->fils.erp_pmkid;
3117 #endif /* CONFIG_FILS */
3118 	}
3119 
3120 	if (wpa_pasn_add_rsne(buf, pmkid,
3121 			      sta->pasn->akmp, sta->pasn->cipher) < 0)
3122 		goto fail;
3123 
3124 	/* No need to derive PMK if PMKSA is given */
3125 	if (!pmksa)
3126 		wrapped_data_buf = pasn_get_wrapped_data(hapd, sta);
3127 	else
3128 		sta->pasn->wrapped_data_format = WPA_PASN_WRAPPED_DATA_NO;
3129 
3130 	/* Get public key */
3131 	pubkey = crypto_ecdh_get_pubkey(sta->pasn->ecdh, 0);
3132 	pubkey = wpabuf_zeropad(pubkey,
3133 				crypto_ecdh_prime_len(sta->pasn->ecdh));
3134 	if (!pubkey) {
3135 		wpa_printf(MSG_DEBUG, "PASN: Failed to get pubkey");
3136 		goto fail;
3137 	}
3138 
3139 	wpa_pasn_add_parameter_ie(buf, sta->pasn->group,
3140 				  sta->pasn->wrapped_data_format,
3141 				  pubkey, true, NULL, 0);
3142 
3143 	if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
3144 		goto fail;
3145 
3146 	wpabuf_free(wrapped_data_buf);
3147 	wrapped_data_buf = NULL;
3148 	wpabuf_free(pubkey);
3149 	pubkey = NULL;
3150 
3151 	/* Add RSNXE if needed */
3152 	rsnxe_ie = hostapd_wpa_ie(hapd, WLAN_EID_RSNX);
3153 	if (rsnxe_ie)
3154 		wpabuf_put_data(buf, rsnxe_ie, 2 + rsnxe_ie[1]);
3155 
3156 	/* Add the mic */
3157 	mic_len = pasn_mic_len(sta->pasn->akmp, sta->pasn->cipher);
3158 	wpabuf_put_u8(buf, WLAN_EID_MIC);
3159 	wpabuf_put_u8(buf, mic_len);
3160 	ptr = wpabuf_put(buf, mic_len);
3161 
3162 	os_memset(ptr, 0, mic_len);
3163 
3164 	frame = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
3165 	frame_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
3166 
3167 	rsn_ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &rsn_ie_len);
3168 	if (!rsn_ie || !rsn_ie_len)
3169 		goto fail;
3170 
3171 	/*
3172 	 * Note: wpa_auth_get_wpa_ie() might return not only the RSNE but also
3173 	 * MDE, etc. Thus, do not use the returned length but instead use the
3174 	 * length specified in the IE header.
3175 	 */
3176 	data_len = rsn_ie[1] + 2;
3177 	if (rsnxe_ie) {
3178 		data_buf = os_zalloc(rsn_ie[1] + 2 + rsnxe_ie[1] + 2);
3179 		if (!data_buf)
3180 			goto fail;
3181 
3182 		os_memcpy(data_buf, rsn_ie, rsn_ie[1] + 2);
3183 		os_memcpy(data_buf + rsn_ie[1] + 2, rsnxe_ie, rsnxe_ie[1] + 2);
3184 		data_len += rsnxe_ie[1] + 2;
3185 		data = data_buf;
3186 	} else {
3187 		data = rsn_ie;
3188 	}
3189 
3190 	ret = pasn_mic(sta->pasn->ptk.kck, sta->pasn->akmp, sta->pasn->cipher,
3191 		       hapd->own_addr, sta->addr, data, data_len,
3192 		       frame, frame_len, mic);
3193 	os_free(data_buf);
3194 	if (ret) {
3195 		wpa_printf(MSG_DEBUG, "PASN: Frame 3: Failed MIC calculation");
3196 		goto fail;
3197 	}
3198 
3199 #ifdef CONFIG_TESTING_OPTIONS
3200 	if (hapd->conf->pasn_corrupt_mic) {
3201 		wpa_printf(MSG_DEBUG, "PASN: frame 2: Corrupt MIC");
3202 		mic[0] = ~mic[0];
3203 	}
3204 #endif /* CONFIG_TESTING_OPTIONS */
3205 
3206 	os_memcpy(ptr, mic, mic_len);
3207 
3208 done:
3209 	wpa_printf(MSG_DEBUG,
3210 		   "PASN: Building frame 2: success; resp STA=" MACSTR,
3211 		   MAC2STR(sta->addr));
3212 
3213 	ret = hostapd_drv_send_mlme(hapd, wpabuf_head(buf), wpabuf_len(buf), 0,
3214 				    NULL, 0, 0);
3215 	if (ret)
3216 		wpa_printf(MSG_INFO, "send_auth_reply: Send failed");
3217 
3218 	wpabuf_free(buf);
3219 	return ret;
3220 fail:
3221 	wpabuf_free(wrapped_data_buf);
3222 	wpabuf_free(pubkey);
3223 	wpabuf_free(buf);
3224 	return -1;
3225 }
3226 
3227 
3228 static void handle_auth_pasn_1(struct hostapd_data *hapd, struct sta_info *sta,
3229 			       const struct ieee80211_mgmt *mgmt, size_t len)
3230 {
3231 	struct ieee802_11_elems elems;
3232 	struct wpa_ie_data rsn_data;
3233 	struct wpa_pasn_params_data pasn_params;
3234 	struct rsn_pmksa_cache_entry *pmksa = NULL;
3235 	const u8 *cached_pmk = NULL;
3236 	size_t cached_pmk_len = 0;
3237 #ifdef CONFIG_IEEE80211R_AP
3238 	u8 pmk_r1[PMK_LEN_MAX];
3239 	size_t pmk_r1_len;
3240 #endif /* CONFIG_IEEE80211R_AP */
3241 	struct wpabuf *wrapped_data = NULL, *secret = NULL;
3242 	const int *groups = hapd->conf->pasn_groups;
3243 	static const int default_groups[] = { 19, 0 };
3244 	u16 status = WLAN_STATUS_SUCCESS;
3245 	int ret, inc_y;
3246 	bool derive_keys;
3247 	u32 i;
3248 
3249 	if (!groups)
3250 		groups = default_groups;
3251 
3252 	if (ieee802_11_parse_elems(mgmt->u.auth.variable,
3253 				   len - offsetof(struct ieee80211_mgmt,
3254 						  u.auth.variable),
3255 				   &elems, 0) == ParseFailed) {
3256 		wpa_printf(MSG_DEBUG,
3257 			   "PASN: Failed parsing Authentication frame");
3258 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3259 		goto send_resp;
3260 	}
3261 
3262 	ret = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
3263 				   &rsn_data);
3264 	if (ret) {
3265 		wpa_printf(MSG_DEBUG, "PASN: Failed parsing RNSE");
3266 		status = WLAN_STATUS_INVALID_RSNIE;
3267 		goto send_resp;
3268 	}
3269 
3270 	ret = wpa_pasn_validate_rsne(&rsn_data);
3271 	if (ret) {
3272 		wpa_printf(MSG_DEBUG, "PASN: Failed validating RSNE");
3273 		status = WLAN_STATUS_INVALID_RSNIE;
3274 		goto send_resp;
3275 	}
3276 
3277 	if (!(rsn_data.key_mgmt & hapd->conf->wpa_key_mgmt) ||
3278 	    !(rsn_data.pairwise_cipher & hapd->conf->rsn_pairwise)) {
3279 		wpa_printf(MSG_DEBUG, "PASN: Mismatch in AKMP/cipher");
3280 		status = WLAN_STATUS_INVALID_RSNIE;
3281 		goto send_resp;
3282 	}
3283 
3284 	sta->pasn->akmp = rsn_data.key_mgmt;
3285 	sta->pasn->cipher = rsn_data.pairwise_cipher;
3286 
3287 	if (hapd->conf->force_kdk_derivation ||
3288 	    ((hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF) &&
3289 	     ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
3290 				       WLAN_RSNX_CAPAB_SECURE_LTF)))
3291 		sta->pasn->kdk_len = WPA_KDK_MAX_LEN;
3292 	else
3293 		sta->pasn->kdk_len = 0;
3294 	wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", sta->pasn->kdk_len);
3295 
3296 	if (!elems.pasn_params || !elems.pasn_params_len) {
3297 		wpa_printf(MSG_DEBUG,
3298 			   "PASN: No PASN Parameters element found");
3299 		status = WLAN_STATUS_INVALID_PARAMETERS;
3300 		goto send_resp;
3301 	}
3302 
3303 	ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
3304 					  elems.pasn_params_len + 3,
3305 					  false, &pasn_params);
3306 	if (ret) {
3307 		wpa_printf(MSG_DEBUG,
3308 			   "PASN: Failed validation of PASN Parameters IE");
3309 		status = WLAN_STATUS_INVALID_PARAMETERS;
3310 		goto send_resp;
3311 	}
3312 
3313 	for (i = 0; groups[i] > 0 && groups[i] != pasn_params.group; i++)
3314 		;
3315 
3316 	if (!pasn_params.group || groups[i] != pasn_params.group) {
3317 		wpa_printf(MSG_DEBUG, "PASN: Requested group=%hu not allowed",
3318 			   pasn_params.group);
3319 		status = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
3320 		goto send_resp;
3321 	}
3322 
3323 	if (!pasn_params.pubkey || !pasn_params.pubkey_len) {
3324 		wpa_printf(MSG_DEBUG, "PASN: Invalid public key");
3325 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3326 		goto send_resp;
3327 	}
3328 
3329 	if (pasn_params.comeback) {
3330 		wpa_printf(MSG_DEBUG, "PASN: Checking peer comeback token");
3331 
3332 		ret = check_comeback_token(hapd, sta->addr,
3333 					   pasn_params.comeback,
3334 					   pasn_params.comeback_len);
3335 
3336 		if (ret) {
3337 			wpa_printf(MSG_DEBUG, "PASN: Invalid comeback token");
3338 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3339 			goto send_resp;
3340 		}
3341 	} else if (use_anti_clogging(hapd)) {
3342 		wpa_printf(MSG_DEBUG, "PASN: Respond with comeback");
3343 		handle_auth_pasn_comeback(hapd, sta, pasn_params.group);
3344 		ap_free_sta(hapd, sta);
3345 		return;
3346 	}
3347 
3348 	sta->pasn->ecdh = crypto_ecdh_init(pasn_params.group);
3349 	if (!sta->pasn->ecdh) {
3350 		wpa_printf(MSG_DEBUG, "PASN: Failed to init ECDH");
3351 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3352 		goto send_resp;
3353 	}
3354 
3355 	sta->pasn->group = pasn_params.group;
3356 
3357 	if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_UNCOMPRESSED) {
3358 		inc_y = 1;
3359 	} else if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_0 ||
3360 		   pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_1) {
3361 		inc_y = 0;
3362 	} else {
3363 		wpa_printf(MSG_DEBUG,
3364 			   "PASN: Invalid first octet in pubkey=0x%x",
3365 			   pasn_params.pubkey[0]);
3366 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3367 		goto send_resp;
3368 	}
3369 
3370 	secret = crypto_ecdh_set_peerkey(sta->pasn->ecdh, inc_y,
3371 					 pasn_params.pubkey + 1,
3372 					 pasn_params.pubkey_len - 1);
3373 	if (!secret) {
3374 		wpa_printf(MSG_DEBUG, "PASN: Failed to derive shared secret");
3375 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3376 		goto send_resp;
3377 	}
3378 
3379 	derive_keys = true;
3380 	if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
3381 		wrapped_data = ieee802_11_defrag(&elems,
3382 						 WLAN_EID_EXTENSION,
3383 						 WLAN_EID_EXT_WRAPPED_DATA);
3384 		if (!wrapped_data) {
3385 			wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
3386 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3387 			goto send_resp;
3388 		}
3389 
3390 #ifdef CONFIG_SAE
3391 		if (sta->pasn->akmp == WPA_KEY_MGMT_SAE) {
3392 			ret = pasn_wd_handle_sae_commit(hapd, sta,
3393 							wrapped_data);
3394 			if (ret) {
3395 				wpa_printf(MSG_DEBUG,
3396 					   "PASN: Failed processing SAE commit");
3397 				status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3398 				goto send_resp;
3399 			}
3400 		}
3401 #endif /* CONFIG_SAE */
3402 #ifdef CONFIG_FILS
3403 		if (sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
3404 		    sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
3405 			ret = pasn_wd_handle_fils(hapd, sta, wrapped_data);
3406 			if (ret) {
3407 				wpa_printf(MSG_DEBUG,
3408 					   "PASN: Failed processing FILS wrapped data");
3409 				status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3410 				goto send_resp;
3411 			}
3412 
3413 			wpa_printf(MSG_DEBUG,
3414 				   "PASN: FILS: Pending AS response");
3415 
3416 			/*
3417 			 * With PASN/FILS, keys can be derived only after a
3418 			 * response from the AS is processed.
3419 			 */
3420 			derive_keys = false;
3421 		}
3422 #endif /* CONFIG_FILS */
3423 	}
3424 
3425 	sta->pasn->wrapped_data_format = pasn_params.wrapped_data_format;
3426 
3427 	ret = pasn_auth_frame_hash(sta->pasn->akmp, sta->pasn->cipher,
3428 				   ((const u8 *) mgmt) + IEEE80211_HDRLEN,
3429 				   len - IEEE80211_HDRLEN, sta->pasn->hash);
3430 	if (ret) {
3431 		wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
3432 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3433 		goto send_resp;
3434 	}
3435 
3436 	if (!derive_keys) {
3437 		wpa_printf(MSG_DEBUG, "PASN: Storing secret");
3438 		sta->pasn->secret = secret;
3439 		wpabuf_free(wrapped_data);
3440 		return;
3441 	}
3442 
3443 	if (rsn_data.num_pmkid) {
3444 		if (wpa_key_mgmt_ft(sta->pasn->akmp)) {
3445 #ifdef CONFIG_IEEE80211R_AP
3446 			wpa_printf(MSG_DEBUG, "PASN: FT: Fetch PMK-R1");
3447 
3448 			ret = wpa_ft_fetch_pmk_r1(hapd->wpa_auth, sta->addr,
3449 						  rsn_data.pmkid,
3450 						  pmk_r1, &pmk_r1_len, NULL,
3451 						  NULL, NULL, NULL,
3452 						  NULL, NULL, NULL);
3453 			if (ret) {
3454 				wpa_printf(MSG_DEBUG,
3455 					   "PASN: FT: Failed getting PMK-R1");
3456 				status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3457 				goto send_resp;
3458 			}
3459 			cached_pmk = pmk_r1;
3460 			cached_pmk_len = pmk_r1_len;
3461 #else /* CONFIG_IEEE80211R_AP */
3462 			wpa_printf(MSG_DEBUG, "PASN: FT: Not supported");
3463 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3464 			goto send_resp;
3465 #endif /* CONFIG_IEEE80211R_AP */
3466 		} else {
3467 			wpa_printf(MSG_DEBUG, "PASN: Try to find PMKSA entry");
3468 
3469 			pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr,
3470 						   rsn_data.pmkid);
3471 			if (pmksa) {
3472 				cached_pmk = pmksa->pmk;
3473 				cached_pmk_len = pmksa->pmk_len;
3474 			}
3475 		}
3476 	} else {
3477 		wpa_printf(MSG_DEBUG, "PASN: No PMKID specified");
3478 	}
3479 
3480 	ret = pasn_derive_keys(hapd, sta, cached_pmk, cached_pmk_len,
3481 			       &pasn_params, wrapped_data, secret);
3482 	if (ret) {
3483 		wpa_printf(MSG_DEBUG, "PASN: Failed to derive keys");
3484 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3485 		goto send_resp;
3486 	}
3487 
3488 	ret = pasn_auth_frame_hash(sta->pasn->akmp, sta->pasn->cipher,
3489 				   ((const u8 *) mgmt) + IEEE80211_HDRLEN,
3490 				   len - IEEE80211_HDRLEN, sta->pasn->hash);
3491 	if (ret) {
3492 		wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
3493 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3494 	}
3495 
3496 send_resp:
3497 	ret = handle_auth_pasn_resp(hapd, sta, pmksa, status);
3498 	if (ret) {
3499 		wpa_printf(MSG_DEBUG, "PASN: Failed to send response");
3500 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3501 	} else {
3502 		wpa_printf(MSG_DEBUG,
3503 			   "PASN: Success handling transaction == 1");
3504 	}
3505 
3506 	wpabuf_free(secret);
3507 	wpabuf_free(wrapped_data);
3508 
3509 	if (status != WLAN_STATUS_SUCCESS)
3510 		ap_free_sta(hapd, sta);
3511 }
3512 
3513 
3514 static void handle_auth_pasn_3(struct hostapd_data *hapd, struct sta_info *sta,
3515 			       const struct ieee80211_mgmt *mgmt, size_t len)
3516 {
3517 	struct ieee802_11_elems elems;
3518 	struct wpa_pasn_params_data pasn_params;
3519 	struct wpabuf *wrapped_data = NULL;
3520 	u8 mic[WPA_PASN_MAX_MIC_LEN], out_mic[WPA_PASN_MAX_MIC_LEN];
3521 	u8 mic_len;
3522 	int ret;
3523 
3524 	if (ieee802_11_parse_elems(mgmt->u.auth.variable,
3525 				   len - offsetof(struct ieee80211_mgmt,
3526 						  u.auth.variable),
3527 				   &elems, 0) == ParseFailed) {
3528 		wpa_printf(MSG_DEBUG,
3529 			   "PASN: Failed parsing Authentication frame");
3530 		goto fail;
3531 	}
3532 
3533 	/* Check that the MIC IE exists. Save it and zero out the memory. */
3534 	mic_len = pasn_mic_len(sta->pasn->akmp, sta->pasn->cipher);
3535 	if (!elems.mic || elems.mic_len != mic_len) {
3536 		wpa_printf(MSG_DEBUG,
3537 			   "PASN: Invalid MIC. Expecting len=%u", mic_len);
3538 		goto fail;
3539 	} else {
3540 		os_memcpy(mic, elems.mic, mic_len);
3541 		/* TODO: Clean this up.. Should not modify received frame
3542 		 * buffer. */
3543 		os_memset((u8 *) elems.mic, 0, mic_len);
3544 	}
3545 
3546 	if (!elems.pasn_params || !elems.pasn_params_len) {
3547 		wpa_printf(MSG_DEBUG,
3548 			   "PASN: No PASN Parameters element found");
3549 		goto fail;
3550 	}
3551 
3552 	ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
3553 					  elems.pasn_params_len + 3,
3554 					  false, &pasn_params);
3555 	if (ret) {
3556 		wpa_printf(MSG_DEBUG,
3557 			   "PASN: Failed validation of PASN Parameters IE");
3558 		goto fail;
3559 	}
3560 
3561 	if (pasn_params.pubkey || pasn_params.pubkey_len) {
3562 		wpa_printf(MSG_DEBUG,
3563 			   "PASN: Public key should not be included");
3564 		goto fail;
3565 	}
3566 
3567 	/* Verify the MIC */
3568 	ret = pasn_mic(sta->pasn->ptk.kck, sta->pasn->akmp, sta->pasn->cipher,
3569 		       sta->addr, hapd->own_addr,
3570 		       sta->pasn->hash, mic_len * 2,
3571 		       (u8 *) &mgmt->u.auth,
3572 		       len - offsetof(struct ieee80211_mgmt, u.auth),
3573 		       out_mic);
3574 
3575 	wpa_hexdump_key(MSG_DEBUG, "PASN: Frame MIC", mic, mic_len);
3576 	if (ret || os_memcmp(mic, out_mic, mic_len) != 0) {
3577 		wpa_printf(MSG_DEBUG, "PASN: Failed MIC verification");
3578 		goto fail;
3579 	}
3580 
3581 	if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
3582 		wrapped_data = ieee802_11_defrag(&elems,
3583 						 WLAN_EID_EXTENSION,
3584 						 WLAN_EID_EXT_WRAPPED_DATA);
3585 
3586 		if (!wrapped_data) {
3587 			wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
3588 			goto fail;
3589 		}
3590 
3591 #ifdef CONFIG_SAE
3592 		if (sta->pasn->akmp == WPA_KEY_MGMT_SAE) {
3593 			ret = pasn_wd_handle_sae_confirm(hapd, sta,
3594 							 wrapped_data);
3595 			if (ret) {
3596 				wpa_printf(MSG_DEBUG,
3597 					   "PASN: Failed processing SAE confirm");
3598 				wpabuf_free(wrapped_data);
3599 				goto fail;
3600 			}
3601 		}
3602 #endif /* CONFIG_SAE */
3603 #ifdef CONFIG_FILS
3604 		if (sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
3605 		    sta->pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
3606 			if (wrapped_data) {
3607 				wpa_printf(MSG_DEBUG,
3608 					   "PASN: FILS: Ignore wrapped data");
3609 			}
3610 		}
3611 #endif /* CONFIG_FILS */
3612 		wpabuf_free(wrapped_data);
3613 	}
3614 
3615 	wpa_printf(MSG_INFO,
3616 		   "PASN: Success handling transaction == 3. Store PTK");
3617 
3618 	ptksa_cache_add(hapd->ptksa, sta->addr, sta->pasn->cipher, 43200,
3619 			&sta->pasn->ptk);
3620 fail:
3621 	ap_free_sta(hapd, sta);
3622 }
3623 
3624 
3625 static void handle_auth_pasn(struct hostapd_data *hapd, struct sta_info *sta,
3626 			     const struct ieee80211_mgmt *mgmt, size_t len,
3627 			     u16 trans_seq, u16 status)
3628 {
3629 	if (hapd->conf->wpa != WPA_PROTO_RSN) {
3630 		wpa_printf(MSG_INFO, "PASN: RSN is not configured");
3631 		return;
3632 	}
3633 
3634 	wpa_printf(MSG_INFO, "PASN authentication: sta=" MACSTR,
3635 		   MAC2STR(sta->addr));
3636 
3637 	if (trans_seq == 1) {
3638 		if (sta->pasn) {
3639 			wpa_printf(MSG_DEBUG,
3640 				   "PASN: Not expecting transaction == 1");
3641 			return;
3642 		}
3643 
3644 		if (status != WLAN_STATUS_SUCCESS) {
3645 			wpa_printf(MSG_DEBUG,
3646 				   "PASN: Failure status in transaction == 1");
3647 			return;
3648 		}
3649 
3650 		sta->pasn = os_zalloc(sizeof(*sta->pasn));
3651 		if (!sta->pasn) {
3652 			wpa_printf(MSG_DEBUG,
3653 				   "PASN: Failed to allocate PASN context");
3654 			return;
3655 		}
3656 
3657 		handle_auth_pasn_1(hapd, sta, mgmt, len);
3658 	} else if (trans_seq == 3) {
3659 		if (!sta->pasn) {
3660 			wpa_printf(MSG_DEBUG,
3661 				   "PASN: Not expecting transaction == 3");
3662 			return;
3663 		}
3664 
3665 		if (status != WLAN_STATUS_SUCCESS) {
3666 			wpa_printf(MSG_DEBUG,
3667 				   "PASN: Failure status in transaction == 3");
3668 			ap_free_sta_pasn(hapd, sta);
3669 			return;
3670 		}
3671 
3672 		handle_auth_pasn_3(hapd, sta, mgmt, len);
3673 	} else {
3674 		wpa_printf(MSG_DEBUG,
3675 			   "PASN: Invalid transaction %u - ignore", trans_seq);
3676 	}
3677 }
3678 
3679 #endif /* CONFIG_PASN */
3680 
3681 #ifdef LOS_CONFIG_HOSTAPD_MGMT
3682 static void handle_auth(struct hostapd_data *hapd,
3683 			const struct ieee80211_mgmt *mgmt, size_t len,
3684 			int rssi, int from_queue)
3685 {
3686 	u16 auth_alg, auth_transaction, status_code;
3687 	u16 resp = WLAN_STATUS_SUCCESS;
3688 	struct sta_info *sta = NULL;
3689 	int res, reply_res;
3690 	u16 fc;
3691 	const u8 *challenge = NULL;
3692 	u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
3693 	size_t resp_ies_len = 0;
3694 	u16 seq_ctrl;
3695 #ifndef EXT_CODE_CROP
3696 	struct radius_sta rad_info;
3697 #endif /* EXT_CODE_CROP */
3698 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
3699 		wpa_warning_log1(MSG_INFO, "handle_auth - too short payload (len=%lu)",
3700 			   (unsigned long) len);
3701 		return;
3702 	}
3703 
3704 #ifdef CONFIG_TESTING_OPTIONS
3705 	if (hapd->iconf->ignore_auth_probability > 0.0 &&
3706 	    drand48() < hapd->iconf->ignore_auth_probability) {
3707 		wpa_printf(MSG_INFO,
3708 			   "TESTING: ignoring auth frame from " MACSTR,
3709 			   MAC2STR(mgmt->sa));
3710 		return;
3711 	}
3712 #endif /* CONFIG_TESTING_OPTIONS */
3713 
3714 	auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
3715 	auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
3716 	status_code = le_to_host16(mgmt->u.auth.status_code);
3717 	fc = le_to_host16(mgmt->frame_control);
3718 	seq_ctrl = le_to_host16(mgmt->seq_ctrl);
3719 
3720 	if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
3721 	    2 + WLAN_AUTH_CHALLENGE_LEN &&
3722 	    mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
3723 	    mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
3724 		challenge = &mgmt->u.auth.variable[2];
3725 
3726 	wpa_warning_log4(MSG_DEBUG, "authentication: STA=" "%02x:xx:xx:%02x:%02x:%02x",
3727 		   (mgmt->sa)[0], (mgmt->sa)[3], (mgmt->sa)[4], (mgmt->sa)[5]);
3728 	wpa_error_log4(MSG_DEBUG, "authentication: STA=" " auth_alg=%d "
3729 		   "auth_transaction=%d status_code=%d wep=%d",
3730 		   auth_alg, auth_transaction,
3731 		   status_code, !!(fc & WLAN_FC_ISWEP));
3732 	wpa_warning_log1(MSG_DEBUG, "authentication: STA=" "seq_ctrl=0x%x", seq_ctrl);
3733 
3734 #ifdef CONFIG_NO_RC4
3735 	if (auth_alg == WLAN_AUTH_SHARED_KEY) {
3736 		wpa_printf(MSG_INFO,
3737 			   "Unsupported authentication algorithm (%d)",
3738 			   auth_alg);
3739 		resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
3740 		goto fail;
3741 	}
3742 #endif /* CONFIG_NO_RC4 */
3743 
3744 #ifndef LOS_CONFIG_HOSTAPD_TKIP_MIC
3745 	if (hapd->tkip_countermeasures) {
3746 		wpa_warning_log0(MSG_DEBUG,
3747 			   "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
3748 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3749 		goto fail;
3750 	}
3751 #endif /* LOS_CONFIG_HOSTAPD_TKIP_MIC */
3752 
3753 	if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
3754 	       auth_alg == WLAN_AUTH_OPEN) ||
3755 #ifdef CONFIG_IEEE80211R_AP
3756 	      (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) &&
3757 	       auth_alg == WLAN_AUTH_FT) ||
3758 #endif /* CONFIG_IEEE80211R_AP */
3759 #ifdef CONFIG_SAE
3760 	      (hapd->conf->wpa && wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
3761 	       auth_alg == WLAN_AUTH_SAE) ||
3762 #endif /* CONFIG_SAE */
3763 #ifdef CONFIG_FILS
3764 	      (hapd->conf->wpa && wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt) &&
3765 	       auth_alg == WLAN_AUTH_FILS_SK) ||
3766 	      (hapd->conf->wpa && wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt) &&
3767 	       hapd->conf->fils_dh_group &&
3768 	       auth_alg == WLAN_AUTH_FILS_SK_PFS) ||
3769 #endif /* CONFIG_FILS */
3770 #ifdef CONFIG_PASN
3771 	      (hapd->conf->wpa &&
3772 	       (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_PASN) &&
3773 	       auth_alg == WLAN_AUTH_PASN) ||
3774 #endif /* CONFIG_PASN */
3775 	      ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
3776 	       auth_alg == WLAN_AUTH_SHARED_KEY))) {
3777 		wpa_warning_log1(MSG_INFO, "Unsupported authentication algorithm (%d)",
3778 			   auth_alg);
3779 		resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
3780 		goto fail;
3781 	}
3782 
3783 	if (!(auth_transaction == 1 || auth_alg == WLAN_AUTH_SAE ||
3784 #ifdef CONFIG_PASN
3785 	      (auth_alg == WLAN_AUTH_PASN && auth_transaction == 3) ||
3786 #endif /* CONFIG_PASN */
3787 	      (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
3788 		wpa_warning_log1(MSG_INFO, "Unknown authentication transaction number (%d)",
3789 			   auth_transaction);
3790 		resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
3791 		goto fail;
3792 	}
3793 
3794 	if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
3795 		wpa_warning_log4(MSG_INFO, "Station " "%02x:xx:xx:%02x:%02x:%02x" " not allowed to authenticate",
3796 			   (mgmt->sa)[0], (mgmt->sa)[3], (mgmt->sa)[4], (mgmt->sa)[5]);
3797 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3798 		goto fail;
3799 	}
3800 
3801 #ifndef EXT_CODE_CROP
3802 	if (hapd->conf->no_auth_if_seen_on) {
3803 		struct hostapd_data *other;
3804 
3805 		other = sta_track_seen_on(hapd->iface, mgmt->sa,
3806 					  hapd->conf->no_auth_if_seen_on);
3807 		if (other) {
3808 			u8 *pos;
3809 			u32 info;
3810 			u8 op_class, channel, phytype;
3811 
3812 			wpa_printf(MSG_DEBUG, "%s: Reject authentication from "
3813 				   MACSTR " since STA has been seen on %s",
3814 				   hapd->conf->iface, MAC2STR(mgmt->sa),
3815 				   hapd->conf->no_auth_if_seen_on);
3816 
3817 			resp = WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION;
3818 			pos = &resp_ies[0];
3819 			*pos++ = WLAN_EID_NEIGHBOR_REPORT;
3820 			*pos++ = 13;
3821 			os_memcpy(pos, other->own_addr, ETH_ALEN);
3822 			pos += ETH_ALEN;
3823 			info = 0; /* TODO: BSSID Information */
3824 			WPA_PUT_LE32(pos, info);
3825 			pos += 4;
3826 			if (other->iconf->hw_mode == HOSTAPD_MODE_IEEE80211AD)
3827 				phytype = 8; /* dmg */
3828 			else if (other->iconf->ieee80211ac)
3829 				phytype = 9; /* vht */
3830 			else if (other->iconf->ieee80211n)
3831 				phytype = 7; /* ht */
3832 			else if (other->iconf->hw_mode ==
3833 				 HOSTAPD_MODE_IEEE80211A)
3834 				phytype = 4; /* ofdm */
3835 			else if (other->iconf->hw_mode ==
3836 				 HOSTAPD_MODE_IEEE80211G)
3837 				phytype = 6; /* erp */
3838 			else
3839 				phytype = 5; /* hrdsss */
3840 			if (ieee80211_freq_to_channel_ext(
3841 				    hostapd_hw_get_freq(other,
3842 							other->iconf->channel),
3843 				    other->iconf->secondary_channel,
3844 				    other->iconf->ieee80211ac,
3845 				    &op_class, &channel) == NUM_HOSTAPD_MODES) {
3846 				op_class = 0;
3847 				channel = other->iconf->channel;
3848 			}
3849 			*pos++ = op_class;
3850 			*pos++ = channel;
3851 			*pos++ = phytype;
3852 			resp_ies_len = pos - &resp_ies[0];
3853 			goto fail;
3854 		}
3855 	}
3856 
3857 	res = ieee802_11_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len,
3858 					 &rad_info);
3859 	if (res == HOSTAPD_ACL_REJECT) {
3860 		wpa_msg(hapd->msg_ctx, MSG_DEBUG,
3861 			"Ignore Authentication frame from " MACSTR
3862 			" due to ACL reject", MAC2STR(mgmt->sa));
3863 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3864 		goto fail;
3865 	}
3866 	if (res == HOSTAPD_ACL_PENDING)
3867 		return;
3868 
3869 #endif /* EXT_CODE_CROP */
3870 #ifdef CONFIG_SAE
3871 	if (auth_alg == WLAN_AUTH_SAE && !from_queue &&
3872 	    (auth_transaction == 1 ||
3873 	     (auth_transaction == 2 && auth_sae_queued_addr(hapd, mgmt->sa)))) {
3874 		/* Handle SAE Authentication commit message through a queue to
3875 		 * provide more control for postponing the needed heavy
3876 		 * processing under a possible DoS attack scenario. In addition,
3877 		 * queue SAE Authentication confirm message if there happens to
3878 		 * be a queued commit message from the same peer. This is needed
3879 		 * to avoid reordering Authentication frames within the same
3880 		 * SAE exchange. */
3881 		auth_sae_queue(hapd, mgmt, len, rssi);
3882 		return;
3883 	}
3884 #endif /* CONFIG_SAE */
3885 
3886 	sta = ap_get_sta(hapd, mgmt->sa);
3887 	if (sta) {
3888 		sta->flags &= ~WLAN_STA_PENDING_FILS_ERP;
3889 		sta->ft_over_ds = 0;
3890 		if ((fc & WLAN_FC_RETRY) &&
3891 		    sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
3892 		    sta->last_seq_ctrl == seq_ctrl &&
3893 		    sta->last_subtype == WLAN_FC_STYPE_AUTH) {
3894 			hostapd_logger(hapd, sta->addr,
3895 				       HOSTAPD_MODULE_IEEE80211,
3896 				       HOSTAPD_LEVEL_DEBUG,
3897 				       "Drop repeated authentication frame seq_ctrl=0x%x",
3898 				       seq_ctrl);
3899 			return;
3900 		}
3901 #ifdef CONFIG_MESH
3902 		if ((hapd->conf->mesh & MESH_ENABLED) &&
3903 		    sta->plink_state == PLINK_BLOCKED) {
3904 			wpa_warning_log4(MSG_DEBUG, "Mesh peer " "%02x:xx:xx:%02x:%02x:%02x"
3905 				   " is blocked - drop Authentication frame",
3906 				   (mgmt->sa)[0], (mgmt->sa)[3], (mgmt->sa)[4], (mgmt->sa)[5]);
3907 
3908 			return;
3909 		}
3910 #endif /* CONFIG_MESH */
3911 #ifdef CONFIG_PASN
3912 		if (auth_alg == WLAN_AUTH_PASN &&
3913 		    (sta->flags & WLAN_STA_ASSOC)) {
3914 			wpa_printf(MSG_DEBUG,
3915 				   "PASN: auth: Existing station: " MACSTR,
3916 				   MAC2STR(sta->addr));
3917 			return;
3918 		}
3919 #endif /* CONFIG_PASN */
3920 	} else {
3921 #ifndef EXT_CODE_CROP
3922 #ifdef CONFIG_MESH
3923 		if (hapd->conf->mesh & MESH_ENABLED) {
3924 			/* if the mesh peer is not available, we don't do auth.
3925 			 */
3926 			wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
3927 				   " not yet known - drop Authentication frame",
3928 				   MAC2STR(mgmt->sa));
3929 			/*
3930 			 * Save a copy of the frame so that it can be processed
3931 			 * if a new peer entry is added shortly after this.
3932 			 */
3933 			wpabuf_free(hapd->mesh_pending_auth);
3934 			hapd->mesh_pending_auth = wpabuf_alloc_copy(mgmt, len);
3935 			os_get_reltime(&hapd->mesh_pending_auth_time);
3936 			return;
3937 		}
3938 #endif /* CONFIG_MESH */
3939 #endif /* EXT_CODE_CROP */
3940 
3941 #ifdef CONFIG_MESH
3942 		if ((hapd->conf->mesh & MESH_ENABLED) && (los_mesh_peer_connect_is_rejected())) {
3943 			wpa_error_log0(MSG_ERROR, "handle_auth: reject mesh peer now.");
3944 			goto fail;
3945 		}
3946 #endif /* CONFIG_MESH */
3947 		sta = ap_sta_add(hapd, mgmt->sa);
3948 		if (!sta) {
3949 			wpa_printf(MSG_DEBUG, "ap_sta_add() failed");
3950 			resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
3951 			goto fail;
3952 		}
3953 #ifdef LOS_CONFIG_MESH
3954 		/* soc insert into driver */
3955 		os_memset(&params, 0, sizeof(params));
3956 		params.addr = mgmt->sa;
3957 		if ((hapd->driver->sta_add == NULL) ||
3958 			((hapd->driver->sta_add != NULL) && (hapd->driver->sta_add(hapd->drv_priv, &params)))) {
3959 			wpa_error_log4(MSG_ERROR, "Driver failed to insert " "%02x:xx:xx:%02x:%02x:%02x", (mgmt->sa)[0], (mgmt->sa)[3], (mgmt->sa)[4], (mgmt->sa)[5]);
3960 			ap_free_sta(hapd, sta);
3961 			goto fail;
3962 		}
3963 #endif /* LOS_CONFIG_MESH */
3964 	}
3965 	sta->last_seq_ctrl = seq_ctrl;
3966 	sta->last_subtype = WLAN_FC_STYPE_AUTH;
3967 #ifdef CONFIG_MBO
3968 	sta->auth_rssi = rssi;
3969 #endif /* CONFIG_MBO */
3970 #ifndef EXT_CODE_CROP
3971 	res = ieee802_11_set_radius_info(hapd, sta, res, &rad_info);
3972 	if (res) {
3973 		wpa_printf(MSG_DEBUG, "ieee802_11_set_radius_info() failed");
3974 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
3975 		goto fail;
3976 	}
3977 #else
3978 	sta->psk = NULL;
3979 #endif /* EXT_CODE_CROP */
3980 	sta->flags &= ~WLAN_STA_PREAUTH;
3981 	ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
3982 
3983 	/*
3984 	 * If the driver supports full AP client state, add a station to the
3985 	 * driver before sending authentication reply to make sure the driver
3986 	 * has resources, and not to go through the entire authentication and
3987 	 * association handshake, and fail it at the end.
3988 	 *
3989 	 * If this is not the first transaction, in a multi-step authentication
3990 	 * algorithm, the station already exists in the driver
3991 	 * (sta->added_unassoc = 1) so skip it.
3992 	 *
3993 	 * In mesh mode, the station was already added to the driver when the
3994 	 * NEW_PEER_CANDIDATE event is received.
3995 	 *
3996 	 * If PMF was negotiated for the existing association, skip this to
3997 	 * avoid dropping the STA entry and the associated keys. This is needed
3998 	 * to allow the original connection work until the attempt can complete
3999 	 * (re)association, so that unprotected Authentication frame cannot be
4000 	 * used to bypass PMF protection.
4001 	 *
4002 	 * PASN authentication does not require adding/removing station to the
4003 	 * driver so skip this flow in case of PASN authentication.
4004 	 */
4005 #ifndef EXT_CODE_CROP
4006 	if (FULL_AP_CLIENT_STATE_SUPP(hapd->iface->drv_flags) &&
4007 	    (!(sta->flags & WLAN_STA_MFP) || !ap_sta_is_authorized(sta)) &&
4008 	    !(hapd->conf->mesh & MESH_ENABLED) &&
4009 	    !(sta->added_unassoc) && auth_alg != WLAN_AUTH_PASN) {
4010 		if (ap_sta_re_add(hapd, sta) < 0) {
4011 			resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
4012 			goto fail;
4013 		}
4014 	}
4015 #endif /* EXT_CODE_CROP */
4016 
4017 	switch (auth_alg) {
4018 	case WLAN_AUTH_OPEN:
4019 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4020 			       HOSTAPD_LEVEL_DEBUG,
4021 			       "authentication OK (open system)");
4022 		sta->flags |= WLAN_STA_AUTH;
4023 		wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
4024 		sta->auth_alg = WLAN_AUTH_OPEN;
4025 		mlme_authenticate_indication(hapd, sta);
4026 		break;
4027 #ifdef CONFIG_WEP
4028 #ifndef CONFIG_NO_RC4
4029 	case WLAN_AUTH_SHARED_KEY:
4030 		resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
4031 				       fc & WLAN_FC_ISWEP);
4032 		if (resp != 0)
4033 			wpa_printf(MSG_DEBUG,
4034 				   "auth_shared_key() failed: status=%d", resp);
4035 		sta->auth_alg = WLAN_AUTH_SHARED_KEY;
4036 		mlme_authenticate_indication(hapd, sta);
4037 		if (sta->challenge && auth_transaction == 1) {
4038 			resp_ies[0] = WLAN_EID_CHALLENGE;
4039 			resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
4040 			os_memcpy(resp_ies + 2, sta->challenge,
4041 				  WLAN_AUTH_CHALLENGE_LEN);
4042 			resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
4043 		}
4044 		break;
4045 #endif /* CONFIG_NO_RC4 */
4046 #endif /* CONFIG_WEP */
4047 #ifdef CONFIG_IEEE80211R_AP
4048 	case WLAN_AUTH_FT:
4049 		sta->auth_alg = WLAN_AUTH_FT;
4050 		if (sta->wpa_sm == NULL)
4051 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
4052 							sta->addr, NULL);
4053 		if (sta->wpa_sm == NULL) {
4054 			wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
4055 				   "state machine");
4056 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
4057 			goto fail;
4058 		}
4059 		wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid,
4060 				    auth_transaction, mgmt->u.auth.variable,
4061 				    len - IEEE80211_HDRLEN -
4062 				    sizeof(mgmt->u.auth),
4063 				    handle_auth_ft_finish, hapd);
4064 		/* handle_auth_ft_finish() callback will complete auth. */
4065 		return;
4066 #endif /* CONFIG_IEEE80211R_AP */
4067 #ifdef CONFIG_SAE
4068 	case WLAN_AUTH_SAE:
4069 #ifdef CONFIG_MESH
4070 		if (status_code == WLAN_STATUS_SUCCESS &&
4071 		    hapd->conf->mesh & MESH_ENABLED) {
4072 			if (sta->wpa_sm == NULL)
4073 				sta->wpa_sm =
4074 					wpa_auth_sta_init(hapd->wpa_auth,
4075 							  sta->addr, NULL);
4076 			if (sta->wpa_sm == NULL) {
4077 				wpa_warning_log0(MSG_DEBUG,
4078 					   "SAE: Failed to initialize WPA state machine");
4079 				resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
4080 				goto fail;
4081 			}
4082 		}
4083 #endif /* CONFIG_MESH */
4084 		handle_auth_sae(hapd, sta, mgmt, len, auth_transaction,
4085 				status_code);
4086 		return;
4087 #endif /* CONFIG_SAE */
4088 #ifdef CONFIG_FILS
4089 	case WLAN_AUTH_FILS_SK:
4090 	case WLAN_AUTH_FILS_SK_PFS:
4091 		handle_auth_fils(hapd, sta, mgmt->u.auth.variable,
4092 				 len - IEEE80211_HDRLEN - sizeof(mgmt->u.auth),
4093 				 auth_alg, auth_transaction, status_code,
4094 				 handle_auth_fils_finish);
4095 		return;
4096 #endif /* CONFIG_FILS */
4097 #ifdef CONFIG_PASN
4098 	case WLAN_AUTH_PASN:
4099 		handle_auth_pasn(hapd, sta, mgmt, len, auth_transaction,
4100 				 status_code);
4101 		return;
4102 #endif /* CONFIG_PASN */
4103 	}
4104 
4105  fail:
4106 #if (defined(LOS_CONFIG_HOSTAPD_MGMT) && defined(CONFIG_SAE))
4107 	reply_res = send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, auth_alg,
4108 				    auth_alg == WLAN_AUTH_SAE ?
4109 				    auth_transaction : auth_transaction + 1,
4110 				    resp, resp_ies, resp_ies_len,
4111 				    "handle-auth");
4112 
4113 	if (sta && sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
4114 					  reply_res != WLAN_STATUS_SUCCESS)) {
4115 		hostapd_drv_sta_remove(hapd, sta->addr);
4116 		sta->added_unassoc = 0;
4117 	}
4118 #else
4119 	if (sta && sta->added_unassoc) {
4120 		hostapd_drv_sta_remove(hapd, sta->addr);
4121 		sta->added_unassoc = 0;
4122 	}
4123 #endif /* defined(LOS_CONFIG_HOSTAPD_MGMT) && defined(CONFIG_SAE) */
4124 }
4125 #endif /* LOS_CONFIG_HOSTAPD_MGMT */
4126 
4127 int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
4128 {
4129 	int i, j = 32, aid;
4130 
4131 	/* get a unique AID */
4132 	if (sta->aid > 0) {
4133 		wpa_warning_log1(MSG_DEBUG, "  old AID %d", sta->aid);
4134 		return 0;
4135 	}
4136 
4137 #ifndef EXT_CODE_CROP
4138 	if (TEST_FAIL())
4139 		return -1;
4140 
4141 	for (i = 0; i < AID_WORDS; i++) {
4142 		if (hapd->sta_aid[i] == (u32) -1)
4143 			continue;
4144 		for (j = 0; j < 32; j++) {
4145 			if (!(hapd->sta_aid[i] & BIT(j)))
4146 				break;
4147 		}
4148 		if (j < 32)
4149 			break;
4150 	}
4151 	if (j == 32)
4152 		return -1;
4153 	aid = i * 32 + j + 1;
4154 	if (aid > 2007)
4155 		return -1;
4156 
4157 	sta->aid = aid;
4158 	hapd->sta_aid[i] |= BIT(j);
4159 #else
4160 	for (j = 0; j < 32; j++) {
4161 		if (!(hapd->sta_aid & BIT(j)))
4162 			break;
4163 	}
4164 	if (j == 32)
4165 		return -1;
4166 	aid = j + 1;
4167 	sta->aid = (u16)aid;
4168 	hapd->sta_aid |= BIT(j);
4169 #endif /* EXT_CODE_CROP */
4170 	wpa_warning_log1(MSG_DEBUG, "  new AID %d", sta->aid);
4171 	return 0;
4172 }
4173 
4174 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
4175 static u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta,
4176 		      const u8 *ssid_ie, size_t ssid_ie_len)
4177 {
4178 	if (ssid_ie == NULL)
4179 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4180 
4181 	if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
4182 	    os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
4183 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4184 			       HOSTAPD_LEVEL_INFO,
4185 			       "Station tried to associate with unknown SSID "
4186 			       "'%s'", wpa_ssid_txt(ssid_ie, ssid_ie_len));
4187 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4188 	}
4189 
4190 	return WLAN_STATUS_SUCCESS;
4191 }
4192 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
4193 
4194 
4195 #ifndef LOS_CONFIG_HOSTAPD_QOS
4196 static u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta,
4197 		     const u8 *wmm_ie, size_t wmm_ie_len)
4198 {
4199 	sta->flags &= ~WLAN_STA_WMM;
4200 	sta->qosinfo = 0;
4201 	if (wmm_ie && hapd->conf->wmm_enabled) {
4202 		struct wmm_information_element *wmm;
4203 
4204 		if (!hostapd_eid_wmm_valid(hapd, wmm_ie, wmm_ie_len)) {
4205 			hostapd_logger(hapd, sta->addr,
4206 				       HOSTAPD_MODULE_WPA,
4207 				       HOSTAPD_LEVEL_DEBUG,
4208 				       "invalid WMM element in association "
4209 				       "request");
4210 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
4211 		}
4212 
4213 		sta->flags |= WLAN_STA_WMM;
4214 		wmm = (struct wmm_information_element *) wmm_ie;
4215 		sta->qosinfo = wmm->qos_info;
4216 	}
4217 	return WLAN_STATUS_SUCCESS;
4218 }
4219 #endif /* LOS_CONFIG_HOSTAPD_QOS */
4220 
4221 #ifdef CONFIG_MULTI_AP
4222 static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta,
4223 			  const u8 *multi_ap_ie, size_t multi_ap_len)
4224 {
4225 	u8 multi_ap_value = 0;
4226 
4227 	sta->flags &= ~WLAN_STA_MULTI_AP;
4228 
4229 	if (!hapd->conf->multi_ap)
4230 		return WLAN_STATUS_SUCCESS;
4231 
4232 	if (multi_ap_ie) {
4233 		const u8 *multi_ap_subelem;
4234 
4235 		multi_ap_subelem = get_ie(multi_ap_ie + 4,
4236 					  multi_ap_len - 4,
4237 					  MULTI_AP_SUB_ELEM_TYPE);
4238 		if (multi_ap_subelem && multi_ap_subelem[1] == 1) {
4239 			multi_ap_value = multi_ap_subelem[2];
4240 		} else {
4241 			hostapd_logger(hapd, sta->addr,
4242 				       HOSTAPD_MODULE_IEEE80211,
4243 				       HOSTAPD_LEVEL_INFO,
4244 				       "Multi-AP IE has missing or invalid Multi-AP subelement");
4245 			return WLAN_STATUS_INVALID_IE;
4246 		}
4247 	}
4248 
4249 	if (multi_ap_value && multi_ap_value != MULTI_AP_BACKHAUL_STA)
4250 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4251 			       HOSTAPD_LEVEL_INFO,
4252 			       "Multi-AP IE with unexpected value 0x%02x",
4253 			       multi_ap_value);
4254 
4255 	if (!(multi_ap_value & MULTI_AP_BACKHAUL_STA)) {
4256 		if (hapd->conf->multi_ap & FRONTHAUL_BSS)
4257 			return WLAN_STATUS_SUCCESS;
4258 
4259 		hostapd_logger(hapd, sta->addr,
4260 			       HOSTAPD_MODULE_IEEE80211,
4261 			       HOSTAPD_LEVEL_INFO,
4262 			       "Non-Multi-AP STA tries to associate with backhaul-only BSS");
4263 		return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
4264 	}
4265 
4266 	if (!(hapd->conf->multi_ap & BACKHAUL_BSS))
4267 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4268 			       HOSTAPD_LEVEL_DEBUG,
4269 			       "Backhaul STA tries to associate with fronthaul-only BSS");
4270 
4271 	sta->flags |= WLAN_STA_MULTI_AP;
4272 	return WLAN_STATUS_SUCCESS;
4273 }
4274 #endif /* CONFIG_MULTI_AP */
4275 
4276 
4277 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
4278 static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
4279 			   struct ieee802_11_elems *elems)
4280 {
4281 #ifndef EXT_CODE_CROP
4282 	/* Supported rates not used in IEEE 802.11ad/DMG */
4283 	if (hapd->iface->current_mode &&
4284 	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211AD)
4285 		return WLAN_STATUS_SUCCESS;
4286 #endif
4287 #ifdef CONFIG_NO_HOSTAPD_LOGGER
4288 		(void)hapd;
4289 #endif
4290 	if (!elems->supp_rates) {
4291 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4292 			       HOSTAPD_LEVEL_DEBUG,
4293 			       "No supported rates element in AssocReq");
4294 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4295 	}
4296 
4297 	if (elems->supp_rates_len + elems->ext_supp_rates_len >
4298 	    sizeof(sta->supported_rates)) {
4299 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4300 			       HOSTAPD_LEVEL_DEBUG,
4301 			       "Invalid supported rates element length %d+%d",
4302 			       elems->supp_rates_len,
4303 			       elems->ext_supp_rates_len);
4304 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4305 	}
4306 
4307 	sta->supported_rates_len = merge_byte_arrays(
4308 		sta->supported_rates, sizeof(sta->supported_rates),
4309 		elems->supp_rates, elems->supp_rates_len,
4310 		elems->ext_supp_rates, elems->ext_supp_rates_len);
4311 
4312 	return WLAN_STATUS_SUCCESS;
4313 }
4314 
4315 
4316 static u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta,
4317 			   const u8 *ext_capab_ie, size_t ext_capab_ie_len)
4318 {
4319 	(void)hapd;
4320 #ifndef EXT_CODE_CROP
4321 #ifdef CONFIG_INTERWORKING
4322 	/* check for QoS Map support */
4323 	if (ext_capab_ie_len >= 5) {
4324 		if (ext_capab_ie[4] & 0x01)
4325 			sta->qos_map_enabled = 1;
4326 	}
4327 #endif /* CONFIG_INTERWORKING */
4328 #endif /* EXT_CODE_CROP */
4329 	if (ext_capab_ie_len > 0) {
4330 		sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2));
4331 		os_free(sta->ext_capability);
4332 		sta->ext_capability = os_malloc(1 + ext_capab_ie_len);
4333 		if (sta->ext_capability) {
4334 			sta->ext_capability[0] = ext_capab_ie_len;
4335 			os_memcpy(sta->ext_capability + 1, ext_capab_ie,
4336 				  ext_capab_ie_len);
4337 		}
4338 	}
4339 
4340 	return WLAN_STATUS_SUCCESS;
4341 }
4342 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
4343 
4344 #ifdef CONFIG_OWE
4345 
4346 static int owe_group_supported(struct hostapd_data *hapd, u16 group)
4347 {
4348 	int i;
4349 	int *groups = hapd->conf->owe_groups;
4350 
4351 	if (group != 19 && group != 20 && group != 21)
4352 		return 0;
4353 
4354 	if (!groups)
4355 		return 1;
4356 
4357 	for (i = 0; groups[i] > 0; i++) {
4358 		if (groups[i] == group)
4359 			return 1;
4360 	}
4361 
4362 	return 0;
4363 }
4364 
4365 
4366 static u16 owe_process_assoc_req(struct hostapd_data *hapd,
4367 				 struct sta_info *sta, const u8 *owe_dh,
4368 				 u8 owe_dh_len)
4369 {
4370 	struct wpabuf *secret, *pub, *hkey;
4371 	int res;
4372 	u8 prk[SHA512_MAC_LEN], pmkid[SHA512_MAC_LEN];
4373 	const char *info = "OWE Key Generation";
4374 	const u8 *addr[2];
4375 	size_t len[2];
4376 	u16 group;
4377 	size_t hash_len, prime_len;
4378 
4379 	if (wpa_auth_sta_get_pmksa(sta->wpa_sm)) {
4380 		wpa_printf(MSG_DEBUG, "OWE: Using PMKSA caching");
4381 		return WLAN_STATUS_SUCCESS;
4382 	}
4383 
4384 	group = WPA_GET_LE16(owe_dh);
4385 	if (!owe_group_supported(hapd, group)) {
4386 		wpa_printf(MSG_DEBUG, "OWE: Unsupported DH group %u", group);
4387 		return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
4388 	}
4389 	if (group == 19)
4390 		prime_len = 32;
4391 	else if (group == 20)
4392 		prime_len = 48;
4393 	else if (group == 21)
4394 		prime_len = 66;
4395 	else
4396 		return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
4397 
4398 	crypto_ecdh_deinit(sta->owe_ecdh);
4399 	sta->owe_ecdh = crypto_ecdh_init(group);
4400 	if (!sta->owe_ecdh)
4401 		return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
4402 	sta->owe_group = group;
4403 
4404 	secret = crypto_ecdh_set_peerkey(sta->owe_ecdh, 0, owe_dh + 2,
4405 					 owe_dh_len - 2);
4406 	secret = wpabuf_zeropad(secret, prime_len);
4407 	if (!secret) {
4408 		wpa_printf(MSG_DEBUG, "OWE: Invalid peer DH public key");
4409 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4410 	}
4411 	wpa_hexdump_buf_key(MSG_DEBUG, "OWE: DH shared secret", secret);
4412 
4413 	/* prk = HKDF-extract(C | A | group, z) */
4414 
4415 	pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
4416 	if (!pub) {
4417 		wpabuf_clear_free(secret);
4418 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4419 	}
4420 
4421 	/* PMKID = Truncate-128(Hash(C | A)) */
4422 	addr[0] = owe_dh + 2;
4423 	len[0] = owe_dh_len - 2;
4424 	addr[1] = wpabuf_head(pub);
4425 	len[1] = wpabuf_len(pub);
4426 	if (group == 19) {
4427 		res = sha256_vector(2, addr, len, pmkid);
4428 		hash_len = SHA256_MAC_LEN;
4429 	} else if (group == 20) {
4430 		res = sha384_vector(2, addr, len, pmkid);
4431 		hash_len = SHA384_MAC_LEN;
4432 	} else if (group == 21) {
4433 		res = sha512_vector(2, addr, len, pmkid);
4434 		hash_len = SHA512_MAC_LEN;
4435 	} else {
4436 		wpabuf_free(pub);
4437 		wpabuf_clear_free(secret);
4438 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4439 	}
4440 	pub = wpabuf_zeropad(pub, prime_len);
4441 	if (res < 0 || !pub) {
4442 		wpabuf_free(pub);
4443 		wpabuf_clear_free(secret);
4444 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4445 	}
4446 
4447 	hkey = wpabuf_alloc(owe_dh_len - 2 + wpabuf_len(pub) + 2);
4448 	if (!hkey) {
4449 		wpabuf_free(pub);
4450 		wpabuf_clear_free(secret);
4451 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4452 	}
4453 
4454 	wpabuf_put_data(hkey, owe_dh + 2, owe_dh_len - 2); /* C */
4455 	wpabuf_put_buf(hkey, pub); /* A */
4456 	wpabuf_free(pub);
4457 	wpabuf_put_le16(hkey, group); /* group */
4458 	if (group == 19)
4459 		res = hmac_sha256(wpabuf_head(hkey), wpabuf_len(hkey),
4460 				  wpabuf_head(secret), wpabuf_len(secret), prk);
4461 	else if (group == 20)
4462 		res = hmac_sha384(wpabuf_head(hkey), wpabuf_len(hkey),
4463 				  wpabuf_head(secret), wpabuf_len(secret), prk);
4464 	else if (group == 21)
4465 		res = hmac_sha512(wpabuf_head(hkey), wpabuf_len(hkey),
4466 				  wpabuf_head(secret), wpabuf_len(secret), prk);
4467 	wpabuf_clear_free(hkey);
4468 	wpabuf_clear_free(secret);
4469 	if (res < 0)
4470 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4471 
4472 	wpa_hexdump_key(MSG_DEBUG, "OWE: prk", prk, hash_len);
4473 
4474 	/* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
4475 
4476 	os_free(sta->owe_pmk);
4477 	sta->owe_pmk = os_malloc(hash_len);
4478 	if (!sta->owe_pmk) {
4479 		os_memset(prk, 0, SHA512_MAC_LEN);
4480 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4481 	}
4482 
4483 	if (group == 19)
4484 		res = hmac_sha256_kdf(prk, hash_len, NULL, (const u8 *) info,
4485 				      os_strlen(info), sta->owe_pmk, hash_len);
4486 	else if (group == 20)
4487 		res = hmac_sha384_kdf(prk, hash_len, NULL, (const u8 *) info,
4488 				      os_strlen(info), sta->owe_pmk, hash_len);
4489 	else if (group == 21)
4490 		res = hmac_sha512_kdf(prk, hash_len, NULL, (const u8 *) info,
4491 				      os_strlen(info), sta->owe_pmk, hash_len);
4492 	os_memset(prk, 0, SHA512_MAC_LEN);
4493 	if (res < 0) {
4494 		os_free(sta->owe_pmk);
4495 		sta->owe_pmk = NULL;
4496 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4497 	}
4498 	sta->owe_pmk_len = hash_len;
4499 
4500 	wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sta->owe_pmk, sta->owe_pmk_len);
4501 	wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, PMKID_LEN);
4502 #ifndef LOS_CONFIG_HOSTAPD_PMKSA_CROP
4503 	wpa_auth_pmksa_add2(hapd->wpa_auth, sta->addr, sta->owe_pmk,
4504 			    sta->owe_pmk_len, pmkid, 0, WPA_KEY_MGMT_OWE);
4505 #endif
4506 	return WLAN_STATUS_SUCCESS;
4507 }
4508 
4509 
4510 u16 owe_validate_request(struct hostapd_data *hapd, const u8 *peer,
4511 			 const u8 *rsn_ie, size_t rsn_ie_len,
4512 			 const u8 *owe_dh, size_t owe_dh_len)
4513 {
4514 	struct wpa_ie_data data;
4515 	int res;
4516 
4517 	if (!rsn_ie || rsn_ie_len < 2) {
4518 		wpa_printf(MSG_DEBUG, "OWE: Invalid RSNE from " MACSTR,
4519 			   MAC2STR(peer));
4520 		return WLAN_STATUS_INVALID_IE;
4521 	}
4522 	rsn_ie -= 2;
4523 	rsn_ie_len += 2;
4524 
4525 	res = wpa_parse_wpa_ie_rsn(rsn_ie, rsn_ie_len, &data);
4526 	if (res) {
4527 		wpa_printf(MSG_DEBUG, "Failed to parse RSNE from " MACSTR
4528 			   " (res=%d)", MAC2STR(peer), res);
4529 		wpa_hexdump(MSG_DEBUG, "RSNE", rsn_ie, rsn_ie_len);
4530 		return wpa_res_to_status_code(res);
4531 	}
4532 	if (!(data.key_mgmt & WPA_KEY_MGMT_OWE)) {
4533 		wpa_printf(MSG_DEBUG,
4534 			   "OWE: Unexpected key mgmt 0x%x from " MACSTR,
4535 			   (unsigned int) data.key_mgmt, MAC2STR(peer));
4536 		return WLAN_STATUS_AKMP_NOT_VALID;
4537 	}
4538 	if (!owe_dh) {
4539 		wpa_printf(MSG_DEBUG,
4540 			   "OWE: No Diffie-Hellman Parameter element from "
4541 			   MACSTR, MAC2STR(peer));
4542 		return WLAN_STATUS_AKMP_NOT_VALID;
4543 	}
4544 
4545 	return WLAN_STATUS_SUCCESS;
4546 }
4547 
4548 
4549 u16 owe_process_rsn_ie(struct hostapd_data *hapd,
4550 		       struct sta_info *sta,
4551 		       const u8 *rsn_ie, size_t rsn_ie_len,
4552 		       const u8 *owe_dh, size_t owe_dh_len)
4553 {
4554 	u16 status;
4555 	u8 *owe_buf, ie[256 * 2];
4556 	size_t ie_len = 0;
4557 	enum wpa_validate_result res;
4558 
4559 	if (!rsn_ie || rsn_ie_len < 2) {
4560 		wpa_printf(MSG_DEBUG, "OWE: No RSNE in (Re)AssocReq");
4561 		status = WLAN_STATUS_INVALID_IE;
4562 		goto end;
4563 	}
4564 
4565 	if (!sta->wpa_sm)
4566 		sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,	sta->addr,
4567 						NULL);
4568 	if (!sta->wpa_sm) {
4569 		wpa_printf(MSG_WARNING,
4570 			   "OWE: Failed to initialize WPA state machine");
4571 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
4572 		goto end;
4573 	}
4574 	rsn_ie -= 2;
4575 	rsn_ie_len += 2;
4576 	res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
4577 #ifndef EXT_CODE_CROP
4578 				  hapd->iface->freq,
4579 #endif
4580 				  rsn_ie, rsn_ie_len,
4581 				  NULL, 0, NULL, 0, owe_dh, owe_dh_len);
4582 	status = wpa_res_to_status_code(res);
4583 	if (status != WLAN_STATUS_SUCCESS)
4584 		goto end;
4585 	status = owe_process_assoc_req(hapd, sta, owe_dh, owe_dh_len);
4586 	if (status != WLAN_STATUS_SUCCESS)
4587 		goto end;
4588 	owe_buf = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, ie, sizeof(ie),
4589 						NULL, 0);
4590 	if (!owe_buf) {
4591 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
4592 		goto end;
4593 	}
4594 
4595 	if (sta->owe_ecdh) {
4596 		struct wpabuf *pub;
4597 
4598 		pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
4599 		if (!pub) {
4600 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
4601 			goto end;
4602 		}
4603 
4604 		/* OWE Diffie-Hellman Parameter element */
4605 		*owe_buf++ = WLAN_EID_EXTENSION; /* Element ID */
4606 		*owe_buf++ = 1 + 2 + wpabuf_len(pub); /* Length */
4607 		*owe_buf++ = WLAN_EID_EXT_OWE_DH_PARAM; /* Element ID Extension
4608 							 */
4609 		WPA_PUT_LE16(owe_buf, sta->owe_group);
4610 		owe_buf += 2;
4611 		os_memcpy(owe_buf, wpabuf_head(pub), wpabuf_len(pub));
4612 		owe_buf += wpabuf_len(pub);
4613 		wpabuf_free(pub);
4614 		sta->external_dh_updated = 1;
4615 	}
4616 	ie_len = owe_buf - ie;
4617 
4618 end:
4619 	wpa_printf(MSG_DEBUG, "OWE: Update status %d, ie len %d for peer "
4620 			      MACSTR, status, (unsigned int) ie_len,
4621 			      MAC2STR(sta->addr));
4622 	hostapd_drv_update_dh_ie(hapd, sta->addr, status,
4623 				 status == WLAN_STATUS_SUCCESS ? ie : NULL,
4624 				 ie_len);
4625 
4626 	return status;
4627 }
4628 
4629 #endif /* CONFIG_OWE */
4630 
4631 
4632 static bool check_sa_query(struct hostapd_data *hapd, struct sta_info *sta,
4633 			   int reassoc)
4634 {
4635 	if ((sta->flags &
4636 	     (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED)) !=
4637 	    (WLAN_STA_ASSOC | WLAN_STA_MFP | WLAN_STA_AUTHORIZED))
4638 		return false;
4639 
4640 	if (!sta->sa_query_timed_out && sta->sa_query_count > 0)
4641 		ap_check_sa_query_timeout(hapd, sta);
4642 
4643 	if (!sta->sa_query_timed_out &&
4644 	    (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) {
4645 		/*
4646 		 * STA has already been associated with MFP and SA Query timeout
4647 		 * has not been reached. Reject the association attempt
4648 		 * temporarily and start SA Query, if one is not pending.
4649 		 */
4650 		if (sta->sa_query_count == 0)
4651 			ap_sta_start_sa_query(hapd, sta);
4652 
4653 		return true;
4654 	}
4655 
4656 	return false;
4657 }
4658 
4659 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
4660 static int check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
4661 			   const u8 *ies, size_t ies_len, int reassoc)
4662 {
4663 	struct ieee802_11_elems elems;
4664 	int resp;
4665 	const u8 *wpa_ie;
4666 	size_t wpa_ie_len;
4667 	const u8 *p2p_dev_addr = NULL;
4668 
4669 	if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
4670 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4671 			       HOSTAPD_LEVEL_INFO, "Station sent an invalid "
4672 			       "association request");
4673 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
4674 	}
4675 
4676 	resp = check_ssid(hapd, sta, elems.ssid, elems.ssid_len);
4677 	if (resp != WLAN_STATUS_SUCCESS)
4678 		return resp;
4679 	resp = check_wmm(hapd, sta, elems.wmm, elems.wmm_len);
4680 	if (resp != WLAN_STATUS_SUCCESS)
4681 		return resp;
4682 	resp = check_ext_capab(hapd, sta, elems.ext_capab, elems.ext_capab_len);
4683 	if (resp != WLAN_STATUS_SUCCESS)
4684 		return resp;
4685 	resp = copy_supp_rates(hapd, sta, &elems);
4686 	if (resp != WLAN_STATUS_SUCCESS)
4687 		return resp;
4688 
4689 	resp = check_multi_ap(hapd, sta, elems.multi_ap, elems.multi_ap_len);
4690 	if (resp != WLAN_STATUS_SUCCESS)
4691 		return resp;
4692 
4693 	resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities);
4694 	if (resp != WLAN_STATUS_SUCCESS)
4695 		return resp;
4696 	if (hapd->iconf->ieee80211n && hapd->iconf->require_ht &&
4697 	    !(sta->flags & WLAN_STA_HT)) {
4698 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4699 			       HOSTAPD_LEVEL_INFO, "Station does not support "
4700 			       "mandatory HT PHY - reject association");
4701 		return WLAN_STATUS_ASSOC_DENIED_NO_HT;
4702 	}
4703 
4704 #ifdef CONFIG_IEEE80211AC
4705 	if (hapd->iconf->ieee80211ac) {
4706 		resp = copy_sta_vht_capab(hapd, sta, elems.vht_capabilities);
4707 		if (resp != WLAN_STATUS_SUCCESS)
4708 			return resp;
4709 
4710 		resp = set_sta_vht_opmode(hapd, sta, elems.vht_opmode_notif);
4711 		if (resp != WLAN_STATUS_SUCCESS)
4712 			return resp;
4713 	}
4714 
4715 	if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht &&
4716 	    !(sta->flags & WLAN_STA_VHT)) {
4717 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4718 			       HOSTAPD_LEVEL_INFO, "Station does not support "
4719 			       "mandatory VHT PHY - reject association");
4720 		return WLAN_STATUS_ASSOC_DENIED_NO_VHT;
4721 	}
4722 
4723 	if (hapd->conf->vendor_vht && !elems.vht_capabilities) {
4724 		resp = copy_sta_vendor_vht(hapd, sta, elems.vendor_vht,
4725 					   elems.vendor_vht_len);
4726 		if (resp != WLAN_STATUS_SUCCESS)
4727 			return resp;
4728 	}
4729 #endif /* CONFIG_IEEE80211AC */
4730 #ifdef CONFIG_IEEE80211AX
4731 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
4732 		resp = copy_sta_he_capab(hapd, sta, IEEE80211_MODE_AP,
4733 					 elems.he_capabilities,
4734 					 elems.he_capabilities_len);
4735 		if (resp != WLAN_STATUS_SUCCESS)
4736 			return resp;
4737 		if (is_6ghz_op_class(hapd->iconf->op_class)) {
4738 			if (!(sta->flags & WLAN_STA_HE)) {
4739 				hostapd_logger(hapd, sta->addr,
4740 					       HOSTAPD_MODULE_IEEE80211,
4741 					       HOSTAPD_LEVEL_INFO,
4742 					       "Station does not support mandatory HE PHY - reject association");
4743 				return WLAN_STATUS_DENIED_HE_NOT_SUPPORTED;
4744 			}
4745 			resp = copy_sta_he_6ghz_capab(hapd, sta,
4746 						      elems.he_6ghz_band_cap);
4747 			if (resp != WLAN_STATUS_SUCCESS)
4748 				return resp;
4749 		}
4750 	}
4751 #endif /* CONFIG_IEEE80211AX */
4752 
4753 #ifdef CONFIG_P2P
4754 	if (elems.p2p) {
4755 		wpabuf_free(sta->p2p_ie);
4756 		sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
4757 							  P2P_IE_VENDOR_TYPE);
4758 		if (sta->p2p_ie)
4759 			p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
4760 	} else {
4761 		wpabuf_free(sta->p2p_ie);
4762 		sta->p2p_ie = NULL;
4763 	}
4764 #endif /* CONFIG_P2P */
4765 
4766 	if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) {
4767 		wpa_ie = elems.rsn_ie;
4768 		wpa_ie_len = elems.rsn_ie_len;
4769 	} else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
4770 		   elems.wpa_ie) {
4771 		wpa_ie = elems.wpa_ie;
4772 		wpa_ie_len = elems.wpa_ie_len;
4773 	} else {
4774 		wpa_ie = NULL;
4775 		wpa_ie_len = 0;
4776 	}
4777 
4778 #ifdef CONFIG_WPS_AP
4779 	sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
4780 	if (hapd->conf->wps_state && elems.wps_ie) {
4781 		wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association "
4782 			   "Request - assume WPS is used");
4783 		if (check_sa_query(hapd, sta, reassoc))
4784 			return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
4785 		sta->flags |= WLAN_STA_WPS;
4786 		wpabuf_free(sta->wps_ie);
4787 		sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
4788 							  WPS_IE_VENDOR_TYPE);
4789 		if (sta->wps_ie && wps_is_20(sta->wps_ie)) {
4790 			wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0");
4791 			sta->flags |= WLAN_STA_WPS2;
4792 		}
4793 		wpa_ie = NULL;
4794 		wpa_ie_len = 0;
4795 		if (sta->wps_ie && wps_validate_assoc_req(sta->wps_ie) < 0) {
4796 			wpa_printf(MSG_DEBUG, "WPS: Invalid WPS IE in "
4797 				   "(Re)Association Request - reject");
4798 			return WLAN_STATUS_INVALID_IE;
4799 		}
4800 	} else if (hapd->conf->wps_state && wpa_ie == NULL) {
4801 		wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in "
4802 			   "(Re)Association Request - possible WPS use");
4803 		sta->flags |= WLAN_STA_MAYBE_WPS;
4804 	} else
4805 #endif /* CONFIG_WPS_AP */
4806 	if (hapd->conf->wpa && wpa_ie == NULL) {
4807 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4808 			       HOSTAPD_LEVEL_INFO,
4809 			       "No WPA/RSN IE in association request");
4810 		return WLAN_STATUS_INVALID_IE;
4811 	}
4812 
4813 	if (hapd->conf->wpa && wpa_ie) {
4814 		enum wpa_validate_result res;
4815 
4816 		wpa_ie -= 2;
4817 		wpa_ie_len += 2;
4818 		if (sta->wpa_sm == NULL)
4819 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
4820 							sta->addr,
4821 							p2p_dev_addr);
4822 		if (sta->wpa_sm == NULL) {
4823 			wpa_printf(MSG_WARNING, "Failed to initialize WPA "
4824 				   "state machine");
4825 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
4826 		}
4827 		wpa_auth_set_auth_alg(sta->wpa_sm, sta->auth_alg);
4828 		res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
4829 					  hapd->iface->freq,
4830 					  wpa_ie, wpa_ie_len,
4831 					  elems.rsnxe ? elems.rsnxe - 2 : NULL,
4832 					  elems.rsnxe ? elems.rsnxe_len + 2 : 0,
4833 					  elems.mdie, elems.mdie_len,
4834 					  elems.owe_dh, elems.owe_dh_len);
4835 		resp = wpa_res_to_status_code(res);
4836 		if (resp != WLAN_STATUS_SUCCESS)
4837 			return resp;
4838 #ifdef CONFIG_IEEE80211W_AP
4839 		if (check_sa_query(hapd, sta, reassoc))
4840 			return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
4841 
4842 		if (wpa_auth_uses_mfp(sta->wpa_sm))
4843 			sta->flags |= WLAN_STA_MFP;
4844 		else
4845 			sta->flags &= ~WLAN_STA_MFP;
4846 #else
4847 	(void)reassoc;
4848 #endif /* CONFIG_IEEE80211W_AP */
4849 
4850 #ifdef CONFIG_IEEE80211R_AP
4851 		if (sta->auth_alg == WLAN_AUTH_FT) {
4852 			if (!reassoc) {
4853 				wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
4854 					   "to use association (not "
4855 					   "re-association) with FT auth_alg",
4856 					   MAC2STR(sta->addr));
4857 				return WLAN_STATUS_UNSPECIFIED_FAILURE;
4858 			}
4859 
4860 			resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies,
4861 						       ies_len);
4862 			if (resp != WLAN_STATUS_SUCCESS)
4863 				return resp;
4864 		}
4865 #endif /* CONFIG_IEEE80211R_AP */
4866 
4867 #ifdef CONFIG_SAE
4868 		if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae &&
4869 		    sta->sae->state == SAE_ACCEPTED)
4870 			wpa_auth_add_sae_pmkid(sta->wpa_sm, sta->sae->pmkid);
4871 
4872 		if (wpa_auth_uses_sae(sta->wpa_sm) &&
4873 		    sta->auth_alg == WLAN_AUTH_OPEN) {
4874 			struct rsn_pmksa_cache_entry *sa;
4875 			sa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
4876 			if (!sa || sa->akmp != WPA_KEY_MGMT_SAE) {
4877 				wpa_warning_log4(MSG_DEBUG,
4878 					   "SAE: No PMKSA cache entry found for "
4879 					   "%02x:xx:xx:%02x:%02x:%02x", (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
4880 				return WLAN_STATUS_INVALID_PMKID;
4881 			}
4882 			wpa_warning_log4(MSG_DEBUG, "SAE: " "%02x:xx:xx:%02x:%02x:%02x"
4883 				   " using PMKSA caching", (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
4884 		} else if (wpa_auth_uses_sae(sta->wpa_sm) &&
4885 			   sta->auth_alg != WLAN_AUTH_SAE &&
4886 			   !(sta->auth_alg == WLAN_AUTH_FT &&
4887 			     wpa_auth_uses_ft_sae(sta->wpa_sm))) {
4888 			wpa_warning_log4(MSG_DEBUG, "SAE: " "%02x:xx:xx:%02x:%02x:%02x" " tried to use "
4889 				   (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
4890 			wpa_warning_log1(MSG_DEBUG, "SAE: "
4891 				   "SAE AKM after non-SAE auth_alg %u", sta->auth_alg);
4892 			return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
4893 		}
4894 
4895 		if (hapd->conf->sae_pwe == 2 &&
4896 		    sta->auth_alg == WLAN_AUTH_SAE &&
4897 		    sta->sae && !sta->sae->h2e &&
4898 		    ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
4899 					      WLAN_RSNX_CAPAB_SAE_H2E)) {
4900 			wpa_printf(MSG_INFO, "SAE: " MACSTR
4901 				   " indicates support for SAE H2E, but did not use it",
4902 				   MAC2STR(sta->addr));
4903 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
4904 		}
4905 #endif /* CONFIG_SAE */
4906 
4907 #ifdef CONFIG_OWE
4908 		if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
4909 		    wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE &&
4910 		    elems.owe_dh) {
4911 			resp = owe_process_assoc_req(hapd, sta, elems.owe_dh,
4912 						     elems.owe_dh_len);
4913 			if (resp != WLAN_STATUS_SUCCESS)
4914 				return resp;
4915 		}
4916 #endif /* CONFIG_OWE */
4917 
4918 #ifdef CONFIG_DPP2
4919 		dpp_pfs_free(sta->dpp_pfs);
4920 		sta->dpp_pfs = NULL;
4921 
4922 		if (DPP_VERSION > 1 &&
4923 		    (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) &&
4924 		    hapd->conf->dpp_netaccesskey && sta->wpa_sm &&
4925 		    wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP &&
4926 		    elems.owe_dh) {
4927 			sta->dpp_pfs = dpp_pfs_init(
4928 				wpabuf_head(hapd->conf->dpp_netaccesskey),
4929 				wpabuf_len(hapd->conf->dpp_netaccesskey));
4930 			if (!sta->dpp_pfs) {
4931 				wpa_printf(MSG_DEBUG,
4932 					   "DPP: Could not initialize PFS");
4933 				/* Try to continue without PFS */
4934 				goto pfs_fail;
4935 			}
4936 
4937 			if (dpp_pfs_process(sta->dpp_pfs, elems.owe_dh,
4938 					    elems.owe_dh_len) < 0) {
4939 				dpp_pfs_free(sta->dpp_pfs);
4940 				sta->dpp_pfs = NULL;
4941 				return WLAN_STATUS_UNSPECIFIED_FAILURE;
4942 			}
4943 		}
4944 
4945 		wpa_auth_set_dpp_z(sta->wpa_sm, sta->dpp_pfs ?
4946 				   sta->dpp_pfs->secret : NULL);
4947 	pfs_fail:
4948 #endif /* CONFIG_DPP2 */
4949 
4950 		if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) &&
4951 		    wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) {
4952 			hostapd_logger(hapd, sta->addr,
4953 				       HOSTAPD_MODULE_IEEE80211,
4954 				       HOSTAPD_LEVEL_INFO,
4955 				       "Station tried to use TKIP with HT "
4956 				       "association");
4957 			return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
4958 		}
4959 #ifdef CONFIG_HS20
4960 	} else if (hapd->conf->osen) {
4961 		if (elems.osen == NULL) {
4962 			hostapd_logger(
4963 				hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4964 				HOSTAPD_LEVEL_INFO,
4965 				"No HS 2.0 OSEN element in association request");
4966 			return WLAN_STATUS_INVALID_IE;
4967 		}
4968 
4969 		wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association");
4970 		if (sta->wpa_sm == NULL)
4971 			sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
4972 							sta->addr, NULL);
4973 		if (sta->wpa_sm == NULL) {
4974 			wpa_printf(MSG_WARNING, "Failed to initialize WPA "
4975 				   "state machine");
4976 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
4977 		}
4978 		if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
4979 				      elems.osen - 2, elems.osen_len + 2) < 0)
4980 			return WLAN_STATUS_INVALID_IE;
4981 #endif /* CONFIG_HS20 */
4982 	} else
4983 		wpa_auth_sta_no_wpa(sta->wpa_sm);
4984 
4985 #ifdef CONFIG_P2P
4986 	p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len);
4987 #endif /* CONFIG_P2P */
4988 
4989 #ifdef CONFIG_HS20
4990 	wpabuf_free(sta->hs20_ie);
4991 	if (elems.hs20 && elems.hs20_len > 4) {
4992 		int release;
4993 
4994 		sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
4995 						 elems.hs20_len - 4);
4996 		release = ((elems.hs20[4] >> 4) & 0x0f) + 1;
4997 		if (release >= 2 && !wpa_auth_uses_mfp(sta->wpa_sm) &&
4998 		    hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
4999 			wpa_printf(MSG_DEBUG,
5000 				   "HS 2.0: PMF not negotiated by release %d station "
5001 				   MACSTR, release, MAC2STR(sta->addr));
5002 			return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
5003 		}
5004 	} else {
5005 		sta->hs20_ie = NULL;
5006 	}
5007 
5008 	wpabuf_free(sta->roaming_consortium);
5009 	if (elems.roaming_cons_sel)
5010 		sta->roaming_consortium = wpabuf_alloc_copy(
5011 			elems.roaming_cons_sel + 4,
5012 			elems.roaming_cons_sel_len - 4);
5013 	else
5014 		sta->roaming_consortium = NULL;
5015 #endif /* CONFIG_HS20 */
5016 
5017 #ifdef CONFIG_FST
5018 	wpabuf_free(sta->mb_ies);
5019 	if (hapd->iface->fst)
5020 		sta->mb_ies = mb_ies_by_info(&elems.mb_ies);
5021 	else
5022 		sta->mb_ies = NULL;
5023 #endif /* CONFIG_FST */
5024 
5025 #ifdef CONFIG_MBO
5026 	mbo_ap_check_sta_assoc(hapd, sta, &elems);
5027 
5028 	if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
5029 	    elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
5030 	    hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
5031 		wpa_printf(MSG_INFO,
5032 			   "MBO: Reject WPA2 association without PMF");
5033 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
5034 	}
5035 #endif /* CONFIG_MBO */
5036 
5037 #if defined(CONFIG_FILS) && defined(CONFIG_OCV)
5038 	if (wpa_auth_uses_ocv(sta->wpa_sm) &&
5039 	    (sta->auth_alg == WLAN_AUTH_FILS_SK ||
5040 	     sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
5041 	     sta->auth_alg == WLAN_AUTH_FILS_PK)) {
5042 		struct wpa_channel_info ci;
5043 		int tx_chanwidth;
5044 		int tx_seg1_idx;
5045 		enum oci_verify_result res;
5046 
5047 		if (hostapd_drv_channel_info(hapd, &ci) != 0) {
5048 			wpa_printf(MSG_WARNING,
5049 				   "Failed to get channel info to validate received OCI in FILS (Re)Association Request frame");
5050 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
5051 		}
5052 
5053 		if (get_sta_tx_parameters(sta->wpa_sm,
5054 					  channel_width_to_int(ci.chanwidth),
5055 					  ci.seg1_idx, &tx_chanwidth,
5056 					  &tx_seg1_idx) < 0)
5057 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
5058 
5059 		res = ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
5060 					   tx_chanwidth, tx_seg1_idx);
5061 		if (wpa_auth_uses_ocv(sta->wpa_sm) == 2 &&
5062 		    res == OCI_NOT_FOUND) {
5063 			/* Work around misbehaving STAs */
5064 			wpa_printf(MSG_INFO,
5065 				   "FILS: Disable OCV with a STA that does not send OCI");
5066 			wpa_auth_set_ocv(sta->wpa_sm, 0);
5067 		} else if (res != OCI_SUCCESS) {
5068 			wpa_printf(MSG_WARNING, "FILS: OCV failed: %s",
5069 				   ocv_errorstr);
5070 			wpa_msg(hapd->msg_ctx, MSG_INFO, OCV_FAILURE "addr="
5071 				MACSTR " frame=fils-reassoc-req error=%s",
5072 				MAC2STR(sta->addr), ocv_errorstr);
5073 			return WLAN_STATUS_UNSPECIFIED_FAILURE;
5074 		}
5075 	}
5076 #endif /* CONFIG_FILS && CONFIG_OCV */
5077 
5078 	ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
5079 				    elems.supp_op_classes_len);
5080 
5081 	if ((sta->capability & WLAN_CAPABILITY_RADIO_MEASUREMENT) &&
5082 	    elems.rrm_enabled &&
5083 	    elems.rrm_enabled_len >= sizeof(sta->rrm_enabled_capa))
5084 		os_memcpy(sta->rrm_enabled_capa, elems.rrm_enabled,
5085 			  sizeof(sta->rrm_enabled_capa));
5086 
5087 	if (elems.power_capab) {
5088 		sta->min_tx_power = elems.power_capab[0];
5089 		sta->max_tx_power = elems.power_capab[1];
5090 		sta->power_capab = 1;
5091 	} else {
5092 		sta->power_capab = 0;
5093 	}
5094 
5095 	return WLAN_STATUS_SUCCESS;
5096 }
5097 
5098 
5099 static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
5100 			u16 reason_code)
5101 {
5102 	int send_len;
5103 	struct ieee80211_mgmt reply;
5104 
5105 	os_memset(&reply, 0, sizeof(reply));
5106 	reply.frame_control =
5107 		IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH);
5108 	os_memcpy(reply.da, addr, ETH_ALEN);
5109 	os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN);
5110 	os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN);
5111 
5112 	send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
5113 	reply.u.deauth.reason_code = host_to_le16(reason_code);
5114 
5115 	if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0, NULL, 0, 0) < 0)
5116 		wpa_printf(MSG_INFO, "Failed to send deauth: %s",
5117 			   strerror(errno));
5118 }
5119 
5120 
5121 static int add_associated_sta(struct hostapd_data *hapd,
5122 			      struct sta_info *sta, int reassoc)
5123 {
5124 	struct ieee80211_ht_capabilities ht_cap;
5125 	struct ieee80211_vht_capabilities vht_cap;
5126 	struct ieee80211_he_capabilities he_cap;
5127 	int set = 1;
5128 
5129 	/*
5130 	 * Remove the STA entry to ensure the STA PS state gets cleared and
5131 	 * configuration gets updated. This is relevant for cases, such as
5132 	 * FT-over-the-DS, where a station re-associates back to the same AP but
5133 	 * skips the authentication flow, or if working with a driver that
5134 	 * does not support full AP client state.
5135 	 *
5136 	 * Skip this if the STA has already completed FT reassociation and the
5137 	 * TK has been configured since the TX/RX PN must not be reset to 0 for
5138 	 * the same key.
5139 	 *
5140 	 * FT-over-the-DS has a special case where the STA entry (and as such,
5141 	 * the TK) has not yet been configured to the driver depending on which
5142 	 * driver interface is used. For that case, allow add-STA operation to
5143 	 * be used (instead of set-STA). This is needed to allow mac80211-based
5144 	 * drivers to accept the STA parameter configuration. Since this is
5145 	 * after a new FT-over-DS exchange, a new TK has been derived, so key
5146 	 * reinstallation is not a concern for this case.
5147 	 */
5148 	wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR
5149 		   " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
5150 		   MAC2STR(sta->addr), sta->added_unassoc, sta->auth_alg,
5151 		   sta->ft_over_ds, reassoc,
5152 		   !!(sta->flags & WLAN_STA_AUTHORIZED),
5153 		   wpa_auth_sta_ft_tk_already_set(sta->wpa_sm),
5154 		   wpa_auth_sta_fils_tk_already_set(sta->wpa_sm));
5155 
5156 	if (!sta->added_unassoc &&
5157 	    (!(sta->flags & WLAN_STA_AUTHORIZED) ||
5158 	     (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) ||
5159 	     (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) &&
5160 	      !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)))) {
5161 		hostapd_drv_sta_remove(hapd, sta->addr);
5162 		wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED);
5163 		set = 0;
5164 
5165 		 /* Do not allow the FT-over-DS exception to be used more than
5166 		  * once per authentication exchange to guarantee a new TK is
5167 		  * used here */
5168 		sta->ft_over_ds = 0;
5169 	}
5170 
5171 	if (sta->flags & WLAN_STA_HT)
5172 		hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap);
5173 #ifdef CONFIG_IEEE80211AC
5174 	if (sta->flags & WLAN_STA_VHT)
5175 		hostapd_get_vht_capab(hapd, sta->vht_capabilities, &vht_cap);
5176 #endif /* CONFIG_IEEE80211AC */
5177 #ifdef CONFIG_IEEE80211AX
5178 	if (sta->flags & WLAN_STA_HE) {
5179 		hostapd_get_he_capab(hapd, sta->he_capab, &he_cap,
5180 				     sta->he_capab_len);
5181 	}
5182 #endif /* CONFIG_IEEE80211AX */
5183 
5184 	/*
5185 	 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
5186 	 * will be set when the ACK frame for the (Re)Association Response frame
5187 	 * is processed (TX status driver event).
5188 	 */
5189 	if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability,
5190 			    sta->supported_rates, sta->supported_rates_len,
5191 			    sta->listen_interval,
5192 			    sta->flags & WLAN_STA_HT ? &ht_cap : NULL,
5193 			    sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
5194 			    sta->flags & WLAN_STA_HE ? &he_cap : NULL,
5195 			    sta->flags & WLAN_STA_HE ? sta->he_capab_len : 0,
5196 			    sta->he_6ghz_capab,
5197 			    sta->flags | WLAN_STA_ASSOC, sta->qosinfo,
5198 			    sta->vht_opmode, sta->p2p_ie ? 1 : 0,
5199 			    set)) {
5200 		hostapd_logger(hapd, sta->addr,
5201 			       HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE,
5202 			       "Could not %s STA to kernel driver",
5203 			       set ? "set" : "add");
5204 
5205 		if (sta->added_unassoc) {
5206 			hostapd_drv_sta_remove(hapd, sta->addr);
5207 			sta->added_unassoc = 0;
5208 		}
5209 
5210 		return -1;
5211 	}
5212 
5213 	sta->added_unassoc = 0;
5214 
5215 	return 0;
5216 }
5217 
5218 
5219 static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
5220 			   const u8 *addr, u16 status_code, int reassoc,
5221 			   const u8 *ies, size_t ies_len, int rssi,
5222 			   int omit_rsnxe)
5223 {
5224 	int send_len;
5225 	u8 *buf;
5226 	size_t buflen;
5227 	struct ieee80211_mgmt *reply;
5228 	u8 *p;
5229 	u16 res = WLAN_STATUS_SUCCESS;
5230 
5231 	buflen = sizeof(struct ieee80211_mgmt) + 1024;
5232 #ifdef CONFIG_FILS
5233 	if (sta && sta->fils_hlp_resp)
5234 		buflen += wpabuf_len(sta->fils_hlp_resp);
5235 	if (sta)
5236 		buflen += 150;
5237 #endif /* CONFIG_FILS */
5238 #ifdef CONFIG_OWE
5239 	if (sta && (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE))
5240 		buflen += 150;
5241 #endif /* CONFIG_OWE */
5242 #ifdef CONFIG_DPP2
5243 	if (sta && sta->dpp_pfs)
5244 		buflen += 5 + sta->dpp_pfs->curve->prime_len;
5245 #endif /* CONFIG_DPP2 */
5246 	buf = os_zalloc(buflen);
5247 	if (!buf) {
5248 		res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5249 		goto done;
5250 	}
5251 	reply = (struct ieee80211_mgmt *) buf;
5252 	reply->frame_control =
5253 		IEEE80211_FC(WLAN_FC_TYPE_MGMT,
5254 			     (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
5255 			      WLAN_FC_STYPE_ASSOC_RESP));
5256 	os_memcpy(reply->da, addr, ETH_ALEN);
5257 	os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
5258 	os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN);
5259 
5260 	send_len = IEEE80211_HDRLEN;
5261 	send_len += sizeof(reply->u.assoc_resp);
5262 	reply->u.assoc_resp.capab_info =
5263 		host_to_le16(hostapd_own_capab_info(hapd));
5264 	reply->u.assoc_resp.status_code = host_to_le16(status_code);
5265 
5266 	reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0) |
5267 					       BIT(14) | BIT(15));
5268 	/* Supported rates */
5269 	p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
5270 	/* Extended supported rates */
5271 	p = hostapd_eid_ext_supp_rates(hapd, p);
5272 
5273 	/* Radio measurement capabilities */
5274 	p = hostapd_eid_rm_enabled_capab(hapd, p, buf + buflen - p);
5275 
5276 #ifdef CONFIG_MBO
5277 	if (status_code == WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS &&
5278 	    rssi != 0) {
5279 		int delta = hapd->iconf->rssi_reject_assoc_rssi - rssi;
5280 
5281 		p = hostapd_eid_mbo_rssi_assoc_rej(hapd, p, buf + buflen - p,
5282 						   delta);
5283 	}
5284 #endif /* CONFIG_MBO */
5285 
5286 #ifdef CONFIG_IEEE80211R_AP
5287 	if (sta && status_code == WLAN_STATUS_SUCCESS) {
5288 		/* IEEE 802.11r: Mobility Domain Information, Fast BSS
5289 		 * Transition Information, RSN, [RIC Response] */
5290 		p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
5291 						buf + buflen - p,
5292 						sta->auth_alg, ies, ies_len,
5293 						omit_rsnxe);
5294 		if (!p) {
5295 #ifndef CONFIG_PRINT_NOUSE
5296 			wpa_warning_log0(MSG_DEBUG,
5297 				   "FT: Failed to write AssocResp IEs");
5298 #endif
5299 			res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5300 			goto done;
5301 		}
5302 	}
5303 #endif /* CONFIG_IEEE80211R_AP */
5304 #ifdef CONFIG_FILS
5305 	if (sta && status_code == WLAN_STATUS_SUCCESS &&
5306 	    (sta->auth_alg == WLAN_AUTH_FILS_SK ||
5307 	     sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
5308 	     sta->auth_alg == WLAN_AUTH_FILS_PK))
5309 		p = wpa_auth_write_assoc_resp_fils(sta->wpa_sm, p,
5310 						   buf + buflen - p,
5311 						   ies, ies_len);
5312 #endif /* CONFIG_FILS */
5313 
5314 #ifdef CONFIG_OWE
5315 	if (sta && status_code == WLAN_STATUS_SUCCESS &&
5316 	    (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE))
5317 		p = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, p,
5318 						  buf + buflen - p,
5319 						  ies, ies_len);
5320 #endif /* CONFIG_OWE */
5321 
5322 	if (sta && status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
5323 		p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
5324 
5325 	p = hostapd_eid_ht_capabilities(hapd, p);
5326 	p = hostapd_eid_ht_operation(hapd, p);
5327 
5328 #ifdef CONFIG_IEEE80211AC
5329 	if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac &&
5330 	    !is_6ghz_op_class(hapd->iconf->op_class)) {
5331 		u32 nsts = 0, sta_nsts;
5332 
5333 		if (sta && hapd->conf->use_sta_nsts && sta->vht_capabilities) {
5334 			struct ieee80211_vht_capabilities *capa;
5335 
5336 			nsts = (hapd->iface->conf->vht_capab >>
5337 				VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
5338 			capa = sta->vht_capabilities;
5339 			sta_nsts = (le_to_host32(capa->vht_capabilities_info) >>
5340 				    VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
5341 
5342 			if (nsts < sta_nsts)
5343 				nsts = 0;
5344 			else
5345 				nsts = sta_nsts;
5346 		}
5347 		p = hostapd_eid_vht_capabilities(hapd, p, nsts);
5348 		p = hostapd_eid_vht_operation(hapd, p);
5349 	}
5350 #endif /* CONFIG_IEEE80211AC */
5351 
5352 #ifdef CONFIG_IEEE80211AX
5353 	if (hapd->iconf->ieee80211ax && !hapd->conf->disable_11ax) {
5354 		p = hostapd_eid_he_capab(hapd, p, IEEE80211_MODE_AP);
5355 		p = hostapd_eid_he_operation(hapd, p);
5356 		p = hostapd_eid_spatial_reuse(hapd, p);
5357 		p = hostapd_eid_he_mu_edca_parameter_set(hapd, p);
5358 		p = hostapd_eid_he_6ghz_band_cap(hapd, p);
5359 	}
5360 #endif /* CONFIG_IEEE80211AX */
5361 
5362 	p = hostapd_eid_ext_capab(hapd, p);
5363 	p = hostapd_eid_bss_max_idle_period(hapd, p);
5364 	if (sta && sta->qos_map_enabled)
5365 		p = hostapd_eid_qos_map_set(hapd, p);
5366 
5367 #ifdef CONFIG_FST
5368 	if (hapd->iface->fst_ies) {
5369 		os_memcpy(p, wpabuf_head(hapd->iface->fst_ies),
5370 			  wpabuf_len(hapd->iface->fst_ies));
5371 		p += wpabuf_len(hapd->iface->fst_ies);
5372 	}
5373 #endif /* CONFIG_FST */
5374 
5375 #ifdef CONFIG_TESTING_OPTIONS
5376 	if (hapd->conf->rsnxe_override_ft &&
5377 	    buf + buflen - p >=
5378 	    (long int) wpabuf_len(hapd->conf->rsnxe_override_ft) &&
5379 	    sta && sta->auth_alg == WLAN_AUTH_FT) {
5380 		wpa_printf(MSG_DEBUG, "TESTING: RSNXE FT override");
5381 		os_memcpy(p, wpabuf_head(hapd->conf->rsnxe_override_ft),
5382 			  wpabuf_len(hapd->conf->rsnxe_override_ft));
5383 		p += wpabuf_len(hapd->conf->rsnxe_override_ft);
5384 		goto rsnxe_done;
5385 	}
5386 #endif /* CONFIG_TESTING_OPTIONS */
5387 	if (!omit_rsnxe)
5388 		p = hostapd_eid_rsnxe(hapd, p, buf + buflen - p);
5389 #ifdef CONFIG_TESTING_OPTIONS
5390 rsnxe_done:
5391 #endif /* CONFIG_TESTING_OPTIONS */
5392 
5393 #ifdef CONFIG_OWE
5394 	if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
5395 	    sta && sta->owe_ecdh && status_code == WLAN_STATUS_SUCCESS &&
5396 	    wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE &&
5397 	    !wpa_auth_sta_get_pmksa(sta->wpa_sm)) {
5398 		struct wpabuf *pub;
5399 
5400 		pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
5401 		if (!pub) {
5402 			res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5403 			goto done;
5404 		}
5405 		/* OWE Diffie-Hellman Parameter element */
5406 		*p++ = WLAN_EID_EXTENSION; /* Element ID */
5407 		*p++ = 1 + 2 + wpabuf_len(pub); /* Length */
5408 		*p++ = WLAN_EID_EXT_OWE_DH_PARAM; /* Element ID Extension */
5409 		WPA_PUT_LE16(p, sta->owe_group);
5410 		p += 2;
5411 		os_memcpy(p, wpabuf_head(pub), wpabuf_len(pub));
5412 		p += wpabuf_len(pub);
5413 		wpabuf_free(pub);
5414 	}
5415 #endif /* CONFIG_OWE */
5416 
5417 #ifdef CONFIG_DPP2
5418 	if (DPP_VERSION > 1 && (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) &&
5419 	    sta && sta->dpp_pfs && status_code == WLAN_STATUS_SUCCESS &&
5420 	    wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP) {
5421 		os_memcpy(p, wpabuf_head(sta->dpp_pfs->ie),
5422 			  wpabuf_len(sta->dpp_pfs->ie));
5423 		p += wpabuf_len(sta->dpp_pfs->ie);
5424 	}
5425 #endif /* CONFIG_DPP2 */
5426 
5427 #ifdef CONFIG_IEEE80211AC
5428 	if (sta && hapd->conf->vendor_vht && (sta->flags & WLAN_STA_VENDOR_VHT))
5429 		p = hostapd_eid_vendor_vht(hapd, p);
5430 #endif /* CONFIG_IEEE80211AC */
5431 
5432 	if (sta && (sta->flags & WLAN_STA_WMM))
5433 		p = hostapd_eid_wmm(hapd, p);
5434 
5435 #ifdef CONFIG_WPS
5436 	if (sta &&
5437 	    ((sta->flags & WLAN_STA_WPS) ||
5438 	     ((sta->flags & WLAN_STA_MAYBE_WPS) && hapd->conf->wpa))) {
5439 		struct wpabuf *wps = wps_build_assoc_resp_ie();
5440 		if (wps) {
5441 			os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps));
5442 			p += wpabuf_len(wps);
5443 			wpabuf_free(wps);
5444 		}
5445 	}
5446 #endif /* CONFIG_WPS */
5447 
5448 	if (sta && (sta->flags & WLAN_STA_MULTI_AP))
5449 		p = hostapd_eid_multi_ap(hapd, p);
5450 
5451 #ifdef CONFIG_P2P
5452 	if (sta && sta->p2p_ie && hapd->p2p_group) {
5453 		struct wpabuf *p2p_resp_ie;
5454 		enum p2p_status_code status;
5455 		switch (status_code) {
5456 		case WLAN_STATUS_SUCCESS:
5457 			status = P2P_SC_SUCCESS;
5458 			break;
5459 		case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:
5460 			status = P2P_SC_FAIL_LIMIT_REACHED;
5461 			break;
5462 		default:
5463 			status = P2P_SC_FAIL_INVALID_PARAMS;
5464 			break;
5465 		}
5466 		p2p_resp_ie = p2p_group_assoc_resp_ie(hapd->p2p_group, status);
5467 		if (p2p_resp_ie) {
5468 			os_memcpy(p, wpabuf_head(p2p_resp_ie),
5469 				  wpabuf_len(p2p_resp_ie));
5470 			p += wpabuf_len(p2p_resp_ie);
5471 			wpabuf_free(p2p_resp_ie);
5472 		}
5473 	}
5474 #endif /* CONFIG_P2P */
5475 
5476 #ifdef CONFIG_P2P_MANAGER
5477 	if (hapd->conf->p2p & P2P_MANAGE)
5478 		p = hostapd_eid_p2p_manage(hapd, p);
5479 #endif /* CONFIG_P2P_MANAGER */
5480 
5481 	p = hostapd_eid_mbo(hapd, p, buf + buflen - p);
5482 
5483 	if (hapd->conf->assocresp_elements &&
5484 	    (size_t) (buf + buflen - p) >=
5485 	    wpabuf_len(hapd->conf->assocresp_elements)) {
5486 		os_memcpy(p, wpabuf_head(hapd->conf->assocresp_elements),
5487 			  wpabuf_len(hapd->conf->assocresp_elements));
5488 		p += wpabuf_len(hapd->conf->assocresp_elements);
5489 	}
5490 
5491 	send_len += p - reply->u.assoc_resp.variable;
5492 
5493 #ifdef CONFIG_FILS
5494 	if (sta &&
5495 	    (sta->auth_alg == WLAN_AUTH_FILS_SK ||
5496 	     sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
5497 	     sta->auth_alg == WLAN_AUTH_FILS_PK) &&
5498 	    status_code == WLAN_STATUS_SUCCESS) {
5499 		struct ieee802_11_elems elems;
5500 
5501 		if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
5502 		    ParseFailed || !elems.fils_session) {
5503 			res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5504 			goto done;
5505 		}
5506 
5507 		/* FILS Session */
5508 		*p++ = WLAN_EID_EXTENSION; /* Element ID */
5509 		*p++ = 1 + FILS_SESSION_LEN; /* Length */
5510 		*p++ = WLAN_EID_EXT_FILS_SESSION; /* Element ID Extension */
5511 		os_memcpy(p, elems.fils_session, FILS_SESSION_LEN);
5512 		send_len += 2 + 1 + FILS_SESSION_LEN;
5513 
5514 		send_len = fils_encrypt_assoc(sta->wpa_sm, buf, send_len,
5515 					      buflen, sta->fils_hlp_resp);
5516 		if (send_len < 0) {
5517 			res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5518 			goto done;
5519 		}
5520 	}
5521 #endif /* CONFIG_FILS */
5522 
5523 	if (hostapd_drv_send_mlme(hapd, reply, send_len, 0, NULL, 0, 0) < 0) {
5524 		wpa_warning_buf(MSG_INFO, "Failed to send assoc resp: %s",
5525 			   strerror(errno), strlen(strerror(errno)));
5526 		res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5527 	}
5528 
5529 done:
5530 	os_free(buf);
5531 	return res;
5532 }
5533 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
5534 
5535 #ifdef CONFIG_OWE
5536 u8 * owe_assoc_req_process(struct hostapd_data *hapd, struct sta_info *sta,
5537 			   const u8 *owe_dh, u8 owe_dh_len,
5538 			   u8 *owe_buf, size_t owe_buf_len, u16 *status)
5539 {
5540 #ifdef CONFIG_TESTING_OPTIONS
5541 	if (hapd->conf->own_ie_override) {
5542 		wpa_printf(MSG_DEBUG, "OWE: Using IE override");
5543 		*status = WLAN_STATUS_SUCCESS;
5544 		return wpa_auth_write_assoc_resp_owe(sta->wpa_sm, owe_buf,
5545 						     owe_buf_len, NULL, 0);
5546 	}
5547 #endif /* CONFIG_TESTING_OPTIONS */
5548 
5549 	if (wpa_auth_sta_get_pmksa(sta->wpa_sm)) {
5550 		wpa_printf(MSG_DEBUG, "OWE: Using PMKSA caching");
5551 		owe_buf = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, owe_buf,
5552 							owe_buf_len, NULL, 0);
5553 		*status = WLAN_STATUS_SUCCESS;
5554 		return owe_buf;
5555 	}
5556 
5557 	if (sta->owe_pmk && sta->external_dh_updated) {
5558 		wpa_warning_log0(MSG_DEBUG, "OWE: Using previously derived PMK");
5559 		*status = WLAN_STATUS_SUCCESS;
5560 		return owe_buf;
5561 	}
5562 
5563 	*status = owe_process_assoc_req(hapd, sta, owe_dh, owe_dh_len);
5564 	if (*status != WLAN_STATUS_SUCCESS)
5565 		return NULL;
5566 
5567 	owe_buf = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, owe_buf,
5568 						owe_buf_len, NULL, 0);
5569 
5570 	if (sta->owe_ecdh && owe_buf) {
5571 		struct wpabuf *pub;
5572 
5573 		pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
5574 		if (!pub) {
5575 			*status = WLAN_STATUS_UNSPECIFIED_FAILURE;
5576 			return owe_buf;
5577 		}
5578 
5579 		/* OWE Diffie-Hellman Parameter element */
5580 		*owe_buf++ = WLAN_EID_EXTENSION; /* Element ID */
5581 		*owe_buf++ = 1 + 2 + wpabuf_len(pub); /* Length */
5582 		*owe_buf++ = WLAN_EID_EXT_OWE_DH_PARAM; /* Element ID Extension
5583 							 */
5584 		WPA_PUT_LE16(owe_buf, sta->owe_group);
5585 		owe_buf += 2;
5586 		os_memcpy(owe_buf, wpabuf_head(pub), wpabuf_len(pub));
5587 		owe_buf += wpabuf_len(pub);
5588 		wpabuf_free(pub);
5589 	}
5590 
5591 	return owe_buf;
5592 }
5593 #endif /* CONFIG_OWE */
5594 
5595 
5596 #ifdef CONFIG_FILS
5597 
5598 void fils_hlp_finish_assoc(struct hostapd_data *hapd, struct sta_info *sta)
5599 {
5600 	u16 reply_res;
5601 
5602 	wpa_printf(MSG_DEBUG, "FILS: Finish association with " MACSTR,
5603 		   MAC2STR(sta->addr));
5604 	eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
5605 	if (!sta->fils_pending_assoc_req)
5606 		return;
5607 	reply_res = send_assoc_resp(hapd, sta, sta->addr, WLAN_STATUS_SUCCESS,
5608 				    sta->fils_pending_assoc_is_reassoc,
5609 				    sta->fils_pending_assoc_req,
5610 				    sta->fils_pending_assoc_req_len, 0, 0);
5611 	os_free(sta->fils_pending_assoc_req);
5612 	sta->fils_pending_assoc_req = NULL;
5613 	sta->fils_pending_assoc_req_len = 0;
5614 	wpabuf_free(sta->fils_hlp_resp);
5615 	sta->fils_hlp_resp = NULL;
5616 	wpabuf_free(sta->hlp_dhcp_discover);
5617 	sta->hlp_dhcp_discover = NULL;
5618 
5619 	/*
5620 	 * Remove the station in case transmission of a success response fails.
5621 	 * At this point the station was already added associated to the driver.
5622 	 */
5623 	if (reply_res != WLAN_STATUS_SUCCESS)
5624 		hostapd_drv_sta_remove(hapd, sta->addr);
5625 }
5626 
5627 
5628 void fils_hlp_timeout(void *eloop_ctx, void *eloop_data)
5629 {
5630 	struct hostapd_data *hapd = eloop_ctx;
5631 	struct sta_info *sta = eloop_data;
5632 
5633 	wpa_printf(MSG_DEBUG,
5634 		   "FILS: HLP response timeout - continue with association response for "
5635 		   MACSTR, MAC2STR(sta->addr));
5636 	if (sta->fils_drv_assoc_finish)
5637 		hostapd_notify_assoc_fils_finish(hapd, sta);
5638 	else
5639 		fils_hlp_finish_assoc(hapd, sta);
5640 }
5641 
5642 #endif /* CONFIG_FILS */
5643 
5644 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
5645 static void handle_assoc(struct hostapd_data *hapd,
5646 			 const struct ieee80211_mgmt *mgmt, size_t len,
5647 			 int reassoc, int rssi)
5648 {
5649 	u16 capab_info, listen_interval, seq_ctrl, fc;
5650 	int resp = WLAN_STATUS_SUCCESS;
5651 	u16 reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
5652 	const u8 *pos;
5653 	int left, i;
5654 	struct sta_info *sta;
5655 	u8 *tmp = NULL;
5656 #ifdef CONFIG_FILS
5657 	int delay_assoc = 0;
5658 #endif /* CONFIG_FILS */
5659 	int omit_rsnxe = 0;
5660 
5661 	if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
5662 				      sizeof(mgmt->u.assoc_req))) {
5663 		wpa_printf(MSG_INFO, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
5664 			   reassoc, (unsigned long) len);
5665 		return;
5666 	}
5667 
5668 #ifdef CONFIG_TESTING_OPTIONS
5669 	if (reassoc) {
5670 		if (hapd->iconf->ignore_reassoc_probability > 0.0 &&
5671 		    drand48() < hapd->iconf->ignore_reassoc_probability) {
5672 			wpa_printf(MSG_INFO,
5673 				   "TESTING: ignoring reassoc request from "
5674 				   MACSTR, MAC2STR(mgmt->sa));
5675 			return;
5676 		}
5677 	} else {
5678 		if (hapd->iconf->ignore_assoc_probability > 0.0 &&
5679 		    drand48() < hapd->iconf->ignore_assoc_probability) {
5680 			wpa_printf(MSG_INFO,
5681 				   "TESTING: ignoring assoc request from "
5682 				   MACSTR, MAC2STR(mgmt->sa));
5683 			return;
5684 		}
5685 	}
5686 #endif /* CONFIG_TESTING_OPTIONS */
5687 
5688 	fc = le_to_host16(mgmt->frame_control);
5689 	seq_ctrl = le_to_host16(mgmt->seq_ctrl);
5690 
5691 	if (reassoc) {
5692 		capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
5693 		listen_interval = le_to_host16(
5694 			mgmt->u.reassoc_req.listen_interval);
5695 		wpa_warning_log4(MSG_DEBUG, "reassociation request: STA = %02x:xx:xx:%02x:%02x:%02x",
5696 			   (mgmt->sa)[0], (mgmt->sa)[3], (mgmt->sa)[4], (mgmt->sa)[5]);
5697 		wpa_warning_log2(MSG_DEBUG, "reassociation request: STA="
5698 			   " capab_info=0x%02x listen_interval=%d",
5699 			   capab_info, listen_interval);
5700 		wpa_warning_log4(MSG_DEBUG, "reassociation request: STA="
5701 			   " current_ap=" "%02x:xx:xx:%02x:%02x:%02x",
5702 			   (mgmt->u.reassoc_req.current_ap)[0], (mgmt->u.reassoc_req.current_ap)[3],
5703 			   (mgmt->u.reassoc_req.current_ap)[4], (mgmt->u.reassoc_req.current_ap)[5]);
5704 		wpa_warning_log1(MSG_DEBUG, "reassociation request: STA="  " seq_ctrl=0x%x", seq_ctrl);
5705 		wpa_warning_buf(MSG_DEBUG, "reassociation request: STA=" "%s",
5706 					(fc & WLAN_FC_RETRY) ? " retry" : "",
5707 					(fc & WLAN_FC_RETRY) ? strlen(" retry") : strlen(""));
5708 		left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
5709 		pos = mgmt->u.reassoc_req.variable;
5710 	} else {
5711 		capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
5712 		listen_interval = le_to_host16(
5713 			mgmt->u.assoc_req.listen_interval);
5714 		wpa_warning_log4(MSG_DEBUG, "association request: STA=" "%02x:xx:xx:%02x:%02x:%02x",
5715 			   (mgmt->sa)[0], (mgmt->sa)[3], (mgmt->sa)[4], (mgmt->sa)[5]));
5716 		wpa_warning_log3(MSG_DEBUG, "association request: STA="
5717 			   " capab_info=0x%02x listen_interval=%d "
5718 			   "seq_ctrl=0x%x", capab_info, listen_interval, seq_ctrl);
5719 		wpa_warning_buf(MSG_DEBUG, "association request: STA="
5720 			   "%s", (fc & WLAN_FC_RETRY) ? " retry" : "",
5721 			   (fc & WLAN_FC_RETRY) ? strlen(" retry") : strlen(""));
5722 		left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
5723 		pos = mgmt->u.assoc_req.variable;
5724 	}
5725 
5726 	sta = ap_get_sta(hapd, mgmt->sa);
5727 #ifdef CONFIG_IEEE80211R_AP
5728 	if (sta && sta->auth_alg == WLAN_AUTH_FT &&
5729 	    (sta->flags & WLAN_STA_AUTH) == 0) {
5730 		wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
5731 			   "prior to authentication since it is using "
5732 			   "over-the-DS FT", MAC2STR(mgmt->sa));
5733 
5734 		/*
5735 		 * Mark station as authenticated, to avoid adding station
5736 		 * entry in the driver as associated and not authenticated
5737 		 */
5738 		sta->flags |= WLAN_STA_AUTH;
5739 	} else
5740 #endif /* CONFIG_IEEE80211R_AP */
5741 	if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
5742 		if (hapd->iface->current_mode &&
5743 		    hapd->iface->current_mode->mode ==
5744 			HOSTAPD_MODE_IEEE80211AD) {
5745 #ifndef EXT_CODE_CROP
5746 			int acl_res;
5747 			struct radius_sta info;
5748 
5749 			acl_res = ieee802_11_allowed_address(hapd, mgmt->sa,
5750 							     (const u8 *) mgmt,
5751 							     len, &info);
5752 			if (acl_res == HOSTAPD_ACL_REJECT) {
5753 				wpa_msg(hapd->msg_ctx, MSG_DEBUG,
5754 					"Ignore Association Request frame from "
5755 					MACSTR " due to ACL reject",
5756 					MAC2STR(mgmt->sa));
5757 				resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5758 				goto fail;
5759 			}
5760 			if (acl_res == HOSTAPD_ACL_PENDING)
5761 				return;
5762 #endif /* EXT_CODE_CROP */
5763 			/* DMG/IEEE 802.11ad does not use authentication.
5764 			 * Allocate sta entry upon association. */
5765 			sta = ap_sta_add(hapd, mgmt->sa);
5766 			if (!sta) {
5767 				hostapd_logger(hapd, mgmt->sa,
5768 					       HOSTAPD_MODULE_IEEE80211,
5769 					       HOSTAPD_LEVEL_INFO,
5770 					       "Failed to add STA");
5771 				resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
5772 				goto fail;
5773 			}
5774 #ifndef EXT_CODE_CROP
5775 			acl_res = ieee802_11_set_radius_info(
5776 				hapd, sta, acl_res, &info);
5777 			if (acl_res) {
5778 				resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5779 				goto fail;
5780 			}
5781 #endif /* EXT_CODE_CROP */
5782 			hostapd_logger(hapd, sta->addr,
5783 				       HOSTAPD_MODULE_IEEE80211,
5784 				       HOSTAPD_LEVEL_DEBUG,
5785 				       "Skip authentication for DMG/IEEE 802.11ad");
5786 			sta->flags |= WLAN_STA_AUTH;
5787 			wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
5788 			sta->auth_alg = WLAN_AUTH_OPEN;
5789 		} else {
5790 			hostapd_logger(hapd, mgmt->sa,
5791 				       HOSTAPD_MODULE_IEEE80211,
5792 				       HOSTAPD_LEVEL_INFO,
5793 				       "Station tried to associate before authentication (aid=%d flags=0x%x)",
5794 				       sta ? sta->aid : -1,
5795 				       sta ? sta->flags : 0);
5796 			send_deauth(hapd, mgmt->sa,
5797 				    WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
5798 			return;
5799 		}
5800 	}
5801 
5802 	if ((fc & WLAN_FC_RETRY) &&
5803 	    sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
5804 	    sta->last_seq_ctrl == seq_ctrl &&
5805 	    sta->last_subtype == (reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
5806 				  WLAN_FC_STYPE_ASSOC_REQ)) {
5807 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
5808 			       HOSTAPD_LEVEL_DEBUG,
5809 			       "Drop repeated association frame seq_ctrl=0x%x",
5810 			       seq_ctrl);
5811 		return;
5812 	}
5813 	sta->last_seq_ctrl = seq_ctrl;
5814 	sta->last_subtype = reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
5815 		WLAN_FC_STYPE_ASSOC_REQ;
5816 
5817 	if (hapd->tkip_countermeasures) {
5818 		resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5819 		goto fail;
5820 	}
5821 
5822 	if (listen_interval > hapd->conf->max_listen_interval) {
5823 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
5824 			       HOSTAPD_LEVEL_DEBUG,
5825 			       "Too large Listen Interval (%d)",
5826 			       listen_interval);
5827 		resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
5828 		goto fail;
5829 	}
5830 
5831 #ifdef CONFIG_MBO
5832 	if (hapd->conf->mbo_enabled && hapd->mbo_assoc_disallow) {
5833 		resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
5834 		goto fail;
5835 	}
5836 
5837 	if (hapd->iconf->rssi_reject_assoc_rssi && rssi &&
5838 	    rssi < hapd->iconf->rssi_reject_assoc_rssi &&
5839 	    (sta->auth_rssi == 0 ||
5840 	     sta->auth_rssi < hapd->iconf->rssi_reject_assoc_rssi)) {
5841 		resp = WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS;
5842 		goto fail;
5843 	}
5844 #endif /* CONFIG_MBO */
5845 
5846 	/*
5847 	 * sta->capability is used in check_assoc_ies() for RRM enabled
5848 	 * capability element.
5849 	 */
5850 	sta->capability = capab_info;
5851 
5852 #ifdef CONFIG_FILS
5853 	if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
5854 	    sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
5855 	    sta->auth_alg == WLAN_AUTH_FILS_PK) {
5856 		int res;
5857 
5858 		/* The end of the payload is encrypted. Need to decrypt it
5859 		 * before parsing. */
5860 
5861 		tmp = os_memdup(pos, left);
5862 		if (!tmp) {
5863 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5864 			goto fail;
5865 		}
5866 
5867 		res = fils_decrypt_assoc(sta->wpa_sm, sta->fils_session, mgmt,
5868 					 len, tmp, left);
5869 		if (res < 0) {
5870 			resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5871 			goto fail;
5872 		}
5873 		pos = tmp;
5874 		left = res;
5875 	}
5876 #endif /* CONFIG_FILS */
5877 
5878 	/* followed by SSID and Supported rates; and HT capabilities if 802.11n
5879 	 * is used */
5880 	resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
5881 	if (resp != WLAN_STATUS_SUCCESS)
5882 		goto fail;
5883 	omit_rsnxe = !get_ie(pos, left, WLAN_EID_RSNX);
5884 
5885 	if (hostapd_get_aid(hapd, sta) < 0) {
5886 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
5887 			       HOSTAPD_LEVEL_INFO, "No room for more AIDs");
5888 		resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
5889 		goto fail;
5890 	}
5891 
5892 	sta->listen_interval = listen_interval;
5893 
5894 	if (hapd->iface->current_mode &&
5895 	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
5896 		sta->flags |= WLAN_STA_NONERP;
5897 	for (i = 0; i < sta->supported_rates_len; i++) {
5898 		if ((sta->supported_rates[i] & 0x7f) > 22) {
5899 			sta->flags &= ~WLAN_STA_NONERP;
5900 			break;
5901 		}
5902 	}
5903 	if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
5904 		sta->nonerp_set = 1;
5905 		hapd->iface->num_sta_non_erp++;
5906 		if (hapd->iface->num_sta_non_erp == 1)
5907 			ieee802_11_set_beacons(hapd->iface);
5908 	}
5909 
5910 	if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
5911 	    !sta->no_short_slot_time_set) {
5912 		sta->no_short_slot_time_set = 1;
5913 		hapd->iface->num_sta_no_short_slot_time++;
5914 		if (hapd->iface->current_mode &&
5915 		    hapd->iface->current_mode->mode ==
5916 		    HOSTAPD_MODE_IEEE80211G &&
5917 		    hapd->iface->num_sta_no_short_slot_time == 1)
5918 			ieee802_11_set_beacons(hapd->iface);
5919 	}
5920 
5921 	if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
5922 		sta->flags |= WLAN_STA_SHORT_PREAMBLE;
5923 	else
5924 		sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
5925 
5926 	if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
5927 	    !sta->no_short_preamble_set) {
5928 		sta->no_short_preamble_set = 1;
5929 		hapd->iface->num_sta_no_short_preamble++;
5930 		if (hapd->iface->current_mode &&
5931 		    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
5932 		    && hapd->iface->num_sta_no_short_preamble == 1)
5933 			ieee802_11_set_beacons(hapd->iface);
5934 	}
5935 
5936 	update_ht_state(hapd, sta);
5937 
5938 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
5939 		       HOSTAPD_LEVEL_DEBUG,
5940 		       "association OK (aid %d)", sta->aid);
5941 	/* Station will be marked associated, after it acknowledges AssocResp
5942 	 */
5943 	sta->flags |= WLAN_STA_ASSOC_REQ_OK;
5944 
5945 	if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) {
5946 		wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out "
5947 			   "SA Query procedure", reassoc ? "re" : "");
5948 		/* TODO: Send a protected Disassociate frame to the STA using
5949 		 * the old key and Reason Code "Previous Authentication no
5950 		 * longer valid". Make sure this is only sent protected since
5951 		 * unprotected frame would be received by the STA that is now
5952 		 * trying to associate.
5953 		 */
5954 	}
5955 
5956 	/* Make sure that the previously registered inactivity timer will not
5957 	 * remove the STA immediately. */
5958 	sta->timeout_next = STA_NULLFUNC;
5959 
5960 #ifdef CONFIG_TAXONOMY
5961 	taxonomy_sta_info_assoc_req(hapd, sta, pos, left);
5962 #endif /* CONFIG_TAXONOMY */
5963 
5964 #ifndef EXT_CODE_CROP
5965 	sta->pending_wds_enable = 0;
5966 #endif /* EXT_CODE_CROP */
5967 
5968 #ifdef CONFIG_FILS
5969 	if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
5970 	    sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
5971 	    sta->auth_alg == WLAN_AUTH_FILS_PK) {
5972 		if (fils_process_hlp(hapd, sta, pos, left) > 0)
5973 			delay_assoc = 1;
5974 	}
5975 #endif /* CONFIG_FILS */
5976 
5977  fail:
5978 
5979 	/*
5980 	 * In case of a successful response, add the station to the driver.
5981 	 * Otherwise, the kernel may ignore Data frames before we process the
5982 	 * ACK frame (TX status). In case of a failure, this station will be
5983 	 * removed.
5984 	 *
5985 	 * Note that this is not compliant with the IEEE 802.11 standard that
5986 	 * states that a non-AP station should transition into the
5987 	 * authenticated/associated state only after the station acknowledges
5988 	 * the (Re)Association Response frame. However, still do this as:
5989 	 *
5990 	 * 1. In case the station does not acknowledge the (Re)Association
5991 	 *    Response frame, it will be removed.
5992 	 * 2. Data frames will be dropped in the kernel until the station is
5993 	 *    set into authorized state, and there are no significant known
5994 	 *    issues with processing other non-Data Class 3 frames during this
5995 	 *    window.
5996 	 */
5997 	if (resp == WLAN_STATUS_SUCCESS && sta &&
5998 	    add_associated_sta(hapd, sta, reassoc))
5999 		resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
6000 
6001 #ifdef CONFIG_FILS
6002 	if (sta && delay_assoc && resp == WLAN_STATUS_SUCCESS &&
6003 	    eloop_is_timeout_registered(fils_hlp_timeout, hapd, sta) &&
6004 	    sta->fils_pending_assoc_req) {
6005 		/* Do not reschedule fils_hlp_timeout in case the station
6006 		 * retransmits (Re)Association Request frame while waiting for
6007 		 * the previously started FILS HLP wait, so that the timeout can
6008 		 * be determined from the first pending attempt. */
6009 		wpa_printf(MSG_DEBUG,
6010 			   "FILS: Continue waiting for HLP processing before sending (Re)Association Response frame to "
6011 			   MACSTR, MAC2STR(sta->addr));
6012 		os_free(tmp);
6013 		return;
6014 	}
6015 	if (sta) {
6016 		eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
6017 		os_free(sta->fils_pending_assoc_req);
6018 		sta->fils_pending_assoc_req = NULL;
6019 		sta->fils_pending_assoc_req_len = 0;
6020 		wpabuf_free(sta->fils_hlp_resp);
6021 		sta->fils_hlp_resp = NULL;
6022 	}
6023 	if (sta && delay_assoc && resp == WLAN_STATUS_SUCCESS) {
6024 		sta->fils_pending_assoc_req = tmp;
6025 		sta->fils_pending_assoc_req_len = left;
6026 		sta->fils_pending_assoc_is_reassoc = reassoc;
6027 		sta->fils_drv_assoc_finish = 0;
6028 		wpa_printf(MSG_DEBUG,
6029 			   "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
6030 			   MACSTR, MAC2STR(sta->addr));
6031 		eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
6032 		eloop_register_timeout(0, hapd->conf->fils_hlp_wait_time * 1024,
6033 				       fils_hlp_timeout, hapd, sta);
6034 		return;
6035 	}
6036 #endif /* CONFIG_FILS */
6037 
6038 	if (resp >= 0)
6039 		reply_res = send_assoc_resp(hapd, sta, mgmt->sa, resp, reassoc,
6040 					    pos, left, rssi, omit_rsnxe);
6041 	os_free(tmp);
6042 
6043 	/*
6044 	 * Remove the station in case transmission of a success response fails
6045 	 * (the STA was added associated to the driver) or if the station was
6046 	 * previously added unassociated.
6047 	 */
6048 	if (sta && ((reply_res != WLAN_STATUS_SUCCESS &&
6049 		     resp == WLAN_STATUS_SUCCESS) || sta->added_unassoc)) {
6050 		hostapd_drv_sta_remove(hapd, sta->addr);
6051 		sta->added_unassoc = 0;
6052 	}
6053 }
6054 
6055 
6056 static void handle_disassoc(struct hostapd_data *hapd,
6057 			    const struct ieee80211_mgmt *mgmt, size_t len)
6058 {
6059 	struct sta_info *sta;
6060 
6061 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
6062 		wpa_warning_log1(MSG_INFO, "handle_disassoc - too short payload (len=%lu)",
6063 			   (unsigned long) len);
6064 		return;
6065 	}
6066 
6067 	wpa_warning_log4(MSG_DEBUG, "disassocation: STA=" "%02x:xx:xx:%02x:%02x:%02x",
6068 		   (mgmt->sa)[0], (mgmt->sa)[3], (mgmt->sa)[4], (mgmt->sa)[5]);
6069 	wpa_warning_log1(MSG_DEBUG, " reason_code=%d",
6070 		   le_to_host16(mgmt->u.disassoc.reason_code));
6071 
6072 	sta = ap_get_sta(hapd, mgmt->sa);
6073 	if (sta == NULL) {
6074 		wpa_warning_log4(MSG_INFO, "Station " "%02x:xx:xx:%02x:%02x:%02x" " trying to disassociate, but it is not associated",
6075 			   (mgmt->sa)[0], (mgmt->sa)[3], (mgmt->sa)[4], (mgmt->sa)[5]);
6076 		return;
6077 	}
6078 
6079 	ap_sta_set_authorized(hapd, sta, 0);
6080 	sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
6081 	sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
6082 	hostapd_set_sta_flags(hapd, sta);
6083 	wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
6084 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
6085 		       HOSTAPD_LEVEL_INFO, "disassociated");
6086 #ifndef EXT_CODE_CROP
6087 	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
6088 #endif /* EXT_CODE_CROP */
6089 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
6090 	/* Stop Accounting and IEEE 802.1X sessions, but leave the STA
6091 	 * authenticated. */
6092 	accounting_sta_stop(hapd, sta);
6093 	ieee802_1x_free_station(hapd, sta);
6094 	if (sta->ipaddr)
6095 		hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr);
6096 	ap_sta_ip6addr_del(hapd, sta);
6097 	hostapd_drv_sta_remove(hapd, sta->addr);
6098 	sta->added_unassoc = 0;
6099 
6100 	if (sta->timeout_next == STA_NULLFUNC ||
6101 	    sta->timeout_next == STA_DISASSOC) {
6102 		sta->timeout_next = STA_DEAUTH;
6103 		eloop_cancel_timeout(ap_handle_timer, hapd, sta);
6104 		eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
6105 				       hapd, sta);
6106 	}
6107 
6108 	mlme_disassociate_indication(
6109 		hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
6110 #ifndef EXT_CODE_CROP
6111 	/* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
6112 	 * disassociation. */
6113 	if (hapd->iface->current_mode &&
6114 	    hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211AD) {
6115 		sta->flags &= ~WLAN_STA_AUTH;
6116 		wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
6117 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
6118 			       HOSTAPD_LEVEL_DEBUG, "deauthenticated");
6119 		ap_free_sta(hapd, sta);
6120 	}
6121 #endif /* EXT_CODE_CROP */
6122 }
6123 
6124 
6125 static void handle_deauth(struct hostapd_data *hapd,
6126 			  const struct ieee80211_mgmt *mgmt, size_t len)
6127 {
6128 	struct sta_info *sta;
6129 
6130 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
6131 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "handle_deauth - too short "
6132 			"payload (len=%lu)", (unsigned long) len);
6133 		return;
6134 	}
6135 
6136 	wpa_msg(hapd->msg_ctx, MSG_DEBUG, "deauthentication: STA=" MACSTR
6137 		" reason_code=%d",
6138 		MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
6139 
6140 	/* Clear the PTKSA cache entries for PASN */
6141 	ptksa_cache_flush(hapd->ptksa, mgmt->sa, WPA_CIPHER_NONE);
6142 
6143 	sta = ap_get_sta(hapd, mgmt->sa);
6144 	if (sta == NULL) {
6145 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
6146 			"to deauthenticate, but it is not authenticated",
6147 			MAC2STR(mgmt->sa));
6148 		return;
6149 	}
6150 
6151 	ap_sta_set_authorized(hapd, sta, 0);
6152 	sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
6153 	sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
6154 			WLAN_STA_ASSOC_REQ_OK);
6155 	hostapd_set_sta_flags(hapd, sta);
6156 	wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
6157 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
6158 		       HOSTAPD_LEVEL_DEBUG, "deauthenticated");
6159 	mlme_deauthenticate_indication(
6160 		hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
6161 #ifndef EXT_CODE_CROP
6162 	sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
6163 #endif /* EXT_CODE_CROP */
6164 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
6165 	ap_free_sta(hapd, sta);
6166 }
6167 
6168 
6169 static void handle_beacon(struct hostapd_data *hapd,
6170 			  const struct ieee80211_mgmt *mgmt, size_t len,
6171 			  struct hostapd_frame_info *fi)
6172 {
6173 	struct ieee802_11_elems elems;
6174 
6175 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
6176 		wpa_warning_log1(MSG_INFO, "handle_beacon - too short payload (len=%lu)",
6177 			   (unsigned long) len);
6178 		return;
6179 	}
6180 
6181 	(void) ieee802_11_parse_elems(mgmt->u.beacon.variable,
6182 				      len - (IEEE80211_HDRLEN +
6183 					     sizeof(mgmt->u.beacon)), &elems,
6184 				      0);
6185 
6186 	ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
6187 }
6188 #endif /*LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT*/
6189 
6190 #ifdef CONFIG_IEEE80211W_AP
6191 static int robust_action_frame(u8 category)
6192 {
6193 	return category != WLAN_ACTION_PUBLIC &&
6194 		category != WLAN_ACTION_HT;
6195 }
6196 #endif /* CONFIG_IEEE80211W_AP */
6197 
6198 #ifdef LOS_CONFIG_HOSTAPD_MGMT
6199 #ifdef CONFIG_P2P
6200 static int handle_action(struct hostapd_data *hapd,
6201 			 const struct ieee80211_mgmt *mgmt, size_t len,
6202 			 unsigned int freq)
6203 {
6204 	struct sta_info *sta;
6205 	u8 *action __maybe_unused;
6206 
6207 	if (len < IEEE80211_HDRLEN + 2 + 1) {
6208 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
6209 			       HOSTAPD_LEVEL_DEBUG,
6210 			       "handle_action - too short payload (len=%lu)",
6211 			       (unsigned long) len);
6212 		return 0;
6213 	}
6214 
6215 	action = (u8 *) &mgmt->u.action.u;
6216 	wpa_warning_log4(MSG_DEBUG, "RX_ACTION category %u action %u"
6217 		  " len %d freq %u",
6218 		   mgmt->u.action.category, *action, (int) len, freq);
6219 	wpa_warning_log4(MSG_DEBUG, "sa " "%02x:xx:xx:%02x:%02x:%02x",
6220 		   (mgmt->sa)[0], (mgmt->sa)[3], (mgmt->sa)[4], (mgmt->sa)[5]);
6221 	wpa_warning_log4(MSG_DEBUG, " da " "%02x:xx:xx:%02x:%02x:%02x",
6222 		   (mgmt->da)[0], (mgmt->da)[3], (mgmt->da)[4], (mgmt->da)[5]);
6223 	sta = ap_get_sta(hapd, mgmt->sa);
6224 
6225 	if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
6226 	    (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
6227 		wpa_warning_log1(MSG_DEBUG, "IEEE 802.11: Ignored Action "
6228 			   "frame (category=%u) from unassociated STA ",
6229 			   mgmt->u.action.category);
6230 		wpa_warning_log4(MSG_DEBUG, "%02x:xx:xx:%02x:%02x:%02x",
6231 			   (mgmt->sa)[0], (mgmt->sa)[3], (mgmt->sa)[4], (mgmt->sa)[5]);
6232 		return 0;
6233 	}
6234 
6235 #ifdef CONFIG_IEEE80211W_AP
6236 	if (sta && (sta->flags & WLAN_STA_MFP) &&
6237 	    !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP)) &&
6238 	    robust_action_frame(mgmt->u.action.category)) {
6239 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
6240 			       HOSTAPD_LEVEL_DEBUG,
6241 			       "Dropped unprotected Robust Action frame from "
6242 			       "an MFP STA");
6243 		return 0;
6244 	}
6245 #endif /* CONFIG_IEEE80211W_AP */
6246 
6247 	if (sta) {
6248 		u16 fc = le_to_host16(mgmt->frame_control);
6249 		u16 seq_ctrl = le_to_host16(mgmt->seq_ctrl);
6250 
6251 		if ((fc & WLAN_FC_RETRY) &&
6252 		    sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
6253 		    sta->last_seq_ctrl == seq_ctrl &&
6254 		    sta->last_subtype == WLAN_FC_STYPE_ACTION) {
6255 			hostapd_logger(hapd, sta->addr,
6256 				       HOSTAPD_MODULE_IEEE80211,
6257 				       HOSTAPD_LEVEL_DEBUG,
6258 				       "Drop repeated action frame seq_ctrl=0x%x",
6259 				       seq_ctrl);
6260 			return 1;
6261 		}
6262 
6263 		sta->last_seq_ctrl = seq_ctrl;
6264 		sta->last_subtype = WLAN_FC_STYPE_ACTION;
6265 	}
6266 
6267 	switch (mgmt->u.action.category) {
6268 #ifdef CONFIG_IEEE80211R_AP
6269 	case WLAN_ACTION_FT:
6270 		if (!sta ||
6271 		    wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
6272 				     len - IEEE80211_HDRLEN))
6273 			break;
6274 		return 1;
6275 #endif /* CONFIG_IEEE80211R_AP */
6276 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
6277 	case WLAN_ACTION_WMM:
6278 		hostapd_wmm_action(hapd, mgmt, len);
6279 		return 1;
6280 #endif /*LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT*/
6281 #ifdef CONFIG_IEEE80211W_AP
6282 	case WLAN_ACTION_SA_QUERY:
6283 		ieee802_11_sa_query_action(hapd, mgmt, len);
6284 		return 1;
6285 #endif /* CONFIG_IEEE80211W_AP */
6286 #ifdef CONFIG_WNM_AP
6287 	case WLAN_ACTION_WNM:
6288 		ieee802_11_rx_wnm_action_ap(hapd, mgmt, len);
6289 		return 1;
6290 #endif /* CONFIG_WNM_AP */
6291 #ifdef CONFIG_FST
6292 	case WLAN_ACTION_FST:
6293 		if (hapd->iface->fst)
6294 			fst_rx_action(hapd->iface->fst, mgmt, len);
6295 		else
6296 			wpa_warning_log0(MSG_DEBUG,
6297 				   "FST: Ignore FST Action frame - no FST attached");
6298 		return 1;
6299 #endif /* CONFIG_FST */
6300 #ifdef CONFIG_P2P
6301 	case WLAN_ACTION_PUBLIC:
6302 	case WLAN_ACTION_PROTECTED_DUAL:
6303 #ifndef EXT_CODE_CROP
6304 		if (len >= IEEE80211_HDRLEN + 2 &&
6305 		    mgmt->u.action.u.public_action.action ==
6306 		    WLAN_PA_20_40_BSS_COEX) {
6307 			hostapd_2040_coex_action(hapd, mgmt, len);
6308 			return 1;
6309 		}
6310 #endif /* EXT_CODE_CROP */
6311 #ifdef CONFIG_DPP
6312 		if (len >= IEEE80211_HDRLEN + 6 &&
6313 		    mgmt->u.action.u.vs_public_action.action ==
6314 		    WLAN_PA_VENDOR_SPECIFIC &&
6315 		    WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
6316 		    OUI_WFA &&
6317 		    mgmt->u.action.u.vs_public_action.variable[0] ==
6318 		    DPP_OUI_TYPE) {
6319 			const u8 *pos, *end;
6320 
6321 			pos = mgmt->u.action.u.vs_public_action.oui;
6322 			end = ((const u8 *) mgmt) + len;
6323 			hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
6324 					      freq);
6325 			return 1;
6326 		}
6327 		if (len >= IEEE80211_HDRLEN + 2 &&
6328 		    (mgmt->u.action.u.public_action.action ==
6329 		     WLAN_PA_GAS_INITIAL_RESP ||
6330 		     mgmt->u.action.u.public_action.action ==
6331 		     WLAN_PA_GAS_COMEBACK_RESP)) {
6332 			const u8 *pos, *end;
6333 
6334 			pos = &mgmt->u.action.u.public_action.action;
6335 			end = ((const u8 *) mgmt) + len;
6336 			gas_query_ap_rx(hapd->gas, mgmt->sa,
6337 					mgmt->u.action.category,
6338 					pos, end - pos, hapd->iface->freq);
6339 			return 1;
6340 		}
6341 #endif /* CONFIG_DPP */
6342 		if (hapd->public_action_cb) {
6343 			hapd->public_action_cb(hapd->public_action_cb_ctx,
6344 					       (u8 *) mgmt, len,
6345 					       hapd->iface->freq);
6346 		}
6347 #ifndef EXT_CODE_CROP
6348 		if (hapd->public_action_cb2) {
6349 			hapd->public_action_cb2(hapd->public_action_cb2_ctx,
6350 						(u8 *) mgmt, len,
6351 						hapd->iface->freq);
6352 		}
6353 		if (hapd->public_action_cb || hapd->public_action_cb2)
6354 #else
6355 		if (hapd->public_action_cb)
6356 #endif /* EXT_CODE_CROP */
6357 			return 1;
6358 		break;
6359 	case WLAN_ACTION_VENDOR_SPECIFIC:
6360 		if (hapd->vendor_action_cb) {
6361 			if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx,
6362 						   (u8 *) mgmt, len,
6363 						   hapd->iface->freq) == 0)
6364 				return 1;
6365 		}
6366 		break;
6367 #endif /* CONFIG_P2P */
6368 #ifndef LOS_CONFIG_HOSTAPD_RRM
6369 	case WLAN_ACTION_RADIO_MEASUREMENT:
6370 		hostapd_handle_radio_measurement(hapd, (const u8 *) mgmt, len);
6371 		return 1;
6372 #endif /* LOS_CONFIG_HOSTAPD_RRM */
6373 	}
6374 
6375 	hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
6376 		       HOSTAPD_LEVEL_DEBUG,
6377 		       "handle_action - unknown action category %d or invalid "
6378 		       "frame",
6379 		       mgmt->u.action.category);
6380 	if (!is_multicast_ether_addr(mgmt->da) &&
6381 	    !(mgmt->u.action.category & 0x80) &&
6382 	    !is_multicast_ether_addr(mgmt->sa)) {
6383 		struct ieee80211_mgmt *resp;
6384 
6385 		/*
6386 		 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
6387 		 * Return the Action frame to the source without change
6388 		 * except that MSB of the Category set to 1.
6389 		 */
6390 		wpa_warning_log0(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
6391 			   "frame back to sender");
6392 		resp = os_memdup(mgmt, len);
6393 		if (resp == NULL)
6394 			return 0;
6395 		os_memcpy(resp->da, resp->sa, ETH_ALEN);
6396 		os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
6397 		os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
6398 		resp->u.action.category |= 0x80;
6399 
6400 		if (hostapd_drv_send_mlme(hapd, resp, len, 0, NULL, 0, 0) < 0) {
6401 			wpa_error_log0(MSG_ERROR, "IEEE 802.11: Failed to send "
6402 				   "Action frame");
6403 		}
6404 		os_free(resp);
6405 	}
6406 
6407 	return 1;
6408 }
6409 #endif /* CONFIG_P2P */
6410 
6411 /**
6412  * notify_mgmt_frame - Notify of Management frames on the control interface
6413  * @hapd: hostapd BSS data structure (the BSS to which the Management frame was
6414  * sent to)
6415  * @buf: Management frame data (starting from the IEEE 802.11 header)
6416  * @len: Length of frame data in octets
6417  *
6418  * Notify the control interface of any received Management frame.
6419  */
6420 static void notify_mgmt_frame(struct hostapd_data *hapd, const u8 *buf,
6421 			      size_t len)
6422 {
6423 
6424 	int hex_len = len * 2 + 1;
6425 	char *hex = os_malloc(hex_len);
6426 
6427 	if (hex) {
6428 		wpa_snprintf_hex(hex, hex_len, buf, len);
6429 		wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO,
6430 			     AP_MGMT_FRAME_RECEIVED "buf=%s", hex);
6431 		os_free(hex);
6432 	}
6433 }
6434 
6435 
6436 /**
6437  * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
6438  * @hapd: hostapd BSS data structure (the BSS to which the management frame was
6439  * sent to)
6440  * @buf: management frame data (starting from IEEE 802.11 header)
6441  * @len: length of frame data in octets
6442  * @fi: meta data about received frame (signal level, etc.)
6443  *
6444  * Process all incoming IEEE 802.11 management frames. This will be called for
6445  * each frame received from the kernel driver through wlan#ap interface. In
6446  * addition, it can be called to re-inserted pending frames (e.g., when using
6447  * external RADIUS server as an MAC ACL).
6448  */
6449 int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
6450 		    struct hostapd_frame_info *fi)
6451 {
6452 	struct ieee80211_mgmt *mgmt;
6453 	u16 fc, stype;
6454 	int ret = 0;
6455 	unsigned int freq;
6456 	int ssi_signal = fi ? fi->ssi_signal : 0;
6457 
6458 	if (len < 24)
6459 		return 0;
6460 
6461 	if (fi && fi->freq)
6462 		freq = fi->freq;
6463 	else
6464 		freq = hapd->iface->freq;
6465 
6466 	mgmt = (struct ieee80211_mgmt *) buf;
6467 	fc = le_to_host16(mgmt->frame_control);
6468 	stype = WLAN_FC_GET_STYPE(fc);
6469 
6470 	if (is_multicast_ether_addr(mgmt->sa) ||
6471 	    is_zero_ether_addr(mgmt->sa) ||
6472 	    os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
6473 		/* Do not process any frames with unexpected/invalid SA so that
6474 		 * we do not add any state for unexpected STA addresses or end
6475 		 * up sending out frames to unexpected destination. */
6476 		wpa_printf(MSG_DEBUG, "MGMT: Invalid SA=" MACSTR
6477 			   " in received frame - ignore this frame silently",
6478 			   MAC2STR(mgmt->sa));
6479 		return 0;
6480 	}
6481 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
6482 	if (stype == WLAN_FC_STYPE_BEACON) {
6483 		handle_beacon(hapd, mgmt, len, fi);
6484 		return 1;
6485 	}
6486 #endif /*LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT*/
6487 	if (!is_broadcast_ether_addr(mgmt->bssid) &&
6488 #ifdef CONFIG_P2P
6489 	    /* Invitation responses can be sent with the peer MAC as BSSID */
6490 	    !((hapd->conf->p2p & P2P_GROUP_OWNER) &&
6491 	      stype == WLAN_FC_STYPE_ACTION) &&
6492 #endif /* CONFIG_P2P */
6493 #ifdef CONFIG_MESH
6494 	    !(hapd->conf->mesh & MESH_ENABLED) &&
6495 #endif /* CONFIG_MESH */
6496 	    os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) {
6497 		wpa_warning_log4(MSG_INFO, "MGMT: BSSID=" "%02x:xx:xx:%02x:%02x:%02x" " not our address",
6498 			   (mgmt->bssid)[0], (mgmt->bssid)[3], (mgmt->bssid)[4], (mgmt->bssid)[5]);
6499 		return 0;
6500 	}
6501 
6502 	if (hapd->iface->state != HAPD_IFACE_ENABLED) {
6503 		wpa_printf(MSG_DEBUG, "MGMT: Ignore management frame while interface is not enabled (SA=" MACSTR " DA=" MACSTR " subtype=%u)",
6504 			   MAC2STR(mgmt->sa), MAC2STR(mgmt->da), stype);
6505 		return 1;
6506 	}
6507 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
6508 	if (stype == WLAN_FC_STYPE_PROBE_REQ) {
6509 		handle_probe_req(hapd, mgmt, len, ssi_signal);
6510 		return 1;
6511 	}
6512 #endif /*LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT*/
6513 	if ((!is_broadcast_ether_addr(mgmt->da) ||
6514 	     stype != WLAN_FC_STYPE_ACTION) &&
6515 	    os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
6516 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
6517 			       HOSTAPD_LEVEL_DEBUG,
6518 			       "MGMT: DA=" MACSTR " not our address",
6519 			       MAC2STR(mgmt->da));
6520 		return 0;
6521 	}
6522 
6523 #ifndef EXT_CODE_CROP
6524 	if (hapd->iconf->track_sta_max_num)
6525 		sta_track_add(hapd->iface, mgmt->sa, ssi_signal);
6526 #endif /* EXT_CODE_CROP */
6527 	if (hapd->conf->notify_mgmt_frames)
6528 		notify_mgmt_frame(hapd, buf, len);
6529 
6530 	switch (stype) {
6531 	case WLAN_FC_STYPE_AUTH:
6532 		wpa_warning_log0(MSG_DEBUG, "mgmt::auth");
6533 		handle_auth(hapd, mgmt, len, ssi_signal, 0);
6534 		ret = 1;
6535 		break;
6536 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
6537 	case WLAN_FC_STYPE_ASSOC_REQ:
6538 		wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
6539 		handle_assoc(hapd, mgmt, len, 0, ssi_signal);
6540 		ret = 1;
6541 		break;
6542 	case WLAN_FC_STYPE_REASSOC_REQ:
6543 		wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
6544 		handle_assoc(hapd, mgmt, len, 1, ssi_signal);
6545 		ret = 1;
6546 		break;
6547 	case WLAN_FC_STYPE_DISASSOC:
6548 		wpa_printf(MSG_DEBUG, "mgmt::disassoc");
6549 		handle_disassoc(hapd, mgmt, len);
6550 		ret = 1;
6551 		break;
6552 	case WLAN_FC_STYPE_DEAUTH:
6553 		wpa_msg(hapd->msg_ctx, MSG_DEBUG, "mgmt::deauth");
6554 		handle_deauth(hapd, mgmt, len);
6555 		ret = 1;
6556 		break;
6557 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
6558 #ifdef CONFIG_P2P
6559 	case WLAN_FC_STYPE_ACTION:
6560 		wpa_warning_log0(MSG_DEBUG, "mgmt::action");
6561 		ret = handle_action(hapd, mgmt, len, freq);
6562 		break;
6563 #endif /* CONFIG_P2P */
6564 	default:
6565 		hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
6566 			       HOSTAPD_LEVEL_DEBUG,
6567 			       "unknown mgmt frame subtype %d", stype);
6568 		break;
6569 	}
6570 
6571 	return ret;
6572 }
6573 #endif /* LOS_CONFIG_HOSTAPD_MGMT */
6574 
6575 #ifdef CONFIG_P2P
6576 static void handle_auth_cb(struct hostapd_data *hapd,
6577 			   const struct ieee80211_mgmt *mgmt,
6578 			   size_t len, int ok)
6579 {
6580 	u16 auth_alg, auth_transaction, status_code;
6581 	struct sta_info *sta;
6582 	bool success_status;
6583 
6584 	sta = ap_get_sta(hapd, mgmt->da);
6585 	if (!sta) {
6586 		wpa_warning_log4(MSG_DEBUG, "handle_auth_cb: STA " "%02x:xx:xx:%02x:%02x:%02x"
6587 			   " not found",
6588 			   (mgmt->da)[0], (mgmt->da)[3], (mgmt->da)[4], (mgmt->da)[5]);
6589 		return;
6590 	}
6591 
6592 	if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
6593 		wpa_printf(MSG_INFO, "handle_auth_cb - too short payload (len=%lu)",
6594 			   (unsigned long) len);
6595 		auth_alg = 0;
6596 		auth_transaction = 0;
6597 		status_code = WLAN_STATUS_UNSPECIFIED_FAILURE;
6598 		goto fail;
6599 	}
6600 
6601 	auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
6602 	auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
6603 	status_code = le_to_host16(mgmt->u.auth.status_code);
6604 
6605 	if (!ok) {
6606 		hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
6607 			       HOSTAPD_LEVEL_NOTICE,
6608 			       "did not acknowledge authentication response");
6609 		goto fail;
6610 	}
6611 
6612 	if (status_code == WLAN_STATUS_SUCCESS &&
6613 	    ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
6614 	     (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
6615 		hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
6616 			       HOSTAPD_LEVEL_INFO, "authenticated");
6617 		sta->flags |= WLAN_STA_AUTH;
6618 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
6619 		if (sta->added_unassoc)
6620 			hostapd_set_sta_flags(hapd, sta);
6621 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
6622 		return;
6623 	}
6624 
6625 fail:
6626 	success_status = status_code == WLAN_STATUS_SUCCESS;
6627 #ifdef CONFIG_SAE
6628 	if (auth_alg == WLAN_AUTH_SAE && auth_transaction == 1)
6629 		success_status = sae_status_success(hapd, status_code);
6630 #endif /* CONFIG_SAE */
6631 	if (!success_status && sta->added_unassoc) {
6632 		hostapd_drv_sta_remove(hapd, sta->addr);
6633 		sta->added_unassoc = 0;
6634 	}
6635 }
6636 #endif /* CONFIG_P2P */
6637 
6638 #ifndef EXT_CODE_CROP
6639 static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
6640 				       struct sta_info *sta,
6641 				       char *ifname_wds)
6642 {
6643 #ifdef CONFIG_WEP
6644 	int i;
6645 	struct hostapd_ssid *ssid = &hapd->conf->ssid;
6646 
6647 	if (hapd->conf->ieee802_1x || hapd->conf->wpa)
6648 		return;
6649 
6650 	for (i = 0; i < 4; i++) {
6651 		if (ssid->wep.key[i] &&
6652 		    hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
6653 					0, i == ssid->wep.idx, NULL, 0,
6654 					ssid->wep.key[i], ssid->wep.len[i],
6655 					i == ssid->wep.idx ?
6656 					KEY_FLAG_GROUP_RX_TX_DEFAULT :
6657 					KEY_FLAG_GROUP_RX_TX)) {
6658 			wpa_printf(MSG_WARNING,
6659 				   "Could not set WEP keys for WDS interface; %s",
6660 				   ifname_wds);
6661 			break;
6662 		}
6663 	}
6664 #endif /* CONFIG_WEP */
6665 }
6666 #endif /* EXT_CODE_CROP */
6667 
6668 #ifdef CONFIG_P2P
6669 static void handle_assoc_cb(struct hostapd_data *hapd,
6670 			    const struct ieee80211_mgmt *mgmt,
6671 			    size_t len, int reassoc, int ok)
6672 {
6673 	u16 status;
6674 	struct sta_info *sta;
6675 	int new_assoc = 1;
6676 
6677 	sta = ap_get_sta(hapd, mgmt->da);
6678 	if (!sta) {
6679 		wpa_warning_log4(MSG_INFO, "handle_assoc_cb: STA " "%02x:xx:xx:%02x:%02x:%02x" " not found",
6680 			   (mgmt->da)[0], (mgmt->da)[3], (mgmt->da)[4], (mgmt->da)[5]);
6681 		return;
6682 	}
6683 
6684 	if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
6685 				      sizeof(mgmt->u.assoc_resp))) {
6686 		wpa_warning_log2(MSG_INFO,
6687 			   "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
6688 			   reassoc, (unsigned long) len);
6689 		hostapd_drv_sta_remove(hapd, sta->addr);
6690 		return;
6691 	}
6692 
6693 	if (reassoc)
6694 		status = le_to_host16(mgmt->u.reassoc_resp.status_code);
6695 	else
6696 		status = le_to_host16(mgmt->u.assoc_resp.status_code);
6697 
6698 	if (!ok) {
6699 		hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
6700 			       HOSTAPD_LEVEL_DEBUG,
6701 			       "did not acknowledge association response");
6702 		sta->flags &= ~WLAN_STA_ASSOC_REQ_OK;
6703 		/* The STA is added only in case of SUCCESS */
6704 		if (status == WLAN_STATUS_SUCCESS)
6705 			hostapd_drv_sta_remove(hapd, sta->addr);
6706 
6707 		return;
6708 	}
6709 
6710 	if (status != WLAN_STATUS_SUCCESS)
6711 		return;
6712 
6713 	/* Stop previous accounting session, if one is started, and allocate
6714 	 * new session id for the new session. */
6715 	accounting_sta_stop(hapd, sta);
6716 
6717 	hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
6718 		       HOSTAPD_LEVEL_INFO,
6719 		       "associated (aid %d)",
6720 		       sta->aid);
6721 
6722 	if (sta->flags & WLAN_STA_ASSOC)
6723 		new_assoc = 0;
6724 	sta->flags |= WLAN_STA_ASSOC;
6725 	sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
6726 #ifndef LOS_CONFIG_HOSTAPD_SECURITY
6727 	if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa &&
6728 	     !hapd->conf->osen) ||
6729 	    sta->auth_alg == WLAN_AUTH_FILS_SK ||
6730 	    sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
6731 	    sta->auth_alg == WLAN_AUTH_FILS_PK ||
6732 #else
6733 	if ((!hapd->conf->wpa) ||
6734 #endif /* LOS_CONFIG_HOSTAPD_SECURITY */
6735 	    sta->auth_alg == WLAN_AUTH_FT) {
6736 		/*
6737 		 * Open, static WEP, FT protocol, or FILS; no separate
6738 		 * authorization step.
6739 		 */
6740 		ap_sta_set_authorized(hapd, sta, 1);
6741 	}
6742 
6743 	if (reassoc)
6744 		mlme_reassociate_indication(hapd, sta);
6745 	else
6746 		mlme_associate_indication(hapd, sta);
6747 
6748 #ifdef CONFIG_IEEE80211W_AP
6749 	sta->sa_query_timed_out = 0;
6750 #endif /* CONFIG_IEEE80211W_AP */
6751 #ifndef LOS_CONFIG_NO_VLAN
6752 	if (sta->eapol_sm == NULL) {
6753 		/*
6754 		 * This STA does not use RADIUS server for EAP authentication,
6755 		 * so bind it to the selected VLAN interface now, since the
6756 		 * interface selection is not going to change anymore.
6757 		 */
6758 		if (ap_sta_bind_vlan(hapd, sta) < 0)
6759 			return;
6760 	} else if (sta->vlan_id) {
6761 		/* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
6762 		if (ap_sta_bind_vlan(hapd, sta) < 0)
6763 			return;
6764 	}
6765 #endif /* LOS_CONFIG_NO_VLAN */
6766 #ifndef LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT
6767 	(void)hostapd_set_sta_flags(hapd, sta);
6768 #endif /* LOS_CONFIG_EXT_DRIVER_NOT_SUPPORT */
6769 
6770 #ifndef EXT_CODE_CROP
6771 	if (!(sta->flags & WLAN_STA_WDS) && sta->pending_wds_enable) {
6772 		wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for STA "
6773 			   MACSTR " based on pending request",
6774 			   MAC2STR(sta->addr));
6775 		sta->pending_wds_enable = 0;
6776 		sta->flags |= WLAN_STA_WDS;
6777 	}
6778 
6779 	if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP)) {
6780 		int ret;
6781 		char ifname_wds[IFNAMSIZ + 1];
6782 
6783 		wpa_printf(MSG_DEBUG, "Reenable 4-address WDS mode for STA "
6784 			   MACSTR " (aid %u)",
6785 			   MAC2STR(sta->addr), sta->aid);
6786 		ret = hostapd_set_wds_sta(hapd, ifname_wds, sta->addr,
6787 					  sta->aid, 1);
6788 		if (!ret)
6789 			hostapd_set_wds_encryption(hapd, sta, ifname_wds);
6790 	}
6791 #endif /* EXT_CODE_CROP */
6792 	if (sta->auth_alg == WLAN_AUTH_FT)
6793 		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
6794 	else
6795 		wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
6796 	hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
6797 	ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
6798 
6799 #ifdef CONFIG_FILS
6800 	if ((sta->auth_alg == WLAN_AUTH_FILS_SK ||
6801 	     sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
6802 	     sta->auth_alg == WLAN_AUTH_FILS_PK) &&
6803 	    fils_set_tk(sta->wpa_sm) < 0) {
6804 		wpa_warning_log0(MSG_DEBUG, "FILS: TK configuration failed");
6805 		ap_sta_disconnect(hapd, sta, sta->addr,
6806 				  WLAN_REASON_UNSPECIFIED);
6807 		return;
6808 	}
6809 #endif /* CONFIG_FILS */
6810 #ifndef EXT_CODE_CROP
6811 	if (sta->pending_eapol_rx) {
6812 		struct os_reltime now, age;
6813 
6814 		os_get_reltime(&now);
6815 		os_reltime_sub(&now, &sta->pending_eapol_rx->rx_time, &age);
6816 		if (age.sec == 0 && age.usec < 200000) {
6817 			wpa_printf(MSG_DEBUG,
6818 				   "Process pending EAPOL frame that was received from " MACSTR " just before association notification",
6819 				   MAC2STR(sta->addr));
6820 			ieee802_1x_receive(
6821 				hapd, mgmt->da,
6822 				wpabuf_head(sta->pending_eapol_rx->buf),
6823 				wpabuf_len(sta->pending_eapol_rx->buf));
6824 		}
6825 		wpabuf_free(sta->pending_eapol_rx->buf);
6826 		os_free(sta->pending_eapol_rx);
6827 		sta->pending_eapol_rx = NULL;
6828 	}
6829 #endif /* EXT_CODE_CROP */
6830 }
6831 
6832 
6833 static void handle_deauth_cb(struct hostapd_data *hapd,
6834 			     const struct ieee80211_mgmt *mgmt,
6835 			     size_t len, int ok)
6836 {
6837 	struct sta_info *sta;
6838 	if (is_multicast_ether_addr(mgmt->da))
6839 		return;
6840 	sta = ap_get_sta(hapd, mgmt->da);
6841 	if (!sta) {
6842 		wpa_warning_log4(MSG_DEBUG, "handle_deauth_cb: STA " "%02x:xx:xx:%02x:%02x:%02x"
6843 			   " not found", (mgmt->da)[0], (mgmt->da)[3], (mgmt->da)[4], (mgmt->da)[5]);
6844 		return;
6845 	}
6846 	if (ok) {
6847 		wpa_warning_log4(MSG_DEBUG, "STA " "%02x:xx:xx:%02x:%02x:%02x" " acknowledged deauth",
6848 			   (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
6849 	}
6850 	else {
6851 		wpa_warning_log4(MSG_DEBUG, "STA " "%02x:xx:xx:%02x:%02x:%02x" " did not acknowledge "
6852 			   "deauth", (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
6853 	}
6854 
6855 	ap_sta_deauth_cb(hapd, sta);
6856 }
6857 
6858 
6859 static void handle_disassoc_cb(struct hostapd_data *hapd,
6860 			       const struct ieee80211_mgmt *mgmt,
6861 			       size_t len, int ok)
6862 {
6863 	struct sta_info *sta;
6864 	if (is_multicast_ether_addr(mgmt->da))
6865 		return;
6866 	sta = ap_get_sta(hapd, mgmt->da);
6867 	if (!sta) {
6868 		wpa_warning_log4(MSG_DEBUG, "handle_disassoc_cb: STA " "%02x:xx:xx:%02x:%02x:%02x"
6869 			   " not found", (mgmt->da)[0], (mgmt->da)[3], (mgmt->da)[4], (mgmt->da)[5]);
6870 		return;
6871 	}
6872 	if (ok) {
6873 		wpa_warning_log4(MSG_DEBUG, "STA " "%02x:xx:xx:%02x:%02x:%02x" " acknowledged disassoc",
6874 			   (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
6875 	}
6876 	else {
6877 		wpa_warning_log4(MSG_DEBUG, "STA " "%02x:xx:xx:%02x:%02x:%02x" " did not acknowledge "
6878 			   "disassoc", (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
6879 	}
6880 
6881 	ap_sta_disassoc_cb(hapd, sta);
6882 }
6883 
6884 #ifndef LOS_CONFIG_HOSTAPD_RRM
6885 static void handle_action_cb(struct hostapd_data *hapd,
6886 			     const struct ieee80211_mgmt *mgmt,
6887 			     size_t len, int ok)
6888 {
6889 	struct sta_info *sta;
6890 	const struct rrm_measurement_report_element *report;
6891 
6892 	if (is_multicast_ether_addr(mgmt->da))
6893 		return;
6894 #ifdef CONFIG_DPP
6895 	if (len >= IEEE80211_HDRLEN + 6 &&
6896 	    mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
6897 	    mgmt->u.action.u.vs_public_action.action ==
6898 	    WLAN_PA_VENDOR_SPECIFIC &&
6899 	    WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
6900 	    OUI_WFA &&
6901 	    mgmt->u.action.u.vs_public_action.variable[0] ==
6902 	    DPP_OUI_TYPE) {
6903 		const u8 *pos, *end;
6904 
6905 		pos = &mgmt->u.action.u.vs_public_action.variable[1];
6906 		end = ((const u8 *) mgmt) + len;
6907 		hostapd_dpp_tx_status(hapd, mgmt->da, pos, end - pos, ok);
6908 		return;
6909 	}
6910 	if (len >= IEEE80211_HDRLEN + 2 &&
6911 	    mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
6912 	    (mgmt->u.action.u.public_action.action ==
6913 	     WLAN_PA_GAS_INITIAL_REQ ||
6914 	     mgmt->u.action.u.public_action.action ==
6915 	     WLAN_PA_GAS_COMEBACK_REQ)) {
6916 		const u8 *pos, *end;
6917 
6918 		pos = mgmt->u.action.u.public_action.variable;
6919 		end = ((const u8 *) mgmt) + len;
6920 		gas_query_ap_tx_status(hapd->gas, mgmt->da, pos, end - pos, ok);
6921 		return;
6922 	}
6923 #endif /* CONFIG_DPP */
6924 #ifndef LOS_CONFIG_HOSTAPD_RRM
6925 	sta = ap_get_sta(hapd, mgmt->da);
6926 	if (!sta) {
6927 		wpa_warning_log4(MSG_DEBUG, "handle_action_cb: STA " "%02x:xx:xx:%02x:%02x:%02x"
6928 			   " not found", (mgmt->da)[0], (mgmt->da)[3], (mgmt->da)[4], (mgmt->da)[5]);
6929 		return;
6930 	}
6931 
6932 	if (len < 24 + 5 + sizeof(*report))
6933 		return;
6934 	report = (const struct rrm_measurement_report_element *)
6935 		&mgmt->u.action.u.rrm.variable[2];
6936 	if (mgmt->u.action.category == WLAN_ACTION_RADIO_MEASUREMENT &&
6937 	    mgmt->u.action.u.rrm.action == WLAN_RRM_RADIO_MEASUREMENT_REQUEST &&
6938 	    report->eid == WLAN_EID_MEASURE_REQUEST &&
6939 	    report->len >= 3 &&
6940 	    report->type == MEASURE_TYPE_BEACON)
6941 		hostapd_rrm_beacon_req_tx_status(hapd, mgmt, len, ok);
6942 #endif /* LOS_CONFIG_HOSTAPD_RRM */
6943 }
6944 #endif /* LOS_CONFIG_HOSTAPD_RRM */
6945 
6946 /**
6947  * ieee802_11_mgmt_cb - Process management frame TX status callback
6948  * @hapd: hostapd BSS data structure (the BSS from which the management frame
6949  * was sent from)
6950  * @buf: management frame data (starting from IEEE 802.11 header)
6951  * @len: length of frame data in octets
6952  * @stype: management frame subtype from frame control field
6953  * @ok: Whether the frame was ACK'ed
6954  */
6955 void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
6956 			u16 stype, int ok)
6957 {
6958 	const struct ieee80211_mgmt *mgmt;
6959 	mgmt = (const struct ieee80211_mgmt *) buf;
6960 
6961 #ifdef CONFIG_TESTING_OPTIONS
6962 	if (hapd->ext_mgmt_frame_handling) {
6963 		size_t hex_len = 2 * len + 1;
6964 		char *hex = os_malloc(hex_len);
6965 
6966 		if (hex) {
6967 			wpa_snprintf_hex(hex, hex_len, buf, len);
6968 			wpa_msg(hapd->msg_ctx, MSG_INFO,
6969 				"MGMT-TX-STATUS stype=%u ok=%d buf=%s",
6970 				stype, ok, hex);
6971 			os_free(hex);
6972 		}
6973 		return;
6974 	}
6975 #endif /* CONFIG_TESTING_OPTIONS */
6976 
6977 	switch (stype) {
6978 	case WLAN_FC_STYPE_AUTH:
6979 		wpa_warning_log0(MSG_DEBUG, "mgmt::auth cb");
6980 		handle_auth_cb(hapd, mgmt, len, ok);
6981 		break;
6982 	case WLAN_FC_STYPE_ASSOC_RESP:
6983 		wpa_warning_log0(MSG_DEBUG, "mgmt::assoc_resp cb");
6984 		handle_assoc_cb(hapd, mgmt, len, 0, ok);
6985 		break;
6986 	case WLAN_FC_STYPE_REASSOC_RESP:
6987 		wpa_warning_log0(MSG_DEBUG, "mgmt::reassoc_resp cb");
6988 		handle_assoc_cb(hapd, mgmt, len, 1, ok);
6989 		break;
6990 	case WLAN_FC_STYPE_PROBE_RESP:
6991 		wpa_msgdump_log1(MSG_EXCESSIVE, "mgmt::proberesp cb ok=%d", ok);
6992 		break;
6993 	case WLAN_FC_STYPE_DEAUTH:
6994 		wpa_warning_log0(MSG_DEBUG, "mgmt::deauth cb");
6995 		handle_deauth_cb(hapd, mgmt, len, ok);
6996 		break;
6997 	case WLAN_FC_STYPE_DISASSOC:
6998 		wpa_warning_log0(MSG_DEBUG, "mgmt::disassoc cb");
6999 		handle_disassoc_cb(hapd, mgmt, len, ok);
7000 		break;
7001 #ifndef LOS_CONFIG_HOSTAPD_RRM
7002 	case WLAN_FC_STYPE_ACTION:
7003 		wpa_warning_log1(MSG_DEBUG, "mgmt::action cb ok=%d", ok);
7004 		handle_action_cb(hapd, mgmt, len, ok);
7005 		break;
7006 #endif /* LOS_CONFIG_HOSTAPD_RRM */
7007 	default:
7008 		wpa_warning_log1(MSG_INFO, "unknown mgmt cb frame subtype %d", stype);
7009 		break;
7010 	}
7011 }
7012 #endif /* CONFIG_P2P */
7013 
7014 int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
7015 {
7016 	/* TODO */
7017 	return 0;
7018 }
7019 
7020 #ifndef EXT_CODE_CROP
7021 int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
7022 			   char *buf, size_t buflen)
7023 {
7024 	/* TODO */
7025 	return 0;
7026 }
7027 #endif /* EXT_CODE_CROP */
7028 
7029 void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
7030 		       const u8 *buf, size_t len, int ack)
7031 {
7032 	struct sta_info *sta;
7033 	struct hostapd_iface *iface = hapd->iface;
7034 
7035 	sta = ap_get_sta(hapd, addr);
7036 	if (sta == NULL && iface->num_bss > 1) {
7037 		size_t j;
7038 		for (j = 0; j < iface->num_bss; j++) {
7039 			hapd = iface->bss[j];
7040 			sta = ap_get_sta(hapd, addr);
7041 			if (sta)
7042 				break;
7043 		}
7044 	}
7045 	if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))
7046 		return;
7047 	if (sta->flags & WLAN_STA_PENDING_POLL) {
7048 		wpa_warning_log4(MSG_DEBUG, "STA " "%02x:xx:xx:%02x:%02x:%02x",
7049 			(sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
7050 		wpa_warning_buf(MSG_DEBUG, " %s pending " "activity poll",
7051 			   ack ? "ACKed" : "did not ACK", ack ? strlen("ACKed") : strlen("did not ACK"));
7052 		if (ack)
7053 			sta->flags &= ~WLAN_STA_PENDING_POLL;
7054 	}
7055 
7056 	ieee802_1x_tx_status(hapd, sta, buf, len, ack);
7057 }
7058 
7059 
7060 void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
7061 			     const u8 *data, size_t len, int ack)
7062 {
7063 	struct sta_info *sta;
7064 	struct hostapd_iface *iface = hapd->iface;
7065 
7066 	sta = ap_get_sta(hapd, dst);
7067 	if (sta == NULL && iface->num_bss > 1) {
7068 		size_t j;
7069 		for (j = 0; j < iface->num_bss; j++) {
7070 			hapd = iface->bss[j];
7071 			sta = ap_get_sta(hapd, dst);
7072 			if (sta)
7073 				break;
7074 		}
7075 	}
7076 	if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
7077 		wpa_warning_log4(MSG_DEBUG, "Ignore TX status for Data frame to STA "
7078 			   "%02x:xx:xx:%02x:%02x:%02x" " that is not currently associated",
7079 			   dst[0], dst[3], dst[4], dst[5]);
7080 		return;
7081 	}
7082 
7083 	ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack);
7084 }
7085 
7086 
7087 void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr)
7088 {
7089 	struct sta_info *sta;
7090 	struct hostapd_iface *iface = hapd->iface;
7091 
7092 	sta = ap_get_sta(hapd, addr);
7093 	if (sta == NULL && iface->num_bss > 1) {
7094 		size_t j;
7095 		for (j = 0; j < iface->num_bss; j++) {
7096 			hapd = iface->bss[j];
7097 			sta = ap_get_sta(hapd, addr);
7098 			if (sta)
7099 				break;
7100 		}
7101 	}
7102 	if (sta == NULL)
7103 		return;
7104 	wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POLL_OK MACSTR,
7105 		MAC2STR(sta->addr));
7106 	if (!(sta->flags & WLAN_STA_PENDING_POLL))
7107 		return;
7108 
7109 	wpa_warning_log4(MSG_DEBUG, "STA " "%02x:xx:xx:%02x:%02x:%02x" " ACKed pending "
7110 		   "activity poll", (sta->addr)[0], (sta->addr)[3], (sta->addr)[4], (sta->addr)[5]);
7111 	sta->flags &= ~WLAN_STA_PENDING_POLL;
7112 }
7113 
7114 #ifndef EXT_CODE_CROP
7115 void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
7116 				int wds)
7117 {
7118 	struct sta_info *sta;
7119 
7120 	sta = ap_get_sta(hapd, src);
7121 	if (sta &&
7122 	    ((sta->flags & WLAN_STA_ASSOC) ||
7123 	     ((sta->flags & WLAN_STA_ASSOC_REQ_OK) && wds))) {
7124 		if (!hapd->conf->wds_sta)
7125 			return;
7126 
7127 		if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK)) ==
7128 		    WLAN_STA_ASSOC_REQ_OK) {
7129 			wpa_printf(MSG_DEBUG,
7130 				   "Postpone 4-address WDS mode enabling for STA "
7131 				   MACSTR " since TX status for AssocResp is not yet known",
7132 				   MAC2STR(sta->addr));
7133 			sta->pending_wds_enable = 1;
7134 			return;
7135 		}
7136 
7137 		if (wds && !(sta->flags & WLAN_STA_WDS)) {
7138 			int ret;
7139 			char ifname_wds[IFNAMSIZ + 1];
7140 
7141 			wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for "
7142 				   "STA " MACSTR " (aid %u)",
7143 				   MAC2STR(sta->addr), sta->aid);
7144 			sta->flags |= WLAN_STA_WDS;
7145 			ret = hostapd_set_wds_sta(hapd, ifname_wds,
7146 						  sta->addr, sta->aid, 1);
7147 			if (!ret)
7148 				hostapd_set_wds_encryption(hapd, sta,
7149 							   ifname_wds);
7150 		}
7151 		return;
7152 	}
7153 
7154 	wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA "
7155 		   MACSTR, MAC2STR(src));
7156 	if (is_multicast_ether_addr(src) || is_zero_ether_addr(src) ||
7157 	    os_memcmp(src, hapd->own_addr, ETH_ALEN) == 0) {
7158 		/* Broadcast bit set in SA or unexpected SA?! Ignore the frame
7159 		 * silently. */
7160 		return;
7161 	}
7162 
7163 	if (sta && (sta->flags & WLAN_STA_ASSOC_REQ_OK)) {
7164 		wpa_printf(MSG_DEBUG, "Association Response to the STA has "
7165 			   "already been sent, but no TX status yet known - "
7166 			   "ignore Class 3 frame issue with " MACSTR,
7167 			   MAC2STR(src));
7168 		return;
7169 	}
7170 
7171 	if (sta && (sta->flags & WLAN_STA_AUTH))
7172 		hostapd_drv_sta_disassoc(
7173 			hapd, src,
7174 			WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
7175 	else
7176 		hostapd_drv_sta_deauth(
7177 			hapd, src,
7178 			WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
7179 }
7180 #endif /* EXT_CODE_CROP */
7181 
7182 #ifdef EXT_CODE_CROP
7183 u8 * hostapd_eid_txpower_envelope(struct hostapd_data *hapd, u8 *eid)
7184 {
7185 	struct hostapd_iface *iface = hapd->iface;
7186 	struct hostapd_config *iconf = iface->conf;
7187 	struct hostapd_hw_modes *mode = iface->current_mode;
7188 	struct hostapd_channel_data *chan;
7189 	int dfs, i;
7190 	u8 channel, tx_pwr_count, local_pwr_constraint;
7191 	int max_tx_power;
7192 	u8 tx_pwr;
7193 
7194 	if (!mode)
7195 		return eid;
7196 
7197 	if (ieee80211_freq_to_chan(iface->freq, &channel) == NUM_HOSTAPD_MODES)
7198 		return eid;
7199 
7200 	for (i = 0; i < mode->num_channels; i++) {
7201 		if (mode->channels[i].freq == iface->freq)
7202 			break;
7203 	}
7204 	if (i == mode->num_channels)
7205 		return eid;
7206 
7207 	switch (hostapd_get_oper_chwidth(iconf)) {
7208 	case CHANWIDTH_USE_HT:
7209 		if (iconf->secondary_channel == 0) {
7210 			/* Max Transmit Power count = 0 (20 MHz) */
7211 			tx_pwr_count = 0;
7212 		} else {
7213 			/* Max Transmit Power count = 1 (20, 40 MHz) */
7214 			tx_pwr_count = 1;
7215 		}
7216 		break;
7217 	case CHANWIDTH_80MHZ:
7218 		/* Max Transmit Power count = 2 (20, 40, and 80 MHz) */
7219 		tx_pwr_count = 2;
7220 		break;
7221 	case CHANWIDTH_80P80MHZ:
7222 	case CHANWIDTH_160MHZ:
7223 		/* Max Transmit Power count = 3 (20, 40, 80, 160/80+80 MHz) */
7224 		tx_pwr_count = 3;
7225 		break;
7226 	default:
7227 		return eid;
7228 	}
7229 
7230 	/*
7231 	 * Below local_pwr_constraint logic is referred from
7232 	 * hostapd_eid_pwr_constraint.
7233 	 *
7234 	 * Check if DFS is required by regulatory.
7235 	 */
7236 #ifndef EXT_CODE_CROP
7237 	dfs = hostapd_is_dfs_required(hapd->iface);
7238 	if (dfs < 0)
7239 		dfs = 0;
7240 #else
7241 	dfs = 0;
7242 #endif
7243 	/*
7244 	 * In order to meet regulations when TPC is not implemented using
7245 	 * a transmit power that is below the legal maximum (including any
7246 	 * mitigation factor) should help. In this case, indicate 3 dB below
7247 	 * maximum allowed transmit power.
7248 	 */
7249 	if (hapd->iconf->local_pwr_constraint == -1)
7250 		local_pwr_constraint = (dfs == 0) ? 0 : 3;
7251 	else
7252 		local_pwr_constraint = hapd->iconf->local_pwr_constraint;
7253 
7254 	/*
7255 	 * A STA that is not an AP shall use a transmit power less than or
7256 	 * equal to the local maximum transmit power level for the channel.
7257 	 * The local maximum transmit power can be calculated from the formula:
7258 	 * local max TX pwr = max TX pwr - local pwr constraint
7259 	 * Where max TX pwr is maximum transmit power level specified for
7260 	 * channel in Country element and local pwr constraint is specified
7261 	 * for channel in this Power Constraint element.
7262 	 */
7263 	chan = &mode->channels[i];
7264 	max_tx_power = chan->max_tx_power - local_pwr_constraint;
7265 
7266 	/*
7267 	 * Local Maximum Transmit power is encoded as two's complement
7268 	 * with a 0.5 dB step.
7269 	 */
7270 	max_tx_power *= 2; /* in 0.5 dB steps */
7271 	if (max_tx_power > 127) {
7272 		/* 63.5 has special meaning of 63.5 dBm or higher */
7273 		max_tx_power = 127;
7274 	}
7275 	if (max_tx_power < -128)
7276 		max_tx_power = -128;
7277 	if (max_tx_power < 0)
7278 		tx_pwr = 0x80 + max_tx_power + 128;
7279 	else
7280 		tx_pwr = max_tx_power;
7281 
7282 	*eid++ = WLAN_EID_TRANSMIT_POWER_ENVELOPE;
7283 	*eid++ = 2 + tx_pwr_count;
7284 
7285 	/*
7286 	 * Max Transmit Power count and
7287 	 * Max Transmit Power units = 0 (EIRP)
7288 	 */
7289 	*eid++ = tx_pwr_count;
7290 
7291 	for (i = 0; i <= tx_pwr_count; i++)
7292 		*eid++ = tx_pwr;
7293 
7294 	return eid;
7295 }
7296 
7297 
7298 u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
7299 {
7300 	u8 bw, chan1, chan2 = 0;
7301 	int freq1;
7302 
7303 	if (!hapd->cs_freq_params.channel ||
7304 	    (!hapd->cs_freq_params.vht_enabled &&
7305 	     !hapd->cs_freq_params.he_enabled))
7306 		return eid;
7307 
7308 	/* bandwidth: 0: 40, 1: 80, 2: 160, 3: 80+80 */
7309 	switch (hapd->cs_freq_params.bandwidth) {
7310 	case 40:
7311 		bw = 0;
7312 		break;
7313 	case 80:
7314 		/* check if it's 80+80 */
7315 		if (!hapd->cs_freq_params.center_freq2)
7316 			bw = 1;
7317 		else
7318 			bw = 3;
7319 		break;
7320 	case 160:
7321 		bw = 2;
7322 		break;
7323 	default:
7324 		/* not valid VHT bandwidth or not in CSA */
7325 		return eid;
7326 	}
7327 
7328 	freq1 = hapd->cs_freq_params.center_freq1 ?
7329 		hapd->cs_freq_params.center_freq1 :
7330 		hapd->cs_freq_params.freq;
7331 	if (ieee80211_freq_to_chan(freq1, &chan1) !=
7332 	    HOSTAPD_MODE_IEEE80211A)
7333 		return eid;
7334 
7335 	if (hapd->cs_freq_params.center_freq2 &&
7336 	    ieee80211_freq_to_chan(hapd->cs_freq_params.center_freq2,
7337 				   &chan2) != HOSTAPD_MODE_IEEE80211A)
7338 		return eid;
7339 
7340 	*eid++ = WLAN_EID_VHT_CHANNEL_SWITCH_WRAPPER;
7341 	*eid++ = 5; /* Length of Channel Switch Wrapper */
7342 	*eid++ = WLAN_EID_VHT_WIDE_BW_CHSWITCH;
7343 	*eid++ = 3; /* Length of Wide Bandwidth Channel Switch element */
7344 	*eid++ = bw; /* New Channel Width */
7345 	*eid++ = chan1; /* New Channel Center Frequency Segment 0 */
7346 	*eid++ = chan2; /* New Channel Center Frequency Segment 1 */
7347 
7348 	return eid;
7349 }
7350 
7351 
7352 static size_t hostapd_eid_nr_db_len(struct hostapd_data *hapd,
7353 				    size_t *current_len)
7354 {
7355 	struct hostapd_neighbor_entry *nr;
7356 	size_t total_len = 0, len = *current_len;
7357 
7358 	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
7359 			 list) {
7360 		if (!nr->nr || wpabuf_len(nr->nr) < 12)
7361 			continue;
7362 
7363 		if (nr->short_ssid == hapd->conf->ssid.short_ssid)
7364 			continue;
7365 
7366 		/* Start a new element */
7367 		if (!len ||
7368 		    len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
7369 			len = RNR_HEADER_LEN;
7370 			total_len += RNR_HEADER_LEN;
7371 		}
7372 
7373 		len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
7374 		total_len += RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN;
7375 	}
7376 
7377 	*current_len = len;
7378 	return total_len;
7379 }
7380 
7381 
7382 static size_t hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
7383 					struct hostapd_data *reporting_hapd,
7384 					size_t *current_len)
7385 {
7386 	size_t total_len = 0, len = *current_len;
7387 	int tbtt_count = 0;
7388 	size_t i, start = 0;
7389 
7390 	while (start < hapd->iface->num_bss) {
7391 		if (!len ||
7392 		    len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
7393 			len = RNR_HEADER_LEN;
7394 			total_len += RNR_HEADER_LEN;
7395 		}
7396 
7397 		len += RNR_TBTT_HEADER_LEN;
7398 		total_len += RNR_TBTT_HEADER_LEN;
7399 
7400 		for (i = start; i < hapd->iface->num_bss; i++) {
7401 			struct hostapd_data *bss = hapd->iface->bss[i];
7402 
7403 			if (!bss || !bss->conf || !bss->started)
7404 				continue;
7405 
7406 			if (bss == reporting_hapd ||
7407 			    bss->conf->ignore_broadcast_ssid)
7408 				continue;
7409 
7410 			if (len + RNR_TBTT_INFO_LEN > 255 ||
7411 			    tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
7412 				break;
7413 
7414 			len += RNR_TBTT_INFO_LEN;
7415 			total_len += RNR_TBTT_INFO_LEN;
7416 			tbtt_count++;
7417 		}
7418 		start = i;
7419 	}
7420 
7421 	if (!tbtt_count)
7422 		total_len = 0;
7423 	else
7424 		*current_len = len;
7425 
7426 	return total_len;
7427 }
7428 
7429 
7430 enum colocation_mode {
7431 	NO_COLOCATED_6GHZ,
7432 	STANDALONE_6GHZ,
7433 	COLOCATED_6GHZ,
7434 	COLOCATED_LOWER_BAND,
7435 };
7436 
7437 static enum colocation_mode get_colocation_mode(struct hostapd_data *hapd)
7438 {
7439 	u8 i;
7440 	bool is_6ghz = is_6ghz_op_class(hapd->iconf->op_class);
7441 
7442 	if (!hapd->iface || !hapd->iface->interfaces)
7443 		return NO_COLOCATED_6GHZ;
7444 
7445 	if (is_6ghz && hapd->iface->interfaces->count == 1)
7446 		return STANDALONE_6GHZ;
7447 
7448 	for (i = 0; i < hapd->iface->interfaces->count; i++) {
7449 		struct hostapd_iface *iface;
7450 		bool is_colocated_6ghz;
7451 
7452 		iface = hapd->iface->interfaces->iface[i];
7453 		if (iface == hapd->iface || !iface || !iface->conf)
7454 			continue;
7455 
7456 		is_colocated_6ghz = is_6ghz_op_class(iface->conf->op_class);
7457 		if (!is_6ghz && is_colocated_6ghz)
7458 			return COLOCATED_LOWER_BAND;
7459 		if (is_6ghz && !is_colocated_6ghz)
7460 			return COLOCATED_6GHZ;
7461 	}
7462 
7463 	if (is_6ghz)
7464 		return STANDALONE_6GHZ;
7465 
7466 	return NO_COLOCATED_6GHZ;
7467 }
7468 
7469 
7470 static size_t hostapd_eid_rnr_colocation_len(struct hostapd_data *hapd,
7471 					     size_t *current_len)
7472 {
7473 	struct hostapd_iface *iface;
7474 	size_t len = 0;
7475 	size_t i;
7476 
7477 	if (!hapd->iface || !hapd->iface->interfaces)
7478 		return 0;
7479 
7480 	for (i = 0; i < hapd->iface->interfaces->count; i++) {
7481 		iface = hapd->iface->interfaces->iface[i];
7482 
7483 		if (iface == hapd->iface ||
7484 		    !is_6ghz_op_class(iface->conf->op_class))
7485 			continue;
7486 
7487 		len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
7488 						 current_len);
7489 	}
7490 
7491 	return len;
7492 }
7493 
7494 
7495 size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
7496 {
7497 	size_t total_len = 0, current_len = 0;
7498 	enum colocation_mode mode = get_colocation_mode(hapd);
7499 
7500 	switch (type) {
7501 	case WLAN_FC_STYPE_BEACON:
7502 		if (hapd->conf->rnr)
7503 			total_len += hostapd_eid_nr_db_len(hapd, &current_len);
7504 		/* fallthrough */
7505 
7506 	case WLAN_FC_STYPE_PROBE_RESP:
7507 		if (mode == COLOCATED_LOWER_BAND)
7508 			total_len += hostapd_eid_rnr_colocation_len(
7509 				hapd, &current_len);
7510 
7511 		if (hapd->conf->rnr && hapd->iface->num_bss > 1)
7512 			total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
7513 							       &current_len);
7514 		break;
7515 
7516 	case WLAN_FC_STYPE_ACTION:
7517 		if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
7518 			total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
7519 							       &current_len);
7520 		break;
7521 
7522 	default:
7523 		break;
7524 	}
7525 
7526 	return total_len;
7527 }
7528 
7529 
7530 static u8 * hostapd_eid_nr_db(struct hostapd_data *hapd, u8 *eid,
7531 			      size_t *current_len)
7532 {
7533 	struct hostapd_neighbor_entry *nr;
7534 	size_t len = *current_len;
7535 	u8 *size_offset = (eid - len) + 1;
7536 
7537 	dl_list_for_each(nr, &hapd->nr_db, struct hostapd_neighbor_entry,
7538 			 list) {
7539 		if (!nr->nr || wpabuf_len(nr->nr) < 12)
7540 			continue;
7541 
7542 		if (nr->short_ssid == hapd->conf->ssid.short_ssid)
7543 			continue;
7544 
7545 		/* Start a new element */
7546 		if (!len ||
7547 		    len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
7548 			*eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
7549 			size_offset = eid++;
7550 			len = RNR_HEADER_LEN;
7551 		}
7552 
7553 		/* TBTT Information Header subfield (2 octets) */
7554 		*eid++ = 0;
7555 		/* TBTT Information Length */
7556 		*eid++ = RNR_TBTT_INFO_LEN;
7557 		/* Operating Class */
7558 		*eid++ = wpabuf_head_u8(nr->nr)[10];
7559 		/* Channel Number */
7560 		*eid++ = wpabuf_head_u8(nr->nr)[11];
7561 		len += RNR_TBTT_HEADER_LEN;
7562 		/* TBTT Information Set */
7563 		/* TBTT Information field */
7564 		/* Neighbor AP TBTT Offset */
7565 		*eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN;
7566 		/* BSSID */
7567 		os_memcpy(eid, nr->bssid, ETH_ALEN);
7568 		eid += ETH_ALEN;
7569 		/* Short SSID */
7570 		os_memcpy(eid, &nr->short_ssid, 4);
7571 		eid += 4;
7572 		/* BSS parameters */
7573 		*eid++ = nr->bss_parameters;
7574 		/* 20 MHz PSD */
7575 		*eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1;
7576 		len += RNR_TBTT_INFO_LEN;
7577 		*size_offset = (eid - size_offset) - 1;
7578 	}
7579 
7580 	*current_len = len;
7581 	return eid;
7582 }
7583 
7584 
7585 static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
7586 				  struct hostapd_data *reporting_hapd,
7587 				  u8 *eid, size_t *current_len)
7588 {
7589 	struct hostapd_data *bss;
7590 	struct hostapd_iface *iface = hapd->iface;
7591 	size_t i, start = 0;
7592 	size_t len = *current_len;
7593 	u8 *tbtt_count_pos, *eid_start = eid, *size_offset = (eid - len) + 1;
7594 	u8 tbtt_count = 0, op_class, channel, bss_param;
7595 
7596 	if (!(iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) || !iface->freq)
7597 		return eid;
7598 
7599 	if (ieee80211_freq_to_channel_ext(iface->freq,
7600 					  hapd->iconf->secondary_channel,
7601 #ifndef EXT_CODE_CROP
7602 					  hostapd_get_oper_chwidth(hapd->iconf),
7603 #endif
7604 					  &op_class, &channel) ==
7605 	    NUM_HOSTAPD_MODES)
7606 		return eid;
7607 
7608 	while (start < iface->num_bss) {
7609 		if (!len ||
7610 		    len + RNR_TBTT_HEADER_LEN + RNR_TBTT_INFO_LEN > 255) {
7611 			eid_start = eid;
7612 			*eid++ = WLAN_EID_REDUCED_NEIGHBOR_REPORT;
7613 			size_offset = eid++;
7614 			len = RNR_HEADER_LEN;
7615 			tbtt_count = 0;
7616 		}
7617 
7618 		tbtt_count_pos = eid++;
7619 		*eid++ = RNR_TBTT_INFO_LEN;
7620 		*eid++ = op_class;
7621 		*eid++ = hapd->iconf->channel;
7622 		len += RNR_TBTT_HEADER_LEN;
7623 
7624 		for (i = start; i < iface->num_bss; i++) {
7625 			bss_param = 0;
7626 			bss = iface->bss[i];
7627 			if (!bss || !bss->conf || !bss->started)
7628 				continue;
7629 
7630 			if (bss == reporting_hapd ||
7631 			    bss->conf->ignore_broadcast_ssid)
7632 				continue;
7633 
7634 			if (len + RNR_TBTT_INFO_LEN > 255 ||
7635 			    tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
7636 				break;
7637 
7638 			*eid++ = RNR_NEIGHBOR_AP_OFFSET_UNKNOWN;
7639 			os_memcpy(eid, bss->conf->bssid, ETH_ALEN);
7640 			eid += ETH_ALEN;
7641 			os_memcpy(eid, &bss->conf->ssid.short_ssid, 4);
7642 			eid += 4;
7643 			if (bss->conf->ssid.short_ssid ==
7644 			    reporting_hapd->conf->ssid.short_ssid)
7645 				bss_param |= RNR_BSS_PARAM_SAME_SSID;
7646 
7647 			if (is_6ghz_op_class(hapd->iconf->op_class) &&
7648 			    bss->conf->unsol_bcast_probe_resp_interval)
7649 				bss_param |=
7650 					RNR_BSS_PARAM_UNSOLIC_PROBE_RESP_ACTIVE;
7651 
7652 			bss_param |= RNR_BSS_PARAM_CO_LOCATED;
7653 
7654 			*eid++ = bss_param;
7655 			*eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1;
7656 			len += RNR_TBTT_INFO_LEN;
7657 			tbtt_count += 1;
7658 		}
7659 
7660 		start = i;
7661 		*tbtt_count_pos = RNR_TBTT_INFO_COUNT(tbtt_count - 1);
7662 		*size_offset = (eid - size_offset) - 1;
7663 	}
7664 
7665 	if (tbtt_count == 0)
7666 		return eid_start;
7667 
7668 	*current_len = len;
7669 	return eid;
7670 }
7671 
7672 
7673 static u8 * hostapd_eid_rnr_colocation(struct hostapd_data *hapd, u8 *eid,
7674 				       size_t *current_len)
7675 {
7676 	struct hostapd_iface *iface;
7677 	size_t i;
7678 
7679 	if (!hapd->iface || !hapd->iface->interfaces)
7680 		return eid;
7681 
7682 	for (i = 0; i < hapd->iface->interfaces->count; i++) {
7683 		iface = hapd->iface->interfaces->iface[i];
7684 
7685 		if (iface == hapd->iface ||
7686 		    !is_6ghz_op_class(iface->conf->op_class))
7687 			continue;
7688 
7689 		eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid,
7690 					    current_len);
7691 	}
7692 
7693 	return eid;
7694 }
7695 
7696 
7697 u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
7698 {
7699 	u8 *eid_start = eid;
7700 	size_t current_len = 0;
7701 	enum colocation_mode mode = get_colocation_mode(hapd);
7702 
7703 	switch (type) {
7704 	case WLAN_FC_STYPE_BEACON:
7705 		if (hapd->conf->rnr)
7706 			eid = hostapd_eid_nr_db(hapd, eid, &current_len);
7707 		/* fallthrough */
7708 
7709 	case WLAN_FC_STYPE_PROBE_RESP:
7710 		if (mode == COLOCATED_LOWER_BAND)
7711 			eid = hostapd_eid_rnr_colocation(hapd, eid,
7712 							 &current_len);
7713 
7714 		if (hapd->conf->rnr && hapd->iface->num_bss > 1)
7715 			eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
7716 						    &current_len);
7717 		break;
7718 
7719 	case WLAN_FC_STYPE_ACTION:
7720 		if (hapd->iface->num_bss > 1 && mode == STANDALONE_6GHZ)
7721 			eid = hostapd_eid_rnr_iface(hapd, hapd,	eid,
7722 						    &current_len);
7723 		break;
7724 
7725 	default:
7726 		return eid_start;
7727 	}
7728 
7729 	if (eid == eid_start + 2)
7730 		return eid_start;
7731 
7732 	return eid;
7733 }
7734 #endif /* EXT_CODE_CROP */
7735 #endif /* CONFIG_NATIVE_WINDOWS */
7736