3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-25 17:59:25 +01:00

ft: add FTE/RSNE building to ft_prepare_handshake

In preparation to remove ft_associate build the FTE/RSNE in
ft_prepare_handshake and set into the handshake object directly.
This commit is contained in:
James Prestwood 2023-12-06 12:17:57 -08:00 committed by Denis Kenzior
parent 0a0a257e1e
commit cf137f4199

View File

@ -904,9 +904,15 @@ static void ft_info_destroy(void *data)
l_free(info); l_free(info);
} }
static void ft_prepare_handshake(struct ft_info *info, static bool ft_prepare_handshake(struct ft_info *info,
struct handshake_state *hs) struct handshake_state *hs)
{ {
uint32_t kck_len = handshake_state_get_kck_len(hs);
struct ie_rsn_info rsn_info;
struct ie_ft_info ft_info;
uint8_t *fte;
uint8_t *rsne;
handshake_state_set_authenticator_address(hs, info->aa); handshake_state_set_authenticator_address(hs, info->aa);
memcpy(hs->mde + 2, info->mde, 3); memcpy(hs->mde + 2, info->mde, 3);
@ -914,7 +920,7 @@ static void ft_prepare_handshake(struct ft_info *info,
handshake_state_set_chandef(hs, NULL); handshake_state_set_chandef(hs, NULL);
if (!hs->supplicant_ie) if (!hs->supplicant_ie)
return; return true;
if (info->authenticator_ie) if (info->authenticator_ie)
handshake_state_set_authenticator_ie(hs, handshake_state_set_authenticator_ie(hs,
@ -931,6 +937,80 @@ static void ft_prepare_handshake(struct ft_info *info,
info->ft_info.r1khid); info->ft_info.r1khid);
handshake_state_derive_ptk(hs); handshake_state_derive_ptk(hs);
/*
* Rebuild the RSNE to include the PMKR1Name and append
* MDE + FTE.
*
* 12.8.4: "If present, the RSNE shall be set as follows:
* - Version field shall be set to 1.
* - PMKID Count field shall be set to 1.
* - PMKID field shall contain the PMKR1Name.
* - All other fields shall be as specified in 8.4.2.27
* and 11.5.3."
*/
if (ie_parse_rsne_from_data(hs->supplicant_ie,
hs->supplicant_ie[1] + 2,
&rsn_info) < 0)
return false;
rsn_info.num_pmkids = 1;
rsn_info.pmkids = hs->pmk_r1_name;
/* Always set OCVC false for FT for now */
rsn_info.ocvc = false;
rsne = alloca(256);
ie_build_rsne(&rsn_info, rsne);
handshake_state_set_supplicant_ie(hs, rsne);
/*
* 12.8.4: "If present, the FTE shall be set as follows:
* - ANonce, SNonce, R0KH-ID, and R1KH-ID shall be set to
* the values contained in the second message of this
* sequence.
* - The Element Count field of the MIC Control field shall
* be set to the number of elements protected in this
* frame (variable).
* [...]
* - All other fields shall be set to 0."
*/
memset(&ft_info, 0, sizeof(ft_info));
ft_info.mic_element_count = 3;
memcpy(ft_info.r0khid, hs->r0khid, hs->r0khid_len);
ft_info.r0khid_len = hs->r0khid_len;
memcpy(ft_info.r1khid, hs->r1khid, 6);
ft_info.r1khid_present = true;
memcpy(ft_info.anonce, hs->anonce, 32);
memcpy(ft_info.snonce, hs->snonce, 32);
/*
* IEEE 802.11-2020 Section 13.7.1 FT reassociation in an RSN
*
* "If dot11RSNAOperatingChannelValidationActivated is true and
* the FTO indicates OCVC capability, the target AP shall
* ensure that OCI subelement of the FTE matches by ensuring
* that all of the following are true:
* - OCI subelement is present
* - Channel information in the OCI matches current
* operating channel parameters (see 12.2.9)"
*/
if (hs->supplicant_ocvc && hs->chandef) {
oci_from_chandef(hs->chandef, ft_info.oci);
ft_info.oci_present = true;
}
fte = alloca(256);
ie_build_fast_bss_transition(&ft_info, kck_len, fte);
if (!ft_calculate_fte_mic(hs, 5, rsne, fte, NULL, ft_info.mic))
return false;
/* Rebuild the FT IE now with the MIC included */
ie_build_fast_bss_transition(&ft_info, kck_len, fte);
handshake_state_set_supplicant_fte(hs, fte);
return true;
} }
static bool ft_send_action(struct wiphy_radio_work_item *work) static bool ft_send_action(struct wiphy_radio_work_item *work)