L-1004e.A1 i.MX 6 / i.MX 8 Security Manual

Table of Contents

L-1004e.A1 i.MX 6 / i.MX 8 Security Manual
Document TitleL-1004e.A1 i.MX 6 / i.MX 8 Mini Security Manual
Article NumberL-1004e.A1
Release Date17.05.2021

Copyrighted products are not explicitly indicated in this manual. The absence of the trademark (TM or ®) and copyright (©) symbols does not imply that a product is not protected. Additionally, registered patents and trademarks are similarly not expressly indicated in this manual.

The information in this document has been carefully checked and is considered to be entirely reliable. However, PHYTEC Messtechnik GmbH assumes no responsibility for any inaccuracies. PHYTEC Messtechnik GmbH neither gives any guarantee nor accepts any liability whatsoever for consequential damages resulting from the use of this manual or its associated product. PHYTEC Messtechnik GmbH reserves the right to alter the information contained herein without prior notification and accepts no responsibility for any damages that might result.

Additionally, PHYTEC Messtechnik GmbH offers no guarantee nor accepts any liability for damages arising from the improper usage or improper installation of the hardware or software. PHYTEC Messtechnik GmbH further reserves the right to alter the layout and/or design of the hardware without prior notification and accepts no liability for doing so.

@ Copyright 2021 PHYTEC Messtechnik GmbH, D-55129 Mainz.

Rights - including those of translation, reprint, broadcast, photomechanical or similar reproduction and storage or processing in computer systems, in whole or in part - are reserved. No reproduction may occur without the express written consent from PHYTEC Messtechnik GmbH.







PHYTEC Messtechnik GmbH
Robert-Koch-Str. 39
D-55129 Mainz

203 Parfitt Way SW
Bainbridge Island, WA 98110

17, place Saint-Etienne
F-72140 Sillé-le-Guillaume

PHYTEC Embedded Pvt. Ltd
No. 1688, 25th A Cross
27th Main, 2nd Sector, Opp. PEP School
V2, HRS Layout
Bangalore 560102

PHYTEC Information Technology (Shenzhen) Co. Ltd.
2106A, Block A, Tianxia Jinniu Square,
Taoyuan Road, Nanshan District,
518052 Shenzhen, Guangdong,

Ordering Information:

+49 6131 9221-32

+1 800 278-9913

+33 2 43 29 22 33

+91-80-4086 7046/48

Technical Support:

+49 6131 9221-31

+1 206 780-9047


+91-80-4086 7047



+49 6131 9221-33

+1 206 780-9135

+33 2 43 29 22 34


Web Site:






With increasing digitization and networking, the protection of embedded systems against unauthorized access and targeted attacks is more important than ever. Guaranteeing this type of security, along with functional security, is a major challenge in electronics design. PHYTEC supports you in minimizing risks by considering security requirements during the development of our hardware and board support packages. On top of these deployment-ready solutions, we support you with individual project consulting on complex security principles.

Security is a process that regards all parts of a device and all development phases of its lifetime.

Compatible Controllers

The following table lists the compatible controller as well as any other necessary information to use this manual.


Please make sure your controller can be found on this table before beginning.

ControllerCompatible BSPExample DistroBootloaderKernel Signing / FIT-ImageFile Encryption SupportKernel Modsign

(based on NXP Vendor BSP)

u-bootKernel and DTB Signing with NXP HAB Keynoyes




(based on NXP Vendor BSP)

u-bootKernel and DTB Signing with NXP HAB Keynoyes
NXP i.MX6UL/ULLBSP-Yocto-i.MX6UL-PD21.1.0

(based on Linux Mainline)

bareboxFIT-Image with separate Keynono
NXP i.MX6BSP-Yocto-i.MX6-PD20.1.0

(based on Linux Mainline)

bareboxFIT-Image with separate Key

with additional Keytype secure


Introduction to Yocto

This document assumes that you are familiar with our Yocto BSPs. The basics of our BSPs are explained in the document Yocto Reference Manual (L-813e_7).

Introduction to the BSP with Security Support

ControllerLink to BSP Manual
i.MX8MMBSP Manual i.MX8MM PD21.1.0
i.MX6ULBSP Manual i.MX6UL PD21.1.0
i.MX6BSP Manual i.MX6 PD20.1.0

Short Crypto Refresher

Symmetric cryptographyThe same key for encryption or decryption
Public key cryptographyTwo mathematically dependent keys for encryption or decryption
HashOne-way function, fixed output size (SHA*)
HMACData authentication using hash and shared secret
SignatureData authentication using public-key cryptography (keys & certificates, RSA & ECDSA)
Unauthenticated encryptionAttackers can‘t read private data but could modify it (AES-CBC, AES-XTS, ...)
Authenticated encryptionAttacker can‘t read private data and modification is detected (AEAD: AES GCM, AEGIS)

Recommended Security Requirements

As of the writing of this manual, recommendations apply for key lengths, certificates, and hash values. These recommendations come from BSI (Bundesamt für Sicherheit in der Informationstechnik) and NIST (National Institute of Standards and Technology).

Distro yogurt-secure and yogurt-vendor-secure

What is Distro yogurt-secure and yogurt-vendor-secure?

Distro yogurt-secure and yogurt-vendor secure are a sample Yocto distro like yogurt with additional security configurations:

  • Activated DISTRO_FEATURE "secureboot" for building signed bootloader and FIT-Image or kernel
  • Image phytec-headless-image is configured for filesystem encryption with FIT-Image, which includes a ramdisk and a boot initialization script.


    This example for filesystem encryption only works with SD card and eMMC, but not with NAND nor NOR Flash.

  • Activated DISTRO_FEATURE protection shield for password protection in bootloader and kernel
  • Enabled Linux kernel module signing, so only modules signed with a specific key can be loaded

Enable yogurt-secure and yogurt-vendor-secure

Change the distro in build/conf/local.conf from yogurt to yogurt-secure or from yogurt-vendor to yogurt-vendor-secure

MACHINE ?= "phyboard-mira-imx6-5"
DISTRO ?= "yogurt-secure"

