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