diff --git a/keystore-engine/Android.mk b/keystore-engine/Android.mk
index 1f5d903..8988857 100644
--- a/keystore-engine/Android.mk
+++ b/keystore-engine/Android.mk
@@ -16,45 +16,51 @@
 
 include $(CLEAR_VARS)
 
+LOCAL_MODULE := libkeystore-engine
 
-ifneq (,$(wildcard $(TOP)/external/boringssl/flavor.mk))
-	include $(TOP)/external/boringssl/flavor.mk
-else
-	include $(TOP)/external/openssl/flavor.mk
-endif
-ifeq ($(OPENSSL_FLAVOR),BoringSSL)
-  LOCAL_MODULE := libkeystore-engine
-
-  LOCAL_SRC_FILES := \
-	android_engine.cpp
-else
-  LOCAL_MODULE := libkeystore
-
-  LOCAL_MODULE_RELATIVE_PATH := ssl/engines
-
-  LOCAL_SRC_FILES := \
-	eng_keystore.cpp \
-	keyhandle.cpp \
-	ecdsa_meth.cpp \
-	dsa_meth.cpp \
-	rsa_meth.cpp
-
-  LOCAL_C_INCLUDES += \
-	external/openssl/include \
-	external/openssl
-endif
+LOCAL_SRC_FILES := \
+	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 d23f169..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
@@ -125,7 +134,7 @@
  * we've transferred ownership, without triggering a warning by not using the
  * result of release(). */
 #define OWNERSHIP_TRANSFERRED(obj) \
