]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FT: Derive PMKR0Name/PMKR1Name using SHA-384 with AKM 00-0F-AC:13
authorJouni Malinen <jouni@codeaurora.org>
Wed, 6 Jun 2018 18:57:58 +0000 (21:57 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 6 Jun 2018 20:59:46 +0000 (23:59 +0300)
The AKM 00-0F-AC:13 is supposed to use cryptographic algorithms
consistently, but the current IEEE 802.11 standard is not doing so for
the key names: PMKID (uses SHA-1), PMKR0Name/PMKR1Name (uses SHA-256).
The PMKID case was already implemented with SHA-384 and this commit
replaces use of SHA-256 with SHA-384 for PMKR0Name/PMKR1Name derivation
to be consistent in SHA-384. While this is not compliant with the
current IEEE 802.11 standard, this is clearly needed to meet CNSA Suite
requirements. Matching change is being proposed in REVmd to get the IEEE
802.11 standard to meet the use case requirements.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/ap/wpa_auth_ft.c
src/common/wpa_common.c
src/common/wpa_common.h
src/rsn_supp/wpa.c

index 52111773685c355059ac581a7076f357e462427d..e8d46ab0dbb3f290820280a93d05219295ef27d3 100644 (file)
@@ -2834,7 +2834,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm,
                    parse.rsn_pmkid, WPA_PMK_NAME_LEN);
        if (wpa_derive_pmk_r1_name(parse.rsn_pmkid,
                                   sm->wpa_auth->conf.r1_key_holder, sm->addr,
-                                  pmk_r1_name) < 0)
+                                  pmk_r1_name, use_sha384) < 0)
                return WLAN_STATUS_UNSPECIFIED_FAILURE;
        wpa_hexdump(MSG_DEBUG, "FT: Derived requested PMKR1Name",
                    pmk_r1_name, WPA_PMK_NAME_LEN);
index a8da7f02fd89ac7cbeffd574d97b3b2d79ba962f..14c5769b08170cefe9ec5570482bbacdf81920c7 100644 (file)
@@ -1480,7 +1480,7 @@ int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
 {
        u8 buf[1 + SSID_MAX_LEN + MOBILITY_DOMAIN_ID_LEN + 1 +
               FT_R0KH_ID_MAX_LEN + ETH_ALEN];
-       u8 *pos, r0_key_data[64], hash[32];
+       u8 *pos, r0_key_data[64], hash[48];
        const u8 *addr[2];
        size_t len[2];
        size_t q = use_sha384 ? 48 : 32;
@@ -1546,14 +1546,18 @@ int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
        wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0Name-Salt", &r0_key_data[q], 16);
 
        /*
-        * PMKR0Name = Truncate-128(SHA-256("FT-R0N" || PMK-R0Name-Salt)
+        * PMKR0Name = Truncate-128(Hash("FT-R0N" || PMK-R0Name-Salt)
         */
        addr[0] = (const u8 *) "FT-R0N";
        len[0] = 6;
        addr[1] = &r0_key_data[q];
        len[1] = 16;
 
-       if (sha256_vector(2, addr, len, hash) < 0)
+#ifdef CONFIG_SHA384
+       if (use_sha384 && sha384_vector(2, addr, len, hash) < 0)
+               return -1;
+#endif /* CONFIG_SHA384 */
+       if (!use_sha384 && sha256_vector(2, addr, len, hash) < 0)
                return -1;
        os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN);
        os_memset(r0_key_data, 0, sizeof(r0_key_data));
@@ -1567,15 +1571,15 @@ int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
  * IEEE Std 802.11r-2008 - 8.5.1.5.4
  */
 int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
-                          const u8 *s1kh_id, u8 *pmk_r1_name)
+                          const u8 *s1kh_id, u8 *pmk_r1_name, int use_sha384)
 {
-       u8 hash[32];
+       u8 hash[48];
        const u8 *addr[4];
        size_t len[4];
 
        /*
-        * PMKR1Name = Truncate-128(SHA-256("FT-R1N" || PMKR0Name ||
-        *                                  R1KH-ID || S1KH-ID))
+        * PMKR1Name = Truncate-128(Hash("FT-R1N" || PMKR0Name ||
+        *                               R1KH-ID || S1KH-ID))
         */
        addr[0] = (const u8 *) "FT-R1N";
        len[0] = 6;
@@ -1586,7 +1590,11 @@ int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
        addr[3] = s1kh_id;
        len[3] = ETH_ALEN;
 
-       if (sha256_vector(4, addr, len, hash) < 0)
+#ifdef CONFIG_SHA384
+       if (use_sha384 && sha384_vector(4, addr, len, hash) < 0)
+               return -1;
+#endif /* CONFIG_SHA384 */
+       if (!use_sha384 && sha256_vector(4, addr, len, hash) < 0)
                return -1;
        os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN);
        return 0;
@@ -1636,7 +1644,8 @@ int wpa_derive_pmk_r1(const u8 *pmk_r0, size_t pmk_r0_len,
        wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r0_len);
 
        return wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id,
-                                     pmk_r1_name);
+                                     pmk_r1_name,
+                                     pmk_r0_len == SHA384_MAC_LEN);
 }
 
 
index 6d808d7fdaa4bb9cf1f61d25f78862f9e06b3b33..62617444058b4d2d9a46410ffe5c07b9a552858a 100644 (file)
@@ -375,7 +375,7 @@ int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len,
                      const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name,
                      int use_sha384);
 int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id,
-                          const u8 *s1kh_id, u8 *pmk_r1_name);
+                          const u8 *s1kh_id, u8 *pmk_r1_name, int use_sha384);
 int wpa_derive_pmk_r1(const u8 *pmk_r0, size_t pmk_r0_len,
                      const u8 *pmk_r0_name,
                      const u8 *r1kh_id, const u8 *s1kh_id,
index b8ab2b1bc36847564581b961a8e689a51f993fa4..56f3af7998452fc49bccc08e82bad3c2af985495 100644 (file)
@@ -3829,7 +3829,7 @@ static int fils_ft_build_assoc_req_rsne(struct wpa_sm *sm, struct wpabuf *buf)
                   MAC2STR(sm->r1kh_id));
        pos = wpabuf_put(buf, WPA_PMK_NAME_LEN);
        if (wpa_derive_pmk_r1_name(sm->pmk_r0_name, sm->r1kh_id, sm->own_addr,
-                                  pos) < 0) {
+                                  pos, use_sha384) < 0) {
                wpa_printf(MSG_WARNING, "FILS+FT: Could not derive PMKR1Name");
                return -1;
        }