diff --git a/keystore-engine/Android.mk b/keystore-engine/Android.mk
index b4ba269..8988857 100644
--- a/keystore-engine/Android.mk
+++ b/keystore-engine/Android.mk
@@ -19,19 +19,48 @@
 LOCAL_MODULE := libkeystore-engine
 
 LOCAL_SRC_FILES := \
-	android_engine.cpp
+	android_engine.cpp \
+	keystore_backend_binder.cpp
 
 LOCAL_MODULE_TAGS := optional
 LOCAL_CFLAGS := -fvisibility=hidden -Wall -Werror
 
 LOCAL_SHARED_LIBRARIES += \
-	libcrypto \
-	liblog \
-	libcutils \
-	libutils \
 	libbinder \
-	libkeystore_binder
+	libcrypto \
+	libcutils \
+	libhidlbase \
+	libkeystore_binder \
+	liblog \
+	libutils
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+# This builds a variant of libkeystore-engine that uses a HIDL HAL
+# owned by the WiFi user to perform signing operations.
+LOCAL_MODULE := libkeystore-engine-wifi-hidl
+
+LOCAL_SRC_FILES := \
+	android_engine.cpp \
+	keystore_backend_hidl.cpp
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := -fvisibility=hidden -Wall -Werror -DBACKEND_WIFI_HIDL
+
+LOCAL_SHARED_LIBRARIES += \
+	android.system.wifi.keystore@1.0 \
+	libcrypto \
+	liblog \
+	libhidlbase \
+	libhidltransport \
+	libcutils \
+	libutils
+
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_VENDOR_MODULE := true
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/keystore-engine/android_engine.cpp b/keystore-engine/android_engine.cpp
index de67df2..25d426f 100644
--- a/keystore-engine/android_engine.cpp
+++ b/keystore-engine/android_engine.cpp
@@ -20,13 +20,17 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
 
+#define LOG_TAG "keystore-engine"
 #include <UniquePtr.h>
 
+#include <pthread.h>
 #include <sys/socket.h>
 #include <stdarg.h>
 #include <string.h>
 #include <unistd.h>
 
+#include <cutils/log.h>
+
 #include <openssl/bn.h>
 #include <openssl/ec.h>
 #include <openssl/ec_key.h>
@@ -36,14 +40,13 @@
 #include <openssl/rsa.h>
 #include <openssl/x509.h>
 
-#include <binder/IServiceManager.h>
-#include <keystore/keystore.h>
-#include <keystore/IKeystoreService.h>
-
-using namespace android;
+#ifndef BACKEND_WIFI_HIDL
+#include "keystore_backend_binder.h"
+#else
+#include "keystore_backend_hidl.h"
+#endif
 
 namespace {
-
 extern const RSA_METHOD keystore_rsa_method;
 extern const ECDSA_METHOD keystore_ecdsa_method;
 
@@ -107,11 +110,17 @@
 
 pthread_once_t g_keystore_engine_once = PTHREAD_ONCE_INIT;
 KeystoreEngine *g_keystore_engine;
+KeystoreBackend *g_keystore_backend;
 
 /* init_keystore_engine is called to initialize |g_keystore_engine|. This
  * should only be called by |pthread_once|. */
 void init_keystore_engine() {
     g_keystore_engine = new KeystoreEngine;
+#ifndef BACKEND_WIFI_HIDL
+    g_keystore_backend = new KeystoreBackendBinder;
+#else
+    g_keystore_backend = new KeystoreBackendHidl;
+#endif
 }
 
 /* ensure_keystore_engine ensures that |g_keystore_engine| is pointing to a
@@ -139,33 +148,25 @@
 int rsa_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) {
     ALOGV("rsa_private_transform(%p, %p, %p, %u)", rsa, out, in, (unsigned) len);
 
+    ensure_keystore_engine();
+
     const char *key_id = rsa_get_key_id(rsa);
     if (key_id == NULL) {
         ALOGE("key had no key_id!");
         return 0;
     }
 
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
-    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-
-    if (service == NULL) {
-        ALOGE("could not contact keystore");
-        return 0;
-    }
-
     uint8_t* reply = NULL;
     size_t reply_len;
-    int32_t ret = service->sign(String16(key_id), in, len, &reply, &reply_len);
+    int32_t ret = g_keystore_backend->sign(key_id, in, len, &reply, &reply_len);
     if (ret < 0) {
         ALOGW("There was an error during rsa_decrypt: could not connect");
         return 0;
     } else if (ret != 0) {
         ALOGW("Error during sign from keystore: %d", ret);
         return 0;
-    } else if (reply_len == 0) {
+    } else if (reply_len == 0 || reply == NULL) {
         ALOGW("No valid signature returned");
-        free(reply);
         return 0;
     }
 
@@ -174,20 +175,20 @@
          * the modulus so we assume that the result has extra zeros on the
          * left. This provides attackers with an oracle, but there's nothing
          * that we can do about it here. */
-        memcpy(out, reply + reply_len - len, len);
+        ALOGW("Reply len %zu greater than expected %zu", reply_len, len);
+        memcpy(out, &reply[reply_len - len], len);
     } else if (reply_len < len) {
         /* If the Keystore implementation returns a short value we assume that
          * it's because it removed leading zeros from the left side. This is
          * bad because it provides attackers with an oracle but we cannot do
          * anything about a broken Keystore implementation here. */
+        ALOGW("Reply len %zu lesser than expected %zu", reply_len, len);
         memset(out, 0, len);
-        memcpy(out + len - reply_len, reply, reply_len);
+        memcpy(out + len - reply_len, &reply[0], reply_len);
     } else {
-        memcpy(out, reply, len);
+        memcpy(out, &reply[0], len);
     }
 
-    free(reply);
-
     ALOGV("rsa=%p keystore_rsa_priv_dec successful", rsa);
     return 1;
 }
@@ -236,44 +237,33 @@
                       unsigned int* sig_len, EC_KEY* ec_key) {
     ALOGV("ecdsa_sign(%p, %u, %p)", digest, (unsigned) digest_len, ec_key);
 
+    ensure_keystore_engine();
+
     const char *key_id = ecdsa_get_key_id(ec_key);
     if (key_id == NULL) {
         ALOGE("key had no key_id!");
         return 0;
     }
 
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
-    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-
-    if (service == NULL) {
-        ALOGE("could not contact keystore");
-        return 0;
-    }
-
     size_t ecdsa_size = ECDSA_size(ec_key);
 
     uint8_t* reply = NULL;
     size_t reply_len;
-    int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)),
-                                digest, digest_len, &reply, &reply_len);
+    int32_t ret = g_keystore_backend->sign(
+            key_id, digest, digest_len, &reply, &reply_len);
     if (ret < 0) {
         ALOGW("There was an error during ecdsa_sign: could not connect");
         return 0;
-    } else if (ret != 0) {
-        ALOGW("Error during sign from keystore: %d", ret);
-        return 0;
-    } else if (reply_len == 0) {
+    } else if (reply_len == 0 || reply == NULL) {
         ALOGW("No valid signature returned");
-        free(reply);
         return 0;
     } else if (reply_len > ecdsa_size) {
         ALOGW("Signature is too large");
-        free(reply);
         return 0;
     }
 
-    memcpy(sig, reply, reply_len);
+    // Reviewer: should't sig_len be checked here? Or is it just assumed that it is at least ecdsa_size?
+    memcpy(sig, &reply[0], reply_len);
     *sig_len = reply_len;
 
     ALOGV("ecdsa_sign(%p, %u, %p) => success", digest, (unsigned)digest_len,
@@ -401,36 +391,26 @@
 EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id) {
     ALOGV("EVP_PKEY_from_keystore(\"%s\")", key_id);
 
-    sp<IServiceManager> sm = defaultServiceManager();
-    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
-    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
-
-    if (service == NULL) {
-        ALOGE("could not contact keystore");
-        return 0;
-    }
+    ensure_keystore_engine();
 
     uint8_t *pubkey = NULL;
     size_t pubkey_len;
-    int32_t ret = service->get_pubkey(String16(key_id), &pubkey, &pubkey_len);
+    int32_t ret = g_keystore_backend->get_pubkey(key_id, &pubkey, &pubkey_len);
     if (ret < 0) {
         ALOGW("could not contact keystore");
         return NULL;
-    } else if (ret != 0) {
+    } else if (ret != 0 || pubkey == NULL) {
         ALOGW("keystore reports error: %d", ret);
         return NULL;
     }
 
     const uint8_t *inp = pubkey;
     Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &inp, pubkey_len));
-    free(pubkey);
     if (pkey.get() == NULL) {
         ALOGW("Cannot convert pubkey");
         return NULL;
     }
 
-    ensure_keystore_engine();
-
     EVP_PKEY *result;
     switch (EVP_PKEY_type(pkey->type)) {
     case EVP_PKEY_RSA: {
diff --git a/keystore-engine/keystore_backend.h b/keystore-engine/keystore_backend.h
new file mode 100644
index 0000000..88c94b3
--- /dev/null
+++ b/keystore-engine/keystore_backend.h
@@ -0,0 +1,37 @@
+/* Copyright 2017 The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#ifndef ANDROID_KEYSTORE_BACKEND_H
+#define ANDROID_KEYSTORE_BACKEND_H
+
+#include <stdint.h>
+
+class KeystoreBackend {
+  public:
+    virtual ~KeystoreBackend() {}
+    virtual int32_t sign(const char *key_id, const uint8_t* in, size_t len,
+                         uint8_t** reply, size_t* reply_len) = 0;
+    virtual int32_t get_pubkey(const char *key_id, uint8_t** pubkey,
+                               size_t* reply_len) = 0;
+};
+
+#endif  // ANDROID_KEYSTORE_BACKEND_H
diff --git a/keystore-engine/keystore_backend_binder.cpp b/keystore-engine/keystore_backend_binder.cpp
new file mode 100644
index 0000000..dce8242
--- /dev/null
+++ b/keystore-engine/keystore_backend_binder.cpp
@@ -0,0 +1,82 @@
+/* Copyright 2017 The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "keystore_backend_binder.h"
+
+#include <binder/IServiceManager.h>
+#include <keystore/keystore.h>
+#include <keystore/IKeystoreService.h>
+#include <keystore/keystore_hidl_support.h>
+
+using namespace android;
+using keystore::blob2hidlVec;
+using keystore::hidl_vec;
+
+namespace {
+const char keystore_service_name[] = "android.security.keystore";
+};
+
+int32_t KeystoreBackendBinder::sign(
+        const char *key_id, const uint8_t* in, size_t len, uint8_t** reply,
+        size_t* reply_len) {
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16(keystore_service_name));
+    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
+
+    if (service == NULL) {
+        ALOGE("could not contact keystore");
+        return -1;
+    }
+
+    auto inBlob = blob2hidlVec(in ,len);
+    hidl_vec<uint8_t> reply_vec;
+    auto ret = service->sign(String16(key_id), inBlob, &reply_vec);
+    if (!ret.isOk()) {
+        return -1;
+    }
+
+    *reply = reply_vec.releaseData();
+    *reply_len = reply_vec.size();
+    return 0;
+}
+
+int32_t KeystoreBackendBinder::get_pubkey(
+        const char *key_id, uint8_t** pubkey, size_t* pubkey_len) {
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16(keystore_service_name));
+    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
+
+    if (service == NULL) {
+        ALOGE("could not contact keystore");
+        return -1;
+    }
+
+    hidl_vec<uint8_t> pubkey_vec;
+    auto ret = service->get_pubkey(String16(key_id), &pubkey_vec);
+    if (!ret.isOk()) {
+        return -1;
+    }
+
+    *pubkey = pubkey_vec.releaseData();
+    *pubkey_len = pubkey_vec.size();
+    return 0;
+}
diff --git a/keystore-engine/keystore_backend_binder.h b/keystore-engine/keystore_backend_binder.h
new file mode 100644
index 0000000..1db90f7
--- /dev/null
+++ b/keystore-engine/keystore_backend_binder.h
@@ -0,0 +1,38 @@
+/* Copyright 2017 The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#ifndef ANDROID_KEYSTORE_BACKEND_BINDER_H
+#define ANDROID_KEYSTORE_BACKEND_BINDER_H
+
+#include "keystore_backend.h"
+
+class KeystoreBackendBinder : public KeystoreBackend {
+  public:
+    KeystoreBackendBinder() {}
+    virtual ~KeystoreBackendBinder() {}
+    int32_t sign(const char *key_id, const uint8_t* in, size_t len,
+                 uint8_t** reply, size_t* reply_len) override;
+    int32_t get_pubkey(const char *key_id, uint8_t** pubkey,
+                     size_t* reply_len) override;
+};
+
+#endif  // ANDROID_KEYSTORE_BACKEND_BINDER_H
diff --git a/keystore-engine/keystore_backend_hidl.cpp b/keystore-engine/keystore_backend_hidl.cpp
new file mode 100644
index 0000000..9a84e67
--- /dev/null
+++ b/keystore-engine/keystore_backend_hidl.cpp
@@ -0,0 +1,91 @@
+/* Copyright 2017 The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "keystore_backend_hidl.h"
+
+#include <android/system/wifi/keystore/1.0/IKeystore.h>
+#include <log/log.h>
+
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::sp;
+using android::system::wifi::keystore::V1_0::IKeystore;
+
+int32_t KeystoreBackendHidl::sign(
+        const char *key_id, const uint8_t* in, size_t len, uint8_t** reply,
+        size_t* reply_len) {
+    if (key_id == NULL || in == NULL || reply == NULL || reply_len == NULL) {
+        ALOGE("Null pointer argument passed");
+        return -1;
+    }
+
+    sp<IKeystore> service = IKeystore::tryGetService();
+    if (service == NULL) {
+        ALOGE("could not contact keystore HAL");
+        return -1;
+    }
+
+    bool success = false;
+    auto cb = [&](IKeystore::KeystoreStatusCode status,
+                  hidl_vec<uint8_t> signedData) {
+      if (status == IKeystore::KeystoreStatusCode::SUCCESS) {
+          *reply_len = signedData.size();
+          *reply = signedData.releaseData();
+          success = true;
+      }
+    };
+    Return<void> ret = service->sign(
+        key_id, std::vector<uint8_t>(in, in + len), cb);
+    if (!ret.isOk() || !success) {
+        return 1;
+    }
+    return 0;
+}
+
+int32_t KeystoreBackendHidl::get_pubkey(
+        const char *key_id, uint8_t** pubkey, size_t* pubkey_len) {
+    if (key_id == NULL || pubkey == NULL || pubkey_len == NULL) {
+        ALOGE("Null pointer argument passed");
+        return -1;
+    }
+
+    sp<IKeystore> service = IKeystore::tryGetService();
+    if (service == NULL) {
+        ALOGE("could not contact keystore HAL");
+        return -1;
+    }
+
+    bool success = false;
+    auto cb = [&](IKeystore::KeystoreStatusCode status,
+                  hidl_vec<uint8_t> publicKey) {
+      if (status == IKeystore::KeystoreStatusCode::SUCCESS) {
+          *pubkey_len = publicKey.size();
+          *pubkey = publicKey.releaseData();
+          success = true;
+      }
+    };
+    Return<void> ret = service->getPublicKey(key_id, cb);
+    if (!ret.isOk() || !success) {
+        return 1;
+    }
+    return 0;
+}
diff --git a/keystore-engine/keystore_backend_hidl.h b/keystore-engine/keystore_backend_hidl.h
new file mode 100644
index 0000000..fd38f69
--- /dev/null
+++ b/keystore-engine/keystore_backend_hidl.h
@@ -0,0 +1,38 @@
+/* Copyright 2017 The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#ifndef ANDROID_KEYSTORE_BACKEND_HIDL_H
+#define ANDROID_KEYSTORE_BACKEND_HIDL_H
+
+#include "keystore_backend.h"
+
+class KeystoreBackendHidl : public KeystoreBackend {
+  public:
+    KeystoreBackendHidl() {}
+    virtual ~KeystoreBackendHidl() {}
+    int32_t sign(const char *key_id, const uint8_t* in, size_t len,
+                 uint8_t** reply, size_t* reply_len) override;
+    int32_t get_pubkey(const char *key_id, uint8_t** pubkey,
+                     size_t* reply_len) override;
+};
+
+#endif  // ANDROID_KEYSTORE_BACKEND_HIDL_H
diff --git a/keystore/.clang-format b/keystore/.clang-format
index 5747e19..b0dc94c 100644
--- a/keystore/.clang-format
+++ b/keystore/.clang-format
@@ -3,7 +3,7 @@
 UseTab: Never
 BreakBeforeBraces: Attach
 AllowShortFunctionsOnASingleLine: Inline
-AllowShortIfStatementsOnASingleLine: false
+AllowShortIfStatementsOnASingleLine: true
 IndentCaseLabels: false
 ColumnLimit: 100
 PointerBindsToType: true
diff --git a/keystore/Android.mk b/keystore/Android.mk
index f17d5eb..f87675d 100644
--- a/keystore/Android.mk
+++ b/keystore/Android.mk
@@ -22,6 +22,7 @@
 $(call local-generated-sources-dir)/proto/$(LOCAL_PATH)
 endef
 
+ifneq ($(TARGET_BUILD_PDK),true)
 include $(CLEAR_VARS)
 ifeq ($(USE_32_BIT_KEYSTORE), true)
 LOCAL_MULTILIB := 32
@@ -32,18 +33,23 @@
 	blob.cpp \
 	entropy.cpp \
 	key_store_service.cpp \
+	keystore_attestation_id.cpp \
 	keyblob_utils.cpp \
 	keystore.cpp \
 	keystore_main.cpp \
 	keystore_utils.cpp \
+	legacy_keymaster_device_wrapper.cpp \
+	keymaster_enforcement.cpp \
 	operation.cpp \
 	permissions.cpp \
-	user_state.cpp
+	user_state.cpp \
+	../../../frameworks/base/core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl
 LOCAL_SHARED_LIBRARIES := \
 	libbinder \
 	libcutils \
 	libcrypto \
 	libhardware \
+	libwifikeystorehal \
 	libkeystore_binder \
 	liblog \
 	libsoftkeymaster \
@@ -51,7 +57,13 @@
 	libselinux \
 	libsoftkeymasterdevice \
 	libkeymaster_messages \
-	libkeymaster1
+	libkeymaster1 \
+	libhwbinder \
+	libhidlbase \
+	libhidltransport \
+	android.hardware.keymaster@3.0 \
+	android.system.wifi.keystore@1.0
+LOCAL_HEADER_LIBRARIES := libbase_headers
 LOCAL_MODULE := keystore
 LOCAL_MODULE_TAGS := optional
 LOCAL_INIT_RC := keystore.rc
@@ -59,7 +71,9 @@
 LOCAL_CLANG := true
 LOCAL_SANITIZE := integer
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_AIDL_INCLUDES := frameworks/base/core/java/
 include $(BUILD_EXECUTABLE)
+endif
 
 include $(CLEAR_VARS)
 ifeq ($(USE_32_BIT_KEYSTORE), true)
@@ -67,7 +81,10 @@
 endif
 LOCAL_CFLAGS := -Wall -Wextra -Werror
 LOCAL_SRC_FILES := keystore_cli.cpp
-LOCAL_SHARED_LIBRARIES := libcutils libcrypto libkeystore_binder libutils liblog libbinder
+LOCAL_SHARED_LIBRARIES := libcutils libcrypto libkeystore_binder libutils liblog libbinder \
+	libhwbinder \
+	libhidlbase \
+	android.hardware.keymaster@3.0
 LOCAL_MODULE := keystore_cli
 LOCAL_MODULE_TAGS := debug
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
@@ -81,8 +98,11 @@
 LOCAL_SRC_FILES := keystore_cli_v2.cpp
 LOCAL_SHARED_LIBRARIES := \
 	libchrome \
-	libkeymaster_messages \
-	libkeystore_binder
+	libkeystore_binder \
+	libhwbinder \
+	libhidlbase \
+	android.hardware.keymaster@3.0
+
 LOCAL_MODULE := keystore_cli_v2
 LOCAL_MODULE_TAGS := debug
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include external/gtest/include
@@ -97,28 +117,61 @@
 LOCAL_CFLAGS := -Wall -Wextra -Werror
 LOCAL_SRC_FILES := \
 	IKeystoreService.cpp \
+	KeyAttestationApplicationId.cpp \
+	KeyAttestationPackageInfo.cpp \
+	Signature.cpp \
 	keyblob_utils.cpp \
 	keystore_client.proto \
 	keystore_client_impl.cpp \
-	keystore_get.cpp
+	keystore_get.cpp \
+	authorization_set.cpp \
+	keystore_tags_utils.cpp \
+	keystore_aidl_hidl_marshalling_utils.cpp
 LOCAL_SHARED_LIBRARIES := \
 	libbinder \
-	libkeymaster_messages \
 	liblog \
 	libprotobuf-cpp-lite \
-	libsoftkeymasterdevice \
-	libutils
+	libutils \
+	libhwbinder \
+	libhidlbase \
+	android.hardware.keymaster@3.0
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 LOCAL_MODULE := libkeystore_binder
 LOCAL_MODULE_TAGS := optional
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(call keystore_proto_include)
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder \
+	libhwbinder \
+	libhidlbase \
+	android.hardware.keymaster@3.0
 LOCAL_CLANG := true
 LOCAL_SANITIZE := integer
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_SHARED_LIBRARY)
 
+# Library for keystore clients using the WiFi HIDL interface
+include $(CLEAR_VARS)
+LOCAL_CFLAGS := -Wall -Wextra -Werror
+LOCAL_SRC_FILES := \
+	keystore_get_wifi_hidl.cpp
+LOCAL_SHARED_LIBRARIES := \
+	android.system.wifi.keystore@1.0 \
+	libbase \
+	libhidlbase \
+	libhidltransport \
+	liblog \
+	libutils
+LOCAL_MODULE_CLASS := SHARED_LIBRARIES
+LOCAL_MODULE := libkeystore-wifi-hidl
+LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_CLANG := true
+LOCAL_SANITIZE := integer
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_VENDOR_MODULE := true
+include $(BUILD_SHARED_LIBRARY)
+
 # Library for unit tests
 include $(CLEAR_VARS)
 ifeq ($(USE_32_BIT_KEYSTORE), true)
@@ -129,7 +182,12 @@
 LOCAL_MODULE := libkeystore_test
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_STATIC_LIBRARIES := libgtest_main
-LOCAL_SHARED_LIBRARIES := libkeymaster_messages
+LOCAL_SHARED_LIBRARIES := libkeymaster_messages \
+	libutils \
+	libhwbinder \
+	libhidlbase \
+	android.hardware.keymaster@3.0
+
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_STATIC_LIBRARY)
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
index acd6968..344687b 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -19,28 +19,31 @@
 #include <sys/limits.h>
 #include <sys/types.h>
 
+#include <algorithm>
+#include <limits>
+
 #define LOG_TAG "KeystoreService"
 #include <utils/Log.h>
 
-#include <binder/Parcel.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
+#include <binder/Parcel.h>
 
 #include <keystore/IKeystoreService.h>
+#include <keystore/keystore_hidl_support.h>
+
+#include "keystore_aidl_hidl_marshalling_utils.h"
 
 namespace android {
+using namespace ::keystore;
 
 const ssize_t MAX_GENERATE_ARGS = 3;
-static keymaster_key_param_t* readParamList(const Parcel& in, size_t* length);
 
-KeystoreArg::KeystoreArg(const void* data, size_t len)
-    : mData(data), mSize(len) {
-}
+KeystoreArg::KeystoreArg(const void* data, size_t len) : mData(data), mSize(len) {}
 
-KeystoreArg::~KeystoreArg() {
-}
+KeystoreArg::~KeystoreArg() {}
 
-const void *KeystoreArg::data() const {
+const void* KeystoreArg::data() const {
     return mData;
 }
 
@@ -48,36 +51,18 @@
     return mSize;
 }
 
-OperationResult::OperationResult() : resultCode(0), token(), handle(0), inputConsumed(0),
-    data(NULL), dataLength(0) {
-}
+OperationResult::OperationResult() : resultCode(), token(), handle(0), inputConsumed(0), data() {}
 
-OperationResult::~OperationResult() {
-}
+OperationResult::~OperationResult() {}
 
 status_t OperationResult::readFromParcel(const Parcel* inn) {
     const Parcel& in = *inn;
-    resultCode = in.readInt32();
+    resultCode = ErrorCode(in.readInt32());
     token = in.readStrongBinder();
-    handle = static_cast<keymaster_operation_handle_t>(in.readInt64());
+    handle = static_cast<uint64_t>(in.readInt64());
     inputConsumed = in.readInt32();
-    ssize_t length = in.readInt32();
-    dataLength = 0;
-    if (length > 0) {
-        const void* buf = in.readInplace(length);
-        if (buf) {
-            data.reset(reinterpret_cast<uint8_t*>(malloc(length)));
-            if (data.get()) {
-                memcpy(data.get(), buf, length);
-                dataLength = (size_t) length;
-            } else {
-                ALOGE("Failed to allocate OperationResult buffer");
-            }
-        } else {
-            ALOGE("Failed to readInplace OperationResult data");
-        }
-    }
-    outParams.readFromParcel(in);
+    data = readKeymasterBlob(in);
+    outParams = readParamSetFromParcel(in);
     return OK;
 }
 
@@ -86,322 +71,28 @@
     out->writeStrongBinder(token);
     out->writeInt64(handle);
     out->writeInt32(inputConsumed);
-    out->writeInt32(dataLength);
-    if (dataLength && data) {
-        void* buf = out->writeInplace(dataLength);
-        if (buf) {
-            memcpy(buf, data.get(), dataLength);
-        } else {
-            ALOGE("Failed to writeInplace OperationResult data.");
-        }
-    }
-    outParams.writeToParcel(out);
+    writeKeymasterBlob(data, out);
+    writeParamSetToParcel(outParams, out);
     return OK;
 }
 
-ExportResult::ExportResult() : resultCode(0), exportData(NULL), dataLength(0) {
-}
+ExportResult::ExportResult() : resultCode() {}
 
-ExportResult::~ExportResult() {
-}
+ExportResult::~ExportResult() {}
 
 status_t ExportResult::readFromParcel(const Parcel* inn) {
     const Parcel& in = *inn;
-    resultCode = in.readInt32();
-    ssize_t length = in.readInt32();
-    dataLength = 0;
-    if (length > 0) {
-        const void* buf = in.readInplace(length);
-        if (buf) {
-            exportData.reset(reinterpret_cast<uint8_t*>(malloc(length)));
-            if (exportData.get()) {
-                memcpy(exportData.get(), buf, length);
-                dataLength = (size_t) length;
-            } else {
-                ALOGE("Failed to allocate ExportData buffer");
-            }
-        } else {
-            ALOGE("Failed to readInplace ExportData data");
-        }
-    }
+    resultCode = ErrorCode(in.readInt32());
+    exportData = readKeymasterBlob(in);
     return OK;
 }
 
 status_t ExportResult::writeToParcel(Parcel* out) const {
     out->writeInt32(resultCode);
-    out->writeInt32(dataLength);
-    if (exportData && dataLength) {
-        void* buf = out->writeInplace(dataLength);
-        if (buf) {
-            memcpy(buf, exportData.get(), dataLength);
-        } else {
-            ALOGE("Failed to writeInplace ExportResult data.");
-        }
-    }
+    writeKeymasterBlob(exportData, out);
     return OK;
 }
 
-KeymasterArguments::KeymasterArguments() {
-}
-
-KeymasterArguments::~KeymasterArguments() {
-    keymaster_free_param_values(params.data(), params.size());
-}
-
-void KeymasterArguments::readFromParcel(const Parcel& in) {
-    ssize_t length = in.readInt32();
-    size_t ulength = (size_t) length;
-    if (length < 0) {
-        ulength = 0;
-    }
-    keymaster_free_param_values(params.data(), params.size());
-    params.clear();
-    for(size_t i = 0; i < ulength; i++) {
-        keymaster_key_param_t param;
-        if (!readKeymasterArgumentFromParcel(in, &param)) {
-            ALOGE("Error reading keymaster argument from parcel");
-            break;
-        }
-        params.push_back(param);
-    }
-}
-
-void KeymasterArguments::writeToParcel(Parcel* out) const {
-    out->writeInt32(params.size());
-    for (auto param : params) {
-        out->writeInt32(1);
-        writeKeymasterArgumentToParcel(param, out);
-    }
-}
-
-KeyCharacteristics::KeyCharacteristics() {
-    memset((void*) &characteristics, 0, sizeof(characteristics));
-}
-
-KeyCharacteristics::~KeyCharacteristics() {
-    keymaster_free_characteristics(&characteristics);
-}
-
-status_t KeyCharacteristics::readFromParcel(const Parcel* inn) {
-    const Parcel& in = *inn;
-    size_t length = 0;
-    keymaster_key_param_t* params = readParamList(in, &length);
-    characteristics.sw_enforced.params = params;
-    characteristics.sw_enforced.length = length;
-
-    params = readParamList(in, &length);
-    characteristics.hw_enforced.params = params;
-    characteristics.hw_enforced.length = length;
-    return OK;
-}
-
-status_t KeyCharacteristics::writeToParcel(Parcel* out) const {
-    if (characteristics.sw_enforced.params) {
-        out->writeInt32(characteristics.sw_enforced.length);
-        for (size_t i = 0; i < characteristics.sw_enforced.length; i++) {
-            out->writeInt32(1);
-            writeKeymasterArgumentToParcel(characteristics.sw_enforced.params[i], out);
-        }
-    } else {
-        out->writeInt32(0);
-    }
-    if (characteristics.hw_enforced.params) {
-        out->writeInt32(characteristics.hw_enforced.length);
-        for (size_t i = 0; i < characteristics.hw_enforced.length; i++) {
-            out->writeInt32(1);
-            writeKeymasterArgumentToParcel(characteristics.hw_enforced.params[i], out);
-        }
-    } else {
-        out->writeInt32(0);
-    }
-    return OK;
-}
-
-KeymasterCertificateChain::KeymasterCertificateChain() {
-    memset(&chain, 0, sizeof(chain));
-}
-
-KeymasterCertificateChain::~KeymasterCertificateChain() {
-    keymaster_free_cert_chain(&chain);
-}
-
-static bool readKeymasterBlob(const Parcel& in, keymaster_blob_t* blob) {
-    if (in.readInt32() != 1) {
-        return false;
-    }
-
-    ssize_t length = in.readInt32();
-    if (length <= 0) {
-        return false;
-    }
-
-    blob->data = static_cast<const uint8_t*>(malloc(length));
-    if (!blob->data)
-        return false;
-
-    const void* buf = in.readInplace(length);
-    if (!buf)
-        return false;
-
-    blob->data_length = static_cast<size_t>(length);
-    memcpy(const_cast<uint8_t*>(blob->data), buf, length);
-
-    return true;
-}
-
-void KeymasterCertificateChain::readFromParcel(const Parcel& in) {
-    keymaster_free_cert_chain(&chain);
-
-    ssize_t count = in.readInt32();
-    size_t ucount = count;
-    if (count <= 0) {
-        return;
-    }
-
-    chain.entries = reinterpret_cast<keymaster_blob_t*>(malloc(sizeof(keymaster_blob_t) * ucount));
-    if (!chain.entries) {
-        ALOGE("Error allocating memory for certificate chain");
-        return;
-    }
-
-    memset(chain.entries, 0, sizeof(keymaster_blob_t) * ucount);
-    for (size_t i = 0; i < ucount; ++i) {
-        if (!readKeymasterBlob(in, &chain.entries[i])) {
-            ALOGE("Error reading certificate from parcel");
-            keymaster_free_cert_chain(&chain);
-            return;
-        }
-    }
-}
-
-void KeymasterCertificateChain::writeToParcel(Parcel* out) const {
-    out->writeInt32(chain.entry_count);
-    for (size_t i = 0; i < chain.entry_count; ++i) {
-        if (chain.entries[i].data) {
-            out->writeInt32(chain.entries[i].data_length);
-            void* buf = out->writeInplace(chain.entries[i].data_length);
-            if (buf) {
-                memcpy(buf, chain.entries[i].data, chain.entries[i].data_length);
-            } else {
-                ALOGE("Failed to writeInplace keymaster cert chain entry");
-            }
-        } else {
-            out->writeInt32(0); // Tell Java side this object is NULL.
-            ALOGE("Found NULL certificate chain entry");
-        }
-    }
-}
-
-void writeKeymasterArgumentToParcel(const keymaster_key_param_t& param, Parcel* out) {
-    switch (keymaster_tag_get_type(param.tag)) {
-        case KM_ENUM:
-        case KM_ENUM_REP: {
-            out->writeInt32(param.tag);
-            out->writeInt32(param.enumerated);
-            break;
-        }
-        case KM_UINT:
-        case KM_UINT_REP: {
-            out->writeInt32(param.tag);
-            out->writeInt32(param.integer);
-            break;
-        }
-        case KM_ULONG:
-        case KM_ULONG_REP: {
-            out->writeInt32(param.tag);
-            out->writeInt64(param.long_integer);
-            break;
-        }
-        case KM_DATE: {
-            out->writeInt32(param.tag);
-            out->writeInt64(param.date_time);
-            break;
-        }
-        case KM_BOOL: {
-            out->writeInt32(param.tag);
-            break;
-        }
-        case KM_BIGNUM:
-        case KM_BYTES: {
-            out->writeInt32(param.tag);
-            out->writeInt32(param.blob.data_length);
-            void* buf = out->writeInplace(param.blob.data_length);
-            if (buf) {
-                memcpy(buf, param.blob.data, param.blob.data_length);
-            } else {
-                ALOGE("Failed to writeInplace keymaster blob param");
-            }
-            break;
-        }
-        default: {
-            ALOGE("Failed to write argument: Unsupported keymaster_tag_t %d", param.tag);
-        }
-    }
-}
-
-
-bool readKeymasterArgumentFromParcel(const Parcel& in, keymaster_key_param_t* out) {
-    if (in.readInt32() == 0) {
-        return false;
-    }
-    keymaster_tag_t tag = static_cast<keymaster_tag_t>(in.readInt32());
-    switch (keymaster_tag_get_type(tag)) {
-        case KM_ENUM:
-        case KM_ENUM_REP: {
-            uint32_t value = in.readInt32();
-            *out = keymaster_param_enum(tag, value);
-            break;
-        }
-        case KM_UINT:
-        case KM_UINT_REP: {
-            uint32_t value = in.readInt32();
-            *out = keymaster_param_int(tag, value);
-            break;
-        }
-        case KM_ULONG:
-        case KM_ULONG_REP: {
-            uint64_t value = in.readInt64();
-            *out = keymaster_param_long(tag, value);
-            break;
-        }
-        case KM_DATE: {
-            uint64_t value = in.readInt64();
-            *out = keymaster_param_date(tag, value);
-            break;
-        }
-        case KM_BOOL: {
-            *out = keymaster_param_bool(tag);
-            break;
-        }
-        case KM_BIGNUM:
-        case KM_BYTES: {
-            ssize_t length = in.readInt32();
-            uint8_t* data = NULL;
-            size_t ulength = 0;
-            if (length >= 0) {
-                ulength = (size_t) length;
-                // use malloc here so we can use keymaster_free_param_values
-                // consistently.
-                data = reinterpret_cast<uint8_t*>(malloc(ulength));
-                const void* buf = in.readInplace(ulength);
-                if (!buf || !data) {
-                    ALOGE("Failed to allocate buffer for keymaster blob param");
-                    free(data);
-                    return false;
-                }
-                memcpy(data, buf, ulength);
-            }
-            *out = keymaster_param_blob(tag, data, ulength);
-            break;
-        }
-        default: {
-            ALOGE("Unsupported keymaster_tag_t %d", tag);
-            return false;
-        }
-    }
-    return true;
-}
-
 /**
  * Read a byte array from in. The data at *data is still owned by the parcel
  */
@@ -420,77 +111,31 @@
     }
 }
 
-// Read a keymaster_key_param_t* from a Parcel for use in a
-// keymaster_key_characteristics_t. This will be free'd by calling
-// keymaster_free_key_characteristics.
-static keymaster_key_param_t* readParamList(const Parcel& in, size_t* length) {
-    ssize_t slength = in.readInt32();
-    *length = 0;
-    if (slength < 0) {
-        return NULL;
-    }
-    *length = (size_t) slength;
-    if (*length >= UINT_MAX / sizeof(keymaster_key_param_t)) {
-        return NULL;
-    }
-    keymaster_key_param_t* list =
-            reinterpret_cast<keymaster_key_param_t*>(malloc(*length *
-                                                            sizeof(keymaster_key_param_t)));
-    if (!list) {
-        ALOGD("Failed to allocate buffer for generateKey outCharacteristics");
-        goto err;
-    }
-    for (size_t i = 0; i < *length ; i++) {
-        if (!readKeymasterArgumentFromParcel(in, &list[i])) {
-            ALOGE("Failed to read keymaster argument");
-            keymaster_free_param_values(list, i);
-            goto err;
-        }
-    }
-    return list;
-err:
-    free(list);
-    return NULL;
-}
-
-static std::unique_ptr<keymaster_blob_t> readKeymasterBlob(const Parcel& in) {
-    std::unique_ptr<keymaster_blob_t> blob (new keymaster_blob_t);
-    if (!readKeymasterBlob(in, blob.get())) {
-        blob.reset();
-    }
-    return blob;
-}
-
-class BpKeystoreService: public BpInterface<IKeystoreService>
-{
-public:
-    explicit BpKeystoreService(const sp<IBinder>& impl)
-        : BpInterface<IKeystoreService>(impl)
-    {
-    }
+class BpKeystoreService : public BpInterface<IKeystoreService> {
+  public:
+    explicit BpKeystoreService(const sp<IBinder>& impl) : BpInterface<IKeystoreService>(impl) {}
 
     // test ping
-    virtual int32_t getState(int32_t userId)
-    {
+    KeyStoreServiceReturnCode getState(int32_t userId) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
         status_t status = remote()->transact(BnKeystoreService::GET_STATE, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("getState() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
+        ResponseCode ret = ResponseCode(reply.readInt32());
         if (err < 0) {
             ALOGD("getState() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         return ret;
     }
 
-    virtual int32_t get(const String16& name, int32_t uid, uint8_t** item, size_t* itemLength)
-    {
+    KeyStoreServiceReturnCode get(const String16& name, int32_t uid,
+                                  hidl_vec<uint8_t>* item) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -498,58 +143,40 @@
         status_t status = remote()->transact(BnKeystoreService::GET, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("get() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        ssize_t len = reply.readInt32();
-        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
-            size_t ulen = (size_t) len;
-            const void* buf = reply.readInplace(ulen);
-            *item = (uint8_t*) malloc(ulen);
-            if (*item != NULL) {
-                memcpy(*item, buf, ulen);
-                *itemLength = ulen;
-            } else {
-                ALOGE("out of memory allocating output array in get");
-                *itemLength = 0;
-            }
-        } else {
-            *itemLength = 0;
-        }
         if (err < 0) {
             ALOGD("get() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return 0;
+        auto resultItem = readBlobAsByteArray(reply);
+        if (item) *item = resultItem.value();
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid,
-            int32_t flags)
-    {
+    KeyStoreServiceReturnCode insert(const String16& name, const hidl_vec<uint8_t>& item, int uid,
+                                     int32_t flags) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(itemLength);
-        void* buf = data.writeInplace(itemLength);
-        memcpy(buf, item, itemLength);
+        writeBlobAsByteArray(item, &data);
         data.writeInt32(uid);
         data.writeInt32(flags);
         status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("import() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("import() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t del(const String16& name, int uid)
-    {
+    KeyStoreServiceReturnCode del(const String16& name, int uid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -557,19 +184,17 @@
         status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("del() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("del() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t exist(const String16& name, int uid)
-    {
+    KeyStoreServiceReturnCode exist(const String16& name, int uid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -577,19 +202,18 @@
         status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("exist() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("exist() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t list(const String16& prefix, int uid, Vector<String16>* matches)
-    {
+    KeyStoreServiceReturnCode list(const String16& prefix, int uid,
+                                   Vector<String16>* matches) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(prefix);
@@ -597,81 +221,74 @@
         status_t status = remote()->transact(BnKeystoreService::LIST, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("list() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
         int32_t numMatches = reply.readInt32();
         for (int32_t i = 0; i < numMatches; i++) {
             matches->push(reply.readString16());
         }
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("list() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t reset()
-    {
+    KeyStoreServiceReturnCode reset() override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("reset() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("reset() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t onUserPasswordChanged(int32_t userId, const String16& password)
-    {
+    KeyStoreServiceReturnCode onUserPasswordChanged(int32_t userId,
+                                                    const String16& password) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
         data.writeString16(password);
-        status_t status = remote()->transact(BnKeystoreService::ON_USER_PASSWORD_CHANGED, data,
-                                             &reply);
+        status_t status =
+            remote()->transact(BnKeystoreService::ON_USER_PASSWORD_CHANGED, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("onUserPasswordChanged() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("onUserPasswordChanged() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t lock(int32_t userId)
-    {
+    KeyStoreServiceReturnCode lock(int32_t userId) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
         status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("lock() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("lock() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t unlock(int32_t userId, const String16& password)
-    {
+    KeyStoreServiceReturnCode unlock(int32_t userId, const String16& password) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
@@ -679,19 +296,17 @@
         status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("unlock() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("unlock() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual bool isEmpty(int32_t userId)
-    {
+    bool isEmpty(int32_t userId) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
@@ -701,17 +316,16 @@
             return false;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("isEmpty() caught exception %d\n", err);
             return false;
         }
-        return ret != 0;
+        return reply.readInt32() != 0;
     }
 
-    virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize,
-            int32_t flags, Vector<sp<KeystoreArg> >* args)
-    {
+    KeyStoreServiceReturnCode generate(const String16& name, int32_t uid, int32_t keyType,
+                                       int32_t keySize, int32_t flags,
+                                       Vector<sp<KeystoreArg>>* args) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -721,7 +335,7 @@
         data.writeInt32(flags);
         data.writeInt32(1);
         data.writeInt32(args->size());
-        for (Vector<sp<KeystoreArg> >::iterator it = args->begin(); it != args->end(); ++it) {
+        for (Vector<sp<KeystoreArg>>::iterator it = args->begin(); it != args->end(); ++it) {
             sp<KeystoreArg> item = *it;
             size_t keyLength = item->size();
             data.writeInt32(keyLength);
@@ -731,142 +345,104 @@
         status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("generate() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("generate() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength, int uid,
-            int flags)
-    {
+    KeyStoreServiceReturnCode import(const String16& name, const hidl_vec<uint8_t>& key, int uid,
+                                     int flags) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(keyLength);
-        void* buf = data.writeInplace(keyLength);
-        memcpy(buf, key, keyLength);
+        writeBlobAsByteArray(key, &data);
         data.writeInt32(uid);
         data.writeInt32(flags);
         status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("import() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("import() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t sign(const String16& name, const uint8_t* in, size_t inLength, uint8_t** out,
-            size_t* outLength)
-    {
+    KeyStoreServiceReturnCode sign(const String16& name, const hidl_vec<uint8_t>& in,
+                                   hidl_vec<uint8_t>* out) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(inLength);
-        void* buf = data.writeInplace(inLength);
-        memcpy(buf, in, inLength);
+        writeBlobAsByteArray(in, &data);
         status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("import() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        ssize_t len = reply.readInt32();
-        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
-            size_t ulen = (size_t) len;
-            const void* outBuf = reply.readInplace(ulen);
-            *out = (uint8_t*) malloc(ulen);
-            if (*out != NULL) {
-                memcpy((void*) *out, outBuf, ulen);
-                *outLength = ulen;
-            } else {
-                ALOGE("out of memory allocating output array in sign");
-                *outLength = 0;
-            }
-        } else {
-            *outLength = 0;
-        }
         if (err < 0) {
             ALOGD("import() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return 0;
+        auto outBlob = readBlobAsByteArray(reply);
+        if (out) {
+            // don't need to check outBlob.isOk()
+            // if !outBlob.isOk() the wrapped value is default constructed and therefore empty,
+            // as expected.
+            *out = outBlob.value();
+        }
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t verify(const String16& name, const uint8_t* in, size_t inLength,
-            const uint8_t* signature, size_t signatureLength)
-    {
+    KeyStoreServiceReturnCode verify(const String16& name, const hidl_vec<uint8_t>& in,
+                                     const hidl_vec<uint8_t>& signature) override {
         Parcel data, reply;
-        void* buf;
 
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(inLength);
-        buf = data.writeInplace(inLength);
-        memcpy(buf, in, inLength);
-        data.writeInt32(signatureLength);
-        buf = data.writeInplace(signatureLength);
-        memcpy(buf, signature, signatureLength);
+        writeBlobAsByteArray(in, &data);
+        writeBlobAsByteArray(signature, &data);
         status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("verify() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("verify() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength)
-    {
+    KeyStoreServiceReturnCode get_pubkey(const String16& name, hidl_vec<uint8_t>* pubkey) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
         status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("get_pubkey() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        ssize_t len = reply.readInt32();
-        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
-            size_t ulen = (size_t) len;
-            const void* buf = reply.readInplace(ulen);
-            *pubkey = (uint8_t*) malloc(ulen);
-            if (*pubkey != NULL) {
-                memcpy(*pubkey, buf, ulen);
-                *pubkeyLength = ulen;
-            } else {
-                ALOGE("out of memory allocating output array in get_pubkey");
-                *pubkeyLength = 0;
-            }
-        } else {
-            *pubkeyLength = 0;
-        }
         if (err < 0) {
             ALOGD("get_pubkey() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return 0;
-     }
+        auto resultKey = readBlobAsByteArray(reply);
+        if (pubkey) *pubkey = resultKey.value();
+        return ResponseCode(reply.readInt32());
+    }
 
-    virtual int32_t grant(const String16& name, int32_t granteeUid)
-    {
+    KeyStoreServiceReturnCode grant(const String16& name, int32_t granteeUid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -874,19 +450,17 @@
         status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("grant() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("grant() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t ungrant(const String16& name, int32_t granteeUid)
-    {
+    KeyStoreServiceReturnCode ungrant(const String16& name, int32_t granteeUid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -894,19 +468,17 @@
         status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("ungrant() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("ungrant() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    int64_t getmtime(const String16& name, int32_t uid)
-    {
+    int64_t getmtime(const String16& name, int32_t uid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -917,17 +489,15 @@
             return -1;
         }
         int32_t err = reply.readExceptionCode();
-        int64_t ret = reply.readInt64();
         if (err < 0) {
             ALOGD("getmtime() caught exception %d\n", err);
             return -1;
         }
-        return ret;
+        return reply.readInt64();
     }
 
-    virtual int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
-            int32_t destUid)
-    {
+    KeyStoreServiceReturnCode duplicate(const String16& srcKey, int32_t srcUid,
+                                        const String16& destKey, int32_t destUid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(srcKey);
@@ -937,19 +507,17 @@
         status_t status = remote()->transact(BnKeystoreService::DUPLICATE, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("duplicate() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("duplicate() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t is_hardware_backed(const String16& keyType)
-    {
+    int32_t is_hardware_backed(const String16& keyType) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(keyType);
@@ -959,151 +527,132 @@
             return -1;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("is_hardware_backed() caught exception %d\n", err);
             return -1;
         }
-        return ret;
+        return reply.readInt32();
     }
 
-    virtual int32_t clear_uid(int64_t uid)
-    {
+    KeyStoreServiceReturnCode clear_uid(int64_t uid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt64(uid);
         status_t status = remote()->transact(BnKeystoreService::CLEAR_UID, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("clear_uid() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("clear_uid() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t addRngEntropy(const uint8_t* buf, size_t bufLength)
-    {
+    KeyStoreServiceReturnCode addRngEntropy(const hidl_vec<uint8_t>& entropy) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
-        data.writeByteArray(bufLength, buf);
+        writeBlobAsByteArray(entropy, &data);
         status_t status = remote()->transact(BnKeystoreService::ADD_RNG_ENTROPY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("addRngEntropy() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("addRngEntropy() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     };
 
-    virtual int32_t generateKey(const String16& name, const KeymasterArguments& params,
-                                const uint8_t* entropy, size_t entropyLength, int uid, int flags,
-                                KeyCharacteristics* outCharacteristics)
-    {
+    KeyStoreServiceReturnCode generateKey(const String16& name,
+                                          const hidl_vec<KeyParameter>& params,
+                                          const hidl_vec<uint8_t>& entropy, int uid, int flags,
+                                          KeyCharacteristics* outCharacteristics) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeByteArray(entropyLength, entropy);
+        nullable(writeParamSetToParcel, params, &data);
+        writeBlobAsByteArray(entropy, &data);
         data.writeInt32(uid);
         data.writeInt32(flags);
         status_t status = remote()->transact(BnKeystoreService::GENERATE_KEY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("generateKey() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
+        ResponseCode ret = ResponseCode(reply.readInt32());
         if (err < 0) {
             ALOGD("generateKey() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         if (outCharacteristics) {
-            reply.readParcelable(outCharacteristics);
+            *outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value();
         }
         return ret;
     }
-    virtual int32_t getKeyCharacteristics(const String16& name,
-                                          const keymaster_blob_t* clientId,
-                                          const keymaster_blob_t* appData,
-                                          int32_t uid, KeyCharacteristics* outCharacteristics)
-    {
+    KeyStoreServiceReturnCode
+    getKeyCharacteristics(const String16& name, const hidl_vec<uint8_t>& clientId,
+                          const hidl_vec<uint8_t>& appData, int32_t uid,
+                          KeyCharacteristics* outCharacteristics) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        if (clientId) {
-            data.writeByteArray(clientId->data_length, clientId->data);
-        } else {
-            data.writeInt32(-1);
-        }
-        if (appData) {
-            data.writeByteArray(appData->data_length, appData->data);
-        } else {
-            data.writeInt32(-1);
-        }
+        writeBlobAsByteArray(clientId, &data);
+        writeBlobAsByteArray(appData, &data);
         data.writeInt32(uid);
-        status_t status = remote()->transact(BnKeystoreService::GET_KEY_CHARACTERISTICS,
-                                             data, &reply);
+        status_t status =
+            remote()->transact(BnKeystoreService::GET_KEY_CHARACTERISTICS, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("getKeyCharacteristics() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
+        ResponseCode ret = ResponseCode(reply.readInt32());
         if (err < 0) {
             ALOGD("getKeyCharacteristics() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         if (outCharacteristics) {
-            reply.readParcelable(outCharacteristics);
+            *outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value();
         }
         return ret;
     }
-    virtual int32_t importKey(const String16& name, const KeymasterArguments&  params,
-                              keymaster_key_format_t format, const uint8_t *keyData,
-                              size_t keyLength, int uid, int flags,
-                              KeyCharacteristics* outCharacteristics)
-    {
+    KeyStoreServiceReturnCode importKey(const String16& name, const hidl_vec<KeyParameter>& params,
+                                        KeyFormat format, const hidl_vec<uint8_t>& keyData, int uid,
+                                        int flags,
+                                        KeyCharacteristics* outCharacteristics) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeInt32(format);
-        data.writeByteArray(keyLength, keyData);
+        nullable(writeParamSetToParcel, params, &data);
+        data.writeInt32(uint32_t(format));
+        writeBlobAsByteArray(keyData, &data);
         data.writeInt32(uid);
         data.writeInt32(flags);
         status_t status = remote()->transact(BnKeystoreService::IMPORT_KEY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("importKey() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
+        ResponseCode ret = ResponseCode(reply.readInt32());
         if (err < 0) {
             ALOGD("importKey() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         if (outCharacteristics) {
-            reply.readParcelable(outCharacteristics);
+            *outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value();
         }
         return ret;
     }
 
-    virtual void exportKey(const String16& name, keymaster_key_format_t format,
-                           const keymaster_blob_t* clientId,
-                           const keymaster_blob_t* appData, int32_t uid, ExportResult* result)
-    {
+    void exportKey(const String16& name, KeyFormat format, const hidl_vec<uint8_t>& clientId,
+                   const hidl_vec<uint8_t>& appData, int32_t uid, ExportResult* result) override {
         if (!result) {
             return;
         }
@@ -1111,39 +660,29 @@
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(format);
-        if (clientId) {
-            data.writeByteArray(clientId->data_length, clientId->data);
-        } else {
-            data.writeInt32(-1);
-        }
-        if (appData) {
-            data.writeByteArray(appData->data_length, appData->data);
-        } else {
-            data.writeInt32(-1);
-        }
+        data.writeInt32(int32_t(format));
+        writeBlobAsByteArray(clientId, &data);
+        writeBlobAsByteArray(appData, &data);
         data.writeInt32(uid);
         status_t status = remote()->transact(BnKeystoreService::EXPORT_KEY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("exportKey() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
         int32_t err = reply.readExceptionCode();
         if (err < 0) {
             ALOGD("exportKey() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
 
         reply.readParcelable(result);
     }
 
-    virtual void begin(const sp<IBinder>& appToken, const String16& name,
-                       keymaster_purpose_t purpose, bool pruneable,
-                       const KeymasterArguments& params, const uint8_t* entropy,
-                       size_t entropyLength, int32_t uid, OperationResult* result)
-    {
+    void begin(const sp<IBinder>& appToken, const String16& name, KeyPurpose purpose,
+               bool pruneable, const hidl_vec<KeyParameter>& params,
+               const hidl_vec<uint8_t>& entropy, int32_t uid, OperationResult* result) override {
         if (!result) {
             return;
         }
@@ -1151,147 +690,134 @@
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeStrongBinder(appToken);
         data.writeString16(name);
-        data.writeInt32(purpose);
+        data.writeInt32(int32_t(purpose));
         data.writeInt32(pruneable ? 1 : 0);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeByteArray(entropyLength, entropy);
+        nullable(writeParamSetToParcel, params, &data);
+        writeBlobAsByteArray(entropy, &data);
         data.writeInt32(uid);
         status_t status = remote()->transact(BnKeystoreService::BEGIN, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("begin() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
         int32_t err = reply.readExceptionCode();
         if (err < 0) {
             ALOGD("begin() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
 
         reply.readParcelable(result);
     }
 
-    virtual void update(const sp<IBinder>& token, const KeymasterArguments& params,
-                        const uint8_t* opData, size_t dataLength, OperationResult* result)
-    {
+    void update(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
+                const hidl_vec<uint8_t>& opData, OperationResult* result) override {
         if (!result) {
             return;
         }
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeStrongBinder(token);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeByteArray(dataLength, opData);
+        nullable(writeParamSetToParcel, params, &data);
+        writeBlobAsByteArray(opData, &data);
         status_t status = remote()->transact(BnKeystoreService::UPDATE, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("update() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
         int32_t err = reply.readExceptionCode();
         if (err < 0) {
             ALOGD("update() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
 
         reply.readParcelable(result);
     }
 
-    virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
-                        const uint8_t* signature, size_t signatureLength,
-                        const uint8_t* entropy, size_t entropyLength,
-                        OperationResult* result)
-    {
+    void finish(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
+                const hidl_vec<uint8_t>& signature, const hidl_vec<uint8_t>& entropy,
+                OperationResult* result) override {
         if (!result) {
             return;
         }
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeStrongBinder(token);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeByteArray(signatureLength, signature);
-        data.writeByteArray(entropyLength, entropy);
+        nullable(writeParamSetToParcel, params, &data);
+        writeBlobAsByteArray(signature, &data);
+        writeBlobAsByteArray(entropy, &data);
         status_t status = remote()->transact(BnKeystoreService::FINISH, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("finish() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
         int32_t err = reply.readExceptionCode();
         if (err < 0) {
             ALOGD("finish() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
 
         reply.readParcelable(result);
     }
 
-    virtual int32_t abort(const sp<IBinder>& token)
-    {
+    KeyStoreServiceReturnCode abort(const sp<IBinder>& token) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeStrongBinder(token);
         status_t status = remote()->transact(BnKeystoreService::ABORT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("abort() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("abort() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual bool isOperationAuthorized(const sp<IBinder>& token)
-    {
+    bool isOperationAuthorized(const sp<IBinder>& token) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeStrongBinder(token);
-        status_t status = remote()->transact(BnKeystoreService::IS_OPERATION_AUTHORIZED, data,
-                                             &reply);
+        status_t status =
+            remote()->transact(BnKeystoreService::IS_OPERATION_AUTHORIZED, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("isOperationAuthorized() could not contact remote: %d\n", status);
             return false;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("isOperationAuthorized() caught exception %d\n", err);
             return false;
         }
-        return ret == 1;
+        return reply.readInt32() == 1;
     }
 
-    virtual int32_t addAuthToken(const uint8_t* token, size_t length)
-    {
+    KeyStoreServiceReturnCode addAuthToken(const uint8_t* token, size_t length) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeByteArray(length, token);
         status_t status = remote()->transact(BnKeystoreService::ADD_AUTH_TOKEN, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("addAuthToken() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("addAuthToken() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     };
 
-    virtual int32_t onUserAdded(int32_t userId, int32_t parentId)
-    {
+    KeyStoreServiceReturnCode onUserAdded(int32_t userId, int32_t parentId) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
@@ -1299,609 +825,537 @@
         status_t status = remote()->transact(BnKeystoreService::ON_USER_ADDED, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("onUserAdded() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("onUserAdded() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t onUserRemoved(int32_t userId)
-    {
+    KeyStoreServiceReturnCode onUserRemoved(int32_t userId) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
         status_t status = remote()->transact(BnKeystoreService::ON_USER_REMOVED, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("onUserRemoved() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("onUserRemoved() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t attestKey(const String16& name, const KeymasterArguments& params,
-                              KeymasterCertificateChain* outChain) {
-        if (!outChain)
-            return KM_ERROR_OUTPUT_PARAMETER_NULL;
+    KeyStoreServiceReturnCode attestKey(const String16& name, const hidl_vec<KeyParameter>& params,
+                                        hidl_vec<hidl_vec<uint8_t>>* outChain) override {
+        if (!outChain) return ErrorCode::OUTPUT_PARAMETER_NULL;
 
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(1);  // params is not NULL.
-        params.writeToParcel(&data);
+        nullable(writeParamSetToParcel, params, &data);
 
         status_t status = remote()->transact(BnKeystoreService::ATTEST_KEY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("attestkey() count not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
+        ResponseCode ret = ResponseCode(reply.readInt32());
         if (err < 0) {
             ALOGD("attestKey() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         if (reply.readInt32() != 0) {
-            outChain->readFromParcel(reply);
+            *outChain = readCertificateChainFromParcel(reply);
         }
         return ret;
     }
 
-    virtual int32_t onDeviceOffBody()
-    {
+    KeyStoreServiceReturnCode attestDeviceIds(const hidl_vec<KeyParameter>& params,
+                                              hidl_vec<hidl_vec<uint8_t>>* outChain) override {
+        if (!outChain) return ErrorCode::OUTPUT_PARAMETER_NULL;
+
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        nullable(writeParamSetToParcel, params, &data);
+
+        status_t status = remote()->transact(BnKeystoreService::ATTEST_DEVICE_IDS, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("attestDeviceIds() count not contact remote: %d\n", status);
+            return ResponseCode::SYSTEM_ERROR;
+        }
+        int32_t err = reply.readExceptionCode();
+        ResponseCode ret = ResponseCode(reply.readInt32());
+        if (err < 0) {
+            ALOGD("attestDeviceIds() caught exception %d\n", err);
+            return ResponseCode::SYSTEM_ERROR;
+        }
+        if (reply.readInt32() != 0) {
+            *outChain = readCertificateChainFromParcel(reply);
+        }
+        return ret;
+    }
+
+    KeyStoreServiceReturnCode onDeviceOffBody() override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         status_t status = remote()->transact(BnKeystoreService::ON_DEVICE_OFF_BODY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("onDeviceOffBody() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("onDeviceOffBody() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
-
 };
 
 IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService");
 
 // ----------------------------------------------------------------------
 
-status_t BnKeystoreService::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case GET_STATE: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            int32_t ret = getState(userId);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case GET: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int32_t uid = data.readInt32();
-            void* out = NULL;
-            size_t outSize = 0;
-            int32_t ret = get(name, uid, (uint8_t**) &out, &outSize);
-            reply->writeNoException();
-            if (ret == 1) {
-                reply->writeInt32(outSize);
-                void* buf = reply->writeInplace(outSize);
-                memcpy(buf, out, outSize);
-                free(out);
-            } else {
-                reply->writeInt32(-1);
+status_t BnKeystoreService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+                                       uint32_t flags) {
+    switch (code) {
+    case GET_STATE: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        int32_t ret = getState(userId);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case GET: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int32_t uid = data.readInt32();
+        hidl_vec<uint8_t> out;
+        auto ret = get(name, uid, &out);
+        reply->writeNoException();
+        if (ret.isOk()) {
+            writeBlobAsByteArray(out, reply);
+        } else {
+            reply->writeInt32(-1);
+        }
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case INSERT: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto in = readBlobAsByteArray(data);
+        int uid = data.readInt32();
+        int32_t flags = data.readInt32();
+        int32_t ret = insert(name, in.value(), uid, flags);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case DEL: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int uid = data.readInt32();
+        int32_t ret = del(name, uid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case EXIST: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int uid = data.readInt32();
+        int32_t ret = exist(name, uid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case LIST: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 prefix = data.readString16();
+        int uid = data.readInt32();
+        Vector<String16> matches;
+        int32_t ret = list(prefix, uid, &matches);
+        reply->writeNoException();
+        reply->writeInt32(matches.size());
+        Vector<String16>::const_iterator it = matches.begin();
+        for (; it != matches.end(); ++it) {
+            reply->writeString16(*it);
+        }
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case RESET: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t ret = reset();
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case ON_USER_PASSWORD_CHANGED: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        String16 pass = data.readString16();
+        int32_t ret = onUserPasswordChanged(userId, pass);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case LOCK: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        int32_t ret = lock(userId);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case UNLOCK: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        String16 pass = data.readString16();
+        int32_t ret = unlock(userId, pass);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case IS_EMPTY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        bool ret = isEmpty(userId);
+        reply->writeNoException();
+        reply->writeInt32(ret ? 1 : 0);
+        return NO_ERROR;
+    } break;
+    case GENERATE: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int32_t uid = data.readInt32();
+        int32_t keyType = data.readInt32();
+        int32_t keySize = data.readInt32();
+        int32_t flags = data.readInt32();
+        Vector<sp<KeystoreArg>> args;
+        int32_t argsPresent = data.readInt32();
+        if (argsPresent == 1) {
+            ssize_t numArgs = data.readInt32();
+            if (numArgs > MAX_GENERATE_ARGS) {
+                return BAD_VALUE;
             }
-            return NO_ERROR;
-        } break;
-        case INSERT: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            ssize_t inSize = data.readInt32();
-            const void* in;
-            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
-                in = data.readInplace(inSize);
-            } else {
-                in = NULL;
-                inSize = 0;
-            }
-            int uid = data.readInt32();
-            int32_t flags = data.readInt32();
-            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case DEL: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int uid = data.readInt32();
-            int32_t ret = del(name, uid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case EXIST: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int uid = data.readInt32();
-            int32_t ret = exist(name, uid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case LIST: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 prefix = data.readString16();
-            int uid = data.readInt32();
-            Vector<String16> matches;
-            int32_t ret = list(prefix, uid, &matches);
-            reply->writeNoException();
-            reply->writeInt32(matches.size());
-            Vector<String16>::const_iterator it = matches.begin();
-            for (; it != matches.end(); ++it) {
-                reply->writeString16(*it);
-            }
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case RESET: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t ret = reset();
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case ON_USER_PASSWORD_CHANGED: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            String16 pass = data.readString16();
-            int32_t ret = onUserPasswordChanged(userId, pass);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case LOCK: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            int32_t ret = lock(userId);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case UNLOCK: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            String16 pass = data.readString16();
-            int32_t ret = unlock(userId, pass);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case IS_EMPTY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            bool ret = isEmpty(userId);
-            reply->writeNoException();
-            reply->writeInt32(ret ? 1 : 0);
-            return NO_ERROR;
-        } break;
-        case GENERATE: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int32_t uid = data.readInt32();
-            int32_t keyType = data.readInt32();
-            int32_t keySize = data.readInt32();
-            int32_t flags = data.readInt32();
-            Vector<sp<KeystoreArg> > args;
-            int32_t argsPresent = data.readInt32();
-            if (argsPresent == 1) {
-                ssize_t numArgs = data.readInt32();
-                if (numArgs > MAX_GENERATE_ARGS) {
-                    return BAD_VALUE;
-                }
-                if (numArgs > 0) {
-                    for (size_t i = 0; i < (size_t) numArgs; i++) {
-                        ssize_t inSize = data.readInt32();
-                        if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
-                            sp<KeystoreArg> arg = new KeystoreArg(data.readInplace(inSize),
-                                                                  inSize);
-                            args.push_back(arg);
-                        } else {
-                            args.push_back(NULL);
-                        }
+            if (numArgs > 0) {
+                for (size_t i = 0; i < (size_t)numArgs; i++) {
+                    ssize_t inSize = data.readInt32();
+                    if (inSize >= 0 && (size_t)inSize <= data.dataAvail()) {
+                        sp<KeystoreArg> arg = new KeystoreArg(data.readInplace(inSize), inSize);
+                        args.push_back(arg);
+                    } else {
+                        args.push_back(NULL);
                     }
                 }
             }
-            int32_t ret = generate(name, uid, keyType, keySize, flags, &args);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case IMPORT: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            ssize_t inSize = data.readInt32();
-            const void* in;
-            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
-                in = data.readInplace(inSize);
-            } else {
-                in = NULL;
-                inSize = 0;
-            }
-            int uid = data.readInt32();
-            int32_t flags = data.readInt32();
-            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case SIGN: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            ssize_t inSize = data.readInt32();
-            const void* in;
-            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
-                in = data.readInplace(inSize);
-            } else {
-                in = NULL;
-                inSize = 0;
-            }
-            void* out = NULL;
-            size_t outSize = 0;
-            int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
-            reply->writeNoException();
-            if (outSize > 0 && out != NULL) {
-                reply->writeInt32(outSize);
-                void* buf = reply->writeInplace(outSize);
-                memcpy(buf, out, outSize);
-                delete[] reinterpret_cast<uint8_t*>(out);
-            } else {
-                reply->writeInt32(-1);
-            }
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case VERIFY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            ssize_t inSize = data.readInt32();
-            const void* in;
-            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
-                in = data.readInplace(inSize);
-            } else {
-                in = NULL;
-                inSize = 0;
-            }
-            ssize_t sigSize = data.readInt32();
-            const void* sig;
-            if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
-                sig = data.readInplace(sigSize);
-            } else {
-                sig = NULL;
-                sigSize = 0;
-            }
-            bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
-                    (size_t) sigSize);
-            reply->writeNoException();
-            reply->writeInt32(ret ? 1 : 0);
-            return NO_ERROR;
-        } break;
-        case GET_PUBKEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            void* out = NULL;
-            size_t outSize = 0;
-            int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
-            reply->writeNoException();
-            if (outSize > 0 && out != NULL) {
-                reply->writeInt32(outSize);
-                void* buf = reply->writeInplace(outSize);
-                memcpy(buf, out, outSize);
-                free(out);
-            } else {
-                reply->writeInt32(-1);
-            }
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case GRANT: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int32_t granteeUid = data.readInt32();
-            int32_t ret = grant(name, granteeUid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case UNGRANT: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int32_t granteeUid = data.readInt32();
-            int32_t ret = ungrant(name, granteeUid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case GETMTIME: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int32_t uid = data.readInt32();
-            int64_t ret = getmtime(name, uid);
-            reply->writeNoException();
-            reply->writeInt64(ret);
-            return NO_ERROR;
-        } break;
-        case DUPLICATE: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 srcKey = data.readString16();
-            int32_t srcUid = data.readInt32();
-            String16 destKey = data.readString16();
-            int32_t destUid = data.readInt32();
-            int32_t ret = duplicate(srcKey, srcUid, destKey, destUid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case IS_HARDWARE_BACKED: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 keyType = data.readString16();
-            int32_t ret = is_hardware_backed(keyType);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
         }
-        case CLEAR_UID: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int64_t uid = data.readInt64();
-            int32_t ret = clear_uid(uid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        }
-        case ADD_RNG_ENTROPY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            const uint8_t* bytes = NULL;
-            size_t size = 0;
-            readByteArray(data, &bytes, &size);
-            int32_t ret = addRngEntropy(bytes, size);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        }
-        case GENERATE_KEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            const uint8_t* entropy = NULL;
-            size_t entropyLength = 0;
-            readByteArray(data, &entropy, &entropyLength);
-            int32_t uid = data.readInt32();
-            int32_t flags = data.readInt32();
-            KeyCharacteristics outCharacteristics;
-            int32_t ret = generateKey(name, args, entropy, entropyLength, uid, flags,
-                                      &outCharacteristics);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeParcelable(outCharacteristics);
-            return NO_ERROR;
-        }
-        case GET_KEY_CHARACTERISTICS: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
-            std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
-            int32_t uid = data.readInt32();
-            KeyCharacteristics outCharacteristics;
-            int ret = getKeyCharacteristics(name, clientId.get(), appData.get(), uid,
-                                            &outCharacteristics);
-            if (clientId.get() && clientId->data) {
-                free(const_cast<void*>(static_cast<const void*>(clientId->data)));
-            }
-            if (appData.get() && appData->data) {
-                free(const_cast<void*>(static_cast<const void*>(appData->data)));
-            }
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeParcelable(outCharacteristics);
-            return NO_ERROR;
-        }
-        case IMPORT_KEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
-            const uint8_t* keyData = NULL;
-            size_t keyLength = 0;
-            readByteArray(data, &keyData, &keyLength);
-            int32_t uid = data.readInt32();
-            int32_t flags = data.readInt32();
-            KeyCharacteristics outCharacteristics;
-            int32_t ret = importKey(name, args, format, keyData, keyLength, uid, flags,
-                                    &outCharacteristics);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeParcelable(outCharacteristics);
-            return NO_ERROR;
-        }
-        case EXPORT_KEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
-            std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
-            std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
-            int32_t uid = data.readInt32();
-            ExportResult result;
-            exportKey(name, format, clientId.get(), appData.get(), uid, &result);
-            if (clientId.get() && clientId->data) {
-                free(const_cast<void*>(static_cast<const void*>(clientId->data)));
-            }
-            if (appData.get() && appData->data) {
-                free(const_cast<void*>(static_cast<const void*>(appData->data)));
-            }
-            reply->writeNoException();
-            reply->writeParcelable(result);
+        int32_t ret = generate(name, uid, keyType, keySize, flags, &args);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case IMPORT: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto in = readBlobAsByteArray(data);
+        int uid = data.readInt32();
+        int32_t flags = data.readInt32();
+        auto ret = import(name, in.value(), uid, flags);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case SIGN: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto in = readBlobAsByteArray(data);
+        hidl_vec<uint8_t> out;
+        auto ret = sign(name, in.value(), &out);
+        reply->writeNoException();
+        writeBlobAsByteArray(out, reply);
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case VERIFY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto in = readBlobAsByteArray(data);
+        auto signature = readBlobAsByteArray(data);
+        auto ret = verify(name, in.value(), signature.value());
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case GET_PUBKEY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        hidl_vec<uint8_t> out;
+        auto ret = get_pubkey(name, &out);
+        reply->writeNoException();
+        writeBlobAsByteArray(out, reply);
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case GRANT: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int32_t granteeUid = data.readInt32();
+        int32_t ret = grant(name, granteeUid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case UNGRANT: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int32_t granteeUid = data.readInt32();
+        int32_t ret = ungrant(name, granteeUid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case GETMTIME: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int32_t uid = data.readInt32();
+        int64_t ret = getmtime(name, uid);
+        reply->writeNoException();
+        reply->writeInt64(ret);
+        return NO_ERROR;
+    } break;
+    case DUPLICATE: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 srcKey = data.readString16();
+        int32_t srcUid = data.readInt32();
+        String16 destKey = data.readString16();
+        int32_t destUid = data.readInt32();
+        int32_t ret = duplicate(srcKey, srcUid, destKey, destUid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case IS_HARDWARE_BACKED: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 keyType = data.readString16();
+        int32_t ret = is_hardware_backed(keyType);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    }
+    case CLEAR_UID: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int64_t uid = data.readInt64();
+        int32_t ret = clear_uid(uid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    }
+    case ADD_RNG_ENTROPY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        auto entropy = readBlobAsByteArray(data);
+        auto ret = addRngEntropy(entropy.value());
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    }
+    case GENERATE_KEY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto params = nullable(readParamSetFromParcel, data);
+        auto entropy = readBlobAsByteArray(data);
+        int32_t uid = data.readInt32();
+        int32_t flags = data.readInt32();
+        KeyCharacteristics outCharacteristics;
+        int32_t ret =
+            generateKey(name, params.value(), entropy.value(), uid, flags, &outCharacteristics);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply);
+        return NO_ERROR;
+    }
+    case GET_KEY_CHARACTERISTICS: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto clientId = nullable(readKeymasterBlob, data, true);
+        auto appData = nullable(readKeymasterBlob, data, true);
+        int32_t uid = data.readInt32();
+        KeyCharacteristics outCharacteristics;
+        int ret = getKeyCharacteristics(name, clientId.value(), appData.value(), uid,
+                                        &outCharacteristics);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply);
+        return NO_ERROR;
+    }
+    case IMPORT_KEY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto args = nullable(readParamSetFromParcel, data);
+        KeyFormat format = static_cast<KeyFormat>(data.readInt32());
+        auto keyData = readBlobAsByteArray(data);
+        int32_t uid = data.readInt32();
+        int32_t flags = data.readInt32();
+        KeyCharacteristics outCharacteristics;
+        int32_t ret =
+            importKey(name, args.value(), format, keyData.value(), uid, flags, &outCharacteristics);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply);
+        return NO_ERROR;
+    }
+    case EXPORT_KEY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        KeyFormat format = static_cast<KeyFormat>(data.readInt32());
+        auto clientId = nullable(readKeymasterBlob, data, true);
+        auto appData = nullable(readKeymasterBlob, data, true);
+        int32_t uid = data.readInt32();
+        ExportResult result;
+        exportKey(name, format, clientId.value(), appData.value(), uid, &result);
+        reply->writeNoException();
+        reply->writeParcelable(result);
 
-            return NO_ERROR;
-        }
-        case BEGIN: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            String16 name = data.readString16();
-            keymaster_purpose_t purpose = static_cast<keymaster_purpose_t>(data.readInt32());
-            bool pruneable = data.readInt32() != 0;
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            const uint8_t* entropy = NULL;
-            size_t entropyLength = 0;
-            readByteArray(data, &entropy, &entropyLength);
-            int32_t uid = data.readInt32();
-            OperationResult result;
-            begin(token, name, purpose, pruneable, args, entropy, entropyLength, uid, &result);
-            reply->writeNoException();
-            reply->writeParcelable(result);
+        return NO_ERROR;
+    }
+    case BEGIN: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        sp<IBinder> token = data.readStrongBinder();
+        String16 name = data.readString16();
+        KeyPurpose purpose = static_cast<KeyPurpose>(data.readInt32());
+        bool pruneable = data.readInt32() != 0;
+        auto args = nullable(readParamSetFromParcel, data);
+        auto entropy = readBlobAsByteArray(data);
+        int32_t uid = data.readInt32();
+        OperationResult result;
+        begin(token, name, purpose, pruneable, args.value(), entropy.value(), uid, &result);
+        reply->writeNoException();
+        reply->writeParcelable(result);
 
-            return NO_ERROR;
-        }
-        case UPDATE: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            const uint8_t* buf = NULL;
-            size_t bufLength = 0;
-            readByteArray(data, &buf, &bufLength);
-            OperationResult result;
-            update(token, args, buf, bufLength, &result);
-            reply->writeNoException();
-            reply->writeParcelable(result);
+        return NO_ERROR;
+    }
+    case UPDATE: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        sp<IBinder> token = data.readStrongBinder();
+        auto args = nullable(readParamSetFromParcel, data);
+        auto buf = readBlobAsByteArray(data);
+        OperationResult result;
+        update(token, args.value(), buf.value(), &result);
+        reply->writeNoException();
+        reply->writeParcelable(result);
 
-            return NO_ERROR;
-        }
-        case FINISH: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            const uint8_t* signature = NULL;
-            size_t signatureLength = 0;
-            readByteArray(data, &signature, &signatureLength);
-            const uint8_t* entropy = NULL;
-            size_t entropyLength = 0;
-            readByteArray(data, &entropy, &entropyLength);
-            OperationResult result;
-            finish(token, args, signature, signatureLength, entropy, entropyLength,  &result);
-            reply->writeNoException();
-            reply->writeParcelable(result);
+        return NO_ERROR;
+    }
+    case FINISH: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        sp<IBinder> token = data.readStrongBinder();
+        auto args = nullable(readParamSetFromParcel, data);
+        auto signature = readBlobAsByteArray(data);
+        auto entropy = readBlobAsByteArray(data);
+        OperationResult result;
+        finish(token, args.value(), signature.value(), entropy.value(), &result);
+        reply->writeNoException();
+        reply->writeParcelable(result);
 
-            return NO_ERROR;
-        }
-        case ABORT: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            int32_t result = abort(token);
-            reply->writeNoException();
-            reply->writeInt32(result);
+        return NO_ERROR;
+    }
+    case ABORT: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        sp<IBinder> token = data.readStrongBinder();
+        int32_t result = abort(token);
+        reply->writeNoException();
+        reply->writeInt32(result);
 
-            return NO_ERROR;
-        }
-        case IS_OPERATION_AUTHORIZED: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            bool result = isOperationAuthorized(token);
-            reply->writeNoException();
-            reply->writeInt32(result ? 1 : 0);
+        return NO_ERROR;
+    }
+    case IS_OPERATION_AUTHORIZED: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        sp<IBinder> token = data.readStrongBinder();
+        bool result = isOperationAuthorized(token);
+        reply->writeNoException();
+        reply->writeInt32(result ? 1 : 0);
 
-            return NO_ERROR;
-        }
-        case ADD_AUTH_TOKEN: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            const uint8_t* token_bytes = NULL;
-            size_t size = 0;
-            readByteArray(data, &token_bytes, &size);
-            int32_t result = addAuthToken(token_bytes, size);
-            reply->writeNoException();
-            reply->writeInt32(result);
+        return NO_ERROR;
+    }
+    case ADD_AUTH_TOKEN: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        const uint8_t* token_bytes = NULL;
+        size_t size = 0;
+        readByteArray(data, &token_bytes, &size);
+        int32_t result = addAuthToken(token_bytes, size);
+        reply->writeNoException();
+        reply->writeInt32(result);
 
-            return NO_ERROR;
-        }
-        case ON_USER_ADDED: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            int32_t parentId = data.readInt32();
-            int32_t result = onUserAdded(userId, parentId);
-            reply->writeNoException();
-            reply->writeInt32(result);
+        return NO_ERROR;
+    }
+    case ON_USER_ADDED: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        int32_t parentId = data.readInt32();
+        int32_t result = onUserAdded(userId, parentId);
+        reply->writeNoException();
+        reply->writeInt32(result);
 
-            return NO_ERROR;
-        }
-        case ON_USER_REMOVED: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            int32_t result = onUserRemoved(userId);
-            reply->writeNoException();
-            reply->writeInt32(result);
+        return NO_ERROR;
+    }
+    case ON_USER_REMOVED: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        int32_t result = onUserRemoved(userId);
+        reply->writeNoException();
+        reply->writeInt32(result);
 
-            return NO_ERROR;
-        }
-        case ATTEST_KEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            KeymasterArguments params;
-            if (data.readInt32() != 0) {
-                params.readFromParcel(data);
-            }
-            KeymasterCertificateChain chain;
-            int ret = attestKey(name, params, &chain);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeInt32(1);
-            chain.writeToParcel(reply);
+        return NO_ERROR;
+    }
+    case ATTEST_KEY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto params = nullable(readParamSetFromParcel, data);
+        hidl_vec<hidl_vec<uint8_t>> chain;
+        int ret = attestKey(name, params.value(), &chain);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        nullable(writeCertificateChainToParcel, chain, reply);
 
-            return NO_ERROR;
-        }
-        case ON_DEVICE_OFF_BODY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t ret = onDeviceOffBody();
-            reply->writeNoException();
-            reply->writeInt32(ret);
+        return NO_ERROR;
+    }
 
-            return NO_ERROR;
-        }
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
+    case ATTEST_DEVICE_IDS: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        auto params = nullable(readParamSetFromParcel, data);
+        hidl_vec<hidl_vec<uint8_t>> chain;
+        int ret = attestDeviceIds(params.value(), &chain);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        nullable(writeCertificateChainToParcel, chain, reply);
+
+        return NO_ERROR;
+    }
+
+    case ON_DEVICE_OFF_BODY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t ret = onDeviceOffBody();
+        reply->writeNoException();
+        reply->writeInt32(ret);
+
+        return NO_ERROR;
+    }
+    default:
+        return BBinder::onTransact(code, data, reply, flags);
     }
 }
 
 // ----------------------------------------------------------------------------
 
-}; // namespace android
+};  // namespace android
diff --git a/keystore/KeyAttestationApplicationId.cpp b/keystore/KeyAttestationApplicationId.cpp
new file mode 100644
index 0000000..1352124
--- /dev/null
+++ b/keystore/KeyAttestationApplicationId.cpp
@@ -0,0 +1,40 @@
+/*
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "include/keystore/KeyAttestationApplicationId.h"
+
+#include <binder/Parcel.h>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+status_t KeyAttestationApplicationId::writeToParcel(Parcel* parcel) const {
+    return parcel->writeParcelableVector(packageInfos_);
+}
+
+status_t KeyAttestationApplicationId::readFromParcel(const Parcel* parcel) {
+    std::unique_ptr<std::vector<std::unique_ptr<KeyAttestationPackageInfo>>> temp_vector;
+    auto rc = parcel->readParcelableVector(&temp_vector);
+    if (rc != NO_ERROR) return rc;
+    packageInfos_.reset(temp_vector.release());
+    return NO_ERROR;
+}
+
+}  // namespace keymaster
+}  // namespace security
+}  // namespace android
diff --git a/keystore/KeyAttestationPackageInfo.cpp b/keystore/KeyAttestationPackageInfo.cpp
new file mode 100644
index 0000000..a84c246
--- /dev/null
+++ b/keystore/KeyAttestationPackageInfo.cpp
@@ -0,0 +1,49 @@
+/*
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "include/keystore/KeyAttestationPackageInfo.h"
+
+#include <binder/Parcel.h>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+status_t KeyAttestationPackageInfo::writeToParcel(Parcel* parcel) const {
+    auto rc = parcel->writeString16(packageName_);
+    if (rc != NO_ERROR) return rc;
+    rc = parcel->writeInt32(versionCode_);
+    if (rc != NO_ERROR) return rc;
+    return parcel->writeParcelableVector(signatures_);
+}
+
+status_t KeyAttestationPackageInfo::readFromParcel(const Parcel* parcel) {
+    auto rc = parcel->readString16(&packageName_);
+    if (rc != NO_ERROR) return rc;
+    rc = parcel->readInt32(&versionCode_);
+    if (rc != NO_ERROR) return rc;
+
+    std::unique_ptr<std::vector<std::unique_ptr<content::pm::Signature>>> temp_vector;
+    rc = parcel->readParcelableVector(&temp_vector);
+    if (rc != NO_ERROR) return rc;
+    signatures_.reset(temp_vector.release());
+    return NO_ERROR;
+}
+
+}  // namespace keymaster
+}  // namespace security
+}  // namespace android
diff --git a/keystore/Signature.cpp b/keystore/Signature.cpp
new file mode 100644
index 0000000..1566df9
--- /dev/null
+++ b/keystore/Signature.cpp
@@ -0,0 +1,36 @@
+/*
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include "include/keystore/Signature.h"
+
+#include <binder/Parcel.h>
+
+namespace android {
+namespace content {
+namespace pm {
+
+status_t Signature::writeToParcel(Parcel* parcel) const {
+    return parcel->writeByteVector(sig_data_);
+}
+
+status_t Signature::readFromParcel(const Parcel* parcel) {
+    return parcel->readByteVector(&sig_data_);
+}
+
+}  // namespace pm
+}  // namespace content
+}  // namespace android
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
index f0f4981..3f476cd 100644
--- a/keystore/auth_token_table.cpp
+++ b/keystore/auth_token_table.cpp
@@ -21,10 +21,36 @@
 
 #include <algorithm>
 
-#include <keymaster/android_keymaster_utils.h>
-#include <keymaster/logger.h>
+#include <cutils/log.h>
 
-namespace keymaster {
+namespace keystore {
+
+template <typename IntType, uint32_t byteOrder> struct choose_hton;
+
+template <typename IntType> struct choose_hton<IntType, __ORDER_LITTLE_ENDIAN__> {
+    inline static IntType hton(const IntType& value) {
+        IntType result = 0;
+        const unsigned char* inbytes = reinterpret_cast<const unsigned char*>(&value);
+        unsigned char* outbytes = reinterpret_cast<unsigned char*>(&result);
+        for (int i = sizeof(IntType) - 1; i >= 0; --i) {
+            *(outbytes++) = inbytes[i];
+        }
+        return result;
+    }
+};
+
+template <typename IntType> struct choose_hton<IntType, __ORDER_BIG_ENDIAN__> {
+    inline static IntType hton(const IntType& value) { return value; }
+};
+
+template <typename IntType> inline IntType hton(const IntType& value) {
+    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
+}
+
+template <typename IntType> inline IntType ntoh(const IntType& value) {
+    // same operation and hton
+    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
+}
 
 //
 // Some trivial template wrappers around std algorithms, so they take containers not ranges.
@@ -49,48 +75,43 @@
     return time.tv_sec;
 }
 
-void AuthTokenTable::AddAuthenticationToken(const hw_auth_token_t* auth_token) {
+void AuthTokenTable::AddAuthenticationToken(const HardwareAuthToken* auth_token) {
     Entry new_entry(auth_token, clock_function_());
     RemoveEntriesSupersededBy(new_entry);
     if (entries_.size() >= max_entries_) {
-        LOG_W("Auth token table filled up; replacing oldest entry", 0);
+        ALOGW("Auth token table filled up; replacing oldest entry");
         *min_element(entries_) = std::move(new_entry);
     } else {
         entries_.push_back(std::move(new_entry));
     }
 }
 
-inline bool is_secret_key_operation(keymaster_algorithm_t algorithm, keymaster_purpose_t purpose) {
-    if ((algorithm != KM_ALGORITHM_RSA && algorithm != KM_ALGORITHM_EC))
+inline bool is_secret_key_operation(Algorithm algorithm, KeyPurpose purpose) {
+    if ((algorithm != Algorithm::RSA && algorithm != Algorithm::EC))
         return true;
-    if (purpose == KM_PURPOSE_SIGN || purpose == KM_PURPOSE_DECRYPT)
+    if (purpose == KeyPurpose::SIGN || purpose == KeyPurpose::DECRYPT)
         return true;
     return false;
 }
 
-inline bool KeyRequiresAuthentication(const AuthorizationSet& key_info,
-                                      keymaster_purpose_t purpose) {
-    keymaster_algorithm_t algorithm = KM_ALGORITHM_AES;
-    key_info.GetTagValue(TAG_ALGORITHM, &algorithm);
-    return is_secret_key_operation(algorithm, purpose) && key_info.find(TAG_NO_AUTH_REQUIRED) == -1;
+inline bool KeyRequiresAuthentication(const AuthorizationSet& key_info, KeyPurpose purpose) {
+    auto algorithm = defaultOr(key_info.GetTagValue(TAG_ALGORITHM), Algorithm::AES);
+    return is_secret_key_operation(algorithm, purpose) &&
+           key_info.find(Tag::NO_AUTH_REQUIRED) == -1;
 }
 
-inline bool KeyRequiresAuthPerOperation(const AuthorizationSet& key_info,
-                                        keymaster_purpose_t purpose) {
-    keymaster_algorithm_t algorithm = KM_ALGORITHM_AES;
-    key_info.GetTagValue(TAG_ALGORITHM, &algorithm);
-    return is_secret_key_operation(algorithm, purpose) && key_info.find(TAG_AUTH_TIMEOUT) == -1;
+inline bool KeyRequiresAuthPerOperation(const AuthorizationSet& key_info, KeyPurpose purpose) {
+    auto algorithm = defaultOr(key_info.GetTagValue(TAG_ALGORITHM), Algorithm::AES);
+    return is_secret_key_operation(algorithm, purpose) && key_info.find(Tag::AUTH_TIMEOUT) == -1;
 }
 
 AuthTokenTable::Error AuthTokenTable::FindAuthorization(const AuthorizationSet& key_info,
-                                                        keymaster_purpose_t purpose,
-                                                        keymaster_operation_handle_t op_handle,
-                                                        const hw_auth_token_t** found) {
-    if (!KeyRequiresAuthentication(key_info, purpose))
-        return AUTH_NOT_REQUIRED;
+                                                        KeyPurpose purpose, uint64_t op_handle,
+                                                        const HardwareAuthToken** found) {
+    if (!KeyRequiresAuthentication(key_info, purpose)) return AUTH_NOT_REQUIRED;
 
-    hw_authenticator_type_t auth_type = HW_AUTH_NONE;
-    key_info.GetTagValue(TAG_USER_AUTH_TYPE, &auth_type);
+    auto auth_type =
+        defaultOr(key_info.GetTagValue(TAG_USER_AUTH_TYPE), HardwareAuthenticatorType::NONE);
 
     std::vector<uint64_t> key_sids;
     ExtractSids(key_info, &key_sids);
@@ -101,44 +122,41 @@
         return FindTimedAuthorization(key_sids, auth_type, key_info, found);
 }
 
-AuthTokenTable::Error AuthTokenTable::FindAuthPerOpAuthorization(
-    const std::vector<uint64_t>& sids, hw_authenticator_type_t auth_type,
-    keymaster_operation_handle_t op_handle, const hw_auth_token_t** found) {
-    if (op_handle == 0)
-        return OP_HANDLE_REQUIRED;
+AuthTokenTable::Error
+AuthTokenTable::FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
+                                           HardwareAuthenticatorType auth_type, uint64_t op_handle,
+                                           const HardwareAuthToken** found) {
+    if (op_handle == 0) return OP_HANDLE_REQUIRED;
 
     auto matching_op = find_if(
         entries_, [&](Entry& e) { return e.token()->challenge == op_handle && !e.completed(); });
 
-    if (matching_op == entries_.end())
-        return AUTH_TOKEN_NOT_FOUND;
+    if (matching_op == entries_.end()) return AUTH_TOKEN_NOT_FOUND;
 
-    if (!matching_op->SatisfiesAuth(sids, auth_type))
-        return AUTH_TOKEN_WRONG_SID;
+    if (!matching_op->SatisfiesAuth(sids, auth_type)) return AUTH_TOKEN_WRONG_SID;
 
     *found = matching_op->token();
     return OK;
 }
 
 AuthTokenTable::Error AuthTokenTable::FindTimedAuthorization(const std::vector<uint64_t>& sids,
-                                                             hw_authenticator_type_t auth_type,
+                                                             HardwareAuthenticatorType auth_type,
                                                              const AuthorizationSet& key_info,
-                                                             const hw_auth_token_t** found) {
+                                                             const HardwareAuthToken** found) {
     Entry* newest_match = NULL;
     for (auto& entry : entries_)
         if (entry.SatisfiesAuth(sids, auth_type) && entry.is_newer_than(newest_match))
             newest_match = &entry;
 
-    if (!newest_match)
-        return AUTH_TOKEN_NOT_FOUND;
+    if (!newest_match) return AUTH_TOKEN_NOT_FOUND;
 
-    uint32_t timeout;
-    key_info.GetTagValue(TAG_AUTH_TIMEOUT, &timeout);
+    auto timeout = defaultOr(key_info.GetTagValue(TAG_AUTH_TIMEOUT), 0);
+
     time_t now = clock_function_();
     if (static_cast<int64_t>(newest_match->time_received()) + timeout < static_cast<int64_t>(now))
         return AUTH_TOKEN_EXPIRED;
 
-    if (key_info.GetTagValue(TAG_ALLOW_WHILE_ON_BODY)) {
+    if (key_info.GetTagValue(TAG_ALLOW_WHILE_ON_BODY).isOk()) {
         if (static_cast<int64_t>(newest_match->time_received()) <
             static_cast<int64_t>(last_off_body_)) {
             return AUTH_TOKEN_EXPIRED;
@@ -153,8 +171,8 @@
 void AuthTokenTable::ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids) {
     assert(sids);
     for (auto& param : key_info)
-        if (param.tag == TAG_USER_SECURE_ID)
-            sids->push_back(param.long_integer);
+        if (param.tag == Tag::USER_SECURE_ID)
+            sids->push_back(authorizationValue(TAG_USER_SECURE_ID, param).value());
 }
 
 void AuthTokenTable::RemoveEntriesSupersededBy(const Entry& entry) {
@@ -175,38 +193,35 @@
                        [&](Entry& e) { return e.Supersedes(entry); });
 }
 
-void AuthTokenTable::MarkCompleted(const keymaster_operation_handle_t op_handle) {
+void AuthTokenTable::MarkCompleted(const uint64_t op_handle) {
     auto found = find_if(entries_, [&](Entry& e) { return e.token()->challenge == op_handle; });
-    if (found == entries_.end())
-        return;
+    if (found == entries_.end()) return;
 
     assert(!IsSupersededBySomeEntry(*found));
     found->mark_completed();
 
-    if (IsSupersededBySomeEntry(*found))
-        entries_.erase(found);
+    if (IsSupersededBySomeEntry(*found)) entries_.erase(found);
 }
 
-AuthTokenTable::Entry::Entry(const hw_auth_token_t* token, time_t current_time)
+AuthTokenTable::Entry::Entry(const HardwareAuthToken* token, time_t current_time)
     : token_(token), time_received_(current_time), last_use_(current_time),
-      operation_completed_(token_->challenge == 0) {
-}
+      operation_completed_(token_->challenge == 0) {}
 
 uint32_t AuthTokenTable::Entry::timestamp_host_order() const {
     return ntoh(token_->timestamp);
 }
 
-hw_authenticator_type_t AuthTokenTable::Entry::authenticator_type() const {
-    hw_authenticator_type_t result = static_cast<hw_authenticator_type_t>(
-        ntoh(static_cast<uint32_t>(token_->authenticator_type)));
+HardwareAuthenticatorType AuthTokenTable::Entry::authenticator_type() const {
+    HardwareAuthenticatorType result = static_cast<HardwareAuthenticatorType>(
+        ntoh(static_cast<uint32_t>(token_->authenticatorType)));
     return result;
 }
 
 bool AuthTokenTable::Entry::SatisfiesAuth(const std::vector<uint64_t>& sids,
-                                          hw_authenticator_type_t auth_type) {
+                                          HardwareAuthenticatorType auth_type) {
     for (auto sid : sids)
-        if ((sid == token_->authenticator_id) ||
-            (sid == token_->user_id && (auth_type & authenticator_type()) != 0))
+        if ((sid == token_->authenticatorId) ||
+            (sid == token_->userId && (auth_type & authenticator_type()) != 0))
             return true;
     return false;
 }
@@ -216,12 +231,11 @@
 }
 
 bool AuthTokenTable::Entry::Supersedes(const Entry& entry) const {
-    if (!entry.completed())
-        return false;
+    if (!entry.completed()) return false;
 
-    return (token_->user_id == entry.token_->user_id &&
-            token_->authenticator_type == entry.token_->authenticator_type &&
-            token_->authenticator_type == entry.token_->authenticator_type &&
+    return (token_->userId == entry.token_->userId &&
+            token_->authenticatorType == entry.token_->authenticatorType &&
+            token_->authenticatorType == entry.token_->authenticatorType &&
             timestamp_host_order() > entry.timestamp_host_order());
 }
 
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index 4d54a39..6f7aab1 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -18,12 +18,14 @@
 #include <vector>
 
 #include <hardware/hw_auth_token.h>
-#include <keymaster/authorization_set.h>
+#include <keystore/authorization_set.h>
 
 #ifndef KEYSTORE_AUTH_TOKEN_TABLE_H_
 #define KEYSTORE_AUTH_TOKEN_TABLE_H_
 
-namespace keymaster {
+namespace keystore {
+
+using android::hardware::keymaster::V3_0::HardwareAuthToken;
 
 namespace test {
 class AuthTokenTableTest;
@@ -42,7 +44,8 @@
 class AuthTokenTable {
   public:
     explicit AuthTokenTable(size_t max_entries = 32, time_t (*clock_function)() = clock_gettime_raw)
-        : max_entries_(max_entries), last_off_body_(clock_function()), clock_function_(clock_function) {}
+        : max_entries_(max_entries), last_off_body_(clock_function()),
+          clock_function_(clock_function) {}
 
     enum Error {
         OK,
@@ -58,7 +61,7 @@
     /**
      * Add an authorization token to the table.  The table takes ownership of the argument.
      */
-    void AddAuthenticationToken(const hw_auth_token_t* token);
+    void AddAuthenticationToken(const HardwareAuthToken* token);
 
     /**
      * Find an authorization token that authorizes the operation specified by \p operation_handle on
@@ -70,30 +73,14 @@
      *
      * The table retains ownership of the returned object.
      */
-    Error FindAuthorization(const AuthorizationSet& key_info, keymaster_purpose_t purpose,
-                            keymaster_operation_handle_t op_handle, const hw_auth_token_t** found);
-
-    /**
-     * Find an authorization token that authorizes the operation specified by \p operation_handle on
-     * a key with the characteristics specified in \p key_info.
-     *
-     * This method is O(n * m), where n is the number of KM_TAG_USER_SECURE_ID entries in key_info
-     * and m is the number of entries in the table.  It could be made better, but n and m should
-     * always be small.
-     *
-     * The table retains ownership of the returned object.
-     */
-    Error FindAuthorization(const keymaster_key_param_t* params, size_t params_count,
-                            keymaster_purpose_t purpose, keymaster_operation_handle_t op_handle,
-                            const hw_auth_token_t** found) {
-        return FindAuthorization(AuthorizationSet(params, params_count), purpose, op_handle, found);
-    }
+    Error FindAuthorization(const AuthorizationSet& key_info, KeyPurpose purpose,
+                            uint64_t op_handle, const HardwareAuthToken** found);
 
     /**
      * Mark operation completed.  This allows tokens associated with the specified operation to be
      * superseded by new tokens.
      */
-    void MarkCompleted(const keymaster_operation_handle_t op_handle);
+    void MarkCompleted(const uint64_t op_handle);
 
     /**
      * Update the last_off_body_ timestamp so that tokens which remain authorized only so long as
@@ -110,7 +97,7 @@
 
     class Entry {
       public:
-        Entry(const hw_auth_token_t* token, time_t current_time);
+        Entry(const HardwareAuthToken* token, time_t current_time);
         Entry(Entry&& entry) { *this = std::move(entry); }
 
         void operator=(Entry&& rhs) {
@@ -125,36 +112,34 @@
         void UpdateLastUse(time_t time);
 
         bool Supersedes(const Entry& entry) const;
-        bool SatisfiesAuth(const std::vector<uint64_t>& sids, hw_authenticator_type_t auth_type);
+        bool SatisfiesAuth(const std::vector<uint64_t>& sids, HardwareAuthenticatorType auth_type);
 
         bool is_newer_than(const Entry* entry) {
-            if (!entry)
-                return true;
+            if (!entry) return true;
             return timestamp_host_order() > entry->timestamp_host_order();
         }
 
         void mark_completed() { operation_completed_ = true; }
 
-        const hw_auth_token_t* token() { return token_.get(); }
+        const HardwareAuthToken* token() { return token_.get(); }
         time_t time_received() const { return time_received_; }
         bool completed() const { return operation_completed_; }
         uint32_t timestamp_host_order() const;
-        hw_authenticator_type_t authenticator_type() const;
+        HardwareAuthenticatorType authenticator_type() const;
 
       private:
-        std::unique_ptr<const hw_auth_token_t> token_;
+        std::unique_ptr<const HardwareAuthToken> token_;
         time_t time_received_;
         time_t last_use_;
         bool operation_completed_;
     };
 
     Error FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
-                                     hw_authenticator_type_t auth_type,
-                                     keymaster_operation_handle_t op_handle,
-                                     const hw_auth_token_t** found);
+                                     HardwareAuthenticatorType auth_type, uint64_t op_handle,
+                                     const HardwareAuthToken** found);
     Error FindTimedAuthorization(const std::vector<uint64_t>& sids,
-                                 hw_authenticator_type_t auth_type,
-                                 const AuthorizationSet& key_info, const hw_auth_token_t** found);
+                                 HardwareAuthenticatorType auth_type,
+                                 const AuthorizationSet& key_info, const HardwareAuthToken** found);
     void ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids);
     void RemoveEntriesSupersededBy(const Entry& entry);
     bool IsSupersededBySomeEntry(const Entry& entry);
diff --git a/keystore/authorization_set.cpp b/keystore/authorization_set.cpp
new file mode 100644
index 0000000..e30b32d
--- /dev/null
+++ b/keystore/authorization_set.cpp
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <keystore/authorization_set.h>
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits>
+#include <ostream>
+#include <istream>
+
+#include <new>
+
+namespace keystore {
+
+inline bool keyParamLess(const KeyParameter& a, const KeyParameter& b) {
+    if (a.tag != b.tag) return a.tag < b.tag;
+    int retval;
+    switch (typeFromTag(a.tag)) {
+    case TagType::INVALID:
+    case TagType::BOOL:
+        return false;
+    case TagType::ENUM:
+    case TagType::ENUM_REP:
+    case TagType::UINT:
+    case TagType::UINT_REP:
+        return a.f.integer < b.f.integer;
+    case TagType::ULONG:
+    case TagType::ULONG_REP:
+        return a.f.longInteger < b.f.longInteger;
+    case TagType::DATE:
+        return a.f.dateTime < b.f.dateTime;
+    case TagType::BIGNUM:
+    case TagType::BYTES:
+        // Handle the empty cases.
+        if (a.blob.size() == 0)
+            return b.blob.size() != 0;
+        if (b.blob.size() == 0) return false;
+
+        retval = memcmp(&a.blob[0], &b.blob[0], std::min(a.blob.size(), b.blob.size()));
+        // if one is the prefix of the other the longer wins
+        if (retval == 0) return a.blob.size() < b.blob.size();
+        // Otherwise a is less if a is less.
+        else return retval < 0;
+    }
+    return false;
+}
+
+inline bool keyParamEqual(const KeyParameter& a, const KeyParameter& b) {
+    if (a.tag != b.tag) return false;
+
+    switch (typeFromTag(a.tag)) {
+    case TagType::INVALID:
+    case TagType::BOOL:
+        return true;
+    case TagType::ENUM:
+    case TagType::ENUM_REP:
+    case TagType::UINT:
+    case TagType::UINT_REP:
+        return a.f.integer == b.f.integer;
+    case TagType::ULONG:
+    case TagType::ULONG_REP:
+        return a.f.longInteger == b.f.longInteger;
+    case TagType::DATE:
+        return a.f.dateTime == b.f.dateTime;
+    case TagType::BIGNUM:
+    case TagType::BYTES:
+        if (a.blob.size() != b.blob.size()) return false;
+        return a.blob.size() == 0 ||
+                memcmp(&a.blob[0], &b.blob[0], a.blob.size()) == 0;
+    }
+    return false;
+}
+
+void AuthorizationSet::Sort() {
+    std::sort(data_.begin(), data_.end(), keyParamLess);
+}
+
+void AuthorizationSet::Deduplicate() {
+    if (data_.empty()) return;
+
+    Sort();
+    std::vector<KeyParameter> result;
+
+    auto curr = data_.begin();
+    auto prev = curr++;
+    for (; curr != data_.end(); ++prev, ++curr) {
+        if (prev->tag == Tag::INVALID) continue;
+
+        if (!keyParamEqual(*prev, *curr)) {
+            result.emplace_back(std::move(*prev));
+        }
+    }
+    result.emplace_back(std::move(*prev));
+
+    std::swap(data_, result);
+}
+
+void AuthorizationSet::Union(const AuthorizationSet& other) {
+    data_.insert(data_.end(), other.data_.begin(), other.data_.end());
+    Deduplicate();
+}
+
+void AuthorizationSet::Subtract(const AuthorizationSet& other) {
+    Deduplicate();
+
+    auto i = other.begin();
+    while (i != other.end()) {
+        int pos = -1;
+        do {
+            pos = find(i->tag, pos);
+            if (pos != -1 && keyParamEqual(*i, data_[pos])) {
+                data_.erase(data_.begin() + pos);
+                break;
+            }
+        } while (pos != -1);
+        ++i;
+    }
+}
+
+int AuthorizationSet::find(Tag tag, int begin) const {
+    auto iter = data_.begin() + (1 + begin);
+
+    while (iter != data_.end() && iter->tag != tag) ++iter;
+
+    if (iter != data_.end()) return iter - data_.begin();
+    return -1;
+}
+
+bool AuthorizationSet::erase(int index) {
+    auto pos = data_.begin() + index;
+    if (pos != data_.end()) {
+        data_.erase(pos);
+        return true;
+    }
+    return false;
+}
+
+KeyParameter& AuthorizationSet::operator[](int at) {
+    return data_[at];
+}
+
+const KeyParameter& AuthorizationSet::operator[](int at) const {
+    return data_[at];
+}
+
+void AuthorizationSet::Clear() {
+    data_.clear();
+}
+
+size_t AuthorizationSet::GetTagCount(Tag tag) const {
+    size_t count = 0;
+    for (int pos = -1; (pos = find(tag, pos)) != -1;)
+        ++count;
+    return count;
+}
+
+NullOr<const KeyParameter&> AuthorizationSet::GetEntry(Tag tag) const {
+    int pos = find(tag);
+    if (pos == -1) return {};
+    return data_[pos];
+}
+
+/**
+ * Persistent format is:
+ * | 32 bit indirect_size         |
+ * --------------------------------
+ * | indirect_size bytes of data  | this is where the blob data is stored
+ * --------------------------------
+ * | 32 bit element_count         | number of entries
+ * | 32 bit elements_size         | total bytes used by entries (entries have variable length)
+ * --------------------------------
+ * | elementes_size bytes of data | where the elements are stored
+ */
+
+/**
+ * Persistent format of blobs and bignums:
+ * | 32 bit tag             |
+ * | 32 bit blob_length     |
+ * | 32 bit indirect_offset |
+ */
+
+struct OutStreams {
+    std::ostream& indirect;
+    std::ostream& elements;
+};
+
+OutStreams& serializeParamValue(OutStreams& out, const hidl_vec<uint8_t>& blob) {
+    uint32_t buffer;
+
+    // write blob_length
+    auto blob_length = blob.size();
+    if (blob_length > std::numeric_limits<uint32_t>::max()) {
+        out.elements.setstate(std::ios_base::badbit);
+        return out;
+    }
+    buffer = blob_length;
+    out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
+
+    // write indirect_offset
+    auto offset = out.indirect.tellp();
+    if (offset < 0 || offset > std::numeric_limits<uint32_t>::max() ||
+            uint32_t(offset) + uint32_t(blob_length) < uint32_t(offset)) { // overflow check
+        out.elements.setstate(std::ios_base::badbit);
+        return out;
+    }
+    buffer = offset;
+    out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
+
+    // write blob to indirect stream
+    if(blob_length)
+        out.indirect.write(reinterpret_cast<const char*>(&blob[0]), blob_length);
+
+    return out;
+}
+
+template <typename T>
+OutStreams& serializeParamValue(OutStreams& out, const T& value) {
+    out.elements.write(reinterpret_cast<const char*>(&value), sizeof(T));
+    return out;
+}
+
+OutStreams& serialize(TAG_INVALID_t&&, OutStreams& out, const KeyParameter&) {
+    // skip invalid entries.
+    return out;
+}
+template <typename T>
+OutStreams& serialize(T ttag, OutStreams& out, const KeyParameter& param) {
+    out.elements.write(reinterpret_cast<const char*>(&param.tag), sizeof(int32_t));
+    return serializeParamValue(out, accessTagValue(ttag, param));
+}
+
+template <typename... T>
+struct choose_serializer;
+template <typename... Tags>
+struct choose_serializer<MetaList<Tags...>> {
+    static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
+        return choose_serializer<Tags...>::serialize(out, param);
+    }
+};
+template <>
+struct choose_serializer<> {
+    static OutStreams& serialize(OutStreams& out, const KeyParameter&) {
+        return out;
+    }
+};
+template <TagType tag_type, Tag tag, typename... Tail>
+struct choose_serializer<TypedTag<tag_type, tag>, Tail...> {
+    static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
+        if (param.tag == tag) {
+            return keystore::serialize(TypedTag<tag_type, tag>(), out, param);
+        } else {
+            return choose_serializer<Tail...>::serialize(out, param);
+        }
+    }
+};
+
+OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
+    return choose_serializer<all_tags_t>::serialize(out, param);
+}
+
+std::ostream& serialize(std::ostream& out, const std::vector<KeyParameter>& params) {
+    std::stringstream indirect;
+    std::stringstream elements;
+    OutStreams streams = { indirect, elements };
+    for (const auto& param: params) {
+        serialize(streams, param);
+    }
+    if (indirect.bad() || elements.bad()) {
+        out.setstate(std::ios_base::badbit);
+        return out;
+    }
+    auto pos = indirect.tellp();
+    if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
+        out.setstate(std::ios_base::badbit);
+        return out;
+    }
+    uint32_t indirect_size = pos;
+    pos = elements.tellp();
+    if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
+        out.setstate(std::ios_base::badbit);
+        return out;
+    }
+    uint32_t elements_size = pos;
+    uint32_t element_count = params.size();
+
+    out.write(reinterpret_cast<const char*>(&indirect_size), sizeof(uint32_t));
+
+    pos = out.tellp();
+    if (indirect_size)
+        out << indirect.rdbuf();
+    assert(out.tellp() - pos == indirect_size);
+
+    out.write(reinterpret_cast<const char*>(&element_count), sizeof(uint32_t));
+    out.write(reinterpret_cast<const char*>(&elements_size), sizeof(uint32_t));
+
+    pos = out.tellp();
+    if (elements_size)
+        out << elements.rdbuf();
+    assert(out.tellp() - pos == elements_size);
+
+    return out;
+}
+
+struct InStreams {
+    std::istream& indirect;
+    std::istream& elements;
+};
+
+InStreams& deserializeParamValue(InStreams& in, hidl_vec<uint8_t>* blob) {
+    uint32_t blob_length = 0;
+    uint32_t offset = 0;
+    in.elements.read(reinterpret_cast<char*>(&blob_length), sizeof(uint32_t));
+    blob->resize(blob_length);
+    in.elements.read(reinterpret_cast<char*>(&offset), sizeof(uint32_t));
+    in.indirect.seekg(offset);
+    in.indirect.read(reinterpret_cast<char*>(&(*blob)[0]), blob->size());
+    return in;
+}
+
+template <typename T>
+InStreams& deserializeParamValue(InStreams& in, T* value) {
+    in.elements.read(reinterpret_cast<char*>(value), sizeof(T));
+    return in;
+}
+
+InStreams& deserialize(TAG_INVALID_t&&, InStreams& in, KeyParameter*) {
+    // there should be no invalid KeyParamaters but if handle them as zero sized.
+    return in;
+}
+
+template <typename T>
+InStreams& deserialize(T&& ttag, InStreams& in, KeyParameter* param) {
+    return deserializeParamValue(in, &accessTagValue(ttag, *param));
+}
+
+template <typename... T>
+struct choose_deserializer;
+template <typename... Tags>
+struct choose_deserializer<MetaList<Tags...>> {
+    static InStreams& deserialize(InStreams& in, KeyParameter* param) {
+        return choose_deserializer<Tags...>::deserialize(in, param);
+    }
+};
+template <>
+struct choose_deserializer<> {
+    static InStreams& deserialize(InStreams& in, KeyParameter*) {
+        // encountered an unknown tag -> fail parsing
+        in.elements.setstate(std::ios_base::badbit);
+        return in;
+    }
+};
+template <TagType tag_type, Tag tag, typename... Tail>
+struct choose_deserializer<TypedTag<tag_type, tag>, Tail...> {
+    static InStreams& deserialize(InStreams& in, KeyParameter* param) {
+        if (param->tag == tag) {
+            return keystore::deserialize(TypedTag<tag_type, tag>(), in, param);
+        } else {
+            return choose_deserializer<Tail...>::deserialize(in, param);
+        }
+    }
+};
+
+InStreams& deserialize(InStreams& in, KeyParameter* param) {
+    in.elements.read(reinterpret_cast<char*>(&param->tag), sizeof(Tag));
+    return choose_deserializer<all_tags_t>::deserialize(in, param);
+}
+
+std::istream& deserialize(std::istream& in, std::vector<KeyParameter>* params) {
+    uint32_t indirect_size = 0;
+    in.read(reinterpret_cast<char*>(&indirect_size), sizeof(uint32_t));
+    std::string indirect_buffer(indirect_size, '\0');
+    if (indirect_buffer.size() != indirect_size) {
+        in.setstate(std::ios_base::badbit);
+        return in;
+    }
+    in.read(&indirect_buffer[0], indirect_buffer.size());
+
+    uint32_t element_count = 0;
+    in.read(reinterpret_cast<char*>(&element_count), sizeof(uint32_t));
+    uint32_t elements_size = 0;
+    in.read(reinterpret_cast<char*>(&elements_size), sizeof(uint32_t));
+
+    std::string elements_buffer(elements_size, '\0');
+    if(elements_buffer.size() != elements_size) {
+        in.setstate(std::ios_base::badbit);
+        return in;
+    }
+    in.read(&elements_buffer[0], elements_buffer.size());
+
+    if (in.bad()) return in;
+
+    // TODO write one-shot stream buffer to avoid copying here
+    std::stringstream indirect(indirect_buffer);
+    std::stringstream elements(elements_buffer);
+    InStreams streams = { indirect, elements };
+
+    params->resize(element_count);
+
+    for (uint32_t i = 0; i < element_count; ++i) {
+        deserialize(streams, &(*params)[i]);
+    }
+    return in;
+}
+void AuthorizationSet::Serialize(std::ostream* out) const {
+    serialize(*out, data_);
+}
+void AuthorizationSet::Deserialize(std::istream* in) {
+    deserialize(*in, &data_);
+}
+
+}  // namespace keystore
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
index 8b08f07..237d896 100644
--- a/keystore/blob.cpp
+++ b/keystore/blob.cpp
@@ -71,12 +71,28 @@
     return mBlob.flags & KEYSTORE_FLAG_ENCRYPTED;
 }
 
+bool Blob::isSuperEncrypted() const {
+    return mBlob.flags & KEYSTORE_FLAG_SUPER_ENCRYPTED;
+}
+
+bool Blob::isCriticalToDeviceEncryption() const {
+    return mBlob.flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION;
+}
+
+inline uint8_t setFlag(uint8_t flags, bool set, KeyStoreFlag flag) {
+    return set ? (flags | flag) : (flags & ~flag);
+}
+
 void Blob::setEncrypted(bool encrypted) {
-    if (encrypted) {
-        mBlob.flags |= KEYSTORE_FLAG_ENCRYPTED;
-    } else {
-        mBlob.flags &= ~KEYSTORE_FLAG_ENCRYPTED;
-    }
+    mBlob.flags = setFlag(mBlob.flags, encrypted, KEYSTORE_FLAG_ENCRYPTED);
+}
+
+void Blob::setSuperEncrypted(bool superEncrypted) {
+    mBlob.flags = setFlag(mBlob.flags, superEncrypted, KEYSTORE_FLAG_SUPER_ENCRYPTED);
+}
+
+void Blob::setCriticalToDeviceEncryption(bool critical) {
+    mBlob.flags = setFlag(mBlob.flags, critical, KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
 }
 
 void Blob::setFallback(bool fallback) {
@@ -90,15 +106,15 @@
 ResponseCode Blob::writeBlob(const char* filename, AES_KEY* aes_key, State state,
                              Entropy* entropy) {
     ALOGV("writing blob %s", filename);
-    if (isEncrypted()) {
+    if (isEncrypted() || isSuperEncrypted()) {
         if (state != STATE_NO_ERROR) {
             ALOGD("couldn't insert encrypted blob while not unlocked");
-            return LOCKED;
+            return ResponseCode::LOCKED;
         }
 
         if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
             ALOGW("Could not read random data for: %s", filename);
-            return SYSTEM_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
     }
 
@@ -115,7 +131,7 @@
 
     mBlob.length = htonl(mBlob.length);
 
-    if (isEncrypted()) {
+    if (isEncrypted() || isSuperEncrypted()) {
         MD5(mBlob.digested, digestedLength, mBlob.digest);
 
         uint8_t vector[AES_BLOCK_SIZE];
@@ -132,60 +148,60 @@
         TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
     if (out < 0) {
         ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno));
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     size_t writtenBytes = writeFully(out, (uint8_t*)&mBlob, fileLength);
     if (close(out) != 0) {
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     if (writtenBytes != fileLength) {
         ALOGW("blob not fully written %zu != %zu", writtenBytes, fileLength);
         unlink(tmpFileName);
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     if (rename(tmpFileName, filename) == -1) {
         ALOGW("could not rename blob to %s: %s", filename, strerror(errno));
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
-    return NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
 ResponseCode Blob::readBlob(const char* filename, AES_KEY* aes_key, State state) {
     ALOGV("reading blob %s", filename);
     int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY));
     if (in < 0) {
-        return (errno == ENOENT) ? KEY_NOT_FOUND : SYSTEM_ERROR;
+        return (errno == ENOENT) ? ResponseCode::KEY_NOT_FOUND : ResponseCode::SYSTEM_ERROR;
     }
     // fileLength may be less than sizeof(mBlob) since the in
     // memory version has extra padding to tolerate rounding up to
     // the AES_BLOCK_SIZE
     size_t fileLength = readFully(in, (uint8_t*)&mBlob, sizeof(mBlob));
     if (close(in) != 0) {
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     if (fileLength == 0) {
-        return VALUE_CORRUPTED;
+        return ResponseCode::VALUE_CORRUPTED;
     }
 
-    if (isEncrypted() && (state != STATE_NO_ERROR)) {
-        return LOCKED;
+    if ((isEncrypted() || isSuperEncrypted()) && (state != STATE_NO_ERROR)) {
+        return ResponseCode::LOCKED;
     }
 
     size_t headerLength = (mBlob.encrypted - (uint8_t*)&mBlob);
     if (fileLength < headerLength) {
-        return VALUE_CORRUPTED;
+        return ResponseCode::VALUE_CORRUPTED;
     }
 
     ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
     if (encryptedLength < 0) {
-        return VALUE_CORRUPTED;
+        return ResponseCode::VALUE_CORRUPTED;
     }
 
     ssize_t digestedLength;
-    if (isEncrypted()) {
+    if (isEncrypted() || isSuperEncrypted()) {
         if (encryptedLength % AES_BLOCK_SIZE != 0) {
-            return VALUE_CORRUPTED;
+            return ResponseCode::VALUE_CORRUPTED;
         }
 
         AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, mBlob.vector,
@@ -194,7 +210,7 @@
         uint8_t computedDigest[MD5_DIGEST_LENGTH];
         MD5(mBlob.digested, digestedLength, computedDigest);
         if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
-            return VALUE_CORRUPTED;
+            return ResponseCode::VALUE_CORRUPTED;
         }
     } else {
         digestedLength = encryptedLength;
@@ -203,11 +219,11 @@
     ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
     mBlob.length = ntohl(mBlob.length);
     if (mBlob.length < 0 || mBlob.length > maxValueLength) {
-        return VALUE_CORRUPTED;
+        return ResponseCode::VALUE_CORRUPTED;
     }
     if (mBlob.info != 0) {
         // move info from after padding to after data
         memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
     }
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
diff --git a/keystore/blob.h b/keystore/blob.h
index d4b5a84..06f9ea5 100644
--- a/keystore/blob.h
+++ b/keystore/blob.h
@@ -95,6 +95,12 @@
     bool isEncrypted() const;
     void setEncrypted(bool encrypted);
 
+    bool isSuperEncrypted() const;
+    void setSuperEncrypted(bool superEncrypted);
+
+    bool isCriticalToDeviceEncryption() const;
+    void setCriticalToDeviceEncryption(bool critical);
+
     bool isFallback() const { return mBlob.flags & KEYSTORE_FLAG_FALLBACK; }
     void setFallback(bool fallback);
 
diff --git a/keystore/defaults.h b/keystore/defaults.h
index 9232dd0..6f7ff2d 100644
--- a/keystore/defaults.h
+++ b/keystore/defaults.h
@@ -24,19 +24,19 @@
  */
 
 /* DSA */
-#define DSA_DEFAULT_KEY_SIZE 1024
-#define DSA_MIN_KEY_SIZE 512
-#define DSA_MAX_KEY_SIZE 8192
+constexpr int32_t DSA_DEFAULT_KEY_SIZE = 1024;
+constexpr int32_t DSA_MIN_KEY_SIZE = 512;
+constexpr int32_t DSA_MAX_KEY_SIZE = 8192;
 
 /* EC */
-#define EC_DEFAULT_KEY_SIZE 256
-#define EC_MIN_KEY_SIZE 192
-#define EC_MAX_KEY_SIZE 521
+constexpr int32_t EC_DEFAULT_KEY_SIZE = 256;
+constexpr int32_t EC_MIN_KEY_SIZE = 192;
+constexpr int32_t EC_MAX_KEY_SIZE = 521;
 
 /* RSA */
-#define RSA_DEFAULT_KEY_SIZE 2048
-#define RSA_DEFAULT_EXPONENT 0x10001
-#define RSA_MIN_KEY_SIZE 512
-#define RSA_MAX_KEY_SIZE 8192
+constexpr int32_t RSA_DEFAULT_KEY_SIZE = 2048;
+constexpr int32_t RSA_DEFAULT_EXPONENT = 0x10001;
+constexpr int32_t RSA_MIN_KEY_SIZE = 512;
+constexpr int32_t RSA_MAX_KEY_SIZE = 8192;
 
 #endif /* KEYSTORE_DEFAULTS_H_ */
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
index 1a2f554..18bd8eb 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -17,23 +17,25 @@
 #ifndef KEYSTORE_IKEYSTORESERVICE_H
 #define KEYSTORE_IKEYSTORESERVICE_H
 
-#include <hardware/keymaster_defs.h>
-#include <utils/RefBase.h>
+#include "keystore.h"
+#include "keystore_return_types.h"
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
+#include <keystore/keymaster_tags.h>
+#include <utils/RefBase.h>
 #include <vector>
 
 namespace android {
 
 class KeystoreArg : public RefBase {
-public:
-    KeystoreArg(const void *data, size_t len);
+  public:
+    KeystoreArg(const void* data, size_t len);
     ~KeystoreArg();
 
     const void* data() const;
     size_t size() const;
 
-private:
+  private:
     const void* mData;
     size_t mSize;
 };
@@ -42,16 +44,6 @@
     void operator()(uint8_t* p) { free(p); }
 };
 
-// struct for serializing/deserializing a list of keymaster_key_param_t's
-struct KeymasterArguments {
-    KeymasterArguments();
-    ~KeymasterArguments();
-    void readFromParcel(const Parcel& in);
-    void writeToParcel(Parcel* out) const;
-
-    std::vector<keymaster_key_param_t> params;
-};
-
 // struct for serializing the results of begin/update/finish
 struct OperationResult : public ::android::Parcelable {
     OperationResult();
@@ -59,13 +51,12 @@
     status_t readFromParcel(const Parcel* in) override;
     status_t writeToParcel(Parcel* out) const override;
 
-    int resultCode;
+    ::keystore::KeyStoreServiceReturnCode resultCode;
     sp<IBinder> token;
-    keymaster_operation_handle_t handle;
+    uint64_t handle;
     int inputConsumed;
-    std::unique_ptr<uint8_t[], MallocDeleter> data;
-    size_t dataLength;
-    KeymasterArguments outParams;
+    ::keystore::hidl_vec<uint8_t> data;
+    ::keystore::hidl_vec<::keystore::KeyParameter> outParams;
 };
 
 // struct for serializing the results of export
@@ -75,41 +66,15 @@
     status_t readFromParcel(const Parcel* in) override;
     status_t writeToParcel(Parcel* out) const override;
 
-    int resultCode;
-    std::unique_ptr<uint8_t[], MallocDeleter> exportData;
-    size_t dataLength;
+    ::keystore::KeyStoreServiceReturnCode resultCode;
+    ::keystore::hidl_vec<uint8_t> exportData;
 };
 
-// struct for serializing keymaster_key_characteristics_t's
-struct KeyCharacteristics : public ::android::Parcelable {
-    KeyCharacteristics();
-    ~KeyCharacteristics();
-    status_t readFromParcel(const Parcel* in) override;
-    status_t writeToParcel(Parcel* out) const override;
-
-    keymaster_key_characteristics_t characteristics;
-};
-
-// struct for serializing keymaster_cert_chain_t's
-struct KeymasterCertificateChain {
-    KeymasterCertificateChain();
-    ~KeymasterCertificateChain();
-    void readFromParcel(const Parcel& in);
-    void writeToParcel(Parcel* out) const;
-
-    void FreeChain();
-
-    keymaster_cert_chain_t chain;
-};
-
-bool readKeymasterArgumentFromParcel(const Parcel& in, keymaster_key_param_t* out);
-void writeKeymasterArgumentToParcel(const keymaster_key_param_t& param, Parcel* out);
-
 /*
  * This must be kept manually in sync with frameworks/base's IKeystoreService.java
  */
-class IKeystoreService: public IInterface {
-public:
+class IKeystoreService : public IInterface {
+  public:
     enum {
         GET_STATE = IBinder::FIRST_CALL_TRANSACTION + 0,
         GET = IBinder::FIRST_CALL_TRANSACTION + 1,
@@ -147,119 +112,144 @@
         ON_USER_ADDED = IBinder::FIRST_CALL_TRANSACTION + 33,
         ON_USER_REMOVED = IBinder::FIRST_CALL_TRANSACTION + 34,
         ATTEST_KEY = IBinder::FIRST_CALL_TRANSACTION + 35,
-        ON_DEVICE_OFF_BODY = IBinder::FIRST_CALL_TRANSACTION + 36,
+        ATTEST_DEVICE_IDS = IBinder::FIRST_CALL_TRANSACTION + 36,
+        ON_DEVICE_OFF_BODY = IBinder::FIRST_CALL_TRANSACTION + 37,
     };
 
     DECLARE_META_INTERFACE(KeystoreService);
 
-    virtual int32_t getState(int32_t userId) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode getState(int32_t userId) = 0;
 
-    virtual int32_t get(const String16& name, int32_t uid, uint8_t** item, size_t* itemLength) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode get(const String16& name, int32_t uid,
+                                                      ::keystore::hidl_vec<uint8_t>* item) = 0;
 
-    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid,
-            int32_t flags) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode insert(const String16& name,
+                                                         const ::keystore::hidl_vec<uint8_t>& item,
+                                                         int uid, int32_t flags) = 0;
 
-    virtual int32_t del(const String16& name, int uid) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode del(const String16& name, int uid) = 0;
 
-    virtual int32_t exist(const String16& name, int uid) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode exist(const String16& name, int uid) = 0;
 
-    virtual int32_t list(const String16& prefix, int uid, Vector<String16>* matches) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode list(const String16& prefix, int uid,
+                                                       Vector<String16>* matches) = 0;
 
-    virtual int32_t reset() = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode reset() = 0;
 
-    virtual int32_t onUserPasswordChanged(int32_t userId, const String16& newPassword) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode
+    onUserPasswordChanged(int32_t userId, const String16& newPassword) = 0;
 
-    virtual int32_t lock(int32_t userId) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode lock(int32_t userId) = 0;
 
-    virtual int32_t unlock(int32_t userId, const String16& password) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode unlock(int32_t userId,
+                                                         const String16& password) = 0;
 
     virtual bool isEmpty(int32_t userId) = 0;
 
-    virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize,
-            int32_t flags, Vector<sp<KeystoreArg> >* args) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode generate(const String16& name, int32_t uid,
+                                                           int32_t keyType, int32_t keySize,
+                                                           int32_t flags,
+                                                           Vector<sp<KeystoreArg>>* args) = 0;
 
-    virtual int32_t import(const String16& name, const uint8_t* data, size_t length, int uid,
-            int32_t flags) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode import(const String16& name,
+                                                         const ::keystore::hidl_vec<uint8_t>& data,
+                                                         int uid, int32_t flags) = 0;
 
-    virtual int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
-            size_t* outLength) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode sign(const String16& name,
+                                                       const ::keystore::hidl_vec<uint8_t>& data,
+                                                       ::keystore::hidl_vec<uint8_t>* out) = 0;
 
-    virtual int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
-            const uint8_t* signature, size_t signatureLength) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode
+    verify(const String16& name, const ::keystore::hidl_vec<uint8_t>& data,
+           const ::keystore::hidl_vec<uint8_t>& signature) = 0;
 
-    virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode
+    get_pubkey(const String16& name, ::keystore::hidl_vec<uint8_t>* pubKey) = 0;
 
-    virtual int32_t grant(const String16& name, int32_t granteeUid) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode grant(const String16& name,
+                                                        int32_t granteeUid) = 0;
 
-    virtual int32_t ungrant(const String16& name, int32_t granteeUid) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode ungrant(const String16& name,
+                                                          int32_t granteeUid) = 0;
 
     virtual int64_t getmtime(const String16& name, int32_t uid) = 0;
 
-    virtual int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
-            int32_t destUid) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode
+    duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey, int32_t destUid) = 0;
 
     virtual int32_t is_hardware_backed(const String16& keyType) = 0;
 
-    virtual int32_t clear_uid(int64_t uid) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode clear_uid(int64_t uid) = 0;
 
-    virtual int32_t addRngEntropy(const uint8_t* data, size_t dataLength) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode
+    addRngEntropy(const ::keystore::hidl_vec<uint8_t>& entropy) = 0;
 
-    virtual int32_t generateKey(const String16& name, const KeymasterArguments& params,
-                                const uint8_t* entropy, size_t entropyLength, int uid, int flags,
-                                KeyCharacteristics* outCharacteristics) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode
+    generateKey(const String16& name, const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
+                const ::keystore::hidl_vec<uint8_t>& entropy, int uid, int flags,
+                ::keystore::KeyCharacteristics* outCharacteristics) = 0;
 
-    virtual int32_t getKeyCharacteristics(const String16& name,
-                                          const keymaster_blob_t* clientId,
-                                          const keymaster_blob_t* appData,
-                                          int32_t uid,
-                                          KeyCharacteristics* outCharacteristics) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode
+    getKeyCharacteristics(const String16& name, const ::keystore::hidl_vec<uint8_t>& clientId,
+                          const ::keystore::hidl_vec<uint8_t>& appData, int32_t uid,
+                          ::keystore::KeyCharacteristics* outCharacteristics) = 0;
 
-    virtual int32_t importKey(const String16& name, const KeymasterArguments&  params,
-                              keymaster_key_format_t format, const uint8_t *keyData,
-                              size_t keyLength, int uid, int flags,
-                              KeyCharacteristics* outCharacteristics) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode
+    importKey(const String16& name, const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
+              ::keystore::KeyFormat format, const ::keystore::hidl_vec<uint8_t>& key, int uid,
+              int flags, ::keystore::KeyCharacteristics* outCharacteristics) = 0;
 
-    virtual void exportKey(const String16& name, keymaster_key_format_t format,
-                           const keymaster_blob_t* clientId,
-                           const keymaster_blob_t* appData, int32_t uid, ExportResult* result) = 0;
+    virtual void exportKey(const String16& name, ::keystore::KeyFormat format,
+                           const ::keystore::hidl_vec<uint8_t>& clientId,
+                           const ::keystore::hidl_vec<uint8_t>& appData, int uid,
+                           ExportResult* result) = 0;
 
     virtual void begin(const sp<IBinder>& apptoken, const String16& name,
-                       keymaster_purpose_t purpose, bool pruneable,
-                       const KeymasterArguments& params, const uint8_t* entropy,
-                       size_t entropyLength, int32_t uid, OperationResult* result) = 0;
+                       ::keystore::KeyPurpose purpose, bool pruneable,
+                       const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
+                       const ::keystore::hidl_vec<uint8_t>& entropy, int32_t uid,
+                       OperationResult* opResult) = 0;
 
-    virtual void update(const sp<IBinder>& token, const KeymasterArguments& params,
-                        const uint8_t* data, size_t dataLength, OperationResult* result) = 0;
+    virtual void update(const sp<IBinder>& token,
+                        const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
+                        const ::keystore::hidl_vec<uint8_t>& data, OperationResult* opResult) = 0;
 
-    virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
-                        const uint8_t* signature, size_t signatureLength,
-                        const uint8_t* entropy, size_t entropyLength,
-                        OperationResult* result) = 0;
+    virtual void finish(const sp<IBinder>& token,
+                        const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
+                        const ::keystore::hidl_vec<uint8_t>& signature,
+                        const ::keystore::hidl_vec<uint8_t>& entropy,
+                        OperationResult* opResult) = 0;
 
-    virtual int32_t abort(const sp<IBinder>& handle) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode abort(const sp<IBinder>& handle) = 0;
 
     virtual bool isOperationAuthorized(const sp<IBinder>& handle) = 0;
 
-    virtual int32_t addAuthToken(const uint8_t* token, size_t length) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode addAuthToken(const uint8_t* token,
+                                                               size_t length) = 0;
 
-    virtual int32_t onUserAdded(int32_t userId, int32_t parentId) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode onUserAdded(int32_t userId, int32_t parentId) = 0;
 
-    virtual int32_t onUserRemoved(int32_t userId) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode onUserRemoved(int32_t userId) = 0;
 
-    virtual int32_t attestKey(const String16& name, const KeymasterArguments& params,
-                              KeymasterCertificateChain* outChain) = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode
+    attestKey(const String16& name, const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
+              ::keystore::hidl_vec<::keystore::hidl_vec<uint8_t>>* outChain) = 0;
 
-    virtual int32_t onDeviceOffBody() = 0;
+    virtual ::keystore::KeyStoreServiceReturnCode attestDeviceIds(
+            const ::keystore::hidl_vec<::keystore::KeyParameter>& params,
+            ::keystore::hidl_vec<::keystore::hidl_vec<uint8_t>>* outChain) = 0;
+
+    virtual ::keystore::KeyStoreServiceReturnCode onDeviceOffBody() = 0;
 };
 
 // ----------------------------------------------------------------------------
 
-class BnKeystoreService: public BnInterface<IKeystoreService> {
-public:
+class BnKeystoreService : public BnInterface<IKeystoreService> {
+  public:
     virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
-            uint32_t flags = 0);
+                                uint32_t flags = 0);
 };
 
-} // namespace android
+}  // namespace android
 
 #endif
diff --git a/keystore/include/keystore/KeyAttestationApplicationId.h b/keystore/include/keystore/KeyAttestationApplicationId.h
new file mode 100644
index 0000000..a7ce210
--- /dev/null
+++ b/keystore/include/keystore/KeyAttestationApplicationId.h
@@ -0,0 +1,51 @@
+// Copyright 2016 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_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
+
+#include "KeyAttestationPackageInfo.h"
+#include "utils.h"
+#include <binder/Parcelable.h>
+#include <memory>
+#include <vector>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+class KeyAttestationApplicationId : public Parcelable {
+  public:
+    typedef SharedNullableIterator<const KeyAttestationPackageInfo, std::vector>
+        ConstKeyAttestationPackageInfoIterator;
+
+    status_t writeToParcel(Parcel*) const override;
+    status_t readFromParcel(const Parcel* parcel) override;
+
+    ConstKeyAttestationPackageInfoIterator pinfos_begin() const {
+        return ConstKeyAttestationPackageInfoIterator(packageInfos_);
+    }
+    ConstKeyAttestationPackageInfoIterator pinfos_end() const {
+        return ConstKeyAttestationPackageInfoIterator();
+    }
+
+  private:
+    std::shared_ptr<std::vector<std::unique_ptr<KeyAttestationPackageInfo>>> packageInfos_;
+};
+
+}  // namespace keymaster
+}  // namespace security
+}  // namsepace android
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONAPPLICATIONID_H_
diff --git a/keystore/include/keystore/KeyAttestationPackageInfo.h b/keystore/include/keystore/KeyAttestationPackageInfo.h
new file mode 100644
index 0000000..b938e83
--- /dev/null
+++ b/keystore/include/keystore/KeyAttestationPackageInfo.h
@@ -0,0 +1,53 @@
+// Copyright 2016 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_INCLUDE_KEYSTORE_KEYATTESTATIONPACKAGEINFO_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONPACKAGEINFO_H_
+
+#include "Signature.h"
+#include "utils.h"
+#include <binder/Parcelable.h>
+#include <memory>
+#include <stdint.h>
+#include <vector>
+
+namespace android {
+namespace security {
+namespace keymaster {
+
+class KeyAttestationPackageInfo : public Parcelable {
+  public:
+    typedef SharedNullableIterator<const content::pm::Signature, std::vector>
+        ConstSignatureIterator;
+
+    status_t writeToParcel(Parcel*) const override;
+    status_t readFromParcel(const Parcel* parcel) override;
+
+    const std::unique_ptr<String16>& package_name() const { return packageName_; }
+    int32_t version_code() const { return versionCode_; }
+
+    ConstSignatureIterator sigs_begin() const { return ConstSignatureIterator(signatures_); }
+    ConstSignatureIterator sigs_end() const { return ConstSignatureIterator(); }
+
+  private:
+    std::unique_ptr<String16> packageName_;
+    int32_t versionCode_;
+    std::shared_ptr<std::vector<std::unique_ptr<content::pm::Signature>>> signatures_;
+};
+
+}  // namespace keymaster
+}  // namespace security
+}  // namespace android
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYATTESTATIONPACKAGEINFO_H_
diff --git a/keystore/include/keystore/Signature.h b/keystore/include/keystore/Signature.h
new file mode 100644
index 0000000..59b77bf
--- /dev/null
+++ b/keystore/include/keystore/Signature.h
@@ -0,0 +1,43 @@
+// Copyright 2016 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_INCLUDE_KEYSTORE_SIGNATURE_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_SIGNATURE_H_
+
+#include <binder/Parcelable.h>
+#include <stdint.h>
+#include <vector>
+
+namespace android {
+namespace content {
+namespace pm {
+
+class Signature : public Parcelable {
+  public:
+    status_t writeToParcel(Parcel*) const override;
+    status_t readFromParcel(const Parcel* parcel) override;
+
+    const std::vector<uint8_t>& data() const & { return sig_data_; }
+    std::vector<uint8_t>& data() & { return sig_data_; }
+    std::vector<uint8_t>&& data() && { return std::move(sig_data_); }
+
+  private:
+    std::vector<uint8_t> sig_data_;
+};
+
+}  // namespace pm
+}  // namespace content
+}  // namespace android
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_SIGNATURE_H_
diff --git a/keystore/include/keystore/authorization_set.h b/keystore/include/keystore/authorization_set.h
new file mode 100644
index 0000000..0e57a19
--- /dev/null
+++ b/keystore/include/keystore/authorization_set.h
@@ -0,0 +1,336 @@
+/*
+ * Copyright 2014 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 SYSTEM_SECURITY_KEYSTORE_AUTHORIZATION_SET_H_
+#define SYSTEM_SECURITY_KEYSTORE_AUTHORIZATION_SET_H_
+
+#include "keymaster_tags.h"
+#include <vector>
+
+namespace keystore {
+
+class AuthorizationSetBuilder;
+
+/**
+ * An ordered collection of KeyParameters. It provides memory ownership and some convenient
+ * functionality for sorting, deduplicating, joining, and subtracting sets of KeyParameters.
+ * For serialization, wrap the backing store of this structure in a hidl_vec<KeyParameter>.
+ */
+class AuthorizationSet {
+  public:
+    /**
+     * Construct an empty, dynamically-allocated, growable AuthorizationSet.
+     */
+    AuthorizationSet() {};
+
+    // Copy constructor.
+    AuthorizationSet(const AuthorizationSet& other) : data_(other.data_) {}
+
+    // Move constructor.
+    AuthorizationSet(AuthorizationSet&& other) : data_(std::move(other.data_)) {}
+
+    // Constructor from hidl_vec<KeyParameter>
+    AuthorizationSet(const hidl_vec<KeyParameter>& other) {
+        *this = other;
+    }
+
+    // Copy assignment.
+    AuthorizationSet& operator=(const AuthorizationSet& other) {
+        data_ = other.data_;
+        return *this;
+    }
+
+    // Move assignment.
+    AuthorizationSet& operator=(AuthorizationSet&& other) {
+        data_ = std::move(other.data_);
+        return *this;
+    }
+
+    AuthorizationSet& operator=(const hidl_vec<KeyParameter>& other) {
+        if (other.size() > 0) {
+            data_.resize(other.size());
+            for (size_t i = 0; i < data_.size(); ++i) {
+                /* This makes a deep copy even of embedded blobs.
+                 * See assignment operator/copy constructor of hidl_vec.*/
+                data_[i] = other[i];
+            }
+        }
+        return *this;
+    }
+
+    /**
+     * Clear existing authorization set data
+     */
+    void Clear();
+
+    ~AuthorizationSet() = default;
+
+    /**
+     * Returns the size of the set.
+     */
+    size_t size() const { return data_.size(); }
+
+    /**
+     * Returns true if the set is empty.
+     */
+    bool empty() const { return size() == 0; }
+
+    /**
+     * Returns the data in the set, directly. Be careful with this.
+     */
+    const KeyParameter* data() const { return data_.data(); }
+
+    /**
+     * Sorts the set
+     */
+    void Sort();
+
+    /**
+     * Sorts the set and removes duplicates (inadvertently duplicating tags is easy to do with the
+     * AuthorizationSetBuilder).
+     */
+    void Deduplicate();
+
+    /**
+     * Adds all elements from \p set that are not already present in this AuthorizationSet.  As a
+     * side-effect, if \p set is not null this AuthorizationSet will end up sorted.
+     */
+    void Union(const AuthorizationSet& set);
+
+    /**
+     * Removes all elements in \p set from this AuthorizationSet.
+     */
+    void Subtract(const AuthorizationSet& set);
+
+    /**
+     * Returns the offset of the next entry that matches \p tag, starting from the element after \p
+     * begin.  If not found, returns -1.
+     */
+    int find(Tag tag, int begin = -1) const;
+
+    /**
+     * Removes the entry at the specified index. Returns true if successful, false if the index was
+     * out of bounds.
+     */
+    bool erase(int index);
+
+    /**
+     * Returns iterator (pointer) to beginning of elems array, to enable STL-style iteration
+     */
+    std::vector<KeyParameter>::const_iterator begin() const { return data_.begin(); }
+
+    /**
+     * Returns iterator (pointer) one past end of elems array, to enable STL-style iteration
+     */
+    std::vector<KeyParameter>::const_iterator end() const { return data_.end(); }
+
+    /**
+     * Returns the nth element of the set.
+     * Like for std::vector::operator[] there is no range check performed. Use of out of range
+     * indices is undefined.
+     */
+    KeyParameter& operator[](int n);
+
+    /**
+     * Returns the nth element of the set.
+     * Like for std::vector::operator[] there is no range check performed. Use of out of range
+     * indices is undefined.
+     */
+    const KeyParameter& operator[](int n) const;
+
+    /**
+     * Returns true if the set contains at least one instance of \p tag
+     */
+    bool Contains(Tag tag) const {
+        return find(tag) != -1;
+    }
+
+    template <TagType tag_type, Tag tag, typename ValueT>
+    bool Contains(TypedTag<tag_type, tag> ttag, const ValueT& value) const {
+        for (const auto& param: data_) {
+            auto entry = authorizationValue(ttag, param);
+            if (entry.isOk() && entry.value() == value) return true;
+        }
+        return false;
+    }
+    /**
+     * Returns the number of \p tag entries.
+     */
+    size_t GetTagCount(Tag tag) const;
+
+    template <typename T>
+    inline NullOr<const typename TypedTag2ValueType<T>::type&> GetTagValue(T tag) const {
+        auto entry = GetEntry(tag);
+        if (entry.isOk()) return authorizationValue(tag, entry.value());
+        return {};
+    }
+
+    void push_back(const KeyParameter& param) {
+        data_.push_back(param);
+    }
+    void push_back(KeyParameter&& param) {
+        data_.push_back(std::move(param));
+    }
+
+    /**
+     * Append the tag and enumerated value to the set.
+     * "val" may be exactly one parameter unless a boolean parameter is added.
+     * In this case "val" is omitted. This condition is checked at compile time by Authorization()
+     */
+    template <typename TypedTagT, typename... Value>
+    void push_back(TypedTagT tag, Value&&... val) {
+        push_back(Authorization(tag, std::forward<Value>(val)...));
+    }
+
+    template <typename Iterator>
+    void append(Iterator begin, Iterator end) {
+        while (begin != end) {
+            push_back(*begin);
+            ++begin;
+        }
+    }
+
+    hidl_vec<KeyParameter> hidl_data() const {
+        hidl_vec<KeyParameter> result;
+        result.setToExternal(const_cast<KeyParameter*>(data()), size());
+        return result;
+    }
+
+    void Serialize(std::ostream* out) const;
+    void Deserialize(std::istream* in);
+
+  private:
+    NullOr<const KeyParameter&> GetEntry(Tag tag) const;
+
+    std::vector<KeyParameter> data_;
+};
+
+class AuthorizationSetBuilder: public AuthorizationSet {
+  public:
+    template <typename TagType, typename... ValueType>
+    AuthorizationSetBuilder& Authorization(TagType ttag, ValueType&&... value) {
+        push_back(ttag, std::forward<ValueType>(value)...);
+        return *this;
+    }
+
+    template <Tag tag>
+    AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data,
+                                           size_t data_length) {
+        hidl_vec<uint8_t> new_blob;
+        new_blob.setToExternal(const_cast<uint8_t*>(data), data_length);
+        push_back(ttag, std::move(new_blob));
+        return *this;
+    }
+
+    template <Tag tag>
+    AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const char* data,
+                                           size_t data_length) {
+        return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length);
+    }
+
+    AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent);
+    AuthorizationSetBuilder& EcdsaKey(uint32_t key_size);
+    AuthorizationSetBuilder& AesKey(uint32_t key_size);
+    AuthorizationSetBuilder& HmacKey(uint32_t key_size);
+
+    AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent);
+    AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent);
+    AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size);
+    AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size);
+
+    AuthorizationSetBuilder& SigningKey();
+    AuthorizationSetBuilder& EncryptionKey();
+    AuthorizationSetBuilder& NoDigestOrPadding();
+    AuthorizationSetBuilder& EcbMode();
+
+    AuthorizationSetBuilder& Digest(Digest digest) {
+        return Authorization(TAG_DIGEST, digest);
+    }
+
+    AuthorizationSetBuilder& Padding(PaddingMode padding) {
+        return Authorization(TAG_PADDING, padding);
+    }
+};
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
+                                                                uint64_t public_exponent) {
+    Authorization(TAG_ALGORITHM, Algorithm::RSA);
+    Authorization(TAG_KEY_SIZE, key_size);
+    Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
+    return *this;
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) {
+    Authorization(TAG_ALGORITHM, Algorithm::EC);
+    Authorization(TAG_KEY_SIZE, key_size);
+    return *this;
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
+    Authorization(TAG_ALGORITHM, Algorithm::AES);
+    return Authorization(TAG_KEY_SIZE, key_size);
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) {
+    Authorization(TAG_ALGORITHM, Algorithm::HMAC);
+    Authorization(TAG_KEY_SIZE, key_size);
+    return SigningKey();
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
+                                                                       uint64_t public_exponent) {
+    RsaKey(key_size, public_exponent);
+    return SigningKey();
+}
+
+inline AuthorizationSetBuilder&
+AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent) {
+    RsaKey(key_size, public_exponent);
+    return EncryptionKey();
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
+    EcdsaKey(key_size);
+    return SigningKey();
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
+    AesKey(key_size);
+    return EncryptionKey();
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
+    Authorization(TAG_PURPOSE, KeyPurpose::SIGN);
+    return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY);
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
+    Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT);
+    return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT);
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
+    Authorization(TAG_DIGEST, Digest::NONE);
+    return Authorization(TAG_PADDING, PaddingMode::NONE);
+}
+
+inline AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
+    return Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
+}
+
+}  // namespace keystore
+
+#endif  // SYSTEM_SECURITY_KEYSTORE_AUTHORIZATION_SET_H_
diff --git a/keystore/include/keystore/keymaster_tags.h b/keystore/include/keystore/keymaster_tags.h
new file mode 100644
index 0000000..05a33cd
--- /dev/null
+++ b/keystore/include/keystore/keymaster_tags.h
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2014 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 SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_
+#define SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_
+
+/**
+ * This header contains various definitions that make working with keymaster tags safer and easier.
+ *
+ * It makes use of a fair amount of template metaprogramming. The metaprogramming serves the purpose
+ * of making it impossible to make certain classes of mistakes when operating on keymaster
+ * authorizations.  For example, it's an error to create a KeyParameter with tag == Tag::PURPOSE
+ * and then to assign Algorithm::RSA to algorithm element of its union. But because the user
+ * must choose the union field, there could be a mismatch which the compiler has now way to
+ * diagnose.
+ *
+ * The machinery in this header solves these problems by describing which union field corresponds
+ * to which Tag. Central to this mechanism is the template TypedTag. It has zero size and binds a
+ * numeric Tag to a type that the compiler understands. By means of the macro DECLARE_TYPED_TAG,
+ * we declare types for each of the tags defined in hardware/interfaces/keymaster/2.0/types.hal.
+ *
+ * The macro DECLARE_TYPED_TAG(name) generates a typename TAG_name_t and a zero sized instance
+ * TAG_name. Once these typed tags have been declared we define metafunctions mapping the each tag
+ * to its value c++ type and the correct union element of KeyParameter. This is done by means of
+ * the macros MAKE_TAG_*VALUE_ACCESSOR, which generates TypedTag2ValueType, a metafunction mapping
+ * a typed tag to the corresponding c++ type, and access function, accessTagValue returning a
+ * reference to the correct element of KeyParameter.
+ * E.g.:
+ *      given "KeyParameter param;" then "accessTagValue(TAG_PURPOSE, param)"
+ *      yields a reference to param.f.purpose
+ * If used in an assignment the compiler can now check the compatibility of the assigned value.
+ *
+ * For convenience we also provide the constructor like function Authorization().
+ * Authorization takes a typed tag and a value and checks at compile time whether the value given
+ * is suitable for the given tag. At runtime it creates a new KeyParameter initialized with the
+ * given tag and value and returns it by value.
+ *
+ * The second convenience function, authorizationValue, allows access to the KeyParameter value in
+ * a safe way. It takes a typed tag and a KeyParameter and returns a reference to the value wrapped
+ * by NullOr. NullOr has out-of-band information about whether it is save to access the wrapped
+ * reference.
+ * E.g.:
+ *      auto param = Authorization(TAG_ALGORITM, Algorithm::RSA);
+ *      auto value1 = authorizationValue(TAG_PURPOSE, param);
+ *      auto value2 = authorizationValue(TAG_ALGORITM, param);
+ * value1.isOk() yields false, but value2.isOk() yields true, thus value2.value() is save to access.
+ */
+
+#include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
+#include <hardware/hw_auth_token.h>
+#include <type_traits>
+
+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;
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+
+// The following create the numeric values that KM_TAG_PADDING and KM_TAG_DIGEST used to have.  We
+// need these old values to be able to support old keys that use them.
+static const int32_t KM_TAG_DIGEST_OLD = static_cast<int32_t>(TagType::ENUM) | 5;
+static const int32_t KM_TAG_PADDING_OLD = static_cast<int32_t>(TagType::ENUM) | 7;
+
+constexpr TagType typeFromTag(Tag tag) {
+    return static_cast<TagType>(static_cast<uint32_t>(tag) & static_cast<uint32_t>(0xf0000000));
+}
+
+/**
+ * TypedTag is a templatized version of Tag, which provides compile-time checking of
+ * keymaster tag types. Instances are convertible to Tag, so they can be used wherever
+ * Tag is expected, and because they encode the tag type it's possible to create
+ * function overloads that only operate on tags with a particular type.
+ */
+template <TagType tag_type, Tag tag> struct TypedTag {
+    inline TypedTag() {
+        // Ensure that it's impossible to create a TypedTag instance whose 'tag' doesn't have type
+        // 'tag_type'.  Attempting to instantiate a tag with the wrong type will result in a compile
+        // error (no match for template specialization StaticAssert<false>), with no run-time cost.
+        static_assert(typeFromTag(tag) == tag_type, "mismatch between tag and tag_type");
+    }
+    operator Tag() const { return tag; }
+};
+
+template <Tag tag> struct Tag2TypedTag { typedef TypedTag<typeFromTag(tag), tag> type; };
+
+template <Tag tag> struct Tag2String;
+
+#define _TAGS_STRINGIFY(x) #x
+#define TAGS_STRINGIFY(x) _TAGS_STRINGIFY(x)
+
+#define DECLARE_TYPED_TAG(name)                                                                    \
+    typedef typename Tag2TypedTag<Tag::name>::type TAG_##name##_t;                                 \
+    extern TAG_##name##_t TAG_##name;                                                              \
+    template <> struct Tag2String<Tag::name> {                                                     \
+        static const char* value() { return "Tag::" TAGS_STRINGIFY(name); }                        \
+    }
+
+DECLARE_TYPED_TAG(INVALID);
+DECLARE_TYPED_TAG(KEY_SIZE);
+DECLARE_TYPED_TAG(MAC_LENGTH);
+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(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);
+DECLARE_TYPED_TAG(UNIQUE_ID);
+DECLARE_TYPED_TAG(ATTESTATION_CHALLENGE);
+DECLARE_TYPED_TAG(ATTESTATION_APPLICATION_ID);
+DECLARE_TYPED_TAG(RESET_SINCE_ID_ROTATION);
+
+DECLARE_TYPED_TAG(PURPOSE);
+DECLARE_TYPED_TAG(ALGORITHM);
+DECLARE_TYPED_TAG(BLOCK_MODE);
+DECLARE_TYPED_TAG(DIGEST);
+DECLARE_TYPED_TAG(PADDING);
+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_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>;
+
+/* implementation in keystore_utils.cpp */
+extern const char* stringifyTag(Tag tag);
+
+template <typename TypedTagType> struct TypedTag2ValueType;
+
+#define MAKE_TAG_VALUE_ACCESSOR(tag_type, field_name)                                              \
+    template <Tag tag> struct TypedTag2ValueType<TypedTag<tag_type, tag>> {                        \
+        typedef decltype(static_cast<KeyParameter*>(nullptr)->field_name) type;                    \
+    };                                                                                             \
+    template <Tag tag>                                                                             \
+    inline auto accessTagValue(TypedTag<tag_type, tag>, const KeyParameter& param)                 \
+        ->const decltype(param.field_name)& {                                                      \
+        return param.field_name;                                                                   \
+    }                                                                                              \
+    template <Tag tag>                                                                             \
+    inline auto accessTagValue(TypedTag<tag_type, tag>, KeyParameter& param)                       \
+        ->decltype(param.field_name)& {                                                            \
+        return param.field_name;                                                                   \
+    }
+
+MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG, f.longInteger)
+MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG_REP, f.longInteger)
+MAKE_TAG_VALUE_ACCESSOR(TagType::DATE, f.dateTime)
+MAKE_TAG_VALUE_ACCESSOR(TagType::UINT, f.integer)
+MAKE_TAG_VALUE_ACCESSOR(TagType::UINT_REP, f.integer)
+MAKE_TAG_VALUE_ACCESSOR(TagType::BOOL, f.boolValue)
+MAKE_TAG_VALUE_ACCESSOR(TagType::BYTES, blob)
+MAKE_TAG_VALUE_ACCESSOR(TagType::BIGNUM, blob)
+
+#define MAKE_TAG_ENUM_VALUE_ACCESSOR(typed_tag, field_name)                                        \
+    template <> struct TypedTag2ValueType<decltype(typed_tag)> {                                   \
+        typedef decltype(static_cast<KeyParameter*>(nullptr)->field_name) type;                    \
+    };                                                                                             \
+    inline auto accessTagValue(decltype(typed_tag), const KeyParameter& param)                     \
+        ->const decltype(param.field_name)& {                                                      \
+        return param.field_name;                                                                   \
+    }                                                                                              \
+    inline auto accessTagValue(decltype(typed_tag), KeyParameter& param)                           \
+        ->decltype(param.field_name)& {                                                            \
+        return param.field_name;                                                                   \
+    }
+
+MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ALGORITHM, f.algorithm)
+MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_BLOB_USAGE_REQUIREMENTS, f.keyBlobUsageRequirements)
+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)
+MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_USER_AUTH_TYPE, f.hardwareAuthenticatorType)
+
+template <TagType tag_type, Tag tag, typename ValueT>
+inline KeyParameter makeKeyParameter(TypedTag<tag_type, tag> ttag, ValueT&& value) {
+    KeyParameter param;
+    param.tag = tag;
+    param.f.longInteger = 0;
+    accessTagValue(ttag, param) = std::forward<ValueT>(value);
+    return param;
+}
+
+// the boolean case
+template <Tag tag> inline KeyParameter makeKeyParameter(TypedTag<TagType::BOOL, tag>) {
+    KeyParameter param;
+    param.tag = tag;
+    param.f.boolValue = true;
+    return param;
+}
+
+template <typename... Pack> struct FirstOrNoneHelper;
+template <typename First> struct FirstOrNoneHelper<First> { typedef First type; };
+template <> struct FirstOrNoneHelper<> {
+    struct type {};
+};
+
+template <typename... Pack> using FirstOrNone = typename FirstOrNoneHelper<Pack...>::type;
+
+template <TagType tag_type, Tag tag, typename... Args>
+inline KeyParameter Authorization(TypedTag<tag_type, tag> ttag, Args&&... args) {
+    static_assert(tag_type != TagType::BOOL || (sizeof...(args) == 0),
+                  "TagType::BOOL Authorizations do not take parameters. Presence is truth.");
+    static_assert(tag_type == TagType::BOOL || (sizeof...(args) == 1),
+                  "Authorization other then TagType::BOOL take exactly one parameter.");
+    static_assert(
+        tag_type == TagType::BOOL ||
+            std::is_convertible<std::remove_cv_t<std::remove_reference_t<FirstOrNone<Args...>>>,
+                                typename TypedTag2ValueType<TypedTag<tag_type, tag>>::type>::value,
+        "Invalid argument type for given tag.");
+
+    return makeKeyParameter(ttag, std::forward<Args>(args)...);
+}
+
+/**
+ * This class wraps a (mostly return) value and stores whether or not the wrapped value is valid out
+ * of band. Note that if the wrapped value is a reference it is unsafe to access the value if
+ * !isOk(). If the wrapped type is a pointer or value and !isOk(), it is still safe to access the
+ * wrapped value. In this case the pointer will be NULL though, and the value will be default
+ * constructed.
+ */
+template <typename ValueT> class NullOr {
+    template <typename T> struct reference_initializer {
+        static T&& init() { return *static_cast<std::remove_reference_t<T>*>(nullptr); }
+    };
+    template <typename T> struct pointer_initializer {
+        static T init() { return nullptr; }
+    };
+    template <typename T> struct value_initializer {
+        static T init() { return T(); }
+    };
+    template <typename T>
+    using initializer_t =
+        std::conditional_t<std::is_lvalue_reference<T>::value, reference_initializer<T>,
+                           std::conditional_t<std::is_pointer<T>::value, pointer_initializer<T>,
+                                              value_initializer<T>>>;
+
+  public:
+    NullOr() : value_(initializer_t<ValueT>::init()), null_(true) {}
+    NullOr(ValueT&& value) : value_(std::forward<ValueT>(value)), null_(false) {}
+
+    bool isOk() const { return !null_; }
+
+    const ValueT& value() const & { return value_; }
+    ValueT& value() & { return value_; }
+    ValueT&& value() && { return std::move(value_); }
+
+  private:
+    ValueT value_;
+    bool null_;
+};
+
+template <typename T> std::remove_reference_t<T> NullOrOr(T&& v) {
+    if (v.isOk()) return v;
+    return {};
+}
+
+template <typename Head, typename... Tail>
+std::remove_reference_t<Head> NullOrOr(Head&& head, Tail&&... tail) {
+    if (head.isOk()) return head;
+    return NullOrOr(std::forward<Tail>(tail)...);
+}
+
+template <typename Default, typename Wrapped>
+std::remove_reference_t<Wrapped> defaultOr(NullOr<Wrapped>&& optional, Default&& def) {
+    static_assert(std::is_convertible<std::remove_reference_t<Default>,
+                                      std::remove_reference_t<Wrapped>>::value,
+                  "Type of default value must match the type wrapped by NullOr");
+    if (optional.isOk()) return optional.value();
+    return def;
+}
+
+template <TagType tag_type, Tag tag>
+inline NullOr<const typename TypedTag2ValueType<TypedTag<tag_type, tag>>::type&>
+authorizationValue(TypedTag<tag_type, tag> ttag, const KeyParameter& param) {
+    if (tag != param.tag) return {};
+    return accessTagValue(ttag, param);
+}
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_SECURITY_KEYSTORE_KEYMASTER_TAGS_H_
diff --git a/keystore/include/keystore/keystore.h b/keystore/include/keystore/keystore.h
index dcb6032..7260363 100644
--- a/keystore/include/keystore/keystore.h
+++ b/keystore/include/keystore/keystore.h
@@ -26,7 +26,7 @@
     STATE_UNINITIALIZED = 3,
 };
 
-enum ResponseCode {
+enum class ResponseCode: int32_t {
     NO_ERROR          =  STATE_NO_ERROR, // 1
     LOCKED            =  STATE_LOCKED, // 2
     UNINITIALIZED     =  STATE_UNINITIALIZED, // 3
@@ -47,10 +47,21 @@
 /*
  * All the flags for import and insert calls.
  */
-enum {
+enum KeyStoreFlag : uint8_t {
     KEYSTORE_FLAG_NONE = 0,
     KEYSTORE_FLAG_ENCRYPTED = 1 << 0,
     KEYSTORE_FLAG_FALLBACK = 1 << 1,
+    // KEYSTORE_FLAG_SUPER_ENCRYPTED is for blobs that are already encrypted by keymaster but have
+    // an additional layer of password-based encryption applied.  The same encryption scheme is used
+    // as KEYSTORE_FLAG_ENCRYPTED, but it's safe to remove super-encryption when the password is
+    // cleared, rather than deleting blobs, and the error returned when attempting to use a
+    // super-encrypted blob while keystore is locked is different.
+    KEYSTORE_FLAG_SUPER_ENCRYPTED = 1 << 2,
+    // KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION is for blobs that are part of device encryption
+    // flow so it receives special treatment from keystore. For example this blob will not be super
+    // encrypted, and it will be stored separately under an unique UID instead. This flag should
+    // only be available to system uid.
+    KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION = 1 << 3,
 };
 
 /**
diff --git a/keystore/include/keystore/keystore_client.h b/keystore/include/keystore/keystore_client.h
index cec29f7..2ba7fd4 100644
--- a/keystore/include/keystore/keystore_client.h
+++ b/keystore/include/keystore/keystore_client.h
@@ -19,16 +19,21 @@
 #include <string>
 #include <vector>
 
-#include "hardware/keymaster_defs.h"
-#include "keymaster/authorization_set.h"
+#include <android-base/macros.h>
+
+#include "authorization_set.h"
+#include "keystore.h"
+#include "keystore_return_types.h"
 
 namespace keystore {
 
+
+
 // An abstract class providing a convenient interface to keystore services. This
 // interface is designed to:
 //   - hide details of the IPC mechanism (e.g. binder)
 //   - use std data types
-//   - encourage the use of keymaster::AuthorizationSet[Builder]
+//   - encourage the use of keystore::AuthorizationSet[Builder]
 //   - be convenient for native services integrating with keystore
 //   - be safely mocked for unit testing (e.g. pure virtual methods)
 //
@@ -73,79 +78,79 @@
     // BeginOperation. The |input_data| is as in UpdateOperation. The
     // |signature_to_verify| and |output_data| are as in FinishOperation. On
     // success returns true.
-    virtual bool oneShotOperation(keymaster_purpose_t purpose, const std::string& key_name,
-                                  const keymaster::AuthorizationSet& input_parameters,
+    virtual bool oneShotOperation(KeyPurpose purpose, const std::string& key_name,
+                                  const keystore::AuthorizationSet& input_parameters,
                                   const std::string& input_data,
                                   const std::string& signature_to_verify,
-                                  keymaster::AuthorizationSet* output_parameters,
+                                  keystore::AuthorizationSet* output_parameters,
                                   std::string* output_data) = 0;
 
     // Adds |entropy| to the random number generator. Returns KM_ERROR_OK on
     // success and a Keystore ResponseCode or keymaster_error_t on failure.
-    virtual int32_t addRandomNumberGeneratorEntropy(const std::string& entropy) = 0;
+    virtual KeyStoreNativeReturnCode addRandomNumberGeneratorEntropy(const std::string& entropy) = 0;
 
     // Generates a key according to the given |key_parameters| and stores it with
     // the given |key_name|. The [hardware|software]_enforced_characteristics of
     // the key are provided on success. Returns KM_ERROR_OK on success. Returns
     // KM_ERROR_OK on success and a Keystore ResponseCode or keymaster_error_t on
     // failure.
-    virtual int32_t generateKey(const std::string& key_name,
-                                const keymaster::AuthorizationSet& key_parameters,
-                                keymaster::AuthorizationSet* hardware_enforced_characteristics,
-                                keymaster::AuthorizationSet* software_enforced_characteristics) = 0;
+    virtual KeyStoreNativeReturnCode generateKey(const std::string& key_name,
+                                const keystore::AuthorizationSet& key_parameters,
+                                keystore::AuthorizationSet* hardware_enforced_characteristics,
+                                keystore::AuthorizationSet* software_enforced_characteristics) = 0;
 
     // Provides the [hardware|software]_enforced_characteristics of a key
     // identified by |key_name|. Returns KM_ERROR_OK on success and a Keystore
     // ResponseCode or keymaster_error_t on failure.
-    virtual int32_t
+    virtual KeyStoreNativeReturnCode
     getKeyCharacteristics(const std::string& key_name,
-                          keymaster::AuthorizationSet* hardware_enforced_characteristics,
-                          keymaster::AuthorizationSet* software_enforced_characteristics) = 0;
+                          keystore::AuthorizationSet* hardware_enforced_characteristics,
+                          keystore::AuthorizationSet* software_enforced_characteristics) = 0;
 
     // Imports |key_data| in the given |key_format|, applies the given
     // |key_parameters|, and stores it with the given |key_name|. The
     // [hardware|software]_enforced_characteristics of the key are provided on
     // success. Returns KM_ERROR_OK on success and a Keystore ResponseCode or
     // keymaster_error_t on failure.
-    virtual int32_t importKey(const std::string& key_name,
-                              const keymaster::AuthorizationSet& key_parameters,
-                              keymaster_key_format_t key_format, const std::string& key_data,
-                              keymaster::AuthorizationSet* hardware_enforced_characteristics,
-                              keymaster::AuthorizationSet* software_enforced_characteristics) = 0;
+    virtual KeyStoreNativeReturnCode importKey(const std::string& key_name,
+                              const keystore::AuthorizationSet& key_parameters,
+                              KeyFormat key_format, const std::string& key_data,
+                              keystore::AuthorizationSet* hardware_enforced_characteristics,
+                              keystore::AuthorizationSet* software_enforced_characteristics) = 0;
 
     // Exports the public key identified by |key_name| to |export_data| using
     // |export_format|. Returns KM_ERROR_OK on success and a Keystore ResponseCode
     // or keymaster_error_t on failure.
-    virtual int32_t exportKey(keymaster_key_format_t export_format, const std::string& key_name,
+    virtual KeyStoreNativeReturnCode exportKey(KeyFormat export_format, const std::string& key_name,
                               std::string* export_data) = 0;
 
     // Deletes the key identified by |key_name|. Returns KM_ERROR_OK on success
     // and a Keystore ResponseCode or keymaster_error_t on failure.
-    virtual int32_t deleteKey(const std::string& key_name) = 0;
+    virtual KeyStoreNativeReturnCode deleteKey(const std::string& key_name) = 0;
 
     // Deletes all keys owned by the caller. Returns KM_ERROR_OK on success and a
     // Keystore ResponseCode or keymaster_error_t on failure.
-    virtual int32_t deleteAllKeys() = 0;
+    virtual KeyStoreNativeReturnCode deleteAllKeys() = 0;
 
     // Begins a cryptographic operation (e.g. encrypt, sign) identified by
     // |purpose| using the key identified by |key_name| and the given
     // |input_parameters|. On success, any |output_parameters| and an operation
     // |handle| are populated. Returns KM_ERROR_OK on success and a Keystore
     // ResponseCode or keymaster_error_t on failure.
-    virtual int32_t beginOperation(keymaster_purpose_t purpose, const std::string& key_name,
-                                   const keymaster::AuthorizationSet& input_parameters,
-                                   keymaster::AuthorizationSet* output_parameters,
-                                   keymaster_operation_handle_t* handle) = 0;
+    virtual KeyStoreNativeReturnCode beginOperation(KeyPurpose purpose, const std::string& key_name,
+                                   const keystore::AuthorizationSet& input_parameters,
+                                   keystore::AuthorizationSet* output_parameters,
+                                   uint64_t* handle) = 0;
 
     // Continues the operation associated with |handle| using the given
     // |input_parameters| and |input_data|. On success, the
     // |num_input_bytes_consumed| and any |output_parameters| are populated. Any
     // |output_data| will be appended. Returns KM_ERROR_OK on success and a
     // Keystore ResponseCode or keymaster_error_t on failure.
-    virtual int32_t updateOperation(keymaster_operation_handle_t handle,
-                                    const keymaster::AuthorizationSet& input_parameters,
+    virtual KeyStoreNativeReturnCode updateOperation(uint64_t handle,
+                                    const keystore::AuthorizationSet& input_parameters,
                                     const std::string& input_data, size_t* num_input_bytes_consumed,
-                                    keymaster::AuthorizationSet* output_parameters,
+                                    keystore::AuthorizationSet* output_parameters,
                                     std::string* output_data) = 0;
 
     // Finishes the operation associated with |handle| using the given
@@ -153,15 +158,15 @@
     // any |output_parameters| are populated and |output_data| is appended.
     // Returns KM_ERROR_OK on success and a Keystore ResponseCode or
     // keymaster_error_t on failure.
-    virtual int32_t finishOperation(keymaster_operation_handle_t handle,
-                                    const keymaster::AuthorizationSet& input_parameters,
+    virtual KeyStoreNativeReturnCode finishOperation(uint64_t handle,
+                                    const keystore::AuthorizationSet& input_parameters,
                                     const std::string& signature_to_verify,
-                                    keymaster::AuthorizationSet* output_parameters,
+                                    keystore::AuthorizationSet* output_parameters,
                                     std::string* output_data) = 0;
 
     // Aborts the operation associated with |handle|. Returns KM_ERROR_OK on
     // success and a Keystore ResponseCode or keymaster_error_t on failure.
-    virtual int32_t abortOperation(keymaster_operation_handle_t handle) = 0;
+    virtual KeyStoreNativeReturnCode abortOperation(uint64_t handle) = 0;
 
     // Returns true if a key identified by |key_name| exists in the caller's
     // key store. Returns false if an error occurs.
diff --git a/keystore/include/keystore/keystore_client_impl.h b/keystore/include/keystore/keystore_client_impl.h
index 21f68f9..eb02275 100644
--- a/keystore/include/keystore/keystore_client_impl.h
+++ b/keystore/include/keystore/keystore_client_impl.h
@@ -15,16 +15,16 @@
 #ifndef KEYSTORE_KEYSTORE_CLIENT_IMPL_H_
 #define KEYSTORE_KEYSTORE_CLIENT_IMPL_H_
 
-#include "keystore/keystore_client.h"
+#include "keystore_client.h"
 
 #include <string>
 #include <map>
 #include <vector>
 
-#include "binder/IBinder.h"
-#include "binder/IServiceManager.h"
-#include "keystore/IKeystoreService.h"
-#include "utils/StrongPointer.h"
+#include <binder/IBinder.h>
+#include <binder/IServiceManager.h>
+#include "IKeystoreService.h"
+#include <utils/StrongPointer.h>
 
 namespace keystore {
 
@@ -38,54 +38,54 @@
                                    std::string* encrypted_data) override;
     bool decryptWithAuthentication(const std::string& key_name, const std::string& encrypted_data,
                                    std::string* data) override;
-    bool oneShotOperation(keymaster_purpose_t purpose, const std::string& key_name,
-                          const keymaster::AuthorizationSet& input_parameters,
+    bool oneShotOperation(KeyPurpose purpose, const std::string& key_name,
+                          const keystore::AuthorizationSet& input_parameters,
                           const std::string& input_data, const std::string& signature_to_verify,
-                          keymaster::AuthorizationSet* output_parameters,
+                          keystore::AuthorizationSet* output_parameters,
                           std::string* output_data) override;
-    int32_t addRandomNumberGeneratorEntropy(const std::string& entropy) override;
-    int32_t generateKey(const std::string& key_name,
-                        const keymaster::AuthorizationSet& key_parameters,
-                        keymaster::AuthorizationSet* hardware_enforced_characteristics,
-                        keymaster::AuthorizationSet* software_enforced_characteristics) override;
-    int32_t
+    KeyStoreNativeReturnCode addRandomNumberGeneratorEntropy(const std::string& entropy) override;
+    KeyStoreNativeReturnCode generateKey(const std::string& key_name,
+                        const keystore::AuthorizationSet& key_parameters,
+                        keystore::AuthorizationSet* hardware_enforced_characteristics,
+                        keystore::AuthorizationSet* software_enforced_characteristics) override;
+    KeyStoreNativeReturnCode
     getKeyCharacteristics(const std::string& key_name,
-                          keymaster::AuthorizationSet* hardware_enforced_characteristics,
-                          keymaster::AuthorizationSet* software_enforced_characteristics) override;
-    int32_t importKey(const std::string& key_name,
-                      const keymaster::AuthorizationSet& key_parameters,
-                      keymaster_key_format_t key_format, const std::string& key_data,
-                      keymaster::AuthorizationSet* hardware_enforced_characteristics,
-                      keymaster::AuthorizationSet* software_enforced_characteristics) override;
-    int32_t exportKey(keymaster_key_format_t export_format, const std::string& key_name,
+                          keystore::AuthorizationSet* hardware_enforced_characteristics,
+                          keystore::AuthorizationSet* software_enforced_characteristics) override;
+    KeyStoreNativeReturnCode importKey(const std::string& key_name,
+                      const keystore::AuthorizationSet& key_parameters,
+                      KeyFormat key_format, const std::string& key_data,
+                      keystore::AuthorizationSet* hardware_enforced_characteristics,
+                      keystore::AuthorizationSet* software_enforced_characteristics) override;
+    KeyStoreNativeReturnCode exportKey(KeyFormat export_format, const std::string& key_name,
                       std::string* export_data) override;
-    int32_t deleteKey(const std::string& key_name) override;
-    int32_t deleteAllKeys() override;
-    int32_t beginOperation(keymaster_purpose_t purpose, const std::string& key_name,
-                           const keymaster::AuthorizationSet& input_parameters,
-                           keymaster::AuthorizationSet* output_parameters,
-                           keymaster_operation_handle_t* handle) override;
-    int32_t updateOperation(keymaster_operation_handle_t handle,
-                            const keymaster::AuthorizationSet& input_parameters,
+    KeyStoreNativeReturnCode deleteKey(const std::string& key_name) override;
+    KeyStoreNativeReturnCode deleteAllKeys() override;
+    KeyStoreNativeReturnCode beginOperation(KeyPurpose purpose, const std::string& key_name,
+                           const keystore::AuthorizationSet& input_parameters,
+                           keystore::AuthorizationSet* output_parameters,
+                           uint64_t* handle) override;
+    KeyStoreNativeReturnCode updateOperation(uint64_t handle,
+                            const keystore::AuthorizationSet& input_parameters,
                             const std::string& input_data, size_t* num_input_bytes_consumed,
-                            keymaster::AuthorizationSet* output_parameters,
+                            keystore::AuthorizationSet* output_parameters,
                             std::string* output_data) override;
-    int32_t finishOperation(keymaster_operation_handle_t handle,
-                            const keymaster::AuthorizationSet& input_parameters,
+    KeyStoreNativeReturnCode finishOperation(uint64_t handle,
+                            const keystore::AuthorizationSet& input_parameters,
                             const std::string& signature_to_verify,
-                            keymaster::AuthorizationSet* output_parameters,
+                            keystore::AuthorizationSet* output_parameters,
                             std::string* output_data) override;
-    int32_t abortOperation(keymaster_operation_handle_t handle) override;
+    KeyStoreNativeReturnCode abortOperation(uint64_t handle) override;
     bool doesKeyExist(const std::string& key_name) override;
     bool listKeys(const std::string& prefix, std::vector<std::string>* key_name_list) override;
 
   private:
     // Returns an available virtual operation handle.
-    keymaster_operation_handle_t getNextVirtualHandle();
+    uint64_t getNextVirtualHandle();
 
     // Maps a keystore error code to a code where all success cases use
     // KM_ERROR_OK (not keystore's NO_ERROR).
-    int32_t mapKeystoreError(int32_t keystore_error);
+//    int32_t mapKeystoreError(int32_t keystore_error);
 
     // Creates an encryption key suitable for EncryptWithAuthentication or
     // verifies attributes if the key already exists. Returns true on success.
@@ -108,8 +108,8 @@
     android::sp<android::IServiceManager> service_manager_;
     android::sp<android::IBinder> keystore_binder_;
     android::sp<android::IKeystoreService> keystore_;
-    keymaster_operation_handle_t next_virtual_handle_ = 1;
-    std::map<keymaster_operation_handle_t, android::sp<android::IBinder>> active_operations_;
+    uint64_t next_virtual_handle_ = 1;
+    std::map<uint64_t, android::sp<android::IBinder>> active_operations_;
 
     DISALLOW_COPY_AND_ASSIGN(KeystoreClientImpl);
 };
diff --git a/keystore/include/keystore/keystore_hidl_support.h b/keystore/include/keystore/keystore_hidl_support.h
new file mode 100644
index 0000000..3c64d2a
--- /dev/null
+++ b/keystore/include/keystore/keystore_hidl_support.h
@@ -0,0 +1,130 @@
+/*
+ **
+ ** Copyright 2016, 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_KEYSTORE_HIDL_SUPPORT_H_
+#define KEYSTORE_KEYSTORE_HIDL_SUPPORT_H_
+
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+#include <hidl/Status.h>
+#include <keystore/keymaster_tags.h>
+#include <ostream>
+#include <sstream>
+#include <string>
+
+namespace keystore {
+
+inline static std::ostream& formatArgs(std::ostream& out) {
+    return out;
+}
+
+template <typename First, typename... Args>
+inline static std::ostream& formatArgs(std::ostream& out, First&& first, Args&&... args) {
+    out << first;
+    return formatArgs(out, args...);
+}
+
+template <typename... Args> inline static std::string argsToString(Args&&... args) {
+    std::stringstream s;
+    formatArgs(s, args...);
+    return s.str();
+}
+
+template <typename... Msgs>
+inline static ErrorCode ksHandleHidlError(const Return<ErrorCode>& error, Msgs&&... msgs) {
+    if (!error.isOk()) {
+        ALOGE("HIDL call failed with %s @ %s", error.description().c_str(),
+              argsToString(msgs...).c_str());
+        return ErrorCode::UNKNOWN_ERROR;
+    }
+    return ErrorCode(error);
+}
+template <typename... Msgs>
+inline static ErrorCode ksHandleHidlError(const Return<void>& error, Msgs&&... msgs) {
+    if (!error.isOk()) {
+        ALOGE("HIDL call failed with %s @ %s", error.description().c_str(),
+              argsToString(msgs...).c_str());
+        return ErrorCode::UNKNOWN_ERROR;
+    }
+    return ErrorCode::OK;
+}
+
+#define KS_HANDLE_HIDL_ERROR(rc)                                                                   \
+    ::keystore::ksHandleHidlError(rc, __FILE__, ":", __LINE__, ":", __PRETTY_FUNCTION__)
+
+inline static hidl_vec<uint8_t> blob2hidlVec(const uint8_t* data, const size_t length,
+                                             bool inPlace = true) {
+    hidl_vec<uint8_t> result;
+    if (inPlace)
+        result.setToExternal(const_cast<unsigned char*>(data), length);
+    else {
+        result.resize(length);
+        memcpy(&result[0], data, length);
+    }
+    return result;
+}
+
+inline static hidl_vec<uint8_t> blob2hidlVec(const std::string& value) {
+    hidl_vec<uint8_t> result;
+    result.setToExternal(
+        reinterpret_cast<uint8_t*>(const_cast<std::string::value_type*>(value.data())),
+        static_cast<size_t>(value.size()));
+    return result;
+}
+
+inline static hidl_vec<uint8_t> blob2hidlVec(const std::vector<uint8_t>& blob) {
+    hidl_vec<uint8_t> result;
+    result.setToExternal(const_cast<uint8_t*>(blob.data()), static_cast<size_t>(blob.size()));
+    return result;
+}
+
+template <typename T, typename OutIter>
+inline static OutIter copy_bytes_to_iterator(const T& value, OutIter dest) {
+    const uint8_t* value_ptr = reinterpret_cast<const uint8_t*>(&value);
+    return std::copy(value_ptr, value_ptr + sizeof(value), dest);
+}
+
+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.");
+    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),
+                  "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);
+    pos = copy_bytes_to_iterator(token.authenticatorType, pos);
+    pos = copy_bytes_to_iterator(token.timestamp, pos);
+    pos = std::copy(token.hmac.data(), token.hmac.data() + token.hmac.size(), pos);
+
+    return result;
+}
+
+inline std::string hidlVec2String(const hidl_vec<uint8_t>& value) {
+    return std::string(reinterpret_cast<const std::string::value_type*>(&value[0]), value.size());
+}
+
+}  // namespace keystore
+
+#endif  // KEYSTORE_KEYSTORE_HIDL_SUPPORT_H_
diff --git a/keystore/include/keystore/keystore_return_types.h b/keystore/include/keystore/keystore_return_types.h
new file mode 100644
index 0000000..70380c3
--- /dev/null
+++ b/keystore/include/keystore/keystore_return_types.h
@@ -0,0 +1,186 @@
+/*
+**
+** Copyright 2016, 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_INCLUDE_KEYSTORE_KEYSTORE_RETURN_TYPES_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_RETURN_TYPES_H_
+
+#include "keystore.h"
+#include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
+
+namespace keystore {
+
+using ::android::hardware::keymaster::V3_0::ErrorCode;
+
+class KeyStoreServiceReturnCode;
+class KeyStoreNativeReturnCode;
+
+/**
+ * The keystore service return code is a bit tricky. It can return error codes from two name spaces:
+ * ErrorCode, which has negative error codes and use 0 for ERROR_OK;
+ * ResponseCode, which has positive error codes and uses 1 for NO_ERROR.
+ * This class can be initialized by both. And when accessed through the operator int32_t () it
+ * always returns ResponseCode::NO_ERROR (1) on success, even if it was initialized with
+ * ErrorCode::OK (0), because this is what (java) clients expect.
+ *
+ * !!! Do not confuse this with KeyStoreNativeReturnCode which always converts to 0 on success. !!!
+ */
+class KeyStoreServiceReturnCode {
+  public:
+    KeyStoreServiceReturnCode() : errorCode_(0) {}
+    KeyStoreServiceReturnCode(const ErrorCode& errorCode) : errorCode_(int32_t(errorCode)) {}
+    KeyStoreServiceReturnCode(const ResponseCode& errorCode) : errorCode_(int32_t(errorCode)) {}
+    KeyStoreServiceReturnCode(const KeyStoreServiceReturnCode& errorCode)
+        : errorCode_(errorCode.errorCode_) {}
+    KeyStoreServiceReturnCode(const KeyStoreNativeReturnCode& errorCode);
+    inline KeyStoreServiceReturnCode& operator=(const ErrorCode& errorCode) {
+        errorCode_ = int32_t(errorCode);
+        return *this;
+    }
+    inline KeyStoreServiceReturnCode& operator=(const ResponseCode& errorCode) {
+        errorCode_ = int32_t(errorCode);
+        return *this;
+    }
+    inline KeyStoreServiceReturnCode& operator=(const KeyStoreServiceReturnCode& errorCode) {
+        errorCode_ = errorCode.errorCode_;
+        return *this;
+    }
+    inline bool isOk() const {
+        return errorCode_ == static_cast<int32_t>(ResponseCode::NO_ERROR) ||
+               errorCode_ == static_cast<int32_t>(ErrorCode::OK);
+    }
+    inline operator int32_t() const {
+        if (!errorCode_) return static_cast<int32_t>(ResponseCode::NO_ERROR);
+        return errorCode_;
+    }
+    inline bool operator==(const ResponseCode& rhs) const {
+        return (rhs == ResponseCode::NO_ERROR &&
+                errorCode_ == static_cast<int32_t>(ErrorCode::OK)) ||
+               errorCode_ == int32_t(rhs);
+    }
+    inline bool operator==(const ErrorCode& rhs) const {
+        return (rhs == ErrorCode::OK &&
+                errorCode_ == static_cast<int32_t>(ResponseCode::NO_ERROR)) ||
+               errorCode_ == int32_t(rhs);
+    }
+    inline bool operator!=(const ResponseCode& rhs) const { return !(*this == rhs); }
+    inline bool operator!=(const ErrorCode& rhs) const { return !(*this == rhs); }
+
+  private:
+    int32_t errorCode_;
+};
+
+inline bool operator==(const ResponseCode& lhs, const KeyStoreServiceReturnCode& rhs) {
+    return rhs == lhs;
+}
+inline bool operator==(const ErrorCode& lhs, const KeyStoreServiceReturnCode& rhs) {
+    return rhs == lhs;
+}
+inline bool operator!=(const ResponseCode& lhs, const KeyStoreServiceReturnCode& rhs) {
+    return rhs != lhs;
+}
+inline bool operator!=(const ErrorCode& lhs, const KeyStoreServiceReturnCode& rhs) {
+    return rhs != lhs;
+}
+
+inline std::ostream& operator<<(std::ostream& out, const KeyStoreServiceReturnCode& error) {
+    return out << int32_t(error);
+}
+
+/**
+ * The keystore native return code is a bit tricky. It can return error codes from two name spaces:
+ * ErrorCode, which has negative error codes and use 0 for ERROR_OK;
+ * ResponseCode, which has positive error codes and uses 1 for NO_ERROR.
+ * This class can be initialized by both. And when accessed through the operator int32_t () it
+ * always returns ErrorCode::OK (0) on success, even if it was initialized with
+ * ResponseCode::NO_ERROR (1), because this is what (native) clients expect.
+ *
+ * !!! Do not this confuse with KeyStoreServiceReturnCode which always converts to 1 on success. !!!
+ */
+class KeyStoreNativeReturnCode {
+  public:
+    KeyStoreNativeReturnCode() : errorCode_(0) {}
+    KeyStoreNativeReturnCode(const ErrorCode& errorCode) : errorCode_(int32_t(errorCode)) {}
+    KeyStoreNativeReturnCode(const ResponseCode& errorCode) : errorCode_(int32_t(errorCode)) {}
+    KeyStoreNativeReturnCode(const KeyStoreNativeReturnCode& errorCode)
+        : errorCode_(errorCode.errorCode_) {}
+    KeyStoreNativeReturnCode(const KeyStoreServiceReturnCode& errorcode);
+    inline KeyStoreNativeReturnCode& operator=(const ErrorCode& errorCode) {
+        errorCode_ = int32_t(errorCode);
+        return *this;
+    }
+    inline KeyStoreNativeReturnCode& operator=(const ResponseCode& errorCode) {
+        errorCode_ = int32_t(errorCode);
+        return *this;
+    }
+    inline KeyStoreNativeReturnCode& operator=(const KeyStoreNativeReturnCode& errorCode) {
+        errorCode_ = errorCode.errorCode_;
+        return *this;
+    }
+    inline bool isOk() const {
+        return errorCode_ == static_cast<int32_t>(ResponseCode::NO_ERROR) ||
+               errorCode_ == static_cast<int32_t>(ErrorCode::OK);
+    }
+    inline operator int32_t() const {
+        if (errorCode_ == static_cast<int32_t>(ResponseCode::NO_ERROR)) {
+            return static_cast<int32_t>(ErrorCode::OK);
+        }
+        return errorCode_;
+    }
+    inline bool operator==(const ResponseCode& rhs) const {
+        return (rhs == ResponseCode::NO_ERROR &&
+                errorCode_ == static_cast<int32_t>(ErrorCode::OK)) ||
+               errorCode_ == int32_t(rhs);
+    }
+    inline bool operator==(const ErrorCode& rhs) const {
+        return (rhs == ErrorCode::OK &&
+                errorCode_ == static_cast<int32_t>(ResponseCode::NO_ERROR)) ||
+               errorCode_ == int32_t(rhs);
+    }
+    inline bool operator!=(const ResponseCode& rhs) const { return !(*this == rhs); }
+    inline bool operator!=(const ErrorCode& rhs) const { return !(*this == rhs); }
+
+  private:
+    int32_t errorCode_;
+};
+
+inline bool operator==(const ResponseCode& lhs, const KeyStoreNativeReturnCode& rhs) {
+    return rhs == lhs;
+}
+inline bool operator==(const ErrorCode& lhs, const KeyStoreNativeReturnCode& rhs) {
+    return rhs == lhs;
+}
+inline bool operator!=(const ResponseCode& lhs, const KeyStoreNativeReturnCode& rhs) {
+    return rhs != lhs;
+}
+inline bool operator!=(const ErrorCode& lhs, const KeyStoreNativeReturnCode& rhs) {
+    return rhs != lhs;
+}
+
+inline KeyStoreNativeReturnCode::KeyStoreNativeReturnCode(
+    const KeyStoreServiceReturnCode& errorCode)
+    : errorCode_(int32_t(errorCode)) {}
+inline KeyStoreServiceReturnCode::KeyStoreServiceReturnCode(
+    const KeyStoreNativeReturnCode& errorCode)
+    : errorCode_(int32_t(errorCode)) {}
+
+inline std::ostream& operator<<(std::ostream& out, const KeyStoreNativeReturnCode& error) {
+    return out << int32_t(error);
+}
+
+}  // namespace keystore
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_KEYSTORE_RETURN_TYPES_H_
diff --git a/keystore/include/keystore/utils.h b/keystore/include/keystore/utils.h
new file mode 100644
index 0000000..f95ae71
--- /dev/null
+++ b/keystore/include/keystore/utils.h
@@ -0,0 +1,96 @@
+// TODO: Insert description here. (generated by jdanis)
+
+#ifndef KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_
+#define KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_
+
+#include <iterator>
+#include <memory>
+#include <vector>
+
+namespace android {
+namespace security {
+
+/*
+ * This iterator abstracts from a collection of the form
+ * std::shared_ptr<COLLECTION_TYPE<std::unique_ptr<T>>>
+ * such that it is defined both for nulled outer pointer and
+ * nulled entries. If shared_ptr(nullptr) is passed in, the iterator behaves
+ * like the end iterator yielding an empty collection. Nulled
+ * entries are skipped so that the iterator is always dereferencable unless
+ * it is equal to end.
+ * The default constructor always yields an iterator equal to end.
+ * The same iterator invalidation rules apply as they do for the iterators
+ * of the corresponding collection.
+ */
+template <typename T, template <typename...> class Coll = std::vector>
+class SharedNullableIterator {
+  public:
+    typedef Coll<std::unique_ptr<typename std::remove_const<T>::type>> CollectionType;
+    typedef std::shared_ptr<CollectionType> CollectionPtr;
+
+    SharedNullableIterator() {}
+    SharedNullableIterator(const std::shared_ptr<CollectionType>& coll) : coll_(coll) { init(); }
+    SharedNullableIterator(std::shared_ptr<CollectionType>&& coll) : coll_(coll) { init(); }
+
+    SharedNullableIterator(const SharedNullableIterator& other)
+        : coll_(other.coll_), cur_(other.cur_) {}
+    SharedNullableIterator(SharedNullableIterator&& other)
+        : coll_(std::move(other.coll_)), cur_(std::move(other.cur_)) {}
+
+    SharedNullableIterator& operator++() {
+        inc();
+        return *this;
+    }
+    SharedNullableIterator operator++(int) {
+        SharedNullableIterator retval(*this);
+        ++(*this);
+        return retval;
+    }
+    T& operator*() const { return **cur_; }
+
+    T* operator->() const { return &**cur_; }
+
+    bool operator==(const SharedNullableIterator& other) const {
+        return cur_ == other.cur_ || (is_end() && other.is_end());
+    }
+    bool operator!=(const SharedNullableIterator& other) const { return !(*this == other); }
+
+    SharedNullableIterator& operator=(const SharedNullableIterator&) = default;
+    SharedNullableIterator& operator=(SharedNullableIterator&&) = default;
+
+  private:
+    inline bool is_end() const { return !coll_ || cur_ == coll_->end(); }
+    inline void inc() {
+        if (!is_end()) {
+            do {
+                ++cur_;
+                // move forward to the next non null member or stay at end
+            } while (cur_ != coll_->end() && !(*cur_));
+        }
+    }
+    void init() {
+        if (coll_) {
+            // move forward to the first non null member
+            for (cur_ = coll_->begin(); cur_ != coll_->end() && !(*cur_); ++cur_) {
+            }
+        }
+    }
+
+    CollectionPtr coll_;
+    typename CollectionType::iterator cur_;
+};
+
+}  // namespace security
+}  // namespace android
+
+namespace std {
+template <typename T, template <typename...> class COLL>
+struct iterator_traits<android::security::SharedNullableIterator<T, COLL>> {
+    typedef T& reference;
+    typedef T value_type;
+    typedef T* pointer;
+    typedef forward_iterator_tag iterator_category;
+};
+}
+
+#endif  // KEYSTORE_INCLUDE_KEYSTORE_UTILS_H_
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index d68c367..248fa00 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -14,39 +14,112 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "keystore"
+
 #include "key_store_service.h"
 
 #include <fcntl.h>
 #include <sys/stat.h>
 
+#include <algorithm>
 #include <sstream>
 
+#include <binder/IInterface.h>
 #include <binder/IPCThreadState.h>
+#include <binder/IPermissionController.h>
+#include <binder/IServiceManager.h>
 
 #include <private/android_filesystem_config.h>
 
-#include <hardware/keymaster_defs.h>
+#include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
 
 #include "defaults.h"
+#include "keystore_attestation_id.h"
+#include "keystore_keymaster_enforcement.h"
 #include "keystore_utils.h"
+#include <keystore/keystore_hidl_support.h>
 
-using keymaster::AuthorizationSet;
-using keymaster::AuthorizationSetBuilder;
-using keymaster::TAG_APPLICATION_DATA;
-using keymaster::TAG_APPLICATION_ID;
+namespace keystore {
 
-namespace android {
+using namespace android;
 
-const size_t MAX_OPERATIONS = 15;
+namespace {
+
+constexpr size_t kMaxOperations = 15;
+constexpr double kIdRotationPeriod = 30 * 24 * 60 * 60; /* Thirty days, in seconds */
+const char* kTimestampFilePath = "timestamp";
 
 struct BIGNUM_Delete {
     void operator()(BIGNUM* p) const { BN_free(p); }
 };
 typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
 
-struct Malloc_Delete {
-    void operator()(uint8_t* p) const { free(p); }
-};
+bool containsTag(const hidl_vec<KeyParameter>& params, Tag tag) {
+    return params.end() != std::find_if(params.begin(), params.end(),
+                                        [&](auto& param) { return param.tag == tag; });
+}
+
+bool isAuthenticationBound(const hidl_vec<KeyParameter>& params) {
+    return !containsTag(params, Tag::NO_AUTH_REQUIRED);
+}
+
+std::pair<KeyStoreServiceReturnCode, bool> hadFactoryResetSinceIdRotation() {
+    struct stat sbuf;
+    if (stat(kTimestampFilePath, &sbuf) == 0) {
+        double diff_secs = difftime(time(NULL), sbuf.st_ctime);
+        return {ResponseCode::NO_ERROR, diff_secs < kIdRotationPeriod};
+    }
+
+    if (errno != ENOENT) {
+        ALOGE("Failed to stat \"timestamp\" file, with error %d", errno);
+        return {ResponseCode::SYSTEM_ERROR, false /* don't care */};
+    }
+
+    int fd = creat(kTimestampFilePath, 0600);
+    if (fd < 0) {
+        ALOGE("Couldn't create \"timestamp\" file, with error %d", errno);
+        return {ResponseCode::SYSTEM_ERROR, false /* don't care */};
+    }
+
+    if (close(fd)) {
+        ALOGE("Couldn't close \"timestamp\" file, with error %d", errno);
+        return {ResponseCode::SYSTEM_ERROR, false /* don't care */};
+    }
+
+    return {ResponseCode::NO_ERROR, true};
+}
+
+constexpr size_t KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE = 1024;
+
+KeyStoreServiceReturnCode updateParamsForAttestation(uid_t callingUid, AuthorizationSet* params) {
+    KeyStoreServiceReturnCode responseCode;
+    bool factoryResetSinceIdRotation;
+    std::tie(responseCode, factoryResetSinceIdRotation) = hadFactoryResetSinceIdRotation();
+
+    if (!responseCode.isOk()) return responseCode;
+    if (factoryResetSinceIdRotation) params->push_back(TAG_RESET_SINCE_ID_ROTATION);
+
+    auto asn1_attestation_id_result = security::gather_attestation_application_id(callingUid);
+    if (!asn1_attestation_id_result.isOk()) {
+        ALOGE("failed to gather attestation_id");
+        return ErrorCode::ATTESTATION_APPLICATION_ID_MISSING;
+    }
+    std::vector<uint8_t>& asn1_attestation_id = asn1_attestation_id_result;
+
+    /*
+     * The attestation application ID cannot be longer than
+     * KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE, so we truncate if too long.
+     */
+    if (asn1_attestation_id.size() > KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE) {
+        asn1_attestation_id.resize(KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE);
+    }
+
+    params->push_back(TAG_ATTESTATION_APPLICATION_ID, asn1_attestation_id);
+
+    return ResponseCode::NO_ERROR;
+}
+
+}  // anonymous namespace
 
 void KeyStoreService::binderDied(const wp<IBinder>& who) {
     auto operations = mOperationMap.getOperationsForToken(who.unsafe_get());
@@ -55,116 +128,125 @@
     }
 }
 
-int32_t KeyStoreService::getState(int32_t userId) {
+KeyStoreServiceReturnCode KeyStoreService::getState(int32_t userId) {
     if (!checkBinderPermission(P_GET_STATE)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
-    return mKeyStore->getState(userId);
+    return ResponseCode(mKeyStore->getState(userId));
 }
 
-int32_t KeyStoreService::get(const String16& name, int32_t uid, uint8_t** item,
-                             size_t* itemLength) {
+KeyStoreServiceReturnCode KeyStoreService::get(const String16& name, int32_t uid,
+                                               hidl_vec<uint8_t>* item) {
     uid_t targetUid = getEffectiveUid(uid);
     if (!checkBinderPermission(P_GET, targetUid)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     String8 name8(name);
     Blob keyBlob;
 
-    ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_GENERIC);
-    if (responseCode != ::NO_ERROR) {
-        *item = NULL;
-        *itemLength = 0;
-        return responseCode;
+    KeyStoreServiceReturnCode rc =
+        mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_GENERIC);
+    if (!rc.isOk()) {
+        if (item) *item = hidl_vec<uint8_t>();
+        return rc;
     }
 
-    *item = (uint8_t*)malloc(keyBlob.getLength());
-    memcpy(*item, keyBlob.getValue(), keyBlob.getLength());
-    *itemLength = keyBlob.getLength();
+    // Do not replace this with "if (item) *item = blob2hidlVec(keyBlob)"!
+    // blob2hidlVec creates a hidl_vec<uint8_t> that references, but not owns, the data in keyBlob
+    // the subsequent assignment (*item = resultBlob) makes a deep copy, so that *item will own the
+    // corresponding resources.
+    auto resultBlob = blob2hidlVec(keyBlob);
+    if (item) {
+        *item = resultBlob;
+    }
 
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::insert(const String16& name, const uint8_t* item, size_t itemLength,
-                                int targetUid, int32_t flags) {
+KeyStoreServiceReturnCode KeyStoreService::insert(const String16& name,
+                                                  const hidl_vec<uint8_t>& item, int targetUid,
+                                                  int32_t flags) {
     targetUid = getEffectiveUid(targetUid);
-    int32_t result =
+    auto result =
         checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (result != ::NO_ERROR) {
+    if (!result.isOk()) {
         return result;
     }
 
     String8 name8(name);
     String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_GENERIC));
 
-    Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC);
+    Blob keyBlob(&item[0], item.size(), NULL, 0, ::TYPE_GENERIC);
     keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
 
     return mKeyStore->put(filename.string(), &keyBlob, get_user_id(targetUid));
 }
 
-int32_t KeyStoreService::del(const String16& name, int targetUid) {
+KeyStoreServiceReturnCode KeyStoreService::del(const String16& name, int targetUid) {
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_DELETE, targetUid)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
     String8 name8(name);
+    ALOGI("del %s %d", name8.string(), targetUid);
     String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
-    int32_t result = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
-    if (result != ::NO_ERROR) {
+    ResponseCode result = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
+    if (result != ResponseCode::NO_ERROR) {
         return result;
     }
 
     // Also delete any characteristics files
-    String8 chrFilename(mKeyStore->getKeyNameForUidWithDir(
-        name8, targetUid, ::TYPE_KEY_CHARACTERISTICS));
+    String8 chrFilename(
+        mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_KEY_CHARACTERISTICS));
     return mKeyStore->del(chrFilename.string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid));
 }
 
-int32_t KeyStoreService::exist(const String16& name, int targetUid) {
+KeyStoreServiceReturnCode KeyStoreService::exist(const String16& name, int targetUid) {
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_EXIST, targetUid)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     String8 name8(name);
     String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
 
     if (access(filename.string(), R_OK) == -1) {
-        return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
+        return (errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::KEY_NOT_FOUND;
     }
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::list(const String16& prefix, int targetUid, Vector<String16>* matches) {
+KeyStoreServiceReturnCode KeyStoreService::list(const String16& prefix, int targetUid,
+                                                Vector<String16>* matches) {
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_LIST, targetUid)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
     const String8 prefix8(prefix);
     String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid, TYPE_ANY));
 
-    if (mKeyStore->list(filename, matches, get_user_id(targetUid)) != ::NO_ERROR) {
-        return ::SYSTEM_ERROR;
+    if (mKeyStore->list(filename, matches, get_user_id(targetUid)) != ResponseCode::NO_ERROR) {
+        return ResponseCode::SYSTEM_ERROR;
     }
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::reset() {
+KeyStoreServiceReturnCode KeyStoreService::reset() {
     if (!checkBinderPermission(P_RESET)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     mKeyStore->resetUser(get_user_id(callingUid), false);
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::onUserPasswordChanged(int32_t userId, const String16& password) {
+KeyStoreServiceReturnCode KeyStoreService::onUserPasswordChanged(int32_t userId,
+                                                                 const String16& password) {
     if (!checkBinderPermission(P_PASSWORD)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     const String8 password8(password);
@@ -175,7 +257,7 @@
     if (password.size() == 0) {
         ALOGI("Secure lockscreen for user %d removed, deleting encrypted entries", userId);
         mKeyStore->resetUser(userId, true);
-        return ::NO_ERROR;
+        return ResponseCode::NO_ERROR;
     } else {
         switch (mKeyStore->getState(userId)) {
         case ::STATE_UNINITIALIZED: {
@@ -193,13 +275,13 @@
             return mKeyStore->initializeUser(password8, userId);
         }
         }
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 }
 
-int32_t KeyStoreService::onUserAdded(int32_t userId, int32_t parentId) {
+KeyStoreServiceReturnCode KeyStoreService::onUserAdded(int32_t userId, int32_t parentId) {
     if (!checkBinderPermission(P_USER_CHANGED)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     // Sanity check that the new user has an empty keystore.
@@ -215,37 +297,37 @@
         // parent profile, forever.
         return mKeyStore->copyMasterKey(parentId, userId);
     } else {
-        return ::NO_ERROR;
+        return ResponseCode::NO_ERROR;
     }
 }
 
-int32_t KeyStoreService::onUserRemoved(int32_t userId) {
+KeyStoreServiceReturnCode KeyStoreService::onUserRemoved(int32_t userId) {
     if (!checkBinderPermission(P_USER_CHANGED)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     mKeyStore->resetUser(userId, false);
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::lock(int32_t userId) {
+KeyStoreServiceReturnCode KeyStoreService::lock(int32_t userId) {
     if (!checkBinderPermission(P_LOCK)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     State state = mKeyStore->getState(userId);
     if (state != ::STATE_NO_ERROR) {
         ALOGD("calling lock in state: %d", state);
-        return state;
+        return ResponseCode(state);
     }
 
     mKeyStore->lock(userId);
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::unlock(int32_t userId, const String16& pw) {
+KeyStoreServiceReturnCode KeyStoreService::unlock(int32_t userId, const String16& pw) {
     if (!checkBinderPermission(P_UNLOCK)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     State state = mKeyStore->getState(userId);
@@ -261,7 +343,7 @@
             ALOGE("unlock called on keystore in unknown state: %d", state);
             break;
         }
-        return state;
+        return ResponseCode(state);
     }
 
     const String8 password8(pw);
@@ -277,43 +359,44 @@
     return mKeyStore->isEmpty(userId);
 }
 
-int32_t KeyStoreService::generate(const String16& name, int32_t targetUid, int32_t keyType,
-                                  int32_t keySize, int32_t flags, Vector<sp<KeystoreArg>>* args) {
+KeyStoreServiceReturnCode KeyStoreService::generate(const String16& name, int32_t targetUid,
+                                                    int32_t keyType, int32_t keySize, int32_t flags,
+                                                    Vector<sp<KeystoreArg>>* args) {
     targetUid = getEffectiveUid(targetUid);
-    int32_t result =
+    auto result =
         checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (result != ::NO_ERROR) {
+    if (!result.isOk()) {
         return result;
     }
 
-    KeymasterArguments params;
-    add_legacy_key_authorizations(keyType, &params.params);
+    keystore::AuthorizationSet params;
+    add_legacy_key_authorizations(keyType, &params);
 
     switch (keyType) {
     case EVP_PKEY_EC: {
-        params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_EC));
+        params.push_back(TAG_ALGORITHM, Algorithm::EC);
         if (keySize == -1) {
             keySize = EC_DEFAULT_KEY_SIZE;
         } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
             ALOGI("invalid key size %d", keySize);
-            return ::SYSTEM_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        params.params.push_back(keymaster_param_int(KM_TAG_KEY_SIZE, keySize));
+        params.push_back(TAG_KEY_SIZE, keySize);
         break;
     }
     case EVP_PKEY_RSA: {
-        params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_RSA));
+        params.push_back(TAG_ALGORITHM, Algorithm::RSA);
         if (keySize == -1) {
             keySize = RSA_DEFAULT_KEY_SIZE;
         } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
             ALOGI("invalid key size %d", keySize);
-            return ::SYSTEM_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        params.params.push_back(keymaster_param_int(KM_TAG_KEY_SIZE, keySize));
+        params.push_back(TAG_KEY_SIZE, keySize);
         unsigned long exponent = RSA_DEFAULT_EXPONENT;
         if (args->size() > 1) {
             ALOGI("invalid number of arguments: %zu", args->size());
-            return ::SYSTEM_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         } else if (args->size() == 1) {
             const sp<KeystoreArg>& expArg = args->itemAt(0);
             if (expArg != NULL) {
@@ -321,84 +404,88 @@
                     reinterpret_cast<const unsigned char*>(expArg->data()), expArg->size(), NULL));
                 if (pubExpBn.get() == NULL) {
                     ALOGI("Could not convert public exponent to BN");
-                    return ::SYSTEM_ERROR;
+                    return ResponseCode::SYSTEM_ERROR;
                 }
                 exponent = BN_get_word(pubExpBn.get());
                 if (exponent == 0xFFFFFFFFL) {
                     ALOGW("cannot represent public exponent as a long value");
-                    return ::SYSTEM_ERROR;
+                    return ResponseCode::SYSTEM_ERROR;
                 }
             } else {
                 ALOGW("public exponent not read");
-                return ::SYSTEM_ERROR;
+                return ResponseCode::SYSTEM_ERROR;
             }
         }
-        params.params.push_back(keymaster_param_long(KM_TAG_RSA_PUBLIC_EXPONENT, exponent));
+        params.push_back(TAG_RSA_PUBLIC_EXPONENT, exponent);
         break;
     }
     default: {
         ALOGW("Unsupported key type %d", keyType);
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     }
 
-    int32_t rc = generateKey(name, params, NULL, 0, targetUid, flags,
-                             /*outCharacteristics*/ NULL);
-    if (rc != ::NO_ERROR) {
-        ALOGW("generate failed: %d", rc);
+    auto rc = generateKey(name, params.hidl_data(), hidl_vec<uint8_t>(), targetUid, flags,
+                          /*outCharacteristics*/ NULL);
+    if (!rc.isOk()) {
+        ALOGW("generate failed: %d", int32_t(rc));
     }
     return translateResultToLegacyResult(rc);
 }
 
-int32_t KeyStoreService::import(const String16& name, const uint8_t* data, size_t length,
-                                int targetUid, int32_t flags) {
-    const uint8_t* ptr = data;
+KeyStoreServiceReturnCode KeyStoreService::import(const String16& name,
+                                                  const hidl_vec<uint8_t>& data, int targetUid,
+                                                  int32_t flags) {
 
-    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &ptr, length));
+    const uint8_t* ptr = &data[0];
+
+    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &ptr, data.size()));
     if (!pkcs8.get()) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
     if (!pkey.get()) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     int type = EVP_PKEY_type(pkey->type);
-    KeymasterArguments params;
-    add_legacy_key_authorizations(type, &params.params);
+    AuthorizationSet params;
+    add_legacy_key_authorizations(type, &params);
     switch (type) {
     case EVP_PKEY_RSA:
-        params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_RSA));
+        params.push_back(TAG_ALGORITHM, Algorithm::RSA);
         break;
     case EVP_PKEY_EC:
-        params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_EC));
+        params.push_back(TAG_ALGORITHM, Algorithm::EC);
         break;
     default:
         ALOGW("Unsupported key type %d", type);
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
-    int32_t rc = importKey(name, params, KM_KEY_FORMAT_PKCS8, data, length, targetUid, flags,
-                           /*outCharacteristics*/ NULL);
-    if (rc != ::NO_ERROR) {
-        ALOGW("importKey failed: %d", rc);
+
+    auto rc = importKey(name, params.hidl_data(), KeyFormat::PKCS8, data, targetUid, flags,
+                        /*outCharacteristics*/ NULL);
+
+    if (!rc.isOk()) {
+        ALOGW("importKey failed: %d", int32_t(rc));
     }
     return translateResultToLegacyResult(rc);
 }
 
-int32_t KeyStoreService::sign(const String16& name, const uint8_t* data, size_t length,
-                              uint8_t** out, size_t* outLength) {
+KeyStoreServiceReturnCode KeyStoreService::sign(const String16& name, const hidl_vec<uint8_t>& data,
+                                                hidl_vec<uint8_t>* out) {
     if (!checkBinderPermission(P_SIGN)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
-    return doLegacySignVerify(name, data, length, out, outLength, NULL, 0, KM_PURPOSE_SIGN);
+    return doLegacySignVerify(name, data, out, hidl_vec<uint8_t>(), KeyPurpose::SIGN);
 }
 
-int32_t KeyStoreService::verify(const String16& name, const uint8_t* data, size_t dataLength,
-                                const uint8_t* signature, size_t signatureLength) {
+KeyStoreServiceReturnCode KeyStoreService::verify(const String16& name,
+                                                  const hidl_vec<uint8_t>& data,
+                                                  const hidl_vec<uint8_t>& signature) {
     if (!checkBinderPermission(P_VERIFY)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
-    return doLegacySignVerify(name, data, dataLength, NULL, NULL, signature, signatureLength,
-                              KM_PURPOSE_VERIFY);
+    return doLegacySignVerify(name, data, nullptr, signature, KeyPurpose::VERIFY);
 }
 
 /*
@@ -412,23 +499,23 @@
  * "del_key" since the Java code doesn't really communicate what it's
  * intentions are.
  */
-int32_t KeyStoreService::get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {
+KeyStoreServiceReturnCode KeyStoreService::get_pubkey(const String16& name,
+                                                      hidl_vec<uint8_t>* pubKey) {
     ExportResult result;
-    exportKey(name, KM_KEY_FORMAT_X509, NULL, NULL, UID_SELF, &result);
-    if (result.resultCode != ::NO_ERROR) {
-        ALOGW("export failed: %d", result.resultCode);
+    exportKey(name, KeyFormat::X509, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(), UID_SELF, &result);
+    if (!result.resultCode.isOk()) {
+        ALOGW("export failed: %d", int32_t(result.resultCode));
         return translateResultToLegacyResult(result.resultCode);
     }
 
-    *pubkey = result.exportData.release();
-    *pubkeyLength = result.dataLength;
-    return ::NO_ERROR;
+    if (pubKey) *pubKey = std::move(result.exportData);
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::grant(const String16& name, int32_t granteeUid) {
+KeyStoreServiceReturnCode KeyStoreService::grant(const String16& name, int32_t granteeUid) {
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    int32_t result = checkBinderPermissionAndKeystoreState(P_GRANT);
-    if (result != ::NO_ERROR) {
+    auto result = checkBinderPermissionAndKeystoreState(P_GRANT);
+    if (!result.isOk()) {
         return result;
     }
 
@@ -436,17 +523,17 @@
     String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
 
     if (access(filename.string(), R_OK) == -1) {
-        return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
+        return (errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::KEY_NOT_FOUND;
     }
 
     mKeyStore->addGrant(filename.string(), granteeUid);
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::ungrant(const String16& name, int32_t granteeUid) {
+KeyStoreServiceReturnCode KeyStoreService::ungrant(const String16& name, int32_t granteeUid) {
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
-    int32_t result = checkBinderPermissionAndKeystoreState(P_GRANT);
-    if (result != ::NO_ERROR) {
+    auto result = checkBinderPermissionAndKeystoreState(P_GRANT);
+    if (!result.isOk()) {
         return result;
     }
 
@@ -454,10 +541,11 @@
     String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
 
     if (access(filename.string(), R_OK) == -1) {
-        return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
+        return (errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::KEY_NOT_FOUND;
     }
 
-    return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND;
+    return mKeyStore->removeGrant(filename.string(), granteeUid) ? ResponseCode::NO_ERROR
+                                                                 : ResponseCode::KEY_NOT_FOUND;
 }
 
 int64_t KeyStoreService::getmtime(const String16& name, int32_t uid) {
@@ -493,26 +581,26 @@
 }
 
 // TODO(tuckeris): This is dead code, remove it.  Don't bother copying over key characteristics here
-int32_t KeyStoreService::duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
-                                   int32_t destUid) {
+KeyStoreServiceReturnCode KeyStoreService::duplicate(const String16& srcKey, int32_t srcUid,
+                                                     const String16& destKey, int32_t destUid) {
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     pid_t spid = IPCThreadState::self()->getCallingPid();
     if (!has_permission(callingUid, P_DUPLICATE, spid)) {
         ALOGW("permission denied for %d: duplicate", callingUid);
-        return -1L;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     State state = mKeyStore->getState(get_user_id(callingUid));
     if (!isKeystoreUnlocked(state)) {
         ALOGD("calling duplicate in state: %d", state);
-        return state;
+        return ResponseCode(state);
     }
 
     if (srcUid == -1 || static_cast<uid_t>(srcUid) == callingUid) {
         srcUid = callingUid;
     } else if (!is_granted_to(callingUid, srcUid)) {
         ALOGD("migrate not granted from source: %d -> %d", callingUid, srcUid);
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     if (destUid == -1) {
@@ -524,12 +612,12 @@
             ALOGD("can only duplicate from caller to other or to same uid: "
                   "calling=%d, srcUid=%d, destUid=%d",
                   callingUid, srcUid, destUid);
-            return ::PERMISSION_DENIED;
+            return ResponseCode::PERMISSION_DENIED;
         }
 
         if (!is_granted_to(callingUid, destUid)) {
             ALOGD("duplicate not granted to dest: %d -> %d", callingUid, destUid);
-            return ::PERMISSION_DENIED;
+            return ResponseCode::PERMISSION_DENIED;
         }
     }
 
@@ -541,13 +629,13 @@
 
     if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) {
         ALOGD("destination already exists: %s", targetFile.string());
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     Blob keyBlob;
     ResponseCode responseCode =
         mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY, get_user_id(srcUid));
-    if (responseCode != ::NO_ERROR) {
+    if (responseCode != ResponseCode::NO_ERROR) {
         return responseCode;
     }
 
@@ -558,159 +646,146 @@
     return mKeyStore->isHardwareBacked(keyType) ? 1 : 0;
 }
 
-int32_t KeyStoreService::clear_uid(int64_t targetUid64) {
+KeyStoreServiceReturnCode KeyStoreService::clear_uid(int64_t targetUid64) {
     uid_t targetUid = getEffectiveUid(targetUid64);
     if (!checkBinderPermissionSelfOrSystem(P_CLEAR_UID, targetUid)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
+    ALOGI("clear_uid %" PRId64, targetUid64);
 
     String8 prefix = String8::format("%u_", targetUid);
     Vector<String16> aliases;
-    if (mKeyStore->list(prefix, &aliases, get_user_id(targetUid)) != ::NO_ERROR) {
-        return ::SYSTEM_ERROR;
+    if (mKeyStore->list(prefix, &aliases, get_user_id(targetUid)) != ResponseCode::NO_ERROR) {
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     for (uint32_t i = 0; i < aliases.size(); i++) {
         String8 name8(aliases[i]);
         String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
+
+        if (get_app_id(targetUid) == AID_SYSTEM) {
+            Blob keyBlob;
+            ResponseCode responseCode =
+                mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, get_user_id(targetUid));
+            if (responseCode == ResponseCode::NO_ERROR && keyBlob.isCriticalToDeviceEncryption()) {
+                // Do not clear keys critical to device encryption under system uid.
+                continue;
+            }
+        }
+
         mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
 
         // del() will fail silently if no cached characteristics are present for this alias.
-        String8 chr_filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid,
-            ::TYPE_KEY_CHARACTERISTICS));
+        String8 chr_filename(
+            mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_KEY_CHARACTERISTICS));
         mKeyStore->del(chr_filename.string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid));
     }
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::addRngEntropy(const uint8_t* data, size_t dataLength) {
-    const auto* device = mKeyStore->getDevice();
-    const auto* fallback = mKeyStore->getFallbackDevice();
-    int32_t devResult = KM_ERROR_UNIMPLEMENTED;
-    int32_t fallbackResult = KM_ERROR_UNIMPLEMENTED;
-    if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 &&
-        device->add_rng_entropy != NULL) {
-        devResult = device->add_rng_entropy(device, data, dataLength);
-    }
-    if (fallback->add_rng_entropy) {
-        fallbackResult = fallback->add_rng_entropy(fallback, data, dataLength);
-    }
-    if (devResult) {
-        return devResult;
-    }
-    if (fallbackResult) {
-        return fallbackResult;
-    }
-    return ::NO_ERROR;
+KeyStoreServiceReturnCode KeyStoreService::addRngEntropy(const hidl_vec<uint8_t>& entropy) {
+    const auto& device = mKeyStore->getDevice();
+    return KS_HANDLE_HIDL_ERROR(device->addRngEntropy(entropy));
 }
 
-int32_t KeyStoreService::generateKey(const String16& name, const KeymasterArguments& params,
-                                     const uint8_t* entropy, size_t entropyLength, int uid,
-                                     int flags, KeyCharacteristics* outCharacteristics) {
+KeyStoreServiceReturnCode KeyStoreService::generateKey(const String16& name,
+                                                       const hidl_vec<KeyParameter>& params,
+                                                       const hidl_vec<uint8_t>& entropy, int uid,
+                                                       int flags,
+                                                       KeyCharacteristics* outCharacteristics) {
     uid = getEffectiveUid(uid);
-    int rc = checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (rc != ::NO_ERROR) {
+    KeyStoreServiceReturnCode rc =
+        checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
+    if (!rc.isOk()) {
         return rc;
     }
-
-    rc = KM_ERROR_UNIMPLEMENTED;
-    bool isFallback = false;
-    keymaster_key_blob_t blob;
-    keymaster_key_characteristics_t out = {{nullptr, 0}, {nullptr, 0}};
-
-    const auto* device = mKeyStore->getDevice();
-    const auto* fallback = mKeyStore->getFallbackDevice();
-    std::vector<keymaster_key_param_t> opParams(params.params);
-    const keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()};
-    if (device == NULL) {
-        return ::SYSTEM_ERROR;
+    if ((flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION) && get_app_id(uid) != AID_SYSTEM) {
+        ALOGE("Non-system uid %d cannot set FLAG_CRITICAL_TO_DEVICE_ENCRYPTION", uid);
+        return ResponseCode::PERMISSION_DENIED;
     }
 
-    // Capture characteristics before they're potentially stripped by the device
-    AuthorizationSet keyCharacteristics(opParams.data(), opParams.size());
-    if (keyCharacteristics.is_valid() != AuthorizationSet::Error::OK) {
-        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    if (containsTag(params, Tag::INCLUDE_UNIQUE_ID)) {
+        if (!checkBinderPermission(P_GEN_UNIQUE_ID)) return ResponseCode::PERMISSION_DENIED;
     }
-    UniquePtr<uint8_t[]> kc_buf;
-    kc_buf.reset(new (std::nothrow) uint8_t[keyCharacteristics.SerializedSize()]);
-    if (!kc_buf.get()) {
-        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
-    }
-    keyCharacteristics.Serialize(kc_buf.get(), kc_buf.get() + keyCharacteristics.SerializedSize());
+
+    bool usingFallback = false;
+    auto& dev = mKeyStore->getDevice();
+    AuthorizationSet keyCharacteristics = params;
 
     // TODO: Seed from Linux RNG before this.
-    if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 &&
-        device->generate_key != NULL) {
-        if (!entropy) {
-            rc = KM_ERROR_OK;
-        } else if (device->add_rng_entropy) {
-            rc = device->add_rng_entropy(device, entropy, entropyLength);
-        } else {
-            rc = KM_ERROR_UNIMPLEMENTED;
-        }
-        if (rc == KM_ERROR_OK) {
-            rc =
-                device->generate_key(device, &inParams, &blob, outCharacteristics ? &out : nullptr);
-        }
-    }
-    // If the HW device didn't support generate_key or generate_key failed
-    // fall back to the software implementation.
-    if (rc && fallback->generate_key != NULL) {
-        ALOGW("Primary keymaster device failed to generate key, falling back to SW.");
-        isFallback = true;
-        if (!entropy) {
-            rc = KM_ERROR_OK;
-        } else if (fallback->add_rng_entropy) {
-            rc = fallback->add_rng_entropy(fallback, entropy, entropyLength);
-        } else {
-            rc = KM_ERROR_UNIMPLEMENTED;
-        }
-        if (rc == KM_ERROR_OK) {
-            rc = fallback->generate_key(fallback, &inParams, &blob,
-                                        outCharacteristics ? &out : nullptr);
-        }
-    }
-
-    if (outCharacteristics) {
-        outCharacteristics->characteristics = out;
-    }
-
-    if (rc) {
+    rc = addRngEntropy(entropy);
+    if (!rc.isOk()) {
         return rc;
     }
 
-    // Write the key:
-    String8 name8(name);
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
+    KeyStoreServiceReturnCode error;
+    auto hidl_cb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
+                       const KeyCharacteristics& keyCharacteristics) {
+        error = ret;
+        if (!error.isOk()) {
+            return;
+        }
+        if (outCharacteristics) *outCharacteristics = keyCharacteristics;
 
-    Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10);
-    keyBlob.setFallback(isFallback);
-    keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
+        // Write the key
+        String8 name8(name);
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
 
-    free(const_cast<uint8_t*>(blob.key_material));
-    rc = mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
+        Blob keyBlob(&hidlKeyBlob[0], hidlKeyBlob.size(), NULL, 0, ::TYPE_KEYMASTER_10);
+        keyBlob.setFallback(usingFallback);
+        keyBlob.setCriticalToDeviceEncryption(flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
+        if (isAuthenticationBound(params) && !keyBlob.isCriticalToDeviceEncryption()) {
+            keyBlob.setSuperEncrypted(true);
+        }
+        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
 
-    if (rc != ::NO_ERROR) {
+        error = mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
+    };
+
+    rc = KS_HANDLE_HIDL_ERROR(dev->generateKey(params, hidl_cb));
+    if (!rc.isOk()) {
         return rc;
     }
+    if (!error.isOk()) {
+        ALOGE("Failed to generate key -> falling back to software keymaster");
+        usingFallback = true;
+        auto fallback = mKeyStore->getFallbackDevice();
+        if (!fallback.isOk()) {
+            return error;
+        }
+        rc = KS_HANDLE_HIDL_ERROR(fallback.value()->generateKey(params, hidl_cb));
+        if (!rc.isOk()) {
+            return rc;
+        }
+        if (!error.isOk()) {
+            return error;
+        }
+    }
 
     // Write the characteristics:
+    String8 name8(name);
     String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
 
-    Blob charBlob(kc_buf.get(), keyCharacteristics.SerializedSize(),
-        NULL, 0, ::TYPE_KEY_CHARACTERISTICS);
-    charBlob.setFallback(isFallback);
+    std::stringstream kc_stream;
+    keyCharacteristics.Serialize(&kc_stream);
+    if (kc_stream.bad()) {
+        return ResponseCode::SYSTEM_ERROR;
+    }
+    auto kc_buf = kc_stream.str();
+    Blob charBlob(reinterpret_cast<const uint8_t*>(kc_buf.data()), kc_buf.size(), NULL, 0,
+                  ::TYPE_KEY_CHARACTERISTICS);
+    charBlob.setFallback(usingFallback);
     charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
 
     return mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid));
 }
 
-int32_t KeyStoreService::getKeyCharacteristics(const String16& name,
-                                               const keymaster_blob_t* clientId,
-                                               const keymaster_blob_t* appData, int32_t uid,
-                                               KeyCharacteristics* outCharacteristics) {
+KeyStoreServiceReturnCode
+KeyStoreService::getKeyCharacteristics(const String16& name, const hidl_vec<uint8_t>& clientId,
+                                       const hidl_vec<uint8_t>& appData, int32_t uid,
+                                       KeyCharacteristics* outCharacteristics) {
     if (!outCharacteristics) {
-        return KM_ERROR_UNEXPECTED_NULL_POINTER;
+        return ErrorCode::UNEXPECTED_NULL_POINTER;
     }
 
     uid_t targetUid = getEffectiveUid(uid);
@@ -718,330 +793,368 @@
     if (!is_granted_to(callingUid, targetUid)) {
         ALOGW("uid %d not permitted to act for uid %d in getKeyCharacteristics", callingUid,
               targetUid);
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     Blob keyBlob;
     String8 name8(name);
-    int rc;
 
-    ResponseCode responseCode =
+    KeyStoreServiceReturnCode rc =
         mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
-    if (responseCode != ::NO_ERROR) {
-        return responseCode;
+    if (!rc.isOk()) {
+        return rc;
     }
-    keymaster_key_blob_t key = {keyBlob.getValue(), static_cast<size_t>(keyBlob.getLength())};
-    auto* dev = mKeyStore->getDeviceForBlob(keyBlob);
-    keymaster_key_characteristics_t out = {};
-    if (!dev->get_key_characteristics) {
-        ALOGE("device does not implement get_key_characteristics");
-        return KM_ERROR_UNIMPLEMENTED;
-    }
-    rc = dev->get_key_characteristics(dev, &key, clientId, appData, &out);
-    if (rc == KM_ERROR_KEY_REQUIRES_UPGRADE) {
-        AuthorizationSet upgradeParams;
-        if (clientId && clientId->data && clientId->data_length) {
-            upgradeParams.push_back(TAG_APPLICATION_ID, *clientId);
+
+    auto hidlKeyBlob = blob2hidlVec(keyBlob);
+    auto& dev = mKeyStore->getDevice(keyBlob);
+
+    KeyStoreServiceReturnCode error;
+
+    auto hidlCb = [&](ErrorCode ret, const KeyCharacteristics& keyCharacteristics) {
+        error = ret;
+        if (!error.isOk()) {
+            return;
         }
-        if (appData && appData->data && appData->data_length) {
-            upgradeParams.push_back(TAG_APPLICATION_DATA, *appData);
+        *outCharacteristics = keyCharacteristics;
+    };
+
+    rc = KS_HANDLE_HIDL_ERROR(dev->getKeyCharacteristics(hidlKeyBlob, clientId, appData, hidlCb));
+    if (!rc.isOk()) {
+        return rc;
+    }
+
+    if (error == ErrorCode::KEY_REQUIRES_UPGRADE) {
+        AuthorizationSet upgradeParams;
+        if (clientId.size()) {
+            upgradeParams.push_back(TAG_APPLICATION_ID, clientId);
+        }
+        if (appData.size()) {
+            upgradeParams.push_back(TAG_APPLICATION_DATA, appData);
         }
         rc = upgradeKeyBlob(name, targetUid, upgradeParams, &keyBlob);
-        if (rc != ::NO_ERROR) {
+        if (!rc.isOk()) {
             return rc;
         }
-        key = {keyBlob.getValue(), static_cast<size_t>(keyBlob.getLength())};
-        rc = dev->get_key_characteristics(dev, &key, clientId, appData, &out);
-    }
-    if (rc != KM_ERROR_OK) {
-        return rc;
-    }
 
-    outCharacteristics->characteristics = out;
-    return ::NO_ERROR;
+        auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
+
+        rc = KS_HANDLE_HIDL_ERROR(
+            dev->getKeyCharacteristics(upgradedHidlKeyBlob, clientId, appData, hidlCb));
+        if (!rc.isOk()) {
+            return rc;
+        }
+        // Note that, on success, "error" will have been updated by the hidlCB callback.
+        // So it is fine to return "error" below.
+    }
+    return error;
 }
 
-int32_t KeyStoreService::importKey(const String16& name, const KeymasterArguments& params,
-                                   keymaster_key_format_t format, const uint8_t* keyData,
-                                   size_t keyLength, int uid, int flags,
-                                   KeyCharacteristics* outCharacteristics) {
+KeyStoreServiceReturnCode
+KeyStoreService::importKey(const String16& name, const hidl_vec<KeyParameter>& params,
+                           KeyFormat format, const hidl_vec<uint8_t>& keyData, int uid, int flags,
+                           KeyCharacteristics* outCharacteristics) {
     uid = getEffectiveUid(uid);
-    int rc = checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (rc != ::NO_ERROR) {
+    KeyStoreServiceReturnCode rc =
+        checkBinderPermissionAndKeystoreState(P_INSERT, uid, flags & KEYSTORE_FLAG_ENCRYPTED);
+    if (!rc.isOk()) {
         return rc;
     }
-
-    rc = KM_ERROR_UNIMPLEMENTED;
-    bool isFallback = false;
-    keymaster_key_blob_t blob;
-    keymaster_key_characteristics_t out = {{nullptr, 0}, {nullptr, 0}};
-
-    const auto* device = mKeyStore->getDevice();
-    const auto* fallback = mKeyStore->getFallbackDevice();
-    std::vector<keymaster_key_param_t> opParams(params.params);
-    const keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()};
-    const keymaster_blob_t input = {keyData, keyLength};
-    if (device == NULL) {
-        return ::SYSTEM_ERROR;
+    if ((flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION) && get_app_id(uid) != AID_SYSTEM) {
+        ALOGE("Non-system uid %d cannot set FLAG_CRITICAL_TO_DEVICE_ENCRYPTION", uid);
+        return ResponseCode::PERMISSION_DENIED;
     }
 
-    // Capture characteristics before they're potentially stripped
-    AuthorizationSet keyCharacteristics(opParams.data(), opParams.size());
-    if (keyCharacteristics.is_valid() != AuthorizationSet::Error::OK) {
-        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
-    }
-    UniquePtr<uint8_t[]> kc_buf;
-    kc_buf.reset(new (std::nothrow) uint8_t[keyCharacteristics.SerializedSize()]);
-    if (!kc_buf.get()) {
-        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
-    }
-    keyCharacteristics.Serialize(kc_buf.get(), kc_buf.get() + keyCharacteristics.SerializedSize());
+    bool usingFallback = false;
+    auto& dev = mKeyStore->getDevice();
 
-    if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 &&
-        device->import_key != NULL) {
-        rc = device->import_key(device, &inParams, format, &input, &blob,
-                                outCharacteristics ? &out : nullptr);
-    }
-    if (rc && fallback->import_key != NULL) {
-        ALOGW("Primary keymaster device failed to import key, falling back to SW.");
-        isFallback = true;
-        rc = fallback->import_key(fallback, &inParams, format, &input, &blob,
-                                  outCharacteristics ? &out : nullptr);
-    }
-    if (outCharacteristics) {
-        outCharacteristics->characteristics = out;
-    }
-
-    if (rc) {
-        return rc;
-    }
-
-    // Write the key:
     String8 name8(name);
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
 
-    Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10);
-    keyBlob.setFallback(isFallback);
-    keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
+    KeyStoreServiceReturnCode error;
 
-    free(const_cast<uint8_t*>(blob.key_material));
-    rc = mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
+    auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
+                      const KeyCharacteristics& keyCharacteristics) {
+        error = ret;
+        if (!error.isOk()) {
+            return;
+        }
 
-    if (rc != ::NO_ERROR) {
+        if (outCharacteristics) *outCharacteristics = keyCharacteristics;
+
+        // Write the key:
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
+
+        Blob ksBlob(&keyBlob[0], keyBlob.size(), NULL, 0, ::TYPE_KEYMASTER_10);
+        ksBlob.setFallback(usingFallback);
+        ksBlob.setCriticalToDeviceEncryption(flags & KEYSTORE_FLAG_CRITICAL_TO_DEVICE_ENCRYPTION);
+        if (isAuthenticationBound(params) && !ksBlob.isCriticalToDeviceEncryption()) {
+            ksBlob.setSuperEncrypted(true);
+        }
+        ksBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
+
+        error = mKeyStore->put(filename.string(), &ksBlob, get_user_id(uid));
+    };
+
+    rc = KS_HANDLE_HIDL_ERROR(dev->importKey(params, format, keyData, hidlCb));
+    // possible hidl error
+    if (!rc.isOk()) {
         return rc;
     }
+    // now check error from callback
+    if (!error.isOk()) {
+        ALOGE("Failed to import key -> falling back to software keymaster");
+        usingFallback = true;
+        auto fallback = mKeyStore->getFallbackDevice();
+        if (!fallback.isOk()) {
+            return error;
+        }
+        rc = KS_HANDLE_HIDL_ERROR(fallback.value()->importKey(params, format, keyData, hidlCb));
+        // possible hidl error
+        if (!rc.isOk()) {
+            return rc;
+        }
+        // now check error from callback
+        if (!error.isOk()) {
+            return error;
+        }
+    }
 
     // Write the characteristics:
     String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
 
-    Blob charBlob(kc_buf.get(), keyCharacteristics.SerializedSize(),
-        NULL, 0, ::TYPE_KEY_CHARACTERISTICS);
-    charBlob.setFallback(isFallback);
+    AuthorizationSet opParams = params;
+    std::stringstream kcStream;
+    opParams.Serialize(&kcStream);
+    if (kcStream.bad()) return ResponseCode::SYSTEM_ERROR;
+    auto kcBuf = kcStream.str();
+
+    Blob charBlob(reinterpret_cast<const uint8_t*>(kcBuf.data()), kcBuf.size(), NULL, 0,
+                  ::TYPE_KEY_CHARACTERISTICS);
+    charBlob.setFallback(usingFallback);
     charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
 
     return mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid));
 }
 
-void KeyStoreService::exportKey(const String16& name, keymaster_key_format_t format,
-                                const keymaster_blob_t* clientId, const keymaster_blob_t* appData,
+void KeyStoreService::exportKey(const String16& name, KeyFormat format,
+                                const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
                                 int32_t uid, ExportResult* result) {
 
     uid_t targetUid = getEffectiveUid(uid);
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     if (!is_granted_to(callingUid, targetUid)) {
         ALOGW("uid %d not permitted to act for uid %d in exportKey", callingUid, targetUid);
-        result->resultCode = ::PERMISSION_DENIED;
+        result->resultCode = ResponseCode::PERMISSION_DENIED;
         return;
     }
 
     Blob keyBlob;
     String8 name8(name);
-    int rc;
 
-    ResponseCode responseCode =
-        mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
-    if (responseCode != ::NO_ERROR) {
-        result->resultCode = responseCode;
+    result->resultCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
+    if (!result->resultCode.isOk()) {
         return;
     }
-    keymaster_key_blob_t key;
-    key.key_material_size = keyBlob.getLength();
-    key.key_material = keyBlob.getValue();
-    auto* dev = mKeyStore->getDeviceForBlob(keyBlob);
-    if (!dev->export_key) {
-        result->resultCode = KM_ERROR_UNIMPLEMENTED;
-        return;
-    }
-    keymaster_blob_t output = {NULL, 0};
-    rc = dev->export_key(dev, format, &key, clientId, appData, &output);
-    if (rc == KM_ERROR_KEY_REQUIRES_UPGRADE) {
-        AuthorizationSet upgradeParams;
-        if (clientId && clientId->data && clientId->data_length) {
-            upgradeParams.push_back(TAG_APPLICATION_ID, *clientId);
-        }
-        if (appData && appData->data && appData->data_length) {
-            upgradeParams.push_back(TAG_APPLICATION_DATA, *appData);
-        }
-        rc = upgradeKeyBlob(name, targetUid, upgradeParams, &keyBlob);
-        if (rc != ::NO_ERROR) {
-            result->resultCode = rc;
+
+    auto key = blob2hidlVec(keyBlob);
+    auto& dev = mKeyStore->getDevice(keyBlob);
+
+    auto hidlCb = [&](ErrorCode ret, const ::android::hardware::hidl_vec<uint8_t>& keyMaterial) {
+        result->resultCode = ret;
+        if (!result->resultCode.isOk()) {
             return;
         }
-        key = {keyBlob.getValue(), static_cast<size_t>(keyBlob.getLength())};
-        rc = dev->export_key(dev, format, &key, clientId, appData, &output);
+        result->exportData = keyMaterial;
+    };
+    KeyStoreServiceReturnCode rc =
+        KS_HANDLE_HIDL_ERROR(dev->exportKey(format, key, clientId, appData, hidlCb));
+    // Overwrite result->resultCode only on HIDL error. Otherwise we want the result set in the
+    // callback hidlCb.
+    if (!rc.isOk()) {
+        result->resultCode = rc;
     }
 
-    result->exportData.reset(const_cast<uint8_t*>(output.data));
-    result->dataLength = output.data_length;
-    result->resultCode = rc ? rc : ::NO_ERROR;
+    if (result->resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
+        AuthorizationSet upgradeParams;
+        if (clientId.size()) {
+            upgradeParams.push_back(TAG_APPLICATION_ID, clientId);
+        }
+        if (appData.size()) {
+            upgradeParams.push_back(TAG_APPLICATION_DATA, appData);
+        }
+        result->resultCode = upgradeKeyBlob(name, targetUid, upgradeParams, &keyBlob);
+        if (!result->resultCode.isOk()) {
+            return;
+        }
+
+        auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
+
+        result->resultCode = KS_HANDLE_HIDL_ERROR(
+            dev->exportKey(format, upgradedHidlKeyBlob, clientId, appData, hidlCb));
+        if (!result->resultCode.isOk()) {
+            return;
+        }
+    }
 }
 
-void KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name,
-                            keymaster_purpose_t purpose, bool pruneable,
-                            const KeymasterArguments& params, const uint8_t* entropy,
-                            size_t entropyLength, int32_t uid, OperationResult* result) {
+static inline void addAuthTokenToParams(AuthorizationSet* params, const HardwareAuthToken* token) {
+    if (token) {
+        params->push_back(TAG_AUTH_TOKEN, authToken2HidlVec(*token));
+    }
+}
+
+void KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name, KeyPurpose purpose,
+                            bool pruneable, const hidl_vec<KeyParameter>& params,
+                            const hidl_vec<uint8_t>& entropy, int32_t uid,
+                            OperationResult* result) {
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     uid_t targetUid = getEffectiveUid(uid);
     if (!is_granted_to(callingUid, targetUid)) {
         ALOGW("uid %d not permitted to act for uid %d in begin", callingUid, targetUid);
-        result->resultCode = ::PERMISSION_DENIED;
+        result->resultCode = ResponseCode::PERMISSION_DENIED;
         return;
     }
     if (!pruneable && get_app_id(callingUid) != AID_SYSTEM) {
         ALOGE("Non-system uid %d trying to start non-pruneable operation", callingUid);
-        result->resultCode = ::PERMISSION_DENIED;
+        result->resultCode = ResponseCode::PERMISSION_DENIED;
         return;
     }
-    if (!checkAllowedOperationParams(params.params)) {
-        result->resultCode = KM_ERROR_INVALID_ARGUMENT;
+    if (!checkAllowedOperationParams(params)) {
+        result->resultCode = ErrorCode::INVALID_ARGUMENT;
         return;
     }
     Blob keyBlob;
     String8 name8(name);
-    ResponseCode responseCode =
-        mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
-    if (responseCode != ::NO_ERROR) {
-        result->resultCode = responseCode;
+    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;
     }
-    keymaster_key_blob_t key;
-    key.key_material_size = keyBlob.getLength();
-    key.key_material = keyBlob.getValue();
-    keymaster_operation_handle_t handle;
-    auto* dev = mKeyStore->getDeviceForBlob(keyBlob);
-    keymaster_error_t err = KM_ERROR_UNIMPLEMENTED;
-    std::vector<keymaster_key_param_t> opParams(params.params);
-    Unique_keymaster_key_characteristics characteristics;
-    characteristics.reset(new keymaster_key_characteristics_t);
-    err = getOperationCharacteristics(key, dev, opParams, characteristics.get());
-    if (err == KM_ERROR_KEY_REQUIRES_UPGRADE) {
-        int32_t rc = upgradeKeyBlob(name, targetUid,
-                                    AuthorizationSet(opParams.data(), opParams.size()), &keyBlob);
-        if (rc != ::NO_ERROR) {
-            result->resultCode = rc;
+
+    auto key = blob2hidlVec(keyBlob);
+    auto& dev = mKeyStore->getDevice(keyBlob);
+    AuthorizationSet opParams = params;
+    KeyCharacteristics characteristics;
+    result->resultCode = getOperationCharacteristics(key, &dev, opParams, &characteristics);
+
+    if (result->resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
+        result->resultCode = upgradeKeyBlob(name, targetUid, opParams, &keyBlob);
+        if (!result->resultCode.isOk()) {
             return;
         }
-        key = {keyBlob.getValue(), static_cast<size_t>(keyBlob.getLength())};
-        err = getOperationCharacteristics(key, dev, opParams, characteristics.get());
+        key = blob2hidlVec(keyBlob);
+        result->resultCode = getOperationCharacteristics(key, &dev, opParams, &characteristics);
     }
-    if (err) {
-        result->resultCode = err;
+    if (!result->resultCode.isOk()) {
         return;
     }
-    const hw_auth_token_t* authToken = NULL;
+
+    const HardwareAuthToken* authToken = NULL;
 
     // Merge these characteristics with the ones cached when the key was generated or imported
     Blob charBlob;
     AuthorizationSet persistedCharacteristics;
-    responseCode = mKeyStore->getKeyForName(&charBlob, name8, targetUid, TYPE_KEY_CHARACTERISTICS);
-    if (responseCode == ::NO_ERROR) {
-        const uint8_t* serializedCharacteristics = charBlob.getValue();
-        persistedCharacteristics.Deserialize(&serializedCharacteristics,
-            serializedCharacteristics + charBlob.getLength());
+    result->resultCode =
+        mKeyStore->getKeyForName(&charBlob, name8, targetUid, TYPE_KEY_CHARACTERISTICS);
+    if (result->resultCode.isOk()) {
+        // TODO write one shot stream buffer to avoid copying (twice here)
+        std::string charBuffer(reinterpret_cast<const char*>(charBlob.getValue()),
+                               charBlob.getLength());
+        std::stringstream charStream(charBuffer);
+        persistedCharacteristics.Deserialize(&charStream);
     } else {
         ALOGD("Unable to read cached characteristics for key");
     }
 
     // Replace the sw_enforced set with those persisted to disk, minus hw_enforced
-    persistedCharacteristics.Union(characteristics.get()->sw_enforced);
-    persistedCharacteristics.Difference(characteristics.get()->hw_enforced);
-    persistedCharacteristics.CopyToParamSet(&characteristics.get()->sw_enforced);
+    AuthorizationSet softwareEnforced = characteristics.softwareEnforced;
+    AuthorizationSet teeEnforced = characteristics.teeEnforced;
+    persistedCharacteristics.Union(softwareEnforced);
+    persistedCharacteristics.Subtract(teeEnforced);
+    characteristics.softwareEnforced = persistedCharacteristics.hidl_data();
 
-    int32_t authResult = getAuthToken(characteristics.get(), 0, purpose, &authToken,
+    result->resultCode = getAuthToken(characteristics, 0, purpose, &authToken,
                                       /*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.
-    if (authResult != ::NO_ERROR && authResult != ::OP_AUTH_NEEDED) {
-        result->resultCode = authResult;
-        return;
-    }
-    addAuthToParams(&opParams, authToken);
+    if (!result->resultCode.isOk() && result->resultCode != ResponseCode::OP_AUTH_NEEDED) return;
+
+    addAuthTokenToParams(&opParams, authToken);
+
     // Add entropy to the device first.
-    if (entropy) {
-        if (dev->add_rng_entropy) {
-            err = dev->add_rng_entropy(dev, entropy, entropyLength);
-        } else {
-            err = KM_ERROR_UNIMPLEMENTED;
-        }
-        if (err) {
-            result->resultCode = err;
+    if (entropy.size()) {
+        result->resultCode = addRngEntropy(entropy);
+        if (!result->resultCode.isOk()) {
             return;
         }
     }
-    keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()};
 
     // Create a keyid for this key.
-    keymaster::km_id_t keyid;
+    km_id_t keyid;
     if (!enforcement_policy.CreateKeyId(key, &keyid)) {
         ALOGE("Failed to create a key ID for authorization checking.");
-        result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+        result->resultCode = ErrorCode::UNKNOWN_ERROR;
         return;
     }
 
     // Check that all key authorization policy requirements are met.
-    keymaster::AuthorizationSet key_auths(characteristics->hw_enforced);
-    key_auths.push_back(characteristics->sw_enforced);
-    keymaster::AuthorizationSet operation_params(inParams);
-    err = enforcement_policy.AuthorizeOperation(purpose, keyid, key_auths, operation_params,
-                                                0 /* op_handle */, true /* is_begin_operation */);
-    if (err) {
-        result->resultCode = err;
+    AuthorizationSet key_auths = characteristics.teeEnforced;
+    key_auths.append(&characteristics.softwareEnforced[0],
+                     &characteristics.softwareEnforced[characteristics.softwareEnforced.size()]);
+
+    result->resultCode = enforcement_policy.AuthorizeOperation(
+        purpose, keyid, key_auths, opParams, 0 /* op_handle */, true /* is_begin_operation */);
+    if (!result->resultCode.isOk()) {
         return;
     }
 
-    keymaster_key_param_set_t outParams = {NULL, 0};
-
-    // If there are more than MAX_OPERATIONS, abort the oldest operation that was started as
+    // If there are more than kMaxOperations, abort the oldest operation that was started as
     // pruneable.
-    while (mOperationMap.getOperationCount() >= MAX_OPERATIONS) {
+    while (mOperationMap.getOperationCount() >= kMaxOperations) {
         ALOGD("Reached or exceeded concurrent operations limit");
         if (!pruneOperation()) {
             break;
         }
     }
 
-    err = dev->begin(dev, purpose, &key, &inParams, &outParams, &handle);
-    if (err != KM_ERROR_OK) {
-        ALOGE("Got error %d from begin()", err);
+    auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
+                      uint64_t operationHandle) {
+        result->resultCode = ret;
+        if (!result->resultCode.isOk()) {
+            return;
+        }
+        result->handle = operationHandle;
+        result->outParams = outParams;
+    };
+
+    ErrorCode rc = KS_HANDLE_HIDL_ERROR(dev->begin(purpose, key, opParams.hidl_data(), hidlCb));
+    if (rc != ErrorCode::OK) {
+        ALOGW("Got error %d from begin()", rc);
     }
 
     // If there are too many operations abort the oldest operation that was
     // started as pruneable and try again.
-    while (err == KM_ERROR_TOO_MANY_OPERATIONS && mOperationMap.hasPruneableOperation()) {
-        ALOGE("Ran out of operation handles");
+    while (rc == ErrorCode::TOO_MANY_OPERATIONS && mOperationMap.hasPruneableOperation()) {
+        ALOGW("Ran out of operation handles");
         if (!pruneOperation()) {
             break;
         }
-        err = dev->begin(dev, purpose, &key, &inParams, &outParams, &handle);
+        rc = KS_HANDLE_HIDL_ERROR(dev->begin(purpose, key, opParams.hidl_data(), hidlCb));
     }
-    if (err) {
-        result->resultCode = err;
+    if (rc != ErrorCode::OK) {
+        result->resultCode = rc;
         return;
     }
 
-    sp<IBinder> operationToken = mOperationMap.addOperation(handle, keyid, purpose, dev, appToken,
-                                                            characteristics.release(), pruneable);
+    // 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, purpose, dev, appToken, std::move(characteristics), pruneable);
+    assert(characteristics.teeEnforced.size() == 0);
+    assert(characteristics.softwareEnforced.size() == 0);
+
     if (authToken) {
         mOperationMap.setOperationAuthToken(operationToken, authToken);
     }
@@ -1050,224 +1163,343 @@
     // application should get an auth token using the handle before the
     // first call to update, which will fail if keystore hasn't received the
     // auth token.
-    result->resultCode = authResult;
+    // All fields but "token" were set in the begin operation's callback.
     result->token = operationToken;
-    result->handle = handle;
-    if (outParams.params) {
-        result->outParams.params.assign(outParams.params, outParams.params + outParams.length);
-        free(outParams.params);
-    }
 }
 
-void KeyStoreService::update(const sp<IBinder>& token, const KeymasterArguments& params,
-                             const uint8_t* data, size_t dataLength, OperationResult* result) {
-    if (!checkAllowedOperationParams(params.params)) {
-        result->resultCode = KM_ERROR_INVALID_ARGUMENT;
+void KeyStoreService::update(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
+                             const hidl_vec<uint8_t>& data, OperationResult* result) {
+    if (!checkAllowedOperationParams(params)) {
+        result->resultCode = ErrorCode::INVALID_ARGUMENT;
         return;
     }
-    const keymaster2_device_t* dev;
-    keymaster_operation_handle_t handle;
-    keymaster_purpose_t purpose;
-    keymaster::km_id_t keyid;
-    const keymaster_key_characteristics_t* characteristics;
+    km_device_t dev;
+    uint64_t handle;
+    KeyPurpose purpose;
+    km_id_t keyid;
+    const KeyCharacteristics* characteristics;
     if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
-        result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE;
+        result->resultCode = ErrorCode::INVALID_OPERATION_HANDLE;
         return;
     }
-    std::vector<keymaster_key_param_t> opParams(params.params);
-    int32_t authResult = addOperationAuthTokenIfNeeded(token, &opParams);
-    if (authResult != ::NO_ERROR) {
-        result->resultCode = authResult;
+    AuthorizationSet opParams = params;
+    result->resultCode = addOperationAuthTokenIfNeeded(token, &opParams);
+    if (!result->resultCode.isOk()) {
         return;
     }
-    keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()};
-    keymaster_blob_t input = {data, dataLength};
-    size_t consumed = 0;
-    keymaster_blob_t output = {NULL, 0};
-    keymaster_key_param_set_t outParams = {NULL, 0};
 
     // Check that all key authorization policy requirements are met.
-    keymaster::AuthorizationSet key_auths(characteristics->hw_enforced);
-    key_auths.push_back(characteristics->sw_enforced);
-    keymaster::AuthorizationSet operation_params(inParams);
+    AuthorizationSet key_auths(characteristics->teeEnforced);
+    key_auths.append(&characteristics->softwareEnforced[0],
+                     &characteristics->softwareEnforced[characteristics->softwareEnforced.size()]);
     result->resultCode = enforcement_policy.AuthorizeOperation(
-        purpose, keyid, key_auths, operation_params, handle, false /* is_begin_operation */);
-    if (result->resultCode) {
+        purpose, keyid, key_auths, opParams, handle, false /* is_begin_operation */);
+    if (!result->resultCode.isOk()) {
         return;
     }
 
-    keymaster_error_t err =
-        dev->update(dev, handle, &inParams, &input, &consumed, &outParams, &output);
-    result->data.reset(const_cast<uint8_t*>(output.data));
-    result->dataLength = output.data_length;
-    result->inputConsumed = consumed;
-    result->resultCode = err ? (int32_t)err : ::NO_ERROR;
-    if (outParams.params) {
-        result->outParams.params.assign(outParams.params, outParams.params + outParams.length);
-        free(outParams.params);
+    auto hidlCb = [&](ErrorCode ret, uint32_t inputConsumed,
+                      const hidl_vec<KeyParameter>& outParams, const hidl_vec<uint8_t>& output) {
+        result->resultCode = ret;
+        if (!result->resultCode.isOk()) {
+            return;
+        }
+        result->inputConsumed = inputConsumed;
+        result->outParams = outParams;
+        result->data = output;
+    };
+
+    KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(dev->update(handle, opParams.hidl_data(),
+                                                        data, 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.
+    if (!rc.isOk()) {
+        result->resultCode = rc;
     }
 }
 
-void KeyStoreService::finish(const sp<IBinder>& token, const KeymasterArguments& params,
-                             const uint8_t* signature, size_t signatureLength,
-                             const uint8_t* entropy, size_t entropyLength,
+void KeyStoreService::finish(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
+                             const hidl_vec<uint8_t>& signature, const hidl_vec<uint8_t>& entropy,
                              OperationResult* result) {
-    if (!checkAllowedOperationParams(params.params)) {
-        result->resultCode = KM_ERROR_INVALID_ARGUMENT;
+    if (!checkAllowedOperationParams(params)) {
+        result->resultCode = ErrorCode::INVALID_ARGUMENT;
         return;
     }
-    const keymaster2_device_t* dev;
-    keymaster_operation_handle_t handle;
-    keymaster_purpose_t purpose;
-    keymaster::km_id_t keyid;
-    const keymaster_key_characteristics_t* characteristics;
+    km_device_t dev;
+    uint64_t handle;
+    KeyPurpose purpose;
+    km_id_t keyid;
+    const KeyCharacteristics* characteristics;
     if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
-        result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE;
+        result->resultCode = ErrorCode::INVALID_OPERATION_HANDLE;
         return;
     }
-    std::vector<keymaster_key_param_t> opParams(params.params);
-    int32_t authResult = addOperationAuthTokenIfNeeded(token, &opParams);
-    if (authResult != ::NO_ERROR) {
-        result->resultCode = authResult;
+    AuthorizationSet opParams = params;
+    result->resultCode = addOperationAuthTokenIfNeeded(token, &opParams);
+    if (!result->resultCode.isOk()) {
         return;
     }
-    keymaster_error_t err;
-    if (entropy) {
-        if (dev->add_rng_entropy) {
-            err = dev->add_rng_entropy(dev, entropy, entropyLength);
-        } else {
-            err = KM_ERROR_UNIMPLEMENTED;
-        }
-        if (err) {
-            result->resultCode = err;
+
+    if (entropy.size()) {
+        result->resultCode = addRngEntropy(entropy);
+        if (!result->resultCode.isOk()) {
             return;
         }
     }
 
-    keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()};
-    keymaster_blob_t input = {nullptr, 0};
-    keymaster_blob_t sig = {signature, signatureLength};
-    keymaster_blob_t output = {nullptr, 0};
-    keymaster_key_param_set_t outParams = {nullptr, 0};
-
     // Check that all key authorization policy requirements are met.
-    keymaster::AuthorizationSet key_auths(characteristics->hw_enforced);
-    key_auths.push_back(characteristics->sw_enforced);
-    keymaster::AuthorizationSet operation_params(inParams);
-    err = enforcement_policy.AuthorizeOperation(purpose, keyid, key_auths, operation_params, handle,
-                                                false /* is_begin_operation */);
-    if (err) {
-        result->resultCode = err;
-        return;
-    }
+    AuthorizationSet key_auths(characteristics->teeEnforced);
+    key_auths.append(&characteristics->softwareEnforced[0],
+                     &characteristics->softwareEnforced[characteristics->softwareEnforced.size()]);
+    result->resultCode = enforcement_policy.AuthorizeOperation(
+        purpose, keyid, key_auths, opParams, handle, false /* is_begin_operation */);
+    if (!result->resultCode.isOk()) return;
 
-    err =
-        dev->finish(dev, handle, &inParams, &input /* TODO(swillden): wire up input to finish() */,
-                    &sig, &outParams, &output);
+    auto hidlCb = [&](ErrorCode ret, const hidl_vec<KeyParameter>& outParams,
+                      const hidl_vec<uint8_t>& output) {
+        result->resultCode = ret;
+        if (!result->resultCode.isOk()) {
+            return;
+        }
+        result->outParams = outParams;
+        result->data = output;
+    };
+
+    KeyStoreServiceReturnCode rc = KS_HANDLE_HIDL_ERROR(dev->finish(
+        handle, opParams.hidl_data(),
+        hidl_vec<uint8_t>() /* TODO(swillden): wire up input to finish() */, signature, hidlCb));
     // Remove the operation regardless of the result
     mOperationMap.removeOperation(token);
     mAuthTokenTable.MarkCompleted(handle);
 
-    result->data.reset(const_cast<uint8_t*>(output.data));
-    result->dataLength = output.data_length;
-    result->resultCode = err ? (int32_t)err : ::NO_ERROR;
-    if (outParams.params) {
-        result->outParams.params.assign(outParams.params, outParams.params + outParams.length);
-        free(outParams.params);
+    // 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.
+    if (!rc.isOk()) {
+        result->resultCode = rc;
     }
 }
 
-int32_t KeyStoreService::abort(const sp<IBinder>& token) {
-    const keymaster2_device_t* dev;
-    keymaster_operation_handle_t handle;
-    keymaster_purpose_t purpose;
-    keymaster::km_id_t keyid;
+KeyStoreServiceReturnCode KeyStoreService::abort(const sp<IBinder>& token) {
+    km_device_t dev;
+    uint64_t handle;
+    KeyPurpose purpose;
+    km_id_t keyid;
     if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, NULL)) {
-        return KM_ERROR_INVALID_OPERATION_HANDLE;
+        return ErrorCode::INVALID_OPERATION_HANDLE;
     }
     mOperationMap.removeOperation(token);
-    int32_t rc;
-    if (!dev->abort) {
-        rc = KM_ERROR_UNIMPLEMENTED;
-    } else {
-        rc = dev->abort(dev, handle);
-    }
+
+    ErrorCode rc = KS_HANDLE_HIDL_ERROR(dev->abort(handle));
     mAuthTokenTable.MarkCompleted(handle);
-    if (rc) {
-        return rc;
-    }
-    return ::NO_ERROR;
+    return rc;
 }
 
 bool KeyStoreService::isOperationAuthorized(const sp<IBinder>& token) {
-    const keymaster2_device_t* dev;
-    keymaster_operation_handle_t handle;
-    const keymaster_key_characteristics_t* characteristics;
-    keymaster_purpose_t purpose;
-    keymaster::km_id_t keyid;
+    km_device_t dev;
+    uint64_t handle;
+    const KeyCharacteristics* characteristics;
+    KeyPurpose purpose;
+    km_id_t keyid;
     if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
         return false;
     }
-    const hw_auth_token_t* authToken = NULL;
+    const HardwareAuthToken* authToken = NULL;
     mOperationMap.getOperationAuthToken(token, &authToken);
-    std::vector<keymaster_key_param_t> ignored;
-    int32_t authResult = addOperationAuthTokenIfNeeded(token, &ignored);
-    return authResult == ::NO_ERROR;
+    AuthorizationSet ignored;
+    auto authResult = addOperationAuthTokenIfNeeded(token, &ignored);
+    return authResult.isOk();
 }
 
-int32_t KeyStoreService::addAuthToken(const uint8_t* token, size_t length) {
+KeyStoreServiceReturnCode KeyStoreService::addAuthToken(const uint8_t* token, size_t length) {
+    // TODO(swillden): When gatekeeper and fingerprint are ready, this should be updated to
+    // receive a HardwareAuthToken, rather than an opaque byte array.
+
     if (!checkBinderPermission(P_ADD_AUTH)) {
         ALOGW("addAuthToken: permission denied for %d", IPCThreadState::self()->getCallingUid());
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
     if (length != sizeof(hw_auth_token_t)) {
-        return KM_ERROR_INVALID_ARGUMENT;
+        return ErrorCode::INVALID_ARGUMENT;
     }
-    hw_auth_token_t* authToken = new hw_auth_token_t;
-    memcpy(reinterpret_cast<void*>(authToken), token, sizeof(hw_auth_token_t));
+
+    hw_auth_token_t authToken;
+    memcpy(reinterpret_cast<void*>(&authToken), token, sizeof(hw_auth_token_t));
+    if (authToken.version != 0) {
+        return ErrorCode::INVALID_ARGUMENT;
+    }
+
+    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());
+
     // The table takes ownership of authToken.
-    mAuthTokenTable.AddAuthenticationToken(authToken);
-    return ::NO_ERROR;
+    mAuthTokenTable.AddAuthenticationToken(hidlAuthToken.release());
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::attestKey(const String16& name, const KeymasterArguments& params,
-                                   KeymasterCertificateChain* outChain) {
-    if (!outChain)
-        return KM_ERROR_OUTPUT_PARAMETER_NULL;
+bool isDeviceIdAttestationRequested(const hidl_vec<KeyParameter>& params) {
+    for (size_t i = 0; i < params.size(); ++i) {
+        switch (params[i].tag) {
+        case Tag::ATTESTATION_ID_BRAND:
+        case Tag::ATTESTATION_ID_DEVICE:
+        case Tag::ATTESTATION_ID_IMEI:
+        case Tag::ATTESTATION_ID_MANUFACTURER:
+        case Tag::ATTESTATION_ID_MEID:
+        case Tag::ATTESTATION_ID_MODEL:
+        case Tag::ATTESTATION_ID_PRODUCT:
+        case Tag::ATTESTATION_ID_SERIAL:
+            return true;
+        default:
+            break;
+        }
+    }
+    return false;
+}
 
-    if (!checkAllowedOperationParams(params.params)) {
-        return KM_ERROR_INVALID_ARGUMENT;
+KeyStoreServiceReturnCode KeyStoreService::attestKey(const String16& name,
+                                                     const hidl_vec<KeyParameter>& params,
+                                                     hidl_vec<hidl_vec<uint8_t>>* outChain) {
+    if (!outChain) {
+        return ErrorCode::OUTPUT_PARAMETER_NULL;
+    }
+
+    if (!checkAllowedOperationParams(params)) {
+        return ErrorCode::INVALID_ARGUMENT;
+    }
+
+    if (isDeviceIdAttestationRequested(params)) {
+        // There is a dedicated attestDeviceIds() method for device ID attestation.
+        return ErrorCode::INVALID_ARGUMENT;
     }
 
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
 
-    Blob keyBlob;
-    String8 name8(name);
-    ResponseCode responseCode =
-        mKeyStore->getKeyForName(&keyBlob, name8, callingUid, TYPE_KEYMASTER_10);
-    if (responseCode != ::NO_ERROR) {
-        return responseCode;
+    AuthorizationSet mutableParams = params;
+    KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
+    if (!rc.isOk()) {
+        return rc;
     }
 
-    keymaster_key_blob_t key = {keyBlob.getValue(),
-                                static_cast<size_t>(std::max(0, keyBlob.getLength()))};
-    auto* dev = mKeyStore->getDeviceForBlob(keyBlob);
-    if (!dev->attest_key)
-        return KM_ERROR_UNIMPLEMENTED;
-
-    const keymaster_key_param_set_t in_params = {
-        const_cast<keymaster_key_param_t*>(params.params.data()), params.params.size()};
-    outChain->chain = {nullptr, 0};
-    int32_t rc = dev->attest_key(dev, &key, &in_params, &outChain->chain);
-    if (rc)
+    Blob keyBlob;
+    String8 name8(name);
+    rc = mKeyStore->getKeyForName(&keyBlob, name8, callingUid, TYPE_KEYMASTER_10);
+    if (!rc.isOk()) {
         return rc;
-    return ::NO_ERROR;
+    }
+
+    KeyStoreServiceReturnCode error;
+    auto hidlCb = [&](ErrorCode ret, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
+        error = ret;
+        if (!error.isOk()) {
+            return;
+        }
+        if (outChain) *outChain = certChain;
+    };
+
+    auto hidlKey = blob2hidlVec(keyBlob);
+    auto& dev = mKeyStore->getDevice(keyBlob);
+    rc = KS_HANDLE_HIDL_ERROR(dev->attestKey(hidlKey, mutableParams.hidl_data(), hidlCb));
+    if (!rc.isOk()) {
+        return rc;
+    }
+    return error;
 }
 
-int32_t KeyStoreService::onDeviceOffBody() {
+KeyStoreServiceReturnCode KeyStoreService::attestDeviceIds(const hidl_vec<KeyParameter>& params,
+                                                           hidl_vec<hidl_vec<uint8_t>>* outChain) {
+    if (!outChain) {
+        return ErrorCode::OUTPUT_PARAMETER_NULL;
+    }
+
+    if (!checkAllowedOperationParams(params)) {
+        return ErrorCode::INVALID_ARGUMENT;
+    }
+
+    if (!isDeviceIdAttestationRequested(params)) {
+        // There is an attestKey() method for attesting keys without device ID attestation.
+        return ErrorCode::INVALID_ARGUMENT;
+    }
+
+    uid_t callingUid = IPCThreadState::self()->getCallingUid();
+    sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
+    if (binder == 0) {
+        return ErrorCode::CANNOT_ATTEST_IDS;
+    }
+    if (!interface_cast<IPermissionController>(binder)->checkPermission(
+            String16("android.permission.READ_PRIVILEGED_PHONE_STATE"),
+            IPCThreadState::self()->getCallingPid(), callingUid)) {
+        return ErrorCode::CANNOT_ATTEST_IDS;
+    }
+
+    AuthorizationSet mutableParams = params;
+    KeyStoreServiceReturnCode rc = updateParamsForAttestation(callingUid, &mutableParams);
+    if (!rc.isOk()) {
+        return rc;
+    }
+
+    // Generate temporary key.
+    auto& dev = mKeyStore->getDevice();
+    KeyStoreServiceReturnCode error;
+    hidl_vec<uint8_t> hidlKey;
+
+    AuthorizationSet keyCharacteristics;
+    keyCharacteristics.push_back(TAG_PURPOSE, KeyPurpose::VERIFY);
+    keyCharacteristics.push_back(TAG_ALGORITHM, Algorithm::EC);
+    keyCharacteristics.push_back(TAG_DIGEST, Digest::SHA_2_256);
+    keyCharacteristics.push_back(TAG_NO_AUTH_REQUIRED);
+    keyCharacteristics.push_back(TAG_EC_CURVE, EcCurve::P_256);
+    auto generateHidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& hidlKeyBlob,
+                              const KeyCharacteristics&) {
+        error = ret;
+        if (!error.isOk()) {
+            return;
+        }
+        hidlKey = hidlKeyBlob;
+    };
+
+    rc = KS_HANDLE_HIDL_ERROR(dev->generateKey(keyCharacteristics.hidl_data(), generateHidlCb));
+    if (!rc.isOk()) {
+        return rc;
+    }
+    if (!error.isOk()) {
+        return error;
+    }
+
+    // Attest key and device IDs.
+    auto attestHidlCb = [&](ErrorCode ret, const hidl_vec<hidl_vec<uint8_t>>& certChain) {
+        error = ret;
+        if (!error.isOk()) {
+            return;
+        }
+        *outChain = certChain;
+    };
+    KeyStoreServiceReturnCode attestationRc =
+            KS_HANDLE_HIDL_ERROR(dev->attestKey(hidlKey, mutableParams.hidl_data(), attestHidlCb));
+
+    // Delete temporary key.
+    KeyStoreServiceReturnCode deletionRc = KS_HANDLE_HIDL_ERROR(dev->deleteKey(hidlKey));
+
+    if (!attestationRc.isOk()) {
+        return attestationRc;
+    }
+    if (!error.isOk()) {
+        return error;
+    }
+    return deletionRc;
+}
+
+KeyStoreServiceReturnCode KeyStoreService::onDeviceOffBody() {
     // TODO(tuckeris): add permission check.  This should be callable from ClockworkHome only.
     mAuthTokenTable.onDeviceOffBody();
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
 /**
@@ -1354,17 +1586,19 @@
  * otherwise the state of keystore when not unlocked and checkUnlocked is
  * true.
  */
-int32_t KeyStoreService::checkBinderPermissionAndKeystoreState(perm_t permission, int32_t targetUid,
-                                                               bool checkUnlocked) {
+KeyStoreServiceReturnCode
+KeyStoreService::checkBinderPermissionAndKeystoreState(perm_t permission, int32_t targetUid,
+                                                       bool checkUnlocked) {
     if (!checkBinderPermission(permission, targetUid)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
     State state = mKeyStore->getState(get_user_id(getEffectiveUid(targetUid)));
     if (checkUnlocked && !isKeystoreUnlocked(state)) {
-        return state;
+        // All State values coincide with ResponseCodes
+        return static_cast<ResponseCode>(state);
     }
 
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
 bool KeyStoreService::isKeystoreUnlocked(State state) {
@@ -1378,43 +1612,16 @@
     return false;
 }
 
-bool KeyStoreService::isKeyTypeSupported(const keymaster2_device_t* device,
-                                         keymaster_keypair_t keyType) {
-    const int32_t device_api = device->common.module->module_api_version;
-    if (device_api == KEYMASTER_MODULE_API_VERSION_0_2) {
-        switch (keyType) {
-        case TYPE_RSA:
-        case TYPE_DSA:
-        case TYPE_EC:
-            return true;
-        default:
-            return false;
-        }
-    } else if (device_api >= KEYMASTER_MODULE_API_VERSION_0_3) {
-        switch (keyType) {
-        case TYPE_RSA:
-            return true;
-        case TYPE_DSA:
-            return device->flags & KEYMASTER_SUPPORTS_DSA;
-        case TYPE_EC:
-            return device->flags & KEYMASTER_SUPPORTS_EC;
-        default:
-            return false;
-        }
-    } else {
-        return keyType == TYPE_RSA;
-    }
-}
-
 /**
- * Check that all keymaster_key_param_t's provided by the application are
+ * Check that all KeyParameter's provided by the application are
  * allowed. Any parameter that keystore adds itself should be disallowed here.
  */
-bool KeyStoreService::checkAllowedOperationParams(
-    const std::vector<keymaster_key_param_t>& params) {
-    for (auto param : params) {
-        switch (param.tag) {
-        case KM_TAG_AUTH_TOKEN:
+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:
             break;
@@ -1423,30 +1630,32 @@
     return true;
 }
 
-keymaster_error_t KeyStoreService::getOperationCharacteristics(
-    const keymaster_key_blob_t& key, const keymaster2_device_t* dev,
-    const std::vector<keymaster_key_param_t>& params, keymaster_key_characteristics_t* out) {
-    UniquePtr<keymaster_blob_t> appId;
-    UniquePtr<keymaster_blob_t> appData;
+ErrorCode KeyStoreService::getOperationCharacteristics(const hidl_vec<uint8_t>& key,
+                                                       km_device_t* dev,
+                                                       const AuthorizationSet& params,
+                                                       KeyCharacteristics* out) {
+    hidl_vec<uint8_t> appId;
+    hidl_vec<uint8_t> appData;
     for (auto param : params) {
-        if (param.tag == KM_TAG_APPLICATION_ID) {
-            appId.reset(new keymaster_blob_t);
-            appId->data = param.blob.data;
-            appId->data_length = param.blob.data_length;
-        } else if (param.tag == KM_TAG_APPLICATION_DATA) {
-            appData.reset(new keymaster_blob_t);
-            appData->data = param.blob.data;
-            appData->data_length = param.blob.data_length;
+        if (param.tag == Tag::APPLICATION_ID) {
+            appId = authorizationValue(TAG_APPLICATION_ID, param).value();
+        } else if (param.tag == Tag::APPLICATION_DATA) {
+            appData = authorizationValue(TAG_APPLICATION_DATA, param).value();
         }
     }
-    keymaster_key_characteristics_t result = {{nullptr, 0}, {nullptr, 0}};
-    if (!dev->get_key_characteristics) {
-        return KM_ERROR_UNIMPLEMENTED;
-    }
-    keymaster_error_t error =
-        dev->get_key_characteristics(dev, &key, appId.get(), appData.get(), &result);
-    if (error == KM_ERROR_OK) {
-        *out = result;
+    ErrorCode error = ErrorCode::OK;
+
+    auto hidlCb = [&](ErrorCode ret, const KeyCharacteristics& keyCharacteristics) {
+        error = ret;
+        if (error != ErrorCode::OK) {
+            return;
+        }
+        if (out) *out = keyCharacteristics;
+    };
+
+    ErrorCode rc = KS_HANDLE_HIDL_ERROR((*dev)->getKeyCharacteristics(key, appId, appData, hidlCb));
+    if (rc != ErrorCode::OK) {
+        return rc;
     }
     return error;
 }
@@ -1454,49 +1663,41 @@
 /**
  * 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.
+ * Returns ResponseCode::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
  */
-int32_t KeyStoreService::getAuthToken(const keymaster_key_characteristics_t* characteristics,
-                                      keymaster_operation_handle_t handle,
-                                      keymaster_purpose_t purpose,
-                                      const hw_auth_token_t** authToken, bool failOnTokenMissing) {
+KeyStoreServiceReturnCode KeyStoreService::getAuthToken(const KeyCharacteristics& characteristics,
+                                                        uint64_t handle, KeyPurpose purpose,
+                                                        const HardwareAuthToken** authToken,
+                                                        bool failOnTokenMissing) {
 
-    std::vector<keymaster_key_param_t> allCharacteristics;
-    for (size_t i = 0; i < characteristics->sw_enforced.length; i++) {
-        allCharacteristics.push_back(characteristics->sw_enforced.params[i]);
+    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->hw_enforced.length; i++) {
-        allCharacteristics.push_back(characteristics->hw_enforced.params[i]);
+    for (size_t i = 0; i < characteristics.teeEnforced.size(); i++) {
+        allCharacteristics.push_back(characteristics.teeEnforced[i]);
     }
-    keymaster::AuthTokenTable::Error err = mAuthTokenTable.FindAuthorization(
-        allCharacteristics.data(), allCharacteristics.size(), purpose, handle, authToken);
+    AuthTokenTable::Error err =
+        mAuthTokenTable.FindAuthorization(allCharacteristics, purpose, handle, authToken);
     switch (err) {
-    case keymaster::AuthTokenTable::OK:
-    case keymaster::AuthTokenTable::AUTH_NOT_REQUIRED:
-        return ::NO_ERROR;
-    case keymaster::AuthTokenTable::AUTH_TOKEN_NOT_FOUND:
-    case keymaster::AuthTokenTable::AUTH_TOKEN_EXPIRED:
-    case keymaster::AuthTokenTable::AUTH_TOKEN_WRONG_SID:
-        return KM_ERROR_KEY_USER_NOT_AUTHENTICATED;
-    case keymaster::AuthTokenTable::OP_HANDLE_REQUIRED:
-        return failOnTokenMissing ? (int32_t)KM_ERROR_KEY_USER_NOT_AUTHENTICATED
-                                  : (int32_t)::OP_AUTH_NEEDED;
+    case AuthTokenTable::OK:
+    case AuthTokenTable::AUTH_NOT_REQUIRED:
+        return ResponseCode::NO_ERROR;
+    case AuthTokenTable::AUTH_TOKEN_NOT_FOUND:
+    case AuthTokenTable::AUTH_TOKEN_EXPIRED:
+    case AuthTokenTable::AUTH_TOKEN_WRONG_SID:
+        return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
+    case AuthTokenTable::OP_HANDLE_REQUIRED:
+        return failOnTokenMissing ? KeyStoreServiceReturnCode(ErrorCode::KEY_USER_NOT_AUTHENTICATED)
+                                  : KeyStoreServiceReturnCode(ResponseCode::OP_AUTH_NEEDED);
     default:
         ALOGE("Unexpected FindAuthorization return value %d", err);
-        return KM_ERROR_INVALID_ARGUMENT;
-    }
-}
-
-inline void KeyStoreService::addAuthToParams(std::vector<keymaster_key_param_t>* params,
-                                             const hw_auth_token_t* token) {
-    if (token) {
-        params->push_back(keymaster_param_blob(
-            KM_TAG_AUTH_TOKEN, reinterpret_cast<const uint8_t*>(token), sizeof(hw_auth_token_t)));
+        return ErrorCode::INVALID_ARGUMENT;
     }
 }
 
@@ -1505,185 +1706,199 @@
  * 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.
+ * Returns ResponseCode::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.
  */
-int32_t KeyStoreService::addOperationAuthTokenIfNeeded(const sp<IBinder>& token,
-                                                       std::vector<keymaster_key_param_t>* params) {
-    const hw_auth_token_t* authToken = NULL;
+KeyStoreServiceReturnCode KeyStoreService::addOperationAuthTokenIfNeeded(const sp<IBinder>& token,
+                                                                         AuthorizationSet* params) {
+    const HardwareAuthToken* authToken = nullptr;
     mOperationMap.getOperationAuthToken(token, &authToken);
     if (!authToken) {
-        const keymaster2_device_t* dev;
-        keymaster_operation_handle_t handle;
-        const keymaster_key_characteristics_t* characteristics = NULL;
-        keymaster_purpose_t purpose;
-        keymaster::km_id_t keyid;
+        km_device_t dev;
+        uint64_t handle;
+        const KeyCharacteristics* characteristics = nullptr;
+        KeyPurpose purpose;
+        km_id_t keyid;
         if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
-            return KM_ERROR_INVALID_OPERATION_HANDLE;
+            return ErrorCode::INVALID_OPERATION_HANDLE;
         }
-        int32_t result = getAuthToken(characteristics, handle, purpose, &authToken);
-        if (result != ::NO_ERROR) {
+        auto result = getAuthToken(*characteristics, handle, purpose, &authToken);
+        if (!result.isOk()) {
             return result;
         }
         if (authToken) {
             mOperationMap.setOperationAuthToken(token, authToken);
         }
     }
-    addAuthToParams(params, authToken);
-    return ::NO_ERROR;
+    addAuthTokenToParams(params, authToken);
+    return ResponseCode::NO_ERROR;
 }
 
 /**
  * Translate a result value to a legacy return value. All keystore errors are
  * preserved and keymaster errors become SYSTEM_ERRORs
  */
-int32_t KeyStoreService::translateResultToLegacyResult(int32_t result) {
+KeyStoreServiceReturnCode KeyStoreService::translateResultToLegacyResult(int32_t result) {
     if (result > 0) {
-        return result;
+        return static_cast<ResponseCode>(result);
     }
-    return ::SYSTEM_ERROR;
+    return ResponseCode::SYSTEM_ERROR;
 }
 
-keymaster_key_param_t*
-KeyStoreService::getKeyAlgorithm(keymaster_key_characteristics_t* characteristics) {
-    for (size_t i = 0; i < characteristics->hw_enforced.length; i++) {
-        if (characteristics->hw_enforced.params[i].tag == KM_TAG_ALGORITHM) {
-            return &characteristics->hw_enforced.params[i];
-        }
+static NullOr<const Algorithm&>
+getKeyAlgoritmFromKeyCharacteristics(const KeyCharacteristics& characteristics) {
+    for (size_t i = 0; i < characteristics.teeEnforced.size(); ++i) {
+        auto algo = authorizationValue(TAG_ALGORITHM, characteristics.teeEnforced[i]);
+        if (algo.isOk()) return algo.value();
     }
-    for (size_t i = 0; i < characteristics->sw_enforced.length; i++) {
-        if (characteristics->sw_enforced.params[i].tag == KM_TAG_ALGORITHM) {
-            return &characteristics->sw_enforced.params[i];
-        }
+    for (size_t i = 0; i < characteristics.softwareEnforced.size(); ++i) {
+        auto algo = authorizationValue(TAG_ALGORITHM, characteristics.softwareEnforced[i]);
+        if (algo.isOk()) return algo.value();
     }
-    return NULL;
+    return {};
 }
 
-void KeyStoreService::addLegacyBeginParams(const String16& name,
-                                           std::vector<keymaster_key_param_t>& params) {
+void KeyStoreService::addLegacyBeginParams(const String16& name, AuthorizationSet* params) {
     // All legacy keys are DIGEST_NONE/PAD_NONE.
-    params.push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE));
-    params.push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE));
+    params->push_back(TAG_DIGEST, Digest::NONE);
+    params->push_back(TAG_PADDING, PaddingMode::NONE);
 
     // Look up the algorithm of the key.
     KeyCharacteristics characteristics;
-    int32_t rc = getKeyCharacteristics(name, NULL, NULL, UID_SELF, &characteristics);
-    if (rc != ::NO_ERROR) {
+    auto rc = getKeyCharacteristics(name, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(), UID_SELF,
+                                    &characteristics);
+    if (!rc.isOk()) {
         ALOGE("Failed to get key characteristics");
         return;
     }
-    keymaster_key_param_t* algorithm = getKeyAlgorithm(&characteristics.characteristics);
-    if (!algorithm) {
+    auto algorithm = getKeyAlgoritmFromKeyCharacteristics(characteristics);
+    if (!algorithm.isOk()) {
         ALOGE("getKeyCharacteristics did not include KM_TAG_ALGORITHM");
         return;
     }
-    params.push_back(*algorithm);
+    params->push_back(TAG_ALGORITHM, algorithm.value());
 }
 
-int32_t KeyStoreService::doLegacySignVerify(const String16& name, const uint8_t* data,
-                                            size_t length, uint8_t** out, size_t* outLength,
-                                            const uint8_t* signature, size_t signatureLength,
-                                            keymaster_purpose_t purpose) {
+KeyStoreServiceReturnCode KeyStoreService::doLegacySignVerify(const String16& name,
+                                                              const hidl_vec<uint8_t>& data,
+                                                              hidl_vec<uint8_t>* out,
+                                                              const hidl_vec<uint8_t>& signature,
+                                                              KeyPurpose purpose) {
 
     std::basic_stringstream<uint8_t> outBuffer;
     OperationResult result;
-    KeymasterArguments inArgs;
-    addLegacyBeginParams(name, inArgs.params);
+    AuthorizationSet inArgs;
+    addLegacyBeginParams(name, &inArgs);
     sp<IBinder> appToken(new BBinder);
     sp<IBinder> token;
 
-    begin(appToken, name, purpose, true, inArgs, NULL, 0, UID_SELF, &result);
-    if (result.resultCode != ResponseCode::NO_ERROR) {
-        if (result.resultCode == ::KEY_NOT_FOUND) {
+    begin(appToken, name, purpose, true, inArgs.hidl_data(), hidl_vec<uint8_t>(), UID_SELF,
+          &result);
+    if (!result.resultCode.isOk()) {
+        if (result.resultCode == ResponseCode::KEY_NOT_FOUND) {
             ALOGW("Key not found");
         } else {
-            ALOGW("Error in begin: %d", result.resultCode);
+            ALOGW("Error in begin: %d", int32_t(result.resultCode));
         }
         return translateResultToLegacyResult(result.resultCode);
     }
-    inArgs.params.clear();
+    inArgs.Clear();
     token = result.token;
     size_t consumed = 0;
     size_t lastConsumed = 0;
+    hidl_vec<uint8_t> data_view;
     do {
-        update(token, inArgs, data + consumed, length - consumed, &result);
+        data_view.setToExternal(const_cast<uint8_t*>(&data[consumed]), data.size() - consumed);
+        update(token, inArgs.hidl_data(), data_view, &result);
         if (result.resultCode != ResponseCode::NO_ERROR) {
-            ALOGW("Error in update: %d", result.resultCode);
+            ALOGW("Error in update: %d", int32_t(result.resultCode));
             return translateResultToLegacyResult(result.resultCode);
         }
         if (out) {
-            outBuffer.write(result.data.get(), result.dataLength);
+            outBuffer.write(&result.data[0], result.data.size());
         }
         lastConsumed = result.inputConsumed;
         consumed += lastConsumed;
-    } while (consumed < length && lastConsumed > 0);
+    } while (consumed < data.size() && lastConsumed > 0);
 
-    if (consumed != length) {
-        ALOGW("Not all data consumed. Consumed %zu of %zu", consumed, length);
-        return ::SYSTEM_ERROR;
+    if (consumed != data.size()) {
+        ALOGW("Not all data consumed. Consumed %zu of %zu", consumed, data.size());
+        return ResponseCode::SYSTEM_ERROR;
     }
 
-    finish(token, inArgs, signature, signatureLength, NULL, 0, &result);
+    finish(token, inArgs.hidl_data(), signature, hidl_vec<uint8_t>(), &result);
     if (result.resultCode != ResponseCode::NO_ERROR) {
-        ALOGW("Error in finish: %d", result.resultCode);
+        ALOGW("Error in finish: %d", int32_t(result.resultCode));
         return translateResultToLegacyResult(result.resultCode);
     }
     if (out) {
-        outBuffer.write(result.data.get(), result.dataLength);
+        outBuffer.write(&result.data[0], result.data.size());
     }
 
     if (out) {
         auto buf = outBuffer.str();
-        *out = new uint8_t[buf.size()];
-        memcpy(*out, buf.c_str(), buf.size());
-        *outLength = buf.size();
+        out->resize(buf.size());
+        memcpy(&(*out)[0], buf.data(), out->size());
     }
 
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::upgradeKeyBlob(const String16& name, uid_t uid,
-                                        const AuthorizationSet& params, Blob* blob) {
+KeyStoreServiceReturnCode KeyStoreService::upgradeKeyBlob(const String16& name, uid_t uid,
+                                                          const AuthorizationSet& params,
+                                                          Blob* blob) {
     // Read the blob rather than assuming the caller provided the right name/uid/blob triplet.
     String8 name8(name);
     ResponseCode responseCode = mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
-    if (responseCode != ::NO_ERROR) {
+    if (responseCode != ResponseCode::NO_ERROR) {
         return responseCode;
     }
+    ALOGI("upgradeKeyBlob %s %d", name8.string(), uid);
 
-    keymaster_key_blob_t key = {blob->getValue(), static_cast<size_t>(blob->getLength())};
-    auto* dev = mKeyStore->getDeviceForBlob(*blob);
-    keymaster_key_blob_t upgraded_key;
-    int32_t rc = dev->upgrade_key(dev, &key, &params, &upgraded_key);
-    if (rc != KM_ERROR_OK) {
-        return rc;
-    }
-    UniquePtr<uint8_t, Malloc_Delete> upgraded_key_deleter(
-        const_cast<uint8_t*>(upgraded_key.key_material));
+    auto hidlKey = blob2hidlVec(*blob);
+    auto& dev = mKeyStore->getDevice(*blob);
 
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
-    rc = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(uid));
-    if (rc != ::NO_ERROR) {
+    KeyStoreServiceReturnCode error;
+    auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
+        error = ret;
+        if (!error.isOk()) {
+            return;
+        }
+
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
+        error = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(uid));
+        if (!error.isOk()) {
+            ALOGI("upgradeKeyBlob keystore->del failed %d", (int)error);
+            return;
+        }
+
+        Blob newBlob(&upgradedKeyBlob[0], upgradedKeyBlob.size(), nullptr /* info */,
+                     0 /* infoLength */, ::TYPE_KEYMASTER_10);
+        newBlob.setFallback(blob->isFallback());
+        newBlob.setEncrypted(blob->isEncrypted());
+        newBlob.setSuperEncrypted(blob->isSuperEncrypted());
+        newBlob.setCriticalToDeviceEncryption(blob->isCriticalToDeviceEncryption());
+
+        error = mKeyStore->put(filename.string(), &newBlob, get_user_id(uid));
+        if (!error.isOk()) {
+            ALOGI("upgradeKeyBlob keystore->put failed %d", (int)error);
+            return;
+        }
+
+        // Re-read blob for caller.  We can't use newBlob because writing it modified it.
+        error = mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
+    };
+
+    KeyStoreServiceReturnCode rc =
+        KS_HANDLE_HIDL_ERROR(dev->upgradeKey(hidlKey, params.hidl_data(), hidlCb));
+    if (!rc.isOk()) {
         return rc;
     }
 
-    Blob newBlob(upgraded_key.key_material, upgraded_key.key_material_size, nullptr /* info */,
-                 0 /* infoLength */, ::TYPE_KEYMASTER_10);
-    newBlob.setFallback(blob->isFallback());
-    newBlob.setEncrypted(blob->isEncrypted());
-
-    rc = mKeyStore->put(filename.string(), &newBlob, get_user_id(uid));
-
-    // Re-read blob for caller.  We can't use newBlob because writing it modified it.
-    responseCode = mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
-    if (responseCode != ::NO_ERROR) {
-        return responseCode;
-    }
-
-    return rc;
+    return error;
 }
 
-}  // namespace android
+}  // namespace keystore
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index cfbc91f..3b4ef85 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -19,7 +19,7 @@
 
 #include <keystore/IKeystoreService.h>
 
-#include <keymaster/authorization_set.h>
+#include <keystore/authorization_set.h>
 
 #include "auth_token_table.h"
 #include "keystore.h"
@@ -27,42 +27,48 @@
 #include "operation.h"
 #include "permissions.h"
 
-namespace android {
+namespace keystore {
 
-class KeyStoreService : public BnKeystoreService, public IBinder::DeathRecipient {
+class KeyStoreService : public android::BnKeystoreService, public android::IBinder::DeathRecipient {
+    typedef ::android::sp<::android::hardware::keymaster::V3_0::IKeymasterDevice> km_device_t;
+
   public:
     explicit KeyStoreService(KeyStore* keyStore) : mKeyStore(keyStore), mOperationMap(this) {}
 
-    void binderDied(const wp<IBinder>& who);
+    void binderDied(const android::wp<android::IBinder>& who);
 
-    int32_t getState(int32_t userId);
+    KeyStoreServiceReturnCode getState(int32_t userId) override;
 
-    int32_t get(const String16& name, int32_t uid, uint8_t** item, size_t* itemLength);
-    int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid,
-                   int32_t flags);
-    int32_t del(const String16& name, int targetUid);
-    int32_t exist(const String16& name, int targetUid);
-    int32_t list(const String16& prefix, int targetUid, Vector<String16>* matches);
+    KeyStoreServiceReturnCode get(const android::String16& name, int32_t uid,
+                                  hidl_vec<uint8_t>* item) override;
+    KeyStoreServiceReturnCode insert(const android::String16& name, const hidl_vec<uint8_t>& item,
+                                     int targetUid, int32_t flags) override;
+    KeyStoreServiceReturnCode del(const android::String16& name, int targetUid) override;
+    KeyStoreServiceReturnCode exist(const android::String16& name, int targetUid) override;
+    KeyStoreServiceReturnCode list(const android::String16& prefix, int targetUid,
+                                   android::Vector<android::String16>* matches) override;
 
-    int32_t reset();
+    KeyStoreServiceReturnCode reset() override;
 
-    int32_t onUserPasswordChanged(int32_t userId, const String16& password);
-    int32_t onUserAdded(int32_t userId, int32_t parentId);
-    int32_t onUserRemoved(int32_t userId);
+    KeyStoreServiceReturnCode onUserPasswordChanged(int32_t userId,
+                                                    const android::String16& password) override;
+    KeyStoreServiceReturnCode onUserAdded(int32_t userId, int32_t parentId) override;
+    KeyStoreServiceReturnCode onUserRemoved(int32_t userId) override;
 
-    int32_t lock(int32_t userId);
-    int32_t unlock(int32_t userId, const String16& pw);
+    KeyStoreServiceReturnCode lock(int32_t userId) override;
+    KeyStoreServiceReturnCode unlock(int32_t userId, const android::String16& pw) override;
 
-    bool isEmpty(int32_t userId);
+    bool isEmpty(int32_t userId) override;
 
-    int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize,
-                     int32_t flags, Vector<sp<KeystoreArg>>* args);
-    int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid,
-                   int32_t flags);
-    int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
-                 size_t* outLength);
-    int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
-                   const uint8_t* signature, size_t signatureLength);
+    KeyStoreServiceReturnCode
+    generate(const android::String16& name, int32_t targetUid, int32_t keyType, int32_t keySize,
+             int32_t flags, android::Vector<android::sp<android::KeystoreArg>>* args) override;
+    KeyStoreServiceReturnCode import(const android::String16& name, const hidl_vec<uint8_t>& data,
+                                     int targetUid, int32_t flags) override;
+    KeyStoreServiceReturnCode sign(const android::String16& name, const hidl_vec<uint8_t>& data,
+                                   hidl_vec<uint8_t>* out) override;
+    KeyStoreServiceReturnCode verify(const android::String16& name, const hidl_vec<uint8_t>& data,
+                                     const hidl_vec<uint8_t>& signature) override;
 
     /*
      * TODO: The abstraction between things stored in hardware and regular blobs
@@ -75,51 +81,60 @@
      * "del_key" since the Java code doesn't really communicate what it's
      * intentions are.
      */
-    int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength);
+    KeyStoreServiceReturnCode get_pubkey(const android::String16& name,
+                                         hidl_vec<uint8_t>* pubKey) override;
 
-    int32_t grant(const String16& name, int32_t granteeUid);
-    int32_t ungrant(const String16& name, int32_t granteeUid);
+    KeyStoreServiceReturnCode grant(const android::String16& name, int32_t granteeUid) override;
+    KeyStoreServiceReturnCode ungrant(const android::String16& name, int32_t granteeUid) override;
 
-    int64_t getmtime(const String16& name, int32_t uid);
+    int64_t getmtime(const android::String16& name, int32_t uid) override;
 
-    int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
-                      int32_t destUid);
+    KeyStoreServiceReturnCode duplicate(const android::String16& srcKey, int32_t srcUid,
+                                        const android::String16& destKey, int32_t destUid) override;
 
-    int32_t is_hardware_backed(const String16& keyType);
+    int32_t is_hardware_backed(const android::String16& keyType) override;
 
-    int32_t clear_uid(int64_t targetUid64);
+    KeyStoreServiceReturnCode clear_uid(int64_t targetUid64) override;
 
-    int32_t addRngEntropy(const uint8_t* data, size_t dataLength);
-    int32_t generateKey(const String16& name, const KeymasterArguments& params,
-                        const uint8_t* entropy, size_t entropyLength, int uid, int flags,
-                        KeyCharacteristics* outCharacteristics);
-    int32_t getKeyCharacteristics(const String16& name, const keymaster_blob_t* clientId,
-                                  const keymaster_blob_t* appData, int32_t uid,
-                                  KeyCharacteristics* outCharacteristics);
-    int32_t importKey(const String16& name, const KeymasterArguments& params,
-                      keymaster_key_format_t format, const uint8_t* keyData, size_t keyLength,
-                      int uid, int flags, KeyCharacteristics* outCharacteristics);
-    void exportKey(const String16& name, keymaster_key_format_t format,
-                   const keymaster_blob_t* clientId, const keymaster_blob_t* appData, int32_t uid,
-                   ExportResult* result);
-    void begin(const sp<IBinder>& appToken, const String16& name, keymaster_purpose_t purpose,
-               bool pruneable, const KeymasterArguments& params, const uint8_t* entropy,
-               size_t entropyLength, int32_t uid, OperationResult* result);
-    void update(const sp<IBinder>& token, const KeymasterArguments& params, const uint8_t* data,
-                size_t dataLength, OperationResult* result);
-    void finish(const sp<IBinder>& token, const KeymasterArguments& params,
-                const uint8_t* signature, size_t signatureLength, const uint8_t* entropy,
-                size_t entropyLength, OperationResult* result);
-    int32_t abort(const sp<IBinder>& token);
+    KeyStoreServiceReturnCode addRngEntropy(const hidl_vec<uint8_t>& entropy) override;
+    KeyStoreServiceReturnCode generateKey(const android::String16& name,
+                                          const hidl_vec<KeyParameter>& params,
+                                          const hidl_vec<uint8_t>& entropy, int uid, int flags,
+                                          KeyCharacteristics* outCharacteristics) override;
+    KeyStoreServiceReturnCode
+    getKeyCharacteristics(const android::String16& name, const hidl_vec<uint8_t>& clientId,
+                          const hidl_vec<uint8_t>& appData, int32_t uid,
+                          KeyCharacteristics* outCharacteristics) override;
+    KeyStoreServiceReturnCode importKey(const android::String16& name,
+                                        const hidl_vec<KeyParameter>& params, KeyFormat format,
+                                        const hidl_vec<uint8_t>& keyData, int uid, int flags,
+                                        KeyCharacteristics* outCharacteristics) override;
+    void exportKey(const android::String16& name, KeyFormat format,
+                   const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData, int32_t uid,
+                   android::ExportResult* result) override;
+    void begin(const sp<android::IBinder>& appToken, const android::String16& name,
+               KeyPurpose purpose, bool pruneable, const hidl_vec<KeyParameter>& params,
+               const hidl_vec<uint8_t>& entropy, int32_t uid,
+               android::OperationResult* result) override;
+    void update(const sp<android::IBinder>& token, const hidl_vec<KeyParameter>& params,
+                const hidl_vec<uint8_t>& data, android::OperationResult* result) override;
+    void finish(const sp<android::IBinder>& token, const hidl_vec<KeyParameter>& params,
+                const hidl_vec<uint8_t>& signature, const hidl_vec<uint8_t>& entropy,
+                android::OperationResult* result) override;
+    KeyStoreServiceReturnCode abort(const sp<android::IBinder>& token) override;
 
-    bool isOperationAuthorized(const sp<IBinder>& token);
+    bool isOperationAuthorized(const sp<android::IBinder>& token) override;
 
-    int32_t addAuthToken(const uint8_t* token, size_t length);
+    KeyStoreServiceReturnCode addAuthToken(const uint8_t* token, size_t length) override;
 
-    int32_t attestKey(const String16& name, const KeymasterArguments& params,
-                      KeymasterCertificateChain* outChain) override;
+    KeyStoreServiceReturnCode attestKey(const android::String16& name,
+                                        const hidl_vec<KeyParameter>& params,
+                                        hidl_vec<hidl_vec<uint8_t>>* outChain) override;
 
-    int32_t onDeviceOffBody();
+    KeyStoreServiceReturnCode attestDeviceIds(const hidl_vec<KeyParameter>& params,
+                                              hidl_vec<hidl_vec<uint8_t>>* outChain) override;
+
+    KeyStoreServiceReturnCode onDeviceOffBody() override;
 
   private:
     static const int32_t UID_SELF = -1;
@@ -164,23 +179,20 @@
      * otherwise the state of keystore when not unlocked and checkUnlocked is
      * true.
      */
-    int32_t checkBinderPermissionAndKeystoreState(perm_t permission, int32_t targetUid = -1,
-                                                  bool checkUnlocked = true);
+    KeyStoreServiceReturnCode checkBinderPermissionAndKeystoreState(perm_t permission,
+                                                                    int32_t targetUid = -1,
+                                                                    bool checkUnlocked = true);
 
     bool isKeystoreUnlocked(State state);
 
-    bool isKeyTypeSupported(const keymaster2_device_t* device, keymaster_keypair_t keyType);
-
     /**
      * Check that all keymaster_key_param_t's provided by the application are
      * allowed. Any parameter that keystore adds itself should be disallowed here.
      */
-    bool checkAllowedOperationParams(const std::vector<keymaster_key_param_t>& params);
+    bool checkAllowedOperationParams(const hidl_vec<KeyParameter>& params);
 
-    keymaster_error_t getOperationCharacteristics(const keymaster_key_blob_t& key,
-                                                  const keymaster2_device_t* dev,
-                                                  const std::vector<keymaster_key_param_t>& params,
-                                                  keymaster_key_characteristics_t* out);
+    ErrorCode getOperationCharacteristics(const hidl_vec<uint8_t>& key, km_device_t* dev,
+                                          const AuthorizationSet& params, KeyCharacteristics* out);
 
     /**
      * Get the auth token for this operation from the auth token table.
@@ -192,11 +204,10 @@
      *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if there is no valid auth
      *         token for the operation
      */
-    int32_t getAuthToken(const keymaster_key_characteristics_t* characteristics,
-                         keymaster_operation_handle_t handle, keymaster_purpose_t purpose,
-                         const hw_auth_token_t** authToken, bool failOnTokenMissing = true);
-
-    void addAuthToParams(std::vector<keymaster_key_param_t>* params, const hw_auth_token_t* token);
+    KeyStoreServiceReturnCode getAuthToken(const KeyCharacteristics& characteristics,
+                                           uint64_t handle, KeyPurpose purpose,
+                                           const HardwareAuthToken** authToken,
+                                           bool failOnTokenMissing = true);
 
     /**
      * Add the auth token for the operation to the param list if the operation
@@ -209,22 +220,22 @@
      *         KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid
      *         operation token.
      */
-    int32_t addOperationAuthTokenIfNeeded(const sp<IBinder>& token,
-                                          std::vector<keymaster_key_param_t>* params);
+    KeyStoreServiceReturnCode addOperationAuthTokenIfNeeded(const sp<android::IBinder>& token,
+                                                            AuthorizationSet* params);
 
     /**
      * Translate a result value to a legacy return value. All keystore errors are
      * preserved and keymaster errors become SYSTEM_ERRORs
      */
-    int32_t translateResultToLegacyResult(int32_t result);
+    KeyStoreServiceReturnCode translateResultToLegacyResult(int32_t result);
 
-    keymaster_key_param_t* getKeyAlgorithm(keymaster_key_characteristics_t* characteristics);
+    void addLegacyBeginParams(const android::String16& name, AuthorizationSet* params);
 
-    void addLegacyBeginParams(const String16& name, std::vector<keymaster_key_param_t>& params);
-
-    int32_t doLegacySignVerify(const String16& name, const uint8_t* data, size_t length,
-                               uint8_t** out, size_t* outLength, const uint8_t* signature,
-                               size_t signatureLength, keymaster_purpose_t purpose);
+    KeyStoreServiceReturnCode doLegacySignVerify(const android::String16& name,
+                                                 const hidl_vec<uint8_t>& data,
+                                                 hidl_vec<uint8_t>* out,
+                                                 const hidl_vec<uint8_t>& signature,
+                                                 KeyPurpose purpose);
 
     /**
      * Upgrade a key blob under alias "name", returning the new blob in "blob".  If "blob"
@@ -234,15 +245,15 @@
      *         KM_ERROR_VERSION_MISMATCH if called on a key whose patch level is greater than or
      *         equal to the current system patch level.
      */
-    int32_t upgradeKeyBlob(const String16& name, uid_t targetUid,
-                           const keymaster::AuthorizationSet& params, Blob* blob);
+    KeyStoreServiceReturnCode upgradeKeyBlob(const android::String16& name, uid_t targetUid,
+                                             const AuthorizationSet& params, Blob* blob);
 
     ::KeyStore* mKeyStore;
     OperationMap mOperationMap;
-    keymaster::AuthTokenTable mAuthTokenTable;
+    keystore::AuthTokenTable mAuthTokenTable;
     KeystoreKeymasterEnforcement enforcement_policy;
 };
 
-};  // namespace android
+};  // namespace keystore
 
 #endif  // KEYSTORE_KEYSTORE_SERVICE_H_
diff --git a/keystore/keymaster_enforcement.cpp b/keystore/keymaster_enforcement.cpp
new file mode 100644
index 0000000..4cee57d
--- /dev/null
+++ b/keystore/keymaster_enforcement.cpp
@@ -0,0 +1,606 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#define LOG_TAG "keystore"
+
+#include "keymaster_enforcement.h"
+
+#include <assert.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <string.h>
+
+#include <openssl/evp.h>
+
+#include <cutils/log.h>
+#include <hardware/hw_auth_token.h>
+#include <list>
+
+namespace keystore {
+
+class AccessTimeMap {
+  public:
+    explicit AccessTimeMap(uint32_t max_size) : max_size_(max_size) {}
+
+    /* If the key is found, returns true and fills \p last_access_time.  If not found returns
+     * false. */
+    bool LastKeyAccessTime(km_id_t keyid, uint32_t* last_access_time) const;
+
+    /* Updates the last key access time with the currentTime parameter.  Adds the key if
+     * needed, returning false if key cannot be added because list is full. */
+    bool UpdateKeyAccessTime(km_id_t keyid, uint32_t current_time, uint32_t timeout);
+
+  private:
+    struct AccessTime {
+        km_id_t keyid;
+        uint32_t access_time;
+        uint32_t timeout;
+    };
+    std::list<AccessTime> last_access_list_;
+    const uint32_t max_size_;
+};
+
+class AccessCountMap {
+  public:
+    explicit AccessCountMap(uint32_t max_size) : max_size_(max_size) {}
+
+    /* If the key is found, returns true and fills \p count.  If not found returns
+     * false. */
+    bool KeyAccessCount(km_id_t keyid, uint32_t* count) const;
+
+    /* Increments key access count, adding an entry if the key has never been used.  Returns
+     * false if the list has reached maximum size. */
+    bool IncrementKeyAccessCount(km_id_t keyid);
+
+  private:
+    struct AccessCount {
+        km_id_t keyid;
+        uint64_t access_count;
+    };
+    std::list<AccessCount> access_count_list_;
+    const uint32_t max_size_;
+};
+
+bool is_public_key_algorithm(const AuthorizationSet& auth_set) {
+    auto algorithm = auth_set.GetTagValue(TAG_ALGORITHM);
+    return algorithm.isOk() &&
+           (algorithm.value() == Algorithm::RSA || algorithm.value() == Algorithm::EC);
+}
+
+static ErrorCode authorized_purpose(const KeyPurpose purpose, const AuthorizationSet& auth_set) {
+    switch (purpose) {
+    case KeyPurpose::VERIFY:
+    case KeyPurpose::ENCRYPT:
+    case KeyPurpose::SIGN:
+    case KeyPurpose::DECRYPT:
+        if (auth_set.Contains(TAG_PURPOSE, purpose)) return ErrorCode::OK;
+        return ErrorCode::INCOMPATIBLE_PURPOSE;
+
+    default:
+        return ErrorCode::UNSUPPORTED_PURPOSE;
+    }
+}
+
+inline bool is_origination_purpose(KeyPurpose purpose) {
+    return purpose == KeyPurpose::ENCRYPT || purpose == KeyPurpose::SIGN;
+}
+
+inline bool is_usage_purpose(KeyPurpose purpose) {
+    return purpose == KeyPurpose::DECRYPT || purpose == KeyPurpose::VERIFY;
+}
+
+KeymasterEnforcement::KeymasterEnforcement(uint32_t max_access_time_map_size,
+                                           uint32_t max_access_count_map_size)
+    : access_time_map_(new (std::nothrow) AccessTimeMap(max_access_time_map_size)),
+      access_count_map_(new (std::nothrow) AccessCountMap(max_access_count_map_size)) {}
+
+KeymasterEnforcement::~KeymasterEnforcement() {
+    delete access_time_map_;
+    delete access_count_map_;
+}
+
+ErrorCode KeymasterEnforcement::AuthorizeOperation(const KeyPurpose purpose, const km_id_t keyid,
+                                                   const AuthorizationSet& auth_set,
+                                                   const AuthorizationSet& operation_params,
+                                                   uint64_t op_handle, bool is_begin_operation) {
+    if (is_public_key_algorithm(auth_set)) {
+        switch (purpose) {
+        case KeyPurpose::ENCRYPT:
+        case KeyPurpose::VERIFY:
+            /* Public key operations are always authorized. */
+            return ErrorCode::OK;
+
+        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);
+    else
+        return AuthorizeUpdateOrFinish(auth_set, operation_params, 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,
+                                                        uint64_t op_handle) {
+    int auth_type_index = -1;
+    for (size_t pos = 0; pos < auth_set.size(); ++pos) {
+        switch (auth_set[pos].tag) {
+        case Tag::NO_AUTH_REQUIRED:
+        case Tag::AUTH_TIMEOUT:
+            // If no auth is required or if auth is timeout-based, we have nothing to check.
+            return ErrorCode::OK;
+
+        case Tag::USER_AUTH_TYPE:
+            auth_type_index = pos;
+            break;
+
+        default:
+            break;
+        }
+    }
+
+    // Note that at this point we should be able to assume that authentication is required, because
+    // authentication is required if KM_TAG_NO_AUTH_REQUIRED is absent.  However, there are legacy
+    // keys which have no authentication-related tags, so we assume that absence is equivalent to
+    // presence of KM_TAG_NO_AUTH_REQUIRED.
+    //
+    // So, if we found KM_TAG_USER_AUTH_TYPE or if we find KM_TAG_USER_SECURE_ID then authentication
+    // is required.  If we find neither, then we assume authentication is not required and return
+    // success.
+    bool authentication_required = (auth_type_index != -1);
+    for (auto& param : auth_set) {
+        auto user_secure_id = authorizationValue(TAG_USER_SECURE_ID, param);
+        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 */))
+                return ErrorCode::OK;
+        }
+    }
+
+    if (authentication_required) return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
+
+    return ErrorCode::OK;
+}
+
+ErrorCode KeymasterEnforcement::AuthorizeBegin(const KeyPurpose purpose, const km_id_t keyid,
+                                               const AuthorizationSet& auth_set,
+                                               const AuthorizationSet& operation_params) {
+    // Find some entries that may be needed to handle KM_TAG_USER_SECURE_ID
+    int auth_timeout_index = -1;
+    int auth_type_index = -1;
+    int no_auth_required_index = -1;
+    for (size_t pos = 0; pos < auth_set.size(); ++pos) {
+        switch (auth_set[pos].tag) {
+        case Tag::AUTH_TIMEOUT:
+            auth_timeout_index = pos;
+            break;
+        case Tag::USER_AUTH_TYPE:
+            auth_type_index = pos;
+            break;
+        case Tag::NO_AUTH_REQUIRED:
+            no_auth_required_index = pos;
+            break;
+        default:
+            break;
+        }
+    }
+
+    ErrorCode error = authorized_purpose(purpose, auth_set);
+    if (error != ErrorCode::OK) return error;
+
+    // If successful, and if key has a min time between ops, this will be set to the time limit
+    uint32_t min_ops_timeout = UINT32_MAX;
+
+    bool update_access_count = false;
+    bool caller_nonce_authorized_by_key = false;
+    bool authentication_required = false;
+    bool auth_token_matched = false;
+
+    for (auto& param : auth_set) {
+
+        // KM_TAG_PADDING_OLD and KM_TAG_DIGEST_OLD aren't actually members of the enum, so we can't
+        // switch on them.  There's nothing to validate for them, though, so just ignore them.
+        if (int32_t(param.tag) == KM_TAG_PADDING_OLD || int32_t(param.tag) == KM_TAG_DIGEST_OLD)
+            continue;
+
+        switch (param.tag) {
+
+        case Tag::ACTIVE_DATETIME: {
+            auto date = authorizationValue(TAG_ACTIVE_DATETIME, param);
+            if (date.isOk() && !activation_date_valid(date.value()))
+                return ErrorCode::KEY_NOT_YET_VALID;
+            break;
+        }
+        case Tag::ORIGINATION_EXPIRE_DATETIME: {
+            auto date = authorizationValue(TAG_ORIGINATION_EXPIRE_DATETIME, param);
+            if (is_origination_purpose(purpose) && date.isOk() &&
+                expiration_date_passed(date.value()))
+                return ErrorCode::KEY_EXPIRED;
+            break;
+        }
+        case Tag::USAGE_EXPIRE_DATETIME: {
+            auto date = authorizationValue(TAG_USAGE_EXPIRE_DATETIME, param);
+            if (is_usage_purpose(purpose) && date.isOk() && expiration_date_passed(date.value()))
+                return ErrorCode::KEY_EXPIRED;
+            break;
+        }
+        case Tag::MIN_SECONDS_BETWEEN_OPS: {
+            auto min_ops_timeout = authorizationValue(TAG_MIN_SECONDS_BETWEEN_OPS, param);
+            if (min_ops_timeout.isOk() && !MinTimeBetweenOpsPassed(min_ops_timeout.value(), keyid))
+                return ErrorCode::KEY_RATE_LIMIT_EXCEEDED;
+            break;
+        }
+        case Tag::MAX_USES_PER_BOOT: {
+            auto max_users = authorizationValue(TAG_MAX_USES_PER_BOOT, param);
+            update_access_count = true;
+            if (max_users.isOk() && !MaxUsesPerBootNotExceeded(keyid, max_users.value()))
+                return ErrorCode::KEY_MAX_OPS_EXCEEDED;
+            break;
+        }
+        case Tag::USER_SECURE_ID:
+            if (no_auth_required_index != -1) {
+                // Key has both KM_TAG_USER_SECURE_ID and KM_TAG_NO_AUTH_REQUIRED
+                return ErrorCode::INVALID_KEY_BLOB;
+            }
+
+            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 */,
+                                     true /* is_begin_operation */))
+                    auth_token_matched = true;
+            }
+            break;
+
+        case Tag::CALLER_NONCE:
+            caller_nonce_authorized_by_key = true;
+            break;
+
+        /* 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:
+        case Tag::ATTESTATION_APPLICATION_ID:
+        case Tag::ATTESTATION_ID_BRAND:
+        case Tag::ATTESTATION_ID_DEVICE:
+        case Tag::ATTESTATION_ID_PRODUCT:
+        case Tag::ATTESTATION_ID_SERIAL:
+        case Tag::ATTESTATION_ID_IMEI:
+        case Tag::ATTESTATION_ID_MEID:
+        case Tag::ATTESTATION_ID_MANUFACTURER:
+        case Tag::ATTESTATION_ID_MODEL:
+            return ErrorCode::INVALID_KEY_BLOB;
+
+        /* Tags used for cryptographic parameters in keygen.  Nothing to enforce. */
+        case Tag::PURPOSE:
+        case Tag::ALGORITHM:
+        case Tag::KEY_SIZE:
+        case Tag::BLOCK_MODE:
+        case Tag::DIGEST:
+        case Tag::MAC_LENGTH:
+        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:
+
+        /* Tags handled when KM_TAG_USER_SECURE_ID is handled */
+        case Tag::NO_AUTH_REQUIRED:
+        case Tag::USER_AUTH_TYPE:
+        case Tag::AUTH_TIMEOUT:
+
+        /* Tag to provide data to operations. */
+        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:
+            break;
+
+        case Tag::BOOTLOADER_ONLY:
+            return ErrorCode::INVALID_KEY_BLOB;
+        }
+    }
+
+    if (authentication_required && !auth_token_matched) {
+        ALOGE("Auth required but no matching auth token found");
+        return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
+    }
+
+    if (!caller_nonce_authorized_by_key && is_origination_purpose(purpose) &&
+        operation_params.Contains(Tag::NONCE))
+        return ErrorCode::CALLER_NONCE_PROHIBITED;
+
+    if (min_ops_timeout != UINT32_MAX) {
+        if (!access_time_map_) {
+            ALOGE("Rate-limited keys table not allocated.  Rate-limited keys disabled");
+            return ErrorCode::MEMORY_ALLOCATION_FAILED;
+        }
+
+        if (!access_time_map_->UpdateKeyAccessTime(keyid, get_current_time(), min_ops_timeout)) {
+            ALOGE("Rate-limited keys table full.  Entries will time out.");
+            return ErrorCode::TOO_MANY_OPERATIONS;
+        }
+    }
+
+    if (update_access_count) {
+        if (!access_count_map_) {
+            ALOGE("Usage-count limited keys tabel not allocated.  Count-limited keys disabled");
+            return ErrorCode::MEMORY_ALLOCATION_FAILED;
+        }
+
+        if (!access_count_map_->IncrementKeyAccessCount(keyid)) {
+            ALOGE("Usage count-limited keys table full, until reboot.");
+            return ErrorCode::TOO_MANY_OPERATIONS;
+        }
+    }
+
+    return ErrorCode::OK;
+}
+
+class EvpMdCtx {
+  public:
+    EvpMdCtx() { EVP_MD_CTX_init(&ctx_); }
+    ~EvpMdCtx() { EVP_MD_CTX_cleanup(&ctx_); }
+
+    EVP_MD_CTX* get() { return &ctx_; }
+
+  private:
+    EVP_MD_CTX ctx_;
+};
+
+/* static */
+bool KeymasterEnforcement::CreateKeyId(const hidl_vec<uint8_t>& key_blob, km_id_t* keyid) {
+    EvpMdCtx ctx;
+
+    uint8_t hash[EVP_MAX_MD_SIZE];
+    unsigned int hash_len;
+    if (EVP_DigestInit_ex(ctx.get(), EVP_sha256(), nullptr /* ENGINE */) &&
+        EVP_DigestUpdate(ctx.get(), &key_blob[0], key_blob.size()) &&
+        EVP_DigestFinal_ex(ctx.get(), hash, &hash_len)) {
+        assert(hash_len >= sizeof(*keyid));
+        memcpy(keyid, hash, sizeof(*keyid));
+        return true;
+    }
+
+    return false;
+}
+
+bool KeymasterEnforcement::MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid) {
+    if (!access_time_map_) return false;
+
+    uint32_t last_access_time;
+    if (!access_time_map_->LastKeyAccessTime(keyid, &last_access_time)) return true;
+    return min_time_between <= static_cast<int64_t>(get_current_time()) - last_access_time;
+}
+
+bool KeymasterEnforcement::MaxUsesPerBootNotExceeded(const km_id_t keyid, uint32_t max_uses) {
+    if (!access_count_map_) return false;
+
+    uint32_t key_access_count;
+    if (!access_count_map_->KeyAccessCount(keyid, &key_access_count)) return true;
+    return key_access_count < max_uses;
+}
+
+template <typename IntType, uint32_t byteOrder> struct choose_hton;
+
+template <typename IntType> struct choose_hton<IntType, __ORDER_LITTLE_ENDIAN__> {
+    inline static IntType hton(const IntType& value) {
+        IntType result = 0;
+        const unsigned char* inbytes = reinterpret_cast<const unsigned char*>(&value);
+        unsigned char* outbytes = reinterpret_cast<unsigned char*>(&result);
+        for (int i = sizeof(IntType) - 1; i >= 0; --i) {
+            *(outbytes++) = inbytes[i];
+        }
+        return result;
+    }
+};
+
+template <typename IntType> struct choose_hton<IntType, __ORDER_BIG_ENDIAN__> {
+    inline static IntType hton(const IntType& value) { return value; }
+};
+
+template <typename IntType> inline IntType hton(const IntType& value) {
+    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
+}
+
+template <typename IntType> inline IntType ntoh(const IntType& value) {
+    // same operation and hton
+    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
+}
+
+bool KeymasterEnforcement::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 {
+    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;
+    }
+
+    hw_auth_token_t auth_token;
+    memcpy(&auth_token, &auth_token_blob.value()[0], sizeof(hw_auth_token_t));
+    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;
+    }
+
+    if (auth_timeout_index == -1 && op_handle && op_handle != auth_token.challenge) {
+        ALOGE("Auth token has the challenge %" PRIu64 ", need %" PRIu64, auth_token.challenge,
+              op_handle);
+        return false;
+    }
+
+    if (user_secure_id != auth_token.user_id && user_secure_id != auth_token.authenticator_id) {
+        ALOGI("Auth token SIDs %" PRIu64 " and %" PRIu64 " do not match key SID %" PRIu64,
+              auth_token.user_id, auth_token.authenticator_id, user_secure_id);
+        return false;
+    }
+
+    if (auth_type_index < 0 || auth_type_index > static_cast<int>(auth_set.size())) {
+        ALOGE("Auth required but no auth type found");
+        return false;
+    }
+
+    assert(auth_set[auth_type_index].tag == KM_TAG_USER_AUTH_TYPE);
+    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.authenticator_type);
+    if ((uint32_t(key_auth_type_mask.value()) & token_auth_type) == 0) {
+        ALOGE("Key requires match of auth type mask 0%uo, but token contained 0%uo",
+              key_auth_type_mask.value(), token_auth_type);
+        return false;
+    }
+
+    if (auth_timeout_index != -1 && is_begin_operation) {
+        assert(auth_set[auth_timeout_index].tag == KM_TAG_AUTH_TIMEOUT);
+        auto auth_token_timeout =
+            authorizationValue(TAG_AUTH_TIMEOUT, auth_set[auth_timeout_index]);
+        if (!auth_token_timeout.isOk()) return false;
+
+        if (auth_token_timed_out(auth_token, auth_token_timeout.value())) {
+            ALOGE("Auth token has timed out");
+            return false;
+        }
+    }
+
+    // Survived the whole gauntlet.  We have authentage!
+    return true;
+}
+
+bool AccessTimeMap::LastKeyAccessTime(km_id_t keyid, uint32_t* last_access_time) const {
+    for (auto& entry : last_access_list_)
+        if (entry.keyid == keyid) {
+            *last_access_time = entry.access_time;
+            return true;
+        }
+    return false;
+}
+
+bool AccessTimeMap::UpdateKeyAccessTime(km_id_t keyid, uint32_t current_time, uint32_t timeout) {
+    for (auto iter = last_access_list_.begin(); iter != last_access_list_.end();) {
+        if (iter->keyid == keyid) {
+            iter->access_time = current_time;
+            return true;
+        }
+
+        // Expire entry if possible.
+        assert(current_time >= iter->access_time);
+        if (current_time - iter->access_time >= iter->timeout)
+            iter = last_access_list_.erase(iter);
+        else
+            ++iter;
+    }
+
+    if (last_access_list_.size() >= max_size_) return false;
+
+    AccessTime new_entry;
+    new_entry.keyid = keyid;
+    new_entry.access_time = current_time;
+    new_entry.timeout = timeout;
+    last_access_list_.push_front(new_entry);
+    return true;
+}
+
+bool AccessCountMap::KeyAccessCount(km_id_t keyid, uint32_t* count) const {
+    for (auto& entry : access_count_list_)
+        if (entry.keyid == keyid) {
+            *count = entry.access_count;
+            return true;
+        }
+    return false;
+}
+
+bool AccessCountMap::IncrementKeyAccessCount(km_id_t keyid) {
+    for (auto& entry : access_count_list_)
+        if (entry.keyid == keyid) {
+            // Note that the 'if' below will always be true because KM_TAG_MAX_USES_PER_BOOT is a
+            // uint32_t, and as soon as entry.access_count reaches the specified maximum value
+            // operation requests will be rejected and access_count won't be incremented any more.
+            // And, besides, UINT64_MAX is huge.  But we ensure that it doesn't wrap anyway, out of
+            // an abundance of caution.
+            if (entry.access_count < UINT64_MAX) ++entry.access_count;
+            return true;
+        }
+
+    if (access_count_list_.size() >= max_size_) return false;
+
+    AccessCount new_entry;
+    new_entry.keyid = keyid;
+    new_entry.access_count = 1;
+    access_count_list_.push_front(new_entry);
+    return true;
+}
+}; /* namespace keystore */
diff --git a/keystore/keymaster_enforcement.h b/keystore/keymaster_enforcement.h
new file mode 100644
index 0000000..4f22f01
--- /dev/null
+++ b/keystore/keymaster_enforcement.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2014 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_ENFORCEMENT_H
+#define KEYSTORE_KEYMASTER_ENFORCEMENT_H
+
+#include <stdio.h>
+
+#include <keystore/authorization_set.h>
+
+namespace keystore {
+
+typedef uint64_t km_id_t;
+
+class KeymasterEnforcementContext {
+  public:
+    virtual ~KeymasterEnforcementContext() {}
+    /*
+     * Get current time.
+     */
+};
+
+class AccessTimeMap;
+class AccessCountMap;
+
+class KeymasterEnforcement {
+  public:
+    /**
+     * Construct a KeymasterEnforcement.
+     */
+    KeymasterEnforcement(uint32_t max_access_time_map_size, uint32_t max_access_count_map_size);
+    virtual ~KeymasterEnforcement();
+
+    /**
+     * 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 AuthorizeOperation(const KeyPurpose purpose, const km_id_t keyid,
+                                 const AuthorizationSet& auth_set,
+                                 const AuthorizationSet& operation_params, uint64_t op_handle,
+                                 bool is_begin_operation);
+
+    /**
+     * 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. Used for encrypt, decrypt sign, and verify.
+     */
+    ErrorCode AuthorizeBegin(const KeyPurpose purpose, const km_id_t keyid,
+                             const AuthorizationSet& auth_set,
+                             const AuthorizationSet& operation_params);
+
+    /**
+     * 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);
+    }
+
+    /**
+     * 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 AuthorizeFinish(const AuthorizationSet& auth_set,
+                              const AuthorizationSet& operation_params, uint64_t op_handle) {
+        return AuthorizeUpdateOrFinish(auth_set, operation_params, op_handle);
+    }
+
+    /**
+     * Creates a key ID for use in subsequent calls to AuthorizeOperation.  Clients needn't use this
+     * method of creating key IDs, as long as they use something consistent and unique.  This method
+     * hashes the key blob.
+     *
+     * Returns false if an error in the crypto library prevents creation of an ID.
+     */
+    static bool CreateKeyId(const hidl_vec<uint8_t>& key_blob, km_id_t* keyid);
+
+    //
+    // Methods that must be implemented by subclasses
+    //
+    // The time-related methods address the fact that different enforcement contexts may have
+    // different time-related capabilities.  In particular:
+    //
+    // - They may or may not be able to check dates against real-world clocks.
+    //
+    // - They may or may not be able to check timestampls against authentication trustlets (minters
+    //   of hw_auth_token_t structs).
+    //
+    // - They must have some time source for relative times, but may not be able to provide more
+    //   than reliability and monotonicity.
+
+    /*
+     * Returns true if the specified activation date has passed, or if activation cannot be
+     * enforced.
+     */
+    virtual bool activation_date_valid(uint64_t activation_date) const = 0;
+
+    /*
+     * Returns true if the specified expiration date has passed.  Returns false if it has not, or if
+     * expiration cannot be enforced.
+     */
+    virtual bool expiration_date_passed(uint64_t expiration_date) const = 0;
+
+    /*
+     * Returns true if the specified auth_token is older than the specified timeout.
+     */
+    virtual bool auth_token_timed_out(const hw_auth_token_t& token, uint32_t timeout) const = 0;
+
+    /*
+     * Get current time in seconds from some starting point.  This value is used to compute relative
+     * times between events.  It must be monotonically increasing, and must not skip or lag.  It
+     * need not have any relation to any external time standard (other than the duration of
+     * "second").
+     *
+     * On POSIX systems, it's recommented to use clock_gettime(CLOCK_MONOTONIC, ...) to implement
+     * this method.
+     */
+    virtual uint32_t get_current_time() const = 0;
+
+    /*
+     * Returns true if the specified auth_token has a valid signature, or if signature validation is
+     * not available.
+     */
+    virtual bool ValidateTokenSignature(const hw_auth_token_t& token) const = 0;
+
+  private:
+    ErrorCode AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
+                                      const AuthorizationSet& operation_params, 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;
+
+    AccessTimeMap* access_time_map_;
+    AccessCountMap* access_count_map_;
+};
+
+}; /* namespace keystore */
+
+#endif  // KEYSTORE_KEYMASTER_ENFORCEMENT_H
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 0b86e83..bc2e0dc 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "keystore"
+
 #include "keystore.h"
 
 #include <dirent.h>
@@ -25,16 +27,23 @@
 
 #include <keystore/IKeystoreService.h>
 
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+
 #include "keystore_utils.h"
 #include "permissions.h"
+#include <keystore/keystore_hidl_support.h>
 
 const char* KeyStore::sOldMasterKey = ".masterkey";
 const char* KeyStore::sMetaDataFile = ".metadata";
 
 const android::String16 KeyStore::sRSAKeyType("RSA");
 
-KeyStore::KeyStore(Entropy* entropy, keymaster2_device_t* device, keymaster2_device_t* fallback)
-    : mEntropy(entropy), mDevice(device), mFallbackDevice(fallback) {
+using namespace keystore;
+
+KeyStore::KeyStore(Entropy* entropy, const km_device_t& device, const km_device_t& fallback,
+                   bool allowNewFallback)
+    : mEntropy(entropy), mDevice(device), mFallbackDevice(fallback),
+      mAllowNewFallback(allowNewFallback) {
     memset(&mMetaData, '\0', sizeof(mMetaData));
 }
 
@@ -57,7 +66,7 @@
         writeMetaData();
     }
 
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
 ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
@@ -154,7 +163,7 @@
     android::String8 prefix("");
     android::Vector<android::String16> aliases;
     UserState* userState = getUserState(userId);
-    if (list(prefix, &aliases, userId) != ::NO_ERROR) {
+    if (list(prefix, &aliases, userId) != ResponseCode::NO_ERROR) {
         return;
     }
     for (uint32_t i = 0; i < aliases.size(); i++) {
@@ -166,13 +175,28 @@
             Blob blob;
             ResponseCode rc = get(filename, &blob, ::TYPE_ANY, userId);
 
-            /* get can fail if the blob is encrypted and the state is
-             * not unlocked, only skip deleting blobs that were loaded and
-             * who are not encrypted. If there are blobs we fail to read for
-             * other reasons err on the safe side and delete them since we
-             * can't tell if they're encrypted.
-             */
-            shouldDelete = !(rc == ::NO_ERROR && !blob.isEncrypted());
+            switch (rc) {
+            case ResponseCode::SYSTEM_ERROR:
+            case ResponseCode::VALUE_CORRUPTED:
+                // If we can't read blobs, delete them.
+                shouldDelete = true;
+                break;
+
+            case ResponseCode::NO_ERROR:
+            case ResponseCode::LOCKED:
+                // Delete encrypted blobs but keep unencrypted blobs and super-encrypted blobs.  We
+                // need to keep super-encrypted blobs so we can report that the user is
+                // unauthenticated if a caller tries to use them, rather than reporting that they
+                // don't exist.
+                shouldDelete = blob.isEncrypted();
+                break;
+
+            default:
+                ALOGE("Got unexpected return code %d from KeyStore::get()", rc);
+                // This shouldn't happen.  To be on the safe side, delete it.
+                shouldDelete = true;
+                break;
+            }
         }
         if (shouldDelete) {
             del(filename, ::TYPE_ANY, userId);
@@ -236,7 +260,7 @@
     UserState* userState = getUserState(userId);
     ResponseCode rc =
         keyBlob->readBlob(filename, userState->getDecryptionKey(), userState->getState());
-    if (rc != NO_ERROR) {
+    if (rc != ResponseCode::NO_ERROR) {
         return rc;
     }
 
@@ -247,28 +271,24 @@
          * it's written.
          */
         if (upgradeBlob(filename, keyBlob, version, type, userId)) {
-            if ((rc = this->put(filename, keyBlob, userId)) != NO_ERROR ||
+            if ((rc = this->put(filename, keyBlob, userId)) != ResponseCode::NO_ERROR ||
                 (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(),
-                                        userState->getState())) != NO_ERROR) {
+                                        userState->getState())) != ResponseCode::NO_ERROR) {
                 return rc;
             }
         }
     }
 
     /*
-     * This will upgrade software-backed keys to hardware-backed keys when
-     * the HAL for the device supports the newer key types.
+     * This will upgrade software-backed keys to hardware-backed keys.
      */
-    if (rc == NO_ERROR && type == TYPE_KEY_PAIR &&
-        mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2 &&
-        keyBlob->isFallback()) {
+    if (rc == ResponseCode::NO_ERROR && type == TYPE_KEY_PAIR && keyBlob->isFallback()) {
         ResponseCode imported =
             importKey(keyBlob->getValue(), keyBlob->getLength(), filename, userId,
                       keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
 
-        // The HAL allowed the import, reget the key to have the "fresh"
-        // version.
-        if (imported == NO_ERROR) {
+        // The HAL allowed the import, reget the key to have the "fresh" version.
+        if (imported == ResponseCode::NO_ERROR) {
             rc = get(filename, keyBlob, TYPE_KEY_PAIR, userId);
         }
     }
@@ -281,7 +301,7 @@
 
     if (type != TYPE_ANY && keyBlob->getType() != type) {
         ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type);
-        return KEY_NOT_FOUND;
+        return ResponseCode::KEY_NOT_FOUND;
     }
 
     return rc;
@@ -296,38 +316,27 @@
 ResponseCode KeyStore::del(const char* filename, const BlobType type, uid_t userId) {
     Blob keyBlob;
     ResponseCode rc = get(filename, &keyBlob, type, userId);
-    if (rc == ::VALUE_CORRUPTED) {
+    if (rc == ResponseCode::VALUE_CORRUPTED) {
         // The file is corrupt, the best we can do is rm it.
-        return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
+        return (unlink(filename) && errno != ENOENT) ?
+                ResponseCode::SYSTEM_ERROR : ResponseCode::NO_ERROR;
     }
-    if (rc != ::NO_ERROR) {
+    if (rc != ResponseCode::NO_ERROR) {
         return rc;
     }
 
-    if (keyBlob.getType() == ::TYPE_KEY_PAIR) {
+    auto& dev = getDevice(keyBlob);
+
+    if (keyBlob.getType() == ::TYPE_KEY_PAIR || keyBlob.getType() == ::TYPE_KEYMASTER_10) {
+        auto ret = KS_HANDLE_HIDL_ERROR(dev->deleteKey(blob2hidlVec(keyBlob)));
+
         // A device doesn't have to implement delete_key.
-        if (mDevice->delete_key != NULL && !keyBlob.isFallback()) {
-            keymaster_key_blob_t blob = {keyBlob.getValue(),
-                                         static_cast<size_t>(keyBlob.getLength())};
-            if (mDevice->delete_key(mDevice, &blob)) {
-                rc = ::SYSTEM_ERROR;
-            }
-        }
-    }
-    if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
-        auto* dev = getDeviceForBlob(keyBlob);
-        if (dev->delete_key) {
-            keymaster_key_blob_t blob;
-            blob.key_material = keyBlob.getValue();
-            blob.key_material_size = keyBlob.getLength();
-            dev->delete_key(dev, &blob);
-        }
-    }
-    if (rc != ::NO_ERROR) {
-        return rc;
+        if (ret != ErrorCode::OK && ret != ErrorCode::UNIMPLEMENTED)
+            return ResponseCode::SYSTEM_ERROR;
     }
 
-    return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
+    return (unlink(filename) && errno != ENOENT) ?
+            ResponseCode::SYSTEM_ERROR : ResponseCode::NO_ERROR;
 }
 
 /*
@@ -376,7 +385,7 @@
     DIR* dir = opendir(userState->getUserDirName());
     if (!dir) {
         ALOGW("can't open directory for user: %s", strerror(errno));
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     struct dirent* file;
@@ -407,7 +416,7 @@
         }
     }
     closedir(dir);
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
 void KeyStore::addGrant(const char* filename, uid_t granteeUid) {
@@ -436,74 +445,74 @@
                                  uid_t userId, int32_t flags) {
     Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, keyLen));
     if (!pkcs8.get()) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
     if (!pkey.get()) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     int type = EVP_PKEY_type(pkey->type);
-    android::KeymasterArguments params;
-    add_legacy_key_authorizations(type, &params.params);
+    AuthorizationSet params;
+    add_legacy_key_authorizations(type, &params);
     switch (type) {
     case EVP_PKEY_RSA:
-        params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_RSA));
+        params.push_back(TAG_ALGORITHM, Algorithm::RSA);
         break;
     case EVP_PKEY_EC:
-        params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_EC));
+        params.push_back(TAG_ALGORITHM, Algorithm::EC);
         break;
     default:
         ALOGW("Unsupported key type %d", type);
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
-    std::vector<keymaster_key_param_t> opParams(params.params);
-    const keymaster_key_param_set_t inParams = {opParams.data(), opParams.size()};
-    keymaster_blob_t input = {key, keyLen};
-    keymaster_key_blob_t blob = {nullptr, 0};
-    bool isFallback = false;
-    keymaster_error_t error = mDevice->import_key(mDevice, &inParams, KM_KEY_FORMAT_PKCS8, &input,
-                                                  &blob, NULL /* characteristics */);
-    if (error != KM_ERROR_OK) {
-        ALOGE("Keymaster error %d importing key pair, falling back", error);
+    AuthorizationSet opParams(params);
+    hidl_vec<uint8_t> blob;
 
-        /*
-         * There should be no way to get here.  Fallback shouldn't ever really happen
-         * because the main device may be many (SW, KM0/SW hybrid, KM1/SW hybrid), but it must
-         * provide full support of the API.  In any case, we'll do the fallback just for
-         * consistency... and I suppose to cover for broken HW implementations.
-         */
-        error = mFallbackDevice->import_key(mFallbackDevice, &inParams, KM_KEY_FORMAT_PKCS8, &input,
-                                            &blob, NULL /* characteristics */);
-        isFallback = true;
+    ErrorCode error;
+    auto hidlCb = [&] (ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
+            const KeyCharacteristics& /* ignored */) {
+        error = ret;
+        if (error != ErrorCode::OK) return;
+        blob = keyBlob;
+    };
+    auto input = blob2hidlVec(key, keyLen);
 
-        if (error) {
-            ALOGE("Keymaster error while importing key pair with fallback: %d", error);
-            return SYSTEM_ERROR;
-        }
+    ErrorCode rc = KS_HANDLE_HIDL_ERROR(
+            mDevice->importKey(params.hidl_data(), KeyFormat::PKCS8, input, hidlCb));
+    if (rc != ErrorCode::OK) return ResponseCode::SYSTEM_ERROR;
+    if (error != ErrorCode::OK) {
+        ALOGE("Keymaster error %d importing key pair", error);
+        return ResponseCode::SYSTEM_ERROR;
     }
 
-    Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, TYPE_KEYMASTER_10);
-    free(const_cast<uint8_t*>(blob.key_material));
+    Blob keyBlob(&blob[0], blob.size(), NULL, 0, TYPE_KEYMASTER_10);
 
     keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
-    keyBlob.setFallback(isFallback);
+    keyBlob.setFallback(false);
 
     return put(filename, &keyBlob, userId);
 }
 
-bool KeyStore::isHardwareBacked(const android::String16& keyType) const {
+bool KeyStore::isHardwareBacked(const android::String16& /*keyType*/) const {
+    using ::android::hardware::hidl_string;
     if (mDevice == NULL) {
         ALOGW("can't get keymaster device");
         return false;
     }
 
-    if (sRSAKeyType == keyType) {
-        return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0;
-    } else {
-        return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0 &&
-               (mDevice->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2);
+    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());
+        return false;
     }
+    return isSecure;
 }
 
 ResponseCode KeyStore::getKeyForName(Blob* keyBlob, const android::String8& keyName,
@@ -512,7 +521,7 @@
     uid_t userId = get_user_id(uid);
 
     ResponseCode responseCode = get(filepath8.string(), keyBlob, type, userId);
-    if (responseCode == NO_ERROR) {
+    if (responseCode == ResponseCode::NO_ERROR) {
         return responseCode;
     }
 
@@ -521,7 +530,7 @@
     if (euid != uid) {
         filepath8 = getKeyNameForUidWithDir(keyName, euid, type);
         responseCode = get(filepath8.string(), keyBlob, type, userId);
-        if (responseCode == NO_ERROR) {
+        if (responseCode == ResponseCode::NO_ERROR) {
             return responseCode;
         }
     }
@@ -531,7 +540,7 @@
     char* end;
     strtoul(filename8.string(), &end, 10);
     if (end[0] != '_' || end[1] == 0) {
-        return KEY_NOT_FOUND;
+        return ResponseCode::KEY_NOT_FOUND;
     }
     filepath8 = android::String8::format("%s/%s", getUserState(userId)->getUserDirName(),
                                          filename8.string());
@@ -645,32 +654,32 @@
     Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength()));
     if (b.get() == NULL) {
         ALOGE("Problem instantiating BIO");
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL));
     if (pkey.get() == NULL) {
         ALOGE("Couldn't read old PEM file");
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get()));
     int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL);
     if (len < 0) {
         ALOGE("Couldn't measure PKCS#8 length");
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]);
     uint8_t* tmp = pkcs8key.get();
     if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) {
         ALOGE("Couldn't convert to PKCS#8");
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     ResponseCode rc = importKey(pkcs8key.get(), len, filename, get_user_id(uid),
                                 blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
-    if (rc != NO_ERROR) {
+    if (rc != ResponseCode::NO_ERROR) {
         return rc;
     }
 
diff --git a/keystore/keystore.h b/keystore/keystore.h
index 278a0a0..8ff8899 100644
--- a/keystore/keystore.h
+++ b/keystore/keystore.h
@@ -19,27 +19,43 @@
 
 #include "user_state.h"
 
-#include <hardware/keymaster2.h>
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
 
 #include <utils/Vector.h>
 
 #include "blob.h"
+#include "include/keystore/keymaster_tags.h"
 
 typedef struct {
     uint32_t uid;
     const uint8_t* filename;
 } grant_t;
 
+using ::keystore::NullOr;
+
 class KeyStore {
+    typedef ::android::sp<::android::hardware::keymaster::V3_0::IKeymasterDevice> km_device_t;
+
   public:
-    KeyStore(Entropy* entropy, keymaster2_device_t* device, keymaster2_device_t* fallback);
+    KeyStore(Entropy* entropy, const km_device_t& device, const km_device_t& fallback,
+             bool allowNewFallback);
     ~KeyStore();
 
-    keymaster2_device_t* getDevice() const { return mDevice; }
+    km_device_t& getDevice() { return mDevice; }
 
-    keymaster2_device_t* getFallbackDevice() const { return mFallbackDevice; }
+    NullOr<km_device_t&> getFallbackDevice() {
+        // we only return the fallback device if the creation of new fallback key blobs is
+        // allowed. (also see getDevice below)
+        if (mAllowNewFallback) {
+            return mFallbackDevice;
+        } else {
+            return {};
+        }
+    }
 
-    keymaster2_device_t* getDeviceForBlob(const Blob& blob) const {
+    km_device_t& getDevice(const Blob& blob) {
+        // We return a device, based on the nature of the blob to provide backward
+        // compatibility with old key blobs generated using the fallback device.
         return blob.isFallback() ? mFallbackDevice : mDevice;
     }
 
@@ -115,8 +131,9 @@
     static const android::String16 sRSAKeyType;
     Entropy* mEntropy;
 
-    keymaster2_device_t* mDevice;
-    keymaster2_device_t* mFallbackDevice;
+    km_device_t mDevice;
+    km_device_t mFallbackDevice;
+    bool mAllowNewFallback;
 
     android::Vector<UserState*> mMasterKeys;
 
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.cpp b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
new file mode 100644
index 0000000..3137ae1
--- /dev/null
+++ b/keystore/keystore_aidl_hidl_marshalling_utils.cpp
@@ -0,0 +1,225 @@
+/*
+**
+** Copyright 2016, 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.
+*/
+
+#define LOG_TAG "KeystoreService"
+#include <utils/Log.h>
+
+#include "keystore_aidl_hidl_marshalling_utils.h"
+#include <keystore/keystore_hidl_support.h>
+
+namespace keystore {
+
+hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in, bool inPlace) {
+    ssize_t length = in.readInt32();
+    if (length <= 0) {
+        return {};
+    }
+
+    const void* buf = in.readInplace(length);
+    if (!buf) return {};
+
+    return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length), inPlace);
+}
+
+android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out) {
+    int32_t size = int32_t(std::min<size_t>(blob.size(), std::numeric_limits<int32_t>::max()));
+
+    auto rc = out->writeInt32(size);
+    if (rc != ::android::OK) return rc;
+
+    if (!size) return ::android::OK;
+
+    return out->write(&blob[0], size);
+}
+
+NullOr<hidl_vec<uint8_t>> readBlobAsByteArray(const android::Parcel& in, bool inPlace) {
+    // The distinction from readKeymasterBob is that the byte array is not prefixed with a presence
+    // value, instead a -1 in the length field indicates NULL.
+    ssize_t length = in.readInt32();
+    if (length < 0) {
+        return {};
+    }
+
+    if (length == 0) {
+        return hidl_vec<uint8_t>();
+    }
+
+    const void* buf = in.readInplace(length);
+    if (!buf) return hidl_vec<uint8_t>();
+
+    return blob2hidlVec(reinterpret_cast<const uint8_t*>(buf), size_t(length), inPlace);
+}
+
+android::status_t writeBlobAsByteArray(const NullOr<const hidl_vec<uint8_t>&>& blob,
+                                       android::Parcel* out) {
+    if (!blob.isOk()) {
+        return out->writeInt32(-1);
+    }
+    int32_t size =
+        int32_t(std::min<size_t>(blob.value().size(), std::numeric_limits<int32_t>::max()));
+
+    auto rc = out->writeInt32(size);
+    if (rc != ::android::OK) return rc;
+
+    if (!size) return ::android::OK;
+
+    return out->write(&blob.value()[0], size);
+}
+
+NullOr<KeyParameter> readKeyParameterFromParcel(const android::Parcel& in) {
+    if (in.readInt32() == 0) {
+        return {};
+    }
+    KeyParameter result;
+
+    Tag tag = static_cast<Tag>(in.readInt32());
+    result.tag = tag;
+    switch (typeFromTag(tag)) {
+    case TagType::ENUM:
+    case TagType::ENUM_REP:
+    case TagType::UINT:
+    case TagType::UINT_REP:
+        result.f.integer = in.readInt32();
+        break;
+    case TagType::ULONG:
+    case TagType::ULONG_REP:
+    case TagType::DATE:
+        result.f.longInteger = in.readInt64();
+        break;
+    case TagType::BOOL:
+        result.f.boolValue = true;
+        break;
+    case TagType::BIGNUM:
+    case TagType::BYTES:
+        result.blob = readKeymasterBlob(in);
+        break;
+    default:
+        ALOGE("Unsupported KeyParameter tag %d", tag);
+        return {};
+    }
+    return result;
+}
+
+android::status_t writeKeyParameterToParcel(const KeyParameter& param, android::Parcel* out) {
+    auto tag = param.tag;
+    auto rc = out->writeInt32(uint32_t(tag));
+    if (rc != ::android::OK) return rc;
+    switch (typeFromTag(param.tag)) {
+    case TagType::ENUM:
+    case TagType::ENUM_REP:
+    case TagType::UINT:
+    case TagType::UINT_REP:
+        rc = out->writeInt32(param.f.integer);
+        break;
+    case TagType::ULONG:
+    case TagType::ULONG_REP:
+    case TagType::DATE:
+        rc = out->writeInt64(param.f.longInteger);
+        break;
+    case TagType::BOOL:
+        // nothing to do here presence indicates true
+        break;
+    case TagType::BIGNUM:
+    case TagType::BYTES:
+        rc = writeKeymasterBlob(param.blob, out);
+        break;
+    default:
+        ALOGE("Failed to write KeyParameter: Unsupported tag %d", param.tag);
+        rc = android::BAD_VALUE;
+        break;
+    }
+    return rc;
+}
+
+hidl_vec<KeyParameter> readParamSetFromParcel(const android::Parcel& in) {
+    ssize_t length = in.readInt32();
+    size_t ulength = (size_t)length;
+    if (length < 0) {
+        ulength = 0;
+    }
+    hidl_vec<KeyParameter> result;
+    result.resize(ulength);
+    for (size_t i = 0; i < ulength; ++i) {
+        auto param = readKeyParameterFromParcel(in);
+        if (!param.isOk()) {
+            ALOGE("Error reading KeyParameter from parcel");
+            return {};
+        }
+        result[i] = param.value();
+    }
+    return result;
+}
+
+android::status_t writeParamSetToParcel(const hidl_vec<KeyParameter>& params,
+                                        android::Parcel* out) {
+    int32_t size = int32_t(std::min<size_t>(params.size(), std::numeric_limits<int32_t>::max()));
+
+    auto rc = out->writeInt32(size);
+    if (rc != ::android::OK) return rc;
+    for (int32_t i = 0; i < size; ++i) {
+        rc = out->writeInt32(1);
+        if (rc != ::android::OK) return rc;
+        rc = writeKeyParameterToParcel(params[i], out);
+        if (rc != ::android::OK) return rc;
+    }
+    return rc;
+}
+
+KeyCharacteristics readKeyCharacteristicsFromParcel(const android::Parcel& in) {
+    KeyCharacteristics result;
+    result.softwareEnforced = readParamSetFromParcel(in);
+    result.teeEnforced = readParamSetFromParcel(in);
+    return result;
+}
+
+android::status_t writeKeyCharacteristicsToParcel(const KeyCharacteristics& keyChara,
+                                                  android::Parcel* out) {
+    auto rc = writeParamSetToParcel(keyChara.softwareEnforced, out);
+    if (rc != ::android::OK) return rc;
+
+    return writeParamSetToParcel(keyChara.teeEnforced, out);
+}
+
+hidl_vec<hidl_vec<uint8_t>> readCertificateChainFromParcel(const android::Parcel& in) {
+    hidl_vec<hidl_vec<uint8_t>> result;
+
+    ssize_t count = in.readInt32();
+    size_t ucount = count;
+    if (count <= 0) {
+        return result;
+    }
+
+    result.resize(ucount);
+
+    for (size_t i = 0; i < ucount; ++i) {
+        result[i] = readKeymasterBlob(in);
+    }
+    return result;
+}
+
+android::status_t writeCertificateChainToParcel(const hidl_vec<hidl_vec<uint8_t>>& certs,
+                                                android::Parcel* out) {
+    int32_t count = int32_t(std::min<size_t>(certs.size(), std::numeric_limits<int32_t>::max()));
+    auto rc = out->writeInt32(count);
+
+    for (int32_t i = 0; i < count; ++i) {
+        rc = writeKeymasterBlob(certs[i], out);
+        if (rc != ::android::OK) return rc;
+    }
+    return rc;
+}
+}
diff --git a/keystore/keystore_aidl_hidl_marshalling_utils.h b/keystore/keystore_aidl_hidl_marshalling_utils.h
new file mode 100644
index 0000000..fcd02ae
--- /dev/null
+++ b/keystore/keystore_aidl_hidl_marshalling_utils.h
@@ -0,0 +1,83 @@
+/*
+**
+** Copyright 2016, 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_KEYSTORE_AIDL_HIDL_MARSHALLING_UTILS_H_
+#define KEYSTORE_KEYSTORE_AIDL_HIDL_MARSHALLING_UTILS_H_
+
+#include <binder/Parcel.h>
+#include <keystore/keymaster_tags.h>
+#include <utility>
+
+namespace keystore {
+
+template <typename Fn, typename... Args>
+inline auto nullable(Fn fn, const android::Parcel& in, Args&&... args)
+    -> NullOr<decltype(fn(in, std::forward<Args>(args)...))> {
+    if (in.readInt32() != 1) {
+        return {};
+    }
+
+    return fn(in, std::forward<Args>(args)...);
+}
+template <typename Fn, typename Arg>
+inline android::status_t nullable(Fn fn, const NullOr<Arg>& arg, android::Parcel* out) {
+    if (!arg.isOk()) {
+        return out->writeInt32(0);
+    }
+    auto rc = out->writeInt32(1);
+    if (rc != ::android::OK) return rc;
+
+    return fn(arg.value(), out);
+}
+template <typename Fn, typename Arg>
+inline android::status_t nullable(Fn fn, Arg&& arg, android::Parcel* out) {
+    auto rc = out->writeInt32(1);
+    if (rc != ::android::OK) return rc;
+
+    return fn(std::forward<Arg>(arg), out);
+}
+
+inline android::status_t nullable(android::Parcel* out) {
+    return out->writeInt32(0);
+}
+
+/**
+ * makes a copy only if inPlace is false
+ */
+hidl_vec<uint8_t> readKeymasterBlob(const android::Parcel& in, bool inPlace = true);
+android::status_t writeKeymasterBlob(const hidl_vec<uint8_t>& blob, android::Parcel* out);
+
+NullOr<hidl_vec<uint8_t>> readBlobAsByteArray(const android::Parcel& in, bool inPlace = true);
+android::status_t writeBlobAsByteArray(const NullOr<const hidl_vec<uint8_t>&>& blob,
+                                       android::Parcel* out);
+
+NullOr<KeyParameter> readKeyParameterFromParcel(const android::Parcel& in);
+android::status_t writeKeyParameterToParcel(const KeyParameter& param, android::Parcel* out);
+
+hidl_vec<KeyParameter> readParamSetFromParcel(const android::Parcel& in);
+android::status_t writeParamSetToParcel(const hidl_vec<KeyParameter>& params, android::Parcel* out);
+
+KeyCharacteristics readKeyCharacteristicsFromParcel(const android::Parcel& in);
+android::status_t writeKeyCharacteristicsToParcel(const KeyCharacteristics& keyChara,
+                                                  android::Parcel* out);
+
+hidl_vec<hidl_vec<uint8_t>> readCertificateChainFromParcel(const android::Parcel& in);
+android::status_t writeCertificateChainToParcel(const hidl_vec<hidl_vec<uint8_t>>& certs,
+                                                android::Parcel* out);
+}
+
+#endif  // KEYSTORE_KEYSTORE_AIDL_HIDL_MARSHALLING_UTILS_H_
diff --git a/keystore/keystore_attestation_id.cpp b/keystore/keystore_attestation_id.cpp
new file mode 100644
index 0000000..830482b
--- /dev/null
+++ b/keystore/keystore_attestation_id.cpp
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "keystore_attestation_id.h"
+
+#define LOG_TAG "keystore_att_id"
+
+#include <cutils/log.h>
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <binder/IServiceManager.h>
+#include <binder/Parcel.h>
+#include <binder/Parcelable.h>
+#include <binder/PersistableBundle.h>
+
+#include <android/security/keymaster/BpKeyAttestationApplicationIdProvider.h>
+#include <android/security/keymaster/IKeyAttestationApplicationIdProvider.h>
+#include <keystore/KeyAttestationApplicationId.h>
+#include <keystore/KeyAttestationPackageInfo.h>
+#include <keystore/Signature.h>
+
+#include <openssl/asn1t.h>
+#include <openssl/sha.h>
+
+#include <utils/String8.h>
+
+namespace android {
+
+namespace {
+
+static std::vector<uint8_t> signature2SHA256(const content::pm::Signature& sig) {
+    std::vector<uint8_t> digest_buffer(SHA256_DIGEST_LENGTH);
+    SHA256(sig.data().data(), sig.data().size(), digest_buffer.data());
+    return digest_buffer;
+}
+
+using ::android::security::keymaster::BpKeyAttestationApplicationIdProvider;
+
+class KeyAttestationApplicationIdProvider : public BpKeyAttestationApplicationIdProvider {
+  public:
+    KeyAttestationApplicationIdProvider();
+
+    static KeyAttestationApplicationIdProvider& get();
+
+  private:
+    android::sp<android::IServiceManager> service_manager_;
+};
+
+KeyAttestationApplicationIdProvider& KeyAttestationApplicationIdProvider::get() {
+    static KeyAttestationApplicationIdProvider mpm;
+    return mpm;
+}
+
+KeyAttestationApplicationIdProvider::KeyAttestationApplicationIdProvider()
+    : BpKeyAttestationApplicationIdProvider(
+          android::defaultServiceManager()->getService(String16("sec_key_att_app_id_provider"))) {}
+
+DECLARE_STACK_OF(ASN1_OCTET_STRING);
+
+typedef struct km_attestation_package_info {
+    ASN1_OCTET_STRING* package_name;
+    ASN1_INTEGER* version;
+} KM_ATTESTATION_PACKAGE_INFO;
+
+ASN1_SEQUENCE(KM_ATTESTATION_PACKAGE_INFO) = {
+    ASN1_SIMPLE(KM_ATTESTATION_PACKAGE_INFO, package_name, ASN1_OCTET_STRING),
+    ASN1_SIMPLE(KM_ATTESTATION_PACKAGE_INFO, version, ASN1_INTEGER),
+} ASN1_SEQUENCE_END(KM_ATTESTATION_PACKAGE_INFO);
+IMPLEMENT_ASN1_FUNCTIONS(KM_ATTESTATION_PACKAGE_INFO);
+
+DECLARE_STACK_OF(KM_ATTESTATION_PACKAGE_INFO);
+
+typedef struct km_attestation_application_id {
+    STACK_OF(KM_ATTESTATION_PACKAGE_INFO) * package_infos;
+    STACK_OF(ASN1_OCTET_STRING) * signature_digests;
+} KM_ATTESTATION_APPLICATION_ID;
+
+ASN1_SEQUENCE(KM_ATTESTATION_APPLICATION_ID) = {
+    ASN1_SET_OF(KM_ATTESTATION_APPLICATION_ID, package_infos, KM_ATTESTATION_PACKAGE_INFO),
+    ASN1_SET_OF(KM_ATTESTATION_APPLICATION_ID, signature_digests, ASN1_OCTET_STRING),
+} ASN1_SEQUENCE_END(KM_ATTESTATION_APPLICATION_ID);
+IMPLEMENT_ASN1_FUNCTIONS(KM_ATTESTATION_APPLICATION_ID);
+}
+
+}  // namespace android
+
+namespace std {
+template <> struct default_delete<android::KM_ATTESTATION_PACKAGE_INFO> {
+    void operator()(android::KM_ATTESTATION_PACKAGE_INFO* p) {
+        android::KM_ATTESTATION_PACKAGE_INFO_free(p);
+    }
+};
+template <> struct default_delete<ASN1_OCTET_STRING> {
+    void operator()(ASN1_OCTET_STRING* p) { ASN1_OCTET_STRING_free(p); }
+};
+template <> struct default_delete<android::KM_ATTESTATION_APPLICATION_ID> {
+    void operator()(android::KM_ATTESTATION_APPLICATION_ID* p) {
+        android::KM_ATTESTATION_APPLICATION_ID_free(p);
+    }
+};
+}  // namespace std
+
+namespace android {
+namespace security {
+namespace {
+
+using ::android::security::keymaster::KeyAttestationApplicationId;
+using ::android::security::keymaster::KeyAttestationPackageInfo;
+
+status_t build_attestation_package_info(const KeyAttestationPackageInfo& pinfo,
+    std::unique_ptr<KM_ATTESTATION_PACKAGE_INFO>* attestation_package_info_ptr) {
+
+    if (!attestation_package_info_ptr) return BAD_VALUE;
+    auto& attestation_package_info = *attestation_package_info_ptr;
+
+    attestation_package_info.reset(KM_ATTESTATION_PACKAGE_INFO_new());
+    if (!attestation_package_info.get()) return NO_MEMORY;
+
+    if (!pinfo.package_name()) {
+        ALOGE("Key attestation package info lacks package name");
+        return BAD_VALUE;
+    }
+
+    std::string pkg_name(String8(*pinfo.package_name()).string());
+    if (!ASN1_OCTET_STRING_set(attestation_package_info->package_name,
+                               reinterpret_cast<const unsigned char*>(pkg_name.data()),
+                               pkg_name.size())) {
+        return UNKNOWN_ERROR;
+    }
+
+    if (!ASN1_INTEGER_set(attestation_package_info->version, pinfo.version_code())) {
+        return UNKNOWN_ERROR;
+    }
+    return NO_ERROR;
+}
+
+StatusOr<std::vector<uint8_t>>
+build_attestation_application_id(const KeyAttestationApplicationId& key_attestation_id) {
+    auto attestation_id =
+        std::unique_ptr<KM_ATTESTATION_APPLICATION_ID>(KM_ATTESTATION_APPLICATION_ID_new());
+
+    auto attestation_pinfo_stack = reinterpret_cast<_STACK*>(attestation_id->package_infos);
+
+    if (key_attestation_id.pinfos_begin() == key_attestation_id.pinfos_end()) return BAD_VALUE;
+
+    for (auto pinfo = key_attestation_id.pinfos_begin(); pinfo != key_attestation_id.pinfos_end();
+         ++pinfo) {
+        if (!pinfo->package_name()) {
+            ALOGE("Key attestation package info lacks package name");
+            return BAD_VALUE;
+        }
+        std::string package_name(String8(*pinfo->package_name()).string());
+        std::unique_ptr<KM_ATTESTATION_PACKAGE_INFO> attestation_package_info;
+        auto rc = build_attestation_package_info(*pinfo, &attestation_package_info);
+        if (rc != NO_ERROR) {
+            ALOGE("Building DER attestation package info failed %d", rc);
+            return rc;
+        }
+        if (!sk_push(attestation_pinfo_stack, attestation_package_info.get())) {
+            return NO_MEMORY;
+        }
+        // if push succeeded, the stack takes ownership
+        attestation_package_info.release();
+    }
+
+    /** Apps can only share a uid iff they were signed with the same certificate(s). Because the
+     *  signature field actually holds the signing certificate, rather than a signature, we can
+     *  simply use the set of signature digests of the first package info.
+     */
+    const auto& pinfo = *key_attestation_id.pinfos_begin();
+    std::vector<std::vector<uint8_t>> signature_digests;
+
+    for (auto sig = pinfo.sigs_begin(); sig != pinfo.sigs_end(); ++sig) {
+        signature_digests.push_back(signature2SHA256(*sig));
+    }
+
+    auto signature_digest_stack = reinterpret_cast<_STACK*>(attestation_id->signature_digests);
+    for (auto si : signature_digests) {
+        auto asn1_item = std::unique_ptr<ASN1_OCTET_STRING>(ASN1_OCTET_STRING_new());
+        if (!asn1_item) return NO_MEMORY;
+        if (!ASN1_OCTET_STRING_set(asn1_item.get(), si.data(), si.size())) {
+            return UNKNOWN_ERROR;
+        }
+        if (!sk_push(signature_digest_stack, asn1_item.get())) {
+            return NO_MEMORY;
+        }
+        asn1_item.release();  // if push succeeded, the stack takes ownership
+    }
+
+    int len = i2d_KM_ATTESTATION_APPLICATION_ID(attestation_id.get(), nullptr);
+    if (len < 0) return UNKNOWN_ERROR;
+
+    std::vector<uint8_t> result(len);
+    uint8_t* p = result.data();
+    len = i2d_KM_ATTESTATION_APPLICATION_ID(attestation_id.get(), &p);
+    if (len < 0) return UNKNOWN_ERROR;
+
+    return result;
+}
+
+/* The following function are not used. They are mentioned here to silence
+ * warnings about them not being used.
+ */
+void unused_functions_silencer() __attribute__((unused));
+void unused_functions_silencer() {
+    i2d_KM_ATTESTATION_PACKAGE_INFO(nullptr, nullptr);
+    d2i_KM_ATTESTATION_APPLICATION_ID(nullptr, nullptr, 0);
+    d2i_KM_ATTESTATION_PACKAGE_INFO(nullptr, nullptr, 0);
+}
+
+}  // namespace
+
+StatusOr<std::vector<uint8_t>> gather_attestation_application_id(uid_t uid) {
+    auto& pm = KeyAttestationApplicationIdProvider::get();
+
+    /* Get the attestation application ID from package manager */
+    KeyAttestationApplicationId key_attestation_id;
+    auto status = pm.getKeyAttestationApplicationId(uid, &key_attestation_id);
+    if (!status.isOk()) {
+        ALOGE("package manager request for key attestation ID failed with: %s",
+              status.exceptionMessage().string());
+        return FAILED_TRANSACTION;
+    }
+
+    /* DER encode the attestation application ID */
+    return build_attestation_application_id(key_attestation_id);
+}
+
+}  // namespace security
+}  // namespace android
diff --git a/keystore/keystore_attestation_id.h b/keystore/keystore_attestation_id.h
new file mode 100644
index 0000000..8d20550
--- /dev/null
+++ b/keystore/keystore_attestation_id.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2016 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_KEYSTORE_ATTESTATION_ID_H_
+#define KEYSTORE_KEYSTORE_ATTESTATION_ID_H_
+
+#include <utils/Errors.h>
+#include <vector>
+
+namespace android {
+namespace security {
+
+template <typename T> class StatusOr {
+  public:
+    StatusOr(const status_t error) : _status(error), _value() {}
+    StatusOr(const T& value) : _status(NO_ERROR), _value(value) {}
+    StatusOr(T&& value) : _status(NO_ERROR), _value(value) {}
+
+    operator const T&() const { return _value; }
+    operator T&() { return _value; }
+    operator T &&() && { return std::move(_value); }
+
+    bool isOk() const { return NO_ERROR == _status; }
+
+    ::android::status_t status() const { return _status; }
+
+    const T& value() const & { return _value; }
+    T& value() & { return _value; }
+    T&& value() && { return std::move(_value); }
+
+  private:
+    ::android::status_t _status;
+    T _value;
+};
+
+/**
+ * Gathers the attestation id for the application determined by uid by querying the package manager
+ * As of this writing uids can be shared in android, which is why the asn.1 encoded attestation
+ * application id may contain more than one package info followed by a set of digests of the
+ * packages signing certificates.
+ *
+ * @returns the asn.1 encoded attestation application id or an error code. Check the result with
+ *          .isOk() before accessing.
+ */
+StatusOr<std::vector<uint8_t>> gather_attestation_application_id(uid_t uid);
+
+}  // namespace security
+}  // namespace android
+#endif  // KEYSTORE_KEYSTORE_ATTESTATION_ID_H_
diff --git a/keystore/keystore_cli.cpp b/keystore/keystore_cli.cpp
index d9781e0..24af024 100644
--- a/keystore/keystore_cli.cpp
+++ b/keystore/keystore_cli.cpp
@@ -26,6 +26,7 @@
 #include <keystore/keystore.h>
 
 using namespace android;
+using namespace keystore;
 
 static const char* responses[] = {
     NULL,
@@ -124,14 +125,13 @@
                 fprintf(stderr, "Usage: %s " #cmd " <name> <uid>\n", argv[0]); \
                 return 1; \
             } \
-            uint8_t* data; \
-            size_t dataSize; \
+            hidl_vec<uint8_t> data; \
             int uid = -1; \
             if (argc > 3) { \
                 uid = atoi(argv[3]); \
                 fprintf(stderr, "Running as uid %d\n", uid); \
             } \
-            int32_t ret = service->cmd(String16(argv[2]), uid, &data, &dataSize); \
+            int32_t ret = service->cmd(String16(argv[2]), uid, &data); \
             if (ret < 0) { \
                 fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
                 return 1; \
@@ -139,9 +139,8 @@
                 fprintf(stderr, "%s: " #cmd ": %s (%d)\n", argv[0], responses[ret], ret); \
                 return 1; \
             } else { \
-                fwrite(data, dataSize, 1, stdout); \
+                fwrite(&data[0], data.size(), 1, stdout); \
                 fflush(stdout); \
-                free(data); \
                 return 0; \
             } \
         } \
@@ -175,9 +174,8 @@
                 fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
                 return 1; \
             } \
-            uint8_t* data; \
-            size_t dataSize; \
-            int32_t ret = service->cmd(String16(argv[2]), &data, &dataSize); \
+            hidl_vec<uint8_t> data; \
+            int32_t ret = service->cmd(String16(argv[2]), &data); \
             if (ret < 0) { \
                 fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
                 return 1; \
@@ -185,9 +183,8 @@
                 fprintf(stderr, "%s: " #cmd ": %s (%d)\n", argv[0], responses[ret], ret); \
                 return 1; \
             } else { \
-                fwrite(data, dataSize, 1, stdout); \
+                fwrite(&data[0], data.size(), 1, stdout); \
                 fflush(stdout); \
-                free(data); \
                 return 0; \
             } \
         } \
diff --git a/keystore/keystore_cli_v2.cpp b/keystore/keystore_cli_v2.cpp
index 6c229db..95fc491 100644
--- a/keystore/keystore_cli_v2.cpp
+++ b/keystore/keystore_cli_v2.cpp
@@ -20,16 +20,17 @@
 #include "base/command_line.h"
 #include "base/files/file_util.h"
 #include "base/strings/string_util.h"
-#include "keymaster/authorization_set.h"
-#include "keymaster/keymaster_tags.h"
+#include "keystore/authorization_set.h"
+#include "keystore/keymaster_tags.h"
 #include "keystore/keystore_client_impl.h"
 
 using base::CommandLine;
-using keymaster::AuthorizationSet;
-using keymaster::AuthorizationSetBuilder;
+using keystore::AuthorizationSet;
+//using keymaster::AuthorizationSetBuilder;
 using keystore::KeystoreClient;
 
 namespace {
+using namespace keystore;
 
 struct TestCase {
     std::string name;
@@ -55,17 +56,13 @@
 }
 
 std::unique_ptr<KeystoreClient> CreateKeystoreInstance() {
-    return std::unique_ptr<KeystoreClient>(new keystore::KeystoreClientImpl);
+    return std::unique_ptr<KeystoreClient>(
+            static_cast<KeystoreClient*>(new keystore::KeystoreClientImpl));
 }
 
-#ifndef KEYMASTER_NAME_TAGS
-#error KEYMASTER_NAME_TAGS must be defined
-#endif
-
 void PrintTags(const AuthorizationSet& parameters) {
-    const keymaster_key_param_t* iter = nullptr;
-    for (iter = parameters.begin(); iter != parameters.end(); ++iter) {
-        printf("  %s\n", keymaster::StringifyTag(iter->tag));
+    for (auto iter = parameters.begin(); iter != parameters.end(); ++iter) {
+        printf("  %s\n", stringifyTag(iter->tag));
     }
 }
 
@@ -81,16 +78,16 @@
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    int32_t result = keystore->generateKey("tmp", parameters, &hardware_enforced_characteristics,
+    auto result = keystore->generateKey("tmp", parameters, &hardware_enforced_characteristics,
                                            &software_enforced_characteristics);
     const char kBoldRedAbort[] = "\033[1;31mABORT\033[0m";
-    if (result != KM_ERROR_OK) {
+    if (!result.isOk()) {
         LOG(ERROR) << "Failed to generate key: " << result;
         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
         return false;
     }
     result = keystore->deleteKey("tmp");
-    if (result != KM_ERROR_OK) {
+    if (!result.isOk()) {
         LOG(ERROR) << "Failed to delete key: " << result;
         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
         return false;
@@ -99,9 +96,9 @@
     printf("%s Key Characteristics:\n", name.c_str());
     PrintKeyCharacteristics(hardware_enforced_characteristics, software_enforced_characteristics);
     bool hardware_backed = (hardware_enforced_characteristics.size() > 0);
-    if (software_enforced_characteristics.GetTagCount(KM_TAG_ALGORITHM) > 0 ||
-        software_enforced_characteristics.GetTagCount(KM_TAG_KEY_SIZE) > 0 ||
-        software_enforced_characteristics.GetTagCount(KM_TAG_RSA_PUBLIC_EXPONENT) > 0) {
+    if (software_enforced_characteristics.GetTagCount(TAG_ALGORITHM) > 0 ||
+        software_enforced_characteristics.GetTagCount(TAG_KEY_SIZE) > 0 ||
+        software_enforced_characteristics.GetTagCount(TAG_RSA_PUBLIC_EXPONENT) > 0) {
         VLOG(1) << "Hardware-backed key but required characteristics enforced in software.";
         hardware_backed = false;
     }
@@ -118,62 +115,62 @@
 AuthorizationSet GetRSASignParameters(uint32_t key_size, bool sha256_only) {
     AuthorizationSetBuilder parameters;
     parameters.RsaSigningKey(key_size, 65537)
-        .Digest(KM_DIGEST_SHA_2_256)
-        .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)
-        .Padding(KM_PAD_RSA_PSS)
-        .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+        .Digest(Digest::SHA_2_256)
+        .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
+        .Padding(PaddingMode::RSA_PSS)
+        .Authorization(TAG_NO_AUTH_REQUIRED);
     if (!sha256_only) {
-        parameters.Digest(KM_DIGEST_SHA_2_224)
-            .Digest(KM_DIGEST_SHA_2_384)
-            .Digest(KM_DIGEST_SHA_2_512);
+        parameters.Digest(Digest::SHA_2_224)
+            .Digest(Digest::SHA_2_384)
+            .Digest(Digest::SHA_2_512);
     }
-    return parameters.build();
+    return parameters;
 }
 
 AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) {
     AuthorizationSetBuilder parameters;
     parameters.RsaEncryptionKey(key_size, 65537)
-        .Padding(KM_PAD_RSA_PKCS1_1_5_ENCRYPT)
-        .Padding(KM_PAD_RSA_OAEP)
-        .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
-    return parameters.build();
+        .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
+        .Padding(PaddingMode::RSA_OAEP)
+        .Authorization(TAG_NO_AUTH_REQUIRED);
+    return parameters;
 }
 
 AuthorizationSet GetECDSAParameters(uint32_t key_size, bool sha256_only) {
     AuthorizationSetBuilder parameters;
     parameters.EcdsaSigningKey(key_size)
-        .Digest(KM_DIGEST_SHA_2_256)
-        .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+        .Digest(Digest::SHA_2_256)
+        .Authorization(TAG_NO_AUTH_REQUIRED);
     if (!sha256_only) {
-        parameters.Digest(KM_DIGEST_SHA_2_224)
-            .Digest(KM_DIGEST_SHA_2_384)
-            .Digest(KM_DIGEST_SHA_2_512);
+        parameters.Digest(Digest::SHA_2_224)
+            .Digest(Digest::SHA_2_384)
+            .Digest(Digest::SHA_2_512);
     }
-    return parameters.build();
+    return parameters;
 }
 
 AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) {
     AuthorizationSetBuilder parameters;
-    parameters.AesEncryptionKey(key_size).Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+    parameters.AesEncryptionKey(key_size).Authorization(TAG_NO_AUTH_REQUIRED);
     if (with_gcm_mode) {
-        parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_GCM)
-            .Authorization(keymaster::TAG_MIN_MAC_LENGTH, 128);
+        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
+            .Authorization(TAG_MIN_MAC_LENGTH, 128);
     } else {
-        parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_ECB);
-        parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CBC);
-        parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CTR);
-        parameters.Padding(KM_PAD_NONE);
+        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
+        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
+        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CTR);
+        parameters.Padding(PaddingMode::NONE);
     }
-    return parameters.build();
+    return parameters;
 }
 
-AuthorizationSet GetHMACParameters(uint32_t key_size, keymaster_digest_t digest) {
+AuthorizationSet GetHMACParameters(uint32_t key_size, Digest digest) {
     AuthorizationSetBuilder parameters;
     parameters.HmacKey(key_size)
         .Digest(digest)
-        .Authorization(keymaster::TAG_MIN_MAC_LENGTH, 224)
-        .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
-    return parameters.build();
+        .Authorization(TAG_MIN_MAC_LENGTH, 224)
+        .Authorization(TAG_NO_AUTH_REQUIRED);
+    return parameters;
 }
 
 std::vector<TestCase> GetTestCases() {
@@ -194,12 +191,12 @@
         {"AES-256", true, GetAESParameters(256, false)},
         {"AES-128-GCM", false, GetAESParameters(128, true)},
         {"AES-256-GCM", false, GetAESParameters(256, true)},
-        {"HMAC-SHA256-16", true, GetHMACParameters(16, KM_DIGEST_SHA_2_256)},
-        {"HMAC-SHA256-32", true, GetHMACParameters(32, KM_DIGEST_SHA_2_256)},
-        {"HMAC-SHA256-64", false, GetHMACParameters(64, KM_DIGEST_SHA_2_256)},
-        {"HMAC-SHA224-32", false, GetHMACParameters(32, KM_DIGEST_SHA_2_224)},
-        {"HMAC-SHA384-32", false, GetHMACParameters(32, KM_DIGEST_SHA_2_384)},
-        {"HMAC-SHA512-32", false, GetHMACParameters(32, KM_DIGEST_SHA_2_512)},
+        {"HMAC-SHA256-16", true, GetHMACParameters(16, Digest::SHA_2_256)},
+        {"HMAC-SHA256-32", true, GetHMACParameters(32, Digest::SHA_2_256)},
+        {"HMAC-SHA256-64", false, GetHMACParameters(64, Digest::SHA_2_256)},
+        {"HMAC-SHA224-32", false, GetHMACParameters(32, Digest::SHA_2_224)},
+        {"HMAC-SHA384-32", false, GetHMACParameters(32, Digest::SHA_2_384)},
+        {"HMAC-SHA512-32", false, GetHMACParameters(32, Digest::SHA_2_512)},
     };
     return std::vector<TestCase>(&test_cases[0], &test_cases[arraysize(test_cases)]);
 }
@@ -273,19 +270,19 @@
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSetBuilder params;
     params.RsaSigningKey(2048, 65537)
-        .Digest(KM_DIGEST_SHA_2_224)
-        .Digest(KM_DIGEST_SHA_2_256)
-        .Digest(KM_DIGEST_SHA_2_384)
-        .Digest(KM_DIGEST_SHA_2_512)
-        .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)
-        .Padding(KM_PAD_RSA_PSS)
-        .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+        .Digest(Digest::SHA_2_224)
+        .Digest(Digest::SHA_2_256)
+        .Digest(Digest::SHA_2_384)
+        .Digest(Digest::SHA_2_512)
+        .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
+        .Padding(PaddingMode::RSA_PSS)
+        .Authorization(TAG_NO_AUTH_REQUIRED);
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    int32_t result = keystore->generateKey(name, params.build(), &hardware_enforced_characteristics,
+    auto result = keystore->generateKey(name, params, &hardware_enforced_characteristics,
                                            &software_enforced_characteristics);
-    printf("GenerateKey: %d\n", result);
-    if (result == KM_ERROR_OK) {
+    printf("GenerateKey: %d\n", int32_t(result));
+    if (result.isOk()) {
         PrintKeyCharacteristics(hardware_enforced_characteristics,
                                 software_enforced_characteristics);
     }
@@ -296,10 +293,10 @@
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    int32_t result = keystore->getKeyCharacteristics(name, &hardware_enforced_characteristics,
+    auto result = keystore->getKeyCharacteristics(name, &hardware_enforced_characteristics,
                                                      &software_enforced_characteristics);
-    printf("GetCharacteristics: %d\n", result);
-    if (result == KM_ERROR_OK) {
+    printf("GetCharacteristics: %d\n", int32_t(result));
+    if (result.isOk()) {
         PrintKeyCharacteristics(hardware_enforced_characteristics,
                                 software_enforced_characteristics);
     }
@@ -309,7 +306,7 @@
 int ExportKey(const std::string& name) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     std::string data;
-    int32_t result = keystore->exportKey(KM_KEY_FORMAT_X509, name, &data);
+    int32_t result = keystore->exportKey(KeyFormat::X509, name, &data);
     printf("ExportKey: %d (%zu)\n", result, data.size());
     return result;
 }
@@ -351,14 +348,14 @@
 int SignAndVerify(const std::string& name) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSetBuilder sign_params;
-    sign_params.Padding(KM_PAD_RSA_PKCS1_1_5_SIGN);
-    sign_params.Digest(KM_DIGEST_SHA_2_256);
+    sign_params.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
+    sign_params.Digest(Digest::SHA_2_256);
     AuthorizationSet output_params;
-    keymaster_operation_handle_t handle;
-    int32_t result = keystore->beginOperation(KM_PURPOSE_SIGN, name, sign_params.build(),
+    uint64_t handle;
+    auto result = keystore->beginOperation(KeyPurpose::SIGN, name, sign_params,
                                               &output_params, &handle);
-    if (result != KM_ERROR_OK) {
-        printf("Sign: BeginOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Sign: BeginOperation failed: %d\n", int32_t(result));
         return result;
     }
     AuthorizationSet empty_params;
@@ -366,40 +363,40 @@
     std::string output_data;
     result = keystore->updateOperation(handle, empty_params, "data_to_sign",
                                        &num_input_bytes_consumed, &output_params, &output_data);
-    if (result != KM_ERROR_OK) {
-        printf("Sign: UpdateOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Sign: UpdateOperation failed: %d\n", int32_t(result));
         return result;
     }
     result = keystore->finishOperation(handle, empty_params, std::string() /*signature_to_verify*/,
                                        &output_params, &output_data);
-    if (result != KM_ERROR_OK) {
-        printf("Sign: FinishOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Sign: FinishOperation failed: %d\n", int32_t(result));
         return result;
     }
     printf("Sign: %zu bytes.\n", output_data.size());
     // We have a signature, now verify it.
     std::string signature_to_verify = output_data;
     output_data.clear();
-    result = keystore->beginOperation(KM_PURPOSE_VERIFY, name, sign_params.build(), &output_params,
+    result = keystore->beginOperation(KeyPurpose::VERIFY, name, sign_params, &output_params,
                                       &handle);
-    if (result != KM_ERROR_OK) {
-        printf("Verify: BeginOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Verify: BeginOperation failed: %d\n", int32_t(result));
         return result;
     }
     result = keystore->updateOperation(handle, empty_params, "data_to_sign",
                                        &num_input_bytes_consumed, &output_params, &output_data);
-    if (result != KM_ERROR_OK) {
-        printf("Verify: UpdateOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Verify: UpdateOperation failed: %d\n", int32_t(result));
         return result;
     }
     result = keystore->finishOperation(handle, empty_params, signature_to_verify, &output_params,
                                        &output_data);
-    if (result == KM_ERROR_VERIFICATION_FAILED) {
+    if (result == ErrorCode::VERIFICATION_FAILED) {
         printf("Verify: Failed to verify signature.\n");
         return result;
     }
-    if (result != KM_ERROR_OK) {
-        printf("Verify: FinishOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Verify: FinishOperation failed: %d\n", int32_t(result));
         return result;
     }
     printf("Verify: OK\n");
diff --git a/keystore/keystore_client_impl.cpp b/keystore/keystore_client_impl.cpp
index c3d8f35..f9df134 100644
--- a/keystore/keystore_client_impl.cpp
+++ b/keystore/keystore_client_impl.cpp
@@ -19,24 +19,25 @@
 #include <string>
 #include <vector>
 
-#include "binder/IBinder.h"
-#include "binder/IInterface.h"
-#include "binder/IServiceManager.h"
-#include "keystore/IKeystoreService.h"
-#include "keystore/keystore.h"
-#include "log/log.h"
-#include "utils/String16.h"
-#include "utils/String8.h"
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <binder/IServiceManager.h>
+#include <keystore/IKeystoreService.h>
+#include <keystore/keystore.h>
+#include <log/log.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
 
 #include "keystore_client.pb.h"
+#include <keystore/authorization_set.h>
+#include <keystore/keystore_hidl_support.h>
 
 using android::ExportResult;
-using android::KeyCharacteristics;
-using android::KeymasterArguments;
+using keystore::KeyCharacteristics;
 using android::OperationResult;
 using android::String16;
-using keymaster::AuthorizationSet;
-using keymaster::AuthorizationSetBuilder;
+using keystore::AuthorizationSet;
+using keystore::AuthorizationSetBuilder;
 
 namespace {
 
@@ -44,24 +45,9 @@
 const int kDefaultUID = -1;
 const char kEncryptSuffix[] = "_ENC";
 const char kAuthenticateSuffix[] = "_AUTH";
-const uint32_t kAESKeySize = 256;      // bits
-const uint32_t kHMACKeySize = 256;     // bits
-const uint32_t kHMACOutputSize = 256;  // bits
-
-const uint8_t* StringAsByteArray(const std::string& s) {
-    return reinterpret_cast<const uint8_t*>(s.data());
-}
-
-std::string ByteArrayAsString(const uint8_t* data, size_t data_size) {
-    return std::string(reinterpret_cast<const char*>(data), data_size);
-}
-
-void CopyParameters(const AuthorizationSet& in, std::vector<keymaster_key_param_t>* out) {
-  keymaster_key_param_set_t tmp;
-  in.CopyToParamSet(&tmp);
-  out->assign(&tmp.params[0], &tmp.params[tmp.length]);
-  free(tmp.params);
-}
+constexpr uint32_t kAESKeySize = 256;      // bits
+constexpr uint32_t kHMACKeySize = 256;     // bits
+constexpr uint32_t kHMACOutputSize = 256;  // bits
 
 }  // namespace
 
@@ -89,29 +75,28 @@
         return false;
     }
     AuthorizationSetBuilder encrypt_params;
-    encrypt_params.Padding(KM_PAD_PKCS7);
-    encrypt_params.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CBC);
+    encrypt_params.Padding(PaddingMode::PKCS7);
+    encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
     AuthorizationSet output_params;
     std::string raw_encrypted_data;
-    if (!oneShotOperation(KM_PURPOSE_ENCRYPT, encryption_key_name, encrypt_params.build(), data,
+    if (!oneShotOperation(KeyPurpose::ENCRYPT, encryption_key_name, encrypt_params, data,
                           std::string(), /* signature_to_verify */
                           &output_params, &raw_encrypted_data)) {
         ALOGE("Encrypt: AES operation failed.");
         return false;
     }
-    keymaster_blob_t init_vector_blob;
-    if (!output_params.GetTagValue(keymaster::TAG_NONCE, &init_vector_blob)) {
+    auto init_vector_blob = output_params.GetTagValue(TAG_NONCE);
+    if (!init_vector_blob.isOk()){
         ALOGE("Encrypt: Missing initialization vector.");
         return false;
     }
-    std::string init_vector =
-        ByteArrayAsString(init_vector_blob.data, init_vector_blob.data_length);
+    std::string init_vector = hidlVec2String(init_vector_blob.value());
 
     AuthorizationSetBuilder authenticate_params;
-    authenticate_params.Digest(KM_DIGEST_SHA_2_256);
-    authenticate_params.Authorization(keymaster::TAG_MAC_LENGTH, kHMACOutputSize);
+    authenticate_params.Digest(Digest::SHA_2_256);
+    authenticate_params.Authorization(TAG_MAC_LENGTH, kHMACOutputSize);
     std::string raw_authentication_data;
-    if (!oneShotOperation(KM_PURPOSE_SIGN, authentication_key_name, authenticate_params.build(),
+    if (!oneShotOperation(KeyPurpose::SIGN, authentication_key_name, authenticate_params,
                           init_vector + raw_encrypted_data, std::string(), /* signature_to_verify */
                           &output_params, &raw_authentication_data)) {
         ALOGE("Encrypt: HMAC operation failed.");
@@ -138,10 +123,10 @@
     // Verify authentication before attempting decryption.
     std::string authentication_key_name = key_name + kAuthenticateSuffix;
     AuthorizationSetBuilder authenticate_params;
-    authenticate_params.Digest(KM_DIGEST_SHA_2_256);
+    authenticate_params.Digest(Digest::SHA_2_256);
     AuthorizationSet output_params;
     std::string output_data;
-    if (!oneShotOperation(KM_PURPOSE_VERIFY, authentication_key_name, authenticate_params.build(),
+    if (!oneShotOperation(KeyPurpose::VERIFY, authentication_key_name, authenticate_params,
                           protobuf.init_vector() + protobuf.encrypted_data(),
                           protobuf.authentication_data(), &output_params, &output_data)) {
         ALOGE("Decrypt: HMAC operation failed.");
@@ -149,11 +134,11 @@
     }
     std::string encryption_key_name = key_name + kEncryptSuffix;
     AuthorizationSetBuilder encrypt_params;
-    encrypt_params.Padding(KM_PAD_PKCS7);
-    encrypt_params.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CBC);
-    encrypt_params.Authorization(keymaster::TAG_NONCE, protobuf.init_vector().data(),
+    encrypt_params.Padding(PaddingMode::PKCS7);
+    encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
+    encrypt_params.Authorization(TAG_NONCE, protobuf.init_vector().data(),
                                  protobuf.init_vector().size());
-    if (!oneShotOperation(KM_PURPOSE_DECRYPT, encryption_key_name, encrypt_params.build(),
+    if (!oneShotOperation(KeyPurpose::DECRYPT, encryption_key_name, encrypt_params,
                           protobuf.encrypted_data(), std::string(), /* signature_to_verify */
                           &output_params, data)) {
         ALOGE("Decrypt: AES operation failed.");
@@ -162,17 +147,17 @@
     return true;
 }
 
-bool KeystoreClientImpl::oneShotOperation(keymaster_purpose_t purpose, const std::string& key_name,
-                                          const keymaster::AuthorizationSet& input_parameters,
+bool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string& key_name,
+                                          const AuthorizationSet& input_parameters,
                                           const std::string& input_data,
                                           const std::string& signature_to_verify,
-                                          keymaster::AuthorizationSet* output_parameters,
+                                          AuthorizationSet* output_parameters,
                                           std::string* output_data) {
-    keymaster_operation_handle_t handle;
-    int32_t result =
+    uint64_t handle;
+    auto result =
         beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
-    if (result != KM_ERROR_OK) {
-        ALOGE("BeginOperation failed: %d", result);
+    if (!result.isOk()) {
+        ALOGE("BeginOperation failed: %d", int32_t(result));
         return false;
     }
     AuthorizationSet empty_params;
@@ -180,174 +165,172 @@
     AuthorizationSet ignored_params;
     result = updateOperation(handle, empty_params, input_data, &num_input_bytes_consumed,
                              &ignored_params, output_data);
-    if (result != KM_ERROR_OK) {
-        ALOGE("UpdateOperation failed: %d", result);
+    if (!result.isOk()) {
+        ALOGE("UpdateOperation failed: %d", int32_t(result));
         return false;
     }
     result =
         finishOperation(handle, empty_params, signature_to_verify, &ignored_params, output_data);
-    if (result != KM_ERROR_OK) {
-        ALOGE("FinishOperation failed: %d", result);
+    if (!result.isOk()) {
+        ALOGE("FinishOperation failed: %d", int32_t(result));
         return false;
     }
     return true;
 }
 
-int32_t KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy) {
-    return mapKeystoreError(keystore_->addRngEntropy(StringAsByteArray(entropy), entropy.size()));
+KeyStoreNativeReturnCode KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy) {
+    return keystore_->addRngEntropy(blob2hidlVec(entropy));
 }
 
-int32_t KeystoreClientImpl::generateKey(const std::string& key_name,
+KeyStoreNativeReturnCode KeystoreClientImpl::generateKey(const std::string& key_name,
                                         const AuthorizationSet& key_parameters,
                                         AuthorizationSet* hardware_enforced_characteristics,
                                         AuthorizationSet* software_enforced_characteristics) {
     String16 key_name16(key_name.data(), key_name.size());
-    KeymasterArguments key_arguments;
-    CopyParameters(key_parameters, &key_arguments.params);
     KeyCharacteristics characteristics;
-    int32_t result =
-        keystore_->generateKey(key_name16, key_arguments, NULL /*entropy*/, 0 /*entropyLength*/,
+    auto result =
+        keystore_->generateKey(key_name16, key_parameters.hidl_data(), hidl_vec<uint8_t>(),
                                kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics);
-    hardware_enforced_characteristics->Reinitialize(characteristics.characteristics.hw_enforced);
-    software_enforced_characteristics->Reinitialize(characteristics.characteristics.sw_enforced);
-    return mapKeystoreError(result);
+
+    /* 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;
+    *software_enforced_characteristics = characteristics.softwareEnforced;
+    return result;
 }
 
-int32_t
+KeyStoreNativeReturnCode
 KeystoreClientImpl::getKeyCharacteristics(const std::string& key_name,
                                           AuthorizationSet* hardware_enforced_characteristics,
                                           AuthorizationSet* software_enforced_characteristics) {
     String16 key_name16(key_name.data(), key_name.size());
-    keymaster_blob_t client_id_blob = {nullptr, 0};
-    keymaster_blob_t app_data_blob = {nullptr, 0};
     KeyCharacteristics characteristics;
-    int32_t result = keystore_->getKeyCharacteristics(key_name16, &client_id_blob, &app_data_blob,
+    auto result = keystore_->getKeyCharacteristics(key_name16, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(),
                                                       kDefaultUID, &characteristics);
-    hardware_enforced_characteristics->Reinitialize(characteristics.characteristics.hw_enforced);
-    software_enforced_characteristics->Reinitialize(characteristics.characteristics.sw_enforced);
-    return mapKeystoreError(result);
+
+    /* 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;
+    *software_enforced_characteristics = characteristics.softwareEnforced;
+    return result;
 }
 
-int32_t KeystoreClientImpl::importKey(const std::string& key_name,
+KeyStoreNativeReturnCode KeystoreClientImpl::importKey(const std::string& key_name,
                                       const AuthorizationSet& key_parameters,
-                                      keymaster_key_format_t key_format,
+                                      KeyFormat key_format,
                                       const std::string& key_data,
                                       AuthorizationSet* hardware_enforced_characteristics,
                                       AuthorizationSet* software_enforced_characteristics) {
     String16 key_name16(key_name.data(), key_name.size());
-    KeymasterArguments key_arguments;
-    CopyParameters(key_parameters, &key_arguments.params);
+    auto hidlKeyData = blob2hidlVec(key_data);
     KeyCharacteristics characteristics;
-    int32_t result =
-        keystore_->importKey(key_name16, key_arguments, key_format, StringAsByteArray(key_data),
-                             key_data.size(), kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics);
-    hardware_enforced_characteristics->Reinitialize(characteristics.characteristics.hw_enforced);
-    software_enforced_characteristics->Reinitialize(characteristics.characteristics.sw_enforced);
-    return mapKeystoreError(result);
+    auto result = keystore_->importKey(key_name16, key_parameters.hidl_data(), key_format,
+            hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics);
+
+    /* 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;
+    *software_enforced_characteristics = characteristics.softwareEnforced;
+    return result;
 }
 
-int32_t KeystoreClientImpl::exportKey(keymaster_key_format_t export_format,
+KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
                                       const std::string& key_name, std::string* export_data) {
     String16 key_name16(key_name.data(), key_name.size());
-    keymaster_blob_t client_id_blob = {nullptr, 0};
-    keymaster_blob_t app_data_blob = {nullptr, 0};
     ExportResult export_result;
-    keystore_->exportKey(key_name16, export_format, &client_id_blob, &app_data_blob,
+    keystore_->exportKey(key_name16, export_format, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(),
                          kDefaultUID, &export_result);
-    *export_data = ByteArrayAsString(export_result.exportData.get(), export_result.dataLength);
-    return mapKeystoreError(export_result.resultCode);
+    *export_data = hidlVec2String(export_result.exportData);
+    return export_result.resultCode;
 }
 
-int32_t KeystoreClientImpl::deleteKey(const std::string& key_name) {
+KeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) {
     String16 key_name16(key_name.data(), key_name.size());
-    return mapKeystoreError(keystore_->del(key_name16, kDefaultUID));
+    return keystore_->del(key_name16, kDefaultUID);
 }
 
-int32_t KeystoreClientImpl::deleteAllKeys() {
-    return mapKeystoreError(keystore_->clear_uid(kDefaultUID));
+KeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() {
+    return keystore_->clear_uid(kDefaultUID);
 }
 
-int32_t KeystoreClientImpl::beginOperation(keymaster_purpose_t purpose, const std::string& key_name,
+KeyStoreNativeReturnCode KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
                                            const AuthorizationSet& input_parameters,
                                            AuthorizationSet* output_parameters,
-                                           keymaster_operation_handle_t* handle) {
+                                           uint64_t* handle) {
     android::sp<android::IBinder> token(new android::BBinder);
     String16 key_name16(key_name.data(), key_name.size());
-    KeymasterArguments input_arguments;
-    CopyParameters(input_parameters, &input_arguments.params);
     OperationResult result;
-    keystore_->begin(token, key_name16, purpose, true /*pruneable*/, input_arguments,
-                     NULL /*entropy*/, 0 /*entropyLength*/, kDefaultUID, &result);
-    int32_t error_code = mapKeystoreError(result.resultCode);
-    if (error_code == KM_ERROR_OK) {
+    keystore_->begin(token, key_name16, purpose, true /*pruneable*/, input_parameters.hidl_data(),
+                     hidl_vec<uint8_t>(), kDefaultUID, &result);
+    if (result.resultCode.isOk()) {
         *handle = getNextVirtualHandle();
         active_operations_[*handle] = result.token;
-        if (!result.outParams.params.empty()) {
-            output_parameters->Reinitialize(&*result.outParams.params.begin(),
-                                            result.outParams.params.size());
+        if (result.outParams.size()) {
+            *output_parameters = result.outParams;
         }
     }
-    return error_code;
+    return result.resultCode;
 }
 
-int32_t KeystoreClientImpl::updateOperation(keymaster_operation_handle_t handle,
+KeyStoreNativeReturnCode KeystoreClientImpl::updateOperation(uint64_t handle,
                                             const AuthorizationSet& input_parameters,
                                             const std::string& input_data,
                                             size_t* num_input_bytes_consumed,
                                             AuthorizationSet* output_parameters,
                                             std::string* output_data) {
     if (active_operations_.count(handle) == 0) {
-        return KM_ERROR_INVALID_OPERATION_HANDLE;
+        return ErrorCode::INVALID_OPERATION_HANDLE;
     }
-    KeymasterArguments input_arguments;
-    CopyParameters(input_parameters, &input_arguments.params);
     OperationResult result;
-    keystore_->update(active_operations_[handle], input_arguments, StringAsByteArray(input_data),
-                      input_data.size(), &result);
-    int32_t error_code = mapKeystoreError(result.resultCode);
-    if (error_code == KM_ERROR_OK) {
+    auto hidlInputData = blob2hidlVec(input_data);
+    keystore_->update(active_operations_[handle], input_parameters.hidl_data(), hidlInputData,
+            &result);
+
+    if (result.resultCode.isOk()) {
         *num_input_bytes_consumed = result.inputConsumed;
-        if (!result.outParams.params.empty()) {
-            output_parameters->Reinitialize(&*result.outParams.params.begin(),
-                                            result.outParams.params.size());
+        if (result.outParams.size()) {
+            *output_parameters = result.outParams;
         }
-        output_data->append(ByteArrayAsString(result.data.get(), result.dataLength));
+        // TODO verify that append should not be assign
+        output_data->append(hidlVec2String(result.data));
     }
-    return error_code;
+    return result.resultCode;
 }
 
-int32_t KeystoreClientImpl::finishOperation(keymaster_operation_handle_t handle,
+KeyStoreNativeReturnCode KeystoreClientImpl::finishOperation(uint64_t handle,
                                             const AuthorizationSet& input_parameters,
                                             const std::string& signature_to_verify,
                                             AuthorizationSet* output_parameters,
                                             std::string* output_data) {
     if (active_operations_.count(handle) == 0) {
-        return KM_ERROR_INVALID_OPERATION_HANDLE;
+        return ErrorCode::INVALID_OPERATION_HANDLE;
     }
-    KeymasterArguments input_arguments;
-    CopyParameters(input_parameters, &input_arguments.params);
     OperationResult result;
-    keystore_->finish(active_operations_[handle], input_arguments,
-                      StringAsByteArray(signature_to_verify), signature_to_verify.size(),
-                      NULL /*entropy*/, 0 /*entropyLength*/, &result);
-    int32_t error_code = mapKeystoreError(result.resultCode);
-    if (error_code == KM_ERROR_OK) {
-        if (!result.outParams.params.empty()) {
-            output_parameters->Reinitialize(&*result.outParams.params.begin(),
-                                            result.outParams.params.size());
+    auto hidlSignature = blob2hidlVec(signature_to_verify);
+    keystore_->finish(active_operations_[handle], input_parameters.hidl_data(),
+                      hidlSignature,
+                      hidl_vec<uint8_t>(), &result);
+
+    if (result.resultCode.isOk()) {
+        if (result.outParams.size()) {
+            *output_parameters = result.outParams;
         }
-        output_data->append(ByteArrayAsString(result.data.get(), result.dataLength));
+        // TODO verify that append should not be assign
+        output_data->append(hidlVec2String(result.data));
         active_operations_.erase(handle);
     }
-    return error_code;
+    return result.resultCode;
 }
 
-int32_t KeystoreClientImpl::abortOperation(keymaster_operation_handle_t handle) {
+KeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) {
     if (active_operations_.count(handle) == 0) {
-        return KM_ERROR_INVALID_OPERATION_HANDLE;
+        return ErrorCode::INVALID_OPERATION_HANDLE;
     }
-    int32_t error_code = mapKeystoreError(keystore_->abort(active_operations_[handle]));
-    if (error_code == KM_ERROR_OK) {
+    auto error_code = keystore_->abort(active_operations_[handle]);
+    if (error_code.isOk()) {
         active_operations_.erase(handle);
     }
     return error_code;
@@ -355,16 +338,16 @@
 
 bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
     String16 key_name16(key_name.data(), key_name.size());
-    int32_t error_code = mapKeystoreError(keystore_->exist(key_name16, kDefaultUID));
-    return (error_code == KM_ERROR_OK);
+    auto error_code = keystore_->exist(key_name16, kDefaultUID);
+    return error_code.isOk();
 }
 
 bool KeystoreClientImpl::listKeys(const std::string& prefix,
                                   std::vector<std::string>* key_name_list) {
     String16 prefix16(prefix.data(), prefix.size());
     android::Vector<String16> matches;
-    int32_t error_code = mapKeystoreError(keystore_->list(prefix16, kDefaultUID, &matches));
-    if (error_code == KM_ERROR_OK) {
+    auto error_code = keystore_->list(prefix16, kDefaultUID, &matches);
+    if (error_code.isOk()) {
         for (const auto& match : matches) {
             android::String8 key_name(match);
             key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size()));
@@ -374,18 +357,10 @@
     return false;
 }
 
-keymaster_operation_handle_t KeystoreClientImpl::getNextVirtualHandle() {
+uint64_t KeystoreClientImpl::getNextVirtualHandle() {
     return next_virtual_handle_++;
 }
 
-int32_t KeystoreClientImpl::mapKeystoreError(int32_t keystore_error) {
-    // See notes in keystore_client.h for rationale.
-    if (keystore_error == ::NO_ERROR) {
-        return KM_ERROR_OK;
-    }
-    return keystore_error;
-}
-
 bool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name) {
     bool key_exists = doesKeyExist(key_name);
     if (key_exists) {
@@ -394,9 +369,9 @@
             return false;
         }
         if (!verified) {
-            int32_t result = deleteKey(key_name);
-            if (result != KM_ERROR_OK) {
-                ALOGE("Failed to delete invalid encryption key: %d", result);
+            auto result = deleteKey(key_name);
+            if (!result.isOk()) {
+                ALOGE("Failed to delete invalid encryption key: %d", int32_t(result));
                 return false;
             }
             key_exists = false;
@@ -405,16 +380,16 @@
     if (!key_exists) {
         AuthorizationSetBuilder key_parameters;
         key_parameters.AesEncryptionKey(kAESKeySize)
-            .Padding(KM_PAD_PKCS7)
-            .Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CBC)
-            .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+            .Padding(PaddingMode::PKCS7)
+            .Authorization(TAG_BLOCK_MODE, BlockMode::CBC)
+            .Authorization(TAG_NO_AUTH_REQUIRED);
         AuthorizationSet hardware_enforced_characteristics;
         AuthorizationSet software_enforced_characteristics;
-        int32_t result =
-            generateKey(key_name, key_parameters.build(), &hardware_enforced_characteristics,
+        auto result =
+            generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
                         &software_enforced_characteristics);
-        if (result != KM_ERROR_OK) {
-            ALOGE("Failed to generate encryption key: %d", result);
+        if (!result.isOk()) {
+            ALOGE("Failed to generate encryption key: %d", int32_t(result));
             return false;
         }
         if (hardware_enforced_characteristics.size() == 0) {
@@ -432,9 +407,9 @@
             return false;
         }
         if (!verified) {
-            int32_t result = deleteKey(key_name);
-            if (result != KM_ERROR_OK) {
-                ALOGE("Failed to delete invalid authentication key: %d", result);
+            auto result = deleteKey(key_name);
+            if (!result.isOk()) {
+                ALOGE("Failed to delete invalid authentication key: %d", int32_t(result));
                 return false;
             }
             key_exists = false;
@@ -443,16 +418,16 @@
     if (!key_exists) {
         AuthorizationSetBuilder key_parameters;
         key_parameters.HmacKey(kHMACKeySize)
-            .Digest(KM_DIGEST_SHA_2_256)
-            .Authorization(keymaster::TAG_MIN_MAC_LENGTH, kHMACOutputSize)
-            .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+            .Digest(Digest::SHA_2_256)
+            .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize)
+            .Authorization(TAG_NO_AUTH_REQUIRED);
         AuthorizationSet hardware_enforced_characteristics;
         AuthorizationSet software_enforced_characteristics;
-        int32_t result =
-            generateKey(key_name, key_parameters.build(), &hardware_enforced_characteristics,
+        auto result =
+            generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
                         &software_enforced_characteristics);
-        if (result != KM_ERROR_OK) {
-            ALOGE("Failed to generate authentication key: %d", result);
+        if (!result.isOk()) {
+            ALOGE("Failed to generate authentication key: %d", int32_t(result));
             return false;
         }
         if (hardware_enforced_characteristics.size() == 0) {
@@ -466,38 +441,34 @@
                                                        bool* verified) {
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    int32_t result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
+    auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
                                            &software_enforced_characteristics);
-    if (result != KM_ERROR_OK) {
-        ALOGE("Failed to query encryption key: %d", result);
+    if (!result.isOk()) {
+        ALOGE("Failed to query encryption key: %d", int32_t(result));
         return false;
     }
     *verified = true;
-    keymaster_algorithm_t algorithm = KM_ALGORITHM_RSA;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm)) ||
-        algorithm != KM_ALGORITHM_AES) {
+    auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
+            software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
+    if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
         ALOGW("Found encryption key with invalid algorithm.");
         *verified = false;
     }
-    uint32_t key_size = 0;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_KEY_SIZE, &key_size) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_KEY_SIZE, &key_size)) ||
-        key_size != kAESKeySize) {
+    auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
+            software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
+    if (!key_size.isOk() || key_size.value() != kAESKeySize) {
         ALOGW("Found encryption key with invalid size.");
         *verified = false;
     }
-    keymaster_block_mode_t block_mode = KM_MODE_ECB;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_BLOCK_MODE, &block_mode) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_BLOCK_MODE, &block_mode)) ||
-        block_mode != KM_MODE_CBC) {
+    auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
+            software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
+    if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
         ALOGW("Found encryption key with invalid block mode.");
         *verified = false;
     }
-    keymaster_padding_t padding_mode = KM_PAD_NONE;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_PADDING, &padding_mode) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_PADDING, &padding_mode)) ||
-        padding_mode != KM_PAD_PKCS7) {
+    auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
+            software_enforced_characteristics.GetTagValue(TAG_PADDING));
+    if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
         ALOGW("Found encryption key with invalid padding mode.");
         *verified = false;
     }
@@ -511,39 +482,34 @@
                                                            bool* verified) {
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    int32_t result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
+    auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
                                            &software_enforced_characteristics);
-    if (result != KM_ERROR_OK) {
-        ALOGE("Failed to query authentication key: %d", result);
+    if (!result.isOk()) {
+        ALOGE("Failed to query authentication key: %d", int32_t(result));
         return false;
     }
     *verified = true;
-    keymaster_algorithm_t algorithm = KM_ALGORITHM_RSA;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm)) ||
-        algorithm != KM_ALGORITHM_HMAC) {
+    auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
+            software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
+    if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC){
         ALOGW("Found authentication key with invalid algorithm.");
         *verified = false;
     }
-    uint32_t key_size = 0;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_KEY_SIZE, &key_size) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_KEY_SIZE, &key_size)) ||
-        key_size != kHMACKeySize) {
+    auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
+            software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
+    if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
         ALOGW("Found authentication key with invalid size.");
         *verified = false;
     }
-    uint32_t mac_size = 0;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_MIN_MAC_LENGTH, &mac_size) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_MIN_MAC_LENGTH,
-                                                        &mac_size)) ||
-        mac_size != kHMACOutputSize) {
+    auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
+            software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
+    if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
         ALOGW("Found authentication key with invalid minimum mac size.");
         *verified = false;
     }
-    keymaster_digest_t digest = KM_DIGEST_NONE;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_DIGEST, &digest) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_DIGEST, &digest)) ||
-        digest != KM_DIGEST_SHA_2_256) {
+    auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
+            software_enforced_characteristics.GetTagValue(TAG_DIGEST));
+    if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
         ALOGW("Found authentication key with invalid digest list.");
         *verified = false;
     }
diff --git a/keystore/keystore_get.cpp b/keystore/keystore_get.cpp
index 2783816..8fb7f80 100644
--- a/keystore/keystore_get.cpp
+++ b/keystore/keystore_get.cpp
@@ -20,6 +20,7 @@
 #include <keystore/keystore_get.h>
 
 using namespace android;
+using namespace keystore;
 
 ssize_t keystore_get(const char *key, size_t keyLength, uint8_t** value) {
     sp<IServiceManager> sm = defaultServiceManager();
@@ -30,13 +31,15 @@
         return -1;
     }
 
-    size_t valueLength;
-    int32_t ret = service->get(String16(key, keyLength), -1, value, &valueLength);
-    if (ret < 0) {
-        return -1;
-    } else if (ret != ::NO_ERROR) {
-        return -1;
-    } else {
-        return valueLength;
+    hidl_vec<uint8_t> result;
+    auto ret = service->get(String16(key, keyLength), -1, &result);
+    if (!ret.isOk()) return -1;
+
+    if (value) {
+        *value = reinterpret_cast<uint8_t*>(malloc(result.size()));
+        if (!*value) return -1;
+        memcpy(*value, &result[0], result.size());
     }
+    return result.size();
+
 }
diff --git a/keystore/keystore_get_wifi_hidl.cpp b/keystore/keystore_get_wifi_hidl.cpp
new file mode 100644
index 0000000..79639b6
--- /dev/null
+++ b/keystore/keystore_get_wifi_hidl.cpp
@@ -0,0 +1,60 @@
+/* Copyright 2017 The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include <android/system/wifi/keystore/1.0/IKeystore.h>
+#include <log/log.h>
+
+#include <keystore/keystore_get.h>
+
+using namespace android;
+
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::sp;
+using android::system::wifi::keystore::V1_0::IKeystore;
+
+ssize_t keystore_get(const char *key, size_t keyLength, uint8_t** value) {
+    if (key == NULL || keyLength == 0 || value == NULL) {
+        ALOGE("Null pointer argument passed");
+        return -1;
+    }
+
+    sp<IKeystore> service = IKeystore::tryGetService();
+    if (service == NULL) {
+        ALOGE("could not contact keystore HAL");
+        return -1;
+    }
+
+    ssize_t return_size;
+    bool success = false;
+    auto cb = [&](IKeystore::KeystoreStatusCode status, hidl_vec<uint8_t> returnedValue) {
+        if (status == IKeystore::KeystoreStatusCode::SUCCESS) {
+            return_size = returnedValue.size();
+            *value = returnedValue.releaseData();
+            success = true;
+        }
+    };
+
+    Return<void> ret = service->getBlob(hidl_string(key, keyLength), cb);
+    return ret.isOk() && success ? return_size : -1;
+}
diff --git a/keystore/keystore_keymaster_enforcement.h b/keystore/keystore_keymaster_enforcement.h
index d20d7a6..0389201 100644
--- a/keystore/keystore_keymaster_enforcement.h
+++ b/keystore/keystore_keymaster_enforcement.h
@@ -14,18 +14,19 @@
  * limitations under the License.
  */
 
-#ifndef KEYSTORE_KEYMASTER_ENFORCEMENT_H_
-#define KEYSTORE_KEYMASTER_ENFORCEMENT_H_
+#ifndef KEYSTORE_KEYSTORE_KEYMASTER_ENFORCEMENT_H_
+#define KEYSTORE_KEYSTORE_KEYMASTER_ENFORCEMENT_H_
 
 #include <time.h>
 
-#include <keymaster/keymaster_enforcement.h>
+#include "keymaster_enforcement.h"
 
+namespace keystore {
 /**
  * This is a specialization of the KeymasterEnforcement class to be used by Keystore to enforce
  * keymaster requirements on all key operation.
  */
-class KeystoreKeymasterEnforcement : public keymaster::KeymasterEnforcement {
+class KeystoreKeymasterEnforcement : public KeymasterEnforcement {
   public:
     KeystoreKeymasterEnforcement() : KeymasterEnforcement(64, 64) {}
 
@@ -85,4 +86,6 @@
     }
 };
 
-#endif  // KEYSTORE_KEYMASTER_ENFORCEMENT_H_
+} // namespace keystore
+
+#endif  // KEYSTORE_KEYSTORE_KEYMASTER_ENFORCEMENT_H_
diff --git a/keystore/keystore_main.cpp b/keystore/keystore_main.cpp
index e84fb37..a739c5e 100644
--- a/keystore/keystore_main.cpp
+++ b/keystore/keystore_main.cpp
@@ -17,19 +17,22 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "keystore"
 
-#include <keymaster/keymaster_configuration.h>
-#include <keymaster/soft_keymaster_device.h>
-#include <keymaster/soft_keymaster_logger.h>
-
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
+#include <android/hardware/keymaster/3.0/IHwKeymasterDevice.h>
+#include <android/system/wifi/keystore/1.0/IKeystore.h>
+#include <wifikeystorehal/keystore.h>
+
 #include <cutils/log.h>
 
 #include "entropy.h"
 #include "key_store_service.h"
 #include "keystore.h"
 #include "permissions.h"
+#include "legacy_keymaster_device_wrapper.h"
+#include "include/keystore/keystore_hidl_support.h"
+#include "include/keystore/keystore_return_types.h"
 
 /* KeyStore is a secured storage for key-value pairs. In this implementation,
  * each file stores one key-value pair. Keys are encoded in file names, and
@@ -37,159 +40,16 @@
  * user-defined password. To keep things simple, buffers are always larger than
  * the maximum space we needed, so boundary checks on buffers are omitted. */
 
-using keymaster::AuthorizationSet;
-using keymaster::AuthorizationSetBuilder;
-using keymaster::SoftKeymasterDevice;
+using ::android::system::wifi::keystore::V1_0::IKeystore;
+using ::android::system::wifi::keystore::V1_0::implementation::Keystore;
+using ::android::hardware::configureRpcThreadpool;
 
-static int configure_keymaster_devices(keymaster2_device_t* main, keymaster2_device_t* fallback) {
-    keymaster_error_t error = keymaster::ConfigureDevice(main);
-    if (error != KM_ERROR_OK) {
-        return -1;
-    }
-
-    error = keymaster::ConfigureDevice(fallback);
-    if (error != KM_ERROR_OK) {
-        return -1;
-    }
-
-    return 0;
-}
-
-static int keymaster0_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) {
-    assert(mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0);
-    ALOGI("Found keymaster0 module %s, version %x", mod->name, mod->module_api_version);
-
-    UniquePtr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
-    keymaster0_device_t* km0_device = NULL;
-    keymaster_error_t error = KM_ERROR_OK;
-
-    int rc = keymaster0_open(mod, &km0_device);
-    if (rc) {
-        ALOGE("Error opening keystore keymaster0 device.");
-        goto err;
-    }
-
-    if (km0_device->flags & KEYMASTER_SOFTWARE_ONLY) {
-        ALOGI("Keymaster0 module is software-only.  Using SoftKeymasterDevice instead.");
-        km0_device->common.close(&km0_device->common);
-        km0_device = NULL;
-        // SoftKeymasterDevice will be deleted by keymaster_device_release()
-        *dev = soft_keymaster.release()->keymaster2_device();
-        return 0;
-    }
-
-    ALOGD("Wrapping keymaster0 module %s with SoftKeymasterDevice", mod->name);
-    error = soft_keymaster->SetHardwareDevice(km0_device);
-    km0_device = NULL;  // SoftKeymasterDevice has taken ownership.
-    if (error != KM_ERROR_OK) {
-        ALOGE("Got error %d from SetHardwareDevice", error);
-        rc = error;
-        goto err;
-    }
-
-    // SoftKeymasterDevice will be deleted by  keymaster_device_release()
-    *dev = soft_keymaster.release()->keymaster2_device();
-    return 0;
-
-err:
-    if (km0_device)
-        km0_device->common.close(&km0_device->common);
-    *dev = NULL;
-    return rc;
-}
-
-static int keymaster1_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) {
-    assert(mod->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0);
-    ALOGI("Found keymaster1 module %s, version %x", mod->name, mod->module_api_version);
-
-    UniquePtr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
-    keymaster1_device_t* km1_device = nullptr;
-    keymaster_error_t error = KM_ERROR_OK;
-
-    int rc = keymaster1_open(mod, &km1_device);
-    if (rc) {
-        ALOGE("Error %d opening keystore keymaster1 device", rc);
-        goto err;
-    }
-
-    ALOGD("Wrapping keymaster1 module %s with SofKeymasterDevice", mod->name);
-    error = soft_keymaster->SetHardwareDevice(km1_device);
-    km1_device = nullptr;  // SoftKeymasterDevice has taken ownership.
-    if (error != KM_ERROR_OK) {
-        ALOGE("Got error %d from SetHardwareDevice", error);
-        rc = error;
-        goto err;
-    }
-
-    // SoftKeymasterDevice will be deleted by keymaster_device_release()
-    *dev = soft_keymaster.release()->keymaster2_device();
-    return 0;
-
-err:
-    if (km1_device)
-        km1_device->common.close(&km1_device->common);
-    *dev = NULL;
-    return rc;
-}
-
-static int keymaster2_device_initialize(const hw_module_t* mod, keymaster2_device_t** dev) {
-    assert(mod->module_api_version >= KEYMASTER_MODULE_API_VERSION_2_0);
-    ALOGI("Found keymaster2 module %s, version %x", mod->name, mod->module_api_version);
-
-    UniquePtr<SoftKeymasterDevice> soft_keymaster(new SoftKeymasterDevice);
-    keymaster2_device_t* km2_device = nullptr;
-
-    int rc = keymaster2_open(mod, &km2_device);
-    if (rc) {
-        ALOGE("Error %d opening keystore keymaster2 device", rc);
-        goto err;
-    }
-
-    *dev = km2_device;
-    return 0;
-
-err:
-    if (km2_device)
-        km2_device->common.close(&km2_device->common);
-    *dev = nullptr;
-    return rc;
-}
-
-static int keymaster_device_initialize(keymaster2_device_t** dev) {
-    const hw_module_t* mod;
-
-    int rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
-    if (rc) {
-        ALOGI("Could not find any keystore module, using software-only implementation.");
-        // SoftKeymasterDevice will be deleted by keymaster_device_release()
-        *dev = (new SoftKeymasterDevice)->keymaster2_device();
-        return 0;
-    }
-
-    if (mod->module_api_version < KEYMASTER_MODULE_API_VERSION_1_0) {
-        return keymaster0_device_initialize(mod, dev);
-    } else if (mod->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
-        return keymaster1_device_initialize(mod, dev);
-    } else {
-        return keymaster2_device_initialize(mod, dev);
-    }
-}
-
-// softkeymaster_logger appears not to be used in keystore, but it installs itself as the
-// logger used by SoftKeymasterDevice.
-static keymaster::SoftKeymasterLogger softkeymaster_logger;
-
-static int fallback_keymaster_device_initialize(keymaster2_device_t** dev) {
-    *dev = (new SoftKeymasterDevice)->keymaster2_device();
-    // SoftKeymasterDevice will be deleted by keymaster_device_release()
-    return 0;
-}
-
-static void keymaster_device_release(keymaster2_device_t* dev) {
-    dev->common.close(&dev->common);
-}
+/**
+ * TODO implement keystore daemon using binderized keymaster HAL.
+ */
 
 int main(int argc, char* argv[]) {
+    using android::hardware::hidl_string;
     if (argc < 2) {
         ALOGE("A directory must be specified!");
         return 1;
@@ -204,43 +64,60 @@
         return 1;
     }
 
-    keymaster2_device_t* dev;
-    if (keymaster_device_initialize(&dev)) {
-        ALOGE("keystore keymaster could not be initialized; exiting");
-        return 1;
+    auto dev = android::hardware::keymaster::V3_0::IKeymasterDevice::getService();
+    if (dev.get() == nullptr) {
+        return -1;
     }
-
-    keymaster2_device_t* fallback;
-    if (fallback_keymaster_device_initialize(&fallback)) {
-        ALOGE("software keymaster could not be initialized; exiting");
-        return 1;
-    }
-
-    if (configure_keymaster_devices(dev, fallback)) {
-        ALOGE("Keymaster devices could not be configured; exiting");
-        return 1;
+    auto fallback = android::keystore::makeSoftwareKeymasterDevice();
+    if (dev.get() == nullptr) {
+        return -1;
     }
 
     if (configure_selinux() == -1) {
         return -1;
     }
 
-    KeyStore keyStore(&entropy, dev, fallback);
+    bool allowNewFallbackDevice = false;
+
+    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;
+    }
+
+    KeyStore keyStore(&entropy, dev, fallback, allowNewFallbackDevice);
     keyStore.initialize();
     android::sp<android::IServiceManager> sm = android::defaultServiceManager();
-    android::sp<android::KeyStoreService> service = new android::KeyStoreService(&keyStore);
+    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;
     }
 
+    /**
+     * Register the wifi keystore HAL service to run in passthrough mode.
+     * This will spawn off a new thread which will service the HIDL
+     * transactions.
+     */
+    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);
+    }
+
     /*
-     * We're the only thread in existence, so we're just going to process
-     * Binder transaction as a single-threaded program.
+     * This thread is just going to process Binder transactions.
      */
     android::IPCThreadState::self()->joinThreadPool();
-
-    keymaster_device_release(dev);
     return 1;
 }
diff --git a/keystore/keystore_tags_utils.cpp b/keystore/keystore_tags_utils.cpp
new file mode 100644
index 0000000..278348a
--- /dev/null
+++ b/keystore/keystore_tags_utils.cpp
@@ -0,0 +1,46 @@
+/*
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <keystore/keymaster_tags.h>
+
+namespace keystore {
+
+template<typename TagList>
+struct TagStringifier;
+
+template<typename ... Tags>
+struct TagStringifier<MetaList<Tags...>> {
+    template<TagType tag_type, Tag tag>
+    static TypedTag<tag_type, tag> chooseString(TypedTag<tag_type, tag> ttag, Tag runtime_tag,
+            const char** result) {
+        if (tag == runtime_tag) {
+            *result = Tag2String<tag>::value();
+        }
+        return ttag;
+    }
+    static const char* stringify(Tag tag) {
+        const char* result = "unknown tag";
+        [] (Tags&&...) {}(chooseString(Tags(), tag, &result)...);
+        return result;
+    }
+};
+
+const char* stringifyTag(Tag tag) {
+    return TagStringifier<all_tags_t>::stringify(tag);
+}
+
+}
diff --git a/keystore/keystore_utils.cpp b/keystore/keystore_utils.cpp
index 4617afd..0d3f0ec 100644
--- a/keystore/keystore_utils.cpp
+++ b/keystore/keystore_utils.cpp
@@ -26,6 +26,9 @@
 #include <private/android_filesystem_config.h>
 
 #include <keymaster/android_keymaster_utils.h>
+#include <keystore/authorization_set.h>
+#include <keystore/keystore_client.h>
+#include <keystore/IKeystoreService.h>
 
 size_t readFully(int fd, uint8_t* data, size_t size) {
     size_t remaining = size;
@@ -58,30 +61,31 @@
     return size;
 }
 
-void add_legacy_key_authorizations(int keyType, std::vector<keymaster_key_param_t>* params) {
-    params->push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_SIGN));
-    params->push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_VERIFY));
-    params->push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
-    params->push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_DECRYPT));
-    params->push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE));
+void add_legacy_key_authorizations(int keyType, keystore::AuthorizationSet* params) {
+    using namespace keystore;
+    params->push_back(TAG_PURPOSE, KeyPurpose::SIGN);
+    params->push_back(TAG_PURPOSE, KeyPurpose::VERIFY);
+    params->push_back(TAG_PURPOSE, KeyPurpose::ENCRYPT);
+    params->push_back(TAG_PURPOSE, KeyPurpose::DECRYPT);
+    params->push_back(TAG_PADDING, PaddingMode::NONE);
     if (keyType == EVP_PKEY_RSA) {
-        params->push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN));
-        params->push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
-        params->push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_PSS));
-        params->push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_OAEP));
+        params->push_back(TAG_PADDING, PaddingMode::RSA_PKCS1_1_5_SIGN);
+        params->push_back(TAG_PADDING, PaddingMode::RSA_PKCS1_1_5_ENCRYPT);
+        params->push_back(TAG_PADDING, PaddingMode::RSA_PSS);
+        params->push_back(TAG_PADDING, PaddingMode::RSA_OAEP);
     }
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_MD5));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA1));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_224));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_256));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_384));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_512));
-    params->push_back(keymaster_param_bool(KM_TAG_ALL_USERS));
-    params->push_back(keymaster_param_bool(KM_TAG_NO_AUTH_REQUIRED));
-    params->push_back(keymaster_param_date(KM_TAG_ORIGINATION_EXPIRE_DATETIME, LLONG_MAX));
-    params->push_back(keymaster_param_date(KM_TAG_USAGE_EXPIRE_DATETIME, LLONG_MAX));
-    params->push_back(keymaster_param_date(KM_TAG_ACTIVE_DATETIME, 0));
+    params->push_back(TAG_DIGEST, Digest::NONE);
+    params->push_back(TAG_DIGEST, Digest::MD5);
+    params->push_back(TAG_DIGEST, Digest::SHA1);
+    params->push_back(TAG_DIGEST, Digest::SHA_2_224);
+    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);
+    params->push_back(TAG_ACTIVE_DATETIME, 0);
 }
 
 uid_t get_app_id(uid_t uid) {
diff --git a/keystore/keystore_utils.h b/keystore/keystore_utils.h
index eaa5eb3..0f7922a 100644
--- a/keystore/keystore_utils.h
+++ b/keystore/keystore_utils.h
@@ -28,10 +28,14 @@
 
 #include <UniquePtr.h>
 
+#include <keystore/authorization_set.h>
+
+#include "blob.h"
+
 size_t readFully(int fd, uint8_t* data, size_t size);
 size_t writeFully(int fd, uint8_t* data, size_t size);
 
-void add_legacy_key_authorizations(int keyType, std::vector<keymaster_key_param_t>* params);
+void add_legacy_key_authorizations(int keyType, keystore::AuthorizationSet* params);
 
 /**
  * Returns the app ID (in the Android multi-user sense) for the current
@@ -55,4 +59,14 @@
 };
 typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
 
+namespace keystore {
+
+inline static hidl_vec<uint8_t> blob2hidlVec(const Blob& blob) {
+    hidl_vec<uint8_t> result;
+    result.setToExternal(const_cast<uint8_t*>(blob.getValue()), blob.getLength());
+    return result;
+}
+
+} // namespace keystore
+
 #endif  // KEYSTORE_KEYSTORE_UTILS_H_
diff --git a/keystore/legacy_keymaster_device_wrapper.cpp b/keystore/legacy_keymaster_device_wrapper.cpp
new file mode 100644
index 0000000..187252e
--- /dev/null
+++ b/keystore/legacy_keymaster_device_wrapper.cpp
@@ -0,0 +1,543 @@
+/*
+ **
+ ** Copyright 2016, 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.
+ */
+
+#define LOG_TAG "android.hardware.keymaster@3.0-impl"
+
+#include "legacy_keymaster_device_wrapper.h"
+
+#include <cutils/log.h>
+
+#include <hardware/keymaster2.h>
+#include <hardware/keymaster_defs.h>
+#include <keymaster/keymaster_configuration.h>
+#include <keymaster/soft_keymaster_device.h>
+
+namespace android {
+namespace keystore {
+
+using ::keymaster::SoftKeymasterDevice;
+
+LegacyKeymasterDeviceWrapper::LegacyKeymasterDeviceWrapper(keymaster2_device_t* dev)
+    : keymaster_device_(dev) {}
+
+LegacyKeymasterDeviceWrapper::~LegacyKeymasterDeviceWrapper() {
+    if (keymaster_device_) keymaster_device_->common.close(&keymaster_device_->common);
+}
+
+static inline keymaster_tag_type_t typeFromTag(const keymaster_tag_t tag) {
+    return keymaster_tag_get_type(tag);
+}
+
+/**
+ * legacy_enum_conversion converts enums from hidl to keymaster and back. Currently, this is just a
+ * cast to make the compiler happy. One of two thigs should happen though:
+ * TODO The keymaster enums should become aliases for the hidl generated enums so that we have a
+ *      single point of truth. Then this cast function can go away.
+ */
+inline static keymaster_tag_t legacy_enum_conversion(const Tag value) {
+    return keymaster_tag_t(value);
+}
+inline static Tag legacy_enum_conversion(const keymaster_tag_t value) {
+    return Tag(value);
+}
+inline static keymaster_purpose_t legacy_enum_conversion(const KeyPurpose value) {
+    return keymaster_purpose_t(value);
+}
+inline static keymaster_key_format_t legacy_enum_conversion(const KeyFormat value) {
+    return keymaster_key_format_t(value);
+}
+inline static ErrorCode legacy_enum_conversion(const keymaster_error_t value) {
+    return ErrorCode(value);
+}
+
+class KmParamSet : public keymaster_key_param_set_t {
+  public:
+    KmParamSet(const hidl_vec<KeyParameter>& keyParams) {
+        params = new keymaster_key_param_t[keyParams.size()];
+        length = keyParams.size();
+        for (size_t i = 0; i < keyParams.size(); ++i) {
+            auto tag = legacy_enum_conversion(keyParams[i].tag);
+            switch (typeFromTag(tag)) {
+            case KM_ENUM:
+            case KM_ENUM_REP:
+                params[i] = keymaster_param_enum(tag, keyParams[i].f.integer);
+                break;
+            case KM_UINT:
+            case KM_UINT_REP:
+                params[i] = keymaster_param_int(tag, keyParams[i].f.integer);
+                break;
+            case KM_ULONG:
+            case KM_ULONG_REP:
+                params[i] = keymaster_param_long(tag, keyParams[i].f.longInteger);
+                break;
+            case KM_DATE:
+                params[i] = keymaster_param_date(tag, keyParams[i].f.dateTime);
+                break;
+            case KM_BOOL:
+                if (keyParams[i].f.boolValue)
+                    params[i] = keymaster_param_bool(tag);
+                else
+                    params[i].tag = KM_TAG_INVALID;
+                break;
+            case KM_BIGNUM:
+            case KM_BYTES:
+                params[i] =
+                    keymaster_param_blob(tag, &keyParams[i].blob[0], keyParams[i].blob.size());
+                break;
+            case KM_INVALID:
+            default:
+                params[i].tag = KM_TAG_INVALID;
+                /* just skip */
+                break;
+            }
+        }
+    }
+    KmParamSet(KmParamSet&& other) : keymaster_key_param_set_t{other.params, other.length} {
+        other.length = 0;
+        other.params = nullptr;
+    }
+    KmParamSet(const KmParamSet&) = delete;
+    ~KmParamSet() { delete[] params; }
+};
+
+inline static KmParamSet hidlParams2KmParamSet(const hidl_vec<KeyParameter>& params) {
+    return KmParamSet(params);
+}
+
+inline static keymaster_blob_t hidlVec2KmBlob(const hidl_vec<uint8_t>& blob) {
+    /* hidl unmarshals funny pointers if the the blob is empty */
+    if (blob.size()) return {&blob[0], blob.size()};
+    return {};
+}
+
+inline static keymaster_key_blob_t hidlVec2KmKeyBlob(const hidl_vec<uint8_t>& blob) {
+    /* hidl unmarshals funny pointers if the the blob is empty */
+    if (blob.size()) return {&blob[0], blob.size()};
+    return {};
+}
+
+inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_key_blob_t& blob) {
+    hidl_vec<uint8_t> result;
+    result.setToExternal(const_cast<unsigned char*>(blob.key_material), blob.key_material_size);
+    return result;
+}
+inline static hidl_vec<uint8_t> kmBlob2hidlVec(const keymaster_blob_t& blob) {
+    hidl_vec<uint8_t> result;
+    result.setToExternal(const_cast<unsigned char*>(blob.data), blob.data_length);
+    return result;
+}
+
+inline static hidl_vec<hidl_vec<uint8_t>>
+kmCertChain2Hidl(const keymaster_cert_chain_t* cert_chain) {
+    hidl_vec<hidl_vec<uint8_t>> result;
+    if (!cert_chain || cert_chain->entry_count == 0 || !cert_chain->entries) return result;
+
+    result.resize(cert_chain->entry_count);
+    for (size_t i = 0; i < cert_chain->entry_count; ++i) {
+        auto& entry = cert_chain->entries[i];
+        result[i] = kmBlob2hidlVec(entry);
+    }
+
+    return result;
+}
+
+static inline hidl_vec<KeyParameter> kmParamSet2Hidl(const keymaster_key_param_set_t& set) {
+    hidl_vec<KeyParameter> result;
+    if (set.length == 0 || set.params == nullptr) return result;
+
+    result.resize(set.length);
+    keymaster_key_param_t* params = set.params;
+    for (size_t i = 0; i < set.length; ++i) {
+        auto tag = params[i].tag;
+        result[i].tag = legacy_enum_conversion(tag);
+        switch (typeFromTag(tag)) {
+        case KM_ENUM:
+        case KM_ENUM_REP:
+            result[i].f.integer = params[i].enumerated;
+            break;
+        case KM_UINT:
+        case KM_UINT_REP:
+            result[i].f.integer = params[i].integer;
+            break;
+        case KM_ULONG:
+        case KM_ULONG_REP:
+            result[i].f.longInteger = params[i].long_integer;
+            break;
+        case KM_DATE:
+            result[i].f.dateTime = params[i].date_time;
+            break;
+        case KM_BOOL:
+            result[i].f.boolValue = params[i].boolean;
+            break;
+        case KM_BIGNUM:
+        case KM_BYTES:
+            result[i].blob.setToExternal(const_cast<unsigned char*>(params[i].blob.data),
+                                         params[i].blob.data_length);
+            break;
+        case KM_INVALID:
+        default:
+            params[i].tag = KM_TAG_INVALID;
+            /* just skip */
+            break;
+        }
+    }
+    return result;
+}
+
+// Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
+Return<void> LegacyKeymasterDeviceWrapper::getHardwareFeatures(getHardwareFeatures_cb _hidl_cb) {
+    _hidl_cb(false, false, false, false, false, "Fallback Device", "Google Android Security");
+    return Void();
+}
+
+Return<ErrorCode> LegacyKeymasterDeviceWrapper::addRngEntropy(const hidl_vec<uint8_t>& data) {
+    return legacy_enum_conversion(
+        keymaster_device_->add_rng_entropy(keymaster_device_, &data[0], data.size()));
+}
+
+Return<void> LegacyKeymasterDeviceWrapper::generateKey(const hidl_vec<KeyParameter>& keyParams,
+                                                       generateKey_cb _hidl_cb) {
+    // result variables for the wire
+    KeyCharacteristics resultCharacteristics;
+    hidl_vec<uint8_t> resultKeyBlob;
+
+    // result variables the backend understands
+    keymaster_key_blob_t key_blob{nullptr, 0};
+    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
+
+    // convert the parameter set to something our backend understands
+    auto kmParams = hidlParams2KmParamSet(keyParams);
+
+    auto rc = keymaster_device_->generate_key(keymaster_device_, &kmParams, &key_blob,
+                                              &key_characteristics);
+
+    if (rc == KM_ERROR_OK) {
+        // on success convert the result to wire format
+        resultKeyBlob = kmBlob2hidlVec(key_blob);
+        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
+        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
+    }
+
+    // send results off to the client
+    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics);
+
+    // free buffers that we are responsible for
+    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
+    keymaster_free_characteristics(&key_characteristics);
+
+    return Void();
+}
+
+Return<void> LegacyKeymasterDeviceWrapper::getKeyCharacteristics(
+    const hidl_vec<uint8_t>& keyBlob, const hidl_vec<uint8_t>& clientId,
+    const hidl_vec<uint8_t>& appData, getKeyCharacteristics_cb _hidl_cb) {
+    // result variables for the wire
+    KeyCharacteristics resultCharacteristics;
+
+    // result variables the backend understands
+    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
+
+    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
+    auto kmClientId = hidlVec2KmBlob(clientId);
+    auto kmAppData = hidlVec2KmBlob(appData);
+
+    auto rc = keymaster_device_->get_key_characteristics(
+        keymaster_device_, keyBlob.size() ? &kmKeyBlob : nullptr,
+        clientId.size() ? &kmClientId : nullptr, appData.size() ? &kmAppData : nullptr,
+        &key_characteristics);
+
+    if (rc == KM_ERROR_OK) {
+        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
+        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultCharacteristics);
+
+    keymaster_free_characteristics(&key_characteristics);
+
+    return Void();
+}
+
+Return<void> LegacyKeymasterDeviceWrapper::importKey(const hidl_vec<KeyParameter>& params,
+                                                     KeyFormat keyFormat,
+                                                     const hidl_vec<uint8_t>& keyData,
+                                                     importKey_cb _hidl_cb) {
+    // result variables for the wire
+    KeyCharacteristics resultCharacteristics;
+    hidl_vec<uint8_t> resultKeyBlob;
+
+    // result variables the backend understands
+    keymaster_key_blob_t key_blob{nullptr, 0};
+    keymaster_key_characteristics_t key_characteristics{{nullptr, 0}, {nullptr, 0}};
+
+    auto kmParams = hidlParams2KmParamSet(params);
+    auto kmKeyData = hidlVec2KmBlob(keyData);
+
+    auto rc = keymaster_device_->import_key(keymaster_device_, &kmParams,
+                                            legacy_enum_conversion(keyFormat), &kmKeyData,
+                                            &key_blob, &key_characteristics);
+
+    if (rc == KM_ERROR_OK) {
+        // on success convert the result to wire format
+        resultKeyBlob = kmBlob2hidlVec(key_blob);
+        resultCharacteristics.softwareEnforced = kmParamSet2Hidl(key_characteristics.sw_enforced);
+        resultCharacteristics.teeEnforced = kmParamSet2Hidl(key_characteristics.hw_enforced);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob, resultCharacteristics);
+
+    // free buffers that we are responsible for
+    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
+    keymaster_free_characteristics(&key_characteristics);
+
+    return Void();
+}
+
+Return<void> LegacyKeymasterDeviceWrapper::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) {
+
+    // result variables for the wire
+    hidl_vec<uint8_t> resultKeyBlob;
+
+    // result variables the backend understands
+    keymaster_blob_t out_blob = {};
+
+    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
+    auto kmClientId = hidlVec2KmBlob(clientId);
+    auto kmAppData = hidlVec2KmBlob(appData);
+
+    auto rc = keymaster_device_->export_key(keymaster_device_, legacy_enum_conversion(exportFormat),
+                                            keyBlob.size() ? &kmKeyBlob : nullptr,
+                                            clientId.size() ? &kmClientId : nullptr,
+                                            appData.size() ? &kmAppData : nullptr, &out_blob);
+
+    if (rc == KM_ERROR_OK) {
+        // on success convert the result to wire format
+        // (Can we assume that key_blob is {nullptr, 0} or a valid buffer description?)
+        resultKeyBlob = kmBlob2hidlVec(out_blob);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob);
+
+    // free buffers that we are responsible for
+    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
+
+    return Void();
+}
+
+Return<void> LegacyKeymasterDeviceWrapper::attestKey(const hidl_vec<uint8_t>& keyToAttest,
+                                                     const hidl_vec<KeyParameter>& attestParams,
+                                                     attestKey_cb _hidl_cb) {
+
+    hidl_vec<hidl_vec<uint8_t>> resultCertChain;
+
+    for (size_t i = 0; i < attestParams.size(); ++i) {
+        switch (attestParams[i].tag) {
+            case Tag::ATTESTATION_ID_BRAND:
+            case Tag::ATTESTATION_ID_DEVICE:
+            case Tag::ATTESTATION_ID_PRODUCT:
+            case Tag::ATTESTATION_ID_SERIAL:
+            case Tag::ATTESTATION_ID_IMEI:
+            case Tag::ATTESTATION_ID_MEID:
+            case Tag::ATTESTATION_ID_MANUFACTURER:
+            case Tag::ATTESTATION_ID_MODEL:
+                // Device id attestation may only be supported if the device is able to permanently
+                // destroy its knowledge of the ids. This device is unable to do this, so it must
+                // never perform any device id attestation.
+                _hidl_cb(ErrorCode::CANNOT_ATTEST_IDS, resultCertChain);
+                return Void();
+            default:
+                break;
+        }
+    }
+
+    keymaster_cert_chain_t cert_chain = {};
+
+    auto kmKeyToAttest = hidlVec2KmKeyBlob(keyToAttest);
+    auto kmAttestParams = hidlParams2KmParamSet(attestParams);
+
+    auto rc = keymaster_device_->attest_key(keymaster_device_, &kmKeyToAttest, &kmAttestParams,
+                                            &cert_chain);
+
+    if (rc == KM_ERROR_OK) {
+        resultCertChain = kmCertChain2Hidl(&cert_chain);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultCertChain);
+
+    keymaster_free_cert_chain(&cert_chain);
+
+    return Void();
+}
+
+Return<void> LegacyKeymasterDeviceWrapper::upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+                                                      const hidl_vec<KeyParameter>& upgradeParams,
+                                                      upgradeKey_cb _hidl_cb) {
+
+    // result variables for the wire
+    hidl_vec<uint8_t> resultKeyBlob;
+
+    // result variables the backend understands
+    keymaster_key_blob_t key_blob = {};
+
+    auto kmKeyBlobToUpgrade = hidlVec2KmKeyBlob(keyBlobToUpgrade);
+    auto kmUpgradeParams = hidlParams2KmParamSet(upgradeParams);
+
+    auto rc = keymaster_device_->upgrade_key(keymaster_device_, &kmKeyBlobToUpgrade,
+                                             &kmUpgradeParams, &key_blob);
+
+    if (rc == KM_ERROR_OK) {
+        // on success convert the result to wire format
+        resultKeyBlob = kmBlob2hidlVec(key_blob);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultKeyBlob);
+
+    if (key_blob.key_material) free(const_cast<uint8_t*>(key_blob.key_material));
+
+    return Void();
+}
+
+Return<ErrorCode> LegacyKeymasterDeviceWrapper::deleteKey(const hidl_vec<uint8_t>& keyBlob) {
+    auto kmKeyBlob = hidlVec2KmKeyBlob(keyBlob);
+    return legacy_enum_conversion(keymaster_device_->delete_key(keymaster_device_, &kmKeyBlob));
+}
+
+Return<ErrorCode> LegacyKeymasterDeviceWrapper::deleteAllKeys() {
+    return legacy_enum_conversion(keymaster_device_->delete_all_keys(keymaster_device_));
+}
+
+Return<ErrorCode> LegacyKeymasterDeviceWrapper::destroyAttestationIds() {
+    return ErrorCode::UNIMPLEMENTED;
+}
+
+Return<void> LegacyKeymasterDeviceWrapper::begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+                                                 const hidl_vec<KeyParameter>& inParams,
+                                                 begin_cb _hidl_cb) {
+
+    // result variables for the wire
+    hidl_vec<KeyParameter> resultParams;
+    uint64_t resultOpHandle = 0;
+
+    // result variables the backend understands
+    keymaster_key_param_set_t out_params{nullptr, 0};
+    keymaster_operation_handle_t& operation_handle = resultOpHandle;
+
+    auto kmKey = hidlVec2KmKeyBlob(key);
+    auto kmInParams = hidlParams2KmParamSet(inParams);
+
+    auto rc = keymaster_device_->begin(keymaster_device_, legacy_enum_conversion(purpose), &kmKey,
+                                       &kmInParams, &out_params, &operation_handle);
+
+    if (rc == KM_ERROR_OK) resultParams = kmParamSet2Hidl(out_params);
+
+    _hidl_cb(legacy_enum_conversion(rc), resultParams, resultOpHandle);
+
+    keymaster_free_param_set(&out_params);
+
+    return Void();
+}
+
+Return<void> LegacyKeymasterDeviceWrapper::update(uint64_t operationHandle,
+                                                  const hidl_vec<KeyParameter>& inParams,
+                                                  const hidl_vec<uint8_t>& input,
+                                                  update_cb _hidl_cb) {
+    // result variables for the wire
+    uint32_t resultConsumed = 0;
+    hidl_vec<KeyParameter> resultParams;
+    hidl_vec<uint8_t> resultBlob;
+
+    // result variables the backend understands
+    size_t consumed = 0;
+    keymaster_key_param_set_t out_params = {};
+    keymaster_blob_t out_blob = {};
+
+    auto kmInParams = hidlParams2KmParamSet(inParams);
+    auto kmInput = hidlVec2KmBlob(input);
+
+    auto rc = keymaster_device_->update(keymaster_device_, operationHandle, &kmInParams, &kmInput,
+                                        &consumed, &out_params, &out_blob);
+
+    if (rc == KM_ERROR_OK) {
+        resultConsumed = consumed;
+        resultParams = kmParamSet2Hidl(out_params);
+        resultBlob = kmBlob2hidlVec(out_blob);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultConsumed, resultParams, resultBlob);
+
+    keymaster_free_param_set(&out_params);
+    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
+
+    return Void();
+}
+
+Return<void> LegacyKeymasterDeviceWrapper::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) {
+    // result variables for the wire
+    hidl_vec<KeyParameter> resultParams;
+    hidl_vec<uint8_t> resultBlob;
+
+    // result variables the backend understands
+    keymaster_key_param_set_t out_params = {};
+    keymaster_blob_t out_blob = {};
+
+    auto kmInParams = hidlParams2KmParamSet(inParams);
+    auto kmInput = hidlVec2KmBlob(input);
+    auto kmSignature = hidlVec2KmBlob(signature);
+
+    auto rc = keymaster_device_->finish(keymaster_device_, operationHandle, &kmInParams, &kmInput,
+                                        &kmSignature, &out_params, &out_blob);
+
+    if (rc == KM_ERROR_OK) {
+        resultParams = kmParamSet2Hidl(out_params);
+        resultBlob = kmBlob2hidlVec(out_blob);
+    }
+
+    _hidl_cb(legacy_enum_conversion(rc), resultParams, resultBlob);
+
+    keymaster_free_param_set(&out_params);
+    if (out_blob.data) free(const_cast<uint8_t*>(out_blob.data));
+
+    return Void();
+}
+
+Return<ErrorCode> LegacyKeymasterDeviceWrapper::abort(uint64_t operationHandle) {
+    return legacy_enum_conversion(keymaster_device_->abort(keymaster_device_, operationHandle));
+}
+
+sp<IKeymasterDevice> makeSoftwareKeymasterDevice() {
+    keymaster2_device_t* dev = nullptr;
+    dev = (new SoftKeymasterDevice)->keymaster2_device();
+
+    auto kmrc = ::keymaster::ConfigureDevice(dev);
+    if (kmrc != KM_ERROR_OK) {
+        dev->common.close(&dev->common);
+        return nullptr;
+    }
+
+    return new LegacyKeymasterDeviceWrapper(dev);
+}
+
+}  // namespace keystore
+}  // namespace android
diff --git a/keystore/legacy_keymaster_device_wrapper.h b/keystore/legacy_keymaster_device_wrapper.h
new file mode 100644
index 0000000..ad26221
--- /dev/null
+++ b/keystore/legacy_keymaster_device_wrapper.h
@@ -0,0 +1,90 @@
+/*
+ **
+ ** Copyright 2016, 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 LEGACY_KEYMASTER_DEVICE_WRAPPER_H_
+#define LEGACY_KEYMASTER_DEVICE_WRAPPER_H_
+
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
+#include <hidl/Status.h>
+#include <hidl/MQDescriptor.h>
+
+struct keymaster2_device;
+typedef struct keymaster2_device keymaster2_device_t;
+
+namespace android {
+namespace keystore {
+
+using ::android::hardware::keymaster::V3_0::ErrorCode;
+using ::android::hardware::keymaster::V3_0::IKeymasterDevice;
+using ::android::hardware::keymaster::V3_0::KeyCharacteristics;
+using ::android::hardware::keymaster::V3_0::KeyFormat;
+using ::android::hardware::keymaster::V3_0::KeyParameter;
+using ::android::hardware::keymaster::V3_0::KeyPurpose;
+using ::android::hardware::keymaster::V3_0::Tag;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+class LegacyKeymasterDeviceWrapper : public IKeymasterDevice {
+  public:
+    LegacyKeymasterDeviceWrapper(keymaster2_device_t* dev);
+    virtual ~LegacyKeymasterDeviceWrapper();
+
+    // Methods from ::android::hardware::keymaster::V3_0::IKeymasterDevice follow.
+    Return<void> getHardwareFeatures(getHardwareFeatures_cb _hidl_cb);
+    Return<ErrorCode> addRngEntropy(const hidl_vec<uint8_t>& data) override;
+    Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
+                             generateKey_cb _hidl_cb) override;
+    Return<void> getKeyCharacteristics(const hidl_vec<uint8_t>& keyBlob,
+                                       const hidl_vec<uint8_t>& clientId,
+                                       const hidl_vec<uint8_t>& appData,
+                                       getKeyCharacteristics_cb _hidl_cb) override;
+    Return<void> importKey(const hidl_vec<KeyParameter>& params, KeyFormat keyFormat,
+                           const hidl_vec<uint8_t>& keyData, importKey_cb _hidl_cb) override;
+    Return<void> exportKey(KeyFormat exportFormat, const hidl_vec<uint8_t>& keyBlob,
+                           const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
+                           exportKey_cb _hidl_cb) override;
+    Return<void> attestKey(const hidl_vec<uint8_t>& keyToAttest,
+                           const hidl_vec<KeyParameter>& attestParams,
+                           attestKey_cb _hidl_cb) override;
+    Return<void> upgradeKey(const hidl_vec<uint8_t>& keyBlobToUpgrade,
+                            const hidl_vec<KeyParameter>& upgradeParams,
+                            upgradeKey_cb _hidl_cb) override;
+    Return<ErrorCode> deleteKey(const hidl_vec<uint8_t>& keyBlob) override;
+    Return<ErrorCode> deleteAllKeys() override;
+    Return<ErrorCode> destroyAttestationIds() override;
+    Return<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+                       const hidl_vec<KeyParameter>& inParams, 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<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<ErrorCode> abort(uint64_t operationHandle) override;
+
+  private:
+    keymaster2_device_t* keymaster_device_;
+};
+
+sp<IKeymasterDevice> makeSoftwareKeymasterDevice();
+
+}  // namespace keystore
+}  // namespace android
+
+#endif  // LEGACY_KEYMASTER_DEVICE_WRAPPER_H_
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
index e8ae8b7..8c39716 100644
--- a/keystore/operation.cpp
+++ b/keystore/operation.cpp
@@ -19,17 +19,18 @@
 
 #include <algorithm>
 
-namespace android {
+namespace keystore {
+using namespace android;
+
 OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient)
     : mDeathRecipient(deathRecipient) {}
 
-sp<IBinder> OperationMap::addOperation(keymaster_operation_handle_t handle, uint64_t keyid,
-                                       keymaster_purpose_t purpose, const keymaster2_device_t* dev,
+sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
+                                       const OperationMap::km_device_t& dev,
                                        const sp<IBinder>& appToken,
-                                       keymaster_key_characteristics_t* characteristics,
-                                       bool pruneable) {
+                                       KeyCharacteristics&& characteristics, bool pruneable) {
     sp<IBinder> token = new BBinder();
-    mMap[token] = Operation(handle, keyid, purpose, dev, characteristics, appToken);
+    mMap[token] = Operation(handle, keyid, purpose, dev, std::move(characteristics), appToken);
     if (pruneable) {
         mLru.push_back(token);
     }
@@ -40,10 +41,9 @@
     return token;
 }
 
-bool OperationMap::getOperation(const sp<IBinder>& token, keymaster_operation_handle_t* outHandle,
-                                uint64_t* outKeyid, keymaster_purpose_t* outPurpose,
-                                const keymaster2_device_t** outDevice,
-                                const keymaster_key_characteristics_t** outCharacteristics) {
+bool OperationMap::getOperation(const sp<IBinder>& token, uint64_t* outHandle, uint64_t* outKeyid,
+                                KeyPurpose* outPurpose, km_device_t* outDevice,
+                                const KeyCharacteristics** outCharacteristics) {
     if (!outHandle || !outDevice) {
         return false;
     }
@@ -58,7 +58,7 @@
     *outPurpose = entry->second.purpose;
     *outDevice = entry->second.device;
     if (outCharacteristics) {
-        *outCharacteristics = entry->second.characteristics.get();
+        *outCharacteristics = &entry->second.characteristics;
     }
     return true;
 }
@@ -116,7 +116,8 @@
     return mLru[0];
 }
 
-bool OperationMap::getOperationAuthToken(const sp<IBinder>& token, const hw_auth_token_t** outToken) {
+bool OperationMap::getOperationAuthToken(const sp<IBinder>& token,
+                                         const HardwareAuthToken** outToken) {
     auto entry = mMap.find(token);
     if (entry == mMap.end()) {
         return false;
@@ -125,12 +126,13 @@
     return true;
 }
 
-bool OperationMap::setOperationAuthToken(const sp<IBinder>& token, const hw_auth_token_t* authToken) {
+bool OperationMap::setOperationAuthToken(const sp<IBinder>& token,
+                                         const HardwareAuthToken* authToken) {
     auto entry = mMap.find(token);
     if (entry == mMap.end()) {
         return false;
     }
-    entry->second.authToken.reset(new hw_auth_token_t);
+    entry->second.authToken.reset(new HardwareAuthToken);
     *entry->second.authToken = *authToken;
     return true;
 }
@@ -144,13 +146,13 @@
     }
 }
 
-OperationMap::Operation::Operation(keymaster_operation_handle_t handle_, uint64_t keyid_,
-                                   keymaster_purpose_t purpose_, const keymaster2_device_t* device_,
-                                   keymaster_key_characteristics_t* characteristics_,
-                                   sp<IBinder> appToken_)
+OperationMap::Operation::Operation(uint64_t handle_, uint64_t keyid_, KeyPurpose purpose_,
+                                   const OperationMap::km_device_t& device_,
+                                   KeyCharacteristics&& characteristics_, sp<IBinder> appToken_)
     : handle(handle_), keyid(keyid_), purpose(purpose_), device(device_),
       characteristics(characteristics_), appToken(appToken_) {}
 
-OperationMap::Operation::Operation() : handle(0), device(NULL), characteristics(), appToken(NULL) {}
+OperationMap::Operation::Operation()
+    : handle(0), keyid(0), device(nullptr), characteristics(), appToken(nullptr) {}
 
 }  // namespace android
diff --git a/keystore/operation.h b/keystore/operation.h
index 263b5c9..e69b43a 100644
--- a/keystore/operation.h
+++ b/keystore/operation.h
@@ -17,73 +17,74 @@
 #ifndef KEYSTORE_OPERATION_H_
 #define KEYSTORE_OPERATION_H_
 
-#include <hardware/hw_auth_token.h>
-#include <hardware/keymaster2.h>
 #include <binder/Binder.h>
 #include <binder/IBinder.h>
+#include <keystore/keymaster_tags.h>
+#include <map>
 #include <utils/LruCache.h>
 #include <utils/StrongPointer.h>
-#include <map>
 #include <vector>
 
-namespace android {
+namespace keystore {
 
-struct keymaster_key_characteristics_t_Delete {
-    void operator()(keymaster_key_characteristics_t* characteristics) const {
-        keymaster_free_characteristics(characteristics);
-        delete characteristics;
-    }
-};
-typedef std::unique_ptr<keymaster_key_characteristics_t, keymaster_key_characteristics_t_Delete>
-    Unique_keymaster_key_characteristics;
+using ::android::IBinder;
+using ::android::sp;
 
 /**
- * OperationMap handles the translation of keymaster_operation_handle_t's and
- * keymaster2_device_t's to opaque binder tokens that can be used to reference
- * that operation at a later time by applications. It also does LRU tracking
- * for operation pruning and keeps a mapping of clients to operations to allow
- * for graceful handling of application death.
+ * OperationMap handles the translation of uint64_t's and keymaster2_device_t's to opaque binder
+ * tokens that can be used to reference that operation at a later time by applications. It also does
+ * LRU tracking for operation pruning and keeps a mapping of clients to operations to allow for
+ * graceful handling of application death.
  */
+
 class OperationMap {
-public:
+    typedef ::android::sp<::android::hardware::keymaster::V3_0::IKeymasterDevice> km_device_t;
+
+  public:
     explicit OperationMap(IBinder::DeathRecipient* deathRecipient);
-    sp<IBinder> addOperation(keymaster_operation_handle_t handle, uint64_t keyid,
-                             keymaster_purpose_t purpose, const keymaster2_device_t* dev,
-                             const sp<IBinder>& appToken, keymaster_key_characteristics_t* characteristics,
-                             bool pruneable);
-    bool getOperation(const sp<IBinder>& token, keymaster_operation_handle_t* outHandle,
-                      uint64_t* outKeyid, keymaster_purpose_t* outPurpose,
-                      const keymaster2_device_t** outDev,
-                      const keymaster_key_characteristics_t** outCharacteristics);
-    bool removeOperation(const sp<IBinder>& token);
+    android::sp<android::IBinder> addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
+                                               const km_device_t& dev,
+                                               const android::sp<android::IBinder>& appToken,
+                                               KeyCharacteristics&& characteristics,
+                                               bool pruneable);
+    bool getOperation(const android::sp<android::IBinder>& token, uint64_t* outHandle,
+                      uint64_t* outKeyid, KeyPurpose* outPurpose, km_device_t* outDev,
+                      const KeyCharacteristics** outCharacteristics);
+    bool removeOperation(const android::sp<android::IBinder>& token);
     bool hasPruneableOperation() const;
     size_t getOperationCount() const { return mMap.size(); }
     size_t getPruneableOperationCount() const;
-    bool getOperationAuthToken(const sp<IBinder>& token, const hw_auth_token_t** outToken);
-    bool setOperationAuthToken(const sp<IBinder>& token, const hw_auth_token_t* authToken);
-    sp<IBinder> getOldestPruneableOperation();
-    std::vector<sp<IBinder>> getOperationsForToken(const sp<IBinder>& appToken);
+    bool getOperationAuthToken(const android::sp<android::IBinder>& token,
+                               const HardwareAuthToken** outToken);
+    bool setOperationAuthToken(const android::sp<android::IBinder>& token,
+                               const HardwareAuthToken* authToken);
+    android::sp<android::IBinder> getOldestPruneableOperation();
+    std::vector<android::sp<android::IBinder>>
+    getOperationsForToken(const android::sp<android::IBinder>& appToken);
 
-private:
-    void updateLru(const sp<IBinder>& token);
-    void removeOperationTracking(const sp<IBinder>& token, const sp<IBinder>& appToken);
+  private:
+    void updateLru(const android::sp<android::IBinder>& token);
+    void removeOperationTracking(const android::sp<android::IBinder>& token,
+                                 const android::sp<android::IBinder>& appToken);
     struct Operation {
         Operation();
-        Operation(keymaster_operation_handle_t handle, uint64_t keyid, keymaster_purpose_t purpose,
-                  const keymaster2_device_t* device,
-                  keymaster_key_characteristics_t* characteristics, sp<IBinder> appToken);
-        keymaster_operation_handle_t handle;
+        Operation(uint64_t handle, uint64_t keyid, KeyPurpose purpose, const km_device_t& device,
+                  KeyCharacteristics&& characteristics, android::sp<android::IBinder> appToken);
+        uint64_t handle;
         uint64_t keyid;
-        keymaster_purpose_t purpose;
-        const keymaster2_device_t* device;
-        Unique_keymaster_key_characteristics characteristics;
-        sp<IBinder> appToken;
-        std::unique_ptr<hw_auth_token_t> authToken;
+        KeyPurpose purpose;
+        km_device_t device;
+        KeyCharacteristics characteristics;
+        android::sp<android::IBinder> appToken;
+        std::unique_ptr<HardwareAuthToken> authToken;
     };
-    std::map<sp<IBinder>, struct Operation> mMap;
-    std::vector<sp<IBinder>> mLru;
-    std::map<sp<IBinder>, std::vector<sp<IBinder>>> mAppTokenMap;
-    IBinder::DeathRecipient* mDeathRecipient;
+    std::map<android::sp<android::IBinder>, Operation> mMap;
+    std::vector<android::sp<android::IBinder>> mLru;
+    std::map<android::sp<android::IBinder>, std::vector<android::sp<android::IBinder>>>
+        mAppTokenMap;
+    android::IBinder::DeathRecipient* mDeathRecipient;
 };
-} // namespace android
+
+}  // namespace keystore
+
 #endif
diff --git a/keystore/permissions.cpp b/keystore/permissions.cpp
index 1d3fb8f..1ba91d9 100644
--- a/keystore/permissions.cpp
+++ b/keystore/permissions.cpp
@@ -28,9 +28,25 @@
 
 /* perm_labels associcated with keystore_key SELinux class verbs. */
 const char* perm_labels[] = {
-    "get_state", "get",      "insert",    "delete",    "exist",    "list",
-    "reset",     "password", "lock",      "unlock",    "is_empty", "sign",
-    "verify",    "grant",    "duplicate", "clear_uid", "add_auth", "user_changed",
+    "get_state",
+    "get",
+    "insert",
+    "delete",
+    "exist",
+    "list",
+    "reset",
+    "password",
+    "lock",
+    "unlock",
+    "is_empty",
+    "sign",
+    "verify",
+    "grant",
+    "duplicate",
+    "clear_uid",
+    "add_auth",
+    "user_changed",
+    "gen_unique_id",
 };
 
 struct user_euid {
@@ -40,6 +56,7 @@
 
 user_euid user_euids[] = {
     {AID_VPN, AID_SYSTEM}, {AID_WIFI, AID_SYSTEM}, {AID_ROOT, AID_SYSTEM},
+    {AID_WIFI, AID_KEYSTORE}, {AID_KEYSTORE, AID_WIFI}
 };
 
 struct user_perm {
@@ -54,8 +71,9 @@
     {AID_ROOT, static_cast<perm_t>(P_GET)},
 };
 
-static const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_GET_STATE | P_GET | P_INSERT | P_DELETE |
-                                                        P_EXIST | P_LIST | P_SIGN | P_VERIFY);
+static const perm_t DEFAULT_PERMS = static_cast<perm_t>(
+    P_GET_STATE | P_GET | P_INSERT | P_DELETE | P_EXIST | P_LIST | P_SIGN | P_VERIFY |
+    P_GEN_UNIQUE_ID /* Only privileged apps can do this, but enforcement is done by SELinux */);
 
 struct audit_data {
     pid_t pid;
diff --git a/keystore/permissions.h b/keystore/permissions.h
index f5f1831..80d0e04 100644
--- a/keystore/permissions.h
+++ b/keystore/permissions.h
@@ -39,6 +39,7 @@
     P_CLEAR_UID = 1 << 15,
     P_ADD_AUTH = 1 << 16,
     P_USER_CHANGED = 1 << 17,
+    P_GEN_UNIQUE_ID = 1 << 18,
 };
 
 const char* get_perm_label(perm_t perm);
diff --git a/keystore/user_state.cpp b/keystore/user_state.cpp
index 3da88c2..bd4f979 100644
--- a/keystore/user_state.cpp
+++ b/keystore/user_state.cpp
@@ -31,7 +31,9 @@
 #include "blob.h"
 #include "keystore_utils.h"
 
-UserState::UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) {
+
+UserState::UserState(uid_t userId) :
+        mUserId(userId), mState(STATE_UNINITIALIZED), mRetry(MAX_RETRY) {
     asprintf(&mUserDir, "user_%u", mUserId);
     asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir);
 }
@@ -78,22 +80,22 @@
 
 ResponseCode UserState::initialize(const android::String8& pw, Entropy* entropy) {
     if (!generateMasterKey(entropy)) {
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     ResponseCode response = writeMasterKey(pw, entropy);
-    if (response != NO_ERROR) {
+    if (response != ResponseCode::NO_ERROR) {
         return response;
     }
     setupMasterKeys();
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
 ResponseCode UserState::copyMasterKey(UserState* src) {
     if (mState != STATE_UNINITIALIZED) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     if (src->getState() != STATE_NO_ERROR) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES);
     setupMasterKeys();
@@ -106,28 +108,28 @@
      */
     int in = TEMP_FAILURE_RETRY(open(src->getMasterKeyFileName(), O_RDONLY));
     if (in < 0) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     blob rawBlob;
     size_t length = readFully(in, (uint8_t*)&rawBlob, sizeof(rawBlob));
     if (close(in) != 0) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     int out =
         TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
     if (out < 0) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     size_t outLength = writeFully(out, (uint8_t*)&rawBlob, length);
     if (close(out) != 0) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     if (outLength != length) {
         ALOGW("blob not fully written %zu != %zu", outLength, length);
         unlink(mMasterKeyFile);
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
 ResponseCode UserState::writeMasterKey(const android::String8& pw, Entropy* entropy) {
@@ -142,7 +144,7 @@
 ResponseCode UserState::readMasterKey(const android::String8& pw, Entropy* entropy) {
     int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY));
     if (in < 0) {
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     // We read the raw blob to just to get the salt to generate the AES key, then we create the Blob
@@ -150,7 +152,7 @@
     blob rawBlob;
     size_t length = readFully(in, (uint8_t*)&rawBlob, sizeof(rawBlob));
     if (close(in) != 0) {
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     // find salt at EOF if present, otherwise we have an old file
     uint8_t* salt;
@@ -165,18 +167,18 @@
     AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
     Blob masterKeyBlob(rawBlob);
     ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR);
-    if (response == SYSTEM_ERROR) {
+    if (response == ResponseCode::SYSTEM_ERROR) {
         return response;
     }
-    if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
+    if (response == ResponseCode::NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
         // If salt was missing, generate one and write a new master key file with the salt.
         if (salt == NULL) {
             if (!generateSalt(entropy)) {
-                return SYSTEM_ERROR;
+                return ResponseCode::SYSTEM_ERROR;
             }
             response = writeMasterKey(pw, entropy);
         }
-        if (response == NO_ERROR) {
+        if (response == ResponseCode::NO_ERROR) {
             memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
             setupMasterKeys();
         }
@@ -184,20 +186,20 @@
     }
     if (mRetry <= 0) {
         reset();
-        return UNINITIALIZED;
+        return ResponseCode::UNINITIALIZED;
     }
     --mRetry;
     switch (mRetry) {
     case 0:
-        return WRONG_PASSWORD_0;
+        return ResponseCode::WRONG_PASSWORD_0;
     case 1:
-        return WRONG_PASSWORD_1;
+        return ResponseCode::WRONG_PASSWORD_1;
     case 2:
-        return WRONG_PASSWORD_2;
+        return ResponseCode::WRONG_PASSWORD_2;
     case 3:
-        return WRONG_PASSWORD_3;
+        return ResponseCode::WRONG_PASSWORD_3;
     default:
-        return WRONG_PASSWORD_3;
+        return ResponseCode::WRONG_PASSWORD_3;
     }
 }
 
