[PATCH 5/5] PASN: Change PASN flows to use SAE H2E only

Ilan Peer ilan.peer at intel.com
Thu Apr 8 10:06:24 BST 2021


Do so for both wpa_supplicant and hostapd.

Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
 src/ap/ieee802_11.c              | 20 ++++-----
 wpa_supplicant/pasn_supplicant.c | 77 +++++++++++++++++++++++---------
 2 files changed, 65 insertions(+), 32 deletions(-)

diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index e4dd2b4b3f..9cd225b26d 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2383,11 +2383,12 @@ static int pasn_wd_handle_sae_commit(struct hostapd_data *hapd,
 				     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)
@@ -2409,8 +2410,8 @@ static int pasn_wd_handle_sae_commit(struct hostapd_data *hapd,
 	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;
 	}
@@ -2424,15 +2425,14 @@ static int pasn_wd_handle_sae_commit(struct hostapd_data *hapd,
 		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;
@@ -2529,7 +2529,7 @@ static struct wpabuf * pasn_get_sae_wd(struct hostapd_data *hapd,
 	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);
diff --git a/wpa_supplicant/pasn_supplicant.c b/wpa_supplicant/pasn_supplicant.c
index c0db686dfe..3df3aa4707 100644
--- a/wpa_supplicant/pasn_supplicant.c
+++ b/wpa_supplicant/pasn_supplicant.c
@@ -102,30 +102,17 @@ static struct wpabuf * wpas_pasn_wd_sae_commit(struct wpa_supplicant *wpa_s)
 {
 	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;
@@ -140,7 +127,7 @@ static struct wpabuf * wpas_pasn_wd_sae_commit(struct wpa_supplicant *wpa_s)
 
 	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;
@@ -186,14 +173,14 @@ static int wpas_pasn_wd_sae_rx(struct wpa_supplicant *wpa_s, struct wpabuf *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: 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;
@@ -271,8 +258,33 @@ static struct wpabuf * wpas_pasn_wd_sae_confirm(struct wpa_supplicant *wpa_s)
 	return buf;
 }
 
-#endif /* CONFIG_SAE */
 
+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;
+	}
+
+	/* PT already derived */
+	if (ssid->pt)
+		return 0;
+
+	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 */
 
 #ifdef CONFIG_FILS
 
@@ -718,8 +730,9 @@ static struct wpabuf * wpas_pasn_build_auth_1(struct wpa_supplicant *wpa_s,
 		goto fail;
 
 	/* Add own RNSXE */
-	/* TODO: How to handle protected TWT and SAE H2E? */
 	capab = 0;
+	if (wpa_s->conf->sae_pwe == 1 || wpa_s->conf->sae_pwe == 2)
+		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)
@@ -1008,6 +1021,26 @@ static int wpas_pasn_start(struct wpa_supplicant *wpa_s, const u8 *bssid,
 				   "PASN: No network profile found for SAE");
 			return -1;
 		}
+
+		if (wpa_s->conf->sae_pwe != 1 && wpa_s->conf->sae_pwe != 2) {
+			wpa_printf(MSG_DEBUG,
+				   "PASN: SAE H2E not enabled in configuration");
+			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;
-- 
2.17.1




More information about the Hostap mailing list