[DO NOT MERGE] Fix keychain key upgrade issue am: 7593bbf15a am: c06ec2348a
am: 1ed3e156c3  -s ours

Change-Id: I8c0536ffb8dc6c524f538db2a718febf033e06ce
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
index 384e423..7df03c7 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -1352,6 +1352,24 @@
         return ret;
     }
 
+    virtual int32_t onDeviceOffBody()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
+        status_t status = remote()->transact(BnKeystoreService::ON_DEVICE_OFF_BODY, data, &reply);
+        if (status != NO_ERROR) {
+            ALOGD("onDeviceOffBody() could not contact remote: %d\n", status);
+            return -1;
+        }
+        int32_t err = reply.readExceptionCode();
+        int32_t ret = reply.readInt32();
+        if (err < 0) {
+            ALOGD("onDeviceOffBody() caught exception %d\n", err);
+            return -1;
+        }
+        return ret;
+    }
+
 };
 
 IMPLEMENT_META_INTERFACE(KeystoreService, "android.security.IKeystoreService");
@@ -1862,6 +1880,14 @@
 
             return NO_ERROR;
         }
+        case ON_DEVICE_OFF_BODY: {
+            CHECK_INTERFACE(IKeystoreService, data, reply);
+            int32_t ret = onDeviceOffBody();
+            reply->writeNoException();
+            reply->writeInt32(ret);
+
+            return NO_ERROR;
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/keystore/auth_token_table.cpp b/keystore/auth_token_table.cpp
index c6e5843..76e757b 100644
--- a/keystore/auth_token_table.cpp
+++ b/keystore/auth_token_table.cpp
@@ -138,6 +138,13 @@
     if (static_cast<int64_t>(newest_match->time_received()) + timeout < static_cast<int64_t>(now))
         return AUTH_TOKEN_EXPIRED;
 
+    if (key_info.GetTagValue(TAG_ALLOW_WHILE_ON_BODY)) {
+        if (static_cast<int64_t>(newest_match->time_received()) <
+            static_cast<int64_t>(last_off_body_)) {
+            return AUTH_TOKEN_EXPIRED;
+        }
+    }
+
     newest_match->UpdateLastUse(now);
     *found = newest_match->token();
     return OK;
@@ -155,6 +162,10 @@
                    entries_.end());
 }
 
+void AuthTokenTable::onDeviceOffBody() {
+    last_off_body_ = clock_function_();
+}
+
 void AuthTokenTable::Clear() {
     entries_.clear();
 }
diff --git a/keystore/auth_token_table.h b/keystore/auth_token_table.h
index a2f1446..76cf816 100644
--- a/keystore/auth_token_table.h
+++ b/keystore/auth_token_table.h
@@ -42,7 +42,7 @@
 class AuthTokenTable {
   public:
     AuthTokenTable(size_t max_entries = 32, time_t (*clock_function)() = clock_gettime_raw)
-        : max_entries_(max_entries), clock_function_(clock_function) {}
+        : max_entries_(max_entries), last_off_body_(clock_function()), clock_function_(clock_function) {}
 
     enum Error {
         OK,
@@ -95,6 +95,12 @@
      */
     void MarkCompleted(const keymaster_operation_handle_t op_handle);
 
+    /**
+     * Update the last_off_body_ timestamp so that tokens which remain authorized only so long as
+     * the device stays on body can be revoked.
+     */
+    void onDeviceOffBody();
+
     void Clear();
 
     size_t size() { return entries_.size(); }
@@ -155,6 +161,7 @@
 
     std::vector<Entry> entries_;
     size_t max_entries_;
+    time_t last_off_body_;
     time_t (*clock_function_)();
 };
 
diff --git a/keystore/blob.h b/keystore/blob.h
index 584e312..e2fc9be 100644
--- a/keystore/blob.h
+++ b/keystore/blob.h
@@ -70,6 +70,7 @@
     TYPE_MASTER_KEY = 2,
     TYPE_KEY_PAIR = 3,
     TYPE_KEYMASTER_10 = 4,
+    TYPE_KEY_CHARACTERISTICS = 5,
 } BlobType;
 
 class Entropy;
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
index f5d812a..defd4a9 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -147,6 +147,7 @@
         ON_USER_ADDED = IBinder::FIRST_CALL_TRANSACTION + 33,
         ON_USER_REMOVED = IBinder::FIRST_CALL_TRANSACTION + 34,
         ATTEST_KEY = IBinder::FIRST_CALL_TRANSACTION + 35,
