blob: a27882bd782f4f67abe61ef36a7f33dd652baaa8 [file] [log] [blame]
<html devsite>
<head>
<title>Gatekeeper</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>The Gatekeeper subsystem performs device pattern/password authentication in a
Trusted Execution Environment (TEE). Gatekeeper enrolls and verifies passwords
via an HMAC with a hardware-backed secret key. Additionally, Gatekeeper
throttles consecutive failed verification attempts and must refuse to service
requests based on a given timeout and a given number of consecutive failed
attempts.</p>
<p>When users verify their passwords, Gatekeeper uses the TEE-derived shared
secret to sign an authentication attestation to send to the
<a href="/security/keystore/index.html">hardware-backed Keystore</a>. That is, a
Gatekeeper attestation notifies Keystore that authentication-bound keys (for
example, keys that apps have created) can be released for use by apps.</p>
<h2 id=architecture>Architecture</h2>
<p>Gatekeeper involves three main components:</p>
<ul>
<li><code>gatekeeperd</code> (Gatekeeper daemon). A C++ binder service
containing platform-independent logic and corresponding to the
<code>GateKeeperService</code> Java interface.</li>
<li><strong>Gatekeeper Hardware Abstraction Layer (HAL)</strong>. The HAL
interface in <code>hardware/libhardware/include/hardware/gatekeeper.h</code>,
and the implementing module.</li>
<li><strong>Gatekeeper (TEE)</strong>. The TEE counterpart of
<code>gatekeeperd</code>. A TEE-based implementation of Gatekeeper.</li>
</ul>
<p>Gatekeeper requires implementation of the
<a href="#hal_implementation">Gatekeeper HAL</a> (specifically the functions in
<code>hardware/libhardware/include/hardware/gatekeeper.h</code>) and the
<a href="#trusty_and_other_implementations">TEE-specific Gatekeeper
component</a> (based in part on the
<code>system/gatekeeper/include/gatekeeper/gatekeeper.h</code> header file that
includes pure virtual functions for creating/accessing keys and computing
signatures).
<p>The <code>LockSettingsService</code> makes a request (via Binder) that
reaches the <code>gatekeeperd</code> daemon in the Android OS. The
<code>gatekeeperd</code> daemon then makes a request that reaches its
counterpart (Gatekeeper) in the TEE:</p>
<img src="../images/gatekeeper-flow.png" alt="Gatekeeper flow" id="figure1" />
<figcaption><strong>Figure 1.</strong> High-level data flow for authentication
by GateKeeper</figcaption>
<p>The <code>gatekeeperd</code> daemon gives the Android framework APIs access
to the HAL, and participates in reporting device
<a href="/security/authentication/index.html">authentications</a> to Keystore.
The <code>gatekeeperd</code> daemon runs in its own process and is separate from
the system server.</p>
<h2 id=hal_implementation>HAL implementation</h2>
<p>The <code>gatekeeperd</code> daemon uses the HAL to interact
with the <code>gatekeeperd</code> daemon's TEE counterpart for
password authentication. The HAL implementation must be able to sign (enroll)
and verify blobs. All implementations are expected to adhere to the standard
format for the authentication token (AuthToken) generated on each successful
password verification. For details on the content and semantic of the AuthToken,
see <a href="/security/authentication/index.html#authtoken_format">AuthToken
format</a>.</p>
<p>Implementations of the
<code>hardware/libhardware/include/hardware/gatekeeper.h</code> header file
must implement the <code>enroll</code> and <code>verify</code> functions:</p>
<ul>
<li>The <code>enroll</code> function takes a password blob, signs it, and
returns the signature as a handle. The returned blob (from a call to
<code>enroll</code>) must have the structure shown in
<code>system/gatekeeper/include/gatekeeper/password_handle.h</code>.</li>
<li>The <code>verify</code> function must compare the signature produced by the
provided password and ensure it matches the enrolled password handle.</li>
</ul>
<p>The key used to enroll and verify must never change, and should be
re-derivable at every device boot.</p>
<h2 id=trusty_and_other_implementations>Trusty and other implementations</h2>
<p>The <a href="/security/trusty/index.html">Trusty</a> operating system is
Google's open source trusted OS for TEE environments and contains an approved
implementation of GateKeeper. However, you can use <strong>any TEE OS</strong>
to implement Gatekeeper as long as the TEE has access to a hardware-backed key
and a secure, monotonic clock <strong>that ticks in suspend</strong>.</p>
<p>Trusty uses an internal IPC system to communicate a shared secret directly
between Keymaster and the Trusty implementation of Gatekeeper (the <em>Trusty
Gatekeeper</em>). This shared secret is used for signing AuthTokens sent to
Keystore to provide attestations of password verification. Trusty Gatekeeper
requests the key from Keymaster for each use and does not persist or cache the
value. Implementations are free to share this secret in any way that does not
compromise security.</p>
<p>The HMAC key used to enroll and verify passwords is derived and kept solely
in GateKeeper.</p>
<p>Android provides a generic C++ implementation of GateKeeper that requires
only the addition of device-specific routines to be complete. To implement a
TEE Gatekeeper with device-specific code for your TEE, refer to the functions
and comments in <code>system/gatekeeper/include/gatekeeper/gatekeeper.h</code>.
For the TEE GateKeeper, the primary responsibilities of a compliant
implementation include:</p>
<ul>
<li>Adherence to the Gatekeeper HAL.</li>
<li>Returned AuthTokens must be formatted according to the AuthToken
specification (described in
<a href="/security/authentication/index.html">Authentication</a>).</li>
<li>The TEE Gatekeeper must be able to share an HMAC key with Keymaster,
either by requesting the key through a TEE IPC on demand or maintaining a
valid cache of the value at all times.</li>
</ul>
<h2 id=user_sids>User Secure IDs (SIDs)</h2>
<p>A User SID is the TEE representation of a user (with no strong connection to
an Android user ID). The SID is generated with a cryptographic pseudorandom
number generator (PRNG) whenever a user enrolls a new password without providing
a previous one. This is known as an <em>untrusted</em> re-enroll and is not
allowed by the Android framework in normal circumstances. A <em>trusted</em>
re-enroll occurs when a user provides a valid, previous password; in this case,
the User SID is migrated to the new password handle, conserving the keys that
were bound to it.</p>
<p>The User SID is HMAC'ed along with the password in the password handle when
the password is enrolled.</p>
<p>User SIDs are written into the AuthToken returned by the <code>verify</code>
function and associated to all authentication-bound Keystore keys (for details
on the AuthToken format and Keystore, see
<a href="/security/authentication/index.html">Authentication</a>). As an
untrusted call to the <code>enroll</code> function will change the User SID, the
call will render the keys bound to that password useless. Attackers can change
the password for the device if they control the Android OS, but they will
destroy root-protected, sensitive keys in the process.</p>
<h2 id=request_throttling>Request throttling</h2>
<p>GateKeeper must be able to securely throttle brute-force attempts on a user
credential. As shown in
<code>hardware/libhardware/include/hardware/gatekeeper.h</code>, the HAL
provides for returning a timeout in milliseconds. The timeout informs the client
not to call GateKeeper again until after the timeout has elapsed; GateKeeper
should not service requests if there is a pending timeout.</p>
<p>GateKeeper must write a failure counter before verifying a user password. If
the password verification succeeds, the failure counter should be cleared. This
prevents attacks that prevent throttling by disabling the embedded MMC (eMMC)
after issuing a <code>verify</code> call. The <code>enroll</code> function also
verifies the user password (if provided) and must be throttled in the same way.
</p>
<p>If supported by the device, it is highly recommended that the failure counter
be written to secure storage. If the device does not support
file-based encryption, or if secure storage is too slow, implementations may use
Replay Protected Memory Block (RPMB) directly.</p>
</body>
</html>