diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
index b4e35ab..53788bd 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -16,7 +16,6 @@
 */
 
 #include <stdint.h>
-#include <sys/limits.h>
 #include <sys/types.h>
 
 #define LOG_TAG "KeystoreService"
@@ -30,8 +29,6 @@
 
 namespace android {
 
-static keymaster_key_param_t* readParamList(const Parcel& in, size_t* length);
-
 KeystoreArg::KeystoreArg(const void* data, size_t len)
     : mData(data), mSize(len) {
 }
@@ -47,316 +44,6 @@
     return mSize;
 }
 
-OperationResult::OperationResult() : resultCode(0), token(), inputConsumed(0),
-    data(NULL), dataLength(0) {
-}
-
-OperationResult::~OperationResult() {
-}
-
-void OperationResult::readFromParcel(const Parcel& in) {
-    resultCode = in.readInt32();
-    token = in.readStrongBinder();
-    inputConsumed = in.readInt32();
-    ssize_t length = in.readInt32();
-    dataLength = 0;
-    if (length > 0) {
-        const void* buf = in.readInplace(length);
-        if (buf) {
-            data.reset(reinterpret_cast<uint8_t*>(malloc(length)));
-            if (data.get()) {
-                memcpy(data.get(), buf, length);
-                dataLength = (size_t) length;
-            } else {
-                ALOGE("Failed to allocate OperationResult buffer");
-            }
-        } else {
-            ALOGE("Failed to readInplace OperationResult data");
-        }
-    }
-}
-
-void OperationResult::writeToParcel(Parcel* out) const {
-    out->writeInt32(resultCode);
-    out->writeStrongBinder(token);
-    out->writeInt32(inputConsumed);
-    out->writeInt32(dataLength);
-    if (dataLength && data) {
-        void* buf = out->writeInplace(dataLength);
-        if (buf) {
-            memcpy(buf, data.get(), dataLength);
-        } else {
-            ALOGE("Failed to writeInplace OperationResult data.");
-        }
-    }
-}
-
-ExportResult::ExportResult() : resultCode(0), exportData(NULL), dataLength(0) {
-}
-
-ExportResult::~ExportResult() {
-}
-
-void ExportResult::readFromParcel(const Parcel& in) {
-    resultCode = in.readInt32();
-    ssize_t length = in.readInt32();
-    dataLength = 0;
-    if (length > 0) {
-        const void* buf = in.readInplace(length);
-        if (buf) {
-            exportData.reset(reinterpret_cast<uint8_t*>(malloc(length)));
-            if (exportData.get()) {
-                memcpy(exportData.get(), buf, length);
-                dataLength = (size_t) length;
-            } else {
-                ALOGE("Failed to allocate ExportData buffer");
-            }
-        } else {
-            ALOGE("Failed to readInplace ExportData data");
-        }
-    }
-}
-
-void ExportResult::writeToParcel(Parcel* out) const {
-    out->writeInt32(resultCode);
-    out->writeInt32(dataLength);
-    if (exportData && dataLength) {
-        void* buf = out->writeInplace(dataLength);
-        if (buf) {
-            memcpy(buf, exportData.get(), dataLength);
-        } else {
-            ALOGE("Failed to writeInplace ExportResult data.");
-        }
-    }
-}
-
-KeymasterArguments::KeymasterArguments() {
-}
-
-KeymasterArguments::~KeymasterArguments() {
-    keymaster_free_param_values(params.data(), params.size());
-}
-
-void KeymasterArguments::readFromParcel(const Parcel& in) {
-    ssize_t length = in.readInt32();
-    size_t ulength = (size_t) length;
-    if (length < 0) {
-        ulength = 0;
-    }
-    keymaster_free_param_values(params.data(), params.size());
-    params.clear();
-    for(size_t i = 0; i < ulength; i++) {
-        keymaster_key_param_t param;
-        if (!readKeymasterArgumentFromParcel(in, &param)) {
-            ALOGE("Error reading keymaster argument from parcel");
-            break;
-        }
-        params.push_back(param);
-    }
-}
-
-void KeymasterArguments::writeToParcel(Parcel* out) const {
-    out->writeInt32(params.size());
-    for (auto param : params) {
-        out->writeInt32(1);
-        writeKeymasterArgumentToParcel(param, out);
-    }
-}
-
-KeyCharacteristics::KeyCharacteristics() {
-    memset((void*) &characteristics, 0, sizeof(characteristics));
-}
-
-KeyCharacteristics::~KeyCharacteristics() {
-    keymaster_free_characteristics(&characteristics);
-}
-
-void KeyCharacteristics::readFromParcel(const Parcel& in) {
-    size_t length;
-    keymaster_key_param_t* params = readParamList(in, &length);
-    characteristics.sw_enforced.params = params;
-    characteristics.sw_enforced.length = length;
-
-    params = readParamList(in, &length);
-    characteristics.hw_enforced.params = params;
-    characteristics.hw_enforced.length = length;
-}
-
-void KeyCharacteristics::writeToParcel(Parcel* out) const {
-    if (characteristics.sw_enforced.params) {
-        out->writeInt32(characteristics.sw_enforced.length);
-        for (size_t i = 0; i < characteristics.sw_enforced.length; i++) {
-            out->writeInt32(1);
-            writeKeymasterArgumentToParcel(characteristics.sw_enforced.params[i], out);
-        }
-    } else {
-        out->writeInt32(0);
-    }
-    if (characteristics.hw_enforced.params) {
-        out->writeInt32(characteristics.hw_enforced.length);
-        for (size_t i = 0; i < characteristics.hw_enforced.length; i++) {
-            out->writeInt32(1);
-            writeKeymasterArgumentToParcel(characteristics.hw_enforced.params[i], out);
-        }
-    } else {
-        out->writeInt32(0);
-    }
-}
-
-void writeKeymasterArgumentToParcel(const keymaster_key_param_t& param, Parcel* out) {
-    switch (keymaster_tag_get_type(param.tag)) {
-        case KM_ENUM:
-        case KM_ENUM_REP: {
-            out->writeInt32(param.tag);
-            out->writeInt32(param.enumerated);
-            break;
-        }
-        case KM_INT:
-        case KM_INT_REP: {
-            out->writeInt32(param.tag);
-            out->writeInt32(param.integer);
-            break;
-        }
-        case KM_LONG: {
-            out->writeInt32(param.tag);
-            out->writeInt64(param.long_integer);
-            break;
-        }
-        case KM_DATE: {
-            out->writeInt32(param.tag);
-            out->writeInt64(param.date_time);
-            break;
-        }
-        case KM_BOOL: {
-            out->writeInt32(param.tag);
-            break;
-        }
-        case KM_BIGNUM:
-        case KM_BYTES: {
-            out->writeInt32(param.tag);
-            out->writeInt32(param.blob.data_length);
-            void* buf = out->writeInplace(param.blob.data_length);
-            if (buf) {
-                memcpy(buf, param.blob.data, param.blob.data_length);
-            } else {
-                ALOGE("Failed to writeInplace keymaster blob param");
-            }
-            break;
-        }
-        default: {
-            ALOGE("Failed to write argument: Unsupported keymaster_tag_t %d", param.tag);
-        }
-    }
-}
-
-
-bool readKeymasterArgumentFromParcel(const Parcel& in, keymaster_key_param_t* out) {
-    if (in.readInt32() == 0) {
-        return false;
-    }
-    keymaster_tag_t tag = static_cast<keymaster_tag_t>(in.readInt32());
-    switch (keymaster_tag_get_type(tag)) {
-        case KM_ENUM:
-        case KM_ENUM_REP: {
-            uint32_t value = in.readInt32();
-            *out = keymaster_param_enum(tag, value);
-            break;
-        }
-        case KM_INT:
-        case KM_INT_REP: {
-            uint32_t value = in.readInt32();
-            *out = keymaster_param_int(tag, value);
-            break;
-        }
-        case KM_LONG: {
-            uint64_t value = in.readInt64();
-            *out = keymaster_param_long(tag, value);
-            break;
-        }
-        case KM_DATE: {
-            uint64_t value = in.readInt64();
-            *out = keymaster_param_date(tag, value);
-            break;
-        }
-        case KM_BOOL: {
-            *out = keymaster_param_bool(tag);
-            break;
-        }
-        case KM_BIGNUM:
-        case KM_BYTES: {
-            ssize_t length = in.readInt32();
-            uint8_t* data = NULL;
-            size_t ulength = 0;
-            if (length >= 0) {
-                ulength = (size_t) length;
-                // use malloc here so we can use keymaster_free_param_values
-                // consistently.
-                data = reinterpret_cast<uint8_t*>(malloc(ulength));
-                const void* buf = in.readInplace(ulength);
-                if (!buf || !data) {
-                    ALOGE("Failed to allocate buffer for keymaster blob param");
-                    return false;
-                }
-                memcpy(data, buf, ulength);
-            }
-            *out = keymaster_param_blob(tag, data, ulength);
-            break;
-        }
-        default: {
-            ALOGE("Unsupported keymaster_tag_t %d", tag);
-            return false;
-        }
-    }
-    return true;
-}
-
-// Read a keymaster_key_param_t* from a Parcel for use in a
-// keymaster_key_characteristics_t. This will be free'd by calling
-// keymaster_free_key_characteristics.
-static keymaster_key_param_t* readParamList(const Parcel& in, size_t* length) {
-    ssize_t slength = in.readInt32();
-    if (slength < 0) {
-        return NULL;
-    }
-    *length = (size_t) slength;
-    if (*length >= UINT_MAX / sizeof(keymaster_key_param_t)) {
-        return NULL;
-    }
-    keymaster_key_param_t* list =
-            reinterpret_cast<keymaster_key_param_t*>(malloc(*length *
-                                                            sizeof(keymaster_key_param_t)));
-    if (!list) {
-        ALOGD("Failed to allocate buffer for generateKey outCharacteristics");
-        goto err;
-    }
-    for (size_t i = 0; i < *length ; i++) {
-        if (!readKeymasterArgumentFromParcel(in, &list[i])) {
-            ALOGE("Failed to read keymaster argument");
-            keymaster_free_param_values(list, i);
-            goto err;
-        }
-    }
-    return list;
-err:
-    free(list);
-    return NULL;
-}
-
-static void readKeymasterBlob(const Parcel& in, keymaster_blob_t* blob) {
-    ssize_t length = in.readInt32();
-    if (length > 0) {
-        blob->data = (uint8_t*) in.readInplace(length);
-        if (blob->data) {
-            blob->data_length = (size_t) length;
-        } else {
-            blob->data_length = 0;
-        }
-    } else {
-        blob->data = NULL;
-        blob->data_length = 0;
-    }
-}
-
 class BpKeystoreService: public BpInterface<IKeystoreService>
 {
 public:
@@ -952,254 +639,6 @@
         }
         return ret;
     }
