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
)
92 if (hapd
->iface
->current_rates
== NULL
)
95 *pos
++ = WLAN_EID_SUPP_RATES
;
96 num
= hapd
->iface
->num_rates
;
97 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
99 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
102 /* rest of the rates are encoded in Extended supported
108 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
;
111 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
112 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
117 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&& count
< 8) {
119 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
122 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&& count
< 8) {
124 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
131 u8
* hostapd_eid_ext_supp_rates(struct hostapd_data
*hapd
, u8
*eid
)
136 if (hapd
->iface
->current_rates
== NULL
)
139 num
= hapd
->iface
->num_rates
;
140 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
)
142 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
)
148 *pos
++ = WLAN_EID_EXT_SUPP_RATES
;
150 for (i
= 0, count
= 0; i
< hapd
->iface
->num_rates
&& count
< num
+ 8;
154 continue; /* already in SuppRates IE */
155 *pos
= hapd
->iface
->current_rates
[i
].rate
/ 5;
156 if (hapd
->iface
->current_rates
[i
].flags
& HOSTAPD_RATE_BASIC
)
161 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
) {
164 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY
;
167 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
) {
170 *pos
++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY
;
177 u16
hostapd_own_capab_info(struct hostapd_data
*hapd
)
179 int capab
= WLAN_CAPABILITY_ESS
;
184 /* Check if any of configured channels require DFS */
185 dfs
= hostapd_is_dfs_required(hapd
->iface
);
187 wpa_printf(MSG_WARNING
, "Failed to check if DFS is required; ret=%d",
192 if (hapd
->iface
->num_sta_no_short_preamble
== 0 &&
193 hapd
->iconf
->preamble
== SHORT_PREAMBLE
)
194 capab
|= WLAN_CAPABILITY_SHORT_PREAMBLE
;
196 privacy
= hapd
->conf
->ssid
.wep
.keys_set
;
198 if (hapd
->conf
->ieee802_1x
&&
199 (hapd
->conf
->default_wep_key_len
||
200 hapd
->conf
->individual_wep_key_len
))
207 if (hapd
->conf
->osen
)
209 #endif /* CONFIG_HS20 */
212 capab
|= WLAN_CAPABILITY_PRIVACY
;
214 if (hapd
->iface
->current_mode
&&
215 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
&&
216 hapd
->iface
->num_sta_no_short_slot_time
== 0)
217 capab
|= WLAN_CAPABILITY_SHORT_SLOT_TIME
;
220 * Currently, Spectrum Management capability bit is set when directly
221 * requested in configuration by spectrum_mgmt_required or when AP is
222 * running on DFS channel.
223 * TODO: Also consider driver support for TPC to set Spectrum Mgmt bit
225 if (hapd
->iface
->current_mode
&&
226 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211A
&&
227 (hapd
->iconf
->spectrum_mgmt_required
|| dfs
))
228 capab
|= WLAN_CAPABILITY_SPECTRUM_MGMT
;
230 for (i
= 0; i
< RRM_CAPABILITIES_IE_LEN
; i
++) {
231 if (hapd
->conf
->radio_measurements
[i
]) {
232 capab
|= IEEE80211_CAP_RRM
;
241 #ifndef CONFIG_NO_RC4
242 static u16
auth_shared_key(struct hostapd_data
*hapd
, struct sta_info
*sta
,
243 u16 auth_transaction
, const u8
*challenge
,
246 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
248 "authentication (shared key, transaction %d)",
251 if (auth_transaction
== 1) {
252 if (!sta
->challenge
) {
253 /* Generate a pseudo-random challenge */
256 sta
->challenge
= os_zalloc(WLAN_AUTH_CHALLENGE_LEN
);
257 if (sta
->challenge
== NULL
)
258 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
260 if (os_get_random(key
, sizeof(key
)) < 0) {
261 os_free(sta
->challenge
);
262 sta
->challenge
= NULL
;
263 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
266 rc4_skip(key
, sizeof(key
), 0,
267 sta
->challenge
, WLAN_AUTH_CHALLENGE_LEN
);
272 if (auth_transaction
!= 3)
273 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
276 if (!iswep
|| !sta
->challenge
|| !challenge
||
277 os_memcmp_const(sta
->challenge
, challenge
,
278 WLAN_AUTH_CHALLENGE_LEN
)) {
279 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
281 "shared key authentication - invalid "
282 "challenge-response");
283 return WLAN_STATUS_CHALLENGE_FAIL
;
286 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
288 "authentication OK (shared key)");
289 sta
->flags
|= WLAN_STA_AUTH
;
290 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
291 os_free(sta
->challenge
);
292 sta
->challenge
= NULL
;
296 #endif /* CONFIG_NO_RC4 */
299 static int send_auth_reply(struct hostapd_data
*hapd
,
300 const u8
*dst
, const u8
*bssid
,
301 u16 auth_alg
, u16 auth_transaction
, u16 resp
,
302 const u8
*ies
, size_t ies_len
, const char *dbg
)
304 struct ieee80211_mgmt
*reply
;
307 int reply_res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
309 rlen
= IEEE80211_HDRLEN
+ sizeof(reply
->u
.auth
) + ies_len
;
310 buf
= os_zalloc(rlen
);
314 reply
= (struct ieee80211_mgmt
*) buf
;
315 reply
->frame_control
= IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
317 os_memcpy(reply
->da
, dst
, ETH_ALEN
);
318 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
319 os_memcpy(reply
->bssid
, bssid
, ETH_ALEN
);
321 reply
->u
.auth
.auth_alg
= host_to_le16(auth_alg
);
322 reply
->u
.auth
.auth_transaction
= host_to_le16(auth_transaction
);
323 reply
->u
.auth
.status_code
= host_to_le16(resp
);
326 os_memcpy(reply
->u
.auth
.variable
, ies
, ies_len
);
328 wpa_printf(MSG_DEBUG
, "authentication reply: STA=" MACSTR
329 " auth_alg=%d auth_transaction=%d resp=%d (IE len=%lu) (dbg=%s)",
330 MAC2STR(dst
), auth_alg
, auth_transaction
,
331 resp
, (unsigned long) ies_len
, dbg
);
332 if (hostapd_drv_send_mlme(hapd
, reply
, rlen
, 0) < 0)
333 wpa_printf(MSG_INFO
, "send_auth_reply: send failed");
335 reply_res
= WLAN_STATUS_SUCCESS
;
343 #ifdef CONFIG_IEEE80211R_AP
344 static void handle_auth_ft_finish(void *ctx
, const u8
*dst
, const u8
*bssid
,
345 u16 auth_transaction
, u16 status
,
346 const u8
*ies
, size_t ies_len
)
348 struct hostapd_data
*hapd
= ctx
;
349 struct sta_info
*sta
;
352 reply_res
= send_auth_reply(hapd
, dst
, bssid
, WLAN_AUTH_FT
,
353 auth_transaction
, status
, ies
, ies_len
,
356 sta
= ap_get_sta(hapd
, dst
);
360 if (sta
->added_unassoc
&& (reply_res
!= WLAN_STATUS_SUCCESS
||
361 status
!= WLAN_STATUS_SUCCESS
)) {
362 hostapd_drv_sta_remove(hapd
, sta
->addr
);
363 sta
->added_unassoc
= 0;
367 if (status
!= WLAN_STATUS_SUCCESS
)
370 hostapd_logger(hapd
, dst
, HOSTAPD_MODULE_IEEE80211
,
371 HOSTAPD_LEVEL_DEBUG
, "authentication OK (FT)");
372 sta
->flags
|= WLAN_STA_AUTH
;
373 mlme_authenticate_indication(hapd
, sta
);
375 #endif /* CONFIG_IEEE80211R_AP */
380 static void sae_set_state(struct sta_info
*sta
, enum sae_state state
,
383 wpa_printf(MSG_DEBUG
, "SAE: State %s -> %s for peer " MACSTR
" (%s)",
384 sae_state_txt(sta
->sae
->state
), sae_state_txt(state
),
385 MAC2STR(sta
->addr
), reason
);
386 sta
->sae
->state
= state
;
390 static struct wpabuf
* auth_build_sae_commit(struct hostapd_data
*hapd
,
391 struct sta_info
*sta
, int update
)
394 const char *password
= NULL
;
395 struct sae_password_entry
*pw
;
396 const char *rx_id
= NULL
;
399 rx_id
= sta
->sae
->tmp
->pw_id
;
401 for (pw
= hapd
->conf
->sae_passwords
; pw
; pw
= pw
->next
) {
402 if (!is_broadcast_ether_addr(pw
->peer_addr
) &&
403 os_memcmp(pw
->peer_addr
, sta
->addr
, ETH_ALEN
) != 0)
405 if ((rx_id
&& !pw
->identifier
) || (!rx_id
&& pw
->identifier
))
407 if (rx_id
&& pw
->identifier
&&
408 os_strcmp(rx_id
, pw
->identifier
) != 0)
410 password
= pw
->password
;
414 password
= hapd
->conf
->ssid
.wpa_passphrase
;
416 wpa_printf(MSG_DEBUG
, "SAE: No password available");
421 sae_prepare_commit(hapd
->own_addr
, sta
->addr
,
422 (u8
*) password
, os_strlen(password
), rx_id
,
424 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
428 if (pw
&& pw
->vlan_id
) {
429 if (!sta
->sae
->tmp
) {
431 "SAE: No temporary data allocated - cannot store VLAN ID");
434 sta
->sae
->tmp
->vlan_id
= pw
->vlan_id
;
437 buf
= wpabuf_alloc(SAE_COMMIT_MAX_LEN
+
438 (rx_id
? 3 + os_strlen(rx_id
) : 0));
441 sae_write_commit(sta
->sae
, buf
, sta
->sae
->tmp
?
442 sta
->sae
->tmp
->anti_clogging_token
: NULL
, rx_id
);
448 static struct wpabuf
* auth_build_sae_confirm(struct hostapd_data
*hapd
,
449 struct sta_info
*sta
)
453 buf
= wpabuf_alloc(SAE_CONFIRM_MAX_LEN
);
457 sae_write_confirm(sta
->sae
, buf
);
463 static int auth_sae_send_commit(struct hostapd_data
*hapd
,
464 struct sta_info
*sta
,
465 const u8
*bssid
, int update
)
470 data
= auth_build_sae_commit(hapd
, sta
, update
);
471 if (!data
&& sta
->sae
->tmp
&& sta
->sae
->tmp
->pw_id
)
472 return WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
;
474 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
476 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 1,
477 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
478 wpabuf_len(data
), "sae-send-commit");
486 static int auth_sae_send_confirm(struct hostapd_data
*hapd
,
487 struct sta_info
*sta
,
493 data
= auth_build_sae_confirm(hapd
, sta
);
495 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
497 reply_res
= send_auth_reply(hapd
, sta
->addr
, bssid
, WLAN_AUTH_SAE
, 2,
498 WLAN_STATUS_SUCCESS
, wpabuf_head(data
),
499 wpabuf_len(data
), "sae-send-confirm");
507 static int use_sae_anti_clogging(struct hostapd_data
*hapd
)
509 struct sta_info
*sta
;
510 unsigned int open
= 0;
512 if (hapd
->conf
->sae_anti_clogging_threshold
== 0)
515 for (sta
= hapd
->sta_list
; sta
; sta
= sta
->next
) {
518 if (sta
->sae
->state
!= SAE_COMMITTED
&&
519 sta
->sae
->state
!= SAE_CONFIRMED
)
522 if (open
>= hapd
->conf
->sae_anti_clogging_threshold
)
526 /* In addition to already existing open SAE sessions, check whether
527 * there are enough pending commit messages in the processing queue to
528 * potentially result in too many open sessions. */
529 if (open
+ dl_list_len(&hapd
->sae_commit_queue
) >=
530 hapd
->conf
->sae_anti_clogging_threshold
)
537 static u8
sae_token_hash(struct hostapd_data
*hapd
, const u8
*addr
)
539 u8 hash
[SHA256_MAC_LEN
];
541 hmac_sha256(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
542 addr
, ETH_ALEN
, hash
);
547 static int check_sae_token(struct hostapd_data
*hapd
, const u8
*addr
,
548 const u8
*token
, size_t token_len
)
550 u8 mac
[SHA256_MAC_LEN
];
556 if (token_len
!= SHA256_MAC_LEN
)
558 idx
= sae_token_hash(hapd
, addr
);
559 token_idx
= hapd
->sae_pending_token_idx
[idx
];
560 if (token_idx
== 0 || token_idx
!= WPA_GET_BE16(token
)) {
561 wpa_printf(MSG_DEBUG
, "SAE: Invalid anti-clogging token from "
562 MACSTR
" - token_idx 0x%04x, expected 0x%04x",
563 MAC2STR(addr
), WPA_GET_BE16(token
), token_idx
);
571 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
572 2, addrs
, len
, mac
) < 0 ||
573 os_memcmp_const(token
+ 2, &mac
[2], SHA256_MAC_LEN
- 2) != 0)
576 hapd
->sae_pending_token_idx
[idx
] = 0; /* invalidate used token */
582 static struct wpabuf
* auth_build_token_req(struct hostapd_data
*hapd
,
583 int group
, const u8
*addr
)
587 struct os_reltime now
;
594 os_get_reltime(&now
);
595 if (!os_reltime_initialized(&hapd
->last_sae_token_key_update
) ||
596 os_reltime_expired(&now
, &hapd
->last_sae_token_key_update
, 60) ||
597 hapd
->sae_token_idx
== 0xffff) {
598 if (random_get_bytes(hapd
->sae_token_key
,
599 sizeof(hapd
->sae_token_key
)) < 0)
601 wpa_hexdump(MSG_DEBUG
, "SAE: Updated token key",
602 hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
));
603 hapd
->last_sae_token_key_update
= now
;
604 hapd
->sae_token_idx
= 0;
605 os_memset(hapd
->sae_pending_token_idx
, 0,
606 sizeof(hapd
->sae_pending_token_idx
));
609 buf
= wpabuf_alloc(sizeof(le16
) + SHA256_MAC_LEN
);
613 wpabuf_put_le16(buf
, group
); /* Finite Cyclic Group */
615 p_idx
= sae_token_hash(hapd
, addr
);
616 token_idx
= hapd
->sae_pending_token_idx
[p_idx
];
618 hapd
->sae_token_idx
++;
619 token_idx
= hapd
->sae_token_idx
;
620 hapd
->sae_pending_token_idx
[p_idx
] = token_idx
;
622 WPA_PUT_BE16(idx
, token_idx
);
623 token
= wpabuf_put(buf
, SHA256_MAC_LEN
);
627 len
[1] = sizeof(idx
);
628 if (hmac_sha256_vector(hapd
->sae_token_key
, sizeof(hapd
->sae_token_key
),
629 2, addrs
, len
, token
) < 0) {
633 WPA_PUT_BE16(token
, token_idx
);
639 static int sae_check_big_sync(struct hostapd_data
*hapd
, struct sta_info
*sta
)
641 if (sta
->sae
->sync
> hapd
->conf
->sae_sync
) {
642 sae_set_state(sta
, SAE_NOTHING
, "Sync > dot11RSNASAESync");
650 static void auth_sae_retransmit_timer(void *eloop_ctx
, void *eloop_data
)
652 struct hostapd_data
*hapd
= eloop_ctx
;
653 struct sta_info
*sta
= eloop_data
;
656 if (sae_check_big_sync(hapd
, sta
))
659 wpa_printf(MSG_DEBUG
, "SAE: Auth SAE retransmit timer for " MACSTR
660 " (sync=%d state=%s)",
661 MAC2STR(sta
->addr
), sta
->sae
->sync
,
662 sae_state_txt(sta
->sae
->state
));
664 switch (sta
->sae
->state
) {
666 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
667 eloop_register_timeout(0,
668 hapd
->dot11RSNASAERetransPeriod
* 1000,
669 auth_sae_retransmit_timer
, hapd
, sta
);
672 ret
= auth_sae_send_confirm(hapd
, sta
, hapd
->own_addr
);
673 eloop_register_timeout(0,
674 hapd
->dot11RSNASAERetransPeriod
* 1000,
675 auth_sae_retransmit_timer
, hapd
, sta
);
682 if (ret
!= WLAN_STATUS_SUCCESS
)
683 wpa_printf(MSG_INFO
, "SAE: Failed to retransmit: ret=%d", ret
);
687 void sae_clear_retransmit_timer(struct hostapd_data
*hapd
, struct sta_info
*sta
)
689 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
693 static void sae_set_retransmit_timer(struct hostapd_data
*hapd
,
694 struct sta_info
*sta
)
696 if (!(hapd
->conf
->mesh
& MESH_ENABLED
))
699 eloop_cancel_timeout(auth_sae_retransmit_timer
, hapd
, sta
);
700 eloop_register_timeout(0, hapd
->dot11RSNASAERetransPeriod
* 1000,
701 auth_sae_retransmit_timer
, hapd
, sta
);
705 static void sae_sme_send_external_auth_status(struct hostapd_data
*hapd
,
706 struct sta_info
*sta
, u16 status
)
708 struct external_auth params
;
710 os_memset(¶ms
, 0, sizeof(params
));
711 params
.status
= status
;
712 params
.bssid
= sta
->addr
;
713 if (status
== WLAN_STATUS_SUCCESS
&& sta
->sae
&&
714 !hapd
->conf
->disable_pmksa_caching
)
715 params
.pmkid
= sta
->sae
->pmkid
;
717 hostapd_drv_send_external_auth_status(hapd
, ¶ms
);
721 void sae_accept_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
)
723 #ifndef CONFIG_NO_VLAN
724 struct vlan_description vlan_desc
;
726 if (sta
->sae
->tmp
&& sta
->sae
->tmp
->vlan_id
> 0) {
727 wpa_printf(MSG_DEBUG
, "SAE: Assign STA " MACSTR
729 MAC2STR(sta
->addr
), sta
->sae
->tmp
->vlan_id
);
731 os_memset(&vlan_desc
, 0, sizeof(vlan_desc
));
732 vlan_desc
.notempty
= 1;
733 vlan_desc
.untagged
= sta
->sae
->tmp
->vlan_id
;
734 if (!hostapd_vlan_valid(hapd
->conf
->vlan
, &vlan_desc
)) {
736 "Invalid VLAN ID %d in sae_password",
737 sta
->sae
->tmp
->vlan_id
);
741 if (ap_sta_set_vlan(hapd
, sta
, &vlan_desc
) < 0 ||
742 ap_sta_bind_vlan(hapd
, sta
) < 0) {
744 "Failed to assign VLAN ID %d from sae_password to "
745 MACSTR
, sta
->sae
->tmp
->vlan_id
,
750 #endif /* CONFIG_NO_VLAN */
752 sta
->flags
|= WLAN_STA_AUTH
;
753 sta
->auth_alg
= WLAN_AUTH_SAE
;
754 mlme_authenticate_indication(hapd
, sta
);
755 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
756 sae_set_state(sta
, SAE_ACCEPTED
, "Accept Confirm");
757 wpa_auth_pmksa_add_sae(hapd
->wpa_auth
, sta
->addr
,
758 sta
->sae
->pmk
, sta
->sae
->pmkid
);
759 sae_sme_send_external_auth_status(hapd
, sta
, WLAN_STATUS_SUCCESS
);
763 static int sae_sm_step(struct hostapd_data
*hapd
, struct sta_info
*sta
,
764 const u8
*bssid
, u8 auth_transaction
, int allow_reuse
,
771 if (auth_transaction
!= 1 && auth_transaction
!= 2)
772 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
774 wpa_printf(MSG_DEBUG
, "SAE: Peer " MACSTR
" state=%s auth_trans=%u",
775 MAC2STR(sta
->addr
), sae_state_txt(sta
->sae
->state
),
777 switch (sta
->sae
->state
) {
779 if (auth_transaction
== 1) {
780 ret
= auth_sae_send_commit(hapd
, sta
, bssid
,
784 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
786 if (sae_process_commit(sta
->sae
) < 0)
787 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
790 * In mesh case, both Commit and Confirm can be sent
791 * immediately. In infrastructure BSS, only a single
792 * Authentication frame (Commit) is expected from the AP
793 * here and the second one (Confirm) will be sent once
794 * the STA has sent its second Authentication frame
797 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
799 * Send both Commit and Confirm immediately
800 * based on SAE finite state machine
801 * Nothing -> Confirm transition.
803 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
806 sae_set_state(sta
, SAE_CONFIRMED
,
807 "Sent Confirm (mesh)");
810 * For infrastructure BSS, send only the Commit
811 * message now to get alternating sequence of
812 * Authentication frames between the AP and STA.
813 * Confirm will be sent in
814 * Committed -> Confirmed/Accepted transition
815 * when receiving Confirm from STA.
819 sae_set_retransmit_timer(hapd
, sta
);
821 hostapd_logger(hapd
, sta
->addr
,
822 HOSTAPD_MODULE_IEEE80211
,
824 "SAE confirm before commit");
828 sae_clear_retransmit_timer(hapd
, sta
);
829 if (auth_transaction
== 1) {
830 if (sae_process_commit(sta
->sae
) < 0)
831 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
833 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
836 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
838 sae_set_retransmit_timer(hapd
, sta
);
839 } else if (hapd
->conf
->mesh
& MESH_ENABLED
) {
841 * In mesh case, follow SAE finite state machine and
842 * send Commit now, if sync count allows.
844 if (sae_check_big_sync(hapd
, sta
))
845 return WLAN_STATUS_SUCCESS
;
848 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 0);
852 sae_set_retransmit_timer(hapd
, sta
);
855 * For instructure BSS, send the postponed Confirm from
856 * Nothing -> Confirmed transition that was reduced to
857 * Nothing -> Committed above.
859 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
863 sae_set_state(sta
, SAE_CONFIRMED
, "Sent Confirm");
866 * Since this was triggered on Confirm RX, run another
867 * step to get to Accepted without waiting for
870 return sae_sm_step(hapd
, sta
, bssid
, auth_transaction
,
875 sae_clear_retransmit_timer(hapd
, sta
);
876 if (auth_transaction
== 1) {
877 if (sae_check_big_sync(hapd
, sta
))
878 return WLAN_STATUS_SUCCESS
;
881 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
885 if (sae_process_commit(sta
->sae
) < 0)
886 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
888 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
892 sae_set_retransmit_timer(hapd
, sta
);
894 sta
->sae
->send_confirm
= 0xffff;
895 sae_accept_sta(hapd
, sta
);
899 if (auth_transaction
== 1 &&
900 (hapd
->conf
->mesh
& MESH_ENABLED
)) {
901 wpa_printf(MSG_DEBUG
, "SAE: remove the STA (" MACSTR
902 ") doing reauthentication",
904 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
905 ap_free_sta(hapd
, sta
);
907 } else if (auth_transaction
== 1) {
908 wpa_printf(MSG_DEBUG
, "SAE: Start reauthentication");
909 ret
= auth_sae_send_commit(hapd
, sta
, bssid
, 1);
912 sae_set_state(sta
, SAE_COMMITTED
, "Sent Commit");
914 if (sae_process_commit(sta
->sae
) < 0)
915 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
917 sae_set_retransmit_timer(hapd
, sta
);
919 if (sae_check_big_sync(hapd
, sta
))
920 return WLAN_STATUS_SUCCESS
;
923 ret
= auth_sae_send_confirm(hapd
, sta
, bssid
);
924 sae_clear_temp_data(sta
->sae
);
930 wpa_printf(MSG_ERROR
, "SAE: invalid state %d",
932 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
934 return WLAN_STATUS_SUCCESS
;
938 static void sae_pick_next_group(struct hostapd_data
*hapd
, struct sta_info
*sta
)
940 struct sae_data
*sae
= sta
->sae
;
941 int i
, *groups
= hapd
->conf
->sae_groups
;
942 int default_groups
[] = { 19, 0 };
944 if (sae
->state
!= SAE_COMMITTED
)
947 wpa_printf(MSG_DEBUG
, "SAE: Previously selected group: %d", sae
->group
);
950 groups
= default_groups
;
951 for (i
= 0; groups
[i
] > 0; i
++) {
952 if (sae
->group
== groups
[i
])
956 if (groups
[i
] <= 0) {
957 wpa_printf(MSG_DEBUG
,
958 "SAE: Previously selected group not found from the current configuration");
964 if (groups
[i
] <= 0) {
965 wpa_printf(MSG_DEBUG
,
966 "SAE: No alternative group enabled");
970 if (sae_set_group(sae
, groups
[i
]) < 0)
975 wpa_printf(MSG_DEBUG
, "SAE: Selected new group: %d", groups
[i
]);
979 static void handle_auth_sae(struct hostapd_data
*hapd
, struct sta_info
*sta
,
980 const struct ieee80211_mgmt
*mgmt
, size_t len
,
981 u16 auth_transaction
, u16 status_code
)
983 int resp
= WLAN_STATUS_SUCCESS
;
984 struct wpabuf
*data
= NULL
;
985 int *groups
= hapd
->conf
->sae_groups
;
986 int default_groups
[] = { 19, 0 };
991 groups
= default_groups
;
993 #ifdef CONFIG_TESTING_OPTIONS
994 if (hapd
->conf
->sae_reflection_attack
&& auth_transaction
== 1) {
995 wpa_printf(MSG_DEBUG
, "SAE: TESTING - reflection attack");
996 pos
= mgmt
->u
.auth
.variable
;
997 end
= ((const u8
*) mgmt
) + len
;
998 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
999 auth_transaction
, resp
, pos
, end
- pos
,
1000 "auth-sae-reflection-attack");
1004 if (hapd
->conf
->sae_commit_override
&& auth_transaction
== 1) {
1005 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
1006 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1007 auth_transaction
, resp
,
1008 wpabuf_head(hapd
->conf
->sae_commit_override
),
1009 wpabuf_len(hapd
->conf
->sae_commit_override
),
1010 "sae-commit-override");
1013 #endif /* CONFIG_TESTING_OPTIONS */
1015 if (auth_transaction
!= 1 ||
1016 status_code
!= WLAN_STATUS_SUCCESS
) {
1020 sta
->sae
= os_zalloc(sizeof(*sta
->sae
));
1025 sae_set_state(sta
, SAE_NOTHING
, "Init");
1029 if (sta
->mesh_sae_pmksa_caching
) {
1030 wpa_printf(MSG_DEBUG
,
1031 "SAE: Cancel use of mesh PMKSA caching because peer starts SAE authentication");
1032 wpa_auth_pmksa_remove(hapd
->wpa_auth
, sta
->addr
);
1033 sta
->mesh_sae_pmksa_caching
= 0;
1036 if (auth_transaction
== 1) {
1037 const u8
*token
= NULL
;
1038 size_t token_len
= 0;
1039 int allow_reuse
= 0;
1041 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1042 HOSTAPD_LEVEL_DEBUG
,
1043 "start SAE authentication (RX commit, status=%u (%s))",
1044 status_code
, status2str(status_code
));
1046 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1047 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
1049 pos
= mgmt
->u
.auth
.variable
;
1050 end
= ((const u8
*) mgmt
) + len
;
1051 if (pos
+ sizeof(le16
) > end
) {
1052 wpa_printf(MSG_ERROR
,
1053 "SAE: Too short anti-clogging token request");
1054 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1057 resp
= sae_group_allowed(sta
->sae
, groups
,
1059 if (resp
!= WLAN_STATUS_SUCCESS
) {
1060 wpa_printf(MSG_ERROR
,
1061 "SAE: Invalid group in anti-clogging token request");
1064 pos
+= sizeof(le16
);
1066 wpabuf_free(sta
->sae
->tmp
->anti_clogging_token
);
1067 sta
->sae
->tmp
->anti_clogging_token
=
1068 wpabuf_alloc_copy(pos
, end
- pos
);
1069 if (sta
->sae
->tmp
->anti_clogging_token
== NULL
) {
1070 wpa_printf(MSG_ERROR
,
1071 "SAE: Failed to alloc for anti-clogging token");
1072 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1077 * IEEE Std 802.11-2012, 11.3.8.6.4: If the Status code
1078 * is 76, a new Commit Message shall be constructed
1079 * with the Anti-Clogging Token from the received
1080 * Authentication frame, and the commit-scalar and
1081 * COMMIT-ELEMENT previously sent.
1083 resp
= auth_sae_send_commit(hapd
, sta
, mgmt
->bssid
, 0);
1084 if (resp
!= WLAN_STATUS_SUCCESS
) {
1085 wpa_printf(MSG_ERROR
,
1086 "SAE: Failed to send commit message");
1089 sae_set_state(sta
, SAE_COMMITTED
,
1090 "Sent Commit (anti-clogging token case in mesh)");
1092 sae_set_retransmit_timer(hapd
, sta
);
1096 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
1098 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1100 wpa_printf(MSG_DEBUG
,
1101 "SAE: Peer did not accept our SAE group");
1102 sae_pick_next_group(hapd
, sta
);
1106 if (status_code
!= WLAN_STATUS_SUCCESS
)
1109 if (!(hapd
->conf
->mesh
& MESH_ENABLED
) &&
1110 sta
->sae
->state
== SAE_COMMITTED
) {
1111 /* This is needed in the infrastructure BSS case to
1112 * address a sequence where a STA entry may remain in
1113 * hostapd across two attempts to do SAE authentication
1114 * by the same STA. The second attempt may end up trying
1115 * to use a different group and that would not be
1116 * allowed if we remain in Committed state with the
1117 * previously set parameters. */
1118 pos
= mgmt
->u
.auth
.variable
;
1119 end
= ((const u8
*) mgmt
) + len
;
1120 if (end
- pos
>= (int) sizeof(le16
) &&
1121 sae_group_allowed(sta
->sae
, groups
,
1122 WPA_GET_LE16(pos
)) ==
1123 WLAN_STATUS_SUCCESS
) {
1124 /* Do not waste resources deriving the same PWE
1125 * again since the same group is reused. */
1126 sae_set_state(sta
, SAE_NOTHING
,
1127 "Allow previous PWE to be reused");
1130 sae_set_state(sta
, SAE_NOTHING
,
1131 "Clear existing state to allow restart");
1132 sae_clear_data(sta
->sae
);
1136 resp
= sae_parse_commit(sta
->sae
, mgmt
->u
.auth
.variable
,
1137 ((const u8
*) mgmt
) + len
-
1138 mgmt
->u
.auth
.variable
, &token
,
1139 &token_len
, groups
);
1140 if (resp
== SAE_SILENTLY_DISCARD
) {
1141 wpa_printf(MSG_DEBUG
,
1142 "SAE: Drop commit message from " MACSTR
" due to reflection attack",
1143 MAC2STR(sta
->addr
));
1147 if (resp
== WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER
) {
1148 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
1149 WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER
1150 MACSTR
, MAC2STR(sta
->addr
));
1151 sae_clear_retransmit_timer(hapd
, sta
);
1152 sae_set_state(sta
, SAE_NOTHING
,
1153 "Unknown Password Identifier");
1157 if (token
&& check_sae_token(hapd
, sta
->addr
, token
, token_len
)
1159 wpa_printf(MSG_DEBUG
, "SAE: Drop commit message with "
1160 "incorrect token from " MACSTR
,
1161 MAC2STR(sta
->addr
));
1162 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1166 if (resp
!= WLAN_STATUS_SUCCESS
)
1169 if (!token
&& use_sae_anti_clogging(hapd
) && !allow_reuse
) {
1170 wpa_printf(MSG_DEBUG
,
1171 "SAE: Request anti-clogging token from "
1172 MACSTR
, MAC2STR(sta
->addr
));
1173 data
= auth_build_token_req(hapd
, sta
->sae
->group
,
1175 resp
= WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
;
1176 if (hapd
->conf
->mesh
& MESH_ENABLED
)
1177 sae_set_state(sta
, SAE_NOTHING
,
1178 "Request anti-clogging token case in mesh");
1182 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
,
1183 allow_reuse
, &sta_removed
);
1184 } else if (auth_transaction
== 2) {
1185 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1186 HOSTAPD_LEVEL_DEBUG
,
1187 "SAE authentication (RX confirm, status=%u (%s))",
1188 status_code
, status2str(status_code
));
1189 if (status_code
!= WLAN_STATUS_SUCCESS
)
1191 if (sta
->sae
->state
>= SAE_CONFIRMED
||
1192 !(hapd
->conf
->mesh
& MESH_ENABLED
)) {
1195 u16 peer_send_confirm
;
1197 var
= mgmt
->u
.auth
.variable
;
1198 var_len
= ((u8
*) mgmt
) + len
- mgmt
->u
.auth
.variable
;
1200 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1204 peer_send_confirm
= WPA_GET_LE16(var
);
1206 if (sta
->sae
->state
== SAE_ACCEPTED
&&
1207 (peer_send_confirm
<= sta
->sae
->rc
||
1208 peer_send_confirm
== 0xffff)) {
1209 wpa_printf(MSG_DEBUG
,
1210 "SAE: Silently ignore unexpected Confirm from peer "
1212 " (peer-send-confirm=%u Rc=%u)",
1214 peer_send_confirm
, sta
->sae
->rc
);
1218 if (sae_check_confirm(sta
->sae
, var
, var_len
) < 0) {
1219 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1222 sta
->sae
->rc
= peer_send_confirm
;
1224 resp
= sae_sm_step(hapd
, sta
, mgmt
->bssid
, auth_transaction
, 0,
1227 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1228 HOSTAPD_LEVEL_DEBUG
,
1229 "unexpected SAE authentication transaction %u (status=%u (%s))",
1230 auth_transaction
, status_code
,
1231 status2str(status_code
));
1232 if (status_code
!= WLAN_STATUS_SUCCESS
)
1234 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
1238 if (!sta_removed
&& resp
!= WLAN_STATUS_SUCCESS
) {
1239 pos
= mgmt
->u
.auth
.variable
;
1240 end
= ((const u8
*) mgmt
) + len
;
1242 /* Copy the Finite Cyclic Group field from the request if we
1243 * rejected it as unsupported group. */
1244 if (resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
1245 !data
&& end
- pos
>= 2)
1246 data
= wpabuf_alloc_copy(pos
, 2);
1248 sae_sme_send_external_auth_status(hapd
, sta
, resp
);
1249 send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, WLAN_AUTH_SAE
,
1250 auth_transaction
, resp
,
1251 data
? wpabuf_head(data
) : (u8
*) "",
1252 data
? wpabuf_len(data
) : 0, "auth-sae");
1256 if (!sta_removed
&& sta
->added_unassoc
&&
1257 (resp
!= WLAN_STATUS_SUCCESS
||
1258 status_code
!= WLAN_STATUS_SUCCESS
)) {
1259 hostapd_drv_sta_remove(hapd
, sta
->addr
);
1260 sta
->added_unassoc
= 0;
1267 * auth_sae_init_committed - Send COMMIT and start SAE in committed state
1268 * @hapd: BSS data for the device initiating the authentication
1269 * @sta: the peer to which commit authentication frame is sent
1271 * This function implements Init event handling (IEEE Std 802.11-2012,
1272 * 11.3.8.6.3) in which initial COMMIT message is sent. Prior to calling, the
1273 * sta->sae structure should be initialized appropriately via a call to
1274 * sae_prepare_commit().
1276 int auth_sae_init_committed(struct hostapd_data
*hapd
, struct sta_info
*sta
)
1280 if (!sta
->sae
|| !sta
->sae
->tmp
)
1283 if (sta
->sae
->state
!= SAE_NOTHING
)
1286 ret
= auth_sae_send_commit(hapd
, sta
, hapd
->own_addr
, 0);
1290 sae_set_state(sta
, SAE_COMMITTED
, "Init and sent commit");
1292 sae_set_retransmit_timer(hapd
, sta
);
1298 void auth_sae_process_commit(void *eloop_ctx
, void *user_ctx
)
1300 struct hostapd_data
*hapd
= eloop_ctx
;
1301 struct hostapd_sae_commit_queue
*q
;
1302 unsigned int queue_len
;
1304 q
= dl_list_first(&hapd
->sae_commit_queue
,
1305 struct hostapd_sae_commit_queue
, list
);
1308 wpa_printf(MSG_DEBUG
,
1309 "SAE: Process next available message from queue");
1310 dl_list_del(&q
->list
);
1311 handle_auth(hapd
, (const struct ieee80211_mgmt
*) q
->msg
, q
->len
,
1315 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1317 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1318 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1323 static void auth_sae_queue(struct hostapd_data
*hapd
,
1324 const struct ieee80211_mgmt
*mgmt
, size_t len
,
1327 struct hostapd_sae_commit_queue
*q
, *q2
;
1328 unsigned int queue_len
;
1329 const struct ieee80211_mgmt
*mgmt2
;
1331 queue_len
= dl_list_len(&hapd
->sae_commit_queue
);
1332 if (queue_len
>= 15) {
1333 wpa_printf(MSG_DEBUG
,
1334 "SAE: No more room in message queue - drop the new frame from "
1335 MACSTR
, MAC2STR(mgmt
->sa
));
1339 wpa_printf(MSG_DEBUG
, "SAE: Queue Authentication message from "
1340 MACSTR
" for processing (queue_len %u)", MAC2STR(mgmt
->sa
),
1342 q
= os_zalloc(sizeof(*q
) + len
);
1347 os_memcpy(q
->msg
, mgmt
, len
);
1349 /* Check whether there is already a queued Authentication frame from the
1350 * same station with the same transaction number and if so, replace that
1351 * queue entry with the new one. This avoids issues with a peer that
1352 * sends multiple times (e.g., due to frequent SAE retries). There is no
1353 * point in us trying to process the old attempts after a new one has
1354 * obsoleted them. */
1355 dl_list_for_each(q2
, &hapd
->sae_commit_queue
,
1356 struct hostapd_sae_commit_queue
, list
) {
1357 mgmt2
= (const struct ieee80211_mgmt
*) q2
->msg
;
1358 if (os_memcmp(mgmt
->sa
, mgmt2
->sa
, ETH_ALEN
) == 0 &&
1359 mgmt
->u
.auth
.auth_transaction
==
1360 mgmt2
->u
.auth
.auth_transaction
) {
1361 wpa_printf(MSG_DEBUG
,
1362 "SAE: Replace queued message from same STA with same transaction number");
1363 dl_list_add(&q2
->list
, &q
->list
);
1364 dl_list_del(&q2
->list
);
1370 /* No pending identical entry, so add to the end of the queue */
1371 dl_list_add_tail(&hapd
->sae_commit_queue
, &q
->list
);
1374 if (eloop_is_timeout_registered(auth_sae_process_commit
, hapd
, NULL
))
1376 eloop_register_timeout(0, queue_len
* 10000, auth_sae_process_commit
,
1381 static int auth_sae_queued_addr(struct hostapd_data
*hapd
, const u8
*addr
)
1383 struct hostapd_sae_commit_queue
*q
;
1384 const struct ieee80211_mgmt
*mgmt
;
1386 dl_list_for_each(q
, &hapd
->sae_commit_queue
,
1387 struct hostapd_sae_commit_queue
, list
) {
1388 mgmt
= (const struct ieee80211_mgmt
*) q
->msg
;
1389 if (os_memcmp(addr
, mgmt
->sa
, ETH_ALEN
) == 0)
1396 #endif /* CONFIG_SAE */
1399 static u16
wpa_res_to_status_code(int res
)
1401 if (res
== WPA_INVALID_GROUP
)
1402 return WLAN_STATUS_GROUP_CIPHER_NOT_VALID
;
1403 if (res
== WPA_INVALID_PAIRWISE
)
1404 return WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID
;
1405 if (res
== WPA_INVALID_AKMP
)
1406 return WLAN_STATUS_AKMP_NOT_VALID
;
1407 if (res
== WPA_ALLOC_FAIL
)
1408 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
1409 #ifdef CONFIG_IEEE80211W
1410 if (res
== WPA_MGMT_FRAME_PROTECTION_VIOLATION
)
1411 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
1412 if (res
== WPA_INVALID_MGMT_GROUP_CIPHER
)
1413 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
1414 #endif /* CONFIG_IEEE80211W */
1415 if (res
== WPA_INVALID_MDIE
)
1416 return WLAN_STATUS_INVALID_MDIE
;
1417 if (res
== WPA_INVALID_PMKID
)
1418 return WLAN_STATUS_INVALID_PMKID
;
1419 if (res
!= WPA_IE_OK
)
1420 return WLAN_STATUS_INVALID_IE
;
1421 return WLAN_STATUS_SUCCESS
;
1427 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1428 struct sta_info
*sta
, u16 resp
,
1429 struct wpabuf
*data
, int pub
);
1431 void handle_auth_fils(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1432 const u8
*pos
, size_t len
, u16 auth_alg
,
1433 u16 auth_transaction
, u16 status_code
,
1434 void (*cb
)(struct hostapd_data
*hapd
,
1435 struct sta_info
*sta
, u16 resp
,
1436 struct wpabuf
*data
, int pub
))
1438 u16 resp
= WLAN_STATUS_SUCCESS
;
1440 struct ieee802_11_elems elems
;
1442 struct wpa_ie_data rsn
;
1443 struct rsn_pmksa_cache_entry
*pmksa
= NULL
;
1445 if (auth_transaction
!= 1 || status_code
!= WLAN_STATUS_SUCCESS
)
1450 wpa_hexdump(MSG_DEBUG
, "FILS: Authentication frame fields",
1454 #ifdef CONFIG_FILS_SK_PFS
1455 if (auth_alg
== WLAN_AUTH_FILS_SK_PFS
) {
1460 /* Using FILS PFS */
1462 /* Finite Cyclic Group */
1463 if (end
- pos
< 2) {
1464 wpa_printf(MSG_DEBUG
,
1465 "FILS: No room for Finite Cyclic Group");
1466 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1469 group
= WPA_GET_LE16(pos
);
1471 if (group
!= hapd
->conf
->fils_dh_group
) {
1472 wpa_printf(MSG_DEBUG
,
1473 "FILS: Unsupported Finite Cyclic Group: %u (expected %u)",
1474 group
, hapd
->conf
->fils_dh_group
);
1475 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1479 crypto_ecdh_deinit(sta
->fils_ecdh
);
1480 sta
->fils_ecdh
= crypto_ecdh_init(group
);
1481 if (!sta
->fils_ecdh
) {
1482 wpa_printf(MSG_INFO
,
1483 "FILS: Could not initialize ECDH with group %d",
1485 resp
= WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
1489 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1491 wpa_printf(MSG_DEBUG
,
1492 "FILS: Failed to derive ECDH public key");
1493 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1496 elem_len
= wpabuf_len(pub
);
1500 if ((size_t) (end
- pos
) < elem_len
) {
1501 wpa_printf(MSG_DEBUG
, "FILS: No room for Element");
1502 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1506 wpabuf_free(sta
->fils_g_sta
);
1507 sta
->fils_g_sta
= wpabuf_alloc_copy(pos
, elem_len
);
1508 wpabuf_clear_free(sta
->fils_dh_ss
);
1509 sta
->fils_dh_ss
= crypto_ecdh_set_peerkey(sta
->fils_ecdh
, 1,
1511 if (!sta
->fils_dh_ss
) {
1512 wpa_printf(MSG_DEBUG
, "FILS: ECDH operation failed");
1513 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1516 wpa_hexdump_buf_key(MSG_DEBUG
, "FILS: DH_SS", sta
->fils_dh_ss
);
1519 crypto_ecdh_deinit(sta
->fils_ecdh
);
1520 sta
->fils_ecdh
= NULL
;
1521 wpabuf_clear_free(sta
->fils_dh_ss
);
1522 sta
->fils_dh_ss
= NULL
;
1524 #endif /* CONFIG_FILS_SK_PFS */
1526 wpa_hexdump(MSG_DEBUG
, "FILS: Remaining IEs", pos
, end
- pos
);
1527 if (ieee802_11_parse_elems(pos
, end
- pos
, &elems
, 1) == ParseFailed
) {
1528 wpa_printf(MSG_DEBUG
, "FILS: Could not parse elements");
1529 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1534 wpa_hexdump(MSG_DEBUG
, "FILS: RSN element",
1535 elems
.rsn_ie
, elems
.rsn_ie_len
);
1536 if (!elems
.rsn_ie
||
1537 wpa_parse_wpa_ie_rsn(elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1539 wpa_printf(MSG_DEBUG
, "FILS: No valid RSN element");
1540 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1545 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
1548 wpa_printf(MSG_DEBUG
,
1549 "FILS: Failed to initialize RSN state machine");
1550 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1554 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
1556 elems
.rsn_ie
- 2, elems
.rsn_ie_len
+ 2,
1557 elems
.mdie
, elems
.mdie_len
, NULL
, 0);
1558 resp
= wpa_res_to_status_code(res
);
1559 if (resp
!= WLAN_STATUS_SUCCESS
)
1562 if (!elems
.fils_nonce
) {
1563 wpa_printf(MSG_DEBUG
, "FILS: No FILS Nonce field");
1564 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1567 wpa_hexdump(MSG_DEBUG
, "FILS: SNonce", elems
.fils_nonce
,
1569 os_memcpy(sta
->fils_snonce
, elems
.fils_nonce
, FILS_NONCE_LEN
);
1572 if (rsn
.pmkid
&& rsn
.num_pmkid
> 0) {
1576 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID List",
1577 rsn
.pmkid
, rsn
.num_pmkid
* PMKID_LEN
);
1580 num
= rsn
.num_pmkid
;
1582 wpa_hexdump(MSG_DEBUG
, "FILS: PMKID", pmkid
, PMKID_LEN
);
1583 pmksa
= wpa_auth_pmksa_get(hapd
->wpa_auth
, sta
->addr
,
1587 pmksa
= wpa_auth_pmksa_get_fils_cache_id(hapd
->wpa_auth
,
1596 if (pmksa
&& wpa_auth_sta_key_mgmt(sta
->wpa_sm
) != pmksa
->akmp
) {
1597 wpa_printf(MSG_DEBUG
,
1598 "FILS: Matching PMKSA cache entry has different AKMP (0x%x != 0x%x) - ignore",
1599 wpa_auth_sta_key_mgmt(sta
->wpa_sm
), pmksa
->akmp
);
1603 wpa_printf(MSG_DEBUG
, "FILS: Found matching PMKSA cache entry");
1606 if (!elems
.fils_session
) {
1607 wpa_printf(MSG_DEBUG
, "FILS: No FILS Session element");
1608 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1611 wpa_hexdump(MSG_DEBUG
, "FILS: FILS Session", elems
.fils_session
,
1613 os_memcpy(sta
->fils_session
, elems
.fils_session
, FILS_SESSION_LEN
);
1615 /* FILS Wrapped Data */
1616 if (elems
.fils_wrapped_data
) {
1617 wpa_hexdump(MSG_DEBUG
, "FILS: Wrapped Data",
1618 elems
.fils_wrapped_data
,
1619 elems
.fils_wrapped_data_len
);
1621 #ifndef CONFIG_NO_RADIUS
1622 if (!sta
->eapol_sm
) {
1624 ieee802_1x_alloc_eapol_sm(hapd
, sta
);
1626 wpa_printf(MSG_DEBUG
,
1627 "FILS: Forward EAP-Initiate/Re-auth to authentication server");
1628 ieee802_1x_encapsulate_radius(
1629 hapd
, sta
, elems
.fils_wrapped_data
,
1630 elems
.fils_wrapped_data_len
);
1631 sta
->fils_pending_cb
= cb
;
1632 wpa_printf(MSG_DEBUG
,
1633 "FILS: Will send Authentication frame once the response from authentication server is available");
1634 sta
->flags
|= WLAN_STA_PENDING_FILS_ERP
;
1635 /* Calculate pending PMKID here so that we do not need
1636 * to maintain a copy of the EAP-Initiate/Reauth
1638 if (fils_pmkid_erp(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1639 elems
.fils_wrapped_data
,
1640 elems
.fils_wrapped_data_len
,
1641 sta
->fils_erp_pmkid
) == 0)
1642 sta
->fils_erp_pmkid_set
= 1;
1644 #else /* CONFIG_NO_RADIUS */
1645 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1647 #endif /* CONFIG_NO_RADIUS */
1653 struct wpabuf
*data
;
1656 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, pmksa
, NULL
,
1659 wpa_printf(MSG_DEBUG
,
1660 "%s: prepare_auth_resp_fils() returned failure",
1664 cb(hapd
, sta
, resp
, data
, pub
);
1669 static struct wpabuf
*
1670 prepare_auth_resp_fils(struct hostapd_data
*hapd
,
1671 struct sta_info
*sta
, u16
*resp
,
1672 struct rsn_pmksa_cache_entry
*pmksa
,
1673 struct wpabuf
*erp_resp
,
1674 const u8
*msk
, size_t msk_len
,
1677 u8 fils_nonce
[FILS_NONCE_LEN
];
1679 struct wpabuf
*data
= NULL
;
1682 const u8
*pmk
= NULL
;
1684 u8 pmk_buf
[PMK_LEN_MAX
];
1685 struct wpabuf
*pub
= NULL
;
1687 if (*resp
!= WLAN_STATUS_SUCCESS
)
1690 ie
= wpa_auth_get_wpa_ie(hapd
->wpa_auth
, &ielen
);
1692 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1697 /* Add PMKID of the selected PMKSA into RSNE */
1698 ie_buf
= os_malloc(ielen
+ 2 + 2 + PMKID_LEN
);
1700 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1704 os_memcpy(ie_buf
, ie
, ielen
);
1705 if (wpa_insert_pmkid(ie_buf
, &ielen
, pmksa
->pmkid
) < 0) {
1706 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1712 if (random_get_bytes(fils_nonce
, FILS_NONCE_LEN
) < 0) {
1713 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1716 wpa_hexdump(MSG_DEBUG
, "RSN: Generated FILS Nonce",
1717 fils_nonce
, FILS_NONCE_LEN
);
1719 #ifdef CONFIG_FILS_SK_PFS
1720 if (sta
->fils_dh_ss
&& sta
->fils_ecdh
) {
1721 pub
= crypto_ecdh_get_pubkey(sta
->fils_ecdh
, 1);
1723 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1727 #endif /* CONFIG_FILS_SK_PFS */
1729 data
= wpabuf_alloc(1000 + ielen
+ (pub
? wpabuf_len(pub
) : 0));
1731 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1736 #ifdef CONFIG_FILS_SK_PFS
1738 /* Finite Cyclic Group */
1739 wpabuf_put_le16(data
, hapd
->conf
->fils_dh_group
);
1742 wpabuf_put_buf(data
, pub
);
1744 #endif /* CONFIG_FILS_SK_PFS */
1747 wpabuf_put_data(data
, ie
, ielen
);
1749 /* MDE when using FILS+FT (already included in ie,ielen with RSNE) */
1751 #ifdef CONFIG_IEEE80211R_AP
1752 if (wpa_key_mgmt_ft(wpa_auth_sta_key_mgmt(sta
->wpa_sm
))) {
1753 /* FTE[R1KH-ID,R0KH-ID] when using FILS+FT */
1755 int use_sha384
= wpa_key_mgmt_sha384(
1756 wpa_auth_sta_key_mgmt(sta
->wpa_sm
));
1758 res
= wpa_auth_write_fte(hapd
->wpa_auth
, use_sha384
,
1759 wpabuf_put(data
, 0),
1760 wpabuf_tailroom(data
));
1762 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1765 wpabuf_put(data
, res
);
1767 #endif /* CONFIG_IEEE80211R_AP */
1770 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1771 wpabuf_put_u8(data
, 1 + FILS_NONCE_LEN
); /* Length */
1772 /* Element ID Extension */
1773 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_NONCE
);
1774 wpabuf_put_data(data
, fils_nonce
, FILS_NONCE_LEN
);
1777 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1778 wpabuf_put_u8(data
, 1 + FILS_SESSION_LEN
); /* Length */
1779 /* Element ID Extension */
1780 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_SESSION
);
1781 wpabuf_put_data(data
, sta
->fils_session
, FILS_SESSION_LEN
);
1783 /* FILS Wrapped Data */
1784 if (!pmksa
&& erp_resp
) {
1785 wpabuf_put_u8(data
, WLAN_EID_EXTENSION
); /* Element ID */
1786 wpabuf_put_u8(data
, 1 + wpabuf_len(erp_resp
)); /* Length */
1787 /* Element ID Extension */
1788 wpabuf_put_u8(data
, WLAN_EID_EXT_FILS_WRAPPED_DATA
);
1789 wpabuf_put_buf(data
, erp_resp
);
1791 if (fils_rmsk_to_pmk(wpa_auth_sta_key_mgmt(sta
->wpa_sm
),
1792 msk
, msk_len
, sta
->fils_snonce
, fils_nonce
,
1794 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1796 wpabuf_len(sta
->fils_dh_ss
) : 0,
1797 pmk_buf
, &pmk_len
)) {
1798 wpa_printf(MSG_DEBUG
, "FILS: Failed to derive PMK");
1799 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1806 /* Don't use DHss in PTK derivation if PMKSA caching is not
1808 wpabuf_clear_free(sta
->fils_dh_ss
);
1809 sta
->fils_dh_ss
= NULL
;
1811 if (sta
->fils_erp_pmkid_set
) {
1812 /* TODO: get PMKLifetime from WPA parameters */
1813 unsigned int dot11RSNAConfigPMKLifetime
= 43200;
1814 int session_timeout
;
1816 session_timeout
= dot11RSNAConfigPMKLifetime
;
1817 if (sta
->session_timeout_set
) {
1818 struct os_reltime now
, diff
;
1820 os_get_reltime(&now
);
1821 os_reltime_sub(&sta
->session_timeout
, &now
,
1823 session_timeout
= diff
.sec
;
1826 sta
->fils_erp_pmkid_set
= 0;
1827 wpa_auth_add_fils_pmk_pmkid(sta
->wpa_sm
, pmk
, pmk_len
,
1828 sta
->fils_erp_pmkid
);
1829 if (!hapd
->conf
->disable_pmksa_caching
&&
1830 wpa_auth_pmksa_add2(
1831 hapd
->wpa_auth
, sta
->addr
,
1833 sta
->fils_erp_pmkid
,
1835 wpa_auth_sta_key_mgmt(sta
->wpa_sm
)) < 0) {
1836 wpa_printf(MSG_ERROR
,
1837 "FILS: Failed to add PMKSA cache entry based on ERP");
1842 pmk_len
= pmksa
->pmk_len
;
1846 wpa_printf(MSG_DEBUG
, "FILS: No PMK available");
1847 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1853 if (fils_auth_pmk_to_ptk(sta
->wpa_sm
, pmk
, pmk_len
,
1854 sta
->fils_snonce
, fils_nonce
,
1856 wpabuf_head(sta
->fils_dh_ss
) : NULL
,
1858 wpabuf_len(sta
->fils_dh_ss
) : 0,
1859 sta
->fils_g_sta
, pub
) < 0) {
1860 *resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
1868 *is_pub
= pub
!= NULL
;
1871 wpabuf_clear_free(sta
->fils_dh_ss
);
1872 sta
->fils_dh_ss
= NULL
;
1873 #ifdef CONFIG_FILS_SK_PFS
1874 crypto_ecdh_deinit(sta
->fils_ecdh
);
1875 sta
->fils_ecdh
= NULL
;
1876 #endif /* CONFIG_FILS_SK_PFS */
1881 static void handle_auth_fils_finish(struct hostapd_data
*hapd
,
1882 struct sta_info
*sta
, u16 resp
,
1883 struct wpabuf
*data
, int pub
)
1888 resp
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
) ?
1889 WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1890 send_auth_reply(hapd
, sta
->addr
, hapd
->own_addr
, auth_alg
, 2, resp
,
1891 data
? wpabuf_head(data
) : (u8
*) "",
1892 data
? wpabuf_len(data
) : 0, "auth-fils-finish");
1895 if (resp
== WLAN_STATUS_SUCCESS
) {
1896 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
1897 HOSTAPD_LEVEL_DEBUG
,
1898 "authentication OK (FILS)");
1899 sta
->flags
|= WLAN_STA_AUTH
;
1900 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
1901 sta
->auth_alg
= pub
? WLAN_AUTH_FILS_SK_PFS
: WLAN_AUTH_FILS_SK
;
1902 mlme_authenticate_indication(hapd
, sta
);
1907 void ieee802_11_finish_fils_auth(struct hostapd_data
*hapd
,
1908 struct sta_info
*sta
, int success
,
1909 struct wpabuf
*erp_resp
,
1910 const u8
*msk
, size_t msk_len
)
1912 struct wpabuf
*data
;
1916 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
1918 if (!sta
->fils_pending_cb
)
1920 resp
= success
? WLAN_STATUS_SUCCESS
: WLAN_STATUS_UNSPECIFIED_FAILURE
;
1921 data
= prepare_auth_resp_fils(hapd
, sta
, &resp
, NULL
, erp_resp
,
1922 msk
, msk_len
, &pub
);
1924 wpa_printf(MSG_DEBUG
,
1925 "%s: prepare_auth_resp_fils() returned failure",
1928 sta
->fils_pending_cb(hapd
, sta
, resp
, data
, pub
);
1931 #endif /* CONFIG_FILS */
1935 ieee802_11_allowed_address(struct hostapd_data
*hapd
, const u8
*addr
,
1936 const u8
*msg
, size_t len
, u32
*session_timeout
,
1937 u32
*acct_interim_interval
,
1938 struct vlan_description
*vlan_id
,
1939 struct hostapd_sta_wpa_psk_short
**psk
,
1940 char **identity
, char **radius_cui
, int is_probe_req
)
1944 os_memset(vlan_id
, 0, sizeof(*vlan_id
));
1945 res
= hostapd_allowed_address(hapd
, addr
, msg
, len
,
1946 session_timeout
, acct_interim_interval
,
1947 vlan_id
, psk
, identity
, radius_cui
,
1950 if (res
== HOSTAPD_ACL_REJECT
) {
1952 wpa_printf(MSG_DEBUG
,
1954 " not allowed to authenticate",
1956 return HOSTAPD_ACL_REJECT
;
1959 if (res
== HOSTAPD_ACL_PENDING
) {
1960 wpa_printf(MSG_DEBUG
, "Authentication frame from " MACSTR
1961 " waiting for an external authentication",
1963 /* Authentication code will re-send the authentication frame
1964 * after it has received (and cached) information from the
1965 * external source. */
1966 return HOSTAPD_ACL_PENDING
;
1974 ieee802_11_set_radius_info(struct hostapd_data
*hapd
, struct sta_info
*sta
,
1975 int res
, u32 session_timeout
,
1976 u32 acct_interim_interval
,
1977 struct vlan_description
*vlan_id
,
1978 struct hostapd_sta_wpa_psk_short
**psk
,
1979 char **identity
, char **radius_cui
)
1981 if (vlan_id
->notempty
&&
1982 !hostapd_vlan_valid(hapd
->conf
->vlan
, vlan_id
)) {
1983 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1985 "Invalid VLAN %d%s received from RADIUS server",
1987 vlan_id
->tagged
[0] ? "+" : "");
1990 if (ap_sta_set_vlan(hapd
, sta
, vlan_id
) < 0)
1993 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_RADIUS
,
1994 HOSTAPD_LEVEL_INFO
, "VLAN ID %d", sta
->vlan_id
);
1996 hostapd_free_psk_list(sta
->psk
);
1997 if (hapd
->conf
->wpa_psk_radius
!= PSK_RADIUS_IGNORED
) {
2004 os_free(sta
->identity
);
2005 sta
->identity
= *identity
;
2008 os_free(sta
->radius_cui
);
2009 sta
->radius_cui
= *radius_cui
;
2012 if (hapd
->conf
->acct_interim_interval
== 0 && acct_interim_interval
)
2013 sta
->acct_interim_interval
= acct_interim_interval
;
2014 if (res
== HOSTAPD_ACL_ACCEPT_TIMEOUT
) {
2015 sta
->session_timeout_set
= 1;
2016 os_get_reltime(&sta
->session_timeout
);
2017 sta
->session_timeout
.sec
+= session_timeout
;
2018 ap_sta_session_timeout(hapd
, sta
, session_timeout
);
2020 sta
->session_timeout_set
= 0;
2021 ap_sta_no_session_timeout(hapd
, sta
);
2028 static void handle_auth(struct hostapd_data
*hapd
,
2029 const struct ieee80211_mgmt
*mgmt
, size_t len
,
2030 int rssi
, int from_queue
)
2032 u16 auth_alg
, auth_transaction
, status_code
;
2033 u16 resp
= WLAN_STATUS_SUCCESS
;
2034 struct sta_info
*sta
= NULL
;
2037 const u8
*challenge
= NULL
;
2038 u32 session_timeout
, acct_interim_interval
;
2039 struct vlan_description vlan_id
;
2040 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
2041 u8 resp_ies
[2 + WLAN_AUTH_CHALLENGE_LEN
];
2042 size_t resp_ies_len
= 0;
2043 char *identity
= NULL
;
2044 char *radius_cui
= NULL
;
2047 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
2048 wpa_printf(MSG_INFO
, "handle_auth - too short payload (len=%lu)",
2049 (unsigned long) len
);
2053 #ifdef CONFIG_TESTING_OPTIONS
2054 if (hapd
->iconf
->ignore_auth_probability
> 0.0 &&
2055 drand48() < hapd
->iconf
->ignore_auth_probability
) {
2056 wpa_printf(MSG_INFO
,
2057 "TESTING: ignoring auth frame from " MACSTR
,
2061 #endif /* CONFIG_TESTING_OPTIONS */
2063 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
2064 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
2065 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
2066 fc
= le_to_host16(mgmt
->frame_control
);
2067 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
2069 if (len
>= IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
) +
2070 2 + WLAN_AUTH_CHALLENGE_LEN
&&
2071 mgmt
->u
.auth
.variable
[0] == WLAN_EID_CHALLENGE
&&
2072 mgmt
->u
.auth
.variable
[1] == WLAN_AUTH_CHALLENGE_LEN
)
2073 challenge
= &mgmt
->u
.auth
.variable
[2];
2075 wpa_printf(MSG_DEBUG
, "authentication: STA=" MACSTR
" auth_alg=%d "
2076 "auth_transaction=%d status_code=%d wep=%d%s "
2077 "seq_ctrl=0x%x%s%s",
2078 MAC2STR(mgmt
->sa
), auth_alg
, auth_transaction
,
2079 status_code
, !!(fc
& WLAN_FC_ISWEP
),
2080 challenge
? " challenge" : "",
2081 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "",
2082 from_queue
? " (from queue)" : "");
2084 #ifdef CONFIG_NO_RC4
2085 if (auth_alg
== WLAN_AUTH_SHARED_KEY
) {
2086 wpa_printf(MSG_INFO
,
2087 "Unsupported authentication algorithm (%d)",
2089 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2092 #endif /* CONFIG_NO_RC4 */
2094 if (hapd
->tkip_countermeasures
) {
2095 wpa_printf(MSG_DEBUG
,
2096 "Ongoing TKIP countermeasures (Michael MIC failure) - reject authentication");
2097 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2101 if (!(((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_OPEN
) &&
2102 auth_alg
== WLAN_AUTH_OPEN
) ||
2103 #ifdef CONFIG_IEEE80211R_AP
2104 (hapd
->conf
->wpa
&& wpa_key_mgmt_ft(hapd
->conf
->wpa_key_mgmt
) &&
2105 auth_alg
== WLAN_AUTH_FT
) ||
2106 #endif /* CONFIG_IEEE80211R_AP */
2108 (hapd
->conf
->wpa
&& wpa_key_mgmt_sae(hapd
->conf
->wpa_key_mgmt
) &&
2109 auth_alg
== WLAN_AUTH_SAE
) ||
2110 #endif /* CONFIG_SAE */
2112 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2113 auth_alg
== WLAN_AUTH_FILS_SK
) ||
2114 (hapd
->conf
->wpa
&& wpa_key_mgmt_fils(hapd
->conf
->wpa_key_mgmt
) &&
2115 hapd
->conf
->fils_dh_group
&&
2116 auth_alg
== WLAN_AUTH_FILS_SK_PFS
) ||
2117 #endif /* CONFIG_FILS */
2118 ((hapd
->conf
->auth_algs
& WPA_AUTH_ALG_SHARED
) &&
2119 auth_alg
== WLAN_AUTH_SHARED_KEY
))) {
2120 wpa_printf(MSG_INFO
, "Unsupported authentication algorithm (%d)",
2122 resp
= WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
2126 if (!(auth_transaction
== 1 || auth_alg
== WLAN_AUTH_SAE
||
2127 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 3))) {
2128 wpa_printf(MSG_INFO
, "Unknown authentication transaction number (%d)",
2130 resp
= WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION
;
2134 if (os_memcmp(mgmt
->sa
, hapd
->own_addr
, ETH_ALEN
) == 0) {
2135 wpa_printf(MSG_INFO
, "Station " MACSTR
" not allowed to authenticate",
2137 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2141 if (hapd
->conf
->no_auth_if_seen_on
) {
2142 struct hostapd_data
*other
;
2144 other
= sta_track_seen_on(hapd
->iface
, mgmt
->sa
,
2145 hapd
->conf
->no_auth_if_seen_on
);
2149 u8 op_class
, channel
, phytype
;
2151 wpa_printf(MSG_DEBUG
, "%s: Reject authentication from "
2152 MACSTR
" since STA has been seen on %s",
2153 hapd
->conf
->iface
, MAC2STR(mgmt
->sa
),
2154 hapd
->conf
->no_auth_if_seen_on
);
2156 resp
= WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION
;
2158 *pos
++ = WLAN_EID_NEIGHBOR_REPORT
;
2160 os_memcpy(pos
, other
->own_addr
, ETH_ALEN
);
2162 info
= 0; /* TODO: BSSID Information */
2163 WPA_PUT_LE32(pos
, info
);
2165 if (other
->iconf
->hw_mode
== HOSTAPD_MODE_IEEE80211AD
)
2166 phytype
= 8; /* dmg */
2167 else if (other
->iconf
->ieee80211ac
)
2168 phytype
= 9; /* vht */
2169 else if (other
->iconf
->ieee80211n
)
2170 phytype
= 7; /* ht */
2171 else if (other
->iconf
->hw_mode
==
2172 HOSTAPD_MODE_IEEE80211A
)
2173 phytype
= 4; /* ofdm */
2174 else if (other
->iconf
->hw_mode
==
2175 HOSTAPD_MODE_IEEE80211G
)
2176 phytype
= 6; /* erp */
2178 phytype
= 5; /* hrdsss */
2179 if (ieee80211_freq_to_channel_ext(
2180 hostapd_hw_get_freq(other
,
2181 other
->iconf
->channel
),
2182 other
->iconf
->secondary_channel
,
2183 other
->iconf
->ieee80211ac
,
2184 &op_class
, &channel
) == NUM_HOSTAPD_MODES
) {
2186 channel
= other
->iconf
->channel
;
2191 resp_ies_len
= pos
- &resp_ies
[0];
2196 res
= ieee802_11_allowed_address(
2197 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
, &session_timeout
,
2198 &acct_interim_interval
, &vlan_id
, &psk
, &identity
, &radius_cui
,
2200 if (res
== HOSTAPD_ACL_REJECT
) {
2201 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
2202 "Ignore Authentication frame from " MACSTR
2203 " due to ACL reject", MAC2STR(mgmt
->sa
));
2204 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2207 if (res
== HOSTAPD_ACL_PENDING
)
2211 if (auth_alg
== WLAN_AUTH_SAE
&& !from_queue
&&
2212 (auth_transaction
== 1 ||
2213 (auth_transaction
== 2 && auth_sae_queued_addr(hapd
, mgmt
->sa
)))) {
2214 /* Handle SAE Authentication commit message through a queue to
2215 * provide more control for postponing the needed heavy
2216 * processing under a possible DoS attack scenario. In addition,
2217 * queue SAE Authentication confirm message if there happens to
2218 * be a queued commit message from the same peer. This is needed
2219 * to avoid reordering Authentication frames within the same
2221 auth_sae_queue(hapd
, mgmt
, len
, rssi
);
2224 #endif /* CONFIG_SAE */
2226 sta
= ap_get_sta(hapd
, mgmt
->sa
);
2228 sta
->flags
&= ~WLAN_STA_PENDING_FILS_ERP
;
2229 sta
->ft_over_ds
= 0;
2230 if ((fc
& WLAN_FC_RETRY
) &&
2231 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
2232 sta
->last_seq_ctrl
== seq_ctrl
&&
2233 sta
->last_subtype
== WLAN_FC_STYPE_AUTH
) {
2234 hostapd_logger(hapd
, sta
->addr
,
2235 HOSTAPD_MODULE_IEEE80211
,
2236 HOSTAPD_LEVEL_DEBUG
,
2237 "Drop repeated authentication frame seq_ctrl=0x%x",
2242 if ((hapd
->conf
->mesh
& MESH_ENABLED
) &&
2243 sta
->plink_state
== PLINK_BLOCKED
) {
2244 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2245 " is blocked - drop Authentication frame",
2249 #endif /* CONFIG_MESH */
2252 if (hapd
->conf
->mesh
& MESH_ENABLED
) {
2253 /* if the mesh peer is not available, we don't do auth.
2255 wpa_printf(MSG_DEBUG
, "Mesh peer " MACSTR
2256 " not yet known - drop Authentication frame",
2259 * Save a copy of the frame so that it can be processed
2260 * if a new peer entry is added shortly after this.
2262 wpabuf_free(hapd
->mesh_pending_auth
);
2263 hapd
->mesh_pending_auth
= wpabuf_alloc_copy(mgmt
, len
);
2264 os_get_reltime(&hapd
->mesh_pending_auth_time
);
2267 #endif /* CONFIG_MESH */
2269 sta
= ap_sta_add(hapd
, mgmt
->sa
);
2271 wpa_printf(MSG_DEBUG
, "ap_sta_add() failed");
2272 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2276 sta
->last_seq_ctrl
= seq_ctrl
;
2277 sta
->last_subtype
= WLAN_FC_STYPE_AUTH
;
2279 sta
->auth_rssi
= rssi
;
2280 #endif /* CONFIG_MBO */
2282 res
= ieee802_11_set_radius_info(
2283 hapd
, sta
, res
, session_timeout
, acct_interim_interval
,
2284 &vlan_id
, &psk
, &identity
, &radius_cui
);
2286 wpa_printf(MSG_DEBUG
, "ieee802_11_set_radius_info() failed");
2287 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2291 sta
->flags
&= ~WLAN_STA_PREAUTH
;
2292 ieee802_1x_notify_pre_auth(sta
->eapol_sm
, 0);
2295 * If the driver supports full AP client state, add a station to the
2296 * driver before sending authentication reply to make sure the driver
2297 * has resources, and not to go through the entire authentication and
2298 * association handshake, and fail it at the end.
2300 * If this is not the first transaction, in a multi-step authentication
2301 * algorithm, the station already exists in the driver
2302 * (sta->added_unassoc = 1) so skip it.
2304 * In mesh mode, the station was already added to the driver when the
2305 * NEW_PEER_CANDIDATE event is received.
2307 * If PMF was negotiated for the existing association, skip this to
2308 * avoid dropping the STA entry and the associated keys. This is needed
2309 * to allow the original connection work until the attempt can complete
2310 * (re)association, so that unprotected Authentication frame cannot be
2311 * used to bypass PMF protection.
2313 if (FULL_AP_CLIENT_STATE_SUPP(hapd
->iface
->drv_flags
) &&
2314 (!(sta
->flags
& WLAN_STA_MFP
) || !ap_sta_is_authorized(sta
)) &&
2315 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
2316 !(sta
->added_unassoc
)) {
2318 * If a station that is already associated to the AP, is trying
2319 * to authenticate again, remove the STA entry, in order to make
2320 * sure the STA PS state gets cleared and configuration gets
2321 * updated. To handle this, station's added_unassoc flag is
2322 * cleared once the station has completed association.
2324 ap_sta_set_authorized(hapd
, sta
, 0);
2325 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2326 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_AUTH
|
2327 WLAN_STA_AUTHORIZED
);
2329 if (hostapd_sta_add(hapd
, sta
->addr
, 0, 0,
2330 sta
->supported_rates
,
2331 sta
->supported_rates_len
,
2332 0, NULL
, NULL
, NULL
, 0,
2333 sta
->flags
, 0, 0, 0, 0)) {
2334 hostapd_logger(hapd
, sta
->addr
,
2335 HOSTAPD_MODULE_IEEE80211
,
2336 HOSTAPD_LEVEL_NOTICE
,
2337 "Could not add STA to kernel driver");
2338 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
2342 sta
->added_unassoc
= 1;
2346 case WLAN_AUTH_OPEN
:
2347 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2348 HOSTAPD_LEVEL_DEBUG
,
2349 "authentication OK (open system)");
2350 sta
->flags
|= WLAN_STA_AUTH
;
2351 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
2352 sta
->auth_alg
= WLAN_AUTH_OPEN
;
2353 mlme_authenticate_indication(hapd
, sta
);
2355 #ifndef CONFIG_NO_RC4
2356 case WLAN_AUTH_SHARED_KEY
:
2357 resp
= auth_shared_key(hapd
, sta
, auth_transaction
, challenge
,
2358 fc
& WLAN_FC_ISWEP
);
2360 wpa_printf(MSG_DEBUG
,
2361 "auth_shared_key() failed: status=%d", resp
);
2362 sta
->auth_alg
= WLAN_AUTH_SHARED_KEY
;
2363 mlme_authenticate_indication(hapd
, sta
);
2364 if (sta
->challenge
&& auth_transaction
== 1) {
2365 resp_ies
[0] = WLAN_EID_CHALLENGE
;
2366 resp_ies
[1] = WLAN_AUTH_CHALLENGE_LEN
;
2367 os_memcpy(resp_ies
+ 2, sta
->challenge
,
2368 WLAN_AUTH_CHALLENGE_LEN
);
2369 resp_ies_len
= 2 + WLAN_AUTH_CHALLENGE_LEN
;
2372 #endif /* CONFIG_NO_RC4 */
2373 #ifdef CONFIG_IEEE80211R_AP
2375 sta
->auth_alg
= WLAN_AUTH_FT
;
2376 if (sta
->wpa_sm
== NULL
)
2377 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
2379 if (sta
->wpa_sm
== NULL
) {
2380 wpa_printf(MSG_DEBUG
, "FT: Failed to initialize WPA "
2382 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2385 wpa_ft_process_auth(sta
->wpa_sm
, mgmt
->bssid
,
2386 auth_transaction
, mgmt
->u
.auth
.variable
,
2387 len
- IEEE80211_HDRLEN
-
2388 sizeof(mgmt
->u
.auth
),
2389 handle_auth_ft_finish
, hapd
);
2390 /* handle_auth_ft_finish() callback will complete auth. */
2392 #endif /* CONFIG_IEEE80211R_AP */
2396 if (status_code
== WLAN_STATUS_SUCCESS
&&
2397 hapd
->conf
->mesh
& MESH_ENABLED
) {
2398 if (sta
->wpa_sm
== NULL
)
2400 wpa_auth_sta_init(hapd
->wpa_auth
,
2402 if (sta
->wpa_sm
== NULL
) {
2403 wpa_printf(MSG_DEBUG
,
2404 "SAE: Failed to initialize WPA state machine");
2405 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2409 #endif /* CONFIG_MESH */
2410 handle_auth_sae(hapd
, sta
, mgmt
, len
, auth_transaction
,
2413 #endif /* CONFIG_SAE */
2415 case WLAN_AUTH_FILS_SK
:
2416 case WLAN_AUTH_FILS_SK_PFS
:
2417 handle_auth_fils(hapd
, sta
, mgmt
->u
.auth
.variable
,
2418 len
- IEEE80211_HDRLEN
- sizeof(mgmt
->u
.auth
),
2419 auth_alg
, auth_transaction
, status_code
,
2420 handle_auth_fils_finish
);
2422 #endif /* CONFIG_FILS */
2427 os_free(radius_cui
);
2428 hostapd_free_psk_list(psk
);
2430 reply_res
= send_auth_reply(hapd
, mgmt
->sa
, mgmt
->bssid
, auth_alg
,
2431 auth_transaction
+ 1, resp
, resp_ies
,
2432 resp_ies_len
, "handle-auth");
2434 if (sta
&& sta
->added_unassoc
&& (resp
!= WLAN_STATUS_SUCCESS
||
2435 reply_res
!= WLAN_STATUS_SUCCESS
)) {
2436 hostapd_drv_sta_remove(hapd
, sta
->addr
);
2437 sta
->added_unassoc
= 0;
2442 int hostapd_get_aid(struct hostapd_data
*hapd
, struct sta_info
*sta
)
2446 /* get a unique AID */
2448 wpa_printf(MSG_DEBUG
, " old AID %d", sta
->aid
);
2455 for (i
= 0; i
< AID_WORDS
; i
++) {
2456 if (hapd
->sta_aid
[i
] == (u32
) -1)
2458 for (j
= 0; j
< 32; j
++) {
2459 if (!(hapd
->sta_aid
[i
] & BIT(j
)))
2467 aid
= i
* 32 + j
+ 1;
2472 hapd
->sta_aid
[i
] |= BIT(j
);
2473 wpa_printf(MSG_DEBUG
, " new AID %d", sta
->aid
);
2478 static u16
check_ssid(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2479 const u8
*ssid_ie
, size_t ssid_ie_len
)
2481 if (ssid_ie
== NULL
)
2482 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2484 if (ssid_ie_len
!= hapd
->conf
->ssid
.ssid_len
||
2485 os_memcmp(ssid_ie
, hapd
->conf
->ssid
.ssid
, ssid_ie_len
) != 0) {
2486 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2488 "Station tried to associate with unknown SSID "
2489 "'%s'", wpa_ssid_txt(ssid_ie
, ssid_ie_len
));
2490 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2493 return WLAN_STATUS_SUCCESS
;
2497 static u16
check_wmm(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2498 const u8
*wmm_ie
, size_t wmm_ie_len
)
2500 sta
->flags
&= ~WLAN_STA_WMM
;
2502 if (wmm_ie
&& hapd
->conf
->wmm_enabled
) {
2503 struct wmm_information_element
*wmm
;
2505 if (!hostapd_eid_wmm_valid(hapd
, wmm_ie
, wmm_ie_len
)) {
2506 hostapd_logger(hapd
, sta
->addr
,
2508 HOSTAPD_LEVEL_DEBUG
,
2509 "invalid WMM element in association "
2511 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2514 sta
->flags
|= WLAN_STA_WMM
;
2515 wmm
= (struct wmm_information_element
*) wmm_ie
;
2516 sta
->qosinfo
= wmm
->qos_info
;
2518 return WLAN_STATUS_SUCCESS
;
2521 static u16
check_multi_ap(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2522 const u8
*multi_ap_ie
, size_t multi_ap_len
)
2524 u8 multi_ap_value
= 0;
2526 sta
->flags
&= ~WLAN_STA_MULTI_AP
;
2528 if (!hapd
->conf
->multi_ap
)
2529 return WLAN_STATUS_SUCCESS
;
2532 const u8
*multi_ap_subelem
;
2534 multi_ap_subelem
= get_ie(multi_ap_ie
+ 4,
2536 MULTI_AP_SUB_ELEM_TYPE
);
2537 if (multi_ap_subelem
&& multi_ap_subelem
[1] == 1) {
2538 multi_ap_value
= multi_ap_subelem
[2];
2540 hostapd_logger(hapd
, sta
->addr
,
2541 HOSTAPD_MODULE_IEEE80211
,
2543 "Multi-AP IE has missing or invalid Multi-AP subelement");
2544 return WLAN_STATUS_INVALID_IE
;
2548 if (multi_ap_value
&& multi_ap_value
!= MULTI_AP_BACKHAUL_STA
)
2549 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2551 "Multi-AP IE with unexpected value 0x%02x",
2554 if (!(multi_ap_value
& MULTI_AP_BACKHAUL_STA
)) {
2555 if (hapd
->conf
->multi_ap
& FRONTHAUL_BSS
)
2556 return WLAN_STATUS_SUCCESS
;
2558 hostapd_logger(hapd
, sta
->addr
,
2559 HOSTAPD_MODULE_IEEE80211
,
2561 "Non-Multi-AP STA tries to associate with backhaul-only BSS");
2562 return WLAN_STATUS_ASSOC_DENIED_UNSPEC
;
2565 if (!(hapd
->conf
->multi_ap
& BACKHAUL_BSS
))
2566 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2567 HOSTAPD_LEVEL_DEBUG
,
2568 "Backhaul STA tries to associate with fronthaul-only BSS");
2570 sta
->flags
|= WLAN_STA_MULTI_AP
;
2571 return WLAN_STATUS_SUCCESS
;
2575 static u16
copy_supp_rates(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2576 struct ieee802_11_elems
*elems
)
2578 /* Supported rates not used in IEEE 802.11ad/DMG */
2579 if (hapd
->iface
->current_mode
&&
2580 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
)
2581 return WLAN_STATUS_SUCCESS
;
2583 if (!elems
->supp_rates
) {
2584 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2585 HOSTAPD_LEVEL_DEBUG
,
2586 "No supported rates element in AssocReq");
2587 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2590 if (elems
->supp_rates_len
+ elems
->ext_supp_rates_len
>
2591 sizeof(sta
->supported_rates
)) {
2592 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2593 HOSTAPD_LEVEL_DEBUG
,
2594 "Invalid supported rates element length %d+%d",
2595 elems
->supp_rates_len
,
2596 elems
->ext_supp_rates_len
);
2597 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2600 sta
->supported_rates_len
= merge_byte_arrays(
2601 sta
->supported_rates
, sizeof(sta
->supported_rates
),
2602 elems
->supp_rates
, elems
->supp_rates_len
,
2603 elems
->ext_supp_rates
, elems
->ext_supp_rates_len
);
2605 return WLAN_STATUS_SUCCESS
;
2609 static u16
check_ext_capab(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2610 const u8
*ext_capab_ie
, size_t ext_capab_ie_len
)
2612 #ifdef CONFIG_INTERWORKING
2613 /* check for QoS Map support */
2614 if (ext_capab_ie_len
>= 5) {
2615 if (ext_capab_ie
[4] & 0x01)
2616 sta
->qos_map_enabled
= 1;
2618 #endif /* CONFIG_INTERWORKING */
2620 if (ext_capab_ie_len
> 0) {
2621 sta
->ecsa_supported
= !!(ext_capab_ie
[0] & BIT(2));
2622 os_free(sta
->ext_capability
);
2623 sta
->ext_capability
= os_malloc(1 + ext_capab_ie_len
);
2624 if (sta
->ext_capability
) {
2625 sta
->ext_capability
[0] = ext_capab_ie_len
;
2626 os_memcpy(sta
->ext_capability
+ 1, ext_capab_ie
,
2631 return WLAN_STATUS_SUCCESS
;
2637 static int owe_group_supported(struct hostapd_data
*hapd
, u16 group
)
2640 int *groups
= hapd
->conf
->owe_groups
;
2642 if (group
!= 19 && group
!= 20 && group
!= 21)
2648 for (i
= 0; groups
[i
] > 0; i
++) {
2649 if (groups
[i
] == group
)
2657 static u16
owe_process_assoc_req(struct hostapd_data
*hapd
,
2658 struct sta_info
*sta
, const u8
*owe_dh
,
2661 struct wpabuf
*secret
, *pub
, *hkey
;
2663 u8 prk
[SHA512_MAC_LEN
], pmkid
[SHA512_MAC_LEN
];
2664 const char *info
= "OWE Key Generation";
2668 size_t hash_len
, prime_len
;
2670 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
2671 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
2672 return WLAN_STATUS_SUCCESS
;
2675 group
= WPA_GET_LE16(owe_dh
);
2676 if (!owe_group_supported(hapd
, group
)) {
2677 wpa_printf(MSG_DEBUG
, "OWE: Unsupported DH group %u", group
);
2678 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2682 else if (group
== 20)
2684 else if (group
== 21)
2687 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2689 crypto_ecdh_deinit(sta
->owe_ecdh
);
2690 sta
->owe_ecdh
= crypto_ecdh_init(group
);
2692 return WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
;
2693 sta
->owe_group
= group
;
2695 secret
= crypto_ecdh_set_peerkey(sta
->owe_ecdh
, 0, owe_dh
+ 2,
2697 secret
= wpabuf_zeropad(secret
, prime_len
);
2699 wpa_printf(MSG_DEBUG
, "OWE: Invalid peer DH public key");
2700 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2702 wpa_hexdump_buf_key(MSG_DEBUG
, "OWE: DH shared secret", secret
);
2704 /* prk = HKDF-extract(C | A | group, z) */
2706 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2708 wpabuf_clear_free(secret
);
2709 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2712 /* PMKID = Truncate-128(Hash(C | A)) */
2713 addr
[0] = owe_dh
+ 2;
2714 len
[0] = owe_dh_len
- 2;
2715 addr
[1] = wpabuf_head(pub
);
2716 len
[1] = wpabuf_len(pub
);
2718 res
= sha256_vector(2, addr
, len
, pmkid
);
2719 hash_len
= SHA256_MAC_LEN
;
2720 } else if (group
== 20) {
2721 res
= sha384_vector(2, addr
, len
, pmkid
);
2722 hash_len
= SHA384_MAC_LEN
;
2723 } else if (group
== 21) {
2724 res
= sha512_vector(2, addr
, len
, pmkid
);
2725 hash_len
= SHA512_MAC_LEN
;
2728 wpabuf_clear_free(secret
);
2729 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2731 pub
= wpabuf_zeropad(pub
, prime_len
);
2732 if (res
< 0 || !pub
) {
2734 wpabuf_clear_free(secret
);
2735 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2738 hkey
= wpabuf_alloc(owe_dh_len
- 2 + wpabuf_len(pub
) + 2);
2741 wpabuf_clear_free(secret
);
2742 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2745 wpabuf_put_data(hkey
, owe_dh
+ 2, owe_dh_len
- 2); /* C */
2746 wpabuf_put_buf(hkey
, pub
); /* A */
2748 wpabuf_put_le16(hkey
, group
); /* group */
2750 res
= hmac_sha256(wpabuf_head(hkey
), wpabuf_len(hkey
),
2751 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2752 else if (group
== 20)
2753 res
= hmac_sha384(wpabuf_head(hkey
), wpabuf_len(hkey
),
2754 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2755 else if (group
== 21)
2756 res
= hmac_sha512(wpabuf_head(hkey
), wpabuf_len(hkey
),
2757 wpabuf_head(secret
), wpabuf_len(secret
), prk
);
2758 wpabuf_clear_free(hkey
);
2759 wpabuf_clear_free(secret
);
2761 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2763 wpa_hexdump_key(MSG_DEBUG
, "OWE: prk", prk
, hash_len
);
2765 /* PMK = HKDF-expand(prk, "OWE Key Generation", n) */
2767 os_free(sta
->owe_pmk
);
2768 sta
->owe_pmk
= os_malloc(hash_len
);
2769 if (!sta
->owe_pmk
) {
2770 os_memset(prk
, 0, SHA512_MAC_LEN
);
2771 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2775 res
= hmac_sha256_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2776 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2777 else if (group
== 20)
2778 res
= hmac_sha384_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2779 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2780 else if (group
== 21)
2781 res
= hmac_sha512_kdf(prk
, hash_len
, NULL
, (const u8
*) info
,
2782 os_strlen(info
), sta
->owe_pmk
, hash_len
);
2783 os_memset(prk
, 0, SHA512_MAC_LEN
);
2785 os_free(sta
->owe_pmk
);
2786 sta
->owe_pmk
= NULL
;
2787 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2789 sta
->owe_pmk_len
= hash_len
;
2791 wpa_hexdump_key(MSG_DEBUG
, "OWE: PMK", sta
->owe_pmk
, sta
->owe_pmk_len
);
2792 wpa_hexdump(MSG_DEBUG
, "OWE: PMKID", pmkid
, PMKID_LEN
);
2793 wpa_auth_pmksa_add2(hapd
->wpa_auth
, sta
->addr
, sta
->owe_pmk
,
2794 sta
->owe_pmk_len
, pmkid
, 0, WPA_KEY_MGMT_OWE
);
2796 return WLAN_STATUS_SUCCESS
;
2800 u16
owe_validate_request(struct hostapd_data
*hapd
, const u8
*peer
,
2801 const u8
*rsn_ie
, size_t rsn_ie_len
,
2802 const u8
*owe_dh
, size_t owe_dh_len
)
2804 struct wpa_ie_data data
;
2807 if (!rsn_ie
|| rsn_ie_len
< 2) {
2808 wpa_printf(MSG_DEBUG
, "OWE: Invalid RSNE from " MACSTR
,
2810 return WLAN_STATUS_INVALID_IE
;
2815 res
= wpa_parse_wpa_ie_rsn(rsn_ie
, rsn_ie_len
, &data
);
2817 wpa_printf(MSG_DEBUG
, "Failed to parse RSNE from " MACSTR
2818 " (res=%d)", MAC2STR(peer
), res
);
2819 wpa_hexdump(MSG_DEBUG
, "RSNE", rsn_ie
, rsn_ie_len
);
2820 return wpa_res_to_status_code(res
);
2822 if (!(data
.key_mgmt
& WPA_KEY_MGMT_OWE
)) {
2823 wpa_printf(MSG_DEBUG
,
2824 "OWE: Unexpected key mgmt 0x%x from " MACSTR
,
2825 (unsigned int) data
.key_mgmt
, MAC2STR(peer
));
2826 return WLAN_STATUS_AKMP_NOT_VALID
;
2829 wpa_printf(MSG_DEBUG
,
2830 "OWE: No Diffie-Hellman Parameter element from "
2831 MACSTR
, MAC2STR(peer
));
2832 return WLAN_STATUS_AKMP_NOT_VALID
;
2835 return WLAN_STATUS_SUCCESS
;
2839 u16
owe_process_rsn_ie(struct hostapd_data
*hapd
,
2840 struct sta_info
*sta
,
2841 const u8
*rsn_ie
, size_t rsn_ie_len
,
2842 const u8
*owe_dh
, size_t owe_dh_len
)
2845 u8
*owe_buf
, ie
[256 * 2];
2849 if (!rsn_ie
|| rsn_ie_len
< 2) {
2850 wpa_printf(MSG_DEBUG
, "OWE: No RSNE in (Re)AssocReq");
2851 status
= WLAN_STATUS_INVALID_IE
;
2856 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
, sta
->addr
,
2859 wpa_printf(MSG_WARNING
,
2860 "OWE: Failed to initialize WPA state machine");
2861 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2866 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
2867 hapd
->iface
->freq
, rsn_ie
, rsn_ie_len
,
2868 NULL
, 0, owe_dh
, owe_dh_len
);
2869 status
= wpa_res_to_status_code(res
);
2870 if (status
!= WLAN_STATUS_SUCCESS
)
2872 status
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
2873 if (status
!= WLAN_STATUS_SUCCESS
)
2875 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, ie
, sizeof(ie
),
2878 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2882 if (sta
->owe_ecdh
) {
2885 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
2887 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
2891 /* OWE Diffie-Hellman Parameter element */
2892 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
2893 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
2894 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
2896 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
2898 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
2899 owe_buf
+= wpabuf_len(pub
);
2901 sta
->external_dh_updated
= 1;
2903 ie_len
= owe_buf
- ie
;
2906 wpa_printf(MSG_DEBUG
, "OWE: Update status %d, ie len %d for peer "
2907 MACSTR
, status
, (unsigned int) ie_len
,
2908 MAC2STR(sta
->addr
));
2909 hostapd_drv_update_dh_ie(hapd
, sta
->addr
, status
,
2910 status
== WLAN_STATUS_SUCCESS
? ie
: NULL
,
2916 #endif /* CONFIG_OWE */
2919 static u16
check_assoc_ies(struct hostapd_data
*hapd
, struct sta_info
*sta
,
2920 const u8
*ies
, size_t ies_len
, int reassoc
)
2922 struct ieee802_11_elems elems
;
2926 const u8
*p2p_dev_addr
= NULL
;
2928 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 1) == ParseFailed
) {
2929 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2930 HOSTAPD_LEVEL_INFO
, "Station sent an invalid "
2931 "association request");
2932 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
2935 resp
= check_ssid(hapd
, sta
, elems
.ssid
, elems
.ssid_len
);
2936 if (resp
!= WLAN_STATUS_SUCCESS
)
2938 resp
= check_wmm(hapd
, sta
, elems
.wmm
, elems
.wmm_len
);
2939 if (resp
!= WLAN_STATUS_SUCCESS
)
2941 resp
= check_ext_capab(hapd
, sta
, elems
.ext_capab
, elems
.ext_capab_len
);
2942 if (resp
!= WLAN_STATUS_SUCCESS
)
2944 resp
= copy_supp_rates(hapd
, sta
, &elems
);
2945 if (resp
!= WLAN_STATUS_SUCCESS
)
2948 resp
= check_multi_ap(hapd
, sta
, elems
.multi_ap
, elems
.multi_ap_len
);
2949 if (resp
!= WLAN_STATUS_SUCCESS
)
2952 #ifdef CONFIG_IEEE80211N
2953 resp
= copy_sta_ht_capab(hapd
, sta
, elems
.ht_capabilities
);
2954 if (resp
!= WLAN_STATUS_SUCCESS
)
2956 if (hapd
->iconf
->ieee80211n
&& hapd
->iconf
->require_ht
&&
2957 !(sta
->flags
& WLAN_STA_HT
)) {
2958 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2959 HOSTAPD_LEVEL_INFO
, "Station does not support "
2960 "mandatory HT PHY - reject association");
2961 return WLAN_STATUS_ASSOC_DENIED_NO_HT
;
2963 #endif /* CONFIG_IEEE80211N */
2965 #ifdef CONFIG_IEEE80211AC
2966 if (hapd
->iconf
->ieee80211ac
) {
2967 resp
= copy_sta_vht_capab(hapd
, sta
, elems
.vht_capabilities
);
2968 if (resp
!= WLAN_STATUS_SUCCESS
)
2971 resp
= set_sta_vht_opmode(hapd
, sta
, elems
.vht_opmode_notif
);
2972 if (resp
!= WLAN_STATUS_SUCCESS
)
2976 if (hapd
->iconf
->ieee80211ac
&& hapd
->iconf
->require_vht
&&
2977 !(sta
->flags
& WLAN_STA_VHT
)) {
2978 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
2979 HOSTAPD_LEVEL_INFO
, "Station does not support "
2980 "mandatory VHT PHY - reject association");
2981 return WLAN_STATUS_ASSOC_DENIED_NO_VHT
;
2984 if (hapd
->conf
->vendor_vht
&& !elems
.vht_capabilities
) {
2985 resp
= copy_sta_vendor_vht(hapd
, sta
, elems
.vendor_vht
,
2986 elems
.vendor_vht_len
);
2987 if (resp
!= WLAN_STATUS_SUCCESS
)
2990 #endif /* CONFIG_IEEE80211AC */
2991 #ifdef CONFIG_IEEE80211AX
2992 if (hapd
->iconf
->ieee80211ax
) {
2993 resp
= copy_sta_he_capab(hapd
, sta
, IEEE80211_MODE_AP
,
2994 elems
.he_capabilities
,
2995 elems
.he_capabilities_len
);
2996 if (resp
!= WLAN_STATUS_SUCCESS
)
2999 #endif /* CONFIG_IEEE80211AX */
3003 wpabuf_free(sta
->p2p_ie
);
3004 sta
->p2p_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3005 P2P_IE_VENDOR_TYPE
);
3007 p2p_dev_addr
= p2p_get_go_dev_addr(sta
->p2p_ie
);
3009 wpabuf_free(sta
->p2p_ie
);
3012 #endif /* CONFIG_P2P */
3014 if ((hapd
->conf
->wpa
& WPA_PROTO_RSN
) && elems
.rsn_ie
) {
3015 wpa_ie
= elems
.rsn_ie
;
3016 wpa_ie_len
= elems
.rsn_ie_len
;
3017 } else if ((hapd
->conf
->wpa
& WPA_PROTO_WPA
) &&
3019 wpa_ie
= elems
.wpa_ie
;
3020 wpa_ie_len
= elems
.wpa_ie_len
;
3027 sta
->flags
&= ~(WLAN_STA_WPS
| WLAN_STA_MAYBE_WPS
| WLAN_STA_WPS2
);
3028 if (hapd
->conf
->wps_state
&& elems
.wps_ie
) {
3029 wpa_printf(MSG_DEBUG
, "STA included WPS IE in (Re)Association "
3030 "Request - assume WPS is used");
3031 sta
->flags
|= WLAN_STA_WPS
;
3032 wpabuf_free(sta
->wps_ie
);
3033 sta
->wps_ie
= ieee802_11_vendor_ie_concat(ies
, ies_len
,
3034 WPS_IE_VENDOR_TYPE
);
3035 if (sta
->wps_ie
&& wps_is_20(sta
->wps_ie
)) {
3036 wpa_printf(MSG_DEBUG
, "WPS: STA supports WPS 2.0");
3037 sta
->flags
|= WLAN_STA_WPS2
;
3041 if (sta
->wps_ie
&& wps_validate_assoc_req(sta
->wps_ie
) < 0) {
3042 wpa_printf(MSG_DEBUG
, "WPS: Invalid WPS IE in "
3043 "(Re)Association Request - reject");
3044 return WLAN_STATUS_INVALID_IE
;
3046 } else if (hapd
->conf
->wps_state
&& wpa_ie
== NULL
) {
3047 wpa_printf(MSG_DEBUG
, "STA did not include WPA/RSN IE in "
3048 "(Re)Association Request - possible WPS use");
3049 sta
->flags
|= WLAN_STA_MAYBE_WPS
;
3051 #endif /* CONFIG_WPS */
3052 if (hapd
->conf
->wpa
&& wpa_ie
== NULL
) {
3053 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3055 "No WPA/RSN IE in association request");
3056 return WLAN_STATUS_INVALID_IE
;
3059 if (hapd
->conf
->wpa
&& wpa_ie
) {
3063 if (sta
->wpa_sm
== NULL
)
3064 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3067 if (sta
->wpa_sm
== NULL
) {
3068 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3070 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3072 wpa_auth_set_auth_alg(sta
->wpa_sm
, sta
->auth_alg
);
3073 res
= wpa_validate_wpa_ie(hapd
->wpa_auth
, sta
->wpa_sm
,
3076 elems
.mdie
, elems
.mdie_len
,
3077 elems
.owe_dh
, elems
.owe_dh_len
);
3078 resp
= wpa_res_to_status_code(res
);
3079 if (resp
!= WLAN_STATUS_SUCCESS
)
3081 #ifdef CONFIG_IEEE80211W
3082 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3083 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3084 !sta
->sa_query_timed_out
&&
3085 sta
->sa_query_count
> 0)
3086 ap_check_sa_query_timeout(hapd
, sta
);
3087 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_MFP
)) ==
3088 (WLAN_STA_ASSOC
| WLAN_STA_MFP
) &&
3089 !sta
->sa_query_timed_out
&&
3090 (!reassoc
|| sta
->auth_alg
!= WLAN_AUTH_FT
)) {
3092 * STA has already been associated with MFP and SA
3093 * Query timeout has not been reached. Reject the
3094 * association attempt temporarily and start SA Query,
3095 * if one is not pending.
3098 if (sta
->sa_query_count
== 0)
3099 ap_sta_start_sa_query(hapd
, sta
);
3101 return WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
;
3104 if (wpa_auth_uses_mfp(sta
->wpa_sm
))
3105 sta
->flags
|= WLAN_STA_MFP
;
3107 sta
->flags
&= ~WLAN_STA_MFP
;
3108 #endif /* CONFIG_IEEE80211W */
3110 #ifdef CONFIG_IEEE80211R_AP
3111 if (sta
->auth_alg
== WLAN_AUTH_FT
) {
3113 wpa_printf(MSG_DEBUG
, "FT: " MACSTR
" tried "
3114 "to use association (not "
3115 "re-association) with FT auth_alg",
3116 MAC2STR(sta
->addr
));
3117 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3120 resp
= wpa_ft_validate_reassoc(sta
->wpa_sm
, ies
,
3122 if (resp
!= WLAN_STATUS_SUCCESS
)
3125 #endif /* CONFIG_IEEE80211R_AP */
3128 if (wpa_auth_uses_sae(sta
->wpa_sm
) && sta
->sae
&&
3129 sta
->sae
->state
== SAE_ACCEPTED
)
3130 wpa_auth_add_sae_pmkid(sta
->wpa_sm
, sta
->sae
->pmkid
);
3132 if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3133 sta
->auth_alg
== WLAN_AUTH_OPEN
) {
3134 struct rsn_pmksa_cache_entry
*sa
;
3135 sa
= wpa_auth_sta_get_pmksa(sta
->wpa_sm
);
3136 if (!sa
|| sa
->akmp
!= WPA_KEY_MGMT_SAE
) {
3137 wpa_printf(MSG_DEBUG
,
3138 "SAE: No PMKSA cache entry found for "
3139 MACSTR
, MAC2STR(sta
->addr
));
3140 return WLAN_STATUS_INVALID_PMKID
;
3142 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
3143 " using PMKSA caching", MAC2STR(sta
->addr
));
3144 } else if (wpa_auth_uses_sae(sta
->wpa_sm
) &&
3145 sta
->auth_alg
!= WLAN_AUTH_SAE
&&
3146 !(sta
->auth_alg
== WLAN_AUTH_FT
&&
3147 wpa_auth_uses_ft_sae(sta
->wpa_sm
))) {
3148 wpa_printf(MSG_DEBUG
, "SAE: " MACSTR
" tried to use "
3149 "SAE AKM after non-SAE auth_alg %u",
3150 MAC2STR(sta
->addr
), sta
->auth_alg
);
3151 return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
;
3153 #endif /* CONFIG_SAE */
3156 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3157 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
&&
3159 resp
= owe_process_assoc_req(hapd
, sta
, elems
.owe_dh
,
3161 if (resp
!= WLAN_STATUS_SUCCESS
)
3164 #endif /* CONFIG_OWE */
3167 dpp_pfs_free(sta
->dpp_pfs
);
3168 sta
->dpp_pfs
= NULL
;
3170 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3171 hapd
->conf
->dpp_netaccesskey
&& sta
->wpa_sm
&&
3172 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
&&
3174 sta
->dpp_pfs
= dpp_pfs_init(
3175 wpabuf_head(hapd
->conf
->dpp_netaccesskey
),
3176 wpabuf_len(hapd
->conf
->dpp_netaccesskey
));
3177 if (!sta
->dpp_pfs
) {
3178 wpa_printf(MSG_DEBUG
,
3179 "DPP: Could not initialize PFS");
3180 /* Try to continue without PFS */
3184 if (dpp_pfs_process(sta
->dpp_pfs
, elems
.owe_dh
,
3185 elems
.owe_dh_len
) < 0) {
3186 dpp_pfs_free(sta
->dpp_pfs
);
3187 sta
->dpp_pfs
= NULL
;
3188 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3192 wpa_auth_set_dpp_z(sta
->wpa_sm
, sta
->dpp_pfs
?
3193 sta
->dpp_pfs
->secret
: NULL
);
3195 #endif /* CONFIG_DPP2 */
3197 #ifdef CONFIG_IEEE80211N
3198 if ((sta
->flags
& (WLAN_STA_HT
| WLAN_STA_VHT
)) &&
3199 wpa_auth_get_pairwise(sta
->wpa_sm
) == WPA_CIPHER_TKIP
) {
3200 hostapd_logger(hapd
, sta
->addr
,
3201 HOSTAPD_MODULE_IEEE80211
,
3203 "Station tried to use TKIP with HT "
3205 return WLAN_STATUS_CIPHER_REJECTED_PER_POLICY
;
3207 #endif /* CONFIG_IEEE80211N */
3209 } else if (hapd
->conf
->osen
) {
3210 if (elems
.osen
== NULL
) {
3212 hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
3214 "No HS 2.0 OSEN element in association request");
3215 return WLAN_STATUS_INVALID_IE
;
3218 wpa_printf(MSG_DEBUG
, "HS 2.0: OSEN association");
3219 if (sta
->wpa_sm
== NULL
)
3220 sta
->wpa_sm
= wpa_auth_sta_init(hapd
->wpa_auth
,
3222 if (sta
->wpa_sm
== NULL
) {
3223 wpa_printf(MSG_WARNING
, "Failed to initialize WPA "
3225 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3227 if (wpa_validate_osen(hapd
->wpa_auth
, sta
->wpa_sm
,
3228 elems
.osen
- 2, elems
.osen_len
+ 2) < 0)
3229 return WLAN_STATUS_INVALID_IE
;
3230 #endif /* CONFIG_HS20 */
3232 wpa_auth_sta_no_wpa(sta
->wpa_sm
);
3235 p2p_group_notif_assoc(hapd
->p2p_group
, sta
->addr
, ies
, ies_len
);
3236 #endif /* CONFIG_P2P */
3239 wpabuf_free(sta
->hs20_ie
);
3240 if (elems
.hs20
&& elems
.hs20_len
> 4) {
3243 sta
->hs20_ie
= wpabuf_alloc_copy(elems
.hs20
+ 4,
3244 elems
.hs20_len
- 4);
3245 release
= ((elems
.hs20
[4] >> 4) & 0x0f) + 1;
3246 if (release
>= 2 && !wpa_auth_uses_mfp(sta
->wpa_sm
) &&
3247 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3248 wpa_printf(MSG_DEBUG
,
3249 "HS 2.0: PMF not negotiated by release %d station "
3250 MACSTR
, release
, MAC2STR(sta
->addr
));
3251 return WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION
;
3254 sta
->hs20_ie
= NULL
;
3257 wpabuf_free(sta
->roaming_consortium
);
3258 if (elems
.roaming_cons_sel
)
3259 sta
->roaming_consortium
= wpabuf_alloc_copy(
3260 elems
.roaming_cons_sel
+ 4,
3261 elems
.roaming_cons_sel_len
- 4);
3263 sta
->roaming_consortium
= NULL
;
3264 #endif /* CONFIG_HS20 */
3267 wpabuf_free(sta
->mb_ies
);
3268 if (hapd
->iface
->fst
)
3269 sta
->mb_ies
= mb_ies_by_info(&elems
.mb_ies
);
3272 #endif /* CONFIG_FST */
3275 mbo_ap_check_sta_assoc(hapd
, sta
, &elems
);
3277 if (hapd
->conf
->mbo_enabled
&& (hapd
->conf
->wpa
& 2) &&
3278 elems
.mbo
&& sta
->cell_capa
&& !(sta
->flags
& WLAN_STA_MFP
) &&
3279 hapd
->conf
->ieee80211w
!= NO_MGMT_FRAME_PROTECTION
) {
3280 wpa_printf(MSG_INFO
,
3281 "MBO: Reject WPA2 association without PMF");
3282 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3284 #endif /* CONFIG_MBO */
3286 #if defined(CONFIG_FILS) && defined(CONFIG_OCV)
3287 if (wpa_auth_uses_ocv(sta
->wpa_sm
) &&
3288 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3289 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3290 sta
->auth_alg
== WLAN_AUTH_FILS_PK
)) {
3291 struct wpa_channel_info ci
;
3295 if (hostapd_drv_channel_info(hapd
, &ci
) != 0) {
3296 wpa_printf(MSG_WARNING
,
3297 "Failed to get channel info to validate received OCI in FILS (Re)Association Request frame");
3298 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3301 if (get_sta_tx_parameters(sta
->wpa_sm
,
3302 channel_width_to_int(ci
.chanwidth
),
3303 ci
.seg1_idx
, &tx_chanwidth
,
3305 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3307 if (ocv_verify_tx_params(elems
.oci
, elems
.oci_len
, &ci
,
3308 tx_chanwidth
, tx_seg1_idx
) != 0) {
3309 wpa_printf(MSG_WARNING
, "FILS: %s", ocv_errorstr
);
3310 return WLAN_STATUS_UNSPECIFIED_FAILURE
;
3313 #endif /* CONFIG_FILS && CONFIG_OCV */
3315 ap_copy_sta_supp_op_classes(sta
, elems
.supp_op_classes
,
3316 elems
.supp_op_classes_len
);
3318 if ((sta
->capability
& WLAN_CAPABILITY_RADIO_MEASUREMENT
) &&
3319 elems
.rrm_enabled
&&
3320 elems
.rrm_enabled_len
>= sizeof(sta
->rrm_enabled_capa
))
3321 os_memcpy(sta
->rrm_enabled_capa
, elems
.rrm_enabled
,
3322 sizeof(sta
->rrm_enabled_capa
));
3324 if (elems
.power_capab
) {
3325 sta
->min_tx_power
= elems
.power_capab
[0];
3326 sta
->max_tx_power
= elems
.power_capab
[1];
3327 sta
->power_capab
= 1;
3329 sta
->power_capab
= 0;
3332 return WLAN_STATUS_SUCCESS
;
3336 static void send_deauth(struct hostapd_data
*hapd
, const u8
*addr
,
3340 struct ieee80211_mgmt reply
;
3342 os_memset(&reply
, 0, sizeof(reply
));
3343 reply
.frame_control
=
3344 IEEE80211_FC(WLAN_FC_TYPE_MGMT
, WLAN_FC_STYPE_DEAUTH
);
3345 os_memcpy(reply
.da
, addr
, ETH_ALEN
);
3346 os_memcpy(reply
.sa
, hapd
->own_addr
, ETH_ALEN
);
3347 os_memcpy(reply
.bssid
, hapd
->own_addr
, ETH_ALEN
);
3349 send_len
= IEEE80211_HDRLEN
+ sizeof(reply
.u
.deauth
);
3350 reply
.u
.deauth
.reason_code
= host_to_le16(reason_code
);
3352 if (hostapd_drv_send_mlme(hapd
, &reply
, send_len
, 0) < 0)
3353 wpa_printf(MSG_INFO
, "Failed to send deauth: %s",
3358 static int add_associated_sta(struct hostapd_data
*hapd
,
3359 struct sta_info
*sta
, int reassoc
)
3361 struct ieee80211_ht_capabilities ht_cap
;
3362 struct ieee80211_vht_capabilities vht_cap
;
3363 struct ieee80211_he_capabilities he_cap
;
3367 * Remove the STA entry to ensure the STA PS state gets cleared and
3368 * configuration gets updated. This is relevant for cases, such as
3369 * FT-over-the-DS, where a station re-associates back to the same AP but
3370 * skips the authentication flow, or if working with a driver that
3371 * does not support full AP client state.
3373 * Skip this if the STA has already completed FT reassociation and the
3374 * TK has been configured since the TX/RX PN must not be reset to 0 for
3377 * FT-over-the-DS has a special case where the STA entry (and as such,
3378 * the TK) has not yet been configured to the driver depending on which
3379 * driver interface is used. For that case, allow add-STA operation to
3380 * be used (instead of set-STA). This is needed to allow mac80211-based
3381 * drivers to accept the STA parameter configuration. Since this is
3382 * after a new FT-over-DS exchange, a new TK has been derived, so key
3383 * reinstallation is not a concern for this case.
3385 wpa_printf(MSG_DEBUG
, "Add associated STA " MACSTR
3386 " (added_unassoc=%d auth_alg=%u ft_over_ds=%u reassoc=%d authorized=%d ft_tk=%d fils_tk=%d)",
3387 MAC2STR(sta
->addr
), sta
->added_unassoc
, sta
->auth_alg
,
3388 sta
->ft_over_ds
, reassoc
,
3389 !!(sta
->flags
& WLAN_STA_AUTHORIZED
),
3390 wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
),
3391 wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
));
3393 if (!sta
->added_unassoc
&&
3394 (!(sta
->flags
& WLAN_STA_AUTHORIZED
) ||
3395 (reassoc
&& sta
->ft_over_ds
&& sta
->auth_alg
== WLAN_AUTH_FT
) ||
3396 (!wpa_auth_sta_ft_tk_already_set(sta
->wpa_sm
) &&
3397 !wpa_auth_sta_fils_tk_already_set(sta
->wpa_sm
)))) {
3398 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3399 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DRV_STA_REMOVED
);
3402 /* Do not allow the FT-over-DS exception to be used more than
3403 * once per authentication exchange to guarantee a new TK is
3405 sta
->ft_over_ds
= 0;
3408 #ifdef CONFIG_IEEE80211N
3409 if (sta
->flags
& WLAN_STA_HT
)
3410 hostapd_get_ht_capab(hapd
, sta
->ht_capabilities
, &ht_cap
);
3411 #endif /* CONFIG_IEEE80211N */
3412 #ifdef CONFIG_IEEE80211AC
3413 if (sta
->flags
& WLAN_STA_VHT
)
3414 hostapd_get_vht_capab(hapd
, sta
->vht_capabilities
, &vht_cap
);
3415 #endif /* CONFIG_IEEE80211AC */
3416 #ifdef CONFIG_IEEE80211AX
3417 if (sta
->flags
& WLAN_STA_HE
) {
3418 hostapd_get_he_capab(hapd
, sta
->he_capab
, &he_cap
,
3421 #endif /* CONFIG_IEEE80211AX */
3424 * Add the station with forced WLAN_STA_ASSOC flag. The sta->flags
3425 * will be set when the ACK frame for the (Re)Association Response frame
3426 * is processed (TX status driver event).
3428 if (hostapd_sta_add(hapd
, sta
->addr
, sta
->aid
, sta
->capability
,
3429 sta
->supported_rates
, sta
->supported_rates_len
,
3430 sta
->listen_interval
,
3431 sta
->flags
& WLAN_STA_HT
? &ht_cap
: NULL
,
3432 sta
->flags
& WLAN_STA_VHT
? &vht_cap
: NULL
,
3433 sta
->flags
& WLAN_STA_HE
? &he_cap
: NULL
,
3434 sta
->flags
& WLAN_STA_HE
? sta
->he_capab_len
: 0,
3435 sta
->flags
| WLAN_STA_ASSOC
, sta
->qosinfo
,
3436 sta
->vht_opmode
, sta
->p2p_ie
? 1 : 0,
3438 hostapd_logger(hapd
, sta
->addr
,
3439 HOSTAPD_MODULE_IEEE80211
, HOSTAPD_LEVEL_NOTICE
,
3440 "Could not %s STA to kernel driver",
3441 set
? "set" : "add");
3443 if (sta
->added_unassoc
) {
3444 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3445 sta
->added_unassoc
= 0;
3451 sta
->added_unassoc
= 0;
3457 static u16
send_assoc_resp(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3458 const u8
*addr
, u16 status_code
, int reassoc
,
3459 const u8
*ies
, size_t ies_len
, int rssi
)
3464 struct ieee80211_mgmt
*reply
;
3466 u16 res
= WLAN_STATUS_SUCCESS
;
3468 buflen
= sizeof(struct ieee80211_mgmt
) + 1024;
3470 if (sta
&& sta
->fils_hlp_resp
)
3471 buflen
+= wpabuf_len(sta
->fils_hlp_resp
);
3474 #endif /* CONFIG_FILS */
3476 if (sta
&& (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3478 #endif /* CONFIG_OWE */
3480 if (sta
&& sta
->dpp_pfs
)
3481 buflen
+= 5 + sta
->dpp_pfs
->curve
->prime_len
;
3482 #endif /* CONFIG_DPP2 */
3483 buf
= os_zalloc(buflen
);
3485 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3488 reply
= (struct ieee80211_mgmt
*) buf
;
3489 reply
->frame_control
=
3490 IEEE80211_FC(WLAN_FC_TYPE_MGMT
,
3491 (reassoc
? WLAN_FC_STYPE_REASSOC_RESP
:
3492 WLAN_FC_STYPE_ASSOC_RESP
));
3493 os_memcpy(reply
->da
, addr
, ETH_ALEN
);
3494 os_memcpy(reply
->sa
, hapd
->own_addr
, ETH_ALEN
);
3495 os_memcpy(reply
->bssid
, hapd
->own_addr
, ETH_ALEN
);
3497 send_len
= IEEE80211_HDRLEN
;
3498 send_len
+= sizeof(reply
->u
.assoc_resp
);
3499 reply
->u
.assoc_resp
.capab_info
=
3500 host_to_le16(hostapd_own_capab_info(hapd
));
3501 reply
->u
.assoc_resp
.status_code
= host_to_le16(status_code
);
3503 reply
->u
.assoc_resp
.aid
= host_to_le16((sta
? sta
->aid
: 0) |
3505 /* Supported rates */
3506 p
= hostapd_eid_supp_rates(hapd
, reply
->u
.assoc_resp
.variable
);
3507 /* Extended supported rates */
3508 p
= hostapd_eid_ext_supp_rates(hapd
, p
);
3511 if (status_code
== WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
&&
3513 int delta
= hapd
->iconf
->rssi_reject_assoc_rssi
- rssi
;
3515 p
= hostapd_eid_mbo_rssi_assoc_rej(hapd
, p
, buf
+ buflen
- p
,
3518 #endif /* CONFIG_MBO */
3520 #ifdef CONFIG_IEEE80211R_AP
3521 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
) {
3522 /* IEEE 802.11r: Mobility Domain Information, Fast BSS
3523 * Transition Information, RSN, [RIC Response] */
3524 p
= wpa_sm_write_assoc_resp_ies(sta
->wpa_sm
, p
,
3526 sta
->auth_alg
, ies
, ies_len
);
3528 wpa_printf(MSG_DEBUG
,
3529 "FT: Failed to write AssocResp IEs");
3530 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3534 #endif /* CONFIG_IEEE80211R_AP */
3536 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3537 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3538 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3539 sta
->auth_alg
== WLAN_AUTH_FILS_PK
))
3540 p
= wpa_auth_write_assoc_resp_fils(sta
->wpa_sm
, p
,
3543 #endif /* CONFIG_FILS */
3546 if (sta
&& status_code
== WLAN_STATUS_SUCCESS
&&
3547 (hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
))
3548 p
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, p
,
3551 #endif /* CONFIG_OWE */
3553 #ifdef CONFIG_IEEE80211W
3554 if (sta
&& status_code
== WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
)
3555 p
= hostapd_eid_assoc_comeback_time(hapd
, sta
, p
);
3556 #endif /* CONFIG_IEEE80211W */
3558 #ifdef CONFIG_IEEE80211N
3559 p
= hostapd_eid_ht_capabilities(hapd
, p
);
3560 p
= hostapd_eid_ht_operation(hapd
, p
);
3561 #endif /* CONFIG_IEEE80211N */
3563 #ifdef CONFIG_IEEE80211AC
3564 if (hapd
->iconf
->ieee80211ac
&& !hapd
->conf
->disable_11ac
) {
3565 u32 nsts
= 0, sta_nsts
;
3567 if (sta
&& hapd
->conf
->use_sta_nsts
&& sta
->vht_capabilities
) {
3568 struct ieee80211_vht_capabilities
*capa
;
3570 nsts
= (hapd
->iface
->conf
->vht_capab
>>
3571 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3572 capa
= sta
->vht_capabilities
;
3573 sta_nsts
= (le_to_host32(capa
->vht_capabilities_info
) >>
3574 VHT_CAP_BEAMFORMEE_STS_OFFSET
) & 7;
3576 if (nsts
< sta_nsts
)
3581 p
= hostapd_eid_vht_capabilities(hapd
, p
, nsts
);
3582 p
= hostapd_eid_vht_operation(hapd
, p
);
3584 #endif /* CONFIG_IEEE80211AC */
3586 #ifdef CONFIG_IEEE80211AX
3587 if (hapd
->iconf
->ieee80211ax
) {
3588 p
= hostapd_eid_he_capab(hapd
, p
, IEEE80211_MODE_AP
);
3589 p
= hostapd_eid_he_operation(hapd
, p
);
3590 p
= hostapd_eid_spatial_reuse(hapd
, p
);
3591 p
= hostapd_eid_he_mu_edca_parameter_set(hapd
, p
);
3593 #endif /* CONFIG_IEEE80211AX */
3595 p
= hostapd_eid_ext_capab(hapd
, p
);
3596 p
= hostapd_eid_bss_max_idle_period(hapd
, p
);
3597 if (sta
&& sta
->qos_map_enabled
)
3598 p
= hostapd_eid_qos_map_set(hapd
, p
);
3601 if (hapd
->iface
->fst_ies
) {
3602 os_memcpy(p
, wpabuf_head(hapd
->iface
->fst_ies
),
3603 wpabuf_len(hapd
->iface
->fst_ies
));
3604 p
+= wpabuf_len(hapd
->iface
->fst_ies
);
3606 #endif /* CONFIG_FST */
3609 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_OWE
) &&
3610 sta
&& sta
->owe_ecdh
&& status_code
== WLAN_STATUS_SUCCESS
&&
3611 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_OWE
) {
3614 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3616 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3619 /* OWE Diffie-Hellman Parameter element */
3620 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3621 *p
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3622 *p
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension */
3623 WPA_PUT_LE16(p
, sta
->owe_group
);
3625 os_memcpy(p
, wpabuf_head(pub
), wpabuf_len(pub
));
3626 p
+= wpabuf_len(pub
);
3629 #endif /* CONFIG_OWE */
3632 if ((hapd
->conf
->wpa_key_mgmt
& WPA_KEY_MGMT_DPP
) &&
3633 sta
&& sta
->dpp_pfs
&& status_code
== WLAN_STATUS_SUCCESS
&&
3634 wpa_auth_sta_key_mgmt(sta
->wpa_sm
) == WPA_KEY_MGMT_DPP
) {
3635 os_memcpy(p
, wpabuf_head(sta
->dpp_pfs
->ie
),
3636 wpabuf_len(sta
->dpp_pfs
->ie
));
3637 p
+= wpabuf_len(sta
->dpp_pfs
->ie
);
3639 #endif /* CONFIG_DPP2 */
3641 #ifdef CONFIG_IEEE80211AC
3642 if (sta
&& hapd
->conf
->vendor_vht
&& (sta
->flags
& WLAN_STA_VENDOR_VHT
))
3643 p
= hostapd_eid_vendor_vht(hapd
, p
);
3644 #endif /* CONFIG_IEEE80211AC */
3646 if (sta
&& (sta
->flags
& WLAN_STA_WMM
))
3647 p
= hostapd_eid_wmm(hapd
, p
);
3651 ((sta
->flags
& WLAN_STA_WPS
) ||
3652 ((sta
->flags
& WLAN_STA_MAYBE_WPS
) && hapd
->conf
->wpa
))) {
3653 struct wpabuf
*wps
= wps_build_assoc_resp_ie();
3655 os_memcpy(p
, wpabuf_head(wps
), wpabuf_len(wps
));
3656 p
+= wpabuf_len(wps
);
3660 #endif /* CONFIG_WPS */
3662 if (sta
&& (sta
->flags
& WLAN_STA_MULTI_AP
))
3663 p
= hostapd_eid_multi_ap(hapd
, p
);
3666 if (sta
&& sta
->p2p_ie
&& hapd
->p2p_group
) {
3667 struct wpabuf
*p2p_resp_ie
;
3668 enum p2p_status_code status
;
3669 switch (status_code
) {
3670 case WLAN_STATUS_SUCCESS
:
3671 status
= P2P_SC_SUCCESS
;
3673 case WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
:
3674 status
= P2P_SC_FAIL_LIMIT_REACHED
;
3677 status
= P2P_SC_FAIL_INVALID_PARAMS
;
3680 p2p_resp_ie
= p2p_group_assoc_resp_ie(hapd
->p2p_group
, status
);
3682 os_memcpy(p
, wpabuf_head(p2p_resp_ie
),
3683 wpabuf_len(p2p_resp_ie
));
3684 p
+= wpabuf_len(p2p_resp_ie
);
3685 wpabuf_free(p2p_resp_ie
);
3688 #endif /* CONFIG_P2P */
3690 #ifdef CONFIG_P2P_MANAGER
3691 if (hapd
->conf
->p2p
& P2P_MANAGE
)
3692 p
= hostapd_eid_p2p_manage(hapd
, p
);
3693 #endif /* CONFIG_P2P_MANAGER */
3695 p
= hostapd_eid_mbo(hapd
, p
, buf
+ buflen
- p
);
3697 if (hapd
->conf
->assocresp_elements
&&
3698 (size_t) (buf
+ buflen
- p
) >=
3699 wpabuf_len(hapd
->conf
->assocresp_elements
)) {
3700 os_memcpy(p
, wpabuf_head(hapd
->conf
->assocresp_elements
),
3701 wpabuf_len(hapd
->conf
->assocresp_elements
));
3702 p
+= wpabuf_len(hapd
->conf
->assocresp_elements
);
3705 send_len
+= p
- reply
->u
.assoc_resp
.variable
;
3709 (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
3710 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
3711 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
3712 status_code
== WLAN_STATUS_SUCCESS
) {
3713 struct ieee802_11_elems elems
;
3715 if (ieee802_11_parse_elems(ies
, ies_len
, &elems
, 0) ==
3716 ParseFailed
|| !elems
.fils_session
) {
3717 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3722 *p
++ = WLAN_EID_EXTENSION
; /* Element ID */
3723 *p
++ = 1 + FILS_SESSION_LEN
; /* Length */
3724 *p
++ = WLAN_EID_EXT_FILS_SESSION
; /* Element ID Extension */
3725 os_memcpy(p
, elems
.fils_session
, FILS_SESSION_LEN
);
3726 send_len
+= 2 + 1 + FILS_SESSION_LEN
;
3728 send_len
= fils_encrypt_assoc(sta
->wpa_sm
, buf
, send_len
,
3729 buflen
, sta
->fils_hlp_resp
);
3731 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3735 #endif /* CONFIG_FILS */
3737 if (hostapd_drv_send_mlme(hapd
, reply
, send_len
, 0) < 0) {
3738 wpa_printf(MSG_INFO
, "Failed to send assoc resp: %s",
3740 res
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3750 u8
* owe_assoc_req_process(struct hostapd_data
*hapd
, struct sta_info
*sta
,
3751 const u8
*owe_dh
, u8 owe_dh_len
,
3752 u8
*owe_buf
, size_t owe_buf_len
, u16
*reason
)
3754 #ifdef CONFIG_TESTING_OPTIONS
3755 if (hapd
->conf
->own_ie_override
) {
3756 wpa_printf(MSG_DEBUG
, "OWE: Using IE override");
3757 *reason
= WLAN_STATUS_SUCCESS
;
3758 return wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3759 owe_buf_len
, NULL
, 0);
3761 #endif /* CONFIG_TESTING_OPTIONS */
3763 if (wpa_auth_sta_get_pmksa(sta
->wpa_sm
)) {
3764 wpa_printf(MSG_DEBUG
, "OWE: Using PMKSA caching");
3765 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3766 owe_buf_len
, NULL
, 0);
3767 *reason
= WLAN_STATUS_SUCCESS
;
3771 if (sta
->owe_pmk
&& sta
->external_dh_updated
) {
3772 wpa_printf(MSG_DEBUG
, "OWE: Using previously derived PMK");
3773 *reason
= WLAN_STATUS_SUCCESS
;
3777 *reason
= owe_process_assoc_req(hapd
, sta
, owe_dh
, owe_dh_len
);
3778 if (*reason
!= WLAN_STATUS_SUCCESS
)
3781 owe_buf
= wpa_auth_write_assoc_resp_owe(sta
->wpa_sm
, owe_buf
,
3782 owe_buf_len
, NULL
, 0);
3784 if (sta
->owe_ecdh
&& owe_buf
) {
3787 pub
= crypto_ecdh_get_pubkey(sta
->owe_ecdh
, 0);
3789 *reason
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3793 /* OWE Diffie-Hellman Parameter element */
3794 *owe_buf
++ = WLAN_EID_EXTENSION
; /* Element ID */
3795 *owe_buf
++ = 1 + 2 + wpabuf_len(pub
); /* Length */
3796 *owe_buf
++ = WLAN_EID_EXT_OWE_DH_PARAM
; /* Element ID Extension
3798 WPA_PUT_LE16(owe_buf
, sta
->owe_group
);
3800 os_memcpy(owe_buf
, wpabuf_head(pub
), wpabuf_len(pub
));
3801 owe_buf
+= wpabuf_len(pub
);
3807 #endif /* CONFIG_OWE */
3812 void fils_hlp_finish_assoc(struct hostapd_data
*hapd
, struct sta_info
*sta
)
3816 wpa_printf(MSG_DEBUG
, "FILS: Finish association with " MACSTR
,
3817 MAC2STR(sta
->addr
));
3818 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
3819 if (!sta
->fils_pending_assoc_req
)
3821 reply_res
= send_assoc_resp(hapd
, sta
, sta
->addr
, WLAN_STATUS_SUCCESS
,
3822 sta
->fils_pending_assoc_is_reassoc
,
3823 sta
->fils_pending_assoc_req
,
3824 sta
->fils_pending_assoc_req_len
, 0);
3825 os_free(sta
->fils_pending_assoc_req
);
3826 sta
->fils_pending_assoc_req
= NULL
;
3827 sta
->fils_pending_assoc_req_len
= 0;
3828 wpabuf_free(sta
->fils_hlp_resp
);
3829 sta
->fils_hlp_resp
= NULL
;
3830 wpabuf_free(sta
->hlp_dhcp_discover
);
3831 sta
->hlp_dhcp_discover
= NULL
;
3834 * Remove the station in case transmission of a success response fails.
3835 * At this point the station was already added associated to the driver.
3837 if (reply_res
!= WLAN_STATUS_SUCCESS
)
3838 hostapd_drv_sta_remove(hapd
, sta
->addr
);
3842 void fils_hlp_timeout(void *eloop_ctx
, void *eloop_data
)
3844 struct hostapd_data
*hapd
= eloop_ctx
;
3845 struct sta_info
*sta
= eloop_data
;
3847 wpa_printf(MSG_DEBUG
,
3848 "FILS: HLP response timeout - continue with association response for "
3849 MACSTR
, MAC2STR(sta
->addr
));
3850 if (sta
->fils_drv_assoc_finish
)
3851 hostapd_notify_assoc_fils_finish(hapd
, sta
);
3853 fils_hlp_finish_assoc(hapd
, sta
);
3856 #endif /* CONFIG_FILS */
3859 static void handle_assoc(struct hostapd_data
*hapd
,
3860 const struct ieee80211_mgmt
*mgmt
, size_t len
,
3861 int reassoc
, int rssi
)
3863 u16 capab_info
, listen_interval
, seq_ctrl
, fc
;
3864 u16 resp
= WLAN_STATUS_SUCCESS
, reply_res
;
3867 struct sta_info
*sta
;
3869 struct hostapd_sta_wpa_psk_short
*psk
= NULL
;
3870 char *identity
= NULL
;
3871 char *radius_cui
= NULL
;
3873 int delay_assoc
= 0;
3874 #endif /* CONFIG_FILS */
3876 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_req
) :
3877 sizeof(mgmt
->u
.assoc_req
))) {
3878 wpa_printf(MSG_INFO
, "handle_assoc(reassoc=%d) - too short payload (len=%lu)",
3879 reassoc
, (unsigned long) len
);
3883 #ifdef CONFIG_TESTING_OPTIONS
3885 if (hapd
->iconf
->ignore_reassoc_probability
> 0.0 &&
3886 drand48() < hapd
->iconf
->ignore_reassoc_probability
) {
3887 wpa_printf(MSG_INFO
,
3888 "TESTING: ignoring reassoc request from "
3889 MACSTR
, MAC2STR(mgmt
->sa
));
3893 if (hapd
->iconf
->ignore_assoc_probability
> 0.0 &&
3894 drand48() < hapd
->iconf
->ignore_assoc_probability
) {
3895 wpa_printf(MSG_INFO
,
3896 "TESTING: ignoring assoc request from "
3897 MACSTR
, MAC2STR(mgmt
->sa
));
3901 #endif /* CONFIG_TESTING_OPTIONS */
3903 fc
= le_to_host16(mgmt
->frame_control
);
3904 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
3907 capab_info
= le_to_host16(mgmt
->u
.reassoc_req
.capab_info
);
3908 listen_interval
= le_to_host16(
3909 mgmt
->u
.reassoc_req
.listen_interval
);
3910 wpa_printf(MSG_DEBUG
, "reassociation request: STA=" MACSTR
3911 " capab_info=0x%02x listen_interval=%d current_ap="
3912 MACSTR
" seq_ctrl=0x%x%s",
3913 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
3914 MAC2STR(mgmt
->u
.reassoc_req
.current_ap
),
3915 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
3916 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.reassoc_req
));
3917 pos
= mgmt
->u
.reassoc_req
.variable
;
3919 capab_info
= le_to_host16(mgmt
->u
.assoc_req
.capab_info
);
3920 listen_interval
= le_to_host16(
3921 mgmt
->u
.assoc_req
.listen_interval
);
3922 wpa_printf(MSG_DEBUG
, "association request: STA=" MACSTR
3923 " capab_info=0x%02x listen_interval=%d "
3925 MAC2STR(mgmt
->sa
), capab_info
, listen_interval
,
3926 seq_ctrl
, (fc
& WLAN_FC_RETRY
) ? " retry" : "");
3927 left
= len
- (IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.assoc_req
));
3928 pos
= mgmt
->u
.assoc_req
.variable
;
3931 sta
= ap_get_sta(hapd
, mgmt
->sa
);
3932 #ifdef CONFIG_IEEE80211R_AP
3933 if (sta
&& sta
->auth_alg
== WLAN_AUTH_FT
&&
3934 (sta
->flags
& WLAN_STA_AUTH
) == 0) {
3935 wpa_printf(MSG_DEBUG
, "FT: Allow STA " MACSTR
" to associate "
3936 "prior to authentication since it is using "
3937 "over-the-DS FT", MAC2STR(mgmt
->sa
));
3940 * Mark station as authenticated, to avoid adding station
3941 * entry in the driver as associated and not authenticated
3943 sta
->flags
|= WLAN_STA_AUTH
;
3945 #endif /* CONFIG_IEEE80211R_AP */
3946 if (sta
== NULL
|| (sta
->flags
& WLAN_STA_AUTH
) == 0) {
3947 if (hapd
->iface
->current_mode
&&
3948 hapd
->iface
->current_mode
->mode
==
3949 HOSTAPD_MODE_IEEE80211AD
) {
3951 u32 session_timeout
, acct_interim_interval
;
3952 struct vlan_description vlan_id
;
3954 acl_res
= ieee802_11_allowed_address(
3955 hapd
, mgmt
->sa
, (const u8
*) mgmt
, len
,
3956 &session_timeout
, &acct_interim_interval
,
3957 &vlan_id
, &psk
, &identity
, &radius_cui
, 0);
3958 if (acl_res
== HOSTAPD_ACL_REJECT
) {
3959 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
,
3960 "Ignore Association Request frame from "
3961 MACSTR
" due to ACL reject",
3963 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3966 if (acl_res
== HOSTAPD_ACL_PENDING
)
3969 /* DMG/IEEE 802.11ad does not use authentication.
3970 * Allocate sta entry upon association. */
3971 sta
= ap_sta_add(hapd
, mgmt
->sa
);
3973 hostapd_logger(hapd
, mgmt
->sa
,
3974 HOSTAPD_MODULE_IEEE80211
,
3976 "Failed to add STA");
3977 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
3981 acl_res
= ieee802_11_set_radius_info(
3982 hapd
, sta
, acl_res
, session_timeout
,
3983 acct_interim_interval
, &vlan_id
, &psk
,
3984 &identity
, &radius_cui
);
3986 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
3990 hostapd_logger(hapd
, sta
->addr
,
3991 HOSTAPD_MODULE_IEEE80211
,
3992 HOSTAPD_LEVEL_DEBUG
,
3993 "Skip authentication for DMG/IEEE 802.11ad");
3994 sta
->flags
|= WLAN_STA_AUTH
;
3995 wpa_auth_sm_event(sta
->wpa_sm
, WPA_AUTH
);
3996 sta
->auth_alg
= WLAN_AUTH_OPEN
;
3998 hostapd_logger(hapd
, mgmt
->sa
,
3999 HOSTAPD_MODULE_IEEE80211
,
4001 "Station tried to associate before authentication (aid=%d flags=0x%x)",
4002 sta
? sta
->aid
: -1,
4003 sta
? sta
->flags
: 0);
4004 send_deauth(hapd
, mgmt
->sa
,
4005 WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
);
4010 if ((fc
& WLAN_FC_RETRY
) &&
4011 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4012 sta
->last_seq_ctrl
== seq_ctrl
&&
4013 sta
->last_subtype
== (reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4014 WLAN_FC_STYPE_ASSOC_REQ
)) {
4015 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4016 HOSTAPD_LEVEL_DEBUG
,
4017 "Drop repeated association frame seq_ctrl=0x%x",
4021 sta
->last_seq_ctrl
= seq_ctrl
;
4022 sta
->last_subtype
= reassoc
? WLAN_FC_STYPE_REASSOC_REQ
:
4023 WLAN_FC_STYPE_ASSOC_REQ
;
4025 if (hapd
->tkip_countermeasures
) {
4026 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4030 if (listen_interval
> hapd
->conf
->max_listen_interval
) {
4031 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4032 HOSTAPD_LEVEL_DEBUG
,
4033 "Too large Listen Interval (%d)",
4035 resp
= WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE
;
4040 if (hapd
->conf
->mbo_enabled
&& hapd
->mbo_assoc_disallow
) {
4041 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4045 if (hapd
->iconf
->rssi_reject_assoc_rssi
&& rssi
&&
4046 rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
&&
4047 (sta
->auth_rssi
== 0 ||
4048 sta
->auth_rssi
< hapd
->iconf
->rssi_reject_assoc_rssi
)) {
4049 resp
= WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS
;
4052 #endif /* CONFIG_MBO */
4055 * sta->capability is used in check_assoc_ies() for RRM enabled
4056 * capability element.
4058 sta
->capability
= capab_info
;
4061 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4062 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4063 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4066 /* The end of the payload is encrypted. Need to decrypt it
4067 * before parsing. */
4069 tmp
= os_memdup(pos
, left
);
4071 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4075 res
= fils_decrypt_assoc(sta
->wpa_sm
, sta
->fils_session
, mgmt
,
4078 resp
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
4084 #endif /* CONFIG_FILS */
4086 /* followed by SSID and Supported rates; and HT capabilities if 802.11n
4088 resp
= check_assoc_ies(hapd
, sta
, pos
, left
, reassoc
);
4089 if (resp
!= WLAN_STATUS_SUCCESS
)
4092 if (hostapd_get_aid(hapd
, sta
) < 0) {
4093 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4094 HOSTAPD_LEVEL_INFO
, "No room for more AIDs");
4095 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4099 sta
->listen_interval
= listen_interval
;
4101 if (hapd
->iface
->current_mode
&&
4102 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
4103 sta
->flags
|= WLAN_STA_NONERP
;
4104 for (i
= 0; i
< sta
->supported_rates_len
; i
++) {
4105 if ((sta
->supported_rates
[i
] & 0x7f) > 22) {
4106 sta
->flags
&= ~WLAN_STA_NONERP
;
4110 if (sta
->flags
& WLAN_STA_NONERP
&& !sta
->nonerp_set
) {
4111 sta
->nonerp_set
= 1;
4112 hapd
->iface
->num_sta_non_erp
++;
4113 if (hapd
->iface
->num_sta_non_erp
== 1)
4114 ieee802_11_set_beacons(hapd
->iface
);
4117 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
) &&
4118 !sta
->no_short_slot_time_set
) {
4119 sta
->no_short_slot_time_set
= 1;
4120 hapd
->iface
->num_sta_no_short_slot_time
++;
4121 if (hapd
->iface
->current_mode
&&
4122 hapd
->iface
->current_mode
->mode
==
4123 HOSTAPD_MODE_IEEE80211G
&&
4124 hapd
->iface
->num_sta_no_short_slot_time
== 1)
4125 ieee802_11_set_beacons(hapd
->iface
);
4128 if (sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
4129 sta
->flags
|= WLAN_STA_SHORT_PREAMBLE
;
4131 sta
->flags
&= ~WLAN_STA_SHORT_PREAMBLE
;
4133 if (!(sta
->capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
) &&
4134 !sta
->no_short_preamble_set
) {
4135 sta
->no_short_preamble_set
= 1;
4136 hapd
->iface
->num_sta_no_short_preamble
++;
4137 if (hapd
->iface
->current_mode
&&
4138 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211G
4139 && hapd
->iface
->num_sta_no_short_preamble
== 1)
4140 ieee802_11_set_beacons(hapd
->iface
);
4143 #ifdef CONFIG_IEEE80211N
4144 update_ht_state(hapd
, sta
);
4145 #endif /* CONFIG_IEEE80211N */
4147 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4148 HOSTAPD_LEVEL_DEBUG
,
4149 "association OK (aid %d)", sta
->aid
);
4150 /* Station will be marked associated, after it acknowledges AssocResp
4152 sta
->flags
|= WLAN_STA_ASSOC_REQ_OK
;
4154 #ifdef CONFIG_IEEE80211W
4155 if ((sta
->flags
& WLAN_STA_MFP
) && sta
->sa_query_timed_out
) {
4156 wpa_printf(MSG_DEBUG
, "Allowing %sassociation after timed out "
4157 "SA Query procedure", reassoc
? "re" : "");
4158 /* TODO: Send a protected Disassociate frame to the STA using
4159 * the old key and Reason Code "Previous Authentication no
4160 * longer valid". Make sure this is only sent protected since
4161 * unprotected frame would be received by the STA that is now
4162 * trying to associate.
4165 #endif /* CONFIG_IEEE80211W */
4167 /* Make sure that the previously registered inactivity timer will not
4168 * remove the STA immediately. */
4169 sta
->timeout_next
= STA_NULLFUNC
;
4171 #ifdef CONFIG_TAXONOMY
4172 taxonomy_sta_info_assoc_req(hapd
, sta
, pos
, left
);
4173 #endif /* CONFIG_TAXONOMY */
4175 sta
->pending_wds_enable
= 0;
4178 if (sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4179 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4180 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) {
4181 if (fils_process_hlp(hapd
, sta
, pos
, left
) > 0)
4184 #endif /* CONFIG_FILS */
4188 os_free(radius_cui
);
4189 hostapd_free_psk_list(psk
);
4192 * In case of a successful response, add the station to the driver.
4193 * Otherwise, the kernel may ignore Data frames before we process the
4194 * ACK frame (TX status). In case of a failure, this station will be
4197 * Note that this is not compliant with the IEEE 802.11 standard that
4198 * states that a non-AP station should transition into the
4199 * authenticated/associated state only after the station acknowledges
4200 * the (Re)Association Response frame. However, still do this as:
4202 * 1. In case the station does not acknowledge the (Re)Association
4203 * Response frame, it will be removed.
4204 * 2. Data frames will be dropped in the kernel until the station is
4205 * set into authorized state, and there are no significant known
4206 * issues with processing other non-Data Class 3 frames during this
4209 if (resp
== WLAN_STATUS_SUCCESS
&& sta
&&
4210 add_associated_sta(hapd
, sta
, reassoc
))
4211 resp
= WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA
;
4214 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
&&
4215 eloop_is_timeout_registered(fils_hlp_timeout
, hapd
, sta
) &&
4216 sta
->fils_pending_assoc_req
) {
4217 /* Do not reschedule fils_hlp_timeout in case the station
4218 * retransmits (Re)Association Request frame while waiting for
4219 * the previously started FILS HLP wait, so that the timeout can
4220 * be determined from the first pending attempt. */
4221 wpa_printf(MSG_DEBUG
,
4222 "FILS: Continue waiting for HLP processing before sending (Re)Association Response frame to "
4223 MACSTR
, MAC2STR(sta
->addr
));
4228 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4229 os_free(sta
->fils_pending_assoc_req
);
4230 sta
->fils_pending_assoc_req
= NULL
;
4231 sta
->fils_pending_assoc_req_len
= 0;
4232 wpabuf_free(sta
->fils_hlp_resp
);
4233 sta
->fils_hlp_resp
= NULL
;
4235 if (sta
&& delay_assoc
&& resp
== WLAN_STATUS_SUCCESS
) {
4236 sta
->fils_pending_assoc_req
= tmp
;
4237 sta
->fils_pending_assoc_req_len
= left
;
4238 sta
->fils_pending_assoc_is_reassoc
= reassoc
;
4239 sta
->fils_drv_assoc_finish
= 0;
4240 wpa_printf(MSG_DEBUG
,
4241 "FILS: Waiting for HLP processing before sending (Re)Association Response frame to "
4242 MACSTR
, MAC2STR(sta
->addr
));
4243 eloop_cancel_timeout(fils_hlp_timeout
, hapd
, sta
);
4244 eloop_register_timeout(0, hapd
->conf
->fils_hlp_wait_time
* 1024,
4245 fils_hlp_timeout
, hapd
, sta
);
4248 #endif /* CONFIG_FILS */
4250 reply_res
= send_assoc_resp(hapd
, sta
, mgmt
->sa
, resp
, reassoc
, pos
,
4255 * Remove the station in case tranmission of a success response fails
4256 * (the STA was added associated to the driver) or if the station was
4257 * previously added unassociated.
4259 if (sta
&& ((reply_res
!= WLAN_STATUS_SUCCESS
&&
4260 resp
== WLAN_STATUS_SUCCESS
) || sta
->added_unassoc
)) {
4261 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4262 sta
->added_unassoc
= 0;
4267 static void handle_disassoc(struct hostapd_data
*hapd
,
4268 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4270 struct sta_info
*sta
;
4272 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.disassoc
)) {
4273 wpa_printf(MSG_INFO
, "handle_disassoc - too short payload (len=%lu)",
4274 (unsigned long) len
);
4278 wpa_printf(MSG_DEBUG
, "disassocation: STA=" MACSTR
" reason_code=%d",
4280 le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4282 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4284 wpa_printf(MSG_INFO
, "Station " MACSTR
" trying to disassociate, but it is not associated",
4289 ap_sta_set_authorized(hapd
, sta
, 0);
4290 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4291 sta
->flags
&= ~(WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
);
4292 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DISASSOC
);
4293 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4294 HOSTAPD_LEVEL_INFO
, "disassociated");
4295 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4296 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4297 /* Stop Accounting and IEEE 802.1X sessions, but leave the STA
4299 accounting_sta_stop(hapd
, sta
);
4300 ieee802_1x_free_station(hapd
, sta
);
4302 hostapd_drv_br_delete_ip_neigh(hapd
, 4, (u8
*) &sta
->ipaddr
);
4303 ap_sta_ip6addr_del(hapd
, sta
);
4304 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4305 sta
->added_unassoc
= 0;
4307 if (sta
->timeout_next
== STA_NULLFUNC
||
4308 sta
->timeout_next
== STA_DISASSOC
) {
4309 sta
->timeout_next
= STA_DEAUTH
;
4310 eloop_cancel_timeout(ap_handle_timer
, hapd
, sta
);
4311 eloop_register_timeout(AP_DEAUTH_DELAY
, 0, ap_handle_timer
,
4315 mlme_disassociate_indication(
4316 hapd
, sta
, le_to_host16(mgmt
->u
.disassoc
.reason_code
));
4318 /* DMG/IEEE 802.11ad does not use deauthication. Deallocate sta upon
4319 * disassociation. */
4320 if (hapd
->iface
->current_mode
&&
4321 hapd
->iface
->current_mode
->mode
== HOSTAPD_MODE_IEEE80211AD
) {
4322 sta
->flags
&= ~WLAN_STA_AUTH
;
4323 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4324 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4325 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4326 ap_free_sta(hapd
, sta
);
4331 static void handle_deauth(struct hostapd_data
*hapd
,
4332 const struct ieee80211_mgmt
*mgmt
, size_t len
)
4334 struct sta_info
*sta
;
4336 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.deauth
)) {
4337 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "handle_deauth - too short "
4338 "payload (len=%lu)", (unsigned long) len
);
4342 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "deauthentication: STA=" MACSTR
4344 MAC2STR(mgmt
->sa
), le_to_host16(mgmt
->u
.deauth
.reason_code
));
4346 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4348 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "Station " MACSTR
" trying "
4349 "to deauthenticate, but it is not authenticated",
4354 ap_sta_set_authorized(hapd
, sta
, 0);
4355 sta
->last_seq_ctrl
= WLAN_INVALID_MGMT_SEQ
;
4356 sta
->flags
&= ~(WLAN_STA_AUTH
| WLAN_STA_ASSOC
|
4357 WLAN_STA_ASSOC_REQ_OK
);
4358 wpa_auth_sm_event(sta
->wpa_sm
, WPA_DEAUTH
);
4359 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4360 HOSTAPD_LEVEL_DEBUG
, "deauthenticated");
4361 mlme_deauthenticate_indication(
4362 hapd
, sta
, le_to_host16(mgmt
->u
.deauth
.reason_code
));
4363 sta
->acct_terminate_cause
= RADIUS_ACCT_TERMINATE_CAUSE_USER_REQUEST
;
4364 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 0);
4365 ap_free_sta(hapd
, sta
);
4369 static void handle_beacon(struct hostapd_data
*hapd
,
4370 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4371 struct hostapd_frame_info
*fi
)
4373 struct ieee802_11_elems elems
;
4375 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.beacon
)) {
4376 wpa_printf(MSG_INFO
, "handle_beacon - too short payload (len=%lu)",
4377 (unsigned long) len
);
4381 (void) ieee802_11_parse_elems(mgmt
->u
.beacon
.variable
,
4382 len
- (IEEE80211_HDRLEN
+
4383 sizeof(mgmt
->u
.beacon
)), &elems
,
4386 ap_list_process_beacon(hapd
->iface
, mgmt
, &elems
, fi
);
4390 #ifdef CONFIG_IEEE80211W
4391 static int robust_action_frame(u8 category
)
4393 return category
!= WLAN_ACTION_PUBLIC
&&
4394 category
!= WLAN_ACTION_HT
;
4396 #endif /* CONFIG_IEEE80211W */
4399 static int handle_action(struct hostapd_data
*hapd
,
4400 const struct ieee80211_mgmt
*mgmt
, size_t len
,
4403 struct sta_info
*sta
;
4404 u8
*action __maybe_unused
;
4406 if (len
< IEEE80211_HDRLEN
+ 2 + 1) {
4407 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4408 HOSTAPD_LEVEL_DEBUG
,
4409 "handle_action - too short payload (len=%lu)",
4410 (unsigned long) len
);
4414 action
= (u8
*) &mgmt
->u
.action
.u
;
4415 wpa_printf(MSG_DEBUG
, "RX_ACTION category %u action %u sa " MACSTR
4416 " da " MACSTR
" len %d freq %u",
4417 mgmt
->u
.action
.category
, *action
,
4418 MAC2STR(mgmt
->sa
), MAC2STR(mgmt
->da
), (int) len
, freq
);
4420 sta
= ap_get_sta(hapd
, mgmt
->sa
);
4422 if (mgmt
->u
.action
.category
!= WLAN_ACTION_PUBLIC
&&
4423 (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))) {
4424 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Ignored Action "
4425 "frame (category=%u) from unassociated STA " MACSTR
,
4426 mgmt
->u
.action
.category
, MAC2STR(mgmt
->sa
));
4430 #ifdef CONFIG_IEEE80211W
4431 if (sta
&& (sta
->flags
& WLAN_STA_MFP
) &&
4432 !(mgmt
->frame_control
& host_to_le16(WLAN_FC_ISWEP
)) &&
4433 robust_action_frame(mgmt
->u
.action
.category
)) {
4434 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4435 HOSTAPD_LEVEL_DEBUG
,
4436 "Dropped unprotected Robust Action frame from "
4440 #endif /* CONFIG_IEEE80211W */
4443 u16 fc
= le_to_host16(mgmt
->frame_control
);
4444 u16 seq_ctrl
= le_to_host16(mgmt
->seq_ctrl
);
4446 if ((fc
& WLAN_FC_RETRY
) &&
4447 sta
->last_seq_ctrl
!= WLAN_INVALID_MGMT_SEQ
&&
4448 sta
->last_seq_ctrl
== seq_ctrl
&&
4449 sta
->last_subtype
== WLAN_FC_STYPE_ACTION
) {
4450 hostapd_logger(hapd
, sta
->addr
,
4451 HOSTAPD_MODULE_IEEE80211
,
4452 HOSTAPD_LEVEL_DEBUG
,
4453 "Drop repeated action frame seq_ctrl=0x%x",
4458 sta
->last_seq_ctrl
= seq_ctrl
;
4459 sta
->last_subtype
= WLAN_FC_STYPE_ACTION
;
4462 switch (mgmt
->u
.action
.category
) {
4463 #ifdef CONFIG_IEEE80211R_AP
4464 case WLAN_ACTION_FT
:
4466 wpa_ft_action_rx(sta
->wpa_sm
, (u8
*) &mgmt
->u
.action
,
4467 len
- IEEE80211_HDRLEN
))
4470 #endif /* CONFIG_IEEE80211R_AP */
4471 case WLAN_ACTION_WMM
:
4472 hostapd_wmm_action(hapd
, mgmt
, len
);
4474 #ifdef CONFIG_IEEE80211W
4475 case WLAN_ACTION_SA_QUERY
:
4476 ieee802_11_sa_query_action(hapd
, mgmt
, len
);
4478 #endif /* CONFIG_IEEE80211W */
4479 #ifdef CONFIG_WNM_AP
4480 case WLAN_ACTION_WNM
:
4481 ieee802_11_rx_wnm_action_ap(hapd
, mgmt
, len
);
4483 #endif /* CONFIG_WNM_AP */
4485 case WLAN_ACTION_FST
:
4486 if (hapd
->iface
->fst
)
4487 fst_rx_action(hapd
->iface
->fst
, mgmt
, len
);
4489 wpa_printf(MSG_DEBUG
,
4490 "FST: Ignore FST Action frame - no FST attached");
4492 #endif /* CONFIG_FST */
4493 case WLAN_ACTION_PUBLIC
:
4494 case WLAN_ACTION_PROTECTED_DUAL
:
4495 #ifdef CONFIG_IEEE80211N
4496 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4497 mgmt
->u
.action
.u
.public_action
.action
==
4498 WLAN_PA_20_40_BSS_COEX
) {
4499 hostapd_2040_coex_action(hapd
, mgmt
, len
);
4502 #endif /* CONFIG_IEEE80211N */
4504 if (len
>= IEEE80211_HDRLEN
+ 6 &&
4505 mgmt
->u
.action
.u
.vs_public_action
.action
==
4506 WLAN_PA_VENDOR_SPECIFIC
&&
4507 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
4509 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
4511 const u8
*pos
, *end
;
4513 pos
= mgmt
->u
.action
.u
.vs_public_action
.oui
;
4514 end
= ((const u8
*) mgmt
) + len
;
4515 hostapd_dpp_rx_action(hapd
, mgmt
->sa
, pos
, end
- pos
,
4519 if (len
>= IEEE80211_HDRLEN
+ 2 &&
4520 (mgmt
->u
.action
.u
.public_action
.action
==
4521 WLAN_PA_GAS_INITIAL_RESP
||
4522 mgmt
->u
.action
.u
.public_action
.action
==
4523 WLAN_PA_GAS_COMEBACK_RESP
)) {
4524 const u8
*pos
, *end
;
4526 pos
= &mgmt
->u
.action
.u
.public_action
.action
;
4527 end
= ((const u8
*) mgmt
) + len
;
4528 gas_query_ap_rx(hapd
->gas
, mgmt
->sa
,
4529 mgmt
->u
.action
.category
,
4530 pos
, end
- pos
, hapd
->iface
->freq
);
4533 #endif /* CONFIG_DPP */
4534 if (hapd
->public_action_cb
) {
4535 hapd
->public_action_cb(hapd
->public_action_cb_ctx
,
4539 if (hapd
->public_action_cb2
) {
4540 hapd
->public_action_cb2(hapd
->public_action_cb2_ctx
,
4544 if (hapd
->public_action_cb
|| hapd
->public_action_cb2
)
4547 case WLAN_ACTION_VENDOR_SPECIFIC
:
4548 if (hapd
->vendor_action_cb
) {
4549 if (hapd
->vendor_action_cb(hapd
->vendor_action_cb_ctx
,
4551 hapd
->iface
->freq
) == 0)
4555 case WLAN_ACTION_RADIO_MEASUREMENT
:
4556 hostapd_handle_radio_measurement(hapd
, (const u8
*) mgmt
, len
);
4560 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4561 HOSTAPD_LEVEL_DEBUG
,
4562 "handle_action - unknown action category %d or invalid "
4564 mgmt
->u
.action
.category
);
4565 if (!is_multicast_ether_addr(mgmt
->da
) &&
4566 !(mgmt
->u
.action
.category
& 0x80) &&
4567 !is_multicast_ether_addr(mgmt
->sa
)) {
4568 struct ieee80211_mgmt
*resp
;
4571 * IEEE 802.11-REVma/D9.0 - 7.3.1.11
4572 * Return the Action frame to the source without change
4573 * except that MSB of the Category set to 1.
4575 wpa_printf(MSG_DEBUG
, "IEEE 802.11: Return unknown Action "
4576 "frame back to sender");
4577 resp
= os_memdup(mgmt
, len
);
4580 os_memcpy(resp
->da
, resp
->sa
, ETH_ALEN
);
4581 os_memcpy(resp
->sa
, hapd
->own_addr
, ETH_ALEN
);
4582 os_memcpy(resp
->bssid
, hapd
->own_addr
, ETH_ALEN
);
4583 resp
->u
.action
.category
|= 0x80;
4585 if (hostapd_drv_send_mlme(hapd
, resp
, len
, 0) < 0) {
4586 wpa_printf(MSG_ERROR
, "IEEE 802.11: Failed to send "
4597 * ieee802_11_mgmt - process incoming IEEE 802.11 management frames
4598 * @hapd: hostapd BSS data structure (the BSS to which the management frame was
4600 * @buf: management frame data (starting from IEEE 802.11 header)
4601 * @len: length of frame data in octets
4602 * @fi: meta data about received frame (signal level, etc.)
4604 * Process all incoming IEEE 802.11 management frames. This will be called for
4605 * each frame received from the kernel driver through wlan#ap interface. In
4606 * addition, it can be called to re-inserted pending frames (e.g., when using
4607 * external RADIUS server as an MAC ACL).
4609 int ieee802_11_mgmt(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
4610 struct hostapd_frame_info
*fi
)
4612 struct ieee80211_mgmt
*mgmt
;
4616 int ssi_signal
= fi
? fi
->ssi_signal
: 0;
4624 freq
= hapd
->iface
->freq
;
4626 mgmt
= (struct ieee80211_mgmt
*) buf
;
4627 fc
= le_to_host16(mgmt
->frame_control
);
4628 stype
= WLAN_FC_GET_STYPE(fc
);
4630 if (stype
== WLAN_FC_STYPE_BEACON
) {
4631 handle_beacon(hapd
, mgmt
, len
, fi
);
4635 if (!is_broadcast_ether_addr(mgmt
->bssid
) &&
4637 /* Invitation responses can be sent with the peer MAC as BSSID */
4638 !((hapd
->conf
->p2p
& P2P_GROUP_OWNER
) &&
4639 stype
== WLAN_FC_STYPE_ACTION
) &&
4640 #endif /* CONFIG_P2P */
4642 !(hapd
->conf
->mesh
& MESH_ENABLED
) &&
4643 #endif /* CONFIG_MESH */
4644 os_memcmp(mgmt
->bssid
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4645 wpa_printf(MSG_INFO
, "MGMT: BSSID=" MACSTR
" not our address",
4646 MAC2STR(mgmt
->bssid
));
4651 if (stype
== WLAN_FC_STYPE_PROBE_REQ
) {
4652 handle_probe_req(hapd
, mgmt
, len
, ssi_signal
);
4656 if ((!is_broadcast_ether_addr(mgmt
->da
) ||
4657 stype
!= WLAN_FC_STYPE_ACTION
) &&
4658 os_memcmp(mgmt
->da
, hapd
->own_addr
, ETH_ALEN
) != 0) {
4659 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4660 HOSTAPD_LEVEL_DEBUG
,
4661 "MGMT: DA=" MACSTR
" not our address",
4666 if (hapd
->iconf
->track_sta_max_num
)
4667 sta_track_add(hapd
->iface
, mgmt
->sa
, ssi_signal
);
4670 case WLAN_FC_STYPE_AUTH
:
4671 wpa_printf(MSG_DEBUG
, "mgmt::auth");
4672 handle_auth(hapd
, mgmt
, len
, ssi_signal
, 0);
4675 case WLAN_FC_STYPE_ASSOC_REQ
:
4676 wpa_printf(MSG_DEBUG
, "mgmt::assoc_req");
4677 handle_assoc(hapd
, mgmt
, len
, 0, ssi_signal
);
4680 case WLAN_FC_STYPE_REASSOC_REQ
:
4681 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_req");
4682 handle_assoc(hapd
, mgmt
, len
, 1, ssi_signal
);
4685 case WLAN_FC_STYPE_DISASSOC
:
4686 wpa_printf(MSG_DEBUG
, "mgmt::disassoc");
4687 handle_disassoc(hapd
, mgmt
, len
);
4690 case WLAN_FC_STYPE_DEAUTH
:
4691 wpa_msg(hapd
->msg_ctx
, MSG_DEBUG
, "mgmt::deauth");
4692 handle_deauth(hapd
, mgmt
, len
);
4695 case WLAN_FC_STYPE_ACTION
:
4696 wpa_printf(MSG_DEBUG
, "mgmt::action");
4697 ret
= handle_action(hapd
, mgmt
, len
, freq
);
4700 hostapd_logger(hapd
, mgmt
->sa
, HOSTAPD_MODULE_IEEE80211
,
4701 HOSTAPD_LEVEL_DEBUG
,
4702 "unknown mgmt frame subtype %d", stype
);
4710 static void handle_auth_cb(struct hostapd_data
*hapd
,
4711 const struct ieee80211_mgmt
*mgmt
,
4714 u16 auth_alg
, auth_transaction
, status_code
;
4715 struct sta_info
*sta
;
4717 sta
= ap_get_sta(hapd
, mgmt
->da
);
4719 wpa_printf(MSG_DEBUG
, "handle_auth_cb: STA " MACSTR
4725 auth_alg
= le_to_host16(mgmt
->u
.auth
.auth_alg
);
4726 auth_transaction
= le_to_host16(mgmt
->u
.auth
.auth_transaction
);
4727 status_code
= le_to_host16(mgmt
->u
.auth
.status_code
);
4730 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4731 HOSTAPD_LEVEL_NOTICE
,
4732 "did not acknowledge authentication response");
4736 if (len
< IEEE80211_HDRLEN
+ sizeof(mgmt
->u
.auth
)) {
4737 wpa_printf(MSG_INFO
, "handle_auth_cb - too short payload (len=%lu)",
4738 (unsigned long) len
);
4742 if (status_code
== WLAN_STATUS_SUCCESS
&&
4743 ((auth_alg
== WLAN_AUTH_OPEN
&& auth_transaction
== 2) ||
4744 (auth_alg
== WLAN_AUTH_SHARED_KEY
&& auth_transaction
== 4))) {
4745 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4746 HOSTAPD_LEVEL_INFO
, "authenticated");
4747 sta
->flags
|= WLAN_STA_AUTH
;
4748 if (sta
->added_unassoc
)
4749 hostapd_set_sta_flags(hapd
, sta
);
4754 if (status_code
!= WLAN_STATUS_SUCCESS
&& sta
->added_unassoc
) {
4755 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4756 sta
->added_unassoc
= 0;
4761 static void hostapd_set_wds_encryption(struct hostapd_data
*hapd
,
4762 struct sta_info
*sta
,
4766 struct hostapd_ssid
*ssid
= &hapd
->conf
->ssid
;
4768 if (hapd
->conf
->ieee802_1x
|| hapd
->conf
->wpa
)
4771 for (i
= 0; i
< 4; i
++) {
4772 if (ssid
->wep
.key
[i
] &&
4773 hostapd_drv_set_key(ifname_wds
, hapd
, WPA_ALG_WEP
, NULL
, i
,
4774 i
== ssid
->wep
.idx
, NULL
, 0,
4775 ssid
->wep
.key
[i
], ssid
->wep
.len
[i
])) {
4776 wpa_printf(MSG_WARNING
,
4777 "Could not set WEP keys for WDS interface; %s",
4785 static void handle_assoc_cb(struct hostapd_data
*hapd
,
4786 const struct ieee80211_mgmt
*mgmt
,
4787 size_t len
, int reassoc
, int ok
)
4790 struct sta_info
*sta
;
4793 sta
= ap_get_sta(hapd
, mgmt
->da
);
4795 wpa_printf(MSG_INFO
, "handle_assoc_cb: STA " MACSTR
" not found",
4800 if (len
< IEEE80211_HDRLEN
+ (reassoc
? sizeof(mgmt
->u
.reassoc_resp
) :
4801 sizeof(mgmt
->u
.assoc_resp
))) {
4802 wpa_printf(MSG_INFO
,
4803 "handle_assoc_cb(reassoc=%d) - too short payload (len=%lu)",
4804 reassoc
, (unsigned long) len
);
4805 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4810 status
= le_to_host16(mgmt
->u
.reassoc_resp
.status_code
);
4812 status
= le_to_host16(mgmt
->u
.assoc_resp
.status_code
);
4815 hostapd_logger(hapd
, mgmt
->da
, HOSTAPD_MODULE_IEEE80211
,
4816 HOSTAPD_LEVEL_DEBUG
,
4817 "did not acknowledge association response");
4818 sta
->flags
&= ~WLAN_STA_ASSOC_REQ_OK
;
4819 /* The STA is added only in case of SUCCESS */
4820 if (status
== WLAN_STATUS_SUCCESS
)
4821 hostapd_drv_sta_remove(hapd
, sta
->addr
);
4826 if (status
!= WLAN_STATUS_SUCCESS
)
4829 /* Stop previous accounting session, if one is started, and allocate
4830 * new session id for the new session. */
4831 accounting_sta_stop(hapd
, sta
);
4833 hostapd_logger(hapd
, sta
->addr
, HOSTAPD_MODULE_IEEE80211
,
4835 "associated (aid %d)",
4838 if (sta
->flags
& WLAN_STA_ASSOC
)
4840 sta
->flags
|= WLAN_STA_ASSOC
;
4841 sta
->flags
&= ~WLAN_STA_WNM_SLEEP_MODE
;
4842 if ((!hapd
->conf
->ieee802_1x
&& !hapd
->conf
->wpa
&&
4843 !hapd
->conf
->osen
) ||
4844 sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4845 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4846 sta
->auth_alg
== WLAN_AUTH_FILS_PK
||
4847 sta
->auth_alg
== WLAN_AUTH_FT
) {
4849 * Open, static WEP, FT protocol, or FILS; no separate
4850 * authorization step.
4852 ap_sta_set_authorized(hapd
, sta
, 1);
4856 mlme_reassociate_indication(hapd
, sta
);
4858 mlme_associate_indication(hapd
, sta
);
4860 #ifdef CONFIG_IEEE80211W
4861 sta
->sa_query_timed_out
= 0;
4862 #endif /* CONFIG_IEEE80211W */
4864 if (sta
->eapol_sm
== NULL
) {
4866 * This STA does not use RADIUS server for EAP authentication,
4867 * so bind it to the selected VLAN interface now, since the
4868 * interface selection is not going to change anymore.
4870 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4872 } else if (sta
->vlan_id
) {
4873 /* VLAN ID already set (e.g., by PMKSA caching), so bind STA */
4874 if (ap_sta_bind_vlan(hapd
, sta
) < 0)
4878 hostapd_set_sta_flags(hapd
, sta
);
4880 if (!(sta
->flags
& WLAN_STA_WDS
) && sta
->pending_wds_enable
) {
4881 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for STA "
4882 MACSTR
" based on pending request",
4883 MAC2STR(sta
->addr
));
4884 sta
->pending_wds_enable
= 0;
4885 sta
->flags
|= WLAN_STA_WDS
;
4888 if (sta
->flags
& (WLAN_STA_WDS
| WLAN_STA_MULTI_AP
)) {
4890 char ifname_wds
[IFNAMSIZ
+ 1];
4892 wpa_printf(MSG_DEBUG
, "Reenable 4-address WDS mode for STA "
4894 MAC2STR(sta
->addr
), sta
->aid
);
4895 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
, sta
->addr
,
4898 hostapd_set_wds_encryption(hapd
, sta
, ifname_wds
);
4901 if (sta
->auth_alg
== WLAN_AUTH_FT
)
4902 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC_FT
);
4904 wpa_auth_sm_event(sta
->wpa_sm
, WPA_ASSOC
);
4905 hapd
->new_assoc_sta_cb(hapd
, sta
, !new_assoc
);
4906 ieee802_1x_notify_port_enabled(sta
->eapol_sm
, 1);
4909 if ((sta
->auth_alg
== WLAN_AUTH_FILS_SK
||
4910 sta
->auth_alg
== WLAN_AUTH_FILS_SK_PFS
||
4911 sta
->auth_alg
== WLAN_AUTH_FILS_PK
) &&
4912 fils_set_tk(sta
->wpa_sm
) < 0) {
4913 wpa_printf(MSG_DEBUG
, "FILS: TK configuration failed");
4914 ap_sta_disconnect(hapd
, sta
, sta
->addr
,
4915 WLAN_REASON_UNSPECIFIED
);
4918 #endif /* CONFIG_FILS */
4920 if (sta
->pending_eapol_rx
) {
4921 struct os_reltime now
, age
;
4923 os_get_reltime(&now
);
4924 os_reltime_sub(&now
, &sta
->pending_eapol_rx
->rx_time
, &age
);
4925 if (age
.sec
== 0 && age
.usec
< 200000) {
4926 wpa_printf(MSG_DEBUG
,
4927 "Process pending EAPOL frame that was received from " MACSTR
" just before association notification",
4928 MAC2STR(sta
->addr
));
4931 wpabuf_head(sta
->pending_eapol_rx
->buf
),
4932 wpabuf_len(sta
->pending_eapol_rx
->buf
));
4934 wpabuf_free(sta
->pending_eapol_rx
->buf
);
4935 os_free(sta
->pending_eapol_rx
);
4936 sta
->pending_eapol_rx
= NULL
;
4941 static void handle_deauth_cb(struct hostapd_data
*hapd
,
4942 const struct ieee80211_mgmt
*mgmt
,
4945 struct sta_info
*sta
;
4946 if (is_multicast_ether_addr(mgmt
->da
))
4948 sta
= ap_get_sta(hapd
, mgmt
->da
);
4950 wpa_printf(MSG_DEBUG
, "handle_deauth_cb: STA " MACSTR
4951 " not found", MAC2STR(mgmt
->da
));
4955 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged deauth",
4956 MAC2STR(sta
->addr
));
4958 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
4959 "deauth", MAC2STR(sta
->addr
));
4961 ap_sta_deauth_cb(hapd
, sta
);
4965 static void handle_disassoc_cb(struct hostapd_data
*hapd
,
4966 const struct ieee80211_mgmt
*mgmt
,
4969 struct sta_info
*sta
;
4970 if (is_multicast_ether_addr(mgmt
->da
))
4972 sta
= ap_get_sta(hapd
, mgmt
->da
);
4974 wpa_printf(MSG_DEBUG
, "handle_disassoc_cb: STA " MACSTR
4975 " not found", MAC2STR(mgmt
->da
));
4979 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" acknowledged disassoc",
4980 MAC2STR(sta
->addr
));
4982 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" did not acknowledge "
4983 "disassoc", MAC2STR(sta
->addr
));
4985 ap_sta_disassoc_cb(hapd
, sta
);
4989 static void handle_action_cb(struct hostapd_data
*hapd
,
4990 const struct ieee80211_mgmt
*mgmt
,
4993 struct sta_info
*sta
;
4994 const struct rrm_measurement_report_element
*report
;
4996 if (is_multicast_ether_addr(mgmt
->da
))
4999 if (len
>= IEEE80211_HDRLEN
+ 6 &&
5000 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5001 mgmt
->u
.action
.u
.vs_public_action
.action
==
5002 WLAN_PA_VENDOR_SPECIFIC
&&
5003 WPA_GET_BE24(mgmt
->u
.action
.u
.vs_public_action
.oui
) ==
5005 mgmt
->u
.action
.u
.vs_public_action
.variable
[0] ==
5007 const u8
*pos
, *end
;
5009 pos
= &mgmt
->u
.action
.u
.vs_public_action
.variable
[1];
5010 end
= ((const u8
*) mgmt
) + len
;
5011 hostapd_dpp_tx_status(hapd
, mgmt
->da
, pos
, end
- pos
, ok
);
5014 if (len
>= IEEE80211_HDRLEN
+ 2 &&
5015 mgmt
->u
.action
.category
== WLAN_ACTION_PUBLIC
&&
5016 (mgmt
->u
.action
.u
.public_action
.action
==
5017 WLAN_PA_GAS_INITIAL_REQ
||
5018 mgmt
->u
.action
.u
.public_action
.action
==
5019 WLAN_PA_GAS_COMEBACK_REQ
)) {
5020 const u8
*pos
, *end
;
5022 pos
= mgmt
->u
.action
.u
.public_action
.variable
;
5023 end
= ((const u8
*) mgmt
) + len
;
5024 gas_query_ap_tx_status(hapd
->gas
, mgmt
->da
, pos
, end
- pos
, ok
);
5027 #endif /* CONFIG_DPP */
5028 sta
= ap_get_sta(hapd
, mgmt
->da
);
5030 wpa_printf(MSG_DEBUG
, "handle_action_cb: STA " MACSTR
5031 " not found", MAC2STR(mgmt
->da
));
5035 if (len
< 24 + 5 + sizeof(*report
))
5037 report
= (const struct rrm_measurement_report_element
*)
5038 &mgmt
->u
.action
.u
.rrm
.variable
[2];
5039 if (mgmt
->u
.action
.category
== WLAN_ACTION_RADIO_MEASUREMENT
&&
5040 mgmt
->u
.action
.u
.rrm
.action
== WLAN_RRM_RADIO_MEASUREMENT_REQUEST
&&
5041 report
->eid
== WLAN_EID_MEASURE_REQUEST
&&
5043 report
->type
== MEASURE_TYPE_BEACON
)
5044 hostapd_rrm_beacon_req_tx_status(hapd
, mgmt
, len
, ok
);
5049 * ieee802_11_mgmt_cb - Process management frame TX status callback
5050 * @hapd: hostapd BSS data structure (the BSS from which the management frame
5052 * @buf: management frame data (starting from IEEE 802.11 header)
5053 * @len: length of frame data in octets
5054 * @stype: management frame subtype from frame control field
5055 * @ok: Whether the frame was ACK'ed
5057 void ieee802_11_mgmt_cb(struct hostapd_data
*hapd
, const u8
*buf
, size_t len
,
5060 const struct ieee80211_mgmt
*mgmt
;
5061 mgmt
= (const struct ieee80211_mgmt
*) buf
;
5063 #ifdef CONFIG_TESTING_OPTIONS
5064 if (hapd
->ext_mgmt_frame_handling
) {
5065 size_t hex_len
= 2 * len
+ 1;
5066 char *hex
= os_malloc(hex_len
);
5069 wpa_snprintf_hex(hex
, hex_len
, buf
, len
);
5070 wpa_msg(hapd
->msg_ctx
, MSG_INFO
,
5071 "MGMT-TX-STATUS stype=%u ok=%d buf=%s",
5077 #endif /* CONFIG_TESTING_OPTIONS */
5080 case WLAN_FC_STYPE_AUTH
:
5081 wpa_printf(MSG_DEBUG
, "mgmt::auth cb");
5082 handle_auth_cb(hapd
, mgmt
, len
, ok
);
5084 case WLAN_FC_STYPE_ASSOC_RESP
:
5085 wpa_printf(MSG_DEBUG
, "mgmt::assoc_resp cb");
5086 handle_assoc_cb(hapd
, mgmt
, len
, 0, ok
);
5088 case WLAN_FC_STYPE_REASSOC_RESP
:
5089 wpa_printf(MSG_DEBUG
, "mgmt::reassoc_resp cb");
5090 handle_assoc_cb(hapd
, mgmt
, len
, 1, ok
);
5092 case WLAN_FC_STYPE_PROBE_RESP
:
5093 wpa_printf(MSG_EXCESSIVE
, "mgmt::proberesp cb ok=%d", ok
);
5095 case WLAN_FC_STYPE_DEAUTH
:
5096 wpa_printf(MSG_DEBUG
, "mgmt::deauth cb");
5097 handle_deauth_cb(hapd
, mgmt
, len
, ok
);
5099 case WLAN_FC_STYPE_DISASSOC
:
5100 wpa_printf(MSG_DEBUG
, "mgmt::disassoc cb");
5101 handle_disassoc_cb(hapd
, mgmt
, len
, ok
);
5103 case WLAN_FC_STYPE_ACTION
:
5104 wpa_printf(MSG_DEBUG
, "mgmt::action cb ok=%d", ok
);
5105 handle_action_cb(hapd
, mgmt
, len
, ok
);
5108 wpa_printf(MSG_INFO
, "unknown mgmt cb frame subtype %d", stype
);
5114 int ieee802_11_get_mib(struct hostapd_data
*hapd
, char *buf
, size_t buflen
)
5121 int ieee802_11_get_mib_sta(struct hostapd_data
*hapd
, struct sta_info
*sta
,
5122 char *buf
, size_t buflen
)
5129 void hostapd_tx_status(struct hostapd_data
*hapd
, const u8
*addr
,
5130 const u8
*buf
, size_t len
, int ack
)
5132 struct sta_info
*sta
;
5133 struct hostapd_iface
*iface
= hapd
->iface
;
5135 sta
= ap_get_sta(hapd
, addr
);
5136 if (sta
== NULL
&& iface
->num_bss
> 1) {
5138 for (j
= 0; j
< iface
->num_bss
; j
++) {
5139 hapd
= iface
->bss
[j
];
5140 sta
= ap_get_sta(hapd
, addr
);
5145 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
))
5147 if (sta
->flags
& WLAN_STA_PENDING_POLL
) {
5148 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" %s pending "
5149 "activity poll", MAC2STR(sta
->addr
),
5150 ack
? "ACKed" : "did not ACK");
5152 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5155 ieee802_1x_tx_status(hapd
, sta
, buf
, len
, ack
);
5159 void hostapd_eapol_tx_status(struct hostapd_data
*hapd
, const u8
*dst
,
5160 const u8
*data
, size_t len
, int ack
)
5162 struct sta_info
*sta
;
5163 struct hostapd_iface
*iface
= hapd
->iface
;
5165 sta
= ap_get_sta(hapd
, dst
);
5166 if (sta
== NULL
&& iface
->num_bss
> 1) {
5168 for (j
= 0; j
< iface
->num_bss
; j
++) {
5169 hapd
= iface
->bss
[j
];
5170 sta
= ap_get_sta(hapd
, dst
);
5175 if (sta
== NULL
|| !(sta
->flags
& WLAN_STA_ASSOC
)) {
5176 wpa_printf(MSG_DEBUG
, "Ignore TX status for Data frame to STA "
5177 MACSTR
" that is not currently associated",
5182 ieee802_1x_eapol_tx_status(hapd
, sta
, data
, len
, ack
);
5186 void hostapd_client_poll_ok(struct hostapd_data
*hapd
, const u8
*addr
)
5188 struct sta_info
*sta
;
5189 struct hostapd_iface
*iface
= hapd
->iface
;
5191 sta
= ap_get_sta(hapd
, addr
);
5192 if (sta
== NULL
&& iface
->num_bss
> 1) {
5194 for (j
= 0; j
< iface
->num_bss
; j
++) {
5195 hapd
= iface
->bss
[j
];
5196 sta
= ap_get_sta(hapd
, addr
);
5203 wpa_msg(hapd
->msg_ctx
, MSG_INFO
, AP_STA_POLL_OK MACSTR
,
5204 MAC2STR(sta
->addr
));
5205 if (!(sta
->flags
& WLAN_STA_PENDING_POLL
))
5208 wpa_printf(MSG_DEBUG
, "STA " MACSTR
" ACKed pending "
5209 "activity poll", MAC2STR(sta
->addr
));
5210 sta
->flags
&= ~WLAN_STA_PENDING_POLL
;
5214 void ieee802_11_rx_from_unknown(struct hostapd_data
*hapd
, const u8
*src
,
5217 struct sta_info
*sta
;
5219 sta
= ap_get_sta(hapd
, src
);
5221 ((sta
->flags
& WLAN_STA_ASSOC
) ||
5222 ((sta
->flags
& WLAN_STA_ASSOC_REQ_OK
) && wds
))) {
5223 if (!hapd
->conf
->wds_sta
)
5226 if ((sta
->flags
& (WLAN_STA_ASSOC
| WLAN_STA_ASSOC_REQ_OK
)) ==
5227 WLAN_STA_ASSOC_REQ_OK
) {
5228 wpa_printf(MSG_DEBUG
,
5229 "Postpone 4-address WDS mode enabling for STA "
5230 MACSTR
" since TX status for AssocResp is not yet known",
5231 MAC2STR(sta
->addr
));
5232 sta
->pending_wds_enable
= 1;
5236 if (wds
&& !(sta
->flags
& WLAN_STA_WDS
)) {
5238 char ifname_wds
[IFNAMSIZ
+ 1];
5240 wpa_printf(MSG_DEBUG
, "Enable 4-address WDS mode for "
5241 "STA " MACSTR
" (aid %u)",
5242 MAC2STR(sta
->addr
), sta
->aid
);
5243 sta
->flags
|= WLAN_STA_WDS
;
5244 ret
= hostapd_set_wds_sta(hapd
, ifname_wds
,
5245 sta
->addr
, sta
->aid
, 1);
5247 hostapd_set_wds_encryption(hapd
, sta
,
5253 wpa_printf(MSG_DEBUG
, "Data/PS-poll frame from not associated STA "
5254 MACSTR
, MAC2STR(src
));
5255 if (is_multicast_ether_addr(src
)) {
5256 /* Broadcast bit set in SA?! Ignore the frame silently. */
5260 if (sta
&& (sta
->flags
& WLAN_STA_ASSOC_REQ_OK
)) {
5261 wpa_printf(MSG_DEBUG
, "Association Response to the STA has "
5262 "already been sent, but no TX status yet known - "
5263 "ignore Class 3 frame issue with " MACSTR
,
5268 if (sta
&& (sta
->flags
& WLAN_STA_AUTH
))
5269 hostapd_drv_sta_disassoc(
5271 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5273 hostapd_drv_sta_deauth(
5275 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
5279 #endif /* CONFIG_NATIVE_WINDOWS */