1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
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
17 #define LOG_TAG "keystore"
18
19 #include "KeyStore.h"
20
21 #include <dirent.h>
22 #include <fcntl.h>
23
24 #include <openssl/bio.h>
25
26 #include <utils/String16.h>
27 #include <utils/String8.h>
28
29 #include <android-base/scopeguard.h>
30 #include <android/hardware/keymaster/3.0/IKeymasterDevice.h>
31 #include <android/security/keystore/IKeystoreService.h>
32 #include <log/log_event_list.h>
33
34 #include <private/android_logger.h>
35
36 #include "keystore_utils.h"
37 #include "permissions.h"
38 #include <keystore/keystore_hidl_support.h>
39
40 #include "keymaster_worker.h"
41
42 namespace keystore {
43
44 const char* KeyStore::kOldMasterKey = ".masterkey";
45 const char* KeyStore::kMetaDataFile = ".metadata";
46
47 const android::String16 KeyStore::kRsaKeyType("RSA");
48 const android::String16 KeyStore::kEcKeyType("EC");
49
50 using android::String8;
51
KeyStore(const KeymasterDevices & kmDevices,SecurityLevel minimalAllowedSecurityLevelForNewKeys)52 KeyStore::KeyStore(const KeymasterDevices& kmDevices,
53 SecurityLevel minimalAllowedSecurityLevelForNewKeys)
54 : mAllowNewFallback(minimalAllowedSecurityLevelForNewKeys == SecurityLevel::SOFTWARE),
55 mConfirmationManager(new ConfirmationManager(this)) {
56 memset(&mMetaData, '\0', sizeof(mMetaData));
57
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 }
67 }
68
~KeyStore()69 KeyStore::~KeyStore() {
70 }
71
initialize()72 ResponseCode KeyStore::initialize() {
73 readMetaData();
74 if (upgradeKeystore()) {
75 writeMetaData();
76 }
77
78 return ResponseCode::NO_ERROR;
79 }
80
initializeUser(const android::String8 & pw,uid_t userId)81 ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
82 auto userState = mUserStateDB.getUserState(userId);
83 return userState->initialize(pw);
84 }
85
copyMasterKey(uid_t srcUser,uid_t dstUser)86 ResponseCode KeyStore::copyMasterKey(uid_t srcUser, uid_t dstUser) {
87 auto userState = mUserStateDB.getUserState(dstUser);
88 auto initState = mUserStateDB.getUserState(srcUser);
89 return userState->copyMasterKey(&initState);
90 }
91
writeMasterKey(const android::String8 & pw,uid_t userId)92 ResponseCode KeyStore::writeMasterKey(const android::String8& pw, uid_t userId) {
93 auto userState = mUserStateDB.getUserState(userId);
94 return userState->writeMasterKey(pw);
95 }
96
readMasterKey(const android::String8 & pw,uid_t userId)97 ResponseCode KeyStore::readMasterKey(const android::String8& pw, uid_t userId) {
98 auto userState = mUserStateDB.getUserState(userId);
99 return userState->readMasterKey(pw);
100 }
101
getLockedBlobEntryIfNotExists(const std::string & alias,uid_t uid)102 LockedKeyBlobEntry 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;
107 }
108
getBlobEntryIfExists(const std::string & alias,uid_t uid)109 std::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;
112
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) {
116 kbe = KeyBlobEntry(alias, mUserStateDB.getUserStateByUid(euid)->getUserDirName(), euid);
117 if (kbe.hasKeyBlob()) return kbe;
118 }
119
120 // They might be using a granted key.
121 auto grant = mGrants.get(uid, alias);
122 if (grant) {
123 kbe = grant->entry_;
124 if (kbe.hasKeyBlob()) return kbe;
125 }
126 return {};
127 }
getLockedBlobEntryIfExists(const std::string & alias,uid_t uid)128 LockedKeyBlobEntry 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 }
135
resetUser(uid_t userId,bool keepUnenryptedEntries)136 void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
137 android::String8 prefix("");
138 android::Vector<android::String16> aliases;
139
140 auto userState = mUserStateDB.getUserState(userId);
141 std::string userDirName = userState->getUserDirName();
142 auto encryptionKey = userState->getEncryptionKey();
143 auto state = userState->getState();
144 // 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.
147 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) {
156 return;
157 }
158
159 for (LockedKeyBlobEntry& lockedEntry : matches) {
160 bool shouldDelete = true;
161
162 if (keepUnenryptedEntries) {
163 Blob blob;
164 Blob charBlob;
165 ResponseCode rc;
166
167 std::tie(rc, blob, charBlob) = lockedEntry.readBlobs(encryptionKey, state);
168
169 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:
186 ALOGE("Got unexpected return code %d from readBlobs", rc);
187 // This shouldn't happen. To be on the safe side, delete it.
188 shouldDelete = true;
189 break;
190 }
191 }
192 if (shouldDelete) {
193 del(lockedEntry);
194 }
195 }
196
197 userState = mUserStateDB.getUserState(userId);
198 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
isEmpty(uid_t userId) const208 bool KeyStore::isEmpty(uid_t userId) const {
209 std::string userDirName;
210 {
211 // userState holds a lock which must be relinquished before list is called. This scope
212 // prevents deadlocks.
213 auto userState = mUserStateDB.getUserState(userId);
214 if (!userState) {
215 return true;
216 }
217 userDirName = userState->getUserDirName();
218 }
219
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;
228 }
229
lock(uid_t userId)230 void KeyStore::lock(uid_t userId) {
231 auto userState = mUserStateDB.getUserState(userId);
232 userState->zeroizeMasterKeysInMemory();
233 userState->setState(STATE_LOCKED);
234 }
235
maybeLogKeyIntegrityViolation(const LockedKeyBlobEntry & lockedEntry,const BlobType type)236 static 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 }
241
get(const LockedKeyBlobEntry & blobfile)242 std::tuple<ResponseCode, Blob, Blob> KeyStore::get(const LockedKeyBlobEntry& blobfile) {
243 std::tuple<ResponseCode, Blob, Blob> result;
244
245 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;
251 auto logOnScopeExit = android::base::make_scope_guard([&] {
252 if (rc == ResponseCode::VALUE_CORRUPTED) {
253 maybeLogKeyIntegrityViolation(blobfile, type);
254 }
255 });
256
257 result = blobfile.readBlobs(userState->getEncryptionKey(), userState->getState());
258 if (rc != ResponseCode::NO_ERROR) {
259 return result;
260 }
261
262 // update the type for logging (see scope_guard above)
263 type = keyBlob.getType();
264
265 const uint8_t version = keyBlob.getVersion();
266 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 */
271 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;
276 }
277 }
278 }
279
280 return result;
281 }
282
put(const LockedKeyBlobEntry & blobfile,Blob keyBlob,Blob characteristicsBlob)283 ResponseCode 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),
287 userState->getEncryptionKey(), userState->getState());
288 }
289
del(const LockedKeyBlobEntry & blobfile)290 ResponseCode KeyStore::del(const LockedKeyBlobEntry& blobfile) {
291 Blob keyBlob;
292 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
303 if (rc != ResponseCode::NO_ERROR) {
304 LOG(ERROR) << "get keyblob failed " << int(rc);
305 return rc;
306 }
307
308 // if we got the blob successfully, we try and delete it from the keymaster device
309 auto dev = getDevice(keyBlob);
310
311 if (keyBlob.getType() == ::TYPE_KEYMASTER_10) {
312 dev->deleteKey(blob2hidlVec(keyBlob), [dev, alias, uid](Return<ErrorCode> rc) {
313 auto ret = KS_HANDLE_HIDL_ERROR(dev, rc);
314 // 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;
319 }
320 if (!success) {
321 LOG(ERROR) << "Keymaster delete for key " << alias << " of uid " << uid
322 << " failed";
323 }
324 });
325 }
326
327 return result;
328 }
329
addGrant(const LockedKeyBlobEntry & blobfile,uid_t granteeUid)330 std::string KeyStore::addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid) {
331 return mGrants.put(granteeUid, blobfile);
332 }
333
removeGrant(const LockedKeyBlobEntry & blobfile,const uid_t granteeUid)334 bool KeyStore::removeGrant(const LockedKeyBlobEntry& blobfile, const uid_t granteeUid) {
335 return mGrants.removeByFileAlias(granteeUid, blobfile);
336 }
removeAllGrantsToUid(const uid_t granteeUid)337 void KeyStore::removeAllGrantsToUid(const uid_t granteeUid) {
338 mGrants.removeAllGrantsToUid(granteeUid);
339 }
340
isHardwareBacked(const android::String16 & keyType) const341 bool KeyStore::isHardwareBacked(const android::String16& keyType) const {
342 // 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)) {
346 ALOGW("can't get keymaster device");
347 return false;
348 }
349
350 auto version = getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)->halVersion();
351 if (keyType == kRsaKeyType) return true; // All versions support RSA
352 return keyType == kEcKeyType && version.supportsEc;
353 }
354
355 std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry>
getKeyForName(const android::String8 & keyName,const uid_t uid,const BlobType type)356 KeyStore::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;
359
360 lockedEntry = getLockedBlobEntryIfExists(keyName.string(), uid);
361
362 if (!lockedEntry) return rc = ResponseCode::KEY_NOT_FOUND, std::move(result);
363
364 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);
368 }
369 return result;
370 }
371
upgradeBlob(Blob * blob,const uint8_t oldVersion)372 bool KeyStore::upgradeBlob(Blob* blob, const uint8_t oldVersion) {
373 bool updated = false;
374 uint8_t version = oldVersion;
375
376 if (!blob || !(*blob)) return false;
377
378 /* From V0 -> V1: All old types were unknown */
379 if (version == 0) {
380 ALOGE("Failed to upgrade key blob. Ancient blob version 0 is no longer supported");
381
382 return false;
383 }
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;
392 }
393
394 /*
395 * If we've updated, set the key blob to the right version
396 * and write it.
397 */
398 if (updated) {
399 blob->setVersion(version);
400 }
401
402 return updated;
403 }
404
readMetaData()405 void KeyStore::readMetaData() {
406 int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
407 if (in < 0) {
408 return;
409 }
410 size_t fileLength = readFully(in, (uint8_t*)&mMetaData, sizeof(mMetaData));
411 if (fileLength != sizeof(mMetaData)) {
412 ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, sizeof(mMetaData));
413 }
414 close(in);
415 }
416
writeMetaData()417 void KeyStore::writeMetaData() {
418 const char* tmpFileName = ".metadata.tmp";
419 int out =
420 TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
421 if (out < 0) {
422 ALOGE("couldn't write metadata file: %s", strerror(errno));
423 return;
424 }
425 size_t fileLength = writeFully(out, (uint8_t*)&mMetaData, sizeof(mMetaData));
426 if (fileLength != sizeof(mMetaData)) {
427 ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
428 sizeof(mMetaData));
429 }
430 close(out);
431 rename(tmpFileName, kMetaDataFile);
432 }
433
upgradeKeystore()434 bool KeyStore::upgradeKeystore() {
435 bool upgraded = false;
436
437 if (mMetaData.version == 0) {
438 auto userState = getUserStateDB().getUserStateByUid(0);
439
440 // Initialize first so the directory is made.
441 userState->initialize();
442
443 // Migrate the old .masterkey file to user 0.
444 if (access(kOldMasterKey, R_OK) == 0) {
445 if (rename(kOldMasterKey, userState->getMasterKeyFileName().c_str()) < 0) {
446 ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
447 return false;
448 }
449 }
450
451 // Initialize again in case we had a key.
452 userState->initialize();
453
454 // Try to migrate existing keys.
455 DIR* dir = opendir(".");
456 if (!dir) {
457 // Give up now; maybe we can upgrade later.
458 ALOGE("couldn't open keystore's directory; something is wrong");
459 return false;
460 }
461
462 struct dirent* file;
463 while ((file = readdir(dir)) != nullptr) {
464 // We only care about files.
465 if (file->d_type != DT_REG) {
466 continue;
467 }
468
469 // Skip anything that starts with a "."
470 if (file->d_name[0] == '.') {
471 continue;
472 }
473
474 // Find the current file's user.
475 char* end;
476 unsigned long thisUid = strtoul(file->d_name, &end, 10);
477 if (end[0] != '_' || end[1] == 0) {
478 continue;
479 }
480 auto otherUser = getUserStateDB().getUserStateByUid(thisUid);
481 if (otherUser->getUserId() != 0) {
482 unlinkat(dirfd(dir), file->d_name, 0);
483 }
484
485 // Rename the file into user directory.
486 DIR* otherdir = opendir(otherUser->getUserDirName().c_str());
487 if (otherdir == nullptr) {
488 ALOGW("couldn't open user directory for rename");
489 continue;
490 }
491 if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
492 ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
493 }
494 closedir(otherdir);
495 }
496 closedir(dir);
497
498 mMetaData.version = 1;
499 upgraded = true;
500 }
501
502 return upgraded;
503 }
504
binderDied(const::android::wp<IBinder> & who)505 void KeyStore::binderDied(const ::android::wp<IBinder>& who) {
506 for (unsigned i = 0; i < mKmDevices.size(); ++i) {
507 if (mKmDevices[SecurityLevel(i)]) mKmDevices[SecurityLevel(i)]->binderDied(who);
508 }
509 getConfirmationManager().binderDied(who);
510 }
511
512 } // namespace keystore
513