diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 760ec4d..482e21b 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -24,6 +24,7 @@
 #include <signal.h>
 #include <errno.h>
 #include <dirent.h>
+#include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <assert.h>
@@ -41,9 +42,9 @@
 
 #include <hardware/keymaster.h>
 
+#include <utils/String8.h>
 #include <utils/UniquePtr.h>
-
-#include <cutils/list.h>
+#include <utils/Vector.h>
 
 #include <keystore/IKeystoreService.h>
 #include <binder/IPCThreadState.h>
@@ -162,7 +163,29 @@
 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);
 
+/**
+ * Returns the app ID (in the Android multi-user sense) for the current
+ * UNIX UID.
+ */
+static uid_t get_app_id(uid_t uid) {
+    return uid % AID_USER;
+}
+
+/**
+ * Returns the user ID (in the Android multi-user sense) for the current
+ * UNIX UID.
+ */
+static uid_t get_user_id(uid_t uid) {
+    return uid / AID_USER;
+}
+
+
 static bool has_permission(uid_t uid, perm_t perm) {
+    // All system users are equivalent for multi-user support.
+    if (get_app_id(uid) == AID_SYSTEM) {
+        uid = AID_SYSTEM;
+    }
+
     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) {
@@ -211,16 +234,27 @@
  * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
  * that Base64 cannot be used here due to the need of prefix match on keys. */
 
+static size_t encode_key_length(const android::String8& keyName) {
+    const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
+    size_t length = keyName.length();
+    for (int i = length; i > 0; --i, ++in) {
+        if (*in < '0' || *in > '~') {
+            ++length;
+        }
+    }
+    return length;
+}
+
 static int encode_key(char* out, const android::String8& keyName) {
     const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
     size_t length = keyName.length();
     for (int i = length; i > 0; --i, ++in, ++out) {
-        if (*in >= '0' && *in <= '~') {
-            *out = *in;
-        } else {
+        if (*in < '0' || *in > '~') {
             *out = '+' + (*in >> 6);
             *++out = '0' + (*in & 0x3F);
             ++length;
+        } else {
+            *out = *in;
         }
     }
     *out = '\0';
@@ -521,27 +555,50 @@
     struct blob mBlob;
 };
 
-typedef struct {
-    uint32_t uid;
-    const uint8_t* filename;
-
-    struct listnode plist;
-} grant_t;
-
-class KeyStore {
+class UserState {
 public:
-    KeyStore(Entropy* entropy, keymaster_device_t* device)
-        : mEntropy(entropy)
-        , mDevice(device)
-        , mRetry(MAX_RETRY)
-    {
-        if (access(MASTER_KEY_FILE, R_OK) == 0) {
+    UserState(uid_t userId) : mUserId(userId), mRetry(MAX_RETRY) {
+        asprintf(&mUserDir, "user_%u", mUserId);
+        asprintf(&mMasterKeyFile, "%s/.masterkey", mUserDir);
+    }
+
+    ~UserState() {
+        free(mUserDir);
+        free(mMasterKeyFile);
+    }
+
+    bool initialize() {
+        if ((mkdir(mUserDir, S_IRUSR | S_IWUSR | S_IXUSR) < 0) && (errno != EEXIST)) {
+            ALOGE("Could not create directory '%s'", mUserDir);
+            return false;
+        }
+
+        if (access(mMasterKeyFile, R_OK) == 0) {
             setState(STATE_LOCKED);
         } else {
             setState(STATE_UNINITIALIZED);
         }
 
-        list_init(&mGrants);
+        return true;
+    }
+
+    uid_t getUserId() const {
+        return mUserId;
+    }
+
+    const char* getUserDirName() const {
+        return mUserDir;
+    }
+
+    const char* getMasterKeyFileName() const {
+        return mMasterKeyFile;
+    }
+
+    void setState(State state) {
+        mState = state;
+        if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
+            mRetry = MAX_RETRY;
+        }
     }
 
     State getState() const {
@@ -552,15 +609,18 @@
         return mRetry;
     }
 
-    keymaster_device_t* getDevice() const {
-        return mDevice;
+    void zeroizeMasterKeysInMemory() {
+        memset(mMasterKey, 0, sizeof(mMasterKey));
+        memset(mSalt, 0, sizeof(mSalt));
+        memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
+        memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
     }
 
-    ResponseCode initialize(const android::String8& pw) {
-        if (!generateMasterKey()) {
+    ResponseCode initialize(const android::String8& pw, Entropy* entropy) {
+        if (!generateMasterKey(entropy)) {
             return SYSTEM_ERROR;
         }
-        ResponseCode response = writeMasterKey(pw);
+        ResponseCode response = writeMasterKey(pw, entropy);
         if (response != NO_ERROR) {
             return response;
         }
@@ -568,17 +628,17 @@
         return ::NO_ERROR;
     }
 
-    ResponseCode writeMasterKey(const android::String8& pw) {
+    ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy) {
         uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
         generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
         AES_KEY passwordAesKey;
         AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
         Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
-        return masterKeyBlob.encryptBlob(MASTER_KEY_FILE, &passwordAesKey, mEntropy);
+        return masterKeyBlob.encryptBlob(mMasterKeyFile, &passwordAesKey, entropy);
     }
 
-    ResponseCode readMasterKey(const android::String8& pw) {
-        int in = TEMP_FAILURE_RETRY(open(MASTER_KEY_FILE, O_RDONLY));
+    ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy) {
+        int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY));
         if (in < 0) {
             return SYSTEM_ERROR;
         }
@@ -602,17 +662,17 @@
         AES_KEY passwordAesKey;
         AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
         Blob masterKeyBlob(rawBlob);
-        ResponseCode response = masterKeyBlob.decryptBlob(MASTER_KEY_FILE, &passwordAesKey);
+        ResponseCode response = masterKeyBlob.decryptBlob(mMasterKeyFile, &passwordAesKey);
         if (response == SYSTEM_ERROR) {
             return SYSTEM_ERROR;
         }
         if (response == NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
             // if salt was missing, generate one and write a new master key file with the salt.
             if (salt == NULL) {
-                if (!generateSalt()) {
+                if (!generateSalt(entropy)) {
                     return SYSTEM_ERROR;
                 }
-                response = writeMasterKey(pw);
+                response = writeMasterKey(pw, entropy);
             }
             if (response == NO_ERROR) {
                 memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
@@ -634,32 +694,225 @@
         }
     }
 
+    AES_KEY* getEncryptionKey() {
+        return &mMasterKeyEncryption;
+    }
+
+    AES_KEY* getDecryptionKey() {
+        return &mMasterKeyDecryption;
+    }
+
     bool reset() {
-        clearMasterKeys();
-        setState(STATE_UNINITIALIZED);
-
-        DIR* dir = opendir(".");
-        struct dirent* file;
-
+        DIR* dir = opendir(getUserDirName());
         if (!dir) {
+            ALOGW("couldn't open user directory: %s", strerror(errno));
             return false;
         }
+
+        struct dirent* file;
         while ((file = readdir(dir)) != NULL) {
-            unlink(file->d_name);
+            // We only care about files.
+            if (file->d_type != DT_REG) {
+                continue;
+            }
+
+            // 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) {
+                continue;
+            }
+
+            unlinkat(dirfd(dir), file->d_name, 0);
         }
         closedir(dir);
         return true;
     }
 
-    bool isEmpty() const {
-        DIR* dir = opendir(".");
+private:
+    static const int MASTER_KEY_SIZE_BYTES = 16;
+    static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
+
+    static const int MAX_RETRY = 4;
+    static const size_t SALT_SIZE = 16;
+
+    void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw,
+            uint8_t* salt) {
+        size_t saltSize;
+        if (salt != NULL) {
+            saltSize = SALT_SIZE;
+        } else {
+            // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
+            salt = (uint8_t*) "keystore";
+            // sizeof = 9, not strlen = 8
+            saltSize = sizeof("keystore");
+        }
+
+        PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt,
+                saltSize, 8192, keySize, key);
+    }
+
+    bool generateSalt(Entropy* entropy) {
+        return entropy->generate_random_data(mSalt, sizeof(mSalt));
+    }
+
+    bool generateMasterKey(Entropy* entropy) {
+        if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
+            return false;
+        }
+        if (!generateSalt(entropy)) {
+            return false;
+        }
+        return true;
+    }
+
+    void setupMasterKeys() {
+        AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
+        AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
+        setState(STATE_NO_ERROR);
+    }
+
+    uid_t mUserId;
+
+    char* mUserDir;
+    char* mMasterKeyFile;
+
+    State mState;
+    int8_t mRetry;
+
+    uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
+    uint8_t mSalt[SALT_SIZE];
+
+    AES_KEY mMasterKeyEncryption;
+    AES_KEY mMasterKeyDecryption;
+};
+
+typedef struct {
+    uint32_t uid;
+    const uint8_t* filename;
+} grant_t;
+
+class KeyStore {
+public:
+    KeyStore(Entropy* entropy, keymaster_device_t* device)
+        : mEntropy(entropy)
+        , mDevice(device)
+    {
+        memset(&mMetaData, '\0', sizeof(mMetaData));
+    }
+
+    ~KeyStore() {
+        for (android::Vector<grant_t*>::iterator it(mGrants.begin());
+                it != mGrants.end(); it++) {
+            delete *it;
+            mGrants.erase(it);
+        }
+
+        for (android::Vector<UserState*>::iterator it(mMasterKeys.begin());
+                it != mMasterKeys.end(); it++) {
+            delete *it;
+            mMasterKeys.erase(it);
+        }
+    }
+
+    keymaster_device_t* getDevice() const {
+        return mDevice;
+    }
+
+    ResponseCode initialize() {
+        readMetaData();
+        if (upgradeKeystore()) {
+            writeMetaData();
+        }
+
+        return ::NO_ERROR;
+    }
+
+    State getState(uid_t uid) {
+        return getUserState(uid)->getState();
+    }
+
+    ResponseCode initializeUser(const android::String8& pw, uid_t uid) {
+        UserState* userState = getUserState(uid);
+        return userState->initialize(pw, mEntropy);
+    }
+
+    ResponseCode writeMasterKey(const android::String8& pw, uid_t uid) {
+        uid_t user_id = get_user_id(uid);
+        UserState* userState = getUserState(user_id);
+        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);
+        return userState->readMasterKey(pw, mEntropy);
+    }
+
+    android::String8 getKeyName(const android::String8& keyName) {
+        char encoded[encode_key_length(keyName)];
+        encode_key(encoded, keyName);
+        return android::String8(encoded);
+    }
+
+    android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid) {
+        char encoded[encode_key_length(keyName)];
+        encode_key(encoded, keyName);
+        return android::String8::format("%u_%s", uid, encoded);
+    }
+
+    android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) {
+        char encoded[encode_key_length(keyName)];
+        encode_key(encoded, keyName);
+        return android::String8::format("%s/%u_%s", getUserState(uid)->getUserDirName(), uid,
+                encoded);
+    }
+
+    bool reset(uid_t uid) {
+        UserState* userState = getUserState(uid);
+        userState->zeroizeMasterKeysInMemory();
+        userState->setState(STATE_UNINITIALIZED);
+        return userState->reset();
+    }
+
+    bool isEmpty(uid_t uid) const {
+        const UserState* userState = getUserState(uid);
+        if (userState == NULL) {
+            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);
+
         while ((file = readdir(dir)) != NULL) {
-            if (isKeyFile(file->d_name)) {
+            // 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(file->d_name, filename, n)) {
                 result = false;
                 break;
             }
@@ -668,13 +921,15 @@
         return result;
     }
 
-    void lock() {
-        clearMasterKeys();
-        setState(STATE_LOCKED);
+    void lock(uid_t uid) {
+        UserState* userState = getUserState(uid);
+        userState->zeroizeMasterKeysInMemory();
+        userState->setState(STATE_LOCKED);
     }
 
-    ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type) {
-        ResponseCode rc = keyBlob->decryptBlob(filename, &mMasterKeyDecryption);
+    ResponseCode get(const char* filename, Blob* keyBlob, const BlobType type, uid_t uid) {
+        UserState* userState = getUserState(uid);
+        ResponseCode rc = keyBlob->decryptBlob(filename, userState->getDecryptionKey());
         if (rc != NO_ERROR) {
             return rc;
         }
@@ -685,9 +940,10 @@
              * it must be read it again since the blob is encrypted each time
              * it's written.
              */
-            if (upgrade(filename, keyBlob, version, type)) {
-                if ((rc = this->put(filename, keyBlob)) != NO_ERROR
-                        || (rc = keyBlob->decryptBlob(filename, &mMasterKeyDecryption)) != NO_ERROR) {
+            if (upgradeBlob(filename, keyBlob, version, type, uid)) {
+                if ((rc = this->put(filename, keyBlob, uid)) != NO_ERROR
+                        || (rc = keyBlob->decryptBlob(filename, userState->getDecryptionKey()))
+                                != NO_ERROR) {
                     return rc;
                 }
             }
@@ -701,28 +957,31 @@
         return rc;
     }
 
-    ResponseCode put(const char* filename, Blob* keyBlob) {
-        return keyBlob->encryptBlob(filename, &mMasterKeyEncryption, mEntropy);
+    ResponseCode put(const char* filename, Blob* keyBlob, uid_t uid) {
+        UserState* userState = getUserState(uid);
+        return keyBlob->encryptBlob(filename, userState->getEncryptionKey(), mEntropy);
     }
 
     void addGrant(const char* filename, uid_t granteeUid) {
-        grant_t *grant = getGrant(filename, granteeUid);
-        if (grant == NULL) {
-            grant = new grant_t;
+        const grant_t* existing = getGrant(filename, granteeUid);
+        if (existing == NULL) {
+            grant_t* grant = new grant_t;
             grant->uid = granteeUid;
             grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename));
-            list_add_tail(&mGrants, &grant->plist);
+            mGrants.add(grant);
         }
     }
 
     bool removeGrant(const char* filename, uid_t granteeUid) {
-        grant_t *grant = getGrant(filename, granteeUid);
-        if (grant != NULL) {
-            list_remove(&grant->plist);
-            delete grant;
-            return true;
+        for (android::Vector<grant_t*>::iterator it(mGrants.begin());
+                it != mGrants.end(); it++) {
+            grant_t* grant = *it;
+            if (grant->uid == granteeUid
+                    && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) {
+                mGrants.erase(it);
+                return true;
+            }
         }
-
         return false;
     }
 
@@ -730,7 +989,7 @@
         return getGrant(filename, uid) != NULL;
     }
 
-    ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename) {
+    ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t uid) {
         uint8_t* data;
         size_t dataLength;
         int rc;
@@ -749,105 +1008,128 @@
         Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
         free(data);
 
-        return put(filename, &keyBlob);
+        return put(filename, &keyBlob, uid);
     }
 
     bool isHardwareBacked() const {
         return (mDevice->flags & KEYMASTER_SOFTWARE_ONLY) == 0;
     }
 
+    ResponseCode getKeyForName(Blob* keyBlob, const android::String8& keyName, const uid_t uid,
+            const BlobType type) {
+        char filename[NAME_MAX];
+        encode_key_for_uid(filename, uid, keyName);
+
+        UserState* userState = getUserState(uid);
+        android::String8 filepath8;
+
+        filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename);
+        if (filepath8.string() == NULL) {
+            ALOGW("can't create filepath for key %s", filename);
+            return SYSTEM_ERROR;
+        }
+
+        ResponseCode responseCode = get(filepath8.string(), keyBlob, type, uid);
+        if (responseCode == NO_ERROR) {
+            return responseCode;
+        }
+
+        // If this is one of the legacy UID->UID mappings, use it.
+        uid_t euid = get_keystore_euid(uid);
+        if (euid != uid) {
+            encode_key_for_uid(filename, euid, keyName);
+            filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename);
+            responseCode = get(filepath8.string(), keyBlob, type, uid);
+            if (responseCode == NO_ERROR) {
+                return responseCode;
+            }
+        }
+
+        // They might be using a granted key.
+        encode_key(filename, keyName);
+        char* end;
+        strtoul(filename, &end, 10);
+        if (end[0] != '_' || end[1] == 0) {
+            return KEY_NOT_FOUND;
+        }
+        filepath8 = android::String8::format("%s/%s", userState->getUserDirName(), filename);
+        if (!hasGrant(filepath8.string(), uid)) {
+            return responseCode;
+        }
+
+        // It is a granted key. Try to load it.
+        return get(filepath8.string(), keyBlob, type, uid);
+    }
+
+    /**
+     * Returns any existing UserState or creates it if it doesn't exist.
+     */
+    UserState* getUserState(uid_t uid) {
+        uid_t userId = get_user_id(uid);
+
+        for (android::Vector<UserState*>::iterator it(mMasterKeys.begin());
+                it != mMasterKeys.end(); it++) {
+            UserState* state = *it;
+            if (state->getUserId() == userId) {
+                return state;
+            }
+        }
+
+        UserState* userState = new UserState(userId);
+        if (!userState->initialize()) {
+            /* There's not much we can do if initialization fails. Trying to
+             * unlock the keystore for that user will fail as well, so any
+             * subsequent request for this user will just return SYSTEM_ERROR.
+             */
+            ALOGE("User initialization failed for %u; subsuquent operations will fail", userId);
+        }
+        mMasterKeys.add(userState);
+        return userState;
+    }
+
+    /**
+     * Returns NULL if the UserState doesn't already exist.
+     */
+    const UserState* getUserState(uid_t uid) const {
+        uid_t userId = get_user_id(uid);
+
+        for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin());
+                it != mMasterKeys.end(); it++) {
+            UserState* state = *it;
+            if (state->getUserId() == userId) {
+                return state;
+            }
+        }
+
+        return NULL;
+    }
+
 private:
-    static const char* MASTER_KEY_FILE;
-    static const int MASTER_KEY_SIZE_BYTES = 16;
-    static const int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8;
-
-    static const int MAX_RETRY = 4;
-    static const size_t SALT_SIZE = 16;
-
+    static const char* sOldMasterKey;
+    static const char* sMetaDataFile;
     Entropy* mEntropy;
 
     keymaster_device_t* mDevice;
 
-    State mState;
-    int8_t mRetry;
+    android::Vector<UserState*> mMasterKeys;
 
-    uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
-    uint8_t mSalt[SALT_SIZE];
+    android::Vector<grant_t*> mGrants;
 
-    AES_KEY mMasterKeyEncryption;
-    AES_KEY mMasterKeyDecryption;
+    typedef struct {
+        uint32_t version;
+    } keystore_metadata_t;
 
-    struct listnode mGrants;
+    keystore_metadata_t mMetaData;
 
-    void setState(State state) {
-        mState = state;
-        if (mState == STATE_NO_ERROR || mState == STATE_UNINITIALIZED) {
-            mRetry = MAX_RETRY;
-        }
-    }
-
-    bool generateSalt() {
-        return mEntropy->generate_random_data(mSalt, sizeof(mSalt));
-    }
-
-    bool generateMasterKey() {
-        if (!mEntropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
-            return false;
-        }
-        if (!generateSalt()) {
-            return false;
-        }
-        return true;
-    }
-
-    void setupMasterKeys() {
-        AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
-        AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
-        setState(STATE_NO_ERROR);
-    }
-
-    void clearMasterKeys() {
-        memset(mMasterKey, 0, sizeof(mMasterKey));
-        memset(mSalt, 0, sizeof(mSalt));
-        memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
-        memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
-    }
-
-    static void generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw,
-            uint8_t* salt) {
-        size_t saltSize;
-        if (salt != NULL) {
-            saltSize = SALT_SIZE;
-        } else {
-            // pre-gingerbread used this hardwired salt, readMasterKey will rewrite these when found
-            salt = (uint8_t*) "keystore";
-            // sizeof = 9, not strlen = 8
-            saltSize = sizeof("keystore");
-        }
-
-        PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt,
-                saltSize, 8192, keySize, key);
-    }
-
-    static bool isKeyFile(const char* filename) {
-        return ((strcmp(filename, MASTER_KEY_FILE) != 0)
-                && (strcmp(filename, ".") != 0)
-                && (strcmp(filename, "..") != 0));
-    }
-
-    grant_t* getGrant(const char* filename, uid_t uid) const {
-        struct listnode *node;
-        grant_t *grant;
-
-        list_for_each(node, &mGrants) {
-            grant = node_to_item(node, grant_t, plist);
+    const grant_t* getGrant(const char* filename, uid_t uid) const {
+        for (android::Vector<grant_t*>::const_iterator it(mGrants.begin());
+                it != mGrants.end(); it++) {
+            grant_t* grant = *it;
             if (grant->uid == uid
-                    && !strcmp(reinterpret_cast<const char*>(grant->filename),
-                               filename)) {
+                    && !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) {
                 return grant;
             }
         }
-
         return NULL;
     }
 
@@ -855,7 +1137,8 @@
      * Upgrade code. This will upgrade the key from the current version
      * to whatever is newest.
      */
-    bool upgrade(const char* filename, Blob* blob, const uint8_t oldVersion, const BlobType type) {
+    bool upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion,
+            const BlobType type, uid_t uid) {
         bool updated = false;
         uint8_t version = oldVersion;
 
@@ -865,7 +1148,7 @@
 
             blob->setType(type);
             if (type == TYPE_KEY_PAIR) {
-                importBlobAsKey(blob, filename);
+                importBlobAsKey(blob, filename, uid);
             }
             version = 1;
             updated = true;
@@ -889,7 +1172,7 @@
      * Then it overwrites the original blob with the new blob
      * format that is returned from the keymaster.
      */
-    ResponseCode importBlobAsKey(Blob* blob, const char* filename) {
+    ResponseCode importBlobAsKey(Blob* blob, const char* filename, uid_t uid) {
         // We won't even write to the blob directly with this BIO, so const_cast is okay.
         Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength()));
         if (b.get() == NULL) {
@@ -917,46 +1200,118 @@
             return SYSTEM_ERROR;
         }
 
-        ResponseCode rc = importKey(pkcs8key.get(), len, filename);
+        ResponseCode rc = importKey(pkcs8key.get(), len, filename, uid);
         if (rc != NO_ERROR) {
             return rc;
         }
 
-        return get(filename, blob, TYPE_KEY_PAIR);
+        return get(filename, blob, TYPE_KEY_PAIR, uid);
+    }
+
+    void readMetaData() {
+        int in = TEMP_FAILURE_RETRY(open(sMetaDataFile, O_RDONLY));
+        if (in < 0) {
+            return;
+        }
+        size_t fileLength = readFully(in, (uint8_t*) &mMetaData, sizeof(mMetaData));
+        if (fileLength != sizeof(mMetaData)) {
+            ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength,
+                    sizeof(mMetaData));
+        }
+        close(in);
+    }
+
+    void writeMetaData() {
+        const char* tmpFileName = ".metadata.tmp";
+        int out = TEMP_FAILURE_RETRY(open(tmpFileName,
+                O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
+        if (out < 0) {
+            ALOGE("couldn't write metadata file: %s", strerror(errno));
+            return;
+        }
+        size_t fileLength = writeFully(out, (uint8_t*) &mMetaData, sizeof(mMetaData));
+        if (fileLength != sizeof(mMetaData)) {
+            ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
+                    sizeof(mMetaData));
+        }
+        close(out);
+        rename(tmpFileName, sMetaDataFile);
+    }
+
+    bool upgradeKeystore() {
+        bool upgraded = false;
+
+        if (mMetaData.version == 0) {
+            UserState* userState = getUserState(0);
+
+            // Initialize first so the directory is made.
+            userState->initialize();
+
+            // Migrate the old .masterkey file to user 0.
+            if (access(sOldMasterKey, R_OK) == 0) {
+                if (rename(sOldMasterKey, userState->getMasterKeyFileName()) < 0) {
+                    ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
+                    return false;
+                }
+            }
+
+            // Initialize again in case we had a key.
+            userState->initialize();
+
+            // Try to migrate existing keys.
+            DIR* dir = opendir(".");
+            if (!dir) {
+                // Give up now; maybe we can upgrade later.
+                ALOGE("couldn't open keystore's directory; something is wrong");
+                return false;
+            }
+
+            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;
+                }
+
+                // Find the current file's user.
+                char* end;
+                unsigned long thisUid = strtoul(file->d_name, &end, 10);
+                if (end[0] != '_' || end[1] == 0) {
+                    continue;
+                }
+                UserState* otherUser = getUserState(thisUid);
+                if (otherUser->getUserId() != 0) {
+                    unlinkat(dirfd(dir), file->d_name, 0);
+                }
+
+                // Rename the file into user directory.
+                DIR* otherdir = opendir(otherUser->getUserDirName());
+                if (otherdir == NULL) {
+                    ALOGW("couldn't open user directory for rename");
+                    continue;
+                }
+                if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
+                    ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
+                }
+                closedir(otherdir);
+            }
+            closedir(dir);
+
+            mMetaData.version = 1;
+            upgraded = true;
+        }
+
+        return upgraded;
     }
 };
 
