diff --git a/keystore-engine/Android.mk b/keystore-engine/Android.mk
index bd86b6a..1f5d903 100644
--- a/keystore-engine/Android.mk
+++ b/keystore-engine/Android.mk
@@ -16,24 +16,36 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_MODULE := libkeystore
 
-LOCAL_MODULE_TAGS := optional
+ifneq (,$(wildcard $(TOP)/external/boringssl/flavor.mk))
+	include $(TOP)/external/boringssl/flavor.mk
+else
+	include $(TOP)/external/openssl/flavor.mk
+endif
+ifeq ($(OPENSSL_FLAVOR),BoringSSL)
+  LOCAL_MODULE := libkeystore-engine
 
-LOCAL_MODULE_RELATIVE_PATH := ssl/engines
+  LOCAL_SRC_FILES := \
+	android_engine.cpp
+else
+  LOCAL_MODULE := libkeystore
 
-LOCAL_SRC_FILES := \
+  LOCAL_MODULE_RELATIVE_PATH := ssl/engines
+
+  LOCAL_SRC_FILES := \
 	eng_keystore.cpp \
 	keyhandle.cpp \
 	ecdsa_meth.cpp \
 	dsa_meth.cpp \
 	rsa_meth.cpp
 
-LOCAL_CFLAGS := -fvisibility=hidden -Wall -Werror
-
-LOCAL_C_INCLUDES += \
+  LOCAL_C_INCLUDES += \
 	external/openssl/include \
 	external/openssl
+endif
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := -fvisibility=hidden -Wall -Werror
 
 LOCAL_SHARED_LIBRARIES += \
 	libcrypto \
diff --git a/keystore-engine/android_engine.cpp b/keystore-engine/android_engine.cpp
new file mode 100644
index 0000000..aa7bcbc
--- /dev/null
+++ b/keystore-engine/android_engine.cpp
@@ -0,0 +1,453 @@
+/* Copyright 2014 The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include <UniquePtr.h>
+
+#include <sys/socket.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <openssl/bn.h>
+#include <openssl/ec.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
+#include <openssl/engine.h>
+#include <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <openssl/x509.h>
+
+#include <binder/IServiceManager.h>
+#include <keystore/keystore.h>
+#include <keystore/IKeystoreService.h>
+
+using namespace android;
+
+namespace {
+
+extern const RSA_METHOD keystore_rsa_method;
+extern const ECDSA_METHOD keystore_ecdsa_method;
+
+/* key_id_dup is called when one of the RSA or EC_KEY objects is duplicated. */
+int key_id_dup(CRYPTO_EX_DATA* /* to */,
+               const CRYPTO_EX_DATA* /* from */,
+               void** from_d,
+               int /* index */,
+               long /* argl */,
+               void* /* argp */) {
+    char *key_id = reinterpret_cast<char *>(*from_d);
+    if (key_id != NULL) {
+        *from_d = strdup(key_id);
+    }
+    return 1;
+}
+
+/* key_id_free is called when one of the RSA, DSA or EC_KEY object is freed. */
+void key_id_free(void* /* parent */,
+                 void* ptr,
+                 CRYPTO_EX_DATA* /* ad */,
+                 int /* index */,
+                 long /* argl */,
+                 void* /* argp */) {
+    char *key_id = reinterpret_cast<char *>(ptr);
+    free(key_id);
+}
+
+/* KeystoreEngine is a BoringSSL ENGINE that implements RSA and ECDSA by
+ * forwarding the requested operations to Keystore. */
+class KeystoreEngine {
+ public:
+  KeystoreEngine()
+      : rsa_index_(RSA_get_ex_new_index(0 /* argl */,
+                                        NULL /* argp */,
+                                        NULL /* new_func */,
+                                        key_id_dup,
+                                        key_id_free)),
+        ec_key_index_(EC_KEY_get_ex_new_index(0 /* argl */,
+                                              NULL /* argp */,
+                                              NULL /* new_func */,
+                                              key_id_dup,
+                                              key_id_free)),
+        engine_(ENGINE_new()) {
+    ENGINE_set_RSA_method(
+        engine_, &keystore_rsa_method, sizeof(keystore_rsa_method));
+    ENGINE_set_ECDSA_method(
+        engine_, &keystore_ecdsa_method, sizeof(keystore_ecdsa_method));
+  }
+
+  int rsa_ex_index() const { return rsa_index_; }
+  int ec_key_ex_index() const { return ec_key_index_; }
+
+  const ENGINE* engine() const { return engine_; }
+
+ private:
+  const int rsa_index_;
+  const int ec_key_index_;
+  ENGINE* const engine_;
+};
+
+pthread_once_t g_keystore_engine_once = PTHREAD_ONCE_INIT;
+KeystoreEngine *g_keystore_engine;
+
+/* init_keystore_engine is called to initialize |g_keystore_engine|. This
+ * should only be called by |pthread_once|. */
+void init_keystore_engine() {
+    g_keystore_engine = new KeystoreEngine;
+}
+
+/* ensure_keystore_engine ensures that |g_keystore_engine| is pointing to a
+ * valid |KeystoreEngine| object and creates one if not. */
+void ensure_keystore_engine() {
+    pthread_once(&g_keystore_engine_once, init_keystore_engine);
+}
+
+/* Many OpenSSL APIs take ownership of an argument on success but don't free
+ * the argument on failure. This means we need to tell our scoped pointers when
+ * we've transferred ownership, without triggering a warning by not using the
+ * result of release(). */
+#define OWNERSHIP_TRANSFERRED(obj) \
+    typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
+
+const char* rsa_get_key_id(const RSA* rsa) {
+  return reinterpret_cast<char*>(
+      RSA_get_ex_data(rsa, g_keystore_engine->rsa_ex_index()));
+}
+
+/* rsa_private_transform takes a big-endian integer from |in|, calculates the
+ * d'th power of it, modulo the RSA modulus, and writes the result as a
+ * big-endian integer to |out|. Both |in| and |out| are |len| bytes long. It
+ * returns one on success and zero otherwise. */
+int rsa_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, size_t len) {
+    ALOGV("rsa_private_transform(%p, %p, %p, %u)", rsa, out, in, (unsigned) len);
+
+    const char *key_id = rsa_get_key_id(rsa);
+    if (key_id == NULL) {
+        ALOGE("key had no key_id!");
+        return 0;
+    }
+
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
+    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
+
+    if (service == NULL) {
+        ALOGE("could not contact keystore");
+        return 0;
+    }
+
+    uint8_t* reply = NULL;
+    size_t reply_len;
+    int32_t ret = service->sign(String16(key_id), in, len, &reply, &reply_len);
+    if (ret < 0) {
+        ALOGW("There was an error during rsa_decrypt: could not connect");
+        return 0;
+    } else if (ret != 0) {
+        ALOGW("Error during sign from keystore: %d", ret);
+        return 0;
+    } else if (reply_len == 0) {
+        ALOGW("No valid signature returned");
+        free(reply);
+        return 0;
+    }
+
+    if (reply_len > len) {
+        /* The result of the RSA operation can never be larger than the size of
+         * the modulus so we assume that the result has extra zeros on the
+         * left. This provides attackers with an oracle, but there's nothing
+         * that we can do about it here. */
+        memcpy(out, reply + reply_len - len, len);
+    } else if (reply_len < len) {
+        /* If the Keystore implementation returns a short value we assume that
+         * it's because it removed leading zeros from the left side. This is
+         * bad because it provides attackers with an oracle but we cannot do
+         * anything about a broken Keystore implementation here. */
+        memset(out, 0, len);
+        memcpy(out + len - reply_len, reply, reply_len);
+    } else {
+        memcpy(out, reply, len);
+    }
+
+    free(reply);
+
+    ALOGV("rsa=%p keystore_rsa_priv_dec successful", rsa);
+    return 1;
+}
+
+const struct rsa_meth_st keystore_rsa_method = {
+  {
+    0 /* references */,
+    1 /* is_static */,
+  },
+  NULL /* app_data */,
+
+  NULL /* init */,
+  NULL /* finish */,
+
+  NULL /* size */,
+
+  NULL /* sign */,
+  NULL /* verify */,
+
+  NULL /* encrypt */,
+  NULL /* sign_raw */,
+  NULL /* decrypt */,
+  NULL /* verify_raw */,
+
+  rsa_private_transform,
+
+  NULL /* mod_exp */,
+  NULL /* bn_mod_exp */,
+
+  RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_OPAQUE | RSA_FLAG_EXT_PKEY,
+
+  NULL /* keygen */,
+  NULL /* supports_digest */,
+};
+
+const char* ecdsa_get_key_id(const EC_KEY* ec_key) {
+    return reinterpret_cast<char*>(
+        EC_KEY_get_ex_data(ec_key, g_keystore_engine->ec_key_ex_index()));
+}
+
+/* ecdsa_sign signs |digest_len| bytes from |digest| with |ec_key| and writes
+ * the resulting signature (an ASN.1 encoded blob) to |sig|. It returns one on
+ * success and zero otherwise. */
+static int ecdsa_sign(const uint8_t* digest, size_t digest_len, uint8_t* sig,
+                      unsigned int* sig_len, EC_KEY* ec_key) {
+    ALOGV("ecdsa_sign(%p, %u, %p)", digest, (unsigned) digest_len, ec_key);
+
+    const char *key_id = ecdsa_get_key_id(ec_key);
+    if (key_id == NULL) {
+        ALOGE("key had no key_id!");
+        return 0;
+    }
+
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
+    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
+
+    if (service == NULL) {
+        ALOGE("could not contact keystore");
+        return 0;
+    }
+
+    size_t ecdsa_size = ECDSA_size(ec_key);
+
+    uint8_t* reply = NULL;
+    size_t reply_len;
+    int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)),
+                                digest, digest_len, &reply, &reply_len);
+    if (ret < 0) {
+        ALOGW("There was an error during ecdsa_sign: could not connect");
+        return 0;
+    } else if (ret != 0) {
+        ALOGW("Error during sign from keystore: %d", ret);
+        return 0;
+    } else if (reply_len == 0) {
+        ALOGW("No valid signature returned");
+        free(reply);
+        return 0;
+    } else if (reply_len > ecdsa_size) {
+        ALOGW("Signature is too large");
+        free(reply);
+        return 0;
+    }
+
+    memcpy(sig, reply, reply_len);
+    *sig_len = reply_len;
+
+    ALOGV("ecdsa_sign(%p, %u, %p) => success", digest, (unsigned)digest_len,
+          ec_key);
+    return 1;
+}
+
+const ECDSA_METHOD keystore_ecdsa_method = {
+    {
+     0 /* references */,
+     1 /* is_static */
+    } /* common */,
+    NULL /* app_data */,
+
+    NULL /* init */,
+    NULL /* finish */,
+    NULL /* group_order_size */,
+    ecdsa_sign,
+    NULL /* verify */,
+    ECDSA_FLAG_OPAQUE,
+};
+
+struct EVP_PKEY_Delete {
+    void operator()(EVP_PKEY* p) const {
+        EVP_PKEY_free(p);
+    }
+};
+typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
+
+struct RSA_Delete {
+    void operator()(RSA* p) const {
+        RSA_free(p);
+    }
+};
+typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
+
+struct EC_KEY_Delete {
+    void operator()(EC_KEY* ec) const {
+        EC_KEY_free(ec);
+    }
+};
+typedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
+
+/* wrap_rsa returns an |EVP_PKEY| that contains an RSA key where the public
+ * part is taken from |public_rsa| and the private operations are forwarded to
+ * KeyStore and operate on the key named |key_id|. */
+static EVP_PKEY *wrap_rsa(const char *key_id, const RSA *public_rsa) {
+    Unique_RSA rsa(RSA_new_method(g_keystore_engine->engine()));
+    if (rsa.get() == NULL) {
+        return NULL;
+    }
+
+    char *key_id_copy = strdup(key_id);
+    if (key_id_copy == NULL) {
+        return NULL;
+    }
+
+    if (!RSA_set_ex_data(rsa.get(), g_keystore_engine->rsa_ex_index(),
+                         key_id_copy)) {
+        free(key_id_copy);
+        return NULL;
+    }
+
+    rsa->n = BN_dup(public_rsa->n);
+    rsa->e = BN_dup(public_rsa->e);
+    if (rsa->n == NULL || rsa->e == NULL) {
+        return NULL;
+    }
+
+    Unique_EVP_PKEY result(EVP_PKEY_new());
+    if (result.get() == NULL ||
+        !EVP_PKEY_assign_RSA(result.get(), rsa.get())) {
+        return NULL;
+    }
+    OWNERSHIP_TRANSFERRED(rsa);
+
+    return result.release();
+}
+
+/* wrap_ecdsa returns an |EVP_PKEY| that contains an ECDSA key where the public
+ * part is taken from |public_rsa| and the private operations are forwarded to
+ * KeyStore and operate on the key named |key_id|. */
+static EVP_PKEY *wrap_ecdsa(const char *key_id, const EC_KEY *public_ecdsa) {
+    Unique_EC_KEY ec(EC_KEY_new_method(g_keystore_engine->engine()));
+    if (ec.get() == NULL) {
+        return NULL;
+    }
+
+    if (!EC_KEY_set_group(ec.get(), EC_KEY_get0_group(public_ecdsa)) ||
+        !EC_KEY_set_public_key(ec.get(), EC_KEY_get0_public_key(public_ecdsa))) {
+        return NULL;
+    }
+
+    char *key_id_copy = strdup(key_id);
+    if (key_id_copy == NULL) {
+        return NULL;
+    }
+
+    if (!EC_KEY_set_ex_data(ec.get(), g_keystore_engine->ec_key_ex_index(),
+                            key_id_copy)) {
+        free(key_id_copy);
+        return NULL;
+    }
+
+    Unique_EVP_PKEY result(EVP_PKEY_new());
+    if (result.get() == NULL ||
+        !EVP_PKEY_assign_EC_KEY(result.get(), ec.get())) {
+        return NULL;
+    }
+    OWNERSHIP_TRANSFERRED(ec);
+
+    return result.release();
+}
+
+}  /* anonymous namespace */
+
+extern "C" {
+
+EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id) __attribute__((visibility("default")));
+
+/* EVP_PKEY_from_keystore returns an |EVP_PKEY| that contains either an RSA or
+ * ECDSA key where the public part of the key reflects the value of the key
+ * named |key_id| in Keystore and the private operations are forwarded onto
+ * KeyStore. */
+EVP_PKEY* EVP_PKEY_from_keystore(const char* key_id) {
+    ALOGV("EVP_PKEY_from_keystore(\"%s\")", key_id);
+
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
+    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
+
+    if (service == NULL) {
+        ALOGE("could not contact keystore");
+        return 0;
+    }
+
+    uint8_t *pubkey = NULL;
+    size_t pubkey_len;
+    int32_t ret = service->get_pubkey(String16(key_id), &pubkey, &pubkey_len);
+    if (ret < 0) {
+        ALOGW("could not contact keystore");
+        return NULL;
+    } else if (ret != 0) {
+        ALOGW("keystore reports error: %d", ret);
+        return NULL;
+    }
+
+    const uint8_t *inp = pubkey;
+    Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &inp, pubkey_len));
+    free(pubkey);
+    if (pkey.get() == NULL) {
+        ALOGW("Cannot convert pubkey");
+        return NULL;
+    }
+
+    ensure_keystore_engine();
+
+    EVP_PKEY *result;
+    switch (EVP_PKEY_type(pkey->type)) {
+    case EVP_PKEY_RSA: {
+        Unique_RSA public_rsa(EVP_PKEY_get1_RSA(pkey.get()));
+        result = wrap_rsa(key_id, public_rsa.get());
+        break;
+    }
+    case EVP_PKEY_EC: {
+        Unique_EC_KEY public_ecdsa(EVP_PKEY_get1_EC_KEY(pkey.get()));
+        result = wrap_ecdsa(key_id, public_ecdsa.get());
+        break;
+    }
+    default:
+        ALOGE("Unsupported key type %d", EVP_PKEY_type(pkey->type));
+        result = NULL;
+    }
+
+    return result;
+}
+
+}  // extern "C"
diff --git a/keystore-engine/keyhandle.cpp b/keystore-engine/keyhandle.cpp
index 1799735..aeba896 100644
--- a/keystore-engine/keyhandle.cpp
+++ b/keystore-engine/keyhandle.cpp
@@ -25,6 +25,8 @@
 
 #include <openssl/engine.h>
 
+#include <string.h>
+
 /**
  * Makes sure the ex_data for the keyhandle is initially set to NULL.
  */
