Home | History | Annotate | Line # | Download | only in pasn
      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