diff --git a/src/ap/beacon.c b/src/ap/beacon.c index b3b33b7fa..6d5bb7106 100644 --- a/src/ap/beacon.c +++ b/src/ap/beacon.c @@ -1507,6 +1507,9 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd) IEEE80211_MODE_AP); #endif /* CONFIG_IEEE80211AX */ hapd->reenable_beacon = 0; +#ifdef CONFIG_SAE + params.sae_pwe = hapd->conf->sae_pwe; +#endif /* CONFIG_SAE */ if (cmode && hostapd_set_freq_params(&freq, iconf->hw_mode, iface->freq, diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 2f7f09a8a..722e428f1 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -1189,6 +1189,14 @@ struct wpa_driver_associate_params { * fils_erp_rrk_len - Length of fils_erp_rrk in bytes */ size_t fils_erp_rrk_len; + + /** + * sae_pwe - SAE mechanism for PWE derivation + * 0 = hunting-and-pecking loop only + * 1 = hash-to-element only + * 2 = both hunting-and-pecking loop and hash-to-element enabled + */ + int sae_pwe; }; enum hide_ssid { @@ -1508,6 +1516,14 @@ struct wpa_driver_ap_params { * twt_responder - Whether Target Wait Time responder is enabled */ int twt_responder; + + /** + * sae_pwe - SAE mechanism for PWE derivation + * 0 = hunting-and-pecking loop only + * 1 = hash-to-element only + * 2 = both hunting-and-pecking loop and hash-to-element enabled + */ + int sae_pwe; }; struct wpa_driver_mesh_bss_params { diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 477443050..94bf98210 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -4304,6 +4304,30 @@ static int nl80211_set_multicast_to_unicast(struct i802_bss *bss, } +#ifdef CONFIG_SAE +static int nl80211_put_sae_pwe(struct nl_msg *msg, int pwe) +{ + u8 sae_pwe; + + wpa_printf(MSG_DEBUG, "nl802111: sae_pwe=%d", pwe); + if (pwe == 0) + sae_pwe = NL80211_SAE_PWE_HUNT_AND_PECK; + else if (pwe == 1) + sae_pwe = NL80211_SAE_PWE_HASH_TO_ELEMENT; + else if (pwe == 2) + sae_pwe = NL80211_SAE_PWE_BOTH; + else if (pwe == 3) + return 0; /* special test mode */ + else + return -1; + if (nla_put_u8(msg, NL80211_ATTR_SAE_PWE, sae_pwe)) + return -1; + + return 0; +} +#endif /* CONFIG_SAE */ + + static int wpa_driver_nl80211_set_ap(void *priv, struct wpa_driver_ap_params *params) { @@ -4564,6 +4588,13 @@ static int wpa_driver_nl80211_set_ap(void *priv, } #endif /* CONFIG_IEEE80211AX */ +#ifdef CONFIG_SAE + if (((params->key_mgmt_suites & WPA_KEY_MGMT_SAE) || + (params->key_mgmt_suites & WPA_KEY_MGMT_FT_SAE)) && + nl80211_put_sae_pwe(msg, params->sae_pwe) < 0) + goto fail; +#endif /* CONFIG_SAE */ + ret = send_and_recv_msgs_owner(drv, msg, get_connect_handle(bss), 1, NULL, NULL, NULL, NULL); if (ret) { @@ -6114,6 +6145,13 @@ static int wpa_driver_nl80211_try_connect( nla_put_u32(msg, NL80211_ATTR_USE_MFP, NL80211_MFP_OPTIONAL)) goto fail; +#ifdef CONFIG_SAE + if ((params->key_mgmt_suite == WPA_KEY_MGMT_SAE || + params->key_mgmt_suite == WPA_KEY_MGMT_FT_SAE) && + nl80211_put_sae_pwe(msg, params->sae_pwe) < 0) + goto fail; +#endif /* CONFIG_SAE */ + algs = 0; if (params->auth_alg & WPA_AUTH_ALG_OPEN) algs++; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index fba6d0eaf..ba7c23fa9 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -3831,6 +3831,10 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) wpa_s->current_ssid) params.prev_bssid = prev_bssid; +#ifdef CONFIG_SAE + params.sae_pwe = wpa_s->conf->sae_pwe; +#endif /* CONFIG_SAE */ + ret = wpa_drv_associate(wpa_s, ¶ms); os_free(wpa_ie); if (ret < 0) {