diff --git a/keystore/.clang-format b/keystore/.clang-format
new file mode 100644
index 0000000..5747e19
--- /dev/null
+++ b/keystore/.clang-format
@@ -0,0 +1,10 @@
+BasedOnStyle: LLVM
+IndentWidth: 4
+UseTab: Never
+BreakBeforeBraces: Attach
+AllowShortFunctionsOnASingleLine: Inline
+AllowShortIfStatementsOnASingleLine: false
+IndentCaseLabels: false
+ColumnLimit: 100
+PointerBindsToType: true
+SpacesBeforeTrailingComments: 2
diff --git a/keystore/Android.mk b/keystore/Android.mk
index 9dca502..9463f3d 100644
--- a/keystore/Android.mk
+++ b/keystore/Android.mk
@@ -20,9 +20,8 @@
 ifeq ($(USE_32_BIT_KEYSTORE), true)
 LOCAL_MULTILIB := 32
 endif
-LOCAL_CFLAGS := -Wall -Wextra -Werror
-LOCAL_SRC_FILES := keystore.cpp keyblob_utils.cpp
-LOCAL_C_INCLUDES := external/openssl/include
+LOCAL_CFLAGS := -Wall -Wextra -Werror -Wunused
+LOCAL_SRC_FILES := keystore.cpp keyblob_utils.cpp operation.cpp auth_token_table.cpp
 LOCAL_SHARED_LIBRARIES := \
 	libbinder \
 	libcutils \
@@ -32,9 +31,12 @@
 	liblog \
 	libsoftkeymaster \
 	libutils \
-	libselinux
+	libselinux \
+	libsoftkeymasterdevice \
+	libkeymaster_messages
 LOCAL_MODULE := keystore
 LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUES := system/keymaster/
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_EXECUTABLE)
 
@@ -44,7 +46,6 @@
 endif
 LOCAL_CFLAGS := -Wall -Wextra -Werror
 LOCAL_SRC_FILES := keystore_cli.cpp
-LOCAL_C_INCLUDES := external/openssl/include
 LOCAL_SHARED_LIBRARIES := libcutils libcrypto libkeystore_binder libutils liblog libbinder
 LOCAL_MODULE := keystore_cli
 LOCAL_MODULE_TAGS := debug
@@ -58,10 +59,25 @@
 endif
 LOCAL_CFLAGS := -Wall -Wextra -Werror
 LOCAL_SRC_FILES := IKeystoreService.cpp keystore_get.cpp keyblob_utils.cpp
-LOCAL_SHARED_LIBRARIES := libbinder libutils liblog
+LOCAL_SHARED_LIBRARIES := libbinder libutils liblog libsoftkeymasterdevice
 LOCAL_MODULE := libkeystore_binder
 LOCAL_MODULE_TAGS := optional
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_SHARED_LIBRARY)
+
+# Library for unit tests
+include $(CLEAR_VARS)
+ifeq ($(USE_32_BIT_KEYSTORE), true)
+LOCAL_MULTILIB := 32
+endif
+LOCAL_CFLAGS := -Wall -Wextra -Werror
+LOCAL_SRC_FILES := auth_token_table.cpp
+LOCAL_MODULE := libkeystore_test
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_STATIC_LIBRARIES := libgtest_main
+LOCAL_SHARED_LIBRARIES := libkeymaster_messages
+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 40fbe0e..f920095 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -16,6 +16,7 @@
 */
 
 #include <stdint.h>
+#include <sys/limits.h>
 #include <sys/types.h>
 
 #define LOG_TAG "KeystoreService"
@@ -29,6 +30,8 @@
 
 namespace android {
 
+static keymaster_key_param_t* readParamList(const Parcel& in, size_t* length);
+
 KeystoreArg::KeystoreArg(const void* data, size_t len)
     : mData(data), mSize(len) {
 }
@@ -44,6 +47,346 @@
     return mSize;
 }
 
+OperationResult::OperationResult() : resultCode(0), token(), handle(0), inputConsumed(0),
+    data(NULL), dataLength(0) {
+}
+
+OperationResult::~OperationResult() {
+}
+
+void OperationResult::readFromParcel(const Parcel& in) {
+    resultCode = in.readInt32();
+    token = in.readStrongBinder();
+    handle = static_cast<keymaster_operation_handle_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");
+        }
+    }
+}
+
+void OperationResult::writeToParcel(Parcel* out) const {
+    out->writeInt32(resultCode);
+    out->writeStrongBinder(token);
+    out->writeInt64(handle);
+    out->writeInt32(inputConsumed);
+    out->writeInt32(dataLength);
+    if (dataLength && data) {
+        void* buf = out->writeInplace(dataLength);
+        if (buf) {
+            memcpy(buf, data.get(), dataLength);
+        } else {
+            ALOGE("Failed to writeInplace OperationResult data.");
+        }
+    }
+}
+
+ExportResult::ExportResult() : resultCode(0), exportData(NULL), dataLength(0) {
+}
+
+ExportResult::~ExportResult() {
+}
+
+void ExportResult::readFromParcel(const Parcel& in) {
+    resultCode = in.readInt32();
+    ssize_t length = in.readInt32();
+    dataLength = 0;
+    if (length > 0) {
+        const void* buf = in.readInplace(length);
+        if (buf) {
+            exportData.reset(reinterpret_cast<uint8_t*>(malloc(length)));
+            if (exportData.get()) {
+                memcpy(exportData.get(), buf, length);
+                dataLength = (size_t) length;
+            } else {
+                ALOGE("Failed to allocate ExportData buffer");
+            }
+        } else {
+            ALOGE("Failed to readInplace ExportData data");
+        }
+    }
+}
+
+void ExportResult::writeToParcel(Parcel* out) const {
+    out->writeInt32(resultCode);
+    out->writeInt32(dataLength);
+    if (exportData && dataLength) {
+        void* buf = out->writeInplace(dataLength);
+        if (buf) {
+            memcpy(buf, exportData.get(), dataLength);
+        } else {
+            ALOGE("Failed to writeInplace ExportResult data.");
+        }
+    }
+}
+
+KeymasterArguments::KeymasterArguments() {
+}
+
+KeymasterArguments::~KeymasterArguments() {
+    keymaster_free_param_values(params.data(), params.size());
+}
+
+void KeymasterArguments::readFromParcel(const Parcel& in) {
+    ssize_t length = in.readInt32();
+    size_t ulength = (size_t) length;
+    if (length < 0) {
+        ulength = 0;
+    }
+    keymaster_free_param_values(params.data(), params.size());
+    params.clear();
+    for(size_t i = 0; i < ulength; i++) {
+        keymaster_key_param_t param;
+        if (!readKeymasterArgumentFromParcel(in, &param)) {
+            ALOGE("Error reading keymaster argument from parcel");
+            break;
+        }
+        params.push_back(param);
+    }
+}
+
+void KeymasterArguments::writeToParcel(Parcel* out) const {
+    out->writeInt32(params.size());
+    for (auto param : params) {
+        out->writeInt32(1);
+        writeKeymasterArgumentToParcel(param, out);
+    }
+}
+
+KeyCharacteristics::KeyCharacteristics() {
+    memset((void*) &characteristics, 0, sizeof(characteristics));
+}
+
+KeyCharacteristics::~KeyCharacteristics() {
+    keymaster_free_characteristics(&characteristics);
+}
+
+void KeyCharacteristics::readFromParcel(const Parcel& in) {
+    size_t length = 0;
+    keymaster_key_param_t* params = readParamList(in, &length);
+    characteristics.sw_enforced.params = params;
+    characteristics.sw_enforced.length = length;
+
+    params = readParamList(in, &length);
+    characteristics.hw_enforced.params = params;
+    characteristics.hw_enforced.length = length;
+}
+
+void KeyCharacteristics::writeToParcel(Parcel* out) const {
+    if (characteristics.sw_enforced.params) {
+        out->writeInt32(characteristics.sw_enforced.length);
+        for (size_t i = 0; i < characteristics.sw_enforced.length; i++) {
+            out->writeInt32(1);
+            writeKeymasterArgumentToParcel(characteristics.sw_enforced.params[i], out);
+        }
+    } else {
+        out->writeInt32(0);
+    }
+    if (characteristics.hw_enforced.params) {
+        out->writeInt32(characteristics.hw_enforced.length);
+        for (size_t i = 0; i < characteristics.hw_enforced.length; i++) {
+            out->writeInt32(1);
+            writeKeymasterArgumentToParcel(characteristics.hw_enforced.params[i], out);
+        }
+    } else {
+        out->writeInt32(0);
+    }
+}
+
+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_INT:
+        case KM_INT_REP: {
+            out->writeInt32(param.tag);
+            out->writeInt32(param.integer);
+            break;
+        }
+        case KM_LONG:
+        case KM_LONG_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_INT:
+        case KM_INT_REP: {
+            uint32_t value = in.readInt32();
+            *out = keymaster_param_int(tag, value);
+            break;
+        }
+        case KM_LONG:
+        case KM_LONG_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");
+                    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
+ */
+static void readByteArray(const Parcel& in, const uint8_t** data, size_t* length) {
+    ssize_t slength = in.readInt32();
+    if (slength > 0) {
+        *data = reinterpret_cast<const uint8_t*>(in.readInplace(slength));
+        if (*data) {
+            *length = static_cast<size_t>(slength);
+        } else {
+            *length = 0;
+        }
+    } else {
+        *data = NULL;
+        *length = 0;
+    }
+}
+
+// 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;
+    if (in.readInt32() != 1) {
+        blob.reset(NULL);
+        return blob;
+    }
+    ssize_t length = in.readInt32();
+    blob.reset(new keymaster_blob_t);
+    if (length > 0) {
+        blob->data = reinterpret_cast<const uint8_t*>(in.readInplace(length));
+        if (blob->data) {
+            blob->data_length = static_cast<size_t>(length);
+        } else {
+            blob->data_length = 0;
+        }
+    } else {
+        blob->data = NULL;
+        blob->data_length = 0;
+    }
+    return blob;
+}
+
 class BpKeystoreService: public BpInterface<IKeystoreService>
 {
 public:
@@ -295,6 +638,7 @@
         data.writeInt32(keyType);
         data.writeInt32(keySize);
         data.writeInt32(flags);
+        data.writeInt32(1);
         data.writeInt32(args->size());
         for (Vector<sp<KeystoreArg> >::iterator it = args->begin(); it != args->end(); ++it) {
             sp<KeystoreArg> item = *it;
@@ -638,9 +982,314 @@
         }
         return ret;
     }
+    virtual int32_t addRngEntropy(const uint8_t* buf, size_t bufLength)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeByteArray(bufLength, buf);
+        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;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("addRngEntropy() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    };
+
+    virtual int32_t generateKey(const String16& name, const KeymasterArguments& params,
+                                const uint8_t* entropy, size_t entropyLength, int uid, int flags,
+                                KeyCharacteristics* outCharacteristics)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(1);
+        params.writeToParcel(&data);
+        data.writeByteArray(entropyLength, entropy);
+        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;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("generateKey() caught exception %d\n", err);
+            return KM_ERROR_UNKNOWN_ERROR;
+        }
+        if (reply.readInt32() != 0 && outCharacteristics) {
+            outCharacteristics->readFromParcel(reply);
+        }
+        return ret;
+    }
+    virtual int32_t getKeyCharacteristics(const String16& name,
+                                          const keymaster_blob_t* clientId,
+                                          const keymaster_blob_t* appData,
+                                          KeyCharacteristics* outCharacteristics)
+    {
+        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);
+        }
+        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;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("getKeyCharacteristics() caught exception %d\n", err);
+            return KM_ERROR_UNKNOWN_ERROR;
+        }
+        if (reply.readInt32() != 0 && outCharacteristics) {
+            outCharacteristics->readFromParcel(reply);
+        }
+        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)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(1);
+        params.writeToParcel(&data);
+        data.writeInt32(format);
+        data.writeByteArray(keyLength, keyData);
+        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;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("importKey() caught exception %d\n", err);
+            return KM_ERROR_UNKNOWN_ERROR;
+        }
+        if (reply.readInt32() != 0 && outCharacteristics) {
+            outCharacteristics->readFromParcel(reply);
+        }
+        return ret;
+    }
+
+    virtual void exportKey(const String16& name, keymaster_key_format_t format,
+                           const keymaster_blob_t* clientId,
+                           const keymaster_blob_t* appData, ExportResult* result)
+    {
+        if (!result) {
+            return;
+        }
+
+        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);
+        }
+        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;
+            return;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            ALOGD("exportKey() caught exception %d\n", err);
+            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            return;
+        }
+        if (reply.readInt32() != 0) {
+            result->readFromParcel(reply);
+        }
+    }
+
+    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, KeymasterArguments* outParams,
+                       OperationResult* result)
+    {
+        if (!result || !outParams) {
+            return;
+        }
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeStrongBinder(appToken);
+        data.writeString16(name);
+        data.writeInt32(purpose);
+        data.writeInt32(pruneable ? 1 : 0);
+        data.writeInt32(1);
+        params.writeToParcel(&data);
+        data.writeByteArray(entropyLength, entropy);
+        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;
+            return;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            ALOGD("begin() caught exception %d\n", err);
+            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            return;
+        }
+        if (reply.readInt32() != 0) {
+            result->readFromParcel(reply);
+        }
+        if (reply.readInt32() != 0) {
+            outParams->readFromParcel(reply);
+        }
+    }
+
+    virtual void update(const sp<IBinder>& token, const KeymasterArguments& params,
+                        const uint8_t* opData, size_t dataLength, OperationResult* result)
+    {
+        if (!result) {
+            return;
+        }
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeStrongBinder(token);
+        data.writeInt32(1);
+        params.writeToParcel(&data);
+        data.writeByteArray(dataLength, opData);
+        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;
+            return;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            ALOGD("update() caught exception %d\n", err);
+            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            return;
+        }
+        if (reply.readInt32() != 0) {
+            result->readFromParcel(reply);
+        }
+    }
+
+    virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
+                        const uint8_t* signature, size_t signatureLength, OperationResult* result)
+    {
+        if (!result) {
+            return;
+        }
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeStrongBinder(token);
+        data.writeInt32(1);
+        params.writeToParcel(&data);
+        data.writeByteArray(signatureLength, signature);
+        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;
+            return;
+        }
+        int32_t err = reply.readExceptionCode();
+        if (err < 0) {
+            ALOGD("finish() caught exception %d\n", err);
+            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
+            return;
+        }
+        if (reply.readInt32() != 0) {
+            result->readFromParcel(reply);
+        }
+    }
+
+    virtual int32_t abort(const sp<IBinder>& token)
+    {
+        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;
+        }
+        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 ret;
+    }
+
+    virtual bool isOperationAuthorized(const sp<IBinder>& token)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeStrongBinder(token);
+        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;
+    }
+
+    virtual int32_t addAuthToken(const uint8_t* token, size_t length)
+    {
+        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;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("addAuthToken() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    };
 };
 
-IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
+IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService");
 
 // ----------------------------------------------------------------------
 
@@ -768,15 +1417,19 @@
             int32_t keySize = data.readInt32();
             int32_t flags = data.readInt32();
             Vector<sp<KeystoreArg> > args;
-            ssize_t numArgs = data.readInt32();
-            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 argsPresent = data.readInt32();
+            if (argsPresent == 1) {
+                ssize_t numArgs = data.readInt32();
+                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);
+                        }
                     }
                 }
             }
@@ -960,6 +1613,178 @@
             reply->writeInt32(ret);
             return NO_ERROR;
         }
