[avb] Collect kernel/initrd digests when verification succeeds

Bug: 265897559
Test: m pvmfw_img && atest libpvmfw_avb.integration_test
Change-Id: I6f281090d0f53464824d80e1348f4d099330ad31
diff --git a/pvmfw/avb/src/descriptor.rs b/pvmfw/avb/src/descriptor.rs
index b0598de..c54d416 100644
--- a/pvmfw/avb/src/descriptor.rs
+++ b/pvmfw/avb/src/descriptor.rs
@@ -31,7 +31,8 @@
 };
 use tinyvec::ArrayVec;
 
-const DIGEST_SIZE: usize = AVB_SHA256_DIGEST_SIZE as usize;
+/// Digest type for kernel and initrd.
+pub type Digest = [u8; AVB_SHA256_DIGEST_SIZE as usize];
 
 /// `HashDescriptors` can have maximum one `HashDescriptor` per known partition.
 #[derive(Default)]
@@ -132,9 +133,7 @@
 #[derive(Default)]
 pub(crate) struct HashDescriptor {
     partition_name: PartitionName,
-    /// TODO(b/265897559): Pass this digest to DICE.
-    #[allow(dead_code)]
-    pub(crate) digest: [u8; DIGEST_SIZE],
+    pub(crate) digest: Digest,
 }
 
 impl HashDescriptor {
@@ -145,7 +144,7 @@
             .try_into()?;
         let partition_digest =
             data.get(desc.digest_range()?).ok_or(AvbIOError::RangeOutsidePartition)?;
-        let mut digest = [0u8; DIGEST_SIZE];
+        let mut digest = [0u8; size_of::<Digest>()];
         digest.copy_from_slice(partition_digest);
         Ok(Self { partition_name, digest })
     }
diff --git a/pvmfw/avb/src/lib.rs b/pvmfw/avb/src/lib.rs
index 065eca5..8fea162 100644
--- a/pvmfw/avb/src/lib.rs
+++ b/pvmfw/avb/src/lib.rs
@@ -25,5 +25,6 @@
 mod utils;
 mod verify;
 
+pub use descriptor::Digest;
 pub use error::AvbSlotVerifyError;
-pub use verify::{verify_payload, DebugLevel};
+pub use verify::{verify_payload, DebugLevel, VerifiedBootData};
diff --git a/pvmfw/avb/src/partition.rs b/pvmfw/avb/src/partition.rs
index 636bfd3..bc63003 100644
--- a/pvmfw/avb/src/partition.rs
+++ b/pvmfw/avb/src/partition.rs
@@ -18,7 +18,7 @@
 use crate::utils::is_not_null;
 use core::ffi::{c_char, CStr};
 
-#[derive(Clone, Debug, Default, PartialEq, Eq)]
+#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
 pub(crate) enum PartitionName {
     /// The default `PartitionName` is needed to build the default `HashDescriptor`.
     #[default]
diff --git a/pvmfw/avb/src/verify.rs b/pvmfw/avb/src/verify.rs
index 14b0e7e..1a79c83 100644
--- a/pvmfw/avb/src/verify.rs
+++ b/pvmfw/avb/src/verify.rs
@@ -14,15 +14,26 @@
 
 //! This module handles the pvmfw payload verification.
 
-use crate::descriptor::HashDescriptors;
+use crate::descriptor::{Digest, HashDescriptors};
 use crate::error::AvbSlotVerifyError;
 use crate::ops::{Ops, Payload};
 use crate::partition::PartitionName;
 use avb_bindgen::{AvbPartitionData, AvbVBMetaData};
 use core::ffi::c_char;
 
+/// Verified data returned when the payload verification succeeds.
+#[derive(Debug)]
+pub struct VerifiedBootData {
+    /// DebugLevel of the VM.
+    pub debug_level: DebugLevel,
+    /// Kernel digest.
+    pub kernel_digest: Digest,
+    /// Initrd digest if initrd exists.
+    pub initrd_digest: Option<Digest>,
+}
+
 /// This enum corresponds to the `DebugLevel` in `VirtualMachineConfig`.
-#[derive(Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
 pub enum DebugLevel {
     /// Not debuggable at all.
     None,
@@ -87,7 +98,7 @@
     kernel: &[u8],
     initrd: Option<&[u8]>,
     trusted_public_key: &[u8],
-) -> Result<DebugLevel, AvbSlotVerifyError> {
+) -> Result<VerifiedBootData, AvbSlotVerifyError> {
     let mut payload = Payload::new(kernel, initrd, trusted_public_key);
     let mut ops = Ops::from(&mut payload);
     let kernel_verify_result = ops.verify_partition(PartitionName::Kernel.as_cstr())?;
@@ -100,12 +111,15 @@
     // which is returned by `avb_slot_verify()` when the verification succeeds. It is
     // guaranteed by libavb to be non-null and to point to a valid VBMeta structure.
     let hash_descriptors = unsafe { HashDescriptors::from_vbmeta(vbmeta_image)? };
-    // TODO(b/265897559): Pass the digest in kernel descriptor to DICE.
-    let _kernel_descriptor = hash_descriptors.find(PartitionName::Kernel)?;
+    let kernel_descriptor = hash_descriptors.find(PartitionName::Kernel)?;
 
     if initrd.is_none() {
         verify_vbmeta_has_only_one_hash_descriptor(&hash_descriptors)?;
-        return Ok(DebugLevel::None);
+        return Ok(VerifiedBootData {
+            debug_level: DebugLevel::None,
+            kernel_digest: kernel_descriptor.digest,
+            initrd_digest: None,
+        });
     }
 
     let initrd = initrd.unwrap();
@@ -123,5 +137,10 @@
         initrd_partition_name,
         initrd.len(),
     )?;
-    Ok(debug_level)
+    let initrd_descriptor = hash_descriptors.find(initrd_partition_name)?;
+    Ok(VerifiedBootData {
+        debug_level,
+        kernel_digest: kernel_descriptor.digest,
+        initrd_digest: Some(initrd_descriptor.digest),
+    })
 }