diff mbox series

[23/40] WPA_AUTH: Add PTKSA cache to hostapd

Message ID 20191215093438.10120-24-ilan.peer@intel.com
State Changes Requested
Headers show
Series Support for Pre association Security Negotiation (PASN) | expand

Commit Message

Peer, Ilan Dec. 15, 2019, 9:34 a.m. UTC
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
---
 hostapd/Makefile       |  2 ++
 hostapd/ctrl_iface.c   |  4 ++++
 src/ap/hostapd.h       |  3 +++
 src/ap/wpa_auth.c      | 30 ++++++++++++++++++++++++++++++
 src/ap/wpa_auth.h      |  3 +++
 src/ap/wpa_auth_glue.c | 34 ++++++++++++++++++++++++++++++++++
 6 files changed, 76 insertions(+)
diff mbox series

Patch

diff --git a/hostapd/Makefile b/hostapd/Makefile
index a3a5235c99..3e3d4721f5 100644
--- a/hostapd/Makefile
+++ b/hostapd/Makefile
@@ -589,10 +589,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
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 8692284d12..14f891e81c 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -3408,6 +3408,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;
diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h
index 2358d1664e..f5a7a5b658 100644
--- a/src/ap/hostapd.h
+++ b/src/ap/hostapd.h
@@ -17,6 +17,7 @@ 
 #include "utils/list.h"
 #include "ap_config.h"
 #include "drivers/driver.h"
+#include "common/ptksa_cache.h"
 
 #define OCE_STA_CFON_ENABLED(hapd) \
 	((hapd->conf->oce & OCE_STA_CFON) && \
@@ -356,6 +357,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;
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 28b23d4d8a..5c5ce7f756 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -196,6 +196,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, 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)
 {
@@ -1713,6 +1730,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))
 		wpa_printf(MSG_DEBUG,
@@ -2754,6 +2774,12 @@  int fils_set_tk(struct wpa_state_machine *sm)
 		wpa_printf(MSG_DEBUG, "FILS: Failed to set TK to the driver");
 		return -1;
 	}
+
+	wpa_auth_store_ptksa(sm->wpa_auth, sm->addr,
+			     sm->pairwise,
+			     dot11RSNAConfigPMKLifetime,
+			     &sm->PTK);
+
 	sm->tk_already_set = TRUE;
 
 	return 0;
@@ -3384,6 +3410,10 @@  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 ||
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index 0576bbfba2..ed5bd9bd8e 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -282,6 +282,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,
+			    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 (*set_vlan)(void *ctx, const u8 *sta_addr,
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index 97de7d9b0a..86b06a5282 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -806,6 +806,26 @@  static int hostapd_channel_info(void *ctx, struct wpa_channel_info *ci)
 	return hostapd_drv_channel_info(hapd, ci);
 }
 
+#ifdef CONFIG_PASN
+
+static void hostapd_store_ptksa(void *ctx, const u8 *addr,int cipher,
+				u32 life_time, 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)
 {
@@ -1298,6 +1318,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 */
@@ -1348,6 +1373,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)) {
@@ -1389,6 +1420,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);