Move Keymaster wrapper into support library.

This wrapper was used to manage KM3/KM4 compatibility in keystore.
It's also needed in vold, so this CL moves it here, to make it usable
for vold.

Test: keystore CTS tests
Change-Id: I8079b8577f7d4a8fd67f47fbe1f48861e4a0734b
diff --git a/keymaster/4.0/support/Android.bp b/keymaster/4.0/support/Android.bp
index 748fed3..d5c0b5e 100644
--- a/keymaster/4.0/support/Android.bp
+++ b/keymaster/4.0/support/Android.bp
@@ -26,11 +26,17 @@
         "attestation_record.cpp",
         "authorization_set.cpp",
         "key_param_output.cpp",
+        "Keymaster3.cpp",
+        "Keymaster4.cpp",
     ],
     export_include_dirs: ["include"],
     shared_libs: [
+        "android.hardware.keymaster@3.0",
         "android.hardware.keymaster@4.0",
+        "libbase",
         "libcrypto",
         "libhidlbase",
+        "libhidltransport",
+        "libutils",
     ]
 }
diff --git a/keymaster/4.0/support/Keymaster3.cpp b/keymaster/4.0/support/Keymaster3.cpp
new file mode 100644
index 0000000..6dfe85b
--- /dev/null
+++ b/keymaster/4.0/support/Keymaster3.cpp
@@ -0,0 +1,325 @@
+/*
+ **
+ ** Copyright 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.
+ */
+
+#include <keymasterV4_0/Keymaster3.h>
+
+#include <android-base/logging.h>
+#include <hardware/hw_auth_token.h>
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace support {
+
+using android::hardware::details::StatusOf;
+
+namespace {
+
+ErrorCode convert(V3_0::ErrorCode error) {
+    return static_cast<ErrorCode>(error);
+}
+
+V3_0::KeyPurpose convert(KeyPurpose purpose) {
+    return static_cast<V3_0::KeyPurpose>(purpose);
+}
+
+V3_0::KeyFormat convert(KeyFormat purpose) {
+    return static_cast<V3_0::KeyFormat>(purpose);
+}
+
+V3_0::KeyParameter convert(const KeyParameter& param) {
+    V3_0::KeyParameter converted;
+    converted.tag = static_cast<V3_0::Tag>(param.tag);
+    static_assert(sizeof(converted.f) == sizeof(param.f), "This function assumes sizes match");
+    memcpy(&converted.f, &param.f, sizeof(param.f));
+    converted.blob = param.blob;
+    return converted;
+}
+
+KeyParameter convert(const V3_0::KeyParameter& param) {
+    KeyParameter converted;
+    converted.tag = static_cast<Tag>(param.tag);
+    static_assert(sizeof(converted.f) == sizeof(param.f), "This function assumes sizes match");
+    memcpy(&converted.f, &param.f, sizeof(param.f));
+    converted.blob = param.blob;
+    return converted;
+}
+
+hidl_vec<V3_0::KeyParameter> convert(const hidl_vec<KeyParameter>& params) {
+    hidl_vec<V3_0::KeyParameter> converted(params.size());
+    for (size_t i = 0; i < params.size(); ++i) {
+        converted[i] = convert(params[i]);
+    }
+    return converted;
+}
+
+hidl_vec<KeyParameter> convert(const hidl_vec<V3_0::KeyParameter>& params) {
+    hidl_vec<KeyParameter> converted(params.size());
+    for (size_t i = 0; i < params.size(); ++i) {
+        converted[i] = convert(params[i]);
+    }
+    return converted;
+}
+
+template <typename T, typename OutIter>
+inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) {
+    const uint8_t* value_ptr = reinterpret_cast<const uint8_t*>(&value);
+    return std::copy(value_ptr, value_ptr + sizeof(value), dest);
+}
+
+constexpr size_t kHmacSize = 32;
+
+inline static hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) {
+    static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
+                          sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
+                          sizeof(token.timestamp) + kHmacSize ==
+                      sizeof(hw_auth_token_t),
+                  "HardwareAuthToken content size does not match hw_auth_token_t size");
+
+    hidl_vec<uint8_t> result;
+    result.resize(sizeof(hw_auth_token_t));
+    auto pos = result.begin();
+    *pos++ = 0;  // Version byte
+    pos = copy_bytes_to_iterator(token.challenge, pos);
+    pos = copy_bytes_to_iterator(token.userId, pos);
+    pos = copy_bytes_to_iterator(token.authenticatorId, pos);
+    auto auth_type = htonl(static_cast<uint32_t>(token.authenticatorType));
+    pos = copy_bytes_to_iterator(auth_type, pos);
+    auto timestamp = htonq(token.timestamp);
+    pos = copy_bytes_to_iterator(timestamp, pos);
+    if (token.mac.size() != kHmacSize) {
+        std::fill(pos, pos + kHmacSize, 0);
+    } else {
+        std::copy(token.mac.begin(), token.mac.end(), pos);
+    }
+
+    return result;
+}
+
+hidl_vec<V3_0::KeyParameter> convertAndAddAuthToken(const hidl_vec<KeyParameter>& params,
+                                                    const HardwareAuthToken& authToken) {
+    hidl_vec<V3_0::KeyParameter> converted(params.size() + 1);
+    for (size_t i = 0; i < params.size(); ++i) {
+        converted[i] = convert(params[i]);
+    }
+    converted[params.size()].tag = V3_0::Tag::AUTH_TOKEN;
+    converted[params.size()].blob = authToken2HidlVec(authToken);
+
+    return converted;
+}
+
+KeyCharacteristics convert(const V3_0::KeyCharacteristics& chars) {
+    KeyCharacteristics converted;
+    converted.hardwareEnforced = convert(chars.teeEnforced);
+    converted.softwareEnforced = convert(chars.softwareEnforced);
+    return converted;
+}
+
+}  // namespace
+
+void Keymaster3::getVersionIfNeeded() {
+    if (haveVersion_) return;
+
+    auto rc = km3_dev_->getHardwareFeatures(
+        [&](bool isSecure, bool supportsEllipticCurve, bool supportsSymmetricCryptography,
+            bool supportsAttestation, bool supportsAllDigests, const hidl_string& keymasterName,
+            const hidl_string& keymasterAuthorName) {
+            securityLevel_ =
+                isSecure ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE;
+            supportsEllipticCurve_ = supportsEllipticCurve;
+            supportsSymmetricCryptography_ = supportsSymmetricCryptography;
+            supportsAttestation_ = supportsAttestation;
+            supportsAllDigests_ = supportsAllDigests;
+            keymasterName_ = keymasterName;
+            authorName_ = keymasterAuthorName;
+        });
+
+    CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware features";
+
+    if (securityLevel_ == SecurityLevel::SOFTWARE) {
+        majorVersion_ = 3;
+    } else if (supportsAttestation_) {
+        majorVersion_ = 3;  // Could be 2, doesn't matter.
+    } else if (supportsSymmetricCryptography_) {
+        majorVersion_ = 1;
+    } else {
+        majorVersion_ = 0;
+    }
+}
+
+Keymaster::VersionResult Keymaster3::halVersion() {
+    getVersionIfNeeded();
+    return {ErrorCode::OK, majorVersion_, securityLevel_, supportsEllipticCurve_};
+}
+
+Return<void> Keymaster3::getHardwareInfo(Keymaster3::getHardwareInfo_cb _hidl_cb) {
+    getVersionIfNeeded();
+    _hidl_cb(securityLevel_, keymasterName_ + " (wrapped by keystore::Keymaster3)", authorName_);
+    return Void();
+}
+
+Return<ErrorCode> Keymaster3::addRngEntropy(const hidl_vec<uint8_t>& data) {
+    auto rc = km3_dev_->addRngEntropy(data);
+    if (!rc.isOk()) {
+        return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
+    }
+    return convert(rc);
+}
+
+Return<void> Keymaster3::generateKey(const hidl_vec<KeyParameter>& keyParams,
+                                     generateKey_cb _hidl_cb) {
+    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
+                  const V3_0::KeyCharacteristics& characteristics) {
+        _hidl_cb(convert(error), keyBlob, convert(characteristics));
+    };
+    auto rc = km3_dev_->generateKey(convert(keyParams), cb);
+    rc.isOk();  // move ctor prereq
+    return rc;
+}
+
+Return<void> Keymaster3::getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+                                               const hidl_vec<uint8_t>& clientId,
+                                               const hidl_vec<uint8_t>& appData,
+                                               getKeyCharacteristics_cb _hidl_cb) {
+    auto cb = [&](V3_0::ErrorCode error, const V3_0::KeyCharacteristics& chars) {
+        _hidl_cb(convert(error), convert(chars));
+    };
+
+    auto rc = km3_dev_->getKeyCharacteristics(keyBlob, clientId, appData, cb);
+    rc.isOk();  // move ctor prereq
+    return rc;
+}
+
+Return<void> Keymaster3::importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+                                   const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) {
+    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
+                  const V3_0::KeyCharacteristics& chars) {
+        _hidl_cb(convert(error), keyBlob, convert(chars));
+    };
+    auto rc = km3_dev_->importKey(convert(params), convert(keyFormat), keyData, cb);
+    rc.isOk();  // move ctor prereq
+    return rc;
+}
+
+Return<void> Keymaster3::exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+                                   const hidl_vec<uint8_t>& clientId,
+                                   const hidl_vec<uint8_t>& appData, exportKey_cb _hidl_cb) {
+    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& keyMaterial) {
+        _hidl_cb(convert(error), keyMaterial);
+    };
+    auto rc = km3_dev_->exportKey(convert(exportFormat), keyBlob, clientId, appData, cb);
+    rc.isOk();  // move ctor prereq
+    return rc;
+}
+
+Return<void> Keymaster3::attestKey(const hidl_vec<uint8_t>& keyToAttest,
+                                   const hidl_vec<KeyParameter>& attestParams,
+                                   attestKey_cb _hidl_cb) {
+    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
+        _hidl_cb(convert(error), certChain);
+    };
+    auto rc = km3_dev_->attestKey(keyToAttest, convert(attestParams), cb);
+    rc.isOk();  // move ctor prereq
+    return rc;
+}
+
+Return<void> Keymaster3::upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+                                    const hidl_vec<KeyParameter>& upgradeParams,
+                                    upgradeKey_cb _hidl_cb) {
+    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<uint8_t>& upgradedKeyBlob) {
+        _hidl_cb(convert(error), upgradedKeyBlob);
+    };
+    auto rc = km3_dev_->upgradeKey(keyBlobToUpgrade, convert(upgradeParams), cb);
+    rc.isOk();  // move ctor prereq
+    return rc;
+}
+
+Return<ErrorCode> Keymaster3::deleteKey(const hidl_vec<uint8_t>& keyBlob) {
+    auto rc = km3_dev_->deleteKey(keyBlob);
+    if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
+    return convert(rc);
+}
+
+Return<ErrorCode> Keymaster3::deleteAllKeys() {
+    auto rc = km3_dev_->deleteAllKeys();
+    if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
+    return convert(rc);
+}
+
+Return<ErrorCode> Keymaster3::destroyAttestationIds() {
+    auto rc = km3_dev_->destroyAttestationIds();
+    if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
+    return convert(rc);
+}
+
+Return<void> Keymaster3::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+                               const hidl_vec<KeyParameter>& inParams,
+                               const HardwareAuthToken& authToken, begin_cb _hidl_cb) {
+    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<V3_0::KeyParameter>& outParams,
+                  OperationHandle operationHandle) {
+        _hidl_cb(convert(error), convert(outParams), operationHandle);
+    };
+
+    auto rc =
+        km3_dev_->begin(convert(purpose), key, convertAndAddAuthToken(inParams, authToken), cb);
+    rc.isOk();  // move ctor prereq
+    return rc;
+}
+
+Return<void> Keymaster3::update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+                                const hidl_vec<uint8_t>& input, const HardwareAuthToken& authToken,
+                                const VerificationToken& /* verificationToken */,
+                                update_cb _hidl_cb) {
+    auto cb = [&](V3_0::ErrorCode error, uint32_t inputConsumed,
+                  const hidl_vec<V3_0::KeyParameter>& outParams, const hidl_vec<uint8_t>& output) {
+        _hidl_cb(convert(error), inputConsumed, convert(outParams), output);
+    };
+
+    auto rc =
+        km3_dev_->update(operationHandle, convertAndAddAuthToken(inParams, authToken), input, cb);
+    rc.isOk();  // move ctor prereq
+    return rc;
+}
+
+Return<void> Keymaster3::finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+                                const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
+                                const HardwareAuthToken& authToken,
+                                const VerificationToken& /* verificationToken */,
+                                finish_cb _hidl_cb) {
+    auto cb = [&](V3_0::ErrorCode error, const hidl_vec<V3_0::KeyParameter>& outParams,
+                  const hidl_vec<uint8_t>& output) {
+        _hidl_cb(convert(error), convert(outParams), output);
+    };
+
+    auto rc = km3_dev_->finish(operationHandle, convertAndAddAuthToken(inParams, authToken), input,
+                               signature, cb);
+    rc.isOk();  // move ctor prereq
+    return rc;
+}
+
+Return<ErrorCode> Keymaster3::abort(uint64_t operationHandle) {
+    auto rc = km3_dev_->abort(operationHandle);
+    if (!rc.isOk()) return StatusOf<V3_0::ErrorCode, ErrorCode>(rc);
+    return convert(rc);
+}
+
+}  // namespace support
+}  // namespace V4_0
+}  // namespace keymaster
+}  // namespace hardware
+}  // namespace android
diff --git a/keymaster/4.0/support/Keymaster4.cpp b/keymaster/4.0/support/Keymaster4.cpp
new file mode 100644
index 0000000..fdf78ae
--- /dev/null
+++ b/keymaster/4.0/support/Keymaster4.cpp
@@ -0,0 +1,48 @@
+/*
+**
+** Copyright 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.
+*/
+
+#include <keymasterV4_0/Keymaster4.h>
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace support {
+
+void Keymaster4::getVersionIfNeeded() {
+    if (haveVersion_) return;
+
+    auto rc = dev_->getHardwareInfo([&](SecurityLevel securityLevel, auto...) {
+        securityLevel_ = securityLevel;
+        haveVersion_ = true;
+    });
+
+    CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware info";
+}
+
+Keymaster::VersionResult Keymaster4::halVersion() {
+    getVersionIfNeeded();
+    return {ErrorCode::OK, halMajorVersion(), securityLevel_, true};
+}
+
+}  // namespace support
+}  // namespace V4_0
+}  // namespace keymaster
+}  // namespace hardware
+}  // namespace android
diff --git a/keymaster/4.0/support/include/keymasterV4_0/Keymaster.h b/keymaster/4.0/support/include/keymasterV4_0/Keymaster.h
new file mode 100644
index 0000000..2686fcd
--- /dev/null
+++ b/keymaster/4.0/support/include/keymasterV4_0/Keymaster.h
@@ -0,0 +1,58 @@
+/*
+ **
+ ** Copyright 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.
+ */
+
+#ifndef HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_H_
+#define HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_H_
+
+#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace support {
+
+/**
+ * Keymaster abstracts the underlying V4_0::IKeymasterDevice.  There is one implementation
+ * (Keymaster4) which is a trivial passthrough and one that wraps a V3_0::IKeymasterDevice.
+ *
+ * The reason for adding this additional layer, rather than simply using the latest HAL directly and
+ * subclassing it to wrap any older HAL, is because this provides a place to put additional methods
+ * which clients can use when they need to distinguish between different underlying HAL versions,
+ * while still having to use only the latest interface.
+ */
+class Keymaster : public IKeymasterDevice {
+   public:
+    virtual ~Keymaster() {}
+
+    struct VersionResult {
+        ErrorCode error;
+        uint8_t majorVersion;
+        SecurityLevel securityLevel;
+        bool supportsEc;
+    };
+
+    virtual VersionResult halVersion() = 0;
+};
+
+}  // namespace support
+}  // namespace V4_0
+}  // namespace keymaster
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_H_
diff --git a/keymaster/4.0/support/include/keymasterV4_0/Keymaster3.h b/keymaster/4.0/support/include/keymasterV4_0/Keymaster3.h
new file mode 100644
index 0000000..051e570
--- /dev/null
+++ b/keymaster/4.0/support/include/keymasterV4_0/Keymaster3.h
@@ -0,0 +1,129 @@
+/*
+ **
+ ** Copyright 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.
+ */
+
+#ifndef HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_3_H_
+#define HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_3_H_
+
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+
+#include "Keymaster.h"
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace support {
+
+using IKeymaster3Device = ::android::hardware::keymaster::V3_0::IKeymasterDevice;
+
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::details::return_status;
+
+class Keymaster3 : public Keymaster {
+   public:
+    using WrappedIKeymasterDevice = IKeymaster3Device;
+    Keymaster3(sp<IKeymaster3Device> km3_dev) : km3_dev_(km3_dev), haveVersion_(false) {}
+
+    VersionResult halVersion() override;
+
+    Return<void> getHardwareInfo(getHardwareInfo_cb _hidl_cb);
+
+    Return<void> getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) override {
+        _hidl_cb(ErrorCode::UNIMPLEMENTED, {});
+        return Void();
+    }
+
+    Return<void> computeSharedHmac(const hidl_vec<HmacSharingParameters>&,
+                                   computeSharedHmac_cb _hidl_cb) override {
+        _hidl_cb(ErrorCode::UNIMPLEMENTED, {});
+        return Void();
+    }
+
+    Return<void> verifyAuthorization(uint64_t, const hidl_vec<KeyParameter>&,
+                                     const HardwareAuthToken&,
+                                     verifyAuthorization_cb _hidl_cb) override {
+        _hidl_cb(ErrorCode::UNIMPLEMENTED, {});
+        return Void();
+    }
+
+    Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override;
+    Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
+                             generateKey_cb _hidl_cb) override;
+    Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+                                       const hidl_vec<uint8_t>& clientId,
+                                       const hidl_vec<uint8_t>& appData,
+                                       getKeyCharacteristics_cb _hidl_cb) override;
+    Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+                           const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) override;
+
+    Return<void> importWrappedKey(const hidl_vec<uint8_t>&, const hidl_vec<uint8_t>&,
+                                  const hidl_vec<uint8_t>&, importWrappedKey_cb _hidl_cb) {
+        _hidl_cb(ErrorCode::UNIMPLEMENTED, {}, {});
+        return Void();
+    }
+
+    Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+                           const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
+                           exportKey_cb _hidl_cb) override;
+    Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
+                           const hidl_vec<KeyParameter>& attestParams,
+                           attestKey_cb _hidl_cb) override;
+    Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+                            const hidl_vec<KeyParameter>& upgradeParams,
+                            upgradeKey_cb _hidl_cb) override;
+    Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override;
+    Return<ErrorCode> deleteAllKeys() override;
+    Return<ErrorCode> destroyAttestationIds() override;
+    Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+                       const hidl_vec<KeyParameter>& inParams, const HardwareAuthToken& authToken,
+                       begin_cb _hidl_cb) override;
+    Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+                        const hidl_vec<uint8_t>& input, const HardwareAuthToken& authToken,
+                        const VerificationToken& verificationToken, update_cb _hidl_cb) override;
+    Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+                        const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
+                        const HardwareAuthToken& authToken,
+                        const VerificationToken& verificationToken, finish_cb _hidl_cb) override;
+    Return<ErrorCode> abort(uint64_t operationHandle) override;
+
+   private:
+    void getVersionIfNeeded();
+
+    sp<IKeymaster3Device> km3_dev_;
+
+    bool haveVersion_;
+    uint8_t majorVersion_;
+    SecurityLevel securityLevel_;
+    bool supportsEllipticCurve_;
+    bool supportsSymmetricCryptography_;
+    bool supportsAttestation_;
+    bool supportsAllDigests_;
+    std::string keymasterName_;
+    std::string authorName_;
+};
+
+}  // namespace support
+}  // namespace V4_0
+}  // namespace keymaster
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_3_H_
diff --git a/keymaster/4.0/support/include/keymasterV4_0/Keymaster4.h b/keymaster/4.0/support/include/keymasterV4_0/Keymaster4.h
new file mode 100644
index 0000000..ffddcac
--- /dev/null
+++ b/keymaster/4.0/support/include/keymasterV4_0/Keymaster4.h
@@ -0,0 +1,153 @@
+/*
+ **
+ ** Copyright 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.
+ */
+
+#ifndef HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_4_H_
+#define HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_4_H_
+
+#include "Keymaster.h"
+
+namespace android {
+namespace hardware {
+namespace keymaster {
+namespace V4_0 {
+namespace support {
+
+using android::sp;
+using IKeymaster4Device = ::android::hardware::keymaster::V4_0::IKeymasterDevice;
+
+class Keymaster4 : public Keymaster {
+   public:
+    using WrappedIKeymasterDevice = IKeymaster4Device;
+    Keymaster4(sp<IKeymasterDevice> km4_dev) : haveVersion_(false), dev_(km4_dev) {}
+
+    uint8_t halMajorVersion() { return 4; }
+
+    VersionResult halVersion() override;
+
+    Return<void> getHardwareInfo(getHardwareInfo_cb _hidl_cb) override {
+        return dev_->getHardwareInfo(_hidl_cb);
+    }
+
+    Return<void> getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) override {
+        return dev_->getHmacSharingParameters(_hidl_cb);
+    }
+
+    Return<void> computeSharedHmac(const hidl_vec<HmacSharingParameters>& params,
+                                   computeSharedHmac_cb _hidl_cb) override {
+        return dev_->computeSharedHmac(params, _hidl_cb);
+    }
+
+    Return<void> verifyAuthorization(uint64_t operationHandle, const hidl_vec<KeyParameter>& params,
+                                     const HardwareAuthToken& authToken,
+                                     verifyAuthorization_cb _hidl_cb) override {
+        return dev_->verifyAuthorization(operationHandle, params, authToken, _hidl_cb);
+    }
+
+    Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override {
+        return dev_->addRngEntropy(data);
+    }
+
+    Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
+                             generateKey_cb _hidl_cb) override {
+        return dev_->generateKey(keyParams, _hidl_cb);
+    }
+
+    Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+                                       const hidl_vec<uint8_t>& clientId,
+                                       const hidl_vec<uint8_t>& appData,
+                                       getKeyCharacteristics_cb _hidl_cb) override {
+        return dev_->getKeyCharacteristics(keyBlob, clientId, appData, _hidl_cb);
+    }
+
+    Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+                           const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) override {
+        return dev_->importKey(params, keyFormat, keyData, _hidl_cb);
+    }
+
+    Return<void> importWrappedKey(const hidl_vec<uint8_t>& wrappedKeyData,
+                                  const hidl_vec<uint8_t>& wrappingKeyBlob,
+                                  const hidl_vec<uint8_t>& maskingKey,
+                                  importWrappedKey_cb _hidl_cb) {
+        return dev_->importWrappedKey(wrappedKeyData, wrappingKeyBlob, maskingKey, _hidl_cb);
+    }
+
+    Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+                           const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
+                           exportKey_cb _hidl_cb) override {
+        return dev_->exportKey(exportFormat, keyBlob, clientId, appData, _hidl_cb);
+    }
+
+    Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
+                           const hidl_vec<KeyParameter>& attestParams,
+                           attestKey_cb _hidl_cb) override {
+        return dev_->attestKey(keyToAttest, attestParams, _hidl_cb);
+    }
+
+    Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+                            const hidl_vec<KeyParameter>& upgradeParams,
+                            upgradeKey_cb _hidl_cb) override {
+        return dev_->upgradeKey(keyBlobToUpgrade, upgradeParams, _hidl_cb);
+    }
+
+    Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override {
+        return dev_->deleteKey(keyBlob);
+    }
+
+    Return<ErrorCode> deleteAllKeys() override { return dev_->deleteAllKeys(); }
+
+    Return<ErrorCode> destroyAttestationIds() override { return dev_->destroyAttestationIds(); }
+
+    Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+                       const hidl_vec<KeyParameter>& inParams, const HardwareAuthToken& authToken,
+                       begin_cb _hidl_cb) override {
+        return dev_->begin(purpose, key, inParams, authToken, _hidl_cb);
+    }
+
+    Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+                        const hidl_vec<uint8_t>& input, const HardwareAuthToken& authToken,
+                        const VerificationToken& verificationToken, update_cb _hidl_cb) override {
+        return dev_->update(operationHandle, inParams, input, authToken, verificationToken,
+                            _hidl_cb);
+    }
+
+    Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+                        const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
+                        const HardwareAuthToken& authToken,
+                        const VerificationToken& verificationToken, finish_cb _hidl_cb) override {
+        return dev_->finish(operationHandle, inParams, input, signature, authToken,
+                            verificationToken, _hidl_cb);
+    }
+
+    Return<ErrorCode> abort(uint64_t operationHandle) override {
+        return dev_->abort(operationHandle);
+    }
+
+   private:
+    void getVersionIfNeeded();
+
+    bool haveVersion_;
+    SecurityLevel securityLevel_;
+    sp<IKeymaster4Device> dev_;
+};
+
+}  // namespace support
+}  // namespace V4_0
+}  // namespace keymaster
+}  // namespace hardware
+}  // namespace android
+
+#endif  // HARDWARE_INTERFACES_KEYMASTER_40_SUPPORT_KEYMASTER_4_H_