]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
DPP2: Extend wpa_pmk_to_ptk() to support extra Z.x component in context
authorJouni Malinen <jouni@codeaurora.org>
Sun, 17 Mar 2019 20:02:06 +0000 (22:02 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 17 Mar 2019 23:31:31 +0000 (01:31 +0200)
DPP allows Diffie-Hellman exchange to be used for PFS in PTK derivation.
This requires an additional Z.x (x coordinate of the DH shared secret)
to be passed to wpa_pmk_to_ptk(). This commit adds that to the function
and updates all the callers to pass NULL,0 for that part in preparation
of the DPP specific changes to start using this.

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

index 1cb8113d0af2e7ae1d4c5a01b6edc14a4c460ba9..71dd00bc5b54fa47c051bd1293ec4cc2a9aec774 100644 (file)
@@ -2160,7 +2160,7 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce,
 
        return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion",
                              sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce,
-                             ptk, sm->wpa_key_mgmt, sm->pairwise);
+                             ptk, sm->wpa_key_mgmt, sm->pairwise, NULL, 0);
 }
 
 
index 613d5d05b1f51bdbb58ce507712f3bcaf409f320..2c5b2eba2357078389deaf5e3f8809f2620be800 100644 (file)
@@ -340,14 +340,21 @@ int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
  * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
  * PTK = PRF-X(PMK, "Pairwise key expansion",
  *             Min(AA, SA) || Max(AA, SA) ||
- *             Min(ANonce, SNonce) || Max(ANonce, SNonce))
+ *             Min(ANonce, SNonce) || Max(ANonce, SNonce)
+ *             [ || Z.x ])
+ *
+ * The optional Z.x component is used only with DPP and that part is not defined
+ * in IEEE 802.11.
  */
 int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
                   const u8 *addr1, const u8 *addr2,
                   const u8 *nonce1, const u8 *nonce2,
-                  struct wpa_ptk *ptk, int akmp, int cipher)
+                  struct wpa_ptk *ptk, int akmp, int cipher,
+                  const u8 *z, size_t z_len)
 {
-       u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];
+#define MAX_Z_LEN 66 /* with NIST P-521 */
+       u8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN + MAX_Z_LEN];
+       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;
 
@@ -356,6 +363,9 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
                return -1;
        }
 
+       if (z_len > MAX_Z_LEN)
+               return -1;
+
        if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
                os_memcpy(data, addr1, ETH_ALEN);
                os_memcpy(data + ETH_ALEN, addr2, ETH_ALEN);
@@ -374,6 +384,11 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
                          WPA_NONCE_LEN);
        }
 
+       if (z && z_len) {
+               os_memcpy(data + 2 * ETH_ALEN + 2 * WPA_NONCE_LEN, z, z_len);
+               data_len += z_len;
+       }
+
        ptk->kck_len = wpa_kck_len(akmp, pmk_len);
        ptk->kek_len = wpa_kek_len(akmp, pmk_len);
        ptk->tk_len = wpa_cipher_key_len(cipher);
