• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * wpa_supplicant - PASN processing
3  *
4  * Copyright (C) 2019 Intel Corporation
5  *
6  * This software may be distributed under the terms of the BSD license.
7  * See README for more details.
8  */
9 
10 #include "includes.h"
11 
12 #include "common/ieee802_11_defs.h"
13 #include "common/ieee802_11_common.h"
14 #include "common/dragonfly.h"
15 #include "common/ptksa_cache.h"
16 #include "utils/eloop.h"
17 #include "drivers/driver.h"
18 #include "crypto/crypto.h"
19 #include "crypto/random.h"
20 #include "eap_common/eap_defs.h"
21 #include "rsn_supp/wpa.h"
22 #include "rsn_supp/pmksa_cache.h"
23 #include "wpa_supplicant_i.h"
24 #include "driver_i.h"
25 #include "bss.h"
26 #include "config.h"
27 
28 static const int dot11RSNAConfigPMKLifetime = 43200;
29 
30 struct wpa_pasn_auth_work {
31 	u8 bssid[ETH_ALEN];
32 	int akmp;
33 	int cipher;
34 	u16 group;
35 	int network_id;
36 	struct wpabuf *comeback;
37 };
38 
39 
wpas_pasn_free_auth_work(struct wpa_pasn_auth_work * awork)40 static void wpas_pasn_free_auth_work(struct wpa_pasn_auth_work *awork)
41 {
42 	wpabuf_free(awork->comeback);
43 	awork->comeback = NULL;
44 	os_free(awork);
45 }
46 
47 
wpas_pasn_auth_work_timeout(void * eloop_ctx,void * timeout_ctx)48 static void wpas_pasn_auth_work_timeout(void *eloop_ctx, void *timeout_ctx)
49 {
50 	struct wpa_supplicant *wpa_s = eloop_ctx;
51 
52 	wpa_printf(MSG_DEBUG, "PASN: Auth work timeout - stopping auth");
53 
54 	wpas_pasn_auth_stop(wpa_s);
55 }
56 
57 
wpas_pasn_cancel_auth_work(struct wpa_supplicant * wpa_s)58 static void wpas_pasn_cancel_auth_work(struct wpa_supplicant *wpa_s)
59 {
60 	wpa_printf(MSG_DEBUG, "PASN: Cancel pasn-start-auth work");
61 
62 	/* Remove pending/started work */
63 	radio_remove_works(wpa_s, "pasn-start-auth", 0);
64 }
65 
66 
wpas_pasn_auth_status(struct wpa_supplicant * wpa_s,const u8 * bssid,int akmp,int cipher,u8 status,struct wpabuf * comeback,u16 comeback_after)67 static void wpas_pasn_auth_status(struct wpa_supplicant *wpa_s, const u8 *bssid,
68 				  int akmp, int cipher, u8 status,
69 				  struct wpabuf *comeback,
70 				  u16 comeback_after)
71 {
72 	if (comeback) {
73 		size_t comeback_len = wpabuf_len(comeback);
74 		size_t buflen = comeback_len * 2 + 1;
75 		char *comeback_txt = os_malloc(buflen);
76 
77 		if (comeback_txt) {
78 			wpa_snprintf_hex(comeback_txt, buflen,
79 					 wpabuf_head(comeback), comeback_len);
80 
81 			wpa_msg_only_for_cb(wpa_s, MSG_INFO, PASN_AUTH_STATUS MACSTR
82 				" akmp=%s, status=%u comeback_after=%u comeback=%s",
83 				MAC2STR(bssid),
84 				wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
85 				status, comeback_after, comeback_txt);
86 			wpa_printf(MSG_INFO, PASN_AUTH_STATUS MACSTR_SEC
87 				" akmp=%s, status=%u comeback_after=%u comeback=%s",
88 				MAC2STR_SEC(bssid),
89 				wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
90 				status, comeback_after, comeback_txt);
91 
92 			os_free(comeback_txt);
93 			return;
94 		}
95 	}
96 
97 	wpa_msg(wpa_s, MSG_INFO,
98 		PASN_AUTH_STATUS MACSTR " akmp=%s, status=%u",
99 		MAC2STR(bssid), wpa_key_mgmt_txt(akmp, WPA_PROTO_RSN),
100 		status);
101 }
102 
103 
104 #ifdef CONFIG_SAE
105 
wpas_pasn_wd_sae_commit(struct wpa_supplicant * wpa_s)106 static struct wpabuf * wpas_pasn_wd_sae_commit(struct wpa_supplicant *wpa_s)
107 {
108 	struct wpas_pasn *pasn = &wpa_s->pasn;
109 	struct wpabuf *buf = NULL;
110 	int ret;
111 
112 	ret = sae_set_group(&pasn->sae, pasn->group);
113 	if (ret) {
114 		wpa_printf(MSG_DEBUG, "PASN: Failed to set SAE group");
115 		return NULL;
116 	}
117 
118 	ret = sae_prepare_commit_pt(&pasn->sae, pasn->ssid->pt,
119 				    wpa_s->own_addr, pasn->bssid,
120 				    NULL, NULL);
121 	if (ret) {
122 		wpa_printf(MSG_DEBUG, "PASN: Failed to prepare SAE commit");
123 		return NULL;
124 	}
125 
126 	/* Need to add the entire Authentication frame body */
127 	buf = wpabuf_alloc(6 + SAE_COMMIT_MAX_LEN);
128 	if (!buf) {
129 		wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
130 		return NULL;
131 	}
132 
133 	wpabuf_put_le16(buf, WLAN_AUTH_SAE);
134 	wpabuf_put_le16(buf, 1);
135 	wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
136 
137 	sae_write_commit(&pasn->sae, buf, NULL, 0);
138 	pasn->sae.state = SAE_COMMITTED;
139 
140 	return buf;
141 }
142 
143 
wpas_pasn_wd_sae_rx(struct wpa_supplicant * wpa_s,struct wpabuf * wd)144 static int wpas_pasn_wd_sae_rx(struct wpa_supplicant *wpa_s, struct wpabuf *wd)
145 {
146 	struct wpas_pasn *pasn = &wpa_s->pasn;
147 	const u8 *data;
148 	size_t buf_len;
149 	u16 len, res, alg, seq, status;
150 	int groups[] = { pasn->group, 0 };
151 	int ret;
152 
153 	if (!wd)
154 		return -1;
155 
156 	data = wpabuf_head_u8(wd);
157 	buf_len = wpabuf_len(wd);
158 
159 	/* first handle the commit message */
160 	if (buf_len < 2) {
161 		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short (commit)");
162 		return -1;
163 	}
164 
165 	len = WPA_GET_LE16(data);
166 	if (len < 6 || buf_len - 2 < len) {
167 		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short for commit");
168 		return -1;
169 	}
170 
171 	buf_len -= 2;
172 	data += 2;
173 
174 	alg = WPA_GET_LE16(data);
175 	seq = WPA_GET_LE16(data + 2);
176 	status = WPA_GET_LE16(data + 4);
177 
178 	wpa_printf(MSG_DEBUG, "PASN: SAE: commit: alg=%u, seq=%u, status=%u",
179 		   alg, seq, status);
180 
181 	if (alg != WLAN_AUTH_SAE || seq != 1 ||
182 	    status != WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
183 		wpa_printf(MSG_DEBUG, "PASN: SAE: dropping peer commit");
184 		return -1;
185 	}
186 
187 	res = sae_parse_commit(&pasn->sae, data + 6, len - 6, NULL, 0, groups,
188 			       1);
189 	if (res != WLAN_STATUS_SUCCESS) {
190 		wpa_printf(MSG_DEBUG, "PASN: SAE failed parsing commit");
191 		return -1;
192 	}
193 
194 	/* Process the commit message and derive the PMK */
195 	ret = sae_process_commit(&pasn->sae);
196 	if (ret) {
197 		wpa_printf(MSG_DEBUG, "SAE: Failed to process peer commit");
198 		return -1;
199 	}
200 
201 	buf_len -= len;
202 	data += len;
203 
204 	/* Handle the confirm message */
205 	if (buf_len < 2) {
206 		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short (confirm)");
207 		return -1;
208 	}
209 
210 	len = WPA_GET_LE16(data);
211 	if (len < 6 || buf_len - 2 < len) {
212 		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short for confirm");
213 		return -1;
214 	}
215 
216 	buf_len -= 2;
217 	data += 2;
218 
219 	alg = WPA_GET_LE16(data);
220 	seq = WPA_GET_LE16(data + 2);
221 	status = WPA_GET_LE16(data + 4);
222 
223 	wpa_printf(MSG_DEBUG, "PASN: SAE confirm: alg=%u, seq=%u, status=%u",
224 		   alg, seq, status);
225 
226 	if (alg != WLAN_AUTH_SAE || seq != 2 || status != WLAN_STATUS_SUCCESS) {
227 		wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE confirm");
228 		return -1;
229 	}
230 
231 	res = sae_check_confirm(&pasn->sae, data + 6, len - 6);
232 	if (res != WLAN_STATUS_SUCCESS) {
233 		wpa_printf(MSG_DEBUG, "PASN: SAE failed checking confirm");
234 		return -1;
235 	}
236 
237 	wpa_printf(MSG_DEBUG, "PASN: SAE completed successfully");
238 	pasn->sae.state = SAE_ACCEPTED;
239 
240 	return 0;
241 }
242 
243 
wpas_pasn_wd_sae_confirm(struct wpa_supplicant * wpa_s)244 static struct wpabuf * wpas_pasn_wd_sae_confirm(struct wpa_supplicant *wpa_s)
245 {
246 	struct wpas_pasn *pasn = &wpa_s->pasn;
247 	struct wpabuf *buf = NULL;
248 
249 	/* Need to add the entire authentication frame body */
250 	buf = wpabuf_alloc(6 + SAE_CONFIRM_MAX_LEN);
251 	if (!buf) {
252 		wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
253 		return NULL;
254 	}
255 
256 	wpabuf_put_le16(buf, WLAN_AUTH_SAE);
257 	wpabuf_put_le16(buf, 2);
258 	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
259 
260 	sae_write_confirm(&pasn->sae, buf);
261 	pasn->sae.state = SAE_CONFIRMED;
262 
263 	return buf;
264 }
265 
266 
wpas_pasn_sae_setup_pt(struct wpa_supplicant * wpa_s,struct wpa_ssid * ssid,int group)267 static int wpas_pasn_sae_setup_pt(struct wpa_supplicant *wpa_s,
268 				  struct wpa_ssid *ssid, int group)
269 {
270 	const char *password = ssid->sae_password;
271 	int groups[2] = { group, 0 };
272 
273 	if (!password)
274 		password = ssid->passphrase;
275 
276 	if (!password) {
277 		wpa_printf(MSG_DEBUG, "PASN: SAE without a password");
278 		return -1;
279 	}
280 
281 	if (ssid->pt)
282 		return 0; /* PT already derived */
283 
284 	ssid->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
285 				 (const u8 *) password, os_strlen(password),
286 				 ssid->sae_password_id);
287 
288 	return ssid->pt ? 0 : -1;
289 }
290 
291 #endif /* CONFIG_SAE */
292 
293 
294 #ifdef CONFIG_FILS
295 
wpas_pasn_fils_build_auth(struct wpa_supplicant * wpa_s)296 static struct wpabuf * wpas_pasn_fils_build_auth(struct wpa_supplicant *wpa_s)
297 {
298 	struct wpas_pasn *pasn = &wpa_s->pasn;
299 	struct wpabuf *buf = NULL;
300 	struct wpabuf *erp_msg;
301 	int ret;
302 
303 	erp_msg = eapol_sm_build_erp_reauth_start(wpa_s->eapol);
304 	if (!erp_msg) {
305 		wpa_printf(MSG_DEBUG,
306 			   "PASN: FILS: ERP EAP-Initiate/Re-auth unavailable");
307 		return NULL;
308 	}
309 
310 	if (random_get_bytes(pasn->fils.nonce, FILS_NONCE_LEN) < 0 ||
311 	    random_get_bytes(pasn->fils.session, FILS_SESSION_LEN) < 0)
312 		goto fail;
313 
314 	wpa_hexdump(MSG_DEBUG, "PASN: FILS: Nonce", pasn->fils.nonce,
315 		    FILS_NONCE_LEN);
316 
317 	wpa_hexdump(MSG_DEBUG, "PASN: FILS: Session", pasn->fils.session,
318 		    FILS_SESSION_LEN);
319 
320 	buf = wpabuf_alloc(1500);
321 	if (!buf)
322 		goto fail;
323 
324 	/* Add the authentication algorithm */
325 	wpabuf_put_le16(buf, WLAN_AUTH_FILS_SK);
326 
327 	/* Authentication Transaction seq# */
328 	wpabuf_put_le16(buf, 1);
329 
330 	/* Status Code */
331 	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
332 
333 	/* Own RSNE */
334 	wpa_pasn_add_rsne(buf, NULL, pasn->akmp, pasn->cipher);
335 
336 	/* FILS Nonce */
337 	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
338 	wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN);
339 	wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
340 	wpabuf_put_data(buf, pasn->fils.nonce, FILS_NONCE_LEN);
341 
342 	/* FILS Session */
343 	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
344 	wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN);
345 	wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
346 	wpabuf_put_data(buf, pasn->fils.session, FILS_SESSION_LEN);
347 
348 	/* Wrapped Data (ERP) */
349 	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
350 	wpabuf_put_u8(buf, 1 + wpabuf_len(erp_msg));
351 	wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
352 	wpabuf_put_buf(buf, erp_msg);
353 
354 	/*
355 	 * Calculate pending PMKID here so that we do not need to maintain a
356 	 * copy of the EAP-Initiate/Reauth message.
357 	 */
358 	ret = fils_pmkid_erp(pasn->akmp, wpabuf_head(erp_msg),
359 			     wpabuf_len(erp_msg),
360 			     pasn->fils.erp_pmkid);
361 	if (ret) {
362 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to get ERP PMKID");
363 		goto fail;
364 	}
365 
366 	wpabuf_free(erp_msg);
367 	erp_msg = NULL;
368 
369 	wpa_hexdump_buf(MSG_DEBUG, "PASN: FILS: Authentication frame", buf);
370 	return buf;
371 fail:
372 	wpabuf_free(erp_msg);
373 	wpabuf_free(buf);
374 	return NULL;
375 }
376 
377 
wpas_pasn_initiate_eapol(struct wpa_supplicant * wpa_s)378 static void wpas_pasn_initiate_eapol(struct wpa_supplicant *wpa_s)
379 {
380 	struct wpas_pasn *pasn = &wpa_s->pasn;
381 	struct eapol_config eapol_conf;
382 	struct wpa_ssid *ssid = pasn->ssid;
383 
384 	wpa_printf(MSG_DEBUG, "PASN: FILS: Initiating EAPOL");
385 
386 	eapol_sm_notify_eap_success(wpa_s->eapol, false);
387 	eapol_sm_notify_eap_fail(wpa_s->eapol, false);
388 	eapol_sm_notify_portControl(wpa_s->eapol, Auto);
389 
390 	os_memset(&eapol_conf, 0, sizeof(eapol_conf));
391 	eapol_conf.fast_reauth = wpa_s->conf->fast_reauth;
392 	eapol_conf.workaround = ssid->eap_workaround;
393 
394 	eapol_sm_notify_config(wpa_s->eapol, &ssid->eap, &eapol_conf);
395 }
396 
397 
wpas_pasn_wd_fils_auth(struct wpa_supplicant * wpa_s)398 static struct wpabuf * wpas_pasn_wd_fils_auth(struct wpa_supplicant *wpa_s)
399 {
400 	struct wpas_pasn *pasn = &wpa_s->pasn;
401 	struct wpa_bss *bss;
402 	const u8 *indic;
403 	u16 fils_info;
404 
405 	wpa_printf(MSG_DEBUG, "PASN: FILS: wrapped data - completed=%u",
406 		   pasn->fils.completed);
407 
408 	/* Nothing to add as we are done */
409 	if (pasn->fils.completed)
410 		return NULL;
411 
412 	if (!pasn->ssid) {
413 		wpa_printf(MSG_DEBUG, "PASN: FILS: No network block");
414 		return NULL;
415 	}
416 
417 	bss = wpa_bss_get_bssid(wpa_s, pasn->bssid);
418 	if (!bss) {
419 		wpa_printf(MSG_DEBUG, "PASN: FILS: BSS not found");
420 		return NULL;
421 	}
422 
423 	indic = wpa_bss_get_ie(bss, WLAN_EID_FILS_INDICATION);
424 	if (!indic || indic[1] < 2) {
425 		wpa_printf(MSG_DEBUG, "PASN: Missing FILS Indication IE");
426 		return NULL;
427 	}
428 
429 	fils_info = WPA_GET_LE16(indic + 2);
430 	if (!(fils_info & BIT(9))) {
431 		wpa_printf(MSG_DEBUG,
432 			   "PASN: FILS auth without PFS not supported");
433 		return NULL;
434 	}
435 
436 	wpas_pasn_initiate_eapol(wpa_s);
437 
438 	return wpas_pasn_fils_build_auth(wpa_s);
439 }
440 
441 
wpas_pasn_wd_fils_rx(struct wpa_supplicant * wpa_s,struct wpabuf * wd)442 static int wpas_pasn_wd_fils_rx(struct wpa_supplicant *wpa_s, struct wpabuf *wd)
443 {
444 	struct wpas_pasn *pasn = &wpa_s->pasn;
445 	struct ieee802_11_elems elems;
446 	struct wpa_ie_data rsne_data;
447 	u8 rmsk[ERP_MAX_KEY_LEN];
448 	size_t rmsk_len;
449 	u8 anonce[FILS_NONCE_LEN];
450 	const u8 *data;
451 	size_t buf_len;
452 	struct wpabuf *fils_wd = NULL;
453 	u16 alg, seq, status;
454 	int ret;
455 
456 	if (!wd)
457 		return -1;
458 
459 	data = wpabuf_head(wd);
460 	buf_len = wpabuf_len(wd);
461 
462 	wpa_hexdump(MSG_DEBUG, "PASN: FILS: Authentication frame len=%zu",
463 		    data, buf_len);
464 
465 	/* first handle the header */
466 	if (buf_len < 6) {
467 		wpa_printf(MSG_DEBUG, "PASN: FILS: Buffer too short");
468 		return -1;
469 	}
470 
471 	alg = WPA_GET_LE16(data);
472 	seq = WPA_GET_LE16(data + 2);
473 	status = WPA_GET_LE16(data + 4);
474 
475 	wpa_printf(MSG_DEBUG, "PASN: FILS: commit: alg=%u, seq=%u, status=%u",
476 		   alg, seq, status);
477 
478 	if (alg != WLAN_AUTH_FILS_SK || seq != 2 ||
479 	    status != WLAN_STATUS_SUCCESS) {
480 		wpa_printf(MSG_DEBUG,
481 			   "PASN: FILS: Dropping peer authentication");
482 		return -1;
483 	}
484 
485 	data += 6;
486 	buf_len -= 6;
487 
488 	if (ieee802_11_parse_elems(data, buf_len, &elems, 1) == ParseFailed) {
489 		wpa_printf(MSG_DEBUG, "PASN: FILS: Could not parse elements");
490 		return -1;
491 	}
492 
493 	if (!elems.rsn_ie || !elems.fils_nonce || !elems.fils_nonce ||
494 	    !elems.wrapped_data) {
495 		wpa_printf(MSG_DEBUG, "PASN: FILS: Missing IEs");
496 		return -1;
497 	}
498 
499 	ret = wpa_parse_wpa_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
500 			       &rsne_data);
501 	if (ret) {
502 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed parsing RNSE");
503 		return -1;
504 	}
505 
506 	ret = wpa_pasn_validate_rsne(&rsne_data);
507 	if (ret) {
508 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed validating RSNE");
509 		return -1;
510 	}
511 
512 	if (rsne_data.num_pmkid) {
513 		wpa_printf(MSG_DEBUG,
514 			   "PASN: FILS: Not expecting PMKID in RSNE");
515 		return -1;
516 	}
517 
518 	wpa_hexdump(MSG_DEBUG, "PASN: FILS: ANonce", elems.fils_nonce,
519 		    FILS_NONCE_LEN);
520 	os_memcpy(anonce, elems.fils_nonce, FILS_NONCE_LEN);
521 
522 	wpa_hexdump(MSG_DEBUG, "PASN: FILS: FILS Session", elems.fils_session,
523 		    FILS_SESSION_LEN);
524 
525 	if (os_memcmp(pasn->fils.session, elems.fils_session,
526 		      FILS_SESSION_LEN)) {
527 		wpa_printf(MSG_DEBUG, "PASN: FILS: Session mismatch");
528 		return -1;
529 	}
530 
531 	fils_wd = ieee802_11_defrag(&elems, WLAN_EID_EXTENSION,
532 				    WLAN_EID_EXT_WRAPPED_DATA);
533 
534 	if (!fils_wd) {
535 		wpa_printf(MSG_DEBUG,
536 			   "PASN: FILS: Failed getting wrapped data");
537 		return -1;
538 	}
539 
540 	eapol_sm_process_erp_finish(wpa_s->eapol, wpabuf_head(fils_wd),
541 				    wpabuf_len(fils_wd));
542 
543 	wpabuf_free(fils_wd);
544 	fils_wd = NULL;
545 
546 	if (eapol_sm_failed(wpa_s->eapol)) {
547 		wpa_printf(MSG_DEBUG, "PASN: FILS: ERP finish failed");
548 		return -1;
549 	}
550 
551 	rmsk_len = ERP_MAX_KEY_LEN;
552 	ret = eapol_sm_get_key(wpa_s->eapol, rmsk, rmsk_len);
553 
554 	if (ret == PMK_LEN) {
555 		rmsk_len = PMK_LEN;
556 		ret = eapol_sm_get_key(wpa_s->eapol, rmsk, rmsk_len);
557 	}
558 
559 	if (ret) {
560 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed getting RMSK");
561 		return -1;
562 	}
563 
564 	ret = fils_rmsk_to_pmk(pasn->akmp, rmsk, rmsk_len,
565 			       pasn->fils.nonce, anonce, NULL, 0,
566 			       pasn->pmk, &pasn->pmk_len);
567 
568 	forced_memzero(rmsk, sizeof(rmsk));
569 
570 	if (ret) {
571 		wpa_printf(MSG_DEBUG, "PASN: FILS: Failed to derive PMK");
572 		return -1;
573 	}
574 
575 	wpa_hexdump(MSG_DEBUG, "PASN: FILS: PMKID", pasn->fils.erp_pmkid,
576 		    PMKID_LEN);
577 
578 	wpa_printf(MSG_DEBUG, "PASN: FILS: ERP processing succeeded");
579 
580 	wpa_pasn_pmksa_cache_add(wpa_s->wpa, pasn->pmk,
581 				 pasn->pmk_len, pasn->fils.erp_pmkid,
582 				 pasn->bssid, pasn->akmp);
583 
584 	pasn->fils.completed = true;
585 	return 0;
586 }
587 
588 #endif /* CONFIG_FILS */
589 
590 
wpas_pasn_get_wrapped_data(struct wpa_supplicant * wpa_s)591 static struct wpabuf * wpas_pasn_get_wrapped_data(struct wpa_supplicant *wpa_s)
592 {
593 	struct wpas_pasn *pasn = &wpa_s->pasn;
594 
595 	if (pasn->using_pmksa)
596 		return NULL;
597 
598 	switch (pasn->akmp) {
599 	case WPA_KEY_MGMT_PASN:
600 		/* no wrapped data */
601 		return NULL;
602 	case WPA_KEY_MGMT_SAE:
603 #ifdef CONFIG_SAE
604 		if (pasn->trans_seq == 0)
605 			return wpas_pasn_wd_sae_commit(wpa_s);
606 		if (pasn->trans_seq == 2)
607 			return wpas_pasn_wd_sae_confirm(wpa_s);
608 #endif /* CONFIG_SAE */
609 		wpa_printf(MSG_ERROR,
610 			   "PASN: SAE: Cannot derive wrapped data");
611 		return NULL;
612 	case WPA_KEY_MGMT_FILS_SHA256:
613 	case WPA_KEY_MGMT_FILS_SHA384:
614 #ifdef CONFIG_FILS
615 		return wpas_pasn_wd_fils_auth(wpa_s);
616 #endif /* CONFIG_FILS */
617 	case WPA_KEY_MGMT_FT_PSK:
618 	case WPA_KEY_MGMT_FT_IEEE8021X:
619 	case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
620 		/*
621 		 * Wrapped data with these AKMs is optional and is only needed
622 		 * for further validation of FT security parameters. For now do
623 		 * not use them.
624 		 */
625 		return NULL;
626 	default:
627 		wpa_printf(MSG_ERROR,
628 			   "PASN: TODO: Wrapped data for akmp=0x%x",
629 			   pasn->akmp);
630 		return NULL;
631 	}
632 }
633 
634 
wpas_pasn_get_wrapped_data_format(struct wpas_pasn * pasn)635 static u8 wpas_pasn_get_wrapped_data_format(struct wpas_pasn *pasn)
636 {
637 	if (pasn->using_pmksa)
638 		return WPA_PASN_WRAPPED_DATA_NO;
639 
640 	/* Note: Valid AKMP is expected to already be validated */
641 	switch (pasn->akmp) {
642 	case WPA_KEY_MGMT_SAE:
643 		return WPA_PASN_WRAPPED_DATA_SAE;
644 	case WPA_KEY_MGMT_FILS_SHA256:
645 	case WPA_KEY_MGMT_FILS_SHA384:
646 		return WPA_PASN_WRAPPED_DATA_FILS_SK;
647 	case WPA_KEY_MGMT_FT_PSK:
648 	case WPA_KEY_MGMT_FT_IEEE8021X:
649 	case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
650 		/*
651 		 * Wrapped data with these AKMs is optional and is only needed
652 		 * for further validation of FT security parameters. For now do
653 		 * not use them.
654 		 */
655 		return WPA_PASN_WRAPPED_DATA_NO;
656 	case WPA_KEY_MGMT_PASN:
657 	default:
658 		return WPA_PASN_WRAPPED_DATA_NO;
659 	}
660 }
661 
662 
wpas_pasn_build_auth_1(struct wpa_supplicant * wpa_s,const struct wpabuf * comeback)663 static struct wpabuf * wpas_pasn_build_auth_1(struct wpa_supplicant *wpa_s,
664 					      const struct wpabuf *comeback)
665 {
666 	struct wpas_pasn *pasn = &wpa_s->pasn;
667 	struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL;
668 	const u8 *pmkid;
669 	u8 wrapped_data;
670 	int ret;
671 	u16 capab;
672 
673 	wpa_printf(MSG_DEBUG, "PASN: Building frame 1");
674 
675 	if (pasn->trans_seq)
676 		return NULL;
677 
678 	buf = wpabuf_alloc(1500);
679 	if (!buf)
680 		goto fail;
681 
682 	/* Get public key */
683 	pubkey = crypto_ecdh_get_pubkey(pasn->ecdh, 0);
684 	pubkey = wpabuf_zeropad(pubkey, crypto_ecdh_prime_len(pasn->ecdh));
685 	if (!pubkey) {
686 		wpa_printf(MSG_DEBUG, "PASN: Failed to get pubkey");
687 		goto fail;
688 	}
689 
690 	wrapped_data = wpas_pasn_get_wrapped_data_format(pasn);
691 
692 	wpa_pasn_build_auth_header(buf, pasn->bssid,
693 				   wpa_s->own_addr, pasn->bssid,
694 				   pasn->trans_seq + 1, WLAN_STATUS_SUCCESS);
695 
696 	pmkid = NULL;
697 	if (wpa_key_mgmt_ft(pasn->akmp)) {
698 		ret = wpa_pasn_ft_derive_pmk_r1(wpa_s->wpa, pasn->akmp,
699 						pasn->bssid,
700 						pasn->pmk_r1,
701 						&pasn->pmk_r1_len,
702 						pasn->pmk_r1_name);
703 		if (ret) {
704 			wpa_printf(MSG_DEBUG,
705 				   "PASN: FT: Failed to derive keys");
706 			goto fail;
707 		}
708 
709 		pmkid = pasn->pmk_r1_name;
710 	} else if (wrapped_data != WPA_PASN_WRAPPED_DATA_NO) {
711 		struct rsn_pmksa_cache_entry *pmksa;
712 
713 		pmksa = wpa_sm_pmksa_cache_get(wpa_s->wpa, pasn->bssid,
714 					       NULL, NULL, pasn->akmp);
715 		if (pmksa)
716 			pmkid = pmksa->pmkid;
717 
718 		/*
719 		 * Note: Even when PMKSA is available, also add wrapped data as
720 		 * it is possible that the PMKID is no longer valid at the AP.
721 		 */
722 		wrapped_data_buf = wpas_pasn_get_wrapped_data(wpa_s);
723 	}
724 
725 	if (wpa_pasn_add_rsne(buf, pmkid, pasn->akmp, pasn->cipher) < 0)
726 		goto fail;
727 
728 	if (!wrapped_data_buf)
729 		wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
730 
731 	wpa_pasn_add_parameter_ie(buf, pasn->group, wrapped_data,
732 				  pubkey, true, comeback, -1);
733 
734 	if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
735 		goto fail;
736 
737 	/* Add own RNSXE */
738 	capab = 0;
739 	capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
740 	if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF)
741 		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
742 	if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT)
743 		capab |= BIT(WLAN_RSNX_CAPAB_SECURE_RTT);
744 	if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_PROT_RANGE_NEG)
745 		capab |= BIT(WLAN_RSNX_CAPAB_PROT_RANGE_NEG);
746 	wpa_pasn_add_rsnxe(buf, capab);
747 
748 	ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher,
749 				   wpabuf_head_u8(buf) + IEEE80211_HDRLEN,
750 				   wpabuf_len(buf) - IEEE80211_HDRLEN,
751 				   pasn->hash);
752 	if (ret) {
753 		wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
754 		goto fail;
755 	}
756 
757 	pasn->trans_seq++;
758 
759 	wpabuf_free(wrapped_data_buf);
760 	wpabuf_free(pubkey);
761 
762 	wpa_printf(MSG_DEBUG, "PASN: Frame 1: Success");
763 	return buf;
764 fail:
765 	pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
766 	wpabuf_free(wrapped_data_buf);
767 	wpabuf_free(pubkey);
768 	wpabuf_free(buf);
769 	return NULL;
770 }
771 
772 
wpas_pasn_build_auth_3(struct wpa_supplicant * wpa_s)773 static struct wpabuf * wpas_pasn_build_auth_3(struct wpa_supplicant *wpa_s)
774 {
775 	struct wpas_pasn *pasn = &wpa_s->pasn;
776 	struct wpabuf *buf, *wrapped_data_buf = NULL;
777 	u8 mic[WPA_PASN_MAX_MIC_LEN];
778 	u8 mic_len, data_len;
779 	const u8 *data;
780 	u8 *ptr;
781 	u8 wrapped_data;
782 	int ret;
783 
784 	wpa_printf(MSG_DEBUG, "PASN: Building frame 3");
785 
786 	if (pasn->trans_seq != 2)
787 		return NULL;
788 
789 	buf = wpabuf_alloc(1500);
790 	if (!buf)
791 		goto fail;
792 
793 	wrapped_data = wpas_pasn_get_wrapped_data_format(pasn);
794 
795 	wpa_pasn_build_auth_header(buf, pasn->bssid,
796 				   wpa_s->own_addr, pasn->bssid,
797 				   pasn->trans_seq + 1, WLAN_STATUS_SUCCESS);
798 
799 	wrapped_data_buf = wpas_pasn_get_wrapped_data(wpa_s);
800 
801 	if (!wrapped_data_buf)
802 		wrapped_data = WPA_PASN_WRAPPED_DATA_NO;
803 
804 	wpa_pasn_add_parameter_ie(buf, pasn->group, wrapped_data,
805 				  NULL, false, NULL, -1);
806 
807 	if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
808 		goto fail;
809 	wpabuf_free(wrapped_data_buf);
810 	wrapped_data_buf = NULL;
811 
812 	/* Add the MIC */
813 	mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
814 	wpabuf_put_u8(buf, WLAN_EID_MIC);
815 	wpabuf_put_u8(buf, mic_len);
816 	ptr = wpabuf_put(buf, mic_len);
817 
818 	os_memset(ptr, 0, mic_len);
819 
820 	data = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
821 	data_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
822 
823 	ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
824 		       wpa_s->own_addr, pasn->bssid,
825 		       pasn->hash, mic_len * 2, data, data_len, mic);
826 	if (ret) {
827 		wpa_printf(MSG_DEBUG, "PASN: frame 3: Failed MIC calculation");
828 		goto fail;
829 	}
830 
831 #ifdef CONFIG_TESTING_OPTIONS
832 	if (wpa_s->conf->pasn_corrupt_mic) {
833 		wpa_printf(MSG_DEBUG, "PASN: frame 3: Corrupt MIC");
834 		mic[0] = ~mic[0];
835 	}
836 #endif /* CONFIG_TESTING_OPTIONS */
837 
838 	os_memcpy(ptr, mic, mic_len);
839 
840 	pasn->trans_seq++;
841 
842 	wpa_printf(MSG_DEBUG, "PASN: frame 3: Success");
843 	return buf;
844 fail:
845 	pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
846 	wpabuf_free(wrapped_data_buf);
847 	wpabuf_free(buf);
848 	return NULL;
849 }
850 
851 
wpas_pasn_reset(struct wpa_supplicant * wpa_s)852 static void wpas_pasn_reset(struct wpa_supplicant *wpa_s)
853 {
854 	struct wpas_pasn *pasn = &wpa_s->pasn;
855 
856 	wpa_printf(MSG_DEBUG, "PASN: Reset");
857 
858 	crypto_ecdh_deinit(pasn->ecdh);
859 	pasn->ecdh = NULL;
860 
861 	wpas_pasn_cancel_auth_work(wpa_s);
862 	wpa_s->pasn_auth_work = NULL;
863 
864 	eloop_cancel_timeout(wpas_pasn_auth_work_timeout, wpa_s, NULL);
865 
866 	pasn->akmp = 0;
867 	pasn->cipher = 0;
868 	pasn->group = 0;
869 	pasn->trans_seq = 0;
870 	pasn->pmk_len = 0;
871 	pasn->using_pmksa = false;
872 
873 	forced_memzero(pasn->pmk, sizeof(pasn->pmk));
874 	forced_memzero(&pasn->ptk, sizeof(pasn->ptk));
875 	forced_memzero(&pasn->hash, sizeof(pasn->hash));
876 
877 	wpabuf_free(pasn->beacon_rsne_rsnxe);
878 	pasn->beacon_rsne_rsnxe = NULL;
879 
880 	wpabuf_free(pasn->comeback);
881 	pasn->comeback = NULL;
882 	pasn->comeback_after = 0;
883 
884 #ifdef CONFIG_SAE
885 	sae_clear_data(&pasn->sae);
886 #endif /* CONFIG_SAE */
887 
888 #ifdef CONFIG_FILS
889 	os_memset(&pasn->fils, 0, sizeof(pasn->fils));
890 #endif /* CONFIG_FILS*/
891 
892 #ifdef CONFIG_IEEE80211R
893 	forced_memzero(pasn->pmk_r1, sizeof(pasn->pmk_r1));
894 	pasn->pmk_r1_len = 0;
895 	os_memset(pasn->pmk_r1_name, 0, sizeof(pasn->pmk_r1_name));
896 #endif /* CONFIG_IEEE80211R */
897 	pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
898 }
899 
900 
wpas_pasn_set_pmk(struct wpa_supplicant * wpa_s,struct wpa_ie_data * rsn_data,struct wpa_pasn_params_data * pasn_data,struct wpabuf * wrapped_data)901 static int wpas_pasn_set_pmk(struct wpa_supplicant *wpa_s,
902 			     struct wpa_ie_data *rsn_data,
903 			     struct wpa_pasn_params_data *pasn_data,
904 			     struct wpabuf *wrapped_data)
905 {
906 	static const u8 pasn_default_pmk[] = {'P', 'M', 'K', 'z'};
907 	struct wpas_pasn *pasn = &wpa_s->pasn;
908 
909 	os_memset(pasn->pmk, 0, sizeof(pasn->pmk));
910 	pasn->pmk_len = 0;
911 
912 	if (pasn->akmp == WPA_KEY_MGMT_PASN) {
913 		wpa_printf(MSG_DEBUG, "PASN: Using default PMK");
914 
915 		pasn->pmk_len = WPA_PASN_PMK_LEN;
916 		os_memcpy(pasn->pmk, pasn_default_pmk,
917 			  sizeof(pasn_default_pmk));
918 		return 0;
919 	}
920 
921 	if (wpa_key_mgmt_ft(pasn->akmp)) {
922 #ifdef CONFIG_IEEE80211R
923 		wpa_printf(MSG_DEBUG, "PASN: FT: Using PMK-R1");
924 		pasn->pmk_len = pasn->pmk_r1_len;
925 		os_memcpy(pasn->pmk, pasn->pmk_r1, pasn->pmk_r1_len);
926 		pasn->using_pmksa = true;
927 		return 0;
928 #else /* CONFIG_IEEE80211R */
929 		wpa_printf(MSG_DEBUG, "PASN: FT: Not supported");
930 		return -1;
931 #endif /* CONFIG_IEEE80211R */
932 	}
933 
934 	if (rsn_data->num_pmkid) {
935 		struct rsn_pmksa_cache_entry *pmksa;
936 
937 		pmksa = wpa_sm_pmksa_cache_get(wpa_s->wpa, pasn->bssid,
938 					       rsn_data->pmkid, NULL,
939 					       pasn->akmp);
940 		if (pmksa) {
941 			wpa_printf(MSG_DEBUG, "PASN: Using PMKSA");
942 
943 			pasn->pmk_len = pmksa->pmk_len;
944 			os_memcpy(pasn->pmk, pmksa->pmk, pmksa->pmk_len);
945 			pasn->using_pmksa = true;
946 
947 			return 0;
948 		}
949 	}
950 
951 #ifdef CONFIG_SAE
952 	if (pasn->akmp == WPA_KEY_MGMT_SAE) {
953 		int ret;
954 
955 		ret = wpas_pasn_wd_sae_rx(wpa_s, wrapped_data);
956 		if (ret) {
957 			wpa_printf(MSG_DEBUG,
958 				   "PASN: Failed processing SAE wrapped data");
959 			pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
960 			return -1;
961 		}
962 
963 		wpa_printf(MSG_DEBUG, "PASN: Success deriving PMK with SAE");
964 		pasn->pmk_len = PMK_LEN;
965 		os_memcpy(pasn->pmk, pasn->sae.pmk, PMK_LEN);
966 
967 		wpa_pasn_pmksa_cache_add(wpa_s->wpa, pasn->pmk,
968 					 pasn->pmk_len, pasn->sae.pmkid,
969 					 pasn->bssid, pasn->akmp);
970 		return 0;
971 	}
972 #endif /* CONFIG_SAE */
973 
974 #ifdef CONFIG_FILS
975 	if (pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
976 	    pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
977 		int ret;
978 
979 		ret = wpas_pasn_wd_fils_rx(wpa_s, wrapped_data);
980 		if (ret) {
981 			wpa_printf(MSG_DEBUG,
982 				   "PASN: Failed processing FILS wrapped data");
983 			pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
984 			return -1;
985 		}
986 
987 		return 0;
988 	}
989 #endif	/* CONFIG_FILS */
990 
991 	/* TODO: Derive PMK based on wrapped data */
992 	wpa_printf(MSG_DEBUG, "PASN: Missing implementation to derive PMK");
993 	pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
994 	return -1;
995 }
996 
997 
wpas_pasn_start(struct wpa_supplicant * wpa_s,const u8 * bssid,int akmp,int cipher,u16 group,int freq,const u8 * beacon_rsne,u8 beacon_rsne_len,const u8 * beacon_rsnxe,u8 beacon_rsnxe_len,int network_id,struct wpabuf * comeback)998 static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
999 			   int akmp, int cipher, u16 group, int freq,
1000 			   const u8 *beacon_rsne, u8 beacon_rsne_len,
1001 			   const u8 *beacon_rsnxe, u8 beacon_rsnxe_len,
1002 			   int network_id, struct wpabuf *comeback)
1003 {
1004 	struct wpas_pasn *pasn = &wpa_s->pasn;
1005 	struct wpa_ssid *ssid = NULL;
1006 	struct wpabuf *frame;
1007 	int ret;
1008 
1009 	/* TODO: Currently support only ECC groups */
1010 	if (!dragonfly_suitable_group(group, 1)) {
1011 		wpa_printf(MSG_DEBUG,
1012 			   "PASN: Reject unsuitable group %u", group);
1013 		return -1;
1014 	}
1015 
1016 	ssid = wpa_config_get_network(wpa_s->conf, network_id);
1017 
1018 	switch (akmp) {
1019 	case WPA_KEY_MGMT_PASN:
1020 		break;
1021 #ifdef CONFIG_SAE
1022 	case WPA_KEY_MGMT_SAE:
1023 		if (!ssid) {
1024 			wpa_printf(MSG_DEBUG,
1025 				   "PASN: No network profile found for SAE");
1026 			return -1;
1027 		}
1028 
1029 		if (!ieee802_11_rsnx_capab(beacon_rsnxe,
1030 					   WLAN_RSNX_CAPAB_SAE_H2E)) {
1031 			wpa_printf(MSG_DEBUG,
1032 				   "PASN: AP does not support SAE H2E");
1033 			return -1;
1034 		}
1035 
1036 		if (wpas_pasn_sae_setup_pt(wpa_s, ssid, group) < 0) {
1037 			wpa_printf(MSG_DEBUG,
1038 				   "PASN: Failed to derive PT");
1039 			return -1;
1040 		}
1041 
1042 		pasn->sae.state = SAE_NOTHING;
1043 		pasn->sae.send_confirm = 0;
1044 		pasn->ssid = ssid;
1045 		break;
1046 #endif /* CONFIG_SAE */
1047 #ifdef CONFIG_FILS
1048 	case WPA_KEY_MGMT_FILS_SHA256:
1049 	case WPA_KEY_MGMT_FILS_SHA384:
1050 		pasn->ssid = ssid;
1051 		break;
1052 #endif /* CONFIG_FILS */
1053 #ifdef CONFIG_IEEE80211R
1054 	case WPA_KEY_MGMT_FT_PSK:
1055 	case WPA_KEY_MGMT_FT_IEEE8021X:
1056 	case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
1057 		break;
1058 #endif /* CONFIG_IEEE80211R */
1059 	default:
1060 		wpa_printf(MSG_ERROR, "PASN: Unsupported AKMP=0x%x", akmp);
1061 		return -1;
1062 	}
1063 
1064 	pasn->ecdh = crypto_ecdh_init(group);
1065 	if (!pasn->ecdh) {
1066 		wpa_printf(MSG_DEBUG, "PASN: Failed to init ECDH");
1067 		goto fail;
1068 	}
1069 
1070 	pasn->beacon_rsne_rsnxe = wpabuf_alloc(beacon_rsne_len +
1071 					       beacon_rsnxe_len);
1072 	if (!pasn->beacon_rsne_rsnxe) {
1073 		wpa_printf(MSG_DEBUG, "PASN: Failed storing beacon RSNE/RSNXE");
1074 		goto fail;
1075 	}
1076 
1077 	wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsne, beacon_rsne_len);
1078 	if (beacon_rsnxe && beacon_rsnxe_len)
1079 		wpabuf_put_data(pasn->beacon_rsne_rsnxe, beacon_rsnxe,
1080 				beacon_rsnxe_len);
1081 
1082 	pasn->akmp = akmp;
1083 	pasn->cipher = cipher;
1084 	pasn->group = group;
1085 	pasn->freq = freq;
1086 
1087 	if (wpa_s->conf->force_kdk_derivation ||
1088 	    (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF &&
1089 	     ieee802_11_rsnx_capab(beacon_rsnxe, WLAN_RSNX_CAPAB_SECURE_LTF)))
1090 		pasn->kdk_len = WPA_KDK_MAX_LEN;
1091 	else
1092 		pasn->kdk_len = 0;
1093 	wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", pasn->kdk_len);
1094 
1095 	os_memcpy(pasn->bssid, bssid, ETH_ALEN);
1096 
1097 	wpa_printf(MSG_DEBUG,
1098 		   "PASN: Init: " MACSTR_SEC " akmp=0x%x, cipher=0x%x, group=%u",
1099 		   MAC2STR_SEC(pasn->bssid), pasn->akmp, pasn->cipher,
1100 		   pasn->group);
1101 
1102 	frame = wpas_pasn_build_auth_1(wpa_s, comeback);
1103 	if (!frame) {
1104 		wpa_printf(MSG_DEBUG, "PASN: Failed building 1st auth frame");
1105 		goto fail;
1106 	}
1107 
1108 	ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(frame), wpabuf_len(frame), 0,
1109 				pasn->freq, 1000);
1110 
1111 	wpabuf_free(frame);
1112 	if (ret) {
1113 		wpa_printf(MSG_DEBUG, "PASN: Failed sending 1st auth frame");
1114 		goto fail;
1115 	}
1116 
1117 	eloop_register_timeout(2, 0, wpas_pasn_auth_work_timeout, wpa_s, NULL);
1118 	return 0;
1119 
1120 fail:
1121 	return -1;
1122 }
1123 
1124 
wpas_pasn_allowed(struct wpa_supplicant * wpa_s,const u8 * bssid,int akmp,int cipher)1125 static struct wpa_bss * wpas_pasn_allowed(struct wpa_supplicant *wpa_s,
1126 					  const u8 *bssid, int akmp, int cipher)
1127 {
1128 	struct wpa_bss *bss;
1129 	const u8 *rsne;
1130 	struct wpa_ie_data rsne_data;
1131 	int ret;
1132 
1133 	if (os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) == 0) {
1134 		wpa_printf(MSG_DEBUG,
1135 			   "PASN: Not doing authentication with current BSS");
1136 		return NULL;
1137 	}
1138 
1139 	bss = wpa_bss_get_bssid(wpa_s, bssid);
1140 	if (!bss) {
1141 		wpa_printf(MSG_DEBUG, "PASN: BSS not found");
1142 		return NULL;
1143 	}
1144 
1145 	rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1146 	if (!rsne) {
1147 		wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
1148 		return NULL;
1149 	}
1150 
1151 	ret = wpa_parse_wpa_ie(rsne, *(rsne + 1) + 2, &rsne_data);
1152 	if (ret) {
1153 		wpa_printf(MSG_DEBUG, "PASN: Failed parsing RSNE data");
1154 		return NULL;
1155 	}
1156 
1157 	if (!(rsne_data.key_mgmt & akmp) ||
1158 	    !(rsne_data.pairwise_cipher & cipher)) {
1159 		wpa_printf(MSG_DEBUG,
1160 			   "PASN: AP does not support requested AKMP or cipher");
1161 		return NULL;
1162 	}
1163 
1164 	return bss;
1165 }
1166 
1167 
wpas_pasn_auth_start_cb(struct wpa_radio_work * work,int deinit)1168 static void wpas_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit)
1169 {
1170 	struct wpa_supplicant *wpa_s = work->wpa_s;
1171 	struct wpa_pasn_auth_work *awork = work->ctx;
1172 	struct wpa_bss *bss;
1173 	const u8 *rsne, *rsnxe;
1174 	int ret;
1175 
1176 	wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: deinit=%d", deinit);
1177 
1178 	if (deinit) {
1179 		if (work->started) {
1180 			eloop_cancel_timeout(wpas_pasn_auth_work_timeout,
1181 					     wpa_s, NULL);
1182 			wpa_s->pasn_auth_work = NULL;
1183 		}
1184 
1185 		wpas_pasn_free_auth_work(awork);
1186 		return;
1187 	}
1188 
1189 	/*
1190 	 * It is possible that by the time the callback is called, the PASN
1191 	 * authentication is not allowed, e.g., a connection with the AP was
1192 	 * established.
1193 	 */
1194 	bss = wpas_pasn_allowed(wpa_s, awork->bssid, awork->akmp,
1195 				awork->cipher);
1196 	if (!bss) {
1197 		wpa_printf(MSG_DEBUG, "PASN: auth_start_cb: Not allowed");
1198 		goto fail;
1199 	}
1200 
1201 	rsne = wpa_bss_get_ie(bss, WLAN_EID_RSN);
1202 	if (!rsne) {
1203 		wpa_printf(MSG_DEBUG, "PASN: BSS without RSNE");
1204 		goto fail;
1205 	}
1206 
1207 	rsnxe = wpa_bss_get_ie(bss, WLAN_EID_RSNX);
1208 
1209 	ret = wpas_pasn_start(wpa_s, awork->bssid, awork->akmp, awork->cipher,
1210 			      awork->group, bss->freq, rsne, *(rsne + 1) + 2,
1211 			      rsnxe, rsnxe ? *(rsnxe + 1) + 2 : 0,
1212 			      awork->network_id, awork->comeback);
1213 	if (ret) {
1214 		wpa_printf(MSG_DEBUG,
1215 			   "PASN: Failed to start PASN authentication");
1216 		goto fail;
1217 	}
1218 
1219 	/* comeback token is no longer needed at this stage */
1220 	wpabuf_free(awork->comeback);
1221 	awork->comeback = NULL;
1222 
1223 	wpa_s->pasn_auth_work = work;
1224 	return;
1225 fail:
1226 	wpas_pasn_free_auth_work(awork);
1227 	work->ctx = NULL;
1228 	radio_work_done(work);
1229 }
1230 
1231 
wpas_pasn_auth_start(struct wpa_supplicant * wpa_s,const u8 * bssid,int akmp,int cipher,u16 group,int network_id,const u8 * comeback,size_t comeback_len)1232 int wpas_pasn_auth_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
1233 			 int akmp, int cipher, u16 group, int network_id,
1234 			 const u8 *comeback, size_t comeback_len)
1235 {
1236 	struct wpa_pasn_auth_work *awork;
1237 	struct wpa_bss *bss;
1238 
1239 	wpa_printf(MSG_DEBUG, "PASN: Start: " MACSTR_SEC " akmp=0x%x, cipher=0x%x",
1240 		   MAC2STR_SEC(bssid), akmp, cipher);
1241 
1242 	/*
1243 	 * TODO: Consider modifying the offchannel logic to handle additional
1244 	 * Management frames other then Action frames. For now allow PASN only
1245 	 * with drivers that support off-channel TX.
1246 	 */
1247 	if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_OFFCHANNEL_TX)) {
1248 		wpa_printf(MSG_DEBUG,
1249 			   "PASN: Driver does not support offchannel TX");
1250 		return -1;
1251 	}
1252 
1253 	if (radio_work_pending(wpa_s, "pasn-start-auth")) {
1254 		wpa_printf(MSG_DEBUG,
1255 			   "PASN: send_auth: Work is already pending");
1256 		return -1;
1257 	}
1258 
1259 	if (wpa_s->pasn_auth_work) {
1260 		wpa_printf(MSG_DEBUG, "PASN: send_auth: Already in progress");
1261 		return -1;
1262 	}
1263 
1264 	bss = wpas_pasn_allowed(wpa_s, bssid, akmp, cipher);
1265 	if (!bss)
1266 		return -1;
1267 
1268 	wpas_pasn_reset(wpa_s);
1269 
1270 	awork = os_zalloc(sizeof(*awork));
1271 	if (!awork)
1272 		return -1;
1273 
1274 	os_memcpy(awork->bssid, bssid, ETH_ALEN);
1275 	awork->akmp = akmp;
1276 	awork->cipher = cipher;
1277 	awork->group = group;
1278 	awork->network_id = network_id;
1279 
1280 	if (comeback && comeback_len) {
1281 		awork->comeback = wpabuf_alloc_copy(comeback, comeback_len);
1282 		if (!awork->comeback) {
1283 			wpas_pasn_free_auth_work(awork);
1284 			return -1;
1285 		}
1286 	}
1287 
1288 	if (radio_add_work(wpa_s, bss->freq, "pasn-start-auth", 1,
1289 			   wpas_pasn_auth_start_cb, awork) < 0) {
1290 		wpas_pasn_free_auth_work(awork);
1291 		return -1;
1292 	}
1293 
1294 	wpa_printf(MSG_DEBUG, "PASN: Auth work successfully added");
1295 	return 0;
1296 }
1297 
1298 
wpas_pasn_auth_stop(struct wpa_supplicant * wpa_s)1299 void wpas_pasn_auth_stop(struct wpa_supplicant *wpa_s)
1300 {
1301 	struct wpas_pasn *pasn = &wpa_s->pasn;
1302 
1303 	if (!wpa_s->pasn.ecdh)
1304 		return;
1305 
1306 	wpa_printf(MSG_DEBUG, "PASN: Stopping authentication");
1307 
1308 	wpas_pasn_auth_status(wpa_s, pasn->bssid, pasn->akmp, pasn->cipher,
1309 			      pasn->status, pasn->comeback,
1310 			      pasn->comeback_after);
1311 
1312 	wpas_pasn_reset(wpa_s);
1313 }
1314 
1315 
wpas_pasn_immediate_retry(struct wpa_supplicant * wpa_s,struct wpas_pasn * pasn,struct wpa_pasn_params_data * params)1316 static int wpas_pasn_immediate_retry(struct wpa_supplicant *wpa_s,
1317 				     struct wpas_pasn *pasn,
1318 				     struct wpa_pasn_params_data *params)
1319 {
1320 	int akmp = pasn->akmp;
1321 	int cipher = pasn->cipher;
1322 	u16 group = pasn->group;
1323 	u8 bssid[ETH_ALEN];
1324 	int network_id = pasn->ssid ? pasn->ssid->id : 0;
1325 
1326 	wpa_printf(MSG_DEBUG, "PASN: Immediate retry");
1327 	os_memcpy(bssid, pasn->bssid, ETH_ALEN);
1328 	wpas_pasn_reset(wpa_s);
1329 
1330 	return wpas_pasn_auth_start(wpa_s, bssid, akmp, cipher, group,
1331 				    network_id,
1332 				    params->comeback, params->comeback_len);
1333 }
1334 
1335 
wpas_pasn_auth_rx(struct wpa_supplicant * wpa_s,const struct ieee80211_mgmt * mgmt,size_t len)1336 int wpas_pasn_auth_rx(struct wpa_supplicant *wpa_s,
1337 		      const struct ieee80211_mgmt *mgmt, size_t len)
1338 {
1339 	struct wpas_pasn *pasn = &wpa_s->pasn;
1340 	struct ieee802_11_elems elems;
1341 	struct wpa_ie_data rsn_data;
1342 	struct wpa_pasn_params_data pasn_params;
1343 	struct wpabuf *wrapped_data = NULL, *secret = NULL, *frame = NULL;
1344 	u8 mic[WPA_PASN_MAX_MIC_LEN], out_mic[WPA_PASN_MAX_MIC_LEN];
1345 	u8 mic_len;
1346 	u16 status;
1347 	int ret, inc_y;
1348 	u16 fc = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
1349 			      (WLAN_FC_STYPE_AUTH << 4));
1350 
1351 	if (!wpa_s->pasn_auth_work || !mgmt ||
1352 	    len < offsetof(struct ieee80211_mgmt, u.auth.variable))
1353 		return -2;
1354 
1355 	/* Not an Authentication frame; do nothing */
1356 	if ((mgmt->frame_control & fc) != fc)
1357 		return -2;
1358 
1359 	/* Not our frame; do nothing */
1360 	if (os_memcmp(mgmt->da, wpa_s->own_addr, ETH_ALEN) != 0 ||
1361 	    os_memcmp(mgmt->sa, pasn->bssid, ETH_ALEN) != 0 ||
1362 	    os_memcmp(mgmt->bssid, pasn->bssid, ETH_ALEN) != 0)
1363 		return -2;
1364 
1365 	/* Not PASN; do nothing */
1366 	if (mgmt->u.auth.auth_alg != host_to_le16(WLAN_AUTH_PASN))
1367 		return -2;
1368 
1369 	if (mgmt->u.auth.auth_transaction !=
1370 	    host_to_le16(pasn->trans_seq + 1)) {
1371 		wpa_printf(MSG_DEBUG,
1372 			   "PASN: RX: Invalid transaction sequence: (%u != %u)",
1373 			   le_to_host16(mgmt->u.auth.auth_transaction),
1374 			   pasn->trans_seq + 1);
1375 		return -1;
1376 	}
1377 
1378 	status = le_to_host16(mgmt->u.auth.status_code);
1379 
1380 	if (status != WLAN_STATUS_SUCCESS &&
1381 	    status != WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
1382 		wpa_printf(MSG_DEBUG,
1383 			   "PASN: Authentication rejected - status=%u", status);
1384 		pasn->status = status;
1385 		wpas_pasn_auth_stop(wpa_s);
1386 		return -1;
1387 	}
1388 
1389 	if (ieee802_11_parse_elems(mgmt->u.auth.variable,
1390 				   len - offsetof(struct ieee80211_mgmt,
1391 						  u.auth.variable),
1392 				   &elems, 0) == ParseFailed) {
1393 		wpa_printf(MSG_DEBUG,
1394 			   "PASN: Failed parsing Authentication frame");
1395 		goto fail;
1396 	}
1397 
1398 	/* Check that the MIC IE exists. Save it and zero out the memory */
1399 	mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
1400 	if (status == WLAN_STATUS_SUCCESS) {
1401 		if (!elems.mic || elems.mic_len != mic_len) {
1402 			wpa_printf(MSG_DEBUG,
1403 				   "PASN: Invalid MIC. Expecting len=%u",
1404 				   mic_len);
1405 			goto fail;
1406 		} else {
1407 			os_memcpy(mic, elems.mic, mic_len);
1408 			/* TODO: Clean this up.. Should not be modifying the
1409 			 * received message buffer. */
1410 			os_memset((u8 *) elems.mic, 0, mic_len);
1411 		}
1412 	}
1413 
1414 	if (!elems.pasn_params || !elems.pasn_params_len) {
1415 		wpa_printf(MSG_DEBUG,
1416 			   "PASN: Missing PASN Parameters IE");
1417 		goto fail;
1418 	}
1419 
1420 	ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
1421 					  elems.pasn_params_len + 3,
1422 					  true, &pasn_params);
1423 	if (ret) {
1424 		wpa_printf(MSG_DEBUG,
1425 			   "PASN: Failed validation PASN of Parameters IE");
1426 		goto fail;
1427 	}
1428 
1429 	if (status == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY) {
1430 		wpa_printf(MSG_DEBUG,
1431 			   "PASN: Authentication temporarily rejected");
1432 
1433 		if (pasn_params.comeback && pasn_params.comeback_len) {
1434 			wpa_printf(MSG_DEBUG,
1435 				   "PASN: Comeback token available. After=%u",
1436 				   pasn_params.after);
1437 
1438 			if (!pasn_params.after)
1439 				return wpas_pasn_immediate_retry(wpa_s, pasn,
1440 								 &pasn_params);
1441 
1442 			pasn->comeback = wpabuf_alloc_copy(
1443 				pasn_params.comeback, pasn_params.comeback_len);
1444 			if (pasn->comeback)
1445 				pasn->comeback_after = pasn_params.after;
1446 		}
1447 
1448 		pasn->status = status;
1449 		goto fail;
1450 	}
1451 
1452 	ret = wpa_parse_wpa_ie(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
1453 			       &rsn_data);
1454 	if (ret) {
1455 		wpa_printf(MSG_DEBUG, "PASN: Failed parsing RNSE");
1456 		goto fail;
1457 	}
1458 
1459 	ret = wpa_pasn_validate_rsne(&rsn_data);
1460 	if (ret) {
1461 		wpa_printf(MSG_DEBUG, "PASN: Failed validating RSNE");
1462 		goto fail;
1463 	}
1464 
1465 	if (pasn->akmp != rsn_data.key_mgmt ||
1466 	    pasn->cipher != rsn_data.pairwise_cipher) {
1467 		wpa_printf(MSG_DEBUG, "PASN: Mismatch in AKMP/cipher");
1468 		goto fail;
1469 	}
1470 
1471 	if (pasn->group != pasn_params.group) {
1472 		wpa_printf(MSG_DEBUG, "PASN: Mismatch in group");
1473 		goto fail;
1474 	}
1475 
1476 	if (!pasn_params.pubkey || !pasn_params.pubkey_len) {
1477 		wpa_printf(MSG_DEBUG, "PASN: Invalid public key");
1478 		goto fail;
1479 	}
1480 
1481 	if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_UNCOMPRESSED) {
1482 		inc_y = 1;
1483 	} else if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_0 ||
1484 		   pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_1) {
1485 		inc_y = 0;
1486 	} else {
1487 		wpa_printf(MSG_DEBUG,
1488 			   "PASN: Invalid first octet in pubkey=0x%x",
1489 			   pasn_params.pubkey[0]);
1490 		goto fail;
1491 	}
1492 
1493 	secret = crypto_ecdh_set_peerkey(pasn->ecdh, inc_y,
1494 					 pasn_params.pubkey + 1,
1495 					 pasn_params.pubkey_len - 1);
1496 
1497 	if (!secret) {
1498 		wpa_printf(MSG_DEBUG, "PASN: Failed to derive shared secret");
1499 		goto fail;
1500 	}
1501 
1502 	if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
1503 		wrapped_data = ieee802_11_defrag(&elems,
1504 						 WLAN_EID_EXTENSION,
1505 						 WLAN_EID_EXT_WRAPPED_DATA);
1506 
1507 		if (!wrapped_data) {
1508 			wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
1509 			goto fail;
1510 		}
1511 	}
1512 
1513 	ret = wpas_pasn_set_pmk(wpa_s, &rsn_data, &pasn_params, wrapped_data);
1514 	if (ret) {
1515 		wpa_printf(MSG_DEBUG, "PASN: Failed to set PMK");
1516 		goto fail;
1517 	}
1518 
1519 	ret = pasn_pmk_to_ptk(pasn->pmk, pasn->pmk_len,
1520 			      wpa_s->own_addr, pasn->bssid,
1521 			      wpabuf_head(secret), wpabuf_len(secret),
1522 			      &pasn->ptk, pasn->akmp, pasn->cipher,
1523 			      pasn->kdk_len);
1524 	if (ret) {
1525 		wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
1526 		goto fail;
1527 	}
1528 
1529 	wpabuf_free(wrapped_data);
1530 	wrapped_data = NULL;
1531 	wpabuf_free(secret);
1532 	secret = NULL;
1533 
1534 	/* Verify the MIC */
1535 	ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
1536 		       pasn->bssid, wpa_s->own_addr,
1537 		       wpabuf_head(pasn->beacon_rsne_rsnxe),
1538 		       wpabuf_len(pasn->beacon_rsne_rsnxe),
1539 		       (u8 *) &mgmt->u.auth,
1540 		       len - offsetof(struct ieee80211_mgmt, u.auth),
1541 		       out_mic);
1542 
1543 	wpa_hexdump_key(MSG_DEBUG, "PASN: Frame MIC", mic, mic_len);
1544 	if (ret || os_memcmp(mic, out_mic, mic_len) != 0) {
1545 		wpa_printf(MSG_DEBUG, "PASN: Failed MIC verification");
1546 		goto fail;
1547 	}
1548 
1549 	pasn->trans_seq++;
1550 
1551 	wpa_printf(MSG_DEBUG, "PASN: Success verifying Authentication frame");
1552 
1553 	frame = wpas_pasn_build_auth_3(wpa_s);
1554 	if (!frame) {
1555 		wpa_printf(MSG_DEBUG, "PASN: Failed building 3rd auth frame");
1556 		goto fail;
1557 	}
1558 
1559 	ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(frame), wpabuf_len(frame), 0,
1560 				pasn->freq, 100);
1561 	wpabuf_free(frame);
1562 	if (ret) {
1563 		wpa_printf(MSG_DEBUG, "PASN: Failed sending 3st auth frame");
1564 		goto fail;
1565 	}
1566 
1567 	wpa_printf(MSG_DEBUG, "PASN: Success sending last frame. Store PTK");
1568 
1569 	ptksa_cache_add(wpa_s->ptksa, pasn->bssid, pasn->cipher,
1570 			dot11RSNAConfigPMKLifetime, &pasn->ptk);
1571 
1572 	forced_memzero(&pasn->ptk, sizeof(pasn->ptk));
1573 
1574 	pasn->status = WLAN_STATUS_SUCCESS;
1575 	return 0;
1576 fail:
1577 	wpa_printf(MSG_DEBUG, "PASN: Failed RX processing - terminating");
1578 	wpabuf_free(wrapped_data);
1579 	wpabuf_free(secret);
1580 
1581 	/*
1582 	 * TODO: In case of an error the standard allows to silently drop
1583 	 * the frame and terminate the authentication exchange. However, better
1584 	 * reply to the AP with an error status.
1585 	 */
1586 	if (status == WLAN_STATUS_SUCCESS)
1587 		pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
1588 	else
1589 		pasn->status = status;
1590 
1591 	wpas_pasn_auth_stop(wpa_s);
1592 	return -1;
1593 }
1594 
1595 
wpas_pasn_auth_tx_status(struct wpa_supplicant * wpa_s,const u8 * data,size_t data_len,u8 acked)1596 int wpas_pasn_auth_tx_status(struct wpa_supplicant *wpa_s,
1597 			     const u8 *data, size_t data_len, u8 acked)
1598 
1599 {
1600 	struct wpas_pasn *pasn = &wpa_s->pasn;
1601 	const struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) data;
1602 	u16 fc = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
1603 			      (WLAN_FC_STYPE_AUTH << 4));
1604 
1605 	wpa_printf(MSG_DEBUG, "PASN: auth_tx_status: acked=%u", acked);
1606 
1607 	if (!wpa_s->pasn_auth_work) {
1608 		wpa_printf(MSG_DEBUG,
1609 			   "PASN: auth_tx_status: no work in progress");
1610 		return -1;
1611 	}
1612 
1613 	if (!mgmt ||
1614 	    data_len < offsetof(struct ieee80211_mgmt, u.auth.variable))
1615 		return -1;
1616 
1617 	/* Not an authentication frame; do nothing */
1618 	if ((mgmt->frame_control & fc) != fc)
1619 		return -1;
1620 
1621 	/* Not our frame; do nothing */
1622 	if (os_memcmp(mgmt->da, pasn->bssid, ETH_ALEN) ||
1623 	    os_memcmp(mgmt->sa, wpa_s->own_addr, ETH_ALEN) ||
1624 	    os_memcmp(mgmt->bssid, pasn->bssid, ETH_ALEN))
1625 		return -1;
1626 
1627 	/* Not PASN; do nothing */
1628 	if (mgmt->u.auth.auth_alg !=  host_to_le16(WLAN_AUTH_PASN))
1629 		return -1;
1630 
1631 	if (mgmt->u.auth.auth_transaction != host_to_le16(pasn->trans_seq)) {
1632 		wpa_printf(MSG_ERROR,
1633 			   "PASN: Invalid transaction sequence: (%u != %u)",
1634 			   pasn->trans_seq,
1635 			   le_to_host16(mgmt->u.auth.auth_transaction));
1636 		return 0;
1637 	}
1638 
1639 	wpa_printf(MSG_ERROR,
1640 		   "PASN: auth with trans_seq=%u, acked=%u", pasn->trans_seq,
1641 		   acked);
1642 
1643 	/*
1644 	 * Even if the frame was not acked, do not treat this is an error, and
1645 	 * try to complete the flow, relying on the PASN timeout callback to
1646 	 * clean up.
1647 	 */
1648 	if (pasn->trans_seq == 3) {
1649 		wpa_printf(MSG_DEBUG, "PASN: auth complete with: " MACSTR_SEC,
1650 			   MAC2STR_SEC(pasn->bssid));
1651 		/*
1652 		 * Either frame was not ACKed or it was ACKed but the trans_seq
1653 		 * != 1, i.e., not expecting an RX frame, so we are done.
1654 		 */
1655 		wpas_pasn_auth_stop(wpa_s);
1656 	}
1657 
1658 	return 0;
1659 }
1660 
1661 
wpas_pasn_deauthenticate(struct wpa_supplicant * wpa_s,const u8 * bssid)1662 int wpas_pasn_deauthenticate(struct wpa_supplicant *wpa_s, const u8 *bssid)
1663 {
1664 	struct wpa_bss *bss;
1665 	struct wpabuf *buf;
1666 	struct ieee80211_mgmt *deauth;
1667 	int ret;
1668 
1669 	if (os_memcmp(wpa_s->bssid, bssid, ETH_ALEN) == 0) {
1670 		wpa_printf(MSG_DEBUG,
1671 			   "PASN: Cannot deauthenticate from current BSS");
1672 		return -1;
1673 	}
1674 
1675 	wpa_printf(MSG_DEBUG, "PASN: deauth: Flushing all PTKSA entries for "
1676 		   MACSTR_SEC, MAC2STR_SEC(bssid));
1677 	ptksa_cache_flush(wpa_s->ptksa, bssid, WPA_CIPHER_NONE);
1678 
1679 	bss = wpa_bss_get_bssid(wpa_s, bssid);
1680 	if (!bss) {
1681 		wpa_printf(MSG_DEBUG, "PASN: deauth: BSS not found");
1682 		return -1;
1683 	}
1684 
1685 	buf = wpabuf_alloc(64);
1686 	if (!buf) {
1687 		wpa_printf(MSG_DEBUG, "PASN: deauth: Failed wpabuf allocate");
1688 		return -1;
1689 	}
1690 
1691 	deauth = wpabuf_put(buf, offsetof(struct ieee80211_mgmt,
1692 					  u.deauth.variable));
1693 
1694 	deauth->frame_control = host_to_le16((WLAN_FC_TYPE_MGMT << 2) |
1695 					     (WLAN_FC_STYPE_DEAUTH << 4));
1696 
1697 	os_memcpy(deauth->da, bssid, ETH_ALEN);
1698 	os_memcpy(deauth->sa, wpa_s->own_addr, ETH_ALEN);
1699 	os_memcpy(deauth->bssid, bssid, ETH_ALEN);
1700 	deauth->u.deauth.reason_code =
1701 		host_to_le16(WLAN_REASON_PREV_AUTH_NOT_VALID);
1702 
1703 	/*
1704 	 * Since we do not expect any response from the AP, implement the
1705 	 * Deauthentication frame transmission using direct call to the driver
1706 	 * without a radio work.
1707 	 */
1708 	ret = wpa_drv_send_mlme(wpa_s, wpabuf_head(buf), wpabuf_len(buf), 1,
1709 				bss->freq, 0);
1710 
1711 	wpabuf_free(buf);
1712 	wpa_printf(MSG_DEBUG, "PASN: deauth: send_mlme ret=%d", ret);
1713 
1714 	return ret;
1715 }
1716