Expand DICE chain in VTS/test to contain arrays

Include a list of subcomponents in AVB DiceChainEntry in the sample DICE
chain and include constraints on that in the sealing_policy.

Bug: 291238565
Test: VTS#secret_management_policy_gate
Change-Id: Id36ddf137bacf99c273b61c3136691426f2d5b34
diff --git a/security/secretkeeper/aidl/vts/dice_sample.rs b/security/secretkeeper/aidl/vts/dice_sample.rs
index db532b1..97b4789 100644
--- a/security/secretkeeper/aidl/vts/dice_sample.rs
+++ b/security/secretkeeper/aidl/vts/dice_sample.rs
@@ -18,9 +18,16 @@
 //! module duplicates a large chunk of code in libdiced_sample_inputs. We avoid modifying the
 //! latter for testing purposes because it is installed on device.
 
-use ciborium::{de, ser, value::Value};
+use crate::{
+    COMPONENT_NAME, COMPONENT_RESETTABLE, COMPONENT_VERSION, SUBCOMPONENT_AUTHORITY_HASH,
+    SUBCOMPONENT_CODE_HASH, SUBCOMPONENT_DESCRIPTORS, SUBCOMPONENT_NAME,
+    SUBCOMPONENT_SECURITY_VERSION,
+};
+use ciborium::{cbor, de, ser, value::Value};
 use core::ffi::CStr;
