Move keystore to Keymaster4

Test: CTS
Change-Id: I6b7fa300f505ee685b1fe503edea3188225a98e3
diff --git a/keystore/Android.bp b/keystore/Android.bp
index 42301f2..6e69e0a 100644
--- a/keystore/Android.bp
+++ b/keystore/Android.bp
@@ -40,11 +40,11 @@
     ],
     shared_libs: [
         "android.hardware.keymaster@3.0",
+        "android.hardware.keymaster@4.0",
         "android.system.wifi.keystore@1.0",
         "libbase",
         "libbinder",
         "libcrypto",
-        "libcutils",
         "libhardware",
         "libhidlbase",
         "libhidltransport",
@@ -131,7 +131,7 @@
         "keystore_aidl_hidl_marshalling_utils.cpp",
     ],
     shared_libs: [
-        "android.hardware.keymaster@3.0",
+        "android.hardware.keymaster@4.0",
         "libbinder",
         "libhardware",
         "libhidlbase",
@@ -141,7 +141,7 @@
         "libutils",
     ],
     export_shared_lib_headers: [
-        "android.hardware.keymaster@3.0",
+        "android.hardware.keymaster@4.0",
         "libbinder",
         "libhidlbase",
         "libhwbinder",
@@ -222,13 +222,13 @@
     ],
     static_libs: ["libgtest_main"],
     shared_libs: [
-        "android.hardware.keymaster@3.0",
+        "android.hardware.keymaster@4.0",
         "libhidlbase",
         "libhwbinder",
         "libutils",
     ],
     export_shared_lib_headers: [
-        "android.hardware.keymaster@3.0",
+        "android.hardware.keymaster@4.0",
         "libhidlbase",
         "libhwbinder",
     ],
diff --git a/keystore/KeyStore.cpp b/keystore/KeyStore.cpp
index 4cdae1d..fd5b26d 100644
--- a/keystore/KeyStore.cpp
+++ b/keystore/KeyStore.cpp
@@ -35,10 +35,11 @@
 
 namespace keystore {
 
-const char* KeyStore::sOldMasterKey = ".masterkey";
-const char* KeyStore::sMetaDataFile = ".metadata";
+const char* KeyStore::kOldMasterKey = ".masterkey";
+const char* KeyStore::kMetaDataFile = ".metadata";
 
-const android::String16 KeyStore::sRSAKeyType("RSA");
+const android::String16 KeyStore::kRsaKeyType("RSA");
+const android::String16 KeyStore::kEcKeyType("EC");
 
 using android::String8;
 
@@ -548,23 +549,22 @@
     return put(filename, &keyBlob, userId);
 }
 
-bool KeyStore::isHardwareBacked(const android::String16& /*keyType*/) const {
-    using ::android::hardware::hidl_string;
+bool KeyStore::isHardwareBacked(const android::String16& keyType) const {
     if (mDevice == NULL) {
         ALOGW("can't get keymaster device");
         return false;
     }
 
-    bool isSecure = false;
-    auto hidlcb = [&](bool _isSecure, bool, bool, bool, bool, const hidl_string&,
-                      const hidl_string&) { isSecure = _isSecure; };
-    auto rc = mDevice->getHardwareFeatures(hidlcb);
-    if (!rc.isOk()) {
-        ALOGE("Communication with keymaster HAL failed while retrieving hardware features (%s)",
-              rc.description().c_str());
+    auto version = mDevice->halVersion();
+    if (version.error != ErrorCode::OK) {
+        ALOGE("Failed to get HAL version info");
         return false;
     }
-    return isSecure;
+
+    if (!version.isSecure) return false;
+
+    if (keyType == kRsaKeyType) return true;  // All versions support RSA
+    return keyType == kEcKeyType && version.supportsEc;
 }
 
 ResponseCode KeyStore::getKeyForName(Blob* keyBlob, const android::String8& keyName,
@@ -701,7 +701,7 @@
 }
 
 void KeyStore::readMetaData() {
-    int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY));
+    int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
     if (in < 0) {
         return;
     }
@@ -726,7 +726,7 @@
               sizeof(mMetaData));
     }
     close(out);
