}
+void p2p_usd_service_hash(struct p2p_data *p2p, const char *service_name)
+{
+ u8 buf[P2PS_HASH_LEN];
+
+ p2p->usd_service = false;
+
+ if (!service_name)
+ return;
+
+ if (!p2ps_gen_hash(p2p, service_name, buf))
+ return;
+ p2p_dbg(p2p, "USD service %s hash " MACSTR,
+ service_name, MAC2STR(buf));
+ p2p->usd_service = true;
+ os_memcpy(&p2p->p2p_service_hash, buf, P2PS_HASH_LEN);
+}
+
+
struct wpabuf * p2p_usd_elems(struct p2p_data *p2p)
{
struct wpabuf *buf;
}
+static struct wpabuf * p2p_pasn_service_hash(struct p2p_data *p2p,
+ struct wpabuf *extra_ies)
+{
+ struct wpabuf *buf;
+ u8 *ie_len = NULL;
+
+ if (!p2p->usd_service)
+ return extra_ies;
+
+ p2p_dbg(p2p, "Add P2P2 USD service hash in extra IE");
+ buf = wpabuf_alloc(100);
+ if (!buf) {
+ wpabuf_free(extra_ies);
+ return NULL;
+ }
+
+ ie_len = p2p_buf_add_ie_hdr(buf);
+ p2p_buf_add_usd_service_hash(buf, p2p);
+ p2p_buf_update_ie_hdr(buf, ie_len);
+
+ return wpabuf_concat(buf, extra_ies);
+}
+
+
static struct wpabuf * p2p_pairing_generate_rsnxe(struct p2p_data *p2p,
int akmp)
{
goto out;
}
+ extra_ies = p2p_pasn_service_hash(p2p, extra_ies);
+ if (!extra_ies)
+ goto out;
+
pasn_extra_ies = os_memdup(wpabuf_head_u8(extra_ies),
wpabuf_len(extra_ies));
if (!pasn_extra_ies) {
goto out;
}
+ extra_ies = p2p_pasn_service_hash(p2p, extra_ies);
+ if (!extra_ies)
+ goto out;
+
ies_len = wpabuf_len(extra_ies);
ies = os_memdup(wpabuf_head_u8(extra_ies), ies_len);
if (!ies) {
void p2p_set_store_pasn_ptk(struct p2p_data *p2p, u8 val);
void p2p_pasn_store_ptk(struct p2p_data *p2p, struct wpa_ptk *ptk);
int p2p_pasn_get_ptk(struct p2p_data *p2p, const u8 **buf, size_t *buf_len);
+void p2p_usd_service_hash(struct p2p_data *p2p, const char *service_name);
#endif /* P2P_H */
}
+void p2p_buf_add_usd_service_hash(struct wpabuf *buf, struct p2p_data *p2p)
+{
+ if (!p2p)
+ return;
+
+ /* USD Service Hash */
+ wpabuf_put_u8(buf, P2P_ATTR_SERVICE_HASH);
+ wpabuf_put_le16(buf, P2PS_HASH_LEN);
+ wpabuf_put_data(buf, p2p->p2p_service_hash, P2PS_HASH_LEN);
+ wpa_hexdump(MSG_DEBUG, "P2P: * Service Hash",
+ p2p->p2p_service_hash, P2PS_HASH_LEN);
+}
+
+
void p2p_buf_add_session_info(struct wpabuf *buf, const char *info)
{
size_t info_len = 0;
*/
size_t pasn_ptk_len;
#endif /* CONFIG_TESTING_OPTIONS */
+
+ bool usd_service;
+ u8 p2p_service_hash[P2PS_HASH_LEN];
};
/**
void p2p_pasn_initialize(struct p2p_data *p2p, struct p2p_device *dev,
const u8 *addr, int freq, bool verify,
bool derive_kek);
+void p2p_buf_add_usd_service_hash(struct wpabuf *buf, struct p2p_data *p2p);
void p2p_dbg(struct p2p_data *p2p, const char *fmt, ...)
PRINTF_FORMAT(2, 3);
return -1;
if (p2p) {
- elems = wpas_p2p_usd_elems(wpa_s);
+ elems = wpas_p2p_usd_elems(wpa_s, service_name);
addr = wpa_s->global->p2p_dev_addr;
} else {
addr = wpa_s->own_addr;
return -1;
if (p2p) {
- elems = wpas_p2p_usd_elems(wpa_s);
+ elems = wpas_p2p_usd_elems(wpa_s, service_name);
addr = wpa_s->global->p2p_dev_addr;
} else {
addr = wpa_s->own_addr;
}
-struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s)
+struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s,
+ const char *service_name)
{
struct p2p_data *p2p = wpa_s->global->p2p;
if (wpa_s->global->p2p_disabled || !p2p)
return NULL;
+ p2p_usd_service_hash(p2p, service_name);
return p2p_usd_elems(p2p);
}
unsigned int count);
int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s);
int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s);
-struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s);
+struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s,
+ const char *service_name);
void wpas_p2p_update_dev_addr(struct wpa_supplicant *wpa_s);
int wpas_p2p_pasn_auth_rx(struct wpa_supplicant *wpa_s,
const struct ieee80211_mgmt *mgmt, size_t len,