From c3e4f40cd65a30ee2977b5de02cee40c9928f407 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 6 Jun 2018 21:57:58 +0300 Subject: [PATCH] FT: Derive PMKR0Name/PMKR1Name using SHA-384 with AKM 00-0F-AC:13 The AKM 00-0F-AC:13 is supposed to use cryptographic algorithms consistently, but the current IEEE 802.11 standard is not doing so for the key names: PMKID (uses SHA-1), PMKR0Name/PMKR1Name (uses SHA-256). The PMKID case was already implemented with SHA-384 and this commit replaces use of SHA-256 with SHA-384 for PMKR0Name/PMKR1Name derivation to be consistent in SHA-384. While this is not compliant with the current IEEE 802.11 standard, this is clearly needed to meet CNSA Suite requirements. Matching change is being proposed in REVmd to get the IEEE 802.11 standard to meet the use case requirements. Signed-off-by: Jouni Malinen --- src/ap/wpa_auth_ft.c | 2 +- src/common/wpa_common.c | 27 ++++++++++++++++++--------- src/common/wpa_common.h | 2 +- src/rsn_supp/wpa.c | 2 +- 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 521117736..e8d46ab0d 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -2834,7 +2834,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, parse.rsn_pmkid, WPA_PMK_NAME_LEN); if (wpa_derive_pmk_r1_name(parse.rsn_pmkid, sm->wpa_auth->conf.r1_key_holder, sm->addr, - pmk_r1_name) < 0) + pmk_r1_name, use_sha384) < 0) return WLAN_STATUS_UNSPECIFIED_FAILURE; wpa_hexdump(MSG_DEBUG, "FT: Derived requested PMKR1Name", pmk_r1_name, WPA_PMK_NAME_LEN); diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index a8da7f02f..14c5769b0 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -1480,7 +1480,7 @@ int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len, { u8 buf[1 + SSID_MAX_LEN + MOBILITY_DOMAIN_ID_LEN + 1 + FT_R0KH_ID_MAX_LEN + ETH_ALEN]; - u8 *pos, r0_key_data[64], hash[32]; + u8 *pos, r0_key_data[64], hash[48]; const u8 *addr[2]; size_t len[2]; size_t q = use_sha384 ? 48 : 32; @@ -1546,14 +1546,18 @@ int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len, wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0Name-Salt", &r0_key_data[q], 16); /* - * PMKR0Name = Truncate-128(SHA-256("FT-R0N" || PMK-R0Name-Salt) + * PMKR0Name = Truncate-128(Hash("FT-R0N" || PMK-R0Name-Salt) */ addr[0] = (const u8 *) "FT-R0N"; len[0] = 6; addr[1] = &r0_key_data[q]; len[1] = 16; - if (sha256_vector(2, addr, len, hash) < 0) +#ifdef CONFIG_SHA384 + if (use_sha384 && sha384_vector(2, addr, len, hash) < 0) + return -1; +#endif /* CONFIG_SHA384 */ + if (!use_sha384 && sha256_vector(2, addr, len, hash) < 0) return -1; os_memcpy(pmk_r0_name, hash, WPA_PMK_NAME_LEN); os_memset(r0_key_data, 0, sizeof(r0_key_data)); @@ -1567,15 +1571,15 @@ int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len, * IEEE Std 802.11r-2008 - 8.5.1.5.4 */ int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id, - const u8 *s1kh_id, u8 *pmk_r1_name) + const u8 *s1kh_id, u8 *pmk_r1_name, int use_sha384) { - u8 hash[32]; + u8 hash[48]; const u8 *addr[4]; size_t len[4]; /* - * PMKR1Name = Truncate-128(SHA-256("FT-R1N" || PMKR0Name || - * R1KH-ID || S1KH-ID)) + * PMKR1Name = Truncate-128(Hash("FT-R1N" || PMKR0Name || + * R1KH-ID || S1KH-ID)) */ addr[0] = (const u8 *) "FT-R1N"; len[0] = 6; @@ -1586,7 +1590,11 @@ int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id, addr[3] = s1kh_id; len[3] = ETH_ALEN; - if (sha256_vector(4, addr, len, hash) < 0) +#ifdef CONFIG_SHA384 + if (use_sha384 && sha384_vector(4, addr, len, hash) < 0) + return -1; +#endif /* CONFIG_SHA384 */ + if (!use_sha384 && sha256_vector(4, addr, len, hash) < 0) return -1; os_memcpy(pmk_r1_name, hash, WPA_PMK_NAME_LEN); return 0; @@ -1636,7 +1644,8 @@ int wpa_derive_pmk_r1(const u8 *pmk_r0, size_t pmk_r0_len, wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r0_len); return wpa_derive_pmk_r1_name(pmk_r0_name, r1kh_id, s1kh_id, - pmk_r1_name); + pmk_r1_name, + pmk_r0_len == SHA384_MAC_LEN); } diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index 6d808d7fd..626174440 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -375,7 +375,7 @@ int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len, const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name, int use_sha384); int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id, - const u8 *s1kh_id, u8 *pmk_r1_name); + const u8 *s1kh_id, u8 *pmk_r1_name, int use_sha384); int wpa_derive_pmk_r1(const u8 *pmk_r0, size_t pmk_r0_len, const u8 *pmk_r0_name, const u8 *r1kh_id, const u8 *s1kh_id, diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index b8ab2b1bc..56f3af799 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -3829,7 +3829,7 @@ static int fils_ft_build_assoc_req_rsne(struct wpa_sm *sm, struct wpabuf *buf) MAC2STR(sm->r1kh_id)); pos = wpabuf_put(buf, WPA_PMK_NAME_LEN); if (wpa_derive_pmk_r1_name(sm->pmk_r0_name, sm->r1kh_id, sm->own_addr, - pos) < 0) { + pos, use_sha384) < 0) { wpa_printf(MSG_WARNING, "FILS+FT: Could not derive PMKR1Name"); return -1; }