-    rename(tmpFileName, sMetaDataFile);
+    rename(tmpFileName, kMetaDataFile);
 }
 
 bool KeyStore::upgradeKeystore() {
@@ -739,8 +739,8 @@
         userState->initialize();
 
         // Migrate the old .masterkey file to user 0.
-        if (access(sOldMasterKey, R_OK) == 0) {
-            if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) {
+        if (access(kOldMasterKey, R_OK) == 0) {
+            if (rename(kOldMasterKey, userState->getMasterKeyFileName()) < 0) {
                 ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
                 return false;
             }
diff --git a/keystore/KeyStore.h b/keystore/KeyStore.h
index 4000b81..60cf56d 100644
--- a/keystore/KeyStore.h
+++ b/keystore/KeyStore.h
@@ -122,9 +122,10 @@
     const UserState* getUserStateByUid(uid_t uid) const;
 
   private:
-    static const char* sOldMasterKey;
-    static const char* sMetaDataFile;
-    static const android::String16 sRSAKeyType;
+    static const char* kOldMasterKey;
+    static const char* kMetaDataFile;
+    static const android::String16 kRsaKeyType;
+    static const android::String16 kEcKeyType;
     Entropy* mEntropy;
 
     sp<Keymaster> mDevice;
diff --git a/keystore/Keymaster3.cpp b/keystore/Keymaster3.cpp
index 53a92cc..c4ddc75 100644
--- a/keystore/Keymaster3.cpp
+++ b/keystore/Keymaster3.cpp
@@ -23,7 +23,73 @@
 
 namespace keystore {
 
-using android::hardware::hidl_string;
+namespace oldkeymaster = ::android::hardware::keymaster::V3_0;
+using android::hardware::details::StatusOf;
+
+namespace {
+
+ErrorCode convert(oldkeymaster::ErrorCode error) {
+    return static_cast<ErrorCode>(error);
+}
+
+oldkeymaster::KeyPurpose convert(KeyPurpose purpose) {
+    return static_cast<oldkeymaster::KeyPurpose>(purpose);
+}
+
+oldkeymaster::KeyParameter convert(const KeyParameter& param) {
+    oldkeymaster::KeyParameter converted;
+    converted.tag = static_cast<oldkeymaster::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 oldkeymaster::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<oldkeymaster::KeyParameter> convert(const hidl_vec<KeyParameter>& params) {
+    hidl_vec<oldkeymaster::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<oldkeymaster::KeyParameter>& params) {
+    hidl_vec<KeyParameter> converted(params.size());
+    for (size_t i = 0; i < params.size(); ++i) {
+        converted[i] = convert(params[i]);
+    }
+    return converted;
+}
+
+hidl_vec<oldkeymaster::KeyParameter> convertAndAddAuthToken(const hidl_vec<KeyParameter>& params,
+                                                            const HardwareAuthToken& authToken) {
+    hidl_vec<oldkeymaster::KeyParameter> converted(params.size() + 1);
+    for (size_t i = 0; i < params.size(); ++i) {
+        converted[i] = convert(params[i]);
+    }
+    converted[params.size()].tag = oldkeymaster::Tag::AUTH_TOKEN;
+    converted[params.size()].blob = authToken2HidlVec(authToken);
+
+    return converted;
+}
+
+KeyCharacteristics convert(const oldkeymaster::KeyCharacteristics& chars) {
+    KeyCharacteristics converted;
+    converted.hardwareEnforced = convert(chars.teeEnforced);
+    converted.softwareEnforced = convert(chars.softwareEnforced);
+    return converted;
+}
+
+}  // namespace
 
 void Keymaster3::getVersionIfNeeded() {
     if (haveVersion_) return;
@@ -39,19 +105,19 @@
             supportsAllDigests_ = supportsAllDigests;
             keymasterName_ = keymasterName;
             authorName_ = keymasterAuthorName;
-
-            if (!isSecure) {
-                majorVersion_ = 3;  // SW version is 3 (don't think this should happen).
-            } else if (supportsAttestation) {
-                majorVersion_ = 2;  // Could be 3, no real difference.
-            } else if (supportsSymmetricCryptography) {
-                majorVersion_ = 1;
-            } else {
-                majorVersion_ = 0;
-            }
         });
 
     CHECK(rc.isOk()) << "Got error " << rc.description() << " trying to get hardware features";
+
+    if (!isSecure_) {
+        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() {
@@ -59,4 +125,159 @@
     return {ErrorCode::OK, majorVersion_, isSecure_, supportsEllipticCurve_};
 }
 
+Return<void> Keymaster3::getHardwareInfo(Keymaster3::getHardwareInfo_cb _hidl_cb) {
+    getVersionIfNeeded();
+    _hidl_cb(isSecure_ ? SecurityLevel::TRUSTED_ENVIRONMENT : SecurityLevel::SOFTWARE,
+             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<oldkeymaster::ErrorCode, ErrorCode>(rc);
+    }
+    return convert(rc);
+}
+
+Return<void> Keymaster3::generateKey(const hidl_vec<KeyParameter>& keyParams,
+                                     generateKey_cb _hidl_cb) {
+    auto cb = [&](oldkeymaster::ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
+                  const oldkeymaster::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 = [&](oldkeymaster::ErrorCode error, const oldkeymaster::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 = [&](oldkeymaster::ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
+                  const oldkeymaster::KeyCharacteristics& chars) {
+        _hidl_cb(convert(error), keyBlob, convert(chars));
+    };
+    auto rc = km3_dev_->importKey(convert(params), 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 = [&](oldkeymaster::ErrorCode error, const hidl_vec<uint8_t>& keyMaterial) {
+        _hidl_cb(convert(error), keyMaterial);
+    };
+    auto rc = km3_dev_->exportKey(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 = [&](oldkeymaster::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 = [&](oldkeymaster::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<oldkeymaster::ErrorCode, ErrorCode>(rc);
+    return convert(rc);
+}
+
+Return<ErrorCode> Keymaster3::deleteAllKeys() {
+    auto rc = km3_dev_->deleteAllKeys();
+    if (!rc.isOk()) return StatusOf<oldkeymaster::ErrorCode, ErrorCode>(rc);
+    return convert(rc);
+}
+
+Return<ErrorCode> Keymaster3::destroyAttestationIds() {
+    auto rc = km3_dev_->destroyAttestationIds();
+    if (!rc.isOk()) return StatusOf<oldkeymaster::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 = [&](oldkeymaster::ErrorCode error,
+                  const hidl_vec<oldkeymaster::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 = [&](oldkeymaster::ErrorCode error, uint32_t inputConsumed,
+                  const hidl_vec<oldkeymaster::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 = [&](oldkeymaster::ErrorCode error,
+                  const hidl_vec<oldkeymaster::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<oldkeymaster::ErrorCode, ErrorCode>(rc);
+    return convert(rc);
+}
+
 }  // namespace keystore
diff --git a/keystore/Keymaster3.h b/keystore/Keymaster3.h
index 3be01d7..172ab23 100644
--- a/keystore/Keymaster3.h
+++ b/keystore/Keymaster3.h
@@ -15,99 +15,90 @@
  ** limitations under the License.
  */
 
-#ifndef KEYSTORE_KEYMASTER_3_H_
-#define KEYSTORE_KEYMASTER_3_H_
+#ifndef KEYMASTER_3_DEVICE_WRAPPER_H_
+#define KEYMASTER_3_DEVICE_WRAPPER_H_
 
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
 #include <keystore/keymaster_types.h>
-#include <utils/StrongPointer.h>
 
 #include "Keymaster.h"
 
 namespace keystore {
 
-using android::sp;
 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:
-    Keymaster3(sp<IKeymasterDevice> km3_dev) : km3_dev_(km3_dev) {}
+    Keymaster3(sp<IKeymaster3Device> km3_dev) : km3_dev_(km3_dev) {}
 
     VersionResult halVersion() override;
 
-    Return<void> getHardwareFeatures(getHardwareFeatures_cb _hidl_cb) override {
-        getVersionIfNeeded();
-        _hidl_cb(isSecure_, supportsEllipticCurve_, supportsSymmetricCryptography_,
-                 supportsAttestation_, supportsAllDigests_,
-                 keymasterName_ + " (wrapped by keystore::Keymaster3)", authorName_);
-        return android::hardware::Void();
+    Return<void> getHardwareInfo(getHardwareInfo_cb _hidl_cb);
+
+    Return<void> getHmacSharingParameters(getHmacSharingParameters_cb _hidl_cb) override {
+        _hidl_cb(ErrorCode::UNIMPLEMENTED, {});
+        return Void();
     }
 
-    Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override {
-        return km3_dev_->addRngEntropy(data);
+    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 km3_dev_->generateKey(keyParams, _hidl_cb);
-    }
-
+                             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 km3_dev_->getKeyCharacteristics(keyBlob, clientId, appData, _hidl_cb);
-    }
-
+                                       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 km3_dev_->importKey(params, keyFormat, keyData, _hidl_cb);
+                           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 km3_dev_->exportKey(exportFormat, keyBlob, clientId, appData, _hidl_cb);
-    }
-
+                           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 km3_dev_->attestKey(keyToAttest, attestParams, _hidl_cb);
-    }
-
+                           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 km3_dev_->upgradeKey(keyBlobToUpgrade, upgradeParams, _hidl_cb);
-    }
-
-    Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override {
-        return km3_dev_->deleteKey(keyBlob);
-    }
-
-    Return<ErrorCode> deleteAllKeys() override { return km3_dev_->deleteAllKeys(); }
-
-    Return<ErrorCode> destroyAttestationIds() override { return km3_dev_->destroyAttestationIds(); }
-
+                            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, begin_cb _hidl_cb) override {
-        return km3_dev_->begin(purpose, key, inParams, _hidl_cb);
-    }
-
+                       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, update_cb _hidl_cb) override {
-        return km3_dev_->update(operationHandle, inParams, input, _hidl_cb);
-    }
-
+                        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,
-                        finish_cb _hidl_cb) override {
-        return km3_dev_->finish(operationHandle, inParams, input, signature, _hidl_cb);
-    }
-
-    Return<ErrorCode> abort(uint64_t operationHandle) override {
-        return km3_dev_->abort(operationHandle);
-    }
+                        const HardwareAuthToken& authToken,
+                        const VerificationToken& verificationToken, finish_cb _hidl_cb) override;
+    Return<ErrorCode> abort(uint64_t operationHandle) override;
 
   private:
     void getVersionIfNeeded();
@@ -125,6 +116,8 @@
     std::string authorName_;
 };
 
+sp<IKeymaster3Device> makeSoftwareKeymasterDevice();
+
 }  // namespace keystore
 
-#endif  // KEYSTORE_KEYMASTER_3_H_
+#endif  // KEYMASTER_3_DEVICE_WRAPPER_H_
diff --git a/keystore/Keymaster4.h b/keystore/Keymaster4.h
new file mode 100644
index 0000000..867f304
--- /dev/null
+++ b/keystore/Keymaster4.h
@@ -0,0 +1,143 @@
+/*
+ **
+ ** 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 KEYSTORE_KEYMASTER_4_H_
+#define KEYSTORE_KEYMASTER_4_H_
+
+#include <keystore/keymaster_types.h>
+#include <utils/StrongPointer.h>
+
+#include "Keymaster.h"
+
+namespace keystore {
+
+using android::sp;
+using IKeymaster4Device = ::android::hardware::keymaster::V4_0::IKeymasterDevice;
+
+class Keymaster4 : public Keymaster {
+  public:
+    Keymaster4(sp<IKeymasterDevice> km4_dev) : dev_(km4_dev) {}
+
+    uint8_t halMajorVersion() { return 4; }
+
+    VersionResult halVersion() override { return {ErrorCode::OK, halMajorVersion(), true, true}; }
+
+    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:
+    sp<IKeymaster4Device> dev_;
+};
+
+}  // namespace keystore
+
+#endif  // KEYSTORE_KEYMASTER_3_H_
diff --git a/keystore/KeymasterArguments.cpp b/keystore/KeymasterArguments.cpp
index 792c831..829156c 100644
--- a/keystore/KeymasterArguments.cpp
+++ b/keystore/KeymasterArguments.cpp
@@ -34,7 +34,7 @@
     return keystore::writeParamSetToParcel(data_, out);
 };
 
-KeymasterArguments::KeymasterArguments(const hardware::hidl_vec<keymaster::KeyParameter>& other)
+KeymasterArguments::KeymasterArguments(const hardware::hidl_vec<keystore::KeyParameter>& other)
     : data_(other) {}
 
 }  // namespace keymaster
diff --git a/keystore/OperationResult.cpp b/keystore/OperationResult.cpp
index f7f33f9..62c957e 100644
--- a/keystore/OperationResult.cpp
+++ b/keystore/OperationResult.cpp
@@ -27,7 +27,7 @@
 namespace security {
 namespace keymaster {
 
-using ::android::hardware::keymaster::V3_0::ErrorCode;
+using keystore::keymaster::ErrorCode;
 using ::android::status_t;
 
 OperationResult::OperationResult() : resultCode(), token(), handle(0), inputConsumed(0), data() {}
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
index e54febe..3c51c70 100644
--- a/keystore/auth_token_table.cpp
+++ b/keystore/auth_token_table.cpp
@@ -77,13 +77,12 @@
     return time.tv_sec;
 }
 
-void AuthTokenTable::AddAuthenticationToken(std::unique_ptr<const HardwareAuthToken>&& auth_token) {
+void AuthTokenTable::AddAuthenticationToken(HardwareAuthToken&& auth_token) {
     Entry new_entry(std::move(auth_token), clock_function_());
-    //STOPSHIP: debug only, to be removed
-    ALOGD("AddAuthenticationToken: timestamp = %llu (%llu), time_received = %lld",
-        static_cast<unsigned long long>(new_entry.timestamp_host_order()),
-        static_cast<unsigned long long>(new_entry.token().timestamp),
-        static_cast<long long>(new_entry.time_received()));
+    // STOPSHIP: debug only, to be removed
+    ALOGD("AddAuthenticationToken: timestamp = %llu, time_received = %lld",
+          static_cast<unsigned long long>(new_entry.token().timestamp),
+          static_cast<long long>(new_entry.time_received()));
 
     RemoveEntriesSupersededBy(new_entry);
     if (entries_.size() >= max_entries_) {
@@ -95,10 +94,8 @@
 }
 
 inline bool is_secret_key_operation(Algorithm algorithm, KeyPurpose purpose) {
-    if ((algorithm != Algorithm::RSA && algorithm != Algorithm::EC))
-        return true;
-    if (purpose == KeyPurpose::SIGN || purpose == KeyPurpose::DECRYPT)
-        return true;
+    if ((algorithm != Algorithm::RSA && algorithm != Algorithm::EC)) return true;
+    if (purpose == KeyPurpose::SIGN || purpose == KeyPurpose::DECRYPT) return true;
     return false;
 }
 
@@ -211,26 +208,15 @@
     if (IsSupersededBySomeEntry(*found)) entries_.erase(found);
 }
 
-AuthTokenTable::Entry::Entry(std::unique_ptr<const HardwareAuthToken>&& token, time_t current_time)
+AuthTokenTable::Entry::Entry(HardwareAuthToken&& token, time_t current_time)
     : token_(std::move(token)), time_received_(current_time), last_use_(current_time),
-      operation_completed_(token_->challenge == 0) {}
-
-uint64_t AuthTokenTable::Entry::timestamp_host_order() const {
-    return ntoh(token_->timestamp);
-}
-
-HardwareAuthenticatorType AuthTokenTable::Entry::authenticator_type() const {
-    HardwareAuthenticatorType result = static_cast<HardwareAuthenticatorType>(
-        ntoh(static_cast<uint32_t>(token_->authenticatorType)));
-    return result;
-}
+      operation_completed_(token_.challenge == 0) {}
 
 bool AuthTokenTable::Entry::SatisfiesAuth(const std::vector<uint64_t>& sids,
                                           HardwareAuthenticatorType auth_type) {
-    for (auto sid : sids)
-        if ((sid == token_->authenticatorId) ||
-            (sid == token_->userId && (auth_type & authenticator_type()) != 0))
-            return true;
+    for (auto sid : sids) {
+        if (SatisfiesAuth(sid, auth_type)) return true;
+    }
     return false;
 }
 
@@ -241,10 +227,9 @@
 bool AuthTokenTable::Entry::Supersedes(const Entry& entry) const {
     if (!entry.completed()) return false;
 
-    return (token_->userId == entry.token_->userId &&
-            token_->authenticatorType == entry.token_->authenticatorType &&
-            token_->authenticatorId == entry.token_->authenticatorId &&
-            is_newer_than(&entry));
+    return (token_.userId == entry.token_.userId &&
+            token_.authenticatorType == entry.token_.authenticatorType &&
+            token_.authenticatorId == entry.token_.authenticatorId && is_newer_than(&entry));
 }
 
-}  // namespace keymaster
+}  // namespace keystore
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index 3e3ff6e..0a23c99 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -18,13 +18,14 @@
 #include <vector>
 
 #include <keystore/authorization_set.h>
+#include <keystore/keymaster_types.h>
 
 #ifndef KEYSTORE_AUTH_TOKEN_TABLE_H_
 #define KEYSTORE_AUTH_TOKEN_TABLE_H_
 
 namespace keystore {
 
-using android::hardware::keymaster::V3_0::HardwareAuthToken;
+using keymaster::HardwareAuthToken;
 
 namespace test {
 class AuthTokenTableTest;
@@ -60,7 +61,7 @@
     /**
      * Add an authorization token to the table.  The table takes ownership of the argument.
      */
-    void AddAuthenticationToken(std::unique_ptr<const HardwareAuthToken>&& auth_token);
+    void AddAuthenticationToken(HardwareAuthToken&& auth_token);
 
     /**
      * Find an authorization token that authorizes the operation specified by \p operation_handle on
@@ -96,7 +97,7 @@
 
     class Entry {
       public:
-        Entry(std::unique_ptr<const HardwareAuthToken>&& token, time_t current_time);
+        Entry(HardwareAuthToken&& token, time_t current_time);
         Entry(Entry&& entry) { *this = std::move(entry); }
 
         void operator=(Entry&& rhs) {
@@ -115,8 +116,8 @@
 
         bool is_newer_than(const Entry* entry) const {
             if (!entry) return true;
-            uint64_t ts = timestamp_host_order();
-            uint64_t other_ts = entry->timestamp_host_order();
+            uint64_t ts = token_.timestamp;
+            uint64_t other_ts = entry->token_.timestamp;
             // Normally comparing timestamp_host_order alone is sufficient, but here is an
             // additional hack to compare time_received value for some devices where their auth
             // tokens contain fixed timestamp (due to the a stuck secure RTC on them)
@@ -126,14 +127,17 @@
 
         void mark_completed() { operation_completed_ = true; }
 
-        const HardwareAuthToken& token() { return *token_.get(); }
+        const HardwareAuthToken& token() const & { return token_; }
         time_t time_received() const { return time_received_; }
         bool completed() const { return operation_completed_; }
-        uint64_t timestamp_host_order() const;
-        HardwareAuthenticatorType authenticator_type() const;
 
       private:
-        std::unique_ptr<const HardwareAuthToken> token_;
+        bool SatisfiesAuth(uint64_t sid, HardwareAuthenticatorType auth_type) const {
+            return (sid == token_.userId || sid == token_.authenticatorId) &&
+                   (auth_type & token_.authenticatorType) != 0;
+        }
+
+        HardwareAuthToken token_;
         time_t time_received_;
         time_t last_use_;
         bool operation_completed_;
@@ -155,6 +159,6 @@
     time_t (*clock_function_)();
 };
 
-}  // namespace keymaster
+}  // namespace keystore
 
 #endif  // KEYSTORE_AUTH_TOKEN_TABLE_H_
diff --git a/keystore/include/keystore/KeyCharacteristics.h b/keystore/include/keystore/KeyCharacteristics.h
index ddb1208..7fc89c6 100644
--- a/keystore/include/keystore/KeyCharacteristics.h
+++ b/keystore/include/keystore/KeyCharacteristics.h
@@ -18,25 +18,24 @@
 #include <binder/Parcelable.h>
 
 #include "KeymasterArguments.h"
+#include "keymaster_types.h"
 
 namespace android {
 namespace security {
 namespace keymaster {
 
-using hardware::keymaster::V3_0::KeyParameter;
-
-// Parcelable version of hardware::keymaster::V3_0::KeyCharacteristics
+// Parcelable version of keystore::KeyCharacteristics
 struct KeyCharacteristics : public ::android::Parcelable {
     KeyCharacteristics(){};
-    explicit KeyCharacteristics(const android::hardware::keymaster::V3_0::KeyCharacteristics& other) {
+    explicit KeyCharacteristics(const keystore::KeyCharacteristics& other) {
         softwareEnforced = KeymasterArguments(other.softwareEnforced);
-        teeEnforced = KeymasterArguments(other.teeEnforced);
+        hardwareEnforced = KeymasterArguments(other.hardwareEnforced);
     }
     status_t readFromParcel(const Parcel* in) override;
     status_t writeToParcel(Parcel* out) const override;
 
     KeymasterArguments softwareEnforced;
-    KeymasterArguments teeEnforced;
+    KeymasterArguments hardwareEnforced;
 };
 
 }  // namespace keymaster
diff --git a/keystore/include/keystore/KeymasterArguments.h b/keystore/include/keystore/KeymasterArguments.h
index 3f35a91..329579a 100644
--- a/keystore/include/keystore/KeymasterArguments.h
+++ b/keystore/include/keystore/KeymasterArguments.h
@@ -23,20 +23,18 @@
 namespace security {
 namespace keymaster {
 
-using hardware::keymaster::V3_0::KeyParameter;
-
-// struct for serializing/deserializing a list of KeyParameter's
+// struct for serializing/deserializing a list of KeyParameters
 struct KeymasterArguments : public Parcelable {
     KeymasterArguments(){};
-    explicit KeymasterArguments(const hardware::hidl_vec<KeyParameter>& other);
+    explicit KeymasterArguments(const hardware::hidl_vec<keystore::KeyParameter>& other);
 
     status_t readFromParcel(const Parcel* in) override;
     status_t writeToParcel(Parcel* out) const override;
 
-    const inline hardware::hidl_vec<KeyParameter>& getParameters() const { return data_; }
+    const inline hardware::hidl_vec<keystore::KeyParameter>& getParameters() const { return data_; }
 
   private:
-    hardware::hidl_vec<KeyParameter> data_;
+    hardware::hidl_vec<keystore::KeyParameter> data_;
 };
 
 }  // namespace keymaster
diff --git a/keystore/include/keystore/KeystoreArguments.h b/keystore/include/keystore/KeystoreArguments.h
index 8c2e336..c0a8b0a 100644
--- a/keystore/include/keystore/KeystoreArguments.h
+++ b/keystore/include/keystore/KeystoreArguments.h
@@ -17,6 +17,7 @@
 
 #include <binder/Parcelable.h>
 #include <utils/RefBase.h>
+#include <utils/Vector.h>
 
 #include "KeystoreArg.h"
 #include "keystore_return_types.h"
diff --git a/keystore/include/keystore/keymaster_tags.h b/keystore/include/keystore/keymaster_tags.h
index 1b3e71b..6d2048a 100644
--- a/keystore/include/keystore/keymaster_tags.h
+++ b/keystore/include/keystore/keymaster_tags.h
@@ -62,26 +62,36 @@
 #include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
 #include <type_traits>
 
+#include "keymaster_types.h"
+
 namespace keystore {
 
-using ::android::hardware::keymaster::V3_0::Algorithm;
-using ::android::hardware::keymaster::V3_0::BlockMode;
-using ::android::hardware::keymaster::V3_0::Digest;
-using ::android::hardware::keymaster::V3_0::EcCurve;
-using ::android::hardware::keymaster::V3_0::ErrorCode;
-using ::android::hardware::keymaster::V3_0::HardwareAuthToken;
-using ::android::hardware::keymaster::V3_0::HardwareAuthenticatorType;
-using ::android::hardware::keymaster::V3_0::IKeymasterDevice;
-using ::android::hardware::keymaster::V3_0::KeyBlobUsageRequirements;
-using ::android::hardware::keymaster::V3_0::KeyCharacteristics;
-using ::android::hardware::keymaster::V3_0::KeyDerivationFunction;
-using ::android::hardware::keymaster::V3_0::KeyFormat;
-using ::android::hardware::keymaster::V3_0::KeyOrigin;
-using ::android::hardware::keymaster::V3_0::KeyParameter;
-using ::android::hardware::keymaster::V3_0::KeyPurpose;
-using ::android::hardware::keymaster::V3_0::PaddingMode;
-using ::android::hardware::keymaster::V3_0::Tag;
-using ::android::hardware::keymaster::V3_0::TagType;
+// This namespace alias is temporary.  This file will be removed in favor of the KM4 support
+// library version.
+namespace oldkeymaster = android::hardware::keymaster::V3_0;
+
+using keymaster::ErrorCode;
+using keymaster::HardwareAuthToken;
+using keymaster::HmacSharingParameters;
+using keymaster::IKeymasterDevice;
+using keymaster::KeyCharacteristics;
+using keymaster::KeyOrigin;
+using keymaster::KeyParameter;
+using keymaster::KeyPurpose;
+using keymaster::OperationHandle;
+using keymaster::SecurityLevel;
+using keymaster::Tag;
+using keymaster::VerificationToken;
+using oldkeymaster::Algorithm;
+using oldkeymaster::BlockMode;
+using oldkeymaster::Digest;
+using oldkeymaster::EcCurve;
+using oldkeymaster::HardwareAuthenticatorType;
+using oldkeymaster::KeyBlobUsageRequirements;
+using oldkeymaster::KeyDerivationFunction;
+using oldkeymaster::KeyFormat;
+using oldkeymaster::PaddingMode;
+using oldkeymaster::TagType;
 
 using ::android::hardware::hidl_vec;
 using ::android::hardware::Return;
@@ -131,28 +141,23 @@
 DECLARE_TYPED_TAG(CALLER_NONCE);
 DECLARE_TYPED_TAG(MIN_MAC_LENGTH);
 DECLARE_TYPED_TAG(RSA_PUBLIC_EXPONENT);
-DECLARE_TYPED_TAG(ECIES_SINGLE_HASH_MODE);
 DECLARE_TYPED_TAG(INCLUDE_UNIQUE_ID);
 DECLARE_TYPED_TAG(ACTIVE_DATETIME);
 DECLARE_TYPED_TAG(ORIGINATION_EXPIRE_DATETIME);
 DECLARE_TYPED_TAG(USAGE_EXPIRE_DATETIME);
 DECLARE_TYPED_TAG(MIN_SECONDS_BETWEEN_OPS);
 DECLARE_TYPED_TAG(MAX_USES_PER_BOOT);
-DECLARE_TYPED_TAG(ALL_USERS);
-DECLARE_TYPED_TAG(USER_ID);
 DECLARE_TYPED_TAG(USER_SECURE_ID);
 DECLARE_TYPED_TAG(NO_AUTH_REQUIRED);
 DECLARE_TYPED_TAG(AUTH_TIMEOUT);
 DECLARE_TYPED_TAG(ALLOW_WHILE_ON_BODY);
-DECLARE_TYPED_TAG(ALL_APPLICATIONS);
 DECLARE_TYPED_TAG(APPLICATION_ID);
 DECLARE_TYPED_TAG(APPLICATION_DATA);
 DECLARE_TYPED_TAG(CREATION_DATETIME);
-DECLARE_TYPED_TAG(ROLLBACK_RESISTANT);
+DECLARE_TYPED_TAG(ROLLBACK_RESISTANCE);
 DECLARE_TYPED_TAG(ROOT_OF_TRUST);
 DECLARE_TYPED_TAG(ASSOCIATED_DATA);
 DECLARE_TYPED_TAG(NONCE);
-DECLARE_TYPED_TAG(AUTH_TOKEN);
 DECLARE_TYPED_TAG(BOOTLOADER_ONLY);
 DECLARE_TYPED_TAG(OS_VERSION);
 DECLARE_TYPED_TAG(OS_PATCHLEVEL);
@@ -169,23 +174,21 @@
 DECLARE_TYPED_TAG(BLOB_USAGE_REQUIREMENTS);
 DECLARE_TYPED_TAG(ORIGIN);
 DECLARE_TYPED_TAG(USER_AUTH_TYPE);
-DECLARE_TYPED_TAG(KDF);
 DECLARE_TYPED_TAG(EC_CURVE);
 
 template <typename... Elems> struct MetaList {};
 
 using all_tags_t = MetaList<
     TAG_INVALID_t, TAG_KEY_SIZE_t, TAG_MAC_LENGTH_t, TAG_CALLER_NONCE_t, TAG_MIN_MAC_LENGTH_t,
-    TAG_RSA_PUBLIC_EXPONENT_t, TAG_ECIES_SINGLE_HASH_MODE_t, TAG_INCLUDE_UNIQUE_ID_t,
-    TAG_ACTIVE_DATETIME_t, TAG_ORIGINATION_EXPIRE_DATETIME_t, TAG_USAGE_EXPIRE_DATETIME_t,
-    TAG_MIN_SECONDS_BETWEEN_OPS_t, TAG_MAX_USES_PER_BOOT_t, TAG_ALL_USERS_t, TAG_USER_ID_t,
-    TAG_USER_SECURE_ID_t, TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t, TAG_ALLOW_WHILE_ON_BODY_t,
-    TAG_ALL_APPLICATIONS_t, TAG_APPLICATION_ID_t, TAG_APPLICATION_DATA_t, TAG_CREATION_DATETIME_t,
-    TAG_ROLLBACK_RESISTANT_t, TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, TAG_NONCE_t,
-    TAG_AUTH_TOKEN_t, TAG_BOOTLOADER_ONLY_t, TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t,
+    TAG_RSA_PUBLIC_EXPONENT_t, TAG_INCLUDE_UNIQUE_ID_t, TAG_ACTIVE_DATETIME_t,
+    TAG_ORIGINATION_EXPIRE_DATETIME_t, TAG_USAGE_EXPIRE_DATETIME_t, TAG_MIN_SECONDS_BETWEEN_OPS_t,
+    TAG_MAX_USES_PER_BOOT_t, TAG_USER_SECURE_ID_t, TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t,
+    TAG_ALLOW_WHILE_ON_BODY_t, TAG_APPLICATION_ID_t, TAG_APPLICATION_DATA_t,
+    TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t, TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t,
+    TAG_NONCE_t, TAG_BOOTLOADER_ONLY_t, TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t,
     TAG_ATTESTATION_CHALLENGE_t, TAG_ATTESTATION_APPLICATION_ID_t, TAG_RESET_SINCE_ID_ROTATION_t,
     TAG_PURPOSE_t, TAG_ALGORITHM_t, TAG_BLOCK_MODE_t, TAG_DIGEST_t, TAG_PADDING_t,
-    TAG_BLOB_USAGE_REQUIREMENTS_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_KDF_t, TAG_EC_CURVE_t>;
+    TAG_BLOB_USAGE_REQUIREMENTS_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_EC_CURVE_t>;
 
 /* implementation in keystore_utils.cpp */
 extern const char* stringifyTag(Tag tag);
@@ -234,7 +237,6 @@
 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_BLOCK_MODE, f.blockMode)
 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_DIGEST, f.digest)
 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_EC_CURVE, f.ecCurve)
-MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_KDF, f.keyDerivationFunction)
 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ORIGIN, f.origin)
 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PADDING, f.paddingMode)
 MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PURPOSE, f.purpose)