-const char* KeyStore::MASTER_KEY_FILE = ".masterkey";
-
-static ResponseCode get_key_for_name(KeyStore* keyStore, Blob* keyBlob,
-        const android::String8& keyName, const uid_t uid, const BlobType type) {
-    char filename[NAME_MAX];
-
-    encode_key_for_uid(filename, uid, keyName);
-    ResponseCode responseCode = keyStore->get(filename, keyBlob, type);
-    if (responseCode == NO_ERROR) {
-        return responseCode;
-    }
-
-    // If this is one of the legacy UID->UID mappings, use it.
-    uid_t euid = get_keystore_euid(uid);
-    if (euid != uid) {
-        encode_key_for_uid(filename, euid, keyName);
-        responseCode = keyStore->get(filename, keyBlob, type);
-        if (responseCode == NO_ERROR) {
-            return responseCode;
-        }
-    }
-
-    // They might be using a granted key.
-    encode_key(filename, keyName);
-    if (!keyStore->hasGrant(filename, uid)) {
-        return responseCode;
-    }
-
-    // It is a granted key. Try to load it.
-    return keyStore->get(filename, keyBlob, type);
-}
+const char* KeyStore::sOldMasterKey = ".masterkey";
+const char* KeyStore::sMetaDataFile = ".metadata";
 
 namespace android {
 class KeyStoreProxy : public BnKeystoreService, public IBinder::DeathRecipient {
@@ -977,7 +1332,7 @@
             return ::PERMISSION_DENIED;
         }
 
-        return mKeyStore->getState();
+        return mKeyStore->getState(callingUid);
     }
 
     int32_t get(const String16& name, uint8_t** item, size_t* itemLength) {
@@ -987,20 +1342,19 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (!isKeystoreUnlocked(state)) {
             ALOGD("calling get in state: %d", state);
             return state;
         }
 
         String8 name8(name);
-        char filename[NAME_MAX];
         Blob keyBlob;
 
-        ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid,
+        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
                 TYPE_GENERIC);
         if (responseCode != ::NO_ERROR) {
-            ALOGW("Could not read %s", filename);
+            ALOGW("Could not read %s", name8.string());
             *item = NULL;
             *itemLength = 0;
             return responseCode;
@@ -1026,19 +1380,17 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (!isKeystoreUnlocked(state)) {
             ALOGD("calling insert in state: %d", state);
             return state;
         }
 
         String8 name8(name);
-        char filename[NAME_MAX];
-
-        encode_key_for_uid(filename, targetUid, name8);
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
 
         Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC);
