From patchwork Tue Aug 28 22:51:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10579259 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 302D3920 for ; Tue, 28 Aug 2018 22:51:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1E8492AB98 for ; Tue, 28 Aug 2018 22:51:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 121A32ABC0; Tue, 28 Aug 2018 22:51:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B02122AB98 for ; Tue, 28 Aug 2018 22:51:52 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id A9F962110397A; Tue, 28 Aug 2018 15:51:52 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.20; helo=mga02.intel.com; envelope-from=dave.jiang@intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 86BC121102DAE for ; Tue, 28 Aug 2018 15:51:51 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Aug 2018 15:51:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,300,1531810800"; d="scan'208";a="69861538" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by orsmga006.jf.intel.com with ESMTP; 28 Aug 2018 15:51:51 -0700 Subject: [PATCH v3 1/6] ndctl: add support for display security state From: Dave Jiang To: vishal.l.verma@intel.com Date: Tue, 28 Aug 2018 15:51:50 -0700 Message-ID: <153549671087.5723.14981430820112198685.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> References: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dhowells@redhat.com, alison.schofield@intel.com, linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Adding libndctl API call for retrieving security state for a DIMM and also adding support to ndctl list for displaying security state. Signed-off-by: Dave Jiang --- Documentation/ndctl/ndctl-list.txt | 8 ++++++++ ndctl/lib/dimm.c | 16 ++++++++++++++++ ndctl/lib/libndctl.sym | 1 + ndctl/libndctl.h | 1 + util/json.c | 8 ++++++++ 5 files changed, 34 insertions(+) diff --git a/Documentation/ndctl/ndctl-list.txt b/Documentation/ndctl/ndctl-list.txt index e24c8f40..a4a712a0 100644 --- a/Documentation/ndctl/ndctl-list.txt +++ b/Documentation/ndctl/ndctl-list.txt @@ -98,6 +98,14 @@ include::xable-region-options.txt[] -D:: --dimms:: Include dimm info in the listing +[verse] +{ + "dev":"nmem0", + "id":"cdab-0a-07e0-ffffffff", + "handle":0, + "phys_id":0, + "security_state:":"disabled" +} -H:: --health:: diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c index b3e032e0..8ed58559 100644 --- a/ndctl/lib/dimm.c +++ b/ndctl/lib/dimm.c @@ -579,3 +579,19 @@ NDCTL_EXPORT unsigned long ndctl_dimm_get_available_labels( return strtoul(buf, NULL, 0); } + +NDCTL_EXPORT int ndctl_dimm_get_security_state(struct ndctl_dimm *dimm, + char *state) +{ + struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm); + char *path = dimm->dimm_buf; + int len = dimm->buf_len; + + if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len) { + err(ctx, "%s: buffer too small!\n", + ndctl_dimm_get_devname(dimm)); + return -ERANGE; + } + + return sysfs_read_attr(ctx, path, state); +} diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym index a6849ee1..062b41d3 100644 --- a/ndctl/lib/libndctl.sym +++ b/ndctl/lib/libndctl.sym @@ -377,4 +377,5 @@ global: ndctl_dimm_is_flag_supported; ndctl_region_get_max_available_extent; ndctl_cmd_smart_inject_ctrl_temperature; + ndctl_dimm_get_security_state; } LIBNDCTL_16; diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h index 83d6c6ca..f23bfdee 100644 --- a/ndctl/libndctl.h +++ b/ndctl/libndctl.h @@ -673,6 +673,7 @@ unsigned long long ndctl_cmd_fw_fquery_get_fw_rev(struct ndctl_cmd *cmd); enum ND_FW_STATUS ndctl_cmd_fw_xlat_firmware_status(struct ndctl_cmd *cmd); struct ndctl_cmd *ndctl_dimm_cmd_new_ack_shutdown_count(struct ndctl_dimm *dimm); int ndctl_dimm_fw_update_supported(struct ndctl_dimm *dimm); +int ndctl_dimm_get_security_state(struct ndctl_dimm *dimm, char *state); #ifdef __cplusplus } /* extern "C" */ diff --git a/util/json.c b/util/json.c index 2d158592..d8514ab2 100644 --- a/util/json.c +++ b/util/json.c @@ -164,6 +164,7 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm *dimm, unsigned int handle = ndctl_dimm_get_handle(dimm); unsigned short phys_id = ndctl_dimm_get_phys_id(dimm); struct json_object *jobj; + char security_state[32]; if (!jdimm) return NULL; @@ -243,6 +244,13 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm *dimm, json_object_object_add(jdimm, "flag_smart_event", jobj); } + if (ndctl_dimm_get_security_state(dimm, security_state) == 0) { + jobj = json_object_new_string(security_state); + if (!jobj) + goto err; + json_object_object_add(jdimm, "security_state:", jobj); + } + return jdimm; err: json_object_put(jdimm); From patchwork Tue Aug 28 22:51:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10579261 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 19721920 for ; Tue, 28 Aug 2018 22:52:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0619B2AB98 for ; Tue, 28 Aug 2018 22:52:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EE77D2ABC0; Tue, 28 Aug 2018 22:52:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C4A1B2AB98 for ; Tue, 28 Aug 2018 22:51:58 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id BEBB721103982; Tue, 28 Aug 2018 15:51:58 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.126; helo=mga18.intel.com; envelope-from=dave.jiang@intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 235A121102DAE for ; Tue, 28 Aug 2018 15:51:57 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Aug 2018 15:51:56 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,300,1531810800"; d="scan'208";a="69861557" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by orsmga006.jf.intel.com with ESMTP; 28 Aug 2018 15:51:56 -0700 Subject: [PATCH v3 2/6] ndctl: add update to security support From: Dave Jiang To: vishal.l.verma@intel.com Date: Tue, 28 Aug 2018 15:51:56 -0700 Message-ID: <153549671642.5723.4125145745863193059.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> References: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dhowells@redhat.com, alison.schofield@intel.com, linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Add API call for triggering sysfs knob to update the security for a DIMM in libndctl. Also add the ndctl "update-security" to trigger that as well. ndctl does not actually handle the passphrase file. It only initiates the update and expects all the necessary mechanisms are already in place. Signed-off-by: Dave Jiang --- Documentation/ndctl/Makefile.am | 3 - Documentation/ndctl/ndctl-update-security.txt | 56 +++++++++++ builtin.h | 1 configure.ac | 1 ndctl.spec.in | 1 ndctl/dimm.c | 92 ++++++++++++++++-- ndctl/lib/Makefile.am | 4 + ndctl/lib/dimm.c | 24 +++++ ndctl/lib/keys.c | 130 +++++++++++++++++++++++++ ndctl/lib/libndctl.sym | 7 + ndctl/libndctl.h | 7 + ndctl/ndctl.c | 1 12 files changed, 314 insertions(+), 13 deletions(-) create mode 100644 Documentation/ndctl/ndctl-update-security.txt create mode 100644 ndctl/lib/keys.c diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am index a30b139b..2c064c3a 100644 --- a/Documentation/ndctl/Makefile.am +++ b/Documentation/ndctl/Makefile.am @@ -47,7 +47,8 @@ man1_MANS = \ ndctl-inject-smart.1 \ ndctl-update-firmware.1 \ ndctl-list.1 \ - ndctl-monitor.1 + ndctl-monitor.1 \ + ndctl-update-security.1 CLEANFILES = $(man1_MANS) diff --git a/Documentation/ndctl/ndctl-update-security.txt b/Documentation/ndctl/ndctl-update-security.txt new file mode 100644 index 00000000..cfc99656 --- /dev/null +++ b/Documentation/ndctl/ndctl-update-security.txt @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 + +ndctl-update-security(1) +======================== + +NAME +---- +ndctl-update-security - enabling or update the security passphrase for a +NVDIMM + +SYNOPSIS +-------- +[verse] +'ndctl update-security' [] + +DESCRIPTION +----------- +Provide a generic interface for enabling or updating security passphrase for +NVDIMM. The use of this depends on support from the underlying libndctl, +kernel, as well as the platform itself. + +For the reference passphrase setup, /etc/nvdimm.passwd is read for passphrase +retrieval: + +The nvdimm.passwd is formatted as: +: +cdab-0a-07e0-feffffff:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +To update a DIMM that has passphrase already enabled, the format is done as: +: + +cdab-0a-07e0-feffffff:bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +The accepted key will replace the old payload with the new payload in the +cached key that resides in the kernel key ring. + +OPTIONS +------- +:: +include::xable-dimm-options.txt[] + +-i:: +--insecure:: + Using the default reference support to parse the nvdimm passphrase + file, inject the key, and initiate update operation. This is labeled + as insecure as it just provides a reference to how to inject keys + for the nvdimm. The passphrase is in clear text and is not considered + as secure as it can be. + +-e:: +--exec:: + The external binary module that would inject the passphrase and + initiate the update operation. Use this or -i, not both. + +include::../copyright.txt[] diff --git a/builtin.h b/builtin.h index 675a6ce7..37404c79 100644 --- a/builtin.h +++ b/builtin.h @@ -48,4 +48,5 @@ int cmd_bat(int argc, const char **argv, void *ctx); #endif int cmd_update_firmware(int argc, const char **argv, void *ctx); int cmd_inject_smart(int argc, const char **argv, void *ctx); +int cmd_key_update(int argc, const char **argv, void *ctx); #endif /* _NDCTL_BUILTIN_H_ */ diff --git a/configure.ac b/configure.ac index 7bfe5a74..4fc6cdd9 100644 --- a/configure.ac +++ b/configure.ac @@ -114,6 +114,7 @@ PKG_CHECK_MODULES([KMOD], [libkmod]) PKG_CHECK_MODULES([UDEV], [libudev]) PKG_CHECK_MODULES([UUID], [uuid]) PKG_CHECK_MODULES([JSON], [json-c]) +PKG_CHECK_MODULES([KEYUTILS], [keyutils]) AC_ARG_WITH([bash-completion-dir], AS_HELP_STRING([--with-bash-completion-dir[=PATH]], diff --git a/ndctl.spec.in b/ndctl.spec.in index b782aeae..c71bd581 100644 --- a/ndctl.spec.in +++ b/ndctl.spec.in @@ -21,6 +21,7 @@ BuildRequires: pkgconfig(uuid) BuildRequires: pkgconfig(json-c) BuildRequires: pkgconfig(bash-completion) BuildRequires: systemd +BuildRequires: pkgconfig(keyutils) %description Utility library for managing the "libnvdimm" subsystem. The "libnvdimm" diff --git a/ndctl/dimm.c b/ndctl/dimm.c index a4203f35..48d366c6 100644 --- a/ndctl/dimm.c +++ b/ndctl/dimm.c @@ -40,6 +40,20 @@ struct action_context { struct update_context update; }; +static struct parameters { + const char *bus; + const char *outfile; + const char *infile; + const char *labelversion; + const char *key_exec; + bool force; + bool json; + bool verbose; + bool key_insecure; +} param = { + .labelversion = "1.1", +}; + static int action_disable(struct ndctl_dimm *dimm, struct action_context *actx) { if (ndctl_dimm_is_active(dimm)) { @@ -824,17 +838,46 @@ static int action_update(struct ndctl_dimm *dimm, struct action_context *actx) return rc; } -static struct parameters { - const char *bus; - const char *outfile; - const char *infile; - const char *labelversion; - bool force; - bool json; - bool verbose; -} param = { - .labelversion = "1.1", -}; +static int action_key(struct ndctl_dimm *dimm, + struct action_context *actx) +{ + int rc; + char payload[64]; + int psize; + key_serial_t current_key, new_key; + + if (ndctl_dimm_is_enabled(dimm)) { + fprintf(stderr, "%s: DIMM is not disabled\n", + ndctl_dimm_get_devname(dimm)); + return -EACCES; + } + + if (param.key_exec) + return execl(param.key_exec, ndctl_dimm_get_devname(dimm), + ndctl_dimm_get_unique_id(dimm), (char *)NULL); + + if (!param.key_insecure) + return -EINVAL; + + rc = ndctl_dimm_get_key_payload(dimm, payload, &psize); + if (rc < 0) + return rc; + + rc = ndctl_dimm_get_current_key(dimm, ¤t_key); + if (rc < 0) + return rc; + + rc = ndctl_dimm_add_key(dimm, payload, psize, &new_key); + if (rc < 0) + return rc; + + /* now do actual writing to update */ + rc = ndctl_dimm_set_change_key(dimm, current_key, new_key); + if (rc < 0) + return rc; + + return rc; +} static int __action_init(struct ndctl_dimm *dimm, enum ndctl_namespace_version version, int chk_only) @@ -925,6 +968,12 @@ OPT_BOOLEAN('f', "force", ¶m.force, \ OPT_STRING('V', "label-version", ¶m.labelversion, "version-number", \ "namespace label specification version (default: 1.1)") +#define KEY_OPTIONS() \ +OPT_BOOLEAN('i', "insecure", ¶m.key_insecure, \ + "insecure reference passphrase update method"), \ +OPT_STRING('e', "exec", ¶m.key_exec, "external-exec", \ + "external exec module for passphrase update") + static const struct option read_options[] = { BASE_OPTIONS(), READ_OPTIONS(), @@ -954,6 +1003,12 @@ static const struct option init_options[] = { OPT_END(), }; +static const struct option key_options[] = { + BASE_OPTIONS(), + KEY_OPTIONS(), + OPT_END(), +}; + static int dimm_action(int argc, const char **argv, void *ctx, int (*action)(struct ndctl_dimm *dimm, struct action_context *actx), const struct option *options, const char *usage) @@ -1024,6 +1079,11 @@ static int dimm_action(int argc, const char **argv, void *ctx, } } + if (action == action_key && param.key_insecure && param.key_exec) { + usage_with_options(u, options); + return -EINVAL; + } + if (param.verbose) ndctl_set_log_priority(ctx, LOG_DEBUG); @@ -1181,3 +1241,13 @@ int cmd_update_firmware(int argc, const char **argv, void *ctx) count > 1 ? "s" : ""); return count >= 0 ? 0 : EXIT_FAILURE; } + +int cmd_key_update(int argc, const char **argv, void *ctx) +{ + int count = dimm_action(argc, argv, ctx, action_key, key_options, + "ndctl update-security [..] []"); + + fprintf(stderr, "security updated for %d nmem%s.\n", count >= 0 ? count : 0, + count > 1 ? "s" : ""); + return count >= 0 ? 0 : EXIT_FAILURE; +} diff --git a/ndctl/lib/Makefile.am b/ndctl/lib/Makefile.am index 77970399..245b78a9 100644 --- a/ndctl/lib/Makefile.am +++ b/ndctl/lib/Makefile.am @@ -22,13 +22,15 @@ libndctl_la_SOURCES =\ msft.c \ ars.c \ firmware.c \ + keys.c \ libndctl.c libndctl_la_LIBADD =\ ../../daxctl/lib/libdaxctl.la \ $(UDEV_LIBS) \ $(UUID_LIBS) \ - $(KMOD_LIBS) + $(KMOD_LIBS) \ + $(KEYUTILS_LIBS) EXTRA_DIST += libndctl.sym diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c index 8ed58559..57bbf01a 100644 --- a/ndctl/lib/dimm.c +++ b/ndctl/lib/dimm.c @@ -595,3 +595,27 @@ NDCTL_EXPORT int ndctl_dimm_get_security_state(struct ndctl_dimm *dimm, return sysfs_read_attr(ctx, path, state); } + +static int ndctl_dimm_write_security(struct ndctl_dimm *dimm, const char *cmd) +{ + struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm); + char *path = dimm->dimm_buf; + int len = dimm->buf_len; + + if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len) { + err(ctx, "%s: buffer too small!\n", + ndctl_dimm_get_devname(dimm)); + return -ERANGE; + } + + return sysfs_write_attr(ctx, path, cmd); +} + +NDCTL_EXPORT int ndctl_dimm_set_change_key(struct ndctl_dimm *dimm, + key_serial_t ckey, key_serial_t nkey) +{ + char buf[SYSFS_ATTR_SIZE]; + + sprintf(buf, "update:%d:%d\n", ckey, nkey); + return ndctl_dimm_write_security(dimm, buf); +} diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c new file mode 100644 index 00000000..3fd35442 --- /dev/null +++ b/ndctl/lib/keys.c @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2018 Intel Corporation. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "private.h" + +#define PASSPHRASE_SIZE 32 +#define PASS_PATH "/etc/nvdimm.passwd" +#define NVDIMM_KEY_DESC_LEN 22 +#define NVDIMM_KEY_DESC_PREFIX 7 + +NDCTL_EXPORT int ndctl_dimm_get_key_payload(struct ndctl_dimm *dimm, + char *pass, int *psize) +{ + struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm); + ssize_t rc = 0; + static FILE *fp; + const char *dimm_id; + size_t size; + char *line = NULL; + char *tmp, *id_tok, *secret; + int found = 0; + + dimm_id = ndctl_dimm_get_unique_id(dimm); + if (!dimm_id) + return -EINVAL; + + fp = fopen(PASS_PATH, "r+"); + if (!fp) { + err(ctx, "fopen: %s\n", strerror(errno)); + return -errno; + } + + while ((rc = getline(&line, &size, fp)) != -1) { + id_tok = strtok_r(line, ":", &tmp); + if (!id_tok) + break; + if (strcmp(id_tok, dimm_id) == 0) { + secret = tmp; + found = 1; + rc = 0; + break; + } + } + + if (rc == 0 && found && secret) { + memset(pass, 0, PASSPHRASE_SIZE * 2 + 1); + size = MIN(strlen(secret), (PASSPHRASE_SIZE * 2 + 1)); + memcpy(pass, secret, size); + *psize = size-1; + } else + rc = -ENXIO; + + free(line); + fclose(fp); + return rc; +} + +NDCTL_EXPORT int ndctl_dimm_add_key(struct ndctl_dimm *dimm, + const char *passphrase, int pass_size, key_serial_t *key) +{ + int rc; + char desc[NVDIMM_KEY_DESC_LEN + NVDIMM_KEY_DESC_PREFIX]; + struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm); + + rc = sprintf(desc, "nvdimm:%s", ndctl_dimm_get_unique_id(dimm)); + if (rc < 0) { + err(ctx, "sprintf: %s\n", strerror(errno)); + return -errno; + } + + *key = add_key("logon", desc, passphrase, pass_size, + KEY_SPEC_USER_KEYRING); + if (*key == -1) { + err(ctx, "add_key: %s\n", strerror(errno)); + return -errno; + } + + return 0; +} + +static int ndctl_dimm_get_keyring(struct ndctl_dimm *dimm, + key_serial_t *keyring) +{ + *keyring = find_key_by_type_and_desc("keyring", ".nvdimm", 0); + if (*keyring == -1) + return -errno; + return 0; +} + +NDCTL_EXPORT int ndctl_dimm_get_current_key(struct ndctl_dimm *dimm, + key_serial_t *key) +{ + struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm); + key_serial_t ring; + char desc[NVDIMM_KEY_DESC_LEN + NVDIMM_KEY_DESC_PREFIX]; + int rc; + + rc = sprintf(desc, "nvdimm:%s", ndctl_dimm_get_unique_id(dimm)); + if (rc < 0) { + err(ctx, "sprintf: %s\n", strerror(errno)); + return -errno; + } + + rc = ndctl_dimm_get_keyring(dimm, &ring); + if (rc < 0) + return rc; + + *key = keyctl_search(ring, "logon", desc, 0); + if (*key == -1) { + if (errno == ENOKEY) + *key = 0; + else + return -errno; + } + + return 0; +} diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym index 062b41d3..d4764450 100644 --- a/ndctl/lib/libndctl.sym +++ b/ndctl/lib/libndctl.sym @@ -379,3 +379,10 @@ global: ndctl_cmd_smart_inject_ctrl_temperature; ndctl_dimm_get_security_state; } LIBNDCTL_16; +LIBNDCTL_18 { +global: + ndctl_dimm_get_key_payload; + ndctl_dimm_add_key; + ndctl_dimm_get_current_key; + ndctl_dimm_set_change_key; +} LIBNDCTL_17; diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h index f23bfdee..f845b11b 100644 --- a/ndctl/libndctl.h +++ b/ndctl/libndctl.h @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef HAVE_LIBUUID #include @@ -674,6 +675,12 @@ enum ND_FW_STATUS ndctl_cmd_fw_xlat_firmware_status(struct ndctl_cmd *cmd); struct ndctl_cmd *ndctl_dimm_cmd_new_ack_shutdown_count(struct ndctl_dimm *dimm); int ndctl_dimm_fw_update_supported(struct ndctl_dimm *dimm); int ndctl_dimm_get_security_state(struct ndctl_dimm *dimm, char *state); +int ndctl_dimm_set_change_key(struct ndctl_dimm *dimm, key_serial_t ckey, + key_serial_t nkey); +int ndctl_dimm_get_key_payload(struct ndctl_dimm *dimm, char *pass, int *psize); +int ndctl_dimm_add_key(struct ndctl_dimm *dimm, const char *passphrase, + int pass_size, key_serial_t *key); +int ndctl_dimm_get_current_key(struct ndctl_dimm *dimm, key_serial_t *key); #ifdef __cplusplus } /* extern "C" */ diff --git a/ndctl/ndctl.c b/ndctl/ndctl.c index 73dabfac..c7096dfd 100644 --- a/ndctl/ndctl.c +++ b/ndctl/ndctl.c @@ -88,6 +88,7 @@ static struct cmd_struct commands[] = { { "inject-smart", cmd_inject_smart }, { "wait-scrub", cmd_wait_scrub }, { "start-scrub", cmd_start_scrub }, + { "update-security", cmd_key_update }, { "list", cmd_list }, { "monitor", cmd_monitor}, { "help", cmd_help }, From patchwork Tue Aug 28 22:52:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10579263 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6E27A5A4 for ; Tue, 28 Aug 2018 22:52:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5C1072AB98 for ; Tue, 28 Aug 2018 22:52:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4EB7E2ABC0; Tue, 28 Aug 2018 22:52:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D87882AB98 for ; Tue, 28 Aug 2018 22:52:03 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id D33192110398C; Tue, 28 Aug 2018 15:52:03 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.126; helo=mga18.intel.com; envelope-from=dave.jiang@intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id A9F8221102DAE for ; Tue, 28 Aug 2018 15:52:02 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Aug 2018 15:52:02 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,300,1531810800"; d="scan'208";a="85295803" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by fmsmga001.fm.intel.com with ESMTP; 28 Aug 2018 15:52:02 -0700 Subject: [PATCH v3 3/6] ndctl: add disable security support From: Dave Jiang To: vishal.l.verma@intel.com Date: Tue, 28 Aug 2018 15:52:02 -0700 Message-ID: <153549672202.5723.1082050945219792209.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> References: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dhowells@redhat.com, alison.schofield@intel.com, linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Add support for disable security to libndctl and also command line option of "disable-security" for ndctl. This provides a way to disable security on the nvdimm. ndctl does not handle the actual processing of the passphrase. It only starts the request. Signed-off-by: Dave Jiang --- Documentation/ndctl/Makefile.am | 3 ++- Documentation/ndctl/ndctl-disable-security.txt | 21 +++++++++++++++++++++ builtin.h | 1 + ndctl/dimm.c | 22 ++++++++++++++++++++++ ndctl/lib/dimm.c | 5 +++++ ndctl/lib/libndctl.sym | 1 + ndctl/libndctl.h | 1 + ndctl/ndctl.c | 1 + 8 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 Documentation/ndctl/ndctl-disable-security.txt diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am index 2c064c3a..faeb0d9b 100644 --- a/Documentation/ndctl/Makefile.am +++ b/Documentation/ndctl/Makefile.am @@ -48,7 +48,8 @@ man1_MANS = \ ndctl-update-firmware.1 \ ndctl-list.1 \ ndctl-monitor.1 \ - ndctl-update-security.1 + ndctl-update-security.1 \ + ndctl-disable-security.1 CLEANFILES = $(man1_MANS) diff --git a/Documentation/ndctl/ndctl-disable-security.txt b/Documentation/ndctl/ndctl-disable-security.txt new file mode 100644 index 00000000..651f8d03 --- /dev/null +++ b/Documentation/ndctl/ndctl-disable-security.txt @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 + +ndctl-disable-security(1) +======================== + +NAME +---- +ndctl-disable-security - enabling or disable security for an NVDIMM + +SYNOPSIS +-------- +[verse] +'ndctl disable-security' + +DESCRIPTION +----------- +Provide a generic interface for disabling security for NVDIMM. The use of this +depends on support from the underlying libndctl, kernel, as well as the +platform itself. + +include::../copyright.txt[] diff --git a/builtin.h b/builtin.h index 37404c79..39e4e38d 100644 --- a/builtin.h +++ b/builtin.h @@ -49,4 +49,5 @@ int cmd_bat(int argc, const char **argv, void *ctx); int cmd_update_firmware(int argc, const char **argv, void *ctx); int cmd_inject_smart(int argc, const char **argv, void *ctx); int cmd_key_update(int argc, const char **argv, void *ctx); +int cmd_disable_security(int argc, const char **argv, void *ctx); #endif /* _NDCTL_BUILTIN_H_ */ diff --git a/ndctl/dimm.c b/ndctl/dimm.c index 48d366c6..96733ff6 100644 --- a/ndctl/dimm.c +++ b/ndctl/dimm.c @@ -879,6 +879,18 @@ static int action_key(struct ndctl_dimm *dimm, return rc; } +static int action_security_disable(struct ndctl_dimm *dimm, + struct action_context *actx) +{ + int rc; + + rc = ndctl_dimm_disable_security(dimm); + if (rc < 0) + error("Failed to disable security for %s\n", + ndctl_dimm_get_devname(dimm)); + return rc; +} + static int __action_init(struct ndctl_dimm *dimm, enum ndctl_namespace_version version, int chk_only) { @@ -1251,3 +1263,13 @@ int cmd_key_update(int argc, const char **argv, void *ctx) count > 1 ? "s" : ""); return count >= 0 ? 0 : EXIT_FAILURE; } + +int cmd_disable_security(int argc, const char **argv, void *ctx) +{ + int count = dimm_action(argc, argv, ctx, action_security_disable, base_options, + "ndctl disable-security [..] []"); + + fprintf(stderr, "security disabled %d nmem%s.\n", count >= 0 ? count : 0, + count > 1 ? "s" : ""); + return count >= 0 ? 0 : EXIT_FAILURE; +} diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c index 57bbf01a..53e99906 100644 --- a/ndctl/lib/dimm.c +++ b/ndctl/lib/dimm.c @@ -619,3 +619,8 @@ NDCTL_EXPORT int ndctl_dimm_set_change_key(struct ndctl_dimm *dimm, sprintf(buf, "update:%d:%d\n", ckey, nkey); return ndctl_dimm_write_security(dimm, buf); } + +NDCTL_EXPORT int ndctl_dimm_disable_security(struct ndctl_dimm *dimm) +{ + return ndctl_dimm_write_security(dimm, "disable"); +} diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym index d4764450..136f4e04 100644 --- a/ndctl/lib/libndctl.sym +++ b/ndctl/lib/libndctl.sym @@ -385,4 +385,5 @@ global: ndctl_dimm_add_key; ndctl_dimm_get_current_key; ndctl_dimm_set_change_key; + ndctl_dimm_disable_security; } LIBNDCTL_17; diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h index f845b11b..a914cfc3 100644 --- a/ndctl/libndctl.h +++ b/ndctl/libndctl.h @@ -681,6 +681,7 @@ int ndctl_dimm_get_key_payload(struct ndctl_dimm *dimm, char *pass, int *psize); int ndctl_dimm_add_key(struct ndctl_dimm *dimm, const char *passphrase, int pass_size, key_serial_t *key); int ndctl_dimm_get_current_key(struct ndctl_dimm *dimm, key_serial_t *key); +int ndctl_dimm_disable_security(struct ndctl_dimm *dimm); #ifdef __cplusplus } /* extern "C" */ diff --git a/ndctl/ndctl.c b/ndctl/ndctl.c index c7096dfd..2dab02d2 100644 --- a/ndctl/ndctl.c +++ b/ndctl/ndctl.c @@ -89,6 +89,7 @@ static struct cmd_struct commands[] = { { "wait-scrub", cmd_wait_scrub }, { "start-scrub", cmd_start_scrub }, { "update-security", cmd_key_update }, + { "disable-security", cmd_disable_security }, { "list", cmd_list }, { "monitor", cmd_monitor}, { "help", cmd_help }, From patchwork Tue Aug 28 22:52:07 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10579265 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AF1DF5A4 for ; Tue, 28 Aug 2018 22:52:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9E6FF2ABAE for ; Tue, 28 Aug 2018 22:52:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 92CBB2ABD1; Tue, 28 Aug 2018 22:52:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1D5BA2ABC0 for ; Tue, 28 Aug 2018 22:52:26 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 16E892110398E; Tue, 28 Aug 2018 15:52:26 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.43; helo=mga05.intel.com; envelope-from=dave.jiang@intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id DD33A21102DAE for ; Tue, 28 Aug 2018 15:52:24 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga105.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Aug 2018 15:52:24 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,300,1531810800"; d="scan'208";a="228429915" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by orsmga004.jf.intel.com with ESMTP; 28 Aug 2018 15:52:07 -0700 Subject: [PATCH v3 4/6] ndctl: add support for freeze security From: Dave Jiang To: vishal.l.verma@intel.com Date: Tue, 28 Aug 2018 15:52:07 -0700 Message-ID: <153549672736.5723.6409645443443463937.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> References: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dhowells@redhat.com, alison.schofield@intel.com, linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Add support for freeze security to libndctl and also command line option of "freeze-security" for ndctl. This will lock the ability to make changes to the NVDIMM security. Signed-off-by: Dave Jiang --- Documentation/ndctl/Makefile.am | 3 ++- Documentation/ndctl/ndctl-freeze-security.txt | 21 +++++++++++++++++++++ builtin.h | 1 + ndctl/dimm.c | 22 ++++++++++++++++++++++ ndctl/lib/dimm.c | 5 +++++ ndctl/lib/libndctl.sym | 1 + ndctl/libndctl.h | 1 + ndctl/ndctl.c | 1 + 8 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 Documentation/ndctl/ndctl-freeze-security.txt diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am index faeb0d9b..3a761ba0 100644 --- a/Documentation/ndctl/Makefile.am +++ b/Documentation/ndctl/Makefile.am @@ -49,7 +49,8 @@ man1_MANS = \ ndctl-list.1 \ ndctl-monitor.1 \ ndctl-update-security.1 \ - ndctl-disable-security.1 + ndctl-disable-security.1 \ + ndctl-freeze-security.1 CLEANFILES = $(man1_MANS) diff --git a/Documentation/ndctl/ndctl-freeze-security.txt b/Documentation/ndctl/ndctl-freeze-security.txt new file mode 100644 index 00000000..343bb019 --- /dev/null +++ b/Documentation/ndctl/ndctl-freeze-security.txt @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0 + +ndctl-freeze-security(1) +======================== + +NAME +---- +ndctl-freeze-security - enabling or freeze the security for an NVDIMM + +SYNOPSIS +-------- +[verse] +'ndctl freeze-security' + +DESCRIPTION +----------- +Provide a generic interface to freeze the security for NVDIMM. The use of this +depends on support from the underlying libndctl, kernel, as well as the +platform itself. + +include::../copyright.txt[] diff --git a/builtin.h b/builtin.h index 39e4e38d..7b970e10 100644 --- a/builtin.h +++ b/builtin.h @@ -50,4 +50,5 @@ int cmd_update_firmware(int argc, const char **argv, void *ctx); int cmd_inject_smart(int argc, const char **argv, void *ctx); int cmd_key_update(int argc, const char **argv, void *ctx); int cmd_disable_security(int argc, const char **argv, void *ctx); +int cmd_freeze_security(int argc, const char **argv, void *ctx); #endif /* _NDCTL_BUILTIN_H_ */ diff --git a/ndctl/dimm.c b/ndctl/dimm.c index 96733ff6..432ead74 100644 --- a/ndctl/dimm.c +++ b/ndctl/dimm.c @@ -891,6 +891,18 @@ static int action_security_disable(struct ndctl_dimm *dimm, return rc; } +static int action_security_freeze(struct ndctl_dimm *dimm, + struct action_context *actx) +{ + int rc; + + rc = ndctl_dimm_freeze_security(dimm); + if (rc < 0) + error("Failed to freeze security for %s\n", + ndctl_dimm_get_devname(dimm)); + return rc; +} + static int __action_init(struct ndctl_dimm *dimm, enum ndctl_namespace_version version, int chk_only) { @@ -1273,3 +1285,13 @@ int cmd_disable_security(int argc, const char **argv, void *ctx) count > 1 ? "s" : ""); return count >= 0 ? 0 : EXIT_FAILURE; } + +int cmd_freeze_security(int argc, const char **argv, void *ctx) +{ + int count = dimm_action(argc, argv, ctx, action_security_freeze, base_options, + "ndctl freeze-security [..] []"); + + fprintf(stderr, "security freezed %d nmem%s.\n", count >= 0 ? count : 0, + count > 1 ? "s" : ""); + return count >= 0 ? 0 : EXIT_FAILURE; +} diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c index 53e99906..b383127c 100644 --- a/ndctl/lib/dimm.c +++ b/ndctl/lib/dimm.c @@ -624,3 +624,8 @@ NDCTL_EXPORT int ndctl_dimm_disable_security(struct ndctl_dimm *dimm) { return ndctl_dimm_write_security(dimm, "disable"); } + +NDCTL_EXPORT int ndctl_dimm_freeze_security(struct ndctl_dimm *dimm) +{ + return ndctl_dimm_write_security(dimm, "freeze"); +} diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym index 136f4e04..d543088f 100644 --- a/ndctl/lib/libndctl.sym +++ b/ndctl/lib/libndctl.sym @@ -386,4 +386,5 @@ global: ndctl_dimm_get_current_key; ndctl_dimm_set_change_key; ndctl_dimm_disable_security; + ndctl_dimm_freeze_security; } LIBNDCTL_17; diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h index a914cfc3..75364212 100644 --- a/ndctl/libndctl.h +++ b/ndctl/libndctl.h @@ -682,6 +682,7 @@ int ndctl_dimm_add_key(struct ndctl_dimm *dimm, const char *passphrase, int pass_size, key_serial_t *key); int ndctl_dimm_get_current_key(struct ndctl_dimm *dimm, key_serial_t *key); int ndctl_dimm_disable_security(struct ndctl_dimm *dimm); +int ndctl_dimm_freeze_security(struct ndctl_dimm *dimm); #ifdef __cplusplus } /* extern "C" */ diff --git a/ndctl/ndctl.c b/ndctl/ndctl.c index 2dab02d2..7a242aab 100644 --- a/ndctl/ndctl.c +++ b/ndctl/ndctl.c @@ -90,6 +90,7 @@ static struct cmd_struct commands[] = { { "start-scrub", cmd_start_scrub }, { "update-security", cmd_key_update }, { "disable-security", cmd_disable_security }, + { "freeze-security", cmd_freeze_security }, { "list", cmd_list }, { "monitor", cmd_monitor}, { "help", cmd_help }, From patchwork Tue Aug 28 22:52:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10579271 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DCBE15A4 for ; Tue, 28 Aug 2018 22:52:32 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CC6232AB98 for ; Tue, 28 Aug 2018 22:52:32 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C0B2D2ABC0; Tue, 28 Aug 2018 22:52:32 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 485B32AB98 for ; Tue, 28 Aug 2018 22:52:32 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 434BE2110399C; Tue, 28 Aug 2018 15:52:32 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.24; helo=mga09.intel.com; envelope-from=dave.jiang@intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id EE31E21103987 for ; Tue, 28 Aug 2018 15:52:30 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Aug 2018 15:52:31 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,300,1531810800"; d="scan'208";a="81005996" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by fmsmga002.fm.intel.com with ESMTP; 28 Aug 2018 15:52:13 -0700 Subject: [PATCH v3 5/6] ndctl: add support for sanitize dimm From: Dave Jiang To: vishal.l.verma@intel.com Date: Tue, 28 Aug 2018 15:52:13 -0700 Message-ID: <153549673298.5723.9236311781816609734.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> References: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dhowells@redhat.com, alison.schofield@intel.com, linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Add support to secure erase to libndctl and also command line option of "sanitize" for ndctl. This will initiate the request to crypto erase a DIMM. ndctl does not actually handle the verification of the security. That is handled by the kernel and the key upcall mechanism. Signed-off-by: Dave Jiang --- Documentation/ndctl/Makefile.am | 3 +- Documentation/ndctl/ndctl-sanitize.txt | 32 +++++++++++++++++++++++ builtin.h | 1 + ndctl/dimm.c | 44 ++++++++++++++++++++++++++++++++ ndctl/lib/dimm.c | 5 ++++ ndctl/lib/libndctl.sym | 1 + ndctl/libndctl.h | 1 + ndctl/ndctl.c | 1 + 8 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 Documentation/ndctl/ndctl-sanitize.txt diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am index 3a761ba0..8c171ecb 100644 --- a/Documentation/ndctl/Makefile.am +++ b/Documentation/ndctl/Makefile.am @@ -50,7 +50,8 @@ man1_MANS = \ ndctl-monitor.1 \ ndctl-update-security.1 \ ndctl-disable-security.1 \ - ndctl-freeze-security.1 + ndctl-freeze-security.1 \ + ndctl-sanitize.1 CLEANFILES = $(man1_MANS) diff --git a/Documentation/ndctl/ndctl-sanitize.txt b/Documentation/ndctl/ndctl-sanitize.txt new file mode 100644 index 00000000..376487fa --- /dev/null +++ b/Documentation/ndctl/ndctl-sanitize.txt @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 + +ndctl-sanitize(1) +================= + +NAME +---- +ndctl-sanitize - sanitize the data on the NVDIMM + +SYNOPSIS +-------- +[verse] +'ndctl sanitize' [] + +OPTIONS +------- +:: +include::xable-dimm-options.txt[] + +-m:: +--method:: + The method for sanitizing the dimm content. + + crypto-erase: replaces encryption keys. This does not change label data. + +DESCRIPTION +----------- +Provide a generic interface to crypto erase a NVDIMM. +The use of this depends on support from the underlying +libndctl, kernel, as well as the platform itself. + +include::../copyright.txt[] diff --git a/builtin.h b/builtin.h index 7b970e10..f43988af 100644 --- a/builtin.h +++ b/builtin.h @@ -51,4 +51,5 @@ int cmd_inject_smart(int argc, const char **argv, void *ctx); int cmd_key_update(int argc, const char **argv, void *ctx); int cmd_disable_security(int argc, const char **argv, void *ctx); int cmd_freeze_security(int argc, const char **argv, void *ctx); +int cmd_sanitize(int argc, const char **argv, void *ctx); #endif /* _NDCTL_BUILTIN_H_ */ diff --git a/ndctl/dimm.c b/ndctl/dimm.c index 432ead74..c1321d39 100644 --- a/ndctl/dimm.c +++ b/ndctl/dimm.c @@ -46,6 +46,7 @@ static struct parameters { const char *infile; const char *labelversion; const char *key_exec; + const char *sanitize_method; bool force; bool json; bool verbose; @@ -903,6 +904,29 @@ static int action_security_freeze(struct ndctl_dimm *dimm, return rc; } +static int action_sanitize(struct ndctl_dimm *dimm, + struct action_context *actx) +{ + int rc; + + if (!param.sanitize_method) { + error("No sanitize_method passed in\n"); + return -EINVAL; + } + + if (strcmp(param.sanitize_method, "crypto-erase") == 0) { + rc = ndctl_dimm_secure_erase(dimm); + if (rc < 0) + error("Failed to secure erase for %s\n", + ndctl_dimm_get_devname(dimm)); + } else { + error("Incorrect sanitize method passed in.\n"); + return -EINVAL; + } + + return rc; +} + static int __action_init(struct ndctl_dimm *dimm, enum ndctl_namespace_version version, int chk_only) { @@ -998,6 +1022,10 @@ OPT_BOOLEAN('i', "insecure", ¶m.key_insecure, \ OPT_STRING('e', "exec", ¶m.key_exec, "external-exec", \ "external exec module for passphrase update") +#define SANITIZE_OPTIONS() \ +OPT_STRING('m', "method", ¶m.sanitize_method, "sanitize-method", \ + "method for sanitize a dimm") + static const struct option read_options[] = { BASE_OPTIONS(), READ_OPTIONS(), @@ -1033,6 +1061,12 @@ static const struct option key_options[] = { OPT_END(), }; +static const struct option sanitize_options[] = { + BASE_OPTIONS(), + SANITIZE_OPTIONS(), + OPT_END(), +}; + static int dimm_action(int argc, const char **argv, void *ctx, int (*action)(struct ndctl_dimm *dimm, struct action_context *actx), const struct option *options, const char *usage) @@ -1295,3 +1329,13 @@ int cmd_freeze_security(int argc, const char **argv, void *ctx) count > 1 ? "s" : ""); return count >= 0 ? 0 : EXIT_FAILURE; } + +int cmd_sanitize(int argc, const char **argv, void *ctx) +{ + int count = dimm_action(argc, argv, ctx, action_sanitize, sanitize_options, + "ndctl sanitize [..] []"); + + fprintf(stderr, "sanitized %d nmem%s.\n", count >= 0 ? count : 0, + count > 1 ? "s" : ""); + return count >= 0 ? 0 : EXIT_FAILURE; +} diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c index b383127c..2a28e227 100644 --- a/ndctl/lib/dimm.c +++ b/ndctl/lib/dimm.c @@ -629,3 +629,8 @@ NDCTL_EXPORT int ndctl_dimm_freeze_security(struct ndctl_dimm *dimm) { return ndctl_dimm_write_security(dimm, "freeze"); } + +NDCTL_EXPORT int ndctl_dimm_secure_erase(struct ndctl_dimm *dimm) +{ + return ndctl_dimm_write_security(dimm, "erase"); +} diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym index d543088f..2db49cad 100644 --- a/ndctl/lib/libndctl.sym +++ b/ndctl/lib/libndctl.sym @@ -387,4 +387,5 @@ global: ndctl_dimm_set_change_key; ndctl_dimm_disable_security; ndctl_dimm_freeze_security; + ndctl_dimm_secure_erase; } LIBNDCTL_17; diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h index 75364212..ef71cdd8 100644 --- a/ndctl/libndctl.h +++ b/ndctl/libndctl.h @@ -683,6 +683,7 @@ int ndctl_dimm_add_key(struct ndctl_dimm *dimm, const char *passphrase, int ndctl_dimm_get_current_key(struct ndctl_dimm *dimm, key_serial_t *key); int ndctl_dimm_disable_security(struct ndctl_dimm *dimm); int ndctl_dimm_freeze_security(struct ndctl_dimm *dimm); +int ndctl_dimm_secure_erase(struct ndctl_dimm *dimm); #ifdef __cplusplus } /* extern "C" */ diff --git a/ndctl/ndctl.c b/ndctl/ndctl.c index 7a242aab..07af7305 100644 --- a/ndctl/ndctl.c +++ b/ndctl/ndctl.c @@ -91,6 +91,7 @@ static struct cmd_struct commands[] = { { "update-security", cmd_key_update }, { "disable-security", cmd_disable_security }, { "freeze-security", cmd_freeze_security }, + { "sanitize", cmd_sanitize }, { "list", cmd_list }, { "monitor", cmd_monitor}, { "help", cmd_help }, From patchwork Tue Aug 28 22:52:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10579267 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 37AB1920 for ; Tue, 28 Aug 2018 22:52:28 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 279822AB98 for ; Tue, 28 Aug 2018 22:52:28 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1B15C2ABC0; Tue, 28 Aug 2018 22:52:28 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 07CF72AB98 for ; Tue, 28 Aug 2018 22:52:26 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id F261D21103988; Tue, 28 Aug 2018 15:52:25 -0700 (PDT) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.31; helo=mga06.intel.com; envelope-from=dave.jiang@intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga06.intel.com (mga06.intel.com [134.134.136.31]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 6CB0421102DAE for ; Tue, 28 Aug 2018 15:52:24 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga104.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 28 Aug 2018 15:52:24 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,300,1531810800"; d="scan'208";a="66725948" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by fmsmga008.fm.intel.com with ESMTP; 28 Aug 2018 15:52:18 -0700 Subject: [PATCH v3 6/6] ndctl: add request-key upcall reference app From: Dave Jiang To: vishal.l.verma@intel.com Date: Tue, 28 Aug 2018 15:52:18 -0700 Message-ID: <153549673831.5723.3252005522935384062.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> References: <153549661384.5723.4757814248604794802.stgit@djiang5-desk3.ch.intel.com> User-Agent: StGit/unknown-version MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: dhowells@redhat.com, alison.schofield@intel.com, linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Adding a reference upcall helper for request-key in order to retrieve the security passphrase from userspace to provide to the kernel. The reference app uses keyutils API to respond to the upcall from the kernel and is invoked by /sbin/request-key of the keyutils. Signed-off-by: Dave Jiang --- Documentation/ndctl/Makefile.am | 3 - Documentation/ndctl/nvdimm-upcall.txt | 33 ++++++++ ndctl.spec.in | 1 ndctl/Makefile.am | 5 + ndctl/nvdimm-upcall.c | 138 +++++++++++++++++++++++++++++++++ 5 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 Documentation/ndctl/nvdimm-upcall.txt create mode 100644 ndctl/nvdimm-upcall.c diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am index 8c171ecb..f4e8b24c 100644 --- a/Documentation/ndctl/Makefile.am +++ b/Documentation/ndctl/Makefile.am @@ -51,7 +51,8 @@ man1_MANS = \ ndctl-update-security.1 \ ndctl-disable-security.1 \ ndctl-freeze-security.1 \ - ndctl-sanitize.1 + ndctl-sanitize.1 \ + nvdimm-upcall.1 CLEANFILES = $(man1_MANS) diff --git a/Documentation/ndctl/nvdimm-upcall.txt b/Documentation/ndctl/nvdimm-upcall.txt new file mode 100644 index 00000000..bbf52fd1 --- /dev/null +++ b/Documentation/ndctl/nvdimm-upcall.txt @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 + +nvdimm-upcall(1) +================ + +NAME +---- +nvdimm-upcall - upcall helper for keyutils + +SYNOPSIS +-------- +[verse] +'nvdimm-upcall' [key_id] + +DESCRIPTION +----------- +nvdimm-upcall is called by request-key from keyutils and not meant to be used +directly by the user. It expects to read from /etc/nvdimm.passwd to retrieve +the description and passphrase for the NVDIMM key. + +The nvdimm.passwd is formatted as: +: +cdab-0a-07e0-feffffff:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +In order for this util to be called, /etc/request-key.conf must be appended +with the following line: +create logon nvdimm* * /usr/sbin/nvdimm-upcall %k + +include::../copyright.txt[] + +SEE ALSO +-------- +http://pmem.io/documents/NVDIMM_DSM_Interface-V1.7.pdf diff --git a/ndctl.spec.in b/ndctl.spec.in index c71bd581..6416c0b6 100644 --- a/ndctl.spec.in +++ b/ndctl.spec.in @@ -123,6 +123,7 @@ make check %{_unitdir}/ndctl-monitor.service %{_udevrulesdir}/80-ndctl.rules %{udevdir}/ndctl-udev +%{_sbindir}/nvdimm-upcall %files -n daxctl %defattr(-,root,root) diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am index 4b44294e..ec4c9229 100644 --- a/ndctl/Makefile.am +++ b/ndctl/Makefile.am @@ -1,6 +1,7 @@ include $(top_srcdir)/Makefile.am.in bin_PROGRAMS = ndctl +sbin_PROGRAMS = nvdimm-upcall ndctl_SOURCES = ndctl.c \ bus.c \ @@ -56,3 +57,7 @@ ndctl_udevdir = $(UDEVDIR) ndctl_udev_PROGRAMS = ndctl-udev ndctl_udev_SOURCES = ndctl-udev.c ndctl_udev_LDADD = lib/libndctl.la + +nvdimm_upcall_SOURCES = nvdimm-upcall.c + +nvdimm_upcall_LDADD = $(KEYUTILS_LIBS) diff --git a/ndctl/nvdimm-upcall.c b/ndctl/nvdimm-upcall.c new file mode 100644 index 00000000..904a1141 --- /dev/null +++ b/ndctl/nvdimm-upcall.c @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright(c) 2018 Intel Corporation. All rights reserved. */ + +/* + * Used by /sbin/request-key for handling nvdimm upcall of key requests + * for security DSMs. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PASSPHRASE_SIZE 32 +#define PASS_PATH "/etc/nvdimm.passwd" + +static FILE *fp; + +static int get_passphrase_from_id(const char *id, char *pass, int *psize) +{ + ssize_t rc = 0; + size_t size; + char *line = NULL; + char *tmp, *id_tok, *secret; + int found = 0; + + fp = fopen(PASS_PATH, "r+"); + if (!fp) { + syslog(LOG_ERR, "fopen: %s\n", strerror(errno)); + return -errno; + } + + while ((rc = getline(&line, &size, fp)) != -1) { + id_tok = strtok_r(line, ":", &tmp); + if (!id_tok) + break; + if (strcmp(id_tok, id) == 0) { + secret = tmp; + found = 1; + rc = 0; + break; + } + } + + if (rc == 0 && found && secret) { + memset(pass, 0, PASSPHRASE_SIZE*2+1); + size = MIN(strlen(secret), (PASSPHRASE_SIZE*2+1)); + memcpy(pass, secret, size); + *psize = size-1; + } else + rc = -ENXIO; + + free(line); + fclose(fp); + return rc; +} + +static char *get_key_desc(char *buf) +{ + char *tmp = &buf[0]; + int count = 0; + + while (*tmp != '\0') { + if (*tmp == ';') + count++; + if (count == 4) { + tmp++; + return tmp; + } + tmp++; + } + + return NULL; +} + +int main(int argc, const char **argv) +{ + key_serial_t key; + int rc; + char *buf, *desc, *dimm_id; + char pass[PASSPHRASE_SIZE * 2 + 1]; + int size = 0; + + if (argc < 2) { + syslog(LOG_ERR, "Incorrect number of arguments\n"); + return -EINVAL; + } + + syslog(LOG_DEBUG, "key passed in: %s\n", argv[1]); + key = strtol(argv[1], NULL, 10); + if (key < 0) { + syslog(LOG_ERR, "Invalid key format: %s\n", strerror(errno)); + return -errno; + } + + rc = keyctl_describe_alloc(key, &buf); + if (rc < 0) { + syslog(LOG_ERR, "keyctl_describe_alloc failed: %s\n", + strerror(errno)); + rc = -errno; + goto out; + } + + desc = get_key_desc(buf); + if (!desc) { + syslog(LOG_ERR, "Can't find key description\n"); + rc = -EINVAL; + goto out; + } + + strtok_r(desc, ":", &dimm_id); + rc = get_passphrase_from_id(dimm_id, pass, &size); + if (rc < 0) { + syslog(LOG_ERR, "failed to retrieve passphrase\n"); + goto out; + } + + rc = keyctl_instantiate(key, pass, size, 0); + if (rc < 0) { + syslog(LOG_ERR, "keyctl_instantiate failed: %s\n", + strerror(errno)); + rc = -errno; + goto out; + } + + out: + if (rc < 0) + keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT); + + return rc; +}