Implement user manager AIDL.

This CL implements add/remove user and onPasswordChanged.
clearUID functionality, which is also part of this API will be added in
a separate upcoming CL.

Bug: 176123105
Test: TBD
Change-Id: I610441b0aac225740e09039958542dcf2f4fe0b6
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index 0a5fb29..fec74f6 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -24,6 +24,7 @@
         "android.security.authorization-rust",
         "android.security.compat-rust",
         "android.security.remoteprovisioning-rust",
+        "android.security.usermanager-rust",
         "android.system.keystore2-V1-rust",
         "libanyhow",
         "libbinder_rs",
@@ -66,6 +67,7 @@
         "android.security.authorization-rust",
         "android.security.compat-rust",
         "android.security.remoteprovisioning-rust",
+        "android.security.usermanager-rust",
         "android.system.keystore2-V1-rust",
         "libandroid_logger",
         "libanyhow",
diff --git a/keystore2/src/authorization.rs b/keystore2/src/authorization.rs
index ad86625..fbaa9eb 100644
--- a/keystore2/src/authorization.rs
+++ b/keystore2/src/authorization.rs
@@ -20,10 +20,7 @@
 use crate::permission::KeystorePerm;
 use crate::utils::check_keystore_permission;
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
-    HardwareAuthToken::HardwareAuthToken, HardwareAuthenticatorType::HardwareAuthenticatorType,
-};
-use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
-    Timestamp::Timestamp,
+    HardwareAuthToken::HardwareAuthToken,
 };
 use android_security_authorization::binder::{Interface, Result as BinderResult, Strong};
 use android_security_authorization::aidl::android::security::authorization::IKeystoreAuthorization::{
@@ -50,16 +47,7 @@
         //check keystore permission
         check_keystore_permission(KeystorePerm::add_auth()).context("In add_auth_token.")?;
 
-        //TODO: Keymint's HardwareAuthToken aidl needs to implement Copy/Clone
-        let auth_token_copy = HardwareAuthToken {
-            challenge: auth_token.challenge,
-            userId: auth_token.userId,
-            authenticatorId: auth_token.authenticatorId,
-            authenticatorType: HardwareAuthenticatorType(auth_token.authenticatorType.0),
-            timestamp: Timestamp { milliSeconds: auth_token.timestamp.milliSeconds },
-            mac: auth_token.mac.clone(),
-        };
-        ENFORCEMENTS.add_auth_token(auth_token_copy)?;
+        ENFORCEMENTS.add_auth_token(auth_token.clone())?;
         Ok(())
     }
 
@@ -85,9 +73,9 @@
                     //method is used as it is, which created a super key for the user if one does
                     //not exists, in addition to unlocking the existing super key of the user/
                     SUPER_KEY.unlock_user_key(
+                        &mut db,
                         user_id as u32,
                         user_password,
-                        &mut db,
                         &LEGACY_BLOB_LOADER,
                     )?;
                     Ok(())
diff --git a/keystore2/src/database.rs b/keystore2/src/database.rs
index 3c26827..6cdbc3e 100644
--- a/keystore2/src/database.rs
+++ b/keystore2/src/database.rs
@@ -45,7 +45,7 @@
 use crate::impl_metadata; // This is in db_utils.rs
 use crate::key_parameter::{KeyParameter, Tag};
 use crate::permission::KeyPermSet;
-use crate::utils::get_current_time_in_seconds;
+use crate::utils::{get_current_time_in_seconds, AID_USER_OFFSET};
 use crate::{
     db_utils::{self, SqlField},
     gc::Gc,
@@ -1120,6 +1120,47 @@
         .context("In key_exists.")
     }
 
