aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2017-02-21 10:18:58 (GMT)
committerJouni Malinen <j@w1.fi>2017-02-21 10:18:58 (GMT)
commit7eace3787c0659bda640a4a7ea4ca6fe4b5c4e8f (patch)
treecc30ee67f25938fd206656dee251e6a3cd660b5b
parent128f6a98b3d4d6ed103db759707309f451db9682 (diff)
downloadhostap-7eace3787c0659bda640a4a7ea4ca6fe4b5c4e8f.zip
hostap-7eace3787c0659bda640a4a7ea4ca6fe4b5c4e8f.tar.gz
hostap-7eace3787c0659bda640a4a7ea4ca6fe4b5c4e8f.tar.bz2
FILS: Find PMKSA cache entries on AP based on FILS Cache Identifier
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>
-rw-r--r--src/ap/ieee802_11.c5
-rw-r--r--src/ap/wpa_auth.c44
-rw-r--r--src/ap/wpa_auth.h7
-rw-r--r--src/ap/wpa_auth_glue.c5
4 files changed, 61 insertions, 0 deletions
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index e1a6712..7369966 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -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--;
}
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 7b26c04..a3df81b 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -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 */
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index 0920a16..bfca7e5 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -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,
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index 394f77a..969ede2 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -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 */
}