pvmfw: README: Document ABIs & guest signing
Test: preview Change-Id: I1d624e7ff479c5ed03c4d1a013890d394b4fe2d2
This commit is contained in:
parent
7968aa9970
commit
d62d04b828
116
pvmfw/README.md
116
pvmfw/README.md
|
@ -270,3 +270,119 @@ OS's device tree and config header of `pvmfw`. Both `virtualizationmanager` and
|
|||
|
||||
For details about device tree properties for debug policies, see
|
||||
[microdroid's debugging policy guide](../microdroid/README.md#option-1-running-microdroid-on-avf-debug-policy-configured-device).
|
||||
|
||||
## Booting Protected Virtual Machines
|
||||
|
||||
### Boot Protocol
|
||||
|
||||
As the hypervisor makes pvmfw the entry point of the VM, the initial value of
|
||||
the registers it receives is configured by the VMM and is expected to follow the
|
||||
[Linux ABI] _i.e._
|
||||
|
||||
- x0 = physical address of device tree blob (dtb) in system RAM.
|
||||
- x1 = 0 (reserved for future use)
|
||||
- x2 = 0 (reserved for future use)
|
||||
- x3 = 0 (reserved for future use)
|
||||
|
||||
Images to be verified, which have been loaded to guest memory by the VMM prior
|
||||
to booting the VM, are described to pvmfw using the device tree (x0):
|
||||
|
||||
- the kernel in the `/config` DT node _e.g._
|
||||
|
||||
```
|
||||
/ {
|
||||
config {
|
||||
kernel-address = <0x80200000>;
|
||||
kernel-size = <0x1000000>;
|
||||
};
|
||||
};
|
||||
````
|
||||
|
||||
- the (optional) ramdisk in the standard `/chosen` node _e.g._
|
||||
|
||||
```
|
||||
/ {
|
||||
chosen {
|
||||
linux,initrd-start = <0x82000000>;
|
||||
linux,initrd-end = <0x82800000>;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
[Linux ABI]: https://www.kernel.org/doc/Documentation/arm64/booting.txt
|
||||
|
||||
### Handover ABI
|
||||
|
||||
After verifying the guest kernel, pvmfw boots it using the Linux ABI described
|
||||
above. It uses the device tree to pass the following:
|
||||
|
||||
- a reserved memory node containing the produced BCC:
|
||||
|
||||
```
|
||||
/ {
|
||||
reserved-memory {
|
||||
#address-cells = <0x02>;
|
||||
#size-cells = <0x02>;
|
||||
ranges;
|
||||
dice {
|
||||
compatible = "google,open-dice";
|
||||
no-map;
|
||||
reg = <0x0 0x7fe0000>, <0x0 0x1000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
- the `/chosen/avf,new-instance` flag, set when pvmfw generated a new secret
|
||||
(_i.e._ the pVM instance was booted for the first time). This should be used
|
||||
by the next stages to ensure that an attacker isn't trying to force new
|
||||
secrets to be generated by one stage, in isolation;
|
||||
|
||||
- the `/chosen/avf,strict-boot` flag, always set and can be used by guests to
|
||||
enable extra validation
|
||||
|
||||
### Guest Image Signing
|
||||
|
||||
pvmfw verifies the guest kernel image (loaded by the VMM) by re-using tools and
|
||||
formats introduced by the Android Verified Boot. In particular, it expects the
|
||||
kernel region (see `/config/kernel-{address,size}` described above) to contain
|
||||
an appended VBMeta structure, which can be generated as follows:
|
||||
|
||||
```
|
||||
avbtool add_hash_footer --image <kernel.bin> \
|
||||
--partition_name boot \
|
||||
--dynamic_partition_size \
|
||||
--key $KEY
|
||||
```
|
||||
|
||||
In cases where a ramdisk is required by the guest, pvmfw must also verify it. To
|
||||
do so, it must be covered by a hash descriptor in the VBMeta of the kernel:
|
||||
|
||||
```
|
||||
cp <initrd.bin> /tmp/
|
||||
avbtool add_hash_footer --image /tmp/<initrd.bin> \
|
||||
--partition_name $INITRD_NAME \
|
||||
--dynamic_partition_size \
|
||||
--key $KEY
|
||||
avbtool add_hash_footer --image <kernel.bin> \
|
||||
--partition_name boot \
|
||||
--dynamic_partition_size \
|
||||
--include_descriptor_from_image /tmp/<initrd.bin> \
|
||||
--key $KEY
|
||||
```
|
||||
|
||||
Note that the `/tmp/<initrd.bin>` file is only created to temporarily hold the
|
||||
hash descriptor to be added to the kernel footer and that the unsigned
|
||||
`<initrd.bin>` should be passed to the VMM when booting a pVM.
|
||||
|
||||
The name of the AVB "partition" for the ramdisk (`$INITRD_NAME`) can be used by
|
||||
the signer to specify if pvmfw must consider the guest to be debuggable
|
||||
(`initrd_debug`) or not (`initrd_normal`), which will be reflected in the
|
||||
certificate of the guest and will affect the secrets being provisioned.
|
||||
|
||||
If pVM guest kernels are built and/or packaged using the Android Build system,
|
||||
the signing described above is recommended to be done through an
|
||||
`avb_add_hash_footer` Soong module (see [how we sign the Microdroid
|
||||
kernel][soong-udroid]).
|
||||
|
||||
[soong-udroid]: https://cs.android.com/android/platform/superproject/+/master:packages/modules/Virtualization/microdroid/Android.bp;l=427;drc=ca0049be4d84897b8c9956924cfae506773103eb
|
||||
|
|
Loading…
Reference in New Issue