]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Add PTKSA cache to hostapd
authorIlan Peer <ilan.peer@intel.com>
Wed, 16 Dec 2020 11:00:31 +0000 (13:00 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 25 Jan 2021 17:15:47 +0000 (19:15 +0200)
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
hostapd/Android.mk
hostapd/Makefile
hostapd/ctrl_iface.c
src/ap/hostapd.h
src/ap/wpa_auth.c
src/ap/wpa_auth.h
src/ap/wpa_auth_glue.c

index 54fafe1803b9a39f5fe659da8f8eb7e3953fbcb2..b3af96886996fbd4e33bac76329d4e3e9a36264d 100644 (file)
@@ -567,10 +567,12 @@ endif
 
 ifdef CONFIG_PASN
 L_CFLAGS += -DCONFIG_PASN
+L_CFLAGS += -DCONFIG_PTKSA_CACHE
 NEED_HMAC_SHA256_KDF=y
 NEED_HMAC_SHA384_KDF=y
 NEED_SHA256=y
 NEED_SHA384=y
+OBJS += src/common/ptksa_cache.c
 endif
 
 ifdef CONFIG_EAP_IKEV2
index cfd6495c488a6a792eaf2d21b2cad8e50534ba13..ac085fd1052016bc58194cd3a51b8b5bdf9c508b 100644 (file)
@@ -597,10 +597,12 @@ endif
 
 ifdef CONFIG_PASN
 CFLAGS += -DCONFIG_PASN
+CFLAGS += -DCONFIG_PTKSA_CACHE
 NEED_HMAC_SHA256_KDF=y
 NEED_HMAC_SHA384_KDF=y
 NEED_SHA256=y
 NEED_SHA384=y
+OBJS += ../src/common/ptksa_cache.o
 endif
 
 ifdef CONFIG_EAP_IKEV2
index 7af4f095a368ecaec965603f988423e2ee7a876a..ba7cc29351c22f28d6af30ca24b27f038aeb8c78 100644 (file)
@@ -37,6 +37,7 @@
 #include "common/dpp.h"
 #endif /* CONFIG_DPP */
 #include "common/wpa_ctrl.h"
+#include "common/ptksa_cache.h"
 #include "crypto/tls.h"
 #include "drivers/driver.h"
 #include "eapol_auth/eapol_auth_sm.h"
@@ -3810,6 +3811,10 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
        } else if (os_strncmp(buf, "GET_CAPABILITY ", 15) == 0) {
                reply_len = hostapd_ctrl_iface_get_capability(
                        hapd, buf + 15, reply, reply_size);
+#ifdef CONFIG_PASN
+       } else if (os_strcmp(buf, "PTKSA_CACHE_LIST") == 0) {
+               reply_len = ptksa_cache_list(hapd->ptksa, reply, reply_size);
+#endif /* CONFIG_PASN */
        } else {
                os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
                reply_len = 16;
index 4ce31416deb7a9bcb8e79e3c1c3873a0903f4a1e..0eff47e1ab083ff49c46732b4134e67a5d8c43d0 100644 (file)
@@ -370,6 +370,8 @@ struct hostapd_data {
 
        int dhcp_sock; /* UDP socket used with the DHCP server */
 
+       struct ptksa_cache *ptksa;
+
 #ifdef CONFIG_DPP
        int dpp_init_done;
        struct dpp_authentication *dpp_auth;
index dbba41d31a5d9401e050a30f85aeb4b5dedcd04a..e6dfb34d11c468100c110696bb5ad277d0089b4f 100644 (file)
@@ -224,6 +224,23 @@ int wpa_auth_for_each_auth(struct wpa_authenticator *wpa_auth,
 }
 
 
+void wpa_auth_store_ptksa(struct wpa_authenticator *wpa_auth,
+                         const u8 *addr, int cipher,
+                         u32 life_time, const struct wpa_ptk *ptk)
+{
+       if (wpa_auth->cb->store_ptksa)
+               wpa_auth->cb->store_ptksa(wpa_auth->cb_ctx, addr, cipher,
+                                         life_time, ptk);
+}
+
+
+void wpa_auth_remove_ptksa(struct wpa_authenticator *wpa_auth,
+                          const u8 *addr, int cipher)
+{
+       if (wpa_auth->cb->clear_ptksa)
+               wpa_auth->cb->clear_ptksa(wpa_auth->cb_ctx, addr, cipher);
+}
+
 void wpa_auth_logger(struct wpa_authenticator *wpa_auth, const u8 *addr,
                     logger_level level, const char *txt)
 {
@@ -1739,6 +1756,9 @@ void wpa_remove_ptk(struct wpa_state_machine *sm)
 {
        sm->PTK_valid = false;
        os_memset(&sm->PTK, 0, sizeof(sm->PTK));
+
+       wpa_auth_remove_ptksa(sm->wpa_auth, sm->addr, sm->pairwise);
+
        if (wpa_auth_set_key(sm->wpa_auth, 0, WPA_ALG_NONE, sm->addr, 0, NULL,
                             0, KEY_FLAG_PAIRWISE))
                wpa_printf(MSG_DEBUG,
@@ -2823,6 +2843,9 @@ int fils_set_tk(struct wpa_state_machine *sm)
        }
        sm->tk_already_set = true;
 
+       wpa_auth_store_ptksa(sm->wpa_auth, sm->addr, sm->pairwise,
+                            dot11RSNAConfigPMKLifetime, &sm->PTK);
+
        return 0;
 }
 
@@ -3611,6 +3634,8 @@ SM_STATE(WPA_PTK, PTKINITDONE)
                sm->pairwise_set = true;
 
                wpa_auth_set_ptk_rekey_timer(sm);
+               wpa_auth_store_ptksa(sm->wpa_auth, sm->addr, sm->pairwise,
+                                    dot11RSNAConfigPMKLifetime, &sm->PTK);
 
                if (wpa_key_mgmt_wpa_psk(sm->wpa_key_mgmt) ||
                    sm->wpa_key_mgmt == WPA_KEY_MGMT_DPP ||
index 5dc3cc5c6d30aa9348fcdfb34383187b10dfb94c..0f91e3ee5ee38dd0e1422baad845648012f41f5b 100644 (file)
@@ -312,6 +312,9 @@ struct wpa_auth_callbacks {
        int (*get_sta_tx_params)(void *ctx, const u8 *addr,
                                 int ap_max_chanwidth, int ap_seg1_idx,
                                 int *bandwidth, int *seg1_idx);
+       void (*store_ptksa)(void *ctx, const u8 *addr, int cipher,
+                           u32 life_time, const struct wpa_ptk *ptk);
+       void (*clear_ptksa)(void *ctx, const u8 *addr, int cipher);
 #ifdef CONFIG_IEEE80211R_AP
        struct wpa_state_machine * (*add_sta)(void *ctx, const u8 *sta_addr);
        int (*add_sta_ft)(void *ctx, const u8 *sta_addr);
index a829361b5853e6f5971fe5815b72b237f28351e7..c31961e052ce2fe2c2c557eea096136d023088be 100644 (file)
@@ -14,6 +14,7 @@
 #include "common/ieee802_11_defs.h"
 #include "common/sae.h"
 #include "common/wpa_ctrl.h"
+#include "common/ptksa_cache.h"
 #include "crypto/sha1.h"
 #include "eapol_auth/eapol_auth_sm.h"
 #include "eapol_auth/eapol_auth_sm_i.h"
@@ -917,6 +918,27 @@ static int hostapd_channel_info(void *ctx, struct wpa_channel_info *ci)
 }
 
 
+#ifdef CONFIG_PASN
+
+static void hostapd_store_ptksa(void *ctx, const u8 *addr,int cipher,
+                               u32 life_time, const struct wpa_ptk *ptk)
+{
+       struct hostapd_data *hapd = ctx;
+
+       ptksa_cache_add(hapd->ptksa, addr, cipher, life_time, ptk);
+}
+
+
+static void hostapd_clear_ptksa(void *ctx, const u8 *addr, int cipher)
+{
+       struct hostapd_data *hapd = ctx;
+
+       ptksa_cache_flush(hapd->ptksa, addr, cipher);
+}
+
+#endif /* CONFIG_PASN */
+
+
 static int hostapd_wpa_auth_update_vlan(void *ctx, const u8 *addr, int vlan_id)
 {
 #ifndef CONFIG_NO_VLAN
@@ -1442,6 +1464,11 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
                .send_oui = hostapd_wpa_auth_send_oui,
                .channel_info = hostapd_channel_info,
                .update_vlan = hostapd_wpa_auth_update_vlan,
+#ifdef CONFIG_PASN
+               .store_ptksa = hostapd_store_ptksa,
+               .clear_ptksa = hostapd_clear_ptksa,
+#endif /* CONFIG_PASN */
+
 #ifdef CONFIG_OCV
                .get_sta_tx_params = hostapd_get_sta_tx_params,
 #endif /* CONFIG_OCV */
@@ -1510,6 +1537,12 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
                return -1;
        }
 
+       hapd->ptksa = ptksa_cache_init();
+       if (!hapd->ptksa) {
+               wpa_printf(MSG_ERROR, "Failed to allocate PTKSA cache");
+               return -1;
+       }
+
 #ifdef CONFIG_IEEE80211R_AP
        if (!hostapd_drv_none(hapd) &&
            wpa_key_mgmt_ft(hapd->conf->wpa_key_mgmt)) {
@@ -1549,6 +1582,9 @@ void hostapd_reconfig_wpa(struct hostapd_data *hapd)
 void hostapd_deinit_wpa(struct hostapd_data *hapd)
 {
        ieee80211_tkip_countermeasures_deinit(hapd);
+       ptksa_cache_deinit(hapd->ptksa);
+       hapd->ptksa = NULL;
+
        rsn_preauth_iface_deinit(hapd);
        if (hapd->wpa_auth) {
                wpa_deinit(hapd->wpa_auth);