From 4ffb0fefe4e7b8b81f0983c5cdc8e9f779927df6 Mon Sep 17 00:00:00 2001
From: Srinivas Dasari <dasaris@codeaurora.org>
Date: Mon, 18 Mar 2019 15:04:04 +0530
Subject: [PATCH] hostapd: Support external authentication offload in AP mode

Extend commit 5ff39c1380d9 ("SAE: Support external authentication
offload for driver-SME cases") to support external authentication
with drivers that implement AP SME by notifying the status of
SAE authentication to the driver after SAE handshake as the
driver acts as a pass through for the SAE Authentication frames.

Signed-off-by: Srinivas Dasari <dasaris@codeaurora.org>
---
 src/ap/ap_drv_ops.h | 10 ++++++++++
 src/ap/ieee802_11.c | 17 +++++++++++++++++
 2 files changed, 27 insertions(+)

diff --git a/src/ap/ap_drv_ops.h b/src/ap/ap_drv_ops.h
index d45ab8462..de40171e1 100644
--- a/src/ap/ap_drv_ops.h
+++ b/src/ap/ap_drv_ops.h
@@ -364,4 +364,14 @@ static inline int hostapd_drv_channel_info(struct hostapd_data *hapd,
 	return hapd->driver->channel_info(hapd->drv_priv, ci);
 }
 
+static inline int
+hostapd_drv_send_external_auth_status(struct hostapd_data *hapd,
+				      struct external_auth *params)
+{
+	if (!hapd->driver || !hapd->drv_priv ||
+	    !hapd->driver->send_external_auth_status)
+		return -1;
+	return hapd->driver->send_external_auth_status(hapd->drv_priv, params);
+}
+
 #endif /* AP_DRV_OPS */
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index 096ad9906..a8f3fc1d8 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -701,6 +701,21 @@ static void sae_set_retransmit_timer(struct hostapd_data *hapd,
 }
 
 
+static void sae_sme_send_external_auth_status(struct hostapd_data *hapd,
+					      struct sta_info *sta, u16 status)
+{
+	struct external_auth params;
+
+	os_memset(&params, 0, sizeof(params));
+	params.status = status;
+	os_memcpy(params.bssid, sta->addr, ETH_ALEN);
+	if (status == WLAN_STATUS_SUCCESS && sta->sae)
+		params.pmkid = sta->sae->pmkid;
+
+	hostapd_drv_send_external_auth_status(hapd, &params);
+}
+
+
 void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
 {
 #ifndef CONFIG_NO_VLAN
@@ -739,6 +754,7 @@ void sae_accept_sta(struct hostapd_data *hapd, struct sta_info *sta)
 	sae_set_state(sta, SAE_ACCEPTED, "Accept Confirm");
 	wpa_auth_pmksa_add_sae(hapd->wpa_auth, sta->addr,
 			       sta->sae->pmk, sta->sae->pmkid);
+	sae_sme_send_external_auth_status(hapd, sta, WLAN_STATUS_SUCCESS);
 }
 
 
@@ -1220,6 +1236,7 @@ reply:
 		    !data && end - pos >= 2)
 			data = wpabuf_alloc_copy(pos, 2);
 
+		sae_sme_send_external_auth_status(hapd, sta, resp);
 		send_auth_reply(hapd, mgmt->sa, mgmt->bssid, WLAN_AUTH_SAE,
 				auth_transaction, resp,
 				data ? wpabuf_head(data) : (u8 *) "",