[PATCH v2 20/28] PASN: Add support for MIC computation for M3 frame for SME-in-Userspace

Ainy Kumari ainy.kumari at oss.qualcomm.com
Tue Jan 6 05:45:30 PST 2026


For SME-in-Userspace scenarios, MIC is computed on frame3 body,
hash of frame1 body, but frame1 and frame3 contain auth_data starting
from transaction number to comply with mac80211 requirement, hence
prepend auth algorithm to frame body for preparing MIC.

Signed-off-by: Ainy Kumari <ainy.kumari at oss.qualcomm.com>
---
 src/pasn/pasn_initiator.c | 53 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 47 insertions(+), 6 deletions(-)

diff --git a/src/pasn/pasn_initiator.c b/src/pasn/pasn_initiator.c
index 30f42fb65..b7ed5ee9d 100644
--- a/src/pasn/pasn_initiator.c
+++ b/src/pasn/pasn_initiator.c
@@ -582,6 +582,18 @@ static u8 wpas_pasn_get_wrapped_data_format(struct pasn_data *pasn)
 }
 
 
+static u8 * pasn_prepend_auth_alg(u16 auth_alg, const u8 *buf, size_t len)
+{
+	u8 *new_buf = os_malloc(len + 2);
+	if (!new_buf)
+		return NULL;
+
+	os_memcpy(new_buf, &auth_alg, 2);
+	os_memcpy(new_buf + 2, buf, len);
+	return new_buf;
+}
+
+
 struct wpabuf *wpas_pasn_build_auth_1(struct pasn_data *pasn,
 					      const struct wpabuf *comeback,
 					      bool verify, bool is_sme_drv)
@@ -589,6 +601,9 @@ struct wpabuf *wpas_pasn_build_auth_1(struct pasn_data *pasn,
 	struct wpabuf *buf, *pubkey = NULL, *wrapped_data_buf = NULL;
 	const u8 *pmkid;
 	u8 wrapped_data;
+	const u8 *data;
+	size_t data_len;
+	u8 *copy = NULL;
 
 	wpa_printf(MSG_DEBUG, "PASN: Building frame 1");
 
@@ -676,9 +691,23 @@ struct wpabuf *wpas_pasn_build_auth_1(struct pasn_data *pasn,
 	}
 #endif /* CONFIG_ENC_ASSOC */
 
+	if (!is_sme_drv) {
+		copy = pasn_prepend_auth_alg(pasn->auth_alg,
+					     wpabuf_head_u8(buf),
+					     wpabuf_len(buf));
+		if (!copy)
+			goto fail;
+		data = copy;
+		data_len = wpabuf_len(buf) + 2;
+		os_free(copy);
+	} else {
+		data = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
+		data_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
+	}
+
 	wpabuf_free(pasn->auth1);
-	pasn->auth1 = wpabuf_alloc_copy(wpabuf_head_u8(buf) + IEEE80211_HDRLEN,
-					wpabuf_len(buf) - IEEE80211_HDRLEN);
+	pasn->auth1 = wpabuf_alloc_copy(data, data_len);
+
 	if (!pasn->auth1) {
 		wpa_printf(MSG_DEBUG, "PASN: Failed to store a copy of Auth1");
 		goto fail;
@@ -696,6 +725,7 @@ fail:
 	wpabuf_free(wrapped_data_buf);
 	wpabuf_free(pubkey);
 	wpabuf_free(buf);
+	os_free(copy);
 	return NULL;
 }
 
@@ -708,7 +738,7 @@ struct wpabuf *wpas_pasn_build_auth_3(struct pasn_data *pasn,
 	u8 mic_len;
 	size_t data_len;
 	const u8 *data;
-	u8 *ptr;
+	u8 *ptr, *copy = NULL;
 	u8 wrapped_data;
 	int ret;
 	u8 hash[SHA512_MAC_LEN];
@@ -770,11 +800,21 @@ struct wpabuf *wpas_pasn_build_auth_3(struct pasn_data *pasn,
 	wpabuf_put_u8(buf, WLAN_EID_MIC);
 	wpabuf_put_u8(buf, mic_len);
 	ptr = wpabuf_put(buf, mic_len);
-
 	os_memset(ptr, 0, mic_len);
 
-	data = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
-	data_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
+	if (!is_sme_drv) {
+		copy = pasn_prepend_auth_alg(pasn->auth_alg,
+					     wpabuf_head_u8(buf), wpabuf_len(buf));
+		if (!copy)
+			goto fail;
+		data = copy;
+		data_len = wpabuf_len(buf) + 2;
+		os_free(copy);
+	} else {
+		data = wpabuf_head_u8(buf) + IEEE80211_HDRLEN;
+		data_len = wpabuf_len(buf) - IEEE80211_HDRLEN;
+	}
+
 
 	if (!pasn->auth1 ||
 	    pasn_auth_frame_hash(pasn->hash_alg, wpabuf_head(pasn->auth1),
@@ -808,6 +848,7 @@ fail:
 	pasn->status = WLAN_STATUS_UNSPECIFIED_FAILURE;
 	wpabuf_free(wrapped_data_buf);
 	wpabuf_free(buf);
+	os_free(copy);
 	return NULL;
 }
 
-- 
2.25.1




More information about the Hostap mailing list