Merge "[dice] Replace DiceContext with OwnedDiceArtifacts in microdroid"
diff --git a/microdroid_manager/src/dice.rs b/microdroid_manager/src/dice.rs
index cf5e73e..9a2648f 100644
--- a/microdroid_manager/src/dice.rs
+++ b/microdroid_manager/src/dice.rs
@@ -17,7 +17,7 @@
use anyhow::{bail, Context, Error, Result};
use byteorder::{NativeEndian, ReadBytesExt};
use diced_open_dice::{
- retry_bcc_main_flow, Config, DiceMode, Hash, Hidden, InputValues, OwnedDiceArtifacts, CDI_SIZE,
+ retry_bcc_main_flow, Cdi, Config, DiceMode, Hash, Hidden, InputValues, OwnedDiceArtifacts,
};
use keystore2_crypto::ZVec;
use libc::{c_void, mmap, munmap, MAP_FAILED, MAP_PRIVATE, PROT_READ};
@@ -29,33 +29,16 @@
use std::ptr::null_mut;
use std::slice;
-/// Artifacts that are kept in the process address space after the artifacts from the driver have
-/// been consumed.
-/// TODO(b/267575445): Replace with `OwnedDiceArtifacts` from the library `diced_open_dice`.
-pub struct DiceContext {
- pub cdi_attest: [u8; CDI_SIZE],
- pub cdi_seal: [u8; CDI_SIZE],
- pub bcc: Vec<u8>,
-}
-
-impl From<OwnedDiceArtifacts> for DiceContext {
- fn from(dice_artifacts: OwnedDiceArtifacts) -> Self {
- Self {
- cdi_attest: dice_artifacts.cdi_values.cdi_attest,
- cdi_seal: dice_artifacts.cdi_values.cdi_seal,
- bcc: dice_artifacts.bcc[..].to_vec(),
- }
- }
-}
-
-impl DiceContext {
- pub fn get_sealing_key(&self, salt: &[u8], identifier: &[u8], keysize: u32) -> Result<ZVec> {
- // Deterministically derive a key to use for sealing data based on salt. Use different salt
- // for different keys.
- let mut key = ZVec::new(keysize as usize)?;
- hkdf(&mut key, Md::sha256(), &self.cdi_seal, salt, identifier)?;
- Ok(key)
- }
+/// Derives a sealing key from the DICE sealing CDI.
+pub fn derive_sealing_key(
+ cdi_seal: &Cdi,
+ 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)
}
/// Artifacts that are mapped into the process address space from the driver.
@@ -64,11 +47,11 @@
driver_path: PathBuf,
mmap_addr: *mut c_void,
mmap_size: usize,
- cdi_attest: &'a [u8; CDI_SIZE],
- cdi_seal: &'a [u8; CDI_SIZE],
+ cdi_attest: &'a Cdi,
+ cdi_seal: &'a Cdi,
bcc: &'a [u8],
},
- Fake(DiceContext),
+ Fake(OwnedDiceArtifacts),
}
impl DiceDriver<'_> {
@@ -81,7 +64,7 @@
log::warn!("Using sample DICE values");
let dice_artifacts = diced_sample_inputs::make_sample_bcc_and_cdis()
.expect("Failed to create sample dice artifacts.");
- return Ok(Self::Fake(dice_artifacts.into()));
+ return Ok(Self::Fake(dice_artifacts));
};
let mut file = fs::File::open(driver_path)
@@ -133,12 +116,10 @@
// input key material is already cryptographically strong.
let cdi_seal = match self {
Self::Real { cdi_seal, .. } => cdi_seal,
- Self::Fake(fake) => &fake.cdi_seal,
+ Self::Fake(fake) => &fake.cdi_values.cdi_seal,
};
let salt = &[];
- let mut key = ZVec::new(32)?;
- hkdf(&mut key, Md::sha256(), cdi_seal, salt, identifier)?;
- Ok(key)
+ derive_sealing_key(cdi_seal, salt, identifier, 32)
}
pub fn derive(
@@ -148,7 +129,7 @@
authority_hash: Hash,
debug: bool,
hidden: Hidden,
- ) -> Result<DiceContext> {
+ ) -> Result<OwnedDiceArtifacts> {
let input_values = InputValues::new(
code_hash,
Config::Descriptor(config_desc),
@@ -158,7 +139,9 @@
);
let (cdi_attest, cdi_seal, bcc) = match &self {
Self::Real { cdi_attest, cdi_seal, bcc, .. } => (*cdi_attest, *cdi_seal, *bcc),
- Self::Fake(fake) => (&fake.cdi_attest, &fake.cdi_seal, fake.bcc.as_slice()),
+ 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")?;
@@ -168,7 +151,7 @@
fs::write(driver_path, "wipe")
.map_err(|err| Error::new(err).context("Wiping driver"))?;
}
- Ok(dice_artifacts.into())
+ Ok(dice_artifacts)
}
}
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 777a42c..7ca0d3c 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -21,7 +21,7 @@
mod swap;
mod vm_payload_service;
-use crate::dice::{DiceContext, DiceDriver};
+use crate::dice::{DiceDriver, derive_sealing_key};
use crate::instance::{ApexData, ApkData, InstanceDisk, MicrodroidData, RootHash};
use crate::vm_payload_service::register_vm_payload_service;
use android_system_virtualizationcommon::aidl::android::system::virtualizationcommon::ErrorCode::ErrorCode;
@@ -34,6 +34,7 @@
use anyhow::{anyhow, bail, ensure, Context, Error, Result};
use apkverify::{get_public_key_der, verify, V4Signature};
use binder::Strong;
+use diced_open_dice::OwnedDiceArtifacts;
use diced_utils::cbor::{encode_header, encode_number};
use glob::glob;
use itertools::sorted;
@@ -88,7 +89,7 @@
const ENCRYPTEDSTORE_BACKING_DEVICE: &str = "/dev/block/by-name/encryptedstore";
const ENCRYPTEDSTORE_KEY_IDENTIFIER: &str = "encryptedstore_key";
-const ENCRYPTEDSTORE_KEYSIZE: u32 = 32;
+const ENCRYPTEDSTORE_KEYSIZE: usize = 32;
#[derive(thiserror::Error, Debug)]
enum MicrodroidError {
@@ -268,7 +269,7 @@
dice: DiceDriver,
verified_data: &MicrodroidData,
payload_metadata: &PayloadMetadata,
-) -> Result<DiceContext> {
+) -> Result<OwnedDiceArtifacts> {
// Calculate compound digests of code and authorities
let mut code_hash_ctx = Sha512::new();
let mut authority_hash_ctx = Sha512::new();
@@ -413,12 +414,12 @@
// To minimize the exposure to untrusted data, derive dice profile as soon as possible.
info!("DICE derivation for payload");
- let dice_context = dice_derivation(dice, &verified_data, &payload_metadata)?;
+ let dice_artifacts = dice_derivation(dice, &verified_data, &payload_metadata)?;
// Run encryptedstore binary to prepare the storage
let encryptedstore_child = if Path::new(ENCRYPTEDSTORE_BACKING_DEVICE).exists() {
info!("Preparing encryptedstore ...");
- Some(prepare_encryptedstore(&dice_context).context("encryptedstore run")?)
+ Some(prepare_encryptedstore(&dice_artifacts).context("encryptedstore run")?)
} else {
None
};
@@ -473,7 +474,7 @@
// Wait until zipfuse has mounted the APKs so we can access the payload
zipfuse.wait_until_done()?;
- register_vm_payload_service(allow_restricted_apis, service.clone(), dice_context)?;
+ register_vm_payload_service(allow_restricted_apis, service.clone(), dice_artifacts)?;
// Wait for encryptedstore to finish mounting the storage (if enabled) before setting
// microdroid_manager.init_done. Reason is init stops uneventd after that.
@@ -907,7 +908,7 @@
buf.iter().map(|b| format!("{:02X}", b)).collect()
}
-fn prepare_encryptedstore(dice: &DiceContext) -> Result<Child> {
+fn prepare_encryptedstore(dice_artifacts: &OwnedDiceArtifacts) -> Result<Child> {
// Use a fixed salt to scope the derivation to this API.
// Generated using hexdump -vn32 -e'14/1 "0x%02X, " 1 "\n"' /dev/urandom
// TODO(b/241541860) : Move this (& other salts) to a salt container, i.e. a global enum
@@ -916,7 +917,8 @@
0x6F, 0xB3, 0xF9, 0x40, 0xCE, 0xDD, 0x99, 0x40, 0xAA, 0xA7, 0x0E, 0x92, 0x73, 0x90, 0x86,
0x4A, 0x75,
];
- let key = dice.get_sealing_key(
+ let key = derive_sealing_key(
+ &dice_artifacts.cdi_values.cdi_seal,
&salt,
ENCRYPTEDSTORE_KEY_IDENTIFIER.as_bytes(),
ENCRYPTEDSTORE_KEYSIZE,
diff --git a/microdroid_manager/src/vm_payload_service.rs b/microdroid_manager/src/vm_payload_service.rs
index 98b9f2b..ac8f60a 100644
--- a/microdroid_manager/src/vm_payload_service.rs
+++ b/microdroid_manager/src/vm_payload_service.rs
@@ -14,12 +14,12 @@
//! Implementation of the AIDL interface `IVmPayloadService`.
-use crate::dice::DiceContext;
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 log::{error, info};
use openssl::hkdf::hkdf;
use openssl::md::Md;
@@ -29,7 +29,7 @@
struct VmPayloadService {
allow_restricted_apis: bool,
virtual_machine_service: Strong<dyn IVirtualMachineService>,
- dice: DiceContext,
+ dice: OwnedDiceArtifacts,
}
impl IVmPayloadService for VmPayloadService {
@@ -48,10 +48,11 @@
0xB7, 0xA8, 0x43, 0x92,
];
let mut secret = vec![0; size.try_into().unwrap()];
- hkdf(&mut secret, Md::sha256(), &self.dice.cdi_seal, &salt, identifier).map_err(|e| {
- error!("Failed to derive VM instance secret: {:?}", e);
- Status::new_service_specific_error(-1, None)
- })?;
+ 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)
+ })?;
Ok(secret)
}
@@ -62,7 +63,7 @@
fn getDiceAttestationCdi(&self) -> binder::Result<Vec<u8>> {
self.check_restricted_apis_allowed()?;
- Ok(self.dice.cdi_attest.to_vec())
+ Ok(self.dice.cdi_values.cdi_attest.to_vec())
}
}
@@ -73,7 +74,7 @@
fn new(
allow_restricted_apis: bool,
vm_service: Strong<dyn IVirtualMachineService>,
- dice: DiceContext,
+ dice: OwnedDiceArtifacts,
) -> Self {
Self { allow_restricted_apis, virtual_machine_service: vm_service, dice }
}
@@ -92,7 +93,7 @@
pub(crate) fn register_vm_payload_service(
allow_restricted_apis: bool,
vm_service: Strong<dyn IVirtualMachineService>,
- dice: DiceContext,
+ dice: OwnedDiceArtifacts,
) -> Result<()> {
let vm_payload_binder = BnVmPayloadService::new_binder(
VmPayloadService::new(allow_restricted_apis, vm_service, dice),