Set Secure=1 for EAPOL-Key msg 3/4 in WPA conditional on 2/4
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>
This commit is contained in:
parent
e9447a94c0
commit
0d442affb6
2 changed files with 19 additions and 0 deletions
|
@ -766,6 +766,9 @@ void wpa_receive(struct wpa_authenticator *wpa_auth,
|
||||||
key = (struct wpa_eapol_key *) (hdr + 1);
|
key = (struct wpa_eapol_key *) (hdr + 1);
|
||||||
key_info = WPA_GET_BE16(key->key_info);
|
key_info = WPA_GET_BE16(key->key_info);
|
||||||
key_data_length = WPA_GET_BE16(key->key_data_length);
|
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)) {
|
if (key_data_length > data_len - sizeof(*hdr) - sizeof(*key)) {
|
||||||
wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - "
|
wpa_printf(MSG_INFO, "WPA: Invalid EAPOL-Key frame - "
|
||||||
"key_data overflow (%d > %lu)",
|
"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);
|
os_memcpy(sm->last_rx_eapol_key, data, data_len);
|
||||||
sm->last_rx_eapol_key_len = 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->EAPOLKeyReceived = TRUE;
|
||||||
sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE);
|
sm->EAPOLKeyPairwise = !!(key_info & WPA_KEY_INFO_KEY_TYPE);
|
||||||
sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST);
|
sm->EAPOLKeyRequest = !!(key_info & WPA_KEY_INFO_REQUEST);
|
||||||
|
@ -1882,6 +1886,20 @@ SM_STATE(WPA_PTK, PTKINITNEGOTIATING)
|
||||||
gtk_len = 0;
|
gtk_len = 0;
|
||||||
keyidx = 0;
|
keyidx = 0;
|
||||||
_rsc = NULL;
|
_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);
|
kde_len = wpa_ie_len + ieee80211w_kde_len(sm);
|
||||||
|
|
|
@ -86,6 +86,7 @@ struct wpa_state_machine {
|
||||||
unsigned int pending_deinit:1;
|
unsigned int pending_deinit:1;
|
||||||
unsigned int started:1;
|
unsigned int started:1;
|
||||||
unsigned int mgmt_frame_prot:1;
|
unsigned int mgmt_frame_prot:1;
|
||||||
|
unsigned int rx_eapol_key_secure:1;
|
||||||
#ifdef CONFIG_IEEE80211R
|
#ifdef CONFIG_IEEE80211R
|
||||||
unsigned int ft_completed:1;
|
unsigned int ft_completed:1;
|
||||||
unsigned int pmk_r1_name_valid:1;
|
unsigned int pmk_r1_name_valid:1;
|
||||||
|
|
Loading…
Reference in a new issue