xref: /freebsd/contrib/wpa/src/pasn/pasn_responder.c (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
1 /*
2  * PASN responder processing
3  *
4  * Copyright (C) 2019, Intel Corporation
5  * Copyright (C) 2022, Qualcomm Innovation Center, Inc.
6  *
7  * This software may be distributed under the terms of the BSD license.
8  * See README for more details.
9  */
10 
11 #include "utils/includes.h"
12 
13 #include "utils/common.h"
14 #include "common/wpa_common.h"
15 #include "common/sae.h"
16 #include "common/ieee802_11_common.h"
17 #include "common/ieee802_11_defs.h"
18 #include "crypto/sha384.h"
19 #include "crypto/sha256.h"
20 #include "crypto/random.h"
21 #include "crypto/crypto.h"
22 #include "ap/hostapd.h"
23 #include "ap/comeback_token.h"
24 #include "ap/ieee802_1x.h"
25 #include "ap/pmksa_cache_auth.h"
26 #include "pasn_common.h"
27 
28 
29 void pasn_set_responder_pmksa(struct pasn_data *pasn,
30 			      struct rsn_pmksa_cache *pmksa)
31 {
32 	if (pasn)
33 		pasn->pmksa = pmksa;
34 }
35 
36 
37 #ifdef CONFIG_PASN
38 #ifdef CONFIG_SAE
39 
40 static int pasn_wd_handle_sae_commit(struct pasn_data *pasn,
41 				     const u8 *own_addr, const u8 *peer_addr,
42 				     struct wpabuf *wd)
43 {
44 	const u8 *data;
45 	size_t buf_len;
46 	u16 res, alg, seq, status;
47 	int groups[] = { pasn->group, 0 };
48 	int ret;
49 
50 	if (!wd)
51 		return -1;
52 
53 	data = wpabuf_head_u8(wd);
54 	buf_len = wpabuf_len(wd);
55 
56 	if (buf_len < 6) {
57 		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
58 			   buf_len);
59 		return -1;
60 	}
61 
62 	alg = WPA_GET_LE16(data);
63 	seq = WPA_GET_LE16(data + 2);
64 	status = WPA_GET_LE16(data + 4);
65 
66 	wpa_printf(MSG_DEBUG, "PASN: SAE commit: alg=%u, seq=%u, status=%u",
67 		   alg, seq, status);
68 
69 	if (alg != WLAN_AUTH_SAE || seq != 1 ||
70 	    status != WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
71 		wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE commit");
72 		return -1;
73 	}
74 
75 	sae_clear_data(&pasn->sae);
76 	pasn->sae.state = SAE_NOTHING;
77 
78 	ret = sae_set_group(&pasn->sae, pasn->group);
79 	if (ret) {
80 		wpa_printf(MSG_DEBUG, "PASN: Failed to set SAE group");
81 		return -1;
82 	}
83 
84 	if (!pasn->password || !pasn->pt) {
85 		wpa_printf(MSG_DEBUG, "PASN: No SAE PT found");
86 		return -1;
87 	}
88 
89 	ret = sae_prepare_commit_pt(&pasn->sae, pasn->pt, own_addr, peer_addr,
90 				    NULL, NULL);
91 	if (ret) {
92 		wpa_printf(MSG_DEBUG, "PASN: Failed to prepare SAE commit");
93 		return -1;
94 	}
95 
96 	res = sae_parse_commit(&pasn->sae, data + 6, buf_len - 6, NULL, 0,
97 			       groups, 0, NULL);
98 	if (res != WLAN_STATUS_SUCCESS) {
99 		wpa_printf(MSG_DEBUG, "PASN: Failed parsing SAE commit");
100 		return -1;
101 	}
102 
103 	/* Process the commit message and derive the PMK */
104 	ret = sae_process_commit(&pasn->sae);
105 	if (ret) {
106 		wpa_printf(MSG_DEBUG, "SAE: Failed to process peer commit");
107 		return -1;
108 	}
109 
110 	pasn->sae.state = SAE_COMMITTED;
111 
112 	return 0;
113 }
114 
115 
116 static int pasn_wd_handle_sae_confirm(struct pasn_data *pasn,
117 				      const u8 *peer_addr, struct wpabuf *wd)
118 {
119 	const u8 *data;
120 	size_t buf_len;
121 	u16 res, alg, seq, status;
122 
123 	if (!wd)
124 		return -1;
125 
126 	data = wpabuf_head_u8(wd);
127 	buf_len = wpabuf_len(wd);
128 
129 	if (buf_len < 6) {
130 		wpa_printf(MSG_DEBUG, "PASN: SAE buffer too short. len=%zu",
131 			   buf_len);
132 		return -1;
133 	}
134 
135 	alg = WPA_GET_LE16(data);
136 	seq = WPA_GET_LE16(data + 2);
137 	status = WPA_GET_LE16(data + 4);
138 
139 	wpa_printf(MSG_DEBUG, "PASN: SAE confirm: alg=%u, seq=%u, status=%u",
140 		   alg, seq, status);
141 
142 	if (alg != WLAN_AUTH_SAE || seq != 2 || status != WLAN_STATUS_SUCCESS) {
143 		wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE confirm");
144 		return -1;
145 	}
146 
147 	res = sae_check_confirm(&pasn->sae, data + 6, buf_len - 6, NULL);
148 	if (res != WLAN_STATUS_SUCCESS) {
149 		wpa_printf(MSG_DEBUG, "PASN: SAE failed checking confirm");
150 		return -1;
151 	}
152 
153 	pasn->sae.state = SAE_ACCEPTED;
154 
155 	/*
156 	 * TODO: Based on on IEEE P802.11az/D2.6, the PMKSA derived with
157 	 * PASN/SAE should only be allowed with future PASN only. For now do not
158 	 * restrict this only for PASN.
159 	 */
160 	if (pasn->disable_pmksa_caching)
161 		return 0;
162 
163 	wpa_hexdump_key(MSG_DEBUG, "RSN: Cache PMK from SAE",
164 			pasn->sae.pmk, pasn->sae.pmk_len);
165 	if (!pasn->sae.akmp)
166 		pasn->sae.akmp = WPA_KEY_MGMT_SAE;
167 
168 	pmksa_cache_auth_add(pasn->pmksa, pasn->sae.pmk, pasn->sae.pmk_len,
169 			     pasn->sae.pmkid, NULL, 0, pasn->own_addr,
170 			     peer_addr, 0, NULL, pasn->sae.akmp);
171 	return 0;
172 }
173 
174 
175 static struct wpabuf * pasn_get_sae_wd(struct pasn_data *pasn)
176 {
177 	struct wpabuf *buf = NULL;
178 	u8 *len_ptr;
179 	size_t len;
180 
181 	/* Need to add the entire Authentication frame body */
182 	buf = wpabuf_alloc(8 + SAE_COMMIT_MAX_LEN + 8 + SAE_CONFIRM_MAX_LEN);
183 	if (!buf) {
184 		wpa_printf(MSG_DEBUG, "PASN: Failed to allocate SAE buffer");
185 		return NULL;
186 	}
187 
188 	/* Need to add the entire authentication frame body for the commit */
189 	len_ptr = wpabuf_put(buf, 2);
190 	wpabuf_put_le16(buf, WLAN_AUTH_SAE);
191 	wpabuf_put_le16(buf, 1);
192 	wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
193 
194 	/* Write the actual commit and update the length accordingly */
195 	sae_write_commit(&pasn->sae, buf, NULL, 0);
196 	len = wpabuf_len(buf);
197 	WPA_PUT_LE16(len_ptr, len - 2);
198 
199 	/* Need to add the entire Authentication frame body for the confirm */
200 	len_ptr = wpabuf_put(buf, 2);
201 	wpabuf_put_le16(buf, WLAN_AUTH_SAE);
202 	wpabuf_put_le16(buf, 2);
203 	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
204 
205 	sae_write_confirm(&pasn->sae, buf);
206 	WPA_PUT_LE16(len_ptr, wpabuf_len(buf) - len - 2);
207 
208 	pasn->sae.state = SAE_CONFIRMED;
209 
210 	return buf;
211 }
212 
213 #endif /* CONFIG_SAE */
214 
215 
216 #ifdef CONFIG_FILS
217 
218 static struct wpabuf * pasn_get_fils_wd(struct pasn_data *pasn)
219 {
220 	struct pasn_fils *fils = &pasn->fils;
221 	struct wpabuf *buf = NULL;
222 
223 	if (!fils->erp_resp) {
224 		wpa_printf(MSG_DEBUG, "PASN: FILS: Missing erp_resp");
225 		return NULL;
226 	}
227 
228 	buf = wpabuf_alloc(1500);
229 	if (!buf)
230 		return NULL;
231 
232 	/* Add the authentication algorithm */
233 	wpabuf_put_le16(buf, WLAN_AUTH_FILS_SK);
234 
235 	/* Authentication Transaction seq# */
236 	wpabuf_put_le16(buf, 2);
237 
238 	/* Status Code */
239 	wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
240 
241 	/* Own RSNE */
242 	wpa_pasn_add_rsne(buf, NULL, pasn->akmp, pasn->cipher);
243 
244 	/* FILS Nonce */
245 	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
246 	wpabuf_put_u8(buf, 1 + FILS_NONCE_LEN);
247 	wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_NONCE);
248 	wpabuf_put_data(buf, fils->anonce, FILS_NONCE_LEN);
249 
250 	/* FILS Session */
251 	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
252 	wpabuf_put_u8(buf, 1 + FILS_SESSION_LEN);
253 	wpabuf_put_u8(buf, WLAN_EID_EXT_FILS_SESSION);
254 	wpabuf_put_data(buf, fils->session, FILS_SESSION_LEN);
255 
256 	/* Wrapped Data */
257 	wpabuf_put_u8(buf, WLAN_EID_EXTENSION);
258 	wpabuf_put_u8(buf, 1 + wpabuf_len(fils->erp_resp));
259 	wpabuf_put_u8(buf, WLAN_EID_EXT_WRAPPED_DATA);
260 	wpabuf_put_buf(buf, fils->erp_resp);
261 
262 	return buf;
263 }
264 
265 #endif /* CONFIG_FILS */
266 
267 static struct wpabuf * pasn_get_wrapped_data(struct pasn_data *pasn)
268 {
269 	switch (pasn->akmp) {
270 	case WPA_KEY_MGMT_PASN:
271 		/* no wrapped data */
272 		return NULL;
273 	case WPA_KEY_MGMT_SAE:
274 #ifdef CONFIG_SAE
275 		return pasn_get_sae_wd(pasn);
276 #else /* CONFIG_SAE */
277 		wpa_printf(MSG_ERROR,
278 			   "PASN: SAE: Cannot derive wrapped data");
279 		return NULL;
280 #endif /* CONFIG_SAE */
281 	case WPA_KEY_MGMT_FILS_SHA256:
282 	case WPA_KEY_MGMT_FILS_SHA384:
283 #ifdef CONFIG_FILS
284 		return pasn_get_fils_wd(pasn);
285 #endif /* CONFIG_FILS */
286 		/* fall through */
287 	case WPA_KEY_MGMT_FT_PSK:
288 	case WPA_KEY_MGMT_FT_IEEE8021X:
289 	case WPA_KEY_MGMT_FT_IEEE8021X_SHA384:
290 	default:
291 		wpa_printf(MSG_ERROR,
292 			   "PASN: TODO: Wrapped data for akmp=0x%x",
293 			   pasn->akmp);
294 		return NULL;
295 	}
296 }
297 
298 
299 static int
300 pasn_derive_keys(struct pasn_data *pasn,
301 		 const u8 *own_addr, const u8 *peer_addr,
302 		 const u8 *cached_pmk, size_t cached_pmk_len,
303 		 struct wpa_pasn_params_data *pasn_data,
304 		 struct wpabuf *wrapped_data,
305 		 struct wpabuf *secret)
306 {
307 	static const u8 pasn_default_pmk[] = {'P', 'M', 'K', 'z'};
308 	u8 pmk[PMK_LEN_MAX];
309 	u8 pmk_len;
310 	int ret;
311 
312 	os_memset(pmk, 0, sizeof(pmk));
313 	pmk_len = 0;
314 
315 	if (!cached_pmk || !cached_pmk_len)
316 		wpa_printf(MSG_DEBUG, "PASN: No valid PMKSA entry");
317 
318 	if (pasn->akmp == WPA_KEY_MGMT_PASN) {
319 		wpa_printf(MSG_DEBUG, "PASN: Using default PMK");
320 
321 		pmk_len = WPA_PASN_PMK_LEN;
322 		os_memcpy(pmk, pasn_default_pmk, sizeof(pasn_default_pmk));
323 	} else if (cached_pmk && cached_pmk_len) {
324 		wpa_printf(MSG_DEBUG, "PASN: Using PMKSA entry");
325 
326 		pmk_len = cached_pmk_len;
327 		os_memcpy(pmk, cached_pmk, cached_pmk_len);
328 	} else {
329 		switch (pasn->akmp) {
330 #ifdef CONFIG_SAE
331 		case WPA_KEY_MGMT_SAE:
332 			if (pasn->sae.state == SAE_COMMITTED) {
333 				pmk_len = PMK_LEN;
334 				os_memcpy(pmk, pasn->sae.pmk, PMK_LEN);
335 				break;
336 			}
337 #endif /* CONFIG_SAE */
338 			/* fall through */
339 		default:
340 			/* TODO: Derive PMK based on wrapped data */
341 			wpa_printf(MSG_DEBUG,
342 				   "PASN: Missing PMK derivation");
343 			return -1;
344 		}
345 	}
346 
347 	pasn->pmk_len = pmk_len;
348 	os_memcpy(pasn->pmk, pmk, pmk_len);
349 	ret = pasn_pmk_to_ptk(pmk, pmk_len, peer_addr, own_addr,
350 			      wpabuf_head(secret), wpabuf_len(secret),
351 			      &pasn->ptk, pasn->akmp,
352 			      pasn->cipher, pasn->kdk_len);
353 	if (ret) {
354 		wpa_printf(MSG_DEBUG, "PASN: Failed to derive PTK");
355 		return -1;
356 	}
357 
358 	if (pasn->secure_ltf) {
359 		ret = wpa_ltf_keyseed(&pasn->ptk, pasn->akmp,
360 				      pasn->cipher);
361 		if (ret) {
362 			wpa_printf(MSG_DEBUG,
363 				   "PASN: Failed to derive LTF keyseed");
364 			return -1;
365 		}
366 	}
367 
368 	wpa_printf(MSG_DEBUG, "PASN: PTK successfully derived");
369 	return 0;
370 }
371 
372 
373 static void handle_auth_pasn_comeback(struct pasn_data *pasn,
374 				      const u8 *own_addr, const u8 *peer_addr,
375 				      u16 group)
376 {
377 	struct wpabuf *buf, *comeback;
378 	int ret;
379 
380 	wpa_printf(MSG_DEBUG,
381 		   "PASN: Building comeback frame 2. Comeback after=%u",
382 		   pasn->comeback_after);
383 
384 	buf = wpabuf_alloc(1500);
385 	if (!buf)
386 		return;
387 
388 	wpa_pasn_build_auth_header(buf, pasn->bssid, own_addr, peer_addr, 2,
389 				   WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY);
390 
391 	/*
392 	 * Do not include the group as a part of the token since it is not going
393 	 * to be used.
394 	 */
395 	comeback = auth_build_token_req(&pasn->last_comeback_key_update,
396 					pasn->comeback_key, pasn->comeback_idx,
397 					pasn->comeback_pending_idx,
398 					sizeof(u16) * COMEBACK_PENDING_IDX_SIZE,
399 					0, peer_addr, 0);
400 	if (!comeback) {
401 		wpa_printf(MSG_DEBUG,
402 			   "PASN: Failed sending auth with comeback");
403 		wpabuf_free(buf);
404 		return;
405 	}
406 
407 	wpa_pasn_add_parameter_ie(buf, group,
408 				  WPA_PASN_WRAPPED_DATA_NO,
409 				  NULL, 0, comeback,
410 				  pasn->comeback_after);
411 	wpabuf_free(comeback);
412 
413 	wpa_printf(MSG_DEBUG,
414 		   "PASN: comeback: STA=" MACSTR, MAC2STR(peer_addr));
415 
416 	ret = pasn->send_mgmt(pasn->cb_ctx, wpabuf_head_u8(buf),
417 			      wpabuf_len(buf), 0, 0, 0);
418 	if (ret)
419 		wpa_printf(MSG_INFO, "PASN: Failed to send comeback frame 2");
420 
421 	wpabuf_free(buf);
422 }
423 
424 
425 int handle_auth_pasn_resp(struct pasn_data *pasn, const u8 *own_addr,
426 			  const u8 *peer_addr,
427 			  struct rsn_pmksa_cache_entry *pmksa, u16 status)
428 {
429 	struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL;
430 	struct wpabuf *rsn_buf = NULL;
431 	u8 mic[WPA_PASN_MAX_MIC_LEN];
432 	u8 mic_len;
433 	u8 *ptr;
434 	const u8 *frame, *data, *rsn_ie, *rsnxe_ie;
435 	u8 *data_buf = NULL;
436 	size_t frame_len, data_len;
437 	int ret;
438 	const u8 *pmkid = NULL;
439 
440 	wpa_printf(MSG_DEBUG, "PASN: Building frame 2: status=%u", status);
441 
442 	buf = wpabuf_alloc(1500);
443 	if (!buf)
444 		goto fail;
445 
446 	wpa_pasn_build_auth_header(buf, pasn->bssid, own_addr, peer_addr, 2,
447 				   status);
448 
449 	if (status != WLAN_STATUS_SUCCESS)
450 		goto done;
451 
452 	if (pmksa && pasn->custom_pmkid_valid)
453 		pmkid = pasn->custom_pmkid;
454 	else if (pmksa) {
455 		pmkid = pmksa->pmkid;
456 #ifdef CONFIG_SAE
457 	} else if (pasn->akmp == WPA_KEY_MGMT_SAE) {
458 		wpa_printf(MSG_DEBUG, "PASN: Use SAE PMKID");
459 		pmkid = pasn->sae.pmkid;
460 #endif /* CONFIG_SAE */
461 #ifdef CONFIG_FILS
462 	} else if (pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
463 		   pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
464 		wpa_printf(MSG_DEBUG, "PASN: Use FILS ERP PMKID");
465 		pmkid = pasn->fils.erp_pmkid;
466 #endif /* CONFIG_FILS */
467 	}
468 
469 	if (wpa_pasn_add_rsne(buf, pmkid,
470 			      pasn->akmp, pasn->cipher) < 0)
471 		goto fail;
472 
473 	/* No need to derive PMK if PMKSA is given */
474 	if (!pmksa)
475 		wrapped_data_buf = pasn_get_wrapped_data(pasn);
476 	else
477 		pasn->wrapped_data_format = WPA_PASN_WRAPPED_DATA_NO;
478 
479 	/* Get public key */
480 	pubkey = crypto_ecdh_get_pubkey(pasn->ecdh, 0);
481 	pubkey = wpabuf_zeropad(pubkey,
482 				crypto_ecdh_prime_len(pasn->ecdh));
483 	if (!pubkey) {
484 		wpa_printf(MSG_DEBUG, "PASN: Failed to get pubkey");
485 		goto fail;
486 	}
487 
488 	wpa_pasn_add_parameter_ie(buf, pasn->group,
489 				  pasn->wrapped_data_format,
490 				  pubkey, true, NULL, 0);
491 
492 	if (wpa_pasn_add_wrapped_data(buf, wrapped_data_buf) < 0)
493 		goto fail;
494 
495 	wpabuf_free(wrapped_data_buf);
496 	wrapped_data_buf = NULL;
497 	wpabuf_free(pubkey);
498 	pubkey = NULL;
499 
500 	/* Add RSNXE if needed */
501 	rsnxe_ie = pasn->rsnxe_ie;
502 	if (rsnxe_ie)
503 		wpabuf_put_data(buf, rsnxe_ie, 2 + rsnxe_ie[1]);
504 
505 	wpa_pasn_add_extra_ies(buf, pasn->extra_ies, pasn->extra_ies_len);
506 
507 	/* Add the mic */
508 	mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
509 	wpabuf_put_u8(buf, WLAN_EID_MIC);
510 	wpabuf_put_u8(buf, mic_len);
511 	ptr = wpabuf_put(buf, mic_len);
512 
513 	os_memset(ptr, 0, mic_len);
514 
515 	frame = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
516 	frame_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
517 
518 	if (pasn->rsn_ie && pasn->rsn_ie_len) {
519 		rsn_ie = pasn->rsn_ie;
520 	} else {
521 		/*
522 		 * Note: when pasn->rsn_ie is NULL, it is likely that Beacon
523 		 * frame RSNE is not initialized. This is possible in case of
524 		 * PASN authentication used for Wi-Fi Aware for which Beacon
525 		 * frame RSNE and RSNXE are same as RSNE and RSNXE in the
526 		 * Authentication frame.
527 		 */
528 		rsn_buf = wpabuf_alloc(500);
529 		if (!rsn_buf)
530 			goto fail;
531 
532 		if (wpa_pasn_add_rsne(rsn_buf, pmkid,
533 				      pasn->akmp, pasn->cipher) < 0)
534 			goto fail;
535 
536 		rsn_ie = wpabuf_head_u8(rsn_buf);
537 	}
538 
539 	/*
540 	 * Note: wpa_auth_get_wpa_ie() might return not only the RSNE but also
541 	 * MDE, etc. Thus, do not use the returned length but instead use the
542 	 * length specified in the IE header.
543 	 */
544 	data_len = rsn_ie[1] + 2;
545 	if (rsnxe_ie) {
546 		data_buf = os_zalloc(rsn_ie[1] + 2 + rsnxe_ie[1] + 2);
547 		if (!data_buf)
548 			goto fail;
549 
550 		os_memcpy(data_buf, rsn_ie, rsn_ie[1] + 2);
551 		os_memcpy(data_buf + rsn_ie[1] + 2, rsnxe_ie, rsnxe_ie[1] + 2);
552 		data_len += rsnxe_ie[1] + 2;
553 		data = data_buf;
554 	} else {
555 		data = rsn_ie;
556 	}
557 
558 	ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
559 		       own_addr, peer_addr, data, data_len,
560 		       frame, frame_len, mic);
561 	os_free(data_buf);
562 	if (ret) {
563 		wpa_printf(MSG_DEBUG, "PASN: Frame 3: Failed MIC calculation");
564 		goto fail;
565 	}
566 
567 #ifdef CONFIG_TESTING_OPTIONS
568 	if (pasn->corrupt_mic) {
569 		wpa_printf(MSG_DEBUG, "PASN: frame 2: Corrupt MIC");
570 		mic[0] = ~mic[0];
571 	}
572 #endif /* CONFIG_TESTING_OPTIONS */
573 
574 	os_memcpy(ptr, mic, mic_len);
575 
576 done:
577 	wpa_printf(MSG_DEBUG,
578 		   "PASN: Building frame 2: success; resp STA=" MACSTR,
579 		   MAC2STR(peer_addr));
580 
581 	ret = pasn->send_mgmt(pasn->cb_ctx, wpabuf_head_u8(buf),
582 			      wpabuf_len(buf), 0, 0, 0);
583 	if (ret)
584 		wpa_printf(MSG_INFO, "send_auth_reply: Send failed");
585 
586 	wpabuf_free(rsn_buf);
587 	wpabuf_free(buf);
588 	return ret;
589 fail:
590 	wpabuf_free(wrapped_data_buf);
591 	wpabuf_free(pubkey);
592 	wpabuf_free(rsn_buf);
593 	wpabuf_free(buf);
594 	return -1;
595 }
596 
597 
598 int handle_auth_pasn_1(struct pasn_data *pasn,
599 		       const u8 *own_addr, const u8 *peer_addr,
600 		       const struct ieee80211_mgmt *mgmt, size_t len)
601 {
602 	struct ieee802_11_elems elems;
603 	struct wpa_ie_data rsn_data;
604 	struct wpa_pasn_params_data pasn_params;
605 	struct rsn_pmksa_cache_entry *pmksa = NULL;
606 	const u8 *cached_pmk = NULL;
607 	size_t cached_pmk_len = 0;
608 	struct wpabuf *wrapped_data = NULL, *secret = NULL;
609 	const int *groups = pasn->pasn_groups;
610 	static const int default_groups[] = { 19, 0 };
611 	u16 status = WLAN_STATUS_SUCCESS;
612 	int ret, inc_y;
613 	bool derive_keys;
614 	u32 i;
615 
616 	if (!groups)
617 		groups = default_groups;
618 
619 	if (ieee802_11_parse_elems(mgmt->u.auth.variable,
620 				   len - offsetof(struct ieee80211_mgmt,
621 						  u.auth.variable),
622 				   &elems, 0) == ParseFailed) {
623 		wpa_printf(MSG_DEBUG,
624 			   "PASN: Failed parsing Authentication frame");
625 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
626 		goto send_resp;
627 	}
628 
629 	if (!elems.rsn_ie) {
630 		wpa_printf(MSG_DEBUG, "PASN: No RSNE");
631 		status = WLAN_STATUS_INVALID_RSNIE;
632 		goto send_resp;
633 	}
634 
635 	ret = wpa_parse_wpa_ie_rsn(elems.rsn_ie - 2, elems.rsn_ie_len + 2,
636 				   &rsn_data);
637 	if (ret) {
638 		wpa_printf(MSG_DEBUG, "PASN: Failed parsing RSNE");
639 		status = WLAN_STATUS_INVALID_RSNIE;
640 		goto send_resp;
641 	}
642 
643 	ret = wpa_pasn_validate_rsne(&rsn_data);
644 	if (ret) {
645 		wpa_printf(MSG_DEBUG, "PASN: Failed validating RSNE");
646 		status = WLAN_STATUS_INVALID_RSNIE;
647 		goto send_resp;
648 	}
649 
650 	if (!(rsn_data.key_mgmt & pasn->wpa_key_mgmt) ||
651 	    !(rsn_data.pairwise_cipher & pasn->rsn_pairwise)) {
652 		wpa_printf(MSG_DEBUG, "PASN: Mismatch in AKMP/cipher");
653 		status = WLAN_STATUS_INVALID_RSNIE;
654 		goto send_resp;
655 	}
656 
657 	pasn->akmp = rsn_data.key_mgmt;
658 	pasn->cipher = rsn_data.pairwise_cipher;
659 
660 	if (pasn->derive_kdk &&
661 	    ieee802_11_rsnx_capab_len(elems.rsnxe, elems.rsnxe_len,
662 				      WLAN_RSNX_CAPAB_SECURE_LTF))
663 		pasn->secure_ltf = true;
664 
665 	if (pasn->derive_kdk)
666 		pasn->kdk_len = WPA_KDK_MAX_LEN;
667 	else
668 		pasn->kdk_len = 0;
669 
670 	wpa_printf(MSG_DEBUG, "PASN: kdk_len=%zu", pasn->kdk_len);
671 
672 	if (!elems.pasn_params || !elems.pasn_params_len) {
673 		wpa_printf(MSG_DEBUG,
674 			   "PASN: No PASN Parameters element found");
675 		status = WLAN_STATUS_INVALID_PARAMETERS;
676 		goto send_resp;
677 	}
678 
679 	ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
680 					  elems.pasn_params_len + 3,
681 					  false, &pasn_params);
682 	if (ret) {
683 		wpa_printf(MSG_DEBUG,
684 			   "PASN: Failed validation of PASN Parameters IE");
685 		status = WLAN_STATUS_INVALID_PARAMETERS;
686 		goto send_resp;
687 	}
688 
689 	for (i = 0; groups[i] > 0 && groups[i] != pasn_params.group; i++)
690 		;
691 
692 	if (!pasn_params.group || groups[i] != pasn_params.group) {
693 		wpa_printf(MSG_DEBUG, "PASN: Requested group=%hu not allowed",
694 			   pasn_params.group);
695 		status = WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED;
696 		goto send_resp;
697 	}
698 
699 	if (!pasn_params.pubkey || !pasn_params.pubkey_len) {
700 		wpa_printf(MSG_DEBUG, "PASN: Invalid public key");
701 		status = WLAN_STATUS_INVALID_PARAMETERS;
702 		goto send_resp;
703 	}
704 
705 	if (pasn_params.comeback) {
706 		wpa_printf(MSG_DEBUG, "PASN: Checking peer comeback token");
707 
708 		ret = check_comeback_token(pasn->comeback_key,
709 					   pasn->comeback_pending_idx,
710 					   peer_addr,
711 					   pasn_params.comeback,
712 					   pasn_params.comeback_len);
713 
714 		if (ret) {
715 			wpa_printf(MSG_DEBUG, "PASN: Invalid comeback token");
716 			status = WLAN_STATUS_INVALID_PARAMETERS;
717 			goto send_resp;
718 		}
719 	} else if (pasn->use_anti_clogging) {
720 		wpa_printf(MSG_DEBUG, "PASN: Respond with comeback");
721 		handle_auth_pasn_comeback(pasn, own_addr, peer_addr,
722 					  pasn_params.group);
723 		return -1;
724 	}
725 
726 	pasn->ecdh = crypto_ecdh_init(pasn_params.group);
727 	if (!pasn->ecdh) {
728 		wpa_printf(MSG_DEBUG, "PASN: Failed to init ECDH");
729 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
730 		goto send_resp;
731 	}
732 
733 	pasn->group = pasn_params.group;
734 
735 	if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_UNCOMPRESSED) {
736 		inc_y = 1;
737 	} else if (pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_0 ||
738 		   pasn_params.pubkey[0] == WPA_PASN_PUBKEY_COMPRESSED_1) {
739 		inc_y = 0;
740 	} else {
741 		wpa_printf(MSG_DEBUG,
742 			   "PASN: Invalid first octet in pubkey=0x%x",
743 			   pasn_params.pubkey[0]);
744 		status = WLAN_STATUS_INVALID_PUBLIC_KEY;
745 		goto send_resp;
746 	}
747 
748 	secret = crypto_ecdh_set_peerkey(pasn->ecdh, inc_y,
749 					 pasn_params.pubkey + 1,
750 					 pasn_params.pubkey_len - 1);
751 	if (!secret) {
752 		wpa_printf(MSG_DEBUG, "PASN: Failed to derive shared secret");
753 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
754 		goto send_resp;
755 	}
756 
757 	if (!pasn->noauth && pasn->akmp == WPA_KEY_MGMT_PASN) {
758 		wpa_printf(MSG_DEBUG, "PASN: Refuse PASN-UNAUTH");
759 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
760 		goto send_resp;
761 	}
762 
763 	derive_keys = true;
764 	if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
765 		wrapped_data = ieee802_11_defrag(elems.wrapped_data,
766 						 elems.wrapped_data_len, true);
767 		if (!wrapped_data) {
768 			wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
769 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
770 			goto send_resp;
771 		}
772 
773 #ifdef CONFIG_SAE
774 		if (pasn->akmp == WPA_KEY_MGMT_SAE) {
775 			ret = pasn_wd_handle_sae_commit(pasn, own_addr,
776 							peer_addr,
777 							wrapped_data);
778 			if (ret) {
779 				wpa_printf(MSG_DEBUG,
780 					   "PASN: Failed processing SAE commit");
781 				status = WLAN_STATUS_UNSPECIFIED_FAILURE;
782 				goto send_resp;
783 			}
784 		}
785 #endif /* CONFIG_SAE */
786 #ifdef CONFIG_FILS
787 		if (pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
788 		    pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
789 			if (!pasn->fils_wd_valid) {
790 				wpa_printf(MSG_DEBUG,
791 					   "PASN: Invalid FILS wrapped data");
792 				status = WLAN_STATUS_UNSPECIFIED_FAILURE;
793 				goto send_resp;
794 			}
795 
796 			wpa_printf(MSG_DEBUG,
797 				   "PASN: FILS: Pending AS response");
798 
799 			/*
800 			 * With PASN/FILS, keys can be derived only after a
801 			 * response from the AS is processed.
802 			 */
803 			derive_keys = false;
804 		}
805 #endif /* CONFIG_FILS */
806 	}
807 
808 	pasn->wrapped_data_format = pasn_params.wrapped_data_format;
809 
810 	ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher,
811 				   ((const u8 *) mgmt) + IEEE80211_HDRLEN,
812 				   len - IEEE80211_HDRLEN, pasn->hash);
813 	if (ret) {
814 		wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
815 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
816 		goto send_resp;
817 	}
818 
819 	if (!derive_keys) {
820 		wpa_printf(MSG_DEBUG, "PASN: Storing secret");
821 		pasn->secret = secret;
822 		wpabuf_free(wrapped_data);
823 		return 0;
824 	}
825 
826 	if (rsn_data.num_pmkid) {
827 		if (wpa_key_mgmt_ft(pasn->akmp)) {
828 #ifdef CONFIG_IEEE80211R_AP
829 			wpa_printf(MSG_DEBUG, "PASN: FT: Fetch PMK-R1");
830 
831 			if (!pasn->pmk_r1_len) {
832 				wpa_printf(MSG_DEBUG,
833 					   "PASN: FT: Failed getting PMK-R1");
834 				status = WLAN_STATUS_UNSPECIFIED_FAILURE;
835 				goto send_resp;
836 			}
837 			cached_pmk = pasn->pmk_r1;
838 			cached_pmk_len = pasn->pmk_r1_len;
839 #else /* CONFIG_IEEE80211R_AP */
840 			wpa_printf(MSG_DEBUG, "PASN: FT: Not supported");
841 			status = WLAN_STATUS_UNSPECIFIED_FAILURE;
842 			goto send_resp;
843 #endif /* CONFIG_IEEE80211R_AP */
844 		} else {
845 			wpa_printf(MSG_DEBUG, "PASN: Try to find PMKSA entry");
846 
847 			if (pasn->pmksa) {
848 				const u8 *pmkid = NULL;
849 
850 				if (pasn->custom_pmkid_valid) {
851 					ret = pasn->validate_custom_pmkid(
852 						pasn->cb_ctx, peer_addr,
853 						rsn_data.pmkid);
854 					if (ret) {
855 						wpa_printf(MSG_DEBUG,
856 							   "PASN: Failed custom PMKID validation");
857 						status = WLAN_STATUS_UNSPECIFIED_FAILURE;
858 						goto send_resp;
859 					}
860 				} else {
861 					pmkid = rsn_data.pmkid;
862 				}
863 
864 				pmksa = pmksa_cache_auth_get(pasn->pmksa,
865 							     peer_addr,
866 							     pmkid);
867 				if (pmksa) {
868 					cached_pmk = pmksa->pmk;
869 					cached_pmk_len = pmksa->pmk_len;
870 				}
871 			}
872 		}
873 	} else {
874 		wpa_printf(MSG_DEBUG, "PASN: No PMKID specified");
875 	}
876 
877 	ret = pasn_derive_keys(pasn, own_addr, peer_addr,
878 			       cached_pmk, cached_pmk_len,
879 			       &pasn_params, wrapped_data, secret);
880 	if (ret) {
881 		wpa_printf(MSG_DEBUG, "PASN: Failed to derive keys");
882 		status = WLAN_STATUS_PASN_BASE_AKMP_FAILED;
883 		goto send_resp;
884 	}
885 
886 	ret = pasn_auth_frame_hash(pasn->akmp, pasn->cipher,
887 				   ((const u8 *) mgmt) + IEEE80211_HDRLEN,
888 				   len - IEEE80211_HDRLEN, pasn->hash);
889 	if (ret) {
890 		wpa_printf(MSG_DEBUG, "PASN: Failed to compute hash");
891 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
892 	}
893 
894 send_resp:
895 	ret = handle_auth_pasn_resp(pasn, own_addr, peer_addr, pmksa, status);
896 	if (ret) {
897 		wpa_printf(MSG_DEBUG, "PASN: Failed to send response");
898 		status = WLAN_STATUS_UNSPECIFIED_FAILURE;
899 	} else {
900 		wpa_printf(MSG_DEBUG,
901 			   "PASN: Success handling transaction == 1");
902 	}
903 
904 	wpabuf_free(secret);
905 	wpabuf_free(wrapped_data);
906 
907 	if (status != WLAN_STATUS_SUCCESS)
908 		return -1;
909 
910 	return 0;
911 }
912 
913 
914 int handle_auth_pasn_3(struct pasn_data *pasn, const u8 *own_addr,
915 		       const u8 *peer_addr,
916 		       const struct ieee80211_mgmt *mgmt, size_t len)
917 {
918 	struct ieee802_11_elems elems;
919 	struct wpa_pasn_params_data pasn_params;
920 	struct wpabuf *wrapped_data = NULL;
921 	u8 mic[WPA_PASN_MAX_MIC_LEN], out_mic[WPA_PASN_MAX_MIC_LEN];
922 	u8 mic_len;
923 	int ret;
924 	u8 *copy = NULL;
925 	size_t copy_len, mic_offset;
926 
927 	if (ieee802_11_parse_elems(mgmt->u.auth.variable,
928 				   len - offsetof(struct ieee80211_mgmt,
929 						  u.auth.variable),
930 				   &elems, 0) == ParseFailed) {
931 		wpa_printf(MSG_DEBUG,
932 			   "PASN: Failed parsing Authentication frame");
933 		goto fail;
934 	}
935 
936 	/* Check that the MIC IE exists. Save it and zero out the memory. */
937 	mic_len = pasn_mic_len(pasn->akmp, pasn->cipher);
938 	if (!elems.mic || elems.mic_len != mic_len) {
939 		wpa_printf(MSG_DEBUG,
940 			   "PASN: Invalid MIC. Expecting len=%u", mic_len);
941 		goto fail;
942 	}
943 	os_memcpy(mic, elems.mic, mic_len);
944 
945 	if (!elems.pasn_params || !elems.pasn_params_len) {
946 		wpa_printf(MSG_DEBUG,
947 			   "PASN: No PASN Parameters element found");
948 		goto fail;
949 	}
950 
951 	ret = wpa_pasn_parse_parameter_ie(elems.pasn_params - 3,
952 					  elems.pasn_params_len + 3,
953 					  false, &pasn_params);
954 	if (ret) {
955 		wpa_printf(MSG_DEBUG,
956 			   "PASN: Failed validation of PASN Parameters IE");
957 		goto fail;
958 	}
959 
960 	if (pasn_params.pubkey || pasn_params.pubkey_len) {
961 		wpa_printf(MSG_DEBUG,
962 			   "PASN: Public key should not be included");
963 		goto fail;
964 	}
965 
966 	/* Verify the MIC */
967 	copy_len = len - offsetof(struct ieee80211_mgmt, u.auth);
968 	mic_offset = elems.mic - (const u8 *) &mgmt->u.auth;
969 	copy_len = len - offsetof(struct ieee80211_mgmt, u.auth);
970 	if (mic_offset + mic_len > copy_len)
971 		goto fail;
972 	copy = os_memdup(&mgmt->u.auth, copy_len);
973 	if (!copy)
974 		goto fail;
975 	os_memset(copy + mic_offset, 0, mic_len);
976 	ret = pasn_mic(pasn->ptk.kck, pasn->akmp, pasn->cipher,
977 		       peer_addr, own_addr,
978 		       pasn->hash, mic_len * 2,
979 		       copy, copy_len, out_mic);
980 	os_free(copy);
981 	copy = NULL;
982 
983 	wpa_hexdump_key(MSG_DEBUG, "PASN: Frame MIC", mic, mic_len);
984 	if (ret || os_memcmp(mic, out_mic, mic_len) != 0) {
985 		wpa_printf(MSG_DEBUG, "PASN: Failed MIC verification");
986 		goto fail;
987 	}
988 
989 	if (pasn_params.wrapped_data_format != WPA_PASN_WRAPPED_DATA_NO) {
990 		wrapped_data = ieee802_11_defrag(elems.wrapped_data,
991 						 elems.wrapped_data_len,
992 						 true);
993 
994 		if (!wrapped_data) {
995 			wpa_printf(MSG_DEBUG, "PASN: Missing wrapped data");
996 			goto fail;
997 		}
998 
999 #ifdef CONFIG_SAE
1000 		if (pasn->akmp == WPA_KEY_MGMT_SAE) {
1001 			ret = pasn_wd_handle_sae_confirm(pasn, peer_addr,
1002 							 wrapped_data);
1003 			if (ret) {
1004 				wpa_printf(MSG_DEBUG,
1005 					   "PASN: Failed processing SAE confirm");
1006 				wpabuf_free(wrapped_data);
1007 				goto fail;
1008 			}
1009 		}
1010 #endif /* CONFIG_SAE */
1011 #ifdef CONFIG_FILS
1012 		if (pasn->akmp == WPA_KEY_MGMT_FILS_SHA256 ||
1013 		    pasn->akmp == WPA_KEY_MGMT_FILS_SHA384) {
1014 			if (wrapped_data) {
1015 				wpa_printf(MSG_DEBUG,
1016 					   "PASN: FILS: Ignore wrapped data");
1017 			}
1018 		}
1019 #endif /* CONFIG_FILS */
1020 		wpabuf_free(wrapped_data);
1021 	}
1022 
1023 	wpa_printf(MSG_INFO,
1024 		   "PASN: Success handling transaction == 3. Store PTK");
1025 	return 0;
1026 
1027 fail:
1028 	os_free(copy);
1029 	return -1;
1030 }
1031 
1032 #endif /* CONFIG_PASN */
1033