From bc0268d053b4db5841f3e73a5600e7d9edcb4345 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 11 Aug 2023 20:35:34 +0300 Subject: [PATCH] wlantest: Guess SAE/OWE group from EAPOL-Key length mismatch The MIC length depends on the negotiated group when SAE-EXT-KEY or OWE key_mgmt is used. wlantest can determine the group if the capture file includes the group negotiation, i.e., the initial association when a PMK was created. However, if the capture file includes only an association using PMKSA caching, the group information is not available. This can result in inability to be able to process the EAPOL-Key frames (e.g., with the "Truncated EAPOL-Key from" message). If the negotiated group is not known and an EAPOL-Key frame length does not seem to match the default expectations for group 19, check whether the alternative lengths for group 20 or 21 would result in a frame that seems to have valid length. If so, update the STA entry with the guessed group and continue processing the EAPOL-Key frames based on this. Signed-off-by: Jouni Malinen --- wlantest/rx_eapol.c | 56 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/wlantest/rx_eapol.c b/wlantest/rx_eapol.c index 742efb92c..c1fe1f224 100644 --- a/wlantest/rx_eapol.c +++ b/wlantest/rx_eapol.c @@ -1428,12 +1428,12 @@ static void rx_data_eapol_key(struct wlantest *wt, const u8 *bssid, { const struct ieee802_1x_hdr *eapol; const struct wpa_eapol_key *hdr; - const u8 *key_data; - u16 key_info, key_length, ver, key_data_length; - size_t mic_len = 16; + const u8 *key_data, *alt_key_data; + u16 key_info, key_length, ver, key_data_length, alt_key_data_length; + size_t mic_len = 16, alt_mic_len; const u8 *mic; struct wlantest_bss *bss; - struct wlantest_sta *sta; + struct wlantest_sta *sta = NULL; bss = bss_get(wt, bssid); if (bss) { @@ -1474,6 +1474,54 @@ static void rx_data_eapol_key(struct wlantest *wt, const u8 *bssid, key_length = WPA_GET_BE16(hdr->key_length); key_data_length = WPA_GET_BE16(mic + mic_len); key_data = mic + mic_len + 2; + + if (key_data + key_data_length != data + len && sta && + ((wpa_key_mgmt_sae_ext_key(sta->key_mgmt) && sta->sae_group == 0) || + (sta->key_mgmt == WPA_KEY_MGMT_OWE && sta->owe_group == 0))) { + /* We do not know which group was used (e.g., due to use of + * PMKSA caching without the initial association included in + * the capture file), so the MIC length might not be correct. + * Try the other options to see if matching EAPOL-Key length + * can be determined. */ + + /* Group 20 */ + alt_mic_len = wpa_mic_len(sta->key_mgmt, 48); + alt_key_data_length = WPA_GET_BE16(mic + alt_mic_len); + alt_key_data = mic + alt_mic_len + 2; + if (len >= sizeof(*hdr) + alt_mic_len + 2 && + alt_key_data + alt_key_data_length == data + len) { + add_note(wt, MSG_INFO, + "Assume group 20 was used to get matching Key MIC length for EAPOL-Key"); + if (wpa_key_mgmt_sae_ext_key(sta->key_mgmt)) + sta->sae_group = 20; + else + sta->owe_group = 20; + mic_len = alt_mic_len; + key_data_length = alt_key_data_length; + key_data = alt_key_data; + goto group_determined; + } + + /* Group 21 */ + alt_mic_len = wpa_mic_len(sta->key_mgmt, 64); + alt_key_data_length = WPA_GET_BE16(mic + alt_mic_len); + alt_key_data = mic + alt_mic_len + 2; + if (len >= sizeof(*hdr) + alt_mic_len + 2 && + alt_key_data + alt_key_data_length == data + len) { + add_note(wt, MSG_INFO, + "Assume group 21 was used to get matching Key MIC length for EAPOL-Key"); + if (wpa_key_mgmt_sae_ext_key(sta->key_mgmt)) + sta->sae_group = 21; + else + sta->owe_group = 21; + mic_len = alt_mic_len; + key_data_length = alt_key_data_length; + key_data = alt_key_data; + goto group_determined; + } + } + +group_determined: if (key_data + key_data_length > data + len) { add_note(wt, MSG_INFO, "Truncated EAPOL-Key from " MACSTR, MAC2STR(src));