get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.0/patches/2198436/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 2198436,
    "url": "http://patchwork.ozlabs.org/api/1.0/patches/2198436/?format=api",
    "project": {
        "id": 22,
        "url": "http://patchwork.ozlabs.org/api/1.0/projects/22/?format=api",
        "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-39-andrei.otcheretianski@intel.com>",
    "date": "2026-02-19T20:24:54",
    "name": "[38/58] NAN: Add support for NDP security Rx flow",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "e945312b12a687e99a879ccea3f4e99867273579",
    "submitter": {
        "id": 62065,
        "url": "http://patchwork.ozlabs.org/api/1.0/people/62065/?format=api",
        "name": "Andrei Otcheretianski",
        "email": "andrei.otcheretianski@intel.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/hostap/patch/20260219202514.5781-39-andrei.otcheretianski@intel.com/mbox/",
    "series": [
        {
            "id": 492721,
            "url": "http://patchwork.ozlabs.org/api/1.0/series/492721/?format=api",
            "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/2198436/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=d+Rk6vB+;\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=IbOCgrYm;\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 4fH4j6521fz1xpY\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 20 Feb 2026 07:28:58 +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 1vtAdS-0000000BzSH-36dx;\n\tThu, 19 Feb 2026 20:28:30 +0000",
            "from mgamail.intel.com ([198.175.65.10])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1vtAcq-0000000BwCB-2kHq\n\tfor hostap@lists.infradead.org;\n\tThu, 19 Feb 2026 20:28:07 +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:18 -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:15 -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=N/+WCeH1CfqZRLq9ntYBNx4Q9q7S1gRGGlT9lV1xL8A=; b=d+Rk6vB+pyKvab\n\tLQPSt+VW54neNyUMyqgXkJ0WB3SPoYkvBSv+TnAfQny4WrxDDc6atT+XDDwW5Bhk8nLo8S6CyjfNB\n\t7CR83x0VfXyLgPCUCXhYlYBS8CueXQrSEcxNzs/xqkcxazQzbeqE7vufF+9ytALT/7rj+SuvCO8Z3\n\tRWiRpBsgBdfhDwycEIXP8SuIvL2XQbwHqizjM5vGCK5L0zOejyK138/+2MASsuIg8kEqH5WsuEyxQ\n\t55OC4eAh2IOooWknODC9MVz6HshCMzxNobE8h5cEqabo5+W41KdotYoYxhsB8ERu8h5N00C0D5foe\n\tioBGOsBgIgz4hhRv/28g==;",
            "v=1; a=rsa-sha256; c=relaxed/simple;\n  d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n  t=1771532873; x=1803068873;\n  h=from:to:cc:subject:date:message-id:in-reply-to:\n   references:mime-version:content-transfer-encoding;\n  bh=lDxm8W/cdCLjDnbrxiK2GT6+dozoxRup4A/Oku53gqs=;\n  b=IbOCgrYmluhz9ih7+USzNk9bImgBTbv/FVvIlbqJDtPmdnCkfOcMgxPd\n   5GwHQ1zT+MxayB8WEKxICA146HGrNeN4Zjwk1i9py9o6VxyenZA2Df1HU\n   ZG14JAQLosz5GQ+Sj2x+BJmO7ihG2GP4JTnOLl6+NKP+FmsxMnKTIa1s4\n   M/S0w3xmY7aQGEqgtGK59yqkF+f3QfinxmWKo6Y9KvSwGl3jLUsRH43dn\n   EzWd3tZ+zzA2T+bDIpsi65zyg+0YY/mjjYtLyH8dbgml102qSWXo0OK6h\n   7p7JGymxKekAuInpXXCPQizqaV8B+0Uye/zSsmbnS7UOnYjWhhysTvzLw\n   A==;"
        ],
        "X-CSE-ConnectionGUID": [
            "hiY69bY/THiFTJ6xVV9jGw==",
            "rQ4OSqbCTtuq8TajLHlxmQ=="
        ],
        "X-CSE-MsgGUID": [
            "AT568gvzQH6wjbHQChi+nA==",
            "hKQhtUtvSbSz6f+GBachzA=="
        ],
        "X-IronPort-AV": [
            "E=McAfee;i=\"6800,10657,11706\"; a=\"90040108\"",
            "E=Sophos;i=\"6.21,300,1763452800\";\n   d=\"scan'208\";a=\"90040108\"",
            "E=Sophos;i=\"6.21,300,1763452800\";\n   d=\"scan'208\";a=\"219153964\""
        ],
        "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 38/58] NAN: Add support for NDP security Rx flow",
        "Date": "Thu, 19 Feb 2026 22:24:54 +0200",
        "Message-ID": "<20260219202514.5781-39-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_122752_848236_82772753 ",
        "X-CRM114-Status": "GOOD (  24.95  )",
        "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: Ilan Peer <ilan.peer@intel.com> Add Rx flow\n processing\n    and state for NDP security attributes. Currently support only shared key\n   flows. Signed-off-by: Ilan Peer <ilan.peer@intel.com> --- src/nan/Makefile\n    | 9 +- src/nan/nan_i.h | 53 ++++ src/nan/nan_sec.c | 625\n ++++++++++++++++++++++++++++++++++++++++\n    wpa_supplicant/Makefile | 1 + 4 fi [...]\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                             [198.175.65.10 listed in list.dnswl.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_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_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 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_EF          Message has a valid DKIM or DK signature from\n                             envelope-from domain\n -0.1 DKIM_VALID             Message has at least one valid DKIM or DK\n signature\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: Ilan Peer <ilan.peer@intel.com>\n\nAdd Rx flow processing and state for NDP security attributes.\nCurrently support only shared key flows.\n\nSigned-off-by: Ilan Peer <ilan.peer@intel.com>\n---\n src/nan/Makefile        |   9 +-\n src/nan/nan_i.h         |  53 ++++\n src/nan/nan_sec.c       | 625 ++++++++++++++++++++++++++++++++++++++++\n wpa_supplicant/Makefile |   1 +\n 4 files changed, 687 insertions(+), 1 deletion(-)\n create mode 100644 src/nan/nan_sec.c",
    "diff": "diff --git a/src/nan/Makefile b/src/nan/Makefile\nindex 7d79a2d77e..ae7879553a 100644\n--- a/src/nan/Makefile\n+++ b/src/nan/Makefile\n@@ -1,2 +1,9 @@\n-LIB_OBJS= nan.o nan_util.o nan_ndp.o nan_ndl.o nan_crypto.o\n+LIB_OBJS= \\\n+\t  nan.o \\\n+\t  nan_util.o \\\n+\t  nan_ndp.o \\\n+\t  nan_ndl.o \\\n+\t  nan_crypto.o \\\n+\t  nan_sec.o\n+\n include ../lib.rules\ndiff --git a/src/nan/nan_i.h b/src/nan/nan_i.h\nindex 23d644b99b..ccba63503c 100644\n--- a/src/nan/nan_i.h\n+++ b/src/nan/nan_i.h\n@@ -43,6 +43,54 @@ struct nan_ptk {\n \tsize_t tk_len;\n };\n \n+/*\n+ * struct nan_ndp_sec - NAN ndp security state\n+ *\n+ * @present: True iff NDP setup exchange includes security\n+ * @valid: True iff the security configuration is valid\n+ * @replaycnt_ok: True iff replay count ok\n+ * @replaycnt: Current replay count\n+ * @i_nonce: Initiator nonce\n+ * @i_capab: Initiator capabilities\n+ * @i_csid: Initiator cipher suite ID\n+ * @i_instance_id: Initiator publish instance ID\n+ * @i_pmkid: Initiator PMKID\n+ * @r_nonce: Responder nonce\n+ * @r_capab: Responder capabilities\n+ * @r_csid: Responder cipher suite ID\n+ * @r_instance_id: Responder instance ID\n+ * @r_pmkid: Responder PMKID\n+ * @auth_token: Authentication token\n+ * @pmk: PMK used for the secure NDP establishment\n+ * @ptk: Derived PTK\n+ */\n+struct nan_ndp_sec {\n+\tbool present;\n+\tbool valid;\n+\n+\tbool replaycnt_ok;\n+\tu8 replaycnt[8];\n+\n+\t/* Initiator data */\n+\tu8 i_nonce[WPA_NONCE_LEN];\n+\tu8 i_capab;\n+\tu8 i_csid;\n+\tu8 i_instance_id;\n+\tu8 i_pmkid[PMKID_LEN];\n+\n+\t/* Responder data */\n+\tu8 r_nonce[WPA_NONCE_LEN];\n+\tu8 r_capab;\n+\tu8 r_csid;\n+\tu8 r_instance_id;\n+\tu8 r_pmkid[PMKID_LEN];\n+\n+\tu8 auth_token[NAN_AUTH_TOKEN_LEN];\n+\tu8 pmk[PMK_LEN];\n+\n+\tstruct nan_ptk ptk;\n+};\n+\n /*\n  * enum nan_ndp_state - State of NDP establishment\n  * @NAN_NDP_STATE_NONE: No NDP establishment in progress.\n@@ -112,6 +160,7 @@ struct nan_ndp {\n  * @ssi: Service specific information\n  * @ssi_len: Service specific information length\n  * @service_id: Service ID of the service used for NDP setup\n+ * @sec: NDP security data\n  */\n struct nan_ndp_setup {\n \tstruct nan_ndp *ndp;\n@@ -125,6 +174,7 @@ struct nan_ndp_setup {\n \tu16 ssi_len;\n \n \tu8 service_id[NAN_SERVICE_ID_LEN];\n+\tstruct nan_ndp_sec sec;\n };\n \n /*\n@@ -533,4 +583,7 @@ 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+void nan_sec_reset(struct nan_data *nan, struct nan_ndp_sec *ndp_sec);\n+int nan_sec_rx(struct nan_data *nan, struct nan_peer *peer,\n+\t       struct nan_msg *msg);\n #endif /* NAN_I_H */\ndiff --git a/src/nan/nan_sec.c b/src/nan/nan_sec.c\nnew file mode 100644\nindex 0000000000..b5f51282ae\n--- /dev/null\n+++ b/src/nan/nan_sec.c\n@@ -0,0 +1,625 @@\n+/*\n+ * Wi-Fi Aware - NAN Data link security\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 \"nan_i.h\"\n+\n+/*\n+ * nan_sec_reset - Reset security state\n+ *\n+ * @nan: NAN module context from nan_init()\n+ * @ndp_sec: NDP security context to reset\n+ */\n+void nan_sec_reset(struct nan_data *nan, struct nan_ndp_sec *ndp_sec)\n+{\n+\tos_memset(ndp_sec, 0, sizeof(*ndp_sec));\n+}\n+\n+\n+static void nan_sec_dump(struct nan_data *nan, struct nan_peer *peer)\n+{\n+\tstruct nan_ndp_sec *s = &peer->ndp_setup.sec;\n+\n+\twpa_printf(MSG_DEBUG,\n+\t\t   \"NAN: SEC: present=%u, valid=%u\",\n+\t\t   s->present, s->valid);\n+\twpa_printf(MSG_DEBUG,\n+\t\t   \"NAN: SEC: i_csid=%u, i_instance_id=%u\",\n+\t\t   s->i_csid, s->i_instance_id);\n+\twpa_printf(MSG_DEBUG,\n+\t\t   \"NAN: SEC: r_csid=%u, r_instance_id=%u\",\n+\t\t   s->r_csid, s->r_instance_id);\n+}\n+\n+\n+static int nan_sec_rx_m1_verify(struct nan_data *nan,\n+\t\t\t\tconst struct nan_attrs *attrs)\n+{\n+\tstruct nan_sec_ctxt *sc;\n+\tu16 expected_len;\n+\n+\texpected_len = sizeof(struct nan_cipher_suite_info) +\n+\t\tsizeof(struct nan_cipher_suite);\n+\n+\tif (!attrs->cipher_suite_info  ||\n+\t    attrs->cipher_suite_info_len < expected_len) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: Missing valid cipher suite attribute\");\n+\t\treturn -1;\n+\t}\n+\n+\t/* Need at least one PMKID */\n+\texpected_len = sizeof(struct nan_sec_ctxt) + PMKID_LEN;\n+\n+\tif (!attrs->sec_ctxt_info  || attrs->sec_ctxt_info_len < expected_len) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: Missing valid security context attribute\");\n+\t\treturn -1;\n+\t}\n+\n+\tsc = (struct nan_sec_ctxt *)attrs->sec_ctxt_info;\n+\tif (sc->scid != NAN_SEC_CTX_TYPE_PMKID ||\n+\t    le_to_host16(sc->len) != PMKID_LEN) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: Got unknown security context\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+\n+static int nan_sec_parse_csia(const u8 *csia, size_t csia_len, u8 *instance_id,\n+\t\t\t      u8 *capab, u8 *csid, u8 *gtk_csid)\n+{\n+\tconst struct nan_cipher_suite_info *cs_info =\n+\t\t(const struct nan_cipher_suite_info *)csia;\n+\tconst u8 *cs_buf = cs_info->cs;\n+\tconst struct nan_cipher_suite *cs;\n+\n+\tif (!csia || csia_len < sizeof(*cs_info)) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: Invalid CSIA attribute\");\n+\t\treturn -1;\n+\t}\n+\n+\t*instance_id = 0;\n+\t*capab = cs_info->capab;\n+\tcsia_len -= sizeof(*cs_info);\n+\n+\t*csid = NAN_CS_NONE;\n+\t*gtk_csid = NAN_CS_NONE;\n+\n+\twhile (csia_len >= sizeof(*cs)) {\n+\t\tcs = (const struct nan_cipher_suite *)(cs_buf);\n+\t\tif (*instance_id && cs->instance_id != *instance_id) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: SEC: Multiple instance IDs in CSIA\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\t*instance_id = cs->instance_id;\n+\n+\t\tif (cs->csid == NAN_CS_GTK_CCMP_128 ||\n+\t\t    cs->csid == NAN_CS_GTK_GCMP_256) {\n+\t\t\tif (*gtk_csid != NAN_CS_NONE) {\n+\t\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t\t   \"NAN: SEC: Multiple GTK CSIDs in CSIA\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\n+\t\t\t*gtk_csid = cs->csid;\n+\t\t} else {\n+\t\t\tif (*csid != NAN_CS_NONE) {\n+\t\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t\t   \"NAN: SEC: Multiple CSIDs in CSIA\");\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\n+\t\t\tif (cs->csid != NAN_CS_SK_CCM_128 &&\n+\t\t\t    cs->csid != NAN_CS_SK_GCM_256) {\n+\t\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t\t   \"NAN: SEC: Unsupported cipher suite=%u\",\n+\t\t\t\t\t   cs->csid);\n+\t\t\t\treturn -1;\n+\t\t\t}\n+\n+\t\t\t*csid = cs->csid;\n+\t\t}\n+\n+\t\tcs_buf += sizeof(*cs);\n+\t\tcsia_len -= sizeof(*cs);\n+\t}\n+\n+\tif (*csid == NAN_CS_NONE) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: No valid CSID in CSIA\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+\n+static int nan_sec_rx_m1(struct nan_data *nan, struct nan_peer *peer,\n+\t\t\t const struct nan_msg *msg,\n+\t\t\t const struct wpa_eapol_key *key)\n+{\n+\tstruct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;\n+\tstruct nan_sec_ctxt *sc;\n+\tu8 instance_id;\n+\tint ret;\n+\n+\tif (peer->ndp_setup.state != NAN_NDP_STATE_REQ_RECV) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: Not expecting m1\");\n+\t\treturn -1;\n+\t}\n+\n+\tret = nan_sec_rx_m1_verify(nan, &msg->attrs);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tsc = (struct nan_sec_ctxt *)msg->attrs.sec_ctxt_info;\n+\n+\tinstance_id = sc->instance_id;\n+\n+\tif (ndp_sec->i_instance_id && instance_id &&\n+\t    ndp_sec->i_instance_id != instance_id) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: Mismatched instance ID\");\n+\t\treturn -1;\n+\t}\n+\n+\tos_memcpy(ndp_sec->i_pmkid, sc->ctxt, PMKID_LEN);\n+\n+\t/* Save initiator's nonce */\n+\tos_memcpy(ndp_sec->i_nonce, key->key_nonce, WPA_NONCE_LEN);\n+\n+\t/* Save the replay counter */\n+\tos_memcpy(ndp_sec->replaycnt, key->replay_counter,\n+\t\t  sizeof(key->replay_counter));\n+\n+\t/* Store the authentication token, that is required for m3 MIC */\n+\tret = nan_crypto_calc_auth_token(ndp_sec->i_csid, (u8 *)&msg->mgmt->u,\n+\t\t\t\t\t msg->len - 24, ndp_sec->auth_token);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* The flow will continue, once higher layer ACK the NDP setup */\n+\tndp_sec->valid = 1;\n+\treturn 0;\n+}\n+\n+\n+static int nan_sec_key_mic_ver(struct nan_data *nan, u8 *buf, size_t len,\n+\t\t\t       const struct wpa_eapol_key *key,\n+\t\t\t       u8 *kck, size_t kck_len, u8 csid)\n+{\n+\tu8 mic[NAN_KEY_MIC_24_LEN];\n+\tu8 *pos = (u8 *)(key + 1);\n+\tu8 mic_len;\n+\tint ret;\n+\n+\tos_memset(mic, 0, sizeof(mic));\n+\n+\tif (csid == NAN_CS_SK_CCM_128)\n+\t\tmic_len = NAN_KEY_MIC_LEN;\n+\telse if (csid == NAN_CS_SK_GCM_256)\n+\t\tmic_len = NAN_KEY_MIC_24_LEN;\n+\telse\n+\t\treturn -1;\n+\n+\tos_memcpy(mic, pos, mic_len);\n+\tos_memset(pos, 0, mic_len);\n+\n+\tret = nan_crypto_key_mic(buf, len, kck, kck_len, csid, pos);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tif (os_memcmp_const(mic, pos, mic_len) != 0) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: MIC verification failed\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+\n+static int nan_sec_rx_m2(struct nan_data *nan, struct nan_peer *peer,\n+\t\t\t const struct nan_msg *msg,\n+\t\t\t const struct wpa_eapol_key *key)\n+{\n+\tstruct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;\n+\tstruct nan_ndp *ndp = peer->ndp_setup.ndp;\n+\tstruct nan_ptk tptk;\n+\tu8 *pos;\n+\tint ret;\n+\n+\tif (peer->ndp_setup.state != NAN_NDP_STATE_RES_RECV) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: Not expecting m2\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (ndp_sec->i_csid != ndp_sec->r_csid) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: i_csid != r_csid (%u, %u)\",\n+\t\t\t   ndp_sec->i_csid, ndp_sec->r_csid);\n+\t\treturn -1;\n+\t}\n+\n+\t/* Save responder's nonce */\n+\tos_memcpy(ndp_sec->r_nonce, key->key_nonce, WPA_NONCE_LEN);\n+\n+\t/* Note: replay counter should have been verified by caller */\n+\n+\t/* PTK should be derived using NDI addresses */\n+\tret = nan_crypto_pmk_to_ptk(ndp_sec->pmk,\n+\t\t\t\t    ndp->init_ndi, ndp->resp_ndi,\n+\t\t\t\t    ndp_sec->i_nonce, ndp_sec->r_nonce,\n+\t\t\t\t    &tptk, ndp_sec->i_csid);\n+\tif (ret) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: m2 failed to derive PTK\");\n+\t\treturn ret;\n+\t}\n+\n+\t/*\n+\t * Due to the different MIC size, need to handle the fields starting\n+\t * with the mic differently\n+\t */\n+\tpos = (u8 *)(key + 1);\n+\tif (ndp_sec->i_csid == NAN_CS_SK_CCM_128)\n+\t\tpos += NAN_KEY_MIC_LEN;\n+\telse\n+\t\tpos += NAN_KEY_MIC_24_LEN;\n+\n+\tif (WPA_GET_BE16(pos))\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: TODO: m2 key data\");\n+\n+\t/* Verify MIC */\n+\tret = nan_sec_key_mic_ver(nan, (u8 *)&msg->mgmt->u,\n+\t\t\t\t  msg->len - 24, key,\n+\t\t\t\t  tptk.kck, tptk.kck_len,\n+\t\t\t\t  ndp_sec->i_csid);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* MIC is verified; save PTK */\n+\tos_memcpy(&ndp_sec->ptk, &tptk, sizeof(tptk));\n+\tforced_memzero(&tptk, sizeof(tptk));\n+\n+\t/* Increment the replay counter here to prevent replays */\n+\tWPA_PUT_BE64(ndp_sec->replaycnt,\n+\t\t     (WPA_GET_BE64(ndp_sec->replaycnt) + 1));\n+\treturn 0;\n+}\n+\n+\n+static int nan_sec_rx_m3(struct nan_data *nan, struct nan_peer *peer,\n+\t\t\t const struct nan_msg *msg,\n+\t\t\t const struct wpa_eapol_key *key)\n+{\n+\tstruct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;\n+\tu8 mic[NAN_KEY_MIC_24_LEN];\n+\tu8 *buf;\n+\tu8 mic_len;\n+\tu8 *pos;\n+\tint ret;\n+\n+\tif (peer->ndp_setup.state != NAN_NDP_STATE_CON_RECV) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: Not expecting m3\");\n+\t\treturn -1;\n+\t}\n+\n+\t/* Note: replay counter should have been verified by caller */\n+\n+\t/* Verify the i_nonce did not change */\n+\tif (os_memcmp(key->key_nonce, ndp_sec->i_nonce, WPA_NONCE_LEN) != 0) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: m3 key nonce mismatch\");\n+\t\treturn -1;\n+\t}\n+\n+\t/*\n+\t * In case of m3, the MIC is calculated over the frame body\n+\t * concatenated with the authentication token\n+\t */\n+\tbuf = os_malloc(msg->len - 24 + NAN_AUTH_TOKEN_LEN);\n+\tif (!buf)\n+\t\treturn -ENOBUFS;\n+\n+\t/*\n+\t * Due to the different MIC size, need to handle the fields starting\n+\t * with the mic differently\n+\t */\n+\tpos = (u8 *)(key + 1);\n+\tif (ndp_sec->i_csid == NAN_CS_SK_CCM_128)\n+\t\tmic_len = NAN_KEY_MIC_LEN;\n+\telse\n+\t\tmic_len = NAN_KEY_MIC_24_LEN;\n+\n+\tif (WPA_GET_BE16(pos + mic_len))\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: TODO: m3 key data\");\n+\n+\t/* Copy MIC and os_memset it */\n+\tos_memcpy(mic, pos, mic_len);\n+\tos_memset(pos, 0, mic_len);\n+\tos_memcpy(buf, ndp_sec->auth_token, NAN_AUTH_TOKEN_LEN);\n+\tos_memcpy(buf + NAN_AUTH_TOKEN_LEN, (u8 *)&msg->mgmt->u, msg->len - 24);\n+\n+\tret = nan_crypto_key_mic(buf, msg->len - 24 + NAN_AUTH_TOKEN_LEN,\n+\t\t\t\t ndp_sec->ptk.kck,\n+\t\t\t\t ndp_sec->ptk.kck_len,\n+\t\t\t\t ndp_sec->i_csid,\n+\t\t\t\t pos);\n+\tos_free(buf);\n+\n+\tif (ret) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: m3 MIC calculation failed\");\n+\t\treturn ret;\n+\t}\n+\n+\tif (os_memcmp_const(mic, pos, mic_len) != 0) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: m3 MIC verification failed\");\n+\t\treturn -1;\n+\t}\n+\n+\tforced_memzero(mic, sizeof(mic));\n+\n+\t/* Save replay counter */\n+\tos_memcpy(ndp_sec->replaycnt, key->replay_counter,\n+\t\t  sizeof(key->replay_counter));\n+\treturn 0;\n+}\n+\n+\n+static int nan_sec_rx_m4(struct nan_data *nan, struct nan_peer *peer,\n+\t\t\t const struct nan_msg *msg,\n+\t\t\t const struct wpa_eapol_key *key)\n+{\n+\tstruct nan_ndp_sec *ndp_sec = &peer->ndp_setup.sec;\n+\tu8 *pos = (u8 *)(key + 1);\n+\tint ret;\n+\n+\tif (peer->ndp_setup.state != NAN_NDP_STATE_DONE) {\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: Not expecting m4\");\n+\t\treturn -1;\n+\t}\n+\n+\t/* Note: replay counter should have been verified by caller */\n+\n+\t/*\n+\t * Due to the different MIC size, need to handle the fields starting\n+\t * with the mic differently\n+\t */\n+\tif (ndp_sec->i_csid == NAN_CS_SK_CCM_128)\n+\t\tpos += NAN_KEY_MIC_LEN;\n+\telse\n+\t\tpos += NAN_KEY_MIC_24_LEN;\n+\n+\tif (WPA_GET_BE16(pos))\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: TODO: m4 key data\");\n+\n+\t/* Verify MIC */\n+\tret = nan_sec_key_mic_ver(nan, (u8 *)&msg->mgmt->u,\n+\t\t\t\t  msg->len - 24, key,\n+\t\t\t\t  ndp_sec->ptk.kck,\n+\t\t\t\t  ndp_sec->ptk.kck_len,\n+\t\t\t\t  ndp_sec->i_csid);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\t/* Increment the replay counter here to prevent replays */\n+\tWPA_PUT_BE64(ndp_sec->replaycnt,\n+\t\t     (WPA_GET_BE64(ndp_sec->replaycnt) + 1));\n+\n+\t/* Security negotiation done */\n+\treturn 0;\n+}\n+\n+\n+/*\n+ * nan_sec_rx - Handle security context for Rx frames\n+ *\n+ * @nan: NAN module context from nan_init()\n+ * @peer: Peer from which the original message was received\n+ * @msg: Parsed nan action frame\n+ * Returns: 0 on success, negative on failure\n+ */\n+int nan_sec_rx(struct nan_data *nan, struct nan_peer *peer,\n+\t       struct nan_msg *msg)\n+{\n+\tstruct nan_ndp_setup *ndp_setup = &peer->ndp_setup;\n+\tstruct nan_ndp_sec *ndp_sec = &ndp_setup->sec;\n+\tstruct wpa_eapol_key *key;\n+\tstruct nan_shared_key *shared_key_desc;\n+\tu16 info, desc, shared_key_desc_len;\n+\tsize_t total_len;\n+\tu8 instance_id, cipher, capab, gtk_csid;\n+\tu8 *pos;\n+\tint ret;\n+\n+\twpa_printf(MSG_DEBUG, \"NAN: SEC: NDP security Rx\");\n+\tnan_sec_dump(nan, peer);\n+\n+\tif (!ndp_sec->present) {\n+\t\tif (!ndp_sec->valid)\n+\t\t\treturn 0;\n+\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: NDP with security but present=0\");\n+\t\treturn -1;\n+\t}\n+\n+\tshared_key_desc = (struct nan_shared_key *)msg->attrs.shared_key_desc;\n+\tshared_key_desc_len = msg->attrs.shared_key_desc_len;\n+\n+\t/* Shared key descriptor mandatory in all messages */\n+\tif (!shared_key_desc || !shared_key_desc_len) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: No shared key descriptor attribute\");\n+\t\treturn -1;\n+\t}\n+\n+\t/*\n+\t * As the shared key type depends on the cipher suite negotiated, need\n+\t * to get the cipher suite to validate the proper length of the\n+\t * descriptor.\n+\t */\n+\tif (msg->oui_subtype == NAN_SUBTYPE_DATA_PATH_REQUEST ||\n+\t    msg->oui_subtype == NAN_SUBTYPE_DATA_PATH_RESPONSE) {\n+\t\tif (nan_sec_parse_csia(msg->attrs.cipher_suite_info,\n+\t\t\t\t       msg->attrs.cipher_suite_info_len,\n+\t\t\t\t       &instance_id, &capab, &cipher,\n+\t\t\t\t       &gtk_csid)) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: SEC: Missing/bad cipher suite attribute\");\n+\t\t\treturn -1;\n+\t\t}\n+\t} else {\n+\t\tcipher = ndp_sec->i_csid;\n+\t}\n+\n+\tkey = (struct wpa_eapol_key *)shared_key_desc->key;\n+\tpos = (u8 *)(key + 1);\n+\n+\ttotal_len = sizeof(*key) + 2;\n+\n+\tif (cipher == NAN_CS_SK_CCM_128) {\n+\t\tif (shared_key_desc_len <\n+\t\t    (sizeof(struct nan_shared_key) + sizeof(*key) +\n+\t\t     NAN_KEY_MIC_LEN + 2)) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: SEC: Shared key descriptor too small\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\ttotal_len += NAN_KEY_MIC_LEN +\n+\t\t\tWPA_GET_BE16(pos + NAN_KEY_MIC_LEN);\n+\n+\t\tif (total_len >\n+\t\t    (shared_key_desc_len - sizeof(struct nan_shared_key))) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: SEC: Invalid shared key: payload len\");\n+\t\t\treturn -1;\n+\t\t}\n+\t} else {\n+\t\tif (shared_key_desc_len <\n+\t\t    (sizeof(struct nan_shared_key) + sizeof(*key) +\n+\t\t     NAN_KEY_MIC_24_LEN + 2)) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: SEC: Shared key (24) descriptor too small\");\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\ttotal_len += NAN_KEY_MIC_24_LEN +\n+\t\t\tWPA_GET_BE16(pos + NAN_KEY_MIC_24_LEN);\n+\n+\t\tif (total_len >\n+\t\t    (shared_key_desc_len - sizeof(struct nan_shared_key))) {\n+\t\t\twpa_printf(MSG_DEBUG,\n+\t\t\t\t   \"NAN: SEC: Invalid shared key (24): payload len\");\n+\t\t\treturn -1;\n+\t\t}\n+\t}\n+\n+\t/*\n+\t * Note: only the fields before the mic are accessed in the function, so\n+\t * it is safe to continue with the key pointer.\n+\t */\n+\n+\t/* Note: according to the NAN specification the following fields should\n+\t * be ignored:\n+\t * key->len: as the key length is derived from the cipher suite.\n+\t * key->iv: not needed for AES Key WRAP\n+\t * key->rsc: to avoid implicit assumption of a single GTK.\n+\t */\n+\tif (key->type != NAN_KEY_DESC) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: Invalid shared key: key descriptor=0x%x\",\n+\t\t\t   key->type);\n+\t\treturn -1;\n+\t}\n+\n+\tinfo = WPA_GET_BE16(key->key_info);\n+\n+\t/* Discard EAPOL-Key frames with an unknown descriptor version */\n+\tdesc = info & WPA_KEY_INFO_TYPE_MASK;\n+\tif (desc != WPA_KEY_INFO_TYPE_AKM_DEFINED) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: Invalid shared key: invalid key version=0x%x\",\n+\t\t\t   desc);\n+\t\treturn -1;\n+\t}\n+\n+\tif (ndp_sec->replaycnt_ok &&\n+\t    WPA_GET_BE64(key->replay_counter) <\n+\t    WPA_GET_BE64(ndp_sec->replaycnt)) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: Replay counter did not increase\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (info & WPA_KEY_INFO_REQUEST) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: Invalid shared key: key request not supported\");\n+\t\treturn -1;\n+\t} else if (!(info & WPA_KEY_INFO_KEY_TYPE)) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: Invalid shared key: group handshake not supported\");\n+\t\treturn -1;\n+\t}\n+\n+\tswitch (msg->oui_subtype) {\n+\tcase NAN_SUBTYPE_DATA_PATH_REQUEST:\n+\t\tif (!(info & WPA_KEY_INFO_ACK))\n+\t\t\treturn -1;\n+\n+\t\tndp_sec->i_capab = capab;\n+\t\tndp_sec->i_csid = cipher;\n+\t\tndp_sec->i_instance_id = instance_id;\n+\t\tret = nan_sec_rx_m1(nan, peer, msg, key);\n+\t\tbreak;\n+\tcase NAN_SUBTYPE_DATA_PATH_RESPONSE:\n+\t\tif (!(info & WPA_KEY_INFO_MIC))\n+\t\t\treturn -1;\n+\n+\t\tndp_sec->r_capab = capab;\n+\t\tndp_sec->r_csid = cipher;\n+\t\tndp_sec->r_instance_id = instance_id;\n+\t\tret = nan_sec_rx_m2(nan, peer, msg, key);\n+\t\tbreak;\n+\tcase NAN_SUBTYPE_DATA_PATH_CONFIRM:\n+\t\tif (!(info & WPA_KEY_INFO_MIC) ||\n+\t\t    !(info & WPA_KEY_INFO_ACK) ||\n+\t\t    !(info & WPA_KEY_INFO_SECURE))\n+\t\t\treturn -1;\n+\t\tret = nan_sec_rx_m3(nan, peer, msg, key);\n+\t\tbreak;\n+\tcase NAN_SUBTYPE_DATA_PATH_KEY_INSTALL:\n+\t\tif (!(info & WPA_KEY_INFO_MIC) ||\n+\t\t    !(info & WPA_KEY_INFO_SECURE))\n+\t\t\treturn -1;\n+\t\tret = nan_sec_rx_m4(nan, peer, msg, key);\n+\t\tbreak;\n+\tdefault:\n+\t\twpa_printf(MSG_DEBUG, \"NAN: SEC: Invalid frame OUI subtype\");\n+\t\treturn -1;\n+\t}\n+\n+\tif (ret)\n+\t\treturn ret;\n+\n+\tinstance_id = shared_key_desc->publish_id;\n+\tif (ndp_sec->i_instance_id && instance_id &&\n+\t    ndp_sec->i_instance_id != instance_id) {\n+\t\twpa_printf(MSG_DEBUG,\n+\t\t\t   \"NAN: SEC: Mismatch instance ID in shared key descriptor\");\n+\t\treturn -1;\n+\t}\n+\n+\treturn 0;\n+}\ndiff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile\nindex 6d2a9a76ac..283dd01d65 100644\n--- a/wpa_supplicant/Makefile\n+++ b/wpa_supplicant/Makefile\n@@ -336,6 +336,7 @@ 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+OBJS += ../src/nan/nan_sec.o\n endif\n \n ifdef CONFIG_PR\n",
    "prefixes": [
        "38/58"
    ]
}