[PATCH 6/7] stm32mp: cmd_stm32key: add read OTP subcommand

Hexagon Email Recovery email-recovery2 at hexagon.com
Thu Jul 1 14:56:33 CEST 2021


This message could not be delivered immediately due to an internal mail routing issue.
The mail routing error has been resolved in the meantime.
We apologize for the delay in delivery and any inconvenience this may have caused.
In case of any questions please contact us via it at hexagon.com.

Original sender: patrick.delaunay at foss.st.com
Original delivery time: 28-Jun-2021 01:00 PM (UTC)
-----------------------------------------------------------------------------------------------------------------------
This email is not from Hexagon’s Office 365 instance. Please be careful while clicking links, opening attachments, or replying to this email. Allow to read the OTP value and lock status with the command $> stm32key read. This patch also protects the stm32key fuse command. Signed-off-by: Patrick Delaunay --- arch/arm/mach-stm32mp/cmd_stm32key.c | 93 ++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-stm32mp/cmd_stm32key.c b/arch/arm/mach-stm32mp/cmd_stm32key.c index 886c52794f..8c8d476b65 100644 --- a/arch/arm/mach-stm32mp/cmd_stm32key.c +++ b/arch/arm/mach-stm32mp/cmd_stm32key.c @@ -11,8 +11,13 @@ #include #include -#define STM32_OTP_HASH_KEY_START 24 -#define STM32_OTP_HASH_KEY_SIZE 8 +/* Closed device : bit 6 of OPT0*/ +#define STM32_OTP_CLOSE_ID 0 +#define STM32_OTP_CLOSE_MASK BIT(6) + +/* HASH of key: 8 OTPs, starting with OTP24) */ +#define STM32_OTP_HASH_KEY_START 24 +#define STM32_OTP_HASH_KEY_SIZE 8 static int get_misc_dev(struct udevice **dev) { @@ -29,6 +34,7 @@ static void read_hash_value(u32 addr) { int i; + printf("Read KEY at 0x%x\n", addr); 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)); @@ -36,6 +42,69 @@ static void read_hash_value(u32 addr) } } +static int read_hash_otp(bool print, bool *locked, bool *closed) +{ + struct udevice *dev; + int i, word, ret; + int nb_invalid = 0, nb_zero = 0, nb_lock = 0; + u32 val, lock; + bool status; + + ret = get_misc_dev(&dev); + if (ret) + return ret; + + for (i = 0, word = STM32_OTP_HASH_KEY_START; i < STM32_OTP_HASH_KEY_SIZE; i++, word++) { + ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); + if (ret != 4) + val = ~0x0; + ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); + if (ret != 4) + lock = -1; + if (print) + printf("OTP HASH %i: %x lock : %d\n", word, val, lock); + if (val == ~0x0) + nb_invalid++; + else if (val == 0x0) + nb_zero++; + if (lock == 1) + nb_lock++; + } + + word = STM32_OTP_CLOSE_ID; + ret = misc_read(dev, STM32_BSEC_OTP(word), &val, 4); + if (ret != 4) + val = 0x0; + ret = misc_read(dev, STM32_BSEC_LOCK(word), &lock, 4); + if (ret != 4) + lock = -1; + + status = (val & STM32_OTP_CLOSE_MASK) == STM32_OTP_CLOSE_MASK; + if (closed) + *closed = status; + if (print) + printf("OTP %d: closed status: %d lock : %d\n", word, status, lock); + + status = (nb_lock == STM32_OTP_HASH_KEY_SIZE); + if (locked) + *locked = status; + if (!status && print) + printf("Hash of key is not locked!\n"); + + if (nb_invalid == STM32_OTP_HASH_KEY_SIZE) { + if (print) + printf("Hash of key is invalid!\n"); + return -EINVAL; + } + if (nb_zero == STM32_OTP_HASH_KEY_SIZE) { + if (print) + printf("Hash of key is free!\n"); + return -ENOENT; + } + + return 0; +} + static int fuse_hash_value(u32 addr, bool print) { struct udevice *dev; @@ -88,8 +157,10 @@ static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *con { u32 addr; - if (argc == 1) - return CMD_RET_USAGE; + if (argc == 1) { + read_hash_otp(true, NULL, NULL); + return CMD_RET_SUCCESS; + } addr = simple_strtoul(argv[1], NULL, 16); if (!addr) @@ -103,7 +174,7 @@ static int do_stm32key_read(struct cmd_tbl *cmdtp, int flag, int argc, char *con static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { u32 addr; - bool yes = false; + bool yes = false, lock, closed; if (argc < 2) return CMD_RET_USAGE; @@ -118,6 +189,16 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *con if (!addr) return CMD_RET_USAGE; + if (read_hash_otp(!yes, &lock, &closed) != -ENOENT) { + printf("Error: can't fuse again the OTP\n"); + return CMD_RET_FAILURE; + } + + if (lock || closed) { + printf("Error: invalid OTP configuration (lock=%d, closed=%d)\n", lock, closed); + return CMD_RET_FAILURE; + } + if (!yes && !confirm_prog()) return CMD_RET_FAILURE; @@ -130,7 +211,7 @@ static int do_stm32key_fuse(struct cmd_tbl *cmdtp, int flag, int argc, char *con } static char stm32key_help_text[] = - "read : Read the hash stored at addr in memory\n" + "read []: Read the hash stored at addr in memory or in OTP\n" "stm32key fuse [-y] : Fuse hash stored at addr in OTP\n"; U_BOOT_CMD_WITH_SUBCMDS(stm32key, "Fuse ST Hash key", stm32key_help_text, -- 2.25.1


More information about the U-Boot mailing list