diff --git a/keystore-engine/Android.mk b/keystore-engine/Android.mk
index 89d3fba..acad442 100644
--- a/keystore-engine/Android.mk
+++ b/keystore-engine/Android.mk
@@ -27,13 +27,14 @@
 LOCAL_CFLAGS := -fvisibility=hidden -Wall -Werror
 
 LOCAL_C_INCLUDES += \
-	system/security/keystore \
 	external/openssl/include
 
 LOCAL_SHARED_LIBRARIES += \
 	libcrypto \
 	liblog \
 	libcutils \
-	libkeystore_client
+	libutils \
+	libbinder \
+	libkeystore_binder
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/keystore-engine/eng_keystore.cpp b/keystore-engine/eng_keystore.cpp
index 8a6df77..4790a66 100644
--- a/keystore-engine/eng_keystore.cpp
+++ b/keystore-engine/eng_keystore.cpp
@@ -23,8 +23,6 @@
  *
  */
 
-#include <keystore.h>
-
 #include <utils/UniquePtr.h>
 
 #include <sys/socket.h>
@@ -40,8 +38,11 @@
 #define LOG_TAG "OpenSSL-keystore"
 #include <cutils/log.h>
 
-#include <keystore_client.h>
+#include <binder/IServiceManager.h>
+#include <keystore/keystore.h>
+#include <keystore/IKeystoreService.h>
 
+using namespace android;
 
 #define DYNAMIC_ENGINE
 #define KEYSTORE_ENGINE_ID   "keystore"
@@ -160,21 +161,33 @@
         return 0;
     }
 
-    Keystore_Reply reply;
-    if (keystore_cmd(CommandCodes[SIGN], &reply, 2, strlen(reinterpret_cast<const char*>(key_id)),
-            key_id, static_cast<size_t>(num), reinterpret_cast<const uint8_t*>(padded.get()))
-            != NO_ERROR) {
-        ALOGE("There was an error during rsa_mod_exp");
+    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;
     }
 
-    const size_t replyLen = reply.length();
-    if (replyLen <= 0) {
+    uint8_t* reply = NULL;
+    size_t replyLen;
+    int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)), padded.get(),
+            num, &reply, &replyLen);
+    if (ret < 0) {
+        ALOGW("There was an error during rsa_mod_exp: could not connect");
+        free(reply);
+        return 0;
+    } else if (ret != 0) {
+        ALOGW("Error during rsa_mod_exp from keystore: %d", ret);
+        free(reply);
+        return 0;
+    } else if (replyLen <= 0) {
         ALOGW("No valid signature returned");
         return 0;
     }
 
-    memcpy(to, reply.get(), replyLen);
+    memcpy(to, reply, replyLen);
 
     ALOGV("rsa=%p keystore_rsa_sign => returning %p len %llu", rsa, to,
             (unsigned long long) replyLen);
@@ -219,14 +232,31 @@
     ALOGV("keystore_loadkey(%p, \"%s\", %p, %p)", e, key_id, ui_method, callback_data);
 #endif
 
