blob: 097e6d4c8f680081567e962fd81e22f7ec537be9 [file] [log] [blame]
Joel Galensonde386b42020-09-30 10:53:05 -07001// Copyright 2020, The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// TODO: Once this is stable, remove this and document everything public.
16#![allow(missing_docs)]
17
18extern "C" {
19 fn addKeyMintDeviceService() -> i32;
20}
21
22pub fn add_keymint_device_service() -> i32 {
23 unsafe { addKeyMintDeviceService() }
24}
25
26#[cfg(test)]
27mod tests {
28
29 use super::*;
30 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
Shawn Willdendbdac602021-01-12 22:35:16 -070031 Algorithm::Algorithm, BeginResult::BeginResult, BlockMode::BlockMode, Digest::Digest,
32 ErrorCode::ErrorCode, HardwareAuthToken::HardwareAuthToken, IKeyMintDevice::IKeyMintDevice,
33 KeyCreationResult::KeyCreationResult, KeyFormat::KeyFormat, KeyParameter::KeyParameter,
Janis Danisevskisb60c0042020-12-17 00:11:21 -080034 KeyParameterArray::KeyParameterArray, KeyParameterValue::KeyParameterValue,
35 KeyPurpose::KeyPurpose, PaddingMode::PaddingMode, SecurityLevel::SecurityLevel, Tag::Tag,
Joel Galensonde386b42020-09-30 10:53:05 -070036 };
37 use android_hardware_security_keymint::binder;
38 use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
39
Joel Galensonf21c0022020-12-11 14:37:52 -080040 static COMPAT_NAME: &str = "android.security.compat";
41
Janis Danisevskis12913842021-02-01 13:49:25 -080042 fn get_device() -> Option<Box<dyn IKeyMintDevice>> {
Joel Galensonde386b42020-09-30 10:53:05 -070043 add_keymint_device_service();
44 let compat_service: Box<dyn IKeystoreCompatService> =
Janis Danisevskis12913842021-02-01 13:49:25 -080045 binder::get_interface(COMPAT_NAME).ok()?;
46 compat_service.getKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT).ok()
47 }
48
49 macro_rules! get_device_or_skip_test {
50 () => {
51 match get_device() {
52 Some(dev) => dev,
53 None => return,
54 }
55 };
Joel Galensonde386b42020-09-30 10:53:05 -070056 }
57
58 #[test]
59 fn test_get_hardware_info() {
Janis Danisevskis12913842021-02-01 13:49:25 -080060 let legacy = get_device_or_skip_test!();
Joel Galensond4dbfd52021-01-25 09:45:33 -080061 let hinfo = legacy.getHardwareInfo();
62 assert!(hinfo.is_ok());
Joel Galensonde386b42020-09-30 10:53:05 -070063 }
64
65 #[test]
Joel Galensonde386b42020-09-30 10:53:05 -070066 fn test_add_rng_entropy() {
Janis Danisevskis12913842021-02-01 13:49:25 -080067 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -070068 let result = legacy.addRngEntropy(&[42; 16]);
69 assert!(result.is_ok(), "{:?}", result);
70 }
71
72 // TODO: If I only need the key itself, don't return the other things.
Shawn Willdendbdac602021-01-12 22:35:16 -070073 fn generate_key(legacy: &dyn IKeyMintDevice, kps: Vec<KeyParameter>) -> KeyCreationResult {
74 let creation_result = legacy.generateKey(&kps).expect("Failed to generate key");
75 assert_ne!(creation_result.keyBlob.len(), 0);
76 creation_result
Joel Galensonde386b42020-09-30 10:53:05 -070077 }
78
Janis Danisevskis2c084012021-01-31 22:23:17 -080079 // Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to GeneralizedTime
80 // 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
81 const UNDEFINED_NOT_AFTER: i64 = 253402300799000i64;
82
Joel Galensonde386b42020-09-30 10:53:05 -070083 fn generate_rsa_key(legacy: &dyn IKeyMintDevice, encrypt: bool, attest: bool) -> Vec<u8> {
84 let mut kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -080085 KeyParameter {
86 tag: Tag::ALGORITHM,
87 value: KeyParameterValue::Algorithm(Algorithm::RSA),
88 },
89 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) },
Joel Galensonde386b42020-09-30 10:53:05 -070090 KeyParameter {
91 tag: Tag::RSA_PUBLIC_EXPONENT,
Janis Danisevskisb60c0042020-12-17 00:11:21 -080092 value: KeyParameterValue::LongInteger(65537),
Joel Galensonde386b42020-09-30 10:53:05 -070093 },
Janis Danisevskisb60c0042020-12-17 00:11:21 -080094 KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) },
Joel Galensonde386b42020-09-30 10:53:05 -070095 KeyParameter {
96 tag: Tag::PADDING,
Janis Danisevskisb60c0042020-12-17 00:11:21 -080097 value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
Joel Galensonde386b42020-09-30 10:53:05 -070098 },
Janis Danisevskisb60c0042020-12-17 00:11:21 -080099 KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
100 KeyParameter {
101 tag: Tag::PURPOSE,
102 value: KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
103 },
Janis Danisevskis2c084012021-01-31 22:23:17 -0800104 KeyParameter {
105 tag: Tag::CERTIFICATE_NOT_BEFORE,
106 value: KeyParameterValue::DateTime(0),
107 },
108 KeyParameter {
109 tag: Tag::CERTIFICATE_NOT_AFTER,
110 value: KeyParameterValue::DateTime(UNDEFINED_NOT_AFTER),
111 },
Joel Galensonde386b42020-09-30 10:53:05 -0700112 ];
113 if encrypt {
114 kps.push(KeyParameter {
115 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800116 value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -0700117 });
118 }
119 if attest {
120 kps.push(KeyParameter {
121 tag: Tag::ATTESTATION_CHALLENGE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800122 value: KeyParameterValue::Blob(vec![42; 8]),
Joel Galensonde386b42020-09-30 10:53:05 -0700123 });
124 kps.push(KeyParameter {
125 tag: Tag::ATTESTATION_APPLICATION_ID,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800126 value: KeyParameterValue::Blob(vec![42; 8]),
Joel Galensonde386b42020-09-30 10:53:05 -0700127 });
128 }
Shawn Willdendbdac602021-01-12 22:35:16 -0700129 let creation_result = generate_key(legacy, kps);
Joel Galensonde386b42020-09-30 10:53:05 -0700130 if attest {
131 // TODO: Will this always be greater than 1?
Shawn Willdendbdac602021-01-12 22:35:16 -0700132 assert!(creation_result.certificateChain.len() > 1);
Joel Galensonde386b42020-09-30 10:53:05 -0700133 } else {
Shawn Willdendbdac602021-01-12 22:35:16 -0700134 assert_eq!(creation_result.certificateChain.len(), 1);
Joel Galensonde386b42020-09-30 10:53:05 -0700135 }
Shawn Willdendbdac602021-01-12 22:35:16 -0700136 creation_result.keyBlob
Joel Galensonde386b42020-09-30 10:53:05 -0700137 }
138
139 #[test]
140 fn test_generate_key_no_encrypt() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800141 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700142 generate_rsa_key(legacy.as_ref(), false, false);
143 }
144
145 #[test]
146 fn test_generate_key_encrypt() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800147 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700148 generate_rsa_key(legacy.as_ref(), true, false);
149 }
150
151 #[test]
152 fn test_generate_key_attested() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800153 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700154 generate_rsa_key(legacy.as_ref(), false, true);
155 }
156
157 #[test]
158 fn test_import_key() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800159 let legacy = get_device_or_skip_test!();
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800160 let kps = [KeyParameter {
161 tag: Tag::ALGORITHM,
162 value: KeyParameterValue::Algorithm(Algorithm::AES),
163 }];
Joel Galensonde386b42020-09-30 10:53:05 -0700164 let kf = KeyFormat::RAW;
165 let kd = [0; 16];
Shawn Willdendbdac602021-01-12 22:35:16 -0700166 let creation_result = legacy.importKey(&kps, kf, &kd).expect("Failed to import key");
167 assert_ne!(creation_result.keyBlob.len(), 0);
168 assert_eq!(creation_result.certificateChain.len(), 0);
Joel Galensonde386b42020-09-30 10:53:05 -0700169 }
170
171 #[test]
172 fn test_import_wrapped_key() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800173 let legacy = get_device_or_skip_test!();
Shawn Willdendbdac602021-01-12 22:35:16 -0700174 let result = legacy.importWrappedKey(&[], &[], &[], &[], 0, 0);
Joel Galensond4dbfd52021-01-25 09:45:33 -0800175 // For this test we only care that there was no crash.
176 assert!(result.is_ok() || result.is_err());
Joel Galensonde386b42020-09-30 10:53:05 -0700177 }
178
179 #[test]
180 fn test_upgrade_key() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800181 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700182 let blob = generate_rsa_key(legacy.as_ref(), false, false);
183 let result = legacy.upgradeKey(&blob, &[]);
Joel Galensond4dbfd52021-01-25 09:45:33 -0800184 // For this test we only care that there was no crash.
185 assert!(result.is_ok() || result.is_err());
Joel Galensonde386b42020-09-30 10:53:05 -0700186 }
187
188 #[test]
189 fn test_delete_key() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800190 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700191 let blob = generate_rsa_key(legacy.as_ref(), false, false);
192 let result = legacy.deleteKey(&blob);
193 assert!(result.is_ok(), "{:?}", result);
194 }
195
196 #[test]
197 fn test_delete_all_keys() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800198 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700199 let result = legacy.deleteAllKeys();
200 assert!(result.is_ok(), "{:?}", result);
201 }
202
203 #[test]
204 fn test_destroy_attestation_ids() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800205 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700206 let result = legacy.destroyAttestationIds();
207 assert!(result.is_err());
208 assert_eq!(result.unwrap_err().service_specific_error(), ErrorCode::UNIMPLEMENTED.0,);
209 }
210
211 fn generate_aes_key(legacy: &dyn IKeyMintDevice) -> Vec<u8> {
212 let kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800213 KeyParameter {
214 tag: Tag::ALGORITHM,
215 value: KeyParameterValue::Algorithm(Algorithm::AES),
216 },
217 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
218 KeyParameter {
219 tag: Tag::BLOCK_MODE,
220 value: KeyParameterValue::BlockMode(BlockMode::CBC),
221 },
222 KeyParameter {
223 tag: Tag::PADDING,
224 value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
225 },
226 KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
Joel Galensonde386b42020-09-30 10:53:05 -0700227 KeyParameter {
228 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800229 value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -0700230 },
231 KeyParameter {
232 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800233 value: KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -0700234 },
235 ];
Shawn Willdendbdac602021-01-12 22:35:16 -0700236 let creation_result = generate_key(legacy, kps);
237 assert_eq!(creation_result.certificateChain.len(), 0);
238 creation_result.keyBlob
Joel Galensonde386b42020-09-30 10:53:05 -0700239 }
240
241 fn begin(
242 legacy: &dyn IKeyMintDevice,
243 blob: &[u8],
244 purpose: KeyPurpose,
245 extra_params: Option<Vec<KeyParameter>>,
246 ) -> BeginResult {
247 let mut kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800248 KeyParameter {
249 tag: Tag::BLOCK_MODE,
250 value: KeyParameterValue::BlockMode(BlockMode::CBC),
251 },
252 KeyParameter {
253 tag: Tag::PADDING,
254 value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
255 },
Joel Galensonde386b42020-09-30 10:53:05 -0700256 ];
257 if let Some(mut extras) = extra_params {
258 kps.append(&mut extras);
259 }
260 let result = legacy.begin(purpose, &blob, &kps, &HardwareAuthToken::default());
261 assert!(result.is_ok(), "{:?}", result);
262 result.unwrap()
263 }
264
265 #[test]
266 fn test_begin_abort() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800267 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700268 let blob = generate_aes_key(legacy.as_ref());
269 let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
270 let operation = begin_result.operation.unwrap();
271 let result = operation.abort();
272 assert!(result.is_ok(), "{:?}", result);
273 let result = operation.abort();
274 assert!(result.is_err());
275 }
276
277 #[test]
278 fn test_begin_update_finish() {
Janis Danisevskis12913842021-02-01 13:49:25 -0800279 let legacy = get_device_or_skip_test!();
Joel Galensonde386b42020-09-30 10:53:05 -0700280 let blob = generate_aes_key(legacy.as_ref());
281
282 let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
283 let operation = begin_result.operation.unwrap();
284 let params = KeyParameterArray {
285 params: vec![KeyParameter {
286 tag: Tag::ASSOCIATED_DATA,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800287 value: KeyParameterValue::Blob(b"foobar".to_vec()),
Joel Galensonde386b42020-09-30 10:53:05 -0700288 }],
289 };
290 let message = [42; 128];
291 let mut out_params = None;
292 let result =
293 operation.finish(Some(&params), Some(&message), None, None, None, &mut out_params);
294 assert!(result.is_ok(), "{:?}", result);
295 let ciphertext = result.unwrap();
296 assert!(!ciphertext.is_empty());
297 assert!(out_params.is_some());
298
299 let begin_result =
300 begin(legacy.as_ref(), &blob, KeyPurpose::DECRYPT, Some(begin_result.params));
301 let operation = begin_result.operation.unwrap();
302 let mut out_params = None;
303 let mut output = None;
304 let result = operation.update(
305 Some(&params),
306 Some(&ciphertext),
307 None,
308 None,
309 &mut out_params,
310 &mut output,
311 );
312 assert!(result.is_ok(), "{:?}", result);
313 assert_eq!(result.unwrap(), message.len() as i32);
314 assert!(output.is_some());
315 assert_eq!(output.unwrap().data, message.to_vec());
316 let result = operation.finish(Some(&params), None, None, None, None, &mut out_params);
317 assert!(result.is_ok(), "{:?}", result);
318 assert!(out_params.is_some());
319 }
Joel Galensonf21c0022020-12-11 14:37:52 -0800320
321 #[test]
322 fn test_secure_clock() {
323 add_keymint_device_service();
324 let compat_service: Box<dyn IKeystoreCompatService> =
325 binder::get_interface(COMPAT_NAME).unwrap();
326 let secure_clock = compat_service.getSecureClock().unwrap();
327
328 let challenge = 42;
329 let result = secure_clock.generateTimeStamp(challenge);
330 assert!(result.is_ok(), "{:?}", result);
331 let result = result.unwrap();
332 assert_eq!(result.challenge, challenge);
333 assert_eq!(result.mac.len(), 32);
334 }
335
336 #[test]
337 fn test_shared_secret() {
338 add_keymint_device_service();
339 let compat_service: Box<dyn IKeystoreCompatService> =
340 binder::get_interface(COMPAT_NAME).unwrap();
341 let shared_secret =
342 compat_service.getSharedSecret(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
343
344 let result = shared_secret.getSharedSecretParameters();
345 assert!(result.is_ok(), "{:?}", result);
346 let params = result.unwrap();
347
348 let result = shared_secret.computeSharedSecret(&[params]);
349 assert!(result.is_ok(), "{:?}", result);
350 assert_ne!(result.unwrap().len(), 0);
351 }
Joel Galensonde386b42020-09-30 10:53:05 -0700352}