diff --git a/keystore2/aidl/Android.bp b/keystore2/aidl/Android.bp
index c297a15..ae3fb18 100644
--- a/keystore2/aidl/Android.bp
+++ b/keystore2/aidl/Android.bp
@@ -22,25 +22,6 @@
 }
 
 aidl_interface {
-    name: "android.security.attestationmanager",
-    srcs: ["android/security/attestationmanager/*.aidl"],
-    imports: ["android.hardware.security.keymint-V3"],
-    unstable: true,
-    backend: {
-        java: {
-            platform_apis: true,
-        },
-        rust: {
-            enabled: true,
-        },
-        ndk: {
-            enabled: true,
-            apps_enabled: false,
-        },
-    },
-}
-
-aidl_interface {
     name: "android.security.authorization",
     srcs: ["android/security/authorization/*.aidl"],
     imports: [
diff --git a/keystore2/aidl/android/security/attestationmanager/ByteArray.aidl b/keystore2/aidl/android/security/attestationmanager/ByteArray.aidl
deleted file mode 100644
index dc37b1b..0000000
--- a/keystore2/aidl/android/security/attestationmanager/ByteArray.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-package android.security.attestationmanager;
-
-/**
- * Simple data holder for a byte array, allowing for multidimensional arrays in AIDL.
- * @hide
- */
-parcelable ByteArray {
-    byte[] data;
-}
\ No newline at end of file
diff --git a/keystore2/aidl/android/security/attestationmanager/IAttestationManager.aidl b/keystore2/aidl/android/security/attestationmanager/IAttestationManager.aidl
deleted file mode 100644
index e77a21e..0000000
--- a/keystore2/aidl/android/security/attestationmanager/IAttestationManager.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-package android.security.attestationmanager;
-
-import android.security.attestationmanager.ByteArray;
-import android.hardware.security.keymint.KeyParameter;
-
-/**
- * Internal interface for performing device attestation.
- * @hide
- */
-interface IAttestationManager {
-    /**
-     * Attest a provided list of device identifiers.
-     *
-     * @return The signed certificate chain, with each individual certificate encoded as a byte
-     *         array.
-     */
-    ByteArray[] attestDevice(
-            in KeyParameter[] deviceIdentifiers, boolean useIndividualAttestation,
-            in byte[] attestationChallenge, int securityLevel);
-}
\ No newline at end of file
diff --git a/keystore2/src/enforcements.rs b/keystore2/src/enforcements.rs
index a5e2d37..d086dd2 100644
--- a/keystore2/src/enforcements.rs
+++ b/keystore2/src/enforcements.rs
@@ -653,16 +653,12 @@
     /// Check if the device is locked for the given user. If there's no entry yet for the user,
     /// we assume that the device is locked
     fn is_device_locked(&self, user_id: i32) -> bool {
-        // unwrap here because there's no way this mutex guard can be poisoned and
-        // because there's no way to recover, even if it is poisoned.
         let set = self.device_unlocked_set.lock().unwrap();
         !set.contains(&user_id)
     }
 
     /// Sets the device locked status for the user. This method is called externally.
     pub fn set_device_locked(&self, user_id: i32, device_locked_status: bool) {
-        // unwrap here because there's no way this mutex guard can be poisoned and
-        // because there's no way to recover, even if it is poisoned.
         let mut set = self.device_unlocked_set.lock().unwrap();
         if device_locked_status {
             set.remove(&user_id);
diff --git a/keystore2/test_utils/authorizations.rs b/keystore2/test_utils/authorizations.rs
index a96d994..d3d6fc4 100644
--- a/keystore2/test_utils/authorizations.rs
+++ b/keystore2/test_utils/authorizations.rs
@@ -18,8 +18,9 @@
 
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
     Algorithm::Algorithm, BlockMode::BlockMode, Digest::Digest, EcCurve::EcCurve,
-    KeyParameter::KeyParameter, KeyParameterValue::KeyParameterValue, KeyPurpose::KeyPurpose,
-    PaddingMode::PaddingMode, Tag::Tag,
+    HardwareAuthenticatorType::HardwareAuthenticatorType, KeyParameter::KeyParameter,
+    KeyParameterValue::KeyParameterValue, KeyPurpose::KeyPurpose, PaddingMode::PaddingMode,
+    Tag::Tag,
 };
 
 /// Helper struct to create set of Authorizations.
@@ -369,6 +370,33 @@
         });
         self
     }
+
+    /// Set user secure ID.
+    pub fn user_secure_id(mut self, sid: i64) -> Self {
+        self.0.push(KeyParameter {
+            tag: Tag::USER_SECURE_ID,
+            value: KeyParameterValue::LongInteger(sid),
+        });
+        self
+    }
+
+    /// Set user auth type.
+    pub fn user_auth_type(mut self, auth_type: HardwareAuthenticatorType) -> Self {
+        self.0.push(KeyParameter {
+            tag: Tag::USER_AUTH_TYPE,
+            value: KeyParameterValue::HardwareAuthenticatorType(auth_type),
+        });
+        self
+    }
+
+    /// Set auth timeout.
+    pub fn auth_timeout(mut self, timeout_secs: i32) -> Self {
+        self.0.push(KeyParameter {
+            tag: Tag::AUTH_TIMEOUT,
+            value: KeyParameterValue::Integer(timeout_secs),
+        });
+        self
+    }
 }
 
 impl Deref for AuthSetBuilder {
diff --git a/keystore2/test_utils/key_generations.rs b/keystore2/test_utils/key_generations.rs
index e63ee60..5e823c2 100644
--- a/keystore2/test_utils/key_generations.rs
+++ b/keystore2/test_utils/key_generations.rs
@@ -392,6 +392,30 @@
     })
 }
 
+/// Check for a specific KeyMint error.
+#[macro_export]
+macro_rules! expect_km_error {
+    { $result:expr, $want:expr } => {
+        match $result {
+            Ok(_) => return Err(format!(
+                "{}:{}: Expected KeyMint error {:?}, found success",
+                file!(),
+                line!(),
+                $want
+            ).into()),
+            Err(s) if s.exception_code() == ExceptionCode::SERVICE_SPECIFIC
+                    && s.service_specific_error() == $want.0 => {}
+            Err(e) => return Err(format!(
+                "{}:{}: Expected KeyMint service-specific error {:?}, got {e:?}",
+                file!(),
+                line!(),
+                $want
+            ).into()),
+        }
+
+    };
+}
+
 /// Get the value of the given system property, if the given system property doesn't exist
 /// then returns an empty byte vector.
 pub fn get_system_prop(name: &str) -> Vec<u8> {
diff --git a/keystore2/test_utils/run_as.rs b/keystore2/test_utils/run_as.rs
index 2cd9fec..14a72be 100644
--- a/keystore2/test_utils/run_as.rs
+++ b/keystore2/test_utils/run_as.rs
@@ -32,12 +32,104 @@
     fork, pipe as nix_pipe, read as nix_read, setgid, setuid, write as nix_write, ForkResult, Gid,
     Pid, Uid,
 };
