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