From: Peddolla Harshavardhan Reddy Date: Sat, 26 Apr 2025 18:27:32 +0000 (+0530) Subject: PR: Derive and add DIRA in USD PR element X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1f516cf6ede62ce495541a1326d6d6020d8d1dd4;p=thirdparty%2Fhostap.git PR: Derive and add DIRA in USD PR element Derive the Device Identity Resolution Attribute (DIRA) and add it to the Proximity Ranging element. The DIRA attribute is used to resolve the identity of a device even when MAC randomization causes the peer device's MAC address to change. The DIRA attribute includes fields such as the cipher version, a nonce, and a tag. Signed-off-by: Peddolla Harshavardhan Reddy --- diff --git a/src/common/proximity_ranging.c b/src/common/proximity_ranging.c index 8eb951eb2..341c0de7c 100644 --- a/src/common/proximity_ranging.c +++ b/src/common/proximity_ranging.c @@ -10,6 +10,7 @@ #include "utils/common.h" #include "common/ieee802_11_defs.h" +#include "crypto/sha256.h" #include "proximity_ranging.h" @@ -223,6 +224,61 @@ static void pr_get_ntb_capabilities(struct pr_data *pr, } +static int pr_derive_dira(struct pr_data *pr, struct pr_dira *dira) +{ + u8 nonce[DEVICE_IDENTITY_NONCE_LEN]; + u8 tag[DEVICE_MAX_HASH_LEN]; + u8 data[DIR_STR_LEN + ETH_ALEN + DEVICE_IDENTITY_NONCE_LEN]; + + if (pr->cfg->dik_cipher != DIRA_CIPHER_VERSION_128) { + wpa_printf(MSG_INFO, "PR: Unsupported DIRA Cipher version %d", + pr->cfg->dik_cipher); + return -1; + } + + if (pr->cfg->dik_len != DEVICE_IDENTITY_KEY_LEN) { + wpa_printf(MSG_INFO, "PR: Invalid DIK length %zu", + pr->cfg->dik_len); + return -1; + } + + os_memset(data, 0, sizeof(data)); + + if (os_get_random(nonce, DEVICE_IDENTITY_NONCE_LEN) < 0) { + wpa_printf(MSG_INFO, "PR: Failed to generate DIRA nonce"); + return -1; + } + + /* Tag = Truncate-64(HMAC-SHA-256(DevIK, "DIR" || PR Device Address || + * Nonce)) + */ + os_memcpy(data, "DIR", DIR_STR_LEN); + os_memcpy(&data[DIR_STR_LEN], pr->cfg->dev_addr, ETH_ALEN); + os_memcpy(&data[DIR_STR_LEN + ETH_ALEN], nonce, + DEVICE_IDENTITY_NONCE_LEN); + + if (hmac_sha256(pr->cfg->dik_data, pr->cfg->dik_len, data, sizeof(data), + tag) < 0) { + wpa_printf(MSG_ERROR, "PR: Could not derive DIRA tag"); + return -1; + } + + os_memset(dira, 0, sizeof(struct pr_dira)); + dira->cipher_version = pr->cfg->dik_cipher; + dira->nonce_len = DEVICE_IDENTITY_NONCE_LEN; + os_memcpy(dira->nonce, nonce, DEVICE_IDENTITY_NONCE_LEN); + dira->tag_len = DEVICE_IDENTITY_TAG_LEN; + os_memcpy(dira->tag, tag, DEVICE_IDENTITY_TAG_LEN); + + wpa_hexdump_key(MSG_DEBUG, "PR: DIK", pr->cfg->dik_data, + pr->cfg->dik_len); + wpa_hexdump(MSG_DEBUG, "PR: DIRA-NONCE", dira->nonce, dira->nonce_len); + wpa_hexdump(MSG_DEBUG, "PR: DIRA-TAG", dira->tag, dira->tag_len); + + return 0; +} + + static void pr_buf_add_channel_list(struct wpabuf *buf, const char *country, const struct pr_channels *chan) { @@ -341,11 +397,35 @@ static void pr_buf_add_ntb_capa_info(struct wpabuf *buf, } +static void pr_buf_add_dira(struct wpabuf *buf, const struct pr_dira *dira) +{ + u8 *len; + size_t _len; + + /* Proximity Ranging Device Identity Resolution attribute */ + wpabuf_put_u8(buf, PR_ATTR_DEVICE_IDENTITY_RESOLUTION); + + /* Length to be filled */ + len = wpabuf_put(buf, 2); + + wpabuf_put_u8(buf, dira->cipher_version); + wpabuf_put_data(buf, dira->nonce, dira->nonce_len); + wpabuf_put_data(buf, dira->tag, dira->tag_len); + + /* Update attribute length */ + _len = (u8 *) wpabuf_put(buf, 0) - len - 2; + WPA_PUT_LE16(len, _len); + + wpa_printf(MSG_DEBUG, "PR: * DIRA"); +} + + struct wpabuf * pr_prepare_usd_elems(struct pr_data *pr) { u32 ie_type; struct wpabuf *buf, *buf2; struct pr_capabilities pr_caps; + struct pr_dira dira; buf = wpabuf_alloc(1000); if (!buf) @@ -368,6 +448,9 @@ struct wpabuf * pr_prepare_usd_elems(struct pr_data *pr) pr_buf_add_ntb_capa_info(buf, &ntb_caps); } + if (!pr_derive_dira(pr, &dira)) + pr_buf_add_dira(buf, &dira); + ie_type = (OUI_WFA << 8) | PR_OUI_TYPE; buf2 = pr_encaps_elem(buf, ie_type); wpabuf_free(buf); diff --git a/src/common/proximity_ranging.h b/src/common/proximity_ranging.h index 45ae998fc..b05dc54c7 100644 --- a/src/common/proximity_ranging.h +++ b/src/common/proximity_ranging.h @@ -13,6 +13,13 @@ #include "wps/wps_defs.h" #define DEVICE_IDENTITY_KEY_LEN 16 +#define DEVICE_IDENTITY_TAG_LEN 8 +#define DEVICE_IDENTITY_NONCE_LEN 8 +#define DIR_STR_LEN 3 +#define DEVICE_MAX_HASH_LEN 32 + +/* DIRA Cipher versions */ +#define DIRA_CIPHER_VERSION_128 0 /** * PR_MAX_OP_CLASSES - Maximum number of operating classes @@ -317,6 +324,20 @@ struct pr_data { struct dl_list devices; }; +/* PR Device Identity Resolution Attribute parameters */ +struct pr_dira { + /* Cipher version type */ + int cipher_version; + /* Nonce used in DIRA attribute */ + u8 nonce[DEVICE_IDENTITY_NONCE_LEN]; + /* Length of nonce */ + size_t nonce_len; + /* Tag computed for nonce using NIK */ + u8 tag[DEVICE_IDENTITY_TAG_LEN]; + /* Length of tag in octets */ + size_t tag_len; +}; + struct pr_data * pr_init(const struct pr_config *cfg); void pr_deinit(struct pr_data *pr); struct wpabuf * pr_prepare_usd_elems(struct pr_data *pr);