wlantest: Get STA IEs based on EAPOL-Key msg 2/4 before PTK derivation

The previous implementation tried to update STA IE information based on
EAPOL-Key msg 2/4 to be able to handle captures that do not include the
(Re)Association Request frame. This was not sufficient (OSEN was not
included) and was done too late (the parsed information is needed for
PMK-to-PTK derivation).

Move the IE update step to happen before trying to derive the PTK if no
(Re)Association Request frame has been seen.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2020-02-28 00:31:33 +02:00
parent b8f6b0713a
commit a8a277c169
3 changed files with 31 additions and 31 deletions

View file

@ -257,7 +257,35 @@ static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
} }
os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN); os_memcpy(sta->snonce, hdr->key_nonce, WPA_NONCE_LEN);
key_info = WPA_GET_BE16(hdr->key_info); key_info = WPA_GET_BE16(hdr->key_info);
key_data = mic + mic_len + 2;
key_data_len = WPA_GET_BE16(mic + mic_len); key_data_len = WPA_GET_BE16(mic + mic_len);
if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
return;
}
if (!sta->assocreq_seen) {
struct ieee802_11_elems elems;
os_memset(&elems, 0, sizeof(elems));
if (ie.wpa_ie) {
elems.wpa_ie = ie.wpa_ie + 2;
elems.wpa_ie_len = ie.wpa_ie_len - 2;
}
if (ie.rsn_ie) {
elems.rsn_ie = ie.rsn_ie + 2;
elems.rsn_ie_len = ie.rsn_ie_len - 2;
}
if (ie.osen) {
elems.osen = ie.osen + 2;
elems.osen_len = ie.osen_len - 2;
}
wpa_printf(MSG_DEBUG,
"Update STA data based on IEs in EAPOL-Key 2/4");
sta_update_assoc(sta, &elems);
}
derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len); derive_ptk(wt, bss, sta, key_info & WPA_KEY_INFO_TYPE_MASK, data, len);
if (!sta->ptk_set && !sta->tptk_set) { if (!sta->ptk_set && !sta->tptk_set) {
@ -281,18 +309,10 @@ static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
} }
add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/4"); add_note(wt, MSG_DEBUG, "Valid MIC found in EAPOL-Key 2/4");
key_data = mic + mic_len + 2;
if (wpa_supplicant_parse_ies(key_data, key_data_len, &ie) < 0) {
add_note(wt, MSG_INFO, "Failed to parse EAPOL-Key Key Data");
return;
}
if (ie.wpa_ie) { if (ie.wpa_ie) {
wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE", wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - WPA IE",
ie.wpa_ie, ie.wpa_ie_len); ie.wpa_ie, ie.wpa_ie_len);
if (os_memcmp(ie.wpa_ie, sta->rsnie, ie.wpa_ie_len) != 0) { if (os_memcmp(ie.wpa_ie, sta->rsnie, ie.wpa_ie_len) != 0) {
struct ieee802_11_elems elems;
add_note(wt, MSG_INFO, add_note(wt, MSG_INFO,
"Mismatch in WPA IE between EAPOL-Key 2/4 " "Mismatch in WPA IE between EAPOL-Key 2/4 "
"and (Re)Association Request from " MACSTR, "and (Re)Association Request from " MACSTR,
@ -303,17 +323,6 @@ static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
"Request", "Request",
sta->rsnie, sta->rsnie,
sta->rsnie[0] ? 2 + sta->rsnie[1] : 0); sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
/*
* The sniffer may have missed (Re)Association
* Request, so try to survive with the information from
* EAPOL-Key.
*/
os_memset(&elems, 0, sizeof(elems));
elems.wpa_ie = ie.wpa_ie + 2;
elems.wpa_ie_len = ie.wpa_ie_len - 2;
wpa_printf(MSG_DEBUG, "Update STA data based on WPA "
"IE in EAPOL-Key 2/4");
sta_update_assoc(sta, &elems);
} }
} }
@ -321,7 +330,6 @@ static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE", wpa_hexdump(MSG_MSGDUMP, "EAPOL-Key Key Data - RSN IE",
ie.rsn_ie, ie.rsn_ie_len); ie.rsn_ie, ie.rsn_ie_len);
if (os_memcmp(ie.rsn_ie, sta->rsnie, ie.rsn_ie_len) != 0) { if (os_memcmp(ie.rsn_ie, sta->rsnie, ie.rsn_ie_len) != 0) {
struct ieee802_11_elems elems;
add_note(wt, MSG_INFO, add_note(wt, MSG_INFO,
"Mismatch in RSN IE between EAPOL-Key 2/4 " "Mismatch in RSN IE between EAPOL-Key 2/4 "
"and (Re)Association Request from " MACSTR, "and (Re)Association Request from " MACSTR,
@ -332,17 +340,6 @@ static void rx_data_eapol_key_2_of_4(struct wlantest *wt, const u8 *dst,
"Request", "Request",
sta->rsnie, sta->rsnie,
sta->rsnie[0] ? 2 + sta->rsnie[1] : 0); sta->rsnie[0] ? 2 + sta->rsnie[1] : 0);
/*
* The sniffer may have missed (Re)Association
* Request, so try to survive with the information from
* EAPOL-Key.
*/
os_memset(&elems, 0, sizeof(elems));
elems.rsn_ie = ie.rsn_ie + 2;
elems.rsn_ie_len = ie.rsn_ie_len - 2;
wpa_printf(MSG_DEBUG, "Update STA data based on RSN "
"IE in EAPOL-Key 2/4");
sta_update_assoc(sta, &elems);
} }
} }
} }

View file

@ -640,6 +640,7 @@ static void rx_mgmt_assoc_req(struct wlantest *wt, const u8 *data, size_t len)
os_memcpy(sta->assocreq_ies, mgmt->u.assoc_req.variable, os_memcpy(sta->assocreq_ies, mgmt->u.assoc_req.variable,
sta->assocreq_ies_len); sta->assocreq_ies_len);
sta->assocreq_seen = 1;
sta_update_assoc(sta, &elems); sta_update_assoc(sta, &elems);
} }
@ -875,6 +876,7 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data,
os_memcpy(sta->assocreq_ies, mgmt->u.reassoc_req.variable, os_memcpy(sta->assocreq_ies, mgmt->u.reassoc_req.variable,
sta->assocreq_ies_len); sta->assocreq_ies_len);
sta->assocreq_seen = 1;
sta_update_assoc(sta, &elems); sta_update_assoc(sta, &elems);
/* TODO: FT protocol: verify FTE MIC and update GTK/IGTK for the BSS */ /* TODO: FT protocol: verify FTE MIC and update GTK/IGTK for the BSS */

View file

@ -82,6 +82,7 @@ struct wlantest_sta {
u8 ap_sa_query_tr[2]; u8 ap_sa_query_tr[2];
u8 sta_sa_query_tr[2]; u8 sta_sa_query_tr[2];
u32 counters[NUM_WLANTEST_STA_COUNTER]; u32 counters[NUM_WLANTEST_STA_COUNTER];
int assocreq_seen;
u16 assocreq_capab_info; u16 assocreq_capab_info;
u16 assocreq_listen_int; u16 assocreq_listen_int;
u8 *assocreq_ies; u8 *assocreq_ies;