From b94371af8402f60218716552e571ca72cff4e3c0 Mon Sep 17 00:00:00 2001
From: Jouni Malinen <j@w1.fi>
Date: Fri, 15 Apr 2022 17:36:25 +0300
Subject: [PATCH] RADIUS attributes for EAPOL-Key message details

Use vendor specific RADIUS attributes for sending ANonce and EAPOL-Key
msg 2/4 for the wpa_psk_radius=3 case. The vendor specific attributes
for this are defined in FreeRADIUS as follows:

BEGIN-VENDOR    FreeRADIUS      format=Extended-Vendor-Specific-5
ATTRIBUTE       FreeRADIUS-802.1X-Anonce        1       octets[32]
ATTRIBUTE       FreeRADIUS-802.1X-EAPoL-Key-Msg 2       octets
END-VENDOR      FreeRADIUS

Signed-off-by: Jouni Malinen <j@w1.fi>
---
 src/ap/ieee802_11_auth.c | 29 +++++++++++++++++++++++++++++
 src/radius/radius.h      |  7 +++++++
 2 files changed, 36 insertions(+)

diff --git a/src/ap/ieee802_11_auth.c b/src/ap/ieee802_11_auth.c
index a54d7616e..4277d82cb 100644
--- a/src/ap/ieee802_11_auth.c
+++ b/src/ap/ieee802_11_auth.c
@@ -47,6 +47,9 @@ struct hostapd_acl_query_data {
 	struct hostapd_acl_query_data *next;
 	bool radius_psk;
 	int akm;
+	u8 *anonce;
+	u8 *eapol;
+	size_t eapol_len;
 };
 
 
@@ -102,6 +105,8 @@ static void hostapd_acl_query_free(struct hostapd_acl_query_data *query)
 	if (!query)
 		return;
 	os_free(query->auth_msg);
+	os_free(query->anonce);
+	os_free(query->eapol);
 	os_free(query);
 }
 
@@ -164,6 +169,24 @@ static int hostapd_radius_acl_query(struct hostapd_data *hapd, const u8 *addr,
 		goto fail;
 	}
 
+	if (query->anonce &&
+	    !radius_msg_add_ext_vs(msg, RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5,
+				   RADIUS_VENDOR_ID_FREERADIUS,
+				   RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_ANONCE,
+				   query->anonce, WPA_NONCE_LEN)) {
+		wpa_printf(MSG_DEBUG, "Could not add FreeRADIUS-802.1X-Anonce");
+		goto fail;
+	}
+
+	if (query->eapol &&
+	    !radius_msg_add_ext_vs(msg, RADIUS_ATTR_EXT_VENDOR_SPECIFIC_5,
+				   RADIUS_VENDOR_ID_FREERADIUS,
+				   RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_EAPOL_KEY_MSG,
+				   query->eapol, query->eapol_len)) {
+		wpa_printf(MSG_DEBUG, "Could not add FreeRADIUS-802.1X-EAPoL-Key-Msg");
+		goto fail;
+	}
+
 	if (radius_client_send(hapd->radius, msg, RADIUS_AUTH, addr) < 0)
 		goto fail;
 	return 0;
@@ -703,6 +726,12 @@ void hostapd_acl_req_radius_psk(struct hostapd_data *hapd, const u8 *addr,
 	query->akm = key_mgmt;
 	os_get_reltime(&query->timestamp);
 	os_memcpy(query->addr, addr, ETH_ALEN);
+	if (anonce)
+		query->anonce = os_memdup(anonce, WPA_NONCE_LEN);
+	if (eapol) {
+		query->eapol = os_memdup(eapol, eapol_len);
+		query->eapol_len = eapol_len;
+	}
 	if (hostapd_radius_acl_query(hapd, addr, query)) {
 		wpa_printf(MSG_DEBUG,
 			   "Failed to send Access-Request for RADIUS PSK/ACL query");
diff --git a/src/radius/radius.h b/src/radius/radius.h
index 490c8d1f6..177c64a66 100644
--- a/src/radius/radius.h
+++ b/src/radius/radius.h
@@ -208,6 +208,13 @@ enum { RADIUS_VENDOR_ATTR_MS_MPPE_SEND_KEY = 16,
        RADIUS_VENDOR_ATTR_MS_MPPE_RECV_KEY = 17
 };
 
+/* FreeRADIUS vendor-specific attributes */
+#define RADIUS_VENDOR_ID_FREERADIUS 11344
+/* Extended-Vendor-Specific-5 (245.26; long extended header) */
+enum {
+	RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_ANONCE = 1,
+	RADIUS_VENDOR_ATTR_FREERADIUS_802_1X_EAPOL_KEY_MSG = 2,
+};
 
 /* Hotspot 2.0 - WFA Vendor-specific RADIUS Attributes */
 #define RADIUS_VENDOR_ID_WFA 40808
-- 
2.25.1

