xref: /aosp_15_r20/system/secretkeeper/dice_policy/tests/test.rs (revision 3f8e9d82f4020c68ad19a99fc5fdc1fc90b79379)
1*3f8e9d82SAndroid Build Coastguard Worker /*
2*3f8e9d82SAndroid Build Coastguard Worker  * Copyright (C) 2023 The Android Open Source Project
3*3f8e9d82SAndroid Build Coastguard Worker  *
4*3f8e9d82SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*3f8e9d82SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*3f8e9d82SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*3f8e9d82SAndroid Build Coastguard Worker  *
8*3f8e9d82SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*3f8e9d82SAndroid Build Coastguard Worker  *
10*3f8e9d82SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*3f8e9d82SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*3f8e9d82SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*3f8e9d82SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*3f8e9d82SAndroid Build Coastguard Worker  * limitations under the License.
15*3f8e9d82SAndroid Build Coastguard Worker  */
16*3f8e9d82SAndroid Build Coastguard Worker 
17*3f8e9d82SAndroid Build Coastguard Worker //! Test libsdice_policy_builder & libdice_policy. Uses `rdroidtest` attribute macro.
18*3f8e9d82SAndroid Build Coastguard Worker use ciborium::{cbor, Value};
19*3f8e9d82SAndroid Build Coastguard Worker use coset::{AsCborValue, CborSerializable, CoseKey, CoseSign1, Header, ProtectedHeader};
20*3f8e9d82SAndroid Build Coastguard Worker use dice_policy::{lookup_in_nested_container, Constraint, DicePolicy, NodeConstraints};
21*3f8e9d82SAndroid Build Coastguard Worker use dice_policy_builder::{
22*3f8e9d82SAndroid Build Coastguard Worker     policy_for_dice_chain, ConstraintSpec, ConstraintType, MissingAction, TargetEntry,
23*3f8e9d82SAndroid Build Coastguard Worker     WILDCARD_FULL_ARRAY,
24*3f8e9d82SAndroid Build Coastguard Worker };
25*3f8e9d82SAndroid Build Coastguard Worker use rdroidtest::rdroidtest;
26*3f8e9d82SAndroid Build Coastguard Worker 
27*3f8e9d82SAndroid Build Coastguard Worker const AUTHORITY_HASH: i64 = -4670549;
28*3f8e9d82SAndroid Build Coastguard Worker const CONFIG_DESC: i64 = -4670548;
29*3f8e9d82SAndroid Build Coastguard Worker const COMPONENT_NAME: i64 = -70002;
30*3f8e9d82SAndroid Build Coastguard Worker const COMPONENT_VERSION: i64 = -70003;
31*3f8e9d82SAndroid Build Coastguard Worker const SECURITY_VERSION: i64 = -70005;
32*3f8e9d82SAndroid Build Coastguard Worker const KEY_MODE: i64 = -4670551;
33*3f8e9d82SAndroid Build Coastguard Worker const EXPLICIT_KEY_DICE_CERT_CHAIN_VERSION: u64 = 1;
34*3f8e9d82SAndroid Build Coastguard Worker const COMPOS_CHAIN_SIZE_EXPLICIT_KEY: usize = 6;
35*3f8e9d82SAndroid Build Coastguard Worker const EXAMPLE_COMPONENT_NAME: &str = "example_component_name";
36*3f8e9d82SAndroid Build Coastguard Worker 
37*3f8e9d82SAndroid Build Coastguard Worker // Helper struct to encapsulate artifacts that are useful for unit tests.
38*3f8e9d82SAndroid Build Coastguard Worker struct TestArtifacts {
39*3f8e9d82SAndroid Build Coastguard Worker     // A dice chain.
40*3f8e9d82SAndroid Build Coastguard Worker     input_dice: Vec<u8>,
41*3f8e9d82SAndroid Build Coastguard Worker     // A list of ConstraintSpec that can be applied on the input_dice to get a dice policy.
42*3f8e9d82SAndroid Build Coastguard Worker     constraint_spec: Vec<ConstraintSpec>,
43*3f8e9d82SAndroid Build Coastguard Worker     // The expected dice policy if above constraint_spec is applied to input_dice.
44*3f8e9d82SAndroid Build Coastguard Worker     expected_dice_policy: DicePolicy,
45*3f8e9d82SAndroid Build Coastguard Worker     // Another dice chain, which is almost same as the input_dice, but (roughly) imitates
46*3f8e9d82SAndroid Build Coastguard Worker     // an 'updated' one, ie, some int entries are higher than corresponding entry
47*3f8e9d82SAndroid Build Coastguard Worker     // in input_chain.
48*3f8e9d82SAndroid Build Coastguard Worker     updated_input_dice: Vec<u8>,
49*3f8e9d82SAndroid Build Coastguard Worker }
50*3f8e9d82SAndroid Build Coastguard Worker 
51*3f8e9d82SAndroid Build Coastguard Worker impl TestArtifacts {
52*3f8e9d82SAndroid Build Coastguard Worker     // Get an example instance of TestArtifacts. This uses a hard coded, hypothetical
53*3f8e9d82SAndroid Build Coastguard Worker     // chain of certificates & a list of constraint_spec on this.
get_example() -> Self54*3f8e9d82SAndroid Build Coastguard Worker     fn get_example() -> Self {
55*3f8e9d82SAndroid Build Coastguard Worker         const EXAMPLE_NUM_1: i64 = 59765;
56*3f8e9d82SAndroid Build Coastguard Worker         const EXAMPLE_NUM_2: i64 = 59766;
57*3f8e9d82SAndroid Build Coastguard Worker         const EXAMPLE_STRING: &str = "testing_dice_policy";
58*3f8e9d82SAndroid Build Coastguard Worker         const UNCONSTRAINED_STRING: &str = "unconstrained_string";
59*3f8e9d82SAndroid Build Coastguard Worker         const ANOTHER_UNCONSTRAINED_STRING: &str = "another_unconstrained_string";
60*3f8e9d82SAndroid Build Coastguard Worker         const CONSTRAINED_ARRAY: [&str; 4] = ["Array", "IN", "LAST", "DICE_CHAIN_ENTRY"];
61*3f8e9d82SAndroid Build Coastguard Worker         let constrained_array = cbor!(CONSTRAINED_ARRAY).unwrap();
62*3f8e9d82SAndroid Build Coastguard Worker 
63*3f8e9d82SAndroid Build Coastguard Worker         let rot_key = Value::Bytes(CoseKey::default().to_vec().unwrap());
64*3f8e9d82SAndroid Build Coastguard Worker         let input_dice = Self::get_dice_chain_helper(
65*3f8e9d82SAndroid Build Coastguard Worker             rot_key.clone(),
66*3f8e9d82SAndroid Build Coastguard Worker             EXAMPLE_NUM_1,
67*3f8e9d82SAndroid Build Coastguard Worker             EXAMPLE_STRING,
68*3f8e9d82SAndroid Build Coastguard Worker             UNCONSTRAINED_STRING,
69*3f8e9d82SAndroid Build Coastguard Worker             constrained_array.clone(),
70*3f8e9d82SAndroid Build Coastguard Worker         );
71*3f8e9d82SAndroid Build Coastguard Worker 
72*3f8e9d82SAndroid Build Coastguard Worker         // Now construct constraint_spec on the input dice, note this will use the keys
73*3f8e9d82SAndroid Build Coastguard Worker         // which are also hardcoded within the get_dice_chain_helper.
74*3f8e9d82SAndroid Build Coastguard Worker 
75*3f8e9d82SAndroid Build Coastguard Worker         let constraint_spec = vec![
76*3f8e9d82SAndroid Build Coastguard Worker             ConstraintSpec::new(
77*3f8e9d82SAndroid Build Coastguard Worker                 ConstraintType::ExactMatch,
78*3f8e9d82SAndroid Build Coastguard Worker                 vec![1],
79*3f8e9d82SAndroid Build Coastguard Worker                 MissingAction::Fail,
80*3f8e9d82SAndroid Build Coastguard Worker                 TargetEntry::All,
81*3f8e9d82SAndroid Build Coastguard Worker             ),
82*3f8e9d82SAndroid Build Coastguard Worker             // Notice how key "2" is (deliberately) absent in ConstraintSpec
83*3f8e9d82SAndroid Build Coastguard Worker             // so policy should not constrain it.
84*3f8e9d82SAndroid Build Coastguard Worker             ConstraintSpec::new(
85*3f8e9d82SAndroid Build Coastguard Worker                 ConstraintType::GreaterOrEqual,
86*3f8e9d82SAndroid Build Coastguard Worker                 vec![3, 100],
87*3f8e9d82SAndroid Build Coastguard Worker                 MissingAction::Fail,
88*3f8e9d82SAndroid Build Coastguard Worker                 TargetEntry::All,
89*3f8e9d82SAndroid Build Coastguard Worker             ),
90*3f8e9d82SAndroid Build Coastguard Worker             ConstraintSpec::new(
91*3f8e9d82SAndroid Build Coastguard Worker                 ConstraintType::ExactMatch,
92*3f8e9d82SAndroid Build Coastguard Worker                 vec![4, WILDCARD_FULL_ARRAY],
93*3f8e9d82SAndroid Build Coastguard Worker                 MissingAction::Fail,
94*3f8e9d82SAndroid Build Coastguard Worker                 // Notice although 2 DiceChainEntries have the same component name, only the last
95*3f8e9d82SAndroid Build Coastguard Worker                 // one is expected to be constrained in the DicePolicy.
96*3f8e9d82SAndroid Build Coastguard Worker                 TargetEntry::ByName(EXAMPLE_COMPONENT_NAME.to_string()),
97*3f8e9d82SAndroid Build Coastguard Worker             ),
98*3f8e9d82SAndroid Build Coastguard Worker         ];
99*3f8e9d82SAndroid Build Coastguard Worker         let expected_dice_policy = DicePolicy {
100*3f8e9d82SAndroid Build Coastguard Worker             version: 1,
101*3f8e9d82SAndroid Build Coastguard Worker             node_constraints_list: Box::new([
102*3f8e9d82SAndroid Build Coastguard Worker                 NodeConstraints(Box::new([Constraint::new(
103*3f8e9d82SAndroid Build Coastguard Worker                     // 1st Node -> version
104*3f8e9d82SAndroid Build Coastguard Worker                     ConstraintType::ExactMatch as u16,
105*3f8e9d82SAndroid Build Coastguard Worker                     vec![],
106*3f8e9d82SAndroid Build Coastguard Worker                     Value::from(EXPLICIT_KEY_DICE_CERT_CHAIN_VERSION),
107*3f8e9d82SAndroid Build Coastguard Worker                 )
108*3f8e9d82SAndroid Build Coastguard Worker                 .unwrap()])),
109*3f8e9d82SAndroid Build Coastguard Worker                 NodeConstraints(Box::new([Constraint::new(
110*3f8e9d82SAndroid Build Coastguard Worker                     // 2nd Node -> root key encoding
111*3f8e9d82SAndroid Build Coastguard Worker                     ConstraintType::ExactMatch as u16,
112*3f8e9d82SAndroid Build Coastguard Worker                     vec![],
113*3f8e9d82SAndroid Build Coastguard Worker                     rot_key.clone(),
114*3f8e9d82SAndroid Build Coastguard Worker                 )
115*3f8e9d82SAndroid Build Coastguard Worker                 .unwrap()])),
116*3f8e9d82SAndroid Build Coastguard Worker                 NodeConstraints(Box::new([
117*3f8e9d82SAndroid Build Coastguard Worker                     // 3rd Node -> DiceChainEntry 0
118*3f8e9d82SAndroid Build Coastguard Worker                     Constraint::new(
119*3f8e9d82SAndroid Build Coastguard Worker                         ConstraintType::ExactMatch as u16,
120*3f8e9d82SAndroid Build Coastguard Worker                         vec![1],
121*3f8e9d82SAndroid Build Coastguard Worker                         Value::Text(EXAMPLE_STRING.to_string()),
122*3f8e9d82SAndroid Build Coastguard Worker                     )
123*3f8e9d82SAndroid Build Coastguard Worker                     .unwrap(),
124*3f8e9d82SAndroid Build Coastguard Worker                     Constraint::new(
125*3f8e9d82SAndroid Build Coastguard Worker                         ConstraintType::GreaterOrEqual as u16,
126*3f8e9d82SAndroid Build Coastguard Worker                         vec![3, 100],
127*3f8e9d82SAndroid Build Coastguard Worker                         Value::from(EXAMPLE_NUM_1),
128*3f8e9d82SAndroid Build Coastguard Worker                     )
129*3f8e9d82SAndroid Build Coastguard Worker                     .unwrap(),
130*3f8e9d82SAndroid Build Coastguard Worker                 ])),
131*3f8e9d82SAndroid Build Coastguard Worker                 NodeConstraints(Box::new([
132*3f8e9d82SAndroid Build Coastguard Worker                     // 4rd Node -> DiceChainEntry 1 (Also 0th from last)
133*3f8e9d82SAndroid Build Coastguard Worker                     Constraint::new(
134*3f8e9d82SAndroid Build Coastguard Worker                         ConstraintType::ExactMatch as u16,
135*3f8e9d82SAndroid Build Coastguard Worker                         vec![1],
136*3f8e9d82SAndroid Build Coastguard Worker                         Value::Text(EXAMPLE_STRING.to_string()),
137*3f8e9d82SAndroid Build Coastguard Worker                     )
138*3f8e9d82SAndroid Build Coastguard Worker                     .unwrap(),
139*3f8e9d82SAndroid Build Coastguard Worker                     Constraint::new(
140*3f8e9d82SAndroid Build Coastguard Worker                         ConstraintType::GreaterOrEqual as u16,
141*3f8e9d82SAndroid Build Coastguard Worker                         vec![3, 100],
142*3f8e9d82SAndroid Build Coastguard Worker                         Value::from(EXAMPLE_NUM_1),
143*3f8e9d82SAndroid Build Coastguard Worker                     )
144*3f8e9d82SAndroid Build Coastguard Worker                     .unwrap(),
145*3f8e9d82SAndroid Build Coastguard Worker                     Constraint::new(
146*3f8e9d82SAndroid Build Coastguard Worker                         ConstraintType::ExactMatch as u16,
147*3f8e9d82SAndroid Build Coastguard Worker                         vec![4, 0],
148*3f8e9d82SAndroid Build Coastguard Worker                         Value::from(CONSTRAINED_ARRAY[0]),
149*3f8e9d82SAndroid Build Coastguard Worker                     )
150*3f8e9d82SAndroid Build Coastguard Worker                     .unwrap(),
151*3f8e9d82SAndroid Build Coastguard Worker                     Constraint::new(
152*3f8e9d82SAndroid Build Coastguard Worker                         ConstraintType::ExactMatch as u16,
153*3f8e9d82SAndroid Build Coastguard Worker                         vec![4, 1],
154*3f8e9d82SAndroid Build Coastguard Worker                         Value::from(CONSTRAINED_ARRAY[1]),
155*3f8e9d82SAndroid Build Coastguard Worker                     )
156*3f8e9d82SAndroid Build Coastguard Worker                     .unwrap(),
157*3f8e9d82SAndroid Build Coastguard Worker                     Constraint::new(
158*3f8e9d82SAndroid Build Coastguard Worker                         ConstraintType::ExactMatch as u16,
159*3f8e9d82SAndroid Build Coastguard Worker                         vec![4, 2],
160*3f8e9d82SAndroid Build Coastguard Worker                         Value::from(CONSTRAINED_ARRAY[2]),
161*3f8e9d82SAndroid Build Coastguard Worker                     )
162*3f8e9d82SAndroid Build Coastguard Worker                     .unwrap(),
163*3f8e9d82SAndroid Build Coastguard Worker                     Constraint::new(
164*3f8e9d82SAndroid Build Coastguard Worker                         ConstraintType::ExactMatch as u16,
165*3f8e9d82SAndroid Build Coastguard Worker                         vec![4, 3],
166*3f8e9d82SAndroid Build Coastguard Worker                         Value::from(CONSTRAINED_ARRAY[3]),
167*3f8e9d82SAndroid Build Coastguard Worker                     )
168*3f8e9d82SAndroid Build Coastguard Worker                     .unwrap(),
169*3f8e9d82SAndroid Build Coastguard Worker                 ])),
170*3f8e9d82SAndroid Build Coastguard Worker             ]),
171*3f8e9d82SAndroid Build Coastguard Worker         };
172*3f8e9d82SAndroid Build Coastguard Worker 
173*3f8e9d82SAndroid Build Coastguard Worker         let updated_input_dice = Self::get_dice_chain_helper(
174*3f8e9d82SAndroid Build Coastguard Worker             rot_key,
175*3f8e9d82SAndroid Build Coastguard Worker             EXAMPLE_NUM_2,
176*3f8e9d82SAndroid Build Coastguard Worker             EXAMPLE_STRING,
177*3f8e9d82SAndroid Build Coastguard Worker             ANOTHER_UNCONSTRAINED_STRING,
178*3f8e9d82SAndroid Build Coastguard Worker             constrained_array,
179*3f8e9d82SAndroid Build Coastguard Worker         );
180*3f8e9d82SAndroid Build Coastguard Worker         Self { input_dice, constraint_spec, expected_dice_policy, updated_input_dice }
181*3f8e9d82SAndroid Build Coastguard Worker     }
182*3f8e9d82SAndroid Build Coastguard Worker 
183*3f8e9d82SAndroid Build Coastguard Worker     // Helper method method to generate a dice chain with a given rot_key.
184*3f8e9d82SAndroid Build Coastguard Worker     // Other arguments are ad-hoc values in the nested map. Callers use these to
185*3f8e9d82SAndroid Build Coastguard Worker     // construct appropriate constrains in dice policies.
get_dice_chain_helper( rot_key: Value, version: i64, constrained_string: &str, unconstrained_string: &str, constrained_array: Value, ) -> Vec<u8>186*3f8e9d82SAndroid Build Coastguard Worker     fn get_dice_chain_helper(
187*3f8e9d82SAndroid Build Coastguard Worker         rot_key: Value,
188*3f8e9d82SAndroid Build Coastguard Worker         version: i64,
189*3f8e9d82SAndroid Build Coastguard Worker         constrained_string: &str,
190*3f8e9d82SAndroid Build Coastguard Worker         unconstrained_string: &str,
191*3f8e9d82SAndroid Build Coastguard Worker         constrained_array: Value,
192*3f8e9d82SAndroid Build Coastguard Worker     ) -> Vec<u8> {
193*3f8e9d82SAndroid Build Coastguard Worker         let nested_payload = cbor!({
194*3f8e9d82SAndroid Build Coastguard Worker             100 => version
195*3f8e9d82SAndroid Build Coastguard Worker         })
196*3f8e9d82SAndroid Build Coastguard Worker         .unwrap();
197*3f8e9d82SAndroid Build Coastguard Worker 
198*3f8e9d82SAndroid Build Coastguard Worker         let payload0 = cbor!({
199*3f8e9d82SAndroid Build Coastguard Worker             1 => constrained_string,
200*3f8e9d82SAndroid Build Coastguard Worker             2 => unconstrained_string,
201*3f8e9d82SAndroid Build Coastguard Worker             3 => Value::Bytes(nested_payload.clone().to_vec().unwrap()),
202*3f8e9d82SAndroid Build Coastguard Worker             CONFIG_DESC => {COMPONENT_NAME => EXAMPLE_COMPONENT_NAME}
203*3f8e9d82SAndroid Build Coastguard Worker         })
204*3f8e9d82SAndroid Build Coastguard Worker         .unwrap();
205*3f8e9d82SAndroid Build Coastguard Worker         let payload0 = payload0.clone().to_vec().unwrap();
206*3f8e9d82SAndroid Build Coastguard Worker         let dice_chain_entry0 = CoseSign1 {
207*3f8e9d82SAndroid Build Coastguard Worker             protected: ProtectedHeader::default(),
208*3f8e9d82SAndroid Build Coastguard Worker             unprotected: Header::default(),
209*3f8e9d82SAndroid Build Coastguard Worker             payload: Some(payload0),
210*3f8e9d82SAndroid Build Coastguard Worker             signature: b"ddef".to_vec(),
211*3f8e9d82SAndroid Build Coastguard Worker         }
212*3f8e9d82SAndroid Build Coastguard Worker         .to_cbor_value()
213*3f8e9d82SAndroid Build Coastguard Worker         .unwrap();
214*3f8e9d82SAndroid Build Coastguard Worker 
215*3f8e9d82SAndroid Build Coastguard Worker         let payload1 = cbor!({
216*3f8e9d82SAndroid Build Coastguard Worker             1 => constrained_string,
217*3f8e9d82SAndroid Build Coastguard Worker             2 => unconstrained_string,
218*3f8e9d82SAndroid Build Coastguard Worker             3 => Value::Bytes(nested_payload.to_vec().unwrap()),
219*3f8e9d82SAndroid Build Coastguard Worker             4 => constrained_array,
220*3f8e9d82SAndroid Build Coastguard Worker             CONFIG_DESC => {COMPONENT_NAME => EXAMPLE_COMPONENT_NAME}
221*3f8e9d82SAndroid Build Coastguard Worker         })
222*3f8e9d82SAndroid Build Coastguard Worker         .unwrap();
223*3f8e9d82SAndroid Build Coastguard Worker         let payload1 = payload1.clone().to_vec().unwrap();
224*3f8e9d82SAndroid Build Coastguard Worker         let dice_chain_entry1 = CoseSign1 {
225*3f8e9d82SAndroid Build Coastguard Worker             protected: ProtectedHeader::default(),
226*3f8e9d82SAndroid Build Coastguard Worker             unprotected: Header::default(),
227*3f8e9d82SAndroid Build Coastguard Worker             payload: Some(payload1),
228*3f8e9d82SAndroid Build Coastguard Worker             signature: b"ddef".to_vec(),
229*3f8e9d82SAndroid Build Coastguard Worker         }
230*3f8e9d82SAndroid Build Coastguard Worker         .to_cbor_value()
231*3f8e9d82SAndroid Build Coastguard Worker         .unwrap();
232*3f8e9d82SAndroid Build Coastguard Worker         let input_dice = Value::Array(vec![
233*3f8e9d82SAndroid Build Coastguard Worker             Value::from(EXPLICIT_KEY_DICE_CERT_CHAIN_VERSION),
234*3f8e9d82SAndroid Build Coastguard Worker             rot_key,
235*3f8e9d82SAndroid Build Coastguard Worker             dice_chain_entry0,
236*3f8e9d82SAndroid Build Coastguard Worker             dice_chain_entry1,
237*3f8e9d82SAndroid Build Coastguard Worker         ]);
238*3f8e9d82SAndroid Build Coastguard Worker 
239*3f8e9d82SAndroid Build Coastguard Worker         input_dice.to_vec().unwrap()
240*3f8e9d82SAndroid Build Coastguard Worker     }
241*3f8e9d82SAndroid Build Coastguard Worker }
242*3f8e9d82SAndroid Build Coastguard Worker 
243*3f8e9d82SAndroid Build Coastguard Worker #[rdroidtest]
policy_structure_check()244*3f8e9d82SAndroid Build Coastguard Worker fn policy_structure_check() {
245*3f8e9d82SAndroid Build Coastguard Worker     let example = TestArtifacts::get_example();
246*3f8e9d82SAndroid Build Coastguard Worker     let policy = policy_for_dice_chain(&example.input_dice, example.constraint_spec).unwrap();
247*3f8e9d82SAndroid Build Coastguard Worker 
248*3f8e9d82SAndroid Build Coastguard Worker     // Assert policy is exactly as expected!
249*3f8e9d82SAndroid Build Coastguard Worker     assert_eq!(policy, example.expected_dice_policy);
250*3f8e9d82SAndroid Build Coastguard Worker }
251*3f8e9d82SAndroid Build Coastguard Worker 
252*3f8e9d82SAndroid Build Coastguard Worker #[rdroidtest]
policy_enc_dec_test()253*3f8e9d82SAndroid Build Coastguard Worker fn policy_enc_dec_test() {
254*3f8e9d82SAndroid Build Coastguard Worker     // An example dice policy
255*3f8e9d82SAndroid Build Coastguard Worker     let dice_policy: DicePolicy = TestArtifacts::get_example().expected_dice_policy;
256*3f8e9d82SAndroid Build Coastguard Worker     // Encode & then decode back!
257*3f8e9d82SAndroid Build Coastguard Worker     let dice_policy_enc_dec =
258*3f8e9d82SAndroid Build Coastguard Worker         DicePolicy::from_slice(&dice_policy.clone().to_vec().unwrap()).unwrap();
259*3f8e9d82SAndroid Build Coastguard Worker     assert_eq!(dice_policy, dice_policy_enc_dec);
260*3f8e9d82SAndroid Build Coastguard Worker }
261*3f8e9d82SAndroid Build Coastguard Worker 
262*3f8e9d82SAndroid Build Coastguard Worker #[rdroidtest]
policy_matches_original_dice_chain()263*3f8e9d82SAndroid Build Coastguard Worker fn policy_matches_original_dice_chain() {
264*3f8e9d82SAndroid Build Coastguard Worker     let example = TestArtifacts::get_example();
265*3f8e9d82SAndroid Build Coastguard Worker     policy_for_dice_chain(&example.input_dice, example.constraint_spec)
266*3f8e9d82SAndroid Build Coastguard Worker         .unwrap()
267*3f8e9d82SAndroid Build Coastguard Worker         .matches_dice_chain(&example.input_dice)
268*3f8e9d82SAndroid Build Coastguard Worker         .unwrap();
269*3f8e9d82SAndroid Build Coastguard Worker }
270*3f8e9d82SAndroid Build Coastguard Worker 
271*3f8e9d82SAndroid Build Coastguard Worker #[rdroidtest]
policy_matches_updated_dice_chain()272*3f8e9d82SAndroid Build Coastguard Worker fn policy_matches_updated_dice_chain() {
273*3f8e9d82SAndroid Build Coastguard Worker     let example = TestArtifacts::get_example();
274*3f8e9d82SAndroid Build Coastguard Worker     policy_for_dice_chain(&example.input_dice, example.constraint_spec)
275*3f8e9d82SAndroid Build Coastguard Worker         .unwrap()
276*3f8e9d82SAndroid Build Coastguard Worker         .matches_dice_chain(&example.updated_input_dice)
277*3f8e9d82SAndroid Build Coastguard Worker         .unwrap();
278*3f8e9d82SAndroid Build Coastguard Worker }
279*3f8e9d82SAndroid Build Coastguard Worker 
280*3f8e9d82SAndroid Build Coastguard Worker #[rdroidtest]
policy_mismatch_downgraded_dice_chain()281*3f8e9d82SAndroid Build Coastguard Worker fn policy_mismatch_downgraded_dice_chain() {
282*3f8e9d82SAndroid Build Coastguard Worker     let example = TestArtifacts::get_example();
283*3f8e9d82SAndroid Build Coastguard Worker     assert!(
284*3f8e9d82SAndroid Build Coastguard Worker         policy_for_dice_chain(&example.updated_input_dice, example.constraint_spec)
285*3f8e9d82SAndroid Build Coastguard Worker             .unwrap()
286*3f8e9d82SAndroid Build Coastguard Worker             .matches_dice_chain(&example.input_dice)
287*3f8e9d82SAndroid Build Coastguard Worker             .is_err(),
288*3f8e9d82SAndroid Build Coastguard Worker         "The (downgraded) dice chain matched the policy constructed out of the 'updated'\
289*3f8e9d82SAndroid Build Coastguard Worker             dice chain!!"
290*3f8e9d82SAndroid Build Coastguard Worker     );
291*3f8e9d82SAndroid Build Coastguard Worker }
292*3f8e9d82SAndroid Build Coastguard Worker 
293*3f8e9d82SAndroid Build Coastguard Worker #[rdroidtest]
policy_constructional_required_constraint()294*3f8e9d82SAndroid Build Coastguard Worker fn policy_constructional_required_constraint() {
295*3f8e9d82SAndroid Build Coastguard Worker     let mut example = TestArtifacts::get_example();
296*3f8e9d82SAndroid Build Coastguard Worker     // The constraint_path [9,8,7] is not present in example.input_dice
297*3f8e9d82SAndroid Build Coastguard Worker     example.constraint_spec.push(ConstraintSpec::new(
298*3f8e9d82SAndroid Build Coastguard Worker         ConstraintType::ExactMatch,
299*3f8e9d82SAndroid Build Coastguard Worker         vec![9, 8, 7],
300*3f8e9d82SAndroid Build Coastguard Worker         MissingAction::Fail,
301*3f8e9d82SAndroid Build Coastguard Worker         TargetEntry::All,
302*3f8e9d82SAndroid Build Coastguard Worker     ));
303*3f8e9d82SAndroid Build Coastguard Worker     assert!(
304*3f8e9d82SAndroid Build Coastguard Worker         policy_for_dice_chain(&example.input_dice, example.constraint_spec).is_err(),
305*3f8e9d82SAndroid Build Coastguard Worker         "DicePolicy creation should've failed on Required constraint"
306*3f8e9d82SAndroid Build Coastguard Worker     );
307*3f8e9d82SAndroid Build Coastguard Worker }
308*3f8e9d82SAndroid Build Coastguard Worker 
309*3f8e9d82SAndroid Build Coastguard Worker #[rdroidtest]
policy_constructional_optional_constraint()310*3f8e9d82SAndroid Build Coastguard Worker fn policy_constructional_optional_constraint() {
311*3f8e9d82SAndroid Build Coastguard Worker     let mut example = TestArtifacts::get_example();
312*3f8e9d82SAndroid Build Coastguard Worker     // The constraint_path [9,8,7] is not present in example.input_dice
313*3f8e9d82SAndroid Build Coastguard Worker     example.constraint_spec.push(ConstraintSpec::new(
314*3f8e9d82SAndroid Build Coastguard Worker         ConstraintType::ExactMatch,
315*3f8e9d82SAndroid Build Coastguard Worker         vec![9, 8, 7],
316*3f8e9d82SAndroid Build Coastguard Worker         MissingAction::Ignore,
317*3f8e9d82SAndroid Build Coastguard Worker         TargetEntry::All,
318*3f8e9d82SAndroid Build Coastguard Worker     ));
319*3f8e9d82SAndroid Build Coastguard Worker     // However for optional constraint, policy construction should succeed!
320*3f8e9d82SAndroid Build Coastguard Worker     _ = policy_for_dice_chain(&example.input_dice, example.constraint_spec).unwrap()
321*3f8e9d82SAndroid Build Coastguard Worker }
322*3f8e9d82SAndroid Build Coastguard Worker 
323*3f8e9d82SAndroid Build Coastguard Worker #[rdroidtest]
policy_dice_size_is_same()324*3f8e9d82SAndroid Build Coastguard Worker fn policy_dice_size_is_same() {
325*3f8e9d82SAndroid Build Coastguard Worker     // This is the number of certs in compos bcc (including the first ROT)
326*3f8e9d82SAndroid Build Coastguard Worker     // To analyze a bcc use hwtrust tool from /tools/security/remote_provisioning/hwtrust
327*3f8e9d82SAndroid Build Coastguard Worker     // `hwtrust --verbose dice-chain [path]/composbcc`
328*3f8e9d82SAndroid Build Coastguard Worker     let input_dice = include_bytes!("./testdata/compos_chain_explicit");
329*3f8e9d82SAndroid Build Coastguard Worker     let constraint_spec = vec![
330*3f8e9d82SAndroid Build Coastguard Worker         ConstraintSpec::new(
331*3f8e9d82SAndroid Build Coastguard Worker             ConstraintType::ExactMatch,
332*3f8e9d82SAndroid Build Coastguard Worker             vec![AUTHORITY_HASH],
333*3f8e9d82SAndroid Build Coastguard Worker             MissingAction::Fail,
334*3f8e9d82SAndroid Build Coastguard Worker             TargetEntry::All,
335*3f8e9d82SAndroid Build Coastguard Worker         ),
336*3f8e9d82SAndroid Build Coastguard Worker         ConstraintSpec::new(
337*3f8e9d82SAndroid Build Coastguard Worker             ConstraintType::ExactMatch,
338*3f8e9d82SAndroid Build Coastguard Worker             vec![KEY_MODE],
339*3f8e9d82SAndroid Build Coastguard Worker             MissingAction::Fail,
340*3f8e9d82SAndroid Build Coastguard Worker             TargetEntry::All,
341*3f8e9d82SAndroid Build Coastguard Worker         ),
342*3f8e9d82SAndroid Build Coastguard Worker         ConstraintSpec::new(
343*3f8e9d82SAndroid Build Coastguard Worker             ConstraintType::ExactMatch,
344*3f8e9d82SAndroid Build Coastguard Worker             vec![CONFIG_DESC, COMPONENT_NAME],
345*3f8e9d82SAndroid Build Coastguard Worker             MissingAction::Fail,
346*3f8e9d82SAndroid Build Coastguard Worker             TargetEntry::All,
347*3f8e9d82SAndroid Build Coastguard Worker         ),
348*3f8e9d82SAndroid Build Coastguard Worker         ConstraintSpec::new(
349*3f8e9d82SAndroid Build Coastguard Worker             ConstraintType::GreaterOrEqual,
350*3f8e9d82SAndroid Build Coastguard Worker             vec![CONFIG_DESC, COMPONENT_VERSION],
351*3f8e9d82SAndroid Build Coastguard Worker             MissingAction::Ignore,
352*3f8e9d82SAndroid Build Coastguard Worker             TargetEntry::All,
353*3f8e9d82SAndroid Build Coastguard Worker         ),
354*3f8e9d82SAndroid Build Coastguard Worker         ConstraintSpec::new(
355*3f8e9d82SAndroid Build Coastguard Worker             ConstraintType::GreaterOrEqual,
356*3f8e9d82SAndroid Build Coastguard Worker             vec![CONFIG_DESC, SECURITY_VERSION],
357*3f8e9d82SAndroid Build Coastguard Worker             MissingAction::Ignore,
358*3f8e9d82SAndroid Build Coastguard Worker             TargetEntry::All,
359*3f8e9d82SAndroid Build Coastguard Worker         ),
360*3f8e9d82SAndroid Build Coastguard Worker     ];
361*3f8e9d82SAndroid Build Coastguard Worker     let policy = policy_for_dice_chain(input_dice, constraint_spec).unwrap();
362*3f8e9d82SAndroid Build Coastguard Worker     assert_eq!(policy.node_constraints_list.len(), COMPOS_CHAIN_SIZE_EXPLICIT_KEY);
363*3f8e9d82SAndroid Build Coastguard Worker     // Check that original dice chain matches the policy.
364*3f8e9d82SAndroid Build Coastguard Worker     policy.matches_dice_chain(input_dice).unwrap();
365*3f8e9d82SAndroid Build Coastguard Worker }
366*3f8e9d82SAndroid Build Coastguard Worker 
367*3f8e9d82SAndroid Build Coastguard Worker #[rdroidtest]
policy_matcher_builder_in_sync()368*3f8e9d82SAndroid Build Coastguard Worker fn policy_matcher_builder_in_sync() {
369*3f8e9d82SAndroid Build Coastguard Worker     // DicePolicy builder & matcher are closely coupled.
370*3f8e9d82SAndroid Build Coastguard Worker     assert_eq!(
371*3f8e9d82SAndroid Build Coastguard Worker         dice_policy::DICE_POLICY_VERSION,
372*3f8e9d82SAndroid Build Coastguard Worker         dice_policy_builder::SUPPORTED_DICE_POLICY_VERSION
373*3f8e9d82SAndroid Build Coastguard Worker     );
374*3f8e9d82SAndroid Build Coastguard Worker }
375*3f8e9d82SAndroid Build Coastguard Worker #[rdroidtest]
lookup_in_nested_container_test()376*3f8e9d82SAndroid Build Coastguard Worker fn lookup_in_nested_container_test() {
377*3f8e9d82SAndroid Build Coastguard Worker     const TARGET: &str = "TARGET";
378*3f8e9d82SAndroid Build Coastguard Worker     let nested_container = cbor!({ // MAP
379*3f8e9d82SAndroid Build Coastguard Worker         1 => 5,
380*3f8e9d82SAndroid Build Coastguard Worker         2 => cbor!([                // ARRAY
381*3f8e9d82SAndroid Build Coastguard Worker             "Index0",
382*3f8e9d82SAndroid Build Coastguard Worker             "Index1",
383*3f8e9d82SAndroid Build Coastguard Worker             cbor!({                 // Map
384*3f8e9d82SAndroid Build Coastguard Worker                 1 => 5,
385*3f8e9d82SAndroid Build Coastguard Worker                 2 => cbor!([        // ARRAY
386*3f8e9d82SAndroid Build Coastguard Worker                     "Index0",
387*3f8e9d82SAndroid Build Coastguard Worker                     "Index1",
388*3f8e9d82SAndroid Build Coastguard Worker                     TARGET,
389*3f8e9d82SAndroid Build Coastguard Worker                 ]).unwrap(),
390*3f8e9d82SAndroid Build Coastguard Worker             }).unwrap(),
391*3f8e9d82SAndroid Build Coastguard Worker         ]).unwrap(),
392*3f8e9d82SAndroid Build Coastguard Worker     })
393*3f8e9d82SAndroid Build Coastguard Worker     .unwrap();
394*3f8e9d82SAndroid Build Coastguard Worker     let path_present = vec![2, 2, 2, 2];
395*3f8e9d82SAndroid Build Coastguard Worker     let path_missing1 = vec![2, 2, 2, 3];
396*3f8e9d82SAndroid Build Coastguard Worker     let path_missing2 = vec![2, 2, 3];
397*3f8e9d82SAndroid Build Coastguard Worker     assert_eq!(
398*3f8e9d82SAndroid Build Coastguard Worker         lookup_in_nested_container(&nested_container, &path_present).unwrap(),
399*3f8e9d82SAndroid Build Coastguard Worker         Some(Value::from(TARGET))
400*3f8e9d82SAndroid Build Coastguard Worker     );
401*3f8e9d82SAndroid Build Coastguard Worker     assert_eq!(lookup_in_nested_container(&nested_container, &path_missing1).unwrap(), None);
402*3f8e9d82SAndroid Build Coastguard Worker     assert_eq!(lookup_in_nested_container(&nested_container, &path_missing2).unwrap(), None);
403*3f8e9d82SAndroid Build Coastguard Worker }
404*3f8e9d82SAndroid Build Coastguard Worker 
405*3f8e9d82SAndroid Build Coastguard Worker rdroidtest::test_main!();
406