-    typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
+    typeof ((obj).release()) _dummy __attribute__((unused)) = (obj).release()
 
 const char* rsa_get_key_id(const RSA* rsa) {
   return reinterpret_cast<char*>(
@@ -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;
 }
@@ -217,7 +218,7 @@
   NULL /* mod_exp */,
   NULL /* bn_mod_exp */,
 
-  RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_OPAQUE | RSA_FLAG_EXT_PKEY,
+  RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_OPAQUE,
 
   NULL /* keygen */,
   NULL /* multi_prime_keygen */,
@@ -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/dsa_meth.cpp b/keystore-engine/dsa_meth.cpp
deleted file mode 100644
index 3788364..0000000
--- a/keystore-engine/dsa_meth.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright 2013 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 <UniquePtr.h>
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "OpenSSL-keystore-dsa"
-#include <cutils/log.h>
-
-#include <binder/IServiceManager.h>
-#include <keystore/IKeystoreService.h>
-
-#include <openssl/dsa.h>
-#include <openssl/engine.h>
-
-#include "methods.h"
-
-
-using namespace android;
-
-struct DSA_SIG_Delete {
-    void operator()(DSA_SIG* p) const {
-        DSA_SIG_free(p);
-    }
-};
-typedef UniquePtr<DSA_SIG, struct DSA_SIG_Delete> Unique_DSA_SIG;
-
-static DSA_SIG* keystore_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) {
-    ALOGV("keystore_dsa_do_sign(%p, %d, %p)", dgst, dlen, dsa);
-
-    uint8_t* key_id = reinterpret_cast<uint8_t*>(DSA_get_ex_data(dsa, dsa_key_handle));
-    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;
-    }
-
-    int num = DSA_size(dsa);
-
-    uint8_t* reply = NULL;
-    size_t replyLen;
-    int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)), dgst,
-            dlen, &reply, &replyLen);
-    if (ret < 0) {
-        ALOGW("There was an error during dsa_do_sign: could not connect");
-        return 0;
-    } else if (ret != 0) {
-        ALOGW("Error during sign from keystore: %d", ret);
-        return 0;
-    } else if (replyLen <= 0) {
-        ALOGW("No valid signature returned");
-        return 0;
-    } else if (replyLen > (size_t) num) {
-        ALOGW("Signature is too large");
-        return 0;
-    }
-
-    Unique_DSA_SIG dsa_sig(d2i_DSA_SIG(NULL,
-            const_cast<const unsigned char**>(reinterpret_cast<unsigned char**>(&reply)),
-            replyLen));
-    if (dsa_sig.get() == NULL) {
-        ALOGW("conversion from DER to DSA_SIG failed");
-        return 0;
-    }
-
-    ALOGV("keystore_dsa_do_sign(%p, %d, %p) => returning %p len %zu", dgst, dlen, dsa,
-            dsa_sig.get(), replyLen);
-    return dsa_sig.release();
-}
-
-static DSA_METHOD keystore_dsa_meth = {
-        kKeystoreEngineId, /* name */
-        keystore_dsa_do_sign, /* dsa_do_sign */
-        NULL, /* dsa_sign_setup */
-        NULL, /* dsa_do_verify */
-        NULL, /* dsa_mod_exp */
-        NULL, /* bn_mod_exp */
-        NULL, /* init */
-        NULL, /* finish */
-        0, /* flags */
-        NULL, /* app_data */
-        NULL, /* dsa_paramgen */
-        NULL, /* dsa_keygen */
-};
-
-static int register_dsa_methods() {
-    const DSA_METHOD* dsa_meth = DSA_OpenSSL();
-
-    keystore_dsa_meth.dsa_do_verify = dsa_meth->dsa_do_verify;
-
-    return 1;
-}
-
-int dsa_pkey_setup(ENGINE *e, EVP_PKEY *pkey, const char *key_id) {
-    Unique_DSA dsa(EVP_PKEY_get1_DSA(pkey));
-    if (!DSA_set_ex_data(dsa.get(), dsa_key_handle, reinterpret_cast<void*>(strdup(key_id)))) {
-        ALOGW("Could not set ex_data for loaded DSA key");
-        return 0;
-    }
-
-    DSA_set_method(dsa.get(), &keystore_dsa_meth);
-
-    /*
-     * "DSA_set_ENGINE()" should probably be an OpenSSL API. Since it isn't,
-     * and EVP_PKEY_free() calls ENGINE_finish(), we need to call ENGINE_init()
-     * here.
-     */
-    ENGINE_init(e);
-    dsa->engine = e;
-
-    return 1;
-}
-
-int dsa_register(ENGINE* e) {
-    if (!ENGINE_set_DSA(e, &keystore_dsa_meth)
-            || !register_dsa_methods()) {
-        ALOGE("Could not set up keystore DSA methods");
-        return 0;
-    }
-
-    return 1;
-}
diff --git a/keystore-engine/ecdsa_meth.cpp b/keystore-engine/ecdsa_meth.cpp
deleted file mode 100644
index 48f178d..0000000
--- a/keystore-engine/ecdsa_meth.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2013 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 <UniquePtr.h>
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "OpenSSL-keystore-ecdsa"
-#include <cutils/log.h>
-
-#include <binder/IServiceManager.h>
-#include <keystore/IKeystoreService.h>
-
-#include <openssl/ecdsa.h>
-#include <openssl/engine.h>
-
-// TODO replace this with real OpenSSL API when it exists
-#include "crypto/ec/ec_lcl.h"
-#include "crypto/ecdsa/ecs_locl.h"
-
-#include "methods.h"
-
-
-using namespace android;
-
-struct ECDSA_SIG_Delete {
-    void operator()(ECDSA_SIG* p) const {
-        ECDSA_SIG_free(p);
-    }
-};
-typedef UniquePtr<ECDSA_SIG, struct ECDSA_SIG_Delete> Unique_ECDSA_SIG;
-
-static ECDSA_SIG* keystore_ecdsa_do_sign(const unsigned char *dgst, int dlen,
-        const BIGNUM*, const BIGNUM*, EC_KEY *eckey) {
-    ALOGV("keystore_ecdsa_do_sign(%p, %d, %p)", dgst, dlen, eckey);
-
-    uint8_t* key_id = reinterpret_cast<uint8_t*>(EC_KEY_get_key_method_data(eckey,
-                ex_data_dup, ex_data_free, ex_data_clear_free));
-    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;
-    }
-
-    int num = ECDSA_size(eckey);
-
-    uint8_t* reply = NULL;
-    size_t replyLen;
-    int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)), dgst,
-            dlen, &reply, &replyLen);
-    if (ret < 0) {
-        ALOGW("There was an error during dsa_do_sign: could not connect");
-        return 0;
-    } else if (ret != 0) {
-        ALOGW("Error during sign from keystore: %d", ret);
-        return 0;
-    } else if (replyLen <= 0) {
-        ALOGW("No valid signature returned");
-        return 0;
-    } else if (replyLen > (size_t) num) {
-        ALOGW("Signature is too large");
-        return 0;
-    }
-
-    Unique_ECDSA_SIG ecdsa_sig(d2i_ECDSA_SIG(NULL,
-            const_cast<const unsigned char**>(reinterpret_cast<unsigned char**>(&reply)),
-            replyLen));
-    if (ecdsa_sig.get() == NULL) {
-        ALOGW("conversion from DER to ECDSA_SIG failed");
-        return 0;
-    }
-
-    ALOGV("keystore_ecdsa_do_sign(%p, %d, %p) => returning %p len %zu", dgst, dlen, eckey,
-            ecdsa_sig.get(), replyLen);
-    return ecdsa_sig.release();
-}
-
-static ECDSA_METHOD keystore_ecdsa_meth = {
-        kKeystoreEngineId, /* name */
-        keystore_ecdsa_do_sign, /* ecdsa_do_sign */
-        NULL, /* ecdsa_sign_setup */
-        NULL, /* ecdsa_do_verify */
-        0, /* flags */
-        NULL, /* app_data */
-};
-
-static int register_ecdsa_methods() {
-    const ECDSA_METHOD* ecdsa_meth = ECDSA_OpenSSL();
-
-    keystore_ecdsa_meth.ecdsa_do_verify = ecdsa_meth->ecdsa_do_verify;
-
-    return 1;
-}
-
-int ecdsa_pkey_setup(ENGINE *e, EVP_PKEY *pkey, const char *key_id) {
-    Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
-    void* oldData = EC_KEY_insert_key_method_data(eckey.get(),
-            reinterpret_cast<void*>(strdup(key_id)), ex_data_dup, ex_data_free,
-            ex_data_clear_free);
-    if (oldData != NULL) {
-        free(oldData);
-    }
-
-    ECDSA_set_method(eckey.get(), &keystore_ecdsa_meth);
-
-    /*
-     * "ECDSA_set_ENGINE()" should probably be an OpenSSL API. Since it isn't,
-     * and EC_KEY_free() calls ENGINE_finish(), we need to call ENGINE_init()
-     * here.
-     */
-    ECDSA_DATA *ecdsa = ecdsa_check(eckey.get());
-    ENGINE_init(e);
-    ecdsa->engine = e;
-
-    return 1;
-}
-
-int ecdsa_register(ENGINE* e) {
-    if (!ENGINE_set_ECDSA(e, &keystore_ecdsa_meth)
-            || !register_ecdsa_methods()) {
-        ALOGE("Could not set up keystore ECDSA methods");
-        return 0;
-    }
-
-    return 1;
-}
diff --git a/keystore-engine/eng_keystore.cpp b/keystore-engine/eng_keystore.cpp
deleted file mode 100644
index 6feb0f9..0000000
--- a/keystore-engine/eng_keystore.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright 2012 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 <UniquePtr.h>
-
-#include <sys/socket.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <openssl/dsa.h>
-#include <openssl/engine.h>
-#include <openssl/ec.h>
-#include <openssl/evp.h>
-#include <openssl/objects.h>
-#include <openssl/rsa.h>
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "OpenSSL-keystore"
-#include <cutils/log.h>
-
-#include <binder/IServiceManager.h>
-#include <keystore/keystore.h>
-#include <keystore/IKeystoreService.h>
-
-#include "methods.h"
-
-using namespace android;
-
-#define DYNAMIC_ENGINE
-const char* kKeystoreEngineId = "keystore";
-static const char* kKeystoreEngineDesc = "Android keystore engine";
-
-
-/*
- * ex_data index for keystore's key alias.
- */
-int rsa_key_handle;
-int dsa_key_handle;
-
-
-/*
- * Only initialize the *_key_handle once.
- */
-static pthread_once_t key_handle_control = PTHREAD_ONCE_INIT;
-
-/**
- * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
- * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
- * without triggering a warning by not using the result of release().
- */
-#define OWNERSHIP_TRANSFERRED(obj) \
-    typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
-
-
-struct ENGINE_Delete {
-    void operator()(ENGINE* p) const {
-        ENGINE_free(p);
-    }
-};
-typedef UniquePtr<ENGINE, ENGINE_Delete> Unique_ENGINE;
-
-struct EVP_PKEY_Delete {
-    void operator()(EVP_PKEY* p) const {
-        EVP_PKEY_free(p);
-    }
-};
-typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
-
-/**
- * Called to initialize RSA's ex_data for the key_id handle. This should
- * only be called when protected by a lock.
- */
-static void init_key_handle() {
-    rsa_key_handle = RSA_get_ex_new_index(0, NULL, keyhandle_new, keyhandle_dup, keyhandle_free);
-    dsa_key_handle = DSA_get_ex_new_index(0, NULL, keyhandle_new, keyhandle_dup, keyhandle_free);
-}
-
-static EVP_PKEY* keystore_loadkey(ENGINE* e, const char* key_id, UI_METHOD* ui_method,
-        void* callback_data) {
-#if LOG_NDEBUG
-    (void)ui_method;
-    (void)callback_data;
-#else
-    ALOGV("keystore_loadkey(%p, \"%s\", %p, %p)", e, key_id, ui_method, callback_data);
-#endif
-
-    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 *pubkey = NULL;
-    size_t pubkeyLen;
-    int32_t ret = service->get_pubkey(String16(key_id), &pubkey, &pubkeyLen);
-    if (ret < 0) {
-        ALOGW("could not contact keystore");
-        free(pubkey);
-        return NULL;
-    } else if (ret != 0) {
-        ALOGW("keystore reports error: %d", ret);
-        free(pubkey);
-        return NULL;
-    }
-
-    const unsigned char* tmp = reinterpret_cast<const unsigned char*>(pubkey);
-    Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, pubkeyLen));
-    free(pubkey);
-    if (pkey.get() == NULL) {
-        ALOGW("Cannot convert pubkey");
-        return NULL;
-    }
-
-    switch (EVP_PKEY_type(pkey->type)) {
-    case EVP_PKEY_DSA: {
-        dsa_pkey_setup(e, pkey.get(), key_id);
-        break;
-    }
-    case EVP_PKEY_RSA: {
-        rsa_pkey_setup(e, pkey.get(), key_id);
-        break;
-    }
-    case EVP_PKEY_EC: {
-        ecdsa_pkey_setup(e, pkey.get(), key_id);
-        break;
-    }
-    default:
-        ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type));
-        return NULL;
-    }
-
-    return pkey.release();
-}
-
-static const ENGINE_CMD_DEFN keystore_cmd_defns[] = {
-    {0, NULL, NULL, 0}
-};
-
-static int keystore_engine_setup(ENGINE* e) {
-    ALOGV("keystore_engine_setup");
-
-    if (!ENGINE_set_id(e, kKeystoreEngineId)
-            || !ENGINE_set_name(e, kKeystoreEngineDesc)
-            || !ENGINE_set_load_privkey_function(e, keystore_loadkey)
-            || !ENGINE_set_load_pubkey_function(e, keystore_loadkey)
-            || !ENGINE_set_flags(e, 0)
-            || !ENGINE_set_cmd_defns(e, keystore_cmd_defns)) {
-        ALOGE("Could not set up keystore engine");
-        return 0;
-    }
-
-    /* We need a handle in the keys types as well for keygen if it's not already initialized. */
-    pthread_once(&key_handle_control, init_key_handle);
-    if ((rsa_key_handle < 0) || (dsa_key_handle < 0)) {
-        ALOGE("Could not set up ex_data index");
-        return 0;
-    }
-
-    if (!dsa_register(e)) {
-        ALOGE("DSA registration failed");
-        return 0;
-    } else if (!ecdsa_register(e)) {
-        ALOGE("ECDSA registration failed");
-        return 0;
-    } else if (!rsa_register(e)) {
-        ALOGE("RSA registration failed");
-        return 0;
-    }
-
-    return 1;
-}
-
-ENGINE* ENGINE_keystore() {
-    ALOGV("ENGINE_keystore");
-
-    Unique_ENGINE engine(ENGINE_new());
-    if (engine.get() == NULL) {
-        return NULL;
-    }
-
-    if (!keystore_engine_setup(engine.get())) {
-        return NULL;
-    }
-
-    return engine.release();
-}
-
-static int keystore_bind_fn(ENGINE *e, const char *id) {
-    ALOGV("keystore_bind_fn");
-
-    if (!id) {
-        return 0;
-    }
-
-    if (strcmp(id, kKeystoreEngineId)) {
-        return 0;
-    }
-
-    if (!keystore_engine_setup(e)) {
-        return 0;
-    }
-
-    return 1;
-}
-
-extern "C" {
-#undef OPENSSL_EXPORT
-#define OPENSSL_EXPORT extern __attribute__ ((visibility ("default")))
-
-IMPLEMENT_DYNAMIC_CHECK_FN()
-IMPLEMENT_DYNAMIC_BIND_FN(keystore_bind_fn)
-};
diff --git a/keystore-engine/keyhandle.cpp b/keystore-engine/keyhandle.cpp
deleted file mode 100644
index aeba896..0000000
--- a/keystore-engine/keyhandle.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2012 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 <openssl/engine.h>
-
-#include <string.h>
-
-/**
- * Makes sure the ex_data for the keyhandle is initially set to NULL.
- */
-int keyhandle_new(void*, void*, CRYPTO_EX_DATA* ad, int idx, long, void*) {
-    return CRYPTO_set_ex_data(ad, idx, NULL);
-}
-
-/**
- * Frees a previously allocated keyhandle stored in ex_data.
- */
-void keyhandle_free(void *, void *ptr, CRYPTO_EX_DATA*, int, long, void*) {
-    char* keyhandle = reinterpret_cast<char*>(ptr);
-    if (keyhandle != NULL) {
-        free(keyhandle);
-    }
-}
-
-/**
- * Duplicates a keyhandle stored in ex_data in case we copy a key.
- */
-int keyhandle_dup(CRYPTO_EX_DATA* to, CRYPTO_EX_DATA*, void *ptrRef, int idx, long, void *) {
-    // This appears to be a bug in OpenSSL.
-    void** ptr = reinterpret_cast<void**>(ptrRef);
-    char* keyhandle = reinterpret_cast<char*>(*ptr);
-    if (keyhandle != NULL) {
-        char* keyhandle_copy = strdup(keyhandle);
-        *ptr = keyhandle_copy;
-
-        // Call this in case OpenSSL is fixed in the future.
-        (void) CRYPTO_set_ex_data(to, idx, keyhandle_copy);
-    }
-    return 1;
-}
-
-void *ex_data_dup(void *data) {
-    char* keyhandle = reinterpret_cast<char*>(data);
-    return strdup(keyhandle);
-}
-
-void ex_data_free(void *data) {
-    char* keyhandle = reinterpret_cast<char*>(data);
-    free(keyhandle);
-}
-
-void ex_data_clear_free(void *data) {
-    char* keyhandle = reinterpret_cast<char*>(data);
-    memset(data, '\0', strlen(keyhandle));
-    free(keyhandle);
-}
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-engine/rsa_meth.cpp b/keystore-engine/rsa_meth.cpp
deleted file mode 100644
index 74dfa5c..0000000
--- a/keystore-engine/rsa_meth.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright 2012 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 <UniquePtr.h>
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "OpenSSL-keystore-rsa"
-#include <cutils/log.h>
-
-#include <binder/IServiceManager.h>
-#include <keystore/IKeystoreService.h>
-
-#include <openssl/rsa.h>
-#include <openssl/engine.h>
-
-#include "methods.h"
-
-
-using namespace android;
-
-
-int keystore_rsa_priv_enc(int flen, const unsigned char* from, unsigned char* to, RSA* rsa,
-        int padding) {
-    ALOGV("keystore_rsa_priv_enc(%d, %p, %p, %p, %d)", flen, from, to, rsa, padding);
-
-    int num = RSA_size(rsa);
-    UniquePtr<uint8_t> padded(new uint8_t[num]);
-    if (padded.get() == NULL) {
-        ALOGE("could not allocate padded signature");
-        return 0;
-    }
-
-    switch (padding) {
-    case RSA_PKCS1_PADDING:
-        if (!RSA_padding_add_PKCS1_type_1(padded.get(), num, from, flen)) {
-            return 0;
-        }
-        break;
-    case RSA_X931_PADDING:
-        if (!RSA_padding_add_X931(padded.get(), num, from, flen)) {
-            return 0;
-        }
-        break;
-    case RSA_NO_PADDING:
-        if (!RSA_padding_add_none(padded.get(), num, from, flen)) {
-            return 0;
-        }
-        break;
-    default:
-        ALOGE("Unknown padding type: %d", padding);
-        return 0;
-    }
-
-    uint8_t* key_id = reinterpret_cast<uint8_t*>(RSA_get_ex_data(rsa, rsa_key_handle));
-    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 replyLen;
-    int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)), padded.get(),
-            num, &reply, &replyLen);
-    if (ret < 0) {
-        ALOGW("There was an error during signing: could not connect");
-        free(reply);
-        return 0;
-    } else if (ret != 0) {
-        ALOGW("Error during signing from keystore: %d", ret);
-        free(reply);
-        return 0;
-    } else if (replyLen <= 0) {
-        ALOGW("No valid signature returned");
-        return 0;
-    }
-
-    memcpy(to, reply, replyLen);
-    free(reply);
-
-    ALOGV("rsa=%p keystore_rsa_priv_enc => returning %p len %llu", rsa, to,
-            (unsigned long long) replyLen);
-    return static_cast<int>(replyLen);
-}
-
-int keystore_rsa_priv_dec(int flen, const unsigned char* from, unsigned char* to, RSA* rsa,
-        int padding) {
-    ALOGV("keystore_rsa_priv_dec(%d, %p, %p, %p, %d)", flen, from, to, rsa, padding);
-
-    uint8_t* key_id = reinterpret_cast<uint8_t*>(RSA_get_ex_data(rsa, rsa_key_handle));
-    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;
-    }
-
-    int num = RSA_size(rsa);
-
-    uint8_t* reply = NULL;
-    size_t replyLen;
-    int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)), from,
-            flen, &reply, &replyLen);
-    if (ret < 0) {
-        ALOGW("There was an error during rsa_mod_exp: could not connect");
-        return 0;
-    } else if (ret != 0) {
-        ALOGW("Error during sign from keystore: %d", ret);
-        return 0;
-    } else if (replyLen <= 0) {
-        ALOGW("No valid signature returned");
-        return 0;
-    }
-
-    /* Trim off the top zero if it's there */
-    uint8_t* alignedReply;
-    if (*reply == 0x00) {
-        alignedReply = reply + 1;
-        replyLen--;
-    } else {
-        alignedReply = reply;
-    }
-
-    int outSize;
-    switch (padding) {
-    case RSA_PKCS1_PADDING:
-        outSize = RSA_padding_check_PKCS1_type_2(to, num, alignedReply, replyLen, num);
-        break;
-    case RSA_X931_PADDING:
-        outSize = RSA_padding_check_X931(to, num, alignedReply, replyLen, num);
-        break;
-    case RSA_NO_PADDING:
-        outSize = RSA_padding_check_none(to, num, alignedReply, replyLen, num);
-        break;
-    default:
-        ALOGE("Unknown padding type: %d", padding);
-        outSize = -1;
-        break;
-    }
-
-    free(reply);
-
-    ALOGV("rsa=%p keystore_rsa_priv_dec => returning %p len %d", rsa, to, outSize);
-    return outSize;
-}
-
-static RSA_METHOD keystore_rsa_meth = {
-        kKeystoreEngineId,
-        NULL, /* rsa_pub_enc (wrap) */
-        NULL, /* rsa_pub_dec (verification) */
-        keystore_rsa_priv_enc, /* rsa_priv_enc (signing) */
-        keystore_rsa_priv_dec, /* rsa_priv_dec (unwrap) */
-        NULL, /* rsa_mod_exp */
-        NULL, /* bn_mod_exp */
-        NULL, /* init */
-        NULL, /* finish */
-        RSA_FLAG_EXT_PKEY | RSA_FLAG_NO_BLINDING, /* flags */
-        NULL, /* app_data */
-        NULL, /* rsa_sign */
-        NULL, /* rsa_verify */
-        NULL, /* rsa_keygen */
-};
-
-static int register_rsa_methods() {
-    const RSA_METHOD* rsa_meth = RSA_PKCS1_SSLeay();
-
-    keystore_rsa_meth.rsa_pub_enc = rsa_meth->rsa_pub_enc;
-    keystore_rsa_meth.rsa_pub_dec = rsa_meth->rsa_pub_dec;
-    keystore_rsa_meth.rsa_mod_exp = rsa_meth->rsa_mod_exp;
-    keystore_rsa_meth.bn_mod_exp = rsa_meth->bn_mod_exp;
-
-    return 1;
-}
-
-int rsa_pkey_setup(ENGINE *e, EVP_PKEY *pkey, const char *key_id) {
-    Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
-    if (!RSA_set_ex_data(rsa.get(), rsa_key_handle, reinterpret_cast<void*>(strdup(key_id)))) {
-        ALOGW("Could not set ex_data for loaded RSA key");
-        return 0;
-    }
-
-    RSA_set_method(rsa.get(), &keystore_rsa_meth);
-    RSA_blinding_off(rsa.get());
-
-    /*
-     * "RSA_set_ENGINE()" should probably be an OpenSSL API. Since it isn't,
-     * and EVP_PKEY_free() calls ENGINE_finish(), we need to call ENGINE_init()
-     * here.
-     */
-    ENGINE_init(e);
-    rsa->engine = e;
-    rsa->flags |= RSA_FLAG_EXT_PKEY;
-
-    return 1;
-}
-
-int rsa_register(ENGINE* e) {
-    if (!ENGINE_set_RSA(e, &keystore_rsa_meth)
-            || !register_rsa_methods()) {
-        ALOGE("Could not set up keystore RSA methods");
-        return 0;
-    }
-
-    return 1;
-}
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 baff509..8231bf1 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,12 @@
 	libselinux \
 	libsoftkeymasterdevice \
 	libkeymaster_messages \
