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