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 16:20:58 CET 2022
Hi,
On 2/14/22 12:14, Patrick DELAUNAY wrote:
> 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
>
>
I will propose a patch to solve this issue soon (in few day).
Regards
Patrick
More information about the U-Boot
mailing list