1. Purpose[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
To write and lock the keys in OTP, you use the command:
stm32key fuse ${loadaddr}
3.5. Verify keys file in OTP[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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[edit | edit source]
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