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