Requirements

Digi Embedded Yocto uses NXP’s Code Signing Tool (CST) for the High Assurance Boot library when generating secure firmware images. If the tool is not found, the Digi Embedded Yocto TrustFence build fails. Follow these steps to install the CST tool in your workspace:

  1. Download the CST tool from https://www.nxp.com/webapp/Download?colCode=IMX_CST_TOOL.

  2. If you have not used your Digi Embedded Yocto workspace yet, create the downloads folder in the workspace.

  3. Place the tool in the downloads folder of your Digi Embedded Yocto project workspace.

Digi Embedded Yocto will try to use the latest CST that it supports. To check the CST versions supported by Digi Embedded Yocto, run the following command in your DEY project:

~$ bitbake-layers show-recipes trustfence-cst
trustfence-cst:
  meta-digi-arm        3.1.0

To use a different CST version than the latest one supported, see Advanced options.

To add secure boot support to your Digi Embedded Yocto project:

1. Configure secure boot

To build signed and encrypted artifacts, modify your conf/local.conf file to include the following:

conf/local.conf
# Required to include trustfence support.
INHERIT += "trustfence"

Image signing is enabled by default. To explicitly disable the generation of signed images, see Advanced options.

Digi Embedded Yocto generates by default a PKI tree under a new folder called trustfence inside in your project. To specify a custom path for the PKI tree, see Advanced options.

2. Build your target images

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:

  • u-boot-<platform>.bin: These are the default U-Boot images. They are not signed.

  • u-boot-signed-<platform>.bin: These are the signed U-Boot images. Like default U-Boot images, they are 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-<platform>.boot.vfat image containing the following:

    • Image.gz-<platform>.bin: A signed Linux kernel image.

    • DTBs: Signed device tree blob (dtb) files for all hardware platforms.

    • boot.scr: Signed U-Boot bootscript.

    • dey-image-trustfence-initramfs-<platform>.cpio.gz.u-boot.tf: Signed initramfs for rootfs.

  • A dey-image-qt-xwayland-<platform>.recovery.vfat image containing the following:

    • Image.gz-<platform>.bin: A signed Linux kernel image.

    • DTBs: Signed device tree blob (dtb) files for all hardware platforms.

    • boot.scr: Signed U-Boot bootscript.

    • uramdisk-recovery.img: Signed initramfs for recovery.

  • A dey-image-qt-xwayland-<platform>.sdcard microSD card image able to boot the closed device.

    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 PKI tree and the encryption key are also generated (when not provided). They are stored at the specified TRUSTFENCE_SIGN_KEYS_PATH location.

The folder will contain the following:

  • crts/: directory containing the different certificates used for the signature

  • keys/: directory containing the private key associated with each certificate and the passphrase protecting them

The following files need to be securely stored in order to be used in the manufacturing of secure devices:

  • SRK e-fuses public keys hash bin file (SRK_efuses.bin)

  • PKI tree used to sign the firmware images, including the data encryption key in plain text

3. Program the signed U-Boot image

The signed U-Boot images can be flashed like any other U-Boot image:

=> update uboot tftp u-boot-signed-<platform>.bin
Flashing a signed U-Boot does not enable any security features in the target. See Secure the device to learn how to close your device to only boot signed U-Boot images.

Reset the device, and check the result of command trustfence status:

=> reset
(...)
=> trustfence status
* SRK fuses:     [NOT PROGRAMMED]
   Key 0:           [OK]
   Key 1:           [OK]
   Key 2:           [OK]
   Key 3:           [OK]
* Secure boot:     [OPEN]
* AHAB events:     [ERRORS PRESENT!]

The output shows the device has security events. Get more information about the AHAB events with command ahab_status:

=> ahab_status
Lifecycle: 0x0020, NXP closed

SECO Event[0] = 0x0087FA00
        CMD = AHAB_AUTH_CONTAINER_REQ (0x87)
        IND = AHAB_BAD_KEY_HASH_IND (0xFA)

sc_seco_get_event: idx: 1, res:3

For the command field (CMD), the expected value at this step is 0x87 (ID for AHAB_AUTH_CONTAINER_REQ). The indicator field (IND) shows the code AHAB_BAD_KEY_HASH_IND (0xFA) because the key hash verification does not match the current OTPs. Once the OTP SRK hash fuses are programmed on the target OTPs, the AHAB events will no longer have errors.

See the NXP secure boot application notes for more information on event decoding.

4. Secure the device

The final step in configuring secure boot for a device is burning the secure eFuse configuration.

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

To secure the device:

4.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 will allow the ROM loader to validate the public key included in signed firmware images. When building signed U-Boot images, Yocto generates a file named SRK_efuses.bin, which can be used to program the SRK efuses from the U-Boot shell in a safe way following this procedure:

  1. Verify there are no AHAB events (as explained above).

  2. From the U-Boot prompt, load the SRK_efuses.bin file to memory 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)
    Information in the console log may vary.
  3. Program the device using the trustfence prog_srk command:

    => 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 filesize environment variable is automatically calculated from the previous tftp command to be equal to the size (in bytes) of the SRK_efuses.bin file.

To simplify key management, Digi recommends you program all devices with the same set of four keys.

See Revoke a key for steps to take if any of these keys are compromised.

4.2. Close the device

This step is irreversible and could brick your device.

Before closing the device:

  • Verify you have programmed a signed, not encrypted, U-Boot image.

  • Run ahab_status and:

    • Verify there are no AHAB events

    • Verify the SRK eFuses are programmed. 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 AHAB events will stop booting after being closed if the SRK OTP bits are invalid, not burned, or only partially burned.

To close a device, issue Digi’s U-Boot trustfence close command as follows and then reset the target:

=> trustfence close
=> reset

After that, the device will only boot properly signed images.

Advanced options

Use a custom CST version

If you want to use a different CST version than the latest one supported, set the variable PREFERRED_VERSION_trustfence-cst-native in your conf/local.conf:

conf/local.conf
# Use a different CST version
PREFERRED_VERSION_trustfence-cst-native = "x.y.z"

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:

conf/local.conf
# Disable signed images
TRUSTFENCE_SIGN = "0"

Use a custom PKI tree path

You can use the following parameters to customize the location of the sensitive keys:

  • TRUSTFENCE_SIGN_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 automatically generated. The default value is a new folder trustfence in the Digi Embedded Yocto project home location.

conf/local.conf
# Use a custom path to the signature keys and certificates.
TRUSTFENCE_SIGN_KEYS_PATH = "/mnt/secure/PKI_tree"