mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2024-11-28 18:28:23 -05:00
FT: Share IE parser implementation for Authenticator and Supplicant
These are almost identical, so there is no point in using separate implementations.
This commit is contained in:
parent
c3c828ebfd
commit
6554237f38
@ -29,28 +29,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_IEEE80211R
|
#ifdef CONFIG_IEEE80211R
|
||||||
|
|
||||||
struct wpa_ft_ies {
|
|
||||||
const u8 *mdie;
|
|
||||||
size_t mdie_len;
|
|
||||||
const u8 *ftie;
|
|
||||||
size_t ftie_len;
|
|
||||||
const u8 *r1kh_id;
|
|
||||||
const u8 *gtk;
|
|
||||||
size_t gtk_len;
|
|
||||||
const u8 *r0kh_id;
|
|
||||||
size_t r0kh_id_len;
|
|
||||||
const u8 *rsn;
|
|
||||||
size_t rsn_len;
|
|
||||||
const u8 *rsn_pmkid;
|
|
||||||
const u8 *ric;
|
|
||||||
size_t ric_len;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
|
|
||||||
struct wpa_ft_ies *parse);
|
|
||||||
|
|
||||||
|
|
||||||
static int wpa_ft_rrb_send(struct wpa_authenticator *wpa_auth, const u8 *dst,
|
static int wpa_ft_rrb_send(struct wpa_authenticator *wpa_auth, const u8 *dst,
|
||||||
const u8 *data, size_t data_len)
|
const u8 *data, size_t data_len)
|
||||||
{
|
{
|
||||||
@ -728,143 +706,6 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
|
|
||||||
struct wpa_ft_ies *parse)
|
|
||||||
{
|
|
||||||
const u8 *end, *pos;
|
|
||||||
|
|
||||||
parse->ftie = ie;
|
|
||||||
parse->ftie_len = ie_len;
|
|
||||||
|
|
||||||
pos = ie + sizeof(struct rsn_ftie);
|
|
||||||
end = ie + ie_len;
|
|
||||||
|
|
||||||
while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
|
|
||||||
switch (pos[0]) {
|
|
||||||
case FTIE_SUBELEM_R1KH_ID:
|
|
||||||
if (pos[1] != FT_R1KH_ID_LEN) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: Invalid R1KH-ID "
|
|
||||||
"length in FTIE: %d", pos[1]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
parse->r1kh_id = pos + 2;
|
|
||||||
break;
|
|
||||||
case FTIE_SUBELEM_GTK:
|
|
||||||
parse->gtk = pos + 2;
|
|
||||||
parse->gtk_len = pos[1];
|
|
||||||
break;
|
|
||||||
case FTIE_SUBELEM_R0KH_ID:
|
|
||||||
if (pos[1] < 1 || pos[1] > FT_R0KH_ID_MAX_LEN) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: Invalid R0KH-ID "
|
|
||||||
"length in FTIE: %d", pos[1]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
parse->r0kh_id = pos + 2;
|
|
||||||
parse->r0kh_id_len = pos[1];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos += 2 + pos[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
|
|
||||||
struct wpa_ft_ies *parse)
|
|
||||||
{
|
|
||||||
const u8 *end, *pos;
|
|
||||||
struct wpa_ie_data data;
|
|
||||||
int ret;
|
|
||||||
const struct rsn_ftie *ftie;
|
|
||||||
int prot_ie_count = 0;
|
|
||||||
|
|
||||||
os_memset(parse, 0, sizeof(*parse));
|
|
||||||
if (ies == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pos = ies;
|
|
||||||
end = ies + ies_len;
|
|
||||||
while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
|
|
||||||
switch (pos[0]) {
|
|
||||||
case WLAN_EID_RSN:
|
|
||||||
parse->rsn = pos + 2;
|
|
||||||
parse->rsn_len = pos[1];
|
|
||||||
ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
|
|
||||||
parse->rsn_len + 2,
|
|
||||||
&data);
|
|
||||||
if (ret < 0) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: Failed to parse "
|
|
||||||
"RSN IE: %d", ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (data.num_pmkid == 1 && data.pmkid)
|
|
||||||
parse->rsn_pmkid = data.pmkid;
|
|
||||||
break;
|
|
||||||
case WLAN_EID_MOBILITY_DOMAIN:
|
|
||||||
parse->mdie = pos + 2;
|
|
||||||
parse->mdie_len = pos[1];
|
|
||||||
break;
|
|
||||||
case WLAN_EID_FAST_BSS_TRANSITION:
|
|
||||||
if (pos[1] < sizeof(*ftie))
|
|
||||||
return -1;
|
|
||||||
ftie = (const struct rsn_ftie *) (pos + 2);
|
|
||||||
prot_ie_count = ftie->mic_control[1];
|
|
||||||
if (wpa_ft_parse_ftie(pos + 2, pos[1], parse) < 0)
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case WLAN_EID_RIC_DATA:
|
|
||||||
if (parse->ric == NULL)
|
|
||||||
parse->ric = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos += 2 + pos[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prot_ie_count == 0)
|
|
||||||
return 0; /* no MIC */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check that the protected IE count matches with IEs included in the
|
|
||||||
* frame.
|
|
||||||
*/
|
|
||||||
if (parse->rsn)
|
|
||||||
prot_ie_count--;
|
|
||||||
if (parse->mdie)
|
|
||||||
prot_ie_count--;
|
|
||||||
if (parse->ftie)
|
|
||||||
prot_ie_count--;
|
|
||||||
if (prot_ie_count < 0) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
|
|
||||||
"the protected IE count");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prot_ie_count == 0 && parse->ric) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
|
|
||||||
"included in protected IE count");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine the end of the RIC IE(s) */
|
|
||||||
pos = parse->ric;
|
|
||||||
while (pos && pos + 2 <= end && pos + 2 + pos[1] <= end &&
|
|
||||||
prot_ie_count) {
|
|
||||||
prot_ie_count--;
|
|
||||||
pos += 2 + pos[1];
|
|
||||||
}
|
|
||||||
parse->ric_len = pos - parse->ric;
|
|
||||||
if (prot_ie_count) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
|
|
||||||
"frame", (int) prot_ie_count);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
|
static inline int wpa_auth_set_key(struct wpa_authenticator *wpa_auth,
|
||||||
int vlan_id,
|
int vlan_id,
|
||||||
enum wpa_alg alg, const u8 *addr, int idx,
|
enum wpa_alg alg, const u8 *addr, int idx,
|
||||||
|
@ -188,6 +188,154 @@ int wpa_ft_mic(const u8 *kck, const u8 *sta_addr, const u8 *ap_addr,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
|
||||||
|
struct wpa_ft_ies *parse)
|
||||||
|
{
|
||||||
|
const u8 *end, *pos;
|
||||||
|
|
||||||
|
parse->ftie = ie;
|
||||||
|
parse->ftie_len = ie_len;
|
||||||
|
|
||||||
|
pos = ie + sizeof(struct rsn_ftie);
|
||||||
|
end = ie + ie_len;
|
||||||
|
|
||||||
|
while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
|
||||||
|
switch (pos[0]) {
|
||||||
|
case FTIE_SUBELEM_R1KH_ID:
|
||||||
|
if (pos[1] != FT_R1KH_ID_LEN) {
|
||||||
|
wpa_printf(MSG_DEBUG, "FT: Invalid R1KH-ID "
|
||||||
|
"length in FTIE: %d", pos[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
parse->r1kh_id = pos + 2;
|
||||||
|
break;
|
||||||
|
case FTIE_SUBELEM_GTK:
|
||||||
|
parse->gtk = pos + 2;
|
||||||
|
parse->gtk_len = pos[1];
|
||||||
|
break;
|
||||||
|
case FTIE_SUBELEM_R0KH_ID:
|
||||||
|
if (pos[1] < 1 || pos[1] > FT_R0KH_ID_MAX_LEN) {
|
||||||
|
wpa_printf(MSG_DEBUG, "FT: Invalid R0KH-ID "
|
||||||
|
"length in FTIE: %d", pos[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
parse->r0kh_id = pos + 2;
|
||||||
|
parse->r0kh_id_len = pos[1];
|
||||||
|
break;
|
||||||
|
#ifdef CONFIG_IEEE80211W
|
||||||
|
case FTIE_SUBELEM_IGTK:
|
||||||
|
parse->igtk = pos + 2;
|
||||||
|
parse->igtk_len = pos[1];
|
||||||
|
break;
|
||||||
|
#endif /* CONFIG_IEEE80211W */
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 2 + pos[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
|
||||||
|
struct wpa_ft_ies *parse)
|
||||||
|
{
|
||||||
|
const u8 *end, *pos;
|
||||||
|
struct wpa_ie_data data;
|
||||||
|
int ret;
|
||||||
|
const struct rsn_ftie *ftie;
|
||||||
|
int prot_ie_count = 0;
|
||||||
|
|
||||||
|
os_memset(parse, 0, sizeof(*parse));
|
||||||
|
if (ies == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pos = ies;
|
||||||
|
end = ies + ies_len;
|
||||||
|
while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
|
||||||
|
switch (pos[0]) {
|
||||||
|
case WLAN_EID_RSN:
|
||||||
|
parse->rsn = pos + 2;
|
||||||
|
parse->rsn_len = pos[1];
|
||||||
|
ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
|
||||||
|
parse->rsn_len + 2,
|
||||||
|
&data);
|
||||||
|
if (ret < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "FT: Failed to parse "
|
||||||
|
"RSN IE: %d", ret);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (data.num_pmkid == 1 && data.pmkid)
|
||||||
|
parse->rsn_pmkid = data.pmkid;
|
||||||
|
break;
|
||||||
|
case WLAN_EID_MOBILITY_DOMAIN:
|
||||||
|
parse->mdie = pos + 2;
|
||||||
|
parse->mdie_len = pos[1];
|
||||||
|
break;
|
||||||
|
case WLAN_EID_FAST_BSS_TRANSITION:
|
||||||
|
if (pos[1] < sizeof(*ftie))
|
||||||
|
return -1;
|
||||||
|
ftie = (const struct rsn_ftie *) (pos + 2);
|
||||||
|
prot_ie_count = ftie->mic_control[1];
|
||||||
|
if (wpa_ft_parse_ftie(pos + 2, pos[1], parse) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
case WLAN_EID_TIMEOUT_INTERVAL:
|
||||||
|
parse->tie = pos + 2;
|
||||||
|
parse->tie_len = pos[1];
|
||||||
|
break;
|
||||||
|
case WLAN_EID_RIC_DATA:
|
||||||
|
if (parse->ric == NULL)
|
||||||
|
parse->ric = pos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 2 + pos[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prot_ie_count == 0)
|
||||||
|
return 0; /* no MIC */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check that the protected IE count matches with IEs included in the
|
||||||
|
* frame.
|
||||||
|
*/
|
||||||
|
if (parse->rsn)
|
||||||
|
prot_ie_count--;
|
||||||
|
if (parse->mdie)
|
||||||
|
prot_ie_count--;
|
||||||
|
if (parse->ftie)
|
||||||
|
prot_ie_count--;
|
||||||
|
if (prot_ie_count < 0) {
|
||||||
|
wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
|
||||||
|
"the protected IE count");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prot_ie_count == 0 && parse->ric) {
|
||||||
|
wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
|
||||||
|
"included in protected IE count");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine the end of the RIC IE(s) */
|
||||||
|
pos = parse->ric;
|
||||||
|
while (pos && pos + 2 <= end && pos + 2 + pos[1] <= end &&
|
||||||
|
prot_ie_count) {
|
||||||
|
prot_ie_count--;
|
||||||
|
pos += 2 + pos[1];
|
||||||
|
}
|
||||||
|
parse->ric_len = pos - parse->ric;
|
||||||
|
if (prot_ie_count) {
|
||||||
|
wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
|
||||||
|
"frame", (int) prot_ie_count);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif /* CONFIG_IEEE80211R */
|
#endif /* CONFIG_IEEE80211R */
|
||||||
|
|
||||||
|
|
||||||
|
@ -358,4 +358,27 @@ int wpa_compare_rsn_ie(int ft_initial_assoc,
|
|||||||
const u8 *ie2, size_t ie2len);
|
const u8 *ie2, size_t ie2len);
|
||||||
int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid);
|
int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid);
|
||||||
|
|
||||||
|
struct wpa_ft_ies {
|
||||||
|
const u8 *mdie;
|
||||||
|
size_t mdie_len;
|
||||||
|
const u8 *ftie;
|
||||||
|
size_t ftie_len;
|
||||||
|
const u8 *r1kh_id;
|
||||||
|
const u8 *gtk;
|
||||||
|
size_t gtk_len;
|
||||||
|
const u8 *r0kh_id;
|
||||||
|
size_t r0kh_id_len;
|
||||||
|
const u8 *rsn;
|
||||||
|
size_t rsn_len;
|
||||||
|
const u8 *rsn_pmkid;
|
||||||
|
const u8 *tie;
|
||||||
|
size_t tie_len;
|
||||||
|
const u8 *igtk;
|
||||||
|
size_t igtk_len;
|
||||||
|
const u8 *ric;
|
||||||
|
size_t ric_len;
|
||||||
|
};
|
||||||
|
|
||||||
|
int wpa_ft_parse_ies(const u8 *ies, size_t ies_len, struct wpa_ft_ies *parse);
|
||||||
|
|
||||||
#endif /* WPA_COMMON_H */
|
#endif /* WPA_COMMON_H */
|
||||||
|
@ -25,31 +25,6 @@
|
|||||||
|
|
||||||
#ifdef CONFIG_IEEE80211R
|
#ifdef CONFIG_IEEE80211R
|
||||||
|
|
||||||
struct wpa_ft_ies {
|
|
||||||
const u8 *mdie;
|
|
||||||
size_t mdie_len;
|
|
||||||
const u8 *ftie;
|
|
||||||
size_t ftie_len;
|
|
||||||
const u8 *r1kh_id;
|
|
||||||
const u8 *gtk;
|
|
||||||
size_t gtk_len;
|
|
||||||
const u8 *r0kh_id;
|
|
||||||
size_t r0kh_id_len;
|
|
||||||
const u8 *rsn;
|
|
||||||
size_t rsn_len;
|
|
||||||
const u8 *rsn_pmkid;
|
|
||||||
const u8 *tie;
|
|
||||||
size_t tie_len;
|
|
||||||
const u8 *igtk;
|
|
||||||
size_t igtk_len;
|
|
||||||
const u8 *ric;
|
|
||||||
size_t ric_len;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
|
|
||||||
struct wpa_ft_ies *parse);
|
|
||||||
|
|
||||||
|
|
||||||
int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
|
int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
|
||||||
const struct wpa_eapol_key *key,
|
const struct wpa_eapol_key *key,
|
||||||
struct wpa_ptk *ptk, size_t ptk_len)
|
struct wpa_ptk *ptk, size_t ptk_len)
|
||||||
@ -347,153 +322,6 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wpa_ft_parse_ftie(const u8 *ie, size_t ie_len,
|
|
||||||
struct wpa_ft_ies *parse)
|
|
||||||
{
|
|
||||||
const u8 *end, *pos;
|
|
||||||
|
|
||||||
parse->ftie = ie;
|
|
||||||
parse->ftie_len = ie_len;
|
|
||||||
|
|
||||||
pos = ie + sizeof(struct rsn_ftie);
|
|
||||||
end = ie + ie_len;
|
|
||||||
|
|
||||||
while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
|
|
||||||
switch (pos[0]) {
|
|
||||||
case FTIE_SUBELEM_R1KH_ID:
|
|
||||||
if (pos[1] != FT_R1KH_ID_LEN) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: Invalid R1KH-ID "
|
|
||||||
"length in FTIE: %d", pos[1]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
parse->r1kh_id = pos + 2;
|
|
||||||
break;
|
|
||||||
case FTIE_SUBELEM_GTK:
|
|
||||||
parse->gtk = pos + 2;
|
|
||||||
parse->gtk_len = pos[1];
|
|
||||||
break;
|
|
||||||
case FTIE_SUBELEM_R0KH_ID:
|
|
||||||
if (pos[1] < 1 || pos[1] > FT_R0KH_ID_MAX_LEN) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: Invalid R0KH-ID "
|
|
||||||
"length in FTIE: %d", pos[1]);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
parse->r0kh_id = pos + 2;
|
|
||||||
parse->r0kh_id_len = pos[1];
|
|
||||||
break;
|
|
||||||
#ifdef CONFIG_IEEE80211W
|
|
||||||
case FTIE_SUBELEM_IGTK:
|
|
||||||
parse->igtk = pos + 2;
|
|
||||||
parse->igtk_len = pos[1];
|
|
||||||
break;
|
|
||||||
#endif /* CONFIG_IEEE80211W */
|
|
||||||
}
|
|
||||||
|
|
||||||
pos += 2 + pos[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int wpa_ft_parse_ies(const u8 *ies, size_t ies_len,
|
|
||||||
struct wpa_ft_ies *parse)
|
|
||||||
{
|
|
||||||
const u8 *end, *pos;
|
|
||||||
struct wpa_ie_data data;
|
|
||||||
int ret;
|
|
||||||
const struct rsn_ftie *ftie;
|
|
||||||
int prot_ie_count = 0;
|
|
||||||
|
|
||||||
os_memset(parse, 0, sizeof(*parse));
|
|
||||||
if (ies == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
pos = ies;
|
|
||||||
end = ies + ies_len;
|
|
||||||
while (pos + 2 <= end && pos + 2 + pos[1] <= end) {
|
|
||||||
switch (pos[0]) {
|
|
||||||
case WLAN_EID_RSN:
|
|
||||||
parse->rsn = pos + 2;
|
|
||||||
parse->rsn_len = pos[1];
|
|
||||||
ret = wpa_parse_wpa_ie_rsn(parse->rsn - 2,
|
|
||||||
parse->rsn_len + 2,
|
|
||||||
&data);
|
|
||||||
if (ret < 0) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: Failed to parse "
|
|
||||||
"RSN IE: %d", ret);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (data.num_pmkid == 1 && data.pmkid)
|
|
||||||
parse->rsn_pmkid = data.pmkid;
|
|
||||||
break;
|
|
||||||
case WLAN_EID_MOBILITY_DOMAIN:
|
|
||||||
parse->mdie = pos + 2;
|
|
||||||
parse->mdie_len = pos[1];
|
|
||||||
break;
|
|
||||||
case WLAN_EID_FAST_BSS_TRANSITION:
|
|
||||||
if (pos[1] < sizeof(*ftie))
|
|
||||||
return -1;
|
|
||||||
ftie = (const struct rsn_ftie *) (pos + 2);
|
|
||||||
prot_ie_count = ftie->mic_control[1];
|
|
||||||
if (wpa_ft_parse_ftie(pos + 2, pos[1], parse) < 0)
|
|
||||||
return -1;
|
|
||||||
break;
|
|
||||||
case WLAN_EID_TIMEOUT_INTERVAL:
|
|
||||||
parse->tie = pos + 2;
|
|
||||||
parse->tie_len = pos[1];
|
|
||||||
break;
|
|
||||||
case WLAN_EID_RIC_DATA:
|
|
||||||
if (parse->ric == NULL)
|
|
||||||
parse->ric = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos += 2 + pos[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prot_ie_count == 0)
|
|
||||||
return 0; /* no MIC */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check that the protected IE count matches with IEs included in the
|
|
||||||
* frame.
|
|
||||||
*/
|
|
||||||
if (parse->rsn)
|
|
||||||
prot_ie_count--;
|
|
||||||
if (parse->mdie)
|
|
||||||
prot_ie_count--;
|
|
||||||
if (parse->ftie)
|
|
||||||
prot_ie_count--;
|
|
||||||
if (prot_ie_count < 0) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: Some required IEs not included in "
|
|
||||||
"the protected IE count");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prot_ie_count == 0 && parse->ric) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: RIC IE(s) in the frame, but not "
|
|
||||||
"included in protected IE count");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Determine the end of the RIC IE(s) */
|
|
||||||
pos = parse->ric;
|
|
||||||
while (pos && pos + 2 <= end && pos + 2 + pos[1] <= end &&
|
|
||||||
prot_ie_count) {
|
|
||||||
prot_ie_count--;
|
|
||||||
pos += 2 + pos[1];
|
|
||||||
}
|
|
||||||
parse->ric_len = pos - parse->ric;
|
|
||||||
if (prot_ie_count) {
|
|
||||||
wpa_printf(MSG_DEBUG, "FT: %d protected IEs missing from "
|
|
||||||
"frame", (int) prot_ie_count);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid)
|
static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid)
|
||||||
{
|
{
|
||||||
int keylen;
|
int keylen;
|
||||||
|
Loading…
Reference in New Issue
Block a user