]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Set Secure=1 for EAPOL-Key msg 3/4 in WPA conditional on 2/4
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 17 Nov 2011 20:59:31 +0000 (22:59 +0200)
committerJouni Malinen <j@w1.fi>
Thu, 17 Nov 2011 20:59:31 +0000 (22:59 +0200)
This is a workaround for Windows 7 supplicant rejecting WPA msg 3/4
in case it used Secure=1 in msg 2/4. This can happen, e.g., when
rekeying PTK after EAPOL-Key Error Request (Michael MIC failure)
from the supplicant.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/ap/wpa_auth.c
src/ap/wpa_auth_i.h

index 7ebfd8d544d6b765265060f80f824eda16d13e66..1dba599f6069729bbb1a392afc68bf5f65027a48 100644 (file)
@@ -766,6 +766,9 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
        key = (struct wpa_eapol_key *) (hdr + 1);
        key_info = WPA_GET_BE16(key->key_info);
        key_data_length = WPA_GET_BE16(key->key_data_length);
+       wpa_printf(MSG_DEBUG, "WPA: Received EAPOL-Key from " MACSTR
+                  " key_info=0x%x type=%u key_data_length=%u",
+                  MAC2STR(sm->addr), key_info, key->type, key_data_length);
        if (key_data_length > data_len - sizeof(*hdr) - sizeof(*key)) {
                wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - "
                           "key_data overflow (%d > %lu)",
@@ -1095,6 +1098,7 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
        os_memcpy(sm->last_rx_eapol_key, data, data_len);
        sm->last_rx_eapol_key_len = data_len;
 
+       sm->rx_eapol_key_secure = !!(key_info & WPA_KEY_INFO_SECURE);
        sm->EAPOLKeyReceived = TRUE;
        sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE);
        sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST);
@@ -1882,6 +1886,20 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
                gtk_len = 0;
                keyidx = 0;
                _rsc = NULL;
+               if (sm->rx_eapol_key_secure) {
+                       /*
+                        * It looks like Windows 7 supplicant tries to use
+                        * Secure bit in msg 2/4 after having reported Michael
+                        * MIC failure and it then rejects the 4-way handshake
+                        * if msg 3/4 does not set Secure bit. Work around this
+                        * by setting the Secure bit here even in the case of
+                        * WPA if the supplicant used it first.
+                        */
+                       wpa_auth_logger(sm->wpa_auth, sm->addr, LOGGER_DEBUG,
+                                       "STA used Secure bit in WPA msg 3/4 - "
+                                       "set Secure for 4/4 as workaround");
+                       secure = 1;
+               }
        }
 
        kde_len = wpa_ie_len + ieee80211w_kde_len(sm);
index 67a5c3bf45ae6a82dc16a0b6fa0aaa467154cabe..d82192aca41f2531e058594d7d80303ee6d02c0d 100644 (file)
@@ -86,6 +86,7 @@ struct wpa_state_machine {
        unsigned int pending_deinit:1;
        unsigned int started:1;
        unsigned int mgmt_frame_prot:1;
+       unsigned int rx_eapol_key_secure:1;
 #ifdef CONFIG_IEEE80211R
        unsigned int ft_completed:1;
        unsigned int pmk_r1_name_valid:1;