@@ -345,6 +347,6 @@
     return accessTagValue(ttag, param);
 }
 
-}  // namespace keymaster
+}  // namespace keystore
 
 #endif  // SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_
diff --git a/keystore/include/keystore/keymaster_types.h b/keystore/include/keystore/keymaster_types.h
index 14ab059..272105f 100644
--- a/keystore/include/keystore/keymaster_types.h
+++ b/keystore/include/keystore/keymaster_types.h
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <android/hardware/keymaster/3.0/types.h>
+#include <android/hardware/keymaster/4.0/IKeymasterDevice.h>
+#include <android/hardware/keymaster/4.0/types.h>
 
 /**
  * This header lifts the types from the current Keymaster version into the keystore namespace.
@@ -21,9 +21,13 @@
 
 namespace keystore {
 
-namespace keymaster = ::android::hardware::keymaster::V3_0;
+namespace keymaster = ::android::hardware::keymaster::V4_0;
 
 using keymaster::IKeymasterDevice;
 using keymaster::SecurityLevel;
 
+using Km3HardwareAuthToken = ::android::hardware::keymaster::V3_0::HardwareAuthToken;
+using Km3HardwareAuthenticatorType =
+    ::android::hardware::keymaster::V3_0::HardwareAuthenticatorType;
+
 }  // namespace keystore
diff --git a/keystore/include/keystore/keystore_hidl_support.h b/keystore/include/keystore/keystore_hidl_support.h
index 0edaa3b..944c3f6 100644
--- a/keystore/include/keystore/keystore_hidl_support.h
+++ b/keystore/include/keystore/keystore_hidl_support.h
@@ -18,14 +18,17 @@
 #ifndef KEYSTORE_KEYSTORE_HIDL_SUPPORT_H_
 #define KEYSTORE_KEYSTORE_HIDL_SUPPORT_H_
 
-#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
-#include <hardware/hw_auth_token.h>
-#include <hidl/Status.h>
-#include <keystore/keymaster_tags.h>
 #include <ostream>
 #include <sstream>
 #include <string>
 
+#include <android-base/logging.h>
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+#include <hardware/hw_auth_token.h>
+#include <hidl/Status.h>
+
+#include <keystore/keymaster_tags.h>
+
 namespace keystore {
 
 inline static std::ostream& formatArgs(std::ostream& out) {
@@ -98,14 +101,16 @@
     return std::copy(value_ptr, value_ptr + sizeof(value), dest);
 }
 
-inline static hidl_vec<uint8_t> authToken2HidlVec(const HardwareAuthToken& token) {
-    static_assert(
-        std::is_same<decltype(token.hmac), ::android::hardware::hidl_array<uint8_t, 32>>::value,
-        "This function assumes token HMAC is 32 bytes, but it might not be.");
+constexpr size_t kHmacSize = 32;
+
+inline static hidl_vec<uint8_t> authToken2HidlVec(const Km3HardwareAuthToken& token) {
+    static_assert(std::is_same<decltype(token.hmac),
+                               ::android::hardware::hidl_array<uint8_t, kHmacSize>>::value,
+                  "This function assumes token HMAC is 32 bytes, but it might not be.");
     static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
                           sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
-                          sizeof(token.timestamp) + 32 /* HMAC size */
-                      == sizeof(hw_auth_token_t),
+                          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;
@@ -129,21 +134,21 @@
     return src + sizeof(T);
 }
 
