]> git.ipfire.org Git - thirdparty/hostap.git/blob - wpa_supplicant/sme.c
SAE: Reuse previously generated PWE on a retry with the same AP
[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 "common/ocv.h"
16 #include "eapol_supp/eapol_supp_sm.h"
17 #include "common/wpa_common.h"
18 #include "common/sae.h"
19 #include "rsn_supp/wpa.h"
20 #include "rsn_supp/pmksa_cache.h"
21 #include "config.h"
22 #include "wpa_supplicant_i.h"
23 #include "driver_i.h"
24 #include "wpas_glue.h"
25 #include "wps_supplicant.h"
26 #include "p2p_supplicant.h"
27 #include "notify.h"
28 #include "bss.h"
29 #include "scan.h"
30 #include "sme.h"
31 #include "hs20_supplicant.h"
32
33 #define SME_AUTH_TIMEOUT 5
34 #define SME_ASSOC_TIMEOUT 5
35
36 static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx);
37 static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx);
38 static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx);
39 #ifdef CONFIG_IEEE80211W
40 static void sme_stop_sa_query(struct wpa_supplicant *wpa_s);
41 #endif /* CONFIG_IEEE80211W */
42
43
44 #ifdef CONFIG_SAE
45
46 static int index_within_array(const int *array, int idx)
47 {
48 int i;
49 for (i = 0; i < idx; i++) {
50 if (array[i] <= 0)
51 return 0;
52 }
53 return 1;
54 }
55
56
57 static int sme_set_sae_group(struct wpa_supplicant *wpa_s)
58 {
59 int *groups = wpa_s->conf->sae_groups;
60 int default_groups[] = { 19, 20, 21, 0 };
61
62 if (!groups || groups[0] <= 0)
63 groups = default_groups;
64
65 /* Configuration may have changed, so validate current index */
66 if (!index_within_array(groups, wpa_s->sme.sae_group_index))
67 return -1;
68
69 for (;;) {
70 int group = groups[wpa_s->sme.sae_group_index];
71 if (group <= 0)
72 break;
73 if (sae_set_group(&wpa_s->sme.sae, group) == 0) {
74 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected SAE group %d",
75 wpa_s->sme.sae.group);
76 return 0;
77 }
78 wpa_s->sme.sae_group_index++;
79 }
80
81 return -1;
82 }
83
84
85 static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
86 struct wpa_ssid *ssid,
87 const u8 *bssid, int external,
88 int reuse)
89 {
90 struct wpabuf *buf;
91 size_t len;
92 const char *password;
93
94 #ifdef CONFIG_TESTING_OPTIONS
95 if (wpa_s->sae_commit_override) {
96 wpa_printf(MSG_DEBUG, "SAE: TESTING - commit override");
97 buf = wpabuf_alloc(4 + wpabuf_len(wpa_s->sae_commit_override));
98 if (!buf)
99 return NULL;
100 wpabuf_put_le16(buf, 1); /* Transaction seq# */
101 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
102 wpabuf_put_buf(buf, wpa_s->sae_commit_override);
103 return buf;
104 }
105 #endif /* CONFIG_TESTING_OPTIONS */
106
107 password = ssid->sae_password;
108 if (!password)
109 password = ssid->passphrase;
110 if (!password) {
111 wpa_printf(MSG_DEBUG, "SAE: No password available");
112 return NULL;
113 }
114
115 if (reuse && wpa_s->sme.sae.tmp &&
116 os_memcmp(bssid, wpa_s->sme.sae.tmp->bssid, ETH_ALEN) == 0) {
117 wpa_printf(MSG_DEBUG,
118 "SAE: Reuse previously generated PWE on a retry with the same AP");
119 goto reuse_data;
120 }
121 if (sme_set_sae_group(wpa_s) < 0) {
122 wpa_printf(MSG_DEBUG, "SAE: Failed to select group");
123 return NULL;
124 }
125
126 if (sae_prepare_commit(wpa_s->own_addr, bssid,
127 (u8 *) password, os_strlen(password),
128 ssid->sae_password_id,
129 &wpa_s->sme.sae) < 0) {
130 wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
131 return NULL;
132 }
133 if (wpa_s->sme.sae.tmp)
134 os_memcpy(wpa_s->sme.sae.tmp->bssid, bssid, ETH_ALEN);
135
136 reuse_data:
137 len = wpa_s->sme.sae_token ? wpabuf_len(wpa_s->sme.sae_token) : 0;
138 if (ssid->sae_password_id)
139 len += 4 + os_strlen(ssid->sae_password_id);
140 buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + len);
141 if (buf == NULL)
142 return NULL;
143 if (!external) {
144 wpabuf_put_le16(buf, 1); /* Transaction seq# */
145 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
146 }
147 sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token,
148 ssid->sae_password_id);
149
150 return buf;
151 }
152
153
154 static struct wpabuf * sme_auth_build_sae_confirm(struct wpa_supplicant *wpa_s,
155 int external)
156 {
157 struct wpabuf *buf;
158
159 buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN);
160 if (buf == NULL)
161 return NULL;
162
163 if (!external) {
164 wpabuf_put_le16(buf, 2); /* Transaction seq# */
165 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
166 }
167 sae_write_confirm(&wpa_s->sme.sae, buf);
168
169 return buf;
170 }
171
172 #endif /* CONFIG_SAE */
173
174
175 /**
176 * sme_auth_handle_rrm - Handle RRM aspects of current authentication attempt
177 * @wpa_s: Pointer to wpa_supplicant data
178 * @bss: Pointer to the bss which is the target of authentication attempt
179 */
180 static void sme_auth_handle_rrm(struct wpa_supplicant *wpa_s,
181 struct wpa_bss *bss)
182 {
183 const u8 rrm_ie_len = 5;
184 u8 *pos;
185 const u8 *rrm_ie;
186
187 wpa_s->rrm.rrm_used = 0;
188
189 wpa_printf(MSG_DEBUG,
190 "RRM: Determining whether RRM can be used - device support: 0x%x",
191 wpa_s->drv_rrm_flags);
192
193 rrm_ie = wpa_bss_get_ie(bss, WLAN_EID_RRM_ENABLED_CAPABILITIES);
194 if (!rrm_ie || !(bss->caps & IEEE80211_CAP_RRM)) {
195 wpa_printf(MSG_DEBUG, "RRM: No RRM in network");
196 return;
197 }
198
199 if (!((wpa_s->drv_rrm_flags &
200 WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES) &&
201 (wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_QUIET)) &&
202 !(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_RRM)) {
203 wpa_printf(MSG_DEBUG,
204 "RRM: Insufficient RRM support in driver - do not use RRM");
205 return;
206 }
207
208 if (sizeof(wpa_s->sme.assoc_req_ie) <
209 wpa_s->sme.assoc_req_ie_len + rrm_ie_len + 2) {
210 wpa_printf(MSG_INFO,
211 "RRM: Unable to use RRM, no room for RRM IE");
212 return;
213 }
214
215 wpa_printf(MSG_DEBUG, "RRM: Adding RRM IE to Association Request");
216 pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
217 os_memset(pos, 0, 2 + rrm_ie_len);
218 *pos++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
219 *pos++ = rrm_ie_len;
220
221 /* Set supported capabilites flags */
222 if (wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)
223 *pos |= WLAN_RRM_CAPS_LINK_MEASUREMENT;
224
225 *pos |= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
226 WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE |
227 WLAN_RRM_CAPS_BEACON_REPORT_TABLE;
228
229 if (wpa_s->lci)
230 pos[1] |= WLAN_RRM_CAPS_LCI_MEASUREMENT;
231
232 wpa_s->sme.assoc_req_ie_len += rrm_ie_len + 2;
233 wpa_s->rrm.rrm_used = 1;
234 }
235
236
237 static void sme_send_authentication(struct wpa_supplicant *wpa_s,
238 struct wpa_bss *bss, struct wpa_ssid *ssid,
239 int start)
240 {
241 struct wpa_driver_auth_params params;
242 struct wpa_ssid *old_ssid;
243 #ifdef CONFIG_IEEE80211R
244 const u8 *ie;
245 #endif /* CONFIG_IEEE80211R */
246 #if defined(CONFIG_IEEE80211R) || defined(CONFIG_FILS)
247 const u8 *md = NULL;
248 #endif /* CONFIG_IEEE80211R || CONFIG_FILS */
249 int i, bssid_changed;
250 struct wpabuf *resp = NULL;
251 u8 ext_capab[18];
252 int ext_capab_len;
253 int skip_auth;
254 u8 *wpa_ie;
255 size_t wpa_ie_len;
256 #ifdef CONFIG_MBO
257 const u8 *mbo_ie;
258 #endif /* CONFIG_MBO */
259
260 if (bss == NULL) {
261 wpa_msg(wpa_s, MSG_ERROR, "SME: No scan result available for "
262 "the network");
263 wpas_connect_work_done(wpa_s);
264 return;
265 }
266
267 skip_auth = wpa_s->conf->reassoc_same_bss_optim &&
268 wpa_s->reassoc_same_bss;
269 wpa_s->current_bss = bss;
270
271 os_memset(&params, 0, sizeof(params));
272 wpa_s->reassociate = 0;
273
274 params.freq = bss->freq;
275 params.bssid = bss->bssid;
276 params.ssid = bss->ssid;
277 params.ssid_len = bss->ssid_len;
278 params.p2p = ssid->p2p_group;
279
280 if (wpa_s->sme.ssid_len != params.ssid_len ||
281 os_memcmp(wpa_s->sme.ssid, params.ssid, params.ssid_len) != 0)
282 wpa_s->sme.prev_bssid_set = 0;
283
284 wpa_s->sme.freq = params.freq;
285 os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len);
286 wpa_s->sme.ssid_len = params.ssid_len;
287
288 params.auth_alg = WPA_AUTH_ALG_OPEN;
289 #ifdef IEEE8021X_EAPOL
290 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
291 if (ssid->leap) {
292 if (ssid->non_leap == 0)
293 params.auth_alg = WPA_AUTH_ALG_LEAP;
294 else
295 params.auth_alg |= WPA_AUTH_ALG_LEAP;
296 }
297 }
298 #endif /* IEEE8021X_EAPOL */
299 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x",
300 params.auth_alg);
301 if (ssid->auth_alg) {
302 params.auth_alg = ssid->auth_alg;
303 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
304 "0x%x", params.auth_alg);
305 }
306 #ifdef CONFIG_SAE
307 wpa_s->sme.sae_pmksa_caching = 0;
308 if (wpa_key_mgmt_sae(ssid->key_mgmt)) {
309 const u8 *rsn;
310 struct wpa_ie_data ied;
311
312 rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
313 if (!rsn) {
314 wpa_dbg(wpa_s, MSG_DEBUG,
315 "SAE enabled, but target BSS does not advertise RSN");
316 } else if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
317 wpa_key_mgmt_sae(ied.key_mgmt)) {
318 wpa_dbg(wpa_s, MSG_DEBUG, "Using SAE auth_alg");
319 params.auth_alg = WPA_AUTH_ALG_SAE;
320 } else {
321 wpa_dbg(wpa_s, MSG_DEBUG,
322 "SAE enabled, but target BSS does not advertise SAE AKM for RSN");
323 }
324 }
325 #endif /* CONFIG_SAE */
326
327 for (i = 0; i < NUM_WEP_KEYS; i++) {
328 if (ssid->wep_key_len[i])
329 params.wep_key[i] = ssid->wep_key[i];
330 params.wep_key_len[i] = ssid->wep_key_len[i];
331 }
332 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
333
334 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
335 os_memset(wpa_s->bssid, 0, ETH_ALEN);
336 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
337 if (bssid_changed)
338 wpas_notify_bssid_changed(wpa_s);
339
340 if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
341 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
342 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
343 int try_opportunistic;
344 const u8 *cache_id = NULL;
345
346 try_opportunistic = (ssid->proactive_key_caching < 0 ?
347 wpa_s->conf->okc :
348 ssid->proactive_key_caching) &&
349 (ssid->proto & WPA_PROTO_RSN);
350 #ifdef CONFIG_FILS
351 if (wpa_key_mgmt_fils(ssid->key_mgmt))
352 cache_id = wpa_bss_get_fils_cache_id(bss);
353 #endif /* CONFIG_FILS */
354 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
355 wpa_s->current_ssid,
356 try_opportunistic, cache_id,
357 0) == 0)
358 eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
359 wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
360 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
361 wpa_s->sme.assoc_req_ie,
362 &wpa_s->sme.assoc_req_ie_len)) {
363 wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA "
364 "key management and encryption suites");
365 wpas_connect_work_done(wpa_s);
366 return;
367 }
368 #ifdef CONFIG_HS20
369 } else if (wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE) &&
370 (ssid->key_mgmt & WPA_KEY_MGMT_OSEN)) {
371 /* No PMKSA caching, but otherwise similar to RSN/WPA */
372 wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
373 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
374 wpa_s->sme.assoc_req_ie,
375 &wpa_s->sme.assoc_req_ie_len)) {
376 wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA "
377 "key management and encryption suites");
378 wpas_connect_work_done(wpa_s);
379 return;
380 }
381 #endif /* CONFIG_HS20 */
382 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
383 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
384 /*
385 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
386 * use non-WPA since the scan results did not indicate that the
387 * AP is using WPA or WPA2.
388 */
389 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
390 wpa_s->sme.assoc_req_ie_len = 0;
391 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
392 wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
393 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
394 wpa_s->sme.assoc_req_ie,
395 &wpa_s->sme.assoc_req_ie_len)) {
396 wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA "
397 "key management and encryption suites (no "
398 "scan results)");
399 wpas_connect_work_done(wpa_s);
400 return;
401 }
402 #ifdef CONFIG_WPS
403 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
404 struct wpabuf *wps_ie;
405 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
406 if (wps_ie && wpabuf_len(wps_ie) <=
407 sizeof(wpa_s->sme.assoc_req_ie)) {
408 wpa_s->sme.assoc_req_ie_len = wpabuf_len(wps_ie);
409 os_memcpy(wpa_s->sme.assoc_req_ie, wpabuf_head(wps_ie),
410 wpa_s->sme.assoc_req_ie_len);
411 } else
412 wpa_s->sme.assoc_req_ie_len = 0;
413 wpabuf_free(wps_ie);
414 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
415 #endif /* CONFIG_WPS */
416 } else {
417 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
418 wpa_s->sme.assoc_req_ie_len = 0;
419 }
420
421 /* In case the WPA vendor IE is used, it should be placed after all the
422 * non-vendor IEs, as the lower layer expects the IEs to be ordered as
423 * defined in the standard. Store the WPA IE so it can later be
424 * inserted at the correct location.
425 */
426 wpa_ie = NULL;
427 wpa_ie_len = 0;
428 if (wpa_s->wpa_proto == WPA_PROTO_WPA) {
429 wpa_ie = os_memdup(wpa_s->sme.assoc_req_ie,
430 wpa_s->sme.assoc_req_ie_len);
431 if (wpa_ie) {
432 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Storing WPA IE");
433
434 wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
435 wpa_s->sme.assoc_req_ie_len = 0;
436 } else {
437 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed copy WPA IE");
438 wpas_connect_work_done(wpa_s);
439 return;
440 }
441 }
442
443 #ifdef CONFIG_IEEE80211R
444 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
445 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
446 md = ie + 2;
447 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
448 if (md) {
449 /* Prepare for the next transition */
450 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
451 }
452
453 if (md && !wpa_key_mgmt_ft(ssid->key_mgmt))
454 md = NULL;
455 if (md) {
456 wpa_dbg(wpa_s, MSG_DEBUG, "SME: FT mobility domain %02x%02x",
457 md[0], md[1]);
458
459 if (wpa_s->sme.assoc_req_ie_len + 5 <
460 sizeof(wpa_s->sme.assoc_req_ie)) {
461 struct rsn_mdie *mdie;
462 u8 *pos = wpa_s->sme.assoc_req_ie +
463 wpa_s->sme.assoc_req_ie_len;
464 *pos++ = WLAN_EID_MOBILITY_DOMAIN;
465 *pos++ = sizeof(*mdie);
466 mdie = (struct rsn_mdie *) pos;
467 os_memcpy(mdie->mobility_domain, md,
468 MOBILITY_DOMAIN_ID_LEN);
469 mdie->ft_capab = md[MOBILITY_DOMAIN_ID_LEN];
470 wpa_s->sme.assoc_req_ie_len += 5;
471 }
472
473 if (wpa_s->sme.prev_bssid_set && wpa_s->sme.ft_used &&
474 os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0 &&
475 wpa_sm_has_ptk(wpa_s->wpa)) {
476 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying to use FT "
477 "over-the-air");
478 params.auth_alg = WPA_AUTH_ALG_FT;
479 params.ie = wpa_s->sme.ft_ies;
480 params.ie_len = wpa_s->sme.ft_ies_len;
481 }
482 }
483 #endif /* CONFIG_IEEE80211R */
484
485 #ifdef CONFIG_IEEE80211W
486 wpa_s->sme.mfp = wpas_get_ssid_pmf(wpa_s, ssid);
487 if (wpa_s->sme.mfp != NO_MGMT_FRAME_PROTECTION) {
488 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
489 struct wpa_ie_data _ie;
490 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 &&
491 _ie.capabilities &
492 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
493 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected AP supports "
494 "MFP: require MFP");
495 wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED;
496 }
497 }
498 #endif /* CONFIG_IEEE80211W */
499
500 #ifdef CONFIG_P2P
501 if (wpa_s->global->p2p) {
502 u8 *pos;
503 size_t len;
504 int res;
505 pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
506 len = sizeof(wpa_s->sme.assoc_req_ie) -
507 wpa_s->sme.assoc_req_ie_len;
508 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
509 ssid->p2p_group);
510 if (res >= 0)
511 wpa_s->sme.assoc_req_ie_len += res;
512 }
513 #endif /* CONFIG_P2P */
514
515 #ifdef CONFIG_FST
516 if (wpa_s->fst_ies) {
517 int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
518
519 if (wpa_s->sme.assoc_req_ie_len + fst_ies_len <=
520 sizeof(wpa_s->sme.assoc_req_ie)) {
521 os_memcpy(wpa_s->sme.assoc_req_ie +
522 wpa_s->sme.assoc_req_ie_len,
523 wpabuf_head(wpa_s->fst_ies),
524 fst_ies_len);
525 wpa_s->sme.assoc_req_ie_len += fst_ies_len;
526 }
527 }
528 #endif /* CONFIG_FST */
529
530 sme_auth_handle_rrm(wpa_s, bss);
531
532 wpa_s->sme.assoc_req_ie_len += wpas_supp_op_class_ie(
533 wpa_s, ssid, bss->freq,
534 wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
535 sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len);
536
537 if (params.p2p)
538 wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
539 else
540 wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
541
542 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
543 sizeof(ext_capab));
544 if (ext_capab_len > 0) {
545 u8 *pos = wpa_s->sme.assoc_req_ie;
546 if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN)
547 pos += 2 + pos[1];
548 os_memmove(pos + ext_capab_len, pos,
549 wpa_s->sme.assoc_req_ie_len -
550 (pos - wpa_s->sme.assoc_req_ie));
551 wpa_s->sme.assoc_req_ie_len += ext_capab_len;
552 os_memcpy(pos, ext_capab, ext_capab_len);
553 }
554
555 #ifdef CONFIG_HS20
556 if (is_hs20_network(wpa_s, ssid, bss)) {
557 struct wpabuf *hs20;
558
559 hs20 = wpabuf_alloc(20 + MAX_ROAMING_CONS_OI_LEN);
560 if (hs20) {
561 int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
562 size_t len;
563
564 wpas_hs20_add_indication(hs20, pps_mo_id,
565 get_hs20_version(bss));
566 wpas_hs20_add_roam_cons_sel(hs20, ssid);
567 len = sizeof(wpa_s->sme.assoc_req_ie) -
568 wpa_s->sme.assoc_req_ie_len;
569 if (wpabuf_len(hs20) <= len) {
570 os_memcpy(wpa_s->sme.assoc_req_ie +
571 wpa_s->sme.assoc_req_ie_len,
572 wpabuf_head(hs20), wpabuf_len(hs20));
573 wpa_s->sme.assoc_req_ie_len += wpabuf_len(hs20);
574 }
575 wpabuf_free(hs20);
576 }
577 }
578 #endif /* CONFIG_HS20 */
579
580 if (wpa_ie) {
581 size_t len;
582
583 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Reinsert WPA IE");
584
585 len = sizeof(wpa_s->sme.assoc_req_ie) -
586 wpa_s->sme.assoc_req_ie_len;
587
588 if (len > wpa_ie_len) {
589 os_memcpy(wpa_s->sme.assoc_req_ie +
590 wpa_s->sme.assoc_req_ie_len,
591 wpa_ie, wpa_ie_len);
592 wpa_s->sme.assoc_req_ie_len += wpa_ie_len;
593 } else {
594 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Failed to add WPA IE");
595 }
596
597 os_free(wpa_ie);
598 }
599
600 if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
601 struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
602 size_t len;
603
604 len = sizeof(wpa_s->sme.assoc_req_ie) -
605 wpa_s->sme.assoc_req_ie_len;
606 if (wpabuf_len(buf) <= len) {
607 os_memcpy(wpa_s->sme.assoc_req_ie +
608 wpa_s->sme.assoc_req_ie_len,
609 wpabuf_head(buf), wpabuf_len(buf));
610 wpa_s->sme.assoc_req_ie_len += wpabuf_len(buf);
611 }
612 }
613
614 #ifdef CONFIG_MBO
615 mbo_ie = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE);
616 if (mbo_ie) {
617 int len;
618
619 len = wpas_mbo_ie(wpa_s, wpa_s->sme.assoc_req_ie +
620 wpa_s->sme.assoc_req_ie_len,
621 sizeof(wpa_s->sme.assoc_req_ie) -
622 wpa_s->sme.assoc_req_ie_len,
623 !!mbo_attr_from_mbo_ie(mbo_ie,
624 OCE_ATTR_ID_CAPA_IND));
625 if (len >= 0)
626 wpa_s->sme.assoc_req_ie_len += len;
627 }
628 #endif /* CONFIG_MBO */
629
630 #ifdef CONFIG_SAE
631 if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE &&
632 pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid, ssid, 0,
633 NULL, WPA_KEY_MGMT_SAE) == 0) {
634 wpa_dbg(wpa_s, MSG_DEBUG,
635 "PMKSA cache entry found - try to use PMKSA caching instead of new SAE authentication");
636 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
637 params.auth_alg = WPA_AUTH_ALG_OPEN;
638 wpa_s->sme.sae_pmksa_caching = 1;
639 }
640
641 if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE) {
642 if (start)
643 resp = sme_auth_build_sae_commit(wpa_s, ssid,
644 bss->bssid, 0,
645 start == 2);
646 else
647 resp = sme_auth_build_sae_confirm(wpa_s, 0);
648 if (resp == NULL) {
649 wpas_connection_failed(wpa_s, bss->bssid);
650 return;
651 }
652 params.auth_data = wpabuf_head(resp);
653 params.auth_data_len = wpabuf_len(resp);
654 wpa_s->sme.sae.state = start ? SAE_COMMITTED : SAE_CONFIRMED;
655 }
656 #endif /* CONFIG_SAE */
657
658 old_ssid = wpa_s->current_ssid;
659 wpa_s->current_ssid = ssid;
660 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
661 wpa_supplicant_initiate_eapol(wpa_s);
662
663 #ifdef CONFIG_FILS
664 /* TODO: FILS operations can in some cases be done between different
665 * network_ctx (i.e., same credentials can be used with multiple
666 * networks). */
667 if (params.auth_alg == WPA_AUTH_ALG_OPEN &&
668 wpa_key_mgmt_fils(ssid->key_mgmt)) {
669 const u8 *indic;
670 u16 fils_info;
671 const u8 *realm, *username, *rrk;
672 size_t realm_len, username_len, rrk_len;
673 u16 next_seq_num;
674
675 /*
676 * Check FILS Indication element (FILS Information field) bits
677 * indicating supported authentication algorithms against local
678 * configuration (ssid->fils_dh_group). Try to use FILS
679 * authentication only if the AP supports the combination in the
680 * network profile. */
681 indic = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
682 if (!indic || indic[1] < 2) {
683 wpa_printf(MSG_DEBUG, "SME: " MACSTR
684 " does not include FILS Indication element - cannot use FILS authentication with it",
685 MAC2STR(bss->bssid));
686 goto no_fils;
687 }
688
689 fils_info = WPA_GET_LE16(indic + 2);
690 if (ssid->fils_dh_group == 0 && !(fils_info & BIT(9))) {
691 wpa_printf(MSG_DEBUG, "SME: " MACSTR
692 " does not support FILS SK without PFS - cannot use FILS authentication with it",
693 MAC2STR(bss->bssid));
694 goto no_fils;
695 }
696 if (ssid->fils_dh_group != 0 && !(fils_info & BIT(10))) {
697 wpa_printf(MSG_DEBUG, "SME: " MACSTR
698 " does not support FILS SK with PFS - cannot use FILS authentication with it",
699 MAC2STR(bss->bssid));
700 goto no_fils;
701 }
702
703 if (wpa_s->last_con_fail_realm &&
704 eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap,
705 &username, &username_len,
706 &realm, &realm_len, &next_seq_num,
707 &rrk, &rrk_len) == 0 &&
708 realm && realm_len == wpa_s->last_con_fail_realm_len &&
709 os_memcmp(realm, wpa_s->last_con_fail_realm,
710 realm_len) == 0) {
711 wpa_printf(MSG_DEBUG,
712 "SME: FILS authentication for this realm failed last time - try to regenerate ERP key hierarchy");
713 goto no_fils;
714 }
715
716 if (pmksa_cache_set_current(wpa_s->wpa, NULL, bss->bssid,
717 ssid, 0,
718 wpa_bss_get_fils_cache_id(bss),
719 0) == 0)
720 wpa_printf(MSG_DEBUG,
721 "SME: Try to use FILS with PMKSA caching");
722 resp = fils_build_auth(wpa_s->wpa, ssid->fils_dh_group, md);
723 if (resp) {
724 int auth_alg;
725
726 if (ssid->fils_dh_group)
727 wpa_printf(MSG_DEBUG,
728 "SME: Try to use FILS SK authentication with PFS (DH Group %u)",
729 ssid->fils_dh_group);
730 else
731 wpa_printf(MSG_DEBUG,
732 "SME: Try to use FILS SK authentication without PFS");
733 auth_alg = ssid->fils_dh_group ?
734 WPA_AUTH_ALG_FILS_SK_PFS : WPA_AUTH_ALG_FILS;
735 params.auth_alg = auth_alg;
736 params.auth_data = wpabuf_head(resp);
737 params.auth_data_len = wpabuf_len(resp);
738 wpa_s->sme.auth_alg = auth_alg;
739 }
740 }
741 no_fils:
742 #endif /* CONFIG_FILS */
743
744 wpa_supplicant_cancel_sched_scan(wpa_s);
745 wpa_supplicant_cancel_scan(wpa_s);
746
747 wpa_msg(wpa_s, MSG_INFO, "SME: Trying to authenticate with " MACSTR
748 " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
749 wpa_ssid_txt(params.ssid, params.ssid_len), params.freq);
750
751 eapol_sm_notify_portValid(wpa_s->eapol, FALSE);
752 wpa_clear_keys(wpa_s, bss->bssid);
753 wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
754 if (old_ssid != wpa_s->current_ssid)
755 wpas_notify_network_changed(wpa_s);
756
757 #ifdef CONFIG_HS20
758 hs20_configure_frame_filters(wpa_s);
759 #endif /* CONFIG_HS20 */
760
761 #ifdef CONFIG_P2P
762 /*
763 * If multi-channel concurrency is not supported, check for any
764 * frequency conflict. In case of any frequency conflict, remove the
765 * least prioritized connection.
766 */
767 if (wpa_s->num_multichan_concurrent < 2) {
768 int freq, num;
769 num = get_shared_radio_freqs(wpa_s, &freq, 1);
770 if (num > 0 && freq > 0 && freq != params.freq) {
771 wpa_printf(MSG_DEBUG,
772 "Conflicting frequency found (%d != %d)",
773 freq, params.freq);
774 if (wpas_p2p_handle_frequency_conflicts(wpa_s,
775 params.freq,
776 ssid) < 0) {
777 wpas_connection_failed(wpa_s, bss->bssid);
778 wpa_supplicant_mark_disassoc(wpa_s);
779 wpabuf_free(resp);
780 wpas_connect_work_done(wpa_s);
781 return;
782 }
783 }
784 }
785 #endif /* CONFIG_P2P */
786
787 if (skip_auth) {
788 wpa_msg(wpa_s, MSG_DEBUG,
789 "SME: Skip authentication step on reassoc-to-same-BSS");
790 wpabuf_free(resp);
791 sme_associate(wpa_s, ssid->mode, bss->bssid, WLAN_AUTH_OPEN);
792 return;
793 }
794
795
796 wpa_s->sme.auth_alg = params.auth_alg;
797 if (wpa_drv_authenticate(wpa_s, &params) < 0) {
798 wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the "
799 "driver failed");
800 wpas_connection_failed(wpa_s, bss->bssid);
801 wpa_supplicant_mark_disassoc(wpa_s);
802 wpabuf_free(resp);
803 wpas_connect_work_done(wpa_s);
804 return;
805 }
806
807 eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s,
808 NULL);
809
810 /*
811 * Association will be started based on the authentication event from
812 * the driver.
813 */
814
815 wpabuf_free(resp);
816 }
817
818
819 static void sme_auth_start_cb(struct wpa_radio_work *work, int deinit)
820 {
821 struct wpa_connect_work *cwork = work->ctx;
822 struct wpa_supplicant *wpa_s = work->wpa_s;
823
824 if (deinit) {
825 if (work->started)
826 wpa_s->connect_work = NULL;
827
828 wpas_connect_work_free(cwork);
829 return;
830 }
831
832 wpa_s->connect_work = work;
833
834 if (cwork->bss_removed ||
835 !wpas_valid_bss_ssid(wpa_s, cwork->bss, cwork->ssid) ||
836 wpas_network_disabled(wpa_s, cwork->ssid)) {
837 wpa_dbg(wpa_s, MSG_DEBUG, "SME: BSS/SSID entry for authentication not valid anymore - drop connection attempt");
838 wpas_connect_work_done(wpa_s);
839 return;
840 }
841
842 /* Starting new connection, so clear the possibly used WPA IE from the
843 * previous association. */
844 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
845
846 sme_send_authentication(wpa_s, cwork->bss, cwork->ssid, 1);
847 }
848
849
850 void sme_authenticate(struct wpa_supplicant *wpa_s,
851 struct wpa_bss *bss, struct wpa_ssid *ssid)
852 {
853 struct wpa_connect_work *cwork;
854
855 if (bss == NULL || ssid == NULL)
856 return;
857 if (wpa_s->connect_work) {
858 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reject sme_authenticate() call since connect_work exist");
859 return;
860 }
861
862 if (radio_work_pending(wpa_s, "sme-connect")) {
863 /*
864 * The previous sme-connect work might no longer be valid due to
865 * the fact that the BSS list was updated. In addition, it makes
866 * sense to adhere to the 'newer' decision.
867 */
868 wpa_dbg(wpa_s, MSG_DEBUG,
869 "SME: Remove previous pending sme-connect");
870 radio_remove_works(wpa_s, "sme-connect", 0);
871 }
872
873 wpas_abort_ongoing_scan(wpa_s);
874
875 cwork = os_zalloc(sizeof(*cwork));
876 if (cwork == NULL)
877 return;
878 cwork->bss = bss;
879 cwork->ssid = ssid;
880 cwork->sme = 1;
881
882 #ifdef CONFIG_SAE
883 wpa_s->sme.sae.state = SAE_NOTHING;
884 wpa_s->sme.sae.send_confirm = 0;
885 wpa_s->sme.sae_group_index = 0;
886 #endif /* CONFIG_SAE */
887
888 if (radio_add_work(wpa_s, bss->freq, "sme-connect", 1,
889 sme_auth_start_cb, cwork) < 0)
890 wpas_connect_work_free(cwork);
891 }
892
893
894 #ifdef CONFIG_SAE
895
896 static int sme_external_auth_build_buf(struct wpabuf *buf,
897 struct wpabuf *params,
898 const u8 *sa, const u8 *da,
899 u16 auth_transaction, u16 seq_num)
900 {
901 struct ieee80211_mgmt *resp;
902
903 resp = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
904 u.auth.variable));
905
906 resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
907 (WLAN_FC_STYPE_AUTH << 4));
908 os_memcpy(resp->da, da, ETH_ALEN);
909 os_memcpy(resp->sa, sa, ETH_ALEN);
910 os_memcpy(resp->bssid, da, ETH_ALEN);
911 resp->u.auth.auth_alg = host_to_le16(WLAN_AUTH_SAE);
912 resp->seq_ctrl = host_to_le16(seq_num << 4);
913 resp->u.auth.auth_transaction = host_to_le16(auth_transaction);
914 resp->u.auth.status_code = host_to_le16(WLAN_STATUS_SUCCESS);
915 if (params)
916 wpabuf_put_buf(buf, params);
917
918 return 0;
919 }
920
921
922 static void sme_external_auth_send_sae_commit(struct wpa_supplicant *wpa_s,
923 const u8 *bssid,
924 struct wpa_ssid *ssid)
925 {
926 struct wpabuf *resp, *buf;
927
928 resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid, 1, 0);
929 if (!resp)
930 return;
931
932 wpa_s->sme.sae.state = SAE_COMMITTED;
933 buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + wpabuf_len(resp));
934 if (!buf) {
935 wpabuf_free(resp);
936 return;
937 }
938
939 wpa_s->sme.seq_num++;
940 sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
941 bssid, 1, wpa_s->sme.seq_num);
942 wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0);
943 wpabuf_free(resp);
944 wpabuf_free(buf);
945 }
946
947
948 static void sme_send_external_auth_status(struct wpa_supplicant *wpa_s,
949 u16 status)
950 {
951 struct external_auth params;
952
953 os_memset(&params, 0, sizeof(params));
954 params.status = status;
955 os_memcpy(params.ssid, wpa_s->sme.ext_auth.ssid,
956 wpa_s->sme.ext_auth.ssid_len);
957 params.ssid_len = wpa_s->sme.ext_auth.ssid_len;
958 os_memcpy(params.bssid, wpa_s->sme.ext_auth.bssid, ETH_ALEN);
959 wpa_drv_send_external_auth_status(wpa_s, &params);
960 }
961
962
963 static void sme_handle_external_auth_start(struct wpa_supplicant *wpa_s,
964 union wpa_event_data *data)
965 {
966 struct wpa_ssid *ssid;
967 size_t ssid_str_len = data->external_auth.ssid_len;
968 u8 *ssid_str = data->external_auth.ssid;
969
970 /* Get the SSID conf from the ssid string obtained */
971 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
972 if (!wpas_network_disabled(wpa_s, ssid) &&
973 ssid_str_len == ssid->ssid_len &&
974 os_memcmp(ssid_str, ssid->ssid, ssid_str_len) == 0 &&
975 (ssid->key_mgmt & WPA_KEY_MGMT_SAE))
976 break;
977 }
978 if (ssid)
979 sme_external_auth_send_sae_commit(wpa_s,
980 data->external_auth.bssid,
981 ssid);
982 else
983 sme_send_external_auth_status(wpa_s,
984 WLAN_STATUS_UNSPECIFIED_FAILURE);
985 }
986
987
988 static void sme_external_auth_send_sae_confirm(struct wpa_supplicant *wpa_s,
989 const u8 *da)
990 {
991 struct wpabuf *resp, *buf;
992
993 resp = sme_auth_build_sae_confirm(wpa_s, 1);
994 if (!resp) {
995 wpa_printf(MSG_DEBUG, "SAE: Confirm message buf alloc failure");
996 return;
997 }
998
999 wpa_s->sme.sae.state = SAE_CONFIRMED;
1000 buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN + wpabuf_len(resp));
1001 if (!buf) {
1002 wpa_printf(MSG_DEBUG, "SAE: Auth Confirm buf alloc failure");
1003 wpabuf_free(resp);
1004 return;
1005 }
1006 wpa_s->sme.seq_num++;
1007 sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
1008 da, 2, wpa_s->sme.seq_num);
1009 wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0);
1010 wpabuf_free(resp);
1011 wpabuf_free(buf);
1012 }
1013
1014
1015 void sme_external_auth_trigger(struct wpa_supplicant *wpa_s,
1016 union wpa_event_data *data)
1017 {
1018 if (RSN_SELECTOR_GET(&data->external_auth.key_mgmt_suite) !=
1019 RSN_AUTH_KEY_MGMT_SAE)
1020 return;
1021
1022 if (data->external_auth.action == EXT_AUTH_START) {
1023 os_memcpy(&wpa_s->sme.ext_auth, data,
1024 sizeof(struct external_auth));
1025 wpa_s->sme.seq_num = 0;
1026 wpa_s->sme.sae.state = SAE_NOTHING;
1027 wpa_s->sme.sae.send_confirm = 0;
1028 wpa_s->sme.sae_group_index = 0;
1029 sme_handle_external_auth_start(wpa_s, data);
1030 } else if (data->external_auth.action == EXT_AUTH_ABORT) {
1031 /* Report failure to driver for the wrong trigger */
1032 sme_send_external_auth_status(wpa_s,
1033 WLAN_STATUS_UNSPECIFIED_FAILURE);
1034 }
1035 }
1036
1037
1038 static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
1039 u16 status_code, const u8 *data, size_t len,
1040 int external, const u8 *sa)
1041 {
1042 int *groups;
1043
1044 wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE authentication transaction %u "
1045 "status code %u", auth_transaction, status_code);
1046
1047 if (auth_transaction == 1 &&
1048 status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
1049 wpa_s->sme.sae.state == SAE_COMMITTED &&
1050 (external || wpa_s->current_bss) && wpa_s->current_ssid) {
1051 int default_groups[] = { 19, 20, 21, 0 };
1052 u16 group;
1053
1054 groups = wpa_s->conf->sae_groups;
1055 if (!groups || groups[0] <= 0)
1056 groups = default_groups;
1057
1058 if (len < sizeof(le16)) {
1059 wpa_dbg(wpa_s, MSG_DEBUG,
1060 "SME: Too short SAE anti-clogging token request");
1061 return -1;
1062 }
1063 group = WPA_GET_LE16(data);
1064 wpa_dbg(wpa_s, MSG_DEBUG,
1065 "SME: SAE anti-clogging token requested (group %u)",
1066 group);
1067 if (sae_group_allowed(&wpa_s->sme.sae, groups, group) !=
1068 WLAN_STATUS_SUCCESS) {
1069 wpa_dbg(wpa_s, MSG_ERROR,
1070 "SME: SAE group %u of anti-clogging request is invalid",
1071 group);
1072 return -1;
1073 }
1074 wpabuf_free(wpa_s->sme.sae_token);
1075 wpa_s->sme.sae_token = wpabuf_alloc_copy(data + sizeof(le16),
1076 len - sizeof(le16));
1077 if (!external)
1078 sme_send_authentication(wpa_s, wpa_s->current_bss,
1079 wpa_s->current_ssid, 2);
1080 else
1081 sme_external_auth_send_sae_commit(
1082 wpa_s, wpa_s->sme.ext_auth.bssid,
1083 wpa_s->current_ssid);
1084 return 0;
1085 }
1086
1087 if (auth_transaction == 1 &&
1088 status_code == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
1089 wpa_s->sme.sae.state == SAE_COMMITTED &&
1090 (external || wpa_s->current_bss) && wpa_s->current_ssid) {
1091 wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE group not supported");
1092 wpa_s->sme.sae_group_index++;
1093 if (sme_set_sae_group(wpa_s) < 0)
1094 return -1; /* no other groups enabled */
1095 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Try next enabled SAE group");
1096 if (!external)
1097 sme_send_authentication(wpa_s, wpa_s->current_bss,
1098 wpa_s->current_ssid, 1);
1099 else
1100 sme_external_auth_send_sae_commit(
1101 wpa_s, wpa_s->sme.ext_auth.bssid,
1102 wpa_s->current_ssid);
1103 return 0;
1104 }
1105
1106 if (auth_transaction == 1 &&
1107 status_code == WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER) {
1108 const u8 *bssid = sa ? sa : wpa_s->pending_bssid;
1109
1110 wpa_msg(wpa_s, MSG_INFO,
1111 WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER MACSTR,
1112 MAC2STR(bssid));
1113 return -1;
1114 }
1115
1116 if (status_code != WLAN_STATUS_SUCCESS)
1117 return -1;
1118
1119 if (auth_transaction == 1) {
1120 u16 res;
1121
1122 groups = wpa_s->conf->sae_groups;
1123
1124 wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit");
1125 if ((!external && wpa_s->current_bss == NULL) ||
1126 wpa_s->current_ssid == NULL)
1127 return -1;
1128 if (wpa_s->sme.sae.state != SAE_COMMITTED)
1129 return -1;
1130 if (groups && groups[0] <= 0)
1131 groups = NULL;
1132 res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
1133 groups);
1134 if (res == SAE_SILENTLY_DISCARD) {
1135 wpa_printf(MSG_DEBUG,
1136 "SAE: Drop commit message due to reflection attack");
1137 return 0;
1138 }
1139 if (res != WLAN_STATUS_SUCCESS)
1140 return -1;
1141
1142 if (sae_process_commit(&wpa_s->sme.sae) < 0) {
1143 wpa_printf(MSG_DEBUG, "SAE: Failed to process peer "
1144 "commit");
1145 return -1;
1146 }
1147
1148 wpabuf_free(wpa_s->sme.sae_token);
1149 wpa_s->sme.sae_token = NULL;
1150 if (!external)
1151 sme_send_authentication(wpa_s, wpa_s->current_bss,
1152 wpa_s->current_ssid, 0);
1153 else
1154 sme_external_auth_send_sae_confirm(wpa_s, sa);
1155 return 0;
1156 } else if (auth_transaction == 2) {
1157 wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE confirm");
1158 if (wpa_s->sme.sae.state != SAE_CONFIRMED)
1159 return -1;
1160 if (sae_check_confirm(&wpa_s->sme.sae, data, len) < 0)
1161 return -1;
1162 wpa_s->sme.sae.state = SAE_ACCEPTED;
1163 sae_clear_temp_data(&wpa_s->sme.sae);
1164
1165 if (external) {
1166 /* Report success to driver */
1167 sme_send_external_auth_status(wpa_s,
1168 WLAN_STATUS_SUCCESS);
1169 }
1170
1171 return 1;
1172 }
1173
1174 return -1;
1175 }
1176
1177
1178 void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s,
1179 const u8 *auth_frame, size_t len)
1180 {
1181 const struct ieee80211_mgmt *header;
1182 size_t auth_length;
1183
1184 header = (const struct ieee80211_mgmt *) auth_frame;
1185 auth_length = IEEE80211_HDRLEN + sizeof(header->u.auth);
1186
1187 if (len < auth_length) {
1188 /* Notify failure to the driver */
1189 sme_send_external_auth_status(wpa_s,
1190 WLAN_STATUS_UNSPECIFIED_FAILURE);
1191 return;
1192 }
1193
1194 if (le_to_host16(header->u.auth.auth_alg) == WLAN_AUTH_SAE) {
1195 int res;
1196
1197 res = sme_sae_auth(
1198 wpa_s, le_to_host16(header->u.auth.auth_transaction),
1199 le_to_host16(header->u.auth.status_code),
1200 header->u.auth.variable,
1201 len - auth_length, 1, header->sa);
1202 if (res < 0) {
1203 /* Notify failure to the driver */
1204 sme_send_external_auth_status(
1205 wpa_s, WLAN_STATUS_UNSPECIFIED_FAILURE);
1206 return;
1207 }
1208 if (res != 1)
1209 return;
1210
1211 wpa_printf(MSG_DEBUG,
1212 "SME: SAE completed - setting PMK for 4-way handshake");
1213 wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN,
1214 wpa_s->sme.sae.pmkid, wpa_s->pending_bssid);
1215 }
1216 }
1217
1218 #endif /* CONFIG_SAE */
1219
1220
1221 void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
1222 {
1223 struct wpa_ssid *ssid = wpa_s->current_ssid;
1224
1225 if (ssid == NULL) {
1226 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event "
1227 "when network is not selected");
1228 return;
1229 }
1230
1231 if (wpa_s->wpa_state != WPA_AUTHENTICATING) {
1232 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event "
1233 "when not in authenticating state");
1234 return;
1235 }
1236
1237 if (os_memcmp(wpa_s->pending_bssid, data->auth.peer, ETH_ALEN) != 0) {
1238 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication with "
1239 "unexpected peer " MACSTR,
1240 MAC2STR(data->auth.peer));
1241 return;
1242 }
1243
1244 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication response: peer=" MACSTR
1245 " auth_type=%d auth_transaction=%d status_code=%d",
1246 MAC2STR(data->auth.peer), data->auth.auth_type,
1247 data->auth.auth_transaction, data->auth.status_code);
1248 wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs",
1249 data->auth.ies, data->auth.ies_len);
1250
1251 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
1252
1253 #ifdef CONFIG_SAE
1254 if (data->auth.auth_type == WLAN_AUTH_SAE) {
1255 int res;
1256 res = sme_sae_auth(wpa_s, data->auth.auth_transaction,
1257 data->auth.status_code, data->auth.ies,
1258 data->auth.ies_len, 0, NULL);
1259 if (res < 0) {
1260 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
1261 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1262
1263 }
1264 if (res != 1)
1265 return;
1266
1267 wpa_printf(MSG_DEBUG, "SME: SAE completed - setting PMK for "
1268 "4-way handshake");
1269 wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, PMK_LEN,
1270 wpa_s->sme.sae.pmkid, wpa_s->pending_bssid);
1271 }
1272 #endif /* CONFIG_SAE */
1273
1274 if (data->auth.status_code != WLAN_STATUS_SUCCESS) {
1275 char *ie_txt = NULL;
1276
1277 if (data->auth.ies && data->auth.ies_len) {
1278 size_t buflen = 2 * data->auth.ies_len + 1;
1279 ie_txt = os_malloc(buflen);
1280 if (ie_txt) {
1281 wpa_snprintf_hex(ie_txt, buflen, data->auth.ies,
1282 data->auth.ies_len);
1283 }
1284 }
1285 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AUTH_REJECT MACSTR
1286 " auth_type=%u auth_transaction=%u status_code=%u%s%s",
1287 MAC2STR(data->auth.peer), data->auth.auth_type,
1288 data->auth.auth_transaction, data->auth.status_code,
1289 ie_txt ? " ie=" : "",
1290 ie_txt ? ie_txt : "");
1291 os_free(ie_txt);
1292
1293 #ifdef CONFIG_FILS
1294 if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
1295 wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS)
1296 fils_connection_failure(wpa_s);
1297 #endif /* CONFIG_FILS */
1298
1299 if (data->auth.status_code !=
1300 WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG ||
1301 wpa_s->sme.auth_alg == data->auth.auth_type ||
1302 wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) {
1303 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
1304 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1305 return;
1306 }
1307
1308 wpas_connect_work_done(wpa_s);
1309
1310 switch (data->auth.auth_type) {
1311 case WLAN_AUTH_OPEN:
1312 wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED;
1313
1314 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying SHARED auth");
1315 wpa_supplicant_associate(wpa_s, wpa_s->current_bss,
1316 wpa_s->current_ssid);
1317 return;
1318
1319 case WLAN_AUTH_SHARED_KEY:
1320 wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_LEAP;
1321
1322 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying LEAP auth");
1323 wpa_supplicant_associate(wpa_s, wpa_s->current_bss,
1324 wpa_s->current_ssid);
1325 return;
1326
1327 default:
1328 return;
1329 }
1330 }
1331
1332 #ifdef CONFIG_IEEE80211R
1333 if (data->auth.auth_type == WLAN_AUTH_FT) {
1334 const u8 *ric_ies = NULL;
1335 size_t ric_ies_len = 0;
1336
1337 if (wpa_s->ric_ies) {
1338 ric_ies = wpabuf_head(wpa_s->ric_ies);
1339 ric_ies_len = wpabuf_len(wpa_s->ric_ies);
1340 }
1341 if (wpa_ft_process_response(wpa_s->wpa, data->auth.ies,
1342 data->auth.ies_len, 0,
1343 data->auth.peer,
1344 ric_ies, ric_ies_len) < 0) {
1345 wpa_dbg(wpa_s, MSG_DEBUG,
1346 "SME: FT Authentication response processing failed");
1347 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid="
1348 MACSTR
1349 " reason=%d locally_generated=1",
1350 MAC2STR(wpa_s->pending_bssid),
1351 WLAN_REASON_DEAUTH_LEAVING);
1352 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
1353 wpa_supplicant_mark_disassoc(wpa_s);
1354 return;
1355 }
1356 }
1357 #endif /* CONFIG_IEEE80211R */
1358
1359 #ifdef CONFIG_FILS
1360 if (data->auth.auth_type == WLAN_AUTH_FILS_SK ||
1361 data->auth.auth_type == WLAN_AUTH_FILS_SK_PFS) {
1362 u16 expect_auth_type;
1363
1364 expect_auth_type = wpa_s->sme.auth_alg ==
1365 WPA_AUTH_ALG_FILS_SK_PFS ? WLAN_AUTH_FILS_SK_PFS :
1366 WLAN_AUTH_FILS_SK;
1367 if (data->auth.auth_type != expect_auth_type) {
1368 wpa_dbg(wpa_s, MSG_DEBUG,
1369 "SME: FILS Authentication response used different auth alg (%u; expected %u)",
1370 data->auth.auth_type, expect_auth_type);
1371 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid="
1372 MACSTR
1373 " reason=%d locally_generated=1",
1374 MAC2STR(wpa_s->pending_bssid),
1375 WLAN_REASON_DEAUTH_LEAVING);
1376 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
1377 wpa_supplicant_mark_disassoc(wpa_s);
1378 return;
1379 }
1380
1381 if (fils_process_auth(wpa_s->wpa, wpa_s->pending_bssid,
1382 data->auth.ies, data->auth.ies_len) < 0) {
1383 wpa_dbg(wpa_s, MSG_DEBUG,
1384 "SME: FILS Authentication response processing failed");
1385 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid="
1386 MACSTR
1387 " reason=%d locally_generated=1",
1388 MAC2STR(wpa_s->pending_bssid),
1389 WLAN_REASON_DEAUTH_LEAVING);
1390 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
1391 wpa_supplicant_mark_disassoc(wpa_s);
1392 return;
1393 }
1394 }
1395 #endif /* CONFIG_FILS */
1396
1397 sme_associate(wpa_s, ssid->mode, data->auth.peer,
1398 data->auth.auth_type);
1399 }
1400
1401
1402 #ifdef CONFIG_IEEE80211R
1403 static void remove_ie(u8 *buf, size_t *len, u8 eid)
1404 {
1405 u8 *pos, *next, *end;
1406
1407 pos = (u8 *) get_ie(buf, *len, eid);
1408 if (pos) {
1409 next = pos + 2 + pos[1];
1410 end = buf + *len;
1411 *len -= 2 + pos[1];
1412 os_memmove(pos, next, end - next);
1413 }
1414 }
1415 #endif /* CONFIG_IEEE80211R */
1416
1417
1418 void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
1419 const u8 *bssid, u16 auth_type)
1420 {
1421 struct wpa_driver_associate_params params;
1422 struct ieee802_11_elems elems;
1423 #ifdef CONFIG_FILS
1424 u8 nonces[2 * FILS_NONCE_LEN];
1425 #endif /* CONFIG_FILS */
1426 #ifdef CONFIG_HT_OVERRIDES
1427 struct ieee80211_ht_capabilities htcaps;
1428 struct ieee80211_ht_capabilities htcaps_mask;
1429 #endif /* CONFIG_HT_OVERRIDES */
1430 #ifdef CONFIG_VHT_OVERRIDES
1431 struct ieee80211_vht_capabilities vhtcaps;
1432 struct ieee80211_vht_capabilities vhtcaps_mask;
1433 #endif /* CONFIG_VHT_OVERRIDES */
1434
1435 os_memset(&params, 0, sizeof(params));
1436
1437 #ifdef CONFIG_FILS
1438 if (auth_type == WLAN_AUTH_FILS_SK ||
1439 auth_type == WLAN_AUTH_FILS_SK_PFS) {
1440 struct wpabuf *buf;
1441 const u8 *snonce, *anonce;
1442 const unsigned int max_hlp = 20;
1443 struct wpabuf *hlp[max_hlp];
1444 unsigned int i, num_hlp = 0;
1445 struct fils_hlp_req *req;
1446
1447 dl_list_for_each(req, &wpa_s->fils_hlp_req, struct fils_hlp_req,
1448 list) {
1449 hlp[num_hlp] = wpabuf_alloc(2 * ETH_ALEN + 6 +
1450 wpabuf_len(req->pkt));
1451 if (!hlp[num_hlp])
1452 break;
1453 wpabuf_put_data(hlp[num_hlp], req->dst, ETH_ALEN);
1454 wpabuf_put_data(hlp[num_hlp], wpa_s->own_addr,
1455 ETH_ALEN);
1456 wpabuf_put_data(hlp[num_hlp],
1457 "\xaa\xaa\x03\x00\x00\x00", 6);
1458 wpabuf_put_buf(hlp[num_hlp], req->pkt);
1459 num_hlp++;
1460 if (num_hlp >= max_hlp)
1461 break;
1462 }
1463
1464 buf = fils_build_assoc_req(wpa_s->wpa, &params.fils_kek,
1465 &params.fils_kek_len, &snonce,
1466 &anonce,
1467 (const struct wpabuf **) hlp,
1468 num_hlp);
1469 for (i = 0; i < num_hlp; i++)
1470 wpabuf_free(hlp[i]);
1471 if (!buf)
1472 return;
1473 wpa_hexdump(MSG_DEBUG, "FILS: assoc_req before FILS elements",
1474 wpa_s->sme.assoc_req_ie,
1475 wpa_s->sme.assoc_req_ie_len);
1476 #ifdef CONFIG_IEEE80211R
1477 if (wpa_key_mgmt_ft(wpa_s->key_mgmt)) {
1478 /* Remove RSNE and MDE to allow them to be overridden
1479 * with FILS+FT specific values from
1480 * fils_build_assoc_req(). */
1481 remove_ie(wpa_s->sme.assoc_req_ie,
1482 &wpa_s->sme.assoc_req_ie_len,
1483 WLAN_EID_RSN);
1484 wpa_hexdump(MSG_DEBUG,
1485 "FILS: assoc_req after RSNE removal",
1486 wpa_s->sme.assoc_req_ie,
1487 wpa_s->sme.assoc_req_ie_len);
1488 remove_ie(wpa_s->sme.assoc_req_ie,
1489 &wpa_s->sme.assoc_req_ie_len,
1490 WLAN_EID_MOBILITY_DOMAIN);
1491 wpa_hexdump(MSG_DEBUG,
1492 "FILS: assoc_req after MDE removal",
1493 wpa_s->sme.assoc_req_ie,
1494 wpa_s->sme.assoc_req_ie_len);
1495 }
1496 #endif /* CONFIG_IEEE80211R */
1497 /* TODO: Make wpa_s->sme.assoc_req_ie use dynamic allocation */
1498 if (wpa_s->sme.assoc_req_ie_len + wpabuf_len(buf) >
1499 sizeof(wpa_s->sme.assoc_req_ie)) {
1500 wpa_printf(MSG_ERROR,
1501 "FILS: Not enough buffer room for own AssocReq elements");
1502 wpabuf_free(buf);
1503 return;
1504 }
1505 os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
1506 wpabuf_head(buf), wpabuf_len(buf));
1507 wpa_s->sme.assoc_req_ie_len += wpabuf_len(buf);
1508 wpabuf_free(buf);
1509 wpa_hexdump(MSG_DEBUG, "FILS: assoc_req after FILS elements",
1510 wpa_s->sme.assoc_req_ie,
1511 wpa_s->sme.assoc_req_ie_len);
1512
1513 os_memcpy(nonces, snonce, FILS_NONCE_LEN);
1514 os_memcpy(nonces + FILS_NONCE_LEN, anonce, FILS_NONCE_LEN);
1515 params.fils_nonces = nonces;
1516 params.fils_nonces_len = sizeof(nonces);
1517 }
1518 #endif /* CONFIG_FILS */
1519
1520 #ifdef CONFIG_OWE
1521 #ifdef CONFIG_TESTING_OPTIONS
1522 if (get_ie_ext(wpa_s->sme.assoc_req_ie, wpa_s->sme.assoc_req_ie_len,
1523 WLAN_EID_EXT_OWE_DH_PARAM)) {
1524 wpa_printf(MSG_INFO, "TESTING: Override OWE DH element");
1525 } else
1526 #endif /* CONFIG_TESTING_OPTIONS */
1527 if (auth_type == WLAN_AUTH_OPEN &&
1528 wpa_s->key_mgmt == WPA_KEY_MGMT_OWE) {
1529 struct wpabuf *owe_ie;
1530 u16 group;
1531
1532 if (wpa_s->current_ssid && wpa_s->current_ssid->owe_group) {
1533 group = wpa_s->current_ssid->owe_group;
1534 } else if (wpa_s->assoc_status_code ==
1535 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) {
1536 if (wpa_s->last_owe_group == 19)
1537 group = 20;
1538 else if (wpa_s->last_owe_group == 20)
1539 group = 21;
1540 else
1541 group = OWE_DH_GROUP;
1542 } else {
1543 group = OWE_DH_GROUP;
1544 }
1545
1546 wpa_s->last_owe_group = group;
1547 wpa_printf(MSG_DEBUG, "OWE: Try to use group %u", group);
1548 owe_ie = owe_build_assoc_req(wpa_s->wpa, group);
1549 if (!owe_ie) {
1550 wpa_printf(MSG_ERROR,
1551 "OWE: Failed to build IE for Association Request frame");
1552 return;
1553 }
1554 if (wpa_s->sme.assoc_req_ie_len + wpabuf_len(owe_ie) >
1555 sizeof(wpa_s->sme.assoc_req_ie)) {
1556 wpa_printf(MSG_ERROR,
1557 "OWE: Not enough buffer room for own Association Request frame elements");
1558 wpabuf_free(owe_ie);
1559 return;
1560 }
1561 os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
1562 wpabuf_head(owe_ie), wpabuf_len(owe_ie));
1563 wpa_s->sme.assoc_req_ie_len += wpabuf_len(owe_ie);
1564 wpabuf_free(owe_ie);
1565 }
1566 #endif /* CONFIG_OWE */
1567
1568 if (wpa_s->current_ssid && wpa_s->current_ssid->multi_ap_backhaul_sta) {
1569 size_t multi_ap_ie_len;
1570
1571 multi_ap_ie_len = add_multi_ap_ie(
1572 wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
1573 sizeof(wpa_s->sme.assoc_req_ie) -
1574 wpa_s->sme.assoc_req_ie_len,
1575 MULTI_AP_BACKHAUL_STA);
1576 if (multi_ap_ie_len == 0) {
1577 wpa_printf(MSG_ERROR,
1578 "Multi-AP: Failed to build Multi-AP IE");
1579 return;
1580 }
1581 wpa_s->sme.assoc_req_ie_len += multi_ap_ie_len;
1582 }
1583
1584 params.bssid = bssid;
1585 params.ssid = wpa_s->sme.ssid;
1586 params.ssid_len = wpa_s->sme.ssid_len;
1587 params.freq.freq = wpa_s->sme.freq;
1588 params.bg_scan_period = wpa_s->current_ssid ?
1589 wpa_s->current_ssid->bg_scan_period : -1;
1590 params.wpa_ie = wpa_s->sme.assoc_req_ie_len ?
1591 wpa_s->sme.assoc_req_ie : NULL;
1592 params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
1593 wpa_hexdump(MSG_DEBUG, "SME: Association Request IEs",
1594 params.wpa_ie, params.wpa_ie_len);
1595 params.pairwise_suite = wpa_s->pairwise_cipher;
1596 params.group_suite = wpa_s->group_cipher;
1597 params.mgmt_group_suite = wpa_s->mgmt_group_cipher;
1598 params.key_mgmt_suite = wpa_s->key_mgmt;
1599 params.wpa_proto = wpa_s->wpa_proto;
1600 #ifdef CONFIG_HT_OVERRIDES
1601 os_memset(&htcaps, 0, sizeof(htcaps));
1602 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
1603 params.htcaps = (u8 *) &htcaps;
1604 params.htcaps_mask = (u8 *) &htcaps_mask;
1605 wpa_supplicant_apply_ht_overrides(wpa_s, wpa_s->current_ssid, &params);
1606 #endif /* CONFIG_HT_OVERRIDES */
1607 #ifdef CONFIG_VHT_OVERRIDES
1608 os_memset(&vhtcaps, 0, sizeof(vhtcaps));
1609 os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
1610 params.vhtcaps = &vhtcaps;
1611 params.vhtcaps_mask = &vhtcaps_mask;
1612 wpa_supplicant_apply_vht_overrides(wpa_s, wpa_s->current_ssid, &params);
1613 #endif /* CONFIG_VHT_OVERRIDES */
1614 #ifdef CONFIG_IEEE80211R
1615 if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies &&
1616 get_ie(wpa_s->sme.ft_ies, wpa_s->sme.ft_ies_len,
1617 WLAN_EID_RIC_DATA)) {
1618 /* There seems to be a pretty inconvenient bug in the Linux
1619 * kernel IE splitting functionality when RIC is used. For now,
1620 * skip correct behavior in IE construction here (i.e., drop the
1621 * additional non-FT-specific IEs) to avoid kernel issues. This
1622 * is fine since RIC is used only for testing purposes in the
1623 * current implementation. */
1624 wpa_printf(MSG_INFO,
1625 "SME: Linux kernel workaround - do not try to include additional IEs with RIC");
1626 params.wpa_ie = wpa_s->sme.ft_ies;
1627 params.wpa_ie_len = wpa_s->sme.ft_ies_len;
1628 } else if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) {
1629 const u8 *rm_en, *pos, *end;
1630 size_t rm_en_len = 0;
1631 u8 *rm_en_dup = NULL, *wpos;
1632
1633 /* Remove RSNE, MDE, FTE to allow them to be overridden with
1634 * FT specific values */
1635 remove_ie(wpa_s->sme.assoc_req_ie,
1636 &wpa_s->sme.assoc_req_ie_len,
1637 WLAN_EID_RSN);
1638 remove_ie(wpa_s->sme.assoc_req_ie,
1639 &wpa_s->sme.assoc_req_ie_len,
1640 WLAN_EID_MOBILITY_DOMAIN);
1641 remove_ie(wpa_s->sme.assoc_req_ie,
1642 &wpa_s->sme.assoc_req_ie_len,
1643 WLAN_EID_FAST_BSS_TRANSITION);
1644 rm_en = get_ie(wpa_s->sme.assoc_req_ie,
1645 wpa_s->sme.assoc_req_ie_len,
1646 WLAN_EID_RRM_ENABLED_CAPABILITIES);
1647 if (rm_en) {
1648 /* Need to remove RM Enabled Capabilities element as
1649 * well temporarily, so that it can be placed between
1650 * RSNE and MDE. */
1651 rm_en_len = 2 + rm_en[1];
1652 rm_en_dup = os_memdup(rm_en, rm_en_len);
1653 remove_ie(wpa_s->sme.assoc_req_ie,
1654 &wpa_s->sme.assoc_req_ie_len,
1655 WLAN_EID_RRM_ENABLED_CAPABILITIES);
1656 }
1657 wpa_hexdump(MSG_DEBUG,
1658 "SME: Association Request IEs after FT IE removal",
1659 wpa_s->sme.assoc_req_ie,
1660 wpa_s->sme.assoc_req_ie_len);
1661 if (wpa_s->sme.assoc_req_ie_len + wpa_s->sme.ft_ies_len +
1662 rm_en_len > sizeof(wpa_s->sme.assoc_req_ie)) {
1663 wpa_printf(MSG_ERROR,
1664 "SME: Not enough buffer room for FT IEs in Association Request frame");
1665 os_free(rm_en_dup);
1666 return;
1667 }
1668
1669 os_memmove(wpa_s->sme.assoc_req_ie + wpa_s->sme.ft_ies_len +
1670 rm_en_len,
1671 wpa_s->sme.assoc_req_ie,
1672 wpa_s->sme.assoc_req_ie_len);
1673 pos = wpa_s->sme.ft_ies;
1674 end = pos + wpa_s->sme.ft_ies_len;
1675 wpos = wpa_s->sme.assoc_req_ie;
1676 if (*pos == WLAN_EID_RSN) {
1677 os_memcpy(wpos, pos, 2 + pos[1]);
1678 wpos += 2 + pos[1];
1679 pos += 2 + pos[1];
1680 }
1681 if (rm_en_dup) {
1682 os_memcpy(wpos, rm_en_dup, rm_en_len);
1683 wpos += rm_en_len;
1684 os_free(rm_en_dup);
1685 }
1686 os_memcpy(wpos, pos, end - pos);
1687 wpa_s->sme.assoc_req_ie_len += wpa_s->sme.ft_ies_len +
1688 rm_en_len;
1689 params.wpa_ie = wpa_s->sme.assoc_req_ie;
1690 params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
1691 wpa_hexdump(MSG_DEBUG,
1692 "SME: Association Request IEs after FT override",
1693 params.wpa_ie, params.wpa_ie_len);
1694 }
1695 #endif /* CONFIG_IEEE80211R */
1696 params.mode = mode;
1697 params.mgmt_frame_protection = wpa_s->sme.mfp;
1698 params.rrm_used = wpa_s->rrm.rrm_used;
1699 if (wpa_s->sme.prev_bssid_set)
1700 params.prev_bssid = wpa_s->sme.prev_bssid;
1701
1702 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
1703 " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
1704 params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "",
1705 params.freq.freq);
1706
1707 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
1708
1709 if (params.wpa_ie == NULL ||
1710 ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0)
1711 < 0) {
1712 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Could not parse own IEs?!");
1713 os_memset(&elems, 0, sizeof(elems));
1714 }
1715 if (elems.rsn_ie) {
1716 params.wpa_proto = WPA_PROTO_RSN;
1717 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2,
1718 elems.rsn_ie_len + 2);
1719 } else if (elems.wpa_ie) {
1720 params.wpa_proto = WPA_PROTO_WPA;
1721 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2,
1722 elems.wpa_ie_len + 2);
1723 } else if (elems.osen) {
1724 params.wpa_proto = WPA_PROTO_OSEN;
1725 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.osen - 2,
1726 elems.osen_len + 2);
1727 } else
1728 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1729 if (wpa_s->current_ssid && wpa_s->current_ssid->p2p_group)
1730 params.p2p = 1;
1731
1732 if (wpa_s->p2pdev->set_sta_uapsd)
1733 params.uapsd = wpa_s->p2pdev->sta_uapsd;
1734 else
1735 params.uapsd = -1;
1736
1737 if (wpa_drv_associate(wpa_s, &params) < 0) {
1738 wpa_msg(wpa_s, MSG_INFO, "SME: Association request to the "
1739 "driver failed");
1740 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
1741 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1742 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1743 return;
1744 }
1745
1746 eloop_register_timeout(SME_ASSOC_TIMEOUT, 0, sme_assoc_timer, wpa_s,
1747 NULL);
1748
1749 #ifdef CONFIG_TESTING_OPTIONS
1750 wpabuf_free(wpa_s->last_assoc_req_wpa_ie);
1751 wpa_s->last_assoc_req_wpa_ie = NULL;
1752 if (params.wpa_ie)
1753 wpa_s->last_assoc_req_wpa_ie =
1754 wpabuf_alloc_copy(params.wpa_ie, params.wpa_ie_len);
1755 #endif /* CONFIG_TESTING_OPTIONS */
1756 }
1757
1758
1759 int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
1760 const u8 *ies, size_t ies_len)
1761 {
1762 if (md == NULL || ies == NULL) {
1763 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Remove mobility domain");
1764 os_free(wpa_s->sme.ft_ies);
1765 wpa_s->sme.ft_ies = NULL;
1766 wpa_s->sme.ft_ies_len = 0;
1767 wpa_s->sme.ft_used = 0;
1768 return 0;
1769 }
1770
1771 os_memcpy(wpa_s->sme.mobility_domain, md, MOBILITY_DOMAIN_ID_LEN);
1772 wpa_hexdump(MSG_DEBUG, "SME: FT IEs", ies, ies_len);
1773 os_free(wpa_s->sme.ft_ies);
1774 wpa_s->sme.ft_ies = os_memdup(ies, ies_len);
1775 if (wpa_s->sme.ft_ies == NULL)
1776 return -1;
1777 wpa_s->sme.ft_ies_len = ies_len;
1778 return 0;
1779 }
1780
1781
1782 static void sme_deauth(struct wpa_supplicant *wpa_s)
1783 {
1784 int bssid_changed;
1785
1786 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
1787
1788 if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid,
1789 WLAN_REASON_DEAUTH_LEAVING) < 0) {
1790 wpa_msg(wpa_s, MSG_INFO, "SME: Deauth request to the driver "
1791 "failed");
1792 }
1793 wpa_s->sme.prev_bssid_set = 0;
1794
1795 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
1796 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
1797 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1798 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
1799 if (bssid_changed)
1800 wpas_notify_bssid_changed(wpa_s);
1801 }
1802
1803
1804 void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
1805 union wpa_event_data *data)
1806 {
1807 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association with " MACSTR " failed: "
1808 "status code %d", MAC2STR(wpa_s->pending_bssid),
1809 data->assoc_reject.status_code);
1810
1811 eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
1812
1813 #ifdef CONFIG_SAE
1814 if (wpa_s->sme.sae_pmksa_caching && wpa_s->current_ssid &&
1815 wpa_key_mgmt_sae(wpa_s->current_ssid->key_mgmt)) {
1816 wpa_dbg(wpa_s, MSG_DEBUG,
1817 "PMKSA caching attempt rejected - drop PMKSA cache entry and fall back to SAE authentication");
1818 wpa_sm_aborted_cached(wpa_s->wpa);
1819 wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_s->current_ssid);
1820 if (wpa_s->current_bss) {
1821 struct wpa_bss *bss = wpa_s->current_bss;
1822 struct wpa_ssid *ssid = wpa_s->current_ssid;
1823
1824 wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid,
1825 WLAN_REASON_DEAUTH_LEAVING);
1826 wpas_connect_work_done(wpa_s);
1827 wpa_supplicant_mark_disassoc(wpa_s);
1828 wpa_supplicant_connect(wpa_s, bss, ssid);
1829 return;
1830 }
1831 }
1832 #endif /* CONFIG_SAE */
1833
1834 /*
1835 * For now, unconditionally terminate the previous authentication. In
1836 * theory, this should not be needed, but mac80211 gets quite confused
1837 * if the authentication is left pending.. Some roaming cases might
1838 * benefit from using the previous authentication, so this could be
1839 * optimized in the future.
1840 */
1841 sme_deauth(wpa_s);
1842 }
1843
1844
1845 void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
1846 union wpa_event_data *data)
1847 {
1848 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication timed out");
1849 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
1850 wpa_supplicant_mark_disassoc(wpa_s);
1851 }
1852
1853
1854 void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
1855 union wpa_event_data *data)
1856 {
1857 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association timed out");
1858 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
1859 wpa_supplicant_mark_disassoc(wpa_s);
1860 }
1861
1862
1863 void sme_event_disassoc(struct wpa_supplicant *wpa_s,
1864 struct disassoc_info *info)
1865 {
1866 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Disassociation event received");
1867 if (wpa_s->sme.prev_bssid_set) {
1868 /*
1869 * cfg80211/mac80211 can get into somewhat confused state if
1870 * the AP only disassociates us and leaves us in authenticated
1871 * state. For now, force the state to be cleared to avoid
1872 * confusing errors if we try to associate with the AP again.
1873 */
1874 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Deauthenticate to clear "
1875 "driver state");
1876 wpa_drv_deauthenticate(wpa_s, wpa_s->sme.prev_bssid,
1877 WLAN_REASON_DEAUTH_LEAVING);
1878 }
1879 }
1880
1881
1882 static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx)
1883 {
1884 struct wpa_supplicant *wpa_s = eloop_ctx;
1885 if (wpa_s->wpa_state == WPA_AUTHENTICATING) {
1886 wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timeout");
1887 sme_deauth(wpa_s);
1888 }
1889 }
1890
1891
1892 static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx)
1893 {
1894 struct wpa_supplicant *wpa_s = eloop_ctx;
1895 if (wpa_s->wpa_state == WPA_ASSOCIATING) {
1896 wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timeout");
1897 sme_deauth(wpa_s);
1898 }
1899 }
1900
1901
1902 void sme_state_changed(struct wpa_supplicant *wpa_s)
1903 {
1904 /* Make sure timers are cleaned up appropriately. */
1905 if (wpa_s->wpa_state != WPA_ASSOCIATING)
1906 eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
1907 if (wpa_s->wpa_state != WPA_AUTHENTICATING)
1908 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
1909 }
1910
1911
1912 void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
1913 const u8 *prev_pending_bssid)
1914 {
1915 /*
1916 * mac80211-workaround to force deauth on failed auth cmd,
1917 * requires us to remain in authenticating state to allow the
1918 * second authentication attempt to be continued properly.
1919 */
1920 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Allow pending authentication "
1921 "to proceed after disconnection event");
1922 wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
1923 os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN);
1924
1925 /*
1926 * Re-arm authentication timer in case auth fails for whatever reason.
1927 */
1928 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
1929 eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s,
1930 NULL);
1931 }
1932
1933
1934 void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s)
1935 {
1936 wpa_s->sme.prev_bssid_set = 0;
1937 #ifdef CONFIG_SAE
1938 wpabuf_free(wpa_s->sme.sae_token);
1939 wpa_s->sme.sae_token = NULL;
1940 sae_clear_data(&wpa_s->sme.sae);
1941 #endif /* CONFIG_SAE */
1942 #ifdef CONFIG_IEEE80211R
1943 if (wpa_s->sme.ft_ies || wpa_s->sme.ft_used)
1944 sme_update_ft_ies(wpa_s, NULL, NULL, 0);
1945 #endif /* CONFIG_IEEE80211R */
1946 }
1947
1948
1949 void sme_deinit(struct wpa_supplicant *wpa_s)
1950 {
1951 os_free(wpa_s->sme.ft_ies);
1952 wpa_s->sme.ft_ies = NULL;
1953 wpa_s->sme.ft_ies_len = 0;
1954 #ifdef CONFIG_IEEE80211W
1955 sme_stop_sa_query(wpa_s);
1956 #endif /* CONFIG_IEEE80211W */
1957 sme_clear_on_disassoc(wpa_s);
1958
1959 eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
1960 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
1961 eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL);
1962 }
1963
1964
1965 static void sme_send_2040_bss_coex(struct wpa_supplicant *wpa_s,
1966 const u8 *chan_list, u8 num_channels,
1967 u8 num_intol)
1968 {
1969 struct ieee80211_2040_bss_coex_ie *bc_ie;
1970 struct ieee80211_2040_intol_chan_report *ic_report;
1971 struct wpabuf *buf;
1972
1973 wpa_printf(MSG_DEBUG, "SME: Send 20/40 BSS Coexistence to " MACSTR
1974 " (num_channels=%u num_intol=%u)",
1975 MAC2STR(wpa_s->bssid), num_channels, num_intol);
1976 wpa_hexdump(MSG_DEBUG, "SME: 20/40 BSS Intolerant Channels",
1977 chan_list, num_channels);
1978
1979 buf = wpabuf_alloc(2 + /* action.category + action_code */
1980 sizeof(struct ieee80211_2040_bss_coex_ie) +
1981 sizeof(struct ieee80211_2040_intol_chan_report) +
1982 num_channels);
1983 if (buf == NULL)
1984 return;
1985
1986 wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
1987 wpabuf_put_u8(buf, WLAN_PA_20_40_BSS_COEX);
1988
1989 bc_ie = wpabuf_put(buf, sizeof(*bc_ie));
1990 bc_ie->element_id = WLAN_EID_20_40_BSS_COEXISTENCE;
1991 bc_ie->length = 1;
1992 if (num_intol)
1993 bc_ie->coex_param |= WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ;
1994
1995 if (num_channels > 0) {
1996 ic_report = wpabuf_put(buf, sizeof(*ic_report));
1997 ic_report->element_id = WLAN_EID_20_40_BSS_INTOLERANT;
1998 ic_report->length = num_channels + 1;
1999 ic_report->op_class = 0;
2000 os_memcpy(wpabuf_put(buf, num_channels), chan_list,
2001 num_channels);
2002 }
2003
2004 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
2005 wpa_s->own_addr, wpa_s->bssid,
2006 wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
2007 wpa_msg(wpa_s, MSG_INFO,
2008 "SME: Failed to send 20/40 BSS Coexistence frame");
2009 }
2010
2011 wpabuf_free(buf);
2012 }
2013
2014
2015 int sme_proc_obss_scan(struct wpa_supplicant *wpa_s)
2016 {
2017 struct wpa_bss *bss;
2018 const u8 *ie;
2019 u16 ht_cap;
2020 u8 chan_list[P2P_MAX_CHANNELS], channel;
2021 u8 num_channels = 0, num_intol = 0, i;
2022
2023 if (!wpa_s->sme.sched_obss_scan)
2024 return 0;
2025
2026 wpa_s->sme.sched_obss_scan = 0;
2027 if (!wpa_s->current_bss || wpa_s->wpa_state != WPA_COMPLETED)
2028 return 1;
2029
2030 /*
2031 * Check whether AP uses regulatory triplet or channel triplet in
2032 * country info. Right now the operating class of the BSS channel
2033 * width trigger event is "unknown" (IEEE Std 802.11-2012 10.15.12),
2034 * based on the assumption that operating class triplet is not used in
2035 * beacon frame. If the First Channel Number/Operating Extension
2036 * Identifier octet has a positive integer value of 201 or greater,
2037 * then its operating class triplet.
2038 *
2039 * TODO: If Supported Operating Classes element is present in beacon
2040 * frame, have to lookup operating class in Annex E and fill them in
2041 * 2040 coex frame.
2042 */
2043 ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_COUNTRY);
2044 if (ie && (ie[1] >= 6) && (ie[5] >= 201))
2045 return 1;
2046
2047 os_memset(chan_list, 0, sizeof(chan_list));
2048
2049 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
2050 /* Skip other band bss */
2051 enum hostapd_hw_mode mode;
2052 mode = ieee80211_freq_to_chan(bss->freq, &channel);
2053 if (mode != HOSTAPD_MODE_IEEE80211G &&
2054 mode != HOSTAPD_MODE_IEEE80211B)
2055 continue;
2056
2057 ie = wpa_bss_get_ie(bss, WLAN_EID_HT_CAP);
2058 ht_cap = (ie && (ie[1] == 26)) ? WPA_GET_LE16(ie + 2) : 0;
2059 wpa_printf(MSG_DEBUG, "SME OBSS scan BSS " MACSTR
2060 " freq=%u chan=%u ht_cap=0x%x",
2061 MAC2STR(bss->bssid), bss->freq, channel, ht_cap);
2062
2063 if (!ht_cap || (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)) {
2064 if (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)
2065 num_intol++;
2066
2067 /* Check whether the channel is already considered */
2068 for (i = 0; i < num_channels; i++) {
2069 if (channel == chan_list[i])
2070 break;
2071 }
2072 if (i != num_channels)
2073 continue;
2074
2075 chan_list[num_channels++] = channel;
2076 }
2077 }
2078
2079 sme_send_2040_bss_coex(wpa_s, chan_list, num_channels, num_intol);
2080 return 1;
2081 }
2082
2083
2084 static void wpa_obss_scan_freqs_list(struct wpa_supplicant *wpa_s,
2085 struct wpa_driver_scan_params *params)
2086 {
2087 /* Include only affected channels */
2088 struct hostapd_hw_modes *mode;
2089 int count, i;
2090 int start, end;
2091
2092 mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
2093 HOSTAPD_MODE_IEEE80211G);
2094 if (mode == NULL) {
2095 /* No channels supported in this band - use empty list */
2096 params->freqs = os_zalloc(sizeof(int));
2097 return;
2098 }
2099
2100 if (wpa_s->sme.ht_sec_chan == HT_SEC_CHAN_UNKNOWN &&
2101 wpa_s->current_bss) {
2102 const u8 *ie;
2103
2104 ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_OPERATION);
2105 if (ie && ie[1] >= 2) {
2106 u8 o;
2107
2108 o = ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
2109 if (o == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
2110 wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_ABOVE;
2111 else if (o == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
2112 wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_BELOW;
2113 }
2114 }
2115
2116 start = wpa_s->assoc_freq - 10;
2117 end = wpa_s->assoc_freq + 10;
2118 switch (wpa_s->sme.ht_sec_chan) {
2119 case HT_SEC_CHAN_UNKNOWN:
2120 /* HT40+ possible on channels 1..9 */
2121 if (wpa_s->assoc_freq <= 2452)
2122 start -= 20;
2123 /* HT40- possible on channels 5-13 */
2124 if (wpa_s->assoc_freq >= 2432)
2125 end += 20;
2126 break;
2127 case HT_SEC_CHAN_ABOVE:
2128 end += 20;
2129 break;
2130 case HT_SEC_CHAN_BELOW:
2131 start -= 20;
2132 break;
2133 }
2134 wpa_printf(MSG_DEBUG,
2135 "OBSS: assoc_freq %d possible affected range %d-%d",
2136 wpa_s->assoc_freq, start, end);
2137
2138 params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
2139 if (params->freqs == NULL)
2140 return;
2141 for (count = 0, i = 0; i < mode->num_channels; i++) {
2142 int freq;
2143
2144 if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
2145 continue;
2146 freq = mode->channels[i].freq;
2147 if (freq - 10 >= end || freq + 10 <= start)
2148 continue; /* not affected */
2149 params->freqs[count++] = freq;
2150 }
2151 }
2152
2153
2154 static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx)
2155 {
2156 struct wpa_supplicant *wpa_s = eloop_ctx;
2157 struct wpa_driver_scan_params params;
2158
2159 if (!wpa_s->current_bss) {
2160 wpa_printf(MSG_DEBUG, "SME OBSS: Ignore scan request");
2161 return;
2162 }
2163
2164 os_memset(&params, 0, sizeof(params));
2165 wpa_obss_scan_freqs_list(wpa_s, &params);
2166 params.low_priority = 1;
2167 wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan");
2168
2169 if (wpa_supplicant_trigger_scan(wpa_s, &params))
2170 wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan");
2171 else
2172 wpa_s->sme.sched_obss_scan = 1;
2173 os_free(params.freqs);
2174
2175 eloop_register_timeout(wpa_s->sme.obss_scan_int, 0,
2176 sme_obss_scan_timeout, wpa_s, NULL);
2177 }
2178
2179
2180 void sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable)
2181 {
2182 const u8 *ie;
2183 struct wpa_bss *bss = wpa_s->current_bss;
2184 struct wpa_ssid *ssid = wpa_s->current_ssid;
2185 struct hostapd_hw_modes *hw_mode = NULL;
2186 int i;
2187
2188 eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL);
2189 wpa_s->sme.sched_obss_scan = 0;
2190 wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_UNKNOWN;
2191 if (!enable)
2192 return;
2193
2194 /*
2195 * Schedule OBSS scan if driver is using station SME in wpa_supplicant
2196 * or it expects OBSS scan to be performed by wpa_supplicant.
2197 */
2198 if (!((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
2199 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OBSS_SCAN)) ||
2200 ssid == NULL || ssid->mode != IEEE80211_MODE_INFRA)
2201 return;
2202
2203 if (!wpa_s->hw.modes)
2204 return;
2205
2206 /* only HT caps in 11g mode are relevant */
2207 for (i = 0; i < wpa_s->hw.num_modes; i++) {
2208 hw_mode = &wpa_s->hw.modes[i];
2209 if (hw_mode->mode == HOSTAPD_MODE_IEEE80211G)
2210 break;
2211 }
2212
2213 /* Driver does not support HT40 for 11g or doesn't have 11g. */
2214 if (i == wpa_s->hw.num_modes || !hw_mode ||
2215 !(hw_mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
2216 return;
2217
2218 if (bss == NULL || bss->freq < 2400 || bss->freq > 2500)
2219 return; /* Not associated on 2.4 GHz band */
2220
2221 /* Check whether AP supports HT40 */
2222 ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_CAP);
2223 if (!ie || ie[1] < 2 ||
2224 !(WPA_GET_LE16(ie + 2) & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
2225 return; /* AP does not support HT40 */
2226
2227 ie = wpa_bss_get_ie(wpa_s->current_bss,
2228 WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS);
2229 if (!ie || ie[1] < 14)
2230 return; /* AP does not request OBSS scans */
2231
2232 wpa_s->sme.obss_scan_int = WPA_GET_LE16(ie + 6);
2233 if (wpa_s->sme.obss_scan_int < 10) {
2234 wpa_printf(MSG_DEBUG, "SME: Invalid OBSS Scan Interval %u "
2235 "replaced with the minimum 10 sec",
2236 wpa_s->sme.obss_scan_int);
2237 wpa_s->sme.obss_scan_int = 10;
2238 }
2239 wpa_printf(MSG_DEBUG, "SME: OBSS Scan Interval %u sec",
2240 wpa_s->sme.obss_scan_int);
2241 eloop_register_timeout(wpa_s->sme.obss_scan_int, 0,
2242 sme_obss_scan_timeout, wpa_s, NULL);
2243 }
2244
2245
2246 #ifdef CONFIG_IEEE80211W
2247
2248 static const unsigned int sa_query_max_timeout = 1000;
2249 static const unsigned int sa_query_retry_timeout = 201;
2250 static const unsigned int sa_query_ch_switch_max_delay = 5000; /* in usec */
2251
2252 static int sme_check_sa_query_timeout(struct wpa_supplicant *wpa_s)
2253 {
2254 u32 tu;
2255 struct os_reltime now, passed;
2256 os_get_reltime(&now);
2257 os_reltime_sub(&now, &wpa_s->sme.sa_query_start, &passed);
2258 tu = (passed.sec * 1000000 + passed.usec) / 1024;
2259 if (sa_query_max_timeout < tu) {
2260 wpa_dbg(wpa_s, MSG_DEBUG, "SME: SA Query timed out");
2261 sme_stop_sa_query(wpa_s);
2262 wpa_supplicant_deauthenticate(
2263 wpa_s, WLAN_REASON_PREV_AUTH_NOT_VALID);
2264 return 1;
2265 }
2266
2267 return 0;
2268 }
2269
2270
2271 static void sme_send_sa_query_req(struct wpa_supplicant *wpa_s,
2272 const u8 *trans_id)
2273 {
2274 u8 req[2 + WLAN_SA_QUERY_TR_ID_LEN + OCV_OCI_EXTENDED_LEN];
2275 u8 req_len = 2 + WLAN_SA_QUERY_TR_ID_LEN;
2276
2277 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Request to "
2278 MACSTR, MAC2STR(wpa_s->bssid));
2279 wpa_hexdump(MSG_DEBUG, "SME: SA Query Transaction ID",
2280 trans_id, WLAN_SA_QUERY_TR_ID_LEN);
2281 req[0] = WLAN_ACTION_SA_QUERY;
2282 req[1] = WLAN_SA_QUERY_REQUEST;
2283 os_memcpy(req + 2, trans_id, WLAN_SA_QUERY_TR_ID_LEN);
2284
2285 #ifdef CONFIG_OCV
2286 if (wpa_sm_ocv_enabled(wpa_s->wpa)) {
2287 struct wpa_channel_info ci;
2288
2289 if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
2290 wpa_printf(MSG_WARNING,
2291 "Failed to get channel info for OCI element in SA Query Request frame");
2292 return;
2293 }
2294
2295 if (ocv_insert_extended_oci(&ci, req + req_len) < 0)
2296 return;
2297
2298 req_len += OCV_OCI_EXTENDED_LEN;
2299 }
2300 #endif /* CONFIG_OCV */
2301
2302 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
2303 wpa_s->own_addr, wpa_s->bssid,
2304 req, req_len, 0) < 0)
2305 wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send SA Query "
2306 "Request");
2307 }
2308
2309
2310 static void sme_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
2311 {
2312 struct wpa_supplicant *wpa_s = eloop_ctx;
2313 unsigned int timeout, sec, usec;
2314 u8 *trans_id, *nbuf;
2315
2316 if (wpa_s->sme.sa_query_count > 0 &&
2317 sme_check_sa_query_timeout(wpa_s))
2318 return;
2319
2320 nbuf = os_realloc_array(wpa_s->sme.sa_query_trans_id,
2321 wpa_s->sme.sa_query_count + 1,
2322 WLAN_SA_QUERY_TR_ID_LEN);
2323 if (nbuf == NULL) {
2324 sme_stop_sa_query(wpa_s);
2325 return;
2326 }
2327 if (wpa_s->sme.sa_query_count == 0) {
2328 /* Starting a new SA Query procedure */
2329 os_get_reltime(&wpa_s->sme.sa_query_start);
2330 }
2331 trans_id = nbuf + wpa_s->sme.sa_query_count * WLAN_SA_QUERY_TR_ID_LEN;
2332 wpa_s->sme.sa_query_trans_id = nbuf;
2333 wpa_s->sme.sa_query_count++;
2334
2335 if (os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0) {
2336 wpa_printf(MSG_DEBUG, "Could not generate SA Query ID");
2337 sme_stop_sa_query(wpa_s);
2338 return;
2339 }
2340
2341 timeout = sa_query_retry_timeout;
2342 sec = ((timeout / 1000) * 1024) / 1000;
2343 usec = (timeout % 1000) * 1024;
2344 eloop_register_timeout(sec, usec, sme_sa_query_timer, wpa_s, NULL);
2345
2346 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association SA Query attempt %d",
2347 wpa_s->sme.sa_query_count);
2348
2349 sme_send_sa_query_req(wpa_s, trans_id);
2350 }
2351
2352
2353 static void sme_start_sa_query(struct wpa_supplicant *wpa_s)
2354 {
2355 sme_sa_query_timer(wpa_s, NULL);
2356 }
2357
2358
2359 static void sme_stop_sa_query(struct wpa_supplicant *wpa_s)
2360 {
2361 eloop_cancel_timeout(sme_sa_query_timer, wpa_s, NULL);
2362 os_free(wpa_s->sme.sa_query_trans_id);
2363 wpa_s->sme.sa_query_trans_id = NULL;
2364 wpa_s->sme.sa_query_count = 0;
2365 }
2366
2367
2368 void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa,
2369 const u8 *da, u16 reason_code)
2370 {
2371 struct wpa_ssid *ssid;
2372 struct os_reltime now;
2373
2374 if (wpa_s->wpa_state != WPA_COMPLETED)
2375 return;
2376 ssid = wpa_s->current_ssid;
2377 if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION)
2378 return;
2379 if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0)
2380 return;
2381 if (reason_code != WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA &&
2382 reason_code != WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA)
2383 return;
2384 if (wpa_s->sme.sa_query_count > 0)
2385 return;
2386
2387 os_get_reltime(&now);
2388 if (wpa_s->sme.last_unprot_disconnect.sec &&
2389 !os_reltime_expired(&now, &wpa_s->sme.last_unprot_disconnect, 10))
2390 return; /* limit SA Query procedure frequency */
2391 wpa_s->sme.last_unprot_disconnect = now;
2392
2393 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Unprotected disconnect dropped - "
2394 "possible AP/STA state mismatch - trigger SA Query");
2395 sme_start_sa_query(wpa_s);
2396 }
2397
2398
2399 void sme_event_ch_switch(struct wpa_supplicant *wpa_s)
2400 {
2401 unsigned int usec;
2402 u32 _rand;
2403
2404 if (wpa_s->wpa_state != WPA_COMPLETED ||
2405 !wpa_sm_ocv_enabled(wpa_s->wpa))
2406 return;
2407
2408 wpa_dbg(wpa_s, MSG_DEBUG,
2409 "SME: Channel switch completed - trigger new SA Query to verify new operating channel");
2410 sme_stop_sa_query(wpa_s);
2411
2412 if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0)
2413 _rand = os_random();
2414 usec = _rand % (sa_query_ch_switch_max_delay + 1);
2415 eloop_register_timeout(0, usec, sme_sa_query_timer, wpa_s, NULL);
2416 }
2417
2418
2419 static void sme_process_sa_query_request(struct wpa_supplicant *wpa_s,
2420 const u8 *sa, const u8 *data,
2421 size_t len)
2422 {
2423 u8 resp[2 + WLAN_SA_QUERY_TR_ID_LEN + OCV_OCI_EXTENDED_LEN];
2424 u8 resp_len = 2 + WLAN_SA_QUERY_TR_ID_LEN;
2425
2426 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Response to "
2427 MACSTR, MAC2STR(wpa_s->bssid));
2428
2429 resp[0] = WLAN_ACTION_SA_QUERY;
2430 resp[1] = WLAN_SA_QUERY_RESPONSE;
2431 os_memcpy(resp + 2, data + 1, WLAN_SA_QUERY_TR_ID_LEN);
2432
2433 #ifdef CONFIG_OCV
2434 if (wpa_sm_ocv_enabled(wpa_s->wpa)) {
2435 struct wpa_channel_info ci;
2436
2437 if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
2438 wpa_printf(MSG_WARNING,
2439 "Failed to get channel info for OCI element in SA Query Response frame");
2440 return;
2441 }
2442
2443 if (ocv_insert_extended_oci(&ci, resp + resp_len) < 0)
2444 return;
2445
2446 resp_len += OCV_OCI_EXTENDED_LEN;
2447 }
2448 #endif /* CONFIG_OCV */
2449
2450 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
2451 wpa_s->own_addr, wpa_s->bssid,
2452 resp, resp_len, 0) < 0)
2453 wpa_msg(wpa_s, MSG_INFO,
2454 "SME: Failed to send SA Query Response");
2455 }
2456
2457
2458 static void sme_process_sa_query_response(struct wpa_supplicant *wpa_s,
2459 const u8 *sa, const u8 *data,
2460 size_t len)
2461 {
2462 int i;
2463
2464 if (!wpa_s->sme.sa_query_trans_id)
2465 return;
2466
2467 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query response from "
2468 MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]);
2469
2470 if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0)
2471 return;
2472
2473 for (i = 0; i < wpa_s->sme.sa_query_count; i++) {
2474 if (os_memcmp(wpa_s->sme.sa_query_trans_id +
2475 i * WLAN_SA_QUERY_TR_ID_LEN,
2476 data + 1, WLAN_SA_QUERY_TR_ID_LEN) == 0)
2477 break;
2478 }
2479
2480 if (i >= wpa_s->sme.sa_query_count) {
2481 wpa_dbg(wpa_s, MSG_DEBUG, "SME: No matching SA Query "
2482 "transaction identifier found");
2483 return;
2484 }
2485
2486 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reply to pending SA Query received "
2487 "from " MACSTR, MAC2STR(sa));
2488 sme_stop_sa_query(wpa_s);
2489 }
2490
2491
2492 void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa,
2493 const u8 *data, size_t len)
2494 {
2495 if (len < 1 + WLAN_SA_QUERY_TR_ID_LEN)
2496 return;
2497
2498 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query frame from "
2499 MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]);
2500
2501 #ifdef CONFIG_OCV
2502 if (wpa_sm_ocv_enabled(wpa_s->wpa)) {
2503 struct ieee802_11_elems elems;
2504 struct wpa_channel_info ci;
2505
2506 if (ieee802_11_parse_elems(data + 1 + WLAN_SA_QUERY_TR_ID_LEN,
2507 len - 1 - WLAN_SA_QUERY_TR_ID_LEN,
2508 &elems, 1) == ParseFailed) {
2509 wpa_printf(MSG_DEBUG,
2510 "SA Query: Failed to parse elements");
2511 return;
2512 }
2513
2514 if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
2515 wpa_printf(MSG_WARNING,
2516 "Failed to get channel info to validate received OCI in SA Query Action frame");
2517 return;
2518 }
2519
2520 if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
2521 channel_width_to_int(ci.chanwidth),
2522 ci.seg1_idx) != 0) {
2523 wpa_printf(MSG_WARNING, "%s", ocv_errorstr);
2524 return;
2525 }
2526 }
2527 #endif /* CONFIG_OCV */
2528
2529 if (data[0] == WLAN_SA_QUERY_REQUEST)
2530 sme_process_sa_query_request(wpa_s, sa, data, len);
2531 else if (data[0] == WLAN_SA_QUERY_RESPONSE)
2532 sme_process_sa_query_response(wpa_s, sa, data, len);
2533 }
2534
2535 #endif /* CONFIG_IEEE80211W */