From 8b138d28264e44a11fa3f4254a43efc24b99d779 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 23 Jan 2020 22:46:51 +0200 Subject: [PATCH] OWE: PTK derivation workaround in STA mode 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. The new owe_ptk_workaround=1 network 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. Signed-off-by: Jouni Malinen --- src/rsn_supp/wpa.c | 14 +++++++++++++- src/rsn_supp/wpa.h | 1 + src/rsn_supp/wpa_i.h | 1 + wpa_supplicant/config.c | 1 + wpa_supplicant/config_file.c | 1 + wpa_supplicant/config_ssid.h | 13 +++++++++++++ wpa_supplicant/wpas_glue.c | 1 + 7 files changed, 31 insertions(+), 1 deletion(-) 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) {