From dfa364f9970f1d88782cc9a9b7292afadbf2358b Mon Sep 17 00:00:00 2001
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Date: Tue, 10 Dec 2019 14:06:20 -0600
Subject: [PATCH 11/49] SAE: Support SAE authentication offload in AP mode

Add support for SAE authentication offload in AP mode. In this case, the
SAE authentication process is handled by driver instead of user space.

Signed-off-by: Chung-Hsien Hsu <chung-hsien.hsu@infineon.com>
---
 src/ap/beacon.c        | 11 +++++++++++
 src/ap/wpa_auth.h      |  3 +++
 src/ap/wpa_auth_glue.c |  5 +++++
 src/ap/wpa_auth_ie.c   |  4 +++-
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 583b6836e..e2d7c6970 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -1763,6 +1763,17 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
 			params->psk = hapd->conf->ssid.wpa_psk->psk;
 	}
 
+#ifdef CONFIG_SAE
+	if ((hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP) &&
+	    (params->key_mgmt_suites & WPA_KEY_MGMT_SAE)) {
+		params->auth_algs |= WPA_AUTH_ALG_SAE;
+		if (hapd->conf->sae_passwords)
+			params->sae_password = hapd->conf->sae_passwords->password;
+		else if (hapd->conf->ssid.wpa_passphrase)
+			params->passphrase = hapd->conf->ssid.wpa_passphrase;
+	}
+#endif /* CONFIG_SAE */
+
 	return 0;
 }
 
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index 2f807893f..ff36cfe95 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -275,6 +275,9 @@ struct wpa_auth_config {
 	bool force_kdk_derivation;
 
 	int psk_4way_hs_offload;
+#ifdef CONFIG_SAE
+	int sae_offload;
+#endif /* CONFIG_SAE */
 };
 
 typedef enum {
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index 26de12b5b..c8dee2aef 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -1532,6 +1532,11 @@ int hostapd_setup_wpa(struct hostapd_data *hapd)
 	    (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_4WAY_HANDSHAKE_AP_PSK))
 		_conf.psk_4way_hs_offload = 1;
 
+#ifdef CONFIG_SAE
+	if (hapd->iface->drv_flags2 & WPA_DRIVER_FLAGS2_SAE_OFFLOAD_AP)
+		_conf.sae_offload = 1;
+#endif /* CONFIG_SAE */
+
 	hapd->wpa_auth = wpa_init(hapd->own_addr, &_conf, &cb, hapd);
 	if (hapd->wpa_auth == NULL) {
 		wpa_printf(MSG_ERROR, "WPA initialization failed.");
diff --git a/src/ap/wpa_auth_ie.c b/src/ap/wpa_auth_ie.c
index 524922e4e..30de0c19c 100644
--- a/src/ap/wpa_auth_ie.c
+++ b/src/ap/wpa_auth_ie.c
@@ -977,7 +977,9 @@ wpa_validate_wpa_ie(struct wpa_authenticator *wpa_auth,
 	}
 
 #ifdef CONFIG_SAE
-	if (sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE && data.num_pmkid &&
+	if (!wpa_auth->conf.psk_4way_hs_offload &&
+	    !wpa_auth->conf.sae_offload &&
+	    sm->wpa_key_mgmt == WPA_KEY_MGMT_SAE && data.num_pmkid &&
 	    !sm->pmksa) {
 		wpa_auth_vlogger(wpa_auth, sm->addr, LOGGER_DEBUG,
 				 "No PMKSA cache entry found for SAE");
-- 
2.17.1