+        case ADD_RNG_ENTROPY: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            const uint8_t* bytes = NULL;
+            size_t size = 0;
+            readByteArray(data, &bytes, &size);
+            int32_t ret = addRngEntropy(bytes, size);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        }
+        case GENERATE_KEY: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            KeymasterArguments args;
+            if (data.readInt32() != 0) {
+                args.readFromParcel(data);
+            }
+            const uint8_t* entropy = NULL;
+            size_t entropyLength = 0;
+            readByteArray(data, &entropy, &entropyLength);
+            int32_t uid = data.readInt32();
+            int32_t flags = data.readInt32();
+            KeyCharacteristics outCharacteristics;
+            int32_t ret = generateKey(name, args, entropy, entropyLength, uid, flags,
+                                      &outCharacteristics);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            reply->writeInt32(1);
+            outCharacteristics.writeToParcel(reply);
+            return NO_ERROR;
+        }
+        case GET_KEY_CHARACTERISTICS: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            std::unique_ptr<keymaster_blob_t> clientId = readKeymasterBlob(data);
+            std::unique_ptr<keymaster_blob_t> appData = readKeymasterBlob(data);
+            KeyCharacteristics outCharacteristics;
+            int ret = getKeyCharacteristics(name, clientId.get(), appData.get(),
+                                            &outCharacteristics);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            reply->writeInt32(1);
+            outCharacteristics.writeToParcel(reply);
+            return NO_ERROR;
+        }
+        case IMPORT_KEY: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            KeymasterArguments args;
+            if (data.readInt32() != 0) {
+                args.readFromParcel(data);
+            }
+            keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
+            const uint8_t* keyData = NULL;
+            size_t keyLength = 0;
+            readByteArray(data, &keyData, &keyLength);
+            int32_t uid = data.readInt32();
+            int32_t flags = data.readInt32();
+            KeyCharacteristics outCharacteristics;
+            int32_t ret = importKey(name, args, format, keyData, keyLength, uid, flags,
+                                    &outCharacteristics);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            reply->writeInt32(1);
+            outCharacteristics.writeToParcel(reply);
+
+            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);
+            ExportResult result;
+            exportKey(name, format, clientId.get(), appData.get(), &result);
+            reply->writeNoException();
+            reply->writeInt32(1);
+            result.writeToParcel(reply);
+
+            return NO_ERROR;
+        }
+        case BEGIN: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            sp<IBinder> token = data.readStrongBinder();
+            String16 name = data.readString16();
+            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);
+            KeymasterArguments outArgs;
+            OperationResult result;
+            begin(token, name, purpose, pruneable, args, entropy, entropyLength, &outArgs,
+                  &result);
+            reply->writeNoException();
+            reply->writeInt32(1);
+            result.writeToParcel(reply);
+            reply->writeInt32(1);
+            outArgs.writeToParcel(reply);
+
+            return NO_ERROR;
+        }
+        case UPDATE: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            sp<IBinder> token = data.readStrongBinder();
+            KeymasterArguments args;
+            if (data.readInt32() != 0) {
+                args.readFromParcel(data);
+            }
+            const uint8_t* buf = NULL;
+            size_t bufLength = 0;
+            readByteArray(data, &buf, &bufLength);
+            OperationResult result;
+            update(token, args, buf, bufLength, &result);
+            reply->writeNoException();
+            reply->writeInt32(1);
+            result.writeToParcel(reply);
+
+            return NO_ERROR;
+        }
+        case FINISH: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            sp<IBinder> token = data.readStrongBinder();
+            KeymasterArguments args;
+            if (data.readInt32() != 0) {
+                args.readFromParcel(data);
+            }
+            const uint8_t* buf = NULL;
+            size_t bufLength = 0;
+            readByteArray(data, &buf, &bufLength);
+            OperationResult result;
+            finish(token, args, buf, bufLength, &result);
+            reply->writeNoException();
+            reply->writeInt32(1);
+            result.writeToParcel(reply);
+
+            return NO_ERROR;
+        }
+        case ABORT: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            sp<IBinder> token = data.readStrongBinder();
+            int32_t result = abort(token);
+            reply->writeNoException();
+            reply->writeInt32(result);
+
+            return NO_ERROR;
+        }
+        case 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;
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
new file mode 100644
index 0000000..de5d41d
--- /dev/null
+++ b/keystore/auth_token_table.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2015 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 "auth_token_table.h"
+
+#include <assert.h>
+#include <time.h>
+
+#include <algorithm>
+
+#include <keymaster/google_keymaster_utils.h>
+#include <keymaster/logger.h>
+
+namespace keymaster {
+
+//
+// Some trivial template wrappers around std algorithms, so they take containers not ranges.
+//
+template <typename Container, typename Predicate>
+typename Container::iterator find_if(Container& container, Predicate pred) {
+    return std::find_if(container.begin(), container.end(), pred);
+}
+
+template <typename Container, typename Predicate>
+typename Container::iterator remove_if(Container& container, Predicate pred) {
+    return std::remove_if(container.begin(), container.end(), pred);
+}
+
+template <typename Container> typename Container::iterator min_element(Container& container) {
+    return std::min_element(container.begin(), container.end());
+}
+
+time_t clock_gettime_raw() {
+    struct timespec time;
+    clock_gettime(CLOCK_MONOTONIC_RAW, &time);
+    return time.tv_sec;
+}
+
+void AuthTokenTable::AddAuthenticationToken(const hw_auth_token_t* 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);
+        *min_element(entries_) = std::move(new_entry);
+    } else {
+        entries_.push_back(std::move(new_entry));
+    }
+}
+
+inline bool KeyRequiresAuthentication(const AuthorizationSet& key_info) {
+    return key_info.find(TAG_NO_AUTH_REQUIRED) == -1;
+}
+
+inline bool KeyRequiresAuthPerOperation(const AuthorizationSet& key_info) {
+    return key_info.find(TAG_AUTH_TIMEOUT) == -1;
+}
+
+AuthTokenTable::Error AuthTokenTable::FindAuthorization(const AuthorizationSet& key_info,
+                                                        keymaster_operation_handle_t op_handle,
+                                                        const hw_auth_token_t** found) {
+    if (!KeyRequiresAuthentication(key_info))
+        return AUTH_NOT_REQUIRED;
+
+    hw_authenticator_type_t auth_type = HW_AUTH_NONE;
+    key_info.GetTagValue(TAG_USER_AUTH_TYPE, &auth_type);
+
+    std::vector<uint64_t> key_sids;
+    ExtractSids(key_info, &key_sids);
+
+    if (KeyRequiresAuthPerOperation(key_info))
+        return FindAuthPerOpAuthorization(key_sids, auth_type, op_handle, found);
+    else
+        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;
+
+    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->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,
+                                                             const AuthorizationSet& key_info,
+                                                             const hw_auth_token_t** 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;
+
+    uint32_t timeout;
+    key_info.GetTagValue(TAG_AUTH_TIMEOUT, &timeout);
+    time_t now = clock_function_();
+    if (static_cast<int64_t>(newest_match->time_received()) + timeout < static_cast<int64_t>(now))
+        return AUTH_TOKEN_EXPIRED;
+
+    newest_match->UpdateLastUse(now);
+    *found = newest_match->token();
+    return OK;
+}
+
+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);
+}
+
+void AuthTokenTable::RemoveEntriesSupersededBy(const Entry& entry) {
+    entries_.erase(remove_if(entries_, [&](Entry& e) { return entry.Supersedes(e); }),
+                   entries_.end());
+}
+
+void AuthTokenTable::Clear() {
+    entries_.clear();
+}
+
+bool AuthTokenTable::IsSupersededBySomeEntry(const Entry& entry) {
+    return std::any_of(entries_.begin(), entries_.end(),
+                       [&](Entry& e) { return e.Supersedes(entry); });
+}
+
+void AuthTokenTable::MarkCompleted(const keymaster_operation_handle_t op_handle) {
+    auto found = find_if(entries_, [&](Entry& e) { return e.token()->challenge == op_handle; });
+    if (found == entries_.end())
+        return;
+
+    assert(!IsSupersededBySomeEntry(*found));
+    found->mark_completed();
+
+    if (IsSupersededBySomeEntry(*found))
+        entries_.erase(found);
+}
+
+AuthTokenTable::Entry::Entry(const hw_auth_token_t* token, time_t current_time)
+    : token_(token), time_received_(current_time), last_use_(current_time),
+      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)));
+    return result;
+}
+
+bool AuthTokenTable::Entry::SatisfiesAuth(const std::vector<uint64_t>& sids,
+                                          hw_authenticator_type_t auth_type) {
+    for (auto sid : sids)
+        if ((sid == token_->authenticator_id) ||
+            (sid == token_->user_id && (auth_type & authenticator_type()) != 0))
+            return true;
+    return false;
+}
+
+void AuthTokenTable::Entry::UpdateLastUse(time_t time) {
+    this->last_use_ = time;
+}
+
+bool AuthTokenTable::Entry::Supersedes(const Entry& entry) const {
+    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 &&
+            timestamp_host_order() > entry.timestamp_host_order());
+}
+
+}  // namespace keymaster
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
new file mode 100644
index 0000000..7a9cc34
--- /dev/null
+++ b/keystore/auth_token_table.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2015 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 <memory>
+#include <vector>
+
+#include <hardware/hw_auth_token.h>
+#include <keymaster/authorization_set.h>
+#include <keymaster/key_blob.h>
+
+#ifndef SYSTEM_KEYMASTER_AUTH_TOKEN_TABLE_H
+#define SYSTEM_KEYMASTER_AUTH_TOKEN_TABLE_H
+
+namespace keymaster {
+
+namespace test {
+class AuthTokenTableTest;
+}  // namespace test
+
+time_t clock_gettime_raw();
+
+/**
+ * AuthTokenTable manages a set of received authorization tokens and can provide the appropriate
+ * token for authorizing a key operation.
+ *
+ * To keep the table from growing without bound, superseded entries are removed when possible, and
+ * least recently used entries are automatically pruned when when the table exceeds a size limit,
+ * which is expected to be relatively small, since the implementation uses a linear search.
+ */
+class AuthTokenTable {
+  public:
+    AuthTokenTable(size_t max_entries = 32, time_t (*clock_function)() = clock_gettime_raw)
+        : max_entries_(max_entries), clock_function_(clock_function) {}
+
+    enum Error {
+        OK,
+        AUTH_NOT_REQUIRED = -1,
+        AUTH_TOKEN_EXPIRED = -2,    // Found a matching token, but it's too old.
+        AUTH_TOKEN_WRONG_SID = -3,  // Found a token with the right challenge, but wrong SID.  This
+                                    // most likely indicates that the authenticator was updated
+                                    // (e.g. new fingerprint enrolled).
+        OP_HANDLE_REQUIRED = -4,    // The key requires auth per use but op_handle was zero.
+        AUTH_TOKEN_NOT_FOUND = -5,
+    };
+
+    /**
+     * Add an authorization token to the table.  The table takes ownership of the argument.
+     */
+    void AddAuthenticationToken(const hw_auth_token_t* token);
+
+    /**
+     * 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 AuthorizationSet& key_info,
+                            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_operation_handle_t op_handle, const hw_auth_token_t** found) {
+        return FindAuthorization(AuthorizationSet(params, params_count), op_handle, 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 Clear();
+
+    size_t size() { return entries_.size(); }
+
+  private:
+    friend class AuthTokenTableTest;
+
+    class Entry {
+      public:
+        Entry(const hw_auth_token_t* token, time_t current_time);
+        Entry(Entry&& entry) { *this = std::move(entry); }
+
+        void operator=(Entry&& rhs) {
+            token_ = std::move(rhs.token_);
+            time_received_ = rhs.time_received_;
+            last_use_ = rhs.last_use_;
+            operation_completed_ = rhs.operation_completed_;
+        }
+
+        bool operator<(const Entry& rhs) const { return last_use_ < rhs.last_use_; }
+
+        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 is_newer_than(const Entry* entry) {
+            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(); }
+        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;
+
+      private:
+        std::unique_ptr<const hw_auth_token_t> 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);
+    Error FindTimedAuthorization(const std::vector<uint64_t>& sids,
+                                 hw_authenticator_type_t auth_type,
+                                 const AuthorizationSet& key_info, const hw_auth_token_t** found);
+    void ExtractSids(const AuthorizationSet& key_info, std::vector<uint64_t>* sids);
+    void RemoveEntriesSupersededBy(const Entry& entry);
+    bool IsSupersededBySomeEntry(const Entry& entry);
+
+    std::vector<Entry> entries_;
+    size_t max_entries_;
+    time_t (*clock_function_)();
+};
+
+}  // namespace keymaster
+
+#endif  // SYSTEM_KEYMASTER_AUTH_TOKEN_TABLE_H
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
index afdff8d..8b5b5d3 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -17,9 +17,11 @@
 #ifndef KEYSTORE_IKEYSTORESERVICE_H
 #define KEYSTORE_IKEYSTORESERVICE_H
 
+#include <hardware/keymaster_defs.h>
 #include <utils/RefBase.h>
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
+#include <vector>
 
 namespace android {
 
@@ -36,6 +38,60 @@
     size_t mSize;
 };
 
+struct MallocDeleter {
+    void operator()(uint8_t* p) { free(p); }
+};
+
+// struct for serializing the results of begin/update/finish
+struct OperationResult {
+    OperationResult();
+    ~OperationResult();
+    void readFromParcel(const Parcel& in);
+    void writeToParcel(Parcel* out) const;
+
+    int resultCode;
+    sp<IBinder> token;
+    keymaster_operation_handle_t handle;
+    int inputConsumed;
+    std::unique_ptr<uint8_t[], MallocDeleter> data;
+    size_t dataLength;
+};
+
+// struct for serializing the results of export
+struct ExportResult {
+    ExportResult();
+    ~ExportResult();
+    void readFromParcel(const Parcel& in);
+    void writeToParcel(Parcel* out) const;
+
+    int resultCode;
+    std::unique_ptr<uint8_t[], MallocDeleter> exportData;
+    size_t dataLength;
+};
+
+// 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 keymaster_key_characteristics_t's
+struct KeyCharacteristics {
+    KeyCharacteristics();
+    ~KeyCharacteristics();
+    void readFromParcel(const Parcel& in);
+    void writeToParcel(Parcel* out) const;
+
+    keymaster_key_characteristics_t characteristics;
+};
+
+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
  */
@@ -68,6 +124,17 @@
         RESET_UID = IBinder::FIRST_CALL_TRANSACTION + 23,
         SYNC_UID = IBinder::FIRST_CALL_TRANSACTION + 24,
         PASSWORD_UID = IBinder::FIRST_CALL_TRANSACTION + 25,
+        ADD_RNG_ENTROPY = IBinder::FIRST_CALL_TRANSACTION + 26,
+        GENERATE_KEY = IBinder::FIRST_CALL_TRANSACTION + 27,
+        GET_KEY_CHARACTERISTICS = IBinder::FIRST_CALL_TRANSACTION + 28,
+        IMPORT_KEY = IBinder::FIRST_CALL_TRANSACTION + 29,
+        EXPORT_KEY = IBinder::FIRST_CALL_TRANSACTION + 30,
+        BEGIN = IBinder::FIRST_CALL_TRANSACTION + 31,
+        UPDATE = IBinder::FIRST_CALL_TRANSACTION + 32,
+        FINISH = IBinder::FIRST_CALL_TRANSACTION + 33,
+        ABORT = IBinder::FIRST_CALL_TRANSACTION + 34,
+        IS_OPERATION_AUTHORIZED = IBinder::FIRST_CALL_TRANSACTION + 35,
+        ADD_AUTH_TOKEN = IBinder::FIRST_CALL_TRANSACTION + 36,
     };
 
     DECLARE_META_INTERFACE(KeystoreService);
@@ -129,6 +196,46 @@
     virtual int32_t sync_uid(int32_t sourceUid, int32_t targetUid) = 0;
 
     virtual int32_t password_uid(const String16& password, int32_t uid) = 0;
+
+    virtual int32_t addRngEntropy(const uint8_t* data, size_t dataLength) = 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 int32_t getKeyCharacteristics(const String16& name,
+                                          const keymaster_blob_t* clientId,
+                                          const keymaster_blob_t* appData,
+                                          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 void exportKey(const String16& name, keymaster_key_format_t format,
+                           const keymaster_blob_t* clientId,
+                           const keymaster_blob_t* appData, 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, KeymasterArguments* outParams,
+                       OperationResult* result) = 0;
+
+    virtual void update(const sp<IBinder>& token, const KeymasterArguments& params,
+                        const uint8_t* data, size_t dataLength, OperationResult* result) = 0;
+
+    virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
+                        const uint8_t* signature, size_t signatureLength,
+                        OperationResult* result) = 0;
+
+    virtual int32_t 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;
+
 };
 
 // ----------------------------------------------------------------------------
diff --git a/keystore/keyblob_utils.cpp b/keystore/keyblob_utils.cpp
index b208073..3616822 100644
--- a/keystore/keyblob_utils.cpp
+++ b/keystore/keyblob_utils.cpp
@@ -14,9 +14,13 @@
  * limitations under the License.
  */
 
