diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c index e6dfb34d1..acb4416c5 100644 --- a/src/ap/wpa_auth.c +++ b/src/ap/wpa_auth.c @@ -2278,9 +2278,17 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, struct wpa_ptk *ptk, int force_sha256) { const u8 *z = NULL; - size_t z_len = 0; + size_t z_len = 0, kdk_len; int akmp; + if (sm->wpa_auth->conf.force_kdk_derivation || + (sm->wpa_auth->conf.secure_ltf && + sm->rsnxe && sm->rsnxe_len >= 4 && + sm->rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8))) + kdk_len = WPA_KDK_MAX_LEN; + else + kdk_len = 0; + #ifdef CONFIG_IEEE80211R_AP if (wpa_key_mgmt_ft(sm->wpa_key_mgmt)) { if (sm->ft_completed) { @@ -2293,8 +2301,7 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, ptk, ptk_name, sm->wpa_key_mgmt, sm->pairwise, - sm->wpa_auth->conf.kdk ? - WPA_KDK_MAX_LEN : 0); + kdk_len); } return wpa_auth_derive_ptk_ft(sm, ptk); } @@ -2312,8 +2319,7 @@ static int wpa_derive_ptk(struct wpa_state_machine *sm, const u8 *snonce, akmp |= WPA_KEY_MGMT_PSK_SHA256; return wpa_pmk_to_ptk(pmk, pmk_len, "Pairwise key expansion", sm->wpa_auth->addr, sm->addr, sm->ANonce, snonce, - ptk, akmp, sm->pairwise, z, z_len, - sm->wpa_auth->conf.kdk ? WPA_KDK_MAX_LEN : 0); + ptk, akmp, sm->pairwise, z, z_len, kdk_len); } @@ -2328,14 +2334,21 @@ int fils_auth_pmk_to_ptk(struct wpa_state_machine *sm, const u8 *pmk, size_t ick_len; int res; u8 fils_ft[FILS_FT_MAX_LEN]; - size_t fils_ft_len = 0; + size_t fils_ft_len = 0, kdk_len; + + if (sm->wpa_auth->conf.force_kdk_derivation || + (sm->wpa_auth->conf.secure_ltf && + sm->rsnxe && sm->rsnxe_len >= 4 && + sm->rsnxe[3] & BIT(WLAN_RSNX_CAPAB_SECURE_LTF - 8))) + kdk_len = WPA_KDK_MAX_LEN; + else + kdk_len = 0; res = fils_pmk_to_ptk(pmk, pmk_len, sm->addr, sm->wpa_auth->addr, snonce, anonce, dhss, dhss_len, &sm->PTK, ick, &ick_len, sm->wpa_key_mgmt, sm->pairwise, - fils_ft, &fils_ft_len, - sm->wpa_auth->conf.kdk ? WPA_KDK_MAX_LEN : 0); + fils_ft, &fils_ft_len, kdk_len); if (res < 0) return res; sm->PTK_valid = true; diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h index 0a16141ed..cf0801dc3 100644 --- a/src/ap/wpa_auth.h +++ b/src/ap/wpa_auth.h @@ -270,9 +270,9 @@ struct wpa_auth_config { /* * 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; }; typedef enum { diff --git a/src/ap/wpa_auth_ft.c b/src/ap/wpa_auth_ft.c index 115a6fa2f..32b745651 100644 --- a/src/ap/wpa_auth_ft.c +++ b/src/ap/wpa_auth_ft.c @@ -3066,7 +3066,7 @@ static int wpa_ft_process_auth_req(struct wpa_state_machine *sm, const u8 *identity, *radius_cui; size_t identity_len = 0, radius_cui_len = 0; int use_sha384; - size_t pmk_r1_len; + size_t pmk_r1_len, kdk_len; *resp_ies = NULL; *resp_ies_len = 0; @@ -3196,12 +3196,18 @@ pmk_r1_derived: wpa_hexdump(MSG_DEBUG, "FT: Generated ANonce", sm->ANonce, WPA_NONCE_LEN); + if (sm->wpa_auth->conf.force_kdk_derivation || + (sm->wpa_auth->conf.secure_ltf && + sm->rsnxe && sm->rsnxe_len >= 4 && + sm->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(pmk_r1, pmk_r1_len, sm->SNonce, sm->ANonce, sm->addr, sm->wpa_auth->addr, pmk_r1_name, &sm->PTK, ptk_name, sm->wpa_key_mgmt, - pairwise, - sm->wpa_auth->conf.kdk ? - WPA_KDK_MAX_LEN : 0) < 0) + pairwise, kdk_len) < 0) return WLAN_STATUS_UNSPECIFIED_FAILURE; sm->pairwise = pairwise; diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c index 23025b36a..ebc35dd29 100644 --- a/src/ap/wpa_auth_glue.c +++ b/src/ap/wpa_auth_glue.c @@ -211,7 +211,7 @@ static void hostapd_wpa_auth_conf(struct hostapd_bss_config *conf, #endif /* CONFIG_DPP2 */ #ifdef CONFIG_PASN #ifdef CONFIG_TESTING_OPTIONS - wconf->kdk = conf->force_kdk_derivation; + wconf->force_kdk_derivation = conf->force_kdk_derivation; #endif /* CONFIG_TESTING_OPTIONS */ #endif /* CONFIG_PASN */ }