{"id":2226364,"url":"http://patchwork.ozlabs.org/api/1.2/patches/2226364/?format=json","web_url":"http://patchwork.ozlabs.org/project/hostap/patch/20260422122424.43776-19-andrei.otcheretianski@intel.com/","project":{"id":22,"url":"http://patchwork.ozlabs.org/api/1.2/projects/22/?format=json","name":"HostAP Development","link_name":"hostap","list_id":"hostap.lists.infradead.org","list_email":"hostap@lists.infradead.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260422122424.43776-19-andrei.otcheretianski@intel.com>","list_archive_url":null,"date":"2026-04-22T12:23:09","name":"[18/92] NAN: Add a function for triggering NAN pairing","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"c2a2ba4ca97602f31a54c4b736cb5a612b34766d","submitter":{"id":62065,"url":"http://patchwork.ozlabs.org/api/1.2/people/62065/?format=json","name":"Andrei Otcheretianski","email":"andrei.otcheretianski@intel.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/hostap/patch/20260422122424.43776-19-andrei.otcheretianski@intel.com/mbox/","series":[{"id":501001,"url":"http://patchwork.ozlabs.org/api/1.2/series/501001/?format=json","web_url":"http://patchwork.ozlabs.org/project/hostap/list/?series=501001","date":"2026-04-22T12:23:05","name":"Add NAN PASN pairing support","version":1,"mbox":"http://patchwork.ozlabs.org/series/501001/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2226364/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2226364/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=ag4P2zUb;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256\n header.s=Intel header.b=ifwpraR3;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g0z2v01Qpz1yHB\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 22 Apr 2026 22:25:42 +1000 (AEST)","from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1wFWdg-0000000A2rB-1l3o;\n\tWed, 22 Apr 2026 12:25:08 +0000","from mgamail.intel.com ([192.198.163.17])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1wFWdc-0000000A2aQ-0Psu\n\tfor hostap@lists.infradead.org;\n\tWed, 22 Apr 2026 12:25:05 +0000","from orviesa010.jf.intel.com ([10.64.159.150])\n  by fmvoesa111.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 22 Apr 2026 05:25:03 -0700","from iapp347.iil.intel.com (HELO 87c02287900a.iil.intel.com)\n ([10.167.28.6])\n  by orviesa010-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 22 Apr 2026 05:25:03 -0700"],"DKIM-Signature":["v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:\n\tMessage-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=QlQwpe2yILCDxjDY218YE1TMb/KWLsQspUdQYEydsTI=; b=ag4P2zUbsgTl8L\n\tLnbt5+yzZZxLCacR58DwsVhx0WBur6i/hKy7tJ+9uKaY9Ml6RXxWt0OhWMzKnp9TEFAjFXfmz0PoM\n\t82VIZ8TjY/hJvrtQj3t/Jn41/h7u62VxHaz/B0zxLp0pIB4x8zq5ZDzaUMCnoIEaO32U9zogGtzs9\n\tAy8/drBOm4CfqHxAaTWS7+uTGvsf4iZpgsK6/pf0SNcmChiQH5rLTBigdI7sj1ZugvRfT000UWKSq\n\tZq6tspJtR6UWogp24smJD3vqAQx9lMT/92bVATxTS394bK8ZrM4jkBB5xXXoVbWPtooQdoSvRXgYK\n\tak8HkMTyutWfpbeCtgng==;","v=1; a=rsa-sha256; c=relaxed/simple;\n  d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n  t=1776860704; x=1808396704;\n  h=from:to:cc:subject:date:message-id:in-reply-to:\n   references:mime-version:content-transfer-encoding;\n  bh=uNXt90B3Q7+k2OQvWoSgv/hFnYKq8RvxWhlILYio6PE=;\n  b=ifwpraR3XwPT8GaP+XLm7fCaTs3bpZR5RfuZObHku9u5cqinuRSeGug+\n   9LR0MvI2F2o7Y/wD2rSO4nzt9FnEj8y4WRh1VGoZDqYwN4rpC3qEmOn3q\n   NOFreZ+qyVZIIO0+4Z/I/IeBUjdSsUoj3B5hVk9mIhuN0XzVD2SPBXpMS\n   MgKikCM1jct8FDhEI+lym3ENHLAPjhoemkBxMchkVvjbuvD1zXP+1s6nn\n   Pwaj+CptMT/xRIG81pwA/k1PzrTsa+53QwulLbz80HNzPg/DGwasxhs39\n   6OEo/+uh7dYIdbIu910FlyT3P1DYr2pSAiJNO7OSlJumlb+t1ht/VLmJI\n   g==;"],"X-CSE-ConnectionGUID":["cmtM0BH5TwCWdGKywZdItg==","eEv5f4FyTL+4qOldIl3iFA=="],"X-CSE-MsgGUID":["pkfioo9vTP2QcEV+g+GoKw==","dz99NJxLQralenPVPI7pWA=="],"X-IronPort-AV":["E=McAfee;i=\"6800,10657,11764\"; a=\"77687208\"","E=Sophos;i=\"6.23,192,1770624000\";\n   d=\"scan'208\";a=\"77687208\"","E=Sophos;i=\"6.23,192,1770624000\";\n   d=\"scan'208\";a=\"231444903\""],"X-ExtLoop1":"1","From":"Andrei Otcheretianski <andrei.otcheretianski@intel.com>","To":"hostap@lists.infradead.org","Cc":"vamsin@qti.qualcomm.com,\n\tmaheshkkv@google.com,\n\tAvraham Stern <avraham.stern@intel.com>","Subject":"[PATCH 18/92] NAN: Add a function for triggering NAN pairing","Date":"Wed, 22 Apr 2026 15:23:09 +0300","Message-ID":"<20260422122424.43776-19-andrei.otcheretianski@intel.com>","X-Mailer":"git-send-email 2.53.0","In-Reply-To":"<20260422122424.43776-1-andrei.otcheretianski@intel.com>","References":"<20260422122424.43776-1-andrei.otcheretianski@intel.com>","MIME-Version":"1.0","X-CRM114-Version":"20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ","X-CRM114-CacheID":"sfid-20260422_052504_261534_64360EFF ","X-CRM114-Status":"GOOD (  24.90  )","X-Spam-Score":"-4.4 (----)","X-Spam-Report":"Spam detection software,\n running on the system \"bombadil.infradead.org\",\n has NOT identified this incoming email as spam.  The original\n message has been attached to this so you can view it or label\n similar future email.  If you have any questions, see\n the administrator of that system for details.\n Content preview:  From: Avraham Stern <avraham.stern@intel.com> Add a\n function\n    for triggering NAN pairing. This function will setup the PASN data and\n trigger\n    sending PASN auth frame no. 1. Signed-off-by: Avraham Stern\n <avraham.stern@intel.com>\n    --- src/common/nan_defs.h | 2 + src/nan/nan.c | 1 + src/nan/nan.h | 23 +++\n    src/nan/nan_i.h | 52 ++++++ src/nan/nan_pairing.c | 357 ++++++++++++++\n [...]    \n Content analysis details:   (-4.4 points, 5.0 required)\n  pts rule name              description\n ---- ----------------------\n --------------------------------------------------\n -2.3 RCVD_IN_DNSWL_MED      RBL: Sender listed at https://www.dnswl.org/,\n                             medium trust\n                             [192.198.163.17 listed in list.dnswl.org]\n  0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record\n -0.0 SPF_PASS               SPF: sender matches SPF record\n -0.1 DKIM_VALID             Message has at least one valid DKIM or DK\n signature\n -0.1 DKIM_VALID_AU          Message has a valid DKIM or DK signature from\n author's\n                             domain\n -0.1 DKIM_VALID_EF          Message has a valid DKIM or DK signature from\n                             envelope-from domain\n  0.1 DKIM_SIGNED            Message has a DKIM or DK signature,\n not necessarily valid\n -1.9 BAYES_00               BODY: Bayes spam probability is 0 to 1%\n                             [score: 0.0000]\n -0.0 DKIMWL_WL_HIGH         DKIMwl.org - High trust sender","X-BeenThere":"hostap@lists.infradead.org","X-Mailman-Version":"2.1.34","Precedence":"list","List-Id":"<hostap.lists.infradead.org>","List-Unsubscribe":"<http://lists.infradead.org/mailman/options/hostap>,\n <mailto:hostap-request@lists.infradead.org?subject=unsubscribe>","List-Archive":"<http://lists.infradead.org/pipermail/hostap/>","List-Post":"<mailto:hostap@lists.infradead.org>","List-Help":"<mailto:hostap-request@lists.infradead.org?subject=help>","List-Subscribe":"<http://lists.infradead.org/mailman/listinfo/hostap>,\n <mailto:hostap-request@lists.infradead.org?subject=subscribe>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Sender":"\"Hostap\" <hostap-bounces@lists.infradead.org>","Errors-To":"hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org"},"content":"From: Avraham Stern <avraham.stern@intel.com>\n\nAdd a function for triggering NAN pairing. This function will setup\nthe PASN data and trigger sending PASN auth frame no. 1.\n\nSigned-off-by: Avraham Stern <avraham.stern@intel.com>\n---\n src/common/nan_defs.h |   2 +\n src/nan/nan.c         |   1 +\n src/nan/nan.h         |  23 +++\n src/nan/nan_i.h       |  52 ++++++\n src/nan/nan_pairing.c | 357 ++++++++++++++++++++++++++++++++++++++++++\n 5 files changed, 435 insertions(+)","diff":"diff --git a/src/common/nan_defs.h b/src/common/nan_defs.h\nindex 48a3bcf493..58bcb689df 100644\n--- a/src/common/nan_defs.h\n+++ b/src/common/nan_defs.h\n@@ -564,4 +564,6 @@ struct nan_shared_key {\n #define NAN_NIRA_CIPHER_VER_128\t0\n #define NAN_NIK_LEN\t\t16\n \n+#define NAN_PASN_SSID \"516F9A010000\"\n+\n #endif /* NAN_DEFS_H */\ndiff --git a/src/nan/nan.c b/src/nan/nan.c\nindex ab8b997a3c..b49c4a4ad3 100644\n--- a/src/nan/nan.c\n+++ b/src/nan/nan.c\n@@ -160,6 +160,7 @@ static void nan_del_peer(struct nan_data *nan, struct nan_peer *peer)\n \tnan_ndl_reset(nan, peer);\n \tnan_peer_flush_sec(&peer->info);\n \teloop_cancel_timeout(nan_peer_state_timeout, nan, peer);\n+\tnan_pairing_deinit_peer(peer);\n \tos_free(peer);\n }\n \ndiff --git a/src/nan/nan.h b/src/nan/nan.h\nindex c5300aff41..41a24ab8c9 100644\n--- a/src/nan/nan.h\n+++ b/src/nan/nan.h\n@@ -596,6 +596,16 @@ struct nan_config {\n \t * configured for the service or 0 if service is not found.\n \t */\n \tu16 (*get_supported_bootstrap_methods)(void *ctx, int handle);\n+\n+\t/**\n+\t * send_pasn - Function handler to transmit a PASN auth frame\n+\t *\n+\t * @ctx: Callback context from cb_ctx\n+\t * @data: Frame to transmit\n+\t * @data_len: Length of frame to transmit\n+\t * Returns: 0 on success, -1 on failure\n+\t */\n+\tint (*send_pasn)(void *ctx, const u8 *data, size_t data_len);\n };\n \n struct nan_data * nan_init(const struct nan_config *cfg);\n@@ -668,12 +678,25 @@ struct wpabuf *nan_crypto_derive_nira_tag(const u8 *nik, size_t nik_len,\n \t\t\t\t\t  const u8 *nira_nonce);\n #ifdef CONFIG_PASN\n int nan_pairing_add_attrs(struct nan_data *nan_data, struct wpabuf *buf);\n+int nan_pairing_initiate_pasn_auth(struct nan_data *nan_data, const u8 *addr,\n+\t\t\t\t   u8 auth_mode, int cipher, int handle,\n+\t\t\t\t   u8 peer_instance_id, bool responder,\n+\t\t\t\t   const char *password);\n #else\n static inline int nan_pairing_add_attrs(struct nan_data *nan_data,\n \t\t\t\t\tstruct wpabuf *buf)\n {\n \treturn 0;\n }\n+\n+static inline\n+int nan_pairing_initiate_pasn_auth(struct nan_data *nan_data, const u8 *addr,\n+\t\t\t\t   u8 auth_mode, int cipher, int handle,\n+\t\t\t\t   u8 peer_instance_id, bool responder,\n+\t\t\t\t   const char *password)\n+{\n+\treturn -1;\n+}\n #endif /* CONFIG_PASN */\n \n #endif /* NAN_H */\ndiff --git a/src/nan/nan_i.h b/src/nan/nan_i.h\nindex 4983184690..25ca5b011b 100644\n--- a/src/nan/nan_i.h\n+++ b/src/nan/nan_i.h\n@@ -24,6 +24,8 @@ struct nan_config;\n #define NAN_KEK_MAX_LEN 32\n #define NAN_TK_MAX_LEN  32\n \n+#define NAN_IE_MAX_SIZE 1024\n+\n /**\n  * struct nan_ptk - NAN Pairwise Transient Key\n  * @kck: Key Confirmation Key\n@@ -446,6 +448,49 @@ struct nan_bootstrap {\n \tstruct wpabuf *npba;\n };\n \n+/**\n+ * enum nan_pasn_auth_mode - NAN pairing authentication modes\n+ *\n+ * @NAN_PASN_AUTH_MODE_PASN: Unauthenticated PASN\n+ * @NAN_PASN_AUTH_MODE_SAE: PASN authentication with SAE tunneling\n+ * @NAN_PASN_AUTH_MODE_PMK: PASN authentication with PMK caching\n+ */\n+enum nan_pasn_auth_mode {\n+\tNAN_PASN_AUTH_MODE_PASN = 0,\n+\tNAN_PASN_AUTH_MODE_SAE = 1,\n+\tNAN_PASN_AUTH_MODE_PMK = 2,\n+};\n+\n+/**\n+ * enum nan_pairing_role - NAN pairing role types\n+ *\n+ * @NAN_PAIRING_ROLE_IDLE: No active pairing role\n+ * @NAN_PAIRING_ROLE_INITIATOR: Device acting as pairing initiator\n+ * @NAN_PAIRING_ROLE_RESPONDER: Device acting as pairing responder\n+ */\n+enum nan_pairing_role {\n+\tNAN_PAIRING_ROLE_IDLE,\n+\tNAN_PAIRING_ROLE_INITIATOR,\n+\tNAN_PAIRING_ROLE_RESPONDER,\n+};\n+\n+/**\n+ * struct nan_pairing_peer_data - NAN pairing peer information\n+ *\n+ * @pairing_cfg: NAN pairing configuration parameters\n+ * @self_pairing_role: Role of this device in the pairing process\n+ * @pasn: Pointer to PASN data\n+ * @handle: Handle of the local service instance\n+ * @peer_instance_id: Instance ID of the peer service\n+ */\n+struct nan_pairing_peer_data {\n+\tstruct nan_pairing_cfg pairing_cfg;\n+\tenum nan_pairing_role self_pairing_role;\n+\tstruct pasn_data *pasn;\n+\tint handle;\n+\tint peer_instance_id;\n+};\n+\n /**\n  * struct nan_peer - Represents a known NAN peer\n  * @list: List node for linking peers\n@@ -458,6 +503,7 @@ struct nan_bootstrap {\n  *     progress\n  * @ndl: NDL data associated with this peer\n  * @bootstrap: Bootstrap information of the peer\n+ * @pairing: Pairing data associated with this peer\n  */\n struct nan_peer {\n \tstruct dl_list list;\n@@ -473,6 +519,8 @@ struct nan_peer {\n \tstruct nan_ndl *ndl;\n \n \tstruct nan_bootstrap bootstrap;\n+\n+\tstruct nan_pairing_peer_data pairing;\n };\n \n /**\n@@ -702,6 +750,7 @@ int nan_add_nira_attr(struct wpabuf *buf, const u8 *nira_tag,\n #ifdef CONFIG_PASN\n int nan_nira_get_tag_nonce(const struct nan_config *nan, u8 *nira_nonce,\n \t\t\t   u8 *nira_tag);\n+void nan_pairing_deinit_peer(struct nan_peer *peer);\n #else\n static inline\n int nan_nira_get_tag_nonce(const struct nan_config *nan, u8 *nira_nonce,\n@@ -709,6 +758,9 @@ int nan_nira_get_tag_nonce(const struct nan_config *nan, u8 *nira_nonce,\n {\n \treturn -1;\n }\n+\n+static inline void nan_pairing_deinit_peer(struct nan_peer *peer)\n+{}\n #endif /* CONFIG_PASN */\n \n #endif /* NAN_I_H */\ndiff --git a/src/nan/nan_pairing.c b/src/nan/nan_pairing.c\nindex 60c523c64e..3fb32631b0 100644\n--- a/src/nan/nan_pairing.c\n+++ b/src/nan/nan_pairing.c\n@@ -9,6 +9,7 @@\n #include \"includes.h\"\n #include \"common.h\"\n #include \"nan/nan_i.h\"\n+#include \"pasn/pasn_common.h\"\n \n /*\n  * nan_nira_get_tag_nonce - Generate NIRA nonce and compute NIRA tag\n@@ -79,3 +80,359 @@ int nan_pairing_add_attrs(struct nan_data *nan, struct wpabuf *buf)\n \n \treturn 0;\n }\n+\n+\n+void nan_pairing_deinit_peer(struct nan_peer *peer)\n+{\n+\tif (!peer->pairing.pasn)\n+\t\treturn;\n+\n+\twpa_pasn_reset(peer->pairing.pasn);\n+\tpasn_data_deinit(peer->pairing.pasn);\n+\tpeer->pairing.pasn = NULL;\n+\tpeer->pairing.self_pairing_role = NAN_PAIRING_ROLE_IDLE;\n+}\n+\n+\n+static bool nan_pairing_is_supported(struct nan_data *nan_data,\n+\t\t\t\t     struct nan_peer *peer, u8 auth_mode)\n+{\n+\tif (auth_mode == NAN_PASN_AUTH_MODE_PASN ||\n+\t    auth_mode == NAN_PASN_AUTH_MODE_SAE) {\n+\t\tif (!nan_data->cfg->pairing_cfg.pairing_setup) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: Pairing: Device doesn't support pairing setup\");\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\tif (!peer->pairing.pairing_cfg.pairing_setup) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: Pairing: Peer doesn't support pairing setup\");\n+\t\t\treturn false;\n+\t\t}\n+\t} else if (auth_mode == NAN_PASN_AUTH_MODE_PMK) {\n+\t\tif (!nan_data->cfg->pairing_cfg.pairing_verification) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: Pairing: Device doesn't support pairing verification\");\n+\t\t\treturn false;\n+\t\t}\n+\n+\t\tif (!peer->pairing.pairing_cfg.pairing_verification) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: Pairing: Peer doesn't support pairing verification\");\n+\t\t\treturn false;\n+\t\t}\n+\t}\n+\n+\treturn true;\n+}\n+\n+\n+static int nan_pairing_set_password(struct pasn_data *pasn,\n+\t\t\t\t    const char *passphrase)\n+{\n+#ifdef CONFIG_SAE\n+\tstruct sae_pt *pt;\n+\n+\tpasn->pasn_groups = os_calloc(2, sizeof(*pasn->pasn_groups));\n+\tif (!pasn->pasn_groups) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: Pairing: Failed to allocate PASN groups\");\n+\t\treturn -1;\n+\t}\n+\n+\tpasn->pasn_groups[0] = pasn->group;\n+\n+\tpt = sae_derive_pt(pasn->pasn_groups, (const u8 *)NAN_PASN_SSID,\n+\t\t\t   os_strlen(NAN_PASN_SSID), (const u8 *)passphrase,\n+\t\t\t   os_strlen(passphrase), NULL, 0);\n+\tif (pasn_set_pt(pasn, pt) < 0) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: Pairing: Failed to set SAE pt\");\n+\t\tsae_deinit_pt(pt);\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+#else  /* CONFIG_SAE */\n+\treturn -1;\n+#endif /* CONFIG_SAE */\n+}\n+\n+\n+static struct wpabuf *nan_pairing_generate_rsnxe(int akmp)\n+{\n+\t/* According to Wi-Fi Aware Specification version 4.0, Table 26,\n+\t * the RSNXE's capabilities field in NAN PASN frames is 16 bits long\n+\t */\n+\tu16 capab = 1; /* bit 0-3 = Field length (n - 1) */\n+\n+\tstruct wpabuf *buf;\n+\n+\tif (wpa_key_mgmt_sae(akmp))\n+\t\tcapab |= BIT(WLAN_RSNX_CAPAB_SAE_H2E);\n+\n+\t/* IE header (2 octets) + capabilities field (2 octets) */\n+\tbuf = wpabuf_alloc(4);\n+\tif (!buf)\n+\t\treturn NULL;\n+\n+\twpa_printf(MSG_DEBUG, \"RSNXE capabilities: %04x\", capab);\n+\twpabuf_put_u8(buf, WLAN_EID_RSNX);\n+\twpabuf_put_u8(buf, 2);\n+\twpabuf_put_le16(buf, capab);\n+\treturn buf;\n+}\n+\n+\n+static int nan_pairing_send_cb(void *ctx, const u8 *data, size_t data_len,\n+\t\t\t       int noack, unsigned int freq, unsigned int wait)\n+{\n+\tstruct nan_data *nan_data = (struct nan_data *)ctx;\n+\n+\treturn nan_data->cfg->send_pasn(nan_data->cfg->cb_ctx, data, data_len);\n+}\n+\n+\n+static int nan_pairing_pasn_initialize(struct nan_data *nan_data,\n+\t\t\t\t       struct nan_peer *peer, u8 auth_mode,\n+\t\t\t\t       int cipher, const char *password,\n+\t\t\t\t       enum nan_pairing_role self_role)\n+{\n+\tstruct wpabuf *rsnxe = NULL;\n+\tstruct pasn_data *pasn;\n+\tstruct nan_pairing_peer_data *pairing;\n+\n+\tpairing = &peer->pairing;\n+\tif (pairing->pasn) {\n+\t\twpa_pasn_reset(pairing->pasn);\n+\t} else {\n+\t\tpairing->pasn = pasn_data_init();\n+\t\tif (!pairing->pasn) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: Pairing: Failed to initialize PASN data\");\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\tpasn = pairing->pasn;\n+\tpasn_set_own_addr(pasn, nan_data->cfg->nmi_addr);\n+\tpasn_set_peer_addr(pasn, peer->nmi_addr);\n+\tpasn_set_bssid(pasn, nan_data->cluster_id);\n+\n+\tif (self_role == NAN_PAIRING_ROLE_INITIATOR)\n+\t\tpasn->pmksa = nan_data->initiator_pmksa;\n+\telse\n+\t\tpasn->pmksa = nan_data->responder_pmksa;\n+\n+\tif (cipher == WPA_CIPHER_GCMP_256 &&\n+\t    (nan_data->cfg->pairing_cfg.cipher_suites & NAN_PAIRING_PASN_256)) {\n+\t\tpasn->group = 20;\n+\t\tpasn->cipher = WPA_CIPHER_GCMP_256;\n+\t} else if (cipher == WPA_CIPHER_CCMP &&\n+\t\t   (nan_data->cfg->pairing_cfg.cipher_suites &\n+\t\t    NAN_PAIRING_PASN_128)) {\n+\t\tpasn->group = 19;\n+\t\tpasn->cipher = WPA_CIPHER_CCMP;\n+\t} else {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: Pairing: Unsupported cipher suite %s\",\n+\t\t\t   wpa_cipher_txt(cipher));\n+\t\tgoto fail;\n+\t}\n+\n+\tpasn_enable_kdk_derivation(pasn);\n+\n+\tif (auth_mode == NAN_PASN_AUTH_MODE_SAE) {\n+\t\tpasn_set_akmp(pasn, WPA_KEY_MGMT_SAE);\n+\t\tif (!password) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: Pairing: Password not available\");\n+\t\t\tgoto fail;\n+\t\t}\n+\n+\t\tif (nan_pairing_set_password(pasn, password) < 0) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: Pairing: Failed to set password\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t} else if (auth_mode == NAN_PASN_AUTH_MODE_PASN) {\n+\t\tpasn_set_akmp(pasn, WPA_KEY_MGMT_PASN);\n+\t\tpasn_set_noauth(pasn, true);\n+\n+\t\t/* Set allowed PASN groups for the responder to validate */\n+\t\tpasn->pasn_groups = os_calloc(2, sizeof(*pasn->pasn_groups));\n+\t\tif (!pasn->pasn_groups) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: Pairing: Failed to allocate PASN groups\");\n+\t\t\tgoto fail;\n+\t\t}\n+\t\tpasn->pasn_groups[0] = pasn->group;\n+\t} else {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: Pairing: Unsupported authentication mode %u\",\n+\t\t\t   auth_mode);\n+\t\tgoto fail;\n+\t}\n+\n+\tpasn_set_rsn_pairwise(pasn, pasn->cipher);\n+\tpasn_set_wpa_key_mgmt(pasn, pasn->akmp);\n+\n+\tif (auth_mode != NAN_PASN_AUTH_MODE_PASN) {\n+\t\trsnxe = nan_pairing_generate_rsnxe(pasn->akmp);\n+\t\tif (!rsnxe) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: Pairing: Failed to generate RSNXE\");\n+\t\t\tgoto fail;\n+\t\t}\n+\n+\t\tpasn_set_rsnxe_ie(pairing->pasn, wpabuf_head_u8(rsnxe));\n+\t\twpabuf_free(rsnxe);\n+\t}\n+\n+\tpasn_register_callbacks(pasn, nan_data, nan_pairing_send_cb, NULL,\n+\t\t\t\tNULL, NULL);\n+\treturn 0;\n+\n+fail:\n+\tpasn_data_deinit(pasn);\n+\tpairing->pasn = NULL;\n+\treturn -1;\n+}\n+\n+\n+/*\n+ * nan_pairing_prepare_pasn_elems - Prepare NAN IE for pairing PASN frames\n+ *\n+ * @nan_data: Pointer to NAN data structure\n+ * @peer: Pointer to NAN peer structure\n+ * @extra_ies: Buffer to append the NAN IE to\n+ * @publish_id: Publish ID to use in the CSIA\n+ *\n+ * This function adds a NAN IE containing the NAN attributes that shall be\n+ * included in the first and second PASN frames for NAN pairing.\n+ * The attributes added are:\n+ * - Device Capability Extension attribute (DCEA)\n+ * - Cipher suite information attribute (CSIA) with appropriate PASN cipher\n+ *   (either GCMP-256 or GCMP-128)\n+ * - NAN Pairing Bootstrapping Attribute (NPBA) if available\n+ */\n+static void nan_pairing_prepare_pasn_elems(struct nan_data *nan_data,\n+\t\t\t\t\t   struct nan_peer *peer,\n+\t\t\t\t\t   struct wpabuf *extra_ies,\n+\t\t\t\t\t   int publish_id)\n+{\n+\tu8 *len_ptr;\n+\tstruct nan_cipher_suite cs;\n+\tsize_t initial_len = wpabuf_len(extra_ies);\n+\n+\twpabuf_put_u8(extra_ies, WLAN_EID_VENDOR_SPECIFIC);\n+\n+\t/* placeholder for length - to be filled later */\n+\tlen_ptr = wpabuf_put(extra_ies, 1);\n+\n+\t/* OUI + OUI Type */\n+\twpabuf_put_be32(extra_ies, NAN_IE_VENDOR_TYPE);\n+\n+\tnan_add_dev_capa_ext_attr(nan_data, extra_ies);\n+\tif (peer->pairing.pasn->cipher == WPA_CIPHER_GCMP_256)\n+\t\tcs.csid = NAN_CS_PK_PASN_256;\n+\telse\n+\t\tcs.csid = NAN_CS_PK_PASN_128;\n+\n+\tcs.instance_id = publish_id;\n+\n+\t/*\n+\t * TODO: get security capabilities from somewhere. For now, it doesn't\n+\t * matter as the capability field is not used in pairing anyway\n+\t */\n+\tnan_add_csia(extra_ies, 0, 1, &cs);\n+\n+\tif (peer->bootstrap.npba)\n+\t\twpabuf_put_buf(extra_ies, peer->bootstrap.npba);\n+\n+\t*len_ptr = wpabuf_len(extra_ies) - initial_len - 2;\n+}\n+\n+\n+/*\n+ * nan_pairing_initiate_pasn_auth - Initiate PASN authentication for NAN pairing\n+ *\n+ * @nan_data: NAN data context\n+ * @addr: MAC address of the peer device\n+ * @auth_mode: Authentication mode to be used (PASN, SAE or PMK)\n+ * @cipher: Cipher suite to be used for the pairing\n+ * @handle: Handle of the service instance for which pairing is requested\n+ * @peer_instance_id: Instance ID of the peer service for which pairing is\n+ *\trequested\n+ * @responder: Whether this device is acting as PASN responder\n+ * @password: Password to be used for authentication (if applicable)\n+ *\n+ * Returns: 0 on success, -1 on failure\n+ */\n+int nan_pairing_initiate_pasn_auth(struct nan_data *nan_data, const u8 *addr,\n+\t\t\t\t   u8 auth_mode, int cipher, int handle,\n+\t\t\t\t   u8 peer_instance_id, bool responder,\n+\t\t\t\t   const char *password)\n+{\n+\tint ret = 0;\n+\tstruct pasn_data *pasn;\n+\tstruct nan_peer *peer;\n+\tstruct wpabuf *extra_ies;\n+\n+\tif (!addr) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: Pairing: Peer address missing\");\n+\t\treturn -1;\n+\t}\n+\n+\tpeer = nan_get_peer(nan_data, addr);\n+\tif (!peer) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: Pairing: Peer not known\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (!nan_pairing_is_supported(nan_data, peer, auth_mode)) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: Pairing: Invalid params to initiate Authentication\");\n+\t\treturn -1;\n+\t}\n+\n+\tpeer->pairing.self_pairing_role =\n+\t    responder ? NAN_PAIRING_ROLE_RESPONDER : NAN_PAIRING_ROLE_INITIATOR;\n+\n+\tif (nan_pairing_pasn_initialize(nan_data, peer, auth_mode, cipher,\n+\t\t\t\t\tpassword,\n+\t\t\t\t\tpeer->pairing.self_pairing_role)) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: Pairing: Initialize failed\");\n+\t\treturn -1;\n+\t}\n+\n+\tpasn = peer->pairing.pasn;\n+\n+\textra_ies = wpabuf_alloc(NAN_IE_MAX_SIZE);\n+\tif (!extra_ies)\n+\t\treturn -1;\n+\n+\t/* TODO: Add support for NAN IE fragmentation if it's larger than 255\n+\t * octets, as defined in Wi-Fi Aware Specification v4.0 Section 9.1\n+\t */\n+\tnan_pairing_prepare_pasn_elems(nan_data, peer, extra_ies, handle);\n+\tpasn_set_extra_ies(pasn, wpabuf_head_u8(extra_ies),\n+\t\t\t   wpabuf_len(extra_ies));\n+\twpabuf_free(extra_ies);\n+\n+\tpeer->pairing.handle = handle;\n+\tpeer->pairing.peer_instance_id = peer_instance_id;\n+\n+\tif (responder)\n+\t\treturn 0;\n+\n+\tret = wpas_pasn_start(pasn, pasn->own_addr, pasn->peer_addr,\n+\t\t\t      pasn->bssid, pasn->akmp, pasn->cipher,\n+\t\t\t      pasn->group, 0, NULL, 0, NULL, 0, NULL);\n+\tif (ret) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: Pairing: Failed to start PASN\");\n+\t\tnan_pairing_deinit_peer(peer);\n+\t}\n+\n+\treturn ret;\n+}\n","prefixes":["18/92"]}