-	libkeymaster1
+	libkeymaster1 \
+	libhwbinder \
+	libhidlbase \
+	libhidltransport \
+	android.hardware.keymaster@3.0 \
+	android.system.wifi.keystore@1.0
 LOCAL_MODULE := keystore
 LOCAL_MODULE_TAGS := optional
 LOCAL_INIT_RC := keystore.rc
@@ -59,7 +70,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 +80,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 +97,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,27 +116,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 \
+	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)
@@ -128,7 +181,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 7df03c7..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,349 +51,46 @@
     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() {}
 
-void OperationResult::readFromParcel(const Parcel& in) {
-    resultCode = in.readInt32();
+status_t OperationResult::readFromParcel(const Parcel* inn) {
+    const Parcel& in = *inn;
+    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;
 }
 
-void OperationResult::writeToParcel(Parcel* out) const {
+status_t OperationResult::writeToParcel(Parcel* out) const {
     out->writeInt32(resultCode);
     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() {}
+
+status_t ExportResult::readFromParcel(const Parcel* inn) {
+    const Parcel& in = *inn;
+    resultCode = ErrorCode(in.readInt32());
+    exportData = readKeymasterBlob(in);
+    return OK;
 }
 
-ExportResult::~ExportResult() {
-}
-
-void ExportResult::readFromParcel(const Parcel& in) {
-    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");
-        }
-    }
-}
-
-void ExportResult::writeToParcel(Parcel* out) const {
+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.");
-        }
-    }
-}
-
-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);
-}
-
-void KeyCharacteristics::readFromParcel(const Parcel& in) {
-    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;
-}
-
-void 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);
-    }
-}
-
-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 = reinterpret_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;
+    writeKeymasterBlob(exportData, out);
+    return OK;
 }
 
 /**
@@ -411,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:
-    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);
@@ -489,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);
@@ -548,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);
@@ -568,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);
@@ -588,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);
@@ -670,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);
@@ -692,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);
@@ -712,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);
@@ -722,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);
@@ -865,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);
@@ -885,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);
@@ -908,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);
@@ -928,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);
@@ -950,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 (reply.readInt32() != 0 && outCharacteristics) {
-            outCharacteristics->readFromParcel(reply);
+        if (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 (reply.readInt32() != 0 && outCharacteristics) {
-            outCharacteristics->readFromParcel(reply);
+        if (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 (reply.readInt32() != 0 && outCharacteristics) {
-            outCharacteristics->readFromParcel(reply);
+        if (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;
         }
@@ -1102,40 +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;
         }
-        if (reply.readInt32() != 0) {
-            result->readFromParcel(reply);
-        }
+
+        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;
         }
@@ -1143,150 +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;
         }
-        if (reply.readInt32() != 0) {
-            result->readFromParcel(reply);
-        }
+
+        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;
         }
-        if (reply.readInt32() != 0) {
-            result->readFromParcel(reply);
-        }
+
+        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;
         }
-        if (reply.readInt32() != 0) {
-            result->readFromParcel(reply);
-        }
+
+        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);
@@ -1294,605 +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->writeInt32(1);
-            outCharacteristics.writeToParcel(reply);
-            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);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeInt32(1);
-            outCharacteristics.writeToParcel(reply);
-            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->writeInt32(1);
-            outCharacteristics.writeToParcel(reply);
+        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 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);
-            reply->writeNoException();
-            reply->writeInt32(1);
-            result.writeToParcel(reply);
+        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 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->writeInt32(1);
-            result.writeToParcel(reply);
+        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 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->writeInt32(1);
-            result.writeToParcel(reply);
+        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 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->writeInt32(1);
-            result.writeToParcel(reply);
+        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();
+        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 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;
+    }
 
-            return NO_ERROR;
-        }
-        case ON_DEVICE_OFF_BODY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t ret = onDeviceOffBody();
-            reply->writeNoException();
-            reply->writeInt32(ret);
+    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;
-        }
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
+        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 76e757b..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 76cf816..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;
@@ -41,8 +43,9 @@
  */
 class AuthTokenTable {
   public:
-    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) {}
+    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) {}
 
     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 e2fc9be..06f9ea5 100644
