Skip to content

Secure Boot & Verified Boot

TL;DR

Secure boot ensures each stage verifies the cryptographic signature of the next before execution: PBL → XBL → UEFI/ABL → TZ → kernel. Verified boot (AVB) extends this to OS partitions via vbmeta descriptors and dm-verity hash trees on read-only filesystems. Rollback protection (anti-rollback fuses + metadata version counters) prevents downgrading to patched vulnerabilities. On verification failure, the bootloader refuses to boot, falls back to the other A/B slot, or drops to fastboot/recovery/EDL. It never silently runs tampered code. Your unsigned boot.img fastboot flash failing with SECURE BOOT ENABLE is the chain working, not the tool breaking.

Every flash tool hits a wall eventually: the signature check. This page explains the wall, what’s being verified, by whom, and what the device does when you lose.

Common Gotcha

Flashing a userdebug build’s boot.img onto a production-fused board with fastboot flash boot will fail or produce immediate reboot loops. The signatures don’t match the fused root of trust. Match signing keys to fuse state. This is not a bug in your flash script.

Secure boot is a relay race of signatures. Each runner checks the next runner’s credentials before passing the baton.

flowchart TD
ROM["PBL (ROM)<br/>Root of trust in silicon"]
ROM -->|"verify sig"| XBL["XBL"]
XBL -->|"verify sig"| UEFI["UEFI / ABL"]
UEFI -->|"verify sig"| TZ["TrustZone (TZ)"]
UEFI -->|"verify sig + AVB"| BOOT["boot / vendor_boot"]
BOOT -->|"dm-verity"| SYSTEM["system / vendor in super"]
TZ --> HYP["Hypervisor (hyp)"]
TZ --> MODEM["Modem (if authenticated boot enabled)"]
Stage Stored In Signed By Verifies
PBL ROM (immutable) Qualcomm XBL
XBL UFS LUN 0 OEM/QTI root cert chain UEFI, TZ images, ABL
ABL UFS LUN 0 Same chain boot, vbmeta, dtbo
TZ / hyp UFS LUN 0 Secure boot chain Secure world payloads
boot UFS LUN 1 (slotted) AVB key Kernel + ramdisk integrity
super UFS LUN 1 (slotted) dm-verity (via vbmeta) system/vendor blocks at read time

Trust flows down the chain. Compromise at the top bricks everything; compromise at the bottom only affects one slot.

Mental Model

Secure boot is a nightclub with layered bouncers. ROM bouncer checks XBL’s VIP list. XBL checks ABL’s wristband. ABL checks vbmeta before letting boot onto the floor. dm-verity is the security camera inside — even if someone smuggled a fake system partition past the door, every block read gets hash-checked against the guest list in vbmeta. One mismatch → ejected (boot failure / slot fallback).

Qualcomm Secure Boot: Fuses, Certs, and Image Signing

Section titled “Qualcomm Secure Boot: Fuses, Certs, and Image Signing”
Element Role
QFPROM fuses One-time (or limited) programmable storage for root cert hashes, secure boot enable, debug disable
PBL ROM bootloader; hash of root cert burned into fuses
Root certificate OEM or QTI root; signs subordinate signing keys
Code signing certificate Signs individual boot images (XBL, ABL, TZ)
Debug policy Controls JTAG, EDL restrictions on production units
Property Development / Bench Production (Fused)
Secure boot May be disabled or use test keys Enforced
Unsigned fastboot flash Often allowed on eng builds Rejected
EDL programmer Test programmer accepted Only signed OEM programmer
JTAG May be open Disabled
Key revocation N/A Compromised keys burned via fuse

Image Signing Workflow (What Your Build System Does)

Section titled “Image Signing Workflow (What Your Build System Does)”
  1. Build generates unsigned images (boot.img, abl.elf, xbl.elf)
  2. Signing server applies PKCS#7 / CMS signature with authorized key
  3. Signed images packaged into flash/OTA drops
  4. vbmeta aggregates hashes and rollback indices for AVB consumers

You rarely sign manually, but you debug the failure when CI produces an unsigned artifact or wrong key.

AVB is Android’s partition integrity layer, implemented in ABL and the kernel init path.

vbmeta.img contains descriptors, a table of what to verify:

Descriptor Type What It Describes
Hash partition SHA-256 of entire partition (boot, dtbo)
Hashtree partition dm-verity root hash for system, vendor, etc.
Kernel cmdline Expected dm-verity flags appended to kernel command line
Chain partition Delegate verification to another vbmeta (multi-slot)
Rollback index Minimum acceptable version (anti-downgrade)

