blob: ff1a0d6d9064832083cb11af2594c58cfcb026f8 [file] [view]
# Updatable VM
From Android V+, AVF (with Microdroid) supports Updatable VMs. This allows the VM instances to
remain stable even when the VM core components and payload are upgraded. This includes (but is not
limited to) update of payload apk and Microdroid OS.
## Background
The following constructs have been used (and are critical) to support Updatable VM:
1. [Secretkeeper][sk_project] is the critical piece of solution. It provides secure storage for VM's
secrets. It is specified as [a HAL][secretkeeperhal] and needs to be implemented in an
environment with privilege higher than protected VM.
1. [DICE Policies][dice_policy]: DICE policy is the mechanism for setting constraints on a DICE
chain(i.e., identities of a VM). VM seals its secrets using DICE policies, and Secretkeeper
serves as a policy verifier.
1. [AuthGraph key exchange][authgraphke]: The requests/responses between pVM and Secretkeeper are
ferried via Android (which is untrusted). A cryptographically secure channel is setup using
AuthGraph key exchange.
## VmSecrets::V2
Updatable VMs are achieved by changing Microdroid's secret management. It now supports
`VmSecrets::V2` which is derived from 2 independently secured secrets:
1. Secretkeeper protected secret: This is random 64 bytes generated by VM on first boot & stored in
Secretkeeper.
1. DICE Sealing CDIs (similar to legacy secrets V1): These are defined by
[Open Profile for DICE][open_dice_spec_cdi] and must remain the same across software updates.
Secretkeeper protected secret is protected against rollback of boot images i.e. VM instance rebooted
with downgraded images will not have access to these secrets. This is done using
[Policy Gated Storage feature](policy_gated_storage) of Secretkeeper. On the first boot of the VM
instance, Microdroid Manager (on behalf of the VM payload) generates a secret, stores it in
Secretkeeper and on further reboots, this is retrieved from it. Along with this secret, a
[sealing policy](#sealing-policy) is also stored (in Secretkeeper) that ensures that secrets are not
released to the VM instance booted with downgraded images.
Each Secretkeeper client needs a 64 bytes' Id to store an entry in Secretkeeper. For Microdroid,
this is Instance Id. It is allocated by host (when the VM instance is created) and relayed to VM via a property (`instance-id`)
in device tree node (`/avf/untrusted`)
## Sealing Policy
Sealing Policy is a DICE policy on the DICE chain of the payload running in Microdroid. This is
constructed by Microdroid Manager on behalf of the payload and is stored along with the secret.
A highly simplified view - Sealing policy built by Microdroid has the following constraints:
- ExactMatch on DiceCertChainInitialPayload (root public key)
- ExactMatch of Instance salt, this is present in DiceChainEntry corresponding to OS (and is derived
deterministically from Instance Id). This is needed to prevent the secrets of one instance from
being accessible to another instance running with the same VM images.
- For each DiceChainEntry:
1. ExactMatch on AUTHORITY_HASH.
1. ExactMatch on MODE - Secret should be inaccessible if any of the runtime
configuration changes. For example, the secrets stored with a boot stage being in Normal mode
should be inaccessible when the same stage is booted in Debug mode.
1. GreaterOrEqual on SECURITY_VERSION: The secrets will be accessible if version of any
image is greater or equal to the set version.
- For each Subcomponent on the last DiceChainEntry (which corresponds to VM payload, See
[vm_config.cddl][vm_config_cddl]): - GreaterOrEqual on SECURITY_VERSION - ExactMatch on
AUTHORITY_HASH.
The sealing policy is updated each time the secret is retrieved. This ensures the secrets are only
released if the security version of the images are non-decreasing.
## Deferring rollback protection
Traditionally in Android, each boot stage is responsible for rollback protection of the next boot
image. ABL has access to tamper evident storage to ensure that. VM (Android U and lower) use
instance.img where the boot stages (pvmfw/Microdroid) would store information about packages they
boot (exact code_hash) and on subsequent boot of the instance ensure that the same images are
allowed to run. This prevented running of older images, but also prevented running newer images and
hence VMs were not updatable.
Secretkeeper HAL then introduced the capability of storing secrets in a TA such that the owner of
the secret ( for ex. VM) while storing it, includes a corresponding sealing policy such that only
entities with DICE chain that adheres to those policies can access the secrets.
This allows the bootloaders to defer rollback protection to the payload. Host relays this intention
to pVM (both pVM firmware and OS) using the property (`defer-rollback-protection`) in device tree
node (`/avf/untrusted`). If this is set and the guest OS is capable of `SecretkeeperProtection` then
VMs use Secretkeeper based rollback protection.
### Note on legacy support
If the device does not support Secretkeeper, Microdroid will fallback to legacy secrets
(`VmSecrets::V1`). These are not protected against the rollback of boot images and hence pVM
firmware cannot defer rollback protection. Instance image is used to record information about the
images on the first boot of the instance, and any further boot prevents any different image from
running i.e, Updatable VMs are not supported.
[authgraphke]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/authgraph/aidl/android/hardware/security/authgraph/IAuthGraphKeyExchange.aidl
[dice_policy]: https://android.googlesource.com/platform/system/secretkeeper/+/refs/heads/main/dice_policy/
[open_dice_spec_cdi]: https://pigweed.googlesource.com/open-dice/+/HEAD/docs/specification.md#cdi-values
[secretkeeperhal]: https://cs.android.com/android/platform/superproject/main/+/main:hardware/interfaces/security/secretkeeper/aidl/android/hardware/security/secretkeeper/ISecretkeeper.aidl
[sk_project]: https://android.googlesource.com/platform/system/secretkeeper/
[vm_config_cddl]: https://cs.android.com/android/platform/superproject/main/+/main:packages/modules/Virtualization/microdroid_manager/src/vm_config.cddl