blob: 753024353c00f9167a267365a7e125b60144b457 [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
141 // DO NOT
142 // move
143 // auto userState = userStateDB_.getUserState(userId);
144 // here, in an attempt to replace userStateDB_.getUserState(userId) with userState.
145 // userState is a proxy that holds a lock which may 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 only briefly grabs the lock.
148 // Grabbing the user state lock after the list call is also save since workers cannot grab
149 // blob entry locks.
150
151 auto userState = mUserStateDB.getUserState(userId);
152 std::string userDirName = userState->getUserDirName();
153 auto encryptionKey = userState->getEncryptionKey();
154 auto state = userState->getState();
155 // unlock the user state
156 userState = {};
157
158 ResponseCode rc;
159 std::list<LockedKeyBlobEntry> matches;
160
161 // must not be called by a keymaster worker. List waits for workers to relinquish all access
162 // to blob entries
163 std::tie(rc, matches) = LockedKeyBlobEntry::list(userDirName);
164 if (rc != ResponseCode::NO_ERROR) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700165 return;
166 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700167
168 for (LockedKeyBlobEntry& lockedEntry : matches) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700169 bool shouldDelete = true;
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700170
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700171 if (keepUnenryptedEntries) {
172 Blob blob;
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700173 Blob charBlob;
174 ResponseCode rc;
175
176 std::tie(rc, blob, charBlob) = lockedEntry.readBlobs(encryptionKey, state);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700177
Shawn Willden07aebe72017-02-28 13:53:24 -0700178 switch (rc) {
179 case ResponseCode::SYSTEM_ERROR:
180 case ResponseCode::VALUE_CORRUPTED:
181 // If we can't read blobs, delete them.
182 shouldDelete = true;
183 break;
184
185 case ResponseCode::NO_ERROR:
186 case ResponseCode::LOCKED:
187 // Delete encrypted blobs but keep unencrypted blobs and super-encrypted blobs. We
188 // need to keep super-encrypted blobs so we can report that the user is
189 // unauthenticated if a caller tries to use them, rather than reporting that they
190 // don't exist.
191 shouldDelete = blob.isEncrypted();
192 break;
193
194 default:
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700195 ALOGE("Got unexpected return code %d from readBlobs", rc);
Shawn Willden07aebe72017-02-28 13:53:24 -0700196 // This shouldn't happen. To be on the safe side, delete it.
197 shouldDelete = true;
198 break;
199 }
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700200 }
201 if (shouldDelete) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700202 del(lockedEntry);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700203 }
204 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700205
206 userState = mUserStateDB.getUserState(userId);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700207 if (!userState->deleteMasterKey()) {
208 ALOGE("Failed to delete user %d's master key", userId);
209 }
210 if (!keepUnenryptedEntries) {
211 if (!userState->reset()) {
212 ALOGE("Failed to remove user %d's directory", userId);
213 }
214 }
215}
216
217bool KeyStore::isEmpty(uid_t userId) const {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700218 std::string userDirName;
219 {
220 // userState hold a lock which must be relinqhished before list is called. This scope
221 // prevents deadlocks.
222 auto userState = mUserStateDB.getUserState(userId);
223 if (!userState) {
224 return true;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700225 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700226 userDirName = userState->getUserDirName();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700227 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700228
229 ResponseCode rc;
230 std::list<LockedKeyBlobEntry> matches;
231
232 // must not be called by a keymaster worker. List waits for workers to relinquish all access
233 // to blob entries
234 std::tie(rc, matches) = LockedKeyBlobEntry::list(userDirName);
235
236 return rc == ResponseCode::SYSTEM_ERROR || matches.size() == 0;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700237}
238
239void KeyStore::lock(uid_t userId) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700240 auto userState = mUserStateDB.getUserState(userId);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700241 userState->zeroizeMasterKeysInMemory();
242 userState->setState(STATE_LOCKED);
243}
244
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700245static void maybeLogKeyIntegrityViolation(const LockedKeyBlobEntry& lockedEntry,
246 const BlobType type) {
247 if (!__android_log_security() || (type != TYPE_KEY_PAIR && type != TYPE_KEYMASTER_10)) return;
248 log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
249}
Pavel Grafovcef39472018-02-12 18:45:02 +0000250
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700251std::tuple<ResponseCode, Blob, Blob> KeyStore::get(const LockedKeyBlobEntry& blobfile) {
252 std::tuple<ResponseCode, Blob, Blob> result;
Pavel Grafovcef39472018-02-12 18:45:02 +0000253
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700254 uid_t userId = get_user_id(blobfile->uid());
255 Blob& keyBlob = std::get<1>(result);
256 ResponseCode& rc = std::get<0>(result);
257
258 auto userState = mUserStateDB.getUserState(userId);
259 BlobType type = BlobType::TYPE_ANY;
Pavel Grafovcef39472018-02-12 18:45:02 +0000260 auto logOnScopeExit = android::base::make_scope_guard([&] {
261 if (rc == ResponseCode::VALUE_CORRUPTED) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700262 maybeLogKeyIntegrityViolation(blobfile, type);
Pavel Grafovcef39472018-02-12 18:45:02 +0000263 }
264 });
265
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700266 result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100267 if (rc != ResponseCode::NO_ERROR) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700268 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700269 }
270
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700271 // update the type for logging (see scope_guard above)
272 type = keyBlob.getType();
273
274 const uint8_t version = keyBlob.getVersion();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700275 if (version < CURRENT_BLOB_VERSION) {
276 /* If we upgrade the key, we need to write it to disk again. Then
277 * it must be read it again since the blob is encrypted each time
278 * it's written.
279 */
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700280 if (upgradeBlob(&keyBlob, version)) {
281 if ((rc = this->put(blobfile, keyBlob, {})) != ResponseCode::NO_ERROR ||
282 (result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState()),
283 rc) != ResponseCode::NO_ERROR) {
284 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700285 }
286 }
287 }
288
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700289 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700290}
291
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700292ResponseCode KeyStore::put(const LockedKeyBlobEntry& blobfile, Blob keyBlob,
293 Blob characteristicsBlob) {
294 auto userState = mUserStateDB.getUserStateByUid(blobfile->uid());
295 return blobfile.writeBlobs(std::move(keyBlob), std::move(characteristicsBlob),
296 userState->getEncryptionKey(), userState->getState(), mEntropy);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700297}
298
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700299ResponseCode KeyStore::del(const LockedKeyBlobEntry& blobfile) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700300 Blob keyBlob;
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700301 Blob charactaristicsBlob;
302 ResponseCode rc;
303 uid_t uid = blobfile->uid();
304 std::string alias = blobfile->alias();
305
306 std::tie(rc, keyBlob, charactaristicsBlob) = get(blobfile);
307
308 // after getting the blob from the file system we scrub the filesystem.
309 mGrants.removeAllGrantsToKey(uid, alias);
310 auto result = blobfile.deleteBlobs();
311
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100312 if (rc != ResponseCode::NO_ERROR) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700313 LOG(ERROR) << "get keyblob failed " << int(rc);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700314 return rc;
315 }
316
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700317 // if we got the blob successfully, we try and delete it from the keymaster device
Janis Danisevskisc1460142017-12-18 16:48:46 -0800318 auto dev = getDevice(keyBlob);
Janis Danisevskis69c434a2017-01-30 10:27:10 +0000319
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700320 if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
321 dev->deleteKey(blob2hidlVec(keyBlob), [alias, uid](Return<ErrorCode> rc) {
322 auto ret = KS_HANDLE_HIDL_ERROR(rc);
323 // A device doesn't have to implement delete_key.
324 bool success = ret == ErrorCode::OK || ret == ErrorCode::UNIMPLEMENTED;
325 if (__android_log_security()) {
326 android_log_event_list(SEC_TAG_KEY_DESTROYED)
327 << int32_t(success) << alias << int32_t(uid) << LOG_ID_SECURITY;
Kenny Root07438c82012-11-02 15:41:02 -0700328 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700329 if (!success) {
330 LOG(ERROR) << "Keymaster delete for key " << alias << " of uid " << uid
331 << " failed";
Chad Brubakerdf705172015-06-17 20:17:51 -0700332 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700333 });
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700334 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700335
336 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700337}
Chad Brubaker3a7d9e62015-06-04 15:01:46 -0700338
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700339std::string KeyStore::addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid) {
340 return mGrants.put(granteeUid, blobfile);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700341}
Chad Brubaker3a7d9e62015-06-04 15:01:46 -0700342
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700343bool KeyStore::removeGrant(const LockedKeyBlobEntry& blobfile, const uid_t granteeUid) {
344 return mGrants.removeByFileAlias(granteeUid, blobfile);
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700345}
346void KeyStore::removeAllGrantsToUid(const uid_t granteeUid) {
347 mGrants.removeAllGrantsToUid(granteeUid);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700348}
Chad Brubaker3a7d9e62015-06-04 15:01:46 -0700349
Shawn Willden0329a822017-12-04 13:55:14 -0700350bool KeyStore::isHardwareBacked(const android::String16& keyType) const {
Janis Danisevskisc1460142017-12-18 16:48:46 -0800351 // if strongbox device is present TEE must also be present and of sufficiently high version
352 // to support all keys in hardware
353 if (getDevice(SecurityLevel::STRONGBOX)) return true;
354 if (!getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700355 ALOGW("can't get keymaster device");
356 return false;
357 }
Janis Danisevskise2b6caf2017-03-02 16:37:10 -0800358
Janis Danisevskisc1460142017-12-18 16:48:46 -0800359 auto version = getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)->halVersion();
Shawn Willden0329a822017-12-04 13:55:14 -0700360 if (keyType == kRsaKeyType) return true; // All versions support RSA
361 return keyType == kEcKeyType && version.supportsEc;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700362}
363
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700364std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry>
365KeyStore::getKeyForName(const android::String8& keyName, const uid_t uid, const BlobType type) {
366 std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry> result;
367 auto& [rc, keyBlob, charBlob, lockedEntry] = result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700368
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700369 lockedEntry = getLockedBlobEntryIfExists(keyName.string(), uid);
Riley Spahneaabae92014-06-30 12:39:52 -0700370
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700371 if (!lockedEntry) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700372
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700373 std::tie(rc, keyBlob, charBlob) = get(lockedEntry);
374
375 if (rc == ResponseCode::NO_ERROR) {
376 if (keyBlob.getType() != type) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700377 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700378 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700379}
380
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700381bool KeyStore::upgradeBlob(Blob* blob, const uint8_t oldVersion) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700382 bool updated = false;
383 uint8_t version = oldVersion;
384
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700385 if (!blob || !(*blob)) return false;
386
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700387 /* From V0 -> V1: All old types were unknown */
388 if (version == 0) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700389 ALOGE("Failed to upgrade key blob. Ancient blob version 0 is no longer supported");
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700390
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700391 return false;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700392 }
393
394 /* From V1 -> V2: All old keys were encrypted */
395 if (version == 1) {
396 ALOGV("upgrading to version 2");
397
398 blob->setEncrypted(true);
399 version = 2;
400 updated = true;
Kenny Roota91203b2012-02-15 15:00:46 -0800401 }
Kenny Root07438c82012-11-02 15:41:02 -0700402
403 /*
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700404 * If we've updated, set the key blob to the right version
405 * and write it.
Kenny Root07438c82012-11-02 15:41:02 -0700406 */
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700407 if (updated) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700408 blob->setVersion(version);
409 }
Kenny Root70e3a862012-02-15 17:20:23 -0800410
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700411 return updated;
412}
413
414struct BIO_Delete {
415 void operator()(BIO* p) const { BIO_free(p); }
416};
Janis Danisevskisccfff102017-05-01 11:02:51 -0700417typedef std::unique_ptr<BIO, BIO_Delete> Unique_BIO;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700418
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700419void KeyStore::readMetaData() {
Shawn Willden0329a822017-12-04 13:55:14 -0700420 int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700421 if (in < 0) {
422 return;
423 }
424 size_t fileLength = readFully(in, (uint8_t*)&mMetaData, sizeof(mMetaData));
425 if (fileLength != sizeof(mMetaData)) {
426 ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, sizeof(mMetaData));
427 }
428 close(in);
429}
430
431void KeyStore::writeMetaData() {
432 const char* tmpFileName = ".metadata.tmp";
433 int out =
434 TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
435 if (out < 0) {
436 ALOGE("couldn't write metadata file: %s", strerror(errno));
437 return;
438 }
439 size_t fileLength = writeFully(out, (uint8_t*)&mMetaData, sizeof(mMetaData));
440 if (fileLength != sizeof(mMetaData)) {
441 ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
442 sizeof(mMetaData));
443 }
444 close(out);
Shawn Willden0329a822017-12-04 13:55:14 -0700445 rename(tmpFileName, kMetaDataFile);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700446}
447
448bool KeyStore::upgradeKeystore() {
449 bool upgraded = false;
450
451 if (mMetaData.version == 0) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700452 auto userState = getUserStateDB().getUserStateByUid(0);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700453
454 // Initialize first so the directory is made.
455 userState->initialize();
456
457 // Migrate the old .masterkey file to user 0.
Shawn Willden0329a822017-12-04 13:55:14 -0700458 if (access(kOldMasterKey, R_OK) == 0) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700459 if (rename(kOldMasterKey, userState->getMasterKeyFileName().c_str()) < 0) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700460 ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
461 return false;
462 }
463 }
464
465 // Initialize again in case we had a key.
466 userState->initialize();
467
468 // Try to migrate existing keys.
469 DIR* dir = opendir(".");
470 if (!dir) {
471 // Give up now; maybe we can upgrade later.
472 ALOGE("couldn't open keystore's directory; something is wrong");
473 return false;
474 }
475
476 struct dirent* file;
Yi Konge353f252018-07-30 01:38:39 -0700477 while ((file = readdir(dir)) != nullptr) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700478 // We only care about files.
479 if (file->d_type != DT_REG) {
480 continue;
481 }
482
483 // Skip anything that starts with a "."
484 if (file->d_name[0] == '.') {
485 continue;
486 }
487
488 // Find the current file's user.
489 char* end;
490 unsigned long thisUid = strtoul(file->d_name, &end, 10);
491 if (end[0] != '_' || end[1] == 0) {
492 continue;
493 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700494 auto otherUser = getUserStateDB().getUserStateByUid(thisUid);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700495 if (otherUser->getUserId() != 0) {
496 unlinkat(dirfd(dir), file->d_name, 0);
497 }
498
499 // Rename the file into user directory.
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700500 DIR* otherdir = opendir(otherUser->getUserDirName().c_str());
Yi Konge353f252018-07-30 01:38:39 -0700501 if (otherdir == nullptr) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700502 ALOGW("couldn't open user directory for rename");
503 continue;
504 }
505 if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
506 ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
507 }
508 closedir(otherdir);
509 }
510 closedir(dir);
511
512 mMetaData.version = 1;
513 upgraded = true;
514 }
515
516 return upgraded;
Kenny Roota91203b2012-02-15 15:00:46 -0800517}
Shawn Willdenc67a8aa2017-12-03 17:51:29 -0700518
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700519void KeyStore::binderDied(const ::android::wp<IBinder>& who) {
520 for (unsigned i = 0; i < mKmDevices.size(); ++i) {
521 if (mKmDevices[SecurityLevel(i)]) mKmDevices[SecurityLevel(i)]->binderDied(who);
522 }
523 getConfirmationManager().binderDied(who);
Pavel Grafovcef39472018-02-12 18:45:02 +0000524}
525
Shawn Willdenc67a8aa2017-12-03 17:51:29 -0700526} // namespace keystore