From patchwork Fri Jul 19 04:39:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shivani Baranwal X-Patchwork-Id: 1962285 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=duvuaYnX; 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=N2KghVAk; 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 4WQH7j4XLBz20Mt for ; Fri, 19 Jul 2024 14:41:34 +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=haaiPMqb5UkYH8chhzZz+L1TajtYH2IboodGYjb3wDI=; b=duvuaYnX8wmoDm gnU6PlOe9VYqk1wejidicoAH4IM0npFsi1pVadBkIHfXcbkPck5CdUZlQQpDDvRoZDSObc8rwYEC5 IXvZSdx9gEEnHnBq3vyyXOF7Po2qqo8pcJTki2HSi9+UtT5THEHw0A6A9tYea4BW2PLFP3qtlRKdw 9YXomB6zKGjdb+yYZJSC/+ZKFXuZYNR5+HfrXAKNYN+URrKrFU/jPOpeQiWN7GEtlMBUVBEUJ/zUw D7hQZxgK+hrJ9rYoDfPb2IGI980Gw3WI/hPzPtjSfcgPcHdQ882QrBRzeZrqRy86eTbLvMWSZ82O5 qnWqcI9GJu3zHrDiyxGQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sUfQX-00000001XLU-1rvs; Fri, 19 Jul 2024 04:41:05 +0000 Received: from mx0b-0031df01.pphosted.com ([205.220.180.131]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sUfQM-00000001XHh-2dIb for hostap@lists.infradead.org; Fri, 19 Jul 2024 04:40:57 +0000 Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 46J0ts3j026236 for ; Fri, 19 Jul 2024 04:40:53 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=zy43NQskMjYSPSNiQIluQ/Wz /Ij6ppvS26+jb8D0RAI=; b=N2KghVAkOcOxNlWFTWocG4/goI5OMy3/jSzmAwbu BcdYDtNQUcCqgew6Ndc6fcklrN0N1baoNiQ7FM2SlntWZXD6uK+obApni1miofFm TLr6owHWA7d3zBHTj2zmKBQ+neaXr33Zikz7U720S/3EyvebDWbMkTkEYEbmO917 DIt63FYn+eQoGNjcwRTLjUQg3zCQWizO3yRmsLGP//3LxuTCh9gU+QadxHHAaXSR ur+duDPfkm2vzI8aoo0hQALiAW3OtB/0af+XyPF29Q8m6sgNb0A6xuYT6Hjm/I6p TsO7ylWIiMzsac/fRq9JVgUHqd312HNcJMAAXJ/5Baw43g== Received: from nalasppmta05.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 40fe1m8cdn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 19 Jul 2024 04:40:53 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA05.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 46J4eqW0021039 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 19 Jul 2024 04:40:52 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; Thu, 18 Jul 2024 21:40:50 -0700 From: Shivani Baranwal To: CC: Subject: [PATCH v2 02/14] P2P: Allow P2P IE to be added into NAN SDFs Date: Fri, 19 Jul 2024 10:09:54 +0530 Message-ID: <1721364006-21658-3-git-send-email-quic_shivbara@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1721364006-21658-1-git-send-email-quic_shivbara@quicinc.com> References: <1721364006-21658-1-git-send-email-quic_shivbara@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) 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: iRt-zieiP4pQqNU744aKHzkhcrNncTlL X-Proofpoint-ORIG-GUID: iRt-zieiP4pQqNU744aKHzkhcrNncTlL 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-19_01,2024-07-18_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 impostorscore=0 lowpriorityscore=0 mlxscore=0 mlxlogscore=999 clxscore=1015 bulkscore=0 phishscore=0 malwarescore=0 priorityscore=1501 spamscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2407110000 definitions=main-2407190035 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240718_214054_858396_55A36687 X-CRM114-Status: GOOD ( 24.85 ) X-Spam-Score: -2.1 (--) 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 --- hostapd/ctrl_iface.c | 16 +++- src/ap/nan_usd_ap.c | 8 +- src/ap/nan_usd_ap.h | 4 +- src/common/ieee802_11_defs.h | 19 +++++ src/common/ [...] Content analysis details: (-2.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches 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_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 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 --- hostapd/ctrl_iface.c | 16 +++- src/ap/nan_usd_ap.c | 8 +- src/ap/nan_usd_ap.h | 4 +- src/common/ieee802_11_defs.h | 19 +++++ src/common/nan_de.c | 7 +- src/common/nan_de.h | 4 +- src/p2p/p2p.c | 87 +++++++++++++++++++ src/p2p/p2p.h | 57 +++++++++++++ src/p2p/p2p_build.c | 182 +++++++++++++++++++++++++++++++++++++++- src/p2p/p2p_i.h | 51 +++++++++++ wpa_supplicant/ctrl_iface.c | 16 +++- wpa_supplicant/nan_usd.c | 16 +++- wpa_supplicant/nan_usd.h | 4 +- wpa_supplicant/p2p_supplicant.c | 10 +++ wpa_supplicant/p2p_supplicant.h | 6 ++ 15 files changed, 466 insertions(+), 21 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 39b9ef5..fcdbb5c 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -3705,6 +3705,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 */ @@ -3738,6 +3739,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; @@ -3759,7 +3765,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: @@ -3842,6 +3848,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)); @@ -3875,6 +3882,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); @@ -3883,7 +3895,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 70c6139..570abfc 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 58ff5fc..0571643 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 0fe6310..578ea73 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 0b54f11..5a68cc9 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; @@ -1277,6 +1278,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; @@ -1328,7 +1330,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; @@ -1368,6 +1370,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 ae77cf3..bdac284 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 8e0fc35..a2d0962 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 27bdac3..d8a5249 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -321,6 +321,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 */ struct p2p_peer_info { @@ -590,6 +626,26 @@ struct p2p_config { unsigned int passphrase_len; /** + * p2p_pairing_config - P2P Pairing configuration + */ + struct p2p_pairing_config pairing_config; + + /** + * 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 */ void *cb_ctx; @@ -2429,5 +2485,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 e4f40fe..92bcc6b 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_disable) + 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 0a487e0..0e24e51 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 f939583..3403ce0 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -12207,6 +12207,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 */ @@ -12267,6 +12268,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; @@ -12288,7 +12294,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: @@ -12372,6 +12378,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; @@ -12411,6 +12418,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); @@ -12419,7 +12431,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 3fea540..0b32949 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 149ac9e..ecb4973 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 70025f1..2df2d10 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 d71f770..441e063 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 */