+#include <stdint.h>
+#include <string.h>
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <keystore/keystore.h>
+
 /**
  * When a key is being migrated from a software keymaster implementation
  * to a hardware keymaster implementation, the first 4 bytes of the key_blob
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index c1ce584..2144de2 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -20,6 +20,7 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <string.h>
+#include <strings.h>
 #include <unistd.h>
 #include <signal.h>
 #include <errno.h>
@@ -40,9 +41,10 @@
 #include <openssl/md5.h>
 #include <openssl/pem.h>
 
-#include <hardware/keymaster.h>
+#include <hardware/keymaster0.h>
 
 #include <keymaster/softkeymaster.h>
+#include <keymaster/soft_keymaster_device.h>
 
 #include <UniquePtr.h>
 #include <utils/String8.h>
@@ -60,7 +62,9 @@
 
 #include <selinux/android.h>
 
+#include "auth_token_table.h"
 #include "defaults.h"
+#include "operation.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
@@ -101,8 +105,7 @@
 };
 typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
 
-
-static int keymaster_device_initialize(keymaster_device_t** dev) {
+static int keymaster_device_initialize(keymaster0_device_t** dev) {
     int rc;
 
     const hw_module_t* mod;
@@ -112,7 +115,7 @@
         goto out;
     }
 
-    rc = keymaster_open(mod, dev);
+    rc = keymaster0_open(mod, dev);
     if (rc) {
         ALOGE("could not open keymaster device in %s (%s)",
             KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
@@ -126,8 +129,16 @@
     return rc;
 }
 
-static void keymaster_device_release(keymaster_device_t* dev) {
-    keymaster_close(dev);
+static int fallback_keymaster_device_initialize(keymaster1_device_t** dev) {
+    keymaster::SoftKeymasterDevice* softkeymaster =
+            new keymaster::SoftKeymasterDevice();
+    // SoftKeymasterDevice is designed to make this cast safe.
+    *dev = reinterpret_cast<keymaster1_device_t*>(softkeymaster);
+    return 0;
+}
+
+static void keymaster_device_release(keymaster0_device_t* dev) {
+    keymaster0_close(dev);
 }
 
 /***************
@@ -155,6 +166,7 @@
     P_RESET_UID     = 1 << 16,
     P_SYNC_UID      = 1 << 17,
     P_PASSWORD_UID  = 1 << 18,
+    P_ADD_AUTH      = 1 << 19,
 } perm_t;
 
 static struct user_euid {
@@ -187,6 +199,7 @@
     "reset_uid",
     "sync_uid",
     "password_uid",
+    "add_auth",
 };
 
 static struct user_perm {
@@ -294,6 +307,9 @@
  * namespace.
  */
 static bool is_granted_to(uid_t callingUid, uid_t targetUid) {
+    if (callingUid == targetUid) {
+        return true;
+    }
     for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) {
         struct user_euid user = user_euids[i];
         if (user.euid == callingUid && user.uid == targetUid) {
@@ -304,15 +320,6 @@
     return false;
 }
 
-/**
- * Allow the system to perform some privileged tasks that have to do with
- * system maintenance. This should not be used for any function that uses
- * the keys in any way (e.g., signing).
- */
-static bool is_self_or_system(uid_t callingUid, uid_t targetUid) {
-    return callingUid == targetUid || callingUid == AID_SYSTEM;
-}
-
 /* Here is the encoding of keys. This is necessary in order to allow arbitrary
  * characters in keys. Characters in [0-~] are not encoded. Others are encoded
  * into two bytes. The first byte is one of [+-.] which represents the first
@@ -479,6 +486,7 @@
     TYPE_GENERIC = 1,
     TYPE_MASTER_KEY = 2,
     TYPE_KEY_PAIR = 3,
+    TYPE_KEYMASTER_10 = 4,
 } BlobType;
 
 static const uint8_t CURRENT_BLOB_VERSION = 2;
@@ -952,9 +960,10 @@
 
 class KeyStore {
 public:
-    KeyStore(Entropy* entropy, keymaster_device_t* device)
+    KeyStore(Entropy* entropy, keymaster1_device_t* device, keymaster1_device_t* fallback)
         : mEntropy(entropy)
         , mDevice(device)
+        , mFallbackDevice(fallback)
     {
         memset(&mMetaData, '\0', sizeof(mMetaData));
     }
@@ -973,10 +982,24 @@
         mMasterKeys.clear();
     }
 
-    keymaster_device_t* getDevice() const {
+    /**
+     * Depending on the hardware keymaster version is this may return a
+     * keymaster0_device_t* cast to a keymaster1_device_t*. All methods from
+     * keymaster0 are safe to call, calls to keymaster1_device_t methods should
+     * be guarded by a check on the device's version.
+     */
+    keymaster1_device_t *getDevice() const {
         return mDevice;
     }
 
+    keymaster1_device_t *getFallbackDevice() const {
+        return mFallbackDevice;
+    }
+
+    keymaster1_device_t *getDeviceForBlob(const Blob& blob) const {
+        return blob.isFallback() ? mFallbackDevice: mDevice;
+    }
+
     ResponseCode initialize() {
         readMetaData();
         if (upgradeKeystore()) {
@@ -1156,6 +1179,15 @@
                 }
             }
         }
+        if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
+            keymaster1_device_t* 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;
         }
@@ -1253,7 +1285,7 @@
              * lazier than checking the PKCS#8 key type, but the software
              * implementation will do that anyway.
              */
-            rc = openssl_import_keypair(mDevice, key, keyLen, &data, &dataLength);
+            rc = mFallbackDevice->import_keypair(mFallbackDevice, key, keyLen, &data, &dataLength);
             isFallback = true;
 
             if (rc) {
@@ -1371,7 +1403,8 @@
     static const android::String16 sRSAKeyType;
     Entropy* mEntropy;
 
-    keymaster_device_t* mDevice;
+    keymaster1_device_t* mDevice;
+    keymaster1_device_t* mFallbackDevice;
 
     android::Vector<UserState*> mMasterKeys;
 
@@ -1591,33 +1624,32 @@
 class KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient {
 public:
     KeyStoreProxy(KeyStore* keyStore)
-        : mKeyStore(keyStore)
+        : mKeyStore(keyStore),
+          mOperationMap(this)
     {
     }
 
-    void binderDied(const wp<IBinder>&) {
-        ALOGE("binder death detected");
+    void binderDied(const wp<IBinder>& who) {
+        auto operations = mOperationMap.getOperationsForToken(who.unsafe_get());
+        for (auto token: operations) {
+            abort(token);
+        }
     }
 
     int32_t test() {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_TEST, spid)) {
-            ALOGW("permission denied for %d: test", callingUid);
+        if (!checkBinderPermission(P_TEST)) {
             return ::PERMISSION_DENIED;
         }
 
-        return mKeyStore->getState(callingUid);
+        return mKeyStore->getState(IPCThreadState::self()->getCallingUid());
     }
 
     int32_t get(const String16& name, uint8_t** item, size_t* itemLength) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_GET, spid)) {
-            ALOGW("permission denied for %d: get", callingUid);
+        if (!checkBinderPermission(P_GET)) {
             return ::PERMISSION_DENIED;
         }
 
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
         String8 name8(name);
         Blob keyBlob;
 
@@ -1639,23 +1671,11 @@
 
     int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid,
             int32_t flags) {
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_INSERT, spid)) {
-            ALOGW("permission denied for %d: insert", callingUid);
-            return ::PERMISSION_DENIED;
-        }
-
-        State state = mKeyStore->getState(callingUid);
-        if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) {
-            ALOGD("calling get in state: %d", state);
-            return state;
-        }
-
-        if (targetUid == -1) {
-            targetUid = callingUid;
-        } else if (!is_granted_to(callingUid, targetUid)) {
-            return ::PERMISSION_DENIED;
+        targetUid = getEffectiveUid(targetUid);
+        int32_t result = checkBinderPermissionAndKeystoreState(P_INSERT, targetUid,
+                                                    flags & KEYSTORE_FLAG_ENCRYPTED);
+        if (result != ::NO_ERROR) {
+            return result;
         }
 
         String8 name8(name);
@@ -1668,35 +1688,18 @@
     }
 
     int32_t del(const String16& name, int targetUid) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_DELETE, spid)) {
-            ALOGW("permission denied for %d: del", callingUid);
+        targetUid = getEffectiveUid(targetUid);
+        if (!checkBinderPermission(P_DELETE, targetUid)) {
             return ::PERMISSION_DENIED;
         }
-
-        if (targetUid == -1) {
-            targetUid = callingUid;
-        } else if (!is_granted_to(callingUid, targetUid)) {
-            return ::PERMISSION_DENIED;
-        }
-
         String8 name8(name);
         String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
-        return mKeyStore->del(filename.string(), ::TYPE_GENERIC, targetUid);
+        return mKeyStore->del(filename.string(), ::TYPE_ANY, targetUid);
     }
 
     int32_t exist(const String16& name, int targetUid) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_EXIST, spid)) {
-            ALOGW("permission denied for %d: exist", callingUid);
-            return ::PERMISSION_DENIED;
-        }
-
-        if (targetUid == -1) {
-            targetUid = callingUid;
-        } else if (!is_granted_to(callingUid, targetUid)) {
+        targetUid = getEffectiveUid(targetUid);
+        if (!checkBinderPermission(P_EXIST, targetUid)) {
             return ::PERMISSION_DENIED;
         }
 
@@ -1710,19 +1713,10 @@
     }
 
     int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_SAW, spid)) {
-            ALOGW("permission denied for %d: saw", callingUid);
+        targetUid = getEffectiveUid(targetUid);
+        if (!checkBinderPermission(P_SAW, targetUid)) {
             return ::PERMISSION_DENIED;
         }
-
-        if (targetUid == -1) {
-            targetUid = callingUid;
-        } else if (!is_granted_to(callingUid, targetUid)) {
-            return ::PERMISSION_DENIED;
-        }
-
         const String8 prefix8(prefix);
         String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid));
 
@@ -1733,13 +1727,11 @@
     }
 
     int32_t reset() {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_RESET, spid)) {
-            ALOGW("permission denied for %d: reset", callingUid);
+        if (!checkBinderPermission(P_RESET)) {
             return ::PERMISSION_DENIED;
         }
 
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
         return mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR;
     }
 
@@ -1751,14 +1743,12 @@
      * the old one. This avoids permanent damages of the existing data.
      */
     int32_t password(const String16& password) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_PASSWORD, spid)) {
-            ALOGW("permission denied for %d: password", callingUid);
+        if (!checkBinderPermission(P_PASSWORD)) {
             return ::PERMISSION_DENIED;
         }
 
         const String8 password8(password);
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
 
         switch (mKeyStore->getState(callingUid)) {
             case ::STATE_UNINITIALIZED: {
@@ -1778,13 +1768,11 @@
     }
 
     int32_t lock() {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_LOCK, spid)) {
-            ALOGW("permission denied for %d: lock", callingUid);
+        if (!checkBinderPermission(P_LOCK)) {
             return ::PERMISSION_DENIED;
         }
 
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
         State state = mKeyStore->getState(callingUid);
         if (state != ::STATE_NO_ERROR) {
             ALOGD("calling lock in state: %d", state);
@@ -1796,13 +1784,11 @@
     }
 
     int32_t unlock(const String16& pw) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_UNLOCK, spid)) {
-            ALOGW("permission denied for %d: unlock", callingUid);
+        if (!checkBinderPermission(P_UNLOCK)) {
             return ::PERMISSION_DENIED;
         }
 
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
         State state = mKeyStore->getState(callingUid);
         if (state != ::STATE_LOCKED) {
             ALOGD("calling unlock when not locked");
@@ -1814,43 +1800,29 @@
     }
 
     int32_t zero() {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_ZERO, spid)) {
-            ALOGW("permission denied for %d: zero", callingUid);
+        if (!checkBinderPermission(P_ZERO)) {
             return -1;
         }
 
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
         return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR;
     }
 
     int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize,
             int32_t flags, Vector<sp<KeystoreArg> >* args) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_INSERT, spid)) {
-            ALOGW("permission denied for %d: generate", callingUid);
-            return ::PERMISSION_DENIED;
+        targetUid = getEffectiveUid(targetUid);
+        int32_t result = checkBinderPermissionAndKeystoreState(P_INSERT, targetUid,
+                                                       flags & KEYSTORE_FLAG_ENCRYPTED);
+        if (result != ::NO_ERROR) {
+            return result;
         }
-
-        if (targetUid == -1) {
-            targetUid = callingUid;
-        } else if (!is_granted_to(callingUid, targetUid)) {
-            return ::PERMISSION_DENIED;
-        }
-
-        State state = mKeyStore->getState(callingUid);
-        if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) {
-            ALOGW("calling generate in state: %d", state);
-            return state;
-        }
-
         uint8_t* data;
         size_t dataLength;
         int rc;
         bool isFallback = false;
 
-        const keymaster_device_t* device = mKeyStore->getDevice();
+        const keymaster1_device_t* device = mKeyStore->getDevice();
+        const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice();
         if (device == NULL) {
             return ::SYSTEM_ERROR;
         }
@@ -1899,7 +1871,8 @@
                 rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength);
             } else {
                 isFallback = true;
-                rc = openssl_generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength);
+                rc = fallback->generate_keypair(fallback, TYPE_DSA, &dsa_params, &data,
+                                                &dataLength);
             }
         } else if (keyType == EVP_PKEY_EC) {
             keymaster_ec_keygen_params_t ec_params;
@@ -1917,7 +1890,7 @@
                 rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength);
             } else {
                 isFallback = true;
-                rc = openssl_generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength);
+                rc = fallback->generate_keypair(fallback, TYPE_EC, &ec_params, &data, &dataLength);
             }
         } else if (keyType == EVP_PKEY_RSA) {
             keymaster_rsa_keygen_params_t rsa_params;
@@ -1965,7 +1938,7 @@
         }
 
         String8 name8(name);
-        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
 
         Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
         free(data);
@@ -1973,30 +1946,17 @@
         keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
         keyBlob.setFallback(isFallback);
 
-        return mKeyStore->put(filename.string(), &keyBlob, callingUid);
+        return mKeyStore->put(filename.string(), &keyBlob, targetUid);
     }
 
     int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid,
             int32_t flags) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_INSERT, spid)) {
-            ALOGW("permission denied for %d: import", callingUid);
-            return ::PERMISSION_DENIED;
+        targetUid = getEffectiveUid(targetUid);
+        int32_t result = checkBinderPermissionAndKeystoreState(P_INSERT, targetUid,
+                                                       flags & KEYSTORE_FLAG_ENCRYPTED);
+        if (result != ::NO_ERROR) {
+            return result;
         }
-
-        if (targetUid == -1) {
-            targetUid = callingUid;
-        } else if (!is_granted_to(callingUid, targetUid)) {
-            return ::PERMISSION_DENIED;
-        }
-
-        State state = mKeyStore->getState(targetUid);
-        if ((flags & KEYSTORE_FLAG_ENCRYPTED) && !isKeystoreUnlocked(state)) {
-            ALOGD("calling import in state: %d", state);
-            return state;
-        }
-
         String8 name8(name);
         String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
 
@@ -2005,18 +1965,15 @@
 
     int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
             size_t* outLength) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_SIGN, spid)) {
-            ALOGW("permission denied for %d: saw", callingUid);
+        if (!checkBinderPermission(P_SIGN)) {
             return ::PERMISSION_DENIED;
         }
 
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
         Blob keyBlob;
         String8 name8(name);
 
         ALOGV("sign %s from uid %d", name8.string(), callingUid);
-        int rc;
 
         ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
                 ::TYPE_KEY_PAIR);
@@ -2024,7 +1981,7 @@
             return responseCode;
         }
 
-        const keymaster_device_t* device = mKeyStore->getDevice();
+        const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob);
         if (device == NULL) {
             ALOGE("no keymaster device; cannot sign");
             return ::SYSTEM_ERROR;
@@ -2038,14 +1995,8 @@
         keymaster_rsa_sign_params_t params;
         params.digest_type = DIGEST_NONE;
         params.padding_type = PADDING_NONE;
-
-        if (keyBlob.isFallback()) {
-            rc = openssl_sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
-                    length, out, outLength);
-        } else {
-            rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
-                    length, out, outLength);
-        }
+        int rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
+                length, out, outLength);
         if (rc) {
             ALOGW("device couldn't sign data");
             return ::SYSTEM_ERROR;
@@ -2056,19 +2007,11 @@
 
     int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
             const uint8_t* signature, size_t signatureLength) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_VERIFY, spid)) {
-            ALOGW("permission denied for %d: verify", callingUid);
+        if (!checkBinderPermission(P_VERIFY)) {
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState(callingUid);
-        if (!isKeystoreUnlocked(state)) {
-            ALOGD("calling verify in state: %d", state);
-            return state;
-        }
-
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
         Blob keyBlob;
         String8 name8(name);
         int rc;
@@ -2079,7 +2022,7 @@
             return responseCode;
         }
 
-        const keymaster_device_t* device = mKeyStore->getDevice();
+        const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob);
         if (device == NULL) {
             return ::SYSTEM_ERROR;
         }
@@ -2092,13 +2035,8 @@
         params.digest_type = DIGEST_NONE;
         params.padding_type = PADDING_NONE;
 
-        if (keyBlob.isFallback()) {
-            rc = openssl_verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
-                    dataLength, signature, signatureLength);
-        } else {
-            rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
-                    dataLength, signature, signatureLength);
-        }
+        rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(), data,
+                dataLength, signature, signatureLength);
         if (rc) {
             return ::SYSTEM_ERROR;
         } else {
@@ -2119,8 +2057,7 @@
      */
     int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_GET, spid)) {
+        if (!checkBinderPermission(P_GET)) {
             ALOGW("permission denied for %d: get_pubkey", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -2136,7 +2073,7 @@
             return responseCode;
         }
 
-        const keymaster_device_t* device = mKeyStore->getDevice();
+        const keymaster1_device_t* device = mKeyStore->getDeviceForBlob(keyBlob);
         if (device == NULL) {
             return ::SYSTEM_ERROR;
         }
@@ -2147,13 +2084,8 @@
         }
 
         int rc;
-        if (keyBlob.isFallback()) {
-            rc = openssl_get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey,
-                    pubkeyLength);
-        } else {
-            rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey,
-                    pubkeyLength);
-        }
+        rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey,
+                pubkeyLength);
         if (rc) {
             return ::SYSTEM_ERROR;
         }