-use serde::{de::DeserializeOwned, Serialize};
+use serde::{de::DeserializeOwned, Deserialize, Serialize};
 use std::io::{Read, Write};
 use std::marker::PhantomData;
 use std::os::fd::AsRawFd;
 use std::os::fd::OwnedFd;
 
+/// Newtype string error, which can be serialized and transferred out from a sub-process.
+#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
+pub struct Error(pub String);
+
+/// Allow ergonomic use of [`anyhow::Error`].
+impl From<anyhow::Error> for Error {
+    fn from(err: anyhow::Error) -> Self {
+        // Use the debug format of [`anyhow::Error`] to include backtrace.
+        Self(format!("{:?}", err))
+    }
+}
+impl From<String> for Error {
+    fn from(val: String) -> Self {
+        Self(val)
+    }
+}
+impl From<&str> for Error {
+    fn from(val: &str) -> Self {
+        Self(val.to_string())
+    }
+}
+
+impl std::fmt::Display for Error {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.0)
+    }
+}
+
+impl std::error::Error for Error {}
+
+/// Equivalent to the [`assert!`] macro which returns an [`Error`] rather than emitting a panic.
+/// This is useful for test code that is `run_as`, so failures are more accessible.
+#[macro_export]
+macro_rules! expect {
+    ($cond:expr $(,)?) => {{
+        let result = $cond;
+        if !result {
+            return Err($crate::run_as::Error(format!(
+                "{}:{}: check '{}' failed",
+                file!(),
+                line!(),
+                stringify!($cond)
+            )));
+        }
+    }};
+    ($cond:expr, $($arg:tt)+) => {{
+        let result = $cond;
+        if !result {
+            return Err($crate::run_as::Error(format!(
+                "{}:{}: check '{}' failed: {}",
+                file!(),
+                line!(),
+                stringify!($cond),
+                format_args!($($arg)+)
+            )));
+        }
+    }};
+}
+
+/// Equivalent to the [`assert_eq!`] macro which returns an [`Error`] rather than emitting a panic.
+/// This is useful for test code that is `run_as`, so failures are more accessible.
+#[macro_export]
+macro_rules! expect_eq {
+    ($left:expr, $right:expr $(,)?) => {{
+        let left = $left;
+        let right = $right;
+        if left != right {
+            return Err($crate::run_as::Error(format!(
+                "{}:{}: assertion {} == {} failed\n  left: {left:?}\n right: {right:?}\n",
+                file!(),
+                line!(),
+                stringify!($left),
+                stringify!($right),
+            )));
+        }
+    }};
+    ($left:expr, $right:expr, $($arg:tt)+) => {{
+        let left = $left;
+        let right = $right;
+        if left != right {
+            return Err($crate::run_as::Error(format!(
+                "{}:{}: assertion {} == {} failed: {}\n  left: {left:?}\n right: {right:?}\n",
+                file!(),
+                line!(),
+                stringify!($left),
+                stringify!($right),
+                format_args!($($arg)+)
+            )));
+        }
+    }};
+}
+
 fn transition(se_context: selinux::Context, uid: Uid, gid: Gid) {
     setgid(gid).expect("Failed to set GID. This test might need more privileges.");
     setuid(uid).expect("Failed to set UID. This test might need more privileges.");
@@ -119,31 +211,48 @@
     /// Receiving blocks until an object of type T has been read from the channel.
     /// Panics if an error occurs during io or deserialization.
     pub fn recv(&mut self) -> T {
+        match self.recv_err() {
+            Ok(val) => val,
+            Err(e) => panic!("{e}"),
+        }
+    }
+
+    /// Receives a serializable object from the corresponding ChannelWriter.
+    /// Receiving blocks until an object of type T has been read from the channel.
+    pub fn recv_err(&mut self) -> Result<T, Error> {
         let mut size_buffer = [0u8; std::mem::size_of::<usize>()];
         match self.0.read(&mut size_buffer).expect("In ChannelReader::recv: Failed to read size.") {
             r if r != size_buffer.len() => {
-                panic!("In ChannelReader::recv: Failed to read size. Insufficient data: {}", r);
+                return Err(format!(
+                    "In ChannelReader::recv: Failed to read size. Insufficient data: {}",
+                    r
+                )
+                .into());
             }
             _ => {}
         };
         let size = usize::from_be_bytes(size_buffer);
         let mut data_buffer = vec![0u8; size];
-        match self
-            .0
-            .read(&mut data_buffer)
-            .expect("In ChannelReader::recv: Failed to read serialized data.")
-        {
-            r if r != data_buffer.len() => {
-                panic!(
+        match self.0.read(&mut data_buffer) {
+            Ok(r) if r != data_buffer.len() => {
+                return Err(format!(
                     "In ChannelReader::recv: Failed to read serialized data. Insufficient data: {}",
                     r
-                );
+                )
+                .into());
             }
-            _ => {}
+            Ok(_) => {}
+            Err(e) => {
+                return Err(format!(
+                    "In ChannelReader::recv: Failed to read serialized data: {e:?}"
+                )
+                .into())
+            }
         };
 
-        serde_cbor::from_slice(&data_buffer)
-            .expect("In ChannelReader::recv: Failed to deserialize data.")
+        serde_cbor::from_slice(&data_buffer).map_err(|e| {
+            format!("In ChannelReader::recv: Failed to deserialize data: {e:?}").into()
+        })
     }
 }
 
@@ -186,6 +295,11 @@
     /// Get child result. Panics if the child did not exit with status 0 or if a serialization
     /// error occurred.
     pub fn get_result(mut self) -> R {
+        self.get_death_result()
+    }
+
+    /// Get child result via a mutable reference.
+    fn get_death_result(&mut self) -> R {
         let status =
             waitpid(self.pid, None).expect("ChildHandle::wait: Failed while waiting for child.");
         match status {
@@ -205,6 +319,31 @@
     }
 }
 
+impl<R, M> ChildHandle<Result<R, Error>, M>
+where
+    R: Serialize + DeserializeOwned,
+    M: Serialize + DeserializeOwned,
+{
+    /// Receive a response from the child.  If the child has closed the response
+    /// channel, assume it has terminated and read the final result.
+    /// Panics on child failure, but will display the child error value.
+    pub fn recv_or_die(&mut self) -> M {
+        match self.response_reader.recv_err() {
+            Ok(v) => v,
+            Err(_e) => {
+                // We have failed to read from the `response_reader` channel.
+                // Assume this is because the child completed early with an error.
+                match self.get_death_result() {
+                    Ok(_) => {
+                        panic!("Child completed OK despite failure to read a response!")
+                    }
+                    Err(e) => panic!("Child failed with:\n{e}"),
+                }
+            }
+        }
+    }
+}
+
 impl<R: Serialize + DeserializeOwned, M: Serialize + DeserializeOwned> Drop for ChildHandle<R, M> {
     fn drop(&mut self) {
         if self.exit_status.is_none() {
diff --git a/keystore2/tests/Android.bp b/keystore2/tests/Android.bp
index dbef46c..0406a71 100644
--- a/keystore2/tests/Android.bp
+++ b/keystore2/tests/Android.bp
@@ -42,12 +42,14 @@
     test_config: "AndroidTest.xml",
 
     rustlibs: [
+        "android.hardware.gatekeeper-V1-rust",
         "android.hardware.security.secureclock-V1-rust",
         "android.security.authorization-rust",
         "android.security.maintenance-rust",
         "libaconfig_android_hardware_biometrics_rust",
         "libandroid_logger",
         "libandroid_security_flags_rust",
+        "libanyhow",
         "libbinder_rs",
         "libkeystore2_test_utils",
         "liblog_rust",
diff --git a/keystore2/tests/keystore2_client_test_utils.rs b/keystore2/tests/keystore2_client_test_utils.rs
index f028a65..9029b97 100644
--- a/keystore2/tests/keystore2_client_test_utils.rs
+++ b/keystore2/tests/keystore2_client_test_utils.rs
@@ -51,10 +51,21 @@
     OtherErr,
 }
 
-/// This is used to notify the child or parent process that the expected state is reched.
+/// This is used to notify the child or parent process that the expected state is reached.
 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
 pub struct BarrierReached;
 
+/// This is used to notify the child or parent process that the expected state is reached,
+/// passing a value
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
+pub struct BarrierReachedWithData<T: Send + Sync>(pub T);
+
+impl<T: Send + Sync> BarrierReachedWithData<T> {
+    pub fn new(val: T) -> Self {
+        Self(val)
+    }
+}
+
 /// Forced operation.
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub struct ForcedOp(pub bool);
diff --git a/keystore2/tests/user_auth.rs b/keystore2/tests/user_auth.rs
index 4e3c692..336af4f 100644
--- a/keystore2/tests/user_auth.rs
+++ b/keystore2/tests/user_auth.rs
@@ -14,7 +14,7 @@
 
 //! Tests for user authentication interactions (via `IKeystoreAuthorization`).
 
-use crate::keystore2_client_test_utils::BarrierReached;
+use crate::keystore2_client_test_utils::{BarrierReached, BarrierReachedWithData};
 use android_security_authorization::aidl::android::security::authorization::{
     IKeystoreAuthorization::IKeystoreAuthorization
 };
@@ -22,39 +22,52 @@
      IKeystoreMaintenance,
 };
 use android_hardware_security_keymint::aidl::android::hardware::security::keymint::{
-    Algorithm::Algorithm, Digest::Digest, EcCurve::EcCurve, HardwareAuthToken::HardwareAuthToken,
-    HardwareAuthenticatorType::HardwareAuthenticatorType, SecurityLevel::SecurityLevel,
-    KeyPurpose::KeyPurpose
+    Algorithm::Algorithm, Digest::Digest, EcCurve::EcCurve, ErrorCode::ErrorCode,
+    HardwareAuthToken::HardwareAuthToken, HardwareAuthenticatorType::HardwareAuthenticatorType,
+    KeyPurpose::KeyPurpose, SecurityLevel::SecurityLevel,
+};
+use android_hardware_gatekeeper::aidl::android::hardware::gatekeeper::{
+    IGatekeeper::IGatekeeper, IGatekeeper::ERROR_RETRY_TIMEOUT,
 };
 use android_system_keystore2::aidl::android::system::keystore2::{
     CreateOperationResponse::CreateOperationResponse, Domain::Domain, KeyDescriptor::KeyDescriptor,
     KeyMetadata::KeyMetadata,
 };
+use android_system_keystore2::binder::{ExceptionCode, Result as BinderResult};
 use android_hardware_security_secureclock::aidl::android::hardware::security::secureclock::{
     Timestamp::Timestamp,
 };
+use anyhow::Context;
 use keystore2_test_utils::{
-    get_keystore_service, run_as, authorizations::AuthSetBuilder,
+    authorizations::AuthSetBuilder, expect, get_keystore_service, run_as,
+    run_as::{ChannelReader, ChannelWriter}, expect_km_error,
 };
 use log::{warn, info};
 use nix::unistd::{Gid, Uid};
 use rustutils::users::AID_USER_OFFSET;
+use std::{time::Duration, thread::sleep};
 
+/// SELinux context.
+const CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
 /// Test user ID.
 const TEST_USER_ID: i32 = 100;
-/// Fake password blob.
-static PASSWORD: &[u8] = &[
+/// Corresponding uid value.
+const UID: u32 = TEST_USER_ID as u32 * AID_USER_OFFSET + 1001;
+/// Fake synthetic password blob.
+static SYNTHETIC_PASSWORD: &[u8] = &[
     0x42, 0x39, 0x30, 0x37, 0x44, 0x37, 0x32, 0x37, 0x39, 0x39, 0x43, 0x42, 0x39, 0x41, 0x42, 0x30,
     0x34, 0x31, 0x30, 0x38, 0x46, 0x44, 0x33, 0x45, 0x39, 0x42, 0x32, 0x38, 0x36, 0x35, 0x41, 0x36,
     0x33, 0x44, 0x42, 0x42, 0x43, 0x36, 0x33, 0x42, 0x34, 0x39, 0x37, 0x33, 0x35, 0x45, 0x41, 0x41,
     0x32, 0x45, 0x31, 0x35, 0x43, 0x43, 0x46, 0x32, 0x39, 0x36, 0x33, 0x34, 0x31, 0x32, 0x41, 0x39,
 ];
+/// Gatekeeper password.
+static GK_PASSWORD: &[u8] = b"correcthorsebatterystaple";
 /// Fake SID value corresponding to Gatekeeper.
-static GK_SID: i64 = 123456;
+static GK_FAKE_SID: i64 = 123456;
 /// Fake SID value corresponding to a biometric authenticator.
-static BIO_SID1: i64 = 345678;
+static BIO_FAKE_SID1: i64 = 345678;
 /// Fake SID value corresponding to a biometric authenticator.
-static BIO_SID2: i64 = 456789;
+static BIO_FAKE_SID2: i64 = 456789;
 
 const WEAK_UNLOCK_ENABLED: bool = true;
 const WEAK_UNLOCK_DISABLED: bool = false;
@@ -68,6 +81,18 @@
     binder::get_interface("android.security.maintenance").unwrap()
 }
 
+/// Get the default Gatekeeper instance. This may fail on older devices where Gatekeeper is still a
+/// HIDL interface rather than AIDL.
+fn get_gatekeeper() -> Option<binder::Strong<dyn IGatekeeper>> {
+    binder::get_interface("android.hardware.gatekeeper.IGatekeeper/default").ok()
+}
+
+/// Indicate whether a Gatekeeper result indicates a delayed-retry is needed.
+fn is_gk_retry<T: std::fmt::Debug>(result: &BinderResult<T>) -> bool {
+    matches!(result, Err(s) if s.exception_code() == ExceptionCode::SERVICE_SPECIFIC
+                 && s.service_specific_error() == ERROR_RETRY_TIMEOUT)
+}
+
 fn abort_op(result: binder::Result<CreateOperationResponse>) {
     if let Ok(rsp) = result {
         if let Some(op) = rsp.iOperation {
@@ -86,117 +111,684 @@
 struct TestUser {
     id: i32,
     maint: binder::Strong<dyn IKeystoreMaintenance>,
+    gk: Option<binder::Strong<dyn IGatekeeper>>,
+    gk_sid: Option<i64>,
+    gk_handle: Vec<u8>,
 }
 
 impl TestUser {
     fn new() -> Self {
-        Self::new_user(TEST_USER_ID, PASSWORD)
+        Self::new_user(TEST_USER_ID, SYNTHETIC_PASSWORD)
     }
-    fn new_user(user_id: i32, password: &[u8]) -> Self {
+    fn new_user(user_id: i32, sp: &[u8]) -> Self {
         let maint = get_maintenance();
         maint.onUserAdded(user_id).expect("failed to add test user");
         maint
-            .initUserSuperKeys(user_id, password, /* allowExisting= */ false)
+            .initUserSuperKeys(user_id, sp, /* allowExisting= */ false)
             .expect("failed to init test user");
-        Self { id: user_id, maint }
+        let gk = get_gatekeeper();
+        let (gk_sid, gk_handle) = if let Some(gk) = &gk {
+            // AIDL Gatekeeper is available, so enroll a password.
+            loop {
+                let result = gk.enroll(user_id, &[], &[], GK_PASSWORD);
+                if is_gk_retry(&result) {
+                    sleep(Duration::from_secs(1));
+                    continue;
+                }
+                let rsp = result.expect("gk.enroll() failed");
+                info!("registered test user {user_id} as sid {} with GK", rsp.secureUserId);
+                break (Some(rsp.secureUserId), rsp.data);
+            }
+        } else {
+            (None, vec![])
+        };
+        Self { id: user_id, maint, gk, gk_sid, gk_handle }
+    }
+
+    /// Perform Gatekeeper verification, which will return a HAT on success.
+    fn gk_verify(&self, challenge: i64) -> Option<HardwareAuthToken> {
+        let Some(gk) = &self.gk else { return None };
+        loop {
+            let result = gk.verify(self.id, challenge, &self.gk_handle, GK_PASSWORD);
+            if is_gk_retry(&result) {
+                sleep(Duration::from_secs(1));
+                continue;
+            }
+            let rsp = result.expect("gk.verify failed");
+            break Some(rsp.hardwareAuthToken);
+        }
     }
 }
 
 impl Drop for TestUser {
     fn drop(&mut self) {
         let _ = self.maint.onUserRemoved(self.id);
+        if let Some(gk) = &self.gk {
+            info!("deregister test user {} with GK", self.id);
+            if let Err(e) = gk.deleteUser(self.id) {
+                warn!("failed to deregister test user {}: {e:?}", self.id);
+            }
+        }
     }
 }
 
 #[test]
-fn keystore2_test_unlocked_device_required() {
+fn test_auth_bound_timeout_with_gk() {
+    type Barrier = BarrierReachedWithData<Option<i64>>;
     android_logger::init_once(
         android_logger::Config::default()
             .with_tag("keystore2_client_tests")
             .with_max_level(log::LevelFilter::Debug),
     );
-    static CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
-    const UID: u32 = TEST_USER_ID as u32 * AID_USER_OFFSET + 1001;
 
-    // Safety: only one thread at this point, and nothing yet done with binder.
+    let child_fn = move |reader: &mut ChannelReader<Barrier>,
+                         writer: &mut ChannelWriter<Barrier>|
+          -> Result<(), run_as::Error> {
+        // Now we're in a new process, wait to be notified before starting.
+        let gk_sid: i64 = match reader.recv().0 {
+            Some(sid) => sid,
+            None => {
+                // There is no AIDL Gatekeeper available, so abandon the test.  It would be nice to
+                // know this before starting the child process, but finding it out requires Binder,
+                // which can't be used until after the child has forked.
+                return Ok(());
+            }
+        };
+
+        // Action A: create a new auth-bound key which requires auth in the last 3 seconds,
+        // and fail to start an operation using it.
+        let ks2 = get_keystore_service();
+        let sec_level =
+            ks2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).context("no TEE")?;
+        let params = AuthSetBuilder::new()
+            .user_secure_id(gk_sid)
+            .user_secure_id(BIO_FAKE_SID1)
+            .user_secure_id(BIO_FAKE_SID2)
+            .user_auth_type(HardwareAuthenticatorType::ANY)
+            .auth_timeout(3)
+            .algorithm(Algorithm::EC)
+            .purpose(KeyPurpose::SIGN)
+            .purpose(KeyPurpose::VERIFY)
+            .digest(Digest::SHA_2_256)
+            .ec_curve(EcCurve::P_256);
+
+        let KeyMetadata { key, .. } = sec_level
+            .generateKey(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some("auth-bound-timeout".to_string()),
+                    blob: None,
+                },
+                None,
+                &params,
+                0,
+                b"entropy",
+            )
+            .context("key generation failed")?;
+        info!("A: created auth-timeout key {key:?}");
+
+        // No HATs so cannot create an operation using the key.
+        let params = AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256);
+        let result = sec_level.createOperation(&key, &params, UNFORCED);
+        expect_km_error!(&result, ErrorCode::KEY_USER_NOT_AUTHENTICATED);
+        info!("A: failed auth-bound operation (no HAT) as expected {result:?}");
+
+        writer.send(&Barrier::new(None)); // A done.
+
+        // Action B: succeed when a valid HAT is available.
+        reader.recv();
+
+        let result = sec_level.createOperation(&key, &params, UNFORCED);
+        expect!(result.is_ok());
+        let op = result.unwrap().iOperation.context("no operation in result")?;
+        let result = op.finish(Some(b"data"), None);
+        expect!(result.is_ok());
+        info!("B: performed auth-bound operation (with valid GK HAT) as expected");
+
+        writer.send(&Barrier::new(None)); // B done.
+
+        // Action C: fail again when the HAT is old enough to not even be checked.
+        reader.recv();
+        info!("C: wait so that any HAT times out");
+        sleep(Duration::from_secs(4));
+        let result = sec_level.createOperation(&key, &params, UNFORCED);
+        info!("C: failed auth-bound operation (HAT is too old) as expected {result:?}");
+        writer.send(&Barrier::new(None)); // C done.
+
+        Ok(())
+    };
+
+    // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+    // `--test-threads=1`), and nothing yet done with binder.
     let mut child_handle = unsafe {
         // Perform keystore actions while running as the test user.
-        run_as::run_as_child(
-            CTX,
-            Uid::from_raw(UID),
-            Gid::from_raw(UID),
-            move |reader, writer| -> Result<(), String> {
-                // Action A: create a new unlocked-device-required key (which thus requires
-                // super-encryption), while the device is unlocked.
-                let ks2 = get_keystore_service();
-                if ks2.getInterfaceVersion().unwrap() < 4 {
-                    // Assuming `IKeystoreAuthorization::onDeviceLocked` and
-                    // `IKeystoreAuthorization::onDeviceUnlocked` APIs will be supported on devices
-                    // with `IKeystoreService` >= 4.
-                    return Ok(());
-                }
+        run_as::run_as_child(CTX, Uid::from_raw(UID), Gid::from_raw(UID), child_fn)
+    }
+    .unwrap();
 
-                // Now we're in a new process, wait to be notified before starting.
-                reader.recv();
+    // Now that the separate process has been forked off, it's safe to use binder to setup a test
+    // user.
+    let _ks2 = get_keystore_service();
+    let user = TestUser::new();
+    if user.gk.is_none() {
+        // Can't run this test if there's no AIDL Gatekeeper.
+        child_handle.send(&Barrier::new(None));
+        assert_eq!(child_handle.get_result(), Ok(()), "child process failed");
+        return;
+    }
+    let user_id = user.id;
+    let auth_service = get_authorization();
 
-                let sec_level = ks2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).unwrap();
-                let params = AuthSetBuilder::new()
-                    .no_auth_required()
-                    .unlocked_device_required()
-                    .algorithm(Algorithm::EC)
-                    .purpose(KeyPurpose::SIGN)
-                    .purpose(KeyPurpose::VERIFY)
-                    .digest(Digest::SHA_2_256)
-                    .ec_curve(EcCurve::P_256);
+    // Lock and unlock to ensure super keys are already created.
+    auth_service
+        .onDeviceLocked(user_id, &[BIO_FAKE_SID1, BIO_FAKE_SID2], WEAK_UNLOCK_DISABLED)
+        .unwrap();
+    auth_service.onDeviceUnlocked(user_id, Some(SYNTHETIC_PASSWORD)).unwrap();
 
-                let KeyMetadata { key, .. } = sec_level
-                    .generateKey(
-                        &KeyDescriptor {
-                            domain: Domain::APP,
-                            nspace: -1,
-                            alias: Some("unlocked-device-required".to_string()),
-                            blob: None,
-                        },
-                        None,
-                        &params,
-                        0,
-                        b"entropy",
-                    )
-                    .expect("key generation failed");
-                info!("A: created unlocked-device-required key while unlocked {key:?}");
-                writer.send(&BarrierReached {}); // A done.
+    info!("trigger child process action A and wait for completion");
+    child_handle.send(&Barrier::new(Some(user.gk_sid.unwrap())));
+    child_handle.recv_or_die();
 
-                // Action B: fail to use the unlocked-device-required key while locked.
-                reader.recv();
-                let params =
-                    AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256);
-                let result = sec_level.createOperation(&key, &params, UNFORCED);
-                info!("B: use unlocked-device-required key while locked => {result:?}");
-                assert!(result.is_err());
-                writer.send(&BarrierReached {}); // B done.
+    // Unlock with GK password to get a genuine auth token.
+    let real_hat = user.gk_verify(0).expect("failed to perform GK verify");
+    auth_service.addAuthToken(&real_hat).unwrap();
 
-                // Action C: try to use the unlocked-device-required key while unlocked with a
-                // password.
-                reader.recv();
-                let result = sec_level.createOperation(&key, &params, UNFORCED);
-                info!("C: use unlocked-device-required key while lskf-unlocked => {result:?}");
-                assert!(result.is_ok(), "failed with {result:?}");
-                abort_op(result);
-                writer.send(&BarrierReached {}); // C done.
+    info!("trigger child process action B and wait for completion");
+    child_handle.send(&Barrier::new(None));
+    child_handle.recv_or_die();
 
-                // Action D: try to use the unlocked-device-required key while unlocked with a weak
-                // biometric.
-                reader.recv();
-                let result = sec_level.createOperation(&key, &params, UNFORCED);
-                info!("D: use unlocked-device-required key while weak-locked => {result:?}");
-                assert!(result.is_ok(), "createOperation failed: {result:?}");
-                abort_op(result);
-                writer.send(&BarrierReached {}); // D done.
+    info!("trigger child process action C and wait for completion");
+    child_handle.send(&Barrier::new(None));
+    child_handle.recv_or_die();
 
-                let _ = sec_level.deleteKey(&key);
-                Ok(())
-            },
-        )
+    assert_eq!(child_handle.get_result(), Ok(()), "child process failed");
+}
+
+#[test]
+fn test_auth_bound_timeout_failure() {
+    android_logger::init_once(
+        android_logger::Config::default()
+            .with_tag("keystore2_client_tests")
+            .with_max_level(log::LevelFilter::Debug),
+    );
+
+    let child_fn = move |reader: &mut ChannelReader<BarrierReached>,
+                         writer: &mut ChannelWriter<BarrierReached>|
+          -> Result<(), run_as::Error> {
+        // Now we're in a new process, wait to be notified before starting.
+        reader.recv();
+
+        // Action A: create a new auth-bound key which requires auth in the last 3 seconds,
+        // and fail to start an operation using it.
+        let ks2 = get_keystore_service();
+
+        let sec_level =
+            ks2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).context("no TEE")?;
+        let params = AuthSetBuilder::new()
+            .user_secure_id(BIO_FAKE_SID1)
+            .user_secure_id(BIO_FAKE_SID2)
+            .user_auth_type(HardwareAuthenticatorType::ANY)
+            .auth_timeout(3)
+            .algorithm(Algorithm::EC)
+            .purpose(KeyPurpose::SIGN)
+            .purpose(KeyPurpose::VERIFY)
+            .digest(Digest::SHA_2_256)
+            .ec_curve(EcCurve::P_256);
+
+        let KeyMetadata { key, .. } = sec_level
+            .generateKey(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some("auth-bound-timeout".to_string()),
+                    blob: None,
+                },
+                None,
+                &params,
+                0,
+                b"entropy",
+            )
+            .context("key generation failed")?;
+        info!("A: created auth-timeout key {key:?}");
+
+        // No HATs so cannot create an operation using the key.
+        let params = AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256);
+        let result = sec_level.createOperation(&key, &params, UNFORCED);
+        expect_km_error!(&result, ErrorCode::KEY_USER_NOT_AUTHENTICATED);
+        info!("A: failed auth-bound operation (no HAT) as expected {result:?}");
+
+        writer.send(&BarrierReached {}); // A done.
+
+        // Action B: fail again when an invalid HAT is available.
+        reader.recv();
+
+        let result = sec_level.createOperation(&key, &params, UNFORCED);
+        expect_km_error!(&result, ErrorCode::KEY_USER_NOT_AUTHENTICATED);
+        info!("B: failed auth-bound operation (HAT is invalid) as expected {result:?}");
+
+        writer.send(&BarrierReached {}); // B done.
+
+        // Action C: fail again when the HAT is old enough to not even be checked.
+        reader.recv();
+        info!("C: wait so that any HAT times out");
+        sleep(Duration::from_secs(4));
+        let result = sec_level.createOperation(&key, &params, UNFORCED);
+        expect_km_error!(&result, ErrorCode::KEY_USER_NOT_AUTHENTICATED);
+        info!("C: failed auth-bound operation (HAT is too old) as expected {result:?}");
+        writer.send(&BarrierReached {}); // C done.
+
+        Ok(())
+    };
+
+    // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+    // `--test-threads=1`), and nothing yet done with binder.
+    let mut child_handle = unsafe {
+        // Perform keystore actions while running as the test user.
+        run_as::run_as_child(CTX, Uid::from_raw(UID), Gid::from_raw(UID), child_fn)
+    }
+    .unwrap();
+
+    // Now that the separate process has been forked off, it's safe to use binder to setup a test
+    // user.
+    let _ks2 = get_keystore_service();
+    let user = TestUser::new();
+    let user_id = user.id;
+    let auth_service = get_authorization();
+
+    // Lock and unlock to ensure super keys are already created.
+    auth_service
+        .onDeviceLocked(user_id, &[BIO_FAKE_SID1, BIO_FAKE_SID2], WEAK_UNLOCK_DISABLED)
+        .unwrap();
+    auth_service.onDeviceUnlocked(user_id, Some(SYNTHETIC_PASSWORD)).unwrap();
+    auth_service.addAuthToken(&fake_lskf_token(GK_FAKE_SID)).unwrap();
+
+    info!("trigger child process action A and wait for completion");
+    child_handle.send(&BarrierReached {});
+    child_handle.recv_or_die();
+
+    // Unlock with password and a fake auth token that matches the key
+    auth_service.onDeviceUnlocked(user_id, Some(SYNTHETIC_PASSWORD)).unwrap();
+    auth_service.addAuthToken(&fake_bio_lskf_token(GK_FAKE_SID, BIO_FAKE_SID1)).unwrap();
+
+    info!("trigger child process action B and wait for completion");
+    child_handle.send(&BarrierReached {});
+    child_handle.recv_or_die();
+
+    info!("trigger child process action C and wait for completion");
+    child_handle.send(&BarrierReached {});
+    child_handle.recv_or_die();
+
+    assert_eq!(child_handle.get_result(), Ok(()), "child process failed");
+}
+
+#[test]
+fn test_auth_bound_per_op_with_gk() {
+    type Barrier = BarrierReachedWithData<Option<i64>>;
+    android_logger::init_once(
+        android_logger::Config::default()
+            .with_tag("keystore2_client_tests")
+            .with_max_level(log::LevelFilter::Debug),
+    );
+
+    let child_fn = move |reader: &mut ChannelReader<Barrier>,
+                         writer: &mut ChannelWriter<Barrier>|
+          -> Result<(), run_as::Error> {
+        // Now we're in a new process, wait to be notified before starting.
+        let gk_sid: i64 = match reader.recv().0 {
+            Some(sid) => sid,
+            None => {
+                // There is no AIDL Gatekeeper available, so abandon the test.  It would be nice to
+                // know this before starting the child process, but finding it out requires Binder,
+                // which can't be used until after the child has forked.
+                return Ok(());
+            }
+        };
+
+        // Action A: create a new auth-bound key which requires auth-per-operation (because
+        // AUTH_TIMEOUT is not specified), and fail to finish an operation using it.
+        let ks2 = get_keystore_service();
+        let sec_level =
+            ks2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).context("no TEE")?;
+        let params = AuthSetBuilder::new()
+            .user_secure_id(gk_sid)
+            .user_secure_id(BIO_FAKE_SID1)
+            .user_auth_type(HardwareAuthenticatorType::ANY)
+            .algorithm(Algorithm::EC)
+            .purpose(KeyPurpose::SIGN)
+            .purpose(KeyPurpose::VERIFY)
+            .digest(Digest::SHA_2_256)
+            .ec_curve(EcCurve::P_256);
+
+        let KeyMetadata { key, .. } = sec_level
+            .generateKey(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some("auth-per-op".to_string()),
+                    blob: None,
+                },
+                None,
+                &params,
+                0,
+                b"entropy",
+            )
+            .context("key generation failed")?;
+        info!("A: created auth-per-op key {key:?}");
+
+        // We can create an operation using the key...
+        let params = AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256);
+        let result = sec_level
+            .createOperation(&key, &params, UNFORCED)
+            .expect("failed to create auth-per-op operation");
+        let op = result.iOperation.context("no operation in result")?;
+        info!("A: created auth-per-op operation, got challenge {:?}", result.operationChallenge);
+
+        // .. but attempting to finish the operation fails because Keystore can't find a HAT.
+        let result = op.finish(Some(b"data"), None);
+        expect_km_error!(&result, ErrorCode::KEY_USER_NOT_AUTHENTICATED);
+        info!("A: failed auth-per-op op (no HAT) as expected {result:?}");
+
+        writer.send(&Barrier::new(None)); // A done.
+
+        // Action B: start an operation and pass out the challenge
+        reader.recv();
+        let result = sec_level
+            .createOperation(&key, &params, UNFORCED)
+            .expect("failed to create auth-per-op operation");
+        let op = result.iOperation.context("no operation in result")?;
+        info!("B: created auth-per-op operation, got challenge {:?}", result.operationChallenge);
+        writer.send(&Barrier::new(Some(result.operationChallenge.unwrap().challenge))); // B done.
+
+        // Action C: finishing the operation succeeds now there's a per-op HAT.
+        reader.recv();
+        let result = op.finish(Some(b"data"), None);
+        expect!(result.is_ok());
+        info!("C: performed auth-per-op op expected");
+        writer.send(&Barrier::new(None)); // D done.
+
+        Ok(())
+    };
+
+    // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+    // `--test-threads=1`), and nothing yet done with binder.
+    let mut child_handle = unsafe {
+        // Perform keystore actions while running as the test user.
+        run_as::run_as_child(CTX, Uid::from_raw(UID), Gid::from_raw(UID), child_fn)
+    }
+    .unwrap();
+
+    // Now that the separate process has been forked off, it's safe to use binder to setup a test
+    // user.
+    let _ks2 = get_keystore_service();
+    let user = TestUser::new();
+    if user.gk.is_none() {
+        // Can't run this test if there's no AIDL Gatekeeper.
+        child_handle.send(&Barrier::new(None));
+        assert_eq!(child_handle.get_result(), Ok(()), "child process failed");
+        return;
+    }
+    let user_id = user.id;
+    let auth_service = get_authorization();
+
+    // Lock and unlock to ensure super keys are already created.
+    auth_service
+        .onDeviceLocked(user_id, &[BIO_FAKE_SID1, BIO_FAKE_SID2], WEAK_UNLOCK_DISABLED)
+        .unwrap();
+    auth_service.onDeviceUnlocked(user_id, Some(SYNTHETIC_PASSWORD)).unwrap();
+
+    info!("trigger child process action A and wait for completion");
+    child_handle.send(&Barrier::new(Some(user.gk_sid.unwrap())));
+    child_handle.recv_or_die();
+
+    info!("trigger child process action B and wait for completion");
+    child_handle.send(&Barrier::new(None));
+    let challenge = child_handle.recv_or_die().0.expect("no challenge");
+
+    // Unlock with GK and the challenge to get a genuine per-op auth token
+    let real_hat = user.gk_verify(challenge).expect("failed to perform GK verify");
+    auth_service.addAuthToken(&real_hat).unwrap();
+
+    info!("trigger child process action C and wait for completion");
+    child_handle.send(&Barrier::new(None));
+    child_handle.recv_or_die();
+
+    assert_eq!(child_handle.get_result(), Ok(()), "child process failed");
+}
+
+#[test]
+fn test_auth_bound_per_op_failure() {
+    type Barrier = BarrierReachedWithData<i64>;
+    android_logger::init_once(
+        android_logger::Config::default()
+            .with_tag("keystore2_client_tests")
+            .with_max_level(log::LevelFilter::Debug),
+    );
+
+    let child_fn = move |reader: &mut ChannelReader<Barrier>,
+                         writer: &mut ChannelWriter<Barrier>|
+          -> Result<(), run_as::Error> {
+        // Now we're in a new process, wait to be notified before starting.
+        reader.recv();
+
+        // Action A: create a new auth-bound key which requires auth-per-operation (because
+        // AUTH_TIMEOUT is not specified), and fail to finish an operation using it.
+        let ks2 = get_keystore_service();
+
+        let sec_level =
+            ks2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).context("no TEE")?;
+        let params = AuthSetBuilder::new()
+            .user_secure_id(GK_FAKE_SID)
+            .user_secure_id(BIO_FAKE_SID1)
+            .user_auth_type(HardwareAuthenticatorType::ANY)
+            .algorithm(Algorithm::EC)
+            .purpose(KeyPurpose::SIGN)
+            .purpose(KeyPurpose::VERIFY)
+            .digest(Digest::SHA_2_256)
+            .ec_curve(EcCurve::P_256);
+
+        let KeyMetadata { key, .. } = sec_level
+            .generateKey(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some("auth-per-op".to_string()),
+                    blob: None,
+                },
+                None,
+                &params,
+                0,
+                b"entropy",
+            )
+            .context("key generation failed")?;
+        info!("A: created auth-per-op key {key:?}");
+
+        // We can create an operation using the key...
+        let params = AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256);
+        let result = sec_level
+            .createOperation(&key, &params, UNFORCED)
+            .expect("failed to create auth-per-op operation");
+        let op = result.iOperation.context("no operation in result")?;
+        info!("A: created auth-per-op operation, got challenge {:?}", result.operationChallenge);
+
+        // .. but attempting to finish the operation fails because Keystore can't find a HAT.
+        let result = op.finish(Some(b"data"), None);
+        expect_km_error!(&result, ErrorCode::KEY_USER_NOT_AUTHENTICATED);
+        info!("A: failed auth-per-op op (no HAT) as expected {result:?}");
+
+        writer.send(&Barrier::new(0)); // A done.
+
+        // Action B: fail again when an irrelevant HAT is available.
+        reader.recv();
+
+        let result = sec_level
+            .createOperation(&key, &params, UNFORCED)
+            .expect("failed to create auth-per-op operation");
+        let op = result.iOperation.context("no operation in result")?;
+        info!("B: created auth-per-op operation, got challenge {:?}", result.operationChallenge);
+        // The operation fails because the HAT that Keystore received is not related to the
+        // challenge.
+        let result = op.finish(Some(b"data"), None);
+        expect_km_error!(&result, ErrorCode::KEY_USER_NOT_AUTHENTICATED);
+        info!("B: failed auth-per-op op (HAT is not per-op) as expected {result:?}");
+
+        writer.send(&Barrier::new(0)); // B done.
+
+        // Action C: start an operation and pass out the challenge
+        reader.recv();
+        let result = sec_level
+            .createOperation(&key, &params, UNFORCED)
+            .expect("failed to create auth-per-op operation");
+        let op = result.iOperation.context("no operation in result")?;
+        info!("C: created auth-per-op operation, got challenge {:?}", result.operationChallenge);
+        writer.send(&Barrier::new(result.operationChallenge.unwrap().challenge)); // C done.
+
+        // Action D: finishing the operation still fails because the per-op HAT
+        // is invalid (the HMAC signature is faked and so the secure world
+        // rejects the HAT).
+        reader.recv();
+        let result = op.finish(Some(b"data"), None);
+        expect_km_error!(&result, ErrorCode::KEY_USER_NOT_AUTHENTICATED);
+        info!("D: failed auth-per-op op (HAT is per-op but invalid) as expected {result:?}");
+        writer.send(&Barrier::new(0)); // D done.
+
+        Ok(())
+    };
+
+    // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+    // `--test-threads=1`), and nothing yet done with binder.
+    let mut child_handle = unsafe {
+        // Perform keystore actions while running as the test user.
+        run_as::run_as_child(CTX, Uid::from_raw(UID), Gid::from_raw(UID), child_fn)
+    }
+    .unwrap();
+
+    // Now that the separate process has been forked off, it's safe to use binder to setup a test
+    // user.
+    let _ks2 = get_keystore_service();
+    let user = TestUser::new();
+    let user_id = user.id;
+    let auth_service = get_authorization();
+
+    // Lock and unlock to ensure super keys are already created.
+    auth_service
+        .onDeviceLocked(user_id, &[BIO_FAKE_SID1, BIO_FAKE_SID2], WEAK_UNLOCK_DISABLED)
+        .unwrap();
+    auth_service.onDeviceUnlocked(user_id, Some(SYNTHETIC_PASSWORD)).unwrap();
+    auth_service.addAuthToken(&fake_lskf_token(GK_FAKE_SID)).unwrap();
+
+    info!("trigger child process action A and wait for completion");
+    child_handle.send(&Barrier::new(0));
+    child_handle.recv_or_die();
+
+    // Unlock with password and a fake auth token.
+    auth_service.onDeviceUnlocked(user_id, Some(SYNTHETIC_PASSWORD)).unwrap();
+    auth_service.addAuthToken(&fake_lskf_token(GK_FAKE_SID)).unwrap();
+
+    info!("trigger child process action B and wait for completion");
+    child_handle.send(&Barrier::new(0));
+    child_handle.recv_or_die();
+
+    info!("trigger child process action C and wait for completion");
+    child_handle.send(&Barrier::new(0));
+    let challenge = child_handle.recv_or_die().0;
+
+    // Add a fake auth token with the challenge value.
+    auth_service.addAuthToken(&fake_lskf_token_with_challenge(GK_FAKE_SID, challenge)).unwrap();
+
+    info!("trigger child process action D and wait for completion");
+    child_handle.send(&Barrier::new(0));
+    child_handle.recv_or_die();
+
+    assert_eq!(child_handle.get_result(), Ok(()), "child process failed");
+}
+
+#[test]
+fn test_unlocked_device_required() {
+    android_logger::init_once(
+        android_logger::Config::default()
+            .with_tag("keystore2_client_tests")
+            .with_max_level(log::LevelFilter::Debug),
+    );
+
+    let child_fn = move |reader: &mut ChannelReader<BarrierReached>,
+                         writer: &mut ChannelWriter<BarrierReached>|
+          -> Result<(), run_as::Error> {
+        let ks2 = get_keystore_service();
+        if ks2.getInterfaceVersion().unwrap() < 4 {
+            // Assuming `IKeystoreAuthorization::onDeviceLocked` and
+            // `IKeystoreAuthorization::onDeviceUnlocked` APIs will be supported on devices
+            // with `IKeystoreService` >= 4.
+            return Ok(());
+        }
+
+        // Now we're in a new process, wait to be notified before starting.
+        reader.recv();
+
+        // Action A: create a new unlocked-device-required key (which thus requires
+        // super-encryption), while the device is unlocked.
+        let sec_level =
+            ks2.getSecurityLevel(SecurityLevel::TRUSTED_ENVIRONMENT).context("no TEE")?;
+        let params = AuthSetBuilder::new()
+            .no_auth_required()
+            .unlocked_device_required()
+            .algorithm(Algorithm::EC)
+            .purpose(KeyPurpose::SIGN)
+            .purpose(KeyPurpose::VERIFY)
+            .digest(Digest::SHA_2_256)
+            .ec_curve(EcCurve::P_256);
+
+        let KeyMetadata { key, .. } = sec_level
+            .generateKey(
+                &KeyDescriptor {
+                    domain: Domain::APP,
+                    nspace: -1,
+                    alias: Some("unlocked-device-required".to_string()),
+                    blob: None,
+                },
+                None,
+                &params,
+                0,
+                b"entropy",
+            )
+            .context("key generation failed")?;
+        info!("A: created unlocked-device-required key while unlocked {key:?}");
+        writer.send(&BarrierReached {}); // A done.
+
+        // Action B: fail to use the unlocked-device-required key while locked.
+        reader.recv();
+        let params = AuthSetBuilder::new().purpose(KeyPurpose::SIGN).digest(Digest::SHA_2_256);
+        let result = sec_level.createOperation(&key, &params, UNFORCED);
+        info!("B: use unlocked-device-required key while locked => {result:?}");
+        expect_km_error!(&result, ErrorCode::DEVICE_LOCKED);
+        writer.send(&BarrierReached {}); // B done.
+
+        // Action C: try to use the unlocked-device-required key while unlocked with a
+        // password.
+        reader.recv();
+        let result = sec_level.createOperation(&key, &params, UNFORCED);
+        info!("C: use unlocked-device-required key while lskf-unlocked => {result:?}");
+        expect!(result.is_ok(), "failed with {result:?}");
+        abort_op(result);
+        writer.send(&BarrierReached {}); // C done.
+
+        // Action D: try to use the unlocked-device-required key while unlocked with a weak
+        // biometric.
+        reader.recv();
+        let result = sec_level.createOperation(&key, &params, UNFORCED);
+        info!("D: use unlocked-device-required key while weak-locked => {result:?}");
+        expect!(result.is_ok(), "createOperation failed: {result:?}");
+        abort_op(result);
+        writer.send(&BarrierReached {}); // D done.
+
+        Ok(())
+    };
+
+    // Safety: only one thread at this point (enforced by `AndroidTest.xml` setting
+    // `--test-threads=1`), and nothing yet done with binder.
+    let mut child_handle = unsafe {
+        // Perform keystore actions while running as the test user.
+        run_as::run_as_child(CTX, Uid::from_raw(UID), Gid::from_raw(UID), child_fn)
     }
     .unwrap();
 
@@ -214,46 +806,69 @@
     let auth_service = get_authorization();
 
     // Lock and unlock to ensure super keys are already created.
-    auth_service.onDeviceLocked(user_id, &[BIO_SID1, BIO_SID2], WEAK_UNLOCK_DISABLED).unwrap();
-    auth_service.onDeviceUnlocked(user_id, Some(PASSWORD)).unwrap();
-    auth_service.addAuthToken(&fake_lskf_token(GK_SID)).unwrap();
+    auth_service
+        .onDeviceLocked(user_id, &[BIO_FAKE_SID1, BIO_FAKE_SID2], WEAK_UNLOCK_DISABLED)
+        .unwrap();
+    auth_service.onDeviceUnlocked(user_id, Some(SYNTHETIC_PASSWORD)).unwrap();
+    auth_service.addAuthToken(&fake_lskf_token(GK_FAKE_SID)).unwrap();
 
     info!("trigger child process action A while unlocked and wait for completion");
     child_handle.send(&BarrierReached {});
-    child_handle.recv();
+    child_handle.recv_or_die();
 
     // Move to locked and don't allow weak unlock, so super keys are wiped.
-    auth_service.onDeviceLocked(user_id, &[BIO_SID1, BIO_SID2], WEAK_UNLOCK_DISABLED).unwrap();
+    auth_service
+        .onDeviceLocked(user_id, &[BIO_FAKE_SID1, BIO_FAKE_SID2], WEAK_UNLOCK_DISABLED)
+        .unwrap();
 
     info!("trigger child process action B while locked and wait for completion");
     child_handle.send(&BarrierReached {});
-    child_handle.recv();
+    child_handle.recv_or_die();
 
     // Unlock with password => loads super key from database.
-    auth_service.onDeviceUnlocked(user_id, Some(PASSWORD)).unwrap();
-    auth_service.addAuthToken(&fake_lskf_token(GK_SID)).unwrap();
+    auth_service.onDeviceUnlocked(user_id, Some(SYNTHETIC_PASSWORD)).unwrap();
+    auth_service.addAuthToken(&fake_lskf_token(GK_FAKE_SID)).unwrap();
 
     info!("trigger child process action C while lskf-unlocked and wait for completion");
     child_handle.send(&BarrierReached {});
-    child_handle.recv();
+    child_handle.recv_or_die();
 
     // Move to locked and allow weak unlock, then do a weak unlock.
-    auth_service.onDeviceLocked(user_id, &[BIO_SID1, BIO_SID2], WEAK_UNLOCK_ENABLED).unwrap();
+    auth_service
+        .onDeviceLocked(user_id, &[BIO_FAKE_SID1, BIO_FAKE_SID2], WEAK_UNLOCK_ENABLED)
+        .unwrap();
     auth_service.onDeviceUnlocked(user_id, None).unwrap();
 
     info!("trigger child process action D while weak-unlocked and wait for completion");
     child_handle.send(&BarrierReached {});
-    child_handle.recv();
+    child_handle.recv_or_die();
 
     assert_eq!(child_handle.get_result(), Ok(()), "child process failed");
 }
 
 /// Generate a fake [`HardwareAuthToken`] for the given sid.
 fn fake_lskf_token(gk_sid: i64) -> HardwareAuthToken {
+    fake_lskf_token_with_challenge(gk_sid, 0)
+}
+
+/// Generate a fake [`HardwareAuthToken`] for the given sid and challenge.
+fn fake_lskf_token_with_challenge(gk_sid: i64, challenge: i64) -> HardwareAuthToken {
+    HardwareAuthToken {
+        challenge,
+        userId: gk_sid,
+        authenticatorId: 0,
+        authenticatorType: HardwareAuthenticatorType::PASSWORD,
+        timestamp: Timestamp { milliSeconds: 123 },
+        mac: vec![1, 2, 3],
+    }
+}
+
+/// Generate a fake [`HardwareAuthToken`] for the given sids
+fn fake_bio_lskf_token(gk_sid: i64, bio_sid: i64) -> HardwareAuthToken {
     HardwareAuthToken {
         challenge: 0,
         userId: gk_sid,
-        authenticatorId: 0,
+        authenticatorId: bio_sid,
         authenticatorType: HardwareAuthenticatorType::PASSWORD,
         timestamp: Timestamp { milliSeconds: 123 },
         mac: vec![1, 2, 3],