-    virtual int32_t addRngEntropy(const uint8_t* buf, size_t bufLength)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
-        data.writeInt32(bufLength);
-        data.writeByteArray(bufLength, buf);
-        status_t status = remote()->transact(BnKeystoreService::ADD_RNG_ENTROPY, data, &reply);
-        if (status != NO_ERROR) {
-            ALOGD("addRngEntropy() could not contact remote: %d\n", status);
-            return -1;
-        }
-        int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
-        if (err < 0) {
-            ALOGD("addRngEntropy() caught exception %d\n", err);
-            return -1;
-        }
-        return ret;
-    };
-
-    virtual int32_t generateKey(const String16& name, const KeymasterArguments& params,
-                                int uid, int flags, KeyCharacteristics* outCharacteristics)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
-        data.writeString16(name);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeInt32(uid);
-        data.writeInt32(flags);
-        status_t status = remote()->transact(BnKeystoreService::GENERATE_KEY, data, &reply);
-        if (status != NO_ERROR) {
-            ALOGD("generateKey() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
-        }
-        int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
-        if (err < 0) {
-            ALOGD("generateKey() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
-        }
-        if (reply.readInt32() != 0 && outCharacteristics) {
-            outCharacteristics->readFromParcel(reply);
-        }
-        return ret;
-    }
-    virtual int32_t getKeyCharacteristics(const String16& name,
-                                          const keymaster_blob_t& clientId,
-                                          const keymaster_blob_t& appData,
-                                          KeyCharacteristics* outCharacteristics)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
-        data.writeString16(name);
-        data.writeByteArray(clientId.data_length, clientId.data);
-        data.writeByteArray(appData.data_length, appData.data);
-        status_t status = remote()->transact(BnKeystoreService::GET_KEY_CHARACTERISTICS,
-                                             data, &reply);
-        if (status != NO_ERROR) {
-            ALOGD("getKeyCharacteristics() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
-        }
-        int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
-        if (err < 0) {
-            ALOGD("getKeyCharacteristics() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
-        }
-        if (reply.readInt32() != 0 && outCharacteristics) {
-            outCharacteristics->readFromParcel(reply);
-        }
-        return ret;
-    }
-    virtual int32_t importKey(const String16& name, const KeymasterArguments&  params,
-                              keymaster_key_format_t format, const uint8_t *keyData,
-                              size_t keyLength, int uid, int flags,
-                              KeyCharacteristics* outCharacteristics)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
-        data.writeString16(name);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeInt32(format);
-        data.writeByteArray(keyLength, keyData);
-        data.writeInt32(uid);
-        data.writeInt32(flags);
-        status_t status = remote()->transact(BnKeystoreService::IMPORT_KEY, data, &reply);
-        if (status != NO_ERROR) {
-            ALOGD("importKey() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
-        }
-        int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
-        if (err < 0) {
-            ALOGD("importKey() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
-        }
-        if (reply.readInt32() != 0 && outCharacteristics) {
-            outCharacteristics->readFromParcel(reply);
-        }
-        return ret;
-    }
-
-    virtual void exportKey(const String16& name, keymaster_key_format_t format,
-                           const keymaster_blob_t& clientId,
-                           const keymaster_blob_t& appData, ExportResult* result)
-    {
-        if (!result) {
-            return;
-        }
-
-        Parcel data, reply;
-        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
-        data.writeString16(name);
-        data.writeInt32(format);
-        data.writeByteArray(clientId.data_length, clientId.data);
-        data.writeByteArray(appData.data_length, appData.data);
-        status_t status = remote()->transact(BnKeystoreService::EXPORT_KEY, data, &reply);
-        if (status != NO_ERROR) {
-            ALOGD("exportKey() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
-            return;
-        }
-        int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
-        if (err < 0) {
-            ALOGD("exportKey() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
-            return;
-        }
-        if (reply.readInt32() != 0) {
-            result->readFromParcel(reply);
-        }
-    }
-
-    virtual void begin(const sp<IBinder>& appToken, const String16& name,
-                       keymaster_purpose_t purpose, bool pruneable,
-                       const KeymasterArguments& params, KeymasterArguments* outParams,
-                       OperationResult* result)
-    {
-        if (!result || !outParams) {
-            return;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
-        data.writeStrongBinder(appToken);
-        data.writeString16(name);
-        data.writeInt32(purpose);
-        data.writeInt32(pruneable ? 1 : 0);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        status_t status = remote()->transact(BnKeystoreService::BEGIN, data, &reply);
-        if (status != NO_ERROR) {
-            ALOGD("begin() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
-            return;
-        }
-        int32_t err = reply.readExceptionCode();
-        if (err < 0) {
-            ALOGD("begin() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
-            return;
-        }
-        if (reply.readInt32() != 0) {
-            result->readFromParcel(reply);
-        }
-        if (reply.readInt32() != 0) {
-            outParams->readFromParcel(reply);
-        }
-    }
-
-    virtual void update(const sp<IBinder>& token, const KeymasterArguments& params,
-                        uint8_t* opData, size_t dataLength, OperationResult* result)
-    {
-        if (!result) {
-            return;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
-        data.writeStrongBinder(token);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeByteArray(dataLength, opData);
-        status_t status = remote()->transact(BnKeystoreService::UPDATE, data, &reply);
-        if (status != NO_ERROR) {
-            ALOGD("update() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
-            return;
-        }
-        int32_t err = reply.readExceptionCode();
-        if (err < 0) {
-            ALOGD("update() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
-            return;
-        }
-        if (reply.readInt32() != 0) {
-            result->readFromParcel(reply);
-        }
-    }
-
-    virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
-                        uint8_t* signature, size_t signatureLength, OperationResult* result)
-    {
-        if (!result) {
-            return;
-        }
-        Parcel data, reply;
-        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
-        data.writeStrongBinder(token);
-        data.writeInt32(1);
-        params.writeToParcel(&data);
-        data.writeByteArray(signatureLength, signature);
-        status_t status = remote()->transact(BnKeystoreService::FINISH, data, &reply);
-        if (status != NO_ERROR) {
-            ALOGD("finish() could not contact remote: %d\n", status);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
-            return;
-        }
-        int32_t err = reply.readExceptionCode();
-        if (err < 0) {
-            ALOGD("finish() caught exception %d\n", err);
-            result->resultCode = KM_ERROR_UNKNOWN_ERROR;
-            return;
-        }
-        if (reply.readInt32() != 0) {
-            result->readFromParcel(reply);
-        }
-    }
-
-    virtual int32_t abort(const sp<IBinder>& token)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
-        data.writeStrongBinder(token);
-        status_t status = remote()->transact(BnKeystoreService::FINISH, data, &reply);
-        if (status != NO_ERROR) {
-            ALOGD("abort() could not contact remote: %d\n", status);
-            return KM_ERROR_UNKNOWN_ERROR;
-        }
-        int32_t err = reply.readExceptionCode();
-        int32_t ret = reply.readInt32();
-        if (err < 0) {
-            ALOGD("abort() caught exception %d\n", err);
-            return KM_ERROR_UNKNOWN_ERROR;
-        }
-        return ret;
-    }
 };
 
 IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService");
@@ -1526,170 +965,6 @@
             reply->writeInt32(ret);
             return NO_ERROR;
         }
-        case ADD_RNG_ENTROPY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            size_t size = data.readInt32();
-            uint8_t* bytes;
-            if (size > 0) {
-                bytes = (uint8_t*) data.readInplace(size);
-            } else {
-                bytes = NULL;
-            }
-            int32_t ret = addRngEntropy(bytes, size);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            return NO_ERROR;
-        }
-        case GENERATE_KEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            int32_t uid = data.readInt32();
-            int32_t flags = data.readInt32();
-            KeyCharacteristics outCharacteristics;
-            int32_t ret = generateKey(name, args, uid, flags, &outCharacteristics);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeInt32(1);
-            outCharacteristics.writeToParcel(reply);
-            return NO_ERROR;
-        }
-        case GET_KEY_CHARACTERISTICS: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            keymaster_blob_t clientId, appData;
-            readKeymasterBlob(data, &clientId);
-            readKeymasterBlob(data, &appData);
-            KeyCharacteristics outCharacteristics;
-            int ret = getKeyCharacteristics(name, clientId, appData, &outCharacteristics);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeInt32(1);
-            outCharacteristics.writeToParcel(reply);
-            return NO_ERROR;
-        }
-        case IMPORT_KEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
-            uint8_t* keyData = NULL;
-            ssize_t keyLength = data.readInt32();
-            size_t ukeyLength = (size_t) keyLength;
-            if (keyLength >= 0) {
-                keyData = (uint8_t*) data.readInplace(keyLength);
-            } else {
-                ukeyLength = 0;
-            }
-            int32_t uid = data.readInt32();
-            int32_t flags = data.readInt32();
-            KeyCharacteristics outCharacteristics;
-            int32_t ret = importKey(name, args, format, keyData, ukeyLength, uid, flags,
-                                    &outCharacteristics);
-            reply->writeNoException();
-            reply->writeInt32(ret);
-            reply->writeInt32(1);
-            outCharacteristics.writeToParcel(reply);
-
-            return NO_ERROR;
-        }
-        case EXPORT_KEY: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            String16 name = data.readString16();
-            keymaster_key_format_t format = static_cast<keymaster_key_format_t>(data.readInt32());
-            keymaster_blob_t clientId, appData;
-            readKeymasterBlob(data, &clientId);
-            readKeymasterBlob(data, &appData);
-            ExportResult result;
-            exportKey(name, format, clientId, appData, &result);
-            reply->writeNoException();
-            reply->writeInt32(1);
-            result.writeToParcel(reply);
-
-            return NO_ERROR;
-        }
-        case BEGIN: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            String16 name = data.readString16();
-            keymaster_purpose_t purpose = static_cast<keymaster_purpose_t>(data.readInt32());
-            bool pruneable = data.readInt32() != 0;
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            KeymasterArguments outArgs;
-            OperationResult result;
-            begin(token, name, purpose, pruneable, args, &outArgs, &result);
-            reply->writeNoException();
-            reply->writeInt32(1);
-            result.writeToParcel(reply);
-            reply->writeInt32(1);
-            outArgs.writeToParcel(reply);
-
-            return NO_ERROR;
-        }
-        case UPDATE: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            uint8_t* buf = NULL;
-            ssize_t bufLength = data.readInt32();
-            size_t ubufLength = (size_t) bufLength;
-            if (bufLength > 0) {
-                buf = (uint8_t*) data.readInplace(ubufLength);
-            } else {
-                ubufLength = 0;
-            }
-            OperationResult result;
-            update(token, args, buf, ubufLength, &result);
-            reply->writeNoException();
-            reply->writeInt32(1);
-            result.writeToParcel(reply);
-
-            return NO_ERROR;
-        }
-        case FINISH: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            KeymasterArguments args;
-            if (data.readInt32() != 0) {
-                args.readFromParcel(data);
-            }
-            uint8_t* buf = NULL;
-            ssize_t bufLength = data.readInt32();
-            size_t ubufLength = (size_t) bufLength;
-            if (bufLength > 0) {
-                buf = (uint8_t*) data.readInplace(ubufLength);
-            } else {
-                ubufLength = 0;
-            }
-            OperationResult result;
-            finish(token, args, buf, ubufLength, &result);
-            reply->writeNoException();
-            reply->writeInt32(1);
-            result.writeToParcel(reply);
-
-            return NO_ERROR;
-        }
-        case ABORT: {
-            CHECK_INTERFACE(IKeystoreService, data, reply);
-            sp<IBinder> token = data.readStrongBinder();
-            int32_t result = abort(token);
-            reply->writeNoException();
-            reply->writeInt32(result);
-
-            return NO_ERROR;
-        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
index f69b76e..afdff8d 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -17,11 +17,9 @@
 #ifndef KEYSTORE_IKEYSTORESERVICE_H
 #define KEYSTORE_IKEYSTORESERVICE_H
 
-#include <hardware/keymaster_defs.h>
 #include <utils/RefBase.h>
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
-#include <vector>
 
 namespace android {
 
@@ -38,59 +36,6 @@
     size_t mSize;
 };
 
-struct MallocDeleter {
-    void operator()(uint8_t* p) { free(p); }
-};
-
-// struct for serializing the results of begin/update/finish
-struct OperationResult {
-    OperationResult();
-    ~OperationResult();
-    void readFromParcel(const Parcel& in);
-    void writeToParcel(Parcel* out) const;
-
-    int resultCode;
-    sp<IBinder> token;
-    int inputConsumed;
-    std::unique_ptr<uint8_t[], MallocDeleter> data;
-    size_t dataLength;
-};
-
-// struct for serializing the results of export
-struct ExportResult {
-    ExportResult();
-    ~ExportResult();
-    void readFromParcel(const Parcel& in);
-    void writeToParcel(Parcel* out) const;
-
-    int resultCode;
-    std::unique_ptr<uint8_t[], MallocDeleter> exportData;
-    size_t dataLength;
-};
-
-// struct for serializing/deserializing a list of keymaster_key_param_t's
-struct KeymasterArguments {
-    KeymasterArguments();
-    ~KeymasterArguments();
-    void readFromParcel(const Parcel& in);
-    void writeToParcel(Parcel* out) const;
-
-    std::vector<keymaster_key_param_t> params;
-};
-
-// struct for serializing keymaster_key_characteristics_t's
-struct KeyCharacteristics {
-    KeyCharacteristics();
-    ~KeyCharacteristics();
-    void readFromParcel(const Parcel& in);
-    void writeToParcel(Parcel* out) const;
-
-    keymaster_key_characteristics_t characteristics;
-};
-
-bool readKeymasterArgumentFromParcel(const Parcel& in, keymaster_key_param_t* out);
-void writeKeymasterArgumentToParcel(const keymaster_key_param_t& param, Parcel* out);
-
 /*
  * This must be kept manually in sync with frameworks/base's IKeystoreService.java
  */
@@ -123,15 +68,6 @@
         RESET_UID = IBinder::FIRST_CALL_TRANSACTION + 23,
         SYNC_UID = IBinder::FIRST_CALL_TRANSACTION + 24,
         PASSWORD_UID = IBinder::FIRST_CALL_TRANSACTION + 25,
-        ADD_RNG_ENTROPY = IBinder::FIRST_CALL_TRANSACTION + 26,
-        GENERATE_KEY = IBinder::FIRST_CALL_TRANSACTION + 27,
-        GET_KEY_CHARACTERISTICS = IBinder::FIRST_CALL_TRANSACTION + 28,
-        IMPORT_KEY = IBinder::FIRST_CALL_TRANSACTION + 29,
-        EXPORT_KEY = IBinder::FIRST_CALL_TRANSACTION + 30,
-        BEGIN = IBinder::FIRST_CALL_TRANSACTION + 31,
-        UPDATE = IBinder::FIRST_CALL_TRANSACTION + 32,
-        FINISH = IBinder::FIRST_CALL_TRANSACTION + 33,
-        ABORT = IBinder::FIRST_CALL_TRANSACTION + 34,
     };
 
     DECLARE_META_INTERFACE(KeystoreService);