@@ -2162,36 +2094,14 @@
     }
 
     int32_t del_key(const String16& name, int targetUid) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_DELETE, spid)) {
-            ALOGW("permission denied for %d: del_key", callingUid);
-            return ::PERMISSION_DENIED;
-        }
-
-        if (targetUid == -1) {
-            targetUid = callingUid;
-        } else if (!is_granted_to(callingUid, targetUid)) {
-            return ::PERMISSION_DENIED;
-        }
-
-        String8 name8(name);
-        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
-        return mKeyStore->del(filename.string(), ::TYPE_KEY_PAIR, targetUid);
+        return del(name, targetUid);
     }
 
     int32_t grant(const String16& name, int32_t granteeUid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_GRANT, spid)) {
-            ALOGW("permission denied for %d: grant", callingUid);
-            return ::PERMISSION_DENIED;
-        }
-
-        State state = mKeyStore->getState(callingUid);
-        if (!isKeystoreUnlocked(state)) {
-            ALOGD("calling grant in state: %d", state);
-            return state;
+        int32_t result = checkBinderPermissionAndKeystoreState(P_GRANT);
+        if (result != ::NO_ERROR) {
+            return result;
         }
 
         String8 name8(name);
@@ -2207,16 +2117,9 @@
 
     int32_t ungrant(const String16& name, int32_t granteeUid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_GRANT, spid)) {
-            ALOGW("permission denied for %d: ungrant", callingUid);
-            return ::PERMISSION_DENIED;
-        }
-
-        State state = mKeyStore->getState(callingUid);
-        if (!isKeystoreUnlocked(state)) {
-            ALOGD("calling ungrant in state: %d", state);
-            return state;
+        int32_t result = checkBinderPermissionAndKeystoreState(P_GRANT);
+        if (result != ::NO_ERROR) {
+            return result;
         }
 
         String8 name8(name);
@@ -2231,8 +2134,7 @@
 
     int64_t getmtime(const String16& name) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_GET, spid)) {
+        if (!checkBinderPermission(P_GET)) {
             ALOGW("permission denied for %d: getmtime", callingUid);
             return -1L;
         }
@@ -2327,27 +2229,11 @@
     }
 
     int32_t clear_uid(int64_t targetUid64) {
-        uid_t targetUid = static_cast<uid_t>(targetUid64);
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_CLEAR_UID, spid)) {
-            ALOGW("permission denied for %d: clear_uid", callingUid);
+        uid_t targetUid = getEffectiveUid(targetUid64);
+        if (!checkBinderPermission(P_CLEAR_UID, targetUid)) {
             return ::PERMISSION_DENIED;
         }
 
-        if (targetUid64 == -1) {
-            targetUid = callingUid;
-        } else if (!is_self_or_system(callingUid, targetUid)) {
-            ALOGW("permission denied for %d: clear_uid %d", callingUid, targetUid);
-            return ::PERMISSION_DENIED;
-        }
-
-        const keymaster_device_t* device = mKeyStore->getDevice();
-        if (device == NULL) {
-            ALOGW("can't get keymaster device");
-            return ::SYSTEM_ERROR;
-        }
-
         String8 prefix = String8::format("%u_", targetUid);
         Vector<String16> aliases;
         if (mKeyStore->saw(prefix, &aliases, targetUid) != ::NO_ERROR) {
@@ -2363,32 +2249,22 @@
     }
 
     int32_t reset_uid(int32_t targetUid) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-
-        if (!has_permission(callingUid, P_RESET_UID, spid)) {
-            ALOGW("permission denied for %d: reset_uid %d", callingUid, targetUid);
+        targetUid = getEffectiveUid(targetUid);
+        if (!checkBinderPermission(P_RESET_UID, targetUid)) {
             return ::PERMISSION_DENIED;
         }
-        if (!is_self_or_system(callingUid, targetUid)) {
-            ALOGW("permission denied for %d: reset_uid %d", callingUid, targetUid);
-            return ::PERMISSION_DENIED;
-        }
+        // Flush the auth token table to prevent stale tokens from sticking
+        // around.
+        mAuthTokenTable.Clear();
 
         return mKeyStore->reset(targetUid) ? ::NO_ERROR : ::SYSTEM_ERROR;
     }
 
     int32_t sync_uid(int32_t sourceUid, int32_t targetUid) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_SYNC_UID, spid)) {
-            ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid);
+        if (!checkBinderPermission(P_SYNC_UID, targetUid)) {
             return ::PERMISSION_DENIED;
         }
-        if (callingUid != AID_SYSTEM) {
-            ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid);
-            return ::PERMISSION_DENIED;
-        }
+
         if (sourceUid == targetUid) {
             return ::SYSTEM_ERROR;
         }
@@ -2398,17 +2274,10 @@
     }
 
     int32_t password_uid(const String16& pw, int32_t targetUid) {
-        uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        pid_t spid = IPCThreadState::self()->getCallingPid();
-        if (!has_permission(callingUid, P_PASSWORD_UID, spid)) {
-            ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid);
+        targetUid = getEffectiveUid(targetUid);
+        if (!checkBinderPermission(P_PASSWORD, targetUid)) {
             return ::PERMISSION_DENIED;
         }
-        if (callingUid != AID_SYSTEM) {
-            ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid);
-            return ::PERMISSION_DENIED;
-        }
-
         const String8 password8(pw);
 
         switch (mKeyStore->getState(targetUid)) {
@@ -2428,7 +2297,579 @@
         return ::SYSTEM_ERROR;
     }
 
+    int32_t addRngEntropy(const uint8_t* data, size_t dataLength) {
+        const keymaster1_device_t* device = mKeyStore->getDevice();
+        const keymaster1_device_t* 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;
+    }
+
+    int32_t generateKey(const String16& name, const KeymasterArguments& params,
+                        const uint8_t* entropy, size_t entropyLength, int uid, int flags,
+                        KeyCharacteristics* outCharacteristics) {
+        uid = getEffectiveUid(uid);
+        int rc = checkBinderPermissionAndKeystoreState(P_INSERT, uid,
+                                                       flags & KEYSTORE_FLAG_ENCRYPTED);
+        if (rc != ::NO_ERROR) {
+            return rc;
+        }
+
+        rc = KM_ERROR_UNIMPLEMENTED;
+        bool isFallback = false;
+        keymaster_key_blob_t blob;
+        keymaster_key_characteristics_t *out = NULL;
+
+        const keymaster1_device_t* device = mKeyStore->getDevice();
+        const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice();
+        if (device == NULL) {
+            return ::SYSTEM_ERROR;
+        }
+        // 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, params.params.data(), params.params.size(),
+                                          &blob, &out);
+            }
+        }
+        // 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) {
+            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, params.params.data(), params.params.size(),
+                                            &blob,
+                                            &out);
+            }
+        }
+
+        if (out) {
+            if (outCharacteristics) {
+                outCharacteristics->characteristics = *out;
+            } else {
+                keymaster_free_characteristics(out);
+            }
+            free(out);
+        }
+
+        if (rc) {
+            return rc;
+        }
+
+        String8 name8(name);
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid));
+
+        Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10);
+        keyBlob.setFallback(isFallback);
+        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
+
+        free(const_cast<uint8_t*>(blob.key_material));
+
+        return mKeyStore->put(filename.string(), &keyBlob, uid);
+    }
+
+    int32_t getKeyCharacteristics(const String16& name,
+                                  const keymaster_blob_t* clientId,
+                                  const keymaster_blob_t* appData,
+                                  KeyCharacteristics* outCharacteristics) {
+        if (!outCharacteristics) {
+            return KM_ERROR_UNEXPECTED_NULL_POINTER;
+        }
+
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
+
+        Blob keyBlob;
+        String8 name8(name);
+        int rc;
+
+        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
+                TYPE_KEYMASTER_10);
+        if (responseCode != ::NO_ERROR) {
+            return responseCode;
+        }
+        keymaster_key_blob_t key;
+        key.key_material_size = keyBlob.getLength();
+        key.key_material = keyBlob.getValue();
+        keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob);
+        keymaster_key_characteristics_t *out = NULL;
+        if (!dev->get_key_characteristics) {
+            ALOGW("device does not implement get_key_characteristics");
+            return KM_ERROR_UNIMPLEMENTED;
+        }
+        rc = dev->get_key_characteristics(dev, &key, clientId, appData, &out);
+        if (out) {
+            outCharacteristics->characteristics = *out;
+            free(out);
+        }
+        return rc ? rc : ::NO_ERROR;
+    }
+
+    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) {
+        uid = getEffectiveUid(uid);
+        int rc = checkBinderPermissionAndKeystoreState(P_INSERT, uid,
+                                                       flags & KEYSTORE_FLAG_ENCRYPTED);
+        if (rc != ::NO_ERROR) {
+            return rc;
+        }
+
+        rc = KM_ERROR_UNIMPLEMENTED;
+        bool isFallback = false;
+        keymaster_key_blob_t blob;
+        keymaster_key_characteristics_t *out = NULL;
+
+        const keymaster1_device_t* device = mKeyStore->getDevice();
+        const keymaster1_device_t* fallback = mKeyStore->getFallbackDevice();
+        if (device == NULL) {
+            return ::SYSTEM_ERROR;
+        }
+        if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 &&
+                device->import_key != NULL) {
+            rc = device->import_key(device, params.params.data(), params.params.size(),
+                                    format, keyData, keyLength, &blob, &out);
+        }
+        if (rc && fallback->import_key != NULL) {
+            isFallback = true;
+            rc = fallback->import_key(fallback, params.params.data(), params.params.size(),
+                                      format, keyData, keyLength, &blob, &out);
+        }
+        if (out) {
+            if (outCharacteristics) {
+                outCharacteristics->characteristics = *out;
+            } else {
+                keymaster_free_characteristics(out);
+            }
+            free(out);
+        }
+        if (rc) {
+            return rc;
+        }
+
+        String8 name8(name);
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid));
+
+        Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10);
+        keyBlob.setFallback(isFallback);
+        keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
+
+        free((void*) blob.key_material);
+
+        return mKeyStore->put(filename.string(), &keyBlob, uid);
+    }
+
+    void exportKey(const String16& name, keymaster_key_format_t format,
+                           const keymaster_blob_t* clientId,
+                           const keymaster_blob_t* appData, ExportResult* result) {
+
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
+
+        Blob keyBlob;
+        String8 name8(name);
+        int rc;
+
+        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
+                TYPE_KEYMASTER_10);
+        if (responseCode != ::NO_ERROR) {
+            result->resultCode = responseCode;
+            return;
+        }
+        keymaster_key_blob_t key;
+        key.key_material_size = keyBlob.getLength();
+        key.key_material = keyBlob.getValue();
+        keymaster1_device_t* dev = mKeyStore->getDeviceForBlob(keyBlob);
+        if (!dev->export_key) {
+            result->resultCode = KM_ERROR_UNIMPLEMENTED;
+            return;
+        }
+        uint8_t* ptr = NULL;
+        rc = dev->export_key(dev, format, &key, clientId, appData,
+                                             &ptr, &result->dataLength);
+        result->exportData.reset(ptr);
+        result->resultCode = rc ? rc : ::NO_ERROR;
+    }
+
+    /**
+     * 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) {
+        for (auto param: params) {
+            switch (param.tag) {
+                case KM_TAG_AUTH_TOKEN:
+                    return false;
+                default:
+                    break;
+            }
+        }
+        return true;
+    }
+
+    int authorizeOperation(const keymaster_key_characteristics_t& characteristics,
+                            keymaster_operation_handle_t handle,
+                            std::vector<keymaster_key_param_t>* params,
+                            bool failOnTokenMissing=true) {
+        if (!checkAllowedOperationParams(*params)) {
+            return KM_ERROR_INVALID_ARGUMENT;
+        }
+        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]);
+        }
+        for (size_t i = 0; i < characteristics.hw_enforced.length; i++) {
+            allCharacteristics.push_back(characteristics.hw_enforced.params[i]);
+        }
+        // Check for auth token and add it to the param list if present.
+        const hw_auth_token_t* authToken;
+        switch (mAuthTokenTable.FindAuthorization(allCharacteristics.data(),
+                                                  allCharacteristics.size(), handle, &authToken)) {
+        case keymaster::AuthTokenTable::OK:
+            // Auth token found.
+            params->push_back(keymaster_param_blob(KM_TAG_AUTH_TOKEN,
+                                                   reinterpret_cast<const uint8_t*>(authToken),
+                                                   sizeof(hw_auth_token_t)));
+            break;
+        case keymaster::AuthTokenTable::AUTH_NOT_REQUIRED:
+            return KM_ERROR_OK;
+        case keymaster::AuthTokenTable::AUTH_TOKEN_NOT_FOUND:
+        case keymaster::AuthTokenTable::OP_HANDLE_REQUIRED:
+        case keymaster::AuthTokenTable::AUTH_TOKEN_EXPIRED:
+            if (failOnTokenMissing) {
+                return KM_ERROR_KEY_USER_NOT_AUTHENTICATED;
+            }
+            break;
+        case keymaster::AuthTokenTable::AUTH_TOKEN_WRONG_SID:
+            return KM_ERROR_KEY_USER_NOT_AUTHENTICATED;
+        default:
+            return KM_ERROR_INVALID_ARGUMENT;
+        }
+        // TODO: Enforce the rest of authorization
+        return KM_ERROR_OK;
+    }
+
+    keymaster_error_t getOperationCharacteristics(const keymaster_key_blob_t& key,
+                                    const keymaster1_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;
+        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;
+            }
+        }
+        keymaster_key_characteristics_t* result = NULL;
+        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 (result) {
+            *out = *result;
+            free(result);
+        }
+        return error;
+    }
+
+    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, KeymasterArguments* outParams, OperationResult* result) {
+        if (!result || !outParams) {
+            ALOGE("Unexpected null arguments to begin()");
+            return;
+        }
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
+        if (!pruneable && get_app_id(callingUid) != AID_SYSTEM) {
+            ALOGE("Non-system uid %d trying to start non-pruneable operation", callingUid);
+            result->resultCode = ::PERMISSION_DENIED;
+            return;
+        }
+        Blob keyBlob;
+        String8 name8(name);
+        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
+                TYPE_KEYMASTER_10);
+        if (responseCode != ::NO_ERROR) {
+            result->resultCode = responseCode;
+            return;
+        }
+        keymaster_key_blob_t key;
+        key.key_material_size = keyBlob.getLength();
+        key.key_material = keyBlob.getValue();
+        keymaster_key_param_t* out;
+        size_t outSize;
+        keymaster_operation_handle_t handle;
+        keymaster1_device_t* 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) {
+            result->resultCode = err;
+            return;
+        }
+        // Don't require an auth token for the call to begin, authentication can
+        // require an operation handle. Update and finish will require the token
+        // be present and valid.
+        int32_t authResult = authorizeOperation(*characteristics, 0, &opParams,
+                                                /*failOnTokenMissing*/ false);
+        if (authResult) {
+            result->resultCode = err;
+            return;
+        }
+        // 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;
+                return;
+            }
+        }
+        // Don't do an auth check here, we need begin to succeed for
+        // per-operation auth. update/finish will be doing the auth checks.
+        err = dev->begin(dev, purpose, &key, opParams.data(), opParams.size(), &out, &outSize,
+                         &handle);
+
+        // 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()) {
+            sp<IBinder> oldest = mOperationMap.getOldestPruneableOperation();
+            ALOGD("Ran out of operation handles, trying to prune %p", oldest.get());
+            if (abort(oldest) != ::NO_ERROR) {
+                break;
+            }
+            err = dev->begin(dev, purpose, &key, params.params.data(),
+                             params.params.size(), &out, &outSize,
+                             &handle);
+        }
+        if (err) {
+            result->resultCode = err;
+            return;
+        }
+        if (out) {
+            outParams->params.assign(out, out + outSize);
+            free(out);
+        }
+
+        sp<IBinder> operationToken = mOperationMap.addOperation(handle, dev, appToken,
+                                                                characteristics.release(),
+                                                                pruneable);
+        result->resultCode = ::NO_ERROR;
+        result->token = operationToken;
+        result->handle = handle;
+    }
+
+    void update(const sp<IBinder>& token, const KeymasterArguments& params, const uint8_t* data,
+                size_t dataLength, OperationResult* result) {
+        const keymaster1_device_t* dev;
+        keymaster_operation_handle_t handle;
+        const keymaster_key_characteristics_t* characteristics;
+        if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) {
+            result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE;
+            return;
+        }
+        uint8_t* output_buf = NULL;
+        size_t output_length = 0;
+        size_t consumed = 0;
+        std::vector<keymaster_key_param_t> opParams(params.params);
+        int32_t authResult = authorizeOperation(*characteristics, handle, &opParams);
+        if (authResult) {
+            result->resultCode = authResult;
+            return;
+        }
+        keymaster_error_t err = dev->update(dev, handle, opParams.data(), opParams.size(), data,
+                                            dataLength, &consumed, &output_buf, &output_length);
+        result->data.reset(output_buf);
+        result->dataLength = output_length;
+        result->inputConsumed = consumed;
+        result->resultCode = err ? (int32_t) err : ::NO_ERROR;
+    }
+
+    void finish(const sp<IBinder>& token, const KeymasterArguments& params,
+                const uint8_t* signature, size_t signatureLength, OperationResult* result) {
+        const keymaster1_device_t* dev;
+        keymaster_operation_handle_t handle;
+        const keymaster_key_characteristics_t* characteristics;
+        if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) {
+            result->resultCode = KM_ERROR_INVALID_OPERATION_HANDLE;
+            return;
+        }
+        uint8_t* output_buf = NULL;
+        size_t output_length = 0;
+        std::vector<keymaster_key_param_t> opParams(params.params);
+        int32_t authResult = authorizeOperation(*characteristics, handle, &opParams);
+        if (authResult) {
+            result->resultCode = authResult;
+            return;
+        }
+        keymaster_error_t err = dev->finish(dev, handle, opParams.data(), opParams.size(),
+                                            signature, signatureLength, &output_buf,
+                                            &output_length);
+        // Remove the operation regardless of the result
+        mOperationMap.removeOperation(token);
+        mAuthTokenTable.MarkCompleted(handle);
+        result->data.reset(output_buf);
+        result->dataLength = output_length;
+        result->resultCode = err ? (int32_t) err : ::NO_ERROR;
+    }
+
+    int32_t abort(const sp<IBinder>& token) {
+        const keymaster1_device_t* dev;
+        keymaster_operation_handle_t handle;
+        if (!mOperationMap.getOperation(token, &handle, &dev, NULL)) {
+            return KM_ERROR_INVALID_OPERATION_HANDLE;
+        }
+        mOperationMap.removeOperation(token);
+        int32_t rc;
+        if (!dev->abort) {
+            rc = KM_ERROR_UNIMPLEMENTED;
+        } else {
+            rc = dev->abort(dev, handle);
+        }
+        mAuthTokenTable.MarkCompleted(handle);
+        if (rc) {
+            return rc;
+        }
+        return ::NO_ERROR;
+    }
+
+    bool isOperationAuthorized(const sp<IBinder>& token) {
+        const keymaster1_device_t* dev;
+        keymaster_operation_handle_t handle;
+        const keymaster_key_characteristics_t* characteristics;
+        if (!mOperationMap.getOperation(token, &handle, &dev, &characteristics)) {
+            return false;
+        }
+        std::vector<keymaster_key_param_t> ignored;
+        int32_t authResult = authorizeOperation(*characteristics, handle, &ignored);
+        return authResult == KM_ERROR_OK;
+    }
+
+    int32_t addAuthToken(const uint8_t* token, size_t length) {
+        if (!checkBinderPermission(P_ADD_AUTH)) {
+            ALOGW("addAuthToken: permission denied for %d",
+                  IPCThreadState::self()->getCallingUid());
+            return ::PERMISSION_DENIED;
+        }
+        if (length != sizeof(hw_auth_token_t)) {
+            return KM_ERROR_INVALID_ARGUMENT;
+        }
+        hw_auth_token_t* authToken = new hw_auth_token_t;
+        memcpy(reinterpret_cast<void*>(authToken), token, sizeof(hw_auth_token_t));
+        // The table takes ownership of authToken.
+        mAuthTokenTable.AddAuthenticationToken(authToken);
+        return ::NO_ERROR;
+    }
+
 private:
