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. Developers seeking the Android-specific extensions should go to android.security.keystore.
Before Android 6.0, Android already had a simple, hardware-backed crypto 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 cannot easily be achieved with only a signature API. Keystore in Android 6.0 extends the Keystore API to provide a broader range of capabilities.
In Android 6.0, Keystore 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 authenticated, and only for specified purposes or with specified cryptographic parameters. For more information, see the Authorization Tags and Functions pages.
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 operating system and patch level version. This ensures that an attacker who discovers a weakness in an old version of system or TEE software cannot 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.
In Android 8.0, Keymaster 3 transitioned from the old-style C-structure Hardware Abstraction Layer (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. See the Functions page for more details.
In addition to this interface revision, Android 8.0 extends Keymaster 2's attestation feature 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 / MEID). To implement this addition, change 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.
The Android Keystore API and the underlying Keymaster HAL provides a basic but adequate set of cryptographic primitives to allow the implementation of protocols using access-controlled, hardware-backed keys.
In addition to expanding the range of cryptographic primitives, Keystore in Android 6.0 adds 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
The Keymaster HAL is an OEM-provided, dynamically-loadable library used by the Keystore service to provide hardware-backed cryptographic services. To keep things secure, HAL implementations don't perform any sensitive operations in user space, or even in kernel space. Sensitive operations are delegated to a secure processor reached through some kernel interface. The resulting architecture looks like this:
Within an Android device, the "client" of the Keymaster HAL consists of multiple layers (e.g. app, framework, Keystore daemon), but that can be ignored for the purposes of this document. This means that the described Keymaster HAL API is low-level, used by platform-internal components, and not exposed to app developers. The higher-level API, for API level 23, is described on the Android Developer site.
The purpose of the Keymaster HAL is not to implement the security-sensitive algorithms but only to marshal and unmarshal requests to the secure world. The wire format is implementation-defined.
Compatibility with previous versions
The Keymaster 1 HAL is completely incompatible with the previously-released HALs, e.g. Keymaster 0.2 and 0.3. To facilitate interoperability on devices running Android 5.0 and earlier that launched with the older Keymaster HALs, Keystore provides an adapter that implements the Keymaster 1 HAL with calls to the existing hardware library. The result cannot provide the full range of functionality in the Keymaster 1 HAL. In particular, it only supports RSA and ECDSA algorithms, and all of the key authorization enforcement is performed by the adapter, in the non-secure world.
Keymaster 2 further simplified the HAL interface by removing the
methods and allowing the
finish() method to accept input. This reduces the
number of round trips to the TEE in cases where the input is available all at
once, and simplifies implementation of AEAD decryption.
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). A new-style HAL
implementation is created by subclassing the generated
IKeymasterDevice class and implementing the pure virtual
methods. As part of the change, many of the argument types have changed,
though types and methods have a one-to-one correspondence with the old
types and the HAL struct methods.
The Hardware Interface Definition Language (HIDL) provides an implementation language-independent mechanism for specifying hardware interfaces. The HIDL tooling currently supports generation of C++ and Java interfaces. It's expected that most Trusted Execution Environment (TEE) implementers will find the C++ tooling more convenient, so this document discusses only the C++ representation.
HIDL interfaces consist of a set of methods, expressed as:
methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);
There are various pre-defined types, and HALs can define new enumerated and structure types. For more details on HIDL, see the Reference section.
An example method from the Keymaster 3
generateKey(vec<KeyParameter> keyParams) generates(ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
This is the equivalent of the following from the keymaster2 HAL.:
keymaster_error_t (*generate_key)( const struct keymaster2_device* dev, const keymaster_key_param_set_t* params, keymaster_key_blob_t* key_blob, keymaster_key_characteristics_t* characteristics);
In the HIDL version, the
dev argument is removed, because it's
params argument is no longer a struct containing a
pointer referencing an array of
key_parameter_t objects, but a
vec (vector) containing
KeyParameter objects. The
return values are listed in the "
generates" clause, including a
uint8_t values for the key blob.
The C++ virtual method generated by the HIDL compiler is:
Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams, generateKey_cb _hidl_cb) override;
generate_cb is a function pointer defined as:
std::function<void(ErrorCode error, const hidl_vec<uint8_t>& keyBlob, const KeyCharacteristics& keyCharacteristics)>
generate_cb is a function that takes the return values
listed in the generate clause. The HAL implementation class overrides this
generateKey method and calls the
pointer to return the result of the operation to the caller. Note the function
pointer call is synchronous. The caller calls
generateKey calls the supplied
function pointer, which executes to completion, returning control to the
generateKey implementation, which then returns to the caller.
For a detailed example, see the default implementation in
The default implementation provides backward compatibility for devices with
old-style keymaster0, keymaster1, or keymaster2 HALS.