• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022, 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 use nix::unistd::{Gid, Uid};
16 use serde::{Deserialize, Serialize};
17 
18 use openssl::encrypt::Encrypter;
19 use openssl::error::ErrorStack;
20 use openssl::hash::MessageDigest;
21 use openssl::pkey::PKey;
22 use openssl::pkey::Public;
23 use openssl::rsa::Padding;
24 use openssl::sign::Verifier;
25 use openssl::x509::X509;
26 
27 use binder::wait_for_interface;
28 
29 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
30     BlockMode::BlockMode, Digest::Digest, ErrorCode::ErrorCode,
31     KeyParameterValue::KeyParameterValue, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
32     SecurityLevel::SecurityLevel, Tag::Tag,
33 };
34 use android_system_keystore2::aidl::android::system::keystore2::{
35     CreateOperationResponse::CreateOperationResponse, Domain::Domain,
36     IKeystoreOperation::IKeystoreOperation, IKeystoreSecurityLevel::IKeystoreSecurityLevel,
37     IKeystoreService::IKeystoreService, KeyDescriptor::KeyDescriptor, KeyMetadata::KeyMetadata,
38     KeyParameters::KeyParameters, ResponseCode::ResponseCode,
39 };
40 
41 use packagemanager_aidl::aidl::android::content::pm::IPackageManagerNative::IPackageManagerNative;
42 
43 use keystore2_test_utils::{
44     authorizations, get_keystore_service, key_generations, key_generations::Error, run_as,
45 };
46 
47 /// This enum is used to communicate between parent and child processes.
48 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
49 pub enum TestOutcome {
50     Ok,
51     BackendBusy,
52     InvalidHandle,
53     OtherErr,
54 }
55 
56 /// This is used to notify the child or parent process that the expected state is reched.
57 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
58 pub struct BarrierReached;
59 
60 /// Forced operation.
61 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
62 pub struct ForcedOp(pub bool);
63 
64 /// Sample plain text input for encrypt operation.
65 pub const SAMPLE_PLAIN_TEXT: &[u8] = b"my message 11111";
66 
67 pub const PACKAGE_MANAGER_NATIVE_SERVICE: &str = "package_native";
68 pub const APP_ATTEST_KEY_FEATURE: &str = "android.hardware.keystore.app_attest_key";
69 
70 /// Determines whether app_attest_key_feature is supported or not.
app_attest_key_feature_exists() -> bool71 pub fn app_attest_key_feature_exists() -> bool {
72     let pm = wait_for_interface::<dyn IPackageManagerNative>(PACKAGE_MANAGER_NATIVE_SERVICE)
73         .expect("Failed to get package manager native service.");
74 
75     pm.hasSystemFeature(APP_ATTEST_KEY_FEATURE, 0).expect("hasSystemFeature failed.")
76 }
77 
78 #[macro_export]
79 macro_rules! skip_test_if_no_app_attest_key_feature {
80     () => {
81         if !app_attest_key_feature_exists() {
82             return;
83         }
84     };
85 }
86 
87 /// Indicate whether the default device is KeyMint (rather than Keymaster).
has_default_keymint() -> bool88 pub fn has_default_keymint() -> bool {
89     binder::is_declared("android.hardware.security.keymint.IKeyMintDevice/default")
90         .expect("Could not check for declared keymint interface")
91 }
92 
93 /// Generate EC key and grant it to the list of users with given access vector.
94 /// Returns the list of granted keys `nspace` values in the order of given grantee uids.
generate_ec_key_and_grant_to_users( keystore2: &binder::Strong<dyn IKeystoreService>, sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>, alias: Option<String>, grantee_uids: Vec<i32>, access_vector: i32, ) -> Result<Vec<i64>, binder::Status>95 pub fn generate_ec_key_and_grant_to_users(
96     keystore2: &binder::Strong<dyn IKeystoreService>,
97     sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
98     alias: Option<String>,
99     grantee_uids: Vec<i32>,
100     access_vector: i32,
101 ) -> Result<Vec<i64>, binder::Status> {
102     let key_metadata =
103         key_generations::generate_ec_p256_signing_key(sec_level, Domain::APP, -1, alias, None)?;
104 
105     let mut granted_keys = Vec::new();
106 
107     for uid in grantee_uids {
108         let granted_key = keystore2.grant(&key_metadata.key, uid, access_vector)?;
109         assert_eq!(granted_key.domain, Domain::GRANT);
110         granted_keys.push(granted_key.nspace);
111     }
112 
113     Ok(granted_keys)
114 }
115 
116 /// Generate a EC_P256 key using given domain, namespace and alias.
117 /// Create an operation using the generated key and perform sample signing operation.
create_signing_operation( forced_op: ForcedOp, op_purpose: KeyPurpose, op_digest: Digest, domain: Domain, nspace: i64, alias: Option<String>, ) -> binder::Result<CreateOperationResponse>118 pub fn create_signing_operation(
119     forced_op: ForcedOp,
120     op_purpose: KeyPurpose,
121     op_digest: Digest,
122     domain: Domain,
123     nspace: i64,
124     alias: Option<String>,
125 ) -> binder::Result<CreateOperationResponse> {
126     let keystore2 = get_keystore_service();
127     let sec_level = keystore2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
128 
129     let key_metadata =
130         key_generations::generate_ec_p256_signing_key(&sec_level, domain, nspace, alias, None)
131             .unwrap();
132 
133     sec_level.createOperation(
134         &key_metadata.key,
135         &authorizations::AuthSetBuilder::new().purpose(op_purpose).digest(op_digest),
136         forced_op.0,
137     )
138 }
139 
140 /// Performs sample signing operation.
perform_sample_sign_operation( op: &binder::Strong<dyn IKeystoreOperation>, ) -> Result<(), binder::Status>141 pub fn perform_sample_sign_operation(
142     op: &binder::Strong<dyn IKeystoreOperation>,
143 ) -> Result<(), binder::Status> {
144     op.update(b"my message")?;
145     let sig = op.finish(None, None)?;
146     assert!(sig.is_some());
147     Ok(())
148 }
149 
150 /// Perform sample HMAC sign and verify operations.
perform_sample_hmac_sign_verify_op( sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>, key: &KeyDescriptor, )151 pub fn perform_sample_hmac_sign_verify_op(
152     sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
153     key: &KeyDescriptor,
154 ) {
155     let sign_op = sec_level
156         .createOperation(
157             key,
158             &authorizations::AuthSetBuilder::new()
159                 .purpose(KeyPurpose::SIGN)
160                 .digest(Digest::SHA_2_256)
161                 .mac_length(256),
162             false,
163         )
164         .unwrap();
165     assert!(sign_op.iOperation.is_some());
166 
167     let op = sign_op.iOperation.unwrap();
168     op.update(b"my message").unwrap();
169     let sig = op.finish(None, None).unwrap();
170     assert!(sig.is_some());
171 
172     let sig = sig.unwrap();
173     let verify_op = sec_level
174         .createOperation(
175             key,
176             &authorizations::AuthSetBuilder::new()
177                 .purpose(KeyPurpose::VERIFY)
178                 .digest(Digest::SHA_2_256),
179             false,
180         )
181         .unwrap();
182     assert!(verify_op.iOperation.is_some());
183 
184     let op = verify_op.iOperation.unwrap();
185     let result = op.finish(Some(b"my message"), Some(&sig)).unwrap();
186     assert!(result.is_none());
187 }
188 
189 /// Map KeyMint Digest values to OpenSSL MessageDigest.
get_openssl_digest_mode(digest: Option<Digest>) -> MessageDigest190 pub fn get_openssl_digest_mode(digest: Option<Digest>) -> MessageDigest {
191     match digest {
192         Some(Digest::MD5) => MessageDigest::md5(),
193         Some(Digest::SHA1) => MessageDigest::sha1(),
194         Some(Digest::SHA_2_224) => MessageDigest::sha224(),
195         Some(Digest::SHA_2_256) => MessageDigest::sha256(),
196         Some(Digest::SHA_2_384) => MessageDigest::sha384(),
197         Some(Digest::SHA_2_512) => MessageDigest::sha512(),
198         _ => MessageDigest::sha256(),
199     }
200 }
201 
202 /// Map KeyMint PaddingMode values to OpenSSL Padding.
get_openssl_padding_mode(padding: PaddingMode) -> Padding203 pub fn get_openssl_padding_mode(padding: PaddingMode) -> Padding {
204     match padding {
205         PaddingMode::RSA_OAEP => Padding::PKCS1_OAEP,
206         PaddingMode::RSA_PSS => Padding::PKCS1_PSS,
207         PaddingMode::RSA_PKCS1_1_5_SIGN => Padding::PKCS1,
208         PaddingMode::RSA_PKCS1_1_5_ENCRYPT => Padding::PKCS1,
209         _ => Padding::NONE,
210     }
211 }
212 
213 /// Perform sample sign and verify operations using RSA or EC key.
perform_sample_asym_sign_verify_op( sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>, key_metadata: &KeyMetadata, padding: Option<PaddingMode>, digest: Option<Digest>, )214 pub fn perform_sample_asym_sign_verify_op(
215     sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
216     key_metadata: &KeyMetadata,
217     padding: Option<PaddingMode>,
218     digest: Option<Digest>,
219 ) {
220     let mut authorizations = authorizations::AuthSetBuilder::new().purpose(KeyPurpose::SIGN);
221     if let Some(value) = padding {
222         authorizations = authorizations.padding_mode(value);
223     }
224     if let Some(value) = digest {
225         authorizations = authorizations.digest(value);
226     }
227 
228     let sign_op = sec_level.createOperation(&key_metadata.key, &authorizations, false).unwrap();
229     assert!(sign_op.iOperation.is_some());
230 
231     let op = sign_op.iOperation.unwrap();
232     op.update(b"my message").unwrap();
233     let sig = op.finish(None, None).unwrap();
234     assert!(sig.is_some());
235 
236     let sig = sig.unwrap();
237     let cert_bytes = key_metadata.certificate.as_ref().unwrap();
238     let cert = X509::from_der(cert_bytes.as_ref()).unwrap();
239     let pub_key = cert.public_key().unwrap();
240     let mut verifier = Verifier::new(get_openssl_digest_mode(digest), pub_key.as_ref()).unwrap();
241     if let Some(value) = padding {
242         verifier.set_rsa_padding(get_openssl_padding_mode(value)).unwrap();
243     }
244     verifier.update(b"my message").unwrap();
245     assert!(verifier.verify(&sig).unwrap());
246 }
247 
248 /// Create new operation on child proc and perform simple operation after parent notification.
execute_op_run_as_child( target_ctx: &'static str, domain: Domain, nspace: i64, alias: Option<String>, auid: Uid, agid: Gid, forced_op: ForcedOp, ) -> run_as::ChildHandle<TestOutcome, BarrierReached>249 pub fn execute_op_run_as_child(
250     target_ctx: &'static str,
251     domain: Domain,
252     nspace: i64,
253     alias: Option<String>,
254     auid: Uid,
255     agid: Gid,
256     forced_op: ForcedOp,
257 ) -> run_as::ChildHandle<TestOutcome, BarrierReached> {
258     unsafe {
259         run_as::run_as_child(target_ctx, auid, agid, move |reader, writer| {
260             let result = key_generations::map_ks_error(create_signing_operation(
261                 forced_op,
262                 KeyPurpose::SIGN,
263                 Digest::SHA_2_256,
264                 domain,
265                 nspace,
266                 alias,
267             ));
268 
269             // Let the parent know that an operation has been started, then
270             // wait until the parent notifies us to continue, so the operation
271             // remains open.
272             writer.send(&BarrierReached {});
273             reader.recv();
274 
275             // Continue performing the operation after parent notifies.
276             match &result {
277                 Ok(CreateOperationResponse { iOperation: Some(op), .. }) => {
278                     match key_generations::map_ks_error(perform_sample_sign_operation(op)) {
279                         Ok(()) => TestOutcome::Ok,
280                         Err(Error::Km(ErrorCode::INVALID_OPERATION_HANDLE)) => {
281                             TestOutcome::InvalidHandle
282                         }
283                         Err(e) => panic!("Error in performing op: {:#?}", e),
284                     }
285                 }
286                 Ok(_) => TestOutcome::OtherErr,
287                 Err(Error::Rc(ResponseCode::BACKEND_BUSY)) => TestOutcome::BackendBusy,
288                 _ => TestOutcome::OtherErr,
289             }
290         })
291         .expect("Failed to create an operation.")
292     }
293 }
294 
295 /// Get NONCE value from given key parameters list.
get_op_nonce(parameters: &KeyParameters) -> Option<Vec<u8>>296 pub fn get_op_nonce(parameters: &KeyParameters) -> Option<Vec<u8>> {
297     for key_param in &parameters.keyParameter {
298         if key_param.tag == Tag::NONCE {
299             if let KeyParameterValue::Blob(val) = &key_param.value {
300                 return Some(val.clone());
301             }
302         }
303     }
304     None
305 }
306 
307 /// This performs sample encryption operation with given symmetric key (AES/3DES).
308 /// It encrypts `SAMPLE_PLAIN_TEXT` of length 128-bits.
perform_sample_sym_key_encrypt_op( sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>, padding_mode: PaddingMode, block_mode: BlockMode, nonce: &mut Option<Vec<u8>>, mac_len: Option<i32>, key: &KeyDescriptor, ) -> binder::Result<Option<Vec<u8>>>309 pub fn perform_sample_sym_key_encrypt_op(
310     sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
311     padding_mode: PaddingMode,
312     block_mode: BlockMode,
313     nonce: &mut Option<Vec<u8>>,
314     mac_len: Option<i32>,
315     key: &KeyDescriptor,
316 ) -> binder::Result<Option<Vec<u8>>> {
317     let mut op_params = authorizations::AuthSetBuilder::new()
318         .purpose(KeyPurpose::ENCRYPT)
319         .padding_mode(padding_mode)
320         .block_mode(block_mode);
321     if let Some(value) = nonce {
322         op_params = op_params.nonce(value.to_vec());
323     }
324 
325     if let Some(val) = mac_len {
326         op_params = op_params.mac_length(val);
327     }
328 
329     let op_response = sec_level.createOperation(key, &op_params, false)?;
330     assert!(op_response.iOperation.is_some());
331     let op = op_response.iOperation.unwrap();
332     if op_response.parameters.is_some() && nonce.is_none() {
333         *nonce = get_op_nonce(&op_response.parameters.unwrap());
334     }
335     op.finish(Some(SAMPLE_PLAIN_TEXT), None)
336 }
337 
338 /// This performs sample decryption operation with given symmetric key (AES/3DES).
perform_sample_sym_key_decrypt_op( sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>, input: &[u8], padding_mode: PaddingMode, block_mode: BlockMode, nonce: &mut Option<Vec<u8>>, mac_len: Option<i32>, key: &KeyDescriptor, ) -> binder::Result<Option<Vec<u8>>>339 pub fn perform_sample_sym_key_decrypt_op(
340     sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
341     input: &[u8],
342     padding_mode: PaddingMode,
343     block_mode: BlockMode,
344     nonce: &mut Option<Vec<u8>>,
345     mac_len: Option<i32>,
346     key: &KeyDescriptor,
347 ) -> binder::Result<Option<Vec<u8>>> {
348     let mut op_params = authorizations::AuthSetBuilder::new()
349         .purpose(KeyPurpose::DECRYPT)
350         .padding_mode(padding_mode)
351         .block_mode(block_mode);
352     if let Some(value) = nonce {
353         op_params = op_params.nonce(value.to_vec());
354     }
355 
356     if let Some(val) = mac_len {
357         op_params = op_params.mac_length(val);
358     }
359 
360     let op_response = sec_level.createOperation(key, &op_params, false)?;
361     assert!(op_response.iOperation.is_some());
362     let op = op_response.iOperation.unwrap();
363     op.finish(Some(input), None)
364 }
365 
366 /// Delete a key with domain APP.
delete_app_key( keystore2: &binder::Strong<dyn IKeystoreService>, alias: &str, ) -> binder::Result<()>367 pub fn delete_app_key(
368     keystore2: &binder::Strong<dyn IKeystoreService>,
369     alias: &str,
370 ) -> binder::Result<()> {
371     keystore2.deleteKey(&KeyDescriptor {
372         domain: Domain::APP,
373         nspace: -1,
374         alias: Some(alias.to_string()),
375         blob: None,
376     })
377 }
378 
379 /// Encrypt the secure key with given transport key.
encrypt_secure_key( sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>, secure_key: &[u8], aad: &[u8], nonce: Vec<u8>, mac_len: i32, key: &KeyDescriptor, ) -> binder::Result<Option<Vec<u8>>>380 pub fn encrypt_secure_key(
381     sec_level: &binder::Strong<dyn IKeystoreSecurityLevel>,
382     secure_key: &[u8],
383     aad: &[u8],
384     nonce: Vec<u8>,
385     mac_len: i32,
386     key: &KeyDescriptor,
387 ) -> binder::Result<Option<Vec<u8>>> {
388     let op_params = authorizations::AuthSetBuilder::new()
389         .purpose(KeyPurpose::ENCRYPT)
390         .padding_mode(PaddingMode::NONE)
391         .block_mode(BlockMode::GCM)
392         .nonce(nonce)
393         .mac_length(mac_len);
394 
395     let op_response = sec_level.createOperation(key, &op_params, false)?;
396 
397     let op = op_response.iOperation.unwrap();
398     op.updateAad(aad)?;
399     op.finish(Some(secure_key), None)
400 }
401 
402 /// Encrypt the transport key with given RSA wrapping key.
encrypt_transport_key( transport_key: &[u8], pkey: &PKey<Public>, ) -> Result<Vec<u8>, ErrorStack>403 pub fn encrypt_transport_key(
404     transport_key: &[u8],
405     pkey: &PKey<Public>,
406 ) -> Result<Vec<u8>, ErrorStack> {
407     let mut encrypter = Encrypter::new(pkey).unwrap();
408     encrypter.set_rsa_padding(Padding::PKCS1_OAEP).unwrap();
409     encrypter.set_rsa_oaep_md(MessageDigest::sha256()).unwrap();
410     encrypter.set_rsa_mgf1_md(MessageDigest::sha1()).unwrap();
411 
412     let input = transport_key.to_vec();
413     let buffer_len = encrypter.encrypt_len(&input).unwrap();
414     let mut encoded = vec![0u8; buffer_len];
415     let encoded_len = encrypter.encrypt(&input, &mut encoded).unwrap();
416     let encoded = &encoded[..encoded_len];
417 
418     Ok(encoded.to_vec())
419 }
420