+        ON_DEVICE_OFF_BODY = IBinder::FIRST_CALL_TRANSACTION + 36,
     };
 
     DECLARE_META_INTERFACE(KeystoreService);
@@ -248,6 +249,7 @@
     virtual int32_t attestKey(const String16& name, const KeymasterArguments& params,
                               KeymasterCertificateChain* outChain) = 0;
 
+    virtual int32_t onDeviceOffBody() = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 5cf5e63..8fef42f 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -99,7 +99,7 @@
     }
 
     String8 name8(name);
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
+    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_GENERIC));
 
     Blob keyBlob(item, itemLength, NULL, 0, ::TYPE_GENERIC);
     keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
@@ -113,10 +113,21 @@
         return ::PERMISSION_DENIED;
     }
     String8 name8(name);
-    String8 filename = mKeyStore->getBlobFileNameIfExists(name8, targetUid);
+    String8 filename = mKeyStore->getBlobFileNameIfExists(name8, targetUid, ::TYPE_ANY);
     if (filename.isEmpty()) return ResponseCode::KEY_NOT_FOUND;
 
-    return mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
+    ResponseCode result = mKeyStore->del(filename.string(), ::TYPE_ANY,
+            get_user_id(targetUid));
+    if (result != ResponseCode::NO_ERROR) {
+        return result;
+    }
+
+    filename = mKeyStore->getBlobFileNameIfExists(name8, targetUid, ::TYPE_KEY_CHARACTERISTICS);
+    if (!filename.isEmpty()) {
+        return mKeyStore->del(filename.string(), ::TYPE_KEY_CHARACTERISTICS,
+                get_user_id(targetUid));
+    }
+    return ResponseCode::NO_ERROR;
 }
 
 int32_t KeyStoreService::exist(const String16& name, int targetUid) {
@@ -125,7 +136,7 @@
         return ::PERMISSION_DENIED;
     }
 
-    String8 filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid);
+    String8 filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid,  ::TYPE_ANY);
     return (!filename.isEmpty()) ? ResponseCode::NO_ERROR : ResponseCode::KEY_NOT_FOUND;
 }
 
@@ -135,7 +146,7 @@
         return ::PERMISSION_DENIED;
     }
     const String8 prefix8(prefix);
-    String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid));
+    String8 filename(mKeyStore->getKeyNameForUid(prefix8, targetUid, TYPE_ANY));
 
     if (mKeyStore->list(filename, matches, get_user_id(targetUid)) != ::NO_ERROR) {
         return ::SYSTEM_ERROR;
@@ -424,7 +435,7 @@
     }
 
     String8 name8(name);
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
+    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
 
     if (access(filename.string(), R_OK) == -1) {
         return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
@@ -442,7 +453,7 @@
     }
 
     String8 name8(name);
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid));
+    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
 
     if (access(filename.string(), R_OK) == -1) {
         return (errno != ENOENT) ? ::SYSTEM_ERROR : ::KEY_NOT_FOUND;
@@ -458,7 +469,7 @@
         return -1L;
     }
 
-    String8 filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid);
+    String8 filename = mKeyStore->getBlobFileNameIfExists(String8(name), targetUid, ::TYPE_ANY);
 
     if (filename.isEmpty()) {
         ALOGW("could not access %s for getmtime", filename.string());
@@ -482,6 +493,7 @@
     return static_cast<int64_t>(s.st_mtime);
 }
 
+// TODO(tuckeris): This is dead code, remove it.  Don't bother copying over key characteristics here
 int32_t KeyStoreService::duplicate(const String16& srcKey, int32_t srcUid, const String16& destKey,
                                    int32_t destUid) {
     uid_t callingUid = IPCThreadState::self()->getCallingUid();
@@ -523,10 +535,10 @@
     }
 
     String8 source8(srcKey);
-    String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid));
+    String8 sourceFile(mKeyStore->getKeyNameForUidWithDir(source8, srcUid, ::TYPE_ANY));
 
     String8 target8(destKey);
