fpga: m10bmc-sec: expose max10 canceled keys in sysfs
authorRuss Weight <russell.h.weight@intel.com>
Mon, 6 Jun 2022 16:00:37 +0000 (09:00 -0700)
committerXu Yilun <yilun.xu@intel.com>
Wed, 8 Jun 2022 09:04:38 +0000 (17:04 +0800)
Extend the MAX10 BMC Secure Update driver to provide sysfs files to
expose the 128 bit code signing key (CSK) cancellation vectors. These use
the standard bitmap list format (e.g. 1,2-6,9).

Each CSK is assigned an ID, a number between 0-127, during the signing
process. CSK ID cancellation information is stored in 128-bit fields in
write-once locations in flash.  The cancellation of a CSK can be used
to prevent the card from being rolled back to older images that were
signed with a CSK that is now cancelled.

Reviewed-by: Tom Rix <trix@redhat.com>
Tested-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Russ Weight <russell.h.weight@intel.com>
Link: https://lore.kernel.org/r/20220606160038.846236-5-russell.h.weight@intel.com
Signed-off-by: Xu Yilun <yilun.xu@intel.com>
Documentation/ABI/testing/sysfs-driver-intel-m10-bmc-sec-update
drivers/fpga/intel-m10-bmc-sec-update.c

index 6114e15885e5109df0406440e8350adbbdc1dcc3..0a41afe0ab4cbe9c915fc8a16268738da0aad411 100644 (file)
@@ -28,6 +28,30 @@ Description: Read only. Returns the root entry hash for the BMC image
                underlying device supports it.
                Format: string.
 
+What:          /sys/bus/platform/drivers/intel-m10bmc-sec-update/.../security/sr_canceled_csks
+Date:          Sep 2022
+KernelVersion: 5.20
+Contact:       Russ Weight <russell.h.weight@intel.com>
+Description:   Read only. Returns a list of indices for canceled code
+               signing keys for the static region. The standard bitmap
+               list format is used (e.g. "1,2-6,9").
+
+What:          /sys/bus/platform/drivers/intel-m10bmc-sec-update/.../security/pr_canceled_csks
+Date:          Sep 2022
+KernelVersion: 5.20
+Contact:       Russ Weight <russell.h.weight@intel.com>
+Description:   Read only. Returns a list of indices for canceled code
+               signing keys for the partial reconfiguration region. The
+               standard bitmap list format is used (e.g. "1,2-6,9").
+
+What:          /sys/bus/platform/drivers/intel-m10bmc-sec-update/.../security/bmc_canceled_csks
+Date:          Sep 2022
+KernelVersion: 5.20
+Contact:       Russ Weight <russell.h.weight@intel.com>
+Description:   Read only. Returns a list of indices for canceled code
+               signing keys for the BMC.  The standard bitmap list format
+               is used (e.g. "1,2-6,9").
+
 What:          /sys/bus/platform/drivers/intel-m10bmc-sec-update/.../security/flash_count
 Date:          Sep 2022
 KernelVersion: 5.20
index 25b21f11697652ced65113545432fbe17a0e523b..65fec2a7090166e043a00272cdd32edf71dde136 100644 (file)
@@ -78,6 +78,57 @@ DEVICE_ATTR_SEC_REH_RO(bmc, BMC_PROG_MAGIC, BMC_PROG_ADDR, BMC_REH_ADDR);
 DEVICE_ATTR_SEC_REH_RO(sr, SR_PROG_MAGIC, SR_PROG_ADDR, SR_REH_ADDR);
 DEVICE_ATTR_SEC_REH_RO(pr, PR_PROG_MAGIC, PR_PROG_ADDR, PR_REH_ADDR);
 
+#define CSK_BIT_LEN            128U
+#define CSK_32ARRAY_SIZE       DIV_ROUND_UP(CSK_BIT_LEN, 32)
+
+static ssize_t
+show_canceled_csk(struct device *dev, u32 addr, char *buf)
+{
+       unsigned int i, stride, size = CSK_32ARRAY_SIZE * sizeof(u32);
+       struct m10bmc_sec *sec = dev_get_drvdata(dev);
+       DECLARE_BITMAP(csk_map, CSK_BIT_LEN);
+       __le32 csk_le32[CSK_32ARRAY_SIZE];
+       u32 csk32[CSK_32ARRAY_SIZE];
+       int ret;
+
+       stride = regmap_get_reg_stride(sec->m10bmc->regmap);
+       if (size % stride) {
+               dev_err(sec->dev,
+                       "CSK vector size (0x%x) not aligned to stride (0x%x)\n",
+                       size, stride);
+               WARN_ON_ONCE(1);
+               return -EINVAL;
+       }
+
+       ret = regmap_bulk_read(sec->m10bmc->regmap, addr, csk_le32,
+                              size / stride);
+       if (ret) {
+               dev_err(sec->dev, "failed to read CSK vector: %x cnt %x: %d\n",
+                       addr, size / stride, ret);
+               return ret;
+       }
+
+       for (i = 0; i < CSK_32ARRAY_SIZE; i++)
+               csk32[i] = le32_to_cpu(((csk_le32[i])));
+
+       bitmap_from_arr32(csk_map, csk32, CSK_BIT_LEN);
+       bitmap_complement(csk_map, csk_map, CSK_BIT_LEN);
+       return bitmap_print_to_pagebuf(1, buf, csk_map, CSK_BIT_LEN);
+}
+
+#define DEVICE_ATTR_SEC_CSK_RO(_name, _addr) \
+static ssize_t _name##_canceled_csks_show(struct device *dev, \
+                                         struct device_attribute *attr, \
+                                         char *buf) \
+{ return show_canceled_csk(dev, _addr, buf); } \
+static DEVICE_ATTR_RO(_name##_canceled_csks)
+
+#define CSK_VEC_OFFSET 0x34
+
+DEVICE_ATTR_SEC_CSK_RO(bmc, BMC_PROG_ADDR + CSK_VEC_OFFSET);
+DEVICE_ATTR_SEC_CSK_RO(sr, SR_PROG_ADDR + CSK_VEC_OFFSET);
+DEVICE_ATTR_SEC_CSK_RO(pr, PR_PROG_ADDR + CSK_VEC_OFFSET);
+
 #define FLASH_COUNT_SIZE 4096  /* count stored as inverted bit vector */
 
 static ssize_t flash_count_show(struct device *dev,
@@ -125,6 +176,9 @@ static struct attribute *m10bmc_security_attrs[] = {
        &dev_attr_bmc_root_entry_hash.attr,
        &dev_attr_sr_root_entry_hash.attr,
        &dev_attr_pr_root_entry_hash.attr,
+       &dev_attr_sr_canceled_csks.attr,
+       &dev_attr_pr_canceled_csks.attr,
+       &dev_attr_bmc_canceled_csks.attr,
        NULL,
 };