Merge "pvmfw: main: Skip DICE derivation if missing AVB" into main
diff --git a/guest/pvmfw/src/entry.rs b/guest/pvmfw/src/entry.rs
index 46b1971..8bbbce1 100644
--- a/guest/pvmfw/src/entry.rs
+++ b/guest/pvmfw/src/entry.rs
@@ -144,7 +144,9 @@
         config_entries.vm_dtbo,
         config_entries.vm_ref_dt,
     )?;
-    slices.add_dice_handover(next_dice_handover);
+    if let Some(r) = next_dice_handover {
+        slices.add_dice_handover(r);
+    }
     // Keep UART MMIO_GUARD-ed for debuggable payloads, to enable earlycon.
     let keep_uart = cfg!(debuggable_vms_improvements) && debuggable_payload;
 
diff --git a/guest/pvmfw/src/fdt.rs b/guest/pvmfw/src/fdt.rs
index 8adf8e5..2444b00 100644
--- a/guest/pvmfw/src/fdt.rs
+++ b/guest/pvmfw/src/fdt.rs
@@ -1360,7 +1360,7 @@
 /// Modifies the input DT according to the fields of the configuration.
 pub fn modify_for_next_stage(
     fdt: &mut Fdt,
-    dice_handover: &[u8],
+    dice_handover: Option<&[u8]>,
     new_instance: bool,
     strict_boot: bool,
     debug_policy: Option<&[u8]>,
@@ -1401,14 +1401,18 @@
 }
 
 /// Patch the "google,open-dice"-compatible reserved-memory node to point to the DICE handover.
-fn patch_dice_node(fdt: &mut Fdt, handover: &[u8]) -> libfdt::Result<()> {
+fn patch_dice_node(fdt: &mut Fdt, handover: Option<&[u8]>) -> libfdt::Result<()> {
     // The node is assumed to be present in the template DT.
     let node = fdt.node_mut(c"/reserved-memory")?.ok_or(FdtError::NotFound)?;
     let mut node = node.next_compatible(c"google,open-dice")?.ok_or(FdtError::NotFound)?;
 
-    let addr = (handover.as_ptr() as usize).try_into().unwrap();
-    let size = handover.len().try_into().unwrap();
-    node.setprop_addrrange_inplace(c"reg", addr, size)
+    if let Some(r) = handover {
+        let addr = (r.as_ptr() as usize).try_into().unwrap();
+        let size = r.len().try_into().unwrap();
+        node.setprop_addrrange_inplace(c"reg", addr, size)
+    } else {
+        node.nop()
+    }
 }
 
 fn empty_or_delete_prop(
diff --git a/guest/pvmfw/src/main.rs b/guest/pvmfw/src/main.rs
index f505318..7bf68b8 100644
--- a/guest/pvmfw/src/main.rs
+++ b/guest/pvmfw/src/main.rs
@@ -60,7 +60,7 @@
     mut debug_policy: Option<&[u8]>,
     vm_dtbo: Option<&mut [u8]>,
     vm_ref_dt: Option<&[u8]>,
-) -> Result<(&'a [u8], bool), RebootReason> {
+) -> Result<(Option<&'a [u8]>, bool), RebootReason> {
     info!("pVM firmware");
     debug!("FDT: {:?}", untrusted_fdt.as_ptr());
     debug!("Signed kernel: {:?} ({:#x} bytes)", signed_kernel.as_ptr(), signed_kernel.len());
@@ -81,33 +81,40 @@
         debug_policy = None;
     }
 
-    let (verified_boot_data, debuggable, guest_page_size) =
-        perform_verified_boot(signed_kernel, ramdisk)?;
+    let (verified_boot_data, debuggable, guest_page_size) = {
+        let (dat, debug, sz) = perform_verified_boot(signed_kernel, ramdisk)?;
+        (Some(dat), debug, sz)
+    };
 
     let hyp_page_size = hypervisor_backends::get_granule_size();
     let _ =
         sanitize_device_tree(untrusted_fdt, vm_dtbo, vm_ref_dt, guest_page_size, hyp_page_size)?;
     let fdt = untrusted_fdt; // DT has now been sanitized.
 
-    let instance_hash = salt_from_instance_id(fdt)?;
-    let dice_inputs = PartialInputs::new(&verified_boot_data, instance_hash).map_err(|e| {
-        error!("Failed to compute partial DICE inputs: {e:?}");
-        RebootReason::InternalError
-    })?;
+    let (next_dice_handover, new_instance) = if let Some(ref data) = verified_boot_data {
+        let instance_hash = salt_from_instance_id(fdt)?;
+        let dice_inputs = PartialInputs::new(data, instance_hash).map_err(|e| {
+            error!("Failed to compute partial DICE inputs: {e:?}");
+            RebootReason::InternalError
+        })?;
+        let (new_instance, salt, defer_rollback_protection) =
+            perform_rollback_protection(fdt, data, &dice_inputs, &dice_cdi_seal)?;
+        trace!("Got salt for instance: {salt:x?}");
 
-    let (new_instance, salt, defer_rollback_protection) =
-        perform_rollback_protection(fdt, &verified_boot_data, &dice_inputs, &dice_cdi_seal)?;
-    trace!("Got salt for instance: {salt:x?}");
+        let next_dice_handover = perform_dice_derivation(
+            dice_handover_bytes.as_ref(),
+            dice_context,
+            dice_inputs,
+            &salt,
+            defer_rollback_protection,
+            guest_page_size,
+            guest_page_size,
+        )?;
 
-    let next_dice_handover = perform_dice_derivation(
-        dice_handover_bytes.as_ref(),
-        dice_context,
-        dice_inputs,
-        &salt,
-        defer_rollback_protection,
-        guest_page_size,
-        guest_page_size,
-    )?;
+        (Some(next_dice_handover), new_instance)
+    } else {
+        (None, true)
+    };
 
     let kaslr_seed = u64::from_ne_bytes(rand::random_array().map_err(|e| {
         error!("Failed to generated guest KASLR seed: {e}");