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