• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
405 struct BIO_Delete {
operator ()keystore::BIO_Delete406     void operator()(BIO* p) const { BIO_free(p); }
407 };
408 typedef std::unique_ptr<BIO, BIO_Delete> Unique_BIO;
409 
readMetaData()410 void KeyStore::readMetaData() {
411     int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
412     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 
writeMetaData()422 void 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);
436     rename(tmpFileName, kMetaDataFile);
437 }
438 
upgradeKeystore()439 bool KeyStore::upgradeKeystore() {
440     bool upgraded = false;
441 
442     if (mMetaData.version == 0) {
443         auto userState = getUserStateDB().getUserStateByUid(0);
444 
445         // Initialize first so the directory is made.
446         userState->initialize();
447 
448         // Migrate the old .masterkey file to user 0.
449         if (access(kOldMasterKey, R_OK) == 0) {
450             if (rename(kOldMasterKey, userState->getMasterKeyFileName().c_str()) < 0) {
451                 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;
468         while ((file = readdir(dir)) != nullptr) {
469             // 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             }
485             auto otherUser = getUserStateDB().getUserStateByUid(thisUid);
486             if (otherUser->getUserId() != 0) {
487                 unlinkat(dirfd(dir), file->d_name, 0);
488             }
489 
490             // Rename the file into user directory.
491             DIR* otherdir = opendir(otherUser->getUserDirName().c_str());
492             if (otherdir == nullptr) {
493                 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;
508 }
509 
binderDied(const::android::wp<IBinder> & who)510 void 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);
515 }
516 
517 }  // namespace keystore
518