FILS: Fix KEK2 use in FT-FILS use cases

When support for KCK2 and KEK2 was added, both keys were derived for
FT-FILS cases, but only KCK2 was actually used. Add similar changes to
use KEK2 to protect GTK/IGTK in FTE with using FT-FILS AKMs.

This fixes AES key wrapping to use the correct key. The change is not
backwards compatible.

Fixes: 2f37387812 ("FILS: Add more complete support for FT-FILS use cases")
Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2018-06-05 20:13:34 +03:00
parent 88bf44be42
commit 657b4c45a9
2 changed files with 57 additions and 7 deletions

View file

@ -2104,6 +2104,16 @@ static u8 * wpa_ft_gtk_subelem(struct wpa_state_machine *sm, size_t *len)
const u8 *key;
size_t key_len;
u8 keybuf[32];
const u8 *kek;
size_t kek_len;
if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
kek = sm->PTK.kek2;
kek_len = sm->PTK.kek2_len;
} else {
kek = sm->PTK.kek;
kek_len = sm->PTK.kek_len;
}
key_len = gsm->GTK_len;
if (key_len > sizeof(keybuf))
@ -2142,8 +2152,10 @@ static u8 * wpa_ft_gtk_subelem(struct wpa_state_machine *sm, size_t *len)
WPA_PUT_LE16(&subelem[2], gsm->GN & 0x03);
subelem[4] = gsm->GTK_len;
wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN, subelem + 5);
if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len, key_len / 8, key,
subelem + 13)) {
if (aes_wrap(kek, kek_len, key_len / 8, key, subelem + 13)) {
wpa_printf(MSG_DEBUG,
"FT: GTK subelem encryption failed: kek_len=%d",
(int) kek_len);
os_free(subelem);
return NULL;
}
@ -2159,6 +2171,16 @@ static u8 * wpa_ft_igtk_subelem(struct wpa_state_machine *sm, size_t *len)
u8 *subelem, *pos;
struct wpa_group *gsm = sm->group;
size_t subelem_len;
const u8 *kek;
size_t kek_len;
if (wpa_key_mgmt_fils(sm->wpa_key_mgmt)) {
kek = sm->PTK.kek2;
kek_len = sm->PTK.kek2_len;
} else {
kek = sm->PTK.kek;
kek_len = sm->PTK.kek_len;
}
/* Sub-elem ID[1] | Length[1] | KeyID[2] | IPN[6] | Key Length[1] |
* Key[16+8] */
@ -2175,8 +2197,11 @@ static u8 * wpa_ft_igtk_subelem(struct wpa_state_machine *sm, size_t *len)
wpa_auth_get_seqnum(sm->wpa_auth, NULL, gsm->GN_igtk, pos);
pos += 6;
*pos++ = WPA_IGTK_LEN;
if (aes_wrap(sm->PTK.kek, sm->PTK.kek_len, WPA_IGTK_LEN / 8,
if (aes_wrap(kek, kek_len, WPA_IGTK_LEN / 8,
gsm->IGTK[gsm->GN_igtk - 4], pos)) {
wpa_printf(MSG_DEBUG,
"FT: IGTK subelem encryption failed: kek_len=%d",
(int) kek_len);
os_free(subelem);
return NULL;
}
@ -2369,6 +2394,11 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
/* Fast BSS Transition Information */
if (auth_alg == WLAN_AUTH_FT) {
subelem = wpa_ft_gtk_subelem(sm, &subelem_len);
if (!subelem) {
wpa_printf(MSG_DEBUG,
"FT: Failed to add GTK subelement");
return pos;
}
r0kh_id = sm->r0kh_id;
r0kh_id_len = sm->r0kh_id_len;
anonce = sm->ANonce;
@ -2380,6 +2410,8 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos,
u8 *nbuf;
igtk = wpa_ft_igtk_subelem(sm, &igtk_len);
if (igtk == NULL) {
wpa_printf(MSG_DEBUG,
"FT: Failed to add IGTK subelement");
os_free(subelem);
return pos;
}

View file

@ -641,6 +641,16 @@ static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem,
int keyidx;
enum wpa_alg alg;
size_t gtk_len, keylen, rsc_len;
const u8 *kek;
size_t kek_len;
if (wpa_key_mgmt_fils(sm->key_mgmt)) {
kek = sm->ptk.kek2;
kek_len = sm->ptk.kek2_len;
} else {
kek = sm->ptk.kek;
kek_len = sm->ptk.kek_len;
}
if (gtk_elem == NULL) {
wpa_printf(MSG_DEBUG, "FT: No GTK included in FTIE");
@ -657,8 +667,7 @@ static int wpa_ft_process_gtk_subelem(struct wpa_sm *sm, const u8 *gtk_elem,
return -1;
}
gtk_len = gtk_elem_len - 19;
if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, gtk_len / 8, gtk_elem + 11,
gtk)) {
if (aes_unwrap(kek, kek_len, gtk_len / 8, gtk_elem + 11, gtk)) {
wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not "
"decrypt GTK");
return -1;
@ -714,6 +723,16 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
{
u8 igtk[WPA_IGTK_LEN];
u16 keyidx;
const u8 *kek;
size_t kek_len;
if (wpa_key_mgmt_fils(sm->key_mgmt)) {
kek = sm->ptk.kek2;
kek_len = sm->ptk.kek2_len;
} else {
kek = sm->ptk.kek;
kek_len = sm->ptk.kek_len;
}
if (sm->mgmt_group_cipher != WPA_CIPHER_AES_128_CMAC)
return 0;
@ -737,8 +756,7 @@ static int wpa_ft_process_igtk_subelem(struct wpa_sm *sm, const u8 *igtk_elem,
return -1;
}
if (aes_unwrap(sm->ptk.kek, sm->ptk.kek_len, WPA_IGTK_LEN / 8,
igtk_elem + 9, igtk)) {
if (aes_unwrap(kek, kek_len, WPA_IGTK_LEN / 8, igtk_elem + 9, igtk)) {
wpa_printf(MSG_WARNING, "FT: AES unwrap failed - could not "
"decrypt IGTK");
return -1;