-    Keystore_Reply reply;
-    if (keystore_cmd(CommandCodes[GET_PUBKEY], &reply, 1, strlen(key_id), key_id) != NO_ERROR) {
-        ALOGV("Cannot get public key for %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 pubkeyLen;
+    int32_t ret = service->get_pubkey(String16(key_id), &pubkey, &pubkeyLen);
+    if (ret < 0) {
+        ALOGW("could not contact keystore");
+        free(pubkey);
+        return NULL;
+    } else if (ret != 0) {
+        ALOGW("keystore reports error: %d", ret);
+        free(pubkey);
         return NULL;
     }
 
-    const unsigned char* tmp = reinterpret_cast<const unsigned char*>(reply.get());
-    Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, reply.length()));
+    const unsigned char* tmp = reinterpret_cast<const unsigned char*>(pubkey);
+    Unique_EVP_PKEY pkey(d2i_PUBKEY(NULL, &tmp, pubkeyLen));
+    free(pubkey);
     if (pkey.get() == NULL) {
         ALOGW("Cannot convert pubkey");
         return NULL;
diff --git a/keystore/Android.mk b/keystore/Android.mk
index d4fbe06..8824dfe 100644
--- a/keystore/Android.mk
+++ b/keystore/Android.mk
@@ -20,7 +20,7 @@
 LOCAL_CFLAGS := -Wall -Wextra -Werror
 LOCAL_SRC_FILES := keystore.cpp keyblob_utils.cpp
 LOCAL_C_INCLUDES := external/openssl/include
-LOCAL_SHARED_LIBRARIES := libcutils libcrypto libhardware
+LOCAL_SHARED_LIBRARIES := libcutils libcrypto libhardware libkeystore_binder libutils libbinder
 LOCAL_MODULE := keystore
 LOCAL_MODULE_TAGS := optional
 include $(BUILD_EXECUTABLE)
@@ -29,7 +29,7 @@
 LOCAL_CFLAGS := -Wall -Wextra -Werror
 LOCAL_SRC_FILES := keystore_cli.cpp
 LOCAL_C_INCLUDES := external/openssl/include
-LOCAL_SHARED_LIBRARIES := libcutils libcrypto
+LOCAL_SHARED_LIBRARIES := libcutils libcrypto libkeystore_binder libutils libbinder
 LOCAL_MODULE := keystore_cli
 LOCAL_MODULE_TAGS := debug
 include $(BUILD_EXECUTABLE)
@@ -37,8 +37,10 @@
 # Library for keystore clients
 include $(CLEAR_VARS)
 LOCAL_CFLAGS := -Wall -Wextra -Werror
-LOCAL_SRC_FILES := keystore_client.cpp keyblob_utils.cpp
-LOCAL_SHARED_LIBRARIES := libcutils
-LOCAL_MODULE := libkeystore_client
+LOCAL_SRC_FILES := IKeystoreService.cpp keystore_get.cpp keyblob_utils.cpp
+LOCAL_SHARED_LIBRARIES := libbinder libutils
+LOCAL_MODULE := libkeystore_binder
 LOCAL_MODULE_TAGS := optional
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
 include $(BUILD_SHARED_LIBRARY)
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
new file mode 100644
index 0000000..9b4590e
--- /dev/null
+++ b/keystore/IKeystoreService.cpp
@@ -0,0 +1,726 @@
+/*
+**
+** Copyright 2008, 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 <stdint.h>
+#include <sys/types.h>
+
+#define LOG_TAG "KeystoreService"
+#include <utils/Log.h>
+
+#include <binder/Parcel.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <keystore/IKeystoreService.h>
+
+namespace android {
+
+class BpKeystoreService: public BpInterface<IKeystoreService>
+{
+public:
+    BpKeystoreService(const sp<IBinder>& impl)
+        : BpInterface<IKeystoreService>(impl)
+    {
+    }
+
+    // test ping
+    virtual int32_t test()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        status_t status = remote()->transact(BnKeystoreService::TEST, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("test() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("test() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t get(const String16& name, uint8_t** item, size_t* itemLength)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::GET, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("get() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        ssize_t len = reply.readInt32();
+        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
+            size_t ulen = (size_t) len;
+            const void* buf = reply.readInplace(ulen);
+            *item = (uint8_t*) malloc(ulen);
+            if (*item != NULL) {
+                memcpy(*item, buf, ulen);
+                *itemLength = ulen;
+            } else {
+                ALOGE("out of memory allocating output array in get");
+                *itemLength = 0;
+            }
+        } else {
+            *itemLength = 0;
+        }
+        if (err < 0) {
+            ALOGD("get() caught exception %d\n", err);
+            return -1;
+        }
+        return 0;
+    }
+
+    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(itemLength);
+        void* buf = data.writeInplace(itemLength);
+        memcpy(buf, item, itemLength);
+        status_t status = remote()->transact(BnKeystoreService::INSERT, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("import() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("import() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t del(const String16& name)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::DEL, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("del() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("del() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t exist(const String16& name)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::EXIST, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("exist() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("exist() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t saw(const String16& name, Vector<String16>* matches)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::SAW, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("saw() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t numMatches = reply.readInt32();
+        for (int32_t i = 0; i < numMatches; i++) {
+            matches->push(reply.readString16());
+        }
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("saw() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t reset()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        status_t status = remote()->transact(BnKeystoreService::RESET, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("reset() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("reset() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t password(const String16& password)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(password);
+        status_t status = remote()->transact(BnKeystoreService::PASSWORD, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("password() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("password() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t lock()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        status_t status = remote()->transact(BnKeystoreService::LOCK, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("lock() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("lock() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t unlock(const String16& password)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(password);
+        status_t status = remote()->transact(BnKeystoreService::UNLOCK, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("unlock() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("unlock() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t zero()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        status_t status = remote()->transact(BnKeystoreService::ZERO, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("zero() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("zero() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t generate(const String16& name)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::GENERATE, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("generate() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("generate() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t import(const String16& name, const uint8_t* key, size_t keyLength)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(keyLength);
+        void* buf = data.writeInplace(keyLength);
+        memcpy(buf, key, keyLength);
+        status_t status = remote()->transact(BnKeystoreService::IMPORT, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("import() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("import() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t sign(const String16& name, const uint8_t* in, size_t inLength, uint8_t** out,
+            size_t* outLength)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(inLength);
+        void* buf = data.writeInplace(inLength);
+        memcpy(buf, in, inLength);
+        status_t status = remote()->transact(BnKeystoreService::SIGN, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("import() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        ssize_t len = reply.readInt32();
+        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
+            size_t ulen = (size_t) len;
+            const void* outBuf = reply.readInplace(ulen);
+            *out = (uint8_t*) malloc(ulen);
+            if (*out != NULL) {
+                memcpy((void*) *out, outBuf, ulen);
+                *outLength = ulen;
+            } else {
+                ALOGE("out of memory allocating output array in sign");
+                *outLength = 0;
+            }
+        } else {
+            *outLength = 0;
+        }
+        if (err < 0) {
+            ALOGD("import() caught exception %d\n", err);
+            return -1;
+        }
+        return 0;
+    }
+
+    virtual int32_t verify(const String16& name, const uint8_t* in, size_t inLength,
+            const uint8_t* signature, size_t signatureLength)
+    {
+        Parcel data, reply;
+        void* buf;
+
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(inLength);
+        buf = data.writeInplace(inLength);
+        memcpy(buf, in, inLength);
+        data.writeInt32(signatureLength);
+        buf = data.writeInplace(signatureLength);
+        memcpy(buf, signature, signatureLength);
+        status_t status = remote()->transact(BnKeystoreService::VERIFY, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("verify() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("verify() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::GET_PUBKEY, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("get_pubkey() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        ssize_t len = reply.readInt32();
+        if (len >= 0 && (size_t) len <= reply.dataAvail()) {
+            size_t ulen = (size_t) len;
+            const void* buf = reply.readInplace(ulen);
+            *pubkey = (uint8_t*) malloc(ulen);
+            if (*pubkey != NULL) {
+                memcpy(*pubkey, buf, ulen);
+                *pubkeyLength = ulen;
+            } else {
+                ALOGE("out of memory allocating output array in get_pubkey");
+                *pubkeyLength = 0;
+            }
+        } else {
+            *pubkeyLength = 0;
+        }
+        if (err < 0) {
+            ALOGD("get_pubkey() caught exception %d\n", err);
+            return -1;
+        }
+        return 0;
+     }
+
+    virtual int32_t del_key(const String16& name)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::DEL_KEY, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("del_key() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("del_key() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t grant(const String16& name, int32_t granteeUid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(granteeUid);
+        status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("grant() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("grant() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t ungrant(const String16& name, int32_t granteeUid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        data.writeInt32(granteeUid);
+        status_t status = remote()->transact(BnKeystoreService::UNGRANT, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("ungrant() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("ungrant() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    int64_t getmtime(const String16& name)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(name);
+        status_t status = remote()->transact(BnKeystoreService::GETMTIME, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("getmtime() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int64_t ret = reply.readInt64();
+        if (err < 0) {
+            ALOGD("getmtime() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+};
+
+IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
+
+// ----------------------------------------------------------------------
+
+status_t BnKeystoreService::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case TEST: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t ret = test();
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case GET: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            void* out = NULL;
+            size_t outSize = 0;
+            int32_t ret = get(name, (uint8_t**) &out, &outSize);
+            reply->writeNoException();
+            if (ret == 1) {
+                reply->writeInt32(outSize);
+                void* buf = reply->writeInplace(outSize);
+                memcpy(buf, out, outSize);
+                free(out);
+            } else {
+                reply->writeInt32(-1);
+            }
+            return NO_ERROR;
+        } break;
+        case INSERT: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            ssize_t inSize = data.readInt32();
+            const void* in;
+            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
+                in = data.readInplace(inSize);
+            } else {
+                in = NULL;
+                inSize = 0;
+            }
+            int32_t ret = insert(name, (const uint8_t*) in, (size_t) inSize);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case DEL: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t ret = del(name);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case EXIST: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t ret = exist(name);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case SAW: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            Vector<String16> matches;
+            int32_t ret = saw(name, &matches);
+            reply->writeNoException();
+            reply->writeInt32(matches.size());
+            Vector<String16>::const_iterator it = matches.begin();
+            for (; it != matches.end(); ++it) {
+                reply->writeString16(*it);
+            }
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case RESET: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t ret = reset();
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case PASSWORD: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 pass = data.readString16();
+            int32_t ret = password(pass);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case LOCK: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t ret = lock();
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case UNLOCK: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 pass = data.readString16();
+            int32_t ret = unlock(pass);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case ZERO: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t ret = zero();
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case GENERATE: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t ret = generate(name);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case IMPORT: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            ssize_t inSize = data.readInt32();
+            const void* in;
+            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
+                in = data.readInplace(inSize);
+            } else {
+                in = NULL;
+                inSize = 0;
+            }
+            int32_t ret = import(name, (const uint8_t*) in, (size_t) inSize);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case SIGN: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            ssize_t inSize = data.readInt32();
+            const void* in;
+            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
+                in = data.readInplace(inSize);
+            } else {
+                in = NULL;
+                inSize = 0;
+            }
+            void* out = NULL;
+            size_t outSize = 0;
+            int32_t ret = sign(name, (const uint8_t*) in, (size_t) inSize, (uint8_t**) &out, &outSize);
+            reply->writeNoException();
+            reply->writeInt32(outSize);
+            void* buf = reply->writeInplace(outSize);
+            memcpy(buf, out, outSize);
+            free(out);
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case VERIFY: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            ssize_t inSize = data.readInt32();
+            const void* in;
+            if (inSize >= 0 && (size_t) inSize <= data.dataAvail()) {
+                in = data.readInplace(inSize);
+            } else {
+                in = NULL;
+                inSize = 0;
+            }
+            ssize_t sigSize = data.readInt32();
+            const void* sig;
+            if (sigSize >= 0 && (size_t) sigSize <= data.dataAvail()) {
+                sig = data.readInplace(sigSize);
+            } else {
+                sig = NULL;
+                sigSize = 0;
+            }
+            bool ret = verify(name, (const uint8_t*) in, (size_t) inSize, (const uint8_t*) sig,
+                    (size_t) sigSize);
+            reply->writeNoException();
+            reply->writeInt32(ret ? 1 : 0);
+            return NO_ERROR;
+        } break;
+        case GET_PUBKEY: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            void* out = NULL;
+            size_t outSize = 0;
+            int32_t ret = get_pubkey(name, (unsigned char**) &out, &outSize);
+            reply->writeNoException();
+            reply->writeInt32(outSize);
+            void* buf = reply->writeInplace(outSize);
+            memcpy(buf, out, outSize);
+            free(out);
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        }
+        case DEL_KEY: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t ret = del_key(name);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case GRANT: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t granteeUid = data.readInt32();
+            int32_t ret = grant(name, granteeUid);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case UNGRANT: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int32_t granteeUid = data.readInt32();
+            int32_t ret = ungrant(name, granteeUid);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        } break;
+        case GETMTIME: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 name = data.readString16();
+            int64_t ret = getmtime(name);
+            reply->writeNoException();
+            reply->writeInt64(ret);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
new file mode 100644
index 0000000..15712ce
--- /dev/null
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2012 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_IKEYSTORESERVICE_H
+#define KEYSTORE_IKEYSTORESERVICE_H
+
+#include <utils/RefBase.h>
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+/*
+ * This must be kept manually in sync with frameworks/base's IKeystoreService.java
+ */
+class IKeystoreService: public IInterface {
+public:
+    enum {
+        TEST = IBinder::FIRST_CALL_TRANSACTION + 0,
+        GET = IBinder::FIRST_CALL_TRANSACTION + 1,
+        INSERT = IBinder::FIRST_CALL_TRANSACTION + 2,
+        DEL = IBinder::FIRST_CALL_TRANSACTION + 3,
+        EXIST = IBinder::FIRST_CALL_TRANSACTION + 4,
+        SAW = IBinder::FIRST_CALL_TRANSACTION + 5,
+        RESET = IBinder::FIRST_CALL_TRANSACTION + 6,
+        PASSWORD = IBinder::FIRST_CALL_TRANSACTION + 7,
+        LOCK = IBinder::FIRST_CALL_TRANSACTION + 8,
+        UNLOCK = IBinder::FIRST_CALL_TRANSACTION + 9,
+        ZERO = IBinder::FIRST_CALL_TRANSACTION + 10,
+        GENERATE = IBinder::FIRST_CALL_TRANSACTION + 11,
+        IMPORT = IBinder::FIRST_CALL_TRANSACTION + 12,
+        SIGN = IBinder::FIRST_CALL_TRANSACTION + 13,
+        VERIFY = IBinder::FIRST_CALL_TRANSACTION + 14,
+        GET_PUBKEY = IBinder::FIRST_CALL_TRANSACTION + 15,
+        DEL_KEY = IBinder::FIRST_CALL_TRANSACTION + 16,
+        GRANT = IBinder::FIRST_CALL_TRANSACTION + 17,
+        UNGRANT = IBinder::FIRST_CALL_TRANSACTION + 18,
+        GETMTIME = IBinder::FIRST_CALL_TRANSACTION + 19,
+    };
+
+    DECLARE_META_INTERFACE(KeystoreService);
+
+    virtual int32_t test() = 0;
+
+    virtual int32_t get(const String16& name, uint8_t** item, size_t* itemLength) = 0;
+
+    virtual int32_t insert(const String16& name, const uint8_t* item, size_t itemLength) = 0;
+
+    virtual int32_t del(const String16& name) = 0;
+
+    virtual int32_t exist(const String16& name) = 0;
+
+    virtual int32_t saw(const String16& name, Vector<String16>* matches) = 0;
+
+    virtual int32_t reset() = 0;
+
+    virtual int32_t password(const String16& password) = 0;
+
+    virtual int32_t lock() = 0;
+
+    virtual int32_t unlock(const String16& password) = 0;
+
+    virtual int32_t zero() = 0;
+
+    virtual int32_t generate(const String16& name) = 0;
+
+    virtual int32_t import(const String16& name, const uint8_t* data, size_t length) = 0;
+
+    virtual int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
+            size_t* outLength) = 0;
+
+    virtual int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
+            const uint8_t* signature, size_t signatureLength) = 0;
+
+    virtual int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) = 0;
+
+    virtual int32_t del_key(const String16& name) = 0;
+
+    virtual int32_t grant(const String16& name, int32_t granteeUid) = 0;
+
+    virtual int32_t ungrant(const String16& name, int32_t granteeUid) = 0;
+
+    virtual int64_t getmtime(const String16& name) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnKeystoreService: public BnInterface<IKeystoreService> {
+public:
+    virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+            uint32_t flags = 0);
+};
+
+} // namespace android
+
+#endif
diff --git a/keystore/keystore.h b/keystore/include/keystore/keystore.h
similarity index 67%
rename from keystore/keystore.h
rename to keystore/include/keystore/keystore.h
index f5e4439..c8f2755 100644
--- a/keystore/keystore.h
+++ b/keystore/include/keystore/keystore.h
@@ -43,56 +43,6 @@
     SIGNATURE_INVALID = 14,
 };
 
-enum CommandNames {
-    TEST = 0,
-    GET = 1,
-    INSERT = 2,
-    DELETE = 3,
-    EXIST = 4,
-    SAW = 5,
-    RESET = 6,
-    PASSWORD = 7,
-    LOCK = 8,
-    UNLOCK = 9,
-    ZERO = 10,
-    GENERATE = 11,
-    IMPORT = 12,
-    SIGN = 13,
-    VERIFY = 14,
-    GET_PUBKEY = 15,
-    DEL_KEY = 16,
-    GRANT = 17,
-    UNGRANT = 18,
-    GETMTIME = 19,
-};
-
-typedef uint8_t command_code_t;
-
-// Taken: a b c d e f g h i j k l m n o p q r s t u v w x y z
-//        * * * * *   *   *   * * * *   *   * * * * *   *   *
-command_code_t CommandCodes[] = {
-    't', // TEST
-    'g', // GET
-    'i', // INSERT
-    'd', // DELETE
-    'e', // EXIST
-    's', // SAW
-    'r', // RESET
-    'p', // PASSWORD
-    'l', // LOCK
-    'u', // UNLOCK
-    'z', // ZERO
-    'a', // GENERATE
-    'm', // IMPORT
-    'n', // SIGN
-    'v', // VERIFY
-    'b', // GET_PUBKEY
-    'k', // DEL_KEY
-    'x', // GRANT
-    'y', // UNGRANT
-    'c', // GETMTIME
-};
-
 /**
  * Returns the size of the softkey magic header value for measuring
  * and allocating purposes.
diff --git a/keystore/include/keystore/keystore_get.h b/keystore/include/keystore/keystore_get.h
new file mode 100644
index 0000000..4bddd70
--- /dev/null
+++ b/keystore/include/keystore/keystore_get.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2009 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_GET_H__
+#define __KEYSTORE_GET_H__
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This function is provided for native components to get values from keystore.
+ * Users are required to link against libkeystore_binder.
+ *
+ * Keys and values are 8-bit safe. The first two arguments are the key and its
+ * length. The third argument is a pointer to an array that will be malloc()
+ * and the caller is responsible for calling free() on the buffer.
+ */
+ssize_t keystore_get(const char *key, size_t length, uint8_t** value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index ea58ad6..23711e7 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+//#define LOG_NDEBUG 0
+#define LOG_TAG "keystore"
+
 #include <stdio.h>
 #include <stdint.h>
 #include <string.h>
@@ -42,13 +45,15 @@
 
 #include <cutils/list.h>
 
-//#define LOG_NDEBUG 0
-#define LOG_TAG "keystore"
+#include <keystore/IKeystoreService.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
 #include <cutils/log.h>
 #include <cutils/sockets.h>
 #include <private/android_filesystem_config.h>
 
-#include "keystore.h"
+#include <keystore/keystore.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
@@ -154,6 +159,72 @@
     keymaster_close(dev);
 }
 
