Last edited one month ago

How to use U-Boot stm32key command


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.

3. stm32key supported keys[edit | edit source]

List the supported key:

stm32key list

Click on "Expand", visible on the right side of the page, to view List of the keys supported on STM32MP13x lines More info.png :

Click on "Expand", visible on the right side of the page, to view List of the keys supported on STM32MP15x lines More info.png:

Click on "Expand", visible on the right side of the page, to view List of the keys supported on STM32MP21x lines More info.png:

Click on "Expand", visible on the right side of the page, to view List of the keys supported on STM32MP23x lines More info.png and STM32MP25x lines More info.png:

4. Programming procedure[edit | edit source]

Here are the generic steps to program any key supported by the STM32MPU :

1- Select the key to be programmed :

 stm32key select <key name>
 <key name> selected

2- Load the binary file in the DDR : The key file must be available in DDR before proceeding with the stm32key command.

In the next chapters, key file are 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 is in the bootfs on SD™ card (mmc0):

 load mmc 0#bootfs ${loadaddr} <binary file>

3- Verify keys file in DDR :

stm32key read ${loadaddr} 

4- Key provisioning

 stm32key fuse ${loadaddr} 

5- Verify keys in OTP

 stm32key read

5. Examples[edit | edit source]

This section give an example to program the keys used during a secure boot.

5.1. 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.

5.1.1. Select keys[edit | edit source]

Key is selected with the command stm32key select <key>, with <key>=

  • PKHTH for STM32MP13x lines More info.png
 stm32key select PKHTH
 PKHTH selected
  • PKH for STM32MP15x lines More info.png
 stm32key select PKH
 PKH selected
  • OEM-KEY1 for STM32MP2 series
 stm32key select OEM-KEY1
 OEM-KEY1 selected

5.1.2. Load keys file in DDR[edit | edit source]

The keys hash file, output file from STM32 KeyGen, publicKeysHash.bin (for STM32MP15x lines More info.png) or publicKeysHashHashes.bin (for STM32MP13x lines More info.png and STM32MP2 series) is expected to be in the bootfs on SD™ card (mmc0):

 load mmc 0#bootfs ${loadaddr} publicKeysHash.bin

5.1.3. Verify keys file in DDR[edit | edit source]

Once the publicKeysHash.bin (for STM32MP15x lines More info.png) or publicKeysHashHashes.bin (for STM32MP13x lines More info.png) file is loaded in DDR, you can verify the content of the file with the command:

 stm32key read ${loadaddr} 

Example for STM32MP13x lines More info.png 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 More info.png 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 More info.png 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 More info.png and STM32MP25x lines More info.png 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

5.1.4. Key provisioning[edit | edit source]

The following command is used to write and lock the keys in OTP:

 stm32key fuse ${loadaddr} 

5.1.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 More info.png 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 More info.png 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 More info.png 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 More info.png and STM32MP25x lines More info.png 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

5.2. Encryption Key provisioning[edit | edit source]

On STM32MP13x lines More info.png, the EDMK can be used to encrypt the FSBL and the FIP.

On STM32MP2 series, the FSBL and the FIP are encrypted with 2 different keys : the EDMKx and the FIP-EDMK.

This example give the command for EDMK with the file edmk.bin, for the FIP encryption key replace EDMK by EDMK-FIP and edmk.bin by edmk-fip.bin.

5.2.1. Select EDMK[edit | edit source]

Key is selected with the command stm32key select <key>, with <key>=

  • EDMK for STM32MP13x lines More info.png
 stm32key select EDMK
 EDMK selected
  • EDMK1 for STM32MP21x lines More info.png
 stm32key select EDMK1-128b
 EDMK1-128b selected
  • EDMK1 for STM32MP23x lines More info.png or STM32MP25x lines More info.png
 stm32key select EDMK1
 EDMK1 selected

5.2.2. Load EDMK file in DDR[edit | edit source]

The file edmk.bin is expected to be in the bootfs (partition 7) on SD™ card (mmc0):

 load mmc 0#bootfs ${loadaddr}  edmk.bin

5.2.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 More info.png 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 More info.png 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 More info.png and STM32MP25x lines More info.png 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

5.2.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} 

6. 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