diff --git a/keystore/Android.mk b/keystore/Android.mk
index 91a63e5..500c2f6 100644
--- a/keystore/Android.mk
+++ b/keystore/Android.mk
@@ -38,6 +38,8 @@
 	keystore.cpp \
 	keystore_main.cpp \
 	keystore_utils.cpp \
+	legacy_keymaster_device_wrapper.cpp \
+	keymaster_enforcement.cpp \
 	operation.cpp \
 	permissions.cpp \
 	user_state.cpp \
@@ -54,7 +56,11 @@
 	libselinux \
 	libsoftkeymasterdevice \
 	libkeymaster_messages \
-	libkeymaster1
+	libkeymaster1 \
+	libhwbinder \
+	libhidlbase \
+	libhidltransport \
+	android.hardware.keymaster@3.0
 LOCAL_MODULE := keystore
 LOCAL_MODULE_TAGS := optional
 LOCAL_INIT_RC := keystore.rc
@@ -72,7 +78,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
@@ -86,8 +95,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
@@ -108,20 +120,27 @@
 	keyblob_utils.cpp \
 	keystore_client.proto \
 	keystore_client_impl.cpp \
-	keystore_get.cpp
+	keystore_get.cpp \
+	authorization_set.cpp \
+	keystore_tags_utils.cpp \
+	keystore_aidl_hidl_marshalling_utils.cpp
 LOCAL_SHARED_LIBRARIES := \
 	libbinder \
-	libkeymaster_messages \
 	liblog \
 	libprotobuf-cpp-lite \
-	libsoftkeymasterdevice \
-	libutils
+	libutils \
+	libhwbinder \
+	libhidlbase \
+	android.hardware.keymaster@3.0
 LOCAL_MODULE_CLASS := SHARED_LIBRARIES
 LOCAL_MODULE := libkeystore_binder
 LOCAL_MODULE_TAGS := optional
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include $(call keystore_proto_include)
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := libbinder \
+	libhwbinder \
+	libhidlbase \
+	android.hardware.keymaster@3.0
 LOCAL_CLANG := true
 LOCAL_SANITIZE := integer
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
@@ -137,7 +156,12 @@
 LOCAL_MODULE := libkeystore_test
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_STATIC_LIBRARIES := libgtest_main
-LOCAL_SHARED_LIBRARIES := libkeymaster_messages
+LOCAL_SHARED_LIBRARIES := libkeymaster_messages \
+	libutils \
+	libhwbinder \
+	libhidlbase \
+	android.hardware.keymaster@3.0
+
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_STATIC_LIBRARY)
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
index acd6968..4c26b60 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -19,28 +19,31 @@
 #include <sys/limits.h>
 #include <sys/types.h>
 
+#include <algorithm>
+#include <limits>
+
 #define LOG_TAG "KeystoreService"
 #include <utils/Log.h>
 
-#include <binder/Parcel.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
+#include <binder/Parcel.h>
 
 #include <keystore/IKeystoreService.h>
+#include <keystore/keystore_hidl_support.h>
+
+#include "keystore_aidl_hidl_marshalling_utils.h"
 
 namespace android {
+using namespace ::keystore;
 
 const ssize_t MAX_GENERATE_ARGS = 3;
-static keymaster_key_param_t* readParamList(const Parcel& in, size_t* length);
 
-KeystoreArg::KeystoreArg(const void* data, size_t len)
-    : mData(data), mSize(len) {
-}
+KeystoreArg::KeystoreArg(const void* data, size_t len) : mData(data), mSize(len) {}
 
-KeystoreArg::~KeystoreArg() {
-}
+KeystoreArg::~KeystoreArg() {}
 
-const void *KeystoreArg::data() const {
+const void* KeystoreArg::data() const {
     return mData;
 }
 
@@ -48,36 +51,18 @@
     return mSize;
 }
 
-OperationResult::OperationResult() : resultCode(0), token(), handle(0), inputConsumed(0),
-    data(NULL), dataLength(0) {
-}
+OperationResult::OperationResult() : resultCode(), token(), handle(0), inputConsumed(0), data() {}
 
-OperationResult::~OperationResult() {
-}
+OperationResult::~OperationResult() {}
 
 status_t OperationResult::readFromParcel(const Parcel* inn) {
     const Parcel& in = *inn;
-    resultCode = in.readInt32();
+    resultCode = ErrorCode(in.readInt32());
     token = in.readStrongBinder();
-    handle = static_cast<keymaster_operation_handle_t>(in.readInt64());
+    handle = static_cast<uint64_t>(in.readInt64());
     inputConsumed = in.readInt32();
-    ssize_t length = in.readInt32();
-    dataLength = 0;
-    if (length > 0) {
-        const void* buf = in.readInplace(length);
-        if (buf) {
-            data.reset(reinterpret_cast<uint8_t*>(malloc(length)));
-            if (data.get()) {
-                memcpy(data.get(), buf, length);
-                dataLength = (size_t) length;
-            } else {
-                ALOGE("Failed to allocate OperationResult buffer");
-            }
-        } else {
-            ALOGE("Failed to readInplace OperationResult data");
-        }
-    }
-    outParams.readFromParcel(in);
+    data = readKeymasterBlob(in);
+    outParams = readParamSetFromParcel(in);
     return OK;
 }
 
@@ -86,322 +71,28 @@
     out->writeStrongBinder(token);
     out->writeInt64(handle);
     out->writeInt32(inputConsumed);
-    out->writeInt32(dataLength);
-    if (dataLength && data) {
-        void* buf = out->writeInplace(dataLength);
-        if (buf) {
-            memcpy(buf, data.get(), dataLength);
-        } else {
-            ALOGE("Failed to writeInplace OperationResult data.");
-        }
-    }
-    outParams.writeToParcel(out);
+    writeKeymasterBlob(data, out);
+    writeParamSetToParcel(outParams, out);
     return OK;
 }
 
-ExportResult::ExportResult() : resultCode(0), exportData(NULL), dataLength(0) {
-}
+ExportResult::ExportResult() : resultCode() {}
 
-ExportResult::~ExportResult() {
-}
+ExportResult::~ExportResult() {}
 
 status_t ExportResult::readFromParcel(const Parcel* inn) {
     const Parcel& in = *inn;
-    resultCode = in.readInt32();
-    ssize_t length = in.readInt32();
-    dataLength = 0;
-    if (length > 0) {
-        const void* buf = in.readInplace(length);
-        if (buf) {
-            exportData.reset(reinterpret_cast<uint8_t*>(malloc(length)));
-            if (exportData.get()) {
-                memcpy(exportData.get(), buf, length);
-                dataLength = (size_t) length;
-            } else {
-                ALOGE("Failed to allocate ExportData buffer");
-            }
-        } else {
-            ALOGE("Failed to readInplace ExportData data");
-        }
-    }
+    resultCode = ErrorCode(in.readInt32());
+    exportData = readKeymasterBlob(in);
     return OK;
 }
 
 status_t ExportResult::writeToParcel(Parcel* out) const {
     out->writeInt32(resultCode);
-    out->writeInt32(dataLength);
-    if (exportData && dataLength) {
-        void* buf = out->writeInplace(dataLength);
-        if (buf) {
-            memcpy(buf, exportData.get(), dataLength);
-        } else {
-            ALOGE("Failed to writeInplace ExportResult data.");
-        }
-    }
+    writeKeymasterBlob(exportData, out);
     return OK;
 }
 
-KeymasterArguments::KeymasterArguments() {
-}
-
-KeymasterArguments::~KeymasterArguments() {
-    keymaster_free_param_values(params.data(), params.size());
-}
-
-void KeymasterArguments::readFromParcel(const Parcel& in) {
-    ssize_t length = in.readInt32();
-    size_t ulength = (size_t) length;
-    if (length < 0) {
-        ulength = 0;
-    }
-    keymaster_free_param_values(params.data(), params.size());
-    params.clear();
-    for(size_t i = 0; i < ulength; i++) {
-        keymaster_key_param_t param;
-        if (!readKeymasterArgumentFromParcel(in, &param)) {
-            ALOGE("Error reading keymaster argument from parcel");
-            break;
-        }
-        params.push_back(param);
-    }
-}
-
-void KeymasterArguments::writeToParcel(Parcel* out) const {
-    out->writeInt32(params.size());
-    for (auto param : params) {
-        out->writeInt32(1);
-        writeKeymasterArgumentToParcel(param, out);
-    }
-}
-
-KeyCharacteristics::KeyCharacteristics() {
-    memset((void*) &characteristics, 0, sizeof(characteristics));
-}
-
-KeyCharacteristics::~KeyCharacteristics() {
-    keymaster_free_characteristics(&characteristics);
-}
-
-status_t KeyCharacteristics::readFromParcel(const Parcel* inn) {
-    const Parcel& in = *inn;
-    size_t length = 0;
-    keymaster_key_param_t* params = readParamList(in, &length);
-    characteristics.sw_enforced.params = params;
-    characteristics.sw_enforced.length = length;
-
-    params = readParamList(in, &length);
-    characteristics.hw_enforced.params = params;
-    characteristics.hw_enforced.length = length;
-    return OK;
-}
-
-status_t KeyCharacteristics::writeToParcel(Parcel* out) const {
-    if (characteristics.sw_enforced.params) {
-        out->writeInt32(characteristics.sw_enforced.length);
-        for (size_t i = 0; i < characteristics.sw_enforced.length; i++) {
-            out->writeInt32(1);
-            writeKeymasterArgumentToParcel(characteristics.sw_enforced.params[i], out);
-        }
-    } else {
-        out->writeInt32(0);
-    }
-    if (characteristics.hw_enforced.params) {
-        out->writeInt32(characteristics.hw_enforced.length);
-        for (size_t i = 0; i < characteristics.hw_enforced.length; i++) {
-            out->writeInt32(1);
-            writeKeymasterArgumentToParcel(characteristics.hw_enforced.params[i], out);
-        }
-    } else {
-        out->writeInt32(0);
-    }
-    return OK;
-}
-
-KeymasterCertificateChain::KeymasterCertificateChain() {
-    memset(&chain, 0, sizeof(chain));
-}
-
-KeymasterCertificateChain::~KeymasterCertificateChain() {
-    keymaster_free_cert_chain(&chain);
-}
-
-static bool readKeymasterBlob(const Parcel& in, keymaster_blob_t* blob) {
-    if (in.readInt32() != 1) {
-        return false;
-    }
-
-    ssize_t length = in.readInt32();
-    if (length <= 0) {
-        return false;
-    }
-
-    blob->data = static_cast<const uint8_t*>(malloc(length));
-    if (!blob->data)
-        return false;
-
-    const void* buf = in.readInplace(length);
-    if (!buf)
-        return false;
-
-    blob->data_length = static_cast<size_t>(length);
-    memcpy(const_cast<uint8_t*>(blob->data), buf, length);
-
-    return true;
-}
-
-void KeymasterCertificateChain::readFromParcel(const Parcel& in) {
-    keymaster_free_cert_chain(&chain);
-
-    ssize_t count = in.readInt32();
-    size_t ucount = count;
-    if (count <= 0) {
-        return;
-    }
-
-    chain.entries = reinterpret_cast<keymaster_blob_t*>(malloc(sizeof(keymaster_blob_t) * ucount));
-    if (!chain.entries) {
-        ALOGE("Error allocating memory for certificate chain");
-        return;
-    }
-
-    memset(chain.entries, 0, sizeof(keymaster_blob_t) * ucount);
-    for (size_t i = 0; i < ucount; ++i) {
-        if (!readKeymasterBlob(in, &chain.entries[i])) {
-            ALOGE("Error reading certificate from parcel");
-            keymaster_free_cert_chain(&chain);
-            return;
-        }
-    }
-}
-
-void KeymasterCertificateChain::writeToParcel(Parcel* out) const {
-    out->writeInt32(chain.entry_count);
-    for (size_t i = 0; i < chain.entry_count; ++i) {
-        if (chain.entries[i].data) {
-            out->writeInt32(chain.entries[i].data_length);
-            void* buf = out->writeInplace(chain.entries[i].data_length);
-            if (buf) {
-                memcpy(buf, chain.entries[i].data, chain.entries[i].data_length);
-            } else {
-                ALOGE("Failed to writeInplace keymaster cert chain entry");
-            }
-        } else {
-            out->writeInt32(0); // Tell Java side this object is NULL.
-            ALOGE("Found NULL certificate chain entry");
-        }
-    }
-}
-
-void writeKeymasterArgumentToParcel(const keymaster_key_param_t& param, Parcel* out) {
-    switch (keymaster_tag_get_type(param.tag)) {
-        case KM_ENUM:
-        case KM_ENUM_REP: {
-            out->writeInt32(param.tag);
-            out->writeInt32(param.enumerated);
-            break;
-        }
-        case KM_UINT:
-        case KM_UINT_REP: {
-            out->writeInt32(param.tag);
-            out->writeInt32(param.integer);
-            break;
-        }
-        case KM_ULONG:
-        case KM_ULONG_REP: {
-            out->writeInt32(param.tag);
-            out->writeInt64(param.long_integer);
-            break;
-        }
-        case KM_DATE: {
-            out->writeInt32(param.tag);
-            out->writeInt64(param.date_time);
-            break;
-        }
-        case KM_BOOL: {
-            out->writeInt32(param.tag);
-            break;
-        }
-        case KM_BIGNUM:
-        case KM_BYTES: {
-            out->writeInt32(param.tag);
-            out->writeInt32(param.blob.data_length);
-            void* buf = out->writeInplace(param.blob.data_length);
-            if (buf) {
-                memcpy(buf, param.blob.data, param.blob.data_length);
-            } else {
-                ALOGE("Failed to writeInplace keymaster blob param");
-            }
-            break;
-        }
-        default: {
-            ALOGE("Failed to write argument: Unsupported keymaster_tag_t %d", param.tag);
-        }
-    }
-}
-
-
-bool readKeymasterArgumentFromParcel(const Parcel& in, keymaster_key_param_t* out) {
-    if (in.readInt32() == 0) {
-        return false;
-    }
-    keymaster_tag_t tag = static_cast<keymaster_tag_t>(in.readInt32());
-    switch (keymaster_tag_get_type(tag)) {
-        case KM_ENUM:
-        case KM_ENUM_REP: {
-            uint32_t value = in.readInt32();
-            *out = keymaster_param_enum(tag, value);
-            break;
-        }
-        case KM_UINT:
-        case KM_UINT_REP: {
-            uint32_t value = in.readInt32();
-            *out = keymaster_param_int(tag, value);
-            break;
-        }
-        case KM_ULONG:
-        case KM_ULONG_REP: {
-            uint64_t value = in.readInt64();
-            *out = keymaster_param_long(tag, value);
-            break;
-        }
-        case KM_DATE: {
-            uint64_t value = in.readInt64();
-            *out = keymaster_param_date(tag, value);
-            break;
-        }
-        case KM_BOOL: {
-            *out = keymaster_param_bool(tag);
-            break;
-        }
-        case KM_BIGNUM:
-        case KM_BYTES: {
-            ssize_t length = in.readInt32();
-            uint8_t* data = NULL;
-            size_t ulength = 0;
-            if (length >= 0) {
-                ulength = (size_t) length;
-                // use malloc here so we can use keymaster_free_param_values
-                // consistently.
-                data = reinterpret_cast<uint8_t*>(malloc(ulength));
-                const void* buf = in.readInplace(ulength);
-                if (!buf || !data) {
-                    ALOGE("Failed to allocate buffer for keymaster blob param");
-                    free(data);
-                    return false;
-                }
-                memcpy(data, buf, ulength);
-            }
-            *out = keymaster_param_blob(tag, data, ulength);
-            break;
-        }
-        default: {
-            ALOGE("Unsupported keymaster_tag_t %d", tag);
-            return false;
-        }
-    }
-    return true;
-}
-
 /**
  * Read a byte array from in. The data at *data is still owned by the parcel
  */
@@ -420,77 +111,31 @@
     }
 }
 
