WPA: Add PTKSA cache to wpa_supplicant for PASN
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>
This commit is contained in:
parent
a4e3691616
commit
d70060f966
11 changed files with 59 additions and 2 deletions
|
@ -949,6 +949,9 @@ static int wpa_supplicant_install_ptk(struct wpa_sm *sm,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpa_sm_store_ptk(sm, sm->bssid, sm->pairwise_cipher,
|
||||||
|
sm->dot11RSNAConfigPMKLifetime, &sm->ptk);
|
||||||
|
|
||||||
/* TK is not needed anymore in supplicant */
|
/* TK is not needed anymore in supplicant */
|
||||||
os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
|
os_memset(sm->ptk.tk, 0, WPA_TK_MAX_LEN);
|
||||||
sm->ptk.tk_len = 0;
|
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;
|
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
|
/* TODO: TK could be cleared after auth frame exchange now that driver
|
||||||
* takes care of association frame encryption/decryption. */
|
* takes care of association frame encryption/decryption. */
|
||||||
/* TK is not needed anymore in supplicant */
|
/* TK is not needed anymore in supplicant */
|
||||||
|
|
|
@ -87,6 +87,8 @@ struct wpa_sm_ctx {
|
||||||
const u8 *pkt, size_t pkt_len);
|
const u8 *pkt, size_t pkt_len);
|
||||||
int (*channel_info)(void *ctx, struct wpa_channel_info *ci);
|
int (*channel_info)(void *ctx, struct wpa_channel_info *ci);
|
||||||
void (*transition_disable)(void *ctx, u8 bitmap);
|
void (*transition_disable)(void *ctx, u8 bitmap);
|
||||||
|
void (*store_ptk)(void *ctx, u8 *addr, int cipher,
|
||||||
|
u32 life_time, const struct wpa_ptk *ptk);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -449,6 +449,8 @@ static int wpa_ft_install_ptk(struct wpa_sm *sm, const u8 *bssid)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpa_sm_store_ptk(sm, sm->bssid, sm->pairwise_cipher,
|
||||||
|
sm->dot11RSNAConfigPMKLifetime, &sm->ptk);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
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 wpa_eapol_key_send(struct wpa_sm *sm, struct wpa_ptk *ptk,
|
||||||
int ver, const u8 *dest, u16 proto,
|
int ver, const u8 *dest, u16 proto,
|
||||||
|
|
|
@ -373,10 +373,12 @@ endif
|
||||||
|
|
||||||
ifdef CONFIG_PASN
|
ifdef CONFIG_PASN
|
||||||
L_CFLAGS += -DCONFIG_PASN
|
L_CFLAGS += -DCONFIG_PASN
|
||||||
|
L_CFLAGS += -DCONFIG_PTKSA_CACHE
|
||||||
NEED_HMAC_SHA256_KDF=y
|
NEED_HMAC_SHA256_KDF=y
|
||||||
NEED_HMAC_SHA384_KDF=y
|
NEED_HMAC_SHA384_KDF=y
|
||||||
NEED_SHA256=y
|
NEED_SHA256=y
|
||||||
NEED_SHA384=y
|
NEED_SHA384=y
|
||||||
|
OBJS += src/common/ptksa_cache.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_HS20
|
ifdef CONFIG_HS20
|
||||||
|
|
|
@ -392,10 +392,12 @@ endif
|
||||||
|
|
||||||
ifdef CONFIG_PASN
|
ifdef CONFIG_PASN
|
||||||
CFLAGS += -DCONFIG_PASN
|
CFLAGS += -DCONFIG_PASN
|
||||||
|
CFLAGS += -DCONFIG_PTKSA_CACHE
|
||||||
NEED_HMAC_SHA256_KDF=y
|
NEED_HMAC_SHA256_KDF=y
|
||||||
NEED_HMAC_SHA384_KDF=y
|
NEED_HMAC_SHA384_KDF=y
|
||||||
NEED_SHA256=y
|
NEED_SHA256=y
|
||||||
NEED_SHA384=y
|
NEED_SHA384=y
|
||||||
|
OBJS += ../src/common/ptksa_cache.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_HS20
|
ifdef CONFIG_HS20
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#ifdef CONFIG_DPP
|
#ifdef CONFIG_DPP
|
||||||
#include "common/dpp.h"
|
#include "common/dpp.h"
|
||||||
#endif /* CONFIG_DPP */
|
#endif /* CONFIG_DPP */
|
||||||
|
#include "common/ptksa_cache.h"
|
||||||
#include "crypto/tls.h"
|
#include "crypto/tls.h"
|
||||||
#include "ap/hostapd.h"
|
#include "ap/hostapd.h"
|
||||||
#include "eap_peer/eap.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->auto_interworking = 0;
|
||||||
wpa_s->conf->okc = 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);
|
wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
|
||||||
rsn_preauth_deinit(wpa_s->wpa);
|
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)
|
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);
|
wpa_sm_pmksa_cache_flush(wpa_s->wpa, NULL);
|
||||||
#ifdef CONFIG_AP
|
#ifdef CONFIG_AP
|
||||||
wpas_ap_pmksa_cache_flush(wpa_s);
|
wpas_ap_pmksa_cache_flush(wpa_s);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "common/ieee802_11_common.h"
|
#include "common/ieee802_11_common.h"
|
||||||
#include "common/gas_server.h"
|
#include "common/gas_server.h"
|
||||||
#include "common/dpp.h"
|
#include "common/dpp.h"
|
||||||
|
#include "common/ptksa_cache.h"
|
||||||
#include "crypto/random.h"
|
#include "crypto/random.h"
|
||||||
#include "blacklist.h"
|
#include "blacklist.h"
|
||||||
#include "wpas_glue.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)
|
if (wpa_s->wpa_state >= WPA_AUTHENTICATING)
|
||||||
wpas_connection_failed(wpa_s, bssid);
|
wpas_connection_failed(wpa_s, bssid);
|
||||||
wpa_sm_notify_disassoc(wpa_s->wpa);
|
wpa_sm_notify_disassoc(wpa_s->wpa);
|
||||||
|
ptksa_cache_flush(wpa_s->ptksa, wpa_s->bssid, WPA_CIPHER_NONE);
|
||||||
|
|
||||||
if (locally_generated)
|
if (locally_generated)
|
||||||
wpa_s->disconnect_reason = -reason_code;
|
wpa_s->disconnect_reason = -reason_code;
|
||||||
else
|
else
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "common/hw_features_common.h"
|
#include "common/hw_features_common.h"
|
||||||
#include "common/gas_server.h"
|
#include "common/gas_server.h"
|
||||||
#include "common/dpp.h"
|
#include "common/dpp.h"
|
||||||
|
#include "common/ptksa_cache.h"
|
||||||
#include "p2p/p2p.h"
|
#include "p2p/p2p.h"
|
||||||
#include "fst/fst.h"
|
#include "fst/fst.h"
|
||||||
#include "blacklist.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);
|
wmm_ac_clear_saved_tspecs(wpa_s);
|
||||||
pmksa_candidate_free(wpa_s->wpa);
|
pmksa_candidate_free(wpa_s->wpa);
|
||||||
|
ptksa_cache_deinit(wpa_s->ptksa);
|
||||||
|
wpa_s->ptksa = NULL;
|
||||||
wpa_sm_deinit(wpa_s->wpa);
|
wpa_sm_deinit(wpa_s->wpa);
|
||||||
wpa_s->wpa = NULL;
|
wpa_s->wpa = NULL;
|
||||||
wpa_blacklist_clear(wpa_s);
|
wpa_blacklist_clear(wpa_s);
|
||||||
|
|
|
@ -639,6 +639,8 @@ struct wpa_supplicant {
|
||||||
int interface_removed; /* whether the network interface has been
|
int interface_removed; /* whether the network interface has been
|
||||||
* removed */
|
* removed */
|
||||||
struct wpa_sm *wpa;
|
struct wpa_sm *wpa;
|
||||||
|
struct ptksa_cache *ptksa;
|
||||||
|
|
||||||
struct eapol_sm *eapol;
|
struct eapol_sm *eapol;
|
||||||
|
|
||||||
struct ctrl_iface_priv *ctrl_iface;
|
struct ctrl_iface_priv *ctrl_iface;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "l2_packet/l2_packet.h"
|
#include "l2_packet/l2_packet.h"
|
||||||
#include "common/wpa_common.h"
|
#include "common/wpa_common.h"
|
||||||
|
#include "common/ptksa_cache.h"
|
||||||
#include "wpa_supplicant_i.h"
|
#include "wpa_supplicant_i.h"
|
||||||
#include "driver_i.h"
|
#include "driver_i.h"
|
||||||
#include "rsn_supp/pmksa_cache.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 */
|
#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 */
|
#endif /* CONFIG_NO_WPA */
|
||||||
|
|
||||||
|
|
||||||
|
@ -1348,9 +1358,20 @@ int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_NO_WPA
|
#ifndef CONFIG_NO_WPA
|
||||||
struct wpa_sm_ctx *ctx;
|
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));
|
ctx = os_zalloc(sizeof(*ctx));
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
|
wpa_printf(MSG_ERROR, "Failed to allocate WPA context.");
|
||||||
|
|
||||||
|
ptksa_cache_deinit(wpa_s->ptksa);
|
||||||
|
wpa_s->ptksa = NULL;
|
||||||
|
|
||||||
return -1;
|
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->fils_hlp_rx = wpa_supplicant_fils_hlp_rx;
|
||||||
ctx->channel_info = wpa_supplicant_channel_info;
|
ctx->channel_info = wpa_supplicant_channel_info;
|
||||||
ctx->transition_disable = wpa_supplicant_transition_disable;
|
ctx->transition_disable = wpa_supplicant_transition_disable;
|
||||||
|
ctx->store_ptk = wpa_supplicant_store_ptk;
|
||||||
|
|
||||||
wpa_s->wpa = wpa_sm_init(ctx);
|
wpa_s->wpa = wpa_sm_init(ctx);
|
||||||
if (wpa_s->wpa == NULL) {
|
if (wpa_s->wpa == NULL) {
|
||||||
wpa_printf(MSG_ERROR, "Failed to initialize WPA state "
|
wpa_printf(MSG_ERROR,
|
||||||
"machine");
|
"Failed to initialize WPA state machine");
|
||||||
os_free(ctx);
|
os_free(ctx);
|
||||||
|
ptksa_cache_deinit(wpa_s->ptksa);
|
||||||
|
wpa_s->ptksa = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NO_WPA */
|
#endif /* CONFIG_NO_WPA */
|
||||||
|
|
Loading…
Reference in a new issue