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 wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
);
108 /* rest of the rates are encoded in Extended supported
114 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
117 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
118 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
123 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&& count
< 8) {
125 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
128 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&& count
< 8) {
130 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
133 if (h2e_required
&& count
< 8) {
135 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY
;
142 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
148 if (hapd
->iface
->current_rates
== NULL
)
151 num
= hapd
->iface
->num_rates
;
152 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
154 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
156 h2e_required
= (hapd
->conf
->sae_pwe
== 1 ||
157 hostapd_sae_pw_id_in_use(hapd
->conf
) == 2) &&
158 wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
);
165 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
167 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
171 continue; /* already in SuppRates IE */
172 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
173 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
178 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
) {
181 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
184 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
) {
187 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
193 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY
;
200 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
)
202 int capab
= WLAN_CAPABILITY_ESS
;
207 /* Check if any of configured channels require DFS */
208 dfs
= hostapd_is_dfs_required(hapd
->iface
);
210 wpa_printf(MSG_WARNING
, "Failed to check if DFS is required; ret=%d",
215 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
216 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
217 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
219 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
221 if (hapd
->conf
->ieee802_1x
&&
222 (hapd
->conf
->default_wep_key_len
||
223 hapd
->conf
->individual_wep_key_len
))
230 if (hapd
->conf
->osen
)
232 #endif /* CONFIG_HS20 */
235 capab
|= WLAN_CAPABILITY_PRIVACY
;
237 if (hapd
->iface
->current_mode
&&
238 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
239 hapd
->iface
->num_sta_no_short_slot_time
== 0)
240 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
243 * Currently, Spectrum Management capability bit is set when directly
244 * requested in configuration by spectrum_mgmt_required or when AP is
245 * running on DFS channel.
246 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
248 if (hapd
->iface
->current_mode
&&
249 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
&&
250 (hapd
->iconf
->spectrum_mgmt_required
|| dfs
))
251 capab
|= WLAN_CAPABILITY_SPECTRUM_MGMT
;
253 for (i
= 0; i
< RRM_CAPABILITIES_IE_LEN
; i
++) {
254 if (hapd
->conf
->radio_measurements
[i
]) {
255 capab
|= IEEE80211_CAP_RRM
;
264 #ifndef CONFIG_NO_RC4
265 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
266 u16 auth_transaction
, const u8
*challenge
,
269 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
271 "authentication (shared key, transaction %d)",
274 if (auth_transaction
== 1) {
275 if (!sta
->challenge
) {
276 /* Generate a pseudo-random challenge */
279 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
280 if (sta
->challenge
== NULL
)
281 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
283 if (os_get_random(key
, sizeof(key
)) < 0) {
284 os_free(sta
->challenge
);
285 sta
->challenge
= NULL
;
286 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
289 rc4_skip(key
, sizeof(key
), 0,
290 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
295 if (auth_transaction
!= 3)
296 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
299 if (!iswep
|| !sta
->challenge
|| !challenge
||
300 os_memcmp_const(sta
->challenge
, challenge
,
301 WLAN_AUTH_CHALLENGE_LEN
)) {
302 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
304 "shared key authentication - invalid "
305 "challenge-response");
306 return WLAN_STATUS_CHALLENGE_FAIL
;
309 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
311 "authentication OK (shared key)");
312 sta
->flags
|= WLAN_STA_AUTH
;
313 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
314 os_free(sta
->challenge
);
315 sta
->challenge
= NULL
;
319 #endif /* CONFIG_NO_RC4 */
322 static int send_auth_reply(struct hostapd_data
*hapd
, struct sta_info
*sta
,
323 const u8
*dst
, const u8
*bssid
,
324 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
325 const u8
*ies
, size_t ies_len
, const char *dbg
)
327 struct ieee80211_mgmt
*reply
;
330 int reply_res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
332 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
333 buf
= os_zalloc(rlen
);
337 reply
= (struct ieee80211_mgmt
*) buf
;
338 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
340 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
341 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
342 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
344 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
345 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
346 reply
->u
.auth
.status_code
= host_to_le16(resp
);
349 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
351 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
352 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu) (dbg=%s)",
353 MAC2STR(dst
), auth_alg
, auth_transaction
,
354 resp
, (unsigned long) ies_len
, dbg
);
355 #ifdef CONFIG_TESTING_OPTIONS
357 if (hapd
->conf
->sae_confirm_immediate
== 2 &&
358 auth_alg
== WLAN_AUTH_SAE
) {
359 if (auth_transaction
== 1 &&
360 (resp
== WLAN_STATUS_SUCCESS
||
361 resp
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
)) {
362 wpa_printf(MSG_DEBUG
,
363 "TESTING: Postpone SAE Commit transmission until Confirm is ready");
364 os_free(sta
->sae_postponed_commit
);
365 sta
->sae_postponed_commit
= buf
;
366 sta
->sae_postponed_commit_len
= rlen
;
367 return WLAN_STATUS_SUCCESS
;
370 if (auth_transaction
== 2 && sta
&& sta
->sae_postponed_commit
) {
371 wpa_printf(MSG_DEBUG
,
372 "TESTING: Send postponed SAE Commit first, immediately followed by SAE Confirm");
373 if (hostapd_drv_send_mlme(hapd
,
374 sta
->sae_postponed_commit
,
375 sta
->sae_postponed_commit_len
,
377 wpa_printf(MSG_INFO
, "send_auth_reply: send failed");
378 os_free(sta
->sae_postponed_commit
);
379 sta
->sae_postponed_commit
= NULL
;
380 sta
->sae_postponed_commit_len
= 0;
383 #endif /* CONFIG_SAE */
384 #endif /* CONFIG_TESTING_OPTIONS */
385 if (hostapd_drv_send_mlme(hapd
, reply
, rlen
, 0, NULL
, 0, 0) < 0)
386 wpa_printf(MSG_INFO
, "send_auth_reply: send failed");
388 reply_res
= WLAN_STATUS_SUCCESS
;
396 #ifdef CONFIG_IEEE80211R_AP
397 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
398 u16 auth_transaction
, u16 status
,
399 const u8
*ies
, size_t ies_len
)
401 struct hostapd_data
*hapd
= ctx
;
402 struct sta_info
*sta
;
405 reply_res
= send_auth_reply(hapd
, NULL
, dst
, bssid
, WLAN_AUTH_FT
,
406 auth_transaction
, status
, ies
, ies_len
,
409 sta
= ap_get_sta(hapd
, dst
);
413 if (sta
->added_unassoc
&& (reply_res
!= WLAN_STATUS_SUCCESS
||
414 status
!= WLAN_STATUS_SUCCESS
)) {
415 hostapd_drv_sta_remove(hapd
, sta
->addr
);
416 sta
->added_unassoc
= 0;
420 if (status
!= WLAN_STATUS_SUCCESS
)
423 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
424 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
425 sta
->flags
|= WLAN_STA_AUTH
;
426 mlme_authenticate_indication(hapd
, sta
);
428 #endif /* CONFIG_IEEE80211R_AP */
433 static void sae_set_state(struct sta_info
*sta
, enum sae_state state
,
436 wpa_printf(MSG_DEBUG
, "SAE: State %s -> %s for peer " MACSTR
" (%s)",
437 sae_state_txt(sta
->sae
->state
), sae_state_txt(state
),
438 MAC2STR(sta
->addr
), reason
);
439 sta
->sae
->state
= state
;
443 static struct wpabuf
* auth_build_sae_commit(struct hostapd_data
*hapd
,
444 struct sta_info
*sta
, int update
,
448 const char *password
= NULL
;
449 struct sae_password_entry
*pw
;
450 const char *rx_id
= NULL
;
452 struct sae_pt
*pt
= NULL
;
455 rx_id
= sta
->sae
->tmp
->pw_id
;
456 use_pt
= sta
->sae
->tmp
->h2e
;
461 else if (status_code
== WLAN_STATUS_SUCCESS
)
463 else if (status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
)
466 for (pw
= hapd
->conf
->sae_passwords
; pw
; pw
= pw
->next
) {
467 if (!is_broadcast_ether_addr(pw
->peer_addr
) &&
468 os_memcmp(pw
->peer_addr
, sta
->addr
, ETH_ALEN
) != 0)
470 if ((rx_id
&& !pw
->identifier
) || (!rx_id
&& pw
->identifier
))
472 if (rx_id
&& pw
->identifier
&&
473 os_strcmp(rx_id
, pw
->identifier
) != 0)
475 password
= pw
->password
;
480 password
= hapd
->conf
->ssid
.wpa_passphrase
;
481 pt
= hapd
->conf
->ssid
.pt
;
483 if (!password
|| (use_pt
&& !pt
)) {
484 wpa_printf(MSG_DEBUG
, "SAE: No password available");
488 if (update
&& use_pt
&&
489 sae_prepare_commit_pt(sta
->sae
, pt
, hapd
->own_addr
, sta
->addr
,
493 if (update
&& !use_pt
&&
494 sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
495 (u8
*) password
, os_strlen(password
), rx_id
,
497 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
501 if (pw
&& pw
->vlan_id
) {
502 if (!sta
->sae
->tmp
) {
504 "SAE: No temporary data allocated - cannot store VLAN ID");
507 sta
->sae
->tmp
->vlan_id
= pw
->vlan_id
;
510 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
+
511 (rx_id
? 3 + os_strlen(rx_id
) : 0));
514 sae_write_commit(sta
->sae
, buf
, sta
->sae
->tmp
?
515 sta
->sae
->tmp
->anti_clogging_token
: NULL
, rx_id
);
521 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
522 struct sta_info
*sta
)
526 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
530 sae_write_confirm(sta
->sae
, buf
);
536 static int auth_sae_send_commit(struct hostapd_data
*hapd
,
537 struct sta_info
*sta
,
538 const u8
*bssid
, int update
, int status_code
)
544 data
= auth_build_sae_commit(hapd
, sta
, update
, status_code
);
545 if (!data
&& sta
->sae
->tmp
&& sta
->sae
->tmp
->pw_id
)
546 return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
;
548 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
550 status
= (sta
->sae
->tmp
&& sta
->sae
->tmp
->h2e
) ?
551 WLAN_STATUS_SAE_HASH_TO_ELEMENT
: WLAN_STATUS_SUCCESS
;
552 reply_res
= send_auth_reply(hapd
, sta
, sta
->addr
, bssid
,
554 status
, wpabuf_head(data
),
555 wpabuf_len(data
), "sae-send-commit");
563 static int auth_sae_send_confirm(struct hostapd_data
*hapd
,
564 struct sta_info
*sta
,
570 data
= auth_build_sae_confirm(hapd
, sta
);
572 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
574 reply_res
= send_auth_reply(hapd
, sta
, sta
->addr
, bssid
,
576 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
577 wpabuf_len(data
), "sae-send-confirm");
585 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
587 struct sta_info
*sta
;
588 unsigned int open
= 0;
590 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
593 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
596 if (sta
->sae
->state
!= SAE_COMMITTED
&&
597 sta
->sae
->state
!= SAE_CONFIRMED
)
600 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
604 /* In addition to already existing open SAE sessions, check whether
605 * there are enough pending commit messages in the processing queue to
606 * potentially result in too many open sessions. */
607 if (open
+ dl_list_len(&hapd
->sae_commit_queue
) >=
608 hapd
->conf
->sae_anti_clogging_threshold
)
615 static u8
sae_token_hash(struct hostapd_data
*hapd
, const u8
*addr
)
617 u8 hash
[SHA256_MAC_LEN
];
619 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
620 addr
, ETH_ALEN
, hash
);
625 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
626 const u8
*token
, size_t token_len
)
628 u8 mac
[SHA256_MAC_LEN
];
634 if (token_len
!= SHA256_MAC_LEN
)
636 idx
= sae_token_hash(hapd
, addr
);
637 token_idx
= hapd
->sae_pending_token_idx
[idx
];
638 if (token_idx
== 0 || token_idx
!= WPA_GET_BE16(token
)) {
639 wpa_printf(MSG_DEBUG
, "SAE: Invalid anti-clogging token from "
640 MACSTR
" - token_idx 0x%04x, expected 0x%04x",
641 MAC2STR(addr
), WPA_GET_BE16(token
), token_idx
);
649 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
650 2, addrs
, len
, mac
) < 0 ||
651 os_memcmp_const(token
+ 2, &mac
[2], SHA256_MAC_LEN
- 2) != 0)
654 hapd
->sae_pending_token_idx
[idx
] = 0; /* invalidate used token */
660 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
661 int group
, const u8
*addr
, int h2e
)
665 struct os_reltime now
;
672 os_get_reltime(&now
);
673 if (!os_reltime_initialized(&hapd
->last_sae_token_key_update
) ||
674 os_reltime_expired(&now
, &hapd
->last_sae_token_key_update
, 60) ||
675 hapd
->sae_token_idx
== 0xffff) {
676 if (random_get_bytes(hapd
->sae_token_key
,
677 sizeof(hapd
->sae_token_key
)) < 0)
679 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
680 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
681 hapd
->last_sae_token_key_update
= now
;
682 hapd
->sae_token_idx
= 0;
683 os_memset(hapd
->sae_pending_token_idx
, 0,
684 sizeof(hapd
->sae_pending_token_idx
));
687 buf
= wpabuf_alloc(sizeof(le16
) + 3 + SHA256_MAC_LEN
);
691 wpabuf_put_le16(buf
, group
); /* Finite Cyclic Group */
694 /* Encapsulate Anti-clogging Token field in a container IE */
695 wpabuf_put_u8(buf
, WLAN_EID_EXTENSION
);
696 wpabuf_put_u8(buf
, 1 + SHA256_MAC_LEN
);
697 wpabuf_put_u8(buf
, WLAN_EID_EXT_ANTI_CLOGGING_TOKEN
);
700 p_idx
= sae_token_hash(hapd
, addr
);
701 token_idx
= hapd
->sae_pending_token_idx
[p_idx
];
703 hapd
->sae_token_idx
++;
704 token_idx
= hapd
->sae_token_idx
;
705 hapd
->sae_pending_token_idx
[p_idx
] = token_idx
;
707 WPA_PUT_BE16(idx
, token_idx
);
708 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
712 len
[1] = sizeof(idx
);
713 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
714 2, addrs
, len
, token
) < 0) {
718 WPA_PUT_BE16(token
, token_idx
);
724 static int sae_check_big_sync(struct hostapd_data
*hapd
, struct sta_info
*sta
)
726 if (sta
->sae
->sync
> hapd
->conf
->sae_sync
) {
727 sae_set_state(sta
, SAE_NOTHING
, "Sync > dot11RSNASAESync");
735 static void auth_sae_retransmit_timer(void *eloop_ctx
, void *eloop_data
)
737 struct hostapd_data
*hapd
= eloop_ctx
;
738 struct sta_info
*sta
= eloop_data
;
741 if (sae_check_big_sync(hapd
, sta
))
744 wpa_printf(MSG_DEBUG
, "SAE: Auth SAE retransmit timer for " MACSTR
745 " (sync=%d state=%s)",
746 MAC2STR(sta
->addr
), sta
->sae
->sync
,
747 sae_state_txt(sta
->sae
->state
));
749 switch (sta
->sae
->state
) {
751 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0, -1);
752 eloop_register_timeout(0,
753 hapd
->dot11RSNASAERetransPeriod
* 1000,
754 auth_sae_retransmit_timer
, hapd
, sta
);
757 ret
= auth_sae_send_confirm(hapd
, sta
, hapd
->own_addr
);
758 eloop_register_timeout(0,
759 hapd
->dot11RSNASAERetransPeriod
* 1000,
760 auth_sae_retransmit_timer
, hapd
, sta
);
767 if (ret
!= WLAN_STATUS_SUCCESS
)
768 wpa_printf(MSG_INFO
, "SAE: Failed to retransmit: ret=%d", ret
);
772 void sae_clear_retransmit_timer(struct hostapd_data
*hapd
, struct sta_info
*sta
)
774 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
778 static void sae_set_retransmit_timer(struct hostapd_data
*hapd
,
779 struct sta_info
*sta
)
781 if (!(hapd
->conf
->mesh
& MESH_ENABLED
))
784 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
785 eloop_register_timeout(0, hapd
->dot11RSNASAERetransPeriod
* 1000,
786 auth_sae_retransmit_timer
, hapd
, sta
);
790 static void sae_sme_send_external_auth_status(struct hostapd_data
*hapd
,
791 struct sta_info
*sta
, u16 status
)
793 struct external_auth params
;
795 os_memset(¶ms
, 0, sizeof(params
));
796 params
.status
= status
;
797 params
.bssid
= sta
->addr
;
798 if (status
== WLAN_STATUS_SUCCESS
&& sta
->sae
&&
799 !hapd
->conf
->disable_pmksa_caching
)
800 params
.pmkid
= sta
->sae
->pmkid
;
802 hostapd_drv_send_external_auth_status(hapd
, ¶ms
);
806 void sae_accept_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
808 #ifndef CONFIG_NO_VLAN
809 struct vlan_description vlan_desc
;
811 if (sta
->sae
->tmp
&& sta
->sae
->tmp
->vlan_id
> 0) {
812 wpa_printf(MSG_DEBUG
, "SAE: Assign STA " MACSTR
814 MAC2STR(sta
->addr
), sta
->sae
->tmp
->vlan_id
);
816 os_memset(&vlan_desc
, 0, sizeof(vlan_desc
));
817 vlan_desc
.notempty
= 1;
818 vlan_desc
.untagged
= sta
->sae
->tmp
->vlan_id
;
819 if (!hostapd_vlan_valid(hapd
->conf
->vlan
, &vlan_desc
)) {
821 "Invalid VLAN ID %d in sae_password",
822 sta
->sae
->tmp
->vlan_id
);
826 if (ap_sta_set_vlan(hapd
, sta
, &vlan_desc
) < 0 ||
827 ap_sta_bind_vlan(hapd
, sta
) < 0) {
829 "Failed to assign VLAN ID %d from sae_password to "
830 MACSTR
, sta
->sae
->tmp
->vlan_id
,
835 #endif /* CONFIG_NO_VLAN */
837 sta
->flags
|= WLAN_STA_AUTH
;
838 sta
->auth_alg
= WLAN_AUTH_SAE
;
839 mlme_authenticate_indication(hapd
, sta
);
840 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
841 sae_set_state(sta
, SAE_ACCEPTED
, "Accept Confirm");
842 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
843 sta
->sae
->pmk
, sta
->sae
->pmkid
);
844 sae_sme_send_external_auth_status(hapd
, sta
, WLAN_STATUS_SUCCESS
);
848 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
849 const u8
*bssid
, u16 auth_transaction
, u16 status_code
,
850 int allow_reuse
, int *sta_removed
)
856 if (auth_transaction
!= 1 && auth_transaction
!= 2)
857 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
859 wpa_printf(MSG_DEBUG
, "SAE: Peer " MACSTR
" state=%s auth_trans=%u",
860 MAC2STR(sta
->addr
), sae_state_txt(sta
->sae
->state
),
862 switch (sta
->sae
->state
) {
864 if (auth_transaction
== 1) {
866 sta
->sae
->tmp
->h2e
= status_code
==
867 WLAN_STATUS_SAE_HASH_TO_ELEMENT
;
868 ret
= auth_sae_send_commit(hapd
, sta
, bssid
,
869 !allow_reuse
, status_code
);
872 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
874 if (sae_process_commit(sta
->sae
) < 0)
875 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
878 * In mesh case, both Commit and Confirm are sent
879 * immediately. In infrastructure BSS, by default, only
880 * a single Authentication frame (Commit) is expected
881 * from the AP here and the second one (Confirm) will
882 * be sent once the STA has sent its second
883 * Authentication frame (Confirm). This behavior can be
884 * overridden with explicit configuration so that the
885 * infrastructure BSS case sends both frames together.
887 if ((hapd
->conf
->mesh
& MESH_ENABLED
) ||
888 hapd
->conf
->sae_confirm_immediate
) {
890 * Send both Commit and Confirm immediately
891 * based on SAE finite state machine
892 * Nothing -> Confirm transition.
894 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
897 sae_set_state(sta
, SAE_CONFIRMED
,
898 "Sent Confirm (mesh)");
901 * For infrastructure BSS, send only the Commit
902 * message now to get alternating sequence of
903 * Authentication frames between the AP and STA.
904 * Confirm will be sent in
905 * Committed -> Confirmed/Accepted transition
906 * when receiving Confirm from STA.
910 sae_set_retransmit_timer(hapd
, sta
);
912 hostapd_logger(hapd
, sta
->addr
,
913 HOSTAPD_MODULE_IEEE80211
,
915 "SAE confirm before commit");
919 sae_clear_retransmit_timer(hapd
, sta
);
920 if (auth_transaction
== 1) {
921 if (sae_process_commit(sta
->sae
) < 0)
922 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
924 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
927 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
929 sae_set_retransmit_timer(hapd
, sta
);
930 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
932 * In mesh case, follow SAE finite state machine and
933 * send Commit now, if sync count allows.
935 if (sae_check_big_sync(hapd
, sta
))
936 return WLAN_STATUS_SUCCESS
;
939 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 0,
944 sae_set_retransmit_timer(hapd
, sta
);
947 * For instructure BSS, send the postponed Confirm from
948 * Nothing -> Confirmed transition that was reduced to
949 * Nothing -> Committed above.
951 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
955 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
958 * Since this was triggered on Confirm RX, run another
959 * step to get to Accepted without waiting for
962 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
,
963 WLAN_STATUS_SUCCESS
, 0, sta_removed
);
967 sae_clear_retransmit_timer(hapd
, sta
);
968 if (auth_transaction
== 1) {
969 if (sae_check_big_sync(hapd
, sta
))
970 return WLAN_STATUS_SUCCESS
;
973 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1,
978 if (sae_process_commit(sta
->sae
) < 0)
979 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
981 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
985 sae_set_retransmit_timer(hapd
, sta
);
987 sta
->sae
->send_confirm
= 0xffff;
988 sae_accept_sta(hapd
, sta
);
992 if (auth_transaction
== 1 &&
993 (hapd
->conf
->mesh
& MESH_ENABLED
)) {
994 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
995 ") doing reauthentication",
997 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
998 ap_free_sta(hapd
, sta
);
1000 } else if (auth_transaction
== 1) {
1001 wpa_printf(MSG_DEBUG
, "SAE: Start reauthentication");
1002 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1,
1006 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
1008 if (sae_process_commit(sta
->sae
) < 0)
1009 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1011 sae_set_retransmit_timer(hapd
, sta
);
1013 if (sae_check_big_sync(hapd
, sta
))
1014 return WLAN_STATUS_SUCCESS
;
1017 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
1018 sae_clear_temp_data(sta
->sae
);
1024 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
1026 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1028 return WLAN_STATUS_SUCCESS
;
1032 static void sae_pick_next_group(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1034 struct sae_data
*sae
= sta
->sae
;
1035 int i
, *groups
= hapd
->conf
->sae_groups
;
1036 int default_groups
[] = { 19, 0 };
1038 if (sae
->state
!= SAE_COMMITTED
)
1041 wpa_printf(MSG_DEBUG
, "SAE: Previously selected group: %d", sae
->group
);
1044 groups
= default_groups
;
1045 for (i
= 0; groups
[i
] > 0; i
++) {
1046 if (sae
->group
== groups
[i
])
1050 if (groups
[i
] <= 0) {
1051 wpa_printf(MSG_DEBUG
,
1052 "SAE: Previously selected group not found from the current configuration");
1058 if (groups
[i
] <= 0) {
1059 wpa_printf(MSG_DEBUG
,
1060 "SAE: No alternative group enabled");
1064 if (sae_set_group(sae
, groups
[i
]) < 0)
1069 wpa_printf(MSG_DEBUG
, "SAE: Selected new group: %d", groups
[i
]);
1073 static int sae_status_success(struct hostapd_data
*hapd
, u16 status_code
)
1075 int sae_pwe
= hapd
->conf
->sae_pwe
;
1078 id_in_use
= hostapd_sae_pw_id_in_use(hapd
->conf
);
1081 else if (id_in_use
== 1 && sae_pwe
== 0)
1084 return (sae_pwe
== 0 &&
1085 status_code
== WLAN_STATUS_SUCCESS
) ||
1087 status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
) ||
1089 (status_code
== WLAN_STATUS_SUCCESS
||
1090 status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
));
1094 static int sae_is_group_enabled(struct hostapd_data
*hapd
, int group
)
1096 int *groups
= hapd
->conf
->sae_groups
;
1097 int default_groups
[] = { 19, 0 };
1101 groups
= default_groups
;
1103 for (i
= 0; groups
[i
] > 0; i
++) {
1104 if (groups
[i
] == group
)
1112 static int check_sae_rejected_groups(struct hostapd_data
*hapd
,
1113 const struct wpabuf
*groups
)
1121 pos
= wpabuf_head(groups
);
1122 count
= wpabuf_len(groups
) / 2;
1123 for (i
= 0; i
< count
; i
++) {
1127 group
= WPA_GET_LE16(pos
);
1129 enabled
= sae_is_group_enabled(hapd
, group
);
1130 wpa_printf(MSG_DEBUG
, "SAE: Rejected group %u is %s",
1131 group
, enabled
? "enabled" : "disabled");
1140 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1141 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1142 u16 auth_transaction
, u16 status_code
)
1144 int resp
= WLAN_STATUS_SUCCESS
;
1145 struct wpabuf
*data
= NULL
;
1146 int *groups
= hapd
->conf
->sae_groups
;
1147 int default_groups
[] = { 19, 0 };
1148 const u8
*pos
, *end
;
1149 int sta_removed
= 0;
1152 groups
= default_groups
;
1154 #ifdef CONFIG_TESTING_OPTIONS
1155 if (hapd
->conf
->sae_reflection_attack
&& auth_transaction
== 1) {
1156 wpa_printf(MSG_DEBUG
, "SAE: TESTING - reflection attack");
1157 pos
= mgmt
->u
.auth
.variable
;
1158 end
= ((const u8
*) mgmt
) + len
;
1159 send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1160 auth_transaction
, resp
, pos
, end
- pos
,
1161 "auth-sae-reflection-attack");
1165 if (hapd
->conf
->sae_commit_override
&& auth_transaction
== 1) {
1166 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
1167 send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1168 auth_transaction
, resp
,
1169 wpabuf_head(hapd
->conf
->sae_commit_override
),
1170 wpabuf_len(hapd
->conf
->sae_commit_override
),
1171 "sae-commit-override");
1174 #endif /* CONFIG_TESTING_OPTIONS */
1176 if (auth_transaction
!= 1 ||
1177 !sae_status_success(hapd
, status_code
)) {
1178 wpa_printf(MSG_DEBUG
, "SAE: Unexpected Status Code %u",
1180 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1183 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
1188 sae_set_state(sta
, SAE_NOTHING
, "Init");
1192 if (sta
->mesh_sae_pmksa_caching
) {
1193 wpa_printf(MSG_DEBUG
,
1194 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
1195 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
1196 sta
->mesh_sae_pmksa_caching
= 0;
1199 if (auth_transaction
== 1) {
1200 const u8
*token
= NULL
;
1201 size_t token_len
= 0;
1202 int allow_reuse
= 0;
1204 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1205 HOSTAPD_LEVEL_DEBUG
,
1206 "start SAE authentication (RX commit, status=%u (%s))",
1207 status_code
, status2str(status_code
));
1209 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1210 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
1212 pos
= mgmt
->u
.auth
.variable
;
1213 end
= ((const u8
*) mgmt
) + len
;
1214 if (pos
+ sizeof(le16
) > end
) {
1215 wpa_printf(MSG_ERROR
,
1216 "SAE: Too short anti-clogging token request");
1217 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1220 resp
= sae_group_allowed(sta
->sae
, groups
,
1222 if (resp
!= WLAN_STATUS_SUCCESS
) {
1223 wpa_printf(MSG_ERROR
,
1224 "SAE: Invalid group in anti-clogging token request");
1227 pos
+= sizeof(le16
);
1229 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
1230 sta
->sae
->tmp
->anti_clogging_token
=
1231 wpabuf_alloc_copy(pos
, end
- pos
);
1232 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
1233 wpa_printf(MSG_ERROR
,
1234 "SAE: Failed to alloc for anti-clogging token");
1235 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1240 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
1241 * is 76, a new Commit Message shall be constructed
1242 * with the Anti-Clogging Token from the received
1243 * Authentication frame, and the commit-scalar and
1244 * COMMIT-ELEMENT previously sent.
1246 resp
= auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0,
1248 if (resp
!= WLAN_STATUS_SUCCESS
) {
1249 wpa_printf(MSG_ERROR
,
1250 "SAE: Failed to send commit message");
1253 sae_set_state(sta
, SAE_COMMITTED
,
1254 "Sent Commit (anti-clogging token case in mesh)");
1256 sae_set_retransmit_timer(hapd
, sta
);
1260 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1262 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1264 wpa_printf(MSG_DEBUG
,
1265 "SAE: Peer did not accept our SAE group");
1266 sae_pick_next_group(hapd
, sta
);
1270 if (!sae_status_success(hapd
, status_code
))
1273 if (!(hapd
->conf
->mesh
& MESH_ENABLED
) &&
1274 sta
->sae
->state
== SAE_COMMITTED
) {
1275 /* This is needed in the infrastructure BSS case to
1276 * address a sequence where a STA entry may remain in
1277 * hostapd across two attempts to do SAE authentication
1278 * by the same STA. The second attempt may end up trying
1279 * to use a different group and that would not be
1280 * allowed if we remain in Committed state with the
1281 * previously set parameters. */
1282 pos
= mgmt
->u
.auth
.variable
;
1283 end
= ((const u8
*) mgmt
) + len
;
1284 if (end
- pos
>= (int) sizeof(le16
) &&
1285 sae_group_allowed(sta
->sae
, groups
,
1286 WPA_GET_LE16(pos
)) ==
1287 WLAN_STATUS_SUCCESS
) {
1288 /* Do not waste resources deriving the same PWE
1289 * again since the same group is reused. */
1290 sae_set_state(sta
, SAE_NOTHING
,
1291 "Allow previous PWE to be reused");
1294 sae_set_state(sta
, SAE_NOTHING
,
1295 "Clear existing state to allow restart");
1296 sae_clear_data(sta
->sae
);
1300 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
1301 ((const u8
*) mgmt
) + len
-
1302 mgmt
->u
.auth
.variable
, &token
,
1303 &token_len
, groups
, status_code
==
1304 WLAN_STATUS_SAE_HASH_TO_ELEMENT
);
1305 if (resp
== SAE_SILENTLY_DISCARD
) {
1306 wpa_printf(MSG_DEBUG
,
1307 "SAE: Drop commit message from " MACSTR
" due to reflection attack",
1308 MAC2STR(sta
->addr
));
1312 if (resp
== WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
) {
1313 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
1314 WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER
1315 MACSTR
, MAC2STR(sta
->addr
));
1316 sae_clear_retransmit_timer(hapd
, sta
);
1317 sae_set_state(sta
, SAE_NOTHING
,
1318 "Unknown Password Identifier");
1322 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
1324 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
1325 "incorrect token from " MACSTR
,
1326 MAC2STR(sta
->addr
));
1327 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1331 if (resp
!= WLAN_STATUS_SUCCESS
)
1334 if (sta
->sae
->tmp
&&
1335 check_sae_rejected_groups(
1336 hapd
, sta
->sae
->tmp
->peer_rejected_groups
)) {
1337 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1341 if (!token
&& use_sae_anti_clogging(hapd
) && !allow_reuse
) {
1344 wpa_printf(MSG_DEBUG
,
1345 "SAE: Request anti-clogging token from "
1346 MACSTR
, MAC2STR(sta
->addr
));
1348 h2e
= sta
->sae
->tmp
->h2e
;
1349 if (status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
)
1351 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
1353 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
1354 if (hapd
->conf
->mesh
& MESH_ENABLED
)
1355 sae_set_state(sta
, SAE_NOTHING
,
1356 "Request anti-clogging token case in mesh");
1360 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1361 status_code
, allow_reuse
, &sta_removed
);
1362 } else if (auth_transaction
== 2) {
1363 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1364 HOSTAPD_LEVEL_DEBUG
,
1365 "SAE authentication (RX confirm, status=%u (%s))",
1366 status_code
, status2str(status_code
));
1367 if (status_code
!= WLAN_STATUS_SUCCESS
)
1369 if (sta
->sae
->state
>= SAE_CONFIRMED
||
1370 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
1373 u16 peer_send_confirm
;
1375 var
= mgmt
->u
.auth
.variable
;
1376 var_len
= ((u8
*) mgmt
) + len
- mgmt
->u
.auth
.variable
;
1378 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1382 peer_send_confirm
= WPA_GET_LE16(var
);
1384 if (sta
->sae
->state
== SAE_ACCEPTED
&&
1385 (peer_send_confirm
<= sta
->sae
->rc
||
1386 peer_send_confirm
== 0xffff)) {
1387 wpa_printf(MSG_DEBUG
,
1388 "SAE: Silently ignore unexpected Confirm from peer "
1390 " (peer-send-confirm=%u Rc=%u)",
1392 peer_send_confirm
, sta
->sae
->rc
);
1396 if (sae_check_confirm(sta
->sae
, var
, var_len
) < 0) {
1397 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1400 sta
->sae
->rc
= peer_send_confirm
;
1402 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1403 status_code
, 0, &sta_removed
);
1405 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1406 HOSTAPD_LEVEL_DEBUG
,
1407 "unexpected SAE authentication transaction %u (status=%u (%s))",
1408 auth_transaction
, status_code
,
1409 status2str(status_code
));
1410 if (status_code
!= WLAN_STATUS_SUCCESS
)
1412 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1416 if (!sta_removed
&& resp
!= WLAN_STATUS_SUCCESS
) {
1417 pos
= mgmt
->u
.auth
.variable
;
1418 end
= ((const u8
*) mgmt
) + len
;
1420 /* Copy the Finite Cyclic Group field from the request if we
1421 * rejected it as unsupported group. */
1422 if (resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1423 !data
&& end
- pos
>= 2)
1424 data
= wpabuf_alloc_copy(pos
, 2);
1426 sae_sme_send_external_auth_status(hapd
, sta
, resp
);
1427 send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1428 auth_transaction
, resp
,
1429 data
? wpabuf_head(data
) : (u8
*) "",
1430 data
? wpabuf_len(data
) : 0, "auth-sae");
1434 if (!sta_removed
&& sta
->added_unassoc
&&
1435 (resp
!= WLAN_STATUS_SUCCESS
||
1436 status_code
!= WLAN_STATUS_SUCCESS
)) {
1437 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1438 sta
->added_unassoc
= 0;
1445 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1446 * @hapd: BSS data for the device initiating the authentication
1447 * @sta: the peer to which commit authentication frame is sent
1449 * This function implements Init event handling (IEEE Std 802.11-2012,
1450 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1451 * sta->sae structure should be initialized appropriately via a call to
1452 * sae_prepare_commit().
1454 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1458 if (!sta
->sae
|| !sta
->sae
->tmp
)
1461 if (sta
->sae
->state
!= SAE_NOTHING
)
1464 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0, -1);
1468 sae_set_state(sta
, SAE_COMMITTED
, "Init and sent commit");
1470 sae_set_retransmit_timer(hapd
, sta
);
1476 void auth_sae_process_commit(void *eloop_ctx
, void *user_ctx
)
1478 struct hostapd_data
*hapd
= eloop_ctx
;
1479 struct hostapd_sae_commit_queue
*q
;
1480 unsigned int queue_len
;
1482 q
= dl_list_first(&hapd
->sae_commit_queue
,
1483 struct hostapd_sae_commit_queue
, list
);
1486 wpa_printf(MSG_DEBUG
,
1487 "SAE: Process next available message from queue");
1488 dl_list_del(&q
->list
);
1489 handle_auth(hapd
, (const struct ieee80211_mgmt
*) q
->msg
, q
->len
,
1493 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1495 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1496 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1501 static void auth_sae_queue(struct hostapd_data
*hapd
,
1502 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1505 struct hostapd_sae_commit_queue
*q
, *q2
;
1506 unsigned int queue_len
;
1507 const struct ieee80211_mgmt
*mgmt2
;
1509 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1510 if (queue_len
>= 15) {
1511 wpa_printf(MSG_DEBUG
,
1512 "SAE: No more room in message queue - drop the new frame from "
1513 MACSTR
, MAC2STR(mgmt
->sa
));
1517 wpa_printf(MSG_DEBUG
, "SAE: Queue Authentication message from "
1518 MACSTR
" for processing (queue_len %u)", MAC2STR(mgmt
->sa
),
1520 q
= os_zalloc(sizeof(*q
) + len
);
1525 os_memcpy(q
->msg
, mgmt
, len
);
1527 /* Check whether there is already a queued Authentication frame from the
1528 * same station with the same transaction number and if so, replace that
1529 * queue entry with the new one. This avoids issues with a peer that
1530 * sends multiple times (e.g., due to frequent SAE retries). There is no
1531 * point in us trying to process the old attempts after a new one has
1532 * obsoleted them. */
1533 dl_list_for_each(q2
, &hapd
->sae_commit_queue
,
1534 struct hostapd_sae_commit_queue
, list
) {
1535 mgmt2
= (const struct ieee80211_mgmt
*) q2
->msg
;
1536 if (os_memcmp(mgmt
->sa
, mgmt2
->sa
, ETH_ALEN
) == 0 &&
1537 mgmt
->u
.auth
.auth_transaction
==
1538 mgmt2
->u
.auth
.auth_transaction
) {
1539 wpa_printf(MSG_DEBUG
,
1540 "SAE: Replace queued message from same STA with same transaction number");
1541 dl_list_add(&q2
->list
, &q
->list
);
1542 dl_list_del(&q2
->list
);
1548 /* No pending identical entry, so add to the end of the queue */
1549 dl_list_add_tail(&hapd
->sae_commit_queue
, &q
->list
);
1552 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1554 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1559 static int auth_sae_queued_addr(struct hostapd_data
*hapd
, const u8
*addr
)
1561 struct hostapd_sae_commit_queue
*q
;
1562 const struct ieee80211_mgmt
*mgmt
;
1564 dl_list_for_each(q
, &hapd
->sae_commit_queue
,
1565 struct hostapd_sae_commit_queue
, list
) {
1566 mgmt
= (const struct ieee80211_mgmt
*) q
->msg
;
1567 if (os_memcmp(addr
, mgmt
->sa
, ETH_ALEN
) == 0)
1574 #endif /* CONFIG_SAE */
1577 static u16
wpa_res_to_status_code(int res
)
1579 if (res
== WPA_INVALID_GROUP
)
1580 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1581 if (res
== WPA_INVALID_PAIRWISE
)
1582 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1583 if (res
== WPA_INVALID_AKMP
)
1584 return WLAN_STATUS_AKMP_NOT_VALID
;
1585 if (res
== WPA_ALLOC_FAIL
)
1586 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1587 if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1588 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1589 if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1590 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
1591 if (res
== WPA_INVALID_MDIE
)
1592 return WLAN_STATUS_INVALID_MDIE
;
1593 if (res
== WPA_INVALID_PMKID
)
1594 return WLAN_STATUS_INVALID_PMKID
;
1595 if (res
!= WPA_IE_OK
)
1596 return WLAN_STATUS_INVALID_IE
;
1597 return WLAN_STATUS_SUCCESS
;
1603 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1604 struct sta_info
*sta
, u16 resp
,
1605 struct wpabuf
*data
, int pub
);
1607 void handle_auth_fils(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1608 const u8
*pos
, size_t len
, u16 auth_alg
,
1609 u16 auth_transaction
, u16 status_code
,
1610 void (*cb
)(struct hostapd_data
*hapd
,
1611 struct sta_info
*sta
, u16 resp
,
1612 struct wpabuf
*data
, int pub
))
1614 u16 resp
= WLAN_STATUS_SUCCESS
;
1616 struct ieee802_11_elems elems
;
1618 struct wpa_ie_data rsn
;
1619 struct rsn_pmksa_cache_entry
*pmksa
= NULL
;
1621 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
1626 wpa_hexdump(MSG_DEBUG
, "FILS: Authentication frame fields",
1630 #ifdef CONFIG_FILS_SK_PFS
1631 if (auth_alg
== WLAN_AUTH_FILS_SK_PFS
) {
1636 /* Using FILS PFS */
1638 /* Finite Cyclic Group */
1639 if (end
- pos
< 2) {
1640 wpa_printf(MSG_DEBUG
,
1641 "FILS: No room for Finite Cyclic Group");
1642 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1645 group
= WPA_GET_LE16(pos
);
1647 if (group
!= hapd
->conf
->fils_dh_group
) {
1648 wpa_printf(MSG_DEBUG
,
1649 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1650 group
, hapd
->conf
->fils_dh_group
);
1651 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1655 crypto_ecdh_deinit(sta
->fils_ecdh
);
1656 sta
->fils_ecdh
= crypto_ecdh_init(group
);
1657 if (!sta
->fils_ecdh
) {
1658 wpa_printf(MSG_INFO
,
1659 "FILS: Could not initialize ECDH with group %d",
1661 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1665 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1667 wpa_printf(MSG_DEBUG
,
1668 "FILS: Failed to derive ECDH public key");
1669 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1672 elem_len
= wpabuf_len(pub
);
1676 if ((size_t) (end
- pos
) < elem_len
) {
1677 wpa_printf(MSG_DEBUG
, "FILS: No room for Element");
1678 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1682 wpabuf_free(sta
->fils_g_sta
);
1683 sta
->fils_g_sta
= wpabuf_alloc_copy(pos
, elem_len
);
1684 wpabuf_clear_free(sta
->fils_dh_ss
);
1685 sta
->fils_dh_ss
= crypto_ecdh_set_peerkey(sta
->fils_ecdh
, 1,
1687 if (!sta
->fils_dh_ss
) {
1688 wpa_printf(MSG_DEBUG
, "FILS: ECDH operation failed");
1689 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1692 wpa_hexdump_buf_key(MSG_DEBUG
, "FILS: DH_SS", sta
->fils_dh_ss
);
1695 crypto_ecdh_deinit(sta
->fils_ecdh
);
1696 sta
->fils_ecdh
= NULL
;
1697 wpabuf_clear_free(sta
->fils_dh_ss
);
1698 sta
->fils_dh_ss
= NULL
;
1700 #endif /* CONFIG_FILS_SK_PFS */
1702 wpa_hexdump(MSG_DEBUG
, "FILS: Remaining IEs", pos
, end
- pos
);
1703 if (ieee802_11_parse_elems(pos
, end
- pos
, &elems
, 1) == ParseFailed
) {
1704 wpa_printf(MSG_DEBUG
, "FILS: Could not parse elements");
1705 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1710 wpa_hexdump(MSG_DEBUG
, "FILS: RSN element",
1711 elems
.rsn_ie
, elems
.rsn_ie_len
);
1712 if (!elems
.rsn_ie
||
1713 wpa_parse_wpa_ie_rsn(elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1715 wpa_printf(MSG_DEBUG
, "FILS: No valid RSN element");
1716 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1721 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
1724 wpa_printf(MSG_DEBUG
,
1725 "FILS: Failed to initialize RSN state machine");
1726 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1730 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1732 elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1733 elems
.rsnxe
? elems
.rsnxe
- 2 : NULL
,
1734 elems
.rsnxe
? elems
.rsnxe_len
+ 2 : 0,
1735 elems
.mdie
, elems
.mdie_len
, NULL
, 0);
1736 resp
= wpa_res_to_status_code(res
);
1737 if (resp
!= WLAN_STATUS_SUCCESS
)
1740 if (!elems
.fils_nonce
) {
1741 wpa_printf(MSG_DEBUG
, "FILS: No FILS Nonce field");
1742 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1745 wpa_hexdump(MSG_DEBUG
, "FILS: SNonce", elems
.fils_nonce
,
1747 os_memcpy(sta
->fils_snonce
, elems
.fils_nonce
, FILS_NONCE_LEN
);
1750 if (rsn
.pmkid
&& rsn
.num_pmkid
> 0) {
1754 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID List",
1755 rsn
.pmkid
, rsn
.num_pmkid
* PMKID_LEN
);
1758 num
= rsn
.num_pmkid
;
1760 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID", pmkid
, PMKID_LEN
);
1761 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
,
1765 pmksa
= wpa_auth_pmksa_get_fils_cache_id(hapd
->wpa_auth
,
1774 if (pmksa
&& wpa_auth_sta_key_mgmt(sta
->wpa_sm
) != pmksa
->akmp
) {
1775 wpa_printf(MSG_DEBUG
,
1776 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1777 wpa_auth_sta_key_mgmt(sta
->wpa_sm
), pmksa
->akmp
);
1781 wpa_printf(MSG_DEBUG
, "FILS: Found matching PMKSA cache entry");
1784 if (!elems
.fils_session
) {
1785 wpa_printf(MSG_DEBUG
, "FILS: No FILS Session element");
1786 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1789 wpa_hexdump(MSG_DEBUG
, "FILS: FILS Session", elems
.fils_session
,
1791 os_memcpy(sta
->fils_session
, elems
.fils_session
, FILS_SESSION_LEN
);
1793 /* FILS Wrapped Data */
1794 if (elems
.fils_wrapped_data
) {
1795 wpa_hexdump(MSG_DEBUG
, "FILS: Wrapped Data",
1796 elems
.fils_wrapped_data
,
1797 elems
.fils_wrapped_data_len
);
1799 #ifndef CONFIG_NO_RADIUS
1800 if (!sta
->eapol_sm
) {
1802 ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1804 wpa_printf(MSG_DEBUG
,
1805 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
1806 ieee802_1x_encapsulate_radius(
1807 hapd
, sta
, elems
.fils_wrapped_data
,
1808 elems
.fils_wrapped_data_len
);
1809 sta
->fils_pending_cb
= cb
;
1810 wpa_printf(MSG_DEBUG
,
1811 "FILS: Will send Authentication frame once the response from authentication server is available");
1812 sta
->flags
|= WLAN_STA_PENDING_FILS_ERP
;
1813 /* Calculate pending PMKID here so that we do not need
1814 * to maintain a copy of the EAP-Initiate/Reauth
1816 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1817 elems
.fils_wrapped_data
,
1818 elems
.fils_wrapped_data_len
,
1819 sta
->fils_erp_pmkid
) == 0)
1820 sta
->fils_erp_pmkid_set
= 1;
1822 #else /* CONFIG_NO_RADIUS */
1823 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1825 #endif /* CONFIG_NO_RADIUS */
1831 struct wpabuf
*data
;
1834 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, pmksa
, NULL
,
1837 wpa_printf(MSG_DEBUG
,
1838 "%s: prepare_auth_resp_fils() returned failure",
1842 cb(hapd
, sta
, resp
, data
, pub
);
1847 static struct wpabuf
*
1848 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
1849 struct sta_info
*sta
, u16
*resp
,
1850 struct rsn_pmksa_cache_entry
*pmksa
,
1851 struct wpabuf
*erp_resp
,
1852 const u8
*msk
, size_t msk_len
,
1855 u8 fils_nonce
[FILS_NONCE_LEN
];
1857 struct wpabuf
*data
= NULL
;
1860 const u8
*pmk
= NULL
;
1862 u8 pmk_buf
[PMK_LEN_MAX
];
1863 struct wpabuf
*pub
= NULL
;
1865 if (*resp
!= WLAN_STATUS_SUCCESS
)
1868 ie
= wpa_auth_get_wpa_ie(hapd
->wpa_auth
, &ielen
);
1870 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1875 /* Add PMKID of the selected PMKSA into RSNE */
1876 ie_buf
= os_malloc(ielen
+ 2 + 2 + PMKID_LEN
);
1878 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1882 os_memcpy(ie_buf
, ie
, ielen
);
1883 if (wpa_insert_pmkid(ie_buf
, &ielen
, pmksa
->pmkid
) < 0) {
1884 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1890 if (random_get_bytes(fils_nonce
, FILS_NONCE_LEN
) < 0) {
1891 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1894 wpa_hexdump(MSG_DEBUG
, "RSN: Generated FILS Nonce",
1895 fils_nonce
, FILS_NONCE_LEN
);
1897 #ifdef CONFIG_FILS_SK_PFS
1898 if (sta
->fils_dh_ss
&& sta
->fils_ecdh
) {
1899 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1901 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1905 #endif /* CONFIG_FILS_SK_PFS */
1907 data
= wpabuf_alloc(1000 + ielen
+ (pub
? wpabuf_len(pub
) : 0));
1909 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1914 #ifdef CONFIG_FILS_SK_PFS
1916 /* Finite Cyclic Group */
1917 wpabuf_put_le16(data
, hapd
->conf
->fils_dh_group
);
1920 wpabuf_put_buf(data
, pub
);
1922 #endif /* CONFIG_FILS_SK_PFS */
1925 wpabuf_put_data(data
, ie
, ielen
);
1927 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1929 #ifdef CONFIG_IEEE80211R_AP
1930 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) {
1931 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1933 int use_sha384
= wpa_key_mgmt_sha384(
1934 wpa_auth_sta_key_mgmt(sta
->wpa_sm
));
1936 res
= wpa_auth_write_fte(hapd
->wpa_auth
, use_sha384
,
1937 wpabuf_put(data
, 0),
1938 wpabuf_tailroom(data
));
1940 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1943 wpabuf_put(data
, res
);
1945 #endif /* CONFIG_IEEE80211R_AP */
1948 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1949 wpabuf_put_u8(data
, 1 + FILS_NONCE_LEN
); /* Length */
1950 /* Element ID Extension */
1951 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_NONCE
);
1952 wpabuf_put_data(data
, fils_nonce
, FILS_NONCE_LEN
);
1955 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1956 wpabuf_put_u8(data
, 1 + FILS_SESSION_LEN
); /* Length */
1957 /* Element ID Extension */
1958 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_SESSION
);
1959 wpabuf_put_data(data
, sta
->fils_session
, FILS_SESSION_LEN
);
1961 /* FILS Wrapped Data */
1962 if (!pmksa
&& erp_resp
) {
1963 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1964 wpabuf_put_u8(data
, 1 + wpabuf_len(erp_resp
)); /* Length */
1965 /* Element ID Extension */
1966 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_WRAPPED_DATA
);
1967 wpabuf_put_buf(data
, erp_resp
);
1969 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1970 msk
, msk_len
, sta
->fils_snonce
, fils_nonce
,
1972 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1974 wpabuf_len(sta
->fils_dh_ss
) : 0,
1975 pmk_buf
, &pmk_len
)) {
1976 wpa_printf(MSG_DEBUG
, "FILS: Failed to derive PMK");
1977 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1984 /* Don't use DHss in PTK derivation if PMKSA caching is not
1986 wpabuf_clear_free(sta
->fils_dh_ss
);
1987 sta
->fils_dh_ss
= NULL
;
1989 if (sta
->fils_erp_pmkid_set
) {
1990 /* TODO: get PMKLifetime from WPA parameters */
1991 unsigned int dot11RSNAConfigPMKLifetime
= 43200;
1992 int session_timeout
;
1994 session_timeout
= dot11RSNAConfigPMKLifetime
;
1995 if (sta
->session_timeout_set
) {
1996 struct os_reltime now
, diff
;
1998 os_get_reltime(&now
);
1999 os_reltime_sub(&sta
->session_timeout
, &now
,
2001 session_timeout
= diff
.sec
;
2004 sta
->fils_erp_pmkid_set
= 0;
2005 wpa_auth_add_fils_pmk_pmkid(sta
->wpa_sm
, pmk
, pmk_len
,
2006 sta
->fils_erp_pmkid
);
2007 if (!hapd
->conf
->disable_pmksa_caching
&&
2008 wpa_auth_pmksa_add2(
2009 hapd
->wpa_auth
, sta
->addr
,
2011 sta
->fils_erp_pmkid
,
2013 wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) < 0) {
2014 wpa_printf(MSG_ERROR
,
2015 "FILS: Failed to add PMKSA cache entry based on ERP");
2020 pmk_len
= pmksa
->pmk_len
;
2024 wpa_printf(MSG_DEBUG
, "FILS: No PMK available");
2025 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2031 if (fils_auth_pmk_to_ptk(sta
->wpa_sm
, pmk
, pmk_len
,
2032 sta
->fils_snonce
, fils_nonce
,
2034 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
2036 wpabuf_len(sta
->fils_dh_ss
) : 0,
2037 sta
->fils_g_sta
, pub
) < 0) {
2038 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2046 *is_pub
= pub
!= NULL
;
2049 wpabuf_clear_free(sta
->fils_dh_ss
);
2050 sta
->fils_dh_ss
= NULL
;
2051 #ifdef CONFIG_FILS_SK_PFS
2052 crypto_ecdh_deinit(sta
->fils_ecdh
);
2053 sta
->fils_ecdh
= NULL
;
2054 #endif /* CONFIG_FILS_SK_PFS */
2059 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
2060 struct sta_info
*sta
, u16 resp
,
2061 struct wpabuf
*data
, int pub
)
2066 resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
) ?
2067 WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
2068 send_auth_reply(hapd
, sta
, sta
->addr
, hapd
->own_addr
, auth_alg
, 2, resp
,
2069 data
? wpabuf_head(data
) : (u8
*) "",
2070 data
? wpabuf_len(data
) : 0, "auth-fils-finish");
2073 if (resp
== WLAN_STATUS_SUCCESS
) {
2074 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2075 HOSTAPD_LEVEL_DEBUG
,
2076 "authentication OK (FILS)");
2077 sta
->flags
|= WLAN_STA_AUTH
;
2078 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2079 sta
->auth_alg
= pub
? WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
2080 mlme_authenticate_indication(hapd
, sta
);
2085 void ieee802_11_finish_fils_auth(struct hostapd_data
*hapd
,
2086 struct sta_info
*sta
, int success
,
2087 struct wpabuf
*erp_resp
,
2088 const u8
*msk
, size_t msk_len
)
2090 struct wpabuf
*data
;
2094 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2096 if (!sta
->fils_pending_cb
)
2098 resp
= success
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_UNSPECIFIED_FAILURE
;
2099 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, NULL
, erp_resp
,
2100 msk
, msk_len
, &pub
);
2102 wpa_printf(MSG_DEBUG
,
2103 "%s: prepare_auth_resp_fils() returned failure",
2106 sta
->fils_pending_cb(hapd
, sta
, resp
, data
, pub
);
2109 #endif /* CONFIG_FILS */
2112 static int ieee802_11_allowed_address(struct hostapd_data
*hapd
, const u8
*addr
,
2113 const u8
*msg
, size_t len
,
2114 struct radius_sta
*info
)
2118 res
= hostapd_allowed_address(hapd
, addr
, msg
, len
, info
, 0);
2120 if (res
== HOSTAPD_ACL_REJECT
) {
2121 wpa_printf(MSG_DEBUG
, "Station " MACSTR
2122 " not allowed to authenticate",
2124 return HOSTAPD_ACL_REJECT
;
2127 if (res
== HOSTAPD_ACL_PENDING
) {
2128 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
2129 " waiting for an external authentication",
2131 /* Authentication code will re-send the authentication frame
2132 * after it has received (and cached) information from the
2133 * external source. */
2134 return HOSTAPD_ACL_PENDING
;
2142 ieee802_11_set_radius_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2143 int res
, struct radius_sta
*info
)
2145 u32 session_timeout
= info
->session_timeout
;
2146 u32 acct_interim_interval
= info
->acct_interim_interval
;
2147 struct vlan_description
*vlan_id
= &info
->vlan_id
;
2148 struct hostapd_sta_wpa_psk_short
*psk
= info
->psk
;
2149 char *identity
= info
->identity
;
2150 char *radius_cui
= info
->radius_cui
;
2152 if (vlan_id
->notempty
&&
2153 !hostapd_vlan_valid(hapd
->conf
->vlan
, vlan_id
)) {
2154 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
2156 "Invalid VLAN %d%s received from RADIUS server",
2158 vlan_id
->tagged
[0] ? "+" : "");
2161 if (ap_sta_set_vlan(hapd
, sta
, vlan_id
) < 0)
2164 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
2165 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
2167 hostapd_free_psk_list(sta
->psk
);
2168 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
)
2169 hostapd_copy_psk_list(&sta
->psk
, psk
);
2173 os_free(sta
->identity
);
2175 sta
->identity
= os_strdup(identity
);
2177 sta
->identity
= NULL
;
2179 os_free(sta
->radius_cui
);
2181 sta
->radius_cui
= os_strdup(radius_cui
);
2183 sta
->radius_cui
= NULL
;
2185 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
2186 sta
->acct_interim_interval
= acct_interim_interval
;
2187 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
) {
2188 sta
->session_timeout_set
= 1;
2189 os_get_reltime(&sta
->session_timeout
);
2190 sta
->session_timeout
.sec
+= session_timeout
;
2191 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
2193 sta
->session_timeout_set
= 0;
2194 ap_sta_no_session_timeout(hapd
, sta
);
2201 static void handle_auth(struct hostapd_data
*hapd
,
2202 const struct ieee80211_mgmt
*mgmt
, size_t len
,
2203 int rssi
, int from_queue
)
2205 u16 auth_alg
, auth_transaction
, status_code
;
2206 u16 resp
= WLAN_STATUS_SUCCESS
;
2207 struct sta_info
*sta
= NULL
;
2210 const u8
*challenge
= NULL
;
2211 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
2212 size_t resp_ies_len
= 0;
2214 struct radius_sta rad_info
;
2216 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
2217 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
2218 (unsigned long) len
);
2222 #ifdef CONFIG_TESTING_OPTIONS
2223 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
2224 drand48() < hapd
->iconf
->ignore_auth_probability
) {
2225 wpa_printf(MSG_INFO
,
2226 "TESTING: ignoring auth frame from " MACSTR
,
2230 #endif /* CONFIG_TESTING_OPTIONS */
2232 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
2233 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
2234 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
2235 fc
= le_to_host16(mgmt
->frame_control
);
2236 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
2238 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
2239 2 + WLAN_AUTH_CHALLENGE_LEN
&&
2240 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
2241 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
2242 challenge
= &mgmt
->u
.auth
.variable
[2];
2244 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
2245 "auth_transaction=%d status_code=%d wep=%d%s "
2246 "seq_ctrl=0x%x%s%s",
2247 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
2248 status_code
, !!(fc
& WLAN_FC_ISWEP
),
2249 challenge
? " challenge" : "",
2250 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "",
2251 from_queue
? " (from queue)" : "");
2253 #ifdef CONFIG_NO_RC4
2254 if (auth_alg
== WLAN_AUTH_SHARED_KEY
) {
2255 wpa_printf(MSG_INFO
,
2256 "Unsupported authentication algorithm (%d)",
2258 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2261 #endif /* CONFIG_NO_RC4 */
2263 if (hapd
->tkip_countermeasures
) {
2264 wpa_printf(MSG_DEBUG
,
2265 "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
2266 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2270 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
2271 auth_alg
== WLAN_AUTH_OPEN
) ||
2272 #ifdef CONFIG_IEEE80211R_AP
2273 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
2274 auth_alg
== WLAN_AUTH_FT
) ||
2275 #endif /* CONFIG_IEEE80211R_AP */
2277 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
2278 auth_alg
== WLAN_AUTH_SAE
) ||
2279 #endif /* CONFIG_SAE */
2281 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2282 auth_alg
== WLAN_AUTH_FILS_SK
) ||
2283 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2284 hapd
->conf
->fils_dh_group
&&
2285 auth_alg
== WLAN_AUTH_FILS_SK_PFS
) ||
2286 #endif /* CONFIG_FILS */
2287 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
2288 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
2289 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
2291 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2295 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
2296 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
2297 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
2299 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
2303 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
2304 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
2306 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2310 if (hapd
->conf
->no_auth_if_seen_on
) {
2311 struct hostapd_data
*other
;
2313 other
= sta_track_seen_on(hapd
->iface
, mgmt
->sa
,
2314 hapd
->conf
->no_auth_if_seen_on
);
2318 u8 op_class
, channel
, phytype
;
2320 wpa_printf(MSG_DEBUG
, "%s: Reject authentication from "
2321 MACSTR
" since STA has been seen on %s",
2322 hapd
->conf
->iface
, MAC2STR(mgmt
->sa
),
2323 hapd
->conf
->no_auth_if_seen_on
);
2325 resp
= WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION
;
2327 *pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
2329 os_memcpy(pos
, other
->own_addr
, ETH_ALEN
);
2331 info
= 0; /* TODO: BSSID Information */
2332 WPA_PUT_LE32(pos
, info
);
2334 if (other
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211AD
)
2335 phytype
= 8; /* dmg */
2336 else if (other
->iconf
->ieee80211ac
)
2337 phytype
= 9; /* vht */
2338 else if (other
->iconf
->ieee80211n
)
2339 phytype
= 7; /* ht */
2340 else if (other
->iconf
->hw_mode
==
2341 HOSTAPD_MODE_IEEE80211A
)
2342 phytype
= 4; /* ofdm */
2343 else if (other
->iconf
->hw_mode
==
2344 HOSTAPD_MODE_IEEE80211G
)
2345 phytype
= 6; /* erp */
2347 phytype
= 5; /* hrdsss */
2348 if (ieee80211_freq_to_channel_ext(
2349 hostapd_hw_get_freq(other
,
2350 other
->iconf
->channel
),
2351 other
->iconf
->secondary_channel
,
2352 other
->iconf
->ieee80211ac
,
2353 &op_class
, &channel
) == NUM_HOSTAPD_MODES
) {
2355 channel
= other
->iconf
->channel
;
2360 resp_ies_len
= pos
- &resp_ies
[0];
2365 res
= ieee802_11_allowed_address(hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
,
2367 if (res
== HOSTAPD_ACL_REJECT
) {
2368 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
2369 "Ignore Authentication frame from " MACSTR
2370 " due to ACL reject", MAC2STR(mgmt
->sa
));
2371 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2374 if (res
== HOSTAPD_ACL_PENDING
)
2378 if (auth_alg
== WLAN_AUTH_SAE
&& !from_queue
&&
2379 (auth_transaction
== 1 ||
2380 (auth_transaction
== 2 && auth_sae_queued_addr(hapd
, mgmt
->sa
)))) {
2381 /* Handle SAE Authentication commit message through a queue to
2382 * provide more control for postponing the needed heavy
2383 * processing under a possible DoS attack scenario. In addition,
2384 * queue SAE Authentication confirm message if there happens to
2385 * be a queued commit message from the same peer. This is needed
2386 * to avoid reordering Authentication frames within the same
2388 auth_sae_queue(hapd
, mgmt
, len
, rssi
);
2391 #endif /* CONFIG_SAE */
2393 sta
= ap_get_sta(hapd
, mgmt
->sa
);
2395 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2396 sta
->ft_over_ds
= 0;
2397 if ((fc
& WLAN_FC_RETRY
) &&
2398 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
2399 sta
->last_seq_ctrl
== seq_ctrl
&&
2400 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
2401 hostapd_logger(hapd
, sta
->addr
,
2402 HOSTAPD_MODULE_IEEE80211
,
2403 HOSTAPD_LEVEL_DEBUG
,
2404 "Drop repeated authentication frame seq_ctrl=0x%x",
2409 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
2410 sta
->plink_state
== PLINK_BLOCKED
) {
2411 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2412 " is blocked - drop Authentication frame",
2416 #endif /* CONFIG_MESH */
2419 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
2420 /* if the mesh peer is not available, we don't do auth.
2422 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2423 " not yet known - drop Authentication frame",
2426 * Save a copy of the frame so that it can be processed
2427 * if a new peer entry is added shortly after this.
2429 wpabuf_free(hapd
->mesh_pending_auth
);
2430 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
2431 os_get_reltime(&hapd
->mesh_pending_auth_time
);
2434 #endif /* CONFIG_MESH */
2436 sta
= ap_sta_add(hapd
, mgmt
->sa
);
2438 wpa_printf(MSG_DEBUG
, "ap_sta_add() failed");
2439 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2443 sta
->last_seq_ctrl
= seq_ctrl
;
2444 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
2446 sta
->auth_rssi
= rssi
;
2447 #endif /* CONFIG_MBO */
2449 res
= ieee802_11_set_radius_info(hapd
, sta
, res
, &rad_info
);
2451 wpa_printf(MSG_DEBUG
, "ieee802_11_set_radius_info() failed");
2452 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2456 sta
->flags
&= ~WLAN_STA_PREAUTH
;
2457 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
2460 * If the driver supports full AP client state, add a station to the
2461 * driver before sending authentication reply to make sure the driver
2462 * has resources, and not to go through the entire authentication and
2463 * association handshake, and fail it at the end.
2465 * If this is not the first transaction, in a multi-step authentication
2466 * algorithm, the station already exists in the driver
2467 * (sta->added_unassoc = 1) so skip it.
2469 * In mesh mode, the station was already added to the driver when the
2470 * NEW_PEER_CANDIDATE event is received.
2472 * If PMF was negotiated for the existing association, skip this to
2473 * avoid dropping the STA entry and the associated keys. This is needed
2474 * to allow the original connection work until the attempt can complete
2475 * (re)association, so that unprotected Authentication frame cannot be
2476 * used to bypass PMF protection.
2478 if (FULL_AP_CLIENT_STATE_SUPP(hapd
->iface
->drv_flags
) &&
2479 (!(sta
->flags
& WLAN_STA_MFP
) || !ap_sta_is_authorized(sta
)) &&
2480 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
2481 !(sta
->added_unassoc
)) {
2483 * If a station that is already associated to the AP, is trying
2484 * to authenticate again, remove the STA entry, in order to make
2485 * sure the STA PS state gets cleared and configuration gets
2486 * updated. To handle this, station's added_unassoc flag is
2487 * cleared once the station has completed association.
2489 ap_sta_set_authorized(hapd
, sta
, 0);
2490 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2491 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_AUTH
|
2492 WLAN_STA_AUTHORIZED
);
2494 if (hostapd_sta_add(hapd
, sta
->addr
, 0, 0,
2495 sta
->supported_rates
,
2496 sta
->supported_rates_len
,
2497 0, NULL
, NULL
, NULL
, 0,
2498 sta
->flags
, 0, 0, 0, 0)) {
2499 hostapd_logger(hapd
, sta
->addr
,
2500 HOSTAPD_MODULE_IEEE80211
,
2501 HOSTAPD_LEVEL_NOTICE
,
2502 "Could not add STA to kernel driver");
2503 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2507 sta
->added_unassoc
= 1;
2511 case WLAN_AUTH_OPEN
:
2512 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2513 HOSTAPD_LEVEL_DEBUG
,
2514 "authentication OK (open system)");
2515 sta
->flags
|= WLAN_STA_AUTH
;
2516 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2517 sta
->auth_alg
= WLAN_AUTH_OPEN
;
2518 mlme_authenticate_indication(hapd
, sta
);
2520 #ifndef CONFIG_NO_RC4
2521 case WLAN_AUTH_SHARED_KEY
:
2522 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
2523 fc
& WLAN_FC_ISWEP
);
2525 wpa_printf(MSG_DEBUG
,
2526 "auth_shared_key() failed: status=%d", resp
);
2527 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
2528 mlme_authenticate_indication(hapd
, sta
);
2529 if (sta
->challenge
&& auth_transaction
== 1) {
2530 resp_ies
[0] = WLAN_EID_CHALLENGE
;
2531 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
2532 os_memcpy(resp_ies
+ 2, sta
->challenge
,
2533 WLAN_AUTH_CHALLENGE_LEN
);
2534 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
2537 #endif /* CONFIG_NO_RC4 */
2538 #ifdef CONFIG_IEEE80211R_AP
2540 sta
->auth_alg
= WLAN_AUTH_FT
;
2541 if (sta
->wpa_sm
== NULL
)
2542 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2544 if (sta
->wpa_sm
== NULL
) {
2545 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
2547 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2550 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
2551 auth_transaction
, mgmt
->u
.auth
.variable
,
2552 len
- IEEE80211_HDRLEN
-
2553 sizeof(mgmt
->u
.auth
),
2554 handle_auth_ft_finish
, hapd
);
2555 /* handle_auth_ft_finish() callback will complete auth. */
2557 #endif /* CONFIG_IEEE80211R_AP */
2561 if (status_code
== WLAN_STATUS_SUCCESS
&&
2562 hapd
->conf
->mesh
& MESH_ENABLED
) {
2563 if (sta
->wpa_sm
== NULL
)
2565 wpa_auth_sta_init(hapd
->wpa_auth
,
2567 if (sta
->wpa_sm
== NULL
) {
2568 wpa_printf(MSG_DEBUG
,
2569 "SAE: Failed to initialize WPA state machine");
2570 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2574 #endif /* CONFIG_MESH */
2575 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
2578 #endif /* CONFIG_SAE */
2580 case WLAN_AUTH_FILS_SK
:
2581 case WLAN_AUTH_FILS_SK_PFS
:
2582 handle_auth_fils(hapd
, sta
, mgmt
->u
.auth
.variable
,
2583 len
- IEEE80211_HDRLEN
- sizeof(mgmt
->u
.auth
),
2584 auth_alg
, auth_transaction
, status_code
,
2585 handle_auth_fils_finish
);
2587 #endif /* CONFIG_FILS */
2591 reply_res
= send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
2592 auth_transaction
+ 1, resp
, resp_ies
,
2593 resp_ies_len
, "handle-auth");
2595 if (sta
&& sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
2596 reply_res
!= WLAN_STATUS_SUCCESS
)) {
2597 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2598 sta
->added_unassoc
= 0;
2603 int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2607 /* get a unique AID */
2609 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
2616 for (i
= 0; i
< AID_WORDS
; i
++) {
2617 if (hapd
->sta_aid
[i
] == (u32
) -1)
2619 for (j
= 0; j
< 32; j
++) {
2620 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
2628 aid
= i
* 32 + j
+ 1;
2633 hapd
->sta_aid
[i
] |= BIT(j
);
2634 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
2639 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2640 const u8
*ssid_ie
, size_t ssid_ie_len
)
2642 if (ssid_ie
== NULL
)
2643 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2645 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
2646 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
2647 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2649 "Station tried to associate with unknown SSID "
2650 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
2651 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2654 return WLAN_STATUS_SUCCESS
;
2658 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2659 const u8
*wmm_ie
, size_t wmm_ie_len
)
2661 sta
->flags
&= ~WLAN_STA_WMM
;
2663 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
2664 struct wmm_information_element
*wmm
;
2666 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
2667 hostapd_logger(hapd
, sta
->addr
,
2669 HOSTAPD_LEVEL_DEBUG
,
2670 "invalid WMM element in association "
2672 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2675 sta
->flags
|= WLAN_STA_WMM
;
2676 wmm
= (struct wmm_information_element
*) wmm_ie
;
2677 sta
->qosinfo
= wmm
->qos_info
;
2679 return WLAN_STATUS_SUCCESS
;
2682 static u16
check_multi_ap(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2683 const u8
*multi_ap_ie
, size_t multi_ap_len
)
2685 u8 multi_ap_value
= 0;
2687 sta
->flags
&= ~WLAN_STA_MULTI_AP
;
2689 if (!hapd
->conf
->multi_ap
)
2690 return WLAN_STATUS_SUCCESS
;
2693 const u8
*multi_ap_subelem
;
2695 multi_ap_subelem
= get_ie(multi_ap_ie
+ 4,
2697 MULTI_AP_SUB_ELEM_TYPE
);
2698 if (multi_ap_subelem
&& multi_ap_subelem
[1] == 1) {
2699 multi_ap_value
= multi_ap_subelem
[2];
2701 hostapd_logger(hapd
, sta
->addr
,
2702 HOSTAPD_MODULE_IEEE80211
,
2704 "Multi-AP IE has missing or invalid Multi-AP subelement");
2705 return WLAN_STATUS_INVALID_IE
;
2709 if (multi_ap_value
&& multi_ap_value
!= MULTI_AP_BACKHAUL_STA
)
2710 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2712 "Multi-AP IE with unexpected value 0x%02x",
2715 if (!(multi_ap_value
& MULTI_AP_BACKHAUL_STA
)) {
2716 if (hapd
->conf
->multi_ap
& FRONTHAUL_BSS
)
2717 return WLAN_STATUS_SUCCESS
;
2719 hostapd_logger(hapd
, sta
->addr
,
2720 HOSTAPD_MODULE_IEEE80211
,
2722 "Non-Multi-AP STA tries to associate with backhaul-only BSS");
2723 return WLAN_STATUS_ASSOC_DENIED_UNSPEC
;
2726 if (!(hapd
->conf
->multi_ap
& BACKHAUL_BSS
))
2727 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2728 HOSTAPD_LEVEL_DEBUG
,
2729 "Backhaul STA tries to associate with fronthaul-only BSS");
2731 sta
->flags
|= WLAN_STA_MULTI_AP
;
2732 return WLAN_STATUS_SUCCESS
;
2736 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2737 struct ieee802_11_elems
*elems
)
2739 /* Supported rates not used in IEEE 802.11ad/DMG */
2740 if (hapd
->iface
->current_mode
&&
2741 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
)
2742 return WLAN_STATUS_SUCCESS
;
2744 if (!elems
->supp_rates
) {
2745 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2746 HOSTAPD_LEVEL_DEBUG
,
2747 "No supported rates element in AssocReq");
2748 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2751 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
2752 sizeof(sta
->supported_rates
)) {
2753 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2754 HOSTAPD_LEVEL_DEBUG
,
2755 "Invalid supported rates element length %d+%d",
2756 elems
->supp_rates_len
,
2757 elems
->ext_supp_rates_len
);
2758 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2761 sta
->supported_rates_len
= merge_byte_arrays(
2762 sta
->supported_rates
, sizeof(sta
->supported_rates
),
2763 elems
->supp_rates
, elems
->supp_rates_len
,
2764 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
2766 return WLAN_STATUS_SUCCESS
;
2770 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2771 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
2773 #ifdef CONFIG_INTERWORKING
2774 /* check for QoS Map support */
2775 if (ext_capab_ie_len
>= 5) {
2776 if (ext_capab_ie
[4] & 0x01)
2777 sta
->qos_map_enabled
= 1;
2779 #endif /* CONFIG_INTERWORKING */
2781 if (ext_capab_ie_len
> 0) {
2782 sta
->ecsa_supported
= !!(ext_capab_ie
[0] & BIT(2));
2783 os_free(sta
->ext_capability
);
2784 sta
->ext_capability
= os_malloc(1 + ext_capab_ie_len
);
2785 if (sta
->ext_capability
) {
2786 sta
->ext_capability
[0] = ext_capab_ie_len
;
2787 os_memcpy(sta
->ext_capability
+ 1, ext_capab_ie
,
2792 return WLAN_STATUS_SUCCESS
;
2798 static int owe_group_supported(struct hostapd_data
*hapd
, u16 group
)
2801 int *groups
= hapd
->conf
->owe_groups
;
2803 if (group
!= 19 && group
!= 20 && group
!= 21)
2809 for (i
= 0; groups
[i
] > 0; i
++) {
2810 if (groups
[i
] == group
)
2818 static u16
owe_process_assoc_req(struct hostapd_data
*hapd
,
2819 struct sta_info
*sta
, const u8
*owe_dh
,
2822 struct wpabuf
*secret
, *pub
, *hkey
;
2824 u8 prk
[SHA512_MAC_LEN
], pmkid
[SHA512_MAC_LEN
];
2825 const char *info
= "OWE Key Generation";
2829 size_t hash_len
, prime_len
;
2831 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
2832 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
2833 return WLAN_STATUS_SUCCESS
;
2836 group
= WPA_GET_LE16(owe_dh
);
2837 if (!owe_group_supported(hapd
, group
)) {
2838 wpa_printf(MSG_DEBUG
, "OWE: Unsupported DH group %u", group
);
2839 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2843 else if (group
== 20)
2845 else if (group
== 21)
2848 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2850 crypto_ecdh_deinit(sta
->owe_ecdh
);
2851 sta
->owe_ecdh
= crypto_ecdh_init(group
);
2853 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2854 sta
->owe_group
= group
;
2856 secret
= crypto_ecdh_set_peerkey(sta
->owe_ecdh
, 0, owe_dh
+ 2,
2858 secret
= wpabuf_zeropad(secret
, prime_len
);
2860 wpa_printf(MSG_DEBUG
, "OWE: Invalid peer DH public key");
2861 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2863 wpa_hexdump_buf_key(MSG_DEBUG
, "OWE: DH shared secret", secret
);
2865 /* prk = HKDF-extract(C | A | group, z) */
2867 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2869 wpabuf_clear_free(secret
);
2870 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2873 /* PMKID = Truncate-128(Hash(C | A)) */
2874 addr
[0] = owe_dh
+ 2;
2875 len
[0] = owe_dh_len
- 2;
2876 addr
[1] = wpabuf_head(pub
);
2877 len
[1] = wpabuf_len(pub
);
2879 res
= sha256_vector(2, addr
, len
, pmkid
);
2880 hash_len
= SHA256_MAC_LEN
;
2881 } else if (group
== 20) {
2882 res
= sha384_vector(2, addr
, len
, pmkid
);
2883 hash_len
= SHA384_MAC_LEN
;
2884 } else if (group
== 21) {
2885 res
= sha512_vector(2, addr
, len
, pmkid
);
2886 hash_len
= SHA512_MAC_LEN
;
2889 wpabuf_clear_free(secret
);
2890 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2892 pub
= wpabuf_zeropad(pub
, prime_len
);
2893 if (res
< 0 || !pub
) {
2895 wpabuf_clear_free(secret
);
2896 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2899 hkey
= wpabuf_alloc(owe_dh_len
- 2 + wpabuf_len(pub
) + 2);
2902 wpabuf_clear_free(secret
);
2903 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2906 wpabuf_put_data(hkey
, owe_dh
+ 2, owe_dh_len
- 2); /* C */
2907 wpabuf_put_buf(hkey
, pub
); /* A */
2909 wpabuf_put_le16(hkey
, group
); /* group */
2911 res
= hmac_sha256(wpabuf_head(hkey
), wpabuf_len(hkey
),
2912 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2913 else if (group
== 20)
2914 res
= hmac_sha384(wpabuf_head(hkey
), wpabuf_len(hkey
),
2915 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2916 else if (group
== 21)
2917 res
= hmac_sha512(wpabuf_head(hkey
), wpabuf_len(hkey
),
2918 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2919 wpabuf_clear_free(hkey
);
2920 wpabuf_clear_free(secret
);
2922 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2924 wpa_hexdump_key(MSG_DEBUG
, "OWE: prk", prk
, hash_len
);
2926 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2928 os_free(sta
->owe_pmk
);
2929 sta
->owe_pmk
= os_malloc(hash_len
);
2930 if (!sta
->owe_pmk
) {
2931 os_memset(prk
, 0, SHA512_MAC_LEN
);
2932 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2936 res
= hmac_sha256_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2937 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2938 else if (group
== 20)
2939 res
= hmac_sha384_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2940 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2941 else if (group
== 21)
2942 res
= hmac_sha512_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2943 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2944 os_memset(prk
, 0, SHA512_MAC_LEN
);
2946 os_free(sta
->owe_pmk
);
2947 sta
->owe_pmk
= NULL
;
2948 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2950 sta
->owe_pmk_len
= hash_len
;
2952 wpa_hexdump_key(MSG_DEBUG
, "OWE: PMK", sta
->owe_pmk
, sta
->owe_pmk_len
);
2953 wpa_hexdump(MSG_DEBUG
, "OWE: PMKID", pmkid
, PMKID_LEN
);
2954 wpa_auth_pmksa_add2(hapd
->wpa_auth
, sta
->addr
, sta
->owe_pmk
,
2955 sta
->owe_pmk_len
, pmkid
, 0, WPA_KEY_MGMT_OWE
);
2957 return WLAN_STATUS_SUCCESS
;
2961 u16
owe_validate_request(struct hostapd_data
*hapd
, const u8
*peer
,
2962 const u8
*rsn_ie
, size_t rsn_ie_len
,
2963 const u8
*owe_dh
, size_t owe_dh_len
)
2965 struct wpa_ie_data data
;
2968 if (!rsn_ie
|| rsn_ie_len
< 2) {
2969 wpa_printf(MSG_DEBUG
, "OWE: Invalid RSNE from " MACSTR
,
2971 return WLAN_STATUS_INVALID_IE
;
2976 res
= wpa_parse_wpa_ie_rsn(rsn_ie
, rsn_ie_len
, &data
);
2978 wpa_printf(MSG_DEBUG
, "Failed to parse RSNE from " MACSTR
2979 " (res=%d)", MAC2STR(peer
), res
);
2980 wpa_hexdump(MSG_DEBUG
, "RSNE", rsn_ie
, rsn_ie_len
);
2981 return wpa_res_to_status_code(res
);
2983 if (!(data
.key_mgmt
& WPA_KEY_MGMT_OWE
)) {
2984 wpa_printf(MSG_DEBUG
,
2985 "OWE: Unexpected key mgmt 0x%x from " MACSTR
,
2986 (unsigned int) data
.key_mgmt
, MAC2STR(peer
));
2987 return WLAN_STATUS_AKMP_NOT_VALID
;
2990 wpa_printf(MSG_DEBUG
,
2991 "OWE: No Diffie-Hellman Parameter element from "
2992 MACSTR
, MAC2STR(peer
));
2993 return WLAN_STATUS_AKMP_NOT_VALID
;
2996 return WLAN_STATUS_SUCCESS
;
3000 u16
owe_process_rsn_ie(struct hostapd_data
*hapd
,
3001 struct sta_info
*sta
,
3002 const u8
*rsn_ie
, size_t rsn_ie_len
,
3003 const u8
*owe_dh
, size_t owe_dh_len
)
3006 u8
*owe_buf
, ie
[256 * 2];
3010 if (!rsn_ie
|| rsn_ie_len
< 2) {
3011 wpa_printf(MSG_DEBUG
, "OWE: No RSNE in (Re)AssocReq");
3012 status
= WLAN_STATUS_INVALID_IE
;
3017 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
3020 wpa_printf(MSG_WARNING
,
3021 "OWE: Failed to initialize WPA state machine");
3022 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3027 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
3028 hapd
->iface
->freq
, rsn_ie
, rsn_ie_len
,
3029 NULL
, 0, NULL
, 0, owe_dh
, owe_dh_len
);
3030 status
= wpa_res_to_status_code(res
);
3031 if (status
!= WLAN_STATUS_SUCCESS
)
3033 status
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3034 if (status
!= WLAN_STATUS_SUCCESS
)
3036 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, ie
, sizeof(ie
),
3039 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3043 if (sta
->owe_ecdh
) {
3046 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3048 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3052 /* OWE Diffie-Hellman Parameter element */
3053 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3054 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3055 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3057 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3059 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3060 owe_buf
+= wpabuf_len(pub
);
3062 sta
->external_dh_updated
= 1;
3064 ie_len
= owe_buf
- ie
;
3067 wpa_printf(MSG_DEBUG
, "OWE: Update status %d, ie len %d for peer "
3068 MACSTR
, status
, (unsigned int) ie_len
,
3069 MAC2STR(sta
->addr
));
3070 hostapd_drv_update_dh_ie(hapd
, sta
->addr
, status
,
3071 status
== WLAN_STATUS_SUCCESS
? ie
: NULL
,
3077 #endif /* CONFIG_OWE */
3080 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3081 const u8
*ies
, size_t ies_len
, int reassoc
)
3083 struct ieee802_11_elems elems
;
3087 const u8
*p2p_dev_addr
= NULL
;
3089 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
3090 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3091 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
3092 "association request");
3093 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3096 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
3097 if (resp
!= WLAN_STATUS_SUCCESS
)
3099 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
3100 if (resp
!= WLAN_STATUS_SUCCESS
)
3102 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
3103 if (resp
!= WLAN_STATUS_SUCCESS
)
3105 resp
= copy_supp_rates(hapd
, sta
, &elems
);
3106 if (resp
!= WLAN_STATUS_SUCCESS
)
3109 resp
= check_multi_ap(hapd
, sta
, elems
.multi_ap
, elems
.multi_ap_len
);
3110 if (resp
!= WLAN_STATUS_SUCCESS
)
3113 #ifdef CONFIG_IEEE80211N
3114 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
);
3115 if (resp
!= WLAN_STATUS_SUCCESS
)
3117 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
3118 !(sta
->flags
& WLAN_STA_HT
)) {
3119 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3120 HOSTAPD_LEVEL_INFO
, "Station does not support "
3121 "mandatory HT PHY - reject association");
3122 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
3124 #endif /* CONFIG_IEEE80211N */
3126 #ifdef CONFIG_IEEE80211AC
3127 if (hapd
->iconf
->ieee80211ac
) {
3128 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
);
3129 if (resp
!= WLAN_STATUS_SUCCESS
)
3132 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
3133 if (resp
!= WLAN_STATUS_SUCCESS
)
3137 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
3138 !(sta
->flags
& WLAN_STA_VHT
)) {
3139 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3140 HOSTAPD_LEVEL_INFO
, "Station does not support "
3141 "mandatory VHT PHY - reject association");
3142 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
3145 if (hapd
->conf
->vendor_vht
&& !elems
.vht_capabilities
) {
3146 resp
= copy_sta_vendor_vht(hapd
, sta
, elems
.vendor_vht
,
3147 elems
.vendor_vht_len
);
3148 if (resp
!= WLAN_STATUS_SUCCESS
)
3151 #endif /* CONFIG_IEEE80211AC */
3152 #ifdef CONFIG_IEEE80211AX
3153 if (hapd
->iconf
->ieee80211ax
) {
3154 resp
= copy_sta_he_capab(hapd
, sta
, IEEE80211_MODE_AP
,
3155 elems
.he_capabilities
,
3156 elems
.he_capabilities_len
);
3157 if (resp
!= WLAN_STATUS_SUCCESS
)
3160 #endif /* CONFIG_IEEE80211AX */
3164 wpabuf_free(sta
->p2p_ie
);
3165 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3166 P2P_IE_VENDOR_TYPE
);
3168 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
3170 wpabuf_free(sta
->p2p_ie
);
3173 #endif /* CONFIG_P2P */
3175 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
3176 wpa_ie
= elems
.rsn_ie
;
3177 wpa_ie_len
= elems
.rsn_ie_len
;
3178 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
3180 wpa_ie
= elems
.wpa_ie
;
3181 wpa_ie_len
= elems
.wpa_ie_len
;
3188 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
3189 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
3190 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
3191 "Request - assume WPS is used");
3192 sta
->flags
|= WLAN_STA_WPS
;
3193 wpabuf_free(sta
->wps_ie
);
3194 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3195 WPS_IE_VENDOR_TYPE
);
3196 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
3197 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
3198 sta
->flags
|= WLAN_STA_WPS2
;
3202 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
3203 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
3204 "(Re)Association Request - reject");
3205 return WLAN_STATUS_INVALID_IE
;
3207 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
3208 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
3209 "(Re)Association Request - possible WPS use");
3210 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
3212 #endif /* CONFIG_WPS */
3213 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
3214 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3216 "No WPA/RSN IE in association request");
3217 return WLAN_STATUS_INVALID_IE
;
3220 if (hapd
->conf
->wpa
&& wpa_ie
) {
3224 if (sta
->wpa_sm
== NULL
)
3225 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3228 if (sta
->wpa_sm
== NULL
) {
3229 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3231 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3233 wpa_auth_set_auth_alg(sta
->wpa_sm
, sta
->auth_alg
);
3234 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
3237 elems
.rsnxe
? elems
.rsnxe
- 2 : NULL
,
3238 elems
.rsnxe
? elems
.rsnxe_len
+ 2 : 0,
3239 elems
.mdie
, elems
.mdie_len
,
3240 elems
.owe_dh
, elems
.owe_dh_len
);
3241 resp
= wpa_res_to_status_code(res
);
3242 if (resp
!= WLAN_STATUS_SUCCESS
)
3244 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3245 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3246 !sta
->sa_query_timed_out
&&
3247 sta
->sa_query_count
> 0)
3248 ap_check_sa_query_timeout(hapd
, sta
);
3249 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3250 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3251 !sta
->sa_query_timed_out
&&
3252 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
3254 * STA has already been associated with MFP and SA
3255 * Query timeout has not been reached. Reject the
3256 * association attempt temporarily and start SA Query,
3257 * if one is not pending.
3260 if (sta
->sa_query_count
== 0)
3261 ap_sta_start_sa_query(hapd
, sta
);
3263 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
3266 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
3267 sta
->flags
|= WLAN_STA_MFP
;
3269 sta
->flags
&= ~WLAN_STA_MFP
;
3271 #ifdef CONFIG_IEEE80211R_AP
3272 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
3274 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
3275 "to use association (not "
3276 "re-association) with FT auth_alg",
3277 MAC2STR(sta
->addr
));
3278 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3281 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
3283 if (resp
!= WLAN_STATUS_SUCCESS
)
3286 #endif /* CONFIG_IEEE80211R_AP */
3289 if (wpa_auth_uses_sae(sta
->wpa_sm
) && sta
->sae
&&
3290 sta
->sae
->state
== SAE_ACCEPTED
)
3291 wpa_auth_add_sae_pmkid(sta
->wpa_sm
, sta
->sae
->pmkid
);
3293 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3294 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
3295 struct rsn_pmksa_cache_entry
*sa
;
3296 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
3297 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
3298 wpa_printf(MSG_DEBUG
,
3299 "SAE: No PMKSA cache entry found for "
3300 MACSTR
, MAC2STR(sta
->addr
));
3301 return WLAN_STATUS_INVALID_PMKID
;
3303 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
3304 " using PMKSA caching", MAC2STR(sta
->addr
));
3305 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3306 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
3307 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
3308 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
3309 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
3310 "SAE AKM after non-SAE auth_alg %u",
3311 MAC2STR(sta
->addr
), sta
->auth_alg
);
3312 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
3315 if (hapd
->conf
->sae_pwe
== 2 &&
3316 sta
->auth_alg
== WLAN_AUTH_SAE
&&
3317 sta
->sae
&& sta
->sae
->tmp
&& !sta
->sae
->tmp
->h2e
&&
3318 elems
.rsnxe
&& elems
.rsnxe_len
>= 1 &&
3319 (elems
.rsnxe
[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E
))) {
3320 wpa_printf(MSG_INFO
, "SAE: " MACSTR
3321 " indicates support for SAE H2E, but did not use it",
3322 MAC2STR(sta
->addr
));
3323 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3325 #endif /* CONFIG_SAE */
3328 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3329 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
&&
3331 resp
= owe_process_assoc_req(hapd
, sta
, elems
.owe_dh
,
3333 if (resp
!= WLAN_STATUS_SUCCESS
)
3336 #endif /* CONFIG_OWE */
3339 dpp_pfs_free(sta
->dpp_pfs
);
3340 sta
->dpp_pfs
= NULL
;
3342 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3343 hapd
->conf
->dpp_netaccesskey
&& sta
->wpa_sm
&&
3344 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
&&
3346 sta
->dpp_pfs
= dpp_pfs_init(
3347 wpabuf_head(hapd
->conf
->dpp_netaccesskey
),
3348 wpabuf_len(hapd
->conf
->dpp_netaccesskey
));
3349 if (!sta
->dpp_pfs
) {
3350 wpa_printf(MSG_DEBUG
,
3351 "DPP: Could not initialize PFS");
3352 /* Try to continue without PFS */
3356 if (dpp_pfs_process(sta
->dpp_pfs
, elems
.owe_dh
,
3357 elems
.owe_dh_len
) < 0) {
3358 dpp_pfs_free(sta
->dpp_pfs
);
3359 sta
->dpp_pfs
= NULL
;
3360 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3364 wpa_auth_set_dpp_z(sta
->wpa_sm
, sta
->dpp_pfs
?
3365 sta
->dpp_pfs
->secret
: NULL
);
3367 #endif /* CONFIG_DPP2 */
3369 #ifdef CONFIG_IEEE80211N
3370 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
3371 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
3372 hostapd_logger(hapd
, sta
->addr
,
3373 HOSTAPD_MODULE_IEEE80211
,
3375 "Station tried to use TKIP with HT "
3377 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
3379 #endif /* CONFIG_IEEE80211N */
3381 } else if (hapd
->conf
->osen
) {
3382 if (elems
.osen
== NULL
) {
3384 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3386 "No HS 2.0 OSEN element in association request");
3387 return WLAN_STATUS_INVALID_IE
;
3390 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
3391 if (sta
->wpa_sm
== NULL
)
3392 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3394 if (sta
->wpa_sm
== NULL
) {
3395 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3397 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3399 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
3400 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
3401 return WLAN_STATUS_INVALID_IE
;
3402 #endif /* CONFIG_HS20 */
3404 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
3407 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
3408 #endif /* CONFIG_P2P */
3411 wpabuf_free(sta
->hs20_ie
);
3412 if (elems
.hs20
&& elems
.hs20_len
> 4) {
3415 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
3416 elems
.hs20_len
- 4);
3417 release
= ((elems
.hs20
[4] >> 4) & 0x0f) + 1;
3418 if (release
>= 2 && !wpa_auth_uses_mfp(sta
->wpa_sm
) &&
3419 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3420 wpa_printf(MSG_DEBUG
,
3421 "HS 2.0: PMF not negotiated by release %d station "
3422 MACSTR
, release
, MAC2STR(sta
->addr
));
3423 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
3426 sta
->hs20_ie
= NULL
;
3429 wpabuf_free(sta
->roaming_consortium
);
3430 if (elems
.roaming_cons_sel
)
3431 sta
->roaming_consortium
= wpabuf_alloc_copy(
3432 elems
.roaming_cons_sel
+ 4,
3433 elems
.roaming_cons_sel_len
- 4);
3435 sta
->roaming_consortium
= NULL
;
3436 #endif /* CONFIG_HS20 */
3439 wpabuf_free(sta
->mb_ies
);
3440 if (hapd
->iface
->fst
)
3441 sta
->mb_ies
= mb_ies_by_info(&elems
.mb_ies
);
3444 #endif /* CONFIG_FST */
3447 mbo_ap_check_sta_assoc(hapd
, sta
, &elems
);
3449 if (hapd
->conf
->mbo_enabled
&& (hapd
->conf
->wpa
& 2) &&
3450 elems
.mbo
&& sta
->cell_capa
&& !(sta
->flags
& WLAN_STA_MFP
) &&
3451 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3452 wpa_printf(MSG_INFO
,
3453 "MBO: Reject WPA2 association without PMF");
3454 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3456 #endif /* CONFIG_MBO */
3458 #if defined(CONFIG_FILS) && defined(CONFIG_OCV)
3459 if (wpa_auth_uses_ocv(sta
->wpa_sm
) &&
3460 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3461 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3462 sta
->auth_alg
== WLAN_AUTH_FILS_PK
)) {
3463 struct wpa_channel_info ci
;
3467 if (hostapd_drv_channel_info(hapd
, &ci
) != 0) {
3468 wpa_printf(MSG_WARNING
,
3469 "Failed to get channel info to validate received OCI in FILS (Re)Association Request frame");
3470 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3473 if (get_sta_tx_parameters(sta
->wpa_sm
,
3474 channel_width_to_int(ci
.chanwidth
),
3475 ci
.seg1_idx
, &tx_chanwidth
,
3477 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3479 if (ocv_verify_tx_params(elems
.oci
, elems
.oci_len
, &ci
,
3480 tx_chanwidth
, tx_seg1_idx
) != 0) {
3481 wpa_printf(MSG_WARNING
, "FILS: %s", ocv_errorstr
);
3482 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3485 #endif /* CONFIG_FILS && CONFIG_OCV */
3487 ap_copy_sta_supp_op_classes(sta
, elems
.supp_op_classes
,
3488 elems
.supp_op_classes_len
);
3490 if ((sta
->capability
& WLAN_CAPABILITY_RADIO_MEASUREMENT
) &&
3491 elems
.rrm_enabled
&&
3492 elems
.rrm_enabled_len
>= sizeof(sta
->rrm_enabled_capa
))
3493 os_memcpy(sta
->rrm_enabled_capa
, elems
.rrm_enabled
,
3494 sizeof(sta
->rrm_enabled_capa
));
3496 if (elems
.power_capab
) {
3497 sta
->min_tx_power
= elems
.power_capab
[0];
3498 sta
->max_tx_power
= elems
.power_capab
[1];
3499 sta
->power_capab
= 1;
3501 sta
->power_capab
= 0;
3504 return WLAN_STATUS_SUCCESS
;
3508 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
3512 struct ieee80211_mgmt reply
;
3514 os_memset(&reply
, 0, sizeof(reply
));
3515 reply
.frame_control
=
3516 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
3517 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
3518 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
3519 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
3521 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
3522 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
3524 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0, NULL
, 0, 0) < 0)
3525 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
3530 static int add_associated_sta(struct hostapd_data
*hapd
,
3531 struct sta_info
*sta
, int reassoc
)
3533 struct ieee80211_ht_capabilities ht_cap
;
3534 struct ieee80211_vht_capabilities vht_cap
;
3535 struct ieee80211_he_capabilities he_cap
;
3539 * Remove the STA entry to ensure the STA PS state gets cleared and
3540 * configuration gets updated. This is relevant for cases, such as
3541 * FT-over-the-DS, where a station re-associates back to the same AP but
3542 * skips the authentication flow, or if working with a driver that
3543 * does not support full AP client state.
3545 * Skip this if the STA has already completed FT reassociation and the
3546 * TK has been configured since the TX/RX PN must not be reset to 0 for
3549 * FT-over-the-DS has a special case where the STA entry (and as such,
3550 * the TK) has not yet been configured to the driver depending on which
3551 * driver interface is used. For that case, allow add-STA operation to
3552 * be used (instead of set-STA). This is needed to allow mac80211-based
3553 * drivers to accept the STA parameter configuration. Since this is
3554 * after a new FT-over-DS exchange, a new TK has been derived, so key
3555 * reinstallation is not a concern for this case.
3557 wpa_printf(MSG_DEBUG
, "Add associated STA " MACSTR
3558 " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
3559 MAC2STR(sta
->addr
), sta
->added_unassoc
, sta
->auth_alg
,
3560 sta
->ft_over_ds
, reassoc
,
3561 !!(sta
->flags
& WLAN_STA_AUTHORIZED
),
3562 wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
),
3563 wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
));
3565 if (!sta
->added_unassoc
&&
3566 (!(sta
->flags
& WLAN_STA_AUTHORIZED
) ||
3567 (reassoc
&& sta
->ft_over_ds
&& sta
->auth_alg
== WLAN_AUTH_FT
) ||
3568 (!wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
) &&
3569 !wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
)))) {
3570 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3571 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DRV_STA_REMOVED
);
3574 /* Do not allow the FT-over-DS exception to be used more than
3575 * once per authentication exchange to guarantee a new TK is
3577 sta
->ft_over_ds
= 0;
3580 #ifdef CONFIG_IEEE80211N
3581 if (sta
->flags
& WLAN_STA_HT
)
3582 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
3583 #endif /* CONFIG_IEEE80211N */
3584 #ifdef CONFIG_IEEE80211AC
3585 if (sta
->flags
& WLAN_STA_VHT
)
3586 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
3587 #endif /* CONFIG_IEEE80211AC */
3588 #ifdef CONFIG_IEEE80211AX
3589 if (sta
->flags
& WLAN_STA_HE
) {
3590 hostapd_get_he_capab(hapd
, sta
->he_capab
, &he_cap
,
3593 #endif /* CONFIG_IEEE80211AX */
3596 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
3597 * will be set when the ACK frame for the (Re)Association Response frame
3598 * is processed (TX status driver event).
3600 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
3601 sta
->supported_rates
, sta
->supported_rates_len
,
3602 sta
->listen_interval
,
3603 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
3604 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
3605 sta
->flags
& WLAN_STA_HE
? &he_cap
: NULL
,
3606 sta
->flags
& WLAN_STA_HE
? sta
->he_capab_len
: 0,
3607 sta
->flags
| WLAN_STA_ASSOC
, sta
->qosinfo
,
3608 sta
->vht_opmode
, sta
->p2p_ie
? 1 : 0,
3610 hostapd_logger(hapd
, sta
->addr
,
3611 HOSTAPD_MODULE_IEEE80211
, HOSTAPD_LEVEL_NOTICE
,
3612 "Could not %s STA to kernel driver",
3613 set
? "set" : "add");
3615 if (sta
->added_unassoc
) {
3616 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3617 sta
->added_unassoc
= 0;
3623 sta
->added_unassoc
= 0;
3629 static u16
send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3630 const u8
*addr
, u16 status_code
, int reassoc
,
3631 const u8
*ies
, size_t ies_len
, int rssi
)
3636 struct ieee80211_mgmt
*reply
;
3638 u16 res
= WLAN_STATUS_SUCCESS
;
3640 buflen
= sizeof(struct ieee80211_mgmt
) + 1024;
3642 if (sta
&& sta
->fils_hlp_resp
)
3643 buflen
+= wpabuf_len(sta
->fils_hlp_resp
);
3646 #endif /* CONFIG_FILS */
3648 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3650 #endif /* CONFIG_OWE */
3652 if (sta
&& sta
->dpp_pfs
)
3653 buflen
+= 5 + sta
->dpp_pfs
->curve
->prime_len
;
3654 #endif /* CONFIG_DPP2 */
3655 buf
= os_zalloc(buflen
);
3657 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3660 reply
= (struct ieee80211_mgmt
*) buf
;
3661 reply
->frame_control
=
3662 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
3663 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
3664 WLAN_FC_STYPE_ASSOC_RESP
));
3665 os_memcpy(reply
->da
, addr
, ETH_ALEN
);
3666 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
3667 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
3669 send_len
= IEEE80211_HDRLEN
;
3670 send_len
+= sizeof(reply
->u
.assoc_resp
);
3671 reply
->u
.assoc_resp
.capab_info
=
3672 host_to_le16(hostapd_own_capab_info(hapd
));
3673 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
3675 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0) |
3677 /* Supported rates */
3678 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
3679 /* Extended supported rates */
3680 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
3683 if (status_code
== WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
&&
3685 int delta
= hapd
->iconf
->rssi_reject_assoc_rssi
- rssi
;
3687 p
= hostapd_eid_mbo_rssi_assoc_rej(hapd
, p
, buf
+ buflen
- p
,
3690 #endif /* CONFIG_MBO */
3692 #ifdef CONFIG_IEEE80211R_AP
3693 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
) {
3694 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
3695 * Transition Information, RSN, [RIC Response] */
3696 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
3698 sta
->auth_alg
, ies
, ies_len
);
3700 wpa_printf(MSG_DEBUG
,
3701 "FT: Failed to write AssocResp IEs");
3702 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3706 #endif /* CONFIG_IEEE80211R_AP */
3708 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3709 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3710 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3711 sta
->auth_alg
== WLAN_AUTH_FILS_PK
))
3712 p
= wpa_auth_write_assoc_resp_fils(sta
->wpa_sm
, p
,
3715 #endif /* CONFIG_FILS */
3718 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3719 (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3720 p
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, p
,
3723 #endif /* CONFIG_OWE */
3725 if (sta
&& status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
3726 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
3728 #ifdef CONFIG_IEEE80211N
3729 p
= hostapd_eid_ht_capabilities(hapd
, p
);
3730 p
= hostapd_eid_ht_operation(hapd
, p
);
3731 #endif /* CONFIG_IEEE80211N */
3733 #ifdef CONFIG_IEEE80211AC
3734 if (hapd
->iconf
->ieee80211ac
&& !hapd
->conf
->disable_11ac
&&
3735 !is_6ghz_op_class(hapd
->iconf
->op_class
)) {
3736 u32 nsts
= 0, sta_nsts
;
3738 if (sta
&& hapd
->conf
->use_sta_nsts
&& sta
->vht_capabilities
) {
3739 struct ieee80211_vht_capabilities
*capa
;
3741 nsts
= (hapd
->iface
->conf
->vht_capab
>>
3742 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3743 capa
= sta
->vht_capabilities
;
3744 sta_nsts
= (le_to_host32(capa
->vht_capabilities_info
) >>
3745 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3747 if (nsts
< sta_nsts
)
3752 p
= hostapd_eid_vht_capabilities(hapd
, p
, nsts
);
3753 p
= hostapd_eid_vht_operation(hapd
, p
);
3755 #endif /* CONFIG_IEEE80211AC */
3757 #ifdef CONFIG_IEEE80211AX
3758 if (hapd
->iconf
->ieee80211ax
) {
3759 p
= hostapd_eid_he_capab(hapd
, p
, IEEE80211_MODE_AP
);
3760 p
= hostapd_eid_he_operation(hapd
, p
);
3761 p
= hostapd_eid_spatial_reuse(hapd
, p
);
3762 p
= hostapd_eid_he_mu_edca_parameter_set(hapd
, p
);
3764 #endif /* CONFIG_IEEE80211AX */
3766 p
= hostapd_eid_ext_capab(hapd
, p
);
3767 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
3768 if (sta
&& sta
->qos_map_enabled
)
3769 p
= hostapd_eid_qos_map_set(hapd
, p
);
3772 if (hapd
->iface
->fst_ies
) {
3773 os_memcpy(p
, wpabuf_head(hapd
->iface
->fst_ies
),
3774 wpabuf_len(hapd
->iface
->fst_ies
));
3775 p
+= wpabuf_len(hapd
->iface
->fst_ies
);
3777 #endif /* CONFIG_FST */
3779 p
= hostapd_eid_rsnxe(hapd
, p
, buf
+ buflen
- p
);
3782 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3783 sta
&& sta
->owe_ecdh
&& status_code
== WLAN_STATUS_SUCCESS
&&
3784 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
) {
3787 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3789 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3792 /* OWE Diffie-Hellman Parameter element */
3793 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3794 *p
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3795 *p
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
3796 WPA_PUT_LE16(p
, sta
->owe_group
);
3798 os_memcpy(p
, wpabuf_head(pub
), wpabuf_len(pub
));
3799 p
+= wpabuf_len(pub
);
3802 #endif /* CONFIG_OWE */
3805 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3806 sta
&& sta
->dpp_pfs
&& status_code
== WLAN_STATUS_SUCCESS
&&
3807 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
) {
3808 os_memcpy(p
, wpabuf_head(sta
->dpp_pfs
->ie
),
3809 wpabuf_len(sta
->dpp_pfs
->ie
));
3810 p
+= wpabuf_len(sta
->dpp_pfs
->ie
);
3812 #endif /* CONFIG_DPP2 */
3814 #ifdef CONFIG_IEEE80211AC
3815 if (sta
&& hapd
->conf
->vendor_vht
&& (sta
->flags
& WLAN_STA_VENDOR_VHT
))
3816 p
= hostapd_eid_vendor_vht(hapd
, p
);
3817 #endif /* CONFIG_IEEE80211AC */
3819 if (sta
&& (sta
->flags
& WLAN_STA_WMM
))
3820 p
= hostapd_eid_wmm(hapd
, p
);
3824 ((sta
->flags
& WLAN_STA_WPS
) ||
3825 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
))) {
3826 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
3828 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
3829 p
+= wpabuf_len(wps
);
3833 #endif /* CONFIG_WPS */
3835 if (sta
&& (sta
->flags
& WLAN_STA_MULTI_AP
))
3836 p
= hostapd_eid_multi_ap(hapd
, p
);
3839 if (sta
&& sta
->p2p_ie
&& hapd
->p2p_group
) {
3840 struct wpabuf
*p2p_resp_ie
;
3841 enum p2p_status_code status
;
3842 switch (status_code
) {
3843 case WLAN_STATUS_SUCCESS
:
3844 status
= P2P_SC_SUCCESS
;
3846 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
3847 status
= P2P_SC_FAIL_LIMIT_REACHED
;
3850 status
= P2P_SC_FAIL_INVALID_PARAMS
;
3853 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
3855 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
3856 wpabuf_len(p2p_resp_ie
));
3857 p
+= wpabuf_len(p2p_resp_ie
);
3858 wpabuf_free(p2p_resp_ie
);
3861 #endif /* CONFIG_P2P */
3863 #ifdef CONFIG_P2P_MANAGER
3864 if (hapd
->conf
->p2p
& P2P_MANAGE
)
3865 p
= hostapd_eid_p2p_manage(hapd
, p
);
3866 #endif /* CONFIG_P2P_MANAGER */
3868 p
= hostapd_eid_mbo(hapd
, p
, buf
+ buflen
- p
);
3870 if (hapd
->conf
->assocresp_elements
&&
3871 (size_t) (buf
+ buflen
- p
) >=
3872 wpabuf_len(hapd
->conf
->assocresp_elements
)) {
3873 os_memcpy(p
, wpabuf_head(hapd
->conf
->assocresp_elements
),
3874 wpabuf_len(hapd
->conf
->assocresp_elements
));
3875 p
+= wpabuf_len(hapd
->conf
->assocresp_elements
);
3878 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
3882 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3883 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3884 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
3885 status_code
== WLAN_STATUS_SUCCESS
) {
3886 struct ieee802_11_elems elems
;
3888 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 0) ==
3889 ParseFailed
|| !elems
.fils_session
) {
3890 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3895 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3896 *p
++ = 1 + FILS_SESSION_LEN
; /* Length */
3897 *p
++ = WLAN_EID_EXT_FILS_SESSION
; /* Element ID Extension */
3898 os_memcpy(p
, elems
.fils_session
, FILS_SESSION_LEN
);
3899 send_len
+= 2 + 1 + FILS_SESSION_LEN
;
3901 send_len
= fils_encrypt_assoc(sta
->wpa_sm
, buf
, send_len
,
3902 buflen
, sta
->fils_hlp_resp
);
3904 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3908 #endif /* CONFIG_FILS */
3910 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0, NULL
, 0, 0) < 0) {
3911 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
3913 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3923 u8
* owe_assoc_req_process(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3924 const u8
*owe_dh
, u8 owe_dh_len
,
3925 u8
*owe_buf
, size_t owe_buf_len
, u16
*reason
)
3927 #ifdef CONFIG_TESTING_OPTIONS
3928 if (hapd
->conf
->own_ie_override
) {
3929 wpa_printf(MSG_DEBUG
, "OWE: Using IE override");
3930 *reason
= WLAN_STATUS_SUCCESS
;
3931 return wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3932 owe_buf_len
, NULL
, 0);
3934 #endif /* CONFIG_TESTING_OPTIONS */
3936 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
3937 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
3938 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3939 owe_buf_len
, NULL
, 0);
3940 *reason
= WLAN_STATUS_SUCCESS
;
3944 if (sta
->owe_pmk
&& sta
->external_dh_updated
) {
3945 wpa_printf(MSG_DEBUG
, "OWE: Using previously derived PMK");
3946 *reason
= WLAN_STATUS_SUCCESS
;
3950 *reason
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3951 if (*reason
!= WLAN_STATUS_SUCCESS
)
3954 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3955 owe_buf_len
, NULL
, 0);
3957 if (sta
->owe_ecdh
&& owe_buf
) {
3960 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3962 *reason
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3966 /* OWE Diffie-Hellman Parameter element */
3967 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3968 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3969 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3971 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3973 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3974 owe_buf
+= wpabuf_len(pub
);
3980 #endif /* CONFIG_OWE */
3985 void fils_hlp_finish_assoc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
3989 wpa_printf(MSG_DEBUG
, "FILS: Finish association with " MACSTR
,
3990 MAC2STR(sta
->addr
));
3991 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3992 if (!sta
->fils_pending_assoc_req
)
3994 reply_res
= send_assoc_resp(hapd
, sta
, sta
->addr
, WLAN_STATUS_SUCCESS
,
3995 sta
->fils_pending_assoc_is_reassoc
,
3996 sta
->fils_pending_assoc_req
,
3997 sta
->fils_pending_assoc_req_len
, 0);
3998 os_free(sta
->fils_pending_assoc_req
);
3999 sta
->fils_pending_assoc_req
= NULL
;
4000 sta
->fils_pending_assoc_req_len
= 0;
4001 wpabuf_free(sta
->fils_hlp_resp
);
4002 sta
->fils_hlp_resp
= NULL
;
4003 wpabuf_free(sta
->hlp_dhcp_discover
);
4004 sta
->hlp_dhcp_discover
= NULL
;
4007 * Remove the station in case transmission of a success response fails.
4008 * At this point the station was already added associated to the driver.
4010 if (reply_res
!= WLAN_STATUS_SUCCESS
)
4011 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4015 void fils_hlp_timeout(void *eloop_ctx
, void *eloop_data
)
4017 struct hostapd_data
*hapd
= eloop_ctx
;
4018 struct sta_info
*sta
= eloop_data
;
4020 wpa_printf(MSG_DEBUG
,
4021 "FILS: HLP response timeout - continue with association response for "
4022 MACSTR
, MAC2STR(sta
->addr
));
4023 if (sta
->fils_drv_assoc_finish
)
4024 hostapd_notify_assoc_fils_finish(hapd
, sta
);
4026 fils_hlp_finish_assoc(hapd
, sta
);
4029 #endif /* CONFIG_FILS */
4032 static void handle_assoc(struct hostapd_data
*hapd
,
4033 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4034 int reassoc
, int rssi
)
4036 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
4037 u16 resp
= WLAN_STATUS_SUCCESS
, reply_res
;
4040 struct sta_info
*sta
;
4043 int delay_assoc
= 0;
4044 #endif /* CONFIG_FILS */
4046 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
4047 sizeof(mgmt
->u
.assoc_req
))) {
4048 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
4049 reassoc
, (unsigned long) len
);
4053 #ifdef CONFIG_TESTING_OPTIONS
4055 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
4056 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
4057 wpa_printf(MSG_INFO
,
4058 "TESTING: ignoring reassoc request from "
4059 MACSTR
, MAC2STR(mgmt
->sa
));
4063 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
4064 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
4065 wpa_printf(MSG_INFO
,
4066 "TESTING: ignoring assoc request from "
4067 MACSTR
, MAC2STR(mgmt
->sa
));
4071 #endif /* CONFIG_TESTING_OPTIONS */
4073 fc
= le_to_host16(mgmt
->frame_control
);
4074 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4077 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
4078 listen_interval
= le_to_host16(
4079 mgmt
->u
.reassoc_req
.listen_interval
);
4080 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
4081 " capab_info=0x%02x listen_interval=%d current_ap="
4082 MACSTR
" seq_ctrl=0x%x%s",
4083 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
4084 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
4085 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
4086 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
4087 pos
= mgmt
->u
.reassoc_req
.variable
;
4089 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
4090 listen_interval
= le_to_host16(
4091 mgmt
->u
.assoc_req
.listen_interval
);
4092 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
4093 " capab_info=0x%02x listen_interval=%d "
4095 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
4096 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
4097 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
4098 pos
= mgmt
->u
.assoc_req
.variable
;
4101 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4102 #ifdef CONFIG_IEEE80211R_AP
4103 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
4104 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
4105 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
4106 "prior to authentication since it is using "
4107 "over-the-DS FT", MAC2STR(mgmt
->sa
));
4110 * Mark station as authenticated, to avoid adding station
4111 * entry in the driver as associated and not authenticated
4113 sta
->flags
|= WLAN_STA_AUTH
;
4115 #endif /* CONFIG_IEEE80211R_AP */
4116 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
4117 if (hapd
->iface
->current_mode
&&
4118 hapd
->iface
->current_mode
->mode
==
4119 HOSTAPD_MODE_IEEE80211AD
) {
4121 struct radius_sta info
;
4123 acl_res
= ieee802_11_allowed_address(hapd
, mgmt
->sa
,
4126 if (acl_res
== HOSTAPD_ACL_REJECT
) {
4127 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
4128 "Ignore Association Request frame from "
4129 MACSTR
" due to ACL reject",
4131 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4134 if (acl_res
== HOSTAPD_ACL_PENDING
)
4137 /* DMG/IEEE 802.11ad does not use authentication.
4138 * Allocate sta entry upon association. */
4139 sta
= ap_sta_add(hapd
, mgmt
->sa
);
4141 hostapd_logger(hapd
, mgmt
->sa
,
4142 HOSTAPD_MODULE_IEEE80211
,
4144 "Failed to add STA");
4145 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4149 acl_res
= ieee802_11_set_radius_info(
4150 hapd
, sta
, acl_res
, &info
);
4152 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4156 hostapd_logger(hapd
, sta
->addr
,
4157 HOSTAPD_MODULE_IEEE80211
,
4158 HOSTAPD_LEVEL_DEBUG
,
4159 "Skip authentication for DMG/IEEE 802.11ad");
4160 sta
->flags
|= WLAN_STA_AUTH
;
4161 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
4162 sta
->auth_alg
= WLAN_AUTH_OPEN
;
4164 hostapd_logger(hapd
, mgmt
->sa
,
4165 HOSTAPD_MODULE_IEEE80211
,
4167 "Station tried to associate before authentication (aid=%d flags=0x%x)",
4168 sta
? sta
->aid
: -1,
4169 sta
? sta
->flags
: 0);
4170 send_deauth(hapd
, mgmt
->sa
,
4171 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
4176 if ((fc
& WLAN_FC_RETRY
) &&
4177 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4178 sta
->last_seq_ctrl
== seq_ctrl
&&
4179 sta
->last_subtype
== (reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4180 WLAN_FC_STYPE_ASSOC_REQ
)) {
4181 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4182 HOSTAPD_LEVEL_DEBUG
,
4183 "Drop repeated association frame seq_ctrl=0x%x",
4187 sta
->last_seq_ctrl
= seq_ctrl
;
4188 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4189 WLAN_FC_STYPE_ASSOC_REQ
;
4191 if (hapd
->tkip_countermeasures
) {
4192 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4196 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
4197 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4198 HOSTAPD_LEVEL_DEBUG
,
4199 "Too large Listen Interval (%d)",
4201 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
4206 if (hapd
->conf
->mbo_enabled
&& hapd
->mbo_assoc_disallow
) {
4207 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4211 if (hapd
->iconf
->rssi_reject_assoc_rssi
&& rssi
&&
4212 rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
&&
4213 (sta
->auth_rssi
== 0 ||
4214 sta
->auth_rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
)) {
4215 resp
= WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
;
4218 #endif /* CONFIG_MBO */
4221 * sta->capability is used in check_assoc_ies() for RRM enabled
4222 * capability element.
4224 sta
->capability
= capab_info
;
4227 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4228 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4229 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4232 /* The end of the payload is encrypted. Need to decrypt it
4233 * before parsing. */
4235 tmp
= os_memdup(pos
, left
);
4237 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4241 res
= fils_decrypt_assoc(sta
->wpa_sm
, sta
->fils_session
, mgmt
,
4244 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4250 #endif /* CONFIG_FILS */
4252 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
4254 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
4255 if (resp
!= WLAN_STATUS_SUCCESS
)
4258 if (hostapd_get_aid(hapd
, sta
) < 0) {
4259 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4260 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
4261 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4265 sta
->listen_interval
= listen_interval
;
4267 if (hapd
->iface
->current_mode
&&
4268 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
4269 sta
->flags
|= WLAN_STA_NONERP
;
4270 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
4271 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
4272 sta
->flags
&= ~WLAN_STA_NONERP
;
4276 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
4277 sta
->nonerp_set
= 1;
4278 hapd
->iface
->num_sta_non_erp
++;
4279 if (hapd
->iface
->num_sta_non_erp
== 1)
4280 ieee802_11_set_beacons(hapd
->iface
);
4283 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
4284 !sta
->no_short_slot_time_set
) {
4285 sta
->no_short_slot_time_set
= 1;
4286 hapd
->iface
->num_sta_no_short_slot_time
++;
4287 if (hapd
->iface
->current_mode
&&
4288 hapd
->iface
->current_mode
->mode
==
4289 HOSTAPD_MODE_IEEE80211G
&&
4290 hapd
->iface
->num_sta_no_short_slot_time
== 1)
4291 ieee802_11_set_beacons(hapd
->iface
);
4294 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
4295 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
4297 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
4299 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
4300 !sta
->no_short_preamble_set
) {
4301 sta
->no_short_preamble_set
= 1;
4302 hapd
->iface
->num_sta_no_short_preamble
++;
4303 if (hapd
->iface
->current_mode
&&
4304 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
4305 && hapd
->iface
->num_sta_no_short_preamble
== 1)
4306 ieee802_11_set_beacons(hapd
->iface
);
4309 #ifdef CONFIG_IEEE80211N
4310 update_ht_state(hapd
, sta
);
4311 #endif /* CONFIG_IEEE80211N */
4313 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4314 HOSTAPD_LEVEL_DEBUG
,
4315 "association OK (aid %d)", sta
->aid
);
4316 /* Station will be marked associated, after it acknowledges AssocResp
4318 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
4320 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
4321 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
4322 "SA Query procedure", reassoc
? "re" : "");
4323 /* TODO: Send a protected Disassociate frame to the STA using
4324 * the old key and Reason Code "Previous Authentication no
4325 * longer valid". Make sure this is only sent protected since
4326 * unprotected frame would be received by the STA that is now
4327 * trying to associate.
4331 /* Make sure that the previously registered inactivity timer will not
4332 * remove the STA immediately. */
4333 sta
->timeout_next
= STA_NULLFUNC
;
4335 #ifdef CONFIG_TAXONOMY
4336 taxonomy_sta_info_assoc_req(hapd
, sta
, pos
, left
);
4337 #endif /* CONFIG_TAXONOMY */
4339 sta
->pending_wds_enable
= 0;
4342 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4343 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4344 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4345 if (fils_process_hlp(hapd
, sta
, pos
, left
) > 0)
4348 #endif /* CONFIG_FILS */
4353 * In case of a successful response, add the station to the driver.
4354 * Otherwise, the kernel may ignore Data frames before we process the
4355 * ACK frame (TX status). In case of a failure, this station will be
4358 * Note that this is not compliant with the IEEE 802.11 standard that
4359 * states that a non-AP station should transition into the
4360 * authenticated/associated state only after the station acknowledges
4361 * the (Re)Association Response frame. However, still do this as:
4363 * 1. In case the station does not acknowledge the (Re)Association
4364 * Response frame, it will be removed.
4365 * 2. Data frames will be dropped in the kernel until the station is
4366 * set into authorized state, and there are no significant known
4367 * issues with processing other non-Data Class 3 frames during this
4370 if (resp
== WLAN_STATUS_SUCCESS
&& sta
&&
4371 add_associated_sta(hapd
, sta
, reassoc
))
4372 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4375 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
&&
4376 eloop_is_timeout_registered(fils_hlp_timeout
, hapd
, sta
) &&
4377 sta
->fils_pending_assoc_req
) {
4378 /* Do not reschedule fils_hlp_timeout in case the station
4379 * retransmits (Re)Association Request frame while waiting for
4380 * the previously started FILS HLP wait, so that the timeout can
4381 * be determined from the first pending attempt. */
4382 wpa_printf(MSG_DEBUG
,
4383 "FILS: Continue waiting for HLP processing before sending (Re)Association Response frame to "
4384 MACSTR
, MAC2STR(sta
->addr
));
4389 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4390 os_free(sta
->fils_pending_assoc_req
);
4391 sta
->fils_pending_assoc_req
= NULL
;
4392 sta
->fils_pending_assoc_req_len
= 0;
4393 wpabuf_free(sta
->fils_hlp_resp
);
4394 sta
->fils_hlp_resp
= NULL
;
4396 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
) {
4397 sta
->fils_pending_assoc_req
= tmp
;
4398 sta
->fils_pending_assoc_req_len
= left
;
4399 sta
->fils_pending_assoc_is_reassoc
= reassoc
;
4400 sta
->fils_drv_assoc_finish
= 0;
4401 wpa_printf(MSG_DEBUG
,
4402 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
4403 MACSTR
, MAC2STR(sta
->addr
));
4404 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4405 eloop_register_timeout(0, hapd
->conf
->fils_hlp_wait_time
* 1024,
4406 fils_hlp_timeout
, hapd
, sta
);
4409 #endif /* CONFIG_FILS */
4411 reply_res
= send_assoc_resp(hapd
, sta
, mgmt
->sa
, resp
, reassoc
, pos
,
4416 * Remove the station in case tranmission of a success response fails
4417 * (the STA was added associated to the driver) or if the station was
4418 * previously added unassociated.
4420 if (sta
&& ((reply_res
!= WLAN_STATUS_SUCCESS
&&
4421 resp
== WLAN_STATUS_SUCCESS
) || sta
->added_unassoc
)) {
4422 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4423 sta
->added_unassoc
= 0;
4428 static void handle_disassoc(struct hostapd_data
*hapd
,
4429 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4431 struct sta_info
*sta
;
4433 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
4434 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
4435 (unsigned long) len
);
4439 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
4441 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4443 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4445 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
4450 ap_sta_set_authorized(hapd
, sta
, 0);
4451 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4452 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
4453 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
4454 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4455 HOSTAPD_LEVEL_INFO
, "disassociated");
4456 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4457 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4458 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
4460 accounting_sta_stop(hapd
, sta
);
4461 ieee802_1x_free_station(hapd
, sta
);
4463 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
4464 ap_sta_ip6addr_del(hapd
, sta
);
4465 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4466 sta
->added_unassoc
= 0;
4468 if (sta
->timeout_next
== STA_NULLFUNC
||
4469 sta
->timeout_next
== STA_DISASSOC
) {
4470 sta
->timeout_next
= STA_DEAUTH
;
4471 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
4472 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
4476 mlme_disassociate_indication(
4477 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4479 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
4480 * disassociation. */
4481 if (hapd
->iface
->current_mode
&&
4482 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
) {
4483 sta
->flags
&= ~WLAN_STA_AUTH
;
4484 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4485 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4486 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4487 ap_free_sta(hapd
, sta
);
4492 static void handle_deauth(struct hostapd_data
*hapd
,
4493 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4495 struct sta_info
*sta
;
4497 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
4498 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
4499 "payload (len=%lu)", (unsigned long) len
);
4503 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
4505 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
4507 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4509 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
4510 "to deauthenticate, but it is not authenticated",
4515 ap_sta_set_authorized(hapd
, sta
, 0);
4516 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4517 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
4518 WLAN_STA_ASSOC_REQ_OK
);
4519 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4520 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4521 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4522 mlme_deauthenticate_indication(
4523 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
4524 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4525 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4526 ap_free_sta(hapd
, sta
);
4530 static void handle_beacon(struct hostapd_data
*hapd
,
4531 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4532 struct hostapd_frame_info
*fi
)
4534 struct ieee802_11_elems elems
;
4536 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
4537 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
4538 (unsigned long) len
);
4542 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
4543 len
- (IEEE80211_HDRLEN
+
4544 sizeof(mgmt
->u
.beacon
)), &elems
,
4547 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
4551 static int robust_action_frame(u8 category
)
4553 return category
!= WLAN_ACTION_PUBLIC
&&
4554 category
!= WLAN_ACTION_HT
;
4558 static int handle_action(struct hostapd_data
*hapd
,
4559 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4562 struct sta_info
*sta
;
4563 u8
*action __maybe_unused
;
4565 if (len
< IEEE80211_HDRLEN
+ 2 + 1) {
4566 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4567 HOSTAPD_LEVEL_DEBUG
,
4568 "handle_action - too short payload (len=%lu)",
4569 (unsigned long) len
);
4573 action
= (u8
*) &mgmt
->u
.action
.u
;
4574 wpa_printf(MSG_DEBUG
, "RX_ACTION category %u action %u sa " MACSTR
4575 " da " MACSTR
" len %d freq %u",
4576 mgmt
->u
.action
.category
, *action
,
4577 MAC2STR(mgmt
->sa
), MAC2STR(mgmt
->da
), (int) len
, freq
);
4579 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4581 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
4582 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
4583 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
4584 "frame (category=%u) from unassociated STA " MACSTR
,
4585 mgmt
->u
.action
.category
, MAC2STR(mgmt
->sa
));
4589 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
4590 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
4591 robust_action_frame(mgmt
->u
.action
.category
)) {
4592 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4593 HOSTAPD_LEVEL_DEBUG
,
4594 "Dropped unprotected Robust Action frame from "
4600 u16 fc
= le_to_host16(mgmt
->frame_control
);
4601 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4603 if ((fc
& WLAN_FC_RETRY
) &&
4604 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4605 sta
->last_seq_ctrl
== seq_ctrl
&&
4606 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
4607 hostapd_logger(hapd
, sta
->addr
,
4608 HOSTAPD_MODULE_IEEE80211
,
4609 HOSTAPD_LEVEL_DEBUG
,
4610 "Drop repeated action frame seq_ctrl=0x%x",
4615 sta
->last_seq_ctrl
= seq_ctrl
;
4616 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
4619 switch (mgmt
->u
.action
.category
) {
4620 #ifdef CONFIG_IEEE80211R_AP
4621 case WLAN_ACTION_FT
:
4623 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
4624 len
- IEEE80211_HDRLEN
))
4627 #endif /* CONFIG_IEEE80211R_AP */
4628 case WLAN_ACTION_WMM
:
4629 hostapd_wmm_action(hapd
, mgmt
, len
);
4631 case WLAN_ACTION_SA_QUERY
:
4632 ieee802_11_sa_query_action(hapd
, mgmt
, len
);
4634 #ifdef CONFIG_WNM_AP
4635 case WLAN_ACTION_WNM
:
4636 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
4638 #endif /* CONFIG_WNM_AP */
4640 case WLAN_ACTION_FST
:
4641 if (hapd
->iface
->fst
)
4642 fst_rx_action(hapd
->iface
->fst
, mgmt
, len
);
4644 wpa_printf(MSG_DEBUG
,
4645 "FST: Ignore FST Action frame - no FST attached");
4647 #endif /* CONFIG_FST */
4648 case WLAN_ACTION_PUBLIC
:
4649 case WLAN_ACTION_PROTECTED_DUAL
:
4650 #ifdef CONFIG_IEEE80211N
4651 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4652 mgmt
->u
.action
.u
.public_action
.action
==
4653 WLAN_PA_20_40_BSS_COEX
) {
4654 hostapd_2040_coex_action(hapd
, mgmt
, len
);
4657 #endif /* CONFIG_IEEE80211N */
4659 if (len
>= IEEE80211_HDRLEN
+ 6 &&
4660 mgmt
->u
.action
.u
.vs_public_action
.action
==
4661 WLAN_PA_VENDOR_SPECIFIC
&&
4662 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4664 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4666 const u8
*pos
, *end
;
4668 pos
= mgmt
->u
.action
.u
.vs_public_action
.oui
;
4669 end
= ((const u8
*) mgmt
) + len
;
4670 hostapd_dpp_rx_action(hapd
, mgmt
->sa
, pos
, end
- pos
,
4674 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4675 (mgmt
->u
.action
.u
.public_action
.action
==
4676 WLAN_PA_GAS_INITIAL_RESP
||
4677 mgmt
->u
.action
.u
.public_action
.action
==
4678 WLAN_PA_GAS_COMEBACK_RESP
)) {
4679 const u8
*pos
, *end
;
4681 pos
= &mgmt
->u
.action
.u
.public_action
.action
;
4682 end
= ((const u8
*) mgmt
) + len
;
4683 gas_query_ap_rx(hapd
->gas
, mgmt
->sa
,
4684 mgmt
->u
.action
.category
,
4685 pos
, end
- pos
, hapd
->iface
->freq
);
4688 #endif /* CONFIG_DPP */
4689 if (hapd
->public_action_cb
) {
4690 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
4694 if (hapd
->public_action_cb2
) {
4695 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
4699 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
4702 case WLAN_ACTION_VENDOR_SPECIFIC
:
4703 if (hapd
->vendor_action_cb
) {
4704 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
4706 hapd
->iface
->freq
) == 0)
4710 case WLAN_ACTION_RADIO_MEASUREMENT
:
4711 hostapd_handle_radio_measurement(hapd
, (const u8
*) mgmt
, len
);
4715 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4716 HOSTAPD_LEVEL_DEBUG
,
4717 "handle_action - unknown action category %d or invalid "
4719 mgmt
->u
.action
.category
);
4720 if (!is_multicast_ether_addr(mgmt
->da
) &&
4721 !(mgmt
->u
.action
.category
& 0x80) &&
4722 !is_multicast_ether_addr(mgmt
->sa
)) {
4723 struct ieee80211_mgmt
*resp
;
4726 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
4727 * Return the Action frame to the source without change
4728 * except that MSB of the Category set to 1.
4730 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
4731 "frame back to sender");
4732 resp
= os_memdup(mgmt
, len
);
4735 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
4736 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
4737 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
4738 resp
->u
.action
.category
|= 0x80;
4740 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0, NULL
, 0, 0) < 0) {
4741 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
4752 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
4753 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
4755 * @buf: management frame data (starting from IEEE 802.11 header)
4756 * @len: length of frame data in octets
4757 * @fi: meta data about received frame (signal level, etc.)
4759 * Process all incoming IEEE 802.11 management frames. This will be called for
4760 * each frame received from the kernel driver through wlan#ap interface. In
4761 * addition, it can be called to re-inserted pending frames (e.g., when using
4762 * external RADIUS server as an MAC ACL).
4764 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4765 struct hostapd_frame_info
*fi
)
4767 struct ieee80211_mgmt
*mgmt
;
4771 int ssi_signal
= fi
? fi
->ssi_signal
: 0;
4779 freq
= hapd
->iface
->freq
;
4781 mgmt
= (struct ieee80211_mgmt
*) buf
;
4782 fc
= le_to_host16(mgmt
->frame_control
);
4783 stype
= WLAN_FC_GET_STYPE(fc
);
4785 if (is_multicast_ether_addr(mgmt
->sa
) ||
4786 is_zero_ether_addr(mgmt
->sa
) ||
4787 os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
4788 /* Do not process any frames with unexpected/invalid SA so that
4789 * we do not add any state for unexpected STA addresses or end
4790 * up sending out frames to unexpected destination. */
4791 wpa_printf(MSG_DEBUG
, "MGMT: Invalid SA=" MACSTR
4792 " in received frame - ignore this frame silently",
4797 if (stype
== WLAN_FC_STYPE_BEACON
) {
4798 handle_beacon(hapd
, mgmt
, len
, fi
);
4802 if (!is_broadcast_ether_addr(mgmt
->bssid
) &&
4804 /* Invitation responses can be sent with the peer MAC as BSSID */
4805 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
4806 stype
== WLAN_FC_STYPE_ACTION
) &&
4807 #endif /* CONFIG_P2P */
4809 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
4810 #endif /* CONFIG_MESH */
4811 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4812 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
4813 MAC2STR(mgmt
->bssid
));
4818 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
4819 handle_probe_req(hapd
, mgmt
, len
, ssi_signal
);
4823 if ((!is_broadcast_ether_addr(mgmt
->da
) ||
4824 stype
!= WLAN_FC_STYPE_ACTION
) &&
4825 os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4826 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4827 HOSTAPD_LEVEL_DEBUG
,
4828 "MGMT: DA=" MACSTR
" not our address",
4833 if (hapd
->iconf
->track_sta_max_num
)
4834 sta_track_add(hapd
->iface
, mgmt
->sa
, ssi_signal
);
4837 case WLAN_FC_STYPE_AUTH
:
4838 wpa_printf(MSG_DEBUG
, "mgmt::auth");
4839 handle_auth(hapd
, mgmt
, len
, ssi_signal
, 0);
4842 case WLAN_FC_STYPE_ASSOC_REQ
:
4843 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
4844 handle_assoc(hapd
, mgmt
, len
, 0, ssi_signal
);
4847 case WLAN_FC_STYPE_REASSOC_REQ
:
4848 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
4849 handle_assoc(hapd
, mgmt
, len
, 1, ssi_signal
);
4852 case WLAN_FC_STYPE_DISASSOC
:
4853 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
4854 handle_disassoc(hapd
, mgmt
, len
);
4857 case WLAN_FC_STYPE_DEAUTH
:
4858 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
4859 handle_deauth(hapd
, mgmt
, len
);
4862 case WLAN_FC_STYPE_ACTION
:
4863 wpa_printf(MSG_DEBUG
, "mgmt::action");
4864 ret
= handle_action(hapd
, mgmt
, len
, freq
);
4867 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4868 HOSTAPD_LEVEL_DEBUG
,
4869 "unknown mgmt frame subtype %d", stype
);
4877 static void handle_auth_cb(struct hostapd_data
*hapd
,
4878 const struct ieee80211_mgmt
*mgmt
,
4881 u16 auth_alg
, auth_transaction
, status_code
;
4882 struct sta_info
*sta
;
4884 sta
= ap_get_sta(hapd
, mgmt
->da
);
4886 wpa_printf(MSG_DEBUG
, "handle_auth_cb: STA " MACSTR
4892 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
4893 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
4894 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
4897 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4898 HOSTAPD_LEVEL_NOTICE
,
4899 "did not acknowledge authentication response");
4903 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
4904 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
4905 (unsigned long) len
);
4909 if (status_code
== WLAN_STATUS_SUCCESS
&&
4910 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
4911 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
4912 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4913 HOSTAPD_LEVEL_INFO
, "authenticated");
4914 sta
->flags
|= WLAN_STA_AUTH
;
4915 if (sta
->added_unassoc
)
4916 hostapd_set_sta_flags(hapd
, sta
);
4921 if (status_code
!= WLAN_STATUS_SUCCESS
&& sta
->added_unassoc
) {
4922 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4923 sta
->added_unassoc
= 0;
4928 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
4929 struct sta_info
*sta
,
4933 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
4935 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
4938 for (i
= 0; i
< 4; i
++) {
4939 if (ssid
->wep
.key
[i
] &&
4940 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
4941 0, i
== ssid
->wep
.idx
, NULL
, 0,
4942 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
],
4943 i
== ssid
->wep
.idx
?
4944 KEY_FLAG_GROUP_RX_TX_DEFAULT
:
4945 KEY_FLAG_GROUP_RX_TX
)) {
4946 wpa_printf(MSG_WARNING
,
4947 "Could not set WEP keys for WDS interface; %s",
4955 static void handle_assoc_cb(struct hostapd_data
*hapd
,
4956 const struct ieee80211_mgmt
*mgmt
,
4957 size_t len
, int reassoc
, int ok
)
4960 struct sta_info
*sta
;
4963 sta
= ap_get_sta(hapd
, mgmt
->da
);
4965 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
4970 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
4971 sizeof(mgmt
->u
.assoc_resp
))) {
4972 wpa_printf(MSG_INFO
,
4973 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
4974 reassoc
, (unsigned long) len
);
4975 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4980 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
4982 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
4985 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4986 HOSTAPD_LEVEL_DEBUG
,
4987 "did not acknowledge association response");
4988 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
4989 /* The STA is added only in case of SUCCESS */
4990 if (status
== WLAN_STATUS_SUCCESS
)
4991 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4996 if (status
!= WLAN_STATUS_SUCCESS
)
4999 /* Stop previous accounting session, if one is started, and allocate
5000 * new session id for the new session. */
5001 accounting_sta_stop(hapd
, sta
);
5003 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
5005 "associated (aid %d)",
5008 if (sta
->flags
& WLAN_STA_ASSOC
)
5010 sta
->flags
|= WLAN_STA_ASSOC
;
5011 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
5012 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
5013 !hapd
->conf
->osen
) ||
5014 sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
5015 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
5016 sta
->auth_alg
== WLAN_AUTH_FILS_PK
||
5017 sta
->auth_alg
== WLAN_AUTH_FT
) {
5019 * Open, static WEP, FT protocol, or FILS; no separate
5020 * authorization step.
5022 ap_sta_set_authorized(hapd
, sta
, 1);
5026 mlme_reassociate_indication(hapd
, sta
);
5028 mlme_associate_indication(hapd
, sta
);
5030 sta
->sa_query_timed_out
= 0;
5032 if (sta
->eapol_sm
== NULL
) {
5034 * This STA does not use RADIUS server for EAP authentication,
5035 * so bind it to the selected VLAN interface now, since the
5036 * interface selection is not going to change anymore.
5038 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
5040 } else if (sta
->vlan_id
) {
5041 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
5042 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
5046 hostapd_set_sta_flags(hapd
, sta
);
5048 if (!(sta
->flags
& WLAN_STA_WDS
) && sta
->pending_wds_enable
) {
5049 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for STA "
5050 MACSTR
" based on pending request",
5051 MAC2STR(sta
->addr
));
5052 sta
->pending_wds_enable
= 0;
5053 sta
->flags
|= WLAN_STA_WDS
;
5056 if (sta
->flags
& (WLAN_STA_WDS
| WLAN_STA_MULTI_AP
)) {
5058 char ifname_wds
[IFNAMSIZ
+ 1];
5060 wpa_printf(MSG_DEBUG
, "Reenable 4-address WDS mode for STA "
5062 MAC2STR(sta
->addr
), sta
->aid
);
5063 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
5066 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
5069 if (sta
->auth_alg
== WLAN_AUTH_FT
)
5070 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
5072 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
5073 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
5074 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
5077 if ((sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
5078 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
5079 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
5080 fils_set_tk(sta
->wpa_sm
) < 0) {
5081 wpa_printf(MSG_DEBUG
, "FILS: TK configuration failed");
5082 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
5083 WLAN_REASON_UNSPECIFIED
);
5086 #endif /* CONFIG_FILS */
5088 if (sta
->pending_eapol_rx
) {
5089 struct os_reltime now
, age
;
5091 os_get_reltime(&now
);
5092 os_reltime_sub(&now
, &sta
->pending_eapol_rx
->rx_time
, &age
);
5093 if (age
.sec
== 0 && age
.usec
< 200000) {
5094 wpa_printf(MSG_DEBUG
,
5095 "Process pending EAPOL frame that was received from " MACSTR
" just before association notification",
5096 MAC2STR(sta
->addr
));
5099 wpabuf_head(sta
->pending_eapol_rx
->buf
),
5100 wpabuf_len(sta
->pending_eapol_rx
->buf
));
5102 wpabuf_free(sta
->pending_eapol_rx
->buf
);
5103 os_free(sta
->pending_eapol_rx
);
5104 sta
->pending_eapol_rx
= NULL
;
5109 static void handle_deauth_cb(struct hostapd_data
*hapd
,
5110 const struct ieee80211_mgmt
*mgmt
,
5113 struct sta_info
*sta
;
5114 if (is_multicast_ether_addr(mgmt
->da
))
5116 sta
= ap_get_sta(hapd
, mgmt
->da
);
5118 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
5119 " not found", MAC2STR(mgmt
->da
));
5123 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
5124 MAC2STR(sta
->addr
));
5126 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
5127 "deauth", MAC2STR(sta
->addr
));
5129 ap_sta_deauth_cb(hapd
, sta
);
5133 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
5134 const struct ieee80211_mgmt
*mgmt
,
5137 struct sta_info
*sta
;
5138 if (is_multicast_ether_addr(mgmt
->da
))
5140 sta
= ap_get_sta(hapd
, mgmt
->da
);
5142 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
5143 " not found", MAC2STR(mgmt
->da
));
5147 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
5148 MAC2STR(sta
->addr
));
5150 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
5151 "disassoc", MAC2STR(sta
->addr
));
5153 ap_sta_disassoc_cb(hapd
, sta
);
5157 static void handle_action_cb(struct hostapd_data
*hapd
,
5158 const struct ieee80211_mgmt
*mgmt
,
5161 struct sta_info
*sta
;
5162 const struct rrm_measurement_report_element
*report
;
5164 if (is_multicast_ether_addr(mgmt
->da
))
5167 if (len
>= IEEE80211_HDRLEN
+ 6 &&
5168 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5169 mgmt
->u
.action
.u
.vs_public_action
.action
==
5170 WLAN_PA_VENDOR_SPECIFIC
&&
5171 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
5173 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
5175 const u8
*pos
, *end
;
5177 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
5178 end
= ((const u8
*) mgmt
) + len
;
5179 hostapd_dpp_tx_status(hapd
, mgmt
->da
, pos
, end
- pos
, ok
);
5182 if (len
>= IEEE80211_HDRLEN
+ 2 &&
5183 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5184 (mgmt
->u
.action
.u
.public_action
.action
==
5185 WLAN_PA_GAS_INITIAL_REQ
||
5186 mgmt
->u
.action
.u
.public_action
.action
==
5187 WLAN_PA_GAS_COMEBACK_REQ
)) {
5188 const u8
*pos
, *end
;
5190 pos
= mgmt
->u
.action
.u
.public_action
.variable
;
5191 end
= ((const u8
*) mgmt
) + len
;
5192 gas_query_ap_tx_status(hapd
->gas
, mgmt
->da
, pos
, end
- pos
, ok
);
5195 #endif /* CONFIG_DPP */
5196 sta
= ap_get_sta(hapd
, mgmt
->da
);
5198 wpa_printf(MSG_DEBUG
, "handle_action_cb: STA " MACSTR
5199 " not found", MAC2STR(mgmt
->da
));
5203 if (len
< 24 + 5 + sizeof(*report
))
5205 report
= (const struct rrm_measurement_report_element
*)
5206 &mgmt
->u
.action
.u
.rrm
.variable
[2];
5207 if (mgmt
->u
.action
.category
== WLAN_ACTION_RADIO_MEASUREMENT
&&
5208 mgmt
->u
.action
.u
.rrm
.action
== WLAN_RRM_RADIO_MEASUREMENT_REQUEST
&&
5209 report
->eid
== WLAN_EID_MEASURE_REQUEST
&&
5211 report
->type
== MEASURE_TYPE_BEACON
)
5212 hostapd_rrm_beacon_req_tx_status(hapd
, mgmt
, len
, ok
);
5217 * ieee802_11_mgmt_cb - Process management frame TX status callback
5218 * @hapd: hostapd BSS data structure (the BSS from which the management frame
5220 * @buf: management frame data (starting from IEEE 802.11 header)
5221 * @len: length of frame data in octets
5222 * @stype: management frame subtype from frame control field
5223 * @ok: Whether the frame was ACK'ed
5225 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
5228 const struct ieee80211_mgmt
*mgmt
;
5229 mgmt
= (const struct ieee80211_mgmt
*) buf
;
5231 #ifdef CONFIG_TESTING_OPTIONS
5232 if (hapd
->ext_mgmt_frame_handling
) {
5233 size_t hex_len
= 2 * len
+ 1;
5234 char *hex
= os_malloc(hex_len
);
5237 wpa_snprintf_hex(hex
, hex_len
, buf
, len
);
5238 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
5239 "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
5245 #endif /* CONFIG_TESTING_OPTIONS */
5248 case WLAN_FC_STYPE_AUTH
:
5249 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
5250 handle_auth_cb(hapd
, mgmt
, len
, ok
);
5252 case WLAN_FC_STYPE_ASSOC_RESP
:
5253 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
5254 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
5256 case WLAN_FC_STYPE_REASSOC_RESP
:
5257 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
5258 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
5260 case WLAN_FC_STYPE_PROBE_RESP
:
5261 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb ok=%d", ok
);
5263 case WLAN_FC_STYPE_DEAUTH
:
5264 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
5265 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
5267 case WLAN_FC_STYPE_DISASSOC
:
5268 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
5269 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
5271 case WLAN_FC_STYPE_ACTION
:
5272 wpa_printf(MSG_DEBUG
, "mgmt::action cb ok=%d", ok
);
5273 handle_action_cb(hapd
, mgmt
, len
, ok
);
5276 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
5282 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
5289 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
5290 char *buf
, size_t buflen
)
5297 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
5298 const u8
*buf
, size_t len
, int ack
)
5300 struct sta_info
*sta
;
5301 struct hostapd_iface
*iface
= hapd
->iface
;
5303 sta
= ap_get_sta(hapd
, addr
);
5304 if (sta
== NULL
&& iface
->num_bss
> 1) {
5306 for (j
= 0; j
< iface
->num_bss
; j
++) {
5307 hapd
= iface
->bss
[j
];
5308 sta
= ap_get_sta(hapd
, addr
);
5313 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
5315 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
5316 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
5317 "activity poll", MAC2STR(sta
->addr
),
5318 ack
? "ACKed" : "did not ACK");
5320 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5323 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
5327 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
5328 const u8
*data
, size_t len
, int ack
)
5330 struct sta_info
*sta
;
5331 struct hostapd_iface
*iface
= hapd
->iface
;
5333 sta
= ap_get_sta(hapd
, dst
);
5334 if (sta
== NULL
&& iface
->num_bss
> 1) {
5336 for (j
= 0; j
< iface
->num_bss
; j
++) {
5337 hapd
= iface
->bss
[j
];
5338 sta
= ap_get_sta(hapd
, dst
);
5343 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
5344 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
5345 MACSTR
" that is not currently associated",
5350 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
5354 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
5356 struct sta_info
*sta
;
5357 struct hostapd_iface
*iface
= hapd
->iface
;
5359 sta
= ap_get_sta(hapd
, addr
);
5360 if (sta
== NULL
&& iface
->num_bss
> 1) {
5362 for (j
= 0; j
< iface
->num_bss
; j
++) {
5363 hapd
= iface
->bss
[j
];
5364 sta
= ap_get_sta(hapd
, addr
);
5371 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_POLL_OK MACSTR
,
5372 MAC2STR(sta
->addr
));
5373 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
5376 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
5377 "activity poll", MAC2STR(sta
->addr
));
5378 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5382 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
5385 struct sta_info
*sta
;
5387 sta
= ap_get_sta(hapd
, src
);
5389 ((sta
->flags
& WLAN_STA_ASSOC
) ||
5390 ((sta
->flags
& WLAN_STA_ASSOC_REQ_OK
) && wds
))) {
5391 if (!hapd
->conf
->wds_sta
)
5394 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
)) ==
5395 WLAN_STA_ASSOC_REQ_OK
) {
5396 wpa_printf(MSG_DEBUG
,
5397 "Postpone 4-address WDS mode enabling for STA "
5398 MACSTR
" since TX status for AssocResp is not yet known",
5399 MAC2STR(sta
->addr
));
5400 sta
->pending_wds_enable
= 1;
5404 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
5406 char ifname_wds
[IFNAMSIZ
+ 1];
5408 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
5409 "STA " MACSTR
" (aid %u)",
5410 MAC2STR(sta
->addr
), sta
->aid
);
5411 sta
->flags
|= WLAN_STA_WDS
;
5412 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
5413 sta
->addr
, sta
->aid
, 1);
5415 hostapd_set_wds_encryption(hapd
, sta
,
5421 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
5422 MACSTR
, MAC2STR(src
));
5423 if (is_multicast_ether_addr(src
) || is_zero_ether_addr(src
) ||
5424 os_memcmp(src
, hapd
->own_addr
, ETH_ALEN
) == 0) {
5425 /* Broadcast bit set in SA or unexpected SA?! Ignore the frame
5430 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
5431 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
5432 "already been sent, but no TX status yet known - "
5433 "ignore Class 3 frame issue with " MACSTR
,
5438 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
5439 hostapd_drv_sta_disassoc(
5441 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5443 hostapd_drv_sta_deauth(
5445 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5449 #endif /* CONFIG_NATIVE_WINDOWS */