-    String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid));
+    String8 targetFile(mKeyStore->getKeyNameForUidWithDir(target8, destUid, ::TYPE_ANY));
 
     if (access(targetFile.string(), W_OK) != -1 || errno != ENOENT) {
         ALOGD("destination already exists: %s", targetFile.string());
@@ -561,8 +573,13 @@
 
     for (uint32_t i = 0; i < aliases.size(); i++) {
         String8 name8(aliases[i]);
-        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid));
+        String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid, ::TYPE_ANY));
         mKeyStore->del(filename.string(), ::TYPE_ANY, get_user_id(targetUid));
+
+        // del() will fail silently if no cached characteristics are present for this alias.
+        String8 chr_filename(mKeyStore->getKeyNameForUidWithDir(name8, targetUid,
+            ::TYPE_KEY_CHARACTERISTICS));
+        mKeyStore->del(chr_filename.string(), ::TYPE_KEY_CHARACTERISTICS, get_user_id(targetUid));
     }
     return ::NO_ERROR;
 }
@@ -609,6 +626,19 @@
     if (device == NULL) {
         return ::SYSTEM_ERROR;
     }
+
+    // Capture characteristics before they're potentially stripped by the device
+    AuthorizationSet keyCharacteristics(opParams.data(), opParams.size());
+    if (keyCharacteristics.is_valid() != AuthorizationSet::Error::OK) {
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+    UniquePtr<uint8_t[]> kc_buf;
+    kc_buf.reset(new (std::nothrow) uint8_t[keyCharacteristics.SerializedSize()]);
+    if (!kc_buf.get()) {
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+    keyCharacteristics.Serialize(kc_buf.get(), kc_buf.get() + keyCharacteristics.SerializedSize());
+
     // TODO: Seed from Linux RNG before this.
     if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 &&
         device->generate_key != NULL) {
@@ -650,16 +680,30 @@
         return rc;
     }
 
+    // Write the key:
     String8 name8(name);
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid));
+    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
 
     Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10);
     keyBlob.setFallback(isFallback);
     keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
 
     free(const_cast<uint8_t*>(blob.key_material));
+    rc = mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
 
-    return mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
+    if (rc != ::NO_ERROR) {
+        return rc;
+    }
+
+    // Write the characteristics:
+    String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
+
+    Blob charBlob(kc_buf.get(), keyCharacteristics.SerializedSize(),
+        NULL, 0, ::TYPE_KEY_CHARACTERISTICS);
+    charBlob.setFallback(isFallback);
+    charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
+
+    return mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid));
 }
 
 int32_t KeyStoreService::getKeyCharacteristics(const String16& name,
@@ -741,6 +785,19 @@
     if (device == NULL) {
         return ::SYSTEM_ERROR;
     }
+
+    // Capture characteristics before they're potentially stripped
+    AuthorizationSet keyCharacteristics(opParams.data(), opParams.size());
+    if (keyCharacteristics.is_valid() != AuthorizationSet::Error::OK) {
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+    UniquePtr<uint8_t[]> kc_buf;
+    kc_buf.reset(new (std::nothrow) uint8_t[keyCharacteristics.SerializedSize()]);
+    if (!kc_buf.get()) {
+        return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+    }
+    keyCharacteristics.Serialize(kc_buf.get(), kc_buf.get() + keyCharacteristics.SerializedSize());
+
     if (device->common.module->module_api_version >= KEYMASTER_MODULE_API_VERSION_1_0 &&
         device->import_key != NULL) {
         rc = device->import_key(device, &inParams, format, &input, &blob,
@@ -760,16 +817,30 @@
         return rc;
     }
 
+    // Write the key:
     String8 name8(name);
-    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid));
+    String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEYMASTER_10));
 
     Blob keyBlob(blob.key_material, blob.key_material_size, NULL, 0, ::TYPE_KEYMASTER_10);
     keyBlob.setFallback(isFallback);
     keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
 
     free(const_cast<uint8_t*>(blob.key_material));
+    rc = mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
 
-    return mKeyStore->put(filename.string(), &keyBlob, get_user_id(uid));
+    if (rc != ::NO_ERROR) {
+        return rc;
+    }
+
+    // Write the characteristics:
+    String8 cFilename(mKeyStore->getKeyNameForUidWithDir(name8, uid, ::TYPE_KEY_CHARACTERISTICS));
+
+    Blob charBlob(kc_buf.get(), keyCharacteristics.SerializedSize(),
+        NULL, 0, ::TYPE_KEY_CHARACTERISTICS);
+    charBlob.setFallback(isFallback);
+    charBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
+
+    return mKeyStore->put(cFilename.string(), &charBlob, get_user_id(uid));
 }
 
 void KeyStoreService::exportKey(const String16& name, keymaster_key_format_t format,
@@ -862,6 +933,24 @@
         return;
     }
     const hw_auth_token_t* authToken = NULL;