+    static const int32_t UID_SELF = -1;
+
+    /**
+     * Get the effective target uid for a binder operation that takes an
+     * optional uid as the target.
+     */
+    inline uid_t getEffectiveUid(int32_t targetUid) {
+        if (targetUid == UID_SELF) {
+            return IPCThreadState::self()->getCallingUid();
+        }
+        return static_cast<uid_t>(targetUid);
+    }
+
+    /**
+     * Check if the caller of the current binder method has the required
+     * permission and if acting on other uids the grants to do so.
+     */
+    inline bool checkBinderPermission(perm_t permission, int32_t targetUid = UID_SELF) {
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, permission, spid)) {
+            ALOGW("permission %s denied for %d", get_perm_label(permission), callingUid);
+            return false;
+        }
+        if (!is_granted_to(callingUid, getEffectiveUid(targetUid))) {
+            ALOGW("uid %d not granted to act for %d", callingUid, targetUid);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Check if the caller of the current binder method has the required
+     * permission or the target of the operation is the caller's uid. This is
+     * for operation where the permission is only for cross-uid activity and all
+     * uids are allowed to act on their own (ie: clearing all entries for a
+     * given uid).
+     */
+    inline bool checkBinderPermissionOrSelfTarget(perm_t permission, int32_t targetUid) {
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
+        if (getEffectiveUid(targetUid) == callingUid) {
+            return true;
+        } else {
+            return checkBinderPermission(permission, targetUid);
+        }
+    }
+
+    /**
+     * Helper method to check that the caller has the required permission as
+     * well as the keystore is in the unlocked state if checkUnlocked is true.
+     *
+     * Returns NO_ERROR on success, PERMISSION_DENIED on a permission error and
+     * otherwise the state of keystore when not unlocked and checkUnlocked is
+     * true.
+     */
+    inline int32_t checkBinderPermissionAndKeystoreState(perm_t permission, int32_t targetUid = -1,
+                                                 bool checkUnlocked = true) {
+        if (!checkBinderPermission(permission, targetUid)) {
+            return ::PERMISSION_DENIED;
+        }
+        State state = mKeyStore->getState(getEffectiveUid(targetUid));
+        if (checkUnlocked && !isKeystoreUnlocked(state)) {
+            return state;
+        }
+
+        return ::NO_ERROR;
+
+    }
+
     inline bool isKeystoreUnlocked(State state) {
         switch (state) {
         case ::STATE_NO_ERROR:
@@ -2440,7 +2881,7 @@
         return false;
     }
 
-    bool isKeyTypeSupported(const keymaster_device_t* device, keymaster_keypair_t keyType) {
+    bool isKeyTypeSupported(const keymaster1_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) {
@@ -2468,6 +2909,8 @@
     }
 
     ::KeyStore* mKeyStore;
+    OperationMap mOperationMap;
+    keymaster::AuthTokenTable mAuthTokenTable;
 };
 
 }; // namespace android
@@ -2487,12 +2930,18 @@
         return 1;
     }
 
-    keymaster_device_t* dev;
+    keymaster0_device_t* dev;
     if (keymaster_device_initialize(&dev)) {
         ALOGE("keystore keymaster could not be initialized; exiting");
         return 1;
     }
 
+    keymaster1_device_t* fallback;
+    if (fallback_keymaster_device_initialize(&fallback)) {
+        ALOGE("software keymaster could not be initialized; exiting");
+        return 1;
+    }
+
     ks_is_selinux_enabled = is_selinux_enabled();
     if (ks_is_selinux_enabled) {
         union selinux_callback cb;
@@ -2506,7 +2955,7 @@
         ALOGI("SELinux: Keystore SELinux is disabled.\n");
     }
 
-    KeyStore keyStore(&entropy, dev);
+    KeyStore keyStore(&entropy, reinterpret_cast<keymaster1_device_t*>(dev), fallback);
     keyStore.initialize();
     android::sp<android::IServiceManager> sm = android::defaultServiceManager();
     android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore);