-        return mKeyStore->put(filename, &keyBlob);
+        return mKeyStore->put(filename.string(), &keyBlob, callingUid);
     }
 
     int32_t del(const String16& name, int targetUid) {
@@ -1055,12 +1407,11 @@
         }
 
         String8 name8(name);
-        char filename[NAME_MAX];
-
-        encode_key_for_uid(filename, targetUid, name8);
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
 
         Blob keyBlob;
-        ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, TYPE_GENERIC);
+        ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, TYPE_GENERIC,
+                callingUid);
         if (responseCode != ::NO_ERROR) {
             return responseCode;
         }
@@ -1081,11 +1432,9 @@
         }
 
         String8 name8(name);
-        char filename[NAME_MAX];
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
 
-        encode_key_for_uid(filename, targetUid, name8);
-
-        if (access(filename, R_OK) == -1) {
+        if (access(filename.string(), R_OK) == -1) {
             return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
         }
         return ::NO_ERROR;
@@ -1104,19 +1453,30 @@
             return ::PERMISSION_DENIED;
         }
 
-        DIR* dir = opendir(".");
+        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);
-        char filename[NAME_MAX];
-
-        int n = encode_key_for_uid(filename, targetUid, prefix8);
+        String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid));
+        size_t n = filename.length();
 
         struct dirent* file;
         while ((file = readdir(dir)) != NULL) {
-            if (!strncmp(filename, file->d_name, n)) {
+            // 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);
 
@@ -1143,7 +1503,7 @@
             return ::PERMISSION_DENIED;
         }
 
-        ResponseCode rc = mKeyStore->reset() ? ::NO_ERROR : ::SYSTEM_ERROR;
+        ResponseCode rc = mKeyStore->reset(callingUid) ? ::NO_ERROR : ::SYSTEM_ERROR;
 
         const keymaster_device_t* device = mKeyStore->getDevice();
         if (device == NULL) {
@@ -1180,18 +1540,18 @@
 
         const String8 password8(password);
 
-        switch (mKeyStore->getState()) {
+        switch (mKeyStore->getState(callingUid)) {
             case ::STATE_UNINITIALIZED: {
                 // generate master key, encrypt with password, write to file, initialize mMasterKey*.
-                return mKeyStore->initialize(password8);
+                return mKeyStore->initializeUser(password8, callingUid);
             }
             case ::STATE_NO_ERROR: {
                 // rewrite master key with new password.
-                return mKeyStore->writeMasterKey(password8);
+                return mKeyStore->writeMasterKey(password8, callingUid);
             }
             case ::STATE_LOCKED: {
                 // read master key, decrypt with password, initialize mMasterKey*.
-                return mKeyStore->readMasterKey(password8);
+                return mKeyStore->readMasterKey(password8, callingUid);
             }
         }
         return ::SYSTEM_ERROR;
@@ -1204,13 +1564,13 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (state != ::STATE_NO_ERROR) {
             ALOGD("calling lock in state: %d", state);
             return state;
         }
 
-        mKeyStore->lock();
+        mKeyStore->lock(callingUid);
         return ::NO_ERROR;
     }
 
@@ -1221,7 +1581,7 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (state != ::STATE_LOCKED) {
             ALOGD("calling unlock when not locked");
             return state;
@@ -1238,7 +1598,7 @@
             return -1;
         }
 
-        return mKeyStore->isEmpty() ? ::KEY_NOT_FOUND : ::NO_ERROR;
+        return mKeyStore->isEmpty(callingUid) ? ::KEY_NOT_FOUND : ::NO_ERROR;
     }
 
     int32_t generate(const String16& name, int targetUid) {
@@ -1254,15 +1614,12 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (!isKeystoreUnlocked(state)) {
             ALOGD("calling generate in state: %d", state);
             return state;
         }
 
-        String8 name8(name);
-        char filename[NAME_MAX];
-
         uint8_t* data;
         size_t dataLength;
         int rc;
@@ -1285,12 +1642,13 @@
             return ::SYSTEM_ERROR;
         }
 
-        encode_key_for_uid(filename, targetUid, name8);
+        String8 name8(name);
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
 
         Blob keyBlob(data, dataLength, NULL, 0, TYPE_KEY_PAIR);
         free(data);
 
-        return mKeyStore->put(filename, &keyBlob);
+        return mKeyStore->put(filename.string(), &keyBlob, callingUid);
     }
 
     int32_t import(const String16& name, const uint8_t* data, size_t length, int targetUid) {
@@ -1306,18 +1664,16 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (!isKeystoreUnlocked(state)) {
             ALOGD("calling import in state: %d", state);
             return state;
         }
 
         String8 name8(name);
-        char filename[NAME_MAX];
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
 
-        encode_key_for_uid(filename, targetUid, name8);
-
-        return mKeyStore->importKey(data, length, filename);
+        return mKeyStore->importKey(data, length, filename.string(), callingUid);
     }
 
     int32_t sign(const String16& name, const uint8_t* data, size_t length, uint8_t** out,
@@ -1328,7 +1684,7 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (!isKeystoreUnlocked(state)) {
             ALOGD("calling sign in state: %d", state);
             return state;
@@ -1340,7 +1696,7 @@
         ALOGV("sign %s from uid %d", name8.string(), callingUid);
         int rc;
 
-        ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid,
+        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
                 ::TYPE_KEY_PAIR);
         if (responseCode != ::NO_ERROR) {
             return responseCode;
@@ -1379,7 +1735,7 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (!isKeystoreUnlocked(state)) {
             ALOGD("calling verify in state: %d", state);
             return state;
@@ -1389,7 +1745,7 @@
         String8 name8(name);
         int rc;
 
-        ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid,
+        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
                 TYPE_KEY_PAIR);
         if (responseCode != ::NO_ERROR) {
             return responseCode;
@@ -1435,7 +1791,7 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (!isKeystoreUnlocked(state)) {
             ALOGD("calling get_pubkey in state: %d", state);
             return state;
@@ -1446,7 +1802,7 @@
 
         ALOGV("get_pubkey '%s' from uid %d", name8.string(), callingUid);
 
-        ResponseCode responseCode = get_key_for_name(mKeyStore, &keyBlob, name8, callingUid,
+        ResponseCode responseCode = mKeyStore->getKeyForName(&keyBlob, name8, callingUid,
                 TYPE_KEY_PAIR);
         if (responseCode != ::NO_ERROR) {
             return responseCode;
@@ -1485,12 +1841,11 @@
         }
 
         String8 name8(name);
-        char filename[NAME_MAX];
-
-        encode_key_for_uid(filename, targetUid, name8);
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
 
         Blob keyBlob;
-        ResponseCode responseCode = mKeyStore->get(filename, &keyBlob, ::TYPE_KEY_PAIR);
+        ResponseCode responseCode = mKeyStore->get(filename.string(), &keyBlob, ::TYPE_KEY_PAIR,
+                callingUid);
         if (responseCode != ::NO_ERROR) {
             return responseCode;
         }
@@ -1523,22 +1878,20 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (!isKeystoreUnlocked(state)) {
             ALOGD("calling grant in state: %d", state);
             return state;
         }
 
         String8 name8(name);
-        char filename[NAME_MAX];
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
 
-        encode_key_for_uid(filename, callingUid, name8);
-
-        if (access(filename, R_OK) == -1) {
+        if (access(filename.string(), R_OK) == -1) {
             return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
         }
 
-        mKeyStore->addGrant(filename, granteeUid);
+        mKeyStore->addGrant(filename.string(), granteeUid);
         return ::NO_ERROR;
     }
 
@@ -1549,22 +1902,20 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (!isKeystoreUnlocked(state)) {
             ALOGD("calling ungrant in state: %d", state);
             return state;
         }
 
         String8 name8(name);
-        char filename[NAME_MAX];
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
 
-        encode_key_for_uid(filename, callingUid, name8);
-
-        if (access(filename, R_OK) == -1) {
+        if (access(filename.string(), R_OK) == -1) {
             return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
         }
 
-        return mKeyStore->removeGrant(filename, granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND;
+        return mKeyStore->removeGrant(filename.string(), granteeUid) ? ::NO_ERROR : ::KEY_NOT_FOUND;
     }
 
     int64_t getmtime(const String16& name) {
@@ -1575,18 +1926,16 @@
         }
 
         String8 name8(name);
-        char filename[NAME_MAX];
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
 
-        encode_key_for_uid(filename, callingUid, name8);
-
-        if (access(filename, R_OK) == -1) {
-            ALOGW("could not access %s for getmtime", filename);
+        if (access(filename.string(), R_OK) == -1) {
+            ALOGW("could not access %s for getmtime", filename.string());
             return -1L;
         }
 
-        int fd = TEMP_FAILURE_RETRY(open(filename, O_NOFOLLOW, O_RDONLY));
+        int fd = TEMP_FAILURE_RETRY(open(filename.string(), O_NOFOLLOW, O_RDONLY));
         if (fd < 0) {
-            ALOGW("could not open %s for getmtime", filename);
+            ALOGW("could not open %s for getmtime", filename.string());
             return -1L;
         }
 
@@ -1594,7 +1943,7 @@
         int ret = fstat(fd, &s);
         close(fd);
         if (ret == -1) {
-            ALOGW("could not stat %s for getmtime", filename);
+            ALOGW("could not stat %s for getmtime", filename.string());
             return -1L;
         }
 
@@ -1609,7 +1958,7 @@
             return -1L;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (!isKeystoreUnlocked(state)) {
             ALOGD("calling duplicate in state: %d", state);
             return state;
@@ -1640,27 +1989,24 @@
         }
 
         String8 source8(srcKey);
-        char source[NAME_MAX];
-
-        encode_key_for_uid(source, srcUid, source8);
+        String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid));
 
         String8 target8(destKey);
-        char target[NAME_MAX];
+        String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, srcUid));
 
-        encode_key_for_uid(target, destUid, target8);
-
-        if (access(target, W_OK) != -1 || errno != ENOENT) {
-            ALOGD("destination already exists: %s", target);
+        if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) {
+            ALOGD("destination already exists: %s", targetFile.string());
             return ::SYSTEM_ERROR;
         }
 
         Blob keyBlob;
-        ResponseCode responseCode = mKeyStore->get(source, &keyBlob, TYPE_ANY);
+        ResponseCode responseCode = mKeyStore->get(sourceFile.string(), &keyBlob, TYPE_ANY,
+                callingUid);
         if (responseCode != ::NO_ERROR) {
             return responseCode;
         }
 
-        return mKeyStore->put(target, &keyBlob);
+        return mKeyStore->put(targetFile.string(), &keyBlob, callingUid);
     }
 
     int32_t is_hardware_backed() {
@@ -1674,7 +2020,7 @@
             return ::PERMISSION_DENIED;
         }
 
-        State state = mKeyStore->getState();
+        State state = mKeyStore->getState(callingUid);
         if (!isKeystoreUnlocked(state)) {
             ALOGD("calling clear_uid in state: %d", state);
             return state;
@@ -1682,32 +2028,43 @@
 
         const keymaster_device_t* device = mKeyStore->getDevice();
         if (device == NULL) {
+            ALOGW("can't get keymaster device");
             return ::SYSTEM_ERROR;
         }
 
-        DIR* dir = opendir(".");
+        UserState* userState = mKeyStore->getUserState(callingUid);
+        DIR* dir = opendir(userState->getUserDirName());
         if (!dir) {
+            ALOGW("can't open user directory: %s", strerror(errno));
             return ::SYSTEM_ERROR;
         }
 
-        char filename[NAME_MAX];
-        int n = snprintf(filename, NAME_MAX, "%u_", static_cast<uid_t>(targetUid));
-        char *end = &filename[n];
+        char prefix[NAME_MAX];
+        int n = snprintf(prefix, NAME_MAX, "%u_", static_cast<uid_t>(targetUid));
 
         ResponseCode rc = ::NO_ERROR;
 
         struct dirent* file;
         while ((file = readdir(dir)) != NULL) {
-            if (strncmp(filename, file->d_name, n)) {
+            // We only care about files.
+            if (file->d_type != DT_REG) {
                 continue;
             }
 
-            String8 file8(&file->d_name[n]);
-            encode_key(end, file8);
+            // Skip anything that starts with a "."
+            if (file->d_name[0] == '.') {
+                continue;
+            }
 
+            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, &keyBlob, ::TYPE_ANY) != ::NO_ERROR) {
-                ALOGW("couldn't open %s", filename);
+            if (mKeyStore->get(filename.string(), &keyBlob, ::TYPE_ANY, callingUid)
+                    != ::NO_ERROR) {
+                ALOGW("couldn't open %s", filename.string());
                 continue;
             }
 
@@ -1716,14 +2073,14 @@
                 if (device->delete_keypair != NULL) {
                     if (device->delete_keypair(device, keyBlob.getValue(), keyBlob.getLength())) {
                         rc = ::SYSTEM_ERROR;
-                        ALOGW("device couldn't remove %s", filename);
+                        ALOGW("device couldn't remove %s", filename.string());
                     }
                 }
             }
 
-            if (unlink(filename) && errno != ENOENT) {
+            if (unlinkat(dirfd(dir), filename.string(), 0) && errno != ENOENT) {
                 rc = ::SYSTEM_ERROR;
-                ALOGW("couldn't unlink %s", filename);
+                ALOGW("couldn't unlink %s", filename.string());
             }
         }
         closedir(dir);
@@ -1770,6 +2127,7 @@
     }
 
     KeyStore keyStore(&entropy, dev);
+    keyStore.initialize();
     android::sp<android::IServiceManager> sm = android::defaultServiceManager();
     android::sp<android::KeyStoreProxy> proxy = new android::KeyStoreProxy(&keyStore);
     android::status_t ret = sm->addService(android::String16("android.security.keystore"), proxy);
