Add Keymaster V4.0
This CL merely duplicates all of the Keymaster V3.0 functionality and
VTS tests, and provides a pure software implementation of the 4.0 HAL,
which passes the VTS tests. Future CLs will remove some cruft and
unused features, then add new features and accompanying tests.
Note that the reason that this is V4.0 rather than V3.1 is because V4.0
will not be fully backward compatible with V3.0. Specifically, V4.0
will allow for "StrongBox" implementations, which will only provide a
subset of Keymaster functionality. StrongBox versions of Keymaster will
be implemented in discrete, special-purpose hardware which will
generally be much less powerful (slower, less RAM, etc.) than is needed
to support a full Keymaster implementation.
So, while the V4.0 interface will be a strict superset of the V3.0
interface, which could normally be best implemented as an extension, it
will allow StrongBox implementations which are unable to pass the V3.0
test suite, which means that it will not be true that a V4.0
impementation IS-A V3.0 implementation, as would be expected of a V3.1
implementation. The V4.0 test suite will distinguish between StrongBox
and non-StrongBox implementations and enforce appropriately-reduced
requirements on the former.
In addition to the duplication, 4.0 also cleans up some cruft from 3.0:
- Removes tags and types which were in previous versions but never
used;
- Removes support for wrapping pre-Treble keymaster HALs with KM4,
since they'll only be wrapped by the default KM3 implementation;
- Renames the ROLLBACK_RESISTANT tag to ROLLBACK_RESISTANCE and
defines new semantics for it;
- Changes auth token handling to use the HardwareAuthToken struct
passed in as an explicit argument to the relevant methods,
rather than an opaque byte vector provided as a KeyParameter;
- Updates the VTS tests to use a gtest "environment" for better
integration with VTS test infrastructure;
- Adds a test for upgradeKey.
- Makes comment formatting more consistent, including using the
correct two-space typographical convention to separate sentences.
Bug: 63931634
Test: VtsHalKeymasterV4_0TargetTest
Change-Id: I3f01a4991beaa5c4332f72c91e8878a3bf0dec67
diff --git a/keymaster/4.0/IKeymaster.hal b/keymaster/4.0/IKeymaster.hal
new file mode 100644
index 0000000..b841832
--- /dev/null
+++ b/keymaster/4.0/IKeymaster.hal
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 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.
+ */
+
+package android.hardware.keymaster@4.0;
+
+import android.hardware.keymaster@3.0::ErrorCode;
+import android.hardware.keymaster@3.0::KeyFormat;
+
+/**
+ * Keymaster device definition. For thorough documentation see the implementer's reference, at
+ * https://source.android.com/security/keystore/implementer-ref.html
+ */
+interface IKeymaster {
+
+ /**
+ * Returns information about the underlying keymaster hardware.
+ *
+ * @return isSecure Indicates whether this keymaster implementation is in some sort of secure
+ * hardware.
+ *
+ * @return keymasterName is the name of the keymaster implementation.
+ *
+ * @return keymasterAuthorName is the name of the author of the keymaster implementation
+ * (organization name, not individual).
+ */
+ getHardwareInfo() generates (bool isSecure, string keymasterName, string keymasterAuthorName);
+
+ /**
+ * Adds entropy to the RNG used by keymaster. Entropy added through this method must not be the
+ * only source of entropy used. The keymaster implementation must securely mix entropy provided
+ * through this method with internally-generated entropy.
+ *
+ * @param data Bytes to be mixed into the RNG.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ */
+ addRngEntropy(vec<uint8_t> data) generates (ErrorCode error);
+
+ /**
+ * Generates a key, or key pair, returning a key blob and a description of the key.
+ *
+ * @param keyParams Key generation parameters are defined as keymaster tag/value pairs, provided
+ * in params. See Tag in types.hal for the full list.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return keyBlob Opaque, encrypted descriptor of the generated key. A recommended
+ * implementation strategy is to include an encrypted copy of the key material, wrapped
+ * in a key unavailable outside secure hardware.
+ *
+ * @return keyCharacteristics Description of the generated key. See KeyCharacteristis in
+ * types.hal.
+ */
+ generateKey(vec<KeyParameter> keyParams)
+ generates (ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
+
+ /**
+ * Imports a key, or key pair, returning a key blob and/or a description of the key.
+ *
+ * @param keyParams Key generation parameters are defined as keymaster tag/value pairs, provided
+ * in params. See Tag for the full list.
+ *
+ * @param keyFormat The format of the key material to import.
+ *
+ * @pram keyData The key material to import, in the format specifed in keyFormat.
+ *
+ * @return error See the ErrorCode enum.
+ *
+ * @return keyBlob Opaque, encrypted descriptor of the generated key, which will generally
+ * contain a copy of the key material, wrapped in a key unavailable outside secure
+ * hardware.
+ *
+ * @return keyCharacteristics Decription of the generated key.
+ */
+ importKey(vec<KeyParameter> keyParams, KeyFormat keyFormat, vec<uint8_t> keyData)
+ generates (ErrorCode error, vec<uint8_t> keyBlob, KeyCharacteristics keyCharacteristics);
+
+ /**
+ * Returns the characteristics of the specified key, if the keyBlob is valid (implementations
+ * must fully validate the integrity of the key).
+ *
+ * @param keyBlob The opaque descriptor returned by generateKey() or importKey();
+ *
+ * @param clientId An opaque byte string identifying the client. This value must match the
+ * Tag::APPLICATION_ID data provided during key generation/import. Without the correct
+ * value, it must be computationally infeasible for the secure hardware to obtain the key
+ * material.
+ *
+ * @param appData An opaque byte string provided by the application. This value must match the
+ * Tag::APPLICATION_DATA data provided during key generation/import. Without the correct
+ * value, it must be computationally infeasible for the secure hardware to obtain the key
+ * material.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return keyCharacteristics Decription of the generated key. See KeyCharacteristis in
+ * types.hal.
+ */
+ getKeyCharacteristics(vec<uint8_t> keyBlob, vec<uint8_t> clientId, vec<uint8_t> appData)
+ generates (ErrorCode error, KeyCharacteristics keyCharacteristics);
+
+ /**
+ * Exports a public key, returning the key in the specified format.
+ *
+ * @parm keyFormat The format used for export. See KeyFormat in types.hal.
+ *
+ * @param keyBlob The opaque descriptor returned by generateKey() or importKey(). The
+ * referenced key must be asymmetric.
+ *
+ * @param clientId An opaque byte string identifying the client. This value must match the
+ * Tag::APPLICATION_ID data provided during key generation/import. Without the correct
+ * value, it must be computationally infeasible for the secure hardware to obtain the key
+ * material.
+ *
+ * @param appData An opaque byte string provided by the application. This value must match the
+ * Tag::APPLICATION_DATA data provided during key generation/import. Without the correct
+ * value, it must be computationally infeasible for the secure hardware to obtain the key
+ * material.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return keyMaterial The public key material in PKCS#8 format.
+ */
+ exportKey(KeyFormat keyFormat, vec<uint8_t> keyBlob, vec<uint8_t> clientId,
+ vec<uint8_t> appData) generates (ErrorCode error, vec<uint8_t> keyMaterial);
+
+ /**
+ * Generates a signed X.509 certificate chain attesting to the presence of keyToAttest in
+ * keymaster. The certificate must contain an extension with OID 1.3.6.1.4.1.11129.2.1.17 and
+ * value defined in:
+ *
+ * https://developer.android.com/training/articles/security-key-attestation.html.
+ *
+ * @param keyToAttest The opaque descriptor returned by generateKey() or importKey(). The
+ * referenced key must be asymmetric.
+ *
+ * @param attestParams Parameters for the attestation, notably Tag::ATTESTATION_CHALLENGE.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return certChain The attestation certificate, and additional certificates back to the root
+ * attestation certificate, which clients will need to check against a known-good value.
+ */
+ attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
+ generates (ErrorCode error, vec<vec<uint8_t>> certChain);
+
+ /**
+ * Upgrades an old key blob. Keys can become "old" in two ways: Keymaster can be upgraded to a
+ * new version with an incompatible key blob format, or the system can be updated to invalidate
+ * the OS version and/or patch level. In either case, attempts to use an old key blob with
+ * getKeyCharacteristics(), exportKey(), attestKey() or begin() must result in keymaster
+ * returning ErrorCode::KEY_REQUIRES_UPGRADE. The caller must use this method to upgrade the
+ * key blob.
+ *
+ * @param keyBlobToUpgrade The opaque descriptor returned by generateKey() or importKey();
+ *
+ * @param upgradeParams A parameter list containing any parameters needed to complete the
+ * upgrade, including Tag::APPLICATION_ID and Tag::APPLICATION_DATA.
+ *
+ * @return error See the ErrorCode enum.
+ *
+ * @return upgradedKeyBlob A new key blob that references the same key as keyBlobToUpgrade, but
+ * is in the new format, or has the new version data.
+ */
+ upgradeKey(vec<uint8_t> keyBlobToUpgrade, vec<KeyParameter> upgradeParams)
+ generates (ErrorCode error, vec<uint8_t> upgradedKeyBlob);
+
+ /**
+ * Deletes the key, or key pair, associated with the key blob. Calling this function on a key
+ * with Tag::ROLLBACK_RESISTANCE in its hardware-enforced authorization list must render the key
+ * permanently unusable. Keys without Tag::ROLLBACK_RESISTANCE may or may not be rendered
+ * unusable.
+ *
+ * @param keyBlob The opaque descriptor returned by generateKey() or importKey();
+ *
+ * @return error See the ErrorCode enum.
+ */
+ deleteKey(vec<uint8_t> keyBlob) generates (ErrorCode error);
+
+ /**
+ * Deletes all keys in the hardware keystore. Used when keystore is reset completely. After
+ * this function is called all keys with Tag::ROLLBACK_RESISTANCE in their hardware-enforced
+ * authorization lists must be rendered permanently unusable. Keys without
+ * Tag::ROLLBACK_RESISTANCE may or may not be rendered unusable.
+ *
+ * @return error See the ErrorCode enum.
+ */
+ deleteAllKeys() generates (ErrorCode error);
+
+ /**
+ * Destroys knowledge of the device's ids. This prevents all device id attestation in the
+ * future. The destruction must be permanent so that not even a factory reset will restore the
+ * device ids.
+ *
+ * Device id attestation may be provided only if this method is fully implemented, allowing the
+ * user to permanently disable device id attestation. If this cannot be guaranteed, the device
+ * must never attest any device ids.
+ *
+ * This is a NOP if device id attestation is not supported.
+ *
+ * @return error See the ErrorCode enum.
+ */
+ destroyAttestationIds() generates (ErrorCode error);
+
+ /**
+ * Begins a cryptographic operation using the specified key. If all is well, begin() must
+ * return ErrorCode::OK and create an operation handle which must be passed to subsequent calls
+ * to update(), finish() or abort().
+ *
+ * It is critical that each call to begin() be paired with a subsequent call to finish() or
+ * abort(), to allow the keymaster implementation to clean up any internal operation state. The
+ * caller's failure to do this may leak internal state space or other internal resources and may
+ * eventually cause begin() to return ErrorCode::TOO_MANY_OPERATIONS when it runs out of space
+ * for operations. Any result other than ErrorCode::OK from begin(), update() or finish()
+ * implicitly aborts the operation, in which case abort() need not be called (and must return
+ * ErrorCode::INVALID_OPERATION_HANDLE if called).
+ *
+ * @param purpose The purpose of the operation, one of KeyPurpose::ENCRYPT, KeyPurpose::DECRYPT,
+ * KeyPurpose::SIGN or KeyPurpose::VERIFY. Note that for AEAD modes, encryption and
+ * decryption imply signing and verification, respectively, but must be specified as
+ * KeyPurpose::ENCRYPT and KeyPurpose::DECRYPT.
+ *
+ * @param keyBlob The opaque key descriptor returned by generateKey() or importKey(). The key
+ * must have a purpose compatible with purpose and all of its usage requirements must be
+ * satisfied, or begin() must return an appropriate error code.
+ *
+ * @param inParams Additional parameters for the operation. If Tag::APPLICATION_ID or
+ * Tag::APPLICATION_DATA were provided during generation, they must be provided here, or
+ * the operation must fail with ErrorCode::INVALID_KEY_BLOB. For operations that require
+ * a nonce or IV, on keys that were generated with Tag::CALLER_NONCE, inParams may
+ * contain a tag Tag::NONCE. If Tag::NONCE is provided for a key without
+ * Tag:CALLER_NONCE, ErrorCode::CALLER_NONCE_PROHIBITED must be returned.
+ *
+ * @param authToken Authentication token. Callers that provide no token must set all numeric
+ * fields to zero and the MAC must be an empty vector.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return outParams Output parameters. Used to return additional data from the operation
+ * initialization, notably to return the IV or nonce from operations that generate an IV
+ * or nonce.
+ *
+ * @return operationHandle The newly-created operation handle which must be passed to update(),
+ * finish() or abort().
+ */
+ begin(KeyPurpose purpose, vec<uint8_t> keyBlob, vec<KeyParameter> inParams,
+ HardwareAuthToken authToken)
+ generates (ErrorCode error, vec<KeyParameter> outParams, OperationHandle operationHandle);
+
+ /**
+ * Provides data to, and possibly receives output from, an ongoing cryptographic operation begun
+ * with begin().
+ *
+ * If operationHandle is invalid, update() must return ErrorCode::INVALID_OPERATION_HANDLE.
+ *
+ * update() may not consume all of the data provided in the data buffer. update() must return
+ * the amount consumed in inputConsumed. The caller may provide the unconsumed data in a
+ * subsequent call.
+ *
+ * @param operationHandle The operation handle returned by begin().
+ *
+ * @param inParams Additional parameters for the operation. For AEAD modes, this is used to
+ * specify Tag::ADDITIONAL_DATA. Note that additional data may be provided in multiple
+ * calls to update(), but only until input data has been provided.
+ *
+ * @param input Data to be processed. Note that update() may or may not consume all of the data
+ * provided. See inputConsumed.
+ *
+ * @param authToken Authentication token. Callers that provide no token must set all numeric
+ * fields to zero and the MAC must be an empty vector.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return inputConsumed Amount of data that was consumed by update(). If this is less than the
+ * amount provided, the caller may provide the remainder in a subsequent call to
+ * update() or finish(). Every call to update must consume at least one byte, and
+ * implementations should consume as much data as reasonably possible for each call.
+ *
+ * @return outParams Output parameters, used to return additional data from the operation.
+ *
+ * @return output The output data, if any.
+ */
+ update(OperationHandle operationHandle, vec<KeyParameter> inParams, vec<uint8_t> input,
+ HardwareAuthToken authToken)
+ generates (ErrorCode error, uint32_t inputConsumed, vec<KeyParameter> outParams,
+ vec<uint8_t> output);
+
+ /**
+ * Finalizes a cryptographic operation begun with begin() and invalidates operationHandle.
+ *
+ * @param operationHandle The operation handle returned by begin(). This handle must be invalid
+ * when finish() returns.
+ *
+ * @param inParams Additional parameters for the operation. For AEAD modes, this is used to
+ * specify Tag::ADDITIONAL_DATA, but only if no input data was provided to update().
+ *
+ * @param input Data to be processed, per the parameters established in the call to begin().
+ * finish() must consume all provided data or return ErrorCode::INVALID_INPUT_LENGTH.
+ *
+ * @param signature The signature to be verified if the purpose specified in the begin() call
+ * was KeyPurpose::VERIFY.
+ *
+ * @param authToken Authentication token. Callers that provide no token must set all numeric
+ * fields to zero and the MAC must be an empty vector.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ *
+ * @return outParams Any output parameters generated by finish().
+ *
+ * @return output The output data, if any.
+ */
+ finish(OperationHandle operationHandle, vec<KeyParameter> inParams, vec<uint8_t> input,
+ vec<uint8_t> signature, HardwareAuthToken authToken)
+ generates (ErrorCode error, vec<KeyParameter> outParams, vec<uint8_t> output);
+
+ /**
+ * Aborts a cryptographic operation begun with begin(), freeing all internal resources and
+ * invalidating operationHandle.
+ *
+ * @param operationHandle The operation handle returned by begin(). This handle must be
+ * invalid when abort() returns.
+ *
+ * @return error See the ErrorCode enum in types.hal.
+ */
+ abort(OperationHandle operationHandle) generates (ErrorCode error);
+};