1. Purpose
In this article, the stm32key
U-Boot command is used to illustrate and experiment the steps to provision the keys in the correct OTP needed to activate secure boot features: authentication and encryption.
It also allows setting the device directly to the CLOSED state.
1.1. Prerequisite
All the required keys must be generated to provision the OTP.
The OTP write support must be activated in OP-TEE STM32MP BSEC PTA with CFG_STM32_BSEC_WRITE and the OTPs for these keys must be accessible by non-secure world, see st,non-secure-otp-provisioning in BSEC device configuration of OP-TEE.
In ecosystem release ≤ v4.1.0 , this configuration is activated only in OP-TEE debug release with:
CFG_STM32_BSEC_WRITE ?= $(CFG_TEE_CORE_DEBUG)
The command stm32key is not functional by default with the release version of OP-TEE.
2. stm32key command
U-Boot in OpenSTLinux embeds a stm32key
command that can be called from U-Boot command-line interface to manage the keys in OTPs.
stm32key help
stm32key - Manage key on STM32
Usage:
stm32key list: list the supported key with description
stm32key select [<key>]: Select the key identified by <key> or display the key used for read/fuse command
stm32key read [<addr> | -a ]: Read the curent key at <addr> or current / all (-a) key in OTP
stm32key fuse [-y] <addr>: Fuse the current key at addr in OTP
stm32key close [-y]: Close the device, force use of PKH stored in OTP
The optional option -y
is used to skip the confirmation message.
The name of the used <key> is
stm32key list PKHTH: Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) OTP24..31 EDMK: Encryption/Decryption Master Key" OTP92..95
stm32key list
PKH: Hash of the ECC Public Key (ECDSA is the authentication algorithm)
OTP24..31
- for STM32MP2 series:
- OEM-KEY1 for authentication and EDMK1 for encryption of FSBL-A and of FSBL-M [FSBL-M 1]
- OEM-KEY2 for authentication and EDMK2 for encryption of FSBL-M [FSBL-M 1]
- FIP-EDMK for encryption of the FIP
- ↑ 1.0 1.1 STM32MP2 series can use a dedicated set of keys (OEM-KEY2 and EDMK2) for FSBL-M, indicated by the bit 8 of OTP17 (oem_keys2_enable in BOOTROM_CONFIG_8).
When this bit is 0, FSBL-A and FSBL-M share the same set of keys (OEM-KEY1 and EDMK1)stm32key
automatically fuse this bit after having successfully programmed OEM-KEY2.
stm32key list OEM-KEY1: Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLA or M OTP144..151 OEM-KEY2: Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLM OTP152..159 FIP-EDMK: Encryption/Decryption Master Key for FIP OTP260..267 EDMK2: Encryption/Decryption Master Key for FSBLM OTP360..363 EDMK1: Encryption/Decryption Master Key for FSBLA or M OTP364..367
stm32key list OEM-KEY1 : Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLA or M OTP152..159 OEM-KEY2 : Hash of the 8 ECC Public Keys Hashes Table (ECDSA is the authentication algorithm) for FSBLM OTP160..167 FIP-EDMK : Encryption/Decryption Master Key for FIP OTP260..267 EDMK1-128b : Encryption/Decryption Master 128b Key for FSBLA or M OTP356..359 EDMK1-256b : Encryption/Decryption Master 256b Key for FSBLA or M OTP356..363 EDMK2-128b : Encryption/Decryption Master 128b Key for FSBLM OTP348..351 EDMK2-256b : Encryption/Decryption Master 256b Key for FSBLM OTP348..355
3. Authentication keys provisioning
The key provisioning is the first step to enable the authentication: burn the keys in OTPs with the key hash output file from STM32 KeyGen.
3.1. Select keys
Key is selected with the command stm32key select <key>
, with <key>=
stm32key select PKHTH
PKHTH selected
stm32key select PKH
PKH selected
- OEM-KEY1 for STM32MP2 series
stm32key select OEM-KEY1
OEM-KEY1 selected
3.2. Load keys file in DDR
The keys hash file, output file from STM32 KeyGen, publicKeysHash.bin (for STM32MP15x lines ) or publicKeysHashHashes.bin (for STM32MP13x lines
and STM32MP2 series), must be available in DDR before proceeding with the
stm32key
command.
In the next chapters, this file is assumed to be loaded at ${loadaddr} = 0xc4000000 for STM32MP1 series and ${loadaddr} = 0x84000000 for STM32MP2 series.
For example the file can be loaded from a filesystem partition on a storage device by using the load
command (see documentation), if the file publicKeysHash.bin is in the bootfs (partition 7) on SD™ card (mmc0):
load mmc 0#bootfs ${loadaddr} publicKeysHash.bin
or
load mmc 0:7 0xc4000000 publicKeysHash.bin 32 bytes read in 50 ms (0 Bytes/s)
3.3. Verify keys file in DDR
Once the publicKeysHash.bin (for STM32MP15x lines ) or publicKeysHashHashes.bin (for STM32MP13x lines
) file is loaded in DDR, you can verify the content of the file with the command:
stm32key read ${loadaddr}
Example for STM32MP13x lines with PKHTH
stm32key read ${loadaddr}
Read PKHTH at 0xc4000000
PKHTH OTP 24: [c4000000] 27051956
PKHTH OTP 25: [c4000004] b56aef2d
PKHTH OTP 26: [c4000008] 6215263c
PKHTH OTP 27: [c400000c] 00000439
PKHTH OTP 28: [c4000010] 00000000
PKHTH OTP 29: [c4000014] 00000000
PKHTH OTP 30: [c4000018] 72429173
PKHTH OTP 31: [c400001c] 05020600
Example for STM32MP15x lines with PKH
stm32key read ${loadaddr}
Read PKH at 0xc4000000
PKH OTP 24: [c4000000] 27051956
PKH OTP 25: [c4000004] b56aef2d
PKH OTP 26: [c4000008] 6215263c
PKH OTP 27: [c400000c] 00000439
PKH OTP 28: [c4000010] 00000000
PKH OTP 29: [c4000014] 00000000
PKH OTP 30: [c4000018] 72429173
PKH OTP 31: [c400001c] 05020600
Example for STM32MP21x lines with OEM-KEY1
stm32key read ${loadaddr}
Read OEM-KEY1 at 0x84000000
OEM-KEY1 OTP 152: [84000000] f96e3aeb
OEM-KEY1 OTP 153: [84000004] 5c92b5ac
OEM-KEY1 OTP 154: [84000008] 0abdde9e
OEM-KEY1 OTP 155: [8400000c] bb50fdb4
OEM-KEY1 OTP 156: [84000010] 18ea200a
OEM-KEY1 OTP 157: [84000014] 85658efa
OEM-KEY1 OTP 158: [84000018] 4101b7b7
OEM-KEY1 OTP 159: [8400001c] ececbc99
Example for STM32MP23x lines and STM32MP25x lines
with OEM-KEY1
stm32key read ${loadaddr}
Read OEM-KEY1 at 0x84000000
OEM-KEY1 OTP 144: [84000000] 27051956
OEM-KEY1 OTP 145: [84000004] b56aef2d
OEM-KEY1 OTP 146: [84000008] 6215263c
OEM-KEY1 OTP 147: [8400000c] 00000439
OEM-KEY1 OTP 148: [84000010] 00000000
OEM-KEY1 OTP 149: [84000014] 00000000
OEM-KEY1 OTP 150: [84000018] 72429173
OEM-KEY1 OTP 151: [8400001c] 05020600
3.4. Key provisioning
To write and lock the keys in OTP, you use the command:
stm32key fuse ${loadaddr}
3.5. Verify keys file in OTP
After the previous command, the device contains the keys to authenticate images and it can be verified with the command:
stm32key read
Result for STM32MP13x lines with PKHTH
stm32key read PKHTH OTP 24: 27051956 lock : 50000000 PKHTH OTP 25: b56aef2d lock : 50000000 PKHTH OTP 26: 6215263c lock : 50000000 PKHTH OTP 27: 00000439 lock : 50000000 PKHTH OTP 28: 00000000 lock : 50000000 PKHTH OTP 29: 00000000 lock : 50000000 PKHTH OTP 30: 72429173 lock : 50000000 PKHTH OTP 31: 05020600 lock : 50000000
Result for STM32MP15x lines with PKH
stm32key read PKH OTP 24: 27051956 lock : 50000000 PKH OTP 25: b56aef2d lock : 50000000 PKH OTP 26: 6215263c lock : 50000000 PKH OTP 27: 00000439 lock : 50000000 PKH OTP 28: 00000000 lock : 50000000 PKH OTP 29: 00000000 lock : 50000000 PKH OTP 30: 72429173 lock : 50000000 PKH OTP 31: 05020600 lock : 50000000
Example for STM32MP21x lines with OEM-KEY1
stm32key read OEM-KEY1 OTP 152: 27051956 lock : 40000000 OEM-KEY1 OTP 153: b56aef2d lock : 40000000 OEM-KEY1 OTP 154: 6215263c lock : 40000000 OEM-KEY1 OTP 155: 00000439 lock : 40000000 OEM-KEY1 OTP 156: 00000000 lock : 40000000 OEM-KEY1 OTP 157: 00000000 lock : 40000000 OEM-KEY1 OTP 158: 72429173 lock : 40000000 OEM-KEY1 OTP 159: 05020600 lock : 40000000
Example for STM32MP23x lines and STM32MP25x lines
with OEM-KEY1
stm32key read OEM-KEY1 OTP 144: 27051956 lock : 40000000 OEM-KEY1 OTP 145: b56aef2d lock : 40000000 OEM-KEY1 OTP 146: 6215263c lock : 40000000 OEM-KEY1 OTP 147: 00000439 lock : 40000000 OEM-KEY1 OTP 148: 00000000 lock : 40000000 OEM-KEY1 OTP 149: 00000000 lock : 40000000 OEM-KEY1 OTP 150: 72429173 lock : 40000000 OEM-KEY1 OTP 151: 05020600 lock : 40000000
4. Encryption Decryption Master Key provisioning
The EDMK key provisioning is the first step to enable the image decryption.
It is only available on STM32MP13x lines and STM32MP2 series.
4.1. Select EDMK
Key is selected with the command stm32key select <key>
, with <key>=
stm32key select EDMK
EDMK selected
- EDMK1 for STM32MP2 series
stm32key select EDMK1
EDMK1 selected
4.2. Load EDMK file in DDR
The keys file must be available in DDR before proceeding the stm32key
command.
In the next chapters, this file is assumed to be loaded at ${loadaddr} = 0xc4000000 for STM32MP1 series and ${loadaddr} = 0x84000000 for STM32MP2 series.
The file edmk.bin can be loaded from a filesystem partition on a storage device by using the load
command (see documentation).
For example, the file edmk.bin is in the bootfs (partition 7) on SD™ card (mmc0):
load mmc 0#bootfs ${loadaddr} edmk.bin
4.3. Verify EDMK in DDR
Then you can verify the content of keys files loaded in DDR with the command: stm32key read <addr>
Example for STM32MP13x lines with EDMK
stm32key read ${loadaddr}
Read EDMK at 0xc4000000
EDMK OTP 92: [c4000000] 27051956
EDMK OTP 93: [c4000004] b56aef2d
EDMK OTP 94: [c4000008] 6215263c
EDMK OTP 95: [c400000c] 00000439
Example for STM32MP21x lines with EDMK1-128b
stm32key read ${loadaddr}
Read EDMK at 0xc4000000
EDMK1-128b OTP 356: [84000000] 27051956
EDMK1-128b OTP 357: [84000004] b56aef2d
EDMK1-128b OTP 358: [84000008] 6215263c
EDMK1-128b OTP 359: [8400000c] 00000439
Example for STM32MP23x lines and STM32MP25x lines
with EDMK1
stm32key read ${loadaddr}
Read EDMK at 0xc4000000
EDMK1 OTP 364: [84000000] 27051956
EDMK1 OTP 365: [84000004] b56aef2d
EDMK1 OTP 366: [84000008] 6215263c
EDMK1 OTP 367: [8400000c] 00000439
4.4. EDMK provisioning
To write and lock the EDMK in OTP, you use the command with the same address:
stm32key fuse ${loadaddr}
4.5. Verify EDMK in OTP
After the previous command, the device contains the keys to decrypt the images and it can be verified with the command:
stm32key read
Result for STM32MP13x lines with EDMK
stm32key read EDMK OTP 92: 00000000 lock : 50000000 EDMK OTP 93: 00000000 lock : 50000000 EDMK OTP 94: 00000000 lock : 50000000 EDMK OTP 95: 00000000 lock : 50000000
Result for STM32MP21x lines with EDMK1-128b
stm32key read EDMK1 OTP 356: 00000000 lock : 30000000 EDMK1 OTP 357: 00000000 lock : 30000000 EDMK1 OTP 358: 00000000 lock : 30000000 EDMK1 OTP 359: 00000000 lock : 30000000
Result for STM32MP23x lines or STM32MP25x lines
with EDMK1
stm32key read EDMK1 OTP 364: 00000000 lock : 30000000 EDMK1 OTP 365: 00000000 lock : 30000000 EDMK1 OTP 366: 00000000 lock : 30000000 EDMK1 OTP 367: 00000000 lock : 30000000
5. Closing the device
Once the authentication process is confirmed in ROM code and in TF-A, the device can be closed to ensure that only signed images can be used.
This operation is performed with the U-Boot command:
stm32key close