blob: 6d3aa96f307708b6375144f3302d72b5fe319735 [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
40 fn get_device() -> Box<dyn IKeyMintDevice> {
41 add_keymint_device_service();
42 let compat_service: Box<dyn IKeystoreCompatService> =
43 binder::get_interface("android.security.compat").unwrap();
44 compat_service.getKeyMintDevice(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap()
45 }
46
47 #[test]
48 fn test_get_hardware_info() {
49 let legacy = get_device();
50 let hinfo = legacy.getHardwareInfo().unwrap();
51 assert_eq!(hinfo.versionNumber, 0);
52 assert_ne!(hinfo.securityLevel, SecurityLevel::SOFTWARE);
53 assert_eq!(hinfo.keyMintName, "RemoteKeymaster");
54 assert_eq!(hinfo.keyMintAuthorName, "Google");
55 }
56
57 #[test]
58 fn test_verify_authorization() {
59 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::HardwareAuthToken::HardwareAuthToken;
60 let legacy = get_device();
61 let result = legacy.verifyAuthorization(0, &HardwareAuthToken::default());
62 assert!(result.is_err());
63 assert_eq!(result.unwrap_err().service_specific_error(), ErrorCode::UNIMPLEMENTED.0,);
64 }
65
66 #[test]
67 fn test_add_rng_entropy() {
68 let legacy = get_device();
69 let result = legacy.addRngEntropy(&[42; 16]);
70 assert!(result.is_ok(), "{:?}", result);
71 }
72
73 // TODO: If I only need the key itself, don't return the other things.
Shawn Willdendbdac602021-01-12 22:35:16 -070074 fn generate_key(legacy: &dyn IKeyMintDevice, kps: Vec<KeyParameter>) -> KeyCreationResult {
75 let creation_result = legacy.generateKey(&kps).expect("Failed to generate key");
76 assert_ne!(creation_result.keyBlob.len(), 0);
77 creation_result
Joel Galensonde386b42020-09-30 10:53:05 -070078 }
79
80 fn generate_rsa_key(legacy: &dyn IKeyMintDevice, encrypt: bool, attest: bool) -> Vec<u8> {
81 let mut kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -080082 KeyParameter {
83 tag: Tag::ALGORITHM,
84 value: KeyParameterValue::Algorithm(Algorithm::RSA),
85 },
86 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(2048) },
Joel Galensonde386b42020-09-30 10:53:05 -070087 KeyParameter {
88 tag: Tag::RSA_PUBLIC_EXPONENT,
Janis Danisevskisb60c0042020-12-17 00:11:21 -080089 value: KeyParameterValue::LongInteger(65537),
Joel Galensonde386b42020-09-30 10:53:05 -070090 },
Janis Danisevskisb60c0042020-12-17 00:11:21 -080091 KeyParameter { tag: Tag::DIGEST, value: KeyParameterValue::Digest(Digest::SHA_2_256) },
Joel Galensonde386b42020-09-30 10:53:05 -070092 KeyParameter {
93 tag: Tag::PADDING,
Janis Danisevskisb60c0042020-12-17 00:11:21 -080094 value: KeyParameterValue::PaddingMode(PaddingMode::RSA_PSS),
Joel Galensonde386b42020-09-30 10:53:05 -070095 },
Janis Danisevskisb60c0042020-12-17 00:11:21 -080096 KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
97 KeyParameter {
98 tag: Tag::PURPOSE,
99 value: KeyParameterValue::KeyPurpose(KeyPurpose::SIGN),
100 },
Joel Galensonde386b42020-09-30 10:53:05 -0700101 ];
102 if encrypt {
103 kps.push(KeyParameter {
104 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800105 value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -0700106 });
107 }
108 if attest {
109 kps.push(KeyParameter {
110 tag: Tag::ATTESTATION_CHALLENGE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800111 value: KeyParameterValue::Blob(vec![42; 8]),
Joel Galensonde386b42020-09-30 10:53:05 -0700112 });
113 kps.push(KeyParameter {
114 tag: Tag::ATTESTATION_APPLICATION_ID,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800115 value: KeyParameterValue::Blob(vec![42; 8]),
Joel Galensonde386b42020-09-30 10:53:05 -0700116 });
117 }
Shawn Willdendbdac602021-01-12 22:35:16 -0700118 let creation_result = generate_key(legacy, kps);
Joel Galensonde386b42020-09-30 10:53:05 -0700119 if attest {
120 // TODO: Will this always be greater than 1?
Shawn Willdendbdac602021-01-12 22:35:16 -0700121 assert!(creation_result.certificateChain.len() > 1);
Joel Galensonde386b42020-09-30 10:53:05 -0700122 } else {
Shawn Willdendbdac602021-01-12 22:35:16 -0700123 assert_eq!(creation_result.certificateChain.len(), 1);
Joel Galensonde386b42020-09-30 10:53:05 -0700124 }
Shawn Willdendbdac602021-01-12 22:35:16 -0700125 creation_result.keyBlob
Joel Galensonde386b42020-09-30 10:53:05 -0700126 }
127
128 #[test]
129 fn test_generate_key_no_encrypt() {
130 let legacy = get_device();
131 generate_rsa_key(legacy.as_ref(), false, false);
132 }
133
134 #[test]
135 fn test_generate_key_encrypt() {
136 let legacy = get_device();
137 generate_rsa_key(legacy.as_ref(), true, false);
138 }
139
140 #[test]
141 fn test_generate_key_attested() {
142 let legacy = get_device();
143 generate_rsa_key(legacy.as_ref(), false, true);
144 }
145
146 #[test]
147 fn test_import_key() {
148 let legacy = get_device();
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800149 let kps = [KeyParameter {
150 tag: Tag::ALGORITHM,
151 value: KeyParameterValue::Algorithm(Algorithm::AES),
152 }];
Joel Galensonde386b42020-09-30 10:53:05 -0700153 let kf = KeyFormat::RAW;
154 let kd = [0; 16];
Shawn Willdendbdac602021-01-12 22:35:16 -0700155 let creation_result = legacy.importKey(&kps, kf, &kd).expect("Failed to import key");
156 assert_ne!(creation_result.keyBlob.len(), 0);
157 assert_eq!(creation_result.certificateChain.len(), 0);
Joel Galensonde386b42020-09-30 10:53:05 -0700158 }
159
160 #[test]
161 fn test_import_wrapped_key() {
162 let legacy = get_device();
Shawn Willdendbdac602021-01-12 22:35:16 -0700163 let result = legacy.importWrappedKey(&[], &[], &[], &[], 0, 0);
Joel Galensonde386b42020-09-30 10:53:05 -0700164 // TODO: This test seems to fail on cuttlefish. How should I test it?
165 assert!(result.is_err());
166 }
167
168 #[test]
169 fn test_upgrade_key() {
170 let legacy = get_device();
171 let blob = generate_rsa_key(legacy.as_ref(), false, false);
172 let result = legacy.upgradeKey(&blob, &[]);
173 // TODO: This test seems to fail on cuttlefish. How should I test it?
174 assert!(result.is_err());
175 }
176
177 #[test]
178 fn test_delete_key() {
179 let legacy = get_device();
180 let blob = generate_rsa_key(legacy.as_ref(), false, false);
181 let result = legacy.deleteKey(&blob);
182 assert!(result.is_ok(), "{:?}", result);
183 }
184
185 #[test]
186 fn test_delete_all_keys() {
187 let legacy = get_device();
188 let result = legacy.deleteAllKeys();
189 assert!(result.is_ok(), "{:?}", result);
190 }
191
192 #[test]
193 fn test_destroy_attestation_ids() {
194 let legacy = get_device();
195 let result = legacy.destroyAttestationIds();
196 assert!(result.is_err());
197 assert_eq!(result.unwrap_err().service_specific_error(), ErrorCode::UNIMPLEMENTED.0,);
198 }
199
200 fn generate_aes_key(legacy: &dyn IKeyMintDevice) -> Vec<u8> {
201 let kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800202 KeyParameter {
203 tag: Tag::ALGORITHM,
204 value: KeyParameterValue::Algorithm(Algorithm::AES),
205 },
206 KeyParameter { tag: Tag::KEY_SIZE, value: KeyParameterValue::Integer(128) },
207 KeyParameter {
208 tag: Tag::BLOCK_MODE,
209 value: KeyParameterValue::BlockMode(BlockMode::CBC),
210 },
211 KeyParameter {
212 tag: Tag::PADDING,
213 value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
214 },
215 KeyParameter { tag: Tag::NO_AUTH_REQUIRED, value: KeyParameterValue::BoolValue(true) },
Joel Galensonde386b42020-09-30 10:53:05 -0700216 KeyParameter {
217 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800218 value: KeyParameterValue::KeyPurpose(KeyPurpose::ENCRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -0700219 },
220 KeyParameter {
221 tag: Tag::PURPOSE,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800222 value: KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
Joel Galensonde386b42020-09-30 10:53:05 -0700223 },
224 ];
Shawn Willdendbdac602021-01-12 22:35:16 -0700225 let creation_result = generate_key(legacy, kps);
226 assert_eq!(creation_result.certificateChain.len(), 0);
227 creation_result.keyBlob
Joel Galensonde386b42020-09-30 10:53:05 -0700228 }
229
230 fn begin(
231 legacy: &dyn IKeyMintDevice,
232 blob: &[u8],
233 purpose: KeyPurpose,
234 extra_params: Option<Vec<KeyParameter>>,
235 ) -> BeginResult {
236 let mut kps = vec![
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800237 KeyParameter {
238 tag: Tag::BLOCK_MODE,
239 value: KeyParameterValue::BlockMode(BlockMode::CBC),
240 },
241 KeyParameter {
242 tag: Tag::PADDING,
243 value: KeyParameterValue::PaddingMode(PaddingMode::NONE),
244 },
Joel Galensonde386b42020-09-30 10:53:05 -0700245 ];
246 if let Some(mut extras) = extra_params {
247 kps.append(&mut extras);
248 }
249 let result = legacy.begin(purpose, &blob, &kps, &HardwareAuthToken::default());
250 assert!(result.is_ok(), "{:?}", result);
251 result.unwrap()
252 }
253
254 #[test]
255 fn test_begin_abort() {
256 let legacy = get_device();
257 let blob = generate_aes_key(legacy.as_ref());
258 let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
259 let operation = begin_result.operation.unwrap();
260 let result = operation.abort();
261 assert!(result.is_ok(), "{:?}", result);
262 let result = operation.abort();
263 assert!(result.is_err());
264 }
265
266 #[test]
267 fn test_begin_update_finish() {
268 let legacy = get_device();
269 let blob = generate_aes_key(legacy.as_ref());
270
271 let begin_result = begin(legacy.as_ref(), &blob, KeyPurpose::ENCRYPT, None);
272 let operation = begin_result.operation.unwrap();
273 let params = KeyParameterArray {
274 params: vec![KeyParameter {
275 tag: Tag::ASSOCIATED_DATA,
Janis Danisevskisb60c0042020-12-17 00:11:21 -0800276 value: KeyParameterValue::Blob(b"foobar".to_vec()),
Joel Galensonde386b42020-09-30 10:53:05 -0700277 }],
278 };
279 let message = [42; 128];
280 let mut out_params = None;
281 let result =
282 operation.finish(Some(&params), Some(&message), None, None, None, &mut out_params);
283 assert!(result.is_ok(), "{:?}", result);
284 let ciphertext = result.unwrap();
285 assert!(!ciphertext.is_empty());
286 assert!(out_params.is_some());
287
288 let begin_result =
289 begin(legacy.as_ref(), &blob, KeyPurpose::DECRYPT, Some(begin_result.params));
290 let operation = begin_result.operation.unwrap();
291 let mut out_params = None;
292 let mut output = None;
293 let result = operation.update(
294 Some(&params),
295 Some(&ciphertext),
296 None,
297 None,
298 &mut out_params,
299 &mut output,
300 );
301 assert!(result.is_ok(), "{:?}", result);
302 assert_eq!(result.unwrap(), message.len() as i32);
303 assert!(output.is_some());
304 assert_eq!(output.unwrap().data, message.to_vec());
305 let result = operation.finish(Some(&params), None, None, None, None, &mut out_params);
306 assert!(result.is_ok(), "{:?}", result);
307 assert!(out_params.is_some());
308 }
309}