--- a/keystore/blob.h
+++ b/keystore/blob.h
@@ -79,7 +79,7 @@
   public:
     Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_t infoLength,
          BlobType type);
-    Blob(blob b);
+    explicit Blob(blob b);
 
     Blob();
 
@@ -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 defd4a9..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,74 +44,37 @@
     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 {
+struct OperationResult : public ::android::Parcelable {
     OperationResult();
     ~OperationResult();
-    void readFromParcel(const Parcel& in);
-    void writeToParcel(Parcel* out) const;
+    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
-struct ExportResult {
+struct ExportResult : public ::android::Parcelable {
     ExportResult();
     ~ExportResult();
-    void readFromParcel(const Parcel& in);
-    void writeToParcel(Parcel* out) const;
+    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 {
-    KeyCharacteristics();
-    ~KeyCharacteristics();
-    void readFromParcel(const Parcel& in);
-    void writeToParcel(Parcel* out) const;
-
-    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..a0593c1 100644
--- a/keystore/include/keystore/keystore_client.h
+++ b/keystore/include/keystore/keystore_client.h
@@ -19,16 +19,19 @@
 #include <string>
 #include <vector>
 
-#include "hardware/keymaster_defs.h"
-#include "keymaster/authorization_set.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 +76,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 +156,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 8fef42f..fce6349 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -21,152 +21,232 @@
 #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());
-    for (auto token : operations) {
+    for (const auto& token : operations) {
         abort(token);
     }
 }
 
-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);
-    String8 filename = mKeyStore->getBlobFileNameIfExists(name8, targetUid, ::TYPE_ANY);
-    if (filename.isEmpty()) return ResponseCode::KEY_NOT_FOUND;
+    ALOGI("del %s %d", name8.string(), targetUid);
+    auto filename = mKeyStore->getBlobFileNameIfExists(name8, targetUid, ::TYPE_ANY);
+    if (!filename.isOk()) return ResponseCode::KEY_NOT_FOUND;
 
-    ResponseCode result = mKeyStore->del(filename.string(), ::TYPE_ANY,
+    ResponseCode result = mKeyStore->del(filename.value().string(), ::TYPE_ANY,
             get_user_id(targetUid));
     if (result != ResponseCode::NO_ERROR) {
         return result;
     }
 
     filename = mKeyStore->getBlobFileNameIfExists(name8, targetUid, ::TYPE_KEY_CHARACTERISTICS);
-    if (!filename.isEmpty()) {
-        return mKeyStore->del(filename.string(), ::TYPE_KEY_CHARACTERISTICS,
+    if (filename.isOk()) {
+        return mKeyStore->del(filename.value().string(), ::TYPE_KEY_CHARACTERISTICS,
                 get_user_id(targetUid));
     }
     return ResponseCode::NO_ERROR;
 }
 
-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 filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid,  ::TYPE_ANY);
-    return (!filename.isEmpty()) ? ResponseCode::NO_ERROR : ResponseCode::KEY_NOT_FOUND;
+    auto filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid, ::TYPE_ANY);
+    return filename.isOk() ? ResponseCode::NO_ERROR : ResponseCode::KEY_NOT_FOUND;
 }
 
-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);
@@ -177,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: {
@@ -195,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.
@@ -217,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);
@@ -263,7 +343,7 @@
             ALOGE("unlock called on keystore in unknown state: %d", state);
             break;
         }
-        return state;
+        return ResponseCode(state);
     }
 
     const String8 password8(pw);