Secure Boot

Why Secure Boot?

Chain of Trust

Secure boot is used to ensure that only trustworthy, signed software can be executed on the controller. This is the first stage of the Chain-of-Trust. With the Chain-of-Trust, signed programs are always started by other previously verified programs. This ensures that even the end application is at the highest layer of trustworthiness

Process flow i.MX6*:

  • Trusted ROM-bootloader verifies software image before they are executed
  • bootloader verifies Linux-kernel image and device tree (fit-image)
  • Linux-kernel verifies file-system and customer application data

Process flow i.MX8*:

  • The Trusted ROM-bootloader verifies firmware blobs (DDR and HDMI on some variants) and uses HABv4 to verify u-boot SPL.
  • u-boot SPL loads u-boot proper from the FIT image and ATF (ARM Trusted Firmware) and optionally OP-TEE. It verifies those images using HABv4.
  • Then, u-boot loads and verifies the Linux kernel image which has a HABv4 signature for itself and the corresponding DTB.
  • If verification of the kernel image and DTB is successful, u-boot starts the Linux kernel. If built with signed kernel modules (standard), Linux will only load kernel modules signed with a proper private key.

i.MX6 / i.MX6UL / i.MX6ULLi.MX8MM / i.MX8MP
  • Super Root Keys for HABv4
  • FIT-Image Key
  • Super Root Keys for HABv4

Bootloader verified by HABv4

FIT-Image verified by Bootload with FIT-Image Public Key

DDR/HDMI images (signed by NXP)

U-Boot SPL, U-Boot, ATF and Linux+DTB verified by HABv4

Linux kernel modules verified by Linux

Getting Started

NXP Controller

Information about Secure Boot on NXP Controller: https://www.nxp.com/search?keyword=AN4581
HABv4 RVT guidelines and recommendations: https://www.nxp.com/search?keyword=AN12263

  • Code Signing Tools (CST) in version 3.1.0 or newer (install recipes are available in the BSP)
    • Download the cst-3.3.1.tar.gz file
    • Unpack the cst-3.3.1.tar.gz file to cst-3.3.1.tar file.
    • Place the cst-3.3.1.tar file in the yocto download folder

Enable Secure Boot Support in Yocto

Enable Secure Boot in your own distro

To enable secure boot, add the DISTRO_FEATURE "secureboot" to your distro configuration file conf/distro/xyz.conf:

DISTRO_FEATURES += "secureboot"                                                  
DISTRO_FEATURES_NATIVE += "secureboot"                                           

Active image signing during the build process. The class "secureboot" needs to be inherited in your distro configuration:

INHERIT += "secureboot"

Configuration Class-Path to the certificates

The path to the keys and certificates used for code-signing during the build process can be changed in the secureboot.bbclass file:

CERT_PATH ??= "${OEROOT}/../../phytec-dev-ca"

For more information about keys and certificates, refer to Change PKI-Tree from phytec-dev-ca to the own PKI


i.MX6 and i.MX6UL/ULL with Barebox

Standard BootSecure Boot
  • barebox.bin for flash and serial download
  • Signed Barebox for flash: barebox-s.bin
  • USB signed Barebox for serial download: barebox-us.bin
Bootloader Environment
  • loads Environment from flash
  • uses only built-in environment
Bootloader Image Boot
  • loads zImage
  • loads only signed fitImage
  • go command deactivated
SD card image bootloader
  • barebox.bin
  • barebox-s.bin

i.MX8MM and i.MX8MP with u-boot

Standard BootSecure Boot
  • u-boot.bin inside imx-boot container
  • u-boot.bin inside signed imx-boot container
Bootloader Environment
  • load Environment from Flash
  • uses only built-in environment
Bootloader Image Boot
  • loads Image
  • loads Image-signed, containing signatures for kernel and corresponding DTB.
SD card image bootloader
  • u-boot.bin
  • u-boot.bin

Configuration Class - Signing Bootloader

All variables to adjust the bootloader signing process can be found in secureboot.bbclass:

BOOTLOADER_SIGN ??= "true"                                                       
BOOTLOADER_SIGN[type] = "boolean"

BOOTLOADER_SIGN_IMG_PATH ??= "${CERT_PATH}/nxp_habv4_pki/crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem"
BOOTLOADER_SIGN_CSF_PATH ??= "${CERT_PATH}/nxp_habv4_pki/crts/CSF1_1_sha256_4096_65537_v3_usr_crt.pem"
BOOTLOADER_SIGN_SRKFUSE_PATH ??= "${CERT_PATH}/nxp_habv4_pki/crts/SRK_1_2_3_4_table.bin"

BOOTLOADER_SIGN:  enable the bootloader signing
BOOTLOADER_SIGN_IMG_PATH, BOOTLOADER_SIGN_CSF_PATH, BOOTLOADER_SIGN_SRKFUSE_PATH:  paths to the certificates and SRKFUSE-table required to sign the bootloader

Linux Kernel in the FIT-Image for i.MX6 and i.MX6UL/ULL

FIT-Image Generation 

First, add a FIT-Image recipe in your BSP layer. A possible location for this recipe could be recipes-images/fitimage/

You can find two example recipes for Fit-Image generation in the meta-yogurt layer at yocto/source/meta-yogurt/recipes-images/fitimage/.

  • phytec-simple-fitimage.bb:  Example for a FIT-image with kernel and device tree of a selected machine
  • phytec-secureboot-ramdisk-fitimage.bb:  example for a FIT-image with the kernel, device tree of a selected machine, and a ramdisk with file encryption support enabled

To create a fit-image during the build process you need to inherit the Fit-Image class in your build configuration:

