[RFC PATCH 15/34] API to validate DIRA from USD PR IE

Peddolla Harshavardhan Reddy peddolla at qti.qualcomm.com
Thu May 15 00:17:38 PDT 2025


Signed-off-by: Peddolla Harshavardhan Reddy <peddolla at qti.qualcomm.com>
---
 src/common/proximity_ranging.c | 64 ++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c
index 27b9c2c9b..b2eb42d6b 100644
--- a/src/common/proximity_ranging.c
+++ b/src/common/proximity_ranging.c
@@ -348,6 +348,67 @@ static int pr_derive_dira(struct pr_data *pr, struct pr_dira *dira)
 }
 
 
+static int pr_validate_dira(struct pr_data *pr, struct pr_device *dev,
+			    const u8 *dira, u16 dira_len)
+{
+	int ret;
+	size_t len[3];
+	const u8 *addr[3];
+	struct pr_dev_ik *dev_ik;
+	u8 tag[DEVICE_MAX_HASH_LEN];
+	const char *label = "DIR";
+	const u8 *dira_nonce, *dira_tag;
+
+	if (dira_len < 1 || dira[0] != DIRA_CIPHER_VERSION_128) {
+		wpa_printf(MSG_DEBUG, "Unsupported DIRA cipher version %d",
+			   dira[0]);
+		return -1;
+	}
+
+	if (dira_len < 1 + DEVICE_IDENTITY_NONCE_LEN + DEVICE_IDENTITY_TAG_LEN)
+	{
+		wpa_printf(MSG_DEBUG, "Truncated DIRA (length %u)", dira_len);
+		return -1;
+	}
+
+	dira_nonce = &dira[1];
+	dira_tag = &dira[1 + DEVICE_IDENTITY_NONCE_LEN];
+
+	addr[0] = (const u8 *) label;
+	len[0] = DIR_STR_LEN;
+	addr[1] = dev->pr_device_addr;
+	len[1] = ETH_ALEN;
+	addr[2] = dira_nonce;
+	len[2] = DEVICE_IDENTITY_NONCE_LEN;
+
+	dl_list_for_each(dev_ik, &pr->dev_iks, struct pr_dev_ik, list) {
+		ret = hmac_sha256_vector(dev_ik->dik, DEVICE_IDENTITY_KEY_LEN,
+					 3, addr, len, tag);
+		if (ret < 0) {
+			wpa_printf(MSG_ERROR,
+				   "PR: Failed to derive DIRA Tag");
+			return -1;
+		}
+
+		if (os_memcmp(tag, dira_tag, DEVICE_IDENTITY_TAG_LEN) == 0) {
+			wpa_printf(MSG_DEBUG, "PR: DIRA Tag matched");
+			if (dev_ik->password_valid) {
+				os_strlcpy(dev->password, dev_ik->password,
+					   sizeof(dev->password));
+				dev->password_valid = true;
+			}
+			if (dev_ik->pmk_valid) {
+				os_memcpy(dev->pmk, dev_ik->pmk,
+					  WPA_PASN_PMK_LEN);
+				dev->pmk_valid = true;
+			}
+			return 0;
+		}
+	}
+	return -1;
+}
+
+
 static void pr_buf_add_channel_list(struct wpabuf *buf, const char *country,
 				    struct pr_channels *chan)
 {
@@ -907,5 +968,8 @@ void pr_process_usd_elems(struct pr_data *pr, const u8 *ies, u16 ies_len,
 					    &dev->ntb_caps,
 					    dev->pr_caps.secure_he_ltf);
 
+	if (msg.dira && msg.dira_len)
+		pr_validate_dira(pr, dev, msg.dira, msg.dira_len);
+
 	pr_parse_free(&msg);
 }
-- 
2.34.1




More information about the Hostap mailing list