+/***************
+ * PERMISSIONS *
+ ***************/
+
+/* Here are the permissions, actions, users, and the main function. */
+typedef enum {
+    P_TEST     = 1 << 0,
+    P_GET      = 1 << 1,
+    P_INSERT   = 1 << 2,
+    P_DELETE   = 1 << 3,
+    P_EXIST    = 1 << 4,
+    P_SAW      = 1 << 5,
+    P_RESET    = 1 << 6,
+    P_PASSWORD = 1 << 7,
+    P_LOCK     = 1 << 8,
+    P_UNLOCK   = 1 << 9,
+    P_ZERO     = 1 << 10,
+    P_SIGN     = 1 << 11,
+    P_VERIFY   = 1 << 12,
+    P_GRANT    = 1 << 13,
+} perm_t;
+
+static struct user_euid {
+    uid_t uid;
+    uid_t euid;
+} user_euids[] = {
+    {AID_VPN, AID_SYSTEM},
+    {AID_WIFI, AID_SYSTEM},
+    {AID_ROOT, AID_SYSTEM},
+};
+
+static struct user_perm {
+    uid_t uid;
+    perm_t perms;
+} user_perms[] = {
+    {AID_SYSTEM, static_cast<perm_t>((uint32_t)(~0)) },
+    {AID_VPN,    static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) },
+    {AID_WIFI,   static_cast<perm_t>(P_GET | P_SIGN | P_VERIFY) },
+    {AID_ROOT,   static_cast<perm_t>(P_GET) },
+};
+
+static const perm_t DEFAULT_PERMS = static_cast<perm_t>(P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW | P_SIGN
+        | P_VERIFY);
+
+static bool has_permission(uid_t uid, perm_t perm) {
+    for (size_t i = 0; i < sizeof(user_perms)/sizeof(user_perms[0]); i++) {
+        struct user_perm user = user_perms[i];
+        if (user.uid == uid) {
+            return user.perms & perm;
+        }
+    }
+
+    return DEFAULT_PERMS & perm;
+}
+
+static uid_t get_keystore_euid(uid_t uid) {
+    for (size_t i = 0; i < sizeof(user_euids)/sizeof(user_euids[0]); i++) {
+        struct user_euid user = user_euids[i];
+        if (user.uid == uid) {
+            return user.euid;
+        }
+    }
+
+    return uid;
+}
+
 /* 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
@@ -161,9 +232,9 @@
  * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
  * that Base64 cannot be used here due to the need of prefix match on keys. */
 
