• 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     legacy_blob::LegacyBlobLoader,
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 }
82 
83 /// Key used for LskfLocked keys; the corresponding superencryption key is loaded in memory
84 /// when the user first unlocks, and remains in memory until the device reboots.
85 pub const USER_SUPER_KEY: SuperKeyType =
86     SuperKeyType { alias: "USER_SUPER_KEY", algorithm: SuperEncryptionAlgorithm::Aes256Gcm };
87 /// Key used for ScreenLockBound keys; the corresponding superencryption key is loaded in memory
88 /// each time the user enters their LSKF, and cleared from memory each time the device is locked.
89 /// Symmetric.
90 pub const USER_SCREEN_LOCK_BOUND_KEY: SuperKeyType = SuperKeyType {
91     alias: "USER_SCREEN_LOCK_BOUND_KEY",
92     algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
93 };
94 /// Key used for ScreenLockBound keys; the corresponding superencryption key is loaded in memory
95 /// each time the user enters their LSKF, and cleared from memory each time the device is locked.
96 /// Asymmetric, so keys can be encrypted when the device is locked.
97 pub const USER_SCREEN_LOCK_BOUND_P521_KEY: SuperKeyType = SuperKeyType {
98     alias: "USER_SCREEN_LOCK_BOUND_P521_KEY",
99     algorithm: SuperEncryptionAlgorithm::EcdhP521,
100 };
101 
102 /// Superencryption to apply to a new key.
103 #[derive(Debug, Clone, Copy)]
104 pub enum SuperEncryptionType {
105     /// Do not superencrypt this key.
106     None,
107     /// Superencrypt with a key that remains in memory from first unlock to reboot.
108     LskfBound,
109     /// Superencrypt with a key cleared from memory when the device is locked.
110     ScreenLockBound,
111     /// Superencrypt with a key based on the desired boot level
112     BootLevel(i32),
113 }
114 
115 #[derive(Debug, Clone, Copy)]
116 pub enum SuperKeyIdentifier {
117     /// id of the super key in the database.
118     DatabaseId(i64),
119     /// Boot level of the encrypting boot level key
120     BootLevel(i32),
121 }
122 
123 impl SuperKeyIdentifier {
from_metadata(metadata: &BlobMetaData) -> Option<Self>124     fn from_metadata(metadata: &BlobMetaData) -> Option<Self> {
125         if let Some(EncryptedBy::KeyId(key_id)) = metadata.encrypted_by() {
126             Some(SuperKeyIdentifier::DatabaseId(*key_id))
127         } else {
128             metadata.max_boot_level().map(|boot_level| SuperKeyIdentifier::BootLevel(*boot_level))
129         }
130     }
131 
add_to_metadata(&self, metadata: &mut BlobMetaData)132     fn add_to_metadata(&self, metadata: &mut BlobMetaData) {
133         match self {
134             SuperKeyIdentifier::DatabaseId(id) => {
135                 metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::KeyId(*id)));
136             }
137             SuperKeyIdentifier::BootLevel(level) => {
138                 metadata.add(BlobMetaEntry::MaxBootLevel(*level));
139             }
140         }
141     }
142 }
143 
144 pub struct SuperKey {
145     algorithm: SuperEncryptionAlgorithm,
146     key: ZVec,
147     /// Identifier of the encrypting key, used to write an encrypted blob
148     /// back to the database after re-encryption eg on a key update.
149     id: SuperKeyIdentifier,
150     /// ECDH is more expensive than AES. So on ECDH private keys we set the
151     /// reencrypt_with field to point at the corresponding AES key, and the
152     /// keys will be re-encrypted with AES on first use.
153     reencrypt_with: Option<Arc<SuperKey>>,
154 }
155 
156 impl AesGcm for SuperKey {
decrypt(&self, data: &[u8], iv: &[u8], tag: &[u8]) -> Result<ZVec>157     fn decrypt(&self, data: &[u8], iv: &[u8], tag: &[u8]) -> Result<ZVec> {
158         if self.algorithm == SuperEncryptionAlgorithm::Aes256Gcm {
159             aes_gcm_decrypt(data, iv, tag, &self.key)
160                 .context("In SuperKey::decrypt: Decryption failed.")
161         } else {
162             Err(Error::sys()).context("In SuperKey::decrypt: Key is not an AES key.")
163         }
164     }
165 
encrypt(&self, plaintext: &[u8]) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>)>166     fn encrypt(&self, plaintext: &[u8]) -> Result<(Vec<u8>, Vec<u8>, Vec<u8>)> {
167         if self.algorithm == SuperEncryptionAlgorithm::Aes256Gcm {
168             aes_gcm_encrypt(plaintext, &self.key)
169                 .context("In SuperKey::encrypt: Encryption failed.")
170         } else {
171             Err(Error::sys()).context("In SuperKey::encrypt: Key is not an AES key.")
172         }
173     }
174 }
175 
176 /// A SuperKey that has been encrypted with an AES-GCM key. For
177 /// encryption the key is in memory, and for decryption it is in KM.
178 struct LockedKey {
179     algorithm: SuperEncryptionAlgorithm,
180     id: SuperKeyIdentifier,
181     nonce: Vec<u8>,
182     ciphertext: Vec<u8>, // with tag appended
183 }
184 
185 impl LockedKey {
new(key: &[u8], to_encrypt: &Arc<SuperKey>) -> Result<Self>186     fn new(key: &[u8], to_encrypt: &Arc<SuperKey>) -> Result<Self> {
187         let (mut ciphertext, nonce, mut tag) = aes_gcm_encrypt(&to_encrypt.key, key)?;
188         ciphertext.append(&mut tag);
189         Ok(LockedKey { algorithm: to_encrypt.algorithm, id: to_encrypt.id, nonce, ciphertext })
190     }
191 
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>>192     fn decrypt(
193         &self,
194         db: &mut KeystoreDB,
195         km_dev: &KeyMintDevice,
196         key_id_guard: &KeyIdGuard,
197         key_entry: &KeyEntry,
198         auth_token: &HardwareAuthToken,
199         reencrypt_with: Option<Arc<SuperKey>>,
200     ) -> Result<Arc<SuperKey>> {
201         let key_blob = key_entry
202             .key_blob_info()
203             .as_ref()
204             .map(|(key_blob, _)| KeyBlob::Ref(key_blob))
205             .ok_or(Error::Rc(ResponseCode::KEY_NOT_FOUND))
206             .context("In LockedKey::decrypt: Missing key blob info.")?;
207         let key_params = vec![
208             KeyParameterValue::Algorithm(Algorithm::AES),
209             KeyParameterValue::KeySize(256),
210             KeyParameterValue::BlockMode(BlockMode::GCM),
211             KeyParameterValue::PaddingMode(PaddingMode::NONE),
212             KeyParameterValue::Nonce(self.nonce.clone()),
213             KeyParameterValue::MacLength(128),
214         ];
215         let key_params: Vec<KmKeyParameter> = key_params.into_iter().map(|x| x.into()).collect();
216         let key = ZVec::try_from(km_dev.use_key_in_one_step(
217             db,
218             key_id_guard,
219             &key_blob,
220             KeyPurpose::DECRYPT,
221             &key_params,
222             Some(auth_token),
223             &self.ciphertext,
224         )?)?;
225         Ok(Arc::new(SuperKey { algorithm: self.algorithm, key, id: self.id, reencrypt_with }))
226     }
227 }
228 
229 /// Keys for unlocking UNLOCKED_DEVICE_REQUIRED keys, as LockedKeys, complete with
230 /// a database descriptor for the encrypting key and the sids for the auth tokens
231 /// that can be used to decrypt it.
232 struct BiometricUnlock {
233     /// List of auth token SIDs that can be used to unlock these keys.
234     sids: Vec<i64>,
235     /// Database descriptor of key to use to unlock.
236     key_desc: KeyDescriptor,
237     /// Locked versions of the matching UserSuperKeys fields
238     screen_lock_bound: LockedKey,
239     screen_lock_bound_private: LockedKey,
240 }
241 
242 #[derive(Default)]
243 struct UserSuperKeys {
244     /// The per boot key is used for LSKF binding of authentication bound keys. There is one
245     /// key per android user. The key is stored on flash encrypted with a key derived from a
246     /// secret, that is itself derived from the user's lock screen knowledge factor (LSKF).
247     /// When the user unlocks the device for the first time, this key is unlocked, i.e., decrypted,
248     /// and stays memory resident until the device reboots.
249     per_boot: Option<Arc<SuperKey>>,
250     /// The screen lock key works like the per boot key with the distinction that it is cleared
251     /// from memory when the screen lock is engaged.
252     screen_lock_bound: Option<Arc<SuperKey>>,
253     /// When the device is locked, screen-lock-bound keys can still be encrypted, using
254     /// ECDH public-key encryption. This field holds the decryption private key.
255     screen_lock_bound_private: Option<Arc<SuperKey>>,
256     /// Versions of the above two keys, locked behind a biometric.
257     biometric_unlock: Option<BiometricUnlock>,
258 }
259 
260 #[derive(Default)]
261 struct SkmState {
262     user_keys: HashMap<UserId, UserSuperKeys>,
263     key_index: HashMap<i64, Weak<SuperKey>>,
264     boot_level_key_cache: Option<Mutex<BootLevelKeyCache>>,
265 }
266 
267 impl SkmState {
add_key_to_key_index(&mut self, super_key: &Arc<SuperKey>) -> Result<()>268     fn add_key_to_key_index(&mut self, super_key: &Arc<SuperKey>) -> Result<()> {
269         if let SuperKeyIdentifier::DatabaseId(id) = super_key.id {
270             self.key_index.insert(id, Arc::downgrade(super_key));
271             Ok(())
272         } else {
273             Err(Error::sys()).context(format!(
274                 "In add_key_to_key_index: cannot add key with ID {:?}",
275                 super_key.id
276             ))
277         }
278     }
279 }
280 
281 #[derive(Default)]
282 pub struct SuperKeyManager {
283     data: SkmState,
284 }
285 
286 impl SuperKeyManager {
set_up_boot_level_cache(skm: &Arc<RwLock<Self>>, db: &mut KeystoreDB) -> Result<()>287     pub fn set_up_boot_level_cache(skm: &Arc<RwLock<Self>>, db: &mut KeystoreDB) -> Result<()> {
288         let mut skm_guard = skm.write().unwrap();
289         if skm_guard.data.boot_level_key_cache.is_some() {
290             log::info!("In set_up_boot_level_cache: called for a second time");
291             return Ok(());
292         }
293         let level_zero_key = get_level_zero_key(db)
294             .context("In set_up_boot_level_cache: get_level_zero_key failed")?;
295         skm_guard.data.boot_level_key_cache =
296             Some(Mutex::new(BootLevelKeyCache::new(level_zero_key)));
297         log::info!("Starting boot level watcher.");
298         let clone = skm.clone();
299         std::thread::spawn(move || {
300             Self::watch_boot_level(clone)
301                 .unwrap_or_else(|e| log::error!("watch_boot_level failed:\n{:?}", e));
302         });
303         Ok(())
304     }
305 
306     /// Watch the `keystore.boot_level` system property, and keep boot level up to date.
307     /// Blocks waiting for system property changes, so must be run in its own thread.
watch_boot_level(skm: Arc<RwLock<Self>>) -> Result<()>308     fn watch_boot_level(skm: Arc<RwLock<Self>>) -> Result<()> {
309         let mut w = PropertyWatcher::new("keystore.boot_level")
310             .context("In watch_boot_level: PropertyWatcher::new failed")?;
311         loop {
312             let level = w
313                 .read(|_n, v| v.parse::<usize>().map_err(std::convert::Into::into))
314                 .context("In watch_boot_level: read of property failed")?;
315 
316             // This scope limits the skm_guard life, so we don't hold the skm_guard while
317             // waiting.
318             {
319                 let mut skm_guard = skm.write().unwrap();
320                 let boot_level_key_cache = skm_guard
321                     .data
322                     .boot_level_key_cache
323                     .as_mut()
324                     .ok_or_else(Error::sys)
325                     .context("In watch_boot_level: Boot level cache not initialized")?
326                     .get_mut()
327                     .unwrap();
328                 if level < MAX_MAX_BOOT_LEVEL {
329                     log::info!("Read keystore.boot_level value {}", level);
330                     boot_level_key_cache
331                         .advance_boot_level(level)
332                         .context("In watch_boot_level: advance_boot_level failed")?;
333                 } else {
334                     log::info!(
335                         "keystore.boot_level {} hits maximum {}, finishing.",
336                         level,
337                         MAX_MAX_BOOT_LEVEL
338                     );
339                     boot_level_key_cache.finish();
340                     break;
341                 }
342             }
343             w.wait().context("In watch_boot_level: property wait failed")?;
344         }
345         Ok(())
346     }
347 
level_accessible(&self, boot_level: i32) -> bool348     pub fn level_accessible(&self, boot_level: i32) -> bool {
349         self.data
350             .boot_level_key_cache
351             .as_ref()
352             .map_or(false, |c| c.lock().unwrap().level_accessible(boot_level as usize))
353     }
354 
forget_all_keys_for_user(&mut self, user: UserId)355     pub fn forget_all_keys_for_user(&mut self, user: UserId) {
356         self.data.user_keys.remove(&user);
357     }
358 
install_per_boot_key_for_user( &mut self, user: UserId, super_key: Arc<SuperKey>, ) -> Result<()>359     fn install_per_boot_key_for_user(
360         &mut self,
361         user: UserId,
362         super_key: Arc<SuperKey>,
363     ) -> Result<()> {
364         self.data
365             .add_key_to_key_index(&super_key)
366             .context("In install_per_boot_key_for_user: add_key_to_key_index failed")?;
367         self.data.user_keys.entry(user).or_default().per_boot = Some(super_key);
368         Ok(())
369     }
370 
lookup_key(&self, key_id: &SuperKeyIdentifier) -> Result<Option<Arc<SuperKey>>>371     fn lookup_key(&self, key_id: &SuperKeyIdentifier) -> Result<Option<Arc<SuperKey>>> {
372         Ok(match key_id {
373             SuperKeyIdentifier::DatabaseId(id) => {
374                 self.data.key_index.get(id).and_then(|k| k.upgrade())
375             }
376             SuperKeyIdentifier::BootLevel(level) => self
377                 .data
378                 .boot_level_key_cache
379                 .as_ref()
380                 .map(|b| b.lock().unwrap().aes_key(*level as usize))
381                 .transpose()
382                 .context("In lookup_key: aes_key failed")?
383                 .flatten()
384                 .map(|key| {
385                     Arc::new(SuperKey {
386                         algorithm: SuperEncryptionAlgorithm::Aes256Gcm,
387                         key,
388                         id: *key_id,
389                         reencrypt_with: None,
390                     })
391                 }),
392         })
393     }
394 
get_per_boot_key_by_user_id( &self, user_id: UserId, ) -> Option<Arc<dyn AesGcm + Send + Sync>>395     pub fn get_per_boot_key_by_user_id(
396         &self,
397         user_id: UserId,
398     ) -> Option<Arc<dyn AesGcm + Send + Sync>> {
399         self.get_per_boot_key_by_user_id_internal(user_id)
400             .map(|sk| -> Arc<dyn AesGcm + Send + Sync> { sk })
401     }
402 
get_per_boot_key_by_user_id_internal(&self, user_id: UserId) -> Option<Arc<SuperKey>>403     fn get_per_boot_key_by_user_id_internal(&self, user_id: UserId) -> Option<Arc<SuperKey>> {
404         self.data.user_keys.get(&user_id).and_then(|e| e.per_boot.as_ref().cloned())
405     }
406 
407     /// This function unlocks the super keys for a given user.
408     /// This means the key is loaded from the database, decrypted and placed in the
409     /// super key cache. If there is no such key a new key is created, encrypted with
410     /// a key derived from the given password and stored in the database.
unlock_user_key( &mut self, db: &mut KeystoreDB, user: UserId, pw: &Password, legacy_blob_loader: &LegacyBlobLoader, ) -> Result<()>411     pub fn unlock_user_key(
412         &mut self,
413         db: &mut KeystoreDB,
414         user: UserId,
415         pw: &Password,
416         legacy_blob_loader: &LegacyBlobLoader,
417     ) -> Result<()> {
418         let (_, entry) = db
419             .get_or_create_key_with(
420                 Domain::APP,
421                 user as u64 as i64,
422                 USER_SUPER_KEY.alias,
423                 crate::database::KEYSTORE_UUID,
424                 || {
425                     // For backward compatibility we need to check if there is a super key present.
426                     let super_key = legacy_blob_loader
427                         .load_super_key(user, pw)
428                         .context("In create_new_key: Failed to load legacy key blob.")?;
429                     let super_key = match super_key {
430                         None => {
431                             // No legacy file was found. So we generate a new key.
432                             generate_aes256_key()
433                                 .context("In create_new_key: Failed to generate AES 256 key.")?
434                         }
435                         Some(key) => key,
436                     };
437                     // Regardless of whether we loaded an old AES128 key or generated a new AES256
438                     // key as the super key, we derive a AES256 key from the password and re-encrypt
439                     // the super key before we insert it in the database. The length of the key is
440                     // preserved by the encryption so we don't need any extra flags to inform us
441                     // which algorithm to use it with.
442                     Self::encrypt_with_password(&super_key, pw).context("In create_new_key.")
443                 },
444             )
445             .context("In unlock_user_key: Failed to get key id.")?;
446 
447         self.populate_cache_from_super_key_blob(user, USER_SUPER_KEY.algorithm, entry, pw)
448             .context("In unlock_user_key.")?;
449         Ok(())
450     }
451 
452     /// Check if a given key is super-encrypted, from its metadata. If so, unwrap the key using
453     /// the relevant super key.
unwrap_key_if_required<'a>( &self, metadata: &BlobMetaData, blob: &'a [u8], ) -> Result<KeyBlob<'a>>454     pub fn unwrap_key_if_required<'a>(
455         &self,
456         metadata: &BlobMetaData,
457         blob: &'a [u8],
458     ) -> Result<KeyBlob<'a>> {
459         Ok(if let Some(key_id) = SuperKeyIdentifier::from_metadata(metadata) {
460             let super_key = self
461                 .lookup_key(&key_id)
462                 .context("In unwrap_key: lookup_key failed")?
463                 .ok_or(Error::Rc(ResponseCode::LOCKED))
464                 .context("In unwrap_key: Required super decryption key is not in memory.")?;
465             KeyBlob::Sensitive {
466                 key: Self::unwrap_key_with_key(blob, metadata, &super_key)
467                     .context("In unwrap_key: unwrap_key_with_key failed")?,
468                 reencrypt_with: super_key.reencrypt_with.as_ref().unwrap_or(&super_key).clone(),
469                 force_reencrypt: super_key.reencrypt_with.is_some(),
470             }
471         } else {
472             KeyBlob::Ref(blob)
473         })
474     }
475 
476     /// Unwraps an encrypted key blob given an encryption key.
unwrap_key_with_key(blob: &[u8], metadata: &BlobMetaData, key: &SuperKey) -> Result<ZVec>477     fn unwrap_key_with_key(blob: &[u8], metadata: &BlobMetaData, key: &SuperKey) -> Result<ZVec> {
478         match key.algorithm {
479             SuperEncryptionAlgorithm::Aes256Gcm => match (metadata.iv(), metadata.aead_tag()) {
480                 (Some(iv), Some(tag)) => key
481                     .decrypt(blob, iv, tag)
482                     .context("In unwrap_key_with_key: Failed to decrypt the key blob."),
483                 (iv, tag) => Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
484                     concat!(
485                         "In unwrap_key_with_key: Key has incomplete metadata.",
486                         "Present: iv: {}, aead_tag: {}."
487                     ),
488                     iv.is_some(),
489                     tag.is_some(),
490                 )),
491             },
492             SuperEncryptionAlgorithm::EcdhP521 => {
493                 match (metadata.public_key(), metadata.salt(), metadata.iv(), metadata.aead_tag()) {
494                     (Some(public_key), Some(salt), Some(iv), Some(aead_tag)) => {
495                         ECDHPrivateKey::from_private_key(&key.key)
496                             .and_then(|k| k.decrypt_message(public_key, salt, iv, blob, aead_tag))
497                             .context(
498                                 "In unwrap_key_with_key: Failed to decrypt the key blob with ECDH.",
499                             )
500                     }
501                     (public_key, salt, iv, aead_tag) => {
502                         Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
503                             concat!(
504                                 "In unwrap_key_with_key: Key has incomplete metadata.",
505                                 "Present: public_key: {}, salt: {}, iv: {}, aead_tag: {}."
506                             ),
507                             public_key.is_some(),
508                             salt.is_some(),
509                             iv.is_some(),
510                             aead_tag.is_some(),
511                         ))
512                     }
513                 }
514             }
515         }
516     }
517 
518     /// Checks if user has setup LSKF, even when super key cache is empty for the user.
519     /// The reference to self is unused but it is required to prevent calling this function
520     /// 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>521     fn super_key_exists_in_db_for_user(
522         &self,
523         db: &mut KeystoreDB,
524         legacy_importer: &LegacyImporter,
525         user_id: UserId,
526     ) -> Result<bool> {
527         let key_in_db = db
528             .key_exists(Domain::APP, user_id as u64 as i64, USER_SUPER_KEY.alias, KeyType::Super)
529             .context("In super_key_exists_in_db_for_user.")?;
530 
531         if key_in_db {
532             Ok(key_in_db)
533         } else {
534             legacy_importer
535                 .has_super_key(user_id)
536                 .context("In super_key_exists_in_db_for_user: Trying to query legacy db.")
537         }
538     }
539 
540     /// Checks if user has already setup LSKF (i.e. a super key is persisted in the database or the
541     /// legacy database). If not, return Uninitialized state.
542     /// Otherwise, decrypt the super key from the password and return LskfUnlocked state.
check_and_unlock_super_key( &mut self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, pw: &Password, ) -> Result<UserState>543     pub fn check_and_unlock_super_key(
544         &mut self,
545         db: &mut KeystoreDB,
546         legacy_importer: &LegacyImporter,
547         user_id: UserId,
548         pw: &Password,
549     ) -> Result<UserState> {
550         let alias = &USER_SUPER_KEY;
551         let result = legacy_importer
552             .with_try_import_super_key(user_id, pw, || db.load_super_key(alias, user_id))
553             .context("In check_and_unlock_super_key. Failed to load super key")?;
554 
555         match result {
556             Some((_, entry)) => {
557                 let super_key = self
558                     .populate_cache_from_super_key_blob(user_id, alias.algorithm, entry, pw)
559                     .context("In check_and_unlock_super_key.")?;
560                 Ok(UserState::LskfUnlocked(super_key))
561             }
562             None => Ok(UserState::Uninitialized),
563         }
564     }
565 
566     /// Checks if user has already setup LSKF (i.e. a super key is persisted in the database or the
567     /// legacy database). If so, return LskfLocked state.
568     /// If the password is provided, generate a new super key, encrypt with the password,
569     /// store in the database and populate the super key cache for the new user
570     /// and return LskfUnlocked state.
571     /// If the password is not provided, return Uninitialized state.
check_and_initialize_super_key( &mut self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, pw: Option<&Password>, ) -> Result<UserState>572     pub fn check_and_initialize_super_key(
573         &mut self,
574         db: &mut KeystoreDB,
575         legacy_importer: &LegacyImporter,
576         user_id: UserId,
577         pw: Option<&Password>,
578     ) -> Result<UserState> {
579         let super_key_exists_in_db = self
580             .super_key_exists_in_db_for_user(db, legacy_importer, user_id)
581             .context("In check_and_initialize_super_key. Failed to check if super key exists.")?;
582         if super_key_exists_in_db {
583             Ok(UserState::LskfLocked)
584         } else if let Some(pw) = pw {
585             // Generate a new super key.
586             let super_key = generate_aes256_key()
587                 .context("In check_and_initialize_super_key: Failed to generate AES 256 key.")?;
588             // Derive an AES256 key from the password and re-encrypt the super key
589             // before we insert it in the database.
590             let (encrypted_super_key, blob_metadata) = Self::encrypt_with_password(&super_key, pw)
591                 .context("In check_and_initialize_super_key.")?;
592 
593             let key_entry = db
594                 .store_super_key(
595                     user_id,
596                     &USER_SUPER_KEY,
597                     &encrypted_super_key,
598                     &blob_metadata,
599                     &KeyMetaData::new(),
600                 )
601                 .context("In check_and_initialize_super_key. Failed to store super key.")?;
602 
603             let super_key = self
604                 .populate_cache_from_super_key_blob(
605                     user_id,
606                     USER_SUPER_KEY.algorithm,
607                     key_entry,
608                     pw,
609                 )
610                 .context("In check_and_initialize_super_key.")?;
611             Ok(UserState::LskfUnlocked(super_key))
612         } else {
613             Ok(UserState::Uninitialized)
614         }
615     }
616 
617     // 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>>618     fn populate_cache_from_super_key_blob(
619         &mut self,
620         user_id: UserId,
621         algorithm: SuperEncryptionAlgorithm,
622         entry: KeyEntry,
623         pw: &Password,
624     ) -> Result<Arc<SuperKey>> {
625         let super_key = Self::extract_super_key_from_key_entry(algorithm, entry, pw, None)
626             .context(
627                 "In populate_cache_from_super_key_blob. Failed to extract super key from key entry",
628             )?;
629         self.install_per_boot_key_for_user(user_id, super_key.clone())?;
630         Ok(super_key)
631     }
632 
633     /// 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>>634     pub fn extract_super_key_from_key_entry(
635         algorithm: SuperEncryptionAlgorithm,
636         entry: KeyEntry,
637         pw: &Password,
638         reencrypt_with: Option<Arc<SuperKey>>,
639     ) -> Result<Arc<SuperKey>> {
640         if let Some((blob, metadata)) = entry.key_blob_info() {
641             let key = match (
642                 metadata.encrypted_by(),
643                 metadata.salt(),
644                 metadata.iv(),
645                 metadata.aead_tag(),
646             ) {
647                 (Some(&EncryptedBy::Password), Some(salt), Some(iv), Some(tag)) => {
648                     // Note that password encryption is AES no matter the value of algorithm.
649                     let key = pw.derive_key(Some(salt), AES_256_KEY_LENGTH).context(
650                         "In extract_super_key_from_key_entry: Failed to generate key from password.",
651                     )?;
652 
653                     aes_gcm_decrypt(blob, iv, tag, &key).context(
654                         "In extract_super_key_from_key_entry: Failed to decrypt key blob.",
655                     )?
656                 }
657                 (enc_by, salt, iv, tag) => {
658                     return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
659                         concat!(
660                         "In extract_super_key_from_key_entry: Super key has incomplete metadata.",
661                         "encrypted_by: {:?}; Present: salt: {}, iv: {}, aead_tag: {}."
662                     ),
663                         enc_by,
664                         salt.is_some(),
665                         iv.is_some(),
666                         tag.is_some()
667                     ));
668                 }
669             };
670             Ok(Arc::new(SuperKey {
671                 algorithm,
672                 key,
673                 id: SuperKeyIdentifier::DatabaseId(entry.id()),
674                 reencrypt_with,
675             }))
676         } else {
677             Err(Error::Rc(ResponseCode::VALUE_CORRUPTED))
678                 .context("In extract_super_key_from_key_entry: No key blob info.")
679         }
680     }
681 
682     /// Encrypts the super key from a key derived from the password, before storing in the database.
encrypt_with_password( super_key: &[u8], pw: &Password, ) -> Result<(Vec<u8>, BlobMetaData)>683     pub fn encrypt_with_password(
684         super_key: &[u8],
685         pw: &Password,
686     ) -> Result<(Vec<u8>, BlobMetaData)> {
687         let salt = generate_salt().context("In encrypt_with_password: Failed to generate salt.")?;
688         let derived_key = pw
689             .derive_key(Some(&salt), AES_256_KEY_LENGTH)
690             .context("In encrypt_with_password: Failed to derive password.")?;
691         let mut metadata = BlobMetaData::new();
692         metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
693         metadata.add(BlobMetaEntry::Salt(salt));
694         let (encrypted_key, iv, tag) = aes_gcm_encrypt(super_key, &derived_key)
695             .context("In encrypt_with_password: Failed to encrypt new super key.")?;
696         metadata.add(BlobMetaEntry::Iv(iv));
697         metadata.add(BlobMetaEntry::AeadTag(tag));
698         Ok((encrypted_key, metadata))
699     }
700 
701     // Encrypt the given key blob with the user's super key, if the super key exists and the device
702     // is unlocked. If the super key exists and the device is locked, or LSKF is not setup,
703     // return error. Note that it is out of the scope of this function to check if super encryption
704     // is required. Such check should be performed before calling this function.
super_encrypt_on_key_init( &self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, key_blob: &[u8], ) -> Result<(Vec<u8>, BlobMetaData)>705     fn super_encrypt_on_key_init(
706         &self,
707         db: &mut KeystoreDB,
708         legacy_importer: &LegacyImporter,
709         user_id: UserId,
710         key_blob: &[u8],
711     ) -> Result<(Vec<u8>, BlobMetaData)> {
712         match self
713             .get_user_state(db, legacy_importer, user_id)
714             .context("In super_encrypt. Failed to get user state.")?
715         {
716             UserState::LskfUnlocked(super_key) => {
717                 Self::encrypt_with_aes_super_key(key_blob, &super_key)
718                     .context("In super_encrypt_on_key_init. Failed to encrypt the key.")
719             }
720             UserState::LskfLocked => {
721                 Err(Error::Rc(ResponseCode::LOCKED)).context("In super_encrypt. Device is locked.")
722             }
723             UserState::Uninitialized => Err(Error::Rc(ResponseCode::UNINITIALIZED))
724                 .context("In super_encrypt. LSKF is not setup for the user."),
725         }
726     }
727 
728     // Helper function to encrypt a key with the given super key. Callers should select which super
729     // key to be used. This is called when a key is super encrypted at its creation as well as at
730     // its upgrade.
encrypt_with_aes_super_key( key_blob: &[u8], super_key: &SuperKey, ) -> Result<(Vec<u8>, BlobMetaData)>731     fn encrypt_with_aes_super_key(
732         key_blob: &[u8],
733         super_key: &SuperKey,
734     ) -> Result<(Vec<u8>, BlobMetaData)> {
735         if super_key.algorithm != SuperEncryptionAlgorithm::Aes256Gcm {
736             return Err(Error::sys())
737                 .context("In encrypt_with_aes_super_key: unexpected algorithm");
738         }
739         let mut metadata = BlobMetaData::new();
740         let (encrypted_key, iv, tag) = aes_gcm_encrypt(key_blob, &(super_key.key))
741             .context("In encrypt_with_aes_super_key: Failed to encrypt new super key.")?;
742         metadata.add(BlobMetaEntry::Iv(iv));
743         metadata.add(BlobMetaEntry::AeadTag(tag));
744         super_key.id.add_to_metadata(&mut metadata);
745         Ok((encrypted_key, metadata))
746     }
747 
748     /// Check if super encryption is required and if so, super-encrypt the key to be stored in
749     /// the database.
750     #[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)>751     pub fn handle_super_encryption_on_key_init(
752         &self,
753         db: &mut KeystoreDB,
754         legacy_importer: &LegacyImporter,
755         domain: &Domain,
756         key_parameters: &[KeyParameter],
757         flags: Option<i32>,
758         user_id: UserId,
759         key_blob: &[u8],
760     ) -> Result<(Vec<u8>, BlobMetaData)> {
761         match Enforcements::super_encryption_required(domain, key_parameters, flags) {
762             SuperEncryptionType::None => Ok((key_blob.to_vec(), BlobMetaData::new())),
763             SuperEncryptionType::LskfBound => self
764                 .super_encrypt_on_key_init(db, legacy_importer, user_id, key_blob)
765                 .context(concat!(
766                     "In handle_super_encryption_on_key_init. ",
767                     "Failed to super encrypt with LskfBound key."
768                 )),
769             SuperEncryptionType::ScreenLockBound => {
770                 let entry =
771                     self.data.user_keys.get(&user_id).and_then(|e| e.screen_lock_bound.as_ref());
772                 if let Some(super_key) = entry {
773                     Self::encrypt_with_aes_super_key(key_blob, super_key).context(concat!(
774                         "In handle_super_encryption_on_key_init. ",
775                         "Failed to encrypt with ScreenLockBound key."
776                     ))
777                 } else {
778                     // Symmetric key is not available, use public key encryption
779                     let loaded =
780                         db.load_super_key(&USER_SCREEN_LOCK_BOUND_P521_KEY, user_id).context(
781                             "In handle_super_encryption_on_key_init: load_super_key failed.",
782                         )?;
783                     let (key_id_guard, key_entry) = loaded.ok_or_else(Error::sys).context(
784                         "In handle_super_encryption_on_key_init: User ECDH key missing.",
785                     )?;
786                     let public_key =
787                         key_entry.metadata().sec1_public_key().ok_or_else(Error::sys).context(
788                             "In handle_super_encryption_on_key_init: sec1_public_key missing.",
789                         )?;
790                     let mut metadata = BlobMetaData::new();
791                     let (ephem_key, salt, iv, encrypted_key, aead_tag) =
792                         ECDHPrivateKey::encrypt_message(public_key, key_blob).context(concat!(
793                             "In handle_super_encryption_on_key_init: ",
794                             "ECDHPrivateKey::encrypt_message failed."
795                         ))?;
796                     metadata.add(BlobMetaEntry::PublicKey(ephem_key));
797                     metadata.add(BlobMetaEntry::Salt(salt));
798                     metadata.add(BlobMetaEntry::Iv(iv));
799                     metadata.add(BlobMetaEntry::AeadTag(aead_tag));
800                     SuperKeyIdentifier::DatabaseId(key_id_guard.id())
801                         .add_to_metadata(&mut metadata);
802                     Ok((encrypted_key, metadata))
803                 }
804             }
805             SuperEncryptionType::BootLevel(level) => {
806                 let key_id = SuperKeyIdentifier::BootLevel(level);
807                 let super_key = self
808                     .lookup_key(&key_id)
809                     .context("In handle_super_encryption_on_key_init: lookup_key failed")?
810                     .ok_or(Error::Rc(ResponseCode::LOCKED))
811                     .context("In handle_super_encryption_on_key_init: Boot stage key absent")?;
812                 Self::encrypt_with_aes_super_key(key_blob, &super_key).context(concat!(
813                     "In handle_super_encryption_on_key_init: ",
814                     "Failed to encrypt with BootLevel key."
815                 ))
816             }
817         }
818     }
819 
820     /// Check if a given key needs re-super-encryption, from its KeyBlob type.
821     /// If so, re-super-encrypt the key and return a new set of metadata,
822     /// 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>)>823     pub fn reencrypt_if_required<'a>(
824         key_blob_before_upgrade: &KeyBlob,
825         key_after_upgrade: &'a [u8],
826     ) -> Result<(KeyBlob<'a>, Option<BlobMetaData>)> {
827         match key_blob_before_upgrade {
828             KeyBlob::Sensitive { reencrypt_with: super_key, .. } => {
829                 let (key, metadata) =
830                     Self::encrypt_with_aes_super_key(key_after_upgrade, super_key)
831                         .context("In reencrypt_if_required: Failed to re-super-encrypt key.")?;
832                 Ok((KeyBlob::NonSensitive(key), Some(metadata)))
833             }
834             _ => Ok((KeyBlob::Ref(key_after_upgrade), None)),
835         }
836     }
837 
838     /// Fetch a superencryption key from the database, or create it if it doesn't already exist.
839     /// When this is called, the caller must hold the lock on the SuperKeyManager.
840     /// 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>>841     fn get_or_create_super_key(
842         &mut self,
843         db: &mut KeystoreDB,
844         user_id: UserId,
845         key_type: &SuperKeyType,
846         password: &Password,
847         reencrypt_with: Option<Arc<SuperKey>>,
848     ) -> Result<Arc<SuperKey>> {
849         let loaded_key = db.load_super_key(key_type, user_id)?;
850         if let Some((_, key_entry)) = loaded_key {
851             Ok(Self::extract_super_key_from_key_entry(
852                 key_type.algorithm,
853                 key_entry,
854                 password,
855                 reencrypt_with,
856             )?)
857         } else {
858             let (super_key, public_key) = match key_type.algorithm {
859                 SuperEncryptionAlgorithm::Aes256Gcm => (
860                     generate_aes256_key()
861                         .context("In get_or_create_super_key: Failed to generate AES 256 key.")?,
862                     None,
863                 ),
864                 SuperEncryptionAlgorithm::EcdhP521 => {
865                     let key = ECDHPrivateKey::generate()
866                         .context("In get_or_create_super_key: Failed to generate ECDH key")?;
867                     (
868                         key.private_key()
869                             .context("In get_or_create_super_key: private_key failed")?,
870                         Some(
871                             key.public_key()
872                                 .context("In get_or_create_super_key: public_key failed")?,
873                         ),
874                     )
875                 }
876             };
877             // Derive an AES256 key from the password and re-encrypt the super key
878             // before we insert it in the database.
879             let (encrypted_super_key, blob_metadata) =
880                 Self::encrypt_with_password(&super_key, password)
881                     .context("In get_or_create_super_key.")?;
882             let mut key_metadata = KeyMetaData::new();
883             if let Some(pk) = public_key {
884                 key_metadata.add(KeyMetaEntry::Sec1PublicKey(pk));
885             }
886             let key_entry = db
887                 .store_super_key(
888                     user_id,
889                     key_type,
890                     &encrypted_super_key,
891                     &blob_metadata,
892                     &key_metadata,
893                 )
894                 .context("In get_or_create_super_key. Failed to store super key.")?;
895             Ok(Arc::new(SuperKey {
896                 algorithm: key_type.algorithm,
897                 key: super_key,
898                 id: SuperKeyIdentifier::DatabaseId(key_entry.id()),
899                 reencrypt_with,
900             }))
901         }
902     }
903 
904     /// Decrypt the screen-lock bound keys for this user using the password and store in memory.
unlock_screen_lock_bound_key( &mut self, db: &mut KeystoreDB, user_id: UserId, password: &Password, ) -> Result<()>905     pub fn unlock_screen_lock_bound_key(
906         &mut self,
907         db: &mut KeystoreDB,
908         user_id: UserId,
909         password: &Password,
910     ) -> Result<()> {
911         let (screen_lock_bound, screen_lock_bound_private) = self
912             .data
913             .user_keys
914             .get(&user_id)
915             .map(|e| (e.screen_lock_bound.clone(), e.screen_lock_bound_private.clone()))
916             .unwrap_or((None, None));
917 
918         if screen_lock_bound.is_some() && screen_lock_bound_private.is_some() {
919             // Already unlocked.
920             return Ok(());
921         }
922 
923         let aes = if let Some(screen_lock_bound) = screen_lock_bound {
924             // This is weird. If this point is reached only one of the screen locked keys was
925             // initialized. This should never happen.
926             screen_lock_bound
927         } else {
928             self.get_or_create_super_key(db, user_id, &USER_SCREEN_LOCK_BOUND_KEY, password, None)
929                 .context("In unlock_screen_lock_bound_key: Trying to get or create symmetric key.")?
930         };
931 
932         let ecdh = if let Some(screen_lock_bound_private) = screen_lock_bound_private {
933             // This is weird. If this point is reached only one of the screen locked keys was
934             // initialized. This should never happen.
935             screen_lock_bound_private
936         } else {
937             self.get_or_create_super_key(
938                 db,
939                 user_id,
940                 &USER_SCREEN_LOCK_BOUND_P521_KEY,
941                 password,
942                 Some(aes.clone()),
943             )
944             .context("In unlock_screen_lock_bound_key: Trying to get or create asymmetric key.")?
945         };
946 
947         self.data.add_key_to_key_index(&aes)?;
948         self.data.add_key_to_key_index(&ecdh)?;
949         let entry = self.data.user_keys.entry(user_id).or_default();
950         entry.screen_lock_bound = Some(aes);
951         entry.screen_lock_bound_private = Some(ecdh);
952         Ok(())
953     }
954 
955     /// Wipe the screen-lock bound keys for this user from memory.
lock_screen_lock_bound_key( &mut self, db: &mut KeystoreDB, user_id: UserId, unlocking_sids: &[i64], )956     pub fn lock_screen_lock_bound_key(
957         &mut self,
958         db: &mut KeystoreDB,
959         user_id: UserId,
960         unlocking_sids: &[i64],
961     ) {
962         log::info!("Locking screen bound for user {} sids {:?}", user_id, unlocking_sids);
963         let mut entry = self.data.user_keys.entry(user_id).or_default();
964         if !unlocking_sids.is_empty() {
965             if let (Some(aes), Some(ecdh)) = (
966                 entry.screen_lock_bound.as_ref().cloned(),
967                 entry.screen_lock_bound_private.as_ref().cloned(),
968             ) {
969                 let res = (|| -> Result<()> {
970                     let key_desc = KeyMintDevice::internal_descriptor(format!(
971                         "biometric_unlock_key_{}",
972                         user_id
973                     ));
974                     let encrypting_key = generate_aes256_key()?;
975                     let km_dev: KeyMintDevice =
976                         KeyMintDevice::get(SecurityLevel::TRUSTED_ENVIRONMENT)
977                             .context("In lock_screen_lock_bound_key: KeyMintDevice::get failed")?;
978                     let mut key_params = vec![
979                         KeyParameterValue::Algorithm(Algorithm::AES),
980                         KeyParameterValue::KeySize(256),
981                         KeyParameterValue::BlockMode(BlockMode::GCM),
982                         KeyParameterValue::PaddingMode(PaddingMode::NONE),
983                         KeyParameterValue::CallerNonce,
984                         KeyParameterValue::KeyPurpose(KeyPurpose::DECRYPT),
985                         KeyParameterValue::MinMacLength(128),
986                         KeyParameterValue::AuthTimeout(BIOMETRIC_AUTH_TIMEOUT_S),
987                         KeyParameterValue::HardwareAuthenticatorType(
988                             HardwareAuthenticatorType::FINGERPRINT,
989                         ),
990                     ];
991                     for sid in unlocking_sids {
992                         key_params.push(KeyParameterValue::UserSecureID(*sid));
993                     }
994                     let key_params: Vec<KmKeyParameter> =
995                         key_params.into_iter().map(|x| x.into()).collect();
996                     km_dev.create_and_store_key(
997                         db,
998                         &key_desc,
999                         KeyType::Client, /* TODO Should be Super b/189470584 */
1000                         |dev| {
1001                             let _wp = wd::watch_millis(
1002                                 "In lock_screen_lock_bound_key: calling importKey.",
1003                                 500,
1004                             );
1005                             dev.importKey(
1006                                 key_params.as_slice(),
1007                                 KeyFormat::RAW,
1008                                 &encrypting_key,
1009                                 None,
1010                             )
1011                         },
1012                     )?;
1013                     entry.biometric_unlock = Some(BiometricUnlock {
1014                         sids: unlocking_sids.into(),
1015                         key_desc,
1016                         screen_lock_bound: LockedKey::new(&encrypting_key, &aes)?,
1017                         screen_lock_bound_private: LockedKey::new(&encrypting_key, &ecdh)?,
1018                     });
1019                     Ok(())
1020                 })();
1021                 // There is no reason to propagate an error here upwards. We must discard
1022                 // entry.screen_lock_bound* in any case.
1023                 if let Err(e) = res {
1024                     log::error!("Error setting up biometric unlock: {:#?}", e);
1025                 }
1026             }
1027         }
1028         entry.screen_lock_bound = None;
1029         entry.screen_lock_bound_private = None;
1030     }
1031 
1032     /// User has unlocked, not using a password. See if any of our stored auth tokens can be used
1033     /// to unlock the keys protecting UNLOCKED_DEVICE_REQUIRED keys.
try_unlock_user_with_biometric( &mut self, db: &mut KeystoreDB, user_id: UserId, ) -> Result<()>1034     pub fn try_unlock_user_with_biometric(
1035         &mut self,
1036         db: &mut KeystoreDB,
1037         user_id: UserId,
1038     ) -> Result<()> {
1039         let mut entry = self.data.user_keys.entry(user_id).or_default();
1040         if let Some(biometric) = entry.biometric_unlock.as_ref() {
1041             let (key_id_guard, key_entry) = db
1042                 .load_key_entry(
1043                     &biometric.key_desc,
1044                     KeyType::Client, // This should not be a Client key.
1045                     KeyEntryLoadBits::KM,
1046                     AID_KEYSTORE,
1047                     |_, _| Ok(()),
1048                 )
1049                 .context("In try_unlock_user_with_biometric: load_key_entry failed")?;
1050             let km_dev: KeyMintDevice = KeyMintDevice::get(SecurityLevel::TRUSTED_ENVIRONMENT)
1051                 .context("In try_unlock_user_with_biometric: KeyMintDevice::get failed")?;
1052             for sid in &biometric.sids {
1053                 if let Some((auth_token_entry, _)) = db.find_auth_token_entry(|entry| {
1054                     entry.auth_token().userId == *sid || entry.auth_token().authenticatorId == *sid
1055                 }) {
1056                     let res: Result<(Arc<SuperKey>, Arc<SuperKey>)> = (|| {
1057                         let slb = biometric.screen_lock_bound.decrypt(
1058                             db,
1059                             &km_dev,
1060                             &key_id_guard,
1061                             &key_entry,
1062                             auth_token_entry.auth_token(),
1063                             None,
1064                         )?;
1065                         let slbp = biometric.screen_lock_bound_private.decrypt(
1066                             db,
1067                             &km_dev,
1068                             &key_id_guard,
1069                             &key_entry,
1070                             auth_token_entry.auth_token(),
1071                             Some(slb.clone()),
1072                         )?;
1073                         Ok((slb, slbp))
1074                     })();
1075                     match res {
1076                         Ok((slb, slbp)) => {
1077                             entry.screen_lock_bound = Some(slb.clone());
1078                             entry.screen_lock_bound_private = Some(slbp.clone());
1079                             self.data.add_key_to_key_index(&slb)?;
1080                             self.data.add_key_to_key_index(&slbp)?;
1081                             log::info!(concat!(
1082                                 "In try_unlock_user_with_biometric: ",
1083                                 "Successfully unlocked with biometric"
1084                             ));
1085                             return Ok(());
1086                         }
1087                         Err(e) => {
1088                             log::warn!("In try_unlock_user_with_biometric: attempt failed: {:?}", e)
1089                         }
1090                     }
1091                 }
1092             }
1093         }
1094         Ok(())
1095     }
1096 
1097     /// Returns the keystore locked state of the given user. It requires the thread local
1098     /// keystore database and a reference to the legacy migrator because it may need to
1099     /// 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>1100     pub fn get_user_state(
1101         &self,
1102         db: &mut KeystoreDB,
1103         legacy_importer: &LegacyImporter,
1104         user_id: UserId,
1105     ) -> Result<UserState> {
1106         match self.get_per_boot_key_by_user_id_internal(user_id) {
1107             Some(super_key) => Ok(UserState::LskfUnlocked(super_key)),
1108             None => {
1109                 // Check if a super key exists in the database or legacy database.
1110                 // If so, return locked user state.
1111                 if self
1112                     .super_key_exists_in_db_for_user(db, legacy_importer, user_id)
1113                     .context("In get_user_state.")?
1114                 {
1115                     Ok(UserState::LskfLocked)
1116                 } else {
1117                     Ok(UserState::Uninitialized)
1118                 }
1119             }
1120         }
1121     }
1122 
1123     /// If the given user is unlocked:
1124     /// * and `password` is None, the user is reset, all authentication bound keys are deleted and
1125     ///   `Ok(UserState::Uninitialized)` is returned.
1126     /// * and `password` is Some, `Ok(UserState::LskfUnlocked)` is returned.
1127     /// If the given user is locked:
1128     /// * and the user was initialized before, `Ok(UserState::Locked)` is returned.
1129     /// * and the user was not initialized before:
1130     ///   * and `password` is None, `Ok(Uninitialized)` is returned.
1131     ///   * and `password` is Some, super keys are generated and `Ok(UserState::LskfUnlocked)` is
1132     ///     returned.
reset_or_init_user_and_get_user_state( &mut self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, password: Option<&Password>, ) -> Result<UserState>1133     pub fn reset_or_init_user_and_get_user_state(
1134         &mut self,
1135         db: &mut KeystoreDB,
1136         legacy_importer: &LegacyImporter,
1137         user_id: UserId,
1138         password: Option<&Password>,
1139     ) -> Result<UserState> {
1140         match self.get_per_boot_key_by_user_id_internal(user_id) {
1141             Some(_) if password.is_none() => {
1142                 // Transitioning to swiping, delete only the super key in database and cache,
1143                 // and super-encrypted keys in database (and in KM).
1144                 self.reset_user(db, legacy_importer, user_id, true).context(
1145                     "In reset_or_init_user_and_get_user_state: Trying to delete keys from the db.",
1146                 )?;
1147                 // Lskf is now removed in Keystore.
1148                 Ok(UserState::Uninitialized)
1149             }
1150             Some(super_key) => {
1151                 // Keystore won't be notified when changing to a new password when LSKF is
1152                 // already setup. Therefore, ideally this path wouldn't be reached.
1153                 Ok(UserState::LskfUnlocked(super_key))
1154             }
1155             None => {
1156                 // Check if a super key exists in the database or legacy database.
1157                 // If so, return LskfLocked state.
1158                 // Otherwise, i) if the password is provided, initialize the super key and return
1159                 // LskfUnlocked state ii) if password is not provided, return Uninitialized state.
1160                 self.check_and_initialize_super_key(db, legacy_importer, user_id, password)
1161             }
1162         }
1163     }
1164 
1165     /// Unlocks the given user with the given password. If the key was already unlocked or unlocking
1166     /// was successful, `Ok(UserState::LskfUnlocked)` is returned.
1167     /// If the user was never initialized `Ok(UserState::Uninitialized)` is returned.
unlock_and_get_user_state( &mut self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, password: &Password, ) -> Result<UserState>1168     pub fn unlock_and_get_user_state(
1169         &mut self,
1170         db: &mut KeystoreDB,
1171         legacy_importer: &LegacyImporter,
1172         user_id: UserId,
1173         password: &Password,
1174     ) -> Result<UserState> {
1175         match self.get_per_boot_key_by_user_id_internal(user_id) {
1176             Some(super_key) => {
1177                 log::info!("In unlock_and_get_user_state. Trying to unlock when already unlocked.");
1178                 Ok(UserState::LskfUnlocked(super_key))
1179             }
1180             None => {
1181                 // Check if a super key exists in the database or legacy database.
1182                 // If not, return Uninitialized state.
1183                 // Otherwise, try to unlock the super key and if successful,
1184                 // return LskfUnlocked.
1185                 self.check_and_unlock_super_key(db, legacy_importer, user_id, password)
1186                     .context("In unlock_and_get_user_state. Failed to unlock super key.")
1187             }
1188         }
1189     }
1190 
1191     /// Delete all the keys created on behalf of the user.
1192     /// If 'keep_non_super_encrypted_keys' is set to true, delete only the super key and super
1193     /// encrypted keys.
reset_user( &mut self, db: &mut KeystoreDB, legacy_importer: &LegacyImporter, user_id: UserId, keep_non_super_encrypted_keys: bool, ) -> Result<()>1194     pub fn reset_user(
1195         &mut self,
1196         db: &mut KeystoreDB,
1197         legacy_importer: &LegacyImporter,
1198         user_id: UserId,
1199         keep_non_super_encrypted_keys: bool,
1200     ) -> Result<()> {
1201         // Mark keys created on behalf of the user as unreferenced.
1202         legacy_importer
1203             .bulk_delete_user(user_id, keep_non_super_encrypted_keys)
1204             .context("In reset_user: Trying to delete legacy keys.")?;
1205         db.unbind_keys_for_user(user_id, keep_non_super_encrypted_keys)
1206             .context("In reset user. Error in unbinding keys.")?;
1207 
1208         // Delete super key in cache, if exists.
1209         self.forget_all_keys_for_user(user_id);
1210         Ok(())
1211     }
1212 }
1213 
1214 /// This enum represents different states of the user's life cycle in the device.
1215 /// For now, only three states are defined. More states may be added later.
1216 pub enum UserState {
1217     // The user has registered LSKF and has unlocked the device by entering PIN/Password,
1218     // and hence the per-boot super key is available in the cache.
1219     LskfUnlocked(Arc<SuperKey>),
1220     // The user has registered LSKF, but has not unlocked the device using password, after reboot.
1221     // Hence the per-boot super-key(s) is not available in the cache.
1222     // However, the encrypted super key is available in the database.
1223     LskfLocked,
1224     // There's no user in the device for the given user id, or the user with the user id has not
1225     // setup LSKF.
1226     Uninitialized,
1227 }
1228 
1229 /// This enum represents three states a KeyMint Blob can be in, w.r.t super encryption.
1230 /// `Sensitive` holds the non encrypted key and a reference to its super key.
1231 /// `NonSensitive` holds a non encrypted key that is never supposed to be encrypted.
1232 /// `Ref` holds a reference to a key blob when it does not need to be modified if its
1233 /// life time allows it.
1234 pub enum KeyBlob<'a> {
1235     Sensitive {
1236         key: ZVec,
1237         /// If KeyMint reports that the key must be upgraded, we must
1238         /// re-encrypt the key before writing to the database; we use
1239         /// this key.
1240         reencrypt_with: Arc<SuperKey>,
1241         /// If this key was decrypted with an ECDH key, we want to
1242         /// re-encrypt it on first use whether it was upgraded or not;
1243         /// this field indicates that that's necessary.
1244         force_reencrypt: bool,
1245     },
1246     NonSensitive(Vec<u8>),
1247     Ref(&'a [u8]),
1248 }
1249 
1250 impl<'a> KeyBlob<'a> {
force_reencrypt(&self) -> bool1251     pub fn force_reencrypt(&self) -> bool {
1252         if let KeyBlob::Sensitive { force_reencrypt, .. } = self {
1253             *force_reencrypt
1254         } else {
1255             false
1256         }
1257     }
1258 }
1259 
1260 /// Deref returns a reference to the key material in any variant.
1261 impl<'a> Deref for KeyBlob<'a> {
1262     type Target = [u8];
1263 
deref(&self) -> &Self::Target1264     fn deref(&self) -> &Self::Target {
1265         match self {
1266             Self::Sensitive { key, .. } => key,
1267             Self::NonSensitive(key) => key,
1268             Self::Ref(key) => key,
1269         }
1270     }
1271 }
1272