diff --git a/keystore/operation.cpp b/keystore/operation.cpp
new file mode 100644
index 0000000..e871f83
--- /dev/null
+++ b/keystore/operation.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2015 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 "KeystoreOperation"
+
+#include "operation.h"
+
+#include <algorithm>
+
+namespace android {
+OperationMap::OperationMap(IBinder::DeathRecipient* deathRecipient)
+        : mDeathRecipient(deathRecipient) {
+}
+
+sp<IBinder> OperationMap::addOperation(keymaster_operation_handle_t handle,
+                                       const keymaster1_device_t* dev,
+                                       sp<IBinder> appToken,
+                                       keymaster_key_characteristics_t* characteristics,
+                                       bool pruneable) {
+    sp<IBinder> token = new BBinder();
+    mMap[token] = std::move(Operation(handle, dev, characteristics, appToken));
+    if (pruneable) {
+        mLru.push_back(token);
+    }
+    if (mAppTokenMap.find(appToken) == mAppTokenMap.end()) {
+        appToken->linkToDeath(mDeathRecipient);
+    }
+    mAppTokenMap[appToken].push_back(token);
+    return token;
+}
+
+bool OperationMap::getOperation(sp<IBinder> token, keymaster_operation_handle_t* outHandle,
+                                const keymaster1_device_t** outDevice,
+                                const keymaster_key_characteristics_t** outCharacteristics) {
+    if (!outHandle || !outDevice) {
+        return false;
+    }
+    auto entry = mMap.find(token);
+    if (entry == mMap.end()) {
+        return false;
+    }
+    updateLru(token);
+
+    *outHandle = entry->second.handle;
+    *outDevice = entry->second.device;
+    if (outCharacteristics) {
+        *outCharacteristics = entry->second.characteristics.get();
+    }
+    return true;
+}
+
+void OperationMap::updateLru(sp<IBinder> token) {
+    auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
+    if (lruEntry != mLru.end()) {
+        mLru.erase(lruEntry);
+        mLru.push_back(token);
+    }
+}
+
+bool OperationMap::removeOperation(sp<IBinder> token) {
+    auto entry = mMap.find(token);
+    if (entry == mMap.end()) {
+        return false;
+    }
+    sp<IBinder> appToken = entry->second.appToken;
+    mMap.erase(entry);
+    auto lruEntry = std::find(mLru.begin(), mLru.end(), token);
+    if (lruEntry != mLru.end()) {
+        mLru.erase(lruEntry);
+    }
+    removeOperationTracking(token, appToken);
+    return true;
+}
+
+void OperationMap::removeOperationTracking(sp<IBinder> token, sp<IBinder> appToken) {
+    auto appEntry = mAppTokenMap.find(appToken);
+    if (appEntry == mAppTokenMap.end()) {
+        ALOGE("Entry for %p contains unmapped application token %p", token.get(), appToken.get());
+        return;
+    }
+    auto tokenEntry = std::find(appEntry->second.begin(), appEntry->second.end(), token);
+    appEntry->second.erase(tokenEntry);
+    // Stop listening for death if all operations tied to the token have finished.
+    if (appEntry->second.size() == 0) {
+        appToken->unlinkToDeath(mDeathRecipient);
+        mAppTokenMap.erase(appEntry);
+    }
+}
+
+bool OperationMap::hasPruneableOperation() {
+    return mLru.size() != 0;
+}
+
+sp<IBinder> OperationMap::getOldestPruneableOperation() {
+    if (!hasPruneableOperation()) {
+        return sp<IBinder>(NULL);
+    }
+    return mLru[0];
+}
+
+std::vector<sp<IBinder>> OperationMap::getOperationsForToken(sp<IBinder> appToken) {
+    auto appEntry = mAppTokenMap.find(appToken);
+    if (appEntry != mAppTokenMap.end()) {
+        return appEntry->second;
+    } else {
+        return std::vector<sp<IBinder>>();
+    }
+}
+
+OperationMap::Operation::Operation(keymaster_operation_handle_t handle_,
+                                   const keymaster1_device_t* device_,
+                                   keymaster_key_characteristics_t* characteristics_,
+                                   sp<IBinder> appToken_)
+    : handle(handle_),
+      device(device_),
+      characteristics(characteristics_),
+      appToken(appToken_) {
+}
+
+OperationMap::Operation::Operation() : handle(0), device(NULL), characteristics(), appToken(NULL) {
+}
+} // namespace android
diff --git a/keystore/operation.h b/keystore/operation.h
new file mode 100644
index 0000000..a312528
--- /dev/null
+++ b/keystore/operation.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 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_OPERATION_H_
+#define KEYSTORE_OPERATION_H_
+
+#include <hardware/keymaster1.h>
+#include <binder/Binder.h>
+#include <binder/IBinder.h>
+#include <utils/LruCache.h>
+#include <utils/StrongPointer.h>
+#include <map>
+#include <vector>
+
+namespace android {
+
+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;
+
+/**
+ * OperationMap handles the translation of keymaster_operation_handle_t's and
+ * keymaster1_device_t's to opaque binder tokens that can be used to reference
+ * that operation at a later time by applications. It also does LRU tracking
+ * for operation pruning and keeps a mapping of clients to operations to allow
+ * for graceful handling of application death.
+ */
+class OperationMap {
+public:
+    OperationMap(IBinder::DeathRecipient* deathRecipient);
+    sp<IBinder> addOperation(keymaster_operation_handle_t handle,
+                             const keymaster1_device_t* dev, sp<IBinder> appToken,
+                             keymaster_key_characteristics_t* characteristics, bool pruneable);
+    bool getOperation(sp<IBinder> token, keymaster_operation_handle_t* outHandle,
+                      const keymaster1_device_t** outDev,
+                      const keymaster_key_characteristics_t** outCharacteristics);
+    bool removeOperation(sp<IBinder> token);
+    bool hasPruneableOperation();
+    sp<IBinder> getOldestPruneableOperation();
+    std::vector<sp<IBinder>> getOperationsForToken(sp<IBinder> appToken);
+
+private:
+    void updateLru(sp<IBinder> token);
+    void removeOperationTracking(sp<IBinder> token, sp<IBinder> appToken);
+    struct Operation {
+        Operation();
+        Operation(keymaster_operation_handle_t handle, const keymaster1_device_t* device,
+                  keymaster_key_characteristics_t* characteristics, sp<IBinder> appToken);
+        keymaster_operation_handle_t handle;
+        const keymaster1_device_t* device;
+        Unique_keymaster_key_characteristics characteristics;
+        sp<IBinder> appToken;
+    };
+    std::map<sp<IBinder>, struct Operation> mMap;
+    std::vector<sp<IBinder>> mLru;
+    std::map<sp<IBinder>, std::vector<sp<IBinder>>> mAppTokenMap;
+    IBinder::DeathRecipient* mDeathRecipient;
+};
+} // namespace android
+#endif
diff --git a/keystore/tests/Android.mk b/keystore/tests/Android.mk
new file mode 100644
index 0000000..be8c426
--- /dev/null
+++ b/keystore/tests/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright (C) 2015 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# Unit test for AuthTokenTable
+include $(CLEAR_VARS)
+ifeq ($(USE_32_BIT_KEYSTORE), true)
+LOCAL_MULTILIB := 32
+endif
+LOCAL_CFLAGS := -Wall -Wextra -Werror
+LOCAL_SRC_FILES := auth_token_table_test.cpp
+LOCAL_MODULE := auth_token_table_test
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_STATIC_LIBRARIES := libgtest_main libkeystore_test
+LOCAL_SHARED_LIBRARIES := libkeymaster_messages
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_NATIVE_TEST)
diff --git a/keystore/tests/Makefile b/keystore/tests/Makefile
new file mode 100644
index 0000000..5c1117f
--- /dev/null
+++ b/keystore/tests/Makefile
@@ -0,0 +1,116 @@
+##########
+# This makefile builds local unit tests that run locally on the development machine.  Note
+# that it may be necessary to install some libraries on the dev maching to make the tests
+# build.
+#
+# The same unit tests are also built by Android.mk to run on the target device.  The tests
+# should always build and pass in both places.  The on-device test is what really matters,
+# of course, but debugging is often somewhat easier on the dev platform.
+##########
+
+BASE=../../../..
+SUBS=system/core \
+	system/keymaster\
+	hardware/libhardware \
+	external/gtest
+GTEST=$(BASE)/external/gtest
+KEYMASTER=$(BASE)/system/keymaster
+
+INCLUDES=$(foreach dir,$(SUBS),-I $(BASE)/$(dir)/include) \
+	-I $(BASE)/libnativehelper/include/nativehelper \
+	-I $(GTEST) -Iinclude
+
+# Add USE_CLANG=1 to the make command line to build with clang, which has better error
+# reporting and diagnoses some conditions that GCC doesn't.
+ifdef USE_CLANG
+CC=/usr/bin/clang
+CXX=/usr/bin/clang
+CLANG_TEST_DEFINE=-DKEYMASTER_CLANG_TEST_BUILD
+COMPILER_SPECIFIC_ARGS=-std=c++11 $(CLANG_TEST_DEFINE)
+else
+COMPILER_SPECIFIC_ARGS=-std=c++0x -fprofile-arcs
+endif
+
+CPPFLAGS=$(INCLUDES) -g -O0 -MD
+CXXFLAGS=-Wall -Werror -Wno-unused -Winit-self -Wpointer-arith	-Wunused-parameter \
+        -Werror=sign-compare -Wmissing-declarations -ftest-coverage -fno-permissive \
+	-Wno-deprecated-declarations -fno-exceptions -DKEYMASTER_NAME_TAGS \
+	$(COMPILER_SPECIFIC_ARGS)
+
+# Uncomment to enable debug logging.
+# CXXFLAGS += -DDEBUG
+
+LDLIBS=-lpthread -lstdc++ -lgcov
+
+# This list of sources is used for dependency generation and cleanup.  Add each new source
+# file here (not headers).
+CPPSRCS=\
+	../auth_token_table.cpp \
+	auth_token_table_test.cpp
+
+# This list of binaries determes what gets built and run.  Add each new test binary here.
+BINARIES=\
+	auth_token_table_test
+
+.PHONY: coverage memcheck massif clean run
+
+%.run: %
+	./$<
+	touch $@
+
+run: $(BINARIES:=.run)
+
+auth_token_table_test: auth_token_table_test.o \
+	../auth_token_table.o \
+	$(GTEST)/src/gtest-all.o \
+	$(KEYMASTER)/authorization_set.o \
+	$(KEYMASTER)/logger.o \
+	$(KEYMASTER)/serializable.o
+
+coverage: coverage.info
+	genhtml coverage.info --output-directory coverage
+
+coverage.info: run
+	lcov --capture --directory=. --directory=.. -b . --output-file coverage.info
+
+%.coverage : %
+	$(MAKE) clean && $(MAKE) $<
+	./$<
+	lcov --capture --directory=. --output-file coverage.info
+	genhtml coverage.info --output-directory coverage
+#UNINIT_OPTS=--track-origins=yes
+UNINIT_OPTS=--undef-value-errors=no
+
+MEMCHECK_OPTS=--leak-check=full \
+	--show-reachable=yes \
+	--vgdb=full \
+	$(UNINIT_OPTS) \
+	--error-exitcode=1
+
+MASSIF_OPTS=--tool=massif \
+	--stacks=yes
+
+%.memcheck : %
+	valgrind $(MEMCHECK_OPTS) ./$< && \
+	touch $@
+
+%.massif : %
+	valgrind $(MASSIF_OPTS) --massif-out-file=$@ ./$<
+
+memcheck: $(BINARIES:=.memcheck)
+
+massif: $(BINARIES:=.massif)
+
+OBJS=$(CPPSRCS:.cpp=.o)
+DEPS=$(CPPSRCS:.cpp=.d)
+GCOV=$(CPPSRCS:.cpp=.gcov) $(CPPSRCS:.cpp=.gcda) $(CPPSRCS:.cpp=.gcno)
+
+clean:
+	rm -f $(OBJS) $(DEPS) $(BINARIES) $(GCOV) \
+		$(BINARIES:=.run) $(BINARIES:=.memcheck) $(BINARIES:=.massif) \
+		*gcov *gcno *gcda coverage.info
+	rm -rf coverage
+
+-include $(CPPSRCS:.cpp=.d)
+-include $(CCSRCS:.cc=.d)
+
diff --git a/keystore/tests/auth_token_table_test.cpp b/keystore/tests/auth_token_table_test.cpp
new file mode 100644
index 0000000..fec7e43
--- /dev/null
+++ b/keystore/tests/auth_token_table_test.cpp
@@ -0,0 +1,410 @@
+/*
+ * Copyright (C) 2015 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 <gtest/gtest.h>
+
+#include <keymaster/google_keymaster_utils.h>
+#include <keymaster/logger.h>
+
+#include "../auth_token_table.h"
+
+using std::vector;
+
+int main(int argc, char** argv) {
+    ::testing::InitGoogleTest(&argc, argv);
+    int result = RUN_ALL_TESTS();
+}
+
+inline bool operator==(const hw_auth_token_t& a, const hw_auth_token_t& b) {
+    return (memcmp(&a, &b, sizeof(a)) == 0);
+}
+
+namespace keymaster {
+namespace test {
+
+class StdoutLogger : public Logger {
+  public:
+    StdoutLogger() { set_instance(this); }
+
+    int log_msg(LogLevel level, const char* fmt, va_list args) const {
+        int output_len = 0;
+        switch (level) {
+        case DEBUG_LVL:
+            output_len = printf("DEBUG: ");
+            break;
+        case INFO_LVL:
+            output_len = printf("INFO: ");
+            break;
+        case WARNING_LVL:
+            output_len = printf("WARNING: ");
+            break;
+        case ERROR_LVL:
+            output_len = printf("ERROR: ");
+            break;
+        case SEVERE_LVL:
+            output_len = printf("SEVERE: ");
+            break;
+        }
+
+        output_len += vprintf(fmt, args);
+        output_len += printf("\n");
+        return output_len;
+    }
+};
+
+StdoutLogger logger;
+
+TEST(AuthTokenTableTest, Create) {
+    AuthTokenTable table;
+}
+
+static hw_auth_token_t* make_token(uint64_t rsid, uint64_t ssid = 0, uint64_t challenge = 0,
+                                   uint64_t timestamp = 0) {
+    hw_auth_token_t* token = new hw_auth_token_t;
+    token->user_id = rsid;
+    token->authenticator_id = ssid;
+    token->authenticator_type = hton(static_cast<uint32_t>(HW_AUTH_PASSWORD));
+    token->challenge = challenge;
+    token->timestamp = hton(timestamp);
+    return token;
+}
+
+static AuthorizationSet make_set(uint64_t rsid, uint32_t timeout = 10000) {
+    AuthorizationSetBuilder builder;
+    builder.Authorization(TAG_USER_ID, 10)
+        .Authorization(TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD)
+        .Authorization(TAG_USER_SECURE_ID, rsid);
+    // Use timeout == 0 to indicate tags that require auth per operation.
+    if (timeout != 0)
+        builder.Authorization(TAG_AUTH_TIMEOUT, timeout);
+    return builder.build();
+}
+
+// Tests obviously run so fast that a real-time clock with a one-second granularity rarely changes
+// output during a test run.  This test clock "ticks" one second every time it's called.
+static time_t monotonic_clock() {
+    static time_t time = 0;
+    return time++;
+}
+
+TEST(AuthTokenTableTest, SimpleAddAndFindTokens) {
+    AuthTokenTable table;
+
+    table.AddAuthenticationToken(make_token(1, 2));
+    table.AddAuthenticationToken(make_token(3, 4));
+    EXPECT_EQ(2U, table.size());
+
+    const hw_auth_token_t* found;
+
+    ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), 0, &found));
+    EXPECT_EQ(1U, found->user_id);
+    EXPECT_EQ(2U, found->authenticator_id);
+
+    ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), 0, &found));
+    EXPECT_EQ(1U, found->user_id);
+    EXPECT_EQ(2U, found->authenticator_id);
+
+    ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), 0, &found));
+    EXPECT_EQ(3U, found->user_id);
+    EXPECT_EQ(4U, found->authenticator_id);
+
+    ASSERT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(4), 0, &found));
+    EXPECT_EQ(3U, found->user_id);
+    EXPECT_EQ(4U, found->authenticator_id);
+
+    ASSERT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(5), 0, &found));
+}
+
+TEST(AuthTokenTableTest, FlushTable) {
+    AuthTokenTable table(3, monotonic_clock);
+
+    table.AddAuthenticationToken(make_token(1));
+    table.AddAuthenticationToken(make_token(2));
+    table.AddAuthenticationToken(make_token(3));
+
+    const hw_auth_token_t* found;
+
+    // All three should be in the table.
+    EXPECT_EQ(3U, table.size());
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), 0, &found));
+
+    table.Clear();
+    EXPECT_EQ(0U, table.size());
+}
+
+TEST(AuthTokenTableTest, TableOverflow) {
+    AuthTokenTable table(3, monotonic_clock);
+
+    table.AddAuthenticationToken(make_token(1));
+    table.AddAuthenticationToken(make_token(2));
+    table.AddAuthenticationToken(make_token(3));
+
+    const hw_auth_token_t* found;
+
+    // All three should be in the table.
+    EXPECT_EQ(3U, table.size());
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), 0, &found));
+
+    table.AddAuthenticationToken(make_token(4));
+
+    // Oldest should be gone.
+    EXPECT_EQ(3U, table.size());
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(1), 0, &found));
+
+    // Others should be there, including the new one (4).  Search for it first, then the others, so
+    // 4 becomes the least recently used.
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(4), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), 0, &found));
+
+    table.AddAuthenticationToken(make_token(5));
+
+    // 5 should have replaced 4.
+    EXPECT_EQ(3U, table.size());
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(4), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(5), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), 0, &found));
+
+    table.AddAuthenticationToken(make_token(6));
+    table.AddAuthenticationToken(make_token(7));
+
+    // 2 and 5 should be gone
+    EXPECT_EQ(3U, table.size());
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(2), 0, &found));
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(5), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(6), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(7), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(3), 0, &found));
+
+    table.AddAuthenticationToken(make_token(8));
+    table.AddAuthenticationToken(make_token(9));
+    table.AddAuthenticationToken(make_token(10));
+
+    // Only the three most recent should be there.
+    EXPECT_EQ(3U, table.size());
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(1), 0, &found));
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(2), 0, &found));
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(3), 0, &found));
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(4), 0, &found));
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(5), 0, &found));
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(6), 0, &found));
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(7), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(8), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(9), 0, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(10), 0, &found));
+}
+
+TEST(AuthTokenTableTest, AuthenticationNotRequired) {
+    AuthTokenTable table;
+    const hw_auth_token_t* found;
+
+    EXPECT_EQ(AuthTokenTable::AUTH_NOT_REQUIRED,
+              table.FindAuthorization(AuthorizationSetBuilder().Authorization(TAG_NO_AUTH_REQUIRED),
+                                      0 /* no challenge */, &found));
+}
+
+TEST(AuthTokenTableTest, OperationHandleNotFound) {
+    AuthTokenTable table;
+    const hw_auth_token_t* found;
+
+    table.AddAuthenticationToken(make_token(1, 0, 1, 5));
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(1, 0 /* no timeout */),
+                                      2 /* non-matching challenge */, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1, 0 /* no timeout */),
+                                                          1 /* matching challenge */, &found));
+    table.MarkCompleted(1);
+    EXPECT_EQ(
+        AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+        table.FindAuthorization(make_set(1, 0 /* no timeout */), 1 /* used challenge */, &found));
+}
+
+TEST(AuthTokenTableTest, OperationHandleRequired) {
+    AuthTokenTable table;
+    const hw_auth_token_t* found;
+
+    table.AddAuthenticationToken(make_token(1));
+    EXPECT_EQ(
+        AuthTokenTable::OP_HANDLE_REQUIRED,
+        table.FindAuthorization(make_set(1, 0 /* no timeout */), 0 /* no op handle */, &found));
+}
+
+TEST(AuthTokenTableTest, AuthSidChanged) {
+    AuthTokenTable table;
+    const hw_auth_token_t* found;
+
+    table.AddAuthenticationToken(make_token(1, 3, /* op handle */ 1));
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_WRONG_SID,
+              table.FindAuthorization(make_set(2, 0 /* no timeout */), 1 /* op handle */, &found));
+}
+
+TEST(AuthTokenTableTest, TokenExpired) {
+    AuthTokenTable table(5, monotonic_clock);
+    const hw_auth_token_t* found;
+
+    auto key_info = make_set(1, 5 /* five second timeout */);
+
+    // monotonic_clock "ticks" one second each time it's called, which is once per request, so the
+    // sixth request should fail, since key_info says the key is good for five seconds.
+    //
+    // Note that this tests the decision of the AuthTokenTable to reject a request it knows is
+    // expired.  An additional check of the secure timestamp (in the token) will be made by
+    // keymaster when the found token is passed to it.
+    table.AddAuthenticationToken(make_token(1, 0));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(key_info, 0 /* no op handle */, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(key_info, 0 /* no op handle */, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(key_info, 0 /* no op handle */, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(key_info, 0 /* no op handle */, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(key_info, 0 /* no op handle */, &found));
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_EXPIRED,
+              table.FindAuthorization(key_info, 0 /* no op handle */, &found));
+}
+
+TEST(AuthTokenTableTest, MarkNonexistentEntryCompleted) {
+    AuthTokenTable table;
+    // Marking a nonexistent entry completed is ignored.  This test is mainly for code coverage.
+    table.MarkCompleted(1);
+}
+
+TEST(AuthTokenTableTest, SupersededEntries) {
+    AuthTokenTable table;
+    const hw_auth_token_t* found;
+
+    // Add two identical tokens, without challenges.  The second should supersede the first, based
+    // on timestamp (fourth arg to make_token).
+    table.AddAuthenticationToken(make_token(1, 0, 0, 0));
+    table.AddAuthenticationToken(make_token(1, 0, 0, 1));
+    EXPECT_EQ(1U, table.size());
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), 0, &found));
+    EXPECT_EQ(1U, ntoh(found->timestamp));
+
+    // Add a third token, this with a different RSID.  It should not be superseded.
+    table.AddAuthenticationToken(make_token(2, 0, 0, 2));
+    EXPECT_EQ(2U, table.size());
+
+    // Add two more, superseding each of the two in the table.
+    table.AddAuthenticationToken(make_token(1, 0, 0, 3));
+    table.AddAuthenticationToken(make_token(2, 0, 0, 4));
+    EXPECT_EQ(2U, table.size());
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), 0, &found));
+    EXPECT_EQ(3U, ntoh(found->timestamp));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), 0, &found));
+    EXPECT_EQ(4U, ntoh(found->timestamp));
+
+    // Add another, this one with a challenge value.  It should supersede the old one since it is
+    // newer, and matches other than the challenge.
+    table.AddAuthenticationToken(make_token(1, 0, 1, 5));
+    EXPECT_EQ(2U, table.size());
+
+    // And another, also with a challenge.  Because of the challenge values, the one just added
+    // cannot be superseded.
+    table.AddAuthenticationToken(make_token(1, 0, 2, 6));
+    EXPECT_EQ(3U, table.size());
+
+    // Should be able to find each of them, by specifying their challenge, with a key that is not
+    // timed (timed keys don't care about challenges).
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(1, 0 /* no timeout*/), 1 /* challenge */, &found));
+    EXPECT_EQ(5U, ntoh(found->timestamp));
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(1, 0 /* no timeout */), 2 /* challenge */, &found));
+    EXPECT_EQ(6U, ntoh(found->timestamp));
+
+    // Add another, without a challenge, and the same timestamp as the last one.  This new one
+    // actually could be considered already-superseded, but the table doesn't handle that case,
+    // since it seems unlikely to occur in practice.
+    table.AddAuthenticationToken(make_token(1, 0, 0, 6));
+    EXPECT_EQ(4U, table.size());
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), 0 /* challenge */, &found));
+    EXPECT_EQ(6U, ntoh(found->timestamp));
+
+    // Add another without a challenge but an increased timestamp. This should supersede the
+    // previous challenge-free entry.
+    table.AddAuthenticationToken(make_token(1, 0, 0, 7));
+    EXPECT_EQ(4U, table.size());
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(1, 0 /* no timeout */), 2 /* challenge */, &found));
+    EXPECT_EQ(6U, ntoh(found->timestamp));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), 0 /* challenge */, &found));
+    EXPECT_EQ(7U, ntoh(found->timestamp));
+
+    // Mark the entry with challenge 2 as complete.  Since there's a newer challenge-free entry, the
+    // challenge entry will be superseded.
+    table.MarkCompleted(2);
+    EXPECT_EQ(3U, table.size());
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(1, 0 /* no timeout */), 2 /* challenge */, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), 0 /* challenge */, &found));
+    EXPECT_EQ(7U, ntoh(found->timestamp));
+
+    // Add another SID 1 entry with a challenge.  It supersedes the previous SID 1 entry with
+    // no challenge (timestamp 7), but not the one with challenge 1 (timestamp 5).
+    table.AddAuthenticationToken(make_token(1, 0, 3, 8));
+    EXPECT_EQ(3U, table.size());
+
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(1, 0 /* no timeout */), 1 /* challenge */, &found));
+    EXPECT_EQ(5U, ntoh(found->timestamp));
+
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(1, 0 /* no timeout */), 3 /* challenge */, &found));
+    EXPECT_EQ(8U, ntoh(found->timestamp));
+
+    // SID 2 entry is still there.
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(2), 0 /* challenge */, &found));
+    EXPECT_EQ(4U, ntoh(found->timestamp));
+
+    // Mark the entry with challenge 3 as complete.  Since the older challenge 1 entry is
+    // incomplete, nothing is superseded.
+    table.MarkCompleted(3);
+    EXPECT_EQ(3U, table.size());
+
+    EXPECT_EQ(AuthTokenTable::OK,
+              table.FindAuthorization(make_set(1, 0 /* no timeout */), 1 /* challenge */, &found));
+    EXPECT_EQ(5U, ntoh(found->timestamp));
+
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), 0 /* challenge */, &found));
+    EXPECT_EQ(8U, ntoh(found->timestamp));
+
+    // Mark the entry with challenge 1 as complete.  Since there's a newer one (with challenge 3,
+    // completed), the challenge 1 entry is superseded and removed.
+    table.MarkCompleted(1);
+    EXPECT_EQ(2U, table.size());
+    EXPECT_EQ(AuthTokenTable::AUTH_TOKEN_NOT_FOUND,
+              table.FindAuthorization(make_set(1, 0 /* no timeout */), 1 /* challenge */, &found));
+    EXPECT_EQ(AuthTokenTable::OK, table.FindAuthorization(make_set(1), 0 /* challenge */, &found));
+    EXPECT_EQ(8U, ntoh(found->timestamp));
+}
+
+}  // namespace keymaster
+}  // namespace test
diff --git a/softkeymaster/Android.mk b/softkeymaster/Android.mk
index 0c733aa..eb32c87 100644
--- a/softkeymaster/Android.mk
+++ b/softkeymaster/Android.mk
@@ -21,9 +21,7 @@
 LOCAL_MODULE := keystore.default
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SRC_FILES := module.cpp
-LOCAL_C_INCLUDES := \
-	system/security/keystore \
-	external/openssl/include
+LOCAL_C_INCLUDES := system/security/keystore
 LOCAL_CFLAGS = -fvisibility=hidden -Wall -Werror
 LOCAL_SHARED_LIBRARIES := libcrypto liblog libkeystore_binder libsoftkeymaster
 LOCAL_MODULE_TAGS := optional