@@ -193,37 +129,6 @@
     virtual int32_t sync_uid(int32_t sourceUid, int32_t targetUid) = 0;
 
     virtual int32_t password_uid(const String16& password, int32_t uid) = 0;
-
-    virtual int32_t addRngEntropy(const uint8_t* data, size_t dataLength) = 0;
-
-    virtual int32_t generateKey(const String16& name, const KeymasterArguments& params,
-                                int uid, int flags, KeyCharacteristics* outCharacteristics) = 0;
-    virtual int32_t getKeyCharacteristics(const String16& name,
-                                          const keymaster_blob_t& clientId,
-                                          const keymaster_blob_t& appData,
-                                          KeyCharacteristics* outCharacteristics) = 0;
-    virtual int32_t importKey(const String16& name, const KeymasterArguments&  params,
-                              keymaster_key_format_t format, const uint8_t *keyData,
-                              size_t keyLength, int uid, int flags,
-                              KeyCharacteristics* outCharacteristics) = 0;
-
-    virtual void exportKey(const String16& name, keymaster_key_format_t format,
-                           const keymaster_blob_t& clientId,
-                           const keymaster_blob_t& appData, ExportResult* result) = 0;
-
-    virtual void begin(const sp<IBinder>& apptoken, const String16& name,
-                       keymaster_purpose_t purpose, bool pruneable,
-                       const KeymasterArguments& params, KeymasterArguments* outParams,
-                       OperationResult* result) = 0;
-
-    virtual void update(const sp<IBinder>& token, const KeymasterArguments& params,
-                        uint8_t* data, size_t dataLength, OperationResult* result) = 0;
-
-    virtual void finish(const sp<IBinder>& token, const KeymasterArguments& params,
-                        uint8_t* signature, size_t signatureLength, OperationResult* result) = 0;
-
-    virtual int32_t abort(const sp<IBinder>& handle) = 0;
-
 };
 
 // ----------------------------------------------------------------------------
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 0a45003..194b87c 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -2433,55 +2433,6 @@
         return ::SYSTEM_ERROR;
     }
 