+    /// Stores a super key in the database.
+    pub fn store_super_key(
+        &mut self,
+        user_id: i64,
+        blob_info: &(&[u8], &BlobMetaData),
+    ) -> Result<KeyEntry> {
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let key_id = Self::insert_with_retry(|id| {
+                tx.execute(
+                    "INSERT into persistent.keyentry
+                            (id, key_type, domain, namespace, alias, state, km_uuid)
+                            VALUES(?, ?, NULL, ?, ?, ?, ?);",
+                    params![
+                        id,
+                        KeyType::Super,
+                        user_id,
+                        Self::USER_SUPER_KEY_ALIAS,
+                        KeyLifeCycle::Live,
+                        &KEYSTORE_UUID,
+                    ],
+                )
+            })
+            .context("Failed to insert into keyentry table.")?;
+
+            let (blob, blob_metadata) = *blob_info;
+            Self::set_blob_internal(
+                &tx,
+                key_id,
+                SubComponentType::KEY_BLOB,
+                Some(blob),
+                Some(blob_metadata),
+            )
+            .context("Failed to store key blob.")?;
+
+            Self::load_key_components(tx, KeyEntryLoadBits::KM, key_id)
+                .context("Trying to load key components.")
+                .no_gc()
+        })
+        .context("In store_super_key.")
+    }
+
     /// Atomically loads a key entry and associated metadata or creates it using the
     /// callback create_new_key callback. The callback is called during a database
     /// transaction. This means that implementers should be mindful about using
@@ -2419,6 +2460,82 @@
         .context("In get_key_km_uuid.")
     }
 
+    /// Delete the keys created on behalf of the user, denoted by the user id.
+    /// Delete all the keys unless 'keep_non_super_encrypted_keys' set to true.
+    /// Returned boolean is to hint the garbage collector to delete the unbound keys.
+    /// The caller of this function should notify the gc if the returned value is true.
+    pub fn unbind_keys_for_user(
+        &mut self,
+        user_id: u32,
+        keep_non_super_encrypted_keys: bool,
+    ) -> Result<()> {
+        self.with_transaction(TransactionBehavior::Immediate, |tx| {
+            let mut stmt = tx
+                .prepare(&format!(
+                    "SELECT id from persistent.keyentry
+                     WHERE (
+                         key_type = ?
+                         AND domain = ?
+                         AND cast ( (namespace/{aid_user_offset}) as int) = ?
+                         AND state = ?
+                     ) OR (
+                         key_type = ?
+                         AND namespace = ?
+                         AND alias = ?
+                         AND state = ?
+                     );",
+                    aid_user_offset = AID_USER_OFFSET
+                ))
+                .context(concat!(
+                    "In unbind_keys_for_user. ",
+                    "Failed to prepare the query to find the keys created by apps."
+                ))?;
+
+            let mut rows = stmt
+                .query(params![
+                    // WHERE client key:
+                    KeyType::Client,
+                    Domain::APP.0 as u32,
+                    user_id,
+                    KeyLifeCycle::Live,
+                    // OR super key:
+                    KeyType::Super,
+                    user_id,
+                    Self::USER_SUPER_KEY_ALIAS,
+                    KeyLifeCycle::Live
+                ])
+                .context("In unbind_keys_for_user. Failed to query the keys created by apps.")?;
+
+            let mut key_ids: Vec<i64> = Vec::new();
+            db_utils::with_rows_extract_all(&mut rows, |row| {
+                key_ids
+                    .push(row.get(0).context("Failed to read key id of a key created by an app.")?);
+                Ok(())
+            })
+            .context("In unbind_keys_for_user.")?;
+
+            let mut notify_gc = false;
+            for key_id in key_ids {
+                if keep_non_super_encrypted_keys {
+                    // Load metadata and filter out non-super-encrypted keys.
+                    if let (_, Some((_, blob_metadata)), _, _) =
+                        Self::load_blob_components(key_id, KeyEntryLoadBits::KM, tx)
+                            .context("In unbind_keys_for_user: Trying to load blob info.")?
+                    {
+                        if blob_metadata.encrypted_by().is_none() {
+                            continue;
+                        }
+                    }
+                }
+                notify_gc = Self::mark_unreferenced(&tx, key_id as u64 as i64)
+                    .context("In unbind_keys_for_user.")?
+                    || notify_gc;
+            }
+            Ok(()).do_gc(notify_gc)
+        })
+        .context("In unbind_keys_for_user.")
+    }
+
     fn load_key_components(
         tx: &Transaction,
         load_bits: KeyEntryLoadBits,
@@ -2711,6 +2828,7 @@
     };
     use crate::key_perm_set;
     use crate::permission::{KeyPerm, KeyPermSet};