-static int encode_key(char* out, const Value* key) {
-    const uint8_t* in = key->value;
-    int length = key->length;
+static int encode_key(char* out, const android::String8& keyName) {
+    const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
+    size_t length = keyName.length();
     for (int i = length; i > 0; --i, ++in, ++out) {
         if (*in >= '0' && *in <= '~') {
             *out = *in;
@@ -177,25 +248,48 @@
     return length;
 }
 
-static int encode_key_for_uid(char* out, uid_t uid, const Value* key) {
+static int encode_key_for_uid(char* out, uid_t uid, const android::String8& keyName) {
     int n = snprintf(out, NAME_MAX, "%u_", uid);
     out += n;
 
-    return n + encode_key(out, key);
+    return n + encode_key(out, keyName);
 }
 
-static int decode_key(uint8_t* out, const char* in, int length) {
-    for (int i = 0; i < length; ++i, ++in, ++out) {
-        if (*in >= '0' && *in <= '~') {
-            *out = *in;
+/*
+ * Converts from the "escaped" format on disk to actual name.
+ * This will be smaller than the input string.
+ *
+ * Characters that should combine with the next at the end will be truncated.
+ */
+static size_t decode_key_length(const char* in, size_t length) {
+    size_t outLength = 0;
+
+    for (const char* end = in + length; in < end; in++) {
+        /* This combines with the next character. */
+        if (*in < '0' || *in > '~') {
+            continue;
+        }
+
+        outLength++;
+    }
+    return outLength;
+}
+
+static void decode_key(char* out, const char* in, size_t length) {
+    for (const char* end = in + length; in < end; in++) {
+        if (*in < '0' || *in > '~') {
+            /* Truncate combining characters at the end. */
+            if (in + 1 >= end) {
+                break;
+            }
+
+            *out = (*in++ - '+') << 6;
+            *out++ |= (*in - '0') & 0x3F;
         } else {
-            *out = (*in - '+') << 6;
-            *out |= (*++in - '0') & 0x3F;
-            --length;
+            *out++ = *in;
         }
     }
     *out = '\0';
-    return length;
 }
 
 static size_t readFully(int fd, uint8_t* data, size_t size) {
@@ -293,18 +387,19 @@
     TYPE_KEY_PAIR = 3,
 } BlobType;
 
-static const uint8_t CurrentBlobVersion = 1;
+static const uint8_t CURRENT_BLOB_VERSION = 1;
 
 class Blob {
 public:
-    Blob(uint8_t* value, int32_t valueLength, uint8_t* info, uint8_t infoLength, BlobType type) {
+    Blob(const uint8_t* value, int32_t valueLength, const uint8_t* info, uint8_t infoLength,
+            BlobType type) {
         mBlob.length = valueLength;
         memcpy(mBlob.value, value, valueLength);
 
         mBlob.info = infoLength;
         memcpy(mBlob.value + valueLength, info, infoLength);
 
-        mBlob.version = CurrentBlobVersion;
+        mBlob.version = CURRENT_BLOB_VERSION;
         mBlob.type = uint8_t(type);
     }
 
@@ -388,7 +483,7 @@
             unlink(tmpFileName);
             return SYSTEM_ERROR;
         }
-        return (rename(tmpFileName, filename) == 0) ? NO_ERROR : SYSTEM_ERROR;
+        return (rename(tmpFileName, filename) == 0) ? ::NO_ERROR : ::SYSTEM_ERROR;
     }
 
     ResponseCode decryptBlob(const char* filename, AES_KEY *aes_key) {
@@ -430,7 +525,7 @@
             // move info from after padding to after data
             memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
         }
-        return NO_ERROR;
+        return ::NO_ERROR;
     }
 
 private:
@@ -472,7 +567,7 @@
         return mDevice;
     }
 
-    ResponseCode initialize(Value* pw) {
+    ResponseCode initialize(const android::String8& pw) {
         if (!generateMasterKey()) {
             return SYSTEM_ERROR;
         }
@@ -481,10 +576,10 @@
             return response;
         }
         setupMasterKeys();
-        return NO_ERROR;
+        return ::NO_ERROR;
     }
 
-    ResponseCode writeMasterKey(Value* pw) {
+    ResponseCode writeMasterKey(const android::String8& pw) {
         uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
         generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
         AES_KEY passwordAesKey;
@@ -493,7 +588,7 @@
         return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy);
     }
 
-    ResponseCode readMasterKey(Value* pw) {
+    ResponseCode readMasterKey(const android::String8& pw) {
         int in = open(MASTER_KEY_FILE, O_RDONLY);
         if (in == -1) {
             return SYSTEM_ERROR;
@@ -596,7 +691,7 @@
         }
 
         const uint8_t version = keyBlob->getVersion();
-        if (version < CurrentBlobVersion) {
+        if (version < CURRENT_BLOB_VERSION) {
             upgrade(filename, keyBlob, version, type);
         }
 
@@ -612,28 +707,18 @@
         return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy);
     }
 
-    void addGrant(const char* filename, const Value* uidValue) {
-        uid_t uid;
-        if (!convertToUid(uidValue, &uid)) {
-            return;
-        }
-
-        grant_t *grant = getGrant(filename, uid);
+    void addGrant(const char* filename, uid_t granteeUid) {
+        grant_t *grant = getGrant(filename, granteeUid);
         if (grant == NULL) {
             grant = new grant_t;
-            grant->uid = uid;
+            grant->uid = granteeUid;
             grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename));
             list_add_tail(&mGrants, &grant->plist);
         }
     }
 
-    bool removeGrant(const char* filename, const Value* uidValue) {
-        uid_t uid;
-        if (!convertToUid(uidValue, &uid)) {
-            return false;
-        }
-
-        grant_t *grant = getGrant(filename, uid);
+    bool removeGrant(const char* filename, uid_t granteeUid) {
+        grant_t *grant = getGrant(filename, granteeUid);
         if (grant != NULL) {
             list_remove(&grant->plist);
             delete grant;
@@ -647,7 +732,7 @@
         return getGrant(filename, uid) != NULL;
     }
 
-    ResponseCode importKey(const Value* key, const char* filename) {
+    ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename) {
         uint8_t* data;
         size_t dataLength;
         int rc;
@@ -657,7 +742,7 @@
             return SYSTEM_ERROR;
         }
 
-        rc = mDevice->import_keypair(mDevice, key->value, key->length, &data, &dataLength);
+        rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength);
         if (rc) {
             ALOGE("Error while importing keypair: %d", rc);
             return SYSTEM_ERROR;
@@ -726,7 +811,8 @@
         memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
     }
 
-    static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, Value* pw, uint8_t* salt) {
+    static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw,
+            uint8_t* salt) {
         size_t saltSize;
         if (salt != NULL) {
             saltSize = SALT_SIZE;
@@ -736,7 +822,9 @@
             // sizeof = 9, not strlen = 8
             saltSize = sizeof("keystore");
         }
-        PKCS5_PBKDF2_HMAC_SHA1((char*) pw->value, pw->length, salt, saltSize, 8192, keySize, key);
+
+        PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt,
+                saltSize, 8192, keySize, key);
     }
 
     static bool isKeyFile(const char* filename) {
@@ -834,7 +922,7 @@
             return SYSTEM_ERROR;
         }
 
-        ResponseCode rc = importKey(&pkcs8key, filename);
+        ResponseCode rc = importKey(pkcs8key.value, pkcs8key.length, filename);
         if (rc != NO_ERROR) {
             return rc;
         }
@@ -845,55 +933,8 @@
 
 const char* KeyStore::MASTER_KEY_FILE = ".masterkey";
 
-/* Here is the protocol used in both requests and responses:
- *     code [length_1 message_1 ... length_n message_n] end-of-file
- * where code is one byte long and lengths are unsigned 16-bit integers in
- * network order. Thus the maximum length of a message is 65535 bytes. */
-
-static int recv_code(int sock, int8_t* code) {
-    return recv(sock, code, 1, 0) == 1;
-}
-
-static int recv_message(int sock, uint8_t* message, int length) {
-    uint8_t bytes[2];
-    if (recv(sock, &bytes[0], 1, 0) != 1 ||
-        recv(sock, &bytes[1], 1, 0) != 1) {
-        return -1;
-    } else {
-        int offset = bytes[0] << 8 | bytes[1];
-        if (length < offset) {
-            return -1;
-        }
-        length = offset;
-        offset = 0;
-        while (offset < length) {
-            int n = recv(sock, &message[offset], length - offset, 0);
-            if (n <= 0) {
-                return -1;
-            }
-            offset += n;
-        }
-    }
-    return length;
-}
-
-static int recv_end_of_file(int sock) {
-    uint8_t byte;
-    return recv(sock, &byte, 1, 0) == 0;
-}
-
-static void send_code(int sock, int8_t code) {
-    send(sock, &code, 1, 0);
-}
-
-static void send_message(int sock, const uint8_t* message, int length) {
-    uint16_t bytes = htons(length);
-    send(sock, &bytes, 2, 0);
-    send(sock, message, length, 0);
-}
-
-static ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob, const Value* keyName,
-        const uid_t uid, const BlobType type) {
+static ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob,
+        const android::String8& keyName, const uid_t uid, const BlobType type) {
     char filename[NAME_MAX];
 
     encode_key_for_uid(filename, uid, keyName);
@@ -922,494 +963,627 @@
     return keyStore->get(filename, keyBlob, type);
 }
 
-/* Here are the actions. Each of them is a function without arguments. All
- * information is defined in global variables, which are set properly before
- * performing an action. The number of parameters required by each action is
- * fixed and defined in a table. If the return value of an action is positive,
- * it will be treated as a response code and transmitted to the client. Note
- * that the lengths of parameters are checked when they are received, so
- * boundary checks on parameters are omitted. */
-
-static const ResponseCode NO_ERROR_RESPONSE_CODE_SENT = (ResponseCode) 0;
-
-static ResponseCode test(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
-    return (ResponseCode) keyStore->getState();
-}
-
-static ResponseCode get(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
-    char filename[NAME_MAX];
-    encode_key_for_uid(filename, uid, keyName);
-    Blob keyBlob;
-    ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_GENERIC);
-    if (responseCode != NO_ERROR) {
-        return responseCode;
+namespace android {
+class KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient {
+public:
+    KeyStoreProxy(KeyStore* keyStore)
+        : mKeyStore(keyStore)
+    {
     }
-    send_code(sock, NO_ERROR);
-    send_message(sock, keyBlob.getValue(), keyBlob.getLength());
-    return NO_ERROR_RESPONSE_CODE_SENT;
-}
 
-static ResponseCode insert(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* val,
-        Value*) {
-    char filename[NAME_MAX];
-    encode_key_for_uid(filename, uid, keyName);
-    Blob keyBlob(val->value, val->length, NULL, 0, TYPE_GENERIC);
-    return keyStore->put(filename, &keyBlob);
-}
-
-static ResponseCode del(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*, Value*) {
-    char filename[NAME_MAX];
-    encode_key_for_uid(filename, uid, keyName);
-    Blob keyBlob;
-    ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_GENERIC);
-    if (responseCode != NO_ERROR) {
-        return responseCode;
+    void binderDied(const wp<IBinder>&) {
+        ALOGE("binder death detected");
     }
-    return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR;
-}
 
-static ResponseCode exist(KeyStore*, int, uid_t uid, Value* keyName, Value*, Value*) {
-    char filename[NAME_MAX];
-    encode_key_for_uid(filename, uid, keyName);
-    if (access(filename, R_OK) == -1) {
-        return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
-    }
-    return NO_ERROR;
-}
-
-static ResponseCode saw(KeyStore*, int sock, uid_t uid, Value* keyPrefix, Value*, Value*) {
-    DIR* dir = opendir(".");
-    if (!dir) {
-        return SYSTEM_ERROR;
-    }
-    char filename[NAME_MAX];
-    int n = encode_key_for_uid(filename, uid, keyPrefix);
-    send_code(sock, NO_ERROR);
-
-    struct dirent* file;
-    while ((file = readdir(dir)) != NULL) {
-        if (!strncmp(filename, file->d_name, n)) {
-            const char* p = &file->d_name[n];
-            keyPrefix->length = decode_key(keyPrefix->value, p, strlen(p));
-            send_message(sock, keyPrefix->value, keyPrefix->length);
+    int32_t test() {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_TEST)) {
+            ALOGW("permission denied for %d: test", uid);
+            return ::PERMISSION_DENIED;
         }
-    }
-    closedir(dir);
-    return NO_ERROR_RESPONSE_CODE_SENT;
-}
 
-static ResponseCode reset(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
-    ResponseCode rc = keyStore->reset() ? NO_ERROR : SYSTEM_ERROR;
-
-    const keymaster_device_t* device = keyStore->getDevice();
-    if (device == NULL) {
-        ALOGE("No keymaster device!");
-        return SYSTEM_ERROR;
+        return mKeyStore->getState();
     }
 
-    if (device->delete_all == NULL) {
-        ALOGV("keymaster device doesn't implement delete_all");
-        return rc;
-    }
-
-    if (device->delete_all(device)) {
-        ALOGE("Problem calling keymaster's delete_all");
-        return SYSTEM_ERROR;
-    }
-
-    return rc;
-}
-
-/* Here is the history. To improve the security, the parameters to generate the
- * master key has been changed. To make a seamless transition, we update the
- * file using the same password when the user unlock it for the first time. If
- * any thing goes wrong during the transition, the new file will not overwrite
- * the old one. This avoids permanent damages of the existing data. */
-
-static ResponseCode password(KeyStore* keyStore, int, uid_t, Value* pw, Value*, Value*) {
-    switch (keyStore->getState()) {
-        case STATE_UNINITIALIZED: {
-            // generate master key, encrypt with password, write to file, initialize mMasterKey*.
-            return keyStore->initialize(pw);
+    int32_t get(const String16& name, uint8_t** item, size_t* itemLength) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_GET)) {
+            ALOGW("permission denied for %d: get", uid);
+            return ::PERMISSION_DENIED;
         }
-        case STATE_NO_ERROR: {
-            // rewrite master key with new password.
-            return keyStore->writeMasterKey(pw);
+        uid = get_keystore_euid(uid);
+
+        State state = checkState();
+        if (state != STATE_NO_ERROR) {
+            ALOGD("calling get in state: %d", state);
+            return state;
         }
-        case STATE_LOCKED: {
-            // read master key, decrypt with password, initialize mMasterKey*.
-            return keyStore->readMasterKey(pw);
+
+        String8 name8(name);
+        char filename[NAME_MAX];
+
+        encode_key_for_uid(filename, uid, name8);
+
+        Blob keyBlob;
+        ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC);
+        if (responseCode != ::NO_ERROR) {
+            *item = NULL;
+            *itemLength = 0;
+            return responseCode;
         }
-    }
-    return SYSTEM_ERROR;
-}
 
-static ResponseCode lock(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
-    keyStore->lock();
-    return NO_ERROR;
-}
+        *item = (uint8_t*) malloc(keyBlob.getLength());
+        memcpy(*item, keyBlob.getValue(), keyBlob.getLength());
+        *itemLength = keyBlob.getLength();
 
-static ResponseCode unlock(KeyStore* keyStore, int sock, uid_t uid, Value* pw, Value* unused,
-        Value* unused2) {
-    return password(keyStore, sock, uid, pw, unused, unused2);
-}
-
-static ResponseCode zero(KeyStore* keyStore, int, uid_t, Value*, Value*, Value*) {
-    return keyStore->isEmpty() ? KEY_NOT_FOUND : NO_ERROR;
-}
-
-static ResponseCode generate(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*,
-        Value*) {
-    char filename[NAME_MAX];
-    uint8_t* data;
-    size_t dataLength;
-    int rc;
-
-    const keymaster_device_t* device = keyStore->getDevice();
-    if (device == NULL) {
-        return SYSTEM_ERROR;
+        return ::NO_ERROR;
     }
 
-    if (device->generate_keypair == NULL) {
-        return SYSTEM_ERROR;
+    int32_t insert(const String16& name, const uint8_t* item, size_t itemLength) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_INSERT)) {
+            ALOGW("permission denied for %d: insert", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
+
+        State state = checkState();
+        if (state != STATE_NO_ERROR) {
+            ALOGD("calling insert in state: %d", state);
+            return state;
+        }
+
+        String8 name8(name);
+        char filename[NAME_MAX];
+
+        encode_key_for_uid(filename, uid, name8);
+
+        Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC);
+        return mKeyStore->put(filename, &keyBlob);
     }
 
-    keymaster_rsa_keygen_params_t rsa_params;
-    rsa_params.modulus_size = 2048;
-    rsa_params.public_exponent = 0x10001;
+    int32_t del(const String16& name) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_DELETE)) {
+            ALOGW("permission denied for %d: del", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
 
-    rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength);
-    if (rc) {
-        return SYSTEM_ERROR;
+        String8 name8(name);
+        char filename[NAME_MAX];
+
+        encode_key_for_uid(filename, uid, name8);
+
+        Blob keyBlob;
+        ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC);
+        if (responseCode != ::NO_ERROR) {
+            return responseCode;
+        }
+        return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
     }
 
-    encode_key_for_uid(filename, uid, keyName);
+    int32_t exist(const String16& name) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_EXIST)) {
+            ALOGW("permission denied for %d: exist", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
 
-    Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
-    free(data);
+        String8 name8(name);
+        char filename[NAME_MAX];
 
-    return keyStore->put(filename, &keyBlob);
-}
+        encode_key_for_uid(filename, uid, name8);
 
-static ResponseCode import(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* key,
-        Value*) {
-    char filename[NAME_MAX];
-
-    encode_key_for_uid(filename, uid, keyName);
-
-    return keyStore->importKey(key, filename);
-}
-
-/*
- * TODO: The abstraction between things stored in hardware and regular blobs
- * of data stored on the filesystem should be moved down to keystore itself.
- * Unfortunately the Java code that calls this has naming conventions that it
- * knows about. Ideally keystore shouldn't be used to store random blobs of
- * data.
- *
- * Until that happens, it's necessary to have a separate "get_pubkey" and
- * "del_key" since the Java code doesn't really communicate what it's
- * intentions are.
- */
-static ResponseCode get_pubkey(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value*, Value*) {
-    Blob keyBlob;
-    ALOGV("get_pubkey '%s' from uid %d", ValueString(keyName).c_str(), uid);
-
-    ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR);
-    if (responseCode != NO_ERROR) {
-        return responseCode;
+        if (access(filename, R_OK) == -1) {
+            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
+        }
+        return ::NO_ERROR;
     }
 
-    const keymaster_device_t* device = keyStore->getDevice();
-    if (device == NULL) {
-        return SYSTEM_ERROR;
-    }
+    int32_t saw(const String16& prefix, Vector<String16>* matches) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_SAW)) {
+            ALOGW("permission denied for %d: saw", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
 
-    if (device->get_keypair_public == NULL) {
-        ALOGE("device has no get_keypair_public implementation!");
-        return SYSTEM_ERROR;
-    }
+        DIR* dir = opendir(".");
+        if (!dir) {
+            return ::SYSTEM_ERROR;
+        }
 
-    uint8_t* data = NULL;
-    size_t dataLength;
+        const String8 prefix8(prefix);
+        char filename[NAME_MAX];
 
-    int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), &data,
-            &dataLength);
-    if (rc) {
-        return SYSTEM_ERROR;
-    }
+        int n = encode_key_for_uid(filename, uid, prefix8);
 