@@ -36,9 +34,8 @@
 endif
 LOCAL_MODULE := libsoftkeymaster
 LOCAL_SRC_FILES := keymaster_openssl.cpp
-LOCAL_C_INCLUDES := \
-	system/security/keystore \
-	external/openssl/include
+LOCAL_C_INCLUDES := system/security/keystore \
+	$(LOCAL_PATH)/include
 LOCAL_CFLAGS = -fvisibility=hidden -Wall -Werror
 LOCAL_SHARED_LIBRARIES := libcrypto liblog libkeystore_binder
 LOCAL_MODULE_TAGS := optional
diff --git a/softkeymaster/include/keymaster/softkeymaster.h b/softkeymaster/include/keymaster/softkeymaster.h
index f304aed..e86ba3d 100644
--- a/softkeymaster/include/keymaster/softkeymaster.h
+++ b/softkeymaster/include/keymaster/softkeymaster.h
@@ -14,28 +14,32 @@
  * limitations under the License.
  */
 
-#include <hardware/keymaster.h>
+#include <hardware/keymaster0.h>
 
 #ifndef SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H_
 #define SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H_
 
-int openssl_generate_keypair(const keymaster_device_t* dev, const keymaster_keypair_t key_type,
+int openssl_generate_keypair(const keymaster0_device_t* dev, const keymaster_keypair_t key_type,
                              const void* key_params, uint8_t** keyBlob, size_t* keyBlobLength);
 
-int openssl_import_keypair(const keymaster_device_t* dev, const uint8_t* key,
+int openssl_import_keypair(const keymaster0_device_t* dev, const uint8_t* key,
                            const size_t key_length, uint8_t** key_blob, size_t* key_blob_length);
 
-int openssl_get_keypair_public(const struct keymaster_device* dev, const uint8_t* key_blob,
+int openssl_get_keypair_public(const struct keymaster0_device* dev, const uint8_t* key_blob,
                                const size_t key_blob_length, uint8_t** x509_data,
                                size_t* x509_data_length);
 
-int openssl_sign_data(const keymaster_device_t* dev, const void* params, const uint8_t* keyBlob,
+int openssl_sign_data(const keymaster0_device_t* dev, const void* params, const uint8_t* keyBlob,
                       const size_t keyBlobLength, const uint8_t* data, const size_t dataLength,
                       uint8_t** signedData, size_t* signedDataLength);
 
-int openssl_verify_data(const keymaster_device_t* dev, const void* params, const uint8_t* keyBlob,
+int openssl_verify_data(const keymaster0_device_t* dev, const void* params, const uint8_t* keyBlob,
                         const size_t keyBlobLength, const uint8_t* signedData,
                         const size_t signedDataLength, const uint8_t* signature,
                         const size_t signatureLength);
 
+int openssl_open(const hw_module_t* module, const char* name, hw_device_t** device);
+
+extern struct keystore_module softkeymaster_module;
+
 #endif  // SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H_
diff --git a/softkeymaster/keymaster_openssl.cpp b/softkeymaster/keymaster_openssl.cpp
index 85ecc6e..edf4db2 100644
--- a/softkeymaster/keymaster_openssl.cpp
+++ b/softkeymaster/keymaster_openssl.cpp
@@ -18,9 +18,10 @@
 #include <stdint.h>
 
 #include <keystore/keystore.h>
+#include <keymaster/softkeymaster.h>
 
 #include <hardware/hardware.h>
-#include <hardware/keymaster.h>
+#include <hardware/keymaster0.h>
 
 #include <openssl/evp.h>
 #include <openssl/bio.h>
@@ -37,61 +38,45 @@
 #include <cutils/log.h>
 
 struct BIGNUM_Delete {
-    void operator()(BIGNUM* p) const {
-        BN_free(p);
-    }
+    void operator()(BIGNUM* p) const { BN_free(p); }
 };
 typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
 
 struct EVP_PKEY_Delete {
-    void operator()(EVP_PKEY* p) const {
-        EVP_PKEY_free(p);
-    }
+    void operator()(EVP_PKEY* p) const { EVP_PKEY_free(p); }
 };
 typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
 
 struct PKCS8_PRIV_KEY_INFO_Delete {
-    void operator()(PKCS8_PRIV_KEY_INFO* p) const {
-        PKCS8_PRIV_KEY_INFO_free(p);
-    }
+    void operator()(PKCS8_PRIV_KEY_INFO* p) const { PKCS8_PRIV_KEY_INFO_free(p); }
 };
 typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
 
 struct DSA_Delete {
-    void operator()(DSA* p) const {
-        DSA_free(p);
-    }
+    void operator()(DSA* p) const { DSA_free(p); }
 };
 typedef UniquePtr<DSA, DSA_Delete> Unique_DSA;
 
 struct EC_KEY_Delete {
-    void operator()(EC_KEY* p) const {
-        EC_KEY_free(p);
-    }
+    void operator()(EC_KEY* p) const { EC_KEY_free(p); }
 };
 typedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
 
 struct EC_GROUP_Delete {
-    void operator()(EC_GROUP* p) const {
-        EC_GROUP_free(p);
-    }
+    void operator()(EC_GROUP* p) const { EC_GROUP_free(p); }
 };
 typedef UniquePtr<EC_GROUP, EC_GROUP_Delete> Unique_EC_GROUP;
 
 struct RSA_Delete {
-    void operator()(RSA* p) const {
-        RSA_free(p);
-    }
+    void operator()(RSA* p) const { RSA_free(p); }
 };
 typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
 
 struct Malloc_Free {
-    void operator()(void* p) const {
-        free(p);
-    }
+    void operator()(void* p) const { free(p); }
 };
 
-typedef UniquePtr<keymaster_device_t> Unique_keymaster_device_t;
+typedef UniquePtr<keymaster0_device_t> Unique_keymaster_device_t;
 
 /**
  * Many OpenSSL APIs take ownership of an argument on success but
@@ -118,7 +103,7 @@
     }
 
     ERR_clear_error();
-    ERR_remove_state(0);
+    ERR_remove_thread_state(NULL);
 }
 
 static int wrap_key(EVP_PKEY* pkey, int type, uint8_t** keyBlob, size_t* keyBlobLength) {
@@ -291,9 +276,6 @@
 static int generate_ec_keypair(EVP_PKEY* pkey, const keymaster_ec_keygen_params_t* ec_params) {
     Unique_EC_GROUP group;
     switch (ec_params->field_size) {
-    case 192:
-        group.reset(EC_GROUP_new_by_curve_name(NID_X9_62_prime192v1));
-        break;
     case 224:
         group.reset(EC_GROUP_new_by_curve_name(NID_secp224r1));
         break;
@@ -315,8 +297,10 @@
         return -1;
     }
 
+#if !defined(OPENSSL_IS_BORINGSSL)
     EC_GROUP_set_point_conversion_form(group.get(), POINT_CONVERSION_UNCOMPRESSED);
     EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE);
+#endif
 
     /* initialize EC key */
     Unique_EC_KEY eckey(EC_KEY_new());
@@ -379,7 +363,7 @@
 }
 
 __attribute__((visibility("default"))) int openssl_generate_keypair(
-    const keymaster_device_t*, const keymaster_keypair_t key_type, const void* key_params,
+    const keymaster0_device_t*, const keymaster_keypair_t key_type, const void* key_params,
     uint8_t** keyBlob, size_t* keyBlobLength) {
     Unique_EVP_PKEY pkey(EVP_PKEY_new());
     if (pkey.get() == NULL) {
@@ -414,7 +398,7 @@
     return 0;
 }
 
-__attribute__((visibility("default"))) int openssl_import_keypair(const keymaster_device_t*,
+__attribute__((visibility("default"))) int openssl_import_keypair(const keymaster0_device_t*,
                                                                   const uint8_t* key,
                                                                   const size_t key_length,
                                                                   uint8_t** key_blob,
@@ -439,7 +423,6 @@
         logOpenSSLError("openssl_import_keypair");
         return -1;
     }
-    release_because_ownership_transferred(pkcs8);
 
     if (wrap_key(pkey.get(), EVP_PKEY_type(pkey->type), key_blob, key_blob_length)) {
         return -1;
@@ -448,10 +431,11 @@
     return 0;
 }
 
-__attribute__((visibility("default"))) int openssl_get_keypair_public(
-    const struct keymaster_device*, const uint8_t* key_blob, const size_t key_blob_length,
-    uint8_t** x509_data, size_t* x509_data_length) {
-
+__attribute__((visibility("default"))) int openssl_get_keypair_public(const keymaster0_device_t*,
+                                                                      const uint8_t* key_blob,
+                                                                      const size_t key_blob_length,
+                                                                      uint8_t** x509_data,
+                                                                      size_t* x509_data_length) {
     if (x509_data == NULL || x509_data_length == NULL) {
         ALOGW("output public key buffer == NULL");
         return -1;
@@ -586,7 +570,7 @@
 }
 
 __attribute__((visibility("default"))) int openssl_sign_data(
-    const keymaster_device_t*, const void* params, const uint8_t* keyBlob,
+    const keymaster0_device_t*, const void* params, const uint8_t* keyBlob,
     const size_t keyBlobLength, const uint8_t* data, const size_t dataLength, uint8_t** signedData,
     size_t* signedDataLength) {
     if (data == NULL) {
@@ -710,10 +694,9 @@
 }
 
 __attribute__((visibility("default"))) int openssl_verify_data(
-    const keymaster_device_t*, const void* params, const uint8_t* keyBlob,
+    const keymaster0_device_t*, const void* params, const uint8_t* keyBlob,
     const size_t keyBlobLength, const uint8_t* signedData, const size_t signedDataLength,
     const uint8_t* signature, const size_t signatureLength) {
-
     if (signedData == NULL || signature == NULL) {
         ALOGW("data or signature buffers == NULL");
         return -1;
@@ -745,3 +728,63 @@
         return -1;
     }
 }
+
+/* Close an opened OpenSSL instance */
+static int openssl_close(hw_device_t* dev) {
+    delete dev;
+    return 0;
+}
+
+/*
+ * Generic device handling
+ */
+__attribute__((visibility("default"))) int openssl_open(const hw_module_t* module, const char* name,
+                                                        hw_device_t** device) {
+    if (strcmp(name, KEYSTORE_KEYMASTER) != 0)
+        return -EINVAL;
+
+    Unique_keymaster_device_t dev(new keymaster0_device_t);
+    if (dev.get() == NULL)
+        return -ENOMEM;
+
+    dev->common.tag = HARDWARE_DEVICE_TAG;
+    dev->common.version = 1;
+    dev->common.module = (struct hw_module_t*)module;
+    dev->common.close = openssl_close;
+
+    dev->flags = KEYMASTER_SOFTWARE_ONLY;
+
+    dev->generate_keypair = openssl_generate_keypair;
+    dev->import_keypair = openssl_import_keypair;
+    dev->get_keypair_public = openssl_get_keypair_public;
+    dev->delete_keypair = NULL;
+    dev->delete_all = NULL;
+    dev->sign_data = openssl_sign_data;
+    dev->verify_data = openssl_verify_data;
+
+    ERR_load_crypto_strings();
+    ERR_load_BIO_strings();
+
+    *device = reinterpret_cast<hw_device_t*>(dev.release());
+
+    return 0;
+}
+
+static struct hw_module_methods_t keystore_module_methods = {
+    .open = openssl_open,
+};
+
+struct keystore_module softkeymaster_module __attribute__((visibility("default"))) = {
+    .common =
+        {
+         .tag = HARDWARE_MODULE_TAG,
+         .module_api_version = KEYMASTER_MODULE_API_VERSION_0_2,
+         .hal_api_version = HARDWARE_HAL_API_VERSION,
+         .id = KEYSTORE_HARDWARE_MODULE_ID,
+         .name = "Keymaster OpenSSL HAL",
+         .author = "The Android Open Source Project",
+         .methods = &keystore_module_methods,
+         .dso = 0,
+         .reserved = {},
+        },
+};
diff --git a/softkeymaster/module.cpp b/softkeymaster/module.cpp
index 9eeb9b4..0dcbadd 100644
--- a/softkeymaster/module.cpp
+++ b/softkeymaster/module.cpp
@@ -13,83 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#include <errno.h>
-#include <string.h>
-#include <stdint.h>
-
 #include <keymaster/softkeymaster.h>
 
 #include <keystore/keystore.h>
 
 #include <hardware/hardware.h>
-#include <hardware/keymaster.h>
+#include <hardware/keymaster0.h>
 
-#include <openssl/err.h>
-
-#include <UniquePtr.h>
-
-// For debugging
-// #define LOG_NDEBUG 0
-
-#define LOG_TAG "OpenSSLKeyMaster"
-#include <cutils/log.h>
-
-typedef UniquePtr<keymaster_device_t> Unique_keymaster_device_t;
-
-/* Close an opened OpenSSL instance */
-static int openssl_close(hw_device_t* dev) {
-    delete dev;
-    return 0;
-}
-
-/*
- * Generic device handling
- */
-static int openssl_open(const hw_module_t* module, const char* name, hw_device_t** device) {
-    if (strcmp(name, KEYSTORE_KEYMASTER) != 0)
-        return -EINVAL;
-
-    Unique_keymaster_device_t dev(new keymaster_device_t);
-    if (dev.get() == NULL)
-        return -ENOMEM;
-
-    dev->common.tag = HARDWARE_DEVICE_TAG;
-    dev->common.version = 1;
-    dev->common.module = (struct hw_module_t*)module;
-    dev->common.close = openssl_close;
-
-    dev->flags = KEYMASTER_SOFTWARE_ONLY | KEYMASTER_BLOBS_ARE_STANDALONE;
-
-    dev->generate_keypair = openssl_generate_keypair;
-    dev->import_keypair = openssl_import_keypair;
-    dev->get_keypair_public = openssl_get_keypair_public;
-    dev->delete_keypair = NULL;
-    dev->delete_all = NULL;
-    dev->sign_data = openssl_sign_data;
-    dev->verify_data = openssl_verify_data;
-
-    ERR_load_crypto_strings();
-    ERR_load_BIO_strings();
-
-    *device = reinterpret_cast<hw_device_t*>(dev.release());
-
-    return 0;
-}
-
-static struct hw_module_methods_t keystore_module_methods = {
-    .open = openssl_open,
-};
-
-struct keystore_module HAL_MODULE_INFO_SYM __attribute__((visibility("default"))) = {
-    .common = {
-        .tag = HARDWARE_MODULE_TAG,
-        .module_api_version = KEYMASTER_MODULE_API_VERSION_0_2,
-        .hal_api_version = HARDWARE_HAL_API_VERSION,
-        .id = KEYSTORE_HARDWARE_MODULE_ID,
-        .name = "Keymaster OpenSSL HAL",
-        .author = "The Android Open Source Project",
-        .methods = &keystore_module_methods,
-        .dso = 0,
-        .reserved = {},
-    },
-};
+struct keystore_module HAL_MODULE_INFO_SYM __attribute__((visibility("default")))
+    = softkeymaster_module;
