struct wpabuf *wd)
{
struct pasn_data *pasn = sta->pasn;
- const char *password = NULL;
+ const char *password;
const u8 *data;
size_t buf_len;
u16 res, alg, seq, status;
int groups[] = { pasn->group, 0 };
+ struct sae_pt *pt = NULL;
int ret;
if (!wd)
wpa_printf(MSG_DEBUG, "PASN: SAE commit: alg=%u, seq=%u, status=%u",
alg, seq, status);
- /* TODO: SAE H2E */
- if (alg != WLAN_AUTH_SAE || seq != 1 || status != WLAN_STATUS_SUCCESS) {
+ if (alg != WLAN_AUTH_SAE || seq != 1 ||
+ status != WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
wpa_printf(MSG_DEBUG, "PASN: Dropping peer SAE commit");
return -1;
}
return -1;
}
- password = sae_get_password(hapd, sta, NULL, NULL, NULL, NULL);
- if (!password) {
- wpa_printf(MSG_DEBUG, "PASN: No SAE password found");
+ password = sae_get_password(hapd, sta, NULL, NULL, &pt, NULL);
+ if (!password || !pt) {
+ wpa_printf(MSG_DEBUG, "PASN: No SAE PT found");
return -1;
}
- ret = sae_prepare_commit(hapd->own_addr, sta->addr,
- (const u8 *) password, os_strlen(password), 0,
- &pasn->sae);
+ ret = sae_prepare_commit_pt(&pasn->sae, pt, hapd->own_addr, sta->addr,
+ NULL, NULL);
if (ret) {
wpa_printf(MSG_DEBUG, "PASN: Failed to prepare SAE commit");
return -1;
len_ptr = wpabuf_put(buf, 2);
wpabuf_put_le16(buf, WLAN_AUTH_SAE);
wpabuf_put_le16(buf, 1);
- wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+ wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
/* Write the actual commit and update the length accordingly */
sae_write_commit(&pasn->sae, buf, NULL, 0);
{
struct wpas_pasn *pasn = &wpa_s->pasn;
struct wpabuf *buf = NULL;
- const char *password = NULL;
int ret;
- if (pasn->ssid) {
- password = pasn->ssid->sae_password;
- if (!password)
- password = pasn->ssid->passphrase;
- }
-
- if (!password) {
- wpa_printf(MSG_DEBUG, "PASN: SAE without a password");
- return NULL;
- }
-
ret = sae_set_group(&pasn->sae, pasn->group);
if (ret) {
wpa_printf(MSG_DEBUG, "PASN: Failed to set SAE group");
return NULL;
}
- /* TODO: SAE H2E */
- ret = sae_prepare_commit(wpa_s->own_addr, pasn->bssid,
- (const u8 *) password, os_strlen(password), 0,
- &pasn->sae);
+ ret = sae_prepare_commit_pt(&pasn->sae, pasn->ssid->pt,
+ wpa_s->own_addr, pasn->bssid,
+ NULL, NULL);
if (ret) {
wpa_printf(MSG_DEBUG, "PASN: Failed to prepare SAE commit");
return NULL;
wpabuf_put_le16(buf, WLAN_AUTH_SAE);
wpabuf_put_le16(buf, 1);
- wpabuf_put_le16(buf, WLAN_STATUS_SUCCESS);
+ wpabuf_put_le16(buf, WLAN_STATUS_SAE_HASH_TO_ELEMENT);
sae_write_commit(&pasn->sae, buf, NULL, 0);
pasn->sae.state = SAE_COMMITTED;
wpa_printf(MSG_DEBUG, "PASN: SAE: commit: alg=%u, seq=%u, status=%u",
alg, seq, status);
- /* TODO: SAE H2E */
- if (alg != WLAN_AUTH_SAE || seq != 1 || status != WLAN_STATUS_SUCCESS) {
+ if (alg != WLAN_AUTH_SAE || seq != 1 ||
+ status != WLAN_STATUS_SAE_HASH_TO_ELEMENT) {
wpa_printf(MSG_DEBUG, "PASN: SAE: dropping peer commit");
return -1;
}
res = sae_parse_commit(&pasn->sae, data + 6, len - 6, NULL, 0, groups,
- 0);
+ 1);
if (res != WLAN_STATUS_SUCCESS) {
wpa_printf(MSG_DEBUG, "PASN: SAE failed parsing commit");
return -1;
return buf;
}
+
+static int wpas_pasn_sae_setup_pt(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid, int group)
+{
+ const char *password = ssid->sae_password;
+ int groups[2] = { group, 0 };
+
+ if (!password)
+ password = ssid->passphrase;
+
+ if (!password) {
+ wpa_printf(MSG_DEBUG, "PASN: SAE without a password");
+ return -1;
+ }
+
+ if (ssid->pt)
+ return 0; /* PT already derived */
+
+ ssid->pt = sae_derive_pt(groups, ssid->ssid, ssid->ssid_len,
+ (const u8 *) password, os_strlen(password),
+ ssid->sae_password_id);
+
+ return ssid->pt ? 0 : -1;
+}
+
#endif /* CONFIG_SAE */
goto fail;
/* Add own RNSXE */
- /* TODO: How to handle protected TWT and SAE H2E? */
capab = 0;
+ capab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);
if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_LTF)
capab |= BIT(WLAN_RSNX_CAPAB_SECURE_LTF);
if (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_SEC_RTT)
"PASN: No network profile found for SAE");
return -1;
}
+
+ if (beacon_rsnxe_len < 3 ||
+ !(beacon_rsnxe[2] & BIT(WLAN_RSNX_CAPAB_SAE_H2E))) {
+ wpa_printf(MSG_DEBUG,
+ "PASN: AP does not support SAE H2E");
+ return -1;
+ }
+
+ if (wpas_pasn_sae_setup_pt(wpa_s, ssid, group) < 0) {
+ wpa_printf(MSG_DEBUG,
+ "PASN: Failed to derive PT");
+ return -1;
+ }
+
pasn->sae.state = SAE_NOTHING;
pasn->sae.send_confirm = 0;
pasn->ssid = ssid;