The availability of a trusted execution environment in a system on a chip
(SoC) offers an opportunity for Android devices to provide hardware-backed,
strong security services to the Android OS, to platform services, and even to
third-party apps (in the form of Android-specific extensions to the standard
Java Cryptography Architecture, see
KeyGenParameterSpec
).
Glossary
Here is a quick overview of Keystore components and their relationships.
AndroidKeyStore
- The Android Framework API and component used
by apps to access Keystore functionality. It is an implementation of the
standard Java Cryptography Architecture APIs, but also adds Android-specific
extensions and consists of Java code that runs in the app's own process
space.
AndroidKeyStore
fulfills app requests for Keystore behavior by forwarding them to the keystore daemon. - keystore daemon
- An Android system daemon that provides access to all Keystore functionality through a Binder API. This daemon is responsible for storing keyblobs created by the underlying KeyMint (or Keymaster) implementation, which contain the secret key material, encrypted so Keystore can store them but not use or reveal them.
- KeyMint HAL service
- An AIDL server that implements
the
IKeyMintDevice
HAL, providing access to the underlying KeyMint TA. - KeyMint trusted app (TA)
- Software running in a secure context, most often in TrustZone on an ARM SoC, that provides all of the secure cryptographic operations. This app has access to the raw key material, and validates all of the access control conditions on keys before allowing their use.
LockSettingsService
- The Android system component responsible for user authentication, both password and
fingerprint. It's not part of Keystore, but is relevant because Keystore supports the concept
of authentication bound keys: keys that can be used only if the user has authenticated.
LockSettingsService
interacts with the Gatekeeper TA and Fingerprint TA to obtain authentication tokens, which it provides to the keystore daemon, and which are consumed by the KeyMint TA. - Gatekeeper TA
- The component running in the secure environment that's responsible for authenticating user passwords and generating authentication tokens used to prove to the KeyMint TA that an authentication was done for a particular user at a particular point in time.
- Fingerprint TA
- The component running in the secure environment that's responsible for authenticating user fingerprints and generating authentication tokens used to prove to the KeyMint TA that an authentication was done for a particular user at a particular point in time.
Architecture
The Android Keystore API and the underlying KeyMint HAL provide a basic but adequate set of cryptographic primitives to allow the implementation of protocols using access-controlled, hardware-backed keys.
The KeyMint HAL is an OEM-provided service used by the Keystore service to provide hardware-backed cryptographic services. To keep private key material secure, HAL implementations don't perform any sensitive operations in user space, or even in kernel space. Instead, the KeyMint HAL service running in Android delegates sensitive operations to a TA running in some kind of secure environment, typically by marshalling and unmarshalling requests in some implementation-defined wire format.
The resulting architecture looks like this:

