Encrypted boot loader on SabreSD i.MX6q board

Document created by Vitaliy Vasinovich on Apr 18, 2016Last modified by Vitaliy Vasinovich on Apr 25, 2016
Version 9Show Document
  • View in full screen mode

     This documents shows how to secure and encrypt boot loader image for i.MX6 processor. Secure boot is necessary to be sure that CPU is allowed to run genuine and authentic images. Encrypted image secures your intellectual property from theft. Both methods secure/encryption can be extended to cover whole software on board.


Boot loader image encryption is easy to do with CST tools and HAB feature build in Freescale processor. Encrypted image preparation is consist of three parts:

    • Encrypt u-boot.imx plain image by CST utility;
    • Wrap DEK to get DEK blob by specific board;
    • Append DEK blob key to the u-boot image.


In this document as reference board we used SABRESD iMX6q. But it's easily to adjust it for any other board based on i.MX6 CPU with HAB4.1 feature.


Encrypted u-boot image consist of: IVT, DCD, u-boot.bin, CSF, dek_blob.bin. In our example finished u-boot_encrypted.imx image looks like:


Address in file
0x000020DCD + pad to address 0xC00

u-boot.bin + pad to address* 0x7BC000

0x07DBB8CSF bin data + pad to address** 0x07DBB8 + Wrapped DEK (dek_blob.bin)**

* (IVT + DCD + u-boot.bin) has to be padded to align 0x1000.

** (CSF bin data + padding + dek_blob.bin) has to have size 0x2000


