Simplify control flow for user unlocking.

Keystore2 super key handling is being refactored in preparation for
Unlocked-Only Storage.

Currently, super_key.rs exposes two functions to authorization.rs for
key unlocking:
- unlock_screen_lock_bound_key
- unlock_and_get_user_state

This change simplifies the key_unlocking logic to a single function,
unlock_user. This new function handles all of the unlocking logic and
functions more like a state machine than the previous code.

This change mainly improves readability. It tries not to change
functionality.

Bug: 280502317
Bug: 277798192
Test: Wiped device. Setup user with PIN. Ensured unlock works. Remove
    PIN. Ensured unlock works. Added pin and biometric. Ensured unlock
    works.  Rebooted device. Ensured unlock works.
Change-Id: Ib9a3e907cd40d34c5ecf2a869a65e403deda0254
diff --git a/keystore2/src/authorization.rs b/keystore2/src/authorization.rs
index 1953920..4f2c7bd 100644
--- a/keystore2/src/authorization.rs
+++ b/keystore2/src/authorization.rs
@@ -19,7 +19,6 @@
 use crate::error::anyhow_error_to_cstring;
 use crate::globals::{ENFORCEMENTS, SUPER_KEY, DB, LEGACY_IMPORTER};
 use crate::permission::KeystorePerm;
-use crate::super_key::UserState;
 use crate::utils::{check_keystore_permission, watchdog as wd};
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
     HardwareAuthToken::HardwareAuthToken,
@@ -158,31 +157,14 @@
                 let mut skm = SUPER_KEY.write().unwrap();
 
                 DB.with(|db| {
-                    skm.unlock_screen_lock_bound_key(
+                    skm.unlock_user(
                         &mut db.borrow_mut(),
+                        &LEGACY_IMPORTER,
                         user_id as u32,
                         &password,
                     )
                 })
-                .context(ks_err!("unlock_screen_lock_bound_key failed"))?;
-
-                // Unlock super key.
-                if let UserState::Uninitialized = DB
-                    .with(|db| {
-                        skm.unlock_and_get_user_state(
-                            &mut db.borrow_mut(),
-                            &LEGACY_IMPORTER,
-                            user_id as u32,
-                            &password,
-                        )
-                    })
-                    .context(ks_err!("Unlock with password."))?
-                {
-                    log::info!(
-                        "In on_lock_screen_event. Trying to unlock when LSKF is uninitialized."
-                    );
-                }
-
+                .context(ks_err!("Unlock with password."))?;
                 Ok(())
             }
             (LockScreenEvent::UNLOCK, None) => {
diff --git a/keystore2/src/super_key.rs b/keystore2/src/super_key.rs
index b155349..fc82538 100644
--- a/keystore2/src/super_key.rs
+++ b/keystore2/src/super_key.rs
@@ -480,32 +480,6 @@
         }
     }
 
-    /// Checks if user has already setup LSKF (i.e. a super key is persisted in the database or the
-    /// legacy database). If not, return Uninitialized state.
-    /// Otherwise, decrypt the super key from the password and return LskfUnlocked state.
-    pub fn check_and_unlock_super_key(
-        &mut self,
-        db: &mut KeystoreDB,
-        legacy_importer: &LegacyImporter,
-        user_id: UserId,
-        pw: &Password,
-    ) -> Result<UserState> {
-        let alias = &USER_SUPER_KEY;
-        let result = legacy_importer
-            .with_try_import_super_key(user_id, pw, || db.load_super_key(alias, user_id))
-            .context(ks_err!("Failed to load super key"))?;
-
-        match result {
-            Some((_, entry)) => {
-                let super_key = self
-                    .populate_cache_from_super_key_blob(user_id, alias.algorithm, entry, pw)
-                    .context(ks_err!())?;
-                Ok(UserState::LskfUnlocked(super_key))
-            }
-            None => Ok(UserState::Uninitialized),
-        }
-    }
-
     // Helper function to populate super key cache from the super key blob loaded from the database.
     fn populate_cache_from_super_key_blob(
         &mut self,
@@ -665,9 +639,8 @@
         match Enforcements::super_encryption_required(domain, key_parameters, flags) {
             SuperEncryptionType::None => Ok((key_blob.to_vec(), BlobMetaData::new())),
             SuperEncryptionType::LskfBound => {
-                // Encrypt the given key blob with the user's per-boot super key, if the per-boot
-                // super key is available.  If the device is boot-locked or the LSKF is not setup,
-                // an error is returned.
+                // Encrypt the given key blob with the user's per-boot super key.  If the per-boot
+                // super key is not unlocked or the LSKF is not setup, an error is returned.
                 match self
                     .get_user_state(db, legacy_importer, user_id)
                     .context(ks_err!("Failed to get user state."))?
@@ -1101,28 +1074,50 @@
         }
     }
 
-    /// Unlocks the given user with the given password. If the key was already unlocked or unlocking
-    /// was successful, `Ok(UserState::LskfUnlocked)` is returned.
-    /// If the user was never initialized `Ok(UserState::Uninitialized)` is returned.
-    pub fn unlock_and_get_user_state(
+    /// Unlocks the given user with the given password.
+    ///
+    /// If the user is LskfLocked:
+    /// - Unlock the per_boot super key
+    /// - Unlock the screen_lock_bound super key
+    ///
+    /// If the user is LskfUnlocked:
+    /// - Unlock the screen_lock_bound super key only
+    ///
+    pub fn unlock_user(
         &mut self,
         db: &mut KeystoreDB,
         legacy_importer: &LegacyImporter,
         user_id: UserId,
         password: &Password,
-    ) -> Result<UserState> {
-        match self.get_per_boot_key_by_user_id_internal(user_id) {
-            Some(super_key) => {
-                log::info!("Trying to unlock when already unlocked.");
-                Ok(UserState::LskfUnlocked(super_key))
+    ) -> Result<()> {
+        match self.get_user_state(db, legacy_importer, user_id)? {
+            UserState::LskfUnlocked(_) => self.unlock_screen_lock_bound_key(db, user_id, password),
+            UserState::Uninitialized => {
+                Err(Error::sys()).context(ks_err!("Tried to unlock an uninitialized user!"))
             }
-            None => {
-                // Check if a super key exists in the database or legacy database.
-                // If not, return Uninitialized state.
-                // Otherwise, try to unlock the super key and if successful,
-                // return LskfUnlocked.
-                self.check_and_unlock_super_key(db, legacy_importer, user_id, password)
-                    .context(ks_err!("Failed to unlock super key."))
+            UserState::LskfLocked => {
+                let alias = &USER_SUPER_KEY;
+                let result = legacy_importer
+                    .with_try_import_super_key(user_id, password, || {
+                        db.load_super_key(alias, user_id)
+                    })
+                    .context(ks_err!("Failed to load super key"))?;
+
+                match result {
+                    Some((_, entry)) => {
+                        self.populate_cache_from_super_key_blob(
+                            user_id,
+                            alias.algorithm,
+                            entry,
+                            password,
+                        )
+                        .context(ks_err!("Failed when unlocking user."))?;
+                        self.unlock_screen_lock_bound_key(db, user_id, password)
+                    }
+                    None => {
+                        Err(Error::sys()).context(ks_err!("Locked user does not have a super key!"))
+                    }
+                }
             }
         }
     }