]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FT: Extend PTK derivation for FT-SAE-EXT-KEY
authorJouni Malinen <quic_jouni@quicinc.com>
Sun, 16 Oct 2022 13:38:27 +0000 (16:38 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 16 Oct 2022 14:24:25 +0000 (17:24 +0300)
Cover the SHA512-based derivation case.

Signed-off-by: Jouni Malinen <quic_jouni@quicinc.com>
src/common/wpa_common.c

index 4801f8a7df56e6c13b1ab9b91eb0494fda5bacc8..11620ccfc693972f904391a022df6413a204b565 100644 (file)
@@ -2276,7 +2276,8 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len,
        u8 tmp[2 * WPA_KCK_MAX_LEN + 2 * WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN +
               WPA_KDK_MAX_LEN];
        size_t ptk_len, offset;
-       int use_sha384 = wpa_key_mgmt_sha384(akmp);
+       size_t key_len;
+       int res;
 
        if (kdk_len > WPA_KDK_MAX_LEN) {
                wpa_printf(MSG_ERROR,
@@ -2285,12 +2286,20 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len,
                return -1;
        }
 
+       if (akmp == WPA_KEY_MGMT_FT_SAE_EXT_KEY &&
+           (pmk_r1_len == SHA256_MAC_LEN || pmk_r1_len == SHA384_MAC_LEN ||
+            pmk_r1_len == SHA512_MAC_LEN))
+               key_len = pmk_r1_len;
+       else if (wpa_key_mgmt_sha384(akmp))
+               key_len = SHA384_MAC_LEN;
+       else
+               key_len = SHA256_MAC_LEN;
+
        /*
         * PTK = KDF-PTKLen(PMK-R1, "FT-PTK", SNonce || ANonce ||
         *                  BSSID || STA-ADDR)
         */
-       wpa_printf(MSG_DEBUG, "FT: Derive PTK using KDF-%s",
-                  use_sha384 ? "SHA384" : "SHA256");
+       wpa_printf(MSG_DEBUG, "FT: Derive PTK using KDF-SHA%zu", key_len * 8);
        wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r1_len);
        wpa_hexdump(MSG_DEBUG, "FT: SNonce", snonce, WPA_NONCE_LEN);
        wpa_hexdump(MSG_DEBUG, "FT: ANonce", anonce, WPA_NONCE_LEN);
@@ -2306,39 +2315,52 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len,
        os_memcpy(pos, sta_addr, ETH_ALEN);
        pos += ETH_ALEN;
 
-       ptk->kck_len = wpa_kck_len(akmp, PMK_LEN);
+       ptk->kck_len = wpa_kck_len(akmp, key_len);
        ptk->kck2_len = wpa_kck2_len(akmp);
-       ptk->kek_len = wpa_kek_len(akmp, PMK_LEN);
+       ptk->kek_len = wpa_kek_len(akmp, key_len);
        ptk->kek2_len = wpa_kek2_len(akmp);
        ptk->tk_len = wpa_cipher_key_len(cipher);
        ptk->kdk_len = kdk_len;
        ptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len +
                ptk->kck2_len + ptk->kek2_len + ptk->kdk_len;
 
+       res = -1;
+#ifdef CONFIG_SHA512
+       if (key_len == SHA512_MAC_LEN) {
+               if (pmk_r1_len != SHA512_MAC_LEN) {
+                       wpa_printf(MSG_ERROR,
+                                  "FT: Unexpected PMK-R1 length %d (expected %d)",
+                                  (int) pmk_r1_len, SHA512_MAC_LEN);
+                       return -1;
+               }
+               res = sha512_prf(pmk_r1, pmk_r1_len, "FT-PTK",
+                                buf, pos - buf, tmp, ptk_len);
+       }
+#endif /* CONFIG_SHA512 */
 #ifdef CONFIG_SHA384
-       if (use_sha384) {
+       if (key_len == SHA384_MAC_LEN) {
                if (pmk_r1_len != SHA384_MAC_LEN) {
                        wpa_printf(MSG_ERROR,
                                   "FT: Unexpected PMK-R1 length %d (expected %d)",
                                   (int) pmk_r1_len, SHA384_MAC_LEN);
                        return -1;
                }
-               if (sha384_prf(pmk_r1, pmk_r1_len, "FT-PTK",
-                              buf, pos - buf, tmp, ptk_len) < 0)
-                       return -1;
+               res = sha384_prf(pmk_r1, pmk_r1_len, "FT-PTK",
+                                buf, pos - buf, tmp, ptk_len);
        }
 #endif /* CONFIG_SHA384 */
-       if (!use_sha384) {
+       if (key_len == SHA256_MAC_LEN) {
                if (pmk_r1_len != PMK_LEN) {
                        wpa_printf(MSG_ERROR,
                                   "FT: Unexpected PMK-R1 length %d (expected %d)",
                                   (int) pmk_r1_len, PMK_LEN);
                        return -1;
                }
-               if (sha256_prf(pmk_r1, pmk_r1_len, "FT-PTK",
-                              buf, pos - buf, tmp, ptk_len) < 0)
-                       return -1;
+               res = sha256_prf(pmk_r1, pmk_r1_len, "FT-PTK",
+                                buf, pos - buf, tmp, ptk_len);
        }
+       if (res < 0)
+               return -1;
        wpa_hexdump_key(MSG_DEBUG, "FT: PTK", tmp, ptk_len);
 
        /*