]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FILS: Fix KEK2 use in FT-FILS use cases
authorJouni Malinen <j@w1.fi>
Tue, 5 Jun 2018 17:13:34 +0000 (20:13 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 5 Jun 2018 18:04:54 +0000 (21:04 +0300)
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: 2f37387812a5 ("FILS: Add more complete support for FT-FILS use cases")
Signed-off-by: Jouni Malinen <j@w1.fi>
src/ap/wpa_auth_ft.c
src/rsn_supp/wpa_ft.c

index fab958199b549beff9308bf3ae72f972a0056262..cf4bbfaaae217a8c02376be138276a3a2aee934b 100644 (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;
                        }
index b6465d4f14eb3eda20877e776afd7a40a5c35b81..1b2dc1bb32b48ecb6db6baa208f72d9d77c20a77 100644 (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;