INHERIT += "fitimage"
  • To create the manifest file, you may either use the built-in class mechanism or provide a custom manifest.
  • For using the built-in bundle generation, you need to specify some variables:
    • FITIMAGE_SLOTS: Use this to list all slot classes for which the FIT-Image should contain images. A value of "kernel fdt", for example, will create a manifest with images for two slot classes - kernel and devicetree.
    • FITIMAGE_SLOT_<slotclass>: For each slot class, set this to the image (recipe) name which builds the artifact you intend to place in the slot class.
    • FITIMAGE_SLOT_<slotclass>[type]: For each slot class, set this to the type of image you intend to place in this slot. Possible types are:  kernel, fdt, or ramdisk.
    • FITIMAGE_SLOT_<slotclass>[file]: For slot type kernel and fdt, set this to the file of image you intend to place in this slot.
    • FITIMAGE_SLOT_<slotclass>[fstype]: For slot type ramdisk, set this to the filesystem type of image you intend to place in this slot.

Configuration Class - Signing FIT-Image

In the configuration class secureboot.bbclass, you can set all relevant variables for signing the FIT-Image.

FITIMAGE_SIGN ??= "true"                                                         
FITIMAGE_SIGN[type] = "boolean"

FITIMAGE_SIGNER ??= "customer"                                                   

FITIMAGE_SIGN_KEY_PATH ??= "${CERT_PATH}/fit/FIT-4096.key"                   
FITIMAGE_HASH ??= "sha256"                                                   
FITIMAGE_SIGNATURE_ENCRYPTION ??= "rsa4096"                                  
  • FITIMAGE_SIGN: Activation of the FIT-Image signing
  • FITIMAGE_SIGNER: Name of the FIT-Image signer, which is part of the FIT-Image certificate
  • FITIMAGE_PUBKEY_SIGNATURE_PATH: Automatically created manifest with public key of the FITIMAGE_SIGN_KEY_PATH for storing in the bootloader device tree
  • FITIMAGE_SIGN_KEY_PATH: Path to the signing key
  • FITIMAGE_HASH: Hash function for the FIT-Image artifacts. SHA1 and SHA256 are supported
  • FITIMAGE_SIGNATURE_ENCRYPTION: Key type for FIT-Image certificate signing. RSA2048 and RSA4096 are supported
  • FITIMAGE_SIGNER_VERSION: Version of the signer, which is part of the FIT-Image certificate

Start the Build Process

Refer to Start the Build.

The phytec-headless-image has support for FIT-Image creation with an example for file encryption with SD-Card/eMMC only, not for NAND/NOR Flash. The phytec-headless-image includes a FIT-Image with Kernel, devicetree, and ramdisk.

BSP Images

All images generated by Bitbake are deployed to yocto/build/deploy/images/<MACHINE>. The following list shows all additionally generated files for the i.MX 6 SoC, phyboard-mira-imx6-5 machine with activated Secure Boot:

  • Barebox:barebox-s.bin, barebox-us.bin
  • FIT-Image:fitImage.fitimg with kernel, device tree, and ramdisk
  • FIT-Image manifest: phytec-secureboot-ramdisk-fitimage-phyboard-mira-imx6-5.its
  • RAM-disk: phytec-secureboot-ramdisk-image-phyboard-mira-imx6-5.cpio.gz
  • Root filesystem: phytec-headless-image-phyboard-mira-imx6-5.tar.gz
  • SD card image: phytec-headless-image-phyboard-mira-imx6-5.sdcard with barebox-s.bin

Booting and Updating the System

Refer to Introduction to the BSP with Security Support for booting from different flashes and updating the software. Please use the signed bootloader images and Kernel or FIT-Images to program to the flash. The SD card image is ready to use with a signed bootloader.

Activate Secure Boot on the Device

The final step to activate secure boot on your device is to burn the secure eFuse configuration.


The secure eFuse configuration can only be written once and is irreversible!

The SRK fuses contain the hash value of the SRK public keys. In open devices, they are never used. In closed devices, they are used to validate the public key contained in signed firmware images. Before closing the device, you must store the hash of the public keys in the SRK OTP bits on the device. This will allow the ROM loader to validate the public key included in signed firmware images.

When building the yocto-secure distro for the first time, the bootloader image is signed with PHYTEC's development keys. Yocto stores these development keys to yocto/phytec-dev-ca. Please refer to Change PKI-Tree from phytec-dev-ca to the own PKI.

For NXP i.MX Controllers with HABv4 (i.MX6, i.MX7, i.MX8M, i.MX8M mini, i.MX8M Plus), you will need the SRK_1_2_3_4_fuse.bin file. An example file is located in yocto/phytec-dev-ca/nxp_habv4_pki/crts/SRK_1_2_3_4_fuse.bin.


Create and use your own keys and certificates for signing your images. Burn the right key into the Controller eFuse. Please refer Create Your Own PKI Tree.

Program the SRK eFuse

Taski.MX6* with Bareboxi.MX8M* with u-boot

Check the Current State of Your Device
bootloader$ hab -i

You will receive:

Current SRK hash: 
devel mode
u-boot$ hab_status

You will receive:

Secure boot disabled

HAB Configuration: 0xf0, HAB State: 0x66
No HAB Events Found!

Get the eFuse from the right SRK_1_2_3_4_fuse.bin!
bootloader$ cp /mnt/tftp/SRK_1_2_3_4_fuse.bin .
host$ hexdump -e '/4 "0x"' -e '/4 "%X""\n"' SRK_1_2_3_4_fuse.bin

You will receive:


Burn the eFuse with the right SRK_1_2_3_4_fuse.bin!
bootloader$ hab -p -s SRK_1_2_3_4_fuse.bin

You will receive:

ocotp0: reloading shadow registers...
ocotp0: reloading shadow registers...
ocotp0: reloading shadow registers...
ocotp0: reloading shadow registers...
ocotp0: reloading shadow registers...
ocotp0: reloading shadow registers...
ocotp0: reloading shadow registers...
ocotp0: reloading shadow registers...
barebox@PHYTEC phyCORE-i.MX6 Quad with eMMC:/
bootloader$ fuse prog 6 0 0x9A842534
bootloader$ fuse prog 6 1 0xB0491AB4
bootloader$ fuse prog 6 2 0xD5B6A07B
bootloader$ fuse prog 6 3 0xFD92DCE7
bootloader$ fuse prog 7 0 0xC10DC87C
bootloader$ fuse prog 7 1 0xD8BD04A9
bootloader$ fuse prog 7 2 0x704E9FE4
bootloader$ fuse prog 7 3 0x9B025359

