am 1c73457a: am b124c9e8: Fix unchecked length in Blob creation

* commit '1c73457afe3cb0afbc2a2884c41cfdd1148aca36':
  Fix unchecked length in Blob creation
diff --git a/keystore-engine/dsa_meth.cpp b/keystore-engine/dsa_meth.cpp
index 372d5c4..3788364 100644
--- a/keystore-engine/dsa_meth.cpp
+++ b/keystore-engine/dsa_meth.cpp
@@ -93,7 +93,7 @@
         return 0;
     }
 
-    ALOGV("keystore_dsa_do_sign(%p, %d, %p) => returning %p len %llu", dgst, dlen, dsa,
+    ALOGV("keystore_dsa_do_sign(%p, %d, %p) => returning %p len %zu", dgst, dlen, dsa,
             dsa_sig.get(), replyLen);
     return dsa_sig.release();
 }
diff --git a/keystore-engine/ecdsa_meth.cpp b/keystore-engine/ecdsa_meth.cpp
index a059b54..48f178d 100644
--- a/keystore-engine/ecdsa_meth.cpp
+++ b/keystore-engine/ecdsa_meth.cpp
@@ -99,7 +99,7 @@
         return 0;
     }
 
-    ALOGV("keystore_ecdsa_do_sign(%p, %d, %p) => returning %p len %llu", dgst, dlen, eckey,
+    ALOGV("keystore_ecdsa_do_sign(%p, %d, %p) => returning %p len %zu", dgst, dlen, eckey,
             ecdsa_sig.get(), replyLen);
     return ecdsa_sig.release();
 }
diff --git a/keystore-engine/rsa_meth.cpp b/keystore-engine/rsa_meth.cpp
index da9e45f..74dfa5c 100644
--- a/keystore-engine/rsa_meth.cpp
+++ b/keystore-engine/rsa_meth.cpp
@@ -177,7 +177,7 @@
 
     free(reply);
 
-    ALOGV("rsa=%p keystore_rsa_priv_dec => returning %p len %llu", rsa, to, outSize);
+    ALOGV("rsa=%p keystore_rsa_priv_dec => returning %p len %d", rsa, to, outSize);
     return outSize;
 }
 
diff --git a/keystore/Android.mk b/keystore/Android.mk
index 47b7e84..9dca502 100644
--- a/keystore/Android.mk
+++ b/keystore/Android.mk
@@ -17,6 +17,9 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
+ifeq ($(USE_32_BIT_KEYSTORE), true)
+LOCAL_MULTILIB := 32
+endif
 LOCAL_CFLAGS := -Wall -Wextra -Werror
 LOCAL_SRC_FILES := keystore.cpp keyblob_utils.cpp
 LOCAL_C_INCLUDES := external/openssl/include
@@ -28,13 +31,17 @@
 	libkeystore_binder \
 	liblog \
 	libsoftkeymaster \
-	libutils
+	libutils \
+	libselinux
 LOCAL_MODULE := keystore
 LOCAL_MODULE_TAGS := optional
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
+ifeq ($(USE_32_BIT_KEYSTORE), true)
+LOCAL_MULTILIB := 32
+endif
 LOCAL_CFLAGS := -Wall -Wextra -Werror
 LOCAL_SRC_FILES := keystore_cli.cpp
 LOCAL_C_INCLUDES := external/openssl/include
@@ -46,6 +53,9 @@
 
 # Library for keystore clients
 include $(CLEAR_VARS)
+ifeq ($(USE_32_BIT_KEYSTORE), true)
+LOCAL_MULTILIB := 32
+endif
 LOCAL_CFLAGS := -Wall -Wextra -Werror
 LOCAL_SRC_FILES := IKeystoreService.cpp keystore_get.cpp keyblob_utils.cpp
 LOCAL_SHARED_LIBRARIES := libbinder libutils liblog
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
index 727e746..40fbe0e 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -579,6 +579,65 @@
         }
         return ret;
     }
