]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WPA: Add PTKSA cache to wpa_supplicant for PASN
authorIlan Peer <ilan.peer@intel.com>
Wed, 16 Dec 2020 11:00:27 +0000 (13:00 +0200)
committerJouni Malinen <j@w1.fi>
Mon, 25 Jan 2021 16:36:40 +0000 (18:36 +0200)
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@intel.com>
src/rsn_supp/wpa.c
src/rsn_supp/wpa.h
src/rsn_supp/wpa_ft.c
src/rsn_supp/wpa_i.h
wpa_supplicant/Android.mk
wpa_supplicant/Makefile
wpa_supplicant/ctrl_iface.c
wpa_supplicant/events.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h
wpa_supplicant/wpas_glue.c

index 0f348b04c5d795d07cc6b6636b016dc52b4a198e..0d79f3aceb767a6fedceb15353f464935ef95216 100644 (file)
@@ -949,6 +949,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;
@@ -4916,6 +4919,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 */
index 80531eb513f17bcf33f64c29966f9d701864acfe..9f5164df0cba3a258af2c80d5f7c1b1c0ecc1013 100644 (file)
@@ -87,6 +87,8 @@ struct wpa_sm_ctx {
                            const u8 *pkt, size_t pkt_len);
        int (*channel_info)(void *ctx, struct wpa_channel_info *ci);
        void (*transition_disable)(void *ctx, u8 bitmap);
+       void (*store_ptk)(void *ctx, u8 *addr, int cipher,
+                         u32 life_time, const struct wpa_ptk *ptk);
 };
 
 
index 6ca9cb7ce704a5183fcdc8ac92d89cf51ebc18e7..7fa47a1e5a04be3584ee438a3a12cfa1d81b1f0f 100644 (file)
@@ -449,6 +449,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;
 }
 
index 1ac453c7769472d3e1984cfbb6fb9ffabd40c26d..728280e3b01dbef2840324e05ba3b0026b6ba3ca 100644 (file)
@@ -447,6 +447,14 @@ static inline void wpa_sm_transition_disable(struct wpa_sm *sm, u8 bitmap)
                sm->ctx->transition_disable(sm->ctx->ctx, bitmap);
 }
 
+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,
index 302cd1954aeb9e58538e81cbf75bf7ce14f74ed1..33527942801b0791ab7815e15ef5a7ad5fe0b468 100644 (file)
@@ -373,10 +373,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_HS20
index dcb3322234b5bb36757190af8b326404cfbe7275..bb18d821cb90e0977eced2906fd5f1c9e32bd7e3 100644 (file)
@@ -392,10 +392,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_HS20
index e63c3f7df8ccf9bcc18b2dd84b6e16e8ce646478..10743745b5974b724adc1da7a46e8d2ae19759ce 100644 (file)
@@ -22,6 +22,7 @@
 #ifdef CONFIG_DPP
 #include "common/dpp.h"
 #endif /* CONFIG_DPP */
+#include "common/ptksa_cache.h"
 #include "crypto/tls.h"
 #include "ap/hostapd.h"
 #include "eap_peer/eap.h"
@@ -8431,6 +8432,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);
 
@@ -10108,6 +10110,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);
index d9ecbefc0ba9ec225d8df57e584eaa064c66631f..7db90646112201631cfd66636913622de3cfbbd9 100644 (file)
@@ -30,6 +30,7 @@
 #include "common/ieee802_11_common.h"
 #include "common/gas_server.h"
 #include "common/dpp.h"
+#include "common/ptksa_cache.h"
 #include "crypto/random.h"
 #include "blacklist.h"
 #include "wpas_glue.h"
@@ -3482,6 +3483,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
index 9f474fd0d8516ce0732f315c100263994b19ec29..1ba35c3c25e3ac3edd618406153873f90d5085b9 100644 (file)
@@ -41,6 +41,7 @@
 #include "common/hw_features_common.h"
 #include "common/gas_server.h"
 #include "common/dpp.h"
+#include "common/ptksa_cache.h"
 #include "p2p/p2p.h"
 #include "fst/fst.h"
 #include "blacklist.h"
@@ -573,6 +574,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);
index 51fa00702513af68e0838acfd94ae3438c9fb4a2..09f6a7b4a804ea4397fb3832dfdc7d3571956bf8 100644 (file)
@@ -639,6 +639,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;
index 6cee1e7909d05416408af5ca1557b47f109c8e2a..b914d2974b4340eec1888b8c8ec1ef5e9e27ab10 100644 (file)
@@ -16,6 +16,7 @@
 #include "config.h"
 #include "l2_packet/l2_packet.h"
 #include "common/wpa_common.h"
+#include "common/ptksa_cache.h"
 #include "wpa_supplicant_i.h"
 #include "driver_i.h"
 #include "rsn_supp/pmksa_cache.h"
@@ -1341,6 +1342,15 @@ static void wpa_supplicant_transition_disable(void *_wpa_s, u8 bitmap)
 #endif /* CONFIG_NO_CONFIG_WRITE */
 }
 
+
+static void wpa_supplicant_store_ptk(void *ctx, u8 *addr, int cipher,
+                                    u32 life_time, const 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 */
 
 
@@ -1348,9 +1358,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;
        }
 
@@ -1394,12 +1415,15 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
        ctx->fils_hlp_rx = wpa_supplicant_fils_hlp_rx;
        ctx->channel_info = wpa_supplicant_channel_info;
        ctx->transition_disable = wpa_supplicant_transition_disable;
+       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 */