Add APEX info to the DICE chain

Add subcomponent information for the APEXes in the payload.

Bug: 308759880
Test: composd_cmd test-compile, inspect DICE chain
Change-Id: I2c2b28fdb2d3ae83142b5a381599f86299c524c3
diff --git a/microdroid_manager/src/dice.rs b/microdroid_manager/src/dice.rs
index 6b0775a..e6ddfb9 100644
--- a/microdroid_manager/src/dice.rs
+++ b/microdroid_manager/src/dice.rs
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 use crate::dice_driver::DiceDriver;
-use crate::instance::ApkData;
+use crate::instance::{ApexData, ApkData};
 use crate::{is_debuggable, MicrodroidData};
 use anyhow::{bail, Context, Result};
 use ciborium::{cbor, Value};
@@ -26,24 +26,23 @@
 /// Perform an open DICE derivation for the payload.
 pub fn dice_derivation(
     dice: DiceDriver,
-    verified_data: &MicrodroidData,
+    instance_data: &MicrodroidData,
     payload_metadata: &PayloadMetadata,
 ) -> Result<OwnedDiceArtifacts> {
-    let subcomponents = build_subcomponent_list(verified_data);
-
+    let subcomponents = build_subcomponent_list(instance_data);
     let config_descriptor = format_payload_config_descriptor(payload_metadata, &subcomponents)
         .context("Building config descriptor")?;
 
     // Calculate compound digests of code and authorities
     let mut code_hash_ctx = Sha512::new();
     let mut authority_hash_ctx = Sha512::new();
-    code_hash_ctx.update(verified_data.apk_data.root_hash.as_ref());
-    authority_hash_ctx.update(verified_data.apk_data.pubkey.as_ref());
-    for extra_apk in &verified_data.extra_apks_data {
+    code_hash_ctx.update(instance_data.apk_data.root_hash.as_ref());
+    authority_hash_ctx.update(instance_data.apk_data.pubkey.as_ref());
+    for extra_apk in &instance_data.extra_apks_data {
         code_hash_ctx.update(extra_apk.root_hash.as_ref());
         authority_hash_ctx.update(extra_apk.pubkey.as_ref());
     }
-    for apex in &verified_data.apex_data {
+    for apex in &instance_data.apex_data {
         code_hash_ctx.update(apex.root_digest.as_ref());
         authority_hash_ctx.update(apex.public_key.as_ref());
     }
@@ -54,7 +53,7 @@
     let debuggable = is_debuggable()?;
 
     // Send the details to diced
-    let hidden = verified_data.salt.clone().try_into().unwrap();
+    let hidden = instance_data.salt.clone().try_into().unwrap();
     dice.derive(code_hash, &config_descriptor, authority_hash, debuggable, hidden)
 }
 
@@ -85,17 +84,29 @@
                 Box::new(sha512(&apk.pubkey)),
         }
     }
+
+    fn for_apex(apex: &'a ApexData) -> Self {
+        // Note that this is only reachable if the dice_changes flag is on, in which case
+        // the manifest data will always be present.
+        Self {
+            name: format!("apex:{}", apex.manifest_name.as_ref().unwrap()),
+            version: apex.manifest_version.unwrap() as u64,
+            code_hash: &apex.root_digest,
+            authority_hash: Box::new(sha512(&apex.public_key)),
+        }
+    }
 }
 
-fn build_subcomponent_list(verified_data: &MicrodroidData) -> Vec<Subcomponent> {
+fn build_subcomponent_list(instance_data: &MicrodroidData) -> Vec<Subcomponent> {
     if !cfg!(dice_changes) {
         return vec![];
     }
 
-    once(&verified_data.apk_data)
-        .chain(&verified_data.extra_apks_data)
-        .map(Subcomponent::for_apk)
-        .collect()
+    let apks = once(&instance_data.apk_data)
+        .chain(&instance_data.extra_apks_data)
+        .map(Subcomponent::for_apk);
+    let apexes = instance_data.apex_data.iter().map(Subcomponent::for_apex);
+    apks.chain(apexes).collect()
 }
 
 // Returns a configuration descriptor of the given payload. See vm_config.cddl for a definition
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 1b41e58..9e167a4 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -246,20 +246,20 @@
     }
 
     // Verify the payload before using it.
-    let verified_data = verify_payload(&metadata, saved_data.as_ref())
+    let extracted_data = verify_payload(&metadata, saved_data.as_ref())
         .context("Payload verification failed")
         .map_err(|e| MicrodroidError::PayloadVerificationFailed(e.to_string()))?;
 
     // In case identity is ignored (by debug policy), we should reuse existing payload data, even
     // when the payload is changed. This is to keep the derived secret same as before.
-    let verified_data = if let Some(saved_data) = saved_data {
+    let instance_data = if let Some(saved_data) = saved_data {
         if !is_verified_boot() {
-            if saved_data != verified_data {
+            if saved_data != extracted_data {
                 info!("Detected an update of the payload, but continue (regarding debug policy)")
             }
         } else {
             ensure!(
-                saved_data == verified_data,
+                saved_data == extracted_data,
                 MicrodroidError::PayloadChanged(String::from(
                     "Detected an update of the payload which isn't supported yet."
                 ))
@@ -270,9 +270,9 @@
     } else {
         info!("Saving verified data.");
         instance
-            .write_microdroid_data(&verified_data, &dice)
+            .write_microdroid_data(&extracted_data, &dice)
             .context("Failed to write identity data")?;
-        verified_data
+        extracted_data
     };
 
     let payload_metadata = metadata.payload.ok_or_else(|| {
@@ -281,7 +281,7 @@
 
     // To minimize the exposure to untrusted data, derive dice profile as soon as possible.
     info!("DICE derivation for payload");
-    let dice_artifacts = dice_derivation(dice, &verified_data, &payload_metadata)?;
+    let dice_artifacts = dice_derivation(dice, &instance_data, &payload_metadata)?;
     let vm_secret = VmSecret::new(dice_artifacts).context("Failed to create VM secrets")?;
 
     if cfg!(dice_changes) {
@@ -326,10 +326,10 @@
         .ok_or_else(|| MicrodroidError::PayloadInvalidConfig("No task in VM config".to_string()))?;
 
     ensure!(
-        config.extra_apks.len() == verified_data.extra_apks_data.len(),
+        config.extra_apks.len() == instance_data.extra_apks_data.len(),
         "config expects {} extra apks, but found {}",
         config.extra_apks.len(),
-        verified_data.extra_apks_data.len()
+        instance_data.extra_apks_data.len()
     );
     mount_extra_apks(&config, &mut zipfuse)?;