lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Fri,  2 Oct 2020 18:24:08 -0700
From:   Russ Weight <russell.h.weight@...el.com>
To:     mdf@...nel.org, lee.jones@...aro.org, linux-fpga@...r.kernel.org,
        linux-kernel@...r.kernel.org
Cc:     trix@...hat.com, lgoncalv@...hat.com, yilun.xu@...el.com,
        hao.wu@...el.com, matthew.gerlach@...el.com,
        Russ Weight <russell.h.weight@...el.com>
Subject: [PATCH v2 2/6] fpga: m10bmc-sec: create max10 bmc security engine

Create a platform driver that can be invoked as a sub
driver for the Intel MAX10 BMC in order to support
secure updates. This sub-driver will invoke an
instance of the Intel FPGA Security Manager class driver
in order to expose sysfs interfaces for managing and
monitoring secure updates to FPGA and BMC images.

This patch creates the MAX10 BMC Security Engine driver and
provides support for displaying the current root entry hashes
for the FPGA static region, the FPGA PR region, and the MAX10
BMC.

Signed-off-by: Russ Weight <russell.h.weight@...el.com>
---
v2:
  - Added drivers/fpga/intel-m10-bmc-secure.c file to MAINTAINERS.
  - Switched to GENMASK(31, 16) for a couple of mask definitions.
  - Moved MAX10 BMC address and function definitions to a separate
    patch.
  - Replaced small function-creation macros with explicit function
    declarations.
  - Removed ifpga_sec_mgr_init() and ifpga_sec_mgr_uinit() functions.
  - Adapted to changes in the Intel FPGA Security Manager by splitting
    the single call to ifpga_sec_mgr_register() into two function
    calls: devm_ifpga_sec_mgr_create() and ifpga_sec_mgr_register().
---
 MAINTAINERS                         |   1 +
 drivers/fpga/Kconfig                |  11 ++
 drivers/fpga/Makefile               |   3 +
 drivers/fpga/intel-m10-bmc-secure.c | 165 ++++++++++++++++++++++++++++
 4 files changed, 180 insertions(+)
 create mode 100644 drivers/fpga/intel-m10-bmc-secure.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 0bb5ef309dec..c359d0214980 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6898,6 +6898,7 @@ S:	Maintained
 F:	Documentation/ABI/testing/sysfs-class-ifpga-sec-mgr
 F:	Documentation/fpga/ifpga-sec-mgr.rst
 F:	drivers/fpga/ifpga-sec-mgr.c
+F:	drivers/fpga/intel-m10-bmc-secure.c
 F:	include/linux/fpga/ifpga-sec-mgr.h
 
 FPU EMULATOR
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index c534cc80f398..2380d36b08c7 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -235,4 +235,15 @@ config IFPGA_SEC_MGR
 	  region and for the BMC. Select this option to enable
 	  updates for secure FPGA devices.
 
+config IFPGA_M10_BMC_SECURE
+        tristate "Intel MAX10 BMC security engine"
+	depends on MFD_INTEL_M10_BMC && IFPGA_SEC_MGR
+        help
+          Secure update support for the Intel MAX10 board management
+	  controller.
+
+	  This is a subdriver of the Intel MAX10 board management controller
+	  (BMC) and provides support for secure updates for the BMC image,
+	  the FPGA image, the Root Entry Hashes, etc.
+
 endif # FPGA
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 6f706590e209..8e702689cdda 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -24,6 +24,9 @@ obj-$(CONFIG_ALTERA_PR_IP_CORE_PLAT)    += altera-pr-ip-core-plat.o
 # Intel FPGA Security Manager Framework
 obj-$(CONFIG_IFPGA_SEC_MGR)		+= ifpga-sec-mgr.o
 
+# Intel Security Manager Drivers
+obj-$(CONFIG_IFPGA_M10_BMC_SECURE)	+= intel-m10-bmc-secure.o
+
 # FPGA Bridge Drivers
 obj-$(CONFIG_FPGA_BRIDGE)		+= fpga-bridge.o
 obj-$(CONFIG_SOCFPGA_FPGA_BRIDGE)	+= altera-hps2fpga.o altera-fpga2sdram.o
