From 62097e7d82a8d8af35a18d6a25bea5632153192b Mon Sep 17 00:00:00 2001 From: James Prestwood Date: Thu, 25 Apr 2019 12:52:48 -0700 Subject: [PATCH] crypto: allow PTK derivation using SHA384 crypto_derive_pairwise_ptk was taking a boolean to decide whether to use SHA1 or SHA256, but for FILS SHA384 may also be required for rekeys depending on the AKM. crypto_derive_pairwise_ptk was changed to take l_checksum_type instead of a boolean to allow for all 3 SHA types. --- src/crypto.c | 11 +++++++---- src/crypto.h | 2 +- src/eapol.c | 3 ++- src/handshake.c | 8 ++++---- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/crypto.c b/src/crypto.c index 85de78f3..1c2d2db2 100644 --- a/src/crypto.c +++ b/src/crypto.c @@ -785,7 +785,7 @@ static bool crypto_derive_ptk(const uint8_t *pmk, size_t pmk_len, const uint8_t *addr1, const uint8_t *addr2, const uint8_t *nonce1, const uint8_t *nonce2, uint8_t *out_ptk, size_t ptk_len, - bool use_sha256) + enum l_checksum_type type) { /* Nonce length is 32 */ uint8_t data[ETH_ALEN * 2 + 64]; @@ -812,7 +812,10 @@ static bool crypto_derive_ptk(const uint8_t *pmk, size_t pmk_len, } pos += 64; - if (use_sha256) + if (type == L_CHECKSUM_SHA384) + return kdf_sha384(pmk, pmk_len, label, strlen(label), + data, sizeof(data), out_ptk, ptk_len); + else if (type == L_CHECKSUM_SHA256) return kdf_sha256(pmk, pmk_len, label, strlen(label), data, sizeof(data), out_ptk, ptk_len); else @@ -824,12 +827,12 @@ bool crypto_derive_pairwise_ptk(const uint8_t *pmk, size_t pmk_len, const uint8_t *addr1, const uint8_t *addr2, const uint8_t *nonce1, const uint8_t *nonce2, uint8_t *out_ptk, size_t ptk_len, - bool use_sha256) + enum l_checksum_type type) { return crypto_derive_ptk(pmk, pmk_len, "Pairwise key expansion", addr1, addr2, nonce1, nonce2, out_ptk, ptk_len, - use_sha256); + type); } /* Defined in 802.11-2012, Section 11.6.1.7.3 PMK-R0 */ diff --git a/src/crypto.h b/src/crypto.h index 34a97c9c..0b7f0275 100644 --- a/src/crypto.h +++ b/src/crypto.h @@ -114,7 +114,7 @@ bool crypto_derive_pairwise_ptk(const uint8_t *pmk, size_t pmk_len, const uint8_t *addr1, const uint8_t *addr2, const uint8_t *nonce1, const uint8_t *nonce2, uint8_t *out_ptk, size_t ptk_len, - bool use_sha256); + enum l_checksum_type type); bool crypto_derive_pmk_r0(const uint8_t *xxkey, const uint8_t *ssid, size_t ssid_len, diff --git a/src/eapol.c b/src/eapol.c index caf8710f..90d0d4bf 100644 --- a/src/eapol.c +++ b/src/eapol.c @@ -1379,7 +1379,8 @@ static void eapol_handle_ptk_2_of_4(struct eapol_sm *sm, sm->handshake->pmk_len, sm->handshake->spa, aa, sm->handshake->anonce, ek->key_nonce, - sm->handshake->ptk, ptk_size, false)) + sm->handshake->ptk, ptk_size, + L_CHECKSUM_SHA1)) return; kck = handshake_state_get_kck(sm->handshake); diff --git a/src/handshake.c b/src/handshake.c index 94389eda..07203aef 100644 --- a/src/handshake.c +++ b/src/handshake.c @@ -375,7 +375,7 @@ static bool handshake_get_key_sizes(struct handshake_state *s, size_t *ptk_size, bool handshake_state_derive_ptk(struct handshake_state *s) { size_t ptk_size; - bool use_sha256; + enum l_checksum_type type; if (!s->have_snonce || !s->have_pmk) return false; @@ -393,9 +393,9 @@ bool handshake_state_derive_ptk(struct handshake_state *s) IE_RSN_AKM_SUITE_SAE_SHA256 | IE_RSN_AKM_SUITE_FT_OVER_SAE_SHA256 | IE_RSN_AKM_SUITE_OWE)) - use_sha256 = true; + type = L_CHECKSUM_SHA256; else - use_sha256 = false; + type = L_CHECKSUM_SHA1; ptk_size = handshake_state_get_ptk_size(s); @@ -439,7 +439,7 @@ bool handshake_state_derive_ptk(struct handshake_state *s) } else if (!crypto_derive_pairwise_ptk(s->pmk, s->pmk_len, s->spa, s->aa, s->anonce, s->snonce, - s->ptk, ptk_size, use_sha256)) + s->ptk, ptk_size, type)) return false; return true;