]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
wlantest: Guess SAE/OWE group from EAPOL-Key length mismatch
authorJouni Malinen <quic_jouni@quicinc.com>
Fri, 11 Aug 2023 17:35:34 +0000 (20:35 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 11 Aug 2023 17:35:34 +0000 (20:35 +0300)
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 <quic_jouni@quicinc.com>
wlantest/rx_eapol.c

index 742efb92c381a732456090ac56c384b6c743f259..c1fe1f22432ba50237838306907a53b6562d7d98 100644 (file)
@@ -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));