From patchwork Fri Jan 18 02:38:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Jiang X-Patchwork-Id: 10769301 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 47B026C5 for ; Fri, 18 Jan 2019 02:38:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 31A262FA0F for ; Fri, 18 Jan 2019 02:38:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2257F2F9D6; Fri, 18 Jan 2019 02:38:36 +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 5466B2F9D6 for ; Fri, 18 Jan 2019 02:38:35 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id 4DA4A211B85DF; Thu, 17 Jan 2019 18:38:35 -0800 (PST) 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 0EAAA211B509C for ; Thu, 17 Jan 2019 18:38:33 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Jan 2019 18:38:33 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,489,1539673200"; d="scan'208";a="110789501" Received: from djiang5-desk3.ch.intel.com ([143.182.136.93]) by orsmga008.jf.intel.com with ESMTP; 17 Jan 2019 18:38:33 -0800 Subject: [PATCH v9 02/13] ndctl: add command for ndctl to receive the key encryption key (master) From: Dave Jiang To: vishal.l.verma@intel.com, dan.j.williams@intel.com Date: Thu, 17 Jan 2019 19:38:33 -0700 Message-ID: <154777911312.42557.15688834797714631330.stgit@djiang5-desk3.ch.intel.com> In-Reply-To: <154777861562.42557.12388414625709189905.stgit@djiang5-desk3.ch.intel.com> References: <154777861562.42557.12388414625709189905.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: linux-nvdimm@lists.01.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Add command that allows the user to provide the master encryption key name to be installed in the key material directory where ndctl can refer to for later security operations. Signed-off-by: Dave Jiang --- Documentation/ndctl/Makefile.am | 3 Documentation/ndctl/ndctl-install-encrypt-key.txt | 31 +++++ configure.ac | 3 ndctl/Makefile.am | 4 - ndctl/builtin.h | 1 ndctl/kek.c | 133 +++++++++++++++++++++ ndctl/lib/libndctl.c | 31 +++++ ndctl/lib/libndctl.sym | 1 ndctl/lib/private.h | 1 ndctl/libndctl.h | 1 ndctl/ndctl.c | 1 11 files changed, 208 insertions(+), 2 deletions(-) create mode 100644 Documentation/ndctl/ndctl-install-encrypt-key.txt create mode 100644 ndctl/kek.c diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am index a30b139b..7cb7bd6b 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-install-encrypt-key.1 CLEANFILES = $(man1_MANS) diff --git a/Documentation/ndctl/ndctl-install-encrypt-key.txt b/Documentation/ndctl/ndctl-install-encrypt-key.txt new file mode 100644 index 00000000..d00463e3 --- /dev/null +++ b/Documentation/ndctl/ndctl-install-encrypt-key.txt @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0 + +ndctl-install-encrypt-key(1) +============================ + +NAME +---- +ndctl-install-encrypt-key - store encryption key name for nvdimm bus + +SYNOPSIS +-------- +[verse] +'ndctl install-encrypt-key [..] [-k ] + +Take the provided master encryption key handle and store it in a file that +A file would be created for the designated bus provider. +i.e. /etc/ndctl/keys/nfit_test.0.kek +The command only succeeds on bus(es) that contain nvdimms with security support. + +OPTIONS +------- +-k:: +--kek=:: + Key encryption key (master key) handle. The key handle has the format + of :. i.e. trusted:nvdimm-master. + +-v:: +--verbose:: + Turn on debug output + +include::../copyright.txt[] diff --git a/configure.ac b/configure.ac index a02a2d80..61e91e0a 100644 --- a/configure.ac +++ b/configure.ac @@ -159,6 +159,9 @@ ndctl_monitorconf=monitor.conf AC_SUBST([ndctl_monitorconfdir]) AC_SUBST([ndctl_monitorconf]) +ndctl_keysdir=${sysconfdir}/ndctl/keys +AC_SUBST([ndctl_keysdir]) + my_CFLAGS="\ -Wall \ -Wchar-subscripts \ diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am index 97de1814..e412dbf7 100644 --- a/ndctl/Makefile.am +++ b/ndctl/Makefile.am @@ -8,6 +8,7 @@ config.h: Makefile.am $(AM_V_GEN) echo "/* Autogenerated by ndctl/Makefile.am */" >$@ $(AM_V_GEN) echo '#define NDCTL_CONF_FILE \ "$(ndctl_monitorconfdir)/$(ndctl_monitorconf)"' >>$@ + $(AM_V_GEN) echo '#define NDCTL_KEYS_DIR "$(ndctl_keysdir)"' >>$@ ndctl_SOURCES = ndctl.c \ bus.c \ @@ -23,7 +24,8 @@ ndctl_SOURCES = ndctl.c \ util/json-firmware.c \ inject-error.c \ inject-smart.c \ - monitor.c + monitor.c \ + kek.c if ENABLE_DESTRUCTIVE ndctl_SOURCES += ../test/blk_namespaces.c \ diff --git a/ndctl/builtin.h b/ndctl/builtin.h index 17300df0..4af34f04 100644 --- a/ndctl/builtin.h +++ b/ndctl/builtin.h @@ -32,4 +32,5 @@ int cmd_bat(int argc, const char **argv, struct ndctl_ctx *ctx); #endif int cmd_update_firmware(int argc, const char **argv, struct ndctl_ctx *ctx); int cmd_inject_smart(int argc, const char **argv, struct ndctl_ctx *ctx); +int cmd_install_kek(int argc, const char **argv, struct ndctl_ctx *ctx); #endif /* _NDCTL_BUILTIN_H_ */ diff --git a/ndctl/kek.c b/ndctl/kek.c new file mode 100644 index 00000000..1cb1555e --- /dev/null +++ b/ndctl/kek.c @@ -0,0 +1,133 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright(c) 2019 Intel Corporation. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static struct parameters { + const char *kek; + bool verbose; +} param; + +static int store_kek(const char *provider, const char *kek) +{ + char path[PATH_MAX]; + FILE *fp; + ssize_t rc, wrote = 0; + int size = strlen(kek); + + rc = sprintf(path, "%s/%s.kek", NDCTL_KEYS_DIR, provider); + if (rc < 0) { + perror("sprintf kek path failed"); + return rc; + } + + fp = fopen(path, "w+"); + if (!fp) { + fprintf(stderr, "Opening file %s failed: %s\n", + path, strerror(errno)); + return -errno; + } + + do { + rc = fwrite(kek + wrote, 1, size - wrote, fp); + if (rc < 0) { + fprintf(stderr, "writing file %s failed: %s\n", + path, strerror(errno)); + fclose(fp); + return -errno; + } + wrote += rc; + } while (wrote != size); + + fclose(fp); + printf("key handle %s installed to %s\n", kek, path); + return 0; +} + +int cmd_install_kek(int argc, const char **argv, struct ndctl_ctx *ctx) +{ + const struct option options[] = { + OPT_BOOLEAN('v',"verbose", ¶m.verbose, "turn on debug"), + OPT_STRING('k', "kek", ¶m.kek, "kek", + "Key encription key (master)"), + OPT_END(), + }; + const char * const u[] = { + "ndctl intall-encrypt-key [..] [-k ]", + NULL + }; + int i, rc; + bool all = false; + + argc = parse_options(argc, argv, options, u, 0); + + if (argc == 0) { + usage_with_options(u, options); + return -EINVAL; + } + + if (!param.kek) { + usage_with_options(u, options); + return -EINVAL; + } + + for (i = 0; i < argc; i++) { + if (strcmp(argv[i], "all") == 0) { + argv[0] = "all"; + argc = 1; + all = true; + break; + } + } + + if (param.verbose) + ndctl_set_log_priority(ctx, LOG_DEBUG); + + for (i = 0; i < argc; i++) { + struct ndctl_bus *bus; + struct ndctl_dimm *dimm; + bool security = false; + + ndctl_bus_foreach(ctx, bus) { + if (!util_bus_filter(bus, argv[i]) && !all) + continue; + + ndctl_dimm_foreach(bus, dimm) { + if (ndctl_dimm_get_security(dimm) >= 0) { + security = true; + break; + } + } + + if (!security) + continue; + + rc = store_kek(ndctl_bus_get_provider(bus), + param.kek); + if (rc < 0) + fprintf(stderr, "store kek %s for bus %s failed\n", + param.kek, ndctl_bus_get_devname(bus)); + + } + } + + return 0; +} diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c index 830b7913..b255eb1b 100644 --- a/ndctl/lib/libndctl.c +++ b/ndctl/lib/libndctl.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "private.h" static uuid_t null_uuid; @@ -620,6 +621,7 @@ static void free_bus(struct ndctl_bus *bus, struct list_head *head) free(bus->bus_buf); free(bus->wait_probe_path); free(bus->scrub_path); + free(bus->kek_handle); free(bus); } @@ -812,6 +814,28 @@ static void parse_dimm_flags(struct ndctl_dimm *dimm, char *flags) ndctl_dimm_get_devname(dimm), flags); } +static int bus_retrieve_kek_handle(struct ndctl_bus *bus) +{ + char path[PATH_MAX]; + FILE *fp; + ssize_t rc; + + rc = sprintf(path, "%s/%s.kek", NDCTL_KEYS_DIR, + ndctl_bus_get_provider(bus)); + if (rc < 0) + return -errno; + + fp = fopen(path, "r"); + if (!fp) + return -errno; + + if (fscanf(fp, "%ms", &bus->kek_handle) == EOF) + return -errno; + + fclose(fp); + return 0; +} + static void *add_bus(void *parent, int id, const char *ctl_base) { char buf[SYSFS_ATTR_SIZE]; @@ -890,6 +914,8 @@ static void *add_bus(void *parent, int id, const char *ctl_base) return bus_dup; } + bus_retrieve_kek_handle(bus); + list_add(&ctx->busses, &bus->list); free(path); @@ -5396,3 +5422,8 @@ NDCTL_EXPORT struct daxctl_region *ndctl_dax_get_daxctl_region( return dax->region; } + +NDCTL_EXPORT const char *ndctl_bus_get_kek_handle(struct ndctl_bus *bus) +{ + return bus->kek_handle; +} diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym index 0888c824..6d5e6606 100644 --- a/ndctl/lib/libndctl.sym +++ b/ndctl/lib/libndctl.sym @@ -391,4 +391,5 @@ global: ndctl_cmd_xlat_firmware_status; ndctl_cmd_submit_xlat; ndctl_dimm_get_security; + ndctl_bus_get_kek_handle; } LIBNDCTL_18; diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h index a387b0b5..a860f0db 100644 --- a/ndctl/lib/private.h +++ b/ndctl/lib/private.h @@ -172,6 +172,7 @@ struct ndctl_bus { char *scrub_path; unsigned long cmd_mask; unsigned long nfit_dsm_mask; + char *kek_handle; }; /** diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h index e228c64f..b0cc4543 100644 --- a/ndctl/libndctl.h +++ b/ndctl/libndctl.h @@ -694,6 +694,7 @@ enum ndctl_security_state { }; enum ndctl_security_state ndctl_dimm_get_security(struct ndctl_dimm *dimm); +const char *ndctl_bus_get_kek_handle(struct ndctl_bus *bus); #ifdef __cplusplus } /* extern "C" */ diff --git a/ndctl/ndctl.c b/ndctl/ndctl.c index b01594e0..bd11ec03 100644 --- a/ndctl/ndctl.c +++ b/ndctl/ndctl.c @@ -90,6 +90,7 @@ static struct cmd_struct commands[] = { { "start-scrub", { cmd_start_scrub } }, { "list", { cmd_list } }, { "monitor", { cmd_monitor } }, + { "install-encrypt-key", { cmd_install_kek } }, { "help", { cmd_help } }, #ifdef ENABLE_TEST { "test", { cmd_test } },