+
+    // Merge these characteristics with the ones cached when the key was generated or imported
+    Blob charBlob;
+    AuthorizationSet persistedCharacteristics;
+    responseCode = mKeyStore->getKeyForName(&charBlob, name8, targetUid, TYPE_KEY_CHARACTERISTICS);
+    if (responseCode == ::NO_ERROR) {
+        const uint8_t* serializedCharacteristics = charBlob.getValue();
+        persistedCharacteristics.Deserialize(&serializedCharacteristics,
+            serializedCharacteristics + charBlob.getLength());
+    } else {
+        ALOGD("Unable to read cached characteristics for key");
+    }
+
+    // Replace the sw_enforced set with those persisted to disk, minus hw_enforced
+    persistedCharacteristics.Union(characteristics.get()->sw_enforced);
+    persistedCharacteristics.Difference(characteristics.get()->hw_enforced);
+    persistedCharacteristics.CopyToParamSet(&characteristics.get()->sw_enforced);
+
     int32_t authResult = getAuthToken(characteristics.get(), 0, purpose, &authToken,
                                       /*failOnTokenMissing*/ false);
     // If per-operation auth is needed we need to begin the operation and
@@ -1159,6 +1248,12 @@
     return ::NO_ERROR;
 }
 
+int32_t KeyStoreService::onDeviceOffBody() {
+    // TODO(tuckeris): add permission check.  This should be callable from ClockworkHome only.
+    mAuthTokenTable.onDeviceOffBody();
+    return ::NO_ERROR;
+}
+
 /**
  * Prune the oldest pruneable operation.
  */
@@ -1553,7 +1648,7 @@
     UniquePtr<uint8_t, Malloc_Delete> upgraded_key_deleter(
         const_cast<uint8_t*>(upgraded_key.key_material));
 
-    String8 filename = mKeyStore->getBlobFileNameIfExists(name8, uid);
+    String8 filename = mKeyStore->getBlobFileNameIfExists(name8, uid, ::TYPE_KEYMASTER_10);
     if (filename.isEmpty()) {
         ALOGI("trying to upgrade a non existing blob");
         return KEY_NOT_FOUND;
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index 7d55919..cd43391 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -119,6 +119,8 @@
     int32_t attestKey(const String16& name, const KeymasterArguments& params,
                       KeymasterCertificateChain* outChain) override;
 
+    int32_t onDeviceOffBody();
+
   private:
     static const int32_t UID_SELF = -1;
 
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 5675e91..a7a81e8 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -115,34 +115,51 @@
     return length;
 }
 
