mirror of
				https://github.com/Telecominfraproject/wlan-ap.git
				synced 2025-10-31 02:17:58 +00:00 
			
		
		
		
	ipq807x/hostapd: backport FT VLAN fix
The bug was in the upstream hostapd codebase, backport/rebase the fix --> ba150059d1ec964add8f29eb2c92dd6dfde97308 Fixes: WIFI-14508 Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
		| @@ -0,0 +1,411 @@ | |||||||
|  | From: Jouni Malinen <quic_jouni@quicinc.com> | ||||||
|  | Date: Tue, 14 Feb 2023 11:29:30 +0200 | ||||||
|  | Subject: [PATCH] FT: Store PMK-R0/PMK-R1 after EAPOL-Key msg 2/4 MIC | ||||||
|  |  validation | ||||||
|  |  | ||||||
|  | hostapd was previously storing the derived PMK-R0 and PMK-R1 as soon as | ||||||
|  | these keys were derived. While that is fine for most purposes, it is | ||||||
|  | unnecessary to do that so quickly and if anything were to fail before | ||||||
|  | the supplicant is able to return a valid EAPOL-Key msg 2/4, there would | ||||||
|  | not really be any real use for the derived keys. | ||||||
|  |  | ||||||
|  | For the special case of FT-PSK and VLAN determination based on the | ||||||
|  | wpa_psk file, the VLAN information is set in the per-STA data structures | ||||||
|  | only after the EAPOL-Key msg 2/4 MIC has been verified. This ended up | ||||||
|  | storing the PMK-R0/PMK-R1 entries without correct VLAN assignment and as | ||||||
|  | such, any use of the FT protocol would not be able to transfer the VLAN | ||||||
|  | information through RRB. | ||||||
|  |  | ||||||
|  | Split local storing of the FT key hierarchy for the cases using the FT | ||||||
|  | 4-way handshake so that PMK-R0 and PMK-R1 are first derived and then | ||||||
|  | stored as a separate step after having verified the MIC in the EAPOL-Key | ||||||
|  | msg 2/4 (i.e., after having confirmed the per-STA passphrase/PSK was | ||||||
|  | selected) and VLAN update. This fixes VLAN information for the | ||||||
|  | wpa_psk_file cases with FT-PSK. | ||||||
|  |  | ||||||
|  | Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com> | ||||||
|  | --- | ||||||
|  |  | ||||||
|  | --- a/src/ap/wpa_auth.c | ||||||
|  | +++ b/src/ap/wpa_auth.c | ||||||
|  | @@ -58,7 +58,9 @@ static int wpa_group_config_group_keys(s | ||||||
|  |  				       struct wpa_group *group); | ||||||
|  |  static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, | ||||||
|  |  			  const u8 *pmk, unsigned int pmk_len, | ||||||
|  | -			  struct wpa_ptk *ptk, int force_sha256); | ||||||
|  | +			  struct wpa_ptk *ptk, int force_sha256, | ||||||
|  | +			  u8 *pmk_r0, u8 *pmk_r1, u8 *pmk_r0_name, | ||||||
|  | +			  size_t *key_len); | ||||||
|  |  static void wpa_group_free(struct wpa_authenticator *wpa_auth, | ||||||
|  |  			   struct wpa_group *group); | ||||||
|  |  static void wpa_group_get(struct wpa_authenticator *wpa_auth, | ||||||
|  | @@ -940,6 +942,10 @@ static int wpa_try_alt_snonce(struct wpa | ||||||
|  |  	const u8 *pmk = NULL; | ||||||
|  |  	size_t pmk_len; | ||||||
|  |  	int vlan_id = 0; | ||||||
|  | +	u8 pmk_r0[PMK_LEN_MAX], pmk_r0_name[WPA_PMK_NAME_LEN]; | ||||||
|  | +	u8 pmk_r1[PMK_LEN_MAX]; | ||||||
|  | +	size_t key_len; | ||||||
|  | +	int ret = -1; | ||||||
|  |   | ||||||
|  |  	os_memset(&PTK, 0, sizeof(PTK)); | ||||||
|  |  	for (;;) { | ||||||
|  | @@ -961,8 +967,8 @@ static int wpa_try_alt_snonce(struct wpa | ||||||
|  |  			pmk_len = sm->pmk_len; | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  | -		if (wpa_derive_ptk(sm, sm->alt_SNonce, pmk, pmk_len, &PTK, 0) < | ||||||
|  | -		    0) | ||||||
|  | +		if (wpa_derive_ptk(sm, sm->alt_SNonce, pmk, pmk_len, &PTK, 0, | ||||||
|  | +				   pmk_r0, pmk_r1, pmk_r0_name, &key_len) < 0) | ||||||
|  |  			break; | ||||||
|  |   | ||||||
|  |  		if (wpa_verify_key_mic(sm->wpa_key_mgmt, pmk_len, &PTK, | ||||||
|  | @@ -983,7 +989,7 @@ static int wpa_try_alt_snonce(struct wpa | ||||||
|  |  	if (!ok) { | ||||||
|  |  		wpa_printf(MSG_DEBUG, | ||||||
|  |  			   "WPA: Earlier SNonce did not result in matching MIC"); | ||||||
|  | -		return -1; | ||||||
|  | +		goto fail; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	wpa_printf(MSG_DEBUG, | ||||||
|  | @@ -992,14 +998,26 @@ static int wpa_try_alt_snonce(struct wpa | ||||||
|  |   | ||||||
|  |  	if (vlan_id && wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) && | ||||||
|  |  	    wpa_auth_update_vlan(sm->wpa_auth, sm->addr, vlan_id) < 0) | ||||||
|  | -		return -1; | ||||||
|  | +		goto fail; | ||||||
|  | + | ||||||
|  | +#ifdef CONFIG_IEEE80211R_AP | ||||||
|  | +	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt) && !sm->ft_completed) { | ||||||
|  | +		wpa_printf(MSG_DEBUG, "FT: Store PMK-R0/PMK-R1"); | ||||||
|  | +		wpa_auth_ft_store_keys(sm, pmk_r0, pmk_r1, pmk_r0_name, | ||||||
|  | +				       key_len); | ||||||
|  | +	} | ||||||
|  | +#endif /* CONFIG_IEEE80211R_AP */ | ||||||
|  |   | ||||||
|  |  	os_memcpy(sm->SNonce, sm->alt_SNonce, WPA_NONCE_LEN); | ||||||
|  |  	os_memcpy(&sm->PTK, &PTK, sizeof(PTK)); | ||||||
|  |  	forced_memzero(&PTK, sizeof(PTK)); | ||||||
|  |  	sm->PTK_valid = true; | ||||||
|  |   | ||||||
|  | -	return 0; | ||||||
|  | +	ret = 0; | ||||||
|  | +fail: | ||||||
|  | +	forced_memzero(pmk_r0, sizeof(pmk_r0)); | ||||||
|  | +	forced_memzero(pmk_r1, sizeof(pmk_r1)); | ||||||
|  | +	return ret; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  | @@ -2283,7 +2301,9 @@ SM_STATE(WPA_PTK, PTKSTART) | ||||||
|  |   | ||||||
|  |  static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, | ||||||
|  |  			  const u8 *pmk, unsigned int pmk_len, | ||||||
|  | -			  struct wpa_ptk *ptk, int force_sha256) | ||||||
|  | +			  struct wpa_ptk *ptk, int force_sha256, | ||||||
|  | +			  u8 *pmk_r0, u8 *pmk_r1, u8 *pmk_r0_name, | ||||||
|  | +			  size_t *key_len) | ||||||
|  |  { | ||||||
|  |  	const u8 *z = NULL; | ||||||
|  |  	size_t z_len = 0, kdk_len; | ||||||
|  | @@ -2311,7 +2331,8 @@ static int wpa_derive_ptk(struct wpa_sta | ||||||
|  |  						 sm->pairwise, | ||||||
|  |  						 kdk_len); | ||||||
|  |  		} | ||||||
|  | -		return wpa_auth_derive_ptk_ft(sm, ptk); | ||||||
|  | +		return wpa_auth_derive_ptk_ft(sm, ptk, pmk_r0, pmk_r1, | ||||||
|  | +					      pmk_r0_name, key_len); | ||||||
|  |  	} | ||||||
|  |  #endif /* CONFIG_IEEE80211R_AP */ | ||||||
|  |   | ||||||
|  | @@ -2934,6 +2955,9 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  	struct wpa_eapol_ie_parse kde; | ||||||
|  |  	int vlan_id = 0; | ||||||
|  |  	int owe_ptk_workaround = !!wpa_auth->conf.owe_ptk_workaround; | ||||||
|  | +	u8 pmk_r0[PMK_LEN_MAX], pmk_r0_name[WPA_PMK_NAME_LEN]; | ||||||
|  | +	u8 pmk_r1[PMK_LEN_MAX]; | ||||||
|  | +	size_t key_len; | ||||||
|  |   | ||||||
|  |  	SM_ENTRY_MA(WPA_PTK, PTKCALCNEGOTIATING, wpa_ptk); | ||||||
|  |  	sm->EAPOLKeyReceived = false; | ||||||
|  | @@ -2972,7 +2996,8 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  		if (wpa_derive_ptk(sm, sm->SNonce, pmk, pmk_len, &PTK, | ||||||
|  | -				   owe_ptk_workaround == 2) < 0) | ||||||
|  | +				   owe_ptk_workaround == 2, pmk_r0, pmk_r1, | ||||||
|  | +				   pmk_r0_name, &key_len) < 0) | ||||||
|  |  			break; | ||||||
|  |   | ||||||
|  |  		if (mic_len && | ||||||
|  | @@ -3021,7 +3046,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  						 sm->last_rx_eapol_key, | ||||||
|  |  						 sm->last_rx_eapol_key_len); | ||||||
|  |  		sm->waiting_radius_psk = 1; | ||||||
|  | -		return; | ||||||
|  | +		goto out; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	if (!ok) { | ||||||
|  | @@ -3029,7 +3054,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  				"invalid MIC in msg 2/4 of 4-Way Handshake"); | ||||||
|  |  		if (psk_found) | ||||||
|  |  			wpa_auth_psk_failure_report(sm->wpa_auth, sm->addr); | ||||||
|  | -		return; | ||||||
|  | +		goto out; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	/* | ||||||
|  | @@ -3043,12 +3068,12 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  	key_data_length = WPA_GET_BE16(mic + mic_len); | ||||||
|  |  	if (key_data_length > sm->last_rx_eapol_key_len - sizeof(*hdr) - | ||||||
|  |  	    sizeof(*key) - mic_len - 2) | ||||||
|  | -		return; | ||||||
|  | +		goto out; | ||||||
|  |   | ||||||
|  |  	if (wpa_parse_kde_ies(key_data, key_data_length, &kde) < 0) { | ||||||
|  |  		wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO, | ||||||
|  |  				 "received EAPOL-Key msg 2/4 with invalid Key Data contents"); | ||||||
|  | -		return; | ||||||
|  | +		goto out; | ||||||
|  |  	} | ||||||
|  |  	if (kde.rsn_ie) { | ||||||
|  |  		eapol_key_ie = kde.rsn_ie; | ||||||
|  | @@ -3075,7 +3100,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  		/* MLME-DEAUTHENTICATE.request */ | ||||||
|  |  		wpa_sta_disconnect(wpa_auth, sm->addr, | ||||||
|  |  				   WLAN_REASON_PREV_AUTH_NOT_VALID); | ||||||
|  | -		return; | ||||||
|  | +		goto out; | ||||||
|  |  	} | ||||||
|  |  	if ((!sm->rsnxe && kde.rsnxe) || | ||||||
|  |  	    (sm->rsnxe && !kde.rsnxe) || | ||||||
|  | @@ -3091,7 +3116,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  		/* MLME-DEAUTHENTICATE.request */ | ||||||
|  |  		wpa_sta_disconnect(wpa_auth, sm->addr, | ||||||
|  |  				   WLAN_REASON_PREV_AUTH_NOT_VALID); | ||||||
|  | -		return; | ||||||
|  | +		goto out; | ||||||
|  |  	} | ||||||
|  |  #ifdef CONFIG_OCV | ||||||
|  |  	if (wpa_auth_uses_ocv(sm)) { | ||||||
|  | @@ -3103,14 +3128,14 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  		if (wpa_channel_info(wpa_auth, &ci) != 0) { | ||||||
|  |  			wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO, | ||||||
|  |  					"Failed to get channel info to validate received OCI in EAPOL-Key 2/4"); | ||||||
|  | -			return; | ||||||
|  | +			goto out; | ||||||
|  |  		} | ||||||
|  |   | ||||||
|  |  		if (get_sta_tx_parameters(sm, | ||||||
|  |  					  channel_width_to_int(ci.chanwidth), | ||||||
|  |  					  ci.seg1_idx, &tx_chanwidth, | ||||||
|  |  					  &tx_seg1_idx) < 0) | ||||||
|  | -			return; | ||||||
|  | +			goto out; | ||||||
|  |   | ||||||
|  |  		res = ocv_verify_tx_params(kde.oci, kde.oci_len, &ci, | ||||||
|  |  					   tx_chanwidth, tx_seg1_idx); | ||||||
|  | @@ -3127,7 +3152,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  					OCV_FAILURE "addr=" MACSTR | ||||||
|  |  					" frame=eapol-key-m2 error=%s", | ||||||
|  |  					MAC2STR(sm->addr), ocv_errorstr); | ||||||
|  | -			return; | ||||||
|  | +			goto out; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |  #endif /* CONFIG_OCV */ | ||||||
|  | @@ -3135,7 +3160,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  	if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) { | ||||||
|  |  		wpa_sta_disconnect(wpa_auth, sm->addr, | ||||||
|  |  				   WLAN_REASON_PREV_AUTH_NOT_VALID); | ||||||
|  | -		return; | ||||||
|  | +		goto out; | ||||||
|  |  	} | ||||||
|  |  #endif /* CONFIG_IEEE80211R_AP */ | ||||||
|  |  #ifdef CONFIG_P2P | ||||||
|  | @@ -3171,7 +3196,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  				   "DPP: Peer indicated it supports PFS and local configuration allows this, but PFS was not negotiated for the association"); | ||||||
|  |  			wpa_sta_disconnect(wpa_auth, sm->addr, | ||||||
|  |  					   WLAN_REASON_PREV_AUTH_NOT_VALID); | ||||||
|  | -			return; | ||||||
|  | +			goto out; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |  #endif /* CONFIG_DPP2 */ | ||||||
|  | @@ -3191,7 +3216,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  				    sm->sup_pmk_r1_name, WPA_PMK_NAME_LEN); | ||||||
|  |  			wpa_hexdump(MSG_DEBUG, "FT: Derived PMKR1Name", | ||||||
|  |  				    sm->pmk_r1_name, WPA_PMK_NAME_LEN); | ||||||
|  | -			return; | ||||||
|  | +			goto out; | ||||||
|  |  		} | ||||||
|  |  	} | ||||||
|  |  #endif /* CONFIG_IEEE80211R_AP */ | ||||||
|  | @@ -3200,7 +3225,7 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |  	    wpa_auth_update_vlan(wpa_auth, sm->addr, vlan_id) < 0) { | ||||||
|  |  		wpa_sta_disconnect(wpa_auth, sm->addr, | ||||||
|  |  				   WLAN_REASON_PREV_AUTH_NOT_VALID); | ||||||
|  | -		return; | ||||||
|  | +		goto out; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	sm->pending_1_of_4_timeout = 0; | ||||||
|  | @@ -3216,9 +3241,20 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING) | ||||||
|  |   | ||||||
|  |  	sm->MICVerified = true; | ||||||
|  |   | ||||||
|  | +#ifdef CONFIG_IEEE80211R_AP | ||||||
|  | +	if (wpa_key_mgmt_ft(sm->wpa_key_mgmt) && !sm->ft_completed) { | ||||||
|  | +		wpa_printf(MSG_DEBUG, "FT: Store PMK-R0/PMK-R1"); | ||||||
|  | +		wpa_auth_ft_store_keys(sm, pmk_r0, pmk_r1, pmk_r0_name, | ||||||
|  | +				       key_len); | ||||||
|  | +	} | ||||||
|  | +#endif /* CONFIG_IEEE80211R_AP */ | ||||||
|  | + | ||||||
|  |  	os_memcpy(&sm->PTK, &PTK, sizeof(PTK)); | ||||||
|  |  	forced_memzero(&PTK, sizeof(PTK)); | ||||||
|  |  	sm->PTK_valid = true; | ||||||
|  | +out: | ||||||
|  | +	forced_memzero(pmk_r0, sizeof(pmk_r0)); | ||||||
|  | +	forced_memzero(pmk_r1, sizeof(pmk_r1)); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  | --- a/src/ap/wpa_auth_ft.c | ||||||
|  | +++ b/src/ap/wpa_auth_ft.c | ||||||
|  | @@ -2175,13 +2175,13 @@ int wpa_ft_store_pmk_fils(struct wpa_sta | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  | -int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk) | ||||||
|  | +int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk, | ||||||
|  | +			   u8 *pmk_r0, u8 *pmk_r1, u8 *pmk_r0_name, | ||||||
|  | +			   size_t *key_len) | ||||||
|  |  { | ||||||
|  | -	u8 pmk_r0[PMK_LEN_MAX], pmk_r0_name[WPA_PMK_NAME_LEN]; | ||||||
|  |  	size_t pmk_r0_len = wpa_key_mgmt_sha384(sm->wpa_key_mgmt) ? | ||||||
|  |  		SHA384_MAC_LEN : PMK_LEN; | ||||||
|  |  	size_t pmk_r1_len = pmk_r0_len; | ||||||
|  | -	u8 pmk_r1[PMK_LEN_MAX]; | ||||||
|  |  	u8 ptk_name[WPA_PMK_NAME_LEN]; | ||||||
|  |  	const u8 *mdid = sm->wpa_auth->conf.mobility_domain; | ||||||
|  |  	const u8 *r0kh = sm->wpa_auth->conf.r0_key_holder; | ||||||
|  | @@ -2189,13 +2189,6 @@ int wpa_auth_derive_ptk_ft(struct wpa_st | ||||||
|  |  	const u8 *r1kh = sm->wpa_auth->conf.r1_key_holder; | ||||||
|  |  	const u8 *ssid = sm->wpa_auth->conf.ssid; | ||||||
|  |  	size_t ssid_len = sm->wpa_auth->conf.ssid_len; | ||||||
|  | -	int psk_local = sm->wpa_auth->conf.ft_psk_generate_local; | ||||||
|  | -	int expires_in = sm->wpa_auth->conf.r0_key_lifetime; | ||||||
|  | -	struct vlan_description vlan; | ||||||
|  | -	struct rate_description rate; | ||||||
|  | -	const u8 *identity, *radius_cui; | ||||||
|  | -	size_t identity_len, radius_cui_len; | ||||||
|  | -	int session_timeout; | ||||||
|  |  	const u8 *mpmk; | ||||||
|  |  	size_t mpmk_len; | ||||||
|  |   | ||||||
|  | @@ -2211,10 +2204,41 @@ int wpa_auth_derive_ptk_ft(struct wpa_st | ||||||
|  |  		return -1; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  | +	*key_len = pmk_r0_len; | ||||||
|  | +	if (wpa_derive_pmk_r0(mpmk, mpmk_len, ssid, ssid_len, mdid, | ||||||
|  | +			      r0kh, r0kh_len, sm->addr, | ||||||
|  | +			      pmk_r0, pmk_r0_name, | ||||||
|  | +			      pmk_r0_len == SHA384_MAC_LEN) < 0 || | ||||||
|  | +	    wpa_derive_pmk_r1(pmk_r0, pmk_r0_len, pmk_r0_name, r1kh, sm->addr, | ||||||
|  | +			      pmk_r1, sm->pmk_r1_name) < 0) | ||||||
|  | +		return -1; | ||||||
|  | + | ||||||
|  | +	return wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce, | ||||||
|  | +				 sm->addr, sm->wpa_auth->addr, sm->pmk_r1_name, | ||||||
|  | +				 ptk, ptk_name, sm->wpa_key_mgmt, sm->pairwise, | ||||||
|  | +				 0); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | + | ||||||
|  | +void wpa_auth_ft_store_keys(struct wpa_state_machine *sm, const u8 *pmk_r0, | ||||||
|  | +			    const u8 *pmk_r1, const u8 *pmk_r0_name, | ||||||
|  | +			    size_t key_len) | ||||||
|  | +{ | ||||||
|  | +	int psk_local = sm->wpa_auth->conf.ft_psk_generate_local; | ||||||
|  | +	int expires_in = sm->wpa_auth->conf.r0_key_lifetime; | ||||||
|  | +	struct vlan_description vlan; | ||||||
|  | +	struct rate_description rate; | ||||||
|  | +	const u8 *identity, *radius_cui; | ||||||
|  | +	size_t identity_len, radius_cui_len; | ||||||
|  | +	int session_timeout; | ||||||
|  | + | ||||||
|  | +	if (psk_local && wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt)) | ||||||
|  | +		return; | ||||||
|  | + | ||||||
|  |  	if (wpa_ft_get_vlan(sm->wpa_auth, sm->addr, &vlan) < 0) { | ||||||
|  |  		wpa_printf(MSG_DEBUG, "FT: vlan not available for STA " MACSTR, | ||||||
|  |  			   MAC2STR(sm->addr)); | ||||||
|  | -		return -1; | ||||||
|  | +		return; | ||||||
|  |  	} | ||||||
|  |   | ||||||
|  |  	wpa_ft_get_rate_limit(sm->wpa_auth, sm->addr, &rate); | ||||||
|  | @@ -2224,32 +2248,16 @@ int wpa_auth_derive_ptk_ft(struct wpa_st | ||||||
|  |  					       &radius_cui); | ||||||
|  |  	session_timeout = wpa_ft_get_session_timeout(sm->wpa_auth, sm->addr); | ||||||
|  |   | ||||||
|  | -	if (wpa_derive_pmk_r0(mpmk, mpmk_len, ssid, ssid_len, mdid, | ||||||
|  | -			      r0kh, r0kh_len, sm->addr, | ||||||
|  | -			      pmk_r0, pmk_r0_name, | ||||||
|  | -			      wpa_key_mgmt_sha384(sm->wpa_key_mgmt)) < 0) | ||||||
|  | -		return -1; | ||||||
|  | -	if (!psk_local || !wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt)) | ||||||
|  | -		wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_len, | ||||||
|  | -				    pmk_r0_name, | ||||||
|  | -				    sm->pairwise, &vlan, expires_in, | ||||||
|  | -				    session_timeout, identity, identity_len, | ||||||
|  | -				    radius_cui, radius_cui_len, &rate); | ||||||
|  | - | ||||||
|  | -	if (wpa_derive_pmk_r1(pmk_r0, pmk_r0_len, pmk_r0_name, r1kh, sm->addr, | ||||||
|  | -			      pmk_r1, sm->pmk_r1_name) < 0) | ||||||
|  | -		return -1; | ||||||
|  | -	if (!psk_local || !wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt)) | ||||||
|  | -		wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, pmk_r1_len, | ||||||
|  | -				    sm->pmk_r1_name, sm->pairwise, &vlan, | ||||||
|  | -				    expires_in, session_timeout, identity, | ||||||
|  | -				    identity_len, radius_cui, radius_cui_len, | ||||||
|  | -				    &rate); | ||||||
|  | - | ||||||
|  | -	return wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce, | ||||||
|  | -				 sm->addr, sm->wpa_auth->addr, sm->pmk_r1_name, | ||||||
|  | -				 ptk, ptk_name, sm->wpa_key_mgmt, sm->pairwise, | ||||||
|  | -				 0); | ||||||
|  | +	wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, key_len, | ||||||
|  | +			    pmk_r0_name, | ||||||
|  | +			    sm->pairwise, &vlan, expires_in, | ||||||
|  | +			    session_timeout, identity, identity_len, | ||||||
|  | +			    radius_cui, radius_cui_len, &rate); | ||||||
|  | + | ||||||
|  | +	wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, key_len, | ||||||
|  | +			    sm->pmk_r1_name, sm->pairwise, &vlan, | ||||||
|  | +			    expires_in, session_timeout, identity, | ||||||
|  | +			    identity_len, radius_cui, radius_cui_len, &rate); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |   | ||||||
|  | --- a/src/ap/wpa_auth_i.h | ||||||
|  | +++ b/src/ap/wpa_auth_i.h | ||||||
|  | @@ -302,7 +302,12 @@ int wpa_write_ftie(struct wpa_auth_confi | ||||||
|  |  		   const u8 *anonce, const u8 *snonce, | ||||||
|  |  		   u8 *buf, size_t len, const u8 *subelem, | ||||||
|  |  		   size_t subelem_len, int rsnxe_used); | ||||||
|  | -int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk); | ||||||
|  | +int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, struct wpa_ptk *ptk, | ||||||
|  | +			   u8 *pmk_r0, u8 *pmk_r1, u8 *pmk_r0_name, | ||||||
|  | +			   size_t *key_len); | ||||||
|  | +void wpa_auth_ft_store_keys(struct wpa_state_machine *sm, const u8 *pmk_r0, | ||||||
|  | +			    const u8 *pmk_r1, const u8 *pmk_r0_name, | ||||||
|  | +			    size_t key_len); | ||||||
|  |  struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void); | ||||||
|  |  void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache); | ||||||
|  |  void wpa_ft_install_ptk(struct wpa_state_machine *sm, int retry); | ||||||
		Reference in New Issue
	
	Block a user
	 John Crispin
					John Crispin