[dice][microdroid] Refactor DiceDriver with the trait DiceArtifacts

This cl uses DiceArtifacts to unify the access to DICE values like
CDIs or BCC in DiceDriver.

There is no behavior change in this cl.

Test: atest MicrodroidTests
Bug: 267575445
Change-Id: I5214db2637ad51f9777ecabc9b631933890248ab
diff --git a/microdroid_manager/src/dice.rs b/microdroid_manager/src/dice.rs
index fd22198..c3136e8 100644
--- a/microdroid_manager/src/dice.rs
+++ b/microdroid_manager/src/dice.rs
@@ -17,8 +17,8 @@
 use anyhow::{anyhow, bail, Context, Error, Result};
 use byteorder::{NativeEndian, ReadBytesExt};
 use diced_open_dice::{
-    bcc_handover_parse, retry_bcc_main_flow, BccHandover, Cdi, Config, DiceMode, Hash, Hidden,
-    InputValues, OwnedDiceArtifacts,
+    bcc_handover_parse, retry_bcc_main_flow, BccHandover, Config, DiceArtifacts, DiceMode, Hash,
+    Hidden, InputValues, OwnedDiceArtifacts,
 };
 use keystore2_crypto::ZVec;
 use libc::{c_void, mmap, munmap, MAP_FAILED, MAP_PRIVATE, PROT_READ};
@@ -32,14 +32,12 @@
 
 /// Derives a sealing key from the DICE sealing CDI.
 pub fn derive_sealing_key(
-    cdi_seal: &Cdi,
+    dice_artifacts: &dyn DiceArtifacts,
     salt: &[u8],
     info: &[u8],
-    keysize: usize,
-) -> Result<ZVec> {
-    let mut key = ZVec::new(keysize)?;
-    hkdf(&mut key, Md::sha256(), cdi_seal, salt, info)?;
-    Ok(key)
+    key: &mut [u8],
+) -> Result<()> {
+    Ok(hkdf(key, Md::sha256(), dice_artifacts.cdi_seal(), salt, info)?)
 }
 
 /// Artifacts that are mapped into the process address space from the driver.
@@ -54,6 +52,13 @@
 }
 
 impl DiceDriver<'_> {
+    fn dice_artifacts(&self) -> &dyn DiceArtifacts {
+        match self {
+            Self::Real { bcc_handover, .. } => bcc_handover,
+            Self::Fake(owned_dice_artifacts) => owned_dice_artifacts,
+        }
+    }
+
     pub fn new(driver_path: &Path) -> Result<Self> {
         if driver_path.exists() {
             log::info!("Using DICE values from driver");
@@ -95,16 +100,15 @@
         })
     }
 
-    pub fn get_sealing_key(&self, identifier: &[u8]) -> Result<ZVec> {
+    /// 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
         // directly, so we have the chance to rotate the key if needed. A salt isn't needed as the
         // input key material is already cryptographically strong.
-        let cdi_seal = match self {
-            Self::Real { bcc_handover, .. } => bcc_handover.cdi_seal,
-            Self::Fake(fake) => &fake.cdi_values.cdi_seal,
-        };
+        let mut key = ZVec::new(key_length)?;
         let salt = &[];
-        derive_sealing_key(cdi_seal, salt, identifier, 32)
+        derive_sealing_key(self.dice_artifacts(), salt, identifier, &mut key)?;
+        Ok(key)
     }
 
     pub fn derive(
@@ -122,25 +126,21 @@
             if debug { DiceMode::kDiceModeDebug } else { DiceMode::kDiceModeNormal },
             hidden,
         );
-        let (cdi_attest, cdi_seal, bcc) = match &self {
-            Self::Real { bcc_handover, .. } => (
-                bcc_handover.cdi_attest,
-                bcc_handover.cdi_seal,
-                bcc_handover.bcc.ok_or_else(|| anyhow!("bcc is none"))?,
-            ),
-            Self::Fake(fake) => {
-                (&fake.cdi_values.cdi_attest, &fake.cdi_values.cdi_seal, fake.bcc.as_slice())
-            }
-        };
-        let dice_artifacts = retry_bcc_main_flow(cdi_attest, cdi_seal, bcc, &input_values)
-            .context("DICE derive from driver")?;
+        let current_dice_artifacts = self.dice_artifacts();
+        let next_dice_artifacts = retry_bcc_main_flow(
+            current_dice_artifacts.cdi_attest(),
+            current_dice_artifacts.cdi_seal(),
+            current_dice_artifacts.bcc().ok_or_else(|| anyhow!("bcc is none"))?,
+            &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"))?;
         }
-        Ok(dice_artifacts)
+        Ok(next_dice_artifacts)
     }
 }
 
diff --git a/microdroid_manager/src/instance.rs b/microdroid_manager/src/instance.rs
index 96e9360..6900ea5 100644
--- a/microdroid_manager/src/instance.rs
+++ b/microdroid_manager/src/instance.rs
@@ -142,9 +142,9 @@
         self.file.read_exact(&mut header)?;
 
         // Decrypt and authenticate the data (along with the header).
