Version binding

All KeyMint keys must be bound to a root of trust for the device. The root of trust is a bitstring derived from the public key used to verify the signature of the boot image, together with the bootloader lock state.

KeyMint keys must also be bound to the operating system version and patch level of the device. To support Treble's modular structure, this version binding includes separate patch levels for each partition (boot, system, and vendor). This allows each partition to be updated independently, while still providing rollback protection.

To implement this version binding, the KeyMint trusted app (TA) needs a way to securely receive the current OS version and patch levels, and to ensure that the information it receives matches all the information about the running system.

  • Devices with Android Verified Boot (AVB):
    • The patch levels and OS version can be included in vbmeta.img, so the bootloader can provide them to KeyMint.
    • For chained partitions, the version info for the partition is in the chained VBMeta.
    • In general, version information should be in the VBMeta struct that contains the verification data (hash or hashtree) for a given partition.
  • Devices without AVB:
    • Verified Boot implementations need to provide a hash of the version metadata to the bootloader, so the bootloader can provide the hash to KeyMint.
    • boot.img can continue storing patch levels in the header.
    • system.img can continue storing patch levels and the OS version in read-only properties.
    • vendor.img stores the patch level in the read-only property ro.vendor.build.version.security_patch.
    • The bootloader can provide a hash of all data validated by Verified Boot to KeyMint.

The following tags describe version information for the relevant partitions:

KeyMint implementations should treat all patch levels independently. Keys are usable if all version info matches the values associated with a key. If the current device version is more recent than any value associated with a key, KeyMint returns the KEY_REQUIRES_UPGRADE error on any attempt to use the key. Keystore then performs IKeyMintDevice::upgradeKey() to generate a new keyblob that is bound to the current patch levels (and Keystore subsequently deletes the previous keyblob with a call to IKeyMintDevice::deleteKey()).