• 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 use crate::{
16     boot_level_keys::{get_level_zero_key, BootLevelKeyCache},
17     database::BlobMetaData,
18     database::BlobMetaEntry,
19     database::EncryptedBy,
20     database::KeyEntry,
21     database::KeyType,
22     database::{KeyEntryLoadBits, KeyIdGuard, KeyMetaData, KeyMetaEntry, KeystoreDB},
23     ec_crypto::ECDHPrivateKey,
24     enforcements::Enforcements,
25     error::Error,
26     error::ResponseCode,
27     key_parameter::{KeyParameter, KeyParameterValue},
28     ks_err,
29     legacy_importer::LegacyImporter,
30     raw_device::KeyMintDevice,
31     utils::{watchdog as wd, AesGcm, AID_KEYSTORE},
32 };
33 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
34     Algorithm::Algorithm, BlockMode::BlockMode, HardwareAuthToken::HardwareAuthToken,
35     HardwareAuthenticatorType::HardwareAuthenticatorType, KeyFormat::KeyFormat,
36     KeyParameter::KeyParameter as KmKeyParameter, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
37     SecurityLevel::SecurityLevel,
38 };
39 use android_system_keystore2::aidl::android::system::keystore2::{
40     Domain::Domain, KeyDescriptor::KeyDescriptor,
41 };
42 use anyhow::{Context, Result};
43 use keystore2_crypto::{
44     aes_gcm_decrypt, aes_gcm_encrypt, generate_aes256_key, generate_salt, Password, ZVec,
45     AES_256_KEY_LENGTH,
46 };
47 use rustutils::system_properties::PropertyWatcher;
48 use std::{
49     collections::HashMap,
50     sync::Arc,
51     sync::{Mutex, RwLock, Weak},
52 };
53 use std::{convert::TryFrom, ops::Deref};
54 
55 const MAX_MAX_BOOT_LEVEL: usize = 1_000_000_000;
56 /// Allow up to 15 seconds between the user unlocking using a biometric, and the auth
57 /// token being used to unlock in [`SuperKeyManager::try_unlock_user_with_biometric`].
58 /// This seems short enough for security purposes, while long enough that even the
59 /// very slowest device will present the auth token in time.
60 const BIOMETRIC_AUTH_TIMEOUT_S: i32 = 15; // seconds
61 
62 type UserId = u32;
63 
64 /// Encryption algorithm used by a particular type of superencryption key
65 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
66 pub enum SuperEncryptionAlgorithm {
67     /// Symmetric encryption with AES-256-GCM
68     Aes256Gcm,
69     /// Public-key encryption with ECDH P-521
70     EcdhP521,
71 }
72 
73 /// A particular user may have several superencryption keys in the database, each for a
74 /// different purpose, distinguished by alias. Each is associated with a static
75 /// constant of this type.
76 pub struct SuperKeyType<'a> {
77     /// Alias used to look up the key in the `persistent.keyentry` table.
78     pub alias: &'a str,
79     /// Encryption algorithm
80     pub algorithm: SuperEncryptionAlgorithm,
81     /// What to call this key in log messages. Not used for anything else.
82     pub name: &'a str,
83 }
84 
85 /// The user's AfterFirstUnlock super key. This super key is loaded into memory when the user first
86 /// unlocks the device, and it remains in memory until the device reboots. This is used to encrypt
87 /// keys that require user authentication but not an unlocked device.
88 pub const USER_AFTER_FIRST_UNLOCK_SUPER_KEY: SuperKeyType = SuperKeyType {
89     alias: "USER_SUPER_KEY",
90     algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
91     name: "AfterFirstUnlock super key",
92 };
93 
94 /// The user's UnlockedDeviceRequired symmetric super key. This super key is loaded into memory each
95 /// time the user unlocks the device, and it is cleared from memory each time the user locks the
96 /// device. This is used to encrypt keys that use the UnlockedDeviceRequired key parameter.
97 pub const USER_UNLOCKED_DEVICE_REQUIRED_SYMMETRIC_SUPER_KEY: SuperKeyType = SuperKeyType {
98     alias: "USER_SCREEN_LOCK_BOUND_KEY",
99     algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
100     name: "UnlockedDeviceRequired symmetric super key",
101 };
102 
103 /// The user's UnlockedDeviceRequired asymmetric super key. This is used to allow, while the device
104 /// is locked, the creation of keys that use the UnlockedDeviceRequired key parameter. The private
105 /// part of this key is loaded and cleared when the symmetric key is loaded and cleared.
106 pub const USER_UNLOCKED_DEVICE_REQUIRED_P521_SUPER_KEY: SuperKeyType = SuperKeyType {
107     alias: "USER_SCREEN_LOCK_BOUND_P521_KEY",
108     algorithm: SuperEncryptionAlgorithm::EcdhP521,
109     name: "UnlockedDeviceRequired asymmetric super key",
110 };
111 
112 /// Superencryption to apply to a new key.
113 #[derive(Debug, Clone, Copy)]
114 pub enum SuperEncryptionType {
115     /// Do not superencrypt this key.
116     None,
117     /// Superencrypt with the AfterFirstUnlock super key.
118     AfterFirstUnlock,
119     /// Superencrypt with an UnlockedDeviceRequired super key.
120     UnlockedDeviceRequired,
121     /// Superencrypt with a key based on the desired boot level
122     BootLevel(i32),
123 }
124 
125 #[derive(Debug, Clone, Copy)]
126 pub enum SuperKeyIdentifier {
127     /// id of the super key in the database.
128     DatabaseId(i64),
129     /// Boot level of the encrypting boot level key
130     BootLevel(i32),
131 }
132 
133 impl SuperKeyIdentifier {
from_metadata(metadata: &BlobMetaData) -> Option<Self>134     fn from_metadata(metadata: &BlobMetaData) -> Option<Self> {
135         if let Some(EncryptedBy::KeyId(key_id)) = metadata.encrypted_by() {
136             Some(SuperKeyIdentifier::DatabaseId(*key_id))
137         } else {
138             metadata.max_boot_level().map(|boot_level| SuperKeyIdentifier::BootLevel(*boot_level))
139         }
140     }
141 
add_to_metadata(&self, metadata: &mut BlobMetaData)142     fn add_to_metadata(&self, metadata: &mut BlobMetaData) {
143         match self {
144             SuperKeyIdentifier::DatabaseId(id) => {
145                 metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::KeyId(*id)));
146             }
147             SuperKeyIdentifier::BootLevel(level) => {
148                 metadata.add(BlobMetaEntry::MaxBootLevel(*level));
149             }
150         }
151     }
152 }
153 
154 pub struct SuperKey {
155     algorithm: SuperEncryptionAlgorithm,
156     key: ZVec,
157     /// Identifier of the encrypting key, used to write an encrypted blob
158     /// back to the database after re-encryption eg on a key update.
159     id: SuperKeyIdentifier,
160     /// ECDH is more expensive than AES. So on ECDH private keys we set the
161     /// reencrypt_with field to point at the corresponding AES key, and the
162     /// keys will be re-encrypted with AES on first use.
163     reencrypt_with: Option<Arc<SuperKey>>,
164 }
165 
166 impl AesGcm for SuperKey {
decrypt(&self, data: &[u8], iv: &[u8], tag: &[u8]) -> Result<ZVec>167     fn decrypt(&self, data: &[u8], iv: &[u8], tag: &[u8]) -> Result<ZVec> {
168         if self.algorithm == SuperEncryptionAlgorithm::Aes256Gcm {
169             aes_gcm_decrypt(data, iv, tag, &self.key).context(ks_err!("Decryption failed."))
170         } else {
171             Err(Error::sys()).context(ks_err!("Key is not an AES key."))
172         }
173     }
174 
encrypt(&self, plaintext: &[u8]) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>)>175     fn encrypt(&self, plaintext: &[u8]) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>)> {
176         if self.algorithm == SuperEncryptionAlgorithm::Aes256Gcm {
177             aes_gcm_encrypt(plaintext, &self.key).context(ks_err!("Encryption failed."))
178         } else {
179             Err(Error::sys()).context(ks_err!("Key is not an AES key."))
180         }
181     }
182 }
183 
184 /// A SuperKey that has been encrypted with an AES-GCM key. For
185 /// encryption the key is in memory, and for decryption it is in KM.
186 struct LockedKey {
187     algorithm: SuperEncryptionAlgorithm,
188     id: SuperKeyIdentifier,
189     nonce: Vec<u8>,
190     ciphertext: Vec<u8>, // with tag appended
191 }
192 
193 impl LockedKey {
new(key: &[u8], to_encrypt: &Arc<SuperKey>) -> Result<Self>194     fn new(key: &[u8], to_encrypt: &Arc<SuperKey>) -> Result<Self> {
195         let (mut ciphertext, nonce, mut tag) = aes_gcm_encrypt(&to_encrypt.key, key)?;
196         ciphertext.append(&mut tag);
197         Ok(LockedKey { algorithm: to_encrypt.algorithm, id: to_encrypt.id, nonce, ciphertext })
198     }
199 
decrypt( &self, db: &mut KeystoreDB, km_dev: &KeyMintDevice, key_id_guard: &KeyIdGuard, key_entry: &KeyEntry, auth_token: &HardwareAuthToken, reencrypt_with: Option<Arc<SuperKey>>, ) -> Result<Arc<SuperKey>>200     fn decrypt(
201         &self,
202         db: &mut KeystoreDB,
203         km_dev: &KeyMintDevice,
204         key_id_guard: &KeyIdGuard,
205         key_entry: &KeyEntry,
206         auth_token: &HardwareAuthToken,
207         reencrypt_with: Option<Arc<SuperKey>>,
208     ) -> Result<Arc<SuperKey>> {
209         let key_blob = key_entry
210             .key_blob_info()
211             .as_ref()
212             .map(|(key_blob, _)| KeyBlob::Ref(key_blob))
213             .ok_or(Error::Rc(ResponseCode::KEY_NOT_FOUND))
214             .context(ks_err!("Missing key blob info."))?;
215         let key_params = vec![
216             KeyParameterValue::Algorithm(Algorithm::AES),
217             KeyParameterValue::KeySize(256),
218             KeyParameterValue::BlockMode(BlockMode::GCM),
219             KeyParameterValue::PaddingMode(PaddingMode::NONE),
220             KeyParameterValue::Nonce(self.nonce.clone()),
221             KeyParameterValue::MacLength(128),
222         ];
223         let key_params: Vec<KmKeyParameter> = key_params.into_iter().map(|x| x.into()).collect();
224         let key = ZVec::try_from(km_dev.use_key_in_one_step(
225             db,
226             key_id_guard,
227             &key_blob,
228             KeyPurpose::DECRYPT,
229             &key_params,
230             Some(auth_token),
231             &self.ciphertext,
232         )?)?;
233         Ok(Arc::new(SuperKey { algorithm: self.algorithm, key, id: self.id, reencrypt_with }))
234     }
235 }
236 
237 /// A user's UnlockedDeviceRequired super keys, encrypted with a biometric-bound key, and
238 /// information about that biometric-bound key.
239 struct BiometricUnlock {
240     /// List of auth token SIDs that are accepted by the encrypting biometric-bound key.
241     sids: Vec<i64>,
242     /// Key descriptor of the encrypting biometric-bound key.
243     key_desc: KeyDescriptor,
244     /// The UnlockedDeviceRequired super keys, encrypted with a biometric-bound key.
245     symmetric: LockedKey,
246     private: LockedKey,
247 }
248 
249 #[derive(Default)]
250 struct UserSuperKeys {
251     /// The AfterFirstUnlock super key is used for synthetic password binding of authentication
252     /// bound keys. There is one key per android user. The key is stored on flash encrypted with a
253     /// key derived from a secret, that is itself derived from the user's synthetic password. (In
254     /// most cases, the user's synthetic password can, in turn, only be decrypted using the user's
255     /// Lock Screen Knowledge Factor or LSKF.) When the user unlocks the device for the first time,
256     /// this key is unlocked, i.e., decrypted, and stays memory resident until the device reboots.
257     after_first_unlock: Option<Arc<SuperKey>>,
258     /// The UnlockedDeviceRequired symmetric super key works like the AfterFirstUnlock super key
259     /// with the distinction that it is cleared from memory when the device is locked.
260     unlocked_device_required_symmetric: Option<Arc<SuperKey>>,
261     /// When the device is locked, keys that use the UnlockedDeviceRequired key parameter can still
262     /// be created, using ECDH public-key encryption. This field holds the decryption private key.
263     unlocked_device_required_private: Option<Arc<SuperKey>>,
264     /// Versions of the above two keys, locked behind a biometric.
265     biometric_unlock: Option<BiometricUnlock>,
266 }
267 
268 #[derive(Default)]
269 struct SkmState {
270     user_keys: HashMap<UserId, UserSuperKeys>,
271     key_index: HashMap<i64, Weak<SuperKey>>,
272     boot_level_key_cache: Option<Mutex<BootLevelKeyCache>>,
273 }
274 
275 impl SkmState {
add_key_to_key_index(&mut self, super_key: &Arc<SuperKey>) -> Result<()>276     fn add_key_to_key_index(&mut self, super_key: &Arc<SuperKey>) -> Result<()> {
277         if let SuperKeyIdentifier::DatabaseId(id) = super_key.id {
278             self.key_index.insert(id, Arc::downgrade(super_key));
279             Ok(())
280         } else {
281             Err(Error::sys()).context(ks_err!("Cannot add key with ID {:?}", super_key.id))
282         }
283     }
284 }
285 
286 #[derive(Default)]
287 pub struct SuperKeyManager {
288     data: SkmState,
289 }
290 
291 impl SuperKeyManager {
set_up_boot_level_cache(skm: &Arc<RwLock<Self>>, db: &mut KeystoreDB) -> Result<()>292     pub fn set_up_boot_level_cache(skm: &Arc<RwLock<Self>>, db: &mut KeystoreDB) -> Result<()> {
293         let mut skm_guard = skm.write().unwrap();
294         if skm_guard.data.boot_level_key_cache.is_some() {
295             log::info!("In set_up_boot_level_cache: called for a second time");
296             return Ok(());
297         }
298         let level_zero_key =
299             get_level_zero_key(db).context(ks_err!("get_level_zero_key failed"))?;
300         skm_guard.data.boot_level_key_cache =
301             Some(Mutex::new(BootLevelKeyCache::new(level_zero_key)));
302         log::info!("Starting boot level watcher.");
303         let clone = skm.clone();
304         std::thread::spawn(move || {
305             Self::watch_boot_level(clone)
306                 .unwrap_or_else(|e| log::error!("watch_boot_level failed:\n{:?}", e));
307         });
308         Ok(())
309     }
310 
311     /// Watch the `keystore.boot_level` system property, and keep boot level up to date.
312     /// Blocks waiting for system property changes, so must be run in its own thread.
watch_boot_level(skm: Arc<RwLock<Self>>) -> Result<()>313     fn watch_boot_level(skm: Arc<RwLock<Self>>) -> Result<()> {
314         let mut w = PropertyWatcher::new("keystore.boot_level")
315             .context(ks_err!("PropertyWatcher::new failed"))?;
316         loop {
317             let level = w
318                 .read(|_n, v| v.parse::<usize>().map_err(std::convert::Into::into))
319                 .context(ks_err!("read of property failed"))?;
320 
321             // This scope limits the skm_guard life, so we don't hold the skm_guard while
322             // waiting.
323             {
324                 let mut skm_guard = skm.write().unwrap();
325                 let boot_level_key_cache = skm_guard
326                     .data
327                     .boot_level_key_cache
328                     .as_mut()
329                     .ok_or_else(Error::sys)
330                     .context(ks_err!("Boot level cache not initialized"))?
331                     .get_mut()
332                     .unwrap();
333                 if level < MAX_MAX_BOOT_LEVEL {
334                     log::info!("Read keystore.boot_level value {}", level);
335                     boot_level_key_cache
336                         .advance_boot_level(level)
337                         .context(ks_err!("advance_boot_level failed"))?;
338                 } else {
339                     log::info!(
340                         "keystore.boot_level {} hits maximum {}, finishing.",
341                         level,
342                         MAX_MAX_BOOT_LEVEL
343                     );
344                     boot_level_key_cache.finish();
345                     break;
346                 }
347             }
348             w.wait(None).context(ks_err!("property wait failed"))?;
349         }
350         Ok(())
351     }
352 
level_accessible(&self, boot_level: i32) -> bool353     pub fn level_accessible(&self, boot_level: i32) -> bool {
354         self.data
355             .boot_level_key_cache
356             .as_ref()
357             .map_or(false, |c| c.lock().unwrap().level_accessible(boot_level as usize))
358     }
359 
forget_all_keys_for_user(&mut self, user: UserId)360     pub fn forget_all_keys_for_user(&mut self, user: UserId) {
361         self.data.user_keys.remove(&user);
362     }
363 
install_after_first_unlock_key_for_user( &mut self, user: UserId, super_key: Arc<SuperKey>, ) -> Result<()>364     fn install_after_first_unlock_key_for_user(
365         &mut self,
366         user: UserId,
367         super_key: Arc<SuperKey>,
368     ) -> Result<()> {
369         self.data
370             .add_key_to_key_index(&super_key)
371             .context(ks_err!("add_key_to_key_index failed"))?;
372         self.data.user_keys.entry(user).or_default().after_first_unlock = Some(super_key);
373         Ok(())
374     }
375 
lookup_key(&self, key_id: &SuperKeyIdentifier) -> Result<Option<Arc<SuperKey>>>376     fn lookup_key(&self, key_id: &SuperKeyIdentifier) -> Result<Option<Arc<SuperKey>>> {
377         Ok(match key_id {
378             SuperKeyIdentifier::DatabaseId(id) => {
379                 self.data.key_index.get(id).and_then(|k| k.upgrade())
380             }
381             SuperKeyIdentifier::BootLevel(level) => self
382                 .data
383                 .boot_level_key_cache
384                 .as_ref()
385                 .map(|b| b.lock().unwrap().aes_key(*level as usize))
386                 .transpose()
387                 .context(ks_err!("aes_key failed"))?
388                 .flatten()
389                 .map(|key| {
390                     Arc::new(SuperKey {
391                         algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
392                         key,
393                         id: *key_id,
394                         reencrypt_with: None,
395                     })
396                 }),
397         })
398     }
399 
400     /// Returns the AfterFirstUnlock superencryption key for the given user ID, or None if the user
401     /// has not yet unlocked the device since boot.
get_after_first_unlock_key_by_user_id( &self, user_id: UserId, ) -> Option<Arc<dyn AesGcm + Send + Sync>>402     pub fn get_after_first_unlock_key_by_user_id(
403         &self,
404         user_id: UserId,
405     ) -> Option<Arc<dyn AesGcm + Send + Sync>> {
406         self.get_after_first_unlock_key_by_user_id_internal(user_id)
407             .map(|sk| -> Arc<dyn AesGcm + Send + Sync> { sk })
408     }
409 
get_after_first_unlock_key_by_user_id_internal( &self, user_id: UserId, ) -> Option<Arc<SuperKey>>410     fn get_after_first_unlock_key_by_user_id_internal(
411         &self,
412         user_id: UserId,
413     ) -> Option<Arc<SuperKey>> {
414         self.data.user_keys.get(&user_id).and_then(|e| e.after_first_unlock.as_ref().cloned())
415     }
416 
417     /// Check if a given key is super-encrypted, from its metadata. If so, unwrap the key using
418     /// the relevant super key.
unwrap_key_if_required<'a>( &self, metadata: &BlobMetaData, blob: &'a [u8], ) -> Result<KeyBlob<'a>>419     pub fn unwrap_key_if_required<'a>(
420         &self,
421         metadata: &BlobMetaData,
422         blob: &'a [u8],
423     ) -> Result<KeyBlob<'a>> {
424         Ok(if let Some(key_id) = SuperKeyIdentifier::from_metadata(metadata) {
425             let super_key = self
426                 .lookup_key(&key_id)
427                 .context(ks_err!("lookup_key failed"))?
428                 .ok_or(Error::Rc(ResponseCode::LOCKED))
429                 .context(ks_err!("Required super decryption key is not in memory."))?;
430             KeyBlob::Sensitive {
431                 key: Self::unwrap_key_with_key(blob, metadata, &super_key)
432                     .context(ks_err!("unwrap_key_with_key failed"))?,
433                 reencrypt_with: super_key.reencrypt_with.as_ref().unwrap_or(&super_key).clone(),
434                 force_reencrypt: super_key.reencrypt_with.is_some(),
435             }
436         } else {
437             KeyBlob::Ref(blob)
438         })
439     }
440 
441     /// Unwraps an encrypted key blob given an encryption key.
unwrap_key_with_key(blob: &[u8], metadata: &BlobMetaData, key: &SuperKey) -> Result<ZVec>442     fn unwrap_key_with_key(blob: &[u8], metadata: &BlobMetaData, key: &SuperKey) -> Result<ZVec> {
443         match key.algorithm {
444             SuperEncryptionAlgorithm::Aes256Gcm => match (metadata.iv(), metadata.aead_tag()) {
445                 (Some(iv), Some(tag)) => {
446                     key.decrypt(blob, iv, tag).context(ks_err!("Failed to decrypt the key blob."))
447                 }
448                 (iv, tag) => Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(ks_err!(
449                     "Key has incomplete metadata. Present: iv: {}, aead_tag: {}.",
450                     iv.is_some(),
451                     tag.is_some(),
452                 )),
453             },
454             SuperEncryptionAlgorithm::EcdhP521 => {
455                 match (metadata.public_key(), metadata.salt(), metadata.iv(), metadata.aead_tag()) {
456                     (Some(public_key), Some(salt), Some(iv), Some(aead_tag)) => {
457                         ECDHPrivateKey::from_private_key(&key.key)
458                             .and_then(|k| k.decrypt_message(public_key, salt, iv, blob, aead_tag))
459                             .context(ks_err!("Failed to decrypt the key blob with ECDH."))
460                     }
461                     (public_key, salt, iv, aead_tag) => {
462                         Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(ks_err!(
463                             concat!(
464                                 "Key has incomplete metadata. ",
465                                 "Present: public_key: {}, salt: {}, iv: {}, aead_tag: {}."
466                             ),
467                             public_key.is_some(),
468                             salt.is_some(),
469                             iv.is_some(),
470                             aead_tag.is_some(),
471                         ))
472                     }
473                 }
474             }
475         }
476     }
477 
478     /// Checks if the user's AfterFirstUnlock super key exists in the database (or legacy database).
479     /// The reference to self is unused but it is required to prevent calling this function
480     /// concurrently with skm state database changes.
super_key_exists_in_db_for_user( &self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, ) -> Result<bool>481     fn super_key_exists_in_db_for_user(
482         &self,
483         db: &mut KeystoreDB,
484         legacy_importer: &LegacyImporter,
485         user_id: UserId,
486     ) -> Result<bool> {
487         let key_in_db = db
488             .key_exists(
489                 Domain::APP,
490                 user_id as u64 as i64,
491                 USER_AFTER_FIRST_UNLOCK_SUPER_KEY.alias,
492                 KeyType::Super,
493             )
494             .context(ks_err!())?;
495 
496         if key_in_db {
497             Ok(key_in_db)
498         } else {
499             legacy_importer.has_super_key(user_id).context(ks_err!("Trying to query legacy db."))
500         }
501     }
502 
503     // Helper function to populate super key cache from the super key blob loaded from the database.
populate_cache_from_super_key_blob( &mut self, user_id: UserId, algorithm: SuperEncryptionAlgorithm, entry: KeyEntry, pw: &Password, ) -> Result<Arc<SuperKey>>504     fn populate_cache_from_super_key_blob(
505         &mut self,
506         user_id: UserId,
507         algorithm: SuperEncryptionAlgorithm,
508         entry: KeyEntry,
509         pw: &Password,
510     ) -> Result<Arc<SuperKey>> {
511         let super_key = Self::extract_super_key_from_key_entry(algorithm, entry, pw, None)
512             .context(ks_err!("Failed to extract super key from key entry"))?;
513         self.install_after_first_unlock_key_for_user(user_id, super_key.clone())
514             .context(ks_err!("Failed to install AfterFirstUnlock super key for user!"))?;
515         Ok(super_key)
516     }
517 
518     /// Extracts super key from the entry loaded from the database.
extract_super_key_from_key_entry( algorithm: SuperEncryptionAlgorithm, entry: KeyEntry, pw: &Password, reencrypt_with: Option<Arc<SuperKey>>, ) -> Result<Arc<SuperKey>>519     pub fn extract_super_key_from_key_entry(
520         algorithm: SuperEncryptionAlgorithm,
521         entry: KeyEntry,
522         pw: &Password,
523         reencrypt_with: Option<Arc<SuperKey>>,
524     ) -> Result<Arc<SuperKey>> {
525         if let Some((blob, metadata)) = entry.key_blob_info() {
526             let key = match (
527                 metadata.encrypted_by(),
528                 metadata.salt(),
529                 metadata.iv(),
530                 metadata.aead_tag(),
531             ) {
532                 (Some(&EncryptedBy::Password), Some(salt), Some(iv), Some(tag)) => {
533                     // Note that password encryption is AES no matter the value of algorithm.
534                     let key = pw
535                         .derive_key_hkdf(salt, AES_256_KEY_LENGTH)
536                         .context(ks_err!("Failed to derive key from password."))?;
537 
538                     aes_gcm_decrypt(blob, iv, tag, &key).or_else(|_e| {
539                         // Handle old key stored before the switch to HKDF.
540                         let key = pw
541                             .derive_key_pbkdf2(salt, AES_256_KEY_LENGTH)
542                             .context(ks_err!("Failed to derive key from password (PBKDF2)."))?;
543                         aes_gcm_decrypt(blob, iv, tag, &key)
544                             .context(ks_err!("Failed to decrypt key blob."))
545                     })?
546                 }
547                 (enc_by, salt, iv, tag) => {
548                     return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(ks_err!(
549                         concat!(
550                             "Super key has incomplete metadata.",
551                             "encrypted_by: {:?}; Present: salt: {}, iv: {}, aead_tag: {}."
552                         ),
553                         enc_by,
554                         salt.is_some(),
555                         iv.is_some(),
556                         tag.is_some()
557                     ));
558                 }
559             };
560             Ok(Arc::new(SuperKey {
561                 algorithm,
562                 key,
563                 id: SuperKeyIdentifier::DatabaseId(entry.id()),
564                 reencrypt_with,
565             }))
566         } else {
567             Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(ks_err!("No key blob info."))
568         }
569     }
570 
571     /// Encrypts the super key from a key derived from the password, before storing in the database.
572     /// This does not stretch the password; i.e., it assumes that the password is a high-entropy
573     /// synthetic password, not a low-entropy user provided password.
encrypt_with_password( super_key: &[u8], pw: &Password, ) -> Result<(Vec<u8>, BlobMetaData)>574     pub fn encrypt_with_password(
575         super_key: &[u8],
576         pw: &Password,
577     ) -> Result<(Vec<u8>, BlobMetaData)> {
578         let salt = generate_salt().context("In encrypt_with_password: Failed to generate salt.")?;
579         let derived_key = if android_security_flags::fix_unlocked_device_required_keys_v2() {
580             pw.derive_key_hkdf(&salt, AES_256_KEY_LENGTH)
581                 .context(ks_err!("Failed to derive key from password."))?
582         } else {
583             pw.derive_key_pbkdf2(&salt, AES_256_KEY_LENGTH)
584                 .context(ks_err!("Failed to derive password."))?
585         };
586         let mut metadata = BlobMetaData::new();
587         metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
588         metadata.add(BlobMetaEntry::Salt(salt));
589         let (encrypted_key, iv, tag) = aes_gcm_encrypt(super_key, &derived_key)
590             .context(ks_err!("Failed to encrypt new super key."))?;
591         metadata.add(BlobMetaEntry::Iv(iv));
592         metadata.add(BlobMetaEntry::AeadTag(tag));
593         Ok((encrypted_key, metadata))
594     }
595 
596     // Helper function to encrypt a key with the given super key. Callers should select which super
597     // key to be used. This is called when a key is super encrypted at its creation as well as at
598     // its upgrade.
encrypt_with_aes_super_key( key_blob: &[u8], super_key: &SuperKey, ) -> Result<(Vec<u8>, BlobMetaData)>599     fn encrypt_with_aes_super_key(
600         key_blob: &[u8],
601         super_key: &SuperKey,
602     ) -> Result<(Vec<u8>, BlobMetaData)> {
603         if super_key.algorithm != SuperEncryptionAlgorithm::Aes256Gcm {
604             return Err(Error::sys()).context(ks_err!("unexpected algorithm"));
605         }
606         let mut metadata = BlobMetaData::new();
607         let (encrypted_key, iv, tag) = aes_gcm_encrypt(key_blob, &(super_key.key))
608             .context(ks_err!("Failed to encrypt new super key."))?;
609         metadata.add(BlobMetaEntry::Iv(iv));
610         metadata.add(BlobMetaEntry::AeadTag(tag));
611         super_key.id.add_to_metadata(&mut metadata);
612         Ok((encrypted_key, metadata))
613     }
614 
615     // Encrypts a given key_blob using a hybrid approach, which can either use the symmetric super
616     // key or the public super key depending on which is available.
617     //
618     // If the symmetric_key is available, the key_blob is encrypted using symmetric encryption with
619     // the provided symmetric super key.  Otherwise, the function loads the public super key from
620     // the KeystoreDB and encrypts the key_blob using ECDH encryption and marks the keyblob to be
621     // re-encrypted with the symmetric super key on the first use.
622     //
623     // This hybrid scheme allows keys that use the UnlockedDeviceRequired key parameter to be
624     // created while the device is locked.
encrypt_with_hybrid_super_key( key_blob: &[u8], symmetric_key: Option<&SuperKey>, public_key_type: &SuperKeyType, db: &mut KeystoreDB, user_id: UserId, ) -> Result<(Vec<u8>, BlobMetaData)>625     fn encrypt_with_hybrid_super_key(
626         key_blob: &[u8],
627         symmetric_key: Option<&SuperKey>,
628         public_key_type: &SuperKeyType,
629         db: &mut KeystoreDB,
630         user_id: UserId,
631     ) -> Result<(Vec<u8>, BlobMetaData)> {
632         if let Some(super_key) = symmetric_key {
633             Self::encrypt_with_aes_super_key(key_blob, super_key).context(ks_err!(
634                 "Failed to encrypt with UnlockedDeviceRequired symmetric super key."
635             ))
636         } else {
637             // Symmetric key is not available, use public key encryption
638             let loaded = db
639                 .load_super_key(public_key_type, user_id)
640                 .context(ks_err!("load_super_key failed."))?;
641             let (key_id_guard, key_entry) =
642                 loaded.ok_or_else(Error::sys).context(ks_err!("User ECDH super key missing."))?;
643             let public_key = key_entry
644                 .metadata()
645                 .sec1_public_key()
646                 .ok_or_else(Error::sys)
647                 .context(ks_err!("sec1_public_key missing."))?;
648             let mut metadata = BlobMetaData::new();
649             let (ephem_key, salt, iv, encrypted_key, aead_tag) =
650                 ECDHPrivateKey::encrypt_message(public_key, key_blob)
651                     .context(ks_err!("ECDHPrivateKey::encrypt_message failed."))?;
652             metadata.add(BlobMetaEntry::PublicKey(ephem_key));
653             metadata.add(BlobMetaEntry::Salt(salt));
654             metadata.add(BlobMetaEntry::Iv(iv));
655             metadata.add(BlobMetaEntry::AeadTag(aead_tag));
656             SuperKeyIdentifier::DatabaseId(key_id_guard.id()).add_to_metadata(&mut metadata);
657             Ok((encrypted_key, metadata))
658         }
659     }
660 
661     /// Check if super encryption is required and if so, super-encrypt the key to be stored in
662     /// the database.
663     #[allow(clippy::too_many_arguments)]
handle_super_encryption_on_key_init( &self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, domain: &Domain, key_parameters: &[KeyParameter], flags: Option<i32>, user_id: UserId, key_blob: &[u8], ) -> Result<(Vec<u8>, BlobMetaData)>664     pub fn handle_super_encryption_on_key_init(
665         &self,
666         db: &mut KeystoreDB,
667         legacy_importer: &LegacyImporter,
668         domain: &Domain,
669         key_parameters: &[KeyParameter],
670         flags: Option<i32>,
671         user_id: UserId,
672         key_blob: &[u8],
673     ) -> Result<(Vec<u8>, BlobMetaData)> {
674         match Enforcements::super_encryption_required(domain, key_parameters, flags) {
675             SuperEncryptionType::None => Ok((key_blob.to_vec(), BlobMetaData::new())),
676             SuperEncryptionType::AfterFirstUnlock => {
677                 // Encrypt the given key blob with the user's AfterFirstUnlock super key. If the
678                 // user has not unlocked the device since boot or the super keys were never
679                 // initialized for the user for some reason, an error is returned.
680                 match self
681                     .get_user_state(db, legacy_importer, user_id)
682                     .context(ks_err!("Failed to get user state for user {user_id}"))?
683                 {
684                     UserState::AfterFirstUnlock(super_key) => {
685                         Self::encrypt_with_aes_super_key(key_blob, &super_key).context(ks_err!(
686                             "Failed to encrypt with AfterFirstUnlock super key for user {user_id}"
687                         ))
688                     }
689                     UserState::BeforeFirstUnlock => {
690                         Err(Error::Rc(ResponseCode::LOCKED)).context(ks_err!("Device is locked."))
691                     }
692                     UserState::Uninitialized => Err(Error::Rc(ResponseCode::UNINITIALIZED))
693                         .context(ks_err!("User {user_id} does not have super keys")),
694                 }
695             }
696             SuperEncryptionType::UnlockedDeviceRequired => {
697                 let symmetric_key = self
698                     .data
699                     .user_keys
700                     .get(&user_id)
701                     .and_then(|e| e.unlocked_device_required_symmetric.as_ref())
702                     .map(|arc| arc.as_ref());
703                 Self::encrypt_with_hybrid_super_key(
704                     key_blob,
705                     symmetric_key,
706                     &USER_UNLOCKED_DEVICE_REQUIRED_P521_SUPER_KEY,
707                     db,
708                     user_id,
709                 )
710                 .context(ks_err!("Failed to encrypt with UnlockedDeviceRequired hybrid scheme."))
711             }
712             SuperEncryptionType::BootLevel(level) => {
713                 let key_id = SuperKeyIdentifier::BootLevel(level);
714                 let super_key = self
715                     .lookup_key(&key_id)
716                     .context(ks_err!("lookup_key failed"))?
717                     .ok_or(Error::Rc(ResponseCode::LOCKED))
718                     .context(ks_err!("Boot stage key absent"))?;
719                 Self::encrypt_with_aes_super_key(key_blob, &super_key)
720                     .context(ks_err!("Failed to encrypt with BootLevel key."))
721             }
722         }
723     }
724 
725     /// Check if a given key needs re-super-encryption, from its KeyBlob type.
726     /// If so, re-super-encrypt the key and return a new set of metadata,
727     /// containing the new super encryption information.
reencrypt_if_required<'a>( key_blob_before_upgrade: &KeyBlob, key_after_upgrade: &'a [u8], ) -> Result<(KeyBlob<'a>, Option<BlobMetaData>)>728     pub fn reencrypt_if_required<'a>(
729         key_blob_before_upgrade: &KeyBlob,
730         key_after_upgrade: &'a [u8],
731     ) -> Result<(KeyBlob<'a>, Option<BlobMetaData>)> {
732         match key_blob_before_upgrade {
733             KeyBlob::Sensitive { reencrypt_with: super_key, .. } => {
734                 let (key, metadata) =
735                     Self::encrypt_with_aes_super_key(key_after_upgrade, super_key)
736                         .context(ks_err!("Failed to re-super-encrypt key."))?;
737                 Ok((KeyBlob::NonSensitive(key), Some(metadata)))
738             }
739             _ => Ok((KeyBlob::Ref(key_after_upgrade), None)),
740         }
741     }
742 
create_super_key( &mut self, db: &mut KeystoreDB, user_id: UserId, key_type: &SuperKeyType, password: &Password, reencrypt_with: Option<Arc<SuperKey>>, ) -> Result<Arc<SuperKey>>743     fn create_super_key(
744         &mut self,
745         db: &mut KeystoreDB,
746         user_id: UserId,
747         key_type: &SuperKeyType,
748         password: &Password,
749         reencrypt_with: Option<Arc<SuperKey>>,
750     ) -> Result<Arc<SuperKey>> {
751         log::info!("Creating {} for user {}", key_type.name, user_id);
752         let (super_key, public_key) = match key_type.algorithm {
753             SuperEncryptionAlgorithm::Aes256Gcm => {
754                 (generate_aes256_key().context(ks_err!("Failed to generate AES-256 key."))?, None)
755             }
756             SuperEncryptionAlgorithm::EcdhP521 => {
757                 let key =
758                     ECDHPrivateKey::generate().context(ks_err!("Failed to generate ECDH key"))?;
759                 (
760                     key.private_key().context(ks_err!("private_key failed"))?,
761                     Some(key.public_key().context(ks_err!("public_key failed"))?),
762                 )
763             }
764         };
765         // Derive an AES-256 key from the password and re-encrypt the super key before we insert it
766         // in the database.
767         let (encrypted_super_key, blob_metadata) =
768             Self::encrypt_with_password(&super_key, password).context(ks_err!())?;
769         let mut key_metadata = KeyMetaData::new();
770         if let Some(pk) = public_key {
771             key_metadata.add(KeyMetaEntry::Sec1PublicKey(pk));
772         }
773         let key_entry = db
774             .store_super_key(user_id, key_type, &encrypted_super_key, &blob_metadata, &key_metadata)
775             .context(ks_err!("Failed to store super key."))?;
776         Ok(Arc::new(SuperKey {
777             algorithm: key_type.algorithm,
778             key: super_key,
779             id: SuperKeyIdentifier::DatabaseId(key_entry.id()),
780             reencrypt_with,
781         }))
782     }
783 
784     /// Fetch a superencryption key from the database, or create it if it doesn't already exist.
785     /// When this is called, the caller must hold the lock on the SuperKeyManager.
786     /// So it's OK that the check and creation are different DB transactions.
get_or_create_super_key( &mut self, db: &mut KeystoreDB, user_id: UserId, key_type: &SuperKeyType, password: &Password, reencrypt_with: Option<Arc<SuperKey>>, ) -> Result<Arc<SuperKey>>787     fn get_or_create_super_key(
788         &mut self,
789         db: &mut KeystoreDB,
790         user_id: UserId,
791         key_type: &SuperKeyType,
792         password: &Password,
793         reencrypt_with: Option<Arc<SuperKey>>,
794     ) -> Result<Arc<SuperKey>> {
795         let loaded_key = db.load_super_key(key_type, user_id)?;
796         if let Some((_, key_entry)) = loaded_key {
797             Ok(Self::extract_super_key_from_key_entry(
798                 key_type.algorithm,
799                 key_entry,
800                 password,
801                 reencrypt_with,
802             )?)
803         } else {
804             self.create_super_key(db, user_id, key_type, password, reencrypt_with)
805         }
806     }
807 
808     /// Decrypt the UnlockedDeviceRequired super keys for this user using the password and store
809     /// them in memory. If these keys don't exist yet, create them.
unlock_unlocked_device_required_keys( &mut self, db: &mut KeystoreDB, user_id: UserId, password: &Password, ) -> Result<()>810     pub fn unlock_unlocked_device_required_keys(
811         &mut self,
812         db: &mut KeystoreDB,
813         user_id: UserId,
814         password: &Password,
815     ) -> Result<()> {
816         let (symmetric, private) = self
817             .data
818             .user_keys
819             .get(&user_id)
820             .map(|e| {
821                 (
822                     e.unlocked_device_required_symmetric.clone(),
823                     e.unlocked_device_required_private.clone(),
824                 )
825             })
826             .unwrap_or((None, None));
827 
828         if symmetric.is_some() && private.is_some() {
829             // Already unlocked.
830             return Ok(());
831         }
832 
833         let aes = if let Some(symmetric) = symmetric {
834             // This is weird. If this point is reached only one of the UnlockedDeviceRequired super
835             // keys was initialized. This should never happen.
836             symmetric
837         } else {
838             self.get_or_create_super_key(
839                 db,
840                 user_id,
841                 &USER_UNLOCKED_DEVICE_REQUIRED_SYMMETRIC_SUPER_KEY,
842                 password,
843                 None,
844             )
845             .context(ks_err!("Trying to get or create symmetric key."))?
846         };
847 
848         let ecdh = if let Some(private) = private {
849             // This is weird. If this point is reached only one of the UnlockedDeviceRequired super
850             // keys was initialized. This should never happen.
851             private
852         } else {
853             self.get_or_create_super_key(
854                 db,
855                 user_id,
856                 &USER_UNLOCKED_DEVICE_REQUIRED_P521_SUPER_KEY,
857                 password,
858                 Some(aes.clone()),
859             )
860             .context(ks_err!("Trying to get or create asymmetric key."))?
861         };
862 
863         self.data.add_key_to_key_index(&aes)?;
864         self.data.add_key_to_key_index(&ecdh)?;
865         let entry = self.data.user_keys.entry(user_id).or_default();
866         entry.unlocked_device_required_symmetric = Some(aes);
867         entry.unlocked_device_required_private = Some(ecdh);
868         Ok(())
869     }
870 
871     /// Protects the user's UnlockedDeviceRequired super keys in a way such that they can only be
872     /// unlocked by the enabled unlock methods.
lock_unlocked_device_required_keys( &mut self, db: &mut KeystoreDB, user_id: UserId, unlocking_sids: &[i64], weak_unlock_enabled: bool, )873     pub fn lock_unlocked_device_required_keys(
874         &mut self,
875         db: &mut KeystoreDB,
876         user_id: UserId,
877         unlocking_sids: &[i64],
878         weak_unlock_enabled: bool,
879     ) {
880         let entry = self.data.user_keys.entry(user_id).or_default();
881         if unlocking_sids.is_empty() {
882             if android_security_flags::fix_unlocked_device_required_keys_v2() {
883                 entry.biometric_unlock = None;
884             }
885         } else if let (Some(aes), Some(ecdh)) = (
886             entry.unlocked_device_required_symmetric.as_ref().cloned(),
887             entry.unlocked_device_required_private.as_ref().cloned(),
888         ) {
889             // If class 3 biometric unlock methods are enabled, create a biometric-encrypted copy of
890             // the keys.  Do this even if weak unlock methods are enabled too; in that case we'll
891             // also retain a plaintext copy of the keys, but that copy will be wiped later if weak
892             // unlock methods expire.  So we need the biometric-encrypted copy too just in case.
893             let res = (|| -> Result<()> {
894                 let key_desc =
895                     KeyMintDevice::internal_descriptor(format!("biometric_unlock_key_{}", user_id));
896                 let encrypting_key = generate_aes256_key()?;
897                 let km_dev: KeyMintDevice = KeyMintDevice::get(SecurityLevel::TRUSTED_ENVIRONMENT)
898                     .context(ks_err!("KeyMintDevice::get failed"))?;
899                 let mut key_params = vec![
900                     KeyParameterValue::Algorithm(Algorithm::AES),
901                     KeyParameterValue::KeySize(256),
902                     KeyParameterValue::BlockMode(BlockMode::GCM),
903                     KeyParameterValue::PaddingMode(PaddingMode::NONE),
904                     KeyParameterValue::CallerNonce,
905                     KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
906                     KeyParameterValue::MinMacLength(128),
907                     KeyParameterValue::AuthTimeout(BIOMETRIC_AUTH_TIMEOUT_S),
908                     KeyParameterValue::HardwareAuthenticatorType(
909                         HardwareAuthenticatorType::FINGERPRINT,
910                     ),
911                 ];
912                 for sid in unlocking_sids {
913                     key_params.push(KeyParameterValue::UserSecureID(*sid));
914                 }
915                 let key_params: Vec<KmKeyParameter> =
916                     key_params.into_iter().map(|x| x.into()).collect();
917                 km_dev.create_and_store_key(
918                     db,
919                     &key_desc,
920                     KeyType::Client, /* TODO Should be Super b/189470584 */
921                     |dev| {
922                         let _wp =
923                             wd::watch("In lock_unlocked_device_required_keys: calling importKey.");
924                         dev.importKey(key_params.as_slice(), KeyFormat::RAW, &encrypting_key, None)
925                     },
926                 )?;
927                 entry.biometric_unlock = Some(BiometricUnlock {
928                     sids: unlocking_sids.into(),
929                     key_desc,
930                     symmetric: LockedKey::new(&encrypting_key, &aes)?,
931                     private: LockedKey::new(&encrypting_key, &ecdh)?,
932                 });
933                 Ok(())
934             })();
935             if let Err(e) = res {
936                 log::error!("Error setting up biometric unlock: {:#?}", e);
937                 // The caller can't do anything about the error, and for security reasons we still
938                 // wipe the keys (unless a weak unlock method is enabled).  So just log the error.
939             }
940         }
941         // Wipe the plaintext copy of the keys, unless a weak unlock method is enabled.
942         if !weak_unlock_enabled {
943             entry.unlocked_device_required_symmetric = None;
944             entry.unlocked_device_required_private = None;
945         }
946         Self::log_status_of_unlocked_device_required_keys(user_id, entry);
947     }
948 
wipe_plaintext_unlocked_device_required_keys(&mut self, user_id: UserId)949     pub fn wipe_plaintext_unlocked_device_required_keys(&mut self, user_id: UserId) {
950         let entry = self.data.user_keys.entry(user_id).or_default();
951         entry.unlocked_device_required_symmetric = None;
952         entry.unlocked_device_required_private = None;
953         Self::log_status_of_unlocked_device_required_keys(user_id, entry);
954     }
955 
wipe_all_unlocked_device_required_keys(&mut self, user_id: UserId)956     pub fn wipe_all_unlocked_device_required_keys(&mut self, user_id: UserId) {
957         let entry = self.data.user_keys.entry(user_id).or_default();
958         entry.unlocked_device_required_symmetric = None;
959         entry.unlocked_device_required_private = None;
960         entry.biometric_unlock = None;
961         Self::log_status_of_unlocked_device_required_keys(user_id, entry);
962     }
963 
log_status_of_unlocked_device_required_keys(user_id: UserId, entry: &UserSuperKeys)964     fn log_status_of_unlocked_device_required_keys(user_id: UserId, entry: &UserSuperKeys) {
965         let status = match (
966             // Note: the status of the symmetric and private keys should always be in sync.
967             // So we only check one here.
968             entry.unlocked_device_required_symmetric.is_some(),
969             entry.biometric_unlock.is_some(),
970         ) {
971             (false, false) => "fully protected",
972             (false, true) => "biometric-encrypted",
973             (true, false) => "retained in plaintext",
974             (true, true) => "retained in plaintext, with biometric-encrypted copy too",
975         };
976         log::info!("UnlockedDeviceRequired super keys for user {user_id} are {status}.");
977     }
978 
979     /// User has unlocked, not using a password. See if any of our stored auth tokens can be used
980     /// to unlock the keys protecting UNLOCKED_DEVICE_REQUIRED keys.
try_unlock_user_with_biometric( &mut self, db: &mut KeystoreDB, user_id: UserId, ) -> Result<()>981     pub fn try_unlock_user_with_biometric(
982         &mut self,
983         db: &mut KeystoreDB,
984         user_id: UserId,
985     ) -> Result<()> {
986         let entry = self.data.user_keys.entry(user_id).or_default();
987         if android_security_flags::fix_unlocked_device_required_keys_v2()
988             && entry.unlocked_device_required_symmetric.is_some()
989             && entry.unlocked_device_required_private.is_some()
990         {
991             // If the keys are already cached in plaintext, then there is no need to decrypt the
992             // biometric-encrypted copy.  Both copies can be present here if the user has both
993             // class 3 biometric and weak unlock methods enabled, and the device was unlocked before
994             // the weak unlock methods expired.
995             return Ok(());
996         }
997         if let Some(biometric) = entry.biometric_unlock.as_ref() {
998             let (key_id_guard, key_entry) = db
999                 .load_key_entry(
1000                     &biometric.key_desc,
1001                     KeyType::Client, // This should not be a Client key.
1002                     KeyEntryLoadBits::KM,
1003                     AID_KEYSTORE,
1004                     |_, _| Ok(()),
1005                 )
1006                 .context(ks_err!("load_key_entry failed"))?;
1007             let km_dev: KeyMintDevice = KeyMintDevice::get(SecurityLevel::TRUSTED_ENVIRONMENT)
1008                 .context(ks_err!("KeyMintDevice::get failed"))?;
1009             let mut errs = vec![];
1010             for sid in &biometric.sids {
1011                 let sid = *sid;
1012                 if let Some(auth_token_entry) = db.find_auth_token_entry(|entry| {
1013                     entry.auth_token().userId == sid || entry.auth_token().authenticatorId == sid
1014                 }) {
1015                     let res: Result<(Arc<SuperKey>, Arc<SuperKey>)> = (|| {
1016                         let symmetric = biometric.symmetric.decrypt(
1017                             db,
1018                             &km_dev,
1019                             &key_id_guard,
1020                             &key_entry,
1021                             auth_token_entry.auth_token(),
1022                             None,
1023                         )?;
1024                         let private = biometric.private.decrypt(
1025                             db,
1026                             &km_dev,
1027                             &key_id_guard,
1028                             &key_entry,
1029                             auth_token_entry.auth_token(),
1030                             Some(symmetric.clone()),
1031                         )?;
1032                         Ok((symmetric, private))
1033                     })();
1034                     match res {
1035                         Ok((symmetric, private)) => {
1036                             entry.unlocked_device_required_symmetric = Some(symmetric.clone());
1037                             entry.unlocked_device_required_private = Some(private.clone());
1038                             self.data.add_key_to_key_index(&symmetric)?;
1039                             self.data.add_key_to_key_index(&private)?;
1040                             log::info!("Successfully unlocked user {user_id} with biometric {sid}",);
1041                             return Ok(());
1042                         }
1043                         Err(e) => {
1044                             // Don't log an error yet, as some other biometric SID might work.
1045                             errs.push((sid, e));
1046                         }
1047                     }
1048                 }
1049             }
1050             if !errs.is_empty() {
1051                 log::warn!("biometric unlock failed for all SIDs, with errors:");
1052                 for (sid, err) in errs {
1053                     log::warn!("  biometric {sid}: {err}");
1054                 }
1055             }
1056         }
1057         Ok(())
1058     }
1059 
1060     /// Returns the keystore locked state of the given user. It requires the thread local
1061     /// keystore database and a reference to the legacy migrator because it may need to
1062     /// import the super key from the legacy blob database to the keystore database.
get_user_state( &self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, ) -> Result<UserState>1063     pub fn get_user_state(
1064         &self,
1065         db: &mut KeystoreDB,
1066         legacy_importer: &LegacyImporter,
1067         user_id: UserId,
1068     ) -> Result<UserState> {
1069         match self.get_after_first_unlock_key_by_user_id_internal(user_id) {
1070             Some(super_key) => Ok(UserState::AfterFirstUnlock(super_key)),
1071             None => {
1072                 // Check if a super key exists in the database or legacy database.
1073                 // If so, return locked user state.
1074                 if self
1075                     .super_key_exists_in_db_for_user(db, legacy_importer, user_id)
1076                     .context(ks_err!())?
1077                 {
1078                     Ok(UserState::BeforeFirstUnlock)
1079                 } else {
1080                     Ok(UserState::Uninitialized)
1081                 }
1082             }
1083         }
1084     }
1085 
1086     /// Deletes all keys and super keys for the given user.
1087     /// This is called when a user is deleted.
remove_user( &mut self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, ) -> Result<()>1088     pub fn remove_user(
1089         &mut self,
1090         db: &mut KeystoreDB,
1091         legacy_importer: &LegacyImporter,
1092         user_id: UserId,
1093     ) -> Result<()> {
1094         log::info!("remove_user(user={user_id})");
1095         // Mark keys created on behalf of the user as unreferenced.
1096         legacy_importer
1097             .bulk_delete_user(user_id, false)
1098             .context(ks_err!("Trying to delete legacy keys."))?;
1099         db.unbind_keys_for_user(user_id, false).context(ks_err!("Error in unbinding keys."))?;
1100 
1101         // Delete super key in cache, if exists.
1102         self.forget_all_keys_for_user(user_id);
1103         Ok(())
1104     }
1105 
1106     /// Deletes all authentication bound keys and super keys for the given user.  The user must be
1107     /// unlocked before this function is called.  This function is used to transition a user to
1108     /// swipe.
reset_user( &mut self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, ) -> Result<()>1109     pub fn reset_user(
1110         &mut self,
1111         db: &mut KeystoreDB,
1112         legacy_importer: &LegacyImporter,
1113         user_id: UserId,
1114     ) -> Result<()> {
1115         log::info!("reset_user(user={user_id})");
1116         match self.get_user_state(db, legacy_importer, user_id)? {
1117             UserState::Uninitialized => {
1118                 Err(Error::sys()).context(ks_err!("Tried to reset an uninitialized user!"))
1119             }
1120             UserState::BeforeFirstUnlock => {
1121                 Err(Error::sys()).context(ks_err!("Tried to reset a locked user's password!"))
1122             }
1123             UserState::AfterFirstUnlock(_) => {
1124                 // Mark keys created on behalf of the user as unreferenced.
1125                 legacy_importer
1126                     .bulk_delete_user(user_id, true)
1127                     .context(ks_err!("Trying to delete legacy keys."))?;
1128                 db.unbind_keys_for_user(user_id, true)
1129                     .context(ks_err!("Error in unbinding keys."))?;
1130 
1131                 // Delete super key in cache, if exists.
1132                 self.forget_all_keys_for_user(user_id);
1133                 Ok(())
1134             }
1135         }
1136     }
1137 
1138     /// If the user hasn't been initialized yet, then this function generates the user's
1139     /// AfterFirstUnlock super key and sets the user's state to AfterFirstUnlock. Otherwise this
1140     /// function returns an error.
init_user( &mut self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, password: &Password, ) -> Result<()>1141     pub fn init_user(
1142         &mut self,
1143         db: &mut KeystoreDB,
1144         legacy_importer: &LegacyImporter,
1145         user_id: UserId,
1146         password: &Password,
1147     ) -> Result<()> {
1148         log::info!("init_user(user={user_id})");
1149         match self.get_user_state(db, legacy_importer, user_id)? {
1150             UserState::AfterFirstUnlock(_) | UserState::BeforeFirstUnlock => {
1151                 Err(Error::sys()).context(ks_err!("Tried to re-init an initialized user!"))
1152             }
1153             UserState::Uninitialized => {
1154                 // Generate a new super key.
1155                 let super_key =
1156                     generate_aes256_key().context(ks_err!("Failed to generate AES 256 key."))?;
1157                 // Derive an AES256 key from the password and re-encrypt the super key
1158                 // before we insert it in the database.
1159                 let (encrypted_super_key, blob_metadata) =
1160                     Self::encrypt_with_password(&super_key, password)
1161                         .context(ks_err!("Failed to encrypt super key with password!"))?;
1162 
1163                 let key_entry = db
1164                     .store_super_key(
1165                         user_id,
1166                         &USER_AFTER_FIRST_UNLOCK_SUPER_KEY,
1167                         &encrypted_super_key,
1168                         &blob_metadata,
1169                         &KeyMetaData::new(),
1170                     )
1171                     .context(ks_err!("Failed to store super key."))?;
1172 
1173                 self.populate_cache_from_super_key_blob(
1174                     user_id,
1175                     USER_AFTER_FIRST_UNLOCK_SUPER_KEY.algorithm,
1176                     key_entry,
1177                     password,
1178                 )
1179                 .context(ks_err!("Failed to initialize user!"))?;
1180                 Ok(())
1181             }
1182         }
1183     }
1184 
1185     /// Initializes the given user by creating their super keys, both AfterFirstUnlock and
1186     /// UnlockedDeviceRequired. If allow_existing is true, then the user already being initialized
1187     /// is not considered an error.
initialize_user( &mut self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, password: &Password, allow_existing: bool, ) -> Result<()>1188     pub fn initialize_user(
1189         &mut self,
1190         db: &mut KeystoreDB,
1191         legacy_importer: &LegacyImporter,
1192         user_id: UserId,
1193         password: &Password,
1194         allow_existing: bool,
1195     ) -> Result<()> {
1196         // Create the AfterFirstUnlock super key.
1197         if self.super_key_exists_in_db_for_user(db, legacy_importer, user_id)? {
1198             log::info!("AfterFirstUnlock super key already exists");
1199             if !allow_existing {
1200                 return Err(Error::sys()).context(ks_err!("Tried to re-init an initialized user!"));
1201             }
1202         } else {
1203             let super_key = self
1204                 .create_super_key(db, user_id, &USER_AFTER_FIRST_UNLOCK_SUPER_KEY, password, None)
1205                 .context(ks_err!("Failed to create AfterFirstUnlock super key"))?;
1206 
1207             self.install_after_first_unlock_key_for_user(user_id, super_key)
1208                 .context(ks_err!("Failed to install AfterFirstUnlock super key for user"))?;
1209         }
1210 
1211         // Create the UnlockedDeviceRequired super keys.
1212         self.unlock_unlocked_device_required_keys(db, user_id, password)
1213             .context(ks_err!("Failed to create UnlockedDeviceRequired super keys"))
1214     }
1215 
1216     /// Unlocks the given user with the given password.
1217     ///
1218     /// If the user state is BeforeFirstUnlock:
1219     /// - Unlock the user's AfterFirstUnlock super key
1220     /// - Unlock the user's UnlockedDeviceRequired super keys
1221     ///
1222     /// If the user state is AfterFirstUnlock:
1223     /// - Unlock the user's UnlockedDeviceRequired super keys only
1224     ///
unlock_user( &mut self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, password: &Password, ) -> Result<()>1225     pub fn unlock_user(
1226         &mut self,
1227         db: &mut KeystoreDB,
1228         legacy_importer: &LegacyImporter,
1229         user_id: UserId,
1230         password: &Password,
1231     ) -> Result<()> {
1232         log::info!("unlock_user(user={user_id})");
1233         match self.get_user_state(db, legacy_importer, user_id)? {
1234             UserState::AfterFirstUnlock(_) => {
1235                 self.unlock_unlocked_device_required_keys(db, user_id, password)
1236             }
1237             UserState::Uninitialized => {
1238                 Err(Error::sys()).context(ks_err!("Tried to unlock an uninitialized user!"))
1239             }
1240             UserState::BeforeFirstUnlock => {
1241                 let alias = &USER_AFTER_FIRST_UNLOCK_SUPER_KEY;
1242                 let result = legacy_importer
1243                     .with_try_import_super_key(user_id, password, || {
1244                         db.load_super_key(alias, user_id)
1245                     })
1246                     .context(ks_err!("Failed to load super key"))?;
1247 
1248                 match result {
1249                     Some((_, entry)) => {
1250                         self.populate_cache_from_super_key_blob(
1251                             user_id,
1252                             alias.algorithm,
1253                             entry,
1254                             password,
1255                         )
1256                         .context(ks_err!("Failed when unlocking user."))?;
1257                         self.unlock_unlocked_device_required_keys(db, user_id, password)
1258                     }
1259                     None => {
1260                         Err(Error::sys()).context(ks_err!("Locked user does not have a super key!"))
1261                     }
1262                 }
1263             }
1264         }
1265     }
1266 }
1267 
1268 /// This enum represents different states of the user's life cycle in the device.
1269 /// For now, only three states are defined. More states may be added later.
1270 pub enum UserState {
1271     // The user's super keys exist, and the user has unlocked the device at least once since boot.
1272     // Hence, the AfterFirstUnlock super key is available in the cache.
1273     AfterFirstUnlock(Arc<SuperKey>),
1274     // The user's super keys exist, but the user hasn't unlocked the device at least once since
1275     // boot. Hence, the AfterFirstUnlock and UnlockedDeviceRequired super keys are not available in
1276     // the cache. However, they exist in the database in encrypted form.
1277     BeforeFirstUnlock,
1278     // The user's super keys don't exist. I.e., there's no user with the given user ID, or the user
1279     // is in the process of being created or destroyed.
1280     Uninitialized,
1281 }
1282 
1283 /// This enum represents three states a KeyMint Blob can be in, w.r.t super encryption.
1284 /// `Sensitive` holds the non encrypted key and a reference to its super key.
1285 /// `NonSensitive` holds a non encrypted key that is never supposed to be encrypted.
1286 /// `Ref` holds a reference to a key blob when it does not need to be modified if its
1287 /// life time allows it.
1288 pub enum KeyBlob<'a> {
1289     Sensitive {
1290         key: ZVec,
1291         /// If KeyMint reports that the key must be upgraded, we must
1292         /// re-encrypt the key before writing to the database; we use
1293         /// this key.
1294         reencrypt_with: Arc<SuperKey>,
1295         /// If this key was decrypted with an ECDH key, we want to
1296         /// re-encrypt it on first use whether it was upgraded or not;
1297         /// this field indicates that that's necessary.
1298         force_reencrypt: bool,
1299     },
1300     NonSensitive(Vec<u8>),
1301     Ref(&'a [u8]),
1302 }
1303 
1304 impl<'a> KeyBlob<'a> {
force_reencrypt(&self) -> bool1305     pub fn force_reencrypt(&self) -> bool {
1306         if let KeyBlob::Sensitive { force_reencrypt, .. } = self {
1307             *force_reencrypt
1308         } else {
1309             false
1310         }
1311     }
1312 }
1313 
1314 /// Deref returns a reference to the key material in any variant.
1315 impl<'a> Deref for KeyBlob<'a> {
1316     type Target = [u8];
1317 
deref(&self) -> &Self::Target1318     fn deref(&self) -> &Self::Target {
1319         match self {
1320             Self::Sensitive { key, .. } => key,
1321             Self::NonSensitive(key) => key,
1322             Self::Ref(key) => key,
1323         }
1324     }
1325 }
1326 
1327 #[cfg(test)]
1328 mod tests {
1329     use super::*;
1330     use crate::database::tests::make_bootlevel_key_entry;
1331     use crate::database::tests::make_test_key_entry;
1332     use crate::database::tests::new_test_db;
1333     use rand::prelude::*;
1334     const USER_ID: u32 = 0;
1335     const TEST_KEY_ALIAS: &str = "TEST_KEY";
1336     const TEST_BOOT_KEY_ALIAS: &str = "TEST_BOOT_KEY";
1337 
generate_password_blob() -> Password<'static>1338     pub fn generate_password_blob() -> Password<'static> {
1339         let mut rng = rand::thread_rng();
1340         let mut password = vec![0u8; 64];
1341         rng.fill_bytes(&mut password);
1342 
1343         let mut zvec = ZVec::new(64).expect("Failed to create ZVec");
1344         zvec[..].copy_from_slice(&password[..]);
1345 
1346         Password::Owned(zvec)
1347     }
1348 
setup_test(pw: &Password) -> (Arc<RwLock<SuperKeyManager>>, KeystoreDB, LegacyImporter)1349     fn setup_test(pw: &Password) -> (Arc<RwLock<SuperKeyManager>>, KeystoreDB, LegacyImporter) {
1350         let mut keystore_db = new_test_db().unwrap();
1351         let mut legacy_importer = LegacyImporter::new(Arc::new(Default::default()));
1352         legacy_importer.set_empty();
1353         let skm: Arc<RwLock<SuperKeyManager>> = Default::default();
1354         assert!(skm
1355             .write()
1356             .unwrap()
1357             .init_user(&mut keystore_db, &legacy_importer, USER_ID, pw)
1358             .is_ok());
1359         (skm, keystore_db, legacy_importer)
1360     }
1361 
assert_unlocked( skm: &Arc<RwLock<SuperKeyManager>>, keystore_db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: u32, err_msg: &str, )1362     fn assert_unlocked(
1363         skm: &Arc<RwLock<SuperKeyManager>>,
1364         keystore_db: &mut KeystoreDB,
1365         legacy_importer: &LegacyImporter,
1366         user_id: u32,
1367         err_msg: &str,
1368     ) {
1369         let user_state =
1370             skm.write().unwrap().get_user_state(keystore_db, legacy_importer, user_id).unwrap();
1371         match user_state {
1372             UserState::AfterFirstUnlock(_) => {}
1373             _ => panic!("{}", err_msg),
1374         }
1375     }
1376 
assert_locked( skm: &Arc<RwLock<SuperKeyManager>>, keystore_db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: u32, err_msg: &str, )1377     fn assert_locked(
1378         skm: &Arc<RwLock<SuperKeyManager>>,
1379         keystore_db: &mut KeystoreDB,
1380         legacy_importer: &LegacyImporter,
1381         user_id: u32,
1382         err_msg: &str,
1383     ) {
1384         let user_state =
1385             skm.write().unwrap().get_user_state(keystore_db, legacy_importer, user_id).unwrap();
1386         match user_state {
1387             UserState::BeforeFirstUnlock => {}
1388             _ => panic!("{}", err_msg),
1389         }
1390     }
1391 
assert_uninitialized( skm: &Arc<RwLock<SuperKeyManager>>, keystore_db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: u32, err_msg: &str, )1392     fn assert_uninitialized(
1393         skm: &Arc<RwLock<SuperKeyManager>>,
1394         keystore_db: &mut KeystoreDB,
1395         legacy_importer: &LegacyImporter,
1396         user_id: u32,
1397         err_msg: &str,
1398     ) {
1399         let user_state =
1400             skm.write().unwrap().get_user_state(keystore_db, legacy_importer, user_id).unwrap();
1401         match user_state {
1402             UserState::Uninitialized => {}
1403             _ => panic!("{}", err_msg),
1404         }
1405     }
1406 
1407     #[test]
test_init_user()1408     fn test_init_user() {
1409         let pw: Password = generate_password_blob();
1410         let (skm, mut keystore_db, legacy_importer) = setup_test(&pw);
1411         assert_unlocked(
1412             &skm,
1413             &mut keystore_db,
1414             &legacy_importer,
1415             USER_ID,
1416             "The user was not unlocked after initialization!",
1417         );
1418     }
1419 
1420     #[test]
test_unlock_user()1421     fn test_unlock_user() {
1422         let pw: Password = generate_password_blob();
1423         let (skm, mut keystore_db, legacy_importer) = setup_test(&pw);
1424         assert_unlocked(
1425             &skm,
1426             &mut keystore_db,
1427             &legacy_importer,
1428             USER_ID,
1429             "The user was not unlocked after initialization!",
1430         );
1431 
1432         skm.write().unwrap().data.user_keys.clear();
1433         assert_locked(
1434             &skm,
1435             &mut keystore_db,
1436             &legacy_importer,
1437             USER_ID,
1438             "Clearing the cache did not lock the user!",
1439         );
1440 
1441         assert!(skm
1442             .write()
1443             .unwrap()
1444             .unlock_user(&mut keystore_db, &legacy_importer, USER_ID, &pw)
1445             .is_ok());
1446         assert_unlocked(
1447             &skm,
1448             &mut keystore_db,
1449             &legacy_importer,
1450             USER_ID,
1451             "The user did not unlock!",
1452         );
1453     }
1454 
1455     #[test]
test_unlock_wrong_password()1456     fn test_unlock_wrong_password() {
1457         let pw: Password = generate_password_blob();
1458         let wrong_pw: Password = generate_password_blob();
1459         let (skm, mut keystore_db, legacy_importer) = setup_test(&pw);
1460         assert_unlocked(
1461             &skm,
1462             &mut keystore_db,
1463             &legacy_importer,
1464             USER_ID,
1465             "The user was not unlocked after initialization!",
1466         );
1467 
1468         skm.write().unwrap().data.user_keys.clear();
1469         assert_locked(
1470             &skm,
1471             &mut keystore_db,
1472             &legacy_importer,
1473             USER_ID,
1474             "Clearing the cache did not lock the user!",
1475         );
1476 
1477         assert!(skm
1478             .write()
1479             .unwrap()
1480             .unlock_user(&mut keystore_db, &legacy_importer, USER_ID, &wrong_pw)
1481             .is_err());
1482         assert_locked(
1483             &skm,
1484             &mut keystore_db,
1485             &legacy_importer,
1486             USER_ID,
1487             "The user was unlocked with an incorrect password!",
1488         );
1489     }
1490 
1491     #[test]
test_unlock_user_idempotent()1492     fn test_unlock_user_idempotent() {
1493         let pw: Password = generate_password_blob();
1494         let (skm, mut keystore_db, legacy_importer) = setup_test(&pw);
1495         assert_unlocked(
1496             &skm,
1497             &mut keystore_db,
1498             &legacy_importer,
1499             USER_ID,
1500             "The user was not unlocked after initialization!",
1501         );
1502 
1503         skm.write().unwrap().data.user_keys.clear();
1504         assert_locked(
1505             &skm,
1506             &mut keystore_db,
1507             &legacy_importer,
1508             USER_ID,
1509             "Clearing the cache did not lock the user!",
1510         );
1511 
1512         for _ in 0..5 {
1513             assert!(skm
1514                 .write()
1515                 .unwrap()
1516                 .unlock_user(&mut keystore_db, &legacy_importer, USER_ID, &pw)
1517                 .is_ok());
1518             assert_unlocked(
1519                 &skm,
1520                 &mut keystore_db,
1521                 &legacy_importer,
1522                 USER_ID,
1523                 "The user did not unlock!",
1524             );
1525         }
1526     }
1527 
test_user_removal(locked: bool)1528     fn test_user_removal(locked: bool) {
1529         let pw: Password = generate_password_blob();
1530         let (skm, mut keystore_db, legacy_importer) = setup_test(&pw);
1531         assert_unlocked(
1532             &skm,
1533             &mut keystore_db,
1534             &legacy_importer,
1535             USER_ID,
1536             "The user was not unlocked after initialization!",
1537         );
1538 
1539         assert!(make_test_key_entry(
1540             &mut keystore_db,
1541             Domain::APP,
1542             USER_ID.into(),
1543             TEST_KEY_ALIAS,
1544             None
1545         )
1546         .is_ok());
1547         assert!(make_bootlevel_key_entry(
1548             &mut keystore_db,
1549             Domain::APP,
1550             USER_ID.into(),
1551             TEST_BOOT_KEY_ALIAS,
1552             false
1553         )
1554         .is_ok());
1555 
1556         assert!(keystore_db
1557             .key_exists(Domain::APP, USER_ID.into(), TEST_KEY_ALIAS, KeyType::Client)
1558             .unwrap());
1559         assert!(keystore_db
1560             .key_exists(Domain::APP, USER_ID.into(), TEST_BOOT_KEY_ALIAS, KeyType::Client)
1561             .unwrap());
1562 
1563         if locked {
1564             skm.write().unwrap().data.user_keys.clear();
1565             assert_locked(
1566                 &skm,
1567                 &mut keystore_db,
1568                 &legacy_importer,
1569                 USER_ID,
1570                 "Clearing the cache did not lock the user!",
1571             );
1572         }
1573 
1574         assert!(skm
1575             .write()
1576             .unwrap()
1577             .remove_user(&mut keystore_db, &legacy_importer, USER_ID)
1578             .is_ok());
1579         assert_uninitialized(
1580             &skm,
1581             &mut keystore_db,
1582             &legacy_importer,
1583             USER_ID,
1584             "The user was not removed!",
1585         );
1586 
1587         assert!(!skm
1588             .write()
1589             .unwrap()
1590             .super_key_exists_in_db_for_user(&mut keystore_db, &legacy_importer, USER_ID)
1591             .unwrap());
1592 
1593         assert!(!keystore_db
1594             .key_exists(Domain::APP, USER_ID.into(), TEST_KEY_ALIAS, KeyType::Client)
1595             .unwrap());
1596         assert!(!keystore_db
1597             .key_exists(Domain::APP, USER_ID.into(), TEST_BOOT_KEY_ALIAS, KeyType::Client)
1598             .unwrap());
1599     }
1600 
test_user_reset(locked: bool)1601     fn test_user_reset(locked: bool) {
1602         let pw: Password = generate_password_blob();
1603         let (skm, mut keystore_db, legacy_importer) = setup_test(&pw);
1604         assert_unlocked(
1605             &skm,
1606             &mut keystore_db,
1607             &legacy_importer,
1608             USER_ID,
1609             "The user was not unlocked after initialization!",
1610         );
1611 
1612         assert!(make_test_key_entry(
1613             &mut keystore_db,
1614             Domain::APP,
1615             USER_ID.into(),
1616             TEST_KEY_ALIAS,
1617             None
1618         )
1619         .is_ok());
1620         assert!(make_bootlevel_key_entry(
1621             &mut keystore_db,
1622             Domain::APP,
1623             USER_ID.into(),
1624             TEST_BOOT_KEY_ALIAS,
1625             false
1626         )
1627         .is_ok());
1628         assert!(keystore_db
1629             .key_exists(Domain::APP, USER_ID.into(), TEST_KEY_ALIAS, KeyType::Client)
1630             .unwrap());
1631         assert!(keystore_db
1632             .key_exists(Domain::APP, USER_ID.into(), TEST_BOOT_KEY_ALIAS, KeyType::Client)
1633             .unwrap());
1634 
1635         if locked {
1636             skm.write().unwrap().data.user_keys.clear();
1637             assert_locked(
1638                 &skm,
1639                 &mut keystore_db,
1640                 &legacy_importer,
1641                 USER_ID,
1642                 "Clearing the cache did not lock the user!",
1643             );
1644             assert!(skm
1645                 .write()
1646                 .unwrap()
1647                 .reset_user(&mut keystore_db, &legacy_importer, USER_ID)
1648                 .is_err());
1649             assert_locked(
1650                 &skm,
1651                 &mut keystore_db,
1652                 &legacy_importer,
1653                 USER_ID,
1654                 "User state should not have changed!",
1655             );
1656 
1657             // Keys should still exist.
1658             assert!(keystore_db
1659                 .key_exists(Domain::APP, USER_ID.into(), TEST_KEY_ALIAS, KeyType::Client)
1660                 .unwrap());
1661             assert!(keystore_db
1662                 .key_exists(Domain::APP, USER_ID.into(), TEST_BOOT_KEY_ALIAS, KeyType::Client)
1663                 .unwrap());
1664         } else {
1665             assert!(skm
1666                 .write()
1667                 .unwrap()
1668                 .reset_user(&mut keystore_db, &legacy_importer, USER_ID)
1669                 .is_ok());
1670             assert_uninitialized(
1671                 &skm,
1672                 &mut keystore_db,
1673                 &legacy_importer,
1674                 USER_ID,
1675                 "The user was not reset!",
1676             );
1677             assert!(!skm
1678                 .write()
1679                 .unwrap()
1680                 .super_key_exists_in_db_for_user(&mut keystore_db, &legacy_importer, USER_ID)
1681                 .unwrap());
1682 
1683             // Auth bound key should no longer exist.
1684             assert!(!keystore_db
1685                 .key_exists(Domain::APP, USER_ID.into(), TEST_KEY_ALIAS, KeyType::Client)
1686                 .unwrap());
1687             assert!(keystore_db
1688                 .key_exists(Domain::APP, USER_ID.into(), TEST_BOOT_KEY_ALIAS, KeyType::Client)
1689                 .unwrap());
1690         }
1691     }
1692 
1693     #[test]
test_remove_unlocked_user()1694     fn test_remove_unlocked_user() {
1695         test_user_removal(false);
1696     }
1697 
1698     #[test]
test_remove_locked_user()1699     fn test_remove_locked_user() {
1700         test_user_removal(true);
1701     }
1702 
1703     #[test]
test_reset_unlocked_user()1704     fn test_reset_unlocked_user() {
1705         test_user_reset(false);
1706     }
1707 
1708     #[test]
test_reset_locked_user()1709     fn test_reset_locked_user() {
1710         test_user_reset(true);
1711     }
1712 }
1713