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