-    int32_t addRngEntropy(const uint8_t* data, size_t dataLength) {
-        return KM_ERROR_UNIMPLEMENTED;
-    }
-
-    int32_t generateKey(const String16& name, const KeymasterArguments& params,
-                        int uid, int flags, KeyCharacteristics* outCharacteristics) {
-        return KM_ERROR_UNIMPLEMENTED;
-    }
-
-    int32_t getKeyCharacteristics(const String16& name,
-                                  const keymaster_blob_t& clientId,
-                                  const keymaster_blob_t& appData,
-                                  KeyCharacteristics* outCharacteristics) {
-        return KM_ERROR_UNIMPLEMENTED;
-    }
-
-    int32_t importKey(const String16& name, const KeymasterArguments&  params,
-                                keymaster_key_format_t format, const uint8_t *keyData,
-                                size_t keyLength, int uid, int flags,
-                                KeyCharacteristics* outCharacteristics) {
-        return KM_ERROR_UNIMPLEMENTED;
-    }
-
-    void exportKey(const String16& name, keymaster_key_format_t format,
-                           const keymaster_blob_t& clientId,
-                           const keymaster_blob_t& appData, ExportResult* result) {
-        result->resultCode = KM_ERROR_UNIMPLEMENTED;
-    }
-
-    void begin(const sp<IBinder>& appToken, const String16& name, keymaster_purpose_t purpose,
-               bool pruneable, const KeymasterArguments& params,
-               KeymasterArguments* outParams, OperationResult* result) {
-        result->resultCode = KM_ERROR_UNIMPLEMENTED;
-    }
-
-    void update(const sp<IBinder>& token, const KeymasterArguments& params, uint8_t* data,
-                size_t dataLength, OperationResult* result) {
-        result->resultCode = KM_ERROR_UNIMPLEMENTED;
-    }
-
-    void finish(const sp<IBinder>& token, const KeymasterArguments& args, uint8_t* signature,
-                size_t signatureLength, OperationResult* result) {
-        result->resultCode = KM_ERROR_UNIMPLEMENTED;
-    }
-
-    int32_t abort(const sp<IBinder>& token) {
-        return KM_ERROR_UNIMPLEMENTED;
-    }
-
 private:
     inline bool isKeystoreUnlocked(State state) {
         switch (state) {
