From a3e18dbb6aeaac79151ea5386b3606f3c973f126 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 4 Jun 2018 15:16:54 +0300 Subject: [PATCH] FT: Support variable length keys This is a step in adding support for SHA384-based FT AKM. Signed-off-by: Jouni Malinen --- src/ap/wpa_auth_ft.c | 93 +++++++++++++++++++++++++---------------- src/ap/wpa_auth_i.h | 3 +- src/common/wpa_common.c | 6 ++- src/common/wpa_common.h | 7 ++-- src/rsn_supp/wpa.c | 5 ++- src/rsn_supp/wpa_ft.c | 43 +++++++++++-------- src/rsn_supp/wpa_i.h | 11 +++-- wlantest/rx_eapol.c | 4 +- 8 files changed, 106 insertions(+), 66 deletions(-) diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index bf1240a92..52e5779d9 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -16,6 +16,7 @@ #include "crypto/aes.h" #include "crypto/aes_siv.h" #include "crypto/aes_wrap.h" +#include "crypto/sha384.h" #include "crypto/random.h" #include "ap_config.h" #include "ieee802_11.h" @@ -1091,7 +1092,8 @@ static int wpa_ft_new_seq(struct ft_remote_seq *rkh_seq, struct wpa_ft_pmk_r0_sa { struct dl_list list; - u8 pmk_r0[PMK_LEN]; + u8 pmk_r0[PMK_LEN_MAX]; + size_t pmk_r0_len; u8 pmk_r0_name[WPA_PMK_NAME_LEN]; u8 spa[ETH_ALEN]; int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */ @@ -1108,7 +1110,8 @@ struct wpa_ft_pmk_r0_sa { struct wpa_ft_pmk_r1_sa { struct dl_list list; - u8 pmk_r1[PMK_LEN]; + u8 pmk_r1[PMK_LEN_MAX]; + size_t pmk_r1_len; u8 pmk_r1_name[WPA_PMK_NAME_LEN]; u8 spa[ETH_ALEN]; int pairwise; /* Pairwise cipher suite, WPA_CIPHER_* */ @@ -1139,7 +1142,7 @@ static void wpa_ft_free_pmk_r0(struct wpa_ft_pmk_r0_sa *r0) dl_list_del(&r0->list); eloop_cancel_timeout(wpa_ft_expire_pmk_r0, r0, NULL); - os_memset(r0->pmk_r0, 0, PMK_LEN); + os_memset(r0->pmk_r0, 0, PMK_LEN_MAX); os_free(r0->vlan); os_free(r0->identity); os_free(r0->radius_cui); @@ -1193,7 +1196,7 @@ static void wpa_ft_free_pmk_r1(struct wpa_ft_pmk_r1_sa *r1) dl_list_del(&r1->list); eloop_cancel_timeout(wpa_ft_expire_pmk_r1, r1, NULL); - os_memset(r1->pmk_r1, 0, PMK_LEN); + os_memset(r1->pmk_r1, 0, PMK_LEN_MAX); os_free(r1->vlan); os_free(r1->identity); os_free(r1->radius_cui); @@ -1242,6 +1245,7 @@ void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache) static int wpa_ft_store_pmk_r0(struct wpa_authenticator *wpa_auth, const u8 *spa, const u8 *pmk_r0, + size_t pmk_r0_len, const u8 *pmk_r0_name, int pairwise, const struct vlan_description *vlan, int expires_in, int session_timeout, @@ -1259,7 +1263,8 @@ static int wpa_ft_store_pmk_r0(struct wpa_authenticator *wpa_auth, if (r0 == NULL) return -1; - os_memcpy(r0->pmk_r0, pmk_r0, PMK_LEN); + os_memcpy(r0->pmk_r0, pmk_r0, pmk_r0_len); + r0->pmk_r0_len = pmk_r0_len; os_memcpy(r0->pmk_r0_name, pmk_r0_name, WPA_PMK_NAME_LEN); os_memcpy(r0->spa, spa, ETH_ALEN); r0->pairwise = pairwise; @@ -1327,6 +1332,7 @@ static int wpa_ft_fetch_pmk_r0(struct wpa_authenticator *wpa_auth, static int wpa_ft_store_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *spa, const u8 *pmk_r1, + size_t pmk_r1_len, const u8 *pmk_r1_name, int pairwise, const struct vlan_description *vlan, int expires_in, int session_timeout, @@ -1348,7 +1354,8 @@ static int wpa_ft_store_pmk_r1(struct wpa_authenticator *wpa_auth, if (r1 == NULL) return -1; - os_memcpy(r1->pmk_r1, pmk_r1, PMK_LEN); + os_memcpy(r1->pmk_r1, pmk_r1, pmk_r1_len); + r1->pmk_r1_len = pmk_r1_len; os_memcpy(r1->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN); os_memcpy(r1->spa, spa, ETH_ALEN); r1->pairwise = pairwise; @@ -1392,7 +1399,7 @@ static int wpa_ft_store_pmk_r1(struct wpa_authenticator *wpa_auth, static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth, const u8 *spa, const u8 *pmk_r1_name, - u8 *pmk_r1, int *pairwise, + u8 *pmk_r1, size_t *pmk_r1_len, int *pairwise, struct vlan_description *vlan, const u8 **identity, size_t *identity_len, const u8 **radius_cui, size_t *radius_cui_len, @@ -1408,7 +1415,8 @@ static int wpa_ft_fetch_pmk_r1(struct wpa_authenticator *wpa_auth, if (os_memcmp(r1->spa, spa, ETH_ALEN) == 0 && os_memcmp_const(r1->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN) == 0) { - os_memcpy(pmk_r1, r1->pmk_r1, PMK_LEN); + os_memcpy(pmk_r1, r1->pmk_r1, r1->pmk_r1_len); + *pmk_r1_len = r1->pmk_r1_len; if (pairwise) *pairwise = r1->pairwise; if (vlan && r1->vlan) @@ -1972,6 +1980,7 @@ int wpa_ft_store_pmk_fils(struct wpa_state_machine *sm, const u8 *identity, *radius_cui; size_t identity_len, radius_cui_len; int session_timeout; + size_t pmk_r0_len = PMK_LEN; if (wpa_ft_get_vlan(sm->wpa_auth, sm->addr, &vlan) < 0) { wpa_printf(MSG_DEBUG, "FT: vlan not available for STA " MACSTR, @@ -1984,8 +1993,8 @@ int wpa_ft_store_pmk_fils(struct wpa_state_machine *sm, &radius_cui); session_timeout = wpa_ft_get_session_timeout(sm->wpa_auth, sm->addr); - return wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_name, - sm->pairwise, &vlan, expires_in, + return wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_len, + pmk_r0_name, sm->pairwise, &vlan, expires_in, session_timeout, identity, identity_len, radius_cui, radius_cui_len); } @@ -1994,8 +2003,10 @@ int wpa_ft_store_pmk_fils(struct wpa_state_machine *sm, int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk, struct wpa_ptk *ptk) { - u8 pmk_r0[PMK_LEN], pmk_r0_name[WPA_PMK_NAME_LEN]; - u8 pmk_r1[PMK_LEN]; + u8 pmk_r0[PMK_LEN_MAX], pmk_r0_name[WPA_PMK_NAME_LEN]; + size_t pmk_r0_len = PMK_LEN; + size_t pmk_r1_len = pmk_r0_len; + u8 pmk_r1[PMK_LEN_MAX]; u8 ptk_name[WPA_PMK_NAME_LEN]; const u8 *mdid = sm->wpa_auth->conf.mobility_domain; const u8 *r0kh = sm->wpa_auth->conf.r0_key_holder; @@ -2031,28 +2042,29 @@ int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk, r0kh, r0kh_len, sm->addr, pmk_r0, pmk_r0_name) < 0) return -1; - wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, PMK_LEN); + wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", pmk_r0, pmk_r0_len); wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name, WPA_PMK_NAME_LEN); if (!psk_local || !wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt)) - wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_name, + wpa_ft_store_pmk_r0(sm->wpa_auth, sm->addr, pmk_r0, pmk_r0_len, + pmk_r0_name, sm->pairwise, &vlan, expires_in, session_timeout, identity, identity_len, radius_cui, radius_cui_len); - if (wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, r1kh, sm->addr, + if (wpa_derive_pmk_r1(pmk_r0, pmk_r0_len, pmk_r0_name, r1kh, sm->addr, pmk_r1, sm->pmk_r1_name) < 0) return -1; - wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, PMK_LEN); + wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, pmk_r1_len); wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", sm->pmk_r1_name, WPA_PMK_NAME_LEN); if (!psk_local || !wpa_key_mgmt_ft_psk(sm->wpa_key_mgmt)) - wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, + wpa_ft_store_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1, pmk_r1_len, sm->pmk_r1_name, sm->pairwise, &vlan, expires_in, session_timeout, identity, identity_len, radius_cui, radius_cui_len); - return wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr, - sm->wpa_auth->addr, sm->pmk_r1_name, + return wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce, + sm->addr, sm->wpa_auth->addr, sm->pmk_r1_name, ptk, ptk_name, sm->wpa_key_mgmt, sm->pairwise); } @@ -2501,8 +2513,8 @@ static int wpa_ft_psk_pmk_r1(struct wpa_state_machine *sm, if (wpa_derive_pmk_r0(pmk, PMK_LEN, ssid, ssid_len, mdid, r0kh, r0kh_len, sm->addr, pmk_r0, pmk_r0_name) < 0 || - wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, r1kh, sm->addr, - pmk_r1, pmk_r1_name) < 0 || + wpa_derive_pmk_r1(pmk_r0, PMK_LEN, pmk_r0_name, r1kh, + sm->addr, pmk_r1, pmk_r1_name) < 0 || os_memcmp_const(pmk_r1_name, req_pmk_r1_name, WPA_PMK_NAME_LEN) != 0) continue; @@ -2619,10 +2631,11 @@ static int wpa_ft_local_derive_pmk_r1(struct wpa_authenticator *wpa_auth, wpa_printf(MSG_DEBUG, "FT: Requested PMKR0Name found in local cache"); - if (wpa_derive_pmk_r1(r0->pmk_r0, r0->pmk_r0_name, conf->r1_key_holder, + if (wpa_derive_pmk_r1(r0->pmk_r0, r0->pmk_r0_len, r0->pmk_r0_name, + conf->r1_key_holder, sm->addr, out_pmk_r1, pmk_r1_name) < 0) return -1; - wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", out_pmk_r1, PMK_LEN); + wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", out_pmk_r1, r0->pmk_r0_len); wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name, WPA_PMK_NAME_LEN); os_get_reltime(&now); @@ -2632,7 +2645,8 @@ static int wpa_ft_local_derive_pmk_r1(struct wpa_authenticator *wpa_auth, if (r0->session_timeout) session_timeout = r0->session_timeout - now.sec; - wpa_ft_store_pmk_r1(wpa_auth, sm->addr, out_pmk_r1, pmk_r1_name, + wpa_ft_store_pmk_r1(wpa_auth, sm->addr, out_pmk_r1, r0->pmk_r0_len, + pmk_r1_name, sm->pairwise, r0->vlan, expires_in, session_timeout, r0->identity, r0->identity_len, r0->radius_cui, r0->radius_cui_len); @@ -2667,7 +2681,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, { struct rsn_mdie *mdie; struct rsn_ftie *ftie; - u8 pmk_r1[PMK_LEN], pmk_r1_name[WPA_PMK_NAME_LEN]; + u8 pmk_r1[PMK_LEN_MAX], pmk_r1_name[WPA_PMK_NAME_LEN]; u8 ptk_name[WPA_PMK_NAME_LEN]; struct wpa_auth_config *conf; struct wpa_ft_ies parse; @@ -2678,6 +2692,8 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, struct vlan_description vlan; const u8 *identity, *radius_cui; size_t identity_len = 0, radius_cui_len = 0; + int use_sha384 = wpa_key_mgmt_sha384(sm->wpa_key_mgmt); + size_t pmk_r1_len = use_sha384 ? SHA384_MAC_LEN : PMK_LEN; *resp_ies = NULL; *resp_ies_len = 0; @@ -2747,8 +2763,8 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, wpa_printf(MSG_DEBUG, "FT: Generated PMK-R1 for FT-PSK locally"); } else if (wpa_ft_fetch_pmk_r1(sm->wpa_auth, sm->addr, pmk_r1_name, - pmk_r1, &pairwise, &vlan, &identity, - &identity_len, &radius_cui, + pmk_r1, &pmk_r1_len, &pairwise, &vlan, + &identity, &identity_len, &radius_cui, &radius_cui_len, &session_timeout) < 0) { wpa_printf(MSG_DEBUG, "FT: No PMK-R1 available in local cache for the requested PMKR1Name"); @@ -2776,7 +2792,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, } pmk_r1_derived: - wpa_hexdump_key(MSG_DEBUG, "FT: Selected PMK-R1", pmk_r1, PMK_LEN); + wpa_hexdump_key(MSG_DEBUG, "FT: Selected PMK-R1", pmk_r1, pmk_r1_len); sm->pmk_r1_name_valid = 1; os_memcpy(sm->pmk_r1_name, pmk_r1_name, WPA_PMK_NAME_LEN); @@ -2791,8 +2807,8 @@ pmk_r1_derived: wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce", sm->ANonce, WPA_NONCE_LEN); - if (wpa_pmk_r1_to_ptk(pmk_r1, sm->SNonce, sm->ANonce, sm->addr, - sm->wpa_auth->addr, pmk_r1_name, + if (wpa_pmk_r1_to_ptk(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce, + sm->addr, sm->wpa_auth->addr, pmk_r1_name, &sm->PTK, ptk_name, sm->wpa_key_mgmt, pairwise) < 0) return WLAN_STATUS_UNSPECIFIED_FAILURE; @@ -3238,7 +3254,8 @@ static int wpa_ft_rrb_build_r0(const u8 *key, const size_t key_len, const u8 *src_addr, u8 type, u8 **packet, size_t *packet_len) { - u8 pmk_r1[PMK_LEN]; + u8 pmk_r1[PMK_LEN_MAX]; + size_t pmk_r1_len = pmk_r0->pmk_r0_len; u8 pmk_r1_name[WPA_PMK_NAME_LEN]; u8 f_pairwise[sizeof(le16)]; u8 f_expires_in[sizeof(le16)]; @@ -3248,7 +3265,7 @@ static int wpa_ft_rrb_build_r0(const u8 *key, const size_t key_len, struct os_reltime now; int ret; struct tlv_list sess_tlv[] = { - { .type = FT_RRB_PMK_R1, .len = sizeof(pmk_r1), + { .type = FT_RRB_PMK_R1, .len = pmk_r1_len, .data = pmk_r1 }, { .type = FT_RRB_PMK_R1_NAME, .len = sizeof(pmk_r1_name), .data = pmk_r1_name }, @@ -3266,11 +3283,14 @@ static int wpa_ft_rrb_build_r0(const u8 *key, const size_t key_len, { .type = FT_RRB_LAST_EMPTY, .len = 0, .data = NULL }, }; - if (wpa_derive_pmk_r1(pmk_r0->pmk_r0, pmk_r0->pmk_r0_name, r1kh_id, + if (wpa_derive_pmk_r1(pmk_r0->pmk_r0, pmk_r0->pmk_r0_len, + pmk_r0->pmk_r0_name, r1kh_id, s1kh_id, pmk_r1, pmk_r1_name) < 0) return -1; - wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, PMK_LEN); - wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name, WPA_PMK_NAME_LEN); + wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1 (for peer AP)", + pmk_r1, pmk_r1_len); + wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name (for peer AP)", + pmk_r1_name, WPA_PMK_NAME_LEN); WPA_PUT_LE16(f_pairwise, pmk_r0->pairwise); os_get_reltime(&now); @@ -3605,7 +3625,8 @@ static int wpa_ft_rrb_rx_r1(struct wpa_authenticator *wpa_auth, session_timeout = 0; wpa_printf(MSG_DEBUG, "FT: session_timeout %d", session_timeout); - if (wpa_ft_store_pmk_r1(wpa_auth, f_s1kh_id, f_pmk_r1, f_pmk_r1_name, + if (wpa_ft_store_pmk_r1(wpa_auth, f_s1kh_id, f_pmk_r1, PMK_LEN, + f_pmk_r1_name, pairwise, &vlan, expires_in, session_timeout, f_identity, f_identity_len, f_radius_cui, f_radius_cui_len) < 0) diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h index 9f797e92a..676e4bf15 100644 --- a/src/ap/wpa_auth_i.h +++ b/src/ap/wpa_auth_i.h @@ -112,7 +112,8 @@ struct wpa_state_machine { u32 dot11RSNAStatsTKIPRemoteMICFailures; #ifdef CONFIG_IEEE80211R_AP - u8 xxkey[PMK_LEN]; /* PSK or the second 256 bits of MSK */ + u8 xxkey[PMK_LEN_MAX]; /* PSK or the second 256 bits of MSK, or the + * first 384 bits of MSK */ size_t xxkey_len; u8 pmk_r1_name[WPA_PMK_NAME_LEN]; /* PMKR1Name derived from FT Auth * Request */ diff --git a/src/common/wpa_common.c b/src/common/wpa_common.c index d13f3000c..b6d4fba43 100644 --- a/src/common/wpa_common.c +++ b/src/common/wpa_common.c @@ -1479,7 +1479,8 @@ int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id, * * IEEE Std 802.11r-2008 - 8.5.1.5.4 */ -int wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name, +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, u8 *pmk_r1, u8 *pmk_r1_name) { @@ -1507,7 +1508,8 @@ int wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name, * * IEEE Std 802.11r-2008 - 8.5.1.5.5 */ -int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce, +int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len, + const u8 *snonce, const u8 *anonce, const u8 *sta_addr, const u8 *bssid, const u8 *pmk_r1_name, struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher) diff --git a/src/common/wpa_common.h b/src/common/wpa_common.h index 30f6e5b8e..3843167f0 100644 --- a/src/common/wpa_common.h +++ b/src/common/wpa_common.h @@ -367,11 +367,12 @@ int wpa_derive_pmk_r0(const u8 *xxkey, size_t xxkey_len, const u8 *s0kh_id, u8 *pmk_r0, u8 *pmk_r0_name); int wpa_derive_pmk_r1_name(const u8 *pmk_r0_name, const u8 *r1kh_id, const u8 *s1kh_id, u8 *pmk_r1_name); -int wpa_derive_pmk_r1(const u8 *pmk_r0, const u8 *pmk_r0_name, +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, u8 *pmk_r1, u8 *pmk_r1_name); -int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, const u8 *snonce, const u8 *anonce, - const u8 *sta_addr, const u8 *bssid, +int wpa_pmk_r1_to_ptk(const u8 *pmk_r1, size_t pmk_r1_len, const u8 *snonce, + const u8 *anonce, const u8 *sta_addr, const u8 *bssid, const u8 *pmk_r1_name, struct wpa_ptk *ptk, u8 *ptk_name, int akmp, int cipher); #endif /* CONFIG_IEEE80211R */ diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index 51b24f430..da597e90f 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -1,6 +1,6 @@ /* * WPA Supplicant - WPA state machine and EAPOL-Key processing - * Copyright (c) 2003-2017, Jouni Malinen + * Copyright (c) 2003-2018, Jouni Malinen * Copyright(c) 2015 Intel Deutschland GmbH * * This software may be distributed under the terms of the BSD license. @@ -3151,8 +3151,11 @@ void wpa_sm_drop_sa(struct wpa_sm *sm) #endif /* CONFIG_IEEE80211W */ #ifdef CONFIG_IEEE80211R os_memset(sm->xxkey, 0, sizeof(sm->xxkey)); + sm->xxkey_len = 0; os_memset(sm->pmk_r0, 0, sizeof(sm->pmk_r0)); + sm->pmk_r0_len = 0; os_memset(sm->pmk_r1, 0, sizeof(sm->pmk_r1)); + sm->pmk_r1_len = 0; #endif /* CONFIG_IEEE80211R */ } diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index 77b00bda7..da1ce39f0 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -30,21 +30,26 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr, return -1; } - wpa_derive_pmk_r0(sm->xxkey, sm->xxkey_len, sm->ssid, - sm->ssid_len, sm->mobility_domain, - sm->r0kh_id, sm->r0kh_id_len, sm->own_addr, - sm->pmk_r0, sm->pmk_r0_name); - wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", sm->pmk_r0, PMK_LEN); + sm->pmk_r0_len = PMK_LEN; + if (wpa_derive_pmk_r0(sm->xxkey, sm->xxkey_len, sm->ssid, + sm->ssid_len, sm->mobility_domain, + sm->r0kh_id, sm->r0kh_id_len, sm->own_addr, + sm->pmk_r0, sm->pmk_r0_name) < 0) + return -1; + wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R0", sm->pmk_r0, sm->pmk_r0_len); wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", sm->pmk_r0_name, WPA_PMK_NAME_LEN); - wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_name, sm->r1kh_id, - sm->own_addr, sm->pmk_r1, sm->pmk_r1_name); - wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", sm->pmk_r1, PMK_LEN); + sm->pmk_r1_len = sm->pmk_r0_len; + if (wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_len, sm->pmk_r0_name, + sm->r1kh_id, sm->own_addr, sm->pmk_r1, + sm->pmk_r1_name) < 0) + return -1; + wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", sm->pmk_r1, sm->pmk_r1_len); wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", sm->pmk_r1_name, WPA_PMK_NAME_LEN); - return wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->snonce, anonce, sm->own_addr, - sm->bssid, sm->pmk_r1_name, ptk, ptk_name, - sm->key_mgmt, sm->pairwise_cipher); + return wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, anonce, + sm->own_addr, sm->bssid, sm->pmk_r1_name, ptk, + ptk_name, sm->key_mgmt, sm->pairwise_cipher); } @@ -510,16 +515,20 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len, wpa_hexdump(MSG_DEBUG, "FT: SNonce", sm->snonce, WPA_NONCE_LEN); wpa_hexdump(MSG_DEBUG, "FT: ANonce", ftie->anonce, WPA_NONCE_LEN); os_memcpy(sm->anonce, ftie->anonce, WPA_NONCE_LEN); - wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_name, sm->r1kh_id, - sm->own_addr, sm->pmk_r1, sm->pmk_r1_name); - wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", sm->pmk_r1, PMK_LEN); + if (wpa_derive_pmk_r1(sm->pmk_r0, sm->pmk_r0_len, sm->pmk_r0_name, + sm->r1kh_id, sm->own_addr, sm->pmk_r1, + sm->pmk_r1_name) < 0) + return -1; + sm->pmk_r1_len = sm->pmk_r0_len; + wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", sm->pmk_r1, sm->pmk_r1_len); wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", sm->pmk_r1_name, WPA_PMK_NAME_LEN); bssid = target_ap; - if (wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->snonce, ftie->anonce, - sm->own_addr, bssid, sm->pmk_r1_name, &sm->ptk, - ptk_name, sm->key_mgmt, sm->pairwise_cipher) < 0) + if (wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, + ftie->anonce, sm->own_addr, bssid, + sm->pmk_r1_name, &sm->ptk, ptk_name, sm->key_mgmt, + sm->pairwise_cipher) < 0) return -1; if (wpa_key_mgmt_fils(sm->key_mgmt)) { diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index e8da19457..b94b17a85 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -1,6 +1,6 @@ /* * Internal WPA/RSN supplicant state machine definitions - * Copyright (c) 2004-2017, Jouni Malinen + * Copyright (c) 2004-2018, Jouni Malinen * * This software may be distributed under the terms of the BSD license. * See README for more details. @@ -112,11 +112,14 @@ struct wpa_sm { #endif /* CONFIG_TDLS */ #ifdef CONFIG_IEEE80211R - u8 xxkey[PMK_LEN]; /* PSK or the second 256 bits of MSK */ + u8 xxkey[PMK_LEN_MAX]; /* PSK or the second 256 bits of MSK, or the + * first 384 bits of MSK */ size_t xxkey_len; - u8 pmk_r0[PMK_LEN]; + u8 pmk_r0[PMK_LEN_MAX]; + size_t pmk_r0_len; u8 pmk_r0_name[WPA_PMK_NAME_LEN]; - u8 pmk_r1[PMK_LEN]; + u8 pmk_r1[PMK_LEN_MAX]; + size_t pmk_r1_len; u8 pmk_r1_name[WPA_PMK_NAME_LEN]; u8 mobility_domain[MOBILITY_DOMAIN_ID_LEN]; u8 r0kh_id[FT_R0KH_ID_MAX_LEN]; diff --git a/wlantest/rx_eapol.c b/wlantest/rx_eapol.c index 536a6c07d..069e63476 100644 --- a/wlantest/rx_eapol.c +++ b/wlantest/rx_eapol.c @@ -113,12 +113,12 @@ static int try_pmk(struct wlantest *wt, struct wlantest_bss *bss, wpa_hexdump(MSG_DEBUG, "FT: PMK-R0", pmk_r0, PMK_LEN); wpa_hexdump(MSG_DEBUG, "FT: PMKR0Name", pmk_r0_name, WPA_PMK_NAME_LEN); - wpa_derive_pmk_r1(pmk_r0, pmk_r0_name, bss->r1kh_id, + wpa_derive_pmk_r1(pmk_r0, PMK_LEN, pmk_r0_name, bss->r1kh_id, sta->addr, pmk_r1, pmk_r1_name); wpa_hexdump_key(MSG_DEBUG, "FT: PMK-R1", pmk_r1, PMK_LEN); wpa_hexdump(MSG_DEBUG, "FT: PMKR1Name", pmk_r1_name, WPA_PMK_NAME_LEN); - if (wpa_pmk_r1_to_ptk(pmk_r1, sta->snonce, sta->anonce, + if (wpa_pmk_r1_to_ptk(pmk_r1, PMK_LEN, sta->snonce, sta->anonce, sta->addr, bss->bssid, pmk_r1_name, &ptk, ptk_name, sta->key_mgmt,