-inline static HardwareAuthToken hidlVec2AuthToken(const hidl_vec<uint8_t>& buffer) {
-    HardwareAuthToken token;
-    static_assert(
-        std::is_same<decltype(token.hmac), ::android::hardware::hidl_array<uint8_t, 32>>::value,
-        "This function assumes token HMAC is 32 bytes, but it might not be.");
+inline static Km3HardwareAuthToken hidlVec2Km3AuthToken(const hidl_vec<uint8_t>& buffer) {
+    Km3HardwareAuthToken token;
+    static_assert(std::is_same<decltype(token.hmac),
+                               ::android::hardware::hidl_array<uint8_t, kHmacSize>>::value,
+                  "This function assumes token HMAC is 32 bytes, but it might not be.");
     static_assert(1 /* version size */ + sizeof(token.challenge) + sizeof(token.userId) +
                           sizeof(token.authenticatorId) + sizeof(token.authenticatorType) +
-                          sizeof(token.timestamp) + 32 /* HMAC size */
-                      == sizeof(hw_auth_token_t),
+                          sizeof(token.timestamp) + kHmacSize ==
+                      sizeof(hw_auth_token_t),
                   "HardwareAuthToken content size does not match hw_auth_token_t size");
 
     if (buffer.size() != sizeof(hw_auth_token_t)) return {};
 
     auto pos = buffer.begin();
-    ++pos; // skip first byte
+    ++pos;  // skip first byte
     pos = copy_bytes_from_iterator(&token.challenge, pos);
     pos = copy_bytes_from_iterator(&token.userId, pos);
     pos = copy_bytes_from_iterator(&token.authenticatorId, pos);
@@ -154,6 +159,59 @@
     return token;
 }
 
+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;
+}
+
+inline static HardwareAuthToken hidlVec2AuthToken(const hidl_vec<uint8_t>& buffer) {
+    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");
+
+    if (buffer.size() != sizeof(hw_auth_token_t)) return {};
+
+    auto pos = buffer.begin();
+    ++pos;  // skip first byte
+    pos = copy_bytes_from_iterator(&token.challenge, pos);
+    pos = copy_bytes_from_iterator(&token.userId, pos);
+    pos = copy_bytes_from_iterator(&token.authenticatorId, pos);
+    pos = copy_bytes_from_iterator(&token.authenticatorType, pos);
+    token.authenticatorType = static_cast<HardwareAuthenticatorType>(
+        ntohl(static_cast<uint32_t>(token.authenticatorType)));
+    pos = copy_bytes_from_iterator(&token.timestamp, pos);
+    token.timestamp = ntohq(token.timestamp);
+    token.mac.resize(kHmacSize);
+    std::copy(pos, pos + kHmacSize, token.mac.data());
+
+    return token;
+}
+
 inline std::string hidlVec2String(const hidl_vec<uint8_t>& value) {
     return std::string(reinterpret_cast<const std::string::value_type*>(&value[0]), value.size());
 }
diff --git a/keystore/include/keystore/keystore_return_types.h b/keystore/include/keystore/keystore_return_types.h
index 52d700a..fa4a224 100644
--- a/keystore/include/keystore/keystore_return_types.h
+++ b/keystore/include/keystore/keystore_return_types.h
@@ -18,12 +18,12 @@
 #ifndef KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_RETURN_TYPES_H_
 #define KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_RETURN_TYPES_H_
 
+#include "keymaster_types.h"
 #include "keystore.h"
-#include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
 
 namespace keystore {
 
-using ::android::hardware::keymaster::V3_0::ErrorCode;
+using keymaster::ErrorCode;
 
 class KeyStoreServiceReturnCode;
 class KeyStoreNativeReturnCode;
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 9459520..137ab48 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -1172,16 +1172,12 @@
     return Status::ok();
 }
 
-static inline void addAuthTokenToParams(AuthorizationSet* params, const HardwareAuthToken* token) {
-    if (token) {
-        params->push_back(TAG_AUTH_TOKEN, authToken2HidlVec(*token));
-    }
-}
-
 Status KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name, int32_t purpose,
                               bool pruneable, const KeymasterArguments& params,
                               const ::std::vector<uint8_t>& entropy, int32_t uid,
                               OperationResult* result) {
+    auto keyPurpose = static_cast<KeyPurpose>(purpose);
+
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     uid_t targetUid = getEffectiveUid(uid);
     if (!is_granted_to(callingUid, targetUid)) {
@@ -1198,15 +1194,14 @@
         result->resultCode = ErrorCode::INVALID_ARGUMENT;
         return Status::ok();
     }
+
     Blob keyBlob;
     String8 name8(name);
     result->resultCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
     if (result->resultCode == ResponseCode::LOCKED && keyBlob.isSuperEncrypted()) {
         result->resultCode = ErrorCode::KEY_USER_NOT_AUTHENTICATED;
     }
-    if (!result->resultCode.isOk()) {
-        return Status::ok();
-    }
+    if (!result->resultCode.isOk()) return Status::ok();
 
     auto key = blob2hidlVec(keyBlob);
     auto& dev = mKeyStore->getDevice(keyBlob);
@@ -1226,8 +1221,6 @@
         return Status::ok();
     }
 
-    const HardwareAuthToken* authToken = NULL;
-
     // Merge these characteristics with the ones cached when the key was generated or imported
     Blob charBlob;
     AuthorizationSet persistedCharacteristics;
@@ -1245,13 +1238,17 @@
 
     // Replace the sw_enforced set with those persisted to disk, minus hw_enforced
     AuthorizationSet softwareEnforced = characteristics.softwareEnforced;
-    AuthorizationSet teeEnforced = characteristics.teeEnforced;
+    AuthorizationSet hardwareEnforced = characteristics.hardwareEnforced;
     persistedCharacteristics.Union(softwareEnforced);
-    persistedCharacteristics.Subtract(teeEnforced);
+    persistedCharacteristics.Subtract(hardwareEnforced);
     characteristics.softwareEnforced = persistedCharacteristics.hidl_data();
 
-    auto authResult = getAuthToken(characteristics, 0, KeyPurpose(purpose), &authToken,
-                                   /*failOnTokenMissing*/ false);
+    KeyStoreServiceReturnCode authResult;
+    HardwareAuthToken authToken;
+    std::tie(authResult, authToken) =
+        getAuthToken(characteristics, 0 /* no challenge */, keyPurpose,
+                     /*failOnTokenMissing*/ false);
+
     // If per-operation auth is needed we need to begin the operation and
     // the client will need to authorize that operation before calling
     // update. Any other auth issues stop here.
@@ -1260,8 +1257,6 @@
         return Status::ok();
     }
 
-    addAuthTokenToParams(&opParams, authToken);
-
     // Add entropy to the device first.
     if (entropy.size()) {
         int32_t resultCode;
@@ -1281,12 +1276,12 @@
     }
 
     // Check that all key authorization policy requirements are met.
-    AuthorizationSet key_auths = characteristics.teeEnforced;
-    key_auths.append(&characteristics.softwareEnforced[0],
-                     &characteristics.softwareEnforced[characteristics.softwareEnforced.size()]);
+    AuthorizationSet key_auths = characteristics.hardwareEnforced;
+    key_auths.append(characteristics.softwareEnforced.begin(),
+                     characteristics.softwareEnforced.end());
 
     result->resultCode =
-        enforcement_policy.AuthorizeOperation(KeyPurpose(purpose), keyid, key_auths, opParams,
+        enforcement_policy.AuthorizeOperation(keyPurpose, keyid, key_auths, opParams, authToken,
                                               0 /* op_handle */, true /* is_begin_operation */);
     if (!result->resultCode.isOk()) {
         return Status::ok();
@@ -1312,7 +1307,7 @@
     };
 
     ErrorCode rc =
-        KS_HANDLE_HIDL_ERROR(dev->begin(KeyPurpose(purpose), key, opParams.hidl_data(), hidlCb));
+        KS_HANDLE_HIDL_ERROR(dev->begin(keyPurpose, key, opParams.hidl_data(), authToken, hidlCb));
     if (rc != ErrorCode::OK) {
         ALOGW("Got error %d from begin()", rc);
     }
@@ -1325,7 +1320,7 @@
             break;
         }
         rc = KS_HANDLE_HIDL_ERROR(
-            dev->begin(KeyPurpose(purpose), key, opParams.hidl_data(), hidlCb));
+            dev->begin(keyPurpose, key, opParams.hidl_data(), authToken, hidlCb));
     }
     if (rc != ErrorCode::OK) {
         result->resultCode = rc;
@@ -1334,16 +1329,14 @@
 
     // Note: The operation map takes possession of the contents of "characteristics".
     // It is safe to use characteristics after the following line but it will be empty.
-    sp<IBinder> operationToken =
-        mOperationMap.addOperation(result->handle, keyid, KeyPurpose(purpose), dev, appToken,
-                                   std::move(characteristics), pruneable);
-    assert(characteristics.teeEnforced.size() == 0);
+    sp<IBinder> operationToken = mOperationMap.addOperation(
+        result->handle, keyid, keyPurpose, dev, appToken, std::move(characteristics), pruneable);
+    assert(characteristics.hardwareEnforced.size() == 0);
     assert(characteristics.softwareEnforced.size() == 0);
     result->token = operationToken;
 
-    if (authToken) {
-        mOperationMap.setOperationAuthToken(operationToken, *authToken);
-    }
+    mOperationMap.setOperationAuthToken(operationToken, std::move(authToken));
+
     // Return the authentication lookup result. If this is a per operation
     // auth'd key then the resultCode will be ::OP_AUTH_NEEDED and the
     // application should get an auth token using the handle before the
@@ -1371,17 +1364,18 @@
     }
     const auto& op = getOpResult.value();
 
-    AuthorizationSet opParams = params.getParameters();
-    result->resultCode = addOperationAuthTokenIfNeeded(token, &opParams);
+    HardwareAuthToken authToken;
+    std::tie(result->resultCode, authToken) = getOperationAuthTokenIfNeeded(token);
     if (!result->resultCode.isOk()) return Status::ok();
 
     // Check that all key authorization policy requirements are met.
-    AuthorizationSet key_auths(op.characteristics.teeEnforced);
+    AuthorizationSet key_auths(op.characteristics.hardwareEnforced);
     key_auths.append(op.characteristics.softwareEnforced.begin(),
                      op.characteristics.softwareEnforced.end());
 
     result->resultCode = enforcement_policy.AuthorizeOperation(
-        op.purpose, op.keyid, key_auths, opParams, op.handle, false /* is_begin_operation */);
+        op.purpose, op.keyid, key_auths, params.getParameters(), authToken, op.handle,
+        false /* is_begin_operation */);
     if (!result->resultCode.isOk()) return Status::ok();
 
     auto hidlCb = [&](ErrorCode ret, uint32_t inputConsumed,
@@ -1395,8 +1389,8 @@
         }
     };
 
-    KeyStoreServiceReturnCode rc =
-        KS_HANDLE_HIDL_ERROR(op.device->update(op.handle, opParams.hidl_data(), data, hidlCb));
+    KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(op.device->update(
+        op.handle, params.getParameters(), data, authToken, VerificationToken(), hidlCb));
 
     // just a reminder: on success result->resultCode was set in the callback. So we only overwrite
     // it if there was a communication error indicated by the ErrorCode.
@@ -1419,8 +1413,8 @@
         return Status::ok();
     }
 
-    AuthorizationSet opParams = params.getParameters();
-    result->resultCode = addOperationAuthTokenIfNeeded(token, &opParams);
+    HardwareAuthToken authToken;
+    std::tie(result->resultCode, authToken) = getOperationAuthTokenIfNeeded(token);
     if (!result->resultCode.isOk()) return Status::ok();
 
     if (entropy.size()) {
@@ -1433,12 +1427,13 @@
     }
 
     // Check that all key authorization policy requirements are met.
-    AuthorizationSet key_auths(op.characteristics.teeEnforced);
+    AuthorizationSet key_auths(op.characteristics.hardwareEnforced);
     key_auths.append(op.characteristics.softwareEnforced.begin(),
                      op.characteristics.softwareEnforced.end());
 
     result->resultCode = enforcement_policy.AuthorizeOperation(
-        op.purpose, op.keyid, key_auths, opParams, op.handle, false /* is_begin_operation */);
+        op.purpose, op.keyid, key_auths, params.getParameters(), authToken, op.handle,
+        false /* is_begin_operation */);
     if (!result->resultCode.isOk()) return Status::ok();
 
     auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
@@ -1451,9 +1446,9 @@
     };
 
     KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(
-        op.device->finish(op.handle, opParams.hidl_data(),
+        op.device->finish(op.handle, params.getParameters(),
                           ::std::vector<uint8_t>() /* TODO(swillden): wire up input to finish() */,
-                          signature, hidlCb));
+                          signature, authToken, VerificationToken(), hidlCb));
     mOperationMap.removeOperation(token);
     mAuthTokenTable.MarkCompleted(op.handle);
 
