blob: 77e35d9607cf8fba3b7a8f70f99b1522d074ebe0 [file] [log] [blame]
<html devsite>
<head>
<title>Authentication</title>
<meta name="project_path" value="/_project.yaml" />
<meta name="book_path" value="/_book.yaml" />
</head>
<body>
<!--
Copyright 2017 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.
-->
<p>Android uses the concept of user-authentication-gated cryptographic keys that
requires the following components:</p>
<ul>
<li><strong>Cryptographic key storage and service provider</strong>. Stores
cryptographic keys and provides standard crypto routines on top of those keys.
Android supports a <a href="/security/keystore/index.html">hardware-backed
Keystore</a> and Keymaster for cryptographic services, including hardware-backed
cryptography for key storage that might include a Trusted Execution Environment
(TEE) or Secure Element (SE), such as Strongbox.</li>
<li><strong>User authenticators</strong>. Attest to the user's presence and/or
successful authentication. Android supports
<a href="gatekeeper.html">Gatekeeper</a> for PIN/pattern/password authentication
and <a href="fingerprint-hal.html">Fingerprint</a> for fingerprint
authentication. Devices that ship with Android 9 and higher can use <a
href="https://developer.android.com/reference/android/hardware/biometrics/BiometricPrompt"
class="external">BiometricPrompt</a> as a single integration point for
fingerprint and additional biometrics. These components communicate their
authentication state with the keystore service via an authenticated channel.
(The <a href="https://developer.android.com/training/articles/keystore.html"
class="external">Android Keystore system</a> at the framework level is also
backed by the keystore service.)</li>
</ul>
<p>Gatekeeper, Fingerprint, and Biometric components work with Keystore and other
components to support the use of hardware-backed
<a href="#authtoken_format">authentication tokens</a> (AuthTokens).</p>
<h2 id="enrollment">Enrollment</h2>
<p>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/password with Gatekeeper. This initial enrollment creates a
randomly generated, 64-bit User SID (user secure identifier) 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.</p>
<p>A user who wants to change a credential must present an existing 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. If a user does not present
an existing credential, the new credential is enrolled with a fully random User
SID. The user can access the device, but keys created under the old User SID are
permanently lost. This is known as an <em>untrusted enroll</em>.</p>
<p>Under normal circumstances, the Android framework does not allow an untrusted
enroll, so most users won't ever see this functionality. However, forcible
password resets, either by a device administrator or an attacker, may
cause this to occur.</p>
<h2 id="authentication">Authentication</h2>
<p>After a user has set up a credential and received a User SID, they may
proceed to start authentication, which begins when a user provides a PIN,
pattern, password, or fingerprint. All TEE components share a secret key which
they use to authenticate each other's messages.</p>
<img src="../images/authentication-flow.png" alt="Authentication flow"
id="Authentication flow" />
<figcaption><strong>Figure 1.</strong> Authentication flow.</figcaption>
<ol>
<li>A user provides an authentication method and the associated service
makes a request to the the associated daemon.
<ul>
<li>For PIN, pattern, or password, the <code>LockSettingsService</code>
makes a request to <code>gatekeeperd</code>.</li>
<li>Biometrics-based authentication flows depend on the Android version.
On devices running Android 8.x and lower, <code>FingerprintService</code>
makes a request to <code>fingerprintd</code>). On devices
running Android 9 and higher, <code>BiometricPrompt</code> makes a
request to the appropriate biometric daemon (for example,
<code>fingerprintd</code> for fingerprints or <code>faced</code> for
face) using the appropriate <code><var>Biometric</var>Manager</code>
class, such as <code>FingerprintManager</code> or
<code>FaceManager</code>. Regardless of version, biometric
authentication occurs asynchronously after the request is sent.</li>
</ul>
</li>
<li>The daemon sends data to its counterpart, which generates an AuthToken:
<ul>
<li>For PIN/pattern/password authentication, <code>gatekeeperd</code> sends
the PIN, pattern, or password hash to Gatekeeper in the TEE. If
authentication in the TEE is successful, Gatekeeper in the TEE sends an
AuthToken containing the corresponding User SID (signed with the AuthToken
HMAC key) to its counterpart in the Android OS.
<li>For fingerprint authentication, <code>fingerprintd</code> listens for
fingerprint events and sends the data to Fingerprint in the TEE. If
authentication in the TEE is successful, Fingerprint in the TEE sends an
AuthToken (signed with the AuthToken HMAC key) to its counterpart in the
Android OS.</li>
<li>For other biometric authentication, the appropriate biometric daemon
listens for the biometric event and sends it to the appropriate biometric
TEE component.</li>
</ul>
</li>
<li>The daemon receives a signed AuthToken and passes it to the keystore
service via an extension to the keystore service's Binder interface.
(<code>gatekeeperd</code> also notifies the keystore service when the device
is re-locked and when the device password changes.)
<li>The keystore service passes the AuthTokens to Keymaster and verifies them
using the key shared with the Gatekeeper and supported biometric TEE
component. Keymaster trusts the timestamp in the token as the last
authentication time and bases a key release decision (to allow an app to use
the key) on the timestamp.</li>
</ol>
<aside class="note"><strong>Note:</strong> AuthTokens are invalidated when a
device reboots.</aside>
<h2 id="authtoken_format">AuthToken format</h2>
<p>To ensure token sharing and compatibility across languages and components,
the AuthToken format is described in
<a href="https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/hw_auth_token.h" class="external"><code>hw_auth_token.h</code></a>.
The format is a simple serialization protocol with fixed size fields:</p>
<table>
<tr>
<th width="15%">Field</th>
<th width="20%">Type</th>
<th width="10%">Required</th>
<th>Description</th>
</tr>
<tr>
<td>AuthToken Version</td>
<td>1 byte</td>
<td>Yes</td>
<td>Group tag for all fields below.</td>
</tr>
<tr>
<td>Challenge</td>
<td>64-bit unsigned integer</td>
<td>No</td>
<td>A random integer to prevent replay attacks. Usually the ID of a
requested crypto operation. Currently used by transactional fingerprint
authorizations. If present, the AuthToken is valid only for crypto
operations containing the same challenge.</td>
</tr>
<tr>
<td>User SID</td>
<td>64-bit unsigned integer</td>
<td>Yes</td>
<td>Non-repeating user identifier tied cryptographically to all keys
associated with device authentication. For details, see
<a href="/security/authentication/gatekeeper.html">Gatekeeper</a>.</td>
</tr>
<tr>
<td>Authenticator ID (ASID)</td>
<td>64-bit unsigned integer in network order</td>
<td>No</td>
<td>Identifier used to bind to a specific authenticator policy. All
authenticators have their own value of ASID that they can change according
to their own requirements.</td>
</tr>
<tr>
<td>Authenticator type</td>
<td>32-bit unsigned integer in network order</td>
<td>Yes</td>
<td><ul>
<li>0x00 is Gatekeeper.</li>
<li>0x01 is Fingerprint.</li>
</ul>
</td>
</tr>
<tr>
<td>Timestamp</td>
<td>64-bit unsigned integer in network order</td>
<td>Yes</td>
<td>Time (in milliseconds) since the most recent system boot.</td>
</tr>
<tr>
<td>AuthToken HMAC (SHA-256)</td>
<td>256-bit blob</td>
<td>Yes</td>
<td>Keyed SHA-256 MAC of all fields except the HMAC field.</td>
</tr>
</table>
<h2 id="device_boot_flow">Device boot flow</h2>
<p>On every boot of a device, the AuthToken HMAC key must be generated and
shared with all TEE components (Gatekeeper, Keymaster, and supported biometrics
trustlets). Thus, for added protection against replay attacks, the HMAC key
must be randomly generated every time the device reboots.</p>
<p>The protocol for sharing this HMAC key with all components is a
platform-dependent implementation feature. The key must <strong>never</strong>
be made available outside the TEE. If a TEE OS lacks an internal inter-process
communication (IPC) mechanism and needs to transfer the data through the
untrusted OS, the transfer must be done via a secure key exchange protocol.</p>
<p>The <a href="/security/trusty/index.html">Trusty</a> 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
Keymaster and Gatekeeper or the appropriate biometric trustlet. The HMAC key is
kept solely in Keymaster; Fingerprint and Gatekeeper request the key from
Keymaster for each use and do not persist or cache the value.</p>
<p>As some TEEs lack an IPC infrastructure, no communication occurs between
applets in the TEE. This also permits the keystore service to quickly deny
requests that are bound to fail as it has knowledge of the authentication table
in the system, saving a potentially costly IPC into the TEE.</p>
</body>
</html>