Discard unencrypted EAPOL-Key msg 1/4 when TK is set and PMF is enabled

RSN design is supposed to encrypt all Data frames, including EAPOL
frames, once the TK has been configured. However, there are deployed
implementations that do not really follow this design and there are
various examples from the older uses of EAPOL frame where those frames
were not encrypted. As such, strict filtering of unencrypted EAPOL
frames might results in undesired interoperation issues.

However, some of the most important cases of missing EAPOL frame
encryption should be possible to handle without causing too significant
issues. These are for cases where an attacker could potentially cause an
existing association to be dropped when PMF is used. EAPOL-Key msg 1/4
is one potential candidate for such attacks since that frame could be
used to initiate a 4-way handshake that the real AP might never complete
and the station might end up disconnecting because of that or at
minimum, getting into somewhat mismatching state with the AP.

Drop EAPOL-Key msg 1/4 when it is known that it was not encrypted but
should have been and when PMF is enabled. While it would be correct to
drop this even without PMF, that does not provide any significant
benefit since it is trivial to force disconnection in no-PMF cases. It
should also be noted that not all drivers provide information about the
encryption status of the EAPOL frames and this change has no impact with
drivers that do not indicate whether the frame was encrypted.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2022-05-07 11:54:16 +03:00
parent e6c0e12158
commit 872a57500c

View file

@ -672,7 +672,8 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
const unsigned char *src_addr, const unsigned char *src_addr,
const struct wpa_eapol_key *key, const struct wpa_eapol_key *key,
u16 ver, const u8 *key_data, u16 ver, const u8 *key_data,
size_t key_data_len) size_t key_data_len,
enum frame_encryption encrypted)
{ {
struct wpa_eapol_ie_parse ie; struct wpa_eapol_ie_parse ie;
struct wpa_ptk *ptk; struct wpa_ptk *ptk;
@ -680,6 +681,13 @@ static void wpa_supplicant_process_1_of_4(struct wpa_sm *sm,
u8 *kde, *kde_buf = NULL; u8 *kde, *kde_buf = NULL;
size_t kde_len; size_t kde_len;
if (encrypted == FRAME_NOT_ENCRYPTED && sm->tk_set &&
wpa_sm_pmf_enabled(sm)) {
wpa_printf(MSG_DEBUG,
"RSN: Discard unencrypted EAPOL-Key msg 1/4 when TK is set and PMF is enabled");
return;
}
if (wpa_sm_get_network_ctx(sm) == NULL) { if (wpa_sm_get_network_ctx(sm) == NULL) {
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No SSID info " wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "WPA: No SSID info "
"found (msg 1 of 4)"); "found (msg 1 of 4)");
@ -2727,7 +2735,8 @@ int wpa_sm_rx_eapol(struct wpa_sm *sm, const u8 *src_addr,
/* 1/4 4-Way Handshake */ /* 1/4 4-Way Handshake */
wpa_supplicant_process_1_of_4(sm, src_addr, key, wpa_supplicant_process_1_of_4(sm, src_addr, key,
ver, key_data, ver, key_data,
key_data_len); key_data_len,
encrypted);
} }
} else { } else {
if ((mic_len && (key_info & WPA_KEY_INFO_MIC)) || if ((mic_len && (key_info & WPA_KEY_INFO_MIC)) ||