pvmfw/avb: Add Capability::UefiSupport
Add support for a new VM capability flag in the VBMeta property
"com.android.virt.cap" representing guest kernel support for
the UEFI boot process.
Add unit tests to test the new capability.
Test: atest libpvmfw_avb.integration_test
Change-Id: I4c364909a743d860b9cb68fbda78a4860c136417
diff --git a/guest/pvmfw/avb/Android.bp b/guest/pvmfw/avb/Android.bp
index 558152d..f97a713 100644
--- a/guest/pvmfw/avb/Android.bp
+++ b/guest/pvmfw/avb/Android.bp
@@ -43,6 +43,7 @@
":test_image_with_duplicated_capability",
":test_image_with_rollback_index_5",
":test_image_with_multiple_capabilities",
+ ":test_image_with_all_capabilities",
":unsigned_test_image",
],
prefer_rlib: true,
@@ -218,3 +219,17 @@
},
],
}
+
+avb_add_hash_footer {
+ name: "test_image_with_all_capabilities",
+ src: ":unsigned_test_image",
+ partition_name: "boot",
+ private_key: ":pvmfw_sign_key",
+ salt: "4231",
+ props: [
+ {
+ name: "com.android.virt.cap",
+ value: "remote_attest|secretkeeper_protection|supports_uefi_boot",
+ },
+ ],
+}
diff --git a/guest/pvmfw/avb/src/verify.rs b/guest/pvmfw/avb/src/verify.rs
index 038b1d6..bd700ce 100644
--- a/guest/pvmfw/avb/src/verify.rs
+++ b/guest/pvmfw/avb/src/verify.rs
@@ -70,6 +70,11 @@
RemoteAttest,
/// Secretkeeper protected secrets.
SecretkeeperProtection,
+ /// UEFI support for booting guest kernel.
+ SupportsUefiBoot,
+ /// (internal)
+ #[allow(non_camel_case_types)] // TODO: Use mem::variant_count once stable.
+ _VARIANT_COUNT,
}
impl Capability {
@@ -77,6 +82,9 @@
const REMOTE_ATTEST: &'static [u8] = b"remote_attest";
const SECRETKEEPER_PROTECTION: &'static [u8] = b"secretkeeper_protection";
const SEPARATOR: u8 = b'|';
+ const SUPPORTS_UEFI_BOOT: &'static [u8] = b"supports_uefi_boot";
+ /// Number of supported capabilites.
+ pub const COUNT: usize = Self::_VARIANT_COUNT as usize;
/// Returns the capabilities indicated in `descriptor`, or error if the descriptor has
/// unexpected contents.
@@ -91,6 +99,7 @@
let cap = match v {
Self::REMOTE_ATTEST => Self::RemoteAttest,
Self::SECRETKEEPER_PROTECTION => Self::SecretkeeperProtection,
+ Self::SUPPORTS_UEFI_BOOT => Self::SupportsUefiBoot,
_ => return Err(PvmfwVerifyError::UnknownVbmetaProperty),
};
if res.contains(&cap) {
diff --git a/guest/pvmfw/avb/tests/api_test.rs b/guest/pvmfw/avb/tests/api_test.rs
index 8683e69..01c13d4 100644
--- a/guest/pvmfw/avb/tests/api_test.rs
+++ b/guest/pvmfw/avb/tests/api_test.rs
@@ -38,6 +38,7 @@
const TEST_IMG_WITH_INITRD_AND_NON_INITRD_DESC_PATH: &str =
"test_image_with_initrd_and_non_initrd_desc.img";
const TEST_IMG_WITH_MULTIPLE_CAPABILITIES: &str = "test_image_with_multiple_capabilities.img";
+const TEST_IMG_WITH_ALL_CAPABILITIES: &str = "test_image_with_all_capabilities.img";
const UNSIGNED_TEST_IMG_PATH: &str = "unsigned_test.img";
const RANDOM_FOOTER_POS: usize = 30;
@@ -418,3 +419,22 @@
assert!(verified_boot_data.has_capability(Capability::SecretkeeperProtection));
Ok(())
}
+
+#[test]
+fn payload_with_all_capabilities() -> Result<()> {
+ let public_key = load_trusted_public_key()?;
+ let verified_boot_data = verify_payload(
+ &fs::read(TEST_IMG_WITH_ALL_CAPABILITIES)?,
+ /* initrd= */ None,
+ &public_key,
+ )
+ .map_err(|e| anyhow!("Verification failed. Error: {}", e))?;
+
+ assert!(verified_boot_data.has_capability(Capability::RemoteAttest));
+ assert!(verified_boot_data.has_capability(Capability::SecretkeeperProtection));
+ assert!(verified_boot_data.has_capability(Capability::SupportsUefiBoot));
+ // Fail if this test doesn't actually cover all supported capabilities.
+ assert_eq!(Capability::COUNT, 3);
+
+ Ok(())
+}