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