{"id":2198434,"url":"http://patchwork.ozlabs.org/api/1.0/patches/2198434/?format=json","project":{"id":22,"url":"http://patchwork.ozlabs.org/api/1.0/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":""},"msgid":"<20260219202514.5781-38-andrei.otcheretianski@intel.com>","date":"2026-02-19T20:24:53","name":"[37/58] NAN: Add NAN cryptographic functions","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"3d846286f28183fc92eb2d919fa3f0a4aeaf46f0","submitter":{"id":62065,"url":"http://patchwork.ozlabs.org/api/1.0/people/62065/?format=json","name":"Andrei Otcheretianski","email":"andrei.otcheretianski@intel.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/hostap/patch/20260219202514.5781-38-andrei.otcheretianski@intel.com/mbox/","series":[{"id":492721,"url":"http://patchwork.ozlabs.org/api/1.0/series/492721/?format=json","date":"2026-02-19T20:24:21","name":"NAN: Add NAN Data Path (NDP) support","version":1,"mbox":"http://patchwork.ozlabs.org/series/492721/mbox/"}],"check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2198434/checks/","tags":{},"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=QP3ZVyzQ;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n secure) header.d=infradead.org header.i=@infradead.org header.a=rsa-sha256\n header.s=desiato.20200630 header.b=euhJAoEC;\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=fXt2NfwC;\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 4fH4hr2PxNz1xpY\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 20 Feb 2026 07:28:44 +1100 (AEDT)","from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1vtAdD-0000000Bz7w-06ln;\n\tThu, 19 Feb 2026 20:28:15 +0000","from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1vtAd2-0000000Byrc-0E80\n\tfor hostap@bombadil.infradead.org;\n\tThu, 19 Feb 2026 20:28:04 +0000","from mgamail.intel.com ([198.175.65.10])\n\tby desiato.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1vtAcn-00000001pxP-2x0p\n\tfor hostap@lists.infradead.org;\n\tThu, 19 Feb 2026 20:27:56 +0000","from orviesa004.jf.intel.com ([10.64.159.144])\n  by orvoesa102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 19 Feb 2026 12:27:15 -0800","from aotchere-mobl1.ger.corp.intel.com (HELO\n aotchere-mobl1.intel.com) ([10.245.246.171])\n  by orviesa004-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 19 Feb 2026 12:27:12 -0800"],"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=aPgJUef0oLFYlgOFTINoMcR8zukeYD5DsNJURzPSSmA=; b=QP3ZVyzQaGUL9r\n\tPqRGf99JKj7Tgm3gY7jBbSEGnp48YEeCHWzhFpuzrg1WRY7knqDRAzIP57uni7PXYS7gdnf2A1qaE\n\tCzRKr0wojZtia901zDFwgRUfgygFJWZHEcphMKdpULykKU09KKRsyv20aGHqg0cx57e2zeAlOmdyI\n\tv/iTRdLvvPRk9U++uHs2JBhXRWARtJRMuqdcw6rSvV0IcATdZ3PwH7yCJYo9feDiGnB2IR2HuII1+\n\tLvkb1/I1D2QKa4HiQu1UCVpZNhn2T1u1vyS9n4N9dWH4yQrFBZ410bZhB1IYNgwFXvqQRx01BKO5l\n\tLjQEv7Zyj/srYH5TDLiA==;","v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version\n\t:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:\n\tContent-Type:Content-ID:Content-Description;\n\tbh=Irpz6y/dtDW1vAIJXcDZfeFgoRBovP824ngko8kIXag=; b=euhJAoECRF2Iw1bYml1XqggVIM\n\tgfqq7J3wAaaBPPa+9MfCY7Ety8WpiTR3Wo7teivgrY2/c9UX+UG6EeuJ/u3zwPJzl2RPC7cRikmpm\n\tGlv+lZhJOfGAajh7wPFCB+VuiLTJjbeZoi4mHIPrX19jvJK8Gg4ODCuPI6j4m+iOXItTd7Hjt70K1\n\tGeM5MJPUYx3DinX+MTtmWcenxIEQ54D+7jlmKf+RX3nXNOFpRgtBWbo/juviG79czcflNegrnooPb\n\tjdxHpq1kRUtPPjVZKWoOzgjvLEDQVNqeYaHVoPZhKJsWYH2v5nUYRJ5rElvwxagwSoy0mWCKAX16s\n\t5PUPVhBA==;","v=1; a=rsa-sha256; c=relaxed/simple;\n  d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n  t=1771532870; x=1803068870;\n  h=from:to:cc:subject:date:message-id:in-reply-to:\n   references:mime-version:content-transfer-encoding;\n  bh=B2LoYzzOUQVkeXFnLSHDCrD2UkaGLSvx4F5To8lh3xE=;\n  b=fXt2NfwC/GAkdXYQN1GgV94JRY7C5Gzp/UhlB9wNm2IOefdMdV2xAnm5\n   /l+LvgggXunZbkTcg1SmggBOlVIZE8Xj0vVWlrQLMo9oXuYxqGexKjlKW\n   sVxE7FFwVIBuj/DyhpxhSl5fLIM5Je41TktWKpt/6mt8wh/VBa4lAhbC9\n   mSfsgj2c4p+Og2bfwHyvjCq3zhdQ/i+9ggbGn0C1HASaRK1B08ZC9JTtr\n   saW27qUAJSqNR7t8fgfyLEJG9kEOXmmM1DWln0keaCwMzV0fKPt/RUthj\n   7XwjiWn/97P0sd3m4X5m2oGTrZ/Y8ZQiZ+egO/VjDH5mfeRPachha2rKB\n   g==;"],"X-CSE-ConnectionGUID":["yTlApiUXQ2aASMeyNHGVbA==","w4S09uRIQkm37td4zkk6JQ=="],"X-CSE-MsgGUID":["m5+CU7ONQKutW6FuWEjA0A==","KqyvpMgRRJ2EUuVwJvIjag=="],"X-IronPort-AV":["E=McAfee;i=\"6800,10657,11706\"; a=\"90040101\"","E=Sophos;i=\"6.21,300,1763452800\";\n   d=\"scan'208\";a=\"90040101\"","E=Sophos;i=\"6.21,300,1763452800\";\n   d=\"scan'208\";a=\"219153954\""],"X-ExtLoop1":"1","From":"Andrei Otcheretianski <andrei.otcheretianski@intel.com>","To":"hostap@lists.infradead.org,\n\tvamsin@qti.qualcomm.com,\n\tvganneva@qti.qualcomm.com,\n\tmaheshkkv@google.com","Cc":"Ilan Peer <ilan.peer@intel.com>","Subject":"[PATCH 37/58] NAN: Add NAN cryptographic functions","Date":"Thu, 19 Feb 2026 22:24:53 +0200","Message-ID":"<20260219202514.5781-38-andrei.otcheretianski@intel.com>","X-Mailer":"git-send-email 2.52.0","In-Reply-To":"<20260219202514.5781-1-andrei.otcheretianski@intel.com>","References":"<20260219202514.5781-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-20260219_202752_870813_7994D605 ","X-CRM114-Status":"GOOD (  26.19  )","X-Spam-Score":"-2.5 (--)","X-Spam-Report":"Spam detection software,\n running on the system \"desiato.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: Ilan Peer <ilan.peer@intel.com> 1. PTK derivation\n from\n    PMK. 2. Authentication token calculation. 3. EAPOL key MIC calculation 4.\n    PMKID calculation. Add few definitions that are specific to NAN to\n nan_defs.h.    \n Content analysis details:   (-2.5 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                             [198.175.65.10 listed in list.dnswl.org]\n -0.0 SPF_PASS               SPF: sender matches SPF record\n  0.0 SPF_HELO_NONE          SPF: HELO does not publish an SPF Record\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             Message has at least one valid DKIM or DK\n signature\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  0.0 RCVD_IN_VALIDITY_CERTIFIED_BLOCKED RBL: ADMINISTRATOR NOTICE: The\n                             query to Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                          [198.175.65.10 listed in\n sa-trusted.bondedsender.org]\n  0.0 RCVD_IN_VALIDITY_SAFE_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to\n                              Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                             [198.175.65.10 listed in sa-accredit.habeas.com]\n  0.0 RCVD_IN_VALIDITY_RPBL_BLOCKED RBL: ADMINISTRATOR NOTICE: The query to\n                              Validity was blocked.  See\n                             https://knowledge.validity.com/hc/en-us/articles/20961730681243\n                              for more information.\n                             [198.175.65.10 listed in\n bl.score.senderscore.com]\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: Ilan Peer <ilan.peer@intel.com>\n\n1. PTK derivation from PMK.\n2. Authentication token calculation.\n3. EAPOL key MIC calculation\n4. PMKID calculation.\n\nAdd few definitions that are specific to NAN to nan_defs.h.\n\nSigned-off-by: Ilan Peer <ilan.peer@intel.com>\n---\n src/common/nan_defs.h   |   4 +\n src/nan/Makefile        |   3 +-\n src/nan/nan_crypto.c    | 397 ++++++++++++++++++++++++++++++++++++++++\n src/nan/nan_i.h         |  36 ++++\n wpa_supplicant/Makefile |   1 +\n 5 files changed, 439 insertions(+), 2 deletions(-)\n create mode 100644 src/nan/nan_crypto.c","diff":"diff --git a/src/common/nan_defs.h b/src/common/nan_defs.h\nindex 2a9afed628..a5fa13ff7c 100644\n--- a/src/common/nan_defs.h\n+++ b/src/common/nan_defs.h\n@@ -456,6 +456,10 @@ struct ieee80211_nan_qos {\n #define NAN_QOS_MIN_SLOTS_NO_PREF   0\n #define NAN_QOS_MAX_LATENCY_NO_PREF 0xffff\n \n+#define NAN_AUTH_TOKEN_LEN 16\n+#define NAN_KEY_MIC_LEN    16\n+#define NAN_KEY_MIC_24_LEN 24\n+\n /* See Table 121 (Cipher Suite attribute field format) */\n enum nan_cipher_suite_id {\n \tNAN_CS_NONE         = 0,\ndiff --git a/src/nan/Makefile b/src/nan/Makefile\nindex 38665ea234..7d79a2d77e 100644\n--- a/src/nan/Makefile\n+++ b/src/nan/Makefile\n@@ -1,3 +1,2 @@\n-LIB_OBJS= nan.o nan_util.o nan_ndp.o nan_ndl.o\n-\n+LIB_OBJS= nan.o nan_util.o nan_ndp.o nan_ndl.o nan_crypto.o\n include ../lib.rules\ndiff --git a/src/nan/nan_crypto.c b/src/nan/nan_crypto.c\nnew file mode 100644\nindex 0000000000..bc2770e98b\n--- /dev/null\n+++ b/src/nan/nan_crypto.c\n@@ -0,0 +1,397 @@\n+/*\n+ * Wi-Fi Aware - NAN Data link cryptography functions\n+ * Copyright (C) 2025 Intel Corporation\n+ *\n+ * This software may be distributed under the terms of the BSD license.\n+ * See README for more details.\n+ */\n+\n+#include \"includes.h\"\n+#include \"utils/common.h\"\n+#include \"common/ieee802_11_common.h\"\n+#include \"crypto/sha256.h\"\n+#include \"crypto/sha384.h\"\n+#include \"crypto/crypto.h\"\n+#include \"nan_i.h\"\n+\n+#define NAN_KCK_MAX_LEN 24\n+#define NAN_KEK_MAX_LEN 32\n+#define NAN_TK_MAX_LEN  32\n+\n+#define NAN_PTK_LABEL       \"NAN Pairwise key expansion\"\n+#define NAN_PMKID_LABEL     \"NAN PMK Name\"\n+\n+/* NAN ciphers use only SHA256 and SHA384, and SHA384 has a bigger digest */\n+#define MAX_MAC_LEN SHA384_MAC_LEN\n+\n+static u32 nan_crypto_cipher_kck_len(enum nan_cipher_suite_id cipher)\n+{\n+\tswitch (cipher) {\n+\tcase NAN_CS_SK_CCM_128:\n+\t\treturn 16;\n+\tcase NAN_CS_SK_GCM_256:\n+\t\treturn 24;\n+\tdefault:\n+\t\treturn 0;\n+\t}\n+}\n+\n+\n+static u32 nan_crypto_cipher_kek_len(enum nan_cipher_suite_id cipher)\n+{\n+\tswitch (cipher) {\n+\tcase NAN_CS_SK_CCM_128:\n+\t\treturn 16;\n+\tcase NAN_CS_SK_GCM_256:\n+\t\treturn 32;\n+\tdefault:\n+\t\treturn 0;\n+\t}\n+}\n+\n+\n+static u32 nan_cipher_key_len(enum nan_cipher_suite_id cipher)\n+{\n+\tswitch (cipher) {\n+\tcase NAN_CS_SK_CCM_128:\n+\t\treturn 16;\n+\tcase NAN_CS_SK_GCM_256:\n+\t\treturn 32;\n+\tdefault:\n+\t\treturn 0;\n+\t}\n+}\n+\n+\n+static int nan_crypto_sha256(const u8 *plaintext, u32 psize, u8 *output)\n+{\n+\tconst u8 *addrs[1];\n+\tsize_t lens[1];\n+\n+\taddrs[0] = plaintext;\n+\tlens[0] = psize;\n+\n+\treturn sha256_vector(1, addrs,  lens, output);\n+}\n+\n+\n+static int nan_crypto_sha384(const u8 *plaintext, u32 psize, u8 *output)\n+{\n+\tconst u8 *addrs[1];\n+\tsize_t lens[1];\n+\n+\taddrs[0] = plaintext;\n+\tlens[0] = psize;\n+\n+\treturn sha384_vector(1, addrs,  lens, output);\n+}\n+\n+\n+static int nan_crypto_hmac_sha256(const u8 *key, u32 ksize,\n+\t\t\t\t  const u8 *plaintext,\n+\t\t\t\t  u32 psize, u8 *output)\n+{\n+\treturn hmac_sha256(key, ksize, plaintext, psize, output);\n+}\n+\n+\n+static int nan_crypto_hmac_sha384(const u8 *key, u32 ksize,\n+\t\t\t\t  const u8 *plaintext,\n+\t\t\t\t  u32 psize, u8 *output)\n+{\n+\treturn hmac_sha384(key, ksize, plaintext, psize, output);\n+}\n+\n+\n+/*\n+ * nan_crypto_kdf - NAN key derivation function\n+ *\n+ * @key: PMK\n+ * @key_len: PMK length\n+ * @label: Unique string used for the key derivation for NAN\n+ * @data: Input for the key derivation\n+ * @data_len: Length of &input\n+ * @buf: Buffer to hold the derived keys\n+ * @buf_len: Length of &buf\n+ * @hmac_func: Pointer to a hmac function that will be used to compute the\n+ *         digest for each iteration.\n+ * @mac_len: the size of the digest computed by %hmac_func\n+ */\n+static int nan_crypto_kdf(const u8 *key, size_t key_len, const char *label,\n+\t\t\t  const u8 *data, size_t data_len, u8 *buf,\n+\t\t\t  size_t buf_len,\n+\t\t\t  int (*hmac_func)(const u8 *key, u32 ksize,\n+\t\t\t\t\t   const u8 *plaintext, u32 psize,\n+\t\t\t\t\t   u8 *output),\n+\t\t\t  u32 mac_len)\n+{\n+\tu16 label_len = os_strlen(label);\n+\tu32 input_len, pos;\n+\tu8 *input;\n+\tint res = -1;\n+\tu16 counter = 1;\n+\n+\t/*\n+\t * counter length (2) + label length + data length +\n+\t * number of bits (2)\n+\t */\n+\tinput_len = 2 + label_len + data_len + 2;\n+\tinput = os_zalloc(input_len);\n+\tif (!input)\n+\t\treturn -1;\n+\n+\tos_memcpy(input + 2, label, os_strlen(label));\n+\tos_memcpy(input + 2 + label_len, data, data_len);\n+\tWPA_PUT_LE16(input + 2 + label_len + data_len, (buf_len * 8));\n+\n+\tpos = 0;\n+\twhile (pos < buf_len) {\n+\t\tu32 plen = buf_len - pos;\n+\n+\t\tWPA_PUT_LE16(input, counter);\n+\n+\t\twpa_hexdump_key(MSG_DEBUG, \"NAN: KDF: RAW DATA\",\n+\t\t\t\tinput, input_len);\n+\t\tif (plen >= mac_len) {\n+\t\t\tif ((*hmac_func)(key, key_len, input, input_len,\n+\t\t\t\t\t &buf[pos]) < 0)\n+\t\t\t\tgoto fail;\n+\t\t\tpos += mac_len;\n+\t\t} else {\n+\t\t\tu8 hash[MAX_MAC_LEN];\n+\n+\t\t\tif ((*hmac_func)(key, key_len, input, input_len,\n+\t\t\t\t\t hash) < 0)\n+\t\t\t\tgoto fail;\n+\t\t\tos_memcpy(&buf[pos], hash, plen);\n+\t\t\tpos += plen;\n+\t\t\tforced_memzero(hash, sizeof(hash));\n+\t\t\tbreak;\n+\t\t}\n+\t\tcounter++;\n+\t}\n+\n+\tres = 0;\n+fail:\n+\tforced_memzero(input, input_len);\n+\tos_free(input);\n+\n+\treturn res;\n+}\n+\n+\n+/*\n+ * nan_crypto_pmk_to_ptk - Calculate PTK from PMK, addresses, and nonces\n+ *\n+ * @pmk: Pairwise master key\n+ * @iaddr: Initiator address\n+ * @raddr: Remote address\n+ * @inonce: Initiator nonce\n+ * @rnonce: Remote nonce\n+ * @ptk: Buffer for Pairwise Transient Key\n+ * @cipher: Negotiated pairwise cipher\n+ * returns: 0 on success, negative value of failure\n+ */\n+int nan_crypto_pmk_to_ptk(const u8 *pmk, const u8 *iaddr, const u8 *raddr,\n+\t\t\t  const u8 *inonce, const u8 *rnonce,\n+\t\t\t  struct nan_ptk *ptk,\n+\t\t\t  enum nan_cipher_suite_id cipher)\n+{\n+\tu8 data[2 * ETH_ALEN + 2 * WPA_NONCE_LEN];\n+\tu8 tmp[NAN_KCK_MAX_LEN + NAN_KEK_MAX_LEN + NAN_TK_MAX_LEN];\n+\tsize_t ptk_len;\n+\tint ret;\n+\n+\tif (cipher != NAN_CS_SK_CCM_128 && cipher != NAN_CS_SK_GCM_256)\n+\t\treturn -1;\n+\n+\tif (!ptk)\n+\t\treturn -1;\n+\n+\tos_memcpy(data, iaddr, ETH_ALEN);\n+\tos_memcpy(data + ETH_ALEN, raddr, ETH_ALEN);\n+\tos_memcpy(data + 2 * ETH_ALEN, inonce, WPA_NONCE_LEN);\n+\tos_memcpy(data + 2 * ETH_ALEN + WPA_NONCE_LEN, rnonce,\n+\t\t  WPA_NONCE_LEN);\n+\n+\tptk->kck_len = nan_crypto_cipher_kck_len(cipher);\n+\tptk->kek_len = nan_crypto_cipher_kek_len(cipher);\n+\tptk->tk_len = nan_cipher_key_len(cipher);\n+\tptk_len = ptk->kck_len + ptk->kek_len + ptk->tk_len;\n+\n+\tif (cipher == NAN_CS_SK_CCM_128)\n+\t\tret = nan_crypto_kdf(pmk, PMK_LEN, NAN_PTK_LABEL, data,\n+\t\t\t\t     sizeof(data), tmp, ptk_len,\n+\t\t\t\t     nan_crypto_hmac_sha256,\n+\t\t\t\t     SHA256_MAC_LEN);\n+\telse\n+\t\tret = nan_crypto_kdf(pmk, PMK_LEN, NAN_PTK_LABEL, data,\n+\t\t\t\t     sizeof(data), tmp, ptk_len,\n+\t\t\t\t     nan_crypto_hmac_sha384,\n+\t\t\t\t     SHA384_MAC_LEN);\n+\n+\tif (ret)\n+\t\tgoto out;\n+\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: PMK\", pmk, PMK_LEN);\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: iaddr\", iaddr, ETH_ALEN);\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: raddr\", raddr, ETH_ALEN);\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: inonce\", inonce, WPA_NONCE_LEN);\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: rnonce\", rnonce, WPA_NONCE_LEN);\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: PTK\", tmp, ptk_len);\n+\n+\tos_memcpy(ptk->kck, tmp, ptk->kck_len);\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: KCK\", ptk->kck, ptk->kck_len);\n+\n+\tos_memcpy(ptk->kek, tmp + ptk->kck_len, ptk->kek_len);\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: KEK\", ptk->kek, ptk->kek_len);\n+\n+\tos_memcpy(ptk->tk, tmp + ptk->kck_len + ptk->kek_len, ptk->tk_len);\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: TK\", ptk->tk, ptk->tk_len);\n+\n+out:\n+\tforced_memzero(data, sizeof(data));\n+\tforced_memzero(tmp, sizeof(tmp));\n+\treturn ret;\n+}\n+\n+\n+/*\n+ * nan_crypto_calc_pmkid - Calculate a NAN PMKID\n+ * @pmk: Pairwise Master Key\n+ * @iaddr: Initiator address\n+ * @raddr: Remote address\n+ * @serv_id: ID of the service providing the PMK\n+ * @cipher: Negotiated pairwise cipher\n+ * @pmkid: Buffer to hold the pmkid\n+ * returns: 0 on success, negative value of failure\n+ */\n+int nan_crypto_calc_pmkid(const u8 *pmk, const u8 *iaddr, const u8 *raddr,\n+\t\t\t  const u8 *serv_id,\n+\t\t\t  enum nan_cipher_suite_id cipher, u8 *pmkid)\n+{\n+\tu8 data[sizeof(NAN_PMKID_LABEL) - 1 + 2 * ETH_ALEN +\n+\t\tNAN_SERVICE_ID_LEN];\n+\tu8 digest[SHA384_MAC_LEN];\n+\tint ret;\n+\n+\tos_memset(data, 0, sizeof(data));\n+\tos_memset(digest, 0, sizeof(digest));\n+\n+\tif (cipher != NAN_CS_SK_CCM_128 && cipher != NAN_CS_SK_GCM_256)\n+\t\treturn -1;\n+\n+\tif (!serv_id)\n+\t\treturn -1;\n+\n+\tif (is_zero_ether_addr(serv_id))\n+\t\treturn -1;\n+\n+\tos_memcpy(data, NAN_PMKID_LABEL, sizeof(NAN_PMKID_LABEL) - 1);\n+\tos_memcpy(data + sizeof(NAN_PMKID_LABEL) - 1, iaddr, ETH_ALEN);\n+\tos_memcpy(data + sizeof(NAN_PMKID_LABEL) - 1 + ETH_ALEN, raddr,\n+\t\t  ETH_ALEN);\n+\tos_memcpy(data + sizeof(NAN_PMKID_LABEL) - 1 + 2 * ETH_ALEN, serv_id,\n+\t\t  NAN_SERVICE_ID_LEN);\n+\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: PMKID DATA\", data, sizeof(data));\n+\n+\tif (cipher == NAN_CS_SK_CCM_128)\n+\t\tret = nan_crypto_hmac_sha256(pmk, PMK_LEN, data,\n+\t\t\t\t\t     sizeof(data), digest);\n+\telse\n+\t\tret = nan_crypto_hmac_sha384(pmk, PMK_LEN, data,\n+\t\t\t\t\t     sizeof(data), digest);\n+\n+\tif (ret)\n+\t\tgoto out;\n+\n+\tos_memcpy(pmkid, digest, PMKID_LEN);\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: PMKID\", pmkid, PMKID_LEN);\n+\n+out:\n+\tforced_memzero(digest, sizeof(digest));\n+\treturn ret;\n+}\n+\n+\n+/*\n+ * nan_crypto_calc_auth_token - calculate authentication token\n+ *\n+ * @buf: Buffer on which to calculate the authentication token\n+ * @len: Length of &buf\n+ * @cipher: Negotiated nan cipher\n+ * @token: Buffer to hold the token (NAN_AUTH_TOKEN_LEN octets)\n+ * returns 0 on success, and a negative error value on failure.\n+ */\n+int nan_crypto_calc_auth_token(enum nan_cipher_suite_id cipher,\n+\t\t\t       const u8 *buf, size_t len, u8 *token)\n+{\n+\tu8 hash[MAX_MAC_LEN];\n+\tint ret;\n+\n+\tif (cipher != NAN_CS_SK_CCM_128 && cipher != NAN_CS_SK_GCM_256)\n+\t\treturn -1;\n+\n+\tif (cipher == NAN_CS_SK_CCM_128)\n+\t\tret = nan_crypto_sha256(buf, len, hash);\n+\telse\n+\t\tret = nan_crypto_sha384(buf, len, hash);\n+\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tos_memcpy(token, hash, NAN_AUTH_TOKEN_LEN);\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: AUTH_TOKEN_DATA\", buf, len);\n+\twpa_hexdump_key(MSG_DEBUG, \"NAN: AUTH TOKEN\", token,\n+\t\t\tNAN_AUTH_TOKEN_LEN);\n+\n+\tforced_memzero(hash, sizeof(hash));\n+\n+\treturn ret;\n+}\n+\n+\n+/*\n+ * nan_crypto_key_mic - Calculate MIC over the given buffer\n+ *\n+ * @buf: Buffer on which to calculate the MIC\n+ * @len: Length of &buf\n+ * @kck: Key Confirmation Key\n+ * @kck_len: Length of &kck\n+ * @cipher: Cipher suite identifier.\n+ * @mic: On successful return, would hold the MIC.\n+ * return 0 on success, and a negative error value on failure.\n+ */\n+int nan_crypto_key_mic(const u8 *buf, size_t len, const u8 *kck,\n+\t\t       size_t kck_len, u8 cipher, u8 *mic)\n+{\n+\tu8 digest[SHA384_MAC_LEN];\n+\tu8 mic_len;\n+\tint ret;\n+\n+\tos_memset(digest, 0, sizeof(digest));\n+\n+\tif (cipher != NAN_CS_SK_CCM_128 && cipher != NAN_CS_SK_GCM_256)\n+\t\treturn -1;\n+\n+\twpa_hexdump_key(MSG_DEBUG, \"MIC DATA\", buf, len);\n+\twpa_hexdump_key(MSG_DEBUG, \"MIC KEY\", kck, kck_len);\n+\n+\tif (cipher == NAN_CS_SK_CCM_128) {\n+\t\tmic_len = NAN_KEY_MIC_LEN;\n+\t\tret = nan_crypto_hmac_sha256(kck, kck_len, buf, len, digest);\n+\t} else {\n+\t\tmic_len = NAN_KEY_MIC_24_LEN;\n+\t\tret = nan_crypto_hmac_sha384(kck, kck_len, buf, len, digest);\n+\t}\n+\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tos_memcpy(mic, digest, mic_len);\n+\tforced_memzero(digest, sizeof(digest));\n+\n+\twpa_hexdump_key(MSG_DEBUG, \"MIC\", mic, mic_len);\n+\treturn 0;\n+}\ndiff --git a/src/nan/nan_i.h b/src/nan/nan_i.h\nindex 89efa8ad47..23d644b99b 100644\n--- a/src/nan/nan_i.h\n+++ b/src/nan/nan_i.h\n@@ -11,6 +11,7 @@\n \n #include \"common/ieee802_11_defs.h\"\n #include \"common/nan_defs.h\"\n+#include \"common/wpa_common.h\"\n #include \"nan.h\"\n #include \"list.h\"\n \n@@ -18,6 +19,30 @@ struct nan_config;\n \n #define NAN_INVALID_MAP_ID 0xff\n \n+#define NAN_KCK_MAX_LEN 24\n+#define NAN_KEK_MAX_LEN 32\n+#define NAN_TK_MAX_LEN  32\n+\n+/**\n+ * struct nan_ptk - NAN Pairwise Transient Key\n+ *\n+ * @kck: Key Confirmation Key\n+ * @kek: Key encryption Key\n+ * @tk: Transient Key\n+ * @kck_len: Length of &kck\n+ * @kek_len: Length of &kek\n+ * @tk_len: Length of &tk\n+ */\n+struct nan_ptk {\n+\tu8 kck[NAN_KCK_MAX_LEN];\n+\tu8 kek[NAN_KEK_MAX_LEN];\n+\tu8 tk[NAN_TK_MAX_LEN];\n+\n+\tsize_t kck_len;\n+\tsize_t kek_len;\n+\tsize_t tk_len;\n+};\n+\n /*\n  * enum nan_ndp_state - State of NDP establishment\n  * @NAN_NDP_STATE_NONE: No NDP establishment in progress.\n@@ -497,4 +522,15 @@ struct bitfield * nan_avail_entries_to_bf(struct nan_data *nan,\n void nan_ndp_terminated(struct nan_data *nan, struct nan_peer *peer,\n \t\t\tstruct nan_ndp_id *ndp_id, const u8 *local_ndi,\n \t\t\tconst u8 *peer_ndi, enum nan_reason reason);\n+int nan_crypto_pmk_to_ptk(const u8 *pmk, const u8 *iaddr, const u8 *raddr,\n+\t\t\t  const u8 *inonce, const u8 *rnonce,\n+\t\t\t  struct nan_ptk *ptk,\n+\t\t\t  enum nan_cipher_suite_id cipher);\n+int nan_crypto_calc_pmkid(const u8 *pmk, const u8 *iaddr, const u8 *raddr,\n+\t\t\t  const u8 *serv_id,\n+\t\t\t  enum nan_cipher_suite_id cipher, u8 *pmkid);\n+int nan_crypto_calc_auth_token(enum nan_cipher_suite_id cipher,\n+\t\t\t       const u8 *buf, size_t len, u8 *token);\n+int nan_crypto_key_mic(const u8 *buf, size_t len, const u8 *kck,\n+\t\t       size_t kck_len, u8 cipher, u8 *mic);\n #endif /* NAN_I_H */\ndiff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile\nindex 7714d326a5..6d2a9a76ac 100644\n--- a/wpa_supplicant/Makefile\n+++ b/wpa_supplicant/Makefile\n@@ -335,6 +335,7 @@ OBJS += ../src/common/nan_de.o\n OBJS += ../src/nan/nan_util.o\n OBJS += ../src/nan/nan_ndp.o\n OBJS += ../src/nan/nan_ndl.o\n+OBJS += ../src/nan/nan_crypto.o\n endif\n \n ifdef CONFIG_PR\n","prefixes":["37/58"]}