Files
AXP-Resurection/docs/009-hardening-signing-checklist.md
T
sunfish-adminandCursor 2d145c2878 009: Polish bacon fixes, OTA host scripts, and migration docs.
Restore disable_configstore, EuiccDisabler and thermal CDEV guards, branding
and rebuild/sync helpers; document device roles, laptop migration, and Gitea.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 21:06:45 +02:00

13 KiB
Raw Blame History

009 — Userspace hardening / signing / AVB checklist (Gate G)

Closure measured 2026-10-09: LAB ship is user + release-keys + AVB flags 0 + Magisk preroot + malloc. Prefer 009-closure-parity-20261009.md over the 2026-09-29 baseline table below (kept for archaeology).

Task: T040.
Companion: kernel half = docs/009-gate-g-kernel-attribution.md.
Policy: project release keys yes; bootloader relock no (AXP/LOS unlocked norm). See specs/009-axp-los23-port/research.md.

Secrets never enter Git. Host material lives under /srv/rom/secrets/ on rom-dev01 only.


Measured baseline (2026-09-29 — historical)

Prop / fact GOLDEN (AXP Pro) LAB (Stage1 pack) Target
ro.build.type user userdebug user for ship; userdebug OK while developing
ro.build.tags release-keys test-keys release-keys
ro.build.flavor lineage_sunfish-user lineage_sunfish-userdebug …-user at ship
ro.debuggable 0 0 on LAB measure wait — typically 1 on userdebug 0 on ship
ro.secure 1 (LOS default) 1
ro.boot.flash.locked 0 0 0 (unlocked — intentional)
ro.boot.verifiedbootstate orange orange orange while unlocked
ro.boot.vbmeta.device_state unlocked (same class) unlocked
ro.boot.veritymode enforcing expect enforcing keep
SELinux Enforcing (expect) Enforcing keep
OTA zip cert AXP releasekey AOSP testkey.x509.pem (byte-match on stage1 zip) project releasekey
AVB signing key in tree AXP custom external/avb/test/data/testkey_rsa2048.pem project AVB key
BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS --flags 3 AXP sets real AVB when enabled LOS sunfish adds --flags 3 unless WITH_AVB=true keep flags 3 (signing infra only; not runtime harden)

LAB adb sample (device 11231JEC207477, Stage1 sideload): test-keys / userdebug / orange / flash.locked=0 / getenforce=Enforcing.

GOLDEN source: /srv/rom/references/axp/golden/2026-09-13/getprop.txt.


What “done” means for Gate G userspace

  1. Ship images/OTAs verify as release-keys (not AOSP test-keys).
  2. Phonesky / microG keep their project JKS identities under /srv/rom/secrets/{phonesky,microg}-signing/ (already exist).
  3. AVB build uses project keys where LOS23/sunfish allows; device stays unlocked (orange). Relock is out of scope.
  4. Userspace hardening stages are attributable (patch dir + map) or explicitly deferred/skipped with reason.
  5. Gaps written down — no silent omit.

Stages (do in order)

US-S0 — Inventory (this doc) — done 2026-09-29

  • Compare GOLDEN vs LAB signing/AVB props.
  • Confirm stage1 zip OTA cert == AOSP testkey.
  • Confirm no ~/.android-certs / platform release keys on host yet (only Phonesky + microG JKS).
  • Record bootloader-lock = wont.

US-S1 — Generate project Android signing keys — done 2026-09-29 (host)

Host-only. Never commit .pk8 / private PEM.

Key Role
releasekey Default APK/OTA (PRODUCT_DEFAULT_DEV_CERTIFICATE)
platform platform-signed priv-apps
shared / media / networkstack / sdk_sandbox / bluetooth / nfc AOSP partition signing set

Procedure: scripts/009-generate-release-keys.sh on rom-dev01 → prefers /srv/rom/secrets/android-certs/ if writable, else $HOME/.android-certs (Lineage default; used 2026-09-29 because secrets/ is root-owned 750 without group write).

Mandatory before first signed ship bacon: encrypted/offline backup of that directory (constitution). Public *.x509.pem may later be copied into Git for docs; private material must not.

Acceptance:

  • $HOME/.android-certs/{releasekey,platform,…}.{pk8,x509.pem} + avb.pem exist on rom-dev01 (2026-09-29T16:37Z)
  • Host tar backup: /home/android-build/backups/android-certs-20260929T1637Z.tar.gz (mode 600; SHA256 in .sha256) — still copy offline/encrypted
  • releasekey DN = O=AXP-Resurection, OU=sunfish-a16, CN=release (not AOSP testkey)
  • Root later: install -d /srv/rom/secrets/android-certs and move keys there
  • Owner offline encrypted copy confirmed

US-S2 — Wire release keys into bacon — in progress

