eapol: allow FILS GTK handshake

The GTK handshake for FILS uses AES-SIV to encrypt the key data, and
does away with the MIC completely. Now, when finalizing the 2/2 GTK
packet we check the MIC length, and if zero we assume FILS is being
used and we use AES-SIV to encrypt the key data.

For FILS, there is no actual data being encrypted for GTK 2/2 (hence
why the input data length is zero). This results in only the SIV
being generated, which essentially serves the same purpose as a MIC.
This commit is contained in:
James Prestwood 2019-04-17 15:16:43 -07:00 committed by Denis Kenzior
parent a6640f1b7a
commit c21f3cd2a4
1 changed files with 26 additions and 6 deletions

View File

@ -1788,14 +1788,34 @@ static void eapol_handle_gtk_1_of_2(struct eapol_sm *sm,
kck = handshake_state_get_kck(sm->handshake);
if (!eapol_calculate_mic(sm->handshake->akm_suite, kck,
step2, mic, sm->mic_len)) {
l_free(step2);
handshake_failed(sm, MMPDU_REASON_CODE_UNSPECIFIED);
return;
if (sm->mic_len) {
if (!eapol_calculate_mic(sm->handshake->akm_suite, kck,
step2, mic, sm->mic_len)) {
l_debug("MIC calculation failed");
l_free(step2);
handshake_failed(sm, MMPDU_REASON_CODE_UNSPECIFIED);
return;
}
memcpy(EAPOL_KEY_MIC(step2), mic, sm->mic_len);
} else {
uint8_t encr[16];
struct iovec ad[1];
ad[0].iov_base = step2;
ad[0].iov_len = EAPOL_KEY_DATA(step2, 0) - (uint8_t *)step2;
if (!aes_siv_encrypt(handshake_state_get_kek(sm->handshake), 32,
EAPOL_KEY_DATA(step2, 0), 0, ad, 1, encr)) {
l_debug("AES-SIV encryption failed");
l_free(step2);
handshake_failed(sm, MMPDU_REASON_CODE_UNSPECIFIED);
return;
}
memcpy(EAPOL_KEY_DATA(step2, 0), encr, 16);
}
memcpy(EAPOL_KEY_MIC(step2), mic, sm->mic_len);
eapol_sm_write(sm, (struct eapol_frame *) step2, false);
l_free(step2);