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:
parent
4097a49669
commit
1accf534dc
14
src/ft.c
14
src/ft.c
@ -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;
|
||||||
|
34
src/ie.c
34
src/ie.c
@ -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;
|
||||||
|
11
src/ie.h
11
src/ie.h
@ -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);
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user