]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FILS: Extend the fils_pmk_to_ptk() function to also derive KDK
authorIlan Peer <ilan.peer@intel.com>
Wed, 16 Dec 2020 11:00:19 +0000 (13:00 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 25 Jan 2021 16:36:40 +0000 (18:36 +0200)
Extend the fils_pmk_to_ptk() to also derive Key Derivation
Key (KDK) which can later be used for secure LTF measurements.

Signed-off-by: Ilan Peer <ilan.peer@intel.com>
src/ap/wpa_auth.c
src/common/wpa_common.c
src/common/wpa_common.h
src/rsn_supp/wpa.c
wlantest/rx_mgmt.c

index 65da18cbe9e087ad1d9bd83346fe775be9e67c15..dbba41d31a5d9401e050a30f85aeb4b5dedcd04a 100644 (file)
@@ -2314,7 +2314,8 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
                              snonce, anonce, dhss, dhss_len,
                              &sm->PTK, ick, &ick_len,
                              sm->wpa_key_mgmt, sm->pairwise,
-                             fils_ft, &fils_ft_len);
+                             fils_ft, &fils_ft_len,
+                             sm->wpa_auth->conf.kdk ? WPA_KDK_MAX_LEN : 0);
        if (res < 0)
                return res;
        sm->PTK_valid = true;
index 877e4b5b3465d04439214de8921468b31e0d075e..bf56aa8d5680cc99db3c0ec7baf64174796714aa 100644 (file)
@@ -592,15 +592,16 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
                    const u8 *snonce, const u8 *anonce, const u8 *dhss,
                    size_t dhss_len, struct wpa_ptk *ptk,
                    u8 *ick, size_t *ick_len, int akmp, int cipher,
-                   u8 *fils_ft, size_t *fils_ft_len)
+                   u8 *fils_ft, size_t *fils_ft_len, size_t kdk_len)
 {
        u8 *data, *pos;
        size_t data_len;
        u8 tmp[FILS_ICK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
-              FILS_FT_MAX_LEN];
+              FILS_FT_MAX_LEN + WPA_KDK_MAX_LEN];
        size_t key_data_len;
        const char *label = "FILS PTK Derivation";
        int ret = -1;
+       size_t offset;
 
        /*
         * FILS-Key-Data = PRF-X(PMK, "FILS PTK Derivation",
@@ -611,6 +612,9 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
         * If doing FT initial mobility domain association:
         * FILS-FT = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits,
         *             FILS-FT_bits)
+        * When a KDK is derived:
+        * KDK = L(FILS-Key-Data, ICK_bits + KEK_bits + TK_bits + FILS-FT_bits,
+        *         KDK_bits)
         */
        data_len = 2 * ETH_ALEN + 2 * FILS_NONCE_LEN + dhss_len;
        data = os_malloc(data_len);
@@ -639,6 +643,19 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
                goto err;
        key_data_len = *ick_len + ptk->kek_len + ptk->tk_len;
 
+       if (kdk_len) {
+               if (kdk_len > WPA_KDK_MAX_LEN) {
+                       wpa_printf(MSG_ERROR, "FILS: KDK len=%zu too big",
+                                  kdk_len);
+                       goto err;
+               }
+
+               ptk->kdk_len = kdk_len;
+               key_data_len += kdk_len;
+       } else {
+               ptk->kdk_len = 0;
+       }
+
        if (fils_ft && fils_ft_len) {
                if (akmp == WPA_KEY_MGMT_FT_FILS_SHA256) {
                        *fils_ft_len = 32;
@@ -673,19 +690,27 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
        wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-Key-Data", tmp, key_data_len);
 
        os_memcpy(ick, tmp, *ick_len);
+       offset = *ick_len;
        wpa_hexdump_key(MSG_DEBUG, "FILS: ICK", ick, *ick_len);
 
-       os_memcpy(ptk->kek, tmp + *ick_len, ptk->kek_len);
+       os_memcpy(ptk->kek, tmp + offset, ptk->kek_len);
        wpa_hexdump_key(MSG_DEBUG, "FILS: KEK", ptk->kek, ptk->kek_len);
+       offset += ptk->kek_len;
 
-       os_memcpy(ptk->tk, tmp + *ick_len + ptk->kek_len, ptk->tk_len);
+       os_memcpy(ptk->tk, tmp + offset, ptk->tk_len);
        wpa_hexdump_key(MSG_DEBUG, "FILS: TK", ptk->tk, ptk->tk_len);
+       offset += ptk->tk_len;
 
        if (fils_ft && fils_ft_len) {
-               os_memcpy(fils_ft, tmp + *ick_len + ptk->kek_len + ptk->tk_len,
-                         *fils_ft_len);
+               os_memcpy(fils_ft, tmp + offset, *fils_ft_len);
                wpa_hexdump_key(MSG_DEBUG, "FILS: FILS-FT",
                                fils_ft, *fils_ft_len);
+               offset += *fils_ft_len;
+       }
+
+       if (ptk->kdk_len) {
+               os_memcpy(ptk->kdk, tmp + offset, ptk->kdk_len);
+               wpa_hexdump_key(MSG_DEBUG, "FILS: KDK", ptk->kdk, ptk->kdk_len);
        }
 
        ptk->kek2_len = 0;
index 193f1d7320a523fbf1df7659a74d56f5b62fc868..7c3692849d409cbe829f35c29e0d0297e29c3aa0 100644 (file)
@@ -396,7 +396,7 @@ int fils_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const u8 *spa, const u8 *aa,
                    const u8 *snonce, const u8 *anonce, const u8 *dhss,
                    size_t dhss_len, struct wpa_ptk *ptk,
                    u8 *ick, size_t *ick_len, int akmp, int cipher,
-                   u8 *fils_ft, size_t *fils_ft_len);
+                   u8 *fils_ft, size_t *fils_ft_len, size_t kdk_len);
 int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce,
                     const u8 *anonce, const u8 *sta_addr, const u8 *bssid,
                     const u8 *g_sta, size_t g_sta_len,
index 24d7422bf5b2b8a01e13093fd55eade62fa2475f..7f10956a52bc1c1aa26ac715b090dee2bffcd682 100644 (file)
@@ -4350,7 +4350,8 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
                            dh_ss ? wpabuf_len(dh_ss) : 0,
                            &sm->ptk, ick, &ick_len,
                            sm->key_mgmt, sm->pairwise_cipher,
-                           sm->fils_ft, &sm->fils_ft_len) < 0) {
+                           sm->fils_ft, &sm->fils_ft_len,
+                           sm->kdk ? WPA_KDK_MAX_LEN : 0) < 0) {
                wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK");
                goto fail;
        }
index f7041b8cb99c4472033cabb43c3c32078f4169bf..61c7f6a4ce5beaaa1d9bd7d2b8090cadfc44faa7 100644 (file)
@@ -494,7 +494,7 @@ static int try_rmsk(struct wlantest *wt, struct wlantest_bss *bss,
                            sta->snonce, sta->anonce, NULL, 0,
                            &ptk, ick, &ick_len,
                            sta->key_mgmt, sta->pairwise_cipher,
-                           NULL, NULL) < 0)
+                           NULL, NULL, 0) < 0)
                return -1;
 
        /* Check AES-SIV decryption with the derived key */