+
+    virtual int32_t reset_uid(int32_t uid) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        status_t status = remote()->transact(BnKeystoreService::RESET_UID, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("reset_uid() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("reset_uid() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+
+    }
+
+    virtual int32_t sync_uid(int32_t sourceUid, int32_t targetUid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeInt32(sourceUid);
+        data.writeInt32(targetUid);
+        status_t status = remote()->transact(BnKeystoreService::SYNC_UID, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("sync_uid() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("sync_uid() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
+    virtual int32_t password_uid(const String16& password, int32_t uid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        data.writeString16(password);
+        data.writeInt32(uid);
+        status_t status = remote()->transact(BnKeystoreService::PASSWORD_UID, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("password_uid() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("password_uid() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.keystore");
@@ -875,6 +934,32 @@
             reply->writeInt32(ret);
             return NO_ERROR;
         }
+        case RESET_UID: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t uid = data.readInt32();
+            int32_t ret = reset_uid(uid);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        }
+        case SYNC_UID: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t sourceUid = data.readInt32();
+            int32_t targetUid = data.readInt32();
+            int32_t ret = sync_uid(sourceUid, targetUid);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            return NO_ERROR;
+        }
+        case PASSWORD_UID: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            String16 password = data.readString16();
+            int32_t uid = data.readInt32();
+            int32_t ret = password_uid(password, uid);
+            reply->writeNoException();
+            reply->writeInt32(ret);
+            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 d7281e3..afdff8d 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -65,6 +65,9 @@
         DUPLICATE = IBinder::FIRST_CALL_TRANSACTION + 20,
         IS_HARDWARE_BACKED = IBinder::FIRST_CALL_TRANSACTION + 21,
         CLEAR_UID = IBinder::FIRST_CALL_TRANSACTION + 22,
+        RESET_UID = IBinder::FIRST_CALL_TRANSACTION + 23,
+        SYNC_UID = IBinder::FIRST_CALL_TRANSACTION + 24,
+        PASSWORD_UID = IBinder::FIRST_CALL_TRANSACTION + 25,
     };
 
     DECLARE_META_INTERFACE(KeystoreService);
@@ -120,6 +123,12 @@
     virtual int32_t is_hardware_backed(const String16& keyType) = 0;
 
     virtual int32_t clear_uid(int64_t uid) = 0;
+
+    virtual int32_t reset_uid(int32_t uid) = 0;
+
+    virtual int32_t sync_uid(int32_t sourceUid, int32_t targetUid) = 0;
+
+    virtual int32_t password_uid(const String16& password, int32_t uid) = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 605df3b..58d2fd6 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -58,6 +58,8 @@
 
 #include <keystore/keystore.h>
 
+#include <selinux/android.h>
+
 #include "defaults.h"
 
 /* KeyStore is a secured storage for key-value pairs. In this implementation,
@@ -134,22 +136,25 @@
 
 /* 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,
-    P_DUPLICATE = 1 << 14,
-    P_CLEAR_UID = 1 << 15,
+    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,
+    P_DUPLICATE     = 1 << 14,
+    P_CLEAR_UID     = 1 << 15,
+    P_RESET_UID     = 1 << 16,
+    P_SYNC_UID      = 1 << 17,
+    P_PASSWORD_UID  = 1 << 18,
 } perm_t;
 
 static struct user_euid {
@@ -161,6 +166,29 @@
     {AID_ROOT, AID_SYSTEM},
 };
 
+/* perm_labels associcated with keystore_key SELinux class verbs. */
+const char *perm_labels[] = {
+    "test",
+    "get",
+    "insert",
+    "delete",
+    "exist",
+    "saw",
+    "reset",
+    "password",
+    "lock",
+    "unlock",
+    "zero",
+    "sign",
+    "verify",
+    "grant",
+    "duplicate",
+    "clear_uid",
+    "reset_uid",
+    "sync_uid",
+    "password_uid",
+};
+
 static struct user_perm {
     uid_t uid;
     perm_t perms;
@@ -174,6 +202,19 @@
 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 char *tctx;
+static int ks_is_selinux_enabled;
+
+static const char *get_perm_label(perm_t perm) {
+    unsigned int index = ffs(perm);
+    if (index > 0 && index <= (sizeof(perm_labels) / sizeof(perm_labels[0]))) {
+        return perm_labels[index - 1];
+    } else {
+        ALOGE("Keystore: Failed to retrieve permission label.\n");
+        abort();
+    }
+}
+
 /**
  * Returns the app ID (in the Android multi-user sense) for the current
  * UNIX UID.
@@ -190,8 +231,31 @@
     return uid / AID_USER;
 }
 
+static bool keystore_selinux_check_access(uid_t uid, perm_t perm, pid_t spid) {
+    if (!ks_is_selinux_enabled) {
+        return true;
+    }
 
-static bool has_permission(uid_t uid, perm_t perm) {
+    char *sctx = NULL;
+    const char *selinux_class = "keystore_key";
+    const char *str_perm = get_perm_label(perm);
+
+    if (!str_perm) {
+        return false;
+    }
+
+    if (getpidcon(spid, &sctx) != 0) {
+        ALOGE("SELinux: Failed to get source pid context.\n");
+        return false;
+    }
+
+    bool allowed = selinux_check_access(sctx, tctx, selinux_class, str_perm,
+            NULL) == 0;
+    freecon(sctx);
+    return allowed;
+}
+
+static bool has_permission(uid_t uid, perm_t perm, pid_t spid) {
     // All system users are equivalent for multi-user support.
     if (get_app_id(uid) == AID_SYSTEM) {
         uid = AID_SYSTEM;
@@ -200,11 +264,13 @@
     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 (user.perms & perm) &&
+                keystore_selinux_check_access(uid, perm, spid);
         }
     }
 
-    return DEFAULT_PERMS & perm;
+    return (DEFAULT_PERMS & perm) &&
+        keystore_selinux_check_access(uid, perm, spid);
 }
 
 /**
@@ -238,6 +304,15 @@
     return false;
 }
 
+/**
+ * Allow the system to perform some privileged tasks that have to do with
+ * system maintenance. This should not be used for any function that uses
+ * the keys in any way (e.g., signing).
+ */
+static bool is_self_or_system(uid_t callingUid, uid_t targetUid) {
+    return callingUid == targetUid || callingUid == AID_SYSTEM;
+}
+
 /* Here is the encoding of keys. This is necessary in order to allow arbitrary
  * characters in keys. Characters in [0-~] are not encoded. Others are encoded
  * into two bytes. The first byte is one of [+-.] which represents the first
@@ -700,6 +775,18 @@
         return ::NO_ERROR;
     }
 
+    ResponseCode copyMasterKey(UserState* src) {
+        if (mState != STATE_UNINITIALIZED) {
+            return ::SYSTEM_ERROR;
+        }
+        if (src->getState() != STATE_NO_ERROR) {
+            return ::SYSTEM_ERROR;
+        }
+        memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES);
+        setupMasterKeys();
+        return ::NO_ERROR;
+    }
+
     ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) {
         uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
         generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
@@ -790,19 +877,7 @@
             }
 
             // Skip anything that starts with a "."
-            if (file->d_name[0] == '.') {
-                continue;
-            }
-
-            // Find the current file's UID.
-            char* end;
-            unsigned long thisUid = strtoul(file->d_name, &end, 10);
-            if (end[0] != '_' || end[1] == 0) {
-                continue;
-            }
-
-            // Skip if this is not our user.
-            if (get_user_id(thisUid) != mUserId) {
+            if (file->d_name[0] == '.' && strcmp(".masterkey", file->d_name)) {
                 continue;
             }
 
@@ -888,14 +963,14 @@
         for (android::Vector<grant_t*>::iterator it(mGrants.begin());
                 it != mGrants.end(); it++) {
             delete *it;
-            mGrants.erase(it);
         }
+        mGrants.clear();
 
         for (android::Vector<UserState*>::iterator it(mMasterKeys.begin());
                 it != mMasterKeys.end(); it++) {
             delete *it;
-            mMasterKeys.erase(it);
         }
+        mMasterKeys.clear();
     }
 
     keymaster_device_t* getDevice() const {
@@ -920,15 +995,19 @@
         return userState->initialize(pw, mEntropy);
     }
 
+    ResponseCode copyMasterKey(uid_t src, uid_t uid) {
+        UserState *userState = getUserState(uid);
+        UserState *initState = getUserState(src);
+        return userState->copyMasterKey(initState);
+    }
+
     ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) {
-        uid_t user_id = get_user_id(uid);
-        UserState* userState = getUserState(user_id);
+        UserState* userState = getUserState(uid);
         return userState->writeMasterKey(pw, mEntropy);
     }
 
     ResponseCode readMasterKey(const android::String8& pw, uid_t uid) {
-        uid_t user_id = get_user_id(uid);
-        UserState* userState = getUserState(user_id);
+        UserState* userState = getUserState(uid);
         return userState->readMasterKey(pw, mEntropy);
     }
 
@@ -952,7 +1031,20 @@
     }
 
     bool reset(uid_t uid) {
+        android::String8 prefix("");
+        android::Vector<android::String16> aliases;
+        if (saw(prefix, &aliases, uid) != ::NO_ERROR) {
+            return ::SYSTEM_ERROR;
+        }
+
         UserState* userState = getUserState(uid);
+        for (uint32_t i = 0; i < aliases.size(); i++) {
+            android::String8 filename(aliases[i]);
+            filename = android::String8::format("%s/%s", userState->getUserDirName(),
+                    getKeyName(filename).string());
+            del(filename, ::TYPE_ANY, uid);
+        }
+
         userState->zeroizeMasterKeysInMemory();
         userState->setState(STATE_UNINITIALIZED);
         return userState->reset();
@@ -960,20 +1052,17 @@
 
     bool isEmpty(uid_t uid) const {
         const UserState* userState = getUserState(uid);
-        if (userState == NULL) {
+        if (userState == NULL || userState->getState() == STATE_UNINITIALIZED) {
             return true;
         }
 
         DIR* dir = opendir(userState->getUserDirName());
-        struct dirent* file;
         if (!dir) {
             return true;
         }
+
         bool result = true;
-
-        char filename[NAME_MAX];
-        int n = snprintf(filename, sizeof(filename), "%u_", uid);
-
+        struct dirent* file;
         while ((file = readdir(dir)) != NULL) {
             // We only care about files.
             if (file->d_type != DT_REG) {
@@ -985,10 +1074,8 @@
                 continue;
             }
 
-            if (!strncmp(file->d_name, filename, n)) {
-                result = false;
-                break;
-            }
+            result = false;
+            break;
         }
         closedir(dir);
         return result;
@@ -1054,6 +1141,71 @@
                 mEntropy);
     }
 
+    ResponseCode del(const char *filename, const BlobType type, uid_t uid) {
+        Blob keyBlob;
+        ResponseCode rc = get(filename, &keyBlob, type, uid);
+        if (rc != ::NO_ERROR) {
+            return rc;
+        }
+
+        if (keyBlob.getType() == ::TYPE_KEY_PAIR) {
+            // A device doesn't have to implement delete_keypair.
+            if (mDevice->delete_keypair != NULL && !keyBlob.isFallback()) {
+                if (mDevice->delete_keypair(mDevice, keyBlob.getValue(), keyBlob.getLength())) {
+                    rc = ::SYSTEM_ERROR;
+                }
+            }
+        }
+        if (rc != ::NO_ERROR) {
+            return rc;
+        }
+
+        return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
+    }
+
+    ResponseCode saw(const android::String8& prefix, android::Vector<android::String16> *matches,
+            uid_t uid) {
+
+        UserState* userState = getUserState(uid);
+        size_t n = prefix.length();
+
+        DIR* dir = opendir(userState->getUserDirName());
+        if (!dir) {
+            ALOGW("can't open directory for user: %s", strerror(errno));
+            return ::SYSTEM_ERROR;
+        }
+
+        struct dirent* file;
+        while ((file = readdir(dir)) != NULL) {
+            // We only care about files.
+            if (file->d_type != DT_REG) {
+                continue;
+            }
+
+            // Skip anything that starts with a "."
+            if (file->d_name[0] == '.') {
+                continue;
+            }
+
+            if (!strncmp(prefix.string(), file->d_name, n)) {
+                const char* p = &file->d_name[n];
+                size_t plen = strlen(p);
+
+                size_t extra = decode_key_length(p, plen);
+                char *match = (char*) malloc(extra + 1);
+                if (match != NULL) {
+                    decode_key(match, p, plen);
+                    matches->push(android::String16(match, extra));
+                    free(match);
+                } else {
+                    ALOGW("could not allocate match of size %zd", extra);
+                }
+            }
+        }
+        closedir(dir);
+        return ::NO_ERROR;
+    }
+
     void addGrant(const char* filename, uid_t granteeUid) {
         const grant_t* existing = getGrant(filename, granteeUid);
         if (existing == NULL) {
@@ -1095,11 +1247,14 @@
         bool isFallback = false;
         rc = mDevice->import_keypair(mDevice, key, keyLen, &data, &dataLength);
         if (rc) {
-            // If this is an old device HAL, try to fall back to an old version
-            if (mDevice->common.module->module_api_version < KEYMASTER_MODULE_API_VERSION_0_2) {
-                rc = openssl_import_keypair(mDevice, key, keyLen, &data, &dataLength);
-                isFallback = true;
-            }
+            /*
+             * Maybe the device doesn't support this type of key. Try to use the
+             * software fallback keymaster implementation. This is a little bit
+             * lazier than checking the PKCS#8 key type, but the software
+             * implementation will do that anyway.
+             */
+            rc = openssl_import_keypair(mDevice, key, keyLen, &data, &dataLength);
+            isFallback = true;
 
             if (rc) {
                 ALOGE("Error while importing keypair: %d", rc);
@@ -1446,7 +1601,8 @@
 
     int32_t test() {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_TEST)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_TEST, spid)) {
             ALOGW("permission denied for %d: test", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1456,7 +1612,8 @@
 
     int32_t get(const String16& name, uint8_t** item, size_t* itemLength) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_GET)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_GET, spid)) {
             ALOGW("permission denied for %d: get", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1482,8 +1639,9 @@
 
     int32_t insert(const String16& name, const uint8_t* item, size_t itemLength, int targetUid,
             int32_t flags) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_INSERT)) {
+        if (!has_permission(callingUid, P_INSERT, spid)) {
             ALOGW("permission denied for %d: insert", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1511,7 +1669,8 @@
 
     int32_t del(const String16& name, int targetUid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_DELETE)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_DELETE, spid)) {
             ALOGW("permission denied for %d: del", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1524,19 +1683,13 @@
 
         String8 name8(name);
         String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
-
-        Blob keyBlob;
-        ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, TYPE_GENERIC,
-                targetUid);
-        if (responseCode != ::NO_ERROR) {
-            return responseCode;
-        }
-        return (unlink(filename) && errno != ENOENT) ? ::SYSTEM_ERROR : ::NO_ERROR;
+        return mKeyStore->del(filename.string(), ::TYPE_GENERIC, targetUid);
     }
 
     int32_t exist(const String16& name, int targetUid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_EXIST)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_EXIST, spid)) {
             ALOGW("permission denied for %d: exist", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1558,7 +1711,8 @@
 
     int32_t saw(const String16& prefix, int targetUid, Vector<String16>* matches) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_SAW)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_SAW, spid)) {
             ALOGW("permission denied for %d: saw", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1569,75 +1723,24 @@
             return ::PERMISSION_DENIED;
         }
 
-        UserState* userState = mKeyStore->getUserState(targetUid);
-        DIR* dir = opendir(userState->getUserDirName());
-        if (!dir) {
-            ALOGW("can't open directory for user: %s", strerror(errno));
-            return ::SYSTEM_ERROR;
-        }
-
         const String8 prefix8(prefix);
         String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid));
