xref: /freebsd/contrib/wpa/wpa_supplicant/pasn_supplicant.c (revision 71e72c9e91c4b8007a4292e09669e8b549c29e97)
1 /*
2  * wpa_supplicant - PASN processing
3  *
4  * Copyright (C) 2019 Intel Corporation
5  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
6  *
7  * This software may be distributed under the terms of the BSD license.
8  * See README for more details.
9  */
10 
11 #include "includes.h"
12 
13 #include "common/ieee802_11_defs.h"
14 #include "common/ieee802_11_common.h"
15 #include "common/dragonfly.h"
16 #include "common/ptksa_cache.h"
17 #include "utils/eloop.h"
18 #include "drivers/driver.h"
19 #include "crypto/crypto.h"
20 #include "crypto/random.h"
21 #include "eap_common/eap_defs.h"
22 #include "rsn_supp/wpa.h"
23 #include "rsn_supp/wpa_ie.h"
24 #include "rsn_supp/pmksa_cache.h"
25 #include "wpa_supplicant_i.h"
26 #include "driver_i.h"
27 #include "bss.h"
28 #include "scan.h"
29 #include "config.h"
30 #include "sme.h"
31 
32 static const int dot11RSNAConfigPMKLifetime = 43200;
33 
34 struct wpa_pasn_auth_work {
35 	u8 own_addr[ETH_ALEN];
36 	u8 peer_addr[ETH_ALEN];
37 	int akmp;
38 	int cipher;
39 	u16 group;
40 	int network_id;
41 	struct wpabuf *comeback;
42 	unsigned int auth_alg;
43 	int group_cipher;
44 	int group_mgmt_cipher;
45 #ifdef CONFIG_ENC_ASSOC
46 	u16 rsn_capab;
47 	u8 *rsnxe_data;
48 	bool is_ml_peer;
49 #endif /* CONFIG_ENC_ASSOC */
50 };
51 
52 
wpas_pasn_free_peer_password(struct pasn_peer * peer)53 static void wpas_pasn_free_peer_password(struct pasn_peer *peer)
54 {
55 	str_clear_free(peer->password);
56 	peer->password = NULL;
57 }
58 
59 
wpas_pasn_free_peer_comeback(struct pasn_peer * peer)60 static void wpas_pasn_free_peer_comeback(struct pasn_peer *peer)
61 {
62 	os_free(peer->comeback);
63 	peer->comeback = NULL;
64 }
65 
66 
wpas_pasn_free_peer(struct pasn_peer * peer)67 static void wpas_pasn_free_peer(struct pasn_peer *peer)
68 {
69 	wpas_pasn_free_peer_password(peer);
70 	wpas_pasn_free_peer_comeback(peer);
71 }
72 
73 
wpas_pasn_send_mlme(void * ctx,const u8 * data,size_t data_len,int noack,unsigned int freq,unsigned int wait)74 static int wpas_pasn_send_mlme(void *ctx, const u8 *data, size_t data_len,
75 			       int noack, unsigned int freq, unsigned int wait)
76 {
77 	struct wpa_supplicant *wpa_s = ctx;
78 
79 	return wpa_drv_send_mlme(wpa_s, data, data_len, noack, freq, wait);
80 }
81 
82 
wpas_pasn_free_auth_work(struct wpa_pasn_auth_work * awork)83 static void wpas_pasn_free_auth_work(struct wpa_pasn_auth_work *awork)
84 {
85 	wpabuf_free(awork->comeback);
86 	awork->comeback = NULL;
87 #ifdef CONFIG_ENC_ASSOC
88 	os_free(awork->rsnxe_data);
89 	awork->rsnxe_data = NULL;
90 #endif /* CONFIG_ENC_ASSOC */
91 	os_free(awork);
92 }
93 
94 
wpas_pasn_auth_work_timeout(void * eloop_ctx,void * timeout_ctx)95 static void wpas_pasn_auth_work_timeout(void *eloop_ctx, void *timeout_ctx)
96 {
97 	struct wpa_supplicant *wpa_s = eloop_ctx;
98 
99 	wpa_printf(MSG_DEBUG, "PASN: Auth work timeout - stopping auth");
100 
101 	wpas_pasn_auth_stop(wpa_s);
102 
103 	wpas_pasn_auth_work_done(wpa_s, PASN_STATUS_FAILURE);
104 }
105 
106 
wpas_pasn_cancel_auth_work(struct wpa_supplicant * wpa_s)107 static void wpas_pasn_cancel_auth_work(struct wpa_supplicant *wpa_s)
108 {
109 	wpa_printf(MSG_DEBUG, "PASN: Cancel pasn-start-auth work");
110 
111 	/* Remove pending/started work */
112 	radio_remove_works(wpa_s, "pasn-start-auth", 0);
113 }
114 
115 
wpas_pasn_auth_status(struct wpa_supplicant * wpa_s,const u8 * peer_addr,int akmp,int cipher,u8 status,struct wpabuf * comeback,u16 comeback_after)116 static void wpas_pasn_auth_status(struct wpa_supplicant *wpa_s,
117 				  const u8 *peer_addr,
118 				  int akmp, int cipher, u8 status,
119 				  struct wpabuf *comeback,
120 				  u16 comeback_after)
121 {
122 	if (comeback) {
123 		size_t comeback_len = wpabuf_len(comeback);
124 		size_t buflen = comeback_len * 2 + 1;
125 		char *comeback_txt = os_malloc(buflen);
126 
127 		if (comeback_txt) {
128 			wpa_snprintf_hex(comeback_txt, buflen,
129 					 wpabuf_head(comeback), comeback_len);
130 
131 			wpa_msg(wpa_s, MSG_INFO, PASN_AUTH_STATUS MACSTR
132 				" akmp=%s, status=%u comeback_after=%u comeback=%s",
133 				MAC2STR(peer_addr),
134 				wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
135 				status, comeback_after, comeback_txt);
136 
137 			os_free(comeback_txt);
138 			return;
139 		}
140 	}
141 
142 	wpa_msg(wpa_s, MSG_INFO,
143 		PASN_AUTH_STATUS MACSTR " akmp=%s, status=%u",
144 		MAC2STR(peer_addr), wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
145 		status);
146 }
147 
148 
149 #ifdef CONFIG_SAE
150 
151 static struct sae_pt *
wpas_pasn_sae_derive_pt(struct wpa_ssid * ssid,int group)152 wpas_pasn_sae_derive_pt(struct wpa_ssid *ssid, int group)
153 {
154 	const char *password = ssid->sae_password;
155 	int groups[2] = { group, 0 };
156 
157 	if (!password)
158 		password = ssid->passphrase;
159 
160 	if (!password) {
161 		wpa_printf(MSG_DEBUG, "PASN: SAE without a password");
162 		return NULL;
163 	}
164 
165 	return sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
166 			     (const u8 *) password, os_strlen(password),
167 			     (const u8 *) ssid->sae_password_id,
168 			     ssid->sae_password_id ?
169 			     os_strlen(ssid->sae_password_id) : 0);
170 }
171 
172 
173 #ifdef CONFIG_ENC_ASSOC
174 struct sae_pt *
wpas_pasn_sae_derive_pt_for_eppke(struct wpa_ssid * ssid,int group)175 wpas_pasn_sae_derive_pt_for_eppke(struct wpa_ssid *ssid, int group)
176 {
177 	const char *password = ssid->sae_password;
178 	int groups[2] = { group, 0 };
179 	const u8 *password_id = NULL;
180 	size_t password_id_len = 0;
181 
182 	if (!password)
183 		password = ssid->passphrase;
184 
185 	if (!password) {
186 		wpa_printf(MSG_DEBUG, "EPPKE: SAE without a password");
187 		return NULL;
188 	}
189 
190 	/* Prefer an alternative (changing) password identifier if available */
191 	if (ssid->alt_sae_password_ids && ssid->alt_sae_password_ids->num) {
192 		unsigned int idx =
193 			os_random() % ssid->alt_sae_password_ids->num;
194 		struct wpabuf *id = ssid->alt_sae_password_ids->buf[idx];
195 
196 		password_id = wpabuf_head(id);
197 		password_id_len = wpabuf_len(id);
198 		wpa_hexdump(MSG_DEBUG,
199 			    "EPPKE: Prepare PT for alternative password ID",
200 			    password_id, password_id_len);
201 		ssid->alt_sae_passwords_ids_idx = idx;
202 		ssid->alt_sae_passwords_ids_used = true;
203 	} else if (ssid->sae_password_id) {
204 		password_id = (const u8 *) ssid->sae_password_id;
205 		password_id_len = os_strlen(ssid->sae_password_id);
206 	}
207 
208 	return sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
209 			     (const u8 *) password, os_strlen(password),
210 			     password_id, password_id_len);
211 }
212 #endif /* CONFIG_ENC_ASSOC */
213 
214 
wpas_pasn_sae_setup_pt(struct wpa_ssid * ssid,int group)215 static int wpas_pasn_sae_setup_pt(struct wpa_ssid *ssid, int group)
216 {
217 	if (!ssid->sae_password && !ssid->passphrase) {
218 		wpa_printf(MSG_DEBUG, "PASN: SAE without a password");
219 		return -1;
220 	}
221 
222 	if (ssid->pt)
223 		return 0; /* PT already derived */
224 
225 	ssid->pt = wpas_pasn_sae_derive_pt(ssid, group);
226 
227 	return ssid->pt ? 0 : -1;
228 }
229 
230 #endif /* CONFIG_SAE */
231 
232 
wpas_pasn_get_group(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid,struct pasn_data * pasn)233 int wpas_pasn_get_group(struct wpa_supplicant *wpa_s,
234 			struct wpa_ssid *ssid, struct pasn_data *pasn)
235 {
236 	static const int default_groups[] = { 19, 20, 21, 0 };
237 	const int *groups;
238 	unsigned int i, j;
239 
240 	if (ssid && ssid->pasn_groups)
241 		groups = ssid->pasn_groups;
242 	else if (wpa_s->conf->pasn_groups)
243 		groups = wpa_s->conf->pasn_groups;
244 	else
245 		groups = default_groups;
246 
247 	for (i = 0; groups[i]; i++) {
248 		bool rejected = false;
249 		bool ap_supported = true;
250 
251 		if (!dragonfly_suitable_group(groups[i], 1))
252 			continue;
253 
254 		if (!pasn)
255 			return groups[i];
256 
257 		/* Skip groups already rejected in this session */
258 		for (j = 0; j < pasn->rejected_group_idx; j++) {
259 			if (groups[i] == pasn->rejected_groups[j]) {
260 				rejected = true;
261 				break;
262 			}
263 		}
264 		if (rejected)
265 			continue;
266 
267 		/* Take intersection with AP's supported groups */
268 		if (pasn->ap_supported_group_idx > 0) {
269 			ap_supported = false;
270 			for (j = 0; j < pasn->ap_supported_group_idx; j++) {
271 				if (groups[i] == pasn->ap_supported_groups[j]) {
272 					ap_supported = true;
273 					break;
274 				}
275 			}
276 		}
277 		if (ap_supported)
278 			return groups[i];
279 	}
280 
281 	/* pasn_groups configured but no suitable group found - failure */
282 	return 0;
283 }
284 
285 
wpas_pasn_get_params_from_bss(struct wpa_supplicant * wpa_s,struct pasn_peer * peer,struct wpa_bss * bss,struct wpa_ssid * ssid)286 static int wpas_pasn_get_params_from_bss(struct wpa_supplicant *wpa_s,
287 					 struct pasn_peer *peer,
288 					 struct wpa_bss *bss,
289 					 struct wpa_ssid *ssid)
290 {
291 	int ret;
292 	const u8 *rsne, *rsnxe;
293 	struct wpa_ie_data rsne_data;
294 	int sel, key_mgmt, pairwise_cipher;
295 	int group;
296 
297 	group = wpas_pasn_get_group(wpa_s, ssid, NULL);
298 
299 	if (!group) {
300 		wpa_printf(MSG_INFO,
301 			   "PASN: No suitable group found; cannot start authentication");
302 		return -1;
303 	}
304 
305 	wpa_printf(MSG_DEBUG, "PASN: Selected group %d", group);
306 
307 	rsne = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
308 	if (!rsne) {
309 		wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
310 		return -1;
311 	}
312 
313 	ret = wpa_parse_wpa_ie(rsne, *(rsne + 1) + 2, &rsne_data);
314 	if (ret) {
315 		wpa_printf(MSG_DEBUG, "PASN: Failed parsing RSNE data");
316 		return -1;
317 	}
318 
319 	rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
320 
321 
322 	sel = rsne_data.pairwise_cipher;
323 	if (peer->cipher && peer->cipher != WPA_CIPHER_NONE)
324 		sel &= peer->cipher;
325 	else if (ssid && !ssid->temporary && ssid->pairwise_cipher)
326 		sel &= ssid->pairwise_cipher;
327 
328 	wpa_printf(MSG_DEBUG, "PASN: peer pairwise 0x%x, select 0x%x",
329 		   rsne_data.pairwise_cipher, sel);
330 
331 	pairwise_cipher = wpa_pick_pairwise_cipher(sel, 1);
332 	if (pairwise_cipher < 0) {
333 		wpa_msg(wpa_s, MSG_WARNING,
334 			"PASN: Failed to select pairwise cipher");
335 		return -1;
336 	}
337 
338 	sel = rsne_data.key_mgmt;
339 	if (peer->akmp && peer->akmp != WPA_KEY_MGMT_NONE)
340 		sel &= peer->akmp;
341 	else if (ssid && !ssid->temporary && ssid->key_mgmt)
342 		sel &= ssid->key_mgmt;
343 
344 	wpa_printf(MSG_DEBUG, "PASN: peer AKMP 0x%x, select 0x%x",
345 		   rsne_data.key_mgmt, sel);
346 #ifdef CONFIG_SAE
347 	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) || !ssid)
348 		sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_SAE_EXT_KEY |
349 			 WPA_KEY_MGMT_FT_SAE | WPA_KEY_MGMT_FT_SAE_EXT_KEY);
350 #endif /* CONFIG_SAE */
351 #ifdef CONFIG_IEEE80211R
352 	if (!(wpa_s->drv_flags & (WPA_DRIVER_FLAGS_SME |
353 				  WPA_DRIVER_FLAGS_UPDATE_FT_IES)))
354 		sel &= ~WPA_KEY_MGMT_FT;
355 #endif /* CONFIG_IEEE80211R */
356 	if (0) {
357 #ifdef CONFIG_IEEE80211R
358 #ifdef CONFIG_SHA384
359 	} else if ((sel & WPA_KEY_MGMT_FT_IEEE8021X_SHA384) &&
360 		   os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0) {
361 		key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X_SHA384;
362 		wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT FT/802.1X-SHA384");
363 		if (ssid && !ssid->ft_eap_pmksa_caching &&
364 		    pmksa_cache_get_current(wpa_s->wpa)) {
365 			/* PMKSA caching with FT may have interoperability
366 			 * issues, so disable that case by default for now.
367 			 */
368 			wpa_printf(MSG_DEBUG,
369 				   "PASN: Disable PMKSA caching for FT/802.1X connection");
370 			pmksa_cache_clear_current(wpa_s->wpa);
371 		}
372 #endif /* CONFIG_SHA384 */
373 #endif /* CONFIG_IEEE80211R */
374 #ifdef CONFIG_SAE
375 	} else if ((sel & WPA_KEY_MGMT_SAE_EXT_KEY) && ssid &&
376 		   (ieee802_11_rsnx_capab(rsnxe,
377 					   WLAN_RSNX_CAPAB_SAE_H2E)) &&
378 		   (wpas_pasn_sae_setup_pt(ssid, group) == 0)) {
379 		key_mgmt = WPA_KEY_MGMT_SAE_EXT_KEY;
380 		wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT SAE (ext key)");
381 	} else if ((sel & WPA_KEY_MGMT_SAE) && ssid &&
382 		   (ieee802_11_rsnx_capab(rsnxe,
383 					   WLAN_RSNX_CAPAB_SAE_H2E)) &&
384 		   (wpas_pasn_sae_setup_pt(ssid, group) == 0)) {
385 		key_mgmt = WPA_KEY_MGMT_SAE;
386 		wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT SAE");
387 #endif /* CONFIG_SAE */
388 #ifdef CONFIG_FILS
389 	} else if (sel & WPA_KEY_MGMT_FILS_SHA384) {
390 		key_mgmt = WPA_KEY_MGMT_FILS_SHA384;
391 		wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT FILS-SHA384");
392 	} else if (sel & WPA_KEY_MGMT_FILS_SHA256) {
393 		key_mgmt = WPA_KEY_MGMT_FILS_SHA256;
394 		wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT FILS-SHA256");
395 #endif /* CONFIG_FILS */
396 #ifdef CONFIG_IEEE80211R
397 	} else if ((sel & WPA_KEY_MGMT_FT_IEEE8021X) &&
398 		   os_strcmp(wpa_supplicant_get_eap_mode(wpa_s), "LEAP") != 0) {
399 		key_mgmt = WPA_KEY_MGMT_FT_IEEE8021X;
400 		wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT FT/802.1X");
401 		if (ssid && !ssid->ft_eap_pmksa_caching &&
402 		    pmksa_cache_get_current(wpa_s->wpa)) {
403 			/* PMKSA caching with FT may have interoperability
404 			 * issues, so disable that case by default for now.
405 			 */
406 			wpa_printf(MSG_DEBUG,
407 				   "PASN: Disable PMKSA caching for FT/802.1X connection");
408 			pmksa_cache_clear_current(wpa_s->wpa);
409 		}
410 	} else if (sel & WPA_KEY_MGMT_FT_PSK) {
411 		key_mgmt = WPA_KEY_MGMT_FT_PSK;
412 		wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT FT/PSK");
413 #endif /* CONFIG_IEEE80211R */
414 	} else if (sel & WPA_KEY_MGMT_PASN) {
415 		key_mgmt = WPA_KEY_MGMT_PASN;
416 		wpa_printf(MSG_DEBUG, "PASN: using KEY_MGMT PASN");
417 	} else {
418 		wpa_printf(MSG_DEBUG, "PASN: invalid AKMP");
419 		return -1;
420 	}
421 
422 	peer->akmp = key_mgmt;
423 	peer->cipher = pairwise_cipher;
424 	if (ssid)
425 		peer->network_id = ssid->id;
426 	peer->group = group;
427 	return 0;
428 }
429 
430 
wpas_pasn_set_keys_from_cache(struct wpa_supplicant * wpa_s,const u8 * own_addr,const u8 * peer_addr,int cipher,int akmp)431 static int wpas_pasn_set_keys_from_cache(struct wpa_supplicant *wpa_s,
432 					 const u8 *own_addr,
433 					 const u8 *peer_addr,
434 					 int cipher, int akmp)
435 {
436 	struct ptksa_cache_entry *entry;
437 
438 	entry = ptksa_cache_get(wpa_s->ptksa, peer_addr, cipher);
439 	if (!entry) {
440 		wpa_printf(MSG_DEBUG, "PASN: peer " MACSTR
441 			   " not present in PTKSA cache", MAC2STR(peer_addr));
442 		return -1;
443 	}
444 
445 	if (!ether_addr_equal(entry->own_addr, own_addr)) {
446 		wpa_printf(MSG_DEBUG,
447 			   "PASN: own addr " MACSTR " and PTKSA entry own addr "
448 			   MACSTR " differ",
449 			   MAC2STR(own_addr), MAC2STR(entry->own_addr));
450 		return -1;
451 	}
452 
453 	wpa_printf(MSG_DEBUG, "PASN: " MACSTR " present in PTKSA cache",
454 		   MAC2STR(peer_addr));
455 	wpa_drv_set_secure_ranging_ctx(wpa_s, own_addr, peer_addr, cipher,
456 				       entry->ptk.tk_len,
457 				       entry->ptk.tk,
458 				       entry->ptk.ltf_keyseed_len,
459 				       entry->ptk.ltf_keyseed, 0);
460 	return 0;
461 }
462 
463 
464 static struct wpa_ssid *
wpas_pasn_add_temporary_network(struct wpa_supplicant * wpa_s,const struct wpa_bss * bss,const char * password)465 wpas_pasn_add_temporary_network(struct wpa_supplicant *wpa_s,
466 				const struct wpa_bss *bss, const char *password)
467 {
468 	struct wpa_ssid *ssid;
469 
470 	ssid = wpa_config_add_network(wpa_s->conf);
471 	if (!ssid) {
472 		wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SSID block");
473 		return NULL;
474 	}
475 
476 	ssid->ssid = os_memdup(bss->ssid, bss->ssid_len);
477 	if (!ssid->ssid)
478 		return NULL;
479 
480 	ssid->ssid_len = bss->ssid_len;
481 	ssid->passphrase = os_strdup(password);
482 	if (!ssid->passphrase) {
483 		wpa_config_free_ssid(ssid);
484 		wpa_printf(MSG_DEBUG, "PASN: Failed to copy password");
485 		return NULL;
486 	}
487 
488 	ssid->temporary = true;
489 	wpa_printf(MSG_DEBUG, "PASN: Created temporary network block for "
490 		   MACSTR, MAC2STR(bss->bssid));
491 
492 	return ssid;
493 }
494 
495 
wpas_pasn_get_bss(struct wpa_supplicant * wpa_s,const u8 * peer_addr)496 static struct wpa_bss * wpas_pasn_get_bss(struct wpa_supplicant *wpa_s,
497 					  const u8 *peer_addr)
498 {
499 	struct wpa_bss *bss;
500 
501 	bss = wpa_bss_get_bssid(wpa_s, peer_addr);
502 	if (!bss) {
503 		wpa_supplicant_update_scan_results(wpa_s, peer_addr);
504 		bss = wpa_bss_get_bssid(wpa_s, peer_addr);
505 	}
506 
507 	return bss;
508 }
509 
510 
wpas_pasn_get_network(struct wpa_supplicant * wpa_s,struct wpa_bss * bss)511 static struct wpa_ssid * wpas_pasn_get_network(struct wpa_supplicant *wpa_s,
512 					       struct wpa_bss *bss)
513 {
514 	size_t ssid_str_len;
515 	const u8 *ssid_str;
516 	struct wpa_ssid *ssid;
517 
518 	ssid_str_len = bss->ssid_len;
519 	ssid_str = bss->ssid;
520 
521 	/* Get the network configuration based on the obtained SSID */
522 	for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) {
523 		if (ssid_str_len == ssid->ssid_len &&
524 		    os_memcmp(ssid_str, ssid->ssid, ssid_str_len) == 0)
525 			break;
526 	}
527 
528 	return ssid;
529 }
530 
531 
wpas_pasn_configure_next_peer(struct wpa_supplicant * wpa_s,struct pasn_auth * pasn_params)532 static void wpas_pasn_configure_next_peer(struct wpa_supplicant *wpa_s,
533 					  struct pasn_auth *pasn_params)
534 {
535 	struct pasn_peer *peer;
536 	struct wpa_ssid *ssid;
537 
538 	if (!pasn_params)
539 		return;
540 
541 	while (wpa_s->pasn_count < pasn_params->num_peers) {
542 		struct wpa_bss *bss;
543 		bool check_cache = true;
544 
545 		peer = &pasn_params->peer[wpa_s->pasn_count];
546 
547 		if (ether_addr_equal(wpa_s->bssid, peer->peer_addr)) {
548 			wpa_printf(MSG_DEBUG,
549 				   "PASN: Associated peer is not expected");
550 			peer->status = PASN_STATUS_FAILURE;
551 			wpa_s->pasn_count++;
552 			continue;
553 		}
554 
555 		bss = wpas_pasn_get_bss(wpa_s, peer->peer_addr);
556 		if (!bss) {
557 			wpa_printf(MSG_DEBUG, "PASN: BSS not found");
558 			peer->status = PASN_STATUS_FAILURE;
559 			wpa_s->pasn_count++;
560 			continue;
561 		}
562 
563 		ssid = wpas_pasn_get_network(wpa_s, bss);
564 		if (peer->password && peer->akmp &&
565 		    peer->akmp != WPA_KEY_MGMT_NONE) {
566 			ssid = wpas_pasn_add_temporary_network(wpa_s, bss,
567 							       peer->password);
568 
569 			if (!ssid) {
570 				wpa_printf(MSG_DEBUG,
571 					   "PASN: Failed to create temporary network");
572 				return;
573 			}
574 			peer->temporary_network = true;
575 		}
576 
577 		if (ssid && ssid->temporary)
578 			check_cache = false;
579 
580 		if (wpas_pasn_get_params_from_bss(wpa_s, peer, bss, ssid)) {
581 			peer->status = PASN_STATUS_FAILURE;
582 			wpa_s->pasn_count++;
583 			continue;
584 		}
585 
586 		if (check_cache &&
587 		    wpas_pasn_set_keys_from_cache(wpa_s, peer->own_addr,
588 						  peer->peer_addr,
589 						  peer->cipher,
590 						  peer->akmp) == 0) {
591 			peer->status = PASN_STATUS_SUCCESS;
592 			wpa_s->pasn_count++;
593 			continue;
594 		}
595 
596 		if (wpas_pasn_auth_start(wpa_s, peer->own_addr,
597 					 peer->peer_addr, peer->akmp,
598 					 peer->cipher, peer->group,
599 					 peer->network_id,
600 					 peer->comeback, peer->comeback_len,
601 					 WLAN_AUTH_PASN, 0, 0, 0, NULL,
602 					 false)) {
603 			peer->status = PASN_STATUS_FAILURE;
604 			wpa_msg(wpa_s, MSG_INFO, PASN_AUTH_STATUS MACSTR
605 				" akmp=%s, status=%u",
606 				MAC2STR(peer->peer_addr),
607 				wpa_key_mgmt_txt(peer->akmp, WPA_PROTO_RSN),
608 				peer->status);
609 			wpa_s->pasn_count++;
610 			wpas_pasn_free_peer(peer);
611 			continue;
612 		}
613 		wpa_printf(MSG_DEBUG, "PASN: Sent PASN auth start for " MACSTR,
614 			   MAC2STR(peer->peer_addr));
615 		return;
616 	}
617 
618 	if (wpa_s->pasn_count == pasn_params->num_peers) {
619 		unsigned int i;
620 
621 		wpa_drv_send_pasn_resp(wpa_s, pasn_params);
622 		wpa_printf(MSG_DEBUG, "PASN: Response sent");
623 		for (i = 0; i < pasn_params->num_peers; i++) {
624 			peer = &pasn_params->peer[i];
625 			wpas_pasn_free_peer(peer);
626 
627 			if (peer->temporary_network) {
628 				ssid = wpa_config_get_network(wpa_s->conf,
629 							      peer->network_id);
630 
631 				if (ssid && ssid->temporary) {
632 					wpa_config_remove_network(
633 						wpa_s->conf, peer->network_id);
634 					wpa_printf(MSG_DEBUG,
635 						   "PASN: Remove temporary network block of "
636 						   MACSTR, MAC2STR(peer->peer_addr));
637 				}
638 			}
639 		}
640 		os_free(wpa_s->pasn_params);
641 		wpa_s->pasn_params = NULL;
642 	}
643 }
644 
645 
wpas_pasn_auth_work_done(struct wpa_supplicant * wpa_s,int status)646 void wpas_pasn_auth_work_done(struct wpa_supplicant *wpa_s, int status)
647 {
648 	if (!wpa_s->pasn_params)
649 		return;
650 
651 	wpa_s->pasn_params->peer[wpa_s->pasn_count].status = status;
652 	wpa_s->pasn_count++;
653 	wpas_pasn_configure_next_peer(wpa_s, wpa_s->pasn_params);
654 }
655 
656 
wpas_pasn_delete_peers(struct wpa_supplicant * wpa_s,struct pasn_auth * pasn_params)657 static void wpas_pasn_delete_peers(struct wpa_supplicant *wpa_s,
658 				   struct pasn_auth *pasn_params)
659 {
660 	struct pasn_peer *peer;
661 	unsigned int i;
662 
663 	if (!pasn_params)
664 		return;
665 
666 	for (i = 0; i < pasn_params->num_peers; i++) {
667 		peer = &pasn_params->peer[i];
668 		ptksa_cache_flush(wpa_s->ptksa, peer->peer_addr,
669 				  WPA_CIPHER_NONE);
670 		wpas_pasn_free_peer_password(peer);
671 	}
672 }
673 
674 
675 #ifdef CONFIG_FILS
wpas_pasn_initiate_eapol(struct pasn_data * pasn,struct wpa_ssid * ssid)676 static void wpas_pasn_initiate_eapol(struct pasn_data *pasn,
677 				     struct wpa_ssid *ssid)
678 {
679 	struct eapol_config eapol_conf;
680 
681 	wpa_printf(MSG_DEBUG, "PASN: FILS: Initiating EAPOL");
682 
683 	eapol_sm_notify_eap_success(pasn->eapol, false);
684 	eapol_sm_notify_eap_fail(pasn->eapol, false);
685 	eapol_sm_notify_portControl(pasn->eapol, Auto);
686 
687 	os_memset(&eapol_conf, 0, sizeof(eapol_conf));
688 	eapol_conf.fast_reauth = pasn->fast_reauth;
689 	eapol_conf.workaround = ssid->eap_workaround;
690 
691 	eapol_sm_notify_config(pasn->eapol, &ssid->eap, &eapol_conf);
692 }
693 #endif /* CONFIG_FILS */
694 
695 
wpas_pasn_reset(struct wpa_supplicant * wpa_s)696 static void wpas_pasn_reset(struct wpa_supplicant *wpa_s)
697 {
698 	struct pasn_data *pasn = &wpa_s->pasn;
699 
700 	wpas_pasn_cancel_auth_work(wpa_s);
701 	wpa_s->pasn_auth_work = NULL;
702 	eloop_cancel_timeout(wpas_pasn_auth_work_timeout, wpa_s, NULL);
703 
704 	wpa_pasn_reset(pasn);
705 }
706 
707 
wpas_pasn_allowed(struct wpa_supplicant * wpa_s,const u8 * peer_addr,int akmp,int cipher,int auth_alg,int group_cipher,int group_mgmt_cipher)708 static struct wpa_bss * wpas_pasn_allowed(struct wpa_supplicant *wpa_s,
709 					  const u8 *peer_addr, int akmp,
710 					  int cipher, int auth_alg,
711 					  int group_cipher,
712 					  int group_mgmt_cipher)
713 {
714 	struct wpa_bss *bss;
715 	const u8 *rsne;
716 	struct wpa_ie_data rsne_data;
717 	int ret;
718 
719 	if (auth_alg != WLAN_AUTH_EPPKE &&
720 	    ether_addr_equal(wpa_s->bssid, peer_addr)) {
721 		wpa_printf(MSG_DEBUG,
722 			   "PASN: Not doing authentication with current BSS");
723 		return NULL;
724 	}
725 
726 	if (auth_alg == WLAN_AUTH_EPPKE) {
727 #if defined(CONFIG_SME) && defined(CONFIG_SAE)
728 		/* EPPKE processing can reach here only when external
729 		 * authentication is used.
730 		 *
731 		 * In this flow, peer_addr is the peer MLD address for MLO.
732 		 * However, wpa_bss_get_bssid_latest() matches a link BSSID
733 		 * entry in the BSS table. Use the link BSSID saved by SME
734 		 * in ext_auth_bssid for BSS lookup.
735 		 */
736 		bss = wpa_bss_get_bssid_latest(wpa_s,
737 					       wpa_s->sme.ext_auth_bssid);
738 #else /* CONFIG_SME && CONFIG_SAE */
739 		wpa_printf(MSG_ERROR,
740 			   "EPPKE ext-auth requires CONFIG_SME and CONFIG_SAE");
741 		return NULL;
742 #endif /* CONFIG_SME && CONFIG_SAE */
743 	} else {
744 		bss = wpa_bss_get_bssid_latest(wpa_s, peer_addr);
745 	}
746 	if (!bss) {
747 		wpa_printf(MSG_DEBUG, "PASN: BSS not found");
748 		return NULL;
749 	}
750 
751 	rsne = wpa_bss_get_rsne(wpa_s, bss, NULL, false);
752 	if (!rsne) {
753 		wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
754 		return NULL;
755 	}
756 
757 	ret = wpa_parse_wpa_ie(rsne, *(rsne + 1) + 2, &rsne_data);
758 	if (ret) {
759 		wpa_printf(MSG_DEBUG, "PASN: Failed parsing RSNE data");
760 		return NULL;
761 	}
762 
763 	if (!(rsne_data.key_mgmt & akmp) ||
764 	    !(rsne_data.pairwise_cipher & cipher)) {
765 		wpa_printf(MSG_DEBUG,
766 			   "PASN: AP does not support requested AKMP or cipher");
767 		return NULL;
768 	}
769 
770 #ifdef CONFIG_ENC_ASSOC
771 	if (auth_alg == WLAN_AUTH_EPPKE) {
772 		if (group_cipher &
773 		    !(rsne_data.group_cipher & group_cipher)) {
774 			wpa_printf(MSG_DEBUG,
775 				   "EPPKE: AP does not support requested group cipher");
776 			return NULL;
777 		}
778 		if (group_mgmt_cipher &&
779 		    !(rsne_data.mgmt_group_cipher & group_mgmt_cipher)) {
780 			wpa_printf(MSG_DEBUG,
781 				   "EPPKE: AP does not support requested group mgmt cipher");
782 			return NULL;
783 		}
784 	}
785 #endif /* CONFIG_ENC_ASSOC */
786 
787 	return bss;
788 }
789 
790 
791 #ifdef CONFIG_ENC_ASSOC
792 /*
793  * Build RSNE for EPPKE in SME-in-driver mode.
794  */
wpas_eppke_set_rsne(struct wpa_supplicant * wpa_s,struct pasn_data * pasn,struct wpa_pasn_auth_work * awork)795 static int wpas_eppke_set_rsne(struct wpa_supplicant *wpa_s,
796 			       struct pasn_data *pasn,
797 			       struct wpa_pasn_auth_work *awork)
798 {
799 	u8 rsne[257];
800 	int rsne_len;
801 
802 	rsne_len = wpa_external_auth_add_rsne(rsne, sizeof(rsne),
803 					      awork->akmp, awork->cipher,
804 					      awork->group_cipher,
805 					      awork->group_mgmt_cipher,
806 					      awork->rsn_capab,
807 					      sme_get_ext_auth_pmkid(wpa_s));
808 	if (rsne_len < 0) {
809 		wpa_printf(MSG_DEBUG, "EPPKE: Failed to build RSNE");
810 		return -1;
811 	}
812 
813 	pasn_set_rsne(pasn, rsne);
814 	if (!pasn->rsn_ie)
815 		return -1;
816 
817 	wpa_printf(MSG_DEBUG,
818 		   "EPPKE: RSNE for ext-auth (group=0x%x mgmt=0x%x capab=0x%x)",
819 		   awork->group_cipher, awork->group_mgmt_cipher,
820 		   awork->rsn_capab);
821 	return 0;
822 }
823 #endif /* CONFIG_ENC_ASSOC */
824 
825 
wpas_pasn_auth_start_cb(struct wpa_radio_work * work,int deinit)826 static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit)
827 {
828 	struct wpa_supplicant *wpa_s = work->wpa_s;
829 	struct wpa_pasn_auth_work *awork = work->ctx;
830 	struct pasn_data *pasn = &wpa_s->pasn;
831 	struct wpa_ssid *ssid;
832 	struct wpa_bss *bss;
833 	const u8 *rsne, *rsnxe;
834 #ifdef CONFIG_FILS
835 	const u8 *indic;
836 	u16 fils_info;
837 #endif /* CONFIG_FILS */
838 	u64 capab = 0;
839 	bool derive_kdk;
840 	int ret;
841 
842 	wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: deinit=%d", deinit);
843 
844 	if (deinit) {
845 		if (work->started) {
846 			eloop_cancel_timeout(wpas_pasn_auth_work_timeout,
847 					     wpa_s, NULL);
848 			wpa_s->pasn_auth_work = NULL;
849 		}
850 
851 		wpas_pasn_free_auth_work(awork);
852 		return;
853 	}
854 
855 	/*
856 	 * It is possible that by the time the callback is called, the PASN
857 	 * authentication is not allowed, e.g., a connection with the AP was
858 	 * established.
859 	 */
860 	bss = wpas_pasn_allowed(wpa_s, awork->peer_addr, awork->akmp,
861 				awork->cipher, awork->auth_alg,
862 				awork->group_cipher,
863 				awork->group_mgmt_cipher);
864 	if (!bss) {
865 		wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: Not allowed");
866 		goto fail;
867 	}
868 
869 	rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
870 	if (!rsne) {
871 		wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
872 		goto fail;
873 	}
874 
875 	/* Use the RSNXOE, if it was included, for actual AP capability check */
876 	rsnxe = wpa_bss_get_rsnxe(wpa_s, bss, NULL, false);
877 
878 	derive_kdk = (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA) &&
879 		ieee802_11_rsnx_capab(rsnxe,
880 				      WLAN_RSNX_CAPAB_SECURE_LTF);
881 #ifdef CONFIG_TESTING_OPTIONS
882 	if (!derive_kdk)
883 		derive_kdk = wpa_s->conf->force_kdk_derivation;
884 #endif /* CONFIG_TESTING_OPTIONS */
885 	if (derive_kdk)
886 		pasn_enable_kdk_derivation(pasn);
887 	else
888 		pasn_disable_kdk_derivation(pasn);
889 
890 	wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", pasn->kdk_len);
891 
892 	if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA) &&
893 	    ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF))
894 		pasn->secure_ltf = true;
895 	else
896 		pasn->secure_ltf = false;
897 
898 #ifdef CONFIG_TESTING_OPTIONS
899 	pasn->corrupt_mic = wpa_s->conf->pasn_corrupt_mic;
900 #endif /* CONFIG_TESTING_OPTIONS */
901 
902 	if (wpa_key_mgmt_sae(awork->akmp))
903 		capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
904 	if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF_STA)
905 		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
906 	if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT_STA)
907 		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
908 	if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG_STA) {
909 		/*
910 		 * URNM_MFPR_X20 is a subset of URNM_MFPR which excludes 20 MHz
911 		 * bandwidth from mandating protected Management frames. Set
912 		 * URNM_MFPR only when URNM_MFPR_X20 is not set.
913 		 */
914 		if (wpa_s->disable_urnm_mfpr) {
915 			wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR, 0);
916 		} else {
917 			capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR);
918 			wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR, 1);
919 		}
920 		if (wpa_s->urnm_mfpr_x20) {
921 			capab |= BIT(WLAN_RSNX_CAPAB_URNM_MFPR_X20);
922 			wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR_X20,
923 					 1);
924 		} else {
925 			wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_URNM_MFPR_X20,
926 					 0);
927 		}
928 	}
929 	if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SPP_AMSDU) &&
930 	    ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_SPP_A_MSDU))
931 		capab |= BIT(WLAN_RSNX_CAPAB_SPP_A_MSDU);
932 	ssid = wpa_config_get_network(wpa_s->conf, awork->network_id);
933 #ifdef CONFIG_ENC_ASSOC
934 	if (awork->auth_alg == WLAN_AUTH_EPPKE) {
935 		if (!ssid) {
936 			wpa_printf(MSG_DEBUG,
937 				   "EPPKE: No network profile found");
938 			goto fail;
939 		}
940 		if (!ieee802_11_rsnx_capab(rsnxe, WLAN_RSNX_CAPAB_KEK_IN_PASN))
941 		{
942 			wpa_printf(MSG_INFO,
943 				   "EPPKE: KEK_IN_PASN not set in AP RSNXE");
944 			goto fail;
945 		}
946 		if (!ieee802_11_rsnx_capab(rsnxe,
947 					   WLAN_RSNX_CAPAB_ASSOC_FRAME_ENCRYPTION)) {
948 			wpa_printf(MSG_INFO,
949 				   "EPPKE: ASSOC_FRAME_ENCRYPTION not set in AP RSNXE");
950 			goto fail;
951 		}
952 		if (awork->akmp == WPA_KEY_MGMT_EPPKE &&
953 		    !ieee802_11_rsnx_capab(rsnxe,
954 					   WLAN_RSNX_CAPAB_UNAUTH_EPPKE)) {
955 			wpa_printf(MSG_DEBUG,
956 				   "EPPKE: AP does not support unauthenticated EPPKE");
957 			goto fail;
958 		}
959 		if (wpa_s->drv_flags2 &
960 		    WPA_DRIVER_FLAGS2_ASSOCIATION_FRAME_ENCRYPTION) {
961 			capab |= BIT(WLAN_RSNX_CAPAB_ASSOC_FRAME_ENCRYPTION);
962 			capab |= BIT(WLAN_RSNX_CAPAB_KEK_IN_PASN);
963 			pasn->derive_kek = true;
964 #ifdef CONFIG_SAE
965 			/*
966 			 * Advertise support for changing SAE password
967 			 * identifiers if configured per network profile.
968 			 */
969 			if (ssid && ssid->sae_password_id &&
970 			    ssid->sae_password_id_change &&
971 			    wpa_key_mgmt_sae_ext_key(awork->akmp)) {
972 				capab |= BIT_ULL(
973 					WLAN_RSNX_CAPAB_SAE_PW_ID_CHANGE);
974 				wpa_sm_set_param(wpa_s->wpa,
975 						 WPA_PARAM_SAE_PW_ID_CHANGE, 1);
976 			}
977 #endif /* CONFIG_SAE */
978 #ifdef CONFIG_PMKSA_PRIVACY
979 			if ((wpa_s->drv_flags2 &
980 			     WPA_DRIVER_FLAGS2_PMKSA_PRIVACY) &&
981 			    ssid->pmksa_privacy &&
982 			    ieee802_11_rsnx_capab(
983 				    rsnxe,
984 				    WLAN_RSNX_CAPAB_PMKSA_CACHING_PRIVACY))
985 				capab |= BIT(
986 					WLAN_RSNX_CAPAB_PMKSA_CACHING_PRIVACY);
987 #endif /* CONFIG_PMKSA_PRIVACY */
988 		}
989 	}
990 #endif /* CONFIG_ENC_ASSOC */
991 
992 	pasn_set_rsnxe_caps(pasn, capab);
993 	pasn_register_callbacks(pasn, wpa_s, wpas_pasn_send_mlme, NULL, NULL,
994 				NULL);
995 
996 #ifdef CONFIG_SAE
997 	if (awork->akmp == WPA_KEY_MGMT_SAE ||
998 	    awork->akmp == WPA_KEY_MGMT_SAE_EXT_KEY) {
999 		struct sae_pt *pt = NULL;
1000 
1001 		if (!ssid) {
1002 			wpa_printf(MSG_DEBUG,
1003 				   "PASN: No network profile found for SAE");
1004 			goto fail;
1005 		}
1006 #ifdef CONFIG_ENC_ASSOC
1007 		if (awork->auth_alg == WLAN_AUTH_EPPKE)
1008 			pt = wpas_pasn_sae_derive_pt_for_eppke(ssid,
1009 							       awork->group);
1010 #endif /* CONFIG_ENC_ASSOC */
1011 		if (awork->auth_alg != WLAN_AUTH_EPPKE)
1012 			pt = wpas_pasn_sae_derive_pt(ssid, awork->group);
1013 		pasn_set_pt(pasn, pt);
1014 		if (!pasn->pt) {
1015 			wpa_printf(MSG_DEBUG, "PASN: Failed to derive PT");
1016 			goto fail;
1017 		}
1018 		pasn->network_id = ssid->id;
1019 	}
1020 #endif /* CONFIG_SAE */
1021 
1022 #ifdef CONFIG_FILS
1023 	/* Prepare needed information for wpas_pasn_wd_fils_auth(). */
1024 	if (awork->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
1025 	    awork->akmp == WPA_KEY_MGMT_FILS_SHA384) {
1026 		indic = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
1027 		if (!ssid) {
1028 			wpa_printf(MSG_DEBUG, "PASN: FILS: No network block");
1029 		} else if (!indic || indic[1] < 2) {
1030 			wpa_printf(MSG_DEBUG,
1031 				   "PASN: Missing FILS Indication IE");
1032 		} else {
1033 			fils_info = WPA_GET_LE16(indic + 2);
1034 			if ((fils_info & BIT(9)) && ssid) {
1035 				pasn->eapol = wpa_s->eapol;
1036 				pasn->network_id = ssid->id;
1037 				wpas_pasn_initiate_eapol(pasn, ssid);
1038 				pasn->fils_eapol = true;
1039 			} else {
1040 				wpa_printf(MSG_DEBUG,
1041 					   "PASN: FILS auth without PFS not supported");
1042 			}
1043 		}
1044 		pasn->fast_reauth = wpa_s->conf->fast_reauth;
1045 	}
1046 #endif /* CONFIG_FILS */
1047 
1048 	pasn_set_initiator_pmksa(pasn, wpa_sm_get_pmksa_cache(wpa_s->wpa));
1049 
1050 	if (wpa_key_mgmt_ft(awork->akmp)) {
1051 #ifdef CONFIG_IEEE80211R
1052 		ret = wpa_pasn_ft_derive_pmk_r1(wpa_s->wpa, awork->akmp,
1053 						awork->peer_addr,
1054 						pasn->pmk_r1,
1055 						&pasn->pmk_r1_len,
1056 						pasn->pmk_r1_name);
1057 		if (ret) {
1058 			wpa_printf(MSG_DEBUG,
1059 				   "PASN: FT: Failed to derive keys");
1060 			goto fail;
1061 		}
1062 #else /* CONFIG_IEEE80211R */
1063 		goto fail;
1064 #endif /* CONFIG_IEEE80211R */
1065 	}
1066 
1067 #ifdef CONFIG_ENC_ASSOC
1068 	pasn->auth_alg = awork->auth_alg;
1069 	pasn->group_cipher = awork->group_cipher;
1070 	pasn->group_mgmt_cipher = awork->group_mgmt_cipher;
1071 	pasn->rsn_capab = awork->rsn_capab;
1072 	pasn_set_rsnxe_ie(pasn, awork->rsnxe_data);
1073 	pasn->is_ml_peer = awork->is_ml_peer;
1074 	/*
1075 	 * Set network_ctx so the PMKSA entry is stored with the correct
1076 	 * network context for lookup on reconnection.
1077 	 */
1078 	if (awork->auth_alg == WLAN_AUTH_EPPKE && ssid)
1079 		pasn->network_ctx = ssid;
1080 
1081 	/* Build RSNE for EPPKE Authentication in SME-in-driver mode */
1082 	if (awork->auth_alg == WLAN_AUTH_EPPKE &&
1083 	    wpas_eppke_set_rsne(wpa_s, pasn, awork) < 0) {
1084 		wpa_printf(MSG_DEBUG, "EPPKE: Failed to configure RSNE");
1085 		goto fail;
1086 	}
1087 #endif /* CONFIG_ENC_ASSOC */
1088 
1089 	/* PASN has not been defined to be modified for RSN overriding, so use
1090 	 * the RSNE and RSNXE from the AP for PASN MIC calculation instead of
1091 	 * the RSNO elements, if any. */
1092 	rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
1093 
1094 	ret = wpas_pasn_start(pasn, awork->own_addr, awork->peer_addr,
1095 			      awork->peer_addr, awork->akmp, awork->cipher,
1096 			      awork->group, bss->freq, rsne, *(rsne + 1) + 2,
1097 			      rsnxe, rsnxe ? *(rsnxe + 1) + 2 : 0,
1098 			      awork->comeback);
1099 	if (ret) {
1100 		wpa_printf(MSG_DEBUG,
1101 			   "PASN: Failed to start PASN authentication");
1102 		goto fail;
1103 	}
1104 	eloop_register_timeout(2, 0, wpas_pasn_auth_work_timeout, wpa_s, NULL);
1105 
1106 	/* comeback token is no longer needed at this stage */
1107 	wpabuf_free(awork->comeback);
1108 	awork->comeback = NULL;
1109 
1110 	wpa_s->pasn_auth_work = work;
1111 	return;
1112 fail:
1113 	wpas_pasn_free_auth_work(awork);
1114 	work->ctx = NULL;
1115 	radio_work_done(work);
1116 }
1117 
1118 
wpas_pasn_auth_start(struct wpa_supplicant * wpa_s,const u8 * own_addr,const u8 * peer_addr,int akmp,int cipher,u16 group,int network_id,const u8 * comeback,size_t comeback_len,unsigned int auth_alg,int group_cipher,int group_mgmt_cipher,u16 rsn_capab,const u8 * rsnxe_data,bool is_ml_peer)1119 int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s,
1120 			 const u8 *own_addr, const u8 *peer_addr,
1121 			 int akmp, int cipher, u16 group, int network_id,
1122 			 const u8 *comeback, size_t comeback_len,
1123 			 unsigned int auth_alg, int group_cipher,
1124 			 int group_mgmt_cipher, u16 rsn_capab,
1125 			 const u8 *rsnxe_data, bool is_ml_peer)
1126 {
1127 	struct wpa_pasn_auth_work *awork;
1128 	struct wpa_bss *bss;
1129 
1130 	wpa_printf(MSG_DEBUG, "PASN: Start: " MACSTR " akmp=0x%x, cipher=0x%x",
1131 		   MAC2STR(peer_addr), akmp, cipher);
1132 
1133 	/*
1134 	 * TODO: Consider modifying the offchannel logic to handle additional
1135 	 * Management frames other then Action frames. For now allow PASN only
1136 	 * with drivers that support off-channel TX.
1137 	 */
1138 	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX)) {
1139 		wpa_printf(MSG_DEBUG,
1140 			   "PASN: Driver does not support offchannel TX");
1141 		return -1;
1142 	}
1143 
1144 	if (radio_work_pending(wpa_s, "pasn-start-auth")) {
1145 		wpa_printf(MSG_DEBUG,
1146 			   "PASN: send_auth: Work is already pending");
1147 		return -1;
1148 	}
1149 
1150 	if (wpa_s->pasn_auth_work) {
1151 		wpa_printf(MSG_DEBUG, "PASN: send_auth: Already in progress");
1152 		return -1;
1153 	}
1154 
1155 	bss = wpas_pasn_allowed(wpa_s, peer_addr, akmp, cipher, auth_alg,
1156 				group_cipher, group_mgmt_cipher);
1157 	if (!bss)
1158 		return -1;
1159 
1160 	wpas_pasn_reset(wpa_s);
1161 
1162 	awork = os_zalloc(sizeof(*awork));
1163 	if (!awork)
1164 		return -1;
1165 
1166 	os_memcpy(awork->own_addr, own_addr, ETH_ALEN);
1167 	os_memcpy(awork->peer_addr, peer_addr, ETH_ALEN);
1168 	awork->akmp = akmp;
1169 	awork->cipher = cipher;
1170 	awork->group = group;
1171 	awork->network_id = network_id;
1172 	awork->auth_alg = auth_alg;
1173 	awork->group_cipher = group_cipher;
1174 	awork->group_mgmt_cipher = group_mgmt_cipher;
1175 #ifdef CONFIG_ENC_ASSOC
1176 	awork->rsn_capab = rsn_capab;
1177 	awork->is_ml_peer = is_ml_peer;
1178 
1179 	if (rsnxe_data) {
1180 		awork->rsnxe_data = os_memdup(rsnxe_data, 2 + rsnxe_data[1]);
1181 		if (!awork->rsnxe_data) {
1182 			wpas_pasn_free_auth_work(awork);
1183 			return -1;
1184 		}
1185 	}
1186 #endif /* CONFIG_ENC_ASSOC */
1187 
1188 	if (comeback && comeback_len) {
1189 		awork->comeback = wpabuf_alloc_copy(comeback, comeback_len);
1190 		if (!awork->comeback) {
1191 			wpas_pasn_free_auth_work(awork);
1192 			return -1;
1193 		}
1194 	}
1195 
1196 	if (!radio_add_work(wpa_s, bss->freq, "pasn-start-auth", 1,
1197 			    wpas_pasn_auth_start_cb, awork)) {
1198 		wpas_pasn_free_auth_work(awork);
1199 		return -1;
1200 	}
1201 
1202 	wpa_printf(MSG_DEBUG, "PASN: Auth work successfully added");
1203 	return 0;
1204 }
1205 
1206 
wpas_pasn_auth_stop(struct wpa_supplicant * wpa_s)1207 void wpas_pasn_auth_stop(struct wpa_supplicant *wpa_s)
1208 {
1209 	struct pasn_data *pasn = &wpa_s->pasn;
1210 
1211 	if (!wpa_s->pasn.ecdh)
1212 		return;
1213 
1214 	wpa_printf(MSG_DEBUG, "PASN: Stopping authentication");
1215 
1216 	wpas_pasn_auth_status(wpa_s, pasn->peer_addr, pasn_get_akmp(pasn),
1217 			      pasn_get_cipher(pasn),
1218 			      pasn->status, pasn->comeback,
1219 			      pasn->comeback_after);
1220 
1221 	wpas_pasn_reset(wpa_s);
1222 
1223 	/* Reset rejected group state when authentication ends */
1224 	pasn->rejected_group_idx = 0;
1225 	os_memset(pasn->rejected_groups, 0, sizeof(pasn->rejected_groups));
1226 }
1227 
1228 
wpas_pasn_free_params(struct wpa_supplicant * wpa_s)1229 void wpas_pasn_free_params(struct wpa_supplicant *wpa_s)
1230 {
1231 	unsigned int i;
1232 
1233 	if (!wpa_s->pasn_params)
1234 		return;
1235 
1236 	for (i = 0; i < wpa_s->pasn_params->num_peers; i++)
1237 		wpas_pasn_free_peer(&wpa_s->pasn_params->peer[i]);
1238 
1239 	os_free(wpa_s->pasn_params);
1240 	wpa_s->pasn_params = NULL;
1241 }
1242 
1243 
wpas_pasn_immediate_retry(struct wpa_supplicant * wpa_s,struct pasn_data * pasn,struct wpa_pasn_params_data * params)1244 static int wpas_pasn_immediate_retry(struct wpa_supplicant *wpa_s,
1245 				     struct pasn_data *pasn,
1246 				     struct wpa_pasn_params_data *params)
1247 {
1248 	int akmp = pasn_get_akmp(pasn);
1249 	int cipher = pasn_get_cipher(pasn);
1250 	u16 group = pasn->group;
1251 	u8 own_addr[ETH_ALEN];
1252 	u8 peer_addr[ETH_ALEN];
1253 	int network_id;
1254 	unsigned int auth_alg;
1255 
1256 	wpa_printf(MSG_DEBUG, "PASN: Immediate retry");
1257 	os_memcpy(own_addr, pasn->own_addr, ETH_ALEN);
1258 	os_memcpy(peer_addr, pasn->peer_addr, ETH_ALEN);
1259 
1260 	/* Hold network ID to avoid losing it in wpas_pasn_reset(). */
1261 	network_id = pasn->network_id;
1262 
1263 	/*
1264 	 * Cache auth_alg before reset as wpas_pasn_reset() clears the pasn
1265 	 * struct. This path is shared with EPPKE, so without preserving it,
1266 	 * a group rejection retry would incorrectly restart with PASN instead
1267 	 * of EPPKE.
1268 	 */
1269 	auth_alg = pasn->auth_alg;
1270 
1271 	wpas_pasn_reset(wpa_s);
1272 
1273 	return wpas_pasn_auth_start(wpa_s, own_addr, peer_addr, akmp, cipher,
1274 				    group, network_id, params->comeback,
1275 				    params->comeback_len, auth_alg,
1276 				    pasn->group_cipher,
1277 				    pasn->group_mgmt_cipher, pasn->rsn_capab,
1278 				    pasn->rsnxe_ie, pasn->is_ml_peer);
1279 }
1280 
1281 
wpas_pasn_retry_with_next_group(struct wpa_supplicant * wpa_s,struct pasn_data * pasn)1282 static int wpas_pasn_retry_with_next_group(struct wpa_supplicant *wpa_s,
1283 					   struct pasn_data *pasn)
1284 {
1285 	struct wpa_pasn_params_data params;
1286 	u16 next_group;
1287 	struct wpa_ssid *ssid = NULL;
1288 
1289 #ifdef CONFIG_ENC_ASSOC
1290 	if (pasn->auth_alg == WLAN_AUTH_EPPKE)
1291 		ssid = wpa_s->current_ssid;
1292 #endif /* CONFIG_ENC_ASSOC */
1293 
1294 	next_group = (u16) wpas_pasn_get_group(wpa_s, ssid, pasn);
1295 	if (!next_group) {
1296 		wpa_printf(MSG_DEBUG,
1297 			   "PASN: No more groups to try after rejection");
1298 		return -1;
1299 	}
1300 
1301 	wpa_printf(MSG_DEBUG, "PASN: Retrying with group %u after rejection",
1302 		   next_group);
1303 
1304 	pasn->group = next_group;
1305 
1306 	os_memset(&params, 0, sizeof(params));
1307 	return wpas_pasn_immediate_retry(wpa_s, pasn, &params);
1308 }
1309 
1310 
wpas_pasn_deauth_cb(struct ptksa_cache_entry * entry)1311 static void wpas_pasn_deauth_cb(struct ptksa_cache_entry *entry)
1312 {
1313 	struct wpa_supplicant *wpa_s = entry->ctx;
1314 	u8 own_addr[ETH_ALEN];
1315 	u8 peer_addr[ETH_ALEN];
1316 
1317 	/* Use a copy of the addresses from the entry to avoid issues with the
1318 	 * entry getting freed during deauthentication processing. */
1319 	os_memcpy(own_addr, entry->own_addr, ETH_ALEN);
1320 	os_memcpy(peer_addr, entry->addr, ETH_ALEN);
1321 	wpas_pasn_deauthenticate(wpa_s, own_addr, peer_addr);
1322 }
1323 
1324 
wpas_pasn_store_comeback_data(struct wpa_supplicant * wpa_s,const struct wpabuf * comeback,u16 comeback_after)1325 static void wpas_pasn_store_comeback_data(struct wpa_supplicant *wpa_s,
1326 					  const struct wpabuf *comeback,
1327 					  u16 comeback_after)
1328 {
1329 	struct pasn_peer *peer;
1330 
1331 	if (!wpa_s->pasn_params)
1332 		return;
1333 
1334 	peer = &wpa_s->pasn_params->peer[wpa_s->pasn_count];
1335 	if (!peer)
1336 		return;
1337 
1338 	wpas_pasn_free_peer_comeback(peer);
1339 	peer->comeback = os_memdup(wpabuf_head(comeback), wpabuf_len(comeback));
1340 	if (!peer->comeback) {
1341 		wpa_printf(MSG_ERROR,
1342 			   "PASN: Mem alloc failed for comeback data");
1343 		return;
1344 	}
1345 
1346 	peer->comeback_len = wpabuf_len(comeback);
1347 	peer->comeback_after = comeback_after;
1348 }
1349 
1350 
wpas_pasn_auth_rx(struct wpa_supplicant * wpa_s,const struct ieee80211_mgmt * mgmt,size_t len)1351 int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
1352 		      const struct ieee80211_mgmt *mgmt, size_t len)
1353 {
1354 	struct pasn_data *pasn = &wpa_s->pasn;
1355 	struct wpa_pasn_params_data pasn_data;
1356 	int ret;
1357 
1358 	if (!wpa_s->pasn_auth_work)
1359 		return -2;
1360 
1361 	wpabuf_free(pasn->frame);
1362 	pasn->frame = NULL;
1363 
1364 	pasn_register_callbacks(pasn, wpa_s, wpas_pasn_send_mlme, NULL, NULL,
1365 				NULL);
1366 	ret = wpa_pasn_auth_rx(pasn, (const u8 *) mgmt, len, &pasn_data);
1367 	if (ret == 0) {
1368 		ptksa_cache_add(wpa_s->ptksa, pasn->own_addr, pasn->peer_addr,
1369 				pasn_get_cipher(pasn),
1370 				dot11RSNAConfigPMKLifetime,
1371 				pasn_get_ptk(pasn),
1372 				wpa_s->pasn_params ? wpas_pasn_deauth_cb : NULL,
1373 				wpa_s->pasn_params ? wpa_s : NULL,
1374 				pasn_get_akmp(pasn), pasn->auth_alg);
1375 
1376 		if (pasn->pmksa_entry)
1377 			wpa_sm_set_cur_pmksa(wpa_s->wpa, pasn->pmksa_entry);
1378 
1379 		if (pasn->auth_alg == WLAN_AUTH_EPPKE) {
1380 #ifdef CONFIG_SME
1381 			os_memcpy(wpa_s->sme.sae.pmkid, pasn->sae.pmkid,
1382 				  PMKID_LEN);
1383 #endif /* CONFIG_SME */
1384 			wpa_sm_set_pmk(wpa_s->wpa, pasn->pmk, pasn->pmk_len,
1385 				       pasn->sae.pmkid, NULL);
1386 		}
1387 	}
1388 
1389 	forced_memzero(pasn_get_ptk(pasn), sizeof(pasn->ptk));
1390 
1391 	if (ret == -1) {
1392 		if (pasn->status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
1393 		    pasn->comeback && wpabuf_len(pasn->comeback))
1394 			wpas_pasn_store_comeback_data(wpa_s, pasn->comeback,
1395 						      pasn->comeback_after);
1396 		wpas_pasn_auth_stop(wpa_s);
1397 		wpas_pasn_auth_work_done(wpa_s, PASN_STATUS_FAILURE);
1398 	}
1399 
1400 	if (ret == 1)
1401 		ret = wpas_pasn_immediate_retry(wpa_s, pasn, &pasn_data);
1402 
1403 	if (ret == 2) {
1404 		ret = wpas_pasn_retry_with_next_group(wpa_s, pasn);
1405 		if (ret) {
1406 			wpa_printf(MSG_INFO,
1407 				   "PASN: Group rejection retry failed");
1408 			wpas_pasn_auth_stop(wpa_s);
1409 			wpas_pasn_auth_work_done(wpa_s, PASN_STATUS_FAILURE);
1410 		}
1411 	}
1412 
1413 	return ret;
1414 }
1415 
1416 
wpas_pasn_auth_trigger(struct wpa_supplicant * wpa_s,struct pasn_auth * pasn_auth)1417 void wpas_pasn_auth_trigger(struct wpa_supplicant *wpa_s,
1418 			    struct pasn_auth *pasn_auth)
1419 {
1420 	struct pasn_peer *src, *dst;
1421 	unsigned int i, num_peers = pasn_auth->num_peers;
1422 
1423 	if (wpa_s->pasn_params) {
1424 		wpa_printf(MSG_DEBUG,
1425 			   "PASN: auth_trigger: Already in progress");
1426 		return;
1427 	}
1428 
1429 	if (!num_peers || num_peers > WPAS_MAX_PASN_PEERS) {
1430 		wpa_printf(MSG_DEBUG,
1431 			   "PASN: auth trigger: Invalid number of peers");
1432 		return;
1433 	}
1434 
1435 	wpa_s->pasn_params = os_zalloc(sizeof(struct pasn_auth));
1436 	if (!wpa_s->pasn_params) {
1437 		wpa_printf(MSG_DEBUG,
1438 			   "PASN: auth trigger: Failed to allocate a buffer");
1439 		return;
1440 	}
1441 
1442 	wpa_s->pasn_count = 0;
1443 	wpa_s->pasn_params->num_peers = num_peers;
1444 
1445 	for (i = 0; i < num_peers; i++) {
1446 		dst = &wpa_s->pasn_params->peer[i];
1447 		src = &pasn_auth->peer[i];
1448 		os_memcpy(dst->own_addr, wpa_s->own_addr, ETH_ALEN);
1449 		os_memcpy(dst->peer_addr, src->peer_addr, ETH_ALEN);
1450 		dst->ltf_keyseed_required = src->ltf_keyseed_required;
1451 		dst->status = PASN_STATUS_SUCCESS;
1452 		dst->akmp = src->akmp;
1453 		dst->cipher = src->cipher;
1454 		if (src->password) {
1455 			dst->password = os_strdup(src->password);
1456 			if (!dst->password) {
1457 				wpa_printf(MSG_DEBUG,
1458 					   "PASN: Mem alloc failed for password");
1459 				goto fail;
1460 			}
1461 		}
1462 		if (src->comeback_len && src->comeback) {
1463 			dst->comeback = os_memdup(src->comeback,
1464 						  src->comeback_len);
1465 			if (!dst->comeback) {
1466 				wpa_printf(MSG_DEBUG,
1467 					   "PASN: Mem alloc failed for comeback cookie");
1468 				goto fail;
1469 			}
1470 			dst->comeback_len = src->comeback_len;
1471 		}
1472 
1473 		if (!is_zero_ether_addr(src->own_addr)) {
1474 			os_memcpy(dst->own_addr, src->own_addr, ETH_ALEN);
1475 			wpa_printf(MSG_DEBUG, "PASN: Own (source) MAC addr: "
1476 				   MACSTR, MAC2STR(dst->own_addr));
1477 		}
1478 	}
1479 
1480 	if (pasn_auth->action == PASN_ACTION_DELETE_SECURE_RANGING_CONTEXT) {
1481 		wpas_pasn_delete_peers(wpa_s, wpa_s->pasn_params);
1482 		os_free(wpa_s->pasn_params);
1483 		wpa_s->pasn_params = NULL;
1484 	} else if (pasn_auth->action == PASN_ACTION_AUTH) {
1485 		wpas_pasn_configure_next_peer(wpa_s, wpa_s->pasn_params);
1486 	}
1487 
1488 	return;
1489 
1490 fail:
1491 	wpas_pasn_free_params(wpa_s);
1492 }
1493 
1494 
1495 #ifdef CONFIG_SME
1496 #ifdef CONFIG_ENC_ASSOC
wpas_eppke_external_auth_set_keys(struct wpa_supplicant * wpa_s,struct pasn_data * pasn,bool acked)1497 static u16 wpas_eppke_external_auth_set_keys(struct wpa_supplicant *wpa_s,
1498 					     struct pasn_data *pasn, bool acked)
1499 {
1500 	static const u8 zero[WPA_TK_MAX_LEN] = { 0 };
1501 	enum wpa_alg alg;
1502 	struct ptksa_cache_entry *entry;
1503 
1504 	if (!acked) {
1505 		wpa_printf(MSG_DEBUG,
1506 			   "EPPKE: Authentication frame 3 TX was not ACKed");
1507 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1508 	}
1509 
1510 	alg = wpa_cipher_to_alg(pasn_get_cipher(pasn));
1511 	entry = ptksa_cache_get(wpa_s->ptksa, pasn->peer_addr,
1512 				pasn_get_cipher(pasn));
1513 	if (!entry) {
1514 		wpa_printf(MSG_INFO,
1515 			   "EPPKE: No PTKSA found to configure keys");
1516 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1517 	}
1518 
1519 	/* Install TK to driver. */
1520 	if (wpa_drv_set_key(wpa_s, -1, alg, pasn->peer_addr, 0, 1, zero, 6,
1521 			    entry->ptk.tk, entry->ptk.tk_len,
1522 			    KEY_FLAG_PAIRWISE_RX_TX)) {
1523 		wpa_printf(MSG_DEBUG,
1524 			   "EPPKE: Failed to install TK to driver");
1525 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1526 	}
1527 
1528 	/* Install LTF Keyseed to driver. */
1529 	if (pasn->secure_ltf &&
1530 	    wpa_drv_set_secure_ranging_ctx(wpa_s, pasn->own_addr,
1531 					   pasn->peer_addr,
1532 					   pasn_get_cipher(pasn), 0, NULL,
1533 					   entry->ptk.ltf_keyseed_len,
1534 					   entry->ptk.ltf_keyseed, 0)) {
1535 		wpa_printf(MSG_DEBUG,
1536 			   "EPPKE: Failed to install LTF Keyseed");
1537 		return WLAN_STATUS_UNSPECIFIED_FAILURE;
1538 	}
1539 
1540 	return WLAN_STATUS_SUCCESS;
1541 }
1542 #endif /* CONFIG_ENC_ASSOC */
1543 #endif /* CONFIG_SME */
1544 
1545 
wpas_pasn_auth_tx_status(struct wpa_supplicant * wpa_s,const u8 * data,size_t data_len,u8 acked)1546 int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
1547 			     const u8 *data, size_t data_len, u8 acked)
1548 
1549 {
1550 	struct pasn_data *pasn = &wpa_s->pasn;
1551 	int ret;
1552 	enum pasn_status auth_status = PASN_STATUS_SUCCESS;
1553 
1554 	if (!wpa_s->pasn_auth_work) {
1555 		wpa_printf(MSG_DEBUG,
1556 			   "PASN: auth_tx_status: no work in progress");
1557 		return -1;
1558 	}
1559 
1560 	ret = wpa_pasn_auth_tx_status(pasn, data, data_len, acked);
1561 	if (ret != 1)
1562 		return ret;
1563 
1564 	if (pasn->auth_alg == WLAN_AUTH_EPPKE) {
1565 #ifdef CONFIG_SME
1566 #ifdef CONFIG_ENC_ASSOC
1567 		u16 status;
1568 
1569 		status = wpas_eppke_external_auth_set_keys(wpa_s, pasn, acked);
1570 		if (status != WLAN_STATUS_SUCCESS)
1571 			auth_status = PASN_STATUS_FAILURE;
1572 #ifdef CONFIG_SAE
1573 		sme_send_external_auth_status(wpa_s, status);
1574 #endif /* CONFIG_SAE */
1575 #endif /* CONFIG_ENC_ASSOC */
1576 #endif /* CONFIG_SME */
1577 		goto auth_done;
1578 	}
1579 
1580 	if (!wpa_s->pasn_params) {
1581 		wpas_pasn_auth_stop(wpa_s);
1582 		return 0;
1583 	}
1584 
1585 	wpas_pasn_set_keys_from_cache(wpa_s, pasn->own_addr, pasn->peer_addr,
1586 				      pasn_get_cipher(pasn),
1587 				      pasn_get_akmp(pasn));
1588 auth_done:
1589 	wpas_pasn_auth_stop(wpa_s);
1590 	wpas_pasn_auth_work_done(wpa_s, auth_status);
1591 
1592 	return 0;
1593 }
1594 
1595 
wpas_pasn_deauthenticate(struct wpa_supplicant * wpa_s,const u8 * own_addr,const u8 * peer_addr)1596 int wpas_pasn_deauthenticate(struct wpa_supplicant *wpa_s, const u8 *own_addr,
1597 			     const u8 *peer_addr)
1598 {
1599 	struct wpa_bss *bss;
1600 	struct wpabuf *buf;
1601 	struct ieee80211_mgmt *deauth;
1602 	int ret;
1603 
1604 	if (ether_addr_equal(wpa_s->bssid, peer_addr)) {
1605 		wpa_printf(MSG_DEBUG,
1606 			   "PASN: Cannot deauthenticate from current BSS");
1607 		return -1;
1608 	}
1609 
1610 	wpa_drv_set_secure_ranging_ctx(wpa_s, own_addr, peer_addr, 0, 0, NULL,
1611 				       0, NULL, 1);
1612 
1613 	wpa_printf(MSG_DEBUG, "PASN: deauth: Flushing all PTKSA entries for "
1614 		   MACSTR, MAC2STR(peer_addr));
1615 	ptksa_cache_flush(wpa_s->ptksa, peer_addr, WPA_CIPHER_NONE);
1616 
1617 	bss = wpa_bss_get_bssid(wpa_s, peer_addr);
1618 	if (!bss) {
1619 		wpa_printf(MSG_DEBUG, "PASN: deauth: BSS not found");
1620 		return -1;
1621 	}
1622 
1623 	buf = wpabuf_alloc(64);
1624 	if (!buf) {
1625 		wpa_printf(MSG_DEBUG, "PASN: deauth: Failed wpabuf allocate");
1626 		return -1;
1627 	}
1628 
1629 	deauth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
1630 					  u.deauth.variable));
1631 
1632 	deauth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
1633 					     (WLAN_FC_STYPE_DEAUTH << 4));
1634 
1635 	os_memcpy(deauth->da, peer_addr, ETH_ALEN);
1636 	os_memcpy(deauth->sa, own_addr, ETH_ALEN);
1637 	os_memcpy(deauth->bssid, peer_addr, ETH_ALEN);
1638 	deauth->u.deauth.reason_code =
1639 		host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
1640 
1641 	/*
1642 	 * Since we do not expect any response from the AP, implement the
1643 	 * Deauthentication frame transmission using direct call to the driver
1644 	 * without a radio work.
1645 	 */
1646 	ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1,
1647 				bss->freq, 0);
1648 
1649 	wpabuf_free(buf);
1650 	wpa_printf(MSG_DEBUG, "PASN: deauth: send_mlme ret=%d", ret);
1651 
1652 	return ret;
1653 }
1654