@@ -1481,8 +1476,9 @@
 
 Status KeyStoreService::isOperationAuthorized(const sp<IBinder>& token, bool* aidl_return) {
     AuthorizationSet ignored;
-    auto authResult = addOperationAuthTokenIfNeeded(token, &ignored);
-    *aidl_return = authResult.isOk();
+    KeyStoreServiceReturnCode rc;
+    std::tie(rc, std::ignore) = getOperationAuthTokenIfNeeded(token);
+    *aidl_return = rc.isOk();
     return Status::ok();
 }
 
@@ -1509,19 +1505,7 @@
         return Status::ok();
     }
 
-    std::unique_ptr<HardwareAuthToken> hidlAuthToken(new HardwareAuthToken);
-    hidlAuthToken->challenge = authToken.challenge;
-    hidlAuthToken->userId = authToken.user_id;
-    hidlAuthToken->authenticatorId = authToken.authenticator_id;
-    hidlAuthToken->authenticatorType = authToken.authenticator_type;
-    hidlAuthToken->timestamp = authToken.timestamp;
-    static_assert(
-        std::is_same<decltype(hidlAuthToken->hmac),
-                     ::android::hardware::hidl_array<uint8_t, sizeof(authToken.hmac)>>::value,
-        "This function assumes token HMAC is 32 bytes, but it might not be.");
-    std::copy(authToken.hmac, authToken.hmac + sizeof(authToken.hmac), hidlAuthToken->hmac.data());
-
-    mAuthTokenTable.AddAuthenticationToken(std::move(hidlAuthToken));
+    mAuthTokenTable.AddAuthenticationToken(hidlVec2AuthToken(hidl_vec<uint8_t>(authTokenAsVector)));
     *aidl_return = static_cast<int32_t>(ResponseCode::NO_ERROR);
     return Status::ok();
 }
