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 crypto_bignum_deinit(sta
->sae
->peer_commit_scalar_accepted
, 0);
843 sta
->sae
->peer_commit_scalar_accepted
= sta
->sae
->peer_commit_scalar
;
844 sta
->sae
->peer_commit_scalar
= NULL
;
845 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
846 sta
->sae
->pmk
, sta
->sae
->pmkid
);
847 sae_sme_send_external_auth_status(hapd
, sta
, WLAN_STATUS_SUCCESS
);
851 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
852 const u8
*bssid
, u16 auth_transaction
, u16 status_code
,
853 int allow_reuse
, int *sta_removed
)
859 if (auth_transaction
!= 1 && auth_transaction
!= 2)
860 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
862 wpa_printf(MSG_DEBUG
, "SAE: Peer " MACSTR
" state=%s auth_trans=%u",
863 MAC2STR(sta
->addr
), sae_state_txt(sta
->sae
->state
),
865 switch (sta
->sae
->state
) {
867 if (auth_transaction
== 1) {
869 sta
->sae
->tmp
->h2e
= status_code
==
870 WLAN_STATUS_SAE_HASH_TO_ELEMENT
;
871 ret
= auth_sae_send_commit(hapd
, sta
, bssid
,
872 !allow_reuse
, status_code
);
875 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
877 if (sae_process_commit(sta
->sae
) < 0)
878 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
881 * In mesh case, both Commit and Confirm are sent
882 * immediately. In infrastructure BSS, by default, only
883 * a single Authentication frame (Commit) is expected
884 * from the AP here and the second one (Confirm) will
885 * be sent once the STA has sent its second
886 * Authentication frame (Confirm). This behavior can be
887 * overridden with explicit configuration so that the
888 * infrastructure BSS case sends both frames together.
890 if ((hapd
->conf
->mesh
& MESH_ENABLED
) ||
891 hapd
->conf
->sae_confirm_immediate
) {
893 * Send both Commit and Confirm immediately
894 * based on SAE finite state machine
895 * Nothing -> Confirm transition.
897 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
900 sae_set_state(sta
, SAE_CONFIRMED
,
901 "Sent Confirm (mesh)");
904 * For infrastructure BSS, send only the Commit
905 * message now to get alternating sequence of
906 * Authentication frames between the AP and STA.
907 * Confirm will be sent in
908 * Committed -> Confirmed/Accepted transition
909 * when receiving Confirm from STA.
913 sae_set_retransmit_timer(hapd
, sta
);
915 hostapd_logger(hapd
, sta
->addr
,
916 HOSTAPD_MODULE_IEEE80211
,
918 "SAE confirm before commit");
922 sae_clear_retransmit_timer(hapd
, sta
);
923 if (auth_transaction
== 1) {
924 if (sae_process_commit(sta
->sae
) < 0)
925 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
927 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
930 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
932 sae_set_retransmit_timer(hapd
, sta
);
933 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
935 * In mesh case, follow SAE finite state machine and
936 * send Commit now, if sync count allows.
938 if (sae_check_big_sync(hapd
, sta
))
939 return WLAN_STATUS_SUCCESS
;
942 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 0,
947 sae_set_retransmit_timer(hapd
, sta
);
950 * For instructure BSS, send the postponed Confirm from
951 * Nothing -> Confirmed transition that was reduced to
952 * Nothing -> Committed above.
954 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
958 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
961 * Since this was triggered on Confirm RX, run another
962 * step to get to Accepted without waiting for
965 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
,
966 WLAN_STATUS_SUCCESS
, 0, sta_removed
);
970 sae_clear_retransmit_timer(hapd
, sta
);
971 if (auth_transaction
== 1) {
972 if (sae_check_big_sync(hapd
, sta
))
973 return WLAN_STATUS_SUCCESS
;
976 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1,
981 if (sae_process_commit(sta
->sae
) < 0)
982 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
984 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
988 sae_set_retransmit_timer(hapd
, sta
);
990 sta
->sae
->send_confirm
= 0xffff;
991 sae_accept_sta(hapd
, sta
);
995 if (auth_transaction
== 1 &&
996 (hapd
->conf
->mesh
& MESH_ENABLED
)) {
997 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
998 ") doing reauthentication",
1000 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
1001 ap_free_sta(hapd
, sta
);
1003 } else if (auth_transaction
== 1) {
1004 wpa_printf(MSG_DEBUG
, "SAE: Start reauthentication");
1005 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1,
1009 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
1011 if (sae_process_commit(sta
->sae
) < 0)
1012 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1014 sae_set_retransmit_timer(hapd
, sta
);
1016 if (sae_check_big_sync(hapd
, sta
))
1017 return WLAN_STATUS_SUCCESS
;
1020 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
1021 sae_clear_temp_data(sta
->sae
);
1027 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
1029 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1031 return WLAN_STATUS_SUCCESS
;
1035 static void sae_pick_next_group(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1037 struct sae_data
*sae
= sta
->sae
;
1038 int i
, *groups
= hapd
->conf
->sae_groups
;
1039 int default_groups
[] = { 19, 0 };
1041 if (sae
->state
!= SAE_COMMITTED
)
1044 wpa_printf(MSG_DEBUG
, "SAE: Previously selected group: %d", sae
->group
);
1047 groups
= default_groups
;
1048 for (i
= 0; groups
[i
] > 0; i
++) {
1049 if (sae
->group
== groups
[i
])
1053 if (groups
[i
] <= 0) {
1054 wpa_printf(MSG_DEBUG
,
1055 "SAE: Previously selected group not found from the current configuration");
1061 if (groups
[i
] <= 0) {
1062 wpa_printf(MSG_DEBUG
,
1063 "SAE: No alternative group enabled");
1067 if (sae_set_group(sae
, groups
[i
]) < 0)
1072 wpa_printf(MSG_DEBUG
, "SAE: Selected new group: %d", groups
[i
]);
1076 static int sae_status_success(struct hostapd_data
*hapd
, u16 status_code
)
1078 int sae_pwe
= hapd
->conf
->sae_pwe
;
1081 id_in_use
= hostapd_sae_pw_id_in_use(hapd
->conf
);
1084 else if (id_in_use
== 1 && sae_pwe
== 0)
1087 return (sae_pwe
== 0 &&
1088 status_code
== WLAN_STATUS_SUCCESS
) ||
1090 status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
) ||
1092 (status_code
== WLAN_STATUS_SUCCESS
||
1093 status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
));
1097 static int sae_is_group_enabled(struct hostapd_data
*hapd
, int group
)
1099 int *groups
= hapd
->conf
->sae_groups
;
1100 int default_groups
[] = { 19, 0 };
1104 groups
= default_groups
;
1106 for (i
= 0; groups
[i
] > 0; i
++) {
1107 if (groups
[i
] == group
)
1115 static int check_sae_rejected_groups(struct hostapd_data
*hapd
,
1116 const struct wpabuf
*groups
)
1124 pos
= wpabuf_head(groups
);
1125 count
= wpabuf_len(groups
) / 2;
1126 for (i
= 0; i
< count
; i
++) {
1130 group
= WPA_GET_LE16(pos
);
1132 enabled
= sae_is_group_enabled(hapd
, group
);
1133 wpa_printf(MSG_DEBUG
, "SAE: Rejected group %u is %s",
1134 group
, enabled
? "enabled" : "disabled");
1143 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1144 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1145 u16 auth_transaction
, u16 status_code
)
1147 int resp
= WLAN_STATUS_SUCCESS
;
1148 struct wpabuf
*data
= NULL
;
1149 int *groups
= hapd
->conf
->sae_groups
;
1150 int default_groups
[] = { 19, 0 };
1151 const u8
*pos
, *end
;
1152 int sta_removed
= 0;
1155 groups
= default_groups
;
1157 #ifdef CONFIG_TESTING_OPTIONS
1158 if (hapd
->conf
->sae_reflection_attack
&& auth_transaction
== 1) {
1159 wpa_printf(MSG_DEBUG
, "SAE: TESTING - reflection attack");
1160 pos
= mgmt
->u
.auth
.variable
;
1161 end
= ((const u8
*) mgmt
) + len
;
1162 send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1163 auth_transaction
, resp
, pos
, end
- pos
,
1164 "auth-sae-reflection-attack");
1168 if (hapd
->conf
->sae_commit_override
&& auth_transaction
== 1) {
1169 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
1170 send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1171 auth_transaction
, resp
,
1172 wpabuf_head(hapd
->conf
->sae_commit_override
),
1173 wpabuf_len(hapd
->conf
->sae_commit_override
),
1174 "sae-commit-override");
1177 #endif /* CONFIG_TESTING_OPTIONS */
1179 if (auth_transaction
!= 1 ||
1180 !sae_status_success(hapd
, status_code
)) {
1181 wpa_printf(MSG_DEBUG
, "SAE: Unexpected Status Code %u",
1183 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1186 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
1191 sae_set_state(sta
, SAE_NOTHING
, "Init");
1195 if (sta
->mesh_sae_pmksa_caching
) {
1196 wpa_printf(MSG_DEBUG
,
1197 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
1198 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
1199 sta
->mesh_sae_pmksa_caching
= 0;
1202 if (auth_transaction
== 1) {
1203 const u8
*token
= NULL
;
1204 size_t token_len
= 0;
1205 int allow_reuse
= 0;
1207 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1208 HOSTAPD_LEVEL_DEBUG
,
1209 "start SAE authentication (RX commit, status=%u (%s))",
1210 status_code
, status2str(status_code
));
1212 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1213 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
1215 pos
= mgmt
->u
.auth
.variable
;
1216 end
= ((const u8
*) mgmt
) + len
;
1217 if (pos
+ sizeof(le16
) > end
) {
1218 wpa_printf(MSG_ERROR
,
1219 "SAE: Too short anti-clogging token request");
1220 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1223 resp
= sae_group_allowed(sta
->sae
, groups
,
1225 if (resp
!= WLAN_STATUS_SUCCESS
) {
1226 wpa_printf(MSG_ERROR
,
1227 "SAE: Invalid group in anti-clogging token request");
1230 pos
+= sizeof(le16
);
1232 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
1233 sta
->sae
->tmp
->anti_clogging_token
=
1234 wpabuf_alloc_copy(pos
, end
- pos
);
1235 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
1236 wpa_printf(MSG_ERROR
,
1237 "SAE: Failed to alloc for anti-clogging token");
1238 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1243 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
1244 * is 76, a new Commit Message shall be constructed
1245 * with the Anti-Clogging Token from the received
1246 * Authentication frame, and the commit-scalar and
1247 * COMMIT-ELEMENT previously sent.
1249 resp
= auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0,
1251 if (resp
!= WLAN_STATUS_SUCCESS
) {
1252 wpa_printf(MSG_ERROR
,
1253 "SAE: Failed to send commit message");
1256 sae_set_state(sta
, SAE_COMMITTED
,
1257 "Sent Commit (anti-clogging token case in mesh)");
1259 sae_set_retransmit_timer(hapd
, sta
);
1263 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1265 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1267 wpa_printf(MSG_DEBUG
,
1268 "SAE: Peer did not accept our SAE group");
1269 sae_pick_next_group(hapd
, sta
);
1273 if (!sae_status_success(hapd
, status_code
))
1276 if (!(hapd
->conf
->mesh
& MESH_ENABLED
) &&
1277 sta
->sae
->state
== SAE_COMMITTED
) {
1278 /* This is needed in the infrastructure BSS case to
1279 * address a sequence where a STA entry may remain in
1280 * hostapd across two attempts to do SAE authentication
1281 * by the same STA. The second attempt may end up trying
1282 * to use a different group and that would not be
1283 * allowed if we remain in Committed state with the
1284 * previously set parameters. */
1285 pos
= mgmt
->u
.auth
.variable
;
1286 end
= ((const u8
*) mgmt
) + len
;
1287 if (end
- pos
>= (int) sizeof(le16
) &&
1288 sae_group_allowed(sta
->sae
, groups
,
1289 WPA_GET_LE16(pos
)) ==
1290 WLAN_STATUS_SUCCESS
) {
1291 /* Do not waste resources deriving the same PWE
1292 * again since the same group is reused. */
1293 sae_set_state(sta
, SAE_NOTHING
,
1294 "Allow previous PWE to be reused");
1297 sae_set_state(sta
, SAE_NOTHING
,
1298 "Clear existing state to allow restart");
1299 sae_clear_data(sta
->sae
);
1303 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
1304 ((const u8
*) mgmt
) + len
-
1305 mgmt
->u
.auth
.variable
, &token
,
1306 &token_len
, groups
, status_code
==
1307 WLAN_STATUS_SAE_HASH_TO_ELEMENT
);
1308 if (resp
== SAE_SILENTLY_DISCARD
) {
1309 wpa_printf(MSG_DEBUG
,
1310 "SAE: Drop commit message from " MACSTR
" due to reflection attack",
1311 MAC2STR(sta
->addr
));
1315 if (resp
== WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
) {
1316 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
1317 WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER
1318 MACSTR
, MAC2STR(sta
->addr
));
1319 sae_clear_retransmit_timer(hapd
, sta
);
1320 sae_set_state(sta
, SAE_NOTHING
,
1321 "Unknown Password Identifier");
1325 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
1327 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
1328 "incorrect token from " MACSTR
,
1329 MAC2STR(sta
->addr
));
1330 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1334 if (resp
!= WLAN_STATUS_SUCCESS
)
1337 if (sta
->sae
->tmp
&&
1338 check_sae_rejected_groups(
1339 hapd
, sta
->sae
->tmp
->peer_rejected_groups
)) {
1340 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1344 if (!token
&& use_sae_anti_clogging(hapd
) && !allow_reuse
) {
1347 wpa_printf(MSG_DEBUG
,
1348 "SAE: Request anti-clogging token from "
1349 MACSTR
, MAC2STR(sta
->addr
));
1351 h2e
= sta
->sae
->tmp
->h2e
;
1352 if (status_code
== WLAN_STATUS_SAE_HASH_TO_ELEMENT
)
1354 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
1356 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
1357 if (hapd
->conf
->mesh
& MESH_ENABLED
)
1358 sae_set_state(sta
, SAE_NOTHING
,
1359 "Request anti-clogging token case in mesh");
1363 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1364 status_code
, allow_reuse
, &sta_removed
);
1365 } else if (auth_transaction
== 2) {
1366 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1367 HOSTAPD_LEVEL_DEBUG
,
1368 "SAE authentication (RX confirm, status=%u (%s))",
1369 status_code
, status2str(status_code
));
1370 if (status_code
!= WLAN_STATUS_SUCCESS
)
1372 if (sta
->sae
->state
>= SAE_CONFIRMED
||
1373 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
1376 u16 peer_send_confirm
;
1378 var
= mgmt
->u
.auth
.variable
;
1379 var_len
= ((u8
*) mgmt
) + len
- mgmt
->u
.auth
.variable
;
1381 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1385 peer_send_confirm
= WPA_GET_LE16(var
);
1387 if (sta
->sae
->state
== SAE_ACCEPTED
&&
1388 (peer_send_confirm
<= sta
->sae
->rc
||
1389 peer_send_confirm
== 0xffff)) {
1390 wpa_printf(MSG_DEBUG
,
1391 "SAE: Silently ignore unexpected Confirm from peer "
1393 " (peer-send-confirm=%u Rc=%u)",
1395 peer_send_confirm
, sta
->sae
->rc
);
1399 if (sae_check_confirm(sta
->sae
, var
, var_len
) < 0) {
1400 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1403 sta
->sae
->rc
= peer_send_confirm
;
1405 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1406 status_code
, 0, &sta_removed
);
1408 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1409 HOSTAPD_LEVEL_DEBUG
,
1410 "unexpected SAE authentication transaction %u (status=%u (%s))",
1411 auth_transaction
, status_code
,
1412 status2str(status_code
));
1413 if (status_code
!= WLAN_STATUS_SUCCESS
)
1415 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1419 if (!sta_removed
&& resp
!= WLAN_STATUS_SUCCESS
) {
1420 pos
= mgmt
->u
.auth
.variable
;
1421 end
= ((const u8
*) mgmt
) + len
;
1423 /* Copy the Finite Cyclic Group field from the request if we
1424 * rejected it as unsupported group. */
1425 if (resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1426 !data
&& end
- pos
>= 2)
1427 data
= wpabuf_alloc_copy(pos
, 2);
1429 sae_sme_send_external_auth_status(hapd
, sta
, resp
);
1430 send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1431 auth_transaction
, resp
,
1432 data
? wpabuf_head(data
) : (u8
*) "",
1433 data
? wpabuf_len(data
) : 0, "auth-sae");
1437 if (!sta_removed
&& sta
->added_unassoc
&&
1438 (resp
!= WLAN_STATUS_SUCCESS
||
1439 status_code
!= WLAN_STATUS_SUCCESS
)) {
1440 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1441 sta
->added_unassoc
= 0;
1448 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1449 * @hapd: BSS data for the device initiating the authentication
1450 * @sta: the peer to which commit authentication frame is sent
1452 * This function implements Init event handling (IEEE Std 802.11-2012,
1453 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1454 * sta->sae structure should be initialized appropriately via a call to
1455 * sae_prepare_commit().
1457 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1461 if (!sta
->sae
|| !sta
->sae
->tmp
)
1464 if (sta
->sae
->state
!= SAE_NOTHING
)
1467 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0, -1);
1471 sae_set_state(sta
, SAE_COMMITTED
, "Init and sent commit");
1473 sae_set_retransmit_timer(hapd
, sta
);
1479 void auth_sae_process_commit(void *eloop_ctx
, void *user_ctx
)
1481 struct hostapd_data
*hapd
= eloop_ctx
;
1482 struct hostapd_sae_commit_queue
*q
;
1483 unsigned int queue_len
;
1485 q
= dl_list_first(&hapd
->sae_commit_queue
,
1486 struct hostapd_sae_commit_queue
, list
);
1489 wpa_printf(MSG_DEBUG
,
1490 "SAE: Process next available message from queue");
1491 dl_list_del(&q
->list
);
1492 handle_auth(hapd
, (const struct ieee80211_mgmt
*) q
->msg
, q
->len
,
1496 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1498 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1499 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1504 static void auth_sae_queue(struct hostapd_data
*hapd
,
1505 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1508 struct hostapd_sae_commit_queue
*q
, *q2
;
1509 unsigned int queue_len
;
1510 const struct ieee80211_mgmt
*mgmt2
;
1512 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1513 if (queue_len
>= 15) {
1514 wpa_printf(MSG_DEBUG
,
1515 "SAE: No more room in message queue - drop the new frame from "
1516 MACSTR
, MAC2STR(mgmt
->sa
));
1520 wpa_printf(MSG_DEBUG
, "SAE: Queue Authentication message from "
1521 MACSTR
" for processing (queue_len %u)", MAC2STR(mgmt
->sa
),
1523 q
= os_zalloc(sizeof(*q
) + len
);
1528 os_memcpy(q
->msg
, mgmt
, len
);
1530 /* Check whether there is already a queued Authentication frame from the
1531 * same station with the same transaction number and if so, replace that
1532 * queue entry with the new one. This avoids issues with a peer that
1533 * sends multiple times (e.g., due to frequent SAE retries). There is no
1534 * point in us trying to process the old attempts after a new one has
1535 * obsoleted them. */
1536 dl_list_for_each(q2
, &hapd
->sae_commit_queue
,
1537 struct hostapd_sae_commit_queue
, list
) {
1538 mgmt2
= (const struct ieee80211_mgmt
*) q2
->msg
;
1539 if (os_memcmp(mgmt
->sa
, mgmt2
->sa
, ETH_ALEN
) == 0 &&
1540 mgmt
->u
.auth
.auth_transaction
==
1541 mgmt2
->u
.auth
.auth_transaction
) {
1542 wpa_printf(MSG_DEBUG
,
1543 "SAE: Replace queued message from same STA with same transaction number");
1544 dl_list_add(&q2
->list
, &q
->list
);
1545 dl_list_del(&q2
->list
);
1551 /* No pending identical entry, so add to the end of the queue */
1552 dl_list_add_tail(&hapd
->sae_commit_queue
, &q
->list
);
1555 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1557 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1562 static int auth_sae_queued_addr(struct hostapd_data
*hapd
, const u8
*addr
)
1564 struct hostapd_sae_commit_queue
*q
;
1565 const struct ieee80211_mgmt
*mgmt
;
1567 dl_list_for_each(q
, &hapd
->sae_commit_queue
,
1568 struct hostapd_sae_commit_queue
, list
) {
1569 mgmt
= (const struct ieee80211_mgmt
*) q
->msg
;
1570 if (os_memcmp(addr
, mgmt
->sa
, ETH_ALEN
) == 0)
1577 #endif /* CONFIG_SAE */
1580 static u16
wpa_res_to_status_code(int res
)
1582 if (res
== WPA_INVALID_GROUP
)
1583 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1584 if (res
== WPA_INVALID_PAIRWISE
)
1585 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1586 if (res
== WPA_INVALID_AKMP
)
1587 return WLAN_STATUS_AKMP_NOT_VALID
;
1588 if (res
== WPA_ALLOC_FAIL
)
1589 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1590 if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1591 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1592 if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1593 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
1594 if (res
== WPA_INVALID_MDIE
)
1595 return WLAN_STATUS_INVALID_MDIE
;
1596 if (res
== WPA_INVALID_PMKID
)
1597 return WLAN_STATUS_INVALID_PMKID
;
1598 if (res
!= WPA_IE_OK
)
1599 return WLAN_STATUS_INVALID_IE
;
1600 return WLAN_STATUS_SUCCESS
;
1606 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1607 struct sta_info
*sta
, u16 resp
,
1608 struct wpabuf
*data
, int pub
);
1610 void handle_auth_fils(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1611 const u8
*pos
, size_t len
, u16 auth_alg
,
1612 u16 auth_transaction
, u16 status_code
,
1613 void (*cb
)(struct hostapd_data
*hapd
,
1614 struct sta_info
*sta
, u16 resp
,
1615 struct wpabuf
*data
, int pub
))
1617 u16 resp
= WLAN_STATUS_SUCCESS
;
1619 struct ieee802_11_elems elems
;
1621 struct wpa_ie_data rsn
;
1622 struct rsn_pmksa_cache_entry
*pmksa
= NULL
;
1624 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
1629 wpa_hexdump(MSG_DEBUG
, "FILS: Authentication frame fields",
1633 #ifdef CONFIG_FILS_SK_PFS
1634 if (auth_alg
== WLAN_AUTH_FILS_SK_PFS
) {
1639 /* Using FILS PFS */
1641 /* Finite Cyclic Group */
1642 if (end
- pos
< 2) {
1643 wpa_printf(MSG_DEBUG
,
1644 "FILS: No room for Finite Cyclic Group");
1645 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1648 group
= WPA_GET_LE16(pos
);
1650 if (group
!= hapd
->conf
->fils_dh_group
) {
1651 wpa_printf(MSG_DEBUG
,
1652 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1653 group
, hapd
->conf
->fils_dh_group
);
1654 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1658 crypto_ecdh_deinit(sta
->fils_ecdh
);
1659 sta
->fils_ecdh
= crypto_ecdh_init(group
);
1660 if (!sta
->fils_ecdh
) {
1661 wpa_printf(MSG_INFO
,
1662 "FILS: Could not initialize ECDH with group %d",
1664 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1668 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1670 wpa_printf(MSG_DEBUG
,
1671 "FILS: Failed to derive ECDH public key");
1672 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1675 elem_len
= wpabuf_len(pub
);
1679 if ((size_t) (end
- pos
) < elem_len
) {
1680 wpa_printf(MSG_DEBUG
, "FILS: No room for Element");
1681 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1685 wpabuf_free(sta
->fils_g_sta
);
1686 sta
->fils_g_sta
= wpabuf_alloc_copy(pos
, elem_len
);
1687 wpabuf_clear_free(sta
->fils_dh_ss
);
1688 sta
->fils_dh_ss
= crypto_ecdh_set_peerkey(sta
->fils_ecdh
, 1,
1690 if (!sta
->fils_dh_ss
) {
1691 wpa_printf(MSG_DEBUG
, "FILS: ECDH operation failed");
1692 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1695 wpa_hexdump_buf_key(MSG_DEBUG
, "FILS: DH_SS", sta
->fils_dh_ss
);
1698 crypto_ecdh_deinit(sta
->fils_ecdh
);
1699 sta
->fils_ecdh
= NULL
;
1700 wpabuf_clear_free(sta
->fils_dh_ss
);
1701 sta
->fils_dh_ss
= NULL
;
1703 #endif /* CONFIG_FILS_SK_PFS */
1705 wpa_hexdump(MSG_DEBUG
, "FILS: Remaining IEs", pos
, end
- pos
);
1706 if (ieee802_11_parse_elems(pos
, end
- pos
, &elems
, 1) == ParseFailed
) {
1707 wpa_printf(MSG_DEBUG
, "FILS: Could not parse elements");
1708 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1713 wpa_hexdump(MSG_DEBUG
, "FILS: RSN element",
1714 elems
.rsn_ie
, elems
.rsn_ie_len
);
1715 if (!elems
.rsn_ie
||
1716 wpa_parse_wpa_ie_rsn(elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1718 wpa_printf(MSG_DEBUG
, "FILS: No valid RSN element");
1719 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1724 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
1727 wpa_printf(MSG_DEBUG
,
1728 "FILS: Failed to initialize RSN state machine");
1729 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1733 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1735 elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1736 elems
.rsnxe
? elems
.rsnxe
- 2 : NULL
,
1737 elems
.rsnxe
? elems
.rsnxe_len
+ 2 : 0,
1738 elems
.mdie
, elems
.mdie_len
, NULL
, 0);
1739 resp
= wpa_res_to_status_code(res
);
1740 if (resp
!= WLAN_STATUS_SUCCESS
)
1743 if (!elems
.fils_nonce
) {
1744 wpa_printf(MSG_DEBUG
, "FILS: No FILS Nonce field");
1745 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1748 wpa_hexdump(MSG_DEBUG
, "FILS: SNonce", elems
.fils_nonce
,
1750 os_memcpy(sta
->fils_snonce
, elems
.fils_nonce
, FILS_NONCE_LEN
);
1753 if (rsn
.pmkid
&& rsn
.num_pmkid
> 0) {
1757 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID List",
1758 rsn
.pmkid
, rsn
.num_pmkid
* PMKID_LEN
);
1761 num
= rsn
.num_pmkid
;
1763 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID", pmkid
, PMKID_LEN
);
1764 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
,
1768 pmksa
= wpa_auth_pmksa_get_fils_cache_id(hapd
->wpa_auth
,
1777 if (pmksa
&& wpa_auth_sta_key_mgmt(sta
->wpa_sm
) != pmksa
->akmp
) {
1778 wpa_printf(MSG_DEBUG
,
1779 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1780 wpa_auth_sta_key_mgmt(sta
->wpa_sm
), pmksa
->akmp
);
1784 wpa_printf(MSG_DEBUG
, "FILS: Found matching PMKSA cache entry");
1787 if (!elems
.fils_session
) {
1788 wpa_printf(MSG_DEBUG
, "FILS: No FILS Session element");
1789 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1792 wpa_hexdump(MSG_DEBUG
, "FILS: FILS Session", elems
.fils_session
,
1794 os_memcpy(sta
->fils_session
, elems
.fils_session
, FILS_SESSION_LEN
);
1796 /* FILS Wrapped Data */
1797 if (elems
.fils_wrapped_data
) {
1798 wpa_hexdump(MSG_DEBUG
, "FILS: Wrapped Data",
1799 elems
.fils_wrapped_data
,
1800 elems
.fils_wrapped_data_len
);
1802 #ifndef CONFIG_NO_RADIUS
1803 if (!sta
->eapol_sm
) {
1805 ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1807 wpa_printf(MSG_DEBUG
,
1808 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
1809 ieee802_1x_encapsulate_radius(
1810 hapd
, sta
, elems
.fils_wrapped_data
,
1811 elems
.fils_wrapped_data_len
);
1812 sta
->fils_pending_cb
= cb
;
1813 wpa_printf(MSG_DEBUG
,
1814 "FILS: Will send Authentication frame once the response from authentication server is available");
1815 sta
->flags
|= WLAN_STA_PENDING_FILS_ERP
;
1816 /* Calculate pending PMKID here so that we do not need
1817 * to maintain a copy of the EAP-Initiate/Reauth
1819 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1820 elems
.fils_wrapped_data
,
1821 elems
.fils_wrapped_data_len
,
1822 sta
->fils_erp_pmkid
) == 0)
1823 sta
->fils_erp_pmkid_set
= 1;
1825 #else /* CONFIG_NO_RADIUS */
1826 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1828 #endif /* CONFIG_NO_RADIUS */
1834 struct wpabuf
*data
;
1837 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, pmksa
, NULL
,
1840 wpa_printf(MSG_DEBUG
,
1841 "%s: prepare_auth_resp_fils() returned failure",
1845 cb(hapd
, sta
, resp
, data
, pub
);
1850 static struct wpabuf
*
1851 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
1852 struct sta_info
*sta
, u16
*resp
,
1853 struct rsn_pmksa_cache_entry
*pmksa
,
1854 struct wpabuf
*erp_resp
,
1855 const u8
*msk
, size_t msk_len
,
1858 u8 fils_nonce
[FILS_NONCE_LEN
];
1860 struct wpabuf
*data
= NULL
;
1863 const u8
*pmk
= NULL
;
1865 u8 pmk_buf
[PMK_LEN_MAX
];
1866 struct wpabuf
*pub
= NULL
;
1868 if (*resp
!= WLAN_STATUS_SUCCESS
)
1871 ie
= wpa_auth_get_wpa_ie(hapd
->wpa_auth
, &ielen
);
1873 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1878 /* Add PMKID of the selected PMKSA into RSNE */
1879 ie_buf
= os_malloc(ielen
+ 2 + 2 + PMKID_LEN
);
1881 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1885 os_memcpy(ie_buf
, ie
, ielen
);
1886 if (wpa_insert_pmkid(ie_buf
, &ielen
, pmksa
->pmkid
) < 0) {
1887 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1893 if (random_get_bytes(fils_nonce
, FILS_NONCE_LEN
) < 0) {
1894 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1897 wpa_hexdump(MSG_DEBUG
, "RSN: Generated FILS Nonce",
1898 fils_nonce
, FILS_NONCE_LEN
);
1900 #ifdef CONFIG_FILS_SK_PFS
1901 if (sta
->fils_dh_ss
&& sta
->fils_ecdh
) {
1902 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1904 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1908 #endif /* CONFIG_FILS_SK_PFS */
1910 data
= wpabuf_alloc(1000 + ielen
+ (pub
? wpabuf_len(pub
) : 0));
1912 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1917 #ifdef CONFIG_FILS_SK_PFS
1919 /* Finite Cyclic Group */
1920 wpabuf_put_le16(data
, hapd
->conf
->fils_dh_group
);
1923 wpabuf_put_buf(data
, pub
);
1925 #endif /* CONFIG_FILS_SK_PFS */
1928 wpabuf_put_data(data
, ie
, ielen
);
1930 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1932 #ifdef CONFIG_IEEE80211R_AP
1933 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) {
1934 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1936 int use_sha384
= wpa_key_mgmt_sha384(
1937 wpa_auth_sta_key_mgmt(sta
->wpa_sm
));
1939 res
= wpa_auth_write_fte(hapd
->wpa_auth
, use_sha384
,
1940 wpabuf_put(data
, 0),
1941 wpabuf_tailroom(data
));
1943 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1946 wpabuf_put(data
, res
);
1948 #endif /* CONFIG_IEEE80211R_AP */
1951 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1952 wpabuf_put_u8(data
, 1 + FILS_NONCE_LEN
); /* Length */
1953 /* Element ID Extension */
1954 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_NONCE
);
1955 wpabuf_put_data(data
, fils_nonce
, FILS_NONCE_LEN
);
1958 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1959 wpabuf_put_u8(data
, 1 + FILS_SESSION_LEN
); /* Length */
1960 /* Element ID Extension */
1961 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_SESSION
);
1962 wpabuf_put_data(data
, sta
->fils_session
, FILS_SESSION_LEN
);
1964 /* FILS Wrapped Data */
1965 if (!pmksa
&& erp_resp
) {
1966 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1967 wpabuf_put_u8(data
, 1 + wpabuf_len(erp_resp
)); /* Length */
1968 /* Element ID Extension */
1969 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_WRAPPED_DATA
);
1970 wpabuf_put_buf(data
, erp_resp
);
1972 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1973 msk
, msk_len
, sta
->fils_snonce
, fils_nonce
,
1975 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1977 wpabuf_len(sta
->fils_dh_ss
) : 0,
1978 pmk_buf
, &pmk_len
)) {
1979 wpa_printf(MSG_DEBUG
, "FILS: Failed to derive PMK");
1980 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1987 /* Don't use DHss in PTK derivation if PMKSA caching is not
1989 wpabuf_clear_free(sta
->fils_dh_ss
);
1990 sta
->fils_dh_ss
= NULL
;
1992 if (sta
->fils_erp_pmkid_set
) {
1993 /* TODO: get PMKLifetime from WPA parameters */
1994 unsigned int dot11RSNAConfigPMKLifetime
= 43200;
1995 int session_timeout
;
1997 session_timeout
= dot11RSNAConfigPMKLifetime
;
1998 if (sta
->session_timeout_set
) {
1999 struct os_reltime now
, diff
;
2001 os_get_reltime(&now
);
2002 os_reltime_sub(&sta
->session_timeout
, &now
,
2004 session_timeout
= diff
.sec
;
2007 sta
->fils_erp_pmkid_set
= 0;
2008 wpa_auth_add_fils_pmk_pmkid(sta
->wpa_sm
, pmk
, pmk_len
,
2009 sta
->fils_erp_pmkid
);
2010 if (!hapd
->conf
->disable_pmksa_caching
&&
2011 wpa_auth_pmksa_add2(
2012 hapd
->wpa_auth
, sta
->addr
,
2014 sta
->fils_erp_pmkid
,
2016 wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) < 0) {
2017 wpa_printf(MSG_ERROR
,
2018 "FILS: Failed to add PMKSA cache entry based on ERP");
2023 pmk_len
= pmksa
->pmk_len
;
2027 wpa_printf(MSG_DEBUG
, "FILS: No PMK available");
2028 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2034 if (fils_auth_pmk_to_ptk(sta
->wpa_sm
, pmk
, pmk_len
,
2035 sta
->fils_snonce
, fils_nonce
,
2037 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
2039 wpabuf_len(sta
->fils_dh_ss
) : 0,
2040 sta
->fils_g_sta
, pub
) < 0) {
2041 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2049 *is_pub
= pub
!= NULL
;
2052 wpabuf_clear_free(sta
->fils_dh_ss
);
2053 sta
->fils_dh_ss
= NULL
;
2054 #ifdef CONFIG_FILS_SK_PFS
2055 crypto_ecdh_deinit(sta
->fils_ecdh
);
2056 sta
->fils_ecdh
= NULL
;
2057 #endif /* CONFIG_FILS_SK_PFS */
2062 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
2063 struct sta_info
*sta
, u16 resp
,
2064 struct wpabuf
*data
, int pub
)
2069 resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
) ?
2070 WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
2071 send_auth_reply(hapd
, sta
, sta
->addr
, hapd
->own_addr
, auth_alg
, 2, resp
,
2072 data
? wpabuf_head(data
) : (u8
*) "",
2073 data
? wpabuf_len(data
) : 0, "auth-fils-finish");
2076 if (resp
== WLAN_STATUS_SUCCESS
) {
2077 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2078 HOSTAPD_LEVEL_DEBUG
,
2079 "authentication OK (FILS)");
2080 sta
->flags
|= WLAN_STA_AUTH
;
2081 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2082 sta
->auth_alg
= pub
? WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
2083 mlme_authenticate_indication(hapd
, sta
);
2088 void ieee802_11_finish_fils_auth(struct hostapd_data
*hapd
,
2089 struct sta_info
*sta
, int success
,
2090 struct wpabuf
*erp_resp
,
2091 const u8
*msk
, size_t msk_len
)
2093 struct wpabuf
*data
;
2097 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2099 if (!sta
->fils_pending_cb
)
2101 resp
= success
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_UNSPECIFIED_FAILURE
;
2102 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, NULL
, erp_resp
,
2103 msk
, msk_len
, &pub
);
2105 wpa_printf(MSG_DEBUG
,
2106 "%s: prepare_auth_resp_fils() returned failure",
2109 sta
->fils_pending_cb(hapd
, sta
, resp
, data
, pub
);
2112 #endif /* CONFIG_FILS */
2115 static int ieee802_11_allowed_address(struct hostapd_data
*hapd
, const u8
*addr
,
2116 const u8
*msg
, size_t len
,
2117 struct radius_sta
*info
)
2121 res
= hostapd_allowed_address(hapd
, addr
, msg
, len
, info
, 0);
2123 if (res
== HOSTAPD_ACL_REJECT
) {
2124 wpa_printf(MSG_DEBUG
, "Station " MACSTR
2125 " not allowed to authenticate",
2127 return HOSTAPD_ACL_REJECT
;
2130 if (res
== HOSTAPD_ACL_PENDING
) {
2131 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
2132 " waiting for an external authentication",
2134 /* Authentication code will re-send the authentication frame
2135 * after it has received (and cached) information from the
2136 * external source. */
2137 return HOSTAPD_ACL_PENDING
;
2145 ieee802_11_set_radius_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2146 int res
, struct radius_sta
*info
)
2148 u32 session_timeout
= info
->session_timeout
;
2149 u32 acct_interim_interval
= info
->acct_interim_interval
;
2150 struct vlan_description
*vlan_id
= &info
->vlan_id
;
2151 struct hostapd_sta_wpa_psk_short
*psk
= info
->psk
;
2152 char *identity
= info
->identity
;
2153 char *radius_cui
= info
->radius_cui
;
2155 if (vlan_id
->notempty
&&
2156 !hostapd_vlan_valid(hapd
->conf
->vlan
, vlan_id
)) {
2157 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
2159 "Invalid VLAN %d%s received from RADIUS server",
2161 vlan_id
->tagged
[0] ? "+" : "");
2164 if (ap_sta_set_vlan(hapd
, sta
, vlan_id
) < 0)
2167 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
2168 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
2170 hostapd_free_psk_list(sta
->psk
);
2171 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
)
2172 hostapd_copy_psk_list(&sta
->psk
, psk
);
2176 os_free(sta
->identity
);
2178 sta
->identity
= os_strdup(identity
);
2180 sta
->identity
= NULL
;
2182 os_free(sta
->radius_cui
);
2184 sta
->radius_cui
= os_strdup(radius_cui
);
2186 sta
->radius_cui
= NULL
;
2188 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
2189 sta
->acct_interim_interval
= acct_interim_interval
;
2190 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
) {
2191 sta
->session_timeout_set
= 1;
2192 os_get_reltime(&sta
->session_timeout
);
2193 sta
->session_timeout
.sec
+= session_timeout
;
2194 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
2196 sta
->session_timeout_set
= 0;
2197 ap_sta_no_session_timeout(hapd
, sta
);
2204 static void handle_auth(struct hostapd_data
*hapd
,
2205 const struct ieee80211_mgmt
*mgmt
, size_t len
,
2206 int rssi
, int from_queue
)
2208 u16 auth_alg
, auth_transaction
, status_code
;
2209 u16 resp
= WLAN_STATUS_SUCCESS
;
2210 struct sta_info
*sta
= NULL
;
2213 const u8
*challenge
= NULL
;
2214 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
2215 size_t resp_ies_len
= 0;
2217 struct radius_sta rad_info
;
2219 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
2220 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
2221 (unsigned long) len
);
2225 #ifdef CONFIG_TESTING_OPTIONS
2226 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
2227 drand48() < hapd
->iconf
->ignore_auth_probability
) {
2228 wpa_printf(MSG_INFO
,
2229 "TESTING: ignoring auth frame from " MACSTR
,
2233 #endif /* CONFIG_TESTING_OPTIONS */
2235 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
2236 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
2237 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
2238 fc
= le_to_host16(mgmt
->frame_control
);
2239 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
2241 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
2242 2 + WLAN_AUTH_CHALLENGE_LEN
&&
2243 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
2244 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
2245 challenge
= &mgmt
->u
.auth
.variable
[2];
2247 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
2248 "auth_transaction=%d status_code=%d wep=%d%s "
2249 "seq_ctrl=0x%x%s%s",
2250 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
2251 status_code
, !!(fc
& WLAN_FC_ISWEP
),
2252 challenge
? " challenge" : "",
2253 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "",
2254 from_queue
? " (from queue)" : "");
2256 #ifdef CONFIG_NO_RC4
2257 if (auth_alg
== WLAN_AUTH_SHARED_KEY
) {
2258 wpa_printf(MSG_INFO
,
2259 "Unsupported authentication algorithm (%d)",
2261 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2264 #endif /* CONFIG_NO_RC4 */
2266 if (hapd
->tkip_countermeasures
) {
2267 wpa_printf(MSG_DEBUG
,
2268 "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
2269 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2273 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
2274 auth_alg
== WLAN_AUTH_OPEN
) ||
2275 #ifdef CONFIG_IEEE80211R_AP
2276 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
2277 auth_alg
== WLAN_AUTH_FT
) ||
2278 #endif /* CONFIG_IEEE80211R_AP */
2280 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
2281 auth_alg
== WLAN_AUTH_SAE
) ||
2282 #endif /* CONFIG_SAE */
2284 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2285 auth_alg
== WLAN_AUTH_FILS_SK
) ||
2286 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2287 hapd
->conf
->fils_dh_group
&&
2288 auth_alg
== WLAN_AUTH_FILS_SK_PFS
) ||
2289 #endif /* CONFIG_FILS */
2290 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
2291 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
2292 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
2294 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2298 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
2299 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
2300 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
2302 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
2306 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
2307 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
2309 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2313 if (hapd
->conf
->no_auth_if_seen_on
) {
2314 struct hostapd_data
*other
;
2316 other
= sta_track_seen_on(hapd
->iface
, mgmt
->sa
,
2317 hapd
->conf
->no_auth_if_seen_on
);
2321 u8 op_class
, channel
, phytype
;
2323 wpa_printf(MSG_DEBUG
, "%s: Reject authentication from "
2324 MACSTR
" since STA has been seen on %s",
2325 hapd
->conf
->iface
, MAC2STR(mgmt
->sa
),
2326 hapd
->conf
->no_auth_if_seen_on
);
2328 resp
= WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION
;
2330 *pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
2332 os_memcpy(pos
, other
->own_addr
, ETH_ALEN
);
2334 info
= 0; /* TODO: BSSID Information */
2335 WPA_PUT_LE32(pos
, info
);
2337 if (other
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211AD
)
2338 phytype
= 8; /* dmg */
2339 else if (other
->iconf
->ieee80211ac
)
2340 phytype
= 9; /* vht */
2341 else if (other
->iconf
->ieee80211n
)
2342 phytype
= 7; /* ht */
2343 else if (other
->iconf
->hw_mode
==
2344 HOSTAPD_MODE_IEEE80211A
)
2345 phytype
= 4; /* ofdm */
2346 else if (other
->iconf
->hw_mode
==
2347 HOSTAPD_MODE_IEEE80211G
)
2348 phytype
= 6; /* erp */
2350 phytype
= 5; /* hrdsss */
2351 if (ieee80211_freq_to_channel_ext(
2352 hostapd_hw_get_freq(other
,
2353 other
->iconf
->channel
),
2354 other
->iconf
->secondary_channel
,
2355 other
->iconf
->ieee80211ac
,
2356 &op_class
, &channel
) == NUM_HOSTAPD_MODES
) {
2358 channel
= other
->iconf
->channel
;
2363 resp_ies_len
= pos
- &resp_ies
[0];
2368 res
= ieee802_11_allowed_address(hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
,
2370 if (res
== HOSTAPD_ACL_REJECT
) {
2371 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
2372 "Ignore Authentication frame from " MACSTR
2373 " due to ACL reject", MAC2STR(mgmt
->sa
));
2374 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2377 if (res
== HOSTAPD_ACL_PENDING
)
2381 if (auth_alg
== WLAN_AUTH_SAE
&& !from_queue
&&
2382 (auth_transaction
== 1 ||
2383 (auth_transaction
== 2 && auth_sae_queued_addr(hapd
, mgmt
->sa
)))) {
2384 /* Handle SAE Authentication commit message through a queue to
2385 * provide more control for postponing the needed heavy
2386 * processing under a possible DoS attack scenario. In addition,
2387 * queue SAE Authentication confirm message if there happens to
2388 * be a queued commit message from the same peer. This is needed
2389 * to avoid reordering Authentication frames within the same
2391 auth_sae_queue(hapd
, mgmt
, len
, rssi
);
2394 #endif /* CONFIG_SAE */
2396 sta
= ap_get_sta(hapd
, mgmt
->sa
);
2398 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2399 sta
->ft_over_ds
= 0;
2400 if ((fc
& WLAN_FC_RETRY
) &&
2401 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
2402 sta
->last_seq_ctrl
== seq_ctrl
&&
2403 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
2404 hostapd_logger(hapd
, sta
->addr
,
2405 HOSTAPD_MODULE_IEEE80211
,
2406 HOSTAPD_LEVEL_DEBUG
,
2407 "Drop repeated authentication frame seq_ctrl=0x%x",
2412 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
2413 sta
->plink_state
== PLINK_BLOCKED
) {
2414 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2415 " is blocked - drop Authentication frame",
2419 #endif /* CONFIG_MESH */
2422 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
2423 /* if the mesh peer is not available, we don't do auth.
2425 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2426 " not yet known - drop Authentication frame",
2429 * Save a copy of the frame so that it can be processed
2430 * if a new peer entry is added shortly after this.
2432 wpabuf_free(hapd
->mesh_pending_auth
);
2433 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
2434 os_get_reltime(&hapd
->mesh_pending_auth_time
);
2437 #endif /* CONFIG_MESH */
2439 sta
= ap_sta_add(hapd
, mgmt
->sa
);
2441 wpa_printf(MSG_DEBUG
, "ap_sta_add() failed");
2442 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2446 sta
->last_seq_ctrl
= seq_ctrl
;
2447 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
2449 sta
->auth_rssi
= rssi
;
2450 #endif /* CONFIG_MBO */
2452 res
= ieee802_11_set_radius_info(hapd
, sta
, res
, &rad_info
);
2454 wpa_printf(MSG_DEBUG
, "ieee802_11_set_radius_info() failed");
2455 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2459 sta
->flags
&= ~WLAN_STA_PREAUTH
;
2460 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
2463 * If the driver supports full AP client state, add a station to the
2464 * driver before sending authentication reply to make sure the driver
2465 * has resources, and not to go through the entire authentication and
2466 * association handshake, and fail it at the end.
2468 * If this is not the first transaction, in a multi-step authentication
2469 * algorithm, the station already exists in the driver
2470 * (sta->added_unassoc = 1) so skip it.
2472 * In mesh mode, the station was already added to the driver when the
2473 * NEW_PEER_CANDIDATE event is received.
2475 * If PMF was negotiated for the existing association, skip this to
2476 * avoid dropping the STA entry and the associated keys. This is needed
2477 * to allow the original connection work until the attempt can complete
2478 * (re)association, so that unprotected Authentication frame cannot be
2479 * used to bypass PMF protection.
2481 if (FULL_AP_CLIENT_STATE_SUPP(hapd
->iface
->drv_flags
) &&
2482 (!(sta
->flags
& WLAN_STA_MFP
) || !ap_sta_is_authorized(sta
)) &&
2483 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
2484 !(sta
->added_unassoc
)) {
2486 * If a station that is already associated to the AP, is trying
2487 * to authenticate again, remove the STA entry, in order to make
2488 * sure the STA PS state gets cleared and configuration gets
2489 * updated. To handle this, station's added_unassoc flag is
2490 * cleared once the station has completed association.
2492 ap_sta_set_authorized(hapd
, sta
, 0);
2493 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2494 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_AUTH
|
2495 WLAN_STA_AUTHORIZED
);
2497 if (hostapd_sta_add(hapd
, sta
->addr
, 0, 0,
2498 sta
->supported_rates
,
2499 sta
->supported_rates_len
,
2500 0, NULL
, NULL
, NULL
, 0,
2501 sta
->flags
, 0, 0, 0, 0)) {
2502 hostapd_logger(hapd
, sta
->addr
,
2503 HOSTAPD_MODULE_IEEE80211
,
2504 HOSTAPD_LEVEL_NOTICE
,
2505 "Could not add STA to kernel driver");
2506 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2510 sta
->added_unassoc
= 1;
2514 case WLAN_AUTH_OPEN
:
2515 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2516 HOSTAPD_LEVEL_DEBUG
,
2517 "authentication OK (open system)");
2518 sta
->flags
|= WLAN_STA_AUTH
;
2519 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2520 sta
->auth_alg
= WLAN_AUTH_OPEN
;
2521 mlme_authenticate_indication(hapd
, sta
);
2523 #ifndef CONFIG_NO_RC4
2524 case WLAN_AUTH_SHARED_KEY
:
2525 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
2526 fc
& WLAN_FC_ISWEP
);
2528 wpa_printf(MSG_DEBUG
,
2529 "auth_shared_key() failed: status=%d", resp
);
2530 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
2531 mlme_authenticate_indication(hapd
, sta
);
2532 if (sta
->challenge
&& auth_transaction
== 1) {
2533 resp_ies
[0] = WLAN_EID_CHALLENGE
;
2534 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
2535 os_memcpy(resp_ies
+ 2, sta
->challenge
,
2536 WLAN_AUTH_CHALLENGE_LEN
);
2537 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
2540 #endif /* CONFIG_NO_RC4 */
2541 #ifdef CONFIG_IEEE80211R_AP
2543 sta
->auth_alg
= WLAN_AUTH_FT
;
2544 if (sta
->wpa_sm
== NULL
)
2545 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2547 if (sta
->wpa_sm
== NULL
) {
2548 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
2550 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2553 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
2554 auth_transaction
, mgmt
->u
.auth
.variable
,
2555 len
- IEEE80211_HDRLEN
-
2556 sizeof(mgmt
->u
.auth
),
2557 handle_auth_ft_finish
, hapd
);
2558 /* handle_auth_ft_finish() callback will complete auth. */
2560 #endif /* CONFIG_IEEE80211R_AP */
2564 if (status_code
== WLAN_STATUS_SUCCESS
&&
2565 hapd
->conf
->mesh
& MESH_ENABLED
) {
2566 if (sta
->wpa_sm
== NULL
)
2568 wpa_auth_sta_init(hapd
->wpa_auth
,
2570 if (sta
->wpa_sm
== NULL
) {
2571 wpa_printf(MSG_DEBUG
,
2572 "SAE: Failed to initialize WPA state machine");
2573 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2577 #endif /* CONFIG_MESH */
2578 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
2581 #endif /* CONFIG_SAE */
2583 case WLAN_AUTH_FILS_SK
:
2584 case WLAN_AUTH_FILS_SK_PFS
:
2585 handle_auth_fils(hapd
, sta
, mgmt
->u
.auth
.variable
,
2586 len
- IEEE80211_HDRLEN
- sizeof(mgmt
->u
.auth
),
2587 auth_alg
, auth_transaction
, status_code
,
2588 handle_auth_fils_finish
);
2590 #endif /* CONFIG_FILS */
2594 reply_res
= send_auth_reply(hapd
, sta
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
2595 auth_transaction
+ 1, resp
, resp_ies
,
2596 resp_ies_len
, "handle-auth");
2598 if (sta
&& sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
2599 reply_res
!= WLAN_STATUS_SUCCESS
)) {
2600 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2601 sta
->added_unassoc
= 0;
2606 int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2610 /* get a unique AID */
2612 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
2619 for (i
= 0; i
< AID_WORDS
; i
++) {
2620 if (hapd
->sta_aid
[i
] == (u32
) -1)
2622 for (j
= 0; j
< 32; j
++) {
2623 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
2631 aid
= i
* 32 + j
+ 1;
2636 hapd
->sta_aid
[i
] |= BIT(j
);
2637 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
2642 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2643 const u8
*ssid_ie
, size_t ssid_ie_len
)
2645 if (ssid_ie
== NULL
)
2646 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2648 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
2649 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
2650 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2652 "Station tried to associate with unknown SSID "
2653 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
2654 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2657 return WLAN_STATUS_SUCCESS
;
2661 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2662 const u8
*wmm_ie
, size_t wmm_ie_len
)
2664 sta
->flags
&= ~WLAN_STA_WMM
;
2666 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
2667 struct wmm_information_element
*wmm
;
2669 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
2670 hostapd_logger(hapd
, sta
->addr
,
2672 HOSTAPD_LEVEL_DEBUG
,
2673 "invalid WMM element in association "
2675 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2678 sta
->flags
|= WLAN_STA_WMM
;
2679 wmm
= (struct wmm_information_element
*) wmm_ie
;
2680 sta
->qosinfo
= wmm
->qos_info
;
2682 return WLAN_STATUS_SUCCESS
;
2685 static u16
check_multi_ap(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2686 const u8
*multi_ap_ie
, size_t multi_ap_len
)
2688 u8 multi_ap_value
= 0;
2690 sta
->flags
&= ~WLAN_STA_MULTI_AP
;
2692 if (!hapd
->conf
->multi_ap
)
2693 return WLAN_STATUS_SUCCESS
;
2696 const u8
*multi_ap_subelem
;
2698 multi_ap_subelem
= get_ie(multi_ap_ie
+ 4,
2700 MULTI_AP_SUB_ELEM_TYPE
);
2701 if (multi_ap_subelem
&& multi_ap_subelem
[1] == 1) {
2702 multi_ap_value
= multi_ap_subelem
[2];
2704 hostapd_logger(hapd
, sta
->addr
,
2705 HOSTAPD_MODULE_IEEE80211
,
2707 "Multi-AP IE has missing or invalid Multi-AP subelement");
2708 return WLAN_STATUS_INVALID_IE
;
2712 if (multi_ap_value
&& multi_ap_value
!= MULTI_AP_BACKHAUL_STA
)
2713 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2715 "Multi-AP IE with unexpected value 0x%02x",
2718 if (!(multi_ap_value
& MULTI_AP_BACKHAUL_STA
)) {
2719 if (hapd
->conf
->multi_ap
& FRONTHAUL_BSS
)
2720 return WLAN_STATUS_SUCCESS
;
2722 hostapd_logger(hapd
, sta
->addr
,
2723 HOSTAPD_MODULE_IEEE80211
,
2725 "Non-Multi-AP STA tries to associate with backhaul-only BSS");
2726 return WLAN_STATUS_ASSOC_DENIED_UNSPEC
;
2729 if (!(hapd
->conf
->multi_ap
& BACKHAUL_BSS
))
2730 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2731 HOSTAPD_LEVEL_DEBUG
,
2732 "Backhaul STA tries to associate with fronthaul-only BSS");
2734 sta
->flags
|= WLAN_STA_MULTI_AP
;
2735 return WLAN_STATUS_SUCCESS
;
2739 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2740 struct ieee802_11_elems
*elems
)
2742 /* Supported rates not used in IEEE 802.11ad/DMG */
2743 if (hapd
->iface
->current_mode
&&
2744 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
)
2745 return WLAN_STATUS_SUCCESS
;
2747 if (!elems
->supp_rates
) {
2748 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2749 HOSTAPD_LEVEL_DEBUG
,
2750 "No supported rates element in AssocReq");
2751 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2754 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
2755 sizeof(sta
->supported_rates
)) {
2756 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2757 HOSTAPD_LEVEL_DEBUG
,
2758 "Invalid supported rates element length %d+%d",
2759 elems
->supp_rates_len
,
2760 elems
->ext_supp_rates_len
);
2761 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2764 sta
->supported_rates_len
= merge_byte_arrays(
2765 sta
->supported_rates
, sizeof(sta
->supported_rates
),
2766 elems
->supp_rates
, elems
->supp_rates_len
,
2767 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
2769 return WLAN_STATUS_SUCCESS
;
2773 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2774 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
2776 #ifdef CONFIG_INTERWORKING
2777 /* check for QoS Map support */
2778 if (ext_capab_ie_len
>= 5) {
2779 if (ext_capab_ie
[4] & 0x01)
2780 sta
->qos_map_enabled
= 1;
2782 #endif /* CONFIG_INTERWORKING */
2784 if (ext_capab_ie_len
> 0) {
2785 sta
->ecsa_supported
= !!(ext_capab_ie
[0] & BIT(2));
2786 os_free(sta
->ext_capability
);
2787 sta
->ext_capability
= os_malloc(1 + ext_capab_ie_len
);
2788 if (sta
->ext_capability
) {
2789 sta
->ext_capability
[0] = ext_capab_ie_len
;
2790 os_memcpy(sta
->ext_capability
+ 1, ext_capab_ie
,
2795 return WLAN_STATUS_SUCCESS
;
2801 static int owe_group_supported(struct hostapd_data
*hapd
, u16 group
)
2804 int *groups
= hapd
->conf
->owe_groups
;
2806 if (group
!= 19 && group
!= 20 && group
!= 21)
2812 for (i
= 0; groups
[i
] > 0; i
++) {
2813 if (groups
[i
] == group
)
2821 static u16
owe_process_assoc_req(struct hostapd_data
*hapd
,
2822 struct sta_info
*sta
, const u8
*owe_dh
,
2825 struct wpabuf
*secret
, *pub
, *hkey
;
2827 u8 prk
[SHA512_MAC_LEN
], pmkid
[SHA512_MAC_LEN
];
2828 const char *info
= "OWE Key Generation";
2832 size_t hash_len
, prime_len
;
2834 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
2835 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
2836 return WLAN_STATUS_SUCCESS
;
2839 group
= WPA_GET_LE16(owe_dh
);
2840 if (!owe_group_supported(hapd
, group
)) {
2841 wpa_printf(MSG_DEBUG
, "OWE: Unsupported DH group %u", group
);
2842 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2846 else if (group
== 20)
2848 else if (group
== 21)
2851 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2853 crypto_ecdh_deinit(sta
->owe_ecdh
);
2854 sta
->owe_ecdh
= crypto_ecdh_init(group
);
2856 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2857 sta
->owe_group
= group
;
2859 secret
= crypto_ecdh_set_peerkey(sta
->owe_ecdh
, 0, owe_dh
+ 2,
2861 secret
= wpabuf_zeropad(secret
, prime_len
);
2863 wpa_printf(MSG_DEBUG
, "OWE: Invalid peer DH public key");
2864 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2866 wpa_hexdump_buf_key(MSG_DEBUG
, "OWE: DH shared secret", secret
);
2868 /* prk = HKDF-extract(C | A | group, z) */
2870 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2872 wpabuf_clear_free(secret
);
2873 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2876 /* PMKID = Truncate-128(Hash(C | A)) */
2877 addr
[0] = owe_dh
+ 2;
2878 len
[0] = owe_dh_len
- 2;
2879 addr
[1] = wpabuf_head(pub
);
2880 len
[1] = wpabuf_len(pub
);
2882 res
= sha256_vector(2, addr
, len
, pmkid
);
2883 hash_len
= SHA256_MAC_LEN
;
2884 } else if (group
== 20) {
2885 res
= sha384_vector(2, addr
, len
, pmkid
);
2886 hash_len
= SHA384_MAC_LEN
;
2887 } else if (group
== 21) {
2888 res
= sha512_vector(2, addr
, len
, pmkid
);
2889 hash_len
= SHA512_MAC_LEN
;
2892 wpabuf_clear_free(secret
);
2893 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2895 pub
= wpabuf_zeropad(pub
, prime_len
);
2896 if (res
< 0 || !pub
) {
2898 wpabuf_clear_free(secret
);
2899 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2902 hkey
= wpabuf_alloc(owe_dh_len
- 2 + wpabuf_len(pub
) + 2);
2905 wpabuf_clear_free(secret
);
2906 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2909 wpabuf_put_data(hkey
, owe_dh
+ 2, owe_dh_len
- 2); /* C */
2910 wpabuf_put_buf(hkey
, pub
); /* A */
2912 wpabuf_put_le16(hkey
, group
); /* group */
2914 res
= hmac_sha256(wpabuf_head(hkey
), wpabuf_len(hkey
),
2915 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2916 else if (group
== 20)
2917 res
= hmac_sha384(wpabuf_head(hkey
), wpabuf_len(hkey
),
2918 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2919 else if (group
== 21)
2920 res
= hmac_sha512(wpabuf_head(hkey
), wpabuf_len(hkey
),
2921 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2922 wpabuf_clear_free(hkey
);
2923 wpabuf_clear_free(secret
);
2925 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2927 wpa_hexdump_key(MSG_DEBUG
, "OWE: prk", prk
, hash_len
);
2929 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2931 os_free(sta
->owe_pmk
);
2932 sta
->owe_pmk
= os_malloc(hash_len
);
2933 if (!sta
->owe_pmk
) {
2934 os_memset(prk
, 0, SHA512_MAC_LEN
);
2935 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2939 res
= hmac_sha256_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2940 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2941 else if (group
== 20)
2942 res
= hmac_sha384_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2943 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2944 else if (group
== 21)
2945 res
= hmac_sha512_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2946 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2947 os_memset(prk
, 0, SHA512_MAC_LEN
);
2949 os_free(sta
->owe_pmk
);
2950 sta
->owe_pmk
= NULL
;
2951 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2953 sta
->owe_pmk_len
= hash_len
;
2955 wpa_hexdump_key(MSG_DEBUG
, "OWE: PMK", sta
->owe_pmk
, sta
->owe_pmk_len
);
2956 wpa_hexdump(MSG_DEBUG
, "OWE: PMKID", pmkid
, PMKID_LEN
);
2957 wpa_auth_pmksa_add2(hapd
->wpa_auth
, sta
->addr
, sta
->owe_pmk
,
2958 sta
->owe_pmk_len
, pmkid
, 0, WPA_KEY_MGMT_OWE
);
2960 return WLAN_STATUS_SUCCESS
;
2964 u16
owe_validate_request(struct hostapd_data
*hapd
, const u8
*peer
,
2965 const u8
*rsn_ie
, size_t rsn_ie_len
,
2966 const u8
*owe_dh
, size_t owe_dh_len
)
2968 struct wpa_ie_data data
;
2971 if (!rsn_ie
|| rsn_ie_len
< 2) {
2972 wpa_printf(MSG_DEBUG
, "OWE: Invalid RSNE from " MACSTR
,
2974 return WLAN_STATUS_INVALID_IE
;
2979 res
= wpa_parse_wpa_ie_rsn(rsn_ie
, rsn_ie_len
, &data
);
2981 wpa_printf(MSG_DEBUG
, "Failed to parse RSNE from " MACSTR
2982 " (res=%d)", MAC2STR(peer
), res
);
2983 wpa_hexdump(MSG_DEBUG
, "RSNE", rsn_ie
, rsn_ie_len
);
2984 return wpa_res_to_status_code(res
);
2986 if (!(data
.key_mgmt
& WPA_KEY_MGMT_OWE
)) {
2987 wpa_printf(MSG_DEBUG
,
2988 "OWE: Unexpected key mgmt 0x%x from " MACSTR
,
2989 (unsigned int) data
.key_mgmt
, MAC2STR(peer
));
2990 return WLAN_STATUS_AKMP_NOT_VALID
;
2993 wpa_printf(MSG_DEBUG
,
2994 "OWE: No Diffie-Hellman Parameter element from "
2995 MACSTR
, MAC2STR(peer
));
2996 return WLAN_STATUS_AKMP_NOT_VALID
;
2999 return WLAN_STATUS_SUCCESS
;
3003 u16
owe_process_rsn_ie(struct hostapd_data
*hapd
,
3004 struct sta_info
*sta
,
3005 const u8
*rsn_ie
, size_t rsn_ie_len
,
3006 const u8
*owe_dh
, size_t owe_dh_len
)
3009 u8
*owe_buf
, ie
[256 * 2];
3013 if (!rsn_ie
|| rsn_ie_len
< 2) {
3014 wpa_printf(MSG_DEBUG
, "OWE: No RSNE in (Re)AssocReq");
3015 status
= WLAN_STATUS_INVALID_IE
;
3020 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
3023 wpa_printf(MSG_WARNING
,
3024 "OWE: Failed to initialize WPA state machine");
3025 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3030 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
3031 hapd
->iface
->freq
, rsn_ie
, rsn_ie_len
,
3032 NULL
, 0, NULL
, 0, owe_dh
, owe_dh_len
);
3033 status
= wpa_res_to_status_code(res
);
3034 if (status
!= WLAN_STATUS_SUCCESS
)
3036 status
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3037 if (status
!= WLAN_STATUS_SUCCESS
)
3039 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, ie
, sizeof(ie
),
3042 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3046 if (sta
->owe_ecdh
) {
3049 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3051 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3055 /* OWE Diffie-Hellman Parameter element */
3056 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3057 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3058 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3060 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3062 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3063 owe_buf
+= wpabuf_len(pub
);
3065 sta
->external_dh_updated
= 1;
3067 ie_len
= owe_buf
- ie
;
3070 wpa_printf(MSG_DEBUG
, "OWE: Update status %d, ie len %d for peer "
3071 MACSTR
, status
, (unsigned int) ie_len
,
3072 MAC2STR(sta
->addr
));
3073 hostapd_drv_update_dh_ie(hapd
, sta
->addr
, status
,
3074 status
== WLAN_STATUS_SUCCESS
? ie
: NULL
,
3080 #endif /* CONFIG_OWE */
3083 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3084 const u8
*ies
, size_t ies_len
, int reassoc
)
3086 struct ieee802_11_elems elems
;
3090 const u8
*p2p_dev_addr
= NULL
;
3092 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
3093 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3094 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
3095 "association request");
3096 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3099 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
3100 if (resp
!= WLAN_STATUS_SUCCESS
)
3102 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
3103 if (resp
!= WLAN_STATUS_SUCCESS
)
3105 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
3106 if (resp
!= WLAN_STATUS_SUCCESS
)
3108 resp
= copy_supp_rates(hapd
, sta
, &elems
);
3109 if (resp
!= WLAN_STATUS_SUCCESS
)
3112 resp
= check_multi_ap(hapd
, sta
, elems
.multi_ap
, elems
.multi_ap_len
);
3113 if (resp
!= WLAN_STATUS_SUCCESS
)
3116 #ifdef CONFIG_IEEE80211N
3117 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
);
3118 if (resp
!= WLAN_STATUS_SUCCESS
)
3120 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
3121 !(sta
->flags
& WLAN_STA_HT
)) {
3122 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3123 HOSTAPD_LEVEL_INFO
, "Station does not support "
3124 "mandatory HT PHY - reject association");
3125 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
3127 #endif /* CONFIG_IEEE80211N */
3129 #ifdef CONFIG_IEEE80211AC
3130 if (hapd
->iconf
->ieee80211ac
) {
3131 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
);
3132 if (resp
!= WLAN_STATUS_SUCCESS
)
3135 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
3136 if (resp
!= WLAN_STATUS_SUCCESS
)
3140 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
3141 !(sta
->flags
& WLAN_STA_VHT
)) {
3142 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3143 HOSTAPD_LEVEL_INFO
, "Station does not support "
3144 "mandatory VHT PHY - reject association");
3145 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
3148 if (hapd
->conf
->vendor_vht
&& !elems
.vht_capabilities
) {
3149 resp
= copy_sta_vendor_vht(hapd
, sta
, elems
.vendor_vht
,
3150 elems
.vendor_vht_len
);
3151 if (resp
!= WLAN_STATUS_SUCCESS
)
3154 #endif /* CONFIG_IEEE80211AC */
3155 #ifdef CONFIG_IEEE80211AX
3156 if (hapd
->iconf
->ieee80211ax
) {
3157 resp
= copy_sta_he_capab(hapd
, sta
, IEEE80211_MODE_AP
,
3158 elems
.he_capabilities
,
3159 elems
.he_capabilities_len
);
3160 if (resp
!= WLAN_STATUS_SUCCESS
)
3163 #endif /* CONFIG_IEEE80211AX */
3167 wpabuf_free(sta
->p2p_ie
);
3168 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3169 P2P_IE_VENDOR_TYPE
);
3171 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
3173 wpabuf_free(sta
->p2p_ie
);
3176 #endif /* CONFIG_P2P */
3178 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
3179 wpa_ie
= elems
.rsn_ie
;
3180 wpa_ie_len
= elems
.rsn_ie_len
;
3181 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
3183 wpa_ie
= elems
.wpa_ie
;
3184 wpa_ie_len
= elems
.wpa_ie_len
;
3191 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
3192 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
3193 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
3194 "Request - assume WPS is used");
3195 sta
->flags
|= WLAN_STA_WPS
;
3196 wpabuf_free(sta
->wps_ie
);
3197 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3198 WPS_IE_VENDOR_TYPE
);
3199 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
3200 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
3201 sta
->flags
|= WLAN_STA_WPS2
;
3205 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
3206 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
3207 "(Re)Association Request - reject");
3208 return WLAN_STATUS_INVALID_IE
;
3210 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
3211 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
3212 "(Re)Association Request - possible WPS use");
3213 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
3215 #endif /* CONFIG_WPS */
3216 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
3217 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3219 "No WPA/RSN IE in association request");
3220 return WLAN_STATUS_INVALID_IE
;
3223 if (hapd
->conf
->wpa
&& wpa_ie
) {
3227 if (sta
->wpa_sm
== NULL
)
3228 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3231 if (sta
->wpa_sm
== NULL
) {
3232 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3234 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3236 wpa_auth_set_auth_alg(sta
->wpa_sm
, sta
->auth_alg
);
3237 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
3240 elems
.rsnxe
? elems
.rsnxe
- 2 : NULL
,
3241 elems
.rsnxe
? elems
.rsnxe_len
+ 2 : 0,
3242 elems
.mdie
, elems
.mdie_len
,
3243 elems
.owe_dh
, elems
.owe_dh_len
);
3244 resp
= wpa_res_to_status_code(res
);
3245 if (resp
!= WLAN_STATUS_SUCCESS
)
3247 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3248 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3249 !sta
->sa_query_timed_out
&&
3250 sta
->sa_query_count
> 0)
3251 ap_check_sa_query_timeout(hapd
, sta
);
3252 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3253 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3254 !sta
->sa_query_timed_out
&&
3255 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
3257 * STA has already been associated with MFP and SA
3258 * Query timeout has not been reached. Reject the
3259 * association attempt temporarily and start SA Query,
3260 * if one is not pending.
3263 if (sta
->sa_query_count
== 0)
3264 ap_sta_start_sa_query(hapd
, sta
);
3266 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
3269 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
3270 sta
->flags
|= WLAN_STA_MFP
;
3272 sta
->flags
&= ~WLAN_STA_MFP
;
3274 #ifdef CONFIG_IEEE80211R_AP
3275 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
3277 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
3278 "to use association (not "
3279 "re-association) with FT auth_alg",
3280 MAC2STR(sta
->addr
));
3281 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3284 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
3286 if (resp
!= WLAN_STATUS_SUCCESS
)
3289 #endif /* CONFIG_IEEE80211R_AP */
3292 if (wpa_auth_uses_sae(sta
->wpa_sm
) && sta
->sae
&&
3293 sta
->sae
->state
== SAE_ACCEPTED
)
3294 wpa_auth_add_sae_pmkid(sta
->wpa_sm
, sta
->sae
->pmkid
);
3296 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3297 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
3298 struct rsn_pmksa_cache_entry
*sa
;
3299 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
3300 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
3301 wpa_printf(MSG_DEBUG
,
3302 "SAE: No PMKSA cache entry found for "
3303 MACSTR
, MAC2STR(sta
->addr
));
3304 return WLAN_STATUS_INVALID_PMKID
;
3306 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
3307 " using PMKSA caching", MAC2STR(sta
->addr
));
3308 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3309 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
3310 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
3311 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
3312 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
3313 "SAE AKM after non-SAE auth_alg %u",
3314 MAC2STR(sta
->addr
), sta
->auth_alg
);
3315 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
3318 if (hapd
->conf
->sae_pwe
== 2 &&
3319 sta
->auth_alg
== WLAN_AUTH_SAE
&&
3320 sta
->sae
&& sta
->sae
->tmp
&& !sta
->sae
->tmp
->h2e
&&
3321 elems
.rsnxe
&& elems
.rsnxe_len
>= 1 &&
3322 (elems
.rsnxe
[0] & BIT(WLAN_RSNX_CAPAB_SAE_H2E
))) {
3323 wpa_printf(MSG_INFO
, "SAE: " MACSTR
3324 " indicates support for SAE H2E, but did not use it",
3325 MAC2STR(sta
->addr
));
3326 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3328 #endif /* CONFIG_SAE */
3331 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3332 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
&&
3334 resp
= owe_process_assoc_req(hapd
, sta
, elems
.owe_dh
,
3336 if (resp
!= WLAN_STATUS_SUCCESS
)
3339 #endif /* CONFIG_OWE */
3342 dpp_pfs_free(sta
->dpp_pfs
);
3343 sta
->dpp_pfs
= NULL
;
3345 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3346 hapd
->conf
->dpp_netaccesskey
&& sta
->wpa_sm
&&
3347 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
&&
3349 sta
->dpp_pfs
= dpp_pfs_init(
3350 wpabuf_head(hapd
->conf
->dpp_netaccesskey
),
3351 wpabuf_len(hapd
->conf
->dpp_netaccesskey
));
3352 if (!sta
->dpp_pfs
) {
3353 wpa_printf(MSG_DEBUG
,
3354 "DPP: Could not initialize PFS");
3355 /* Try to continue without PFS */
3359 if (dpp_pfs_process(sta
->dpp_pfs
, elems
.owe_dh
,
3360 elems
.owe_dh_len
) < 0) {
3361 dpp_pfs_free(sta
->dpp_pfs
);
3362 sta
->dpp_pfs
= NULL
;
3363 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3367 wpa_auth_set_dpp_z(sta
->wpa_sm
, sta
->dpp_pfs
?
3368 sta
->dpp_pfs
->secret
: NULL
);
3370 #endif /* CONFIG_DPP2 */
3372 #ifdef CONFIG_IEEE80211N
3373 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
3374 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
3375 hostapd_logger(hapd
, sta
->addr
,
3376 HOSTAPD_MODULE_IEEE80211
,
3378 "Station tried to use TKIP with HT "
3380 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
3382 #endif /* CONFIG_IEEE80211N */
3384 } else if (hapd
->conf
->osen
) {
3385 if (elems
.osen
== NULL
) {
3387 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3389 "No HS 2.0 OSEN element in association request");
3390 return WLAN_STATUS_INVALID_IE
;
3393 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
3394 if (sta
->wpa_sm
== NULL
)
3395 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3397 if (sta
->wpa_sm
== NULL
) {
3398 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3400 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3402 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
3403 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
3404 return WLAN_STATUS_INVALID_IE
;
3405 #endif /* CONFIG_HS20 */
3407 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
3410 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
3411 #endif /* CONFIG_P2P */
3414 wpabuf_free(sta
->hs20_ie
);
3415 if (elems
.hs20
&& elems
.hs20_len
> 4) {
3418 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
3419 elems
.hs20_len
- 4);
3420 release
= ((elems
.hs20
[4] >> 4) & 0x0f) + 1;
3421 if (release
>= 2 && !wpa_auth_uses_mfp(sta
->wpa_sm
) &&
3422 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3423 wpa_printf(MSG_DEBUG
,
3424 "HS 2.0: PMF not negotiated by release %d station "
3425 MACSTR
, release
, MAC2STR(sta
->addr
));
3426 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
3429 sta
->hs20_ie
= NULL
;
3432 wpabuf_free(sta
->roaming_consortium
);
3433 if (elems
.roaming_cons_sel
)
3434 sta
->roaming_consortium
= wpabuf_alloc_copy(
3435 elems
.roaming_cons_sel
+ 4,
3436 elems
.roaming_cons_sel_len
- 4);
3438 sta
->roaming_consortium
= NULL
;
3439 #endif /* CONFIG_HS20 */
3442 wpabuf_free(sta
->mb_ies
);
3443 if (hapd
->iface
->fst
)
3444 sta
->mb_ies
= mb_ies_by_info(&elems
.mb_ies
);
3447 #endif /* CONFIG_FST */
3450 mbo_ap_check_sta_assoc(hapd
, sta
, &elems
);
3452 if (hapd
->conf
->mbo_enabled
&& (hapd
->conf
->wpa
& 2) &&
3453 elems
.mbo
&& sta
->cell_capa
&& !(sta
->flags
& WLAN_STA_MFP
) &&
3454 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3455 wpa_printf(MSG_INFO
,
3456 "MBO: Reject WPA2 association without PMF");
3457 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3459 #endif /* CONFIG_MBO */
3461 #if defined(CONFIG_FILS) && defined(CONFIG_OCV)
3462 if (wpa_auth_uses_ocv(sta
->wpa_sm
) &&
3463 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3464 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3465 sta
->auth_alg
== WLAN_AUTH_FILS_PK
)) {
3466 struct wpa_channel_info ci
;
3470 if (hostapd_drv_channel_info(hapd
, &ci
) != 0) {
3471 wpa_printf(MSG_WARNING
,
3472 "Failed to get channel info to validate received OCI in FILS (Re)Association Request frame");
3473 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3476 if (get_sta_tx_parameters(sta
->wpa_sm
,
3477 channel_width_to_int(ci
.chanwidth
),
3478 ci
.seg1_idx
, &tx_chanwidth
,
3480 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3482 if (ocv_verify_tx_params(elems
.oci
, elems
.oci_len
, &ci
,
3483 tx_chanwidth
, tx_seg1_idx
) != 0) {
3484 wpa_printf(MSG_WARNING
, "FILS: %s", ocv_errorstr
);
3485 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3488 #endif /* CONFIG_FILS && CONFIG_OCV */
3490 ap_copy_sta_supp_op_classes(sta
, elems
.supp_op_classes
,
3491 elems
.supp_op_classes_len
);
3493 if ((sta
->capability
& WLAN_CAPABILITY_RADIO_MEASUREMENT
) &&
3494 elems
.rrm_enabled
&&
3495 elems
.rrm_enabled_len
>= sizeof(sta
->rrm_enabled_capa
))
3496 os_memcpy(sta
->rrm_enabled_capa
, elems
.rrm_enabled
,
3497 sizeof(sta
->rrm_enabled_capa
));
3499 if (elems
.power_capab
) {
3500 sta
->min_tx_power
= elems
.power_capab
[0];
3501 sta
->max_tx_power
= elems
.power_capab
[1];
3502 sta
->power_capab
= 1;
3504 sta
->power_capab
= 0;
3507 return WLAN_STATUS_SUCCESS
;
3511 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
3515 struct ieee80211_mgmt reply
;
3517 os_memset(&reply
, 0, sizeof(reply
));
3518 reply
.frame_control
=
3519 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
3520 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
3521 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
3522 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
3524 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
3525 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
3527 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0, NULL
, 0, 0) < 0)
3528 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
3533 static int add_associated_sta(struct hostapd_data
*hapd
,
3534 struct sta_info
*sta
, int reassoc
)
3536 struct ieee80211_ht_capabilities ht_cap
;
3537 struct ieee80211_vht_capabilities vht_cap
;
3538 struct ieee80211_he_capabilities he_cap
;
3542 * Remove the STA entry to ensure the STA PS state gets cleared and
3543 * configuration gets updated. This is relevant for cases, such as
3544 * FT-over-the-DS, where a station re-associates back to the same AP but
3545 * skips the authentication flow, or if working with a driver that
3546 * does not support full AP client state.
3548 * Skip this if the STA has already completed FT reassociation and the
3549 * TK has been configured since the TX/RX PN must not be reset to 0 for
3552 * FT-over-the-DS has a special case where the STA entry (and as such,
3553 * the TK) has not yet been configured to the driver depending on which
3554 * driver interface is used. For that case, allow add-STA operation to
3555 * be used (instead of set-STA). This is needed to allow mac80211-based
3556 * drivers to accept the STA parameter configuration. Since this is
3557 * after a new FT-over-DS exchange, a new TK has been derived, so key
3558 * reinstallation is not a concern for this case.
3560 wpa_printf(MSG_DEBUG
, "Add associated STA " MACSTR
3561 " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
3562 MAC2STR(sta
->addr
), sta
->added_unassoc
, sta
->auth_alg
,
3563 sta
->ft_over_ds
, reassoc
,
3564 !!(sta
->flags
& WLAN_STA_AUTHORIZED
),
3565 wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
),
3566 wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
));
3568 if (!sta
->added_unassoc
&&
3569 (!(sta
->flags
& WLAN_STA_AUTHORIZED
) ||
3570 (reassoc
&& sta
->ft_over_ds
&& sta
->auth_alg
== WLAN_AUTH_FT
) ||
3571 (!wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
) &&
3572 !wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
)))) {
3573 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3574 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DRV_STA_REMOVED
);
3577 /* Do not allow the FT-over-DS exception to be used more than
3578 * once per authentication exchange to guarantee a new TK is
3580 sta
->ft_over_ds
= 0;
3583 #ifdef CONFIG_IEEE80211N
3584 if (sta
->flags
& WLAN_STA_HT
)
3585 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
3586 #endif /* CONFIG_IEEE80211N */
3587 #ifdef CONFIG_IEEE80211AC
3588 if (sta
->flags
& WLAN_STA_VHT
)
3589 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
3590 #endif /* CONFIG_IEEE80211AC */
3591 #ifdef CONFIG_IEEE80211AX
3592 if (sta
->flags
& WLAN_STA_HE
) {
3593 hostapd_get_he_capab(hapd
, sta
->he_capab
, &he_cap
,
3596 #endif /* CONFIG_IEEE80211AX */
3599 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
3600 * will be set when the ACK frame for the (Re)Association Response frame
3601 * is processed (TX status driver event).
3603 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
3604 sta
->supported_rates
, sta
->supported_rates_len
,
3605 sta
->listen_interval
,
3606 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
3607 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
3608 sta
->flags
& WLAN_STA_HE
? &he_cap
: NULL
,
3609 sta
->flags
& WLAN_STA_HE
? sta
->he_capab_len
: 0,
3610 sta
->flags
| WLAN_STA_ASSOC
, sta
->qosinfo
,
3611 sta
->vht_opmode
, sta
->p2p_ie
? 1 : 0,
3613 hostapd_logger(hapd
, sta
->addr
,
3614 HOSTAPD_MODULE_IEEE80211
, HOSTAPD_LEVEL_NOTICE
,
3615 "Could not %s STA to kernel driver",
3616 set
? "set" : "add");
3618 if (sta
->added_unassoc
) {
3619 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3620 sta
->added_unassoc
= 0;
3626 sta
->added_unassoc
= 0;
3632 static u16
send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3633 const u8
*addr
, u16 status_code
, int reassoc
,
3634 const u8
*ies
, size_t ies_len
, int rssi
)
3639 struct ieee80211_mgmt
*reply
;
3641 u16 res
= WLAN_STATUS_SUCCESS
;
3643 buflen
= sizeof(struct ieee80211_mgmt
) + 1024;
3645 if (sta
&& sta
->fils_hlp_resp
)
3646 buflen
+= wpabuf_len(sta
->fils_hlp_resp
);
3649 #endif /* CONFIG_FILS */
3651 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3653 #endif /* CONFIG_OWE */
3655 if (sta
&& sta
->dpp_pfs
)
3656 buflen
+= 5 + sta
->dpp_pfs
->curve
->prime_len
;
3657 #endif /* CONFIG_DPP2 */
3658 buf
= os_zalloc(buflen
);
3660 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3663 reply
= (struct ieee80211_mgmt
*) buf
;
3664 reply
->frame_control
=
3665 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
3666 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
3667 WLAN_FC_STYPE_ASSOC_RESP
));
3668 os_memcpy(reply
->da
, addr
, ETH_ALEN
);
3669 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
3670 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
3672 send_len
= IEEE80211_HDRLEN
;
3673 send_len
+= sizeof(reply
->u
.assoc_resp
);
3674 reply
->u
.assoc_resp
.capab_info
=
3675 host_to_le16(hostapd_own_capab_info(hapd
));
3676 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
3678 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0) |
3680 /* Supported rates */
3681 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
3682 /* Extended supported rates */
3683 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
3686 if (status_code
== WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
&&
3688 int delta
= hapd
->iconf
->rssi_reject_assoc_rssi
- rssi
;
3690 p
= hostapd_eid_mbo_rssi_assoc_rej(hapd
, p
, buf
+ buflen
- p
,
3693 #endif /* CONFIG_MBO */
3695 #ifdef CONFIG_IEEE80211R_AP
3696 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
) {
3697 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
3698 * Transition Information, RSN, [RIC Response] */
3699 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
3701 sta
->auth_alg
, ies
, ies_len
);
3703 wpa_printf(MSG_DEBUG
,
3704 "FT: Failed to write AssocResp IEs");
3705 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3709 #endif /* CONFIG_IEEE80211R_AP */
3711 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3712 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3713 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3714 sta
->auth_alg
== WLAN_AUTH_FILS_PK
))
3715 p
= wpa_auth_write_assoc_resp_fils(sta
->wpa_sm
, p
,
3718 #endif /* CONFIG_FILS */
3721 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3722 (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3723 p
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, p
,
3726 #endif /* CONFIG_OWE */
3728 if (sta
&& status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
3729 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
3731 #ifdef CONFIG_IEEE80211N
3732 p
= hostapd_eid_ht_capabilities(hapd
, p
);
3733 p
= hostapd_eid_ht_operation(hapd
, p
);
3734 #endif /* CONFIG_IEEE80211N */
3736 #ifdef CONFIG_IEEE80211AC
3737 if (hapd
->iconf
->ieee80211ac
&& !hapd
->conf
->disable_11ac
&&
3738 !is_6ghz_op_class(hapd
->iconf
->op_class
)) {
3739 u32 nsts
= 0, sta_nsts
;
3741 if (sta
&& hapd
->conf
->use_sta_nsts
&& sta
->vht_capabilities
) {
3742 struct ieee80211_vht_capabilities
*capa
;
3744 nsts
= (hapd
->iface
->conf
->vht_capab
>>
3745 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3746 capa
= sta
->vht_capabilities
;
3747 sta_nsts
= (le_to_host32(capa
->vht_capabilities_info
) >>
3748 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3750 if (nsts
< sta_nsts
)
3755 p
= hostapd_eid_vht_capabilities(hapd
, p
, nsts
);
3756 p
= hostapd_eid_vht_operation(hapd
, p
);
3758 #endif /* CONFIG_IEEE80211AC */
3760 #ifdef CONFIG_IEEE80211AX
3761 if (hapd
->iconf
->ieee80211ax
) {
3762 p
= hostapd_eid_he_capab(hapd
, p
, IEEE80211_MODE_AP
);
3763 p
= hostapd_eid_he_operation(hapd
, p
);
3764 p
= hostapd_eid_spatial_reuse(hapd
, p
);
3765 p
= hostapd_eid_he_mu_edca_parameter_set(hapd
, p
);
3767 #endif /* CONFIG_IEEE80211AX */
3769 p
= hostapd_eid_ext_capab(hapd
, p
);
3770 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
3771 if (sta
&& sta
->qos_map_enabled
)
3772 p
= hostapd_eid_qos_map_set(hapd
, p
);
3775 if (hapd
->iface
->fst_ies
) {
3776 os_memcpy(p
, wpabuf_head(hapd
->iface
->fst_ies
),
3777 wpabuf_len(hapd
->iface
->fst_ies
));
3778 p
+= wpabuf_len(hapd
->iface
->fst_ies
);
3780 #endif /* CONFIG_FST */
3782 p
= hostapd_eid_rsnxe(hapd
, p
, buf
+ buflen
- p
);
3785 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3786 sta
&& sta
->owe_ecdh
&& status_code
== WLAN_STATUS_SUCCESS
&&
3787 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
) {
3790 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3792 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3795 /* OWE Diffie-Hellman Parameter element */
3796 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3797 *p
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3798 *p
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
3799 WPA_PUT_LE16(p
, sta
->owe_group
);
3801 os_memcpy(p
, wpabuf_head(pub
), wpabuf_len(pub
));
3802 p
+= wpabuf_len(pub
);
3805 #endif /* CONFIG_OWE */
3808 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3809 sta
&& sta
->dpp_pfs
&& status_code
== WLAN_STATUS_SUCCESS
&&
3810 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
) {
3811 os_memcpy(p
, wpabuf_head(sta
->dpp_pfs
->ie
),
3812 wpabuf_len(sta
->dpp_pfs
->ie
));
3813 p
+= wpabuf_len(sta
->dpp_pfs
->ie
);
3815 #endif /* CONFIG_DPP2 */
3817 #ifdef CONFIG_IEEE80211AC
3818 if (sta
&& hapd
->conf
->vendor_vht
&& (sta
->flags
& WLAN_STA_VENDOR_VHT
))
3819 p
= hostapd_eid_vendor_vht(hapd
, p
);
3820 #endif /* CONFIG_IEEE80211AC */
3822 if (sta
&& (sta
->flags
& WLAN_STA_WMM
))
3823 p
= hostapd_eid_wmm(hapd
, p
);
3827 ((sta
->flags
& WLAN_STA_WPS
) ||
3828 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
))) {
3829 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
3831 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
3832 p
+= wpabuf_len(wps
);
3836 #endif /* CONFIG_WPS */
3838 if (sta
&& (sta
->flags
& WLAN_STA_MULTI_AP
))
3839 p
= hostapd_eid_multi_ap(hapd
, p
);
3842 if (sta
&& sta
->p2p_ie
&& hapd
->p2p_group
) {
3843 struct wpabuf
*p2p_resp_ie
;
3844 enum p2p_status_code status
;
3845 switch (status_code
) {
3846 case WLAN_STATUS_SUCCESS
:
3847 status
= P2P_SC_SUCCESS
;
3849 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
3850 status
= P2P_SC_FAIL_LIMIT_REACHED
;
3853 status
= P2P_SC_FAIL_INVALID_PARAMS
;
3856 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
3858 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
3859 wpabuf_len(p2p_resp_ie
));
3860 p
+= wpabuf_len(p2p_resp_ie
);
3861 wpabuf_free(p2p_resp_ie
);
3864 #endif /* CONFIG_P2P */
3866 #ifdef CONFIG_P2P_MANAGER
3867 if (hapd
->conf
->p2p
& P2P_MANAGE
)
3868 p
= hostapd_eid_p2p_manage(hapd
, p
);
3869 #endif /* CONFIG_P2P_MANAGER */
3871 p
= hostapd_eid_mbo(hapd
, p
, buf
+ buflen
- p
);
3873 if (hapd
->conf
->assocresp_elements
&&
3874 (size_t) (buf
+ buflen
- p
) >=
3875 wpabuf_len(hapd
->conf
->assocresp_elements
)) {
3876 os_memcpy(p
, wpabuf_head(hapd
->conf
->assocresp_elements
),
3877 wpabuf_len(hapd
->conf
->assocresp_elements
));
3878 p
+= wpabuf_len(hapd
->conf
->assocresp_elements
);
3881 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
3885 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3886 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3887 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
3888 status_code
== WLAN_STATUS_SUCCESS
) {
3889 struct ieee802_11_elems elems
;
3891 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 0) ==
3892 ParseFailed
|| !elems
.fils_session
) {
3893 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3898 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3899 *p
++ = 1 + FILS_SESSION_LEN
; /* Length */
3900 *p
++ = WLAN_EID_EXT_FILS_SESSION
; /* Element ID Extension */
3901 os_memcpy(p
, elems
.fils_session
, FILS_SESSION_LEN
);
3902 send_len
+= 2 + 1 + FILS_SESSION_LEN
;
3904 send_len
= fils_encrypt_assoc(sta
->wpa_sm
, buf
, send_len
,
3905 buflen
, sta
->fils_hlp_resp
);
3907 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3911 #endif /* CONFIG_FILS */
3913 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0, NULL
, 0, 0) < 0) {
3914 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
3916 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3926 u8
* owe_assoc_req_process(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3927 const u8
*owe_dh
, u8 owe_dh_len
,
3928 u8
*owe_buf
, size_t owe_buf_len
, u16
*reason
)
3930 #ifdef CONFIG_TESTING_OPTIONS
3931 if (hapd
->conf
->own_ie_override
) {
3932 wpa_printf(MSG_DEBUG
, "OWE: Using IE override");
3933 *reason
= WLAN_STATUS_SUCCESS
;
3934 return wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3935 owe_buf_len
, NULL
, 0);
3937 #endif /* CONFIG_TESTING_OPTIONS */
3939 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
3940 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
3941 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3942 owe_buf_len
, NULL
, 0);
3943 *reason
= WLAN_STATUS_SUCCESS
;
3947 if (sta
->owe_pmk
&& sta
->external_dh_updated
) {
3948 wpa_printf(MSG_DEBUG
, "OWE: Using previously derived PMK");
3949 *reason
= WLAN_STATUS_SUCCESS
;
3953 *reason
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3954 if (*reason
!= WLAN_STATUS_SUCCESS
)
3957 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3958 owe_buf_len
, NULL
, 0);
3960 if (sta
->owe_ecdh
&& owe_buf
) {
3963 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3965 *reason
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3969 /* OWE Diffie-Hellman Parameter element */
3970 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3971 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3972 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3974 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3976 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3977 owe_buf
+= wpabuf_len(pub
);
3983 #endif /* CONFIG_OWE */
3988 void fils_hlp_finish_assoc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
3992 wpa_printf(MSG_DEBUG
, "FILS: Finish association with " MACSTR
,
3993 MAC2STR(sta
->addr
));
3994 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3995 if (!sta
->fils_pending_assoc_req
)
3997 reply_res
= send_assoc_resp(hapd
, sta
, sta
->addr
, WLAN_STATUS_SUCCESS
,
3998 sta
->fils_pending_assoc_is_reassoc
,
3999 sta
->fils_pending_assoc_req
,
4000 sta
->fils_pending_assoc_req_len
, 0);
4001 os_free(sta
->fils_pending_assoc_req
);
4002 sta
->fils_pending_assoc_req
= NULL
;
4003 sta
->fils_pending_assoc_req_len
= 0;
4004 wpabuf_free(sta
->fils_hlp_resp
);
4005 sta
->fils_hlp_resp
= NULL
;
4006 wpabuf_free(sta
->hlp_dhcp_discover
);
4007 sta
->hlp_dhcp_discover
= NULL
;
4010 * Remove the station in case transmission of a success response fails.
4011 * At this point the station was already added associated to the driver.
4013 if (reply_res
!= WLAN_STATUS_SUCCESS
)
4014 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4018 void fils_hlp_timeout(void *eloop_ctx
, void *eloop_data
)
4020 struct hostapd_data
*hapd
= eloop_ctx
;
4021 struct sta_info
*sta
= eloop_data
;
4023 wpa_printf(MSG_DEBUG
,
4024 "FILS: HLP response timeout - continue with association response for "
4025 MACSTR
, MAC2STR(sta
->addr
));
4026 if (sta
->fils_drv_assoc_finish
)
4027 hostapd_notify_assoc_fils_finish(hapd
, sta
);
4029 fils_hlp_finish_assoc(hapd
, sta
);
4032 #endif /* CONFIG_FILS */
4035 static void handle_assoc(struct hostapd_data
*hapd
,
4036 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4037 int reassoc
, int rssi
)
4039 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
4040 u16 resp
= WLAN_STATUS_SUCCESS
, reply_res
;
4043 struct sta_info
*sta
;
4046 int delay_assoc
= 0;
4047 #endif /* CONFIG_FILS */
4049 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
4050 sizeof(mgmt
->u
.assoc_req
))) {
4051 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
4052 reassoc
, (unsigned long) len
);
4056 #ifdef CONFIG_TESTING_OPTIONS
4058 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
4059 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
4060 wpa_printf(MSG_INFO
,
4061 "TESTING: ignoring reassoc request from "
4062 MACSTR
, MAC2STR(mgmt
->sa
));
4066 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
4067 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
4068 wpa_printf(MSG_INFO
,
4069 "TESTING: ignoring assoc request from "
4070 MACSTR
, MAC2STR(mgmt
->sa
));
4074 #endif /* CONFIG_TESTING_OPTIONS */
4076 fc
= le_to_host16(mgmt
->frame_control
);
4077 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4080 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
4081 listen_interval
= le_to_host16(
4082 mgmt
->u
.reassoc_req
.listen_interval
);
4083 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
4084 " capab_info=0x%02x listen_interval=%d current_ap="
4085 MACSTR
" seq_ctrl=0x%x%s",
4086 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
4087 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
4088 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
4089 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
4090 pos
= mgmt
->u
.reassoc_req
.variable
;
4092 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
4093 listen_interval
= le_to_host16(
4094 mgmt
->u
.assoc_req
.listen_interval
);
4095 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
4096 " capab_info=0x%02x listen_interval=%d "
4098 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
4099 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
4100 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
4101 pos
= mgmt
->u
.assoc_req
.variable
;
4104 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4105 #ifdef CONFIG_IEEE80211R_AP
4106 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
4107 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
4108 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
4109 "prior to authentication since it is using "
4110 "over-the-DS FT", MAC2STR(mgmt
->sa
));
4113 * Mark station as authenticated, to avoid adding station
4114 * entry in the driver as associated and not authenticated
4116 sta
->flags
|= WLAN_STA_AUTH
;
4118 #endif /* CONFIG_IEEE80211R_AP */
4119 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
4120 if (hapd
->iface
->current_mode
&&
4121 hapd
->iface
->current_mode
->mode
==
4122 HOSTAPD_MODE_IEEE80211AD
) {
4124 struct radius_sta info
;
4126 acl_res
= ieee802_11_allowed_address(hapd
, mgmt
->sa
,
4129 if (acl_res
== HOSTAPD_ACL_REJECT
) {
4130 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
4131 "Ignore Association Request frame from "
4132 MACSTR
" due to ACL reject",
4134 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4137 if (acl_res
== HOSTAPD_ACL_PENDING
)
4140 /* DMG/IEEE 802.11ad does not use authentication.
4141 * Allocate sta entry upon association. */
4142 sta
= ap_sta_add(hapd
, mgmt
->sa
);
4144 hostapd_logger(hapd
, mgmt
->sa
,
4145 HOSTAPD_MODULE_IEEE80211
,
4147 "Failed to add STA");
4148 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4152 acl_res
= ieee802_11_set_radius_info(
4153 hapd
, sta
, acl_res
, &info
);
4155 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4159 hostapd_logger(hapd
, sta
->addr
,
4160 HOSTAPD_MODULE_IEEE80211
,
4161 HOSTAPD_LEVEL_DEBUG
,
4162 "Skip authentication for DMG/IEEE 802.11ad");
4163 sta
->flags
|= WLAN_STA_AUTH
;
4164 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
4165 sta
->auth_alg
= WLAN_AUTH_OPEN
;
4167 hostapd_logger(hapd
, mgmt
->sa
,
4168 HOSTAPD_MODULE_IEEE80211
,
4170 "Station tried to associate before authentication (aid=%d flags=0x%x)",
4171 sta
? sta
->aid
: -1,
4172 sta
? sta
->flags
: 0);
4173 send_deauth(hapd
, mgmt
->sa
,
4174 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
4179 if ((fc
& WLAN_FC_RETRY
) &&
4180 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4181 sta
->last_seq_ctrl
== seq_ctrl
&&
4182 sta
->last_subtype
== (reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4183 WLAN_FC_STYPE_ASSOC_REQ
)) {
4184 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4185 HOSTAPD_LEVEL_DEBUG
,
4186 "Drop repeated association frame seq_ctrl=0x%x",
4190 sta
->last_seq_ctrl
= seq_ctrl
;
4191 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4192 WLAN_FC_STYPE_ASSOC_REQ
;
4194 if (hapd
->tkip_countermeasures
) {
4195 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4199 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
4200 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4201 HOSTAPD_LEVEL_DEBUG
,
4202 "Too large Listen Interval (%d)",
4204 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
4209 if (hapd
->conf
->mbo_enabled
&& hapd
->mbo_assoc_disallow
) {
4210 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4214 if (hapd
->iconf
->rssi_reject_assoc_rssi
&& rssi
&&
4215 rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
&&
4216 (sta
->auth_rssi
== 0 ||
4217 sta
->auth_rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
)) {
4218 resp
= WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
;
4221 #endif /* CONFIG_MBO */
4224 * sta->capability is used in check_assoc_ies() for RRM enabled
4225 * capability element.
4227 sta
->capability
= capab_info
;
4230 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4231 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4232 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4235 /* The end of the payload is encrypted. Need to decrypt it
4236 * before parsing. */
4238 tmp
= os_memdup(pos
, left
);
4240 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4244 res
= fils_decrypt_assoc(sta
->wpa_sm
, sta
->fils_session
, mgmt
,
4247 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4253 #endif /* CONFIG_FILS */
4255 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
4257 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
4258 if (resp
!= WLAN_STATUS_SUCCESS
)
4261 if (hostapd_get_aid(hapd
, sta
) < 0) {
4262 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4263 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
4264 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4268 sta
->listen_interval
= listen_interval
;
4270 if (hapd
->iface
->current_mode
&&
4271 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
4272 sta
->flags
|= WLAN_STA_NONERP
;
4273 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
4274 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
4275 sta
->flags
&= ~WLAN_STA_NONERP
;
4279 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
4280 sta
->nonerp_set
= 1;
4281 hapd
->iface
->num_sta_non_erp
++;
4282 if (hapd
->iface
->num_sta_non_erp
== 1)
4283 ieee802_11_set_beacons(hapd
->iface
);
4286 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
4287 !sta
->no_short_slot_time_set
) {
4288 sta
->no_short_slot_time_set
= 1;
4289 hapd
->iface
->num_sta_no_short_slot_time
++;
4290 if (hapd
->iface
->current_mode
&&
4291 hapd
->iface
->current_mode
->mode
==
4292 HOSTAPD_MODE_IEEE80211G
&&
4293 hapd
->iface
->num_sta_no_short_slot_time
== 1)
4294 ieee802_11_set_beacons(hapd
->iface
);
4297 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
4298 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
4300 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
4302 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
4303 !sta
->no_short_preamble_set
) {
4304 sta
->no_short_preamble_set
= 1;
4305 hapd
->iface
->num_sta_no_short_preamble
++;
4306 if (hapd
->iface
->current_mode
&&
4307 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
4308 && hapd
->iface
->num_sta_no_short_preamble
== 1)
4309 ieee802_11_set_beacons(hapd
->iface
);
4312 #ifdef CONFIG_IEEE80211N
4313 update_ht_state(hapd
, sta
);
4314 #endif /* CONFIG_IEEE80211N */
4316 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4317 HOSTAPD_LEVEL_DEBUG
,
4318 "association OK (aid %d)", sta
->aid
);
4319 /* Station will be marked associated, after it acknowledges AssocResp
4321 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
4323 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
4324 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
4325 "SA Query procedure", reassoc
? "re" : "");
4326 /* TODO: Send a protected Disassociate frame to the STA using
4327 * the old key and Reason Code "Previous Authentication no
4328 * longer valid". Make sure this is only sent protected since
4329 * unprotected frame would be received by the STA that is now
4330 * trying to associate.
4334 /* Make sure that the previously registered inactivity timer will not
4335 * remove the STA immediately. */
4336 sta
->timeout_next
= STA_NULLFUNC
;
4338 #ifdef CONFIG_TAXONOMY
4339 taxonomy_sta_info_assoc_req(hapd
, sta
, pos
, left
);
4340 #endif /* CONFIG_TAXONOMY */
4342 sta
->pending_wds_enable
= 0;
4345 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4346 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4347 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4348 if (fils_process_hlp(hapd
, sta
, pos
, left
) > 0)
4351 #endif /* CONFIG_FILS */
4356 * In case of a successful response, add the station to the driver.
4357 * Otherwise, the kernel may ignore Data frames before we process the
4358 * ACK frame (TX status). In case of a failure, this station will be
4361 * Note that this is not compliant with the IEEE 802.11 standard that
4362 * states that a non-AP station should transition into the
4363 * authenticated/associated state only after the station acknowledges
4364 * the (Re)Association Response frame. However, still do this as:
4366 * 1. In case the station does not acknowledge the (Re)Association
4367 * Response frame, it will be removed.
4368 * 2. Data frames will be dropped in the kernel until the station is
4369 * set into authorized state, and there are no significant known
4370 * issues with processing other non-Data Class 3 frames during this
4373 if (resp
== WLAN_STATUS_SUCCESS
&& sta
&&
4374 add_associated_sta(hapd
, sta
, reassoc
))
4375 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4378 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
&&
4379 eloop_is_timeout_registered(fils_hlp_timeout
, hapd
, sta
) &&
4380 sta
->fils_pending_assoc_req
) {
4381 /* Do not reschedule fils_hlp_timeout in case the station
4382 * retransmits (Re)Association Request frame while waiting for
4383 * the previously started FILS HLP wait, so that the timeout can
4384 * be determined from the first pending attempt. */
4385 wpa_printf(MSG_DEBUG
,
4386 "FILS: Continue waiting for HLP processing before sending (Re)Association Response frame to "
4387 MACSTR
, MAC2STR(sta
->addr
));
4392 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4393 os_free(sta
->fils_pending_assoc_req
);
4394 sta
->fils_pending_assoc_req
= NULL
;
4395 sta
->fils_pending_assoc_req_len
= 0;
4396 wpabuf_free(sta
->fils_hlp_resp
);
4397 sta
->fils_hlp_resp
= NULL
;
4399 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
) {
4400 sta
->fils_pending_assoc_req
= tmp
;
4401 sta
->fils_pending_assoc_req_len
= left
;
4402 sta
->fils_pending_assoc_is_reassoc
= reassoc
;
4403 sta
->fils_drv_assoc_finish
= 0;
4404 wpa_printf(MSG_DEBUG
,
4405 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
4406 MACSTR
, MAC2STR(sta
->addr
));
4407 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4408 eloop_register_timeout(0, hapd
->conf
->fils_hlp_wait_time
* 1024,
4409 fils_hlp_timeout
, hapd
, sta
);
4412 #endif /* CONFIG_FILS */
4414 reply_res
= send_assoc_resp(hapd
, sta
, mgmt
->sa
, resp
, reassoc
, pos
,
4419 * Remove the station in case tranmission of a success response fails
4420 * (the STA was added associated to the driver) or if the station was
4421 * previously added unassociated.
4423 if (sta
&& ((reply_res
!= WLAN_STATUS_SUCCESS
&&
4424 resp
== WLAN_STATUS_SUCCESS
) || sta
->added_unassoc
)) {
4425 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4426 sta
->added_unassoc
= 0;
4431 static void handle_disassoc(struct hostapd_data
*hapd
,
4432 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4434 struct sta_info
*sta
;
4436 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
4437 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
4438 (unsigned long) len
);
4442 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
4444 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4446 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4448 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
4453 ap_sta_set_authorized(hapd
, sta
, 0);
4454 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4455 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
4456 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
4457 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4458 HOSTAPD_LEVEL_INFO
, "disassociated");
4459 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4460 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4461 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
4463 accounting_sta_stop(hapd
, sta
);
4464 ieee802_1x_free_station(hapd
, sta
);
4466 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
4467 ap_sta_ip6addr_del(hapd
, sta
);
4468 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4469 sta
->added_unassoc
= 0;
4471 if (sta
->timeout_next
== STA_NULLFUNC
||
4472 sta
->timeout_next
== STA_DISASSOC
) {
4473 sta
->timeout_next
= STA_DEAUTH
;
4474 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
4475 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
4479 mlme_disassociate_indication(
4480 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4482 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
4483 * disassociation. */
4484 if (hapd
->iface
->current_mode
&&
4485 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
) {
4486 sta
->flags
&= ~WLAN_STA_AUTH
;
4487 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4488 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4489 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4490 ap_free_sta(hapd
, sta
);
4495 static void handle_deauth(struct hostapd_data
*hapd
,
4496 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4498 struct sta_info
*sta
;
4500 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
4501 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
4502 "payload (len=%lu)", (unsigned long) len
);
4506 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
4508 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
4510 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4512 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
4513 "to deauthenticate, but it is not authenticated",
4518 ap_sta_set_authorized(hapd
, sta
, 0);
4519 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4520 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
4521 WLAN_STA_ASSOC_REQ_OK
);
4522 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4523 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4524 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4525 mlme_deauthenticate_indication(
4526 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
4527 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4528 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4529 ap_free_sta(hapd
, sta
);
4533 static void handle_beacon(struct hostapd_data
*hapd
,
4534 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4535 struct hostapd_frame_info
*fi
)
4537 struct ieee802_11_elems elems
;
4539 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
4540 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
4541 (unsigned long) len
);
4545 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
4546 len
- (IEEE80211_HDRLEN
+
4547 sizeof(mgmt
->u
.beacon
)), &elems
,
4550 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
4554 static int robust_action_frame(u8 category
)
4556 return category
!= WLAN_ACTION_PUBLIC
&&
4557 category
!= WLAN_ACTION_HT
;
4561 static int handle_action(struct hostapd_data
*hapd
,
4562 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4565 struct sta_info
*sta
;
4566 u8
*action __maybe_unused
;
4568 if (len
< IEEE80211_HDRLEN
+ 2 + 1) {
4569 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4570 HOSTAPD_LEVEL_DEBUG
,
4571 "handle_action - too short payload (len=%lu)",
4572 (unsigned long) len
);
4576 action
= (u8
*) &mgmt
->u
.action
.u
;
4577 wpa_printf(MSG_DEBUG
, "RX_ACTION category %u action %u sa " MACSTR
4578 " da " MACSTR
" len %d freq %u",
4579 mgmt
->u
.action
.category
, *action
,
4580 MAC2STR(mgmt
->sa
), MAC2STR(mgmt
->da
), (int) len
, freq
);
4582 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4584 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
4585 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
4586 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
4587 "frame (category=%u) from unassociated STA " MACSTR
,
4588 mgmt
->u
.action
.category
, MAC2STR(mgmt
->sa
));
4592 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
4593 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
4594 robust_action_frame(mgmt
->u
.action
.category
)) {
4595 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4596 HOSTAPD_LEVEL_DEBUG
,
4597 "Dropped unprotected Robust Action frame from "
4603 u16 fc
= le_to_host16(mgmt
->frame_control
);
4604 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4606 if ((fc
& WLAN_FC_RETRY
) &&
4607 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4608 sta
->last_seq_ctrl
== seq_ctrl
&&
4609 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
4610 hostapd_logger(hapd
, sta
->addr
,
4611 HOSTAPD_MODULE_IEEE80211
,
4612 HOSTAPD_LEVEL_DEBUG
,
4613 "Drop repeated action frame seq_ctrl=0x%x",
4618 sta
->last_seq_ctrl
= seq_ctrl
;
4619 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
4622 switch (mgmt
->u
.action
.category
) {
4623 #ifdef CONFIG_IEEE80211R_AP
4624 case WLAN_ACTION_FT
:
4626 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
4627 len
- IEEE80211_HDRLEN
))
4630 #endif /* CONFIG_IEEE80211R_AP */
4631 case WLAN_ACTION_WMM
:
4632 hostapd_wmm_action(hapd
, mgmt
, len
);
4634 case WLAN_ACTION_SA_QUERY
:
4635 ieee802_11_sa_query_action(hapd
, mgmt
, len
);
4637 #ifdef CONFIG_WNM_AP
4638 case WLAN_ACTION_WNM
:
4639 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
4641 #endif /* CONFIG_WNM_AP */
4643 case WLAN_ACTION_FST
:
4644 if (hapd
->iface
->fst
)
4645 fst_rx_action(hapd
->iface
->fst
, mgmt
, len
);
4647 wpa_printf(MSG_DEBUG
,
4648 "FST: Ignore FST Action frame - no FST attached");
4650 #endif /* CONFIG_FST */
4651 case WLAN_ACTION_PUBLIC
:
4652 case WLAN_ACTION_PROTECTED_DUAL
:
4653 #ifdef CONFIG_IEEE80211N
4654 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4655 mgmt
->u
.action
.u
.public_action
.action
==
4656 WLAN_PA_20_40_BSS_COEX
) {
4657 hostapd_2040_coex_action(hapd
, mgmt
, len
);
4660 #endif /* CONFIG_IEEE80211N */
4662 if (len
>= IEEE80211_HDRLEN
+ 6 &&
4663 mgmt
->u
.action
.u
.vs_public_action
.action
==
4664 WLAN_PA_VENDOR_SPECIFIC
&&
4665 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4667 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4669 const u8
*pos
, *end
;
4671 pos
= mgmt
->u
.action
.u
.vs_public_action
.oui
;
4672 end
= ((const u8
*) mgmt
) + len
;
4673 hostapd_dpp_rx_action(hapd
, mgmt
->sa
, pos
, end
- pos
,
4677 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4678 (mgmt
->u
.action
.u
.public_action
.action
==
4679 WLAN_PA_GAS_INITIAL_RESP
||
4680 mgmt
->u
.action
.u
.public_action
.action
==
4681 WLAN_PA_GAS_COMEBACK_RESP
)) {
4682 const u8
*pos
, *end
;
4684 pos
= &mgmt
->u
.action
.u
.public_action
.action
;
4685 end
= ((const u8
*) mgmt
) + len
;
4686 gas_query_ap_rx(hapd
->gas
, mgmt
->sa
,
4687 mgmt
->u
.action
.category
,
4688 pos
, end
- pos
, hapd
->iface
->freq
);
4691 #endif /* CONFIG_DPP */
4692 if (hapd
->public_action_cb
) {
4693 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
4697 if (hapd
->public_action_cb2
) {
4698 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
4702 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
4705 case WLAN_ACTION_VENDOR_SPECIFIC
:
4706 if (hapd
->vendor_action_cb
) {
4707 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
4709 hapd
->iface
->freq
) == 0)
4713 case WLAN_ACTION_RADIO_MEASUREMENT
:
4714 hostapd_handle_radio_measurement(hapd
, (const u8
*) mgmt
, len
);
4718 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4719 HOSTAPD_LEVEL_DEBUG
,
4720 "handle_action - unknown action category %d or invalid "
4722 mgmt
->u
.action
.category
);
4723 if (!is_multicast_ether_addr(mgmt
->da
) &&
4724 !(mgmt
->u
.action
.category
& 0x80) &&
4725 !is_multicast_ether_addr(mgmt
->sa
)) {
4726 struct ieee80211_mgmt
*resp
;
4729 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
4730 * Return the Action frame to the source without change
4731 * except that MSB of the Category set to 1.
4733 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
4734 "frame back to sender");
4735 resp
= os_memdup(mgmt
, len
);
4738 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
4739 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
4740 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
4741 resp
->u
.action
.category
|= 0x80;
4743 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0, NULL
, 0, 0) < 0) {
4744 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
4755 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
4756 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
4758 * @buf: management frame data (starting from IEEE 802.11 header)
4759 * @len: length of frame data in octets
4760 * @fi: meta data about received frame (signal level, etc.)
4762 * Process all incoming IEEE 802.11 management frames. This will be called for
4763 * each frame received from the kernel driver through wlan#ap interface. In
4764 * addition, it can be called to re-inserted pending frames (e.g., when using
4765 * external RADIUS server as an MAC ACL).
4767 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4768 struct hostapd_frame_info
*fi
)
4770 struct ieee80211_mgmt
*mgmt
;
4774 int ssi_signal
= fi
? fi
->ssi_signal
: 0;
4782 freq
= hapd
->iface
->freq
;
4784 mgmt
= (struct ieee80211_mgmt
*) buf
;
4785 fc
= le_to_host16(mgmt
->frame_control
);
4786 stype
= WLAN_FC_GET_STYPE(fc
);
4788 if (is_multicast_ether_addr(mgmt
->sa
) ||
4789 is_zero_ether_addr(mgmt
->sa
) ||
4790 os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
4791 /* Do not process any frames with unexpected/invalid SA so that
4792 * we do not add any state for unexpected STA addresses or end
4793 * up sending out frames to unexpected destination. */
4794 wpa_printf(MSG_DEBUG
, "MGMT: Invalid SA=" MACSTR
4795 " in received frame - ignore this frame silently",
4800 if (stype
== WLAN_FC_STYPE_BEACON
) {
4801 handle_beacon(hapd
, mgmt
, len
, fi
);
4805 if (!is_broadcast_ether_addr(mgmt
->bssid
) &&
4807 /* Invitation responses can be sent with the peer MAC as BSSID */
4808 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
4809 stype
== WLAN_FC_STYPE_ACTION
) &&
4810 #endif /* CONFIG_P2P */
4812 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
4813 #endif /* CONFIG_MESH */
4814 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4815 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
4816 MAC2STR(mgmt
->bssid
));
4821 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
4822 handle_probe_req(hapd
, mgmt
, len
, ssi_signal
);
4826 if ((!is_broadcast_ether_addr(mgmt
->da
) ||
4827 stype
!= WLAN_FC_STYPE_ACTION
) &&
4828 os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4829 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4830 HOSTAPD_LEVEL_DEBUG
,
4831 "MGMT: DA=" MACSTR
" not our address",
4836 if (hapd
->iconf
->track_sta_max_num
)
4837 sta_track_add(hapd
->iface
, mgmt
->sa
, ssi_signal
);
4840 case WLAN_FC_STYPE_AUTH
:
4841 wpa_printf(MSG_DEBUG
, "mgmt::auth");
4842 handle_auth(hapd
, mgmt
, len
, ssi_signal
, 0);
4845 case WLAN_FC_STYPE_ASSOC_REQ
:
4846 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
4847 handle_assoc(hapd
, mgmt
, len
, 0, ssi_signal
);
4850 case WLAN_FC_STYPE_REASSOC_REQ
:
4851 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
4852 handle_assoc(hapd
, mgmt
, len
, 1, ssi_signal
);
4855 case WLAN_FC_STYPE_DISASSOC
:
4856 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
4857 handle_disassoc(hapd
, mgmt
, len
);
4860 case WLAN_FC_STYPE_DEAUTH
:
4861 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
4862 handle_deauth(hapd
, mgmt
, len
);
4865 case WLAN_FC_STYPE_ACTION
:
4866 wpa_printf(MSG_DEBUG
, "mgmt::action");
4867 ret
= handle_action(hapd
, mgmt
, len
, freq
);
4870 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4871 HOSTAPD_LEVEL_DEBUG
,
4872 "unknown mgmt frame subtype %d", stype
);
4880 static void handle_auth_cb(struct hostapd_data
*hapd
,
4881 const struct ieee80211_mgmt
*mgmt
,
4884 u16 auth_alg
, auth_transaction
, status_code
;
4885 struct sta_info
*sta
;
4887 sta
= ap_get_sta(hapd
, mgmt
->da
);
4889 wpa_printf(MSG_DEBUG
, "handle_auth_cb: STA " MACSTR
4895 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
4896 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
4897 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
4900 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4901 HOSTAPD_LEVEL_NOTICE
,
4902 "did not acknowledge authentication response");
4906 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
4907 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
4908 (unsigned long) len
);
4912 if (status_code
== WLAN_STATUS_SUCCESS
&&
4913 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
4914 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
4915 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4916 HOSTAPD_LEVEL_INFO
, "authenticated");
4917 sta
->flags
|= WLAN_STA_AUTH
;
4918 if (sta
->added_unassoc
)
4919 hostapd_set_sta_flags(hapd
, sta
);
4924 if (status_code
!= WLAN_STATUS_SUCCESS
&& sta
->added_unassoc
) {
4925 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4926 sta
->added_unassoc
= 0;
4931 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
4932 struct sta_info
*sta
,
4936 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
4938 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
4941 for (i
= 0; i
< 4; i
++) {
4942 if (ssid
->wep
.key
[i
] &&
4943 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
4944 0, i
== ssid
->wep
.idx
, NULL
, 0,
4945 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
],
4946 i
== ssid
->wep
.idx
?
4947 KEY_FLAG_GROUP_RX_TX_DEFAULT
:
4948 KEY_FLAG_GROUP_RX_TX
)) {
4949 wpa_printf(MSG_WARNING
,
4950 "Could not set WEP keys for WDS interface; %s",
4958 static void handle_assoc_cb(struct hostapd_data
*hapd
,
4959 const struct ieee80211_mgmt
*mgmt
,
4960 size_t len
, int reassoc
, int ok
)
4963 struct sta_info
*sta
;
4966 sta
= ap_get_sta(hapd
, mgmt
->da
);
4968 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
4973 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
4974 sizeof(mgmt
->u
.assoc_resp
))) {
4975 wpa_printf(MSG_INFO
,
4976 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
4977 reassoc
, (unsigned long) len
);
4978 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4983 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
4985 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
4988 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4989 HOSTAPD_LEVEL_DEBUG
,
4990 "did not acknowledge association response");
4991 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
4992 /* The STA is added only in case of SUCCESS */
4993 if (status
== WLAN_STATUS_SUCCESS
)
4994 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4999 if (status
!= WLAN_STATUS_SUCCESS
)
5002 /* Stop previous accounting session, if one is started, and allocate
5003 * new session id for the new session. */
5004 accounting_sta_stop(hapd
, sta
);
5006 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
5008 "associated (aid %d)",
5011 if (sta
->flags
& WLAN_STA_ASSOC
)
5013 sta
->flags
|= WLAN_STA_ASSOC
;
5014 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
5015 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
5016 !hapd
->conf
->osen
) ||
5017 sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
5018 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
5019 sta
->auth_alg
== WLAN_AUTH_FILS_PK
||
5020 sta
->auth_alg
== WLAN_AUTH_FT
) {
5022 * Open, static WEP, FT protocol, or FILS; no separate
5023 * authorization step.
5025 ap_sta_set_authorized(hapd
, sta
, 1);
5029 mlme_reassociate_indication(hapd
, sta
);
5031 mlme_associate_indication(hapd
, sta
);
5033 sta
->sa_query_timed_out
= 0;
5035 if (sta
->eapol_sm
== NULL
) {
5037 * This STA does not use RADIUS server for EAP authentication,
5038 * so bind it to the selected VLAN interface now, since the
5039 * interface selection is not going to change anymore.
5041 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
5043 } else if (sta
->vlan_id
) {
5044 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
5045 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
5049 hostapd_set_sta_flags(hapd
, sta
);
5051 if (!(sta
->flags
& WLAN_STA_WDS
) && sta
->pending_wds_enable
) {
5052 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for STA "
5053 MACSTR
" based on pending request",
5054 MAC2STR(sta
->addr
));
5055 sta
->pending_wds_enable
= 0;
5056 sta
->flags
|= WLAN_STA_WDS
;
5059 if (sta
->flags
& (WLAN_STA_WDS
| WLAN_STA_MULTI_AP
)) {
5061 char ifname_wds
[IFNAMSIZ
+ 1];
5063 wpa_printf(MSG_DEBUG
, "Reenable 4-address WDS mode for STA "
5065 MAC2STR(sta
->addr
), sta
->aid
);
5066 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
5069 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
5072 if (sta
->auth_alg
== WLAN_AUTH_FT
)
5073 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
5075 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
5076 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
5077 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
5080 if ((sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
5081 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
5082 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
5083 fils_set_tk(sta
->wpa_sm
) < 0) {
5084 wpa_printf(MSG_DEBUG
, "FILS: TK configuration failed");
5085 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
5086 WLAN_REASON_UNSPECIFIED
);
5089 #endif /* CONFIG_FILS */
5091 if (sta
->pending_eapol_rx
) {
5092 struct os_reltime now
, age
;
5094 os_get_reltime(&now
);
5095 os_reltime_sub(&now
, &sta
->pending_eapol_rx
->rx_time
, &age
);
5096 if (age
.sec
== 0 && age
.usec
< 200000) {
5097 wpa_printf(MSG_DEBUG
,
5098 "Process pending EAPOL frame that was received from " MACSTR
" just before association notification",
5099 MAC2STR(sta
->addr
));
5102 wpabuf_head(sta
->pending_eapol_rx
->buf
),
5103 wpabuf_len(sta
->pending_eapol_rx
->buf
));
5105 wpabuf_free(sta
->pending_eapol_rx
->buf
);
5106 os_free(sta
->pending_eapol_rx
);
5107 sta
->pending_eapol_rx
= NULL
;
5112 static void handle_deauth_cb(struct hostapd_data
*hapd
,
5113 const struct ieee80211_mgmt
*mgmt
,
5116 struct sta_info
*sta
;
5117 if (is_multicast_ether_addr(mgmt
->da
))
5119 sta
= ap_get_sta(hapd
, mgmt
->da
);
5121 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
5122 " not found", MAC2STR(mgmt
->da
));
5126 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
5127 MAC2STR(sta
->addr
));
5129 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
5130 "deauth", MAC2STR(sta
->addr
));
5132 ap_sta_deauth_cb(hapd
, sta
);
5136 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
5137 const struct ieee80211_mgmt
*mgmt
,
5140 struct sta_info
*sta
;
5141 if (is_multicast_ether_addr(mgmt
->da
))
5143 sta
= ap_get_sta(hapd
, mgmt
->da
);
5145 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
5146 " not found", MAC2STR(mgmt
->da
));
5150 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
5151 MAC2STR(sta
->addr
));
5153 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
5154 "disassoc", MAC2STR(sta
->addr
));
5156 ap_sta_disassoc_cb(hapd
, sta
);
5160 static void handle_action_cb(struct hostapd_data
*hapd
,
5161 const struct ieee80211_mgmt
*mgmt
,
5164 struct sta_info
*sta
;
5165 const struct rrm_measurement_report_element
*report
;
5167 if (is_multicast_ether_addr(mgmt
->da
))
5170 if (len
>= IEEE80211_HDRLEN
+ 6 &&
5171 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5172 mgmt
->u
.action
.u
.vs_public_action
.action
==
5173 WLAN_PA_VENDOR_SPECIFIC
&&
5174 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
5176 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
5178 const u8
*pos
, *end
;
5180 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
5181 end
= ((const u8
*) mgmt
) + len
;
5182 hostapd_dpp_tx_status(hapd
, mgmt
->da
, pos
, end
- pos
, ok
);
5185 if (len
>= IEEE80211_HDRLEN
+ 2 &&
5186 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5187 (mgmt
->u
.action
.u
.public_action
.action
==
5188 WLAN_PA_GAS_INITIAL_REQ
||
5189 mgmt
->u
.action
.u
.public_action
.action
==
5190 WLAN_PA_GAS_COMEBACK_REQ
)) {
5191 const u8
*pos
, *end
;
5193 pos
= mgmt
->u
.action
.u
.public_action
.variable
;
5194 end
= ((const u8
*) mgmt
) + len
;
5195 gas_query_ap_tx_status(hapd
->gas
, mgmt
->da
, pos
, end
- pos
, ok
);
5198 #endif /* CONFIG_DPP */
5199 sta
= ap_get_sta(hapd
, mgmt
->da
);
5201 wpa_printf(MSG_DEBUG
, "handle_action_cb: STA " MACSTR
5202 " not found", MAC2STR(mgmt
->da
));
5206 if (len
< 24 + 5 + sizeof(*report
))
5208 report
= (const struct rrm_measurement_report_element
*)
5209 &mgmt
->u
.action
.u
.rrm
.variable
[2];
5210 if (mgmt
->u
.action
.category
== WLAN_ACTION_RADIO_MEASUREMENT
&&
5211 mgmt
->u
.action
.u
.rrm
.action
== WLAN_RRM_RADIO_MEASUREMENT_REQUEST
&&
5212 report
->eid
== WLAN_EID_MEASURE_REQUEST
&&
5214 report
->type
== MEASURE_TYPE_BEACON
)
5215 hostapd_rrm_beacon_req_tx_status(hapd
, mgmt
, len
, ok
);
5220 * ieee802_11_mgmt_cb - Process management frame TX status callback
5221 * @hapd: hostapd BSS data structure (the BSS from which the management frame
5223 * @buf: management frame data (starting from IEEE 802.11 header)
5224 * @len: length of frame data in octets
5225 * @stype: management frame subtype from frame control field
5226 * @ok: Whether the frame was ACK'ed
5228 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
5231 const struct ieee80211_mgmt
*mgmt
;
5232 mgmt
= (const struct ieee80211_mgmt
*) buf
;
5234 #ifdef CONFIG_TESTING_OPTIONS
5235 if (hapd
->ext_mgmt_frame_handling
) {
5236 size_t hex_len
= 2 * len
+ 1;
5237 char *hex
= os_malloc(hex_len
);
5240 wpa_snprintf_hex(hex
, hex_len
, buf
, len
);
5241 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
5242 "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
5248 #endif /* CONFIG_TESTING_OPTIONS */
5251 case WLAN_FC_STYPE_AUTH
:
5252 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
5253 handle_auth_cb(hapd
, mgmt
, len
, ok
);
5255 case WLAN_FC_STYPE_ASSOC_RESP
:
5256 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
5257 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
5259 case WLAN_FC_STYPE_REASSOC_RESP
:
5260 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
5261 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
5263 case WLAN_FC_STYPE_PROBE_RESP
:
5264 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb ok=%d", ok
);
5266 case WLAN_FC_STYPE_DEAUTH
:
5267 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
5268 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
5270 case WLAN_FC_STYPE_DISASSOC
:
5271 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
5272 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
5274 case WLAN_FC_STYPE_ACTION
:
5275 wpa_printf(MSG_DEBUG
, "mgmt::action cb ok=%d", ok
);
5276 handle_action_cb(hapd
, mgmt
, len
, ok
);
5279 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
5285 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
5292 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
5293 char *buf
, size_t buflen
)
5300 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
5301 const u8
*buf
, size_t len
, int ack
)
5303 struct sta_info
*sta
;
5304 struct hostapd_iface
*iface
= hapd
->iface
;
5306 sta
= ap_get_sta(hapd
, addr
);
5307 if (sta
== NULL
&& iface
->num_bss
> 1) {
5309 for (j
= 0; j
< iface
->num_bss
; j
++) {
5310 hapd
= iface
->bss
[j
];
5311 sta
= ap_get_sta(hapd
, addr
);
5316 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
5318 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
5319 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
5320 "activity poll", MAC2STR(sta
->addr
),
5321 ack
? "ACKed" : "did not ACK");
5323 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5326 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
5330 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
5331 const u8
*data
, size_t len
, int ack
)
5333 struct sta_info
*sta
;
5334 struct hostapd_iface
*iface
= hapd
->iface
;
5336 sta
= ap_get_sta(hapd
, dst
);
5337 if (sta
== NULL
&& iface
->num_bss
> 1) {
5339 for (j
= 0; j
< iface
->num_bss
; j
++) {
5340 hapd
= iface
->bss
[j
];
5341 sta
= ap_get_sta(hapd
, dst
);
5346 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
5347 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
5348 MACSTR
" that is not currently associated",
5353 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
5357 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
5359 struct sta_info
*sta
;
5360 struct hostapd_iface
*iface
= hapd
->iface
;
5362 sta
= ap_get_sta(hapd
, addr
);
5363 if (sta
== NULL
&& iface
->num_bss
> 1) {
5365 for (j
= 0; j
< iface
->num_bss
; j
++) {
5366 hapd
= iface
->bss
[j
];
5367 sta
= ap_get_sta(hapd
, addr
);
5374 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_POLL_OK MACSTR
,
5375 MAC2STR(sta
->addr
));
5376 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
5379 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
5380 "activity poll", MAC2STR(sta
->addr
));
5381 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5385 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
5388 struct sta_info
*sta
;
5390 sta
= ap_get_sta(hapd
, src
);
5392 ((sta
->flags
& WLAN_STA_ASSOC
) ||
5393 ((sta
->flags
& WLAN_STA_ASSOC_REQ_OK
) && wds
))) {
5394 if (!hapd
->conf
->wds_sta
)
5397 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
)) ==
5398 WLAN_STA_ASSOC_REQ_OK
) {
5399 wpa_printf(MSG_DEBUG
,
5400 "Postpone 4-address WDS mode enabling for STA "
5401 MACSTR
" since TX status for AssocResp is not yet known",
5402 MAC2STR(sta
->addr
));
5403 sta
->pending_wds_enable
= 1;
5407 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
5409 char ifname_wds
[IFNAMSIZ
+ 1];
5411 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
5412 "STA " MACSTR
" (aid %u)",
5413 MAC2STR(sta
->addr
), sta
->aid
);
5414 sta
->flags
|= WLAN_STA_WDS
;
5415 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
5416 sta
->addr
, sta
->aid
, 1);
5418 hostapd_set_wds_encryption(hapd
, sta
,
5424 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
5425 MACSTR
, MAC2STR(src
));
5426 if (is_multicast_ether_addr(src
) || is_zero_ether_addr(src
) ||
5427 os_memcmp(src
, hapd
->own_addr
, ETH_ALEN
) == 0) {
5428 /* Broadcast bit set in SA or unexpected SA?! Ignore the frame
5433 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
5434 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
5435 "already been sent, but no TX status yet known - "
5436 "ignore Class 3 frame issue with " MACSTR
,
5441 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
5442 hostapd_drv_sta_disassoc(
5444 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5446 hostapd_drv_sta_deauth(
5448 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5452 #endif /* CONFIG_NATIVE_WINDOWS */