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(¶ms, 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, ¶ms);
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(¶ms, 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, ¶ms)))) {
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, ¤t_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, ¤t_len);
7510
7511 if (hapd->conf->rnr && hapd->iface->num_bss > 1)
7512 total_len += hostapd_eid_rnr_iface_len(hapd, hapd,
7513 ¤t_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 ¤t_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, ¤t_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 ¤t_len);
7713
7714 if (hapd->conf->rnr && hapd->iface->num_bss > 1)
7715 eid = hostapd_eid_rnr_iface(hapd, hapd, eid,
7716 ¤t_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 ¤t_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