@@ -1814,14 +1798,13 @@
 }
 
 /**
- * Check that all KeyParameter's provided by the application are
- * allowed. Any parameter that keystore adds itself should be disallowed here.
+ * Check that all KeyParameters provided by the application are allowed. Any parameter that keystore
+ * adds itself should be disallowed here.
  */
 bool KeyStoreService::checkAllowedOperationParams(const hidl_vec<KeyParameter>& params) {
     for (size_t i = 0; i < params.size(); ++i) {
         switch (params[i].tag) {
         case Tag::ATTESTATION_APPLICATION_ID:
-        case Tag::AUTH_TOKEN:
         case Tag::RESET_SINCE_ID_ROTATION:
             return false;
         default:
@@ -1871,36 +1854,44 @@
  *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth
  *         token for the operation
  */
-KeyStoreServiceReturnCode KeyStoreService::getAuthToken(const KeyCharacteristics& characteristics,
-                                                        uint64_t handle, KeyPurpose purpose,
-                                                        const HardwareAuthToken** authToken,
-                                                        bool failOnTokenMissing) {
+std::pair<KeyStoreServiceReturnCode, HardwareAuthToken>
+KeyStoreService::getAuthToken(const KeyCharacteristics& characteristics, uint64_t handle,
+                              KeyPurpose purpose, bool failOnTokenMissing) {
 
-    AuthorizationSet allCharacteristics;
-    for (size_t i = 0; i < characteristics.softwareEnforced.size(); i++) {
-        allCharacteristics.push_back(characteristics.softwareEnforced[i]);
-    }
-    for (size_t i = 0; i < characteristics.teeEnforced.size(); i++) {
-        allCharacteristics.push_back(characteristics.teeEnforced[i]);
-    }
+    AuthorizationSet allCharacteristics(characteristics.softwareEnforced);
+    allCharacteristics.append(characteristics.hardwareEnforced.begin(),
+                              characteristics.hardwareEnforced.end());
+
+    const HardwareAuthToken* authToken = nullptr;
     AuthTokenTable::Error err = mAuthTokenTable.FindAuthorization(
-        allCharacteristics, KeyPurpose(purpose), handle, authToken);
+        allCharacteristics, static_cast<KeyPurpose>(purpose), handle, &authToken);
+
+    KeyStoreServiceReturnCode rc;
+
     switch (err) {
     case AuthTokenTable::OK:
     case AuthTokenTable::AUTH_NOT_REQUIRED:
-        return ResponseCode::NO_ERROR;
+        rc = ResponseCode::NO_ERROR;
+        break;
+
     case AuthTokenTable::AUTH_TOKEN_NOT_FOUND:
     case AuthTokenTable::AUTH_TOKEN_EXPIRED:
     case AuthTokenTable::AUTH_TOKEN_WRONG_SID:
         ALOGE("getAuthToken failed: %d", err);  // STOPSHIP: debug only, to be removed
-        return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
+        rc = ErrorCode::KEY_USER_NOT_AUTHENTICATED;
+        break;
+
     case AuthTokenTable::OP_HANDLE_REQUIRED:
-        return failOnTokenMissing ? KeyStoreServiceReturnCode(ErrorCode::KEY_USER_NOT_AUTHENTICATED)
-                                  : KeyStoreServiceReturnCode(ResponseCode::OP_AUTH_NEEDED);
+        rc = failOnTokenMissing ? KeyStoreServiceReturnCode(ErrorCode::KEY_USER_NOT_AUTHENTICATED)
+                                : KeyStoreServiceReturnCode(ResponseCode::OP_AUTH_NEEDED);
+        break;
+
     default:
         ALOGE("Unexpected FindAuthorization return value %d", err);
-        return ErrorCode::INVALID_ARGUMENT;
+        rc = ErrorCode::INVALID_ARGUMENT;
     }
+
+    return {rc, authToken ? std::move(*authToken) : HardwareAuthToken()};
 }
 
 /**
@@ -1914,21 +1905,23 @@
  *         KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid
  *         operation token.
  */
-KeyStoreServiceReturnCode KeyStoreService::addOperationAuthTokenIfNeeded(const sp<IBinder>& token,
-                                                                         AuthorizationSet* params) {
+std::pair<KeyStoreServiceReturnCode, const HardwareAuthToken&>
+KeyStoreService::getOperationAuthTokenIfNeeded(const sp<IBinder>& token) {
+    static HardwareAuthToken emptyToken = {};
+
     auto getOpResult = mOperationMap.getOperation(token);
-    if (!getOpResult.isOk()) return ErrorCode::INVALID_OPERATION_HANDLE;
+    if (!getOpResult.isOk()) return {ErrorCode::INVALID_OPERATION_HANDLE, emptyToken};
     const auto& op = getOpResult.value();
 
-    if (!op.authToken) {
-        const HardwareAuthToken* found = nullptr;
-        auto result = getAuthToken(op.characteristics, op.handle, op.purpose, &found);
-        if (!result.isOk()) return result;
-        if (found) mOperationMap.setOperationAuthToken(token, *found);
-        assert(*op.authToken == *found);
+    if (!op.hasAuthToken()) {
+        KeyStoreServiceReturnCode rc;
+        HardwareAuthToken found;
+        std::tie(rc, found) = getAuthToken(op.characteristics, op.handle, op.purpose);
+        if (!rc.isOk()) return {rc, emptyToken};
+        mOperationMap.setOperationAuthToken(token, std::move(found));
     }
-    addAuthTokenToParams(params, op.authToken.get());
-    return ResponseCode::NO_ERROR;
+
+    return {ResponseCode::NO_ERROR, op.authToken};
 }
 
 /**
@@ -1936,23 +1929,19 @@
  * preserved and keymaster errors become SYSTEM_ERRORs
  */
 KeyStoreServiceReturnCode KeyStoreService::translateResultToLegacyResult(int32_t result) {
-    if (result > 0) {
-        return static_cast<ResponseCode>(result);
-    }
+    if (result > 0) return static_cast<ResponseCode>(result);
     return ResponseCode::SYSTEM_ERROR;
 }
 
 static NullOr<const Algorithm&> getKeyAlgoritmFromKeyCharacteristics(
     const ::android::security::keymaster::KeyCharacteristics& characteristics) {
-    for (size_t i = 0; i < characteristics.teeEnforced.getParameters().size(); ++i) {
-        auto algo =
-            authorizationValue(TAG_ALGORITHM, characteristics.teeEnforced.getParameters()[i]);
-        if (algo.isOk()) return algo.value();
+    for (const auto& param : characteristics.hardwareEnforced.getParameters()) {
+        auto algo = authorizationValue(TAG_ALGORITHM, param);
+        if (algo.isOk()) return algo;
     }
-    for (size_t i = 0; i < characteristics.softwareEnforced.getParameters().size(); ++i) {
-        auto algo =
-            authorizationValue(TAG_ALGORITHM, characteristics.softwareEnforced.getParameters()[i]);
-        if (algo.isOk()) return algo.value();
+    for (const auto& param : characteristics.softwareEnforced.getParameters()) {
+        auto algo = authorizationValue(TAG_ALGORITHM, param);
+        if (algo.isOk()) return algo;
     }
     return {};
 }
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index 0316d6d..da3e60a 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -222,31 +222,28 @@
     /**
      * Get the auth token for this operation from the auth token table.
      *
-     * Returns ::NO_ERROR if the auth token was set or none was required.
-     *         ::OP_AUTH_NEEDED if it is a per op authorization, no
-     *         authorization token exists for that operation and
-     *         failOnTokenMissing is false.
-     *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth
-     *         token for the operation
+     * Returns NO_ERROR if the auth token was found or none was required.  If not needed, the
+     *             token will be empty (which keymaster interprets as no auth token).
+     *         OP_AUTH_NEEDED if it is a per op authorization, no authorization token exists for
+     *             that operation and  failOnTokenMissing is false.
+     *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth token for the operation
      */
-    KeyStoreServiceReturnCode getAuthToken(const KeyCharacteristics& characteristics,
-                                           uint64_t handle, KeyPurpose purpose,
-                                           const HardwareAuthToken** authToken,
-                                           bool failOnTokenMissing = true);
+    std::pair<KeyStoreServiceReturnCode, HardwareAuthToken>
+    getAuthToken(const KeyCharacteristics& characteristics, uint64_t handle, KeyPurpose purpose,
+                 bool failOnTokenMissing = true);
 
     /**
-     * Add the auth token for the operation to the param list if the operation
-     * requires authorization. Uses the cached result in the OperationMap if available
-     * otherwise gets the token from the AuthTokenTable and caches the result.
+     * Get the auth token for the operation if the operation requires authorization. Uses the cached
+     * result in the OperationMap if available otherwise gets the token from the AuthTokenTable and
+     * caches the result.
      *
-     * Returns ::NO_ERROR if the auth token was added or not needed.
-     *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if the operation is not
-     *         authenticated.
-     *         KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid
-     *         operation token.
+     * Returns NO_ERROR if the auth token was found or not needed.  If not needed, the token will
+     *             be empty (which keymaster interprets as no auth token).
+     *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if the operation is not authenticated.
+     *         KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid operation token.
      */
-    KeyStoreServiceReturnCode addOperationAuthTokenIfNeeded(const sp<android::IBinder>& token,
-                                                            AuthorizationSet* params);
+    std::pair<KeyStoreServiceReturnCode, const HardwareAuthToken&>
+    getOperationAuthTokenIfNeeded(const sp<android::IBinder>& token);
 
     /**
      * Translate a result value to a legacy return value. All keystore errors are
diff --git a/keystore/keymaster_enforcement.cpp b/keystore/keymaster_enforcement.cpp
index c27ec6b..16d1354 100644
--- a/keystore/keymaster_enforcement.cpp
+++ b/keystore/keymaster_enforcement.cpp
@@ -117,6 +117,7 @@
 ErrorCode KeymasterEnforcement::AuthorizeOperation(const KeyPurpose purpose, const km_id_t keyid,
                                                    const AuthorizationSet& auth_set,
                                                    const AuthorizationSet& operation_params,
+                                                   const HardwareAuthToken& auth_token,
                                                    uint64_t op_handle, bool is_begin_operation) {
     if (is_public_key_algorithm(auth_set)) {
         switch (purpose) {
@@ -127,23 +128,23 @@
 
         case KeyPurpose::DECRYPT:
         case KeyPurpose::SIGN:
-        case KeyPurpose::DERIVE_KEY:
             break;
+
         case KeyPurpose::WRAP_KEY:
             return ErrorCode::INCOMPATIBLE_PURPOSE;
         };
     };
 
     if (is_begin_operation)
-        return AuthorizeBegin(purpose, keyid, auth_set, operation_params);
+        return AuthorizeBegin(purpose, keyid, auth_set, operation_params, auth_token);
     else
-        return AuthorizeUpdateOrFinish(auth_set, operation_params, op_handle);
+        return AuthorizeUpdateOrFinish(auth_set, auth_token, op_handle);
 }
 
 // For update and finish the only thing to check is user authentication, and then only if it's not
 // timeout-based.
 ErrorCode KeymasterEnforcement::AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
-                                                        const AuthorizationSet& operation_params,
+                                                        const HardwareAuthToken& auth_token,
                                                         uint64_t op_handle) {
     int auth_type_index = -1;
     for (size_t pos = 0; pos < auth_set.size(); ++pos) {
@@ -176,9 +177,9 @@
         if (user_secure_id.isOk()) {
             authentication_required = true;
             int auth_timeout_index = -1;
-            if (AuthTokenMatches(auth_set, operation_params, user_secure_id.value(),
-                                 auth_type_index, auth_timeout_index, op_handle,
-                                 false /* is_begin_operation */))
+            if (auth_token.mac.size() &&
+                AuthTokenMatches(auth_set, auth_token, user_secure_id.value(), auth_type_index,
+                                 auth_timeout_index, op_handle, false /* is_begin_operation */))
                 return ErrorCode::OK;
         }
     }
@@ -190,7 +191,8 @@
 
 ErrorCode KeymasterEnforcement::AuthorizeBegin(const KeyPurpose purpose, const km_id_t keyid,
                                                const AuthorizationSet& auth_set,
-                                               const AuthorizationSet& operation_params) {
+                                               const AuthorizationSet& operation_params,
+                                               NullOr<const HardwareAuthToken&> auth_token) {
     // Find some entries that may be needed to handle KM_TAG_USER_SECURE_ID
     int auth_timeout_index = -1;
     int auth_type_index = -1;
@@ -272,9 +274,9 @@
             if (auth_timeout_index != -1) {
                 auto secure_id = authorizationValue(TAG_USER_SECURE_ID, param);
                 authentication_required = true;
-                if (secure_id.isOk() &&
-                    AuthTokenMatches(auth_set, operation_params, secure_id.value(), auth_type_index,
-                                     auth_timeout_index, 0 /* op_handle */,
+                if (secure_id.isOk() && auth_token.isOk() &&
+                    AuthTokenMatches(auth_set, auth_token.value(), secure_id.value(),
+                                     auth_type_index, auth_timeout_index, 0 /* op_handle */,
                                      true /* is_begin_operation */))
                     auth_token_matched = true;
             }
@@ -286,7 +288,6 @@
 
         /* Tags should never be in key auths. */
         case Tag::INVALID:
-        case Tag::AUTH_TOKEN:
         case Tag::ROOT_OF_TRUST:
         case Tag::APPLICATION_DATA:
         case Tag::ATTESTATION_CHALLENGE:
@@ -311,21 +312,18 @@
         case Tag::PADDING:
         case Tag::NONCE:
         case Tag::MIN_MAC_LENGTH:
-        case Tag::KDF:
         case Tag::EC_CURVE:
 
         /* Tags not used for operations. */
         case Tag::BLOB_USAGE_REQUIREMENTS:
-        case Tag::EXPORTABLE:
 
         /* Algorithm specific parameters not used for access control. */
         case Tag::RSA_PUBLIC_EXPONENT:
-        case Tag::ECIES_SINGLE_HASH_MODE:
 
         /* Informational tags. */
         case Tag::CREATION_DATETIME:
         case Tag::ORIGIN:
-        case Tag::ROLLBACK_RESISTANT:
+        case Tag::ROLLBACK_RESISTANCE:
 
         /* Tags handled when KM_TAG_USER_SECURE_ID is handled */
         case Tag::NO_AUTH_REQUIRED:
@@ -336,20 +334,16 @@
         case Tag::ASSOCIATED_DATA:
 
         /* Tags that are implicitly verified by secure side */
-        case Tag::ALL_APPLICATIONS:
         case Tag::APPLICATION_ID:
         case Tag::OS_VERSION:
         case Tag::OS_PATCHLEVEL:
 
-        /* Ignored pending removal */
-        case Tag::USER_ID:
-        case Tag::ALL_USERS:
-
         /* TODO(swillden): Handle these */
         case Tag::INCLUDE_UNIQUE_ID:
         case Tag::UNIQUE_ID:
         case Tag::RESET_SINCE_ID_ROTATION:
         case Tag::ALLOW_WHILE_ON_BODY:
+        case Tag::HARDWARE_TYPE:
             break;
 
         case Tag::BOOTLOADER_ONLY:
@@ -465,7 +459,7 @@
 }
 
 bool KeymasterEnforcement::AuthTokenMatches(const AuthorizationSet& auth_set,
-                                            const AuthorizationSet& operation_params,
+                                            const HardwareAuthToken& auth_token,
                                             const uint64_t user_secure_id,
                                             const int auth_type_index, const int auth_timeout_index,
                                             const uint64_t op_handle,
@@ -473,25 +467,6 @@
     assert(auth_type_index < static_cast<int>(auth_set.size()));
     assert(auth_timeout_index < static_cast<int>(auth_set.size()));
 
-    auto auth_token_blob = operation_params.GetTagValue(TAG_AUTH_TOKEN);
-    if (!auth_token_blob.isOk()) {
-        ALOGE("Authentication required, but auth token not provided");
-        return false;
-    }
-
-    if (auth_token_blob.value().size() != sizeof(hw_auth_token_t)) {
-        ALOGE("Bug: Auth token is the wrong size (%zu expected, %zu found)",
-              sizeof(hw_auth_token_t), auth_token_blob.value().size());
-        return false;
-    }
-    uint8_t auth_token_version = auth_token_blob.value()[0];
-    HardwareAuthToken auth_token = hidlVec2AuthToken(auth_token_blob.value());
-    if (auth_token_version != HW_AUTH_TOKEN_VERSION) {
-        ALOGE("Bug: Auth token is the version %hhu (or is not an auth token). Expected %d",
-              auth_token_version, HW_AUTH_TOKEN_VERSION);
-        return false;
-    }
-
     if (!ValidateTokenSignature(auth_token)) {
         ALOGE("Auth token signature invalid");
         return false;
@@ -518,10 +493,9 @@
     auto key_auth_type_mask = authorizationValue(TAG_USER_AUTH_TYPE, auth_set[auth_type_index]);
     if (!key_auth_type_mask.isOk()) return false;
 
-    uint32_t token_auth_type = ntoh(auth_token.authenticatorType);
-    if ((uint32_t(key_auth_type_mask.value()) & token_auth_type) == 0) {
+    if ((uint32_t(key_auth_type_mask.value()) & auth_token.authenticatorType) == 0) {
         ALOGE("Key requires match of auth type mask 0%uo, but token contained 0%uo",
-              key_auth_type_mask.value(), token_auth_type);
+              key_auth_type_mask.value(), auth_token.authenticatorType);
         return false;
     }
 
diff --git a/keystore/keymaster_enforcement.h b/keystore/keymaster_enforcement.h
index 28d546a..d751071 100644
--- a/keystore/keymaster_enforcement.h
+++ b/keystore/keymaster_enforcement.h
@@ -51,7 +51,8 @@
      */
     ErrorCode AuthorizeOperation(const KeyPurpose purpose, const km_id_t keyid,
                                  const AuthorizationSet& auth_set,
-                                 const AuthorizationSet& operation_params, uint64_t op_handle,
+                                 const AuthorizationSet& operation_params,
+                                 const HardwareAuthToken& auth_token, uint64_t op_handle,
                                  bool is_begin_operation);
 
     /**
@@ -61,16 +62,17 @@
      */
     ErrorCode AuthorizeBegin(const KeyPurpose purpose, const km_id_t keyid,
                              const AuthorizationSet& auth_set,
-                             const AuthorizationSet& operation_params);
+                             const AuthorizationSet& operation_params,
+                             NullOr<const HardwareAuthToken&> auth_token);
 
     /**
      * Iterates through the authorization set and returns the corresponding keymaster error. Will
      * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
      * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
      */
-    ErrorCode AuthorizeUpdate(const AuthorizationSet& auth_set,
-                              const AuthorizationSet& operation_params, uint64_t op_handle) {
-        return AuthorizeUpdateOrFinish(auth_set, operation_params, op_handle);
+    ErrorCode AuthorizeUpdate(const AuthorizationSet& auth_set, const HardwareAuthToken& auth_token,
+                              uint64_t op_handle) {
+        return AuthorizeUpdateOrFinish(auth_set, auth_token, op_handle);
     }
 
     /**
@@ -78,9 +80,9 @@
      * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
      * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
      */
-    ErrorCode AuthorizeFinish(const AuthorizationSet& auth_set,
-                              const AuthorizationSet& operation_params, uint64_t op_handle) {
-        return AuthorizeUpdateOrFinish(auth_set, operation_params, op_handle);
+    ErrorCode AuthorizeFinish(const AuthorizationSet& auth_set, const HardwareAuthToken& auth_token,
+                              uint64_t op_handle) {
+        return AuthorizeUpdateOrFinish(auth_set, auth_token, op_handle);
     }
 
     /**
@@ -142,14 +144,14 @@
 
   private:
     ErrorCode AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
-                                      const AuthorizationSet& operation_params, uint64_t op_handle);
+                                      const HardwareAuthToken& auth_token, uint64_t op_handle);
 
     bool MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid);
     bool MaxUsesPerBootNotExceeded(const km_id_t keyid, uint32_t max_uses);
-    bool AuthTokenMatches(const AuthorizationSet& auth_set,
-                          const AuthorizationSet& operation_params, const uint64_t user_secure_id,
-                          const int auth_type_index, const int auth_timeout_index,
-                          const uint64_t op_handle, bool is_begin_operation) const;
+    bool AuthTokenMatches(const AuthorizationSet& auth_set, const HardwareAuthToken& auth_token,
+                          const uint64_t user_secure_id, const int auth_type_index,
+                          const int auth_timeout_index, const uint64_t op_handle,
+                          bool is_begin_operation) const;
 
     AccessTimeMap* access_time_map_;
     AccessCountMap* access_count_map_;
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.cpp b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
index 1927cfc..db9b983 100644
--- a/keystore/keystore_aidl_hidl_marshalling_utils.cpp
+++ b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
@@ -15,17 +15,15 @@
 ** limitations under the License.
 */
 
-#define LOG_TAG "KeystoreService"
-#include <utils/Log.h>
-
 #include "keystore_aidl_hidl_marshalling_utils.h"
-#include <keystore/keystore_hidl_support.h>
 
-#include "include/keystore/ExportResult.h"
-#include "include/keystore/KeyCharacteristics.h"
-#include "include/keystore/KeymasterBlob.h"
-#include "include/keystore/KeymasterCertificateChain.h"
-#include "include/keystore/KeystoreArg.h"
+#include <keystore/ExportResult.h>
+#include <keystore/KeyCharacteristics.h>
+#include <keystore/KeymasterBlob.h>
+#include <keystore/KeymasterCertificateChain.h>
+#include <keystore/KeystoreArg.h>
+#include <keystore/keymaster_types.h>
+#include <keystore/keystore_hidl_support.h>
 
 namespace keystore {
 
@@ -207,8 +205,8 @@
 namespace security {
 namespace keymaster {
 
-using ::android::hardware::keymaster::V3_0::ErrorCode;
 using ::android::status_t;
+using ::keystore::keymaster::ErrorCode;
 
 ExportResult::ExportResult() : resultCode() {}
 
@@ -228,12 +226,12 @@
 
 status_t KeyCharacteristics::readFromParcel(const Parcel* in) {
     softwareEnforced.readFromParcel(in);
-    return teeEnforced.readFromParcel(in);
+    return hardwareEnforced.readFromParcel(in);
 }
 
 status_t KeyCharacteristics::writeToParcel(Parcel* out) const {
     softwareEnforced.writeToParcel(out);
-    return teeEnforced.writeToParcel(out);
+    return hardwareEnforced.writeToParcel(out);
 }
 
 status_t KeymasterBlob::readFromParcel(const Parcel* in) {
diff --git a/keystore/keystore_client_impl.cpp b/keystore/keystore_client_impl.cpp
index 99fe606..d9a824b 100644
--- a/keystore/keystore_client_impl.cpp
+++ b/keystore/keystore_client_impl.cpp
@@ -201,7 +201,7 @@
     /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
      * There are no references to Parcel memory after that, and ownership of the newly acquired
      * memory is with the AuthorizationSet objects. */
-    *hardware_enforced_characteristics = characteristics.teeEnforced.getParameters();
+    *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
     *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
     return KeyStoreNativeReturnCode(result);
 }
@@ -220,7 +220,7 @@
     /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
      * There are no references to Parcel memory after that, and ownership of the newly acquired
      * memory is with the AuthorizationSet objects. */
-    *hardware_enforced_characteristics = characteristics.teeEnforced.getParameters();
+    *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
     *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
     return KeyStoreNativeReturnCode(result);
 }
@@ -240,7 +240,7 @@
     /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
      * There are no references to Parcel memory after that, and ownership of the newly acquired
      * memory is with the AuthorizationSet objects. */
-    *hardware_enforced_characteristics = characteristics.teeEnforced.getParameters();
+    *hardware_enforced_characteristics = characteristics.hardwareEnforced.getParameters();
     *software_enforced_characteristics = characteristics.softwareEnforced.getParameters();
     return KeyStoreNativeReturnCode(result);
 }
diff --git a/keystore/keystore_main.cpp b/keystore/keystore_main.cpp
index 59361b4..f4ccf04 100644
--- a/keystore/keystore_main.cpp
+++ b/keystore/keystore_main.cpp
@@ -14,13 +14,10 @@
  * limitations under the License.
  */
 
-//#define LOG_NDEBUG 0
-#define LOG_TAG "keystore"
-
+#include <android-base/logging.h>
 #include <android/system/wifi/keystore/1.0/IKeystore.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
-#include <cutils/log.h>
 #include <utils/StrongPointer.h>
 #include <wifikeystorehal/keystore.h>
 
@@ -53,57 +50,37 @@
 
 int main(int argc, char* argv[]) {
     using android::hardware::hidl_string;
-    if (argc < 2) {
-        ALOGE("A directory must be specified!");
-        return 1;
-    }
-    if (chdir(argv[1]) == -1) {
-        ALOGE("chdir: %s: %s", argv[1], strerror(errno));
-        return 1;
-    }
+    CHECK(argc >= 2) << "A directory must be specified!";
+    CHECK(chdir(argv[1]) != -1) << "chdir: " << argv[1] << ": " << strerror(errno);
 
     Entropy entropy;
-    if (!entropy.open()) {
-        return 1;
-    }
+    CHECK(entropy.open()) << "Failed to open entropy source.";
 
     auto hwdev = android::hardware::keymaster::V3_0::IKeymasterDevice::getService();
-    if (hwdev.get() == nullptr) return -1;
+    CHECK(hwdev.get()) << "Failed to load @3.0::IKeymasterDevice";
     sp<Keymaster> dev = new keystore::Keymaster3(hwdev);
 
     auto fbdev = android::keystore::makeSoftwareKeymasterDevice();
     if (fbdev.get() == nullptr) return -1;
     sp<Keymaster> fallback = new keystore::Keymaster3(fbdev);
 
-    if (configure_selinux() == -1) {
-        return -1;
-    }
+    CHECK(configure_selinux() != -1) << "Failed to configure SELinux.";
 
-    bool allowNewFallbackDevice = false;
+    auto halVersion = dev->halVersion();
+    CHECK(halVersion.error == keystore::ErrorCode::OK)
+        << "Error " << toString(halVersion.error) << " getting HAL version";
 
-    keystore::KeyStoreServiceReturnCode rc;
-    rc = KS_HANDLE_HIDL_ERROR(
-        dev->getHardwareFeatures([&](bool, bool, bool, bool supportsAttestation, bool,
-                                     const hidl_string&, const hidl_string&) {
-            // Attestation support indicates the hardware is keymaster 2.0 or higher.
-            // For these devices we will not allow the fallback device for import or generation
-            // of keys. The fallback device is only used for legacy keys present on the device.
-            allowNewFallbackDevice = !supportsAttestation;
-        }));
-
-    if (!rc.isOk()) {
-        return -1;
-    }
+    // If the hardware is keymaster 2.0 or higher we will not allow the fallback device for import
+    // or generation of keys. The fallback device is only used for legacy keys present on the
+    // device.
+    bool allowNewFallbackDevice = halVersion.majorVersion >= 2 && halVersion.isSecure;
 
     keystore::KeyStore keyStore(&entropy, dev, fallback, allowNewFallbackDevice);
     keyStore.initialize();
     android::sp<android::IServiceManager> sm = android::defaultServiceManager();
     android::sp<keystore::KeyStoreService> service = new keystore::KeyStoreService(&keyStore);
     android::status_t ret = sm->addService(android::String16("android.security.keystore"), service);
-    if (ret != android::OK) {
-        ALOGE("Couldn't register binder service!");
-        return -1;
-    }
+    CHECK(ret == android::OK) << "Couldn't register binder service!";
 
     /**
      * Register the wifi keystore HAL service to run in passthrough mode.
@@ -113,9 +90,7 @@
     configureRpcThreadpool(1, false /* callerWillJoin */);
     android::sp<IKeystore> wifiKeystoreHalService = new Keystore();
     android::status_t err = wifiKeystoreHalService->registerAsService();
-    if (ret != android::OK) {
-        ALOGE("Cannot register wifi keystore HAL service: %d", err);
-    }
+    CHECK(ret == android::OK) << "Cannot register wifi keystore HAL service: " << err;
 
     /*
      * This thread is just going to process Binder transactions.
diff --git a/keystore/keystore_utils.cpp b/keystore/keystore_utils.cpp
index 54883b9..54f61cc 100644
--- a/keystore/keystore_utils.cpp
+++ b/keystore/keystore_utils.cpp
@@ -78,7 +78,6 @@
     params->push_back(TAG_DIGEST, Digest::SHA_2_256);
     params->push_back(TAG_DIGEST, Digest::SHA_2_384);
     params->push_back(TAG_DIGEST, Digest::SHA_2_512);
-    params->push_back(TAG_ALL_USERS);
     params->push_back(TAG_NO_AUTH_REQUIRED);
     params->push_back(TAG_ORIGINATION_EXPIRE_DATETIME, LLONG_MAX);
     params->push_back(TAG_USAGE_EXPIRE_DATETIME, LLONG_MAX);
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
index 66fcee2..e09d515 100644
--- a/keystore/operation.cpp
+++ b/keystore/operation.cpp
@@ -25,8 +25,7 @@
     : mDeathRecipient(deathRecipient) {}
 
 sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
-                                       const OperationMap::km_device_t& dev,
-                                       const sp<IBinder>& appToken,
+                                       const sp<Keymaster>& dev, const sp<IBinder>& appToken,
                                        KeyCharacteristics&& characteristics, bool pruneable) {
     sp<IBinder> token = new ::android::BBinder();
     mMap.emplace(token,
@@ -100,7 +99,7 @@
     auto entry = mMap.find(token);
     if (entry == mMap.end()) return false;
 
-    entry->second.authToken = std::make_unique<HardwareAuthToken>(std::move(authToken));
+    entry->second.authToken = std::move(authToken);
     return true;
 }
 
@@ -111,7 +110,7 @@
 }
 
 OperationMap::Operation::Operation(uint64_t handle_, uint64_t keyid_, KeyPurpose purpose_,
-                                   const OperationMap::km_device_t& device_,
+                                   const sp<Keymaster>& device_,
                                    KeyCharacteristics&& characteristics_, sp<IBinder> appToken_)
     : handle(handle_), keyid(keyid_), purpose(purpose_), device(device_),
       characteristics(characteristics_), appToken(appToken_) {}
diff --git a/keystore/operation.h b/keystore/operation.h
index ac8e945..6e97346 100644
--- a/keystore/operation.h
+++ b/keystore/operation.h
@@ -17,13 +17,16 @@
 #ifndef KEYSTORE_OPERATION_H_
 #define KEYSTORE_OPERATION_H_
 
+#include <map>
+#include <vector>
+
 #include <binder/Binder.h>
 #include <binder/IBinder.h>
-#include <keystore/keymaster_tags.h>
-#include <map>
-#include <utils/LruCache.h>
 #include <utils/StrongPointer.h>
-#include <vector>
+
+#include <keystore/keymaster_tags.h>
+
+#include "Keymaster.h"
 
 namespace keystore {
 
@@ -38,28 +41,28 @@
  */
 
 class OperationMap {
-    typedef sp<::android::hardware::keymaster::V3_0::IKeymasterDevice> km_device_t;
-
   public:
     struct Operation {
         Operation() = default;
-        Operation(uint64_t handle, uint64_t keyid, KeyPurpose purpose, const km_device_t& device,
+        Operation(uint64_t handle, uint64_t keyid, KeyPurpose purpose, const sp<Keymaster>& device,
                   KeyCharacteristics&& characteristics, sp<IBinder> appToken);
         Operation(Operation&&) = default;
         Operation(const Operation&) = delete;
 
+        bool hasAuthToken() const { return authToken.mac.size() == 0; }
+
         uint64_t handle;
         uint64_t keyid;
         KeyPurpose purpose;
-        km_device_t device;
+        sp<Keymaster> device;
         KeyCharacteristics characteristics;
         sp<IBinder> appToken;
-        std::unique_ptr<HardwareAuthToken> authToken;
+        HardwareAuthToken authToken;
     };
 
     explicit OperationMap(IBinder::DeathRecipient* deathRecipient);
     sp<IBinder> addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
-                             const km_device_t& dev, const sp<IBinder>& appToken,
+                             const sp<Keymaster>& dev, const sp<IBinder>& appToken,
                              KeyCharacteristics&& characteristics, bool pruneable);
     NullOr<const Operation&> getOperation(const sp<IBinder>& token);
     NullOr<Operation> removeOperation(const sp<IBinder>& token);
diff --git a/keystore/tests/auth_token_formatting_test.cpp b/keystore/tests/auth_token_formatting_test.cpp
index d6e712e..511256f 100644
--- a/keystore/tests/auth_token_formatting_test.cpp
+++ b/keystore/tests/auth_token_formatting_test.cpp
@@ -16,11 +16,11 @@
 
 #include <gtest/gtest.h>
 
-#include <endian.h>
-#include <keymaster/logger.h>
-#include <hidl/HidlSupport.h>
 #include <android/hardware/keymaster/3.0/types.h>
+#include <endian.h>
 #include <hardware/hw_auth_token.h>
+#include <hidl/HidlSupport.h>
+#include <keymaster/logger.h>
 
 #include "../auth_token_table.h"
 #include <keystore/keystore_hidl_support.h>
@@ -32,7 +32,7 @@
 
 namespace {
 
-class StdoutLogger : public keymaster::Logger {
+class StdoutLogger : public ::keymaster::Logger {
   public:
     StdoutLogger() { set_instance(this); }
 
@@ -64,69 +64,92 @@
 
 StdoutLogger logger;
 
-}
+}  // namespace
 
-
-using android::hardware::keymaster::V3_0::HardwareAuthToken;
-using android::hardware::hidl_vec;
 using android::hardware::hidl_array;
+using android::hardware::hidl_vec;
 
 constexpr const uint8_t test_token[69] = {
-        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-        0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
-        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
-        0x40, 0x41, 0x42, 0x43, 0x44
-};
-
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+    0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
+    0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
+    0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44};
 
 constexpr const uint8_t test_hmac_data[] = {
-        0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c,
-        0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
-        0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c,
-        0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44 };
+    0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34,
+    0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44};
 
-static const HardwareAuthToken hidl_test_token_little_endian = {
-        UINT64_C(0x0807060504030201),
-        UINT64_C(0x100f0e0d0c0b0a09),
-        UINT64_C(0x1817161514131211),
-        UINT32_C(0x1c1b1a19),
-        UINT64_C(0x24232221201f1e1d),
-        hidl_array<uint8_t, 32>(test_hmac_data)
-};
+static const Km3HardwareAuthToken km3_hidl_test_token_little_endian = {
+    UINT64_C(0x0807060504030201), UINT64_C(0x100f0e0d0c0b0a09),
+    UINT64_C(0x1817161514131211), UINT32_C(0x1c1b1a19),
+    UINT64_C(0x24232221201f1e1d), hidl_array<uint8_t, 32>(test_hmac_data)};
 
+static const HardwareAuthToken km4_hidl_test_token = {
+    UINT64_C(0x0807060504030201), UINT64_C(0x100f0e0d0c0b0a09),
+    UINT64_C(0x1817161514131211), static_cast<HardwareAuthenticatorType>(UINT32_C(0x191a1b1c)),
+    UINT64_C(0x1d1e1f2021222324), hidl_vec<uint8_t>(test_hmac_data, test_hmac_data + 32)};
 
-TEST(AuthenticationTokenFormattingTest, hidlVec2AuthToken) {
+TEST(AuthenticationTokenFormattingTest, hidlVec2Km3AuthToken) {
     static_assert(sizeof(hw_auth_token_t) == sizeof(test_token), "test_token has wrong size");
     hidl_vec<uint8_t> hidl_test_token;
     hidl_test_token.setToExternal(const_cast<unsigned char*>(test_token), sizeof(test_token));
-    ASSERT_EQ(hidl_test_token_little_endian, hidlVec2AuthToken(hidl_test_token));
+    ASSERT_EQ(km3_hidl_test_token_little_endian, hidlVec2Km3AuthToken(hidl_test_token));
 }
 
-TEST(AuthenticationTokenFormattingTest, authToken2HidlVec) {
+TEST(AuthenticationTokenFormattingTest, hidlVec2Km4AuthToken) {
     static_assert(sizeof(hw_auth_token_t) == sizeof(test_token), "test_token has wrong size");
     hidl_vec<uint8_t> hidl_test_token;
     hidl_test_token.setToExternal(const_cast<unsigned char*>(test_token), sizeof(test_token));
-    ASSERT_EQ(hidl_test_token, authToken2HidlVec(hidl_test_token_little_endian));
+    ASSERT_EQ(km4_hidl_test_token, hidlVec2AuthToken(hidl_test_token));
+}
+
+TEST(AuthenticationTokenFormattingTest, km3AuthToken2HidlVec) {
+    static_assert(sizeof(hw_auth_token_t) == sizeof(test_token), "test_token has wrong size");
+    hidl_vec<uint8_t> hidl_test_token;
+    hidl_test_token.setToExternal(const_cast<unsigned char*>(test_token), sizeof(test_token));
+    ASSERT_EQ(hidl_test_token, authToken2HidlVec(km3_hidl_test_token_little_endian));
+}
+
+TEST(AuthenticationTokenFormattingTest, km4AuthToken2HidlVec) {
+    static_assert(sizeof(hw_auth_token_t) == sizeof(test_token), "test_token has wrong size");
+    hidl_vec<uint8_t> hidl_test_token;
+    hidl_test_token.setToExternal(const_cast<unsigned char*>(test_token), sizeof(test_token));
+    ASSERT_EQ(hidl_test_token, authToken2HidlVec(km4_hidl_test_token));
 }
 
 TEST(AuthenticationTokenFormattingTest, backAndForth) {
     static_assert(sizeof(hw_auth_token_t) == sizeof(test_token), "test_token has wrong size");
     hidl_vec<uint8_t> hidl_test_token;
     hidl_test_token.setToExternal(const_cast<unsigned char*>(test_token), sizeof(test_token));
-    ASSERT_EQ(hidl_test_token_little_endian, hidlVec2AuthToken(authToken2HidlVec(hidl_test_token_little_endian)));
+    ASSERT_EQ(km3_hidl_test_token_little_endian,
+              hidlVec2Km3AuthToken(authToken2HidlVec(km3_hidl_test_token_little_endian)));
+    ASSERT_EQ(km4_hidl_test_token, hidlVec2AuthToken(authToken2HidlVec(km4_hidl_test_token)));
 }
 
 TEST(AuthenticationTokenFormattingTest, forthAndBack) {
     static_assert(sizeof(hw_auth_token_t) == sizeof(test_token), "test_token has wrong size");
     hidl_vec<uint8_t> hidl_test_token;
     hidl_test_token.setToExternal(const_cast<unsigned char*>(test_token), sizeof(test_token));
-    ASSERT_EQ(hidl_test_token, authToken2HidlVec(hidlVec2AuthToken(hidl_test_token)));
+    ASSERT_EQ(hidl_test_token, authToken2HidlVec(hidlVec2Km3AuthToken(hidl_test_token)));
+    ASSERT_EQ(hidl_test_token, authToken2HidlVec(hidlVec2Km3AuthToken(hidl_test_token)));
 }
 
-}  // namespace keymaster
+TEST(AuthenticationTokenFormattingTest, roundAndRound) {
+    static_assert(sizeof(hw_auth_token_t) == sizeof(test_token), "test_token has wrong size");
+    hidl_vec<uint8_t> hidl_test_token;
+    hidl_test_token.setToExternal(const_cast<unsigned char*>(test_token), sizeof(test_token));
+    HardwareAuthToken km4_from_hidl = hidlVec2AuthToken(hidl_test_token);
+    hidl_vec<uint8_t> hidl_from_km4 = authToken2HidlVec(km4_from_hidl);
+    Km3HardwareAuthToken km3_from_hidl = hidlVec2Km3AuthToken(hidl_from_km4);
+    hidl_vec<uint8_t> hidl_from_km3 = authToken2HidlVec(km3_from_hidl);
+
+    ASSERT_EQ(hidl_from_km4, hidl_test_token);
+    ASSERT_EQ(hidl_from_km3, hidl_test_token);
+    ASSERT_NE(km4_from_hidl.timestamp, km3_from_hidl.timestamp);
+    ASSERT_NE(static_cast<uint32_t>(km4_from_hidl.authenticatorType),
+              km3_from_hidl.authenticatorType);
+}
+
 }  // namespace test
+}  // namespace keystore
diff --git a/keystore/tests/auth_token_table_test.cpp b/keystore/tests/auth_token_table_test.cpp
index 5206ba2..1a5ef90 100644
--- a/keystore/tests/auth_token_table_test.cpp
+++ b/keystore/tests/auth_token_table_test.cpp
@@ -26,7 +26,7 @@
 namespace keystore {
 namespace test {
 
-class StdoutLogger : public keymaster::Logger {
+class StdoutLogger : public ::keymaster::Logger {
   public:
     StdoutLogger() { set_instance(this); }
 
@@ -62,26 +62,23 @@
     AuthTokenTable table;
 }
 
-static std::unique_ptr<const HardwareAuthToken> make_token(uint64_t rsid, uint64_t ssid = 0,
-                                                     uint64_t challenge = 0,
-                                                     uint64_t timestamp = 0) {
-    std::unique_ptr<HardwareAuthToken> token(new HardwareAuthToken);
-    token->userId = rsid;
-    token->authenticatorId = ssid;
-    token->authenticatorType = htonl(static_cast<uint32_t>(HardwareAuthenticatorType::PASSWORD));
-    token->challenge = challenge;
-    token->timestamp = htonq(timestamp);
+HardwareAuthToken make_token(uint64_t rsid, uint64_t ssid = 0, uint64_t challenge = 0,
+                             uint64_t timestamp = 0) {
+    HardwareAuthToken token;
+    token.userId = rsid;
+    token.authenticatorId = ssid;
+    token.authenticatorType = HardwareAuthenticatorType::PASSWORD;
+    token.challenge = challenge;
+    token.timestamp = timestamp;
     return token;
 }
 
 static AuthorizationSet make_set(uint64_t rsid, uint32_t timeout = 10000) {
     AuthorizationSetBuilder builder;
-    builder.Authorization(TAG_USER_ID, 10)
-        .Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::PASSWORD)
+    builder.Authorization(TAG_USER_AUTH_TYPE, HardwareAuthenticatorType::PASSWORD)
         .Authorization(TAG_USER_SECURE_ID, rsid);
     // Use timeout == 0 to indicate tags that require auth per operation.
-    if (timeout != 0)
-        builder.Authorization(TAG_AUTH_TIMEOUT, timeout);
+    if (timeout != 0) builder.Authorization(TAG_AUTH_TIMEOUT, timeout);
     return builder;
 }
 
@@ -101,19 +98,23 @@
 
     const HardwareAuthToken* found;
 
-    ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
+    ASSERT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
     EXPECT_EQ(1U, found->userId);
     EXPECT_EQ(2U, found->authenticatorId);
 
-    ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+    ASSERT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
     EXPECT_EQ(1U, found->userId);
     EXPECT_EQ(2U, found->authenticatorId);
 
-    ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+    ASSERT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
     EXPECT_EQ(3U, found->userId);
     EXPECT_EQ(4U, found->authenticatorId);
 
-    ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
+    ASSERT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
     EXPECT_EQ(3U, found->userId);
     EXPECT_EQ(4U, found->authenticatorId);
 
@@ -132,9 +133,12 @@
 
     // All three should be in the table.
     EXPECT_EQ(3U, table.size());
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
 
     table.Clear();
     EXPECT_EQ(0U, table.size());
@@ -151,9 +155,12 @@
 
     // All three should be in the table.
     EXPECT_EQ(3U, table.size());
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
 
     table.AddAuthenticationToken(make_token(4));
 
@@ -164,9 +171,12 @@
 
     // Others should be there, including the new one (4).  Search for it first, then the others, so
     // 4 becomes the least recently used.
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
 
     table.AddAuthenticationToken(make_token(5));
 
@@ -174,9 +184,12 @@
     EXPECT_EQ(3U, table.size());
     EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
               table.FindAuthorization(make_set(4), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
 
     table.AddAuthenticationToken(make_token(6));
     table.AddAuthenticationToken(make_token(7));
@@ -187,9 +200,12 @@
               table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
     EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
               table.FindAuthorization(make_set(5), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(6), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(7), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(6), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(7), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(3), KeyPurpose::SIGN, 0, &found));
 
     table.AddAuthenticationToken(make_token(8));
     table.AddAuthenticationToken(make_token(9));
@@ -211,8 +227,10 @@
               table.FindAuthorization(make_set(6), KeyPurpose::SIGN, 0, &found));
     EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
               table.FindAuthorization(make_set(7), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(8), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(9), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(8), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(9), KeyPurpose::SIGN, 0, &found));
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(10), KeyPurpose::SIGN, 0, &found));
 }
@@ -222,9 +240,8 @@
     const HardwareAuthToken* found;
 
     EXPECT_EQ(AuthTokenTable::AUTH_NOT_REQUIRED,
-              table.FindAuthorization(
-                  AuthorizationSetBuilder().Authorization(TAG_NO_AUTH_REQUIRED),
-                  KeyPurpose::SIGN, 0 /* no challenge */, &found));
+              table.FindAuthorization(AuthorizationSetBuilder().Authorization(TAG_NO_AUTH_REQUIRED),
+                                      KeyPurpose::SIGN, 0 /* no challenge */, &found));
 }
 
 TEST(AuthTokenTableTest, OperationHandleNotFound) {
@@ -306,8 +323,9 @@
     table.AddAuthenticationToken(make_token(1, 0, 0, 0));
     table.AddAuthenticationToken(make_token(1, 0, 0, 1));
     EXPECT_EQ(1U, table.size());
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(1U, ntohq(found->timestamp));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(1U, found->timestamp);
 
     // Add a third token, this with a different RSID.  It should not be superseded.
     table.AddAuthenticationToken(make_token(2, 0, 0, 2));
@@ -317,10 +335,12 @@
     table.AddAuthenticationToken(make_token(1, 0, 0, 3));
     table.AddAuthenticationToken(make_token(2, 0, 0, 4));
     EXPECT_EQ(2U, table.size());
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(3U, ntohq(found->timestamp));
-    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
-    EXPECT_EQ(4U, ntohq(found->timestamp));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(3U, found->timestamp);
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0, &found));
+    EXPECT_EQ(4U, found->timestamp);
 
     // Add another, this one with a challenge value.  It should supersede the old one since it is
     // newer, and matches other than the challenge.
@@ -337,11 +357,11 @@
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(1, 0 /* no timeout*/), KeyPurpose::SIGN,
                                       1 /* challenge */, &found));
-    EXPECT_EQ(5U, ntohq(found->timestamp));
+    EXPECT_EQ(5U, found->timestamp);
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
                                       2 /* challenge */, &found));
