From 4f58afee9a4ff15e859d08ba6034f51f4d3c50e0 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 16 Oct 2022 16:38:27 +0300 Subject: [PATCH] FT: Extend MIC derivation for FT-SAE-EXT-KEY Provide AKM to the helper function so that the new SHA256 and SHA512 options can be covered for FT-SAE-EXT-KEY. Signed-off-by: Jouni Malinen --- src/ap/wpa_auth_ft.c | 6 ++++-- src/common/wpa_common.c | 37 +++++++++++++++++++++++++++++++------ src/common/wpa_common.h | 2 +- src/rsn_supp/wpa_ft.c | 5 +++-- wlantest/rx_mgmt.c | 6 ++++-- 5 files changed, 43 insertions(+), 13 deletions(-) diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 03376b02f..eb167cb60 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -2813,7 +2813,8 @@ u8 * wpa_sm_write_assoc_resp_ies(struct wpa_state_machine *sm, u8 *pos, kck_len = sm->PTK.kck_len; } if (auth_alg == WLAN_AUTH_FT && - wpa_ft_mic(kck, kck_len, sm->addr, sm->wpa_auth->addr, 6, + wpa_ft_mic(sm->wpa_key_mgmt, kck, kck_len, + sm->addr, sm->wpa_auth->addr, 6, mdie, mdie_len, ftie, ftie_len, rsnie, rsnie_len, ric_start, ric_start ? pos - ric_start : 0, @@ -3548,7 +3549,8 @@ int wpa_ft_validate_reassoc(struct wpa_state_machine *sm, const u8 *ies, kck = sm->PTK.kck; kck_len = sm->PTK.kck_len; } - if (wpa_ft_mic(kck, kck_len, sm->addr, sm->wpa_auth->addr, 5, + if (wpa_ft_mic(sm->wpa_key_mgmt, kck, kck_len, + sm->addr, sm->wpa_auth->addr, 5, parse.mdie - 2, parse.mdie_len + 2, parse.ftie - 2, parse.ftie_len + 2, parse.rsn - 2, parse.rsn_len + 2, diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index f437def50..8c19ace79 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -882,7 +882,7 @@ int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce, #ifdef CONFIG_IEEE80211R -int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr, +int wpa_ft_mic(int key_mgmt, const u8 *kck, size_t kck_len, const u8 *sta_addr, const u8 *ap_addr, u8 transaction_seqnum, const u8 *mdie, size_t mdie_len, const u8 *ftie, size_t ftie_len, @@ -894,8 +894,9 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr, const u8 *addr[10]; size_t len[10]; size_t i, num_elem = 0; - u8 zero_mic[24]; + u8 zero_mic[32]; size_t mic_len, fte_fixed_len; + int res; if (kck_len == 16) { mic_len = 16; @@ -903,6 +904,10 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr, } else if (kck_len == 24) { mic_len = 24; #endif /* CONFIG_SHA384 */ +#ifdef CONFIG_SHA512 + } else if (kck_len == 32) { + mic_len = 32; +#endif /* CONFIG_SHA512 */ } else { wpa_printf(MSG_WARNING, "FT: Unsupported KCK length %u", (unsigned int) kck_len); @@ -967,6 +972,17 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr, for (i = 0; i < num_elem; i++) wpa_hexdump(MSG_MSGDUMP, "FT: MIC data", addr[i], len[i]); + res = -1; +#ifdef CONFIG_SHA512 + if (kck_len == 32) { + u8 hash[SHA512_MAC_LEN]; + + if (hmac_sha512_vector(kck, kck_len, num_elem, addr, len, hash)) + return -1; + os_memcpy(mic, hash, 32); + res = 0; + } +#endif /* CONFIG_SHA384 */ #ifdef CONFIG_SHA384 if (kck_len == 24) { u8 hash[SHA384_MAC_LEN]; @@ -974,13 +990,22 @@ int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr, if (hmac_sha384_vector(kck, kck_len, num_elem, addr, len, hash)) return -1; os_memcpy(mic, hash, 24); + res = 0; } #endif /* CONFIG_SHA384 */ - if (kck_len == 16 && - omac1_aes_128_vector(kck, num_elem, addr, len, mic)) - return -1; + if (kck_len == 16 && key_mgmt == WPA_KEY_MGMT_FT_SAE_EXT_KEY) { + u8 hash[SHA256_MAC_LEN]; - return 0; + if (hmac_sha256_vector(kck, kck_len, num_elem, addr, len, hash)) + return -1; + os_memcpy(mic, hash, 16); + res = 0; + } + if (kck_len == 16 && key_mgmt != WPA_KEY_MGMT_FT_SAE_EXT_KEY && + omac1_aes_128_vector(kck, num_elem, addr, len, mic) == 0) + res = 0; + + return res; } diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index 4667284a3..4af22bf65 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -463,7 +463,7 @@ int fils_key_auth_sk(const u8 *ick, size_t ick_len, const u8 *snonce, size_t *key_auth_len); #ifdef CONFIG_IEEE80211R -int wpa_ft_mic(const u8 *kck, size_t kck_len, const u8 *sta_addr, +int wpa_ft_mic(int key_mgmt, const u8 *kck, size_t kck_len, const u8 *sta_addr, const u8 *ap_addr, u8 transaction_seqnum, const u8 *mdie, size_t mdie_len, const u8 *ftie, size_t ftie_len, diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index c681a99df..1c27a79bd 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -441,7 +441,8 @@ static u8 * wpa_ft_gen_req_ies(struct wpa_sm *sm, size_t *len, *elem_count = 3 + ieee802_11_ie_count(ric_ies, ric_ies_len); if (rsnxe_len) *elem_count += 1; - if (wpa_ft_mic(kck, kck_len, sm->own_addr, target_ap, 5, + if (wpa_ft_mic(sm->key_mgmt, kck, kck_len, + sm->own_addr, target_ap, 5, ((u8 *) mdie) - 2, 2 + sizeof(*mdie), ftie_pos, 2 + *ftie_len, (u8 *) rsnie, 2 + rsnie->len, ric_ies, @@ -1142,7 +1143,7 @@ int wpa_ft_validate_reassoc_resp(struct wpa_sm *sm, const u8 *ies, kck_len = sm->ptk.kck_len; } - if (wpa_ft_mic(kck, kck_len, sm->own_addr, src_addr, 6, + if (wpa_ft_mic(sm->key_mgmt, kck, kck_len, sm->own_addr, src_addr, 6, parse.mdie - 2, parse.mdie_len + 2, parse.ftie - 2, parse.ftie_len + 2, parse.rsn - 2, parse.rsn_len + 2, diff --git a/wlantest/rx_mgmt.c b/wlantest/rx_mgmt.c index a0751df5b..2a9a03058 100644 --- a/wlantest/rx_mgmt.c +++ b/wlantest/rx_mgmt.c @@ -1052,7 +1052,8 @@ static void rx_mgmt_reassoc_req(struct wlantest *wt, const u8 *data, kck = sta->ptk.kck; kck_len = sta->ptk.kck_len; } - if (wpa_ft_mic(kck, kck_len, sta->addr, bss->bssid, 5, + if (wpa_ft_mic(sta->key_mgmt, kck, kck_len, + sta->addr, bss->bssid, 5, parse.mdie - 2, parse.mdie_len + 2, parse.ftie - 2, parse.ftie_len + 2, parse.rsn - 2, parse.rsn_len + 2, @@ -1556,7 +1557,8 @@ static void rx_mgmt_reassoc_resp(struct wlantest *wt, const u8 *data, kek = sta->ptk.kek; kek_len = sta->ptk.kek_len; } - if (wpa_ft_mic(kck, kck_len, sta->addr, bss->bssid, 6, + if (wpa_ft_mic(sta->key_mgmt, kck, kck_len, + sta->addr, bss->bssid, 6, parse.mdie - 2, parse.mdie_len + 2, parse.ftie - 2, parse.ftie_len + 2, parse.rsn - 2, parse.rsn_len + 2,