PASN requires to store the PTK derived during PASN authentication so it can later be used for secure LTF etc. This is also true for a PTK derived during regular connection. Add an instance of a PTKSA cache for each wpa_supplicant interface when PASN is enabled in build configuration. Signed-off-by: Ilan Peer <ilan.peer@xxxxxxxxx> --- src/rsn_supp/wpa.c | 6 ++++++ src/rsn_supp/wpa.h | 2 ++ src/rsn_supp/wpa_ft.c | 2 ++ src/rsn_supp/wpa_i.h | 8 ++++++++ wpa_supplicant/Makefile | 2 ++ wpa_supplicant/ctrl_iface.c | 3 +++ wpa_supplicant/events.c | 3 +++ wpa_supplicant/wpa_supplicant.c | 3 +++ wpa_supplicant/wpa_supplicant_i.h | 2 ++ wpa_supplicant/wpas_glue.c | 29 ++++++++++++++++++++++++++--- 10 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index c9ed784765..0781676bde 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -870,6 +870,9 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm, return -1; } + wpa_sm_store_ptk(sm, sm->bssid, sm->pairwise_cipher, + sm->dot11RSNAConfigPMKLifetime, &sm->ptk); + /* TK is not needed anymore in supplicant */ os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN); sm->ptk.tk_len = 0; @@ -4702,6 +4705,9 @@ int fils_process_assoc_resp(struct wpa_sm *sm, const u8 *resp, size_t len) goto fail; } + wpa_sm_store_ptk(sm, sm->bssid, sm->pairwise_cipher, + sm->dot11RSNAConfigPMKLifetime, &sm->ptk); + /* TODO: TK could be cleared after auth frame exchange now that driver * takes care of association frame encryption/decryption. */ /* TK is not needed anymore in supplicant */ diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 07e4072dec..30e7fad83c 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -85,6 +85,8 @@ struct wpa_sm_ctx { void (*fils_hlp_rx)(void *ctx, const u8 *dst, const u8 *src, const u8 *pkt, size_t pkt_len); int (*channel_info)(void *ctx, struct wpa_channel_info *ci); + void (*store_ptk)(void *ctx, u8 *addr, int cipher, + u32 life_time, struct wpa_ptk *ptk); }; diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c index 42b85147df..027a24ffcd 100644 --- a/src/rsn_supp/wpa_ft.c +++ b/src/rsn_supp/wpa_ft.c @@ -430,6 +430,8 @@ static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid) return -1; } + wpa_sm_store_ptk(sm, sm->bssid, sm->pairwise_cipher, + sm->dot11RSNAConfigPMKLifetime, &sm->ptk); return 0; } diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index f06dbd6ba4..b9164fa111 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -428,6 +428,14 @@ static inline int wpa_sm_channel_info(struct wpa_sm *sm, return sm->ctx->channel_info(sm->ctx->ctx, ci); } +static inline void wpa_sm_store_ptk(struct wpa_sm *sm, + u8 *addr, int cipher, + u32 life_time, struct wpa_ptk *ptk) +{ + if (sm->ctx->store_ptk) + sm->ctx->store_ptk(sm->ctx->ctx, addr, cipher, life_time, + ptk); +} int wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk, int ver, const u8 *dest, u16 proto, diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile index d40804d528..30c31bd18f 100644 --- a/wpa_supplicant/Makefile +++ b/wpa_supplicant/Makefile @@ -392,6 +392,8 @@ NEED_HMAC_SHA256_KDF=y NEED_HMAC_SHA384_KDF=y NEED_SHA256=y NEED_SHA384=y +OBJS += ../src/common/ptksa_cache.o +CFLAGS += -DCONFIG_PTKSA_CACHE endif ifdef CONFIG_WIFI_DISPLAY diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 10c0961297..b9a0d206e9 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -56,6 +56,7 @@ #include "mesh.h" #include "dpp_supplicant.h" #include "sme.h" +#include "common/ptksa_cache.h" #ifdef __NetBSD__ #include <net/if_ether.h> @@ -8130,6 +8131,7 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) wpa_s->conf->auto_interworking = 0; wpa_s->conf->okc = 0; + ptksa_cache_flush(wpa_s->ptksa, NULL, WPA_CIPHER_NONE); wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL); rsn_preauth_deinit(wpa_s->wpa); @@ -9783,6 +9785,7 @@ static int wpas_ctrl_iface_pmksa(struct wpa_supplicant *wpa_s, static void wpas_ctrl_iface_pmksa_flush(struct wpa_supplicant *wpa_s) { + ptksa_cache_flush(wpa_s->ptksa, NULL, WPA_CIPHER_NONE); wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL); #ifdef CONFIG_AP wpas_ap_pmksa_cache_flush(wpa_s); diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 2851ffc810..5b09ec54e4 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -49,6 +49,7 @@ #include "mesh_mpm.h" #include "wmm_ac.h" #include "dpp_supplicant.h" +#include "common/ptksa_cache.h" #define MAX_OWE_TRANSITION_BSS_SELECT_COUNT 5 @@ -3289,6 +3290,8 @@ static void wpa_supplicant_event_disassoc_finish(struct wpa_supplicant *wpa_s, if (wpa_s->wpa_state >= WPA_AUTHENTICATING) wpas_connection_failed(wpa_s, bssid); wpa_sm_notify_disassoc(wpa_s->wpa); + ptksa_cache_flush(wpa_s->ptksa, wpa_s->bssid, WPA_CIPHER_NONE); + if (locally_generated) wpa_s->disconnect_reason = -reason_code; else diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 634fb290e0..d357633e63 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -63,6 +63,7 @@ #include "wpas_kay.h" #include "mesh.h" #include "dpp_supplicant.h" +#include "common/ptksa_cache.h" #ifdef CONFIG_MESH #include "ap/ap_config.h" #include "ap/hostapd.h" @@ -565,6 +566,8 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) wmm_ac_clear_saved_tspecs(wpa_s); pmksa_candidate_free(wpa_s->wpa); + ptksa_cache_deinit(wpa_s->ptksa); + wpa_s->ptksa = NULL; wpa_sm_deinit(wpa_s->wpa); wpa_s->wpa = NULL; wpa_blacklist_clear(wpa_s); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index de2e6350b8..f4ffba2934 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -615,6 +615,8 @@ struct wpa_supplicant { int interface_removed; /* whether the network interface has been * removed */ struct wpa_sm *wpa; + struct ptksa_cache *ptksa; + struct eapol_sm *eapol; struct ctrl_iface_priv *ctrl_iface; diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 29257b9873..eee365748b 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -28,7 +28,7 @@ #include "scan.h" #include "notify.h" #include "wpas_kay.h" - +#include "common/ptksa_cache.h" #ifndef CONFIG_NO_CONFIG_BLOBS #if defined(IEEE8021X_EAPOL) || !defined(CONFIG_NO_WPA) @@ -1225,6 +1225,15 @@ static int wpa_supplicant_channel_info(void *_wpa_s, return wpa_drv_channel_info(wpa_s, ci); } + +static void wpa_supplicant_store_ptk(void *ctx, u8 *addr, int cipher, + u32 life_time, struct wpa_ptk *ptk) +{ + struct wpa_supplicant *wpa_s = ctx; + + ptksa_cache_add(wpa_s->ptksa, addr, cipher, life_time, ptk); +} + #endif /* CONFIG_NO_WPA */ @@ -1232,9 +1241,20 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) { #ifndef CONFIG_NO_WPA struct wpa_sm_ctx *ctx; + + wpa_s->ptksa = ptksa_cache_init(); + if (!wpa_s->ptksa) { + wpa_printf(MSG_ERROR, "Failed to allocate PTKSA"); + return -1; + } + ctx = os_zalloc(sizeof(*ctx)); if (ctx == NULL) { wpa_printf(MSG_ERROR, "Failed to allocate WPA context."); + + ptksa_cache_deinit(wpa_s->ptksa); + wpa_s->ptksa = NULL; + return -1; } @@ -1277,12 +1297,15 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s) ctx->key_mgmt_set_pmk = wpa_supplicant_key_mgmt_set_pmk; ctx->fils_hlp_rx = wpa_supplicant_fils_hlp_rx; ctx->channel_info = wpa_supplicant_channel_info; + ctx->store_ptk = wpa_supplicant_store_ptk; wpa_s->wpa = wpa_sm_init(ctx); if (wpa_s->wpa == NULL) { - wpa_printf(MSG_ERROR, "Failed to initialize WPA state " - "machine"); + wpa_printf(MSG_ERROR, + "Failed to initialize WPA state machine"); os_free(ctx); + ptksa_cache_deinit(wpa_s->ptksa); + wpa_s->ptksa = NULL; return -1; } #endif /* CONFIG_NO_WPA */ -- 2.17.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap