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

Peddolla Harshavardhan Reddy peddolla at qti.qualcomm.com
Thu Jun 19 08:37:08 PDT 2025


Add changes to parse and validate the Device Identity Resolution
Attribute (DIRA). The tag is derived using each DIK in the list
stored in the global Proximity Ranging context, along with the
nonce from the DIRA and the device address.

The derived tag is then compared with the tag present in the
DIRA. If the tags match, the device identity is confirmed, and
any data associated with the matching DIK is retrieved for
later use.

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 1feeaede8..11693dc5d 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)
 {
@@ -905,5 +966,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