Step-by-step instruction:

  1. Clone u-boot git repository.

    $ mkdir ~/imx6encryption

    $ cd ~/imx6encryption

    $ git clone git://git.denx.de/u-boot.git

    $ cd u-boot

    $ git checkout v2016.03 -b tmp

  2. To enable secure features in u-boot modify the following files:
    • Add function usec2ticks to the end of file timer.c.

      $ nano arch/arm/imx-common/timer.c

      unsigned long usec2ticks(unsigned long usec)


              ulong ticks;

              if (usec < 1000)

                      ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000;


                      ticks = ((usec / 10) * (get_tbclk() / 100000));

              return ticks;


      Press Ctrl+X and Y and Enter to save changes.

    • In file mx6q_4x_mt41j128.cfg add string CSF 0x2000 after string BOOT_FROM sd

      $ nano board/freescale/mx6sabresd/mx6q_4x_mt41j128.cfg

      Press Ctrl+X and Y and Enter to save changes.

    • Add defines in file mx6sabresd.h before string #define CONFIG_MACH_TYPE 3980.

      $ nano include/configs/mx6sabresd.h

      #define CONFIG_SECURE_BOOT

      #define CONFIG_SYS_FSL_SEC_COMPAT    4 /* HAB version */

      #define CONFIG_FSL_CAAM

      #define CONFIG_CMD_DEKBLOB

      #define CONFIG_SYS_FSL_SEC_LE

      #define CONFIG_FAT_WRITE

      Press Ctrl+X and Y and Enter to save changes.

    • Delete the following strings:

      gpimage.0 \

      gpimage-common.o \

      omapimage.o \

      in Makefile.

      $ nano tools/Makefile

      Press Ctrl+X and Y and Enter to save changes

  3. Download Linaro GCC compiler.

    $ cd ~/imx6encryption

    $ wget -c https://releases.linaro.org/components/toolchain/binaries/5.3-2016.02/arm-linux-gnueabihf/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf.tar.xz

    $ tar xf gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf.tar.xz

    $ export CC=`pwd`/gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-

    Check compiler version.

    $ ${CC}gcc --version


    arm-linux-gnueabihf-gcc (Linaro GCC 5.3-2016.02) 5.3.1 20160113

    Copyright (C) 2015 Free Software Foundation, Inc.

    This is free software; see the source for copying conditions.  There is NO


  4. Build u-boot image with mx6qsabresd_defconfig.

    $ cd u-boot

    $ make ARCH=arm CROSS_COMPILE=${CC} distclean

    $ make ARCH=arm CROSS_COMPILE=${CC} mx6qsabresd_defconfig

    $ make ARCH=arm CROSS_COMPILE=${CC}

  5. Using mkimage utility build and get information of u-boot.imx image.

    $ ./tools/mkimage -T imximage -n board/freescale/mx6sabresd/mx6q_4x_mt41j128.cfg.cfgtmp -e 0x17800000 -d u-boot.bin u-boot.imx


    Image Type:   Freescale IMX Boot Image

    Image Ver:    2 (i.MX53/6/7 compatible)

    Data Size:    516096 Bytes = 504.00 kB = 0.49 MB

    Load Address: 177ff420

    Entry Point:  17800000

    HAB Blocks:   177ff400 00000000 0007bc00

  6. Register an account on NXP website to have access to download NXP Code Signing Tool for the High Assurance Boot library. Copy downloaded archive into imx6encryption folder.

    $ cd ~/imx6encryption

    $ tar xf cst-2.3.1.tar.gz

    $ cd cst-2.3.1

    $ chmod u+x linux64/* keys/*

  7. Compile back end sources of CST utility

    $ sudo apt-get install libssl-dev

    $ cd ~/imx6encryption/cst-2.3.1/code/back_end/src

    $ gcc -o cst -I ../hdr -L ../../../linux64/lib *.c -lfrontend -lcrypto

    $ mv cst ../../../linux64

  8. Generate keys and certificates which will be used to sign boot loader image.

    $ cd ~/imx6encryption/cst-2.3.1/keys

    • Create file serial.

      $ nano serial

      Enter 8 random digits, for example:


      Press Ctrl+X and Y and Enter to save changes.

    • Create key_pass.txt

      $ nano key_pass.txt

      Enter two lines of identical text:



      Press Ctrl+X and Y and Enter to save changes.

    • Execute hab4_pki_tree.sh.

      $ ./hab4_pki_tree.sh

      Do you want to use an existing CA key (y/n)?: n

      Enter key length in bits for PKI tree: 2048

      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

  9. Generate SRK table.

    $ cd ~/imx6encryption/cst-2.3.1/crts

    $ ../linux64/srktool -h 4 -t SRK_1_2_3_4_table.bin -e SRK_1_2_3_4_fuse.bin -d sha256 -c ./SRK1_sha256_2048_65537_v3_ca_crt.pem,./SRK2_sha256_2048_65537_v3_ca_crt.pem,./SRK3_sha256_2048_65537_v3_ca_crt.pem,./SRK4_sha256_2048_65537_v3_ca_crt.pem -f 1

  10. CST utility requires CSF script. This file describes certificates, keys and the data ranges used in sign and encryption functions. Create u-boot.csf file.

    $ cd ~/imx6encryption/cst-2.3.1/linux64

    $ nano u-boot.csf

    And put the following text:


    Version = 4.1

    Hash Algorithm = SHA256

    Engine Configuration = 0

    Certificate Format = X509

    Signature Format = CMS

    Engine = CAAM


    [Install SRK]

    File = "../crts/SRK_1_2_3_4_table.bin"

    # Index of the key location in the SRK table to be installed

    Source index = 0


    [Install CSFK]

    # Key used to authenticate the CSF data

    File = "../crts/CSF1_1_sha256_2048_65537_v3_usr_crt.pem"


    [Authenticate CSF]



    Engine = CAAM

    Features = RNG


    [Install Key]

    # Key slot index used to authenticate the key to be installed

    Verification Index = 0

    # Key to install

    Target Index = 2

    File = "../crts/IMG1_1_sha256_2048_65537_v3_usr_crt.pem"


    [Authenticate Data]

    # Key slot index used to authenticate the image data

    Verification Index = 2

    #       Address   Offset        Length      Data File Path

    Blocks = 0x177ff400 0x00000000 0x00000C10 "./u-boot.imx"


    #Encrypt the boot image and create a DEK

    [Install Secret Key]

    Verification Index = 0

    Target Index = 0

    Key = "./dek.bin"

    Key Length = 128

    Blob Address = 0x1787CFB8


    #Provide DEK blob location to decrypt

    [Decrypt Data]

    Verification Index = 0

    Mac Bytes = 16

    Blocks = 0x17800010 0x00000C10 0x0007AFF0 "./u-boot.imx"

    Press Ctrl+X and Y and Enter to save changes.


  11. Execute CST utility to encrypt image. Note that after execution u-boot.imx file will be encrypted.

    $ cp ~/imx6encryption/u-boot/u-boot.imx .

    $ ./cst --o u-boot_csf.bin < u-boot.csf

    $ objcopy -I binary -O binary --pad-to=0x1FB8 --gap-fill=0x00 u-boot_csf.bin u-boot_csf.bin

  12. Prepare SD card partition table. Check SD card name in system ($dmesg | tail), for example used /dev/sdb.

    $ echo -e "o""\n""n""\n""p""\n""1""\n""2048""\n""+256M""\n""w" | sudo fdisk /dev/sdb

    $ sudo mkfs.vfat /dev/sdb1

    $ cd ~/imx6encryption/u-boot

    $ sudo dd if=u-boot.imx of=/dev/sdb bs=512 seek=2

    $ sync

  13. Wrap DEK to get DEK blob from i.MX6 CPU. Mount partition 1 and copy dek.bin file to the 1st FAT partition on SD card.

    $ cd ~/imx6encryption/cst-2.3.1/linux64

    $ mkdir /tmp/partition0

    $ sudo mount /dev/sdb1 /tmp/partition0

    $ sudo cp dek.bin /tmp/partition0

    $ sudo umount /tmp/partition0

  14. Insert SD card into the board. And press any key to enter into u-boot prompt. Firstly load dek.bin to the RAM memory. Use dek_blob command to wrap dek.bin. Write file from RAM memory to SD card.

    => fatload mmc 1:1 0x10800000 dek.bin

    => dek_blob 0x10800000 0x10801000 128

    => fatwrite mmc 1:1 0x10801000 dek_blob.bin 0x48

  15. Append DEK blob key to the u-boot image. Mount SD card partition 1 and copy dek_blob.bin file to the linux64 folder.

    $ mkdir -p /tmp/partition0

    $ sudo mount /dev/sdb1 /tmp/partition0

    $ cd /tmp/partition0

    $ cp dek_blob.bin ~/imx6encryption/cst-2.3.1/linux64/

    $ cd ~/imx6encryption/cst-2.3.1/linux64/

    $ sudo umount /tmp/partition0

    $ cat u-boot_csf.bin >> u-boot.imx

    $ cat dek_blob.bin >> u-boot.imx

  16. Install encrypted u-boot.imx into SD card.

    $ sudo dd if=u-boot.imx of=/dev/sdb bs=512 seek=2

    $ sync

  17. Insert SD card into the board. Press any key to enter into u-boot prompt. And check if hab_status command executes without HAB Event errors.

    => hab_status

  18. Attention, OTP fuses can be programmed once, double check everything before burning. If everything is fine, burn required fuses SRK_HASH, SEC_CONFIG as described in AN4581.


As a result we have encrypted boot image which can be loaded and executed by only current board. Because dek_blob.bin is unique per i.MX6 CPU.


Vitaliy Vasinovich

April 2016

9 people found this helpful