]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FILS: Update PMKID derivation rules for ERP key hierarchy establishment
authorJouni Malinen <jouni@qca.qualcomm.com>
Wed, 13 Sep 2017 14:58:29 +0000 (17:58 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 13 Sep 2017 19:17:58 +0000 (22:17 +0300)
IEEE Std 802.11ai-2016 had missed a change in the Pairwise key hierarchy
clause (12.7.1.3 in IEEE Std 802.11-2016) and due to that, the previous
implementation ended up using HMAC-SHA-1 -based PMKID derivation. This
was not really the intent of the FILS design and that issue was fixed
during REVmd work with the changes proposed in
https://mentor.ieee.org/802.11/dcn/17/11-17-0906-04-000m-fils-fixes.docx
that change FILS cases to use HMAC-SHA-256 and HMAC-SHA-384 based on the
negotiated AKM.

Update the implementation to match the new design. This changes the
rsn_pmkid() function to take in the more generic AKMP identifier instead
of a boolean identifying whether SHA256 is used.

Note: This is not backwards compatible, i.e., this breaks PMKSA caching
based on the initial ERP key hierarchy setup if only STA or AP side
implementation is updated. PMKSA caching based on FILS authentication
exchange is not impacted by this, though.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/ap/pmksa_cache_auth.c
src/ap/wpa_auth.c
src/common/wpa_common.c
src/common/wpa_common.h
src/rsn_supp/pmksa_cache.c

index bce5abf98932eb920d75b6282b300fe33a928589..15e2c4943f2bd105dc17ab3140e7b447abd947c5 100644 (file)
@@ -338,8 +338,7 @@ pmksa_cache_auth_create_entry(const u8 *pmk, size_t pmk_len, const u8 *pmkid,
        else if (wpa_key_mgmt_suite_b(akmp))
                rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid);
        else
-               rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
-                         wpa_key_mgmt_sha256(akmp));
+               rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid, akmp);
        os_get_reltime(&now);
        entry->expiration = now.sec;
        if (session_timeout > 0)
@@ -518,7 +517,7 @@ struct rsn_pmksa_cache_entry * pmksa_cache_get_okc(
                if (os_memcmp(entry->spa, spa, ETH_ALEN) != 0)
                        continue;
                rsn_pmkid(entry->pmk, entry->pmk_len, aa, spa, new_pmkid,
-                         wpa_key_mgmt_sha256(entry->akmp));
+                         entry->akmp);
                if (os_memcmp(new_pmkid, pmkid, PMKID_LEN) == 0)
                        return entry;
        }
