wiki:venice/secure_boot

Version 7 (modified by Tim Harvey, 11 months ago) ( diff )

add wget for grabbing the helper script from attachment and boot consoles for various steps

See also Generic Secure Boot Wiki Page for information on securing the rest of your firmware.

i.MX8M High Assurance Boot (HAB)

The i.MX family of processors provides a High Assurance Boot (HAB) feature in the on-chip BOOT ROM responsible for loading the initial program image from the boot media. HAB enables the BOOT ROM to authenticate and/or decrypt the program image by using crypto operations.

The HABv4 secure boot feature uses digital signatures to prevent unauthorized code execution during the device boot sequence. This authentication is based on public key cryptography using RSA where the firmware image data is signed offline using a private key and the resulting signed image data is verified on the processor using the corresponding public key hash value programmed into the SoC fuses for establishing the root of trust.

See also:

Terminology:

  • CSF: Command Sequence File (generated off-line using the HAB CST)
  • CST: Code-Signing Tool
  • DCD: Device Configuration Data
  • DEK: Data Encryption Key
  • HAB: High Assurance Boot
  • IVT: Image Vector Table
  • SRK: Super Root Key

In order to use High Assurance Boot (HAB) features you must have the NXP Code Signing Tool (CST): https://www.nxp.com/webapp/Download?colCode=IMX_CST_TOOL_NEW

i.MX secure boot SPL (U-Boot v2021-07-venice)

This section is based on the v2021-07-venice Gateworks U-Boot repository - Instructions will differ for other versions of U-Boot

Boards using U-Boot SPL and U-Boot propper for boot firmware support using HABv4 authentication for both images.

The HAB library is a sub-component of the boot ROM on i.MX processors. It is responsible for verifying the digital signatures included as part of the product software and ensures that, when the processor is configured as a secure device, no unauthenticated code is allowed to run.

On an 'open' device you can see HAB events which will tell you if the image would pass the authentication process. This is useful to test before you 'close' the device.

In General you must:

  • Build boot firmware that contains HABv4 support
    • CONFIG_IMX_HAB=y ('hab_auto_img', 'hab_status' and 'hab_version' cmds)
    • CONFIG_CMD_FSL_CAAM_KB=y ('caam genblob' and 'caam decap' cmds)
    • CONFIG_CMD_DEKBLOB=y (optional) ('dek_blob' cmd)
    • CONFIG_OF_LIST=<single target> (at this time only a single board can be supported by the image so replace the list of models in configs/imx8*_venice_defconfig with just the model you want to support)
  • Create a PKI tree and SRK table via the NXP Code Signing Tool
  • Construct boot firmware with a proper Command Sequence File (CSF) (CSF blobs are created with the NXP Code Signing Tool)
  • Blow One Time Programmable (OTP) fuses on the target board with public keys
  • Flash signed firmware
  • Boot and verify no HAB events via 'hab_status' U-Boot command
  • Close the device to force trusted boot

