[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/src/dice.rs b/pvmfw/src/dice.rs
index b322850..d1ea5f0 100644
--- a/pvmfw/src/dice.rs
+++ b/pvmfw/src/dice.rs
@@ -15,24 +15,40 @@
//! Support for DICE derivation and BCC generation.
use core::ffi::CStr;
-
+use core::mem::size_of;
use dice::bcc::format_config_descriptor;
use dice::bcc::Handover;
use dice::hash;
use dice::ConfigType;
use dice::InputValues;
+use pvmfw_avb::{DebugLevel, Digest, VerifiedBootData};
+
+fn to_dice_mode(debug_level: DebugLevel) -> dice::Mode {
+ match debug_level {
+ DebugLevel::None => dice::Mode::Normal,
+ DebugLevel::Full => dice::Mode::Debug,
+ }
+}
+
+fn to_dice_hash(verified_boot_data: &VerifiedBootData) -> dice::Result<dice::Hash> {
+ let mut digests = [0u8; size_of::<Digest>() * 2];
+ digests[..size_of::<Digest>()].copy_from_slice(&verified_boot_data.kernel_digest);
+ if let Some(initrd_digest) = verified_boot_data.initrd_digest {
+ digests[size_of::<Digest>()..].copy_from_slice(&initrd_digest);
+ }
+ hash(&digests)
+}
/// Derive the VM-specific secrets and certificate through DICE.
pub fn derive_next_bcc(
bcc: &Handover,
next_bcc: &mut [u8],
- code: &[u8],
- debug_mode: bool,
+ verified_boot_data: &VerifiedBootData,
authority: &[u8],
) -> dice::Result<usize> {
- let code_hash = hash(code)?;
+ let code_hash = to_dice_hash(verified_boot_data)?;
let auth_hash = hash(authority)?;
- let mode = if debug_mode { dice::Mode::Debug } else { dice::Mode::Normal };
+ let mode = to_dice_mode(verified_boot_data.debug_level);
let component_name = CStr::from_bytes_with_nul(b"vm_entry\0").unwrap();
let mut config_descriptor_buffer = [0; 128];
let config_descriptor_size = format_config_descriptor(
diff --git a/pvmfw/src/main.rs b/pvmfw/src/main.rs
index eabdfe8..b343e7b 100644
--- a/pvmfw/src/main.rs
+++ b/pvmfw/src/main.rs
@@ -78,28 +78,11 @@
let mut pci_root = pci::initialise(pci_info, memory)?;
find_virtio_devices(&mut pci_root).map_err(handle_pci_error)?;
- verify_payload(signed_kernel, ramdisk, PUBLIC_KEY).map_err(|e| {
+ let verified_boot_data = verify_payload(signed_kernel, ramdisk, PUBLIC_KEY).map_err(|e| {
error!("Failed to verify the payload: {e}");
RebootReason::PayloadVerificationError
})?;
- let debug_mode = false; // TODO(b/256148034): Derive the DICE mode from the received initrd.
- const HASH_SIZE: usize = 64;
- let mut hashes = [0; HASH_SIZE * 2]; // TODO(b/256148034): Extract AvbHashDescriptor digests.
- hashes[..HASH_SIZE].copy_from_slice(&::dice::hash(signed_kernel).map_err(|_| {
- error!("Failed to hash the kernel");
- RebootReason::InternalError
- })?);
- // Note: Using signed_kernel currently makes the DICE code input depend on its VBMeta fields.
- let code_hash = if let Some(rd) = ramdisk {
- hashes[HASH_SIZE..].copy_from_slice(&::dice::hash(rd).map_err(|_| {
- error!("Failed to hash the ramdisk");
- RebootReason::InternalError
- })?);
- &hashes[..]
- } else {
- &hashes[..HASH_SIZE]
- };
let next_bcc = heap::aligned_boxed_slice(NEXT_BCC_SIZE, GUEST_PAGE_SIZE).ok_or_else(|| {
error!("Failed to allocate the next-stage BCC");
RebootReason::InternalError
@@ -107,7 +90,7 @@
// By leaking the slice, its content will be left behind for the next stage.
let next_bcc = Box::leak(next_bcc);
let next_bcc_size =
- derive_next_bcc(bcc, next_bcc, code_hash, debug_mode, PUBLIC_KEY).map_err(|e| {
+ derive_next_bcc(bcc, next_bcc, &verified_boot_data, PUBLIC_KEY).map_err(|e| {
error!("Failed to derive next-stage DICE secrets: {e:?}");
RebootReason::SecretDerivationError
})?;