DPP2: Extend wpa_pmk_to_ptk() to support extra Z.x component in context

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>
This commit is contained in:
Jouni Malinen 2019-03-17 22:02:06 +02:00 committed by Jouni Malinen
parent 16a4e931f0
commit ecacd9ccd4
5 changed files with 32 additions and 13 deletions

View 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", return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion",
sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce, 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);
} }

View 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 * IEEE Std 802.11i-2004 - 8.5.1.2 Pairwise key hierarchy
* PTK = PRF-X(PMK, "Pairwise key expansion", * PTK = PRF-X(PMK, "Pairwise key expansion",
* Min(AA, SA) || Max(AA, SA) || * 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, int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
const u8 *addr1, const u8 *addr2, const u8 *addr1, const u8 *addr2,
const u8 *nonce1, const u8 *nonce2, 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]; u8 tmp[WPA_KCK_MAX_LEN + WPA_KEK_MAX_LEN + WPA_TK_MAX_LEN];
size_t ptk_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; return -1;
} }
if (z_len > MAX_Z_LEN)
return -1;
if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) { if (os_memcmp(addr1, addr2, ETH_ALEN) < 0) {
os_memcpy(data, addr1, ETH_ALEN); os_memcpy(data, addr1, ETH_ALEN);
os_memcpy(data + ETH_ALEN, addr2, 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); 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->kck_len = wpa_kck_len(akmp, pmk_len);
ptk->kek_len = wpa_kek_len(akmp, pmk_len); ptk->kek_len = wpa_kek_len(akmp, pmk_len);
ptk->tk_len = wpa_cipher_key_len(cipher); 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 (wpa_key_mgmt_sha384(akmp)) {
#if defined(CONFIG_SUITEB192) || defined(CONFIG_FILS) #if defined(CONFIG_SUITEB192) || defined(CONFIG_FILS)
wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)"); 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) tmp, ptk_len) < 0)
return -1; return -1;
#else /* CONFIG_SUITEB192 || CONFIG_FILS */ #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) { } else if (wpa_key_mgmt_sha256(akmp) || akmp == WPA_KEY_MGMT_OWE) {
#if defined(CONFIG_IEEE80211W) || defined(CONFIG_SAE) || defined(CONFIG_FILS) #if defined(CONFIG_IEEE80211W) || defined(CONFIG_SAE) || defined(CONFIG_FILS)
wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)"); 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) tmp, ptk_len) < 0)
return -1; return -1;
#else /* CONFIG_IEEE80211W or CONFIG_SAE or CONFIG_FILS */ #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 #ifdef CONFIG_DPP
} else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 32) { } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 32) {
wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA256)"); 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) tmp, ptk_len) < 0)
return -1; return -1;
} else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 48) { } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 48) {
wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA384)"); 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) tmp, ptk_len) < 0)
return -1; return -1;
} else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 64) { } else if (akmp == WPA_KEY_MGMT_DPP && pmk_len == 64) {
wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA512)"); 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) tmp, ptk_len) < 0)
return -1; return -1;
} else if (akmp == WPA_KEY_MGMT_DPP) { } 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 */ #endif /* CONFIG_DPP */
} else { } else {
wpa_printf(MSG_DEBUG, "WPA: PTK derivation using PRF(SHA1)"); 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) ptk_len) < 0)
return -1; 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)); MAC2STR(addr1), MAC2STR(addr2));
wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "WPA: Nonce1", nonce1, WPA_NONCE_LEN);
wpa_hexdump(MSG_DEBUG, "WPA: Nonce2", nonce2, 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: PMK", pmk, pmk_len);
wpa_hexdump_key(MSG_DEBUG, "WPA: PTK", tmp, ptk_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; ptk->kck2_len = 0;
os_memset(tmp, 0, sizeof(tmp)); os_memset(tmp, 0, sizeof(tmp));
os_memset(data, 0, data_len);
return 0; return 0;
} }

View 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, int wpa_pmk_to_ptk(const u8 *pmk, size_t pmk_len, const char *label,
const u8 *addr1, const u8 *addr2, const u8 *addr1, const u8 *addr2,
const u8 *nonce1, const u8 *nonce2, 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, int fils_rmsk_to_pmk(int akmp, const u8 *rmsk, size_t rmsk_len,
const u8 *snonce, const u8 *anonce, const u8 *dh_ss, const u8 *snonce, const u8 *anonce, const u8 *dh_ss,
size_t dh_ss_len, u8 *pmk, size_t *pmk_len); size_t dh_ss_len, u8 *pmk, size_t *pmk_len);

View 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", return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
sm->own_addr, sm->bssid, sm->snonce, sm->own_addr, sm->bssid, sm->snonce,
key->key_nonce, ptk, sm->key_mgmt, key->key_nonce, ptk, sm->key_mgmt,
sm->pairwise_cipher); sm->pairwise_cipher, NULL, 0);
} }

View File

@ -130,7 +130,7 @@ static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss,
"Pairwise key expansion", "Pairwise key expansion",
bss->bssid, sta->addr, sta->anonce, bss->bssid, sta->addr, sta->anonce,
sta->snonce, &ptk, sta->key_mgmt, 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, check_mic(ptk.kck, ptk.kck_len, sta->key_mgmt, ver, data,
len) < 0) { len) < 0) {
return -1; return -1;