Secure Boot Path: From BootROM to Userspace in ZynqMP and i.MX8

Secure Boot Path: From BootROM to Userspace in ZynqMP and i.MX8

πŸ” Introduction

Secure Boot ensures that only authenticated and untampered code runs on a system.
This post walks through the secure boot process from BootROM all the way to Linux userspace, focusing on Xilinx ZynqMP and NXP i.MX8.

We explain how keys are stored and verified, how FIT images are authenticated, and what protections are required even after Linux boots.


πŸ“Š Secure Boot Flow Overview

The diagram below illustrates the secure boot process commonly used in embedded SoCs like Xilinx ZynqMP and NXP i.MX8.
It shows the sequence of boot stages, starting from power-on and proceeding through:

  • BootROM verification of the first-stage bootloader using fused public key hashes
  • U-Boot FIT image authentication using embedded keys
  • Linux Kernel loading with optional integrity tools
  • Transition to userspace, with optional OP-TEE integration for secure operations

This process forms a Chain of Trust, ensuring only signed and authorized software components are executed.


graph TD A["πŸ”Œ Power-on
Reset

"] --> B["πŸ” BootROM
(eFUSE / OCOTP key)

"] B --> C["πŸ“¦ FSBL / SPL
DDR Init
Load U-Boot"] C --> D["🧰 U-Boot
Verify FIT
with public key
"] D --> E["🐧 Linux Kernel
Optional: dm-verity
IMA / EVM"] E --> F["πŸ§‘β€πŸ’» Userspace
Apps
OP-TEE"] style A fill:#f8f9fa,stroke:#333,stroke-width:1px style B fill:#ffe5e5,stroke:#c00,stroke-width:2px style C fill:#f0f0f0,stroke:#666 style D fill:#e3f2fd,stroke:#2196f3 style E fill:#fff3cd,stroke:#ffc107 style F fill:#e8f5e9,stroke:#4caf50

πŸ“ Stage Descriptions

  • πŸ”Œ Power-on / Reset
    The system powers up or resets. The internal BootROM is the first code to execute.

  • πŸ” BootROM (eFUSE / OCOTP keys)
    Verifies the signature of the first-stage bootloader (FSBL/SPL) using SHA hashes of public keys burned into OTP fuses.
    This step is the immutable root of trust.

  • πŸ“¦ FSBL / SPL – DDR Init, Load U-Boot
    Initializes DDR memory and loads the second-stage bootloader (U-Boot) into RAM.

  • 🧰 U-Boot – Verify FIT with embedded public key
    Verifies the authenticity of the kernel, initrd, boot scripts, and device tree from a signed FIT image using public keys embedded in U-Boot DTB.

  • 🐧 Linux Kernel – Optional: dm-verity / IMA / EVM
    The kernel is loaded and started. Optionally, it enforces runtime file integrity using:

    • dm-verity: read-only rootfs block verification
    • IMA: file measurement and audit
    • EVM: protects file metadata
  • πŸ§‘β€πŸ’» Userspace – Applications, OP-TEE integration
    The final stage where user applications, services, and possibly OP-TEE components run.
    Trusted apps (TAs) can safely store and use cryptographic keys inside the TEE.


πŸš€ Stage 1: BootROM – Root of Trust

ZynqMP:

  • Reads BOOT.BIN from SD/eMMC
  • Verifies signature using SHA3-384 hash of up to 4 RSA public keys burned in eFUSE
  • Supports RSA_USE_KEY_SEL for optional key selection

i.MX8:

  • Loads flash.bin with CSF section
  • Uses SRK Table (4 RSA keys) and hashes them into OCOTP
  • Key is selected with SRK_SEL field

❌ Once keys are burned, they cannot be changed.
βœ… If KEY_SEL is not fused, fallback is possible via key rolling.


🧰 Stage 2: U-Boot – FIT Image Authentication

U-Boot verifies the FIT image, which may include:

  • Kernel (Image)
  • DTB (.dtb)
  • RootFS (as initramfs or cpio.gz)
  • Boot script (boot.scr)
  • signature@x node with hash + RSA signature

The public keys used for FIT signature verification are placed in U-Boot’s Device Tree Blob (DTB).

Embedded vs Separated DTB

Mode Config Modifiable in field Security
Embedded DTB CONFIG_OF_EMBED=y ❌ Requires U-Boot rebuild βœ… More secure
Separated DTB (external) CONFIG_OF_SEPARATE=y βœ… Replaceable if not protected ⚠️ Less secure

πŸ“ Stage 3: Kernel and Root Filesystem

Once the kernel boots, it mounts the rootfs.
At this point, Secure Boot no longer enforces integrity, unless you explicitly enable runtime protections:

Option 1: dm-verity

  • Verifies rootfs block-by-block at runtime
  • Requires a signed Merkle tree
  • Read-only FS – great for immutable systems

Option 2: IMA/EVM

  • Signs and verifies individual files
  • More flexible, but requires file-by-file management
  • Works with writable FS

Option 3: OP-TEE

  • Trusted Execution Environment for key handling, crypto
  • Allows userspace apps to securely use hardware-backed secrets
  • Available on i.MX8, not on all ZynqMP versions

πŸ”„ Update Strategy and FIT Impact

FIT image must be re-signed whenever:

  • Kernel is updated
  • Boot script changes
  • RootFS (if included in FIT) is replaced

If only rootfs is updated via SWUpdate, and not loaded from FIT, the FIT itself doesn’t need to change.

Tip: You can split boot and data into two separate FIT images to avoid signing everything each time.


🧠 Summary Table: ZynqMP vs i.MX8

Feature ZynqMP i.MX8
Root Key Storage eFUSE (SHA3-384) OCOTP (SHA256)
Max Keys 4 4 (SRK Table)
Key Selection Optional via bit Optional via SRK_SEL
FIT Auth U-Boot + signed FIT U-Boot + signed FIT
Runtime Protection Manual (dm-verity, IMA) Often with OP-TEE
FS Updates Re-sign or SWUpdate Re-sign or secure loader

βœ… Final Thoughts

Secure Boot doesn’t stop at the bootloader β€” it’s a full chain of trust from BootROM to your application.
Each stage must hand off to the next via signed, verified content, and U-Boot’s FIT signature mechanism plays a central role in ensuring this.

To fully protect your system, consider:

  • Embedding public keys in U-Boot DTB (CONFIG_OF_EMBED)
  • Using dm-verity for rootfs protection
  • Leveraging OP-TEE for sensitive secrets
  • Automating key rolling and dual-slot update flows (A/B)

Need help integrating this with Yocto or adding signed update flows (SWUpdate, RAUC)?
Feel free to reach out β€” I’d be glad to help secure your system end to end.

Comments
comments powered by Disqus