-android::String8 KeyStore::getKeyName(const android::String8& keyName) {
+android::String8 KeyStore::getKeyName(const android::String8& keyName, const BlobType type) {
     char encoded[encode_key_length(keyName) + 1];  // add 1 for null char
     encode_key(encoded, keyName);
-    return android::String8(encoded);
+    if (type == TYPE_KEY_CHARACTERISTICS) {
+        return android::String8::format(".chr_%s", encoded);
+    } else {
+        return android::String8(encoded);
+    }
 }
 
-android::String8 KeyStore::getKeyNameForUid(const android::String8& keyName, uid_t uid) {
+android::String8 KeyStore::getKeyNameForUid(
+    const android::String8& keyName, uid_t uid, const BlobType type) {
     char encoded[encode_key_length(keyName) + 1];  // add 1 for null char
     encode_key(encoded, keyName);
-    return android::String8::format("%u_%s", uid, encoded);
+    if (type == TYPE_KEY_CHARACTERISTICS) {
+        return android::String8::format(".%u_chr_%s", uid, encoded);
+    } else {
+        return android::String8::format("%u_%s", uid, encoded);
+    }
 }
 
-android::String8 KeyStore::getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid) {
+android::String8 KeyStore::getKeyNameForUidWithDir(
+    const android::String8& keyName, uid_t uid, const BlobType type) {
     char encoded[encode_key_length(keyName) + 1];  // add 1 for null char
     encode_key(encoded, keyName);
-    return android::String8::format("%s/%u_%s", getUserStateByUid(uid)->getUserDirName(), uid,
-                                    encoded);
+
+    if (type == TYPE_KEY_CHARACTERISTICS) {
+        return android::String8::format("%s/.%u_chr_%s", getUserStateByUid(uid)->getUserDirName(),
+                                        uid, encoded);
+    } else {
+        return android::String8::format("%s/%u_%s", getUserStateByUid(uid)->getUserDirName(), uid,
+                                        encoded);
+    }
 }
 
-android::String8 KeyStore::getBlobFileNameIfExists(const android::String8& alias, uid_t uid) {
-    android::String8 filepath8(getKeyNameForUidWithDir(alias, uid));
+android::String8 KeyStore::getBlobFileNameIfExists(const android::String8& alias, uid_t uid,
+                                                  const BlobType type) {
+    android::String8 filepath8(getKeyNameForUidWithDir(alias, uid, type));
 
     if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
 
     // If this is one of the legacy UID->UID mappings, use it.
     uid_t euid = get_keystore_euid(uid);
     if (euid != uid) {
-        filepath8 = getKeyNameForUidWithDir(alias, euid);
+        filepath8 = getKeyNameForUidWithDir(alias, euid, type);
         if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
     }
 
@@ -155,15 +172,19 @@
     }
     android::String8 granted_alias(end + 1);
 
-    filepath8 = getKeyNameForUidWithDir(granted_alias, granter_uid);
-    if (hasGrant(filepath8.string(), uid)) {
-        if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
+    // We might be asked to get a characteristics file, but still need to check grant
+    // on the key file itself.
+    android::String8 keyfilepath8 = getKeyNameForUidWithDir(granted_alias, granter_uid, ::TYPE_ANY);
+    if (!hasGrant(keyfilepath8.string(), uid)) {
+        return android::String8();
     }
+    // Get the granted blob file path of the desired type
+    filepath8 = getKeyNameForUidWithDir(granted_alias, granter_uid, type);
+    if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
 
     return android::String8();
 }
 
-
 void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
     android::String8 prefix("");
     android::Vector<android::String16> aliases;
@@ -174,7 +195,7 @@
     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());
+                                            getKeyName(filename, TYPE_ANY).string());
         bool shouldDelete = true;
         if (keepUnenryptedEntries) {
             Blob blob;
@@ -190,6 +211,13 @@
         }
         if (shouldDelete) {
             del(filename, ::TYPE_ANY, userId);
+
+            // del() will fail silently if no cached characteristics are present for this alias.
+            android::String8 chr_filename(aliases[i]);
+            chr_filename = android::String8::format("%s/%s", userState->getUserDirName(),
+                                            getKeyName(chr_filename,
+                                                TYPE_KEY_CHARACTERISTICS).string());
+            del(chr_filename, ::TYPE_KEY_CHARACTERISTICS, userId);
         }
     }
     if (!userState->deleteMasterKey()) {
@@ -515,7 +543,7 @@
 
 ResponseCode KeyStore::getKeyForName(Blob* keyBlob, const android::String8& keyName,
                                      const uid_t uid, const BlobType type) {
-    auto filepath8 = getBlobFileNameIfExists(keyName, uid);
+    auto filepath8 = getBlobFileNameIfExists(keyName, uid, type);
     uid_t userId = get_user_id(uid);
 
     if (!filepath8.isEmpty())
diff --git a/keystore/keystore.h b/keystore/keystore.h
index b842841..fee4527 100644
--- a/keystore/keystore.h
+++ b/keystore/keystore.h
@@ -53,10 +53,13 @@
     ResponseCode writeMasterKey(const android::String8& pw, uid_t userId);
     ResponseCode readMasterKey(const android::String8& pw, uid_t userId);
 
-    android::String8 getKeyName(const android::String8& keyName);
-    android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid);
-    android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid);
-    android::String8 getBlobFileNameIfExists(const android::String8& alias, uid_t uid);
+    android::String8 getKeyName(const android::String8& keyName, const BlobType type);
+    android::String8 getKeyNameForUid(const android::String8& keyName, uid_t uid,
+                                      const BlobType type);
+    android::String8 getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid,
+                                             const BlobType type);
+    android::String8 getBlobFileNameIfExists(const android::String8& alias, uid_t uid,
+                                            const BlobType type);
 
     /*
      * Delete entries owned by userId. If keepUnencryptedEntries is true