-        size_t n = filename.length();
 
-        struct dirent* file;
-        while ((file = readdir(dir)) != NULL) {
-            // We only care about files.
-            if (file->d_type != DT_REG) {
-                continue;
-            }
-
-            // Skip anything that starts with a "."
-            if (file->d_name[0] == '.') {
-                continue;
-            }
-
-            if (!strncmp(filename.string(), file->d_name, n)) {
-                const char* p = &file->d_name[n];
-                size_t plen = strlen(p);
-
-                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);
-                }
-            }
+        if (mKeyStore->saw(filename, matches, targetUid) != ::NO_ERROR) {
+            return ::SYSTEM_ERROR;
         }
-        closedir(dir);
-
         return ::NO_ERROR;
     }
 
     int32_t reset() {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_RESET)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_RESET, spid)) {
             ALOGW("permission denied for %d: reset", callingUid);
             return ::PERMISSION_DENIED;
         }
 
-        ResponseCode rc = mKeyStore->reset(callingUid) ? ::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 mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR;
     }
 
     /*
@@ -1649,7 +1752,8 @@
      */
     int32_t password(const String16& password) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_PASSWORD)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_PASSWORD, spid)) {
             ALOGW("permission denied for %d: password", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1675,7 +1779,8 @@
 
     int32_t lock() {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_LOCK)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_LOCK, spid)) {
             ALOGW("permission denied for %d: lock", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1692,7 +1797,8 @@
 
     int32_t unlock(const String16& pw) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_UNLOCK)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_UNLOCK, spid)) {
             ALOGW("permission denied for %d: unlock", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1709,7 +1815,8 @@
 
     int32_t zero() {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_ZERO)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_ZERO, spid)) {
             ALOGW("permission denied for %d: zero", callingUid);
             return -1;
         }
@@ -1720,7 +1827,8 @@
     int32_t generate(const String16& name, int32_t targetUid, int32_t keyType, int32_t keySize,
             int32_t flags, Vector<sp<KeystoreArg> >* args) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_INSERT)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_INSERT, spid)) {
             ALOGW("permission denied for %d: generate", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1787,7 +1895,7 @@
                 return ::SYSTEM_ERROR;
             }
 
-            if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2) {
+            if (isKeyTypeSupported(device, TYPE_DSA)) {
                 rc = device->generate_keypair(device, TYPE_DSA, &dsa_params, &data, &dataLength);
             } else {
                 isFallback = true;
@@ -1805,7 +1913,7 @@
             }
             ec_params.field_size = keySize;
 
-            if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_0_2) {
+            if (isKeyTypeSupported(device, TYPE_EC)) {
                 rc = device->generate_keypair(device, TYPE_EC, &ec_params, &data, &dataLength);
             } else {
                 isFallback = true;
@@ -1871,7 +1979,8 @@
     int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid,
             int32_t flags) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_INSERT)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_INSERT, spid)) {
             ALOGW("permission denied for %d: import", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1897,7 +2006,8 @@
     int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
             size_t* outLength) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_SIGN)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_SIGN, spid)) {
             ALOGW("permission denied for %d: saw", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -1947,7 +2057,8 @@
     int32_t verify(const String16& name, const uint8_t* data, size_t dataLength,
             const uint8_t* signature, size_t signatureLength) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_VERIFY)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_VERIFY, spid)) {
             ALOGW("permission denied for %d: verify", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -2008,7 +2119,8 @@
      */
     int32_t get_pubkey(const String16& name, uint8_t** pubkey, size_t* pubkeyLength) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_GET)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_GET, spid)) {
             ALOGW("permission denied for %d: get_pubkey", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -2051,7 +2163,8 @@
 
     int32_t del_key(const String16& name, int targetUid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_DELETE)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_DELETE, spid)) {
             ALOGW("permission denied for %d: del_key", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -2064,38 +2177,13 @@
 
         String8 name8(name);
         String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
-
-        Blob keyBlob;
-        ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, ::TYPE_KEY_PAIR,
-                targetUid);
-        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 && !keyBlob.isFallback()) {
-                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;
+        return mKeyStore->del(filename.string(), ::TYPE_KEY_PAIR, targetUid);
     }
 
     int32_t grant(const String16& name, int32_t granteeUid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_GRANT)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_GRANT, spid)) {
             ALOGW("permission denied for %d: grant", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -2119,7 +2207,8 @@
 
     int32_t ungrant(const String16& name, int32_t granteeUid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_GRANT)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_GRANT, spid)) {
             ALOGW("permission denied for %d: ungrant", callingUid);
             return ::PERMISSION_DENIED;
         }
