pvmfw: main: Skip DICE derivation if missing AVB

DICE can only happen with proper inputs, which pvmfw obtains through AVB
so reflect that in the code. Don't pass the DICE handover if to the
guest if none was generated.

This prepares for a future change which will skip AVB.

Note: No function change intended.

Bug: 393977894
Test: m pvmfw
Change-Id: I2be1955236b73b77496141151a78c4c74edd8504
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}");