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