-    send_code(sock, NO_ERROR);
-    send_message(sock, data, dataLength);
-    free(data);
+        struct dirent* file;
+        while ((file = readdir(dir)) != NULL) {
+            if (!strncmp(filename, file->d_name, n)) {
+                const char* p = &file->d_name[n];
+                size_t plen = strlen(p);
 
-    return NO_ERROR_RESPONSE_CODE_SENT;
-}
-
-static ResponseCode del_key(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value*,
-        Value*) {
-    char filename[NAME_MAX];
-    encode_key_for_uid(filename, uid, keyName);
-    Blob keyBlob;
-    ResponseCode responseCode = keyStore->get(filename, &keyBlob, TYPE_KEY_PAIR);
-    if (responseCode != NO_ERROR) {
-        return responseCode;
-    }
-
-    ResponseCode rc = NO_ERROR;
-
-    const keymaster_device_t* device = keyStore->getDevice();
-    if (device == NULL) {
-        rc = SYSTEM_ERROR;
-    } else {
-        // A device doesn't have to implement delete_keypair.
-        if (device->delete_keypair != NULL) {
-            if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) {
-                rc = SYSTEM_ERROR;
+                size_t extra = decode_key_length(p, plen);
+                char *match = (char*) malloc(extra + 1);
+                if (match != NULL) {
+                    decode_key(match, p, plen);
+                    matches->push(String16(match, extra));
+                    free(match);
+                } else {
+                    ALOGW("could not allocate match of size %zd", extra);
+                }
             }
         }
+        closedir(dir);
+
+        return ::NO_ERROR;
     }
 
-    if (rc != NO_ERROR) {
+    int32_t reset() {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_RESET)) {
+            ALOGW("permission denied for %d: reset", uid);
+            return ::PERMISSION_DENIED;
+        }
+
+        ResponseCode rc = mKeyStore->reset() ? ::NO_ERROR : ::SYSTEM_ERROR;
+
+        const keymaster_device_t* device = mKeyStore->getDevice();
+        if (device == NULL) {
+            ALOGE("No keymaster device!");
+            return ::SYSTEM_ERROR;
+        }
+
+        if (device->delete_all == NULL) {
+            ALOGV("keymaster device doesn't implement delete_all");
+            return rc;
+        }
+
+        if (device->delete_all(device)) {
+            ALOGE("Problem calling keymaster's delete_all");
+            return ::SYSTEM_ERROR;
+        }
+
         return rc;
     }
 
-    return (unlink(filename) && errno != ENOENT) ? SYSTEM_ERROR : NO_ERROR;
-}
+    /*
+     * Here is the history. To improve the security, the parameters to generate the
+     * master key has been changed. To make a seamless transition, we update the
+     * file using the same password when the user unlock it for the first time. If
+     * any thing goes wrong during the transition, the new file will not overwrite
+     * the old one. This avoids permanent damages of the existing data.
+     */
+    int32_t password(const String16& password) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_PASSWORD)) {
+            ALOGW("permission denied for %d: password", uid);
+            return ::PERMISSION_DENIED;
+        }
 
-static ResponseCode sign(KeyStore* keyStore, int sock, uid_t uid, Value* keyName, Value* data,
-        Value*) {
-    ALOGV("sign %s from uid %d", ValueString(keyName).c_str(), uid);
-    Blob keyBlob;
-    int rc;
+        const String8 password8(password);
 
-    ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR);
-    if (responseCode != NO_ERROR) {
-        return responseCode;
+        switch (mKeyStore->getState()) {
+            case ::STATE_UNINITIALIZED: {
+                // generate master key, encrypt with password, write to file, initialize mMasterKey*.
+                return mKeyStore->initialize(password8);
+            }
+            case ::STATE_NO_ERROR: {
+                // rewrite master key with new password.
+                return mKeyStore->writeMasterKey(password8);
+            }
+            case ::STATE_LOCKED: {
+                // read master key, decrypt with password, initialize mMasterKey*.
+                return mKeyStore->readMasterKey(password8);
+            }
+        }
+        return ::SYSTEM_ERROR;
     }
 
-    uint8_t* signedData;
-    size_t signedDataLength;
+    int32_t lock() {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_LOCK)) {
+            ALOGW("permission denied for %d: lock", uid);
+            return ::PERMISSION_DENIED;
+        }
 
-    const keymaster_device_t* device = keyStore->getDevice();
-    if (device == NULL) {
-        ALOGE("no keymaster device; cannot sign");
-        return SYSTEM_ERROR;
+        State state = checkState();
+        if (state != STATE_NO_ERROR) {
+            ALOGD("calling lock in state: %d", state);
+            return state;
+        }
+
+        mKeyStore->lock();
+        return ::NO_ERROR;
     }
 
-    if (device->sign_data == NULL) {
-        ALOGE("device doesn't implement signing");
-        return SYSTEM_ERROR;
+    int32_t unlock(const String16& pw) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_UNLOCK)) {
+            ALOGW("permission denied for %d: unlock", uid);
+            return ::PERMISSION_DENIED;
+        }
+
+        State state = checkState();
+        if (state != STATE_LOCKED) {
+            ALOGD("calling unlock when not locked");
+            return state;
+        }
+
+        const String8 password8(pw);
+        return password(pw);
     }
 
-    keymaster_rsa_sign_params_t params;
-    params.digest_type = DIGEST_NONE;
-    params.padding_type = PADDING_NONE;
+    int32_t zero() {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_ZERO)) {
+            ALOGW("permission denied for %d: zero", uid);
+            return -1;
+        }
 
-    rc = device->sign_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
-            data->value, data->length, &signedData, &signedDataLength);
-    if (rc) {
-        ALOGW("device couldn't sign data");
-        return SYSTEM_ERROR;
+        return mKeyStore->isEmpty() ? ::KEY_NOT_FOUND : ::NO_ERROR;
     }
 
-    send_code(sock, NO_ERROR);
-    send_message(sock, signedData, signedDataLength);
-    return NO_ERROR_RESPONSE_CODE_SENT;
-}
+    int32_t generate(const String16& name) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_INSERT)) {
+            ALOGW("permission denied for %d: generate", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
 
-static ResponseCode verify(KeyStore* keyStore, int, uid_t uid, Value* keyName, Value* data,
-        Value* signature) {
-    Blob keyBlob;
-    int rc;
+        State state = checkState();
+        if (state != STATE_NO_ERROR) {
+            ALOGD("calling generate in state: %d", state);
+            return state;
+        }
 
-    ResponseCode responseCode = get_key_for_name(keyStore, &keyBlob, keyName, uid, TYPE_KEY_PAIR);
-    if (responseCode != NO_ERROR) {
-        return responseCode;
+        String8 name8(name);
+        char filename[NAME_MAX];
+
+        uint8_t* data;
+        size_t dataLength;
+        int rc;
+
+        const keymaster_device_t* device = mKeyStore->getDevice();
+        if (device == NULL) {
+            return ::SYSTEM_ERROR;
+        }
+
+        if (device->generate_keypair == NULL) {
+            return ::SYSTEM_ERROR;
+        }
+
+        keymaster_rsa_keygen_params_t rsa_params;
+        rsa_params.modulus_size = 2048;
+        rsa_params.public_exponent = 0x10001;
+
+        rc = device->generate_keypair(device, TYPE_RSA, &rsa_params, &data, &dataLength);
+        if (rc) {
+            return ::SYSTEM_ERROR;
+        }
+
+        encode_key_for_uid(filename, uid, name8);
+
+        Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
+        free(data);
+
+        return mKeyStore->put(filename, &keyBlob);
     }
 
-    const keymaster_device_t* device = keyStore->getDevice();
-    if (device == NULL) {
-        return SYSTEM_ERROR;
+    int32_t import(const String16& name, const uint8_t* data, size_t length) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_INSERT)) {
+            ALOGW("permission denied for %d: import", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
+
+        State state = checkState();
+        if (state != STATE_NO_ERROR) {
+            ALOGD("calling import in state: %d", state);
+            return state;
+        }
+
+        String8 name8(name);
+        char filename[NAME_MAX];
+
+        encode_key_for_uid(filename, uid, name8);
+
+        return mKeyStore->importKey(data, length, filename);
     }
 
-    if (device->verify_data == NULL) {
-        return SYSTEM_ERROR;
+    int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
+            size_t* outLength) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_SIGN)) {
+            ALOGW("permission denied for %d: saw", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
+
+        State state = checkState();
+        if (state != STATE_NO_ERROR) {
+            ALOGD("calling sign in state: %d", state);
+            return state;
+        }
+
+        Blob keyBlob;
+        String8 name8(name);
+
+        ALOGV("sign %s from uid %d", name8.string(), uid);
+        int rc;
+
+        ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, uid, ::TYPE_KEY_PAIR);
+        if (responseCode != ::NO_ERROR) {
+            return responseCode;
+        }
+
+        const keymaster_device_t* device = mKeyStore->getDevice();
+        if (device == NULL) {
+            ALOGE("no keymaster device; cannot sign");
+            return ::SYSTEM_ERROR;
+        }
+
+        if (device->sign_data == NULL) {
+            ALOGE("device doesn't implement signing");
+            return ::SYSTEM_ERROR;
+        }
+
+        keymaster_rsa_sign_params_t params;
+        params.digest_type = DIGEST_NONE;
+        params.padding_type = PADDING_NONE;
+
+        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;
+        }
+
+        return ::NO_ERROR;
     }
 
