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