Merge "Fix some warnings"
diff --git a/encryptedstore/src/main.rs b/encryptedstore/src/main.rs
index 96c80db..7a41f13 100644
--- a/encryptedstore/src/main.rs
+++ b/encryptedstore/src/main.rs
@@ -95,6 +95,8 @@
         .data_device(data_device, dev_size)
         .cipher(CipherType::AES256HCTR2)
         .key(&key)
+        .opt_param("sector_size:4096")
+        .opt_param("iv_large_sectors")
         .build()
         .context("Couldn't build the DMCrypt target")?;
     let dm = dm::DeviceMapper::new()?;
@@ -125,6 +127,7 @@
     let mkfs_options = [
         "-j",               // Create appropriate sized journal
         "-O metadata_csum", // Metadata checksum for filesystem integrity
+        "-b 4096",          // block size in the filesystem
     ];
     let mut cmd = Command::new(MK2FS_BIN);
     let status = cmd
diff --git a/libs/devicemapper/src/crypt.rs b/libs/devicemapper/src/crypt.rs
index b2e677a..8281b34 100644
--- a/libs/devicemapper/src/crypt.rs
+++ b/libs/devicemapper/src/crypt.rs
@@ -76,7 +76,7 @@
     device_path: Option<&'a Path>,
     offset: u64,
     device_size: u64,
-    // TODO(b/238179332) Extend this to include opt_params, in particular 'integrity'
+    opt_params: Vec<&'a str>,
 }
 
 impl<'a> Default for DmCryptTargetBuilder<'a> {
@@ -88,6 +88,7 @@
             device_path: None,
             offset: 0,
             device_size: 0,
+            opt_params: Vec::new(),
         }
     }
 }
@@ -124,6 +125,12 @@
         self
     }
 
+    /// Add additional optional parameter
+    pub fn opt_param(&mut self, param: &'a str) -> &mut Self {
+        self.opt_params.push(param);
+        self
+    }
+
     /// Constructs a `DmCryptTarget`.
     pub fn build(&self) -> Result<DmCryptTarget> {
         // The `DmCryptTarget` struct actually is a flattened data consisting of a header and
@@ -154,6 +161,7 @@
         write!(&mut body, "{} ", self.iv_offset)?;
         write!(&mut body, "{} ", device_path)?;
         write!(&mut body, "{} ", self.offset)?;
+        write!(&mut body, "{} {} ", self.opt_params.len(), self.opt_params.join(" "))?;
         write!(&mut body, "\0")?; // null terminator
 
         let size = size_of::<DmTargetSpec>() + body.len();
diff --git a/microdroid/Android.bp b/microdroid/Android.bp
index 9264692..dc59fff 100644
--- a/microdroid/Android.bp
+++ b/microdroid/Android.bp
@@ -85,9 +85,12 @@
         "microdroid_property_contexts",
         "mke2fs.microdroid",
 
-        // TODO(b/195425111) these should be added automatically
-        "libcrypto", // used by many (init_second_stage, microdroid_manager, toybox, etc)
-        "liblzma", // used by init_second_stage
+        // Adding more libs manually for unbundled build.
+        // TODO(b/268557568) these should be added automatically.
+        "libcrypto",
+        "liblzma",
+        "libc++",
+        "libssl",
 
         "libvm_payload", // used by payload to interact with microdroid manager
 
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),