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