Actually derive microdroid vendor dice node

The derive_microdroid_vendor_dice_node binary gets the current dice
chain from the /dev/open-dice0 driver, derives the new dice chain with
the microdroid vendor node and writes it to the
/microdroid_resources/dice_chain.raw file.

The microdroid_manager will read the dice chain from
/microdroid_resources/dice_chain.raw and derive the final dice chain
with the payload node. After the derivation is done, microdroid_manager
will delete the /microdroid_resources/dice_chain.raw file.

Additionally, since /microdroid_resources is mounted in first_stage_init
which happens before selinux is configured, we also call the
restorecon_recursive /microdroid_resources before starting
microdroid_manager to make sure that the /microdroid_resources and
/microdroid_resources/dice_chain.raw have correct context.

Bug: 287593065
Test: run microdroid with vendor partition
Test: atest MicrodroidTests
Change-Id: Ibeb05b0ed24610624b11ac2c3e907cc900bd4cab
diff --git a/libs/dice/driver/src/lib.rs b/libs/dice/driver/src/lib.rs
index 79edb51..b5c1f12 100644
--- a/libs/dice/driver/src/lib.rs
+++ b/libs/dice/driver/src/lib.rs
@@ -65,6 +65,7 @@
 
     /// Creates a new dice driver from the given driver_path.
     pub fn new(driver_path: &Path, is_strict_boot: bool) -> Result<Self> {
+        log::info!("Creating DiceDriver backed by {driver_path:?} driver");
         if driver_path.exists() {
             log::info!("Using DICE values from driver");
         } else if is_strict_boot {
@@ -107,6 +108,7 @@
 
     /// Create a new dice driver that reads dice_artifacts from the given file.
     pub fn from_file(file_path: &Path) -> Result<Self> {
+        log::info!("Creating DiceDriver backed by {file_path:?} file");
         let file =
             fs::File::open(file_path).map_err(|error| Error::new(error).context("open file"))?;
         let dice_artifacts = serde_cbor::from_reader(file)
@@ -149,11 +151,18 @@
             &input_values,
         )
         .context("DICE derive from driver")?;
-        if let Self::Real { driver_path, .. } = &self {
-            // Writing to the device wipes the artifacts. The string is ignored by the driver but
-            // included for documentation.
-            fs::write(driver_path, "wipe")
-                .map_err(|err| Error::new(err).context("Wiping driver"))?;
+        match &self {
+            Self::Real { driver_path, .. } => {
+                // Writing to the device wipes the artifacts. The string is ignored by the driver
+                // but included for documentation.
+                fs::write(driver_path, "wipe")
+                    .map_err(|err| Error::new(err).context("Wiping driver"))?;
+            }
+            Self::FromFile { file_path, .. } => {
+                fs::remove_file(file_path)
+                    .map_err(|err| Error::new(err).context("Deleting file"))?;
+            }
+            Self::Fake { .. } => (),
         }
         Ok(next_dice_artifacts)
     }
@@ -176,6 +185,11 @@
 #[cfg(test)]
 mod tests {
     use super::*;
+    use core::ffi::CStr;
+    use diced_open_dice::{
+        hash, retry_bcc_format_config_descriptor, DiceConfigValues, HIDDEN_SIZE,
+    };
+    use std::fs::File;
 
     fn assert_eq_bytes(expected: &[u8], actual: &[u8]) {
         assert_eq!(
@@ -204,4 +218,34 @@
 
         Ok(())
     }
+
+    #[test]
+    fn test_dice_driver_from_file_deletes_file_after_derive() -> Result<()> {
+        let tmp_dir = tempfile::tempdir()?;
+
+        let file_path = tmp_dir.path().join("test-dice-chain.raw");
+
+        {
+            let dice_artifacts = diced_sample_inputs::make_sample_bcc_and_cdis()?;
+            let file = File::create(&file_path)?;
+            serde_cbor::to_writer(file, &dice_artifacts)?;
+        }
+
+        let dice = DiceDriver::from_file(&file_path)?;
+
+        let values = DiceConfigValues {
+            component_name: Some(CStr::from_bytes_with_nul(b"test\0")?),
+            ..Default::default()
+        };
+        let desc = retry_bcc_format_config_descriptor(&values)?;
+        let code_hash = hash(&String::from("test code hash").into_bytes())?;
+        let authority_hash = hash(&String::from("test authority hash").into_bytes())?;
+        let hidden = [0; HIDDEN_SIZE];
+
+        let _ = dice.derive(code_hash, &desc, authority_hash, false, hidden)?;
+
+        assert!(!file_path.exists());
+
+        Ok(())
+    }
 }