[PATCH v3 04/25] P2P: Add DIRA attributes to P2P2 IE of NAN SDFs
Shivani Baranwal
quic_shivbara at quicinc.com
Mon Aug 5 02:33:02 PDT 2024
Add DIRA attribute in P2P2 IE of NAN Subscribe and Publish frames
to enable support for Device identity of paired peers.
Signed-off-by: Shivani Baranwal <quic_shivbara at quicinc.com>
---
src/p2p/p2p.c | 10 ++++++
src/p2p/p2p.h | 18 +++++++++++
src/p2p/p2p_build.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/p2p/p2p_i.h | 25 +++++++++++++++
4 files changed, 141 insertions(+)
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 2f9482a..73fcb16 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -2987,6 +2987,13 @@ int p2p_pairing_info_init(struct p2p_data *p2p)
pairing_info->supported_bootstrap =
p2p->cfg->pairing_config.bootstrap_methods;
+ pairing_info->dev_ik.cipher_version =
+ p2p->cfg->pairing_config.dik_cipher;
+ pairing_info->dev_ik.dik_len =
+ p2p->cfg->pairing_config.dik_len;
+ os_memcpy(pairing_info->dev_ik.dik_data,
+ p2p->cfg->pairing_config.dik_data,
+ p2p->cfg->pairing_config.dik_len);
p2p->pairing_info = pairing_info;
return 0;
@@ -5760,6 +5767,9 @@ struct wpabuf * p2p_usd_elems(struct p2p_data *p2p)
p2p_buf_add_pbma(buf, p2p->cfg->pairing_config.bootstrap_methods, NULL,
0, 0);
+ /* P2P Device Identity Resolution attribute */
+ p2p_buf_add_dira(buf, p2p);
+
p2p_buf_update_p2p2_ie_hdr(buf, len);
return buf;
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 700f839..b7d05e9 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -12,6 +12,16 @@
#include "common/ieee802_11_defs.h"
#include "wps/wps.h"
+#define DEVICE_IDENTITY_KEY_MAX_LEN 64
+#define DEVICE_IDENTITY_KEY_LEN 16
+#define DEVICE_IDENTITY_TAG_LEN 8
+#define DEVICE_IDENTITY_NONCE_LEN 8
+#define DEVICE_MAX_HASH_LEN 32
+#define DIR_STR_LEN 3
+
+/* DIRA Cipher versions */
+#define DIRA_CIPHER_VERSION_128 0
+
struct weighted_pcl;
/* P2P ASP Setup Capability */
@@ -354,6 +364,14 @@ struct p2p_pairing_config {
*/
u8 pasn_type;
+ /* cipher version type */
+ int dik_cipher;
+
+ /* buffer to hold the DevIK */
+ u8 dik_data[DEVICE_IDENTITY_KEY_MAX_LEN];
+
+ /* length of DevIK */
+ size_t dik_len;
};
diff --git a/src/p2p/p2p_build.c b/src/p2p/p2p_build.c
index 4bdfb7e..347e8a1 100644
--- a/src/p2p/p2p_build.c
+++ b/src/p2p/p2p_build.c
@@ -12,6 +12,8 @@
#include "common/ieee802_11_defs.h"
#include "common/ieee802_11_common.h"
#include "common/qca-vendor.h"
+#include "crypto/random.h"
+#include "crypto/sha256.h"
#include "wps/wps_i.h"
#include "p2p_i.h"
@@ -803,6 +805,92 @@ void p2p_buf_add_pbma(struct wpabuf *buf, u16 bootstrap, const u8 *cookie,
bootstrap);
}
+static int p2p_derive_nonce_tag(struct p2p_data *p2p)
+{
+ int ret;
+ u8 dira_nonce[DEVICE_IDENTITY_NONCE_LEN];
+ u8 dira_tag[DEVICE_MAX_HASH_LEN];
+ u8 data[DIR_STR_LEN + DEVICE_IDENTITY_NONCE_LEN + ETH_ALEN];
+ struct p2p_id_key *dev_ik;
+
+ dev_ik = &p2p->pairing_info->dev_ik;
+
+ if (dev_ik->cipher_version != DIRA_CIPHER_VERSION_128) {
+ wpa_printf(MSG_ERROR, "Unsupported DIRA Cipher version = %d",
+ dev_ik->cipher_version);
+ return -1;
+ }
+
+ if (dev_ik->dik_len != DEVICE_IDENTITY_KEY_LEN) {
+ wpa_printf(MSG_ERROR, "Invalid DIK length = %ld",
+ dev_ik->dik_len);
+ return -1;
+ }
+
+ os_memset(data, 0, sizeof(data));
+ os_memset(dira_tag, 0, sizeof(dira_tag));
+
+ ret = random_get_bytes(dira_nonce, DEVICE_IDENTITY_NONCE_LEN);
+ if (ret < 0) {
+ wpa_printf(MSG_ERROR, "Get DIRA nonce Failed, err = %d", ret);
+ return -1;
+ }
+
+ os_memcpy(data, "DIR", DIR_STR_LEN);
+ os_memcpy(&data[DIR_STR_LEN], p2p->cfg->dev_addr, ETH_ALEN);
+ os_memcpy(&data[DIR_STR_LEN + ETH_ALEN], dira_nonce,
+ DEVICE_IDENTITY_NONCE_LEN);
+
+ ret = hmac_sha256(dev_ik->dik_data, dev_ik->dik_len, data, sizeof(data),
+ dira_tag);
+ if (ret < 0) {
+ wpa_printf(MSG_ERROR, "Could not derive DIRA tag, err = %d", ret);
+ return -1;
+ }
+
+ dev_ik->dira_nonce_len = DEVICE_IDENTITY_NONCE_LEN;
+ os_memcpy(dev_ik->dira_nonce, dira_nonce, DEVICE_IDENTITY_NONCE_LEN);
+ dev_ik->dira_tag_len = DEVICE_IDENTITY_TAG_LEN;
+ os_memcpy(dev_ik->dira_tag, dira_tag, DEVICE_IDENTITY_TAG_LEN);
+
+ wpa_hexdump_key(MSG_DEBUG, "P2P: DIK", dev_ik->dik_data,
+ dev_ik->dik_len);
+ wpa_hexdump_key(MSG_DEBUG, "P2P: DIRA-NONCE", dev_ik->dira_nonce,
+ dev_ik->dira_nonce_len);
+ wpa_hexdump_key(MSG_DEBUG, "P2P: DIRA-TAG", dev_ik->dira_tag,
+ dev_ik->dira_tag_len);
+ return 0;
+}
+
+void p2p_buf_add_dira(struct wpabuf *buf, struct p2p_data *p2p)
+{
+ u8 *len;
+ struct p2p_id_key *dev_ik;
+
+ if (!p2p->cfg->pairing_config.pairing_capable ||
+ !p2p->cfg->pairing_config.enable_pairing_cache ||
+ !p2p->cfg->pairing_config.enable_pairing_verification)
+ return;
+
+ if (p2p_derive_nonce_tag(p2p))
+ return;
+
+ dev_ik = &p2p->pairing_info->dev_ik;
+ /* P2P DIRA */
+ wpabuf_put_u8(buf, P2P_ATTR_DEVICE_IDENTITY_RESOLUTION);
+ /* Length to be filled */
+ len = wpabuf_put(buf, 2);
+
+ wpabuf_put_u8(buf, dev_ik->cipher_version);
+ wpabuf_put_data(buf, dev_ik->dira_nonce, dev_ik->dira_nonce_len);
+ wpabuf_put_data(buf, dev_ik->dira_tag, dev_ik->dira_tag_len);
+
+ /* Update attribute length */
+ WPA_PUT_LE16(len, (u8 *)wpabuf_put(buf, 0) - len - 2);
+
+ wpa_printf(MSG_DEBUG, "P2P: * Added DIRA");
+}
+
static int p2p_add_wps_string(struct wpabuf *buf, enum wps_attribute attr,
const char *val)
{
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 381a02e..0879add 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -161,6 +161,28 @@ struct p2p_sd_query {
};
+/* This is p2p device identity key params */
+struct p2p_id_key {
+ /* AKMP used for DevIK derviation */
+ int akmp;
+ /* cipher version type */
+ int cipher_version;
+ /* DevIK expiration time in seconds */
+ u32 expiration;
+ /* buffer to hold the DevIK */
+ u8 dik_data[DEVICE_IDENTITY_KEY_MAX_LEN];
+ /* length of DevIK */
+ size_t dik_len;
+ /* nonce used in DIRA attribute */
+ u8 dira_nonce[DEVICE_IDENTITY_NONCE_LEN];
+ /* length of nonce */
+ size_t dira_nonce_len;
+ /* tag computed for nonce using NIK */
+ u8 dira_tag[DEVICE_IDENTITY_TAG_LEN];
+ /* length of tag */
+ size_t dira_tag_len;
+};
+
struct p2p_pairing_info {
/* P2P device own address */
u8 own_addr[ETH_ALEN];
@@ -170,6 +192,8 @@ struct p2p_pairing_info {
u32 enable_pairing_cache;
/* device supported bootstrapping */
u16 supported_bootstrap;
+ /* p2p device identity key info */
+ struct p2p_id_key dev_ik;
};
/**
@@ -807,6 +831,7 @@ void p2p_buf_add_persistent_group_info(struct wpabuf *buf, const u8 *dev_addr,
void p2p_buf_add_pcea(struct wpabuf *buf, struct p2p_data *p2p);
void p2p_buf_add_pbma(struct wpabuf *buf, u16 bootstrap, const u8 *cookie,
size_t cookie_len, int comeback_after);
+void p2p_buf_add_dira(struct wpabuf *buf, struct p2p_data *p2p);
int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
int all_attr);
void p2p_buf_add_pref_channel_list(struct wpabuf *buf,
--
2.7.4
More information about the Hostap
mailing list