Explore AVB chained partition delegation, to better protect the main AVB key

Android Verified Boot allows arrangements in which asserting the authenticity of partitions need not depend on a single AVB key being available for each signing.

Traditionally, for a given device, CalyxOS has generated and used just one key* for AVB signing: "avb". This "avb" key, also shown as "key0" in documentation examples, is used to sign the VBMeta struct in the central vbmeta partition and also used to sign all other partitions*. Crucially, the key that signs vbmeta's struct is the same avb_custom_key that cannot be rotated. But there can be multiple keys involved here, as individually as desired; vbmeta can be chained to other partitions whose structs may be signed with other keys, like the "key1" in documentation examples.

Given sufficient delegation, the central VBMeta struct does not need to be regenerated or re-signed for every update, which means that this central and non-rotatable "avb" / "key0" key does not need to be available for signing every update.

The VBMeta struct is flexible enough to allow hash descriptors and hashtree descriptors for any partition to live in the vbmeta partition, the partition that they are used to integrity check (via a chain partition descriptor), or any other partition (via a chain partition descriptor). This allows for a wide range of organizational and trust relationships.

The thought here is to have the vbmeta key (key0) protected by stricter access controls than other keys, and to have the central vbmeta partition delegate authority to VBMeta structs in other partitions that are all signed with a single additional "delegated" key (key1). In this scenario, the idea is that the vbmeta key (key0) would be used once to generate a vbmeta partition that effectively honors the delegated key, such that the vbmeta partition would only need to be (re-)generated when establishing keys for a new device or rotating the delegated key. The active employment of the vbmeta key for signing going forward should be rare.

Either or both of the vbmeta / delegated key could be per-device.

To clarify: Above, the vbmeta key is also referred to as "avb", "key0", "central", "non-rotatable", "main". The delegated key is also referred to as "key1".

See: https://android.googlesource.com/platform/external/avb/+/android16-release/README.md

  1. Try doing this. Sign a build where the vbmeta partition uses one key and all the others use a delegated key. Then, change the vbmeta key to something else and sign again. Flash the new build, but manually flash the old vbmeta / write the old avb_custom_key. See if the device will lock and start successfully.
  2. (Partially done: FP5) Try it on devices that seem less likely to support it properly: FP5, hawao, bramble.
  3. Take a photo of the bootloader yellow screen with hashes.
  4. (See comments) Try rotating the delegated key and sideloading an OTA with the rotated key.
  5. (See comments) Take another photo of the bootloader yellow screen with hashes and compare.
  6. Look into rollback indexes and how they work / how we increment them for vbmeta.

* Technically, some devices have also been using a separate key for vbmeta_system in CalyxOS signing.

Edited Jul 15, 2025 by t-m-w
Assignee Loading
Time tracking Loading