STM32MP: Can't lock PHK fuses through U-Boot cmd's "stm32key" or "fuse"

Patrick DELAUNAY patrick.delaunay at foss.st.com
Mon Feb 14 12:14:44 CET 2022


Hi Johann,

On 2/11/22 15:02, Johann Neuhauser wrote:
> Hello Patrick, Patrice and other devs,
>
> I'm trying to roll out secure boot with U-Boot v2022.01 only.
> The boot flow should be like:
> BootROM -(signed STM32 image)-> U-Boot SPL -(signed fit)-> U-Boot -(signed fit)-> Linux
>
> Everything except the first part in the chain is working as expected.
> I've used the U-Boot cmd "stm32key" to programm the file "publicKeyhash.bin",
> but the command failed with: "Lock OTP 24 failed".
>
> Here are the excact commands with output (hash values are replaced by xxxxxxxx):
> STM32MP> load mmc 0:4 ${loadaddr} publicKeyhash.bin
> STM32MP> stm32key read ${loadaddr}
> Read KEY at 0xc2000000
> OTP value 24: xxxxxxxx
> OTP value 25: xxxxxxxx
> OTP value 26: xxxxxxxx
> OTP value 27: xxxxxxxx
> OTP value 28: xxxxxxxx
> OTP value 29: xxxxxxxx
> OTP value 30: xxxxxxxx
> OTP value 31: xxxxxxxx
> STM32MP> stm32key fuse -y ${loadaddr}
> Lock OTP 24 failed
>
> A second call failed because the word 24 is already fused and not locked!
> STM32MP> stm32key fuse ${loadaddr}
> OTP HASH 24: xxxxxxxx lock : 0
> OTP HASH 25: 0 lock : 0
> OTP HASH 26: 0 lock : 0
> OTP HASH 27: 0 lock : 0
> OTP HASH 28: 0 lock : 0
> OTP HASH 29: 0 lock : 0
> OTP HASH 30: 0 lock : 0
> OTP HASH 31: 0 lock : 0
> OTP 0: closed status: 0 lock : 0
> Hash of key is not locked!
> Error: can't fuse again the OTP
>
> After this failed attempt, I tried to fuse the hash with the command "fuse", like:
> STM32MP> fuse prog -y 0 0x18 0x4e31bbcd
> STM32MP> fuse prog -y 0 0x19 0x51e827dd
> STM32MP> fuse prog -y 0 0x1a 0x3511f521
> STM32MP> fuse prog -y 0 0x1b 0xfd9c11a2
> STM32MP> fuse prog -y 0 0x1c 0x5b997b82
> STM32MP> fuse prog -y 0 0x1d 0x8150adc5
> STM32MP> fuse prog -y 0 0x1e 0xa9c68fa9
> STM32MP> fuse prog -y 0 0x1f 0x72a3ba74
> Which gives me a matching "stm32key read" == "stm32key read ${loadaddr}",
> except that the fuses aren't locked.
>
> If I wanna lock the fuses with, it always fails with "ERROR":
> STM32MP> fuse prog -y 0 0x10000018 1 1 1 1 1 1 1 1
> Programming bank 0 word 0x10000018 to 0x00000001...
> ERROR
>
> According to the reference manual, chapter 4, only writes to the shadow registers aren't allowed!
> Do you have any clue why locking the fuses isn't possilbe either with "stm32key" or with "fuse"?
>
> The next thing is, that I can't authenticate any signed STM32 images with the non locked PHK fuses.
> And no, I haven't closed the device already nor have I locked/fused any other fuses.
> I've implemented a authentication status output inside "arch/arm/mach-stm32mp/spl.c"
> like in TF-A "plat/st/stm32mp1/bl2_plat_setup.c", which I'll probably mainline into U-Boot.
> I'm using a STM32MP157C on a DHCOM with PDK2 from DH electronics GmbH.
>
> Best regards and a nice weekend,
> Johann Neuhauser
>
> DH electronics GmbH | Am Anger 8 | 83346 Bergen | Germany | Fon: +49 8662 4882 0
> Board of Management: Stefan Daxenberger, Helmut Henschke | HRB Traunstein 9602


You correctly use the stm32key or the stm32fuse command

https://wiki.st.com/stm32mpu/wiki/STM32MP15_ROM_code_secure_boot

https://wiki.st.com/stm32mpu/wiki/How_to_update_OTP_with_U-Boot


But in fact the OTP LOCK feature is NOT supported in U-Boot basic boot.


As OpenSTLinux only use boot with TF-A and the OTP operations are managed by

secure service (SMC), all the feature in basic boot with SPL wasn't 
developed

By STMicroelectronics.


Today OTP LOCK feature is a a security to avoid a 2nd write on lower OTP 
which

will cause  an ECC error.

So it wasn't a blocking feature, you can experiment the secure boot chain

without  locking the OTP.


Reference in code : CONFIG_ARM_SMCCC is not activated

arch/arm/mach-stm32mp/bsec.c():: stm32mp_bsec_write_lock()


static int stm32mp_bsec_write_lock(struct udevice *dev, u32 val, u32 otp)
{
     if (!IS_ENABLED(CONFIG_ARM_SMCCC) || IS_ENABLED(CONFIG_SPL_BUILD))
         return -ENOTSUPP;
....

=> without TF-A the lock feature is not (yet ?) supported


reference code in TF-A:

drivers/st/bsec/bsec2.c::bsec_permanent_lock_otp()


Regards

Patrick




More information about the U-Boot mailing list