]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
OWE: Fix PTK derivation workaround for interoperability
authorHu Wang <huw@codeaurora.org>
Thu, 5 Mar 2020 11:20:38 +0000 (19:20 +0800)
committerJouni Malinen <j@w1.fi>
Fri, 6 Mar 2020 19:44:31 +0000 (21:44 +0200)
The initial implementation of the PTK derivation workaround for
interoperability with older OWE implementations forced
WPA_KEY_MGMT_PSK_SHA256 to be used for all of PTK derivation. While that
is needed for selecting which hash algorithm to use, this was also
changing the length of the PTK components and by doing so, did not
actually address the backwards compatibility issue.

Fix this by forcing SHA256 as the hash algorithm in PTK derivation
without changing the PTK length calculation for OWE when
owe_ptk_workaround is enabled.

Fixes: 65a44e849af9 ("OWE: PTK derivation workaround in AP mode")
Fixes: 8b138d28264e ("OWE: PTK derivation workaround in STA mode")
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
src/ap/wpa_auth.c
src/common/wpa_common.c
src/rsn_supp/wpa.c

index e67c34498815a3a287ffcf5231d5a3a8020fa1cc..07cc514d9ed5f1d1052b89804013df02e7c66898 100644 (file)
@@ -2286,7 +2286,7 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
 
        akmp = sm->wpa_key_mgmt;
        if (force_sha256)
-               akmp = WPA_KEY_MGMT_PSK_SHA256;
+               akmp |= WPA_KEY_MGMT_PSK_SHA256;
        return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion",
                              sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce,
                              ptk, akmp, sm->pairwise, z, z_len);
index ee306ff509bd5fec22b5e69fb1e89991b6648b5a..c63d7bce1a0c319fb2c1b8c4701758d223ba4249 100644 (file)
@@ -355,6 +355,14 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
        size_t data_len = 2 * ETH_ALEN + 2 * WPA_NONCE_LEN;
        u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
        size_t ptk_len;
+#ifdef CONFIG_OWE
+       int owe_ptk_workaround = 0;
+
+       if (akmp == (WPA_KEY_MGMT_OWE | WPA_KEY_MGMT_PSK_SHA256)) {
+               owe_ptk_workaround = 1;
+               akmp = WPA_KEY_MGMT_OWE;
+       }
+#endif /* CONFIG_OWE */
 
        if (pmk_len == 0) {
                wpa_printf(MSG_ERROR, "WPA: No PMK set for PTK derivation");
@@ -413,7 +421,8 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
                               tmp, ptk_len) < 0)
                        return -1;
 #ifdef CONFIG_OWE
-       } else if (akmp == WPA_KEY_MGMT_OWE && pmk_len == 32) {
+       } else if (akmp == WPA_KEY_MGMT_OWE && (pmk_len == 32 ||
+                                               owe_ptk_workaround)) {
                wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
                if (sha256_prf(pmk, pmk_len, label, data, data_len,
                               tmp, ptk_len) < 0)
index 4ead4c5162ebfe7ed71ed128472937a51de7193b..548da45f6d6f320154ea4e142dba7c61167dd0e4 100644 (file)
@@ -598,7 +598,7 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
            sm->pmk_len > 32) {
                wpa_printf(MSG_DEBUG,
                           "OWE: Force SHA256 for PTK derivation");
-               akmp = WPA_KEY_MGMT_PSK_SHA256;
+               akmp |= WPA_KEY_MGMT_PSK_SHA256;
        }
 #endif /* CONFIG_OWE */
        return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",