Verify new SRK eFuse
bootloader$ hab -i

You will receive:

Current SRK hash: 
devel mode
bootloader$ fuse read 6 0 4

You will receive:

Reading bank 6:

Word 0x00000000: 9a842534 b0491ab4 d5b6a07b fd92dce7
bootloader$ fuse read 7 0 4

You will receive:

Reading bank 7:

Word 0x00000000: c10dc87c d8bd04a9 704e9fe4 9b025359

Lock the device


This step is irreversible and could brick your device.

Before closing the device:

  • Verify you have built a signed bootloader image.
  • Reset your board and verify there are no HAB events.
  • Verify the SRK eFuses have been burned. The SRK OTP bits are not verified on open devices. For a closed device to boot, all the SRK OTP bits must be burned. An open device booting with no HAB events will stop booting after being closed if the SRK OTP bits are invalid, not burned, or only partially burned.

Taski.MX6* with Bareboxi.MX8M* with u-boot

Lockdown your device
bootloader$ hab -p -l

You will receive:

ocotp0: reloading shadow registers...
ocotp0: reloading shadow registers...
Device successfully locked down
bootloader$ fuse prog 1 3 0x2000000

You will receive:

Warning: Programming fuses is an irreversible operation!
         This may brick your system.
         Use this command only if you are sure of what you are doing!

Really perform this fuse programming? <y/N>


If you can successfully reboot after locking the device in the previous step, you should also burn the SRK_LOCK FUSE.


On i.MX6, this step was already performed by the "hab" command of the previous step.

Taski.MX8M* with u-boot

fuse prog 0 0 0x200

You will receive:

Warning: Programming fuses is an irreversible operation!
         This may brick your system.
         Use this command only if you are sure of what you are doing!

Really perform this fuse programming? <y/N>

Next Steps after Lockdown


After you have closed the device, consider the following points with regards to how firmware authentication can potentially be skipped:

  • JTAG could be used to boot the processor and avoid the secure boot. See Secure JTAG
  • Bootloader will drop to a console after an unsuccessful firmware authentication for debugging purposes. That console can still be used to boot, so it should be disabled in production firmware. See Protection Shield Level
  • Direct External Memory Boot could bypass firmware authentication. PHYTEC recommends burning the DIR_BT_DIS fuse on closed devices to prevent this.

Filesystem Encryption (only i.MX6, not i.MX6UL*)

Root filesystem encryption adds another layer of security to your product. It uses the kernel's cryptographic support to encrypt all the data you store in the root filesystem. Attempting to access this data without the correct encryption key returns random, meaningless bytes.


  • yogurt-secure is an example of how encryption on embedded devices works. It uses unauthenticated encryption for a complete partition on SD cards or eMMC. 
  • Encrypting the entire root partition should be considered. However, this can only be done on the device.
  • An integrity check with dm-integrity is a highly recommended addition to the filesystem encryption.
  • Secure Boot must be activated and the device must be locked for proper key-storage. Refer to NXP i.MX CAAM unit for more information
  • Protection Shield Level should be activated.

Boot Process flow:

  • bootloader verifies FIT-Image with linux-kernel image, device tree, and ramdisk before they are executed
  • Linux kernel executes the ramdisk (read-only filesystem)
  • The bootscript loads the encrypted filesystem encryption key with the CAAM unit in the RAM and encrypts the filesystem. After the encryption, the root filesystem will be switched and the boot process continues.

Requirements for Filesystem Encryption

  • File encryption support for block device (SD card, eMMC) or MTD device (NAND, NOR)
  • Master Key Storage to securely store the encryption key

Master Key Storage


The i.MX6 processors include hardware encryption through NXP's Cryptographic Accelerator and Assurance Module (CAAM, also known as SEC4). The CAAM combines functions to create a modular and scalable acceleration and assurance engine.

The kernel 4.19.100 of the BSP includes patches picked from Mailinglist to introduce a new key type, "secure key", into the kernel's keyring. this key type is required to use the NXPs CAAM module for sorting the filesystem encryption key as blob.

More information about the patches can be found here: https://patchwork.kernel.org/project/linux-security-module/list/?submitter=181647)
More information about the CAAM module can be found in the corresponding NXP reference Manual: https://www.nxp.com/docs/en/reference-manual/i.MX_Reference_Manual_Linux.pdf

Additionally, yogurt-secure includes patches to use this new key type directly with dm-crypt.

Refer to Key Generation for Filesystem Encryption for key generation and key storage.

Load an encrypted key

kernel$ keyctl add secure rootfs "load `cat /mnt_secrets/secrets/secure_key.blob`" @u

Starting the Build Process

Filesystem encryption is not included in the DISTRO_FEATURE secureboot. You need to enable it manually.

You will find an example on how to enable filesystem encryption in your distro in meta-yogurt:

  • phytec-secureboot-ramdisk-fitimage
  • phytec-secureboot-ramdisk-image

Filesystem encryption has several dependencies:

DependencyFile ExampleDescriptionDepends OnExample
1Trigger for SD card/eMMC image with file encryption supportrecipes-images/images/security/fileencryption.inc
  • trigger to build FIT-Image with ramdisk for SD-card/eMMC image creation (wic)

2Image for encrypted partitionrecipes-images/images/phytec-headless-image.bb
  • image recipe, which should  encrypt on the target
  • can include a trigger for building the FIT-Image with ramdisk for  SD-card/eMMC image (wic)
  • include security/fileencryption.inc
3FIT-Image with ramdisk for bootrecipes-images/fitimage/phytec-secureboot-ramdisk-fitimage.bb
  • configuration recipe for the FIT-Image with ramdisk

4Ramdisk for encryption handlingrecipes-images/images/phytec-secureboot-ramdisk-image.bb
  • minimal ramdisk with busybox fileencryption support
  • package for fileencryption and init script for fileencryption
  • recipe secureboot-fileencrypt