@@ -2142,7 +2231,8 @@
 
     int64_t getmtime(const String16& name) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_GET)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_GET, spid)) {
             ALOGW("permission denied for %d: getmtime", callingUid);
             return -1L;
         }
@@ -2175,7 +2265,8 @@
     int32_t duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
             int32_t destUid) {
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_DUPLICATE)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_DUPLICATE, spid)) {
             ALOGW("permission denied for %d: duplicate", callingUid);
             return -1L;
         }
@@ -2238,20 +2329,16 @@
     int32_t clear_uid(int64_t targetUid64) {
         uid_t targetUid = static_cast<uid_t>(targetUid64);
         uid_t callingUid = IPCThreadState::self()->getCallingUid();
-        if (!has_permission(callingUid, P_CLEAR_UID)) {
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_CLEAR_UID, spid)) {
             ALOGW("permission denied for %d: clear_uid", callingUid);
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState(callingUid);
-        if (!isKeystoreUnlocked(state)) {
-            ALOGD("calling clear_uid in state: %d", state);
-            return state;
-        }
-
         if (targetUid64 == -1) {
             targetUid = callingUid;
-        } else if (!is_granted_to(callingUid, targetUid)) {
+        } else if (!is_self_or_system(callingUid, targetUid)) {
+            ALOGW("permission denied for %d: clear_uid %d", callingUid, targetUid);
             return ::PERMISSION_DENIED;
         }
 
@@ -2261,60 +2348,84 @@
             return ::SYSTEM_ERROR;
         }
 
-        UserState* userState = mKeyStore->getUserState(targetUid);
-        DIR* dir = opendir(userState->getUserDirName());
-        if (!dir) {
-            ALOGW("can't open user directory: %s", strerror(errno));
+        String8 prefix = String8::format("%u_", targetUid);
+        Vector<String16> aliases;
+        if (mKeyStore->saw(prefix, &aliases, targetUid) != ::NO_ERROR) {
             return ::SYSTEM_ERROR;
         }
 
-        char prefix[NAME_MAX];
-        int n = snprintf(prefix, NAME_MAX, "%u_", targetUid);
+        for (uint32_t i = 0; i < aliases.size(); i++) {
+            String8 name8(aliases[i]);
+            String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
+            mKeyStore->del(filename.string(), ::TYPE_ANY, targetUid);
+        }
+        return ::NO_ERROR;
+    }
 
-        ResponseCode rc = ::NO_ERROR;
+    int32_t reset_uid(int32_t targetUid) {
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
+        pid_t spid = IPCThreadState::self()->getCallingPid();
 
-        struct dirent* file;
-        while ((file = readdir(dir)) != NULL) {
-            // We only care about files.
-            if (file->d_type != DT_REG) {
-                continue;
+        if (!has_permission(callingUid, P_RESET_UID, spid)) {
+            ALOGW("permission denied for %d: reset_uid %d", callingUid, targetUid);
+            return ::PERMISSION_DENIED;
+        }
+        if (!is_self_or_system(callingUid, targetUid)) {
+            ALOGW("permission denied for %d: reset_uid %d", callingUid, targetUid);
+            return ::PERMISSION_DENIED;
+        }
+
+        return mKeyStore->reset(targetUid) ? ::NO_ERROR : ::SYSTEM_ERROR;
+    }
+
+    int32_t sync_uid(int32_t sourceUid, int32_t targetUid) {
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_SYNC_UID, spid)) {
+            ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid);
+            return ::PERMISSION_DENIED;
+        }
+        if (callingUid != AID_SYSTEM) {
+            ALOGW("permission denied for %d: sync_uid %d -> %d", callingUid, sourceUid, targetUid);
+            return ::PERMISSION_DENIED;
+        }
+        if (sourceUid == targetUid) {
+            return ::SYSTEM_ERROR;
+        }
+
+        // Initialise user keystore with existing master key held in-memory
+        return mKeyStore->copyMasterKey(sourceUid, targetUid);
+    }
+
+    int32_t password_uid(const String16& pw, int32_t targetUid) {
+        uid_t callingUid = IPCThreadState::self()->getCallingUid();
+        pid_t spid = IPCThreadState::self()->getCallingPid();
+        if (!has_permission(callingUid, P_PASSWORD_UID, spid)) {
+            ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid);
+            return ::PERMISSION_DENIED;
+        }
+        if (callingUid != AID_SYSTEM) {
+            ALOGW("permission denied for %d: password_uid %d", callingUid, targetUid);
+            return ::PERMISSION_DENIED;
+        }
+
+        const String8 password8(pw);
+
+        switch (mKeyStore->getState(targetUid)) {
+            case ::STATE_UNINITIALIZED: {
+                // generate master key, encrypt with password, write to file, initialize mMasterKey*.
+                return mKeyStore->initializeUser(password8, targetUid);
             }
-
-            // Skip anything that starts with a "."
-            if (file->d_name[0] == '.') {
-                continue;
+            case ::STATE_NO_ERROR: {
+                // rewrite master key with new password.
+                return mKeyStore->writeMasterKey(password8, targetUid);
             }
-
-            if (strncmp(prefix, file->d_name, n)) {
-                continue;
-            }
-
-            String8 filename(String8::format("%s/%s", userState->getUserDirName(), file->d_name));
-            Blob keyBlob;
-            if (mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, targetUid)
-                    != ::NO_ERROR) {
-                ALOGW("couldn't open %s", filename.string());
-                continue;
-            }
-
-            if (keyBlob.getType() == ::TYPE_KEY_PAIR) {
-                // A device doesn't have to implement delete_keypair.
-                if (device->delete_keypair != NULL && !keyBlob.isFallback()) {
-                    if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) {
-                        rc = ::SYSTEM_ERROR;
-                        ALOGW("device couldn't remove %s", filename.string());
-                    }
-                }
-            }
-
-            if (unlinkat(dirfd(dir), file->d_name, 0) && errno != ENOENT) {
-                rc = ::SYSTEM_ERROR;
-                ALOGW("couldn't unlink %s", filename.string());
+            case ::STATE_LOCKED: {
+                // read master key, decrypt with password, initialize mMasterKey*.
+                return mKeyStore->readMasterKey(password8, targetUid);
             }
         }
-        closedir(dir);
-
-        return rc;
+        return ::SYSTEM_ERROR;
     }
 
 private:
@@ -2329,6 +2440,33 @@
         return false;
     }
 
+    bool isKeyTypeSupported(const keymaster_device_t* device, keymaster_keypair_t keyType) {
+        const int32_t device_api = device->common.module->module_api_version;
+        if (device_api == KEYMASTER_MODULE_API_VERSION_0_2) {
+            switch (keyType) {
+                case TYPE_RSA:
+                case TYPE_DSA:
+                case TYPE_EC:
+                    return true;
+                default:
+                    return false;
+            }
+        } else if (device_api >= KEYMASTER_MODULE_API_VERSION_0_3) {
+            switch (keyType) {
+                case TYPE_RSA:
+                    return true;
+                case TYPE_DSA:
+                    return device->flags & KEYMASTER_SUPPORTS_DSA;
+                case TYPE_EC:
+                    return device->flags & KEYMASTER_SUPPORTS_EC;
+                default:
+                    return false;
+            }
+        } else {
+            return keyType == TYPE_RSA;
+        }
+    }
+
     ::KeyStore* mKeyStore;
 };
 
@@ -2355,6 +2493,19 @@
         return 1;
     }
 