Figure 1. Access to KeyMint.
The KeyMint HAL API is low level, used by platform-internal components, and not exposed to app developers. The higher-level Java API that is available to apps is described on the Android Developer site.
Access control
Android Keystore provides a central component for the storage and use of hardware-backed cryptographic keys, both for apps and for other system components. As such, access to any individual key is normally limited to the app or system component that created the key.
Keystore domains
To support this access control, keys are identified to Keystore with a key descriptor. This key descriptor indicates a domain that the descriptor belongs to, together with an identity within that domain.
Android apps access Keystore using the standard Java Cryptography
Architecture, which identifies keys with a string alias. This method of
identification maps to the Keystore APP
domain internally; the
UID of the caller is also included to disambiguate keys from different
apps, preventing one app from accessing another's keys.
Internally, the frameworks code also receives a unique numeric key
ID after a key has been loaded. This numeric ID is used as the identifier
for key descriptors within the KEY_ID
domain. However, access
control is still performed: even if one app discovers a key ID for another app's
key, it can't use it in normal circumstances.
However, it is possible for an app to grant use of a key to a different app
(as identified by UID). This grant operation returns a unique grant identifier,
which is used as the identifier for key descriptors within
the GRANT
domain. Again, access control is still performed: even
if a third app discovers the grant ID for a grantee's key, it can't use it.
Keystore also supports two other domains for key descriptors, which are used for other system components and aren't available for app-created keys:
- The
BLOB
domain indicates that there is no identifier for the key in the key descriptor; instead, the key descriptor holds the keyblob itself and the client handles keyblob storage. This is used by clients (for example,vold
) that need to access Keystore before the data partition is mounted. - The
SELINUX
domain allows system components to share keys, with access governed by a numeric identifier that corresponds to an SELinux label (see SELinux policy for keystore_key).
SELinux policy for keystore_key
The identifier values used for Domain::SELINUX
key descriptors
are configured in the keystore2_key_context
SELinux policy file.
Each line in these files maps a numeric to an SELinux label, for example:
# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and # Settings to share keystore keys. 102 u:object_r:wifi_key:s0
A component that needs access to the key with ID 102 in
the SELINUX
domain must have the corresponding SELinux policy. For
example, to allow wpa_supplicant
to get and use these keys,
add the following line to hal_wifi_supplicant.te
:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
The numeric identifiers for Domain::SELINUX
keys are divided
into ranges to support different partitions without collisions:
Partition | Range | Config files |
---|---|---|
System | 0 ... 9,999 | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
|
Extended System | 10,000 ... 19,999 | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
|
Product | 20,000 ... 29,999 | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
|
Vendor | 30,000 ... 39,999 | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts
|
The following specific values have been defined for the system partition:
Namespace ID | SEPolicy label | UID | Description |
---|---|---|---|
0 | su_key |
N/A | Super user key. Only used for testing on userdebug and eng builds. Not relevant on user builds. |
1 | shell_key |
N/A | Namespace available to shell. Mostly used for testing, but can be used on user builds as well from the command line. |
100 | vold_key |
N/A | Intended for use by vold. |
101 | odsign_key |
N/A | Used by the on-device signing daemon. |
102 | wifi_key |
AID_WIFI(1010) |
Used by Android's Wifi subsystem including wpa_supplicant . |
103 | locksettings_key |
N/A | Used by LockSettingsService |
120 | resume_on_reboot_key |
AID_SYSTEM(1000) |
Used by Android's system server to support resume on reboot. |
Access vectors
Keystore allows control over which operations can be performed on a key, in
addition to controlling overall access to a key. The keystore2_key
permissions are described in
the KeyPermission.aidl
file.
System permissions
In addition to the per-key access controls described in SELinux policy for keystore_key, the following table describes other SELinux permissions that are required to perform various system and maintenance operations:
Permission | Meaning |
---|---|
add_auth
|
Required for adding auth tokens to Keystore; used by authentication providers such as Gatekeeper
or BiometricManager . |
clear_ns
|
Required for deleting all keys in a specific namespace; used as a maintenance operation when apps are uninstalled. |
list
|
Required by the system for enumerating keys by various properties, such as
ownership or whether they are authentication bound. This permission isn't required by callers
enumerating their own namespaces (covered by the
get_info permission). |
lock
|
Required for notifying keystore that the device was locked, which in turn evicts super-keys to ensure that authentication bound keys are unavailable. |
unlock
|
Required to notifying keystore that the device was unlocked, restoring access to the super-keys that protect authentication bound keys. |
reset
|
Required for resetting Keystore to factory default, deleting all keys that aren't vital to the functioning of the Android OS. |
History
In Android 5 and lower, Android had a simple, hardware-backed cryptographic services API, provided by versions 0.2 and 0.3 of the Keymaster hardware abstraction layer (HAL). Keystore provided digital signing and verification operations, plus generation and import of asymmetric signing key pairs. This is already implemented on many devices, but there are many security goals that can't easily be achieved with only a signature API. Android 6.0 extended the Keystore API to provide a broader range of capabilities.
Android 6.0
In Android 6.0, Keymaster 1.0 added symmetric cryptographic primitives, AES and HMAC, and an access control system for hardware-backed keys. Access controls are specified during key generation and enforced for the lifetime of the key. Keys can be restricted to be usable only after the user has been authenticated, and only for specified purposes or with specified cryptographic parameters.
In addition to expanding the range of cryptographic primitives, Keystore in Android 6.0 added the following:
- A usage control scheme to allow key usage to be limited, to mitigate the risk of security compromise due to misuse of keys
- An access control scheme to enable restriction of keys to specified users, clients, and a defined time range
Android 7.0
In Android 7.0, Keymaster 2 added support for key attestation and version binding.
Key attestation provides public key certificates that contain a detailed description of the key and its access controls, to make the key's existence in secure hardware and its configuration remotely verifiable.
Version binding binds keys to the operating system and patch level version. This ensures that an attacker who discovers a weakness in an old version of the system or the TEE software can't roll a device back to the vulnerable version and use keys created with the newer version. In addition, when a key with a given version and patch level is used on a device that has been upgraded to a newer version or patch level, the key is upgraded before it can be used, and the previous version of the key invalidated. As the device is upgraded, the keys ratchet forward along with the device, but any reversion of the device to a previous release causes the keys to be unusable.
Android 8.0
In Android 8.0, Keymaster 3 transitioned from the old-style C-structure HAL to the C++ HAL interface generated from a definition in the new hardware interface definition language (HIDL). As part of the change, many of the argument types changed, though types and methods have a one-to-one correspondence with the old types and the HAL struct methods.
In addition to this interface revision, Android 8.0 extended the attestation feature of Keymaster 2 to support ID attestation. ID attestation provides a limited and optional mechanism for strongly attesting to hardware identifiers, such as device serial number, product name, and phone ID (IMEI or MEID). To implement this addition, Android 8.0 changed the ASN.1 attestation schema to add ID attestation. Keymaster implementations need to find some secure way to retrieve the relevant data items, as well as to define a mechanism for securely and permanently disabling the feature.
Android 9
In Android 9, updates included:
- Update to Keymaster 4
- Support for embedded Secure Elements
- Support for secure key import
- Support for 3DES encryption
- Changes to version binding so that
boot.img
andsystem.img
have separately set versions to allow for independent updates
Android 10
Android 10 introduced version 4.1 of the Keymaster HAL, which added:
- Support for keys that are only usable when the device is unlocked
- Support for keys that can only be used in early boot stages
- Optional support for hardware-wrapped storage keys
- Optional support for device-unique attestation in StrongBox
Android 12
Android 12 introduced the new KeyMint HAL, which replaces the Keymaster HAL but provides similar functionality. In addition to all of the features above, the KeyMint HAL also includes:
- Support for ECDH key agreement
- Support for user-specified attestation keys
- Supoprt for keys with a limited number of uses
Android 12 also includes a new version of the keystore system daemon,
rewritten in Rust and known as keystore2
Android 13
Android 13 added v2 of the KeyMint HAL, which adds support for Curve25519 for both signing and key agreement.