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 <j@w1.fi>
This commit is contained in:
Jouni Malinen 2017-05-07 14:32:25 +03:00
parent 7d440a3bc4
commit 8fed47e013
3 changed files with 33 additions and 4 deletions

View file

@ -2089,14 +2089,40 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk,
u8 ick[FILS_ICK_MAX_LEN]; u8 ick[FILS_ICK_MAX_LEN];
size_t ick_len; size_t ick_len;
int res; 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, res = fils_pmk_to_ptk(pmk, pmk_len, sm->addr, sm->wpa_auth->addr,
snonce, anonce, &sm->PTK, ick, &ick_len, 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) if (res < 0)
return res; return res;
sm->PTK_valid = TRUE; 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, res = fils_key_auth_sk(ick, ick_len, snonce, anonce,
sm->addr, sm->wpa_auth->addr, sm->addr, sm->wpa_auth->addr,
g_sta ? wpabuf_head(g_sta) : NULL, g_sta ? wpabuf_head(g_sta) : NULL,

View file

@ -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, int wpa_ft_store_pmk_r0(struct wpa_authenticator *wpa_auth,
const u8 *spa, const u8 *pmk_r0, const u8 *spa, const u8 *pmk_r0,
const u8 *pmk_r0_name, int pairwise) const u8 *pmk_r0_name, int pairwise)
{ {
struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache; struct wpa_ft_pmk_cache *cache = wpa_auth->ft_pmk_cache;
struct wpa_ft_pmk_r0_sa *r0; struct wpa_ft_pmk_r0_sa *r0;

View file

@ -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); 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_pmk_cache_deinit(struct wpa_ft_pmk_cache *cache);
void wpa_ft_install_ptk(struct wpa_state_machine *sm); 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 /* CONFIG_IEEE80211R_AP */
#endif /* WPA_AUTH_I_H */ #endif /* WPA_AUTH_I_H */