[KM-VM] Check Trusty VM kernel has valid AVB footer
Test: libpvmfw_avb.integration_test
Bug: 369299899
Change-Id: Iba25d6ae4d5017d71339b615cab1c6f1843bd301
diff --git a/guest/pvmfw/avb/Android.bp b/guest/pvmfw/avb/Android.bp
index f97a713..bc5cbfe 100644
--- a/guest/pvmfw/avb/Android.bp
+++ b/guest/pvmfw/avb/Android.bp
@@ -33,6 +33,7 @@
":microdroid_kernel_signed",
":microdroid_initrd_normal",
":microdroid_initrd_debuggable",
+ ":trusty_security_vm_signed",
":test_image_with_one_hashdesc",
":test_image_with_non_initrd_hashdesc",
":test_image_with_initrd_and_non_initrd_desc",
diff --git a/guest/pvmfw/avb/tests/api_test.rs b/guest/pvmfw/avb/tests/api_test.rs
index 01c13d4..72c795c 100644
--- a/guest/pvmfw/avb/tests/api_test.rs
+++ b/guest/pvmfw/avb/tests/api_test.rs
@@ -55,6 +55,17 @@
}
#[test]
+fn latest_trusty_security_vm_kernel_passes_verification() -> Result<()> {
+ let salt = b"trusty_security_vm_salt";
+ let expected_rollback_index = 1;
+ assert_payload_without_initrd_passes_verification(
+ &load_latest_trusty_security_vm_signed_kernel()?,
+ salt,
+ expected_rollback_index,
+ )
+}
+
+#[test]
fn latest_debug_payload_passes_verification() -> Result<()> {
assert_latest_payload_verification_passes(
&load_latest_initrd_debug()?,
diff --git a/guest/pvmfw/avb/tests/utils.rs b/guest/pvmfw/avb/tests/utils.rs
index e989579..0e836d5 100644
--- a/guest/pvmfw/avb/tests/utils.rs
+++ b/guest/pvmfw/avb/tests/utils.rs
@@ -33,6 +33,7 @@
const MICRODROID_KERNEL_IMG_PATH: &str = "microdroid_kernel";
const INITRD_NORMAL_IMG_PATH: &str = "microdroid_initrd_normal.img";
const INITRD_DEBUG_IMG_PATH: &str = "microdroid_initrd_debuggable.img";
+const TRUSTY_SECURITY_VM_KERNEL_IMG_PATH: &str = "trusty_security_vm_signed";
const PUBLIC_KEY_RSA4096_PATH: &str = "data/testkey_rsa4096_pub.bin";
pub const PUBLIC_KEY_RSA2048_PATH: &str = "data/testkey_rsa2048_pub.bin";
@@ -60,6 +61,10 @@
Ok(fs::read(MICRODROID_KERNEL_IMG_PATH)?)
}
+pub fn load_latest_trusty_security_vm_signed_kernel() -> Result<Vec<u8>> {
+ Ok(fs::read(TRUSTY_SECURITY_VM_KERNEL_IMG_PATH)?)
+}
+
pub fn load_latest_initrd_normal() -> Result<Vec<u8>> {
Ok(fs::read(INITRD_NORMAL_IMG_PATH)?)
}
@@ -134,6 +139,35 @@
Ok(())
}
+pub fn assert_payload_without_initrd_passes_verification(
+ kernel: &[u8],
+ salt: &[u8],
+ expected_rollback_index: u64,
+) -> Result<()> {
+ let public_key = load_trusted_public_key()?;
+ let verified_boot_data = verify_payload(
+ kernel,
+ None, // initrd
+ &public_key,
+ )
+ .map_err(|e| anyhow!("Verification failed. Error: {}", e))?;
+
+ let footer = extract_avb_footer(kernel)?;
+ let kernel_digest =
+ hash(&[&hash(&[salt]), &kernel[..usize::try_from(footer.original_image_size)?]]);
+ let expected_boot_data = VerifiedBootData {
+ debug_level: DebugLevel::None,
+ kernel_digest,
+ initrd_digest: None,
+ public_key: &public_key,
+ capabilities: vec![],
+ rollback_index: expected_rollback_index,
+ };
+ assert_eq!(expected_boot_data, verified_boot_data);
+
+ Ok(())
+}
+
pub fn hash(inputs: &[&[u8]]) -> Digest {
let mut digester = sha::Sha256::new();
inputs.iter().for_each(|input| digester.update(input));