Detailed Procedure (for Venice):

  1. Creation of Code Signing Key:
    1. Retrieve the NXP Code Signing Tool (CST): https://www.nxp.com/webapp/Download?colCode=IMX_CST_TOOL_NEW (Account required on NXP site)
    2. Unpack the CST :
      tar xvf cst-3.3.1.tgz
      cd cst-3.3.1/keys
      
    3. Create a text file named "serial", which contains 8 digits. OpenSSL uses the contents of this file for the 'certificate serial numbers'.
      echo "12345678" > serial
      
    4.  Create a text file named "key_pass.txt which contains your pass phrase that will protect the HAB code signing private keys. The format is the first pass phrase repeated on the first and second lines:
      PASS=mypassphrase
      printf "$PASS\n$PASS" > key_pass.txt
      
    5. Create the signature keys (PKI tree) with hab4_pki_tree.sh (Must do this in the keys dir as the script hard-codes a relative path to certs)
      ./hab4_pki_tree.sh
      ...
      Do you want to use an existing CA key (y/n)?: n
      Do you want to use Elliptic Curve Cryptography (y/n)?: n
      Enter key length in bits for PKI tree: 4096
      Enter PKI tree duration (years): 10
      How many Super Root Keys should be generated? 4
      Do you want the SRK certificates to have the CA flag set? (y/n)?: y
      ...
      
      • this creates the following files which you can archive away as your 'PKI tree':
        ../crts/CA1_sha256_4096_65537_v3_ca_crt.der
        ../crts/CA1_sha256_4096_65537_v3_ca_crt.pem
        ../crts/CSF1_1_sha256_4096_65537_v3_usr_crt.der
        ../crts/CSF1_1_sha256_4096_65537_v3_usr_crt.pem
        ../crts/CSF2_1_sha256_4096_65537_v3_usr_crt.der
        ../crts/CSF2_1_sha256_4096_65537_v3_usr_crt.pem
        ../crts/CSF3_1_sha256_4096_65537_v3_usr_crt.der
        ../crts/CSF3_1_sha256_4096_65537_v3_usr_crt.pem
        ../crts/CSF4_1_sha256_4096_65537_v3_usr_crt.der
        ../crts/CSF4_1_sha256_4096_65537_v3_usr_crt.pem
        ../crts/IMG1_1_sha256_4096_65537_v3_usr_crt.der
        ../crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem
        ../crts/IMG2_1_sha256_4096_65537_v3_usr_crt.der
        ../crts/IMG2_1_sha256_4096_65537_v3_usr_crt.pem
        ../crts/IMG3_1_sha256_4096_65537_v3_usr_crt.der
        ../crts/IMG3_1_sha256_4096_65537_v3_usr_crt.pem
        ../crts/IMG4_1_sha256_4096_65537_v3_usr_crt.der
        ../crts/IMG4_1_sha256_4096_65537_v3_usr_crt.pem
        ../crts/SRK1_sha256_4096_65537_v3_ca_crt.der
        ../crts/SRK1_sha256_4096_65537_v3_ca_crt.pem
        ../crts/SRK2_sha256_4096_65537_v3_ca_crt.der
        ../crts/SRK2_sha256_4096_65537_v3_ca_crt.pem
        ../crts/SRK3_sha256_4096_65537_v3_ca_crt.der
        ../crts/SRK3_sha256_4096_65537_v3_ca_crt.pem
        ../crts/SRK4_sha256_4096_65537_v3_ca_crt.der
        ../crts/SRK4_sha256_4096_65537_v3_ca_crt.pem
        ./CA1_sha256_4096_65537_v3_ca_key.der
        ./CA1_sha256_4096_65537_v3_ca_key.pem
        ./CSF1_1_sha256_4096_65537_v3_usr_key.der
        ./CSF1_1_sha256_4096_65537_v3_usr_key.pem
        ./CSF2_1_sha256_4096_65537_v3_usr_key.der
        ./CSF2_1_sha256_4096_65537_v3_usr_key.pem
        ./CSF3_1_sha256_4096_65537_v3_usr_key.der
        ./CSF3_1_sha256_4096_65537_v3_usr_key.pem
        ./CSF4_1_sha256_4096_65537_v3_usr_key.der
        ./CSF4_1_sha256_4096_65537_v3_usr_key.pem
        ./IMG1_1_sha256_4096_65537_v3_usr_key.der
        ./IMG1_1_sha256_4096_65537_v3_usr_key.pem
        ./IMG2_1_sha256_4096_65537_v3_usr_key.der
        ./IMG2_1_sha256_4096_65537_v3_usr_key.pem
        ./IMG3_1_sha256_4096_65537_v3_usr_key.der
        ./IMG3_1_sha256_4096_65537_v3_usr_key.pem
        ./IMG4_1_sha256_4096_65537_v3_usr_key.der
        ./IMG4_1_sha256_4096_65537_v3_usr_key.pem
        ./SRK1_sha256_4096_65537_v3_ca_key.der
        ./SRK1_sha256_4096_65537_v3_ca_key.pem
        ./SRK2_sha256_4096_65537_v3_ca_key.der
        ./SRK2_sha256_4096_65537_v3_ca_key.pem
        ./SRK3_sha256_4096_65537_v3_ca_key.der
        ./SRK3_sha256_4096_65537_v3_ca_key.pem
        ./SRK4_sha256_4096_65537_v3_ca_key.der
        ./SRK4_sha256_4096_65537_v3_ca_key.pem
        
    6. Create the fuse table and binary (to be programmed to IMX OPT fuse blocks) using the SRK*_ca_crt.pem files created in the crts dir with srktool:
      ../linux64/bin/srktool -h 4 -t SRK_1_2_3_4_table.bin -e SRK_1_2_3_4_fuse.bin -d sha256 -c ./SRK1_sha256_4096_65537_v3_ca_crt.pem,./SRK2_sha256_4096_65537_v3_ca_crt.pem,./SRK3_sha256_4096_65537_v3_ca_crt.pem,./SRK4_sha256_4096_65537_v3_ca_crt.pem -f 1
      
      • creates SRK_1_2_3_4_table.bin SRK_1_2_3_4_fuse.bin and
    7. Use hexdump to obtain the fuse table (8x 32bit fuse values) in the correct endianness for programming with u-boot 'fuse prog':
      $ hexdump -e '/4 "0x"' -e '/4 "%X""\n"' < SRK_1_2_3_4_fuse.bin
      0xDCE644DB
      0x3900ABA
      0x1D00ECF6
      0xC4EE5E23
      0x5BCA8A8
      0x75B0AB86
      0xF88753CC
      0xDB9B5895
      
    • Note the above fuse values will differ per your serial/passphrase
  2. Build U-boot with HABv4 enabled and a single DTB:
    # checkout u-boot
    git clone https://github.com/Gateworks/uboot-venice.git -b v2021.07-venice
    cd u-boot
    # setup cross toolchain environment (ie source setup-environment in Venice BSP dir)
    export PATH=$VENICE_BSP/buildroot/output/host/bin:$PATH
    export CROSS_COMPILE="aarch64-linux-"
    export ARCH=arm64
    export ATF_LOAD_ADDR=0x920000 # IMX8MM
    # configure for venice board
    make imx8mm_venice_defconfig
    make menuconfig # select CONFIG_IMX_HAB=y 'Support i.MX HAB features' and CONFIG_OF_LIST to specify a single board dtb
    make flash.bin
    
    • Use the v2021.07-venice U-Boot branch as this has support for IMX8M HAB
    • Select a single board DTB for CONFIG_OF_LIST
  3. create a signed_flash.bin using the sign_hab_imx8m.sh script
    # setup env to point to the CST
    export CST_DIR=/usr/src/nxp/cst-3.3.1/
    export CST_BIN=$CST_DIR/linux64/bin/cst
    export SIGN_KEY=$CST_DIR/crts/CSF1_1_sha256_4096_65537_v3_usr_crt.pem
    export IMG_KEY=$CST_DIR/crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem
    export SRK_TABLE=$CST_DIR/crts/SRK_1_2_3_4_table.bin
    # sign it
    $ wget http://trac.gateworks.com/raw-attachment/wiki/venice/secure_boot/sign_hab_imx8m.sh 
    $ chmod +x sign_hab_imx8m.sh
    $ ./sign_hab_imx8m.sh 
    Install SRK
    Install CSFK
    Authenticate CSF
    Install key
    Authenticate data
    CSF Processed successfully and signed data available in csf_spl.bin
    Install SRK
    Install CSFK
    Authenticate CSF
    Install key
    Authenticate data
    CSF Processed successfully and signed data available in csf_fit.bin
    6472+0 records in
    6472+0 records out
    6472 bytes (6.5 kB, 6.3 KiB) copied, 0.0102526 s, 631 kB/s
    6488+0 records in
    6488+0 records out
    6488 bytes (6.5 kB, 6.3 KiB) copied, 0.0119102 s, 545 kB/s
    signed_flash.bin is ready!
    # create a JTAG image if needed
    mkimage_jtag --emmc -s signed_flash.bin@user:erase_none:66-32640 > signed_u-boot_spl-imx8mm.bin 
    
    • the script will create csf_spl.txt and csf_fit.txt which are templates used to create csf_spl.bin and csf_fit.bin which are then copied to the correct offsets in flash.bin to create signed_flash.bin
    • on a board without SRK Hash fuses programmed and flashed with this signed image the serial console will look this this:
      U-Boot SPL 2021.07-00087-g54ac394a7c74 (Jun 09 2023 - 14:39:52 -0700)
      GSCv3   : v61 0x1d6f RST:VIN Thermal protection:disabled 
      RTC     : 1970-01-01   0:00:31 UTC
      Model   : GW7301-00-B1B
      Serial  : 852420
      MFGDate : 11-19-2021
      PMIC    : MP5416
      DRAM    : LPDDR4 1 GiB
      WDT:   Started with servicing (60s timeout)
      Trying to boot from MMC1
      DTB     : imx8mm-venice-gw73xx-0x
      hab fuse not enabled
      
      Authenticate image from DDR location 0x401fcdc0...
      NOTICE:  BL31: v2.4(release):f884ad7b0ba2
      NOTICE:  BL31: Built : 13:06:09, Oct 20 2021
      
      
      U-Boot 2021.07-00087-g54ac394a7c74 (Jun 09 2023 - 14:39:52 -0700)
      
      CPU:   Freescale i.MX8MMQ rev1.0 1600 MHz (running at 1200 MHz)
      CPU:   Industrial temperature grade (-40C to 105C) at 34C
      Reset cause: POR
      Model: Gateworks Venice GW73xx-0x i.MX8MM Development Kit
      DRAM:  1 GiB
      WDT:   Started with servicing (60s timeout)
      MMC:   FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
      Loading Environment from MMC... OK
      In:    serial
      Out:   serial
      Err:   serial
      Net:   DP83867 eth0: ethernet@30be0000 [PRIME]
      GSC     : boot watchdog disabled
      Hit any key to stop autoboot:  0 
      u-boot=>  
      
    • Note the 'hab fuse not enabled' and the 'Authenticate image from DDR location' messages
  4. Program SRK Hash fuses from Step 1 into IMX OTP (using U-Boot and the keys from fuse bin)
    fuse prog -y 6 0 0xDCE644DB
    fuse prog -y 6 1 0x3900ABA
    fuse prog -y 6 2 0x1D00ECF6
    fuse prog -y 6 3 0xC4EE5E23
    fuse prog -y 7 0 0x5BCA8A8
    fuse prog -y 7 1 0x75B0AB86
    fuse prog -y 7 2 0xF88753CC
    fuse prog -y 7 3 0xDB9B5895
    
    • Do not use the above fuse values - use values generated above from your serial/passphrase
    • OTP fuses can only be programmed once - be careful to use the correct values
  5. Program signed firmware image:
    jtag_usbv4 -p signed_u-boot_spl-imx8mm.bin
    
  6. Boot it and verify no HAB events:
    u-boot=> hab_status
    Secure boot disabled
    
    HAB Configuration: 0xf0, HAB State: 0x66
    No HAB Events Found!
    

