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