Secure Boot on STM32MP1
Secure Boot is a key feature towards having a secure platform. The STM32MP1 boot sequence supports a trusted boot chain. This ensures that the loaded images are authenticated and integrity checked before being used.
Our Implementation
The LmP uses U-Boot as the bootloader, with TF-A BL2 as the first stage loader. The Secure Boot implementation puts the IC in a secure state, accepting only signed TF-A BL2 firmware.
Next, TF-A boots the trusted execution environment—OP-TEE—where we run an ‘early’ trusted application: fiovb (Foundries.io Verified Boot). This trusted application provides secure access to the Replay Protected Memory Block partition in eMMC. This is used to store keys, firmware, and rollback information.
OP-TEE also prepares the next stage bootloader—U-Boot—and generates an overlay DTS for Linux® kernel consumption. U-boot also implements the fiovb command to validate the trusted application functionality. U-boot then jumps to the kernel entry point.
Generate RoT ECC key Pair
The first step is generating the ECC key pair and committing the fuse table to the hardware. This can be done with the STM32 KeyGen tool, part of the STM32CubeProgrammer SDK software package.
Note
For development purposes, we keep sample keys and certificates at lmp-tools/security/stm32mp1.
Here is an example of generating a key pair using the KeyGen tool:
$ cd STM32CubeProgrammer
STM32CubeProgrammer$ ./bin/STM32MP_KeyGen_CLI
-------------------------------------------------------------------
STM32MP Key Generator v2.10.0
-------------------------------------------------------------------
STM32AP Key Generator [Version v2.10.0] <'-? for help>
Copyright (c) 2018 STMicroelectronics. All rights reserved.
Please enter Path for output files < /tmp/ >
/tmp/
Please enter Password
Please re-enter your Password
Please select algorithm: 1. prime256v1 2. brainpoolP256t1 (1/2)?
1
Please select encrypting algorithm: 1. aes256 2. aes128 (1/2)?
1
Prime256v1 curve is selected.
AES_256_cbc algorithm is selected for private key encryption
Generating Prime256v1 keys...
Private key PEM file created
Public key PEM file created
public key hash file created
Keys generated successfully.
+ public key: /tmp/publicKey.pem
+ private key: /tmp/privateKey.pem
+ public hash key: /tmp/publicKeyhash.bin
Note
The password for lmp-tools
sample keys is foundries
.
The tool also generates a third file containing the public key hash (PKH) that should be fused to OTP. This is used to authenticate the public key on the target. For more details refer to ST’s STM32 KeyGen tool guide.
How to Secure the Platform (Automatic Approach)
This approach can be used for both STM32MP15 Discovery and the Evaluation kits.
Automatic Signing Using LmP
The FSBL binary (TF-A BL2) must be signed using a key pair generated by STM32MP_KeyGen_CLI
.
There are two possible ways to do this: during LmP build time, or manually, before deploying binaries to a destination board.
In both cases, the STM32 Signing tool needs to be installed.
To enable implicit, automatic signing of boot images during build time, uncomment the following lines in your conf/local.conf:
#
# STM32CubeProgrammer STM32MP Signing Tool configuration
#
STM32_ROT_SIGN_ENABLE ??= "1"
STM32_CUBE_PATH ??= "/usr/local/STMicroelectronics/STM32Cube/STM32CubeProgrammer"
STM32_ROT_KEY_PATH ??= "${TOPDIR}/../tools/lmp-tools/security/stm32mp1/"
STM32_ROT_KEY_PATH[vardepsexclude] += "TOPDIR"
STM32_ROT_KEY_PASSWORD ??= "foundries"
STM32_CUBE_PATH
contains the correct path to STM32Cube installation.STM32_ROT_KEY_PATH
contains the correct path to generated RoT key pair.STM32_ROT_KEY_PASSWORD
contains the correct password to RoT private key.
To sign boot images manually using the STM32 Signing tool, sign each tf-a-*.stm32
image in the flashlayouts-stm32mp1
deploy directory.
Place them alongside the unsigned binaries:
flashlayouts-stm32mp1$ ls -lah
total 558M
drwxr-xr-x 2 user user 4,0K aug 17 12:47 .
drwxr-xr-x 9 user user 12K aug 17 12:48 ..
-rwxr-xr-x 1 user user 28K aug 17 12:47 create_sdcard_from_flashlayout.sh
-rw-r--r-- 1 user user 1,5M aug 17 12:47 fip-stm32mp157c-dk2-optee.bin
-rwxr-xr-x 1 user user 609 aug 17 12:47 FlashLayout_sd_stm32mp157c-dk2-optee.tsv
-rw-r--r-- 1 user user 709M aug 17 12:47 lmp-base-console-image-stm32mp15-disco-sec.ext4
-rw-r--r-- 1 user user 198K aug 17 12:47 tf-a-stm32mp157c-dk2-sdcard_Signed.stm32
-rw-r--r-- 1 user user 198K aug 17 12:47 tf-a-stm32mp157c-dk2-sdcard.stm32
-rw-r--r-- 1 user user 198K aug 17 12:47 tf-a-stm32mp157c-dk2-emmc_Signed.stm32
-rw-r--r-- 1 user user 198K aug 17 12:47 tf-a-stm32mp157c-dk2-emmc.stm32
-rw-r--r-- 1 user user 194K aug 17 12:47 tf-a-stm32mp157c-dk2-uart_Signed.stm32
-rw-r--r-- 1 user user 194K aug 17 12:47 tf-a-stm32mp157c-dk2-uart.stm32
-rw-r--r-- 1 user user 198K aug 17 12:47 tf-a-stm32mp157c-dk2-usb_Signed.stm32
-rw-r--r-- 1 user user 198K aug 17 12:47 tf-a-stm32mp157c-dk2-usb.stm32
Create combo*
images using signed binaries in the deploy directory:
flashlayouts-stm32mp1$ cp tf-a-stm32mp157c-dk2-emmc_Signed.stm32 combo-emmc-tfa-fip-stm32mp157c-ev1.bin
flashlayouts-stm32mp1$ dd if=fip-stm32mp157c-dk2-optee.bin of=combo-emmc-tfa-fip-stm32mp157c-ev1.bin bs=1024 seek=256 conv=notrunc
Adjust the FlashLayout file, so it uses the signed version (s/tf-a-stm32mp157c-ev1-usb.stm32/tf-a-stm32mp157c-ev1-usb_Signed.stm32/g
):
flashlayouts-stm32mp1$ cat FlashLayout_emmc_stm32mp157c-ev1-optee.tsv
#Opt Id Name Type IP Offset Binary
- 0x01 fsbl-boot Binary none 0x0 tf-a-stm32mp157c-ev1-usb_Signed.stm32
- 0x03 fip-boot Binary none 0x0 fip-stm32mp157c-ev1-optee.bin
PD 0x04 fsbl1 Binary mmc1 boot1 combo-emmc-tfa-fip-stm32mp157c-ev1.bin
PD 0x05 fsbl2 Binary mmc1 boot2 combo-emmc-tfa-fip-stm32mp157c-ev1.bin
PED 0x06 u-boot-env Binary mmc1 0x00080000 none
P 0x10 rootfs System mmc1 0x00100000 lmp-base-console-image-stm32mp15-eval.ext4
Provision PKH, HUK and RPMB
The stm32-mfgtool-files
recipe contains the tools needed for provisioning PKH/HUK, and programming the RPMB key on the destination device.
To use, build the lmp-mfgtool
distro:
$ DISTRO=lmp-mfgtool MACHINE=stm32mp15-eval-sec . setup-environment
$ bitbake stm32-mfgtool-files
Warning
If automatic signing is disabled, sign all boot images manually, and copy to the stm32-mfgtool-files
directory before executing provision.sh
.
See the Sign and Deploy the BL2 Image Manually section for a similar approach for flashlayout-stm32mp1
.
Switch to user root
, and add the path to STM32Cube to PATH
:
sudo -s
export PATH=$PATH:<path_to_stm32cube>
Execute script, providing the path to the PKH binary file:
cd deploy/images/stm32mp15-eval-sec
./stm32-mfgtool-files/provision.sh --pub-key-hash <key_dir>/publicKeyhash.bin
ubkey: dab712cd a4b45564 f70a5706 2135e39c 88e89139 0c20219b 93da5419 c65d1fbd
ount: 8
-------------------------------------------------------------------
STM32CubeProgrammer v2.11.0
-------------------------------------------------------------------
...
...
rovision is finished
After execution, the device is provisioned with PKH and HUK values. The RPMB key (relevant only when eMMC-based board is used) is programmed as well.
Flash System Images to SD/eMMC
How to Secure the Platform (Manual Approach)
Fuse PKH Manually
If you need to fuse the public key hash manually, copy it to the first FAT partition of your SD boot card. During the boot process, drop into the U-Boot console and run these commands:
=> mmc rescan
=> STM32MP> fatls mmc 0:4
3007 boot.itb
32 publicKeyhash.bin
=> load mmc 0:4 0xc0000000 publicKeyhash.bin
=> stm32key read 0xc0000000
Read KEY at 0xc0000000
OTP value 24: 1ce94f90
OTP value 25: 971d082f
OTP value 26: d443cf29
OTP value 27: f7c345d4
OTP value 28: 14873635
OTP value 29: b288ad40
OTP value 30: 38841b57
OTP value 31: b7a16954
Warning
Once the fuses have been programmed, they can not be modified.
Verify that stm32key
has printed valid key hashes.
If everything is correct, fuse these values to OTP:
=> stm32key fuse 0xc0000000
The device now contains public key hashes to authenticate boot images.
To validate, read back the OTP, using the same stm32key
command:
=> stm32key read
OTP HASH 24: 1ce94f90 lock : 0
OTP HASH 25: 971d082f lock : 0
OTP HASH 26: d443cf29 lock : 0
OTP HASH 27: f7c345d4 lock : 0
OTP HASH 28: 14873635 lock : 0
OTP HASH 29: b288ad40 lock : 0
OTP HASH 30: 38841b57 lock : 0
OTP HASH 31: b7a16954 lock : 0
OTP 0: closed status: 0 lock : 0
HASK key is not locked!
Sign and Deploy the BL2 Image Manually
STM32 Signing tool allows you to fill the STM32 binary header that is parsed by the embedded software to authenticate each binary.
To sign the image run:
STM32CubeProgrammer$ ./bin/STM32MP_SigningTool_CLI -bin /build-lmp/deploy/images/stm32mp15-disco/arm-trusted-firmware/tf-a-stm32mp157c-dk2-sync -pubk /tmp/publicKey.pem -prvk /tmp/privateKey.pem -iv 5 -pwd qwerty123 -t fsbl
-------------------------------------------------------------------
STM32MP Signing Tool v2.10.0
-------------------------------------------------------------------
Prime256v1 curve is selected.
Header version 1 preparation ...
Reading Private Key File...
ECDSA signature generated.
Signature verification: SUCCESS
The Signed image file generated successfully: /build-lmp/deploy/images/stm32mp15-disco/arm-trusted-firmware/tf-a-stm32mp157c-dk2-sdcard_Signed.stm32
Validate that signature and sign info (algo etc) were added to the image:
STM32CubeProgrammer$ ./bin/STM32MP_SigningTool_CLI -dump /build-lmp/deploy/images/stm32mp15-disco/arm-trusted-firmware/tf-a-stm32mp157c-dk2-sdcard_Signed.stm32
Magic: 0x53544d32
Signature: f1 f7 3e 73 35 38 a5 00 43 b2 78 fe cd 12 0a ec 39 2e 8a c7 60 35 f4 1f 7f 47 1a 99 11 8a 5b 07
9e dc 1c 51 27 bc e2 e0 4c cf 23 6d 87 92 cb c9 a6 ea a1 7f b0 30 18 f4 73 d5 18 ef 50 c6 56 e3
Checksum: 0x6d09b9
Header version: 0x10000
Size: 0x36fd1
Load address: 0x2ffc2500
Entry point: 0x2ffe9000
Image version: 0x5
Option flags: 0x0
ECDSA Algo: 0x1
ECDSA pub key: f9 0e db 1b d6 91 a5 9d 9f d9 0a a8 63 f2 8b 4c ca 37 c6 65 48 e3 5b 5a 69 b8 8f a9 72 b1 3f 44
01 df ae 4c cd 99 12 bc d3 fc 9b 30 7a 77 c5 2b f0 5b 01 f3 2e bb c3 71 db a4 40 93 2c 01 3f a2
Binary type: 0x10
When a WIC image is used for flashing, deploy the signed images to the SD card after flashing the WIC image.
Here the existing unsigned images must be replaced.
This can be achieved with a dd
command as well (instead of mmcblkx specify correct device):
$ sudo dd if=/build-lmp/deploy/images/stm32mp15-disco/arm-trusted-firmware/tf-a-stm32mp157c-dk2-sdcard_Signed.stm32 bs=1024 seek=17 of=/dev/mmcblkx
$ sudo dd if=/build-lmp/deploy/images/stm32mp15-disco/arm-trusted-firmware/tf-a-stm32mp157c-dk2-sdcard_Signed.stm32 bs=1024 seek=273 of=/dev/mmcblkx
Warning
dd
is not needed if the FlashLayout
approach is used.
Booting Signed Images
When a signed binary is used, the BootROM code will authenticate and start the FSBL, which will report authentication status:
NOTICE: CPU: STM32MP157CAC Rev.B
NOTICE: Model: STMicroelectronics STM32MP157C-DK2 Discovery Board
NOTICE: Board: MB1272 Var2.0 Rev.C-01
NOTICE: Bootrom authentication succeeded <------- auth confirmation
A Bootrom authentication succeeded
message means that BootROM managed to authenticate the FSBL image and the device can be closed.
If the device is not closed, it will be still able to perform image authentication.
However,it will boot the image regardless of the result of that authentication.
Closing the Device
As soon as the authentication process is confirmed, the device can be closed and the user must use signed images.
OTP WORD0
bit 6 is the OTP bit that closes the device.
Fusing this bit will lock authentication processing, and force authentication from the BootROM.
Unsigned binaries will no longer be supported on the target.
To close the device by fusing OTP WORD0 bit 6, run the stm32key cmd in U-Boot:
=> stm32key close
See also