• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 //! Export into Rust a function to create a KeyMintDevice and add it as a service.
16 
17 #[allow(missing_docs)] // TODO remove this
18 extern "C" {
addKeyMintDeviceService() -> i3219     fn addKeyMintDeviceService() -> i32;
20 }
21 
22 #[allow(missing_docs)] // TODO remove this
add_keymint_device_service() -> i3223 pub fn add_keymint_device_service() -> i32 {
24     // SAFETY: This is always safe to call.
25     unsafe { addKeyMintDeviceService() }
26 }
27 
28 #[cfg(test)]
29 mod tests {
30 
31     use super::*;
32     use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
33         Algorithm::Algorithm, BeginResult::BeginResult, BlockMode::BlockMode, Digest::Digest,
34         ErrorCode::ErrorCode, IKeyMintDevice::IKeyMintDevice, KeyCreationResult::KeyCreationResult,
35         KeyFormat::KeyFormat, KeyOrigin::KeyOrigin, KeyParameter::KeyParameter,
36         KeyParameterValue::KeyParameterValue, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
37         SecurityLevel::SecurityLevel, Tag::Tag,
38     };
39     use android_hardware_security_keymint::binder::{self, Strong};
40     use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
41 
42     static COMPAT_NAME: &str = "android.security.compat";
43 
get_device() -> Option<Strong<dyn IKeyMintDevice>>44     fn get_device() -> Option<Strong<dyn IKeyMintDevice>> {
45         add_keymint_device_service();
46         let compat_service: Strong<dyn IKeystoreCompatService> =
47             binder::get_interface(COMPAT_NAME).ok()?;
48         compat_service.getKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT).ok()
49     }
50 
51     macro_rules! get_device_or_skip_test {
52         () => {
53             match get_device() {
54                 Some(dev) => dev,
55                 None => return,
56             }
57         };
58     }
59 
60     #[test]
test_get_hardware_info()61     fn test_get_hardware_info() {
62         let legacy = get_device_or_skip_test!();
63         let hinfo = legacy.getHardwareInfo();
64         assert!(hinfo.is_ok());
65     }
66 
67     #[test]
test_add_rng_entropy()68     fn test_add_rng_entropy() {
69         let legacy = get_device_or_skip_test!();
70         let result = legacy.addRngEntropy(&[42; 16]);
71         assert!(result.is_ok(), "{:?}", result);
72     }
73 
74     // TODO: If I only need the key itself, don't return the other things.
generate_key(legacy: &dyn IKeyMintDevice, kps: Vec<KeyParameter>) -> KeyCreationResult75     fn generate_key(legacy: &dyn IKeyMintDevice, kps: Vec<KeyParameter>) -> KeyCreationResult {
76         let creation_result =
77             legacy.generateKey(&kps, None /* attest_key */).expect("Failed to generate key");
78         assert_ne!(creation_result.keyBlob.len(), 0);
79         creation_result
80     }
81 
82     // Per RFC 5280 4.1.2.5, an undefined expiration (not-after) field should be set to GeneralizedTime
83     // 999912312359559, which is 253402300799000 ms from Jan 1, 1970.
84     const UNDEFINED_NOT_AFTER: i64 = 253402300799000i64;
85 
generate_rsa_key(legacy: &dyn IKeyMintDevice, encrypt: bool, attest: bool) -> Vec<u8>86     fn generate_rsa_key(legacy: &dyn IKeyMintDevice, encrypt: bool, attest: bool) -> Vec<u8> {
87         let mut kps = vec![
88             KeyParameter {
89                 tag: Tag::ALGORITHM,
90                 value: KeyParameterValue::Algorithm(Algorithm::RSA),
91             },
92             KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) },
93             KeyParameter {
94                 tag: Tag::RSA_PUBLIC_EXPONENT,
95                 value: KeyParameterValue::LongInteger(65537),
96             },
97             KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) },
98             KeyParameter {
99                 tag: Tag::PADDING,
100                 value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
101             },
102             KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
103             KeyParameter {
104                 tag: Tag::PURPOSE,
105                 value: KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
106             },
107             KeyParameter {
108                 tag: Tag::CERTIFICATE_NOT_BEFORE,
109                 value: KeyParameterValue::DateTime(0),
110             },
111             KeyParameter {
112                 tag: Tag::CERTIFICATE_NOT_AFTER,
113                 value: KeyParameterValue::DateTime(UNDEFINED_NOT_AFTER),
114             },
115         ];
116         if encrypt {
117             kps.push(KeyParameter {
118                 tag: Tag::PURPOSE,
119                 value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
120             });
121         }
122         if attest {
123             kps.push(KeyParameter {
124                 tag: Tag::ATTESTATION_CHALLENGE,
125                 value: KeyParameterValue::Blob(vec![42; 8]),
126             });
127             kps.push(KeyParameter {
128                 tag: Tag::ATTESTATION_APPLICATION_ID,
129                 value: KeyParameterValue::Blob(vec![42; 8]),
130             });
131         }
132         let creation_result = generate_key(legacy, kps);
133         if attest {
134             // TODO: Will this always be greater than 1?
135             assert!(creation_result.certificateChain.len() > 1);
136         } else {
137             assert_eq!(creation_result.certificateChain.len(), 1);
138         }
139         creation_result.keyBlob
140     }
141 
142     #[test]
test_generate_key_no_encrypt()143     fn test_generate_key_no_encrypt() {
144         let legacy = get_device_or_skip_test!();
145         generate_rsa_key(legacy.as_ref(), false, false);
146     }
147 
148     #[test]
test_generate_key_encrypt()149     fn test_generate_key_encrypt() {
150         let legacy = get_device_or_skip_test!();
151         generate_rsa_key(legacy.as_ref(), true, false);
152     }
153 
154     #[test]
test_generate_key_attested()155     fn test_generate_key_attested() {
156         let legacy = get_device_or_skip_test!();
157         generate_rsa_key(legacy.as_ref(), false, true);
158     }
159 
160     #[test]
test_import_key()161     fn test_import_key() {
162         let legacy = get_device_or_skip_test!();
163         let kps = [KeyParameter {
164             tag: Tag::ALGORITHM,
165             value: KeyParameterValue::Algorithm(Algorithm::AES),
166         }];
167         let kf = KeyFormat::RAW;
168         let kd = [0; 16];
169         let creation_result =
170             legacy.importKey(&kps, kf, &kd, None /* attest_key */).expect("Failed to import key");
171         assert_ne!(creation_result.keyBlob.len(), 0);
172         assert_eq!(creation_result.certificateChain.len(), 0);
173     }
174 
175     #[test]
test_import_wrapped_key()176     fn test_import_wrapped_key() {
177         let legacy = get_device_or_skip_test!();
178         let result = legacy.importWrappedKey(&[], &[], &[], &[], 0, 0);
179         // For this test we only care that there was no crash.
180         assert!(result.is_ok() || result.is_err());
181     }
182 
183     #[test]
test_upgrade_key()184     fn test_upgrade_key() {
185         let legacy = get_device_or_skip_test!();
186         let blob = generate_rsa_key(legacy.as_ref(), false, false);
187         let result = legacy.upgradeKey(&blob, &[]);
188         // For this test we only care that there was no crash.
189         assert!(result.is_ok() || result.is_err());
190     }
191 
192     #[test]
test_delete_key()193     fn test_delete_key() {
194         let legacy = get_device_or_skip_test!();
195         let blob = generate_rsa_key(legacy.as_ref(), false, false);
196         let result = legacy.deleteKey(&blob);
197         assert!(result.is_ok(), "{:?}", result);
198     }
199 
200     #[test]
test_delete_all_keys()201     fn test_delete_all_keys() {
202         let legacy = get_device_or_skip_test!();
203         let result = legacy.deleteAllKeys();
204         assert!(result.is_ok(), "{:?}", result);
205     }
206 
207     #[test]
test_destroy_attestation_ids()208     fn test_destroy_attestation_ids() {
209         let legacy = get_device_or_skip_test!();
210         let result = legacy.destroyAttestationIds();
211         assert!(result.is_err());
212         assert_eq!(result.unwrap_err().service_specific_error(), ErrorCode::UNIMPLEMENTED.0,);
213     }
214 
generate_aes_key(legacy: &dyn IKeyMintDevice) -> Vec<u8>215     fn generate_aes_key(legacy: &dyn IKeyMintDevice) -> Vec<u8> {
216         let kps = vec![
217             KeyParameter {
218                 tag: Tag::ALGORITHM,
219                 value: KeyParameterValue::Algorithm(Algorithm::AES),
220             },
221             KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
222             KeyParameter {
223                 tag: Tag::BLOCK_MODE,
224                 value: KeyParameterValue::BlockMode(BlockMode::CBC),
225             },
226             KeyParameter {
227                 tag: Tag::PADDING,
228                 value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
229             },
230             KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
231             KeyParameter {
232                 tag: Tag::PURPOSE,
233                 value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
234             },
235             KeyParameter {
236                 tag: Tag::PURPOSE,
237                 value: KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
238             },
239         ];
240         let creation_result = generate_key(legacy, kps);
241         assert_eq!(creation_result.certificateChain.len(), 0);
242         creation_result.keyBlob
243     }
244 
begin( legacy: &dyn IKeyMintDevice, blob: &[u8], purpose: KeyPurpose, extra_params: Option<Vec<KeyParameter>>, ) -> BeginResult245     fn begin(
246         legacy: &dyn IKeyMintDevice,
247         blob: &[u8],
248         purpose: KeyPurpose,
249         extra_params: Option<Vec<KeyParameter>>,
250     ) -> BeginResult {
251         let mut kps = vec![
252             KeyParameter {
253                 tag: Tag::BLOCK_MODE,
254                 value: KeyParameterValue::BlockMode(BlockMode::CBC),
255             },
256             KeyParameter {
257                 tag: Tag::PADDING,
258                 value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
259             },
260         ];
261         if let Some(mut extras) = extra_params {
262             kps.append(&mut extras);
263         }
264         let result = legacy.begin(purpose, blob, &kps, None);
265         assert!(result.is_ok(), "{:?}", result);
266         result.unwrap()
267     }
268 
269     #[test]
test_begin_abort()270     fn test_begin_abort() {
271         let legacy = get_device_or_skip_test!();
272         let blob = generate_aes_key(legacy.as_ref());
273         let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
274         let operation = begin_result.operation.unwrap();
275         let result = operation.abort();
276         assert!(result.is_ok(), "{:?}", result);
277         let result = operation.abort();
278         assert!(result.is_err());
279     }
280 
281     #[test]
test_begin_update_finish()282     fn test_begin_update_finish() {
283         let legacy = get_device_or_skip_test!();
284         let blob = generate_aes_key(legacy.as_ref());
285 
286         let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
287         let operation = begin_result.operation.unwrap();
288 
289         let update_aad_result = operation.updateAad(
290             b"foobar".as_ref(),
291             None, /* authToken */
292             None, /* timestampToken */
293         );
294         assert!(update_aad_result.is_ok(), "{:?}", update_aad_result);
295 
296         let message = [42; 128];
297         let result = operation.finish(
298             Some(&message),
299             None, /* signature */
300             None, /* authToken */
301             None, /* timestampToken */
302             None, /* confirmationToken */
303         );
304         assert!(result.is_ok(), "{:?}", result);
305         let ciphertext = result.unwrap();
306         assert!(!ciphertext.is_empty());
307 
308         let begin_result =
309             begin(legacy.as_ref(), &blob, KeyPurpose::DECRYPT, Some(begin_result.params));
310 
311         let operation = begin_result.operation.unwrap();
312 
313         let update_aad_result = operation.updateAad(
314             b"foobar".as_ref(),
315             None, /* authToken */
316             None, /* timestampToken */
317         );
318         assert!(update_aad_result.is_ok(), "{:?}", update_aad_result);
319 
320         let result = operation.update(
321             &ciphertext,
322             None, /* authToken */
323             None, /* timestampToken */
324         );
325         assert!(result.is_ok(), "{:?}", result);
326         assert_eq!(result.unwrap(), message);
327         let result = operation.finish(
328             None, /* input */
329             None, /* signature */
330             None, /* authToken */
331             None, /* timestampToken */
332             None, /* confirmationToken */
333         );
334         assert!(result.is_ok(), "{:?}", result);
335     }
336 
337     #[test]
test_secure_clock()338     fn test_secure_clock() {
339         add_keymint_device_service();
340         let compat_service: binder::Strong<dyn IKeystoreCompatService> =
341             match binder::get_interface(COMPAT_NAME) {
342                 Ok(cs) => cs,
343                 _ => return,
344             };
345         let secure_clock = match compat_service.getSecureClock() {
346             Ok(sc) => sc,
347             _ => return,
348         };
349 
350         let challenge = 42;
351         let result = secure_clock.generateTimeStamp(challenge);
352         assert!(result.is_ok(), "{:?}", result);
353         let result = result.unwrap();
354         assert_eq!(result.challenge, challenge);
355         assert_eq!(result.mac.len(), 32);
356     }
357 
358     #[test]
test_shared_secret()359     fn test_shared_secret() {
360         add_keymint_device_service();
361         let compat_service: binder::Strong<dyn IKeystoreCompatService> =
362             match binder::get_interface(COMPAT_NAME) {
363                 Ok(cs) => cs,
364                 _ => return,
365             };
366         let shared_secret = match compat_service.getSharedSecret(SecurityLevel::TRUSTED_ENVIRONMENT)
367         {
368             Ok(ss) => ss,
369             _ => return,
370         };
371 
372         let result = shared_secret.getSharedSecretParameters();
373         assert!(result.is_ok(), "{:?}", result);
374         let params = result.unwrap();
375 
376         let result = shared_secret.computeSharedSecret(&[params]);
377         assert!(result.is_ok(), "{:?}", result);
378         assert_ne!(result.unwrap().len(), 0);
379     }
380 
381     #[test]
test_get_key_characteristics()382     fn test_get_key_characteristics() {
383         let legacy = get_device_or_skip_test!();
384         let hw_info = legacy.getHardwareInfo().expect("GetHardwareInfo");
385 
386         let blob = generate_rsa_key(legacy.as_ref(), false, false);
387         let characteristics =
388             legacy.getKeyCharacteristics(&blob, &[], &[]).expect("GetKeyCharacteristics.");
389 
390         assert!(characteristics.iter().any(|kc| kc.securityLevel == hw_info.securityLevel));
391         let sec_level_enforced = &characteristics
392             .iter()
393             .find(|kc| kc.securityLevel == hw_info.securityLevel)
394             .expect("There should be characteristics matching the device's security level.")
395             .authorizations;
396 
397         assert!(sec_level_enforced.iter().any(|kp| matches!(
398             kp,
399             KeyParameter {
400                 tag: Tag::PURPOSE,
401                 value: KeyParameterValue::KeyPurpose(KeyPurpose::SIGN)
402             }
403         )));
404         assert!(sec_level_enforced.iter().any(|kp| matches!(
405             kp,
406             KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) }
407         )));
408         assert!(sec_level_enforced.iter().any(|kp| matches!(
409             kp,
410             KeyParameter {
411                 tag: Tag::PADDING,
412                 value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS)
413             }
414         )));
415         assert!(sec_level_enforced.iter().any(|kp| matches!(
416             kp,
417             KeyParameter {
418                 tag: Tag::ALGORITHM,
419                 value: KeyParameterValue::Algorithm(Algorithm::RSA)
420             }
421         )));
422         assert!(sec_level_enforced.iter().any(|kp| matches!(
423             kp,
424             KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) }
425         )));
426         assert!(sec_level_enforced.iter().any(|kp| matches!(
427             kp,
428             KeyParameter {
429                 tag: Tag::RSA_PUBLIC_EXPONENT,
430                 value: KeyParameterValue::LongInteger(65537)
431             }
432         )));
433         assert!(sec_level_enforced.iter().any(|kp| matches!(
434             kp,
435             KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) }
436         )));
437         assert!(sec_level_enforced.iter().any(|kp| matches!(
438             kp,
439             KeyParameter {
440                 tag: Tag::ORIGIN,
441                 value: KeyParameterValue::Origin(KeyOrigin::GENERATED)
442             }
443         )));
444         assert!(sec_level_enforced.iter().any(|kp| matches!(
445             kp,
446             KeyParameter { tag: Tag::OS_VERSION, value: KeyParameterValue::Integer(_) }
447         )));
448         assert!(sec_level_enforced.iter().any(|kp| matches!(
449             kp,
450             KeyParameter { tag: Tag::OS_PATCHLEVEL, value: KeyParameterValue::Integer(_) }
451         )));
452         assert!(sec_level_enforced.iter().any(|kp| matches!(
453             kp,
454             KeyParameter { tag: Tag::VENDOR_PATCHLEVEL, value: KeyParameterValue::Integer(_) }
455         )));
456         assert!(sec_level_enforced.iter().any(|kp| matches!(
457             kp,
458             KeyParameter { tag: Tag::BOOT_PATCHLEVEL, value: KeyParameterValue::Integer(_) }
459         )));
460     }
461 }
462