blob: 4ed0a3003ff42f324208ee5d9568ee5e3d2585f8 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/*
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 "utils/ext_password.h"
14#include "common/ieee802_11_defs.h"
15#include "common/ieee802_11_common.h"
16#include "common/ocv.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
38static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx);
39static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx);
40static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx);
41static void sme_stop_sa_query(struct wpa_supplicant *wpa_s);
42
43
44#ifdef CONFIG_SAE
45
46static 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
57static int sme_set_sae_group(struct wpa_supplicant *wpa_s, bool external)
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 wpa_s->sme.sae.akmp = external ?
77 wpa_s->sme.ext_auth_key_mgmt : wpa_s->key_mgmt;
78 return 0;
79 }
80 wpa_s->sme.sae_group_index++;
81 }
82
83 return -1;
84}
85
86
87static struct wpabuf * sme_auth_build_sae_commit(struct wpa_supplicant *wpa_s,
88 struct wpa_ssid *ssid,
89 const u8 *bssid,
90 const u8 *mld_addr,
91 int external,
92 int reuse, int *ret_use_pt,
93 bool *ret_use_pk)
94{
95 struct wpabuf *buf;
96 size_t len;
97 char *password = NULL;
98 struct wpa_bss *bss;
99 int use_pt = 0;
100 bool use_pk = false;
101 u8 rsnxe_capa = 0;
102 int key_mgmt = external ? wpa_s->sme.ext_auth_key_mgmt :
103 wpa_s->key_mgmt;
104 const u8 *addr = mld_addr ? mld_addr : bssid;
105
106 if (ret_use_pt)
107 *ret_use_pt = 0;
108 if (ret_use_pk)
109 *ret_use_pk = false;
110
111#ifdef CONFIG_TESTING_OPTIONS
112 if (wpa_s->sae_commit_override) {
113 wpa_printf(MSG_DEBUG, "SAE: TESTING - commit override");
114 buf = wpabuf_alloc(4 + wpabuf_len(wpa_s->sae_commit_override));
115 if (!buf)
116 goto fail;
117 if (!external) {
118 wpabuf_put_le16(buf, 1); /* Transaction seq# */
119 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
120 }
121 wpabuf_put_buf(buf, wpa_s->sae_commit_override);
122 return buf;
123 }
124#endif /* CONFIG_TESTING_OPTIONS */
125
126 if (ssid->sae_password) {
127 password = os_strdup(ssid->sae_password);
128 if (!password) {
129 wpa_dbg(wpa_s, MSG_INFO,
130 "SAE: Failed to allocate password");
131 goto fail;
132 }
133 }
134 if (!password && ssid->passphrase) {
135 password = os_strdup(ssid->passphrase);
136 if (!password) {
137 wpa_dbg(wpa_s, MSG_INFO,
138 "SAE: Failed to allocate password");
139 goto fail;
140 }
141 }
142 if (!password && ssid->ext_psk) {
143 struct wpabuf *pw = ext_password_get(wpa_s->ext_pw,
144 ssid->ext_psk);
145
146 if (!pw) {
147 wpa_msg(wpa_s, MSG_INFO,
148 "SAE: No password found from external storage");
149 goto fail;
150 }
151
152 password = os_malloc(wpabuf_len(pw) + 1);
153 if (!password) {
154 wpa_dbg(wpa_s, MSG_INFO,
155 "SAE: Failed to allocate password");
156 goto fail;
157 }
158 os_memcpy(password, wpabuf_head(pw), wpabuf_len(pw));
159 password[wpabuf_len(pw)] = '\0';
160 ext_password_free(pw);
161 }
162 if (!password) {
163 wpa_printf(MSG_DEBUG, "SAE: No password available");
164 goto fail;
165 }
166
167 if (reuse && wpa_s->sme.sae.tmp &&
168 os_memcmp(addr, wpa_s->sme.sae.tmp->bssid, ETH_ALEN) == 0) {
169 wpa_printf(MSG_DEBUG,
170 "SAE: Reuse previously generated PWE on a retry with the same AP");
171 use_pt = wpa_s->sme.sae.h2e;
172 use_pk = wpa_s->sme.sae.pk;
173 goto reuse_data;
174 }
175 if (sme_set_sae_group(wpa_s, external) < 0) {
176 wpa_printf(MSG_DEBUG, "SAE: Failed to select group");
177 goto fail;
178 }
179
180 bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
181 if (!bss) {
182 wpa_printf(MSG_DEBUG,
183 "SAE: BSS not available, update scan result to get BSS");
184 wpa_supplicant_update_scan_results(wpa_s);
185 bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
186 }
187 if (bss) {
188 const u8 *rsnxe;
189
190 rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
191 if (rsnxe && rsnxe[1] >= 1)
192 rsnxe_capa = rsnxe[2];
193 }
194
195 if (ssid->sae_password_id &&
196 wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK)
197 use_pt = 1;
198 if (wpa_key_mgmt_sae_ext_key(key_mgmt) &&
199 wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK)
200 use_pt = 1;
201 if (bss && is_6ghz_freq(bss->freq) &&
202 wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK)
203 use_pt = 1;
204#ifdef CONFIG_SAE_PK
205 if ((rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_PK)) &&
206 ssid->sae_pk != SAE_PK_MODE_DISABLED &&
207 ((ssid->sae_password &&
208 sae_pk_valid_password(ssid->sae_password)) ||
209 (!ssid->sae_password && ssid->passphrase &&
210 sae_pk_valid_password(ssid->passphrase)))) {
211 use_pt = 1;
212 use_pk = true;
213 }
214
215 if (ssid->sae_pk == SAE_PK_MODE_ONLY && !use_pk) {
216 wpa_printf(MSG_DEBUG,
217 "SAE: Cannot use PK with the selected AP");
218 goto fail;
219 }
220#endif /* CONFIG_SAE_PK */
221
222 if (use_pt || wpa_s->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT ||
223 wpa_s->conf->sae_pwe == SAE_PWE_BOTH) {
224 use_pt = !!(rsnxe_capa & BIT(WLAN_RSNX_CAPAB_SAE_H2E));
225
226 if ((wpa_s->conf->sae_pwe == SAE_PWE_HASH_TO_ELEMENT ||
227 ssid->sae_password_id ||
228 wpa_key_mgmt_sae_ext_key(key_mgmt)) &&
229 wpa_s->conf->sae_pwe != SAE_PWE_FORCE_HUNT_AND_PECK &&
230 !use_pt) {
231 wpa_printf(MSG_DEBUG,
232 "SAE: Cannot use H2E with the selected AP");
233 goto fail;
234 }
235 }
236
237 if (use_pt && !ssid->pt)
238 wpa_s_setup_sae_pt(wpa_s->conf, ssid, true);
239 if (use_pt &&
240 sae_prepare_commit_pt(&wpa_s->sme.sae, ssid->pt,
241 wpa_s->own_addr, addr,
242 wpa_s->sme.sae_rejected_groups, NULL) < 0)
243 goto fail;
244 if (!use_pt &&
245 sae_prepare_commit(wpa_s->own_addr, bssid,
246 (u8 *) password, os_strlen(password),
247 &wpa_s->sme.sae) < 0) {
248 wpa_printf(MSG_DEBUG, "SAE: Could not pick PWE");
249 goto fail;
250 }
251 if (wpa_s->sme.sae.tmp) {
252 os_memcpy(wpa_s->sme.sae.tmp->bssid, addr, ETH_ALEN);
253 if (use_pt && use_pk)
254 wpa_s->sme.sae.pk = 1;
255#ifdef CONFIG_SAE_PK
256 os_memcpy(wpa_s->sme.sae.tmp->own_addr, wpa_s->own_addr,
257 ETH_ALEN);
258 os_memcpy(wpa_s->sme.sae.tmp->peer_addr, addr, ETH_ALEN);
259 sae_pk_set_password(&wpa_s->sme.sae, password);
260#endif /* CONFIG_SAE_PK */
261 }
262
263reuse_data:
264 len = wpa_s->sme.sae_token ? 3 + wpabuf_len(wpa_s->sme.sae_token) : 0;
265 if (ssid->sae_password_id)
266 len += 4 + os_strlen(ssid->sae_password_id);
267 buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + len);
268 if (buf == NULL)
269 goto fail;
270 if (!external) {
271 wpabuf_put_le16(buf, 1); /* Transaction seq# */
272 if (use_pk)
273 wpabuf_put_le16(buf, WLAN_STATUS_SAE_PK);
274 else if (use_pt)
275 wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
276 else
277 wpabuf_put_le16(buf,WLAN_STATUS_SUCCESS);
278 }
279 if (sae_write_commit(&wpa_s->sme.sae, buf, wpa_s->sme.sae_token,
280 ssid->sae_password_id) < 0) {
281 wpabuf_free(buf);
282 goto fail;
283 }
284 if (ret_use_pt)
285 *ret_use_pt = use_pt;
286 if (ret_use_pk)
287 *ret_use_pk = use_pk;
288
289 str_clear_free(password);
290 return buf;
291
292fail:
293 str_clear_free(password);
294 return NULL;
295}
296
297
298static struct wpabuf * sme_auth_build_sae_confirm(struct wpa_supplicant *wpa_s,
299 int external)
300{
301 struct wpabuf *buf;
302
303 buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN);
304 if (buf == NULL)
305 return NULL;
306
307 if (!external) {
308 wpabuf_put_le16(buf, 2); /* Transaction seq# */
309 wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
310 }
311 sae_write_confirm(&wpa_s->sme.sae, buf);
312
313 return buf;
314}
315
316#endif /* CONFIG_SAE */
317
318
319/**
320 * sme_auth_handle_rrm - Handle RRM aspects of current authentication attempt
321 * @wpa_s: Pointer to wpa_supplicant data
322 * @bss: Pointer to the bss which is the target of authentication attempt
323 */
324static void sme_auth_handle_rrm(struct wpa_supplicant *wpa_s,
325 struct wpa_bss *bss)
326{
327 const u8 rrm_ie_len = 5;
328 u8 *pos;
329 const u8 *rrm_ie;
330
331 wpa_s->rrm.rrm_used = 0;
332
333 wpa_printf(MSG_DEBUG,
334 "RRM: Determining whether RRM can be used - device support: 0x%x",
335 wpa_s->drv_rrm_flags);
336
337 rrm_ie = wpa_bss_get_ie(bss, WLAN_EID_RRM_ENABLED_CAPABILITIES);
338 if (!rrm_ie || !(bss->caps & IEEE80211_CAP_RRM)) {
339 wpa_printf(MSG_DEBUG, "RRM: No RRM in network");
340 return;
341 }
342
343 if (!((wpa_s->drv_rrm_flags &
344 WPA_DRIVER_FLAGS_DS_PARAM_SET_IE_IN_PROBES) &&
345 (wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_QUIET)) &&
346 !(wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_SUPPORT_RRM)) {
347 wpa_printf(MSG_DEBUG,
348 "RRM: Insufficient RRM support in driver - do not use RRM");
349 return;
350 }
351
352 if (sizeof(wpa_s->sme.assoc_req_ie) <
353 wpa_s->sme.assoc_req_ie_len + rrm_ie_len + 2) {
354 wpa_printf(MSG_INFO,
355 "RRM: Unable to use RRM, no room for RRM IE");
356 return;
357 }
358
359 wpa_printf(MSG_DEBUG, "RRM: Adding RRM IE to Association Request");
360 pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
361 os_memset(pos, 0, 2 + rrm_ie_len);
362 *pos++ = WLAN_EID_RRM_ENABLED_CAPABILITIES;
363 *pos++ = rrm_ie_len;
364
365 /* Set supported capabilities flags */
366 if (wpa_s->drv_rrm_flags & WPA_DRIVER_FLAGS_TX_POWER_INSERTION)
367 *pos |= WLAN_RRM_CAPS_LINK_MEASUREMENT;
368
369 *pos |= WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE |
370 WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE |
371 WLAN_RRM_CAPS_BEACON_REPORT_TABLE;
372
373 if (wpa_s->lci)
374 pos[1] |= WLAN_RRM_CAPS_LCI_MEASUREMENT;
375
376 wpa_s->sme.assoc_req_ie_len += rrm_ie_len + 2;
377 wpa_s->rrm.rrm_used = 1;
378}
379
380
381static bool wpas_ml_element(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
382 struct wpa_ssid *ssid)
383{
384 struct wpabuf *mlbuf;
385 const u8 *rnr_ie, *pos, *rsn_ie;
386 struct wpa_ie_data ie;
387 u8 ml_ie_len, rnr_ie_len;
388 const struct ieee80211_eht_ml *eht_ml;
389 const struct eht_ml_basic_common_info *ml_basic_common_info;
390 u8 i;
391 const u16 control =
392 host_to_le16(MULTI_LINK_CONTROL_TYPE_BASIC |
393 BASIC_MULTI_LINK_CTRL_PRES_LINK_ID |
394 BASIC_MULTI_LINK_CTRL_PRES_BSS_PARAM_CH_COUNT |
395 BASIC_MULTI_LINK_CTRL_PRES_MLD_CAPA);
396 bool ret = false;
397
398 if (!(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_MLO))
399 return false;
400
401 mlbuf = wpa_bss_defrag_mle(bss, MULTI_LINK_CONTROL_TYPE_BASIC);
402 if (!mlbuf) {
403 wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No ML element");
404 return false;
405 }
406
407 rsn_ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
408 if (!rsn_ie || wpa_parse_wpa_ie(rsn_ie, 2 + rsn_ie[1], &ie)) {
409 wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No RSN element");
410 goto out;
411 }
412
413 if (!(ie.capabilities & WPA_CAPABILITY_MFPC) ||
414 wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION) {
415 wpa_dbg(wpa_s, MSG_DEBUG,
416 "MLD: No management frame protection");
417 goto out;
418 }
419
420 ie.key_mgmt &= ~(WPA_KEY_MGMT_PSK | WPA_KEY_MGMT_FT_PSK |
421 WPA_KEY_MGMT_PSK_SHA256);
422 if (!(ie.key_mgmt & ssid->key_mgmt)) {
423 wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No valid key management");
424 goto out;
425 }
426
427 ml_ie_len = wpabuf_len(mlbuf);
428
429 /* control + common info len + MLD address + MLD link information */
430 if (ml_ie_len < 2 + 1 + ETH_ALEN + 1)
431 goto out;
432
433 eht_ml = wpabuf_head(mlbuf);
434 if ((eht_ml->ml_control & control) != control) {
435 wpa_printf(MSG_DEBUG, "MLD: Unexpected ML element control=0x%x",
436 eht_ml->ml_control);
437 goto out;
438 }
439
440 ml_basic_common_info =
441 (const struct eht_ml_basic_common_info *) eht_ml->variable;
442
443 /* common info length should be valid (self, mld_addr, link_id) */
444 if (ml_basic_common_info->len < 1 + ETH_ALEN + 1)
445 goto out;
446
447 /* get the MLD address and MLD link ID */
448 os_memcpy(wpa_s->ap_mld_addr, ml_basic_common_info->mld_addr,
449 ETH_ALEN);
450 wpa_s->mlo_assoc_link_id = ml_basic_common_info->variable[0] &
451 EHT_ML_LINK_ID_MSK;
452
453 os_memcpy(wpa_s->links[wpa_s->mlo_assoc_link_id].bssid, bss->bssid,
454 ETH_ALEN);
455 wpa_s->links[wpa_s->mlo_assoc_link_id].freq = bss->freq;
456
457 wpa_printf(MSG_DEBUG, "MLD: address=" MACSTR ", link ID=%u",
458 MAC2STR(wpa_s->ap_mld_addr), wpa_s->mlo_assoc_link_id);
459
460 wpa_s->valid_links = BIT(wpa_s->mlo_assoc_link_id);
461
462 rnr_ie = wpa_bss_get_ie(bss, WLAN_EID_REDUCED_NEIGHBOR_REPORT);
463 if (!rnr_ie) {
464 wpa_dbg(wpa_s, MSG_DEBUG, "MLD: No RNR element");
465 ret = true;
466 goto out;
467 }
468
469 rnr_ie_len = rnr_ie[1];
470 pos = rnr_ie + 2;
471
472 while (rnr_ie_len > sizeof(struct ieee80211_neighbor_ap_info)) {
473 const struct ieee80211_neighbor_ap_info *ap_info =
474 (const struct ieee80211_neighbor_ap_info *) pos;
475 const u8 *data = ap_info->data;
476 size_t len = sizeof(struct ieee80211_neighbor_ap_info) +
477 ap_info->tbtt_info_len;
478
479 wpa_printf(MSG_DEBUG, "MLD: op_class=%u, channel=%u",
480 ap_info->op_class, ap_info->channel);
481
482 if (len > rnr_ie_len)
483 break;
484
485 if (ap_info->tbtt_info_len < 16) {
486 rnr_ie_len -= len;
487 pos += len;
488 continue;
489 }
490
491 data += 13;
492
493 wpa_printf(MSG_DEBUG, "MLD: mld ID=%u, link ID=%u",
494 *data, *(data + 1) & 0xF);
495
496 if (*data) {
497 wpa_printf(MSG_DEBUG,
498 "MLD: Reported link not part of MLD");
499 } else {
500 struct wpa_bss *neigh_bss =
501 wpa_bss_get_bssid(wpa_s, ap_info->data + 1);
502 u8 link_id = *(data + 1) & 0xF;
503
504 if (neigh_bss) {
505 if (wpa_scan_res_match(wpa_s, 0, neigh_bss,
506 wpa_s->current_ssid,
507 1, 0)) {
508 wpa_s->valid_links |= BIT(link_id);
509 os_memcpy(wpa_s->links[link_id].bssid,
510 ap_info->data + 1, ETH_ALEN);
511 wpa_s->links[link_id].freq =
512 neigh_bss->freq;
513 } else {
514 wpa_printf(MSG_DEBUG,
515 "MLD: Neighbor doesn't match current SSID - skip link");
516 }
517 } else {
518 wpa_printf(MSG_DEBUG,
519 "MLD: Neighbor not found in scan");
520 }
521 }
522
523 rnr_ie_len -= len;
524 pos += len;
525 }
526
527 wpa_printf(MSG_DEBUG, "MLD: valid_links=0x%x", wpa_s->valid_links);
528
529 for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
530 if (!(wpa_s->valid_links & BIT(i)))
531 continue;
532
533 wpa_printf(MSG_DEBUG, "MLD: link=%u, bssid=" MACSTR,
534 i, MAC2STR(wpa_s->links[i].bssid));
535 }
536
537 ret = true;
538out:
539 wpabuf_free(mlbuf);
540 return ret;
541}
542
543
544static void wpas_sme_ml_auth(struct wpa_supplicant *wpa_s,
545 union wpa_event_data *data,
546 int ie_offset)
547{
548 struct ieee802_11_elems elems;
549 const u8 *mld_addr;
550 u16 status_code = data->auth.status_code;
551
552 if (!wpa_s->valid_links)
553 return;
554
555 if (ieee802_11_parse_elems(data->auth.ies + ie_offset,
556 data->auth.ies_len - ie_offset,
557 &elems, 0) == ParseFailed) {
558 wpa_printf(MSG_DEBUG, "MLD: Failed parsing elements");
559 goto out;
560 }
561
562 if (!elems.basic_mle || !elems.basic_mle_len) {
563 wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication");
564 if (status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ ||
565 status_code == WLAN_STATUS_SUCCESS ||
566 status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
567 status_code == WLAN_STATUS_SAE_PK)
568 goto out;
569 /* Accept missing Multi-Link element in failed authentication
570 * cases. */
571 return;
572 }
573
574 mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
575 if (!mld_addr)
576 goto out;
577
578 wpa_printf(MSG_DEBUG, "MLD: mld_address=" MACSTR, MAC2STR(mld_addr));
579
580 if (os_memcmp(wpa_s->ap_mld_addr, mld_addr, ETH_ALEN) != 0) {
581 wpa_printf(MSG_DEBUG, "MLD: Unexpected MLD address (expected "
582 MACSTR ")", MAC2STR(wpa_s->ap_mld_addr));
583 goto out;
584 }
585
586 return;
587out:
588 wpa_printf(MSG_DEBUG, "MLD: Authentication - clearing MLD state");
589 wpas_reset_mlo_info(wpa_s);
590}
591
592
593static void sme_send_authentication(struct wpa_supplicant *wpa_s,
594 struct wpa_bss *bss, struct wpa_ssid *ssid,
595 int start)
596{
597 struct wpa_driver_auth_params params;
598 struct wpa_ssid *old_ssid;
599#ifdef CONFIG_IEEE80211R
600 const u8 *ie;
601#endif /* CONFIG_IEEE80211R */
602#if defined(CONFIG_IEEE80211R) || defined(CONFIG_FILS)
603 const u8 *md = NULL;
604#endif /* CONFIG_IEEE80211R || CONFIG_FILS */
605 int bssid_changed;
606 struct wpabuf *resp = NULL;
607 u8 ext_capab[18];
608 int ext_capab_len;
609 int skip_auth;
610 u8 *wpa_ie;
611 size_t wpa_ie_len;
612#ifdef CONFIG_MBO
613 const u8 *mbo_ie;
614#endif /* CONFIG_MBO */
615 int omit_rsnxe = 0;
616
617 if (bss == NULL) {
618 wpa_msg(wpa_s, MSG_ERROR, "SME: No scan result available for "
619 "the network");
620 wpas_connect_work_done(wpa_s);
621 return;
622 }
623
624 skip_auth = wpa_s->conf->reassoc_same_bss_optim &&
625 wpa_s->reassoc_same_bss;
626 wpa_s->current_bss = bss;
627
628 os_memset(&params, 0, sizeof(params));
629 wpa_s->reassociate = 0;
630
631 params.freq = bss->freq;
632 params.bssid = bss->bssid;
633 params.ssid = bss->ssid;
634 params.ssid_len = bss->ssid_len;
635 params.p2p = ssid->p2p_group;
636
637 if (wpas_ml_element(wpa_s, bss, ssid)) {
638 wpa_printf(MSG_DEBUG, "MLD: In authentication");
639 params.mld = true;
640 params.mld_link_id = wpa_s->mlo_assoc_link_id;
641 params.ap_mld_addr = wpa_s->ap_mld_addr;
642 }
643
644 if (wpa_s->sme.ssid_len != params.ssid_len ||
645 os_memcmp(wpa_s->sme.ssid, params.ssid, params.ssid_len) != 0)
646 wpa_s->sme.prev_bssid_set = 0;
647
648 wpa_s->sme.freq = params.freq;
649 os_memcpy(wpa_s->sme.ssid, params.ssid, params.ssid_len);
650 wpa_s->sme.ssid_len = params.ssid_len;
651
652 params.auth_alg = WPA_AUTH_ALG_OPEN;
653#ifdef IEEE8021X_EAPOL
654 if (ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) {
655 if (ssid->leap) {
656 if (ssid->non_leap == 0)
657 params.auth_alg = WPA_AUTH_ALG_LEAP;
658 else
659 params.auth_alg |= WPA_AUTH_ALG_LEAP;
660 }
661 }
662#endif /* IEEE8021X_EAPOL */
663 wpa_dbg(wpa_s, MSG_DEBUG, "Automatic auth_alg selection: 0x%x",
664 params.auth_alg);
665 if (ssid->auth_alg) {
666 params.auth_alg = ssid->auth_alg;
667 wpa_dbg(wpa_s, MSG_DEBUG, "Overriding auth_alg selection: "
668 "0x%x", params.auth_alg);
669 }
670#ifdef CONFIG_SAE
671 wpa_s->sme.sae_pmksa_caching = 0;
672 if (wpa_key_mgmt_sae(ssid->key_mgmt)) {
673 const u8 *rsn;
674 struct wpa_ie_data ied;
675
676 rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
677 if (!rsn) {
678 wpa_dbg(wpa_s, MSG_DEBUG,
679 "SAE enabled, but target BSS does not advertise RSN");
680#ifdef CONFIG_DPP
681 } else if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
682 (ssid->key_mgmt & WPA_KEY_MGMT_DPP) &&
683 (ied.key_mgmt & WPA_KEY_MGMT_DPP)) {
684 wpa_dbg(wpa_s, MSG_DEBUG, "Prefer DPP over SAE when both are enabled");
685#endif /* CONFIG_DPP */
686 } else if (wpa_parse_wpa_ie(rsn, 2 + rsn[1], &ied) == 0 &&
687 wpa_key_mgmt_sae(ied.key_mgmt)) {
688 if (wpas_is_sae_avoided(wpa_s, ssid, &ied)) {
689 wpa_dbg(wpa_s, MSG_DEBUG,
690 "SAE enabled, but disallowing SAE auth_alg without PMF");
691 } else {
692 wpa_dbg(wpa_s, MSG_DEBUG, "Using SAE auth_alg");
693 params.auth_alg = WPA_AUTH_ALG_SAE;
694 }
695 } else {
696 wpa_dbg(wpa_s, MSG_DEBUG,
697 "SAE enabled, but target BSS does not advertise SAE AKM for RSN");
698 }
699 }
700#endif /* CONFIG_SAE */
701
702#ifdef CONFIG_WEP
703 {
704 int i;
705
706 for (i = 0; i < NUM_WEP_KEYS; i++) {
707 if (ssid->wep_key_len[i])
708 params.wep_key[i] = ssid->wep_key[i];
709 params.wep_key_len[i] = ssid->wep_key_len[i];
710 }
711 params.wep_tx_keyidx = ssid->wep_tx_keyidx;
712 }
713#endif /* CONFIG_WEP */
714
715 if ((wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE) ||
716 wpa_bss_get_ie(bss, WLAN_EID_RSN)) &&
717 wpa_key_mgmt_wpa(ssid->key_mgmt)) {
718 int try_opportunistic;
719 const u8 *cache_id = NULL;
720
721 try_opportunistic = (ssid->proactive_key_caching < 0 ?
722 wpa_s->conf->okc :
723 ssid->proactive_key_caching) &&
724 (ssid->proto & WPA_PROTO_RSN);
725#ifdef CONFIG_FILS
726 if (wpa_key_mgmt_fils(ssid->key_mgmt))
727 cache_id = wpa_bss_get_fils_cache_id(bss);
728#endif /* CONFIG_FILS */
729 if (pmksa_cache_set_current(wpa_s->wpa, NULL,
730 params.mld ? params.ap_mld_addr :
731 bss->bssid,
732 wpa_s->current_ssid,
733 try_opportunistic, cache_id,
734 0) == 0)
735 eapol_sm_notify_pmkid_attempt(wpa_s->eapol);
736 wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
737 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
738 wpa_s->sme.assoc_req_ie,
739 &wpa_s->sme.assoc_req_ie_len,
740 false)) {
741 wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA "
742 "key management and encryption suites");
743 wpas_connect_work_done(wpa_s);
744 return;
745 }
746#ifdef CONFIG_HS20
747 } else if (wpa_bss_get_vendor_ie(bss, OSEN_IE_VENDOR_TYPE) &&
748 (ssid->key_mgmt & WPA_KEY_MGMT_OSEN)) {
749 /* No PMKSA caching, but otherwise similar to RSN/WPA */
750 wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
751 if (wpa_supplicant_set_suites(wpa_s, bss, ssid,
752 wpa_s->sme.assoc_req_ie,
753 &wpa_s->sme.assoc_req_ie_len,
754 false)) {
755 wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA "
756 "key management and encryption suites");
757 wpas_connect_work_done(wpa_s);
758 return;
759 }
760#endif /* CONFIG_HS20 */
761 } else if ((ssid->key_mgmt & WPA_KEY_MGMT_IEEE8021X_NO_WPA) &&
762 wpa_key_mgmt_wpa_ieee8021x(ssid->key_mgmt)) {
763 /*
764 * Both WPA and non-WPA IEEE 802.1X enabled in configuration -
765 * use non-WPA since the scan results did not indicate that the
766 * AP is using WPA or WPA2.
767 */
768 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
769 wpa_s->sme.assoc_req_ie_len = 0;
770 } else if (wpa_key_mgmt_wpa_any(ssid->key_mgmt)) {
771 wpa_s->sme.assoc_req_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
772 if (wpa_supplicant_set_suites(wpa_s, NULL, ssid,
773 wpa_s->sme.assoc_req_ie,
774 &wpa_s->sme.assoc_req_ie_len,
775 false)) {
776 wpa_msg(wpa_s, MSG_WARNING, "SME: Failed to set WPA "
777 "key management and encryption suites (no "
778 "scan results)");
779 wpas_connect_work_done(wpa_s);
780 return;
781 }
782#ifdef CONFIG_WPS
783 } else if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) {
784 struct wpabuf *wps_ie;
785 wps_ie = wps_build_assoc_req_ie(wpas_wps_get_req_type(ssid));
786 if (wps_ie && wpabuf_len(wps_ie) <=
787 sizeof(wpa_s->sme.assoc_req_ie)) {
788 wpa_s->sme.assoc_req_ie_len = wpabuf_len(wps_ie);
789 os_memcpy(wpa_s->sme.assoc_req_ie, wpabuf_head(wps_ie),
790 wpa_s->sme.assoc_req_ie_len);
791 } else
792 wpa_s->sme.assoc_req_ie_len = 0;
793 wpabuf_free(wps_ie);
794 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
795#endif /* CONFIG_WPS */
796 } else {
797 wpa_supplicant_set_non_wpa_policy(wpa_s, ssid);
798 wpa_s->sme.assoc_req_ie_len = 0;
799 }
800
801 /* In case the WPA vendor IE is used, it should be placed after all the
802 * non-vendor IEs, as the lower layer expects the IEs to be ordered as
803 * defined in the standard. Store the WPA IE so it can later be
804 * inserted at the correct location.
805 */
806 wpa_ie = NULL;
807 wpa_ie_len = 0;
808 if (wpa_s->wpa_proto == WPA_PROTO_WPA) {
809 wpa_ie = os_memdup(wpa_s->sme.assoc_req_ie,
810 wpa_s->sme.assoc_req_ie_len);
811 if (wpa_ie) {
812 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Storing WPA IE");
813
814 wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
815 wpa_s->sme.assoc_req_ie_len = 0;
816 } else {
817 wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed copy WPA IE");
818 wpas_connect_work_done(wpa_s);
819 return;
820 }
821 }
822
823#ifdef CONFIG_IEEE80211R
824 ie = wpa_bss_get_ie(bss, WLAN_EID_MOBILITY_DOMAIN);
825 if (ie && ie[1] >= MOBILITY_DOMAIN_ID_LEN)
826 md = ie + 2;
827 wpa_sm_set_ft_params(wpa_s->wpa, ie, ie ? 2 + ie[1] : 0);
828 if (md && (!wpa_key_mgmt_ft(ssid->key_mgmt) ||
829 !wpa_key_mgmt_ft(wpa_s->key_mgmt)))
830 md = NULL;
831 if (md) {
832 /* Prepare for the next transition */
833 wpa_ft_prepare_auth_request(wpa_s->wpa, ie);
834 }
835
836 if (md) {
837 wpa_dbg(wpa_s, MSG_DEBUG, "SME: FT mobility domain %02x%02x",
838 md[0], md[1]);
839
840 omit_rsnxe = !wpa_bss_get_ie(bss, WLAN_EID_RSNX);
841 if (wpa_s->sme.assoc_req_ie_len + 5 <
842 sizeof(wpa_s->sme.assoc_req_ie)) {
843 struct rsn_mdie *mdie;
844 u8 *pos = wpa_s->sme.assoc_req_ie +
845 wpa_s->sme.assoc_req_ie_len;
846 *pos++ = WLAN_EID_MOBILITY_DOMAIN;
847 *pos++ = sizeof(*mdie);
848 mdie = (struct rsn_mdie *) pos;
849 os_memcpy(mdie->mobility_domain, md,
850 MOBILITY_DOMAIN_ID_LEN);
851 mdie->ft_capab = md[MOBILITY_DOMAIN_ID_LEN];
852 wpa_s->sme.assoc_req_ie_len += 5;
853 }
854
855 if (wpa_s->sme.prev_bssid_set && wpa_s->sme.ft_used &&
856 os_memcmp(md, wpa_s->sme.mobility_domain, 2) == 0 &&
857 wpa_sm_has_ft_keys(wpa_s->wpa, md)) {
858 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying to use FT "
859 "over-the-air");
860 params.auth_alg = WPA_AUTH_ALG_FT;
861 params.ie = wpa_s->sme.ft_ies;
862 params.ie_len = wpa_s->sme.ft_ies_len;
863 }
864 }
865#endif /* CONFIG_IEEE80211R */
866
867 wpa_s->sme.mfp = wpas_get_ssid_pmf(wpa_s, ssid);
868 if (wpa_s->sme.mfp != NO_MGMT_FRAME_PROTECTION) {
869 const u8 *rsn = wpa_bss_get_ie(bss, WLAN_EID_RSN);
870 struct wpa_ie_data _ie;
871 if (rsn && wpa_parse_wpa_ie(rsn, 2 + rsn[1], &_ie) == 0 &&
872 _ie.capabilities &
873 (WPA_CAPABILITY_MFPC | WPA_CAPABILITY_MFPR)) {
874 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Selected AP supports "
875 "MFP: require MFP");
876 wpa_s->sme.mfp = MGMT_FRAME_PROTECTION_REQUIRED;
877 }
878 }
879
880#ifdef CONFIG_P2P
881 if (wpa_s->global->p2p) {
882 u8 *pos;
883 size_t len;
884 int res;
885 pos = wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len;
886 len = sizeof(wpa_s->sme.assoc_req_ie) -
887 wpa_s->sme.assoc_req_ie_len;
888 res = wpas_p2p_assoc_req_ie(wpa_s, bss, pos, len,
889 ssid->p2p_group);
890 if (res >= 0)
891 wpa_s->sme.assoc_req_ie_len += res;
892 }
893#endif /* CONFIG_P2P */
894
895#ifdef CONFIG_FST
896 if (wpa_s->fst_ies) {
897 int fst_ies_len = wpabuf_len(wpa_s->fst_ies);
898
899 if (wpa_s->sme.assoc_req_ie_len + fst_ies_len <=
900 sizeof(wpa_s->sme.assoc_req_ie)) {
901 os_memcpy(wpa_s->sme.assoc_req_ie +
902 wpa_s->sme.assoc_req_ie_len,
903 wpabuf_head(wpa_s->fst_ies),
904 fst_ies_len);
905 wpa_s->sme.assoc_req_ie_len += fst_ies_len;
906 }
907 }
908#endif /* CONFIG_FST */
909
910 sme_auth_handle_rrm(wpa_s, bss);
911
912 wpa_s->sme.assoc_req_ie_len += wpas_supp_op_class_ie(
913 wpa_s, ssid, bss,
914 wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
915 sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len);
916
917 if (params.p2p)
918 wpa_drv_get_ext_capa(wpa_s, WPA_IF_P2P_CLIENT);
919 else
920 wpa_drv_get_ext_capa(wpa_s, WPA_IF_STATION);
921
922 ext_capab_len = wpas_build_ext_capab(wpa_s, ext_capab,
923 sizeof(ext_capab));
924 if (ext_capab_len > 0) {
925 u8 *pos = wpa_s->sme.assoc_req_ie;
926 if (wpa_s->sme.assoc_req_ie_len > 0 && pos[0] == WLAN_EID_RSN)
927 pos += 2 + pos[1];
928 os_memmove(pos + ext_capab_len, pos,
929 wpa_s->sme.assoc_req_ie_len -
930 (pos - wpa_s->sme.assoc_req_ie));
931 wpa_s->sme.assoc_req_ie_len += ext_capab_len;
932 os_memcpy(pos, ext_capab, ext_capab_len);
933 }
934
935#ifdef CONFIG_TESTING_OPTIONS
936 if (wpa_s->rsnxe_override_assoc &&
937 wpabuf_len(wpa_s->rsnxe_override_assoc) <=
938 sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len) {
939 wpa_printf(MSG_DEBUG, "TESTING: RSNXE AssocReq override");
940 os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
941 wpabuf_head(wpa_s->rsnxe_override_assoc),
942 wpabuf_len(wpa_s->rsnxe_override_assoc));
943 wpa_s->sme.assoc_req_ie_len +=
944 wpabuf_len(wpa_s->rsnxe_override_assoc);
945 } else
946#endif /* CONFIG_TESTING_OPTIONS */
947 if (wpa_s->rsnxe_len > 0 &&
948 wpa_s->rsnxe_len <=
949 sizeof(wpa_s->sme.assoc_req_ie) - wpa_s->sme.assoc_req_ie_len &&
950 !omit_rsnxe) {
951 os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
952 wpa_s->rsnxe, wpa_s->rsnxe_len);
953 wpa_s->sme.assoc_req_ie_len += wpa_s->rsnxe_len;
954 }
955
956#ifdef CONFIG_HS20
957 if (is_hs20_network(wpa_s, ssid, bss)) {
958 struct wpabuf *hs20;
959
960 hs20 = wpabuf_alloc(20 + MAX_ROAMING_CONS_OI_LEN);
961 if (hs20) {
962 int pps_mo_id = hs20_get_pps_mo_id(wpa_s, ssid);
963 size_t len;
964
965 wpas_hs20_add_indication(hs20, pps_mo_id,
966 get_hs20_version(bss));
967 wpas_hs20_add_roam_cons_sel(hs20, ssid);
968 len = sizeof(wpa_s->sme.assoc_req_ie) -
969 wpa_s->sme.assoc_req_ie_len;
970 if (wpabuf_len(hs20) <= len) {
971 os_memcpy(wpa_s->sme.assoc_req_ie +
972 wpa_s->sme.assoc_req_ie_len,
973 wpabuf_head(hs20), wpabuf_len(hs20));
974 wpa_s->sme.assoc_req_ie_len += wpabuf_len(hs20);
975 }
976 wpabuf_free(hs20);
977 }
978 }
979#endif /* CONFIG_HS20 */
980
981 if (wpa_ie) {
982 size_t len;
983
984 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Reinsert WPA IE");
985
986 len = sizeof(wpa_s->sme.assoc_req_ie) -
987 wpa_s->sme.assoc_req_ie_len;
988
989 if (len > wpa_ie_len) {
990 os_memcpy(wpa_s->sme.assoc_req_ie +
991 wpa_s->sme.assoc_req_ie_len,
992 wpa_ie, wpa_ie_len);
993 wpa_s->sme.assoc_req_ie_len += wpa_ie_len;
994 } else {
995 wpa_dbg(wpa_s, MSG_DEBUG, "WPA: Failed to add WPA IE");
996 }
997
998 os_free(wpa_ie);
999 }
1000
1001 if (wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ]) {
1002 struct wpabuf *buf = wpa_s->vendor_elem[VENDOR_ELEM_ASSOC_REQ];
1003 size_t len;
1004
1005 len = sizeof(wpa_s->sme.assoc_req_ie) -
1006 wpa_s->sme.assoc_req_ie_len;
1007 if (wpabuf_len(buf) <= len) {
1008 os_memcpy(wpa_s->sme.assoc_req_ie +
1009 wpa_s->sme.assoc_req_ie_len,
1010 wpabuf_head(buf), wpabuf_len(buf));
1011 wpa_s->sme.assoc_req_ie_len += wpabuf_len(buf);
1012 }
1013 }
1014
1015#ifdef CONFIG_MBO
1016 mbo_ie = wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE);
1017 if (!wpa_s->disable_mbo_oce && mbo_ie) {
1018 int len;
1019
1020 len = wpas_mbo_ie(wpa_s, wpa_s->sme.assoc_req_ie +
1021 wpa_s->sme.assoc_req_ie_len,
1022 sizeof(wpa_s->sme.assoc_req_ie) -
1023 wpa_s->sme.assoc_req_ie_len,
1024 !!mbo_attr_from_mbo_ie(mbo_ie,
1025 OCE_ATTR_ID_CAPA_IND));
1026 if (len >= 0)
1027 wpa_s->sme.assoc_req_ie_len += len;
1028 }
1029#endif /* CONFIG_MBO */
1030
1031#ifdef CONFIG_SAE
1032 if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE &&
1033 pmksa_cache_set_current(wpa_s->wpa, NULL,
1034 params.mld ? params.ap_mld_addr :
1035 bss->bssid,
1036 ssid, 0,
1037 NULL,
1038 wpa_key_mgmt_sae(wpa_s->key_mgmt) ?
1039 wpa_s->key_mgmt :
1040 (int) WPA_KEY_MGMT_SAE) == 0) {
1041 wpa_dbg(wpa_s, MSG_DEBUG,
1042 "PMKSA cache entry found - try to use PMKSA caching instead of new SAE authentication");
1043 wpa_sm_set_pmk_from_pmksa(wpa_s->wpa);
1044 params.auth_alg = WPA_AUTH_ALG_OPEN;
1045 wpa_s->sme.sae_pmksa_caching = 1;
1046 }
1047
1048 if (!skip_auth && params.auth_alg == WPA_AUTH_ALG_SAE) {
1049 if (start)
1050 resp = sme_auth_build_sae_commit(wpa_s, ssid,
1051 bss->bssid,
1052 params.mld ?
1053 params.ap_mld_addr :
1054 NULL, 0,
1055 start == 2, NULL,
1056 NULL);
1057 else
1058 resp = sme_auth_build_sae_confirm(wpa_s, 0);
1059 if (resp == NULL) {
1060 wpas_connection_failed(wpa_s, bss->bssid);
1061 return;
1062 }
1063 params.auth_data = wpabuf_head(resp);
1064 params.auth_data_len = wpabuf_len(resp);
1065 wpa_s->sme.sae.state = start ? SAE_COMMITTED : SAE_CONFIRMED;
1066 }
1067#endif /* CONFIG_SAE */
1068
1069 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
1070 os_memset(wpa_s->bssid, 0, ETH_ALEN);
1071 os_memcpy(wpa_s->pending_bssid, bss->bssid, ETH_ALEN);
1072 if (bssid_changed)
1073 wpas_notify_bssid_changed(wpa_s);
1074
1075 old_ssid = wpa_s->current_ssid;
1076 wpa_s->current_ssid = ssid;
1077 wpa_supplicant_rsn_supp_set_config(wpa_s, wpa_s->current_ssid);
1078 wpa_supplicant_initiate_eapol(wpa_s);
1079
1080#ifdef CONFIG_FILS
1081 /* TODO: FILS operations can in some cases be done between different
1082 * network_ctx (i.e., same credentials can be used with multiple
1083 * networks). */
1084 if (params.auth_alg == WPA_AUTH_ALG_OPEN &&
1085 wpa_key_mgmt_fils(ssid->key_mgmt)) {
1086 const u8 *indic;
1087 u16 fils_info;
1088 const u8 *realm, *username, *rrk;
1089 size_t realm_len, username_len, rrk_len;
1090 u16 next_seq_num;
1091
1092 /*
1093 * Check FILS Indication element (FILS Information field) bits
1094 * indicating supported authentication algorithms against local
1095 * configuration (ssid->fils_dh_group). Try to use FILS
1096 * authentication only if the AP supports the combination in the
1097 * network profile. */
1098 indic = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
1099 if (!indic || indic[1] < 2) {
1100 wpa_printf(MSG_DEBUG, "SME: " MACSTR
1101 " does not include FILS Indication element - cannot use FILS authentication with it",
1102 MAC2STR(bss->bssid));
1103 goto no_fils;
1104 }
1105
1106 fils_info = WPA_GET_LE16(indic + 2);
1107 if (ssid->fils_dh_group == 0 && !(fils_info & BIT(9))) {
1108 wpa_printf(MSG_DEBUG, "SME: " MACSTR
1109 " does not support FILS SK without PFS - cannot use FILS authentication with it",
1110 MAC2STR(bss->bssid));
1111 goto no_fils;
1112 }
1113 if (ssid->fils_dh_group != 0 && !(fils_info & BIT(10))) {
1114 wpa_printf(MSG_DEBUG, "SME: " MACSTR
1115 " does not support FILS SK with PFS - cannot use FILS authentication with it",
1116 MAC2STR(bss->bssid));
1117 goto no_fils;
1118 }
1119
1120 if (wpa_s->last_con_fail_realm &&
1121 eapol_sm_get_erp_info(wpa_s->eapol, &ssid->eap,
1122 &username, &username_len,
1123 &realm, &realm_len, &next_seq_num,
1124 &rrk, &rrk_len) == 0 &&
1125 realm && realm_len == wpa_s->last_con_fail_realm_len &&
1126 os_memcmp(realm, wpa_s->last_con_fail_realm,
1127 realm_len) == 0) {
1128 wpa_printf(MSG_DEBUG,
1129 "SME: FILS authentication for this realm failed last time - try to regenerate ERP key hierarchy");
1130 goto no_fils;
1131 }
1132
1133 if (pmksa_cache_set_current(wpa_s->wpa, NULL,
1134 params.mld ? params.ap_mld_addr :
1135 bss->bssid,
1136 ssid, 0,
1137 wpa_bss_get_fils_cache_id(bss),
1138 0) == 0)
1139 wpa_printf(MSG_DEBUG,
1140 "SME: Try to use FILS with PMKSA caching");
1141 resp = fils_build_auth(wpa_s->wpa, ssid->fils_dh_group, md);
1142 if (resp) {
1143 int auth_alg;
1144
1145 if (ssid->fils_dh_group)
1146 wpa_printf(MSG_DEBUG,
1147 "SME: Try to use FILS SK authentication with PFS (DH Group %u)",
1148 ssid->fils_dh_group);
1149 else
1150 wpa_printf(MSG_DEBUG,
1151 "SME: Try to use FILS SK authentication without PFS");
1152 auth_alg = ssid->fils_dh_group ?
1153 WPA_AUTH_ALG_FILS_SK_PFS : WPA_AUTH_ALG_FILS;
1154 params.auth_alg = auth_alg;
1155 params.auth_data = wpabuf_head(resp);
1156 params.auth_data_len = wpabuf_len(resp);
1157 wpa_s->sme.auth_alg = auth_alg;
1158 }
1159 }
1160no_fils:
1161#endif /* CONFIG_FILS */
1162
1163 wpa_supplicant_cancel_sched_scan(wpa_s);
1164 wpa_supplicant_cancel_scan(wpa_s);
1165
1166 wpa_msg(wpa_s, MSG_INFO, "SME: Trying to authenticate with " MACSTR
1167 " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
1168 wpa_ssid_txt(params.ssid, params.ssid_len), params.freq);
1169
1170 eapol_sm_notify_portValid(wpa_s->eapol, false);
1171 wpa_clear_keys(wpa_s, bss->bssid);
1172 wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
1173 if (old_ssid != wpa_s->current_ssid)
1174 wpas_notify_network_changed(wpa_s);
1175
1176#ifdef CONFIG_HS20
1177 hs20_configure_frame_filters(wpa_s);
1178#endif /* CONFIG_HS20 */
1179
1180#ifdef CONFIG_P2P
1181 /*
1182 * If multi-channel concurrency is not supported, check for any
1183 * frequency conflict. In case of any frequency conflict, remove the
1184 * least prioritized connection.
1185 */
1186 if (wpa_s->num_multichan_concurrent < 2) {
1187 int freq, num;
1188 num = get_shared_radio_freqs(wpa_s, &freq, 1, false);
1189 if (num > 0 && freq > 0 && freq != params.freq) {
1190 wpa_printf(MSG_DEBUG,
1191 "Conflicting frequency found (%d != %d)",
1192 freq, params.freq);
1193 if (wpas_p2p_handle_frequency_conflicts(wpa_s,
1194 params.freq,
1195 ssid) < 0) {
1196 wpas_connection_failed(wpa_s, bss->bssid);
1197 wpa_supplicant_mark_disassoc(wpa_s);
1198 wpabuf_free(resp);
1199 wpas_connect_work_done(wpa_s);
1200 return;
1201 }
1202 }
1203 }
1204#endif /* CONFIG_P2P */
1205
1206 if (skip_auth) {
1207 wpa_msg(wpa_s, MSG_DEBUG,
1208 "SME: Skip authentication step on reassoc-to-same-BSS");
1209 wpabuf_free(resp);
1210 sme_associate(wpa_s, ssid->mode, bss->bssid, WLAN_AUTH_OPEN);
1211 return;
1212 }
1213
1214
1215 wpa_s->sme.auth_alg = params.auth_alg;
1216 if (wpa_drv_authenticate(wpa_s, &params) < 0) {
1217 wpa_msg(wpa_s, MSG_INFO, "SME: Authentication request to the "
1218 "driver failed");
1219 wpas_connection_failed(wpa_s, bss->bssid);
1220 wpa_supplicant_mark_disassoc(wpa_s);
1221 wpabuf_free(resp);
1222 wpas_connect_work_done(wpa_s);
1223 return;
1224 }
1225
1226 eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s,
1227 NULL);
1228
1229 /*
1230 * Association will be started based on the authentication event from
1231 * the driver.
1232 */
1233
1234 wpabuf_free(resp);
1235}
1236
1237
1238static void sme_auth_start_cb(struct wpa_radio_work *work, int deinit)
1239{
1240 struct wpa_connect_work *cwork = work->ctx;
1241 struct wpa_supplicant *wpa_s = work->wpa_s;
1242
1243 wpa_s->roam_in_progress = false;
1244#ifdef CONFIG_WNM
1245 wpa_s->bss_trans_mgmt_in_progress = false;
1246#endif /* CONFIG_WNM */
1247
1248 if (deinit) {
1249 if (work->started)
1250 wpa_s->connect_work = NULL;
1251
1252 wpas_connect_work_free(cwork);
1253 return;
1254 }
1255
1256 wpa_s->connect_work = work;
1257
1258 if (cwork->bss_removed ||
1259 !wpas_valid_bss_ssid(wpa_s, cwork->bss, cwork->ssid) ||
1260 wpas_network_disabled(wpa_s, cwork->ssid)) {
1261 wpa_dbg(wpa_s, MSG_DEBUG, "SME: BSS/SSID entry for authentication not valid anymore - drop connection attempt");
1262 wpas_connect_work_done(wpa_s);
1263 return;
1264 }
1265
1266 /* Starting new connection, so clear the possibly used WPA IE from the
1267 * previous association. */
1268 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
1269 wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
1270 wpa_s->rsnxe_len = 0;
1271
1272 sme_send_authentication(wpa_s, cwork->bss, cwork->ssid, 1);
1273 wpas_notify_auth_changed(wpa_s);
1274}
1275
1276
1277void sme_authenticate(struct wpa_supplicant *wpa_s,
1278 struct wpa_bss *bss, struct wpa_ssid *ssid)
1279{
1280 struct wpa_connect_work *cwork;
1281
1282 if (bss == NULL || ssid == NULL)
1283 return;
1284 if (wpa_s->connect_work) {
1285 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reject sme_authenticate() call since connect_work exist");
1286 return;
1287 }
1288
1289 if (wpa_s->roam_in_progress) {
1290 wpa_dbg(wpa_s, MSG_DEBUG,
1291 "SME: Reject sme_authenticate() in favor of explicit roam request");
1292 return;
1293 }
1294#ifdef CONFIG_WNM
1295 if (wpa_s->bss_trans_mgmt_in_progress) {
1296 wpa_dbg(wpa_s, MSG_DEBUG,
1297 "SME: Reject sme_authenticate() in favor of BSS transition management request");
1298 return;
1299 }
1300#endif /* CONFIG_WNM */
1301 if (radio_work_pending(wpa_s, "sme-connect")) {
1302 /*
1303 * The previous sme-connect work might no longer be valid due to
1304 * the fact that the BSS list was updated. In addition, it makes
1305 * sense to adhere to the 'newer' decision.
1306 */
1307 wpa_dbg(wpa_s, MSG_DEBUG,
1308 "SME: Remove previous pending sme-connect");
1309 radio_remove_works(wpa_s, "sme-connect", 0);
1310 }
1311
1312 wpas_abort_ongoing_scan(wpa_s);
1313
1314 cwork = os_zalloc(sizeof(*cwork));
1315 if (cwork == NULL)
1316 return;
1317 cwork->bss = bss;
1318 cwork->ssid = ssid;
1319 cwork->sme = 1;
1320
1321#ifdef CONFIG_SAE
1322 wpa_s->sme.sae.state = SAE_NOTHING;
1323 wpa_s->sme.sae.send_confirm = 0;
1324 wpa_s->sme.sae_group_index = 0;
1325#endif /* CONFIG_SAE */
1326
1327 if (radio_add_work(wpa_s, bss->freq, "sme-connect", 1,
1328 sme_auth_start_cb, cwork) < 0)
1329 wpas_connect_work_free(cwork);
1330}
1331
1332
1333#ifdef CONFIG_SAE
1334
1335#define WPA_AUTH_FRAME_ML_IE_LEN (6 + ETH_ALEN)
1336
1337static void wpa_auth_ml_ie(struct wpabuf *buf, const u8 *mld_addr)
1338{
1339
1340 wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
1341 wpabuf_put_u8(buf, 4 + ETH_ALEN);
1342 wpabuf_put_u8(buf, WLAN_EID_EXT_MULTI_LINK);
1343
1344 /* Basic Multi-Link element Control field */
1345 wpabuf_put_u8(buf, 0x0);
1346 wpabuf_put_u8(buf, 0x0);
1347
1348 /* Common Info */
1349 wpabuf_put_u8(buf, 0x7); /* length = Length field + MLD MAC address */
1350 wpabuf_put_data(buf, mld_addr, ETH_ALEN);
1351}
1352
1353
1354static int sme_external_auth_build_buf(struct wpabuf *buf,
1355 struct wpabuf *params,
1356 const u8 *sa, const u8 *da,
1357 u16 auth_transaction, u16 seq_num,
1358 u16 status_code, const u8 *mld_addr)
1359{
1360 struct ieee80211_mgmt *resp;
1361
1362 resp = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
1363 u.auth.variable));
1364
1365 resp->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
1366 (WLAN_FC_STYPE_AUTH << 4));
1367 os_memcpy(resp->da, da, ETH_ALEN);
1368 os_memcpy(resp->sa, sa, ETH_ALEN);
1369 os_memcpy(resp->bssid, da, ETH_ALEN);
1370 resp->u.auth.auth_alg = host_to_le16(WLAN_AUTH_SAE);
1371 resp->seq_ctrl = host_to_le16(seq_num << 4);
1372 resp->u.auth.auth_transaction = host_to_le16(auth_transaction);
1373 resp->u.auth.status_code = host_to_le16(status_code);
1374 if (params)
1375 wpabuf_put_buf(buf, params);
1376
1377 if (mld_addr)
1378 wpa_auth_ml_ie(buf, mld_addr);
1379
1380 return 0;
1381}
1382
1383
1384static int sme_external_auth_send_sae_commit(struct wpa_supplicant *wpa_s,
1385 const u8 *bssid,
1386 struct wpa_ssid *ssid)
1387{
1388 struct wpabuf *resp, *buf;
1389 int use_pt;
1390 bool use_pk;
1391 u16 status;
1392
1393 resp = sme_auth_build_sae_commit(wpa_s, ssid, bssid,
1394 wpa_s->sme.ext_ml_auth ?
1395 wpa_s->sme.ext_auth_ap_mld_addr : NULL,
1396 1, 0, &use_pt, &use_pk);
1397 if (!resp) {
1398 wpa_printf(MSG_DEBUG, "SAE: Failed to build SAE commit");
1399 return -1;
1400 }
1401
1402 wpa_s->sme.sae.state = SAE_COMMITTED;
1403 buf = wpabuf_alloc(4 + SAE_COMMIT_MAX_LEN + wpabuf_len(resp) +
1404 (wpa_s->sme.ext_ml_auth ? WPA_AUTH_FRAME_ML_IE_LEN :
1405 0));
1406 if (!buf) {
1407 wpabuf_free(resp);
1408 return -1;
1409 }
1410
1411 wpa_s->sme.seq_num++;
1412 if (use_pk)
1413 status = WLAN_STATUS_SAE_PK;
1414 else if (use_pt)
1415 status = WLAN_STATUS_SAE_HASH_TO_ELEMENT;
1416 else
1417 status = WLAN_STATUS_SUCCESS;
1418 sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
1419 wpa_s->sme.ext_ml_auth ?
1420 wpa_s->sme.ext_auth_ap_mld_addr : bssid, 1,
1421 wpa_s->sme.seq_num, status,
1422 wpa_s->sme.ext_ml_auth ?
1423 wpa_s->own_addr : NULL);
1424 wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0, 0);
1425 wpabuf_free(resp);
1426 wpabuf_free(buf);
1427
1428 return 0;
1429}
1430
1431
1432static void sme_send_external_auth_status(struct wpa_supplicant *wpa_s,
1433 u16 status)
1434{
1435 struct external_auth params;
1436
1437 wpa_s->sme.ext_auth_wpa_ssid = NULL;
1438 os_memset(&params, 0, sizeof(params));
1439 params.status = status;
1440 params.ssid = wpa_s->sme.ext_auth_ssid;
1441 params.ssid_len = wpa_s->sme.ext_auth_ssid_len;
1442 params.bssid = wpa_s->sme.ext_auth_bssid;
1443 if (wpa_s->conf->sae_pmkid_in_assoc && status == WLAN_STATUS_SUCCESS)
1444 params.pmkid = wpa_s->sme.sae.pmkid;
1445 wpa_drv_send_external_auth_status(wpa_s, &params);
1446}
1447
1448
1449static int sme_handle_external_auth_start(struct wpa_supplicant *wpa_s,
1450 union wpa_event_data *data)
1451{
1452 struct wpa_ssid *ssid;
1453 size_t ssid_str_len = data->external_auth.ssid_len;
1454 const u8 *ssid_str = data->external_auth.ssid;
1455
1456 wpa_s->sme.ext_auth_wpa_ssid = NULL;
1457 /* Get the SSID conf from the ssid string obtained */
1458 for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
1459 if (!wpas_network_disabled(wpa_s, ssid) &&
1460 ssid_str_len == ssid->ssid_len &&
1461 os_memcmp(ssid_str, ssid->ssid, ssid_str_len) == 0 &&
1462 wpa_key_mgmt_sae(ssid->key_mgmt)) {
1463 /* Make sure PT is derived */
1464 wpa_s_setup_sae_pt(wpa_s->conf, ssid, false);
1465 wpa_s->sme.ext_auth_wpa_ssid = ssid;
1466 break;
1467 }
1468 }
1469 if (!ssid ||
1470 sme_external_auth_send_sae_commit(wpa_s, data->external_auth.bssid,
1471 ssid) < 0)
1472 return -1;
1473
1474 return 0;
1475}
1476
1477
1478static void sme_external_auth_send_sae_confirm(struct wpa_supplicant *wpa_s,
1479 const u8 *da)
1480{
1481 struct wpabuf *resp, *buf;
1482
1483 resp = sme_auth_build_sae_confirm(wpa_s, 1);
1484 if (!resp) {
1485 wpa_printf(MSG_DEBUG, "SAE: Confirm message buf alloc failure");
1486 return;
1487 }
1488
1489 wpa_s->sme.sae.state = SAE_CONFIRMED;
1490 buf = wpabuf_alloc(4 + SAE_CONFIRM_MAX_LEN + wpabuf_len(resp) +
1491 (wpa_s->sme.ext_ml_auth ? WPA_AUTH_FRAME_ML_IE_LEN :
1492 0));
1493 if (!buf) {
1494 wpa_printf(MSG_DEBUG, "SAE: Auth Confirm buf alloc failure");
1495 wpabuf_free(resp);
1496 return;
1497 }
1498 wpa_s->sme.seq_num++;
1499 sme_external_auth_build_buf(buf, resp, wpa_s->own_addr,
1500 da, 2, wpa_s->sme.seq_num,
1501 WLAN_STATUS_SUCCESS,
1502 wpa_s->sme.ext_ml_auth ?
1503 wpa_s->own_addr : NULL);
1504
1505 wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1, 0, 0);
1506 wpabuf_free(resp);
1507 wpabuf_free(buf);
1508}
1509
1510
1511static bool is_sae_key_mgmt_suite(struct wpa_supplicant *wpa_s, u32 suite)
1512{
1513 /* suite is supposed to be the selector value in host byte order with
1514 * the OUI in three most significant octets. However, the initial
1515 * implementation swapped that byte order and did not work with drivers
1516 * that followed the expected byte order. Keep a workaround here to
1517 * match that initial implementation so that already deployed use cases
1518 * remain functional. */
1519 if (RSN_SELECTOR_GET(&suite) == RSN_AUTH_KEY_MGMT_SAE) {
1520 /* Old drivers which follow initial implementation send SAE AKM
1521 * for both SAE and FT-SAE connections. In that case, determine
1522 * the actual AKM from wpa_s->key_mgmt. */
1523 wpa_s->sme.ext_auth_key_mgmt = wpa_s->key_mgmt;
1524 return true;
1525 }
1526
1527 if (suite == RSN_AUTH_KEY_MGMT_SAE)
1528 wpa_s->sme.ext_auth_key_mgmt = WPA_KEY_MGMT_SAE;
1529 else if (suite == RSN_AUTH_KEY_MGMT_FT_SAE)
1530 wpa_s->sme.ext_auth_key_mgmt = WPA_KEY_MGMT_FT_SAE;
1531 else if (suite == RSN_AUTH_KEY_MGMT_SAE_EXT_KEY)
1532 wpa_s->sme.ext_auth_key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY;
1533 else if (suite == RSN_AUTH_KEY_MGMT_FT_SAE_EXT_KEY)
1534 wpa_s->sme.ext_auth_key_mgmt = WPA_KEY_MGMT_FT_SAE_EXT_KEY;
1535 else
1536 return false;
1537
1538 return true;
1539}
1540
1541
1542void sme_external_auth_trigger(struct wpa_supplicant *wpa_s,
1543 union wpa_event_data *data)
1544{
1545 if (!is_sae_key_mgmt_suite(wpa_s, data->external_auth.key_mgmt_suite))
1546 return;
1547
1548 if (data->external_auth.action == EXT_AUTH_START) {
1549 if (!data->external_auth.bssid || !data->external_auth.ssid)
1550 return;
1551 os_memcpy(wpa_s->sme.ext_auth_bssid, data->external_auth.bssid,
1552 ETH_ALEN);
1553 os_memcpy(wpa_s->sme.ext_auth_ssid, data->external_auth.ssid,
1554 data->external_auth.ssid_len);
1555 wpa_s->sme.ext_auth_ssid_len = data->external_auth.ssid_len;
1556 if (data->external_auth.mld_addr) {
1557 wpa_s->sme.ext_ml_auth = true;
1558 os_memcpy(wpa_s->sme.ext_auth_ap_mld_addr,
1559 data->external_auth.mld_addr, ETH_ALEN);
1560 } else {
1561 wpa_s->sme.ext_ml_auth = false;
1562 }
1563 wpa_s->sme.seq_num = 0;
1564 wpa_s->sme.sae.state = SAE_NOTHING;
1565 wpa_s->sme.sae.send_confirm = 0;
1566 wpa_s->sme.sae_group_index = 0;
1567 if (sme_handle_external_auth_start(wpa_s, data) < 0)
1568 sme_send_external_auth_status(wpa_s,
1569 WLAN_STATUS_UNSPECIFIED_FAILURE);
1570 } else if (data->external_auth.action == EXT_AUTH_ABORT) {
1571 /* Report failure to driver for the wrong trigger */
1572 sme_send_external_auth_status(wpa_s,
1573 WLAN_STATUS_UNSPECIFIED_FAILURE);
1574 }
1575}
1576
1577
1578static int sme_sae_is_group_enabled(struct wpa_supplicant *wpa_s, int group)
1579{
1580 int *groups = wpa_s->conf->sae_groups;
1581 int default_groups[] = { 19, 20, 21, 0 };
1582 int i;
1583
1584 if (!groups)
1585 groups = default_groups;
1586
1587 for (i = 0; groups[i] > 0; i++) {
1588 if (groups[i] == group)
1589 return 1;
1590 }
1591
1592 return 0;
1593}
1594
1595
1596static int sme_check_sae_rejected_groups(struct wpa_supplicant *wpa_s,
1597 const struct wpabuf *groups)
1598{
1599 size_t i, count;
1600 const u8 *pos;
1601
1602 if (!groups)
1603 return 0;
1604
1605 pos = wpabuf_head(groups);
1606 count = wpabuf_len(groups) / 2;
1607 for (i = 0; i < count; i++) {
1608 int enabled;
1609 u16 group;
1610
1611 group = WPA_GET_LE16(pos);
1612 pos += 2;
1613 enabled = sme_sae_is_group_enabled(wpa_s, group);
1614 wpa_printf(MSG_DEBUG, "SAE: Rejected group %u is %s",
1615 group, enabled ? "enabled" : "disabled");
1616 if (enabled)
1617 return 1;
1618 }
1619
1620 return 0;
1621}
1622
1623
1624static int sme_external_ml_auth(struct wpa_supplicant *wpa_s,
1625 const u8 *data, size_t len, int ie_offset,
1626 u16 status_code)
1627{
1628 struct ieee802_11_elems elems;
1629 const u8 *mld_addr;
1630
1631 if (ieee802_11_parse_elems(data + ie_offset, len - ie_offset,
1632 &elems, 0) == ParseFailed) {
1633 wpa_printf(MSG_DEBUG, "MLD: Failed parsing elements");
1634 return -1;
1635 }
1636
1637 if (!elems.basic_mle || !elems.basic_mle_len) {
1638 wpa_printf(MSG_DEBUG, "MLD: No ML element in authentication");
1639 if (status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ ||
1640 status_code == WLAN_STATUS_SUCCESS ||
1641 status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1642 status_code == WLAN_STATUS_SAE_PK)
1643 return -1;
1644 /* Accept missing Multi-Link element in failed authentication
1645 * cases. */
1646 return 0;
1647 }
1648
1649 mld_addr = get_basic_mle_mld_addr(elems.basic_mle, elems.basic_mle_len);
1650 if (!mld_addr) {
1651 wpa_printf(MSG_DEBUG, "MLD: No MLD address in ML element");
1652 return -1;
1653 }
1654
1655 wpa_printf(MSG_DEBUG, "MLD: mld_address=" MACSTR, MAC2STR(mld_addr));
1656
1657 if (os_memcmp(wpa_s->sme.ext_auth_ap_mld_addr, mld_addr, ETH_ALEN) !=
1658 0) {
1659 wpa_printf(MSG_DEBUG, "MLD: Unexpected MLD address (expected "
1660 MACSTR ")",
1661 MAC2STR(wpa_s->sme.ext_auth_ap_mld_addr));
1662 return -1;
1663 }
1664
1665 return 0;
1666}
1667
1668
1669static int sme_sae_auth(struct wpa_supplicant *wpa_s, u16 auth_transaction,
1670 u16 status_code, const u8 *data, size_t len,
1671 int external, const u8 *sa, int *ie_offset)
1672{
1673 int *groups;
1674
1675 wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE authentication transaction %u "
1676 "status code %u", auth_transaction, status_code);
1677
1678 if (auth_transaction == 1 &&
1679 status_code == WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ &&
1680 wpa_s->sme.sae.state == SAE_COMMITTED &&
1681 ((external && wpa_s->sme.ext_auth_wpa_ssid) ||
1682 (!external && wpa_s->current_bss && wpa_s->current_ssid))) {
1683 int default_groups[] = { 19, 20, 21, 0 };
1684 u16 group;
1685 const u8 *token_pos;
1686 size_t token_len;
1687 int h2e = 0;
1688
1689 groups = wpa_s->conf->sae_groups;
1690 if (!groups || groups[0] <= 0)
1691 groups = default_groups;
1692
1693 wpa_hexdump(MSG_DEBUG, "SME: SAE anti-clogging token request",
1694 data, len);
1695 if (len < sizeof(le16)) {
1696 wpa_dbg(wpa_s, MSG_DEBUG,
1697 "SME: Too short SAE anti-clogging token request");
1698 return -1;
1699 }
1700 group = WPA_GET_LE16(data);
1701 wpa_dbg(wpa_s, MSG_DEBUG,
1702 "SME: SAE anti-clogging token requested (group %u)",
1703 group);
1704 if (sae_group_allowed(&wpa_s->sme.sae, groups, group) !=
1705 WLAN_STATUS_SUCCESS) {
1706 wpa_dbg(wpa_s, MSG_ERROR,
1707 "SME: SAE group %u of anti-clogging request is invalid",
1708 group);
1709 return -1;
1710 }
1711 wpabuf_free(wpa_s->sme.sae_token);
1712 token_pos = data + sizeof(le16);
1713 token_len = len - sizeof(le16);
1714 h2e = wpa_s->sme.sae.h2e;
1715 if (h2e) {
1716 u8 id, elen, extid;
1717
1718 if (token_len < 3) {
1719 wpa_dbg(wpa_s, MSG_DEBUG,
1720 "SME: Too short SAE anti-clogging token container");
1721 return -1;
1722 }
1723 id = *token_pos++;
1724 elen = *token_pos++;
1725 extid = *token_pos++;
1726 if (id != WLAN_EID_EXTENSION ||
1727 elen == 0 || elen > token_len - 2 ||
1728 extid != WLAN_EID_EXT_ANTI_CLOGGING_TOKEN) {
1729 wpa_dbg(wpa_s, MSG_DEBUG,
1730 "SME: Invalid SAE anti-clogging token container header");
1731 return -1;
1732 }
1733 token_len = elen - 1;
1734 }
1735
1736 *ie_offset = token_pos + token_len - data;
1737
1738 wpa_s->sme.sae_token = wpabuf_alloc_copy(token_pos, token_len);
1739 if (!wpa_s->sme.sae_token) {
1740 wpa_dbg(wpa_s, MSG_ERROR,
1741 "SME: Failed to allocate SAE token");
1742 return -1;
1743 }
1744
1745 wpa_hexdump_buf(MSG_DEBUG, "SME: Requested anti-clogging token",
1746 wpa_s->sme.sae_token);
1747 if (!external) {
1748 sme_send_authentication(wpa_s, wpa_s->current_bss,
1749 wpa_s->current_ssid, 2);
1750 } else {
1751 if (wpa_s->sme.ext_ml_auth &&
1752 sme_external_ml_auth(wpa_s, data, len, *ie_offset,
1753 status_code))
1754 return -1;
1755
1756 sme_external_auth_send_sae_commit(
1757 wpa_s, wpa_s->sme.ext_auth_bssid,
1758 wpa_s->sme.ext_auth_wpa_ssid);
1759 }
1760 return 0;
1761 }
1762
1763 if (auth_transaction == 1 &&
1764 status_code == WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED &&
1765 wpa_s->sme.sae.state == SAE_COMMITTED &&
1766 ((external && wpa_s->sme.ext_auth_wpa_ssid) ||
1767 (!external && wpa_s->current_bss && wpa_s->current_ssid))) {
1768 wpa_dbg(wpa_s, MSG_DEBUG, "SME: SAE group not supported");
1769 int_array_add_unique(&wpa_s->sme.sae_rejected_groups,
1770 wpa_s->sme.sae.group);
1771 wpa_s->sme.sae_group_index++;
1772 if (sme_set_sae_group(wpa_s, external) < 0)
1773 return -1; /* no other groups enabled */
1774 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Try next enabled SAE group");
1775 if (!external) {
1776 sme_send_authentication(wpa_s, wpa_s->current_bss,
1777 wpa_s->current_ssid, 1);
1778 } else {
1779 if (wpa_s->sme.ext_ml_auth &&
1780 sme_external_ml_auth(wpa_s, data, len, *ie_offset,
1781 status_code))
1782 return -1;
1783
1784 sme_external_auth_send_sae_commit(
1785 wpa_s, wpa_s->sme.ext_auth_bssid,
1786 wpa_s->sme.ext_auth_wpa_ssid);
1787 }
1788 return 0;
1789 }
1790
1791 if (auth_transaction == 1 &&
1792 status_code == WLAN_STATUS_UNKNOWN_PASSWORD_IDENTIFIER) {
1793 const u8 *bssid = sa ? sa : wpa_s->pending_bssid;
1794
1795 wpa_msg(wpa_s, MSG_INFO,
1796 WPA_EVENT_SAE_UNKNOWN_PASSWORD_IDENTIFIER MACSTR,
1797 MAC2STR(bssid));
1798 return -1;
1799 }
1800
1801 if (status_code != WLAN_STATUS_SUCCESS &&
1802 status_code != WLAN_STATUS_SAE_HASH_TO_ELEMENT &&
1803 status_code != WLAN_STATUS_SAE_PK) {
1804 const u8 *bssid = sa ? sa : wpa_s->pending_bssid;
1805
1806 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AUTH_REJECT MACSTR
1807 " auth_type=%u auth_transaction=%u status_code=%u",
1808 MAC2STR(bssid), WLAN_AUTH_SAE,
1809 auth_transaction, status_code);
1810 return -2;
1811 }
1812
1813 if (auth_transaction == 1) {
1814 u16 res;
1815
1816 groups = wpa_s->conf->sae_groups;
1817
1818 wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE commit");
1819 if ((external && !wpa_s->sme.ext_auth_wpa_ssid) ||
1820 (!external &&
1821 (!wpa_s->current_bss || !wpa_s->current_ssid)))
1822 return -1;
1823 if (wpa_s->sme.sae.state != SAE_COMMITTED) {
1824 wpa_printf(MSG_DEBUG,
1825 "SAE: Ignore commit message while waiting for confirm");
1826 return 0;
1827 }
1828 if (wpa_s->sme.sae.h2e && status_code == WLAN_STATUS_SUCCESS) {
1829 wpa_printf(MSG_DEBUG,
1830 "SAE: Unexpected use of status code 0 in SAE commit when H2E was expected");
1831 return -1;
1832 }
1833 if ((!wpa_s->sme.sae.h2e || wpa_s->sme.sae.pk) &&
1834 status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
1835 wpa_printf(MSG_DEBUG,
1836 "SAE: Unexpected use of status code for H2E in SAE commit when H2E was not expected");
1837 return -1;
1838 }
1839 if (!wpa_s->sme.sae.pk &&
1840 status_code == WLAN_STATUS_SAE_PK) {
1841 wpa_printf(MSG_DEBUG,
1842 "SAE: Unexpected use of status code for PK in SAE commit when PK was not expected");
1843 return -1;
1844 }
1845
1846 if (groups && groups[0] <= 0)
1847 groups = NULL;
1848 res = sae_parse_commit(&wpa_s->sme.sae, data, len, NULL, NULL,
1849 groups, status_code ==
1850 WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
1851 status_code == WLAN_STATUS_SAE_PK,
1852 ie_offset);
1853 if (res == SAE_SILENTLY_DISCARD) {
1854 wpa_printf(MSG_DEBUG,
1855 "SAE: Drop commit message due to reflection attack");
1856 return 0;
1857 }
1858 if (res != WLAN_STATUS_SUCCESS)
1859 return -1;
1860
1861 if (wpa_s->sme.sae.tmp &&
1862 sme_check_sae_rejected_groups(
1863 wpa_s,
1864 wpa_s->sme.sae.tmp->peer_rejected_groups))
1865 return -1;
1866
1867 if (sae_process_commit(&wpa_s->sme.sae) < 0) {
1868 wpa_printf(MSG_DEBUG, "SAE: Failed to process peer "
1869 "commit");
1870 return -1;
1871 }
1872
1873 wpabuf_free(wpa_s->sme.sae_token);
1874 wpa_s->sme.sae_token = NULL;
1875 if (!external) {
1876 sme_send_authentication(wpa_s, wpa_s->current_bss,
1877 wpa_s->current_ssid, 0);
1878 } else {
1879 if (wpa_s->sme.ext_ml_auth &&
1880 sme_external_ml_auth(wpa_s, data, len, *ie_offset,
1881 status_code))
1882 return -1;
1883
1884 sme_external_auth_send_sae_confirm(wpa_s, sa);
1885 }
1886 return 0;
1887 } else if (auth_transaction == 2) {
1888 if (status_code != WLAN_STATUS_SUCCESS)
1889 return -1;
1890 wpa_dbg(wpa_s, MSG_DEBUG, "SME SAE confirm");
1891 if (wpa_s->sme.sae.state != SAE_CONFIRMED)
1892 return -1;
1893 if (sae_check_confirm(&wpa_s->sme.sae, data, len,
1894 ie_offset) < 0)
1895 return -1;
1896 if (external && wpa_s->sme.ext_ml_auth &&
1897 sme_external_ml_auth(wpa_s, data, len, *ie_offset,
1898 status_code))
1899 return -1;
1900
1901 wpa_s->sme.sae.state = SAE_ACCEPTED;
1902 sae_clear_temp_data(&wpa_s->sme.sae);
1903
1904 if (external) {
1905 /* Report success to driver */
1906 sme_send_external_auth_status(wpa_s,
1907 WLAN_STATUS_SUCCESS);
1908 }
1909
1910 return 1;
1911 }
1912
1913 return -1;
1914}
1915
1916
1917static int sme_sae_set_pmk(struct wpa_supplicant *wpa_s, const u8 *bssid)
1918{
1919 wpa_printf(MSG_DEBUG,
1920 "SME: SAE completed - setting PMK for 4-way handshake");
1921 wpa_sm_set_pmk(wpa_s->wpa, wpa_s->sme.sae.pmk, wpa_s->sme.sae.pmk_len,
1922 wpa_s->sme.sae.pmkid, bssid);
1923 if (wpa_s->conf->sae_pmkid_in_assoc) {
1924 /* Update the own RSNE contents now that we have set the PMK
1925 * and added a PMKSA cache entry based on the successfully
1926 * completed SAE exchange. In practice, this will add the PMKID
1927 * into RSNE. */
1928 if (wpa_s->sme.assoc_req_ie_len + 2 + PMKID_LEN >
1929 sizeof(wpa_s->sme.assoc_req_ie)) {
1930 wpa_msg(wpa_s, MSG_WARNING,
1931 "RSN: Not enough room for inserting own PMKID into RSNE");
1932 return -1;
1933 }
1934 if (wpa_insert_pmkid(wpa_s->sme.assoc_req_ie,
1935 &wpa_s->sme.assoc_req_ie_len,
1936 wpa_s->sme.sae.pmkid) < 0)
1937 return -1;
1938 wpa_hexdump(MSG_DEBUG,
1939 "SME: Updated Association Request IEs",
1940 wpa_s->sme.assoc_req_ie,
1941 wpa_s->sme.assoc_req_ie_len);
1942 }
1943
1944 return 0;
1945}
1946
1947
1948void sme_external_auth_mgmt_rx(struct wpa_supplicant *wpa_s,
1949 const u8 *auth_frame, size_t len)
1950{
1951 const struct ieee80211_mgmt *header;
1952 size_t auth_length;
1953
1954 header = (const struct ieee80211_mgmt *) auth_frame;
1955 auth_length = IEEE80211_HDRLEN + sizeof(header->u.auth);
1956
1957 if (len < auth_length) {
1958 /* Notify failure to the driver */
1959 sme_send_external_auth_status(wpa_s,
1960 WLAN_STATUS_UNSPECIFIED_FAILURE);
1961 return;
1962 }
1963
1964 if (le_to_host16(header->u.auth.auth_alg) == WLAN_AUTH_SAE) {
1965 int res;
1966 int ie_offset = 0;
1967
1968 res = sme_sae_auth(
1969 wpa_s, le_to_host16(header->u.auth.auth_transaction),
1970 le_to_host16(header->u.auth.status_code),
1971 header->u.auth.variable,
1972 len - auth_length, 1, header->sa, &ie_offset);
1973 if (res < 0) {
1974 /* Notify failure to the driver */
1975 sme_send_external_auth_status(
1976 wpa_s,
1977 res == -2 ?
1978 le_to_host16(header->u.auth.status_code) :
1979 WLAN_STATUS_UNSPECIFIED_FAILURE);
1980 return;
1981 }
1982 if (res != 1)
1983 return;
1984
1985 if (sme_sae_set_pmk(wpa_s,
1986 wpa_s->sme.ext_ml_auth ?
1987 wpa_s->sme.ext_auth_ap_mld_addr :
1988 wpa_s->sme.ext_auth_bssid) < 0)
1989 return;
1990 }
1991}
1992
1993#endif /* CONFIG_SAE */
1994
1995
1996void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
1997{
1998 struct wpa_ssid *ssid = wpa_s->current_ssid;
1999 int ie_offset = 0;
2000
2001 if (ssid == NULL) {
2002 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event "
2003 "when network is not selected");
2004 return;
2005 }
2006
2007 if (wpa_s->wpa_state != WPA_AUTHENTICATING) {
2008 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication event "
2009 "when not in authenticating state");
2010 return;
2011 }
2012
2013 if (os_memcmp(wpa_s->pending_bssid, data->auth.peer, ETH_ALEN) != 0 &&
2014 !(wpa_s->valid_links &&
2015 os_memcmp(wpa_s->ap_mld_addr, data->auth.peer, ETH_ALEN) == 0)) {
2016 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Ignore authentication with "
2017 "unexpected peer " MACSTR,
2018 MAC2STR(data->auth.peer));
2019 return;
2020 }
2021
2022 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication response: peer=" MACSTR
2023 " auth_type=%d auth_transaction=%d status_code=%d",
2024 MAC2STR(data->auth.peer), data->auth.auth_type,
2025 data->auth.auth_transaction, data->auth.status_code);
2026 wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs",
2027 data->auth.ies, data->auth.ies_len);
2028
2029 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
2030
2031#ifdef CONFIG_SAE
2032 if (data->auth.auth_type == WLAN_AUTH_SAE) {
2033 const u8 *addr = wpa_s->pending_bssid;
2034 int res;
2035
2036 res = sme_sae_auth(wpa_s, data->auth.auth_transaction,
2037 data->auth.status_code, data->auth.ies,
2038 data->auth.ies_len, 0, data->auth.peer,
2039 &ie_offset);
2040 if (res < 0) {
2041 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
2042 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
2043
2044 }
2045 if (res != 1)
2046 return;
2047
2048 if (wpa_s->valid_links)
2049 addr = wpa_s->ap_mld_addr;
2050
2051 if (sme_sae_set_pmk(wpa_s, addr) < 0)
2052 return;
2053 }
2054#endif /* CONFIG_SAE */
2055
2056 if (data->auth.status_code != WLAN_STATUS_SUCCESS) {
2057 char *ie_txt = NULL;
2058
2059 if (data->auth.ies && data->auth.ies_len) {
2060 size_t buflen = 2 * data->auth.ies_len + 1;
2061 ie_txt = os_malloc(buflen);
2062 if (ie_txt) {
2063 wpa_snprintf_hex(ie_txt, buflen, data->auth.ies,
2064 data->auth.ies_len);
2065 }
2066 }
2067 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_AUTH_REJECT MACSTR
2068 " auth_type=%u auth_transaction=%u status_code=%u%s%s",
2069 MAC2STR(data->auth.peer), data->auth.auth_type,
2070 data->auth.auth_transaction, data->auth.status_code,
2071 ie_txt ? " ie=" : "",
2072 ie_txt ? ie_txt : "");
2073 os_free(ie_txt);
2074
2075#ifdef CONFIG_FILS
2076 if (wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS ||
2077 wpa_s->sme.auth_alg == WPA_AUTH_ALG_FILS_SK_PFS)
2078 fils_connection_failure(wpa_s);
2079#endif /* CONFIG_FILS */
2080
2081 if (data->auth.status_code !=
2082 WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG ||
2083 wpa_s->sme.auth_alg == data->auth.auth_type ||
2084 wpa_s->current_ssid->auth_alg == WPA_AUTH_ALG_LEAP) {
2085 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
2086 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
2087 return;
2088 }
2089
2090 wpas_connect_work_done(wpa_s);
2091
2092 switch (data->auth.auth_type) {
2093 case WLAN_AUTH_OPEN:
2094 wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_SHARED;
2095
2096 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying SHARED auth");
2097 wpa_supplicant_associate(wpa_s, wpa_s->current_bss,
2098 wpa_s->current_ssid);
2099 return;
2100
2101 case WLAN_AUTH_SHARED_KEY:
2102 wpa_s->current_ssid->auth_alg = WPA_AUTH_ALG_LEAP;
2103
2104 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Trying LEAP auth");
2105 wpa_supplicant_associate(wpa_s, wpa_s->current_bss,
2106 wpa_s->current_ssid);
2107 return;
2108
2109 default:
2110 return;
2111 }
2112 }
2113
2114#ifdef CONFIG_IEEE80211R
2115 if (data->auth.auth_type == WLAN_AUTH_FT) {
2116 const u8 *ric_ies = NULL;
2117 size_t ric_ies_len = 0;
2118
2119 if (wpa_s->ric_ies) {
2120 ric_ies = wpabuf_head(wpa_s->ric_ies);
2121 ric_ies_len = wpabuf_len(wpa_s->ric_ies);
2122 }
2123 if (wpa_ft_process_response(wpa_s->wpa, data->auth.ies,
2124 data->auth.ies_len, 0,
2125 data->auth.peer,
2126 ric_ies, ric_ies_len) < 0) {
2127 wpa_dbg(wpa_s, MSG_DEBUG,
2128 "SME: FT Authentication response processing failed");
2129 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid="
2130 MACSTR
2131 " reason=%d locally_generated=1",
2132 MAC2STR(wpa_s->pending_bssid),
2133 WLAN_REASON_DEAUTH_LEAVING);
2134 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
2135 wpa_supplicant_mark_disassoc(wpa_s);
2136 return;
2137 }
2138 }
2139#endif /* CONFIG_IEEE80211R */
2140
2141#ifdef CONFIG_FILS
2142 if (data->auth.auth_type == WLAN_AUTH_FILS_SK ||
2143 data->auth.auth_type == WLAN_AUTH_FILS_SK_PFS) {
2144 u16 expect_auth_type;
2145
2146 expect_auth_type = wpa_s->sme.auth_alg ==
2147 WPA_AUTH_ALG_FILS_SK_PFS ? WLAN_AUTH_FILS_SK_PFS :
2148 WLAN_AUTH_FILS_SK;
2149 if (data->auth.auth_type != expect_auth_type) {
2150 wpa_dbg(wpa_s, MSG_DEBUG,
2151 "SME: FILS Authentication response used different auth alg (%u; expected %u)",
2152 data->auth.auth_type, expect_auth_type);
2153 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid="
2154 MACSTR
2155 " reason=%d locally_generated=1",
2156 MAC2STR(wpa_s->pending_bssid),
2157 WLAN_REASON_DEAUTH_LEAVING);
2158 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
2159 wpa_supplicant_mark_disassoc(wpa_s);
2160 return;
2161 }
2162
2163 if (fils_process_auth(wpa_s->wpa, wpa_s->pending_bssid,
2164 data->auth.ies, data->auth.ies_len) < 0) {
2165 wpa_dbg(wpa_s, MSG_DEBUG,
2166 "SME: FILS Authentication response processing failed");
2167 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_DISCONNECTED "bssid="
2168 MACSTR
2169 " reason=%d locally_generated=1",
2170 MAC2STR(wpa_s->pending_bssid),
2171 WLAN_REASON_DEAUTH_LEAVING);
2172 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
2173 wpa_supplicant_mark_disassoc(wpa_s);
2174 return;
2175 }
2176 }
2177#endif /* CONFIG_FILS */
2178
2179 /* TODO: Support additional auth_type values as well */
2180 if (data->auth.auth_type == WLAN_AUTH_OPEN ||
2181 data->auth.auth_type == WLAN_AUTH_SAE)
2182 wpas_sme_ml_auth(wpa_s, data, ie_offset);
2183
2184 sme_associate(wpa_s, ssid->mode, data->auth.peer,
2185 data->auth.auth_type);
2186}
2187
2188
2189#ifdef CONFIG_IEEE80211R
2190static void remove_ie(u8 *buf, size_t *len, u8 eid)
2191{
2192 u8 *pos, *next, *end;
2193
2194 pos = (u8 *) get_ie(buf, *len, eid);
2195 if (pos) {
2196 next = pos + 2 + pos[1];
2197 end = buf + *len;
2198 *len -= 2 + pos[1];
2199 os_memmove(pos, next, end - next);
2200 }
2201}
2202#endif /* CONFIG_IEEE80211R */
2203
2204
2205void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
2206 const u8 *bssid, u16 auth_type)
2207{
2208 struct wpa_driver_associate_params params;
2209 struct ieee802_11_elems elems;
2210 struct wpa_ssid *ssid = wpa_s->current_ssid;
2211#ifdef CONFIG_FILS
2212 u8 nonces[2 * FILS_NONCE_LEN];
2213#endif /* CONFIG_FILS */
2214#ifdef CONFIG_HT_OVERRIDES
2215 struct ieee80211_ht_capabilities htcaps;
2216 struct ieee80211_ht_capabilities htcaps_mask;
2217#endif /* CONFIG_HT_OVERRIDES */
2218#ifdef CONFIG_VHT_OVERRIDES
2219 struct ieee80211_vht_capabilities vhtcaps;
2220 struct ieee80211_vht_capabilities vhtcaps_mask;
2221#endif /* CONFIG_VHT_OVERRIDES */
2222
2223 os_memset(&params, 0, sizeof(params));
2224
2225#ifdef CONFIG_FILS
2226 if (auth_type == WLAN_AUTH_FILS_SK ||
2227 auth_type == WLAN_AUTH_FILS_SK_PFS) {
2228 struct wpabuf *buf;
2229 const u8 *snonce, *anonce;
2230 const unsigned int max_hlp = 20;
2231 struct wpabuf *hlp[max_hlp];
2232 unsigned int i, num_hlp = 0;
2233 struct fils_hlp_req *req;
2234
2235 dl_list_for_each(req, &wpa_s->fils_hlp_req, struct fils_hlp_req,
2236 list) {
2237 hlp[num_hlp] = wpabuf_alloc(2 * ETH_ALEN + 6 +
2238 wpabuf_len(req->pkt));
2239 if (!hlp[num_hlp])
2240 break;
2241 wpabuf_put_data(hlp[num_hlp], req->dst, ETH_ALEN);
2242 wpabuf_put_data(hlp[num_hlp], wpa_s->own_addr,
2243 ETH_ALEN);
2244 wpabuf_put_data(hlp[num_hlp],
2245 "\xaa\xaa\x03\x00\x00\x00", 6);
2246 wpabuf_put_buf(hlp[num_hlp], req->pkt);
2247 num_hlp++;
2248 if (num_hlp >= max_hlp)
2249 break;
2250 }
2251
2252 buf = fils_build_assoc_req(wpa_s->wpa, &params.fils_kek,
2253 &params.fils_kek_len, &snonce,
2254 &anonce,
2255 (const struct wpabuf **) hlp,
2256 num_hlp);
2257 for (i = 0; i < num_hlp; i++)
2258 wpabuf_free(hlp[i]);
2259 if (!buf)
2260 return;
2261 wpa_hexdump(MSG_DEBUG, "FILS: assoc_req before FILS elements",
2262 wpa_s->sme.assoc_req_ie,
2263 wpa_s->sme.assoc_req_ie_len);
2264#ifdef CONFIG_IEEE80211R
2265 if (wpa_key_mgmt_ft(wpa_s->key_mgmt)) {
2266 /* Remove RSNE and MDE to allow them to be overridden
2267 * with FILS+FT specific values from
2268 * fils_build_assoc_req(). */
2269 remove_ie(wpa_s->sme.assoc_req_ie,
2270 &wpa_s->sme.assoc_req_ie_len,
2271 WLAN_EID_RSN);
2272 wpa_hexdump(MSG_DEBUG,
2273 "FILS: assoc_req after RSNE removal",
2274 wpa_s->sme.assoc_req_ie,
2275 wpa_s->sme.assoc_req_ie_len);
2276 remove_ie(wpa_s->sme.assoc_req_ie,
2277 &wpa_s->sme.assoc_req_ie_len,
2278 WLAN_EID_MOBILITY_DOMAIN);
2279 wpa_hexdump(MSG_DEBUG,
2280 "FILS: assoc_req after MDE removal",
2281 wpa_s->sme.assoc_req_ie,
2282 wpa_s->sme.assoc_req_ie_len);
2283 }
2284#endif /* CONFIG_IEEE80211R */
2285 /* TODO: Make wpa_s->sme.assoc_req_ie use dynamic allocation */
2286 if (wpa_s->sme.assoc_req_ie_len + wpabuf_len(buf) >
2287 sizeof(wpa_s->sme.assoc_req_ie)) {
2288 wpa_printf(MSG_ERROR,
2289 "FILS: Not enough buffer room for own AssocReq elements");
2290 wpabuf_free(buf);
2291 return;
2292 }
2293 os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
2294 wpabuf_head(buf), wpabuf_len(buf));
2295 wpa_s->sme.assoc_req_ie_len += wpabuf_len(buf);
2296 wpabuf_free(buf);
2297 wpa_hexdump(MSG_DEBUG, "FILS: assoc_req after FILS elements",
2298 wpa_s->sme.assoc_req_ie,
2299 wpa_s->sme.assoc_req_ie_len);
2300
2301 os_memcpy(nonces, snonce, FILS_NONCE_LEN);
2302 os_memcpy(nonces + FILS_NONCE_LEN, anonce, FILS_NONCE_LEN);
2303 params.fils_nonces = nonces;
2304 params.fils_nonces_len = sizeof(nonces);
2305 }
2306#endif /* CONFIG_FILS */
2307
2308#ifdef CONFIG_OWE
2309#ifdef CONFIG_TESTING_OPTIONS
2310 if (get_ie_ext(wpa_s->sme.assoc_req_ie, wpa_s->sme.assoc_req_ie_len,
2311 WLAN_EID_EXT_OWE_DH_PARAM)) {
2312 wpa_printf(MSG_INFO, "TESTING: Override OWE DH element");
2313 } else
2314#endif /* CONFIG_TESTING_OPTIONS */
2315 if (auth_type == WLAN_AUTH_OPEN &&
2316 wpa_s->key_mgmt == WPA_KEY_MGMT_OWE) {
2317 struct wpabuf *owe_ie;
2318 u16 group;
2319
2320 if (ssid && ssid->owe_group) {
2321 group = ssid->owe_group;
2322 } else if (wpa_s->assoc_status_code ==
2323 WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED) {
2324 if (wpa_s->last_owe_group == 19)
2325 group = 20;
2326 else if (wpa_s->last_owe_group == 20)
2327 group = 21;
2328 else
2329 group = OWE_DH_GROUP;
2330 } else {
2331 group = OWE_DH_GROUP;
2332 }
2333
2334 wpa_s->last_owe_group = group;
2335 wpa_printf(MSG_DEBUG, "OWE: Try to use group %u", group);
2336 owe_ie = owe_build_assoc_req(wpa_s->wpa, group);
2337 if (!owe_ie) {
2338 wpa_printf(MSG_ERROR,
2339 "OWE: Failed to build IE for Association Request frame");
2340 return;
2341 }
2342 if (wpa_s->sme.assoc_req_ie_len + wpabuf_len(owe_ie) >
2343 sizeof(wpa_s->sme.assoc_req_ie)) {
2344 wpa_printf(MSG_ERROR,
2345 "OWE: Not enough buffer room for own Association Request frame elements");
2346 wpabuf_free(owe_ie);
2347 return;
2348 }
2349 os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
2350 wpabuf_head(owe_ie), wpabuf_len(owe_ie));
2351 wpa_s->sme.assoc_req_ie_len += wpabuf_len(owe_ie);
2352 wpabuf_free(owe_ie);
2353 }
2354#endif /* CONFIG_OWE */
2355
2356#ifdef CONFIG_DPP2
2357 if (DPP_VERSION > 1 && wpa_s->key_mgmt == WPA_KEY_MGMT_DPP && ssid &&
2358 ssid->dpp_netaccesskey && ssid->dpp_pfs != 2 &&
2359 !ssid->dpp_pfs_fallback) {
2360 struct rsn_pmksa_cache_entry *pmksa;
2361
2362 pmksa = pmksa_cache_get_current(wpa_s->wpa);
2363 if (!pmksa || !pmksa->dpp_pfs)
2364 goto pfs_fail;
2365
2366 dpp_pfs_free(wpa_s->dpp_pfs);
2367 wpa_s->dpp_pfs = dpp_pfs_init(ssid->dpp_netaccesskey,
2368 ssid->dpp_netaccesskey_len);
2369 if (!wpa_s->dpp_pfs) {
2370 wpa_printf(MSG_DEBUG, "DPP: Could not initialize PFS");
2371 /* Try to continue without PFS */
2372 goto pfs_fail;
2373 }
2374 if (wpa_s->sme.assoc_req_ie_len +
2375 wpabuf_len(wpa_s->dpp_pfs->ie) >
2376 sizeof(wpa_s->sme.assoc_req_ie)) {
2377 wpa_printf(MSG_ERROR,
2378 "DPP: Not enough buffer room for own Association Request frame elements");
2379 dpp_pfs_free(wpa_s->dpp_pfs);
2380 wpa_s->dpp_pfs = NULL;
2381 goto pfs_fail;
2382 }
2383 os_memcpy(wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
2384 wpabuf_head(wpa_s->dpp_pfs->ie),
2385 wpabuf_len(wpa_s->dpp_pfs->ie));
2386 wpa_s->sme.assoc_req_ie_len += wpabuf_len(wpa_s->dpp_pfs->ie);
2387 }
2388pfs_fail:
2389#endif /* CONFIG_DPP2 */
2390
2391 wpa_s->mscs_setup_done = false;
2392 if (wpa_bss_ext_capab(wpa_s->current_bss, WLAN_EXT_CAPAB_MSCS) &&
2393 wpa_s->robust_av.valid_config) {
2394 struct wpabuf *mscs_ie;
2395 size_t mscs_ie_len, buf_len, *wpa_ie_len, max_ie_len;
2396
2397 buf_len = 3 + /* MSCS descriptor IE header */
2398 1 + /* Request type */
2399 2 + /* User priority control */
2400 4 + /* Stream timeout */
2401 3 + /* TCLAS Mask IE header */
2402 wpa_s->robust_av.frame_classifier_len;
2403 mscs_ie = wpabuf_alloc(buf_len);
2404 if (!mscs_ie) {
2405 wpa_printf(MSG_INFO,
2406 "MSCS: Failed to allocate MSCS IE");
2407 goto mscs_fail;
2408 }
2409
2410 wpa_ie_len = &wpa_s->sme.assoc_req_ie_len;
2411 max_ie_len = sizeof(wpa_s->sme.assoc_req_ie);
2412 wpas_populate_mscs_descriptor_ie(&wpa_s->robust_av, mscs_ie);
2413 if ((*wpa_ie_len + wpabuf_len(mscs_ie)) <= max_ie_len) {
2414 wpa_hexdump_buf(MSG_MSGDUMP, "MSCS IE", mscs_ie);
2415 mscs_ie_len = wpabuf_len(mscs_ie);
2416 os_memcpy(wpa_s->sme.assoc_req_ie + *wpa_ie_len,
2417 wpabuf_head(mscs_ie), mscs_ie_len);
2418 *wpa_ie_len += mscs_ie_len;
2419 }
2420
2421 wpabuf_free(mscs_ie);
2422 }
2423mscs_fail:
2424
2425 if (ssid && ssid->multi_ap_backhaul_sta) {
2426 size_t multi_ap_ie_len;
2427
2428 multi_ap_ie_len = add_multi_ap_ie(
2429 wpa_s->sme.assoc_req_ie + wpa_s->sme.assoc_req_ie_len,
2430 sizeof(wpa_s->sme.assoc_req_ie) -
2431 wpa_s->sme.assoc_req_ie_len,
2432 MULTI_AP_BACKHAUL_STA);
2433 if (multi_ap_ie_len == 0) {
2434 wpa_printf(MSG_ERROR,
2435 "Multi-AP: Failed to build Multi-AP IE");
2436 return;
2437 }
2438 wpa_s->sme.assoc_req_ie_len += multi_ap_ie_len;
2439 }
2440
2441 params.bssid = bssid;
2442 params.ssid = wpa_s->sme.ssid;
2443 params.ssid_len = wpa_s->sme.ssid_len;
2444 params.freq.freq = wpa_s->sme.freq;
2445 params.bg_scan_period = ssid ? ssid->bg_scan_period : -1;
2446 params.wpa_ie = wpa_s->sme.assoc_req_ie_len ?
2447 wpa_s->sme.assoc_req_ie : NULL;
2448 params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
2449 wpa_hexdump(MSG_DEBUG, "SME: Association Request IEs",
2450 params.wpa_ie, params.wpa_ie_len);
2451 params.pairwise_suite = wpa_s->pairwise_cipher;
2452 params.group_suite = wpa_s->group_cipher;
2453 params.mgmt_group_suite = wpa_s->mgmt_group_cipher;
2454 params.key_mgmt_suite = wpa_s->key_mgmt;
2455 params.wpa_proto = wpa_s->wpa_proto;
2456#ifdef CONFIG_HT_OVERRIDES
2457 os_memset(&htcaps, 0, sizeof(htcaps));
2458 os_memset(&htcaps_mask, 0, sizeof(htcaps_mask));
2459 params.htcaps = (u8 *) &htcaps;
2460 params.htcaps_mask = (u8 *) &htcaps_mask;
2461 wpa_supplicant_apply_ht_overrides(wpa_s, ssid, &params);
2462#endif /* CONFIG_HT_OVERRIDES */
2463#ifdef CONFIG_VHT_OVERRIDES
2464 os_memset(&vhtcaps, 0, sizeof(vhtcaps));
2465 os_memset(&vhtcaps_mask, 0, sizeof(vhtcaps_mask));
2466 params.vhtcaps = &vhtcaps;
2467 params.vhtcaps_mask = &vhtcaps_mask;
2468 wpa_supplicant_apply_vht_overrides(wpa_s, ssid, &params);
2469#endif /* CONFIG_VHT_OVERRIDES */
2470#ifdef CONFIG_HE_OVERRIDES
2471 wpa_supplicant_apply_he_overrides(wpa_s, ssid, &params);
2472#endif /* CONFIG_HE_OVERRIDES */
2473 wpa_supplicant_apply_eht_overrides(wpa_s, ssid, &params);
2474#ifdef CONFIG_IEEE80211R
2475 if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies &&
2476 get_ie(wpa_s->sme.ft_ies, wpa_s->sme.ft_ies_len,
2477 WLAN_EID_RIC_DATA)) {
2478 /* There seems to be a pretty inconvenient bug in the Linux
2479 * kernel IE splitting functionality when RIC is used. For now,
2480 * skip correct behavior in IE construction here (i.e., drop the
2481 * additional non-FT-specific IEs) to avoid kernel issues. This
2482 * is fine since RIC is used only for testing purposes in the
2483 * current implementation. */
2484 wpa_printf(MSG_INFO,
2485 "SME: Linux kernel workaround - do not try to include additional IEs with RIC");
2486 params.wpa_ie = wpa_s->sme.ft_ies;
2487 params.wpa_ie_len = wpa_s->sme.ft_ies_len;
2488 } else if (auth_type == WLAN_AUTH_FT && wpa_s->sme.ft_ies) {
2489 const u8 *rm_en, *pos, *end;
2490 size_t rm_en_len = 0;
2491 u8 *rm_en_dup = NULL, *wpos;
2492
2493 /* Remove RSNE, MDE, FTE to allow them to be overridden with
2494 * FT specific values */
2495 remove_ie(wpa_s->sme.assoc_req_ie,
2496 &wpa_s->sme.assoc_req_ie_len,
2497 WLAN_EID_RSN);
2498 remove_ie(wpa_s->sme.assoc_req_ie,
2499 &wpa_s->sme.assoc_req_ie_len,
2500 WLAN_EID_MOBILITY_DOMAIN);
2501 remove_ie(wpa_s->sme.assoc_req_ie,
2502 &wpa_s->sme.assoc_req_ie_len,
2503 WLAN_EID_FAST_BSS_TRANSITION);
2504 rm_en = get_ie(wpa_s->sme.assoc_req_ie,
2505 wpa_s->sme.assoc_req_ie_len,
2506 WLAN_EID_RRM_ENABLED_CAPABILITIES);
2507 if (rm_en) {
2508 /* Need to remove RM Enabled Capabilities element as
2509 * well temporarily, so that it can be placed between
2510 * RSNE and MDE. */
2511 rm_en_len = 2 + rm_en[1];
2512 rm_en_dup = os_memdup(rm_en, rm_en_len);
2513 remove_ie(wpa_s->sme.assoc_req_ie,
2514 &wpa_s->sme.assoc_req_ie_len,
2515 WLAN_EID_RRM_ENABLED_CAPABILITIES);
2516 }
2517 wpa_hexdump(MSG_DEBUG,
2518 "SME: Association Request IEs after FT IE removal",
2519 wpa_s->sme.assoc_req_ie,
2520 wpa_s->sme.assoc_req_ie_len);
2521 if (wpa_s->sme.assoc_req_ie_len + wpa_s->sme.ft_ies_len +
2522 rm_en_len > sizeof(wpa_s->sme.assoc_req_ie)) {
2523 wpa_printf(MSG_ERROR,
2524 "SME: Not enough buffer room for FT IEs in Association Request frame");
2525 os_free(rm_en_dup);
2526 return;
2527 }
2528
2529 os_memmove(wpa_s->sme.assoc_req_ie + wpa_s->sme.ft_ies_len +
2530 rm_en_len,
2531 wpa_s->sme.assoc_req_ie,
2532 wpa_s->sme.assoc_req_ie_len);
2533 pos = wpa_s->sme.ft_ies;
2534 end = pos + wpa_s->sme.ft_ies_len;
2535 wpos = wpa_s->sme.assoc_req_ie;
2536 if (*pos == WLAN_EID_RSN) {
2537 os_memcpy(wpos, pos, 2 + pos[1]);
2538 wpos += 2 + pos[1];
2539 pos += 2 + pos[1];
2540 }
2541 if (rm_en_dup) {
2542 os_memcpy(wpos, rm_en_dup, rm_en_len);
2543 wpos += rm_en_len;
2544 os_free(rm_en_dup);
2545 }
2546 os_memcpy(wpos, pos, end - pos);
2547 wpa_s->sme.assoc_req_ie_len += wpa_s->sme.ft_ies_len +
2548 rm_en_len;
2549 params.wpa_ie = wpa_s->sme.assoc_req_ie;
2550 params.wpa_ie_len = wpa_s->sme.assoc_req_ie_len;
2551 wpa_hexdump(MSG_DEBUG,
2552 "SME: Association Request IEs after FT override",
2553 params.wpa_ie, params.wpa_ie_len);
2554 }
2555#endif /* CONFIG_IEEE80211R */
2556 params.mode = mode;
2557 params.mgmt_frame_protection = wpa_s->sme.mfp;
2558 params.rrm_used = wpa_s->rrm.rrm_used;
2559 if (wpa_s->sme.prev_bssid_set)
2560 params.prev_bssid = wpa_s->sme.prev_bssid;
2561
2562 wpa_msg(wpa_s, MSG_INFO, "Trying to associate with " MACSTR
2563 " (SSID='%s' freq=%d MHz)", MAC2STR(params.bssid),
2564 params.ssid ? wpa_ssid_txt(params.ssid, params.ssid_len) : "",
2565 params.freq.freq);
2566
2567 wpa_supplicant_set_state(wpa_s, WPA_ASSOCIATING);
2568
2569 if (params.wpa_ie == NULL ||
2570 ieee802_11_parse_elems(params.wpa_ie, params.wpa_ie_len, &elems, 0)
2571 < 0) {
2572 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Could not parse own IEs?!");
2573 os_memset(&elems, 0, sizeof(elems));
2574 }
2575 if (elems.rsn_ie) {
2576 params.wpa_proto = WPA_PROTO_RSN;
2577 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.rsn_ie - 2,
2578 elems.rsn_ie_len + 2);
2579 } else if (elems.wpa_ie) {
2580 params.wpa_proto = WPA_PROTO_WPA;
2581 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.wpa_ie - 2,
2582 elems.wpa_ie_len + 2);
2583 } else if (elems.osen) {
2584 params.wpa_proto = WPA_PROTO_OSEN;
2585 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, elems.osen - 2,
2586 elems.osen_len + 2);
2587 } else
2588 wpa_sm_set_assoc_wpa_ie(wpa_s->wpa, NULL, 0);
2589 if (elems.rsnxe)
2590 wpa_sm_set_assoc_rsnxe(wpa_s->wpa, elems.rsnxe - 2,
2591 elems.rsnxe_len + 2);
2592 else
2593 wpa_sm_set_assoc_rsnxe(wpa_s->wpa, NULL, 0);
2594 if (ssid && ssid->p2p_group)
2595 params.p2p = 1;
2596
2597 if (wpa_s->p2pdev->set_sta_uapsd)
2598 params.uapsd = wpa_s->p2pdev->sta_uapsd;
2599 else
2600 params.uapsd = -1;
2601
2602 if (wpa_s->valid_links) {
2603 unsigned int i;
2604
2605 wpa_printf(MSG_DEBUG,
2606 "MLD: In association. assoc_link_id=%u, valid_links=0x%x",
2607 wpa_s->mlo_assoc_link_id, wpa_s->valid_links);
2608
2609 params.mld_params.mld_addr = wpa_s->ap_mld_addr;
2610 params.mld_params.valid_links = wpa_s->valid_links;
2611 params.mld_params.assoc_link_id = wpa_s->mlo_assoc_link_id;
2612 for (i = 0; i < MAX_NUM_MLD_LINKS; i++) {
2613 if (!(wpa_s->valid_links & BIT(i)))
2614 continue;
2615
2616 params.mld_params.mld_links[i].bssid =
2617 wpa_s->links[i].bssid;
2618 params.mld_params.mld_links[i].freq =
2619 wpa_s->links[i].freq;
2620
2621 wpa_printf(MSG_DEBUG, "MLD: id=%u, freq=%d, " MACSTR,
2622 i, wpa_s->links[i].freq,
2623 MAC2STR(wpa_s->links[i].bssid));
2624 }
2625 }
2626
2627 if (wpa_drv_associate(wpa_s, &params) < 0) {
2628 wpa_msg(wpa_s, MSG_INFO, "SME: Association request to the "
2629 "driver failed");
2630 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
2631 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
2632 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2633 return;
2634 }
2635
2636 eloop_register_timeout(SME_ASSOC_TIMEOUT, 0, sme_assoc_timer, wpa_s,
2637 NULL);
2638
2639#ifdef CONFIG_TESTING_OPTIONS
2640 wpabuf_free(wpa_s->last_assoc_req_wpa_ie);
2641 wpa_s->last_assoc_req_wpa_ie = NULL;
2642 if (params.wpa_ie)
2643 wpa_s->last_assoc_req_wpa_ie =
2644 wpabuf_alloc_copy(params.wpa_ie, params.wpa_ie_len);
2645#endif /* CONFIG_TESTING_OPTIONS */
2646}
2647
2648
2649int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
2650 const u8 *ies, size_t ies_len)
2651{
2652 if (md == NULL || ies == NULL) {
2653 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Remove mobility domain");
2654 os_free(wpa_s->sme.ft_ies);
2655 wpa_s->sme.ft_ies = NULL;
2656 wpa_s->sme.ft_ies_len = 0;
2657 wpa_s->sme.ft_used = 0;
2658 return 0;
2659 }
2660
2661 os_memcpy(wpa_s->sme.mobility_domain, md, MOBILITY_DOMAIN_ID_LEN);
2662 wpa_hexdump(MSG_DEBUG, "SME: FT IEs", ies, ies_len);
2663 os_free(wpa_s->sme.ft_ies);
2664 wpa_s->sme.ft_ies = os_memdup(ies, ies_len);
2665 if (wpa_s->sme.ft_ies == NULL)
2666 return -1;
2667 wpa_s->sme.ft_ies_len = ies_len;
2668 return 0;
2669}
2670
2671
2672static void sme_deauth(struct wpa_supplicant *wpa_s)
2673{
2674 int bssid_changed;
2675
2676 bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
2677
2678 if (wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid,
2679 WLAN_REASON_DEAUTH_LEAVING) < 0) {
2680 wpa_msg(wpa_s, MSG_INFO, "SME: Deauth request to the driver "
2681 "failed");
2682 }
2683 wpa_s->sme.prev_bssid_set = 0;
2684
2685 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
2686 wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
2687 os_memset(wpa_s->bssid, 0, ETH_ALEN);
2688 os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
2689 if (bssid_changed)
2690 wpas_notify_bssid_changed(wpa_s);
2691}
2692
2693
2694void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
2695 union wpa_event_data *data)
2696{
2697 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association with " MACSTR " failed: "
2698 "status code %d", MAC2STR(wpa_s->pending_bssid),
2699 data->assoc_reject.status_code);
2700
2701 eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
2702
2703#ifdef CONFIG_SAE
2704 if (wpa_s->sme.sae_pmksa_caching && wpa_s->current_ssid &&
2705 wpa_key_mgmt_sae(wpa_s->current_ssid->key_mgmt)) {
2706 wpa_dbg(wpa_s, MSG_DEBUG,
2707 "PMKSA caching attempt rejected - drop PMKSA cache entry and fall back to SAE authentication");
2708 wpa_sm_aborted_cached(wpa_s->wpa);
2709 wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_s->current_ssid);
2710 if (wpa_s->current_bss) {
2711 struct wpa_bss *bss = wpa_s->current_bss;
2712 struct wpa_ssid *ssid = wpa_s->current_ssid;
2713
2714 wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid,
2715 WLAN_REASON_DEAUTH_LEAVING);
2716 wpas_connect_work_done(wpa_s);
2717 wpa_supplicant_mark_disassoc(wpa_s);
2718 wpa_supplicant_connect(wpa_s, bss, ssid);
2719 return;
2720 }
2721 }
2722#endif /* CONFIG_SAE */
2723
2724#ifdef CONFIG_DPP
2725 if (wpa_s->current_ssid &&
2726 wpa_s->current_ssid->key_mgmt == WPA_KEY_MGMT_DPP &&
2727 !data->assoc_reject.timed_out &&
2728 data->assoc_reject.status_code == WLAN_STATUS_INVALID_PMKID) {
2729 struct rsn_pmksa_cache_entry *pmksa;
2730
2731 pmksa = pmksa_cache_get_current(wpa_s->wpa);
2732 if (pmksa) {
2733 wpa_dbg(wpa_s, MSG_DEBUG,
2734 "DPP: Drop PMKSA cache entry for the BSS due to invalid PMKID report");
2735 wpa_sm_pmksa_cache_remove(wpa_s->wpa, pmksa);
2736 }
2737 wpa_sm_aborted_cached(wpa_s->wpa);
2738 if (wpa_s->current_bss) {
2739 struct wpa_bss *bss = wpa_s->current_bss;
2740 struct wpa_ssid *ssid = wpa_s->current_ssid;
2741
2742 wpa_dbg(wpa_s, MSG_DEBUG,
2743 "DPP: Try network introduction again");
2744 wpas_connect_work_done(wpa_s);
2745 wpa_supplicant_mark_disassoc(wpa_s);
2746 wpa_supplicant_connect(wpa_s, bss, ssid);
2747 return;
2748 }
2749 }
2750#endif /* CONFIG_DPP */
2751
2752 /*
2753 * For now, unconditionally terminate the previous authentication. In
2754 * theory, this should not be needed, but mac80211 gets quite confused
2755 * if the authentication is left pending.. Some roaming cases might
2756 * benefit from using the previous authentication, so this could be
2757 * optimized in the future.
2758 */
2759 sme_deauth(wpa_s);
2760}
2761
2762
2763void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
2764 union wpa_event_data *data)
2765{
2766 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Authentication timed out");
2767 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
2768 wpa_supplicant_mark_disassoc(wpa_s);
2769}
2770
2771
2772void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
2773 union wpa_event_data *data)
2774{
2775 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association timed out");
2776 wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
2777 wpa_supplicant_mark_disassoc(wpa_s);
2778}
2779
2780
2781void sme_event_disassoc(struct wpa_supplicant *wpa_s,
2782 struct disassoc_info *info)
2783{
2784 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Disassociation event received");
2785 if (wpa_s->sme.prev_bssid_set) {
2786 /*
2787 * cfg80211/mac80211 can get into somewhat confused state if
2788 * the AP only disassociates us and leaves us in authenticated
2789 * state. For now, force the state to be cleared to avoid
2790 * confusing errors if we try to associate with the AP again.
2791 */
2792 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Deauthenticate to clear "
2793 "driver state");
2794 wpa_drv_deauthenticate(wpa_s, wpa_s->sme.prev_bssid,
2795 WLAN_REASON_DEAUTH_LEAVING);
2796 }
2797}
2798
2799
2800static void sme_auth_timer(void *eloop_ctx, void *timeout_ctx)
2801{
2802 struct wpa_supplicant *wpa_s = eloop_ctx;
2803 if (wpa_s->wpa_state == WPA_AUTHENTICATING) {
2804 wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timeout");
2805 sme_deauth(wpa_s);
2806 }
2807}
2808
2809
2810static void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx)
2811{
2812 struct wpa_supplicant *wpa_s = eloop_ctx;
2813 if (wpa_s->wpa_state == WPA_ASSOCIATING) {
2814 wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timeout");
2815 sme_deauth(wpa_s);
2816 }
2817}
2818
2819
2820void sme_state_changed(struct wpa_supplicant *wpa_s)
2821{
2822 /* Make sure timers are cleaned up appropriately. */
2823 if (wpa_s->wpa_state != WPA_ASSOCIATING)
2824 eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
2825 if (wpa_s->wpa_state != WPA_AUTHENTICATING)
2826 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
2827}
2828
2829
2830void sme_disassoc_while_authenticating(struct wpa_supplicant *wpa_s,
2831 const u8 *prev_pending_bssid)
2832{
2833 /*
2834 * mac80211-workaround to force deauth on failed auth cmd,
2835 * requires us to remain in authenticating state to allow the
2836 * second authentication attempt to be continued properly.
2837 */
2838 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Allow pending authentication "
2839 "to proceed after disconnection event");
2840 wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
2841 os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN);
2842
2843 /*
2844 * Re-arm authentication timer in case auth fails for whatever reason.
2845 */
2846 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
2847 eloop_register_timeout(SME_AUTH_TIMEOUT, 0, sme_auth_timer, wpa_s,
2848 NULL);
2849}
2850
2851
2852void sme_clear_on_disassoc(struct wpa_supplicant *wpa_s)
2853{
2854 wpa_s->sme.prev_bssid_set = 0;
2855#ifdef CONFIG_SAE
2856 wpabuf_free(wpa_s->sme.sae_token);
2857 wpa_s->sme.sae_token = NULL;
2858 sae_clear_data(&wpa_s->sme.sae);
2859#endif /* CONFIG_SAE */
2860#ifdef CONFIG_IEEE80211R
2861 if (wpa_s->sme.ft_ies || wpa_s->sme.ft_used)
2862 sme_update_ft_ies(wpa_s, NULL, NULL, 0);
2863#endif /* CONFIG_IEEE80211R */
2864 sme_stop_sa_query(wpa_s);
2865}
2866
2867
2868void sme_deinit(struct wpa_supplicant *wpa_s)
2869{
2870 sme_clear_on_disassoc(wpa_s);
2871#ifdef CONFIG_SAE
2872 os_free(wpa_s->sme.sae_rejected_groups);
2873 wpa_s->sme.sae_rejected_groups = NULL;
2874#endif /* CONFIG_SAE */
2875
2876 eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
2877 eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
2878 eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL);
2879}
2880
2881
2882static void sme_send_2040_bss_coex(struct wpa_supplicant *wpa_s,
2883 const u8 *chan_list, u8 num_channels,
2884 u8 num_intol)
2885{
2886 struct ieee80211_2040_bss_coex_ie *bc_ie;
2887 struct ieee80211_2040_intol_chan_report *ic_report;
2888 struct wpabuf *buf;
2889
2890 wpa_printf(MSG_DEBUG, "SME: Send 20/40 BSS Coexistence to " MACSTR
2891 " (num_channels=%u num_intol=%u)",
2892 MAC2STR(wpa_s->bssid), num_channels, num_intol);
2893 wpa_hexdump(MSG_DEBUG, "SME: 20/40 BSS Intolerant Channels",
2894 chan_list, num_channels);
2895
2896 buf = wpabuf_alloc(2 + /* action.category + action_code */
2897 sizeof(struct ieee80211_2040_bss_coex_ie) +
2898 sizeof(struct ieee80211_2040_intol_chan_report) +
2899 num_channels);
2900 if (buf == NULL)
2901 return;
2902
2903 wpabuf_put_u8(buf, WLAN_ACTION_PUBLIC);
2904 wpabuf_put_u8(buf, WLAN_PA_20_40_BSS_COEX);
2905
2906 bc_ie = wpabuf_put(buf, sizeof(*bc_ie));
2907 bc_ie->element_id = WLAN_EID_20_40_BSS_COEXISTENCE;
2908 bc_ie->length = 1;
2909 if (num_intol)
2910 bc_ie->coex_param |= WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ;
2911
2912 if (num_channels > 0) {
2913 ic_report = wpabuf_put(buf, sizeof(*ic_report));
2914 ic_report->element_id = WLAN_EID_20_40_BSS_INTOLERANT;
2915 ic_report->length = num_channels + 1;
2916 ic_report->op_class = 0;
2917 os_memcpy(wpabuf_put(buf, num_channels), chan_list,
2918 num_channels);
2919 }
2920
2921 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
2922 wpa_s->own_addr, wpa_s->bssid,
2923 wpabuf_head(buf), wpabuf_len(buf), 0) < 0) {
2924 wpa_msg(wpa_s, MSG_INFO,
2925 "SME: Failed to send 20/40 BSS Coexistence frame");
2926 }
2927
2928 wpabuf_free(buf);
2929}
2930
2931
2932int sme_proc_obss_scan(struct wpa_supplicant *wpa_s)
2933{
2934 struct wpa_bss *bss;
2935 const u8 *ie;
2936 u16 ht_cap;
2937 u8 chan_list[P2P_MAX_CHANNELS], channel;
2938 u8 num_channels = 0, num_intol = 0, i;
2939
2940 if (!wpa_s->sme.sched_obss_scan)
2941 return 0;
2942
2943 wpa_s->sme.sched_obss_scan = 0;
2944 if (!wpa_s->current_bss || wpa_s->wpa_state != WPA_COMPLETED)
2945 return 1;
2946
2947 /*
2948 * Check whether AP uses regulatory triplet or channel triplet in
2949 * country info. Right now the operating class of the BSS channel
2950 * width trigger event is "unknown" (IEEE Std 802.11-2012 10.15.12),
2951 * based on the assumption that operating class triplet is not used in
2952 * beacon frame. If the First Channel Number/Operating Extension
2953 * Identifier octet has a positive integer value of 201 or greater,
2954 * then its operating class triplet.
2955 *
2956 * TODO: If Supported Operating Classes element is present in beacon
2957 * frame, have to lookup operating class in Annex E and fill them in
2958 * 2040 coex frame.
2959 */
2960 ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_COUNTRY);
2961 if (ie && (ie[1] >= 6) && (ie[5] >= 201))
2962 return 1;
2963
2964 os_memset(chan_list, 0, sizeof(chan_list));
2965
2966 dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
2967 /* Skip other band bss */
2968 enum hostapd_hw_mode mode;
2969 mode = ieee80211_freq_to_chan(bss->freq, &channel);
2970 if (mode != HOSTAPD_MODE_IEEE80211G &&
2971 mode != HOSTAPD_MODE_IEEE80211B)
2972 continue;
2973
2974 ie = wpa_bss_get_ie(bss, WLAN_EID_HT_CAP);
2975 ht_cap = (ie && (ie[1] == 26)) ? WPA_GET_LE16(ie + 2) : 0;
2976 wpa_printf(MSG_DEBUG, "SME OBSS scan BSS " MACSTR
2977 " freq=%u chan=%u ht_cap=0x%x",
2978 MAC2STR(bss->bssid), bss->freq, channel, ht_cap);
2979
2980 if (!ht_cap || (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)) {
2981 if (ht_cap & HT_CAP_INFO_40MHZ_INTOLERANT)
2982 num_intol++;
2983
2984 /* Check whether the channel is already considered */
2985 for (i = 0; i < num_channels; i++) {
2986 if (channel == chan_list[i])
2987 break;
2988 }
2989 if (i != num_channels)
2990 continue;
2991
2992 chan_list[num_channels++] = channel;
2993 }
2994 }
2995
2996 sme_send_2040_bss_coex(wpa_s, chan_list, num_channels, num_intol);
2997 return 1;
2998}
2999
3000
3001static void wpa_obss_scan_freqs_list(struct wpa_supplicant *wpa_s,
3002 struct wpa_driver_scan_params *params)
3003{
3004 /* Include only affected channels */
3005 struct hostapd_hw_modes *mode;
3006 int count, i;
3007 int start, end;
3008
3009 mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
3010 HOSTAPD_MODE_IEEE80211G, false);
3011 if (mode == NULL) {
3012 /* No channels supported in this band - use empty list */
3013 params->freqs = os_zalloc(sizeof(int));
3014 return;
3015 }
3016
3017 if (wpa_s->sme.ht_sec_chan == HT_SEC_CHAN_UNKNOWN &&
3018 wpa_s->current_bss) {
3019 const u8 *ie;
3020
3021 ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_OPERATION);
3022 if (ie && ie[1] >= 2) {
3023 u8 o;
3024
3025 o = ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK;
3026 if (o == HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE)
3027 wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_ABOVE;
3028 else if (o == HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW)
3029 wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_BELOW;
3030 }
3031 }
3032
3033 start = wpa_s->assoc_freq - 10;
3034 end = wpa_s->assoc_freq + 10;
3035 switch (wpa_s->sme.ht_sec_chan) {
3036 case HT_SEC_CHAN_UNKNOWN:
3037 /* HT40+ possible on channels 1..9 */
3038 if (wpa_s->assoc_freq <= 2452)
3039 start -= 20;
3040 /* HT40- possible on channels 5-13 */
3041 if (wpa_s->assoc_freq >= 2432)
3042 end += 20;
3043 break;
3044 case HT_SEC_CHAN_ABOVE:
3045 end += 20;
3046 break;
3047 case HT_SEC_CHAN_BELOW:
3048 start -= 20;
3049 break;
3050 }
3051 wpa_printf(MSG_DEBUG,
3052 "OBSS: assoc_freq %d possible affected range %d-%d",
3053 wpa_s->assoc_freq, start, end);
3054
3055 params->freqs = os_calloc(mode->num_channels + 1, sizeof(int));
3056 if (params->freqs == NULL)
3057 return;
3058 for (count = 0, i = 0; i < mode->num_channels; i++) {
3059 int freq;
3060
3061 if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
3062 continue;
3063 freq = mode->channels[i].freq;
3064 if (freq - 10 >= end || freq + 10 <= start)
3065 continue; /* not affected */
3066 params->freqs[count++] = freq;
3067 }
3068}
3069
3070
3071static void sme_obss_scan_timeout(void *eloop_ctx, void *timeout_ctx)
3072{
3073 struct wpa_supplicant *wpa_s = eloop_ctx;
3074 struct wpa_driver_scan_params params;
3075
3076 if (!wpa_s->current_bss) {
3077 wpa_printf(MSG_DEBUG, "SME OBSS: Ignore scan request");
3078 return;
3079 }
3080
3081 os_memset(&params, 0, sizeof(params));
3082 wpa_obss_scan_freqs_list(wpa_s, &params);
3083 params.low_priority = 1;
3084 wpa_printf(MSG_DEBUG, "SME OBSS: Request an OBSS scan");
3085
3086 if (wpa_supplicant_trigger_scan(wpa_s, &params))
3087 wpa_printf(MSG_DEBUG, "SME OBSS: Failed to trigger scan");
3088 else
3089 wpa_s->sme.sched_obss_scan = 1;
3090 os_free(params.freqs);
3091
3092 eloop_register_timeout(wpa_s->sme.obss_scan_int, 0,
3093 sme_obss_scan_timeout, wpa_s, NULL);
3094}
3095
3096
3097void sme_sched_obss_scan(struct wpa_supplicant *wpa_s, int enable)
3098{
3099 const u8 *ie;
3100 struct wpa_bss *bss = wpa_s->current_bss;
3101 struct wpa_ssid *ssid = wpa_s->current_ssid;
3102 struct hostapd_hw_modes *hw_mode = NULL;
3103 int i;
3104
3105 eloop_cancel_timeout(sme_obss_scan_timeout, wpa_s, NULL);
3106 wpa_s->sme.sched_obss_scan = 0;
3107 wpa_s->sme.ht_sec_chan = HT_SEC_CHAN_UNKNOWN;
3108 if (!enable)
3109 return;
3110
3111 /*
3112 * Schedule OBSS scan if driver is using station SME in wpa_supplicant
3113 * or it expects OBSS scan to be performed by wpa_supplicant.
3114 */
3115 if (!((wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) ||
3116 (wpa_s->drv_flags & WPA_DRIVER_FLAGS_OBSS_SCAN)) ||
3117 ssid == NULL || ssid->mode != WPAS_MODE_INFRA)
3118 return;
3119
3120#ifdef CONFIG_HT_OVERRIDES
3121 /* No need for OBSS scan if HT40 is explicitly disabled */
3122 if (ssid->disable_ht40)
3123 return;
3124#endif /* CONFIG_HT_OVERRIDES */
3125
3126 if (!wpa_s->hw.modes)
3127 return;
3128
3129 /* only HT caps in 11g mode are relevant */
3130 for (i = 0; i < wpa_s->hw.num_modes; i++) {
3131 hw_mode = &wpa_s->hw.modes[i];
3132 if (hw_mode->mode == HOSTAPD_MODE_IEEE80211G)
3133 break;
3134 }
3135
3136 /* Driver does not support HT40 for 11g or doesn't have 11g. */
3137 if (i == wpa_s->hw.num_modes || !hw_mode ||
3138 !(hw_mode->ht_capab & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
3139 return;
3140
3141 if (bss == NULL || bss->freq < 2400 || bss->freq > 2500)
3142 return; /* Not associated on 2.4 GHz band */
3143
3144 /* Check whether AP supports HT40 */
3145 ie = wpa_bss_get_ie(wpa_s->current_bss, WLAN_EID_HT_CAP);
3146 if (!ie || ie[1] < 2 ||
3147 !(WPA_GET_LE16(ie + 2) & HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET))
3148 return; /* AP does not support HT40 */
3149
3150 ie = wpa_bss_get_ie(wpa_s->current_bss,
3151 WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS);
3152 if (!ie || ie[1] < 14)
3153 return; /* AP does not request OBSS scans */
3154
3155 wpa_s->sme.obss_scan_int = WPA_GET_LE16(ie + 6);
3156 if (wpa_s->sme.obss_scan_int < 10) {
3157 wpa_printf(MSG_DEBUG, "SME: Invalid OBSS Scan Interval %u "
3158 "replaced with the minimum 10 sec",
3159 wpa_s->sme.obss_scan_int);
3160 wpa_s->sme.obss_scan_int = 10;
3161 }
3162 wpa_printf(MSG_DEBUG, "SME: OBSS Scan Interval %u sec",
3163 wpa_s->sme.obss_scan_int);
3164 eloop_register_timeout(wpa_s->sme.obss_scan_int, 0,
3165 sme_obss_scan_timeout, wpa_s, NULL);
3166}
3167
3168
3169static const unsigned int sa_query_max_timeout = 1000;
3170static const unsigned int sa_query_retry_timeout = 201;
3171static const unsigned int sa_query_ch_switch_max_delay = 5000; /* in usec */
3172
3173static int sme_check_sa_query_timeout(struct wpa_supplicant *wpa_s)
3174{
3175 u32 tu;
3176 struct os_reltime now, passed;
3177 os_get_reltime(&now);
3178 os_reltime_sub(&now, &wpa_s->sme.sa_query_start, &passed);
3179 tu = (passed.sec * 1000000 + passed.usec) / 1024;
3180 if (sa_query_max_timeout < tu) {
3181 wpa_dbg(wpa_s, MSG_DEBUG, "SME: SA Query timed out");
3182 sme_stop_sa_query(wpa_s);
3183 wpa_supplicant_deauthenticate(
3184 wpa_s, WLAN_REASON_PREV_AUTH_NOT_VALID);
3185 return 1;
3186 }
3187
3188 return 0;
3189}
3190
3191
3192static void sme_send_sa_query_req(struct wpa_supplicant *wpa_s,
3193 const u8 *trans_id)
3194{
3195 u8 req[2 + WLAN_SA_QUERY_TR_ID_LEN + OCV_OCI_EXTENDED_LEN];
3196 u8 req_len = 2 + WLAN_SA_QUERY_TR_ID_LEN;
3197
3198 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Request to "
3199 MACSTR, MAC2STR(wpa_s->bssid));
3200 wpa_hexdump(MSG_DEBUG, "SME: SA Query Transaction ID",
3201 trans_id, WLAN_SA_QUERY_TR_ID_LEN);
3202 req[0] = WLAN_ACTION_SA_QUERY;
3203 req[1] = WLAN_SA_QUERY_REQUEST;
3204 os_memcpy(req + 2, trans_id, WLAN_SA_QUERY_TR_ID_LEN);
3205
3206#ifdef CONFIG_OCV
3207 if (wpa_sm_ocv_enabled(wpa_s->wpa)) {
3208 struct wpa_channel_info ci;
3209
3210 if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
3211 wpa_printf(MSG_WARNING,
3212 "Failed to get channel info for OCI element in SA Query Request frame");
3213 return;
3214 }
3215
3216#ifdef CONFIG_TESTING_OPTIONS
3217 if (wpa_s->oci_freq_override_saquery_req) {
3218 wpa_printf(MSG_INFO,
3219 "TEST: Override SA Query Request OCI frequency %d -> %d MHz",
3220 ci.frequency,
3221 wpa_s->oci_freq_override_saquery_req);
3222 ci.frequency = wpa_s->oci_freq_override_saquery_req;
3223 }
3224#endif /* CONFIG_TESTING_OPTIONS */
3225
3226 if (ocv_insert_extended_oci(&ci, req + req_len) < 0)
3227 return;
3228
3229 req_len += OCV_OCI_EXTENDED_LEN;
3230 }
3231#endif /* CONFIG_OCV */
3232
3233 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
3234 wpa_s->own_addr, wpa_s->bssid,
3235 req, req_len, 0) < 0)
3236 wpa_msg(wpa_s, MSG_INFO, "SME: Failed to send SA Query "
3237 "Request");
3238}
3239
3240
3241static void sme_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
3242{
3243 struct wpa_supplicant *wpa_s = eloop_ctx;
3244 unsigned int timeout, sec, usec;
3245 u8 *trans_id, *nbuf;
3246
3247 if (wpa_s->sme.sa_query_count > 0 &&
3248 sme_check_sa_query_timeout(wpa_s))
3249 return;
3250
3251 nbuf = os_realloc_array(wpa_s->sme.sa_query_trans_id,
3252 wpa_s->sme.sa_query_count + 1,
3253 WLAN_SA_QUERY_TR_ID_LEN);
3254 if (nbuf == NULL) {
3255 sme_stop_sa_query(wpa_s);
3256 return;
3257 }
3258 if (wpa_s->sme.sa_query_count == 0) {
3259 /* Starting a new SA Query procedure */
3260 os_get_reltime(&wpa_s->sme.sa_query_start);
3261 }
3262 trans_id = nbuf + wpa_s->sme.sa_query_count * WLAN_SA_QUERY_TR_ID_LEN;
3263 wpa_s->sme.sa_query_trans_id = nbuf;
3264 wpa_s->sme.sa_query_count++;
3265
3266 if (os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN) < 0) {
3267 wpa_printf(MSG_DEBUG, "Could not generate SA Query ID");
3268 sme_stop_sa_query(wpa_s);
3269 return;
3270 }
3271
3272 timeout = sa_query_retry_timeout;
3273 sec = ((timeout / 1000) * 1024) / 1000;
3274 usec = (timeout % 1000) * 1024;
3275 eloop_register_timeout(sec, usec, sme_sa_query_timer, wpa_s, NULL);
3276
3277 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Association SA Query attempt %d",
3278 wpa_s->sme.sa_query_count);
3279
3280 sme_send_sa_query_req(wpa_s, trans_id);
3281}
3282
3283
3284static void sme_start_sa_query(struct wpa_supplicant *wpa_s)
3285{
3286 sme_sa_query_timer(wpa_s, NULL);
3287}
3288
3289
3290static void sme_stop_sa_query(struct wpa_supplicant *wpa_s)
3291{
3292 if (wpa_s->sme.sa_query_trans_id)
3293 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Stop SA Query");
3294 eloop_cancel_timeout(sme_sa_query_timer, wpa_s, NULL);
3295 os_free(wpa_s->sme.sa_query_trans_id);
3296 wpa_s->sme.sa_query_trans_id = NULL;
3297 wpa_s->sme.sa_query_count = 0;
3298}
3299
3300
3301void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s, const u8 *sa,
3302 const u8 *da, u16 reason_code)
3303{
3304 struct wpa_ssid *ssid;
3305 struct os_reltime now;
3306
3307 if (wpa_s->wpa_state != WPA_COMPLETED)
3308 return;
3309 ssid = wpa_s->current_ssid;
3310 if (wpas_get_ssid_pmf(wpa_s, ssid) == NO_MGMT_FRAME_PROTECTION)
3311 return;
3312 if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0)
3313 return;
3314 if (reason_code != WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA &&
3315 reason_code != WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA)
3316 return;
3317 if (wpa_s->sme.sa_query_count > 0)
3318 return;
3319#ifdef CONFIG_TESTING_OPTIONS
3320 if (wpa_s->disable_sa_query)
3321 return;
3322#endif /* CONFIG_TESTING_OPTIONS */
3323
3324 os_get_reltime(&now);
3325 if (wpa_s->sme.last_unprot_disconnect.sec &&
3326 !os_reltime_expired(&now, &wpa_s->sme.last_unprot_disconnect, 10))
3327 return; /* limit SA Query procedure frequency */
3328 wpa_s->sme.last_unprot_disconnect = now;
3329
3330 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Unprotected disconnect dropped - "
3331 "possible AP/STA state mismatch - trigger SA Query");
3332 sme_start_sa_query(wpa_s);
3333}
3334
3335
3336void sme_event_ch_switch(struct wpa_supplicant *wpa_s)
3337{
3338 unsigned int usec;
3339 u32 _rand;
3340
3341 if (wpa_s->wpa_state != WPA_COMPLETED ||
3342 !wpa_sm_ocv_enabled(wpa_s->wpa))
3343 return;
3344
3345 wpa_dbg(wpa_s, MSG_DEBUG,
3346 "SME: Channel switch completed - trigger new SA Query to verify new operating channel");
3347 sme_stop_sa_query(wpa_s);
3348
3349 if (os_get_random((u8 *) &_rand, sizeof(_rand)) < 0)
3350 _rand = os_random();
3351 usec = _rand % (sa_query_ch_switch_max_delay + 1);
3352 eloop_register_timeout(0, usec, sme_sa_query_timer, wpa_s, NULL);
3353}
3354
3355
3356static void sme_process_sa_query_request(struct wpa_supplicant *wpa_s,
3357 const u8 *sa, const u8 *data,
3358 size_t len)
3359{
3360 u8 resp[2 + WLAN_SA_QUERY_TR_ID_LEN + OCV_OCI_EXTENDED_LEN];
3361 u8 resp_len = 2 + WLAN_SA_QUERY_TR_ID_LEN;
3362
3363 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Sending SA Query Response to "
3364 MACSTR, MAC2STR(wpa_s->bssid));
3365
3366 resp[0] = WLAN_ACTION_SA_QUERY;
3367 resp[1] = WLAN_SA_QUERY_RESPONSE;
3368 os_memcpy(resp + 2, data + 1, WLAN_SA_QUERY_TR_ID_LEN);
3369
3370#ifdef CONFIG_OCV
3371 if (wpa_sm_ocv_enabled(wpa_s->wpa)) {
3372 struct wpa_channel_info ci;
3373
3374 if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
3375 wpa_printf(MSG_WARNING,
3376 "Failed to get channel info for OCI element in SA Query Response frame");
3377 return;
3378 }
3379
3380#ifdef CONFIG_TESTING_OPTIONS
3381 if (wpa_s->oci_freq_override_saquery_resp) {
3382 wpa_printf(MSG_INFO,
3383 "TEST: Override SA Query Response OCI frequency %d -> %d MHz",
3384 ci.frequency,
3385 wpa_s->oci_freq_override_saquery_resp);
3386 ci.frequency = wpa_s->oci_freq_override_saquery_resp;
3387 }
3388#endif /* CONFIG_TESTING_OPTIONS */
3389
3390 if (ocv_insert_extended_oci(&ci, resp + resp_len) < 0)
3391 return;
3392
3393 resp_len += OCV_OCI_EXTENDED_LEN;
3394 }
3395#endif /* CONFIG_OCV */
3396
3397 if (wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
3398 wpa_s->own_addr, wpa_s->bssid,
3399 resp, resp_len, 0) < 0)
3400 wpa_msg(wpa_s, MSG_INFO,
3401 "SME: Failed to send SA Query Response");
3402}
3403
3404
3405static void sme_process_sa_query_response(struct wpa_supplicant *wpa_s,
3406 const u8 *sa, const u8 *data,
3407 size_t len)
3408{
3409 int i;
3410
3411 if (!wpa_s->sme.sa_query_trans_id)
3412 return;
3413
3414 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query response from "
3415 MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]);
3416
3417 if (os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0)
3418 return;
3419
3420 for (i = 0; i < wpa_s->sme.sa_query_count; i++) {
3421 if (os_memcmp(wpa_s->sme.sa_query_trans_id +
3422 i * WLAN_SA_QUERY_TR_ID_LEN,
3423 data + 1, WLAN_SA_QUERY_TR_ID_LEN) == 0)
3424 break;
3425 }
3426
3427 if (i >= wpa_s->sme.sa_query_count) {
3428 wpa_dbg(wpa_s, MSG_DEBUG, "SME: No matching SA Query "
3429 "transaction identifier found");
3430 return;
3431 }
3432
3433 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reply to pending SA Query received "
3434 "from " MACSTR, MAC2STR(sa));
3435 sme_stop_sa_query(wpa_s);
3436}
3437
3438
3439void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *da, const u8 *sa,
3440 const u8 *data, size_t len)
3441{
3442 if (len < 1 + WLAN_SA_QUERY_TR_ID_LEN)
3443 return;
3444 if (is_multicast_ether_addr(da)) {
3445 wpa_printf(MSG_DEBUG,
3446 "IEEE 802.11: Ignore group-addressed SA Query frame (A1=" MACSTR " A2=" MACSTR ")",
3447 MAC2STR(da), MAC2STR(sa));
3448 return;
3449 }
3450
3451 wpa_dbg(wpa_s, MSG_DEBUG, "SME: Received SA Query frame from "
3452 MACSTR " (trans_id %02x%02x)", MAC2STR(sa), data[1], data[2]);
3453
3454#ifdef CONFIG_OCV
3455 if (wpa_sm_ocv_enabled(wpa_s->wpa)) {
3456 struct ieee802_11_elems elems;
3457 struct wpa_channel_info ci;
3458
3459 if (ieee802_11_parse_elems(data + 1 + WLAN_SA_QUERY_TR_ID_LEN,
3460 len - 1 - WLAN_SA_QUERY_TR_ID_LEN,
3461 &elems, 1) == ParseFailed) {
3462 wpa_printf(MSG_DEBUG,
3463 "SA Query: Failed to parse elements");
3464 return;
3465 }
3466
3467 if (wpa_drv_channel_info(wpa_s, &ci) != 0) {
3468 wpa_printf(MSG_WARNING,
3469 "Failed to get channel info to validate received OCI in SA Query Action frame");
3470 return;
3471 }
3472
3473 if (ocv_verify_tx_params(elems.oci, elems.oci_len, &ci,
3474 channel_width_to_int(ci.chanwidth),
3475 ci.seg1_idx) != OCI_SUCCESS) {
3476 wpa_msg(wpa_s, MSG_INFO, OCV_FAILURE "addr=" MACSTR
3477 " frame=saquery%s error=%s",
3478 MAC2STR(sa), data[0] == WLAN_SA_QUERY_REQUEST ?
3479 "req" : "resp", ocv_errorstr);
3480 return;
3481 }
3482 }
3483#endif /* CONFIG_OCV */
3484
3485 if (data[0] == WLAN_SA_QUERY_REQUEST)
3486 sme_process_sa_query_request(wpa_s, sa, data, len);
3487 else if (data[0] == WLAN_SA_QUERY_RESPONSE)
3488 sme_process_sa_query_response(wpa_s, sa, data, len);
3489}