+    use crate::super_key::SuperKeyManager;
     use keystore2_test_utils::TempDir;
     use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
         HardwareAuthToken::HardwareAuthToken,
@@ -4568,4 +4686,59 @@
         assert!(last_off_body_1.seconds() < last_off_body_2.seconds());
         Ok(())
     }
+
+    #[test]
+    fn test_unbind_keys_for_user() -> Result<()> {
+        let mut db = new_test_db()?;
+        db.unbind_keys_for_user(1, false)?;
+
+        make_test_key_entry(&mut db, Domain::APP, 210000, TEST_ALIAS, None)?;
+        make_test_key_entry(&mut db, Domain::APP, 110000, TEST_ALIAS, None)?;
+        db.unbind_keys_for_user(2, false)?;
+
+        assert_eq!(1, db.list(Domain::APP, 110000)?.len());
+        assert_eq!(0, db.list(Domain::APP, 210000)?.len());
+
+        db.unbind_keys_for_user(1, true)?;
+        assert_eq!(0, db.list(Domain::APP, 110000)?.len());
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_store_super_key() -> Result<()> {
+        let mut db = new_test_db()?;
+        let pw = "xyzabc".as_bytes();
+        let super_key = keystore2_crypto::generate_aes256_key()?;
+        let secret = String::from("keystore2 is great.");
+        let secret_bytes = secret.into_bytes();
+        let (encrypted_secret, iv, tag) =
+            keystore2_crypto::aes_gcm_encrypt(&secret_bytes, &super_key)?;
+
+        let (encrypted_super_key, metadata) =
+            SuperKeyManager::encrypt_with_password(&super_key, &pw)?;
+        db.store_super_key(1, &(&encrypted_super_key, &metadata))?;
+
+        //load the super key from the database
+        let tx = db.conn.transaction_with_behavior(TransactionBehavior::Immediate)?;
+        let key_descriptor = KeyDescriptor {
+            domain: Domain::APP,
+            nspace: 1,
+            alias: Some(String::from("USER_SUPER_KEY")),
+            blob: None,
+        };
+        let id = KeystoreDB::load_key_entry_id(&tx, &key_descriptor, KeyType::Super)?;
+        let key_entry = KeystoreDB::load_key_components(&tx, KeyEntryLoadBits::KM, id)?;
+        let loaded_super_key = SuperKeyManager::extract_super_key_from_key_entry(key_entry, &pw)?;
+
+        let decrypted_secret_bytes = keystore2_crypto::aes_gcm_decrypt(
+            &encrypted_secret,
+            &iv,
+            &tag,
+            &loaded_super_key.get_key(),
+        )?;
+        let decrypted_secret = String::from_utf8((&decrypted_secret_bytes).to_vec())?;
+        assert_eq!(String::from("keystore2 is great."), decrypted_secret);
+        Ok(())
+    }
 }
diff --git a/keystore2/src/keystore2_main.rs b/keystore2/src/keystore2_main.rs
index 75475e1..30e3e22 100644
--- a/keystore2/src/keystore2_main.rs
+++ b/keystore2/src/keystore2_main.rs
@@ -18,12 +18,14 @@
 use keystore2::authorization::AuthorizationManager;
 use keystore2::globals::ENFORCEMENTS;
 use keystore2::service::KeystoreService;
+use keystore2::user_manager::UserManager;
 use log::{error, info};
 use std::{panic, path::Path, sync::mpsc::channel};
 
 static KS2_SERVICE_NAME: &str = "android.system.keystore2";
 static APC_SERVICE_NAME: &str = "android.security.apc";
 static AUTHORIZATION_SERVICE_NAME: &str = "android.security.authorization";
