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