Add dedicated command to register in fuse a public hash
key provided by keygen tool.

Signed-off-by: Patrick Delaunay <patrick.delau...@st.com>
---

Changes in v2: None

 arch/arm/mach-stm32mp/Kconfig        |   8 +++
 arch/arm/mach-stm32mp/Makefile       |   1 +
 arch/arm/mach-stm32mp/cmd_stm32key.c | 101 +++++++++++++++++++++++++++++++++++
 3 files changed, 110 insertions(+)
 create mode 100644 arch/arm/mach-stm32mp/cmd_stm32key.c

diff --git a/arch/arm/mach-stm32mp/Kconfig b/arch/arm/mach-stm32mp/Kconfig
index 9c5c93c..d13d76e 100644
--- a/arch/arm/mach-stm32mp/Kconfig
+++ b/arch/arm/mach-stm32mp/Kconfig
@@ -90,6 +90,14 @@ config STM32_ETZPC
        help
          Say y to enable STM32 Extended TrustZone Protection
 
+config CMD_STM32KEY
+       bool "command stm32key to fuse public key hash"
+       default y
+       depends on CMD_FUSE
+       help
+               fuse public key hash in corresponding fuse used to authenticate
+               binary.
+
 config BOOTSTAGE_STASH_ADDR
        default 0xC3000000
 
diff --git a/arch/arm/mach-stm32mp/Makefile b/arch/arm/mach-stm32mp/Makefile
index e59bd81..7745060 100644
--- a/arch/arm/mach-stm32mp/Makefile
+++ b/arch/arm/mach-stm32mp/Makefile
@@ -11,6 +11,7 @@ ifdef CONFIG_SPL_BUILD
 obj-y += spl.o
 else
 obj-y += bsec.o
+obj-$(CONFIG_CMD_STM32KEY) += cmd_stm32key.o
 ifndef CONFIG_STM32MP1_TRUSTED
 obj-$(CONFIG_SYSRESET) += cmd_poweroff.o
 endif
diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c 
b/arch/arm/mach-stm32mp/cmd_stm32key.c
new file mode 100644
index 0000000..f1f26e7
--- /dev/null
+++ b/arch/arm/mach-stm32mp/cmd_stm32key.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
+/*
+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ */
+
+#include <common.h>
+#include <command.h>
+#include <console.h>
+#include <misc.h>
+#include <dm/device.h>
+#include <dm/uclass.h>
+
+#define STM32_OTP_HASH_KEY_START 24
+#define STM32_OTP_HASH_KEY_SIZE 8
+
+static void read_hash_value(u32 addr)
+{
+       int i;
+
+       for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) {
+               printf("OTP value %i: %x\n", STM32_OTP_HASH_KEY_START + i,
+                      __be32_to_cpu(*(u32 *)addr));
+               addr += 4;
+       }
+}
+
+static void fuse_hash_value(u32 addr, bool print)
+{
+       struct udevice *dev;
+       u32 word, val;
+       int i, ret;
+
+       ret = uclass_get_device_by_driver(UCLASS_MISC,
+                                         DM_GET_DRIVER(stm32mp_bsec),
+                                         &dev);
+       if (ret) {
+               pr_err("Can't find stm32mp_bsec driver\n");
+               return;
+       }
+
+       for (i = 0; i < STM32_OTP_HASH_KEY_SIZE; i++) {
+               if (print)
+                       printf("Fuse OTP %i : %x\n",
+                              STM32_OTP_HASH_KEY_START + i,
+                              __be32_to_cpu(*(u32 *)addr));
+
+               word = STM32_OTP_HASH_KEY_START + i;
+               val = __be32_to_cpu(*(u32 *)addr);
+               misc_write(dev, STM32_BSEC_OTP(word), &val, 4);
+
+               addr += 4;
+       }
+}
+
+static int confirm_prog(void)
+{
+       puts("Warning: Programming fuses is an irreversible operation!\n"
+                       "         This may brick your system.\n"
+                       "         Use this command only if you are sure of what 
you are doing!\n"
+                       "\nReally perform this fuse programming? <y/N>\n");
+
+       if (confirm_yesno())
+               return 1;
+
+       puts("Fuse programming aborted\n");
+       return 0;
+}
+
+static int do_stm32key(cmd_tbl_t *cmdtp, int flag, int argc,
+                      char * const argv[])
+{
+       u32 addr;
+       const char *op = argc >= 2 ? argv[1] : NULL;
+       int confirmed = argc > 3 && !strcmp(argv[2], "-y");
+
+       argc -= 2 + confirmed;
+       argv += 2 + confirmed;
+
+       if (argc < 1)
+               return CMD_RET_USAGE;
+
+       addr = simple_strtoul(argv[0], NULL, 16);
+       if (!addr)
+               return CMD_RET_USAGE;
+
+       if (!strcmp(op, "read"))
+               read_hash_value(addr);
+
+       if (!strcmp(op, "fuse")) {
+               if (!confirmed && !confirm_prog())
+                       return CMD_RET_FAILURE;
+               fuse_hash_value(addr, !confirmed);
+       }
+
+       return CMD_RET_SUCCESS;
+}
+
+U_BOOT_CMD(stm32key, 4, 1, do_stm32key,
+          "Fuse ST Hash key",
+          "read <addr>: Read the hash store at addr in memory\n"
+          "stm32key fuse [-y] <addr> : Fuse hash store at addr in otp\n");
-- 
2.7.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to