ABL reads vbmeta_a or vbmeta_b matching the selected slot. Mismatch with flashed boot or super → verification failure.

Read-only filesystems (system, vendor) use dm-verity:

  1. Filesystem blocks arranged in Merkle hash tree on disk
  2. Root hash stored in vbmeta descriptor
  3. Kernel dm-verity driver hashes each block on read
  4. Corruption or tamper → I/O error → init failure → reboot

dm-verity runs continuous read-time checking, not just boot-time.

Two mechanisms cooperate. The rollback index in vbmeta lives in per-partition metadata; ABL rejects any image whose index is lower than the stored fuse or metadata value. Anti-rollback fuses (ARO) in QFPROM enforce a hardware minimum version for TZ, XBL, and modem firmware. Boot metadata in misc/bootctrl tracks successful boot count per slot.

Downgrading to an OS with a known CVE is blocked, even if the image is correctly signed with an old key epoch.

flowchart TD
BOOT["ABL selects slot B"]
BOOT --> VB["Read vbmeta_b"]
VB --> SIG{"Signature valid?"}
SIG -->|No| FAIL["Reject slot B"]
SIG -->|Yes| RI{"Rollback index ≥ stored?"}
RI -->|No| FAIL
RI -->|Yes| HASH{"boot hash matches?"}
HASH -->|No| FAIL
HASH -->|Yes| DM["Boot kernel → dm-verity on system"]
DM --> OK["Successful boot → mark slot successful"]
FAIL --> FB{"Other slot valid?"}
FB -->|Yes| SLOT_A["Try slot A"]
FB -->|No| REC["Recovery / fastboot / EDL"]

Behavior depends on where failure occurs and A/B slot state:

Failure Point Typical Device Behavior
XBL signature invalid No boot; EDL or black screen; QFIL recovery
ABL signature invalid Same; boot chain broken
vbmeta / boot mismatch (one slot) ABL tries other A/B slot
Both slots invalid Fastboot mode, recovery, or EDL
dm-verity corruption at runtime Kernel panic / reboot loop on that slot
Rollback index too low Flash rejected in fastboot; OTA aborted in UpdateEngine
Modem secure boot failure Modem offline (no cellular); Android may still boot
  1. ABL attempts current slot
  2. Verification fails → increment retry count in bootctrl metadata
  3. Retries exhausted → mark slot unbootable
  4. ABL attempts alternate slot
  5. If alternate succeeds → running OS may offer “Update failed, rolled back” notification
  6. If both fail → recovery or fastboot with locked state
Where You'll See This

When fastboot flash fails with SECURE BOOT / signature errors:

  1. Confirm build type: eng/userdebug/user and matching signing profile
  2. Check if board is production fused; test keys won’t work
  3. Verify vbmeta was flashed with boot. They’re a pair.
  4. Check rollback index if flash worked yesterday but not today after merging an old branch

When OTA downloads but won’t apply:

Terminal window
adb logcat -s update_engine | grep -i "rollback\|signature\|verity"

Look for RollbackIndicator, Signature verification failed, or Hash mismatch.

Golden rule: Never fastboot-flash boot without matching vbmeta on AVB-enabled builds.

Verified Boot vs Verified Boot (Orange / Yellow / Green)

Android docs describe boot state colors: Green (locked, full verification), Yellow (unlocked bootloader, integrity warning), Orange (custom OS, user acknowledged). Automotive production units target Green: locked bootloader, enforced dm-verity, no user-facing unlock. Dev benches may run Yellow for fastboot iteration. Know your program’s bootloader lock policy before assuming fastboot flash is allowed.

Connect the Dots

Page 8.1 introduced vbmeta in the partition map. Page 8.2 explains why EDL programmers must be signed on fused units. Page 8.3 shows fastboot commands that trigger verification. Page 8.5 covers how OTA preserves rollback indices across slot updates.

  1. Secure boot = signature chain from ROM through XBL/ABL/TZ. AVB = partition integrity via vbmeta + dm-verity.
  2. Production fuses enforce signing. Unsigned dev flashes fail by design.
  3. Rollback protection blocks downgrade attacks via indices and anti-rollback fuses.
  4. Verification failure leads to slot fallback, then recovery/fastboot/EDL. Never silent compromise.

Check Your Understanding

1. What is the role of vbmeta in Android Verified Boot?

2. Your fastboot flash of boot.img succeeds on a bench unit but the device reboot-loops. vbmeta was not updated. Most likely cause?

3. What happens when both A/B slots fail verified boot checks?