diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 83d657d9f..15bfa7c5b 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -889,7 +889,8 @@ struct wpa_ssid { /** * owe_group - OWE DH Group * - * 0 = use default (19) + * 0 = use default (19) first and then try all supported groups one by + * one if AP rejects the selected group * 1-65535 DH Group to use for OWE * * Groups 19 (NIST P-256), 20 (NIST P-384), and 21 (NIST P-521) are diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 820cc5265..26568486f 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -3986,6 +3986,26 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, data->assoc_reject.timeout_reason : ""); wpa_s->assoc_status_code = data->assoc_reject.status_code; wpas_notify_assoc_status_code(wpa_s); + +#ifdef CONFIG_OWE + if (data->assoc_reject.status_code == + WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED && + wpa_s->key_mgmt == WPA_KEY_MGMT_OWE && + wpa_s->current_ssid && + wpa_s->current_ssid->owe_group == 0 && + wpa_s->last_owe_group != 21) { + struct wpa_ssid *ssid = wpa_s->current_ssid; + struct wpa_bss *bss = wpa_s->current_bss; + + wpa_printf(MSG_DEBUG, + "OWE: Try next supported DH group"); + wpas_connect_work_done(wpa_s); + wpa_supplicant_mark_disassoc(wpa_s); + wpa_supplicant_connect(wpa_s, bss, ssid); + break; + } +#endif /* CONFIG_OWE */ + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) sme_event_assoc_reject(wpa_s, data); else { diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index da0e8eb41..723a77969 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -1204,10 +1204,20 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode, if (auth_type == WLAN_AUTH_OPEN && wpa_s->key_mgmt == WPA_KEY_MGMT_OWE) { struct wpabuf *owe_ie; - u16 group = OWE_DH_GROUP; + u16 group; - if (wpa_s->current_ssid && wpa_s->current_ssid->owe_group) + if (wpa_s->current_ssid && wpa_s->current_ssid->owe_group) { group = wpa_s->current_ssid->owe_group; + } else { + if (wpa_s->last_owe_group == 19) + group = 20; + else if (wpa_s->last_owe_group == 20) + group = 21; + else + group = OWE_DH_GROUP; + } + wpa_s->last_owe_group = group; + wpa_printf(MSG_DEBUG, "OWE: Try to use group %u", group); owe_ie = owe_build_assoc_req(wpa_s->wpa, group); if (!owe_ie) { wpa_printf(MSG_ERROR, diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 984fe02f7..9bc2c2710 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2617,10 +2617,20 @@ static u8 * wpas_populate_assoc_ies( if (algs == WPA_AUTH_ALG_OPEN && ssid->key_mgmt == WPA_KEY_MGMT_OWE) { struct wpabuf *owe_ie; - u16 group = OWE_DH_GROUP; + u16 group; - if (ssid->owe_group) + if (ssid->owe_group) { group = ssid->owe_group; + } else { + if (wpa_s->last_owe_group == 19) + group = 20; + else if (wpa_s->last_owe_group == 20) + group = 21; + else + group = OWE_DH_GROUP; + } + wpa_s->last_owe_group = group; + wpa_printf(MSG_DEBUG, "OWE: Try to use group %u", group); owe_ie = owe_build_assoc_req(wpa_s->wpa, group); if (owe_ie && wpabuf_len(owe_ie) <= max_wpa_ie_len - wpa_ie_len) { @@ -3405,6 +3415,7 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s, wpa_s->disconnected = 0; wpa_s->reassociate = 1; + wpa_s->last_owe_group = 0; if (wpa_s->connect_without_scan || wpa_supplicant_fast_associate(wpa_s) != 1) { @@ -6659,6 +6670,7 @@ void wpas_request_connection(struct wpa_supplicant *wpa_s) wpa_s->extra_blacklist_count = 0; wpa_s->disconnected = 0; wpa_s->reassociate = 1; + wpa_s->last_owe_group = 0; if (wpa_supplicant_fast_associate(wpa_s) != 1) wpa_supplicant_req_scan(wpa_s, 0, 0); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index d4c01ba2a..3516c3e7f 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -751,6 +751,7 @@ struct wpa_supplicant { int set_ap_uapsd; int ap_uapsd; int auth_alg; + u16 last_owe_group; #ifdef CONFIG_SME struct {