aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIlan Peer <ilan.peer@intel.com>2020-12-16 11:01:39 (GMT)
committerJouni Malinen <j@w1.fi>2021-01-26 21:09:39 (GMT)
commitdccb6cde037f4693c835697d632c6c16beb9a4e8 (patch)
tree5c870a9e59d842b18ee8a6b31521bc3c3f3524a4 /src
parent9e7b980d6535c7d944c3d137fefef3e9b901dae0 (diff)
downloadhostap-dccb6cde037f4693c835697d632c6c16beb9a4e8.zip
hostap-dccb6cde037f4693c835697d632c6c16beb9a4e8.tar.gz
hostap-dccb6cde037f4693c835697d632c6c16beb9a4e8.tar.bz2
WPA: Support deriving KDK based on capabilities
Derive the KDK as part of PMK to PTK derivation if forced by configuration or in case both the local station and the AP declare support for secure LTF. Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/rsn_supp/wpa.c27
-rw-r--r--src/rsn_supp/wpa.h2
-rw-r--r--src/rsn_supp/wpa_ft.c22
-rw-r--r--src/rsn_supp/wpa_i.h4
4 files changed, 42 insertions, 13 deletions
diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c
index 9ef0731..e1aba36 100644
--- a/src/rsn_supp/wpa.c
+++ b/src/rsn_supp/wpa.c
@@ -579,7 +579,7 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
const struct wpa_eapol_key *key, struct wpa_ptk *ptk)
{
const u8 *z = NULL;
- size_t z_len = 0;
+ size_t z_len = 0, kdk_len;
int akmp;
#ifdef CONFIG_IEEE80211R
@@ -603,11 +603,19 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr,
akmp |= WPA_KEY_MGMT_PSK_SHA256;
}
#endif /* CONFIG_OWE */
+
+ if (sm->force_kdk_derivation ||
+ (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
+ sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
+ kdk_len = WPA_KDK_MAX_LEN;
+ else
+ kdk_len = 0;
+
return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
sm->own_addr, sm->bssid, sm->snonce,
key->key_nonce, ptk, akmp,
sm->pairwise_cipher, z, z_len,
- sm->kdk ? WPA_KDK_MAX_LEN : 0);
+ kdk_len);
}
@@ -3188,7 +3196,7 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
sm->p2p = config->p2p;
sm->wpa_rsc_relaxation = config->wpa_rsc_relaxation;
sm->owe_ptk_workaround = config->owe_ptk_workaround;
- sm->kdk = config->kdk;
+ sm->force_kdk_derivation = config->force_kdk_derivation;
#ifdef CONFIG_FILS
if (config->fils_cache_id) {
sm->fils_cache_id_set = 1;
@@ -3211,7 +3219,7 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config)
sm->wpa_rsc_relaxation = 0;
sm->owe_ptk_workaround = 0;
sm->beacon_prot = 0;
- sm->kdk = false;
+ sm->force_kdk_derivation = false;
}
}
@@ -4134,7 +4142,7 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
const u8 *g_sta = NULL;
size_t g_sta_len = 0;
const u8 *g_ap = NULL;
- size_t g_ap_len = 0;
+ size_t g_ap_len = 0, kdk_len;
struct wpabuf *pub = NULL;
os_memcpy(sm->bssid, bssid, ETH_ALEN);
@@ -4362,6 +4370,13 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
goto fail;
}
+ if (sm->force_kdk_derivation ||
+ (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
+ sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
+ kdk_len = WPA_KDK_MAX_LEN;
+ else
+ kdk_len = 0;
+
if (fils_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid,
sm->fils_nonce, sm->fils_anonce,
dh_ss ? wpabuf_head(dh_ss) : NULL,
@@ -4369,7 +4384,7 @@ int fils_process_auth(struct wpa_sm *sm, const u8 *bssid, const u8 *data,
&sm->ptk, ick, &ick_len,
sm->key_mgmt, sm->pairwise_cipher,
sm->fils_ft, &sm->fils_ft_len,
- sm->kdk ? WPA_KDK_MAX_LEN : 0) < 0) {
+ kdk_len) < 0) {
wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK");
goto fail;
}
diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h
index 9f0861c..8e4533e 100644
--- a/src/rsn_supp/wpa.h
+++ b/src/rsn_supp/wpa.h
@@ -132,7 +132,7 @@ struct rsn_supp_config {
int owe_ptk_workaround;
const u8 *fils_cache_id;
int beacon_prot;
- bool kdk;
+ bool force_kdk_derivation;
};
#ifndef CONFIG_NO_WPA
diff --git a/src/rsn_supp/wpa_ft.c b/src/rsn_supp/wpa_ft.c
index 28985f2..c26f1a5 100644
--- a/src/rsn_supp/wpa_ft.c
+++ b/src/rsn_supp/wpa_ft.c
@@ -40,7 +40,7 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
const u8 *anonce = key->key_nonce;
int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
const u8 *mpmk;
- size_t mpmk_len;
+ size_t mpmk_len, kdk_len;
if (sm->xxkey_len > 0) {
mpmk = sm->xxkey;
@@ -68,10 +68,17 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
wpa_ft_pasn_store_r1kh(sm, src_addr);
+ if (sm->force_kdk_derivation ||
+ (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
+ sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
+ kdk_len = WPA_KDK_MAX_LEN;
+ else
+ kdk_len = 0;
+
return wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce, anonce,
sm->own_addr, sm->bssid, sm->pmk_r1_name, ptk,
ptk_name, sm->key_mgmt, sm->pairwise_cipher,
- sm->kdk ? WPA_KDK_MAX_LEN : 0);
+ kdk_len);
}
@@ -539,7 +546,7 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
int ret;
const u8 *bssid;
const u8 *kck;
- size_t kck_len;
+ size_t kck_len, kdk_len;
int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
const u8 *anonce, *snonce;
@@ -664,11 +671,18 @@ int wpa_ft_process_response(struct wpa_sm *sm, const u8 *ies, size_t ies_len,
wpa_ft_pasn_store_r1kh(sm, bssid);
+ if (sm->force_kdk_derivation ||
+ (sm->secure_ltf && sm->ap_rsnxe && sm->ap_rsnxe_len >= 4 &&
+ sm->ap_rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8)))
+ kdk_len = WPA_KDK_MAX_LEN;
+ else
+ kdk_len = 0;
+
if (wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce,
anonce, sm->own_addr, bssid,
sm->pmk_r1_name, &sm->ptk, ptk_name, sm->key_mgmt,
sm->pairwise_cipher,
- sm->kdk ? WPA_KDK_MAX_LEN : 0) < 0)
+ kdk_len) < 0)
return -1;
if (wpa_key_mgmt_fils(sm->key_mgmt)) {
diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h
index 16f089c..1dc9639 100644
--- a/src/rsn_supp/wpa_i.h
+++ b/src/rsn_supp/wpa_i.h
@@ -80,9 +80,9 @@ struct wpa_sm {
/*
* If set Key Derivation Key should be derived as part of PMK to
- * PTK derivation.
+ * PTK derivation regardless of advertised capabilities.
*/
- bool kdk;
+ bool force_kdk_derivation;
u8 own_addr[ETH_ALEN];
const char *ifname;