-// Read a keymaster_key_param_t* from a Parcel for use in a
-// keymaster_key_characteristics_t. This will be free'd by calling
-// keymaster_free_key_characteristics.
-static keymaster_key_param_t* readParamList(const Parcel& in, size_t* length) {
-    ssize_t slength = in.readInt32();
-    *length = 0;
-    if (slength < 0) {
-        return NULL;
-    }
-    *length = (size_t) slength;
-    if (*length >= UINT_MAX / sizeof(keymaster_key_param_t)) {
-        return NULL;
-    }
-    keymaster_key_param_t* list =
-            reinterpret_cast<keymaster_key_param_t*>(malloc(*length *
-                                                            sizeof(keymaster_key_param_t)));
-    if (!list) {
-        ALOGD("Failed to allocate buffer for generateKey outCharacteristics");
-        goto err;
-    }
-    for (size_t i = 0; i < *length ; i++) {
-        if (!readKeymasterArgumentFromParcel(in, &list[i])) {
-            ALOGE("Failed to read keymaster argument");
-            keymaster_free_param_values(list, i);
-            goto err;
-        }
-    }
-    return list;
-err:
-    free(list);
-    return NULL;
-}
-
-static std::unique_ptr<keymaster_blob_t> readKeymasterBlob(const Parcel& in) {
-    std::unique_ptr<keymaster_blob_t> blob (new keymaster_blob_t);
-    if (!readKeymasterBlob(in, blob.get())) {
-        blob.reset();
-    }
-    return blob;
-}
-
-class BpKeystoreService: public BpInterface<IKeystoreService>
-{
-public:
-    explicit BpKeystoreService(const sp<IBinder>& impl)
-        : BpInterface<IKeystoreService>(impl)
-    {
-    }
+class BpKeystoreService : public BpInterface<IKeystoreService> {
+  public:
+    explicit BpKeystoreService(const sp<IBinder>& impl) : BpInterface<IKeystoreService>(impl) {}
 
     // test ping
-    virtual int32_t getState(int32_t userId)
-    {
+    KeyStoreServiceReturnCode getState(int32_t userId) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
         status_t status = remote()->transact(BnKeystoreService::GET_STATE, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("getState() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
+        ResponseCode ret = ResponseCode(reply.readInt32());
         if (err < 0) {
             ALOGD("getState() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         return ret;
     }
 
-    virtual int32_t get(const String16& name, int32_t uid, uint8_t** item, size_t* itemLength)
-    {
+    KeyStoreServiceReturnCode get(const String16& name, int32_t uid,
+                                  hidl_vec<uint8_t>* item) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -498,58 +143,40 @@
         status_t status = remote()->transact(BnKeystoreService::GET, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("get() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        ssize_t len = reply.readInt32();
-        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
-            size_t ulen = (size_t) len;
-            const void* buf = reply.readInplace(ulen);
-            *item = (uint8_t*) malloc(ulen);
-            if (*item != NULL) {
-                memcpy(*item, buf, ulen);
-                *itemLength = ulen;
-            } else {
-                ALOGE("out of memory allocating output array in get");
-                *itemLength = 0;
-            }
-        } else {
-            *itemLength = 0;
-        }
         if (err < 0) {
             ALOGD("get() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return 0;
+        auto resultItem = readBlobAsByteArray(reply);
+        if (item) *item = resultItem.value();
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int uid,
-            int32_t flags)
-    {
+    KeyStoreServiceReturnCode insert(const String16& name, const hidl_vec<uint8_t>& item, int uid,
+                                     int32_t flags) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(itemLength);
-        void* buf = data.writeInplace(itemLength);
-        memcpy(buf, item, itemLength);
+        writeBlobAsByteArray(item, &data);
         data.writeInt32(uid);
         data.writeInt32(flags);
         status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("import() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("import() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t del(const String16& name, int uid)
-    {
+    KeyStoreServiceReturnCode del(const String16& name, int uid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -557,19 +184,17 @@
         status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("del() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("del() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t exist(const String16& name, int uid)
-    {
+    KeyStoreServiceReturnCode exist(const String16& name, int uid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -577,19 +202,18 @@
         status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("exist() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("exist() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t list(const String16& prefix, int uid, Vector<String16>* matches)
-    {
+    KeyStoreServiceReturnCode list(const String16& prefix, int uid,
+                                   Vector<String16>* matches) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(prefix);
@@ -597,81 +221,74 @@
         status_t status = remote()->transact(BnKeystoreService::LIST, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("list() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
         int32_t numMatches = reply.readInt32();
         for (int32_t i = 0; i < numMatches; i++) {
             matches->push(reply.readString16());
         }
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("list() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t reset()
-    {
+    KeyStoreServiceReturnCode reset() override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("reset() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("reset() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t onUserPasswordChanged(int32_t userId, const String16& password)
-    {
+    KeyStoreServiceReturnCode onUserPasswordChanged(int32_t userId,
+                                                    const String16& password) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
         data.writeString16(password);
-        status_t status = remote()->transact(BnKeystoreService::ON_USER_PASSWORD_CHANGED, data,
-                                             &reply);
+        status_t status =
+            remote()->transact(BnKeystoreService::ON_USER_PASSWORD_CHANGED, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("onUserPasswordChanged() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("onUserPasswordChanged() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t lock(int32_t userId)
-    {
+    KeyStoreServiceReturnCode lock(int32_t userId) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
         status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("lock() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("lock() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t unlock(int32_t userId, const String16& password)
-    {
+    KeyStoreServiceReturnCode unlock(int32_t userId, const String16& password) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
@@ -679,19 +296,17 @@
         status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("unlock() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("unlock() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual bool isEmpty(int32_t userId)
-    {
+    bool isEmpty(int32_t userId) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
@@ -701,17 +316,16 @@
             return false;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("isEmpty() caught exception %d\n", err);
             return false;
         }
-        return ret != 0;
+        return reply.readInt32() != 0;
     }
 
-    virtual int32_t generate(const String16& name, int32_t uid, int32_t keyType, int32_t keySize,
-            int32_t flags, Vector<sp<KeystoreArg> >* args)
-    {
+    KeyStoreServiceReturnCode generate(const String16& name, int32_t uid, int32_t keyType,
+                                       int32_t keySize, int32_t flags,
+                                       Vector<sp<KeystoreArg>>* args) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -721,7 +335,7 @@
         data.writeInt32(flags);
         data.writeInt32(1);
         data.writeInt32(args->size());
-        for (Vector<sp<KeystoreArg> >::iterator it = args->begin(); it != args->end(); ++it) {
+        for (Vector<sp<KeystoreArg>>::iterator it = args->begin(); it != args->end(); ++it) {
             sp<KeystoreArg> item = *it;
             size_t keyLength = item->size();
             data.writeInt32(keyLength);
@@ -731,142 +345,104 @@
         status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("generate() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("generate() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength, int uid,
-            int flags)
-    {
+    KeyStoreServiceReturnCode import(const String16& name, const hidl_vec<uint8_t>& key, int uid,
+                                     int flags) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(keyLength);
-        void* buf = data.writeInplace(keyLength);
-        memcpy(buf, key, keyLength);
+        writeBlobAsByteArray(key, &data);
         data.writeInt32(uid);
         data.writeInt32(flags);
         status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("import() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("import() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t sign(const String16& name, const uint8_t* in, size_t inLength, uint8_t** out,
-            size_t* outLength)
-    {
+    KeyStoreServiceReturnCode sign(const String16& name, const hidl_vec<uint8_t>& in,
+                                   hidl_vec<uint8_t>* out) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(inLength);
-        void* buf = data.writeInplace(inLength);
-        memcpy(buf, in, inLength);
+        writeBlobAsByteArray(in, &data);
         status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("import() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        ssize_t len = reply.readInt32();
-        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
-            size_t ulen = (size_t) len;
-            const void* outBuf = reply.readInplace(ulen);
-            *out = (uint8_t*) malloc(ulen);
-            if (*out != NULL) {
-                memcpy((void*) *out, outBuf, ulen);
-                *outLength = ulen;
-            } else {
-                ALOGE("out of memory allocating output array in sign");
-                *outLength = 0;
-            }
-        } else {
-            *outLength = 0;
-        }
         if (err < 0) {
             ALOGD("import() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return 0;
+        auto outBlob = readBlobAsByteArray(reply);
+        if (out) {
+            // don't need to check outBlob.isOk()
+            // if !outBlob.isOk() the wrapped value is default constructed and therefore empty,
+            // as expected.
+            *out = outBlob.value();
+        }
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t verify(const String16& name, const uint8_t* in, size_t inLength,
-            const uint8_t* signature, size_t signatureLength)
-    {
+    KeyStoreServiceReturnCode verify(const String16& name, const hidl_vec<uint8_t>& in,
+                                     const hidl_vec<uint8_t>& signature) override {
         Parcel data, reply;
-        void* buf;
 
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(inLength);
-        buf = data.writeInplace(inLength);
-        memcpy(buf, in, inLength);
-        data.writeInt32(signatureLength);
-        buf = data.writeInplace(signatureLength);
-        memcpy(buf, signature, signatureLength);
+        writeBlobAsByteArray(in, &data);
+        writeBlobAsByteArray(signature, &data);
         status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("verify() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("verify() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength)
-    {
+    KeyStoreServiceReturnCode get_pubkey(const String16& name, hidl_vec<uint8_t>* pubkey) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
         status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("get_pubkey() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        ssize_t len = reply.readInt32();
-        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
-            size_t ulen = (size_t) len;
-            const void* buf = reply.readInplace(ulen);
-            *pubkey = (uint8_t*) malloc(ulen);
-            if (*pubkey != NULL) {
-                memcpy(*pubkey, buf, ulen);
-                *pubkeyLength = ulen;
-            } else {
-                ALOGE("out of memory allocating output array in get_pubkey");
-                *pubkeyLength = 0;
-            }
-        } else {
-            *pubkeyLength = 0;
-        }
         if (err < 0) {
             ALOGD("get_pubkey() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return 0;
-     }
+        auto resultKey = readBlobAsByteArray(reply);
+        if (pubkey) *pubkey = resultKey.value();
+        return ResponseCode(reply.readInt32());
+    }
 
-    virtual int32_t grant(const String16& name, int32_t granteeUid)
-    {
+    KeyStoreServiceReturnCode grant(const String16& name, int32_t granteeUid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -874,19 +450,17 @@
         status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("grant() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("grant() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t ungrant(const String16& name, int32_t granteeUid)
-    {
+    KeyStoreServiceReturnCode ungrant(const String16& name, int32_t granteeUid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -894,19 +468,17 @@
         status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("ungrant() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("ungrant() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    int64_t getmtime(const String16& name, int32_t uid)
-    {
+    int64_t getmtime(const String16& name, int32_t uid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
@@ -917,17 +489,15 @@
             return -1;
         }
         int32_t err = reply.readExceptionCode();
-        int64_t ret = reply.readInt64();
         if (err < 0) {
             ALOGD("getmtime() caught exception %d\n", err);
             return -1;
         }
-        return ret;
+        return reply.readInt64();
     }
 
-    virtual int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
-            int32_t destUid)
-    {
+    KeyStoreServiceReturnCode duplicate(const String16& srcKey, int32_t srcUid,
+                                        const String16& destKey, int32_t destUid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(srcKey);
@@ -937,19 +507,17 @@
         status_t status = remote()->transact(BnKeystoreService::DUPLICATE, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("duplicate() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("duplicate() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t is_hardware_backed(const String16& keyType)
-    {
+    int32_t is_hardware_backed(const String16& keyType) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(keyType);
@@ -959,151 +527,132 @@
             return -1;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("is_hardware_backed() caught exception %d\n", err);
             return -1;
         }
-        return ret;
+        return reply.readInt32();
     }
 
-    virtual int32_t clear_uid(int64_t uid)
-    {
+    KeyStoreServiceReturnCode clear_uid(int64_t uid) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt64(uid);
         status_t status = remote()->transact(BnKeystoreService::CLEAR_UID, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("clear_uid() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("clear_uid() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual int32_t addRngEntropy(const uint8_t* buf, size_t bufLength)
-    {
+    KeyStoreServiceReturnCode addRngEntropy(const hidl_vec<uint8_t>& entropy) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
-        data.writeByteArray(bufLength, buf);
+        writeBlobAsByteArray(entropy, &data);
         status_t status = remote()->transact(BnKeystoreService::ADD_RNG_ENTROPY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("addRngEntropy() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("addRngEntropy() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     };
 
-    virtual int32_t generateKey(const String16& name, const KeymasterArguments& params,
-                                const uint8_t* entropy, size_t entropyLength, int uid, int flags,
-                                KeyCharacteristics* outCharacteristics)
-    {
+    KeyStoreServiceReturnCode generateKey(const String16& name,
+                                          const hidl_vec<KeyParameter>& params,
+                                          const hidl_vec<uint8_t>& entropy, int uid, int flags,
+                                          KeyCharacteristics* outCharacteristics) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeByteArray(entropyLength, entropy);
+        nullable(writeParamSetToParcel, params, &data);
+        writeBlobAsByteArray(entropy, &data);
         data.writeInt32(uid);
         data.writeInt32(flags);
         status_t status = remote()->transact(BnKeystoreService::GENERATE_KEY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("generateKey() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
+        ResponseCode ret = ResponseCode(reply.readInt32());
         if (err < 0) {
             ALOGD("generateKey() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         if (outCharacteristics) {
-            reply.readParcelable(outCharacteristics);
+            *outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value();
         }
         return ret;
     }
-    virtual int32_t getKeyCharacteristics(const String16& name,
-                                          const keymaster_blob_t* clientId,
-                                          const keymaster_blob_t* appData,
-                                          int32_t uid, KeyCharacteristics* outCharacteristics)
-    {
+    KeyStoreServiceReturnCode
+    getKeyCharacteristics(const String16& name, const hidl_vec<uint8_t>& clientId,
+                          const hidl_vec<uint8_t>& appData, int32_t uid,
+                          KeyCharacteristics* outCharacteristics) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        if (clientId) {
-            data.writeByteArray(clientId->data_length, clientId->data);
-        } else {
-            data.writeInt32(-1);
-        }
-        if (appData) {
-            data.writeByteArray(appData->data_length, appData->data);
-        } else {
-            data.writeInt32(-1);
-        }
+        writeBlobAsByteArray(clientId, &data);
+        writeBlobAsByteArray(appData, &data);
         data.writeInt32(uid);
-        status_t status = remote()->transact(BnKeystoreService::GET_KEY_CHARACTERISTICS,
-                                             data, &reply);
+        status_t status =
+            remote()->transact(BnKeystoreService::GET_KEY_CHARACTERISTICS, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("getKeyCharacteristics() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
+        ResponseCode ret = ResponseCode(reply.readInt32());
         if (err < 0) {
             ALOGD("getKeyCharacteristics() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         if (outCharacteristics) {
-            reply.readParcelable(outCharacteristics);
+            *outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value();
         }
         return ret;
     }
-    virtual int32_t importKey(const String16& name, const KeymasterArguments&  params,
-                              keymaster_key_format_t format, const uint8_t *keyData,
-                              size_t keyLength, int uid, int flags,
-                              KeyCharacteristics* outCharacteristics)
-    {
+    KeyStoreServiceReturnCode importKey(const String16& name, const hidl_vec<KeyParameter>& params,
+                                        KeyFormat format, const hidl_vec<uint8_t>& keyData, int uid,
+                                        int flags,
+                                        KeyCharacteristics* outCharacteristics) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeInt32(format);
-        data.writeByteArray(keyLength, keyData);
+        nullable(writeParamSetToParcel, params, &data);
+        data.writeInt32(uint32_t(format));
+        writeBlobAsByteArray(keyData, &data);
         data.writeInt32(uid);
         data.writeInt32(flags);
         status_t status = remote()->transact(BnKeystoreService::IMPORT_KEY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("importKey() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
+        ResponseCode ret = ResponseCode(reply.readInt32());
         if (err < 0) {
             ALOGD("importKey() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         if (outCharacteristics) {
-            reply.readParcelable(outCharacteristics);
+            *outCharacteristics = nullable(readKeyCharacteristicsFromParcel, reply).value();
         }
         return ret;
     }
 
-    virtual void exportKey(const String16& name, keymaster_key_format_t format,
-                           const keymaster_blob_t* clientId,
-                           const keymaster_blob_t* appData, int32_t uid, ExportResult* result)
-    {
+    void exportKey(const String16& name, KeyFormat format, const hidl_vec<uint8_t>& clientId,
+                   const hidl_vec<uint8_t>& appData, int32_t uid, ExportResult* result) override {
         if (!result) {
             return;
         }
@@ -1111,39 +660,29 @@
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeString16(name);
-        data.writeInt32(format);
-        if (clientId) {
-            data.writeByteArray(clientId->data_length, clientId->data);
-        } else {
-            data.writeInt32(-1);
-        }
-        if (appData) {
-            data.writeByteArray(appData->data_length, appData->data);
-        } else {
-            data.writeInt32(-1);
-        }
+        data.writeInt32(int32_t(format));
+        writeBlobAsByteArray(clientId, &data);
+        writeBlobAsByteArray(appData, &data);
         data.writeInt32(uid);
         status_t status = remote()->transact(BnKeystoreService::EXPORT_KEY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("exportKey() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
         int32_t err = reply.readExceptionCode();
         if (err < 0) {
             ALOGD("exportKey() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
 
         reply.readParcelable(result);
     }
 
-    virtual void begin(const sp<IBinder>& appToken, const String16& name,
-                       keymaster_purpose_t purpose, bool pruneable,
-                       const KeymasterArguments& params, const uint8_t* entropy,
-                       size_t entropyLength, int32_t uid, OperationResult* result)
-    {
+    void begin(const sp<IBinder>& appToken, const String16& name, KeyPurpose purpose,
+               bool pruneable, const hidl_vec<KeyParameter>& params,
+               const hidl_vec<uint8_t>& entropy, int32_t uid, OperationResult* result) override {
         if (!result) {
             return;
         }
@@ -1151,147 +690,134 @@
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeStrongBinder(appToken);
         data.writeString16(name);
-        data.writeInt32(purpose);
+        data.writeInt32(int32_t(purpose));
         data.writeInt32(pruneable ? 1 : 0);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeByteArray(entropyLength, entropy);
+        nullable(writeParamSetToParcel, params, &data);
+        writeBlobAsByteArray(entropy, &data);
         data.writeInt32(uid);
         status_t status = remote()->transact(BnKeystoreService::BEGIN, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("begin() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
         int32_t err = reply.readExceptionCode();
         if (err < 0) {
             ALOGD("begin() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
 
         reply.readParcelable(result);
     }
 
-    virtual void update(const sp<IBinder>& token, const KeymasterArguments& params,
-                        const uint8_t* opData, size_t dataLength, OperationResult* result)
-    {
+    void update(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
+                const hidl_vec<uint8_t>& opData, OperationResult* result) override {
         if (!result) {
             return;
         }
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeStrongBinder(token);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeByteArray(dataLength, opData);
+        nullable(writeParamSetToParcel, params, &data);
+        writeBlobAsByteArray(opData, &data);
         status_t status = remote()->transact(BnKeystoreService::UPDATE, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("update() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
         int32_t err = reply.readExceptionCode();
         if (err < 0) {
             ALOGD("update() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
 
         reply.readParcelable(result);
     }
 
-    virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
-                        const uint8_t* signature, size_t signatureLength,
-                        const uint8_t* entropy, size_t entropyLength,
-                        OperationResult* result)
-    {
+    void finish(const sp<IBinder>& token, const hidl_vec<KeyParameter>& params,
+                const hidl_vec<uint8_t>& signature, const hidl_vec<uint8_t>& entropy,
+                OperationResult* result) override {
         if (!result) {
             return;
         }
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeStrongBinder(token);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeByteArray(signatureLength, signature);
-        data.writeByteArray(entropyLength, entropy);
+        nullable(writeParamSetToParcel, params, &data);
+        writeBlobAsByteArray(signature, &data);
+        writeBlobAsByteArray(entropy, &data);
         status_t status = remote()->transact(BnKeystoreService::FINISH, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("finish() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
         int32_t err = reply.readExceptionCode();
         if (err < 0) {
             ALOGD("finish() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            result->resultCode = ResponseCode::SYSTEM_ERROR;
             return;
         }
 
         reply.readParcelable(result);
     }
 
-    virtual int32_t abort(const sp<IBinder>& token)
-    {
+    KeyStoreServiceReturnCode abort(const sp<IBinder>& token) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeStrongBinder(token);
         status_t status = remote()->transact(BnKeystoreService::ABORT, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("abort() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("abort() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
 
-    virtual bool isOperationAuthorized(const sp<IBinder>& token)
-    {
+    bool isOperationAuthorized(const sp<IBinder>& token) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeStrongBinder(token);
-        status_t status = remote()->transact(BnKeystoreService::IS_OPERATION_AUTHORIZED, data,
-                                             &reply);
+        status_t status =
+            remote()->transact(BnKeystoreService::IS_OPERATION_AUTHORIZED, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("isOperationAuthorized() could not contact remote: %d\n", status);
             return false;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("isOperationAuthorized() caught exception %d\n", err);
             return false;
         }
-        return ret == 1;
+        return reply.readInt32() == 1;
     }
 
-    virtual int32_t addAuthToken(const uint8_t* token, size_t length)
-    {
+    KeyStoreServiceReturnCode addAuthToken(const uint8_t* token, size_t length) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeByteArray(length, token);
         status_t status = remote()->transact(BnKeystoreService::ADD_AUTH_TOKEN, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("addAuthToken() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("addAuthToken() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     };
 
-    virtual int32_t onUserAdded(int32_t userId, int32_t parentId)
-    {
+    KeyStoreServiceReturnCode onUserAdded(int32_t userId, int32_t parentId) override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         data.writeInt32(userId);
@@ -1299,609 +825,499 @@
         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 onDeviceOffBody() override {
         Parcel data, reply;
         data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
         status_t status = remote()->transact(BnKeystoreService::ON_DEVICE_OFF_BODY, data, &reply);
         if (status != NO_ERROR) {
             ALOGD("onDeviceOffBody() could not contact remote: %d\n", status);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
         int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
         if (err < 0) {
             ALOGD("onDeviceOffBody() caught exception %d\n", err);
-            return -1;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        return ret;
+        return ResponseCode(reply.readInt32());
     }
-
 };
 
 IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService");
 
 // ----------------------------------------------------------------------
 
-status_t BnKeystoreService::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch(code) {
-        case GET_STATE: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            int32_t ret = getState(userId);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case GET: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int32_t uid = data.readInt32();
-            void* out = NULL;
-            size_t outSize = 0;
-            int32_t ret = get(name, uid, (uint8_t**) &out, &outSize);
-            reply->writeNoException();
-            if (ret == 1) {
-                reply->writeInt32(outSize);
-                void* buf = reply->writeInplace(outSize);
-                memcpy(buf, out, outSize);
-                free(out);
-            } else {
-                reply->writeInt32(-1);
+status_t BnKeystoreService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+                                       uint32_t flags) {
+    switch (code) {
+    case GET_STATE: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        int32_t ret = getState(userId);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case GET: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int32_t uid = data.readInt32();
+        hidl_vec<uint8_t> out;
+        auto ret = get(name, uid, &out);
+        reply->writeNoException();
+        if (ret.isOk()) {
+            writeBlobAsByteArray(out, reply);
+        } else {
+            reply->writeInt32(-1);
+        }
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case INSERT: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto in = readBlobAsByteArray(data);
+        int uid = data.readInt32();
+        int32_t flags = data.readInt32();
+        int32_t ret = insert(name, in.value(), uid, flags);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case DEL: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int uid = data.readInt32();
+        int32_t ret = del(name, uid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case EXIST: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int uid = data.readInt32();
+        int32_t ret = exist(name, uid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case LIST: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 prefix = data.readString16();
+        int uid = data.readInt32();
+        Vector<String16> matches;
+        int32_t ret = list(prefix, uid, &matches);
+        reply->writeNoException();
+        reply->writeInt32(matches.size());
+        Vector<String16>::const_iterator it = matches.begin();
+        for (; it != matches.end(); ++it) {
+            reply->writeString16(*it);
+        }
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case RESET: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t ret = reset();
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case ON_USER_PASSWORD_CHANGED: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        String16 pass = data.readString16();
+        int32_t ret = onUserPasswordChanged(userId, pass);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case LOCK: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        int32_t ret = lock(userId);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case UNLOCK: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        String16 pass = data.readString16();
+        int32_t ret = unlock(userId, pass);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case IS_EMPTY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        bool ret = isEmpty(userId);
+        reply->writeNoException();
+        reply->writeInt32(ret ? 1 : 0);
+        return NO_ERROR;
+    } break;
+    case GENERATE: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int32_t uid = data.readInt32();
+        int32_t keyType = data.readInt32();
+        int32_t keySize = data.readInt32();
+        int32_t flags = data.readInt32();
+        Vector<sp<KeystoreArg>> args;
+        int32_t argsPresent = data.readInt32();
+        if (argsPresent == 1) {
+            ssize_t numArgs = data.readInt32();
+            if (numArgs > MAX_GENERATE_ARGS) {
+                return BAD_VALUE;
             }
-            return NO_ERROR;
-        } break;
-        case INSERT: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            ssize_t inSize = data.readInt32();
-            const void* in;
-            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
-                in = data.readInplace(inSize);
-            } else {
-                in = NULL;
-                inSize = 0;
-            }
-            int uid = data.readInt32();
-            int32_t flags = data.readInt32();
-            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case DEL: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int uid = data.readInt32();
-            int32_t ret = del(name, uid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case EXIST: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int uid = data.readInt32();
-            int32_t ret = exist(name, uid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case LIST: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 prefix = data.readString16();
-            int uid = data.readInt32();
-            Vector<String16> matches;
-            int32_t ret = list(prefix, uid, &matches);
-            reply->writeNoException();
-            reply->writeInt32(matches.size());
-            Vector<String16>::const_iterator it = matches.begin();
-            for (; it != matches.end(); ++it) {
-                reply->writeString16(*it);
-            }
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case RESET: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t ret = reset();
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case ON_USER_PASSWORD_CHANGED: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            String16 pass = data.readString16();
-            int32_t ret = onUserPasswordChanged(userId, pass);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case LOCK: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            int32_t ret = lock(userId);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case UNLOCK: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            String16 pass = data.readString16();
-            int32_t ret = unlock(userId, pass);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case IS_EMPTY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            bool ret = isEmpty(userId);
-            reply->writeNoException();
-            reply->writeInt32(ret ? 1 : 0);
-            return NO_ERROR;
-        } break;
-        case GENERATE: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int32_t uid = data.readInt32();
-            int32_t keyType = data.readInt32();
-            int32_t keySize = data.readInt32();
-            int32_t flags = data.readInt32();
-            Vector<sp<KeystoreArg> > args;
-            int32_t argsPresent = data.readInt32();
-            if (argsPresent == 1) {
-                ssize_t numArgs = data.readInt32();
-                if (numArgs > MAX_GENERATE_ARGS) {
-                    return BAD_VALUE;
-                }
-                if (numArgs > 0) {
-                    for (size_t i = 0; i < (size_t) numArgs; i++) {
-                        ssize_t inSize = data.readInt32();
-                        if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
-                            sp<KeystoreArg> arg = new KeystoreArg(data.readInplace(inSize),
-                                                                  inSize);
-                            args.push_back(arg);
-                        } else {
-                            args.push_back(NULL);
-                        }
+            if (numArgs > 0) {
+                for (size_t i = 0; i < (size_t)numArgs; i++) {
+                    ssize_t inSize = data.readInt32();
+                    if (inSize >= 0 && (size_t)inSize <= data.dataAvail()) {
+                        sp<KeystoreArg> arg = new KeystoreArg(data.readInplace(inSize), inSize);
+                        args.push_back(arg);
+                    } else {
+                        args.push_back(NULL);
                     }
                 }
             }
-            int32_t ret = generate(name, uid, keyType, keySize, flags, &args);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case IMPORT: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            ssize_t inSize = data.readInt32();
-            const void* in;
-            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
-                in = data.readInplace(inSize);
-            } else {
-                in = NULL;
-                inSize = 0;
-            }
-            int uid = data.readInt32();
-            int32_t flags = data.readInt32();
-            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize, uid, flags);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case SIGN: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            ssize_t inSize = data.readInt32();
-            const void* in;
-            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
-                in = data.readInplace(inSize);
-            } else {
-                in = NULL;
-                inSize = 0;
-            }
-            void* out = NULL;
-            size_t outSize = 0;
-            int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
-            reply->writeNoException();
-            if (outSize > 0 && out != NULL) {
-                reply->writeInt32(outSize);
-                void* buf = reply->writeInplace(outSize);
-                memcpy(buf, out, outSize);
-                delete[] reinterpret_cast<uint8_t*>(out);
-            } else {
-                reply->writeInt32(-1);
-            }
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case VERIFY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            ssize_t inSize = data.readInt32();
-            const void* in;
-            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
-                in = data.readInplace(inSize);
-            } else {
-                in = NULL;
-                inSize = 0;
-            }
-            ssize_t sigSize = data.readInt32();
-            const void* sig;
-            if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
-                sig = data.readInplace(sigSize);
-            } else {
-                sig = NULL;
-                sigSize = 0;
-            }
-            bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
-                    (size_t) sigSize);
-            reply->writeNoException();
-            reply->writeInt32(ret ? 1 : 0);
-            return NO_ERROR;
-        } break;
-        case GET_PUBKEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            void* out = NULL;
-            size_t outSize = 0;
-            int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
-            reply->writeNoException();
-            if (outSize > 0 && out != NULL) {
-                reply->writeInt32(outSize);
-                void* buf = reply->writeInplace(outSize);
-                memcpy(buf, out, outSize);
-                free(out);
-            } else {
-                reply->writeInt32(-1);
-            }
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case GRANT: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int32_t granteeUid = data.readInt32();
-            int32_t ret = grant(name, granteeUid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case UNGRANT: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int32_t granteeUid = data.readInt32();
-            int32_t ret = ungrant(name, granteeUid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case GETMTIME: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            int32_t uid = data.readInt32();
-            int64_t ret = getmtime(name, uid);
-            reply->writeNoException();
-            reply->writeInt64(ret);
-            return NO_ERROR;
-        } break;
-        case DUPLICATE: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 srcKey = data.readString16();
-            int32_t srcUid = data.readInt32();
-            String16 destKey = data.readString16();
-            int32_t destUid = data.readInt32();
-            int32_t ret = duplicate(srcKey, srcUid, destKey, destUid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        } break;
-        case IS_HARDWARE_BACKED: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 keyType = data.readString16();
-            int32_t ret = is_hardware_backed(keyType);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
         }
-        case CLEAR_UID: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int64_t uid = data.readInt64();
-            int32_t ret = clear_uid(uid);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        }
-        case ADD_RNG_ENTROPY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            const uint8_t* bytes = NULL;
-            size_t size = 0;
-            readByteArray(data, &bytes, &size);
-            int32_t ret = addRngEntropy(bytes, size);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        }
-        case GENERATE_KEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            const uint8_t* entropy = NULL;
-            size_t entropyLength = 0;
-            readByteArray(data, &entropy, &entropyLength);
-            int32_t uid = data.readInt32();
-            int32_t flags = data.readInt32();
-            KeyCharacteristics outCharacteristics;
-            int32_t ret = generateKey(name, args, entropy, entropyLength, uid, flags,
-                                      &outCharacteristics);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeParcelable(outCharacteristics);
-            return NO_ERROR;
-        }
-        case GET_KEY_CHARACTERISTICS: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
-            std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
-            int32_t uid = data.readInt32();
-            KeyCharacteristics outCharacteristics;
-            int ret = getKeyCharacteristics(name, clientId.get(), appData.get(), uid,
-                                            &outCharacteristics);
-            if (clientId.get() && clientId->data) {
-                free(const_cast<void*>(static_cast<const void*>(clientId->data)));
-            }
-            if (appData.get() && appData->data) {
-                free(const_cast<void*>(static_cast<const void*>(appData->data)));
-            }
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeParcelable(outCharacteristics);
-            return NO_ERROR;
-        }
-        case IMPORT_KEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
-            const uint8_t* keyData = NULL;
-            size_t keyLength = 0;
-            readByteArray(data, &keyData, &keyLength);
-            int32_t uid = data.readInt32();
-            int32_t flags = data.readInt32();
-            KeyCharacteristics outCharacteristics;
-            int32_t ret = importKey(name, args, format, keyData, keyLength, uid, flags,
-                                    &outCharacteristics);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeParcelable(outCharacteristics);
-            return NO_ERROR;
-        }
-        case EXPORT_KEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
-            std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
-            std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
-            int32_t uid = data.readInt32();
-            ExportResult result;
-            exportKey(name, format, clientId.get(), appData.get(), uid, &result);
-            if (clientId.get() && clientId->data) {
-                free(const_cast<void*>(static_cast<const void*>(clientId->data)));
-            }
-            if (appData.get() && appData->data) {
-                free(const_cast<void*>(static_cast<const void*>(appData->data)));
-            }
-            reply->writeNoException();
-            reply->writeParcelable(result);
+        int32_t ret = generate(name, uid, keyType, keySize, flags, &args);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case IMPORT: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto in = readBlobAsByteArray(data);
+        int uid = data.readInt32();
+        int32_t flags = data.readInt32();
+        auto ret = import(name, in.value(), uid, flags);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case SIGN: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto in = readBlobAsByteArray(data);
+        hidl_vec<uint8_t> out;
+        auto ret = sign(name, in.value(), &out);
+        reply->writeNoException();
+        writeBlobAsByteArray(out, reply);
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case VERIFY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto in = readBlobAsByteArray(data);
+        auto signature = readBlobAsByteArray(data);
+        auto ret = verify(name, in.value(), signature.value());
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case GET_PUBKEY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        hidl_vec<uint8_t> out;
+        auto ret = get_pubkey(name, &out);
+        reply->writeNoException();
+        writeBlobAsByteArray(out, reply);
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case GRANT: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int32_t granteeUid = data.readInt32();
+        int32_t ret = grant(name, granteeUid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case UNGRANT: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int32_t granteeUid = data.readInt32();
+        int32_t ret = ungrant(name, granteeUid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case GETMTIME: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        int32_t uid = data.readInt32();
+        int64_t ret = getmtime(name, uid);
+        reply->writeNoException();
+        reply->writeInt64(ret);
+        return NO_ERROR;
+    } break;
+    case DUPLICATE: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 srcKey = data.readString16();
+        int32_t srcUid = data.readInt32();
+        String16 destKey = data.readString16();
+        int32_t destUid = data.readInt32();
+        int32_t ret = duplicate(srcKey, srcUid, destKey, destUid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    } break;
+    case IS_HARDWARE_BACKED: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 keyType = data.readString16();
+        int32_t ret = is_hardware_backed(keyType);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    }
+    case CLEAR_UID: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int64_t uid = data.readInt64();
+        int32_t ret = clear_uid(uid);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    }
+    case ADD_RNG_ENTROPY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        auto entropy = readBlobAsByteArray(data);
+        auto ret = addRngEntropy(entropy.value());
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        return NO_ERROR;
+    }
+    case GENERATE_KEY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto params = nullable(readParamSetFromParcel, data);
+        auto entropy = readBlobAsByteArray(data);
+        int32_t uid = data.readInt32();
+        int32_t flags = data.readInt32();
+        KeyCharacteristics outCharacteristics;
+        int32_t ret =
+            generateKey(name, params.value(), entropy.value(), uid, flags, &outCharacteristics);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply);
+        return NO_ERROR;
+    }
+    case GET_KEY_CHARACTERISTICS: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto clientId = nullable(readKeymasterBlob, data, true);
+        auto appData = nullable(readKeymasterBlob, data, true);
+        int32_t uid = data.readInt32();
+        KeyCharacteristics outCharacteristics;
+        int ret = getKeyCharacteristics(name, clientId.value(), appData.value(), uid,
+                                        &outCharacteristics);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply);
+        return NO_ERROR;
+    }
+    case IMPORT_KEY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto args = nullable(readParamSetFromParcel, data);
+        KeyFormat format = static_cast<KeyFormat>(data.readInt32());
+        auto keyData = readBlobAsByteArray(data);
+        int32_t uid = data.readInt32();
+        int32_t flags = data.readInt32();
+        KeyCharacteristics outCharacteristics;
+        int32_t ret =
+            importKey(name, args.value(), format, keyData.value(), uid, flags, &outCharacteristics);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        nullable(writeKeyCharacteristicsToParcel, outCharacteristics, reply);
+        return NO_ERROR;
+    }
+    case EXPORT_KEY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        KeyFormat format = static_cast<KeyFormat>(data.readInt32());
+        auto clientId = nullable(readKeymasterBlob, data, true);
+        auto appData = nullable(readKeymasterBlob, data, true);
+        int32_t uid = data.readInt32();
+        ExportResult result;
+        exportKey(name, format, clientId.value(), appData.value(), uid, &result);
+        reply->writeNoException();
+        reply->writeParcelable(result);
 
-            return NO_ERROR;
-        }
-        case BEGIN: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            String16 name = data.readString16();
-            keymaster_purpose_t purpose = static_cast<keymaster_purpose_t>(data.readInt32());
-            bool pruneable = data.readInt32() != 0;
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            const uint8_t* entropy = NULL;
-            size_t entropyLength = 0;
-            readByteArray(data, &entropy, &entropyLength);
-            int32_t uid = data.readInt32();
-            OperationResult result;
-            begin(token, name, purpose, pruneable, args, entropy, entropyLength, uid, &result);
-            reply->writeNoException();
-            reply->writeParcelable(result);
+        return NO_ERROR;
+    }
+    case BEGIN: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        sp<IBinder> token = data.readStrongBinder();
+        String16 name = data.readString16();
+        KeyPurpose purpose = static_cast<KeyPurpose>(data.readInt32());
+        bool pruneable = data.readInt32() != 0;
+        auto args = nullable(readParamSetFromParcel, data);
+        auto entropy = readBlobAsByteArray(data);
+        int32_t uid = data.readInt32();
+        OperationResult result;
+        begin(token, name, purpose, pruneable, args.value(), entropy.value(), uid, &result);
+        reply->writeNoException();
+        reply->writeParcelable(result);
 
-            return NO_ERROR;
-        }
-        case UPDATE: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            const uint8_t* buf = NULL;
-            size_t bufLength = 0;
-            readByteArray(data, &buf, &bufLength);
-            OperationResult result;
-            update(token, args, buf, bufLength, &result);
-            reply->writeNoException();
-            reply->writeParcelable(result);
+        return NO_ERROR;
+    }
+    case UPDATE: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        sp<IBinder> token = data.readStrongBinder();
+        auto args = nullable(readParamSetFromParcel, data);
+        auto buf = readBlobAsByteArray(data);
+        OperationResult result;
+        update(token, args.value(), buf.value(), &result);
+        reply->writeNoException();
+        reply->writeParcelable(result);
 
-            return NO_ERROR;
-        }
-        case FINISH: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            const uint8_t* signature = NULL;
-            size_t signatureLength = 0;
-            readByteArray(data, &signature, &signatureLength);
-            const uint8_t* entropy = NULL;
-            size_t entropyLength = 0;
-            readByteArray(data, &entropy, &entropyLength);
-            OperationResult result;
-            finish(token, args, signature, signatureLength, entropy, entropyLength,  &result);
-            reply->writeNoException();
-            reply->writeParcelable(result);
+        return NO_ERROR;
+    }
+    case FINISH: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        sp<IBinder> token = data.readStrongBinder();
+        auto args = nullable(readParamSetFromParcel, data);
+        auto signature = readBlobAsByteArray(data);
+        auto entropy = readBlobAsByteArray(data);
+        OperationResult result;
+        finish(token, args.value(), signature.value(), entropy.value(), &result);
+        reply->writeNoException();
+        reply->writeParcelable(result);
 
-            return NO_ERROR;
-        }
-        case ABORT: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            int32_t result = abort(token);
-            reply->writeNoException();
-            reply->writeInt32(result);
+        return NO_ERROR;
+    }
+    case ABORT: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        sp<IBinder> token = data.readStrongBinder();
+        int32_t result = abort(token);
+        reply->writeNoException();
+        reply->writeInt32(result);
 
-            return NO_ERROR;
-        }
-        case IS_OPERATION_AUTHORIZED: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            bool result = isOperationAuthorized(token);
-            reply->writeNoException();
-            reply->writeInt32(result ? 1 : 0);
+        return NO_ERROR;
+    }
+    case IS_OPERATION_AUTHORIZED: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        sp<IBinder> token = data.readStrongBinder();
+        bool result = isOperationAuthorized(token);
+        reply->writeNoException();
+        reply->writeInt32(result ? 1 : 0);
 
-            return NO_ERROR;
-        }
-        case ADD_AUTH_TOKEN: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            const uint8_t* token_bytes = NULL;
-            size_t size = 0;
-            readByteArray(data, &token_bytes, &size);
-            int32_t result = addAuthToken(token_bytes, size);
-            reply->writeNoException();
-            reply->writeInt32(result);
+        return NO_ERROR;
+    }
+    case ADD_AUTH_TOKEN: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        const uint8_t* token_bytes = NULL;
+        size_t size = 0;
+        readByteArray(data, &token_bytes, &size);
+        int32_t result = addAuthToken(token_bytes, size);
+        reply->writeNoException();
+        reply->writeInt32(result);
 
-            return NO_ERROR;
-        }
-        case ON_USER_ADDED: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            int32_t parentId = data.readInt32();
-            int32_t result = onUserAdded(userId, parentId);
-            reply->writeNoException();
-            reply->writeInt32(result);
+        return NO_ERROR;
+    }
+    case ON_USER_ADDED: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        int32_t parentId = data.readInt32();
+        int32_t result = onUserAdded(userId, parentId);
+        reply->writeNoException();
+        reply->writeInt32(result);
 
-            return NO_ERROR;
-        }
-        case ON_USER_REMOVED: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t userId = data.readInt32();
-            int32_t result = onUserRemoved(userId);
-            reply->writeNoException();
-            reply->writeInt32(result);
+        return NO_ERROR;
+    }
+    case ON_USER_REMOVED: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        int32_t userId = data.readInt32();
+        int32_t result = onUserRemoved(userId);
+        reply->writeNoException();
+        reply->writeInt32(result);
 
-            return NO_ERROR;
-        }
-        case ATTEST_KEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            KeymasterArguments params;
-            if (data.readInt32() != 0) {
-                params.readFromParcel(data);
-            }
-            KeymasterCertificateChain chain;
-            int ret = attestKey(name, params, &chain);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeInt32(1);
-            chain.writeToParcel(reply);
+        return NO_ERROR;
+    }
+    case ATTEST_KEY: {
+        CHECK_INTERFACE(IKeystoreService, data, reply);
+        String16 name = data.readString16();
+        auto params = nullable(readParamSetFromParcel, data);
+        hidl_vec<hidl_vec<uint8_t>> chain;
+        int ret = attestKey(name, params.value(), &chain);
+        reply->writeNoException();
+        reply->writeInt32(ret);
+        nullable(writeCertificateChainToParcel, chain, reply);
 
-            return NO_ERROR;
-        }
-        case ON_DEVICE_OFF_BODY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            int32_t ret = onDeviceOffBody();
-            reply->writeNoException();
-            reply->writeInt32(ret);
+        return NO_ERROR;
+    }
+    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);
+        return NO_ERROR;
+    }
+    default:
+        return BBinder::onTransact(code, data, reply, flags);
     }
 }
 
 // ----------------------------------------------------------------------------
 
-}; // namespace android
+};  // namespace android
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
index f0f4981..3f476cd 100644
--- a/keystore/auth_token_table.cpp
+++ b/keystore/auth_token_table.cpp
@@ -21,10 +21,36 @@
 
 #include <algorithm>
 
-#include <keymaster/android_keymaster_utils.h>
-#include <keymaster/logger.h>
+#include <cutils/log.h>
 
-namespace keymaster {
+namespace keystore {
+
+template <typename IntType, uint32_t byteOrder> struct choose_hton;
+
+template <typename IntType> struct choose_hton<IntType, __ORDER_LITTLE_ENDIAN__> {
+    inline static IntType hton(const IntType& value) {
+        IntType result = 0;
+        const unsigned char* inbytes = reinterpret_cast<const unsigned char*>(&value);
+        unsigned char* outbytes = reinterpret_cast<unsigned char*>(&result);
+        for (int i = sizeof(IntType) - 1; i >= 0; --i) {
+            *(outbytes++) = inbytes[i];
+        }
+        return result;
+    }
+};
+
+template <typename IntType> struct choose_hton<IntType, __ORDER_BIG_ENDIAN__> {
+    inline static IntType hton(const IntType& value) { return value; }
+};
+
+template <typename IntType> inline IntType hton(const IntType& value) {
+    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
+}
+
+template <typename IntType> inline IntType ntoh(const IntType& value) {
+    // same operation and hton
+    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
+}
 
 //
 // Some trivial template wrappers around std algorithms, so they take containers not ranges.
@@ -49,48 +75,43 @@
     return time.tv_sec;
 }
 
-void AuthTokenTable::AddAuthenticationToken(const hw_auth_token_t* auth_token) {
+void AuthTokenTable::AddAuthenticationToken(const HardwareAuthToken* auth_token) {
     Entry new_entry(auth_token, clock_function_());
     RemoveEntriesSupersededBy(new_entry);
     if (entries_.size() >= max_entries_) {
-        LOG_W("Auth token table filled up; replacing oldest entry", 0);
+        ALOGW("Auth token table filled up; replacing oldest entry");
         *min_element(entries_) = std::move(new_entry);
     } else {
         entries_.push_back(std::move(new_entry));
     }
 }
 
-inline bool is_secret_key_operation(keymaster_algorithm_t algorithm, keymaster_purpose_t purpose) {
-    if ((algorithm != KM_ALGORITHM_RSA && algorithm != KM_ALGORITHM_EC))
+inline bool is_secret_key_operation(Algorithm algorithm, KeyPurpose purpose) {
+    if ((algorithm != Algorithm::RSA && algorithm != Algorithm::EC))
         return true;
-    if (purpose == KM_PURPOSE_SIGN || purpose == KM_PURPOSE_DECRYPT)
+    if (purpose == KeyPurpose::SIGN || purpose == KeyPurpose::DECRYPT)
         return true;
     return false;
 }
 
-inline bool KeyRequiresAuthentication(const AuthorizationSet& key_info,
-                                      keymaster_purpose_t purpose) {
-    keymaster_algorithm_t algorithm = KM_ALGORITHM_AES;
-    key_info.GetTagValue(TAG_ALGORITHM, &algorithm);
-    return is_secret_key_operation(algorithm, purpose) && key_info.find(TAG_NO_AUTH_REQUIRED) == -1;
+inline bool KeyRequiresAuthentication(const AuthorizationSet& key_info, KeyPurpose purpose) {
+    auto algorithm = defaultOr(key_info.GetTagValue(TAG_ALGORITHM), Algorithm::AES);
+    return is_secret_key_operation(algorithm, purpose) &&
+           key_info.find(Tag::NO_AUTH_REQUIRED) == -1;
 }
 
-inline bool KeyRequiresAuthPerOperation(const AuthorizationSet& key_info,
-                                        keymaster_purpose_t purpose) {
-    keymaster_algorithm_t algorithm = KM_ALGORITHM_AES;
-    key_info.GetTagValue(TAG_ALGORITHM, &algorithm);
-    return is_secret_key_operation(algorithm, purpose) && key_info.find(TAG_AUTH_TIMEOUT) == -1;
+inline bool KeyRequiresAuthPerOperation(const AuthorizationSet& key_info, KeyPurpose purpose) {
+    auto algorithm = defaultOr(key_info.GetTagValue(TAG_ALGORITHM), Algorithm::AES);
+    return is_secret_key_operation(algorithm, purpose) && key_info.find(Tag::AUTH_TIMEOUT) == -1;
 }
 
 AuthTokenTable::Error AuthTokenTable::FindAuthorization(const AuthorizationSet& key_info,
-                                                        keymaster_purpose_t purpose,
-                                                        keymaster_operation_handle_t op_handle,
-                                                        const hw_auth_token_t** found) {
-    if (!KeyRequiresAuthentication(key_info, purpose))
-        return AUTH_NOT_REQUIRED;
+                                                        KeyPurpose purpose, uint64_t op_handle,
+                                                        const HardwareAuthToken** found) {
+    if (!KeyRequiresAuthentication(key_info, purpose)) return AUTH_NOT_REQUIRED;
 
-    hw_authenticator_type_t auth_type = HW_AUTH_NONE;
-    key_info.GetTagValue(TAG_USER_AUTH_TYPE, &auth_type);
+    auto auth_type =
+        defaultOr(key_info.GetTagValue(TAG_USER_AUTH_TYPE), HardwareAuthenticatorType::NONE);
 
     std::vector<uint64_t> key_sids;
     ExtractSids(key_info, &key_sids);
@@ -101,44 +122,41 @@
         return FindTimedAuthorization(key_sids, auth_type, key_info, found);
 }
 
-AuthTokenTable::Error AuthTokenTable::FindAuthPerOpAuthorization(
-    const std::vector<uint64_t>& sids, hw_authenticator_type_t auth_type,
-    keymaster_operation_handle_t op_handle, const hw_auth_token_t** found) {
-    if (op_handle == 0)
-        return OP_HANDLE_REQUIRED;
+AuthTokenTable::Error
+AuthTokenTable::FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
+                                           HardwareAuthenticatorType auth_type, uint64_t op_handle,
+                                           const HardwareAuthToken** found) {
+    if (op_handle == 0) return OP_HANDLE_REQUIRED;
 
     auto matching_op = find_if(
         entries_, [&](Entry& e) { return e.token()->challenge == op_handle && !e.completed(); });
 
-    if (matching_op == entries_.end())
-        return AUTH_TOKEN_NOT_FOUND;
+    if (matching_op == entries_.end()) return AUTH_TOKEN_NOT_FOUND;
 
-    if (!matching_op->SatisfiesAuth(sids, auth_type))
-        return AUTH_TOKEN_WRONG_SID;
+    if (!matching_op->SatisfiesAuth(sids, auth_type)) return AUTH_TOKEN_WRONG_SID;
 
     *found = matching_op->token();
     return OK;
 }
 
 AuthTokenTable::Error AuthTokenTable::FindTimedAuthorization(const std::vector<uint64_t>& sids,
-                                                             hw_authenticator_type_t auth_type,
+                                                             HardwareAuthenticatorType auth_type,
                                                              const AuthorizationSet& key_info,
-                                                             const hw_auth_token_t** found) {
+                                                             const HardwareAuthToken** found) {
     Entry* newest_match = NULL;
     for (auto& entry : entries_)
         if (entry.SatisfiesAuth(sids, auth_type) && entry.is_newer_than(newest_match))
             newest_match = &entry;
 
-    if (!newest_match)
-        return AUTH_TOKEN_NOT_FOUND;
+    if (!newest_match) return AUTH_TOKEN_NOT_FOUND;
 
-    uint32_t timeout;
-    key_info.GetTagValue(TAG_AUTH_TIMEOUT, &timeout);
+    auto timeout = defaultOr(key_info.GetTagValue(TAG_AUTH_TIMEOUT), 0);
+
     time_t now = clock_function_();
     if (static_cast<int64_t>(newest_match->time_received()) + timeout < static_cast<int64_t>(now))
         return AUTH_TOKEN_EXPIRED;
 
-    if (key_info.GetTagValue(TAG_ALLOW_WHILE_ON_BODY)) {
+    if (key_info.GetTagValue(TAG_ALLOW_WHILE_ON_BODY).isOk()) {
         if (static_cast<int64_t>(newest_match->time_received()) <
             static_cast<int64_t>(last_off_body_)) {
             return AUTH_TOKEN_EXPIRED;
@@ -153,8 +171,8 @@
 void AuthTokenTable::ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids) {
     assert(sids);
     for (auto& param : key_info)
-        if (param.tag == TAG_USER_SECURE_ID)
-            sids->push_back(param.long_integer);
+        if (param.tag == Tag::USER_SECURE_ID)
+            sids->push_back(authorizationValue(TAG_USER_SECURE_ID, param).value());
 }
 
 void AuthTokenTable::RemoveEntriesSupersededBy(const Entry& entry) {
@@ -175,38 +193,35 @@
                        [&](Entry& e) { return e.Supersedes(entry); });
 }
 
-void AuthTokenTable::MarkCompleted(const keymaster_operation_handle_t op_handle) {
+void AuthTokenTable::MarkCompleted(const uint64_t op_handle) {
     auto found = find_if(entries_, [&](Entry& e) { return e.token()->challenge == op_handle; });
-    if (found == entries_.end())
-        return;
+    if (found == entries_.end()) return;
 
     assert(!IsSupersededBySomeEntry(*found));
     found->mark_completed();
 
-    if (IsSupersededBySomeEntry(*found))
-        entries_.erase(found);
+    if (IsSupersededBySomeEntry(*found)) entries_.erase(found);
 }
 
-AuthTokenTable::Entry::Entry(const hw_auth_token_t* token, time_t current_time)
+AuthTokenTable::Entry::Entry(const HardwareAuthToken* token, time_t current_time)
     : token_(token), time_received_(current_time), last_use_(current_time),
-      operation_completed_(token_->challenge == 0) {
-}
+      operation_completed_(token_->challenge == 0) {}
 
 uint32_t AuthTokenTable::Entry::timestamp_host_order() const {
     return ntoh(token_->timestamp);
 }
 
-hw_authenticator_type_t AuthTokenTable::Entry::authenticator_type() const {
-    hw_authenticator_type_t result = static_cast<hw_authenticator_type_t>(
-        ntoh(static_cast<uint32_t>(token_->authenticator_type)));
+HardwareAuthenticatorType AuthTokenTable::Entry::authenticator_type() const {
+    HardwareAuthenticatorType result = static_cast<HardwareAuthenticatorType>(
+        ntoh(static_cast<uint32_t>(token_->authenticatorType)));
     return result;
 }
 
 bool AuthTokenTable::Entry::SatisfiesAuth(const std::vector<uint64_t>& sids,
-                                          hw_authenticator_type_t auth_type) {
+                                          HardwareAuthenticatorType auth_type) {
     for (auto sid : sids)
-        if ((sid == token_->authenticator_id) ||
-            (sid == token_->user_id && (auth_type & authenticator_type()) != 0))
+        if ((sid == token_->authenticatorId) ||
+            (sid == token_->userId && (auth_type & authenticator_type()) != 0))
             return true;
     return false;
 }
@@ -216,12 +231,11 @@
 }
 
 bool AuthTokenTable::Entry::Supersedes(const Entry& entry) const {
-    if (!entry.completed())
-        return false;
+    if (!entry.completed()) return false;
 
-    return (token_->user_id == entry.token_->user_id &&
-            token_->authenticator_type == entry.token_->authenticator_type &&
-            token_->authenticator_type == entry.token_->authenticator_type &&
+    return (token_->userId == entry.token_->userId &&
+            token_->authenticatorType == entry.token_->authenticatorType &&
+            token_->authenticatorType == entry.token_->authenticatorType &&
             timestamp_host_order() > entry.timestamp_host_order());
 }
 
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index 4d54a39..6f7aab1 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -18,12 +18,14 @@
 #include <vector>
 
 #include <hardware/hw_auth_token.h>
-#include <keymaster/authorization_set.h>
+#include <keystore/authorization_set.h>
 
 #ifndef KEYSTORE_AUTH_TOKEN_TABLE_H_
 #define KEYSTORE_AUTH_TOKEN_TABLE_H_
 
-namespace keymaster {
+namespace keystore {
+
+using android::hardware::keymaster::V3_0::HardwareAuthToken;
 
 namespace test {
 class AuthTokenTableTest;
@@ -42,7 +44,8 @@
 class AuthTokenTable {
   public:
     explicit AuthTokenTable(size_t max_entries = 32, time_t (*clock_function)() = clock_gettime_raw)
-        : max_entries_(max_entries), last_off_body_(clock_function()), clock_function_(clock_function) {}
+        : max_entries_(max_entries), last_off_body_(clock_function()),
+          clock_function_(clock_function) {}
 
     enum Error {
         OK,
@@ -58,7 +61,7 @@
     /**
      * Add an authorization token to the table.  The table takes ownership of the argument.
      */
-    void AddAuthenticationToken(const hw_auth_token_t* token);
+    void AddAuthenticationToken(const HardwareAuthToken* token);
 
     /**
      * Find an authorization token that authorizes the operation specified by \p operation_handle on
@@ -70,30 +73,14 @@
      *
      * The table retains ownership of the returned object.
      */
-    Error FindAuthorization(const AuthorizationSet& key_info, keymaster_purpose_t purpose,
-                            keymaster_operation_handle_t op_handle, const hw_auth_token_t** found);
-
-    /**
-     * Find an authorization token that authorizes the operation specified by \p operation_handle on
-     * a key with the characteristics specified in \p key_info.
-     *
-     * This method is O(n * m), where n is the number of KM_TAG_USER_SECURE_ID entries in key_info
-     * and m is the number of entries in the table.  It could be made better, but n and m should
-     * always be small.
-     *
-     * The table retains ownership of the returned object.
-     */
-    Error FindAuthorization(const keymaster_key_param_t* params, size_t params_count,
-                            keymaster_purpose_t purpose, keymaster_operation_handle_t op_handle,
-                            const hw_auth_token_t** found) {
-        return FindAuthorization(AuthorizationSet(params, params_count), purpose, op_handle, found);
-    }
+    Error FindAuthorization(const AuthorizationSet& key_info, KeyPurpose purpose,
+                            uint64_t op_handle, const HardwareAuthToken** found);
 
     /**
      * Mark operation completed.  This allows tokens associated with the specified operation to be
      * superseded by new tokens.
      */
-    void MarkCompleted(const keymaster_operation_handle_t op_handle);
+    void MarkCompleted(const uint64_t op_handle);
 
     /**
      * Update the last_off_body_ timestamp so that tokens which remain authorized only so long as
@@ -110,7 +97,7 @@
 
     class Entry {
       public:
-        Entry(const hw_auth_token_t* token, time_t current_time);
+        Entry(const HardwareAuthToken* token, time_t current_time);
         Entry(Entry&& entry) { *this = std::move(entry); }
 
         void operator=(Entry&& rhs) {
@@ -125,36 +112,34 @@
         void UpdateLastUse(time_t time);
 
         bool Supersedes(const Entry& entry) const;
-        bool SatisfiesAuth(const std::vector<uint64_t>& sids, hw_authenticator_type_t auth_type);
+        bool SatisfiesAuth(const std::vector<uint64_t>& sids, HardwareAuthenticatorType auth_type);
 
         bool is_newer_than(const Entry* entry) {
-            if (!entry)
-                return true;
+            if (!entry) return true;
             return timestamp_host_order() > entry->timestamp_host_order();
         }
 
         void mark_completed() { operation_completed_ = true; }
 
-        const hw_auth_token_t* token() { return token_.get(); }
+        const HardwareAuthToken* token() { return token_.get(); }
         time_t time_received() const { return time_received_; }
         bool completed() const { return operation_completed_; }
         uint32_t timestamp_host_order() const;
-        hw_authenticator_type_t authenticator_type() const;
+        HardwareAuthenticatorType authenticator_type() const;
 
       private:
-        std::unique_ptr<const hw_auth_token_t> token_;
+        std::unique_ptr<const HardwareAuthToken> token_;
         time_t time_received_;
         time_t last_use_;
         bool operation_completed_;
     };
 
     Error FindAuthPerOpAuthorization(const std::vector<uint64_t>& sids,
-                                     hw_authenticator_type_t auth_type,
-                                     keymaster_operation_handle_t op_handle,
-                                     const hw_auth_token_t** found);
+                                     HardwareAuthenticatorType auth_type, uint64_t op_handle,
+                                     const HardwareAuthToken** found);
     Error FindTimedAuthorization(const std::vector<uint64_t>& sids,
-                                 hw_authenticator_type_t auth_type,
-                                 const AuthorizationSet& key_info, const hw_auth_token_t** found);
+                                 HardwareAuthenticatorType auth_type,
+                                 const AuthorizationSet& key_info, const HardwareAuthToken** found);
     void ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids);
     void RemoveEntriesSupersededBy(const Entry& entry);
     bool IsSupersededBySomeEntry(const Entry& entry);
diff --git a/keystore/authorization_set.cpp b/keystore/authorization_set.cpp
new file mode 100644
index 0000000..e30b32d
--- /dev/null
+++ b/keystore/authorization_set.cpp
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <keystore/authorization_set.h>
+
+#include <assert.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits>
+#include <ostream>
+#include <istream>
+
+#include <new>
+
+namespace keystore {
+
+inline bool keyParamLess(const KeyParameter& a, const KeyParameter& b) {
+    if (a.tag != b.tag) return a.tag < b.tag;
+    int retval;
+    switch (typeFromTag(a.tag)) {
+    case TagType::INVALID:
+    case TagType::BOOL:
+        return false;
+    case TagType::ENUM:
+    case TagType::ENUM_REP:
+    case TagType::UINT:
+    case TagType::UINT_REP:
+        return a.f.integer < b.f.integer;
+    case TagType::ULONG:
+    case TagType::ULONG_REP:
+        return a.f.longInteger < b.f.longInteger;
+    case TagType::DATE:
+        return a.f.dateTime < b.f.dateTime;
+    case TagType::BIGNUM:
+    case TagType::BYTES:
+        // Handle the empty cases.
+        if (a.blob.size() == 0)
+            return b.blob.size() != 0;
+        if (b.blob.size() == 0) return false;
+
+        retval = memcmp(&a.blob[0], &b.blob[0], std::min(a.blob.size(), b.blob.size()));
+        // if one is the prefix of the other the longer wins
+        if (retval == 0) return a.blob.size() < b.blob.size();
+        // Otherwise a is less if a is less.
+        else return retval < 0;
+    }
+    return false;
+}
+
+inline bool keyParamEqual(const KeyParameter& a, const KeyParameter& b) {
+    if (a.tag != b.tag) return false;
+
+    switch (typeFromTag(a.tag)) {
+    case TagType::INVALID:
+    case TagType::BOOL:
+        return true;
+    case TagType::ENUM:
+    case TagType::ENUM_REP:
+    case TagType::UINT:
+    case TagType::UINT_REP:
+        return a.f.integer == b.f.integer;
+    case TagType::ULONG:
+    case TagType::ULONG_REP:
+        return a.f.longInteger == b.f.longInteger;
+    case TagType::DATE:
+        return a.f.dateTime == b.f.dateTime;
+    case TagType::BIGNUM:
+    case TagType::BYTES:
+        if (a.blob.size() != b.blob.size()) return false;
+        return a.blob.size() == 0 ||
+                memcmp(&a.blob[0], &b.blob[0], a.blob.size()) == 0;
+    }
+    return false;
+}
+
+void AuthorizationSet::Sort() {
+    std::sort(data_.begin(), data_.end(), keyParamLess);
+}
+
+void AuthorizationSet::Deduplicate() {
+    if (data_.empty()) return;
+
+    Sort();
+    std::vector<KeyParameter> result;
+
+    auto curr = data_.begin();
+    auto prev = curr++;
+    for (; curr != data_.end(); ++prev, ++curr) {
+        if (prev->tag == Tag::INVALID) continue;
+
+        if (!keyParamEqual(*prev, *curr)) {
+            result.emplace_back(std::move(*prev));
+        }
+    }
+    result.emplace_back(std::move(*prev));
+
+    std::swap(data_, result);
+}
+
+void AuthorizationSet::Union(const AuthorizationSet& other) {
+    data_.insert(data_.end(), other.data_.begin(), other.data_.end());
+    Deduplicate();
+}
+
+void AuthorizationSet::Subtract(const AuthorizationSet& other) {
+    Deduplicate();
+
+    auto i = other.begin();
+    while (i != other.end()) {
+        int pos = -1;
+        do {
+            pos = find(i->tag, pos);
+            if (pos != -1 && keyParamEqual(*i, data_[pos])) {
+                data_.erase(data_.begin() + pos);
+                break;
+            }
+        } while (pos != -1);
+        ++i;
+    }
+}
+
+int AuthorizationSet::find(Tag tag, int begin) const {
+    auto iter = data_.begin() + (1 + begin);
+
+    while (iter != data_.end() && iter->tag != tag) ++iter;
+
+    if (iter != data_.end()) return iter - data_.begin();
+    return -1;
+}
+
+bool AuthorizationSet::erase(int index) {
+    auto pos = data_.begin() + index;
+    if (pos != data_.end()) {
+        data_.erase(pos);
+        return true;
+    }
+    return false;
+}
+
+KeyParameter& AuthorizationSet::operator[](int at) {
+    return data_[at];
+}
+
+const KeyParameter& AuthorizationSet::operator[](int at) const {
+    return data_[at];
+}
+
+void AuthorizationSet::Clear() {
+    data_.clear();
+}
+
+size_t AuthorizationSet::GetTagCount(Tag tag) const {
+    size_t count = 0;
+    for (int pos = -1; (pos = find(tag, pos)) != -1;)
+        ++count;
+    return count;
+}
+
+NullOr<const KeyParameter&> AuthorizationSet::GetEntry(Tag tag) const {
+    int pos = find(tag);
+    if (pos == -1) return {};
+    return data_[pos];
+}
+
+/**
+ * Persistent format is:
+ * | 32 bit indirect_size         |
+ * --------------------------------
+ * | indirect_size bytes of data  | this is where the blob data is stored
+ * --------------------------------
+ * | 32 bit element_count         | number of entries
+ * | 32 bit elements_size         | total bytes used by entries (entries have variable length)
+ * --------------------------------
+ * | elementes_size bytes of data | where the elements are stored
+ */
+
+/**
+ * Persistent format of blobs and bignums:
+ * | 32 bit tag             |
+ * | 32 bit blob_length     |
+ * | 32 bit indirect_offset |
+ */
+
+struct OutStreams {
+    std::ostream& indirect;
+    std::ostream& elements;
+};
+
+OutStreams& serializeParamValue(OutStreams& out, const hidl_vec<uint8_t>& blob) {
+    uint32_t buffer;
+
+    // write blob_length
+    auto blob_length = blob.size();
+    if (blob_length > std::numeric_limits<uint32_t>::max()) {
+        out.elements.setstate(std::ios_base::badbit);
+        return out;
+    }
+    buffer = blob_length;
+    out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
+
+    // write indirect_offset
+    auto offset = out.indirect.tellp();
+    if (offset < 0 || offset > std::numeric_limits<uint32_t>::max() ||
+            uint32_t(offset) + uint32_t(blob_length) < uint32_t(offset)) { // overflow check
+        out.elements.setstate(std::ios_base::badbit);
+        return out;
+    }
+    buffer = offset;
+    out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
+
+    // write blob to indirect stream
+    if(blob_length)
+        out.indirect.write(reinterpret_cast<const char*>(&blob[0]), blob_length);
+
+    return out;
+}
+
+template <typename T>
+OutStreams& serializeParamValue(OutStreams& out, const T& value) {
+    out.elements.write(reinterpret_cast<const char*>(&value), sizeof(T));
+    return out;
+}
+
+OutStreams& serialize(TAG_INVALID_t&&, OutStreams& out, const KeyParameter&) {
+    // skip invalid entries.
+    return out;
+}
+template <typename T>
+OutStreams& serialize(T ttag, OutStreams& out, const KeyParameter& param) {
+    out.elements.write(reinterpret_cast<const char*>(&param.tag), sizeof(int32_t));
+    return serializeParamValue(out, accessTagValue(ttag, param));
+}
+
+template <typename... T>
+struct choose_serializer;
+template <typename... Tags>
+struct choose_serializer<MetaList<Tags...>> {
+    static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
+        return choose_serializer<Tags...>::serialize(out, param);
+    }
+};
+template <>
+struct choose_serializer<> {
+    static OutStreams& serialize(OutStreams& out, const KeyParameter&) {
+        return out;
+    }
+};
+template <TagType tag_type, Tag tag, typename... Tail>
+struct choose_serializer<TypedTag<tag_type, tag>, Tail...> {
+    static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
+        if (param.tag == tag) {
+            return keystore::serialize(TypedTag<tag_type, tag>(), out, param);
+        } else {
+            return choose_serializer<Tail...>::serialize(out, param);
+        }
+    }
+};
+
+OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
+    return choose_serializer<all_tags_t>::serialize(out, param);
+}
+
+std::ostream& serialize(std::ostream& out, const std::vector<KeyParameter>& params) {
+    std::stringstream indirect;
+    std::stringstream elements;
+    OutStreams streams = { indirect, elements };
+    for (const auto& param: params) {
+        serialize(streams, param);
+    }
+    if (indirect.bad() || elements.bad()) {
+        out.setstate(std::ios_base::badbit);
+        return out;
+    }
+    auto pos = indirect.tellp();
+    if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
+        out.setstate(std::ios_base::badbit);
+        return out;
+    }
+    uint32_t indirect_size = pos;
+    pos = elements.tellp();
+    if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
+        out.setstate(std::ios_base::badbit);
+        return out;
+    }
+    uint32_t elements_size = pos;
+    uint32_t element_count = params.size();
+
+    out.write(reinterpret_cast<const char*>(&indirect_size), sizeof(uint32_t));
+
+    pos = out.tellp();
+    if (indirect_size)
+        out << indirect.rdbuf();
+    assert(out.tellp() - pos == indirect_size);
+
+    out.write(reinterpret_cast<const char*>(&element_count), sizeof(uint32_t));
+    out.write(reinterpret_cast<const char*>(&elements_size), sizeof(uint32_t));
+
+    pos = out.tellp();
+    if (elements_size)
+        out << elements.rdbuf();
+    assert(out.tellp() - pos == elements_size);
+
+    return out;
+}
+
+struct InStreams {
+    std::istream& indirect;
+    std::istream& elements;
+};
+
+InStreams& deserializeParamValue(InStreams& in, hidl_vec<uint8_t>* blob) {
+    uint32_t blob_length = 0;
+    uint32_t offset = 0;
+    in.elements.read(reinterpret_cast<char*>(&blob_length), sizeof(uint32_t));
+    blob->resize(blob_length);
+    in.elements.read(reinterpret_cast<char*>(&offset), sizeof(uint32_t));
+    in.indirect.seekg(offset);
+    in.indirect.read(reinterpret_cast<char*>(&(*blob)[0]), blob->size());
+    return in;
+}
+
+template <typename T>
+InStreams& deserializeParamValue(InStreams& in, T* value) {
+    in.elements.read(reinterpret_cast<char*>(value), sizeof(T));
+    return in;
+}
+
+InStreams& deserialize(TAG_INVALID_t&&, InStreams& in, KeyParameter*) {
+    // there should be no invalid KeyParamaters but if handle them as zero sized.
+    return in;
+}
+
+template <typename T>
+InStreams& deserialize(T&& ttag, InStreams& in, KeyParameter* param) {
+    return deserializeParamValue(in, &accessTagValue(ttag, *param));
+}
+
+template <typename... T>
+struct choose_deserializer;
+template <typename... Tags>
+struct choose_deserializer<MetaList<Tags...>> {
+    static InStreams& deserialize(InStreams& in, KeyParameter* param) {
+        return choose_deserializer<Tags...>::deserialize(in, param);
+    }
+};
+template <>
+struct choose_deserializer<> {
+    static InStreams& deserialize(InStreams& in, KeyParameter*) {
+        // encountered an unknown tag -> fail parsing
+        in.elements.setstate(std::ios_base::badbit);
+        return in;
+    }
+};
+template <TagType tag_type, Tag tag, typename... Tail>
+struct choose_deserializer<TypedTag<tag_type, tag>, Tail...> {
+    static InStreams& deserialize(InStreams& in, KeyParameter* param) {
+        if (param->tag == tag) {
+            return keystore::deserialize(TypedTag<tag_type, tag>(), in, param);
+        } else {
+            return choose_deserializer<Tail...>::deserialize(in, param);
+        }
+    }
+};
+
+InStreams& deserialize(InStreams& in, KeyParameter* param) {
+    in.elements.read(reinterpret_cast<char*>(&param->tag), sizeof(Tag));
+    return choose_deserializer<all_tags_t>::deserialize(in, param);
+}
+
+std::istream& deserialize(std::istream& in, std::vector<KeyParameter>* params) {
+    uint32_t indirect_size = 0;
+    in.read(reinterpret_cast<char*>(&indirect_size), sizeof(uint32_t));
+    std::string indirect_buffer(indirect_size, '\0');
+    if (indirect_buffer.size() != indirect_size) {
+        in.setstate(std::ios_base::badbit);
+        return in;
+    }
+    in.read(&indirect_buffer[0], indirect_buffer.size());
+
+    uint32_t element_count = 0;
+    in.read(reinterpret_cast<char*>(&element_count), sizeof(uint32_t));
+    uint32_t elements_size = 0;
+    in.read(reinterpret_cast<char*>(&elements_size), sizeof(uint32_t));
+
+    std::string elements_buffer(elements_size, '\0');
+    if(elements_buffer.size() != elements_size) {
+        in.setstate(std::ios_base::badbit);
+        return in;
+    }
+    in.read(&elements_buffer[0], elements_buffer.size());
+
+    if (in.bad()) return in;
+
+    // TODO write one-shot stream buffer to avoid copying here
+    std::stringstream indirect(indirect_buffer);
+    std::stringstream elements(elements_buffer);
+    InStreams streams = { indirect, elements };
+
+    params->resize(element_count);
+
+    for (uint32_t i = 0; i < element_count; ++i) {
+        deserialize(streams, &(*params)[i]);
+    }
+    return in;
+}
+void AuthorizationSet::Serialize(std::ostream* out) const {
+    serialize(*out, data_);
+}
+void AuthorizationSet::Deserialize(std::istream* in) {
+    deserialize(*in, &data_);
+}
+
+}  // namespace keystore
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
index 8b08f07..7ee26f7 100644
--- a/keystore/blob.cpp
+++ b/keystore/blob.cpp
@@ -93,12 +93,12 @@
     if (isEncrypted()) {
         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;
         }
     }
 
@@ -132,60 +132,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;
+        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 (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 +194,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 +203,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/defaults.h b/keystore/defaults.h
index 9232dd0..6f7ff2d 100644
--- a/keystore/defaults.h
+++ b/keystore/defaults.h
@@ -24,19 +24,19 @@
  */
 
 /* DSA */
-#define DSA_DEFAULT_KEY_SIZE 1024
-#define DSA_MIN_KEY_SIZE 512
-#define DSA_MAX_KEY_SIZE 8192
+constexpr int32_t DSA_DEFAULT_KEY_SIZE = 1024;
+constexpr int32_t DSA_MIN_KEY_SIZE = 512;
+constexpr int32_t DSA_MAX_KEY_SIZE = 8192;
 
 /* EC */
-#define EC_DEFAULT_KEY_SIZE 256
-#define EC_MIN_KEY_SIZE 192
-#define EC_MAX_KEY_SIZE 521
+constexpr int32_t EC_DEFAULT_KEY_SIZE = 256;
+constexpr int32_t EC_MIN_KEY_SIZE = 192;
+constexpr int32_t EC_MAX_KEY_SIZE = 521;
 
 /* RSA */
-#define RSA_DEFAULT_KEY_SIZE 2048
-#define RSA_DEFAULT_EXPONENT 0x10001
-#define RSA_MIN_KEY_SIZE 512
-#define RSA_MAX_KEY_SIZE 8192
+constexpr int32_t RSA_DEFAULT_KEY_SIZE = 2048;
+constexpr int32_t RSA_DEFAULT_EXPONENT = 0x10001;
+constexpr int32_t RSA_MIN_KEY_SIZE = 512;
+constexpr int32_t RSA_MAX_KEY_SIZE = 8192;
 
 #endif /* KEYSTORE_DEFAULTS_H_ */
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
index 1a2f554..5d88564 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -17,23 +17,25 @@
 #ifndef KEYSTORE_IKEYSTORESERVICE_H
 #define KEYSTORE_IKEYSTORESERVICE_H
 
-#include <hardware/keymaster_defs.h>
-#include <utils/RefBase.h>
+#include "keystore.h"
+#include "keystore_return_types.h"
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
+#include <keystore/keymaster_tags.h>
+#include <utils/RefBase.h>
 #include <vector>
 
 namespace android {
 
 class KeystoreArg : public RefBase {
-public:
-    KeystoreArg(const void *data, size_t len);
+  public:
+    KeystoreArg(const void* data, size_t len);
     ~KeystoreArg();
 
     const void* data() const;
     size_t size() const;
 
-private:
+  private:
     const void* mData;
     size_t mSize;
 };
@@ -42,16 +44,6 @@
     void operator()(uint8_t* p) { free(p); }
 };
 
-// struct for serializing/deserializing a list of keymaster_key_param_t's
-struct KeymasterArguments {
-    KeymasterArguments();
-    ~KeymasterArguments();
-    void readFromParcel(const Parcel& in);
-    void writeToParcel(Parcel* out) const;
-
-    std::vector<keymaster_key_param_t> params;
-};
-
 // struct for serializing the results of begin/update/finish
 struct OperationResult : public ::android::Parcelable {
     OperationResult();
@@ -59,13 +51,12 @@
     status_t readFromParcel(const Parcel* in) override;
     status_t writeToParcel(Parcel* out) const override;
 
-    int resultCode;
+    ::keystore::KeyStoreServiceReturnCode resultCode;
     sp<IBinder> token;
-    keymaster_operation_handle_t handle;
+    uint64_t handle;
     int inputConsumed;
-    std::unique_ptr<uint8_t[], MallocDeleter> data;
-    size_t dataLength;
-    KeymasterArguments outParams;
+    ::keystore::hidl_vec<uint8_t> data;
+    ::keystore::hidl_vec<::keystore::KeyParameter> outParams;
 };
 
 // struct for serializing the results of export
@@ -75,41 +66,15 @@
     status_t readFromParcel(const Parcel* in) override;
     status_t writeToParcel(Parcel* out) const override;
 
-    int resultCode;
-    std::unique_ptr<uint8_t[], MallocDeleter> exportData;
-    size_t dataLength;
+    ::keystore::KeyStoreServiceReturnCode resultCode;
+    ::keystore::hidl_vec<uint8_t> exportData;
 };
 
-// struct for serializing keymaster_key_characteristics_t's
-struct KeyCharacteristics : public ::android::Parcelable {
-    KeyCharacteristics();
-    ~KeyCharacteristics();
-    status_t readFromParcel(const Parcel* in) override;
-    status_t writeToParcel(Parcel* out) const override;
-
-    keymaster_key_characteristics_t characteristics;
-};
-
-// struct for serializing keymaster_cert_chain_t's
-struct KeymasterCertificateChain {
-    KeymasterCertificateChain();
-    ~KeymasterCertificateChain();
-    void readFromParcel(const Parcel& in);
-    void writeToParcel(Parcel* out) const;
-
-    void FreeChain();
-
-    keymaster_cert_chain_t chain;
-};
-
-bool readKeymasterArgumentFromParcel(const Parcel& in, keymaster_key_param_t* out);
-void writeKeymasterArgumentToParcel(const keymaster_key_param_t& param, Parcel* out);
-
 /*
  * This must be kept manually in sync with frameworks/base's IKeystoreService.java
  */
-class IKeystoreService: public IInterface {
-public:
+class IKeystoreService : public IInterface {
+  public:
     enum {
         GET_STATE = IBinder::FIRST_CALL_TRANSACTION + 0,
         GET = IBinder::FIRST_CALL_TRANSACTION + 1,
@@ -152,114 +117,134 @@
 
     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 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/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..b347dbf
--- /dev/null
+++ b/keystore/include/keystore/keymaster_tags.h
@@ -0,0 +1,352 @@
+/*
+ * 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;
+using ::android::hardware::Status;
+
+// 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..6f13820 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
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..e858021
--- /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, result.begin());
+    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/key_store_service.cpp b/keystore/key_store_service.cpp
index 5b15e4b..d4032c1 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -28,18 +28,16 @@
 
 #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 android {
+namespace keystore {
+using namespace android;
 
 const size_t MAX_OPERATIONS = 15;
 
@@ -48,10 +46,6 @@
 };
 typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
 
-struct Malloc_Delete {
-    void operator()(uint8_t* p) const { free(p); }
-};
-
 void KeyStoreService::binderDied(const wp<IBinder>& who) {
     auto operations = mOperationMap.getOperationsForToken(who.unsafe_get());
     for (const auto& token : operations) {
@@ -59,116 +53,124 @@
     }
 }
 
-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->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
-    int32_t result = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
-    if (result != ::NO_ERROR) {
+    ResponseCode result = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
+    if (result != ResponseCode::NO_ERROR) {
         return result;
     }
 
     // Also delete any characteristics files
-    String8 chrFilename(mKeyStore->getKeyNameForUidWithDir(
-        name8, targetUid, ::TYPE_KEY_CHARACTERISTICS));
+    String8 chrFilename(
+        mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_KEY_CHARACTERISTICS));
     return mKeyStore->del(chrFilename.string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid));
 }
 
-int32_t KeyStoreService::exist(const String16& name, int targetUid) {
+KeyStoreServiceReturnCode KeyStoreService::exist(const String16& name, int targetUid) {
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_EXIST, targetUid)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     String8 name8(name);
     String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
 
     if (access(filename.string(), R_OK) == -1) {
-        return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
+        return (errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::KEY_NOT_FOUND;
     }
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::list(const String16& prefix, int targetUid, Vector<String16>* matches) {
+KeyStoreServiceReturnCode KeyStoreService::list(const String16& prefix, int targetUid,
+                                                Vector<String16>* matches) {
     targetUid = getEffectiveUid(targetUid);
     if (!checkBinderPermission(P_LIST, targetUid)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
     const String8 prefix8(prefix);
     String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid, TYPE_ANY));
 
-    if (mKeyStore->list(filename, matches, get_user_id(targetUid)) != ::NO_ERROR) {
-        return ::SYSTEM_ERROR;
+    if (mKeyStore->list(filename, matches, get_user_id(targetUid)) != ResponseCode::NO_ERROR) {
+        return ResponseCode::SYSTEM_ERROR;
     }
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::reset() {
+KeyStoreServiceReturnCode KeyStoreService::reset() {
     if (!checkBinderPermission(P_RESET)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     mKeyStore->resetUser(get_user_id(callingUid), false);
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::onUserPasswordChanged(int32_t userId, const String16& password) {
+KeyStoreServiceReturnCode KeyStoreService::onUserPasswordChanged(int32_t userId,
+                                                                 const String16& password) {
     if (!checkBinderPermission(P_PASSWORD)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
 
     const String8 password8(password);
@@ -179,7 +181,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: {
@@ -197,13 +199,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.
@@ -219,37 +221,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);
@@ -265,7 +267,7 @@
             ALOGE("unlock called on keystore in unknown state: %d", state);
             break;
         }
-        return state;
+        return ResponseCode(state);
     }
 
     const String8 password8(pw);
@@ -281,43 +283,44 @@
     return mKeyStore->isEmpty(userId);
 }
 
-int32_t KeyStoreService::generate(const String16& name, int32_t targetUid, int32_t keyType,
-                                  int32_t keySize, int32_t flags, Vector<sp<KeystoreArg>>* args) {
+KeyStoreServiceReturnCode KeyStoreService::generate(const String16& name, int32_t targetUid,
+                                                    int32_t keyType, int32_t keySize, int32_t flags,
+                                                    Vector<sp<KeystoreArg>>* args) {
     targetUid = getEffectiveUid(targetUid);
-    int32_t result =
+    auto result =
         checkBinderPermissionAndKeystoreState(P_INSERT, targetUid, flags & KEYSTORE_FLAG_ENCRYPTED);
-    if (result != ::NO_ERROR) {
+    if (!result.isOk()) {
         return result;
     }
 
-    KeymasterArguments params;
-    add_legacy_key_authorizations(keyType, &params.params);
+    keystore::AuthorizationSet params;
+    add_legacy_key_authorizations(keyType, &params);
 
     switch (keyType) {
     case EVP_PKEY_EC: {
-        params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_EC));
+        params.push_back(TAG_ALGORITHM, Algorithm::EC);
         if (keySize == -1) {
             keySize = EC_DEFAULT_KEY_SIZE;
         } else if (keySize < EC_MIN_KEY_SIZE || keySize > EC_MAX_KEY_SIZE) {
             ALOGI("invalid key size %d", keySize);
-            return ::SYSTEM_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        params.params.push_back(keymaster_param_int(KM_TAG_KEY_SIZE, keySize));
+        params.push_back(TAG_KEY_SIZE, keySize);
         break;
     }
     case EVP_PKEY_RSA: {
-        params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_RSA));
+        params.push_back(TAG_ALGORITHM, Algorithm::RSA);
         if (keySize == -1) {
             keySize = RSA_DEFAULT_KEY_SIZE;
         } else if (keySize < RSA_MIN_KEY_SIZE || keySize > RSA_MAX_KEY_SIZE) {
             ALOGI("invalid key size %d", keySize);
-            return ::SYSTEM_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         }
-        params.params.push_back(keymaster_param_int(KM_TAG_KEY_SIZE, keySize));
+        params.push_back(TAG_KEY_SIZE, keySize);
         unsigned long exponent = RSA_DEFAULT_EXPONENT;
         if (args->size() > 1) {
             ALOGI("invalid number of arguments: %zu", args->size());
-            return ::SYSTEM_ERROR;
+            return ResponseCode::SYSTEM_ERROR;
         } else if (args->size() == 1) {
             const sp<KeystoreArg>& expArg = args->itemAt(0);
             if (expArg != NULL) {
@@ -325,84 +328,88 @@
                     reinterpret_cast<const unsigned char*>(expArg->data()), expArg->size(), NULL));
                 if (pubExpBn.get() == NULL) {
                     ALOGI("Could not convert public exponent to BN");
-                    return ::SYSTEM_ERROR;
+                    return ResponseCode::SYSTEM_ERROR;
                 }
                 exponent = BN_get_word(pubExpBn.get());
                 if (exponent == 0xFFFFFFFFL) {
                     ALOGW("cannot represent public exponent as a long value");
-                    return ::SYSTEM_ERROR;
+                    return ResponseCode::SYSTEM_ERROR;
                 }
             } else {
                 ALOGW("public exponent not read");
-                return ::SYSTEM_ERROR;
+                return ResponseCode::SYSTEM_ERROR;
             }
         }
-        params.params.push_back(keymaster_param_long(KM_TAG_RSA_PUBLIC_EXPONENT, exponent));
+        params.push_back(TAG_RSA_PUBLIC_EXPONENT, exponent);
         break;
     }
     default: {
         ALOGW("Unsupported key type %d", keyType);
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     }
 
-    int32_t rc = generateKey(name, params, NULL, 0, targetUid, flags,
-                             /*outCharacteristics*/ NULL);
-    if (rc != ::NO_ERROR) {
-        ALOGW("generate failed: %d", rc);
+    auto rc = generateKey(name, params.hidl_data(), hidl_vec<uint8_t>(), targetUid, flags,
+                          /*outCharacteristics*/ NULL);
+    if (!rc.isOk()) {
+        ALOGW("generate failed: %d", int32_t(rc));
     }
     return translateResultToLegacyResult(rc);
 }
 
-int32_t KeyStoreService::import(const String16& name, const uint8_t* data, size_t length,
-                                int targetUid, int32_t flags) {
-    const uint8_t* ptr = data;
+KeyStoreServiceReturnCode KeyStoreService::import(const String16& name,
+                                                  const hidl_vec<uint8_t>& data, int targetUid,
+                                                  int32_t flags) {
 
-    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &ptr, length));
+    const uint8_t* ptr = &data[0];
+
+    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &ptr, data.size()));
     if (!pkcs8.get()) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
     if (!pkey.get()) {
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
     int type = EVP_PKEY_type(pkey->type);
-    KeymasterArguments params;
-    add_legacy_key_authorizations(type, &params.params);
+    AuthorizationSet params;
+    add_legacy_key_authorizations(type, &params);
     switch (type) {
     case EVP_PKEY_RSA:
-        params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_RSA));
+        params.push_back(TAG_ALGORITHM, Algorithm::RSA);
         break;
     case EVP_PKEY_EC:
-        params.params.push_back(keymaster_param_enum(KM_TAG_ALGORITHM, KM_ALGORITHM_EC));
+        params.push_back(TAG_ALGORITHM, Algorithm::EC);
         break;
     default:
         ALOGW("Unsupported key type %d", type);
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
-    int32_t rc = importKey(name, params, KM_KEY_FORMAT_PKCS8, data, length, targetUid, flags,
-                           /*outCharacteristics*/ NULL);
-    if (rc != ::NO_ERROR) {
-        ALOGW("importKey failed: %d", rc);
+
+    auto rc = importKey(name, params.hidl_data(), KeyFormat::PKCS8, data, targetUid, flags,
+                        /*outCharacteristics*/ NULL);
+
+    if (!rc.isOk()) {
+        ALOGW("importKey failed: %d", int32_t(rc));
     }
     return translateResultToLegacyResult(rc);
 }
 
-int32_t KeyStoreService::sign(const String16& name, const uint8_t* data, size_t length,
-                              uint8_t** out, size_t* outLength) {
+KeyStoreServiceReturnCode KeyStoreService::sign(const String16& name, const hidl_vec<uint8_t>& data,
+                                                hidl_vec<uint8_t>* out) {
     if (!checkBinderPermission(P_SIGN)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
-    return doLegacySignVerify(name, data, length, out, outLength, NULL, 0, KM_PURPOSE_SIGN);
+    return doLegacySignVerify(name, data, out, hidl_vec<uint8_t>(), KeyPurpose::SIGN);
 }
 
-int32_t KeyStoreService::verify(const String16& name, const uint8_t* data, size_t dataLength,
-                                const uint8_t* signature, size_t signatureLength) {
+KeyStoreServiceReturnCode KeyStoreService::verify(const String16& name,
+                                                  const hidl_vec<uint8_t>& data,
+                                                  const hidl_vec<uint8_t>& signature) {
     if (!checkBinderPermission(P_VERIFY)) {
-        return ::PERMISSION_DENIED;
+        return ResponseCode::PERMISSION_DENIED;
     }
-    return doLegacySignVerify(name, data, dataLength, NULL, NULL, signature, signatureLength,
-                              KM_PURPOSE_VERIFY);
+    return doLegacySignVerify(name, data, nullptr, signature, KeyPurpose::VERIFY);
 }
 
 /*
@@ -416,23 +423,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;
     }
 
@@ -440,17 +447,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;
     }
 
@@ -458,10 +465,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) {
@@ -497,26 +505,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) {
@@ -528,12 +536,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;
         }
     }
 
@@ -545,13 +553,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;
     }
 
@@ -562,16 +570,16 @@
     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;
     }
 
     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++) {
@@ -580,141 +588,101 @@
         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;
-    }
-
-    // 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;
-    }
-    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.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();
+        rc = KS_HANDLE_HIDL_ERROR(fallback->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);
@@ -722,300 +690,309 @@
     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}};
+    bool usingFallback = false;
+    auto& dev = mKeyStore->getDevice();
 
-    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;
-    }
-
-    // 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());
-
-    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.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();
+        rc = KS_HANDLE_HIDL_ERROR(fallback->importKey(params, format, keyData, hidlCb));
+        // possible hidl error
+        if (!rc.isOk()) {
+            return rc;
+        }
+        // now check error from callback
+        if (!error.isOk()) {
+            return error;
+        }
+    }
 
     // Write the characteristics:
     String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
 
-    Blob charBlob(kc_buf.get(), keyCharacteristics.SerializedSize(),
-        NULL, 0, ::TYPE_KEY_CHARACTERISTICS);
-    charBlob.setFallback(isFallback);
+    AuthorizationSet opParams = params;
+    std::stringstream kcStream;
+    opParams.Serialize(&kcStream);
+    if (kcStream.bad()) return ResponseCode::SYSTEM_ERROR;
+    auto kcBuf = kcStream.str();
+
+    Blob charBlob(reinterpret_cast<const uint8_t*>(kcBuf.data()), kcBuf.size(), NULL, 0,
+                  ::TYPE_KEY_CHARACTERISTICS);
+    charBlob.setFallback(usingFallback);
     charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
 
     return mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid));
 }
 
-void KeyStoreService::exportKey(const String16& name, keymaster_key_format_t format,
-                                const keymaster_blob_t* clientId, const keymaster_blob_t* appData,
+void KeyStoreService::exportKey(const String16& name, KeyFormat format,
+                                const hidl_vec<uint8_t>& clientId, const hidl_vec<uint8_t>& appData,
                                 int32_t uid, ExportResult* result) {
 
     uid_t targetUid = getEffectiveUid(uid);
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     if (!is_granted_to(callingUid, targetUid)) {
         ALOGW("uid %d not permitted to act for uid %d in exportKey", callingUid, targetUid);
-        result->resultCode = ::PERMISSION_DENIED;
+        result->resultCode = ResponseCode::PERMISSION_DENIED;
         return;
     }
 
     Blob keyBlob;
     String8 name8(name);
-    int rc;
 
-    ResponseCode responseCode =
-        mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
-    if (responseCode != ::NO_ERROR) {
-        result->resultCode = responseCode;
+    result->resultCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
+    if (!result->resultCode.isOk()) {
         return;
     }
-    keymaster_key_blob_t key;
-    key.key_material_size = keyBlob.getLength();
-    key.key_material = keyBlob.getValue();
-    auto* dev = mKeyStore->getDeviceForBlob(keyBlob);
-    if (!dev->export_key) {
-        result->resultCode = KM_ERROR_UNIMPLEMENTED;
-        return;
-    }
-    keymaster_blob_t output = {NULL, 0};
-    rc = dev->export_key(dev, format, &key, clientId, appData, &output);
-    if (rc == KM_ERROR_KEY_REQUIRES_UPGRADE) {
-        AuthorizationSet upgradeParams;
-        if (clientId && clientId->data && clientId->data_length) {
-            upgradeParams.push_back(TAG_APPLICATION_ID, *clientId);
-        }
-        if (appData && appData->data && appData->data_length) {
-            upgradeParams.push_back(TAG_APPLICATION_DATA, *appData);
-        }
-        rc = upgradeKeyBlob(name, targetUid, upgradeParams, &keyBlob);
-        if (rc != ::NO_ERROR) {
-            result->resultCode = rc;
+
+    auto key = blob2hidlVec(keyBlob);
+    auto& dev = mKeyStore->getDevice(keyBlob);
+
+    auto hidlCb = [&](ErrorCode ret, const ::android::hardware::hidl_vec<uint8_t>& keyMaterial) {
+        result->resultCode = ret;
+        if (!result->resultCode.isOk()) {
             return;
         }
-        key = {keyBlob.getValue(), static_cast<size_t>(keyBlob.getLength())};
-        rc = dev->export_key(dev, format, &key, clientId, appData, &output);
+        result->exportData = keyMaterial;
+    };
+    KeyStoreServiceReturnCode rc =
+        KS_HANDLE_HIDL_ERROR(dev->exportKey(format, key, clientId, appData, hidlCb));
+    // Overwrite result->resultCode only on HIDL error. Otherwise we want the result set in the
+    // callback hidlCb.
+    if (!rc.isOk()) {
+        result->resultCode = rc;
     }
 
-    result->exportData.reset(const_cast<uint8_t*>(output.data));
-    result->dataLength = output.data_length;
-    result->resultCode = rc ? rc : ::NO_ERROR;
+    if (result->resultCode == ErrorCode::KEY_REQUIRES_UPGRADE) {
+        AuthorizationSet upgradeParams;
+        if (clientId.size()) {
+            upgradeParams.push_back(TAG_APPLICATION_ID, clientId);
+        }
+        if (appData.size()) {
+            upgradeParams.push_back(TAG_APPLICATION_DATA, appData);
+        }
+        result->resultCode = upgradeKeyBlob(name, targetUid, upgradeParams, &keyBlob);
+        if (!result->resultCode.isOk()) {
+            return;
+        }
+
+        auto upgradedHidlKeyBlob = blob2hidlVec(keyBlob);
+
+        result->resultCode = KS_HANDLE_HIDL_ERROR(
+            dev->exportKey(format, upgradedHidlKeyBlob, clientId, appData, hidlCb));
+        if (!result->resultCode.isOk()) {
+            return;
+        }
+    }
 }
 
-void KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name,
-                            keymaster_purpose_t purpose, bool pruneable,
-                            const KeymasterArguments& params, const uint8_t* entropy,
-                            size_t entropyLength, int32_t uid, OperationResult* result) {
+static inline void addAuthTokenToParams(AuthorizationSet* params, const HardwareAuthToken* token) {
+    if (token) {
+        params->push_back(TAG_AUTH_TOKEN, authToken2HidlVec(*token));
+    }
+}
+
+void KeyStoreService::begin(const sp<IBinder>& appToken, const String16& name, KeyPurpose purpose,
+                            bool pruneable, const hidl_vec<KeyParameter>& params,
+                            const hidl_vec<uint8_t>& entropy, int32_t uid,
+                            OperationResult* result) {
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
     uid_t targetUid = getEffectiveUid(uid);
     if (!is_granted_to(callingUid, targetUid)) {
         ALOGW("uid %d not permitted to act for uid %d in begin", callingUid, targetUid);
-        result->resultCode = ::PERMISSION_DENIED;
+        result->resultCode = ResponseCode::PERMISSION_DENIED;
         return;
     }
     if (!pruneable && get_app_id(callingUid) != AID_SYSTEM) {
         ALOGE("Non-system uid %d trying to start non-pruneable operation", callingUid);
-        result->resultCode = ::PERMISSION_DENIED;
+        result->resultCode = ResponseCode::PERMISSION_DENIED;
         return;
     }
-    if (!checkAllowedOperationParams(params.params)) {
-        result->resultCode = KM_ERROR_INVALID_ARGUMENT;
+    if (!checkAllowedOperationParams(params)) {
+        result->resultCode = ErrorCode::INVALID_ARGUMENT;
         return;
     }
     Blob keyBlob;
     String8 name8(name);
-    ResponseCode responseCode =
-        mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
-    if (responseCode != ::NO_ERROR) {
-        result->resultCode = responseCode;
+    result->resultCode = mKeyStore->getKeyForName(&keyBlob, name8, targetUid, TYPE_KEYMASTER_10);
+    if (!result->resultCode.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
     // pruneable.
     while (mOperationMap.getOperationCount() >= MAX_OPERATIONS) {
@@ -1025,27 +1002,42 @@
         }
     }
 
-    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);
     }
@@ -1054,241 +1046,251 @@
     // 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, params, 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;
 }
 
 constexpr size_t KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE = 1024;
 
-int32_t KeyStoreService::attestKey(const String16& name, const KeymasterArguments& params,
-                                   KeymasterCertificateChain* outChain) {
-    if (!outChain) return KM_ERROR_OUTPUT_PARAMETER_NULL;
+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.params)) {
-        return KM_ERROR_INVALID_ARGUMENT;
+    if (!checkAllowedOperationParams(params)) {
+        return ErrorCode::INVALID_ARGUMENT;
     }
 
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
 
     Blob keyBlob;
     String8 name8(name);
-    ResponseCode responseCode =
+    KeyStoreServiceReturnCode responseCode =
         mKeyStore->getKeyForName(&keyBlob, name8, callingUid, TYPE_KEYMASTER_10);
-    if (responseCode != ::NO_ERROR) {
+    if (!responseCode.isOk()) {
         return responseCode;
     }
 
-    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;
-
     auto asn1_attestation_id_result = security::gather_attestation_application_id(callingUid);
     if (!asn1_attestation_id_result.isOk()) {
         ALOGE("failed to gather attestation_id");
-        return KM_ERROR_ATTESTATION_APPLICATION_ID_MISSING;
+        return ErrorCode::ATTESTATION_APPLICATION_ID_MISSING;
     }
-    const std::vector<uint8_t>& asn1_attestation_id = asn1_attestation_id_result;
+    std::vector<uint8_t>& asn1_attestation_id = asn1_attestation_id_result;
 
     /*
-     * Make a mutable copy of the params vector which to append the attestation id to.
-     * The copy is shallow, and the lifetime of the inner objects is the calling scope.
+     * The attestation application ID cannot be longer than
+     * KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE, so we truncate if too long.
      */
-    auto mutable_params = params.params;
+    if (asn1_attestation_id.size() > KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE)
+        asn1_attestation_id.resize(KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE);
 
-    mutable_params.push_back(
-        {.tag = KM_TAG_ATTESTATION_APPLICATION_ID,
-         .blob = {asn1_attestation_id.data(),
-                  std::min(asn1_attestation_id.size(), KEY_ATTESTATION_APPLICATION_ID_MAX_SIZE)}});
+    AuthorizationSet mutableParams = params;
 
-    const keymaster_key_param_set_t in_params = {
-        const_cast<keymaster_key_param_t*>(mutable_params.data()), mutable_params.size()};
-    outChain->chain = {nullptr, 0};
-    int32_t rc = dev->attest_key(dev, &key, &in_params, &outChain->chain);
-    if (rc) return rc;
-    return ::NO_ERROR;
+    mutableParams.push_back(TAG_ATTESTATION_APPLICATION_ID, blob2hidlVec(asn1_attestation_id));
+
+    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);
+    KeyStoreServiceReturnCode 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::onDeviceOffBody() {
     // TODO(tuckeris): add permission check.  This should be callable from ClockworkHome only.
     mAuthTokenTable.onDeviceOffBody();
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
 /**
@@ -1375,17 +1377,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) {
@@ -1399,45 +1403,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::AUTH_TOKEN:
         // fall through intended
-        case KM_TAG_ATTESTATION_APPLICATION_ID:
+        case Tag::ATTESTATION_APPLICATION_ID:
             return false;
         default:
             break;
@@ -1446,30 +1421,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;
 }
@@ -1477,49 +1454,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;
     }
 }
 
@@ -1528,185 +1497,194 @@
  * requires authorization. Uses the cached result in the OperationMap if available
  * otherwise gets the token from the AuthTokenTable and caches the result.
  *
- * Returns ::NO_ERROR if the auth token was added or not needed.
+ * Returns ResponseCode::NO_ERROR if the auth token was added or not needed.
  *         KM_ERROR_KEY_USER_NOT_AUTHENTICATED if the operation is not
  *         authenticated.
  *         KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid
  *         operation token.
  */
-int32_t KeyStoreService::addOperationAuthTokenIfNeeded(const sp<IBinder>& token,
-                                                       std::vector<keymaster_key_param_t>* params) {
-    const hw_auth_token_t* authToken = NULL;
+KeyStoreServiceReturnCode KeyStoreService::addOperationAuthTokenIfNeeded(const sp<IBinder>& token,
+                                                                         AuthorizationSet* params) {
+    const HardwareAuthToken* authToken = nullptr;
     mOperationMap.getOperationAuthToken(token, &authToken);
     if (!authToken) {
-        const keymaster2_device_t* dev;
-        keymaster_operation_handle_t handle;
-        const keymaster_key_characteristics_t* characteristics = NULL;
-        keymaster_purpose_t purpose;
-        keymaster::km_id_t keyid;
+        km_device_t dev;
+        uint64_t handle;
+        const KeyCharacteristics* characteristics = nullptr;
+        KeyPurpose purpose;
+        km_id_t keyid;
         if (!mOperationMap.getOperation(token, &handle, &keyid, &purpose, &dev, &characteristics)) {
-            return KM_ERROR_INVALID_OPERATION_HANDLE;
+            return ErrorCode::INVALID_OPERATION_HANDLE;
         }
-        int32_t result = getAuthToken(characteristics, handle, purpose, &authToken);
-        if (result != ::NO_ERROR) {
+        auto result = getAuthToken(*characteristics, handle, purpose, &authToken);
+        if (!result.isOk()) {
             return result;
         }
         if (authToken) {
             mOperationMap.setOperationAuthToken(token, authToken);
         }
     }
-    addAuthToParams(params, authToken);
-    return ::NO_ERROR;
+    addAuthTokenToParams(params, authToken);
+    return ResponseCode::NO_ERROR;
 }
 
 /**
  * Translate a result value to a legacy return value. All keystore errors are
  * preserved and keymaster errors become SYSTEM_ERRORs
  */
-int32_t KeyStoreService::translateResultToLegacyResult(int32_t result) {
+KeyStoreServiceReturnCode KeyStoreService::translateResultToLegacyResult(int32_t result) {
     if (result > 0) {
-        return result;
+        return static_cast<ResponseCode>(result);
     }
-    return ::SYSTEM_ERROR;
+    return ResponseCode::SYSTEM_ERROR;
 }
 
-keymaster_key_param_t*
-KeyStoreService::getKeyAlgorithm(keymaster_key_characteristics_t* characteristics) {
-    for (size_t i = 0; i < characteristics->hw_enforced.length; i++) {
-        if (characteristics->hw_enforced.params[i].tag == KM_TAG_ALGORITHM) {
-            return &characteristics->hw_enforced.params[i];
-        }
+static NullOr<const Algorithm&>
+getKeyAlgoritmFromKeyCharacteristics(const KeyCharacteristics& characteristics) {
+    for (size_t i = 0; i < characteristics.teeEnforced.size(); ++i) {
+        auto algo = authorizationValue(TAG_ALGORITHM, characteristics.teeEnforced[i]);
+        if (algo.isOk()) return algo.value();
     }
-    for (size_t i = 0; i < characteristics->sw_enforced.length; i++) {
-        if (characteristics->sw_enforced.params[i].tag == KM_TAG_ALGORITHM) {
-            return &characteristics->sw_enforced.params[i];
-        }
+    for (size_t i = 0; i < characteristics.softwareEnforced.size(); ++i) {
+        auto algo = authorizationValue(TAG_ALGORITHM, characteristics.softwareEnforced[i]);
+        if (algo.isOk()) return algo.value();
     }
-    return NULL;
+    return {};
 }
 
-void KeyStoreService::addLegacyBeginParams(const String16& name,
-                                           std::vector<keymaster_key_param_t>& params) {
+void KeyStoreService::addLegacyBeginParams(const String16& name, AuthorizationSet* params) {
     // All legacy keys are DIGEST_NONE/PAD_NONE.
-    params.push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE));
-    params.push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE));
+    params->push_back(TAG_DIGEST, Digest::NONE);
+    params->push_back(TAG_PADDING, PaddingMode::NONE);
 
     // Look up the algorithm of the key.
     KeyCharacteristics characteristics;
-    int32_t rc = getKeyCharacteristics(name, NULL, NULL, UID_SELF, &characteristics);
-    if (rc != ::NO_ERROR) {
+    auto rc = getKeyCharacteristics(name, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(), UID_SELF,
+                                    &characteristics);
+    if (!rc.isOk()) {
         ALOGE("Failed to get key characteristics");
         return;
     }
-    keymaster_key_param_t* algorithm = getKeyAlgorithm(&characteristics.characteristics);
-    if (!algorithm) {
+    auto algorithm = getKeyAlgoritmFromKeyCharacteristics(characteristics);
+    if (!algorithm.isOk()) {
         ALOGE("getKeyCharacteristics did not include KM_TAG_ALGORITHM");
         return;
     }
-    params.push_back(*algorithm);
+    params->push_back(TAG_ALGORITHM, algorithm.value());
 }
 
-int32_t KeyStoreService::doLegacySignVerify(const String16& name, const uint8_t* data,
-                                            size_t length, uint8_t** out, size_t* outLength,
-                                            const uint8_t* signature, size_t signatureLength,
-                                            keymaster_purpose_t purpose) {
+KeyStoreServiceReturnCode KeyStoreService::doLegacySignVerify(const String16& name,
+                                                              const hidl_vec<uint8_t>& data,
+                                                              hidl_vec<uint8_t>* out,
+                                                              const hidl_vec<uint8_t>& signature,
+                                                              KeyPurpose purpose) {
 
     std::basic_stringstream<uint8_t> outBuffer;
     OperationResult result;
-    KeymasterArguments inArgs;
-    addLegacyBeginParams(name, inArgs.params);
+    AuthorizationSet inArgs;
+    addLegacyBeginParams(name, &inArgs);
     sp<IBinder> appToken(new BBinder);
     sp<IBinder> token;
 
-    begin(appToken, name, purpose, true, inArgs, NULL, 0, UID_SELF, &result);
-    if (result.resultCode != ResponseCode::NO_ERROR) {
-        if (result.resultCode == ::KEY_NOT_FOUND) {
+    begin(appToken, name, purpose, true, inArgs.hidl_data(), hidl_vec<uint8_t>(), UID_SELF,
+          &result);
+    if (!result.resultCode.isOk()) {
+        if (result.resultCode == ResponseCode::KEY_NOT_FOUND) {
             ALOGW("Key not found");
         } else {
-            ALOGW("Error in begin: %d", result.resultCode);
+            ALOGW("Error in begin: %d", int32_t(result.resultCode));
         }
         return translateResultToLegacyResult(result.resultCode);
     }
-    inArgs.params.clear();
+    inArgs.Clear();
     token = result.token;
     size_t consumed = 0;
     size_t lastConsumed = 0;
+    hidl_vec<uint8_t> data_view;
     do {
-        update(token, inArgs, data + consumed, length - consumed, &result);
+        data_view.setToExternal(const_cast<uint8_t*>(&data[consumed]), data.size() - consumed);
+        update(token, inArgs.hidl_data(), data_view, &result);
         if (result.resultCode != ResponseCode::NO_ERROR) {
-            ALOGW("Error in update: %d", result.resultCode);
+            ALOGW("Error in update: %d", int32_t(result.resultCode));
             return translateResultToLegacyResult(result.resultCode);
         }
         if (out) {
-            outBuffer.write(result.data.get(), result.dataLength);
+            outBuffer.write(&result.data[0], result.data.size());
         }
         lastConsumed = result.inputConsumed;
         consumed += lastConsumed;
-    } while (consumed < length && lastConsumed > 0);
+    } while (consumed < data.size() && lastConsumed > 0);
 
-    if (consumed != length) {
-        ALOGW("Not all data consumed. Consumed %zu of %zu", consumed, length);
-        return ::SYSTEM_ERROR;
+    if (consumed != data.size()) {
+        ALOGW("Not all data consumed. Consumed %zu of %zu", consumed, data.size());
+        return ResponseCode::SYSTEM_ERROR;
     }
 
-    finish(token, inArgs, signature, signatureLength, NULL, 0, &result);
+    finish(token, inArgs.hidl_data(), signature, hidl_vec<uint8_t>(), &result);
     if (result.resultCode != ResponseCode::NO_ERROR) {
-        ALOGW("Error in finish: %d", result.resultCode);
+        ALOGW("Error in finish: %d", int32_t(result.resultCode));
         return translateResultToLegacyResult(result.resultCode);
     }
     if (out) {
-        outBuffer.write(result.data.get(), result.dataLength);
+        outBuffer.write(&result.data[0], result.data.size());
     }
 
     if (out) {
         auto buf = outBuffer.str();
-        *out = new uint8_t[buf.size()];
-        memcpy(*out, buf.c_str(), buf.size());
-        *outLength = buf.size();
+        out->resize(buf.size());
+        memcpy(&(*out)[0], buf.data(), out->size());
     }
 
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
-int32_t KeyStoreService::upgradeKeyBlob(const String16& name, uid_t uid,
-                                        const AuthorizationSet& params, Blob* blob) {
+KeyStoreServiceReturnCode KeyStoreService::upgradeKeyBlob(const String16& name, uid_t uid,
+                                                          const AuthorizationSet& params,
+                                                          Blob* blob) {
     // Read the blob rather than assuming the caller provided the right name/uid/blob triplet.
     String8 name8(name);
     ResponseCode responseCode = mKeyStore->getKeyForName(blob, name8, uid, TYPE_KEYMASTER_10);
-    if (responseCode != ::NO_ERROR) {
+    if (responseCode != ResponseCode::NO_ERROR) {
         return responseCode;
     }
 
-    keymaster_key_blob_t key = {blob->getValue(), static_cast<size_t>(blob->getLength())};
-    auto* dev = mKeyStore->getDeviceForBlob(*blob);
-    keymaster_key_blob_t upgraded_key;
-    int32_t rc = dev->upgrade_key(dev, &key, &params, &upgraded_key);
-    if (rc != KM_ERROR_OK) {
-        return rc;
-    }
-    UniquePtr<uint8_t, Malloc_Delete> upgraded_key_deleter(
-        const_cast<uint8_t*>(upgraded_key.key_material));
+    auto hidlKey = blob2hidlVec(*blob);
+    auto& dev = mKeyStore->getDevice(*blob);
 
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
-    rc = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(uid));
-    if (rc != ::NO_ERROR) {
+    KeyStoreServiceReturnCode error;
+    auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& upgradedKeyBlob) {
+        error = ret;
+        if (!error.isOk()) {
+            return;
+        }
+
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
+        error = mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(uid));
+        if (!error.isOk()) {
+            return;
+        }
+
+        Blob newBlob(&upgradedKeyBlob[0], upgradedKeyBlob.size(), nullptr /* info */,
+                     0 /* infoLength */, ::TYPE_KEYMASTER_10);
+        newBlob.setFallback(blob->isFallback());
+        newBlob.setEncrypted(blob->isEncrypted());
+
+        error = mKeyStore->put(filename.string(), &newBlob, get_user_id(uid));
+        if (!error.isOk()) {
+            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
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index cfbc91f..432e780 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -19,7 +19,7 @@
 
 #include <keystore/IKeystoreService.h>
 
-#include <keymaster/authorization_set.h>
+#include <keystore/authorization_set.h>
 
 #include "auth_token_table.h"
 #include "keystore.h"
@@ -27,42 +27,48 @@
 #include "operation.h"
 #include "permissions.h"
 
-namespace android {
+namespace keystore {
 
-class KeyStoreService : public BnKeystoreService, public IBinder::DeathRecipient {
+class KeyStoreService : public android::BnKeystoreService, public android::IBinder::DeathRecipient {
+    typedef ::android::sp<::android::hardware::keymaster::V3_0::IKeymasterDevice> km_device_t;
+
   public:
     explicit KeyStoreService(KeyStore* keyStore) : mKeyStore(keyStore), mOperationMap(this) {}
 
-    void binderDied(const wp<IBinder>& who);
+    void binderDied(const android::wp<android::IBinder>& who);
 
-    int32_t getState(int32_t userId);
+    KeyStoreServiceReturnCode getState(int32_t userId) override;
 
-    int32_t get(const String16& name, int32_t uid, uint8_t** item, size_t* itemLength);
-    int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid,
-                   int32_t flags);
-    int32_t del(const String16& name, int targetUid);
-    int32_t exist(const String16& name, int targetUid);
-    int32_t list(const String16& prefix, int targetUid, Vector<String16>* matches);
+    KeyStoreServiceReturnCode get(const android::String16& name, int32_t uid,
+                                  hidl_vec<uint8_t>* item) override;
+    KeyStoreServiceReturnCode insert(const android::String16& name, const hidl_vec<uint8_t>& item,
+                                     int targetUid, int32_t flags) override;
+    KeyStoreServiceReturnCode del(const android::String16& name, int targetUid) override;
+    KeyStoreServiceReturnCode exist(const android::String16& name, int targetUid) override;
+    KeyStoreServiceReturnCode list(const android::String16& prefix, int targetUid,
+                                   android::Vector<android::String16>* matches) override;
 
-    int32_t reset();
+    KeyStoreServiceReturnCode reset() override;
 
-    int32_t onUserPasswordChanged(int32_t userId, const String16& password);
-    int32_t onUserAdded(int32_t userId, int32_t parentId);
-    int32_t onUserRemoved(int32_t userId);
+    KeyStoreServiceReturnCode onUserPasswordChanged(int32_t userId,
+                                                    const android::String16& password) override;
+    KeyStoreServiceReturnCode onUserAdded(int32_t userId, int32_t parentId) override;
+    KeyStoreServiceReturnCode onUserRemoved(int32_t userId) override;
 
-    int32_t lock(int32_t userId);
-    int32_t unlock(int32_t userId, const String16& pw);
+    KeyStoreServiceReturnCode lock(int32_t userId) override;
+    KeyStoreServiceReturnCode unlock(int32_t userId, const android::String16& pw) override;
 
-    bool isEmpty(int32_t userId);
+    bool isEmpty(int32_t userId) override;
 
-    int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize,
-                     int32_t flags, Vector<sp<KeystoreArg>>* args);
-    int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid,
-                   int32_t flags);
-    int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
-                 size_t* outLength);
-    int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
-                   const uint8_t* signature, size_t signatureLength);
+    KeyStoreServiceReturnCode
+    generate(const android::String16& name, int32_t targetUid, int32_t keyType, int32_t keySize,
+             int32_t flags, android::Vector<android::sp<android::KeystoreArg>>* args) override;
+    KeyStoreServiceReturnCode import(const android::String16& name, const hidl_vec<uint8_t>& data,
+                                     int targetUid, int32_t flags) override;
+    KeyStoreServiceReturnCode sign(const android::String16& name, const hidl_vec<uint8_t>& data,
+                                   hidl_vec<uint8_t>* out) override;
+    KeyStoreServiceReturnCode verify(const android::String16& name, const hidl_vec<uint8_t>& data,
+                                     const hidl_vec<uint8_t>& signature) override;
 
     /*
      * TODO: The abstraction between things stored in hardware and regular blobs
@@ -75,51 +81,57 @@
      * "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 onDeviceOffBody() override;
 
   private:
     static const int32_t UID_SELF = -1;
@@ -164,23 +176,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 +201,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 +217,22 @@
      *         KM_ERROR_INVALID_OPERATION_HANDLE if token is not a valid
      *         operation token.
      */
-    int32_t addOperationAuthTokenIfNeeded(const sp<IBinder>& token,
-                                          std::vector<keymaster_key_param_t>* params);
+    KeyStoreServiceReturnCode addOperationAuthTokenIfNeeded(const sp<android::IBinder>& token,
+                                                            AuthorizationSet* params);
 
     /**
      * Translate a result value to a legacy return value. All keystore errors are
      * preserved and keymaster errors become SYSTEM_ERRORs
      */
-    int32_t translateResultToLegacyResult(int32_t result);
+    KeyStoreServiceReturnCode translateResultToLegacyResult(int32_t result);
 
-    keymaster_key_param_t* getKeyAlgorithm(keymaster_key_characteristics_t* characteristics);
+    void addLegacyBeginParams(const android::String16& name, AuthorizationSet* params);
 
-    void addLegacyBeginParams(const String16& name, std::vector<keymaster_key_param_t>& params);
-
-    int32_t doLegacySignVerify(const String16& name, const uint8_t* data, size_t length,
-                               uint8_t** out, size_t* outLength, const uint8_t* signature,
-                               size_t signatureLength, keymaster_purpose_t purpose);
+    KeyStoreServiceReturnCode doLegacySignVerify(const android::String16& name,
+                                                 const hidl_vec<uint8_t>& data,
+                                                 hidl_vec<uint8_t>* out,
+                                                 const hidl_vec<uint8_t>& signature,
+                                                 KeyPurpose purpose);
 
     /**
      * Upgrade a key blob under alias "name", returning the new blob in "blob".  If "blob"
@@ -234,15 +242,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..117f048
--- /dev/null
+++ b/keystore/keymaster_enforcement.cpp
@@ -0,0 +1,598 @@
+/*
+ * 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:
+            return ErrorCode::INVALID_KEY_BLOB;
+
+        /* Tags used for cryptographic parameters in keygen.  Nothing to enforce. */
+        case Tag::PURPOSE:
+        case Tag::ALGORITHM:
+        case Tag::KEY_SIZE:
+        case Tag::BLOCK_MODE:
+        case Tag::DIGEST:
+        case Tag::MAC_LENGTH:
+        case Tag::PADDING:
+        case Tag::NONCE:
+        case Tag::MIN_MAC_LENGTH:
+        case Tag::KDF:
+        case Tag::EC_CURVE:
+
+        /* Tags not used for operations. */
+        case Tag::BLOB_USAGE_REQUIREMENTS:
+        case Tag::EXPORTABLE:
+
+        /* Algorithm specific parameters not used for access control. */
+        case Tag::RSA_PUBLIC_EXPONENT:
+        case Tag::ECIES_SINGLE_HASH_MODE:
+
+        /* Informational tags. */
+        case Tag::CREATION_DATETIME:
+        case Tag::ORIGIN:
+        case Tag::ROLLBACK_RESISTANT:
+
+        /* Tags handled when KM_TAG_USER_SECURE_ID is handled */
+        case Tag::NO_AUTH_REQUIRED:
+        case Tag::USER_AUTH_TYPE:
+        case Tag::AUTH_TIMEOUT:
+
+        /* Tag to provide data to operations. */
+        case Tag::ASSOCIATED_DATA:
+
+        /* Tags that are implicitly verified by secure side */
+        case Tag::ALL_APPLICATIONS:
+        case Tag::APPLICATION_ID:
+        case Tag::OS_VERSION:
+        case Tag::OS_PATCHLEVEL:
+
+        /* Ignored pending removal */
+        case Tag::USER_ID:
+        case Tag::ALL_USERS:
+
+        /* TODO(swillden): Handle these */
+        case Tag::INCLUDE_UNIQUE_ID:
+        case Tag::UNIQUE_ID:
+        case Tag::RESET_SINCE_ID_ROTATION:
+        case Tag::ALLOW_WHILE_ON_BODY:
+            break;
+
+        case Tag::BOOTLOADER_ONLY:
+            return ErrorCode::INVALID_KEY_BLOB;
+        }
+    }
+
+    if (authentication_required && !auth_token_matched) {
+        ALOGE("Auth required but no matching auth token found");
+        return ErrorCode::KEY_USER_NOT_AUTHENTICATED;
+    }
+
+    if (!caller_nonce_authorized_by_key && is_origination_purpose(purpose) &&
+        operation_params.Contains(Tag::NONCE))
+        return ErrorCode::CALLER_NONCE_PROHIBITED;
+
+    if (min_ops_timeout != UINT32_MAX) {
+        if (!access_time_map_) {
+            ALOGE("Rate-limited keys table not allocated.  Rate-limited keys disabled");
+            return ErrorCode::MEMORY_ALLOCATION_FAILED;
+        }
+
+        if (!access_time_map_->UpdateKeyAccessTime(keyid, get_current_time(), min_ops_timeout)) {
+            ALOGE("Rate-limited keys table full.  Entries will time out.");
+            return ErrorCode::TOO_MANY_OPERATIONS;
+        }
+    }
+
+    if (update_access_count) {
+        if (!access_count_map_) {
+            ALOGE("Usage-count limited keys tabel not allocated.  Count-limited keys disabled");
+            return ErrorCode::MEMORY_ALLOCATION_FAILED;
+        }
+
+        if (!access_count_map_->IncrementKeyAccessCount(keyid)) {
+            ALOGE("Usage count-limited keys table full, until reboot.");
+            return ErrorCode::TOO_MANY_OPERATIONS;
+        }
+    }
+
+    return ErrorCode::OK;
+}
+
+class EvpMdCtx {
+  public:
+    EvpMdCtx() { EVP_MD_CTX_init(&ctx_); }
+    ~EvpMdCtx() { EVP_MD_CTX_cleanup(&ctx_); }
+
+    EVP_MD_CTX* get() { return &ctx_; }
+
+  private:
+    EVP_MD_CTX ctx_;
+};
+
+/* static */
+bool KeymasterEnforcement::CreateKeyId(const hidl_vec<uint8_t>& key_blob, km_id_t* keyid) {
+    EvpMdCtx ctx;
+
+    uint8_t hash[EVP_MAX_MD_SIZE];
+    unsigned int hash_len;
+    if (EVP_DigestInit_ex(ctx.get(), EVP_sha256(), nullptr /* ENGINE */) &&
+        EVP_DigestUpdate(ctx.get(), &key_blob[0], key_blob.size()) &&
+        EVP_DigestFinal_ex(ctx.get(), hash, &hash_len)) {
+        assert(hash_len >= sizeof(*keyid));
+        memcpy(keyid, hash, sizeof(*keyid));
+        return true;
+    }
+
+    return false;
+}
+
+bool KeymasterEnforcement::MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid) {
+    if (!access_time_map_) return false;
+
+    uint32_t last_access_time;
+    if (!access_time_map_->LastKeyAccessTime(keyid, &last_access_time)) return true;
+    return min_time_between <= static_cast<int64_t>(get_current_time()) - last_access_time;
+}
+
+bool KeymasterEnforcement::MaxUsesPerBootNotExceeded(const km_id_t keyid, uint32_t max_uses) {
+    if (!access_count_map_) return false;
+
+    uint32_t key_access_count;
+    if (!access_count_map_->KeyAccessCount(keyid, &key_access_count)) return true;
+    return key_access_count < max_uses;
+}
+
+template <typename IntType, uint32_t byteOrder> struct choose_hton;
+
+template <typename IntType> struct choose_hton<IntType, __ORDER_LITTLE_ENDIAN__> {
+    inline static IntType hton(const IntType& value) {
+        IntType result = 0;
+        const unsigned char* inbytes = reinterpret_cast<const unsigned char*>(&value);
+        unsigned char* outbytes = reinterpret_cast<unsigned char*>(&result);
+        for (int i = sizeof(IntType) - 1; i >= 0; --i) {
+            *(outbytes++) = inbytes[i];
+        }
+        return result;
+    }
+};
+
+template <typename IntType> struct choose_hton<IntType, __ORDER_BIG_ENDIAN__> {
+    inline static IntType hton(const IntType& value) { return value; }
+};
+
+template <typename IntType> inline IntType hton(const IntType& value) {
+    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
+}
+
+template <typename IntType> inline IntType ntoh(const IntType& value) {
+    // same operation and hton
+    return choose_hton<IntType, __BYTE_ORDER__>::hton(value);
+}
+
+bool KeymasterEnforcement::AuthTokenMatches(const AuthorizationSet& auth_set,
+                                            const AuthorizationSet& operation_params,
+                                            const uint64_t user_secure_id,
+                                            const int auth_type_index, const int auth_timeout_index,
+                                            const uint64_t op_handle,
+                                            bool is_begin_operation) const {
+    assert(auth_type_index < static_cast<int>(auth_set.size()));
+    assert(auth_timeout_index < static_cast<int>(auth_set.size()));
+
+    auto auth_token_blob = operation_params.GetTagValue(TAG_AUTH_TOKEN);
+    if (!auth_token_blob.isOk()) {
+        ALOGE("Authentication required, but auth token not provided");
+        return false;
+    }
+
+    if (auth_token_blob.value().size() != sizeof(hw_auth_token_t)) {
+        ALOGE("Bug: Auth token is the wrong size (%zu expected, %zu found)",
+              sizeof(hw_auth_token_t), auth_token_blob.value().size());
+        return false;
+    }
+
+    hw_auth_token_t auth_token;
+    memcpy(&auth_token, &auth_token_blob.value()[0], sizeof(hw_auth_token_t));
+    if (auth_token.version != HW_AUTH_TOKEN_VERSION) {
+        ALOGE("Bug: Auth token is the version %hhu (or is not an auth token). Expected %d",
+              auth_token.version, HW_AUTH_TOKEN_VERSION);
+        return false;
+    }
+
+    if (!ValidateTokenSignature(auth_token)) {
+        ALOGE("Auth token signature invalid");
+        return false;
+    }
+
+    if (auth_timeout_index == -1 && op_handle && op_handle != auth_token.challenge) {
+        ALOGE("Auth token has the challenge %" PRIu64 ", need %" PRIu64, auth_token.challenge,
+              op_handle);
+        return false;
+    }
+
+    if (user_secure_id != auth_token.user_id && user_secure_id != auth_token.authenticator_id) {
+        ALOGI("Auth token SIDs %" PRIu64 " and %" PRIu64 " do not match key SID %" PRIu64,
+              auth_token.user_id, auth_token.authenticator_id, user_secure_id);
+        return false;
+    }
+
+    if (auth_type_index < 0 || auth_type_index > static_cast<int>(auth_set.size())) {
+        ALOGE("Auth required but no auth type found");
+        return false;
+    }
+
+    assert(auth_set[auth_type_index].tag == KM_TAG_USER_AUTH_TYPE);
+    auto key_auth_type_mask = authorizationValue(TAG_USER_AUTH_TYPE, auth_set[auth_type_index]);
+    if (!key_auth_type_mask.isOk()) return false;
+
+    uint32_t token_auth_type = ntoh(auth_token.authenticator_type);
+    if ((uint32_t(key_auth_type_mask.value()) & token_auth_type) == 0) {
+        ALOGE("Key requires match of auth type mask 0%uo, but token contained 0%uo",
+              key_auth_type_mask.value(), token_auth_type);
+        return false;
+    }
+
+    if (auth_timeout_index != -1 && is_begin_operation) {
+        assert(auth_set[auth_timeout_index].tag == KM_TAG_AUTH_TIMEOUT);
+        auto auth_token_timeout =
+            authorizationValue(TAG_AUTH_TIMEOUT, auth_set[auth_timeout_index]);
+        if (!auth_token_timeout.isOk()) return false;
+
+        if (auth_token_timed_out(auth_token, auth_token_timeout.value())) {
+            ALOGE("Auth token has timed out");
+            return false;
+        }
+    }
+
+    // Survived the whole gauntlet.  We have authentage!
+    return true;
+}
+
+bool AccessTimeMap::LastKeyAccessTime(km_id_t keyid, uint32_t* last_access_time) const {
+    for (auto& entry : last_access_list_)
+        if (entry.keyid == keyid) {
+            *last_access_time = entry.access_time;
+            return true;
+        }
+    return false;
+}
+
+bool AccessTimeMap::UpdateKeyAccessTime(km_id_t keyid, uint32_t current_time, uint32_t timeout) {
+    for (auto iter = last_access_list_.begin(); iter != last_access_list_.end();) {
+        if (iter->keyid == keyid) {
+            iter->access_time = current_time;
+            return true;
+        }
+
+        // Expire entry if possible.
+        assert(current_time >= iter->access_time);
+        if (current_time - iter->access_time >= iter->timeout)
+            iter = last_access_list_.erase(iter);
+        else
+            ++iter;
+    }
+
+    if (last_access_list_.size() >= max_size_) return false;
+
+    AccessTime new_entry;
+    new_entry.keyid = keyid;
+    new_entry.access_time = current_time;
+    new_entry.timeout = timeout;
+    last_access_list_.push_front(new_entry);
+    return true;
+}
+
+bool AccessCountMap::KeyAccessCount(km_id_t keyid, uint32_t* count) const {
+    for (auto& entry : access_count_list_)
+        if (entry.keyid == keyid) {
+            *count = entry.access_count;
+            return true;
+        }
+    return false;
+}
+
+bool AccessCountMap::IncrementKeyAccessCount(km_id_t keyid) {
+    for (auto& entry : access_count_list_)
+        if (entry.keyid == keyid) {
+            // Note that the 'if' below will always be true because KM_TAG_MAX_USES_PER_BOOT is a
+            // uint32_t, and as soon as entry.access_count reaches the specified maximum value
+            // operation requests will be rejected and access_count won't be incremented any more.
+            // And, besides, UINT64_MAX is huge.  But we ensure that it doesn't wrap anyway, out of
+            // an abundance of caution.
+            if (entry.access_count < UINT64_MAX) ++entry.access_count;
+            return true;
+        }
+
+    if (access_count_list_.size() >= max_size_) return false;
+
+    AccessCount new_entry;
+    new_entry.keyid = keyid;
+    new_entry.access_count = 1;
+    access_count_list_.push_front(new_entry);
+    return true;
+}
+}; /* namespace keystore */
diff --git a/keystore/keymaster_enforcement.h b/keystore/keymaster_enforcement.h
new file mode 100644
index 0000000..4f22f01
--- /dev/null
+++ b/keystore/keymaster_enforcement.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef KEYSTORE_KEYMASTER_ENFORCEMENT_H
+#define KEYSTORE_KEYMASTER_ENFORCEMENT_H
+
+#include <stdio.h>
+
+#include <keystore/authorization_set.h>
+
+namespace keystore {
+
+typedef uint64_t km_id_t;
+
+class KeymasterEnforcementContext {
+  public:
+    virtual ~KeymasterEnforcementContext() {}
+    /*
+     * Get current time.
+     */
+};
+
+class AccessTimeMap;
+class AccessCountMap;
+
+class KeymasterEnforcement {
+  public:
+    /**
+     * Construct a KeymasterEnforcement.
+     */
+    KeymasterEnforcement(uint32_t max_access_time_map_size, uint32_t max_access_count_map_size);
+    virtual ~KeymasterEnforcement();
+
+    /**
+     * Iterates through the authorization set and returns the corresponding keymaster error. Will
+     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
+     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
+     */
+    ErrorCode AuthorizeOperation(const KeyPurpose purpose, const km_id_t keyid,
+                                 const AuthorizationSet& auth_set,
+                                 const AuthorizationSet& operation_params, uint64_t op_handle,
+                                 bool is_begin_operation);
+
+    /**
+     * Iterates through the authorization set and returns the corresponding keymaster error. Will
+     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
+     * the given operation params. Used for encrypt, decrypt sign, and verify.
+     */
+    ErrorCode AuthorizeBegin(const KeyPurpose purpose, const km_id_t keyid,
+                             const AuthorizationSet& auth_set,
+                             const AuthorizationSet& operation_params);
+
+    /**
+     * Iterates through the authorization set and returns the corresponding keymaster error. Will
+     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
+     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
+     */
+    ErrorCode AuthorizeUpdate(const AuthorizationSet& auth_set,
+                              const AuthorizationSet& operation_params, uint64_t op_handle) {
+        return AuthorizeUpdateOrFinish(auth_set, operation_params, op_handle);
+    }
+
+    /**
+     * Iterates through the authorization set and returns the corresponding keymaster error. Will
+     * return KM_ERROR_OK if all criteria is met for the given purpose in the authorization set with
+     * the given operation params and handle. Used for encrypt, decrypt sign, and verify.
+     */
+    ErrorCode AuthorizeFinish(const AuthorizationSet& auth_set,
+                              const AuthorizationSet& operation_params, uint64_t op_handle) {
+        return AuthorizeUpdateOrFinish(auth_set, operation_params, op_handle);
+    }
+
+    /**
+     * Creates a key ID for use in subsequent calls to AuthorizeOperation.  Clients needn't use this
+     * method of creating key IDs, as long as they use something consistent and unique.  This method
+     * hashes the key blob.
+     *
+     * Returns false if an error in the crypto library prevents creation of an ID.
+     */
+    static bool CreateKeyId(const hidl_vec<uint8_t>& key_blob, km_id_t* keyid);
+
+    //
+    // Methods that must be implemented by subclasses
+    //
+    // The time-related methods address the fact that different enforcement contexts may have
+    // different time-related capabilities.  In particular:
+    //
+    // - They may or may not be able to check dates against real-world clocks.
+    //
+    // - They may or may not be able to check timestampls against authentication trustlets (minters
+    //   of hw_auth_token_t structs).
+    //
+    // - They must have some time source for relative times, but may not be able to provide more
+    //   than reliability and monotonicity.
+
+    /*
+     * Returns true if the specified activation date has passed, or if activation cannot be
+     * enforced.
+     */
+    virtual bool activation_date_valid(uint64_t activation_date) const = 0;
+
+    /*
+     * Returns true if the specified expiration date has passed.  Returns false if it has not, or if
+     * expiration cannot be enforced.
+     */
+    virtual bool expiration_date_passed(uint64_t expiration_date) const = 0;
+
+    /*
+     * Returns true if the specified auth_token is older than the specified timeout.
+     */
+    virtual bool auth_token_timed_out(const hw_auth_token_t& token, uint32_t timeout) const = 0;
+
+    /*
+     * Get current time in seconds from some starting point.  This value is used to compute relative
+     * times between events.  It must be monotonically increasing, and must not skip or lag.  It
+     * need not have any relation to any external time standard (other than the duration of
+     * "second").
+     *
+     * On POSIX systems, it's recommented to use clock_gettime(CLOCK_MONOTONIC, ...) to implement
+     * this method.
+     */
+    virtual uint32_t get_current_time() const = 0;
+
+    /*
+     * Returns true if the specified auth_token has a valid signature, or if signature validation is
+     * not available.
+     */
+    virtual bool ValidateTokenSignature(const hw_auth_token_t& token) const = 0;
+
+  private:
+    ErrorCode AuthorizeUpdateOrFinish(const AuthorizationSet& auth_set,
+                                      const AuthorizationSet& operation_params, uint64_t op_handle);
+
+    bool MinTimeBetweenOpsPassed(uint32_t min_time_between, const km_id_t keyid);
+    bool MaxUsesPerBootNotExceeded(const km_id_t keyid, uint32_t max_uses);
+    bool AuthTokenMatches(const AuthorizationSet& auth_set,
+                          const AuthorizationSet& operation_params, const uint64_t user_secure_id,
+                          const int auth_type_index, const int auth_timeout_index,
+                          const uint64_t op_handle, bool is_begin_operation) const;
+
+    AccessTimeMap* access_time_map_;
+    AccessCountMap* access_count_map_;
+};
+
+}; /* namespace keystore */
+
+#endif  // KEYSTORE_KEYMASTER_ENFORCEMENT_H
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 0b86e83..3fc9efc 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,15 +27,20 @@
 
 #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)
+using namespace keystore;
+
+KeyStore::KeyStore(Entropy* entropy, const km_device_t& device, const km_device_t& fallback)
     : mEntropy(entropy), mDevice(device), mFallbackDevice(fallback) {
     memset(&mMetaData, '\0', sizeof(mMetaData));
 }
@@ -57,7 +64,7 @@
         writeMetaData();
     }
 
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
 ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
@@ -154,7 +161,7 @@
     android::String8 prefix("");
     android::Vector<android::String16> aliases;
     UserState* userState = getUserState(userId);
-    if (list(prefix, &aliases, userId) != ::NO_ERROR) {
+    if (list(prefix, &aliases, userId) != ResponseCode::NO_ERROR) {
         return;
     }
     for (uint32_t i = 0; i < aliases.size(); i++) {
@@ -172,7 +179,7 @@
              * 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());
+            shouldDelete = !(rc == ResponseCode::NO_ERROR && !blob.isEncrypted());
         }
         if (shouldDelete) {
             del(filename, ::TYPE_ANY, userId);
@@ -236,7 +243,7 @@
     UserState* userState = getUserState(userId);
     ResponseCode rc =
         keyBlob->readBlob(filename, userState->getDecryptionKey(), userState->getState());
-    if (rc != NO_ERROR) {
+    if (rc != ResponseCode::NO_ERROR) {
         return rc;
     }
 
@@ -247,28 +254,25 @@
          * 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) {
+        if (imported == ResponseCode::NO_ERROR) {
             rc = get(filename, keyBlob, TYPE_KEY_PAIR, userId);
         }
     }
@@ -281,7 +285,7 @@
 
     if (type != TYPE_ANY && keyBlob->getType() != type) {
         ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type);
-        return KEY_NOT_FOUND;
+        return ResponseCode::KEY_NOT_FOUND;
     }
 
     return rc;
@@ -296,38 +300,25 @@
 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) {
+    if (keyBlob.getType() == ::TYPE_KEY_PAIR || keyBlob.getType() == ::TYPE_KEYMASTER_10) {
+        auto ret = KS_HANDLE_HIDL_ERROR(mDevice->deleteKey(blob2hidlVec(keyBlob)));
+
         // A device doesn't have to implement delete_key.
-        if (mDevice->delete_key != NULL && !keyBlob.isFallback()) {
-            keymaster_key_blob_t blob = {keyBlob.getValue(),
-                                         static_cast<size_t>(keyBlob.getLength())};
-            if (mDevice->delete_key(mDevice, &blob)) {
-                rc = ::SYSTEM_ERROR;
-            }
-        }
-    }
-    if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
-        auto* dev = getDeviceForBlob(keyBlob);
-        if (dev->delete_key) {
-            keymaster_key_blob_t blob;
-            blob.key_material = keyBlob.getValue();
-            blob.key_material_size = keyBlob.getLength();
-            dev->delete_key(dev, &blob);
-        }
-    }
-    if (rc != ::NO_ERROR) {
-        return rc;
+        if (ret != ErrorCode::OK && ret != ErrorCode::UNIMPLEMENTED)
+            return ResponseCode::SYSTEM_ERROR;
     }
 
-    return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
+    return (unlink(filename) && errno != ENOENT) ?
+            ResponseCode::SYSTEM_ERROR : ResponseCode::NO_ERROR;
 }
 
 /*
@@ -376,7 +367,7 @@
     DIR* dir = opendir(userState->getUserDirName());
     if (!dir) {
         ALOGW("can't open directory for user: %s", strerror(errno));
-        return ::SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     struct dirent* file;
@@ -407,7 +398,7 @@
         }
     }
     closedir(dir);
-    return ::NO_ERROR;
+    return ResponseCode::NO_ERROR;
 }
 
 void KeyStore::addGrant(const char* filename, uid_t granteeUid) {
@@ -436,74 +427,68 @@
                                  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 {
     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);
-    }
+// TODO: This information seems not to be available here
+//    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);
+//    }
+    return true;
 }
 
 ResponseCode KeyStore::getKeyForName(Blob* keyBlob, const android::String8& keyName,
@@ -512,7 +497,7 @@
     uid_t userId = get_user_id(uid);
 
     ResponseCode responseCode = get(filepath8.string(), keyBlob, type, userId);
-    if (responseCode == NO_ERROR) {
+    if (responseCode == ResponseCode::NO_ERROR) {
         return responseCode;
     }
 
@@ -521,7 +506,7 @@
     if (euid != uid) {
         filepath8 = getKeyNameForUidWithDir(keyName, euid, type);
         responseCode = get(filepath8.string(), keyBlob, type, userId);
-        if (responseCode == NO_ERROR) {
+        if (responseCode == ResponseCode::NO_ERROR) {
             return responseCode;
         }
     }
@@ -531,7 +516,7 @@
     char* end;
     strtoul(filename8.string(), &end, 10);
     if (end[0] != '_' || end[1] == 0) {
-        return KEY_NOT_FOUND;
+        return ResponseCode::KEY_NOT_FOUND;
     }
     filepath8 = android::String8::format("%s/%s", getUserState(userId)->getUserDirName(),
                                          filename8.string());
@@ -645,32 +630,32 @@
     Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength()));
     if (b.get() == NULL) {
         ALOGE("Problem instantiating BIO");
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL));
     if (pkey.get() == NULL) {
         ALOGE("Couldn't read old PEM file");
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get()));
     int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL);
     if (len < 0) {
         ALOGE("Couldn't measure PKCS#8 length");
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]);
     uint8_t* tmp = pkcs8key.get();
     if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) {
         ALOGE("Couldn't convert to PKCS#8");
-        return SYSTEM_ERROR;
+        return ResponseCode::SYSTEM_ERROR;
     }
 
     ResponseCode rc = importKey(pkcs8key.get(), len, filename, get_user_id(uid),
                                 blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
-    if (rc != NO_ERROR) {
+    if (rc != ResponseCode::NO_ERROR) {
         return rc;
     }
 
diff --git a/keystore/keystore.h b/keystore/keystore.h
index 278a0a0..210d99d 100644
--- a/keystore/keystore.h
+++ b/keystore/keystore.h
@@ -19,7 +19,7 @@
 
 #include "user_state.h"
 
-#include <hardware/keymaster2.h>
+#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
 
 #include <utils/Vector.h>
 
@@ -31,15 +31,17 @@
 } grant_t;
 
 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);
     ~KeyStore();
 
-    keymaster2_device_t* getDevice() const { return mDevice; }
+    km_device_t& getDevice() { return mDevice; }
 
-    keymaster2_device_t* getFallbackDevice() const { return mFallbackDevice; }
+    km_device_t& getFallbackDevice() { return mFallbackDevice; }
 
-    keymaster2_device_t* getDeviceForBlob(const Blob& blob) const {
+    km_device_t& getDevice(const Blob& blob) {
         return blob.isFallback() ? mFallbackDevice : mDevice;
     }
 
@@ -115,8 +117,8 @@
     static const android::String16 sRSAKeyType;
     Entropy* mEntropy;
 
-    keymaster2_device_t* mDevice;
-    keymaster2_device_t* mFallbackDevice;
+    km_device_t mDevice;
+    km_device_t mFallbackDevice;
 
     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_cli.cpp b/keystore/keystore_cli.cpp
index d9781e0..24af024 100644
--- a/keystore/keystore_cli.cpp
+++ b/keystore/keystore_cli.cpp
@@ -26,6 +26,7 @@
 #include <keystore/keystore.h>
 
 using namespace android;
+using namespace keystore;
 
 static const char* responses[] = {
     NULL,
@@ -124,14 +125,13 @@
                 fprintf(stderr, "Usage: %s " #cmd " <name> <uid>\n", argv[0]); \
                 return 1; \
             } \
-            uint8_t* data; \
-            size_t dataSize; \
+            hidl_vec<uint8_t> data; \
             int uid = -1; \
             if (argc > 3) { \
                 uid = atoi(argv[3]); \
                 fprintf(stderr, "Running as uid %d\n", uid); \
             } \
-            int32_t ret = service->cmd(String16(argv[2]), uid, &data, &dataSize); \
+            int32_t ret = service->cmd(String16(argv[2]), uid, &data); \
             if (ret < 0) { \
                 fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
                 return 1; \
@@ -139,9 +139,8 @@
                 fprintf(stderr, "%s: " #cmd ": %s (%d)\n", argv[0], responses[ret], ret); \
                 return 1; \
             } else { \
-                fwrite(data, dataSize, 1, stdout); \
+                fwrite(&data[0], data.size(), 1, stdout); \
                 fflush(stdout); \
-                free(data); \
                 return 0; \
             } \
         } \
@@ -175,9 +174,8 @@
                 fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
                 return 1; \
             } \
-            uint8_t* data; \
-            size_t dataSize; \
-            int32_t ret = service->cmd(String16(argv[2]), &data, &dataSize); \
+            hidl_vec<uint8_t> data; \
+            int32_t ret = service->cmd(String16(argv[2]), &data); \
             if (ret < 0) { \
                 fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
                 return 1; \
@@ -185,9 +183,8 @@
                 fprintf(stderr, "%s: " #cmd ": %s (%d)\n", argv[0], responses[ret], ret); \
                 return 1; \
             } else { \
-                fwrite(data, dataSize, 1, stdout); \
+                fwrite(&data[0], data.size(), 1, stdout); \
                 fflush(stdout); \
-                free(data); \
                 return 0; \
             } \
         } \
diff --git a/keystore/keystore_cli_v2.cpp b/keystore/keystore_cli_v2.cpp
index 6c229db..95fc491 100644
--- a/keystore/keystore_cli_v2.cpp
+++ b/keystore/keystore_cli_v2.cpp
@@ -20,16 +20,17 @@
 #include "base/command_line.h"
 #include "base/files/file_util.h"
 #include "base/strings/string_util.h"
-#include "keymaster/authorization_set.h"
-#include "keymaster/keymaster_tags.h"
+#include "keystore/authorization_set.h"
+#include "keystore/keymaster_tags.h"
 #include "keystore/keystore_client_impl.h"
 
 using base::CommandLine;
-using keymaster::AuthorizationSet;
-using keymaster::AuthorizationSetBuilder;
+using keystore::AuthorizationSet;
+//using keymaster::AuthorizationSetBuilder;
 using keystore::KeystoreClient;
 
 namespace {
+using namespace keystore;
 
 struct TestCase {
     std::string name;
@@ -55,17 +56,13 @@
 }
 
 std::unique_ptr<KeystoreClient> CreateKeystoreInstance() {
-    return std::unique_ptr<KeystoreClient>(new keystore::KeystoreClientImpl);
+    return std::unique_ptr<KeystoreClient>(
+            static_cast<KeystoreClient*>(new keystore::KeystoreClientImpl));
 }
 
-#ifndef KEYMASTER_NAME_TAGS
-#error KEYMASTER_NAME_TAGS must be defined
-#endif
-
 void PrintTags(const AuthorizationSet& parameters) {
-    const keymaster_key_param_t* iter = nullptr;
-    for (iter = parameters.begin(); iter != parameters.end(); ++iter) {
-        printf("  %s\n", keymaster::StringifyTag(iter->tag));
+    for (auto iter = parameters.begin(); iter != parameters.end(); ++iter) {
+        printf("  %s\n", stringifyTag(iter->tag));
     }
 }
 
@@ -81,16 +78,16 @@
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    int32_t result = keystore->generateKey("tmp", parameters, &hardware_enforced_characteristics,
+    auto result = keystore->generateKey("tmp", parameters, &hardware_enforced_characteristics,
                                            &software_enforced_characteristics);
     const char kBoldRedAbort[] = "\033[1;31mABORT\033[0m";
-    if (result != KM_ERROR_OK) {
+    if (!result.isOk()) {
         LOG(ERROR) << "Failed to generate key: " << result;
         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
         return false;
     }
     result = keystore->deleteKey("tmp");
-    if (result != KM_ERROR_OK) {
+    if (!result.isOk()) {
         LOG(ERROR) << "Failed to delete key: " << result;
         printf("[%s] %s\n", kBoldRedAbort, name.c_str());
         return false;
@@ -99,9 +96,9 @@
     printf("%s Key Characteristics:\n", name.c_str());
     PrintKeyCharacteristics(hardware_enforced_characteristics, software_enforced_characteristics);
     bool hardware_backed = (hardware_enforced_characteristics.size() > 0);
-    if (software_enforced_characteristics.GetTagCount(KM_TAG_ALGORITHM) > 0 ||
-        software_enforced_characteristics.GetTagCount(KM_TAG_KEY_SIZE) > 0 ||
-        software_enforced_characteristics.GetTagCount(KM_TAG_RSA_PUBLIC_EXPONENT) > 0) {
+    if (software_enforced_characteristics.GetTagCount(TAG_ALGORITHM) > 0 ||
+        software_enforced_characteristics.GetTagCount(TAG_KEY_SIZE) > 0 ||
+        software_enforced_characteristics.GetTagCount(TAG_RSA_PUBLIC_EXPONENT) > 0) {
         VLOG(1) << "Hardware-backed key but required characteristics enforced in software.";
         hardware_backed = false;
     }
@@ -118,62 +115,62 @@
 AuthorizationSet GetRSASignParameters(uint32_t key_size, bool sha256_only) {
     AuthorizationSetBuilder parameters;
     parameters.RsaSigningKey(key_size, 65537)
-        .Digest(KM_DIGEST_SHA_2_256)
-        .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)
-        .Padding(KM_PAD_RSA_PSS)
-        .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+        .Digest(Digest::SHA_2_256)
+        .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
+        .Padding(PaddingMode::RSA_PSS)
+        .Authorization(TAG_NO_AUTH_REQUIRED);
     if (!sha256_only) {
-        parameters.Digest(KM_DIGEST_SHA_2_224)
-            .Digest(KM_DIGEST_SHA_2_384)
-            .Digest(KM_DIGEST_SHA_2_512);
+        parameters.Digest(Digest::SHA_2_224)
+            .Digest(Digest::SHA_2_384)
+            .Digest(Digest::SHA_2_512);
     }
-    return parameters.build();
+    return parameters;
 }
 
 AuthorizationSet GetRSAEncryptParameters(uint32_t key_size) {
     AuthorizationSetBuilder parameters;
     parameters.RsaEncryptionKey(key_size, 65537)
-        .Padding(KM_PAD_RSA_PKCS1_1_5_ENCRYPT)
-        .Padding(KM_PAD_RSA_OAEP)
-        .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
-    return parameters.build();
+        .Padding(PaddingMode::RSA_PKCS1_1_5_ENCRYPT)
+        .Padding(PaddingMode::RSA_OAEP)
+        .Authorization(TAG_NO_AUTH_REQUIRED);
+    return parameters;
 }
 
 AuthorizationSet GetECDSAParameters(uint32_t key_size, bool sha256_only) {
     AuthorizationSetBuilder parameters;
     parameters.EcdsaSigningKey(key_size)
-        .Digest(KM_DIGEST_SHA_2_256)
-        .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+        .Digest(Digest::SHA_2_256)
+        .Authorization(TAG_NO_AUTH_REQUIRED);
     if (!sha256_only) {
-        parameters.Digest(KM_DIGEST_SHA_2_224)
-            .Digest(KM_DIGEST_SHA_2_384)
-            .Digest(KM_DIGEST_SHA_2_512);
+        parameters.Digest(Digest::SHA_2_224)
+            .Digest(Digest::SHA_2_384)
+            .Digest(Digest::SHA_2_512);
     }
-    return parameters.build();
+    return parameters;
 }
 
 AuthorizationSet GetAESParameters(uint32_t key_size, bool with_gcm_mode) {
     AuthorizationSetBuilder parameters;
-    parameters.AesEncryptionKey(key_size).Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+    parameters.AesEncryptionKey(key_size).Authorization(TAG_NO_AUTH_REQUIRED);
     if (with_gcm_mode) {
-        parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_GCM)
-            .Authorization(keymaster::TAG_MIN_MAC_LENGTH, 128);
+        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::GCM)
+            .Authorization(TAG_MIN_MAC_LENGTH, 128);
     } else {
-        parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_ECB);
-        parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CBC);
-        parameters.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CTR);
-        parameters.Padding(KM_PAD_NONE);
+        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
+        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
+        parameters.Authorization(TAG_BLOCK_MODE, BlockMode::CTR);
+        parameters.Padding(PaddingMode::NONE);
     }
-    return parameters.build();
+    return parameters;
 }
 
-AuthorizationSet GetHMACParameters(uint32_t key_size, keymaster_digest_t digest) {
+AuthorizationSet GetHMACParameters(uint32_t key_size, Digest digest) {
     AuthorizationSetBuilder parameters;
     parameters.HmacKey(key_size)
         .Digest(digest)
-        .Authorization(keymaster::TAG_MIN_MAC_LENGTH, 224)
-        .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
-    return parameters.build();
+        .Authorization(TAG_MIN_MAC_LENGTH, 224)
+        .Authorization(TAG_NO_AUTH_REQUIRED);
+    return parameters;
 }
 
 std::vector<TestCase> GetTestCases() {
@@ -194,12 +191,12 @@
         {"AES-256", true, GetAESParameters(256, false)},
         {"AES-128-GCM", false, GetAESParameters(128, true)},
         {"AES-256-GCM", false, GetAESParameters(256, true)},
-        {"HMAC-SHA256-16", true, GetHMACParameters(16, KM_DIGEST_SHA_2_256)},
-        {"HMAC-SHA256-32", true, GetHMACParameters(32, KM_DIGEST_SHA_2_256)},
-        {"HMAC-SHA256-64", false, GetHMACParameters(64, KM_DIGEST_SHA_2_256)},
-        {"HMAC-SHA224-32", false, GetHMACParameters(32, KM_DIGEST_SHA_2_224)},
-        {"HMAC-SHA384-32", false, GetHMACParameters(32, KM_DIGEST_SHA_2_384)},
-        {"HMAC-SHA512-32", false, GetHMACParameters(32, KM_DIGEST_SHA_2_512)},
+        {"HMAC-SHA256-16", true, GetHMACParameters(16, Digest::SHA_2_256)},
+        {"HMAC-SHA256-32", true, GetHMACParameters(32, Digest::SHA_2_256)},
+        {"HMAC-SHA256-64", false, GetHMACParameters(64, Digest::SHA_2_256)},
+        {"HMAC-SHA224-32", false, GetHMACParameters(32, Digest::SHA_2_224)},
+        {"HMAC-SHA384-32", false, GetHMACParameters(32, Digest::SHA_2_384)},
+        {"HMAC-SHA512-32", false, GetHMACParameters(32, Digest::SHA_2_512)},
     };
     return std::vector<TestCase>(&test_cases[0], &test_cases[arraysize(test_cases)]);
 }
@@ -273,19 +270,19 @@
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSetBuilder params;
     params.RsaSigningKey(2048, 65537)
-        .Digest(KM_DIGEST_SHA_2_224)
-        .Digest(KM_DIGEST_SHA_2_256)
-        .Digest(KM_DIGEST_SHA_2_384)
-        .Digest(KM_DIGEST_SHA_2_512)
-        .Padding(KM_PAD_RSA_PKCS1_1_5_SIGN)
-        .Padding(KM_PAD_RSA_PSS)
-        .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+        .Digest(Digest::SHA_2_224)
+        .Digest(Digest::SHA_2_256)
+        .Digest(Digest::SHA_2_384)
+        .Digest(Digest::SHA_2_512)
+        .Padding(PaddingMode::RSA_PKCS1_1_5_SIGN)
+        .Padding(PaddingMode::RSA_PSS)
+        .Authorization(TAG_NO_AUTH_REQUIRED);
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    int32_t result = keystore->generateKey(name, params.build(), &hardware_enforced_characteristics,
+    auto result = keystore->generateKey(name, params, &hardware_enforced_characteristics,
                                            &software_enforced_characteristics);
-    printf("GenerateKey: %d\n", result);
-    if (result == KM_ERROR_OK) {
+    printf("GenerateKey: %d\n", int32_t(result));
+    if (result.isOk()) {
         PrintKeyCharacteristics(hardware_enforced_characteristics,
                                 software_enforced_characteristics);
     }
@@ -296,10 +293,10 @@
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    int32_t result = keystore->getKeyCharacteristics(name, &hardware_enforced_characteristics,
+    auto result = keystore->getKeyCharacteristics(name, &hardware_enforced_characteristics,
                                                      &software_enforced_characteristics);
-    printf("GetCharacteristics: %d\n", result);
-    if (result == KM_ERROR_OK) {
+    printf("GetCharacteristics: %d\n", int32_t(result));
+    if (result.isOk()) {
         PrintKeyCharacteristics(hardware_enforced_characteristics,
                                 software_enforced_characteristics);
     }
@@ -309,7 +306,7 @@
 int ExportKey(const std::string& name) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     std::string data;
-    int32_t result = keystore->exportKey(KM_KEY_FORMAT_X509, name, &data);
+    int32_t result = keystore->exportKey(KeyFormat::X509, name, &data);
     printf("ExportKey: %d (%zu)\n", result, data.size());
     return result;
 }
@@ -351,14 +348,14 @@
 int SignAndVerify(const std::string& name) {
     std::unique_ptr<KeystoreClient> keystore = CreateKeystoreInstance();
     AuthorizationSetBuilder sign_params;
-    sign_params.Padding(KM_PAD_RSA_PKCS1_1_5_SIGN);
-    sign_params.Digest(KM_DIGEST_SHA_2_256);
+    sign_params.Padding(PaddingMode::RSA_PKCS1_1_5_SIGN);
+    sign_params.Digest(Digest::SHA_2_256);
     AuthorizationSet output_params;
-    keymaster_operation_handle_t handle;
-    int32_t result = keystore->beginOperation(KM_PURPOSE_SIGN, name, sign_params.build(),
+    uint64_t handle;
+    auto result = keystore->beginOperation(KeyPurpose::SIGN, name, sign_params,
                                               &output_params, &handle);
-    if (result != KM_ERROR_OK) {
-        printf("Sign: BeginOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Sign: BeginOperation failed: %d\n", int32_t(result));
         return result;
     }
     AuthorizationSet empty_params;
@@ -366,40 +363,40 @@
     std::string output_data;
     result = keystore->updateOperation(handle, empty_params, "data_to_sign",
                                        &num_input_bytes_consumed, &output_params, &output_data);
-    if (result != KM_ERROR_OK) {
-        printf("Sign: UpdateOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Sign: UpdateOperation failed: %d\n", int32_t(result));
         return result;
     }
     result = keystore->finishOperation(handle, empty_params, std::string() /*signature_to_verify*/,
                                        &output_params, &output_data);
-    if (result != KM_ERROR_OK) {
-        printf("Sign: FinishOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Sign: FinishOperation failed: %d\n", int32_t(result));
         return result;
     }
     printf("Sign: %zu bytes.\n", output_data.size());
     // We have a signature, now verify it.
     std::string signature_to_verify = output_data;
     output_data.clear();
-    result = keystore->beginOperation(KM_PURPOSE_VERIFY, name, sign_params.build(), &output_params,
+    result = keystore->beginOperation(KeyPurpose::VERIFY, name, sign_params, &output_params,
                                       &handle);
-    if (result != KM_ERROR_OK) {
-        printf("Verify: BeginOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Verify: BeginOperation failed: %d\n", int32_t(result));
         return result;
     }
     result = keystore->updateOperation(handle, empty_params, "data_to_sign",
                                        &num_input_bytes_consumed, &output_params, &output_data);
-    if (result != KM_ERROR_OK) {
-        printf("Verify: UpdateOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Verify: UpdateOperation failed: %d\n", int32_t(result));
         return result;
     }
     result = keystore->finishOperation(handle, empty_params, signature_to_verify, &output_params,
                                        &output_data);
-    if (result == KM_ERROR_VERIFICATION_FAILED) {
+    if (result == ErrorCode::VERIFICATION_FAILED) {
         printf("Verify: Failed to verify signature.\n");
         return result;
     }
-    if (result != KM_ERROR_OK) {
-        printf("Verify: FinishOperation failed: %d\n", result);
+    if (!result.isOk()) {
+        printf("Verify: FinishOperation failed: %d\n", int32_t(result));
         return result;
     }
     printf("Verify: OK\n");
diff --git a/keystore/keystore_client_impl.cpp b/keystore/keystore_client_impl.cpp
index c3d8f35..f9df134 100644
--- a/keystore/keystore_client_impl.cpp
+++ b/keystore/keystore_client_impl.cpp
@@ -19,24 +19,25 @@
 #include <string>
 #include <vector>
 
-#include "binder/IBinder.h"
-#include "binder/IInterface.h"
-#include "binder/IServiceManager.h"
-#include "keystore/IKeystoreService.h"
-#include "keystore/keystore.h"
-#include "log/log.h"
-#include "utils/String16.h"
-#include "utils/String8.h"
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <binder/IServiceManager.h>
+#include <keystore/IKeystoreService.h>
+#include <keystore/keystore.h>
+#include <log/log.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
 
 #include "keystore_client.pb.h"
+#include <keystore/authorization_set.h>
+#include <keystore/keystore_hidl_support.h>
 
 using android::ExportResult;
-using android::KeyCharacteristics;
-using android::KeymasterArguments;
+using keystore::KeyCharacteristics;
 using android::OperationResult;
 using android::String16;
-using keymaster::AuthorizationSet;
-using keymaster::AuthorizationSetBuilder;
+using keystore::AuthorizationSet;
+using keystore::AuthorizationSetBuilder;
 
 namespace {
 
@@ -44,24 +45,9 @@
 const int kDefaultUID = -1;
 const char kEncryptSuffix[] = "_ENC";
 const char kAuthenticateSuffix[] = "_AUTH";
-const uint32_t kAESKeySize = 256;      // bits
-const uint32_t kHMACKeySize = 256;     // bits
-const uint32_t kHMACOutputSize = 256;  // bits
-
-const uint8_t* StringAsByteArray(const std::string& s) {
-    return reinterpret_cast<const uint8_t*>(s.data());
-}
-
-std::string ByteArrayAsString(const uint8_t* data, size_t data_size) {
-    return std::string(reinterpret_cast<const char*>(data), data_size);
-}
-
-void CopyParameters(const AuthorizationSet& in, std::vector<keymaster_key_param_t>* out) {
-  keymaster_key_param_set_t tmp;
-  in.CopyToParamSet(&tmp);
-  out->assign(&tmp.params[0], &tmp.params[tmp.length]);
-  free(tmp.params);
-}
+constexpr uint32_t kAESKeySize = 256;      // bits
+constexpr uint32_t kHMACKeySize = 256;     // bits
+constexpr uint32_t kHMACOutputSize = 256;  // bits
 
 }  // namespace
 
@@ -89,29 +75,28 @@
         return false;
     }
     AuthorizationSetBuilder encrypt_params;
-    encrypt_params.Padding(KM_PAD_PKCS7);
-    encrypt_params.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CBC);
+    encrypt_params.Padding(PaddingMode::PKCS7);
+    encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
     AuthorizationSet output_params;
     std::string raw_encrypted_data;
-    if (!oneShotOperation(KM_PURPOSE_ENCRYPT, encryption_key_name, encrypt_params.build(), data,
+    if (!oneShotOperation(KeyPurpose::ENCRYPT, encryption_key_name, encrypt_params, data,
                           std::string(), /* signature_to_verify */
                           &output_params, &raw_encrypted_data)) {
         ALOGE("Encrypt: AES operation failed.");
         return false;
     }
-    keymaster_blob_t init_vector_blob;
-    if (!output_params.GetTagValue(keymaster::TAG_NONCE, &init_vector_blob)) {
+    auto init_vector_blob = output_params.GetTagValue(TAG_NONCE);
+    if (!init_vector_blob.isOk()){
         ALOGE("Encrypt: Missing initialization vector.");
         return false;
     }
-    std::string init_vector =
-        ByteArrayAsString(init_vector_blob.data, init_vector_blob.data_length);
+    std::string init_vector = hidlVec2String(init_vector_blob.value());
 
     AuthorizationSetBuilder authenticate_params;
-    authenticate_params.Digest(KM_DIGEST_SHA_2_256);
-    authenticate_params.Authorization(keymaster::TAG_MAC_LENGTH, kHMACOutputSize);
+    authenticate_params.Digest(Digest::SHA_2_256);
+    authenticate_params.Authorization(TAG_MAC_LENGTH, kHMACOutputSize);
     std::string raw_authentication_data;
-    if (!oneShotOperation(KM_PURPOSE_SIGN, authentication_key_name, authenticate_params.build(),
+    if (!oneShotOperation(KeyPurpose::SIGN, authentication_key_name, authenticate_params,
                           init_vector + raw_encrypted_data, std::string(), /* signature_to_verify */
                           &output_params, &raw_authentication_data)) {
         ALOGE("Encrypt: HMAC operation failed.");
@@ -138,10 +123,10 @@
     // Verify authentication before attempting decryption.
     std::string authentication_key_name = key_name + kAuthenticateSuffix;
     AuthorizationSetBuilder authenticate_params;
-    authenticate_params.Digest(KM_DIGEST_SHA_2_256);
+    authenticate_params.Digest(Digest::SHA_2_256);
     AuthorizationSet output_params;
     std::string output_data;
-    if (!oneShotOperation(KM_PURPOSE_VERIFY, authentication_key_name, authenticate_params.build(),
+    if (!oneShotOperation(KeyPurpose::VERIFY, authentication_key_name, authenticate_params,
                           protobuf.init_vector() + protobuf.encrypted_data(),
                           protobuf.authentication_data(), &output_params, &output_data)) {
         ALOGE("Decrypt: HMAC operation failed.");
@@ -149,11 +134,11 @@
     }
     std::string encryption_key_name = key_name + kEncryptSuffix;
     AuthorizationSetBuilder encrypt_params;
-    encrypt_params.Padding(KM_PAD_PKCS7);
-    encrypt_params.Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CBC);
-    encrypt_params.Authorization(keymaster::TAG_NONCE, protobuf.init_vector().data(),
+    encrypt_params.Padding(PaddingMode::PKCS7);
+    encrypt_params.Authorization(TAG_BLOCK_MODE, BlockMode::CBC);
+    encrypt_params.Authorization(TAG_NONCE, protobuf.init_vector().data(),
                                  protobuf.init_vector().size());
-    if (!oneShotOperation(KM_PURPOSE_DECRYPT, encryption_key_name, encrypt_params.build(),
+    if (!oneShotOperation(KeyPurpose::DECRYPT, encryption_key_name, encrypt_params,
                           protobuf.encrypted_data(), std::string(), /* signature_to_verify */
                           &output_params, data)) {
         ALOGE("Decrypt: AES operation failed.");
@@ -162,17 +147,17 @@
     return true;
 }
 
-bool KeystoreClientImpl::oneShotOperation(keymaster_purpose_t purpose, const std::string& key_name,
-                                          const keymaster::AuthorizationSet& input_parameters,
+bool KeystoreClientImpl::oneShotOperation(KeyPurpose purpose, const std::string& key_name,
+                                          const AuthorizationSet& input_parameters,
                                           const std::string& input_data,
                                           const std::string& signature_to_verify,
-                                          keymaster::AuthorizationSet* output_parameters,
+                                          AuthorizationSet* output_parameters,
                                           std::string* output_data) {
-    keymaster_operation_handle_t handle;
-    int32_t result =
+    uint64_t handle;
+    auto result =
         beginOperation(purpose, key_name, input_parameters, output_parameters, &handle);
-    if (result != KM_ERROR_OK) {
-        ALOGE("BeginOperation failed: %d", result);
+    if (!result.isOk()) {
+        ALOGE("BeginOperation failed: %d", int32_t(result));
         return false;
     }
     AuthorizationSet empty_params;
@@ -180,174 +165,172 @@
     AuthorizationSet ignored_params;
     result = updateOperation(handle, empty_params, input_data, &num_input_bytes_consumed,
                              &ignored_params, output_data);
-    if (result != KM_ERROR_OK) {
-        ALOGE("UpdateOperation failed: %d", result);
+    if (!result.isOk()) {
+        ALOGE("UpdateOperation failed: %d", int32_t(result));
         return false;
     }
     result =
         finishOperation(handle, empty_params, signature_to_verify, &ignored_params, output_data);
-    if (result != KM_ERROR_OK) {
-        ALOGE("FinishOperation failed: %d", result);
+    if (!result.isOk()) {
+        ALOGE("FinishOperation failed: %d", int32_t(result));
         return false;
     }
     return true;
 }
 
-int32_t KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy) {
-    return mapKeystoreError(keystore_->addRngEntropy(StringAsByteArray(entropy), entropy.size()));
+KeyStoreNativeReturnCode KeystoreClientImpl::addRandomNumberGeneratorEntropy(const std::string& entropy) {
+    return keystore_->addRngEntropy(blob2hidlVec(entropy));
 }
 
-int32_t KeystoreClientImpl::generateKey(const std::string& key_name,
+KeyStoreNativeReturnCode KeystoreClientImpl::generateKey(const std::string& key_name,
                                         const AuthorizationSet& key_parameters,
                                         AuthorizationSet* hardware_enforced_characteristics,
                                         AuthorizationSet* software_enforced_characteristics) {
     String16 key_name16(key_name.data(), key_name.size());
-    KeymasterArguments key_arguments;
-    CopyParameters(key_parameters, &key_arguments.params);
     KeyCharacteristics characteristics;
-    int32_t result =
-        keystore_->generateKey(key_name16, key_arguments, NULL /*entropy*/, 0 /*entropyLength*/,
+    auto result =
+        keystore_->generateKey(key_name16, key_parameters.hidl_data(), hidl_vec<uint8_t>(),
                                kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics);
-    hardware_enforced_characteristics->Reinitialize(characteristics.characteristics.hw_enforced);
-    software_enforced_characteristics->Reinitialize(characteristics.characteristics.sw_enforced);
-    return mapKeystoreError(result);
+
+    /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
+     * There are no references to Parcel memory after that, and ownership of the newly acquired
+     * memory is with the AuthorizationSet objects. */
+    *hardware_enforced_characteristics = characteristics.teeEnforced;
+    *software_enforced_characteristics = characteristics.softwareEnforced;
+    return result;
 }
 
-int32_t
+KeyStoreNativeReturnCode
 KeystoreClientImpl::getKeyCharacteristics(const std::string& key_name,
                                           AuthorizationSet* hardware_enforced_characteristics,
                                           AuthorizationSet* software_enforced_characteristics) {
     String16 key_name16(key_name.data(), key_name.size());
-    keymaster_blob_t client_id_blob = {nullptr, 0};
-    keymaster_blob_t app_data_blob = {nullptr, 0};
     KeyCharacteristics characteristics;
-    int32_t result = keystore_->getKeyCharacteristics(key_name16, &client_id_blob, &app_data_blob,
+    auto result = keystore_->getKeyCharacteristics(key_name16, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(),
                                                       kDefaultUID, &characteristics);
-    hardware_enforced_characteristics->Reinitialize(characteristics.characteristics.hw_enforced);
-    software_enforced_characteristics->Reinitialize(characteristics.characteristics.sw_enforced);
-    return mapKeystoreError(result);
+
+    /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
+     * There are no references to Parcel memory after that, and ownership of the newly acquired
+     * memory is with the AuthorizationSet objects. */
+    *hardware_enforced_characteristics = characteristics.teeEnforced;
+    *software_enforced_characteristics = characteristics.softwareEnforced;
+    return result;
 }
 
-int32_t KeystoreClientImpl::importKey(const std::string& key_name,
+KeyStoreNativeReturnCode KeystoreClientImpl::importKey(const std::string& key_name,
                                       const AuthorizationSet& key_parameters,
-                                      keymaster_key_format_t key_format,
+                                      KeyFormat key_format,
                                       const std::string& key_data,
                                       AuthorizationSet* hardware_enforced_characteristics,
                                       AuthorizationSet* software_enforced_characteristics) {
     String16 key_name16(key_name.data(), key_name.size());
-    KeymasterArguments key_arguments;
-    CopyParameters(key_parameters, &key_arguments.params);
+    auto hidlKeyData = blob2hidlVec(key_data);
     KeyCharacteristics characteristics;
-    int32_t result =
-        keystore_->importKey(key_name16, key_arguments, key_format, StringAsByteArray(key_data),
-                             key_data.size(), kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics);
-    hardware_enforced_characteristics->Reinitialize(characteristics.characteristics.hw_enforced);
-    software_enforced_characteristics->Reinitialize(characteristics.characteristics.sw_enforced);
-    return mapKeystoreError(result);
+    auto result = keystore_->importKey(key_name16, key_parameters.hidl_data(), key_format,
+            hidlKeyData, kDefaultUID, KEYSTORE_FLAG_NONE, &characteristics);
+
+    /* assignment (hidl_vec<KeyParameter> -> AuthorizationSet) makes a deep copy.
+     * There are no references to Parcel memory after that, and ownership of the newly acquired
+     * memory is with the AuthorizationSet objects. */
+    *hardware_enforced_characteristics = characteristics.teeEnforced;
+    *software_enforced_characteristics = characteristics.softwareEnforced;
+    return result;
 }
 
-int32_t KeystoreClientImpl::exportKey(keymaster_key_format_t export_format,
+KeyStoreNativeReturnCode KeystoreClientImpl::exportKey(KeyFormat export_format,
                                       const std::string& key_name, std::string* export_data) {
     String16 key_name16(key_name.data(), key_name.size());
-    keymaster_blob_t client_id_blob = {nullptr, 0};
-    keymaster_blob_t app_data_blob = {nullptr, 0};
     ExportResult export_result;
-    keystore_->exportKey(key_name16, export_format, &client_id_blob, &app_data_blob,
+    keystore_->exportKey(key_name16, export_format, hidl_vec<uint8_t>(), hidl_vec<uint8_t>(),
                          kDefaultUID, &export_result);
-    *export_data = ByteArrayAsString(export_result.exportData.get(), export_result.dataLength);
-    return mapKeystoreError(export_result.resultCode);
+    *export_data = hidlVec2String(export_result.exportData);
+    return export_result.resultCode;
 }
 
-int32_t KeystoreClientImpl::deleteKey(const std::string& key_name) {
+KeyStoreNativeReturnCode KeystoreClientImpl::deleteKey(const std::string& key_name) {
     String16 key_name16(key_name.data(), key_name.size());
-    return mapKeystoreError(keystore_->del(key_name16, kDefaultUID));
+    return keystore_->del(key_name16, kDefaultUID);
 }
 
-int32_t KeystoreClientImpl::deleteAllKeys() {
-    return mapKeystoreError(keystore_->clear_uid(kDefaultUID));
+KeyStoreNativeReturnCode KeystoreClientImpl::deleteAllKeys() {
+    return keystore_->clear_uid(kDefaultUID);
 }
 
-int32_t KeystoreClientImpl::beginOperation(keymaster_purpose_t purpose, const std::string& key_name,
+KeyStoreNativeReturnCode KeystoreClientImpl::beginOperation(KeyPurpose purpose, const std::string& key_name,
                                            const AuthorizationSet& input_parameters,
                                            AuthorizationSet* output_parameters,
-                                           keymaster_operation_handle_t* handle) {
+                                           uint64_t* handle) {
     android::sp<android::IBinder> token(new android::BBinder);
     String16 key_name16(key_name.data(), key_name.size());
-    KeymasterArguments input_arguments;
-    CopyParameters(input_parameters, &input_arguments.params);
     OperationResult result;
-    keystore_->begin(token, key_name16, purpose, true /*pruneable*/, input_arguments,
-                     NULL /*entropy*/, 0 /*entropyLength*/, kDefaultUID, &result);
-    int32_t error_code = mapKeystoreError(result.resultCode);
-    if (error_code == KM_ERROR_OK) {
+    keystore_->begin(token, key_name16, purpose, true /*pruneable*/, input_parameters.hidl_data(),
+                     hidl_vec<uint8_t>(), kDefaultUID, &result);
+    if (result.resultCode.isOk()) {
         *handle = getNextVirtualHandle();
         active_operations_[*handle] = result.token;
-        if (!result.outParams.params.empty()) {
-            output_parameters->Reinitialize(&*result.outParams.params.begin(),
-                                            result.outParams.params.size());
+        if (result.outParams.size()) {
+            *output_parameters = result.outParams;
         }
     }
-    return error_code;
+    return result.resultCode;
 }
 
-int32_t KeystoreClientImpl::updateOperation(keymaster_operation_handle_t handle,
+KeyStoreNativeReturnCode KeystoreClientImpl::updateOperation(uint64_t handle,
                                             const AuthorizationSet& input_parameters,
                                             const std::string& input_data,
                                             size_t* num_input_bytes_consumed,
                                             AuthorizationSet* output_parameters,
                                             std::string* output_data) {
     if (active_operations_.count(handle) == 0) {
-        return KM_ERROR_INVALID_OPERATION_HANDLE;
+        return ErrorCode::INVALID_OPERATION_HANDLE;
     }
-    KeymasterArguments input_arguments;
-    CopyParameters(input_parameters, &input_arguments.params);
     OperationResult result;
-    keystore_->update(active_operations_[handle], input_arguments, StringAsByteArray(input_data),
-                      input_data.size(), &result);
-    int32_t error_code = mapKeystoreError(result.resultCode);
-    if (error_code == KM_ERROR_OK) {
+    auto hidlInputData = blob2hidlVec(input_data);
+    keystore_->update(active_operations_[handle], input_parameters.hidl_data(), hidlInputData,
+            &result);
+
+    if (result.resultCode.isOk()) {
         *num_input_bytes_consumed = result.inputConsumed;
-        if (!result.outParams.params.empty()) {
-            output_parameters->Reinitialize(&*result.outParams.params.begin(),
-                                            result.outParams.params.size());
+        if (result.outParams.size()) {
+            *output_parameters = result.outParams;
         }
-        output_data->append(ByteArrayAsString(result.data.get(), result.dataLength));
+        // TODO verify that append should not be assign
+        output_data->append(hidlVec2String(result.data));
     }
-    return error_code;
+    return result.resultCode;
 }
 
-int32_t KeystoreClientImpl::finishOperation(keymaster_operation_handle_t handle,
+KeyStoreNativeReturnCode KeystoreClientImpl::finishOperation(uint64_t handle,
                                             const AuthorizationSet& input_parameters,
                                             const std::string& signature_to_verify,
                                             AuthorizationSet* output_parameters,
                                             std::string* output_data) {
     if (active_operations_.count(handle) == 0) {
-        return KM_ERROR_INVALID_OPERATION_HANDLE;
+        return ErrorCode::INVALID_OPERATION_HANDLE;
     }
-    KeymasterArguments input_arguments;
-    CopyParameters(input_parameters, &input_arguments.params);
     OperationResult result;
-    keystore_->finish(active_operations_[handle], input_arguments,
-                      StringAsByteArray(signature_to_verify), signature_to_verify.size(),
-                      NULL /*entropy*/, 0 /*entropyLength*/, &result);
-    int32_t error_code = mapKeystoreError(result.resultCode);
-    if (error_code == KM_ERROR_OK) {
-        if (!result.outParams.params.empty()) {
-            output_parameters->Reinitialize(&*result.outParams.params.begin(),
-                                            result.outParams.params.size());
+    auto hidlSignature = blob2hidlVec(signature_to_verify);
+    keystore_->finish(active_operations_[handle], input_parameters.hidl_data(),
+                      hidlSignature,
+                      hidl_vec<uint8_t>(), &result);
+
+    if (result.resultCode.isOk()) {
+        if (result.outParams.size()) {
+            *output_parameters = result.outParams;
         }
-        output_data->append(ByteArrayAsString(result.data.get(), result.dataLength));
+        // TODO verify that append should not be assign
+        output_data->append(hidlVec2String(result.data));
         active_operations_.erase(handle);
     }
-    return error_code;
+    return result.resultCode;
 }
 
-int32_t KeystoreClientImpl::abortOperation(keymaster_operation_handle_t handle) {
+KeyStoreNativeReturnCode KeystoreClientImpl::abortOperation(uint64_t handle) {
     if (active_operations_.count(handle) == 0) {
-        return KM_ERROR_INVALID_OPERATION_HANDLE;
+        return ErrorCode::INVALID_OPERATION_HANDLE;
     }
-    int32_t error_code = mapKeystoreError(keystore_->abort(active_operations_[handle]));
-    if (error_code == KM_ERROR_OK) {
+    auto error_code = keystore_->abort(active_operations_[handle]);
+    if (error_code.isOk()) {
         active_operations_.erase(handle);
     }
     return error_code;
@@ -355,16 +338,16 @@
 
 bool KeystoreClientImpl::doesKeyExist(const std::string& key_name) {
     String16 key_name16(key_name.data(), key_name.size());
-    int32_t error_code = mapKeystoreError(keystore_->exist(key_name16, kDefaultUID));
-    return (error_code == KM_ERROR_OK);
+    auto error_code = keystore_->exist(key_name16, kDefaultUID);
+    return error_code.isOk();
 }
 
 bool KeystoreClientImpl::listKeys(const std::string& prefix,
                                   std::vector<std::string>* key_name_list) {
     String16 prefix16(prefix.data(), prefix.size());
     android::Vector<String16> matches;
-    int32_t error_code = mapKeystoreError(keystore_->list(prefix16, kDefaultUID, &matches));
-    if (error_code == KM_ERROR_OK) {
+    auto error_code = keystore_->list(prefix16, kDefaultUID, &matches);
+    if (error_code.isOk()) {
         for (const auto& match : matches) {
             android::String8 key_name(match);
             key_name_list->push_back(prefix + std::string(key_name.string(), key_name.size()));
@@ -374,18 +357,10 @@
     return false;
 }
 
-keymaster_operation_handle_t KeystoreClientImpl::getNextVirtualHandle() {
+uint64_t KeystoreClientImpl::getNextVirtualHandle() {
     return next_virtual_handle_++;
 }
 
-int32_t KeystoreClientImpl::mapKeystoreError(int32_t keystore_error) {
-    // See notes in keystore_client.h for rationale.
-    if (keystore_error == ::NO_ERROR) {
-        return KM_ERROR_OK;
-    }
-    return keystore_error;
-}
-
 bool KeystoreClientImpl::createOrVerifyEncryptionKey(const std::string& key_name) {
     bool key_exists = doesKeyExist(key_name);
     if (key_exists) {
@@ -394,9 +369,9 @@
             return false;
         }
         if (!verified) {
-            int32_t result = deleteKey(key_name);
-            if (result != KM_ERROR_OK) {
-                ALOGE("Failed to delete invalid encryption key: %d", result);
+            auto result = deleteKey(key_name);
+            if (!result.isOk()) {
+                ALOGE("Failed to delete invalid encryption key: %d", int32_t(result));
                 return false;
             }
             key_exists = false;
@@ -405,16 +380,16 @@
     if (!key_exists) {
         AuthorizationSetBuilder key_parameters;
         key_parameters.AesEncryptionKey(kAESKeySize)
-            .Padding(KM_PAD_PKCS7)
-            .Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_CBC)
-            .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+            .Padding(PaddingMode::PKCS7)
+            .Authorization(TAG_BLOCK_MODE, BlockMode::CBC)
+            .Authorization(TAG_NO_AUTH_REQUIRED);
         AuthorizationSet hardware_enforced_characteristics;
         AuthorizationSet software_enforced_characteristics;
-        int32_t result =
-            generateKey(key_name, key_parameters.build(), &hardware_enforced_characteristics,
+        auto result =
+            generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
                         &software_enforced_characteristics);
-        if (result != KM_ERROR_OK) {
-            ALOGE("Failed to generate encryption key: %d", result);
+        if (!result.isOk()) {
+            ALOGE("Failed to generate encryption key: %d", int32_t(result));
             return false;
         }
         if (hardware_enforced_characteristics.size() == 0) {
@@ -432,9 +407,9 @@
             return false;
         }
         if (!verified) {
-            int32_t result = deleteKey(key_name);
-            if (result != KM_ERROR_OK) {
-                ALOGE("Failed to delete invalid authentication key: %d", result);
+            auto result = deleteKey(key_name);
+            if (!result.isOk()) {
+                ALOGE("Failed to delete invalid authentication key: %d", int32_t(result));
                 return false;
             }
             key_exists = false;
@@ -443,16 +418,16 @@
     if (!key_exists) {
         AuthorizationSetBuilder key_parameters;
         key_parameters.HmacKey(kHMACKeySize)
-            .Digest(KM_DIGEST_SHA_2_256)
-            .Authorization(keymaster::TAG_MIN_MAC_LENGTH, kHMACOutputSize)
-            .Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+            .Digest(Digest::SHA_2_256)
+            .Authorization(TAG_MIN_MAC_LENGTH, kHMACOutputSize)
+            .Authorization(TAG_NO_AUTH_REQUIRED);
         AuthorizationSet hardware_enforced_characteristics;
         AuthorizationSet software_enforced_characteristics;
-        int32_t result =
-            generateKey(key_name, key_parameters.build(), &hardware_enforced_characteristics,
+        auto result =
+            generateKey(key_name, key_parameters, &hardware_enforced_characteristics,
                         &software_enforced_characteristics);
-        if (result != KM_ERROR_OK) {
-            ALOGE("Failed to generate authentication key: %d", result);
+        if (!result.isOk()) {
+            ALOGE("Failed to generate authentication key: %d", int32_t(result));
             return false;
         }
         if (hardware_enforced_characteristics.size() == 0) {
@@ -466,38 +441,34 @@
                                                        bool* verified) {
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    int32_t result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
+    auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
                                            &software_enforced_characteristics);
-    if (result != KM_ERROR_OK) {
-        ALOGE("Failed to query encryption key: %d", result);
+    if (!result.isOk()) {
+        ALOGE("Failed to query encryption key: %d", int32_t(result));
         return false;
     }
     *verified = true;
-    keymaster_algorithm_t algorithm = KM_ALGORITHM_RSA;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm)) ||
-        algorithm != KM_ALGORITHM_AES) {
+    auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
+            software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
+    if (!algorithm.isOk() || algorithm.value() != Algorithm::AES) {
         ALOGW("Found encryption key with invalid algorithm.");
         *verified = false;
     }
-    uint32_t key_size = 0;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_KEY_SIZE, &key_size) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_KEY_SIZE, &key_size)) ||
-        key_size != kAESKeySize) {
+    auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
+            software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
+    if (!key_size.isOk() || key_size.value() != kAESKeySize) {
         ALOGW("Found encryption key with invalid size.");
         *verified = false;
     }
-    keymaster_block_mode_t block_mode = KM_MODE_ECB;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_BLOCK_MODE, &block_mode) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_BLOCK_MODE, &block_mode)) ||
-        block_mode != KM_MODE_CBC) {
+    auto block_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE),
+            software_enforced_characteristics.GetTagValue(TAG_BLOCK_MODE));
+    if (!block_mode.isOk() || block_mode.value() != BlockMode::CBC) {
         ALOGW("Found encryption key with invalid block mode.");
         *verified = false;
     }
-    keymaster_padding_t padding_mode = KM_PAD_NONE;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_PADDING, &padding_mode) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_PADDING, &padding_mode)) ||
-        padding_mode != KM_PAD_PKCS7) {
+    auto padding_mode = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_PADDING),
+            software_enforced_characteristics.GetTagValue(TAG_PADDING));
+    if (!padding_mode.isOk() || padding_mode.value() != PaddingMode::PKCS7) {
         ALOGW("Found encryption key with invalid padding mode.");
         *verified = false;
     }
@@ -511,39 +482,34 @@
                                                            bool* verified) {
     AuthorizationSet hardware_enforced_characteristics;
     AuthorizationSet software_enforced_characteristics;
-    int32_t result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
+    auto result = getKeyCharacteristics(key_name, &hardware_enforced_characteristics,
                                            &software_enforced_characteristics);
-    if (result != KM_ERROR_OK) {
-        ALOGE("Failed to query authentication key: %d", result);
+    if (!result.isOk()) {
+        ALOGE("Failed to query authentication key: %d", int32_t(result));
         return false;
     }
     *verified = true;
-    keymaster_algorithm_t algorithm = KM_ALGORITHM_RSA;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_ALGORITHM, &algorithm)) ||
-        algorithm != KM_ALGORITHM_HMAC) {
+    auto algorithm = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_ALGORITHM),
+            software_enforced_characteristics.GetTagValue(TAG_ALGORITHM));
+    if (!algorithm.isOk() || algorithm.value() != Algorithm::HMAC){
         ALOGW("Found authentication key with invalid algorithm.");
         *verified = false;
     }
-    uint32_t key_size = 0;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_KEY_SIZE, &key_size) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_KEY_SIZE, &key_size)) ||
-        key_size != kHMACKeySize) {
+    auto key_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_KEY_SIZE),
+            software_enforced_characteristics.GetTagValue(TAG_KEY_SIZE));
+    if (!key_size.isOk() || key_size.value() != kHMACKeySize) {
         ALOGW("Found authentication key with invalid size.");
         *verified = false;
     }
-    uint32_t mac_size = 0;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_MIN_MAC_LENGTH, &mac_size) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_MIN_MAC_LENGTH,
-                                                        &mac_size)) ||
-        mac_size != kHMACOutputSize) {
+    auto mac_size = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH),
+            software_enforced_characteristics.GetTagValue(TAG_MIN_MAC_LENGTH));
+    if (!mac_size.isOk() || mac_size.value() != kHMACOutputSize) {
         ALOGW("Found authentication key with invalid minimum mac size.");
         *verified = false;
     }
-    keymaster_digest_t digest = KM_DIGEST_NONE;
-    if ((!hardware_enforced_characteristics.GetTagValue(keymaster::TAG_DIGEST, &digest) &&
-         !software_enforced_characteristics.GetTagValue(keymaster::TAG_DIGEST, &digest)) ||
-        digest != KM_DIGEST_SHA_2_256) {
+    auto digest = NullOrOr(hardware_enforced_characteristics.GetTagValue(TAG_DIGEST),
+            software_enforced_characteristics.GetTagValue(TAG_DIGEST));
+    if (!digest.isOk() || digest.value() != Digest::SHA_2_256) {
         ALOGW("Found authentication key with invalid digest list.");
         *verified = false;
     }
diff --git a/keystore/keystore_get.cpp b/keystore/keystore_get.cpp
index 2783816..8fb7f80 100644
--- a/keystore/keystore_get.cpp
+++ b/keystore/keystore_get.cpp
@@ -20,6 +20,7 @@
 #include <keystore/keystore_get.h>
 
 using namespace android;
+using namespace keystore;
 
 ssize_t keystore_get(const char *key, size_t keyLength, uint8_t** value) {
     sp<IServiceManager> sm = defaultServiceManager();
@@ -30,13 +31,15 @@
         return -1;
     }
 
-    size_t valueLength;
-    int32_t ret = service->get(String16(key, keyLength), -1, value, &valueLength);
-    if (ret < 0) {
-        return -1;
-    } else if (ret != ::NO_ERROR) {
-        return -1;
-    } else {
-        return valueLength;
+    hidl_vec<uint8_t> result;
+    auto ret = service->get(String16(key, keyLength), -1, &result);
+    if (!ret.isOk()) return -1;
+
+    if (value) {
+        *value = reinterpret_cast<uint8_t*>(malloc(result.size()));
+        if (!*value) return -1;
+        memcpy(*value, &result[0], result.size());
     }
+    return result.size();
+
 }
diff --git a/keystore/keystore_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..c5b36fd 100644
--- a/keystore/keystore_main.cpp
+++ b/keystore/keystore_main.cpp
@@ -17,19 +17,18 @@
 //#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 <cutils/log.h>
 
 #include "entropy.h"
 #include "key_store_service.h"
 #include "keystore.h"
 #include "permissions.h"
+#include "legacy_keymaster_device_wrapper.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,157 +36,9 @@
  * 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;
-
-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[]) {
     if (argc < 2) {
@@ -204,21 +55,13 @@
         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("keymaster");
+    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) {
@@ -228,7 +71,7 @@
     KeyStore keyStore(&entropy, dev, fallback);
     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!");
@@ -240,7 +83,5 @@
      * Binder transaction as a single-threaded program.
      */
     android::IPCThreadState::self()->joinThreadPool();
-
-    keymaster_device_release(dev);
     return 1;
 }
diff --git a/keystore/keystore_tags_utils.cpp b/keystore/keystore_tags_utils.cpp
new file mode 100644
index 0000000..278348a
--- /dev/null
+++ b/keystore/keystore_tags_utils.cpp
@@ -0,0 +1,46 @@
+/*
+**
+** Copyright 2016, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <keystore/keymaster_tags.h>
+
+namespace keystore {
+
+template<typename TagList>
+struct TagStringifier;
+
+template<typename ... Tags>
+struct TagStringifier<MetaList<Tags...>> {
+    template<TagType tag_type, Tag tag>
+    static TypedTag<tag_type, tag> chooseString(TypedTag<tag_type, tag> ttag, Tag runtime_tag,
+            const char** result) {
+        if (tag == runtime_tag) {
+            *result = Tag2String<tag>::value();
+        }
+        return ttag;
+    }
+    static const char* stringify(Tag tag) {
+        const char* result = "unknown tag";
+        [] (Tags&&...) {}(chooseString(Tags(), tag, &result)...);
+        return result;
+    }
+};
+
+const char* stringifyTag(Tag tag) {
+    return TagStringifier<all_tags_t>::stringify(tag);
+}
+
+}
diff --git a/keystore/keystore_utils.cpp b/keystore/keystore_utils.cpp
index 4617afd..0d3f0ec 100644
--- a/keystore/keystore_utils.cpp
+++ b/keystore/keystore_utils.cpp
@@ -26,6 +26,9 @@
 #include <private/android_filesystem_config.h>
 
 #include <keymaster/android_keymaster_utils.h>
+#include <keystore/authorization_set.h>
+#include <keystore/keystore_client.h>
+#include <keystore/IKeystoreService.h>
 
 size_t readFully(int fd, uint8_t* data, size_t size) {
     size_t remaining = size;
@@ -58,30 +61,31 @@
     return size;
 }
 
-void add_legacy_key_authorizations(int keyType, std::vector<keymaster_key_param_t>* params) {
-    params->push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_SIGN));
-    params->push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_VERIFY));
-    params->push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_ENCRYPT));
-    params->push_back(keymaster_param_enum(KM_TAG_PURPOSE, KM_PURPOSE_DECRYPT));
-    params->push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_NONE));
+void add_legacy_key_authorizations(int keyType, keystore::AuthorizationSet* params) {
+    using namespace keystore;
+    params->push_back(TAG_PURPOSE, KeyPurpose::SIGN);
+    params->push_back(TAG_PURPOSE, KeyPurpose::VERIFY);
+    params->push_back(TAG_PURPOSE, KeyPurpose::ENCRYPT);
+    params->push_back(TAG_PURPOSE, KeyPurpose::DECRYPT);
+    params->push_back(TAG_PADDING, PaddingMode::NONE);
     if (keyType == EVP_PKEY_RSA) {
-        params->push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_SIGN));
-        params->push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_PKCS1_1_5_ENCRYPT));
-        params->push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_PSS));
-        params->push_back(keymaster_param_enum(KM_TAG_PADDING, KM_PAD_RSA_OAEP));
+        params->push_back(TAG_PADDING, PaddingMode::RSA_PKCS1_1_5_SIGN);
+        params->push_back(TAG_PADDING, PaddingMode::RSA_PKCS1_1_5_ENCRYPT);
+        params->push_back(TAG_PADDING, PaddingMode::RSA_PSS);
+        params->push_back(TAG_PADDING, PaddingMode::RSA_OAEP);
     }
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_NONE));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_MD5));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA1));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_224));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_256));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_384));
-    params->push_back(keymaster_param_enum(KM_TAG_DIGEST, KM_DIGEST_SHA_2_512));
-    params->push_back(keymaster_param_bool(KM_TAG_ALL_USERS));
-    params->push_back(keymaster_param_bool(KM_TAG_NO_AUTH_REQUIRED));
-    params->push_back(keymaster_param_date(KM_TAG_ORIGINATION_EXPIRE_DATETIME, LLONG_MAX));
-    params->push_back(keymaster_param_date(KM_TAG_USAGE_EXPIRE_DATETIME, LLONG_MAX));
-    params->push_back(keymaster_param_date(KM_TAG_ACTIVE_DATETIME, 0));
+    params->push_back(TAG_DIGEST, Digest::NONE);
+    params->push_back(TAG_DIGEST, Digest::MD5);
+    params->push_back(TAG_DIGEST, Digest::SHA1);
+    params->push_back(TAG_DIGEST, Digest::SHA_2_224);
+    params->push_back(TAG_DIGEST, Digest::SHA_2_256);
+    params->push_back(TAG_DIGEST, Digest::SHA_2_384);
+    params->push_back(TAG_DIGEST, Digest::SHA_2_512);
+    params->push_back(TAG_ALL_USERS);
+    params->push_back(TAG_NO_AUTH_REQUIRED);
+    params->push_back(TAG_ORIGINATION_EXPIRE_DATETIME, LLONG_MAX);
+    params->push_back(TAG_USAGE_EXPIRE_DATETIME, LLONG_MAX);
+    params->push_back(TAG_ACTIVE_DATETIME, 0);
 }
 
 uid_t get_app_id(uid_t uid) {
diff --git a/keystore/keystore_utils.h b/keystore/keystore_utils.h
index eaa5eb3..0f7922a 100644
--- a/keystore/keystore_utils.h
+++ b/keystore/keystore_utils.h
@@ -28,10 +28,14 @@
 
 #include <UniquePtr.h>
 
+#include <keystore/authorization_set.h>
+
+#include "blob.h"
+
 size_t readFully(int fd, uint8_t* data, size_t size);
 size_t writeFully(int fd, uint8_t* data, size_t size);
 
-void add_legacy_key_authorizations(int keyType, std::vector<keymaster_key_param_t>* params);
+void add_legacy_key_authorizations(int keyType, keystore::AuthorizationSet* params);
 
 /**
  * Returns the app ID (in the Android multi-user sense) for the current
@@ -55,4 +59,14 @@
 };
 typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
 
+namespace keystore {
+
+inline static hidl_vec<uint8_t> blob2hidlVec(const Blob& blob) {
+    hidl_vec<uint8_t> result;
+    result.setToExternal(const_cast<uint8_t*>(blob.getValue()), blob.getLength());
+    return result;
+}
+
+} // namespace keystore
+
 #endif  // KEYSTORE_KEYSTORE_UTILS_H_
diff --git a/keystore/legacy_keymaster_device_wrapper.cpp b/keystore/legacy_keymaster_device_wrapper.cpp
new file mode 100644
index 0000000..9e36ae6
--- /dev/null
+++ b/keystore/legacy_keymaster_device_wrapper.cpp
@@ -0,0 +1,519 @@
+/*
+ **
+ ** 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);
+    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;
+
+    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<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..5712178
--- /dev/null
+++ b/keystore/legacy_keymaster_device_wrapper.h
@@ -0,0 +1,89 @@
+/*
+ **
+ ** 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<void> begin(KeyPurpose purpose, const hidl_vec<uint8_t>& key,
+                       const hidl_vec<KeyParameter>& inParams, begin_cb _hidl_cb) override;
+    Return<void> update(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+                        const hidl_vec<uint8_t>& input, update_cb _hidl_cb) override;
+    Return<void> finish(uint64_t operationHandle, const hidl_vec<KeyParameter>& inParams,
+                        const hidl_vec<uint8_t>& input, const hidl_vec<uint8_t>& signature,
+                        finish_cb _hidl_cb) override;
+    Return<ErrorCode> abort(uint64_t operationHandle) override;
+
+  private:
+    keymaster2_device_t* keymaster_device_;
+};
+
+sp<IKeymasterDevice> makeSoftwareKeymasterDevice();
+
+}  // namespace keystore
+}  // namespace android
+
+#endif  // LEGACY_KEYMASTER_DEVICE_WRAPPER_H_
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
index e8ae8b7..8c39716 100644
--- a/keystore/operation.cpp
+++ b/keystore/operation.cpp
@@ -19,17 +19,18 @@
 
 #include <algorithm>
 
-namespace android {
+namespace keystore {
+using namespace android;
+
 OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient)
     : mDeathRecipient(deathRecipient) {}
 
-sp<IBinder> OperationMap::addOperation(keymaster_operation_handle_t handle, uint64_t keyid,
-                                       keymaster_purpose_t purpose, const keymaster2_device_t* dev,
+sp<IBinder> OperationMap::addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
+                                       const OperationMap::km_device_t& dev,
                                        const sp<IBinder>& appToken,
-                                       keymaster_key_characteristics_t* characteristics,
-                                       bool pruneable) {
+                                       KeyCharacteristics&& characteristics, bool pruneable) {
     sp<IBinder> token = new BBinder();
-    mMap[token] = Operation(handle, keyid, purpose, dev, characteristics, appToken);
+    mMap[token] = Operation(handle, keyid, purpose, dev, std::move(characteristics), appToken);
     if (pruneable) {
         mLru.push_back(token);
     }
@@ -40,10 +41,9 @@
     return token;
 }
 
-bool OperationMap::getOperation(const sp<IBinder>& token, keymaster_operation_handle_t* outHandle,
-                                uint64_t* outKeyid, keymaster_purpose_t* outPurpose,
-                                const keymaster2_device_t** outDevice,
-                                const keymaster_key_characteristics_t** outCharacteristics) {
+bool OperationMap::getOperation(const sp<IBinder>& token, uint64_t* outHandle, uint64_t* outKeyid,
+                                KeyPurpose* outPurpose, km_device_t* outDevice,
+                                const KeyCharacteristics** outCharacteristics) {
     if (!outHandle || !outDevice) {
         return false;
     }
@@ -58,7 +58,7 @@
     *outPurpose = entry->second.purpose;
     *outDevice = entry->second.device;
     if (outCharacteristics) {
-        *outCharacteristics = entry->second.characteristics.get();
+        *outCharacteristics = &entry->second.characteristics;
     }
     return true;
 }
@@ -116,7 +116,8 @@
     return mLru[0];
 }
 
-bool OperationMap::getOperationAuthToken(const sp<IBinder>& token, const hw_auth_token_t** outToken) {
+bool OperationMap::getOperationAuthToken(const sp<IBinder>& token,
+                                         const HardwareAuthToken** outToken) {
     auto entry = mMap.find(token);
     if (entry == mMap.end()) {
         return false;
@@ -125,12 +126,13 @@
     return true;
 }
 
-bool OperationMap::setOperationAuthToken(const sp<IBinder>& token, const hw_auth_token_t* authToken) {
+bool OperationMap::setOperationAuthToken(const sp<IBinder>& token,
+                                         const HardwareAuthToken* authToken) {
     auto entry = mMap.find(token);
     if (entry == mMap.end()) {
         return false;
     }
-    entry->second.authToken.reset(new hw_auth_token_t);
+    entry->second.authToken.reset(new HardwareAuthToken);
     *entry->second.authToken = *authToken;
     return true;
 }
@@ -144,13 +146,13 @@
     }
 }
 
-OperationMap::Operation::Operation(keymaster_operation_handle_t handle_, uint64_t keyid_,
-                                   keymaster_purpose_t purpose_, const keymaster2_device_t* device_,
-                                   keymaster_key_characteristics_t* characteristics_,
-                                   sp<IBinder> appToken_)
+OperationMap::Operation::Operation(uint64_t handle_, uint64_t keyid_, KeyPurpose purpose_,
+                                   const OperationMap::km_device_t& device_,
+                                   KeyCharacteristics&& characteristics_, sp<IBinder> appToken_)
     : handle(handle_), keyid(keyid_), purpose(purpose_), device(device_),
       characteristics(characteristics_), appToken(appToken_) {}
 
-OperationMap::Operation::Operation() : handle(0), device(NULL), characteristics(), appToken(NULL) {}
+OperationMap::Operation::Operation()
+    : handle(0), keyid(0), device(nullptr), characteristics(), appToken(nullptr) {}
 
 }  // namespace android
diff --git a/keystore/operation.h b/keystore/operation.h
index 263b5c9..e69b43a 100644
--- a/keystore/operation.h
+++ b/keystore/operation.h
@@ -17,73 +17,74 @@
 #ifndef KEYSTORE_OPERATION_H_
 #define KEYSTORE_OPERATION_H_
 
-#include <hardware/hw_auth_token.h>
-#include <hardware/keymaster2.h>
 #include <binder/Binder.h>
 #include <binder/IBinder.h>
+#include <keystore/keymaster_tags.h>
+#include <map>
 #include <utils/LruCache.h>
 #include <utils/StrongPointer.h>
-#include <map>
 #include <vector>
 
-namespace android {
+namespace keystore {
 
-struct keymaster_key_characteristics_t_Delete {
-    void operator()(keymaster_key_characteristics_t* characteristics) const {
-        keymaster_free_characteristics(characteristics);
-        delete characteristics;
-    }
-};
-typedef std::unique_ptr<keymaster_key_characteristics_t, keymaster_key_characteristics_t_Delete>
-    Unique_keymaster_key_characteristics;
+using ::android::IBinder;
+using ::android::sp;
 
 /**
- * OperationMap handles the translation of keymaster_operation_handle_t's and
- * keymaster2_device_t's to opaque binder tokens that can be used to reference
- * that operation at a later time by applications. It also does LRU tracking
- * for operation pruning and keeps a mapping of clients to operations to allow
- * for graceful handling of application death.
+ * OperationMap handles the translation of uint64_t's and keymaster2_device_t's to opaque binder
+ * tokens that can be used to reference that operation at a later time by applications. It also does
+ * LRU tracking for operation pruning and keeps a mapping of clients to operations to allow for
+ * graceful handling of application death.
  */
+
 class OperationMap {
-public:
+    typedef ::android::sp<::android::hardware::keymaster::V3_0::IKeymasterDevice> km_device_t;
+
+  public:
     explicit OperationMap(IBinder::DeathRecipient* deathRecipient);
-    sp<IBinder> addOperation(keymaster_operation_handle_t handle, uint64_t keyid,
-                             keymaster_purpose_t purpose, const keymaster2_device_t* dev,
-                             const sp<IBinder>& appToken, keymaster_key_characteristics_t* characteristics,
-                             bool pruneable);
-    bool getOperation(const sp<IBinder>& token, keymaster_operation_handle_t* outHandle,
-                      uint64_t* outKeyid, keymaster_purpose_t* outPurpose,
-                      const keymaster2_device_t** outDev,
-                      const keymaster_key_characteristics_t** outCharacteristics);
-    bool removeOperation(const sp<IBinder>& token);
+    android::sp<android::IBinder> addOperation(uint64_t handle, uint64_t keyid, KeyPurpose purpose,
+                                               const km_device_t& dev,
+                                               const android::sp<android::IBinder>& appToken,
+                                               KeyCharacteristics&& characteristics,
+                                               bool pruneable);
+    bool getOperation(const android::sp<android::IBinder>& token, uint64_t* outHandle,
+                      uint64_t* outKeyid, KeyPurpose* outPurpose, km_device_t* outDev,
+                      const KeyCharacteristics** outCharacteristics);
+    bool removeOperation(const android::sp<android::IBinder>& token);
     bool hasPruneableOperation() const;
     size_t getOperationCount() const { return mMap.size(); }
     size_t getPruneableOperationCount() const;
-    bool getOperationAuthToken(const sp<IBinder>& token, const hw_auth_token_t** outToken);
-    bool setOperationAuthToken(const sp<IBinder>& token, const hw_auth_token_t* authToken);
-    sp<IBinder> getOldestPruneableOperation();
-    std::vector<sp<IBinder>> getOperationsForToken(const sp<IBinder>& appToken);
+    bool getOperationAuthToken(const android::sp<android::IBinder>& token,
+                               const HardwareAuthToken** outToken);
+    bool setOperationAuthToken(const android::sp<android::IBinder>& token,
+                               const HardwareAuthToken* authToken);
+    android::sp<android::IBinder> getOldestPruneableOperation();
+    std::vector<android::sp<android::IBinder>>
+    getOperationsForToken(const android::sp<android::IBinder>& appToken);
 
-private:
-    void updateLru(const sp<IBinder>& token);
-    void removeOperationTracking(const sp<IBinder>& token, const sp<IBinder>& appToken);
+  private:
+    void updateLru(const android::sp<android::IBinder>& token);
+    void removeOperationTracking(const android::sp<android::IBinder>& token,
+                                 const android::sp<android::IBinder>& appToken);
     struct Operation {
         Operation();
-        Operation(keymaster_operation_handle_t handle, uint64_t keyid, keymaster_purpose_t purpose,
-                  const keymaster2_device_t* device,
-                  keymaster_key_characteristics_t* characteristics, sp<IBinder> appToken);
-        keymaster_operation_handle_t handle;
+        Operation(uint64_t handle, uint64_t keyid, KeyPurpose purpose, const km_device_t& device,
+                  KeyCharacteristics&& characteristics, android::sp<android::IBinder> appToken);
+        uint64_t handle;
         uint64_t keyid;
-        keymaster_purpose_t purpose;
-        const keymaster2_device_t* device;
-        Unique_keymaster_key_characteristics characteristics;
-        sp<IBinder> appToken;
-        std::unique_ptr<hw_auth_token_t> authToken;
+        KeyPurpose purpose;
+        km_device_t device;
+        KeyCharacteristics characteristics;
+        android::sp<android::IBinder> appToken;
+        std::unique_ptr<HardwareAuthToken> authToken;
     };
-    std::map<sp<IBinder>, struct Operation> mMap;
-    std::vector<sp<IBinder>> mLru;
-    std::map<sp<IBinder>, std::vector<sp<IBinder>>> mAppTokenMap;
-    IBinder::DeathRecipient* mDeathRecipient;
+    std::map<android::sp<android::IBinder>, Operation> mMap;
+    std::vector<android::sp<android::IBinder>> mLru;
+    std::map<android::sp<android::IBinder>, std::vector<android::sp<android::IBinder>>>
+        mAppTokenMap;
+    android::IBinder::DeathRecipient* mDeathRecipient;
 };
-} // namespace android
+
+}  // namespace keystore
+
 #endif
diff --git a/keystore/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;
     }
 }
 
