]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
FILS: Find PMKSA cache entries on AP based on FILS Cache Identifier
authorJouni Malinen <jouni@qca.qualcomm.com>
Tue, 21 Feb 2017 10:18:58 +0000 (12:18 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 21 Feb 2017 10:18:58 +0000 (12:18 +0200)
This allows PMKSA cache entries to be shared between all the BSSs
operated by the same hostapd process when those BSSs use the same FILS
Cache Identifier value.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/ap/ieee802_11.c
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_glue.c

index e1a671203e09ec154973050d66a33c575ecb9d71..73699663dc4baa7cc73dae4211160c8ef62f3a14 100644 (file)
@@ -1099,6 +1099,11 @@ static void handle_auth_fils(struct hostapd_data *hapd, struct sta_info *sta,
                                                   pmkid);
                        if (pmksa)
                                break;
+                       pmksa = wpa_auth_pmksa_get_fils_cache_id(hapd->wpa_auth,
+                                                                sta->addr,
+                                                                pmkid);
+                       if (pmksa)
+                               break;
                        pmkid += PMKID_LEN;
                        num--;
                }
index 7b26c04cddf5455543d3b06eb430947e07332194..a3df81bda9787a0383777653ceec7ce080d72b45 100644 (file)
@@ -4216,3 +4216,47 @@ void wpa_auth_reconfig_group_keys(struct wpa_authenticator *wpa_auth)
        for (group = wpa_auth->group; group; group = group->next)
                wpa_group_config_group_keys(wpa_auth, group);
 }
+
+
+#ifdef CONFIG_FILS
+
+struct wpa_auth_fils_iter_data {
+       struct wpa_authenticator *auth;
+       const u8 *cache_id;
+       struct rsn_pmksa_cache_entry *pmksa;
+       const u8 *spa;
+       const u8 *pmkid;
+};
+
+
+static int wpa_auth_fils_iter(struct wpa_authenticator *a, void *ctx)
+{
+       struct wpa_auth_fils_iter_data *data = ctx;
+
+       if (a == data->auth || !a->conf.fils_cache_id ||
+           os_memcmp(a->conf.fils_cache_id, data->cache_id,
+                     FILS_CACHE_ID_LEN) != 0)
+               return 0;
+       data->pmksa = pmksa_cache_auth_get(a->pmksa, data->spa, data->pmkid);
+       return data->pmksa != NULL;
+}
+
+
+struct rsn_pmksa_cache_entry *
+wpa_auth_pmksa_get_fils_cache_id(struct wpa_authenticator *wpa_auth,
+                                const u8 *sta_addr, const u8 *pmkid)
+{
+       struct wpa_auth_fils_iter_data idata;
+
+       if (!wpa_auth->conf.fils_cache_id_set)
+               return NULL;
+       idata.auth = wpa_auth;
+       idata.cache_id = wpa_auth->conf.fils_cache_id;
+       idata.pmksa = NULL;
+       idata.spa = sta_addr;
+       idata.pmkid = pmkid;
+       wpa_auth_for_each_auth(wpa_auth, wpa_auth_fils_iter, &idata);
+       return idata.pmksa;
+}
+
+#endif /* CONFIG_FILS */
index 0920a169dffb4742577d3f0768263a923fcb5c9b..bfca7e5c1c9bcd1f6fb16db946c4d0ce7c34fb8d 100644 (file)
@@ -187,6 +187,10 @@ struct wpa_auth_config {
        u8 ip_addr_start[4];
        u8 ip_addr_end[4];
 #endif /* CONFIG_P2P */
+#ifdef CONFIG_FILS
+       unsigned int fils_cache_id_set:1;
+       u8 fils_cache_id[FILS_CACHE_ID_LEN];
+#endif /* CONFIG_FILS */
 };
 
 typedef enum {
@@ -314,6 +318,9 @@ int wpa_auth_pmksa_add_entry(struct wpa_authenticator *wpa_auth,
 struct rsn_pmksa_cache_entry *
 wpa_auth_pmksa_get(struct wpa_authenticator *wpa_auth, const u8 *sta_addr,
                   const u8 *pmkid);
+struct rsn_pmksa_cache_entry *
+wpa_auth_pmksa_get_fils_cache_id(struct wpa_authenticator *wpa_auth,
+                                const u8 *sta_addr, const u8 *pmkid);
 void wpa_auth_pmksa_set_to_sm(struct rsn_pmksa_cache_entry *pmksa,
                              struct wpa_state_machine *sm,
                              struct wpa_authenticator *wpa_auth,
index 394f77a661a0f894c3996448e34ee179adfc54c0..969ede28ad4f13276f7e518536d3556813407a83 100644 (file)
@@ -110,6 +110,11 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf,
        os_memcpy(wconf->ip_addr_start, conf->ip_addr_start, 4);
        os_memcpy(wconf->ip_addr_end, conf->ip_addr_end, 4);
 #endif /* CONFIG_P2P */
+#ifdef CONFIG_FILS
+       wconf->fils_cache_id_set = conf->fils_cache_id_set;
+       os_memcpy(wconf->fils_cache_id, conf->fils_cache_id,
+                 FILS_CACHE_ID_LEN);
+#endif /* CONFIG_FILS */
 }