index 7ae64c9ac82e16eb63311369b31422570fb08dc7..56857e855785a76149eb9168d65889419e2ce659 100644 (file)
@@ -2085,7 +2085,7 @@ SM_STATE(WPA_PTK, PTKSTART)
                         */
                        rsn_pmkid(sm->PMK, sm->pmk_len, sm->wpa_auth->addr,
                                  sm->addr, &pmkid[2 + RSN_SELECTOR_LEN],
-                                 wpa_key_mgmt_sha256(sm->wpa_key_mgmt));
+                                 sm->wpa_key_mgmt);
                }
        }
        wpa_send_eapol(sm->wpa_auth, sm,
index bddaeeace4113d5afa2557d382154049adc2638d..68e7883773a32dd0c83f73d43d0ca9180317518b 100644 (file)
@@ -1428,29 +1428,48 @@ int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce,
  * @aa: Authenticator address
  * @spa: Supplicant address
  * @pmkid: Buffer for PMKID
- * @use_sha256: Whether to use SHA256-based KDF
+ * @akmp: Negotiated key management protocol
  *
- * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
- * PMKID = HMAC-SHA1-128(PMK, "PMK Name" || AA || SPA)
+ * IEEE Std 802.11-2016 - 12.7.1.3 Pairwise key hierarchy
+ * AKM: 00-0F-AC:5, 00-0F-AC:6, 00-0F-AC:14, 00-0F-AC:16
+ * PMKID = Truncate-128(HMAC-SHA-256(PMK, "PMK Name" || AA || SPA))
+ * AKM: 00-0F-AC:11
+ * See rsn_pmkid_suite_b()
+ * AKM: 00-0F-AC:12
+ * See rsn_pmkid_suite_b_192()
+ * AKM: 00-0F-AC:15, 00-0F-AC:17
+ * PMKID = Truncate-128(HMAC-SHA-384(PMK, "PMK Name" || AA || SPA))
+ * Otherwise:
+ * PMKID = Truncate-128(HMAC-SHA-1(PMK, "PMK Name" || AA || SPA))
  */
 void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
-              u8 *pmkid, int use_sha256)
+              u8 *pmkid, int akmp)
 {
        char *title = "PMK Name";
        const u8 *addr[3];
        const size_t len[3] = { 8, ETH_ALEN, ETH_ALEN };
-       unsigned char hash[SHA256_MAC_LEN];
+       unsigned char hash[SHA384_MAC_LEN];
 
        addr[0] = (u8 *) title;
        addr[1] = aa;
        addr[2] = spa;
 
-#ifdef CONFIG_IEEE80211W
-       if (use_sha256)
+       if (0) {
+#ifdef CONFIG_FILS
+       } else if (wpa_key_mgmt_sha384(akmp)) {
+               wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-384");
+               hmac_sha384_vector(pmk, pmk_len, 3, addr, len, hash);
+#endif /* CONFIG_FILS */
+#if defined(CONFIG_IEEE80211W) || defined(CONFIG_FILS)
+       } else if (wpa_key_mgmt_sha256(akmp)) {
+               wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-256");
                hmac_sha256_vector(pmk, pmk_len, 3, addr, len, hash);
-       else
-#endif /* CONFIG_IEEE80211W */
+#endif /* CONFIG_IEEE80211W || CONFIG_FILS */
+       } else {
+               wpa_printf(MSG_DEBUG, "RSN: Derive PMKID using HMAC-SHA-1");
                hmac_sha1_vector(pmk, pmk_len, 3, addr, len, hash);
+       }
+       wpa_hexdump(MSG_DEBUG, "RSN: Derived PMKID", hash, PMKID_LEN);
        os_memcpy(pmkid, hash, PMKID_LEN);
 }
 
index f96eaa8beb044bf6705264fa5353d974b73cdbfc..b4d6c1384b8798ac93113420c79b7a9ee2341233 100644 (file)
@@ -397,7 +397,7 @@ int wpa_parse_wpa_ie_wpa(const u8 *wpa_ie, size_t wpa_ie_len,
                         struct wpa_ie_data *data);
 
 void rsn_pmkid(const u8 *pmk, size_t pmk_len, const u8 *aa, const u8 *spa,
-              u8 *pmkid, int use_sha256);
+              u8 *pmkid, int akmp);
 #ifdef CONFIG_SUITEB
 int rsn_pmkid_suite_b(const u8 *kck, size_t kck_len, const u8 *aa,
                       const u8 *spa, u8 *pmkid);
index a353404c22b4a58fcb14ead88ac9282c4272da7e..f5024f20f9e1de5e8a71e3db344ca8697b36a86c 100644 (file)
@@ -154,8 +154,7 @@ pmksa_cache_add(struct rsn_pmksa_cache *pmksa, const u8 *pmk, size_t pmk_len,
        else if (wpa_key_mgmt_suite_b(akmp))
                rsn_pmkid_suite_b(kck, kck_len, aa, spa, entry->pmkid);
        else
-               rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid,
-                         wpa_key_mgmt_sha256(akmp));
+               rsn_pmkid(pmk, pmk_len, aa, spa, entry->pmkid, akmp);
        os_get_reltime(&now);
        entry->expiration = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime;
        entry->reauth_time = now.sec + pmksa->sm->dot11RSNAConfigPMKLifetime *