7 Close the device (lock it down!) - this step is irreversible, make sure there are no HAB events from the prior step

u-boot=> fuse prog -y 1 3 0x2000000
  • This sets the SEC_CONFIG[1] fuse on the i.MX8M and once done the processor will not load an image that has not been signed using the correct PKI tree
  • on a board with SRK Hash fuses programmed, SEC_CONFIG[1] set and flashed with a signed image the serial console will look this this:
    U-Boot SPL 2021.07-00087-g54ac394a7c74 (Jun 09 2023 - 14:39:52 -0700)
    GSCv3   : v58 0xf098 RST:VIN Thermal protection:enabled at 96C 
    RTC     : 1970-01-03  16:34:29 UTC
    Model   : GW7301-01-B1B
    Serial  : 852455
    MFGDate : 11-10-2020
    PMIC    : MP5416
    DRAM    : LPDDR4 4 GiB
    WDT:   Started with servicing (60s timeout)
    Trying to boot from MMC1
    DTB     : imx8mm-venice-gw73xx-0x
    
    Authenticate image from DDR location 0x401fcdc0...
    NOTICE:  BL31: v2.4(release):f884ad7b0ba2
    NOTICE:  BL31: Built : 13:06:09, Oct 20 2021
    
    
    U-Boot 2021.07-00087-g54ac394a7c74 (Jun 09 2023 - 14:39:52 -0700)
    
    CPU:   Freescale i.MX8MMQ rev1.0 1600 MHz (running at 1200 MHz)
    CPU:   Industrial temperature grade (-40C to 105C) at 30C
    Reset cause: POR
    Model: Gateworks Venice GW73xx-0x i.MX8MM Development Kit
    DRAM:  4 GiB
    WDT:   Started with servicing (60s timeout)
    MMC:   FSL_SDHC: 0, FSL_SDHC: 1, FSL_SDHC: 2
    Loading Environment from MMC... OK
    In:    serial
    Out:   serial
    Err:   serial
    Net:   DP83867 eth0: ethernet@30be0000 [PRIME]
    GSC     : boot watchdog disabled
    Thermal protection:enabled at 96C 
    Hit any key to stop autoboot:  0 
    
  • Note the 'Authenticate image from DDR location' message

HABv4 encrypted boot architecture

The IMX HABv4 also provides an extra optional security operation by using cryptography (AES-CCM) to obscure the boot image so it can not be seen or used by unauthorized users.

Encrypted boot adds an extra layer of security to the boot sequence using cryptographic techniques to obscure the bootloader data (which can be extended to the entire firmware image)so that it can not be seen or used by unauthorized users. This mechanism protects and conceals the bootloader code residing in flash.

The Data Encryption Key (DEK) is an AES key used to encrypt the boot image (via the Code Signing Tool) and decrypt the boot image (using the DEK blob appended to the image). The DEK blob is used as a security layer to wrap and store the DEK off-chip which is unique to the chip that generated the blob.

Generation of the DEK blob that gets appended to your image must be done on the IMX via the U-Boot dek_blob command which is enabled with CONFIG_CMD_DEKBLOB=y.

References:

Note: See TracWiki for help on using the wiki.