This topic contains detailed instructions to set up secure boot in your device:
1. Configure secure boot
To build signed and encrypted artifacts, modify your conf/local.conf file to enable TrustFence:
# Required to include TrustFence support.
INHERIT += "trustfence"
1.1. Encryption of images
Image encryption is enabled by default. To disable image encryption see Advanced options.
1.2. PKI tree
Digi Embedded Yocto generates by default a PKI tree under a new folder called trustfence inside your project.
To specify a custom path for the PKI tree, see Advanced options.
1.3. U-Boot environment encryption
When TrustFence is enabled, the U-Boot environment is encrypted using a random key derived from the chip’s hardware unique key (HUK), only when the device is closed.
To explicitly disable U-Boot environment encryption, see Advanced options.
2. Build your image
Once TrustFence is enabled and configured in your Digi Embedded Yocto project, you can build your target image. For example:
$ bitbake dey-image-qt
When the build process finishes, several secure artifacts appear in the deployment directory:
-
imx-boot-ccimx8mm-dvk.bin: These are the default U-Boot images. They are not signed. -
imx-boot-signed-ccimx8mm-dvk.bin: These are the signed U-Boot images. Like default U-Boot images, they are specific for each variant. -
imx-boot-encrypted-ccimx8mm-dvk.bin: These are signed and encrypted U-Boot images specific for each variant. -
SRK_efuses.bin: This is a file containing the hash of the SRK public keys. It will be required when setting up the device for secure boot. -
A
dey-image-qt-xwayland-ccimx8mm-dvk.boot.vfatimage containing the following:-
Image.gz-ccimx8mm-dvk.bin: Signed and encrypted Linux kernel image. -
.dtbfiles: Signed and encrypted device tree blob files for all hardware platforms. -
boot.scr: Signed and encrypted U-Boot bootscript. -
dey-image-trustfence-initramfs-ccimx8mm-dvk.cpio.gz.u-boot.tf: Signed and encrypted initramfs for rootfs encryption.
-
-
A
dey-image-qt-xwayland-ccimx8mm-dvk.recovery.vfatimage containing the following:-
Image.gz-ccimx8mm-dvk.bin: Signed and encrypted Linux kernel image. -
.dtbfiles: Signed and encrypted device tree blob files for all hardware platforms. -
boot.scr: Signed and encrypted U-Boot bootscript. -
uramdisk-recovery.img: Signed and encrypted initramfs for recovery.
-
-
A
dey-image-qt-xwayland-ccimx8mm-dvk.wic.gzcompressed microSD card image able to boot the closed device once decompressed.If secure boot encryption is enabled, the microSD card image will be able to boot the closed device into U-Boot, but will not boot the OS.
The
dey-image-qt-xwayland-ccimx8mm-dvk.recovery.vfatimage is only used in systems based on single boot and encrypted rootfs.
TrustFence generates keys at the path specified by variable TRUSTFENCE_KEYS_PATH (by default, a subfolder in the project called trustfence/).
For additional details on TrustFence keys, see Summary of TrustFence keys.
| These files need to be securely stored in order to be used in the manufacturing of secure devices. |
3. Provision the keys on the OTP bits
| The secure OTP configuration can only be written once and is irreversible. |
3.1. Program the SRK eFuse
The SRK fuses hold the hash 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 allows the ROM loader to validate the public key included in signed firmware images.
When building images with TrustFence, Digi Embedded Yocto generates a file named SRK_efuses.bin, which you can use to program the SRK efuses.
-
Check the TrustFence status:
=> trustfence status * SRK fuses: [NOT PROGRAMMED] * Secure boot: [OPEN] * Encrypted U-Boot: [NO] * HAB events: [ERRORS PRESENT!]The output shows:
-
The SRK e-fuses are not programmed
-
The device is still in open configuration
-
U-Boot is not encrypted
-
There are HAB errors (expected because, without SRK, no authentication can succeed)
-
-
From the U-Boot prompt, load the
SRK_efuses.binfile to memory, for example using TFTP:=> tftp ${loadaddr} SRK_efuses.bin Using FEC device TFTP from server 192.168.129.10; our IP address is 192.168.42.30 Filename 'deploy/SRK_efuses.bin'. Load address: 0x12000000 Loading: # 15.6 KiB/s done Bytes transferred = 32 (20 hex) -
Dump the contents in memory
=> md.b ${loadaddr} 20 40480000: ae 82 d3 c8 be 53 de c5 27 42 3c 05 44 b2 1f 2b .....S..'B<.D..+ 40480010: 46 26 20 9c 9d 81 64 d6 4a b7 17 ff a9 f6 38 bd F& ...d.J.....8.Information in the console log may vary. -
Verify the hexadecimal values match the contents of the
SRK_efuses.binthat corresponds to the PKI tree you are using to sign the files. Remember to back up this PKI tree to be able to sign future images. -
Program the device using the
trustfence prog_srkcommand:=> trustfence prog_srk ${loadaddr} ${filesize} 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>The filesizeenvironment variable is automatically calculated from the previoustftpcommand to be equal to the size (in bytes) of theSRK_efuses.binfile.
4. Program the signed artifacts
4.1. Program the signed bootloader
|
The build process produces the following bootloader images:
In this step you need to program the signed only bootloader. The signed and encrypted bootloader must not be programmed until the device has been closed in a later step. |
The signed bootloader can be flashed like any other bootloader image:
=> update uboot tftp imx-boot-signed-ccimx8mm-dvk.bin
4.2. Reboot and check the TrustFence status
Reset the device, and check the result of command trustfence status:
=> trustfence status
* SRK fuses: [PROGRAMMED]
Key 0: [OK]
Key 1: [OK]
Key 2: [OK]
Key 3: [OK]
* Secure boot: [OPEN]
* Encrypted U-Boot: [NO]
* HAB events: [NO ERRORS]
The output shows:
-
The SRK e-fuses are programmed
-
All keys are ok (none revoked)
-
The device is still in open configuration
-
U-Boot is not encrypted
-
There are no HAB errors
If secure boot events were present, you can get additional information with the hab_status command to understand why the signature verification failed.
This U-Boot command dumps extra debug information from the High Assurance Boot ROM.
See the NXP secure boot application notes for more information on event decoding.
4.3. Program the signed system images
|
By default, Digi Embedded Yocto produces encrypted artifacts for the ConnectCore 8M Mini. The device won’t be able to decrypt artifacts until the encryption key has been programmed and the device has been closed Skip this paragraph unless you have specifically disabled the artifacts encryption, as described in Disable encryption of images. |
Once you have verified the bootloader authenticates and boots correctly, you can proceed to deploy the rest of artifacts. See Update firmware using system images for reference.
5. Close the device
| This step is irreversible and could brick your device. |
Before closing the device:
-
Verify the SRK e-fuses are programmed.
-
Verify the device boots the signed U-Boot.
-
Verify there are no HAB events.
-
Make sure you can boot the device via Recover your device#,USB recovery.
-
Make sure you have a backup of the generated PKI tree (by default in the
trustfence/folder in your project).
To close a device:
=> trustfence close
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>
Reboot the device. You’ll see an error message when U-Boot tries to read the environment:
Loading Environment from MMC... Decrypting... Error in blob decapsulation: 536873242
Environment is unencrypted!
Resetting to defaults (read-only variables like MAC addresses will be kept).
## Resetting to default environment
The U-Boot environment encryption feature is enabled by default, so U-Boot will import the MAC addresses (and any other write-once environment variables) from the previous (not encrypted) environment, and will reset any other variable to the default values. After that, a save operation will overwrite the environment with encrypted data.
To ensure that both copies of the environment get encrypted, save the environment twice right after booting a closed device that has a U-Boot with environment encryption support, as follows:
=> saveenv
Saving Environment to MMC...
Writing to MMC(0)... done
=> saveenv
Saving Environment to MMC...
Writing to redundant MMC(0)... done
Check the TrustFence status:
=> trustfence status
* SRK fuses: [PROGRAMMED]
Key 0: [OK]
Key 1: [OK]
Key 2: [OK]
Key 3: [OK]
* Secure boot: [CLOSED]
* Encrypted U-Boot: [NO]
* HAB events: [NO ERRORS]
Now your device is closed and it will only boot properly signed images.
6. Program the signed and encrypted system artifacts on a closed device
Once the device has been closed, the encryption uses the unique and secure OTPMK (One Time Programmable Master Key). The update process encrypts the DEK (Data Encryption Key) into an encrypted blob and stores it in the U-Boot partition. This must happen with the unique secure OTPMK, so be sure final programming happens after the device has been closed and restarted.
6.1. Program the encrypted bootloader
There are two ways to flash an encrypted U-Boot image:
Secure a new DEK
Use this method if you are using encrypted images for the first time, or if you want to change the DEK. In this case, you need two input artifacts:
-
The signed and encrypted U-Boot image
-
The data encryption key (DEK) in plain text
To program the signed and encrypted U-Boot image with a new DEK:
=> trustfence update tftp imx-boot-encrypted-ccimx8mm-dvk.bin dek.bin
This programs the U-Boot image and encrypts and stores the DEK in the uboot partition.
|
On an open device, the encryption uses the test master key, while on a closed device the encryption uses the unique and secure OTPMK. For that reason, the final programming of the encrypted U-Boot image must be done after closing the device and resetting. The DEK blob is secured only if a closed device was used. When using an open device, the DEK blob is not secured and both the DEK in plain text and the decrypted U-Boot could be recovered from the media. |
Reuse an existing DEK
Use this method if you are updating a bootloader that’s already encrypted with the same DEK. In this case you don’t need to send the plain text DEK anymore.
To program the signed and encrypted U-Boot image reusing an existing DEK:
=> trustfence update tftp imx-boot-encrypted-ccimx8mm-dvk.bin
The U-Boot image being flashed must have been encrypted with the existing DEK secured in the device. If the device does not have a DEK secured, the command will fail.
| If a different DEK is used, the device will stop booting. |
| When updating to a new U-Boot major version, Digi recommends installing first the signed-only version, rebooting and then installing the encrypted one. |
6.2. Reboot and check the TrustFence status
Reset the device, and check the result of command trustfence status:
=> trustfence status
* SRK fuses: [PROGRAMMED]
Key 0: [OK]
Key 1: [OK]
Key 2: [OK]
Key 3: [OK]
* Secure boot: [CLOSED]
* Encrypted U-Boot: [YES]
* HAB events: [NO ERRORS]
The output shows:
-
The SRK e-fuses are programmed
-
All keys are ok (none revoked)
-
The device is closed
-
U-Boot is encrypted
-
There are no HAB errors
6.3. Program the encrypted system artifacts
The rest of the encrypted system artifacts (Linux kernel, device tree files, boot scripts) can be flashed using standard procedures as long as:
-
You use a closed device.
-
U-Boot has been encrypted with the same key.
To program the linux partition:
=> update linux tftp dey-image-qt-xwayland-ccimx8mm-dvk.boot.vfat
To program the recovery partition:
=> update recovery tftp dey-image-qt-xwayland-ccimx8mm-dvk.recovery.vfat
7. Encrypt the root file system
Root file system encryption adds another layer of security to TrustFence. It uses the kernel’s cryptographic support to encrypt all the data you store in the root file system. Attempting to access this data without the correct encryption key returns random, meaningless bytes.
When you enable TrustFence (see Enable TrustFence support in Digi Embedded Yocto), you automatically enable root file system encryption. This makes it so any SWU packages built with the project enable root file system encryption when installed on a target.
| Digi Embedded Yocto does not encrypt the root file system image at build time. The encryption is carried out on-the-fly during a system update using an SWU package. After the encryption of the rootfs, you must not program the rootfs artifact from U-Boot anymore, or it won’t mount on a fully encrypted system. You need to update the rootfs using an SWU image. |
To explicitly disable root file system encryption, see Advanced options.
7.1. Build an SWU package
-
Create a software update package. To create a software update package, bitbake your image recipe adding the suffix
-swu. For example, if you have built imagedey-image-qtwith rootfs encryption enabled, run the following command to create a software update package:$ bitbake dey-image-qt-swu
7.2. Transfer the SWU image to the device
-
Make sure the resulting software update artifact (
*.swufile) is accessible by the device. For example, you can store it on the internal eMMC, in the update partition:# ls -l /mnt/update/ -rw-r--r-- 1 root root 731810304 Jan 26 18:15 dey-image-qt-swu-ccimx8mm-dvk.swuOr on external media (microSD card, USB disk):
# ls -l /run/media/sda1 -rwxrwx--- 1 root disk 241062400 Jan 18 19:30 dey-image-qt-swu-ccimx8mm-dvk.swu # ls -l /run/media/mmcblk1p1 -rwxrwx--- 1 root disk 241062400 Jan 18 19:30 dey-image-qt-swu-ccimx8mm-dvk.swuThe *.swufile must be stored on the root folder of the partition. Subfolders are not supported.
7.3. Program the encrypted rootfs
-
Run a firmware update with the SWU file:
# update-firmware file://dey-image-qt-swu-ccimx8mm-dvk.swuThe device boots in recovery mode and starts updating the system with the provided package. Once it finishes, the device reboots using the encrypted rootfs.
Advanced options
|
After you have closed the device, consider the following ways to further secure your device:
|
Disable signing of images
Signing of images is automatically enabled as part of TrustFence.
To explicitly disable the generation of signed images, define TRUSTFENCE_SIGN to 0:
# Disable signed images
TRUSTFENCE_SIGN = "0"
This also disables the encryption of images (bootloader, system artifacts).
Disable encryption
Digi Embedded Yocto provides encryption support for the following elements:
-
U-Boot environment
-
Bootloader
-
System artifacts (Linux kernel, device trees, boot scripts).
-
Root file system
When you enable TrustFence, the following encryption is automatically enabled:
-
U-Boot environment
-
Bootloader
-
System artifacts (Linux kernel, device trees, boot scripts).
-
Root file system
The following sections describe how to explicitly disable the encryption of these elements:
Disable U-Boot environment encryption
To explicitly disable U-Boot environment encryption, set:
# Disable U-Boot environment encryption
TRUSTFENCE_ENCRYPT_ENVIRONMENT = "0"
| When flashing U-Boot without the environment encryption feature in a device with an encrypted environment, all the values will be lost. Be sure to save any important data such as MAC addresses before you execute this procedure. |
Disable encryption of images
To disable the encryption of images (bootloader, system artifacts), set:
# Disable encryption of images
TRUSTFENCE_ENCRYPT = "0"
Disable root file system encryption
To explicitly disable root file system encryption, set TRUSTFENCE_ENCRYPT_ROOTFS to 0 as follows:
TRUSTFENCE_ENCRYPT_ROOTFS = "0"
Then, generate an SWU package and install it on the target to disable the rootfs encryption.
Use a custom PKI tree path
You can use the following parameters to customize the location of the sensitive keys:
-
TRUSTFENCE_KEYS_PATH: Path to a folder containing the PKI tree. If the folder does not exist or does not contain a PKI tree, a new PKI tree will be generated automatically. The default value is a new foldertrustfencein the Digi Embedded Yocto project home location.
# Use a custom path to the signature keys and certificates.
TRUSTFENCE_KEYS_PATH = "/home/username/trustfence/mydevice"
-
TRUSTFENCE_DEK_ENCRYPT_KEYNAME: Filename of the Data Encryption Key (DEK). When provided, it must be a 128-, 192- or 256-bit binary file. Otherwise, a random 256-bit key will be generated automatically. The default value isdek.bin.
# Use a custom filename for the Data Encryption Key
TRUSTFENCE_DEK_ENCRYPT_KEYNAME = "my-custom-dek.bin"
Read-only rootfs authentication
You can choose to build a read-only rootfs (see Read-only root file system). When TrustFence is enabled, the resulting rootfs image is signed and the bootloader authenticates it before booting. This guarantees the rootfs comes from a trusted source.