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