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>
This commit is contained in:
parent
9e7b980d65
commit
dccb6cde03
5 changed files with 43 additions and 14 deletions
|
@ -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 struct wpa_eapol_key *key, struct wpa_ptk *ptk)
|
||||||
{
|
{
|
||||||
const u8 *z = NULL;
|
const u8 *z = NULL;
|
||||||
size_t z_len = 0;
|
size_t z_len = 0, kdk_len;
|
||||||
int akmp;
|
int akmp;
|
||||||
|
|
||||||
#ifdef CONFIG_IEEE80211R
|
#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;
|
akmp |= WPA_KEY_MGMT_PSK_SHA256;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_OWE */
|
#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",
|
return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion",
|
||||||
sm->own_addr, sm->bssid, sm->snonce,
|
sm->own_addr, sm->bssid, sm->snonce,
|
||||||
key->key_nonce, ptk, akmp,
|
key->key_nonce, ptk, akmp,
|
||||||
sm->pairwise_cipher, z, z_len,
|
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->p2p = config->p2p;
|
||||||
sm->wpa_rsc_relaxation = config->wpa_rsc_relaxation;
|
sm->wpa_rsc_relaxation = config->wpa_rsc_relaxation;
|
||||||
sm->owe_ptk_workaround = config->owe_ptk_workaround;
|
sm->owe_ptk_workaround = config->owe_ptk_workaround;
|
||||||
sm->kdk = config->kdk;
|
sm->force_kdk_derivation = config->force_kdk_derivation;
|
||||||
#ifdef CONFIG_FILS
|
#ifdef CONFIG_FILS
|
||||||
if (config->fils_cache_id) {
|
if (config->fils_cache_id) {
|
||||||
sm->fils_cache_id_set = 1;
|
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->wpa_rsc_relaxation = 0;
|
||||||
sm->owe_ptk_workaround = 0;
|
sm->owe_ptk_workaround = 0;
|
||||||
sm->beacon_prot = 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;
|
const u8 *g_sta = NULL;
|
||||||
size_t g_sta_len = 0;
|
size_t g_sta_len = 0;
|
||||||
const u8 *g_ap = NULL;
|
const u8 *g_ap = NULL;
|
||||||
size_t g_ap_len = 0;
|
size_t g_ap_len = 0, kdk_len;
|
||||||
struct wpabuf *pub = NULL;
|
struct wpabuf *pub = NULL;
|
||||||
|
|
||||||
os_memcpy(sm->bssid, bssid, ETH_ALEN);
|
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;
|
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,
|
if (fils_pmk_to_ptk(sm->pmk, sm->pmk_len, sm->own_addr, sm->bssid,
|
||||||
sm->fils_nonce, sm->fils_anonce,
|
sm->fils_nonce, sm->fils_anonce,
|
||||||
dh_ss ? wpabuf_head(dh_ss) : NULL,
|
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->ptk, ick, &ick_len,
|
||||||
sm->key_mgmt, sm->pairwise_cipher,
|
sm->key_mgmt, sm->pairwise_cipher,
|
||||||
sm->fils_ft, &sm->fils_ft_len,
|
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");
|
wpa_printf(MSG_DEBUG, "FILS: Failed to derive PTK");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,7 +132,7 @@ struct rsn_supp_config {
|
||||||
int owe_ptk_workaround;
|
int owe_ptk_workaround;
|
||||||
const u8 *fils_cache_id;
|
const u8 *fils_cache_id;
|
||||||
int beacon_prot;
|
int beacon_prot;
|
||||||
bool kdk;
|
bool force_kdk_derivation;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef CONFIG_NO_WPA
|
#ifndef CONFIG_NO_WPA
|
||||||
|
|
|
@ -40,7 +40,7 @@ int wpa_derive_ptk_ft(struct wpa_sm *sm, const unsigned char *src_addr,
|
||||||
const u8 *anonce = key->key_nonce;
|
const u8 *anonce = key->key_nonce;
|
||||||
int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
|
int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
|
||||||
const u8 *mpmk;
|
const u8 *mpmk;
|
||||||
size_t mpmk_len;
|
size_t mpmk_len, kdk_len;
|
||||||
|
|
||||||
if (sm->xxkey_len > 0) {
|
if (sm->xxkey_len > 0) {
|
||||||
mpmk = sm->xxkey;
|
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);
|
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,
|
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,
|
sm->own_addr, sm->bssid, sm->pmk_r1_name, ptk,
|
||||||
ptk_name, sm->key_mgmt, sm->pairwise_cipher,
|
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;
|
int ret;
|
||||||
const u8 *bssid;
|
const u8 *bssid;
|
||||||
const u8 *kck;
|
const u8 *kck;
|
||||||
size_t kck_len;
|
size_t kck_len, kdk_len;
|
||||||
int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
|
int use_sha384 = wpa_key_mgmt_sha384(sm->key_mgmt);
|
||||||
const u8 *anonce, *snonce;
|
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);
|
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,
|
if (wpa_pmk_r1_to_ptk(sm->pmk_r1, sm->pmk_r1_len, sm->snonce,
|
||||||
anonce, sm->own_addr, bssid,
|
anonce, sm->own_addr, bssid,
|
||||||
sm->pmk_r1_name, &sm->ptk, ptk_name, sm->key_mgmt,
|
sm->pmk_r1_name, &sm->ptk, ptk_name, sm->key_mgmt,
|
||||||
sm->pairwise_cipher,
|
sm->pairwise_cipher,
|
||||||
sm->kdk ? WPA_KDK_MAX_LEN : 0) < 0)
|
kdk_len) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (wpa_key_mgmt_fils(sm->key_mgmt)) {
|
if (wpa_key_mgmt_fils(sm->key_mgmt)) {
|
||||||
|
|
|
@ -80,9 +80,9 @@ struct wpa_sm {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If set Key Derivation Key should be derived as part of PMK to
|
* 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];
|
u8 own_addr[ETH_ALEN];
|
||||||
const char *ifname;
|
const char *ifname;
|
||||||
|
|
|
@ -1477,7 +1477,7 @@ void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_PASN
|
#ifdef CONFIG_PASN
|
||||||
#ifdef CONFIG_TESTING_OPTIONS
|
#ifdef CONFIG_TESTING_OPTIONS
|
||||||
conf.kdk = wpa_s->conf->force_kdk_derivation;
|
conf.force_kdk_derivation = wpa_s->conf->force_kdk_derivation;
|
||||||
#endif /* CONFIG_TESTING_OPTIONS */
|
#endif /* CONFIG_TESTING_OPTIONS */
|
||||||
#endif /* CONFIG_PASN*/
|
#endif /* CONFIG_PASN*/
|
||||||
wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL);
|
wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL);
|
||||||
|
|
Loading…
Reference in a new issue