#sae_confirm_immediate=0
# SAE mechanism for PWE derivation
-# 0 = hunting-and-pecking loop only (default)
-# 1 = hash-to-element only
+# 0 = hunting-and-pecking loop only (default without password identifier)
+# 1 = hash-to-element only (default with password identifier)
# 2 = both hunting-and-pecking loop and hash-to-element enabled
# Note: The default value is likely to change from 0 to 2 once the new
# hash-to-element mechanism has received more interoperability testing.
+# When using SAE password identifier, the hash-to-element mechanism is used
+# regardless of the sae_pwe parameter value.
#sae_pwe=0
# FILS Cache Identifier (16-bit value in hexdump format)
struct hostapd_ssid *ssid = &conf->ssid;
struct sae_password_entry *pw;
- if (conf->sae_pwe == 0 || !wpa_key_mgmt_sae(conf->wpa_key_mgmt))
+ if ((conf->sae_pwe == 0 && !hostapd_sae_pw_id_in_use(conf)) ||
+ !wpa_key_mgmt_sae(conf->wpa_key_mgmt))
return 0; /* PT not needed */
sae_deinit_pt(ssid->pt);
{
u8 *pos = eid;
int i, num, count;
+ int h2e_required;
if (hapd->iface->current_rates == NULL)
return eid;
num++;
if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
num++;
- if (hapd->conf->sae_pwe == 1 &&
- wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt))
+ h2e_required = (hapd->conf->sae_pwe == 1 ||
+ hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&
+ wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt);
+ if (h2e_required)
num++;
if (num > 8) {
/* rest of the rates are encoded in Extended supported
*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
}
- if (hapd->conf->sae_pwe == 1 &&
- wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) &&
- count < 8) {
+ if (h2e_required && count < 8) {
count++;
*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
}
{
u8 *pos = eid;
int i, num, count;
+ int h2e_required;
if (hapd->iface->current_rates == NULL)
return eid;
num++;
if (hapd->iconf->ieee80211ac && hapd->iconf->require_vht)
num++;
- if (hapd->conf->sae_pwe == 1 &&
- wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt))
+ h2e_required = (hapd->conf->sae_pwe == 1 ||
+ hostapd_sae_pw_id_in_use(hapd->conf) == 2) &&
+ wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt);
+ if (h2e_required)
num++;
if (num <= 8)
return eid;
*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY;
}
- if (hapd->conf->sae_pwe == 1 &&
- wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt)) {
+ if (h2e_required) {
count++;
if (count > 8)
*pos++ = 0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY;
use_pt = sta->sae->tmp->h2e;
}
- if (status_code == WLAN_STATUS_SUCCESS)
+ if (rx_id)
+ use_pt = 1;
+ else if (status_code == WLAN_STATUS_SUCCESS)
use_pt = 0;
else if (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT)
use_pt = 1;
static int sae_status_success(struct hostapd_data *hapd, u16 status_code)
{
- return (hapd->conf->sae_pwe == 0 &&
+ int sae_pwe = hapd->conf->sae_pwe;
+ int id_in_use;
+
+ id_in_use = hostapd_sae_pw_id_in_use(hapd->conf);
+ if (id_in_use == 2)
+ sae_pwe = 1;
+ else if (id_in_use == 1 && sae_pwe == 0)
+ sae_pwe = 2;
+
+ return (sae_pwe == 0 &&
status_code == WLAN_STATUS_SUCCESS) ||
- (hapd->conf->sae_pwe == 1 &&
+ (sae_pwe == 1 &&
status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT) ||
- (hapd->conf->sae_pwe == 2 &&
+ (sae_pwe == 2 &&
(status_code == WLAN_STATUS_SUCCESS ||
status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT));
}
if (!(hapd->conf->wpa & WPA_PROTO_RSN) ||
!wpa_key_mgmt_sae(hapd->conf->wpa_key_mgmt) ||
- (hapd->conf->sae_pwe != 1 && hapd->conf->sae_pwe != 2) ||
+ (hapd->conf->sae_pwe != 1 && hapd->conf->sae_pwe != 2 &&
+ !hostapd_sae_pw_id_in_use(hapd->conf)) ||
len < 3)
return pos;
struct hostapd_config *iconf,
struct wpa_auth_config *wconf)
{
+ int sae_pw_id;
+
os_memset(wconf, 0, sizeof(*wconf));
wconf->wpa = conf->wpa;
wconf->wpa_key_mgmt = conf->wpa_key_mgmt;
FILS_CACHE_ID_LEN);
#endif /* CONFIG_FILS */
wconf->sae_pwe = conf->sae_pwe;
+ sae_pw_id = hostapd_sae_pw_id_in_use(conf);
+ if (sae_pw_id == 2)
+ wconf->sae_pwe = 1;
+ else if (sae_pw_id == 1 && wconf->sae_pwe == 0)
+ wconf->sae_pwe = 2;
}
if (flagged && ((rate_ie[j] & 0x7f) ==
BSS_MEMBERSHIP_SELECTOR_SAE_H2E_ONLY)) {
if (wpa_s->conf->sae_pwe == 0 &&
+ !ssid->sae_password_id &&
wpa_key_mgmt_sae(ssid->key_mgmt)) {
if (debug_print)
wpa_dbg(wpa_s, MSG_DEBUG,
}
#ifdef CONFIG_SAE
- if (wpa_s->conf->sae_pwe == 1 &&
+ if ((wpa_s->conf->sae_pwe == 1 || ssid->sae_password_id) &&
wpa_key_mgmt_sae(ssid->key_mgmt) &&
(!(ie = wpa_bss_get_ie(bss, WLAN_EID_RSNX)) ||
ie[1] < 1 ||
return NULL;
}
- if (wpa_s->conf->sae_pwe == 1 || wpa_s->conf->sae_pwe == 2) {
+ if (ssid->sae_password_id)
+ use_pt = 1;
+
+ if (use_pt || wpa_s->conf->sae_pwe == 1 || wpa_s->conf->sae_pwe == 2) {
bss = wpa_bss_get_bssid_latest(wpa_s, bssid);
if (bss) {
const u8 *rsnxe;
BIT(WLAN_RSNX_CAPAB_SAE_H2E));
}
- if (wpa_s->conf->sae_pwe == 1 && !use_pt) {
+ if ((wpa_s->conf->sae_pwe == 1 || ssid->sae_password_id) &&
+ !use_pt) {
wpa_printf(MSG_DEBUG,
"SAE: Cannot use H2E with the selected AP");
return NULL;
u8 *wpa_ie, size_t *wpa_ie_len)
{
struct wpa_ie_data ie;
- int sel, proto;
+ int sel, proto, sae_pwe;
const u8 *bss_wpa, *bss_rsn, *bss_rsnx, *bss_osen;
if (bss) {
#ifdef CONFIG_OCV
wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_OCV, ssid->ocv);
#endif /* CONFIG_OCV */
- wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SAE_PWE, wpa_s->conf->sae_pwe);
+ sae_pwe = wpa_s->conf->sae_pwe;
+ if (ssid->sae_password_id)
+ sae_pwe = 1;
+ wpa_sm_set_param(wpa_s->wpa, WPA_PARAM_SAE_PWE, sae_pwe);
if (wpa_sm_set_assoc_wpa_ie_default(wpa_s->wpa, wpa_ie, wpa_ie_len)) {
wpa_msg(wpa_s, MSG_WARNING, "WPA: Failed to generate WPA IE");
if (!password)
password = ssid->passphrase;
- if (conf->sae_pwe == 0 || !password) {
+ if ((conf->sae_pwe == 0 && !ssid->sae_password_id) || !password) {
/* PT derivation not needed */
sae_deinit_pt(ssid->pt);
ssid->pt = NULL;
#sae_groups=19 20 21
# SAE mechanism for PWE derivation
-# 0 = hunting-and-pecking loop only (default)
-# 1 = hash-to-element only
+# 0 = hunting-and-pecking loop only (default without password identifier)
+# 1 = hash-to-element only (default with password identifier)
# 2 = both hunting-and-pecking loop and hash-to-element enabled
# Note: The default value is likely to change from 0 to 2 once the new
# hash-to-element mechanism has received more interoperability testing.
+# When using SAE password identifier, the hash-to-element mechanism is used
+# regardless of the sae_pwe parameter value.
#sae_pwe=0
# Default value for DTIM period (if not overridden in network block)