]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FILS: Derive FT key hierarchy on authenticator side for FILS+FT
authorJouni Malinen <j@w1.fi>
Sun, 7 May 2017 11:32:25 +0000 (14:32 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 7 May 2017 19:08:43 +0000 (22:08 +0300)
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>
src/ap/wpa_auth.c
src/ap/wpa_auth_ft.c
src/ap/wpa_auth_i.h

index 7e3f9c83e29cdccc2982da6f70de5a32f6e63838..459b56e58963d7e47c5e0773cc5049a32ca679bb 100644 (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];
        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,
index b73ea9944c8e0aec7415b4c8917577019bca5494..dd99db70adc0efc30e4f4d0d043e77c024c6bb32 100644 (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,
-                              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;
index 7ef817f542f0dbb936b6307d4e113523c8a778c0..e7d699ee565a3ae9f2ca265e702a2473bb050589 100644 (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);
 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 */