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