+    ks_is_selinux_enabled = is_selinux_enabled();
+    if (ks_is_selinux_enabled) {
+        union selinux_callback cb;
+        cb.func_log = selinux_log_callback;
+        selinux_set_callback(SELINUX_CB_LOG, cb);
+        if (getcon(&tctx) != 0) {
+            ALOGE("SELinux: Could not acquire target context. Aborting keystore.\n");
+            return -1;
+        }
+    } else {
+        ALOGI("SELinux: Keystore SELinux is disabled.\n");
+    }
+
     KeyStore keyStore(&entropy, dev);
     keyStore.initialize();
     android::sp<android::IServiceManager> sm = android::defaultServiceManager();
diff --git a/softkeymaster/Android.mk b/softkeymaster/Android.mk
index 7eee9c5..0c733aa 100644
--- a/softkeymaster/Android.mk
+++ b/softkeymaster/Android.mk
@@ -15,6 +15,9 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
+ifeq ($(USE_32_BIT_KEYSTORE), true)
+LOCAL_MULTILIB := 32
+endif
 LOCAL_MODULE := keystore.default
 LOCAL_MODULE_RELATIVE_PATH := hw
 LOCAL_SRC_FILES := module.cpp
@@ -28,6 +31,9 @@
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
+ifeq ($(USE_32_BIT_KEYSTORE), true)
+LOCAL_MULTILIB := 32
+endif
 LOCAL_MODULE := libsoftkeymaster
 LOCAL_SRC_FILES := keymaster_openssl.cpp
 LOCAL_C_INCLUDES := \
diff --git a/softkeymaster/include/keymaster/softkeymaster.h b/softkeymaster/include/keymaster/softkeymaster.h
index 7d43099..f304aed 100644
--- a/softkeymaster/include/keymaster/softkeymaster.h
+++ b/softkeymaster/include/keymaster/softkeymaster.h
@@ -16,31 +16,26 @@
 
 #include <hardware/keymaster.h>
 
-#ifndef SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H
-#define SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H
+#ifndef SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H_
+#define SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H_
 
-int openssl_generate_keypair(const keymaster_device_t* dev,
-        const keymaster_keypair_t key_type, const void* key_params,
-        uint8_t** keyBlob, size_t* keyBlobLength);
+int openssl_generate_keypair(const keymaster_device_t* dev, const keymaster_keypair_t key_type,
+                             const void* key_params, uint8_t** keyBlob, size_t* keyBlobLength);
 
-int openssl_import_keypair(const keymaster_device_t* dev,
-        const uint8_t* key, const size_t key_length,
-        uint8_t** key_blob, size_t* key_blob_length);
+int openssl_import_keypair(const keymaster_device_t* dev, const uint8_t* key,
+                           const size_t key_length, uint8_t** key_blob, size_t* key_blob_length);
 
-int openssl_get_keypair_public(const struct keymaster_device* dev,
-        const uint8_t* key_blob, const size_t key_blob_length,
-        uint8_t** x509_data, size_t* x509_data_length);
+int openssl_get_keypair_public(const struct keymaster_device* dev, const uint8_t* key_blob,
+                               const size_t key_blob_length, uint8_t** x509_data,
+                               size_t* x509_data_length);
 
-int openssl_sign_data(const keymaster_device_t* dev,
-        const void* params,
-        const uint8_t* keyBlob, const size_t keyBlobLength,
-        const uint8_t* data, const size_t dataLength,
-        uint8_t** signedData, size_t* signedDataLength);
+int openssl_sign_data(const keymaster_device_t* dev, const void* params, const uint8_t* keyBlob,
+                      const size_t keyBlobLength, const uint8_t* data, const size_t dataLength,
+                      uint8_t** signedData, size_t* signedDataLength);
 
-int openssl_verify_data(const keymaster_device_t* dev,
-        const void* params,
-        const uint8_t* keyBlob, const size_t keyBlobLength,
-        const uint8_t* signedData, const size_t signedDataLength,
-        const uint8_t* signature, const size_t signatureLength);
+int openssl_verify_data(const keymaster_device_t* dev, const void* params, const uint8_t* keyBlob,
+                        const size_t keyBlobLength, const uint8_t* signedData,
+                        const size_t signedDataLength, const uint8_t* signature,
+                        const size_t signatureLength);
 
-#endif /* SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H */
+#endif  // SOFTKEYMASTER_INCLUDE_KEYMASTER_SOFTKEYMASTER_H_
diff --git a/softkeymaster/keymaster_openssl.cpp b/softkeymaster/keymaster_openssl.cpp
index 783148e..85ecc6e 100644
--- a/softkeymaster/keymaster_openssl.cpp
+++ b/softkeymaster/keymaster_openssl.cpp
@@ -31,7 +31,7 @@
 #include <UniquePtr.h>
 
 // For debugging
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
 
 #define LOG_TAG "OpenSSLKeyMaster"
 #include <cutils/log.h>
@@ -71,6 +71,13 @@
 };
 typedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
 
+struct EC_GROUP_Delete {
+    void operator()(EC_GROUP* p) const {
+        EC_GROUP_free(p);
+    }
+};
+typedef UniquePtr<EC_GROUP, EC_GROUP_Delete> Unique_EC_GROUP;
+
 struct RSA_Delete {
     void operator()(RSA* p) const {
         RSA_free(p);
@@ -78,16 +85,24 @@
 };
 typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
 
+struct Malloc_Free {
+    void operator()(void* p) const {
+        free(p);
+    }
+};
+
 typedef UniquePtr<keymaster_device_t> Unique_keymaster_device_t;
 
 /**
- * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
- * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
- * without triggering a warning by not using the result of release().
+ * Many OpenSSL APIs take ownership of an argument on success but
+ * don't free the argument on failure. This means we need to tell our
+ * scoped pointers when we've transferred ownership, without
+ * triggering a warning by not using the result of release().
  */
-#define OWNERSHIP_TRANSFERRED(obj) \
-    typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
-
+template <typename T, typename Delete_T>
+inline void release_because_ownership_transferred(UniquePtr<T, Delete_T>& p) {
+    T* val __attribute__((unused)) = p.release();
+}
 
 /*
  * Checks this thread's OpenSSL error queue and logs if
@@ -108,8 +123,8 @@
 
 static int wrap_key(EVP_PKEY* pkey, int type, uint8_t** keyBlob, size_t* keyBlobLength) {
     /*
-     *  Find the length of each size. Public key is not needed anymore but must be kept for
-     * alignment purposes.
+     * Find the length of each size. Public key is not needed anymore
+     * but must be kept for alignment purposes.
      */
     int publicLen = 0;
     int privateLen = i2d_PrivateKey(pkey, NULL);
@@ -120,10 +135,12 @@
     }
 
     /* int type + int size + private key data + int size + public key data */
-    *keyBlobLength = get_softkey_header_size() + sizeof(int) + sizeof(int) + privateLen
-            + sizeof(int) + publicLen;
+    *keyBlobLength = get_softkey_header_size() + sizeof(type) + sizeof(publicLen) + privateLen +
+                     sizeof(privateLen) + publicLen;
 