-    keymaster_rsa_sign_params_t params;
-    params.digest_type = DIGEST_NONE;
-    params.padding_type = PADDING_NONE;
+    int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
+            const uint8_t* signature, size_t signatureLength) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_VERIFY)) {
+            ALOGW("permission denied for %d: verify", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
 
-    rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
-            data->value, data->length, signature->value, signature->length);
-    if (rc) {
-        return SYSTEM_ERROR;
-    } else {
-        return NO_ERROR;
-    }
-}
+        State state = checkState();
+        if (state != STATE_NO_ERROR) {
+            ALOGD("calling verify in state: %d", state);
+            return state;
+        }
 
-static ResponseCode grant(KeyStore* keyStore, int, uid_t uid, Value* keyName,
-        Value* granteeData, Value*) {
-    char filename[NAME_MAX];
-    encode_key_for_uid(filename, uid, keyName);
-    if (access(filename, R_OK) == -1) {
-        return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
-    }
+        Blob keyBlob;
+        String8 name8(name);
+        int rc;
 
-    keyStore->addGrant(filename, granteeData);
-    return NO_ERROR;
-}
+        ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, uid, TYPE_KEY_PAIR);
+        if (responseCode != ::NO_ERROR) {
+            return responseCode;
+        }
 
-static ResponseCode ungrant(KeyStore* keyStore, int, uid_t uid, Value* keyName,
-        Value* granteeData, Value*) {
-    char filename[NAME_MAX];
-    encode_key_for_uid(filename, uid, keyName);
-    if (access(filename, R_OK) == -1) {
-        return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
-    }
+        const keymaster_device_t* device = mKeyStore->getDevice();
+        if (device == NULL) {
+            return ::SYSTEM_ERROR;
+        }
 
-    return keyStore->removeGrant(filename, granteeData) ? NO_ERROR : KEY_NOT_FOUND;
-}
+        if (device->verify_data == NULL) {
+            return ::SYSTEM_ERROR;
+        }
 
-static ResponseCode getmtime(KeyStore*, int sock, uid_t uid, Value* keyName,
-        Value*, Value*) {
-    char filename[NAME_MAX];
-    encode_key_for_uid(filename, uid, keyName);
-    if (access(filename, R_OK) == -1) {
-        return (errno != ENOENT) ? SYSTEM_ERROR : KEY_NOT_FOUND;
-    }
+        keymaster_rsa_sign_params_t params;
+        params.digest_type = DIGEST_NONE;
+        params.padding_type = PADDING_NONE;
 
-    int fd = open(filename, O_NOFOLLOW, O_RDONLY);
-    if (fd < 0) {
-        return SYSTEM_ERROR;
-    }
-
-    struct stat s;
-    int ret = fstat(fd, &s);
-    close(fd);
-    if (ret == -1) {
-        return SYSTEM_ERROR;
-    }
-
-    uint8_t *data;
-    int dataLength = asprintf(reinterpret_cast<char**>(&data), "%lu", s.st_mtime);
-    if (dataLength < 0) {
-        return SYSTEM_ERROR;
-    }
-
-    send_code(sock, NO_ERROR);
-    send_message(sock, data, dataLength);
-    free(data);
-
-    return NO_ERROR_RESPONSE_CODE_SENT;
-}
-
-/* Here are the permissions, actions, users, and the main function. */
-enum perm {
-    P_TEST     = 1 << TEST,
-    P_GET      = 1 << GET,
-    P_INSERT   = 1 << INSERT,
-    P_DELETE   = 1 << DELETE,
-    P_EXIST    = 1 << EXIST,
-    P_SAW      = 1 << SAW,
-    P_RESET    = 1 << RESET,
-    P_PASSWORD = 1 << PASSWORD,
-    P_LOCK     = 1 << LOCK,
-    P_UNLOCK   = 1 << UNLOCK,
-    P_ZERO     = 1 << ZERO,
-    P_SIGN     = 1 << SIGN,
-    P_VERIFY   = 1 << VERIFY,
-    P_GRANT    = 1 << GRANT,
-};
-
-static const int MAX_PARAM = 3;
-
-static const State STATE_ANY = (State) 0;
-
-static struct action {
-    ResponseCode (*run)(KeyStore* keyStore, int sock, uid_t uid, Value* param1, Value* param2,
-            Value* param3);
-    uint8_t code;
-    State state;
-    uint32_t perm;
-    int lengths[MAX_PARAM];
-} actions[] = {
-    {test,       CommandCodes[TEST],       STATE_ANY,      P_TEST,     {0, 0, 0}},
-    {get,        CommandCodes[GET],        STATE_NO_ERROR, P_GET,      {KEY_SIZE, 0, 0}},
-    {insert,     CommandCodes[INSERT],     STATE_NO_ERROR, P_INSERT,   {KEY_SIZE, VALUE_SIZE, 0}},
-    {del,        CommandCodes[DELETE],     STATE_ANY,      P_DELETE,   {KEY_SIZE, 0, 0}},
-    {exist,      CommandCodes[EXIST],      STATE_ANY,      P_EXIST,    {KEY_SIZE, 0, 0}},
-    {saw,        CommandCodes[SAW],        STATE_ANY,      P_SAW,      {KEY_SIZE, 0, 0}},
-    {reset,      CommandCodes[RESET],      STATE_ANY,      P_RESET,    {0, 0, 0}},
-    {password,   CommandCodes[PASSWORD],   STATE_ANY,      P_PASSWORD, {PASSWORD_SIZE, 0, 0}},
-    {lock,       CommandCodes[LOCK],       STATE_NO_ERROR, P_LOCK,     {0, 0, 0}},
-    {unlock,     CommandCodes[UNLOCK],     STATE_LOCKED,   P_UNLOCK,   {PASSWORD_SIZE, 0, 0}},
-    {zero,       CommandCodes[ZERO],       STATE_ANY,      P_ZERO,     {0, 0, 0}},
-    {generate,   CommandCodes[GENERATE],   STATE_NO_ERROR, P_INSERT,   {KEY_SIZE, 0, 0}},
-    {import,     CommandCodes[IMPORT],     STATE_NO_ERROR, P_INSERT,   {KEY_SIZE, VALUE_SIZE, 0}},
-    {sign,       CommandCodes[SIGN],       STATE_NO_ERROR, P_SIGN,     {KEY_SIZE, VALUE_SIZE, 0}},
-    {verify,     CommandCodes[VERIFY],     STATE_NO_ERROR, P_VERIFY,   {KEY_SIZE, VALUE_SIZE, VALUE_SIZE}},
-    {get_pubkey, CommandCodes[GET_PUBKEY], STATE_NO_ERROR, P_GET,      {KEY_SIZE, 0, 0}},
-    {del_key,    CommandCodes[DEL_KEY],    STATE_ANY,      P_DELETE,   {KEY_SIZE, 0, 0}},
-    {grant,      CommandCodes[GRANT],      STATE_NO_ERROR, P_GRANT,    {KEY_SIZE, KEY_SIZE, 0}},
-    {ungrant,    CommandCodes[UNGRANT],    STATE_NO_ERROR, P_GRANT,    {KEY_SIZE, KEY_SIZE, 0}},
-    {getmtime,   CommandCodes[GETMTIME],   STATE_ANY,      P_SAW,      {KEY_SIZE, 0, 0}},
-    {NULL,       0,                        STATE_ANY,      0,          {0, 0, 0}},
-};
-
-static struct user {
-    uid_t uid;
-    uid_t euid;
-    uint32_t perms;
-} users[] = {
-    {AID_SYSTEM,  (uid_t)(~0), (uint32_t)(~0)},
-    {AID_VPN,     AID_SYSTEM,  P_GET | P_SIGN | P_VERIFY },
-    {AID_WIFI,    AID_SYSTEM,  P_GET | P_SIGN | P_VERIFY },
-    {AID_ROOT,    AID_SYSTEM,  P_GET},
-    {(uid_t)(~0), (uid_t)(~0), P_TEST | P_GET | P_INSERT | P_DELETE | P_EXIST | P_SAW |
-                               P_SIGN | P_VERIFY},
-};
-
-static ResponseCode process(KeyStore* keyStore, int sock, uid_t uid, int8_t code) {
-    struct user* user = users;
-    struct action* action = actions;
-    int i;
-
-    while (~user->uid && user->uid != (uid % AID_USER)) {
-        ++user;
-    }
-    while (action->code && action->code != code) {
-        ++action;
-    }
-    if (!action->code) {
-        return UNDEFINED_ACTION;
-    }
-    if (!(action->perm & user->perms)) {
-        return PERMISSION_DENIED;
-    }
-    if (action->state != STATE_ANY && action->state != keyStore->getState()) {
-        return (ResponseCode) keyStore->getState();
-    }
-    if (~user->euid) {
-        uid = user->euid;
-    }
-    Value params[MAX_PARAM];
-    for (i = 0; i < MAX_PARAM && action->lengths[i] != 0; ++i) {
-        params[i].length = recv_message(sock, params[i].value, action->lengths[i]);
-        if (params[i].length < 0) {
-            return PROTOCOL_ERROR;
+        rc = device->verify_data(device, &params, keyBlob.getValue(), keyBlob.getLength(),
+                data, dataLength, signature, signatureLength);
+        if (rc) {
+            return ::SYSTEM_ERROR;
+        } else {
+            return ::NO_ERROR;
         }
     }
-    if (!recv_end_of_file(sock)) {
-        return PROTOCOL_ERROR;
+
+    /*
+     * TODO: The abstraction between things stored in hardware and regular blobs
+     * of data stored on the filesystem should be moved down to keystore itself.
+     * Unfortunately the Java code that calls this has naming conventions that it
+     * knows about. Ideally keystore shouldn't be used to store random blobs of
+     * data.
+     *
+     * Until that happens, it's necessary to have a separate "get_pubkey" and
+     * "del_key" since the Java code doesn't really communicate what it's
+     * intentions are.
+     */
+    int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_GET)) {
+            ALOGW("permission denied for %d: get_pubkey", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
+
+        State state = checkState();
+        if (state != STATE_NO_ERROR) {
+            ALOGD("calling get_pubkey in state: %d", state);
+            return state;
+        }
+
+        Blob keyBlob;
+        String8 name8(name);
+
+        ALOGV("get_pubkey '%s' from uid %d", name8.string(), uid);
+
+        ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, uid,
+                TYPE_KEY_PAIR);
+        if (responseCode != ::NO_ERROR) {
+            return responseCode;
+        }
+
+        const keymaster_device_t* device = mKeyStore->getDevice();
+        if (device == NULL) {
+            return ::SYSTEM_ERROR;
+        }
+
+        if (device->get_keypair_public == NULL) {
+            ALOGE("device has no get_keypair_public implementation!");
+            return ::SYSTEM_ERROR;
+        }
+
+        int rc = device->get_keypair_public(device, keyBlob.getValue(), keyBlob.getLength(), pubkey,
+                pubkeyLength);
+        if (rc) {
+            return ::SYSTEM_ERROR;
+        }
+
+        return ::NO_ERROR;
     }
-    return action->run(keyStore, sock, uid, &params[0], &params[1], &params[2]);
-}
+
+    int32_t del_key(const String16& name) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_DELETE)) {
+            ALOGW("permission denied for %d: del_key", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
+
+        String8 name8(name);
+        char filename[NAME_MAX];
+
+        encode_key_for_uid(filename, uid, name8);
+
+        Blob keyBlob;
+        ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, ::TYPE_KEY_PAIR);
+        if (responseCode != ::NO_ERROR) {
+            return responseCode;
+        }
+
+        ResponseCode rc = ::NO_ERROR;
+
+        const keymaster_device_t* device = mKeyStore->getDevice();
+        if (device == NULL) {
+            rc = ::SYSTEM_ERROR;
+        } else {
+            // A device doesn't have to implement delete_keypair.
+            if (device->delete_keypair != NULL) {
+                if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) {
+                    rc = ::SYSTEM_ERROR;
+                }
+            }
+        }
+
+        if (rc != ::NO_ERROR) {
+            return rc;
+        }
+
+        return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
+    }
+
+    int32_t grant(const String16& name, int32_t granteeUid) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_GRANT)) {
+            ALOGW("permission denied for %d: grant", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
+
+        State state = checkState();
+        if (state != STATE_NO_ERROR) {
+            ALOGD("calling grant in state: %d", state);
+            return state;
+        }
+
+        String8 name8(name);
+        char filename[NAME_MAX];
+
+        encode_key_for_uid(filename, uid, name8);
+
+        if (access(filename, R_OK) == -1) {
+            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
+        }
+
+        mKeyStore->addGrant(filename, granteeUid);
+        return ::NO_ERROR;
+    }
+
+    int32_t ungrant(const String16& name, int32_t granteeUid) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_GRANT)) {
+            ALOGW("permission denied for %d: ungrant", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
+
+        State state = checkState();
+        if (state != STATE_NO_ERROR) {
+            ALOGD("calling ungrant in state: %d", state);
+            return state;
+        }
+
+        String8 name8(name);
+        char filename[NAME_MAX];
+
+        encode_key_for_uid(filename, uid, name8);
+
+        if (access(filename, R_OK) == -1) {
+            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
+        }
+
+        return mKeyStore->removeGrant(filename, granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND;
+    }
+
+    int64_t getmtime(const String16& name) {
+        uid_t uid = IPCThreadState::self()->getCallingUid();
+        if (!has_permission(uid, P_GET)) {
+            ALOGW("permission denied for %d: getmtime", uid);
+            return ::PERMISSION_DENIED;
+        }
+        uid = get_keystore_euid(uid);
+
+        String8 name8(name);
+        char filename[NAME_MAX];
+
+        encode_key_for_uid(filename, uid, name8);
+
+        if (access(filename, R_OK) == -1) {
+            return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
+        }
+
+        int fd = open(filename, O_NOFOLLOW, O_RDONLY);
+        if (fd < 0) {
+            return ::SYSTEM_ERROR;
+        }
+
+        struct stat s;
+        int ret = fstat(fd, &s);
+        close(fd);
+        if (ret == -1) {
+            return ::SYSTEM_ERROR;
+        }
+
+        return s.st_mtime;
+    }
+
+private:
+    inline State checkState() {
+        return mKeyStore->getState();
+    }
+
+    ::KeyStore* mKeyStore;
+};
+
+}; // namespace android
 
 int main(int argc, char* argv[]) {
-    int controlSocket = android_get_control_socket("keystore");
     if (argc < 2) {
         ALOGE("A directory must be specified!");
         return 1;
@@ -1430,48 +1604,21 @@
         return 1;
     }
 
-    if (listen(controlSocket, 3) == -1) {
-        ALOGE("listen: %s", strerror(errno));
-        return 1;
-    }
-
-    signal(SIGPIPE, SIG_IGN);
-
     KeyStore keyStore(&entropy, dev);
-    int sock;
-    while ((sock = accept(controlSocket, NULL, 0)) != -1) {
-        struct timeval tv;
-        tv.tv_sec = 3;
-        setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
-        setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
-
-        struct ucred cred;
-        socklen_t size = sizeof(cred);
-        int credResult = getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cred, &size);
-        if (credResult != 0) {
-            ALOGW("getsockopt: %s", strerror(errno));
-        } else {
-            int8_t request;
-            if (recv_code(sock, &request)) {
-                State old_state = keyStore.getState();
-                ResponseCode response = process(&keyStore, sock, cred.uid, request);
-                if (response == NO_ERROR_RESPONSE_CODE_SENT) {
-                    response = NO_ERROR;
-                } else {
-                    send_code(sock, response);
-                }
-                ALOGI("uid: %d action: %c -> %d state: %d -> %d retry: %d",
-                     cred.uid,
-                     request, response,
-                     old_state, keyStore.getState(),
-                     keyStore.getRetry());
-            }
-        }
-        close(sock);
+    android::sp<android::IServiceManager> sm = android::defaultServiceManager();
+    android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore);
+    android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy);
+    if (ret != android::OK) {
+        ALOGE("Couldn't register binder service!");
+        return -1;
     }