5Install boot init script and encryption packagesrecipes-core/secureboot/secureboot-fileencrypt.bb
  • include different runtime packages for fileencryption
  • ramdisk init script for encrypt filesystem at boot
  • init script secureboot-fileencrypt.sh

Boot init script for encryption handling on the target

  • boot init script to encrypt and decrypt the filesystem on the target at boot
  • filesystem encryption key, which is stored in the filesystem or secure element like TPM
  • with i.MX CAAM unit encrypted secure_key.blob, which is stored in the first boot partition

Build All Necessary Images and SD card / eMMC Image

host$ bitbake phytec-headless-image

When you change something on the boot init script, then you should clean at least the recipes for ramdisk and FIT-Image, too. If you need a new SD card / eMMC image, then clean the image for encryption partition, too

Setup Root Filesystem Encryption on your Device

The filesystem encryption ensures the target has a unique key or an equal key per device.

The filesystem encryption process flow:

  • The filesystem encryption key is generated and stored encrypted with CAAM.
  • The partition is formatted.
  • Encryption is initialized.
  • Data is copied to the encrypted partition.

1. First Boot of the Device

  1. From a high-level point of view, an eMMC device is like an SD card. Therefore, it is possible to flash the image <name>.sdcard from the Yocto build system directly to the SD card or eMMC. The image contains the signed bootloader, signed FIT-Image, and root filesystem.
  2. Boot the system. At the first boot, the device stops with the following message because there is no encrypted key stored in the folder/secrets:
[ERROR]: No secure_key.blob for Fileencryption in folder /mnt_secrets/secrets

(none) login:

The Protection Shield Level low is in default with user: root and password: root


If there is no login in 60s, then the system fails with Kernel panic.

Login timed out after 60 second[ 402.217501] Kernel panic - not syncing: Attempted to kill init

2. Key Generation for Filesystem Encryption

You can choose between:

  • One individual filesystem encryption key for every device:
kernel$ keyctl add secure rootfs "new 64" @u
  • The same filesystem encryption key for many devices

Create the filesystem encryption key one-time and copy to an external device:

kernel$ cat /dev/hwrng | tr -dc a-f0-9 | head -c${1:-128} > keyfile128


For a 64 bit key, import a 128 bit ASCII key to the kernel keyring.

Import the key to the kernel keyring:

kernel$ keyctl add secure rootfs "load_plain `cat keyfile128`" @u

Both variants can be used with our implementation. The symmetric filesystem encryption key is stored, encrypted with an individual device key in the processor (NXP CAAM unit). The result is named key blob.

The type of key blob created is red. Red key blobs store the encrypted filesystem encryption key for usage at runtime in the RAM. The alternative is the black key blob, which stores the encrypted filesystem encryption key for usage in secure memory. Black key blobs are not supported by the driver at the moment.

  • Show the created or imported filesystem encryption key:
kernel$ keyctl show
Session Keyring
1064738065 --alswrv      0 65534  keyring: _uid_ses.0
 635505777 --alswrv      0 65534   \_ keyring: _uid.0
 347540047 --als-rv      0     0       \_ secure: rootfs

The key type of the filesystem encryption key in the kernel keyring is secure. This is a new key type, which is not part in the mainline kernel at the moment.

  • Key Blob export to the filesystem /mnt_secrets/secrets:
kernel$ mkdir /mnt_secrets/secrets
kernel$ keyctl pipe 347540047 > /mnt_secrets/secrets/secure_key.blob

3. Install Encrypted Filesystem

The file encryption example uses the Linux kernel device-mapper crypto target (dm-crypt).

Please copy the filesystem image, <IMAGENAME>-<MACHINE>.tar.gz, to a USB drive so that it can be installed on the target.

  • Create a mapper /dev/dm-0 for
    • SD card Partition: /dev/mmcblk0p2
    • eMMC Partition: /dev/mmcblk3p2
kernel$ dmsetup create encrootfs --table "0 $(blockdev --getsz  /dev/mmcblk0p2) crypt aes-xts-plain64 :64:secure:rootfs 0 /dev/mmcblk0p2 0"
  • Format the new mapper with ext4 filesystem:
kernel$ mkfs.ext4 /dev/dm-0

You will receive:

mke2fs 1.44.5 (15-Dec-2018)
ext2fs_check_if_mount: Can't check if filesystem is mounted due to missing mtab file while determining whether /dev/dm-0 is mounted.
64-bit filesystem support is not enabled.  The larger fields afforded by this feature enable full-strength checksumming.  Pass -O 64bit to rectify.
Creating filesystem with 230352 1k blocks and 57768 inodes
Filesystem UUID: 90ee890d-b4b4-431c-87de-2adb6bb006ef
Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729, 204801, 221185

Allocating group tables: done
Writing inode tables: done
Creating journal (4096 blocks): done
Writing superblocks and filesystem accounting information: done
  • Mount the formatted mapper:
kernel$ mount /dev/dm-0 /newroot
  • Mount the USB drive with a filesystem image <IMAGENAME>-<MACHINE>.tar.gz:
kernel$ mkdir mnt
kernel$ mount /dev/sda1 /mnt
  • Untar <IMAGENAME>-<MACHINE>.tar.gz rootfs image to it:
kernel$ tar xvfz /mnt/phytec-headless-image-phyboard-mira-imx6-5.tar.gz -C /newroot/
  • Sync the filesystem:
kernel$ sync
  • Unmount the partition:
kernel$ umount /newroot
  • Remove mapper:
kernel$ cryptsetup remove encrootfs
  • If you have a RAUC A/B system, then repeat these instructions for:
    • SD card Partition: /dev/mmcblk0p4
    • eMMC Partition: /dev/mmcblk3p4
  • After the installation, power off the system:
kernel$ poweroff -f
  • Restart the system. After a successful installation, the system will boot to the kernel login console.

Recover a System

If your filesystem is damaged or the secure_key.blob is deleted, then you can reinstall the encrypted filesystem with the following commands.

  • Stop booting in the bootloader.
  • Add Linux bootargs:
