diff --git a/src/rsn_supp/wpa.c b/src/rsn_supp/wpa.c index ea97c9484..039f076fa 100644 --- a/src/rsn_supp/wpa.c +++ b/src/rsn_supp/wpa.c @@ -570,6 +570,7 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr, { const u8 *z = NULL; size_t z_len = 0; + int akmp; #ifdef CONFIG_IEEE80211R if (wpa_key_mgmt_ft(sm->key_mgmt)) @@ -583,9 +584,18 @@ static int wpa_derive_ptk(struct wpa_sm *sm, const unsigned char *src_addr, } #endif /* CONFIG_DPP2 */ + akmp = sm->key_mgmt; +#ifdef CONFIG_OWE + if (sm->owe_ptk_workaround && akmp == WPA_KEY_MGMT_OWE && + sm->pmk_len > 32) { + wpa_printf(MSG_DEBUG, + "OWE: Force SHA256 for PTK derivation"); + akmp = WPA_KEY_MGMT_PSK_SHA256; + } +#endif /* CONFIG_OWE */ return wpa_pmk_to_ptk(sm->pmk, sm->pmk_len, "Pairwise key expansion", sm->own_addr, sm->bssid, sm->snonce, - key->key_nonce, ptk, sm->key_mgmt, + key->key_nonce, ptk, akmp, sm->pairwise_cipher, z, z_len); } @@ -2940,6 +2950,7 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config) sm->wpa_ptk_rekey = config->wpa_ptk_rekey; sm->p2p = config->p2p; sm->wpa_rsc_relaxation = config->wpa_rsc_relaxation; + sm->owe_ptk_workaround = config->owe_ptk_workaround; #ifdef CONFIG_FILS if (config->fils_cache_id) { sm->fils_cache_id_set = 1; @@ -2959,6 +2970,7 @@ void wpa_sm_set_config(struct wpa_sm *sm, struct rsn_supp_config *config) sm->wpa_ptk_rekey = 0; sm->p2p = 0; sm->wpa_rsc_relaxation = 0; + sm->owe_ptk_workaround = 0; } } diff --git a/src/rsn_supp/wpa.h b/src/rsn_supp/wpa.h index 85fedeeae..ceae721aa 100644 --- a/src/rsn_supp/wpa.h +++ b/src/rsn_supp/wpa.h @@ -113,6 +113,7 @@ struct rsn_supp_config { int wpa_ptk_rekey; int p2p; int wpa_rsc_relaxation; + int owe_ptk_workaround; const u8 *fils_cache_id; }; diff --git a/src/rsn_supp/wpa_i.h b/src/rsn_supp/wpa_i.h index 7d7c06ef2..e088a5aa7 100644 --- a/src/rsn_supp/wpa_i.h +++ b/src/rsn_supp/wpa_i.h @@ -63,6 +63,7 @@ struct wpa_sm { int wpa_ptk_rekey; int p2p; int wpa_rsc_relaxation; + int owe_ptk_workaround; u8 own_addr[ETH_ALEN]; const char *ifname; diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 3b37d152d..1bc798b89 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2566,6 +2566,7 @@ static const struct parse_data ssid_fields[] = { #endif /* CONFIG_DPP */ { INT_RANGE(owe_group, 0, 65535) }, { INT_RANGE(owe_only, 0, 1) }, + { INT_RANGE(owe_ptk_workaround, 0, 1) }, { INT_RANGE(multi_ap_backhaul_sta, 0, 1) }, { INT_RANGE(ft_eap_pmksa_caching, 0, 1) }, }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 2a0c7803e..fd2bdff48 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -910,6 +910,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid) #endif /* CONFIG_DPP */ INT(owe_group); INT(owe_only); + INT(owe_ptk_workaround); INT(multi_ap_backhaul_sta); INT(ft_eap_pmksa_caching); #ifdef CONFIG_HT_OVERRIDES diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 98db1fe1a..b752dfdda 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -1008,6 +1008,19 @@ struct wpa_ssid { */ int owe_only; + /** + * owe_ptk_workaround - OWE PTK derivation workaround + * + * Initial OWE implementation used SHA256 when deriving the PTK for all + * OWE groups. This was supposed to change to SHA384 for group 20 and + * SHA512 for group 21. This parameter can be used to enable older + * behavior mainly for testing purposes. There is no impact to group 19 + * behavior, but if enabled, this will make group 20 and 21 cases use + * SHA256-based PTK derivation which will not work with the updated + * OWE implementation on the AP side. + */ + int owe_ptk_workaround; + /** * owe_transition_bss_select_count - OWE transition BSS select count * diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c index 9d5d35607..f113bfe29 100644 --- a/wpa_supplicant/wpas_glue.c +++ b/wpa_supplicant/wpas_glue.c @@ -1286,6 +1286,7 @@ void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s, conf.ssid = ssid->ssid; conf.ssid_len = ssid->ssid_len; conf.wpa_ptk_rekey = ssid->wpa_ptk_rekey; + conf.owe_ptk_workaround = ssid->owe_ptk_workaround; #ifdef CONFIG_P2P if (ssid->p2p_group && wpa_s->current_bss && !wpa_s->p2p_disable_ip_addr_req) {