blob: ac3ab5f33ddd200449f60a45bf351a0499497d0e [file] [log] [blame]
Kenny Roota91203b2012-02-15 15:00:46 -08001/*
Shawn Willdenc1d1fee2016-01-26 22:44:56 -07002 * Copyright (C) 2016 The Android Open Source Project
Kenny Roota91203b2012-02-15 15:00:46 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010017#define LOG_TAG "keystore"
18
Shawn Willdenfa5702f2017-12-03 15:14:58 -070019#include "KeyStore.h"
Kenny Root07438c82012-11-02 15:41:02 -070020
Kenny Roota91203b2012-02-15 15:00:46 -080021#include <dirent.h>
22#include <fcntl.h>
Kenny Roota91203b2012-02-15 15:00:46 -080023
Kenny Root822c3a92012-03-23 16:34:39 -070024#include <openssl/bio.h>
Kenny Roota91203b2012-02-15 15:00:46 -080025
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070026#include <utils/String16.h>
Janis Danisevskis6905c332017-09-01 13:24:23 -070027#include <utils/String8.h>
Kenny Root70e3a862012-02-15 17:20:23 -080028
Pavel Grafovcef39472018-02-12 18:45:02 +000029#include <android-base/scopeguard.h>
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010030#include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
Rob Barnesbb6cabd2018-10-04 17:10:37 -060031#include <android/security/keystore/IKeystoreService.h>
Pavel Grafovff311b42018-01-24 20:34:37 +000032#include <log/log_event_list.h>
33
34#include <private/android_logger.h>
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010035
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070036#include "keystore_utils.h"
37#include "permissions.h"
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010038#include <keystore/keystore_hidl_support.h>
Kenny Roota91203b2012-02-15 15:00:46 -080039
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070040#include "keymaster_worker.h"
41
Shawn Willdenc67a8aa2017-12-03 17:51:29 -070042namespace keystore {
43
Shawn Willden0329a822017-12-04 13:55:14 -070044const char* KeyStore::kOldMasterKey = ".masterkey";
45const char* KeyStore::kMetaDataFile = ".metadata";
Kenny Roota91203b2012-02-15 15:00:46 -080046
Shawn Willden0329a822017-12-04 13:55:14 -070047const android::String16 KeyStore::kRsaKeyType("RSA");
48const android::String16 KeyStore::kEcKeyType("EC");
Riley Spahneaabae92014-06-30 12:39:52 -070049
Janis Danisevskis6905c332017-09-01 13:24:23 -070050using android::String8;
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010051
Janis Danisevskisc1460142017-12-18 16:48:46 -080052KeyStore::KeyStore(Entropy* entropy, const KeymasterDevices& kmDevices,
53 SecurityLevel minimalAllowedSecurityLevelForNewKeys)
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070054 : mEntropy(entropy),
55 mAllowNewFallback(minimalAllowedSecurityLevelForNewKeys == SecurityLevel::SOFTWARE),
56 mConfirmationManager(new ConfirmationManager(this)) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070057 memset(&mMetaData, '\0', sizeof(mMetaData));
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070058
59 static_assert(std::tuple_size<std::decay_t<decltype(kmDevices)>>::value ==
60 std::tuple_size<decltype(mKmDevices)>::value,
61 "KmasterDevices and KeymasterWorkers must have the same size");
62 for (size_t i = 0; i < kmDevices.size(); ++i) {
63 if (kmDevices[SecurityLevel(i)]) {
64 mKmDevices[SecurityLevel(i)] =
65 std::make_shared<KeymasterWorker>(kmDevices[SecurityLevel(i)], this);
66 }
67 }
Kenny Root70e3a862012-02-15 17:20:23 -080068}
69
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070070KeyStore::~KeyStore() {
Shawn Willden55268b52015-07-28 11:06:00 -060071}
72
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070073ResponseCode KeyStore::initialize() {
74 readMetaData();
75 if (upgradeKeystore()) {
76 writeMetaData();
Shawn Willden55268b52015-07-28 11:06:00 -060077 }
78
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010079 return ResponseCode::NO_ERROR;
Shawn Willden55268b52015-07-28 11:06:00 -060080}
81
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070082ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070083 auto userState = mUserStateDB.getUserState(userId);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070084 return userState->initialize(pw, mEntropy);
Chad Brubakerfc18edc2015-01-12 15:17:18 -080085}
86
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070087ResponseCode KeyStore::copyMasterKey(uid_t srcUser, uid_t dstUser) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070088 auto userState = mUserStateDB.getUserState(dstUser);
89 auto initState = mUserStateDB.getUserState(srcUser);
90 return userState->copyMasterKey(&initState);
Kenny Root70e3a862012-02-15 17:20:23 -080091}
92
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070093ResponseCode KeyStore::writeMasterKey(const android::String8& pw, uid_t userId) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070094 auto userState = mUserStateDB.getUserState(userId);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070095 return userState->writeMasterKey(pw, mEntropy);
Shawn Willden55268b52015-07-28 11:06:00 -060096}
97
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070098ResponseCode KeyStore::readMasterKey(const android::String8& pw, uid_t userId) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070099 auto userState = mUserStateDB.getUserState(userId);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700100 return userState->readMasterKey(pw, mEntropy);
Kenny Root49468902013-03-19 13:41:33 -0700101}
102
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700103LockedKeyBlobEntry KeyStore::getLockedBlobEntryIfNotExists(const std::string& alias, uid_t uid) {
104 KeyBlobEntry kbe(alias, mUserStateDB.getUserStateByUid(uid)->getUserDirName(), uid);
105 auto result = LockedKeyBlobEntry::get(std::move(kbe));
106 if (result->hasKeyBlob()) return {};
107 return result;
Kenny Root655b9582013-04-04 08:37:42 -0700108}
109
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700110std::optional<KeyBlobEntry> KeyStore::getBlobEntryIfExists(const std::string& alias, uid_t uid) {
111 KeyBlobEntry kbe(alias, mUserStateDB.getUserStateByUid(uid)->getUserDirName(), uid);
112 if (kbe.hasKeyBlob()) return kbe;
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700113
114 // If this is one of the legacy UID->UID mappings, use it.
115 uid_t euid = get_keystore_euid(uid);
116 if (euid != uid) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700117 kbe = KeyBlobEntry(alias, mUserStateDB.getUserStateByUid(euid)->getUserDirName(), euid);
118 if (kbe.hasKeyBlob()) return kbe;
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700119 }
120
121 // They might be using a granted key.
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700122 auto grant = mGrants.get(uid, alias);
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700123 if (grant) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700124 kbe = grant->entry_;
125 if (kbe.hasKeyBlob()) return kbe;
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700126 }
127 return {};
128}
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700129LockedKeyBlobEntry KeyStore::getLockedBlobEntryIfExists(const std::string& alias, uid_t uid) {
130 auto blobentry = getBlobEntryIfExists(alias, uid);
131 if (!blobentry) return {};
132 LockedKeyBlobEntry lockedentry = LockedKeyBlobEntry::get(std::move(*blobentry));
133 if (!lockedentry || !lockedentry->hasKeyBlob()) return {};
134 return lockedentry;
135}
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700136
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700137void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
138 android::String8 prefix("");
139 android::Vector<android::String16> aliases;
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700140
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700141 auto userState = mUserStateDB.getUserState(userId);
142 std::string userDirName = userState->getUserDirName();
143 auto encryptionKey = userState->getEncryptionKey();
144 auto state = userState->getState();
Janis Danisevskis265435f2018-11-16 14:10:46 -0800145 // userState is a proxy that holds a lock which may be required by a worker.
146 // LockedKeyBlobEntry::list has a fence that waits until all workers have finished which may
147 // not happen if a user state lock is held. The following line relinquishes the lock.
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700148 userState = {};
149
150 ResponseCode rc;
151 std::list<LockedKeyBlobEntry> matches;
152
153 // must not be called by a keymaster worker. List waits for workers to relinquish all access
154 // to blob entries
155 std::tie(rc, matches) = LockedKeyBlobEntry::list(userDirName);
156 if (rc != ResponseCode::NO_ERROR) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700157 return;
158 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700159
160 for (LockedKeyBlobEntry& lockedEntry : matches) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700161 bool shouldDelete = true;
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700162
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700163 if (keepUnenryptedEntries) {
164 Blob blob;
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700165 Blob charBlob;
166 ResponseCode rc;
167
168 std::tie(rc, blob, charBlob) = lockedEntry.readBlobs(encryptionKey, state);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700169
Shawn Willden07aebe72017-02-28 13:53:24 -0700170 switch (rc) {
171 case ResponseCode::SYSTEM_ERROR:
172 case ResponseCode::VALUE_CORRUPTED:
173 // If we can't read blobs, delete them.
174 shouldDelete = true;
175 break;
176
177 case ResponseCode::NO_ERROR:
178 case ResponseCode::LOCKED:
179 // Delete encrypted blobs but keep unencrypted blobs and super-encrypted blobs. We
180 // need to keep super-encrypted blobs so we can report that the user is
181 // unauthenticated if a caller tries to use them, rather than reporting that they
182 // don't exist.
183 shouldDelete = blob.isEncrypted();
184 break;
185
186 default:
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700187 ALOGE("Got unexpected return code %d from readBlobs", rc);
Shawn Willden07aebe72017-02-28 13:53:24 -0700188 // This shouldn't happen. To be on the safe side, delete it.
189 shouldDelete = true;
190 break;
191 }
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700192 }
193 if (shouldDelete) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700194 del(lockedEntry);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700195 }
196 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700197
198 userState = mUserStateDB.getUserState(userId);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700199 if (!userState->deleteMasterKey()) {
200 ALOGE("Failed to delete user %d's master key", userId);
201 }
202 if (!keepUnenryptedEntries) {
203 if (!userState->reset()) {
204 ALOGE("Failed to remove user %d's directory", userId);
205 }
206 }
207}
208
209bool KeyStore::isEmpty(uid_t userId) const {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700210 std::string userDirName;
211 {
Janis Danisevskis265435f2018-11-16 14:10:46 -0800212 // userState holds a lock which must be relinquished before list is called. This scope
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700213 // prevents deadlocks.
214 auto userState = mUserStateDB.getUserState(userId);
215 if (!userState) {
216 return true;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700217 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700218 userDirName = userState->getUserDirName();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700219 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700220
221 ResponseCode rc;
222 std::list<LockedKeyBlobEntry> matches;
223
224 // must not be called by a keymaster worker. List waits for workers to relinquish all access
225 // to blob entries
226 std::tie(rc, matches) = LockedKeyBlobEntry::list(userDirName);
227
228 return rc == ResponseCode::SYSTEM_ERROR || matches.size() == 0;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700229}
230
231void KeyStore::lock(uid_t userId) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700232 auto userState = mUserStateDB.getUserState(userId);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700233 userState->zeroizeMasterKeysInMemory();
234 userState->setState(STATE_LOCKED);
235}
236
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700237static void maybeLogKeyIntegrityViolation(const LockedKeyBlobEntry& lockedEntry,
238 const BlobType type) {
239 if (!__android_log_security() || (type != TYPE_KEY_PAIR && type != TYPE_KEYMASTER_10)) return;
240 log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
241}
Pavel Grafovcef39472018-02-12 18:45:02 +0000242
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700243std::tuple<ResponseCode, Blob, Blob> KeyStore::get(const LockedKeyBlobEntry& blobfile) {
244 std::tuple<ResponseCode, Blob, Blob> result;
Pavel Grafovcef39472018-02-12 18:45:02 +0000245
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700246 uid_t userId = get_user_id(blobfile->uid());
247 Blob& keyBlob = std::get<1>(result);
248 ResponseCode& rc = std::get<0>(result);
249
250 auto userState = mUserStateDB.getUserState(userId);
251 BlobType type = BlobType::TYPE_ANY;
Pavel Grafovcef39472018-02-12 18:45:02 +0000252 auto logOnScopeExit = android::base::make_scope_guard([&] {
253 if (rc == ResponseCode::VALUE_CORRUPTED) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700254 maybeLogKeyIntegrityViolation(blobfile, type);
Pavel Grafovcef39472018-02-12 18:45:02 +0000255 }
256 });
257
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700258 result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100259 if (rc != ResponseCode::NO_ERROR) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700260 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700261 }
262
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700263 // update the type for logging (see scope_guard above)
264 type = keyBlob.getType();
265
266 const uint8_t version = keyBlob.getVersion();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700267 if (version < CURRENT_BLOB_VERSION) {
268 /* If we upgrade the key, we need to write it to disk again. Then
269 * it must be read it again since the blob is encrypted each time
270 * it's written.
271 */
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700272 if (upgradeBlob(&keyBlob, version)) {
273 if ((rc = this->put(blobfile, keyBlob, {})) != ResponseCode::NO_ERROR ||
274 (result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState()),
275 rc) != ResponseCode::NO_ERROR) {
276 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700277 }
278 }
279 }
280
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700281 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700282}
283
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700284ResponseCode KeyStore::put(const LockedKeyBlobEntry& blobfile, Blob keyBlob,
285 Blob characteristicsBlob) {
286 auto userState = mUserStateDB.getUserStateByUid(blobfile->uid());
287 return blobfile.writeBlobs(std::move(keyBlob), std::move(characteristicsBlob),
288 userState->getEncryptionKey(), userState->getState(), mEntropy);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700289}
290
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700291ResponseCode KeyStore::del(const LockedKeyBlobEntry& blobfile) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700292 Blob keyBlob;
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700293 Blob charactaristicsBlob;
294 ResponseCode rc;
295 uid_t uid = blobfile->uid();
296 std::string alias = blobfile->alias();
297
298 std::tie(rc, keyBlob, charactaristicsBlob) = get(blobfile);
299
300 // after getting the blob from the file system we scrub the filesystem.
301 mGrants.removeAllGrantsToKey(uid, alias);
302 auto result = blobfile.deleteBlobs();
303
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100304 if (rc != ResponseCode::NO_ERROR) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700305 LOG(ERROR) << "get keyblob failed " << int(rc);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700306 return rc;
307 }
308
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700309 // if we got the blob successfully, we try and delete it from the keymaster device
Janis Danisevskisc1460142017-12-18 16:48:46 -0800310 auto dev = getDevice(keyBlob);
Janis Danisevskis69c434a2017-01-30 10:27:10 +0000311
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700312 if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
313 dev->deleteKey(blob2hidlVec(keyBlob), [alias, uid](Return<ErrorCode> rc) {
314 auto ret = KS_HANDLE_HIDL_ERROR(rc);
315 // A device doesn't have to implement delete_key.
316 bool success = ret == ErrorCode::OK || ret == ErrorCode::UNIMPLEMENTED;
317 if (__android_log_security()) {
318 android_log_event_list(SEC_TAG_KEY_DESTROYED)
319 << int32_t(success) << alias << int32_t(uid) << LOG_ID_SECURITY;
Kenny Root07438c82012-11-02 15:41:02 -0700320 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700321 if (!success) {
322 LOG(ERROR) << "Keymaster delete for key " << alias << " of uid " << uid
323 << " failed";
Chad Brubakerdf705172015-06-17 20:17:51 -0700324 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700325 });
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700326 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700327
328 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700329}
Chad Brubaker3a7d9e62015-06-04 15:01:46 -0700330
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700331std::string KeyStore::addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid) {
332 return mGrants.put(granteeUid, blobfile);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700333}
Chad Brubaker3a7d9e62015-06-04 15:01:46 -0700334
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700335bool KeyStore::removeGrant(const LockedKeyBlobEntry& blobfile, const uid_t granteeUid) {
336 return mGrants.removeByFileAlias(granteeUid, blobfile);
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700337}
338void KeyStore::removeAllGrantsToUid(const uid_t granteeUid) {
339 mGrants.removeAllGrantsToUid(granteeUid);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700340}
Chad Brubaker3a7d9e62015-06-04 15:01:46 -0700341
Shawn Willden0329a822017-12-04 13:55:14 -0700342bool KeyStore::isHardwareBacked(const android::String16& keyType) const {
Janis Danisevskisc1460142017-12-18 16:48:46 -0800343 // if strongbox device is present TEE must also be present and of sufficiently high version
344 // to support all keys in hardware
345 if (getDevice(SecurityLevel::STRONGBOX)) return true;
346 if (!getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700347 ALOGW("can't get keymaster device");
348 return false;
349 }
Janis Danisevskise2b6caf2017-03-02 16:37:10 -0800350
Janis Danisevskisc1460142017-12-18 16:48:46 -0800351 auto version = getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)->halVersion();
Shawn Willden0329a822017-12-04 13:55:14 -0700352 if (keyType == kRsaKeyType) return true; // All versions support RSA
353 return keyType == kEcKeyType && version.supportsEc;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700354}
355
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700356std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry>
357KeyStore::getKeyForName(const android::String8& keyName, const uid_t uid, const BlobType type) {
358 std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry> result;
359 auto& [rc, keyBlob, charBlob, lockedEntry] = result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700360
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700361 lockedEntry = getLockedBlobEntryIfExists(keyName.string(), uid);
Riley Spahneaabae92014-06-30 12:39:52 -0700362
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700363 if (!lockedEntry) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700364
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700365 std::tie(rc, keyBlob, charBlob) = get(lockedEntry);
366
367 if (rc == ResponseCode::NO_ERROR) {
368 if (keyBlob.getType() != type) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700369 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700370 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700371}
372
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700373bool KeyStore::upgradeBlob(Blob* blob, const uint8_t oldVersion) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700374 bool updated = false;
375 uint8_t version = oldVersion;
376
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700377 if (!blob || !(*blob)) return false;
378
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700379 /* From V0 -> V1: All old types were unknown */
380 if (version == 0) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700381 ALOGE("Failed to upgrade key blob. Ancient blob version 0 is no longer supported");
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700382
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700383 return false;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700384 }
385
386 /* From V1 -> V2: All old keys were encrypted */
387 if (version == 1) {
388 ALOGV("upgrading to version 2");
389
390 blob->setEncrypted(true);
391 version = 2;
392 updated = true;
Kenny Roota91203b2012-02-15 15:00:46 -0800393 }
Kenny Root07438c82012-11-02 15:41:02 -0700394
395 /*
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700396 * If we've updated, set the key blob to the right version
397 * and write it.
Kenny Root07438c82012-11-02 15:41:02 -0700398 */
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700399 if (updated) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700400 blob->setVersion(version);
401 }
Kenny Root70e3a862012-02-15 17:20:23 -0800402
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700403 return updated;
404}
405
406struct BIO_Delete {
407 void operator()(BIO* p) const { BIO_free(p); }
408};
Janis Danisevskisccfff102017-05-01 11:02:51 -0700409typedef std::unique_ptr<BIO, BIO_Delete> Unique_BIO;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700410
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700411void KeyStore::readMetaData() {
Shawn Willden0329a822017-12-04 13:55:14 -0700412 int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700413 if (in < 0) {
414 return;
415 }
416 size_t fileLength = readFully(in, (uint8_t*)&mMetaData, sizeof(mMetaData));
417 if (fileLength != sizeof(mMetaData)) {
418 ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, sizeof(mMetaData));
419 }
420 close(in);
421}
422
423void KeyStore::writeMetaData() {
424 const char* tmpFileName = ".metadata.tmp";
425 int out =
426 TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
427 if (out < 0) {
428 ALOGE("couldn't write metadata file: %s", strerror(errno));
429 return;
430 }
431 size_t fileLength = writeFully(out, (uint8_t*)&mMetaData, sizeof(mMetaData));
432 if (fileLength != sizeof(mMetaData)) {
433 ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
434 sizeof(mMetaData));
435 }
436 close(out);
Shawn Willden0329a822017-12-04 13:55:14 -0700437 rename(tmpFileName, kMetaDataFile);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700438}
439
440bool KeyStore::upgradeKeystore() {
441 bool upgraded = false;
442
443 if (mMetaData.version == 0) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700444 auto userState = getUserStateDB().getUserStateByUid(0);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700445
446 // Initialize first so the directory is made.
447 userState->initialize();
448
449 // Migrate the old .masterkey file to user 0.
Shawn Willden0329a822017-12-04 13:55:14 -0700450 if (access(kOldMasterKey, R_OK) == 0) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700451 if (rename(kOldMasterKey, userState->getMasterKeyFileName().c_str()) < 0) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700452 ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
453 return false;
454 }
455 }
456
457 // Initialize again in case we had a key.
458 userState->initialize();
459
460 // Try to migrate existing keys.
461 DIR* dir = opendir(".");
462 if (!dir) {
463 // Give up now; maybe we can upgrade later.
464 ALOGE("couldn't open keystore's directory; something is wrong");
465 return false;
466 }
467
468 struct dirent* file;
Yi Konge353f252018-07-30 01:38:39 -0700469 while ((file = readdir(dir)) != nullptr) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700470 // We only care about files.
471 if (file->d_type != DT_REG) {
472 continue;
473 }
474
475 // Skip anything that starts with a "."
476 if (file->d_name[0] == '.') {
477 continue;
478 }
479
480 // Find the current file's user.
481 char* end;
482 unsigned long thisUid = strtoul(file->d_name, &end, 10);
483 if (end[0] != '_' || end[1] == 0) {
484 continue;
485 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700486 auto otherUser = getUserStateDB().getUserStateByUid(thisUid);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700487 if (otherUser->getUserId() != 0) {
488 unlinkat(dirfd(dir), file->d_name, 0);
489 }
490
491 // Rename the file into user directory.
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700492 DIR* otherdir = opendir(otherUser->getUserDirName().c_str());
Yi Konge353f252018-07-30 01:38:39 -0700493 if (otherdir == nullptr) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700494 ALOGW("couldn't open user directory for rename");
495 continue;
496 }
497 if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
498 ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
499 }
500 closedir(otherdir);
501 }
502 closedir(dir);
503
504 mMetaData.version = 1;
505 upgraded = true;
506 }
507
508 return upgraded;
Kenny Roota91203b2012-02-15 15:00:46 -0800509}
Shawn Willdenc67a8aa2017-12-03 17:51:29 -0700510
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700511void KeyStore::binderDied(const ::android::wp<IBinder>& who) {
512 for (unsigned i = 0; i < mKmDevices.size(); ++i) {
513 if (mKmDevices[SecurityLevel(i)]) mKmDevices[SecurityLevel(i)]->binderDied(who);
514 }
515 getConfirmationManager().binderDied(who);
Pavel Grafovcef39472018-02-12 18:45:02 +0000516}
517
Shawn Willdenc67a8aa2017-12-03 17:51:29 -0700518} // namespace keystore