Lineage convention: PRODUCT_DEFAULT_DEV_CERTIFICATE → path without suffix (e.g. …/releasekey). On LOS 23 / soong, env export alone is ignored — must be a product makefile PRODUCT_ (see vendor/sunfish-a16/signing.mk, inherited via magisk.mk). Verified get_build_var → project releasekey.

Keys present on rom-dev01 ($HOME/.android-certs/releasekey.pk8, 2026-09-29). First artifact 20261001T221102Z-…-cve-hi-releasekeys was still AOSP testkey (env-only wire). Rebacon after signing.mk (2026-10-01T22:12Z). CVE LAB bacons keep test-keys. First real signed bacon stays userdebug.

LAB 2026-10-02: first signed sideload booted Wi‑Fi OK but Bluetooth crash-looped — zygote selinux_android_setcontext failed with seinfo=default for com.android.bluetooth. Cause: APK signed with project certs/bluetooth.pk8 while MAINLINE_BLUETOOTH_SEPOLICY_DEV_CERTIFICATES stayed on AOSP build/make/target/product/security/ (non-com.google.android.bt default in config.mk). Fix: PRODUCT_MAINLINE_BLUETOOTH_SEPOLICY_DEV_CERTIFICATES in signing.mk (rebacon required; boot-only flash insufficient).

