mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-01-17 18:34:03 -05:00
FT: Fix FTIE generation for 4-way handshake after FT protocol run
wpa_insert_pmkid() did not support cases where the original RSN IE included any PMKIDs. That case can happen when PTK rekeying through 4-way handshake is used after FT protocol run. Such a 4-way handshake used to fail with wpa_supplicant being unable to build the EAPOL-Key msg 2/4. Fix this by extending wpa_insert_pmkid() to support removal of the old PMKIDs, if needed. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
cc02fd3eff
commit
59e78c2408
@ -2298,14 +2298,19 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
|
|||||||
pos += wpa_ie_len;
|
pos += wpa_ie_len;
|
||||||
#ifdef CONFIG_IEEE80211R
|
#ifdef CONFIG_IEEE80211R
|
||||||
if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
|
if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) {
|
||||||
int res = wpa_insert_pmkid(kde, pos - kde, sm->pmk_r1_name);
|
int res;
|
||||||
|
size_t elen;
|
||||||
|
|
||||||
|
elen = pos - kde;
|
||||||
|
res = wpa_insert_pmkid(kde, &elen, sm->pmk_r1_name);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
wpa_printf(MSG_ERROR, "FT: Failed to insert "
|
wpa_printf(MSG_ERROR, "FT: Failed to insert "
|
||||||
"PMKR1Name into RSN IE in EAPOL-Key data");
|
"PMKR1Name into RSN IE in EAPOL-Key data");
|
||||||
os_free(kde);
|
os_free(kde);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pos += res;
|
pos -= wpa_ie_len;
|
||||||
|
pos += elen;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IEEE80211R */
|
#endif /* CONFIG_IEEE80211R */
|
||||||
if (gtk) {
|
if (gtk) {
|
||||||
|
@ -1280,13 +1280,13 @@ int wpa_compare_rsn_ie(int ft_initial_assoc,
|
|||||||
|
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211R
|
#ifdef CONFIG_IEEE80211R
|
||||||
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)
|
||||||
{
|
{
|
||||||
u8 *start, *end, *rpos, *rend;
|
u8 *start, *end, *rpos, *rend;
|
||||||
int added = 0;
|
int added = 0;
|
||||||
|
|
||||||
start = ies;
|
start = ies;
|
||||||
end = ies + ies_len;
|
end = ies + *ies_len;
|
||||||
|
|
||||||
while (start < end) {
|
while (start < end) {
|
||||||
if (*start == WLAN_EID_RSN)
|
if (*start == WLAN_EID_RSN)
|
||||||
@ -1339,11 +1339,29 @@ int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid)
|
|||||||
added += 2 + PMKID_LEN;
|
added += 2 + PMKID_LEN;
|
||||||
start[1] += 2 + PMKID_LEN;
|
start[1] += 2 + PMKID_LEN;
|
||||||
} else {
|
} else {
|
||||||
/* PMKID-Count was included; use it */
|
u16 num_pmkid;
|
||||||
if (WPA_GET_LE16(rpos) != 0) {
|
|
||||||
wpa_printf(MSG_ERROR, "FT: Unexpected PMKID "
|
if (rend - rpos < 2)
|
||||||
"in RSN IE in EAPOL-Key data");
|
|
||||||
return -1;
|
return -1;
|
||||||
|
num_pmkid = WPA_GET_LE16(rpos);
|
||||||
|
/* PMKID-Count was included; use it */
|
||||||
|
if (num_pmkid != 0) {
|
||||||
|
u8 *after;
|
||||||
|
|
||||||
|
if (num_pmkid * PMKID_LEN > rend - rpos - 2)
|
||||||
|
return -1;
|
||||||
|
/*
|
||||||
|
* PMKID may have been included in RSN IE in
|
||||||
|
* (Re)Association Request frame, so remove the old
|
||||||
|
* PMKID(s) first before adding the new one.
|
||||||
|
*/
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"FT: Remove %u old PMKID(s) from RSN IE",
|
||||||
|
num_pmkid);
|
||||||
|
after = rpos + 2 + num_pmkid * PMKID_LEN;
|
||||||
|
os_memmove(rpos + 2, after, rend - after);
|
||||||
|
start[1] -= num_pmkid * PMKID_LEN;
|
||||||
|
added -= num_pmkid * PMKID_LEN;
|
||||||
}
|
}
|
||||||
WPA_PUT_LE16(rpos, 1);
|
WPA_PUT_LE16(rpos, 1);
|
||||||
rpos += 2;
|
rpos += 2;
|
||||||
@ -1356,7 +1374,9 @@ int wpa_insert_pmkid(u8 *ies, size_t ies_len, const u8 *pmkid)
|
|||||||
wpa_hexdump(MSG_DEBUG, "FT: RSN IE after modification "
|
wpa_hexdump(MSG_DEBUG, "FT: RSN IE after modification "
|
||||||
"(PMKID inserted)", start, 2 + start[1]);
|
"(PMKID inserted)", start, 2 + start[1]);
|
||||||
|
|
||||||
return added;
|
*ies_len += added;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_IEEE80211R */
|
#endif /* CONFIG_IEEE80211R */
|
||||||
|
|
||||||
|
@ -409,7 +409,7 @@ u32 wpa_akm_to_suite(int akm);
|
|||||||
int wpa_compare_rsn_ie(int ft_initial_assoc,
|
int wpa_compare_rsn_ie(int ft_initial_assoc,
|
||||||
const u8 *ie1, size_t ie1len,
|
const u8 *ie1, size_t ie1len,
|
||||||
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 {
|
struct wpa_ft_ies {
|
||||||
const u8 *mdie;
|
const u8 *mdie;
|
||||||
|
@ -364,13 +364,12 @@ int wpa_supplicant_send_2_of_4(struct wpa_sm *sm, const unsigned char *dst,
|
|||||||
if (rsn_ie_buf == NULL)
|
if (rsn_ie_buf == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len);
|
os_memcpy(rsn_ie_buf, wpa_ie, wpa_ie_len);
|
||||||
res = wpa_insert_pmkid(rsn_ie_buf, wpa_ie_len,
|
res = wpa_insert_pmkid(rsn_ie_buf, &wpa_ie_len,
|
||||||
sm->pmk_r1_name);
|
sm->pmk_r1_name);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
os_free(rsn_ie_buf);
|
os_free(rsn_ie_buf);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wpa_ie_len += res;
|
|
||||||
|
|
||||||
if (sm->assoc_resp_ies) {
|
if (sm->assoc_resp_ies) {
|
||||||
os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies,
|
os_memcpy(rsn_ie_buf + wpa_ie_len, sm->assoc_resp_ies,
|
||||||
|
Loading…
Reference in New Issue
Block a user