@@ -279,128 +359,133 @@
     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) {
-            sp<KeystoreArg> expArg = args->itemAt(0);
+            const sp<KeystoreArg>& expArg = args->itemAt(0);
             if (expArg != NULL) {
                 Unique_BIGNUM pubExpBn(BN_bin2bn(
                     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);
 }
 
 /*
@@ -414,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;
     }
 
@@ -438,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;
     }
 
@@ -456,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) {
@@ -469,16 +555,16 @@
         return -1L;
     }
 
-    String8 filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid, ::TYPE_ANY);
+    auto filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid, ::TYPE_ANY);
 
-    if (filename.isEmpty()) {
-        ALOGW("could not access %s for getmtime", filename.string());
+    if (!filename.isOk()) {
+        ALOGW("could not access %s for getmtime", filename.value().string());
         return -1L;
     }
 
-    int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY));
+    int fd = TEMP_FAILURE_RETRY(open(filename.value().string(), O_NOFOLLOW, O_RDONLY));
     if (fd < 0) {
-        ALOGW("could not open %s for getmtime", filename.string());
+        ALOGW("could not open %s for getmtime", filename.value().string());
         return -1L;
     }
 
@@ -486,7 +572,7 @@
     int ret = fstat(fd, &s);
     close(fd);
     if (ret == -1) {
-        ALOGW("could not stat %s for getmtime", filename.string());
+        ALOGW("could not stat %s for getmtime", filename.value().string());
         return -1L;
     }
 
@@ -494,26 +580,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) {
@@ -525,12 +611,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;
         }
     }
 
@@ -542,13 +628,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;
     }
 
@@ -559,159 +645,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);
@@ -719,313 +792,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;
+
+    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;
+        }
+        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;
     }
-    keymaster_blob_t output = {NULL, 0};
-    rc = dev->export_key(dev, format, &key, clientId, appData, &output);
-    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);
     }
@@ -1034,224 +1162,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;
 }
 
 /**
@@ -1338,17 +1585,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) {
@@ -1362,43 +1611,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;
@@ -1407,30 +1629,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;
 }
@@ -1438,49 +1662,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;
     }
 }
 
@@ -1489,190 +1705,203 @@
  * 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(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->getBlobFileNameIfExists(name8, uid, ::TYPE_KEYMASTER_10);
-    if (filename.isEmpty()) {
-        ALOGI("trying to upgrade a non existing blob");
-        return KEY_NOT_FOUND;
-    }
-    rc = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(uid));
-    if (rc != ::NO_ERROR) {
-        ALOGI("upgradeKeyBlob keystore->del failed %d", rc);
+    KeyStoreServiceReturnCode error;
+    auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
+        error = ret;
+        if (!error.isOk()) {
+            return;
+        }
+
+        auto filename = mKeyStore->getBlobFileNameIfExists(name8, uid, ::TYPE_KEYMASTER_10);
+        if (!filename.isOk()) {
+            ALOGI("trying to upgrade a non existing blob");
+            return;
+        }
+        error = mKeyStore->del(filename.value().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.value().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 cd43391..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:
-    KeyStoreService(KeyStore* keyStore) : mKeyStore(keyStore), mOperationMap(this) {}
+    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(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 a7a81e8..fecaa09 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) {
@@ -116,42 +125,42 @@
 }
 
 android::String8 KeyStore::getKeyName(const android::String8& keyName, const BlobType type) {
-    char encoded[encode_key_length(keyName) + 1];  // add 1 for null char
-    encode_key(encoded, keyName);
+    std::vector<char> encoded(encode_key_length(keyName) + 1);  // add 1 for null char
+    encode_key(encoded.data(), keyName);
     if (type == TYPE_KEY_CHARACTERISTICS) {
-        return android::String8::format(".chr_%s", encoded);
+        return android::String8::format(".chr_%s", encoded.data());
     } else {
-        return android::String8(encoded);
+        return android::String8(encoded.data());
     }
 }
 
 android::String8 KeyStore::getKeyNameForUid(
     const android::String8& keyName, uid_t uid, const BlobType type) {
-    char encoded[encode_key_length(keyName) + 1];  // add 1 for null char
-    encode_key(encoded, keyName);
+    std::vector<char> encoded(encode_key_length(keyName) + 1);  // add 1 for null char
+    encode_key(encoded.data(), keyName);
     if (type == TYPE_KEY_CHARACTERISTICS) {
-        return android::String8::format(".%u_chr_%s", uid, encoded);
+        return android::String8::format(".%u_chr_%s", uid, encoded.data());
     } else {
-        return android::String8::format("%u_%s", uid, encoded);
+        return android::String8::format("%u_%s", uid, encoded.data());
     }
 }
 
 android::String8 KeyStore::getKeyNameForUidWithDir(
     const android::String8& keyName, uid_t uid, const BlobType type) {
-    char encoded[encode_key_length(keyName) + 1];  // add 1 for null char
-    encode_key(encoded, keyName);
+    std::vector<char> encoded(encode_key_length(keyName) + 1);  // add 1 for null char
+    encode_key(encoded.data(), keyName);
 
     if (type == TYPE_KEY_CHARACTERISTICS) {
         return android::String8::format("%s/.%u_chr_%s", getUserStateByUid(uid)->getUserDirName(),
-                                        uid, encoded);
+                                        uid, encoded.data());
     } else {
         return android::String8::format("%s/%u_%s", getUserStateByUid(uid)->getUserDirName(), uid,
-                                        encoded);
+                                        encoded.data());
     }
 }
 
-android::String8 KeyStore::getBlobFileNameIfExists(const android::String8& alias, uid_t uid,
-                                                  const BlobType type) {
+NullOr<android::String8> KeyStore::getBlobFileNameIfExists(const android::String8& alias, uid_t uid,
+                                                          const BlobType type) {
     android::String8 filepath8(getKeyNameForUidWithDir(alias, uid, type));
 
     if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
@@ -168,7 +177,7 @@
     uid_t granter_uid = strtoul(alias, &end, 10);
     // Does the alias look like a granted key?
     if (end[0] != '_' || end[1] == 0 || (!granter_uid)) {
-        return android::String8();
+        return {};
     }
     android::String8 granted_alias(end + 1);
 
@@ -176,20 +185,21 @@
     // on the key file itself.
     android::String8 keyfilepath8 = getKeyNameForUidWithDir(granted_alias, granter_uid, ::TYPE_ANY);
     if (!hasGrant(keyfilepath8.string(), uid)) {
-        return android::String8();
+        return {};
     }
     // Get the granted blob file path of the desired type
     filepath8 = getKeyNameForUidWithDir(granted_alias, granter_uid, type);
     if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
 
-    return android::String8();
+    return {};
 }
 
+
 void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
     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++) {
@@ -201,13 +211,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);
@@ -271,7 +296,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;
     }
 
@@ -282,28 +307,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);
         }
     }
@@ -316,7 +337,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;
@@ -331,38 +352,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;
 }
 
 /*
@@ -411,7 +421,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;
@@ -442,7 +452,7 @@
         }
     }
     closedir(dir);
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
 void KeyStore::addGrant(const char* filename, uid_t granteeUid) {
@@ -471,74 +481,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,
@@ -546,8 +556,8 @@
     auto filepath8 = getBlobFileNameIfExists(keyName, uid, type);
     uid_t userId = get_user_id(uid);
 
-    if (!filepath8.isEmpty())
-        return get(filepath8.string(), keyBlob, type, userId);
+    if (filepath8.isOk())
+        return get(filepath8.value().string(), keyBlob, type, userId);
 
     return ResponseCode::KEY_NOT_FOUND;
 }
@@ -654,32 +664,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, userId,
                                 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 fee4527..7296806 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;
     }
 
@@ -58,8 +74,8 @@
                                       const BlobType type);
     android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid,
                                              const BlobType type);
-    android::String8 getBlobFileNameIfExists(const android::String8& alias, uid_t uid,
-                                            const BlobType type);
+    NullOr<android::String8> getBlobFileNameIfExists(const android::String8& alias, uid_t uid,
+                                                    const BlobType type);
 
     /*
      * Delete entries owned by userId. If keepUnencryptedEntries is true
@@ -117,8 +133,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 7f6996b..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,15 +183,14 @@
                 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; \
             } \
         } \
     } while (0)
 
-static int list(sp<IKeystoreService> service, const String16& name, int uid) {
+static int list(const sp<IKeystoreService>& service, const String16& name, int uid) {
     Vector<String16> matches;
     int32_t ret = service->list(name, uid, &matches);
     if (ret < 0) {
diff --git a/keystore/keystore_cli_v2.cpp b/keystore/keystore_cli_v2.cpp
index c4dbf5d..95fc491 100644
--- a/keystore/keystore_cli_v2.cpp
+++ b/keystore/keystore_cli_v2.cpp
@@ -19,16 +19,18 @@
 
 #include "base/command_line.h"
 #include "base/files/file_util.h"
-#include "keymaster/authorization_set.h"
-#include "keymaster/keymaster_tags.h"
+#include "base/strings/string_util.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;
@@ -38,7 +40,7 @@
 
 void PrintUsageAndExit() {
     printf("Usage: keystore_client_v2 <command> [options]\n");
-    printf("Commands: brillo-platform-test [--prefix=<test_name_prefix>]\n"
+    printf("Commands: brillo-platform-test [--prefix=<test_name_prefix>] [--test_for_0_3]\n"
            "          list-brillo-tests\n"
            "          add-entropy --input=<entropy>\n"
            "          generate --name=<key_name>\n"
@@ -54,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
-#erro 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));
     }
 }
 
@@ -80,30 +78,27 @@
     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);
-    if (result != KM_ERROR_OK) {
+    const char kBoldRedAbort[] = "\033[1;31mABORT\033[0m";
+    if (!result.isOk()) {
         LOG(ERROR) << "Failed to generate key: " << result;
-        printf("%s Result: ABORT\n", name.c_str());
+        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 Result: ABORT\n", name.c_str());
+        printf("[%s] %s\n", kBoldRedAbort, name.c_str());
         return false;
     }
     printf("===============================================================\n");
     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_PURPOSE) > 0 ||
-        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 ||
-        software_enforced_characteristics.GetTagCount(KM_TAG_DIGEST) > 0 ||
-        software_enforced_characteristics.GetTagCount(KM_TAG_PADDING) > 0 ||
-        software_enforced_characteristics.GetTagCount(KM_TAG_BLOCK_MODE) > 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;
     }
@@ -120,61 +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.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() {
@@ -195,22 +191,33 @@
         {"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)]);
 }
 
-int BrilloPlatformTest(const std::string& prefix) {
+int BrilloPlatformTest(const std::string& prefix, bool test_for_0_3) {
+    const char kBoldYellowWarning[] = "\033[1;33mWARNING\033[0m";
+    if (test_for_0_3) {
+        printf("%s: Testing for keymaster v0.3. "
+               "This does not meet Brillo requirements.\n", kBoldYellowWarning);
+    }
     int test_count = 0;
     int fail_count = 0;
     std::vector<TestCase> test_cases = GetTestCases();
     for (const auto& test_case : test_cases) {
-        if (!prefix.empty() && test_case.name.find(prefix) != 0) {
+        if (!prefix.empty() &&
+            !base::StartsWith(test_case.name, prefix, base::CompareCase::SENSITIVE)) {
+            continue;
+        }
+        if (test_for_0_3 &&
+            (base::StartsWith(test_case.name, "AES", base::CompareCase::SENSITIVE) ||
+             base::StartsWith(test_case.name, "HMAC", base::CompareCase::SENSITIVE))) {
             continue;
         }
         ++test_count;
@@ -263,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);
     }
@@ -286,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);
     }
@@ -299,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;
 }
@@ -341,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;
@@ -356,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");
@@ -432,7 +439,8 @@
         PrintUsageAndExit();
     }
     if (args[0] == "brillo-platform-test") {
-        return BrilloPlatformTest(command_line->GetSwitchValueASCII("prefix"));
+        return BrilloPlatformTest(command_line->GetSwitchValueASCII("prefix"),
+                                  command_line->HasSwitch("test_for_0_3"));
     } else if (args[0] == "list-brillo-tests") {
         return ListTestCases();
     } else if (args[0] == "add-entropy") {
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 b653dd8..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;
@@ -51,33 +54,38 @@
         data += n;
         remaining -= n;
     }
+    if (TEMP_FAILURE_RETRY(fsync(fd)) == -1) {
+        ALOGW("fsync failed: %s", strerror(errno));
+        return -1;
+    }
     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 72aa95f..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> appToken,
-                                       keymaster_key_characteristics_t* characteristics,
-                                       bool pruneable) {
+sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
+                                       const OperationMap::km_device_t& dev,
+                                       const sp<IBinder>& appToken,
+                                       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(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,12 +58,12 @@
     *outPurpose = entry->second.purpose;
     *outDevice = entry->second.device;
     if (outCharacteristics) {
-        *outCharacteristics = entry->second.characteristics.get();
+        *outCharacteristics = &entry->second.characteristics;
     }
     return true;
 }
 
-void OperationMap::updateLru(sp<IBinder> token) {
+void OperationMap::updateLru(const sp<IBinder>& token) {
     auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
     if (lruEntry != mLru.end()) {
         mLru.erase(lruEntry);
@@ -71,7 +71,7 @@
     }
 }
 
-bool OperationMap::removeOperation(sp<IBinder> token) {
+bool OperationMap::removeOperation(const sp<IBinder>& token) {
     auto entry = mMap.find(token);
     if (entry == mMap.end()) {
         return false;
@@ -86,7 +86,7 @@
     return true;
 }
 
-void OperationMap::removeOperationTracking(sp<IBinder> token, sp<IBinder> appToken) {
+void OperationMap::removeOperationTracking(const sp<IBinder>& token, const sp<IBinder>& appToken) {
     auto appEntry = mAppTokenMap.find(appToken);
     if (appEntry == mAppTokenMap.end()) {
         ALOGE("Entry for %p contains unmapped application token %p", token.get(), appToken.get());
@@ -116,7 +116,8 @@
     return mLru[0];
 }
 
-bool OperationMap::getOperationAuthToken(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,17 +126,18 @@
     return true;
 }
 
-bool OperationMap::setOperationAuthToken(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;
 }
 
-std::vector<sp<IBinder>> OperationMap::getOperationsForToken(sp<IBinder> appToken) {
+std::vector<sp<IBinder>> OperationMap::getOperationsForToken(const sp<IBinder>& appToken) {
     auto appEntry = mAppTokenMap.find(appToken);
     if (appEntry != mAppTokenMap.end()) {
         return appEntry->second;
@@ -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 eb16257..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:
-    OperationMap(IBinder::DeathRecipient* deathRecipient);
-    sp<IBinder> addOperation(keymaster_operation_handle_t handle, uint64_t keyid,
-                             keymaster_purpose_t purpose, const keymaster2_device_t* dev,
-                             sp<IBinder> appToken, keymaster_key_characteristics_t* characteristics,
-                             bool pruneable);
-    bool getOperation(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(sp<IBinder> token);
+    typedef ::android::sp<::android::hardware::keymaster::V3_0::IKeymasterDevice> km_device_t;
+
+  public:
+    explicit OperationMap(IBinder::DeathRecipient* deathRecipient);
+    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(sp<IBinder> token, const hw_auth_token_t** outToken);
-    bool setOperationAuthToken(sp<IBinder> token, const hw_auth_token_t* authToken);
-    sp<IBinder> getOldestPruneableOperation();
-    std::vector<sp<IBinder>> getOperationsForToken(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(sp<IBinder> token);
-    void removeOperationTracking(sp<IBinder> token, 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 feacd8f..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;
@@ -84,32 +102,22 @@
 }
 
 static char* tctx;
-static int ks_is_selinux_enabled;
 
 int configure_selinux() {
-    ks_is_selinux_enabled = is_selinux_enabled();
-    if (ks_is_selinux_enabled) {
-        union selinux_callback cb;
-        cb.func_audit = audit_callback;
-        selinux_set_callback(SELINUX_CB_AUDIT, cb);
-        cb.func_log = selinux_log_callback;
-        selinux_set_callback(SELINUX_CB_LOG, cb);
-        if (getcon(&tctx) != 0) {
-            ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n");
-            return -1;
-        }
-    } else {
-        ALOGI("SELinux: Keystore SELinux is disabled.\n");
+    union selinux_callback cb;
+    cb.func_audit = audit_callback;
+    selinux_set_callback(SELINUX_CB_AUDIT, cb);
+    cb.func_log = selinux_log_callback;
+    selinux_set_callback(SELINUX_CB_LOG, cb);
+    if (getcon(&tctx) != 0) {
+        ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n");
+        return -1;
     }
 
     return 0;
 }
 
 static bool keystore_selinux_check_access(uid_t uid, perm_t perm, pid_t spid) {
-    if (!ks_is_selinux_enabled) {
-        return true;
-    }
-
     audit_data ad;
     char* sctx = NULL;
     const char* selinux_class = "keystore_key";
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;
     }
 }
 
diff --git a/keystore/user_state.h b/keystore/user_state.h
index 2a52f81..902719c 100644
--- a/keystore/user_state.h
+++ b/keystore/user_state.h
@@ -29,7 +29,7 @@
 
 class UserState {
   public:
-    UserState(uid_t userId);
+    explicit UserState(uid_t userId);
     ~UserState();
 
     bool initialize();
diff --git a/softkeymaster/keymaster_openssl.cpp b/softkeymaster/keymaster_openssl.cpp
index 6f31195..927b4a6 100644
--- a/softkeymaster/keymaster_openssl.cpp
+++ b/softkeymaster/keymaster_openssl.cpp
@@ -208,17 +208,11 @@
         return NULL;
     }
 
-    Unique_EVP_PKEY pkey(EVP_PKEY_new());
+    Unique_EVP_PKEY pkey(d2i_PrivateKey(type, nullptr, &p, privateLen));
     if (pkey.get() == NULL) {
         logOpenSSLError("unwrap_key");
         return NULL;
     }
-    EVP_PKEY* tmp = pkey.get();
-
-    if (d2i_PrivateKey(type, &tmp, &p, privateLen) == NULL) {
-        logOpenSSLError("unwrap_key");
-        return NULL;
-    }
 
     return pkey.release();
 }