Acceptance:

  • Zip META-INF/com/android/otacert ≠ AOSP testkey
  • ro.build.tags=release-keys on LAB after sideload (boot-only flash insufficient) (note: first RK sideload still showed dev-keys on userdebug — recheck after BT fix)
  • Magisk preroot + microG + Wi‑Fi and Bluetooth OK on Stage1+combo4+CVE-hi ship pack (20261002T085915Z-…-cve-hi-releasekeys, LAB 2026-10-02: BT ON, crashed 0)
  • plat_mac_permissions.xml embeds project bluetooth.x509.pem (seinfo=bluetooth)
  • Minor: LOS SetupWizard after Wi‑Fi connect can bounce to language step (Wi‑Fi stays connected; non-blocking; note only)
  • Prior test-keys image retained for bisect (20261001T201836Z-…-cve-hi-batch2 / #49, or hi-batch3 when OK)

Script: scripts/009-bacon-axp-stage1-combo4-cve-hi-releasekeys.sh + vendor/sunfish-a16/signing.mk → vendor/sunfish-a16/certs/releasekey (in-tree copy of $HOME/.android-certs; gitignored — soong rejects paths outside ANDROID_BUILD_TOP).

US-S3 — Project AVB key (unlocked device)

Today sunfish often signs with AOSP testkey_rsa4096 (or rsa2048) and adds --flags 3 unless WITH_AVB=true (BoardConfigLineage.mk / BoardConfig-common.mk). LAB 20261002T085915Z vbmeta = AOSP testkey_rsa4096

  • flags 3 (not project avb.pem).

AXP ships custom AVB keys and documents AVB2; GOLDEN stays unlocked/orange. Clone that signing posture, not IOdes lock.

Bootloader / OEM unlocking (2026-10-02): relock remains wont for this Magisk track (orange + preroot). Locking with Magisk-patched boot is a brick risk on Pixel unless the full AVB chain is enforced end-to-end — out of scope. Keep flash.locked=0 / verifiedbootstate=orange. Prefer leaving OEM unlocking enabled in Developer options as a best-effort escape hatch for future unlock attempts — it is not a guarantee of recovery, data preservation, or rescue from every failure mode (AOSP: unlock ability is conditional). Do not turn it off casually.

Wire: vendor/sunfish-a16/BoardConfig.mk overrides BOARD_AVB_* → vendor/sunfish-a16/certs/avb.pem + SHA256_RSA4096. Leave WITH_AVB unset so --flags 3 stays (Magisk-friendly).

What flags 3 means (libavb): HASHTREE_DISABLED (1) | VERIFICATION_DISABLED (2). Descriptors are not enforced at boot; this is AVB signing infrastructure, not “AVB-hardened verified boot”. Do not call US-S3 “AVB endurecido” while flags stay 3. A later stage may measure WITH_AVB=true (flags 0) + Magisk resign — separate acceptance.

Acceptance:

  • BOARD_AVB_KEY_PATH → project vendor/sunfish-a16/certs/avb.pem
  • Artifact gates fail closed on target_files/IMAGES (not OUT make images): pubkey sha1 == avb_pkmd.bin (≠ AOSP 2597c218…); Flags 3; verify_image --key vbmeta + --expected_chain_partition vbmeta_system; Magisk boot hash matches vbmeta; magiskboot cpio test ≠ 0
  • Document clearly: runtime AVB enforce = off (flags 3) — not “AVB endurecido”
  • Device still boots unlocked; Magisk preroot intact (LAB 2026-10-02 sideload + boot/vbmeta reinforce; magiskd, flash.locked=0, orange)
  • No bootloader relock; OEM unlocking left enabled (escape hatch, not guarantee)

Branding (no rebacon-only)

  • Wire vendor/sunfish-a16/branding.mk → TARGET_UNOFFICIAL_BUILD_ID=AXP-Resurection-Pro (full Magisk track, not slim; next bacon embeds it in ro.lineage.version)
  • Ship script publishes sibling AXP-Resurection-Pro-*-sunfish.zip (hardlink/copy of Lineage bacon zip). Current artifact renamed the same way without rebuild.

US-S4 — Userspace hardening (first attributable pack)

See docs/009-us-s4-userspace-hardening.md.

  • Stage 0 LAB measure (Enforcing + FBE)
  • US-S4-1: strip Openssh/rsync/procmem packages from Lineage common.mk (apply_009_drop_openssh_packages.py); keep init.openssh.rc (AXP PRO)
  • LAB 2026-10-02: ship 20261002T151944Z sideloaded + reinforced; see docs/009-lab-acceptance-20261002-uss4.md
  • US-S4-2 (wired, pending bacon): drop Jelly + Gallery2 (AXP PRO product oracle — Fossify stays); apply_009_drop_jelly_gallery2.py + NoLineageJelly; see docs/009-axp-pro-product-apps-20260324.md
Candidate Priority Notes
Confirm SELinux Enforcing + encryption done LAB Enforcing + FBE
ptrace/Yama reverted 2026-10-10 Yama off like GOLDEN; scope 2 broke PairIP (Wallapop)
Debug/bugreport surface trim done US-S4-1 AXP PRO product oracle
Jelly + Gallery2 debloat US-S4-2 wired AXP PRO product; Fossify kept
mount flags / noexec where stock allows early don't break HW
hardened_malloc later Graphene/AXP; portability cost
Broad Graphene framework (scopes, etc.) later / deferred high UX cost; not Magisk-clone MVP

Ship patches under vendor/sunfish-a16/patches/009-axp-los23-port/hardening/ with README attribution. One stage per bacon when risk is unclear.

US-S5 — Kernel CVE mega / more Graphene (on boot-OK pack)

Do not flash old 20260918*-axp-kh-cve / kh-full (logo hang).

  • CVE clean-offset 429 + hi-batch1–3 on Magisk ship (151944Z LAB OK)
  • US-S5-1 LAB OK (162840Z): Yama since reverted to unset (PairIP) + CONFIG_SLAB_FREELIST_RANDOM=y — see docs/009-lab-acceptance-20261002-uss5.md
  • Next cycle after the user image is accepted (owner 2026-10-06): close kernel CVE + Graphene/AXP hardening + deblob on that baseline. Boot-check each batch (full cve-strict ~503 and CVE-2022-49980 alone hang at the Google logo). Inventory: remaining high-offset KEEP, 49980 lock-scope port, Stage1 probes that failed (allocsize/0007, ro/0007+0034, slab/0010+0018), hardened_malloc, AXP deblob that still leaves radio, GPS and Widevine working. Still out: location lockdown, bootloader relock, KernelSU, IPA removal.
  • Next-bacon recipe guard (2026-10-07): Stage1 uses patch --forward, omits already-present misc/0021, and fails unless KSYM_NAME_LEN=192; full feature-008 call-recording apply is restored. Quarantine the earlier bacon00949980 build and do not flash it.

Map updates: docs/009-kernel-hardening-map.md + Gate G attribution.

US-S6 — Optional later

  • Confirm lineage_sunfish-user after flash (bacon started 2026-10-06, tmux 009-user-bacon, log /srv/rom/artifacts/detach-009-user-bacon-20261006T203157Z.log. PRO stays branding. Check ro.build.type=user and release-keys on LAB)
  • GPG-sign published SHA sums (AXP does; nice-to-have)
  • LOS23 nightly rebase (vanilla + re-apply Magisk/stage1/keys)
  • Bootloader lock — wont

Host paths

What Path
Platform / OTA / AVB secrets $HOME/.android-certs/ on rom-dev01 (2026-09-29); prefer /srv/rom/secrets/android-certs/ after root relocate
Certs tar backup /home/android-build/backups/android-certs-20260929T1637Z.tar.gz
Phonesky JKS /srv/rom/secrets/phonesky-signing/
microG JKS /srv/rom/secrets/microg-signing/
Keygen script (repo) scripts/009-generate-release-keys.sh
Signing README (vendor) vendor/sunfish-a16/patches/009-axp-los23-port/signing/README.md
GOLDEN props /srv/rom/references/axp/golden/2026-09-13/
AXP docs (mirror) …/axpos.org/docs/knowledge/{signatures,verifiedboot}/

Explicit non-goals

  • Bootloader relock / green verified-boot for end users.
  • Replacing Phonesky/microG keys with platform keys.
  • Committing private keys or passphrases to Git.
  • Treating missing lock as Gate G failure.