-    ALOGE("accept: %s", strerror(errno));
+
+    /*
+     * We're the only thread in existence, so we're just going to process
+     * Binder transaction as a single-threaded program.
+     */
+    android::IPCThreadState::self()->joinThreadPool();
 
     keymaster_device_release(dev);
-
     return 1;
 }
diff --git a/keystore/keystore_cli.cpp b/keystore/keystore_cli.cpp
index dcd3bcb..01da2c0 100644
--- a/keystore/keystore_cli.cpp
+++ b/keystore/keystore_cli.cpp
@@ -18,11 +18,14 @@
 #include <stdint.h>
 #include <string.h>
 #include <sys/types.h>
-#include <sys/socket.h>
 
-#include <cutils/sockets.h>
+#include <keystore/IKeystoreService.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
 
-#include "keystore.h"
+#include <keystore/keystore.h>
+
+using namespace android;
 
 static const char* responses[] = {
     NULL,
@@ -41,55 +44,158 @@
     /* [WRONG_PASSWORD + 3] = */ "Wrong password (4 tries left)",
 };
 
+#define NO_ARG_INT_RETURN(cmd) \
+    do { \
+        if (strcmp(argv[1], #cmd) == 0) { \
+            int32_t ret = service->cmd(); \
+            if (ret < 0) { \
+                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
+                return 1; \
+            } else { \
+                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
+                return 0; \
+            } \
+        } \
+    } while (0)
+
+#define SINGLE_ARG_INT_RETURN(cmd) \
+    do { \
+        if (strcmp(argv[1], #cmd) == 0) { \
+            if (argc < 3) { \
+                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
+                return 1; \
+            } \
+            int32_t ret = service->cmd(String16(argv[2])); \
+            if (ret < 0) { \
+                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
+                return 1; \
+            } else { \
+                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
+                return 0; \
+            } \
+        } \
+    } while (0)
+
+#define STING_ARG_DATA_STDIN_INT_RETURN(cmd) \
+    do { \
+        if (strcmp(argv[1], #cmd) == 0) { \
+            if (argc < 3) { \
+                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
+                return 1; \
+            } \
+            uint8_t* data; \
+            size_t dataSize; \
+            read_input(&data, &dataSize); \
+            int32_t ret = service->cmd(String16(argv[2]), data, dataSize); \
+            if (ret < 0) { \
+                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
+                return 1; \
+            } else { \
+                printf(#cmd ": %s (%d)\n", responses[ret], ret); \
+                return 0; \
+            } \
+        } \
+    } while (0)
+
+#define SINGLE_ARG_DATA_RETURN(cmd) \
+    do { \
+        if (strcmp(argv[1], #cmd) == 0) { \
+            if (argc < 3) { \
+                fprintf(stderr, "Usage: %s " #cmd " <name>\n", argv[0]); \
+                return 1; \
+            } \
+            uint8_t* data; \
+            size_t dataSize; \
+            int32_t ret = service->cmd(String16(argv[2]), &data, &dataSize); \
+            if (ret < 0) { \
+                fprintf(stderr, "%s: could not connect: %d\n", argv[0], ret); \
+                return 1; \
+            } else if (ret != ::NO_ERROR) { \
+                fprintf(stderr, "%s: " #cmd ": %s (%d)\n", argv[0], responses[ret], ret); \
+                return 1; \
+            } else { \
+                fwrite(data, dataSize, 1, stdout); \
+                fflush(stdout); \
+                free(data); \
+                return 0; \
+            } \
+        } \
+    } while (0)
+
+static int saw(sp<IKeystoreService> service, const String16& name) {
+    Vector<String16> matches;
+    int32_t ret = service->saw(name, &matches);
+    if (ret < 0) {
+        fprintf(stderr, "saw: could not connect: %d\n", ret);
+        return 1;
+    } else if (ret != ::NO_ERROR) {
+        fprintf(stderr, "saw: %s (%d)\n", responses[ret], ret);
+        return 1;
+    } else {
+        Vector<String16>::const_iterator it = matches.begin();
+        for (; it != matches.end(); ++it) {
+            printf("%s\n", String8(*it).string());
+        }
+        return 0;
+    }
+}
+
 int main(int argc, char* argv[])
 {
     if (argc < 2) {
-        printf("Usage: %s action [parameter ...]\n", argv[0]);
-        return 0;
-    }
-
-    int sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
-                                   SOCK_STREAM);
-    if (sock == -1) {
-        puts("Failed to connect");
+        fprintf(stderr, "Usage: %s action [parameter ...]\n", argv[0]);
         return 1;
     }
 
-    send(sock, argv[1], 1, 0);
-    uint8_t bytes[65536];
-    for (int i = 2; i < argc; ++i) {
-        uint16_t length = strlen(argv[i]);
-        bytes[0] = length >> 8;
-        bytes[1] = length;
-        send(sock, &bytes, 2, 0);
-        send(sock, argv[i], length, 0);
-    }
-    shutdown(sock, SHUT_WR);
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
+    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
 
-    uint8_t code;
-    if (recv(sock, &code, 1, 0) != 1) {
-        puts("Failed to receive");
+    if (service == NULL) {
+        fprintf(stderr, "%s: error: could not connect to keystore service\n", argv[0]);
         return 1;
     }
-    printf("%d %s\n", code , responses[code] ? responses[code] : "Unknown");
-    int i;
-    while ((i = recv(sock, &bytes[0], 1, 0)) == 1) {
-        int length;
-        int offset;
-        if ((i = recv(sock, &bytes[1], 1, 0)) != 1) {
-            puts("Failed to receive");
-            return 1;
-        }
-        length = bytes[0] << 8 | bytes[1];
-        for (offset = 0; offset < length; offset += i) {
-            i = recv(sock, &bytes[offset], length - offset, 0);
-            if (i <= 0) {
-                puts("Failed to receive");
-                return 1;
-            }
-        }
-        fwrite(bytes, 1, length, stdout);
-        puts("");
+
+    /*
+     * All the commands should return a value
+     */
+
+    NO_ARG_INT_RETURN(test);
+
+    SINGLE_ARG_DATA_RETURN(get);
+
+    // TODO: insert
+
+    SINGLE_ARG_INT_RETURN(del);
+
+    SINGLE_ARG_INT_RETURN(exist);
+
+    if (strcmp(argv[1], "saw") == 0) {
+        return saw(service, argc < 3 ? String16("") : String16(argv[2]));
     }
-    return 0;
+
+    NO_ARG_INT_RETURN(reset);
+
+    SINGLE_ARG_INT_RETURN(password);
+
+    NO_ARG_INT_RETURN(lock);
+
+    SINGLE_ARG_INT_RETURN(unlock);
+
+    NO_ARG_INT_RETURN(zero);
+
+    SINGLE_ARG_INT_RETURN(generate);
+
+    SINGLE_ARG_DATA_RETURN(get_pubkey);
+
+    SINGLE_ARG_INT_RETURN(del_key);
+
+    // TODO: grant
+
+    // TODO: ungrant
+
+    // TODO: getmtime
+
+    fprintf(stderr, "%s: unknown command: %s\n", argv[0], argv[1]);
+    return 1;
 }
diff --git a/keystore/keystore_client.cpp b/keystore/keystore_client.cpp
deleted file mode 100644
index a3a51ec..0000000
--- a/keystore/keystore_client.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <keystore.h>
-#include <keystore_client.h>
-
-#include <cutils/sockets.h>
-
-#define LOG_TAG "keystore_client"
-#include <cutils/log.h>
-
-ResponseCode keystore_cmd(command_code_t cmd, Keystore_Reply* reply, int numArgs, ...) {
-    int sock;
-
-    sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM);
-    if (sock == -1) {
-        return SYSTEM_ERROR;
-    }
-
-    if (TEMP_FAILURE_RETRY(send(sock, &cmd, 1, MSG_NOSIGNAL)) != 1) {
-        close(sock);
-        return SYSTEM_ERROR;
-    }
-
-    va_list vl;
-    va_start(vl, numArgs);
-    for (int i = 0; i < numArgs; i++) {
-        size_t argLen = va_arg(vl, size_t);
-        uint8_t* arg = va_arg(vl, uint8_t*);
-
-        if (argLen > KEYSTORE_MESSAGE_SIZE) {
-            ALOGE("code called us with an argLen out of bounds: %llu", (unsigned long long) argLen);
-            close(sock);
-            return SYSTEM_ERROR;
-        }
-
-        uint8_t bytes[2] = { (uint8_t)(argLen >> 8), (uint8_t)argLen };
-        if (TEMP_FAILURE_RETRY(send(sock, bytes, 2, MSG_NOSIGNAL)) != 2
-                || TEMP_FAILURE_RETRY(send(sock, arg, argLen, MSG_NOSIGNAL))
-                        != static_cast<ssize_t>(argLen)) {
-            ALOGW("truncated write to keystore");
-            close(sock);
-            return SYSTEM_ERROR;
-        }
-    }
-    va_end(vl);
-
-    uint8_t code = 0;
-    if (shutdown(sock, SHUT_WR) != 0
-            || TEMP_FAILURE_RETRY(recv(sock, &code, 1, 0)) != 1
-            || code != NO_ERROR) {
-        ALOGW("Error from keystore: %d", code);
-        close(sock);
-        return SYSTEM_ERROR;
-    }
-
-    if (reply != NULL) {
-        reply->setCode(static_cast<ResponseCode>(code));
-
-        uint8_t bytes[2];
-        uint8_t* data = reply->get();
-        if (TEMP_FAILURE_RETRY(recv(sock, &bytes[0], 1, 0)) == 1
-                && TEMP_FAILURE_RETRY(recv(sock, &bytes[1], 1, 0)) == 1) {
-            int offset = 0;
-            int length = bytes[0] << 8 | bytes[1];
-            while (offset < length) {
-                int n = TEMP_FAILURE_RETRY(recv(sock, &data[offset], length - offset, 0));
-                if (n <= 0) {
-                    ALOGW("truncated read from keystore for data");
-                    code = SYSTEM_ERROR;
-                    break;
-                }
-                offset += n;
-            }
-            reply->setLength(length);
-        } else {
-            ALOGW("truncated read from keystore for length");
-            code = SYSTEM_ERROR;
-        }
-    }
-
-    close(sock);
-    return static_cast<ResponseCode>(code);
-}
-
-Keystore_Reply::Keystore_Reply()
-        : mCode(SYSTEM_ERROR)
-        , mLength(-1) {
-    mData = new uint8_t[KEYSTORE_MESSAGE_SIZE];
-}
-
-Keystore_Reply::~Keystore_Reply() {
-    delete[] mData;
-}
-
-uint8_t* Keystore_Reply::get() {
-    return mData;
-}
-
-void Keystore_Reply::setLength(size_t length) {
-    mLength = length;
-}
-
-size_t Keystore_Reply::length() const {
-    return mLength;
-}
-
-void Keystore_Reply::setCode(ResponseCode code) {
-    mCode = code;
-}
-
-ResponseCode Keystore_Reply::code() const {
-    return mCode;
-}
-
-uint8_t* Keystore_Reply::release() {
-    uint8_t* data = mData;
-    mData = NULL;
-    return data;
-}
diff --git a/keystore/keystore_client.h b/keystore/keystore_client.h
deleted file mode 100644
index 7ea6bb8..0000000
--- a/keystore/keystore_client.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2012 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_CLIENT_H__
-#define __KEYSTORE_CLIENT_H__
-
-#include <keystore.h>
-
-#define KEYSTORE_MESSAGE_SIZE 65535
-
-
-class Keystore_Reply {
-public:
-    Keystore_Reply();
-    ~Keystore_Reply();
-
-    uint8_t* get();
-    void setLength(size_t length);
-    size_t length() const;
-    void setCode(ResponseCode code);
-    ResponseCode code() const;
-    uint8_t* release();
-
-private:
-    ResponseCode mCode;
-    uint8_t* mData;
-    size_t mLength;
-};
-
-
-/**
- * This sends a command to the keystore. The arguments must be of the format:
- *
- * size_t length, const uint8_t* data, [size_t length, const uint8_t* data, [...]]
- */
-ResponseCode keystore_cmd(command_code_t cmd, Keystore_Reply* reply, int numArgs, ...);
-
-#endif /* __KEYSTORE_CLIENT_H__ */
diff --git a/keystore/keystore_get.cpp b/keystore/keystore_get.cpp
new file mode 100644
index 0000000..45ad415
--- /dev/null
+++ b/keystore/keystore_get.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <keystore/IKeystoreService.h>
+#include <binder/IServiceManager.h>
+
+#include <keystore/keystore_get.h>
+
+using namespace android;
+
+ssize_t keystore_get(const char *key, size_t keyLength, uint8_t** value) {
+    sp<IServiceManager> sm = defaultServiceManager();
+    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
+    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
+
+    if (service == NULL) {
+        return -1;
+    }
+
+    size_t valueLength;
+    int32_t ret = service->get(String16(key, keyLength), value, &valueLength);
+    if (ret < 0) {
+        return -1;
+    } else if (ret != ::NO_ERROR) {
+        return -1;
+    } else {
+        return valueLength;
+    }
+}
diff --git a/keystore/keystore_get.h b/keystore/keystore_get.h
deleted file mode 100644
index 4b4923e..0000000
--- a/keystore/keystore_get.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2009 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_GET_H__
-#define __KEYSTORE_GET_H__
-
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#include <cutils/sockets.h>
-
-#define KEYSTORE_MESSAGE_SIZE 65535
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* This function is provided for native components to get values from keystore.
- * Users are required to link against libcutils. Keys and values are 8-bit safe.
- * The first two arguments are the key and its length. The third argument
- * specifies the buffer to store the retrieved value, which must be an array of
- * KEYSTORE_MESSAGE_SIZE bytes. This function returns the length of the value or
- * -1 if an error happens. */
-static int keystore_get(const char *key, int length, char *value)
-{
-    uint8_t bytes[2] = {length >> 8, length};
-    uint8_t code = 'g';
-    int sock;
-
-    if (length < 0 || length > KEYSTORE_MESSAGE_SIZE) {
-        return -1;
-    }
-    sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
-                               SOCK_STREAM);
-    if (sock == -1) {
-        return -1;
-    }
-    if (send(sock, &code, 1, 0) == 1 && send(sock, bytes, 2, 0) == 2 &&
-        send(sock, key, length, 0) == length && shutdown(sock, SHUT_WR) == 0 &&
-        recv(sock, &code, 1, 0) == 1 && code == /* NO_ERROR */ 1 &&
-        recv(sock, &bytes[0], 1, 0) == 1 && recv(sock, &bytes[1], 1, 0) == 1) {
-        int offset = 0;
-        length = bytes[0] << 8 | bytes[1];
-        while (offset < length) {
-            int n = recv(sock, &value[offset], length - offset, 0);
-            if (n <= 0) {
-                length = -1;
-                break;
-            }
-            offset += n;
-        }
-    } else {
-        length = -1;
-    }
-
-    close(sock);
-    return length;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/softkeymaster/Android.mk b/softkeymaster/Android.mk
index 8623c2e..63c2ba1 100644
--- a/softkeymaster/Android.mk
+++ b/softkeymaster/Android.mk
@@ -28,7 +28,7 @@
 
 LOCAL_C_FLAGS = -fvisibility=hidden -Wall -Werror
 
-LOCAL_SHARED_LIBRARIES := libcrypto liblog libkeystore_client
+LOCAL_SHARED_LIBRARIES := libcrypto liblog libkeystore_binder
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/softkeymaster/keymaster_openssl.cpp b/softkeymaster/keymaster_openssl.cpp
index 5a7327b..3620450 100644
--- a/softkeymaster/keymaster_openssl.cpp
+++ b/softkeymaster/keymaster_openssl.cpp
@@ -17,7 +17,7 @@
 #include <string.h>
 #include <stdint.h>
 
-#include <keystore.h>
+#include <keystore/keystore.h>
 
 #include <hardware/hardware.h>
 #include <hardware/keymaster.h>
