Overview
Face authentication allows users to unlock their device simply by looking at the front of their device. Android 10 adds support for a new face authentication stack that can securely process camera frames, preserving security and privacy during face authentication on supported hardware. Android 10 also provides an easy way for security compliant implementations to enable application integration for transactions, such as online banking or other services.
The Android face authentication stack is a new implementation in Android
10. The new implementation introduces the IBiometricsFace.hal
,
IBiometricsFaceClientCallback.hal
,
and types.hal
interfaces.
Architecture
The BiometricPrompt API includes all biometric authentication including, face, finger, and iris. The Face HAL interacts with the following components.
![Biometric stack](https://source.android.google.cn/static/docs/security/images/biometricStack.png?authuser=4)
FaceManager
FaceManager
is a private interface that maintains a
connection with FaceService
. It's used by Keyguard to
access face authentication with a custom UI. Apps don't
have access to FaceManager and must use BiometricPrompt
instead.
FaceService
This is the framework implementation that manages access to the face authentication hardware. It contains basic enrollment and authentication state machines as well as various other helpers (for example, enumeration). Because of stability and security concerns, no vendor code is permitted to run in this process. All vendor code is accessed through the Face 1.0 HIDL interface.
faced
This is a Linux executable that implements the Face 1.0 HIDL interface used
by FaceService
. It registers itself as IBiometricsFace@1.0 so that FaceService
can find it.
Implementation
Face HIDL
To implement the Face HIDL, you must implement all the methods of IBiometricsFace.hal
in a vendor-specific library.
Error messages
Error messages are sent by a callback and return the state machine to the
idle state after they're sent. Most messages have a
corresponding user-facing string to inform the user of the error, but not all
errors have this user-facing string. For more information on error messages, see
types.hal
.
All error messages represent a terminal state, meaning the framework assumes that the
HAL returns to an idle state after sending an error message.
Acquisition messages
Acquisition messages are delivered during enrollment or authentication and
are meant to guide the user toward a successful enrollment or authentication.
Each ordinal has
an associated message from the FaceAuthenticationManager.java
file. Vendor-specific messages can be added as long as the corresponding help
strings are provided. Acquisition messages aren't terminal states in and of
themselves; the HAL is expected to send as many of these as necessary to
complete the current enrollment or authentication. If an acquisition message
results in a terminal state where no progress can be made, then the HAL should
follow the acquisition messages with an error message, for example, where the
image is too dark and stays too dark for progress to be made. In this case, it's
reasonable to send UNABLE_TO_PROCESS
after several attempts have been made
but no further progress can be made.
Hardware
For devices to comply with the strong biometric requirements for Android 10, they must have secure hardware to ensure the integrity of face data and the ultimate authentication comparison. The Android Compatibility Definition Document (CDD) outlines the level of security required and the acceptable spoof acceptance rate (SAR) required. A trusted execution environment (TEE) is required for secure processing and recognition. Additionally, secure camera hardware is required to prevent injection attacks on face authentication. For example, the associated memory pages for image data could be privileged and marked read-only so only the camera hardware can update them. Ideally, no process should have access except TEE and the hardware.
Because face authentication hardware varies considerably, it's necessary to
develop hardware-specific drivers to enable face authentication, depending on
specific device architecture. As such, there is no reference
implementation for faced
.
Methods
The following methods are all asynchronous and must immediately return to the framework. Failing to do so results in a slow system and potential Watchdog resets. It's recommended to have a message queue with multiple threads to avoid blocking the caller. All GET requests should cache information where possible so the caller is blocked for a minimal amount of time.
Method | Description |
---|---|
setCallback() |
Called by FaceService to plumb all messages back to itself. |
setActiveUser() |
Sets the active user, which all subsequent HAL operations are applied. Authentication is always for this user until this method is called again. |
revokeChallenge() |
Finishes the secure transaction by invalidating the challenge generated
by generateChallenge() . |
enroll() |
Enrolls a user's face. |
cancel() |
Cancels the current operation (for example, enroll, authenticate,
remove, or enumerate) and returns faced to the idle state. |
enumerate() |
Enumerates all face templates associated with the active user. |
remove() |
Removes a face template or all face templates associated with the active user. |
authenticate() |
Authenticates the active user. |
userActivity() |
This method should only be used when the HAL is in the authenticating or
standby state. Using this method when the HAL is not in one of these
states returns OPERATION_NOT_SUPPORTED . Calling
this method while the HAL is already authenticating may extend the
amount of time the system looks for a face. |
resetLockout() |
When too many faces are rejected, faced is required to enter a lockout
state (LOCKOUT or LOCKOUT_PERMANENT ). When it
does, it's required to send the remaining time to the framework so it can
display it for the user. As with setFeature() , this method requires an
active hardware authentication token (HAT) to securely reset the internal state. Resets lockout
only for the current user. |
The three remaining methods are all synchronous and should block for the minimal amount of time to avoid stalling the framework.
Method | Description |
---|---|
generateChallenge() |
Generates a unique and cryptographically secure random token used to indicate the start of a secure transaction. |
setFeature() |
Enables or disables a feature for the current user. For security reasons, this requires a HAT from checking the user's pin/pattern/password against the above challenge |
getFeature() |
Retrieves the current enablement state of the feature, as dictated by
the default or a call to setFeature() above. If the face ID is invalid, the
implementation must return ILLEGAL_ARGUMENT |
getAuthenticatorId() |
Returns an identifier associated with the current face set. This identifier must change whenever a face is added |
State Diagram
The framework expects faced
to follow the state diagram below.
![State Diagram](https://source.android.google.cn/static/docs/security/images/faceAuthStateFlow.png?authuser=4)