blob: d4219bd6c74529ade231d573833d78832404bd76 [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
Branden Archer44d1afa2018-12-28 09:10:49 -080052KeyStore::KeyStore(const KeymasterDevices& kmDevices,
Janis Danisevskisc1460142017-12-18 16:48:46 -080053 SecurityLevel minimalAllowedSecurityLevelForNewKeys)
Branden Archer44d1afa2018-12-28 09:10:49 -080054 : mAllowNewFallback(minimalAllowedSecurityLevelForNewKeys == SecurityLevel::SOFTWARE),
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070055 mConfirmationManager(new ConfirmationManager(this)) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070056 memset(&mMetaData, '\0', sizeof(mMetaData));
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070057
58 static_assert(std::tuple_size<std::decay_t<decltype(kmDevices)>>::value ==
59 std::tuple_size<decltype(mKmDevices)>::value,
60 "KmasterDevices and KeymasterWorkers must have the same size");
61 for (size_t i = 0; i < kmDevices.size(); ++i) {
62 if (kmDevices[SecurityLevel(i)]) {
63 mKmDevices[SecurityLevel(i)] =
64 std::make_shared<KeymasterWorker>(kmDevices[SecurityLevel(i)], this);
65 }
66 }
Kenny Root70e3a862012-02-15 17:20:23 -080067}
68
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070069KeyStore::~KeyStore() {
Shawn Willden55268b52015-07-28 11:06:00 -060070}
71
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070072ResponseCode KeyStore::initialize() {
73 readMetaData();
74 if (upgradeKeystore()) {
75 writeMetaData();
Shawn Willden55268b52015-07-28 11:06:00 -060076 }
77
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +010078 return ResponseCode::NO_ERROR;
Shawn Willden55268b52015-07-28 11:06:00 -060079}
80
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070081ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070082 auto userState = mUserStateDB.getUserState(userId);
Branden Archer44d1afa2018-12-28 09:10:49 -080083 return userState->initialize(pw);
Chad Brubakerfc18edc2015-01-12 15:17:18 -080084}
85
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070086ResponseCode KeyStore::copyMasterKey(uid_t srcUser, uid_t dstUser) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070087 auto userState = mUserStateDB.getUserState(dstUser);
88 auto initState = mUserStateDB.getUserState(srcUser);
89 return userState->copyMasterKey(&initState);
Kenny Root70e3a862012-02-15 17:20:23 -080090}
91
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070092ResponseCode KeyStore::writeMasterKey(const android::String8& pw, uid_t userId) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070093 auto userState = mUserStateDB.getUserState(userId);
Branden Archer44d1afa2018-12-28 09:10:49 -080094 return userState->writeMasterKey(pw);
Shawn Willden55268b52015-07-28 11:06:00 -060095}
96
Shawn Willdenc1d1fee2016-01-26 22:44:56 -070097ResponseCode KeyStore::readMasterKey(const android::String8& pw, uid_t userId) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -070098 auto userState = mUserStateDB.getUserState(userId);
Branden Archer44d1afa2018-12-28 09:10:49 -080099 return userState->readMasterKey(pw);
Kenny Root49468902013-03-19 13:41:33 -0700100}
101
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700102LockedKeyBlobEntry KeyStore::getLockedBlobEntryIfNotExists(const std::string& alias, uid_t uid) {
103 KeyBlobEntry kbe(alias, mUserStateDB.getUserStateByUid(uid)->getUserDirName(), uid);
104 auto result = LockedKeyBlobEntry::get(std::move(kbe));
105 if (result->hasKeyBlob()) return {};
106 return result;
Kenny Root655b9582013-04-04 08:37:42 -0700107}
108
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700109std::optional<KeyBlobEntry> KeyStore::getBlobEntryIfExists(const std::string& alias, uid_t uid) {
110 KeyBlobEntry kbe(alias, mUserStateDB.getUserStateByUid(uid)->getUserDirName(), uid);
111 if (kbe.hasKeyBlob()) return kbe;
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700112
113 // If this is one of the legacy UID->UID mappings, use it.
114 uid_t euid = get_keystore_euid(uid);
115 if (euid != uid) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700116 kbe = KeyBlobEntry(alias, mUserStateDB.getUserStateByUid(euid)->getUserDirName(), euid);
117 if (kbe.hasKeyBlob()) return kbe;
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700118 }
119
120 // They might be using a granted key.
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700121 auto grant = mGrants.get(uid, alias);
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700122 if (grant) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700123 kbe = grant->entry_;
124 if (kbe.hasKeyBlob()) return kbe;
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700125 }
126 return {};
127}
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700128LockedKeyBlobEntry KeyStore::getLockedBlobEntryIfExists(const std::string& alias, uid_t uid) {
129 auto blobentry = getBlobEntryIfExists(alias, uid);
130 if (!blobentry) return {};
131 LockedKeyBlobEntry lockedentry = LockedKeyBlobEntry::get(std::move(*blobentry));
132 if (!lockedentry || !lockedentry->hasKeyBlob()) return {};
133 return lockedentry;
134}
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700135
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700136void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
137 android::String8 prefix("");
138 android::Vector<android::String16> aliases;
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700139
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700140 auto userState = mUserStateDB.getUserState(userId);
141 std::string userDirName = userState->getUserDirName();
142 auto encryptionKey = userState->getEncryptionKey();
143 auto state = userState->getState();
Janis Danisevskis265435f2018-11-16 14:10:46 -0800144 // userState is a proxy that holds a lock which may be required by a worker.
145 // LockedKeyBlobEntry::list has a fence that waits until all workers have finished which may
146 // not happen if a user state lock is held. The following line relinquishes the lock.
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700147 userState = {};
148
149 ResponseCode rc;
150 std::list<LockedKeyBlobEntry> matches;
151
152 // must not be called by a keymaster worker. List waits for workers to relinquish all access
153 // to blob entries
154 std::tie(rc, matches) = LockedKeyBlobEntry::list(userDirName);
155 if (rc != ResponseCode::NO_ERROR) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700156 return;
157 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700158
159 for (LockedKeyBlobEntry& lockedEntry : matches) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700160 bool shouldDelete = true;
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700161
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700162 if (keepUnenryptedEntries) {
163 Blob blob;
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700164 Blob charBlob;
165 ResponseCode rc;
166
167 std::tie(rc, blob, charBlob) = lockedEntry.readBlobs(encryptionKey, state);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700168
Shawn Willden07aebe72017-02-28 13:53:24 -0700169 switch (rc) {
170 case ResponseCode::SYSTEM_ERROR:
171 case ResponseCode::VALUE_CORRUPTED:
172 // If we can't read blobs, delete them.
173 shouldDelete = true;
174 break;
175
176 case ResponseCode::NO_ERROR:
177 case ResponseCode::LOCKED:
178 // Delete encrypted blobs but keep unencrypted blobs and super-encrypted blobs. We
179 // need to keep super-encrypted blobs so we can report that the user is
180 // unauthenticated if a caller tries to use them, rather than reporting that they
181 // don't exist.
182 shouldDelete = blob.isEncrypted();
183 break;
184
185 default:
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700186 ALOGE("Got unexpected return code %d from readBlobs", rc);
Shawn Willden07aebe72017-02-28 13:53:24 -0700187 // This shouldn't happen. To be on the safe side, delete it.
188 shouldDelete = true;
189 break;
190 }
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700191 }
192 if (shouldDelete) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700193 del(lockedEntry);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700194 }
195 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700196
197 userState = mUserStateDB.getUserState(userId);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700198 if (!userState->deleteMasterKey()) {
199 ALOGE("Failed to delete user %d's master key", userId);
200 }
201 if (!keepUnenryptedEntries) {
202 if (!userState->reset()) {
203 ALOGE("Failed to remove user %d's directory", userId);
204 }
205 }
206}
207
208bool KeyStore::isEmpty(uid_t userId) const {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700209 std::string userDirName;
210 {
Janis Danisevskis265435f2018-11-16 14:10:46 -0800211 // userState holds a lock which must be relinquished before list is called. This scope
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700212 // prevents deadlocks.
213 auto userState = mUserStateDB.getUserState(userId);
214 if (!userState) {
215 return true;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700216 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700217 userDirName = userState->getUserDirName();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700218 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700219
220 ResponseCode rc;
221 std::list<LockedKeyBlobEntry> matches;
222
223 // must not be called by a keymaster worker. List waits for workers to relinquish all access
224 // to blob entries
225 std::tie(rc, matches) = LockedKeyBlobEntry::list(userDirName);
226
227 return rc == ResponseCode::SYSTEM_ERROR || matches.size() == 0;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700228}
229
230void KeyStore::lock(uid_t userId) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700231 auto userState = mUserStateDB.getUserState(userId);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700232 userState->zeroizeMasterKeysInMemory();
233 userState->setState(STATE_LOCKED);
234}
235
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700236static void maybeLogKeyIntegrityViolation(const LockedKeyBlobEntry& lockedEntry,
237 const BlobType type) {
238 if (!__android_log_security() || (type != TYPE_KEY_PAIR && type != TYPE_KEYMASTER_10)) return;
239 log_key_integrity_violation(lockedEntry->alias().c_str(), lockedEntry->uid());
240}
Pavel Grafovcef39472018-02-12 18:45:02 +0000241
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700242std::tuple<ResponseCode, Blob, Blob> KeyStore::get(const LockedKeyBlobEntry& blobfile) {
243 std::tuple<ResponseCode, Blob, Blob> result;
Pavel Grafovcef39472018-02-12 18:45:02 +0000244
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700245 uid_t userId = get_user_id(blobfile->uid());
246 Blob& keyBlob = std::get<1>(result);
247 ResponseCode& rc = std::get<0>(result);
248
249 auto userState = mUserStateDB.getUserState(userId);
250 BlobType type = BlobType::TYPE_ANY;
Pavel Grafovcef39472018-02-12 18:45:02 +0000251 auto logOnScopeExit = android::base::make_scope_guard([&] {
252 if (rc == ResponseCode::VALUE_CORRUPTED) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700253 maybeLogKeyIntegrityViolation(blobfile, type);
Pavel Grafovcef39472018-02-12 18:45:02 +0000254 }
255 });
256
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700257 result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState());
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100258 if (rc != ResponseCode::NO_ERROR) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700259 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700260 }
261
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700262 // update the type for logging (see scope_guard above)
263 type = keyBlob.getType();
264
265 const uint8_t version = keyBlob.getVersion();
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700266 if (version < CURRENT_BLOB_VERSION) {
267 /* If we upgrade the key, we need to write it to disk again. Then
268 * it must be read it again since the blob is encrypted each time
269 * it's written.
270 */
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700271 if (upgradeBlob(&keyBlob, version)) {
272 if ((rc = this->put(blobfile, keyBlob, {})) != ResponseCode::NO_ERROR ||
273 (result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState()),
274 rc) != ResponseCode::NO_ERROR) {
275 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700276 }
277 }
278 }
279
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700280 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700281}
282
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700283ResponseCode KeyStore::put(const LockedKeyBlobEntry& blobfile, Blob keyBlob,
284 Blob characteristicsBlob) {
285 auto userState = mUserStateDB.getUserStateByUid(blobfile->uid());
286 return blobfile.writeBlobs(std::move(keyBlob), std::move(characteristicsBlob),
Branden Archer44d1afa2018-12-28 09:10:49 -0800287 userState->getEncryptionKey(), userState->getState());
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700288}
289
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700290ResponseCode KeyStore::del(const LockedKeyBlobEntry& blobfile) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700291 Blob keyBlob;
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700292 Blob charactaristicsBlob;
293 ResponseCode rc;
294 uid_t uid = blobfile->uid();
295 std::string alias = blobfile->alias();
296
297 std::tie(rc, keyBlob, charactaristicsBlob) = get(blobfile);
298
299 // after getting the blob from the file system we scrub the filesystem.
300 mGrants.removeAllGrantsToKey(uid, alias);
301 auto result = blobfile.deleteBlobs();
302
Janis Danisevskisc7a9fa22016-10-13 18:43:45 +0100303 if (rc != ResponseCode::NO_ERROR) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700304 LOG(ERROR) << "get keyblob failed " << int(rc);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700305 return rc;
306 }
307
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700308 // if we got the blob successfully, we try and delete it from the keymaster device
Janis Danisevskisc1460142017-12-18 16:48:46 -0800309 auto dev = getDevice(keyBlob);
Janis Danisevskis69c434a2017-01-30 10:27:10 +0000310
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700311 if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
Janis Danisevskisa359c672019-03-14 17:15:06 -0700312 dev->deleteKey(blob2hidlVec(keyBlob), [dev, alias, uid](Return<ErrorCode> rc) {
313 auto ret = KS_HANDLE_HIDL_ERROR(dev, rc);
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700314 // A device doesn't have to implement delete_key.
315 bool success = ret == ErrorCode::OK || ret == ErrorCode::UNIMPLEMENTED;
316 if (__android_log_security()) {
317 android_log_event_list(SEC_TAG_KEY_DESTROYED)
318 << int32_t(success) << alias << int32_t(uid) << LOG_ID_SECURITY;
Kenny Root07438c82012-11-02 15:41:02 -0700319 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700320 if (!success) {
321 LOG(ERROR) << "Keymaster delete for key " << alias << " of uid " << uid
322 << " failed";
Chad Brubakerdf705172015-06-17 20:17:51 -0700323 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700324 });
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700325 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700326
327 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700328}
Chad Brubaker3a7d9e62015-06-04 15:01:46 -0700329
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700330std::string KeyStore::addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid) {
331 return mGrants.put(granteeUid, blobfile);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700332}
Chad Brubaker3a7d9e62015-06-04 15:01:46 -0700333
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700334bool KeyStore::removeGrant(const LockedKeyBlobEntry& blobfile, const uid_t granteeUid) {
335 return mGrants.removeByFileAlias(granteeUid, blobfile);
Janis Danisevskis31b44f22017-09-21 11:29:47 -0700336}
337void KeyStore::removeAllGrantsToUid(const uid_t granteeUid) {
338 mGrants.removeAllGrantsToUid(granteeUid);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700339}
Chad Brubaker3a7d9e62015-06-04 15:01:46 -0700340
Shawn Willden0329a822017-12-04 13:55:14 -0700341bool KeyStore::isHardwareBacked(const android::String16& keyType) const {
Janis Danisevskisc1460142017-12-18 16:48:46 -0800342 // if strongbox device is present TEE must also be present and of sufficiently high version
343 // to support all keys in hardware
344 if (getDevice(SecurityLevel::STRONGBOX)) return true;
345 if (!getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700346 ALOGW("can't get keymaster device");
347 return false;
348 }
Janis Danisevskise2b6caf2017-03-02 16:37:10 -0800349
Janis Danisevskisc1460142017-12-18 16:48:46 -0800350 auto version = getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)->halVersion();
Shawn Willden0329a822017-12-04 13:55:14 -0700351 if (keyType == kRsaKeyType) return true; // All versions support RSA
352 return keyType == kEcKeyType && version.supportsEc;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700353}
354
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700355std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry>
356KeyStore::getKeyForName(const android::String8& keyName, const uid_t uid, const BlobType type) {
357 std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry> result;
358 auto& [rc, keyBlob, charBlob, lockedEntry] = result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700359
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700360 lockedEntry = getLockedBlobEntryIfExists(keyName.string(), uid);
Riley Spahneaabae92014-06-30 12:39:52 -0700361
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700362 if (!lockedEntry) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700363
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700364 std::tie(rc, keyBlob, charBlob) = get(lockedEntry);
365
366 if (rc == ResponseCode::NO_ERROR) {
367 if (keyBlob.getType() != type) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700368 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700369 return result;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700370}
371
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700372bool KeyStore::upgradeBlob(Blob* blob, const uint8_t oldVersion) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700373 bool updated = false;
374 uint8_t version = oldVersion;
375
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700376 if (!blob || !(*blob)) return false;
377
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700378 /* From V0 -> V1: All old types were unknown */
379 if (version == 0) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700380 ALOGE("Failed to upgrade key blob. Ancient blob version 0 is no longer supported");
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700381
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700382 return false;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700383 }
384
385 /* From V1 -> V2: All old keys were encrypted */
386 if (version == 1) {
387 ALOGV("upgrading to version 2");
388
389 blob->setEncrypted(true);
390 version = 2;
391 updated = true;
Kenny Roota91203b2012-02-15 15:00:46 -0800392 }
Kenny Root07438c82012-11-02 15:41:02 -0700393
394 /*
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700395 * If we've updated, set the key blob to the right version
396 * and write it.
Kenny Root07438c82012-11-02 15:41:02 -0700397 */
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700398 if (updated) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700399 blob->setVersion(version);
400 }
Kenny Root70e3a862012-02-15 17:20:23 -0800401
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700402 return updated;
403}
404
405struct BIO_Delete {
406 void operator()(BIO* p) const { BIO_free(p); }
407};
Janis Danisevskisccfff102017-05-01 11:02:51 -0700408typedef std::unique_ptr<BIO, BIO_Delete> Unique_BIO;
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700409
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700410void KeyStore::readMetaData() {
Shawn Willden0329a822017-12-04 13:55:14 -0700411 int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700412 if (in < 0) {
413 return;
414 }
415 size_t fileLength = readFully(in, (uint8_t*)&mMetaData, sizeof(mMetaData));
416 if (fileLength != sizeof(mMetaData)) {
417 ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, sizeof(mMetaData));
418 }
419 close(in);
420}
421
422void KeyStore::writeMetaData() {
423 const char* tmpFileName = ".metadata.tmp";
424 int out =
425 TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
426 if (out < 0) {
427 ALOGE("couldn't write metadata file: %s", strerror(errno));
428 return;
429 }
430 size_t fileLength = writeFully(out, (uint8_t*)&mMetaData, sizeof(mMetaData));
431 if (fileLength != sizeof(mMetaData)) {
432 ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
433 sizeof(mMetaData));
434 }
435 close(out);
Shawn Willden0329a822017-12-04 13:55:14 -0700436 rename(tmpFileName, kMetaDataFile);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700437}
438
439bool KeyStore::upgradeKeystore() {
440 bool upgraded = false;
441
442 if (mMetaData.version == 0) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700443 auto userState = getUserStateDB().getUserStateByUid(0);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700444
445 // Initialize first so the directory is made.
446 userState->initialize();
447
448 // Migrate the old .masterkey file to user 0.
Shawn Willden0329a822017-12-04 13:55:14 -0700449 if (access(kOldMasterKey, R_OK) == 0) {
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700450 if (rename(kOldMasterKey, userState->getMasterKeyFileName().c_str()) < 0) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700451 ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
452 return false;
453 }
454 }
455
456 // Initialize again in case we had a key.
457 userState->initialize();
458
459 // Try to migrate existing keys.
460 DIR* dir = opendir(".");
461 if (!dir) {
462 // Give up now; maybe we can upgrade later.
463 ALOGE("couldn't open keystore's directory; something is wrong");
464 return false;
465 }
466
467 struct dirent* file;
Yi Konge353f252018-07-30 01:38:39 -0700468 while ((file = readdir(dir)) != nullptr) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700469 // We only care about files.
470 if (file->d_type != DT_REG) {
471 continue;
472 }
473
474 // Skip anything that starts with a "."
475 if (file->d_name[0] == '.') {
476 continue;
477 }
478
479 // Find the current file's user.
480 char* end;
481 unsigned long thisUid = strtoul(file->d_name, &end, 10);
482 if (end[0] != '_' || end[1] == 0) {
483 continue;
484 }
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700485 auto otherUser = getUserStateDB().getUserStateByUid(thisUid);
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700486 if (otherUser->getUserId() != 0) {
487 unlinkat(dirfd(dir), file->d_name, 0);
488 }
489
490 // Rename the file into user directory.
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700491 DIR* otherdir = opendir(otherUser->getUserDirName().c_str());
Yi Konge353f252018-07-30 01:38:39 -0700492 if (otherdir == nullptr) {
Shawn Willdenc1d1fee2016-01-26 22:44:56 -0700493 ALOGW("couldn't open user directory for rename");
494 continue;
495 }
496 if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
497 ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
498 }
499 closedir(otherdir);
500 }
501 closedir(dir);
502
503 mMetaData.version = 1;
504 upgraded = true;
505 }
506
507 return upgraded;
Kenny Roota91203b2012-02-15 15:00:46 -0800508}
Shawn Willdenc67a8aa2017-12-03 17:51:29 -0700509
Janis Danisevskisff3d7f42018-10-08 07:15:09 -0700510void KeyStore::binderDied(const ::android::wp<IBinder>& who) {
511 for (unsigned i = 0; i < mKmDevices.size(); ++i) {
512 if (mKmDevices[SecurityLevel(i)]) mKmDevices[SecurityLevel(i)]->binderDied(who);
513 }
514 getConfirmationManager().binderDied(who);
Pavel Grafovcef39472018-02-12 18:45:02 +0000515}
516
Shawn Willdenc67a8aa2017-12-03 17:51:29 -0700517} // namespace keystore