+static USER_MANAGER_SERVICE_NAME: &str = "android.security.usermanager";
 
 /// Keystore 2.0 takes one argument which is a path indicating its designated working directory.
 fn main() {
@@ -87,6 +89,15 @@
             panic!("Failed to register service {} because of {:?}.", AUTHORIZATION_SERVICE_NAME, e);
         });
 
+    let usermanager_service = UserManager::new_native_binder().unwrap_or_else(|e| {
+        panic!("Failed to create service {} because of {:?}.", USER_MANAGER_SERVICE_NAME, e);
+    });
+    binder::add_service(USER_MANAGER_SERVICE_NAME, usermanager_service.as_binder()).unwrap_or_else(
+        |e| {
+            panic!("Failed to register service {} because of {:?}.", USER_MANAGER_SERVICE_NAME, e);
+        },
+    );
+
     info!("Successfully registered Keystore 2.0 service.");
 
     info!("Joining thread pool now.");
diff --git a/keystore2/src/legacy_blob.rs b/keystore2/src/legacy_blob.rs
index deeaa10..d4688ac 100644
--- a/keystore2/src/legacy_blob.rs
+++ b/keystore2/src/legacy_blob.rs
@@ -951,7 +951,7 @@
             Some(&error::Error::Rc(ResponseCode::LOCKED))
         );
 
-        key_manager.unlock_user_key(0, PASSWORD, &mut db, &legacy_blob_loader)?;
+        key_manager.unlock_user_key(&mut db, 0, PASSWORD, &legacy_blob_loader)?;
 
         if let (Some((Blob { flags, value }, _params)), Some(cert), Some(chain), _kp) =
             legacy_blob_loader.load_by_uid_alias(10223, "authbound", &key_manager)?
diff --git a/keystore2/src/lib.rs b/keystore2/src/lib.rs
index f9554ea..445aef6 100644
--- a/keystore2/src/lib.rs
+++ b/keystore2/src/lib.rs
@@ -29,6 +29,7 @@
 pub mod remote_provisioning;
 pub mod security_level;
 pub mod service;
+pub mod user_manager;
 pub mod utils;
 
 mod async_task;
diff --git a/keystore2/src/super_key.rs b/keystore2/src/super_key.rs
index ded14a9..0aae232 100644
--- a/keystore2/src/super_key.rs
+++ b/keystore2/src/super_key.rs
@@ -15,14 +15,15 @@
 #![allow(dead_code)]
 
 use crate::{
-    database::BlobMetaData, database::BlobMetaEntry, database::EncryptedBy, database::KeyType,
-    database::KeystoreDB, error::Error, error::ResponseCode, legacy_blob::LegacyBlobLoader,
+    database::BlobMetaData, database::BlobMetaEntry, database::EncryptedBy, database::KeyEntry,
+    database::KeyType, database::KeystoreDB, error::Error, error::ResponseCode,
+    legacy_blob::LegacyBlobLoader,
 };
 use android_system_keystore2::aidl::android::system::keystore2::Domain::Domain;
 use anyhow::{Context, Result};
 use keystore2_crypto::{
-    aes_gcm_decrypt, aes_gcm_encrypt, derive_key_from_password, generate_salt, ZVec,
-    AES_256_KEY_LENGTH,
+    aes_gcm_decrypt, aes_gcm_encrypt, derive_key_from_password, generate_aes256_key, generate_salt,
+    ZVec, AES_256_KEY_LENGTH,
 };
 use std::{
     collections::HashMap,
@@ -104,11 +105,10 @@
         data.key_index.clear();
     }
 
