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