-    EXPECT_EQ(6U, ntohq(found->timestamp));
+    EXPECT_EQ(6U, found->timestamp);
 
     // Add another, without a challenge, and the same timestamp as the last one.  This new one
     // actually could be considered already-superseded, but the table doesn't handle that case,
@@ -350,7 +370,7 @@
     EXPECT_EQ(4U, table.size());
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(6U, ntohq(found->timestamp));
+    EXPECT_EQ(6U, found->timestamp);
 
     // Add another without a challenge but an increased timestamp. This should supersede the
     // previous challenge-free entry.
@@ -359,10 +379,10 @@
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
                                       2 /* challenge */, &found));
-    EXPECT_EQ(6U, ntohq(found->timestamp));
+    EXPECT_EQ(6U, found->timestamp);
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(7U, ntohq(found->timestamp));
+    EXPECT_EQ(7U, found->timestamp);
 
     // Mark the entry with challenge 2 as complete.  Since there's a newer challenge-free entry, the
     // challenge entry will be superseded.
@@ -373,7 +393,7 @@
                                       2 /* challenge */, &found));
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(7U, ntohq(found->timestamp));
+    EXPECT_EQ(7U, found->timestamp);
 
     // Add another SID 1 entry with a challenge.  It supersedes the previous SID 1 entry with
     // no challenge (timestamp 7), but not the one with challenge 1 (timestamp 5).
