# 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