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