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];
int iov_elems = 0;
struct handshake_state *hs = ft->hs;
uint32_t kck_len = handshake_state_get_kck_len(hs);
bool is_rsn = hs->supplicant_ie != 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);
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))
goto error;
/* 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_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 *fte = NULL;
struct handshake_state *hs = ft->hs;
uint32_t kck_len = handshake_state_get_kck_len(hs);
bool is_rsn;
/* 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;
if (ie_parse_fast_bss_transition_from_data(fte, fte[1] + 2,
&ft_info) < 0)
kck_len, &ft_info) < 0)
goto ft_error;
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 handshake_state *hs = ft->hs;
uint32_t kck_len = handshake_state_get_kck_len(hs);
const uint8_t *rsne = NULL;
const uint8_t *mde = 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];
if (ie_parse_fast_bss_transition_from_data(fte, fte[1] + 2,
&ft_info) < 0)
kck_len, &ft_info) < 0)
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 handshake_state *hs = ft->hs;
uint32_t kck_len = handshake_state_get_kck_len(hs);
bool is_rsn = hs->supplicant_ie != NULL;
uint8_t mde[5];
struct iovec iov[3];
@ -732,7 +736,7 @@ static bool ft_start(struct auth_proto *ap)
memcpy(ft_info.snonce, hs->snonce, 32);
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_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;
}
int ie_parse_fast_bss_transition(struct ie_tlv_iter *iter,
struct ie_ft_info *info)
int ie_parse_fast_bss_transition(struct ie_tlv_iter *iter, uint32_t mic_len,
struct ie_ft_info *info)
{
const uint8_t *data;
uint8_t len, subelem_id, subelem_len;
len = ie_tlv_iter_get_length(iter);
if (len < 82)
if (len < 66 + mic_len)
return -EINVAL;
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];
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;
data += 82;
len -= 66 + mic_len;
data += 66 + mic_len;
while (len >= 2) {
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,
struct ie_ft_info *info)
uint32_t mic_len,
struct ie_ft_info *info)
{
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)
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;
*to++ = IE_TYPE_FAST_BSS_TRANSITION;
len = to++;
*len = 82;
*len = (mic_len == 16) ? 82 : 90;
to[0] = 0x00;
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) {
to[0] = 1;

View File

@ -324,7 +324,7 @@ enum ie_bss_capability {
struct ie_ft_info {
uint8_t mic_element_count;
uint8_t mic[16];
uint8_t mic[24];
uint8_t anonce[32];
uint8_t snonce[32];
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);
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,
struct ie_ft_info *info);
bool ie_build_fast_bss_transition(const struct ie_ft_info *info, uint8_t *to);
uint32_t mic_len,
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,
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) {
uint32_t kck_len =
handshake_state_get_kck_len(netdev->handshake);
/*
* If we are here, then most likely we have a FullMac
* 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.
*/
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_kh_ids(netdev->handshake,
ft_info.r0khid,