[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));