3 * Copyright (c) 2009-2014, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
12 #include "utils/eloop.h"
13 #include "common/ieee802_11_defs.h"
14 #include "common/ieee802_11_common.h"
15 #include "eapol_supp/eapol_supp_sm.h"
16 #include "common/wpa_common.h"
17 #include "common/sae.h"
18 #include "rsn_supp/wpa.h"
19 #include "rsn_supp/pmksa_cache.h"
21 #include "wpa_supplicant_i.h"
23 #include "wpas_glue.h"
24 #include "wps_supplicant.h"
25 #include "p2p_supplicant.h"
30 #include "hs20_supplicant.h"
32 #define SME_AUTH_TIMEOUT 5
33 #define SME_ASSOC_TIMEOUT 5
35 static void sme_auth_timer(void *eloop_ctx
, void *timeout_ctx
);
36 static void sme_assoc_timer(void *eloop_ctx
, void *timeout_ctx
);
37 static void sme_obss_scan_timeout(void *eloop_ctx
, void *timeout_ctx
);
38 #ifdef CONFIG_IEEE80211W
39 static void sme_stop_sa_query(struct wpa_supplicant
*wpa_s
);
40 #endif /* CONFIG_IEEE80211W */
45 static int index_within_array(const int *array
, int idx
)
48 for (i
= 0; i
< idx
; i
++) {
56 static int sme_set_sae_group(struct wpa_supplicant
*wpa_s
)
58 int *groups
= wpa_s
->conf
->sae_groups
;
59 int default_groups
[] = { 19, 20, 21, 25, 26, 0 };
61 if (!groups
|| groups
[0] <= 0)
62 groups
= default_groups
;
64 /* Configuration may have changed, so validate current index */
65 if (!index_within_array(groups
, wpa_s
->sme
.sae_group_index
))
69 int group
= groups
[wpa_s
->sme
.sae_group_index
];
72 if (sae_set_group(&wpa_s
->sme
.sae
, group
) == 0) {
73 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Selected SAE group %d",
74 wpa_s
->sme
.sae
.group
);
77 wpa_s
->sme
.sae_group_index
++;
84 static struct wpabuf
* sme_auth_build_sae_commit(struct wpa_supplicant
*wpa_s
,
85 struct wpa_ssid
*ssid
,
86 const u8
*bssid
, int external
)
92 #ifdef CONFIG_TESTING_OPTIONS
93 if (wpa_s
->sae_commit_override
) {
94 wpa_printf(MSG_DEBUG
, "SAE: TESTING - commit override");
95 buf
= wpabuf_alloc(4 + wpabuf_len(wpa_s
->sae_commit_override
));
98 wpabuf_put_le16(buf
, 1); /* Transaction seq# */
99 wpabuf_put_le16(buf
, WLAN_STATUS_SUCCESS
);
100 wpabuf_put_buf(buf
, wpa_s
->sae_commit_override
);
103 #endif /* CONFIG_TESTING_OPTIONS */
105 password
= ssid
->sae_password
;
107 password
= ssid
->passphrase
;
109 wpa_printf(MSG_DEBUG
, "SAE: No password available");
113 if (sme_set_sae_group(wpa_s
) < 0) {
114 wpa_printf(MSG_DEBUG
, "SAE: Failed to select group");
118 if (sae_prepare_commit(wpa_s
->own_addr
, bssid
,
119 (u8
*) password
, os_strlen(password
),
120 &wpa_s
->sme
.sae
) < 0) {
121 wpa_printf(MSG_DEBUG
, "SAE: Could not pick PWE");
125 len
= wpa_s
->sme
.sae_token
? wpabuf_len(wpa_s
->sme
.sae_token
) : 0;
126 buf
= wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN
+ len
);
130 wpabuf_put_le16(buf
, 1); /* Transaction seq# */
131 wpabuf_put_le16(buf
, WLAN_STATUS_SUCCESS
);
133 sae_write_commit(&wpa_s
->sme
.sae
, buf
, wpa_s
->sme
.sae_token
);
139 static struct wpabuf
* sme_auth_build_sae_confirm(struct wpa_supplicant
*wpa_s
,
144 buf
= wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN
);
149 wpabuf_put_le16(buf
, 2); /* Transaction seq# */
150 wpabuf_put_le16(buf
, WLAN_STATUS_SUCCESS
);
152 sae_write_confirm(&wpa_s
->sme
.sae
, buf
);
157 #endif /* CONFIG_SAE */
161 * sme_auth_handle_rrm - Handle RRM aspects of current authentication attempt
162 * @wpa_s: Pointer to wpa_supplicant data
163 * @bss: Pointer to the bss which is the target of authentication attempt
165 static void sme_auth_handle_rrm(struct wpa_supplicant
*wpa_s
,
168 const u8 rrm_ie_len
= 5;
172 wpa_s
->rrm
.rrm_used
= 0;
174 wpa_printf(MSG_DEBUG
,
175 "RRM: Determining whether RRM can be used - device support: 0x%x",
176 wpa_s
->drv_rrm_flags
);
178 rrm_ie
= wpa_bss_get_ie(bss
, WLAN_EID_RRM_ENABLED_CAPABILITIES
);
179 if (!rrm_ie
|| !(bss
->caps
& IEEE80211_CAP_RRM
)) {
180 wpa_printf(MSG_DEBUG
, "RRM: No RRM in network");
184 if (!((wpa_s
->drv_rrm_flags
&
185 WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES
) &&
186 (wpa_s
->drv_rrm_flags
& WPA_DRIVER_FLAGS_QUIET
)) &&
187 !(wpa_s
->drv_rrm_flags
& WPA_DRIVER_FLAGS_SUPPORT_RRM
)) {
188 wpa_printf(MSG_DEBUG
,
189 "RRM: Insufficient RRM support in driver - do not use RRM");
193 if (sizeof(wpa_s
->sme
.assoc_req_ie
) <
194 wpa_s
->sme
.assoc_req_ie_len
+ rrm_ie_len
+ 2) {
196 "RRM: Unable to use RRM, no room for RRM IE");
200 wpa_printf(MSG_DEBUG
, "RRM: Adding RRM IE to Association Request");
201 pos
= wpa_s
->sme
.assoc_req_ie
+ wpa_s
->sme
.assoc_req_ie_len
;
202 os_memset(pos
, 0, 2 + rrm_ie_len
);
203 *pos
++ = WLAN_EID_RRM_ENABLED_CAPABILITIES
;
206 /* Set supported capabilites flags */
207 if (wpa_s
->drv_rrm_flags
& WPA_DRIVER_FLAGS_TX_POWER_INSERTION
)
208 *pos
|= WLAN_RRM_CAPS_LINK_MEASUREMENT
;
210 *pos
|= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE
|
211 WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE
|
212 WLAN_RRM_CAPS_BEACON_REPORT_TABLE
;
215 pos
[1] |= WLAN_RRM_CAPS_LCI_MEASUREMENT
;
217 wpa_s
->sme
.assoc_req_ie_len
+= rrm_ie_len
+ 2;
218 wpa_s
->rrm
.rrm_used
= 1;
222 static void sme_send_authentication(struct wpa_supplicant
*wpa_s
,
223 struct wpa_bss
*bss
, struct wpa_ssid
*ssid
,
226 struct wpa_driver_auth_params params
;
227 struct wpa_ssid
*old_ssid
;
228 #ifdef CONFIG_IEEE80211R
230 #endif /* CONFIG_IEEE80211R */
231 #if defined(CONFIG_IEEE80211R) || defined(CONFIG_FILS)
233 #endif /* CONFIG_IEEE80211R || CONFIG_FILS */
234 int i
, bssid_changed
;
235 struct wpabuf
*resp
= NULL
;
241 wpa_msg(wpa_s
, MSG_ERROR
, "SME: No scan result available for "
243 wpas_connect_work_done(wpa_s
);
247 skip_auth
= wpa_s
->conf
->reassoc_same_bss_optim
&&
248 wpa_s
->reassoc_same_bss
;
249 wpa_s
->current_bss
= bss
;
251 os_memset(¶ms
, 0, sizeof(params
));
252 wpa_s
->reassociate
= 0;
254 params
.freq
= bss
->freq
;
255 params
.bssid
= bss
->bssid
;
256 params
.ssid
= bss
->ssid
;
257 params
.ssid_len
= bss
->ssid_len
;
258 params
.p2p
= ssid
->p2p_group
;
260 if (wpa_s
->sme
.ssid_len
!= params
.ssid_len
||
261 os_memcmp(wpa_s
->sme
.ssid
, params
.ssid
, params
.ssid_len
) != 0)
262 wpa_s
->sme
.prev_bssid_set
= 0;
264 wpa_s
->sme
.freq
= params
.freq
;
265 os_memcpy(wpa_s
->sme
.ssid
, params
.ssid
, params
.ssid_len
);
266 wpa_s
->sme
.ssid_len
= params
.ssid_len
;
268 params
.auth_alg
= WPA_AUTH_ALG_OPEN
;
269 #ifdef IEEE8021X_EAPOL
270 if (ssid
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_NO_WPA
) {
272 if (ssid
->non_leap
== 0)
273 params
.auth_alg
= WPA_AUTH_ALG_LEAP
;
275 params
.auth_alg
|= WPA_AUTH_ALG_LEAP
;
278 #endif /* IEEE8021X_EAPOL */
279 wpa_dbg(wpa_s
, MSG_DEBUG
, "Automatic auth_alg selection: 0x%x",
281 if (ssid
->auth_alg
) {
282 params
.auth_alg
= ssid
->auth_alg
;
283 wpa_dbg(wpa_s
, MSG_DEBUG
, "Overriding auth_alg selection: "
284 "0x%x", params
.auth_alg
);
287 wpa_s
->sme
.sae_pmksa_caching
= 0;
288 if (wpa_key_mgmt_sae(ssid
->key_mgmt
)) {
290 struct wpa_ie_data ied
;
292 rsn
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
294 wpa_dbg(wpa_s
, MSG_DEBUG
,
295 "SAE enabled, but target BSS does not advertise RSN");
296 } else if (wpa_parse_wpa_ie(rsn
, 2 + rsn
[1], &ied
) == 0 &&
297 wpa_key_mgmt_sae(ied
.key_mgmt
)) {
298 wpa_dbg(wpa_s
, MSG_DEBUG
, "Using SAE auth_alg");
299 params
.auth_alg
= WPA_AUTH_ALG_SAE
;
301 wpa_dbg(wpa_s
, MSG_DEBUG
,
302 "SAE enabled, but target BSS does not advertise SAE AKM for RSN");
305 #endif /* CONFIG_SAE */
307 for (i
= 0; i
< NUM_WEP_KEYS
; i
++) {
308 if (ssid
->wep_key_len
[i
])
309 params
.wep_key
[i
] = ssid
->wep_key
[i
];
310 params
.wep_key_len
[i
] = ssid
->wep_key_len
[i
];
312 params
.wep_tx_keyidx
= ssid
->wep_tx_keyidx
;
314 bssid_changed
= !is_zero_ether_addr(wpa_s
->bssid
);
315 os_memset(wpa_s
->bssid
, 0, ETH_ALEN
);
316 os_memcpy(wpa_s
->pending_bssid
, bss
->bssid
, ETH_ALEN
);
318 wpas_notify_bssid_changed(wpa_s
);
320 if ((wpa_bss_get_vendor_ie(bss
, WPA_IE_VENDOR_TYPE
) ||
321 wpa_bss_get_ie(bss
, WLAN_EID_RSN
)) &&
322 wpa_key_mgmt_wpa(ssid
->key_mgmt
)) {
323 int try_opportunistic
;
324 const u8
*cache_id
= NULL
;
326 try_opportunistic
= (ssid
->proactive_key_caching
< 0 ?
328 ssid
->proactive_key_caching
) &&
329 (ssid
->proto
& WPA_PROTO_RSN
);
331 if (wpa_key_mgmt_fils(ssid
->key_mgmt
))
332 cache_id
= wpa_bss_get_fils_cache_id(bss
);
333 #endif /* CONFIG_FILS */
334 if (pmksa_cache_set_current(wpa_s
->wpa
, NULL
, bss
->bssid
,
336 try_opportunistic
, cache_id
,
338 eapol_sm_notify_pmkid_attempt(wpa_s
->eapol
);
339 wpa_s
->sme
.assoc_req_ie_len
= sizeof(wpa_s
->sme
.assoc_req_ie
);
340 if (wpa_supplicant_set_suites(wpa_s
, bss
, ssid
,
341 wpa_s
->sme
.assoc_req_ie
,
342 &wpa_s
->sme
.assoc_req_ie_len
)) {
343 wpa_msg(wpa_s
, MSG_WARNING
, "SME: Failed to set WPA "
344 "key management and encryption suites");
345 wpas_connect_work_done(wpa_s
);
348 } else if ((ssid
->key_mgmt
& WPA_KEY_MGMT_IEEE8021X_NO_WPA
) &&
349 wpa_key_mgmt_wpa_ieee8021x(ssid
->key_mgmt
)) {
351 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
352 * use non-WPA since the scan results did not indicate that the
353 * AP is using WPA or WPA2.
355 wpa_supplicant_set_non_wpa_policy(wpa_s
, ssid
);
356 wpa_s
->sme
.assoc_req_ie_len
= 0;
357 } else if (wpa_key_mgmt_wpa_any(ssid
->key_mgmt
)) {
358 wpa_s
->sme
.assoc_req_ie_len
= sizeof(wpa_s
->sme
.assoc_req_ie
);
359 if (wpa_supplicant_set_suites(wpa_s
, NULL
, ssid
,
360 wpa_s
->sme
.assoc_req_ie
,
361 &wpa_s
->sme
.assoc_req_ie_len
)) {
362 wpa_msg(wpa_s
, MSG_WARNING
, "SME: Failed to set WPA "
363 "key management and encryption suites (no "
365 wpas_connect_work_done(wpa_s
);
369 } else if (ssid
->key_mgmt
& WPA_KEY_MGMT_WPS
) {
370 struct wpabuf
*wps_ie
;
371 wps_ie
= wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid
));
372 if (wps_ie
&& wpabuf_len(wps_ie
) <=
373 sizeof(wpa_s
->sme
.assoc_req_ie
)) {
374 wpa_s
->sme
.assoc_req_ie_len
= wpabuf_len(wps_ie
);
375 os_memcpy(wpa_s
->sme
.assoc_req_ie
, wpabuf_head(wps_ie
),
376 wpa_s
->sme
.assoc_req_ie_len
);
378 wpa_s
->sme
.assoc_req_ie_len
= 0;
380 wpa_supplicant_set_non_wpa_policy(wpa_s
, ssid
);
381 #endif /* CONFIG_WPS */
383 wpa_supplicant_set_non_wpa_policy(wpa_s
, ssid
);
384 wpa_s
->sme
.assoc_req_ie_len
= 0;
387 #ifdef CONFIG_IEEE80211R
388 ie
= wpa_bss_get_ie(bss
, WLAN_EID_MOBILITY_DOMAIN
);
389 if (ie
&& ie
[1] >= MOBILITY_DOMAIN_ID_LEN
)
391 wpa_sm_set_ft_params(wpa_s
->wpa
, ie
, ie
? 2 + ie
[1] : 0);
393 /* Prepare for the next transition */
394 wpa_ft_prepare_auth_request(wpa_s
->wpa
, ie
);
397 if (md
&& !wpa_key_mgmt_ft(ssid
->key_mgmt
))
400 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: FT mobility domain %02x%02x",
403 if (wpa_s
->sme
.assoc_req_ie_len
+ 5 <
404 sizeof(wpa_s
->sme
.assoc_req_ie
)) {
405 struct rsn_mdie
*mdie
;
406 u8
*pos
= wpa_s
->sme
.assoc_req_ie
+
407 wpa_s
->sme
.assoc_req_ie_len
;
408 *pos
++ = WLAN_EID_MOBILITY_DOMAIN
;
409 *pos
++ = sizeof(*mdie
);
410 mdie
= (struct rsn_mdie
*) pos
;
411 os_memcpy(mdie
->mobility_domain
, md
,
412 MOBILITY_DOMAIN_ID_LEN
);
413 mdie
->ft_capab
= md
[MOBILITY_DOMAIN_ID_LEN
];
414 wpa_s
->sme
.assoc_req_ie_len
+= 5;
417 if (wpa_s
->sme
.ft_used
&&
418 os_memcmp(md
, wpa_s
->sme
.mobility_domain
, 2) == 0 &&
419 wpa_sm_has_ptk(wpa_s
->wpa
)) {
420 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Trying to use FT "
422 params
.auth_alg
= WPA_AUTH_ALG_FT
;
423 params
.ie
= wpa_s
->sme
.ft_ies
;
424 params
.ie_len
= wpa_s
->sme
.ft_ies_len
;
427 #endif /* CONFIG_IEEE80211R */
429 #ifdef CONFIG_IEEE80211W
430 wpa_s
->sme
.mfp
= wpas_get_ssid_pmf(wpa_s
, ssid
);
431 if (wpa_s
->sme
.mfp
!= NO_MGMT_FRAME_PROTECTION
) {
432 const u8
*rsn
= wpa_bss_get_ie(bss
, WLAN_EID_RSN
);
433 struct wpa_ie_data _ie
;
434 if (rsn
&& wpa_parse_wpa_ie(rsn
, 2 + rsn
[1], &_ie
) == 0 &&
436 (WPA_CAPABILITY_MFPC
| WPA_CAPABILITY_MFPR
)) {
437 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Selected AP supports "
439 wpa_s
->sme
.mfp
= MGMT_FRAME_PROTECTION_REQUIRED
;
442 #endif /* CONFIG_IEEE80211W */
445 if (wpa_s
->global
->p2p
) {
449 pos
= wpa_s
->sme
.assoc_req_ie
+ wpa_s
->sme
.assoc_req_ie_len
;
450 len
= sizeof(wpa_s
->sme
.assoc_req_ie
) -
451 wpa_s
->sme
.assoc_req_ie_len
;
452 res
= wpas_p2p_assoc_req_ie(wpa_s
, bss
, pos
, len
,
455 wpa_s
->sme
.assoc_req_ie_len
+= res
;
457 #endif /* CONFIG_P2P */
460 if (wpa_s
->fst_ies
) {
461 int fst_ies_len
= wpabuf_len(wpa_s
->fst_ies
);
463 if (wpa_s
->sme
.assoc_req_ie_len
+ fst_ies_len
<=
464 sizeof(wpa_s
->sme
.assoc_req_ie
)) {
465 os_memcpy(wpa_s
->sme
.assoc_req_ie
+
466 wpa_s
->sme
.assoc_req_ie_len
,
467 wpabuf_head(wpa_s
->fst_ies
),
469 wpa_s
->sme
.assoc_req_ie_len
+= fst_ies_len
;
472 #endif /* CONFIG_FST */
474 sme_auth_handle_rrm(wpa_s
, bss
);
476 wpa_s
->sme
.assoc_req_ie_len
+= wpas_supp_op_class_ie(
478 wpa_s
->sme
.assoc_req_ie
+ wpa_s
->sme
.assoc_req_ie_len
,
479 sizeof(wpa_s
->sme
.assoc_req_ie
) - wpa_s
->sme
.assoc_req_ie_len
);
482 wpa_drv_get_ext_capa(wpa_s
, WPA_IF_P2P_CLIENT
);
484 wpa_drv_get_ext_capa(wpa_s
, WPA_IF_STATION
);
486 ext_capab_len
= wpas_build_ext_capab(wpa_s
, ext_capab
,
488 if (ext_capab_len
> 0) {
489 u8
*pos
= wpa_s
->sme
.assoc_req_ie
;
490 if (wpa_s
->sme
.assoc_req_ie_len
> 0 && pos
[0] == WLAN_EID_RSN
)
492 os_memmove(pos
+ ext_capab_len
, pos
,
493 wpa_s
->sme
.assoc_req_ie_len
-
494 (pos
- wpa_s
->sme
.assoc_req_ie
));
495 wpa_s
->sme
.assoc_req_ie_len
+= ext_capab_len
;
496 os_memcpy(pos
, ext_capab
, ext_capab_len
);
500 if (is_hs20_network(wpa_s
, ssid
, bss
)) {
503 hs20
= wpabuf_alloc(20 + MAX_ROAMING_CONS_OI_LEN
);
505 int pps_mo_id
= hs20_get_pps_mo_id(wpa_s
, ssid
);
508 wpas_hs20_add_indication(hs20
, pps_mo_id
);
509 wpas_hs20_add_roam_cons_sel(hs20
, ssid
);
510 len
= sizeof(wpa_s
->sme
.assoc_req_ie
) -
511 wpa_s
->sme
.assoc_req_ie_len
;
512 if (wpabuf_len(hs20
) <= len
) {
513 os_memcpy(wpa_s
->sme
.assoc_req_ie
+
514 wpa_s
->sme
.assoc_req_ie_len
,
515 wpabuf_head(hs20
), wpabuf_len(hs20
));
516 wpa_s
->sme
.assoc_req_ie_len
+= wpabuf_len(hs20
);
521 #endif /* CONFIG_HS20 */
523 if (wpa_s
->vendor_elem
[VENDOR_ELEM_ASSOC_REQ
]) {
524 struct wpabuf
*buf
= wpa_s
->vendor_elem
[VENDOR_ELEM_ASSOC_REQ
];
527 len
= sizeof(wpa_s
->sme
.assoc_req_ie
) -
528 wpa_s
->sme
.assoc_req_ie_len
;
529 if (wpabuf_len(buf
) <= len
) {
530 os_memcpy(wpa_s
->sme
.assoc_req_ie
+
531 wpa_s
->sme
.assoc_req_ie_len
,
532 wpabuf_head(buf
), wpabuf_len(buf
));
533 wpa_s
->sme
.assoc_req_ie_len
+= wpabuf_len(buf
);
538 if (wpa_bss_get_vendor_ie(bss
, MBO_IE_VENDOR_TYPE
)) {
541 len
= wpas_mbo_ie(wpa_s
, wpa_s
->sme
.assoc_req_ie
+
542 wpa_s
->sme
.assoc_req_ie_len
,
543 sizeof(wpa_s
->sme
.assoc_req_ie
) -
544 wpa_s
->sme
.assoc_req_ie_len
);
546 wpa_s
->sme
.assoc_req_ie_len
+= len
;
548 #endif /* CONFIG_MBO */
551 if (!skip_auth
&& params
.auth_alg
== WPA_AUTH_ALG_SAE
&&
552 pmksa_cache_set_current(wpa_s
->wpa
, NULL
, bss
->bssid
, ssid
, 0,
553 NULL
, WPA_KEY_MGMT_SAE
) == 0) {
554 wpa_dbg(wpa_s
, MSG_DEBUG
,
555 "PMKSA cache entry found - try to use PMKSA caching instead of new SAE authentication");
556 wpa_sm_set_pmk_from_pmksa(wpa_s
->wpa
);
557 params
.auth_alg
= WPA_AUTH_ALG_OPEN
;
558 wpa_s
->sme
.sae_pmksa_caching
= 1;
561 if (!skip_auth
&& params
.auth_alg
== WPA_AUTH_ALG_SAE
) {
563 resp
= sme_auth_build_sae_commit(wpa_s
, ssid
,
566 resp
= sme_auth_build_sae_confirm(wpa_s
, 0);
568 wpas_connection_failed(wpa_s
, bss
->bssid
);
571 params
.auth_data
= wpabuf_head(resp
);
572 params
.auth_data_len
= wpabuf_len(resp
);
573 wpa_s
->sme
.sae
.state
= start
? SAE_COMMITTED
: SAE_CONFIRMED
;
575 #endif /* CONFIG_SAE */
577 old_ssid
= wpa_s
->current_ssid
;
578 wpa_s
->current_ssid
= ssid
;
579 wpa_supplicant_rsn_supp_set_config(wpa_s
, wpa_s
->current_ssid
);
580 wpa_supplicant_initiate_eapol(wpa_s
);
583 /* TODO: FILS operations can in some cases be done between different
584 * network_ctx (i.e., same credentials can be used with multiple
586 if (params
.auth_alg
== WPA_AUTH_ALG_OPEN
&&
587 wpa_key_mgmt_fils(ssid
->key_mgmt
)) {
592 * Check FILS Indication element (FILS Information field) bits
593 * indicating supported authentication algorithms against local
594 * configuration (ssid->fils_dh_group). Try to use FILS
595 * authentication only if the AP supports the combination in the
596 * network profile. */
597 indic
= wpa_bss_get_ie(bss
, WLAN_EID_FILS_INDICATION
);
598 if (!indic
|| indic
[1] < 2) {
599 wpa_printf(MSG_DEBUG
, "SME: " MACSTR
600 " does not include FILS Indication element - cannot use FILS authentication with it",
601 MAC2STR(bss
->bssid
));
605 fils_info
= WPA_GET_LE16(indic
+ 2);
606 if (ssid
->fils_dh_group
== 0 && !(fils_info
& BIT(9))) {
607 wpa_printf(MSG_DEBUG
, "SME: " MACSTR
608 " does not support FILS SK without PFS - cannot use FILS authentication with it",
609 MAC2STR(bss
->bssid
));
612 if (ssid
->fils_dh_group
!= 0 && !(fils_info
& BIT(10))) {
613 wpa_printf(MSG_DEBUG
, "SME: " MACSTR
614 " does not support FILS SK with PFS - cannot use FILS authentication with it",
615 MAC2STR(bss
->bssid
));
619 if (pmksa_cache_set_current(wpa_s
->wpa
, NULL
, bss
->bssid
,
621 wpa_bss_get_fils_cache_id(bss
),
623 wpa_printf(MSG_DEBUG
,
624 "SME: Try to use FILS with PMKSA caching");
625 resp
= fils_build_auth(wpa_s
->wpa
, ssid
->fils_dh_group
, md
);
629 if (ssid
->fils_dh_group
)
630 wpa_printf(MSG_DEBUG
,
631 "SME: Try to use FILS SK authentication with PFS (DH Group %u)",
632 ssid
->fils_dh_group
);
634 wpa_printf(MSG_DEBUG
,
635 "SME: Try to use FILS SK authentication without PFS");
636 auth_alg
= ssid
->fils_dh_group
?
637 WPA_AUTH_ALG_FILS_SK_PFS
: WPA_AUTH_ALG_FILS
;
638 params
.auth_alg
= auth_alg
;
639 params
.auth_data
= wpabuf_head(resp
);
640 params
.auth_data_len
= wpabuf_len(resp
);
641 wpa_s
->sme
.auth_alg
= auth_alg
;
645 #endif /* CONFIG_FILS */
647 wpa_supplicant_cancel_sched_scan(wpa_s
);
648 wpa_supplicant_cancel_scan(wpa_s
);
650 wpa_msg(wpa_s
, MSG_INFO
, "SME: Trying to authenticate with " MACSTR
651 " (SSID='%s' freq=%d MHz)", MAC2STR(params
.bssid
),
652 wpa_ssid_txt(params
.ssid
, params
.ssid_len
), params
.freq
);
654 eapol_sm_notify_portValid(wpa_s
->eapol
, FALSE
);
655 wpa_clear_keys(wpa_s
, bss
->bssid
);
656 wpa_supplicant_set_state(wpa_s
, WPA_AUTHENTICATING
);
657 if (old_ssid
!= wpa_s
->current_ssid
)
658 wpas_notify_network_changed(wpa_s
);
661 hs20_configure_frame_filters(wpa_s
);
662 #endif /* CONFIG_HS20 */
666 * If multi-channel concurrency is not supported, check for any
667 * frequency conflict. In case of any frequency conflict, remove the
668 * least prioritized connection.
670 if (wpa_s
->num_multichan_concurrent
< 2) {
672 num
= get_shared_radio_freqs(wpa_s
, &freq
, 1);
673 if (num
> 0 && freq
> 0 && freq
!= params
.freq
) {
674 wpa_printf(MSG_DEBUG
,
675 "Conflicting frequency found (%d != %d)",
677 if (wpas_p2p_handle_frequency_conflicts(wpa_s
,
680 wpas_connection_failed(wpa_s
, bss
->bssid
);
681 wpa_supplicant_mark_disassoc(wpa_s
);
683 wpas_connect_work_done(wpa_s
);
688 #endif /* CONFIG_P2P */
691 wpa_msg(wpa_s
, MSG_DEBUG
,
692 "SME: Skip authentication step on reassoc-to-same-BSS");
694 sme_associate(wpa_s
, ssid
->mode
, bss
->bssid
, WLAN_AUTH_OPEN
);
699 wpa_s
->sme
.auth_alg
= params
.auth_alg
;
700 if (wpa_drv_authenticate(wpa_s
, ¶ms
) < 0) {
701 wpa_msg(wpa_s
, MSG_INFO
, "SME: Authentication request to the "
703 wpas_connection_failed(wpa_s
, bss
->bssid
);
704 wpa_supplicant_mark_disassoc(wpa_s
);
706 wpas_connect_work_done(wpa_s
);
710 eloop_register_timeout(SME_AUTH_TIMEOUT
, 0, sme_auth_timer
, wpa_s
,
714 * Association will be started based on the authentication event from
722 static void sme_auth_start_cb(struct wpa_radio_work
*work
, int deinit
)
724 struct wpa_connect_work
*cwork
= work
->ctx
;
725 struct wpa_supplicant
*wpa_s
= work
->wpa_s
;
729 wpa_s
->connect_work
= NULL
;
731 wpas_connect_work_free(cwork
);
735 wpa_s
->connect_work
= work
;
737 if (cwork
->bss_removed
||
738 !wpas_valid_bss_ssid(wpa_s
, cwork
->bss
, cwork
->ssid
) ||
739 wpas_network_disabled(wpa_s
, cwork
->ssid
)) {
740 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: BSS/SSID entry for authentication not valid anymore - drop connection attempt");
741 wpas_connect_work_done(wpa_s
);
745 /* Starting new connection, so clear the possibly used WPA IE from the
746 * previous association. */
747 wpa_sm_set_assoc_wpa_ie(wpa_s
->wpa
, NULL
, 0);
749 sme_send_authentication(wpa_s
, cwork
->bss
, cwork
->ssid
, 1);
753 void sme_authenticate(struct wpa_supplicant
*wpa_s
,
754 struct wpa_bss
*bss
, struct wpa_ssid
*ssid
)
756 struct wpa_connect_work
*cwork
;
758 if (bss
== NULL
|| ssid
== NULL
)
760 if (wpa_s
->connect_work
) {
761 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Reject sme_authenticate() call since connect_work exist");
765 if (radio_work_pending(wpa_s
, "sme-connect")) {
767 * The previous sme-connect work might no longer be valid due to
768 * the fact that the BSS list was updated. In addition, it makes
769 * sense to adhere to the 'newer' decision.
771 wpa_dbg(wpa_s
, MSG_DEBUG
,
772 "SME: Remove previous pending sme-connect");
773 radio_remove_works(wpa_s
, "sme-connect", 0);
776 wpas_abort_ongoing_scan(wpa_s
);
778 cwork
= os_zalloc(sizeof(*cwork
));
786 wpa_s
->sme
.sae
.state
= SAE_NOTHING
;
787 wpa_s
->sme
.sae
.send_confirm
= 0;
788 wpa_s
->sme
.sae_group_index
= 0;
789 #endif /* CONFIG_SAE */
791 if (radio_add_work(wpa_s
, bss
->freq
, "sme-connect", 1,
792 sme_auth_start_cb
, cwork
) < 0)
793 wpas_connect_work_free(cwork
);
799 static int sme_external_auth_build_buf(struct wpabuf
*buf
,
800 struct wpabuf
*params
,
801 const u8
*sa
, const u8
*da
,
802 u16 auth_transaction
, u16 seq_num
)
804 struct ieee80211_mgmt
*resp
;
806 resp
= wpabuf_put(buf
, offsetof(struct ieee80211_mgmt
,
809 resp
->frame_control
= host_to_le16((WLAN_FC_TYPE_MGMT
<< 2) |
810 (WLAN_FC_STYPE_AUTH
<< 4));
811 os_memcpy(resp
->da
, da
, ETH_ALEN
);
812 os_memcpy(resp
->sa
, sa
, ETH_ALEN
);
813 os_memcpy(resp
->bssid
, da
, ETH_ALEN
);
814 resp
->u
.auth
.auth_alg
= WLAN_AUTH_SAE
;
815 resp
->seq_ctrl
= seq_num
<< 4;
816 resp
->u
.auth
.auth_transaction
= auth_transaction
;
817 resp
->u
.auth
.status_code
= WLAN_STATUS_SUCCESS
;
819 wpabuf_put_buf(buf
, params
);
825 static void sme_external_auth_send_sae_commit(struct wpa_supplicant
*wpa_s
,
827 struct wpa_ssid
*ssid
)
829 struct wpabuf
*resp
, *buf
;
831 resp
= sme_auth_build_sae_commit(wpa_s
, ssid
, bssid
, 1);
835 wpa_s
->sme
.sae
.state
= SAE_COMMITTED
;
836 buf
= wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN
+ wpabuf_len(resp
));
842 wpa_s
->sme
.seq_num
++;
843 sme_external_auth_build_buf(buf
, resp
, wpa_s
->own_addr
,
844 bssid
, 1, wpa_s
->sme
.seq_num
);
845 wpa_drv_send_mlme(wpa_s
, wpabuf_head(buf
), wpabuf_len(buf
), 1, 0);
851 static void sme_send_external_auth_status(struct wpa_supplicant
*wpa_s
,
854 struct external_auth params
;
856 os_memset(¶ms
, 0, sizeof(params
));
857 params
.status
= status
;
858 os_memcpy(params
.ssid
, wpa_s
->sme
.ext_auth
.ssid
,
859 wpa_s
->sme
.ext_auth
.ssid_len
);
860 params
.ssid_len
= wpa_s
->sme
.ext_auth
.ssid_len
;
861 os_memcpy(params
.bssid
, wpa_s
->sme
.ext_auth
.bssid
, ETH_ALEN
);
862 wpa_drv_send_external_auth_status(wpa_s
, ¶ms
);
866 static void sme_handle_external_auth_start(struct wpa_supplicant
*wpa_s
,
867 union wpa_event_data
*data
)
869 struct wpa_ssid
*ssid
;
870 size_t ssid_str_len
= data
->external_auth
.ssid_len
;
871 u8
*ssid_str
= data
->external_auth
.ssid
;
873 /* Get the SSID conf from the ssid string obtained */
874 for (ssid
= wpa_s
->conf
->ssid
; ssid
; ssid
= ssid
->next
) {
875 if (!wpas_network_disabled(wpa_s
, ssid
) &&
876 ssid_str_len
== ssid
->ssid_len
&&
877 os_memcmp(ssid_str
, ssid
->ssid
, ssid_str_len
) == 0)
881 sme_external_auth_send_sae_commit(wpa_s
,
882 data
->external_auth
.bssid
,
885 sme_send_external_auth_status(wpa_s
,
886 WLAN_STATUS_UNSPECIFIED_FAILURE
);
890 static void sme_external_auth_send_sae_confirm(struct wpa_supplicant
*wpa_s
,
893 struct wpabuf
*resp
, *buf
;
895 resp
= sme_auth_build_sae_confirm(wpa_s
, 1);
897 wpa_printf(MSG_DEBUG
, "SAE: Confirm message buf alloc failure");
901 wpa_s
->sme
.sae
.state
= SAE_CONFIRMED
;
902 buf
= wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN
+ wpabuf_len(resp
));
904 wpa_printf(MSG_DEBUG
, "SAE: Auth Confirm buf alloc failure");
908 wpa_s
->sme
.seq_num
++;
909 sme_external_auth_build_buf(buf
, resp
, wpa_s
->own_addr
,
910 da
, 2, wpa_s
->sme
.seq_num
);
911 wpa_drv_send_mlme(wpa_s
, wpabuf_head(buf
), wpabuf_len(buf
), 1, 0);
917 void sme_external_auth_trigger(struct wpa_supplicant
*wpa_s
,
918 union wpa_event_data
*data
)
920 if (RSN_SELECTOR_GET(&data
->external_auth
.key_mgmt_suite
) !=
921 RSN_AUTH_KEY_MGMT_SAE
)
924 if (data
->external_auth
.action
== EXT_AUTH_START
) {
925 os_memcpy(&wpa_s
->sme
.ext_auth
, data
,
926 sizeof(struct external_auth
));
927 wpa_s
->sme
.seq_num
= 0;
928 wpa_s
->sme
.sae
.state
= SAE_NOTHING
;
929 wpa_s
->sme
.sae
.send_confirm
= 0;
930 wpa_s
->sme
.sae_group_index
= 0;
931 sme_handle_external_auth_start(wpa_s
, data
);
932 } else if (data
->external_auth
.action
== EXT_AUTH_ABORT
) {
933 /* Report failure to driver for the wrong trigger */
934 sme_send_external_auth_status(wpa_s
,
935 WLAN_STATUS_UNSPECIFIED_FAILURE
);
940 static int sme_sae_auth(struct wpa_supplicant
*wpa_s
, u16 auth_transaction
,
941 u16 status_code
, const u8
*data
, size_t len
,
942 int external
, const u8
*sa
)
946 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: SAE authentication transaction %u "
947 "status code %u", auth_transaction
, status_code
);
949 if (auth_transaction
== 1 &&
950 status_code
== WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ
&&
951 wpa_s
->sme
.sae
.state
== SAE_COMMITTED
&&
952 (external
|| wpa_s
->current_bss
) && wpa_s
->current_ssid
) {
953 int default_groups
[] = { 19, 20, 21, 25, 26, 0 };
956 groups
= wpa_s
->conf
->sae_groups
;
957 if (!groups
|| groups
[0] <= 0)
958 groups
= default_groups
;
960 if (len
< sizeof(le16
)) {
961 wpa_dbg(wpa_s
, MSG_DEBUG
,
962 "SME: Too short SAE anti-clogging token request");
965 group
= WPA_GET_LE16(data
);
966 wpa_dbg(wpa_s
, MSG_DEBUG
,
967 "SME: SAE anti-clogging token requested (group %u)",
969 if (sae_group_allowed(&wpa_s
->sme
.sae
, groups
, group
) !=
970 WLAN_STATUS_SUCCESS
) {
971 wpa_dbg(wpa_s
, MSG_ERROR
,
972 "SME: SAE group %u of anti-clogging request is invalid",
976 wpabuf_free(wpa_s
->sme
.sae_token
);
977 wpa_s
->sme
.sae_token
= wpabuf_alloc_copy(data
+ sizeof(le16
),
980 sme_send_authentication(wpa_s
, wpa_s
->current_bss
,
981 wpa_s
->current_ssid
, 1);
983 sme_external_auth_send_sae_commit(
984 wpa_s
, wpa_s
->sme
.ext_auth
.bssid
,
985 wpa_s
->current_ssid
);
989 if (auth_transaction
== 1 &&
990 status_code
== WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED
&&
991 wpa_s
->sme
.sae
.state
== SAE_COMMITTED
&&
992 (external
|| wpa_s
->current_bss
) && wpa_s
->current_ssid
) {
993 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: SAE group not supported");
994 wpa_s
->sme
.sae_group_index
++;
995 if (sme_set_sae_group(wpa_s
) < 0)
996 return -1; /* no other groups enabled */
997 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Try next enabled SAE group");
999 sme_send_authentication(wpa_s
, wpa_s
->current_bss
,
1000 wpa_s
->current_ssid
, 1);
1002 sme_external_auth_send_sae_commit(
1003 wpa_s
, wpa_s
->sme
.ext_auth
.bssid
,
1004 wpa_s
->current_ssid
);
1008 if (status_code
!= WLAN_STATUS_SUCCESS
)
1011 if (auth_transaction
== 1) {
1014 groups
= wpa_s
->conf
->sae_groups
;
1016 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME SAE commit");
1017 if ((!external
&& wpa_s
->current_bss
== NULL
) ||
1018 wpa_s
->current_ssid
== NULL
)
1020 if (wpa_s
->sme
.sae
.state
!= SAE_COMMITTED
)
1022 if (groups
&& groups
[0] <= 0)
1024 res
= sae_parse_commit(&wpa_s
->sme
.sae
, data
, len
, NULL
, NULL
,
1026 if (res
== SAE_SILENTLY_DISCARD
) {
1027 wpa_printf(MSG_DEBUG
,
1028 "SAE: Drop commit message due to reflection attack");
1031 if (res
!= WLAN_STATUS_SUCCESS
)
1034 if (sae_process_commit(&wpa_s
->sme
.sae
) < 0) {
1035 wpa_printf(MSG_DEBUG
, "SAE: Failed to process peer "
1040 wpabuf_free(wpa_s
->sme
.sae_token
);
1041 wpa_s
->sme
.sae_token
= NULL
;
1043 sme_send_authentication(wpa_s
, wpa_s
->current_bss
,
1044 wpa_s
->current_ssid
, 0);
1046 sme_external_auth_send_sae_confirm(wpa_s
, sa
);
1048 } else if (auth_transaction
== 2) {
1049 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME SAE confirm");
1050 if (wpa_s
->sme
.sae
.state
!= SAE_CONFIRMED
)
1052 if (sae_check_confirm(&wpa_s
->sme
.sae
, data
, len
) < 0)
1054 wpa_s
->sme
.sae
.state
= SAE_ACCEPTED
;
1055 sae_clear_temp_data(&wpa_s
->sme
.sae
);
1058 /* Report success to driver */
1059 sme_send_external_auth_status(wpa_s
,
1060 WLAN_STATUS_SUCCESS
);
1070 void sme_external_auth_mgmt_rx(struct wpa_supplicant
*wpa_s
,
1071 const u8
*auth_frame
, size_t len
)
1073 const struct ieee80211_mgmt
*header
;
1076 header
= (const struct ieee80211_mgmt
*) auth_frame
;
1077 auth_length
= IEEE80211_HDRLEN
+ sizeof(header
->u
.auth
);
1079 if (len
< auth_length
) {
1080 /* Notify failure to the driver */
1081 sme_send_external_auth_status(wpa_s
,
1082 WLAN_STATUS_UNSPECIFIED_FAILURE
);
1086 if (header
->u
.auth
.auth_alg
== WLAN_AUTH_SAE
) {
1089 res
= sme_sae_auth(wpa_s
, header
->u
.auth
.auth_transaction
,
1090 header
->u
.auth
.status_code
,
1091 header
->u
.auth
.variable
,
1092 len
- auth_length
, 1, header
->sa
);
1094 /* Notify failure to the driver */
1095 sme_send_external_auth_status(
1096 wpa_s
, WLAN_STATUS_UNSPECIFIED_FAILURE
);
1102 wpa_printf(MSG_DEBUG
,
1103 "SME: SAE completed - setting PMK for 4-way handshake");
1104 wpa_sm_set_pmk(wpa_s
->wpa
, wpa_s
->sme
.sae
.pmk
, PMK_LEN
,
1105 wpa_s
->sme
.sae
.pmkid
, wpa_s
->pending_bssid
);
1109 #endif /* CONFIG_SAE */
1112 void sme_event_auth(struct wpa_supplicant
*wpa_s
, union wpa_event_data
*data
)
1114 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
1117 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Ignore authentication event "
1118 "when network is not selected");
1122 if (wpa_s
->wpa_state
!= WPA_AUTHENTICATING
) {
1123 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Ignore authentication event "
1124 "when not in authenticating state");
1128 if (os_memcmp(wpa_s
->pending_bssid
, data
->auth
.peer
, ETH_ALEN
) != 0) {
1129 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Ignore authentication with "
1130 "unexpected peer " MACSTR
,
1131 MAC2STR(data
->auth
.peer
));
1135 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Authentication response: peer=" MACSTR
1136 " auth_type=%d auth_transaction=%d status_code=%d",
1137 MAC2STR(data
->auth
.peer
), data
->auth
.auth_type
,
1138 data
->auth
.auth_transaction
, data
->auth
.status_code
);
1139 wpa_hexdump(MSG_MSGDUMP
, "SME: Authentication response IEs",
1140 data
->auth
.ies
, data
->auth
.ies_len
);
1142 eloop_cancel_timeout(sme_auth_timer
, wpa_s
, NULL
);
1145 if (data
->auth
.auth_type
== WLAN_AUTH_SAE
) {
1147 res
= sme_sae_auth(wpa_s
, data
->auth
.auth_transaction
,
1148 data
->auth
.status_code
, data
->auth
.ies
,
1149 data
->auth
.ies_len
, 0, NULL
);
1151 wpas_connection_failed(wpa_s
, wpa_s
->pending_bssid
);
1152 wpa_supplicant_set_state(wpa_s
, WPA_DISCONNECTED
);
1158 wpa_printf(MSG_DEBUG
, "SME: SAE completed - setting PMK for "
1160 wpa_sm_set_pmk(wpa_s
->wpa
, wpa_s
->sme
.sae
.pmk
, PMK_LEN
,
1161 wpa_s
->sme
.sae
.pmkid
, wpa_s
->pending_bssid
);
1163 #endif /* CONFIG_SAE */
1165 if (data
->auth
.status_code
!= WLAN_STATUS_SUCCESS
) {
1166 char *ie_txt
= NULL
;
1168 if (data
->auth
.ies
&& data
->auth
.ies_len
) {
1169 size_t buflen
= 2 * data
->auth
.ies_len
+ 1;
1170 ie_txt
= os_malloc(buflen
);
1172 wpa_snprintf_hex(ie_txt
, buflen
, data
->auth
.ies
,
1173 data
->auth
.ies_len
);
1176 wpa_msg(wpa_s
, MSG_INFO
, WPA_EVENT_AUTH_REJECT MACSTR
1177 " auth_type=%u auth_transaction=%u status_code=%u%s%s",
1178 MAC2STR(data
->auth
.peer
), data
->auth
.auth_type
,
1179 data
->auth
.auth_transaction
, data
->auth
.status_code
,
1180 ie_txt
? " ie=" : "",
1181 ie_txt
? ie_txt
: "");
1184 if (data
->auth
.status_code
!=
1185 WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG
||
1186 wpa_s
->sme
.auth_alg
== data
->auth
.auth_type
||
1187 wpa_s
->current_ssid
->auth_alg
== WPA_AUTH_ALG_LEAP
) {
1188 wpas_connection_failed(wpa_s
, wpa_s
->pending_bssid
);
1189 wpa_supplicant_set_state(wpa_s
, WPA_DISCONNECTED
);
1193 wpas_connect_work_done(wpa_s
);
1195 switch (data
->auth
.auth_type
) {
1196 case WLAN_AUTH_OPEN
:
1197 wpa_s
->current_ssid
->auth_alg
= WPA_AUTH_ALG_SHARED
;
1199 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Trying SHARED auth");
1200 wpa_supplicant_associate(wpa_s
, wpa_s
->current_bss
,
1201 wpa_s
->current_ssid
);
1204 case WLAN_AUTH_SHARED_KEY
:
1205 wpa_s
->current_ssid
->auth_alg
= WPA_AUTH_ALG_LEAP
;
1207 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Trying LEAP auth");
1208 wpa_supplicant_associate(wpa_s
, wpa_s
->current_bss
,
1209 wpa_s
->current_ssid
);
1217 #ifdef CONFIG_IEEE80211R
1218 if (data
->auth
.auth_type
== WLAN_AUTH_FT
) {
1219 const u8
*ric_ies
= NULL
;
1220 size_t ric_ies_len
= 0;
1222 if (wpa_s
->ric_ies
) {
1223 ric_ies
= wpabuf_head(wpa_s
->ric_ies
);
1224 ric_ies_len
= wpabuf_len(wpa_s
->ric_ies
);
1226 if (wpa_ft_process_response(wpa_s
->wpa
, data
->auth
.ies
,
1227 data
->auth
.ies_len
, 0,
1229 ric_ies
, ric_ies_len
) < 0) {
1230 wpa_dbg(wpa_s
, MSG_DEBUG
,
1231 "SME: FT Authentication response processing failed");
1232 wpa_msg(wpa_s
, MSG_INFO
, WPA_EVENT_DISCONNECTED
"bssid="
1234 " reason=%d locally_generated=1",
1235 MAC2STR(wpa_s
->pending_bssid
),
1236 WLAN_REASON_DEAUTH_LEAVING
);
1237 wpas_connection_failed(wpa_s
, wpa_s
->pending_bssid
);
1238 wpa_supplicant_mark_disassoc(wpa_s
);
1242 #endif /* CONFIG_IEEE80211R */
1245 if (data
->auth
.auth_type
== WLAN_AUTH_FILS_SK
||
1246 data
->auth
.auth_type
== WLAN_AUTH_FILS_SK_PFS
) {
1247 u16 expect_auth_type
;
1249 expect_auth_type
= wpa_s
->sme
.auth_alg
==
1250 WPA_AUTH_ALG_FILS_SK_PFS
? WLAN_AUTH_FILS_SK_PFS
:
1252 if (data
->auth
.auth_type
!= expect_auth_type
) {
1253 wpa_dbg(wpa_s
, MSG_DEBUG
,
1254 "SME: FILS Authentication response used different auth alg (%u; expected %u)",
1255 data
->auth
.auth_type
, expect_auth_type
);
1256 wpa_msg(wpa_s
, MSG_INFO
, WPA_EVENT_DISCONNECTED
"bssid="
1258 " reason=%d locally_generated=1",
1259 MAC2STR(wpa_s
->pending_bssid
),
1260 WLAN_REASON_DEAUTH_LEAVING
);
1261 wpas_connection_failed(wpa_s
, wpa_s
->pending_bssid
);
1262 wpa_supplicant_mark_disassoc(wpa_s
);
1266 if (fils_process_auth(wpa_s
->wpa
, wpa_s
->pending_bssid
,
1267 data
->auth
.ies
, data
->auth
.ies_len
) < 0) {
1268 wpa_dbg(wpa_s
, MSG_DEBUG
,
1269 "SME: FILS Authentication response processing failed");
1270 wpa_msg(wpa_s
, MSG_INFO
, WPA_EVENT_DISCONNECTED
"bssid="
1272 " reason=%d locally_generated=1",
1273 MAC2STR(wpa_s
->pending_bssid
),
1274 WLAN_REASON_DEAUTH_LEAVING
);
1275 wpas_connection_failed(wpa_s
, wpa_s
->pending_bssid
);
1276 wpa_supplicant_mark_disassoc(wpa_s
);
1280 #endif /* CONFIG_FILS */
1282 sme_associate(wpa_s
, ssid
->mode
, data
->auth
.peer
,
1283 data
->auth
.auth_type
);
1288 #ifdef CONFIG_IEEE80211R
1289 static void remove_ie(u8
*buf
, size_t *len
, u8 eid
)
1291 u8
*pos
, *next
, *end
;
1293 pos
= (u8
*) get_ie(buf
, *len
, eid
);
1295 next
= pos
+ 2 + pos
[1];
1298 os_memmove(pos
, next
, end
- next
);
1301 #endif /* CONFIG_IEEE80211R */
1302 #endif /* CONFIG_FILS */
1305 void sme_associate(struct wpa_supplicant
*wpa_s
, enum wpas_mode mode
,
1306 const u8
*bssid
, u16 auth_type
)
1308 struct wpa_driver_associate_params params
;
1309 struct ieee802_11_elems elems
;
1311 u8 nonces
[2 * FILS_NONCE_LEN
];
1312 #endif /* CONFIG_FILS */
1313 #ifdef CONFIG_HT_OVERRIDES
1314 struct ieee80211_ht_capabilities htcaps
;
1315 struct ieee80211_ht_capabilities htcaps_mask
;
1316 #endif /* CONFIG_HT_OVERRIDES */
1317 #ifdef CONFIG_VHT_OVERRIDES
1318 struct ieee80211_vht_capabilities vhtcaps
;
1319 struct ieee80211_vht_capabilities vhtcaps_mask
;
1320 #endif /* CONFIG_VHT_OVERRIDES */
1322 os_memset(¶ms
, 0, sizeof(params
));
1325 if (auth_type
== WLAN_AUTH_FILS_SK
||
1326 auth_type
== WLAN_AUTH_FILS_SK_PFS
) {
1328 const u8
*snonce
, *anonce
;
1329 const unsigned int max_hlp
= 20;
1330 struct wpabuf
*hlp
[max_hlp
];
1331 unsigned int i
, num_hlp
= 0;
1332 struct fils_hlp_req
*req
;
1334 dl_list_for_each(req
, &wpa_s
->fils_hlp_req
, struct fils_hlp_req
,
1336 hlp
[num_hlp
] = wpabuf_alloc(2 * ETH_ALEN
+ 6 +
1337 wpabuf_len(req
->pkt
));
1340 wpabuf_put_data(hlp
[num_hlp
], req
->dst
, ETH_ALEN
);
1341 wpabuf_put_data(hlp
[num_hlp
], wpa_s
->own_addr
,
1343 wpabuf_put_data(hlp
[num_hlp
],
1344 "\xaa\xaa\x03\x00\x00\x00", 6);
1345 wpabuf_put_buf(hlp
[num_hlp
], req
->pkt
);
1347 if (num_hlp
>= max_hlp
)
1351 buf
= fils_build_assoc_req(wpa_s
->wpa
, ¶ms
.fils_kek
,
1352 ¶ms
.fils_kek_len
, &snonce
,
1354 (const struct wpabuf
**) hlp
,
1356 for (i
= 0; i
< num_hlp
; i
++)
1357 wpabuf_free(hlp
[i
]);
1360 wpa_hexdump(MSG_DEBUG
, "FILS: assoc_req before FILS elements",
1361 wpa_s
->sme
.assoc_req_ie
,
1362 wpa_s
->sme
.assoc_req_ie_len
);
1363 #ifdef CONFIG_IEEE80211R
1364 if (wpa_key_mgmt_ft(wpa_s
->key_mgmt
)) {
1365 /* Remove RSNE and MDE to allow them to be overridden
1366 * with FILS+FT specific values from
1367 * fils_build_assoc_req(). */
1368 remove_ie(wpa_s
->sme
.assoc_req_ie
,
1369 &wpa_s
->sme
.assoc_req_ie_len
,
1371 wpa_hexdump(MSG_DEBUG
,
1372 "FILS: assoc_req after RSNE removal",
1373 wpa_s
->sme
.assoc_req_ie
,
1374 wpa_s
->sme
.assoc_req_ie_len
);
1375 remove_ie(wpa_s
->sme
.assoc_req_ie
,
1376 &wpa_s
->sme
.assoc_req_ie_len
,
1377 WLAN_EID_MOBILITY_DOMAIN
);
1378 wpa_hexdump(MSG_DEBUG
,
1379 "FILS: assoc_req after MDE removal",
1380 wpa_s
->sme
.assoc_req_ie
,
1381 wpa_s
->sme
.assoc_req_ie_len
);
1383 #endif /* CONFIG_IEEE80211R */
1384 /* TODO: Make wpa_s->sme.assoc_req_ie use dynamic allocation */
1385 if (wpa_s
->sme
.assoc_req_ie_len
+ wpabuf_len(buf
) >
1386 sizeof(wpa_s
->sme
.assoc_req_ie
)) {
1387 wpa_printf(MSG_ERROR
,
1388 "FILS: Not enough buffer room for own AssocReq elements");
1392 os_memcpy(wpa_s
->sme
.assoc_req_ie
+ wpa_s
->sme
.assoc_req_ie_len
,
1393 wpabuf_head(buf
), wpabuf_len(buf
));
1394 wpa_s
->sme
.assoc_req_ie_len
+= wpabuf_len(buf
);
1396 wpa_hexdump(MSG_DEBUG
, "FILS: assoc_req after FILS elements",
1397 wpa_s
->sme
.assoc_req_ie
,
1398 wpa_s
->sme
.assoc_req_ie_len
);
1400 os_memcpy(nonces
, snonce
, FILS_NONCE_LEN
);
1401 os_memcpy(nonces
+ FILS_NONCE_LEN
, anonce
, FILS_NONCE_LEN
);
1402 params
.fils_nonces
= nonces
;
1403 params
.fils_nonces_len
= sizeof(nonces
);
1405 #endif /* CONFIG_FILS */
1408 #ifdef CONFIG_TESTING_OPTIONS
1409 if (get_ie_ext(wpa_s
->sme
.assoc_req_ie
, wpa_s
->sme
.assoc_req_ie_len
,
1410 WLAN_EID_EXT_OWE_DH_PARAM
)) {
1411 wpa_printf(MSG_INFO
, "TESTING: Override OWE DH element");
1413 #endif /* CONFIG_TESTING_OPTIONS */
1414 if (auth_type
== WLAN_AUTH_OPEN
&&
1415 wpa_s
->key_mgmt
== WPA_KEY_MGMT_OWE
) {
1416 struct wpabuf
*owe_ie
;
1419 if (wpa_s
->current_ssid
&& wpa_s
->current_ssid
->owe_group
) {
1420 group
= wpa_s
->current_ssid
->owe_group
;
1422 if (wpa_s
->last_owe_group
== 19)
1424 else if (wpa_s
->last_owe_group
== 20)
1427 group
= OWE_DH_GROUP
;
1429 wpa_s
->last_owe_group
= group
;
1430 wpa_printf(MSG_DEBUG
, "OWE: Try to use group %u", group
);
1431 owe_ie
= owe_build_assoc_req(wpa_s
->wpa
, group
);
1433 wpa_printf(MSG_ERROR
,
1434 "OWE: Failed to build IE for Association Request frame");
1437 if (wpa_s
->sme
.assoc_req_ie_len
+ wpabuf_len(owe_ie
) >
1438 sizeof(wpa_s
->sme
.assoc_req_ie
)) {
1439 wpa_printf(MSG_ERROR
,
1440 "OWE: Not enough buffer room for own Association Request frame elements");
1441 wpabuf_free(owe_ie
);
1444 os_memcpy(wpa_s
->sme
.assoc_req_ie
+ wpa_s
->sme
.assoc_req_ie_len
,
1445 wpabuf_head(owe_ie
), wpabuf_len(owe_ie
));
1446 wpa_s
->sme
.assoc_req_ie_len
+= wpabuf_len(owe_ie
);
1447 wpabuf_free(owe_ie
);
1449 #endif /* CONFIG_OWE */
1451 params
.bssid
= bssid
;
1452 params
.ssid
= wpa_s
->sme
.ssid
;
1453 params
.ssid_len
= wpa_s
->sme
.ssid_len
;
1454 params
.freq
.freq
= wpa_s
->sme
.freq
;
1455 params
.bg_scan_period
= wpa_s
->current_ssid
?
1456 wpa_s
->current_ssid
->bg_scan_period
: -1;
1457 params
.wpa_ie
= wpa_s
->sme
.assoc_req_ie_len
?
1458 wpa_s
->sme
.assoc_req_ie
: NULL
;
1459 params
.wpa_ie_len
= wpa_s
->sme
.assoc_req_ie_len
;
1460 params
.pairwise_suite
= wpa_s
->pairwise_cipher
;
1461 params
.group_suite
= wpa_s
->group_cipher
;
1462 params
.mgmt_group_suite
= wpa_s
->mgmt_group_cipher
;
1463 params
.key_mgmt_suite
= wpa_s
->key_mgmt
;
1464 params
.wpa_proto
= wpa_s
->wpa_proto
;
1465 #ifdef CONFIG_HT_OVERRIDES
1466 os_memset(&htcaps
, 0, sizeof(htcaps
));
1467 os_memset(&htcaps_mask
, 0, sizeof(htcaps_mask
));
1468 params
.htcaps
= (u8
*) &htcaps
;
1469 params
.htcaps_mask
= (u8
*) &htcaps_mask
;
1470 wpa_supplicant_apply_ht_overrides(wpa_s
, wpa_s
->current_ssid
, ¶ms
);
1471 #endif /* CONFIG_HT_OVERRIDES */
1472 #ifdef CONFIG_VHT_OVERRIDES
1473 os_memset(&vhtcaps
, 0, sizeof(vhtcaps
));
1474 os_memset(&vhtcaps_mask
, 0, sizeof(vhtcaps_mask
));
1475 params
.vhtcaps
= &vhtcaps
;
1476 params
.vhtcaps_mask
= &vhtcaps_mask
;
1477 wpa_supplicant_apply_vht_overrides(wpa_s
, wpa_s
->current_ssid
, ¶ms
);
1478 #endif /* CONFIG_VHT_OVERRIDES */
1479 #ifdef CONFIG_IEEE80211R
1480 if (auth_type
== WLAN_AUTH_FT
&& wpa_s
->sme
.ft_ies
) {
1481 params
.wpa_ie
= wpa_s
->sme
.ft_ies
;
1482 params
.wpa_ie_len
= wpa_s
->sme
.ft_ies_len
;
1484 #endif /* CONFIG_IEEE80211R */
1486 params
.mgmt_frame_protection
= wpa_s
->sme
.mfp
;
1487 params
.rrm_used
= wpa_s
->rrm
.rrm_used
;
1488 if (wpa_s
->sme
.prev_bssid_set
)
1489 params
.prev_bssid
= wpa_s
->sme
.prev_bssid
;
1491 wpa_msg(wpa_s
, MSG_INFO
, "Trying to associate with " MACSTR
1492 " (SSID='%s' freq=%d MHz)", MAC2STR(params
.bssid
),
1493 params
.ssid
? wpa_ssid_txt(params
.ssid
, params
.ssid_len
) : "",
1496 wpa_supplicant_set_state(wpa_s
, WPA_ASSOCIATING
);
1498 if (params
.wpa_ie
== NULL
||
1499 ieee802_11_parse_elems(params
.wpa_ie
, params
.wpa_ie_len
, &elems
, 0)
1501 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Could not parse own IEs?!");
1502 os_memset(&elems
, 0, sizeof(elems
));
1505 params
.wpa_proto
= WPA_PROTO_RSN
;
1506 wpa_sm_set_assoc_wpa_ie(wpa_s
->wpa
, elems
.rsn_ie
- 2,
1507 elems
.rsn_ie_len
+ 2);
1508 } else if (elems
.wpa_ie
) {
1509 params
.wpa_proto
= WPA_PROTO_WPA
;
1510 wpa_sm_set_assoc_wpa_ie(wpa_s
->wpa
, elems
.wpa_ie
- 2,
1511 elems
.wpa_ie_len
+ 2);
1512 } else if (elems
.osen
) {
1513 params
.wpa_proto
= WPA_PROTO_OSEN
;
1514 wpa_sm_set_assoc_wpa_ie(wpa_s
->wpa
, elems
.osen
- 2,
1515 elems
.osen_len
+ 2);
1517 wpa_sm_set_assoc_wpa_ie(wpa_s
->wpa
, NULL
, 0);
1518 if (wpa_s
->current_ssid
&& wpa_s
->current_ssid
->p2p_group
)
1521 if (wpa_s
->p2pdev
->set_sta_uapsd
)
1522 params
.uapsd
= wpa_s
->p2pdev
->sta_uapsd
;
1526 if (wpa_drv_associate(wpa_s
, ¶ms
) < 0) {
1527 wpa_msg(wpa_s
, MSG_INFO
, "SME: Association request to the "
1529 wpas_connection_failed(wpa_s
, wpa_s
->pending_bssid
);
1530 wpa_supplicant_set_state(wpa_s
, WPA_DISCONNECTED
);
1531 os_memset(wpa_s
->pending_bssid
, 0, ETH_ALEN
);
1535 eloop_register_timeout(SME_ASSOC_TIMEOUT
, 0, sme_assoc_timer
, wpa_s
,
1538 #ifdef CONFIG_TESTING_OPTIONS
1539 wpabuf_free(wpa_s
->last_assoc_req_wpa_ie
);
1540 wpa_s
->last_assoc_req_wpa_ie
= NULL
;
1542 wpa_s
->last_assoc_req_wpa_ie
=
1543 wpabuf_alloc_copy(params
.wpa_ie
, params
.wpa_ie_len
);
1544 #endif /* CONFIG_TESTING_OPTIONS */
1548 int sme_update_ft_ies(struct wpa_supplicant
*wpa_s
, const u8
*md
,
1549 const u8
*ies
, size_t ies_len
)
1551 if (md
== NULL
|| ies
== NULL
) {
1552 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Remove mobility domain");
1553 os_free(wpa_s
->sme
.ft_ies
);
1554 wpa_s
->sme
.ft_ies
= NULL
;
1555 wpa_s
->sme
.ft_ies_len
= 0;
1556 wpa_s
->sme
.ft_used
= 0;
1560 os_memcpy(wpa_s
->sme
.mobility_domain
, md
, MOBILITY_DOMAIN_ID_LEN
);
1561 wpa_hexdump(MSG_DEBUG
, "SME: FT IEs", ies
, ies_len
);
1562 os_free(wpa_s
->sme
.ft_ies
);
1563 wpa_s
->sme
.ft_ies
= os_memdup(ies
, ies_len
);
1564 if (wpa_s
->sme
.ft_ies
== NULL
)
1566 wpa_s
->sme
.ft_ies_len
= ies_len
;
1571 static void sme_deauth(struct wpa_supplicant
*wpa_s
)
1575 bssid_changed
= !is_zero_ether_addr(wpa_s
->bssid
);
1577 if (wpa_drv_deauthenticate(wpa_s
, wpa_s
->pending_bssid
,
1578 WLAN_REASON_DEAUTH_LEAVING
) < 0) {
1579 wpa_msg(wpa_s
, MSG_INFO
, "SME: Deauth request to the driver "
1582 wpa_s
->sme
.prev_bssid_set
= 0;
1584 wpas_connection_failed(wpa_s
, wpa_s
->pending_bssid
);
1585 wpa_supplicant_set_state(wpa_s
, WPA_DISCONNECTED
);
1586 os_memset(wpa_s
->bssid
, 0, ETH_ALEN
);
1587 os_memset(wpa_s
->pending_bssid
, 0, ETH_ALEN
);
1589 wpas_notify_bssid_changed(wpa_s
);
1593 void sme_event_assoc_reject(struct wpa_supplicant
*wpa_s
,
1594 union wpa_event_data
*data
)
1596 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Association with " MACSTR
" failed: "
1597 "status code %d", MAC2STR(wpa_s
->pending_bssid
),
1598 data
->assoc_reject
.status_code
);
1600 eloop_cancel_timeout(sme_assoc_timer
, wpa_s
, NULL
);
1603 if (wpa_s
->sme
.sae_pmksa_caching
&& wpa_s
->current_ssid
&&
1604 wpa_key_mgmt_sae(wpa_s
->current_ssid
->key_mgmt
)) {
1605 wpa_dbg(wpa_s
, MSG_DEBUG
,
1606 "PMKSA caching attempt rejected - drop PMKSA cache entry and fall back to SAE authentication");
1607 wpa_sm_aborted_cached(wpa_s
->wpa
);
1608 wpa_sm_pmksa_cache_flush(wpa_s
->wpa
, wpa_s
->current_ssid
);
1609 if (wpa_s
->current_bss
) {
1610 struct wpa_bss
*bss
= wpa_s
->current_bss
;
1611 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
1613 wpa_drv_deauthenticate(wpa_s
, wpa_s
->pending_bssid
,
1614 WLAN_REASON_DEAUTH_LEAVING
);
1615 wpas_connect_work_done(wpa_s
);
1616 wpa_supplicant_mark_disassoc(wpa_s
);
1617 wpa_supplicant_connect(wpa_s
, bss
, ssid
);
1621 #endif /* CONFIG_SAE */
1624 * For now, unconditionally terminate the previous authentication. In
1625 * theory, this should not be needed, but mac80211 gets quite confused
1626 * if the authentication is left pending.. Some roaming cases might
1627 * benefit from using the previous authentication, so this could be
1628 * optimized in the future.
1634 void sme_event_auth_timed_out(struct wpa_supplicant
*wpa_s
,
1635 union wpa_event_data
*data
)
1637 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Authentication timed out");
1638 wpas_connection_failed(wpa_s
, wpa_s
->pending_bssid
);
1639 wpa_supplicant_mark_disassoc(wpa_s
);
1643 void sme_event_assoc_timed_out(struct wpa_supplicant
*wpa_s
,
1644 union wpa_event_data
*data
)
1646 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Association timed out");
1647 wpas_connection_failed(wpa_s
, wpa_s
->pending_bssid
);
1648 wpa_supplicant_mark_disassoc(wpa_s
);
1652 void sme_event_disassoc(struct wpa_supplicant
*wpa_s
,
1653 struct disassoc_info
*info
)
1655 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Disassociation event received");
1656 if (wpa_s
->sme
.prev_bssid_set
) {
1658 * cfg80211/mac80211 can get into somewhat confused state if
1659 * the AP only disassociates us and leaves us in authenticated
1660 * state. For now, force the state to be cleared to avoid
1661 * confusing errors if we try to associate with the AP again.
1663 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Deauthenticate to clear "
1665 wpa_drv_deauthenticate(wpa_s
, wpa_s
->sme
.prev_bssid
,
1666 WLAN_REASON_DEAUTH_LEAVING
);
1671 static void sme_auth_timer(void *eloop_ctx
, void *timeout_ctx
)
1673 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1674 if (wpa_s
->wpa_state
== WPA_AUTHENTICATING
) {
1675 wpa_msg(wpa_s
, MSG_DEBUG
, "SME: Authentication timeout");
1681 static void sme_assoc_timer(void *eloop_ctx
, void *timeout_ctx
)
1683 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1684 if (wpa_s
->wpa_state
== WPA_ASSOCIATING
) {
1685 wpa_msg(wpa_s
, MSG_DEBUG
, "SME: Association timeout");
1691 void sme_state_changed(struct wpa_supplicant
*wpa_s
)
1693 /* Make sure timers are cleaned up appropriately. */
1694 if (wpa_s
->wpa_state
!= WPA_ASSOCIATING
)
1695 eloop_cancel_timeout(sme_assoc_timer
, wpa_s
, NULL
);
1696 if (wpa_s
->wpa_state
!= WPA_AUTHENTICATING
)
1697 eloop_cancel_timeout(sme_auth_timer
, wpa_s
, NULL
);
1701 void sme_disassoc_while_authenticating(struct wpa_supplicant
*wpa_s
,
1702 const u8
*prev_pending_bssid
)
1705 * mac80211-workaround to force deauth on failed auth cmd,
1706 * requires us to remain in authenticating state to allow the
1707 * second authentication attempt to be continued properly.
1709 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Allow pending authentication "
1710 "to proceed after disconnection event");
1711 wpa_supplicant_set_state(wpa_s
, WPA_AUTHENTICATING
);
1712 os_memcpy(wpa_s
->pending_bssid
, prev_pending_bssid
, ETH_ALEN
);
1715 * Re-arm authentication timer in case auth fails for whatever reason.
1717 eloop_cancel_timeout(sme_auth_timer
, wpa_s
, NULL
);
1718 eloop_register_timeout(SME_AUTH_TIMEOUT
, 0, sme_auth_timer
, wpa_s
,
1723 void sme_clear_on_disassoc(struct wpa_supplicant
*wpa_s
)
1725 wpa_s
->sme
.prev_bssid_set
= 0;
1727 wpabuf_free(wpa_s
->sme
.sae_token
);
1728 wpa_s
->sme
.sae_token
= NULL
;
1729 sae_clear_data(&wpa_s
->sme
.sae
);
1730 #endif /* CONFIG_SAE */
1731 #ifdef CONFIG_IEEE80211R
1732 if (wpa_s
->sme
.ft_ies
|| wpa_s
->sme
.ft_used
)
1733 sme_update_ft_ies(wpa_s
, NULL
, NULL
, 0);
1734 #endif /* CONFIG_IEEE80211R */
1738 void sme_deinit(struct wpa_supplicant
*wpa_s
)
1740 os_free(wpa_s
->sme
.ft_ies
);
1741 wpa_s
->sme
.ft_ies
= NULL
;
1742 wpa_s
->sme
.ft_ies_len
= 0;
1743 #ifdef CONFIG_IEEE80211W
1744 sme_stop_sa_query(wpa_s
);
1745 #endif /* CONFIG_IEEE80211W */
1746 sme_clear_on_disassoc(wpa_s
);
1748 eloop_cancel_timeout(sme_assoc_timer
, wpa_s
, NULL
);
1749 eloop_cancel_timeout(sme_auth_timer
, wpa_s
, NULL
);
1750 eloop_cancel_timeout(sme_obss_scan_timeout
, wpa_s
, NULL
);
1754 static void sme_send_2040_bss_coex(struct wpa_supplicant
*wpa_s
,
1755 const u8
*chan_list
, u8 num_channels
,
1758 struct ieee80211_2040_bss_coex_ie
*bc_ie
;
1759 struct ieee80211_2040_intol_chan_report
*ic_report
;
1762 wpa_printf(MSG_DEBUG
, "SME: Send 20/40 BSS Coexistence to " MACSTR
1763 " (num_channels=%u num_intol=%u)",
1764 MAC2STR(wpa_s
->bssid
), num_channels
, num_intol
);
1765 wpa_hexdump(MSG_DEBUG
, "SME: 20/40 BSS Intolerant Channels",
1766 chan_list
, num_channels
);
1768 buf
= wpabuf_alloc(2 + /* action.category + action_code */
1769 sizeof(struct ieee80211_2040_bss_coex_ie
) +
1770 sizeof(struct ieee80211_2040_intol_chan_report
) +
1775 wpabuf_put_u8(buf
, WLAN_ACTION_PUBLIC
);
1776 wpabuf_put_u8(buf
, WLAN_PA_20_40_BSS_COEX
);
1778 bc_ie
= wpabuf_put(buf
, sizeof(*bc_ie
));
1779 bc_ie
->element_id
= WLAN_EID_20_40_BSS_COEXISTENCE
;
1782 bc_ie
->coex_param
|= WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ
;
1784 if (num_channels
> 0) {
1785 ic_report
= wpabuf_put(buf
, sizeof(*ic_report
));
1786 ic_report
->element_id
= WLAN_EID_20_40_BSS_INTOLERANT
;
1787 ic_report
->length
= num_channels
+ 1;
1788 ic_report
->op_class
= 0;
1789 os_memcpy(wpabuf_put(buf
, num_channels
), chan_list
,
1793 if (wpa_drv_send_action(wpa_s
, wpa_s
->assoc_freq
, 0, wpa_s
->bssid
,
1794 wpa_s
->own_addr
, wpa_s
->bssid
,
1795 wpabuf_head(buf
), wpabuf_len(buf
), 0) < 0) {
1796 wpa_msg(wpa_s
, MSG_INFO
,
1797 "SME: Failed to send 20/40 BSS Coexistence frame");
1804 int sme_proc_obss_scan(struct wpa_supplicant
*wpa_s
)
1806 struct wpa_bss
*bss
;
1809 u8 chan_list
[P2P_MAX_CHANNELS
], channel
;
1810 u8 num_channels
= 0, num_intol
= 0, i
;
1812 if (!wpa_s
->sme
.sched_obss_scan
)
1815 wpa_s
->sme
.sched_obss_scan
= 0;
1816 if (!wpa_s
->current_bss
|| wpa_s
->wpa_state
!= WPA_COMPLETED
)
1820 * Check whether AP uses regulatory triplet or channel triplet in
1821 * country info. Right now the operating class of the BSS channel
1822 * width trigger event is "unknown" (IEEE Std 802.11-2012 10.15.12),
1823 * based on the assumption that operating class triplet is not used in
1824 * beacon frame. If the First Channel Number/Operating Extension
1825 * Identifier octet has a positive integer value of 201 or greater,
1826 * then its operating class triplet.
1828 * TODO: If Supported Operating Classes element is present in beacon
1829 * frame, have to lookup operating class in Annex E and fill them in
1832 ie
= wpa_bss_get_ie(wpa_s
->current_bss
, WLAN_EID_COUNTRY
);
1833 if (ie
&& (ie
[1] >= 6) && (ie
[5] >= 201))
1836 os_memset(chan_list
, 0, sizeof(chan_list
));
1838 dl_list_for_each(bss
, &wpa_s
->bss
, struct wpa_bss
, list
) {
1839 /* Skip other band bss */
1840 enum hostapd_hw_mode mode
;
1841 mode
= ieee80211_freq_to_chan(bss
->freq
, &channel
);
1842 if (mode
!= HOSTAPD_MODE_IEEE80211G
&&
1843 mode
!= HOSTAPD_MODE_IEEE80211B
)
1846 ie
= wpa_bss_get_ie(bss
, WLAN_EID_HT_CAP
);
1847 ht_cap
= (ie
&& (ie
[1] == 26)) ? WPA_GET_LE16(ie
+ 2) : 0;
1848 wpa_printf(MSG_DEBUG
, "SME OBSS scan BSS " MACSTR
1849 " freq=%u chan=%u ht_cap=0x%x",
1850 MAC2STR(bss
->bssid
), bss
->freq
, channel
, ht_cap
);
1852 if (!ht_cap
|| (ht_cap
& HT_CAP_INFO_40MHZ_INTOLERANT
)) {
1853 if (ht_cap
& HT_CAP_INFO_40MHZ_INTOLERANT
)
1856 /* Check whether the channel is already considered */
1857 for (i
= 0; i
< num_channels
; i
++) {
1858 if (channel
== chan_list
[i
])
1861 if (i
!= num_channels
)
1864 chan_list
[num_channels
++] = channel
;
1868 sme_send_2040_bss_coex(wpa_s
, chan_list
, num_channels
, num_intol
);
1873 static void wpa_obss_scan_freqs_list(struct wpa_supplicant
*wpa_s
,
1874 struct wpa_driver_scan_params
*params
)
1876 /* Include only affected channels */
1877 struct hostapd_hw_modes
*mode
;
1881 mode
= get_mode(wpa_s
->hw
.modes
, wpa_s
->hw
.num_modes
,
1882 HOSTAPD_MODE_IEEE80211G
);
1884 /* No channels supported in this band - use empty list */
1885 params
->freqs
= os_zalloc(sizeof(int));
1889 if (wpa_s
->sme
.ht_sec_chan
== HT_SEC_CHAN_UNKNOWN
&&
1890 wpa_s
->current_bss
) {
1893 ie
= wpa_bss_get_ie(wpa_s
->current_bss
, WLAN_EID_HT_OPERATION
);
1894 if (ie
&& ie
[1] >= 2) {
1897 o
= ie
[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK
;
1898 if (o
== HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE
)
1899 wpa_s
->sme
.ht_sec_chan
= HT_SEC_CHAN_ABOVE
;
1900 else if (o
== HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW
)
1901 wpa_s
->sme
.ht_sec_chan
= HT_SEC_CHAN_BELOW
;
1905 start
= wpa_s
->assoc_freq
- 10;
1906 end
= wpa_s
->assoc_freq
+ 10;
1907 switch (wpa_s
->sme
.ht_sec_chan
) {
1908 case HT_SEC_CHAN_UNKNOWN
:
1909 /* HT40+ possible on channels 1..9 */
1910 if (wpa_s
->assoc_freq
<= 2452)
1912 /* HT40- possible on channels 5-13 */
1913 if (wpa_s
->assoc_freq
>= 2432)
1916 case HT_SEC_CHAN_ABOVE
:
1919 case HT_SEC_CHAN_BELOW
:
1923 wpa_printf(MSG_DEBUG
,
1924 "OBSS: assoc_freq %d possible affected range %d-%d",
1925 wpa_s
->assoc_freq
, start
, end
);
1927 params
->freqs
= os_calloc(mode
->num_channels
+ 1, sizeof(int));
1928 if (params
->freqs
== NULL
)
1930 for (count
= 0, i
= 0; i
< mode
->num_channels
; i
++) {
1933 if (mode
->channels
[i
].flag
& HOSTAPD_CHAN_DISABLED
)
1935 freq
= mode
->channels
[i
].freq
;
1936 if (freq
- 10 >= end
|| freq
+ 10 <= start
)
1937 continue; /* not affected */
1938 params
->freqs
[count
++] = freq
;
1943 static void sme_obss_scan_timeout(void *eloop_ctx
, void *timeout_ctx
)
1945 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
1946 struct wpa_driver_scan_params params
;
1948 if (!wpa_s
->current_bss
) {
1949 wpa_printf(MSG_DEBUG
, "SME OBSS: Ignore scan request");
1953 os_memset(¶ms
, 0, sizeof(params
));
1954 wpa_obss_scan_freqs_list(wpa_s
, ¶ms
);
1955 params
.low_priority
= 1;
1956 wpa_printf(MSG_DEBUG
, "SME OBSS: Request an OBSS scan");
1958 if (wpa_supplicant_trigger_scan(wpa_s
, ¶ms
))
1959 wpa_printf(MSG_DEBUG
, "SME OBSS: Failed to trigger scan");
1961 wpa_s
->sme
.sched_obss_scan
= 1;
1962 os_free(params
.freqs
);
1964 eloop_register_timeout(wpa_s
->sme
.obss_scan_int
, 0,
1965 sme_obss_scan_timeout
, wpa_s
, NULL
);
1969 void sme_sched_obss_scan(struct wpa_supplicant
*wpa_s
, int enable
)
1972 struct wpa_bss
*bss
= wpa_s
->current_bss
;
1973 struct wpa_ssid
*ssid
= wpa_s
->current_ssid
;
1974 struct hostapd_hw_modes
*hw_mode
= NULL
;
1977 eloop_cancel_timeout(sme_obss_scan_timeout
, wpa_s
, NULL
);
1978 wpa_s
->sme
.sched_obss_scan
= 0;
1979 wpa_s
->sme
.ht_sec_chan
= HT_SEC_CHAN_UNKNOWN
;
1984 * Schedule OBSS scan if driver is using station SME in wpa_supplicant
1985 * or it expects OBSS scan to be performed by wpa_supplicant.
1987 if (!((wpa_s
->drv_flags
& WPA_DRIVER_FLAGS_SME
) ||
1988 (wpa_s
->drv_flags
& WPA_DRIVER_FLAGS_OBSS_SCAN
)) ||
1989 ssid
== NULL
|| ssid
->mode
!= IEEE80211_MODE_INFRA
)
1992 if (!wpa_s
->hw
.modes
)
1995 /* only HT caps in 11g mode are relevant */
1996 for (i
= 0; i
< wpa_s
->hw
.num_modes
; i
++) {
1997 hw_mode
= &wpa_s
->hw
.modes
[i
];
1998 if (hw_mode
->mode
== HOSTAPD_MODE_IEEE80211G
)
2002 /* Driver does not support HT40 for 11g or doesn't have 11g. */
2003 if (i
== wpa_s
->hw
.num_modes
|| !hw_mode
||
2004 !(hw_mode
->ht_capab
& HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
))
2007 if (bss
== NULL
|| bss
->freq
< 2400 || bss
->freq
> 2500)
2008 return; /* Not associated on 2.4 GHz band */
2010 /* Check whether AP supports HT40 */
2011 ie
= wpa_bss_get_ie(wpa_s
->current_bss
, WLAN_EID_HT_CAP
);
2012 if (!ie
|| ie
[1] < 2 ||
2013 !(WPA_GET_LE16(ie
+ 2) & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET
))
2014 return; /* AP does not support HT40 */
2016 ie
= wpa_bss_get_ie(wpa_s
->current_bss
,
2017 WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS
);
2018 if (!ie
|| ie
[1] < 14)
2019 return; /* AP does not request OBSS scans */
2021 wpa_s
->sme
.obss_scan_int
= WPA_GET_LE16(ie
+ 6);
2022 if (wpa_s
->sme
.obss_scan_int
< 10) {
2023 wpa_printf(MSG_DEBUG
, "SME: Invalid OBSS Scan Interval %u "
2024 "replaced with the minimum 10 sec",
2025 wpa_s
->sme
.obss_scan_int
);
2026 wpa_s
->sme
.obss_scan_int
= 10;
2028 wpa_printf(MSG_DEBUG
, "SME: OBSS Scan Interval %u sec",
2029 wpa_s
->sme
.obss_scan_int
);
2030 eloop_register_timeout(wpa_s
->sme
.obss_scan_int
, 0,
2031 sme_obss_scan_timeout
, wpa_s
, NULL
);
2035 #ifdef CONFIG_IEEE80211W
2037 static const unsigned int sa_query_max_timeout
= 1000;
2038 static const unsigned int sa_query_retry_timeout
= 201;
2040 static int sme_check_sa_query_timeout(struct wpa_supplicant
*wpa_s
)
2043 struct os_reltime now
, passed
;
2044 os_get_reltime(&now
);
2045 os_reltime_sub(&now
, &wpa_s
->sme
.sa_query_start
, &passed
);
2046 tu
= (passed
.sec
* 1000000 + passed
.usec
) / 1024;
2047 if (sa_query_max_timeout
< tu
) {
2048 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: SA Query timed out");
2049 sme_stop_sa_query(wpa_s
);
2050 wpa_supplicant_deauthenticate(
2051 wpa_s
, WLAN_REASON_PREV_AUTH_NOT_VALID
);
2059 static void sme_send_sa_query_req(struct wpa_supplicant
*wpa_s
,
2062 u8 req
[2 + WLAN_SA_QUERY_TR_ID_LEN
];
2063 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Sending SA Query Request to "
2064 MACSTR
, MAC2STR(wpa_s
->bssid
));
2065 wpa_hexdump(MSG_DEBUG
, "SME: SA Query Transaction ID",
2066 trans_id
, WLAN_SA_QUERY_TR_ID_LEN
);
2067 req
[0] = WLAN_ACTION_SA_QUERY
;
2068 req
[1] = WLAN_SA_QUERY_REQUEST
;
2069 os_memcpy(req
+ 2, trans_id
, WLAN_SA_QUERY_TR_ID_LEN
);
2070 if (wpa_drv_send_action(wpa_s
, wpa_s
->assoc_freq
, 0, wpa_s
->bssid
,
2071 wpa_s
->own_addr
, wpa_s
->bssid
,
2072 req
, sizeof(req
), 0) < 0)
2073 wpa_msg(wpa_s
, MSG_INFO
, "SME: Failed to send SA Query "
2078 static void sme_sa_query_timer(void *eloop_ctx
, void *timeout_ctx
)
2080 struct wpa_supplicant
*wpa_s
= eloop_ctx
;
2081 unsigned int timeout
, sec
, usec
;
2082 u8
*trans_id
, *nbuf
;
2084 if (wpa_s
->sme
.sa_query_count
> 0 &&
2085 sme_check_sa_query_timeout(wpa_s
))
2088 nbuf
= os_realloc_array(wpa_s
->sme
.sa_query_trans_id
,
2089 wpa_s
->sme
.sa_query_count
+ 1,
2090 WLAN_SA_QUERY_TR_ID_LEN
);
2092 sme_stop_sa_query(wpa_s
);
2095 if (wpa_s
->sme
.sa_query_count
== 0) {
2096 /* Starting a new SA Query procedure */
2097 os_get_reltime(&wpa_s
->sme
.sa_query_start
);
2099 trans_id
= nbuf
+ wpa_s
->sme
.sa_query_count
* WLAN_SA_QUERY_TR_ID_LEN
;
2100 wpa_s
->sme
.sa_query_trans_id
= nbuf
;
2101 wpa_s
->sme
.sa_query_count
++;
2103 if (os_get_random(trans_id
, WLAN_SA_QUERY_TR_ID_LEN
) < 0) {
2104 wpa_printf(MSG_DEBUG
, "Could not generate SA Query ID");
2105 sme_stop_sa_query(wpa_s
);
2109 timeout
= sa_query_retry_timeout
;
2110 sec
= ((timeout
/ 1000) * 1024) / 1000;
2111 usec
= (timeout
% 1000) * 1024;
2112 eloop_register_timeout(sec
, usec
, sme_sa_query_timer
, wpa_s
, NULL
);
2114 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Association SA Query attempt %d",
2115 wpa_s
->sme
.sa_query_count
);
2117 sme_send_sa_query_req(wpa_s
, trans_id
);
2121 static void sme_start_sa_query(struct wpa_supplicant
*wpa_s
)
2123 sme_sa_query_timer(wpa_s
, NULL
);
2127 static void sme_stop_sa_query(struct wpa_supplicant
*wpa_s
)
2129 eloop_cancel_timeout(sme_sa_query_timer
, wpa_s
, NULL
);
2130 os_free(wpa_s
->sme
.sa_query_trans_id
);
2131 wpa_s
->sme
.sa_query_trans_id
= NULL
;
2132 wpa_s
->sme
.sa_query_count
= 0;
2136 void sme_event_unprot_disconnect(struct wpa_supplicant
*wpa_s
, const u8
*sa
,
2137 const u8
*da
, u16 reason_code
)
2139 struct wpa_ssid
*ssid
;
2140 struct os_reltime now
;
2142 if (wpa_s
->wpa_state
!= WPA_COMPLETED
)
2144 ssid
= wpa_s
->current_ssid
;
2145 if (wpas_get_ssid_pmf(wpa_s
, ssid
) == NO_MGMT_FRAME_PROTECTION
)
2147 if (os_memcmp(sa
, wpa_s
->bssid
, ETH_ALEN
) != 0)
2149 if (reason_code
!= WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA
&&
2150 reason_code
!= WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
)
2152 if (wpa_s
->sme
.sa_query_count
> 0)
2155 os_get_reltime(&now
);
2156 if (wpa_s
->sme
.last_unprot_disconnect
.sec
&&
2157 !os_reltime_expired(&now
, &wpa_s
->sme
.last_unprot_disconnect
, 10))
2158 return; /* limit SA Query procedure frequency */
2159 wpa_s
->sme
.last_unprot_disconnect
= now
;
2161 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Unprotected disconnect dropped - "
2162 "possible AP/STA state mismatch - trigger SA Query");
2163 sme_start_sa_query(wpa_s
);
2167 void sme_sa_query_rx(struct wpa_supplicant
*wpa_s
, const u8
*sa
,
2168 const u8
*data
, size_t len
)
2172 if (wpa_s
->sme
.sa_query_trans_id
== NULL
||
2173 len
< 1 + WLAN_SA_QUERY_TR_ID_LEN
||
2174 data
[0] != WLAN_SA_QUERY_RESPONSE
)
2176 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Received SA Query response from "
2177 MACSTR
" (trans_id %02x%02x)", MAC2STR(sa
), data
[1], data
[2]);
2179 if (os_memcmp(sa
, wpa_s
->bssid
, ETH_ALEN
) != 0)
2182 for (i
= 0; i
< wpa_s
->sme
.sa_query_count
; i
++) {
2183 if (os_memcmp(wpa_s
->sme
.sa_query_trans_id
+
2184 i
* WLAN_SA_QUERY_TR_ID_LEN
,
2185 data
+ 1, WLAN_SA_QUERY_TR_ID_LEN
) == 0)
2189 if (i
>= wpa_s
->sme
.sa_query_count
) {
2190 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: No matching SA Query "
2191 "transaction identifier found");
2195 wpa_dbg(wpa_s
, MSG_DEBUG
, "SME: Reply to pending SA Query received "
2196 "from " MACSTR
, MAC2STR(sa
));
2197 sme_stop_sa_query(wpa_s
);
2200 #endif /* CONFIG_IEEE80211W */