-    fn install_per_boot_key_for_user(&self, user: UserId, id: i64, key: ZVec) {
+    fn install_per_boot_key_for_user(&self, user: UserId, super_key: SuperKey) {
         let mut data = self.data.lock().unwrap();
-        let key = Arc::new(key);
-        data.key_index.insert(id, Arc::downgrade(&key));
-        data.user_keys.entry(user).or_default().per_boot = Some(SuperKey { key, id });
+        data.key_index.insert(super_key.id, Arc::downgrade(&(super_key.key)));
+        data.user_keys.entry(user).or_default().per_boot = Some(super_key);
     }
 
     fn get_key(&self, key_id: &i64) -> Option<Arc<ZVec>> {
@@ -126,9 +126,9 @@
     /// a key derived from the given password and stored in the database.
     pub fn unlock_user_key(
         &self,
+        db: &mut KeystoreDB,
         user: UserId,
         pw: &[u8],
-        db: &mut KeystoreDB,
         legacy_blob_loader: &LegacyBlobLoader,
     ) -> Result<()> {
         let (_, entry) = db
@@ -145,64 +145,22 @@
                     let super_key = match super_key {
                         None => {
                             // No legacy file was found. So we generate a new key.
-                            keystore2_crypto::generate_aes256_key()
+                            generate_aes256_key()
                                 .context("In create_new_key: Failed to generate AES 256 key.")?
                         }
                         Some(key) => key,
                     };
-                    // Regardless of whether we loaded an old AES128 key or a new AES256 key,
-                    // we derive a AES256 key and re-encrypt the key before we insert it in the
-                    // database. The length of the key is preserved by the encryption so we don't
-                    // need any extra flags to inform us which algorithm to use it with.
-                    let salt =
-                        generate_salt().context("In create_new_key: Failed to generate salt.")?;
-                    let derived_key = derive_key_from_password(pw, Some(&salt), AES_256_KEY_LENGTH)
-                        .context("In create_new_key: Failed to derive password.")?;
-                    let mut metadata = BlobMetaData::new();
-                    metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
-                    metadata.add(BlobMetaEntry::Salt(salt));
-                    let (encrypted_key, iv, tag) = aes_gcm_encrypt(&super_key, &derived_key)
-                        .context("In create_new_key: Failed to encrypt new super key.")?;
-                    metadata.add(BlobMetaEntry::Iv(iv));
-                    metadata.add(BlobMetaEntry::AeadTag(tag));
-                    Ok((encrypted_key, metadata))
+                    // Regardless of whether we loaded an old AES128 key or generated a new AES256
+                    // key as the super key, we derive a AES256 key from the password and re-encrypt
+                    // the super key before we insert it in the database. The length of the key is
+                    // preserved by the encryption so we don't need any extra flags to inform us
+                    // which algorithm to use it with.
+                    Self::encrypt_with_password(&super_key, pw).context("In create_new_key.")
                 },
             )
             .context("In unlock_user_key: Failed to get key id.")?;
 
-        if let Some((ref blob, ref metadata)) = entry.key_blob_info() {
-            let super_key = match (
-                metadata.encrypted_by(),
-                metadata.salt(),
-                metadata.iv(),
-                metadata.aead_tag(),
-            ) {
-                (Some(&EncryptedBy::Password), Some(salt), Some(iv), Some(tag)) => {
-                    let key = derive_key_from_password(pw, Some(salt), AES_256_KEY_LENGTH)
-                        .context("In unlock_user_key: Failed to generate key from password.")?;
-
-                    aes_gcm_decrypt(blob, iv, tag, &key)
-                        .context("In unlock_user_key: Failed to decrypt key blob.")?
-                }
-                (enc_by, salt, iv, tag) => {
-                    return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
-                        concat!(
-                            "In unlock_user_key: Super key has incomplete metadata.",
-                            "Present: encrypted_by: {}, salt: {}, iv: {}, aead_tag: {}."
-                        ),
-                        enc_by.is_some(),
-                        salt.is_some(),
-                        iv.is_some(),
-                        tag.is_some(),
-                    ));
-                }
-            };
-            self.install_per_boot_key_for_user(user, entry.id(), super_key);
-        } else {
-            return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED))
-                .context("In unlock_user_key: Key entry has no key blob.");
-        }
-
+        self.populate_cache_from_super_key_blob(user, entry, pw).context("In unlock_user_key.")?;
         Ok(())
     }
 