@@ -388,7 +403,7 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
        if (wpa_key_mgmt_sha384(akmp)) {
 #if defined(CONFIG_SUITEB192) || defined(CONFIG_FILS)
                wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
-               if (sha384_prf(pmk, pmk_len, label, data, sizeof(data),
+               if (sha384_prf(pmk, pmk_len, label, data, data_len,
                               tmp, ptk_len) < 0)
                        return -1;
 #else /* CONFIG_SUITEB192 || CONFIG_FILS */
@@ -397,7 +412,7 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
        } else if (wpa_key_mgmt_sha256(akmp) || akmp == WPA_KEY_MGMT_OWE) {
 #if defined(CONFIG_IEEE80211W) || defined(CONFIG_SAE) || defined(CONFIG_FILS)
                wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
-               if (sha256_prf(pmk, pmk_len, label, data, sizeof(data),
+               if (sha256_prf(pmk, pmk_len, label, data, data_len,
                               tmp, ptk_len) < 0)
                        return -1;
 #else /* CONFIG_IEEE80211W or CONFIG_SAE or CONFIG_FILS */
@@ -406,17 +421,17 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
 #ifdef CONFIG_DPP
        } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 32) {
                wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)");
-               if (sha256_prf(pmk, pmk_len, label, data, sizeof(data),
+               if (sha256_prf(pmk, pmk_len, label, data, data_len,
                               tmp, ptk_len) < 0)
                        return -1;
        } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 48) {
                wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)");
-               if (sha384_prf(pmk, pmk_len, label, data, sizeof(data),
+               if (sha384_prf(pmk, pmk_len, label, data, data_len,
                               tmp, ptk_len) < 0)
                        return -1;
        } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 64) {
                wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA512)");
-               if (sha512_prf(pmk, pmk_len, label, data, sizeof(data),
+               if (sha512_prf(pmk, pmk_len, label, data, data_len,
                               tmp, ptk_len) < 0)
                        return -1;
        } else if (akmp == WPA_KEY_MGMT_DPP) {
@@ -426,7 +441,7 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
 #endif /* CONFIG_DPP */
        } else {
                wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA1)");
-               if (sha1_prf(pmk, pmk_len, label, data, sizeof(data), tmp,
+               if (sha1_prf(pmk, pmk_len, label, data, data_len, tmp,
                             ptk_len) < 0)
                        return -1;
        }
@@ -435,6 +450,8 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
                   MAC2STR(addr1), MAC2STR(addr2));
        wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN);
        wpa_hexdump(MSG_DEBUG, "WPA: Nonce2", nonce2, WPA_NONCE_LEN);
+       if (z && z_len)
+               wpa_hexdump_key(MSG_DEBUG, "WPA: Z.x", z, z_len);
        wpa_hexdump_key(MSG_DEBUG, "WPA: PMK", pmk, pmk_len);
        wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", tmp, ptk_len);
 
@@ -451,6 +468,7 @@ int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
        ptk->kck2_len = 0;
 
        os_memset(tmp, 0, sizeof(tmp));
+       os_memset(data, 0, data_len);
        return 0;
 }
 
index 2d9a71564353a5fdcca1b669c2c6741a8fefff0a..e83d6887a1cd51c5ef897766ba36b23b7bc41082 100644 (file)
@@ -347,7 +347,8 @@ int wpa_eapol_key_mic(const u8 *key, size_t key_len, int akmp, int ver,
 int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
                   const u8 *addr1, const u8 *addr2,
                   const u8 *nonce1, const u8 *nonce2,
-                  struct wpa_ptk *ptk, int akmp, int cipher);
+                  struct wpa_ptk *ptk, int akmp, int cipher,
+                  const u8 *z, size_t z_len);
 int fils_rmsk_to_pmk(int akmp, const u8 *rmsk, size_t rmsk_len,
                     const u8 *snonce, const u8 *anonce, const u8 *dh_ss,
                     size_t dh_ss_len, u8 *pmk, size_t *pmk_len);
index 4b42f89b5d2ab860696d3daef7659b1b8c7d957d..76f7c3faba5ee16d76fe6387e121795b8adfb797 100644 (file)
@@ -542,7 +542,7 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
        return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
                              sm->own_addr, sm->bssid, sm->snonce,
                              key->key_nonce, ptk, sm->key_mgmt,
-                             sm->pairwise_cipher);
+                             sm->pairwise_cipher, NULL, 0);
 }
 
 
index 9c52fbac41dc5dfc15c79035ca61c6eaa8abe2cd..1af48ec8f320ecbb5d60d890679a50d10229078b 100644 (file)
@@ -130,7 +130,7 @@ static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
                                  "Pairwise key expansion",
                                  bss->bssid, sta->addr, sta->anonce,
                                  sta->snonce, &ptk, sta->key_mgmt,
-                                 sta->pairwise_cipher) < 0 ||
+                                 sta->pairwise_cipher, NULL, 0) < 0 ||
                   check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data,
                             len) < 0) {
                return -1;