| # 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 |