diff -Naur a/src/drivers/driver.h b/src/drivers/driver.h --- a/src/drivers/driver.h 2022-01-16 15:51:29.000000000 -0500 +++ b/src/drivers/driver.h 2023-08-30 10:22:48.193810598 -0400 @@ -1015,6 +1015,14 @@ const u8 *psk; /** + * sae_password - Password for SAE authentication + * + * This value is made available only for WPA3-Personal (SAE) and only + * for drivers that set WPA_DRIVER_FLAGS2_SAE_OFFLOAD. + */ + const char *sae_password; + + /** * drop_unencrypted - Enable/disable unencrypted frame filtering * * Configure the driver to drop all non-EAPOL frames (both receive and diff -Naur a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c --- a/src/drivers/driver_nl80211.c 2022-01-16 15:51:29.000000000 -0500 +++ b/src/drivers/driver_nl80211.c 2023-08-30 10:22:48.195810610 -0400 @@ -6173,8 +6173,12 @@ if (params->wpa_proto & WPA_PROTO_WPA) ver |= NL80211_WPA_VERSION_1; - if (params->wpa_proto & WPA_PROTO_RSN) - ver |= NL80211_WPA_VERSION_2; + if (params->wpa_proto & WPA_PROTO_RSN) { + if (params->key_mgmt_suite == WPA_KEY_MGMT_SAE) + ver |= NL80211_WPA_VERSION_3; + else + ver |= NL80211_WPA_VERSION_2; + } wpa_printf(MSG_DEBUG, " * WPA Versions 0x%x", ver); if (nla_put_u32(msg, NL80211_ATTR_WPA_VERSIONS, ver)) @@ -6304,6 +6308,22 @@ return -1; } + /* add SAE password in case of SAE authentication offload */ + if ((params->sae_password || params->passphrase) && + (drv->capa.flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD)) { + const char *password; + size_t pwd_len; + + password = params->sae_password; + if (!password) + password = params->passphrase; + pwd_len = os_strlen(password); + wpa_hexdump_ascii_key(MSG_DEBUG, " * SAE password", + (u8 *) password, pwd_len); + if (nla_put(msg, NL80211_ATTR_SAE_PASSWORD, pwd_len, password)) + return -1; + } + if (nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT)) return -1; @@ -6419,6 +6439,8 @@ algs++; if (params->auth_alg & WPA_AUTH_ALG_FT) algs++; + if (params->auth_alg & WPA_AUTH_ALG_SAE) + algs++; if (algs > 1) { wpa_printf(MSG_DEBUG, " * Leave out Auth Type for automatic " "selection"); diff -Naur a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c --- a/wpa_supplicant/wpa_supplicant.c 2023-08-30 10:18:04.154061324 -0400 +++ b/wpa_supplicant/wpa_supplicant.c 2023-08-30 10:24:53.619588124 -0400 @@ -1537,7 +1537,8 @@ sel = ie.key_mgmt & ssid->key_mgmt; #ifdef CONFIG_SAE - if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) + if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) && + !(wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD)) sel &= ~(WPA_KEY_MGMT_SAE | WPA_KEY_MGMT_FT_SAE); #endif /* CONFIG_SAE */ #ifdef CONFIG_IEEE80211R @@ -3919,6 +3920,18 @@ params.psk = ssid->psk; } + if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD) && + wpa_key_mgmt_sae(params.key_mgmt_suite)) { + params.auth_alg = WPA_AUTH_ALG_SAE; + if (ssid->sae_password) + params.sae_password = ssid->sae_password; + else if (ssid->passphrase) + params.passphrase = ssid->passphrase; + + if (ssid->psk_set) + params.psk = ssid->psk; + } + params.drop_unencrypted = use_crypt; params.mgmt_frame_protection = wpas_get_ssid_pmf(wpa_s, ssid);