mirror of
https://github.com/vanhoefm/fragattacks.git
synced 2025-02-19 10:33:05 -05:00
OCV: Verify OCI in 4-way and group key handshake
Verify the received OCI element in the 4-way and group key handshakes. If verification fails, the handshake message is silently dropped. Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@cs.kuleuven.be>
This commit is contained in:
parent
1034f67bf1
commit
aed61c4efa
@ -2774,6 +2774,32 @@ SM_STATE(WPA_PTK, PTKCALCNEGOTIATING)
|
|||||||
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_OCV
|
||||||
|
if (wpa_auth_uses_ocv(sm)) {
|
||||||
|
struct wpa_channel_info ci;
|
||||||
|
int tx_chanwidth;
|
||||||
|
int tx_seg1_idx;
|
||||||
|
|
||||||
|
if (wpa_channel_info(wpa_auth, &ci) != 0) {
|
||||||
|
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
|
||||||
|
"Failed to get channel info to validate received OCI in EAPOL-Key 2/4");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_sta_tx_parameters(sm,
|
||||||
|
channel_width_to_int(ci.chanwidth),
|
||||||
|
ci.seg1_idx, &tx_chanwidth,
|
||||||
|
&tx_seg1_idx) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ocv_verify_tx_params(kde.oci, kde.oci_len, &ci,
|
||||||
|
tx_chanwidth, tx_seg1_idx) != 0) {
|
||||||
|
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
|
||||||
|
ocv_errorstr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OCV */
|
||||||
#ifdef CONFIG_IEEE80211R_AP
|
#ifdef CONFIG_IEEE80211R_AP
|
||||||
if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) {
|
if (ft && ft_check_msg_2_of_4(wpa_auth, sm, &kde) < 0) {
|
||||||
wpa_sta_disconnect(wpa_auth, sm->addr,
|
wpa_sta_disconnect(wpa_auth, sm->addr,
|
||||||
@ -3419,8 +3445,67 @@ SM_STATE(WPA_PTK_GROUP, REKEYNEGOTIATING)
|
|||||||
|
|
||||||
SM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED)
|
SM_STATE(WPA_PTK_GROUP, REKEYESTABLISHED)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_OCV
|
||||||
|
struct wpa_authenticator *wpa_auth = sm->wpa_auth;
|
||||||
|
const u8 *key_data, *mic;
|
||||||
|
struct ieee802_1x_hdr *hdr;
|
||||||
|
struct wpa_eapol_key *key;
|
||||||
|
struct wpa_eapol_ie_parse kde;
|
||||||
|
size_t mic_len;
|
||||||
|
u16 key_data_length;
|
||||||
|
#endif /* CONFIG_OCV */
|
||||||
|
|
||||||
SM_ENTRY_MA(WPA_PTK_GROUP, REKEYESTABLISHED, wpa_ptk_group);
|
SM_ENTRY_MA(WPA_PTK_GROUP, REKEYESTABLISHED, wpa_ptk_group);
|
||||||
sm->EAPOLKeyReceived = FALSE;
|
sm->EAPOLKeyReceived = FALSE;
|
||||||
|
|
||||||
|
#ifdef CONFIG_OCV
|
||||||
|
mic_len = wpa_mic_len(sm->wpa_key_mgmt, sm->pmk_len);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: last_rx_eapol_key length fields have already been validated in
|
||||||
|
* wpa_receive().
|
||||||
|
*/
|
||||||
|
hdr = (struct ieee802_1x_hdr *) sm->last_rx_eapol_key;
|
||||||
|
key = (struct wpa_eapol_key *) (hdr + 1);
|
||||||
|
mic = (u8 *) (key + 1);
|
||||||
|
key_data = mic + mic_len + 2;
|
||||||
|
key_data_length = WPA_GET_BE16(mic + mic_len);
|
||||||
|
if (key_data_length > sm->last_rx_eapol_key_len - sizeof(*hdr) -
|
||||||
|
sizeof(*key) - mic_len - 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (wpa_parse_kde_ies(key_data, key_data_length, &kde) < 0) {
|
||||||
|
wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_INFO,
|
||||||
|
"received EAPOL-Key group msg 2/2 with invalid Key Data contents");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpa_auth_uses_ocv(sm)) {
|
||||||
|
struct wpa_channel_info ci;
|
||||||
|
int tx_chanwidth;
|
||||||
|
int tx_seg1_idx;
|
||||||
|
|
||||||
|
if (wpa_channel_info(wpa_auth, &ci) != 0) {
|
||||||
|
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
|
||||||
|
"Failed to get channel info to validate received OCI in EAPOL-Key group 1/2");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_sta_tx_parameters(sm,
|
||||||
|
channel_width_to_int(ci.chanwidth),
|
||||||
|
ci.seg1_idx, &tx_chanwidth,
|
||||||
|
&tx_seg1_idx) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ocv_verify_tx_params(kde.oci, kde.oci_len, &ci,
|
||||||
|
tx_chanwidth, tx_seg1_idx) != 0) {
|
||||||
|
wpa_auth_logger(wpa_auth, sm->addr, LOGGER_INFO,
|
||||||
|
ocv_errorstr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OCV */
|
||||||
|
|
||||||
if (sm->GUpdateStationKeys)
|
if (sm->GUpdateStationKeys)
|
||||||
sm->group->GKeyDoneStations--;
|
sm->group->GKeyDoneStations--;
|
||||||
sm->GUpdateStationKeys = FALSE;
|
sm->GUpdateStationKeys = FALSE;
|
||||||
|
@ -1447,6 +1447,26 @@ static void wpa_supplicant_process_3_of_4(struct wpa_sm *sm,
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_P2P */
|
#endif /* CONFIG_P2P */
|
||||||
|
|
||||||
|
#ifdef CONFIG_OCV
|
||||||
|
if (wpa_sm_ocv_enabled(sm)) {
|
||||||
|
struct wpa_channel_info ci;
|
||||||
|
|
||||||
|
if (wpa_sm_channel_info(sm, &ci) != 0) {
|
||||||
|
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
|
||||||
|
"Failed to get channel info to validate received OCI in EAPOL-Key 3/4");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ocv_verify_tx_params(ie.oci, ie.oci_len, &ci,
|
||||||
|
channel_width_to_int(ci.chanwidth),
|
||||||
|
ci.seg1_idx) != 0) {
|
||||||
|
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "%s",
|
||||||
|
ocv_errorstr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OCV */
|
||||||
|
|
||||||
if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
|
if (wpa_supplicant_send_4_of_4(sm, sm->bssid, key, ver, key_info,
|
||||||
&sm->ptk) < 0) {
|
&sm->ptk) < 0) {
|
||||||
goto failed;
|
goto failed;
|
||||||
@ -1540,6 +1560,26 @@ static int wpa_supplicant_process_1_of_2_rsn(struct wpa_sm *sm,
|
|||||||
}
|
}
|
||||||
maxkeylen = gd->gtk_len = ie.gtk_len - 2;
|
maxkeylen = gd->gtk_len = ie.gtk_len - 2;
|
||||||
|
|
||||||
|
#ifdef CONFIG_OCV
|
||||||
|
if (wpa_sm_ocv_enabled(sm)) {
|
||||||
|
struct wpa_channel_info ci;
|
||||||
|
|
||||||
|
if (wpa_sm_channel_info(sm, &ci) != 0) {
|
||||||
|
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING,
|
||||||
|
"Failed to get channel info to validate received OCI in EAPOL-Key group msg 1/2");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ocv_verify_tx_params(ie.oci, ie.oci_len, &ci,
|
||||||
|
channel_width_to_int(ci.chanwidth),
|
||||||
|
ci.seg1_idx) != 0) {
|
||||||
|
wpa_msg(sm->ctx->msg_ctx, MSG_WARNING, "%s",
|
||||||
|
ocv_errorstr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_OCV */
|
||||||
|
|
||||||
if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
|
if (wpa_supplicant_check_group_cipher(sm, sm->group_cipher,
|
||||||
gd->gtk_len, maxkeylen,
|
gd->gtk_len, maxkeylen,
|
||||||
&gd->key_rsc_len, &gd->alg))
|
&gd->key_rsc_len, &gd->alg))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user