@@ -383,17 +403,17 @@
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
                                       1 /* challenge */, &found));
-    EXPECT_EQ(5U, ntohq(found->timestamp));
+    EXPECT_EQ(5U, found->timestamp);
 
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
                                       3 /* challenge */, &found));
-    EXPECT_EQ(8U, ntohq(found->timestamp));
+    EXPECT_EQ(8U, found->timestamp);
 
     // SID 2 entry is still there.
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(2), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(4U, ntohq(found->timestamp));
+    EXPECT_EQ(4U, found->timestamp);
 
     // Mark the entry with challenge 3 as complete.  Since the older challenge 1 entry is
     // incomplete, nothing is superseded.
@@ -403,11 +423,11 @@
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(1, 0 /* no timeout */), KeyPurpose::SIGN,
                                       1 /* challenge */, &found));
-    EXPECT_EQ(5U, ntohq(found->timestamp));
+    EXPECT_EQ(5U, found->timestamp);
 
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(8U, ntohq(found->timestamp));
+    EXPECT_EQ(8U, found->timestamp);
 
     // Mark the entry with challenge 1 as complete.  Since there's a newer one (with challenge 3,
     // completed), the challenge 1 entry is superseded and removed.
@@ -418,8 +438,8 @@
                                       1 /* challenge */, &found));
     EXPECT_EQ(AuthTokenTable::OK,
               table.FindAuthorization(make_set(1), KeyPurpose::SIGN, 0 /* challenge */, &found));
-    EXPECT_EQ(8U, ntohq(found->timestamp));
+    EXPECT_EQ(8U, found->timestamp);
 }
 
-}  // namespace keymaster
 }  // namespace test
+}  // namespace keystore