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:
parent
7d440a3bc4
commit
8fed47e013
3 changed files with 33 additions and 4 deletions
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue