diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index fab958199..cf4bbfaaa 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -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; } diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index b6465d4f1..1b2dc1bb3 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -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;