From patchwork Mon Aug 5 09:33:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shivani Baranwal X-Patchwork-Id: 1969030 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=HwQyY/4d; 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=CGIHPnCN; 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 4WctQ66QKCz1yZb for ; Mon, 5 Aug 2024 20:45:50 +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=+lJ1Wdypb+/5KD71PGhfWK6BJPj20yu0LQlO2QI7968=; b=HwQyY/4d62Q/M7 oMuGIX1a7XaIe3M1YZ38riqOZjtF+T9nOMiI1nJjRkOwV0QyqkW3DNXhiJOentqxiRvnxwTbHbi3V FWqsLgfvQWZ+tEfnOVAK5qJzkSr7EELtvyo8Do9sLZtpPEnHPwLYkFCVRRHYG6iiXgI6R4jXbjUkG BdzSuTikZPHTje+bGA/ii18sN2Dk5YkQMq5gBJu7rRB6QLZTBlABafI+e3v7GQz8YzICEcZCFAe1o m5SDOW+l8Q9KRh1iVfWLyRX3imTkws4WIz2i6jC3d7ZAQaZIbPq7z/y19rvvIkBCS9+awV/njDY2h l7Rvv6bPsLHXV/B9c99Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1savDd-0000000FZEk-2O4j; Mon, 05 Aug 2024 10:45:37 +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 1sau70-0000000FIv1-1MF7 for hostap@lists.infradead.org; Mon, 05 Aug 2024 09:35:11 +0000 Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4752VYV4010343 for ; Mon, 5 Aug 2024 09:34:41 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=OYPS6As41w51vHgwj1JMfKB7 v2mS/wDAbKeBb5bvTmA=; b=CGIHPnCNwIySYlJMW5c/Ak5XM5hC/PoAE0piCh1e zaHjBkBgZhLx6By+E0I3ITsLcNA9Vghy1Phyc1NM3euNhgMqJHjuGE3GR+q0qUOe 6T2TauPnbHPi8G9TVAPfbVSnBSfFjdVzIKTHZ6JtTPoi2AHDcQilRgiPDR7oVCsS XJ0mzAP63Fmk2Ka1qOR1kY/2kkoP5sydV1ymYYWGpoETkRamB6I64KoP/0cnWDfd z1tTLbHbsuvh4WUx79TNtw3+2sBqJDWDWiKf0xUl4QmXU5AHx5neq80ObU8FH/oO ysYwn0SZnSqe+1bxtssN2mbhvjJYxS0WlpYa+UhK2zRyvQ== Received: from nalasppmta04.qualcomm.com (Global_NAT1.qualcomm.com [129.46.96.20]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 40sc4y3fvu-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 05 Aug 2024 09:34:41 +0000 (GMT) Received: from nalasex01a.na.qualcomm.com (nalasex01a.na.qualcomm.com [10.47.209.196]) by NALASPPMTA04.qualcomm.com (8.17.1.19/8.17.1.19) with ESMTPS id 4759YdIC013052 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Mon, 5 Aug 2024 09:34:40 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, 5 Aug 2024 02:34:38 -0700 From: Shivani Baranwal To: CC: Subject: [PATCH v3 19/25] p2p: Add support for Invitation using pairing verification Date: Mon, 5 Aug 2024 15:03:17 +0530 Message-ID: <1722850403-8852-20-git-send-email-quic_shivbara@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1722850403-8852-1-git-send-email-quic_shivbara@quicinc.com> References: <1722850403-8852-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-ORIG-GUID: yNH_rs3Gsr4G01X31MvoZMA0AQ4OoLUF X-Proofpoint-GUID: yNH_rs3Gsr4G01X31MvoZMA0AQ4OoLUF 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-08-04_14,2024-08-02_01,2024-05-17_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 adultscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 suspectscore=0 mlxscore=0 malwarescore=0 mlxlogscore=999 phishscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2407110000 definitions=main-2408050067 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240805_023443_228922_6BDC0B87 X-CRM114-Status: GOOD ( 26.70 ) 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: Signed-off-by: Shivani Baranwal --- src/p2p/p2p.c | 124 +++++++++++++++++++- src/p2p/p2p.h | 18 ++- src/p2p/p2p_i.h | 16 ++- src/p2p/p2p_invitation.c | 100 ++++++++++++++-- [...] Content analysis details: (-2.1 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- 0.0 RCVD_IN_VALIDITY_SAFE_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [205.220.180.131 listed in sa-accredit.habeas.com] 0.0 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [205.220.180.131 listed in sa-trusted.bondedsender.org] 0.0 RCVD_IN_VALIDITY_RPBL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. [205.220.180.131 listed in bl.score.senderscore.com] -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_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -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 Signed-off-by: Shivani Baranwal --- src/p2p/p2p.c | 124 +++++++++++++++++++- src/p2p/p2p.h | 18 ++- src/p2p/p2p_i.h | 16 ++- src/p2p/p2p_invitation.c | 100 ++++++++++++++-- wpa_supplicant/ctrl_iface.c | 12 +- wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 8 +- wpa_supplicant/p2p_supplicant.c | 175 +++++++++++++++++++++++++--- wpa_supplicant/p2p_supplicant.h | 6 +- 8 files changed, 415 insertions(+), 44 deletions(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 8f3d76e..702c90a 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -3996,7 +3996,7 @@ void p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst, p2p_invitation_req_cb(p2p, success); break; case P2P_PENDING_INVITATION_RESPONSE: - p2p_invitation_resp_cb(p2p, success); + p2p_invitation_resp_cb(p2p, dst, success); break; case P2P_PENDING_DEV_DISC_REQUEST: p2p_dev_disc_req_cb(p2p, success); @@ -4296,7 +4296,7 @@ static void p2p_timeout_invite_listen(struct p2p_data *p2p) p2p->cfg->invitation_result( p2p->cfg->cb_ctx, -1, NULL, NULL, p2p->invite_peer->info.p2p_device_addr, - 0, 0); + 0, 0, NULL, NULL, 0); } p2p_set_state(p2p, P2P_IDLE); } @@ -6206,6 +6206,117 @@ void p2p_pasn_initialize(struct p2p_data *p2p, struct p2p_device *dev, pasn->freq = freq; } +int get_listen_freq(struct p2p_data *p2p, const u8 *peer_addr) +{ + int freq; + struct p2p_device *dev; + + if (!peer_addr) { + p2p_dbg(p2p, "peer address NULL"); + return -1; + } + + dev = p2p_get_device(p2p, peer_addr); + if (!dev) { + p2p_dbg(p2p, "Peer not known"); + return -1; + } + + freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq; + if (freq <= 0) + freq = dev->oob_go_neg_freq; + if (freq <= 0) { + p2p_dbg(p2p, "No Listen/Operating frequency known for the peer " + MACSTR, MAC2STR(dev->info.p2p_device_addr)); + return -1; + } + return freq; +} + +int p2p_initiate_pasn_verify(struct p2p_data *p2p, const u8 *peer_addr, + int freq, enum p2p_invite_role role, + const u8 *bssid, const u8 *ssid, size_t ssid_len, + unsigned int force_freq, const u8 *go_dev_addr, + unsigned int pref_freq) +{ + struct pasn_data *pasn; + struct p2p_device *dev; + struct wpabuf *extra_ies, *req; + int ret = 0; + + if (!peer_addr) { + p2p_dbg(p2p, "peer address NULL"); + return -1; + } + + dev = p2p_get_device(p2p, peer_addr); + if (!dev) { + p2p_dbg(p2p, "Peer not known"); + return -1; + } + + if (p2p_invite(p2p, peer_addr, role, bssid, ssid, ssid_len, force_freq, + go_dev_addr, 1, pref_freq, -1, 1)) { + p2p_dbg(p2p, "p2p_invite failed"); + return -1; + } + + dev->role = P2P_ROLE_PAIRING_INITIATOR; + p2p_pasn_initialize(p2p, dev, peer_addr, freq, true); + pasn = dev->pasn; + + req = p2p_build_invitation_req(p2p, dev, go_dev_addr, -1); + if (!req) + return -1; + + p2p_set_state(p2p, P2P_INVITE); + p2p->pending_action_state = P2P_PENDING_INVITATION_REQUEST; + p2p->invite_peer = dev; + dev->invitation_reqs++; + + extra_ies = wpabuf_alloc(1500); + if (!extra_ies) { + wpabuf_free(req); + p2p_dbg(p2p, "Mem alloc failed for extra ies"); + return -1; + } + + if (p2p_prepare_pasn_extra_ie(p2p, extra_ies, req)) { + p2p_dbg(p2p, "prepare pasn extra ies failed"); + ret = -1; + goto out; + } + + pasn->extra_ies = os_zalloc(wpabuf_len(extra_ies)); + if (!pasn->extra_ies) { + p2p_dbg(p2p, "Mem alloc failed for pasn extra ies"); + ret = -1; + goto out; + } + + os_memcpy((u8 *)pasn->extra_ies, wpabuf_head_u8(extra_ies), + wpabuf_len(extra_ies)); + pasn->extra_ies_len = wpabuf_len(extra_ies); + + /* Start PASN Verify */ + if (wpa_pasn_verify(pasn, pasn->own_addr, pasn->peer_addr, pasn->bssid, + pasn->akmp, pasn->cipher, pasn->group, pasn->freq, + NULL, 0, NULL, 0, NULL)) { + p2p_dbg(p2p, "p2p pasn verify failed"); + ret = -1; + } else { + dev->flags |= P2P_DEV_WAIT_INV_REQ_ACK; + } +out: + if (pasn->extra_ies) { + os_free((u8 *)pasn->extra_ies); + pasn->extra_ies = NULL; + pasn->extra_ies_len = 0; + } + wpabuf_free(req); + wpabuf_free(extra_ies); + return ret; +} int p2p_initiate_pasn_auth(struct p2p_data *p2p, const u8 *addr, int freq) { @@ -6370,7 +6481,8 @@ int p2p_pasn_handle_action_wrapper(struct p2p_data *p2p, p2p_handle_go_neg_conf(p2p, mgmt->sa, data + 1, data_len - 1, true); } else { - p2p_invitation_resp_cb(p2p, P2P_SEND_ACTION_SUCCESS); + p2p_invitation_resp_cb(p2p, mgmt->sa, + P2P_SEND_ACTION_SUCCESS); } } p2p_parse_free(&msg); @@ -6631,7 +6743,7 @@ done: } int p2p_pasn_auth_tx_status(struct p2p_data *p2p, const u8 *data, - size_t data_len, u8 acked) + size_t data_len, u8 acked, bool verify) { int ret = 0; struct p2p_device *dev; @@ -6664,7 +6776,9 @@ int p2p_pasn_auth_tx_status(struct p2p_data *p2p, const u8 *data, if (ret != 1) return ret; - if (dev == p2p->go_neg_peer) + if (verify && dev == p2p->invite_peer) + p2p_start_invitation_connect(p2p, dev); + else if (dev == p2p->go_neg_peer) p2p_go_complete(p2p, dev); return 0; diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 65e2e0d..4759947 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1127,7 +1127,8 @@ struct p2p_config { void (*invitation_received)(void *ctx, const u8 *sa, const u8 *bssid, const u8 *ssid, size_t ssid_len, const u8 *go_dev_addr, u8 status, - int op_freq); + int op_freq, u8 *pmkid, u8 *pmk, + size_t pmk_len); /** * invitation_result - Callback on Invitation result @@ -1148,7 +1149,8 @@ struct p2p_config { */ void (*invitation_result)(void *ctx, int status, const u8 *bssid, const struct p2p_channels *channels, - const u8 *addr, int freq, int peer_oper_freq); + const u8 *addr, int freq, int peer_oper_freq, + u8 *pmkid, u8 *pmk, size_t pmk_len); /** * go_connected - Check whether we are connected to a GO @@ -1693,12 +1695,14 @@ enum p2p_invite_role { * force_freq == 0) * @dev_pw_id: Device Password ID from OOB Device Password (NFC) static handover * case or -1 if not used + * @p2p2: Operating in p2p2 mode * Returns: 0 on success, -1 on failure */ int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role, const u8 *bssid, const u8 *ssid, size_t ssid_len, unsigned int force_freq, const u8 *go_dev_addr, - int persistent_group, unsigned int pref_freq, int dev_pw_id); + int persistent_group, unsigned int pref_freq, int dev_pw_id, + bool p2p2); /** * p2p_presence_req - Request GO presence @@ -2675,12 +2679,18 @@ void p2p_set_comeback_after(struct p2p_data *p2p, int comeback_after); void p2p_set_reg_info(struct p2p_data *p2p, u8 val); void p2p_set_twt_power_mgmt(struct p2p_data *p2p, int val); +int get_listen_freq(struct p2p_data *p2p, const u8 *peer_addr); int p2p_initiate_pasn_auth(struct p2p_data *p2p, const u8 *addr, int freq); +int p2p_initiate_pasn_verify(struct p2p_data *p2p, const u8 *peer_addr, + int freq, enum p2p_invite_role role, + const u8 *bssid, const u8 *ssid, size_t ssid_len, + unsigned int force_freq, const u8 *go_dev_addr, + unsigned int pref_freq); int p2p_pasn_auth_rx(struct p2p_data *p2p, const struct ieee80211_mgmt *mgmt, size_t len, int freq); int p2p_pasn_update_extra_ies(struct p2p_data *p2p, const u8 *peer_addr); int p2p_pasn_parse_encrypted_data(struct p2p_data *p2p, const u8 *data, size_t len); int p2p_pasn_auth_tx_status(struct p2p_data *p2p, const u8 *data, - size_t data_len, u8 acked); + size_t data_len, u8 acked, bool verify); #endif /* P2P_H */ diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 440ed1f..7ff2c97 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -201,6 +201,16 @@ struct p2p_device { /* device role */ enum p2p_role role; + + /** + * Invitation params for P2P2 + */ + u8 inv_reject; + u8 inv_status; + int inv_freq; + int inv_peer_oper_freq; + u8 inv_bssid[ETH_ALEN]; + struct p2p_channels *inv_channels; }; struct p2p_sd_query { @@ -979,6 +989,9 @@ void p2p_process_pcea(struct p2p_data *p2p, struct p2p_message *msg, struct p2p_device *dev); /* p2p_invitation.c */ +struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p, + struct p2p_device *peer, + const u8 *go_dev_addr, int dev_pw_id); void p2p_handle_invitation_req(struct p2p_data *p2p, const u8 *sa, const u8 *data, size_t len, int rx_freq); void p2p_handle_invitation_resp(struct p2p_data *p2p, const u8 *sa, @@ -990,7 +1003,8 @@ void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa, int p2p_invite_send(struct p2p_data *p2p, struct p2p_device *dev, const u8 *go_dev_addr, int dev_pw_id); void p2p_invitation_req_cb(struct p2p_data *p2p, int success); -void p2p_invitation_resp_cb(struct p2p_data *p2p, int success); +void p2p_invitation_resp_cb(struct p2p_data *p2p, const u8 *dst, int success); +void p2p_start_invitation_connect(struct p2p_data *p2p, struct p2p_device *dev); /* p2p_dev_disc.c */ void p2p_process_dev_disc_req(struct p2p_data *p2p, const u8 *sa, diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c index 8ade838..19785d4 100644 --- a/src/p2p/p2p_invitation.c +++ b/src/p2p/p2p_invitation.c @@ -13,12 +13,15 @@ #include "common/wpa_ctrl.h" #include "p2p_i.h" #include "p2p.h" +#include "crypto/sha256.h" +#include "crypto/sha384.h" +#include "common/sae.h" +#include "pasn/pasn_common.h" -static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p, - struct p2p_device *peer, - const u8 *go_dev_addr, - int dev_pw_id) +struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p, + struct p2p_device *peer, + const u8 *go_dev_addr, int dev_pw_id) { struct wpabuf *buf; u8 *len; @@ -100,7 +103,7 @@ static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p, if (p2p->vendor_elem && p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]) wpabuf_put_buf(buf, p2p->vendor_elem[VENDOR_ELEM_P2P_INV_REQ]); - if (dev_pw_id >= 0) { + if (dev_pw_id >= 0 && !peer->p2p2) { /* WSC IE in Invitation Request for NFC static handover */ p2p_build_wps_ie(p2p, buf, dev_pw_id, 0); } @@ -120,6 +123,7 @@ static struct wpabuf * p2p_build_invitation_resp(struct p2p_data *p2p, u8 *len; size_t extra = 0; + p2p_dbg(p2p, "Building Invitation Response "); #ifdef CONFIG_WIFI_DISPLAY struct wpabuf *wfd_ie = p2p->wfd_ie_invitation; if (wfd_ie && group_bssid) { @@ -453,6 +457,7 @@ void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa, struct p2p_device *dev; struct p2p_message msg; struct p2p_channels intersection, *channels = NULL; + struct p2p_channels *p2p2_channels = NULL; p2p_dbg(p2p, "Received Invitation Response from " MACSTR, MAC2STR(sa)); @@ -532,14 +537,17 @@ void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa, #endif /* CONFIG_P2P_STRICT */ /* Try to survive without peer channel list */ channels = &p2p->channels; + p2p2_channels = channels; } else if (!msg.channel_list) { /* Non-success cases are not required to include Channel List */ channels = &p2p->channels; + p2p2_channels = channels; } else if (p2p_peer_channels_check(p2p, &p2p->channels, dev, msg.channel_list, msg.channel_list_len) < 0) { p2p_dbg(p2p, "No common channels found"); p2p_parse_free(&msg); + dev->inv_reject = 1; return; } else { p2p_channels_intersect(&p2p->channels, &dev->channels, @@ -547,6 +555,7 @@ void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa, channels = &intersection; } + if (p2p->cfg->invitation_result) { int peer_oper_freq = 0; int freq = p2p_channel_to_freq(p2p->op_reg_class, @@ -568,18 +577,70 @@ void p2p_process_invitation_resp(struct p2p_data *p2p, const u8 *sa, */ p2p_check_pref_chan(p2p, 0, dev, &msg); + if (dev->p2p2) { + dev->inv_freq = freq; + dev->inv_status = *msg.status; + dev->inv_channels = p2p2_channels; + dev->inv_peer_oper_freq = peer_oper_freq; + if (msg.group_bssid) + os_memcpy(dev->inv_bssid, msg.group_bssid, ETH_ALEN); + goto out; + } + p2p->cfg->invitation_result(p2p->cfg->cb_ctx, *msg.status, msg.group_bssid, channels, sa, - freq, peer_oper_freq); + freq, peer_oper_freq, NULL, NULL, + 0); } + p2p_clear_timeout(p2p); + p2p_set_state(p2p, P2P_IDLE); + p2p->invite_peer = NULL; + +out: p2p_parse_free(&msg); +} + + +#ifdef CONFIG_PASN +void p2p_start_invitation_connect(struct p2p_data *p2p, struct p2p_device *dev) +{ + size_t pmk_len = 0; + u8 pmkid[PMKID_LEN]; + u8 pmk[PMK_LEN_MAX]; + struct p2p_channels intersection; + + if (!p2p || !dev || dev->inv_reject || !dev->pasn) + return; + + if (!dev->inv_channels) { + p2p_channels_intersect(&p2p->channels, &dev->channels, + &intersection); + dev->inv_channels = &intersection; + } + + pasn_initiator_pmksa_cache_get(dev->pasn->pmksa, dev->pasn->peer_addr, + pmkid, pmk, &pmk_len); + + wpa_pasn_reset(dev->pasn); + p2p_dbg(p2p, "P2P Invitation connect: msg status %d", dev->inv_status); + if (p2p->cfg->invitation_result) + p2p->cfg->invitation_result(p2p->cfg->cb_ctx, dev->inv_status, + dev->inv_bssid, dev->inv_channels, + dev->info.p2p_device_addr, + dev->inv_freq, + dev->inv_peer_oper_freq, pmkid, + pmk, pmk_len); + + /* Reset pmk and pmkid from RAM */ + memset(pmkid, 0, sizeof(pmkid)); + memset(pmk, 0, sizeof(pmk)); p2p_clear_timeout(p2p); p2p_set_state(p2p, P2P_IDLE); p2p->invite_peer = NULL; } - +#endif /* CONFIG_PASN */ int p2p_invite_send(struct p2p_data *p2p, struct p2p_device *dev, const u8 *go_dev_addr, int dev_pw_id) @@ -649,8 +710,19 @@ void p2p_invitation_req_cb(struct p2p_data *p2p, int success) } -void p2p_invitation_resp_cb(struct p2p_data *p2p, int success) +void p2p_invitation_resp_cb(struct p2p_data *p2p, const u8 *peer, int success) { + size_t pmk_len = 0; + u8 pmkid[PMKID_LEN]; + u8 pmk[PMK_LEN_MAX]; + struct p2p_device *dev; + + dev = p2p_get_device(p2p, peer); + if (dev && dev->pasn) + pasn_responder_pmksa_cache_get(dev->pasn->pmksa, + dev->pasn->peer_addr, pmkid, + pmk, &pmk_len); + p2p_dbg(p2p, "Invitation Response TX callback: success=%d", success); p2p->cfg->send_action_done(p2p->cfg->cb_ctx); @@ -664,15 +736,20 @@ void p2p_invitation_resp_cb(struct p2p_data *p2p, int success) p2p->inv_ssid, p2p->inv_ssid_len, p2p->inv_go_dev_addr, p2p->inv_status, - p2p->inv_op_freq); + p2p->inv_op_freq, pmkid, pmk, + pmk_len); } + /* Reset pmk and pmkid from RAM */ + memset(pmkid, 0, sizeof(pmkid)); + memset(pmk, 0, sizeof(pmk)); } int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role, const u8 *bssid, const u8 *ssid, size_t ssid_len, unsigned int force_freq, const u8 *go_dev_addr, - int persistent_group, unsigned int pref_freq, int dev_pw_id) + int persistent_group, unsigned int pref_freq, int dev_pw_id, + bool p2p2) { struct p2p_device *dev; @@ -740,5 +817,8 @@ int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role, os_memcpy(p2p->inv_ssid, ssid, ssid_len); p2p->inv_ssid_len = ssid_len; p2p->inv_persistent = persistent_group; + if (p2p2) + return 0; + return p2p_invite_send(p2p, dev, go_dev_addr, dev_pw_id); } diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index d976914..daa8bef 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -7073,6 +7073,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) int ht40, vht, he, max_oper_chwidth, chwidth = 0, freq2 = 0; int edmg; bool allow_6ghz; + bool p2p2; id = atoi(cmd); pos = os_strstr(cmd, " peer="); @@ -7129,9 +7130,11 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) if (allow_6ghz && chwidth == 40) max_oper_chwidth = CONF_OPER_CHWIDTH_40MHZ_6GHZ; + p2p2 = os_strstr(cmd, "p2p2") != NULL; + return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, freq2, ht40, vht, max_oper_chwidth, pref_freq, he, edmg, - allow_6ghz); + allow_6ghz, p2p2); } @@ -7186,6 +7189,9 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s, int he, int edmg, bool allow_6ghz, const u8 *go_bssid) { + size_t pmk_len = 0; + u8 pmkid[PMKID_LEN]; + u8 pmk[PMK_LEN_MAX]; struct wpa_ssid *ssid; ssid = wpa_config_get_network(wpa_s->conf, id); @@ -7196,11 +7202,13 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s, return -1; } + /* FIXME Fetch pmk, pmkid from p2p_supplicant.conf */ return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, freq, vht_center_freq2, ht40, vht, vht_chwidth, he, edmg, NULL, 0, 0, allow_6ghz, 0, - go_bssid); + go_bssid, NULL, pmkid, pmk, + pmk_len); } diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c index 65bd478..aad4c5b 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -367,6 +367,9 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message, int he = wpa_s->conf->p2p_go_he; int edmg = wpa_s->conf->p2p_go_edmg; int max_oper_chwidth, chwidth = 0, freq2 = 0; + size_t pmk_len = 0; + u8 pmkid[PMKID_LEN]; + u8 pmk[PMK_LEN_MAX]; dbus_message_iter_init(message, &iter); @@ -477,7 +480,8 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message, freq2, ht40, vht, max_oper_chwidth, he, edmg, NULL, 0, 0, allow_6ghz, - retry_limit, go_bssid)) { + retry_limit, go_bssid, NULL, pmkid, + pmk, pmk_len)) { reply = wpas_dbus_error_unknown_error( message, "Failed to reinvoke a persistent group"); @@ -866,7 +870,7 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message, goto err; if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0, 0, 0, - 0, 0, 0, false) < 0) { + 0, 0, 0, false, 0) < 0) { reply = wpas_dbus_error_unknown_error( message, "Failed to reinvoke a persistent group"); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 71aaeba..0befcdd 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -39,7 +39,8 @@ #include "wifi_display.h" #include "crypto/random.h" - +#include "ap/ieee802_11.h" +#include "ap/wpa_auth.h" /* * How many times to try to scan to find the GO before giving up on join @@ -1736,13 +1737,22 @@ static void wpas_send_action_done(void *ctx) #ifdef CONFIG_PASN struct wpa_p2p_pasn_auth_work { u8 peer_addr[ETH_ALEN]; - bool verify; int freq; + bool verify; + int force_freq; + int pref_freq; + enum p2p_invite_role role; + u8 *ssid; + size_t ssid_len; + u8 bssid[ETH_ALEN]; + u8 go_dev_addr[ETH_ALEN]; }; static void wpas_p2p_pasn_free_auth_work(struct wpa_p2p_pasn_auth_work *awork) { + if (awork->ssid) + os_free(awork->ssid); os_free(awork); } @@ -3522,7 +3532,8 @@ accept_inv: static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid, const u8 *ssid, size_t ssid_len, const u8 *go_dev_addr, u8 status, - int op_freq) + int op_freq, u8 *pmkid, u8 *pmk, + size_t pmk_len) { struct wpa_supplicant *wpa_s = ctx; struct wpa_ssid *s; @@ -3562,7 +3573,7 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid, wpa_s->conf->p2p_go_edmg, NULL, go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 1, is_p2p_allow_6ghz(wpa_s->global->p2p), 0, - NULL); + bssid, sa, pmkid, pmk, pmk_len); } else if (bssid) { wpa_s->user_initiated_pd = 0; wpa_msg_global(wpa_s, MSG_INFO, @@ -3680,12 +3691,20 @@ static void wpas_remove_persistent_client(struct wpa_supplicant *wpa_s, static void wpas_invitation_result(void *ctx, int status, const u8 *bssid, const struct p2p_channels *channels, const u8 *peer, int neg_freq, - int peer_oper_freq) + int peer_oper_freq, u8 *pmkid, u8 *pmk, + size_t pmk_len) { struct wpa_supplicant *wpa_s = ctx; struct wpa_ssid *ssid; int freq; +#ifdef CONFIG_PASN + if (wpa_s->p2p_pasn_auth_work) { + wpas_p2p_pasn_cancel_auth_work(wpa_s); + wpa_s->p2p_pasn_auth_work = NULL; + } +#endif /* CONFIG_PASN */ + if (bssid) { wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_INVITATION_RESULT "status=%d " MACSTR, @@ -3793,7 +3812,7 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid, P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 1, is_p2p_allow_6ghz(wpa_s->global->p2p), 0, - NULL); + bssid, peer, pmkid, pmk, pmk_len); } @@ -4859,7 +4878,8 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, persistent_go->mode == WPAS_MODE_P2P_GO ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : - 0, 0, false, 0, NULL); + 0, 0, false, 0, NULL, NULL, NULL, NULL, + 0); } else if (response_done) { wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0, false); @@ -4982,7 +5002,8 @@ static int wpas_prov_disc_resp_cb(void *ctx) NULL, persistent_go->mode == WPAS_MODE_P2P_GO ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0, - is_p2p_allow_6ghz(wpa_s->global->p2p), 0, NULL); + is_p2p_allow_6ghz(wpa_s->global->p2p), 0, NULL, NULL, + NULL, NULL, 0); } else { wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0, is_p2p_allow_6ghz(wpa_s->global->p2p)); @@ -5075,10 +5096,13 @@ static void wpas_bootstrap_completed(void *ctx, const u8 *addr, int status, #ifdef CONFIG_PASN static void wpas_p2p_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit) { + int ret = 0; struct wpa_supplicant *wpa_s = work->wpa_s; struct wpa_p2p_pasn_auth_work *awork = work->ctx; struct p2p_data *p2p = wpa_s->global->p2p; const u8 *peer_addr = NULL; + const u8 *bssid = NULL; + const u8 *go_dev_addr = NULL; if (deinit) { if (!work->started) { @@ -5091,7 +5115,22 @@ static void wpas_p2p_pasn_auth_start_cb(struct wpa_radio_work *work, int deinit) if (!is_zero_ether_addr(awork->peer_addr)) peer_addr = awork->peer_addr; - if (p2p_initiate_pasn_auth(p2p, peer_addr, awork->freq)) { + if (!is_zero_ether_addr(awork->bssid)) + bssid = awork->bssid; + if (!is_zero_ether_addr(awork->go_dev_addr)) + go_dev_addr = awork->go_dev_addr; + + + if (awork->verify) + ret = p2p_initiate_pasn_verify(p2p, peer_addr, awork->freq, + awork->role, bssid, awork->ssid, + awork->ssid_len, + awork->force_freq, go_dev_addr, + awork->pref_freq); + else + ret = p2p_initiate_pasn_auth(p2p, peer_addr, awork->freq); + + if (ret) { wpa_printf(MSG_DEBUG, "P2P PASN: Failed to start PASN authentication"); goto fail; @@ -5109,6 +5148,59 @@ fail: radio_work_done(work); } +static int wpas_p2p_initiate_pasn_verify(struct wpa_supplicant *wpa_s, + const u8 *peer, + enum p2p_invite_role role, + const u8 *bssid, const u8 *ssid, + size_t ssid_len, + unsigned int force_freq, + const u8 *go_dev_addr, + unsigned int pref_freq) +{ + int freq; + struct wpa_p2p_pasn_auth_work *awork; + + wpas_p2p_pasn_cancel_auth_work(wpa_s); + wpa_s->p2p_pasn_auth_work = NULL; + + freq = get_listen_freq(wpa_s->global->p2p, peer); + if (freq == -1) + return -1; + + awork = os_zalloc(sizeof(*awork)); + if (!awork) + return -1; + + awork->verify = 1; + awork->role = role; + awork->freq = freq; + awork->force_freq = force_freq; + awork->pref_freq = pref_freq; + os_memcpy(awork->peer_addr, peer, ETH_ALEN); + if (go_dev_addr) + os_memcpy(awork->go_dev_addr, go_dev_addr, ETH_ALEN); + if (bssid) + os_memcpy(awork->bssid, bssid, ETH_ALEN); + if (ssid_len) { + awork->ssid = os_zalloc(ssid_len); + if (!awork->ssid) { + os_free(awork); + return -1; + } + memcpy(awork->ssid, ssid, ssid_len); + awork->ssid_len = ssid_len; + } + + if (radio_add_work(wpa_s, freq, "p2p-pasn-start-auth", 1, + wpas_p2p_pasn_auth_start_cb, awork) < 0) { + wpas_p2p_pasn_free_auth_work(awork); + return -1; + } + + wpa_printf(MSG_DEBUG, "P2P PASN: Auth work successfully added"); + return 0; +} + static int wpas_p2p_initiate_pasn_auth(struct wpa_supplicant *wpa_s, const u8 *peer_addr, int freq) { @@ -5166,8 +5258,12 @@ int wpas_p2p_pasn_auth_tx_status(struct wpa_supplicant *wpa_s, const u8 *data, size_t data_len, u8 acked) { struct p2p_data *p2p = wpa_s->global->p2p; + struct wpa_p2p_pasn_auth_work *awork; - return p2p_pasn_auth_tx_status(p2p, data, data_len, acked); + awork = wpa_s->p2p_pasn_auth_work->ctx; + + return p2p_pasn_auth_tx_status(p2p, data, data_len, acked, + awork->verify); } #endif @@ -6897,6 +6993,7 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, params->max_oper_chwidth = max_oper_chwidth; params->vht_center_freq2 = vht_center_freq2; params->edmg = edmg; + params->p2p2 = wpa_s->p2p2; freqs = os_calloc(wpa_s->num_multichan_concurrent, sizeof(struct wpa_used_freq_data)); @@ -7339,7 +7436,8 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s, struct wpa_ssid *params, int addr_allocated, int freq, int force_scan, int retry_limit, - const u8 *go_bssid) + const u8 *go_bssid, bool p2p2, u8 *pmkid, + u8 *pmk, size_t pmk_len) { struct wpa_ssid *ssid; int other_iface_found = 0; @@ -7397,6 +7495,20 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s, os_memcpy(ssid->bssid, go_bssid, ETH_ALEN); } + if (p2p2) { + ssid->key_mgmt = WPA_KEY_MGMT_SAE; + ssid->auth_alg = WPA_AUTH_ALG_OPEN; + ssid->sae_password = "12345678"; + wpa_s->conf->sae_pwe = SAE_PWE_HASH_TO_ELEMENT; + ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED; + ssid->disabled = 0; + + if (pmk && pmk_len && pmkid) + wpa_sm_set_pmk(wpa_s->wpa, pmk, pmk_len, pmkid, + ssid->bssid); + wpa_s->current_ssid = ssid; + } + wpa_s->show_group_started = 1; wpa_s->p2p_in_invitation = 1; wpa_s->p2p_retry_limit = retry_limit; @@ -7444,7 +7556,8 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, const struct p2p_channels *channels, int connection_timeout, int force_scan, bool allow_6ghz, int retry_limit, - const u8 *go_bssid) + const u8 *go_bssid, const u8 *dev_addr, + u8 *pmkid, u8 *pmk, size_t pmk_len) { struct p2p_go_neg_results params; int go = 0, freq; @@ -7513,7 +7626,8 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, } return wpas_start_p2p_client(wpa_s, ssid, addr_allocated, freq, - force_scan, retry_limit, go_bssid); + force_scan, retry_limit, go_bssid, + wpa_s->p2p2, pmkid, pmk, pmk_len); } else { return -1; } @@ -7540,6 +7654,15 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, params.ssid_len = ssid->ssid_len; params.persistent_group = 1; + if (wpa_s->p2p2 && pmk_len && pmk && pmkid) { + memcpy(params.peer_device_addr, dev_addr, ETH_ALEN); + memcpy(params.pmkid, pmkid, PMKID_LEN); + memcpy(params.pmk, pmk, pmk_len); + params.pmk_len = pmk_len; + params.akmp = WPA_KEY_MGMT_SAE; + params.p2p2 = true; + } + wpa_s = wpas_p2p_get_group_iface(wpa_s, addr_allocated, 1); if (wpa_s == NULL) return -1; @@ -8077,7 +8200,7 @@ int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr) int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq, int vht_center_freq2, int ht40, int vht, int max_chwidth, - int pref_freq, int he, int edmg, bool allow_6ghz) + int pref_freq, int he, int edmg, bool allow_6ghz, bool p2p2) { enum p2p_invite_role role; u8 *bssid = NULL; @@ -8103,6 +8226,7 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, wpa_s->p2p_go_max_oper_chwidth = max_chwidth; wpa_s->p2p_go_vht_center_freq2 = vht_center_freq2; wpa_s->p2p_go_edmg = !!edmg; + wpa_s->p2p2 = p2p2; if (ssid->mode == WPAS_MODE_P2P_GO) { role = P2P_INVITE_ROLE_GO; if (peer_addr == NULL) { @@ -8125,7 +8249,8 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, bssid = wpa_s->own_addr; } else { role = P2P_INVITE_ROLE_CLIENT; - peer_addr = ssid->bssid; + if (!wpa_s->p2p2) + peer_addr = ssid->bssid; } wpa_s->pending_invite_ssid_id = ssid->id; @@ -8156,9 +8281,23 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, */ wpas_p2p_stop_find_oper(wpa_s); +#ifdef CONFIG_PASN + if (p2p2) { + if (wpas_p2p_initiate_pasn_verify(wpa_s, peer_addr, role, bssid, + ssid->ssid, ssid->ssid_len, + force_freq, go_dev_addr, + pref_freq) < 0) { + if (wpa_s->create_p2p_iface) + wpas_p2p_remove_pending_group_interface(wpa_s); + return -1; + } + return 0; + } +#endif /* CONFIG_PASN */ + return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid, ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr, - 1, pref_freq, -1); + 1, pref_freq, -1, 0); } @@ -8242,7 +8381,7 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname, return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid, ssid->ssid, ssid->ssid_len, force_freq, - go_dev_addr, persistent, pref_freq, -1); + go_dev_addr, persistent, pref_freq, -1, 0); } @@ -9743,7 +9882,7 @@ static int wpas_p2p_nfc_auth_join(struct wpa_supplicant *wpa_s, P2P_INVITE_ROLE_ACTIVE_GO, wpa_s->own_addr, ssid->ssid, ssid->ssid_len, ssid->frequency, wpa_s->global->p2p_dev_addr, persistent, 0, - wpa_s->p2pdev->p2p_oob_dev_pw_id); + wpa_s->p2pdev->p2p_oob_dev_pw_id, 0); } diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 5612d83..61d4281 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -54,7 +54,8 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, const struct p2p_channels *channels, int connection_timeout, int force_scan, bool allow_6ghz, int retry_limit, - const u8 *go_bssid); + const u8 *go_bssid, const u8 *dev_addr, + u8 *pmkid, u8 *pmk, size_t pmk_len); struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); enum wpas_p2p_prov_disc_use { @@ -122,7 +123,8 @@ int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr); int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq, int vht_center_freq2, int ht40, int vht, int max_chwidth, - int pref_freq, int he, int edmg, bool allow_6ghz); + int pref_freq, int he, int edmg, bool allow_6ghz, + bool p2p2); int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname, const u8 *peer_addr, const u8 *go_dev_addr, bool allow_6ghz);