@@ -259,6 +217,118 @@
             Ok(false)
         }
     }
+
+    /// Checks if user has already setup LSKF (i.e. a super key is persisted in the database or the
+    /// legacy database). If so, return LskfLocked state.
+    /// If the password is provided, generate a new super key, encrypt with the password,
+    /// store in the database and populate the super key cache for the new user
+    /// and return LskfUnlocked state.
+    /// If the password is not provided, return Uninitialized state.
+    pub fn check_and_initialize_super_key(
+        &self,
+        db: &mut KeystoreDB,
+        user_id: u32,
+        pw: Option<&[u8]>,
+    ) -> Result<UserState> {
+        let super_key_exists_in_db = Self::super_key_exists_in_db_for_user(db, user_id)
+            .context("In check_and_initialize_super_key. Failed to check if super key exists.")?;
+
+        if super_key_exists_in_db {
+            Ok(UserState::LskfLocked)
+        } else {
+            //TODO: 159371296. check if super key exists in legacy key database. If so, return
+            //LskfLocked. Otherwise, if pw is provided, initialize the super key.
+            if let Some(pw) = pw {
+                //generate a new super key.
+                let super_key = generate_aes256_key().context(
+                    "In check_and_initialize_super_key: Failed to generate AES 256 key.",
+                )?;
+                //derive an AES256 key from the password and re-encrypt the super key
+                //before we insert it in the database.
+                let (encrypted_super_key, blob_metadata) =
+                    Self::encrypt_with_password(&super_key, pw)
+                        .context("In check_and_initialize_super_key.")?;
+
+                let key_entry = db
+                    .store_super_key(user_id as u64 as i64, &(&encrypted_super_key, &blob_metadata))
+                    .context("In check_and_initialize_super_key. Failed to store super key.")?;
+
+                let super_key = self
+                    .populate_cache_from_super_key_blob(user_id, key_entry, pw)
+                    .context("In check_and_initialize_super_key.")?;
+                Ok(UserState::LskfUnlocked(super_key))
+            } else {
+                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(
+        &self,
+        user_id: u32,
+        entry: KeyEntry,
+        pw: &[u8],
+    ) -> Result<SuperKey> {
+        let super_key = Self::extract_super_key_from_key_entry(entry, pw).context(
+            "In populate_cache_from_super_key_blob. Failed to extract super key from key entry",
+        )?;
+        self.install_per_boot_key_for_user(user_id, super_key.clone());
+        Ok(super_key)
+    }
+
+    /// Extracts super key from the entry loaded from the database
+    pub fn extract_super_key_from_key_entry(entry: KeyEntry, pw: &[u8]) -> Result<SuperKey> {
+        if let Some((blob, metadata)) = entry.key_blob_info() {
+            let key = match (
+                metadata.encrypted_by(),
+                metadata.salt(),
+                metadata.iv(),
+                metadata.aead_tag(),
+            ) {
+                (Some(&EncryptedBy::Password), Some(salt), Some(iv), Some(tag)) => {
+                    let key = derive_key_from_password(pw, Some(salt), AES_256_KEY_LENGTH).context(
+                    "In extract_super_key_from_key_entry: Failed to generate key from password.",
+                )?;
+
+                    aes_gcm_decrypt(blob, iv, tag, &key).context(
+                        "In extract_super_key_from_key_entry: Failed to decrypt key blob.",
+                    )?
+                }
+                (enc_by, salt, iv, tag) => {
+                    return Err(Error::Rc(ResponseCode::VALUE_CORRUPTED)).context(format!(
+                        concat!(
+                        "In extract_super_key_from_key_entry: Super key has incomplete metadata.",
+                        "Present: encrypted_by: {}, salt: {}, iv: {}, aead_tag: {}."
+                    ),
+                        enc_by.is_some(),
+                        salt.is_some(),
+                        iv.is_some(),
+                        tag.is_some()
+                    ));
+                }
+            };
+            Ok(SuperKey { key: Arc::new(key), id: entry.id() })
+        } else {
+            Err(Error::Rc(ResponseCode::VALUE_CORRUPTED))
+                .context("In extract_super_key_from_key_entry: No key blob info.")
+        }
+    }
+
+    /// Encrypts the super key from a key derived from the password, before storing in the database.
+    pub fn encrypt_with_password(super_key: &[u8], pw: &[u8]) -> Result<(Vec<u8>, BlobMetaData)> {
+        let salt = generate_salt().context("In encrypt_with_password: Failed to generate salt.")?;
+        let derived_key = derive_key_from_password(pw, Some(&salt), AES_256_KEY_LENGTH)
+            .context("In encrypt_with_password: Failed to derive password.")?;
+        let mut metadata = BlobMetaData::new();
+        metadata.add(BlobMetaEntry::EncryptedBy(EncryptedBy::Password));
+        metadata.add(BlobMetaEntry::Salt(salt));
+        let (encrypted_key, iv, tag) = aes_gcm_encrypt(super_key, &derived_key)
+            .context("In encrypt_with_password: Failed to encrypt new super key.")?;
+        metadata.add(BlobMetaEntry::Iv(iv));
+        metadata.add(BlobMetaEntry::AeadTag(tag));
+        Ok((encrypted_key, metadata))
+    }
 }
 
 /// This enum represents different states of the user's life cycle in the device.
@@ -277,18 +347,14 @@
 }
 
 impl UserState {
-    pub fn get_user_state(
-        db: &mut KeystoreDB,
-        skm: &SuperKeyManager,
-        user_id: u32,
-    ) -> Result<UserState> {
+    pub fn get(db: &mut KeystoreDB, skm: &SuperKeyManager, user_id: u32) -> Result<UserState> {
         match skm.get_per_boot_key_by_user_id(user_id) {
             Some(super_key) => Ok(UserState::LskfUnlocked(super_key)),
             None => {
                 //Check if a super key exists in the database or legacy database.
                 //If so, return locked user state.
                 if SuperKeyManager::super_key_exists_in_db_for_user(db, user_id)
-                    .context("In get_user_state.")?
+                    .context("In get.")?
                 {
                     Ok(UserState::LskfLocked)
                 } else {
@@ -297,4 +363,54 @@
             }
         }
     }
+
+    /// Queries user state when serving password change requests.
+    pub fn get_with_password_changed(
+        db: &mut KeystoreDB,
+        skm: &SuperKeyManager,
+        user_id: u32,
+        password: Option<&[u8]>,
+    ) -> Result<UserState> {
+        match skm.get_per_boot_key_by_user_id(user_id) {
+            Some(super_key) => {
+                if password.is_none() {
+                    //transitioning to swiping, delete only the super key in database and cache, and
+                    //super-encrypted keys in database (and in KM)
+                    Self::reset_user(db, skm, user_id, true)
+                        .context("In get_with_password_changed.")?;
+                    //Lskf is now removed in Keystore
+                    Ok(UserState::Uninitialized)
+                } else {
+                    //Keystore won't be notified when changing to a new password when LSKF is
+                    //already setup. Therefore, ideally this path wouldn't be reached.
+                    Ok(UserState::LskfUnlocked(super_key))
+                }
+            }
+            None => {
+                //Check if a super key exists in the database or legacy database.
+                //If so, return LskfLocked state.
+                //Otherwise, i) if the password is provided, initialize the super key and return
+                //LskfUnlocked state ii) if password is not provided, return Uninitialized state.
+                skm.check_and_initialize_super_key(db, user_id, password)
+            }
+        }
+    }
+
+    /// Delete all the keys created on behalf of the user.
+    /// If 'keep_non_super_encrypted_keys' is set to true, delete only the super key and super
+    /// encrypted keys.
+    pub fn reset_user(
+        db: &mut KeystoreDB,
+        skm: &SuperKeyManager,
+        user_id: u32,
+        keep_non_super_encrypted_keys: bool,
+    ) -> Result<()> {
+        // mark keys created on behalf of the user as unreferenced.
+        db.unbind_keys_for_user(user_id as u32, keep_non_super_encrypted_keys)
+            .context("In reset user. Error in unbinding keys.")?;
+
+        //delete super key in cache, if exists
+        skm.forget_all_keys_for_user(user_id as u32);
+        Ok(())
+    }
 }
diff --git a/keystore2/src/user_manager.rs b/keystore2/src/user_manager.rs
new file mode 100644
index 0000000..9ee6727
--- /dev/null
+++ b/keystore2/src/user_manager.rs
@@ -0,0 +1,94 @@
+// Copyright 2021, The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! This module implements IKeystoreUserManager AIDL interface.
+
+use crate::error::map_or_log_err;
+use crate::error::Error as KeystoreError;
+use crate::globals::{DB, SUPER_KEY};
+use crate::permission::KeystorePerm;
+use crate::super_key::UserState;
+use crate::utils::check_keystore_permission;
+use android_security_usermanager::aidl::android::security::usermanager::IKeystoreUserManager::{
+    BnKeystoreUserManager, IKeystoreUserManager,
+};
+use android_security_usermanager::binder::{Interface, Result as BinderResult};
+use android_system_keystore2::aidl::android::system::keystore2::ResponseCode::ResponseCode;
+use anyhow::{Context, Result};
+use binder::{IBinder, Strong};
+
+/// This struct is defined to implement the aforementioned AIDL interface.
+/// As of now, it is an empty struct.
+pub struct UserManager;
+
+impl UserManager {
+    /// Create a new instance of Keystore User Manager service.
+    pub fn new_native_binder() -> Result<Strong<dyn IKeystoreUserManager>> {
+        let result = BnKeystoreUserManager::new_binder(Self);
+        result.as_binder().set_requesting_sid(true);
+        Ok(result)
+    }
+
+    fn on_user_password_changed(user_id: i32, password: Option<&[u8]>) -> Result<()> {
+        //Check permission. Function should return if this failed. Therefore having '?' at the end
+        //is very important.
+        check_keystore_permission(KeystorePerm::change_password())
+            .context("In on_user_password_changed.")?;
+
+        match DB
+            .with(|db| {
+                UserState::get_with_password_changed(
+                    &mut db.borrow_mut(),
+                    &SUPER_KEY,
+                    user_id as u32,
+                    password,
+                )
+            })
+            .context("In on_user_password_changed.")?
+        {
+            UserState::LskfLocked => {
+                //error - password can not be changed when the device is locked
+                Err(KeystoreError::Rc(ResponseCode::LOCKED))
+                    .context("In on_user_password_changed. Device is locked.")
+            }
+            _ => {
+                //LskfLocked is the only error case for password change
+                Ok(())
+            }
+        }
+    }
+
+    fn add_or_remove_user(user_id: i32) -> Result<()> {
+        // Check permission. Function should return if this failed. Therefore having '?' at the end
+        // is very important.
+        check_keystore_permission(KeystorePerm::change_user()).context("In add_or_remove_user.")?;
+        DB.with(|db| UserState::reset_user(&mut db.borrow_mut(), &SUPER_KEY, user_id as u32, false))
+    }
+}
+
+impl Interface for UserManager {}
+
+impl IKeystoreUserManager for UserManager {
+    fn onUserPasswordChanged(&self, user_id: i32, password: Option<&[u8]>) -> BinderResult<()> {
+        map_or_log_err(Self::on_user_password_changed(user_id, password), Ok)
+    }
+
+    fn onUserAdded(&self, user_id: i32) -> BinderResult<()> {
+        map_or_log_err(Self::add_or_remove_user(user_id), Ok)
+    }
+
+    fn onUserRemoved(&self, user_id: i32) -> BinderResult<()> {
+        map_or_log_err(Self::add_or_remove_user(user_id), Ok)
+    }
+}