]> git.ipfire.org Git - thirdparty/hostap.git/blob - wpa_supplicant/sme.c
FT: Clear SME FT data on disassoc
[thirdparty/hostap.git] / wpa_supplicant / sme.c
1 /*
2 * wpa_supplicant - SME
3 * Copyright (c) 2009-2014, Jouni Malinen <j@w1.fi>
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include "includes.h"
10
11 #include "common.h"
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"
20 #include "config.h"
21 #include "wpa_supplicant_i.h"
22 #include "driver_i.h"
23 #include "wpas_glue.h"
24 #include "wps_supplicant.h"
25 #include "p2p_supplicant.h"
26 #include "notify.h"
27 #include "bss.h"
28 #include "scan.h"
29 #include "sme.h"
30 #include "hs20_supplicant.h"
31
32 #define SME_AUTH_TIMEOUT 5
33 #define SME_ASSOC_TIMEOUT 5
34
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 */
41
42
43 #ifdef CONFIG_SAE
44
45 static int index_within_array(const int *array, int idx)
46 {
47 int i;
48 for (i = 0; i < idx; i++) {
49 if (array[i] <= 0)
50 return 0;
51 }
52 return 1;
53 }
54
55
56 static int sme_set_sae_group(struct wpa_supplicant *wpa_s)
57 {
58 int *groups = wpa_s->conf->sae_groups;
59 int default_groups[] = { 19, 20, 21, 25, 26, 0 };
60
61 if (!groups || groups[0] <= 0)
62 groups = default_groups;
63
64 /* Configuration may have changed, so validate current index */
65 if (!index_within_array(groups, wpa_s->sme.sae_group_index))
66 return -1;
67
68 for (;;) {
69 int group = groups[wpa_s->sme.sae_group_index];
70 if (group <= 0)
71 break;
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);
75 return 0;
76 }
77 wpa_s->sme.sae_group_index++;
78 }
79
80 return -1;
81 }
82
83
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)
87 {
88 struct wpabuf *buf;
89 size_t len;
90 const char *password;
91
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));
96 if (!buf)
97 return NULL;
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);
101 return buf;
102 }
103 #endif /* CONFIG_TESTING_OPTIONS */
104
105 password = ssid->sae_password;
106 if (!password)
107 password = ssid->passphrase;
108 if (!password) {
109 wpa_printf(MSG_DEBUG, "SAE: No password available");
110 return NULL;
111 }
112
113 if (sme_set_sae_group(wpa_s) < 0) {
114 wpa_printf(MSG_DEBUG, "SAE: Failed to select group");
115 return NULL;
116 }
117
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");
122 return NULL;
123 }
124
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);
127 if (buf == NULL)
128 return NULL;
129 if (!external) {
130 wpabuf_put_le16(buf, 1); /* Transaction seq# */
131 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
132 }
133 sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token);
134
135 return buf;
136 }
137
138
139 static struct wpabuf * sme_auth_build_sae_confirm(struct wpa_supplicant *wpa_s,
140 int external)
141 {
142 struct wpabuf *buf;
143
144 buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN);
145 if (buf == NULL)
146 return NULL;
147
148 if (!external) {
149 wpabuf_put_le16(buf, 2); /* Transaction seq# */
150 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
151 }
152 sae_write_confirm(&wpa_s->sme.sae, buf);
153
154 return buf;
155 }
156
157 #endif /* CONFIG_SAE */
158
159
160 /**
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
164 */
165 static void sme_auth_handle_rrm(struct wpa_supplicant *wpa_s,
166 struct wpa_bss *bss)
167 {
168 const u8 rrm_ie_len = 5;
169 u8 *pos;
170 const u8 *rrm_ie;
171
172 wpa_s->rrm.rrm_used = 0;
173
174 wpa_printf(MSG_DEBUG,
175 "RRM: Determining whether RRM can be used - device support: 0x%x",
176 wpa_s->drv_rrm_flags);
177
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");
181 return;
182 }
183
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");
190 return;
191 }
192
193 if (sizeof(wpa_s->sme.assoc_req_ie) <
194 wpa_s->sme.assoc_req_ie_len + rrm_ie_len + 2) {
195 wpa_printf(MSG_INFO,
196 "RRM: Unable to use RRM, no room for RRM IE");
197 return;
198 }
199
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;
204 *pos++ = rrm_ie_len;
205
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;
209
210 *pos |= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
211 WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE |
212 WLAN_RRM_CAPS_BEACON_REPORT_TABLE;
213
214 if (wpa_s->lci)
215 pos[1] |= WLAN_RRM_CAPS_LCI_MEASUREMENT;
216
217 wpa_s->sme.assoc_req_ie_len += rrm_ie_len + 2;
218 wpa_s->rrm.rrm_used = 1;
219 }
220
221
222 static void sme_send_authentication(struct wpa_supplicant *wpa_s,
223 struct wpa_bss *bss, struct wpa_ssid *ssid,
224 int start)
225 {
226 struct wpa_driver_auth_params params;
227 struct wpa_ssid *old_ssid;
228 #ifdef CONFIG_IEEE80211R
229 const u8 *ie;
230 #endif /* CONFIG_IEEE80211R */
231 #if defined(CONFIG_IEEE80211R) || defined(CONFIG_FILS)
232 const u8 *md = NULL;
233 #endif /* CONFIG_IEEE80211R || CONFIG_FILS */
234 int i, bssid_changed;
235 struct wpabuf *resp = NULL;
236 u8 ext_capab[18];
237 int ext_capab_len;
238 int skip_auth;
239
240 if (bss == NULL) {
241 wpa_msg(wpa_s, MSG_ERROR, "SME: No scan result available for "
242 "the network");
243 wpas_connect_work_done(wpa_s);
244 return;
245 }
246
247 skip_auth = wpa_s->conf->reassoc_same_bss_optim &&
248 wpa_s->reassoc_same_bss;
249 wpa_s->current_bss = bss;
250
251 os_memset(&params, 0, sizeof(params));
252 wpa_s->reassociate = 0;
253
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;
259
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;
263
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;
267
268 params.auth_alg = WPA_AUTH_ALG_OPEN;
269 #ifdef IEEE8021X_EAPOL
270 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
271 if (ssid->leap) {
272 if (ssid->non_leap == 0)
273 params.auth_alg = WPA_AUTH_ALG_LEAP;
274 else
275 params.auth_alg |= WPA_AUTH_ALG_LEAP;
276 }
277 }
278 #endif /* IEEE8021X_EAPOL */
279 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x",
280 params.auth_alg);
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);
285 }
286 #ifdef CONFIG_SAE
287 wpa_s->sme.sae_pmksa_caching = 0;
288 if (wpa_key_mgmt_sae(ssid->key_mgmt)) {
289 const u8 *rsn;
290 struct wpa_ie_data ied;
291
292 rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
293 if (!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;
300 } else {
301 wpa_dbg(wpa_s, MSG_DEBUG,
302 "SAE enabled, but target BSS does not advertise SAE AKM for RSN");
303 }
304 }
305 #endif /* CONFIG_SAE */
306
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];
311 }
312 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
313
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);
317 if (bssid_changed)
318 wpas_notify_bssid_changed(wpa_s);
319
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;
325
326 try_opportunistic = (ssid->proactive_key_caching < 0 ?
327 wpa_s->conf->okc :
328 ssid->proactive_key_caching) &&
329 (ssid->proto & WPA_PROTO_RSN);
330 #ifdef CONFIG_FILS
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,
335 wpa_s->current_ssid,
336 try_opportunistic, cache_id,
337 0) == 0)
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);
346 return;
347 }
348 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
349 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
350 /*
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.
354 */
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 "
364 "scan results)");
365 wpas_connect_work_done(wpa_s);
366 return;
367 }
368 #ifdef CONFIG_WPS
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);
377 } else
378 wpa_s->sme.assoc_req_ie_len = 0;
379 wpabuf_free(wps_ie);
380 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
381 #endif /* CONFIG_WPS */
382 } else {
383 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
384 wpa_s->sme.assoc_req_ie_len = 0;
385 }
386
387 #ifdef CONFIG_IEEE80211R
388 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
389 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
390 md = ie + 2;
391 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
392 if (md) {
393 /* Prepare for the next transition */
394 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
395 }
396
397 if (md && !wpa_key_mgmt_ft(ssid->key_mgmt))
398 md = NULL;
399 if (md) {
400 wpa_dbg(wpa_s, MSG_DEBUG, "SME: FT mobility domain %02x%02x",
401 md[0], md[1]);
402
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;
415 }
416
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 "
421 "over-the-air");
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;
425 }
426 }
427 #endif /* CONFIG_IEEE80211R */
428
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 &&
435 _ie.capabilities &
436 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
437 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected AP supports "
438 "MFP: require MFP");
439 wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED;
440 }
441 }
442 #endif /* CONFIG_IEEE80211W */
443
444 #ifdef CONFIG_P2P
445 if (wpa_s->global->p2p) {
446 u8 *pos;
447 size_t len;
448 int res;
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,
453 ssid->p2p_group);
454 if (res >= 0)
455 wpa_s->sme.assoc_req_ie_len += res;
456 }
457 #endif /* CONFIG_P2P */
458
459 #ifdef CONFIG_FST
460 if (wpa_s->fst_ies) {
461 int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
462
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),
468 fst_ies_len);
469 wpa_s->sme.assoc_req_ie_len += fst_ies_len;
470 }
471 }
472 #endif /* CONFIG_FST */
473
474 sme_auth_handle_rrm(wpa_s, bss);
475
476 wpa_s->sme.assoc_req_ie_len += wpas_supp_op_class_ie(
477 wpa_s, bss->freq,
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);
480
481 if (params.p2p)
482 wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
483 else
484 wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
485
486 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
487 sizeof(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)
491 pos += 2 + pos[1];
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);
497 }
498
499 #ifdef CONFIG_HS20
500 if (is_hs20_network(wpa_s, ssid, bss)) {
501 struct wpabuf *hs20;
502
503 hs20 = wpabuf_alloc(20 + MAX_ROAMING_CONS_OI_LEN);
504 if (hs20) {
505 int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
506 size_t len;
507
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);
517 }
518 wpabuf_free(hs20);
519 }
520 }
521 #endif /* CONFIG_HS20 */
522
523 if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
524 struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
525 size_t len;
526
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);
534 }
535 }
536
537 #ifdef CONFIG_MBO
538 if (wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE)) {
539 int len;
540
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);
545 if (len >= 0)
546 wpa_s->sme.assoc_req_ie_len += len;
547 }
548 #endif /* CONFIG_MBO */
549
550 #ifdef CONFIG_SAE
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;
559 }
560
561 if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE) {
562 if (start)
563 resp = sme_auth_build_sae_commit(wpa_s, ssid,
564 bss->bssid, 0);
565 else
566 resp = sme_auth_build_sae_confirm(wpa_s, 0);
567 if (resp == NULL) {
568 wpas_connection_failed(wpa_s, bss->bssid);
569 return;
570 }
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;
574 }
575 #endif /* CONFIG_SAE */
576
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);
581
582 #ifdef CONFIG_FILS
583 /* TODO: FILS operations can in some cases be done between different
584 * network_ctx (i.e., same credentials can be used with multiple
585 * networks). */
586 if (params.auth_alg == WPA_AUTH_ALG_OPEN &&
587 wpa_key_mgmt_fils(ssid->key_mgmt)) {
588 const u8 *indic;
589 u16 fils_info;
590
591 /*
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));
602 goto no_fils;
603 }
604
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));
610 goto no_fils;
611 }
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));
616 goto no_fils;
617 }
618
619 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
620 ssid, 0,
621 wpa_bss_get_fils_cache_id(bss),
622 0) == 0)
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);
626 if (resp) {
627 int auth_alg;
628
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);
633 else
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;
642 }
643 }
644 no_fils:
645 #endif /* CONFIG_FILS */
646
647 wpa_supplicant_cancel_sched_scan(wpa_s);
648 wpa_supplicant_cancel_scan(wpa_s);
649
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);
653
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);
659
660 #ifdef CONFIG_HS20
661 hs20_configure_frame_filters(wpa_s);
662 #endif /* CONFIG_HS20 */
663
664 #ifdef CONFIG_P2P
665 /*
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.
669 */
670 if (wpa_s->num_multichan_concurrent < 2) {
671 int freq, num;
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)",
676 freq, params.freq);
677 if (wpas_p2p_handle_frequency_conflicts(wpa_s,
678 params.freq,
679 ssid) < 0) {
680 wpas_connection_failed(wpa_s, bss->bssid);
681 wpa_supplicant_mark_disassoc(wpa_s);
682 wpabuf_free(resp);
683 wpas_connect_work_done(wpa_s);
684 return;
685 }
686 }
687 }
688 #endif /* CONFIG_P2P */
689
690 if (skip_auth) {
691 wpa_msg(wpa_s, MSG_DEBUG,
692 "SME: Skip authentication step on reassoc-to-same-BSS");
693 wpabuf_free(resp);
694 sme_associate(wpa_s, ssid->mode, bss->bssid, WLAN_AUTH_OPEN);
695 return;
696 }
697
698
699 wpa_s->sme.auth_alg = params.auth_alg;
700 if (wpa_drv_authenticate(wpa_s, &params) < 0) {
701 wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the "
702 "driver failed");
703 wpas_connection_failed(wpa_s, bss->bssid);
704 wpa_supplicant_mark_disassoc(wpa_s);
705 wpabuf_free(resp);
706 wpas_connect_work_done(wpa_s);
707 return;
708 }
709
710 eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s,
711 NULL);
712
713 /*
714 * Association will be started based on the authentication event from
715 * the driver.
716 */
717
718 wpabuf_free(resp);
719 }
720
721
722 static void sme_auth_start_cb(struct wpa_radio_work *work, int deinit)
723 {
724 struct wpa_connect_work *cwork = work->ctx;
725 struct wpa_supplicant *wpa_s = work->wpa_s;
726
727 if (deinit) {
728 if (work->started)
729 wpa_s->connect_work = NULL;
730
731 wpas_connect_work_free(cwork);
732 return;
733 }
734
735 wpa_s->connect_work = work;
736
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);
742 return;
743 }
744
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);
748
749 sme_send_authentication(wpa_s, cwork->bss, cwork->ssid, 1);
750 }
751
752
753 void sme_authenticate(struct wpa_supplicant *wpa_s,
754 struct wpa_bss *bss, struct wpa_ssid *ssid)
755 {
756 struct wpa_connect_work *cwork;
757
758 if (bss == NULL || ssid == NULL)
759 return;
760 if (wpa_s->connect_work) {
761 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reject sme_authenticate() call since connect_work exist");
762 return;
763 }
764
765 if (radio_work_pending(wpa_s, "sme-connect")) {
766 /*
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.
770 */
771 wpa_dbg(wpa_s, MSG_DEBUG,
772 "SME: Remove previous pending sme-connect");
773 radio_remove_works(wpa_s, "sme-connect", 0);
774 }
775
776 wpas_abort_ongoing_scan(wpa_s);
777
778 cwork = os_zalloc(sizeof(*cwork));
779 if (cwork == NULL)
780 return;
781 cwork->bss = bss;
782 cwork->ssid = ssid;
783 cwork->sme = 1;
784
785 #ifdef CONFIG_SAE
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 */
790
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);
794 }
795
796
797 #ifdef CONFIG_SAE
798
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)
803 {
804 struct ieee80211_mgmt *resp;
805
806 resp = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
807 u.auth.variable));
808
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;
818 if (params)
819 wpabuf_put_buf(buf, params);
820
821 return 0;
822 }
823
824
825 static void sme_external_auth_send_sae_commit(struct wpa_supplicant *wpa_s,
826 const u8 *bssid,
827 struct wpa_ssid *ssid)
828 {
829 struct wpabuf *resp, *buf;
830
831 resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1);
832 if (!resp)
833 return;
834
835 wpa_s->sme.sae.state = SAE_COMMITTED;
836 buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + wpabuf_len(resp));
837 if (!buf) {
838 wpabuf_free(resp);
839 return;
840 }
841
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);
846 wpabuf_free(resp);
847 wpabuf_free(buf);
848 }
849
850
851 static void sme_send_external_auth_status(struct wpa_supplicant *wpa_s,
852 u16 status)
853 {
854 struct external_auth params;
855
856 os_memset(&params, 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, &params);
863 }
864
865
866 static void sme_handle_external_auth_start(struct wpa_supplicant *wpa_s,
867 union wpa_event_data *data)
868 {
869 struct wpa_ssid *ssid;
870 size_t ssid_str_len = data->external_auth.ssid_len;
871 u8 *ssid_str = data->external_auth.ssid;
872
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)
878 break;
879 }
880 if (ssid)
881 sme_external_auth_send_sae_commit(wpa_s,
882 data->external_auth.bssid,
883 ssid);
884 else
885 sme_send_external_auth_status(wpa_s,
886 WLAN_STATUS_UNSPECIFIED_FAILURE);
887 }
888
889
890 static void sme_external_auth_send_sae_confirm(struct wpa_supplicant *wpa_s,
891 const u8 *da)
892 {
893 struct wpabuf *resp, *buf;
894
895 resp = sme_auth_build_sae_confirm(wpa_s, 1);
896 if (!resp) {
897 wpa_printf(MSG_DEBUG, "SAE: Confirm message buf alloc failure");
898 return;
899 }
900
901 wpa_s->sme.sae.state = SAE_CONFIRMED;
902 buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN + wpabuf_len(resp));
903 if (!buf) {
904 wpa_printf(MSG_DEBUG, "SAE: Auth Confirm buf alloc failure");
905 wpabuf_free(resp);
906 return;
907 }
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);
912 wpabuf_free(resp);
913 wpabuf_free(buf);
914 }
915
916
917 void sme_external_auth_trigger(struct wpa_supplicant *wpa_s,
918 union wpa_event_data *data)
919 {
920 if (RSN_SELECTOR_GET(&data->external_auth.key_mgmt_suite) !=
921 RSN_AUTH_KEY_MGMT_SAE)
922 return;
923
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);
936 }
937 }
938
939
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)
943 {
944 int *groups;
945
946 wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE authentication transaction %u "
947 "status code %u", auth_transaction, status_code);
948
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 };
954 u16 group;
955
956 groups = wpa_s->conf->sae_groups;
957 if (!groups || groups[0] <= 0)
958 groups = default_groups;
959
960 if (len < sizeof(le16)) {
961 wpa_dbg(wpa_s, MSG_DEBUG,
962 "SME: Too short SAE anti-clogging token request");
963 return -1;
964 }
965 group = WPA_GET_LE16(data);
966 wpa_dbg(wpa_s, MSG_DEBUG,
967 "SME: SAE anti-clogging token requested (group %u)",
968 group);
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",
973 group);
974 return -1;
975 }
976 wpabuf_free(wpa_s->sme.sae_token);
977 wpa_s->sme.sae_token = wpabuf_alloc_copy(data + sizeof(le16),
978 len - sizeof(le16));
979 if (!external)
980 sme_send_authentication(wpa_s, wpa_s->current_bss,
981 wpa_s->current_ssid, 1);
982 else
983 sme_external_auth_send_sae_commit(
984 wpa_s, wpa_s->sme.ext_auth.bssid,
985 wpa_s->current_ssid);
986 return 0;
987 }
988
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");
998 if (!external)
999 sme_send_authentication(wpa_s, wpa_s->current_bss,
1000 wpa_s->current_ssid, 1);
1001 else
1002 sme_external_auth_send_sae_commit(
1003 wpa_s, wpa_s->sme.ext_auth.bssid,
1004 wpa_s->current_ssid);
1005 return 0;
1006 }
1007
1008 if (status_code != WLAN_STATUS_SUCCESS)
1009 return -1;
1010
1011 if (auth_transaction == 1) {
1012 u16 res;
1013
1014 groups = wpa_s->conf->sae_groups;
1015
1016 wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit");
1017 if ((!external && wpa_s->current_bss == NULL) ||
1018 wpa_s->current_ssid == NULL)
1019 return -1;
1020 if (wpa_s->sme.sae.state != SAE_COMMITTED)
1021 return -1;
1022 if (groups && groups[0] <= 0)
1023 groups = NULL;
1024 res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
1025 groups);
1026 if (res == SAE_SILENTLY_DISCARD) {
1027 wpa_printf(MSG_DEBUG,
1028 "SAE: Drop commit message due to reflection attack");
1029 return 0;
1030 }
1031 if (res != WLAN_STATUS_SUCCESS)
1032 return -1;
1033
1034 if (sae_process_commit(&wpa_s->sme.sae) < 0) {
1035 wpa_printf(MSG_DEBUG, "SAE: Failed to process peer "
1036 "commit");
1037 return -1;
1038 }
1039
1040 wpabuf_free(wpa_s->sme.sae_token);
1041 wpa_s->sme.sae_token = NULL;
1042 if (!external)
1043 sme_send_authentication(wpa_s, wpa_s->current_bss,
1044 wpa_s->current_ssid, 0);
1045 else
1046 sme_external_auth_send_sae_confirm(wpa_s, sa);
1047 return 0;
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)
1051 return -1;
1052 if (sae_check_confirm(&wpa_s->sme.sae, data, len) < 0)
1053 return -1;
1054 wpa_s->sme.sae.state = SAE_ACCEPTED;
1055 sae_clear_temp_data(&wpa_s->sme.sae);
1056
1057 if (external) {
1058 /* Report success to driver */
1059 sme_send_external_auth_status(wpa_s,
1060 WLAN_STATUS_SUCCESS);
1061 }
1062
1063 return 1;
1064 }
1065
1066 return -1;
1067 }
1068
1069
1070 void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s,
1071 const u8 *auth_frame, size_t len)
1072 {
1073 const struct ieee80211_mgmt *header;
1074 size_t auth_length;
1075
1076 header = (const struct ieee80211_mgmt *) auth_frame;
1077 auth_length = IEEE80211_HDRLEN + sizeof(header->u.auth);
1078
1079 if (len < auth_length) {
1080 /* Notify failure to the driver */
1081 sme_send_external_auth_status(wpa_s,
1082 WLAN_STATUS_UNSPECIFIED_FAILURE);
1083 return;
1084 }
1085
1086 if (header->u.auth.auth_alg == WLAN_AUTH_SAE) {
1087 int res;
1088
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);
1093 if (res < 0) {
1094 /* Notify failure to the driver */
1095 sme_send_external_auth_status(
1096 wpa_s, WLAN_STATUS_UNSPECIFIED_FAILURE);
1097 return;
1098 }
1099 if (res != 1)
1100 return;
1101
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);
1106 }
1107 }
1108
1109 #endif /* CONFIG_SAE */
1110
1111
1112 void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
1113 {
1114 struct wpa_ssid *ssid = wpa_s->current_ssid;
1115
1116 if (ssid == NULL) {
1117 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event "
1118 "when network is not selected");
1119 return;
1120 }
1121
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");
1125 return;
1126 }
1127
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));
1132 return;
1133 }
1134
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);
1141
1142 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
1143
1144 #ifdef CONFIG_SAE
1145 if (data->auth.auth_type == WLAN_AUTH_SAE) {
1146 int res;
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);
1150 if (res < 0) {
1151 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
1152 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1153
1154 }
1155 if (res != 1)
1156 return;
1157
1158 wpa_printf(MSG_DEBUG, "SME: SAE completed - setting PMK for "
1159 "4-way handshake");
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);
1162 }
1163 #endif /* CONFIG_SAE */
1164
1165 if (data->auth.status_code != WLAN_STATUS_SUCCESS) {
1166 char *ie_txt = NULL;
1167
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);
1171 if (ie_txt) {
1172 wpa_snprintf_hex(ie_txt, buflen, data->auth.ies,
1173 data->auth.ies_len);
1174 }
1175 }
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 : "");
1182 os_free(ie_txt);
1183
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);
1190 return;
1191 }
1192
1193 wpas_connect_work_done(wpa_s);
1194
1195 switch (data->auth.auth_type) {
1196 case WLAN_AUTH_OPEN:
1197 wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED;
1198
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);
1202 return;
1203
1204 case WLAN_AUTH_SHARED_KEY:
1205 wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_LEAP;
1206
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);
1210 return;
1211
1212 default:
1213 return;
1214 }
1215 }
1216
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;
1221
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);
1225 }
1226 if (wpa_ft_process_response(wpa_s->wpa, data->auth.ies,
1227 data->auth.ies_len, 0,
1228 data->auth.peer,
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="
1233 MACSTR
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);
1239 return;
1240 }
1241 }
1242 #endif /* CONFIG_IEEE80211R */
1243
1244 #ifdef CONFIG_FILS
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;
1248
1249 expect_auth_type = wpa_s->sme.auth_alg ==
1250 WPA_AUTH_ALG_FILS_SK_PFS ? WLAN_AUTH_FILS_SK_PFS :
1251 WLAN_AUTH_FILS_SK;
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="
1257 MACSTR
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);
1263 return;
1264 }
1265
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="
1271 MACSTR
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);
1277 return;
1278 }
1279 }
1280 #endif /* CONFIG_FILS */
1281
1282 sme_associate(wpa_s, ssid->mode, data->auth.peer,
1283 data->auth.auth_type);
1284 }
1285
1286
1287 #ifdef CONFIG_FILS
1288 #ifdef CONFIG_IEEE80211R
1289 static void remove_ie(u8 *buf, size_t *len, u8 eid)
1290 {
1291 u8 *pos, *next, *end;
1292
1293 pos = (u8 *) get_ie(buf, *len, eid);
1294 if (pos) {
1295 next = pos + 2 + pos[1];
1296 end = buf + *len;
1297 *len -= 2 + pos[1];
1298 os_memmove(pos, next, end - next);
1299 }
1300 }
1301 #endif /* CONFIG_IEEE80211R */
1302 #endif /* CONFIG_FILS */
1303
1304
1305 void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
1306 const u8 *bssid, u16 auth_type)
1307 {
1308 struct wpa_driver_associate_params params;
1309 struct ieee802_11_elems elems;
1310 #ifdef CONFIG_FILS
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 */
1321
1322 os_memset(&params, 0, sizeof(params));
1323
1324 #ifdef CONFIG_FILS
1325 if (auth_type == WLAN_AUTH_FILS_SK ||
1326 auth_type == WLAN_AUTH_FILS_SK_PFS) {
1327 struct wpabuf *buf;
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;
1333
1334 dl_list_for_each(req, &wpa_s->fils_hlp_req, struct fils_hlp_req,
1335 list) {
1336 hlp[num_hlp] = wpabuf_alloc(2 * ETH_ALEN + 6 +
1337 wpabuf_len(req->pkt));
1338 if (!hlp[num_hlp])
1339 break;
1340 wpabuf_put_data(hlp[num_hlp], req->dst, ETH_ALEN);
1341 wpabuf_put_data(hlp[num_hlp], wpa_s->own_addr,
1342 ETH_ALEN);
1343 wpabuf_put_data(hlp[num_hlp],
1344 "\xaa\xaa\x03\x00\x00\x00", 6);
1345 wpabuf_put_buf(hlp[num_hlp], req->pkt);
1346 num_hlp++;
1347 if (num_hlp >= max_hlp)
1348 break;
1349 }
1350
1351 buf = fils_build_assoc_req(wpa_s->wpa, &params.fils_kek,
1352 &params.fils_kek_len, &snonce,
1353 &anonce,
1354 (const struct wpabuf **) hlp,
1355 num_hlp);
1356 for (i = 0; i < num_hlp; i++)
1357 wpabuf_free(hlp[i]);
1358 if (!buf)
1359 return;
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,
1370 WLAN_EID_RSN);
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);
1382 }
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");
1389 wpabuf_free(buf);
1390 return;
1391 }
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);
1395 wpabuf_free(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);
1399
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);
1404 }
1405 #endif /* CONFIG_FILS */
1406
1407 #ifdef CONFIG_OWE
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");
1412 } else
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;
1417 u16 group;
1418
1419 if (wpa_s->current_ssid && wpa_s->current_ssid->owe_group) {
1420 group = wpa_s->current_ssid->owe_group;
1421 } else {
1422 if (wpa_s->last_owe_group == 19)
1423 group = 20;
1424 else if (wpa_s->last_owe_group == 20)
1425 group = 21;
1426 else
1427 group = OWE_DH_GROUP;
1428 }
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);
1432 if (!owe_ie) {
1433 wpa_printf(MSG_ERROR,
1434 "OWE: Failed to build IE for Association Request frame");
1435 return;
1436 }
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);
1442 return;
1443 }
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);
1448 }
1449 #endif /* CONFIG_OWE */
1450
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, &params);
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, &params);
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;
1483 }
1484 #endif /* CONFIG_IEEE80211R */
1485 params.mode = mode;
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;
1490
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) : "",
1494 params.freq.freq);
1495
1496 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
1497
1498 if (params.wpa_ie == NULL ||
1499 ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0)
1500 < 0) {
1501 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Could not parse own IEs?!");
1502 os_memset(&elems, 0, sizeof(elems));
1503 }
1504 if (elems.rsn_ie) {
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);
1516 } else
1517 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1518 if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group)
1519 params.p2p = 1;
1520
1521 if (wpa_s->p2pdev->set_sta_uapsd)
1522 params.uapsd = wpa_s->p2pdev->sta_uapsd;
1523 else
1524 params.uapsd = -1;
1525
1526 if (wpa_drv_associate(wpa_s, &params) < 0) {
1527 wpa_msg(wpa_s, MSG_INFO, "SME: Association request to the "
1528 "driver failed");
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);
1532 return;
1533 }
1534
1535 eloop_register_timeout(SME_ASSOC_TIMEOUT, 0, sme_assoc_timer, wpa_s,
1536 NULL);
1537
1538 #ifdef CONFIG_TESTING_OPTIONS
1539 wpabuf_free(wpa_s->last_assoc_req_wpa_ie);
1540 wpa_s->last_assoc_req_wpa_ie = NULL;
1541 if (params.wpa_ie)
1542 wpa_s->last_assoc_req_wpa_ie =
1543 wpabuf_alloc_copy(params.wpa_ie, params.wpa_ie_len);
1544 #endif /* CONFIG_TESTING_OPTIONS */
1545 }
1546
1547
1548 int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
1549 const u8 *ies, size_t ies_len)
1550 {
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;
1557 return 0;
1558 }
1559
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)
1565 return -1;
1566 wpa_s->sme.ft_ies_len = ies_len;
1567 return 0;
1568 }
1569
1570
1571 static void sme_deauth(struct wpa_supplicant *wpa_s)
1572 {
1573 int bssid_changed;
1574
1575 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
1576
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 "
1580 "failed");
1581 }
1582 wpa_s->sme.prev_bssid_set = 0;
1583
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);
1588 if (bssid_changed)
1589 wpas_notify_bssid_changed(wpa_s);
1590 }
1591
1592
1593 void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
1594 union wpa_event_data *data)
1595 {
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);
1599
1600 eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
1601
1602 #ifdef CONFIG_SAE
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;
1612
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);
1618 return;
1619 }
1620 }
1621 #endif /* CONFIG_SAE */
1622
1623 /*
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.
1629 */
1630 sme_deauth(wpa_s);
1631 }
1632
1633
1634 void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
1635 union wpa_event_data *data)
1636 {
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);
1640 }
1641
1642
1643 void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
1644 union wpa_event_data *data)
1645 {
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);
1649 }
1650
1651
1652 void sme_event_disassoc(struct wpa_supplicant *wpa_s,
1653 struct disassoc_info *info)
1654 {
1655 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Disassociation event received");
1656 if (wpa_s->sme.prev_bssid_set) {
1657 /*
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.
1662 */
1663 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Deauthenticate to clear "
1664 "driver state");
1665 wpa_drv_deauthenticate(wpa_s, wpa_s->sme.prev_bssid,
1666 WLAN_REASON_DEAUTH_LEAVING);
1667 }
1668 }
1669
1670
1671 static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx)
1672 {
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");
1676 sme_deauth(wpa_s);
1677 }
1678 }
1679
1680
1681 static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx)
1682 {
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");
1686 sme_deauth(wpa_s);
1687 }
1688 }
1689
1690
1691 void sme_state_changed(struct wpa_supplicant *wpa_s)
1692 {
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);
1698 }
1699
1700
1701 void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
1702 const u8 *prev_pending_bssid)
1703 {
1704 /*
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.
1708 */
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);
1713
1714 /*
1715 * Re-arm authentication timer in case auth fails for whatever reason.
1716 */
1717 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
1718 eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s,
1719 NULL);
1720 }
1721
1722
1723 void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s)
1724 {
1725 wpa_s->sme.prev_bssid_set = 0;
1726 #ifdef CONFIG_SAE
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 */
1735 }
1736
1737
1738 void sme_deinit(struct wpa_supplicant *wpa_s)
1739 {
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);
1747
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);
1751 }
1752
1753
1754 static void sme_send_2040_bss_coex(struct wpa_supplicant *wpa_s,
1755 const u8 *chan_list, u8 num_channels,
1756 u8 num_intol)
1757 {
1758 struct ieee80211_2040_bss_coex_ie *bc_ie;
1759 struct ieee80211_2040_intol_chan_report *ic_report;
1760 struct wpabuf *buf;
1761
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);
1767
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) +
1771 num_channels);
1772 if (buf == NULL)
1773 return;
1774
1775 wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
1776 wpabuf_put_u8(buf, WLAN_PA_20_40_BSS_COEX);
1777
1778 bc_ie = wpabuf_put(buf, sizeof(*bc_ie));
1779 bc_ie->element_id = WLAN_EID_20_40_BSS_COEXISTENCE;
1780 bc_ie->length = 1;
1781 if (num_intol)
1782 bc_ie->coex_param |= WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ;
1783
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,
1790 num_channels);
1791 }
1792
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");
1798 }
1799
1800 wpabuf_free(buf);
1801 }
1802
1803
1804 int sme_proc_obss_scan(struct wpa_supplicant *wpa_s)
1805 {
1806 struct wpa_bss *bss;
1807 const u8 *ie;
1808 u16 ht_cap;
1809 u8 chan_list[P2P_MAX_CHANNELS], channel;
1810 u8 num_channels = 0, num_intol = 0, i;
1811
1812 if (!wpa_s->sme.sched_obss_scan)
1813 return 0;
1814
1815 wpa_s->sme.sched_obss_scan = 0;
1816 if (!wpa_s->current_bss || wpa_s->wpa_state != WPA_COMPLETED)
1817 return 1;
1818
1819 /*
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.
1827 *
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
1830 * 2040 coex frame.
1831 */
1832 ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_COUNTRY);
1833 if (ie && (ie[1] >= 6) && (ie[5] >= 201))
1834 return 1;
1835
1836 os_memset(chan_list, 0, sizeof(chan_list));
1837
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)
1844 continue;
1845
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);
1851
1852 if (!ht_cap || (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)) {
1853 if (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)
1854 num_intol++;
1855
1856 /* Check whether the channel is already considered */
1857 for (i = 0; i < num_channels; i++) {
1858 if (channel == chan_list[i])
1859 break;
1860 }
1861 if (i != num_channels)
1862 continue;
1863
1864 chan_list[num_channels++] = channel;
1865 }
1866 }
1867
1868 sme_send_2040_bss_coex(wpa_s, chan_list, num_channels, num_intol);
1869 return 1;
1870 }
1871
1872
1873 static void wpa_obss_scan_freqs_list(struct wpa_supplicant *wpa_s,
1874 struct wpa_driver_scan_params *params)
1875 {
1876 /* Include only affected channels */
1877 struct hostapd_hw_modes *mode;
1878 int count, i;
1879 int start, end;
1880
1881 mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
1882 HOSTAPD_MODE_IEEE80211G);
1883 if (mode == NULL) {
1884 /* No channels supported in this band - use empty list */
1885 params->freqs = os_zalloc(sizeof(int));
1886 return;
1887 }
1888
1889 if (wpa_s->sme.ht_sec_chan == HT_SEC_CHAN_UNKNOWN &&
1890 wpa_s->current_bss) {
1891 const u8 *ie;
1892
1893 ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_OPERATION);
1894 if (ie && ie[1] >= 2) {
1895 u8 o;
1896
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;
1902 }
1903 }
1904
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)
1911 start -= 20;
1912 /* HT40- possible on channels 5-13 */
1913 if (wpa_s->assoc_freq >= 2432)
1914 end += 20;
1915 break;
1916 case HT_SEC_CHAN_ABOVE:
1917 end += 20;
1918 break;
1919 case HT_SEC_CHAN_BELOW:
1920 start -= 20;
1921 break;
1922 }
1923 wpa_printf(MSG_DEBUG,
1924 "OBSS: assoc_freq %d possible affected range %d-%d",
1925 wpa_s->assoc_freq, start, end);
1926
1927 params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
1928 if (params->freqs == NULL)
1929 return;
1930 for (count = 0, i = 0; i < mode->num_channels; i++) {
1931 int freq;
1932
1933 if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
1934 continue;
1935 freq = mode->channels[i].freq;
1936 if (freq - 10 >= end || freq + 10 <= start)
1937 continue; /* not affected */
1938 params->freqs[count++] = freq;
1939 }
1940 }
1941
1942
1943 static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx)
1944 {
1945 struct wpa_supplicant *wpa_s = eloop_ctx;
1946 struct wpa_driver_scan_params params;
1947
1948 if (!wpa_s->current_bss) {
1949 wpa_printf(MSG_DEBUG, "SME OBSS: Ignore scan request");
1950 return;
1951 }
1952
1953 os_memset(&params, 0, sizeof(params));
1954 wpa_obss_scan_freqs_list(wpa_s, &params);
1955 params.low_priority = 1;
1956 wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan");
1957
1958 if (wpa_supplicant_trigger_scan(wpa_s, &params))
1959 wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan");
1960 else
1961 wpa_s->sme.sched_obss_scan = 1;
1962 os_free(params.freqs);
1963
1964 eloop_register_timeout(wpa_s->sme.obss_scan_int, 0,
1965 sme_obss_scan_timeout, wpa_s, NULL);
1966 }
1967
1968
1969 void sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable)
1970 {
1971 const u8 *ie;
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;
1975 int i;
1976
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;
1980 if (!enable)
1981 return;
1982
1983 /*
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.
1986 */
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)
1990 return;
1991
1992 if (!wpa_s->hw.modes)
1993 return;
1994
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)
1999 break;
2000 }
2001
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))
2005 return;
2006
2007 if (bss == NULL || bss->freq < 2400 || bss->freq > 2500)
2008 return; /* Not associated on 2.4 GHz band */
2009
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 */
2015
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 */
2020
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;
2027 }
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);
2032 }
2033
2034
2035 #ifdef CONFIG_IEEE80211W
2036
2037 static const unsigned int sa_query_max_timeout = 1000;
2038 static const unsigned int sa_query_retry_timeout = 201;
2039
2040 static int sme_check_sa_query_timeout(struct wpa_supplicant *wpa_s)
2041 {
2042 u32 tu;
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);
2052 return 1;
2053 }
2054
2055 return 0;
2056 }
2057
2058
2059 static void sme_send_sa_query_req(struct wpa_supplicant *wpa_s,
2060 const u8 *trans_id)
2061 {
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 "
2074 "Request");
2075 }
2076
2077
2078 static void sme_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
2079 {
2080 struct wpa_supplicant *wpa_s = eloop_ctx;
2081 unsigned int timeout, sec, usec;
2082 u8 *trans_id, *nbuf;
2083
2084 if (wpa_s->sme.sa_query_count > 0 &&
2085 sme_check_sa_query_timeout(wpa_s))
2086 return;
2087
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);
2091 if (nbuf == NULL) {
2092 sme_stop_sa_query(wpa_s);
2093 return;
2094 }
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);
2098 }
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++;
2102
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);
2106 return;
2107 }
2108
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);
2113
2114 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association SA Query attempt %d",
2115 wpa_s->sme.sa_query_count);
2116
2117 sme_send_sa_query_req(wpa_s, trans_id);
2118 }
2119
2120
2121 static void sme_start_sa_query(struct wpa_supplicant *wpa_s)
2122 {
2123 sme_sa_query_timer(wpa_s, NULL);
2124 }
2125
2126
2127 static void sme_stop_sa_query(struct wpa_supplicant *wpa_s)
2128 {
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;
2133 }
2134
2135
2136 void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa,
2137 const u8 *da, u16 reason_code)
2138 {
2139 struct wpa_ssid *ssid;
2140 struct os_reltime now;
2141
2142 if (wpa_s->wpa_state != WPA_COMPLETED)
2143 return;
2144 ssid = wpa_s->current_ssid;
2145 if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION)
2146 return;
2147 if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0)
2148 return;
2149 if (reason_code != WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA &&
2150 reason_code != WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA)
2151 return;
2152 if (wpa_s->sme.sa_query_count > 0)
2153 return;
2154
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;
2160
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);
2164 }
2165
2166
2167 void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa,
2168 const u8 *data, size_t len)
2169 {
2170 int i;
2171
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)
2175 return;
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]);
2178
2179 if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0)
2180 return;
2181
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)
2186 break;
2187 }
2188
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");
2192 return;
2193 }
2194
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);
2198 }
2199
2200 #endif /* CONFIG_IEEE80211W */