blob: 78143648067ee3038aa0cb6985ed103a292a53d5 [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
Joel Galensonde386b42020-09-30 10:53:05 -070042 fn get_device() -> Box<dyn IKeyMintDevice> {
43 add_keymint_device_service();
44 let compat_service: Box<dyn IKeystoreCompatService> =
Joel Galensonf21c0022020-12-11 14:37:52 -080045 binder::get_interface(COMPAT_NAME).unwrap();
Joel Galensonde386b42020-09-30 10:53:05 -070046 compat_service.getKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap()
47 }
48
49 #[test]
50 fn test_get_hardware_info() {
51 let legacy = get_device();
Joel Galensond4dbfd52021-01-25 09:45:33 -080052 let hinfo = legacy.getHardwareInfo();
53 assert!(hinfo.is_ok());
Joel Galensonde386b42020-09-30 10:53:05 -070054 }
55
56 #[test]
Joel Galensonde386b42020-09-30 10:53:05 -070057 fn test_add_rng_entropy() {
58 let legacy = get_device();
59 let result = legacy.addRngEntropy(&[42; 16]);
60 assert!(result.is_ok(), "{:?}", result);
61 }
62
63 // TODO: If I only need the key itself, don't return the other things.
Shawn Willdendbdac602021-01-12 22:35:16 -070064 fn generate_key(legacy: &dyn IKeyMintDevice, kps: Vec<KeyParameter>) -> KeyCreationResult {
65 let creation_result = legacy.generateKey(&kps).expect("Failed to generate key");
66 assert_ne!(creation_result.keyBlob.len(), 0);
67 creation_result
Joel Galensonde386b42020-09-30 10:53:05 -070068 }
69
70 fn generate_rsa_key(legacy: &dyn IKeyMintDevice, encrypt: bool, attest: bool) -> Vec<u8> {
71 let mut kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -080072 KeyParameter {
73 tag: Tag::ALGORITHM,
74 value: KeyParameterValue::Algorithm(Algorithm::RSA),
75 },
76 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) },
Joel Galensonde386b42020-09-30 10:53:05 -070077 KeyParameter {
78 tag: Tag::RSA_PUBLIC_EXPONENT,
Janis Danisevskisb60c0042020-12-17 00:11:21 -080079 value: KeyParameterValue::LongInteger(65537),
Joel Galensonde386b42020-09-30 10:53:05 -070080 },
Janis Danisevskisb60c0042020-12-17 00:11:21 -080081 KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) },
Joel Galensonde386b42020-09-30 10:53:05 -070082 KeyParameter {
83 tag: Tag::PADDING,
Janis Danisevskisb60c0042020-12-17 00:11:21 -080084 value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
Joel Galensonde386b42020-09-30 10:53:05 -070085 },
Janis Danisevskisb60c0042020-12-17 00:11:21 -080086 KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
87 KeyParameter {
88 tag: Tag::PURPOSE,
89 value: KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
90 },
Joel Galensonde386b42020-09-30 10:53:05 -070091 ];
92 if encrypt {
93 kps.push(KeyParameter {
94 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -080095 value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -070096 });
97 }
98 if attest {
99 kps.push(KeyParameter {
100 tag: Tag::ATTESTATION_CHALLENGE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800101 value: KeyParameterValue::Blob(vec![42; 8]),
Joel Galensonde386b42020-09-30 10:53:05 -0700102 });
103 kps.push(KeyParameter {
104 tag: Tag::ATTESTATION_APPLICATION_ID,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800105 value: KeyParameterValue::Blob(vec![42; 8]),
Joel Galensonde386b42020-09-30 10:53:05 -0700106 });
107 }
Shawn Willdendbdac602021-01-12 22:35:16 -0700108 let creation_result = generate_key(legacy, kps);
Joel Galensonde386b42020-09-30 10:53:05 -0700109 if attest {
110 // TODO: Will this always be greater than 1?
Shawn Willdendbdac602021-01-12 22:35:16 -0700111 assert!(creation_result.certificateChain.len() > 1);
Joel Galensonde386b42020-09-30 10:53:05 -0700112 } else {
Shawn Willdendbdac602021-01-12 22:35:16 -0700113 assert_eq!(creation_result.certificateChain.len(), 1);
Joel Galensonde386b42020-09-30 10:53:05 -0700114 }
Shawn Willdendbdac602021-01-12 22:35:16 -0700115 creation_result.keyBlob
Joel Galensonde386b42020-09-30 10:53:05 -0700116 }
117
118 #[test]
119 fn test_generate_key_no_encrypt() {
120 let legacy = get_device();
121 generate_rsa_key(legacy.as_ref(), false, false);
122 }
123
124 #[test]
125 fn test_generate_key_encrypt() {
126 let legacy = get_device();
127 generate_rsa_key(legacy.as_ref(), true, false);
128 }
129
130 #[test]
131 fn test_generate_key_attested() {
132 let legacy = get_device();
133 generate_rsa_key(legacy.as_ref(), false, true);
134 }
135
136 #[test]
137 fn test_import_key() {
138 let legacy = get_device();
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800139 let kps = [KeyParameter {
140 tag: Tag::ALGORITHM,
141 value: KeyParameterValue::Algorithm(Algorithm::AES),
142 }];
Joel Galensonde386b42020-09-30 10:53:05 -0700143 let kf = KeyFormat::RAW;
144 let kd = [0; 16];
Shawn Willdendbdac602021-01-12 22:35:16 -0700145 let creation_result = legacy.importKey(&kps, kf, &kd).expect("Failed to import key");
146 assert_ne!(creation_result.keyBlob.len(), 0);
147 assert_eq!(creation_result.certificateChain.len(), 0);
Joel Galensonde386b42020-09-30 10:53:05 -0700148 }
149
150 #[test]
151 fn test_import_wrapped_key() {
152 let legacy = get_device();
Shawn Willdendbdac602021-01-12 22:35:16 -0700153 let result = legacy.importWrappedKey(&[], &[], &[], &[], 0, 0);
Joel Galensond4dbfd52021-01-25 09:45:33 -0800154 // For this test we only care that there was no crash.
155 assert!(result.is_ok() || result.is_err());
Joel Galensonde386b42020-09-30 10:53:05 -0700156 }
157
158 #[test]
159 fn test_upgrade_key() {
160 let legacy = get_device();
161 let blob = generate_rsa_key(legacy.as_ref(), false, false);
162 let result = legacy.upgradeKey(&blob, &[]);
Joel Galensond4dbfd52021-01-25 09:45:33 -0800163 // For this test we only care that there was no crash.
164 assert!(result.is_ok() || result.is_err());
Joel Galensonde386b42020-09-30 10:53:05 -0700165 }
166
167 #[test]
168 fn test_delete_key() {
169 let legacy = get_device();
170 let blob = generate_rsa_key(legacy.as_ref(), false, false);
171 let result = legacy.deleteKey(&blob);
172 assert!(result.is_ok(), "{:?}", result);
173 }
174
175 #[test]
176 fn test_delete_all_keys() {
177 let legacy = get_device();
178 let result = legacy.deleteAllKeys();
179 assert!(result.is_ok(), "{:?}", result);
180 }
181
182 #[test]
183 fn test_destroy_attestation_ids() {
184 let legacy = get_device();
185 let result = legacy.destroyAttestationIds();
186 assert!(result.is_err());
187 assert_eq!(result.unwrap_err().service_specific_error(), ErrorCode::UNIMPLEMENTED.0,);
188 }
189
190 fn generate_aes_key(legacy: &dyn IKeyMintDevice) -> Vec<u8> {
191 let kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800192 KeyParameter {
193 tag: Tag::ALGORITHM,
194 value: KeyParameterValue::Algorithm(Algorithm::AES),
195 },
196 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
197 KeyParameter {
198 tag: Tag::BLOCK_MODE,
199 value: KeyParameterValue::BlockMode(BlockMode::CBC),
200 },
201 KeyParameter {
202 tag: Tag::PADDING,
203 value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
204 },
205 KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
Joel Galensonde386b42020-09-30 10:53:05 -0700206 KeyParameter {
207 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800208 value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -0700209 },
210 KeyParameter {
211 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800212 value: KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -0700213 },
214 ];
Shawn Willdendbdac602021-01-12 22:35:16 -0700215 let creation_result = generate_key(legacy, kps);
216 assert_eq!(creation_result.certificateChain.len(), 0);
217 creation_result.keyBlob
Joel Galensonde386b42020-09-30 10:53:05 -0700218 }
219
220 fn begin(
221 legacy: &dyn IKeyMintDevice,
222 blob: &[u8],
223 purpose: KeyPurpose,
224 extra_params: Option<Vec<KeyParameter>>,
225 ) -> BeginResult {
226 let mut kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800227 KeyParameter {
228 tag: Tag::BLOCK_MODE,
229 value: KeyParameterValue::BlockMode(BlockMode::CBC),
230 },
231 KeyParameter {
232 tag: Tag::PADDING,
233 value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
234 },
Joel Galensonde386b42020-09-30 10:53:05 -0700235 ];
236 if let Some(mut extras) = extra_params {
237 kps.append(&mut extras);
238 }
239 let result = legacy.begin(purpose, &blob, &kps, &HardwareAuthToken::default());
240 assert!(result.is_ok(), "{:?}", result);
241 result.unwrap()
242 }
243
244 #[test]
245 fn test_begin_abort() {
246 let legacy = get_device();
247 let blob = generate_aes_key(legacy.as_ref());
248 let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
249 let operation = begin_result.operation.unwrap();
250 let result = operation.abort();
251 assert!(result.is_ok(), "{:?}", result);
252 let result = operation.abort();
253 assert!(result.is_err());
254 }
255
256 #[test]
257 fn test_begin_update_finish() {
258 let legacy = get_device();
259 let blob = generate_aes_key(legacy.as_ref());
260
261 let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
262 let operation = begin_result.operation.unwrap();
263 let params = KeyParameterArray {
264 params: vec![KeyParameter {
265 tag: Tag::ASSOCIATED_DATA,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800266 value: KeyParameterValue::Blob(b"foobar".to_vec()),
Joel Galensonde386b42020-09-30 10:53:05 -0700267 }],
268 };
269 let message = [42; 128];
270 let mut out_params = None;
271 let result =
272 operation.finish(Some(&params), Some(&message), None, None, None, &mut out_params);
273 assert!(result.is_ok(), "{:?}", result);
274 let ciphertext = result.unwrap();
275 assert!(!ciphertext.is_empty());
276 assert!(out_params.is_some());
277
278 let begin_result =
279 begin(legacy.as_ref(), &blob, KeyPurpose::DECRYPT, Some(begin_result.params));
280 let operation = begin_result.operation.unwrap();
281 let mut out_params = None;
282 let mut output = None;
283 let result = operation.update(
284 Some(&params),
285 Some(&ciphertext),
286 None,
287 None,
288 &mut out_params,
289 &mut output,
290 );
291 assert!(result.is_ok(), "{:?}", result);
292 assert_eq!(result.unwrap(), message.len() as i32);
293 assert!(output.is_some());
294 assert_eq!(output.unwrap().data, message.to_vec());
295 let result = operation.finish(Some(&params), None, None, None, None, &mut out_params);
296 assert!(result.is_ok(), "{:?}", result);
297 assert!(out_params.is_some());
298 }
Joel Galensonf21c0022020-12-11 14:37:52 -0800299
300 #[test]
301 fn test_secure_clock() {
302 add_keymint_device_service();
303 let compat_service: Box<dyn IKeystoreCompatService> =
304 binder::get_interface(COMPAT_NAME).unwrap();
305 let secure_clock = compat_service.getSecureClock().unwrap();
306
307 let challenge = 42;
308 let result = secure_clock.generateTimeStamp(challenge);
309 assert!(result.is_ok(), "{:?}", result);
310 let result = result.unwrap();
311 assert_eq!(result.challenge, challenge);
312 assert_eq!(result.mac.len(), 32);
313 }
314
315 #[test]
316 fn test_shared_secret() {
317 add_keymint_device_service();
318 let compat_service: Box<dyn IKeystoreCompatService> =
319 binder::get_interface(COMPAT_NAME).unwrap();
320 let shared_secret =
321 compat_service.getSharedSecret(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
322
323 let result = shared_secret.getSharedSecretParameters();
324 assert!(result.is_ok(), "{:?}", result);
325 let params = result.unwrap();
326
327 let result = shared_secret.computeSharedSecret(&[params]);
328 assert!(result.is_ok(), "{:?}", result);
329 assert_ne!(result.unwrap().len(), 0);
330 }
Joel Galensonde386b42020-09-30 10:53:05 -0700331}