3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2025-01-03 10:32:33 +01:00

ie: allow 24 byte FTE MIC

FT over FILS-SHA384 uses a 24 byte FT MIC rather than the 16 byte MIC
used for all other AKMs. This change allows both the FT builder/parser
to handle both lengths of MIC. The mic length is now passed directly
into ie_parse_fast_bss_transition and ie_build_fast_bss_transition
This commit is contained in:
James Prestwood 2019-05-22 15:24:00 -07:00 committed by Denis Kenzior
parent 4097a49669
commit 1accf534dc
4 changed files with 37 additions and 26 deletions

View File

@ -237,6 +237,7 @@ static int ft_tx_reassociate(struct ft_sm *ft)
struct iovec iov[3]; struct iovec iov[3];
int iov_elems = 0; int iov_elems = 0;
struct handshake_state *hs = ft->hs; struct handshake_state *hs = ft->hs;
uint32_t kck_len = handshake_state_get_kck_len(hs);
bool is_rsn = hs->supplicant_ie != NULL; bool is_rsn = hs->supplicant_ie != NULL;
uint8_t *rsne = NULL; uint8_t *rsne = NULL;
@ -302,13 +303,13 @@ static int ft_tx_reassociate(struct ft_sm *ft)
memcpy(ft_info.snonce, hs->snonce, 32); memcpy(ft_info.snonce, hs->snonce, 32);
fte = alloca(256); fte = alloca(256);
ie_build_fast_bss_transition(&ft_info, fte); ie_build_fast_bss_transition(&ft_info, kck_len, fte);
if (!ft_calculate_fte_mic(hs, 5, rsne, fte, NULL, ft_info.mic)) if (!ft_calculate_fte_mic(hs, 5, rsne, fte, NULL, ft_info.mic))
goto error; goto error;
/* Rebuild the FT IE now with the MIC included */ /* Rebuild the FT IE now with the MIC included */
ie_build_fast_bss_transition(&ft_info, fte); ie_build_fast_bss_transition(&ft_info, kck_len, fte);
iov[iov_elems].iov_base = fte; iov[iov_elems].iov_base = fte;
iov[iov_elems].iov_len = fte[1] + 2; iov[iov_elems].iov_len = fte[1] + 2;
@ -330,6 +331,7 @@ static int ft_process_ies(struct ft_sm *ft, const uint8_t *ies, size_t ies_len)
const uint8_t *mde = NULL; const uint8_t *mde = NULL;
const uint8_t *fte = NULL; const uint8_t *fte = NULL;
struct handshake_state *hs = ft->hs; struct handshake_state *hs = ft->hs;
uint32_t kck_len = handshake_state_get_kck_len(hs);
bool is_rsn; bool is_rsn;
/* Check 802.11r IEs */ /* Check 802.11r IEs */
@ -434,7 +436,7 @@ static int ft_process_ies(struct ft_sm *ft, const uint8_t *ies, size_t ies_len)
goto ft_error; goto ft_error;
if (ie_parse_fast_bss_transition_from_data(fte, fte[1] + 2, if (ie_parse_fast_bss_transition_from_data(fte, fte[1] + 2,
&ft_info) < 0) kck_len, &ft_info) < 0)
goto ft_error; goto ft_error;
if (ft_info.mic_element_count != 0 || if (ft_info.mic_element_count != 0 ||
@ -524,6 +526,7 @@ static int ft_rx_associate(struct auth_proto *ap, const uint8_t *frame,
{ {
struct ft_sm *ft = l_container_of(ap, struct ft_sm, ap); struct ft_sm *ft = l_container_of(ap, struct ft_sm, ap);
struct handshake_state *hs = ft->hs; struct handshake_state *hs = ft->hs;
uint32_t kck_len = handshake_state_get_kck_len(hs);
const uint8_t *rsne = NULL; const uint8_t *rsne = NULL;
const uint8_t *mde = NULL; const uint8_t *mde = NULL;
const uint8_t *fte = NULL; const uint8_t *fte = NULL;
@ -589,7 +592,7 @@ static int ft_rx_associate(struct auth_proto *ap, const uint8_t *frame,
uint8_t mic[16]; uint8_t mic[16];
if (ie_parse_fast_bss_transition_from_data(fte, fte[1] + 2, if (ie_parse_fast_bss_transition_from_data(fte, fte[1] + 2,
&ft_info) < 0) kck_len, &ft_info) < 0)
return -EBADMSG; return -EBADMSG;
/* /*
@ -665,6 +668,7 @@ static bool ft_start(struct auth_proto *ap)
{ {
struct ft_sm *ft = l_container_of(ap, struct ft_sm, ap); struct ft_sm *ft = l_container_of(ap, struct ft_sm, ap);
struct handshake_state *hs = ft->hs; struct handshake_state *hs = ft->hs;
uint32_t kck_len = handshake_state_get_kck_len(hs);
bool is_rsn = hs->supplicant_ie != NULL; bool is_rsn = hs->supplicant_ie != NULL;
uint8_t mde[5]; uint8_t mde[5];
struct iovec iov[3]; struct iovec iov[3];
@ -732,7 +736,7 @@ static bool ft_start(struct auth_proto *ap)
memcpy(ft_info.snonce, hs->snonce, 32); memcpy(ft_info.snonce, hs->snonce, 32);
fte = alloca(256); fte = alloca(256);
ie_build_fast_bss_transition(&ft_info, fte); ie_build_fast_bss_transition(&ft_info, kck_len, fte);
iov[iov_elems].iov_base = fte; iov[iov_elems].iov_base = fte;
iov[iov_elems].iov_len = fte[1] + 2; iov[iov_elems].iov_len = fte[1] + 2;

View File

@ -2010,14 +2010,14 @@ bool ie_build_mobility_domain(uint16_t mdid, bool ft_over_ds, bool resource_req,
return true; return true;
} }
int ie_parse_fast_bss_transition(struct ie_tlv_iter *iter, int ie_parse_fast_bss_transition(struct ie_tlv_iter *iter, uint32_t mic_len,
struct ie_ft_info *info) struct ie_ft_info *info)
{ {
const uint8_t *data; const uint8_t *data;
uint8_t len, subelem_id, subelem_len; uint8_t len, subelem_id, subelem_len;
len = ie_tlv_iter_get_length(iter); len = ie_tlv_iter_get_length(iter);
if (len < 82) if (len < 66 + mic_len)
return -EINVAL; return -EINVAL;
data = ie_tlv_iter_get_data(iter); data = ie_tlv_iter_get_data(iter);
@ -2026,14 +2026,14 @@ int ie_parse_fast_bss_transition(struct ie_tlv_iter *iter,
info->mic_element_count = data[1]; info->mic_element_count = data[1];
memcpy(info->mic, data + 2, 16); memcpy(info->mic, data + 2, mic_len);
memcpy(info->anonce, data + 18, 32); memcpy(info->anonce, data + mic_len + 2, 32);
memcpy(info->snonce, data + 50, 32); memcpy(info->snonce, data + mic_len + 34, 32);
len -= 82; len -= 66 + mic_len;
data += 82; data += 66 + mic_len;
while (len >= 2) { while (len >= 2) {
subelem_id = *data++; subelem_id = *data++;
@ -2104,7 +2104,8 @@ int ie_parse_fast_bss_transition(struct ie_tlv_iter *iter,
} }
int ie_parse_fast_bss_transition_from_data(const uint8_t *data, uint8_t len, int ie_parse_fast_bss_transition_from_data(const uint8_t *data, uint8_t len,
struct ie_ft_info *info) uint32_t mic_len,
struct ie_ft_info *info)
{ {
struct ie_tlv_iter iter; struct ie_tlv_iter iter;
@ -2116,28 +2117,29 @@ int ie_parse_fast_bss_transition_from_data(const uint8_t *data, uint8_t len,
if (ie_tlv_iter_get_tag(&iter) != IE_TYPE_FAST_BSS_TRANSITION) if (ie_tlv_iter_get_tag(&iter) != IE_TYPE_FAST_BSS_TRANSITION)
return -EPROTOTYPE; return -EPROTOTYPE;
return ie_parse_fast_bss_transition(&iter, info); return ie_parse_fast_bss_transition(&iter, mic_len, info);
} }
bool ie_build_fast_bss_transition(const struct ie_ft_info *info, uint8_t *to) bool ie_build_fast_bss_transition(const struct ie_ft_info *info,
uint32_t mic_len, uint8_t *to)
{ {
uint8_t *len; uint8_t *len;
*to++ = IE_TYPE_FAST_BSS_TRANSITION; *to++ = IE_TYPE_FAST_BSS_TRANSITION;
len = to++; len = to++;
*len = 82; *len = (mic_len == 16) ? 82 : 90;
to[0] = 0x00; to[0] = 0x00;
to[1] = info->mic_element_count; to[1] = info->mic_element_count;
memcpy(to + 2, info->mic, 16); memcpy(to + 2, info->mic, mic_len);
memcpy(to + 18, info->anonce, 32); memcpy(to + mic_len + 2, info->anonce, 32);
memcpy(to + 50, info->snonce, 32); memcpy(to + mic_len + 34, info->snonce, 32);
to += 82; to += (mic_len == 16) ? 82 : 90;
if (info->r1khid_present) { if (info->r1khid_present) {
to[0] = 1; to[0] = 1;

View File

@ -324,7 +324,7 @@ enum ie_bss_capability {
struct ie_ft_info { struct ie_ft_info {
uint8_t mic_element_count; uint8_t mic_element_count;
uint8_t mic[16]; uint8_t mic[24];
uint8_t anonce[32]; uint8_t anonce[32];
uint8_t snonce[32]; uint8_t snonce[32];
uint8_t r0khid[48]; uint8_t r0khid[48];
@ -449,10 +449,13 @@ bool ie_build_mobility_domain(uint16_t mdid, bool ft_over_ds,
bool resource_req, uint8_t *to); bool resource_req, uint8_t *to);
int ie_parse_fast_bss_transition(struct ie_tlv_iter *iter, int ie_parse_fast_bss_transition(struct ie_tlv_iter *iter,
struct ie_ft_info *info); uint32_t mic_len,
struct ie_ft_info *info);
int ie_parse_fast_bss_transition_from_data(const uint8_t *data, uint8_t len, int ie_parse_fast_bss_transition_from_data(const uint8_t *data, uint8_t len,
struct ie_ft_info *info); uint32_t mic_len,
bool ie_build_fast_bss_transition(const struct ie_ft_info *info, uint8_t *to); struct ie_ft_info *info);
bool ie_build_fast_bss_transition(const struct ie_ft_info *info,
uint32_t mic_len, uint8_t *to);
int ie_parse_neighbor_report(struct ie_tlv_iter *iter, int ie_parse_neighbor_report(struct ie_tlv_iter *iter,
struct ie_neighbor_report_info *info); struct ie_neighbor_report_info *info);

View File

@ -1649,6 +1649,8 @@ static void netdev_connect_event(struct l_genl_msg *msg, struct netdev *netdev)
} }
if (fte) { if (fte) {
uint32_t kck_len =
handshake_state_get_kck_len(netdev->handshake);
/* /*
* If we are here, then most likely we have a FullMac * If we are here, then most likely we have a FullMac
* hw performing initial mobility association. We need * hw performing initial mobility association. We need
@ -1657,7 +1659,7 @@ static void netdev_connect_event(struct l_genl_msg *msg, struct netdev *netdev)
* sanitize the contents and just assume they're okay. * sanitize the contents and just assume they're okay.
*/ */
if (ie_parse_fast_bss_transition_from_data(fte, if (ie_parse_fast_bss_transition_from_data(fte,
fte[1] + 2, &ft_info) >= 0) { fte[1] + 2, kck_len, &ft_info) >= 0) {
handshake_state_set_fte(netdev->handshake, fte); handshake_state_set_fte(netdev->handshake, fte);
handshake_state_set_kh_ids(netdev->handshake, handshake_state_set_kh_ids(netdev->handshake,
ft_info.r0khid, ft_info.r0khid,