OptiStick 5 (S905X5M) secure-boot test — signed bootloader on an unfused unit

Wilber Zheng · 2026-10-29 → 2026-10-30 · follow-up to the dbg1479 report

Result: a device-signed bootloader boots to the player on an unfused unit (dbg1491), once two things are true:
  1. bl30/bl33 are signed only, not AES-encrypted: drop --infile-aes256-bl30/bl33-payload from gen-device-fip.sh.
  2. vbmeta is signed with the same key as bl33 level-3. On S7D, a device-signed u-boot verifies vbmeta against the bl33 key in the FIP first (CONFIG_AVB2_KPUB_FROM_FIP), and treats a mismatch as untrusted.
No eFuse was burned at any point. No u-boot code was changed. All repo changes are on local branches and were never pushed.

Identity

ItemValue
UnitOne OptiStick 5 PVT (S905X5M / S7D rev B, 1 GB, eMMC BJTD4R). eFuse never burned. The same unit was used for every ROM below.
BurnAml_USB_Burn_Tool V1.0.3 (Mac), "Erase Bootloader" + "Erase Flash", image only, no eFuse / no .efuse file
SDKAmlogic Yocto Kirkstone SDK, manifest yocto-kirkstone-sdk-lts.2.0 (u-boot v2023 @48669f6c, fip @76d3ff1e)
Sourceprd36 source (yocto_os branch feature/wilber/secureboot-prd36-test and its children, below)
Signing keysThe device-keys SEI provided (s905x5m template, RSA-4096, trustchain 0)
Docs usedS905X5M Series Secure Boot User Guide (0.3); S905X5M Series eFuse Object Burning User Guide (0.3); Yocto SDK Enable Secureboot User Guide (0.1)
ROMBootloadervbmeta keyResultmd5
dbg1479device-signed, bl30/bl33 AES-encrypted (SDK default)avb-dev-k1FAIL stops after boot bl33 ! and drops to USB mode (DFU:1)9c5b93f925245245ed5a01ffe9984e9c
dbg1489device-signed, not encryptedavb-dev-k1PARTIAL U-Boot runs, then ab: both slots unbootable and the rescue ladder parks in USB mode329862b863d561ff4690fbf3f5d28f04
dbg1476unsigned (control, same source)avb-dev-k1PASS boots to the player; AVB2 cannot find fip key → OptiSigns kpub3deceafbd9a68c1c060805e915cae796
dbg1491device-signed, not encrypted (as dbg1489)SEI bl33-level-3 (sha1 f93861f0…)PASS AVB2 verified with fip key success ×2, boots to the playerc90d0cf748f331d2d20bd3e41b236dd4

dbg1491 sha256 2458fdcb3b2293a436c5cd40b6ec2b01e71e4c874601b0195e427d6f702ec476. ROMs are on the bench host in ~/cand-out/.

Finding 1 — the SDK signing flow also encrypts bl30/bl33 (dbg1479)

Finding 2 — a device-signed u-boot trusts only the FIP bl33 key for vbmeta (dbg1489 → dbg1491)

Repo and SDK changes

Vendor SDK island (untracked; applied for each test bake, restored to pristine after each one)

FileChangeROMs
bl33/v2023/configs/amlogic/s7d_bm201_defconfig+ CONFIG_AML_SIGNED_UBOOT=y (Secure Boot guide §2.6)1479, 1489, 1491
bl33/v2023/board/amlogic/s7d_bm201/fw_arb.cfgdevice_scs/tee/ree_vers 0x6 → 0x01479, 1489, 1491
bl33/v2023/board/amlogic/s7d_bm201/device-keys/SEI device-keys copied in; device-fip-header.bin regenerated with gen_scs_root_hash.sh (the supplied one failed the BL30 size check; roothash unchanged)1479, 1489, 1491
fip/s7d/generate-binaries/bin/gen-device-fip.sh− the two --infile-aes256-bl30/bl33-payload lines1489, 1491
build hostpython2 (needed by pem_extract_pubkey.py)all

yocto_os local branches (never pushed, never merged)

CommitBranchWhat
a0e6b588asecureboot-prd36-testamlogic/island.manifest: pin the signed-u-boot island (so island-manifest verify passes)
387047605secureboot-prd36-testamlogic/sdk-fixes/debug-image/assert-provenance.py: check 3 compares the bootloader with u-boot.bin.device.signed when the deploy aml_upgrade_package_ab.conf names it (it always compared with u-boot.bin.signed and refused the correct dbg1479 pack). Still a hard check.
e341e47bcsecureboot-prd36-noencamlogic/island.manifest: pin the signed-only (no AES) island
4583cd7fasecureboot-prd36-avbfipTEST-ONLY ota-trust:
  • new avb/avb-dev-k2.pub.pem + avb-dev-k2.kpub.bin (public half of the SEI bl33-level-3 key);
  • inventory.json +1 avb_keys row;
  • signers.json avb.dev: avb-dev-k1 → avb-dev-k2.
Gate logic, optisigns-avb-kpub.h, avb-kpub.list, patch 166 and the prd channel are untouched.
--- a/ota-trust/signers.json
+++ b/ota-trust/signers.json
   "avb": {
-    "dev": "avb-dev-k1",
+    "dev": "avb-dev-k2",
     "prod": "avb-prod-k1"
   }

Branches are named feature/wilber/secureboot-prd36-{test,noenc,avbfip}. Each one is stacked on the previous one.

Risks

Plan (ranked)

  1. RECOMMENDED One key for bl33 level-3 and AVB, in KMS.
    • Generate the production (and a separate dev) device keyset so that bl33-level-3 is the AVB key.
    • Sign through --cmd-signpipe-*, signed-only (no --infile-aes256-*).
    • Register the key everywhere one key is expected: ota-trust, optisigns-avb-kpub.h (patch 166), avb-kpub.list.
    • Re-bake, then boot it on an unfused unit first.
  2. Wait for Amlogic's answers before fusing anything: the minimal signed-only set and order (expected: both root-cert hashes + lock, DEVICE_SCS_SIG, DEVICE_VENDOR_SIG; no DVGK/DVUK, DEVICE_PROT, *_PUBRSA_PROT, USB_AUTH or DIF), the RPMB impact, and the signpipe format.
  3. Fuse one sacrificial dev unit (DUT3) with the dev root and the confirmed minimal set. Verify boot, OTA, USB re-burn and recovery. Production fusing comes last.
  4. Alternative (not recommended): undefine CONFIG_AVB2_KPUB_FROM_FIP. That needs a u-boot change, and the fused branch would also need patch 166 to trust our key (C6); a mistake there bricks fused units.

Logs (identifiers scrubbed)

中文摘要

没烧 eFuse 的 Stick5 上,签了名的 bootloader 已经能开到播放器(dbg1491)。前提有两个:

  1. 只签名、不加密。dbg1479 起不来,是因为 SDK 默认把 bl30/bl33 加密了。
  2. vbmeta 要用 bl33 第三级密钥签。S7D 签了名的 u-boot 只认 FIP 里的这把密钥,dbg1489 卡在"两个槽都不可启动"就是这个原因。

u-boot 代码一行没改。仓库的改动都在本地分支,没有推送。下一步建议:用 KMS 生成正式密钥,让 bl33 第三级和 AVB 用同一把;Amlogic 确认最少要烧哪些 eFuse 位以后,先找一台测试机烧 eFuse 验证。