bootloader$ global linux.bootargs.rescue="rescue=1"
  • Boot the FIT-Image:
bootloader$ boot

Hint for RAUC Updates

The RAUC handler on the target only backs up and restores the secrets for boot0 partition. 


After the RAUC update, the encrypted filesystem partition is NOT encrypted.

The RAUC handler must be reworked to handle the updates for an encrypted filesystem. Additionally, the data in the RAUC bundles should be encrypted during the transition to the target with a different key.

Protection Shield Level

The DISTRO_FEATURE protection shield offers an easy way to switch between different protection levels. You can use the low protection level during your development and easily switch to a higher level for your final build when entering series production.

Password Protection

The following table shows the different protection shield levels for password protection.

FeatureLevel LowLevel  MediumLevel High
Debug Interface: Password Protection for Bootloader
  • random hash is set
Debug Interface: Password Protection for Kernel Image
  • the PROTECTION_SHIELD_ROOT_PASSWORD is set for user root
  • the PROTECTION_SHIELD_ROOT_PASSWORD is set for user root
  • login for root is disabled

The password protection depends on the quality of the password. The default password for user root is root, which is a very low-quality password.


The variable PROTECTION_SHIELD_ROOT_PASSWORD is stored in your distro configuration file conf/distro/xyz.conf. Do not push this file to the git repository with your actual series password.

Enable Protection Shield Support in Yocto

Enable Protection Shield in Your Own Distro

To enable the protection shield, add the DISTRO_FEATURE protection shield to your distro configuration file conf/distro/xyz.conf. The variables PROTECTION_SHIELD_LEVEL and PROTECTION_SHIELD_ROOT_PASSWORD must be set:

 DISTRO_FEATURES += "protectionshield"                                            
 PROTECTION_SHIELD_LEVEL = "shieldlow"                                            
 #user root password for shield low and midle                                     
 #password quality decide about the protection level                              

Enable Protection Shield Level in Your Kernel Image

To enable protection shield in your Linux kernel image, you need to include security/userauthentication.inc into your image recipe.  For an example, please take a look at recipes-images/images/phytec-headless-image.bb included in yogurt-secure.

If you use a ramdisk for your filesystem, you will need to include security/userauthentication.inc into your ramdisk recipe, too. For an example, please take a look at recipes-images/images/phytec-secureboot-ramdisk-image.bb included in yogurt-secure.

Kernel module signing (i.MX8MM/i.MX8MP)

When the kernel module signing facility is enabled, Linux can enforce that only modules that have been signed with a specific key can be loaded. Keys with invalid signatures won't be allowed to load. This makes it harder for attackers to load malicious or manipulated modules.

This is enforced by the kernel and does not require userland support.

Enable kernel module signing facility

To enable the kernel module signing facility, add the following DISTRO_FEATURE to your configuration file in conf/distro/xyz.conf

 DISTRO_FEATURES += "kernelmodsign"                                            


By default, the kernel modules will be signed with PHYTEC's public, example development key. Unless you create your own key, this feature does not offer any protection.

Additional Device Security Measures

To further protect your device, it is important to reduce attack vectors. Start by securing development features like JTAG and serial downloader.

For activation or deactivation of controller features, is necessary to write and read eFuses.


The secure eFuse configuration can only be written once and is irreversible.

Secure JTAG

Most embedded devices provide a JTAG interface for debugging purposes. However, if left unprotected, this interface can become an important attack vector on the systems in series production. The i.MX6 series System JTAG Controller (SJC) allows you to regulate JTAG access with three security modes using OTP (One Time Programmable) eFuses:

ModeSecurity LevelDescription
EnabledlowThis is the default mode of operation and you have full access to JTAG
Disabled debuggingmediumThis mode disables debugging but leaves the boundary scan functionality enabled.
SecurehighThis mode provides high security. JTAG use is regulated by a 56-bit secret key-based challenge/response authentication mechanism.
Disabled JTAGhighThis mode provides maximum security. All security-sensitive JTAG features are permanently blocked, preventing any debug.

Additional information about JTAG Security can be found here: https://www.nxp.com/docs/en/application-note/AN4686.pdf

Disabled Debugging Mode

Set JTAG to "Disabled debugging" mode:

i.MX6* with bareboxi.MX8M*

bootloader$  mw -l -d /dev/imx-ocotp 0x18 0xC00000
bootloader$ fuse prog 1 3 0xC00000  

Secure JTAG Mode

Set JTAG to "Secure" mode as example for i.MX6/i.MX6UL.

  1. Generate a secret response key

    You can choose between Identical Response Keys on each device or unique response keys for every device

    host$ cat /dev/random | tr -dc a-f0-9 | head -c${1:-14} | sed 's,^\([[:xdigit:]]\{6\}\)\([[:xdigit:]]\{8\}\),0x00\1 0x\2,g'

    You will receive, for example:

    0x00edcba9 0x87654321
  2. Write secret response key:

    i.MX6* with bareboxi.MX8MM

    barebox$  mw -l -d /dev/imx-ocotp 0x80 0x87654321
    barebox$  mw -l -d /dev/imx-ocotp 0x81 0x00edcba9
    bootloader$ fuse prog 8 0 0x87654321
    bootloader$ fuse prog 8 1 0x00edcba9    
  3. Lock access to secret response key:

    i.MX6* with bareboxi.MX8MM

    barebox$ mw -l -d /dev/imx-ocotp 0x00 0x0040
    bootloader$ fuse prog 0 0 0x400
  4. et Secure JTAG mode:

    i.MX6* with bareboxi.MX8MM
    barebox$  mw -l -d /dev/imx-ocotp 0x18 0x400000

    bootloader$ fuse prog 0 0 0x400000

Disabled JTAG Mode

Taski.MX6* with Bareboxi.MX8MM/i.MX8MP Bootloader
Set JTAG to "Disabled" (SJC_DISAB FUSE)
bootloader$  mw -l -d /dev/imx-ocotp 0x18 0x00100000
bootloader$ fuse prog 1 3 0x200000

