Back to Eliza

Boot Image Format and Key Ladder

packages/chip/docs/security/boot-image-format.md

2.0.15.9 KB
Original Source

Boot Image Format and Key Ladder

Status: pre-silicon specification. No image format, signature path, or key ladder is implemented today. ROM is identity-only (see arch/security.md).

1. Algorithms

PurposeAlgorithmJustification
Image signatureEd25519 (RFC 8032)Small public keys (32 B) and signatures (64 B) fit OTP and SPI overhead budgets; deterministic — no RNG required in ROM; no patent encumbrance; constant-time reference implementations are short and audit-friendly; widely deployed (OpenSSH, libsodium, Tor, AVB optional).
Image hashSHA-256Required by AVB; broad HW/SW support; sufficient for v0 collision resistance.
Key-hash storageSHA-256 truncated to 256 bits in OTPMatches AVB vbmeta rollback-protected key descriptor format.
Optional intermediate KDFHKDF-SHA-256For deriving per-stage authentication keys from a single offline root.

RSA-PSS-3072 is NOT used in v0: larger keys (384 B public, 384 B signature) inflate OTP and SPI overhead, and ROM verification code is larger and harder to audit. ECDSA P-256 is NOT used because it requires per-signature RNG, which complicates ROM correctness.

2. Signed image container

+-------------------------------+
| header (256 B, see 2.1)       |
+-------------------------------+
| payload (image_size B)        |
+-------------------------------+
| signature_blob (96 B)         |
+-------------------------------+

2.1 Header (256 B, little-endian)

OffsetSizeFieldNotes
0x008magicASCII OPNPHN01
0x084header_version=1
0x0C4image_type0=bootloader, 1=recovery, 2=vbmeta, 3=vendor_boot
0x108image_sizebytes in payload
0x184rollback_indexmonotonic per image_type
0x1C4rollback_slotindex into OTP rollback bank
0x204key_idwhich authorized key signed this image
0x244flagsbit0=allow_dev, bit1=allow_mfg
0x2832payload_sha256hash of payload bytes
0x4832next_stage_pubkey_hashSHA-256 of next-stage public key (key-ladder pin)
0x684min_lifecycle_stateimage refuses to run below this state
0x6C148reservedzero-filled, included in signature

2.2 Signature blob (96 B)

OffsetSizeField
0x0032pubkey (Ed25519)
0x2064signature over (header

ROM enforces: SHA-256(pubkey) == OTP.root_key_hash for the first stage, then each stage enforces SHA-256(next_stage_pubkey) == header.next_stage_pubkey_hash loaded from the previous stage. This implements the key ladder.

3. Key ladder

OTP.root_key_hash   -->   Root Ed25519 key (R)   [offline air-gapped HSM]
                                |
                                | signs
                                v
                          AVB / Stage-1 key (A)  -- signs -->  bootloader (BL1, BL2)
                                |
                                v
                          Vendor key set (V0..Vn) -- signs --> vendor partitions
                                |
                                v
                          OTA payload key (O)    -- signs -->  OTA streams
  • Root key (R): offline HSM only. Signs A and revocation list. Used once per product lifetime per re-key event. See key-ceremony.md.
  • AVB key (A): online HSM. Signs vbmeta and bootloader stages.
  • Vendor keys (V): online HSM, scoped per vendor partition.
  • OTA key (O): online HSM, rotates per release train.

Revocation: each non-root key carries a key_id. OTP holds an 8-bit revoked_key_bitmap — programming a bit revokes that key_id. ROM refuses any image whose key_id is revoked, even if signature verifies.

4. Rollback indices

  • Each image_type owns one rollback slot in OTP.
  • Slot value is the count of programmed monotonic fuses (unary encoding).
  • Image accepted only if header.rollback_index >= OTP.rollback[slot].
  • After successful boot, bootloader programs additional fuses until OTP.rollback[slot] == header.rollback_index.
Slotimage_typewidth (fuses)
0bootloader (BL1)32
1bootloader (BL2)32
2vbmeta32
3recovery16
4vendor_boot16

See otp-fuse-map.md for physical fuse allocation.

5. Lifecycle states

Lifecycle is stored as a one-hot fuse field; transitions are one-way.

StateCodeDescriptionDebugOTAFastboot flash
BLANK0b0000_0001Untrimmed die from foundry.Fulln/an/a
DEV0b0000_0010Engineering bring-up. Accepts dev-signed images (flag allow_dev=1).Fulldev-keysyes
MFG0b0000_0100Factory provisioning. Accepts mfg-signed images.Auth requiredmfg-keysyes (gated)
LOCKED0b0000_1000Production. Accepts only production-keyed images.Auth requiredprod-keysdenied unless unlocked then wipe
RMA0b0001_0000Authorized service. User-data partitions wiped on entry.Auth requiredrma-keysyes
SCRAP0b0010_0000Permanently disabled. ROM halts immediately.NoneNoneNone

Allowed transitions: BLANK->DEV, BLANK->MFG, MFG->LOCKED, LOCKED->RMA, any->SCRAP.

min_lifecycle_state in the header lets a production-signed image refuse to boot on a DEV unit.

6. ROM halt behavior

ROM halts and emits a 32-byte structured halt record on UART at 115200n8 if:

  • magic mismatch
  • header_version unsupported
  • payload_sha256 mismatch
  • signature verification failure
  • pubkey hash != OTP root
  • rollback_index < OTP rollback slot
  • key_id revoked
  • lifecycle < min_lifecycle_state
  • OTP read parity failure on any security fuse

Halt is hard: WDT disabled, all DMA quiesced, JTAG state per debug-policy.md. There is no fallback to an unsigned image. There is no "secure mode bypass".

7. Cross-references

  • threat-model.md mitigations M1, M2, M14
  • avb-a-b-ota.md for AVB chain layering
  • otp-fuse-map.md for fuse allocation
  • test-plan.md cases TC-BOOT-* and TC-ROLLBACK-*