From 9ceca7a5214731fbe90ffe70fdbc4007d6774df6 Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Wed, 1 Feb 2017 11:58:40 +0100 Subject: [PATCH] ie: Parse GTK and IGTK subelements in FTE Parse the contents of the GTK and IGTK subelements in an FT IE instead of working with buffers containing the whole subelement. Some more validation of the subelement contents. Drop support for GTK / IGTK when building the FTE (unused). --- src/ie.c | 42 +++++++++++++++++++++++------------------- src/ie.h | 8 ++++++-- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/ie.c b/src/ie.c index 743240e4..e4955219 100644 --- a/src/ie.c +++ b/src/ie.c @@ -1460,8 +1460,18 @@ int ie_parse_fast_bss_transition(struct ie_tlv_iter *iter, if (subelem_len < 35 || subelem_len > 51) return -EINVAL; - memcpy(info->gtk, data, subelem_len); - info->gtk_len = subelem_len; + info->gtk_key_id = util_bit_field(data[0], 0, 2); + info->gtk_len = data[2]; + + /* + * Check Wrapped Key field length is Key Length plus + * padding (0 - 7 bytes) plus 8 bytes for AES key wrap. + */ + if (align_len(info->gtk_len, 8) + 8 != subelem_len - 11) + return -EINVAL; + + memcpy(info->gtk_rsc, data + 3, 8); + memcpy(info->gtk, data + 11, subelem_len - 11); break; case 3: @@ -1475,11 +1485,17 @@ int ie_parse_fast_bss_transition(struct ie_tlv_iter *iter, break; case 4: - if (subelem_len < 1) + if (subelem_len != 33) return -EINVAL; - memcpy(info->igtk, data, subelem_len); - info->igtk_len = subelem_len; + info->igtk_key_id = l_get_le16(data); + memcpy(info->igtk_ipn, data + 2, 6); + info->igtk_len = data[8]; + + if (info->igtk_len > 16) + return -EINVAL; + + memcpy(info->igtk, data + 9, subelem_len - 9); break; } @@ -1538,13 +1554,7 @@ bool ie_build_fast_bss_transition(const struct ie_ft_info *info, uint8_t *to) *len += 8; } - if (info->gtk_len) { - to[0] = 2; - to[1] = info->gtk_len; - memcpy(to + 2, info->gtk, info->gtk_len); - to += 2 + info->gtk_len; - *len += 2 + info->gtk_len; - } + L_WARN_ON(info->gtk_len); /* Not implemented */ if (info->r0khid_len) { to[0] = 3; @@ -1554,13 +1564,7 @@ bool ie_build_fast_bss_transition(const struct ie_ft_info *info, uint8_t *to) *len += 2 + info->r0khid_len; } - if (info->igtk_len) { - to[0] = 4; - to[1] = info->igtk_len; - memcpy(to + 2, info->igtk, info->igtk_len); - to += 2 + info->igtk_len; - *len += 2 + info->igtk_len; - } + L_WARN_ON(info->igtk_len); /* Not implemented */ return true; } diff --git a/src/ie.h b/src/ie.h index 6280a5fa..7fd9cfb5 100644 --- a/src/ie.h +++ b/src/ie.h @@ -238,10 +238,14 @@ struct ie_ft_info { size_t r0khid_len; uint8_t r1khid[6]; bool r1khid_present:1; - uint8_t gtk[51]; + uint8_t gtk_key_id; uint8_t gtk_len; - uint8_t igtk[255]; + uint8_t gtk_rsc[8]; + uint8_t gtk[40]; + uint16_t igtk_key_id; + uint8_t igtk_ipn[6]; uint8_t igtk_len; + uint8_t igtk[24]; }; /* See chapter 8.4.2.47 for radio measurement capability details */