diff --git a/keymaster/4.0/IKeymasterDevice.hal b/keymaster/4.0/IKeymasterDevice.hal
new file mode 100644
index 0000000..06b4b73
--- /dev/null
+++ b/keymaster/4.0/IKeymasterDevice.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 IKeymasterDevice {
+
+    /**
+     * 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);
+};
