From 8fed47e0138276383b03fe464063a49b3e7154cd Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 7 May 2017 14:32:25 +0300 Subject: [PATCH] FILS: Derive FT key hierarchy on authenticator side for FILS+FT Derive PMK-R0 and the relevant key names when using FILS authentication for initial FT mobility domain association. Signed-off-by: Jouni Malinen --- src/ap/wpa_auth.c | 28 +++++++++++++++++++++++++++- src/ap/wpa_auth_ft.c | 6 +++--- src/ap/wpa_auth_i.h | 3 +++ 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index 7e3f9c83e..459b56e58 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -2089,14 +2089,40 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk, u8 ick[FILS_ICK_MAX_LEN]; size_t ick_len; int res; + u8 fils_ft[FILS_FT_MAX_LEN]; + size_t fils_ft_len = 0; res = fils_pmk_to_ptk(pmk, pmk_len, sm->addr, sm->wpa_auth->addr, snonce, anonce, &sm->PTK, ick, &ick_len, - sm->wpa_key_mgmt, sm->pairwise, NULL, NULL); + sm->wpa_key_mgmt, sm->pairwise, + fils_ft, &fils_ft_len); if (res < 0) return res; sm->PTK_valid = TRUE; +#ifdef CONFIG_IEEE80211R_AP + if (fils_ft_len) { + struct wpa_authenticator *wpa_auth = sm->wpa_auth; + struct wpa_auth_config *conf = &wpa_auth->conf; + u8 pmk_r0[PMK_LEN], pmk_r0_name[WPA_PMK_NAME_LEN]; + + if (wpa_derive_pmk_r0(fils_ft, fils_ft_len, + conf->ssid, conf->ssid_len, + conf->mobility_domain, + conf->r0_key_holder, + conf->r0_key_holder_len, + sm->addr, pmk_r0, pmk_r0_name) < 0) + return -1; + + wpa_hexdump_key(MSG_DEBUG, "FILS+FT: PMK-R0", pmk_r0, PMK_LEN); + wpa_hexdump(MSG_DEBUG, "FILS+FT: PMKR0Name", + pmk_r0_name, WPA_PMK_NAME_LEN); + wpa_ft_store_pmk_r0(wpa_auth, sm->addr, pmk_r0, pmk_r0_name, + sm->pairwise); + os_memset(fils_ft, 0, sizeof(fils_ft)); + } +#endif /* CONFIG_IEEE80211R_AP */ + res = fils_key_auth_sk(ick, ick_len, snonce, anonce, sm->addr, sm->wpa_auth->addr, g_sta ? wpabuf_head(g_sta) : NULL, diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index b73ea9944..dd99db70a 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -892,9 +892,9 @@ 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, - const u8 *pmk_r0_name, int pairwise) +int wpa_ft_store_pmk_r0(struct wpa_authenticator *wpa_auth, + const u8 *spa, const u8 *pmk_r0, + const u8 *pmk_r0_name, int pairwise) { struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache; struct wpa_ft_pmk_r0_sa *r0; diff --git a/src/ap/wpa_auth_i.h b/src/ap/wpa_auth_i.h index 7ef817f54..e7d699ee5 100644 --- a/src/ap/wpa_auth_i.h +++ b/src/ap/wpa_auth_i.h @@ -288,6 +288,9 @@ int wpa_auth_derive_ptk_ft(struct wpa_state_machine *sm, const u8 *pmk, struct wpa_ft_pmk_cache * wpa_ft_pmk_cache_init(void); void wpa_ft_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache); void wpa_ft_install_ptk(struct wpa_state_machine *sm); +int wpa_ft_store_pmk_r0(struct wpa_authenticator *wpa_auth, + const u8 *spa, const u8 *pmk_r0, + const u8 *pmk_r0_name, int pairwise); #endif /* CONFIG_IEEE80211R_AP */ #endif /* WPA_AUTH_I_H */