From f2f8e4f45830e9da3d95e47be2b3e48a56c54eba Mon Sep 17 00:00:00 2001 From: Ilan Peer Date: Wed, 16 Dec 2020 13:00:31 +0200 Subject: [PATCH] Add PTKSA cache to hostapd Signed-off-by: Ilan Peer --- hostapd/Android.mk | 2 ++ hostapd/Makefile | 2 ++ hostapd/ctrl_iface.c | 5 +++++ src/ap/hostapd.h | 2 ++ src/ap/wpa_auth.c | 25 +++++++++++++++++++++++++ src/ap/wpa_auth.h | 3 +++ src/ap/wpa_auth_glue.c | 36 ++++++++++++++++++++++++++++++++++++ 7 files changed, 75 insertions(+) diff --git a/hostapd/Android.mk b/hostapd/Android.mk index 54fafe180..b3af96886 100644 --- a/hostapd/Android.mk +++ b/hostapd/Android.mk @@ -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 diff --git a/hostapd/Makefile b/hostapd/Makefile index cfd6495c4..ac085fd10 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -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 diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 7af4f095a..ba7cc2935 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -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; diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index 4ce31416d..0eff47e1a 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -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; diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index dbba41d31..e6dfb34d1 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -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 || diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 5dc3cc5c6..0f91e3ee5 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -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); diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index a829361b5..c31961e05 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -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);