2 * hostapd / IEEE 802.11 Management
3 * Copyright (c) 2002-2017, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
9 #include "utils/includes.h"
11 #ifndef CONFIG_NATIVE_WINDOWS
13 #include "utils/common.h"
14 #include "utils/eloop.h"
15 #include "crypto/crypto.h"
16 #include "crypto/sha256.h"
17 #include "crypto/sha384.h"
18 #include "crypto/sha512.h"
19 #include "crypto/random.h"
20 #include "common/ieee802_11_defs.h"
21 #include "common/ieee802_11_common.h"
22 #include "common/wpa_ctrl.h"
23 #include "common/sae.h"
24 #include "common/dpp.h"
25 #include "common/ocv.h"
26 #include "common/wpa_common.h"
27 #include "radius/radius.h"
28 #include "radius/radius_client.h"
34 #include "ieee802_11_auth.h"
36 #include "ieee802_1x.h"
38 #include "pmksa_cache_auth.h"
41 #include "accounting.h"
42 #include "ap_config.h"
44 #include "p2p_hostapd.h"
45 #include "ap_drv_ops.h"
47 #include "hw_features.h"
48 #include "ieee802_11.h"
54 #include "dpp_hostapd.h"
55 #include "gas_query_ap.h"
59 static struct wpabuf
*
60 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
61 struct sta_info
*sta
, u16
*resp
,
62 struct rsn_pmksa_cache_entry
*pmksa
,
63 struct wpabuf
*erp_resp
,
64 const u8
*msk
, size_t msk_len
,
66 #endif /* CONFIG_FILS */
67 static void handle_auth(struct hostapd_data
*hapd
,
68 const struct ieee80211_mgmt
*mgmt
, size_t len
,
69 int rssi
, int from_queue
);
72 u8
* hostapd_eid_multi_ap(struct hostapd_data
*hapd
, u8
*eid
)
76 if (!hapd
->conf
->multi_ap
)
78 if (hapd
->conf
->multi_ap
& BACKHAUL_BSS
)
79 multi_ap_val
|= MULTI_AP_BACKHAUL_BSS
;
80 if (hapd
->conf
->multi_ap
& FRONTHAUL_BSS
)
81 multi_ap_val
|= MULTI_AP_FRONTHAUL_BSS
;
83 return eid
+ add_multi_ap_ie(eid
, 9, multi_ap_val
);
87 u8
* hostapd_eid_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
93 if (hapd
->iface
->current_rates
== NULL
)
96 *pos
++ = WLAN_EID_SUPP_RATES
;
97 num
= hapd
->iface
->num_rates
;
98 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
100 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
102 h2e_required
= (hapd
->conf
->sae_pwe
== 1 ||
103 hostapd_sae_pw_id_in_use(hapd
->conf
) == 2) &&
104 hapd
->conf
->sae_pwe
!= 3 &&
105 wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
);
109 /* rest of the rates are encoded in Extended supported
115 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
118 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
119 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
124 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&& count
< 8) {
126 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
129 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&& count
< 8) {
131 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
134 if (h2e_required
&& count
< 8) {
136 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY
;
143 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
149 if (hapd
->iface
->current_rates
== NULL
)
152 num
= hapd
->iface
->num_rates
;
153 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
155 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
157 h2e_required
= (hapd
->conf
->sae_pwe
== 1 ||
158 hostapd_sae_pw_id_in_use(hapd
->conf
) == 2) &&
159 hapd
->conf
->sae_pwe
!= 3 &&
160 wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
);
167 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
169 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
173 continue; /* already in SuppRates IE */
174 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
175 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
180 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
) {
183 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
186 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
) {
189 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
195 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY
;
202 u8
* hostapd_eid_rm_enabled_capab(struct hostapd_data
*hapd
, u8
*eid
,
207 for (i
= 0; i
< RRM_CAPABILITIES_IE_LEN
; i
++) {
208 if (hapd
->conf
->radio_measurements
[i
])
212 if (i
== RRM_CAPABILITIES_IE_LEN
|| len
< 2 + RRM_CAPABILITIES_IE_LEN
)
215 *eid
++ = WLAN_EID_RRM_ENABLED_CAPABILITIES
;
216 *eid
++ = RRM_CAPABILITIES_IE_LEN
;
217 os_memcpy(eid
, hapd
->conf
->radio_measurements
, RRM_CAPABILITIES_IE_LEN
);
219 return eid
+ RRM_CAPABILITIES_IE_LEN
;
223 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
)
225 int capab
= WLAN_CAPABILITY_ESS
;
230 /* Check if any of configured channels require DFS */
231 dfs
= hostapd_is_dfs_required(hapd
->iface
);
233 wpa_printf(MSG_WARNING
, "Failed to check if DFS is required; ret=%d",
238 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
239 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
240 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
242 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
244 if (hapd
->conf
->ieee802_1x
&&
245 (hapd
->conf
->default_wep_key_len
||
246 hapd
->conf
->individual_wep_key_len
))
253 if (hapd
->conf
->osen
)
255 #endif /* CONFIG_HS20 */
258 capab
|= WLAN_CAPABILITY_PRIVACY
;
260 if (hapd
->iface
->current_mode
&&
261 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
262 hapd
->iface
->num_sta_no_short_slot_time
== 0)
263 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
266 * Currently, Spectrum Management capability bit is set when directly
267 * requested in configuration by spectrum_mgmt_required or when AP is
268 * running on DFS channel.
269 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
271 if (hapd
->iface
->current_mode
&&
272 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
&&
273 (hapd
->iconf
->spectrum_mgmt_required
|| dfs
))
274 capab
|= WLAN_CAPABILITY_SPECTRUM_MGMT
;
276 for (i
= 0; i
< RRM_CAPABILITIES_IE_LEN
; i
++) {
277 if (hapd
->conf
->radio_measurements
[i
]) {
278 capab
|= IEEE80211_CAP_RRM
;
287 #ifndef CONFIG_NO_RC4
288 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
289 u16 auth_transaction
, const u8
*challenge
,
292 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
294 "authentication (shared key, transaction %d)",
297 if (auth_transaction
== 1) {
298 if (!sta
->challenge
) {
299 /* Generate a pseudo-random challenge */
302 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
303 if (sta
->challenge
== NULL
)
304 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
306 if (os_get_random(key
, sizeof(key
)) < 0) {
307 os_free(sta
->challenge
);
308 sta
->challenge
= NULL
;
309 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
312 rc4_skip(key
, sizeof(key
), 0,
313 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
318 if (auth_transaction
!= 3)
319 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
322 if (!iswep
|| !sta
->challenge
|| !challenge
||
323 os_memcmp_const(sta
->challenge
, challenge
,
324 WLAN_AUTH_CHALLENGE_LEN
)) {
325 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
327 "shared key authentication - invalid "
328 "challenge-response");
329 return WLAN_STATUS_CHALLENGE_FAIL
;
332 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
334 "authentication OK (shared key)");
335 sta
->flags
|= WLAN_STA_AUTH
;
336 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
337 os_free(sta
->challenge
);
338 sta
->challenge
= NULL
;
342 #endif /* CONFIG_NO_RC4 */
345 static int send_auth_reply(struct hostapd_data
*hapd
, struct sta_info
*sta
,
346 const u8
*dst
, const u8
*bssid
,
347 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
348 const u8
*ies
, size_t ies_len
, const char *dbg
)
350 struct ieee80211_mgmt
*reply
;
353 int reply_res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
355 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
356 buf
= os_zalloc(rlen
);
360 reply
= (struct ieee80211_mgmt
*) buf
;
361 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
363 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
364 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
365 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
367 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
368 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
369 reply
->u
.auth
.status_code
= host_to_le16(resp
);
372 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
374 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
375 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu) (dbg=%s)",
376 MAC2STR(dst
), auth_alg
, auth_transaction
,
377 resp
, (unsigned long) ies_len
, dbg
);
378 #ifdef CONFIG_TESTING_OPTIONS
380 if (hapd
->conf
->sae_confirm_immediate
== 2 &&
381 auth_alg
== WLAN_AUTH_SAE
) {
382 if (auth_transaction
== 1 &&
383 (resp
== WLAN_STATUS_SUCCESS
||
384 resp
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
)) {
385 wpa_printf(MSG_DEBUG
,
386 "TESTING: Postpone SAE Commit transmission until Confirm is ready");
387 os_free(sta
->sae_postponed_commit
);
388 sta
->sae_postponed_commit
= buf
;
389 sta
->sae_postponed_commit_len
= rlen
;
390 return WLAN_STATUS_SUCCESS
;
393 if (auth_transaction
== 2 && sta
&& sta
->sae_postponed_commit
) {
394 wpa_printf(MSG_DEBUG
,
395 "TESTING: Send postponed SAE Commit first, immediately followed by SAE Confirm");
396 if (hostapd_drv_send_mlme(hapd
,
397 sta
->sae_postponed_commit
,
398 sta
->sae_postponed_commit_len
,
400 wpa_printf(MSG_INFO
, "send_auth_reply: send failed");
401 os_free(sta
->sae_postponed_commit
);
402 sta
->sae_postponed_commit
= NULL
;
403 sta
->sae_postponed_commit_len
= 0;
406 #endif /* CONFIG_SAE */
407 #endif /* CONFIG_TESTING_OPTIONS */
408 if (hostapd_drv_send_mlme(hapd
, reply
, rlen
, 0, NULL
, 0, 0) < 0)
409 wpa_printf(MSG_INFO
, "send_auth_reply: send failed");
411 reply_res
= WLAN_STATUS_SUCCESS
;
419 #ifdef CONFIG_IEEE80211R_AP
420 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
421 u16 auth_transaction
, u16 status
,
422 const u8
*ies
, size_t ies_len
)
424 struct hostapd_data
*hapd
= ctx
;
425 struct sta_info
*sta
;
428 reply_res
= send_auth_reply(hapd
, NULL
, dst
, bssid
, WLAN_AUTH_FT
,
429 auth_transaction
, status
, ies
, ies_len
,
432 sta
= ap_get_sta(hapd
, dst
);
436 if (sta
->added_unassoc
&& (reply_res
!= WLAN_STATUS_SUCCESS
||
437 status
!= WLAN_STATUS_SUCCESS
)) {
438 hostapd_drv_sta_remove(hapd
, sta
->addr
);
439 sta
->added_unassoc
= 0;
443 if (status
!= WLAN_STATUS_SUCCESS
)
446 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
447 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
448 sta
->flags
|= WLAN_STA_AUTH
;
449 mlme_authenticate_indication(hapd
, sta
);
451 #endif /* CONFIG_IEEE80211R_AP */
456 static void sae_set_state(struct sta_info
*sta
, enum sae_state state
,
459 wpa_printf(MSG_DEBUG
, "SAE: State %s -> %s for peer " MACSTR
" (%s)",
460 sae_state_txt(sta
->sae
->state
), sae_state_txt(state
),
461 MAC2STR(sta
->addr
), reason
);
462 sta
->sae
->state
= state
;
466 static struct wpabuf
* auth_build_sae_commit(struct hostapd_data
*hapd
,
467 struct sta_info
*sta
, int update
,
471 const char *password
= NULL
;
472 struct sae_password_entry
*pw
;
473 const char *rx_id
= NULL
;
475 struct sae_pt
*pt
= NULL
;
478 rx_id
= sta
->sae
->tmp
->pw_id
;
479 use_pt
= sta
->sae
->tmp
->h2e
;
482 if (rx_id
&& hapd
->conf
->sae_pwe
!= 3)
484 else if (status_code
== WLAN_STATUS_SUCCESS
)
486 else if (status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
)
489 for (pw
= hapd
->conf
->sae_passwords
; pw
; pw
= pw
->next
) {
490 if (!is_broadcast_ether_addr(pw
->peer_addr
) &&
491 os_memcmp(pw
->peer_addr
, sta
->addr
, ETH_ALEN
) != 0)
493 if ((rx_id
&& !pw
->identifier
) || (!rx_id
&& pw
->identifier
))
495 if (rx_id
&& pw
->identifier
&&
496 os_strcmp(rx_id
, pw
->identifier
) != 0)
498 password
= pw
->password
;
503 password
= hapd
->conf
->ssid
.wpa_passphrase
;
504 pt
= hapd
->conf
->ssid
.pt
;
506 if (!password
|| (use_pt
&& !pt
)) {
507 wpa_printf(MSG_DEBUG
, "SAE: No password available");
511 if (update
&& use_pt
&&
512 sae_prepare_commit_pt(sta
->sae
, pt
, hapd
->own_addr
, sta
->addr
,
516 if (update
&& !use_pt
&&
517 sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
518 (u8
*) password
, os_strlen(password
), rx_id
,
520 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
524 if (pw
&& pw
->vlan_id
) {
525 if (!sta
->sae
->tmp
) {
527 "SAE: No temporary data allocated - cannot store VLAN ID");
530 sta
->sae
->tmp
->vlan_id
= pw
->vlan_id
;
533 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
+
534 (rx_id
? 3 + os_strlen(rx_id
) : 0));
537 sae_write_commit(sta
->sae
, buf
, sta
->sae
->tmp
?
538 sta
->sae
->tmp
->anti_clogging_token
: NULL
, rx_id
);
544 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
545 struct sta_info
*sta
)
549 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
553 sae_write_confirm(sta
->sae
, buf
);
559 static int auth_sae_send_commit(struct hostapd_data
*hapd
,
560 struct sta_info
*sta
,
561 const u8
*bssid
, int update
, int status_code
)
567 data
= auth_build_sae_commit(hapd
, sta
, update
, status_code
);
568 if (!data
&& sta
->sae
->tmp
&& sta
->sae
->tmp
->pw_id
)
569 return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
;
571 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
573 status
= (sta
->sae
->tmp
&& sta
->sae
->tmp
->h2e
) ?
574 WLAN_STATUS_SAE_HASH_TO_ELEMENT
: WLAN_STATUS_SUCCESS
;
575 reply_res
= send_auth_reply(hapd
, sta
, sta
->addr
, bssid
,
577 status
, wpabuf_head(data
),
578 wpabuf_len(data
), "sae-send-commit");
586 static int auth_sae_send_confirm(struct hostapd_data
*hapd
,
587 struct sta_info
*sta
,
593 data
= auth_build_sae_confirm(hapd
, sta
);
595 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
597 reply_res
= send_auth_reply(hapd
, sta
, sta
->addr
, bssid
,
599 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
600 wpabuf_len(data
), "sae-send-confirm");
608 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
610 struct sta_info
*sta
;
611 unsigned int open
= 0;
613 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
616 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
619 if (sta
->sae
->state
!= SAE_COMMITTED
&&
620 sta
->sae
->state
!= SAE_CONFIRMED
)
623 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
627 /* In addition to already existing open SAE sessions, check whether
628 * there are enough pending commit messages in the processing queue to
629 * potentially result in too many open sessions. */
630 if (open
+ dl_list_len(&hapd
->sae_commit_queue
) >=
631 hapd
->conf
->sae_anti_clogging_threshold
)
638 static u8
sae_token_hash(struct hostapd_data
*hapd
, const u8
*addr
)
640 u8 hash
[SHA256_MAC_LEN
];
642 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
643 addr
, ETH_ALEN
, hash
);
648 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
649 const u8
*token
, size_t token_len
)
651 u8 mac
[SHA256_MAC_LEN
];
657 if (token_len
!= SHA256_MAC_LEN
)
659 idx
= sae_token_hash(hapd
, addr
);
660 token_idx
= hapd
->sae_pending_token_idx
[idx
];
661 if (token_idx
== 0 || token_idx
!= WPA_GET_BE16(token
)) {
662 wpa_printf(MSG_DEBUG
, "SAE: Invalid anti-clogging token from "
663 MACSTR
" - token_idx 0x%04x, expected 0x%04x",
664 MAC2STR(addr
), WPA_GET_BE16(token
), token_idx
);
672 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
673 2, addrs
, len
, mac
) < 0 ||
674 os_memcmp_const(token
+ 2, &mac
[2], SHA256_MAC_LEN
- 2) != 0)
677 hapd
->sae_pending_token_idx
[idx
] = 0; /* invalidate used token */
683 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
684 int group
, const u8
*addr
, int h2e
)
688 struct os_reltime now
;
695 os_get_reltime(&now
);
696 if (!os_reltime_initialized(&hapd
->last_sae_token_key_update
) ||
697 os_reltime_expired(&now
, &hapd
->last_sae_token_key_update
, 60) ||
698 hapd
->sae_token_idx
== 0xffff) {
699 if (random_get_bytes(hapd
->sae_token_key
,
700 sizeof(hapd
->sae_token_key
)) < 0)
702 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
703 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
704 hapd
->last_sae_token_key_update
= now
;
705 hapd
->sae_token_idx
= 0;
706 os_memset(hapd
->sae_pending_token_idx
, 0,
707 sizeof(hapd
->sae_pending_token_idx
));
710 buf
= wpabuf_alloc(sizeof(le16
) + 3 + SHA256_MAC_LEN
);
714 wpabuf_put_le16(buf
, group
); /* Finite Cyclic Group */
717 /* Encapsulate Anti-clogging Token field in a container IE */
718 wpabuf_put_u8(buf
, WLAN_EID_EXTENSION
);
719 wpabuf_put_u8(buf
, 1 + SHA256_MAC_LEN
);
720 wpabuf_put_u8(buf
, WLAN_EID_EXT_ANTI_CLOGGING_TOKEN
);
723 p_idx
= sae_token_hash(hapd
, addr
);
724 token_idx
= hapd
->sae_pending_token_idx
[p_idx
];
726 hapd
->sae_token_idx
++;
727 token_idx
= hapd
->sae_token_idx
;
728 hapd
->sae_pending_token_idx
[p_idx
] = token_idx
;
730 WPA_PUT_BE16(idx
, token_idx
);
731 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
735 len
[1] = sizeof(idx
);
736 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
737 2, addrs
, len
, token
) < 0) {
741 WPA_PUT_BE16(token
, token_idx
);
747 static int sae_check_big_sync(struct hostapd_data
*hapd
, struct sta_info
*sta
)
749 if (sta
->sae
->sync
> hapd
->conf
->sae_sync
) {
750 sae_set_state(sta
, SAE_NOTHING
, "Sync > dot11RSNASAESync");
758 static void auth_sae_retransmit_timer(void *eloop_ctx
, void *eloop_data
)
760 struct hostapd_data
*hapd
= eloop_ctx
;
761 struct sta_info
*sta
= eloop_data
;
764 if (sae_check_big_sync(hapd
, sta
))
767 wpa_printf(MSG_DEBUG
, "SAE: Auth SAE retransmit timer for " MACSTR
768 " (sync=%d state=%s)",
769 MAC2STR(sta
->addr
), sta
->sae
->sync
,
770 sae_state_txt(sta
->sae
->state
));
772 switch (sta
->sae
->state
) {
774 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0, -1);
775 eloop_register_timeout(0,
776 hapd
->dot11RSNASAERetransPeriod
* 1000,
777 auth_sae_retransmit_timer
, hapd
, sta
);
780 ret
= auth_sae_send_confirm(hapd
, sta
, hapd
->own_addr
);
781 eloop_register_timeout(0,
782 hapd
->dot11RSNASAERetransPeriod
* 1000,
783 auth_sae_retransmit_timer
, hapd
, sta
);
790 if (ret
!= WLAN_STATUS_SUCCESS
)
791 wpa_printf(MSG_INFO
, "SAE: Failed to retransmit: ret=%d", ret
);
795 void sae_clear_retransmit_timer(struct hostapd_data
*hapd
, struct sta_info
*sta
)
797 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
801 static void sae_set_retransmit_timer(struct hostapd_data
*hapd
,
802 struct sta_info
*sta
)
804 if (!(hapd
->conf
->mesh
& MESH_ENABLED
))
807 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
808 eloop_register_timeout(0, hapd
->dot11RSNASAERetransPeriod
* 1000,
809 auth_sae_retransmit_timer
, hapd
, sta
);
813 static void sae_sme_send_external_auth_status(struct hostapd_data
*hapd
,
814 struct sta_info
*sta
, u16 status
)
816 struct external_auth params
;
818 os_memset(¶ms
, 0, sizeof(params
));
819 params
.status
= status
;
820 params
.bssid
= sta
->addr
;
821 if (status
== WLAN_STATUS_SUCCESS
&& sta
->sae
&&
822 !hapd
->conf
->disable_pmksa_caching
)
823 params
.pmkid
= sta
->sae
->pmkid
;
825 hostapd_drv_send_external_auth_status(hapd
, ¶ms
);
829 void sae_accept_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
831 #ifndef CONFIG_NO_VLAN
832 struct vlan_description vlan_desc
;
834 if (sta
->sae
->tmp
&& sta
->sae
->tmp
->vlan_id
> 0) {
835 wpa_printf(MSG_DEBUG
, "SAE: Assign STA " MACSTR
837 MAC2STR(sta
->addr
), sta
->sae
->tmp
->vlan_id
);
839 os_memset(&vlan_desc
, 0, sizeof(vlan_desc
));
840 vlan_desc
.notempty
= 1;
841 vlan_desc
.untagged
= sta
->sae
->tmp
->vlan_id
;
842 if (!hostapd_vlan_valid(hapd
->conf
->vlan
, &vlan_desc
)) {
844 "Invalid VLAN ID %d in sae_password",
845 sta
->sae
->tmp
->vlan_id
);
849 if (ap_sta_set_vlan(hapd
, sta
, &vlan_desc
) < 0 ||
850 ap_sta_bind_vlan(hapd
, sta
) < 0) {
852 "Failed to assign VLAN ID %d from sae_password to "
853 MACSTR
, sta
->sae
->tmp
->vlan_id
,
858 #endif /* CONFIG_NO_VLAN */
860 sta
->flags
|= WLAN_STA_AUTH
;
861 sta
->auth_alg
= WLAN_AUTH_SAE
;
862 mlme_authenticate_indication(hapd
, sta
);
863 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
864 sae_set_state(sta
, SAE_ACCEPTED
, "Accept Confirm");
865 crypto_bignum_deinit(sta
->sae
->peer_commit_scalar_accepted
, 0);
866 sta
->sae
->peer_commit_scalar_accepted
= sta
->sae
->peer_commit_scalar
;
867 sta
->sae
->peer_commit_scalar
= NULL
;
868 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
869 sta
->sae
->pmk
, sta
->sae
->pmkid
);
870 sae_sme_send_external_auth_status(hapd
, sta
, WLAN_STATUS_SUCCESS
);
874 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
875 const u8
*bssid
, u16 auth_transaction
, u16 status_code
,
876 int allow_reuse
, int *sta_removed
)
882 if (auth_transaction
!= 1 && auth_transaction
!= 2)
883 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
885 wpa_printf(MSG_DEBUG
, "SAE: Peer " MACSTR
" state=%s auth_trans=%u",
886 MAC2STR(sta
->addr
), sae_state_txt(sta
->sae
->state
),
888 switch (sta
->sae
->state
) {
890 if (auth_transaction
== 1) {
892 sta
->sae
->tmp
->h2e
= status_code
==
893 WLAN_STATUS_SAE_HASH_TO_ELEMENT
;
894 ret
= auth_sae_send_commit(hapd
, sta
, bssid
,
895 !allow_reuse
, status_code
);
898 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
900 if (sae_process_commit(sta
->sae
) < 0)
901 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
904 * In mesh case, both Commit and Confirm are sent
905 * immediately. In infrastructure BSS, by default, only
906 * a single Authentication frame (Commit) is expected
907 * from the AP here and the second one (Confirm) will
908 * be sent once the STA has sent its second
909 * Authentication frame (Confirm). This behavior can be
910 * overridden with explicit configuration so that the
911 * infrastructure BSS case sends both frames together.
913 if ((hapd
->conf
->mesh
& MESH_ENABLED
) ||
914 hapd
->conf
->sae_confirm_immediate
) {
916 * Send both Commit and Confirm immediately
917 * based on SAE finite state machine
918 * Nothing -> Confirm transition.
920 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
923 sae_set_state(sta
, SAE_CONFIRMED
,
924 "Sent Confirm (mesh)");
927 * For infrastructure BSS, send only the Commit
928 * message now to get alternating sequence of
929 * Authentication frames between the AP and STA.
930 * Confirm will be sent in
931 * Committed -> Confirmed/Accepted transition
932 * when receiving Confirm from STA.
936 sae_set_retransmit_timer(hapd
, sta
);
938 hostapd_logger(hapd
, sta
->addr
,
939 HOSTAPD_MODULE_IEEE80211
,
941 "SAE confirm before commit");
945 sae_clear_retransmit_timer(hapd
, sta
);
946 if (auth_transaction
== 1) {
947 if (sae_process_commit(sta
->sae
) < 0)
948 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
950 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
953 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
955 sae_set_retransmit_timer(hapd
, sta
);
956 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
958 * In mesh case, follow SAE finite state machine and
959 * send Commit now, if sync count allows.
961 if (sae_check_big_sync(hapd
, sta
))
962 return WLAN_STATUS_SUCCESS
;
965 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 0,
970 sae_set_retransmit_timer(hapd
, sta
);
973 * For instructure BSS, send the postponed Confirm from
974 * Nothing -> Confirmed transition that was reduced to
975 * Nothing -> Committed above.
977 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
981 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
984 * Since this was triggered on Confirm RX, run another
985 * step to get to Accepted without waiting for
988 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
,
989 WLAN_STATUS_SUCCESS
, 0, sta_removed
);
993 sae_clear_retransmit_timer(hapd
, sta
);
994 if (auth_transaction
== 1) {
995 if (sae_check_big_sync(hapd
, sta
))
996 return WLAN_STATUS_SUCCESS
;
999 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1,
1004 if (sae_process_commit(sta
->sae
) < 0)
1005 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1007 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
1011 sae_set_retransmit_timer(hapd
, sta
);
1013 sta
->sae
->send_confirm
= 0xffff;
1014 sae_accept_sta(hapd
, sta
);
1018 if (auth_transaction
== 1 &&
1019 (hapd
->conf
->mesh
& MESH_ENABLED
)) {
1020 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
1021 ") doing reauthentication",
1022 MAC2STR(sta
->addr
));
1023 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
1024 ap_free_sta(hapd
, sta
);
1026 } else if (auth_transaction
== 1) {
1027 wpa_printf(MSG_DEBUG
, "SAE: Start reauthentication");
1028 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1,
1032 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
1034 if (sae_process_commit(sta
->sae
) < 0)
1035 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1037 sae_set_retransmit_timer(hapd
, sta
);
1039 if (sae_check_big_sync(hapd
, sta
))
1040 return WLAN_STATUS_SUCCESS
;
1043 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
1044 sae_clear_temp_data(sta
->sae
);
1050 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
1052 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1054 return WLAN_STATUS_SUCCESS
;
1058 static void sae_pick_next_group(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1060 struct sae_data
*sae
= sta
->sae
;
1061 int i
, *groups
= hapd
->conf
->sae_groups
;
1062 int default_groups
[] = { 19, 0 };
1064 if (sae
->state
!= SAE_COMMITTED
)
1067 wpa_printf(MSG_DEBUG
, "SAE: Previously selected group: %d", sae
->group
);
1070 groups
= default_groups
;
1071 for (i
= 0; groups
[i
] > 0; i
++) {
1072 if (sae
->group
== groups
[i
])
1076 if (groups
[i
] <= 0) {
1077 wpa_printf(MSG_DEBUG
,
1078 "SAE: Previously selected group not found from the current configuration");
1084 if (groups
[i
] <= 0) {
1085 wpa_printf(MSG_DEBUG
,
1086 "SAE: No alternative group enabled");
1090 if (sae_set_group(sae
, groups
[i
]) < 0)
1095 wpa_printf(MSG_DEBUG
, "SAE: Selected new group: %d", groups
[i
]);
1099 static int sae_status_success(struct hostapd_data
*hapd
, u16 status_code
)
1101 int sae_pwe
= hapd
->conf
->sae_pwe
;
1104 id_in_use
= hostapd_sae_pw_id_in_use(hapd
->conf
);
1105 if (id_in_use
== 2 && sae_pwe
!= 3)
1107 else if (id_in_use
== 1 && sae_pwe
== 0)
1110 return ((sae_pwe
== 0 || sae_pwe
== 3) &&
1111 status_code
== WLAN_STATUS_SUCCESS
) ||
1113 status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
) ||
1115 (status_code
== WLAN_STATUS_SUCCESS
||
1116 status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
));
1120 static int sae_is_group_enabled(struct hostapd_data
*hapd
, int group
)
1122 int *groups
= hapd
->conf
->sae_groups
;
1123 int default_groups
[] = { 19, 0 };
1127 groups
= default_groups
;
1129 for (i
= 0; groups
[i
] > 0; i
++) {
1130 if (groups
[i
] == group
)
1138 static int check_sae_rejected_groups(struct hostapd_data
*hapd
,
1139 const struct wpabuf
*groups
)
1147 pos
= wpabuf_head(groups
);
1148 count
= wpabuf_len(groups
) / 2;
1149 for (i
= 0; i
< count
; i
++) {
1153 group
= WPA_GET_LE16(pos
);
1155 enabled
= sae_is_group_enabled(hapd
, group
);
1156 wpa_printf(MSG_DEBUG
, "SAE: Rejected group %u is %s",
1157 group
, enabled
? "enabled" : "disabled");
1166 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1167 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1168 u16 auth_transaction
, u16 status_code
)
1170 int resp
= WLAN_STATUS_SUCCESS
;
1171 struct wpabuf
*data
= NULL
;
1172 int *groups
= hapd
->conf
->sae_groups
;
1173 int default_groups
[] = { 19, 0 };
1174 const u8
*pos
, *end
;
1175 int sta_removed
= 0;
1178 groups
= default_groups
;
1180 #ifdef CONFIG_TESTING_OPTIONS
1181 if (hapd
->conf
->sae_reflection_attack
&& auth_transaction
== 1) {
1182 wpa_printf(MSG_DEBUG
, "SAE: TESTING - reflection attack");
1183 pos
= mgmt
->u
.auth
.variable
;
1184 end
= ((const u8
*) mgmt
) + len
;
1185 send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1186 auth_transaction
, resp
, pos
, end
- pos
,
1187 "auth-sae-reflection-attack");
1191 if (hapd
->conf
->sae_commit_override
&& auth_transaction
== 1) {
1192 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
1193 send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1194 auth_transaction
, resp
,
1195 wpabuf_head(hapd
->conf
->sae_commit_override
),
1196 wpabuf_len(hapd
->conf
->sae_commit_override
),
1197 "sae-commit-override");
1200 #endif /* CONFIG_TESTING_OPTIONS */
1202 if (auth_transaction
!= 1 ||
1203 !sae_status_success(hapd
, status_code
)) {
1204 wpa_printf(MSG_DEBUG
, "SAE: Unexpected Status Code %u",
1206 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1209 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
1214 sae_set_state(sta
, SAE_NOTHING
, "Init");
1218 if (sta
->mesh_sae_pmksa_caching
) {
1219 wpa_printf(MSG_DEBUG
,
1220 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
1221 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
1222 sta
->mesh_sae_pmksa_caching
= 0;
1225 if (auth_transaction
== 1) {
1226 const u8
*token
= NULL
;
1227 size_t token_len
= 0;
1228 int allow_reuse
= 0;
1230 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1231 HOSTAPD_LEVEL_DEBUG
,
1232 "start SAE authentication (RX commit, status=%u (%s))",
1233 status_code
, status2str(status_code
));
1235 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1236 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
1238 pos
= mgmt
->u
.auth
.variable
;
1239 end
= ((const u8
*) mgmt
) + len
;
1240 if (pos
+ sizeof(le16
) > end
) {
1241 wpa_printf(MSG_ERROR
,
1242 "SAE: Too short anti-clogging token request");
1243 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1246 resp
= sae_group_allowed(sta
->sae
, groups
,
1248 if (resp
!= WLAN_STATUS_SUCCESS
) {
1249 wpa_printf(MSG_ERROR
,
1250 "SAE: Invalid group in anti-clogging token request");
1253 pos
+= sizeof(le16
);
1255 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
1256 sta
->sae
->tmp
->anti_clogging_token
=
1257 wpabuf_alloc_copy(pos
, end
- pos
);
1258 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
1259 wpa_printf(MSG_ERROR
,
1260 "SAE: Failed to alloc for anti-clogging token");
1261 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1266 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
1267 * is 76, a new Commit Message shall be constructed
1268 * with the Anti-Clogging Token from the received
1269 * Authentication frame, and the commit-scalar and
1270 * COMMIT-ELEMENT previously sent.
1272 resp
= auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0,
1274 if (resp
!= WLAN_STATUS_SUCCESS
) {
1275 wpa_printf(MSG_ERROR
,
1276 "SAE: Failed to send commit message");
1279 sae_set_state(sta
, SAE_COMMITTED
,
1280 "Sent Commit (anti-clogging token case in mesh)");
1282 sae_set_retransmit_timer(hapd
, sta
);
1286 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1288 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1290 wpa_printf(MSG_DEBUG
,
1291 "SAE: Peer did not accept our SAE group");
1292 sae_pick_next_group(hapd
, sta
);
1296 if (!sae_status_success(hapd
, status_code
))
1299 if (!(hapd
->conf
->mesh
& MESH_ENABLED
) &&
1300 sta
->sae
->state
== SAE_COMMITTED
) {
1301 /* This is needed in the infrastructure BSS case to
1302 * address a sequence where a STA entry may remain in
1303 * hostapd across two attempts to do SAE authentication
1304 * by the same STA. The second attempt may end up trying
1305 * to use a different group and that would not be
1306 * allowed if we remain in Committed state with the
1307 * previously set parameters. */
1308 pos
= mgmt
->u
.auth
.variable
;
1309 end
= ((const u8
*) mgmt
) + len
;
1310 if (end
- pos
>= (int) sizeof(le16
) &&
1311 sae_group_allowed(sta
->sae
, groups
,
1312 WPA_GET_LE16(pos
)) ==
1313 WLAN_STATUS_SUCCESS
) {
1314 /* Do not waste resources deriving the same PWE
1315 * again since the same group is reused. */
1316 sae_set_state(sta
, SAE_NOTHING
,
1317 "Allow previous PWE to be reused");
1320 sae_set_state(sta
, SAE_NOTHING
,
1321 "Clear existing state to allow restart");
1322 sae_clear_data(sta
->sae
);
1326 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
1327 ((const u8
*) mgmt
) + len
-
1328 mgmt
->u
.auth
.variable
, &token
,
1329 &token_len
, groups
, status_code
==
1330 WLAN_STATUS_SAE_HASH_TO_ELEMENT
);
1331 if (resp
== SAE_SILENTLY_DISCARD
) {
1332 wpa_printf(MSG_DEBUG
,
1333 "SAE: Drop commit message from " MACSTR
" due to reflection attack",
1334 MAC2STR(sta
->addr
));
1338 if (resp
== WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
) {
1339 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
1340 WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER
1341 MACSTR
, MAC2STR(sta
->addr
));
1342 sae_clear_retransmit_timer(hapd
, sta
);
1343 sae_set_state(sta
, SAE_NOTHING
,
1344 "Unknown Password Identifier");
1348 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
1350 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
1351 "incorrect token from " MACSTR
,
1352 MAC2STR(sta
->addr
));
1353 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1357 if (resp
!= WLAN_STATUS_SUCCESS
)
1360 if (sta
->sae
->tmp
&&
1361 check_sae_rejected_groups(
1362 hapd
, sta
->sae
->tmp
->peer_rejected_groups
)) {
1363 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1367 if (!token
&& use_sae_anti_clogging(hapd
) && !allow_reuse
) {
1370 wpa_printf(MSG_DEBUG
,
1371 "SAE: Request anti-clogging token from "
1372 MACSTR
, MAC2STR(sta
->addr
));
1374 h2e
= sta
->sae
->tmp
->h2e
;
1375 if (status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
)
1377 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
1379 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
1380 if (hapd
->conf
->mesh
& MESH_ENABLED
)
1381 sae_set_state(sta
, SAE_NOTHING
,
1382 "Request anti-clogging token case in mesh");
1386 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1387 status_code
, allow_reuse
, &sta_removed
);
1388 } else if (auth_transaction
== 2) {
1389 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1390 HOSTAPD_LEVEL_DEBUG
,
1391 "SAE authentication (RX confirm, status=%u (%s))",
1392 status_code
, status2str(status_code
));
1393 if (status_code
!= WLAN_STATUS_SUCCESS
)
1395 if (sta
->sae
->state
>= SAE_CONFIRMED
||
1396 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
1399 u16 peer_send_confirm
;
1401 var
= mgmt
->u
.auth
.variable
;
1402 var_len
= ((u8
*) mgmt
) + len
- mgmt
->u
.auth
.variable
;
1404 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1408 peer_send_confirm
= WPA_GET_LE16(var
);
1410 if (sta
->sae
->state
== SAE_ACCEPTED
&&
1411 (peer_send_confirm
<= sta
->sae
->rc
||
1412 peer_send_confirm
== 0xffff)) {
1413 wpa_printf(MSG_DEBUG
,
1414 "SAE: Silently ignore unexpected Confirm from peer "
1416 " (peer-send-confirm=%u Rc=%u)",
1418 peer_send_confirm
, sta
->sae
->rc
);
1422 if (sae_check_confirm(sta
->sae
, var
, var_len
) < 0) {
1423 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1426 sta
->sae
->rc
= peer_send_confirm
;
1428 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1429 status_code
, 0, &sta_removed
);
1431 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1432 HOSTAPD_LEVEL_DEBUG
,
1433 "unexpected SAE authentication transaction %u (status=%u (%s))",
1434 auth_transaction
, status_code
,
1435 status2str(status_code
));
1436 if (status_code
!= WLAN_STATUS_SUCCESS
)
1438 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1442 if (!sta_removed
&& resp
!= WLAN_STATUS_SUCCESS
) {
1443 pos
= mgmt
->u
.auth
.variable
;
1444 end
= ((const u8
*) mgmt
) + len
;
1446 /* Copy the Finite Cyclic Group field from the request if we
1447 * rejected it as unsupported group. */
1448 if (resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1449 !data
&& end
- pos
>= 2)
1450 data
= wpabuf_alloc_copy(pos
, 2);
1452 sae_sme_send_external_auth_status(hapd
, sta
, resp
);
1453 send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1454 auth_transaction
, resp
,
1455 data
? wpabuf_head(data
) : (u8
*) "",
1456 data
? wpabuf_len(data
) : 0, "auth-sae");
1460 if (!sta_removed
&& sta
->added_unassoc
&&
1461 (resp
!= WLAN_STATUS_SUCCESS
||
1462 status_code
!= WLAN_STATUS_SUCCESS
)) {
1463 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1464 sta
->added_unassoc
= 0;
1471 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1472 * @hapd: BSS data for the device initiating the authentication
1473 * @sta: the peer to which commit authentication frame is sent
1475 * This function implements Init event handling (IEEE Std 802.11-2012,
1476 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1477 * sta->sae structure should be initialized appropriately via a call to
1478 * sae_prepare_commit().
1480 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1484 if (!sta
->sae
|| !sta
->sae
->tmp
)
1487 if (sta
->sae
->state
!= SAE_NOTHING
)
1490 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0, -1);
1494 sae_set_state(sta
, SAE_COMMITTED
, "Init and sent commit");
1496 sae_set_retransmit_timer(hapd
, sta
);
1502 void auth_sae_process_commit(void *eloop_ctx
, void *user_ctx
)
1504 struct hostapd_data
*hapd
= eloop_ctx
;
1505 struct hostapd_sae_commit_queue
*q
;
1506 unsigned int queue_len
;
1508 q
= dl_list_first(&hapd
->sae_commit_queue
,
1509 struct hostapd_sae_commit_queue
, list
);
1512 wpa_printf(MSG_DEBUG
,
1513 "SAE: Process next available message from queue");
1514 dl_list_del(&q
->list
);
1515 handle_auth(hapd
, (const struct ieee80211_mgmt
*) q
->msg
, q
->len
,
1519 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1521 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1522 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1527 static void auth_sae_queue(struct hostapd_data
*hapd
,
1528 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1531 struct hostapd_sae_commit_queue
*q
, *q2
;
1532 unsigned int queue_len
;
1533 const struct ieee80211_mgmt
*mgmt2
;
1535 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1536 if (queue_len
>= 15) {
1537 wpa_printf(MSG_DEBUG
,
1538 "SAE: No more room in message queue - drop the new frame from "
1539 MACSTR
, MAC2STR(mgmt
->sa
));
1543 wpa_printf(MSG_DEBUG
, "SAE: Queue Authentication message from "
1544 MACSTR
" for processing (queue_len %u)", MAC2STR(mgmt
->sa
),
1546 q
= os_zalloc(sizeof(*q
) + len
);
1551 os_memcpy(q
->msg
, mgmt
, len
);
1553 /* Check whether there is already a queued Authentication frame from the
1554 * same station with the same transaction number and if so, replace that
1555 * queue entry with the new one. This avoids issues with a peer that
1556 * sends multiple times (e.g., due to frequent SAE retries). There is no
1557 * point in us trying to process the old attempts after a new one has
1558 * obsoleted them. */
1559 dl_list_for_each(q2
, &hapd
->sae_commit_queue
,
1560 struct hostapd_sae_commit_queue
, list
) {
1561 mgmt2
= (const struct ieee80211_mgmt
*) q2
->msg
;
1562 if (os_memcmp(mgmt
->sa
, mgmt2
->sa
, ETH_ALEN
) == 0 &&
1563 mgmt
->u
.auth
.auth_transaction
==
1564 mgmt2
->u
.auth
.auth_transaction
) {
1565 wpa_printf(MSG_DEBUG
,
1566 "SAE: Replace queued message from same STA with same transaction number");
1567 dl_list_add(&q2
->list
, &q
->list
);
1568 dl_list_del(&q2
->list
);
1574 /* No pending identical entry, so add to the end of the queue */
1575 dl_list_add_tail(&hapd
->sae_commit_queue
, &q
->list
);
1578 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1580 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1585 static int auth_sae_queued_addr(struct hostapd_data
*hapd
, const u8
*addr
)
1587 struct hostapd_sae_commit_queue
*q
;
1588 const struct ieee80211_mgmt
*mgmt
;
1590 dl_list_for_each(q
, &hapd
->sae_commit_queue
,
1591 struct hostapd_sae_commit_queue
, list
) {
1592 mgmt
= (const struct ieee80211_mgmt
*) q
->msg
;
1593 if (os_memcmp(addr
, mgmt
->sa
, ETH_ALEN
) == 0)
1600 #endif /* CONFIG_SAE */
1603 static u16
wpa_res_to_status_code(int res
)
1605 if (res
== WPA_INVALID_GROUP
)
1606 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1607 if (res
== WPA_INVALID_PAIRWISE
)
1608 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1609 if (res
== WPA_INVALID_AKMP
)
1610 return WLAN_STATUS_AKMP_NOT_VALID
;
1611 if (res
== WPA_ALLOC_FAIL
)
1612 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1613 if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1614 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1615 if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1616 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
1617 if (res
== WPA_INVALID_MDIE
)
1618 return WLAN_STATUS_INVALID_MDIE
;
1619 if (res
== WPA_INVALID_PMKID
)
1620 return WLAN_STATUS_INVALID_PMKID
;
1621 if (res
!= WPA_IE_OK
)
1622 return WLAN_STATUS_INVALID_IE
;
1623 return WLAN_STATUS_SUCCESS
;
1629 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1630 struct sta_info
*sta
, u16 resp
,
1631 struct wpabuf
*data
, int pub
);
1633 void handle_auth_fils(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1634 const u8
*pos
, size_t len
, u16 auth_alg
,
1635 u16 auth_transaction
, u16 status_code
,
1636 void (*cb
)(struct hostapd_data
*hapd
,
1637 struct sta_info
*sta
, u16 resp
,
1638 struct wpabuf
*data
, int pub
))
1640 u16 resp
= WLAN_STATUS_SUCCESS
;
1642 struct ieee802_11_elems elems
;
1644 struct wpa_ie_data rsn
;
1645 struct rsn_pmksa_cache_entry
*pmksa
= NULL
;
1647 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
1652 wpa_hexdump(MSG_DEBUG
, "FILS: Authentication frame fields",
1656 #ifdef CONFIG_FILS_SK_PFS
1657 if (auth_alg
== WLAN_AUTH_FILS_SK_PFS
) {
1662 /* Using FILS PFS */
1664 /* Finite Cyclic Group */
1665 if (end
- pos
< 2) {
1666 wpa_printf(MSG_DEBUG
,
1667 "FILS: No room for Finite Cyclic Group");
1668 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1671 group
= WPA_GET_LE16(pos
);
1673 if (group
!= hapd
->conf
->fils_dh_group
) {
1674 wpa_printf(MSG_DEBUG
,
1675 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1676 group
, hapd
->conf
->fils_dh_group
);
1677 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1681 crypto_ecdh_deinit(sta
->fils_ecdh
);
1682 sta
->fils_ecdh
= crypto_ecdh_init(group
);
1683 if (!sta
->fils_ecdh
) {
1684 wpa_printf(MSG_INFO
,
1685 "FILS: Could not initialize ECDH with group %d",
1687 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1691 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1693 wpa_printf(MSG_DEBUG
,
1694 "FILS: Failed to derive ECDH public key");
1695 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1698 elem_len
= wpabuf_len(pub
);
1702 if ((size_t) (end
- pos
) < elem_len
) {
1703 wpa_printf(MSG_DEBUG
, "FILS: No room for Element");
1704 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1708 wpabuf_free(sta
->fils_g_sta
);
1709 sta
->fils_g_sta
= wpabuf_alloc_copy(pos
, elem_len
);
1710 wpabuf_clear_free(sta
->fils_dh_ss
);
1711 sta
->fils_dh_ss
= crypto_ecdh_set_peerkey(sta
->fils_ecdh
, 1,
1713 if (!sta
->fils_dh_ss
) {
1714 wpa_printf(MSG_DEBUG
, "FILS: ECDH operation failed");
1715 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1718 wpa_hexdump_buf_key(MSG_DEBUG
, "FILS: DH_SS", sta
->fils_dh_ss
);
1721 crypto_ecdh_deinit(sta
->fils_ecdh
);
1722 sta
->fils_ecdh
= NULL
;
1723 wpabuf_clear_free(sta
->fils_dh_ss
);
1724 sta
->fils_dh_ss
= NULL
;
1726 #endif /* CONFIG_FILS_SK_PFS */
1728 wpa_hexdump(MSG_DEBUG
, "FILS: Remaining IEs", pos
, end
- pos
);
1729 if (ieee802_11_parse_elems(pos
, end
- pos
, &elems
, 1) == ParseFailed
) {
1730 wpa_printf(MSG_DEBUG
, "FILS: Could not parse elements");
1731 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1736 wpa_hexdump(MSG_DEBUG
, "FILS: RSN element",
1737 elems
.rsn_ie
, elems
.rsn_ie_len
);
1738 if (!elems
.rsn_ie
||
1739 wpa_parse_wpa_ie_rsn(elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1741 wpa_printf(MSG_DEBUG
, "FILS: No valid RSN element");
1742 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1747 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
1750 wpa_printf(MSG_DEBUG
,
1751 "FILS: Failed to initialize RSN state machine");
1752 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1756 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1758 elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1759 elems
.rsnxe
? elems
.rsnxe
- 2 : NULL
,
1760 elems
.rsnxe
? elems
.rsnxe_len
+ 2 : 0,
1761 elems
.mdie
, elems
.mdie_len
, NULL
, 0);
1762 resp
= wpa_res_to_status_code(res
);
1763 if (resp
!= WLAN_STATUS_SUCCESS
)
1766 if (!elems
.fils_nonce
) {
1767 wpa_printf(MSG_DEBUG
, "FILS: No FILS Nonce field");
1768 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1771 wpa_hexdump(MSG_DEBUG
, "FILS: SNonce", elems
.fils_nonce
,
1773 os_memcpy(sta
->fils_snonce
, elems
.fils_nonce
, FILS_NONCE_LEN
);
1776 if (rsn
.pmkid
&& rsn
.num_pmkid
> 0) {
1780 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID List",
1781 rsn
.pmkid
, rsn
.num_pmkid
* PMKID_LEN
);
1784 num
= rsn
.num_pmkid
;
1786 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID", pmkid
, PMKID_LEN
);
1787 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
,
1791 pmksa
= wpa_auth_pmksa_get_fils_cache_id(hapd
->wpa_auth
,
1800 if (pmksa
&& wpa_auth_sta_key_mgmt(sta
->wpa_sm
) != pmksa
->akmp
) {
1801 wpa_printf(MSG_DEBUG
,
1802 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1803 wpa_auth_sta_key_mgmt(sta
->wpa_sm
), pmksa
->akmp
);
1807 wpa_printf(MSG_DEBUG
, "FILS: Found matching PMKSA cache entry");
1810 if (!elems
.fils_session
) {
1811 wpa_printf(MSG_DEBUG
, "FILS: No FILS Session element");
1812 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1815 wpa_hexdump(MSG_DEBUG
, "FILS: FILS Session", elems
.fils_session
,
1817 os_memcpy(sta
->fils_session
, elems
.fils_session
, FILS_SESSION_LEN
);
1819 /* FILS Wrapped Data */
1820 if (elems
.fils_wrapped_data
) {
1821 wpa_hexdump(MSG_DEBUG
, "FILS: Wrapped Data",
1822 elems
.fils_wrapped_data
,
1823 elems
.fils_wrapped_data_len
);
1825 #ifndef CONFIG_NO_RADIUS
1826 if (!sta
->eapol_sm
) {
1828 ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1830 wpa_printf(MSG_DEBUG
,
1831 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
1832 ieee802_1x_encapsulate_radius(
1833 hapd
, sta
, elems
.fils_wrapped_data
,
1834 elems
.fils_wrapped_data_len
);
1835 sta
->fils_pending_cb
= cb
;
1836 wpa_printf(MSG_DEBUG
,
1837 "FILS: Will send Authentication frame once the response from authentication server is available");
1838 sta
->flags
|= WLAN_STA_PENDING_FILS_ERP
;
1839 /* Calculate pending PMKID here so that we do not need
1840 * to maintain a copy of the EAP-Initiate/Reauth
1842 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1843 elems
.fils_wrapped_data
,
1844 elems
.fils_wrapped_data_len
,
1845 sta
->fils_erp_pmkid
) == 0)
1846 sta
->fils_erp_pmkid_set
= 1;
1848 #else /* CONFIG_NO_RADIUS */
1849 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1851 #endif /* CONFIG_NO_RADIUS */
1857 struct wpabuf
*data
;
1860 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, pmksa
, NULL
,
1863 wpa_printf(MSG_DEBUG
,
1864 "%s: prepare_auth_resp_fils() returned failure",
1868 cb(hapd
, sta
, resp
, data
, pub
);
1873 static struct wpabuf
*
1874 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
1875 struct sta_info
*sta
, u16
*resp
,
1876 struct rsn_pmksa_cache_entry
*pmksa
,
1877 struct wpabuf
*erp_resp
,
1878 const u8
*msk
, size_t msk_len
,
1881 u8 fils_nonce
[FILS_NONCE_LEN
];
1883 struct wpabuf
*data
= NULL
;
1886 const u8
*pmk
= NULL
;
1888 u8 pmk_buf
[PMK_LEN_MAX
];
1889 struct wpabuf
*pub
= NULL
;
1891 if (*resp
!= WLAN_STATUS_SUCCESS
)
1894 ie
= wpa_auth_get_wpa_ie(hapd
->wpa_auth
, &ielen
);
1896 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1901 /* Add PMKID of the selected PMKSA into RSNE */
1902 ie_buf
= os_malloc(ielen
+ 2 + 2 + PMKID_LEN
);
1904 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1908 os_memcpy(ie_buf
, ie
, ielen
);
1909 if (wpa_insert_pmkid(ie_buf
, &ielen
, pmksa
->pmkid
) < 0) {
1910 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1916 if (random_get_bytes(fils_nonce
, FILS_NONCE_LEN
) < 0) {
1917 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1920 wpa_hexdump(MSG_DEBUG
, "RSN: Generated FILS Nonce",
1921 fils_nonce
, FILS_NONCE_LEN
);
1923 #ifdef CONFIG_FILS_SK_PFS
1924 if (sta
->fils_dh_ss
&& sta
->fils_ecdh
) {
1925 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1927 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1931 #endif /* CONFIG_FILS_SK_PFS */
1933 data
= wpabuf_alloc(1000 + ielen
+ (pub
? wpabuf_len(pub
) : 0));
1935 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1940 #ifdef CONFIG_FILS_SK_PFS
1942 /* Finite Cyclic Group */
1943 wpabuf_put_le16(data
, hapd
->conf
->fils_dh_group
);
1946 wpabuf_put_buf(data
, pub
);
1948 #endif /* CONFIG_FILS_SK_PFS */
1951 wpabuf_put_data(data
, ie
, ielen
);
1953 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1955 #ifdef CONFIG_IEEE80211R_AP
1956 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) {
1957 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1959 int use_sha384
= wpa_key_mgmt_sha384(
1960 wpa_auth_sta_key_mgmt(sta
->wpa_sm
));
1962 res
= wpa_auth_write_fte(hapd
->wpa_auth
, use_sha384
,
1963 wpabuf_put(data
, 0),
1964 wpabuf_tailroom(data
));
1966 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1969 wpabuf_put(data
, res
);
1971 #endif /* CONFIG_IEEE80211R_AP */
1974 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1975 wpabuf_put_u8(data
, 1 + FILS_NONCE_LEN
); /* Length */
1976 /* Element ID Extension */
1977 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_NONCE
);
1978 wpabuf_put_data(data
, fils_nonce
, FILS_NONCE_LEN
);
1981 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1982 wpabuf_put_u8(data
, 1 + FILS_SESSION_LEN
); /* Length */
1983 /* Element ID Extension */
1984 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_SESSION
);
1985 wpabuf_put_data(data
, sta
->fils_session
, FILS_SESSION_LEN
);
1987 /* FILS Wrapped Data */
1988 if (!pmksa
&& erp_resp
) {
1989 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1990 wpabuf_put_u8(data
, 1 + wpabuf_len(erp_resp
)); /* Length */
1991 /* Element ID Extension */
1992 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_WRAPPED_DATA
);
1993 wpabuf_put_buf(data
, erp_resp
);
1995 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1996 msk
, msk_len
, sta
->fils_snonce
, fils_nonce
,
1998 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
2000 wpabuf_len(sta
->fils_dh_ss
) : 0,
2001 pmk_buf
, &pmk_len
)) {
2002 wpa_printf(MSG_DEBUG
, "FILS: Failed to derive PMK");
2003 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2010 /* Don't use DHss in PTK derivation if PMKSA caching is not
2012 wpabuf_clear_free(sta
->fils_dh_ss
);
2013 sta
->fils_dh_ss
= NULL
;
2015 if (sta
->fils_erp_pmkid_set
) {
2016 /* TODO: get PMKLifetime from WPA parameters */
2017 unsigned int dot11RSNAConfigPMKLifetime
= 43200;
2018 int session_timeout
;
2020 session_timeout
= dot11RSNAConfigPMKLifetime
;
2021 if (sta
->session_timeout_set
) {
2022 struct os_reltime now
, diff
;
2024 os_get_reltime(&now
);
2025 os_reltime_sub(&sta
->session_timeout
, &now
,
2027 session_timeout
= diff
.sec
;
2030 sta
->fils_erp_pmkid_set
= 0;
2031 wpa_auth_add_fils_pmk_pmkid(sta
->wpa_sm
, pmk
, pmk_len
,
2032 sta
->fils_erp_pmkid
);
2033 if (!hapd
->conf
->disable_pmksa_caching
&&
2034 wpa_auth_pmksa_add2(
2035 hapd
->wpa_auth
, sta
->addr
,
2037 sta
->fils_erp_pmkid
,
2039 wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) < 0) {
2040 wpa_printf(MSG_ERROR
,
2041 "FILS: Failed to add PMKSA cache entry based on ERP");
2046 pmk_len
= pmksa
->pmk_len
;
2050 wpa_printf(MSG_DEBUG
, "FILS: No PMK available");
2051 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2057 if (fils_auth_pmk_to_ptk(sta
->wpa_sm
, pmk
, pmk_len
,
2058 sta
->fils_snonce
, fils_nonce
,
2060 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
2062 wpabuf_len(sta
->fils_dh_ss
) : 0,
2063 sta
->fils_g_sta
, pub
) < 0) {
2064 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2072 *is_pub
= pub
!= NULL
;
2075 wpabuf_clear_free(sta
->fils_dh_ss
);
2076 sta
->fils_dh_ss
= NULL
;
2077 #ifdef CONFIG_FILS_SK_PFS
2078 crypto_ecdh_deinit(sta
->fils_ecdh
);
2079 sta
->fils_ecdh
= NULL
;
2080 #endif /* CONFIG_FILS_SK_PFS */
2085 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
2086 struct sta_info
*sta
, u16 resp
,
2087 struct wpabuf
*data
, int pub
)
2092 resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
) ?
2093 WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
2094 send_auth_reply(hapd
, sta
, sta
->addr
, hapd
->own_addr
, auth_alg
, 2, resp
,
2095 data
? wpabuf_head(data
) : (u8
*) "",
2096 data
? wpabuf_len(data
) : 0, "auth-fils-finish");
2099 if (resp
== WLAN_STATUS_SUCCESS
) {
2100 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2101 HOSTAPD_LEVEL_DEBUG
,
2102 "authentication OK (FILS)");
2103 sta
->flags
|= WLAN_STA_AUTH
;
2104 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2105 sta
->auth_alg
= pub
? WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
2106 mlme_authenticate_indication(hapd
, sta
);
2111 void ieee802_11_finish_fils_auth(struct hostapd_data
*hapd
,
2112 struct sta_info
*sta
, int success
,
2113 struct wpabuf
*erp_resp
,
2114 const u8
*msk
, size_t msk_len
)
2116 struct wpabuf
*data
;
2120 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2122 if (!sta
->fils_pending_cb
)
2124 resp
= success
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_UNSPECIFIED_FAILURE
;
2125 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, NULL
, erp_resp
,
2126 msk
, msk_len
, &pub
);
2128 wpa_printf(MSG_DEBUG
,
2129 "%s: prepare_auth_resp_fils() returned failure",
2132 sta
->fils_pending_cb(hapd
, sta
, resp
, data
, pub
);
2135 #endif /* CONFIG_FILS */
2138 static int ieee802_11_allowed_address(struct hostapd_data
*hapd
, const u8
*addr
,
2139 const u8
*msg
, size_t len
,
2140 struct radius_sta
*info
)
2144 res
= hostapd_allowed_address(hapd
, addr
, msg
, len
, info
, 0);
2146 if (res
== HOSTAPD_ACL_REJECT
) {
2147 wpa_printf(MSG_DEBUG
, "Station " MACSTR
2148 " not allowed to authenticate",
2150 return HOSTAPD_ACL_REJECT
;
2153 if (res
== HOSTAPD_ACL_PENDING
) {
2154 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
2155 " waiting for an external authentication",
2157 /* Authentication code will re-send the authentication frame
2158 * after it has received (and cached) information from the
2159 * external source. */
2160 return HOSTAPD_ACL_PENDING
;
2168 ieee802_11_set_radius_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2169 int res
, struct radius_sta
*info
)
2171 u32 session_timeout
= info
->session_timeout
;
2172 u32 acct_interim_interval
= info
->acct_interim_interval
;
2173 struct vlan_description
*vlan_id
= &info
->vlan_id
;
2174 struct hostapd_sta_wpa_psk_short
*psk
= info
->psk
;
2175 char *identity
= info
->identity
;
2176 char *radius_cui
= info
->radius_cui
;
2178 if (vlan_id
->notempty
&&
2179 !hostapd_vlan_valid(hapd
->conf
->vlan
, vlan_id
)) {
2180 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
2182 "Invalid VLAN %d%s received from RADIUS server",
2184 vlan_id
->tagged
[0] ? "+" : "");
2187 if (ap_sta_set_vlan(hapd
, sta
, vlan_id
) < 0)
2190 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
2191 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
2193 hostapd_free_psk_list(sta
->psk
);
2194 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
)
2195 hostapd_copy_psk_list(&sta
->psk
, psk
);
2199 os_free(sta
->identity
);
2201 sta
->identity
= os_strdup(identity
);
2203 sta
->identity
= NULL
;
2205 os_free(sta
->radius_cui
);
2207 sta
->radius_cui
= os_strdup(radius_cui
);
2209 sta
->radius_cui
= NULL
;
2211 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
2212 sta
->acct_interim_interval
= acct_interim_interval
;
2213 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
) {
2214 sta
->session_timeout_set
= 1;
2215 os_get_reltime(&sta
->session_timeout
);
2216 sta
->session_timeout
.sec
+= session_timeout
;
2217 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
2219 sta
->session_timeout_set
= 0;
2220 ap_sta_no_session_timeout(hapd
, sta
);
2227 static void handle_auth(struct hostapd_data
*hapd
,
2228 const struct ieee80211_mgmt
*mgmt
, size_t len
,
2229 int rssi
, int from_queue
)
2231 u16 auth_alg
, auth_transaction
, status_code
;
2232 u16 resp
= WLAN_STATUS_SUCCESS
;
2233 struct sta_info
*sta
= NULL
;
2236 const u8
*challenge
= NULL
;
2237 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
2238 size_t resp_ies_len
= 0;
2240 struct radius_sta rad_info
;
2242 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
2243 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
2244 (unsigned long) len
);
2248 #ifdef CONFIG_TESTING_OPTIONS
2249 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
2250 drand48() < hapd
->iconf
->ignore_auth_probability
) {
2251 wpa_printf(MSG_INFO
,
2252 "TESTING: ignoring auth frame from " MACSTR
,
2256 #endif /* CONFIG_TESTING_OPTIONS */
2258 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
2259 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
2260 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
2261 fc
= le_to_host16(mgmt
->frame_control
);
2262 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
2264 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
2265 2 + WLAN_AUTH_CHALLENGE_LEN
&&
2266 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
2267 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
2268 challenge
= &mgmt
->u
.auth
.variable
[2];
2270 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
2271 "auth_transaction=%d status_code=%d wep=%d%s "
2272 "seq_ctrl=0x%x%s%s",
2273 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
2274 status_code
, !!(fc
& WLAN_FC_ISWEP
),
2275 challenge
? " challenge" : "",
2276 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "",
2277 from_queue
? " (from queue)" : "");
2279 #ifdef CONFIG_NO_RC4
2280 if (auth_alg
== WLAN_AUTH_SHARED_KEY
) {
2281 wpa_printf(MSG_INFO
,
2282 "Unsupported authentication algorithm (%d)",
2284 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2287 #endif /* CONFIG_NO_RC4 */
2289 if (hapd
->tkip_countermeasures
) {
2290 wpa_printf(MSG_DEBUG
,
2291 "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
2292 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2296 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
2297 auth_alg
== WLAN_AUTH_OPEN
) ||
2298 #ifdef CONFIG_IEEE80211R_AP
2299 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
2300 auth_alg
== WLAN_AUTH_FT
) ||
2301 #endif /* CONFIG_IEEE80211R_AP */
2303 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
2304 auth_alg
== WLAN_AUTH_SAE
) ||
2305 #endif /* CONFIG_SAE */
2307 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2308 auth_alg
== WLAN_AUTH_FILS_SK
) ||
2309 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2310 hapd
->conf
->fils_dh_group
&&
2311 auth_alg
== WLAN_AUTH_FILS_SK_PFS
) ||
2312 #endif /* CONFIG_FILS */
2313 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
2314 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
2315 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
2317 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2321 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
2322 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
2323 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
2325 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
2329 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
2330 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
2332 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2336 if (hapd
->conf
->no_auth_if_seen_on
) {
2337 struct hostapd_data
*other
;
2339 other
= sta_track_seen_on(hapd
->iface
, mgmt
->sa
,
2340 hapd
->conf
->no_auth_if_seen_on
);
2344 u8 op_class
, channel
, phytype
;
2346 wpa_printf(MSG_DEBUG
, "%s: Reject authentication from "
2347 MACSTR
" since STA has been seen on %s",
2348 hapd
->conf
->iface
, MAC2STR(mgmt
->sa
),
2349 hapd
->conf
->no_auth_if_seen_on
);
2351 resp
= WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION
;
2353 *pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
2355 os_memcpy(pos
, other
->own_addr
, ETH_ALEN
);
2357 info
= 0; /* TODO: BSSID Information */
2358 WPA_PUT_LE32(pos
, info
);
2360 if (other
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211AD
)
2361 phytype
= 8; /* dmg */
2362 else if (other
->iconf
->ieee80211ac
)
2363 phytype
= 9; /* vht */
2364 else if (other
->iconf
->ieee80211n
)
2365 phytype
= 7; /* ht */
2366 else if (other
->iconf
->hw_mode
==
2367 HOSTAPD_MODE_IEEE80211A
)
2368 phytype
= 4; /* ofdm */
2369 else if (other
->iconf
->hw_mode
==
2370 HOSTAPD_MODE_IEEE80211G
)
2371 phytype
= 6; /* erp */
2373 phytype
= 5; /* hrdsss */
2374 if (ieee80211_freq_to_channel_ext(
2375 hostapd_hw_get_freq(other
,
2376 other
->iconf
->channel
),
2377 other
->iconf
->secondary_channel
,
2378 other
->iconf
->ieee80211ac
,
2379 &op_class
, &channel
) == NUM_HOSTAPD_MODES
) {
2381 channel
= other
->iconf
->channel
;
2386 resp_ies_len
= pos
- &resp_ies
[0];
2391 res
= ieee802_11_allowed_address(hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
,
2393 if (res
== HOSTAPD_ACL_REJECT
) {
2394 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
2395 "Ignore Authentication frame from " MACSTR
2396 " due to ACL reject", MAC2STR(mgmt
->sa
));
2397 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2400 if (res
== HOSTAPD_ACL_PENDING
)
2404 if (auth_alg
== WLAN_AUTH_SAE
&& !from_queue
&&
2405 (auth_transaction
== 1 ||
2406 (auth_transaction
== 2 && auth_sae_queued_addr(hapd
, mgmt
->sa
)))) {
2407 /* Handle SAE Authentication commit message through a queue to
2408 * provide more control for postponing the needed heavy
2409 * processing under a possible DoS attack scenario. In addition,
2410 * queue SAE Authentication confirm message if there happens to
2411 * be a queued commit message from the same peer. This is needed
2412 * to avoid reordering Authentication frames within the same
2414 auth_sae_queue(hapd
, mgmt
, len
, rssi
);
2417 #endif /* CONFIG_SAE */
2419 sta
= ap_get_sta(hapd
, mgmt
->sa
);
2421 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2422 sta
->ft_over_ds
= 0;
2423 if ((fc
& WLAN_FC_RETRY
) &&
2424 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
2425 sta
->last_seq_ctrl
== seq_ctrl
&&
2426 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
2427 hostapd_logger(hapd
, sta
->addr
,
2428 HOSTAPD_MODULE_IEEE80211
,
2429 HOSTAPD_LEVEL_DEBUG
,
2430 "Drop repeated authentication frame seq_ctrl=0x%x",
2435 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
2436 sta
->plink_state
== PLINK_BLOCKED
) {
2437 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2438 " is blocked - drop Authentication frame",
2442 #endif /* CONFIG_MESH */
2445 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
2446 /* if the mesh peer is not available, we don't do auth.
2448 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2449 " not yet known - drop Authentication frame",
2452 * Save a copy of the frame so that it can be processed
2453 * if a new peer entry is added shortly after this.
2455 wpabuf_free(hapd
->mesh_pending_auth
);
2456 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
2457 os_get_reltime(&hapd
->mesh_pending_auth_time
);
2460 #endif /* CONFIG_MESH */
2462 sta
= ap_sta_add(hapd
, mgmt
->sa
);
2464 wpa_printf(MSG_DEBUG
, "ap_sta_add() failed");
2465 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2469 sta
->last_seq_ctrl
= seq_ctrl
;
2470 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
2472 sta
->auth_rssi
= rssi
;
2473 #endif /* CONFIG_MBO */
2475 res
= ieee802_11_set_radius_info(hapd
, sta
, res
, &rad_info
);
2477 wpa_printf(MSG_DEBUG
, "ieee802_11_set_radius_info() failed");
2478 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2482 sta
->flags
&= ~WLAN_STA_PREAUTH
;
2483 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
2486 * If the driver supports full AP client state, add a station to the
2487 * driver before sending authentication reply to make sure the driver
2488 * has resources, and not to go through the entire authentication and
2489 * association handshake, and fail it at the end.
2491 * If this is not the first transaction, in a multi-step authentication
2492 * algorithm, the station already exists in the driver
2493 * (sta->added_unassoc = 1) so skip it.
2495 * In mesh mode, the station was already added to the driver when the
2496 * NEW_PEER_CANDIDATE event is received.
2498 * If PMF was negotiated for the existing association, skip this to
2499 * avoid dropping the STA entry and the associated keys. This is needed
2500 * to allow the original connection work until the attempt can complete
2501 * (re)association, so that unprotected Authentication frame cannot be
2502 * used to bypass PMF protection.
2504 if (FULL_AP_CLIENT_STATE_SUPP(hapd
->iface
->drv_flags
) &&
2505 (!(sta
->flags
& WLAN_STA_MFP
) || !ap_sta_is_authorized(sta
)) &&
2506 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
2507 !(sta
->added_unassoc
)) {
2509 * If a station that is already associated to the AP, is trying
2510 * to authenticate again, remove the STA entry, in order to make
2511 * sure the STA PS state gets cleared and configuration gets
2512 * updated. To handle this, station's added_unassoc flag is
2513 * cleared once the station has completed association.
2515 ap_sta_set_authorized(hapd
, sta
, 0);
2516 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2517 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_AUTH
|
2518 WLAN_STA_AUTHORIZED
);
2520 if (hostapd_sta_add(hapd
, sta
->addr
, 0, 0,
2521 sta
->supported_rates
,
2522 sta
->supported_rates_len
,
2523 0, NULL
, NULL
, NULL
, 0,
2524 sta
->flags
, 0, 0, 0, 0)) {
2525 hostapd_logger(hapd
, sta
->addr
,
2526 HOSTAPD_MODULE_IEEE80211
,
2527 HOSTAPD_LEVEL_NOTICE
,
2528 "Could not add STA to kernel driver");
2529 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2533 sta
->added_unassoc
= 1;
2537 case WLAN_AUTH_OPEN
:
2538 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2539 HOSTAPD_LEVEL_DEBUG
,
2540 "authentication OK (open system)");
2541 sta
->flags
|= WLAN_STA_AUTH
;
2542 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2543 sta
->auth_alg
= WLAN_AUTH_OPEN
;
2544 mlme_authenticate_indication(hapd
, sta
);
2546 #ifndef CONFIG_NO_RC4
2547 case WLAN_AUTH_SHARED_KEY
:
2548 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
2549 fc
& WLAN_FC_ISWEP
);
2551 wpa_printf(MSG_DEBUG
,
2552 "auth_shared_key() failed: status=%d", resp
);
2553 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
2554 mlme_authenticate_indication(hapd
, sta
);
2555 if (sta
->challenge
&& auth_transaction
== 1) {
2556 resp_ies
[0] = WLAN_EID_CHALLENGE
;
2557 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
2558 os_memcpy(resp_ies
+ 2, sta
->challenge
,
2559 WLAN_AUTH_CHALLENGE_LEN
);
2560 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
2563 #endif /* CONFIG_NO_RC4 */
2564 #ifdef CONFIG_IEEE80211R_AP
2566 sta
->auth_alg
= WLAN_AUTH_FT
;
2567 if (sta
->wpa_sm
== NULL
)
2568 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2570 if (sta
->wpa_sm
== NULL
) {
2571 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
2573 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2576 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
2577 auth_transaction
, mgmt
->u
.auth
.variable
,
2578 len
- IEEE80211_HDRLEN
-
2579 sizeof(mgmt
->u
.auth
),
2580 handle_auth_ft_finish
, hapd
);
2581 /* handle_auth_ft_finish() callback will complete auth. */
2583 #endif /* CONFIG_IEEE80211R_AP */
2587 if (status_code
== WLAN_STATUS_SUCCESS
&&
2588 hapd
->conf
->mesh
& MESH_ENABLED
) {
2589 if (sta
->wpa_sm
== NULL
)
2591 wpa_auth_sta_init(hapd
->wpa_auth
,
2593 if (sta
->wpa_sm
== NULL
) {
2594 wpa_printf(MSG_DEBUG
,
2595 "SAE: Failed to initialize WPA state machine");
2596 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2600 #endif /* CONFIG_MESH */
2601 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
2604 #endif /* CONFIG_SAE */
2606 case WLAN_AUTH_FILS_SK
:
2607 case WLAN_AUTH_FILS_SK_PFS
:
2608 handle_auth_fils(hapd
, sta
, mgmt
->u
.auth
.variable
,
2609 len
- IEEE80211_HDRLEN
- sizeof(mgmt
->u
.auth
),
2610 auth_alg
, auth_transaction
, status_code
,
2611 handle_auth_fils_finish
);
2613 #endif /* CONFIG_FILS */
2617 reply_res
= send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
2618 auth_transaction
+ 1, resp
, resp_ies
,
2619 resp_ies_len
, "handle-auth");
2621 if (sta
&& sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
2622 reply_res
!= WLAN_STATUS_SUCCESS
)) {
2623 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2624 sta
->added_unassoc
= 0;
2629 int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2633 /* get a unique AID */
2635 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
2642 for (i
= 0; i
< AID_WORDS
; i
++) {
2643 if (hapd
->sta_aid
[i
] == (u32
) -1)
2645 for (j
= 0; j
< 32; j
++) {
2646 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
2654 aid
= i
* 32 + j
+ 1;
2659 hapd
->sta_aid
[i
] |= BIT(j
);
2660 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
2665 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2666 const u8
*ssid_ie
, size_t ssid_ie_len
)
2668 if (ssid_ie
== NULL
)
2669 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2671 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
2672 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
2673 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2675 "Station tried to associate with unknown SSID "
2676 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
2677 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2680 return WLAN_STATUS_SUCCESS
;
2684 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2685 const u8
*wmm_ie
, size_t wmm_ie_len
)
2687 sta
->flags
&= ~WLAN_STA_WMM
;
2689 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
2690 struct wmm_information_element
*wmm
;
2692 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
2693 hostapd_logger(hapd
, sta
->addr
,
2695 HOSTAPD_LEVEL_DEBUG
,
2696 "invalid WMM element in association "
2698 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2701 sta
->flags
|= WLAN_STA_WMM
;
2702 wmm
= (struct wmm_information_element
*) wmm_ie
;
2703 sta
->qosinfo
= wmm
->qos_info
;
2705 return WLAN_STATUS_SUCCESS
;
2708 static u16
check_multi_ap(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2709 const u8
*multi_ap_ie
, size_t multi_ap_len
)
2711 u8 multi_ap_value
= 0;
2713 sta
->flags
&= ~WLAN_STA_MULTI_AP
;
2715 if (!hapd
->conf
->multi_ap
)
2716 return WLAN_STATUS_SUCCESS
;
2719 const u8
*multi_ap_subelem
;
2721 multi_ap_subelem
= get_ie(multi_ap_ie
+ 4,
2723 MULTI_AP_SUB_ELEM_TYPE
);
2724 if (multi_ap_subelem
&& multi_ap_subelem
[1] == 1) {
2725 multi_ap_value
= multi_ap_subelem
[2];
2727 hostapd_logger(hapd
, sta
->addr
,
2728 HOSTAPD_MODULE_IEEE80211
,
2730 "Multi-AP IE has missing or invalid Multi-AP subelement");
2731 return WLAN_STATUS_INVALID_IE
;
2735 if (multi_ap_value
&& multi_ap_value
!= MULTI_AP_BACKHAUL_STA
)
2736 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2738 "Multi-AP IE with unexpected value 0x%02x",
2741 if (!(multi_ap_value
& MULTI_AP_BACKHAUL_STA
)) {
2742 if (hapd
->conf
->multi_ap
& FRONTHAUL_BSS
)
2743 return WLAN_STATUS_SUCCESS
;
2745 hostapd_logger(hapd
, sta
->addr
,
2746 HOSTAPD_MODULE_IEEE80211
,
2748 "Non-Multi-AP STA tries to associate with backhaul-only BSS");
2749 return WLAN_STATUS_ASSOC_DENIED_UNSPEC
;
2752 if (!(hapd
->conf
->multi_ap
& BACKHAUL_BSS
))
2753 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2754 HOSTAPD_LEVEL_DEBUG
,
2755 "Backhaul STA tries to associate with fronthaul-only BSS");
2757 sta
->flags
|= WLAN_STA_MULTI_AP
;
2758 return WLAN_STATUS_SUCCESS
;
2762 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2763 struct ieee802_11_elems
*elems
)
2765 /* Supported rates not used in IEEE 802.11ad/DMG */
2766 if (hapd
->iface
->current_mode
&&
2767 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
)
2768 return WLAN_STATUS_SUCCESS
;
2770 if (!elems
->supp_rates
) {
2771 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2772 HOSTAPD_LEVEL_DEBUG
,
2773 "No supported rates element in AssocReq");
2774 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2777 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
2778 sizeof(sta
->supported_rates
)) {
2779 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2780 HOSTAPD_LEVEL_DEBUG
,
2781 "Invalid supported rates element length %d+%d",
2782 elems
->supp_rates_len
,
2783 elems
->ext_supp_rates_len
);
2784 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2787 sta
->supported_rates_len
= merge_byte_arrays(
2788 sta
->supported_rates
, sizeof(sta
->supported_rates
),
2789 elems
->supp_rates
, elems
->supp_rates_len
,
2790 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
2792 return WLAN_STATUS_SUCCESS
;
2796 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2797 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
2799 #ifdef CONFIG_INTERWORKING
2800 /* check for QoS Map support */
2801 if (ext_capab_ie_len
>= 5) {
2802 if (ext_capab_ie
[4] & 0x01)
2803 sta
->qos_map_enabled
= 1;
2805 #endif /* CONFIG_INTERWORKING */
2807 if (ext_capab_ie_len
> 0) {
2808 sta
->ecsa_supported
= !!(ext_capab_ie
[0] & BIT(2));
2809 os_free(sta
->ext_capability
);
2810 sta
->ext_capability
= os_malloc(1 + ext_capab_ie_len
);
2811 if (sta
->ext_capability
) {
2812 sta
->ext_capability
[0] = ext_capab_ie_len
;
2813 os_memcpy(sta
->ext_capability
+ 1, ext_capab_ie
,
2818 return WLAN_STATUS_SUCCESS
;
2824 static int owe_group_supported(struct hostapd_data
*hapd
, u16 group
)
2827 int *groups
= hapd
->conf
->owe_groups
;
2829 if (group
!= 19 && group
!= 20 && group
!= 21)
2835 for (i
= 0; groups
[i
] > 0; i
++) {
2836 if (groups
[i
] == group
)
2844 static u16
owe_process_assoc_req(struct hostapd_data
*hapd
,
2845 struct sta_info
*sta
, const u8
*owe_dh
,
2848 struct wpabuf
*secret
, *pub
, *hkey
;
2850 u8 prk
[SHA512_MAC_LEN
], pmkid
[SHA512_MAC_LEN
];
2851 const char *info
= "OWE Key Generation";
2855 size_t hash_len
, prime_len
;
2857 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
2858 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
2859 return WLAN_STATUS_SUCCESS
;
2862 group
= WPA_GET_LE16(owe_dh
);
2863 if (!owe_group_supported(hapd
, group
)) {
2864 wpa_printf(MSG_DEBUG
, "OWE: Unsupported DH group %u", group
);
2865 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2869 else if (group
== 20)
2871 else if (group
== 21)
2874 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2876 crypto_ecdh_deinit(sta
->owe_ecdh
);
2877 sta
->owe_ecdh
= crypto_ecdh_init(group
);
2879 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2880 sta
->owe_group
= group
;
2882 secret
= crypto_ecdh_set_peerkey(sta
->owe_ecdh
, 0, owe_dh
+ 2,
2884 secret
= wpabuf_zeropad(secret
, prime_len
);
2886 wpa_printf(MSG_DEBUG
, "OWE: Invalid peer DH public key");
2887 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2889 wpa_hexdump_buf_key(MSG_DEBUG
, "OWE: DH shared secret", secret
);
2891 /* prk = HKDF-extract(C | A | group, z) */
2893 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2895 wpabuf_clear_free(secret
);
2896 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2899 /* PMKID = Truncate-128(Hash(C | A)) */
2900 addr
[0] = owe_dh
+ 2;
2901 len
[0] = owe_dh_len
- 2;
2902 addr
[1] = wpabuf_head(pub
);
2903 len
[1] = wpabuf_len(pub
);
2905 res
= sha256_vector(2, addr
, len
, pmkid
);
2906 hash_len
= SHA256_MAC_LEN
;
2907 } else if (group
== 20) {
2908 res
= sha384_vector(2, addr
, len
, pmkid
);
2909 hash_len
= SHA384_MAC_LEN
;
2910 } else if (group
== 21) {
2911 res
= sha512_vector(2, addr
, len
, pmkid
);
2912 hash_len
= SHA512_MAC_LEN
;
2915 wpabuf_clear_free(secret
);
2916 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2918 pub
= wpabuf_zeropad(pub
, prime_len
);
2919 if (res
< 0 || !pub
) {
2921 wpabuf_clear_free(secret
);
2922 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2925 hkey
= wpabuf_alloc(owe_dh_len
- 2 + wpabuf_len(pub
) + 2);
2928 wpabuf_clear_free(secret
);
2929 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2932 wpabuf_put_data(hkey
, owe_dh
+ 2, owe_dh_len
- 2); /* C */
2933 wpabuf_put_buf(hkey
, pub
); /* A */
2935 wpabuf_put_le16(hkey
, group
); /* group */
2937 res
= hmac_sha256(wpabuf_head(hkey
), wpabuf_len(hkey
),
2938 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2939 else if (group
== 20)
2940 res
= hmac_sha384(wpabuf_head(hkey
), wpabuf_len(hkey
),
2941 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2942 else if (group
== 21)
2943 res
= hmac_sha512(wpabuf_head(hkey
), wpabuf_len(hkey
),
2944 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2945 wpabuf_clear_free(hkey
);
2946 wpabuf_clear_free(secret
);
2948 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2950 wpa_hexdump_key(MSG_DEBUG
, "OWE: prk", prk
, hash_len
);
2952 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2954 os_free(sta
->owe_pmk
);
2955 sta
->owe_pmk
= os_malloc(hash_len
);
2956 if (!sta
->owe_pmk
) {
2957 os_memset(prk
, 0, SHA512_MAC_LEN
);
2958 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2962 res
= hmac_sha256_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2963 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2964 else if (group
== 20)
2965 res
= hmac_sha384_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2966 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2967 else if (group
== 21)
2968 res
= hmac_sha512_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2969 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2970 os_memset(prk
, 0, SHA512_MAC_LEN
);
2972 os_free(sta
->owe_pmk
);
2973 sta
->owe_pmk
= NULL
;
2974 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2976 sta
->owe_pmk_len
= hash_len
;
2978 wpa_hexdump_key(MSG_DEBUG
, "OWE: PMK", sta
->owe_pmk
, sta
->owe_pmk_len
);
2979 wpa_hexdump(MSG_DEBUG
, "OWE: PMKID", pmkid
, PMKID_LEN
);
2980 wpa_auth_pmksa_add2(hapd
->wpa_auth
, sta
->addr
, sta
->owe_pmk
,
2981 sta
->owe_pmk_len
, pmkid
, 0, WPA_KEY_MGMT_OWE
);
2983 return WLAN_STATUS_SUCCESS
;
2987 u16
owe_validate_request(struct hostapd_data
*hapd
, const u8
*peer
,
2988 const u8
*rsn_ie
, size_t rsn_ie_len
,
2989 const u8
*owe_dh
, size_t owe_dh_len
)
2991 struct wpa_ie_data data
;
2994 if (!rsn_ie
|| rsn_ie_len
< 2) {
2995 wpa_printf(MSG_DEBUG
, "OWE: Invalid RSNE from " MACSTR
,
2997 return WLAN_STATUS_INVALID_IE
;
3002 res
= wpa_parse_wpa_ie_rsn(rsn_ie
, rsn_ie_len
, &data
);
3004 wpa_printf(MSG_DEBUG
, "Failed to parse RSNE from " MACSTR
3005 " (res=%d)", MAC2STR(peer
), res
);
3006 wpa_hexdump(MSG_DEBUG
, "RSNE", rsn_ie
, rsn_ie_len
);
3007 return wpa_res_to_status_code(res
);
3009 if (!(data
.key_mgmt
& WPA_KEY_MGMT_OWE
)) {
3010 wpa_printf(MSG_DEBUG
,
3011 "OWE: Unexpected key mgmt 0x%x from " MACSTR
,
3012 (unsigned int) data
.key_mgmt
, MAC2STR(peer
));
3013 return WLAN_STATUS_AKMP_NOT_VALID
;
3016 wpa_printf(MSG_DEBUG
,
3017 "OWE: No Diffie-Hellman Parameter element from "
3018 MACSTR
, MAC2STR(peer
));
3019 return WLAN_STATUS_AKMP_NOT_VALID
;
3022 return WLAN_STATUS_SUCCESS
;
3026 u16
owe_process_rsn_ie(struct hostapd_data
*hapd
,
3027 struct sta_info
*sta
,
3028 const u8
*rsn_ie
, size_t rsn_ie_len
,
3029 const u8
*owe_dh
, size_t owe_dh_len
)
3032 u8
*owe_buf
, ie
[256 * 2];
3036 if (!rsn_ie
|| rsn_ie_len
< 2) {
3037 wpa_printf(MSG_DEBUG
, "OWE: No RSNE in (Re)AssocReq");
3038 status
= WLAN_STATUS_INVALID_IE
;
3043 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
3046 wpa_printf(MSG_WARNING
,
3047 "OWE: Failed to initialize WPA state machine");
3048 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3053 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
3054 hapd
->iface
->freq
, rsn_ie
, rsn_ie_len
,
3055 NULL
, 0, NULL
, 0, owe_dh
, owe_dh_len
);
3056 status
= wpa_res_to_status_code(res
);
3057 if (status
!= WLAN_STATUS_SUCCESS
)
3059 status
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3060 if (status
!= WLAN_STATUS_SUCCESS
)
3062 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, ie
, sizeof(ie
),
3065 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3069 if (sta
->owe_ecdh
) {
3072 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3074 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3078 /* OWE Diffie-Hellman Parameter element */
3079 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3080 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3081 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3083 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3085 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3086 owe_buf
+= wpabuf_len(pub
);
3088 sta
->external_dh_updated
= 1;
3090 ie_len
= owe_buf
- ie
;
3093 wpa_printf(MSG_DEBUG
, "OWE: Update status %d, ie len %d for peer "
3094 MACSTR
, status
, (unsigned int) ie_len
,
3095 MAC2STR(sta
->addr
));
3096 hostapd_drv_update_dh_ie(hapd
, sta
->addr
, status
,
3097 status
== WLAN_STATUS_SUCCESS
? ie
: NULL
,
3103 #endif /* CONFIG_OWE */
3106 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3107 const u8
*ies
, size_t ies_len
, int reassoc
)
3109 struct ieee802_11_elems elems
;
3113 const u8
*p2p_dev_addr
= NULL
;
3115 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
3116 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3117 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
3118 "association request");
3119 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3122 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
3123 if (resp
!= WLAN_STATUS_SUCCESS
)
3125 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
3126 if (resp
!= WLAN_STATUS_SUCCESS
)
3128 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
3129 if (resp
!= WLAN_STATUS_SUCCESS
)
3131 resp
= copy_supp_rates(hapd
, sta
, &elems
);
3132 if (resp
!= WLAN_STATUS_SUCCESS
)
3135 resp
= check_multi_ap(hapd
, sta
, elems
.multi_ap
, elems
.multi_ap_len
);
3136 if (resp
!= WLAN_STATUS_SUCCESS
)
3139 #ifdef CONFIG_IEEE80211N
3140 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
);
3141 if (resp
!= WLAN_STATUS_SUCCESS
)
3143 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
3144 !(sta
->flags
& WLAN_STA_HT
)) {
3145 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3146 HOSTAPD_LEVEL_INFO
, "Station does not support "
3147 "mandatory HT PHY - reject association");
3148 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
3150 #endif /* CONFIG_IEEE80211N */
3152 #ifdef CONFIG_IEEE80211AC
3153 if (hapd
->iconf
->ieee80211ac
) {
3154 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
);
3155 if (resp
!= WLAN_STATUS_SUCCESS
)
3158 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
3159 if (resp
!= WLAN_STATUS_SUCCESS
)
3163 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
3164 !(sta
->flags
& WLAN_STA_VHT
)) {
3165 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3166 HOSTAPD_LEVEL_INFO
, "Station does not support "
3167 "mandatory VHT PHY - reject association");
3168 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
3171 if (hapd
->conf
->vendor_vht
&& !elems
.vht_capabilities
) {
3172 resp
= copy_sta_vendor_vht(hapd
, sta
, elems
.vendor_vht
,
3173 elems
.vendor_vht_len
);
3174 if (resp
!= WLAN_STATUS_SUCCESS
)
3177 #endif /* CONFIG_IEEE80211AC */
3178 #ifdef CONFIG_IEEE80211AX
3179 if (hapd
->iconf
->ieee80211ax
) {
3180 resp
= copy_sta_he_capab(hapd
, sta
, IEEE80211_MODE_AP
,
3181 elems
.he_capabilities
,
3182 elems
.he_capabilities_len
);
3183 if (resp
!= WLAN_STATUS_SUCCESS
)
3186 #endif /* CONFIG_IEEE80211AX */
3190 wpabuf_free(sta
->p2p_ie
);
3191 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3192 P2P_IE_VENDOR_TYPE
);
3194 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
3196 wpabuf_free(sta
->p2p_ie
);
3199 #endif /* CONFIG_P2P */
3201 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
3202 wpa_ie
= elems
.rsn_ie
;
3203 wpa_ie_len
= elems
.rsn_ie_len
;
3204 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
3206 wpa_ie
= elems
.wpa_ie
;
3207 wpa_ie_len
= elems
.wpa_ie_len
;
3214 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
3215 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
3216 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
3217 "Request - assume WPS is used");
3218 sta
->flags
|= WLAN_STA_WPS
;
3219 wpabuf_free(sta
->wps_ie
);
3220 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3221 WPS_IE_VENDOR_TYPE
);
3222 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
3223 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
3224 sta
->flags
|= WLAN_STA_WPS2
;
3228 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
3229 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
3230 "(Re)Association Request - reject");
3231 return WLAN_STATUS_INVALID_IE
;
3233 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
3234 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
3235 "(Re)Association Request - possible WPS use");
3236 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
3238 #endif /* CONFIG_WPS */
3239 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
3240 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3242 "No WPA/RSN IE in association request");
3243 return WLAN_STATUS_INVALID_IE
;
3246 if (hapd
->conf
->wpa
&& wpa_ie
) {
3250 if (sta
->wpa_sm
== NULL
)
3251 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3254 if (sta
->wpa_sm
== NULL
) {
3255 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3257 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3259 wpa_auth_set_auth_alg(sta
->wpa_sm
, sta
->auth_alg
);
3260 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
3263 elems
.rsnxe
? elems
.rsnxe
- 2 : NULL
,
3264 elems
.rsnxe
? elems
.rsnxe_len
+ 2 : 0,
3265 elems
.mdie
, elems
.mdie_len
,
3266 elems
.owe_dh
, elems
.owe_dh_len
);
3267 resp
= wpa_res_to_status_code(res
);
3268 if (resp
!= WLAN_STATUS_SUCCESS
)
3270 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3271 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3272 !sta
->sa_query_timed_out
&&
3273 sta
->sa_query_count
> 0)
3274 ap_check_sa_query_timeout(hapd
, sta
);
3275 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3276 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3277 !sta
->sa_query_timed_out
&&
3278 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
3280 * STA has already been associated with MFP and SA
3281 * Query timeout has not been reached. Reject the
3282 * association attempt temporarily and start SA Query,
3283 * if one is not pending.
3286 if (sta
->sa_query_count
== 0)
3287 ap_sta_start_sa_query(hapd
, sta
);
3289 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
3292 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
3293 sta
->flags
|= WLAN_STA_MFP
;
3295 sta
->flags
&= ~WLAN_STA_MFP
;
3297 #ifdef CONFIG_IEEE80211R_AP
3298 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
3300 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
3301 "to use association (not "
3302 "re-association) with FT auth_alg",
3303 MAC2STR(sta
->addr
));
3304 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3307 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
3309 if (resp
!= WLAN_STATUS_SUCCESS
)
3312 #endif /* CONFIG_IEEE80211R_AP */
3315 if (wpa_auth_uses_sae(sta
->wpa_sm
) && sta
->sae
&&
3316 sta
->sae
->state
== SAE_ACCEPTED
)
3317 wpa_auth_add_sae_pmkid(sta
->wpa_sm
, sta
->sae
->pmkid
);
3319 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3320 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
3321 struct rsn_pmksa_cache_entry
*sa
;
3322 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
3323 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
3324 wpa_printf(MSG_DEBUG
,
3325 "SAE: No PMKSA cache entry found for "
3326 MACSTR
, MAC2STR(sta
->addr
));
3327 return WLAN_STATUS_INVALID_PMKID
;
3329 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
3330 " using PMKSA caching", MAC2STR(sta
->addr
));
3331 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3332 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
3333 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
3334 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
3335 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
3336 "SAE AKM after non-SAE auth_alg %u",
3337 MAC2STR(sta
->addr
), sta
->auth_alg
);
3338 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
3341 if (hapd
->conf
->sae_pwe
== 2 &&
3342 sta
->auth_alg
== WLAN_AUTH_SAE
&&
3343 sta
->sae
&& sta
->sae
->tmp
&& !sta
->sae
->tmp
->h2e
&&
3344 elems
.rsnxe
&& elems
.rsnxe_len
>= 1 &&
3345 (elems
.rsnxe
[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E
))) {
3346 wpa_printf(MSG_INFO
, "SAE: " MACSTR
3347 " indicates support for SAE H2E, but did not use it",
3348 MAC2STR(sta
->addr
));
3349 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3351 #endif /* CONFIG_SAE */
3354 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3355 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
&&
3357 resp
= owe_process_assoc_req(hapd
, sta
, elems
.owe_dh
,
3359 if (resp
!= WLAN_STATUS_SUCCESS
)
3362 #endif /* CONFIG_OWE */
3365 dpp_pfs_free(sta
->dpp_pfs
);
3366 sta
->dpp_pfs
= NULL
;
3368 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3369 hapd
->conf
->dpp_netaccesskey
&& sta
->wpa_sm
&&
3370 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
&&
3372 sta
->dpp_pfs
= dpp_pfs_init(
3373 wpabuf_head(hapd
->conf
->dpp_netaccesskey
),
3374 wpabuf_len(hapd
->conf
->dpp_netaccesskey
));
3375 if (!sta
->dpp_pfs
) {
3376 wpa_printf(MSG_DEBUG
,
3377 "DPP: Could not initialize PFS");
3378 /* Try to continue without PFS */
3382 if (dpp_pfs_process(sta
->dpp_pfs
, elems
.owe_dh
,
3383 elems
.owe_dh_len
) < 0) {
3384 dpp_pfs_free(sta
->dpp_pfs
);
3385 sta
->dpp_pfs
= NULL
;
3386 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3390 wpa_auth_set_dpp_z(sta
->wpa_sm
, sta
->dpp_pfs
?
3391 sta
->dpp_pfs
->secret
: NULL
);
3393 #endif /* CONFIG_DPP2 */
3395 #ifdef CONFIG_IEEE80211N
3396 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
3397 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
3398 hostapd_logger(hapd
, sta
->addr
,
3399 HOSTAPD_MODULE_IEEE80211
,
3401 "Station tried to use TKIP with HT "
3403 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
3405 #endif /* CONFIG_IEEE80211N */
3407 } else if (hapd
->conf
->osen
) {
3408 if (elems
.osen
== NULL
) {
3410 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3412 "No HS 2.0 OSEN element in association request");
3413 return WLAN_STATUS_INVALID_IE
;
3416 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
3417 if (sta
->wpa_sm
== NULL
)
3418 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3420 if (sta
->wpa_sm
== NULL
) {
3421 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3423 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3425 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
3426 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
3427 return WLAN_STATUS_INVALID_IE
;
3428 #endif /* CONFIG_HS20 */
3430 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
3433 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
3434 #endif /* CONFIG_P2P */
3437 wpabuf_free(sta
->hs20_ie
);
3438 if (elems
.hs20
&& elems
.hs20_len
> 4) {
3441 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
3442 elems
.hs20_len
- 4);
3443 release
= ((elems
.hs20
[4] >> 4) & 0x0f) + 1;
3444 if (release
>= 2 && !wpa_auth_uses_mfp(sta
->wpa_sm
) &&
3445 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3446 wpa_printf(MSG_DEBUG
,
3447 "HS 2.0: PMF not negotiated by release %d station "
3448 MACSTR
, release
, MAC2STR(sta
->addr
));
3449 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
3452 sta
->hs20_ie
= NULL
;
3455 wpabuf_free(sta
->roaming_consortium
);
3456 if (elems
.roaming_cons_sel
)
3457 sta
->roaming_consortium
= wpabuf_alloc_copy(
3458 elems
.roaming_cons_sel
+ 4,
3459 elems
.roaming_cons_sel_len
- 4);
3461 sta
->roaming_consortium
= NULL
;
3462 #endif /* CONFIG_HS20 */
3465 wpabuf_free(sta
->mb_ies
);
3466 if (hapd
->iface
->fst
)
3467 sta
->mb_ies
= mb_ies_by_info(&elems
.mb_ies
);
3470 #endif /* CONFIG_FST */
3473 mbo_ap_check_sta_assoc(hapd
, sta
, &elems
);
3475 if (hapd
->conf
->mbo_enabled
&& (hapd
->conf
->wpa
& 2) &&
3476 elems
.mbo
&& sta
->cell_capa
&& !(sta
->flags
& WLAN_STA_MFP
) &&
3477 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3478 wpa_printf(MSG_INFO
,
3479 "MBO: Reject WPA2 association without PMF");
3480 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3482 #endif /* CONFIG_MBO */
3484 #if defined(CONFIG_FILS) && defined(CONFIG_OCV)
3485 if (wpa_auth_uses_ocv(sta
->wpa_sm
) &&
3486 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3487 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3488 sta
->auth_alg
== WLAN_AUTH_FILS_PK
)) {
3489 struct wpa_channel_info ci
;
3493 if (hostapd_drv_channel_info(hapd
, &ci
) != 0) {
3494 wpa_printf(MSG_WARNING
,
3495 "Failed to get channel info to validate received OCI in FILS (Re)Association Request frame");
3496 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3499 if (get_sta_tx_parameters(sta
->wpa_sm
,
3500 channel_width_to_int(ci
.chanwidth
),
3501 ci
.seg1_idx
, &tx_chanwidth
,
3503 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3505 if (ocv_verify_tx_params(elems
.oci
, elems
.oci_len
, &ci
,
3506 tx_chanwidth
, tx_seg1_idx
) != 0) {
3507 wpa_printf(MSG_WARNING
, "FILS: %s", ocv_errorstr
);
3508 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3511 #endif /* CONFIG_FILS && CONFIG_OCV */
3513 ap_copy_sta_supp_op_classes(sta
, elems
.supp_op_classes
,
3514 elems
.supp_op_classes_len
);
3516 if ((sta
->capability
& WLAN_CAPABILITY_RADIO_MEASUREMENT
) &&
3517 elems
.rrm_enabled
&&
3518 elems
.rrm_enabled_len
>= sizeof(sta
->rrm_enabled_capa
))
3519 os_memcpy(sta
->rrm_enabled_capa
, elems
.rrm_enabled
,
3520 sizeof(sta
->rrm_enabled_capa
));
3522 if (elems
.power_capab
) {
3523 sta
->min_tx_power
= elems
.power_capab
[0];
3524 sta
->max_tx_power
= elems
.power_capab
[1];
3525 sta
->power_capab
= 1;
3527 sta
->power_capab
= 0;
3530 return WLAN_STATUS_SUCCESS
;
3534 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
3538 struct ieee80211_mgmt reply
;
3540 os_memset(&reply
, 0, sizeof(reply
));
3541 reply
.frame_control
=
3542 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
3543 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
3544 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
3545 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
3547 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
3548 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
3550 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0, NULL
, 0, 0) < 0)
3551 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
3556 static int add_associated_sta(struct hostapd_data
*hapd
,
3557 struct sta_info
*sta
, int reassoc
)
3559 struct ieee80211_ht_capabilities ht_cap
;
3560 struct ieee80211_vht_capabilities vht_cap
;
3561 struct ieee80211_he_capabilities he_cap
;
3565 * Remove the STA entry to ensure the STA PS state gets cleared and
3566 * configuration gets updated. This is relevant for cases, such as
3567 * FT-over-the-DS, where a station re-associates back to the same AP but
3568 * skips the authentication flow, or if working with a driver that
3569 * does not support full AP client state.
3571 * Skip this if the STA has already completed FT reassociation and the
3572 * TK has been configured since the TX/RX PN must not be reset to 0 for
3575 * FT-over-the-DS has a special case where the STA entry (and as such,
3576 * the TK) has not yet been configured to the driver depending on which
3577 * driver interface is used. For that case, allow add-STA operation to
3578 * be used (instead of set-STA). This is needed to allow mac80211-based
3579 * drivers to accept the STA parameter configuration. Since this is
3580 * after a new FT-over-DS exchange, a new TK has been derived, so key
3581 * reinstallation is not a concern for this case.
3583 wpa_printf(MSG_DEBUG
, "Add associated STA " MACSTR
3584 " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
3585 MAC2STR(sta
->addr
), sta
->added_unassoc
, sta
->auth_alg
,
3586 sta
->ft_over_ds
, reassoc
,
3587 !!(sta
->flags
& WLAN_STA_AUTHORIZED
),
3588 wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
),
3589 wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
));
3591 if (!sta
->added_unassoc
&&
3592 (!(sta
->flags
& WLAN_STA_AUTHORIZED
) ||
3593 (reassoc
&& sta
->ft_over_ds
&& sta
->auth_alg
== WLAN_AUTH_FT
) ||
3594 (!wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
) &&
3595 !wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
)))) {
3596 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3597 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DRV_STA_REMOVED
);
3600 /* Do not allow the FT-over-DS exception to be used more than
3601 * once per authentication exchange to guarantee a new TK is
3603 sta
->ft_over_ds
= 0;
3606 #ifdef CONFIG_IEEE80211N
3607 if (sta
->flags
& WLAN_STA_HT
)
3608 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
3609 #endif /* CONFIG_IEEE80211N */
3610 #ifdef CONFIG_IEEE80211AC
3611 if (sta
->flags
& WLAN_STA_VHT
)
3612 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
3613 #endif /* CONFIG_IEEE80211AC */
3614 #ifdef CONFIG_IEEE80211AX
3615 if (sta
->flags
& WLAN_STA_HE
) {
3616 hostapd_get_he_capab(hapd
, sta
->he_capab
, &he_cap
,
3619 #endif /* CONFIG_IEEE80211AX */
3622 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
3623 * will be set when the ACK frame for the (Re)Association Response frame
3624 * is processed (TX status driver event).
3626 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
3627 sta
->supported_rates
, sta
->supported_rates_len
,
3628 sta
->listen_interval
,
3629 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
3630 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
3631 sta
->flags
& WLAN_STA_HE
? &he_cap
: NULL
,
3632 sta
->flags
& WLAN_STA_HE
? sta
->he_capab_len
: 0,
3633 sta
->flags
| WLAN_STA_ASSOC
, sta
->qosinfo
,
3634 sta
->vht_opmode
, sta
->p2p_ie
? 1 : 0,
3636 hostapd_logger(hapd
, sta
->addr
,
3637 HOSTAPD_MODULE_IEEE80211
, HOSTAPD_LEVEL_NOTICE
,
3638 "Could not %s STA to kernel driver",
3639 set
? "set" : "add");
3641 if (sta
->added_unassoc
) {
3642 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3643 sta
->added_unassoc
= 0;
3649 sta
->added_unassoc
= 0;
3655 static u16
send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3656 const u8
*addr
, u16 status_code
, int reassoc
,
3657 const u8
*ies
, size_t ies_len
, int rssi
)
3662 struct ieee80211_mgmt
*reply
;
3664 u16 res
= WLAN_STATUS_SUCCESS
;
3666 buflen
= sizeof(struct ieee80211_mgmt
) + 1024;
3668 if (sta
&& sta
->fils_hlp_resp
)
3669 buflen
+= wpabuf_len(sta
->fils_hlp_resp
);
3672 #endif /* CONFIG_FILS */
3674 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3676 #endif /* CONFIG_OWE */
3678 if (sta
&& sta
->dpp_pfs
)
3679 buflen
+= 5 + sta
->dpp_pfs
->curve
->prime_len
;
3680 #endif /* CONFIG_DPP2 */
3681 buf
= os_zalloc(buflen
);
3683 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3686 reply
= (struct ieee80211_mgmt
*) buf
;
3687 reply
->frame_control
=
3688 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
3689 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
3690 WLAN_FC_STYPE_ASSOC_RESP
));
3691 os_memcpy(reply
->da
, addr
, ETH_ALEN
);
3692 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
3693 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
3695 send_len
= IEEE80211_HDRLEN
;
3696 send_len
+= sizeof(reply
->u
.assoc_resp
);
3697 reply
->u
.assoc_resp
.capab_info
=
3698 host_to_le16(hostapd_own_capab_info(hapd
));
3699 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
3701 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0) |
3703 /* Supported rates */
3704 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
3705 /* Extended supported rates */
3706 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
3708 /* Radio measurement capabilities */
3709 p
= hostapd_eid_rm_enabled_capab(hapd
, p
, buf
+ buflen
- p
);
3712 if (status_code
== WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
&&
3714 int delta
= hapd
->iconf
->rssi_reject_assoc_rssi
- rssi
;
3716 p
= hostapd_eid_mbo_rssi_assoc_rej(hapd
, p
, buf
+ buflen
- p
,
3719 #endif /* CONFIG_MBO */
3721 #ifdef CONFIG_IEEE80211R_AP
3722 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
) {
3723 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
3724 * Transition Information, RSN, [RIC Response] */
3725 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
3727 sta
->auth_alg
, ies
, ies_len
);
3729 wpa_printf(MSG_DEBUG
,
3730 "FT: Failed to write AssocResp IEs");
3731 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3735 #endif /* CONFIG_IEEE80211R_AP */
3737 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3738 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3739 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3740 sta
->auth_alg
== WLAN_AUTH_FILS_PK
))
3741 p
= wpa_auth_write_assoc_resp_fils(sta
->wpa_sm
, p
,
3744 #endif /* CONFIG_FILS */
3747 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3748 (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3749 p
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, p
,
3752 #endif /* CONFIG_OWE */
3754 if (sta
&& status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
3755 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
3757 #ifdef CONFIG_IEEE80211N
3758 p
= hostapd_eid_ht_capabilities(hapd
, p
);
3759 p
= hostapd_eid_ht_operation(hapd
, p
);
3760 #endif /* CONFIG_IEEE80211N */
3762 #ifdef CONFIG_IEEE80211AC
3763 if (hapd
->iconf
->ieee80211ac
&& !hapd
->conf
->disable_11ac
&&
3764 !is_6ghz_op_class(hapd
->iconf
->op_class
)) {
3765 u32 nsts
= 0, sta_nsts
;
3767 if (sta
&& hapd
->conf
->use_sta_nsts
&& sta
->vht_capabilities
) {
3768 struct ieee80211_vht_capabilities
*capa
;
3770 nsts
= (hapd
->iface
->conf
->vht_capab
>>
3771 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3772 capa
= sta
->vht_capabilities
;
3773 sta_nsts
= (le_to_host32(capa
->vht_capabilities_info
) >>
3774 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3776 if (nsts
< sta_nsts
)
3781 p
= hostapd_eid_vht_capabilities(hapd
, p
, nsts
);
3782 p
= hostapd_eid_vht_operation(hapd
, p
);
3784 #endif /* CONFIG_IEEE80211AC */
3786 #ifdef CONFIG_IEEE80211AX
3787 if (hapd
->iconf
->ieee80211ax
) {
3788 p
= hostapd_eid_he_capab(hapd
, p
, IEEE80211_MODE_AP
);
3789 p
= hostapd_eid_he_operation(hapd
, p
);
3790 p
= hostapd_eid_spatial_reuse(hapd
, p
);
3791 p
= hostapd_eid_he_mu_edca_parameter_set(hapd
, p
);
3793 #endif /* CONFIG_IEEE80211AX */
3795 p
= hostapd_eid_ext_capab(hapd
, p
);
3796 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
3797 if (sta
&& sta
->qos_map_enabled
)
3798 p
= hostapd_eid_qos_map_set(hapd
, p
);
3801 if (hapd
->iface
->fst_ies
) {
3802 os_memcpy(p
, wpabuf_head(hapd
->iface
->fst_ies
),
3803 wpabuf_len(hapd
->iface
->fst_ies
));
3804 p
+= wpabuf_len(hapd
->iface
->fst_ies
);
3806 #endif /* CONFIG_FST */
3808 p
= hostapd_eid_rsnxe(hapd
, p
, buf
+ buflen
- p
);
3811 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3812 sta
&& sta
->owe_ecdh
&& status_code
== WLAN_STATUS_SUCCESS
&&
3813 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
) {
3816 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3818 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3821 /* OWE Diffie-Hellman Parameter element */
3822 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3823 *p
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3824 *p
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
3825 WPA_PUT_LE16(p
, sta
->owe_group
);
3827 os_memcpy(p
, wpabuf_head(pub
), wpabuf_len(pub
));
3828 p
+= wpabuf_len(pub
);
3831 #endif /* CONFIG_OWE */
3834 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3835 sta
&& sta
->dpp_pfs
&& status_code
== WLAN_STATUS_SUCCESS
&&
3836 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
) {
3837 os_memcpy(p
, wpabuf_head(sta
->dpp_pfs
->ie
),
3838 wpabuf_len(sta
->dpp_pfs
->ie
));
3839 p
+= wpabuf_len(sta
->dpp_pfs
->ie
);
3841 #endif /* CONFIG_DPP2 */
3843 #ifdef CONFIG_IEEE80211AC
3844 if (sta
&& hapd
->conf
->vendor_vht
&& (sta
->flags
& WLAN_STA_VENDOR_VHT
))
3845 p
= hostapd_eid_vendor_vht(hapd
, p
);
3846 #endif /* CONFIG_IEEE80211AC */
3848 if (sta
&& (sta
->flags
& WLAN_STA_WMM
))
3849 p
= hostapd_eid_wmm(hapd
, p
);
3853 ((sta
->flags
& WLAN_STA_WPS
) ||
3854 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
))) {
3855 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
3857 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
3858 p
+= wpabuf_len(wps
);
3862 #endif /* CONFIG_WPS */
3864 if (sta
&& (sta
->flags
& WLAN_STA_MULTI_AP
))
3865 p
= hostapd_eid_multi_ap(hapd
, p
);
3868 if (sta
&& sta
->p2p_ie
&& hapd
->p2p_group
) {
3869 struct wpabuf
*p2p_resp_ie
;
3870 enum p2p_status_code status
;
3871 switch (status_code
) {
3872 case WLAN_STATUS_SUCCESS
:
3873 status
= P2P_SC_SUCCESS
;
3875 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
3876 status
= P2P_SC_FAIL_LIMIT_REACHED
;
3879 status
= P2P_SC_FAIL_INVALID_PARAMS
;
3882 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
3884 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
3885 wpabuf_len(p2p_resp_ie
));
3886 p
+= wpabuf_len(p2p_resp_ie
);
3887 wpabuf_free(p2p_resp_ie
);
3890 #endif /* CONFIG_P2P */
3892 #ifdef CONFIG_P2P_MANAGER
3893 if (hapd
->conf
->p2p
& P2P_MANAGE
)
3894 p
= hostapd_eid_p2p_manage(hapd
, p
);
3895 #endif /* CONFIG_P2P_MANAGER */
3897 p
= hostapd_eid_mbo(hapd
, p
, buf
+ buflen
- p
);
3899 if (hapd
->conf
->assocresp_elements
&&
3900 (size_t) (buf
+ buflen
- p
) >=
3901 wpabuf_len(hapd
->conf
->assocresp_elements
)) {
3902 os_memcpy(p
, wpabuf_head(hapd
->conf
->assocresp_elements
),
3903 wpabuf_len(hapd
->conf
->assocresp_elements
));
3904 p
+= wpabuf_len(hapd
->conf
->assocresp_elements
);
3907 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
3911 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3912 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3913 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
3914 status_code
== WLAN_STATUS_SUCCESS
) {
3915 struct ieee802_11_elems elems
;
3917 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 0) ==
3918 ParseFailed
|| !elems
.fils_session
) {
3919 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3924 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3925 *p
++ = 1 + FILS_SESSION_LEN
; /* Length */
3926 *p
++ = WLAN_EID_EXT_FILS_SESSION
; /* Element ID Extension */
3927 os_memcpy(p
, elems
.fils_session
, FILS_SESSION_LEN
);
3928 send_len
+= 2 + 1 + FILS_SESSION_LEN
;
3930 send_len
= fils_encrypt_assoc(sta
->wpa_sm
, buf
, send_len
,
3931 buflen
, sta
->fils_hlp_resp
);
3933 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3937 #endif /* CONFIG_FILS */
3939 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0, NULL
, 0, 0) < 0) {
3940 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
3942 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3952 u8
* owe_assoc_req_process(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3953 const u8
*owe_dh
, u8 owe_dh_len
,
3954 u8
*owe_buf
, size_t owe_buf_len
, u16
*reason
)
3956 #ifdef CONFIG_TESTING_OPTIONS
3957 if (hapd
->conf
->own_ie_override
) {
3958 wpa_printf(MSG_DEBUG
, "OWE: Using IE override");
3959 *reason
= WLAN_STATUS_SUCCESS
;
3960 return wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3961 owe_buf_len
, NULL
, 0);
3963 #endif /* CONFIG_TESTING_OPTIONS */
3965 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
3966 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
3967 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3968 owe_buf_len
, NULL
, 0);
3969 *reason
= WLAN_STATUS_SUCCESS
;
3973 if (sta
->owe_pmk
&& sta
->external_dh_updated
) {
3974 wpa_printf(MSG_DEBUG
, "OWE: Using previously derived PMK");
3975 *reason
= WLAN_STATUS_SUCCESS
;
3979 *reason
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3980 if (*reason
!= WLAN_STATUS_SUCCESS
)
3983 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3984 owe_buf_len
, NULL
, 0);
3986 if (sta
->owe_ecdh
&& owe_buf
) {
3989 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3991 *reason
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3995 /* OWE Diffie-Hellman Parameter element */
3996 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3997 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3998 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
4000 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
4002 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
4003 owe_buf
+= wpabuf_len(pub
);
4009 #endif /* CONFIG_OWE */
4014 void fils_hlp_finish_assoc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
4018 wpa_printf(MSG_DEBUG
, "FILS: Finish association with " MACSTR
,
4019 MAC2STR(sta
->addr
));
4020 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4021 if (!sta
->fils_pending_assoc_req
)
4023 reply_res
= send_assoc_resp(hapd
, sta
, sta
->addr
, WLAN_STATUS_SUCCESS
,
4024 sta
->fils_pending_assoc_is_reassoc
,
4025 sta
->fils_pending_assoc_req
,
4026 sta
->fils_pending_assoc_req_len
, 0);
4027 os_free(sta
->fils_pending_assoc_req
);
4028 sta
->fils_pending_assoc_req
= NULL
;
4029 sta
->fils_pending_assoc_req_len
= 0;
4030 wpabuf_free(sta
->fils_hlp_resp
);
4031 sta
->fils_hlp_resp
= NULL
;
4032 wpabuf_free(sta
->hlp_dhcp_discover
);
4033 sta
->hlp_dhcp_discover
= NULL
;
4036 * Remove the station in case transmission of a success response fails.
4037 * At this point the station was already added associated to the driver.
4039 if (reply_res
!= WLAN_STATUS_SUCCESS
)
4040 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4044 void fils_hlp_timeout(void *eloop_ctx
, void *eloop_data
)
4046 struct hostapd_data
*hapd
= eloop_ctx
;
4047 struct sta_info
*sta
= eloop_data
;
4049 wpa_printf(MSG_DEBUG
,
4050 "FILS: HLP response timeout - continue with association response for "
4051 MACSTR
, MAC2STR(sta
->addr
));
4052 if (sta
->fils_drv_assoc_finish
)
4053 hostapd_notify_assoc_fils_finish(hapd
, sta
);
4055 fils_hlp_finish_assoc(hapd
, sta
);
4058 #endif /* CONFIG_FILS */
4061 static void handle_assoc(struct hostapd_data
*hapd
,
4062 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4063 int reassoc
, int rssi
)
4065 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
4066 u16 resp
= WLAN_STATUS_SUCCESS
, reply_res
;
4069 struct sta_info
*sta
;
4072 int delay_assoc
= 0;
4073 #endif /* CONFIG_FILS */
4075 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
4076 sizeof(mgmt
->u
.assoc_req
))) {
4077 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
4078 reassoc
, (unsigned long) len
);
4082 #ifdef CONFIG_TESTING_OPTIONS
4084 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
4085 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
4086 wpa_printf(MSG_INFO
,
4087 "TESTING: ignoring reassoc request from "
4088 MACSTR
, MAC2STR(mgmt
->sa
));
4092 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
4093 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
4094 wpa_printf(MSG_INFO
,
4095 "TESTING: ignoring assoc request from "
4096 MACSTR
, MAC2STR(mgmt
->sa
));
4100 #endif /* CONFIG_TESTING_OPTIONS */
4102 fc
= le_to_host16(mgmt
->frame_control
);
4103 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4106 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
4107 listen_interval
= le_to_host16(
4108 mgmt
->u
.reassoc_req
.listen_interval
);
4109 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
4110 " capab_info=0x%02x listen_interval=%d current_ap="
4111 MACSTR
" seq_ctrl=0x%x%s",
4112 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
4113 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
4114 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
4115 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
4116 pos
= mgmt
->u
.reassoc_req
.variable
;
4118 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
4119 listen_interval
= le_to_host16(
4120 mgmt
->u
.assoc_req
.listen_interval
);
4121 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
4122 " capab_info=0x%02x listen_interval=%d "
4124 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
4125 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
4126 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
4127 pos
= mgmt
->u
.assoc_req
.variable
;
4130 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4131 #ifdef CONFIG_IEEE80211R_AP
4132 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
4133 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
4134 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
4135 "prior to authentication since it is using "
4136 "over-the-DS FT", MAC2STR(mgmt
->sa
));
4139 * Mark station as authenticated, to avoid adding station
4140 * entry in the driver as associated and not authenticated
4142 sta
->flags
|= WLAN_STA_AUTH
;
4144 #endif /* CONFIG_IEEE80211R_AP */
4145 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
4146 if (hapd
->iface
->current_mode
&&
4147 hapd
->iface
->current_mode
->mode
==
4148 HOSTAPD_MODE_IEEE80211AD
) {
4150 struct radius_sta info
;
4152 acl_res
= ieee802_11_allowed_address(hapd
, mgmt
->sa
,
4155 if (acl_res
== HOSTAPD_ACL_REJECT
) {
4156 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
4157 "Ignore Association Request frame from "
4158 MACSTR
" due to ACL reject",
4160 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4163 if (acl_res
== HOSTAPD_ACL_PENDING
)
4166 /* DMG/IEEE 802.11ad does not use authentication.
4167 * Allocate sta entry upon association. */
4168 sta
= ap_sta_add(hapd
, mgmt
->sa
);
4170 hostapd_logger(hapd
, mgmt
->sa
,
4171 HOSTAPD_MODULE_IEEE80211
,
4173 "Failed to add STA");
4174 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4178 acl_res
= ieee802_11_set_radius_info(
4179 hapd
, sta
, acl_res
, &info
);
4181 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4185 hostapd_logger(hapd
, sta
->addr
,
4186 HOSTAPD_MODULE_IEEE80211
,
4187 HOSTAPD_LEVEL_DEBUG
,
4188 "Skip authentication for DMG/IEEE 802.11ad");
4189 sta
->flags
|= WLAN_STA_AUTH
;
4190 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
4191 sta
->auth_alg
= WLAN_AUTH_OPEN
;
4193 hostapd_logger(hapd
, mgmt
->sa
,
4194 HOSTAPD_MODULE_IEEE80211
,
4196 "Station tried to associate before authentication (aid=%d flags=0x%x)",
4197 sta
? sta
->aid
: -1,
4198 sta
? sta
->flags
: 0);
4199 send_deauth(hapd
, mgmt
->sa
,
4200 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
4205 if ((fc
& WLAN_FC_RETRY
) &&
4206 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4207 sta
->last_seq_ctrl
== seq_ctrl
&&
4208 sta
->last_subtype
== (reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4209 WLAN_FC_STYPE_ASSOC_REQ
)) {
4210 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4211 HOSTAPD_LEVEL_DEBUG
,
4212 "Drop repeated association frame seq_ctrl=0x%x",
4216 sta
->last_seq_ctrl
= seq_ctrl
;
4217 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4218 WLAN_FC_STYPE_ASSOC_REQ
;
4220 if (hapd
->tkip_countermeasures
) {
4221 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4225 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
4226 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4227 HOSTAPD_LEVEL_DEBUG
,
4228 "Too large Listen Interval (%d)",
4230 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
4235 if (hapd
->conf
->mbo_enabled
&& hapd
->mbo_assoc_disallow
) {
4236 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4240 if (hapd
->iconf
->rssi_reject_assoc_rssi
&& rssi
&&
4241 rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
&&
4242 (sta
->auth_rssi
== 0 ||
4243 sta
->auth_rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
)) {
4244 resp
= WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
;
4247 #endif /* CONFIG_MBO */
4250 * sta->capability is used in check_assoc_ies() for RRM enabled
4251 * capability element.
4253 sta
->capability
= capab_info
;
4256 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4257 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4258 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4261 /* The end of the payload is encrypted. Need to decrypt it
4262 * before parsing. */
4264 tmp
= os_memdup(pos
, left
);
4266 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4270 res
= fils_decrypt_assoc(sta
->wpa_sm
, sta
->fils_session
, mgmt
,
4273 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4279 #endif /* CONFIG_FILS */
4281 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
4283 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
4284 if (resp
!= WLAN_STATUS_SUCCESS
)
4287 if (hostapd_get_aid(hapd
, sta
) < 0) {
4288 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4289 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
4290 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4294 sta
->listen_interval
= listen_interval
;
4296 if (hapd
->iface
->current_mode
&&
4297 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
4298 sta
->flags
|= WLAN_STA_NONERP
;
4299 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
4300 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
4301 sta
->flags
&= ~WLAN_STA_NONERP
;
4305 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
4306 sta
->nonerp_set
= 1;
4307 hapd
->iface
->num_sta_non_erp
++;
4308 if (hapd
->iface
->num_sta_non_erp
== 1)
4309 ieee802_11_set_beacons(hapd
->iface
);
4312 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
4313 !sta
->no_short_slot_time_set
) {
4314 sta
->no_short_slot_time_set
= 1;
4315 hapd
->iface
->num_sta_no_short_slot_time
++;
4316 if (hapd
->iface
->current_mode
&&
4317 hapd
->iface
->current_mode
->mode
==
4318 HOSTAPD_MODE_IEEE80211G
&&
4319 hapd
->iface
->num_sta_no_short_slot_time
== 1)
4320 ieee802_11_set_beacons(hapd
->iface
);
4323 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
4324 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
4326 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
4328 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
4329 !sta
->no_short_preamble_set
) {
4330 sta
->no_short_preamble_set
= 1;
4331 hapd
->iface
->num_sta_no_short_preamble
++;
4332 if (hapd
->iface
->current_mode
&&
4333 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
4334 && hapd
->iface
->num_sta_no_short_preamble
== 1)
4335 ieee802_11_set_beacons(hapd
->iface
);
4338 #ifdef CONFIG_IEEE80211N
4339 update_ht_state(hapd
, sta
);
4340 #endif /* CONFIG_IEEE80211N */
4342 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4343 HOSTAPD_LEVEL_DEBUG
,
4344 "association OK (aid %d)", sta
->aid
);
4345 /* Station will be marked associated, after it acknowledges AssocResp
4347 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
4349 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
4350 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
4351 "SA Query procedure", reassoc
? "re" : "");
4352 /* TODO: Send a protected Disassociate frame to the STA using
4353 * the old key and Reason Code "Previous Authentication no
4354 * longer valid". Make sure this is only sent protected since
4355 * unprotected frame would be received by the STA that is now
4356 * trying to associate.
4360 /* Make sure that the previously registered inactivity timer will not
4361 * remove the STA immediately. */
4362 sta
->timeout_next
= STA_NULLFUNC
;
4364 #ifdef CONFIG_TAXONOMY
4365 taxonomy_sta_info_assoc_req(hapd
, sta
, pos
, left
);
4366 #endif /* CONFIG_TAXONOMY */
4368 sta
->pending_wds_enable
= 0;
4371 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4372 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4373 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4374 if (fils_process_hlp(hapd
, sta
, pos
, left
) > 0)
4377 #endif /* CONFIG_FILS */
4382 * In case of a successful response, add the station to the driver.
4383 * Otherwise, the kernel may ignore Data frames before we process the
4384 * ACK frame (TX status). In case of a failure, this station will be
4387 * Note that this is not compliant with the IEEE 802.11 standard that
4388 * states that a non-AP station should transition into the
4389 * authenticated/associated state only after the station acknowledges
4390 * the (Re)Association Response frame. However, still do this as:
4392 * 1. In case the station does not acknowledge the (Re)Association
4393 * Response frame, it will be removed.
4394 * 2. Data frames will be dropped in the kernel until the station is
4395 * set into authorized state, and there are no significant known
4396 * issues with processing other non-Data Class 3 frames during this
4399 if (resp
== WLAN_STATUS_SUCCESS
&& sta
&&
4400 add_associated_sta(hapd
, sta
, reassoc
))
4401 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4404 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
&&
4405 eloop_is_timeout_registered(fils_hlp_timeout
, hapd
, sta
) &&
4406 sta
->fils_pending_assoc_req
) {
4407 /* Do not reschedule fils_hlp_timeout in case the station
4408 * retransmits (Re)Association Request frame while waiting for
4409 * the previously started FILS HLP wait, so that the timeout can
4410 * be determined from the first pending attempt. */
4411 wpa_printf(MSG_DEBUG
,
4412 "FILS: Continue waiting for HLP processing before sending (Re)Association Response frame to "
4413 MACSTR
, MAC2STR(sta
->addr
));
4418 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4419 os_free(sta
->fils_pending_assoc_req
);
4420 sta
->fils_pending_assoc_req
= NULL
;
4421 sta
->fils_pending_assoc_req_len
= 0;
4422 wpabuf_free(sta
->fils_hlp_resp
);
4423 sta
->fils_hlp_resp
= NULL
;
4425 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
) {
4426 sta
->fils_pending_assoc_req
= tmp
;
4427 sta
->fils_pending_assoc_req_len
= left
;
4428 sta
->fils_pending_assoc_is_reassoc
= reassoc
;
4429 sta
->fils_drv_assoc_finish
= 0;
4430 wpa_printf(MSG_DEBUG
,
4431 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
4432 MACSTR
, MAC2STR(sta
->addr
));
4433 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4434 eloop_register_timeout(0, hapd
->conf
->fils_hlp_wait_time
* 1024,
4435 fils_hlp_timeout
, hapd
, sta
);
4438 #endif /* CONFIG_FILS */
4440 reply_res
= send_assoc_resp(hapd
, sta
, mgmt
->sa
, resp
, reassoc
, pos
,
4445 * Remove the station in case tranmission of a success response fails
4446 * (the STA was added associated to the driver) or if the station was
4447 * previously added unassociated.
4449 if (sta
&& ((reply_res
!= WLAN_STATUS_SUCCESS
&&
4450 resp
== WLAN_STATUS_SUCCESS
) || sta
->added_unassoc
)) {
4451 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4452 sta
->added_unassoc
= 0;
4457 static void handle_disassoc(struct hostapd_data
*hapd
,
4458 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4460 struct sta_info
*sta
;
4462 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
4463 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
4464 (unsigned long) len
);
4468 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
4470 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4472 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4474 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
4479 ap_sta_set_authorized(hapd
, sta
, 0);
4480 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4481 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
4482 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
4483 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4484 HOSTAPD_LEVEL_INFO
, "disassociated");
4485 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4486 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4487 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
4489 accounting_sta_stop(hapd
, sta
);
4490 ieee802_1x_free_station(hapd
, sta
);
4492 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
4493 ap_sta_ip6addr_del(hapd
, sta
);
4494 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4495 sta
->added_unassoc
= 0;
4497 if (sta
->timeout_next
== STA_NULLFUNC
||
4498 sta
->timeout_next
== STA_DISASSOC
) {
4499 sta
->timeout_next
= STA_DEAUTH
;
4500 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
4501 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
4505 mlme_disassociate_indication(
4506 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4508 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
4509 * disassociation. */
4510 if (hapd
->iface
->current_mode
&&
4511 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
) {
4512 sta
->flags
&= ~WLAN_STA_AUTH
;
4513 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4514 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4515 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4516 ap_free_sta(hapd
, sta
);
4521 static void handle_deauth(struct hostapd_data
*hapd
,
4522 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4524 struct sta_info
*sta
;
4526 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
4527 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
4528 "payload (len=%lu)", (unsigned long) len
);
4532 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
4534 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
4536 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4538 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
4539 "to deauthenticate, but it is not authenticated",
4544 ap_sta_set_authorized(hapd
, sta
, 0);
4545 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4546 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
4547 WLAN_STA_ASSOC_REQ_OK
);
4548 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4549 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4550 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4551 mlme_deauthenticate_indication(
4552 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
4553 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4554 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4555 ap_free_sta(hapd
, sta
);
4559 static void handle_beacon(struct hostapd_data
*hapd
,
4560 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4561 struct hostapd_frame_info
*fi
)
4563 struct ieee802_11_elems elems
;
4565 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
4566 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
4567 (unsigned long) len
);
4571 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
4572 len
- (IEEE80211_HDRLEN
+
4573 sizeof(mgmt
->u
.beacon
)), &elems
,
4576 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
4580 static int robust_action_frame(u8 category
)
4582 return category
!= WLAN_ACTION_PUBLIC
&&
4583 category
!= WLAN_ACTION_HT
;
4587 static int handle_action(struct hostapd_data
*hapd
,
4588 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4591 struct sta_info
*sta
;
4592 u8
*action __maybe_unused
;
4594 if (len
< IEEE80211_HDRLEN
+ 2 + 1) {
4595 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4596 HOSTAPD_LEVEL_DEBUG
,
4597 "handle_action - too short payload (len=%lu)",
4598 (unsigned long) len
);
4602 action
= (u8
*) &mgmt
->u
.action
.u
;
4603 wpa_printf(MSG_DEBUG
, "RX_ACTION category %u action %u sa " MACSTR
4604 " da " MACSTR
" len %d freq %u",
4605 mgmt
->u
.action
.category
, *action
,
4606 MAC2STR(mgmt
->sa
), MAC2STR(mgmt
->da
), (int) len
, freq
);
4608 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4610 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
4611 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
4612 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
4613 "frame (category=%u) from unassociated STA " MACSTR
,
4614 mgmt
->u
.action
.category
, MAC2STR(mgmt
->sa
));
4618 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
4619 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
4620 robust_action_frame(mgmt
->u
.action
.category
)) {
4621 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4622 HOSTAPD_LEVEL_DEBUG
,
4623 "Dropped unprotected Robust Action frame from "
4629 u16 fc
= le_to_host16(mgmt
->frame_control
);
4630 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4632 if ((fc
& WLAN_FC_RETRY
) &&
4633 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4634 sta
->last_seq_ctrl
== seq_ctrl
&&
4635 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
4636 hostapd_logger(hapd
, sta
->addr
,
4637 HOSTAPD_MODULE_IEEE80211
,
4638 HOSTAPD_LEVEL_DEBUG
,
4639 "Drop repeated action frame seq_ctrl=0x%x",
4644 sta
->last_seq_ctrl
= seq_ctrl
;
4645 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
4648 switch (mgmt
->u
.action
.category
) {
4649 #ifdef CONFIG_IEEE80211R_AP
4650 case WLAN_ACTION_FT
:
4652 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
4653 len
- IEEE80211_HDRLEN
))
4656 #endif /* CONFIG_IEEE80211R_AP */
4657 case WLAN_ACTION_WMM
:
4658 hostapd_wmm_action(hapd
, mgmt
, len
);
4660 case WLAN_ACTION_SA_QUERY
:
4661 ieee802_11_sa_query_action(hapd
, mgmt
, len
);
4663 #ifdef CONFIG_WNM_AP
4664 case WLAN_ACTION_WNM
:
4665 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
4667 #endif /* CONFIG_WNM_AP */
4669 case WLAN_ACTION_FST
:
4670 if (hapd
->iface
->fst
)
4671 fst_rx_action(hapd
->iface
->fst
, mgmt
, len
);
4673 wpa_printf(MSG_DEBUG
,
4674 "FST: Ignore FST Action frame - no FST attached");
4676 #endif /* CONFIG_FST */
4677 case WLAN_ACTION_PUBLIC
:
4678 case WLAN_ACTION_PROTECTED_DUAL
:
4679 #ifdef CONFIG_IEEE80211N
4680 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4681 mgmt
->u
.action
.u
.public_action
.action
==
4682 WLAN_PA_20_40_BSS_COEX
) {
4683 hostapd_2040_coex_action(hapd
, mgmt
, len
);
4686 #endif /* CONFIG_IEEE80211N */
4688 if (len
>= IEEE80211_HDRLEN
+ 6 &&
4689 mgmt
->u
.action
.u
.vs_public_action
.action
==
4690 WLAN_PA_VENDOR_SPECIFIC
&&
4691 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4693 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4695 const u8
*pos
, *end
;
4697 pos
= mgmt
->u
.action
.u
.vs_public_action
.oui
;
4698 end
= ((const u8
*) mgmt
) + len
;
4699 hostapd_dpp_rx_action(hapd
, mgmt
->sa
, pos
, end
- pos
,
4703 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4704 (mgmt
->u
.action
.u
.public_action
.action
==
4705 WLAN_PA_GAS_INITIAL_RESP
||
4706 mgmt
->u
.action
.u
.public_action
.action
==
4707 WLAN_PA_GAS_COMEBACK_RESP
)) {
4708 const u8
*pos
, *end
;
4710 pos
= &mgmt
->u
.action
.u
.public_action
.action
;
4711 end
= ((const u8
*) mgmt
) + len
;
4712 gas_query_ap_rx(hapd
->gas
, mgmt
->sa
,
4713 mgmt
->u
.action
.category
,
4714 pos
, end
- pos
, hapd
->iface
->freq
);
4717 #endif /* CONFIG_DPP */
4718 if (hapd
->public_action_cb
) {
4719 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
4723 if (hapd
->public_action_cb2
) {
4724 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
4728 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
4731 case WLAN_ACTION_VENDOR_SPECIFIC
:
4732 if (hapd
->vendor_action_cb
) {
4733 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
4735 hapd
->iface
->freq
) == 0)
4739 case WLAN_ACTION_RADIO_MEASUREMENT
:
4740 hostapd_handle_radio_measurement(hapd
, (const u8
*) mgmt
, len
);
4744 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4745 HOSTAPD_LEVEL_DEBUG
,
4746 "handle_action - unknown action category %d or invalid "
4748 mgmt
->u
.action
.category
);
4749 if (!is_multicast_ether_addr(mgmt
->da
) &&
4750 !(mgmt
->u
.action
.category
& 0x80) &&
4751 !is_multicast_ether_addr(mgmt
->sa
)) {
4752 struct ieee80211_mgmt
*resp
;
4755 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
4756 * Return the Action frame to the source without change
4757 * except that MSB of the Category set to 1.
4759 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
4760 "frame back to sender");
4761 resp
= os_memdup(mgmt
, len
);
4764 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
4765 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
4766 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
4767 resp
->u
.action
.category
|= 0x80;
4769 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0, NULL
, 0, 0) < 0) {
4770 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
4781 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
4782 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
4784 * @buf: management frame data (starting from IEEE 802.11 header)
4785 * @len: length of frame data in octets
4786 * @fi: meta data about received frame (signal level, etc.)
4788 * Process all incoming IEEE 802.11 management frames. This will be called for
4789 * each frame received from the kernel driver through wlan#ap interface. In
4790 * addition, it can be called to re-inserted pending frames (e.g., when using
4791 * external RADIUS server as an MAC ACL).
4793 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4794 struct hostapd_frame_info
*fi
)
4796 struct ieee80211_mgmt
*mgmt
;
4800 int ssi_signal
= fi
? fi
->ssi_signal
: 0;
4808 freq
= hapd
->iface
->freq
;
4810 mgmt
= (struct ieee80211_mgmt
*) buf
;
4811 fc
= le_to_host16(mgmt
->frame_control
);
4812 stype
= WLAN_FC_GET_STYPE(fc
);
4814 if (is_multicast_ether_addr(mgmt
->sa
) ||
4815 is_zero_ether_addr(mgmt
->sa
) ||
4816 os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
4817 /* Do not process any frames with unexpected/invalid SA so that
4818 * we do not add any state for unexpected STA addresses or end
4819 * up sending out frames to unexpected destination. */
4820 wpa_printf(MSG_DEBUG
, "MGMT: Invalid SA=" MACSTR
4821 " in received frame - ignore this frame silently",
4826 if (stype
== WLAN_FC_STYPE_BEACON
) {
4827 handle_beacon(hapd
, mgmt
, len
, fi
);
4831 if (!is_broadcast_ether_addr(mgmt
->bssid
) &&
4833 /* Invitation responses can be sent with the peer MAC as BSSID */
4834 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
4835 stype
== WLAN_FC_STYPE_ACTION
) &&
4836 #endif /* CONFIG_P2P */
4838 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
4839 #endif /* CONFIG_MESH */
4840 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4841 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
4842 MAC2STR(mgmt
->bssid
));
4847 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
4848 handle_probe_req(hapd
, mgmt
, len
, ssi_signal
);
4852 if ((!is_broadcast_ether_addr(mgmt
->da
) ||
4853 stype
!= WLAN_FC_STYPE_ACTION
) &&
4854 os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4855 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4856 HOSTAPD_LEVEL_DEBUG
,
4857 "MGMT: DA=" MACSTR
" not our address",
4862 if (hapd
->iconf
->track_sta_max_num
)
4863 sta_track_add(hapd
->iface
, mgmt
->sa
, ssi_signal
);
4866 case WLAN_FC_STYPE_AUTH
:
4867 wpa_printf(MSG_DEBUG
, "mgmt::auth");
4868 handle_auth(hapd
, mgmt
, len
, ssi_signal
, 0);
4871 case WLAN_FC_STYPE_ASSOC_REQ
:
4872 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
4873 handle_assoc(hapd
, mgmt
, len
, 0, ssi_signal
);
4876 case WLAN_FC_STYPE_REASSOC_REQ
:
4877 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
4878 handle_assoc(hapd
, mgmt
, len
, 1, ssi_signal
);
4881 case WLAN_FC_STYPE_DISASSOC
:
4882 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
4883 handle_disassoc(hapd
, mgmt
, len
);
4886 case WLAN_FC_STYPE_DEAUTH
:
4887 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
4888 handle_deauth(hapd
, mgmt
, len
);
4891 case WLAN_FC_STYPE_ACTION
:
4892 wpa_printf(MSG_DEBUG
, "mgmt::action");
4893 ret
= handle_action(hapd
, mgmt
, len
, freq
);
4896 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4897 HOSTAPD_LEVEL_DEBUG
,
4898 "unknown mgmt frame subtype %d", stype
);
4906 static void handle_auth_cb(struct hostapd_data
*hapd
,
4907 const struct ieee80211_mgmt
*mgmt
,
4910 u16 auth_alg
, auth_transaction
, status_code
;
4911 struct sta_info
*sta
;
4913 sta
= ap_get_sta(hapd
, mgmt
->da
);
4915 wpa_printf(MSG_DEBUG
, "handle_auth_cb: STA " MACSTR
4921 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
4922 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
4923 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
4926 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4927 HOSTAPD_LEVEL_NOTICE
,
4928 "did not acknowledge authentication response");
4932 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
4933 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
4934 (unsigned long) len
);
4938 if (status_code
== WLAN_STATUS_SUCCESS
&&
4939 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
4940 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
4941 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4942 HOSTAPD_LEVEL_INFO
, "authenticated");
4943 sta
->flags
|= WLAN_STA_AUTH
;
4944 if (sta
->added_unassoc
)
4945 hostapd_set_sta_flags(hapd
, sta
);
4950 if (status_code
!= WLAN_STATUS_SUCCESS
&& sta
->added_unassoc
) {
4951 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4952 sta
->added_unassoc
= 0;
4957 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
4958 struct sta_info
*sta
,
4962 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
4964 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
4967 for (i
= 0; i
< 4; i
++) {
4968 if (ssid
->wep
.key
[i
] &&
4969 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
4970 0, i
== ssid
->wep
.idx
, NULL
, 0,
4971 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
],
4972 i
== ssid
->wep
.idx
?
4973 KEY_FLAG_GROUP_RX_TX_DEFAULT
:
4974 KEY_FLAG_GROUP_RX_TX
)) {
4975 wpa_printf(MSG_WARNING
,
4976 "Could not set WEP keys for WDS interface; %s",
4984 static void handle_assoc_cb(struct hostapd_data
*hapd
,
4985 const struct ieee80211_mgmt
*mgmt
,
4986 size_t len
, int reassoc
, int ok
)
4989 struct sta_info
*sta
;
4992 sta
= ap_get_sta(hapd
, mgmt
->da
);
4994 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
4999 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
5000 sizeof(mgmt
->u
.assoc_resp
))) {
5001 wpa_printf(MSG_INFO
,
5002 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
5003 reassoc
, (unsigned long) len
);
5004 hostapd_drv_sta_remove(hapd
, sta
->addr
);
5009 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
5011 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
5014 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
5015 HOSTAPD_LEVEL_DEBUG
,
5016 "did not acknowledge association response");
5017 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
5018 /* The STA is added only in case of SUCCESS */
5019 if (status
== WLAN_STATUS_SUCCESS
)
5020 hostapd_drv_sta_remove(hapd
, sta
->addr
);
5025 if (status
!= WLAN_STATUS_SUCCESS
)
5028 /* Stop previous accounting session, if one is started, and allocate
5029 * new session id for the new session. */
5030 accounting_sta_stop(hapd
, sta
);
5032 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
5034 "associated (aid %d)",
5037 if (sta
->flags
& WLAN_STA_ASSOC
)
5039 sta
->flags
|= WLAN_STA_ASSOC
;
5040 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
5041 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
5042 !hapd
->conf
->osen
) ||
5043 sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
5044 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
5045 sta
->auth_alg
== WLAN_AUTH_FILS_PK
||
5046 sta
->auth_alg
== WLAN_AUTH_FT
) {
5048 * Open, static WEP, FT protocol, or FILS; no separate
5049 * authorization step.
5051 ap_sta_set_authorized(hapd
, sta
, 1);
5055 mlme_reassociate_indication(hapd
, sta
);
5057 mlme_associate_indication(hapd
, sta
);
5059 sta
->sa_query_timed_out
= 0;
5061 if (sta
->eapol_sm
== NULL
) {
5063 * This STA does not use RADIUS server for EAP authentication,
5064 * so bind it to the selected VLAN interface now, since the
5065 * interface selection is not going to change anymore.
5067 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
5069 } else if (sta
->vlan_id
) {
5070 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
5071 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
5075 hostapd_set_sta_flags(hapd
, sta
);
5077 if (!(sta
->flags
& WLAN_STA_WDS
) && sta
->pending_wds_enable
) {
5078 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for STA "
5079 MACSTR
" based on pending request",
5080 MAC2STR(sta
->addr
));
5081 sta
->pending_wds_enable
= 0;
5082 sta
->flags
|= WLAN_STA_WDS
;
5085 if (sta
->flags
& (WLAN_STA_WDS
| WLAN_STA_MULTI_AP
)) {
5087 char ifname_wds
[IFNAMSIZ
+ 1];
5089 wpa_printf(MSG_DEBUG
, "Reenable 4-address WDS mode for STA "
5091 MAC2STR(sta
->addr
), sta
->aid
);
5092 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
5095 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
5098 if (sta
->auth_alg
== WLAN_AUTH_FT
)
5099 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
5101 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
5102 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
5103 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
5106 if ((sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
5107 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
5108 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
5109 fils_set_tk(sta
->wpa_sm
) < 0) {
5110 wpa_printf(MSG_DEBUG
, "FILS: TK configuration failed");
5111 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
5112 WLAN_REASON_UNSPECIFIED
);
5115 #endif /* CONFIG_FILS */
5117 if (sta
->pending_eapol_rx
) {
5118 struct os_reltime now
, age
;
5120 os_get_reltime(&now
);
5121 os_reltime_sub(&now
, &sta
->pending_eapol_rx
->rx_time
, &age
);
5122 if (age
.sec
== 0 && age
.usec
< 200000) {
5123 wpa_printf(MSG_DEBUG
,
5124 "Process pending EAPOL frame that was received from " MACSTR
" just before association notification",
5125 MAC2STR(sta
->addr
));
5128 wpabuf_head(sta
->pending_eapol_rx
->buf
),
5129 wpabuf_len(sta
->pending_eapol_rx
->buf
));
5131 wpabuf_free(sta
->pending_eapol_rx
->buf
);
5132 os_free(sta
->pending_eapol_rx
);
5133 sta
->pending_eapol_rx
= NULL
;
5138 static void handle_deauth_cb(struct hostapd_data
*hapd
,
5139 const struct ieee80211_mgmt
*mgmt
,
5142 struct sta_info
*sta
;
5143 if (is_multicast_ether_addr(mgmt
->da
))
5145 sta
= ap_get_sta(hapd
, mgmt
->da
);
5147 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
5148 " not found", MAC2STR(mgmt
->da
));
5152 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
5153 MAC2STR(sta
->addr
));
5155 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
5156 "deauth", MAC2STR(sta
->addr
));
5158 ap_sta_deauth_cb(hapd
, sta
);
5162 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
5163 const struct ieee80211_mgmt
*mgmt
,
5166 struct sta_info
*sta
;
5167 if (is_multicast_ether_addr(mgmt
->da
))
5169 sta
= ap_get_sta(hapd
, mgmt
->da
);
5171 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
5172 " not found", MAC2STR(mgmt
->da
));
5176 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
5177 MAC2STR(sta
->addr
));
5179 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
5180 "disassoc", MAC2STR(sta
->addr
));
5182 ap_sta_disassoc_cb(hapd
, sta
);
5186 static void handle_action_cb(struct hostapd_data
*hapd
,
5187 const struct ieee80211_mgmt
*mgmt
,
5190 struct sta_info
*sta
;
5191 const struct rrm_measurement_report_element
*report
;
5193 if (is_multicast_ether_addr(mgmt
->da
))
5196 if (len
>= IEEE80211_HDRLEN
+ 6 &&
5197 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5198 mgmt
->u
.action
.u
.vs_public_action
.action
==
5199 WLAN_PA_VENDOR_SPECIFIC
&&
5200 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
5202 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
5204 const u8
*pos
, *end
;
5206 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
5207 end
= ((const u8
*) mgmt
) + len
;
5208 hostapd_dpp_tx_status(hapd
, mgmt
->da
, pos
, end
- pos
, ok
);
5211 if (len
>= IEEE80211_HDRLEN
+ 2 &&
5212 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5213 (mgmt
->u
.action
.u
.public_action
.action
==
5214 WLAN_PA_GAS_INITIAL_REQ
||
5215 mgmt
->u
.action
.u
.public_action
.action
==
5216 WLAN_PA_GAS_COMEBACK_REQ
)) {
5217 const u8
*pos
, *end
;
5219 pos
= mgmt
->u
.action
.u
.public_action
.variable
;
5220 end
= ((const u8
*) mgmt
) + len
;
5221 gas_query_ap_tx_status(hapd
->gas
, mgmt
->da
, pos
, end
- pos
, ok
);
5224 #endif /* CONFIG_DPP */
5225 sta
= ap_get_sta(hapd
, mgmt
->da
);
5227 wpa_printf(MSG_DEBUG
, "handle_action_cb: STA " MACSTR
5228 " not found", MAC2STR(mgmt
->da
));
5232 if (len
< 24 + 5 + sizeof(*report
))
5234 report
= (const struct rrm_measurement_report_element
*)
5235 &mgmt
->u
.action
.u
.rrm
.variable
[2];
5236 if (mgmt
->u
.action
.category
== WLAN_ACTION_RADIO_MEASUREMENT
&&
5237 mgmt
->u
.action
.u
.rrm
.action
== WLAN_RRM_RADIO_MEASUREMENT_REQUEST
&&
5238 report
->eid
== WLAN_EID_MEASURE_REQUEST
&&
5240 report
->type
== MEASURE_TYPE_BEACON
)
5241 hostapd_rrm_beacon_req_tx_status(hapd
, mgmt
, len
, ok
);
5246 * ieee802_11_mgmt_cb - Process management frame TX status callback
5247 * @hapd: hostapd BSS data structure (the BSS from which the management frame
5249 * @buf: management frame data (starting from IEEE 802.11 header)
5250 * @len: length of frame data in octets
5251 * @stype: management frame subtype from frame control field
5252 * @ok: Whether the frame was ACK'ed
5254 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
5257 const struct ieee80211_mgmt
*mgmt
;
5258 mgmt
= (const struct ieee80211_mgmt
*) buf
;
5260 #ifdef CONFIG_TESTING_OPTIONS
5261 if (hapd
->ext_mgmt_frame_handling
) {
5262 size_t hex_len
= 2 * len
+ 1;
5263 char *hex
= os_malloc(hex_len
);
5266 wpa_snprintf_hex(hex
, hex_len
, buf
, len
);
5267 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
5268 "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
5274 #endif /* CONFIG_TESTING_OPTIONS */
5277 case WLAN_FC_STYPE_AUTH
:
5278 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
5279 handle_auth_cb(hapd
, mgmt
, len
, ok
);
5281 case WLAN_FC_STYPE_ASSOC_RESP
:
5282 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
5283 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
5285 case WLAN_FC_STYPE_REASSOC_RESP
:
5286 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
5287 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
5289 case WLAN_FC_STYPE_PROBE_RESP
:
5290 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb ok=%d", ok
);
5292 case WLAN_FC_STYPE_DEAUTH
:
5293 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
5294 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
5296 case WLAN_FC_STYPE_DISASSOC
:
5297 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
5298 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
5300 case WLAN_FC_STYPE_ACTION
:
5301 wpa_printf(MSG_DEBUG
, "mgmt::action cb ok=%d", ok
);
5302 handle_action_cb(hapd
, mgmt
, len
, ok
);
5305 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
5311 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
5318 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
5319 char *buf
, size_t buflen
)
5326 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
5327 const u8
*buf
, size_t len
, int ack
)
5329 struct sta_info
*sta
;
5330 struct hostapd_iface
*iface
= hapd
->iface
;
5332 sta
= ap_get_sta(hapd
, addr
);
5333 if (sta
== NULL
&& iface
->num_bss
> 1) {
5335 for (j
= 0; j
< iface
->num_bss
; j
++) {
5336 hapd
= iface
->bss
[j
];
5337 sta
= ap_get_sta(hapd
, addr
);
5342 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
5344 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
5345 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
5346 "activity poll", MAC2STR(sta
->addr
),
5347 ack
? "ACKed" : "did not ACK");
5349 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5352 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
5356 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
5357 const u8
*data
, size_t len
, int ack
)
5359 struct sta_info
*sta
;
5360 struct hostapd_iface
*iface
= hapd
->iface
;
5362 sta
= ap_get_sta(hapd
, dst
);
5363 if (sta
== NULL
&& iface
->num_bss
> 1) {
5365 for (j
= 0; j
< iface
->num_bss
; j
++) {
5366 hapd
= iface
->bss
[j
];
5367 sta
= ap_get_sta(hapd
, dst
);
5372 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
5373 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
5374 MACSTR
" that is not currently associated",
5379 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
5383 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
5385 struct sta_info
*sta
;
5386 struct hostapd_iface
*iface
= hapd
->iface
;
5388 sta
= ap_get_sta(hapd
, addr
);
5389 if (sta
== NULL
&& iface
->num_bss
> 1) {
5391 for (j
= 0; j
< iface
->num_bss
; j
++) {
5392 hapd
= iface
->bss
[j
];
5393 sta
= ap_get_sta(hapd
, addr
);
5400 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_POLL_OK MACSTR
,
5401 MAC2STR(sta
->addr
));
5402 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
5405 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
5406 "activity poll", MAC2STR(sta
->addr
));
5407 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5411 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
5414 struct sta_info
*sta
;
5416 sta
= ap_get_sta(hapd
, src
);
5418 ((sta
->flags
& WLAN_STA_ASSOC
) ||
5419 ((sta
->flags
& WLAN_STA_ASSOC_REQ_OK
) && wds
))) {
5420 if (!hapd
->conf
->wds_sta
)
5423 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
)) ==
5424 WLAN_STA_ASSOC_REQ_OK
) {
5425 wpa_printf(MSG_DEBUG
,
5426 "Postpone 4-address WDS mode enabling for STA "
5427 MACSTR
" since TX status for AssocResp is not yet known",
5428 MAC2STR(sta
->addr
));
5429 sta
->pending_wds_enable
= 1;
5433 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
5435 char ifname_wds
[IFNAMSIZ
+ 1];
5437 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
5438 "STA " MACSTR
" (aid %u)",
5439 MAC2STR(sta
->addr
), sta
->aid
);
5440 sta
->flags
|= WLAN_STA_WDS
;
5441 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
5442 sta
->addr
, sta
->aid
, 1);
5444 hostapd_set_wds_encryption(hapd
, sta
,
5450 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
5451 MACSTR
, MAC2STR(src
));
5452 if (is_multicast_ether_addr(src
) || is_zero_ether_addr(src
) ||
5453 os_memcmp(src
, hapd
->own_addr
, ETH_ALEN
) == 0) {
5454 /* Broadcast bit set in SA or unexpected SA?! Ignore the frame
5459 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
5460 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
5461 "already been sent, but no TX status yet known - "
5462 "ignore Class 3 frame issue with " MACSTR
,
5467 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
5468 hostapd_drv_sta_disassoc(
5470 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5472 hostapd_drv_sta_deauth(
5474 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5478 #endif /* CONFIG_NATIVE_WINDOWS */