diff --git a/drivers/fpga/intel-m10-bmc-secure.c b/drivers/fpga/intel-m10-bmc-secure.c
new file mode 100644
index 000000000000..df8ebda9a9cb
--- /dev/null
+++ b/drivers/fpga/intel-m10-bmc-secure.c
@@ -0,0 +1,165 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Intel Max10 Board Management Controller Security Engine Driver
+ *
+ * Copyright (C) 2019-2020 Intel Corporation. All rights reserved.
+ *
+ */
+#include <linux/bitfield.h>
+#include <linux/device.h>
+#include <linux/fpga/ifpga-sec-mgr.h>
+#include <linux/mfd/intel-m10-bmc.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/vmalloc.h>
+
+struct m10bmc_sec {
+	struct device *dev;
+	struct intel_m10bmc *m10bmc;
+	struct ifpga_sec_mgr *imgr;
+};
+
+#define REH_SHA256_SIZE		32
+#define REH_SHA384_SIZE		48
+#define REH_MAGIC		GENMASK(15, 0)
+#define REH_SHA_NUM_BYTES	GENMASK(31, 16)
+
+static int m10bmc_reh_size(struct ifpga_sec_mgr *imgr,
+			   u32 exp_magic, u32 prog_addr)
+{
+	struct m10bmc_sec *sec = imgr->priv;
+	int sha_num_bytes, ret;
+	u32 magic;
+
+	ret = m10bmc_raw_read(sec->m10bmc, prog_addr, &magic);
+	if (ret)
+		return ret;
+
+	dev_dbg(sec->dev, "%s magic 0x%08x\n", __func__, magic);
+
+	/*
+	 * If no magic number, then no REH is programmed, so
+	 * the REH size is zero.
+	 */
+	if (FIELD_GET(REH_MAGIC, magic) != exp_magic)
+		return 0;
+
+	sha_num_bytes = FIELD_GET(REH_SHA_NUM_BYTES, magic) / 8;
+	if (sha_num_bytes != REH_SHA256_SIZE &&
+	    sha_num_bytes != REH_SHA384_SIZE)   {
+		dev_err(sec->dev, "%s bad sha num bytes %d\n", __func__,
+			sha_num_bytes);
+		return -EINVAL;
+	}
+
+	return sha_num_bytes;
+}
+
+static int m10bmc_bmc_reh_size(struct ifpga_sec_mgr *imgr)
+{
+	return m10bmc_reh_size(imgr, BMC_PROG_MAGIC, BMC_PROG_ADDR);
+}
+
+static int m10bmc_sr_reh_size(struct ifpga_sec_mgr *imgr)
+{
+	return m10bmc_reh_size(imgr, SR_PROG_MAGIC, SR_PROG_ADDR);
+}
+
+static int m10bmc_pr_reh_size(struct ifpga_sec_mgr *imgr)
+{
+	return m10bmc_reh_size(imgr, PR_PROG_MAGIC, PR_PROG_ADDR);
+}
+
+static int m10bmc_root_entry_hash(struct ifpga_sec_mgr *imgr,
+				  u32 hash_addr, u8 *hash,
+				  unsigned int size)
+{
+	struct m10bmc_sec *sec = imgr->priv;
+	unsigned int stride = regmap_get_reg_stride(sec->m10bmc->regmap);
+	int ret;
+
+	ret = m10bmc_raw_bulk_read(sec->m10bmc, hash_addr,
+				   hash, size / stride);
+	if (ret)
+		dev_err(sec->dev, "bulk_read of 0x%x failed %d",
+			hash_addr, ret);
+
+	return ret;
+}
+
+static int m10bmc_bmc_root_entry_hash(struct ifpga_sec_mgr *imgr,
+				      u8 *hash, unsigned int size)
+{
+	return m10bmc_root_entry_hash(imgr, BMC_REH_ADDR, hash, size);
+}
+
+static int m10bmc_sr_root_entry_hash(struct ifpga_sec_mgr *imgr,
+				     u8 *hash, unsigned int size)
+{
+	return m10bmc_root_entry_hash(imgr, SR_REH_ADDR, hash, size);
+}
+
+static int m10bmc_pr_root_entry_hash(struct ifpga_sec_mgr *imgr,
+				     u8 *hash, unsigned int size)
+{
+	return m10bmc_root_entry_hash(imgr, PR_REH_ADDR, hash, size);
+}
+
+static const struct ifpga_sec_mgr_ops m10bmc_iops = {
+	.bmc_root_entry_hash = m10bmc_bmc_root_entry_hash,
+	.sr_root_entry_hash = m10bmc_sr_root_entry_hash,
+	.pr_root_entry_hash = m10bmc_pr_root_entry_hash,
+	.bmc_reh_size = m10bmc_bmc_reh_size,
+	.sr_reh_size = m10bmc_sr_reh_size,
+	.pr_reh_size = m10bmc_pr_reh_size,
+};
+
+static int m10bmc_secure_probe(struct platform_device *pdev)
+{
+	struct ifpga_sec_mgr *imgr;
+	struct m10bmc_sec *sec;
+	int ret;
+
+	sec = devm_kzalloc(&pdev->dev, sizeof(*sec), GFP_KERNEL);
+	if (!sec)
+		return -ENOMEM;
+
+	sec->dev = &pdev->dev;
+	sec->m10bmc = dev_get_drvdata(pdev->dev.parent);
+	dev_set_drvdata(&pdev->dev, sec);
+
+	imgr = devm_ifpga_sec_mgr_create(sec->dev, "Max10 BMC Security Manager",
+					 &m10bmc_iops, sec);
+	if (!imgr) {
+		dev_err(sec->dev,
+			"Security manager failed to start: %d\n", ret);
+		return -ENOMEM;
+	}
+
+	sec->imgr = imgr;
+
+	return ifpga_sec_mgr_register(imgr);
+}
+
+static int m10bmc_secure_remove(struct platform_device *pdev)
+{
+	struct m10bmc_sec *sec = dev_get_drvdata(&pdev->dev);
+
+	ifpga_sec_mgr_unregister(sec->imgr);
+
+	return 0;
+}
+
+static struct platform_driver intel_m10bmc_secure_driver = {
+	.probe = m10bmc_secure_probe,
+	.remove = m10bmc_secure_remove,
+	.driver = {
+		.name = "n3000bmc-secure",
+	},
+};
+module_platform_driver(intel_m10bmc_secure_driver);
+
+MODULE_ALIAS("platform:n3000bmc-secure");
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Intel MAX10 BMC secure engine");
+MODULE_LICENSE("GPL v2");
-- 
2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