1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 use super::*;
18 use ::test::{assert, assert_ne};
19 
20 #[cfg(feature = "generic-arm-unittest")]
21 use ::test::assert_eq;
22 
23 #[cfg(feature = "generic-arm-unittest")]
24 use system_state::{SystemState, SystemStateFlag};
25 
26 ::test::init!();
27 
28 const TEST_MAC_KEY: &'static [u8; HWBCC_MAC_KEY_SIZE as usize] = &[
29     0xf4, 0xe2, 0xd2, 0xbb, 0x2d, 0x07, 0x16, 0xb9, 0x66, 0x4b, 0x73, 0xe8, 0x56, 0xd3, 0x6e, 0xfb,
30     0x08, 0xb4, 0x01, 0xd8, 0x86, 0x38, 0xa7, 0x9a, 0x97, 0xb3, 0x98, 0x4f, 0x63, 0xdc, 0xef, 0xed,
31 ];
32 
33 const TEST_AAD: &'static [u8] = &[0xcf, 0xe1, 0x89, 0x39, 0xb1, 0x72, 0xbf, 0x4f, 0xa8, 0x0f];
34 
35 #[cfg(feature = "generic-arm-unittest")]
36 #[test]
test_get_dice_artifacts()37 fn test_get_dice_artifacts() {
38     const EMULATOR_CDI_ATTEST: &'static [u8; DICE_CDI_SIZE as usize] = &[
39         0x44, 0x26, 0x69, 0x94, 0x02, 0x34, 0x1c, 0xc8, 0x1d, 0x93, 0xc7, 0xb8, 0x47, 0xaf, 0x55,
40         0xe8, 0xde, 0x8e, 0x79, 0x4c, 0x1b, 0x0f, 0xea, 0x99, 0x7f, 0x91, 0x83, 0x83, 0x7f, 0x26,
41         0x7f, 0x93,
42     ];
43 
44     const EMULATOR_CDI_SEAL: &'static [u8; DICE_CDI_SIZE as usize] = &[
45         0xf7, 0xe5, 0xb0, 0x2b, 0xd0, 0xfa, 0x4d, 0x5b, 0xfa, 0xd8, 0x16, 0x24, 0xfa, 0xc8, 0x50,
46         0xac, 0x4f, 0x1a, 0x3d, 0xb4, 0xbc, 0x02, 0xc9, 0xfd, 0xeb, 0xfe, 0x26, 0xfc, 0x28, 0x98,
47         0x5b, 0xe8,
48     ];
49 
50     let dice_artifacts_buf = &mut [0u8; HWBCC_MAX_RESP_PAYLOAD_LENGTH];
51     /*
52        dice_artifacts expects the following CBOR encoded structure.
53        Since the implementation of hwbcc_get_dice_artifacts serves only the
54        non-secure world, Bcc is not present in the returned dice_artifacts.
55        We calculate the expected size, including CBOR header sizes.
56        BccHandover = {
57            1 : bstr .size 32,	// CDI_Attest
58            2 : bstr .size 32,	// CDI_Seal
59            ? 3 : Bcc,          // Cert_Chain
60        }
61        Bcc = [
62            PubKeyEd25519, // UDS
63            + BccEntry,    // Root -> leaf
64        ]
65     */
66     let bcc_handover_size: usize = 2 * DICE_CDI_SIZE as usize + 7 /*CBOR tags*/;
67 
68     let DiceArtifacts { artifacts } =
69         get_dice_artifacts(0, dice_artifacts_buf).expect("could not get protected data");
70 
71     assert!(artifacts.len() > 0);
72     assert_eq!(artifacts.len(), bcc_handover_size);
73 
74     let next_cdi_attest = &mut [0u8; DICE_CDI_SIZE as usize];
75     let next_cdi_seal = &mut [0u8; DICE_CDI_SIZE as usize];
76 
77     assert!(unsafe {
78         // SAFETY: the artifact bytes will be deserialized from CBOR
79         // and validated via copy, and not in-place. The original
80         // bytestring will remain valid after the check.
81         validate_bcc_handover(
82             artifacts.as_ptr(),
83             artifacts.len(),
84             next_cdi_attest as *mut [u8; DICE_CDI_SIZE as usize],
85             next_cdi_seal as *mut [u8; DICE_CDI_SIZE as usize],
86         )
87     });
88 
89     let system_state_session =
90         SystemState::try_connect().expect("could not connect to system state service");
91     if system_state_session.get_flag(SystemStateFlag::AppLoadingUnlocked).unwrap() != 0 {
92         assert_eq!(EMULATOR_CDI_ATTEST, next_cdi_attest);
93         assert_eq!(EMULATOR_CDI_SEAL, next_cdi_seal);
94     }
95 }
96 
97 #[test]
test_ns_deprivilege()98 fn test_ns_deprivilege() {
99     ns_deprivilege().expect("could not execute ns deprivilege");
100 
101     // ns_deprivilege should not block calls from secure world
102     let dice_artifacts_buf = &mut [0u8; HWBCC_MAX_RESP_PAYLOAD_LENGTH];
103     assert!(get_dice_artifacts(0, dice_artifacts_buf).is_ok());
104 }
105 
106 #[test]
test_get_bcc_test_mode()107 fn test_get_bcc_test_mode() {
108     let mut bcc_buf = [0u8; HWBCC_MAX_RESP_PAYLOAD_LENGTH];
109 
110     let bcc = get_bcc(HwBccMode::Test, &mut bcc_buf).expect("could not get bcc");
111 
112     assert!(bcc.len() > 0);
113 
114     let dk_pub_key = &mut [0u8; ED25519_PUBLIC_KEY_LEN as usize];
115     let km_pub_key = &mut [0u8; ED25519_PUBLIC_KEY_LEN as usize];
116 
117     assert!(unsafe {
118         // SAFETY: the bcc bytes will be deserialized from CBOR
119         // and validated via copy, and not in-place. The original
120         // bytestring will remain valid after the check.
121         validate_bcc(
122             bcc.as_ptr(),
123             bcc.len(),
124             dk_pub_key as *mut [u8; ED25519_PUBLIC_KEY_LEN as usize],
125             km_pub_key as *mut [u8; ED25519_PUBLIC_KEY_LEN as usize],
126         )
127     });
128 
129     // get second set of keys
130     bcc_buf.fill(0);
131 
132     let bcc = get_bcc(HwBccMode::Test, &mut bcc_buf).expect("could not get bcc");
133 
134     assert!(bcc.len() > 0);
135 
136     let dk_pub_key2 = &mut [0u8; ED25519_PUBLIC_KEY_LEN as usize];
137     let km_pub_key2 = &mut [0u8; ED25519_PUBLIC_KEY_LEN as usize];
138 
139     assert!(unsafe {
140         // SAFETY: the bcc bytes will be deserialized from CBOR
141         // and validated via copy, and not in-place. The original
142         // bytestring will remain valid after the check.
143         validate_bcc(
144             bcc.as_ptr(),
145             bcc.len(),
146             dk_pub_key2 as *mut [u8; ED25519_PUBLIC_KEY_LEN as usize],
147             km_pub_key2 as *mut [u8; ED25519_PUBLIC_KEY_LEN as usize],
148         )
149     });
150 
151     /* the two sets of keys must be different in test mode */
152     assert_ne!(dk_pub_key, dk_pub_key2);
153     assert_ne!(km_pub_key, km_pub_key2);
154 }
155 
156 #[cfg(feature = "generic-arm-unittest")]
157 #[test]
test_get_bcc()158 fn test_get_bcc() {
159     /*
160      * Device key is hard-coded on emulator targets, i.e. BCC keys are fixed too.
161      * We test that BCC keys don't change to make sure that we don't accidentally
162      * change the key derivation procedure. Function of test TA app UUID.
163      */
164     const EMULATOR_PUB_KEY: &'static [u8; ED25519_PUBLIC_KEY_LEN as usize] = &[
165         0xc3, 0xfc, 0x8c, 0x92, 0x1d, 0x52, 0xb2, 0x34, 0x9f, 0x6d, 0x59, 0xa3, 0xcd, 0xcd, 0x4a,
166         0x8b, 0x1f, 0x97, 0xb6, 0x7b, 0xde, 0x2a, 0x7e, 0x2a, 0x46, 0xae, 0x98, 0x91, 0x47, 0xff,
167         0x5a, 0xef,
168     ];
169     let mut bcc_buf = [0u8; HWBCC_MAX_RESP_PAYLOAD_LENGTH];
170 
171     let bcc = get_bcc(HwBccMode::Release, &mut bcc_buf).expect("could not get bcc");
172 
173     assert!(bcc.len() > 0);
174 
175     let dk_pub_key = &mut [0u8; ED25519_PUBLIC_KEY_LEN as usize];
176     let km_pub_key = &mut [0u8; ED25519_PUBLIC_KEY_LEN as usize];
177 
178     assert!(unsafe {
179         // SAFETY: the bcc bytes will be deserialized from CBOR
180         // and validated via copy, and not in-place. The original
181         // bytestring will remain valid after the check.
182         validate_bcc(
183             bcc.as_ptr(),
184             bcc.len(),
185             dk_pub_key as *mut [u8; ED25519_PUBLIC_KEY_LEN as usize],
186             km_pub_key as *mut [u8; ED25519_PUBLIC_KEY_LEN as usize],
187         )
188     });
189 
190     assert_eq!(EMULATOR_PUB_KEY, dk_pub_key);
191     assert_eq!(dk_pub_key, km_pub_key);
192 }
193 
194 #[test]
test_sign_data_test_mode()195 fn test_sign_data_test_mode() {
196     let mut cose_sign1_buf = [0u8; HWBCC_MAX_RESP_PAYLOAD_LENGTH];
197 
198     let cose_sign1 = sign_data(
199         HwBccMode::Test,
200         SigningAlgorithm::ED25519,
201         TEST_MAC_KEY,
202         TEST_AAD,
203         &mut cose_sign1_buf,
204     )
205     .expect("could not sign data");
206 
207     assert!(cose_sign1.len() > 0);
208 }
209 
210 #[cfg(feature = "generic-arm-unittest")]
211 #[test]
test_sign_data()212 fn test_sign_data() {
213     let mut cose_sign1_buf = [0u8; HWBCC_MAX_RESP_PAYLOAD_LENGTH];
214 
215     let cose_sign1 = sign_data(
216         HwBccMode::Release,
217         SigningAlgorithm::ED25519,
218         TEST_MAC_KEY,
219         TEST_AAD,
220         &mut cose_sign1_buf,
221     )
222     .expect("could not sign data");
223 
224     assert!(cose_sign1.len() > 0);
225 }
226