• 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/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 namespace keystore {
41 
42 const char* KeyStore::kOldMasterKey = ".masterkey";
43 const char* KeyStore::kMetaDataFile = ".metadata";
44 
45 const android::String16 KeyStore::kRsaKeyType("RSA");
46 const android::String16 KeyStore::kEcKeyType("EC");
47 
48 using android::String8;
49 
operator [](SecurityLevel secLevel)50 sp<Keymaster>& KeymasterDevices::operator[](SecurityLevel secLevel) {
51     static_assert(uint32_t(SecurityLevel::SOFTWARE) == 0 &&
52                       uint32_t(SecurityLevel::TRUSTED_ENVIRONMENT) == 1 &&
53                       uint32_t(SecurityLevel::STRONGBOX) == 2,
54                   "Numeric values of security levels have changed");
55     return at(static_cast<uint32_t>(secLevel));
56 }
57 
operator [](SecurityLevel secLevel) const58 sp<Keymaster> KeymasterDevices::operator[](SecurityLevel secLevel) const {
59     if (static_cast<uint32_t>(secLevel) > static_cast<uint32_t>(SecurityLevel::STRONGBOX)) {
60         LOG(ERROR) << "Invalid security level requested";
61         return nullptr;
62     }
63     return (*const_cast<KeymasterDevices*>(this))[secLevel];
64 }
65 
KeyStore(Entropy * entropy,const KeymasterDevices & kmDevices,SecurityLevel minimalAllowedSecurityLevelForNewKeys)66 KeyStore::KeyStore(Entropy* entropy, const KeymasterDevices& kmDevices,
67                    SecurityLevel minimalAllowedSecurityLevelForNewKeys)
68     : mEntropy(entropy), mKmDevices(kmDevices),
69       mAllowNewFallback(minimalAllowedSecurityLevelForNewKeys == SecurityLevel::SOFTWARE) {
70     memset(&mMetaData, '\0', sizeof(mMetaData));
71 }
72 
~KeyStore()73 KeyStore::~KeyStore() {
74     for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); it != mMasterKeys.end();
75          it++) {
76         delete *it;
77     }
78     mMasterKeys.clear();
79 }
80 
initialize()81 ResponseCode KeyStore::initialize() {
82     readMetaData();
83     if (upgradeKeystore()) {
84         writeMetaData();
85     }
86 
87     return ResponseCode::NO_ERROR;
88 }
89 
initializeUser(const android::String8 & pw,uid_t userId)90 ResponseCode KeyStore::initializeUser(const android::String8& pw, uid_t userId) {
91     UserState* userState = getUserState(userId);
92     return userState->initialize(pw, mEntropy);
93 }
94 
copyMasterKey(uid_t srcUser,uid_t dstUser)95 ResponseCode KeyStore::copyMasterKey(uid_t srcUser, uid_t dstUser) {
96     UserState* userState = getUserState(dstUser);
97     UserState* initState = getUserState(srcUser);
98     return userState->copyMasterKey(initState);
99 }
100 
writeMasterKey(const android::String8 & pw,uid_t userId)101 ResponseCode KeyStore::writeMasterKey(const android::String8& pw, uid_t userId) {
102     UserState* userState = getUserState(userId);
103     return userState->writeMasterKey(pw, mEntropy);
104 }
105 
readMasterKey(const android::String8 & pw,uid_t userId)106 ResponseCode KeyStore::readMasterKey(const android::String8& pw, uid_t userId) {
107     UserState* userState = getUserState(userId);
108     return userState->readMasterKey(pw, mEntropy);
109 }
110 
111 /* Here is the encoding of keys. This is necessary in order to allow arbitrary
112  * characters in keys. Characters in [0-~] are not encoded. Others are encoded
113  * into two bytes. The first byte is one of [+-.] which represents the first
114  * two bits of the character. The second byte encodes the rest of the bits into
115  * [0-o]. Therefore in the worst case the length of a key gets doubled. Note
116  * that Base64 cannot be used here due to the need of prefix match on keys. */
117 
encode_key_length(const android::String8 & keyName)118 static size_t encode_key_length(const android::String8& keyName) {
119     const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
120     size_t length = keyName.length();
121     for (int i = length; i > 0; --i, ++in) {
122         if (*in < '0' || *in > '~') {
123             ++length;
124         }
125     }
126     return length;
127 }
128 
encode_key(char * out,const android::String8 & keyName)129 static int encode_key(char* out, const android::String8& keyName) {
130     const uint8_t* in = reinterpret_cast<const uint8_t*>(keyName.string());
131     size_t length = keyName.length();
132     for (int i = length; i > 0; --i, ++in, ++out) {
133         if (*in < '0' || *in > '~') {
134             *out = '+' + (*in >> 6);
135             *++out = '0' + (*in & 0x3F);
136             ++length;
137         } else {
138             *out = *in;
139         }
140     }
141     *out = '\0';
142     return length;
143 }
144 
getKeyName(const android::String8 & keyName,const BlobType type)145 android::String8 KeyStore::getKeyName(const android::String8& keyName, const BlobType type) {
146     std::vector<char> encoded(encode_key_length(keyName) + 1);  // add 1 for null char
147     encode_key(encoded.data(), keyName);
148     if (type == TYPE_KEY_CHARACTERISTICS) {
149         return android::String8::format(".chr_%s", encoded.data());
150     } else {
151         return android::String8(encoded.data());
152     }
153 }
154 
getKeyNameForUid(const android::String8 & keyName,uid_t uid,const BlobType type)155 android::String8 KeyStore::getKeyNameForUid(const android::String8& keyName, uid_t uid,
156                                             const BlobType type) {
157     std::vector<char> encoded(encode_key_length(keyName) + 1);  // add 1 for null char
158     encode_key(encoded.data(), keyName);
159     if (type == TYPE_KEY_CHARACTERISTICS) {
160         return android::String8::format(".%u_chr_%s", uid, encoded.data());
161     } else {
162         return android::String8::format("%u_%s", uid, encoded.data());
163     }
164 }
165 
getKeyNameForUidWithDir(const android::String8 & keyName,uid_t uid,const BlobType type)166 android::String8 KeyStore::getKeyNameForUidWithDir(const android::String8& keyName, uid_t uid,
167                                                    const BlobType type) {
168     std::vector<char> encoded(encode_key_length(keyName) + 1);  // add 1 for null char
169     encode_key(encoded.data(), keyName);
170 
171     if (type == TYPE_KEY_CHARACTERISTICS) {
172         return android::String8::format("%s/.%u_chr_%s", getUserStateByUid(uid)->getUserDirName(),
173                                         uid, encoded.data());
174     } else {
175         return android::String8::format("%s/%u_%s", getUserStateByUid(uid)->getUserDirName(), uid,
176                                         encoded.data());
177     }
178 }
179 
getBlobFileNameIfExists(const android::String8 & alias,uid_t uid,const BlobType type)180 NullOr<android::String8> KeyStore::getBlobFileNameIfExists(const android::String8& alias, uid_t uid,
181                                                            const BlobType type) {
182     android::String8 filepath8(getKeyNameForUidWithDir(alias, uid, type));
183 
184     if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
185 
186     // If this is one of the legacy UID->UID mappings, use it.
187     uid_t euid = get_keystore_euid(uid);
188     if (euid != uid) {
189         filepath8 = getKeyNameForUidWithDir(alias, euid, type);
190         if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
191     }
192 
193     // They might be using a granted key.
194     auto grant = mGrants.get(uid, alias.string());
195     if (grant) {
196         filepath8 = String8::format(
197             "%s/%s", grant->owner_dir_name_.c_str(),
198             getKeyNameForUid(String8(grant->alias_.c_str()), grant->owner_uid_, type).c_str());
199         if (!access(filepath8.string(), R_OK | W_OK)) return filepath8;
200     }
201     return {};
202 }
203 
resetUser(uid_t userId,bool keepUnenryptedEntries)204 void KeyStore::resetUser(uid_t userId, bool keepUnenryptedEntries) {
205     android::String8 prefix("");
206     android::Vector<android::String16> aliases;
207     UserState* userState = getUserState(userId);
208     if (list(prefix, &aliases, userId) != ResponseCode::NO_ERROR) {
209         return;
210     }
211     for (uint32_t i = 0; i < aliases.size(); i++) {
212         android::String8 filename(aliases[i]);
213         filename = android::String8::format("%s/%s", userState->getUserDirName(),
214                                             getKeyName(filename, TYPE_ANY).string());
215         bool shouldDelete = true;
216         if (keepUnenryptedEntries) {
217             Blob blob;
218             ResponseCode rc = get(filename, &blob, ::TYPE_ANY, userId);
219 
220             switch (rc) {
221             case ResponseCode::SYSTEM_ERROR:
222             case ResponseCode::VALUE_CORRUPTED:
223                 // If we can't read blobs, delete them.
224                 shouldDelete = true;
225                 break;
226 
227             case ResponseCode::NO_ERROR:
228             case ResponseCode::LOCKED:
229                 // Delete encrypted blobs but keep unencrypted blobs and super-encrypted blobs.  We
230                 // need to keep super-encrypted blobs so we can report that the user is
231                 // unauthenticated if a caller tries to use them, rather than reporting that they
232                 // don't exist.
233                 shouldDelete = blob.isEncrypted();
234                 break;
235 
236             default:
237                 ALOGE("Got unexpected return code %d from KeyStore::get()", rc);
238                 // This shouldn't happen.  To be on the safe side, delete it.
239                 shouldDelete = true;
240                 break;
241             }
242         }
243         if (shouldDelete) {
244             del(filename, ::TYPE_ANY, userId);
245 
246             // del() will fail silently if no cached characteristics are present for this alias.
247             android::String8 chr_filename(aliases[i]);
248             chr_filename = android::String8::format(
249                 "%s/%s", userState->getUserDirName(),
250                 getKeyName(chr_filename, TYPE_KEY_CHARACTERISTICS).string());
251             del(chr_filename, ::TYPE_KEY_CHARACTERISTICS, userId);
252         }
253     }
254     if (!userState->deleteMasterKey()) {
255         ALOGE("Failed to delete user %d's master key", userId);
256     }
257     if (!keepUnenryptedEntries) {
258         if (!userState->reset()) {
259             ALOGE("Failed to remove user %d's directory", userId);
260         }
261     }
262 }
263 
isEmpty(uid_t userId) const264 bool KeyStore::isEmpty(uid_t userId) const {
265     const UserState* userState = getUserState(userId);
266     if (userState == NULL) {
267         return true;
268     }
269 
270     DIR* dir = opendir(userState->getUserDirName());
271     if (!dir) {
272         return true;
273     }
274 
275     bool result = true;
276     struct dirent* file;
277     while ((file = readdir(dir)) != NULL) {
278         // We only care about files.
279         if (file->d_type != DT_REG) {
280             continue;
281         }
282 
283         // Skip anything that starts with a "."
284         if (file->d_name[0] == '.') {
285             continue;
286         }
287 
288         result = false;
289         break;
290     }
291     closedir(dir);
292     return result;
293 }
294 
lock(uid_t userId)295 void KeyStore::lock(uid_t userId) {
296     UserState* userState = getUserState(userId);
297     userState->zeroizeMasterKeysInMemory();
298     userState->setState(STATE_LOCKED);
299 }
300 
301 static void maybeLogKeyIntegrityViolation(const char* filename, const BlobType type);
302 
get(const char * filename,Blob * keyBlob,const BlobType type,uid_t userId)303 ResponseCode KeyStore::get(const char* filename, Blob* keyBlob, const BlobType type, uid_t userId) {
304     UserState* userState = getUserState(userId);
305     ResponseCode rc;
306 
307     auto logOnScopeExit = android::base::make_scope_guard([&] {
308         if (rc == ResponseCode::VALUE_CORRUPTED) {
309             maybeLogKeyIntegrityViolation(filename, type);
310         }
311     });
312 
313     rc = keyBlob->readBlob(filename, userState->getEncryptionKey(), userState->getState());
314     if (rc != ResponseCode::NO_ERROR) {
315         return rc;
316     }
317 
318     const uint8_t version = keyBlob->getVersion();
319     if (version < CURRENT_BLOB_VERSION) {
320         /* If we upgrade the key, we need to write it to disk again. Then
321          * it must be read it again since the blob is encrypted each time
322          * it's written.
323          */
324         if (upgradeBlob(filename, keyBlob, version, type, userId)) {
325             if ((rc = this->put(filename, keyBlob, userId)) != ResponseCode::NO_ERROR ||
326                 (rc = keyBlob->readBlob(filename, userState->getEncryptionKey(),
327                                         userState->getState())) != ResponseCode::NO_ERROR) {
328                 return rc;
329             }
330         }
331     }
332 
333     /*
334      * This will upgrade software-backed keys to hardware-backed keys.
335      */
336     if (rc == ResponseCode::NO_ERROR && type == TYPE_KEY_PAIR && keyBlob->isFallback()) {
337         ResponseCode imported =
338             importKey(keyBlob->getValue(), keyBlob->getLength(), filename, userId,
339                       keyBlob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
340 
341         // The HAL allowed the import, reget the key to have the "fresh" version.
342         if (imported == ResponseCode::NO_ERROR) {
343             rc = get(filename, keyBlob, TYPE_KEY_PAIR, userId);
344         }
345     }
346 
347     // Keymaster 0.3 keys are valid keymaster 1.0 keys, so silently upgrade.
348     if (keyBlob->getType() == TYPE_KEY_PAIR) {
349         keyBlob->setType(TYPE_KEYMASTER_10);
350         rc = this->put(filename, keyBlob, userId);
351     }
352 
353     if (type != TYPE_ANY && keyBlob->getType() != type) {
354         ALOGW("key found but type doesn't match: %d vs %d", keyBlob->getType(), type);
355         return ResponseCode::KEY_NOT_FOUND;
356     }
357 
358     return rc;
359 }
360 
put(const char * filename,Blob * keyBlob,uid_t userId)361 ResponseCode KeyStore::put(const char* filename, Blob* keyBlob, uid_t userId) {
362     UserState* userState = getUserState(userId);
363     return keyBlob->writeBlob(filename, userState->getEncryptionKey(), userState->getState(),
364                               mEntropy);
365 }
366 
367 static NullOr<std::tuple<uid_t, std::string>> filename2UidAlias(const std::string& filename);
368 
del(const char * filename,const BlobType type,uid_t userId)369 ResponseCode KeyStore::del(const char* filename, const BlobType type, uid_t userId) {
370     Blob keyBlob;
371     auto uidAlias = filename2UidAlias(filename);
372     uid_t uid;
373     std::string alias;
374     if (uidAlias.isOk()) {
375         std::tie(uid, alias) = std::move(uidAlias).value();
376     }
377     ResponseCode rc = get(filename, &keyBlob, type, userId);
378     if (rc == ResponseCode::VALUE_CORRUPTED) {
379         // The file is corrupt, the best we can do is rm it.
380         if (uidAlias.isOk()) {
381             // remove possible grants
382             mGrants.removeAllGrantsToKey(uid, alias);
383         }
384         return (unlink(filename) && errno != ENOENT) ? ResponseCode::SYSTEM_ERROR
385                                                      : ResponseCode::NO_ERROR;
386     }
387     if (rc != ResponseCode::NO_ERROR) {
388         return rc;
389     }
390 
391     auto dev = getDevice(keyBlob);
392 
393     if (keyBlob.getType() == ::TYPE_KEY_PAIR || keyBlob.getType() == ::TYPE_KEYMASTER_10) {
394         auto ret = KS_HANDLE_HIDL_ERROR(dev->deleteKey(blob2hidlVec(keyBlob)));
395 
396         // A device doesn't have to implement delete_key.
397         bool success = ret == ErrorCode::OK || ret == ErrorCode::UNIMPLEMENTED;
398         if (__android_log_security() && uidAlias.isOk()) {
399             android_log_event_list(SEC_TAG_KEY_DESTROYED)
400                 << int32_t(success) << alias << int32_t(uid) << LOG_ID_SECURITY;
401         }
402         if (!success) return ResponseCode::SYSTEM_ERROR;
403     }
404 
405     rc =
406         (unlink(filename) && errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::NO_ERROR;
407 
408     if (rc == ResponseCode::NO_ERROR && keyBlob.getType() != ::TYPE_KEY_CHARACTERISTICS) {
409         // now that we have successfully deleted a key, let's make sure there are no stale grants
410         if (uidAlias.isOk()) {
411             mGrants.removeAllGrantsToKey(uid, alias);
412         }
413     }
414     return rc;
415 }
416 
417 /*
418  * Converts from the "escaped" format on disk to actual name.
419  * This will be smaller than the input string.
420  *
421  * Characters that should combine with the next at the end will be truncated.
422  */
decode_key_length(const char * in,size_t length)423 static size_t decode_key_length(const char* in, size_t length) {
424     size_t outLength = 0;
425 
426     for (const char* end = in + length; in < end; in++) {
427         /* This combines with the next character. */
428         if (*in < '0' || *in > '~') {
429             continue;
430         }
431 
432         outLength++;
433     }
434     return outLength;
435 }
436 
decode_key(char * out,const char * in,size_t length)437 static void decode_key(char* out, const char* in, size_t length) {
438     for (const char* end = in + length; in < end; in++) {
439         if (*in < '0' || *in > '~') {
440             /* Truncate combining characters at the end. */
441             if (in + 1 >= end) {
442                 break;
443             }
444 
445             *out = (*in++ - '+') << 6;
446             *out++ |= (*in - '0') & 0x3F;
447         } else {
448             *out++ = *in;
449         }
450     }
451     *out = '\0';
452 }
453 
filename2UidAlias(const std::string & filepath)454 static NullOr<std::tuple<uid_t, std::string>> filename2UidAlias(const std::string& filepath) {
455     auto filenamebase = filepath.find_last_of('/');
456     std::string filename =
457         filenamebase == std::string::npos ? filepath : filepath.substr(filenamebase + 1);
458 
459     if (filename[0] == '.') return {};
460 
461     auto sep = filename.find('_');
462     if (sep == std::string::npos) return {};
463 
464     std::stringstream s(filename.substr(0, sep));
465     uid_t uid;
466     s >> uid;
467     if (!s) return {};
468 
469     auto alias = filename.substr(sep + 1);
470 
471     std::vector<char> alias_buffer(decode_key_length(alias.c_str(), alias.size()) + 1);
472 
473     decode_key(alias_buffer.data(), alias.c_str(), alias.size());
474     return std::tuple<uid_t, std::string>(uid, alias_buffer.data());
475 }
476 
list(const android::String8 & prefix,android::Vector<android::String16> * matches,uid_t userId)477 ResponseCode KeyStore::list(const android::String8& prefix,
478                             android::Vector<android::String16>* matches, uid_t userId) {
479 
480     UserState* userState = getUserState(userId);
481     size_t n = prefix.length();
482 
483     DIR* dir = opendir(userState->getUserDirName());
484     if (!dir) {
485         ALOGW("can't open directory for user: %s", strerror(errno));
486         return ResponseCode::SYSTEM_ERROR;
487     }
488 
489     struct dirent* file;
490     while ((file = readdir(dir)) != NULL) {
491         // We only care about files.
492         if (file->d_type != DT_REG) {
493             continue;
494         }
495 
496         // Skip anything that starts with a "."
497         if (file->d_name[0] == '.') {
498             continue;
499         }
500 
501         if (!strncmp(prefix.string(), file->d_name, n)) {
502             const char* p = &file->d_name[n];
503             size_t plen = strlen(p);
504 
505             size_t extra = decode_key_length(p, plen);
506             char* match = (char*)malloc(extra + 1);
507             if (match != NULL) {
508                 decode_key(match, p, plen);
509                 matches->push(android::String16(match, extra));
510                 free(match);
511             } else {
512                 ALOGW("could not allocate match of size %zd", extra);
513             }
514         }
515     }
516     closedir(dir);
517     return ResponseCode::NO_ERROR;
518 }
519 
addGrant(const char * alias,uid_t granterUid,uid_t granteeUid)520 std::string KeyStore::addGrant(const char* alias, uid_t granterUid, uid_t granteeUid) {
521     return mGrants.put(granteeUid, alias, getUserStateByUid(granterUid)->getUserDirName(),
522                        granterUid);
523 }
524 
removeGrant(const char * alias,const uid_t granterUid,const uid_t granteeUid)525 bool KeyStore::removeGrant(const char* alias, const uid_t granterUid, const uid_t granteeUid) {
526     return mGrants.removeByFileAlias(granteeUid, granterUid, alias);
527 }
removeAllGrantsToUid(const uid_t granteeUid)528 void KeyStore::removeAllGrantsToUid(const uid_t granteeUid) {
529     mGrants.removeAllGrantsToUid(granteeUid);
530 }
531 
importKey(const uint8_t * key,size_t keyLen,const char * filename,uid_t userId,int32_t flags)532 ResponseCode KeyStore::importKey(const uint8_t* key, size_t keyLen, const char* filename,
533                                  uid_t userId, int32_t flags) {
534     Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, keyLen));
535     if (!pkcs8.get()) {
536         return ResponseCode::SYSTEM_ERROR;
537     }
538     Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
539     if (!pkey.get()) {
540         return ResponseCode::SYSTEM_ERROR;
541     }
542     int type = EVP_PKEY_type(pkey->type);
543     AuthorizationSet params;
544     add_legacy_key_authorizations(type, &params);
545     switch (type) {
546     case EVP_PKEY_RSA:
547         params.push_back(TAG_ALGORITHM, Algorithm::RSA);
548         break;
549     case EVP_PKEY_EC:
550         params.push_back(TAG_ALGORITHM, Algorithm::EC);
551         break;
552     default:
553         ALOGW("Unsupported key type %d", type);
554         return ResponseCode::SYSTEM_ERROR;
555     }
556 
557     AuthorizationSet opParams(params);
558     hidl_vec<uint8_t> blob;
559 
560     ErrorCode error;
561     auto hidlCb = [&](ErrorCode ret, const hidl_vec<uint8_t>& keyBlob,
562                       const KeyCharacteristics& /* ignored */) {
563         error = ret;
564         if (error != ErrorCode::OK) return;
565         blob = keyBlob;
566     };
567     auto input = blob2hidlVec(key, keyLen);
568 
569     SecurityLevel securityLevel = flagsToSecurityLevel(flags);
570     auto kmDevice = getDevice(securityLevel);
571     if (!kmDevice) {
572         // As of this writing the only caller is KeyStore::get in an attempt to import legacy
573         // software keys. It only ever requests TEE as target which must always be present.
574         // If we see this error, we probably have a new and unanticipated caller.
575         ALOGE("No implementation for security level %d. Cannot import key.", securityLevel);
576         return ResponseCode::SYSTEM_ERROR;
577     }
578 
579     ErrorCode rc = KS_HANDLE_HIDL_ERROR(
580         kmDevice->importKey(params.hidl_data(), KeyFormat::PKCS8, input, hidlCb));
581     if (rc != ErrorCode::OK) return ResponseCode::SYSTEM_ERROR;
582     if (error != ErrorCode::OK) {
583         ALOGE("Keymaster error %d importing key pair", error);
584         return ResponseCode::SYSTEM_ERROR;
585     }
586 
587     Blob keyBlob(&blob[0], blob.size(), NULL, 0, TYPE_KEYMASTER_10);
588 
589     keyBlob.setEncrypted(flags & KEYSTORE_FLAG_ENCRYPTED);
590     keyBlob.setSecurityLevel(securityLevel);
591 
592     return put(filename, &keyBlob, userId);
593 }
594 
isHardwareBacked(const android::String16 & keyType) const595 bool KeyStore::isHardwareBacked(const android::String16& keyType) const {
596     // if strongbox device is present TEE must also be present and of sufficiently high version
597     // to support all keys in hardware
598     if (getDevice(SecurityLevel::STRONGBOX)) return true;
599     if (!getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)) {
600         ALOGW("can't get keymaster device");
601         return false;
602     }
603 
604     auto version = getDevice(SecurityLevel::TRUSTED_ENVIRONMENT)->halVersion();
605     if (keyType == kRsaKeyType) return true;  // All versions support RSA
606     return keyType == kEcKeyType && version.supportsEc;
607 }
608 
getKeyForName(Blob * keyBlob,const android::String8 & keyName,const uid_t uid,const BlobType type)609 ResponseCode KeyStore::getKeyForName(Blob* keyBlob, const android::String8& keyName,
610                                      const uid_t uid, const BlobType type) {
611     auto filepath8 = getBlobFileNameIfExists(keyName, uid, type);
612     uid_t userId = get_user_id(uid);
613 
614     if (filepath8.isOk()) return get(filepath8.value().string(), keyBlob, type, userId);
615 
616     return ResponseCode::KEY_NOT_FOUND;
617 }
618 
getUserState(uid_t userId)619 UserState* KeyStore::getUserState(uid_t userId) {
620     for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); it != mMasterKeys.end();
621          it++) {
622         UserState* state = *it;
623         if (state->getUserId() == userId) {
624             return state;
625         }
626     }
627 
628     UserState* userState = new UserState(userId);
629     if (!userState->initialize()) {
630         /* There's not much we can do if initialization fails. Trying to
631          * unlock the keystore for that user will fail as well, so any
632          * subsequent request for this user will just return SYSTEM_ERROR.
633          */
634         ALOGE("User initialization failed for %u; subsuquent operations will fail", userId);
635     }
636     mMasterKeys.add(userState);
637     return userState;
638 }
639 
getUserStateByUid(uid_t uid)640 UserState* KeyStore::getUserStateByUid(uid_t uid) {
641     uid_t userId = get_user_id(uid);
642     return getUserState(userId);
643 }
644 
getUserState(uid_t userId) const645 const UserState* KeyStore::getUserState(uid_t userId) const {
646     for (android::Vector<UserState*>::const_iterator it(mMasterKeys.begin());
647          it != mMasterKeys.end(); it++) {
648         UserState* state = *it;
649         if (state->getUserId() == userId) {
650             return state;
651         }
652     }
653 
654     return NULL;
655 }
656 
getUserStateByUid(uid_t uid) const657 const UserState* KeyStore::getUserStateByUid(uid_t uid) const {
658     uid_t userId = get_user_id(uid);
659     return getUserState(userId);
660 }
661 
upgradeBlob(const char * filename,Blob * blob,const uint8_t oldVersion,const BlobType type,uid_t userId)662 bool KeyStore::upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion,
663                            const BlobType type, uid_t userId) {
664     bool updated = false;
665     uint8_t version = oldVersion;
666 
667     /* From V0 -> V1: All old types were unknown */
668     if (version == 0) {
669         ALOGV("upgrading to version 1 and setting type %d", type);
670 
671         blob->setType(type);
672         if (type == TYPE_KEY_PAIR) {
673             importBlobAsKey(blob, filename, userId);
674         }
675         version = 1;
676         updated = true;
677     }
678 
679     /* From V1 -> V2: All old keys were encrypted */
680     if (version == 1) {
681         ALOGV("upgrading to version 2");
682 
683         blob->setEncrypted(true);
684         version = 2;
685         updated = true;
686     }
687 
688     /*
689      * If we've updated, set the key blob to the right version
690      * and write it.
691      */
692     if (updated) {
693         ALOGV("updated and writing file %s", filename);
694         blob->setVersion(version);
695     }
696 
697     return updated;
698 }
699 
700 struct BIO_Delete {
operator ()keystore::BIO_Delete701     void operator()(BIO* p) const { BIO_free(p); }
702 };
703 typedef std::unique_ptr<BIO, BIO_Delete> Unique_BIO;
704 
importBlobAsKey(Blob * blob,const char * filename,uid_t userId)705 ResponseCode KeyStore::importBlobAsKey(Blob* blob, const char* filename, uid_t userId) {
706     // We won't even write to the blob directly with this BIO, so const_cast is okay.
707     Unique_BIO b(BIO_new_mem_buf(const_cast<uint8_t*>(blob->getValue()), blob->getLength()));
708     if (b.get() == NULL) {
709         ALOGE("Problem instantiating BIO");
710         return ResponseCode::SYSTEM_ERROR;
711     }
712 
713     Unique_EVP_PKEY pkey(PEM_read_bio_PrivateKey(b.get(), NULL, NULL, NULL));
714     if (pkey.get() == NULL) {
715         ALOGE("Couldn't read old PEM file");
716         return ResponseCode::SYSTEM_ERROR;
717     }
718 
719     Unique_PKCS8_PRIV_KEY_INFO pkcs8(EVP_PKEY2PKCS8(pkey.get()));
720     int len = i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), NULL);
721     if (len < 0) {
722         ALOGE("Couldn't measure PKCS#8 length");
723         return ResponseCode::SYSTEM_ERROR;
724     }
725 
726     std::unique_ptr<unsigned char[]> pkcs8key(new unsigned char[len]);
727     uint8_t* tmp = pkcs8key.get();
728     if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) {
729         ALOGE("Couldn't convert to PKCS#8");
730         return ResponseCode::SYSTEM_ERROR;
731     }
732 
733     ResponseCode rc = importKey(pkcs8key.get(), len, filename, userId,
734                                 blob->isEncrypted() ? KEYSTORE_FLAG_ENCRYPTED : KEYSTORE_FLAG_NONE);
735     if (rc != ResponseCode::NO_ERROR) {
736         return rc;
737     }
738 
739     return get(filename, blob, TYPE_KEY_PAIR, userId);
740 }
741 
readMetaData()742 void KeyStore::readMetaData() {
743     int in = TEMP_FAILURE_RETRY(open(kMetaDataFile, O_RDONLY));
744     if (in < 0) {
745         return;
746     }
747     size_t fileLength = readFully(in, (uint8_t*)&mMetaData, sizeof(mMetaData));
748     if (fileLength != sizeof(mMetaData)) {
749         ALOGI("Metadata file is %zd bytes (%zd experted); upgrade?", fileLength, sizeof(mMetaData));
750     }
751     close(in);
752 }
753 
writeMetaData()754 void KeyStore::writeMetaData() {
755     const char* tmpFileName = ".metadata.tmp";
756     int out =
757         TEMP_FAILURE_RETRY(open(tmpFileName, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR));
758     if (out < 0) {
759         ALOGE("couldn't write metadata file: %s", strerror(errno));
760         return;
761     }
762     size_t fileLength = writeFully(out, (uint8_t*)&mMetaData, sizeof(mMetaData));
763     if (fileLength != sizeof(mMetaData)) {
764         ALOGI("Could only write %zd bytes to metadata file (%zd expected)", fileLength,
765               sizeof(mMetaData));
766     }
767     close(out);
768     rename(tmpFileName, kMetaDataFile);
769 }
770 
upgradeKeystore()771 bool KeyStore::upgradeKeystore() {
772     bool upgraded = false;
773 
774     if (mMetaData.version == 0) {
775         UserState* userState = getUserStateByUid(0);
776 
777         // Initialize first so the directory is made.
778         userState->initialize();
779 
780         // Migrate the old .masterkey file to user 0.
781         if (access(kOldMasterKey, R_OK) == 0) {
782             if (rename(kOldMasterKey, userState->getMasterKeyFileName()) < 0) {
783                 ALOGE("couldn't migrate old masterkey: %s", strerror(errno));
784                 return false;
785             }
786         }
787 
788         // Initialize again in case we had a key.
789         userState->initialize();
790 
791         // Try to migrate existing keys.
792         DIR* dir = opendir(".");
793         if (!dir) {
794             // Give up now; maybe we can upgrade later.
795             ALOGE("couldn't open keystore's directory; something is wrong");
796             return false;
797         }
798 
799         struct dirent* file;
800         while ((file = readdir(dir)) != NULL) {
801             // We only care about files.
802             if (file->d_type != DT_REG) {
803                 continue;
804             }
805 
806             // Skip anything that starts with a "."
807             if (file->d_name[0] == '.') {
808                 continue;
809             }
810 
811             // Find the current file's user.
812             char* end;
813             unsigned long thisUid = strtoul(file->d_name, &end, 10);
814             if (end[0] != '_' || end[1] == 0) {
815                 continue;
816             }
817             UserState* otherUser = getUserStateByUid(thisUid);
818             if (otherUser->getUserId() != 0) {
819                 unlinkat(dirfd(dir), file->d_name, 0);
820             }
821 
822             // Rename the file into user directory.
823             DIR* otherdir = opendir(otherUser->getUserDirName());
824             if (otherdir == NULL) {
825                 ALOGW("couldn't open user directory for rename");
826                 continue;
827             }
828             if (renameat(dirfd(dir), file->d_name, dirfd(otherdir), file->d_name) < 0) {
829                 ALOGW("couldn't rename blob: %s: %s", file->d_name, strerror(errno));
830             }
831             closedir(otherdir);
832         }
833         closedir(dir);
834 
835         mMetaData.version = 1;
836         upgraded = true;
837     }
838 
839     return upgraded;
840 }
841 
maybeLogKeyIntegrityViolation(const char * filename,const BlobType type)842 static void maybeLogKeyIntegrityViolation(const char* filename, const BlobType type) {
843     if (!__android_log_security() || (type != TYPE_KEY_PAIR && type != TYPE_KEYMASTER_10)) return;
844 
845     auto uidAlias = filename2UidAlias(filename);
846     uid_t uid = -1;
847     std::string alias;
848 
849     if (uidAlias.isOk()) std::tie(uid, alias) = std::move(uidAlias).value();
850 
851     log_key_integrity_violation(alias.c_str(), uid);
852 }
853 
854 }  // namespace keystore
855