]> git.ipfire.org Git - thirdparty/hostap.git/blame - src/ap/ieee802_11.c
OWE: Rename owe_assoc_req_process() parameter reason to status
[thirdparty/hostap.git] / src / ap / ieee802_11.c
CommitLineData
6fc6879b
JM
1/*
2 * hostapd / IEEE 802.11 Management
f3383366 3 * Copyright (c) 2002-2017, Jouni Malinen <j@w1.fi>
6fc6879b 4 *
0f3d578e
JM
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
6fc6879b
JM
7 */
8
1057d78e 9#include "utils/includes.h"
6fc6879b
JM
10
11#ifndef CONFIG_NATIVE_WINDOWS
12
1057d78e
JM
13#include "utils/common.h"
14#include "utils/eloop.h"
03da66bd 15#include "crypto/crypto.h"
d136c376 16#include "crypto/sha256.h"
7a12edd1
JM
17#include "crypto/sha384.h"
18#include "crypto/sha512.h"
d136c376 19#include "crypto/random.h"
81f4f619
JM
20#include "common/ieee802_11_defs.h"
21#include "common/ieee802_11_common.h"
03da66bd 22#include "common/wpa_ctrl.h"
98efcc41 23#include "common/sae.h"
10ec6a5f 24#include "common/dpp.h"
99621dc1 25#include "common/ocv.h"
ef60f012 26#include "common/wpa_common.h"
03da66bd
JM
27#include "radius/radius.h"
28#include "radius/radius_client.h"
e44f8bf2 29#include "p2p/p2p.h"
ed7a09f9 30#include "wps/wps.h"
037378ff 31#include "fst/fst.h"
6fc6879b 32#include "hostapd.h"
6fc6879b 33#include "beacon.h"
6fc6879b
JM
34#include "ieee802_11_auth.h"
35#include "sta_info.h"
6fc6879b 36#include "ieee802_1x.h"
6226e38d 37#include "wpa_auth.h"
f2991170 38#include "pmksa_cache_auth.h"
1057d78e 39#include "wmm.h"
6fc6879b
JM
40#include "ap_list.h"
41#include "accounting.h"
6226e38d
JM
42#include "ap_config.h"
43#include "ap_mlme.h"
dce044cc 44#include "p2p_hostapd.h"
cee7d66b 45#include "ap_drv_ops.h"
c79938a5 46#include "wnm_ap.h"
0e2412d0 47#include "hw_features.h"
6226e38d 48#include "ieee802_11.h"
3d7ad2f6 49#include "dfs.h"
6332aaf3 50#include "mbo_ap.h"
2572df34 51#include "rrm.h"
04059ab8 52#include "taxonomy.h"
54b04d6f 53#include "fils_hlp.h"
9c2b8204
JM
54#include "dpp_hostapd.h"
55#include "gas_query_ap.h"
6fc6879b
JM
56
57
5e5f8c81
JM
58#ifdef CONFIG_FILS
59static struct wpabuf *
60prepare_auth_resp_fils(struct hostapd_data *hapd,
61 struct sta_info *sta, u16 *resp,
62 struct rsn_pmksa_cache_entry *pmksa,
63 struct wpabuf *erp_resp,
64 const u8 *msk, size_t msk_len,
65 int *is_pub);
66#endif /* CONFIG_FILS */
ff9f40ae
JM
67static void handle_auth(struct hostapd_data *hapd,
68 const struct ieee80211_mgmt *mgmt, size_t len,
69 int rssi, int from_queue);
5e5f8c81 70
9c06f0f6
VN
71
72u8 * hostapd_eid_multi_ap(struct hostapd_data *hapd, u8 *eid)
73{
74 u8 multi_ap_val = 0;
75
76 if (!hapd->conf->multi_ap)
77 return eid;
78 if (hapd->conf->multi_ap & BACKHAUL_BSS)
79 multi_ap_val |= MULTI_AP_BACKHAUL_BSS;
80 if (hapd->conf->multi_ap & FRONTHAUL_BSS)
81 multi_ap_val |= MULTI_AP_FRONTHAUL_BSS;
82
83 return eid + add_multi_ap_ie(eid, 9, multi_ap_val);
84}
85
86
6fc6879b
JM
87u8 * hostapd_eid_supp_rates(struct hostapd_data *hapd, u8 *eid)
88{
89 u8 *pos = eid;
90 int i, num, count;
e36a5894 91 int h2e_required;
6fc6879b
JM
92
93 if (hapd->iface->current_rates == NULL)
94 return eid;
95
96 *pos++ = WLAN_EID_SUPP_RATES;
97 num = hapd->iface->num_rates;
29448243
JM
98 if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
99 num++;
202d97d4
JB
100 if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
101 num++;
e36a5894
JM
102 h2e_required = (hapd->conf->sae_pwe == 1 ||
103 hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&
641d79f1 104 hapd->conf->sae_pwe != 3 &&
e36a5894
JM
105 wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt);
106 if (h2e_required)
cc0da0ff 107 num++;
6fc6879b
JM
108 if (num > 8) {
109 /* rest of the rates are encoded in Extended supported
110 * rates element */
111 num = 8;
112 }
113
114 *pos++ = num;
6fc6879b
JM
115 for (i = 0, count = 0; i < hapd->iface->num_rates && count < num;
116 i++) {
117 count++;
118 *pos = hapd->iface->current_rates[i].rate / 5;
119 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
120 *pos |= 0x80;
121 pos++;
122 }
123
202d97d4
JB
124 if (hapd->iconf->ieee80211n && hapd->iconf->require_ht && count < 8) {
125 count++;
29448243 126 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
202d97d4
JB
127 }
128
129 if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht && count < 8) {
130 count++;
131 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
132 }
29448243 133
e36a5894 134 if (h2e_required && count < 8) {
cc0da0ff
JM
135 count++;
136 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
137 }
138
6fc6879b
JM
139 return pos;
140}
141
142
143u8 * hostapd_eid_ext_supp_rates(struct hostapd_data *hapd, u8 *eid)
144{
145 u8 *pos = eid;
146 int i, num, count;
e36a5894 147 int h2e_required;
6fc6879b
JM
148
149 if (hapd->iface->current_rates == NULL)
150 return eid;
151
152 num = hapd->iface->num_rates;
29448243
JM
153 if (hapd->iconf->ieee80211n && hapd->iconf->require_ht)
154 num++;
202d97d4
JB
155 if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
156 num++;
e36a5894
JM
157 h2e_required = (hapd->conf->sae_pwe == 1 ||
158 hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&
641d79f1 159 hapd->conf->sae_pwe != 3 &&
e36a5894
JM
160 wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt);
161 if (h2e_required)
cc0da0ff 162 num++;
6fc6879b
JM
163 if (num <= 8)
164 return eid;
165 num -= 8;
166
167 *pos++ = WLAN_EID_EXT_SUPP_RATES;
168 *pos++ = num;
6fc6879b
JM
169 for (i = 0, count = 0; i < hapd->iface->num_rates && count < num + 8;
170 i++) {
171 count++;
172 if (count <= 8)
173 continue; /* already in SuppRates IE */
174 *pos = hapd->iface->current_rates[i].rate / 5;
175 if (hapd->iface->current_rates[i].flags & HOSTAPD_RATE_BASIC)
176 *pos |= 0x80;
177 pos++;
178 }
179
202d97d4
JB
180 if (hapd->iconf->ieee80211n && hapd->iconf->require_ht) {
181 count++;
182 if (count > 8)
183 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY;
184 }
185
186 if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht) {
187 count++;
188 if (count > 8)
189 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
190 }
29448243 191
e36a5894 192 if (h2e_required) {
cc0da0ff
JM
193 count++;
194 if (count > 8)
195 *pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
196 }
197
6fc6879b
JM
198 return pos;
199}
200
201
96a2a9a8
MT
202u8 * hostapd_eid_rm_enabled_capab(struct hostapd_data *hapd, u8 *eid,
203 size_t len)
204{
205 size_t i;
206
207 for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
208 if (hapd->conf->radio_measurements[i])
209 break;
210 }
211
212 if (i == RRM_CAPABILITIES_IE_LEN || len < 2 + RRM_CAPABILITIES_IE_LEN)
213 return eid;
214
215 *eid++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
216 *eid++ = RRM_CAPABILITIES_IE_LEN;
217 os_memcpy(eid, hapd->conf->radio_measurements, RRM_CAPABILITIES_IE_LEN);
218
219 return eid + RRM_CAPABILITIES_IE_LEN;
220}
221
222
f41ded6f 223u16 hostapd_own_capab_info(struct hostapd_data *hapd)
6fc6879b
JM
224{
225 int capab = WLAN_CAPABILITY_ESS;
226 int privacy;
3d7ad2f6 227 int dfs;
01018212 228 int i;
3d7ad2f6
C
229
230 /* Check if any of configured channels require DFS */
231 dfs = hostapd_is_dfs_required(hapd->iface);
232 if (dfs < 0) {
233 wpa_printf(MSG_WARNING, "Failed to check if DFS is required; ret=%d",
234 dfs);
235 dfs = 0;
236 }
6fc6879b
JM
237
238 if (hapd->iface->num_sta_no_short_preamble == 0 &&
239 hapd->iconf->preamble == SHORT_PREAMBLE)
240 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
241
242 privacy = hapd->conf->ssid.wep.keys_set;
243
244 if (hapd->conf->ieee802_1x &&
245 (hapd->conf->default_wep_key_len ||
246 hapd->conf->individual_wep_key_len))
247 privacy = 1;
248
249 if (hapd->conf->wpa)
250 privacy = 1;
251
a14896e8
JM
252#ifdef CONFIG_HS20
253 if (hapd->conf->osen)
254 privacy = 1;
255#endif /* CONFIG_HS20 */
256
6fc6879b
JM
257 if (privacy)
258 capab |= WLAN_CAPABILITY_PRIVACY;
259
260 if (hapd->iface->current_mode &&
261 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G &&
262 hapd->iface->num_sta_no_short_slot_time == 0)
263 capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
264
3d7ad2f6
C
265 /*
266 * Currently, Spectrum Management capability bit is set when directly
267 * requested in configuration by spectrum_mgmt_required or when AP is
268 * running on DFS channel.
269 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
270 */
271 if (hapd->iface->current_mode &&
272 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211A &&
273 (hapd->iconf->spectrum_mgmt_required || dfs))
274 capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
275
01018212
DS
276 for (i = 0; i < RRM_CAPABILITIES_IE_LEN; i++) {
277 if (hapd->conf->radio_measurements[i]) {
278 capab |= IEEE80211_CAP_RRM;
279 break;
280 }
281 }
0629eeb4 282
6fc6879b
JM
283 return capab;
284}
285
286
7cb53ded 287#ifndef CONFIG_NO_RC4
6fc6879b 288static u16 auth_shared_key(struct hostapd_data *hapd, struct sta_info *sta,
b57e086c
JM
289 u16 auth_transaction, const u8 *challenge,
290 int iswep)
6fc6879b
JM
291{
292 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
293 HOSTAPD_LEVEL_DEBUG,
294 "authentication (shared key, transaction %d)",
295 auth_transaction);
296
297 if (auth_transaction == 1) {
298 if (!sta->challenge) {
299 /* Generate a pseudo-random challenge */
300 u8 key[8];
f441e5af 301
6fc6879b
JM
302 sta->challenge = os_zalloc(WLAN_AUTH_CHALLENGE_LEN);
303 if (sta->challenge == NULL)
304 return WLAN_STATUS_UNSPECIFIED_FAILURE;
305
f441e5af
NL
306 if (os_get_random(key, sizeof(key)) < 0) {
307 os_free(sta->challenge);
308 sta->challenge = NULL;
309 return WLAN_STATUS_UNSPECIFIED_FAILURE;
310 }
311
8ef16831
JM
312 rc4_skip(key, sizeof(key), 0,
313 sta->challenge, WLAN_AUTH_CHALLENGE_LEN);
6fc6879b
JM
314 }
315 return 0;
316 }
317
318 if (auth_transaction != 3)
319 return WLAN_STATUS_UNSPECIFIED_FAILURE;
320
321 /* Transaction 3 */
322 if (!iswep || !sta->challenge || !challenge ||
34ef46ce
JM
323 os_memcmp_const(sta->challenge, challenge,
324 WLAN_AUTH_CHALLENGE_LEN)) {
6fc6879b
JM
325 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
326 HOSTAPD_LEVEL_INFO,
327 "shared key authentication - invalid "
328 "challenge-response");
329 return WLAN_STATUS_CHALLENGE_FAIL;
330 }
331
332 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
333 HOSTAPD_LEVEL_DEBUG,
334 "authentication OK (shared key)");
6fc6879b
JM
335 sta->flags |= WLAN_STA_AUTH;
336 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
6fc6879b
JM
337 os_free(sta->challenge);
338 sta->challenge = NULL;
339
340 return 0;
341}
7cb53ded 342#endif /* CONFIG_NO_RC4 */
6fc6879b
JM
343
344
3912cbd8 345static int send_auth_reply(struct hostapd_data *hapd, struct sta_info *sta,
bb598c3b
AB
346 const u8 *dst, const u8 *bssid,
347 u16 auth_alg, u16 auth_transaction, u16 resp,
e7525a29 348 const u8 *ies, size_t ies_len, const char *dbg)
6fc6879b
JM
349{
350 struct ieee80211_mgmt *reply;
351 u8 *buf;
352 size_t rlen;
bb598c3b 353 int reply_res = WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
354
355 rlen = IEEE80211_HDRLEN + sizeof(reply->u.auth) + ies_len;
356 buf = os_zalloc(rlen);
357 if (buf == NULL)
bb598c3b 358 return -1;
6fc6879b
JM
359
360 reply = (struct ieee80211_mgmt *) buf;
361 reply->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
362 WLAN_FC_STYPE_AUTH);
6fc6879b
JM
363 os_memcpy(reply->da, dst, ETH_ALEN);
364 os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
365 os_memcpy(reply->bssid, bssid, ETH_ALEN);
366
367 reply->u.auth.auth_alg = host_to_le16(auth_alg);
368 reply->u.auth.auth_transaction = host_to_le16(auth_transaction);
369 reply->u.auth.status_code = host_to_le16(resp);
370
371 if (ies && ies_len)
372 os_memcpy(reply->u.auth.variable, ies, ies_len);
373
374 wpa_printf(MSG_DEBUG, "authentication reply: STA=" MACSTR
e7525a29 375 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu) (dbg=%s)",
6fc6879b 376 MAC2STR(dst), auth_alg, auth_transaction,
e7525a29 377 resp, (unsigned long) ies_len, dbg);
3912cbd8
JM
378#ifdef CONFIG_TESTING_OPTIONS
379#ifdef CONFIG_SAE
380 if (hapd->conf->sae_confirm_immediate == 2 &&
381 auth_alg == WLAN_AUTH_SAE) {
382 if (auth_transaction == 1 &&
383 (resp == WLAN_STATUS_SUCCESS ||
384 resp == WLAN_STATUS_SAE_HASH_TO_ELEMENT)) {
385 wpa_printf(MSG_DEBUG,
386 "TESTING: Postpone SAE Commit transmission until Confirm is ready");
387 os_free(sta->sae_postponed_commit);
388 sta->sae_postponed_commit = buf;
389 sta->sae_postponed_commit_len = rlen;
390 return WLAN_STATUS_SUCCESS;
391 }
392
393 if (auth_transaction == 2 && sta && sta->sae_postponed_commit) {
394 wpa_printf(MSG_DEBUG,
395 "TESTING: Send postponed SAE Commit first, immediately followed by SAE Confirm");
396 if (hostapd_drv_send_mlme(hapd,
397 sta->sae_postponed_commit,
398 sta->sae_postponed_commit_len,
399 0, NULL, 0, 0) < 0)
400 wpa_printf(MSG_INFO, "send_auth_reply: send failed");
401 os_free(sta->sae_postponed_commit);
402 sta->sae_postponed_commit = NULL;
403 sta->sae_postponed_commit_len = 0;
404 }
405 }
406#endif /* CONFIG_SAE */
407#endif /* CONFIG_TESTING_OPTIONS */
37100274 408 if (hostapd_drv_send_mlme(hapd, reply, rlen, 0, NULL, 0, 0) < 0)
bb598c3b
AB
409 wpa_printf(MSG_INFO, "send_auth_reply: send failed");
410 else
411 reply_res = WLAN_STATUS_SUCCESS;
6fc6879b
JM
412
413 os_free(buf);
bb598c3b
AB
414
415 return reply_res;
6fc6879b
JM
416}
417
418
4ec1fd8e 419#ifdef CONFIG_IEEE80211R_AP
6fc6879b
JM
420static void handle_auth_ft_finish(void *ctx, const u8 *dst, const u8 *bssid,
421 u16 auth_transaction, u16 status,
422 const u8 *ies, size_t ies_len)
423{
424 struct hostapd_data *hapd = ctx;
425 struct sta_info *sta;
bb598c3b 426 int reply_res;
6fc6879b 427
3912cbd8 428 reply_res = send_auth_reply(hapd, NULL, dst, bssid, WLAN_AUTH_FT,
e7525a29
BG
429 auth_transaction, status, ies, ies_len,
430 "auth-ft-finish");
6fc6879b
JM
431
432 sta = ap_get_sta(hapd, dst);
433 if (sta == NULL)
434 return;
435
bb598c3b
AB
436 if (sta->added_unassoc && (reply_res != WLAN_STATUS_SUCCESS ||
437 status != WLAN_STATUS_SUCCESS)) {
438 hostapd_drv_sta_remove(hapd, sta->addr);
439 sta->added_unassoc = 0;
440 return;
441 }
442
443 if (status != WLAN_STATUS_SUCCESS)
444 return;
445
6fc6879b
JM
446 hostapd_logger(hapd, dst, HOSTAPD_MODULE_IEEE80211,
447 HOSTAPD_LEVEL_DEBUG, "authentication OK (FT)");
448 sta->flags |= WLAN_STA_AUTH;
449 mlme_authenticate_indication(hapd, sta);
450}
4ec1fd8e 451#endif /* CONFIG_IEEE80211R_AP */
6fc6879b
JM
452
453
c10347f2 454#ifdef CONFIG_SAE
21af6d15 455
9249afc8
JM
456static void sae_set_state(struct sta_info *sta, enum sae_state state,
457 const char *reason)
458{
459 wpa_printf(MSG_DEBUG, "SAE: State %s -> %s for peer " MACSTR " (%s)",
460 sae_state_txt(sta->sae->state), sae_state_txt(state),
461 MAC2STR(sta->addr), reason);
462 sta->sae->state = state;
463}
464
465
e96da42b 466static struct wpabuf * auth_build_sae_commit(struct hostapd_data *hapd,
93a1e275
JM
467 struct sta_info *sta, int update,
468 int status_code)
21af6d15
JM
469{
470 struct wpabuf *buf;
9be19d0b
JM
471 const char *password = NULL;
472 struct sae_password_entry *pw;
473 const char *rx_id = NULL;
a5dc2a5c
JM
474 int use_pt = 0;
475 struct sae_pt *pt = NULL;
21af6d15 476
a5dc2a5c 477 if (sta->sae->tmp) {
9be19d0b 478 rx_id = sta->sae->tmp->pw_id;
a5dc2a5c
JM
479 use_pt = sta->sae->tmp->h2e;
480 }
9be19d0b 481
641d79f1 482 if (rx_id && hapd->conf->sae_pwe != 3)
e36a5894
JM
483 use_pt = 1;
484 else if (status_code == WLAN_STATUS_SUCCESS)
93a1e275
JM
485 use_pt = 0;
486 else if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT)
487 use_pt = 1;
488
9be19d0b
JM
489 for (pw = hapd->conf->sae_passwords; pw; pw = pw->next) {
490 if (!is_broadcast_ether_addr(pw->peer_addr) &&
491 os_memcmp(pw->peer_addr, sta->addr, ETH_ALEN) != 0)
492 continue;
493 if ((rx_id && !pw->identifier) || (!rx_id && pw->identifier))
494 continue;
495 if (rx_id && pw->identifier &&
496 os_strcmp(rx_id, pw->identifier) != 0)
497 continue;
498 password = pw->password;
a5dc2a5c 499 pt = pw->pt;
9be19d0b
JM
500 break;
501 }
2377c1ca 502 if (!password) {
a5dc2a5c
JM
503 password = hapd->conf->ssid.wpa_passphrase;
504 pt = hapd->conf->ssid.pt;
505 }
506 if (!password || (use_pt && !pt)) {
146f6c9a
JM
507 wpa_printf(MSG_DEBUG, "SAE: No password available");
508 return NULL;
509 }
510
a5dc2a5c
JM
511 if (update && use_pt &&
512 sae_prepare_commit_pt(sta->sae, pt, hapd->own_addr, sta->addr,
513 NULL) < 0)
514 return NULL;
515
516 if (update && !use_pt &&
872b7545 517 sae_prepare_commit(hapd->own_addr, sta->addr,
9be19d0b 518 (u8 *) password, os_strlen(password), rx_id,
8e31e955
JM
519 sta->sae) < 0) {
520 wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
21af6d15 521 return NULL;
8e31e955 522 }
21af6d15 523
b0e91e38
JM
524 if (pw && pw->vlan_id) {
525 if (!sta->sae->tmp) {
526 wpa_printf(MSG_INFO,
527 "SAE: No temporary data allocated - cannot store VLAN ID");
528 return NULL;
529 }
530 sta->sae->tmp->vlan_id = pw->vlan_id;
531 }
532
9be19d0b
JM
533 buf = wpabuf_alloc(SAE_COMMIT_MAX_LEN +
534 (rx_id ? 3 + os_strlen(rx_id) : 0));
8e31e955
JM
535 if (buf == NULL)
536 return NULL;
872b7545 537 sae_write_commit(sta->sae, buf, sta->sae->tmp ?
9be19d0b 538 sta->sae->tmp->anti_clogging_token : NULL, rx_id);
21af6d15
JM
539
540 return buf;
541}
542
543
544static struct wpabuf * auth_build_sae_confirm(struct hostapd_data *hapd,
545 struct sta_info *sta)
546{
547 struct wpabuf *buf;
548
fb8fcc29 549 buf = wpabuf_alloc(SAE_CONFIRM_MAX_LEN);
21af6d15
JM
550 if (buf == NULL)
551 return NULL;
552
fb8fcc29 553 sae_write_confirm(sta->sae, buf);
21af6d15
JM
554
555 return buf;
556}
557
558
e96da42b
BC
559static int auth_sae_send_commit(struct hostapd_data *hapd,
560 struct sta_info *sta,
93a1e275 561 const u8 *bssid, int update, int status_code)
e96da42b
BC
562{
563 struct wpabuf *data;
bb598c3b 564 int reply_res;
a5dc2a5c 565 u16 status;
e96da42b 566
93a1e275 567 data = auth_build_sae_commit(hapd, sta, update, status_code);
9be19d0b
JM
568 if (!data && sta->sae->tmp && sta->sae->tmp->pw_id)
569 return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER;
e96da42b
BC
570 if (data == NULL)
571 return WLAN_STATUS_UNSPECIFIED_FAILURE;
572
a5dc2a5c
JM
573 status = (sta->sae->tmp && sta->sae->tmp->h2e) ?
574 WLAN_STATUS_SAE_HASH_TO_ELEMENT : WLAN_STATUS_SUCCESS;
3912cbd8
JM
575 reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
576 WLAN_AUTH_SAE, 1,
a5dc2a5c 577 status, wpabuf_head(data),
e7525a29 578 wpabuf_len(data), "sae-send-commit");
e96da42b
BC
579
580 wpabuf_free(data);
581
bb598c3b 582 return reply_res;
e96da42b
BC
583}
584
585
586static int auth_sae_send_confirm(struct hostapd_data *hapd,
587 struct sta_info *sta,
588 const u8 *bssid)
589{
590 struct wpabuf *data;
bb598c3b 591 int reply_res;
e96da42b
BC
592
593 data = auth_build_sae_confirm(hapd, sta);
594 if (data == NULL)
595 return WLAN_STATUS_UNSPECIFIED_FAILURE;
596
3912cbd8
JM
597 reply_res = send_auth_reply(hapd, sta, sta->addr, bssid,
598 WLAN_AUTH_SAE, 2,
bb598c3b 599 WLAN_STATUS_SUCCESS, wpabuf_head(data),
e7525a29 600 wpabuf_len(data), "sae-send-confirm");
e96da42b
BC
601
602 wpabuf_free(data);
603
bb598c3b 604 return reply_res;
e96da42b
BC
605}
606
607
d136c376
JM
608static int use_sae_anti_clogging(struct hostapd_data *hapd)
609{
610 struct sta_info *sta;
611 unsigned int open = 0;
612
613 if (hapd->conf->sae_anti_clogging_threshold == 0)
614 return 1;
615
616 for (sta = hapd->sta_list; sta; sta = sta->next) {
617 if (!sta->sae)
618 continue;
619 if (sta->sae->state != SAE_COMMITTED &&
620 sta->sae->state != SAE_CONFIRMED)
621 continue;
622 open++;
623 if (open >= hapd->conf->sae_anti_clogging_threshold)
624 return 1;
625 }
626
ff9f40ae
JM
627 /* In addition to already existing open SAE sessions, check whether
628 * there are enough pending commit messages in the processing queue to
629 * potentially result in too many open sessions. */
630 if (open + dl_list_len(&hapd->sae_commit_queue) >=
631 hapd->conf->sae_anti_clogging_threshold)
632 return 1;
633
d136c376
JM
634 return 0;
635}
636
637
a9af1da0
JM
638static u8 sae_token_hash(struct hostapd_data *hapd, const u8 *addr)
639{
640 u8 hash[SHA256_MAC_LEN];
641
642 hmac_sha256(hapd->sae_token_key, sizeof(hapd->sae_token_key),
643 addr, ETH_ALEN, hash);
644 return hash[0];
645}
646
647
d136c376
JM
648static int check_sae_token(struct hostapd_data *hapd, const u8 *addr,
649 const u8 *token, size_t token_len)
650{
651 u8 mac[SHA256_MAC_LEN];
a9af1da0
JM
652 const u8 *addrs[2];
653 size_t len[2];
654 u16 token_idx;
655 u8 idx;
d136c376
JM
656
657 if (token_len != SHA256_MAC_LEN)
658 return -1;
a9af1da0
JM
659 idx = sae_token_hash(hapd, addr);
660 token_idx = hapd->sae_pending_token_idx[idx];
661 if (token_idx == 0 || token_idx != WPA_GET_BE16(token)) {
662 wpa_printf(MSG_DEBUG, "SAE: Invalid anti-clogging token from "
663 MACSTR " - token_idx 0x%04x, expected 0x%04x",
664 MAC2STR(addr), WPA_GET_BE16(token), token_idx);
665 return -1;
666 }
667
668 addrs[0] = addr;
669 len[0] = ETH_ALEN;
670 addrs[1] = token;
671 len[1] = 2;
672 if (hmac_sha256_vector(hapd->sae_token_key, sizeof(hapd->sae_token_key),
673 2, addrs, len, mac) < 0 ||
674 os_memcmp_const(token + 2, &mac[2], SHA256_MAC_LEN - 2) != 0)
d136c376
JM
675 return -1;
676
a9af1da0
JM
677 hapd->sae_pending_token_idx[idx] = 0; /* invalidate used token */
678
d136c376
JM
679 return 0;
680}
681
682
683static struct wpabuf * auth_build_token_req(struct hostapd_data *hapd,
5e32fb01 684 int group, const u8 *addr, int h2e)
d136c376
JM
685{
686 struct wpabuf *buf;
687 u8 *token;
fe52c210 688 struct os_reltime now;
a9af1da0
JM
689 u8 idx[2];
690 const u8 *addrs[2];
691 size_t len[2];
692 u8 p_idx;
693 u16 token_idx;
d136c376 694
fe52c210
JB
695 os_get_reltime(&now);
696 if (!os_reltime_initialized(&hapd->last_sae_token_key_update) ||
a9af1da0
JM
697 os_reltime_expired(&now, &hapd->last_sae_token_key_update, 60) ||
698 hapd->sae_token_idx == 0xffff) {
a50414c3
JM
699 if (random_get_bytes(hapd->sae_token_key,
700 sizeof(hapd->sae_token_key)) < 0)
701 return NULL;
d136c376
JM
702 wpa_hexdump(MSG_DEBUG, "SAE: Updated token key",
703 hapd->sae_token_key, sizeof(hapd->sae_token_key));
fe52c210 704 hapd->last_sae_token_key_update = now;
a9af1da0
JM
705 hapd->sae_token_idx = 0;
706 os_memset(hapd->sae_pending_token_idx, 0,
707 sizeof(hapd->sae_pending_token_idx));
d136c376
JM
708 }
709
5e32fb01 710 buf = wpabuf_alloc(sizeof(le16) + 3 + SHA256_MAC_LEN);
d136c376
JM
711 if (buf == NULL)
712 return NULL;
713
a959a3b6
MH
714 wpabuf_put_le16(buf, group); /* Finite Cyclic Group */
715
5e32fb01
JM
716 if (h2e) {
717 /* Encapsulate Anti-clogging Token field in a container IE */
718 wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
719 wpabuf_put_u8(buf, 1 + SHA256_MAC_LEN);
720 wpabuf_put_u8(buf, WLAN_EID_EXT_ANTI_CLOGGING_TOKEN);
721 }
722
a9af1da0
JM
723 p_idx = sae_token_hash(hapd, addr);
724 token_idx = hapd->sae_pending_token_idx[p_idx];
725 if (!token_idx) {
726 hapd->sae_token_idx++;
727 token_idx = hapd->sae_token_idx;
728 hapd->sae_pending_token_idx[p_idx] = token_idx;
729 }
730 WPA_PUT_BE16(idx, token_idx);
d136c376 731 token = wpabuf_put(buf, SHA256_MAC_LEN);
a9af1da0
JM
732 addrs[0] = addr;
733 len[0] = ETH_ALEN;
734 addrs[1] = idx;
735 len[1] = sizeof(idx);
736 if (hmac_sha256_vector(hapd->sae_token_key, sizeof(hapd->sae_token_key),
737 2, addrs, len, token) < 0) {
738 wpabuf_free(buf);
739 return NULL;
740 }
741 WPA_PUT_BE16(token, token_idx);
d136c376
JM
742
743 return buf;
744}
745
746
d8b841eb 747static int sae_check_big_sync(struct hostapd_data *hapd, struct sta_info *sta)
f3b8ad4d 748{
d8b841eb 749 if (sta->sae->sync > hapd->conf->sae_sync) {
9249afc8 750 sae_set_state(sta, SAE_NOTHING, "Sync > dot11RSNASAESync");
f3b8ad4d
BC
751 sta->sae->sync = 0;
752 return -1;
753 }
754 return 0;
755}
756
757
758static void auth_sae_retransmit_timer(void *eloop_ctx, void *eloop_data)
759{
760 struct hostapd_data *hapd = eloop_ctx;
761 struct sta_info *sta = eloop_data;
762 int ret;
763
d8b841eb 764 if (sae_check_big_sync(hapd, sta))
f3b8ad4d
BC
765 return;
766 sta->sae->sync++;
dad01292 767 wpa_printf(MSG_DEBUG, "SAE: Auth SAE retransmit timer for " MACSTR
9249afc8
JM
768 " (sync=%d state=%s)",
769 MAC2STR(sta->addr), sta->sae->sync,
770 sae_state_txt(sta->sae->state));
f3b8ad4d
BC
771
772 switch (sta->sae->state) {
773 case SAE_COMMITTED:
93a1e275 774 ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0, -1);
ecd40fef
MH
775 eloop_register_timeout(0,
776 hapd->dot11RSNASAERetransPeriod * 1000,
f3b8ad4d
BC
777 auth_sae_retransmit_timer, hapd, sta);
778 break;
779 case SAE_CONFIRMED:
780 ret = auth_sae_send_confirm(hapd, sta, hapd->own_addr);
ecd40fef
MH
781 eloop_register_timeout(0,
782 hapd->dot11RSNASAERetransPeriod * 1000,
f3b8ad4d
BC
783 auth_sae_retransmit_timer, hapd, sta);
784 break;
785 default:
786 ret = -1;
787 break;
788 }
789
790 if (ret != WLAN_STATUS_SUCCESS)
791 wpa_printf(MSG_INFO, "SAE: Failed to retransmit: ret=%d", ret);
792}
793
794
795void sae_clear_retransmit_timer(struct hostapd_data *hapd, struct sta_info *sta)
796{
797 eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
798}
799
800
801static void sae_set_retransmit_timer(struct hostapd_data *hapd,
802 struct sta_info *sta)
803{
804 if (!(hapd->conf->mesh & MESH_ENABLED))
805 return;
806
807 eloop_cancel_timeout(auth_sae_retransmit_timer, hapd, sta);
ecd40fef 808 eloop_register_timeout(0, hapd->dot11RSNASAERetransPeriod * 1000,
f3b8ad4d
BC
809 auth_sae_retransmit_timer, hapd, sta);
810}
811
812
4ffb0fef
SD
813static void sae_sme_send_external_auth_status(struct hostapd_data *hapd,
814 struct sta_info *sta, u16 status)
815{
816 struct external_auth params;
817
818 os_memset(&params, 0, sizeof(params));
819 params.status = status;
dd1a8cef 820 params.bssid = sta->addr;
14d85a5a
SD
821 if (status == WLAN_STATUS_SUCCESS && sta->sae &&
822 !hapd->conf->disable_pmksa_caching)
4ffb0fef
SD
823 params.pmkid = sta->sae->pmkid;
824
825 hostapd_drv_send_external_auth_status(hapd, &params);
826}
827
828
9f2cf23e
MH
829void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
830{
b0e91e38
JM
831#ifndef CONFIG_NO_VLAN
832 struct vlan_description vlan_desc;
833
834 if (sta->sae->tmp && sta->sae->tmp->vlan_id > 0) {
835 wpa_printf(MSG_DEBUG, "SAE: Assign STA " MACSTR
836 " to VLAN ID %d",
837 MAC2STR(sta->addr), sta->sae->tmp->vlan_id);
838
839 os_memset(&vlan_desc, 0, sizeof(vlan_desc));
840 vlan_desc.notempty = 1;
841 vlan_desc.untagged = sta->sae->tmp->vlan_id;
842 if (!hostapd_vlan_valid(hapd->conf->vlan, &vlan_desc)) {
843 wpa_printf(MSG_INFO,
844 "Invalid VLAN ID %d in sae_password",
845 sta->sae->tmp->vlan_id);
846 return;
847 }
848
849 if (ap_sta_set_vlan(hapd, sta, &vlan_desc) < 0 ||
850 ap_sta_bind_vlan(hapd, sta) < 0) {
851 wpa_printf(MSG_INFO,
852 "Failed to assign VLAN ID %d from sae_password to "
853 MACSTR, sta->sae->tmp->vlan_id,
854 MAC2STR(sta->addr));
855 return;
856 }
857 }
858#endif /* CONFIG_NO_VLAN */
859
9f2cf23e
MH
860 sta->flags |= WLAN_STA_AUTH;
861 sta->auth_alg = WLAN_AUTH_SAE;
862 mlme_authenticate_indication(hapd, sta);
863 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
9249afc8 864 sae_set_state(sta, SAE_ACCEPTED, "Accept Confirm");
8f8473ce
JM
865 crypto_bignum_deinit(sta->sae->peer_commit_scalar_accepted, 0);
866 sta->sae->peer_commit_scalar_accepted = sta->sae->peer_commit_scalar;
867 sta->sae->peer_commit_scalar = NULL;
9f2cf23e
MH
868 wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
869 sta->sae->pmk, sta->sae->pmkid);
4ffb0fef 870 sae_sme_send_external_auth_status(hapd, sta, WLAN_STATUS_SUCCESS);
9f2cf23e
MH
871}
872
873
e96da42b 874static int sae_sm_step(struct hostapd_data *hapd, struct sta_info *sta,
a5dc2a5c
JM
875 const u8 *bssid, u16 auth_transaction, u16 status_code,
876 int allow_reuse, int *sta_removed)
e96da42b
BC
877{
878 int ret;
879
10cf866b
JM
880 *sta_removed = 0;
881
e96da42b
BC
882 if (auth_transaction != 1 && auth_transaction != 2)
883 return WLAN_STATUS_UNSPECIFIED_FAILURE;
884
9249afc8
JM
885 wpa_printf(MSG_DEBUG, "SAE: Peer " MACSTR " state=%s auth_trans=%u",
886 MAC2STR(sta->addr), sae_state_txt(sta->sae->state),
887 auth_transaction);
e96da42b
BC
888 switch (sta->sae->state) {
889 case SAE_NOTHING:
890 if (auth_transaction == 1) {
a5dc2a5c
JM
891 if (sta->sae->tmp)
892 sta->sae->tmp->h2e = status_code ==
893 WLAN_STATUS_SAE_HASH_TO_ELEMENT;
f2143615 894 ret = auth_sae_send_commit(hapd, sta, bssid,
93a1e275 895 !allow_reuse, status_code);
e96da42b
BC
896 if (ret)
897 return ret;
9249afc8 898 sae_set_state(sta, SAE_COMMITTED, "Sent Commit");
e96da42b
BC
899
900 if (sae_process_commit(sta->sae) < 0)
901 return WLAN_STATUS_UNSPECIFIED_FAILURE;
902
903 /*
f7fe0552
JM
904 * In mesh case, both Commit and Confirm are sent
905 * immediately. In infrastructure BSS, by default, only
906 * a single Authentication frame (Commit) is expected
907 * from the AP here and the second one (Confirm) will
908 * be sent once the STA has sent its second
909 * Authentication frame (Confirm). This behavior can be
910 * overridden with explicit configuration so that the
911 * infrastructure BSS case sends both frames together.
e96da42b 912 */
f7fe0552
JM
913 if ((hapd->conf->mesh & MESH_ENABLED) ||
914 hapd->conf->sae_confirm_immediate) {
e96da42b
BC
915 /*
916 * Send both Commit and Confirm immediately
917 * based on SAE finite state machine
918 * Nothing -> Confirm transition.
919 */
920 ret = auth_sae_send_confirm(hapd, sta, bssid);
921 if (ret)
922 return ret;
9249afc8
JM
923 sae_set_state(sta, SAE_CONFIRMED,
924 "Sent Confirm (mesh)");
e96da42b
BC
925 } else {
926 /*
927 * For infrastructure BSS, send only the Commit
928 * message now to get alternating sequence of
929 * Authentication frames between the AP and STA.
930 * Confirm will be sent in
746e5c25 931 * Committed -> Confirmed/Accepted transition
e96da42b
BC
932 * when receiving Confirm from STA.
933 */
934 }
f3b8ad4d
BC
935 sta->sae->sync = 0;
936 sae_set_retransmit_timer(hapd, sta);
e96da42b
BC
937 } else {
938 hostapd_logger(hapd, sta->addr,
939 HOSTAPD_MODULE_IEEE80211,
940 HOSTAPD_LEVEL_DEBUG,
941 "SAE confirm before commit");
942 }
943 break;
944 case SAE_COMMITTED:
f3b8ad4d 945 sae_clear_retransmit_timer(hapd, sta);
e96da42b
BC
946 if (auth_transaction == 1) {
947 if (sae_process_commit(sta->sae) < 0)
948 return WLAN_STATUS_UNSPECIFIED_FAILURE;
949
950 ret = auth_sae_send_confirm(hapd, sta, bssid);
951 if (ret)
952 return ret;
9249afc8 953 sae_set_state(sta, SAE_CONFIRMED, "Sent Confirm");
f3b8ad4d
BC
954 sta->sae->sync = 0;
955 sae_set_retransmit_timer(hapd, sta);
e96da42b
BC
956 } else if (hapd->conf->mesh & MESH_ENABLED) {
957 /*
958 * In mesh case, follow SAE finite state machine and
f3b8ad4d 959 * send Commit now, if sync count allows.
e96da42b 960 */
d8b841eb 961 if (sae_check_big_sync(hapd, sta))
f3b8ad4d
BC
962 return WLAN_STATUS_SUCCESS;
963 sta->sae->sync++;
964
93a1e275
JM
965 ret = auth_sae_send_commit(hapd, sta, bssid, 0,
966 status_code);
e96da42b
BC
967 if (ret)
968 return ret;
f3b8ad4d
BC
969
970 sae_set_retransmit_timer(hapd, sta);
e96da42b
BC
971 } else {
972 /*
973 * For instructure BSS, send the postponed Confirm from
974 * Nothing -> Confirmed transition that was reduced to
975 * Nothing -> Committed above.
976 */
977 ret = auth_sae_send_confirm(hapd, sta, bssid);
978 if (ret)
979 return ret;
980
9249afc8 981 sae_set_state(sta, SAE_CONFIRMED, "Sent Confirm");
e96da42b
BC
982
983 /*
984 * Since this was triggered on Confirm RX, run another
985 * step to get to Accepted without waiting for
986 * additional events.
987 */
f2143615 988 return sae_sm_step(hapd, sta, bssid, auth_transaction,
a5dc2a5c 989 WLAN_STATUS_SUCCESS, 0, sta_removed);
e96da42b
BC
990 }
991 break;
992 case SAE_CONFIRMED:
f3b8ad4d 993 sae_clear_retransmit_timer(hapd, sta);
e96da42b 994 if (auth_transaction == 1) {
d8b841eb 995 if (sae_check_big_sync(hapd, sta))
f3b8ad4d
BC
996 return WLAN_STATUS_SUCCESS;
997 sta->sae->sync++;
998
93a1e275
JM
999 ret = auth_sae_send_commit(hapd, sta, bssid, 1,
1000 status_code);
e96da42b
BC
1001 if (ret)
1002 return ret;
1003
1004 if (sae_process_commit(sta->sae) < 0)
1005 return WLAN_STATUS_UNSPECIFIED_FAILURE;
1006
1007 ret = auth_sae_send_confirm(hapd, sta, bssid);
1008 if (ret)
1009 return ret;
f3b8ad4d
BC
1010
1011 sae_set_retransmit_timer(hapd, sta);
e96da42b 1012 } else {
c4fc7e31 1013 sta->sae->send_confirm = 0xffff;
9f2cf23e 1014 sae_accept_sta(hapd, sta);
e96da42b
BC
1015 }
1016 break;
1017 case SAE_ACCEPTED:
e8d08cf3
JM
1018 if (auth_transaction == 1 &&
1019 (hapd->conf->mesh & MESH_ENABLED)) {
e96da42b
BC
1020 wpa_printf(MSG_DEBUG, "SAE: remove the STA (" MACSTR
1021 ") doing reauthentication",
1022 MAC2STR(sta->addr));
9f2cf23e 1023 wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
153d4c50 1024 ap_free_sta(hapd, sta);
10cf866b 1025 *sta_removed = 1;
e8d08cf3
JM
1026 } else if (auth_transaction == 1) {
1027 wpa_printf(MSG_DEBUG, "SAE: Start reauthentication");
93a1e275
JM
1028 ret = auth_sae_send_commit(hapd, sta, bssid, 1,
1029 status_code);
e8d08cf3
JM
1030 if (ret)
1031 return ret;
1032 sae_set_state(sta, SAE_COMMITTED, "Sent Commit");
1033
1034 if (sae_process_commit(sta->sae) < 0)
1035 return WLAN_STATUS_UNSPECIFIED_FAILURE;
1036 sta->sae->sync = 0;
1037 sae_set_retransmit_timer(hapd, sta);
e96da42b 1038 } else {
d8b841eb 1039 if (sae_check_big_sync(hapd, sta))
f3b8ad4d
BC
1040 return WLAN_STATUS_SUCCESS;
1041 sta->sae->sync++;
1042
e96da42b
BC
1043 ret = auth_sae_send_confirm(hapd, sta, bssid);
1044 sae_clear_temp_data(sta->sae);
1045 if (ret)
1046 return ret;
1047 }
1048 break;
1049 default:
1050 wpa_printf(MSG_ERROR, "SAE: invalid state %d",
1051 sta->sae->state);
1052 return WLAN_STATUS_UNSPECIFIED_FAILURE;
1053 }
1054 return WLAN_STATUS_SUCCESS;
1055}
1056
1057
dad01292
JM
1058static void sae_pick_next_group(struct hostapd_data *hapd, struct sta_info *sta)
1059{
1060 struct sae_data *sae = sta->sae;
1061 int i, *groups = hapd->conf->sae_groups;
941bad5e 1062 int default_groups[] = { 19, 0 };
dad01292
JM
1063
1064 if (sae->state != SAE_COMMITTED)
1065 return;
1066
1067 wpa_printf(MSG_DEBUG, "SAE: Previously selected group: %d", sae->group);
1068
941bad5e
JM
1069 if (!groups)
1070 groups = default_groups;
1071 for (i = 0; groups[i] > 0; i++) {
dad01292
JM
1072 if (sae->group == groups[i])
1073 break;
1074 }
1075
941bad5e 1076 if (groups[i] <= 0) {
dad01292
JM
1077 wpa_printf(MSG_DEBUG,
1078 "SAE: Previously selected group not found from the current configuration");
1079 return;
1080 }
1081
1082 for (;;) {
1083 i++;
1084 if (groups[i] <= 0) {
1085 wpa_printf(MSG_DEBUG,
1086 "SAE: No alternative group enabled");
1087 return;
1088 }
1089
1090 if (sae_set_group(sae, groups[i]) < 0)
1091 continue;
1092
1093 break;
1094 }
1095 wpa_printf(MSG_DEBUG, "SAE: Selected new group: %d", groups[i]);
1096}
1097
1098
a5dc2a5c
JM
1099static int sae_status_success(struct hostapd_data *hapd, u16 status_code)
1100{
e36a5894
JM
1101 int sae_pwe = hapd->conf->sae_pwe;
1102 int id_in_use;
1103
1104 id_in_use = hostapd_sae_pw_id_in_use(hapd->conf);
641d79f1 1105 if (id_in_use == 2 && sae_pwe != 3)
e36a5894
JM
1106 sae_pwe = 1;
1107 else if (id_in_use == 1 && sae_pwe == 0)
1108 sae_pwe = 2;
1109
641d79f1 1110 return ((sae_pwe == 0 || sae_pwe == 3) &&
a5dc2a5c 1111 status_code == WLAN_STATUS_SUCCESS) ||
e36a5894 1112 (sae_pwe == 1 &&
a5dc2a5c 1113 status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT) ||
e36a5894 1114 (sae_pwe == 2 &&
a5dc2a5c
JM
1115 (status_code == WLAN_STATUS_SUCCESS ||
1116 status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT));
1117}
1118
1119
032c8264
JM
1120static int sae_is_group_enabled(struct hostapd_data *hapd, int group)
1121{
1122 int *groups = hapd->conf->sae_groups;
1123 int default_groups[] = { 19, 0 };
1124 int i;
1125
1126 if (!groups)
1127 groups = default_groups;
1128
1129 for (i = 0; groups[i] > 0; i++) {
1130 if (groups[i] == group)
1131 return 1;
1132 }
1133
1134 return 0;
1135}
1136
1137
1138static int check_sae_rejected_groups(struct hostapd_data *hapd,
1139 const struct wpabuf *groups)
1140{
1141 size_t i, count;
1142 const u8 *pos;
1143
1144 if (!groups)
1145 return 0;
1146
1147 pos = wpabuf_head(groups);
1148 count = wpabuf_len(groups) / 2;
1149 for (i = 0; i < count; i++) {
1150 int enabled;
1151 u16 group;
1152
1153 group = WPA_GET_LE16(pos);
1154 pos += 2;
1155 enabled = sae_is_group_enabled(hapd, group);
1156 wpa_printf(MSG_DEBUG, "SAE: Rejected group %u is %s",
1157 group, enabled ? "enabled" : "disabled");
1158 if (enabled)
1159 return 1;
1160 }
1161
1162 return 0;
1163}
1164
1165
c10347f2
JM
1166static void handle_auth_sae(struct hostapd_data *hapd, struct sta_info *sta,
1167 const struct ieee80211_mgmt *mgmt, size_t len,
afa2ffb4 1168 u16 auth_transaction, u16 status_code)
c10347f2 1169{
bb598c3b 1170 int resp = WLAN_STATUS_SUCCESS;
750efe6e 1171 struct wpabuf *data = NULL;
941bad5e
JM
1172 int *groups = hapd->conf->sae_groups;
1173 int default_groups[] = { 19, 0 };
96d6dfa8 1174 const u8 *pos, *end;
10cf866b 1175 int sta_removed = 0;
941bad5e
JM
1176
1177 if (!groups)
1178 groups = default_groups;
c10347f2 1179
e7533538
JM
1180#ifdef CONFIG_TESTING_OPTIONS
1181 if (hapd->conf->sae_reflection_attack && auth_transaction == 1) {
e7533538
JM
1182 wpa_printf(MSG_DEBUG, "SAE: TESTING - reflection attack");
1183 pos = mgmt->u.auth.variable;
1184 end = ((const u8 *) mgmt) + len;
3912cbd8 1185 send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
e7525a29
BG
1186 auth_transaction, resp, pos, end - pos,
1187 "auth-sae-reflection-attack");
e7533538
JM
1188 goto remove_sta;
1189 }
3648d8a1
JM
1190
1191 if (hapd->conf->sae_commit_override && auth_transaction == 1) {
1192 wpa_printf(MSG_DEBUG, "SAE: TESTING - commit override");
3912cbd8 1193 send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
3648d8a1
JM
1194 auth_transaction, resp,
1195 wpabuf_head(hapd->conf->sae_commit_override),
e7525a29
BG
1196 wpabuf_len(hapd->conf->sae_commit_override),
1197 "sae-commit-override");
3648d8a1
JM
1198 goto remove_sta;
1199 }
e7533538 1200#endif /* CONFIG_TESTING_OPTIONS */
98efcc41 1201 if (!sta->sae) {
bb598c3b 1202 if (auth_transaction != 1 ||
a5dc2a5c 1203 !sae_status_success(hapd, status_code)) {
918df222
JM
1204 wpa_printf(MSG_DEBUG, "SAE: Unexpected Status Code %u",
1205 status_code);
1206 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1207 goto reply;
bb598c3b 1208 }
98efcc41 1209 sta->sae = os_zalloc(sizeof(*sta->sae));
bb598c3b
AB
1210 if (!sta->sae) {
1211 resp = -1;
1212 goto remove_sta;
1213 }
9249afc8 1214 sae_set_state(sta, SAE_NOTHING, "Init");
f3b8ad4d 1215 sta->sae->sync = 0;
98efcc41
JM
1216 }
1217
9f2cf23e
MH
1218 if (sta->mesh_sae_pmksa_caching) {
1219 wpa_printf(MSG_DEBUG,
1220 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
1221 wpa_auth_pmksa_remove(hapd->wpa_auth, sta->addr);
1222 sta->mesh_sae_pmksa_caching = 0;
1223 }
1224
c10347f2 1225 if (auth_transaction == 1) {
96d6dfa8 1226 const u8 *token = NULL;
d136c376 1227 size_t token_len = 0;
f2143615
JM
1228 int allow_reuse = 0;
1229
c10347f2
JM
1230 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1231 HOSTAPD_LEVEL_DEBUG,
9c951244
AK
1232 "start SAE authentication (RX commit, status=%u (%s))",
1233 status_code, status2str(status_code));
872b7545
MH
1234
1235 if ((hapd->conf->mesh & MESH_ENABLED) &&
afa2ffb4
JM
1236 status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
1237 sta->sae->tmp) {
a959a3b6
MH
1238 pos = mgmt->u.auth.variable;
1239 end = ((const u8 *) mgmt) + len;
1240 if (pos + sizeof(le16) > end) {
1241 wpa_printf(MSG_ERROR,
1242 "SAE: Too short anti-clogging token request");
1243 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1244 goto reply;
1245 }
941bad5e 1246 resp = sae_group_allowed(sta->sae, groups,
a959a3b6
MH
1247 WPA_GET_LE16(pos));
1248 if (resp != WLAN_STATUS_SUCCESS) {
1249 wpa_printf(MSG_ERROR,
1250 "SAE: Invalid group in anti-clogging token request");
1251 goto reply;
1252 }
1253 pos += sizeof(le16);
1254
872b7545
MH
1255 wpabuf_free(sta->sae->tmp->anti_clogging_token);
1256 sta->sae->tmp->anti_clogging_token =
a959a3b6 1257 wpabuf_alloc_copy(pos, end - pos);
872b7545
MH
1258 if (sta->sae->tmp->anti_clogging_token == NULL) {
1259 wpa_printf(MSG_ERROR,
1260 "SAE: Failed to alloc for anti-clogging token");
bb598c3b
AB
1261 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1262 goto remove_sta;
872b7545
MH
1263 }
1264
1265 /*
1266 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
1267 * is 76, a new Commit Message shall be constructed
1268 * with the Anti-Clogging Token from the received
1269 * Authentication frame, and the commit-scalar and
1270 * COMMIT-ELEMENT previously sent.
1271 */
93a1e275
JM
1272 resp = auth_sae_send_commit(hapd, sta, mgmt->bssid, 0,
1273 status_code);
bb598c3b 1274 if (resp != WLAN_STATUS_SUCCESS) {
872b7545
MH
1275 wpa_printf(MSG_ERROR,
1276 "SAE: Failed to send commit message");
bb598c3b 1277 goto remove_sta;
872b7545 1278 }
9249afc8
JM
1279 sae_set_state(sta, SAE_COMMITTED,
1280 "Sent Commit (anti-clogging token case in mesh)");
f3b8ad4d
BC
1281 sta->sae->sync = 0;
1282 sae_set_retransmit_timer(hapd, sta);
872b7545
MH
1283 return;
1284 }
1285
dad01292
JM
1286 if ((hapd->conf->mesh & MESH_ENABLED) &&
1287 status_code ==
1288 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
1289 sta->sae->tmp) {
1290 wpa_printf(MSG_DEBUG,
1291 "SAE: Peer did not accept our SAE group");
1292 sae_pick_next_group(hapd, sta);
1293 goto remove_sta;
1294 }
1295
a5dc2a5c 1296 if (!sae_status_success(hapd, status_code))
bb598c3b 1297 goto remove_sta;
afa2ffb4 1298
3a8dd390
JM
1299 if (!(hapd->conf->mesh & MESH_ENABLED) &&
1300 sta->sae->state == SAE_COMMITTED) {
1301 /* This is needed in the infrastructure BSS case to
1302 * address a sequence where a STA entry may remain in
1303 * hostapd across two attempts to do SAE authentication
1304 * by the same STA. The second attempt may end up trying
1305 * to use a different group and that would not be
1306 * allowed if we remain in Committed state with the
1307 * previously set parameters. */
f2143615
JM
1308 pos = mgmt->u.auth.variable;
1309 end = ((const u8 *) mgmt) + len;
1310 if (end - pos >= (int) sizeof(le16) &&
1311 sae_group_allowed(sta->sae, groups,
1312 WPA_GET_LE16(pos)) ==
1313 WLAN_STATUS_SUCCESS) {
1314 /* Do not waste resources deriving the same PWE
1315 * again since the same group is reused. */
1316 sae_set_state(sta, SAE_NOTHING,
1317 "Allow previous PWE to be reused");
1318 allow_reuse = 1;
1319 } else {
1320 sae_set_state(sta, SAE_NOTHING,
1321 "Clear existing state to allow restart");
1322 sae_clear_data(sta->sae);
1323 }
3a8dd390
JM
1324 }
1325
146f6c9a
JM
1326 resp = sae_parse_commit(sta->sae, mgmt->u.auth.variable,
1327 ((const u8 *) mgmt) + len -
d136c376 1328 mgmt->u.auth.variable, &token,
86f60848
JM
1329 &token_len, groups, status_code ==
1330 WLAN_STATUS_SAE_HASH_TO_ELEMENT);
6a58444d
JM
1331 if (resp == SAE_SILENTLY_DISCARD) {
1332 wpa_printf(MSG_DEBUG,
1333 "SAE: Drop commit message from " MACSTR " due to reflection attack",
1334 MAC2STR(sta->addr));
bb598c3b 1335 goto remove_sta;
6a58444d 1336 }
9be19d0b
JM
1337
1338 if (resp == WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER) {
1339 wpa_msg(hapd->msg_ctx, MSG_INFO,
1340 WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER
1341 MACSTR, MAC2STR(sta->addr));
1342 sae_clear_retransmit_timer(hapd, sta);
1343 sae_set_state(sta, SAE_NOTHING,
1344 "Unknown Password Identifier");
1345 goto remove_sta;
1346 }
1347
d136c376
JM
1348 if (token && check_sae_token(hapd, sta->addr, token, token_len)
1349 < 0) {
1350 wpa_printf(MSG_DEBUG, "SAE: Drop commit message with "
1351 "incorrect token from " MACSTR,
1352 MAC2STR(sta->addr));
bb598c3b
AB
1353 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1354 goto remove_sta;
d136c376
JM
1355 }
1356
e96da42b
BC
1357 if (resp != WLAN_STATUS_SUCCESS)
1358 goto reply;
1359
032c8264
JM
1360 if (sta->sae->tmp &&
1361 check_sae_rejected_groups(
c88e01e1 1362 hapd, sta->sae->tmp->peer_rejected_groups)) {
032c8264 1363 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
a889e9a7 1364 goto reply;
032c8264
JM
1365 }
1366
f2143615 1367 if (!token && use_sae_anti_clogging(hapd) && !allow_reuse) {
5e32fb01
JM
1368 int h2e = 0;
1369
e96da42b
BC
1370 wpa_printf(MSG_DEBUG,
1371 "SAE: Request anti-clogging token from "
1372 MACSTR, MAC2STR(sta->addr));
5e32fb01
JM
1373 if (sta->sae->tmp)
1374 h2e = sta->sae->tmp->h2e;
1375 if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT)
1376 h2e = 1;
a959a3b6 1377 data = auth_build_token_req(hapd, sta->sae->group,
5e32fb01 1378 sta->addr, h2e);
e96da42b 1379 resp = WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ;
872b7545 1380 if (hapd->conf->mesh & MESH_ENABLED)
9249afc8
JM
1381 sae_set_state(sta, SAE_NOTHING,
1382 "Request anti-clogging token case in mesh");
e96da42b 1383 goto reply;
750efe6e 1384 }
e96da42b 1385
f2143615 1386 resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction,
a5dc2a5c 1387 status_code, allow_reuse, &sta_removed);
c10347f2 1388 } else if (auth_transaction == 2) {
c10347f2
JM
1389 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1390 HOSTAPD_LEVEL_DEBUG,
9c951244
AK
1391 "SAE authentication (RX confirm, status=%u (%s))",
1392 status_code, status2str(status_code));
afa2ffb4 1393 if (status_code != WLAN_STATUS_SUCCESS)
bb598c3b 1394 goto remove_sta;
e96da42b
BC
1395 if (sta->sae->state >= SAE_CONFIRMED ||
1396 !(hapd->conf->mesh & MESH_ENABLED)) {
abcbd060
JM
1397 const u8 *var;
1398 size_t var_len;
1399 u16 peer_send_confirm;
1400
1401 var = mgmt->u.auth.variable;
1402 var_len = ((u8 *) mgmt) + len - mgmt->u.auth.variable;
1403 if (var_len < 2) {
1404 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1405 goto reply;
1406 }
1407
1408 peer_send_confirm = WPA_GET_LE16(var);
1409
1410 if (sta->sae->state == SAE_ACCEPTED &&
1411 (peer_send_confirm <= sta->sae->rc ||
1412 peer_send_confirm == 0xffff)) {
1413 wpa_printf(MSG_DEBUG,
1414 "SAE: Silently ignore unexpected Confirm from peer "
1415 MACSTR
1416 " (peer-send-confirm=%u Rc=%u)",
1417 MAC2STR(sta->addr),
1418 peer_send_confirm, sta->sae->rc);
1419 return;
1420 }
1421
1422 if (sae_check_confirm(sta->sae, var, var_len) < 0) {
750efe6e 1423 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
e96da42b 1424 goto reply;
b4fd3613 1425 }
abcbd060 1426 sta->sae->rc = peer_send_confirm;
21af6d15 1427 }
a5dc2a5c
JM
1428 resp = sae_sm_step(hapd, sta, mgmt->bssid, auth_transaction,
1429 status_code, 0, &sta_removed);
c10347f2
JM
1430 } else {
1431 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
1432 HOSTAPD_LEVEL_DEBUG,
9c951244
AK
1433 "unexpected SAE authentication transaction %u (status=%u (%s))",
1434 auth_transaction, status_code,
1435 status2str(status_code));
afa2ffb4 1436 if (status_code != WLAN_STATUS_SUCCESS)
bb598c3b 1437 goto remove_sta;
c10347f2
JM
1438 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
1439 }
1440
e96da42b 1441reply:
10cf866b 1442 if (!sta_removed && resp != WLAN_STATUS_SUCCESS) {
96d6dfa8
JM
1443 pos = mgmt->u.auth.variable;
1444 end = ((const u8 *) mgmt) + len;
1445
1446 /* Copy the Finite Cyclic Group field from the request if we
1447 * rejected it as unsupported group. */
1448 if (resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
1449 !data && end - pos >= 2)
1450 data = wpabuf_alloc_copy(pos, 2);
1451
4ffb0fef 1452 sae_sme_send_external_auth_status(hapd, sta, resp);
3912cbd8 1453 send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
e96da42b
BC
1454 auth_transaction, resp,
1455 data ? wpabuf_head(data) : (u8 *) "",
e7525a29 1456 data ? wpabuf_len(data) : 0, "auth-sae");
e96da42b 1457 }
bb598c3b
AB
1458
1459remove_sta:
10cf866b
JM
1460 if (!sta_removed && sta->added_unassoc &&
1461 (resp != WLAN_STATUS_SUCCESS ||
1462 status_code != WLAN_STATUS_SUCCESS)) {
bb598c3b
AB
1463 hostapd_drv_sta_remove(hapd, sta->addr);
1464 sta->added_unassoc = 0;
1465 }
21af6d15 1466 wpabuf_free(data);
c10347f2 1467}
a206e2a1
BC
1468
1469
1470/**
1471 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1472 * @hapd: BSS data for the device initiating the authentication
1473 * @sta: the peer to which commit authentication frame is sent
1474 *
1475 * This function implements Init event handling (IEEE Std 802.11-2012,
1476 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1477 * sta->sae structure should be initialized appropriately via a call to
1478 * sae_prepare_commit().
1479 */
1480int auth_sae_init_committed(struct hostapd_data *hapd, struct sta_info *sta)
1481{
1482 int ret;
1483
1484 if (!sta->sae || !sta->sae->tmp)
1485 return -1;
1486
1487 if (sta->sae->state != SAE_NOTHING)
1488 return -1;
1489
93a1e275 1490 ret = auth_sae_send_commit(hapd, sta, hapd->own_addr, 0, -1);
a206e2a1
BC
1491 if (ret)
1492 return -1;
1493
9249afc8 1494 sae_set_state(sta, SAE_COMMITTED, "Init and sent commit");
f3b8ad4d
BC
1495 sta->sae->sync = 0;
1496 sae_set_retransmit_timer(hapd, sta);
a206e2a1
BC
1497
1498 return 0;
1499}
1500
ff9f40ae
JM
1501
1502void auth_sae_process_commit(void *eloop_ctx, void *user_ctx)
1503{
1504 struct hostapd_data *hapd = eloop_ctx;
1505 struct hostapd_sae_commit_queue *q;
1506 unsigned int queue_len;
1507
1508 q = dl_list_first(&hapd->sae_commit_queue,
1509 struct hostapd_sae_commit_queue, list);
1510 if (!q)
1511 return;
1512 wpa_printf(MSG_DEBUG,
5e3a759c 1513 "SAE: Process next available message from queue");
ff9f40ae
JM
1514 dl_list_del(&q->list);
1515 handle_auth(hapd, (const struct ieee80211_mgmt *) q->msg, q->len,
1516 q->rssi, 1);
1517 os_free(q);
1518
1519 if (eloop_is_timeout_registered(auth_sae_process_commit, hapd, NULL))
1520 return;
1521 queue_len = dl_list_len(&hapd->sae_commit_queue);
ff5f54e1 1522 eloop_register_timeout(0, queue_len * 10000, auth_sae_process_commit,
ff9f40ae
JM
1523 hapd, NULL);
1524}
1525
1526
5e3a759c
JM
1527static void auth_sae_queue(struct hostapd_data *hapd,
1528 const struct ieee80211_mgmt *mgmt, size_t len,
1529 int rssi)
ff9f40ae 1530{
5e3a759c 1531 struct hostapd_sae_commit_queue *q, *q2;
ff9f40ae 1532 unsigned int queue_len;
5e3a759c 1533 const struct ieee80211_mgmt *mgmt2;
ff9f40ae
JM
1534
1535 queue_len = dl_list_len(&hapd->sae_commit_queue);
1536 if (queue_len >= 15) {
1537 wpa_printf(MSG_DEBUG,
5e3a759c 1538 "SAE: No more room in message queue - drop the new frame from "
ff9f40ae
JM
1539 MACSTR, MAC2STR(mgmt->sa));
1540 return;
1541 }
1542
5e3a759c
JM
1543 wpa_printf(MSG_DEBUG, "SAE: Queue Authentication message from "
1544 MACSTR " for processing (queue_len %u)", MAC2STR(mgmt->sa),
1545 queue_len);
ff9f40ae
JM
1546 q = os_zalloc(sizeof(*q) + len);
1547 if (!q)
1548 return;
1549 q->rssi = rssi;
1550 q->len = len;
1551 os_memcpy(q->msg, mgmt, len);
5e3a759c
JM
1552
1553 /* Check whether there is already a queued Authentication frame from the
1554 * same station with the same transaction number and if so, replace that
1555 * queue entry with the new one. This avoids issues with a peer that
1556 * sends multiple times (e.g., due to frequent SAE retries). There is no
1557 * point in us trying to process the old attempts after a new one has
1558 * obsoleted them. */
1559 dl_list_for_each(q2, &hapd->sae_commit_queue,
1560 struct hostapd_sae_commit_queue, list) {
1561 mgmt2 = (const struct ieee80211_mgmt *) q2->msg;
1562 if (os_memcmp(mgmt->sa, mgmt2->sa, ETH_ALEN) == 0 &&
1563 mgmt->u.auth.auth_transaction ==
1564 mgmt2->u.auth.auth_transaction) {
1565 wpa_printf(MSG_DEBUG,
1566 "SAE: Replace queued message from same STA with same transaction number");
1567 dl_list_add(&q2->list, &q->list);
1568 dl_list_del(&q2->list);
1569 os_free(q2);
1570 goto queued;
1571 }
1572 }
1573
1574 /* No pending identical entry, so add to the end of the queue */
ff9f40ae 1575 dl_list_add_tail(&hapd->sae_commit_queue, &q->list);
5e3a759c
JM
1576
1577queued:
ff9f40ae
JM
1578 if (eloop_is_timeout_registered(auth_sae_process_commit, hapd, NULL))
1579 return;
ff5f54e1 1580 eloop_register_timeout(0, queue_len * 10000, auth_sae_process_commit,
ff9f40ae
JM
1581 hapd, NULL);
1582}
1583
5e3a759c
JM
1584
1585static int auth_sae_queued_addr(struct hostapd_data *hapd, const u8 *addr)
1586{
1587 struct hostapd_sae_commit_queue *q;
1588 const struct ieee80211_mgmt *mgmt;
1589
1590 dl_list_for_each(q, &hapd->sae_commit_queue,
1591 struct hostapd_sae_commit_queue, list) {
1592 mgmt = (const struct ieee80211_mgmt *) q->msg;
1593 if (os_memcmp(addr, mgmt->sa, ETH_ALEN) == 0)
1594 return 1;
1595 }
1596
1597 return 0;
1598}
1599
c10347f2
JM
1600#endif /* CONFIG_SAE */
1601
1602
ffb62f22
JM
1603static u16 wpa_res_to_status_code(int res)
1604{
1605 if (res == WPA_INVALID_GROUP)
1606 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID;
1607 if (res == WPA_INVALID_PAIRWISE)
1608 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID;
1609 if (res == WPA_INVALID_AKMP)
1610 return WLAN_STATUS_AKMP_NOT_VALID;
1611 if (res == WPA_ALLOC_FAIL)
1612 return WLAN_STATUS_UNSPECIFIED_FAILURE;
ffb62f22
JM
1613 if (res == WPA_MGMT_FRAME_PROTECTION_VIOLATION)
1614 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
1615 if (res == WPA_INVALID_MGMT_GROUP_CIPHER)
feba5848 1616 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
ffb62f22
JM
1617 if (res == WPA_INVALID_MDIE)
1618 return WLAN_STATUS_INVALID_MDIE;
567da5bb
JM
1619 if (res == WPA_INVALID_PMKID)
1620 return WLAN_STATUS_INVALID_PMKID;
ffb62f22
JM
1621 if (res != WPA_IE_OK)
1622 return WLAN_STATUS_INVALID_IE;
1623 return WLAN_STATUS_SUCCESS;
1624}
1625
1626
c4fd6d8a
JM
1627#ifdef CONFIG_FILS
1628
1629static void handle_auth_fils_finish(struct hostapd_data *hapd,
1630 struct sta_info *sta, u16 resp,
5cee22ca
JM
1631 struct wpabuf *data, int pub);
1632
1633void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
1634 const u8 *pos, size_t len, u16 auth_alg,
1635 u16 auth_transaction, u16 status_code,
1636 void (*cb)(struct hostapd_data *hapd,
1637 struct sta_info *sta, u16 resp,
1638 struct wpabuf *data, int pub))
c4fd6d8a
JM
1639{
1640 u16 resp = WLAN_STATUS_SUCCESS;
b8a3453a 1641 const u8 *end;
c4fd6d8a
JM
1642 struct ieee802_11_elems elems;
1643 int res;
1644 struct wpa_ie_data rsn;
1645 struct rsn_pmksa_cache_entry *pmksa = NULL;
1646
1647 if (auth_transaction != 1 || status_code != WLAN_STATUS_SUCCESS)
1648 return;
1649
b8a3453a 1650 end = pos + len;
c4fd6d8a
JM
1651
1652 wpa_hexdump(MSG_DEBUG, "FILS: Authentication frame fields",
1653 pos, end - pos);
1654
1764559e
JM
1655 /* TODO: FILS PK */
1656#ifdef CONFIG_FILS_SK_PFS
1657 if (auth_alg == WLAN_AUTH_FILS_SK_PFS) {
1658 u16 group;
1659 struct wpabuf *pub;
1660 size_t elem_len;
1661
1662 /* Using FILS PFS */
1663
1664 /* Finite Cyclic Group */
1665 if (end - pos < 2) {
1666 wpa_printf(MSG_DEBUG,
1667 "FILS: No room for Finite Cyclic Group");
1668 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1669 goto fail;
1670 }
1671 group = WPA_GET_LE16(pos);
1672 pos += 2;
1673 if (group != hapd->conf->fils_dh_group) {
1674 wpa_printf(MSG_DEBUG,
1675 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1676 group, hapd->conf->fils_dh_group);
1677 resp = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
1678 goto fail;
1679 }
1680
1681 crypto_ecdh_deinit(sta->fils_ecdh);
1682 sta->fils_ecdh = crypto_ecdh_init(group);
1683 if (!sta->fils_ecdh) {
1684 wpa_printf(MSG_INFO,
1685 "FILS: Could not initialize ECDH with group %d",
1686 group);
1687 resp = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
1688 goto fail;
1689 }
1690
1691 pub = crypto_ecdh_get_pubkey(sta->fils_ecdh, 1);
1692 if (!pub) {
1693 wpa_printf(MSG_DEBUG,
1694 "FILS: Failed to derive ECDH public key");
1695 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1696 goto fail;
1697 }
1698 elem_len = wpabuf_len(pub);
1699 wpabuf_free(pub);
1700
1701 /* Element */
1702 if ((size_t) (end - pos) < elem_len) {
1703 wpa_printf(MSG_DEBUG, "FILS: No room for Element");
1704 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1705 goto fail;
1706 }
1707
80ddf5d9
JM
1708 wpabuf_free(sta->fils_g_sta);
1709 sta->fils_g_sta = wpabuf_alloc_copy(pos, elem_len);
1764559e
JM
1710 wpabuf_clear_free(sta->fils_dh_ss);
1711 sta->fils_dh_ss = crypto_ecdh_set_peerkey(sta->fils_ecdh, 1,
1712 pos, elem_len);
1713 if (!sta->fils_dh_ss) {
1714 wpa_printf(MSG_DEBUG, "FILS: ECDH operation failed");
1715 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1716 goto fail;
1717 }
1718 wpa_hexdump_buf_key(MSG_DEBUG, "FILS: DH_SS", sta->fils_dh_ss);
1719 pos += elem_len;
1720 } else {
1721 crypto_ecdh_deinit(sta->fils_ecdh);
1722 sta->fils_ecdh = NULL;
1723 wpabuf_clear_free(sta->fils_dh_ss);
1724 sta->fils_dh_ss = NULL;
1725 }
1726#endif /* CONFIG_FILS_SK_PFS */
c4fd6d8a
JM
1727
1728 wpa_hexdump(MSG_DEBUG, "FILS: Remaining IEs", pos, end - pos);
1729 if (ieee802_11_parse_elems(pos, end - pos, &elems, 1) == ParseFailed) {
1730 wpa_printf(MSG_DEBUG, "FILS: Could not parse elements");
1731 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1732 goto fail;
1733 }
1734
1735 /* RSNE */
1736 wpa_hexdump(MSG_DEBUG, "FILS: RSN element",
1737 elems.rsn_ie, elems.rsn_ie_len);
1738 if (!elems.rsn_ie ||
1739 wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
1740 &rsn) < 0) {
1741 wpa_printf(MSG_DEBUG, "FILS: No valid RSN element");
1742 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1743 goto fail;
1744 }
1745
1746 if (!sta->wpa_sm)
1747 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr,
1748 NULL);
1749 if (!sta->wpa_sm) {
1750 wpa_printf(MSG_DEBUG,
1751 "FILS: Failed to initialize RSN state machine");
1752 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1753 goto fail;
1754 }
1755
1756 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
2c129a1b 1757 hapd->iface->freq,
c4fd6d8a 1758 elems.rsn_ie - 2, elems.rsn_ie_len + 2,
d3516cad
JM
1759 elems.rsnxe ? elems.rsnxe - 2 : NULL,
1760 elems.rsnxe ? elems.rsnxe_len + 2 : 0,
09368515 1761 elems.mdie, elems.mdie_len, NULL, 0);
c4fd6d8a
JM
1762 resp = wpa_res_to_status_code(res);
1763 if (resp != WLAN_STATUS_SUCCESS)
1764 goto fail;
1765
c4fd6d8a
JM
1766 if (!elems.fils_nonce) {
1767 wpa_printf(MSG_DEBUG, "FILS: No FILS Nonce field");
1768 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1769 goto fail;
1770 }
1771 wpa_hexdump(MSG_DEBUG, "FILS: SNonce", elems.fils_nonce,
1772 FILS_NONCE_LEN);
1773 os_memcpy(sta->fils_snonce, elems.fils_nonce, FILS_NONCE_LEN);
1774
1775 /* PMKID List */
1776 if (rsn.pmkid && rsn.num_pmkid > 0) {
1777 u8 num;
1778 const u8 *pmkid;
1779
1780 wpa_hexdump(MSG_DEBUG, "FILS: PMKID List",
1781 rsn.pmkid, rsn.num_pmkid * PMKID_LEN);
1782
1783 pmkid = rsn.pmkid;
1784 num = rsn.num_pmkid;
1785 while (num) {
1786 wpa_hexdump(MSG_DEBUG, "FILS: PMKID", pmkid, PMKID_LEN);
1787 pmksa = wpa_auth_pmksa_get(hapd->wpa_auth, sta->addr,
1788 pmkid);
1789 if (pmksa)
1790 break;
7eace378
JM
1791 pmksa = wpa_auth_pmksa_get_fils_cache_id(hapd->wpa_auth,
1792 sta->addr,
1793 pmkid);
1794 if (pmksa)
1795 break;
c4fd6d8a
JM
1796 pmkid += PMKID_LEN;
1797 num--;
1798 }
1799 }
1800 if (pmksa && wpa_auth_sta_key_mgmt(sta->wpa_sm) != pmksa->akmp) {
1801 wpa_printf(MSG_DEBUG,
1802 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1803 wpa_auth_sta_key_mgmt(sta->wpa_sm), pmksa->akmp);
1804 pmksa = NULL;
1805 }
1806 if (pmksa)
1807 wpa_printf(MSG_DEBUG, "FILS: Found matching PMKSA cache entry");
1808
1809 /* FILS Session */
1810 if (!elems.fils_session) {
1811 wpa_printf(MSG_DEBUG, "FILS: No FILS Session element");
1812 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1813 goto fail;
1814 }
1815 wpa_hexdump(MSG_DEBUG, "FILS: FILS Session", elems.fils_session,
1816 FILS_SESSION_LEN);
1817 os_memcpy(sta->fils_session, elems.fils_session, FILS_SESSION_LEN);
1818
1819 /* FILS Wrapped Data */
1820 if (elems.fils_wrapped_data) {
1821 wpa_hexdump(MSG_DEBUG, "FILS: Wrapped Data",
1822 elems.fils_wrapped_data,
1823 elems.fils_wrapped_data_len);
1824 if (!pmksa) {
1825#ifndef CONFIG_NO_RADIUS
1826 if (!sta->eapol_sm) {
1827 sta->eapol_sm =
1828 ieee802_1x_alloc_eapol_sm(hapd, sta);
1829 }
1830 wpa_printf(MSG_DEBUG,
bfe44833 1831 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
c4fd6d8a
JM
1832 ieee802_1x_encapsulate_radius(
1833 hapd, sta, elems.fils_wrapped_data,
1834 elems.fils_wrapped_data_len);
5cee22ca 1835 sta->fils_pending_cb = cb;
c4fd6d8a
JM
1836 wpa_printf(MSG_DEBUG,
1837 "FILS: Will send Authentication frame once the response from authentication server is available");
1838 sta->flags |= WLAN_STA_PENDING_FILS_ERP;
b3e567c8
JM
1839 /* Calculate pending PMKID here so that we do not need
1840 * to maintain a copy of the EAP-Initiate/Reauth
1841 * message. */
1842 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta->wpa_sm),
1843 elems.fils_wrapped_data,
1844 elems.fils_wrapped_data_len,
1845 sta->fils_erp_pmkid) == 0)
1846 sta->fils_erp_pmkid_set = 1;
c4fd6d8a
JM
1847 return;
1848#else /* CONFIG_NO_RADIUS */
1849 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1850 goto fail;
1851#endif /* CONFIG_NO_RADIUS */
1852 }
1853 }
1854
1855fail:
5cee22ca
JM
1856 if (cb) {
1857 struct wpabuf *data;
1858 int pub = 0;
1859
1860 data = prepare_auth_resp_fils(hapd, sta, &resp, pmksa, NULL,
1861 NULL, 0, &pub);
1862 if (!data) {
1863 wpa_printf(MSG_DEBUG,
1864 "%s: prepare_auth_resp_fils() returned failure",
1865 __func__);
1866 }
1867
1868 cb(hapd, sta, resp, data, pub);
1869 }
c4fd6d8a
JM
1870}
1871
1872
5e5f8c81
JM
1873static struct wpabuf *
1874prepare_auth_resp_fils(struct hostapd_data *hapd,
1875 struct sta_info *sta, u16 *resp,
1876 struct rsn_pmksa_cache_entry *pmksa,
1877 struct wpabuf *erp_resp,
1878 const u8 *msk, size_t msk_len,
1879 int *is_pub)
c4fd6d8a
JM
1880{
1881 u8 fils_nonce[FILS_NONCE_LEN];
1882 size_t ielen;
1883 struct wpabuf *data = NULL;
1884 const u8 *ie;
1885 u8 *ie_buf = NULL;
1886 const u8 *pmk = NULL;
1887 size_t pmk_len = 0;
fcd3d6ce 1888 u8 pmk_buf[PMK_LEN_MAX];
1764559e 1889 struct wpabuf *pub = NULL;
c4fd6d8a 1890
5e5f8c81 1891 if (*resp != WLAN_STATUS_SUCCESS)
c4fd6d8a
JM
1892 goto fail;
1893
1894 ie = wpa_auth_get_wpa_ie(hapd->wpa_auth, &ielen);
1895 if (!ie) {
5e5f8c81 1896 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1897 goto fail;
1898 }
5e5f8c81 1899
c4fd6d8a
JM
1900 if (pmksa) {
1901 /* Add PMKID of the selected PMKSA into RSNE */
1902 ie_buf = os_malloc(ielen + 2 + 2 + PMKID_LEN);
1903 if (!ie_buf) {
5e5f8c81 1904 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1905 goto fail;
1906 }
5e5f8c81 1907
c4fd6d8a
JM
1908 os_memcpy(ie_buf, ie, ielen);
1909 if (wpa_insert_pmkid(ie_buf, &ielen, pmksa->pmkid) < 0) {
5e5f8c81 1910 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1911 goto fail;
1912 }
1913 ie = ie_buf;
1914 }
1915
1916 if (random_get_bytes(fils_nonce, FILS_NONCE_LEN) < 0) {
5e5f8c81 1917 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1918 goto fail;
1919 }
1920 wpa_hexdump(MSG_DEBUG, "RSN: Generated FILS Nonce",
1921 fils_nonce, FILS_NONCE_LEN);
1922
1764559e
JM
1923#ifdef CONFIG_FILS_SK_PFS
1924 if (sta->fils_dh_ss && sta->fils_ecdh) {
1925 pub = crypto_ecdh_get_pubkey(sta->fils_ecdh, 1);
1926 if (!pub) {
5e5f8c81 1927 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
1764559e
JM
1928 goto fail;
1929 }
1930 }
1931#endif /* CONFIG_FILS_SK_PFS */
1932
1933 data = wpabuf_alloc(1000 + ielen + (pub ? wpabuf_len(pub) : 0));
c4fd6d8a 1934 if (!data) {
5e5f8c81 1935 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
1936 goto fail;
1937 }
1938
1764559e
JM
1939 /* TODO: FILS PK */
1940#ifdef CONFIG_FILS_SK_PFS
1941 if (pub) {
1942 /* Finite Cyclic Group */
1943 wpabuf_put_le16(data, hapd->conf->fils_dh_group);
1944
1945 /* Element */
1946 wpabuf_put_buf(data, pub);
1947 }
1948#endif /* CONFIG_FILS_SK_PFS */
c4fd6d8a
JM
1949
1950 /* RSNE */
1951 wpabuf_put_data(data, ie, ielen);
1952
5db997e3
JM
1953 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1954
1955#ifdef CONFIG_IEEE80211R_AP
1956 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta->wpa_sm))) {
1957 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1958 int res;
a7968ea5
JM
1959 int use_sha384 = wpa_key_mgmt_sha384(
1960 wpa_auth_sta_key_mgmt(sta->wpa_sm));
5db997e3 1961
a7968ea5
JM
1962 res = wpa_auth_write_fte(hapd->wpa_auth, use_sha384,
1963 wpabuf_put(data, 0),
5db997e3
JM
1964 wpabuf_tailroom(data));
1965 if (res < 0) {
5e5f8c81 1966 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5db997e3
JM
1967 goto fail;
1968 }
1969 wpabuf_put(data, res);
1970 }
1971#endif /* CONFIG_IEEE80211R_AP */
c4fd6d8a
JM
1972
1973 /* FILS Nonce */
1974 wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
1975 wpabuf_put_u8(data, 1 + FILS_NONCE_LEN); /* Length */
1976 /* Element ID Extension */
1977 wpabuf_put_u8(data, WLAN_EID_EXT_FILS_NONCE);
1978 wpabuf_put_data(data, fils_nonce, FILS_NONCE_LEN);
1979
1980 /* FILS Session */
1981 wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
1982 wpabuf_put_u8(data, 1 + FILS_SESSION_LEN); /* Length */
1983 /* Element ID Extension */
1984 wpabuf_put_u8(data, WLAN_EID_EXT_FILS_SESSION);
1985 wpabuf_put_data(data, sta->fils_session, FILS_SESSION_LEN);
1986
1987 /* FILS Wrapped Data */
1988 if (!pmksa && erp_resp) {
1989 wpabuf_put_u8(data, WLAN_EID_EXTENSION); /* Element ID */
1990 wpabuf_put_u8(data, 1 + wpabuf_len(erp_resp)); /* Length */
1991 /* Element ID Extension */
1992 wpabuf_put_u8(data, WLAN_EID_EXT_FILS_WRAPPED_DATA);
1993 wpabuf_put_buf(data, erp_resp);
1994
fcd3d6ce
JM
1995 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta->wpa_sm),
1996 msk, msk_len, sta->fils_snonce, fils_nonce,
1764559e
JM
1997 sta->fils_dh_ss ?
1998 wpabuf_head(sta->fils_dh_ss) : NULL,
1999 sta->fils_dh_ss ?
2000 wpabuf_len(sta->fils_dh_ss) : 0,
2001 pmk_buf, &pmk_len)) {
fcd3d6ce 2002 wpa_printf(MSG_DEBUG, "FILS: Failed to derive PMK");
5e5f8c81 2003 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
fcd3d6ce
JM
2004 wpabuf_free(data);
2005 data = NULL;
2006 goto fail;
2007 }
2008 pmk = pmk_buf;
b3e567c8 2009
4cada9dc
JM
2010 /* Don't use DHss in PTK derivation if PMKSA caching is not
2011 * used. */
2012 wpabuf_clear_free(sta->fils_dh_ss);
2013 sta->fils_dh_ss = NULL;
2014
b3e567c8
JM
2015 if (sta->fils_erp_pmkid_set) {
2016 /* TODO: get PMKLifetime from WPA parameters */
2017 unsigned int dot11RSNAConfigPMKLifetime = 43200;
13f118dc
MB
2018 int session_timeout;
2019
2020 session_timeout = dot11RSNAConfigPMKLifetime;
2021 if (sta->session_timeout_set) {
2022 struct os_reltime now, diff;
2023
2024 os_get_reltime(&now);
2025 os_reltime_sub(&sta->session_timeout, &now,
2026 &diff);
2027 session_timeout = diff.sec;
2028 }
b3e567c8
JM
2029
2030 sta->fils_erp_pmkid_set = 0;
a40bd06e
JM
2031 wpa_auth_add_fils_pmk_pmkid(sta->wpa_sm, pmk, pmk_len,
2032 sta->fils_erp_pmkid);
aabbdb81
JM
2033 if (!hapd->conf->disable_pmksa_caching &&
2034 wpa_auth_pmksa_add2(
b3e567c8
JM
2035 hapd->wpa_auth, sta->addr,
2036 pmk, pmk_len,
2037 sta->fils_erp_pmkid,
13f118dc 2038 session_timeout,
b3e567c8
JM
2039 wpa_auth_sta_key_mgmt(sta->wpa_sm)) < 0) {
2040 wpa_printf(MSG_ERROR,
2041 "FILS: Failed to add PMKSA cache entry based on ERP");
2042 }
2043 }
c4fd6d8a
JM
2044 } else if (pmksa) {
2045 pmk = pmksa->pmk;
2046 pmk_len = pmksa->pmk_len;
2047 }
2048
2049 if (!pmk) {
2050 wpa_printf(MSG_DEBUG, "FILS: No PMK available");
5e5f8c81 2051 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
2052 wpabuf_free(data);
2053 data = NULL;
2054 goto fail;
2055 }
2056
2057 if (fils_auth_pmk_to_ptk(sta->wpa_sm, pmk, pmk_len,
80ddf5d9 2058 sta->fils_snonce, fils_nonce,
4cada9dc
JM
2059 sta->fils_dh_ss ?
2060 wpabuf_head(sta->fils_dh_ss) : NULL,
2061 sta->fils_dh_ss ?
2062 wpabuf_len(sta->fils_dh_ss) : 0,
80ddf5d9 2063 sta->fils_g_sta, pub) < 0) {
5e5f8c81 2064 *resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
c4fd6d8a
JM
2065 wpabuf_free(data);
2066 data = NULL;
2067 goto fail;
2068 }
2069
2070fail:
5e5f8c81
JM
2071 if (is_pub)
2072 *is_pub = pub != NULL;
2073 os_free(ie_buf);
2074 wpabuf_free(pub);
2075 wpabuf_clear_free(sta->fils_dh_ss);
2076 sta->fils_dh_ss = NULL;
2077#ifdef CONFIG_FILS_SK_PFS
2078 crypto_ecdh_deinit(sta->fils_ecdh);
2079 sta->fils_ecdh = NULL;
2080#endif /* CONFIG_FILS_SK_PFS */
2081 return data;
2082}
2083
2084
2085static void handle_auth_fils_finish(struct hostapd_data *hapd,
2086 struct sta_info *sta, u16 resp,
5cee22ca 2087 struct wpabuf *data, int pub)
5e5f8c81 2088{
5e5f8c81 2089 u16 auth_alg;
5e5f8c81 2090
1764559e
JM
2091 auth_alg = (pub ||
2092 resp == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) ?
2093 WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
3912cbd8 2094 send_auth_reply(hapd, sta, sta->addr, hapd->own_addr, auth_alg, 2, resp,
c4fd6d8a 2095 data ? wpabuf_head(data) : (u8 *) "",
e7525a29 2096 data ? wpabuf_len(data) : 0, "auth-fils-finish");
c4fd6d8a
JM
2097 wpabuf_free(data);
2098
2099 if (resp == WLAN_STATUS_SUCCESS) {
2100 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2101 HOSTAPD_LEVEL_DEBUG,
2102 "authentication OK (FILS)");
2103 sta->flags |= WLAN_STA_AUTH;
2104 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
1764559e 2105 sta->auth_alg = pub ? WLAN_AUTH_FILS_SK_PFS : WLAN_AUTH_FILS_SK;
c4fd6d8a
JM
2106 mlme_authenticate_indication(hapd, sta);
2107 }
c4fd6d8a
JM
2108}
2109
2110
2111void ieee802_11_finish_fils_auth(struct hostapd_data *hapd,
2112 struct sta_info *sta, int success,
2113 struct wpabuf *erp_resp,
2114 const u8 *msk, size_t msk_len)
2115{
5cee22ca
JM
2116 struct wpabuf *data;
2117 int pub = 0;
2118 u16 resp;
2119
c4fd6d8a 2120 sta->flags &= ~WLAN_STA_PENDING_FILS_ERP;
5cee22ca
JM
2121
2122 if (!sta->fils_pending_cb)
2123 return;
2124 resp = success ? WLAN_STATUS_SUCCESS : WLAN_STATUS_UNSPECIFIED_FAILURE;
2125 data = prepare_auth_resp_fils(hapd, sta, &resp, NULL, erp_resp,
2126 msk, msk_len, &pub);
2127 if (!data) {
2128 wpa_printf(MSG_DEBUG,
2129 "%s: prepare_auth_resp_fils() returned failure",
2130 __func__);
2131 }
2132 sta->fils_pending_cb(hapd, sta, resp, data, pub);
c4fd6d8a
JM
2133}
2134
2135#endif /* CONFIG_FILS */
2136
2137
b0621b08
JM
2138static int ieee802_11_allowed_address(struct hostapd_data *hapd, const u8 *addr,
2139 const u8 *msg, size_t len,
2140 struct radius_sta *info)
53d17144
DL
2141{
2142 int res;
2143
b0621b08 2144 res = hostapd_allowed_address(hapd, addr, msg, len, info, 0);
53d17144
DL
2145
2146 if (res == HOSTAPD_ACL_REJECT) {
b0621b08
JM
2147 wpa_printf(MSG_DEBUG, "Station " MACSTR
2148 " not allowed to authenticate",
2149 MAC2STR(addr));
53d17144
DL
2150 return HOSTAPD_ACL_REJECT;
2151 }
2152
2153 if (res == HOSTAPD_ACL_PENDING) {
2154 wpa_printf(MSG_DEBUG, "Authentication frame from " MACSTR
2155 " waiting for an external authentication",
2156 MAC2STR(addr));
2157 /* Authentication code will re-send the authentication frame
2158 * after it has received (and cached) information from the
2159 * external source. */
2160 return HOSTAPD_ACL_PENDING;
2161 }
2162
2163 return res;
2164}
2165
2166
2167static int
2168ieee802_11_set_radius_info(struct hostapd_data *hapd, struct sta_info *sta,
29024efd 2169 int res, struct radius_sta *info)
53d17144 2170{
29024efd
MB
2171 u32 session_timeout = info->session_timeout;
2172 u32 acct_interim_interval = info->acct_interim_interval;
2173 struct vlan_description *vlan_id = &info->vlan_id;
96368172
MB
2174 struct hostapd_sta_wpa_psk_short *psk = info->psk;
2175 char *identity = info->identity;
2176 char *radius_cui = info->radius_cui;
29024efd 2177
53d17144
DL
2178 if (vlan_id->notempty &&
2179 !hostapd_vlan_valid(hapd->conf->vlan, vlan_id)) {
2180 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
2181 HOSTAPD_LEVEL_INFO,
2182 "Invalid VLAN %d%s received from RADIUS server",
2183 vlan_id->untagged,
2184 vlan_id->tagged[0] ? "+" : "");
2185 return -1;
2186 }
2187 if (ap_sta_set_vlan(hapd, sta, vlan_id) < 0)
2188 return -1;
2189 if (sta->vlan_id)
2190 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_RADIUS,
2191 HOSTAPD_LEVEL_INFO, "VLAN ID %d", sta->vlan_id);
2192
2193 hostapd_free_psk_list(sta->psk);
96368172
MB
2194 if (hapd->conf->wpa_psk_radius != PSK_RADIUS_IGNORED)
2195 hostapd_copy_psk_list(&sta->psk, psk);
2196 else
53d17144 2197 sta->psk = NULL;
53d17144 2198
17a8a989 2199 os_free(sta->identity);
96368172
MB
2200 if (identity)
2201 sta->identity = os_strdup(identity);
2202 else
2203 sta->identity = NULL;
17a8a989
MB
2204
2205 os_free(sta->radius_cui);
96368172
MB
2206 if (radius_cui)
2207 sta->radius_cui = os_strdup(radius_cui);
2208 else
2209 sta->radius_cui = NULL;
53d17144
DL
2210
2211 if (hapd->conf->acct_interim_interval == 0 && acct_interim_interval)
2212 sta->acct_interim_interval = acct_interim_interval;
13f118dc
MB
2213 if (res == HOSTAPD_ACL_ACCEPT_TIMEOUT) {
2214 sta->session_timeout_set = 1;
2215 os_get_reltime(&sta->session_timeout);
2216 sta->session_timeout.sec += session_timeout;
53d17144 2217 ap_sta_session_timeout(hapd, sta, session_timeout);
13f118dc
MB
2218 } else {
2219 sta->session_timeout_set = 0;
53d17144 2220 ap_sta_no_session_timeout(hapd, sta);
13f118dc 2221 }
53d17144
DL
2222
2223 return 0;
2224}
2225
2226
b57e086c 2227static void handle_auth(struct hostapd_data *hapd,
2ea1fce3 2228 const struct ieee80211_mgmt *mgmt, size_t len,
ff9f40ae 2229 int rssi, int from_queue)
6fc6879b
JM
2230{
2231 u16 auth_alg, auth_transaction, status_code;
2232 u16 resp = WLAN_STATUS_SUCCESS;
2233 struct sta_info *sta = NULL;
bb598c3b 2234 int res, reply_res;
6fc6879b 2235 u16 fc;
b57e086c 2236 const u8 *challenge = NULL;
6fc6879b
JM
2237 u8 resp_ies[2 + WLAN_AUTH_CHALLENGE_LEN];
2238 size_t resp_ies_len = 0;
38cb0a2d 2239 u16 seq_ctrl;
29024efd
MB
2240 struct radius_sta rad_info;
2241
6fc6879b 2242 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
61323e70
JM
2243 wpa_printf(MSG_INFO, "handle_auth - too short payload (len=%lu)",
2244 (unsigned long) len);
6fc6879b
JM
2245 return;
2246 }
2247
c2aff6b1 2248#ifdef CONFIG_TESTING_OPTIONS
06df2aa6 2249 if (hapd->iconf->ignore_auth_probability > 0.0 &&
c2aff6b1
JB
2250 drand48() < hapd->iconf->ignore_auth_probability) {
2251 wpa_printf(MSG_INFO,
2252 "TESTING: ignoring auth frame from " MACSTR,
2253 MAC2STR(mgmt->sa));
2254 return;
2255 }
2256#endif /* CONFIG_TESTING_OPTIONS */
2257
6fc6879b
JM
2258 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
2259 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
2260 status_code = le_to_host16(mgmt->u.auth.status_code);
2261 fc = le_to_host16(mgmt->frame_control);
38cb0a2d 2262 seq_ctrl = le_to_host16(mgmt->seq_ctrl);
6fc6879b
JM
2263
2264 if (len >= IEEE80211_HDRLEN + sizeof(mgmt->u.auth) +
2265 2 + WLAN_AUTH_CHALLENGE_LEN &&
2266 mgmt->u.auth.variable[0] == WLAN_EID_CHALLENGE &&
2267 mgmt->u.auth.variable[1] == WLAN_AUTH_CHALLENGE_LEN)
2268 challenge = &mgmt->u.auth.variable[2];
2269
2270 wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR " auth_alg=%d "
38cb0a2d 2271 "auth_transaction=%d status_code=%d wep=%d%s "
ff9f40ae 2272 "seq_ctrl=0x%x%s%s",
6fc6879b
JM
2273 MAC2STR(mgmt->sa), auth_alg, auth_transaction,
2274 status_code, !!(fc & WLAN_FC_ISWEP),
38cb0a2d 2275 challenge ? " challenge" : "",
ff9f40ae
JM
2276 seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "",
2277 from_queue ? " (from queue)" : "");
6fc6879b 2278
7cb53ded
JM
2279#ifdef CONFIG_NO_RC4
2280 if (auth_alg == WLAN_AUTH_SHARED_KEY) {
2281 wpa_printf(MSG_INFO,
2282 "Unsupported authentication algorithm (%d)",
2283 auth_alg);
2284 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
2285 goto fail;
2286 }
2287#endif /* CONFIG_NO_RC4 */
2288
6fc6879b 2289 if (hapd->tkip_countermeasures) {
e2fc13d0
BG
2290 wpa_printf(MSG_DEBUG,
2291 "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
fe12ae77 2292 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
2293 goto fail;
2294 }
2295
2296 if (!(((hapd->conf->auth_algs & WPA_AUTH_ALG_OPEN) &&
2297 auth_alg == WLAN_AUTH_OPEN) ||
4ec1fd8e 2298#ifdef CONFIG_IEEE80211R_AP
0bf927a0 2299 (hapd->conf->wpa && wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt) &&
6fc6879b 2300 auth_alg == WLAN_AUTH_FT) ||
4ec1fd8e 2301#endif /* CONFIG_IEEE80211R_AP */
c10347f2
JM
2302#ifdef CONFIG_SAE
2303 (hapd->conf->wpa && wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
2304 auth_alg == WLAN_AUTH_SAE) ||
2305#endif /* CONFIG_SAE */
c4fd6d8a
JM
2306#ifdef CONFIG_FILS
2307 (hapd->conf->wpa && wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt) &&
2308 auth_alg == WLAN_AUTH_FILS_SK) ||
1764559e
JM
2309 (hapd->conf->wpa && wpa_key_mgmt_fils(hapd->conf->wpa_key_mgmt) &&
2310 hapd->conf->fils_dh_group &&
2311 auth_alg == WLAN_AUTH_FILS_SK_PFS) ||
c4fd6d8a 2312#endif /* CONFIG_FILS */
6fc6879b
JM
2313 ((hapd->conf->auth_algs & WPA_AUTH_ALG_SHARED) &&
2314 auth_alg == WLAN_AUTH_SHARED_KEY))) {
61323e70
JM
2315 wpa_printf(MSG_INFO, "Unsupported authentication algorithm (%d)",
2316 auth_alg);
6fc6879b
JM
2317 resp = WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
2318 goto fail;
2319 }
2320
c10347f2 2321 if (!(auth_transaction == 1 || auth_alg == WLAN_AUTH_SAE ||
6fc6879b 2322 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 3))) {
61323e70
JM
2323 wpa_printf(MSG_INFO, "Unknown authentication transaction number (%d)",
2324 auth_transaction);
6fc6879b
JM
2325 resp = WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION;
2326 goto fail;
2327 }
2328
2329 if (os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
61323e70
JM
2330 wpa_printf(MSG_INFO, "Station " MACSTR " not allowed to authenticate",
2331 MAC2STR(mgmt->sa));
6fc6879b
JM
2332 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2333 goto fail;
2334 }
2335
0e2412d0
JM
2336 if (hapd->conf->no_auth_if_seen_on) {
2337 struct hostapd_data *other;
2338
2339 other = sta_track_seen_on(hapd->iface, mgmt->sa,
2340 hapd->conf->no_auth_if_seen_on);
2341 if (other) {
2342 u8 *pos;
2343 u32 info;
2344 u8 op_class, channel, phytype;
2345
2346 wpa_printf(MSG_DEBUG, "%s: Reject authentication from "
2347 MACSTR " since STA has been seen on %s",
2348 hapd->conf->iface, MAC2STR(mgmt->sa),
2349 hapd->conf->no_auth_if_seen_on);
2350
2351 resp = WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION;
2352 pos = &resp_ies[0];
2353 *pos++ = WLAN_EID_NEIGHBOR_REPORT;
2354 *pos++ = 13;
2355 os_memcpy(pos, other->own_addr, ETH_ALEN);
2356 pos += ETH_ALEN;
2357 info = 0; /* TODO: BSSID Information */
2358 WPA_PUT_LE32(pos, info);
2359 pos += 4;
2360 if (other->iconf->hw_mode == HOSTAPD_MODE_IEEE80211AD)
2361 phytype = 8; /* dmg */
2362 else if (other->iconf->ieee80211ac)
2363 phytype = 9; /* vht */
2364 else if (other->iconf->ieee80211n)
2365 phytype = 7; /* ht */
2366 else if (other->iconf->hw_mode ==
2367 HOSTAPD_MODE_IEEE80211A)
2368 phytype = 4; /* ofdm */
2369 else if (other->iconf->hw_mode ==
2370 HOSTAPD_MODE_IEEE80211G)
2371 phytype = 6; /* erp */
2372 else
2373 phytype = 5; /* hrdsss */
2374 if (ieee80211_freq_to_channel_ext(
2375 hostapd_hw_get_freq(other,
2376 other->iconf->channel),
2377 other->iconf->secondary_channel,
2378 other->iconf->ieee80211ac,
2379 &op_class, &channel) == NUM_HOSTAPD_MODES) {
2380 op_class = 0;
2381 channel = other->iconf->channel;
2382 }
2383 *pos++ = op_class;
2384 *pos++ = channel;
2385 *pos++ = phytype;
2386 resp_ies_len = pos - &resp_ies[0];
2387 goto fail;
2388 }
2389 }
2390
b0621b08
JM
2391 res = ieee802_11_allowed_address(hapd, mgmt->sa, (const u8 *) mgmt, len,
2392 &rad_info);
6fc6879b 2393 if (res == HOSTAPD_ACL_REJECT) {
92eb00ae
T
2394 wpa_msg(hapd->msg_ctx, MSG_DEBUG,
2395 "Ignore Authentication frame from " MACSTR
2396 " due to ACL reject", MAC2STR(mgmt->sa));
6fc6879b
JM
2397 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2398 goto fail;
2399 }
53d17144 2400 if (res == HOSTAPD_ACL_PENDING)
6fc6879b 2401 return;
6fc6879b 2402
ff9f40ae 2403#ifdef CONFIG_SAE
5e3a759c
JM
2404 if (auth_alg == WLAN_AUTH_SAE && !from_queue &&
2405 (auth_transaction == 1 ||
2406 (auth_transaction == 2 && auth_sae_queued_addr(hapd, mgmt->sa)))) {
ff9f40ae
JM
2407 /* Handle SAE Authentication commit message through a queue to
2408 * provide more control for postponing the needed heavy
5e3a759c
JM
2409 * processing under a possible DoS attack scenario. In addition,
2410 * queue SAE Authentication confirm message if there happens to
2411 * be a queued commit message from the same peer. This is needed
2412 * to avoid reordering Authentication frames within the same
2413 * SAE exchange. */
2414 auth_sae_queue(hapd, mgmt, len, rssi);
ff9f40ae
JM
2415 return;
2416 }
2417#endif /* CONFIG_SAE */
2418
38cb0a2d
IP
2419 sta = ap_get_sta(hapd, mgmt->sa);
2420 if (sta) {
c4fd6d8a 2421 sta->flags &= ~WLAN_STA_PENDING_FILS_ERP;
4cf5efec 2422 sta->ft_over_ds = 0;
38cb0a2d
IP
2423 if ((fc & WLAN_FC_RETRY) &&
2424 sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
2425 sta->last_seq_ctrl == seq_ctrl &&
2426 sta->last_subtype == WLAN_FC_STYPE_AUTH) {
2427 hostapd_logger(hapd, sta->addr,
2428 HOSTAPD_MODULE_IEEE80211,
2429 HOSTAPD_LEVEL_DEBUG,
2430 "Drop repeated authentication frame seq_ctrl=0x%x",
2431 seq_ctrl);
2432 return;
2433 }
09d96de0
MH
2434#ifdef CONFIG_MESH
2435 if ((hapd->conf->mesh & MESH_ENABLED) &&
2436 sta->plink_state == PLINK_BLOCKED) {
2437 wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
2438 " is blocked - drop Authentication frame",
2439 MAC2STR(mgmt->sa));
2440 return;
2441 }
2442#endif /* CONFIG_MESH */
38cb0a2d 2443 } else {
c50d94f1 2444#ifdef CONFIG_MESH
38cb0a2d
IP
2445 if (hapd->conf->mesh & MESH_ENABLED) {
2446 /* if the mesh peer is not available, we don't do auth.
2447 */
3a322496 2448 wpa_printf(MSG_DEBUG, "Mesh peer " MACSTR
09d96de0 2449 " not yet known - drop Authentication frame",
3a322496
JM
2450 MAC2STR(mgmt->sa));
2451 /*
2452 * Save a copy of the frame so that it can be processed
2453 * if a new peer entry is added shortly after this.
2454 */
2455 wpabuf_free(hapd->mesh_pending_auth);
2456 hapd->mesh_pending_auth = wpabuf_alloc_copy(mgmt, len);
2457 os_get_reltime(&hapd->mesh_pending_auth_time);
c50d94f1 2458 return;
38cb0a2d 2459 }
c50d94f1 2460#endif /* CONFIG_MESH */
38cb0a2d 2461
c50d94f1
BC
2462 sta = ap_sta_add(hapd, mgmt->sa);
2463 if (!sta) {
c6b5b9a3 2464 wpa_printf(MSG_DEBUG, "ap_sta_add() failed");
c50d94f1
BC
2465 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2466 goto fail;
2467 }
6fc6879b 2468 }
38cb0a2d
IP
2469 sta->last_seq_ctrl = seq_ctrl;
2470 sta->last_subtype = WLAN_FC_STYPE_AUTH;
2ea1fce3
JM
2471#ifdef CONFIG_MBO
2472 sta->auth_rssi = rssi;
2473#endif /* CONFIG_MBO */
6fc6879b 2474
29024efd 2475 res = ieee802_11_set_radius_info(hapd, sta, res, &rad_info);
53d17144 2476 if (res) {
c6b5b9a3 2477 wpa_printf(MSG_DEBUG, "ieee802_11_set_radius_info() failed");
8be640b7
MB
2478 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2479 goto fail;
6fc6879b 2480 }
2092597f 2481
6fc6879b
JM
2482 sta->flags &= ~WLAN_STA_PREAUTH;
2483 ieee802_1x_notify_pre_auth(sta->eapol_sm, 0);
2484
bb598c3b
AB
2485 /*
2486 * If the driver supports full AP client state, add a station to the
2487 * driver before sending authentication reply to make sure the driver
2488 * has resources, and not to go through the entire authentication and
2489 * association handshake, and fail it at the end.
2490 *
2491 * If this is not the first transaction, in a multi-step authentication
2492 * algorithm, the station already exists in the driver
2493 * (sta->added_unassoc = 1) so skip it.
2494 *
2495 * In mesh mode, the station was already added to the driver when the
2496 * NEW_PEER_CANDIDATE event is received.
2ab09656
JM
2497 *
2498 * If PMF was negotiated for the existing association, skip this to
2499 * avoid dropping the STA entry and the associated keys. This is needed
2500 * to allow the original connection work until the attempt can complete
2501 * (re)association, so that unprotected Authentication frame cannot be
2502 * used to bypass PMF protection.
bb598c3b
AB
2503 */
2504 if (FULL_AP_CLIENT_STATE_SUPP(hapd->iface->drv_flags) &&
2ab09656 2505 (!(sta->flags & WLAN_STA_MFP) || !ap_sta_is_authorized(sta)) &&
bb598c3b
AB
2506 !(hapd->conf->mesh & MESH_ENABLED) &&
2507 !(sta->added_unassoc)) {
2508 /*
2509 * If a station that is already associated to the AP, is trying
2510 * to authenticate again, remove the STA entry, in order to make
2511 * sure the STA PS state gets cleared and configuration gets
2512 * updated. To handle this, station's added_unassoc flag is
2513 * cleared once the station has completed association.
2514 */
b5ebe5dd 2515 ap_sta_set_authorized(hapd, sta, 0);
bb598c3b
AB
2516 hostapd_drv_sta_remove(hapd, sta->addr);
2517 sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_AUTH |
2518 WLAN_STA_AUTHORIZED);
2519
d5d156bd
JB
2520 if (hostapd_sta_add(hapd, sta->addr, 0, 0,
2521 sta->supported_rates,
2522 sta->supported_rates_len,
2523 0, NULL, NULL, NULL, 0,
78d35b16 2524 sta->flags, 0, 0, 0, 0)) {
bb598c3b
AB
2525 hostapd_logger(hapd, sta->addr,
2526 HOSTAPD_MODULE_IEEE80211,
2527 HOSTAPD_LEVEL_NOTICE,
2528 "Could not add STA to kernel driver");
2529 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2530 goto fail;
2531 }
2532
2533 sta->added_unassoc = 1;
2534 }
2535
6fc6879b
JM
2536 switch (auth_alg) {
2537 case WLAN_AUTH_OPEN:
2538 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2539 HOSTAPD_LEVEL_DEBUG,
2540 "authentication OK (open system)");
6fc6879b
JM
2541 sta->flags |= WLAN_STA_AUTH;
2542 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
2543 sta->auth_alg = WLAN_AUTH_OPEN;
2544 mlme_authenticate_indication(hapd, sta);
6fc6879b 2545 break;
7cb53ded 2546#ifndef CONFIG_NO_RC4
6fc6879b
JM
2547 case WLAN_AUTH_SHARED_KEY:
2548 resp = auth_shared_key(hapd, sta, auth_transaction, challenge,
2549 fc & WLAN_FC_ISWEP);
c6b5b9a3
BG
2550 if (resp != 0)
2551 wpa_printf(MSG_DEBUG,
2552 "auth_shared_key() failed: status=%d", resp);
6fc6879b
JM
2553 sta->auth_alg = WLAN_AUTH_SHARED_KEY;
2554 mlme_authenticate_indication(hapd, sta);
2555 if (sta->challenge && auth_transaction == 1) {
2556 resp_ies[0] = WLAN_EID_CHALLENGE;
2557 resp_ies[1] = WLAN_AUTH_CHALLENGE_LEN;
2558 os_memcpy(resp_ies + 2, sta->challenge,
2559 WLAN_AUTH_CHALLENGE_LEN);
2560 resp_ies_len = 2 + WLAN_AUTH_CHALLENGE_LEN;
2561 }
2562 break;
7cb53ded 2563#endif /* CONFIG_NO_RC4 */
4ec1fd8e 2564#ifdef CONFIG_IEEE80211R_AP
6fc6879b
JM
2565 case WLAN_AUTH_FT:
2566 sta->auth_alg = WLAN_AUTH_FT;
2567 if (sta->wpa_sm == NULL)
2568 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
94ddef3e 2569 sta->addr, NULL);
6fc6879b
JM
2570 if (sta->wpa_sm == NULL) {
2571 wpa_printf(MSG_DEBUG, "FT: Failed to initialize WPA "
2572 "state machine");
2573 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2574 goto fail;
2575 }
2576 wpa_ft_process_auth(sta->wpa_sm, mgmt->bssid,
2577 auth_transaction, mgmt->u.auth.variable,
2578 len - IEEE80211_HDRLEN -
2579 sizeof(mgmt->u.auth),
2580 handle_auth_ft_finish, hapd);
2581 /* handle_auth_ft_finish() callback will complete auth. */
2582 return;
4ec1fd8e 2583#endif /* CONFIG_IEEE80211R_AP */
c10347f2
JM
2584#ifdef CONFIG_SAE
2585 case WLAN_AUTH_SAE:
c50d94f1 2586#ifdef CONFIG_MESH
afa2ffb4
JM
2587 if (status_code == WLAN_STATUS_SUCCESS &&
2588 hapd->conf->mesh & MESH_ENABLED) {
c50d94f1
BC
2589 if (sta->wpa_sm == NULL)
2590 sta->wpa_sm =
2591 wpa_auth_sta_init(hapd->wpa_auth,
2592 sta->addr, NULL);
2593 if (sta->wpa_sm == NULL) {
2594 wpa_printf(MSG_DEBUG,
2595 "SAE: Failed to initialize WPA state machine");
2596 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
2597 goto fail;
2598 }
2599 }
2600#endif /* CONFIG_MESH */
afa2ffb4
JM
2601 handle_auth_sae(hapd, sta, mgmt, len, auth_transaction,
2602 status_code);
c10347f2
JM
2603 return;
2604#endif /* CONFIG_SAE */
c4fd6d8a
JM
2605#ifdef CONFIG_FILS
2606 case WLAN_AUTH_FILS_SK:
1764559e 2607 case WLAN_AUTH_FILS_SK_PFS:
b8a3453a
JM
2608 handle_auth_fils(hapd, sta, mgmt->u.auth.variable,
2609 len - IEEE80211_HDRLEN - sizeof(mgmt->u.auth),
5cee22ca
JM
2610 auth_alg, auth_transaction, status_code,
2611 handle_auth_fils_finish);
c4fd6d8a
JM
2612 return;
2613#endif /* CONFIG_FILS */
6fc6879b
JM
2614 }
2615
2616 fail:
3912cbd8 2617 reply_res = send_auth_reply(hapd, sta, mgmt->sa, mgmt->bssid, auth_alg,
bb598c3b 2618 auth_transaction + 1, resp, resp_ies,
e7525a29 2619 resp_ies_len, "handle-auth");
bb598c3b
AB
2620
2621 if (sta && sta->added_unassoc && (resp != WLAN_STATUS_SUCCESS ||
2622 reply_res != WLAN_STATUS_SUCCESS)) {
2623 hostapd_drv_sta_remove(hapd, sta->addr);
2624 sta->added_unassoc = 0;
2625 }
6fc6879b
JM
2626}
2627
2628
681753f2 2629int hostapd_get_aid(struct hostapd_data *hapd, struct sta_info *sta)
d42a62b3 2630{
2991469c
JM
2631 int i, j = 32, aid;
2632
d42a62b3
JM
2633 /* get a unique AID */
2634 if (sta->aid > 0) {
2635 wpa_printf(MSG_DEBUG, " old AID %d", sta->aid);
2636 return 0;
2637 }
2638
d7358113
JM
2639 if (TEST_FAIL())
2640 return -1;
2641
2991469c
JM
2642 for (i = 0; i < AID_WORDS; i++) {
2643 if (hapd->sta_aid[i] == (u32) -1)
2644 continue;
2645 for (j = 0; j < 32; j++) {
2646 if (!(hapd->sta_aid[i] & BIT(j)))
2647 break;
2648 }
2649 if (j < 32)
d42a62b3 2650 break;
d42a62b3 2651 }
2991469c
JM
2652 if (j == 32)
2653 return -1;
2654 aid = i * 32 + j + 1;
2655 if (aid > 2007)
2656 return -1;
d42a62b3 2657
2991469c
JM
2658 sta->aid = aid;
2659 hapd->sta_aid[i] |= BIT(j);
d42a62b3
JM
2660 wpa_printf(MSG_DEBUG, " new AID %d", sta->aid);
2661 return 0;
2662}
2663
2664
5586f500
JM
2665static u16 check_ssid(struct hostapd_data *hapd, struct sta_info *sta,
2666 const u8 *ssid_ie, size_t ssid_ie_len)
6fc6879b 2667{
5586f500
JM
2668 if (ssid_ie == NULL)
2669 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b 2670
5586f500
JM
2671 if (ssid_ie_len != hapd->conf->ssid.ssid_len ||
2672 os_memcmp(ssid_ie, hapd->conf->ssid.ssid, ssid_ie_len) != 0) {
5586f500
JM
2673 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2674 HOSTAPD_LEVEL_INFO,
2675 "Station tried to associate with unknown SSID "
b37d582e 2676 "'%s'", wpa_ssid_txt(ssid_ie, ssid_ie_len));
5586f500 2677 return WLAN_STATUS_UNSPECIFIED_FAILURE;
b0194fe0
JM
2678 }
2679
5586f500
JM
2680 return WLAN_STATUS_SUCCESS;
2681}
6fc6879b 2682
6fc6879b 2683
5586f500
JM
2684static u16 check_wmm(struct hostapd_data *hapd, struct sta_info *sta,
2685 const u8 *wmm_ie, size_t wmm_ie_len)
2686{
3ae0800c 2687 sta->flags &= ~WLAN_STA_WMM;
5d061637 2688 sta->qosinfo = 0;
5586f500 2689 if (wmm_ie && hapd->conf->wmm_enabled) {
5f32f79c 2690 struct wmm_information_element *wmm;
5f32f79c 2691
c84b868a 2692 if (!hostapd_eid_wmm_valid(hapd, wmm_ie, wmm_ie_len)) {
6fc6879b
JM
2693 hostapd_logger(hapd, sta->addr,
2694 HOSTAPD_MODULE_WPA,
2695 HOSTAPD_LEVEL_DEBUG,
3ae0800c 2696 "invalid WMM element in association "
6fc6879b 2697 "request");
5f32f79c
EP
2698 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2699 }
2700
2701 sta->flags |= WLAN_STA_WMM;
2702 wmm = (struct wmm_information_element *) wmm_ie;
5d061637 2703 sta->qosinfo = wmm->qos_info;
6fc6879b 2704 }
5586f500
JM
2705 return WLAN_STATUS_SUCCESS;
2706}
6fc6879b 2707
9c06f0f6
VN
2708static u16 check_multi_ap(struct hostapd_data *hapd, struct sta_info *sta,
2709 const u8 *multi_ap_ie, size_t multi_ap_len)
2710{
2711 u8 multi_ap_value = 0;
2712
2713 sta->flags &= ~WLAN_STA_MULTI_AP;
2714
2715 if (!hapd->conf->multi_ap)
2716 return WLAN_STATUS_SUCCESS;
2717
2718 if (multi_ap_ie) {
2719 const u8 *multi_ap_subelem;
2720
2721 multi_ap_subelem = get_ie(multi_ap_ie + 4,
2722 multi_ap_len - 4,
2723 MULTI_AP_SUB_ELEM_TYPE);
2724 if (multi_ap_subelem && multi_ap_subelem[1] == 1) {
2725 multi_ap_value = multi_ap_subelem[2];
2726 } else {
2727 hostapd_logger(hapd, sta->addr,
2728 HOSTAPD_MODULE_IEEE80211,
2729 HOSTAPD_LEVEL_INFO,
2730 "Multi-AP IE has missing or invalid Multi-AP subelement");
2731 return WLAN_STATUS_INVALID_IE;
2732 }
2733 }
2734
bfcdac1c
AVEM
2735 if (multi_ap_value && multi_ap_value != MULTI_AP_BACKHAUL_STA)
2736 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2737 HOSTAPD_LEVEL_INFO,
2738 "Multi-AP IE with unexpected value 0x%02x",
2739 multi_ap_value);
9c06f0f6 2740
bfcdac1c
AVEM
2741 if (!(multi_ap_value & MULTI_AP_BACKHAUL_STA)) {
2742 if (hapd->conf->multi_ap & FRONTHAUL_BSS)
2743 return WLAN_STATUS_SUCCESS;
9c06f0f6 2744
bfcdac1c
AVEM
2745 hostapd_logger(hapd, sta->addr,
2746 HOSTAPD_MODULE_IEEE80211,
2747 HOSTAPD_LEVEL_INFO,
2748 "Non-Multi-AP STA tries to associate with backhaul-only BSS");
2749 return WLAN_STATUS_ASSOC_DENIED_UNSPEC;
9c06f0f6
VN
2750 }
2751
bfcdac1c
AVEM
2752 if (!(hapd->conf->multi_ap & BACKHAUL_BSS))
2753 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
2754 HOSTAPD_LEVEL_DEBUG,
2755 "Backhaul STA tries to associate with fronthaul-only BSS");
2756
2757 sta->flags |= WLAN_STA_MULTI_AP;
2758 return WLAN_STATUS_SUCCESS;
9c06f0f6
VN
2759}
2760
5586f500
JM
2761
2762static u16 copy_supp_rates(struct hostapd_data *hapd, struct sta_info *sta,
2763 struct ieee802_11_elems *elems)
2764{
0c4b9025
DL
2765 /* Supported rates not used in IEEE 802.11ad/DMG */
2766 if (hapd->iface->current_mode &&
2767 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211AD)
2768 return WLAN_STATUS_SUCCESS;
2769
5586f500
JM
2770 if (!elems->supp_rates) {
2771 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
6fc6879b
JM
2772 HOSTAPD_LEVEL_DEBUG,
2773 "No supported rates element in AssocReq");
5586f500 2774 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
2775 }
2776
3489cfb0
JM
2777 if (elems->supp_rates_len + elems->ext_supp_rates_len >
2778 sizeof(sta->supported_rates)) {
5586f500 2779 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
6fc6879b 2780 HOSTAPD_LEVEL_DEBUG,
3489cfb0
JM
2781 "Invalid supported rates element length %d+%d",
2782 elems->supp_rates_len,
2783 elems->ext_supp_rates_len);
5586f500 2784 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
2785 }
2786
3489cfb0
JM
2787 sta->supported_rates_len = merge_byte_arrays(
2788 sta->supported_rates, sizeof(sta->supported_rates),
2789 elems->supp_rates, elems->supp_rates_len,
2790 elems->ext_supp_rates, elems->ext_supp_rates_len);
6fc6879b 2791
5586f500
JM
2792 return WLAN_STATUS_SUCCESS;
2793}
2794
2795
c551700f
KP
2796static u16 check_ext_capab(struct hostapd_data *hapd, struct sta_info *sta,
2797 const u8 *ext_capab_ie, size_t ext_capab_ie_len)
2798{
2799#ifdef CONFIG_INTERWORKING
2800 /* check for QoS Map support */
2801 if (ext_capab_ie_len >= 5) {
2802 if (ext_capab_ie[4] & 0x01)
2803 sta->qos_map_enabled = 1;
2804 }
2805#endif /* CONFIG_INTERWORKING */
2806
65f9db6b 2807 if (ext_capab_ie_len > 0) {
98b05081 2808 sta->ecsa_supported = !!(ext_capab_ie[0] & BIT(2));
65f9db6b 2809 os_free(sta->ext_capability);
2810 sta->ext_capability = os_malloc(1 + ext_capab_ie_len);
2811 if (sta->ext_capability) {
2812 sta->ext_capability[0] = ext_capab_ie_len;
2813 os_memcpy(sta->ext_capability + 1, ext_capab_ie,
2814 ext_capab_ie_len);
2815 }
2816 }
98b05081 2817
c551700f
KP
2818 return WLAN_STATUS_SUCCESS;
2819}
2820
2821
09368515 2822#ifdef CONFIG_OWE
91cc34bf
JM
2823
2824static int owe_group_supported(struct hostapd_data *hapd, u16 group)
2825{
2826 int i;
2827 int *groups = hapd->conf->owe_groups;
2828
2829 if (group != 19 && group != 20 && group != 21)
2830 return 0;
2831
2832 if (!groups)
2833 return 1;
2834
2835 for (i = 0; groups[i] > 0; i++) {
2836 if (groups[i] == group)
2837 return 1;
2838 }
2839
2840 return 0;
2841}
2842
2843
d90f10fa
JM
2844static u16 owe_process_assoc_req(struct hostapd_data *hapd,
2845 struct sta_info *sta, const u8 *owe_dh,
09368515
JM
2846 u8 owe_dh_len)
2847{
2848 struct wpabuf *secret, *pub, *hkey;
2849 int res;
7a12edd1 2850 u8 prk[SHA512_MAC_LEN], pmkid[SHA512_MAC_LEN];
09368515
JM
2851 const char *info = "OWE Key Generation";
2852 const u8 *addr[2];
2853 size_t len[2];
7a12edd1
JM
2854 u16 group;
2855 size_t hash_len, prime_len;
2856
d90f10fa
JM
2857 if (wpa_auth_sta_get_pmksa(sta->wpa_sm)) {
2858 wpa_printf(MSG_DEBUG, "OWE: Using PMKSA caching");
2859 return WLAN_STATUS_SUCCESS;
2860 }
2861
7a12edd1 2862 group = WPA_GET_LE16(owe_dh);
91cc34bf
JM
2863 if (!owe_group_supported(hapd, group)) {
2864 wpa_printf(MSG_DEBUG, "OWE: Unsupported DH group %u", group);
2865 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
2866 }
7a12edd1
JM
2867 if (group == 19)
2868 prime_len = 32;
2869 else if (group == 20)
2870 prime_len = 48;
2871 else if (group == 21)
2872 prime_len = 66;
2873 else
09368515
JM
2874 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
2875
2876 crypto_ecdh_deinit(sta->owe_ecdh);
7a12edd1 2877 sta->owe_ecdh = crypto_ecdh_init(group);
09368515
JM
2878 if (!sta->owe_ecdh)
2879 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
7a12edd1 2880 sta->owe_group = group;
09368515
JM
2881
2882 secret = crypto_ecdh_set_peerkey(sta->owe_ecdh, 0, owe_dh + 2,
2883 owe_dh_len - 2);
7a12edd1 2884 secret = wpabuf_zeropad(secret, prime_len);
09368515
JM
2885 if (!secret) {
2886 wpa_printf(MSG_DEBUG, "OWE: Invalid peer DH public key");
2887 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2888 }
2889 wpa_hexdump_buf_key(MSG_DEBUG, "OWE: DH shared secret", secret);
2890
2891 /* prk = HKDF-extract(C | A | group, z) */
2892
2893 pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
2894 if (!pub) {
2895 wpabuf_clear_free(secret);
2896 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2897 }
2898
2899 /* PMKID = Truncate-128(Hash(C | A)) */
2900 addr[0] = owe_dh + 2;
2901 len[0] = owe_dh_len - 2;
2902 addr[1] = wpabuf_head(pub);
2903 len[1] = wpabuf_len(pub);
7a12edd1
JM
2904 if (group == 19) {
2905 res = sha256_vector(2, addr, len, pmkid);
2906 hash_len = SHA256_MAC_LEN;
2907 } else if (group == 20) {
2908 res = sha384_vector(2, addr, len, pmkid);
2909 hash_len = SHA384_MAC_LEN;
2910 } else if (group == 21) {
2911 res = sha512_vector(2, addr, len, pmkid);
2912 hash_len = SHA512_MAC_LEN;
2913 } else {
2914 wpabuf_free(pub);
2915 wpabuf_clear_free(secret);
2916 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2917 }
2918 pub = wpabuf_zeropad(pub, prime_len);
2919 if (res < 0 || !pub) {
09368515
JM
2920 wpabuf_free(pub);
2921 wpabuf_clear_free(secret);
2922 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2923 }
2924
2925 hkey = wpabuf_alloc(owe_dh_len - 2 + wpabuf_len(pub) + 2);
2926 if (!hkey) {
2927 wpabuf_free(pub);
2928 wpabuf_clear_free(secret);
2929 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2930 }
2931
2932 wpabuf_put_data(hkey, owe_dh + 2, owe_dh_len - 2); /* C */
2933 wpabuf_put_buf(hkey, pub); /* A */
2934 wpabuf_free(pub);
7a12edd1
JM
2935 wpabuf_put_le16(hkey, group); /* group */
2936 if (group == 19)
2937 res = hmac_sha256(wpabuf_head(hkey), wpabuf_len(hkey),
2938 wpabuf_head(secret), wpabuf_len(secret), prk);
2939 else if (group == 20)
2940 res = hmac_sha384(wpabuf_head(hkey), wpabuf_len(hkey),
2941 wpabuf_head(secret), wpabuf_len(secret), prk);
2942 else if (group == 21)
2943 res = hmac_sha512(wpabuf_head(hkey), wpabuf_len(hkey),
2944 wpabuf_head(secret), wpabuf_len(secret), prk);
09368515
JM
2945 wpabuf_clear_free(hkey);
2946 wpabuf_clear_free(secret);
2947 if (res < 0)
2948 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2949
7a12edd1 2950 wpa_hexdump_key(MSG_DEBUG, "OWE: prk", prk, hash_len);
09368515
JM
2951
2952 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2953
2954 os_free(sta->owe_pmk);
7a12edd1 2955 sta->owe_pmk = os_malloc(hash_len);
09368515 2956 if (!sta->owe_pmk) {
7a12edd1 2957 os_memset(prk, 0, SHA512_MAC_LEN);
09368515
JM
2958 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2959 }
2960
7a12edd1
JM
2961 if (group == 19)
2962 res = hmac_sha256_kdf(prk, hash_len, NULL, (const u8 *) info,
2963 os_strlen(info), sta->owe_pmk, hash_len);
2964 else if (group == 20)
2965 res = hmac_sha384_kdf(prk, hash_len, NULL, (const u8 *) info,
2966 os_strlen(info), sta->owe_pmk, hash_len);
2967 else if (group == 21)
2968 res = hmac_sha512_kdf(prk, hash_len, NULL, (const u8 *) info,
2969 os_strlen(info), sta->owe_pmk, hash_len);
2970 os_memset(prk, 0, SHA512_MAC_LEN);
09368515
JM
2971 if (res < 0) {
2972 os_free(sta->owe_pmk);
2973 sta->owe_pmk = NULL;
2974 return WLAN_STATUS_UNSPECIFIED_FAILURE;
2975 }
7a12edd1 2976 sta->owe_pmk_len = hash_len;
09368515 2977
7a12edd1 2978 wpa_hexdump_key(MSG_DEBUG, "OWE: PMK", sta->owe_pmk, sta->owe_pmk_len);
09368515 2979 wpa_hexdump(MSG_DEBUG, "OWE: PMKID", pmkid, PMKID_LEN);
d90f10fa
JM
2980 wpa_auth_pmksa_add2(hapd->wpa_auth, sta->addr, sta->owe_pmk,
2981 sta->owe_pmk_len, pmkid, 0, WPA_KEY_MGMT_OWE);
09368515
JM
2982
2983 return WLAN_STATUS_SUCCESS;
2984}
91cc34bf 2985
ef60f012
LD
2986
2987u16 owe_validate_request(struct hostapd_data *hapd, const u8 *peer,
2988 const u8 *rsn_ie, size_t rsn_ie_len,
2989 const u8 *owe_dh, size_t owe_dh_len)
2990{
2991 struct wpa_ie_data data;
2992 int res;
2993
2994 if (!rsn_ie || rsn_ie_len < 2) {
2995 wpa_printf(MSG_DEBUG, "OWE: Invalid RSNE from " MACSTR,
2996 MAC2STR(peer));
2997 return WLAN_STATUS_INVALID_IE;
2998 }
2999 rsn_ie -= 2;
3000 rsn_ie_len += 2;
3001
3002 res = wpa_parse_wpa_ie_rsn(rsn_ie, rsn_ie_len, &data);
3003 if (res) {
3004 wpa_printf(MSG_DEBUG, "Failed to parse RSNE from " MACSTR
3005 " (res=%d)", MAC2STR(peer), res);
3006 wpa_hexdump(MSG_DEBUG, "RSNE", rsn_ie, rsn_ie_len);
3007 return wpa_res_to_status_code(res);
3008 }
3009 if (!(data.key_mgmt & WPA_KEY_MGMT_OWE)) {
3010 wpa_printf(MSG_DEBUG,
3011 "OWE: Unexpected key mgmt 0x%x from " MACSTR,
3012 (unsigned int) data.key_mgmt, MAC2STR(peer));
3013 return WLAN_STATUS_AKMP_NOT_VALID;
3014 }
3015 if (!owe_dh) {
3016 wpa_printf(MSG_DEBUG,
3017 "OWE: No Diffie-Hellman Parameter element from "
3018 MACSTR, MAC2STR(peer));
3019 return WLAN_STATUS_AKMP_NOT_VALID;
3020 }
3021
3022 return WLAN_STATUS_SUCCESS;
3023}
3024
3025
3026u16 owe_process_rsn_ie(struct hostapd_data *hapd,
3027 struct sta_info *sta,
3028 const u8 *rsn_ie, size_t rsn_ie_len,
3029 const u8 *owe_dh, size_t owe_dh_len)
3030{
3031 u16 status;
3032 u8 *owe_buf, ie[256 * 2];
3033 size_t ie_len = 0;
3034 int res;
3035
3036 if (!rsn_ie || rsn_ie_len < 2) {
3037 wpa_printf(MSG_DEBUG, "OWE: No RSNE in (Re)AssocReq");
3038 status = WLAN_STATUS_INVALID_IE;
3039 goto end;
3040 }
3041
3042 if (!sta->wpa_sm)
3043 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth, sta->addr,
3044 NULL);
3045 if (!sta->wpa_sm) {
3046 wpa_printf(MSG_WARNING,
3047 "OWE: Failed to initialize WPA state machine");
3048 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3049 goto end;
3050 }
3051 rsn_ie -= 2;
3052 rsn_ie_len += 2;
3053 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
3054 hapd->iface->freq, rsn_ie, rsn_ie_len,
d3516cad 3055 NULL, 0, NULL, 0, owe_dh, owe_dh_len);
ef60f012
LD
3056 status = wpa_res_to_status_code(res);
3057 if (status != WLAN_STATUS_SUCCESS)
3058 goto end;
3059 status = owe_process_assoc_req(hapd, sta, owe_dh, owe_dh_len);
3060 if (status != WLAN_STATUS_SUCCESS)
3061 goto end;
3062 owe_buf = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, ie, sizeof(ie),
3063 NULL, 0);
3064 if (!owe_buf) {
3065 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3066 goto end;
3067 }
3068
3069 if (sta->owe_ecdh) {
3070 struct wpabuf *pub;
3071
3072 pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
3073 if (!pub) {
3074 status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3075 goto end;
3076 }
3077
3078 /* OWE Diffie-Hellman Parameter element */
3079 *owe_buf++ = WLAN_EID_EXTENSION; /* Element ID */
3080 *owe_buf++ = 1 + 2 + wpabuf_len(pub); /* Length */
3081 *owe_buf++ = WLAN_EID_EXT_OWE_DH_PARAM; /* Element ID Extension
3082 */
3083 WPA_PUT_LE16(owe_buf, sta->owe_group);
3084 owe_buf += 2;
3085 os_memcpy(owe_buf, wpabuf_head(pub), wpabuf_len(pub));
3086 owe_buf += wpabuf_len(pub);
3087 wpabuf_free(pub);
3088 sta->external_dh_updated = 1;
3089 }
3090 ie_len = owe_buf - ie;
3091
3092end:
3093 wpa_printf(MSG_DEBUG, "OWE: Update status %d, ie len %d for peer "
3094 MACSTR, status, (unsigned int) ie_len,
3095 MAC2STR(sta->addr));
3096 hostapd_drv_update_dh_ie(hapd, sta->addr, status,
3097 status == WLAN_STATUS_SUCCESS ? ie : NULL,
3098 ie_len);
3099
3100 return status;
3101}
3102
09368515
JM
3103#endif /* CONFIG_OWE */
3104
3105
5586f500 3106static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
b57e086c 3107 const u8 *ies, size_t ies_len, int reassoc)
5586f500
JM
3108{
3109 struct ieee802_11_elems elems;
3110 u16 resp;
ba091c06 3111 const u8 *wpa_ie;
5586f500 3112 size_t wpa_ie_len;
94ddef3e 3113 const u8 *p2p_dev_addr = NULL;
5586f500
JM
3114
3115 if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed) {
3116 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3117 HOSTAPD_LEVEL_INFO, "Station sent an invalid "
3118 "association request");
3119 return WLAN_STATUS_UNSPECIFIED_FAILURE;
3120 }
3121
3122 resp = check_ssid(hapd, sta, elems.ssid, elems.ssid_len);
3123 if (resp != WLAN_STATUS_SUCCESS)
3124 return resp;
3125 resp = check_wmm(hapd, sta, elems.wmm, elems.wmm_len);
c551700f
KP
3126 if (resp != WLAN_STATUS_SUCCESS)
3127 return resp;
3128 resp = check_ext_capab(hapd, sta, elems.ext_capab, elems.ext_capab_len);
5586f500
JM
3129 if (resp != WLAN_STATUS_SUCCESS)
3130 return resp;
3131 resp = copy_supp_rates(hapd, sta, &elems);
3132 if (resp != WLAN_STATUS_SUCCESS)
3133 return resp;
9c06f0f6
VN
3134
3135 resp = check_multi_ap(hapd, sta, elems.multi_ap, elems.multi_ap_len);
3136 if (resp != WLAN_STATUS_SUCCESS)
3137 return resp;
3138
d45354be 3139#ifdef CONFIG_IEEE80211N
baae4cb9 3140 resp = copy_sta_ht_capab(hapd, sta, elems.ht_capabilities);
5586f500
JM
3141 if (resp != WLAN_STATUS_SUCCESS)
3142 return resp;
29448243
JM
3143 if (hapd->iconf->ieee80211n && hapd->iconf->require_ht &&
3144 !(sta->flags & WLAN_STA_HT)) {
3145 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3146 HOSTAPD_LEVEL_INFO, "Station does not support "
3147 "mandatory HT PHY - reject association");
3148 return WLAN_STATUS_ASSOC_DENIED_NO_HT;
3149 }
d45354be 3150#endif /* CONFIG_IEEE80211N */
5586f500 3151
de3cdf35 3152#ifdef CONFIG_IEEE80211AC
28ffd21c
ARN
3153 if (hapd->iconf->ieee80211ac) {
3154 resp = copy_sta_vht_capab(hapd, sta, elems.vht_capabilities);
3155 if (resp != WLAN_STATUS_SUCCESS)
3156 return resp;
8a458116 3157
28ffd21c
ARN
3158 resp = set_sta_vht_opmode(hapd, sta, elems.vht_opmode_notif);
3159 if (resp != WLAN_STATUS_SUCCESS)
3160 return resp;
3161 }
8a458116 3162
140e850a
MP
3163 if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht &&
3164 !(sta->flags & WLAN_STA_VHT)) {
3165 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3166 HOSTAPD_LEVEL_INFO, "Station does not support "
3167 "mandatory VHT PHY - reject association");
13b24a76 3168 return WLAN_STATUS_ASSOC_DENIED_NO_VHT;
140e850a 3169 }
e7d0e97b
YL
3170
3171 if (hapd->conf->vendor_vht && !elems.vht_capabilities) {
3172 resp = copy_sta_vendor_vht(hapd, sta, elems.vendor_vht,
3173 elems.vendor_vht_len);
3174 if (resp != WLAN_STATUS_SUCCESS)
3175 return resp;
3176 }
de3cdf35 3177#endif /* CONFIG_IEEE80211AC */
78d35b16
JC
3178#ifdef CONFIG_IEEE80211AX
3179 if (hapd->iconf->ieee80211ax) {
29d8bd1d
SE
3180 resp = copy_sta_he_capab(hapd, sta, IEEE80211_MODE_AP,
3181 elems.he_capabilities,
78d35b16
JC
3182 elems.he_capabilities_len);
3183 if (resp != WLAN_STATUS_SUCCESS)
3184 return resp;
3185 }
3186#endif /* CONFIG_IEEE80211AX */
de3cdf35 3187
94ddef3e
JM
3188#ifdef CONFIG_P2P
3189 if (elems.p2p) {
3190 wpabuf_free(sta->p2p_ie);
3191 sta->p2p_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
3192 P2P_IE_VENDOR_TYPE);
3193 if (sta->p2p_ie)
3194 p2p_dev_addr = p2p_get_go_dev_addr(sta->p2p_ie);
3195 } else {
3196 wpabuf_free(sta->p2p_ie);
3197 sta->p2p_ie = NULL;
3198 }
3199#endif /* CONFIG_P2P */
3200
6fc6879b
JM
3201 if ((hapd->conf->wpa & WPA_PROTO_RSN) && elems.rsn_ie) {
3202 wpa_ie = elems.rsn_ie;
3203 wpa_ie_len = elems.rsn_ie_len;
3204 } else if ((hapd->conf->wpa & WPA_PROTO_WPA) &&
3205 elems.wpa_ie) {
3206 wpa_ie = elems.wpa_ie;
3207 wpa_ie_len = elems.wpa_ie_len;
3208 } else {
3209 wpa_ie = NULL;
3210 wpa_ie_len = 0;
3211 }
5586f500 3212
ad08c363 3213#ifdef CONFIG_WPS
17f6b900 3214 sta->flags &= ~(WLAN_STA_WPS | WLAN_STA_MAYBE_WPS | WLAN_STA_WPS2);
c47cf42e
JM
3215 if (hapd->conf->wps_state && elems.wps_ie) {
3216 wpa_printf(MSG_DEBUG, "STA included WPS IE in (Re)Association "
3217 "Request - assume WPS is used");
3218 sta->flags |= WLAN_STA_WPS;
3219 wpabuf_free(sta->wps_ie);
16e46ec0
JM
3220 sta->wps_ie = ieee802_11_vendor_ie_concat(ies, ies_len,
3221 WPS_IE_VENDOR_TYPE);
17f6b900
JM
3222 if (sta->wps_ie && wps_is_20(sta->wps_ie)) {
3223 wpa_printf(MSG_DEBUG, "WPS: STA supports WPS 2.0");
3224 sta->flags |= WLAN_STA_WPS2;
3225 }
c47cf42e
JM
3226 wpa_ie = NULL;
3227 wpa_ie_len = 0;
54f489be
JM
3228 if (sta->wps_ie && wps_validate_assoc_req(sta->wps_ie) < 0) {
3229 wpa_printf(MSG_DEBUG, "WPS: Invalid WPS IE in "
3230 "(Re)Association Request - reject");
3231 return WLAN_STATUS_INVALID_IE;
3232 }
c47cf42e
JM
3233 } else if (hapd->conf->wps_state && wpa_ie == NULL) {
3234 wpa_printf(MSG_DEBUG, "STA did not include WPA/RSN IE in "
3235 "(Re)Association Request - possible WPS use");
3236 sta->flags |= WLAN_STA_MAYBE_WPS;
ad08c363
JM
3237 } else
3238#endif /* CONFIG_WPS */
6fc6879b 3239 if (hapd->conf->wpa && wpa_ie == NULL) {
5586f500
JM
3240 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3241 HOSTAPD_LEVEL_INFO,
3242 "No WPA/RSN IE in association request");
3243 return WLAN_STATUS_INVALID_IE;
6fc6879b
JM
3244 }
3245
3246 if (hapd->conf->wpa && wpa_ie) {
3247 int res;
3248 wpa_ie -= 2;
3249 wpa_ie_len += 2;
3250 if (sta->wpa_sm == NULL)
3251 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
94ddef3e
JM
3252 sta->addr,
3253 p2p_dev_addr);
6fc6879b 3254 if (sta->wpa_sm == NULL) {
5586f500
JM
3255 wpa_printf(MSG_WARNING, "Failed to initialize WPA "
3256 "state machine");
3257 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b 3258 }
36536639 3259 wpa_auth_set_auth_alg(sta->wpa_sm, sta->auth_alg);
6fc6879b 3260 res = wpa_validate_wpa_ie(hapd->wpa_auth, sta->wpa_sm,
2c129a1b 3261 hapd->iface->freq,
6fc6879b 3262 wpa_ie, wpa_ie_len,
d3516cad
JM
3263 elems.rsnxe ? elems.rsnxe - 2 : NULL,
3264 elems.rsnxe ? elems.rsnxe_len + 2 : 0,
09368515
JM
3265 elems.mdie, elems.mdie_len,
3266 elems.owe_dh, elems.owe_dh_len);
ffb62f22 3267 resp = wpa_res_to_status_code(res);
6fc6879b 3268 if (resp != WLAN_STATUS_SUCCESS)
5586f500 3269 return resp;
edb28006
AK
3270 if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_MFP)) ==
3271 (WLAN_STA_ASSOC | WLAN_STA_MFP) &&
3272 !sta->sa_query_timed_out &&
45c94154
JM
3273 sta->sa_query_count > 0)
3274 ap_check_sa_query_timeout(hapd, sta);
edb28006
AK
3275 if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_MFP)) ==
3276 (WLAN_STA_ASSOC | WLAN_STA_MFP) &&
3277 !sta->sa_query_timed_out &&
8f4617c6 3278 (!reassoc || sta->auth_alg != WLAN_AUTH_FT)) {
5d22a1d5 3279 /*
93b76319
JM
3280 * STA has already been associated with MFP and SA
3281 * Query timeout has not been reached. Reject the
3282 * association attempt temporarily and start SA Query,
3283 * if one is not pending.
5d22a1d5
JM
3284 */
3285
93b76319
JM
3286 if (sta->sa_query_count == 0)
3287 ap_sta_start_sa_query(hapd, sta);
5d22a1d5 3288
5586f500 3289 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY;
5d22a1d5
JM
3290 }
3291
f3f7540e
JM
3292 if (wpa_auth_uses_mfp(sta->wpa_sm))
3293 sta->flags |= WLAN_STA_MFP;
3294 else
3295 sta->flags &= ~WLAN_STA_MFP;
6fc6879b 3296
4ec1fd8e 3297#ifdef CONFIG_IEEE80211R_AP
6fc6879b
JM
3298 if (sta->auth_alg == WLAN_AUTH_FT) {
3299 if (!reassoc) {
3300 wpa_printf(MSG_DEBUG, "FT: " MACSTR " tried "
3301 "to use association (not "
3302 "re-association) with FT auth_alg",
3303 MAC2STR(sta->addr));
5586f500 3304 return WLAN_STATUS_UNSPECIFIED_FAILURE;
6fc6879b
JM
3305 }
3306
5586f500
JM
3307 resp = wpa_ft_validate_reassoc(sta->wpa_sm, ies,
3308 ies_len);
6fc6879b 3309 if (resp != WLAN_STATUS_SUCCESS)
5586f500 3310 return resp;
6fc6879b 3311 }
4ec1fd8e 3312#endif /* CONFIG_IEEE80211R_AP */
5586f500 3313
c10347f2 3314#ifdef CONFIG_SAE
9d94e4bb
JM
3315 if (wpa_auth_uses_sae(sta->wpa_sm) && sta->sae &&
3316 sta->sae->state == SAE_ACCEPTED)
3317 wpa_auth_add_sae_pmkid(sta->wpa_sm, sta->sae->pmkid);
3318
c10347f2 3319 if (wpa_auth_uses_sae(sta->wpa_sm) &&
f2991170
JM
3320 sta->auth_alg == WLAN_AUTH_OPEN) {
3321 struct rsn_pmksa_cache_entry *sa;
3322 sa = wpa_auth_sta_get_pmksa(sta->wpa_sm);
3323 if (!sa || sa->akmp != WPA_KEY_MGMT_SAE) {
3324 wpa_printf(MSG_DEBUG,
3325 "SAE: No PMKSA cache entry found for "
3326 MACSTR, MAC2STR(sta->addr));
3327 return WLAN_STATUS_INVALID_PMKID;
3328 }
3329 wpa_printf(MSG_DEBUG, "SAE: " MACSTR
3330 " using PMKSA caching", MAC2STR(sta->addr));
3331 } else if (wpa_auth_uses_sae(sta->wpa_sm) &&
3332 sta->auth_alg != WLAN_AUTH_SAE &&
3333 !(sta->auth_alg == WLAN_AUTH_FT &&
3334 wpa_auth_uses_ft_sae(sta->wpa_sm))) {
c10347f2
JM
3335 wpa_printf(MSG_DEBUG, "SAE: " MACSTR " tried to use "
3336 "SAE AKM after non-SAE auth_alg %u",
3337 MAC2STR(sta->addr), sta->auth_alg);
3338 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
3339 }
898b6d58
JM
3340
3341 if (hapd->conf->sae_pwe == 2 &&
3342 sta->auth_alg == WLAN_AUTH_SAE &&
3343 sta->sae && sta->sae->tmp && !sta->sae->tmp->h2e &&
3344 elems.rsnxe && elems.rsnxe_len >= 1 &&
3345 (elems.rsnxe[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
3346 wpa_printf(MSG_INFO, "SAE: " MACSTR
3347 " indicates support for SAE H2E, but did not use it",
3348 MAC2STR(sta->addr));
3349 return WLAN_STATUS_UNSPECIFIED_FAILURE;
3350 }
c10347f2
JM
3351#endif /* CONFIG_SAE */
3352
09368515
JM
3353#ifdef CONFIG_OWE
3354 if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
3355 wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE &&
3356 elems.owe_dh) {
d90f10fa 3357 resp = owe_process_assoc_req(hapd, sta, elems.owe_dh,
09368515
JM
3358 elems.owe_dh_len);
3359 if (resp != WLAN_STATUS_SUCCESS)
3360 return resp;
3361 }
3362#endif /* CONFIG_OWE */
3363
10ec6a5f
JM
3364#ifdef CONFIG_DPP2
3365 dpp_pfs_free(sta->dpp_pfs);
3366 sta->dpp_pfs = NULL;
3367
3368 if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) &&
3369 hapd->conf->dpp_netaccesskey && sta->wpa_sm &&
3370 wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP &&
3371 elems.owe_dh) {
3372 sta->dpp_pfs = dpp_pfs_init(
3373 wpabuf_head(hapd->conf->dpp_netaccesskey),
3374 wpabuf_len(hapd->conf->dpp_netaccesskey));
3375 if (!sta->dpp_pfs) {
3376 wpa_printf(MSG_DEBUG,
3377 "DPP: Could not initialize PFS");
3378 /* Try to continue without PFS */
3379 goto pfs_fail;
3380 }
3381
3382 if (dpp_pfs_process(sta->dpp_pfs, elems.owe_dh,
3383 elems.owe_dh_len) < 0) {
3384 dpp_pfs_free(sta->dpp_pfs);
3385 sta->dpp_pfs = NULL;
3386 return WLAN_STATUS_UNSPECIFIED_FAILURE;
3387 }
3388 }
3389
3390 wpa_auth_set_dpp_z(sta->wpa_sm, sta->dpp_pfs ?
3391 sta->dpp_pfs->secret : NULL);
3392 pfs_fail:
3393#endif /* CONFIG_DPP2 */
3394
ff36ff00 3395#ifdef CONFIG_IEEE80211N
f0c7a986 3396 if ((sta->flags & (WLAN_STA_HT | WLAN_STA_VHT)) &&
ff36ff00 3397 wpa_auth_get_pairwise(sta->wpa_sm) == WPA_CIPHER_TKIP) {
5586f500
JM
3398 hostapd_logger(hapd, sta->addr,
3399 HOSTAPD_MODULE_IEEE80211,
3400 HOSTAPD_LEVEL_INFO,
3401 "Station tried to use TKIP with HT "
3402 "association");
3403 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
ff36ff00
JM
3404 }
3405#endif /* CONFIG_IEEE80211N */
a14896e8
JM
3406#ifdef CONFIG_HS20
3407 } else if (hapd->conf->osen) {
3408 if (elems.osen == NULL) {
3409 hostapd_logger(
3410 hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
3411 HOSTAPD_LEVEL_INFO,
3412 "No HS 2.0 OSEN element in association request");
3413 return WLAN_STATUS_INVALID_IE;
3414 }
3415
3416 wpa_printf(MSG_DEBUG, "HS 2.0: OSEN association");
3417 if (sta->wpa_sm == NULL)
3418 sta->wpa_sm = wpa_auth_sta_init(hapd->wpa_auth,
3419 sta->addr, NULL);
3420 if (sta->wpa_sm == NULL) {
3421 wpa_printf(MSG_WARNING, "Failed to initialize WPA "
3422 "state machine");
3423 return WLAN_STATUS_UNSPECIFIED_FAILURE;
3424 }
3425 if (wpa_validate_osen(hapd->wpa_auth, sta->wpa_sm,
3426 elems.osen - 2, elems.osen_len + 2) < 0)
3427 return WLAN_STATUS_INVALID_IE;
3428#endif /* CONFIG_HS20 */
a8d05fca
JM
3429 } else
3430 wpa_auth_sta_no_wpa(sta->wpa_sm);
6fc6879b 3431
b305c684 3432#ifdef CONFIG_P2P
3f4ce13f 3433 p2p_group_notif_assoc(hapd->p2p_group, sta->addr, ies, ies_len);
b305c684
JM
3434#endif /* CONFIG_P2P */
3435
f403dcd6
JM
3436#ifdef CONFIG_HS20
3437 wpabuf_free(sta->hs20_ie);
3438 if (elems.hs20 && elems.hs20_len > 4) {
f3784a6b
JM
3439 int release;
3440
f403dcd6
JM
3441 sta->hs20_ie = wpabuf_alloc_copy(elems.hs20 + 4,
3442 elems.hs20_len - 4);
f3784a6b 3443 release = ((elems.hs20[4] >> 4) & 0x0f) + 1;
a762ba8b
JM
3444 if (release >= 2 && !wpa_auth_uses_mfp(sta->wpa_sm) &&
3445 hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
f3784a6b
JM
3446 wpa_printf(MSG_DEBUG,
3447 "HS 2.0: PMF not negotiated by release %d station "
3448 MACSTR, release, MAC2STR(sta->addr));
3449 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION;
3450 }
3451 } else {
f403dcd6 3452 sta->hs20_ie = NULL;
f3784a6b 3453 }
67cca346
JM
3454
3455 wpabuf_free(sta->roaming_consortium);
3456 if (elems.roaming_cons_sel)
3457 sta->roaming_consortium = wpabuf_alloc_copy(
3458 elems.roaming_cons_sel + 4,
3459 elems.roaming_cons_sel_len - 4);
3460 else
3461 sta->roaming_consortium = NULL;
f403dcd6
JM
3462#endif /* CONFIG_HS20 */
3463
ae667c08
AN
3464#ifdef CONFIG_FST
3465 wpabuf_free(sta->mb_ies);
3466 if (hapd->iface->fst)
3467 sta->mb_ies = mb_ies_by_info(&elems.mb_ies);
3468 else
3469 sta->mb_ies = NULL;
3470#endif /* CONFIG_FST */
3471
4c572281 3472#ifdef CONFIG_MBO
6332aaf3
JM
3473 mbo_ap_check_sta_assoc(hapd, sta, &elems);
3474
4c572281
JM
3475 if (hapd->conf->mbo_enabled && (hapd->conf->wpa & 2) &&
3476 elems.mbo && sta->cell_capa && !(sta->flags & WLAN_STA_MFP) &&
3477 hapd->conf->ieee80211w != NO_MGMT_FRAME_PROTECTION) {
3478 wpa_printf(MSG_INFO,
3479 "MBO: Reject WPA2 association without PMF");
3480 return WLAN_STATUS_UNSPECIFIED_FAILURE;
3481 }
3482#endif /* CONFIG_MBO */
3483
99621dc1
MV
3484#if defined(CONFIG_FILS) && defined(CONFIG_OCV)
3485 if (wpa_auth_uses_ocv(sta->wpa_sm) &&
3486 (sta->auth_alg == WLAN_AUTH_FILS_SK ||
3487 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
3488 sta->auth_alg == WLAN_AUTH_FILS_PK)) {
3489 struct wpa_channel_info ci;
3490 int tx_chanwidth;
3491 int tx_seg1_idx;
3492
3493 if (hostapd_drv_channel_info(hapd, &ci) != 0) {
3494 wpa_printf(MSG_WARNING,
3495 "Failed to get channel info to validate received OCI in FILS (Re)Association Request frame");
3496 return WLAN_STATUS_UNSPECIFIED_FAILURE;
3497 }
3498
3499 if (get_sta_tx_parameters(sta->wpa_sm,
3500 channel_width_to_int(ci.chanwidth),
3501 ci.seg1_idx, &tx_chanwidth,
3502 &tx_seg1_idx) < 0)
3503 return WLAN_STATUS_UNSPECIFIED_FAILURE;
3504
3505 if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
3506 tx_chanwidth, tx_seg1_idx) != 0) {
3507 wpa_printf(MSG_WARNING, "FILS: %s", ocv_errorstr);
3508 return WLAN_STATUS_UNSPECIFIED_FAILURE;
3509 }
3510 }
3511#endif /* CONFIG_FILS && CONFIG_OCV */
3512
adf0478e
JM
3513 ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
3514 elems.supp_op_classes_len);
3515
629e1804
DS
3516 if ((sta->capability & WLAN_CAPABILITY_RADIO_MEASUREMENT) &&
3517 elems.rrm_enabled &&
3518 elems.rrm_enabled_len >= sizeof(sta->rrm_enabled_capa))
3519 os_memcpy(sta->rrm_enabled_capa, elems.rrm_enabled,
3520 sizeof(sta->rrm_enabled_capa));
3521
ba72b4b1 3522 if (elems.power_capab) {
3523 sta->min_tx_power = elems.power_capab[0];
3524 sta->max_tx_power = elems.power_capab[1];
3525 sta->power_capab = 1;
3526 } else {
3527 sta->power_capab = 0;
3528 }
3529
5586f500
JM
3530 return WLAN_STATUS_SUCCESS;
3531}
3532
3533
3534static void send_deauth(struct hostapd_data *hapd, const u8 *addr,
3535 u16 reason_code)
3536{
3537 int send_len;
3538 struct ieee80211_mgmt reply;
3539
3540 os_memset(&reply, 0, sizeof(reply));
3541 reply.frame_control =
3542 IEEE80211_FC(WLAN_FC_TYPE_MGMT, WLAN_FC_STYPE_DEAUTH);
3543 os_memcpy(reply.da, addr, ETH_ALEN);
3544 os_memcpy(reply.sa, hapd->own_addr, ETH_ALEN);
3545 os_memcpy(reply.bssid, hapd->own_addr, ETH_ALEN);
3546
3547 send_len = IEEE80211_HDRLEN + sizeof(reply.u.deauth);
3548 reply.u.deauth.reason_code = host_to_le16(reason_code);
3549
37100274 3550 if (hostapd_drv_send_mlme(hapd, &reply, send_len, 0, NULL, 0, 0) < 0)
5586f500
JM
3551 wpa_printf(MSG_INFO, "Failed to send deauth: %s",
3552 strerror(errno));
3553}
3554
3555
3f81ac07 3556static int add_associated_sta(struct hostapd_data *hapd,
4cf5efec 3557 struct sta_info *sta, int reassoc)
3f81ac07
AO
3558{
3559 struct ieee80211_ht_capabilities ht_cap;
3560 struct ieee80211_vht_capabilities vht_cap;
78d35b16 3561 struct ieee80211_he_capabilities he_cap;
0e3bd7ac 3562 int set = 1;
3f81ac07
AO
3563
3564 /*
3565 * Remove the STA entry to ensure the STA PS state gets cleared and
3566 * configuration gets updated. This is relevant for cases, such as
3567 * FT-over-the-DS, where a station re-associates back to the same AP but
3568 * skips the authentication flow, or if working with a driver that
3569 * does not support full AP client state.
0e3bd7ac
MV
3570 *
3571 * Skip this if the STA has already completed FT reassociation and the
3572 * TK has been configured since the TX/RX PN must not be reset to 0 for
3573 * the same key.
4cf5efec
JM
3574 *
3575 * FT-over-the-DS has a special case where the STA entry (and as such,
3576 * the TK) has not yet been configured to the driver depending on which
3577 * driver interface is used. For that case, allow add-STA operation to
3578 * be used (instead of set-STA). This is needed to allow mac80211-based
3579 * drivers to accept the STA parameter configuration. Since this is
3580 * after a new FT-over-DS exchange, a new TK has been derived, so key
3581 * reinstallation is not a concern for this case.
3f81ac07 3582 */
4cf5efec
JM
3583 wpa_printf(MSG_DEBUG, "Add associated STA " MACSTR
3584 " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
3585 MAC2STR(sta->addr), sta->added_unassoc, sta->auth_alg,
3586 sta->ft_over_ds, reassoc,
3587 !!(sta->flags & WLAN_STA_AUTHORIZED),
3588 wpa_auth_sta_ft_tk_already_set(sta->wpa_sm),
3589 wpa_auth_sta_fils_tk_already_set(sta->wpa_sm));
3590
0e3bd7ac
MV
3591 if (!sta->added_unassoc &&
3592 (!(sta->flags & WLAN_STA_AUTHORIZED) ||
4cf5efec 3593 (reassoc && sta->ft_over_ds && sta->auth_alg == WLAN_AUTH_FT) ||
2f1357fb
JM
3594 (!wpa_auth_sta_ft_tk_already_set(sta->wpa_sm) &&
3595 !wpa_auth_sta_fils_tk_already_set(sta->wpa_sm)))) {
3f81ac07 3596 hostapd_drv_sta_remove(hapd, sta->addr);
0e3bd7ac
MV
3597 wpa_auth_sm_event(sta->wpa_sm, WPA_DRV_STA_REMOVED);
3598 set = 0;
4cf5efec
JM
3599
3600 /* Do not allow the FT-over-DS exception to be used more than
3601 * once per authentication exchange to guarantee a new TK is
3602 * used here */
3603 sta->ft_over_ds = 0;
0e3bd7ac 3604 }
3f81ac07
AO
3605
3606#ifdef CONFIG_IEEE80211N
3607 if (sta->flags & WLAN_STA_HT)
3608 hostapd_get_ht_capab(hapd, sta->ht_capabilities, &ht_cap);
3609#endif /* CONFIG_IEEE80211N */
3610#ifdef CONFIG_IEEE80211AC
3611 if (sta->flags & WLAN_STA_VHT)
3612 hostapd_get_vht_capab(hapd, sta->vht_capabilities, &vht_cap);
3613#endif /* CONFIG_IEEE80211AC */
78d35b16
JC
3614#ifdef CONFIG_IEEE80211AX
3615 if (sta->flags & WLAN_STA_HE) {
3616 hostapd_get_he_capab(hapd, sta->he_capab, &he_cap,
3617 sta->he_capab_len);
3618 }
3619#endif /* CONFIG_IEEE80211AX */
3f81ac07
AO
3620
3621 /*
3622 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
3623 * will be set when the ACK frame for the (Re)Association Response frame
3624 * is processed (TX status driver event).
3625 */
3626 if (hostapd_sta_add(hapd, sta->addr, sta->aid, sta->capability,
3627 sta->supported_rates, sta->supported_rates_len,
3628 sta->listen_interval,
3629 sta->flags & WLAN_STA_HT ? &ht_cap : NULL,
3630 sta->flags & WLAN_STA_VHT ? &vht_cap : NULL,
78d35b16
JC
3631 sta->flags & WLAN_STA_HE ? &he_cap : NULL,
3632 sta->flags & WLAN_STA_HE ? sta->he_capab_len : 0,
3f81ac07 3633 sta->flags | WLAN_STA_ASSOC, sta->qosinfo,
ae33239c 3634 sta->vht_opmode, sta->p2p_ie ? 1 : 0,
0e3bd7ac 3635 set)) {
3f81ac07
AO
3636 hostapd_logger(hapd, sta->addr,
3637 HOSTAPD_MODULE_IEEE80211, HOSTAPD_LEVEL_NOTICE,
3638 "Could not %s STA to kernel driver",
0e3bd7ac 3639 set ? "set" : "add");
3f81ac07
AO
3640
3641 if (sta->added_unassoc) {
3642 hostapd_drv_sta_remove(hapd, sta->addr);
3643 sta->added_unassoc = 0;
3644 }
3645
3646 return -1;
3647 }
3648
3649 sta->added_unassoc = 0;
3650
3651 return 0;
3652}
3653
3654
bb598c3b 3655static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
05e5e615 3656 const u8 *addr, u16 status_code, int reassoc,
076f1ea1 3657 const u8 *ies, size_t ies_len, int rssi)
5586f500
JM
3658{
3659 int send_len;
91d91abf
JM
3660 u8 *buf;
3661 size_t buflen;
5586f500
JM
3662 struct ieee80211_mgmt *reply;
3663 u8 *p;
91d91abf 3664 u16 res = WLAN_STATUS_SUCCESS;
5586f500 3665
91d91abf
JM
3666 buflen = sizeof(struct ieee80211_mgmt) + 1024;
3667#ifdef CONFIG_FILS
84bb12aa 3668 if (sta && sta->fils_hlp_resp)
91d91abf 3669 buflen += wpabuf_len(sta->fils_hlp_resp);
831d8c9c
JM
3670 if (sta)
3671 buflen += 150;
91d91abf 3672#endif /* CONFIG_FILS */
09368515
JM
3673#ifdef CONFIG_OWE
3674 if (sta && (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE))
d8c8d857 3675 buflen += 150;
09368515 3676#endif /* CONFIG_OWE */
10ec6a5f
JM
3677#ifdef CONFIG_DPP2
3678 if (sta && sta->dpp_pfs)
3679 buflen += 5 + sta->dpp_pfs->curve->prime_len;
3680#endif /* CONFIG_DPP2 */
91d91abf
JM
3681 buf = os_zalloc(buflen);
3682 if (!buf) {
3683 res = WLAN_STATUS_UNSPECIFIED_FAILURE;
3684 goto done;
3685 }
5586f500
JM
3686 reply = (struct ieee80211_mgmt *) buf;
3687 reply->frame_control =
3688 IEEE80211_FC(WLAN_FC_TYPE_MGMT,
3689 (reassoc ? WLAN_FC_STYPE_REASSOC_RESP :
3690 WLAN_FC_STYPE_ASSOC_RESP));
05e5e615 3691 os_memcpy(reply->da, addr, ETH_ALEN);
5586f500
JM
3692 os_memcpy(reply->sa, hapd->own_addr, ETH_ALEN);
3693 os_memcpy(reply->bssid, hapd->own_addr, ETH_ALEN);
3694
3695 send_len = IEEE80211_HDRLEN;
3696 send_len += sizeof(reply->u.assoc_resp);
3697 reply->u.assoc_resp.capab_info =
f41ded6f 3698 host_to_le16(hostapd_own_capab_info(hapd));
5586f500 3699 reply->u.assoc_resp.status_code = host_to_le16(status_code);
05e5e615
DL
3700
3701 reply->u.assoc_resp.aid = host_to_le16((sta ? sta->aid : 0) |
3702 BIT(14) | BIT(15));
5586f500
JM
3703 /* Supported rates */
3704 p = hostapd_eid_supp_rates(hapd, reply->u.assoc_resp.variable);
3705 /* Extended supported rates */
3706 p = hostapd_eid_ext_supp_rates(hapd, p);
5586f500 3707
96a2a9a8
MT
3708 /* Radio measurement capabilities */
3709 p = hostapd_eid_rm_enabled_capab(hapd, p, buf + buflen - p);
3710
076f1ea1
BL
3711#ifdef CONFIG_MBO
3712 if (status_code == WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS &&
3713 rssi != 0) {
3714 int delta = hapd->iconf->rssi_reject_assoc_rssi - rssi;
3715
3716 p = hostapd_eid_mbo_rssi_assoc_rej(hapd, p, buf + buflen - p,
3717 delta);
3718 }
3719#endif /* CONFIG_MBO */
3720
4ec1fd8e 3721#ifdef CONFIG_IEEE80211R_AP
05e5e615 3722 if (sta && status_code == WLAN_STATUS_SUCCESS) {
5586f500
JM
3723 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
3724 * Transition Information, RSN, [RIC Response] */
3725 p = wpa_sm_write_assoc_resp_ies(sta->wpa_sm, p,
91d91abf 3726 buf + buflen - p,
5586f500 3727 sta->auth_alg, ies, ies_len);
2cf36d60
JM
3728 if (!p) {
3729 wpa_printf(MSG_DEBUG,
3730 "FT: Failed to write AssocResp IEs");
3731 res = WLAN_STATUS_UNSPECIFIED_FAILURE;
3732 goto done;
3733 }
5586f500 3734 }
4ec1fd8e 3735#endif /* CONFIG_IEEE80211R_AP */
831d8c9c
JM
3736#ifdef CONFIG_FILS
3737 if (sta && status_code == WLAN_STATUS_SUCCESS &&
3738 (sta->auth_alg == WLAN_AUTH_FILS_SK ||
3739 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
3740 sta->auth_alg == WLAN_AUTH_FILS_PK))
3741 p = wpa_auth_write_assoc_resp_fils(sta->wpa_sm, p,
3742 buf + buflen - p,
3743 ies, ies_len);
3744#endif /* CONFIG_FILS */
5586f500 3745
d8c8d857 3746#ifdef CONFIG_OWE
8fc6d884
JM
3747 if (sta && status_code == WLAN_STATUS_SUCCESS &&
3748 (hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE))
d8c8d857
JM
3749 p = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, p,
3750 buf + buflen - p,
3751 ies, ies_len);
3752#endif /* CONFIG_OWE */
3753
05e5e615 3754 if (sta && status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY)
5586f500 3755 p = hostapd_eid_assoc_comeback_time(hapd, sta, p);
5586f500 3756
1bc774a1
JM
3757#ifdef CONFIG_IEEE80211N
3758 p = hostapd_eid_ht_capabilities(hapd, p);
3759 p = hostapd_eid_ht_operation(hapd, p);
3760#endif /* CONFIG_IEEE80211N */
3761
14708b50 3762#ifdef CONFIG_IEEE80211AC
49e95ee1
AO
3763 if (hapd->iconf->ieee80211ac && !hapd->conf->disable_11ac &&
3764 !is_6ghz_op_class(hapd->iconf->op_class)) {
fc72a48a
T
3765 u32 nsts = 0, sta_nsts;
3766
05e5e615 3767 if (sta && hapd->conf->use_sta_nsts && sta->vht_capabilities) {
fc72a48a
T
3768 struct ieee80211_vht_capabilities *capa;
3769
3770 nsts = (hapd->iface->conf->vht_capab >>
3771 VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
3772 capa = sta->vht_capabilities;
3773 sta_nsts = (le_to_host32(capa->vht_capabilities_info) >>
3774 VHT_CAP_BEAMFORMEE_STS_OFFSET) & 7;
3775
3776 if (nsts < sta_nsts)
3777 nsts = 0;
3778 else
3779 nsts = sta_nsts;
3780 }
3781 p = hostapd_eid_vht_capabilities(hapd, p, nsts);
e7d0e97b
YL
3782 p = hostapd_eid_vht_operation(hapd, p);
3783 }
14708b50
MP
3784#endif /* CONFIG_IEEE80211AC */
3785
78d35b16
JC
3786#ifdef CONFIG_IEEE80211AX
3787 if (hapd->iconf->ieee80211ax) {
29d8bd1d 3788 p = hostapd_eid_he_capab(hapd, p, IEEE80211_MODE_AP);
78d35b16
JC
3789 p = hostapd_eid_he_operation(hapd, p);
3790 p = hostapd_eid_spatial_reuse(hapd, p);
3791 p = hostapd_eid_he_mu_edca_parameter_set(hapd, p);
3792 }
3793#endif /* CONFIG_IEEE80211AX */
3794
1161ff1e 3795 p = hostapd_eid_ext_capab(hapd, p);
b6668734 3796 p = hostapd_eid_bss_max_idle_period(hapd, p);
05e5e615 3797 if (sta && sta->qos_map_enabled)
c551700f 3798 p = hostapd_eid_qos_map_set(hapd, p);
1161ff1e 3799
347827ff
AN
3800#ifdef CONFIG_FST
3801 if (hapd->iface->fst_ies) {
3802 os_memcpy(p, wpabuf_head(hapd->iface->fst_ies),
3803 wpabuf_len(hapd->iface->fst_ies));
3804 p += wpabuf_len(hapd->iface->fst_ies);
3805 }
3806#endif /* CONFIG_FST */
3807
cb992597
JM
3808 p = hostapd_eid_rsnxe(hapd, p, buf + buflen - p);
3809
b750dde6
JM
3810#ifdef CONFIG_OWE
3811 if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_OWE) &&
3812 sta && sta->owe_ecdh && status_code == WLAN_STATUS_SUCCESS &&
3813 wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_OWE) {
3814 struct wpabuf *pub;
3815
3816 pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
3817 if (!pub) {
3818 res = WLAN_STATUS_UNSPECIFIED_FAILURE;
3819 goto done;
3820 }
3821 /* OWE Diffie-Hellman Parameter element */
3822 *p++ = WLAN_EID_EXTENSION; /* Element ID */
3823 *p++ = 1 + 2 + wpabuf_len(pub); /* Length */
3824 *p++ = WLAN_EID_EXT_OWE_DH_PARAM; /* Element ID Extension */
3825 WPA_PUT_LE16(p, sta->owe_group);
3826 p += 2;
3827 os_memcpy(p, wpabuf_head(pub), wpabuf_len(pub));
3828 p += wpabuf_len(pub);
3829 wpabuf_free(pub);
3830 }
3831#endif /* CONFIG_OWE */
3832
10ec6a5f
JM
3833#ifdef CONFIG_DPP2
3834 if ((hapd->conf->wpa_key_mgmt & WPA_KEY_MGMT_DPP) &&
3835 sta && sta->dpp_pfs && status_code == WLAN_STATUS_SUCCESS &&
3836 wpa_auth_sta_key_mgmt(sta->wpa_sm) == WPA_KEY_MGMT_DPP) {
3837 os_memcpy(p, wpabuf_head(sta->dpp_pfs->ie),
3838 wpabuf_len(sta->dpp_pfs->ie));
3839 p += wpabuf_len(sta->dpp_pfs->ie);
3840 }
3841#endif /* CONFIG_DPP2 */
3842
e7d0e97b 3843#ifdef CONFIG_IEEE80211AC
05e5e615 3844 if (sta && hapd->conf->vendor_vht && (sta->flags & WLAN_STA_VENDOR_VHT))
e7d0e97b
YL
3845 p = hostapd_eid_vendor_vht(hapd, p);
3846#endif /* CONFIG_IEEE80211AC */
3847
05e5e615 3848 if (sta && (sta->flags & WLAN_STA_WMM))
1bc774a1
JM
3849 p = hostapd_eid_wmm(hapd, p);
3850
ed7a09f9 3851#ifdef CONFIG_WPS
05e5e615
DL
3852 if (sta &&
3853 ((sta->flags & WLAN_STA_WPS) ||
3854 ((sta->flags & WLAN_STA_MAYBE_WPS) && hapd->conf->wpa))) {
ed7a09f9
JM
3855 struct wpabuf *wps = wps_build_assoc_resp_ie();
3856 if (wps) {
3857 os_memcpy(p, wpabuf_head(wps), wpabuf_len(wps));
3858 p += wpabuf_len(wps);
3859 wpabuf_free(wps);
3860 }
3861 }
3862#endif /* CONFIG_WPS */
3863
9c06f0f6
VN
3864 if (sta && (sta->flags & WLAN_STA_MULTI_AP))
3865 p = hostapd_eid_multi_ap(hapd, p);
3866
8ccbe415 3867#ifdef CONFIG_P2P
05e5e615 3868 if (sta && sta->p2p_ie && hapd->p2p_group) {
8ccbe415
JM
3869 struct wpabuf *p2p_resp_ie;
3870 enum p2p_status_code status;
3871 switch (status_code) {
3872 case WLAN_STATUS_SUCCESS:
3873 status = P2P_SC_SUCCESS;
3874 break;
3875 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA:
3876 status = P2P_SC_FAIL_LIMIT_REACHED;
3877 break;
3878 default:
3879 status = P2P_SC_FAIL_INVALID_PARAMS;
3880 break;
3881 }
3882 p2p_resp_ie = p2p_group_assoc_resp_ie(hapd->p2p_group, status);
3883 if (p2p_resp_ie) {
3884 os_memcpy(p, wpabuf_head(p2p_resp_ie),
3885 wpabuf_len(p2p_resp_ie));
3886 p += wpabuf_len(p2p_resp_ie);
3887 wpabuf_free(p2p_resp_ie);
3888 }
3889 }
3890#endif /* CONFIG_P2P */
3891
962473c1
JM
3892#ifdef CONFIG_P2P_MANAGER
3893 if (hapd->conf->p2p & P2P_MANAGE)
3894 p = hostapd_eid_p2p_manage(hapd, p);
3895#endif /* CONFIG_P2P_MANAGER */
3896
91d91abf 3897 p = hostapd_eid_mbo(hapd, p, buf + buflen - p);
fb9a1c3e 3898
a9112270 3899 if (hapd->conf->assocresp_elements &&
91d91abf 3900 (size_t) (buf + buflen - p) >=
a9112270
BKB
3901 wpabuf_len(hapd->conf->assocresp_elements)) {
3902 os_memcpy(p, wpabuf_head(hapd->conf->assocresp_elements),
3903 wpabuf_len(hapd->conf->assocresp_elements));
3904 p += wpabuf_len(hapd->conf->assocresp_elements);
3905 }
3906
5586f500
JM
3907 send_len += p - reply->u.assoc_resp.variable;
3908
e73ffa09 3909#ifdef CONFIG_FILS
05e5e615
DL
3910 if (sta &&
3911 (sta->auth_alg == WLAN_AUTH_FILS_SK ||
e73ffa09
JM
3912 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
3913 sta->auth_alg == WLAN_AUTH_FILS_PK) &&
3914 status_code == WLAN_STATUS_SUCCESS) {
3915 struct ieee802_11_elems elems;
3916
3917 if (ieee802_11_parse_elems(ies, ies_len, &elems, 0) ==
91d91abf
JM
3918 ParseFailed || !elems.fils_session) {
3919 res = WLAN_STATUS_UNSPECIFIED_FAILURE;
3920 goto done;
3921 }
e73ffa09
JM
3922
3923 /* FILS Session */
3924 *p++ = WLAN_EID_EXTENSION; /* Element ID */
3925 *p++ = 1 + FILS_SESSION_LEN; /* Length */
3926 *p++ = WLAN_EID_EXT_FILS_SESSION; /* Element ID Extension */
3927 os_memcpy(p, elems.fils_session, FILS_SESSION_LEN);
3928 send_len += 2 + 1 + FILS_SESSION_LEN;
3929
3930 send_len = fils_encrypt_assoc(sta->wpa_sm, buf, send_len,
91d91abf
JM
3931 buflen, sta->fils_hlp_resp);
3932 if (send_len < 0) {
3933 res = WLAN_STATUS_UNSPECIFIED_FAILURE;
3934 goto done;
3935 }
e73ffa09
JM
3936 }
3937#endif /* CONFIG_FILS */
3938
37100274 3939 if (hostapd_drv_send_mlme(hapd, reply, send_len, 0, NULL, 0, 0) < 0) {
5586f500
JM
3940 wpa_printf(MSG_INFO, "Failed to send assoc resp: %s",
3941 strerror(errno));
91d91abf 3942 res = WLAN_STATUS_UNSPECIFIED_FAILURE;
bb598c3b
AB
3943 }
3944
91d91abf
JM
3945done:
3946 os_free(buf);
3947 return res;
5586f500
JM
3948}
3949
3950
33c8bbd8 3951#ifdef CONFIG_OWE
79ce2d51
AP
3952u8 * owe_assoc_req_process(struct hostapd_data *hapd, struct sta_info *sta,
3953 const u8 *owe_dh, u8 owe_dh_len,
e7d8842e 3954 u8 *owe_buf, size_t owe_buf_len, u16 *status)
33c8bbd8 3955{
a22e235f
AP
3956#ifdef CONFIG_TESTING_OPTIONS
3957 if (hapd->conf->own_ie_override) {
3958 wpa_printf(MSG_DEBUG, "OWE: Using IE override");
e7d8842e 3959 *status = WLAN_STATUS_SUCCESS;
a22e235f
AP
3960 return wpa_auth_write_assoc_resp_owe(sta->wpa_sm, owe_buf,
3961 owe_buf_len, NULL, 0);
3962 }
3963#endif /* CONFIG_TESTING_OPTIONS */
3964
cd483be2
AP
3965 if (wpa_auth_sta_get_pmksa(sta->wpa_sm)) {
3966 wpa_printf(MSG_DEBUG, "OWE: Using PMKSA caching");
3967 owe_buf = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, owe_buf,
3968 owe_buf_len, NULL, 0);
e7d8842e 3969 *status = WLAN_STATUS_SUCCESS;
ef60f012
LD
3970 return owe_buf;
3971 }
3972
3973 if (sta->owe_pmk && sta->external_dh_updated) {
3974 wpa_printf(MSG_DEBUG, "OWE: Using previously derived PMK");
e7d8842e 3975 *status = WLAN_STATUS_SUCCESS;
cd483be2
AP
3976 return owe_buf;
3977 }
3978
e7d8842e
SM
3979 *status = owe_process_assoc_req(hapd, sta, owe_dh, owe_dh_len);
3980 if (*status != WLAN_STATUS_SUCCESS)
33c8bbd8 3981 return NULL;
33c8bbd8 3982
af65ef28
AP
3983 owe_buf = wpa_auth_write_assoc_resp_owe(sta->wpa_sm, owe_buf,
3984 owe_buf_len, NULL, 0);
3985
f5701cc6 3986 if (sta->owe_ecdh && owe_buf) {
759da93a
AP
3987 struct wpabuf *pub;
3988
3989 pub = crypto_ecdh_get_pubkey(sta->owe_ecdh, 0);
3990 if (!pub) {
e7d8842e 3991 *status = WLAN_STATUS_UNSPECIFIED_FAILURE;
759da93a
AP
3992 return owe_buf;
3993 }
3994
3995 /* OWE Diffie-Hellman Parameter element */
3996 *owe_buf++ = WLAN_EID_EXTENSION; /* Element ID */
3997 *owe_buf++ = 1 + 2 + wpabuf_len(pub); /* Length */
3998 *owe_buf++ = WLAN_EID_EXT_OWE_DH_PARAM; /* Element ID Extension
3999 */
4000 WPA_PUT_LE16(owe_buf, sta->owe_group);
4001 owe_buf += 2;
4002 os_memcpy(owe_buf, wpabuf_head(pub), wpabuf_len(pub));
4003 owe_buf += wpabuf_len(pub);
4004 wpabuf_free(pub);
4005 }
4006
33c8bbd8
AKP
4007 return owe_buf;
4008}
4009#endif /* CONFIG_OWE */
4010
4011
91d91abf
JM
4012#ifdef CONFIG_FILS
4013
4014void fils_hlp_finish_assoc(struct hostapd_data *hapd, struct sta_info *sta)
4015{
4016 u16 reply_res;
4017
4018 wpa_printf(MSG_DEBUG, "FILS: Finish association with " MACSTR,
4019 MAC2STR(sta->addr));
4020 eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
4021 if (!sta->fils_pending_assoc_req)
4022 return;
4023 reply_res = send_assoc_resp(hapd, sta, sta->addr, WLAN_STATUS_SUCCESS,
4024 sta->fils_pending_assoc_is_reassoc,
4025 sta->fils_pending_assoc_req,
076f1ea1 4026 sta->fils_pending_assoc_req_len, 0);
91d91abf
JM
4027 os_free(sta->fils_pending_assoc_req);
4028 sta->fils_pending_assoc_req = NULL;
4029 sta->fils_pending_assoc_req_len = 0;
4030 wpabuf_free(sta->fils_hlp_resp);
4031 sta->fils_hlp_resp = NULL;
4032 wpabuf_free(sta->hlp_dhcp_discover);
4033 sta->hlp_dhcp_discover = NULL;
4034
4035 /*
fd35ed5b
IP
4036 * Remove the station in case transmission of a success response fails.
4037 * At this point the station was already added associated to the driver.
91d91abf 4038 */
fd35ed5b 4039 if (reply_res != WLAN_STATUS_SUCCESS)
91d91abf 4040 hostapd_drv_sta_remove(hapd, sta->addr);
91d91abf
JM
4041}
4042
4043
4044void fils_hlp_timeout(void *eloop_ctx, void *eloop_data)
4045{
4046 struct hostapd_data *hapd = eloop_ctx;
4047 struct sta_info *sta = eloop_data;
4048
4049 wpa_printf(MSG_DEBUG,
4050 "FILS: HLP response timeout - continue with association response for "
4051 MACSTR, MAC2STR(sta->addr));
8b5ddda5
JM
4052 if (sta->fils_drv_assoc_finish)
4053 hostapd_notify_assoc_fils_finish(hapd, sta);
4054 else
4055 fils_hlp_finish_assoc(hapd, sta);
91d91abf
JM
4056}
4057
4058#endif /* CONFIG_FILS */
4059
4060
5586f500 4061static void handle_assoc(struct hostapd_data *hapd,
b57e086c 4062 const struct ieee80211_mgmt *mgmt, size_t len,
076f1ea1 4063 int reassoc, int rssi)
5586f500 4064{
38cb0a2d 4065 u16 capab_info, listen_interval, seq_ctrl, fc;
bb598c3b 4066 u16 resp = WLAN_STATUS_SUCCESS, reply_res;
b57e086c 4067 const u8 *pos;
5586f500
JM
4068 int left, i;
4069 struct sta_info *sta;
78815f3d 4070 u8 *tmp = NULL;
91d91abf
JM
4071#ifdef CONFIG_FILS
4072 int delay_assoc = 0;
4073#endif /* CONFIG_FILS */
5586f500
JM
4074
4075 if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_req) :
4076 sizeof(mgmt->u.assoc_req))) {
61323e70
JM
4077 wpa_printf(MSG_INFO, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
4078 reassoc, (unsigned long) len);
5586f500
JM
4079 return;
4080 }
4081
c2aff6b1
JB
4082#ifdef CONFIG_TESTING_OPTIONS
4083 if (reassoc) {
06df2aa6 4084 if (hapd->iconf->ignore_reassoc_probability > 0.0 &&
c2aff6b1
JB
4085 drand48() < hapd->iconf->ignore_reassoc_probability) {
4086 wpa_printf(MSG_INFO,
4087 "TESTING: ignoring reassoc request from "
4088 MACSTR, MAC2STR(mgmt->sa));
4089 return;
4090 }
4091 } else {
06df2aa6 4092 if (hapd->iconf->ignore_assoc_probability > 0.0 &&
c2aff6b1
JB
4093 drand48() < hapd->iconf->ignore_assoc_probability) {
4094 wpa_printf(MSG_INFO,
4095 "TESTING: ignoring assoc request from "
4096 MACSTR, MAC2STR(mgmt->sa));
4097 return;
4098 }
4099 }
4100#endif /* CONFIG_TESTING_OPTIONS */
4101
38cb0a2d
IP
4102 fc = le_to_host16(mgmt->frame_control);
4103 seq_ctrl = le_to_host16(mgmt->seq_ctrl);
4104
5586f500
JM
4105 if (reassoc) {
4106 capab_info = le_to_host16(mgmt->u.reassoc_req.capab_info);
4107 listen_interval = le_to_host16(
4108 mgmt->u.reassoc_req.listen_interval);
4109 wpa_printf(MSG_DEBUG, "reassociation request: STA=" MACSTR
4110 " capab_info=0x%02x listen_interval=%d current_ap="
38cb0a2d 4111 MACSTR " seq_ctrl=0x%x%s",
5586f500 4112 MAC2STR(mgmt->sa), capab_info, listen_interval,
38cb0a2d
IP
4113 MAC2STR(mgmt->u.reassoc_req.current_ap),
4114 seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
5586f500
JM
4115 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.reassoc_req));
4116 pos = mgmt->u.reassoc_req.variable;
4117 } else {
4118 capab_info = le_to_host16(mgmt->u.assoc_req.capab_info);
4119 listen_interval = le_to_host16(
4120 mgmt->u.assoc_req.listen_interval);
4121 wpa_printf(MSG_DEBUG, "association request: STA=" MACSTR
38cb0a2d
IP
4122 " capab_info=0x%02x listen_interval=%d "
4123 "seq_ctrl=0x%x%s",
4124 MAC2STR(mgmt->sa), capab_info, listen_interval,
4125 seq_ctrl, (fc & WLAN_FC_RETRY) ? " retry" : "");
5586f500
JM
4126 left = len - (IEEE80211_HDRLEN + sizeof(mgmt->u.assoc_req));
4127 pos = mgmt->u.assoc_req.variable;
4128 }
4129
4130 sta = ap_get_sta(hapd, mgmt->sa);
4ec1fd8e 4131#ifdef CONFIG_IEEE80211R_AP
5586f500
JM
4132 if (sta && sta->auth_alg == WLAN_AUTH_FT &&
4133 (sta->flags & WLAN_STA_AUTH) == 0) {
4134 wpa_printf(MSG_DEBUG, "FT: Allow STA " MACSTR " to associate "
4135 "prior to authentication since it is using "
4136 "over-the-DS FT", MAC2STR(mgmt->sa));
bb598c3b
AB
4137
4138 /*
4139 * Mark station as authenticated, to avoid adding station
4140 * entry in the driver as associated and not authenticated
4141 */
4142 sta->flags |= WLAN_STA_AUTH;
5586f500 4143 } else
4ec1fd8e 4144#endif /* CONFIG_IEEE80211R_AP */
5586f500 4145 if (sta == NULL || (sta->flags & WLAN_STA_AUTH) == 0) {
05e5e615
DL
4146 if (hapd->iface->current_mode &&
4147 hapd->iface->current_mode->mode ==
4148 HOSTAPD_MODE_IEEE80211AD) {
53d17144 4149 int acl_res;
96368172 4150 struct radius_sta info;
53d17144 4151
29024efd
MB
4152 acl_res = ieee802_11_allowed_address(hapd, mgmt->sa,
4153 (const u8 *) mgmt,
b0621b08 4154 len, &info);
53d17144 4155 if (acl_res == HOSTAPD_ACL_REJECT) {
92eb00ae
T
4156 wpa_msg(hapd->msg_ctx, MSG_DEBUG,
4157 "Ignore Association Request frame from "
4158 MACSTR " due to ACL reject",
4159 MAC2STR(mgmt->sa));
53d17144
DL
4160 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
4161 goto fail;
4162 }
4163 if (acl_res == HOSTAPD_ACL_PENDING)
4164 return;
4165
05e5e615
DL
4166 /* DMG/IEEE 802.11ad does not use authentication.
4167 * Allocate sta entry upon association. */
4168 sta = ap_sta_add(hapd, mgmt->sa);
4169 if (!sta) {
4170 hostapd_logger(hapd, mgmt->sa,
4171 HOSTAPD_MODULE_IEEE80211,
4172 HOSTAPD_LEVEL_INFO,
4173 "Failed to add STA");
4174 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
4175 goto fail;
4176 }
4177
53d17144 4178 acl_res = ieee802_11_set_radius_info(
29024efd 4179 hapd, sta, acl_res, &info);
53d17144
DL
4180 if (acl_res) {
4181 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
4182 goto fail;
4183 }
4184
05e5e615
DL
4185 hostapd_logger(hapd, sta->addr,
4186 HOSTAPD_MODULE_IEEE80211,
4187 HOSTAPD_LEVEL_DEBUG,
4188 "Skip authentication for DMG/IEEE 802.11ad");
4189 sta->flags |= WLAN_STA_AUTH;
4190 wpa_auth_sm_event(sta->wpa_sm, WPA_AUTH);
4191 sta->auth_alg = WLAN_AUTH_OPEN;
4192 } else {
4193 hostapd_logger(hapd, mgmt->sa,
4194 HOSTAPD_MODULE_IEEE80211,
4195 HOSTAPD_LEVEL_INFO,
4196 "Station tried to associate before authentication (aid=%d flags=0x%x)",
4197 sta ? sta->aid : -1,
4198 sta ? sta->flags : 0);
4199 send_deauth(hapd, mgmt->sa,
4200 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
4201 return;
4202 }
5586f500
JM
4203 }
4204
38cb0a2d
IP
4205 if ((fc & WLAN_FC_RETRY) &&
4206 sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
4207 sta->last_seq_ctrl == seq_ctrl &&
fa67debf
JM
4208 sta->last_subtype == (reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
4209 WLAN_FC_STYPE_ASSOC_REQ)) {
38cb0a2d
IP
4210 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4211 HOSTAPD_LEVEL_DEBUG,
4212 "Drop repeated association frame seq_ctrl=0x%x",
4213 seq_ctrl);
4214 return;
4215 }
4216 sta->last_seq_ctrl = seq_ctrl;
4217 sta->last_subtype = reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
4218 WLAN_FC_STYPE_ASSOC_REQ;
4219
5586f500 4220 if (hapd->tkip_countermeasures) {
fe12ae77 4221 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
5586f500
JM
4222 goto fail;
4223 }
4224
4225 if (listen_interval > hapd->conf->max_listen_interval) {
4226 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
4227 HOSTAPD_LEVEL_DEBUG,
4228 "Too large Listen Interval (%d)",
4229 listen_interval);
4230 resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
4231 goto fail;
4232 }
4233
fb9a1c3e
AS
4234#ifdef CONFIG_MBO
4235 if (hapd->conf->mbo_enabled && hapd->mbo_assoc_disallow) {
4236 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
4237 goto fail;
4238 }
076f1ea1
BL
4239
4240 if (hapd->iconf->rssi_reject_assoc_rssi && rssi &&
2ea1fce3
JM
4241 rssi < hapd->iconf->rssi_reject_assoc_rssi &&
4242 (sta->auth_rssi == 0 ||
4243 sta->auth_rssi < hapd->iconf->rssi_reject_assoc_rssi)) {
076f1ea1
BL
4244 resp = WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS;
4245 goto fail;
4246 }
fb9a1c3e
AS
4247#endif /* CONFIG_MBO */
4248
629e1804
DS
4249 /*
4250 * sta->capability is used in check_assoc_ies() for RRM enabled
4251 * capability element.
4252 */
4253 sta->capability = capab_info;
4254
78815f3d
JM
4255#ifdef CONFIG_FILS
4256 if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
4257 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
4258 sta->auth_alg == WLAN_AUTH_FILS_PK) {
1489fcf8
JM
4259 int res;
4260
78815f3d
JM
4261 /* The end of the payload is encrypted. Need to decrypt it
4262 * before parsing. */
4263
a1f11e34 4264 tmp = os_memdup(pos, left);
78815f3d
JM
4265 if (!tmp) {
4266 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
4267 goto fail;
4268 }
78815f3d 4269
1489fcf8
JM
4270 res = fils_decrypt_assoc(sta->wpa_sm, sta->fils_session, mgmt,
4271 len, tmp, left);
4272 if (res < 0) {
78815f3d
JM
4273 resp = WLAN_STATUS_UNSPECIFIED_FAILURE;
4274 goto fail;
4275 }
4276 pos = tmp;
1489fcf8 4277 left = res;
78815f3d
JM
4278 }
4279#endif /* CONFIG_FILS */
4280
5586f500
JM
4281 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
4282 * is used */
4283 resp = check_assoc_ies(hapd, sta, pos, left, reassoc);
4284 if (resp != WLAN_STATUS_SUCCESS)
4285 goto fail;
4286
4287 if (hostapd_get_aid(hapd, sta) < 0) {
4288 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
4289 HOSTAPD_LEVEL_INFO, "No room for more AIDs");
4290 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
4291 goto fail;
4292 }
4293
5586f500
JM
4294 sta->listen_interval = listen_interval;
4295
28d12641
AKP
4296 if (hapd->iface->current_mode &&
4297 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G)
6fc6879b
JM
4298 sta->flags |= WLAN_STA_NONERP;
4299 for (i = 0; i < sta->supported_rates_len; i++) {
4300 if ((sta->supported_rates[i] & 0x7f) > 22) {
4301 sta->flags &= ~WLAN_STA_NONERP;
4302 break;
4303 }
4304 }
4305 if (sta->flags & WLAN_STA_NONERP && !sta->nonerp_set) {
4306 sta->nonerp_set = 1;
4307 hapd->iface->num_sta_non_erp++;
4308 if (hapd->iface->num_sta_non_erp == 1)
4309 ieee802_11_set_beacons(hapd->iface);
4310 }
4311
4312 if (!(sta->capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) &&
4313 !sta->no_short_slot_time_set) {
4314 sta->no_short_slot_time_set = 1;
4315 hapd->iface->num_sta_no_short_slot_time++;
28d12641
AKP
4316 if (hapd->iface->current_mode &&
4317 hapd->iface->current_mode->mode ==
6fc6879b
JM
4318 HOSTAPD_MODE_IEEE80211G &&
4319 hapd->iface->num_sta_no_short_slot_time == 1)
4320 ieee802_11_set_beacons(hapd->iface);
4321 }
4322
4323 if (sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
4324 sta->flags |= WLAN_STA_SHORT_PREAMBLE;
4325 else
4326 sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
4327
4328 if (!(sta->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
4329 !sta->no_short_preamble_set) {
4330 sta->no_short_preamble_set = 1;
4331 hapd->iface->num_sta_no_short_preamble++;
28d12641
AKP
4332 if (hapd->iface->current_mode &&
4333 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211G
6fc6879b
JM
4334 && hapd->iface->num_sta_no_short_preamble == 1)
4335 ieee802_11_set_beacons(hapd->iface);
4336 }
4337
d45354be 4338#ifdef CONFIG_IEEE80211N
5586f500 4339 update_ht_state(hapd, sta);
d45354be 4340#endif /* CONFIG_IEEE80211N */
de9289c8 4341
6fc6879b
JM
4342 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4343 HOSTAPD_LEVEL_DEBUG,
4344 "association OK (aid %d)", sta->aid);
4345 /* Station will be marked associated, after it acknowledges AssocResp
4346 */
b8281964 4347 sta->flags |= WLAN_STA_ASSOC_REQ_OK;
6fc6879b 4348
6f5c8dbd
JM
4349 if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) {
4350 wpa_printf(MSG_DEBUG, "Allowing %sassociation after timed out "
4351 "SA Query procedure", reassoc ? "re" : "");
4352 /* TODO: Send a protected Disassociate frame to the STA using
4353 * the old key and Reason Code "Previous Authentication no
4354 * longer valid". Make sure this is only sent protected since
4355 * unprotected frame would be received by the STA that is now
4356 * trying to associate.
4357 */
4358 }
6f5c8dbd 4359
6fc6879b
JM
4360 /* Make sure that the previously registered inactivity timer will not
4361 * remove the STA immediately. */
4362 sta->timeout_next = STA_NULLFUNC;
4363
04059ab8
DG
4364#ifdef CONFIG_TAXONOMY
4365 taxonomy_sta_info_assoc_req(hapd, sta, pos, left);
4366#endif /* CONFIG_TAXONOMY */
4367
1f0fdaf0
JM
4368 sta->pending_wds_enable = 0;
4369
5208160b
JM
4370#ifdef CONFIG_FILS
4371 if (sta->auth_alg == WLAN_AUTH_FILS_SK ||
4372 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
91d91abf
JM
4373 sta->auth_alg == WLAN_AUTH_FILS_PK) {
4374 if (fils_process_hlp(hapd, sta, pos, left) > 0)
4375 delay_assoc = 1;
4376 }
5208160b
JM
4377#endif /* CONFIG_FILS */
4378
6fc6879b 4379 fail:
53d17144 4380
3f81ac07
AO
4381 /*
4382 * In case of a successful response, add the station to the driver.
4383 * Otherwise, the kernel may ignore Data frames before we process the
4384 * ACK frame (TX status). In case of a failure, this station will be
4385 * removed.
4386 *
4387 * Note that this is not compliant with the IEEE 802.11 standard that
4388 * states that a non-AP station should transition into the
4389 * authenticated/associated state only after the station acknowledges
4390 * the (Re)Association Response frame. However, still do this as:
4391 *
4392 * 1. In case the station does not acknowledge the (Re)Association
4393 * Response frame, it will be removed.
4394 * 2. Data frames will be dropped in the kernel until the station is
4395 * set into authorized state, and there are no significant known
4396 * issues with processing other non-Data Class 3 frames during this
4397 * window.
4398 */
4cf5efec
JM
4399 if (resp == WLAN_STATUS_SUCCESS && sta &&
4400 add_associated_sta(hapd, sta, reassoc))
3f81ac07
AO
4401 resp = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
4402
91d91abf 4403#ifdef CONFIG_FILS
17adac9e
JM
4404 if (sta && delay_assoc && resp == WLAN_STATUS_SUCCESS &&
4405 eloop_is_timeout_registered(fils_hlp_timeout, hapd, sta) &&
4406 sta->fils_pending_assoc_req) {
4407 /* Do not reschedule fils_hlp_timeout in case the station
4408 * retransmits (Re)Association Request frame while waiting for
4409 * the previously started FILS HLP wait, so that the timeout can
4410 * be determined from the first pending attempt. */
4411 wpa_printf(MSG_DEBUG,
4412 "FILS: Continue waiting for HLP processing before sending (Re)Association Response frame to "
4413 MACSTR, MAC2STR(sta->addr));
4414 os_free(tmp);
4415 return;
4416 }
91d91abf
JM
4417 if (sta) {
4418 eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
4419 os_free(sta->fils_pending_assoc_req);
4420 sta->fils_pending_assoc_req = NULL;
4421 sta->fils_pending_assoc_req_len = 0;
4422 wpabuf_free(sta->fils_hlp_resp);
4423 sta->fils_hlp_resp = NULL;
4424 }
4425 if (sta && delay_assoc && resp == WLAN_STATUS_SUCCESS) {
4426 sta->fils_pending_assoc_req = tmp;
4427 sta->fils_pending_assoc_req_len = left;
4428 sta->fils_pending_assoc_is_reassoc = reassoc;
8b5ddda5 4429 sta->fils_drv_assoc_finish = 0;
91d91abf
JM
4430 wpa_printf(MSG_DEBUG,
4431 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
4432 MACSTR, MAC2STR(sta->addr));
4433 eloop_cancel_timeout(fils_hlp_timeout, hapd, sta);
4434 eloop_register_timeout(0, hapd->conf->fils_hlp_wait_time * 1024,
4435 fils_hlp_timeout, hapd, sta);
4436 return;
4437 }
4438#endif /* CONFIG_FILS */
4439
05e5e615 4440 reply_res = send_assoc_resp(hapd, sta, mgmt->sa, resp, reassoc, pos,
076f1ea1 4441 left, rssi);
78815f3d 4442 os_free(tmp);
3f81ac07
AO
4443
4444 /*
4445 * Remove the station in case tranmission of a success response fails
4446 * (the STA was added associated to the driver) or if the station was
4447 * previously added unassociated.
4448 */
05e5e615
DL
4449 if (sta && ((reply_res != WLAN_STATUS_SUCCESS &&
4450 resp == WLAN_STATUS_SUCCESS) || sta->added_unassoc)) {
bb598c3b
AB
4451 hostapd_drv_sta_remove(hapd, sta->addr);
4452 sta->added_unassoc = 0;
4453 }
6fc6879b
JM
4454}
4455
4456
6fc6879b 4457static void handle_disassoc(struct hostapd_data *hapd,
f8b1f695 4458 const struct ieee80211_mgmt *mgmt, size_t len)
6fc6879b
JM
4459{
4460 struct sta_info *sta;
4461
4462 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.disassoc)) {
61323e70
JM
4463 wpa_printf(MSG_INFO, "handle_disassoc - too short payload (len=%lu)",
4464 (unsigned long) len);
6fc6879b
JM
4465 return;
4466 }
4467
4468 wpa_printf(MSG_DEBUG, "disassocation: STA=" MACSTR " reason_code=%d",
4469 MAC2STR(mgmt->sa),
4470 le_to_host16(mgmt->u.disassoc.reason_code));
4471
6fc6879b
JM
4472 sta = ap_get_sta(hapd, mgmt->sa);
4473 if (sta == NULL) {
61323e70
JM
4474 wpa_printf(MSG_INFO, "Station " MACSTR " trying to disassociate, but it is not associated",
4475 MAC2STR(mgmt->sa));
6fc6879b
JM
4476 return;
4477 }
4478
ae055af4 4479 ap_sta_set_authorized(hapd, sta, 0);
38cb0a2d 4480 sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
b8281964 4481 sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
6fc6879b
JM
4482 wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
4483 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4484 HOSTAPD_LEVEL_INFO, "disassociated");
4485 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
4486 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
4487 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
4488 * authenticated. */
4489 accounting_sta_stop(hapd, sta);
d7c3347f 4490 ieee802_1x_free_station(hapd, sta);
7d597d46 4491 if (sta->ipaddr)
ed4ddb6d 4492 hostapd_drv_br_delete_ip_neigh(hapd, 4, (u8 *) &sta->ipaddr);
bd00c431 4493 ap_sta_ip6addr_del(hapd, sta);
51e2a27a 4494 hostapd_drv_sta_remove(hapd, sta->addr);
bb598c3b 4495 sta->added_unassoc = 0;
6fc6879b
JM
4496
4497 if (sta->timeout_next == STA_NULLFUNC ||
4498 sta->timeout_next == STA_DISASSOC) {
4499 sta->timeout_next = STA_DEAUTH;
4500 eloop_cancel_timeout(ap_handle_timer, hapd, sta);
4501 eloop_register_timeout(AP_DEAUTH_DELAY, 0, ap_handle_timer,
4502 hapd, sta);
4503 }
4504
4505 mlme_disassociate_indication(
4506 hapd, sta, le_to_host16(mgmt->u.disassoc.reason_code));
05e5e615
DL
4507
4508 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
4509 * disassociation. */
4510 if (hapd->iface->current_mode &&
4511 hapd->iface->current_mode->mode == HOSTAPD_MODE_IEEE80211AD) {
4512 sta->flags &= ~WLAN_STA_AUTH;
4513 wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
4514 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4515 HOSTAPD_LEVEL_DEBUG, "deauthenticated");
4516 ap_free_sta(hapd, sta);
4517 }
6fc6879b
JM
4518}
4519
4520
4521static void handle_deauth(struct hostapd_data *hapd,
f8b1f695 4522 const struct ieee80211_mgmt *mgmt, size_t len)
6fc6879b
JM
4523{
4524 struct sta_info *sta;
4525
4526 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.deauth)) {
3ec1e902
JM
4527 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "handle_deauth - too short "
4528 "payload (len=%lu)", (unsigned long) len);
6fc6879b
JM
4529 return;
4530 }
4531
3ec1e902 4532 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "deauthentication: STA=" MACSTR
24d75245
BG
4533 " reason_code=%d",
4534 MAC2STR(mgmt->sa), le_to_host16(mgmt->u.deauth.reason_code));
6fc6879b 4535
6fc6879b
JM
4536 sta = ap_get_sta(hapd, mgmt->sa);
4537 if (sta == NULL) {
3ec1e902
JM
4538 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "Station " MACSTR " trying "
4539 "to deauthenticate, but it is not authenticated",
24d75245 4540 MAC2STR(mgmt->sa));
6fc6879b
JM
4541 return;
4542 }
4543
ae055af4 4544 ap_sta_set_authorized(hapd, sta, 0);
38cb0a2d 4545 sta->last_seq_ctrl = WLAN_INVALID_MGMT_SEQ;
b8281964
JM
4546 sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
4547 WLAN_STA_ASSOC_REQ_OK);
6fc6879b
JM
4548 wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
4549 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4550 HOSTAPD_LEVEL_DEBUG, "deauthenticated");
4551 mlme_deauthenticate_indication(
4552 hapd, sta, le_to_host16(mgmt->u.deauth.reason_code));
4553 sta->acct_terminate_cause = RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST;
4554 ieee802_1x_notify_port_enabled(sta->eapol_sm, 0);
4555 ap_free_sta(hapd, sta);
4556}
4557
4558
4559static void handle_beacon(struct hostapd_data *hapd,
b57e086c 4560 const struct ieee80211_mgmt *mgmt, size_t len,
6fc6879b
JM
4561 struct hostapd_frame_info *fi)
4562{
4563 struct ieee802_11_elems elems;
4564
4565 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.beacon)) {
61323e70
JM
4566 wpa_printf(MSG_INFO, "handle_beacon - too short payload (len=%lu)",
4567 (unsigned long) len);
6fc6879b
JM
4568 return;
4569 }
4570
3d536eb4 4571 (void) ieee802_11_parse_elems(mgmt->u.beacon.variable,
6fc6879b
JM
4572 len - (IEEE80211_HDRLEN +
4573 sizeof(mgmt->u.beacon)), &elems,
4574 0);
4575
6fc6879b
JM
4576 ap_list_process_beacon(hapd->iface, mgmt, &elems, fi);
4577}
4578
4579
c4e281fd
JM
4580static int robust_action_frame(u8 category)
4581{
4582 return category != WLAN_ACTION_PUBLIC &&
4583 category != WLAN_ACTION_HT;
4584}
4585
4586
912b34f0 4587static int handle_action(struct hostapd_data *hapd,
c5cc7a59
JM
4588 const struct ieee80211_mgmt *mgmt, size_t len,
4589 unsigned int freq)
6fc6879b 4590{
c4e281fd 4591 struct sta_info *sta;
e0785ebb 4592 u8 *action __maybe_unused;
c4e281fd 4593
e0785ebb 4594 if (len < IEEE80211_HDRLEN + 2 + 1) {
6fc6879b
JM
4595 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
4596 HOSTAPD_LEVEL_DEBUG,
4597 "handle_action - too short payload (len=%lu)",
4598 (unsigned long) len);
912b34f0 4599 return 0;
6fc6879b
JM
4600 }
4601
e0785ebb
JM
4602 action = (u8 *) &mgmt->u.action.u;
4603 wpa_printf(MSG_DEBUG, "RX_ACTION category %u action %u sa " MACSTR
4604 " da " MACSTR " len %d freq %u",
4605 mgmt->u.action.category, *action,
4606 MAC2STR(mgmt->sa), MAC2STR(mgmt->da), (int) len, freq);
4607
4608 sta = ap_get_sta(hapd, mgmt->sa);
4609
c79938a5
JM
4610 if (mgmt->u.action.category != WLAN_ACTION_PUBLIC &&
4611 (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))) {
4612 wpa_printf(MSG_DEBUG, "IEEE 802.11: Ignored Action "
4613 "frame (category=%u) from unassociated STA " MACSTR,
ae26d302 4614 mgmt->u.action.category, MAC2STR(mgmt->sa));
912b34f0 4615 return 0;
c79938a5
JM
4616 }
4617
c4e281fd 4618 if (sta && (sta->flags & WLAN_STA_MFP) &&
7b2c42f8
JM
4619 !(mgmt->frame_control & host_to_le16(WLAN_FC_ISWEP)) &&
4620 robust_action_frame(mgmt->u.action.category)) {
c4e281fd
JM
4621 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
4622 HOSTAPD_LEVEL_DEBUG,
4623 "Dropped unprotected Robust Action frame from "
4624 "an MFP STA");
912b34f0 4625 return 0;
c4e281fd 4626 }
c4e281fd 4627
38cb0a2d
IP
4628 if (sta) {
4629 u16 fc = le_to_host16(mgmt->frame_control);
4630 u16 seq_ctrl = le_to_host16(mgmt->seq_ctrl);
4631
4632 if ((fc & WLAN_FC_RETRY) &&
4633 sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
4634 sta->last_seq_ctrl == seq_ctrl &&
4635 sta->last_subtype == WLAN_FC_STYPE_ACTION) {
4636 hostapd_logger(hapd, sta->addr,
4637 HOSTAPD_MODULE_IEEE80211,
4638 HOSTAPD_LEVEL_DEBUG,
4639 "Drop repeated action frame seq_ctrl=0x%x",
4640 seq_ctrl);
4641 return 1;
4642 }
4643
4644 sta->last_seq_ctrl = seq_ctrl;
4645 sta->last_subtype = WLAN_FC_STYPE_ACTION;
4646 }
4647
6fc6879b 4648 switch (mgmt->u.action.category) {
4ec1fd8e 4649#ifdef CONFIG_IEEE80211R_AP
6fc6879b 4650 case WLAN_ACTION_FT:
d6c6b1fb
JM
4651 if (!sta ||
4652 wpa_ft_action_rx(sta->wpa_sm, (u8 *) &mgmt->u.action,
6fc6879b
JM
4653 len - IEEE80211_HDRLEN))
4654 break;
912b34f0 4655 return 1;
4ec1fd8e 4656#endif /* CONFIG_IEEE80211R_AP */
c2a71408 4657 case WLAN_ACTION_WMM:
3ae0800c 4658 hostapd_wmm_action(hapd, mgmt, len);
912b34f0 4659 return 1;
93b76319 4660 case WLAN_ACTION_SA_QUERY:
700b3f39
JM
4661 ieee802_11_sa_query_action(hapd, mgmt, len);
4662 return 1;
b5bf84ba 4663#ifdef CONFIG_WNM_AP
c79938a5 4664 case WLAN_ACTION_WNM:
dbfb8e82
JM
4665 ieee802_11_rx_wnm_action_ap(hapd, mgmt, len);
4666 return 1;
b5bf84ba 4667#endif /* CONFIG_WNM_AP */
037378ff
AN
4668#ifdef CONFIG_FST
4669 case WLAN_ACTION_FST:
4670 if (hapd->iface->fst)
4671 fst_rx_action(hapd->iface->fst, mgmt, len);
94edea89
JM
4672 else
4673 wpa_printf(MSG_DEBUG,
4674 "FST: Ignore FST Action frame - no FST attached");
037378ff
AN
4675 return 1;
4676#endif /* CONFIG_FST */
c706d5aa 4677 case WLAN_ACTION_PUBLIC:
5ce00d09 4678 case WLAN_ACTION_PROTECTED_DUAL:
587d60d2 4679#ifdef CONFIG_IEEE80211N
fd66aa63
JM
4680 if (len >= IEEE80211_HDRLEN + 2 &&
4681 mgmt->u.action.u.public_action.action ==
587d60d2 4682 WLAN_PA_20_40_BSS_COEX) {
587d60d2 4683 hostapd_2040_coex_action(hapd, mgmt, len);
115d5e22 4684 return 1;
587d60d2
PX
4685 }
4686#endif /* CONFIG_IEEE80211N */
9c2b8204
JM
4687#ifdef CONFIG_DPP
4688 if (len >= IEEE80211_HDRLEN + 6 &&
4689 mgmt->u.action.u.vs_public_action.action ==
4690 WLAN_PA_VENDOR_SPECIFIC &&
4691 WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
4692 OUI_WFA &&
4693 mgmt->u.action.u.vs_public_action.variable[0] ==
4694 DPP_OUI_TYPE) {
4695 const u8 *pos, *end;
4696
dc4d271c 4697 pos = mgmt->u.action.u.vs_public_action.oui;
9c2b8204
JM
4698 end = ((const u8 *) mgmt) + len;
4699 hostapd_dpp_rx_action(hapd, mgmt->sa, pos, end - pos,
c5cc7a59 4700 freq);
9c2b8204
JM
4701 return 1;
4702 }
4703 if (len >= IEEE80211_HDRLEN + 2 &&
4704 (mgmt->u.action.u.public_action.action ==
4705 WLAN_PA_GAS_INITIAL_RESP ||
4706 mgmt->u.action.u.public_action.action ==
4707 WLAN_PA_GAS_COMEBACK_RESP)) {
4708 const u8 *pos, *end;
4709
4710 pos = &mgmt->u.action.u.public_action.action;
4711 end = ((const u8 *) mgmt) + len;
4712 gas_query_ap_rx(hapd->gas, mgmt->sa,
4713 mgmt->u.action.category,
4714 pos, end - pos, hapd->iface->freq);
4715 return 1;
4716 }
4717#endif /* CONFIG_DPP */
c706d5aa
JM
4718 if (hapd->public_action_cb) {
4719 hapd->public_action_cb(hapd->public_action_cb_ctx,
4720 (u8 *) mgmt, len,
4721 hapd->iface->freq);
c706d5aa 4722 }
2d9ffe1e 4723 if (hapd->public_action_cb2) {
8dabf4bb 4724 hapd->public_action_cb2(hapd->public_action_cb2_ctx,
2d9ffe1e
JM
4725 (u8 *) mgmt, len,
4726 hapd->iface->freq);
4727 }
4728 if (hapd->public_action_cb || hapd->public_action_cb2)
912b34f0 4729 return 1;
c706d5aa 4730 break;
e44f8bf2
JM
4731 case WLAN_ACTION_VENDOR_SPECIFIC:
4732 if (hapd->vendor_action_cb) {
4733 if (hapd->vendor_action_cb(hapd->vendor_action_cb_ctx,
4734 (u8 *) mgmt, len,
4735 hapd->iface->freq) == 0)
912b34f0 4736 return 1;
e44f8bf2
JM
4737 }
4738 break;
2572df34
DS
4739 case WLAN_ACTION_RADIO_MEASUREMENT:
4740 hostapd_handle_radio_measurement(hapd, (const u8 *) mgmt, len);
4741 return 1;
6fc6879b
JM
4742 }
4743
4744 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
4745 HOSTAPD_LEVEL_DEBUG,
4746 "handle_action - unknown action category %d or invalid "
4747 "frame",
4748 mgmt->u.action.category);
81372e34
JB
4749 if (!is_multicast_ether_addr(mgmt->da) &&
4750 !(mgmt->u.action.category & 0x80) &&
4751 !is_multicast_ether_addr(mgmt->sa)) {
b57e086c
JM
4752 struct ieee80211_mgmt *resp;
4753
6fc6879b
JM
4754 /*
4755 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
4756 * Return the Action frame to the source without change
4757 * except that MSB of the Category set to 1.
4758 */
4759 wpa_printf(MSG_DEBUG, "IEEE 802.11: Return unknown Action "
4760 "frame back to sender");
a1f11e34 4761 resp = os_memdup(mgmt, len);
b57e086c 4762 if (resp == NULL)
912b34f0 4763 return 0;
b57e086c
JM
4764 os_memcpy(resp->da, resp->sa, ETH_ALEN);
4765 os_memcpy(resp->sa, hapd->own_addr, ETH_ALEN);
4766 os_memcpy(resp->bssid, hapd->own_addr, ETH_ALEN);
4767 resp->u.action.category |= 0x80;
4768
37100274 4769 if (hostapd_drv_send_mlme(hapd, resp, len, 0, NULL, 0, 0) < 0) {
41fe8b42
JM
4770 wpa_printf(MSG_ERROR, "IEEE 802.11: Failed to send "
4771 "Action frame");
4772 }
b57e086c 4773 os_free(resp);
6fc6879b 4774 }
912b34f0
JM
4775
4776 return 1;
6fc6879b
JM
4777}
4778
4779
4780/**
4781 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
4782 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
4783 * sent to)
4784 * @buf: management frame data (starting from IEEE 802.11 header)
4785 * @len: length of frame data in octets
a17df5fb 4786 * @fi: meta data about received frame (signal level, etc.)
6fc6879b
JM
4787 *
4788 * Process all incoming IEEE 802.11 management frames. This will be called for
4789 * each frame received from the kernel driver through wlan#ap interface. In
4790 * addition, it can be called to re-inserted pending frames (e.g., when using
4791 * external RADIUS server as an MAC ACL).
4792 */
912b34f0
JM
4793int ieee802_11_mgmt(struct hostapd_data *hapd, const u8 *buf, size_t len,
4794 struct hostapd_frame_info *fi)
6fc6879b 4795{
f8b1f695 4796 struct ieee80211_mgmt *mgmt;
f8b1f695 4797 u16 fc, stype;
912b34f0 4798 int ret = 0;
c5cc7a59 4799 unsigned int freq;
659ac96d 4800 int ssi_signal = fi ? fi->ssi_signal : 0;
f8b1f695 4801
cbcf92b4 4802 if (len < 24)
912b34f0 4803 return 0;
cbcf92b4 4804
c5cc7a59
JM
4805 if (fi && fi->freq)
4806 freq = fi->freq;
4807 else
4808 freq = hapd->iface->freq;
4809
f8b1f695
JM
4810 mgmt = (struct ieee80211_mgmt *) buf;
4811 fc = le_to_host16(mgmt->frame_control);
4812 stype = WLAN_FC_GET_STYPE(fc);
6fc6879b 4813
d86d66dc
JM
4814 if (is_multicast_ether_addr(mgmt->sa) ||
4815 is_zero_ether_addr(mgmt->sa) ||
4816 os_memcmp(mgmt->sa, hapd->own_addr, ETH_ALEN) == 0) {
4817 /* Do not process any frames with unexpected/invalid SA so that
4818 * we do not add any state for unexpected STA addresses or end
4819 * up sending out frames to unexpected destination. */
4820 wpa_printf(MSG_DEBUG, "MGMT: Invalid SA=" MACSTR
4821 " in received frame - ignore this frame silently",
4822 MAC2STR(mgmt->sa));
4823 return 0;
4824 }
4825
6fc6879b
JM
4826 if (stype == WLAN_FC_STYPE_BEACON) {
4827 handle_beacon(hapd, mgmt, len, fi);
912b34f0 4828 return 1;
6fc6879b
JM
4829 }
4830
842c5af5 4831 if (!is_broadcast_ether_addr(mgmt->bssid) &&
3eeee931
AN
4832#ifdef CONFIG_P2P
4833 /* Invitation responses can be sent with the peer MAC as BSSID */
4834 !((hapd->conf->p2p & P2P_GROUP_OWNER) &&
4835 stype == WLAN_FC_STYPE_ACTION) &&
4836#endif /* CONFIG_P2P */
f3e9899e
BC
4837#ifdef CONFIG_MESH
4838 !(hapd->conf->mesh & MESH_ENABLED) &&
4839#endif /* CONFIG_MESH */
fe2c5241 4840 os_memcmp(mgmt->bssid, hapd->own_addr, ETH_ALEN) != 0) {
61323e70
JM
4841 wpa_printf(MSG_INFO, "MGMT: BSSID=" MACSTR " not our address",
4842 MAC2STR(mgmt->bssid));
912b34f0 4843 return 0;
6fc6879b
JM
4844 }
4845
4846
4847 if (stype == WLAN_FC_STYPE_PROBE_REQ) {
659ac96d 4848 handle_probe_req(hapd, mgmt, len, ssi_signal);
912b34f0 4849 return 1;
6fc6879b
JM
4850 }
4851
efeada91
JM
4852 if ((!is_broadcast_ether_addr(mgmt->da) ||
4853 stype != WLAN_FC_STYPE_ACTION) &&
4854 os_memcmp(mgmt->da, hapd->own_addr, ETH_ALEN) != 0) {
6fc6879b
JM
4855 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
4856 HOSTAPD_LEVEL_DEBUG,
4857 "MGMT: DA=" MACSTR " not our address",
4858 MAC2STR(mgmt->da));
912b34f0 4859 return 0;
6fc6879b
JM
4860 }
4861
b308a304 4862 if (hapd->iconf->track_sta_max_num)
659ac96d 4863 sta_track_add(hapd->iface, mgmt->sa, ssi_signal);
b308a304 4864
6fc6879b
JM
4865 switch (stype) {
4866 case WLAN_FC_STYPE_AUTH:
4867 wpa_printf(MSG_DEBUG, "mgmt::auth");
ff9f40ae 4868 handle_auth(hapd, mgmt, len, ssi_signal, 0);
912b34f0 4869 ret = 1;
6fc6879b
JM
4870 break;
4871 case WLAN_FC_STYPE_ASSOC_REQ:
4872 wpa_printf(MSG_DEBUG, "mgmt::assoc_req");
076f1ea1 4873 handle_assoc(hapd, mgmt, len, 0, ssi_signal);
912b34f0 4874 ret = 1;
6fc6879b 4875 break;
6fc6879b
JM
4876 case WLAN_FC_STYPE_REASSOC_REQ:
4877 wpa_printf(MSG_DEBUG, "mgmt::reassoc_req");
076f1ea1 4878 handle_assoc(hapd, mgmt, len, 1, ssi_signal);
912b34f0 4879 ret = 1;
6fc6879b
JM
4880 break;
4881 case WLAN_FC_STYPE_DISASSOC:
4882 wpa_printf(MSG_DEBUG, "mgmt::disassoc");
4883 handle_disassoc(hapd, mgmt, len);
912b34f0 4884 ret = 1;
6fc6879b
JM
4885 break;
4886 case WLAN_FC_STYPE_DEAUTH:
3ec1e902 4887 wpa_msg(hapd->msg_ctx, MSG_DEBUG, "mgmt::deauth");
6fc6879b 4888 handle_deauth(hapd, mgmt, len);
912b34f0 4889 ret = 1;
6fc6879b
JM
4890 break;
4891 case WLAN_FC_STYPE_ACTION:
4892 wpa_printf(MSG_DEBUG, "mgmt::action");
c5cc7a59 4893 ret = handle_action(hapd, mgmt, len, freq);
6fc6879b
JM
4894 break;
4895 default:
4896 hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
4897 HOSTAPD_LEVEL_DEBUG,
4898 "unknown mgmt frame subtype %d", stype);
4899 break;
4900 }
912b34f0
JM
4901
4902 return ret;
6fc6879b
JM
4903}
4904
4905
4906static void handle_auth_cb(struct hostapd_data *hapd,
f8b1f695 4907 const struct ieee80211_mgmt *mgmt,
6fc6879b
JM
4908 size_t len, int ok)
4909{
4910 u16 auth_alg, auth_transaction, status_code;
4911 struct sta_info *sta;
4912
bb598c3b
AB
4913 sta = ap_get_sta(hapd, mgmt->da);
4914 if (!sta) {
dc1b1c8d
JM
4915 wpa_printf(MSG_DEBUG, "handle_auth_cb: STA " MACSTR
4916 " not found",
bb598c3b
AB
4917 MAC2STR(mgmt->da));
4918 return;
4919 }
4920
4921 auth_alg = le_to_host16(mgmt->u.auth.auth_alg);
4922 auth_transaction = le_to_host16(mgmt->u.auth.auth_transaction);
4923 status_code = le_to_host16(mgmt->u.auth.status_code);
4924
6fc6879b
JM
4925 if (!ok) {
4926 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
4927 HOSTAPD_LEVEL_NOTICE,
4928 "did not acknowledge authentication response");
bb598c3b 4929 goto fail;
6fc6879b
JM
4930 }
4931
4932 if (len < IEEE80211_HDRLEN + sizeof(mgmt->u.auth)) {
61323e70
JM
4933 wpa_printf(MSG_INFO, "handle_auth_cb - too short payload (len=%lu)",
4934 (unsigned long) len);
bb598c3b 4935 goto fail;
6fc6879b
JM
4936 }
4937
4938 if (status_code == WLAN_STATUS_SUCCESS &&
4939 ((auth_alg == WLAN_AUTH_OPEN && auth_transaction == 2) ||
4940 (auth_alg == WLAN_AUTH_SHARED_KEY && auth_transaction == 4))) {
4941 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
4942 HOSTAPD_LEVEL_INFO, "authenticated");
4943 sta->flags |= WLAN_STA_AUTH;
bb598c3b
AB
4944 if (sta->added_unassoc)
4945 hostapd_set_sta_flags(hapd, sta);
4946 return;
4947 }
4948
4949fail:
4950 if (status_code != WLAN_STATUS_SUCCESS && sta->added_unassoc) {
4951 hostapd_drv_sta_remove(hapd, sta->addr);
4952 sta->added_unassoc = 0;
6fc6879b
JM
4953 }
4954}
4955
4956
69dd2967
SM
4957static void hostapd_set_wds_encryption(struct hostapd_data *hapd,
4958 struct sta_info *sta,
4959 char *ifname_wds)
4960{
4961 int i;
f41ded6f 4962 struct hostapd_ssid *ssid = &hapd->conf->ssid;
69dd2967
SM
4963
4964 if (hapd->conf->ieee802_1x || hapd->conf->wpa)
4965 return;
4966
4967 for (i = 0; i < 4; i++) {
4968 if (ssid->wep.key[i] &&
4969 hostapd_drv_set_key(ifname_wds, hapd, WPA_ALG_WEP, NULL, i,
4d3ae54f 4970 0, i == ssid->wep.idx, NULL, 0,
a919a260
AW
4971 ssid->wep.key[i], ssid->wep.len[i],
4972 i == ssid->wep.idx ?
4973 KEY_FLAG_GROUP_RX_TX_DEFAULT :
4974 KEY_FLAG_GROUP_RX_TX)) {
69dd2967
SM
4975 wpa_printf(MSG_WARNING,
4976 "Could not set WEP keys for WDS interface; %s",
4977 ifname_wds);
4978 break;
4979 }
4980 }
4981}
4982
4983
6fc6879b 4984static void handle_assoc_cb(struct hostapd_data *hapd,
f8b1f695 4985 const struct ieee80211_mgmt *mgmt,
6fc6879b
JM
4986 size_t len, int reassoc, int ok)
4987{
4988 u16 status;
4989 struct sta_info *sta;
4990 int new_assoc = 1;
4991
6fc6879b
JM
4992 sta = ap_get_sta(hapd, mgmt->da);
4993 if (!sta) {
61323e70
JM
4994 wpa_printf(MSG_INFO, "handle_assoc_cb: STA " MACSTR " not found",
4995 MAC2STR(mgmt->da));
6fc6879b
JM
4996 return;
4997 }
4998
bb598c3b
AB
4999 if (len < IEEE80211_HDRLEN + (reassoc ? sizeof(mgmt->u.reassoc_resp) :
5000 sizeof(mgmt->u.assoc_resp))) {
5001 wpa_printf(MSG_INFO,
5002 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
5003 reassoc, (unsigned long) len);
3f81ac07
AO
5004 hostapd_drv_sta_remove(hapd, sta->addr);
5005 return;
bb598c3b
AB
5006 }
5007
3f81ac07
AO
5008 if (reassoc)
5009 status = le_to_host16(mgmt->u.reassoc_resp.status_code);
5010 else
5011 status = le_to_host16(mgmt->u.assoc_resp.status_code);
5012
22b42372
FF
5013 if (!ok) {
5014 hostapd_logger(hapd, mgmt->da, HOSTAPD_MODULE_IEEE80211,
5015 HOSTAPD_LEVEL_DEBUG,
5016 "did not acknowledge association response");
5017 sta->flags &= ~WLAN_STA_ASSOC_REQ_OK;
3f81ac07
AO
5018 /* The STA is added only in case of SUCCESS */
5019 if (status == WLAN_STATUS_SUCCESS)
5020 hostapd_drv_sta_remove(hapd, sta->addr);
22b42372 5021
3f81ac07
AO
5022 return;
5023 }
22b42372 5024
6fc6879b 5025 if (status != WLAN_STATUS_SUCCESS)
5bdac4ab 5026 return;
6fc6879b
JM
5027
5028 /* Stop previous accounting session, if one is started, and allocate
5029 * new session id for the new session. */
5030 accounting_sta_stop(hapd, sta);
6fc6879b
JM
5031
5032 hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
5033 HOSTAPD_LEVEL_INFO,
2fc98d02
JM
5034 "associated (aid %d)",
5035 sta->aid);
6fc6879b
JM
5036
5037 if (sta->flags & WLAN_STA_ASSOC)
5038 new_assoc = 0;
5039 sta->flags |= WLAN_STA_ASSOC;
3578e665 5040 sta->flags &= ~WLAN_STA_WNM_SLEEP_MODE;
07e0117d
JM
5041 if ((!hapd->conf->ieee802_1x && !hapd->conf->wpa &&
5042 !hapd->conf->osen) ||
5043 sta->auth_alg == WLAN_AUTH_FILS_SK ||
5044 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
5045 sta->auth_alg == WLAN_AUTH_FILS_PK ||
ef580012
JM
5046 sta->auth_alg == WLAN_AUTH_FT) {
5047 /*
07e0117d
JM
5048 * Open, static WEP, FT protocol, or FILS; no separate
5049 * authorization step.
ef580012 5050 */
6905dcb1 5051 ap_sta_set_authorized(hapd, sta, 1);
515cf93f 5052 }
6fc6879b
JM
5053
5054 if (reassoc)
5055 mlme_reassociate_indication(hapd, sta);
5056 else
5057 mlme_associate_indication(hapd, sta);
5058
93b76319 5059 sta->sa_query_timed_out = 0;
5d22a1d5 5060
6fc6879b
JM
5061 if (sta->eapol_sm == NULL) {
5062 /*
5063 * This STA does not use RADIUS server for EAP authentication,
5064 * so bind it to the selected VLAN interface now, since the
5065 * interface selection is not going to change anymore.
5066 */
c8e6beab 5067 if (ap_sta_bind_vlan(hapd, sta) < 0)
5bdac4ab 5068 return;
6fc6879b
JM
5069 } else if (sta->vlan_id) {
5070 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
c8e6beab 5071 if (ap_sta_bind_vlan(hapd, sta) < 0)
5bdac4ab 5072 return;
6fc6879b 5073 }
eddd8010 5074
0e8a96a9 5075 hostapd_set_sta_flags(hapd, sta);
6fc6879b 5076
1f0fdaf0
JM
5077 if (!(sta->flags & WLAN_STA_WDS) && sta->pending_wds_enable) {
5078 wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for STA "
5079 MACSTR " based on pending request",
5080 MAC2STR(sta->addr));
5081 sta->pending_wds_enable = 0;
5082 sta->flags |= WLAN_STA_WDS;
5083 }
5084
9c06f0f6 5085 if (sta->flags & (WLAN_STA_WDS | WLAN_STA_MULTI_AP)) {
cb2b6666
JM
5086 int ret;
5087 char ifname_wds[IFNAMSIZ + 1];
5088
5089 wpa_printf(MSG_DEBUG, "Reenable 4-address WDS mode for STA "
5090 MACSTR " (aid %u)",
5091 MAC2STR(sta->addr), sta->aid);
5092 ret = hostapd_set_wds_sta(hapd, ifname_wds, sta->addr,
5093 sta->aid, 1);
5094 if (!ret)
5095 hostapd_set_wds_encryption(hapd, sta, ifname_wds);
5096 }
5097
6fc6879b
JM
5098 if (sta->auth_alg == WLAN_AUTH_FT)
5099 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC_FT);
5100 else
5101 wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
d24df7c3 5102 hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
6fc6879b 5103 ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
f2accfe7 5104
da24c5aa
JM
5105#ifdef CONFIG_FILS
5106 if ((sta->auth_alg == WLAN_AUTH_FILS_SK ||
5107 sta->auth_alg == WLAN_AUTH_FILS_SK_PFS ||
5108 sta->auth_alg == WLAN_AUTH_FILS_PK) &&
5109 fils_set_tk(sta->wpa_sm) < 0) {
5110 wpa_printf(MSG_DEBUG, "FILS: TK configuration failed");
5111 ap_sta_disconnect(hapd, sta, sta->addr,
5112 WLAN_REASON_UNSPECIFIED);
5113 return;
5114 }
5115#endif /* CONFIG_FILS */
5116
f2accfe7
EP
5117 if (sta->pending_eapol_rx) {
5118 struct os_reltime now, age;
5119
5120 os_get_reltime(&now);
5121 os_reltime_sub(&now, &sta->pending_eapol_rx->rx_time, &age);
5122 if (age.sec == 0 && age.usec < 200000) {
5123 wpa_printf(MSG_DEBUG,
5124 "Process pending EAPOL frame that was received from " MACSTR " just before association notification",
5125 MAC2STR(sta->addr));
5126 ieee802_1x_receive(
5127 hapd, mgmt->da,
5128 wpabuf_head(sta->pending_eapol_rx->buf),
5129 wpabuf_len(sta->pending_eapol_rx->buf));
5130 }
5131 wpabuf_free(sta->pending_eapol_rx->buf);
5132 os_free(sta->pending_eapol_rx);
5133 sta->pending_eapol_rx = NULL;
5134 }
6fc6879b
JM
5135}
5136
5137
4dc03726
JM
5138static void handle_deauth_cb(struct hostapd_data *hapd,
5139 const struct ieee80211_mgmt *mgmt,
5140 size_t len, int ok)
5141{
5142 struct sta_info *sta;
81372e34 5143 if (is_multicast_ether_addr(mgmt->da))
4dc03726
JM
5144 return;
5145 sta = ap_get_sta(hapd, mgmt->da);
5146 if (!sta) {
5147 wpa_printf(MSG_DEBUG, "handle_deauth_cb: STA " MACSTR
5148 " not found", MAC2STR(mgmt->da));
5149 return;
5150 }
5151 if (ok)
5152 wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged deauth",
5153 MAC2STR(sta->addr));
5154 else
5155 wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
5156 "deauth", MAC2STR(sta->addr));
5157
5158 ap_sta_deauth_cb(hapd, sta);
5159}
5160
5161
5162static void handle_disassoc_cb(struct hostapd_data *hapd,
5163 const struct ieee80211_mgmt *mgmt,
5164 size_t len, int ok)
5165{
5166 struct sta_info *sta;
81372e34 5167 if (is_multicast_ether_addr(mgmt->da))
4dc03726
JM
5168 return;
5169 sta = ap_get_sta(hapd, mgmt->da);
5170 if (!sta) {
5171 wpa_printf(MSG_DEBUG, "handle_disassoc_cb: STA " MACSTR
5172 " not found", MAC2STR(mgmt->da));
5173 return;
5174 }
5175 if (ok)
5176 wpa_printf(MSG_DEBUG, "STA " MACSTR " acknowledged disassoc",
5177 MAC2STR(sta->addr));
5178 else
5179 wpa_printf(MSG_DEBUG, "STA " MACSTR " did not acknowledge "
5180 "disassoc", MAC2STR(sta->addr));
5181
5182 ap_sta_disassoc_cb(hapd, sta);
5183}
5184
5185
f3383366
JM
5186static void handle_action_cb(struct hostapd_data *hapd,
5187 const struct ieee80211_mgmt *mgmt,
5188 size_t len, int ok)
5189{
5190 struct sta_info *sta;
167f78a5 5191 const struct rrm_measurement_report_element *report;
f3383366
JM
5192
5193 if (is_multicast_ether_addr(mgmt->da))
5194 return;
9c2b8204
JM
5195#ifdef CONFIG_DPP
5196 if (len >= IEEE80211_HDRLEN + 6 &&
5197 mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
5198 mgmt->u.action.u.vs_public_action.action ==
5199 WLAN_PA_VENDOR_SPECIFIC &&
5200 WPA_GET_BE24(mgmt->u.action.u.vs_public_action.oui) ==
5201 OUI_WFA &&
5202 mgmt->u.action.u.vs_public_action.variable[0] ==
5203 DPP_OUI_TYPE) {
5204 const u8 *pos, *end;
5205
5206 pos = &mgmt->u.action.u.vs_public_action.variable[1];
5207 end = ((const u8 *) mgmt) + len;
5208 hostapd_dpp_tx_status(hapd, mgmt->da, pos, end - pos, ok);
5209 return;
5210 }
5211 if (len >= IEEE80211_HDRLEN + 2 &&
5212 mgmt->u.action.category == WLAN_ACTION_PUBLIC &&
5213 (mgmt->u.action.u.public_action.action ==
5214 WLAN_PA_GAS_INITIAL_REQ ||
5215 mgmt->u.action.u.public_action.action ==
5216 WLAN_PA_GAS_COMEBACK_REQ)) {
5217 const u8 *pos, *end;
5218
5219 pos = mgmt->u.action.u.public_action.variable;
5220 end = ((const u8 *) mgmt) + len;
5221 gas_query_ap_tx_status(hapd->gas, mgmt->da, pos, end - pos, ok);
5222 return;
5223 }
5224#endif /* CONFIG_DPP */
f3383366
JM
5225 sta = ap_get_sta(hapd, mgmt->da);
5226 if (!sta) {
5227 wpa_printf(MSG_DEBUG, "handle_action_cb: STA " MACSTR
5228 " not found", MAC2STR(mgmt->da));
5229 return;
5230 }
5231
167f78a5 5232 if (len < 24 + 5 + sizeof(*report))
f3383366 5233 return;
167f78a5
JM
5234 report = (const struct rrm_measurement_report_element *)
5235 &mgmt->u.action.u.rrm.variable[2];
f3383366 5236 if (mgmt->u.action.category == WLAN_ACTION_RADIO_MEASUREMENT &&
167f78a5
JM
5237 mgmt->u.action.u.rrm.action == WLAN_RRM_RADIO_MEASUREMENT_REQUEST &&
5238 report->eid == WLAN_EID_MEASURE_REQUEST &&
5239 report->len >= 3 &&
5240 report->type == MEASURE_TYPE_BEACON)
f3383366
JM
5241 hostapd_rrm_beacon_req_tx_status(hapd, mgmt, len, ok);
5242}
5243
5244
1c6e69cc
JM
5245/**
5246 * ieee802_11_mgmt_cb - Process management frame TX status callback
5247 * @hapd: hostapd BSS data structure (the BSS from which the management frame
5248 * was sent from)
5249 * @buf: management frame data (starting from IEEE 802.11 header)
5250 * @len: length of frame data in octets
5251 * @stype: management frame subtype from frame control field
5252 * @ok: Whether the frame was ACK'ed
5253 */
f8b1f695 5254void ieee802_11_mgmt_cb(struct hostapd_data *hapd, const u8 *buf, size_t len,
6fc6879b
JM
5255 u16 stype, int ok)
5256{
f8b1f695
JM
5257 const struct ieee80211_mgmt *mgmt;
5258 mgmt = (const struct ieee80211_mgmt *) buf;
6fc6879b 5259
93827f45
JM
5260#ifdef CONFIG_TESTING_OPTIONS
5261 if (hapd->ext_mgmt_frame_handling) {
df949062
JM
5262 size_t hex_len = 2 * len + 1;
5263 char *hex = os_malloc(hex_len);
5264
5265 if (hex) {
5266 wpa_snprintf_hex(hex, hex_len, buf, len);
5267 wpa_msg(hapd->msg_ctx, MSG_INFO,
5268 "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
5269 stype, ok, hex);
5270 os_free(hex);
5271 }
93827f45
JM
5272 return;
5273 }
5274#endif /* CONFIG_TESTING_OPTIONS */
5275
6fc6879b
JM
5276 switch (stype) {
5277 case WLAN_FC_STYPE_AUTH:
5278 wpa_printf(MSG_DEBUG, "mgmt::auth cb");
5279 handle_auth_cb(hapd, mgmt, len, ok);
5280 break;
5281 case WLAN_FC_STYPE_ASSOC_RESP:
5282 wpa_printf(MSG_DEBUG, "mgmt::assoc_resp cb");
5283 handle_assoc_cb(hapd, mgmt, len, 0, ok);
5284 break;
5285 case WLAN_FC_STYPE_REASSOC_RESP:
5286 wpa_printf(MSG_DEBUG, "mgmt::reassoc_resp cb");
5287 handle_assoc_cb(hapd, mgmt, len, 1, ok);
5288 break;
5289 case WLAN_FC_STYPE_PROBE_RESP:
077dcfb8 5290 wpa_printf(MSG_EXCESSIVE, "mgmt::proberesp cb ok=%d", ok);
6fc6879b
JM
5291 break;
5292 case WLAN_FC_STYPE_DEAUTH:
4dc03726
JM
5293 wpa_printf(MSG_DEBUG, "mgmt::deauth cb");
5294 handle_deauth_cb(hapd, mgmt, len, ok);
5295 break;
5296 case WLAN_FC_STYPE_DISASSOC:
5297 wpa_printf(MSG_DEBUG, "mgmt::disassoc cb");
5298 handle_disassoc_cb(hapd, mgmt, len, ok);
6fc6879b 5299 break;
5d22a1d5 5300 case WLAN_FC_STYPE_ACTION:
077dcfb8 5301 wpa_printf(MSG_DEBUG, "mgmt::action cb ok=%d", ok);
f3383366 5302 handle_action_cb(hapd, mgmt, len, ok);
5d22a1d5 5303 break;
6fc6879b 5304 default:
61323e70 5305 wpa_printf(MSG_INFO, "unknown mgmt cb frame subtype %d", stype);
6fc6879b
JM
5306 break;
5307 }
5308}
5309
5310
6fc6879b
JM
5311int ieee802_11_get_mib(struct hostapd_data *hapd, char *buf, size_t buflen)
5312{
5313 /* TODO */
5314 return 0;
5315}
5316
5317
5318int ieee802_11_get_mib_sta(struct hostapd_data *hapd, struct sta_info *sta,
5319 char *buf, size_t buflen)
5320{
5321 /* TODO */
5322 return 0;
5323}
5324
f8b1f695
JM
5325
5326void hostapd_tx_status(struct hostapd_data *hapd, const u8 *addr,
5327 const u8 *buf, size_t len, int ack)
5328{
5329 struct sta_info *sta;
5330 struct hostapd_iface *iface = hapd->iface;
5331
5332 sta = ap_get_sta(hapd, addr);
5333 if (sta == NULL && iface->num_bss > 1) {
5334 size_t j;
5335 for (j = 0; j < iface->num_bss; j++) {
5336 hapd = iface->bss[j];
5337 sta = ap_get_sta(hapd, addr);
5338 if (sta)
5339 break;
5340 }
5341 }
0c01d65d 5342 if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC))
f8b1f695
JM
5343 return;
5344 if (sta->flags & WLAN_STA_PENDING_POLL) {
5345 wpa_printf(MSG_DEBUG, "STA " MACSTR " %s pending "
5346 "activity poll", MAC2STR(sta->addr),
5347 ack ? "ACKed" : "did not ACK");
5348 if (ack)
5349 sta->flags &= ~WLAN_STA_PENDING_POLL;
5350 }
5351
5352 ieee802_1x_tx_status(hapd, sta, buf, len, ack);
5353}
5354
5355
dd840f79
JB
5356void hostapd_eapol_tx_status(struct hostapd_data *hapd, const u8 *dst,
5357 const u8 *data, size_t len, int ack)
5358{
5359 struct sta_info *sta;
5360 struct hostapd_iface *iface = hapd->iface;
5361
5362 sta = ap_get_sta(hapd, dst);
5363 if (sta == NULL && iface->num_bss > 1) {
5364 size_t j;
5365 for (j = 0; j < iface->num_bss; j++) {
5366 hapd = iface->bss[j];
5367 sta = ap_get_sta(hapd, dst);
5368 if (sta)
5369 break;
5370 }
5371 }
d9a38716
JM
5372 if (sta == NULL || !(sta->flags & WLAN_STA_ASSOC)) {
5373 wpa_printf(MSG_DEBUG, "Ignore TX status for Data frame to STA "
5374 MACSTR " that is not currently associated",
5375 MAC2STR(dst));
dd840f79 5376 return;
d9a38716 5377 }
dd840f79
JB
5378
5379 ieee802_1x_eapol_tx_status(hapd, sta, data, len, ack);
5380}
5381
5382
bcf24348
JB
5383void hostapd_client_poll_ok(struct hostapd_data *hapd, const u8 *addr)
5384{
5385 struct sta_info *sta;
5386 struct hostapd_iface *iface = hapd->iface;
5387
5388 sta = ap_get_sta(hapd, addr);
5389 if (sta == NULL && iface->num_bss > 1) {
5390 size_t j;
5391 for (j = 0; j < iface->num_bss; j++) {
5392 hapd = iface->bss[j];
5393 sta = ap_get_sta(hapd, addr);
5394 if (sta)
5395 break;
5396 }
5397 }
5398 if (sta == NULL)
5399 return;
1854eeca
JM
5400 wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_POLL_OK MACSTR,
5401 MAC2STR(sta->addr));
bcf24348
JB
5402 if (!(sta->flags & WLAN_STA_PENDING_POLL))
5403 return;
5404
5405 wpa_printf(MSG_DEBUG, "STA " MACSTR " ACKed pending "
5406 "activity poll", MAC2STR(sta->addr));
5407 sta->flags &= ~WLAN_STA_PENDING_POLL;
5408}
5409
5410
fbbfcbac
FF
5411void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
5412 int wds)
f8b1f695
JM
5413{
5414 struct sta_info *sta;
5415
5416 sta = ap_get_sta(hapd, src);
1f0fdaf0
JM
5417 if (sta &&
5418 ((sta->flags & WLAN_STA_ASSOC) ||
5419 ((sta->flags & WLAN_STA_ASSOC_REQ_OK) && wds))) {
99743811
FF
5420 if (!hapd->conf->wds_sta)
5421 return;
5422
1f0fdaf0
JM
5423 if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK)) ==
5424 WLAN_STA_ASSOC_REQ_OK) {
5425 wpa_printf(MSG_DEBUG,
5426 "Postpone 4-address WDS mode enabling for STA "
5427 MACSTR " since TX status for AssocResp is not yet known",
5428 MAC2STR(sta->addr));
5429 sta->pending_wds_enable = 1;
5430 return;
5431 }
5432
fbbfcbac 5433 if (wds && !(sta->flags & WLAN_STA_WDS)) {
69dd2967
SM
5434 int ret;
5435 char ifname_wds[IFNAMSIZ + 1];
5436
fbbfcbac
FF
5437 wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for "
5438 "STA " MACSTR " (aid %u)",
5439 MAC2STR(sta->addr), sta->aid);
5440 sta->flags |= WLAN_STA_WDS;
69dd2967
SM
5441 ret = hostapd_set_wds_sta(hapd, ifname_wds,
5442 sta->addr, sta->aid, 1);
5443 if (!ret)
5444 hostapd_set_wds_encryption(hapd, sta,
5445 ifname_wds);
fbbfcbac 5446 }
f8b1f695 5447 return;
fbbfcbac 5448 }
f8b1f695
JM
5449
5450 wpa_printf(MSG_DEBUG, "Data/PS-poll frame from not associated STA "
5451 MACSTR, MAC2STR(src));
3394def5
JM
5452 if (is_multicast_ether_addr(src) || is_zero_ether_addr(src) ||
5453 os_memcmp(src, hapd->own_addr, ETH_ALEN) == 0) {
5454 /* Broadcast bit set in SA or unexpected SA?! Ignore the frame
5455 * silently. */
1df492df
JM
5456 return;
5457 }
5458
b8281964
JM
5459 if (sta && (sta->flags & WLAN_STA_ASSOC_REQ_OK)) {
5460 wpa_printf(MSG_DEBUG, "Association Response to the STA has "
5461 "already been sent, but no TX status yet known - "
5462 "ignore Class 3 frame issue with " MACSTR,
5463 MAC2STR(src));
5464 return;
5465 }
5466
f8b1f695 5467 if (sta && (sta->flags & WLAN_STA_AUTH))
51e2a27a 5468 hostapd_drv_sta_disassoc(
f8b1f695
JM
5469 hapd, src,
5470 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
5471 else
51e2a27a 5472 hostapd_drv_sta_deauth(
f8b1f695
JM
5473 hapd, src,
5474 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
5475}
5476
5477
6fc6879b 5478#endif /* CONFIG_NATIVE_WINDOWS */