-    UniquePtr<unsigned char> derData(new unsigned char[*keyBlobLength]);
+    // derData will be returned to the caller, so allocate it with malloc.
+    UniquePtr<unsigned char, Malloc_Free> derData(
+        static_cast<unsigned char*>(malloc(*keyBlobLength)));
     if (derData.get() == NULL) {
         ALOGE("could not allocate memory for key blob");
         return -1;
@@ -134,18 +151,18 @@
     p = add_softkey_header(p, *keyBlobLength);
 
     /* Write key type to allocated buffer */
-    for (int i = sizeof(int) - 1; i >= 0; i--) {
-        *p++ = (type >> (8*i)) & 0xFF;
+    for (int i = sizeof(type) - 1; i >= 0; i--) {
+        *p++ = (type >> (8 * i)) & 0xFF;
     }
 
     /* Write public key to allocated buffer */
-    for (int i = sizeof(int) - 1; i >= 0; i--) {
-        *p++ = (publicLen >> (8*i)) & 0xFF;
+    for (int i = sizeof(publicLen) - 1; i >= 0; i--) {
+        *p++ = (publicLen >> (8 * i)) & 0xFF;
     }
 
     /* Write private key to allocated buffer */
-    for (int i = sizeof(int) - 1; i >= 0; i--) {
-        *p++ = (privateLen >> (8*i)) & 0xFF;
+    for (int i = sizeof(privateLen) - 1; i >= 0; i--) {
+        *p++ = (privateLen >> (8 * i)) & 0xFF;
     }
     if (i2d_PrivateKey(pkey, &p) != privateLen) {
         logOpenSSLError("wrap_key");
@@ -161,17 +178,16 @@
     long publicLen = 0;
     long privateLen = 0;
     const uint8_t* p = keyBlob;
-    const uint8_t *const end = keyBlob + keyBlobLength;
+    const uint8_t* const end = keyBlob + keyBlobLength;
 
     if (keyBlob == NULL) {
         ALOGE("supplied key blob was NULL");
         return NULL;
     }
 
-    // Should be large enough for:
-    // int32 magic, int32 type, int32 pubLen, char* pub, int32 privLen, char* priv
-    if (keyBlobLength < (get_softkey_header_size() + sizeof(int) + sizeof(int) + 1
-            + sizeof(int) + 1)) {
+    int type = 0;
+    if (keyBlobLength < (get_softkey_header_size() + sizeof(type) + sizeof(publicLen) + 1 +
+                         sizeof(privateLen) + 1)) {
         ALOGE("key blob appears to be truncated");
         return NULL;
     }
@@ -182,12 +198,11 @@
     }
     p += get_softkey_header_size();
 
-    int type = 0;
-    for (size_t i = 0; i < sizeof(int); i++) {
+    for (size_t i = 0; i < sizeof(type); i++) {
         type = (type << 8) | *p++;
     }
 
-    for (size_t i = 0; i < sizeof(int); i++) {
+    for (size_t i = 0; i < sizeof(type); i++) {
         publicLen = (publicLen << 8) | *p++;
     }
     if (p + publicLen > end) {
@@ -200,7 +215,7 @@
         ALOGE("private key truncated");
         return NULL;
     }
-    for (size_t i = 0; i < sizeof(int); i++) {
+    for (size_t i = 0; i < sizeof(type); i++) {
         privateLen = (privateLen << 8) | *p++;
     }
     if (p + privateLen > end) {
@@ -223,8 +238,7 @@
     return pkey.release();
 }
 
-static int generate_dsa_keypair(EVP_PKEY* pkey, const keymaster_dsa_keygen_params_t* dsa_params)
-{
+static int generate_dsa_keypair(EVP_PKEY* pkey, const keymaster_dsa_keygen_params_t* dsa_params) {
     if (dsa_params->key_size < 512) {
         ALOGI("Requested DSA key size is too small (<512)");
         return -1;
@@ -232,37 +246,28 @@
 
     Unique_DSA dsa(DSA_new());
 
-    if (dsa_params->generator_len == 0 ||
-            dsa_params->prime_p_len == 0 ||
-            dsa_params->prime_q_len == 0 ||
-            dsa_params->generator == NULL||
-            dsa_params->prime_p == NULL ||
-            dsa_params->prime_q == NULL) {
+    if (dsa_params->generator_len == 0 || dsa_params->prime_p_len == 0 ||
+        dsa_params->prime_q_len == 0 || dsa_params->generator == NULL ||
+        dsa_params->prime_p == NULL || dsa_params->prime_q == NULL) {
         if (DSA_generate_parameters_ex(dsa.get(), dsa_params->key_size, NULL, 0, NULL, NULL,
-                NULL) != 1) {
+                                       NULL) != 1) {
             logOpenSSLError("generate_dsa_keypair");
             return -1;
         }
     } else {
-        dsa->g = BN_bin2bn(dsa_params->generator,
-                dsa_params->generator_len,
-                NULL);
+        dsa->g = BN_bin2bn(dsa_params->generator, dsa_params->generator_len, NULL);
         if (dsa->g == NULL) {
             logOpenSSLError("generate_dsa_keypair");
             return -1;
         }
 
-        dsa->p = BN_bin2bn(dsa_params->prime_p,
-                   dsa_params->prime_p_len,
-                   NULL);
+        dsa->p = BN_bin2bn(dsa_params->prime_p, dsa_params->prime_p_len, NULL);
         if (dsa->p == NULL) {
             logOpenSSLError("generate_dsa_keypair");
             return -1;
         }
 
-        dsa->q = BN_bin2bn(dsa_params->prime_q,
-                   dsa_params->prime_q_len,
-                   NULL);
+        dsa->q = BN_bin2bn(dsa_params->prime_q, dsa_params->prime_q_len, NULL);
         if (dsa->q == NULL) {
             logOpenSSLError("generate_dsa_keypair");
             return -1;
@@ -278,42 +283,40 @@
         logOpenSSLError("generate_dsa_keypair");
         return -1;
     }
-    OWNERSHIP_TRANSFERRED(dsa);
+    release_because_ownership_transferred(dsa);
 
     return 0;
 }
 
-static int generate_ec_keypair(EVP_PKEY* pkey, const keymaster_ec_keygen_params_t* ec_params)
-{
-    EC_GROUP* group;
+static int generate_ec_keypair(EVP_PKEY* pkey, const keymaster_ec_keygen_params_t* ec_params) {
+    Unique_EC_GROUP group;
     switch (ec_params->field_size) {
     case 192:
-        group = EC_GROUP_new_by_curve_name(NID_X9_62_prime192v1);
+        group.reset(EC_GROUP_new_by_curve_name(NID_X9_62_prime192v1));
         break;
     case 224:
-        group = EC_GROUP_new_by_curve_name(NID_secp224r1);
+        group.reset(EC_GROUP_new_by_curve_name(NID_secp224r1));
         break;
     case 256:
-        group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
+        group.reset(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
         break;
     case 384:
-        group = EC_GROUP_new_by_curve_name(NID_secp384r1);
+        group.reset(EC_GROUP_new_by_curve_name(NID_secp384r1));
         break;
     case 521:
-        group = EC_GROUP_new_by_curve_name(NID_secp521r1);
+        group.reset(EC_GROUP_new_by_curve_name(NID_secp521r1));
         break;
     default:
-        group = NULL;
         break;
     }
 
-    if (group == NULL) {
+    if (group.get() == NULL) {
         logOpenSSLError("generate_ec_keypair");
         return -1;
     }
 
-    EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
-    EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+    EC_GROUP_set_point_conversion_form(group.get(), POINT_CONVERSION_UNCOMPRESSED);
+    EC_GROUP_set_asn1_flag(group.get(), OPENSSL_EC_NAMED_CURVE);
 
     /* initialize EC key */
     Unique_EC_KEY eckey(EC_KEY_new());
@@ -322,13 +325,12 @@
         return -1;
     }
 
-    if (EC_KEY_set_group(eckey.get(), group) != 1) {
+    if (EC_KEY_set_group(eckey.get(), group.get()) != 1) {
         logOpenSSLError("generate_ec_keypair");
         return -1;
     }
 
-    if (EC_KEY_generate_key(eckey.get()) != 1
-            || EC_KEY_check_key(eckey.get()) < 0) {
+    if (EC_KEY_generate_key(eckey.get()) != 1 || EC_KEY_check_key(eckey.get()) < 0) {
         logOpenSSLError("generate_ec_keypair");
         return -1;
     }
@@ -337,13 +339,12 @@
         logOpenSSLError("generate_ec_keypair");
         return -1;
     }
-    OWNERSHIP_TRANSFERRED(eckey);
+    release_because_ownership_transferred(eckey);
 
     return 0;
 }
 
-static int generate_rsa_keypair(EVP_PKEY* pkey, const keymaster_rsa_keygen_params_t* rsa_params)
-{
+static int generate_rsa_keypair(EVP_PKEY* pkey, const keymaster_rsa_keygen_params_t* rsa_params) {
     Unique_BIGNUM bn(BN_new());
     if (bn.get() == NULL) {
         logOpenSSLError("generate_rsa_keypair");
@@ -362,8 +363,8 @@
         return -1;
     }
 
-    if (!RSA_generate_key_ex(rsa.get(), rsa_params->modulus_size, bn.get(), NULL)
-            || RSA_check_key(rsa.get()) < 0) {
+    if (!RSA_generate_key_ex(rsa.get(), rsa_params->modulus_size, bn.get(), NULL) ||
+        RSA_check_key(rsa.get()) < 0) {
         logOpenSSLError("generate_rsa_keypair");
         return -1;
     }
@@ -372,15 +373,14 @@
         logOpenSSLError("generate_rsa_keypair");
         return -1;
     }
-    OWNERSHIP_TRANSFERRED(rsa);
+    release_because_ownership_transferred(rsa);
 
     return 0;
 }
 
-__attribute__ ((visibility ("default")))
-int openssl_generate_keypair(const keymaster_device_t*,
-        const keymaster_keypair_t key_type, const void* key_params,
-        uint8_t** keyBlob, size_t* keyBlobLength) {
+__attribute__((visibility("default"))) int openssl_generate_keypair(
+    const keymaster_device_t*, const keymaster_keypair_t key_type, const void* key_params,
+    uint8_t** keyBlob, size_t* keyBlobLength) {
     Unique_EVP_PKEY pkey(EVP_PKEY_new());
     if (pkey.get() == NULL) {
         logOpenSSLError("openssl_generate_keypair");
@@ -392,15 +392,15 @@
         return -1;
     } else if (key_type == TYPE_DSA) {
         const keymaster_dsa_keygen_params_t* dsa_params =
-                (const keymaster_dsa_keygen_params_t*) key_params;
+            (const keymaster_dsa_keygen_params_t*)key_params;
         generate_dsa_keypair(pkey.get(), dsa_params);
     } else if (key_type == TYPE_EC) {
         const keymaster_ec_keygen_params_t* ec_params =
-                (const keymaster_ec_keygen_params_t*) key_params;
+            (const keymaster_ec_keygen_params_t*)key_params;
         generate_ec_keypair(pkey.get(), ec_params);
     } else if (key_type == TYPE_RSA) {
         const keymaster_rsa_keygen_params_t* rsa_params =
-                (const keymaster_rsa_keygen_params_t*) key_params;
+            (const keymaster_rsa_keygen_params_t*)key_params;
         generate_rsa_keypair(pkey.get(), rsa_params);
     } else {
         ALOGW("Unsupported key type %d", key_type);
@@ -414,10 +414,11 @@
     return 0;
 }
 
-__attribute__ ((visibility ("default")))
-int openssl_import_keypair(const keymaster_device_t*,
-        const uint8_t* key, const size_t key_length,
-        uint8_t** key_blob, size_t* key_blob_length) {
+__attribute__((visibility("default"))) int openssl_import_keypair(const keymaster_device_t*,
+                                                                  const uint8_t* key,
+                                                                  const size_t key_length,
+                                                                  uint8_t** key_blob,
+                                                                  size_t* key_blob_length) {
     if (key == NULL) {
         ALOGW("input key == NULL");
         return -1;
@@ -438,7 +439,7 @@
         logOpenSSLError("openssl_import_keypair");
         return -1;
     }
-    OWNERSHIP_TRANSFERRED(pkcs8);
+    release_because_ownership_transferred(pkcs8);
 
     if (wrap_key(pkey.get(), EVP_PKEY_type(pkey->type), key_blob, key_blob_length)) {
         return -1;
@@ -447,10 +448,9 @@
     return 0;
 }
 
-__attribute__ ((visibility ("default")))
-int openssl_get_keypair_public(const struct keymaster_device*,
-        const uint8_t* key_blob, const size_t key_blob_length,
-        uint8_t** x509_data, size_t* x509_data_length) {
+__attribute__((visibility("default"))) int openssl_get_keypair_public(
+    const struct keymaster_device*, const uint8_t* key_blob, const size_t key_blob_length,
+    uint8_t** x509_data, size_t* x509_data_length) {
 
     if (x509_data == NULL || x509_data_length == NULL) {
         ALOGW("output public key buffer == NULL");
@@ -468,7 +468,7 @@
         return -1;
     }
 
-    UniquePtr<uint8_t> key(static_cast<uint8_t*>(malloc(len)));
+    UniquePtr<uint8_t, Malloc_Free> key(static_cast<uint8_t*>(malloc(len)));
     if (key.get() == NULL) {
         ALOGE("Could not allocate memory for public key data");
         return -1;
@@ -488,7 +488,7 @@
 }
 
 static int sign_dsa(EVP_PKEY* pkey, keymaster_dsa_sign_params_t* sign_params, const uint8_t* data,
-        const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
+                    const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
     if (sign_params->digest_type != DIGEST_NONE) {
         ALOGW("Cannot handle digest type %d", sign_params->digest_type);
         return -1;
@@ -501,7 +501,7 @@
     }
 
     unsigned int dsaSize = DSA_size(dsa.get());
-    UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dsaSize)));
+    UniquePtr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dsaSize)));
     if (signedDataPtr.get() == NULL) {
         logOpenSSLError("openssl_sign_dsa");
         return -1;
@@ -520,7 +520,7 @@
 }
 
 static int sign_ec(EVP_PKEY* pkey, keymaster_ec_sign_params_t* sign_params, const uint8_t* data,
-        const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
+                   const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
     if (sign_params->digest_type != DIGEST_NONE) {
         ALOGW("Cannot handle digest type %d", sign_params->digest_type);
         return -1;
@@ -533,7 +533,7 @@
     }
 
     unsigned int ecdsaSize = ECDSA_size(eckey.get());
-    UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(ecdsaSize)));
+    UniquePtr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(ecdsaSize)));
     if (signedDataPtr.get() == NULL) {
         logOpenSSLError("openssl_sign_ec");
         return -1;
@@ -551,9 +551,8 @@
     return 0;
 }
 
-
 static int sign_rsa(EVP_PKEY* pkey, keymaster_rsa_sign_params_t* sign_params, const uint8_t* data,
-        const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
+                    const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
     if (sign_params->digest_type != DIGEST_NONE) {
         ALOGW("Cannot handle digest type %d", sign_params->digest_type);
         return -1;
@@ -568,7 +567,7 @@
         return -1;
     }
 
-    UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dataLength)));
+    UniquePtr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dataLength)));
     if (signedDataPtr.get() == NULL) {
         logOpenSSLError("openssl_sign_rsa");
         return -1;
@@ -586,12 +585,10 @@
     return 0;
 }
 
-__attribute__ ((visibility ("default")))
-int openssl_sign_data(const keymaster_device_t*,
-        const void* params,
-        const uint8_t* keyBlob, const size_t keyBlobLength,
-        const uint8_t* data, const size_t dataLength,
-        uint8_t** signedData, size_t* signedDataLength) {
+__attribute__((visibility("default"))) int openssl_sign_data(
+    const keymaster_device_t*, const void* params, const uint8_t* keyBlob,
+    const size_t keyBlobLength, const uint8_t* data, const size_t dataLength, uint8_t** signedData,
+    size_t* signedDataLength) {
     if (data == NULL) {
         ALOGW("input data to sign == NULL");
         return -1;
@@ -607,14 +604,20 @@
 
     int type = EVP_PKEY_type(pkey->type);
     if (type == EVP_PKEY_DSA) {
-        keymaster_dsa_sign_params_t* sign_params = (keymaster_dsa_sign_params_t*) params;
-        return sign_dsa(pkey.get(), sign_params, data, dataLength, signedData, signedDataLength);
+        const keymaster_dsa_sign_params_t* sign_params =
+            reinterpret_cast<const keymaster_dsa_sign_params_t*>(params);
+        return sign_dsa(pkey.get(), const_cast<keymaster_dsa_sign_params_t*>(sign_params), data,
+                        dataLength, signedData, signedDataLength);
     } else if (type == EVP_PKEY_EC) {
-        keymaster_ec_sign_params_t* sign_params = (keymaster_ec_sign_params_t*) params;
-        return sign_ec(pkey.get(), sign_params, data, dataLength, signedData, signedDataLength);
+        const keymaster_ec_sign_params_t* sign_params =
+            reinterpret_cast<const keymaster_ec_sign_params_t*>(params);
+        return sign_ec(pkey.get(), const_cast<keymaster_ec_sign_params_t*>(sign_params), data,
+                       dataLength, signedData, signedDataLength);
     } else if (type == EVP_PKEY_RSA) {
-        keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params;
-        return sign_rsa(pkey.get(), sign_params, data, dataLength, signedData, signedDataLength);
+        const keymaster_rsa_sign_params_t* sign_params =
+            reinterpret_cast<const keymaster_rsa_sign_params_t*>(params);
+        return sign_rsa(pkey.get(), const_cast<keymaster_rsa_sign_params_t*>(sign_params), data,
+                        dataLength, signedData, signedDataLength);
     } else {
         ALOGW("Unsupported key type");
         return -1;
@@ -622,8 +625,8 @@
 }
 
 static int verify_dsa(EVP_PKEY* pkey, keymaster_dsa_sign_params_t* sign_params,
-        const uint8_t* signedData, const size_t signedDataLength, const uint8_t* signature,
-        const size_t signatureLength) {
+                      const uint8_t* signedData, const size_t signedDataLength,
+                      const uint8_t* signature, const size_t signatureLength) {
     if (sign_params->digest_type != DIGEST_NONE) {
         ALOGW("Cannot handle digest type %d", sign_params->digest_type);
         return -1;
@@ -644,8 +647,8 @@
 }
 
 static int verify_ec(EVP_PKEY* pkey, keymaster_ec_sign_params_t* sign_params,
-        const uint8_t* signedData, const size_t signedDataLength, const uint8_t* signature,
-        const size_t signatureLength) {
+                     const uint8_t* signedData, const size_t signedDataLength,
+                     const uint8_t* signature, const size_t signatureLength) {
     if (sign_params->digest_type != DIGEST_NONE) {
         ALOGW("Cannot handle digest type %d", sign_params->digest_type);
         return -1;
@@ -657,7 +660,8 @@
         return -1;
     }
 
-    if (ECDSA_verify(0, signedData, signedDataLength, signature, signatureLength, eckey.get()) <= 0) {
+    if (ECDSA_verify(0, signedData, signedDataLength, signature, signatureLength, eckey.get()) <=
+        0) {
         logOpenSSLError("openssl_verify_ec");
         return -1;
     }
@@ -666,8 +670,8 @@
 }
 
 static int verify_rsa(EVP_PKEY* pkey, keymaster_rsa_sign_params_t* sign_params,
-        const uint8_t* signedData, const size_t signedDataLength, const uint8_t* signature,
-        const size_t signatureLength) {
+                      const uint8_t* signedData, const size_t signedDataLength,
+                      const uint8_t* signature, const size_t signatureLength) {
     if (sign_params->digest_type != DIGEST_NONE) {
         ALOGW("Cannot handle digest type %d", sign_params->digest_type);
         return -1;
@@ -685,7 +689,7 @@
         return -1;
     }
 
-    UniquePtr<uint8_t> dataPtr(reinterpret_cast<uint8_t*>(malloc(signedDataLength)));
+    UniquePtr<uint8_t[]> dataPtr(new uint8_t[signedDataLength]);
     if (dataPtr.get() == NULL) {
         logOpenSSLError("openssl_verify_data");
         return -1;
@@ -705,12 +709,10 @@
     return result == 0 ? 0 : -1;
 }
 
-__attribute__ ((visibility ("default")))
-int openssl_verify_data(const keymaster_device_t*,
-        const void* params,
-        const uint8_t* keyBlob, const size_t keyBlobLength,
-        const uint8_t* signedData, const size_t signedDataLength,
-        const uint8_t* signature, const size_t signatureLength) {
+__attribute__((visibility("default"))) int openssl_verify_data(
+    const keymaster_device_t*, const void* params, const uint8_t* keyBlob,
+    const size_t keyBlobLength, const uint8_t* signedData, const size_t signedDataLength,
+    const uint8_t* signature, const size_t signatureLength) {
 
     if (signedData == NULL || signature == NULL) {
         ALOGW("data or signature buffers == NULL");
@@ -724,17 +726,20 @@
 
     int type = EVP_PKEY_type(pkey->type);
     if (type == EVP_PKEY_DSA) {
-        keymaster_dsa_sign_params_t* sign_params = (keymaster_dsa_sign_params_t*) params;
-        return verify_dsa(pkey.get(), sign_params, signedData, signedDataLength, signature,
-                signatureLength);
+        const keymaster_dsa_sign_params_t* sign_params =
+            reinterpret_cast<const keymaster_dsa_sign_params_t*>(params);
+        return verify_dsa(pkey.get(), const_cast<keymaster_dsa_sign_params_t*>(sign_params),
+                          signedData, signedDataLength, signature, signatureLength);
     } else if (type == EVP_PKEY_RSA) {
-        keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params;
-        return verify_rsa(pkey.get(), sign_params, signedData, signedDataLength, signature,
-                signatureLength);
+        const keymaster_rsa_sign_params_t* sign_params =
+            reinterpret_cast<const keymaster_rsa_sign_params_t*>(params);
+        return verify_rsa(pkey.get(), const_cast<keymaster_rsa_sign_params_t*>(sign_params),
+                          signedData, signedDataLength, signature, signatureLength);
     } else if (type == EVP_PKEY_EC) {
-        keymaster_ec_sign_params_t* sign_params = (keymaster_ec_sign_params_t*) params;
-        return verify_ec(pkey.get(), sign_params, signedData, signedDataLength, signature,
-                signatureLength);
+        const keymaster_ec_sign_params_t* sign_params =
+            reinterpret_cast<const keymaster_ec_sign_params_t*>(params);
+        return verify_ec(pkey.get(), const_cast<keymaster_ec_sign_params_t*>(sign_params),
+                         signedData, signedDataLength, signature, signatureLength);
     } else {
         ALOGW("Unsupported key type %d", type);
         return -1;
diff --git a/softkeymaster/module.cpp b/softkeymaster/module.cpp
index cba3a79..bfb1dd5 100644
--- a/softkeymaster/module.cpp
+++ b/softkeymaster/module.cpp
@@ -29,7 +29,7 @@
 #include <UniquePtr.h>
 
 // For debugging
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
 
 #define LOG_TAG "OpenSSLKeyMaster"
 #include <cutils/log.h>
@@ -37,7 +37,7 @@
 typedef UniquePtr<keymaster_device_t> Unique_keymaster_device_t;
 
 /* Close an opened OpenSSL instance */
-static int openssl_close(hw_device_t *dev) {
+static int openssl_close(hw_device_t* dev) {
     delete dev;
     return 0;
 }
@@ -45,8 +45,7 @@
 /*
  * Generic device handling
  */
-static int openssl_open(const hw_module_t* module, const char* name,
-        hw_device_t** device) {
+static int openssl_open(const hw_module_t* module, const char* name, hw_device_t** device) {
     if (strcmp(name, KEYSTORE_KEYMASTER) != 0)
         return -EINVAL;
 
@@ -56,7 +55,7 @@
 
     dev->common.tag = HARDWARE_DEVICE_TAG;
     dev->common.version = 1;
-    dev->common.module = (struct hw_module_t*) module;
+    dev->common.module = (struct hw_module_t*)module;
     dev->common.close = openssl_close;
 
     dev->flags = KEYMASTER_SOFTWARE_ONLY;
@@ -81,8 +80,7 @@
     .open = openssl_open,
 };
 
-struct keystore_module HAL_MODULE_INFO_SYM
-__attribute__ ((visibility ("default"))) = {
+struct keystore_module HAL_MODULE_INFO_SYM __attribute__((visibility("default"))) = {
     .common = {
         .tag = HARDWARE_MODULE_TAG,
         .module_api_version = KEYMASTER_MODULE_API_VERSION_0_2,