-use coset::{iana, Algorithm, AsCborValue, CoseKey, KeyOperation, KeyType, Label};
+use coset::{
+    iana, Algorithm, AsCborValue, CborSerializable, CoseKey, KeyOperation, KeyType, Label,
+};
 use diced_open_dice::{
     derive_cdi_private_key_seed, keypair_from_seed, retry_bcc_format_config_descriptor,
     retry_bcc_main_flow, retry_dice_main_flow, Config, DiceArtifacts, DiceConfigValues, DiceError,
@@ -100,7 +107,8 @@
 ///
 /// The DICE chain is of the following format:
 /// public key derived from UDS -> ABL certificate -> AVB certificate -> Android certificate
-/// The `security_version` is included in the Android certificate.
+/// The `security_version` is included in the Android certificate as well as each subcomponent
+/// of AVB certificate.
 pub fn make_explicit_owned_dice(security_version: u64) -> OwnedDiceArtifactsWithExplicitKey {
     let dice = make_sample_bcc_and_cdis(security_version);
     OwnedDiceArtifactsWithExplicitKey::from_owned_artifacts(dice).unwrap()
@@ -135,16 +143,31 @@
     ser::into_writer(&bcc_value, &mut bcc).unwrap();
 
     // Appends AVB certificate to DICE chain.
-    let config_values = DiceConfigValues {
-        component_name: Some(CStr::from_bytes_with_nul(b"AVB\0").unwrap()),
-        component_version: Some(1),
-        resettable: true,
-        ..Default::default()
-    };
-    let config_descriptor = retry_bcc_format_config_descriptor(&config_values).unwrap();
+    let config_desc = cbor!({
+        COMPONENT_NAME => "AVB",
+        COMPONENT_VERSION => 1,
+        COMPONENT_RESETTABLE => null,
+        SUBCOMPONENT_DESCRIPTORS => [
+            {
+                SUBCOMPONENT_NAME => "sub_1",
+                SUBCOMPONENT_SECURITY_VERSION => security_version,
+                SUBCOMPONENT_CODE_HASH=> b"xoxo",
+                SUBCOMPONENT_AUTHORITY_HASH => b"oxox"
+            },
+            {
+                SUBCOMPONENT_NAME => "sub_2",
+                SUBCOMPONENT_SECURITY_VERSION => security_version,
+                SUBCOMPONENT_CODE_HASH => b"xoxo",
+                SUBCOMPONENT_AUTHORITY_HASH => b"oxox",
+            }
+        ]
+    })
+    .unwrap()
+    .to_vec()
+    .unwrap();
     let input_values = InputValues::new(
         CODE_HASH_AVB,
-        Config::Descriptor(config_descriptor.as_slice()),
+        Config::Descriptor(&config_desc),
         AUTHORITY_HASH_AVB,
         DiceMode::kDiceModeNormal,
         HIDDEN_AVB,
diff --git a/security/secretkeeper/aidl/vts/lib.rs b/security/secretkeeper/aidl/vts/lib.rs
index 9f98165..3afe938 100644
--- a/security/secretkeeper/aidl/vts/lib.rs
+++ b/security/secretkeeper/aidl/vts/lib.rs
@@ -28,7 +28,19 @@
 pub const COMPONENT_NAME: i64 = -70002;
 /// Map key for component version.
 pub const COMPONENT_VERSION: i64 = -70003;
+/// Map key for Resettable.
+pub const COMPONENT_RESETTABLE: i64 = -70004;
 /// Map key for security version.
 pub const SECURITY_VERSION: i64 = -70005;
 /// Map key for mode.
 pub const MODE: i64 = -4670551;
+/// Map key for SubcomponentDescriptor.
+pub const SUBCOMPONENT_DESCRIPTORS: i64 = -71002;
+/// Map key for name of subcomponent.
+pub const SUBCOMPONENT_NAME: i64 = 1;
+/// Map key for Security Version of subcomponent.
+pub const SUBCOMPONENT_SECURITY_VERSION: i64 = 2;
+/// Map key for Code hash of subcomponent.
+pub const SUBCOMPONENT_CODE_HASH: i64 = 3;
+/// Map key for Authority Hash of subcomponent.
+pub const SUBCOMPONENT_AUTHORITY_HASH: i64 = 4;
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_cli.rs b/security/secretkeeper/aidl/vts/secretkeeper_cli.rs
index 0c13811..d02bfe6 100644
--- a/security/secretkeeper/aidl/vts/secretkeeper_cli.rs
+++ b/security/secretkeeper/aidl/vts/secretkeeper_cli.rs
@@ -24,7 +24,10 @@
 use authgraph_core::traits::Sha256;
 use clap::{Args, Parser, Subcommand};
 use coset::CborSerializable;
-use dice_policy_builder::{ConstraintSpec, ConstraintType, MissingAction, policy_for_dice_chain};
+use dice_policy_builder::{
+    policy_for_dice_chain, CertIndex, ConstraintSpec, ConstraintType, MissingAction,
+    WILDCARD_FULL_ARRAY,
+};
 
 use secretkeeper_client::{dice::OwnedDiceArtifactsWithExplicitKey, SkSession};
 use secretkeeper_comm::data_types::{
@@ -37,6 +40,7 @@
 };
 use secretkeeper_test::{
     dice_sample::make_explicit_owned_dice, AUTHORITY_HASH, CONFIG_DESC, MODE, SECURITY_VERSION,
+    SUBCOMPONENT_AUTHORITY_HASH, SUBCOMPONENT_DESCRIPTORS, SUBCOMPONENT_SECURITY_VERSION,
 };
 use std::io::Write;
 
@@ -139,12 +143,42 @@
                 ConstraintType::ExactMatch,
                 vec![AUTHORITY_HASH],
                 MissingAction::Fail,
+                CertIndex::All,
             ),
-            ConstraintSpec::new(ConstraintType::ExactMatch, vec![MODE], MissingAction::Fail),
+            ConstraintSpec::new(
+                ConstraintType::ExactMatch,
+                vec![MODE],
+                MissingAction::Fail,
+                CertIndex::All,
+            ),
             ConstraintSpec::new(
                 ConstraintType::GreaterOrEqual,
                 vec![CONFIG_DESC, SECURITY_VERSION],
                 MissingAction::Ignore,
+                CertIndex::All,
+            ),
+            // Constraints on sub components in the second last DiceChainEntry
+            ConstraintSpec::new(
+                ConstraintType::GreaterOrEqual,
+                vec![
+                    CONFIG_DESC,
+                    SUBCOMPONENT_DESCRIPTORS,
+                    WILDCARD_FULL_ARRAY,
+                    SUBCOMPONENT_SECURITY_VERSION,
+                ],
+                MissingAction::Fail,
+                CertIndex::FromEnd(1),
+            ),
+            ConstraintSpec::new(
+                ConstraintType::ExactMatch,
+                vec![
+                    CONFIG_DESC,
+                    SUBCOMPONENT_DESCRIPTORS,
+                    WILDCARD_FULL_ARRAY,
+                    SUBCOMPONENT_AUTHORITY_HASH,
+                ],
+                MissingAction::Fail,
+                CertIndex::FromEnd(1),
             ),
         ];
         policy_for_dice_chain(dice, &constraint_spec)
diff --git a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
index 483aed6..dcba90b 100644
--- a/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
+++ b/security/secretkeeper/aidl/vts/secretkeeper_test_client.rs
@@ -20,7 +20,7 @@
 use authgraph_boringssl as boring;
 use authgraph_core::key;
 use coset::{CborSerializable, CoseEncrypt0};
-use dice_policy_builder::{ConstraintSpec, ConstraintType, MissingAction, policy_for_dice_chain};
+use dice_policy_builder::{CertIndex, ConstraintSpec, ConstraintType, MissingAction, WILDCARD_FULL_ARRAY, policy_for_dice_chain};
 use rdroidtest::{ignore_if, rdroidtest};
 use secretkeeper_client::dice::OwnedDiceArtifactsWithExplicitKey;
 use secretkeeper_client::SkSession;
@@ -34,13 +34,13 @@
 use secretkeeper_comm::data_types::response::Response;
 use secretkeeper_comm::data_types::packet::{ResponsePacket, ResponseType};
 use secretkeeper_test::{
-    AUTHORITY_HASH, MODE, CONFIG_DESC, SECURITY_VERSION,
+    AUTHORITY_HASH, MODE, CONFIG_DESC, SECURITY_VERSION, SUBCOMPONENT_AUTHORITY_HASH,
+    SUBCOMPONENT_DESCRIPTORS, SUBCOMPONENT_SECURITY_VERSION,
     dice_sample::make_explicit_owned_dice
 };
 
 const SECRETKEEPER_SERVICE: &str = "android.hardware.security.secretkeeper.ISecretkeeper";
 const CURRENT_VERSION: u64 = 1;
-
 // Random bytes (of ID_SIZE/SECRET_SIZE) generated for tests.
 const ID_EXAMPLE: Id = Id([
     0xF1, 0xB2, 0xED, 0x3B, 0xD1, 0xBD, 0xF0, 0x7D, 0xE1, 0xF0, 0x01, 0xFC, 0x61, 0x71, 0xD3, 0x42,
@@ -247,14 +247,51 @@
 /// 1. ExactMatch on AUTHORITY_HASH (non-optional).
 /// 2. ExactMatch on MODE (non-optional).
 /// 3. GreaterOrEqual on SECURITY_VERSION (optional).
+/// 4. The second last DiceChainEntry contain SubcomponentDescriptor, for each of those:
+///     a) GreaterOrEqual on SECURITY_VERSION (Required)
+//      b) ExactMatch on AUTHORITY_HASH (Required).
 fn sealing_policy(dice: &[u8]) -> Vec<u8> {
     let constraint_spec = [
-        ConstraintSpec::new(ConstraintType::ExactMatch, vec![AUTHORITY_HASH], MissingAction::Fail),
-        ConstraintSpec::new(ConstraintType::ExactMatch, vec![MODE], MissingAction::Fail),
+        ConstraintSpec::new(
+            ConstraintType::ExactMatch,
+            vec![AUTHORITY_HASH],
+            MissingAction::Fail,
+            CertIndex::All,
+        ),
+        ConstraintSpec::new(
+            ConstraintType::ExactMatch,
+            vec![MODE],
+            MissingAction::Fail,
+            CertIndex::All,
+        ),
         ConstraintSpec::new(
             ConstraintType::GreaterOrEqual,
             vec![CONFIG_DESC, SECURITY_VERSION],
             MissingAction::Ignore,
+            CertIndex::All,
+        ),
+        // Constraints on sub components in the second last DiceChainEntry
+        ConstraintSpec::new(
+            ConstraintType::GreaterOrEqual,
+            vec![
+                CONFIG_DESC,
+                SUBCOMPONENT_DESCRIPTORS,
+                WILDCARD_FULL_ARRAY,
+                SUBCOMPONENT_SECURITY_VERSION,
+            ],
+            MissingAction::Fail,
+            CertIndex::FromEnd(1),
+        ),
+        ConstraintSpec::new(
+            ConstraintType::ExactMatch,
+            vec![
+                CONFIG_DESC,
+                SUBCOMPONENT_DESCRIPTORS,
+                WILDCARD_FULL_ARRAY,
+                SUBCOMPONENT_AUTHORITY_HASH,
+            ],
+            MissingAction::Fail,
+            CertIndex::FromEnd(1),
         ),
     ];