This page contains information about the cryptographic features of Android Keystore, as provided by the underlying KeyMint (or Keymaster) implementation.
Cryptographic primitives
Keystore provides the following categories of operations:
- Creation of keys, resulting in private or secret key material that is
accessible only to the secure environment. Clients can create keys in the following
ways:
- Fresh key generation
- Import of unencrypted key material
- Import of encrypted key material
- Key attestation: Asymmetric key creation generates a certificate holding the public key part of the keypair. This certificate optionally also holds information about the metadata for the key and the state of the device, all signed by a key chaining back to a trusted root.
- Cryptographic operations:
- Symmetric encryption and decryption (AES, 3DES)
- Asymmetric decryption (RSA)
- Asymmetric signing (ECDSA, RSA)
- Symmetric signing and verification (HMAC)
- Asymmetric key agreement (ECDH)
Protocol elements, such as purpose, mode, and padding, as well as access control constraints, are specified when keys are generated or imported and are permanently bound to the key, ensuring the key can't be used in any other way.
The primitives and modes that must be supported by the
KeyMint implementation are described in
the IKeyMintDevice
HAL interface specification.
The underlying KeyMint implementation must perform random number generation to support key generation and creation of randomized padding or initialization vectors (IVs). To support this, the Android system periodically provides additional entropy to the KeyMint implementation.
Key access control
Hardware-based keys that can never be extracted from the device don't provide much security if an attacker can use them at will (though they're more secure than keys which can be exfiltrated). Thus, it's crucial that Keystore enforce access controls.
Access controls are defined as an "authorization list" of tag/value pairs. Authorization tags are 32-bit integers and the values are a variety of types. Some tags can be repeated to specify multiple values. Whether a tag can be repeated is specified in the KeyMint (previously Keymaster) HAL interface.
The supported tag values are defined in the
Tag.aidl
file,
and each is associated with a
TagType
that indicates the type of the associated value (for example, integer or bytes), and
whether it can be repeated to specify multiple supported values.
When KeyMint creates a key, the caller specifies an authorization list for the key. This list is modified by Keystore and KeyMint to add extra constraints, and the underlying KeyMint implementation encodes the final authorization list into the returned keyblob. The encoded authorization list is cryptographically bound into the keyblob, so that any attempt to modify the authorization list (including ordering) results in an invalid keyblob that can't be used for cryptographic operations.
Hardware versus software enforcement
Not all secure hardware implementations contain the same features. To support a variety of approaches, KeyMint distinguishes between secure and nonsecure access control enforcement, or hardware and software enforcement, respectively.
This is exposed in the KeyMint API with the securityLevel field
of
the KeyCharacteristics
type. The secure hardware is responsible for placing the authorizations in the
KeyCharacteristics with the appropriate security level, based on what
it can enforce. This information is also exposed in the
attestation records for asymmetric keys: key characteristics
for SecurityLevel::TRUSTED_ENVIRONMENT
or SecurityLevel::STRONGBOX appear in
the hardwareEnforced list, and characteristics
for SecurityLevel::SOFTWARE or
SecurityLevel::KEYSTORE appear in the
softwareEnforced list.
For example, constraints on the date and time interval when a key can be used are
typically not enforced by the secure environment, because it doesn't have
trustworthy access to date and time information. As a result, authorizations like
Tag::ORIGINATION_EXPIRE_DATETIME are enforced by Keystore in
Android, and would have SecurityLevel::KEYSTORE.
For more information about determining whether keys and their authorizations are hardware backed, see Key attestation.
Cryptographic message construction authorizations
The following tags are used to define the cryptographic characteristics of operations using the associated key:
Tag::ALGORITHMTag::KEY_SIZETag::BLOCK_MODETag::PADDINGTag::CALLER_NONCETag::DIGESTTag::MGF_DIGEST
The following tags are repeatable, meaning that multiple values can be associated with a single key:
Tag::BLOCK_MODETag::PADDINGTag::DIGESTTag::MGF_DIGEST
The value to be used is specified at operation time.
Purpose
Keys have an associated set of purposes, expressed as one or more
authorization entries with the Tag::PURPOSE tag, which defines how they
can be used. The purposes are defined in
KeyPurpose.aidl.
Note that some combinations of purpose values create security problems. For example, an RSA key that can be used to both encrypt and to sign allows an attacker who can convince the system to decrypt arbitrary data to generate signatures.
Key import
KeyMint supports import of:
- Asymmetric key pairs in DER-encoded PKCS#8 format (without password-based encryption)
- Symmetric keys as raw bytes
To ensure that imported keys can be distinguished from securely generated
keys, Tag::ORIGIN is included in the appropriate key
authorization list. For example, if a key
was generated in secure hardware, Tag::ORIGIN with
value KeyOrigin::GENERATED is found in
the hw_enforced list of the key characteristics, while a key
that was imported into secure
hardware has the value KeyOrigin::IMPORTED.
User authentication
Secure KeyMint implementations don't implement user authentication, but depend on other trusted apps that do. For the interface that these apps implement, see the Gatekeeper page.
User authentication requirements are specified via two sets of tags. The first set indicates which authentication methods allow use of the key:
Tag::USER_SECURE_IDhas a 64-bit numeric value specifying the secure user ID that is provided in a secure authentication token to unlock use of the key. If repeated, the key can be used if any of the values is provided in a secure authentication token.
The second set indicates whether and when the user needs to be authenticated.
If neither of these tags is present, but Tag::USER_SECURE_ID is,
authentication is required for every use of the key.
Tag::NO_AUTHENTICATION_REQUIREDindicates no user authentication is required, although access to the key is still restricted to the owning app (and any apps to which it grants access).Tag::AUTH_TIMEOUTis a numeric value specifying, in seconds, how fresh the user authentication needs to be to authorize key usage. Timeouts don't cross reboots; after a reboot, all authentications are invalidated. The timeout can be set to a large value to indicate that authentication is required once per boot (2^32 seconds is ~136 years; presumably Android devices are rebooted more often than that).
Require an unlocked device
Keys with Tag::UNLOCKED_DEVICE_REQUIRED are usable only while
the device is unlocked. For the detailed semantics, see
KeyProtection.Builder#setUnlockedDeviceRequired(boolean).
UNLOCKED_DEVICE_REQUIRED is enforced by Keystore, not by
KeyMint. However, in Android 12 and higher, Keystore cryptographically
protects UNLOCKED_DEVICE_REQUIRED keys while the device is locked
to ensure that, in most cases, they cannot be used even if Keystore is
compromised while the device is locked.
All cryptography and random number generation described in this section uses BoringSSL, except where the use of KeyMint is explicitly mentioned. All secrets are zeroized as soon as they are no longer needed.
UnlockedDeviceRequired super keys
To cryptographically protect UNLOCKED_DEVICE_REQUIRED keys,
Keystore "superencrypts" them before storing them in its database. When
possible, it protects the superencryption keys (super keys) while the device is
locked in such a way that they can be recovered only by a successful device
unlock. (The term "superencryption" is used because this layer of encryption is
applied in addition to the layer of encryption that KeyMint already
applies to all keys.)
Each user (including profiles)
has two super keys associated with UNLOCKED_DEVICE_REQUIRED:
- The UnlockedDeviceRequired symmetric super key. This is an
AES‑256‑GCM key. It encrypts
UNLOCKED_DEVICE_REQUIREDkeys that are imported, generated, or used while the device is unlocked for the user. - The UnlockedDeviceRequired asymmetric super key. This is an ECDH
P‑521 key pair. It encrypts
UNLOCKED_DEVICE_REQUIREDkeys that are imported or generated while the device is locked for the user. For more details, see Storing keys while device is locked.
Generating and protecting the super keys
When a user is created, Keystore generates the user's UnlockedDeviceRequired super keys and stores them in its database, encrypted (indirectly) by the user's synthetic password:
- The system server derives the user's Keystore password from the user's synthetic password using an SP800‑108 KDF.
- The system server passes the user's Keystore password to Keystore.
- Keystore generates the user's super keys.
- For each of the user's super keys:
- Keystore generates a random salt.
- Keystore derives an AES‑256‑GCM key from the user's Keystore password and the salt using HKDF‑SHA256.
- Keystore encrypts the secret part of the super key using this AES‑256‑GCM key.
- Keystore stores the encrypted super key and its salt in its database. If it's an asymmetric key, the public half of the key is also stored unencrypted.
This procedure allows these super keys to be decrypted when the user's synthetic password is known, such as when the user's correct PIN, pattern, or password is entered.
Keystore also caches these super keys in memory, allowing it to operate on
UNLOCKED_DEVICE_REQUIRED keys. However, it tries to cache the
secret parts of these keys only while the device is unlocked for the user. When
the device is locked for the user, Keystore zeroizes its cached copy of the
secret parts of these super keys, if possible. Specifically, when the device is
locked for the user, Keystore selects and applies one of three protection levels
for the user's UnlockedDeviceRequired super keys:
- If the user has only PIN, pattern, or password enabled, then Keystore zeroizes the secret parts of its cached super keys. This makes the super keys recoverable only via the encrypted copy in the database that can be decrypted only by PIN, pattern, or password equivalent.
- If the user has only class 3 ("strong") biometrics and PIN, pattern, or password enabled, then Keystore arranges for the super keys to be recoverable by any of the user's enrolled class 3 biometrics (commonly fingerprint), as an alternative to PIN, pattern, or password equivalent. To do this, it generates a new AES‑256‑GCM key, encrypts the secret parts of the super keys with it, imports the AES‑256‑GCM key into KeyMint as a biometric-bound key that requires biometric authentication to have succeeded within the last 15 seconds, and zeroizes the plaintext copies of all these keys.
- If the user has a class 1 ("convenience") biometric, class 2 ("weak")
biometric, or active unlock trust agent enabled, then Keystore keeps the
super keys cached in plaintext. In this case, cryptographic security for
UNLOCKED_DEVICE_REQUIREDkeys isn't provided. Users can avoid this less secure fallback by not enabling these unlock methods. The most common unlock methods that fall into these categories are face unlock on many devices, and unlock with a paired smartwatch.
When the device is unlocked for the user, Keystore recovers the user's UnlockedDeviceRequired super keys if possible. For PIN, pattern, or password equivalent unlock, it decrypts the copy of these keys that is stored in the database. Otherwise, it checks if it saved a copy of these keys encrypted with a biometric-bound key, and if so tries to decrypt that. This succeeds only if the user has successfully authenticated with a class 3 biometric within the last 15 seconds, enforced by KeyMint (not Keystore).
Storing keys while device is locked
Keystore allows users to import and generate
UNLOCKED_DEVICE_REQUIRED keys while the device is locked. It uses a
hybrid encryption scheme to ensure that they can be decrypted only when the
device is later unlocked:
- Encryption (importing or generating an
UNLOCKED_DEVICE_REQUIREDkey while the device is locked):- Keystore generates a new ephemeral ECDH P‑521 key pair.
- Keystore generates a shared secret by doing ECDH key agreement between the private key of this ephemeral key pair and the public half of the UnlockedDeviceRequired asymmetric super key.
- Keystore generates a random salt.
- Keystore derives an AES‑256‑GCM key from the shared secret and the salt using HKDF‑SHA256.
- Keystore encrypts the
UNLOCKED_DEVICE_REQUIREDkey using this AES‑256‑GCM key. - Keystore stores the encrypted
UNLOCKED_DEVICE_REQUIREDkey, the salt, and the public half of the ephemeral key pair in its database.
- Decryption (using the created
UNLOCKED_DEVICE_REQUIREDkey while the device is unlocked):- Keystore loads the encrypted
UNLOCKED_DEVICE_REQUIREDkey, the salt, and the public half of the ephemeral key pair from its database. - Keystore generates a shared secret by doing ECDH key agreement between the public half of the ephemeral key pair and the private half of the UnlockedDeviceRequired asymmetric super key. The private key is available because the device is unlocked.
- Keystore derives an AES‑256‑GCM key from the shared secret and the salt using HKDF‑SHA256. This AES‑256‑GCM key is the same as the one that was derived during encryption.
- Keystore decrypts the
UNLOCKED_DEVICE_REQUIREDkey using the AES‑256‑GCM key. - Keystore reencrypts the
UNLOCKED_DEVICE_REQUIREDkey using the UnlockedDeviceRequired symmetric super key. This doesn't affect the security properties of the key, but it allows it to be accessed more quickly later.
- Keystore loads the encrypted
This feature makes it possible for apps to store data while the device is locked, such that it can be decrypted only while the device is unlocked. To do so, apps should follow these steps:
- Generate an AES‑256‑GCM key outside of Keystore.
- Encrypt data using the AES‑256‑GCM key.
- Import the AES‑256‑GCM key into Keystore with the
setUnlockedDeviceRequired(true)key protection set. - Zeroize the original copy of the key.
To decrypt the data while the device is unlocked, use the key that was imported into Keystore.
Client binding
Client binding, the association of a key with a particular client
app, is done via an optional client ID and some optional client data
(Tag::APPLICATION_ID and Tag::APPLICATION_DATA,
respectively). Keystore treats these values as opaque blobs, only ensuring that
the same blobs presented during key generation/import are presented for every
use and are byte-for-byte identical. The client binding data isn't returned by
KeyMint. The caller has to know it in order to use the key.
This feature isn't exposed to apps.
Expiration
Keystore supports restricting key usage by date. Key start of validity and
key expirations can be associated with a key and Keystore refuses to
perform key operations if the current date/time is outside of the valid
range. The key validity range is specified with the tags
Tag::ACTIVE_DATETIME,
Tag::ORIGINATION_EXPIRE_DATETIME, and
Tag::USAGE_EXPIRE_DATETIME. The distinction between
"origination" and "usage" is based on whether the key is being used to
"originate" a new ciphertext/signature/etc., or to "use" an existing
ciphertext/signature/etc. Note that this distinction isn't exposed to
apps.
The Tag::ACTIVE_DATETIME,
Tag::ORIGINATION_EXPIRE_DATETIME,
and Tag::USAGE_EXPIRE_DATETIME tags are optional. If the tags
are absent, it is assumed that the key in
question can always be used to decrypt/verify messages.
Because wall-clock time is provided by the non-secure world, the expiration-related tags are in the software-enforced list.
Root of trust binding
Keystore requires keys to be bound to a root of trust, which is a bitstring provided to the KeyMint secure hardware during startup, preferably by the bootloader. This bitstring is cryptographically bound to every key managed by KeyMint.
The root of trust consists of the hash of the public key used to verify the signature on the boot image and the lock state of the device. If the public key is changed to allow a different system image to be used or if the lock state is changed, then none of the KeyMint-protected keys created by the previous system are usable unless the previous root of trust is restored and a system that is signed by that key is booted. The goal is to increase the value of the software-enforced key access controls by making it impossible for an attacker-installed operating system to use KeyMint keys.
Random number generator re-seeding
Because secure hardware generates random numbers for key material and initialization vectors (IVs), and because hardware random number generators might not always be fully trustworthy, the KeyMint HAL provides an interface to allow Keystore to provide additional entropy, which is mixed into the random numbers generated.
Use a hardware random-number generator as the primary seed source. The seed data provided through the external API can't be the sole source of randomness used for number generation. Further, the mixing operation used needs to ensure that the random output is unpredictable if any one of the seed sources is unpredictable.