Android has the concept of user authenticators that are used to unlock the device and to gate access to cryptographic keys. This involves the following components:
- Cryptographic key storage and service provider. Android Keystore
provides hardware-backed cryptographic services for
apps. The Android Keystore
system at the framework level is backed by the
keystore2
system service. This is based in turn on an underlying vendor-specific KeyMint (previously Keymaster) implementation that ensures key material is only accessible in a hardware-backed secure environment, such as a Trusted Execution Environment (TEE) or a Secure Element (SE). - User authenticators. Attest to the successful authentication of the user.
Android supports the following authentication components:
- Gatekeeper for PIN, pattern, or password authentication in the TEE.
- (Optionally) Weaver for PIN, pattern, or password authentication in a secure element.
- Fingerprint for fingerprint authentication.
- Other biometric authentication methods. Devices that ship with Android 9
or higher can
use
BiometricPrompt
as a single integration point for fingerprint and additional biometrics.
keystore2
service through the use of hardware-backed authentication tokens (AuthTokens) .
Each of these components is vendor-specific, but the vendor implementation is required to satisfy a Hardware Abstraction Layer (HAL) interface specification, and to pass the corresponding vendor test suite (VTS) tests.
Vendor implementations are typically also divided into two parts, connected by a vendor-specific communication mechanism :
- A HAL service runs as an Android system process, receiving Binder requests from the Android system.
- A trusted application (TA) runs in the secure environment, performing the actual secure operations.
Enrollment
On first boot of the device after a factory reset, all authenticators are prepared to receive credential enrollments from the user. A user must initially enroll a PIN, pattern, or password with Gatekeeper (or Weaver, if available). This initial enrollment creates a randomly generated, 64-bit user secure identifier (SID) that serves as an identifier for the user and as a binding token for the user's cryptographic material. This user SID is cryptographically bound to the user's password; successful authentications to Gatekeeper result in AuthTokens that contain the user SID for that password.
A user who wants to change an existing credential must present that credential. If an existing credential is verified successfully, the user SID associated with the existing credential is transferred to the new credential, enabling the user to keep accessing keys after changing a credential.
In some situations, a device administrator can perform an untrusted enroll to enroll a new credential without presenting an existing credential. This allows the user to access the device, but keys created under the old user SID are permanently lost.
Authentication
This section describes a typical authentication flow, which involves interactions between multiple components in both Android and the secure environment. Note that all secure components share a (per-boot) secret HMAC key that they use to authenticate each other's messages.
After a user has set up a credential and been assigned a user SID, they can
start authentication, which begins when a user provides a PIN, pattern,
password, fingerprint, or other strong biometric.
Figure 1. Authentication flow
- A user provides an authentication method and the associated service
makes a request to the HAL service.
- For PIN, pattern, or password,
LockSettingsService
makes a request togatekeeperd
. - Biometrics-based authentication flows depend on the Android version.
On devices running Android 8.x and lower,
FingerprintService
makes a request tofingerprintd
). On devices running Android 9 and higher,BiometricPrompt
makes a request to the appropriate biometric daemon (for example,fingerprintd
for fingerprints orfaced
for face) using the appropriateBiometricManager
class, such asFingerprintManager
orFaceManager
. Regardless of version, biometric authentication occurs asynchronously after the request is sent.
- For PIN, pattern, or password,
- The HAL service sends data to its counterpart TA, which generates an
AuthToken:
- For PIN/pattern/password authentication,
gatekeeperd
sends the PIN, pattern, or password hash to the Gatekeeper TA in the TEE, via the Gatekeeper HAL service. If authentication in the TEE is successful, the Gatekeeper TA emits an AuthToken containing the corresponding user SID (signed with the shared HMAC key). - For fingerprint authentication,
fingerprintd
listens for fingerprint events and sends the data to the Fingerprint TA in the TEE, via the Fingerprint HAL. If authentication in the TEE is successful, the Fingerprint TA emits an AuthToken (signed with the AuthToken HMAC key). - For other biometric authentication, the appropriate biometric daemon listens for the biometric event and sends it to the appropriate biometric HAL service and TA.
- For PIN/pattern/password authentication,
- The resulting signed AuthToken is passed to the
keystore2
system service through a Binder interface. - The
keystore2
service attaches the AuthTokens to request for KeyMint (previously Keymaster) to perform cryptographic operations. The KeyMint HAL service passes them on to the KeyMint TA, which verifies them using the HMAC key shared with the Gatekeeper and the supported biometric TEE components. KeyMint trusts the timestamp in the token as the last authentication time, decides whether to allow use of the key based on the timestamp.
The authentication flow does not require direct communication between TAs in
the secure environment: AuthTokens flow from the authenticator TA to the
keystore2
service in Android, which in turn passes them on to the KeyMint TA.
This also permits the keystore2
service to quickly deny requests
that are bound to fail, as it has knowledge of the available AuthTokens in the
system, saving a potentially costly IPC into the TEE.
AuthToken format
The format of the AuthToken is given by the AIDL specification in
HardwareAuthToken.aidl
.
Device boot flow
On every boot of a device, the AuthToken HMAC key must be generated and shared with all TEE components (Gatekeeper, KeyMint/Keymaster, and supported biometrics TAs). To prevent replay attacks, the HMAC key must be randomly generated every time the device reboots.
There are two common ways that TAs acquire access to this shared HMAC key:
- Shared secret agreement: The
keystore2
service performs a multi-way key agreement protocol at device startup, allowing secure derivation of the HMAC key between those TAs that participate. However, participating TAs must have access to a common preshared secret. - Direct access: TAs that reside within the same secure environment can use an internal interprocess communication mechanism (which is platform-dependent) to share the HMAC key.
In either case, the HMAC key must never be made available outside the TEE.
The Trusty operating system, which runs next to Android, is an example of a TEE, but other TEEs can be used instead. Trusty uses an internal IPC system to communicate directly between KeyMint and Gatekeeper or the appropriate biometric TA. The HMAC key is kept solely in KeyMint; Fingerprint and Gatekeeper request the key from KeyMint for each use and don't persist or cache the value.