Add DiceDrive::from_file factory method
This new function will be used in microdroid_manager to read the dice
chain written during first_stage_init for Microdroid VMs with microdroid
vendor partition.
This patch also adds a simple unit test to ensure that a dice chain read
from the file is equal to the one written to it.
Bug: 287593065
Test: atest libdice_driver_test
Change-Id: I5fa10a4b405b23f2c1980a920f0e72077623c01c
diff --git a/libs/dice/driver/src/lib.rs b/libs/dice/driver/src/lib.rs
index ec87ae2..79edb51 100644
--- a/libs/dice/driver/src/lib.rs
+++ b/libs/dice/driver/src/lib.rs
@@ -32,7 +32,7 @@
/// Artifacts that are mapped into the process address space from the driver.
pub enum DiceDriver<'a> {
- /// Real implementation
+ /// Implementation that reads bcc handover from the dice driver.
Real {
/// Path to the driver character device (e.g. /dev/open-dice0).
driver_path: PathBuf,
@@ -45,6 +45,13 @@
},
/// Fake implementation used in tests and non-protected VMs.
Fake(OwnedDiceArtifacts),
+ /// Implementation that reads bcc handover from the file.
+ FromFile {
+ /// Path to the file to read dice chain from,
+ file_path: PathBuf,
+ /// Dice artifacts read from file_path,
+ dice_artifacts: OwnedDiceArtifacts,
+ },
}
impl DiceDriver<'_> {
@@ -52,6 +59,7 @@
match self {
Self::Real { bcc_handover, .. } => bcc_handover,
Self::Fake(owned_dice_artifacts) => owned_dice_artifacts,
+ Self::FromFile { dice_artifacts, .. } => dice_artifacts,
}
}
@@ -97,6 +105,15 @@
})
}
+ /// Create a new dice driver that reads dice_artifacts from the given file.
+ pub fn from_file(file_path: &Path) -> Result<Self> {
+ let file =
+ fs::File::open(file_path).map_err(|error| Error::new(error).context("open file"))?;
+ let dice_artifacts = serde_cbor::from_reader(file)
+ .map_err(|error| Error::new(error).context("read file"))?;
+ Ok(Self::FromFile { file_path: file_path.to_path_buf(), dice_artifacts })
+ }
+
/// Derives a sealing key of `key_length` bytes from the DICE sealing CDI.
pub fn get_sealing_key(&self, identifier: &[u8], key_length: usize) -> Result<ZVec> {
// Deterministically derive a key to use for sealing data, rather than using the CDI
@@ -155,3 +172,36 @@
}
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ fn assert_eq_bytes(expected: &[u8], actual: &[u8]) {
+ assert_eq!(
+ expected,
+ actual,
+ "Expected {}, got {}",
+ hex::encode(expected),
+ hex::encode(actual)
+ )
+ }
+
+ #[test]
+ fn test_write_bcc_to_file_read_from_file() -> Result<()> {
+ let dice_artifacts = diced_sample_inputs::make_sample_bcc_and_cdis()?;
+
+ let test_file = tempfile::NamedTempFile::new()?;
+ serde_cbor::to_writer(test_file.as_file(), &dice_artifacts)?;
+ test_file.as_file().sync_all()?;
+
+ let dice = DiceDriver::from_file(test_file.as_ref())?;
+
+ let dice_artifacts2 = dice.dice_artifacts();
+ assert_eq_bytes(dice_artifacts.cdi_attest(), dice_artifacts2.cdi_attest());
+ assert_eq_bytes(dice_artifacts.cdi_seal(), dice_artifacts2.cdi_seal());
+ assert_eq_bytes(dice_artifacts.bcc().expect("bcc"), dice_artifacts2.bcc().expect("bcc"));
+
+ Ok(())
+ }
+}