From patchwork Mon Jul 8 09:32:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shivani Baranwal X-Patchwork-Id: 1957864 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=A8P541S4; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=quicinc.com header.i=@quicinc.com header.a=rsa-sha256 header.s=qcppdkim1 header.b=jTwZ0XHD; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WHfDw6YCHz1xpd for ; Mon, 8 Jul 2024 19:38:08 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Kusuo58J58Tou1GDjIJq0IegmDZ5oFGj5Y9GvffJAo4=; b=A8P541S4xyJt9L Z9kfxrECxXSBsuRz9q1JmUygdPlPuE3uYlc7EXoRZk8UDvr0svcQmq0fNMFQY4gOoRTF5Fx5oMWm0 bCh+868fnr+GEDUQo40hPkeliWv9icPHvBGLFOSjcFcKPyoTxTKCL/R/q6YpbdK3MAUDrlRaiwj3W LAx9lmyL++tibpD31dtialUzk7X4gIu27oh/03WF/t0ko7TJEJVAMdk2P+3E9dwFpII58oMDWfRb1 AMaQJ+3gH6whkvYN71Vn2UdXaPVzVX8J2wW6MN837ln5/Tf6Ge/EcBMa6nUyFqL/mFpu+pjZab9uB hoiqfW1gwKlQdk04cdCg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sQkoT-00000003ISe-3PxB; Mon, 08 Jul 2024 09:37:37 +0000 Received: from mx0a-0031df01.pphosted.com ([205.220.168.131]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sQkoO-00000003IQK-2FqW for hostap@lists.infradead.org; Mon, 08 Jul 2024 09:37:35 +0000 Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 467NkU85004363 for ; Mon, 8 Jul 2024 09:37:32 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h= cc:content-type:date:from:in-reply-to:message-id:mime-version :references:subject:to; s=qcppdkim1; bh=narADC/X0GwY94/zZkc1JgCz 4EN3T1KTfAY00ZN/kK4=; b=jTwZ0XHD5NaH8GTGdD2G/89TnYvUMaahlkRz4DJ9 IiVn1zhAsiJPNG/l1FduXEOJ0fDgSfW325NRkaHxd1EJdqiKEGHhCqc6F3R0esP6 orspU37Laq0qf3ADL4l2wsnYJ/EGBfjMXRWLZEswEWZdLFe4DXeKZ3YwXP5uY6g/ aGc0Crmv33JmX8LcHZ+iuEgOg4ijLLf4oPnIc/KgiiJOMd42M2M4FCYOzcRUGLyI nOUzymonz1pW7qWdfYDMs6pz6wk/6RCqPMyatgI+jSX5NB1E0w8fgdXUUvF+nUtY QVZVUmDR30YK/whXRG8GzBuo5fqqhQEOCClx9UbDE1UfPA== Received: from nalasppmta03.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 406x5135n3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 08 Jul 2024 09:37:31 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA03.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 4689bVuJ018767 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 8 Jul 2024 09:37:31 GMT Received: from hu-shivbara-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.9; Mon, 8 Jul 2024 02:37:29 -0700 From: Shivani Baranwal To: CC: Subject: [PATCH 03/13] P2P: Allow P2P IE to be added into NAN SDFs Date: Mon, 8 Jul 2024 15:02:19 +0530 Message-ID: <1720431149-7494-3-git-send-email-quic_shivbara@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1720431149-7494-1-git-send-email-quic_shivbara@quicinc.com> References: <1720431149-7494-1-git-send-email-quic_shivbara@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nalasex01a.na.qualcomm.com (10.47.209.196) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: scwcV5LAc7Pi7dzne34Mn3-I6OTucict X-Proofpoint-ORIG-GUID: scwcV5LAc7Pi7dzne34Mn3-I6OTucict X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16 definitions=2024-07-08_04,2024-07-05_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 suspectscore=0 impostorscore=0 mlxlogscore=999 mlxscore=0 bulkscore=0 priorityscore=1501 malwarescore=0 lowpriorityscore=0 phishscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2406140001 definitions=main-2407080075 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240708_023732_659229_8E3DAC09 X-CRM114-Status: GOOD ( 21.86 ) X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Extend the NAN Subscribe and Publish methods to allow p2p=1 to be specified to include P2P attributes in a P2P IE to be added into the NAN Element Container attribute. Signed-off-by: Shivani Baranwal Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Extend the NAN Subscribe and Publish methods to allow p2p=1 to be specified to include P2P attributes in a P2P IE to be added into the NAN Element Container attribute. Signed-off-by: Shivani Baranwal diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 92df81c6c..2fb5f6960 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -3690,6 +3690,7 @@ static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd, struct wpabuf *ssi = NULL; int ret = -1; enum nan_service_protocol_type srv_proto_type = 0; + bool p2p = false; os_memset(¶ms, 0, sizeof(params)); /* USD shall use both solicited and unsolicited transmissions */ @@ -3723,6 +3724,11 @@ static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd, continue; } + if (os_strcmp(token, "p2p=1") == 0) { + p2p = true; + continue; + } + if (os_strcmp(token, "solicited=0") == 0) { params.solicited = false; continue; @@ -3744,7 +3750,7 @@ static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd, } publish_id = hostapd_nan_usd_publish(hapd, service_name, srv_proto_type, - ssi, ¶ms); + ssi, ¶ms, p2p); if (publish_id > 0) ret = os_snprintf(buf, buflen, "%d", publish_id); fail: @@ -3827,6 +3833,7 @@ static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd, struct wpabuf *ssi = NULL; int ret = -1; enum nan_service_protocol_type srv_proto_type = 0; + bool p2p = false; os_memset(¶ms, 0, sizeof(params)); @@ -3860,6 +3867,11 @@ static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd, continue; } + if (os_strcmp(token, "p2p=1") == 0) { + p2p = true; + continue; + } + wpa_printf(MSG_INFO, "CTRL: Invalid NAN_SUBSCRIBE parameter: %s", token); @@ -3868,7 +3880,7 @@ static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd, subscribe_id = hostapd_nan_usd_subscribe(hapd, service_name, srv_proto_type, ssi, - ¶ms); + ¶ms, p2p); if (subscribe_id > 0) ret = os_snprintf(buf, buflen, "%d", subscribe_id); fail: diff --git a/src/ap/nan_usd_ap.c b/src/ap/nan_usd_ap.c index 70c6139fd..570abfce0 100644 --- a/src/ap/nan_usd_ap.c +++ b/src/ap/nan_usd_ap.c @@ -192,7 +192,7 @@ void hostapd_nan_usd_flush(struct hostapd_data *hapd) int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_publish_params *params) + struct nan_publish_params *params, bool p2p) { int publish_id; struct wpabuf *elems = NULL; @@ -201,7 +201,7 @@ int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name, return -1; publish_id = nan_de_publish(hapd->nan_de, service_name, srv_proto_type, - ssi, elems, params); + ssi, elems, params, p2p); wpabuf_free(elems); return publish_id; } @@ -231,7 +231,7 @@ int hostapd_nan_usd_subscribe(struct hostapd_data *hapd, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_subscribe_params *params) + struct nan_subscribe_params *params, bool p2p) { int subscribe_id; struct wpabuf *elems = NULL; @@ -240,7 +240,7 @@ int hostapd_nan_usd_subscribe(struct hostapd_data *hapd, return -1; subscribe_id = nan_de_subscribe(hapd->nan_de, service_name, - srv_proto_type, ssi, elems, params); + srv_proto_type, ssi, elems, params, p2p); wpabuf_free(elems); return subscribe_id; } diff --git a/src/ap/nan_usd_ap.h b/src/ap/nan_usd_ap.h index 58ff5fc48..0571643c6 100644 --- a/src/ap/nan_usd_ap.h +++ b/src/ap/nan_usd_ap.h @@ -21,7 +21,7 @@ void hostapd_nan_usd_flush(struct hostapd_data *hapd); int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_publish_params *params); + struct nan_publish_params *params, bool p2p); void hostapd_nan_usd_cancel_publish(struct hostapd_data *hapd, int publish_id); int hostapd_nan_usd_update_publish(struct hostapd_data *hapd, int publish_id, const struct wpabuf *ssi); @@ -29,7 +29,7 @@ int hostapd_nan_usd_subscribe(struct hostapd_data *hapd, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_subscribe_params *params); + struct nan_subscribe_params *params, bool p2p); void hostapd_nan_usd_cancel_subscribe(struct hostapd_data *hapd, int subscribe_id); int hostapd_nan_usd_transmit(struct hostapd_data *hapd, int handle, diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 0fe631026..578ea73a1 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -1425,6 +1425,7 @@ struct ieee80211_ampe_ie { #define WPS_IE_VENDOR_TYPE 0x0050f204 #define OUI_WFA 0x506f9a #define P2P_IE_VENDOR_TYPE 0x506f9a09 +#define P2P2_IE_VENDOR_TYPE 0x506f9a28 #define WFD_IE_VENDOR_TYPE 0x506f9a0a #define WFD_OUI_TYPE 10 #define HS20_IE_VENDOR_TYPE 0x506f9a10 @@ -1740,6 +1741,12 @@ enum p2p_attr_id { P2P_ATTR_SESSION_ID = 26, P2P_ATTR_FEATURE_CAPABILITY = 27, P2P_ATTR_PERSISTENT_GROUP = 28, + P2P_ATTR_CAPABILITY_EXTENSION = 29, + P2P_ATTR_DEVICE_IDENTITY_KEY = 31, + P2P_ATTR_DEVICE_IDENTITY_RESOLUTION = 32, + P2P_ATTR_PAIRING_AND_BOOTSTRAPPING = 33, + P2P_ATTR_PASSWORD = 34, + P2P_ATTR_ACTION_FRAME_WRAPPER = 35, P2P_ATTR_VENDOR_SPECIFIC = 221 }; @@ -1764,6 +1771,18 @@ enum p2p_attr_id { #define P2P_GROUP_CAPAB_GROUP_FORMATION BIT(6) #define P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION BIT(7) +/* P2P Capability Extension attribute - Capability info */ +#define P2P_PCEA_LEN_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) +#define P2P_PCEA_6GHZ BIT(4) +#define P2P_PCEA_REG_INFO BIT(5) +#define P2P_PCEA_DFS_OWNER BIT(6) +#define P2P_PCEA_CLI_REQ_CS BIT(7) +#define P2P_PCEA_PAIRING_CAPABLE BIT(8) +#define P2P_PCEA_PAIRING_SETUP_ENABLE BIT(9) +#define P2P_PCEA_PMK_CACHING BIT(10) +#define P2P_PCEA_PASN_TYPE BIT(11) +#define P2P_PCEA_TWT_POWER_MGMT BIT(12) + /* P2PS Coordination Protocol Transport Bitmap */ #define P2PS_FEATURE_CAPAB_UDP_TRANSPORT BIT(0) #define P2PS_FEATURE_CAPAB_MAC_TRANSPORT BIT(1) diff --git a/src/common/nan_de.c b/src/common/nan_de.c index ecc73c5fd..7017311b6 100644 --- a/src/common/nan_de.c +++ b/src/common/nan_de.c @@ -58,6 +58,7 @@ struct nan_de_service { struct os_reltime next_publish_state; struct os_reltime next_publish_chan; unsigned int next_publish_duration; + bool is_p2p; }; struct nan_de { @@ -1215,7 +1216,7 @@ const u8 * nan_de_get_service_id(struct nan_de *de, int id) int nan_de_publish(struct nan_de *de, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, const struct wpabuf *elems, - struct nan_publish_params *params) + struct nan_publish_params *params, bool p2p) { int publish_id; struct nan_de_service *srv; @@ -1271,6 +1272,7 @@ int nan_de_publish(struct nan_de *de, const char *service_name, wpa_printf(MSG_DEBUG, "NAN: Assigned new publish handle %d for %s", publish_id, service_name); srv->id = publish_id; + srv->is_p2p = p2p; nan_de_add_srv(de, srv); nan_de_run_timer(de); return publish_id; @@ -1322,7 +1324,7 @@ int nan_de_update_publish(struct nan_de *de, int publish_id, int nan_de_subscribe(struct nan_de *de, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, const struct wpabuf *elems, - struct nan_subscribe_params *params) + struct nan_subscribe_params *params, bool p2p) { int subscribe_id; struct nan_de_service *srv; @@ -1362,6 +1364,7 @@ int nan_de_subscribe(struct nan_de *de, const char *service_name, wpa_printf(MSG_DEBUG, "NAN: Assigned new subscribe handle %d for %s", subscribe_id, service_name); srv->id = subscribe_id; + srv->is_p2p = p2p; nan_de_add_srv(de, srv); nan_de_run_timer(de); return subscribe_id; diff --git a/src/common/nan_de.h b/src/common/nan_de.h index ae77cf399..bdac284b4 100644 --- a/src/common/nan_de.h +++ b/src/common/nan_de.h @@ -106,7 +106,7 @@ struct nan_publish_params { int nan_de_publish(struct nan_de *de, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, const struct wpabuf *elems, - struct nan_publish_params *params); + struct nan_publish_params *params, bool p2p); void nan_de_cancel_publish(struct nan_de *de, int publish_id); @@ -133,7 +133,7 @@ struct nan_subscribe_params { int nan_de_subscribe(struct nan_de *de, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, const struct wpabuf *elems, - struct nan_subscribe_params *params); + struct nan_subscribe_params *params, bool p2p); void nan_de_cancel_subscribe(struct nan_de *de, int subscribe_id); diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 8e0fc35df..a2d09624d 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -16,6 +16,7 @@ #include "common/wpa_ctrl.h" #include "crypto/sha256.h" #include "crypto/crypto.h" +#include "crypto/random.h" #include "wps/wps_i.h" #include "p2p_i.h" #include "p2p.h" @@ -2967,6 +2968,37 @@ bool is_p2p_6ghz_disabled(struct p2p_data *p2p) return false; } +int p2p_pairing_info_init(struct p2p_data *p2p) +{ + struct p2p_pairing_info *pairing_info; + + if (!p2p) { + p2p_dbg(p2p, "P2P data NULL"); + return -1; + } + + pairing_info = os_zalloc(sizeof(struct p2p_pairing_info)); + if (!pairing_info) + return -1; + + pairing_info->enable_pairing_setup = + p2p->cfg->pairing_config.enable_pairing_setup; + pairing_info->enable_pairing_cache = + p2p->cfg->pairing_config.enable_pairing_cache; + pairing_info->supported_bootstrap = + p2p->cfg->pairing_config.bootstrap_methods; + + /* TODO: Add support to fetch DIK from p2p_supplicant.conf + * DIK should be same across device reboots + */ + pairing_info->dev_ik.cipher_version = DIRA_CIPHER_VERSION_128; + pairing_info->dev_ik.dik_len = DEVICE_IDENTITY_KEY_LEN; + random_get_bytes(pairing_info->dev_ik.dik_data, + pairing_info->dev_ik.dik_len); + p2p->pairing_info = pairing_info; + + return 0; +} struct p2p_data * p2p_init(const struct p2p_config *cfg) { @@ -3023,6 +3055,7 @@ struct p2p_data * p2p_init(const struct p2p_config *cfg) p2p->go_timeout = 100; p2p->client_timeout = 20; p2p->num_p2p_sd_queries = 0; + p2p_pairing_info_init(p2p); p2p_dbg(p2p, "initialized"); p2p_channels_dump(p2p, "channels", &p2p->cfg->channels); @@ -3031,6 +3064,10 @@ struct p2p_data * p2p_init(const struct p2p_config *cfg) return p2p; } +void p2p_pairing_info_deinit(struct p2p_data *p2p) +{ + os_free(p2p->pairing_info); +} void p2p_deinit(struct p2p_data *p2p) { @@ -3066,6 +3103,7 @@ void p2p_deinit(struct p2p_data *p2p) p2p_remove_wps_vendor_extensions(p2p); os_free(p2p->no_go_freq.range); p2p_service_flush_asp(p2p); + p2p_pairing_info_deinit(p2p); os_free(p2p); } @@ -5688,3 +5726,52 @@ void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value) { p2p->allow_6ghz = value; } + + +struct wpabuf * p2p_usd_elems(struct p2p_data *p2p) +{ + struct wpabuf *buf; + u8 *len; + u8 group_capab; + + buf = wpabuf_alloc(1000); + if (!buf) + return NULL; + + len = p2p_buf_add_ie_hdr(buf); + + /* P2P Capability attribute */ + group_capab = 0; + if (p2p->num_groups) { + group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER; + if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && + (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) && + p2p->cross_connect) + group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; + } + if (p2p->cfg->p2p_intra_bss) + group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST; + p2p_buf_add_capability(buf, p2p->dev_capab & + ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, + group_capab); + + /* P2P Device Info attribute */ + p2p_buf_add_device_info(buf, p2p, NULL); + + p2p_buf_update_ie_hdr(buf, len); + + len = p2p_buf_add_p2p2_ie_hdr(buf); + /* P2P Capability Extension attribute */ + p2p_buf_add_pcea(buf, p2p); + + /* P2P Pairing Bootstrapping Method attribute */ + 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 27bdac3bf..67124e3c9 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -320,6 +320,42 @@ enum p2p_scan_type { #define P2P_MAX_WPS_VENDOR_EXT 10 +/** + * struct p2p_pairing_config - P2P pairing config. + */ +struct p2p_pairing_config { + /** + * Pairing capable + */ + u8 pairing_capable; + + /** + * Enable P2P pairing setup + */ + u32 enable_pairing_setup; + + /** + * Enable pairing cache to allow verification + */ + u32 enable_pairing_cache; + + /** + * Enable P2P pairing verification with cached NIK/NPK + */ + u32 enable_pairing_verification; + + /** + * P2P bootstrapping methods supported + */ + u16 bootstrap_methods; + + /** + * The set of supported PASN type + */ + u8 pasn_type; +}; + + /** * struct p2p_peer_info - P2P peer information */ @@ -589,6 +625,31 @@ struct p2p_config { */ unsigned int passphrase_len; + /** + * p2p_pairing_config - P2P Pairing configuration + */ + struct p2p_pairing_config pairing_config; + + /** + * p2p_6ghz_enable - 6GHz enable for P2P operations + */ + bool p2p_6ghz_enable; + + /** + * reg_info - regulatory info encoding for operation in 6 GHz band + */ + u8 reg_info; + + /** + * dfs_owner - Enable p2p GO to act as DFS Owner + */ + bool dfs_owner; + + /** + * twt_power_mgmt - Enable TWT based power mgmt for P2P + */ + bool twt_power_mgmt; + /** * cb_ctx - Context to use with callback functions */ @@ -2429,5 +2490,6 @@ bool is_p2p_allow_6ghz(struct p2p_data *p2p); void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value); int p2p_remove_6ghz_channels(struct weighted_pcl *pref_freq_list, int size); int p2p_channel_to_freq(int op_class, int channel); +struct wpabuf * p2p_usd_elems(struct p2p_data *p2p); #endif /* P2P_H */ diff --git a/src/p2p/p2p_build.c b/src/p2p/p2p_build.c index e4f40fe8f..641f9dd47 100644 --- a/src/p2p/p2p_build.c +++ b/src/p2p/p2p_build.c @@ -12,10 +12,11 @@ #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" - void p2p_buf_add_action_hdr(struct wpabuf *buf, u8 subtype, u8 dialog_token) { wpabuf_put_u8(buf, WLAN_ACTION_VENDOR_SPECIFIC); @@ -59,6 +60,24 @@ void p2p_buf_update_ie_hdr(struct wpabuf *buf, u8 *len) *len = (u8 *) wpabuf_put(buf, 0) - len - 1; } +u8 * p2p_buf_add_p2p2_ie_hdr(struct wpabuf *buf) +{ + u8 *len; + + /* P2P2 IE header */ + wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); + len = wpabuf_put(buf, 1); /* IE length to be filled */ + wpabuf_put_be32(buf, P2P2_IE_VENDOR_TYPE); + wpa_printf(MSG_DEBUG, "P2P: * P2P2 IE header"); + return len; +} + + +void p2p_buf_update_p2p2_ie_hdr(struct wpabuf *buf, u8 *len) +{ + /* Update P2P2 IE Length */ + *len = (u8 *) wpabuf_put(buf, 0) - len - 1; +} void p2p_buf_add_capability(struct wpabuf *buf, u8 dev_capab, u8 group_capab) { @@ -709,6 +728,167 @@ 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) +{ + u8 *len; + u16 capability_info = 0; + + /* P2P Capability Extension */ + wpabuf_put_u8(buf, P2P_ATTR_CAPABILITY_EXTENSION); + /* Length to be filled */ + len = wpabuf_put(buf, 2); + + if (p2p->cfg->p2p_6ghz_enable) + capability_info |= P2P_PCEA_6GHZ; + + if (p2p->cfg->reg_info) + capability_info |= P2P_PCEA_REG_INFO; + + if (p2p->cfg->dfs_owner) + capability_info |= P2P_PCEA_DFS_OWNER; + + if (p2p->cfg->pairing_config.pairing_capable) + capability_info |= P2P_PCEA_PAIRING_CAPABLE; + + if (p2p->cfg->pairing_config.enable_pairing_setup) + capability_info |= P2P_PCEA_PAIRING_SETUP_ENABLE; + + if (p2p->cfg->pairing_config.enable_pairing_cache) + capability_info |= P2P_PCEA_PMK_CACHING; + + if (p2p->cfg->pairing_config.pasn_type) + capability_info |= P2P_PCEA_PASN_TYPE; + + if (p2p->cfg->twt_power_mgmt) + capability_info |= P2P_PCEA_TWT_POWER_MGMT; + + /* Field length is (n-1), n in octets */ + capability_info |= (2 - 1) & P2P_PCEA_LEN_MASK; + wpabuf_put_le16(buf, capability_info); + + if (capability_info & P2P_PCEA_REG_INFO) + wpabuf_put_u8(buf, p2p->cfg->reg_info); + + if (capability_info & P2P_PCEA_PASN_TYPE) + wpabuf_put_u8(buf, p2p->cfg->pairing_config.pasn_type); + + /* Update attribute length */ + WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2); + + wpa_printf(MSG_DEBUG, "P2P: * Capability Extension info=0x%x", + capability_info); +} + +void p2p_buf_add_pbma(struct wpabuf *buf, u16 bootstrap, const u8 *cookie, + size_t cookie_len, int comeback_after) +{ + u8 *len; + + if (!bootstrap) + return; + + /* P2P Pairing and Bootstrapping methods */ + wpabuf_put_u8(buf, P2P_ATTR_PAIRING_AND_BOOTSTRAPPING); + /* Length to be filled */ + len = wpabuf_put(buf, 2); + + if (cookie && cookie_len) { + if (comeback_after) + wpabuf_put_le16(buf, comeback_after); + wpabuf_put_u8(buf, cookie_len); + wpabuf_put_data(buf, cookie, cookie_len); + } + wpabuf_put_le16(buf, bootstrap); + + /* Update attribute length */ + WPA_PUT_LE16(len, (u8 *) wpabuf_put(buf, 0) - len - 2); + + wpa_printf(MSG_DEBUG, "P2P: * Bootstrapping method=0x%x", + 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; + } + + if (dev_ik->dira_nonce_len && dev_ik->dira_tag_len) + return 0; + + 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, DEVICE_IDENTITY_KEY_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); + 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 0a487e031..0e24e51ab 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -14,6 +14,11 @@ #include "p2p.h" #define P2P_GO_NEG_CNF_MAX_RETRY_COUNT 1 +#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 /* * A threshold (in seconds) to prefer a direct Probe Response frame from a P2P @@ -160,6 +165,44 @@ struct p2p_sd_query { struct wpabuf *tlvs; }; +/* DIRA Cipher versions */ +#define DIRA_CIPHER_VERSION_128 0 + +/* 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_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]; + /* device capability to enable pairing setup */ + u32 enable_pairing_setup; + /* device capability to enable pairing cache */ + u32 enable_pairing_cache; + /* device supported bootstrapping */ + u16 supported_bootstrap; + /* p2p device identity key info */ + struct p2p_id_key dev_ik; +}; + /** * struct p2p_data - P2P module data (internal to P2P module) */ @@ -554,6 +597,8 @@ struct p2p_data { bool p2p_6ghz_capable; bool include_6ghz; bool allow_6ghz; + + struct p2p_pairing_info *pairing_info; }; /** @@ -748,11 +793,13 @@ void p2p_buf_add_action_hdr(struct wpabuf *buf, u8 subtype, u8 dialog_token); void p2p_buf_add_public_action_hdr(struct wpabuf *buf, u8 subtype, u8 dialog_token); u8 * p2p_buf_add_ie_hdr(struct wpabuf *buf); +u8 * p2p_buf_add_p2p2_ie_hdr(struct wpabuf *buf); void p2p_buf_add_status(struct wpabuf *buf, u8 status); void p2p_buf_add_device_info(struct wpabuf *buf, struct p2p_data *p2p, struct p2p_device *peer); void p2p_buf_add_device_id(struct wpabuf *buf, const u8 *dev_addr); void p2p_buf_update_ie_hdr(struct wpabuf *buf, u8 *len); +void p2p_buf_update_p2p2_ie_hdr(struct wpabuf *buf, u8 *len); void p2p_buf_add_capability(struct wpabuf *buf, u8 dev_capab, u8 group_capab); void p2p_buf_add_go_intent(struct wpabuf *buf, u8 go_intent); void p2p_buf_add_listen_channel(struct wpabuf *buf, const char *country, @@ -788,6 +835,10 @@ void p2p_buf_add_feature_capability(struct wpabuf *buf, u16 len, const u8 *mask); void p2p_buf_add_persistent_group_info(struct wpabuf *buf, const u8 *dev_addr, const u8 *ssid, size_t ssid_len); +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, diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 74d61132e..03434c5ef 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -12193,6 +12193,7 @@ static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd, int ret = -1; enum nan_service_protocol_type srv_proto_type = 0; int *freq_list = NULL; + bool p2p = false; os_memset(¶ms, 0, sizeof(params)); /* USD shall use both solicited and unsolicited transmissions */ @@ -12253,6 +12254,11 @@ static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd, continue; } + if (os_strcmp(token, "p2p=1") == 0) { + p2p = true; + continue; + } + if (os_strcmp(token, "solicited=0") == 0) { params.solicited = false; continue; @@ -12274,7 +12280,7 @@ static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd, } publish_id = wpas_nan_usd_publish(wpa_s, service_name, srv_proto_type, - ssi, ¶ms); + ssi, ¶ms, p2p); if (publish_id > 0) ret = os_snprintf(buf, buflen, "%d", publish_id); fail: @@ -12358,6 +12364,7 @@ static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd, struct wpabuf *ssi = NULL; int ret = -1; enum nan_service_protocol_type srv_proto_type = 0; + bool p2p = false; os_memset(¶ms, 0, sizeof(params)); params.freq = NAN_USD_DEFAULT_FREQ; @@ -12397,6 +12404,11 @@ static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd, continue; } + if (os_strcmp(token, "p2p=1") == 0) { + p2p = true; + continue; + } + wpa_printf(MSG_INFO, "CTRL: Invalid NAN_SUBSCRIBE parameter: %s", token); @@ -12405,7 +12417,7 @@ static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd, subscribe_id = wpas_nan_usd_subscribe(wpa_s, service_name, srv_proto_type, ssi, - ¶ms); + ¶ms, p2p); if (subscribe_id > 0) ret = os_snprintf(buf, buflen, "%d", subscribe_id); fail: diff --git a/wpa_supplicant/nan_usd.c b/wpa_supplicant/nan_usd.c index 3fea540b9..0b329499f 100644 --- a/wpa_supplicant/nan_usd.c +++ b/wpa_supplicant/nan_usd.c @@ -13,6 +13,7 @@ #include "wpa_supplicant_i.h" #include "offchannel.h" #include "driver_i.h" +#include "p2p_supplicant.h" #include "nan_usd.h" @@ -386,7 +387,7 @@ void wpas_nan_usd_flush(struct wpa_supplicant *wpa_s) int wpas_nan_usd_publish(struct wpa_supplicant *wpa_s, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_publish_params *params) + struct nan_publish_params *params, bool p2p) { int publish_id; struct wpabuf *elems = NULL; @@ -394,8 +395,11 @@ int wpas_nan_usd_publish(struct wpa_supplicant *wpa_s, const char *service_name, if (!wpa_s->nan_de) return -1; + if (p2p) + elems = wpas_p2p_usd_elems(wpa_s); + publish_id = nan_de_publish(wpa_s->nan_de, service_name, srv_proto_type, - ssi, elems, params); + ssi, elems, params, p2p); if (publish_id <= 0) goto fail; if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_OFFLOAD) && @@ -443,7 +447,7 @@ int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_subscribe_params *params) + struct nan_subscribe_params *params, bool p2p) { int subscribe_id; struct wpabuf *elems = NULL; @@ -451,8 +455,12 @@ int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s, if (!wpa_s->nan_de) return -1; + if (p2p) + elems = wpas_p2p_usd_elems(wpa_s); + subscribe_id = nan_de_subscribe(wpa_s->nan_de, service_name, - srv_proto_type, ssi, elems, params); + srv_proto_type, ssi, elems, params, + p2p); if (subscribe_id <= 0) goto fail; if ((wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_OFFLOAD) && diff --git a/wpa_supplicant/nan_usd.h b/wpa_supplicant/nan_usd.h index 149ac9e60..ecb4973c4 100644 --- a/wpa_supplicant/nan_usd.h +++ b/wpa_supplicant/nan_usd.h @@ -21,7 +21,7 @@ void wpas_nan_usd_flush(struct wpa_supplicant *wpa_s); int wpas_nan_usd_publish(struct wpa_supplicant *wpa_s, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_publish_params *params); + struct nan_publish_params *params, bool p2p); void wpas_nan_usd_cancel_publish(struct wpa_supplicant *wpa_s, int publish_id); int wpas_nan_usd_update_publish(struct wpa_supplicant *wpa_s, int publish_id, const struct wpabuf *ssi); @@ -29,7 +29,7 @@ int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_subscribe_params *params); + struct nan_subscribe_params *params, bool p2p); void wpas_nan_usd_cancel_subscribe(struct wpa_supplicant *wpa_s, int subscribe_id); int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle, diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 70025f1e4..2df2d108b 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -10242,3 +10242,13 @@ int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s) wpa_s->p2p_lo_started = 0; return ret; } + + +struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s) +{ + struct p2p_data *p2p = wpa_s->global->p2p; + + if (wpa_s->global->p2p_disabled || !p2p) + return NULL; + return p2p_usd_elems(p2p); +} diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index d71f7701c..441e063d9 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -225,6 +225,7 @@ int wpas_p2p_lo_start(struct wpa_supplicant *wpa_s, unsigned int freq, 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); #else /* CONFIG_P2P */ @@ -351,6 +352,11 @@ static inline int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, return 0; } +static inline struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s) +{ + return NULL; +} + #endif /* CONFIG_P2P */ #endif /* P2P_SUPPLICANT_H */