Disable HAB JTAG Enabling

When JTAG is set in "Secure", an option to enable HAB JTAG DEBUG becomes available. By writing '1' to HAB_JDE (HAB JTAG DEBUG ENABLE) bit in the e-fuse controller module, the JTAG is opened, regardless of its security mode. If this feature is not required, it is highly recommended this be disabled. 

For this, we program the JTAG_HEO FUSE.

Taski.MX6 with Bareboxi.MX8MM/i.MX8MP Bootloader

Prevent HAB from enabling JTAG

bootloader$  mw -l -d /dev/imx-ocotp 0x18 0x08000000

information only available with NXP NDA

Disable Serial Downloader

The i.MX6 Controller supports the burning of different eFuse to disable the USB Serial Download Protocol (SDP) and Force Internal Boot Only to enhance device security.

For more information on i.MX6 controllers, please visit https://community.nxp.com/docs/DOC-334996

Below is a list of PHYTEC Products and variants that include the controller version with the feature for Disable serial downloader and Force Internal Boot:



For phyFLEX-i.MX6 and phyCARD-i.MX6 support, ask your sales contact.

Disable SDP Mode Completely

Disabling the serial download support is recommended for security-enabled configurations:

For i.MX6

bootloader$ mw -l -d /dev/imx-ocotp 0x18 0x0001

For i.MX6UL

bootloader$ mw -l -d /dev/imx-ocotp 0x18 0x20000

For i.MX8M*

bootloader$ fuse prog 2 0 0x200000

Disable Read Access in SDP

Disabling only read access via SDP. Writing will still be possible.

For i.MX6

bootloader$ mw -l -d /dev/imx-ocotp 0x18 0x0004

For i.MX6UL

bootloader$ mw -l -d /dev/imx-ocotp 0x18 0x40000

Force Internal Boot

Ensure the device always boots in INTERNAL BOOT mode, ignoring BOOT_MODE pins. This setting is recommended for security-enabled configurations.

This feature is supported in the listed PHYTEC product versions Disable Serial Downloader.

Taski.MX6* with Bareboxi.MX8MM/i.MX8MP Bootloader

Force internal boot


bootloader$  mw -l -d /dev/imx-ocotp 0x18 0x80000000


bootloader$  mw -l -d /dev/imx-ocotp 0x18 0x10000

For i.MX8M*

bootloader$ fuse prog 2 0 0x100000

Disable boot from external memory

By writing to the DIR_BT_DIS FUSE, we can disable boot from external memory.

Taski.MX6* with Bareboxi.MX8M Bootloader

Disable boot from external memory
bootloader$ mw -l -d /dev/imx-ocotp 0x18 0x0008
bootloader$ fuse prog 1 3 0x8000000

Keys and Certificates

Public Key Infrastructure Tree (PKI tree)

To use secure boot with barebox and kernel image, several keys and certificates are required to sign the images. The key and certificate creation is a manual process and the public key infrastructure (PKI) tree must be in place before you start your build. This BSP includes the phytec development pki-tree as an example. You are obligated to create your own pki-tree with your own keys and certificates.


It is highly recommended to use different keys for different parts of your system to avoid a single point of failure regarding your security concept.

PHYTEC Development Keys (phytec-dev-ca)

The included phytec-dev-ca example consists of a self-signed main-ca and three derived sub-ca's for bootloader, Fit-Image, and RAUC updates.

The recipes for Bootloader, FIT-Image, and RAUC depend on the recipe phytec-dev-ca. If you build the BSP for the first time, the PHYTEC development keys are downloaded in yocto/phytec-dev-ca and used to sign the Bootloader, FIT-Image, and the RAUC bundles.

NameDescriptionKey Type
main-caself-signed Certificate authorityRSA-4096
nxp_habv4_pkimain-ca signed NXP HABv4 Key AuthorityRSA-4096
fitmain-ca signed FIT-Image signing key and certificateRSA-4096
raucown self signed Certificate authority and development key for signing the bundlesRSA-2048
rauc-intermediatemain-ca signed rauc ca (intermediate ca) and rauc ca signed development key for signing the bundlesRSA-2048
kernel-modsignExample key for the Linux kernel module signing facility, independent of CARSA-4096


  • Use the PHYTEC development keys only for the first test.
  • The PHYTEC development keys are not secure!
  • Create and use your own keys and certificates!

NXP HABv4 Key Structure

The NXP HABv4 Key structure is for signing the bootloader, which is verified from the ROM bootloader of the NXP controller with the HABv4 module. The i.MX6, i.MX6UL, i.MX7, i.MX8M, and i.MX8M Mini includes a HABv4 module for secure boot.

  • CA (Certification Authority): This certificate is used to sign the SRK keys and establish the authority of other keys. There is only one CA certificate per PKI tree. This certificate is never used on the target and has no requirements. An existing certificate can be used as CA during the generation of all these keys. The rest of the keys and certificates are always generated and have special requirements, as they are directly used on the target.
  • SRK (Super Root Keys): This certificate is used to sign the CSF and IMG certificates. There are up to four SRK certificates per PKI tree (each one is used to sign one CSF and one IMG certificate). See revoke a key for more information on having multiple SRK certificates.
  • CSF (Command Sequence File): This certificate is used to validate the CSF region.
  • IMG: This certificate is used to validate the bootloader.

Create Your Own PKI Tree

We included a script in meta-yogurt/scripts/ to build your own PKI tree. The script helps you generate a main-ca, bootloader keys, Fit-Image keys, and RAUC keys.


To generate keys and certificates for the bootloader, you will need two scripts from the NXP CST-Tool.

  • Copy st-3.2.0/release/keys/hab4_pki_tree.sh and cst-3.2.0/release/linux64/bin/srktool into the yocto/source/meta-yogurt folder.
  • Check the configuration files for main-ca, Fit-Image, and RAUC in meta-yogurt/scripts/, adjust to your requirements.

1. Create the main-ca

host$ ./scripts/openssl-ca.sh -m

You will receive:

Creation of the Main CA for Bootloader, FIT-Image and
rauc bundle Signning
The Main CA based on RSA4096
No pass phrase for protecting the Main CA private keys
Please put a pass phrase (store it in the key_pass.txt):

2. Create bootloader signing and verification keys and certificate

host$ ./scripts/openssl-ca.sh -b -s

You will receive:

serial: a positive 32-bit number that uniquely identifies
the certificate per certification authority e.g. 12345678 ?08154711

Main ca exist, please use existing CA in SRK creation Tool with
CA key name: /home/user/yocto/sources/meta-yogurt/openssl-ca/main-ca/private/mainca-rsa.key
CA certificate name:  /home/user/yocto/sources/meta-yogurt/openssl-ca/main-ca/mainca-rsa.crt
Do you want start the SRK creation with hab4_pki_tree.sh (y/n)y
the script  hab4_pki_tree.sh is started

Do you want to use an existing CA key (y/n)?:y
Enter CA key name:/home/user/yocto/sources/meta-yogurt/openssl-ca/main-ca/private/mainca-rsa.key
Enter CA certificate name:/home/user/yocto/sources/meta-yogurt/openssl-ca/main-ca/mainca-rsa.crt
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
  • The serial content must be a positive 32-bit number that uniquely identifies the certificate per certification authority.
  • You can use an existing key as CA key by answering the first question with 'y' and then providing the path of the given created main-ca certificate and the key for the certificate to be used as CA.
  • If asked about using ECC cryptography, answer 'n'. The RSA keys are used for the signature.
  • The following key sizes are supported: 1024, 2048, and 4096.
  • The PKI duration is used to compute the expiration date for the certificates.


NXP HABV4 does not take into account the expiration date. A signed bootloader image will remain valid if its certificate has expired.

  • You must generate four keys (for key revocation purposes).
  • The last question regarding the “CA flag” in the SRK must be answered as 'y'

The generated Keys, Certificates (IMG1_1_sha256_4096_65537_v3_usr_crt.pem, CSF1_1_sha256_4096_65537_v3_usr_crt.pem), and SRK_1_2_3_5_fuse.bin are in the folder /home/user/yocto/sources/meta-yogurt/openssl-ca/nxp_habv4_pki/crts/.

3. Create FIT-Image key

host$ ./scripts/openssl-ca.sh -f

You will receive:

Creation of Signing Keys for FIT-Image
Enter key length in bits for PKI tree:4096
  • The following key sizes are supported: 2048 and 4096.

4. Create RAUC keys

host$ ./scripts/openssl-ca.sh -r

You will receive:

Creation of Signing Keys for rauc bundles
Enter key length in bits for rauc PKI tree: 2048
  • The following key sizes are supported: 2048.

5. Create kernel module signing key (i.mx8mm/i.mx8mp)

host$ ./scripts/openssl-ca.sh -K

You will receive:

Generating a 4096 bit RSA private key
writing new private key to 'kernel_modsign.pem'

Change PKI-Tree from phytec-dev-ca to Your Own PKI

In the configuration class yocto/source/meta-yogurt/secureboot.bbclass is the path to your PKI tree initial defined.

CERT_PATH ??= "${OEROOT}/../../phytec-dev-ca"

If you want to change the path, then reinit the CERT_PATH ?= in your layer or overwrite the CERT_PATH in the secureboot.class.

The name of your PKI tree must have a name other then phytec-dev-ca. The recipe for phytec-dev-ca use the name phytec-dev-ca as parameter for the clean command.

After the CERT_PATH has been changed, you must clean and rebuild the bootloader, FIT-Image, RAUC bundles, and the rootfs!

Encryption Keys


Secure other keys:

  • symmetric file encryption key

Unique per device and unreadable.

  • You do not need to do anything about this key.
Filesystem encryption keyEncrypts file system dataEncrypted and stored in the first boot partition.
Secure JTAGProtects JTAG port

Stored in the OTPs of the device. Unreadable when the Secure JTAG configuration is locked.

  • You must securely back up this key.

Revoke a key

Revoke NXP SRK Key

Although securing the device involves programming the hash of four public keys into the eFuses, only one key (number 1 by default) is used in the secure boot process. If the key gets compromised, it can be revoked and a different key used.

To use a different key for the signature of bootloader images, change the following variables in yocto/sources/meta-yogurt/classes/secureboot.bbclass:

BOOTLOADER_SIGN_IMG_PATH ??= "${CERT_PATH}/nxp_habv4_pki/crts/IMG1_1_sha256_4096_65537_v3_usr_crt.pem"
BOOTLOADER_SIGN_CSF_PATH ??= "${CERT_PATH}/nxp_habv4_pki/crts/CSF1_1_sha256_4096_65537_v3_usr_crt.pem"

The following keys are available:

Key SlotIMG CertificateCSF CertificateSRK_REVOKE[2:0]
3IMG4_1_sha256_4096_65537_v3_usr_crt.pemCSF4_1_sha256_4096_65537_v3_usr_crt.pemnot revocable

Exmaple: Revoke Key Slot 0 on i.MX6

mw -l -d /dev/imx-ocotp 0xBC 0x0001

Example: Revoke Key Slot 0 on i.MX8MP and i.MX8MN

fuse prog 9 3 0x1


  • The SRK Revocation does not modify the SRK hash values, only the SRK_REVOKE fuse has to be programmed.
  • In a closed configuration, HAB, by default, sets the SRK_REVOKE_LOCK sticky bit in the OCOTP controller to write protect this eFuse field.
  • To instruct HAB not to lock the SRK_REVOKE field, the CSF commands in the bootloader need to be reconfigured.

For more information, refer to https://www.nxp.com/docs/en/application-note/AN4581.pdf or NXP CST User's Guide.

Revision History

DateVersion NumberChanges to the Manal
11.05.2020L-1004e.A01st Release
19.05.2021L-1004e.A1Information added for:
  • phyCORE-i.MX 6UL
  • phyCORE-i.MX 8M Mini
  • phyCORE-i.MX 8M Plus