-        let key = dice.get_sealing_key(INSTANCE_KEY_IDENTIFIER)?;
-        let plaintext =
-            decrypt_aead(Cipher::aes_256_gcm(), &key, Some(&nonce), &header, &data, &tag)?;
+        let cipher = Cipher::aes_256_gcm();
+        let key = dice.get_sealing_key(INSTANCE_KEY_IDENTIFIER, cipher.key_len())?;
+        let plaintext = decrypt_aead(cipher, &key, Some(&nonce), &header, &data, &tag)?;
 
         let microdroid_data = serde_cbor::from_slice(plaintext.as_slice())?;
         Ok(Some(microdroid_data))
@@ -188,10 +188,10 @@
         self.file.write_all(nonce.as_ref())?;
 
         // Then encrypt and sign the data.
-        let key = dice.get_sealing_key(INSTANCE_KEY_IDENTIFIER)?;
+        let cipher = Cipher::aes_256_gcm();
+        let key = dice.get_sealing_key(INSTANCE_KEY_IDENTIFIER, cipher.key_len())?;
         let mut tag = [0; AES_256_GCM_TAG_LENGTH];
-        let ciphertext =
-            encrypt_aead(Cipher::aes_256_gcm(), &key, Some(&nonce), &header, &data, &mut tag)?;
+        let ciphertext = encrypt_aead(cipher, &key, Some(&nonce), &header, &data, &mut tag)?;
 
         // Persist the encrypted payload data and the tag.
         self.file.write_all(&ciphertext)?;
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 7ca0d3c..1148c31 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -40,6 +40,7 @@
 use itertools::sorted;
 use libc::VMADDR_CID_HOST;
 use log::{error, info, warn};
+use keystore2_crypto::ZVec;
 use microdroid_metadata::{write_metadata, Metadata, PayloadMetadata};
 use microdroid_payload_config::{OsConfig, Task, TaskType, VmPayloadConfig};
 use nix::fcntl::{fcntl, F_SETFD, FdFlag};
@@ -917,12 +918,8 @@
         0x6F, 0xB3, 0xF9, 0x40, 0xCE, 0xDD, 0x99, 0x40, 0xAA, 0xA7, 0x0E, 0x92, 0x73, 0x90, 0x86,
         0x4A, 0x75,
     ];
-    let key = derive_sealing_key(
-        &dice_artifacts.cdi_values.cdi_seal,
-        &salt,
-        ENCRYPTEDSTORE_KEY_IDENTIFIER.as_bytes(),
-        ENCRYPTEDSTORE_KEYSIZE,
-    )?;
+    let mut key = ZVec::new(ENCRYPTEDSTORE_KEYSIZE)?;
+    derive_sealing_key(dice_artifacts, &salt, ENCRYPTEDSTORE_KEY_IDENTIFIER.as_bytes(), &mut key)?;
 
     let mut cmd = Command::new(ENCRYPTEDSTORE_BIN);
     cmd.arg("--blkdevice")
diff --git a/microdroid_manager/src/vm_payload_service.rs b/microdroid_manager/src/vm_payload_service.rs
index ac8f60a..96f51f0 100644
--- a/microdroid_manager/src/vm_payload_service.rs
+++ b/microdroid_manager/src/vm_payload_service.rs
@@ -14,15 +14,14 @@
 
 //! Implementation of the AIDL interface `IVmPayloadService`.
 
+use crate::dice::derive_sealing_key;
 use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{
     BnVmPayloadService, IVmPayloadService, VM_PAYLOAD_SERVICE_SOCKET_NAME};
 use android_system_virtualmachineservice::aidl::android::system::virtualmachineservice::IVirtualMachineService::IVirtualMachineService;
 use anyhow::Result;
 use binder::{Interface, BinderFeatures, ExceptionCode, Status, Strong};
-use diced_open_dice::OwnedDiceArtifacts;
+use diced_open_dice::{DiceArtifacts, OwnedDiceArtifacts};
 use log::{error, info};
-use openssl::hkdf::hkdf;
-use openssl::md::Md;
 use rpcbinder::RpcServer;
 
 /// Implementation of `IVmPayloadService`.
@@ -48,22 +47,25 @@
             0xB7, 0xA8, 0x43, 0x92,
         ];
         let mut secret = vec![0; size.try_into().unwrap()];
-        hkdf(&mut secret, Md::sha256(), &self.dice.cdi_values.cdi_seal, &salt, identifier)
-            .map_err(|e| {
-                error!("Failed to derive VM instance secret: {:?}", e);
-                Status::new_service_specific_error(-1, None)
-            })?;
+        derive_sealing_key(&self.dice, &salt, identifier, &mut secret).map_err(|e| {
+            error!("Failed to derive VM instance secret: {:?}", e);
+            Status::new_service_specific_error(-1, None)
+        })?;
         Ok(secret)
     }
 
     fn getDiceAttestationChain(&self) -> binder::Result<Vec<u8>> {
         self.check_restricted_apis_allowed()?;
-        Ok(self.dice.bcc.clone())
+        if let Some(bcc) = self.dice.bcc() {
+            Ok(bcc.to_vec())
+        } else {
+            Err(Status::new_exception_str(ExceptionCode::ILLEGAL_STATE, Some("bcc is none")))
+        }
     }
 
     fn getDiceAttestationCdi(&self) -> binder::Result<Vec<u8>> {
         self.check_restricted_apis_allowed()?;
-        Ok(self.dice.cdi_values.cdi_attest.to_vec())
+        Ok(self.dice.cdi_attest().to_vec())
     }
 }