Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 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 | #ifndef KEYSTORE_KEYSTORE_H_ |
| 18 | #define KEYSTORE_KEYSTORE_H_ |
| 19 | |
Janis Danisevskis | c7a9fa2 | 2016-10-13 18:43:45 +0100 | [diff] [blame] | 20 | #include <android/hardware/keymaster/3.0/IKeymasterDevice.h> |
Shawn Willden | eedcfe9 | 2018-01-18 15:35:46 -0700 | [diff] [blame] | 21 | #include <keymasterV4_0/Keymaster.h> |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 22 | #include <utils/Vector.h> |
| 23 | |
Shawn Willden | bb22a6c | 2017-12-06 19:35:28 -0700 | [diff] [blame] | 24 | #include <keystore/keymaster_types.h> |
| 25 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 26 | #include "auth_token_table.h" |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 27 | #include "blob.h" |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 28 | #include "confirmation_manager.h" |
Janis Danisevskis | 6d449e8 | 2017-06-07 18:03:31 -0700 | [diff] [blame] | 29 | #include "grant_store.h" |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 30 | #include "keymaster_worker.h" |
| 31 | #include "keystore_keymaster_enforcement.h" |
| 32 | #include "operation.h" |
Shawn Willden | fa5702f | 2017-12-03 15:14:58 -0700 | [diff] [blame] | 33 | #include "user_state.h" |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 34 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 35 | #include <array> |
| 36 | #include <optional> |
| 37 | #include <tuple> |
| 38 | |
Shawn Willden | c67a8aa | 2017-12-03 17:51:29 -0700 | [diff] [blame] | 39 | namespace keystore { |
| 40 | |
| 41 | using ::android::sp; |
Shawn Willden | eedcfe9 | 2018-01-18 15:35:46 -0700 | [diff] [blame] | 42 | using keymaster::support::Keymaster; |
Janis Danisevskis | e8ba180 | 2017-01-30 10:49:51 +0000 | [diff] [blame] | 43 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 44 | template <typename T, size_t count> class Devices : public std::array<T, count> { |
Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 45 | public: |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 46 | T& operator[](SecurityLevel secLevel) { |
| 47 | static_assert(uint32_t(SecurityLevel::SOFTWARE) == 0 && |
| 48 | uint32_t(SecurityLevel::TRUSTED_ENVIRONMENT) == 1 && |
| 49 | uint32_t(SecurityLevel::STRONGBOX) == 2, |
| 50 | "Numeric values of security levels have changed"); |
| 51 | return std::array<T, count>::at(static_cast<uint32_t>(secLevel)); |
| 52 | } |
| 53 | T operator[](SecurityLevel secLevel) const { |
| 54 | if (static_cast<uint32_t>(secLevel) > static_cast<uint32_t>(SecurityLevel::STRONGBOX)) { |
| 55 | LOG(ERROR) << "Invalid security level requested"; |
| 56 | return {}; |
| 57 | } |
| 58 | return (*const_cast<Devices*>(this))[secLevel]; |
| 59 | } |
Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 60 | }; |
| 61 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 62 | } // namespace keystore |
| 63 | |
| 64 | namespace std { |
Dan Albert | b1e7936 | 2019-01-11 15:09:54 -0800 | [diff] [blame] | 65 | template <typename T, size_t count> struct tuple_size<keystore::Devices<T, count>> { |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 66 | public: |
| 67 | static constexpr size_t value = std::tuple_size<std::array<T, count>>::value; |
| 68 | }; |
| 69 | } // namespace std |
| 70 | |
| 71 | namespace keystore { |
| 72 | |
| 73 | using KeymasterWorkers = Devices<std::shared_ptr<KeymasterWorker>, 3>; |
| 74 | using KeymasterDevices = Devices<sp<Keymaster>, 3>; |
| 75 | |
| 76 | class KeyStore : public ::android::IBinder::DeathRecipient { |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 77 | public: |
Branden Archer | 44d1afa | 2018-12-28 09:10:49 -0800 | [diff] [blame] | 78 | KeyStore(const KeymasterDevices& kmDevices, |
Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 79 | SecurityLevel minimalAllowedSecurityLevelForNewKeys); |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 80 | ~KeyStore(); |
| 81 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 82 | std::shared_ptr<KeymasterWorker> getDevice(SecurityLevel securityLevel) const { |
| 83 | return mKmDevices[securityLevel]; |
Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 84 | } |
| 85 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 86 | std::shared_ptr<KeymasterWorker> getFallbackDevice() const { |
Janis Danisevskis | e8ba180 | 2017-01-30 10:49:51 +0000 | [diff] [blame] | 87 | // we only return the fallback device if the creation of new fallback key blobs is |
| 88 | // allowed. (also see getDevice below) |
| 89 | if (mAllowNewFallback) { |
Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 90 | return mKmDevices[SecurityLevel::SOFTWARE]; |
Janis Danisevskis | e8ba180 | 2017-01-30 10:49:51 +0000 | [diff] [blame] | 91 | } else { |
Janis Danisevskis | c146014 | 2017-12-18 16:48:46 -0800 | [diff] [blame] | 92 | return nullptr; |
Janis Danisevskis | e8ba180 | 2017-01-30 10:49:51 +0000 | [diff] [blame] | 93 | } |
| 94 | } |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 95 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 96 | std::shared_ptr<KeymasterWorker> getDevice(const Blob& blob) { |
| 97 | return mKmDevices[blob.getSecurityLevel()]; |
| 98 | } |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 99 | |
| 100 | ResponseCode initialize(); |
| 101 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 102 | State getState(uid_t userId) { return mUserStateDB.getUserState(userId)->getState(); } |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 103 | |
| 104 | ResponseCode initializeUser(const android::String8& pw, uid_t userId); |
| 105 | |
| 106 | ResponseCode copyMasterKey(uid_t srcUser, uid_t dstUser); |
| 107 | ResponseCode writeMasterKey(const android::String8& pw, uid_t userId); |
| 108 | ResponseCode readMasterKey(const android::String8& pw, uid_t userId); |
| 109 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 110 | LockedKeyBlobEntry getLockedBlobEntryIfNotExists(const std::string& alias, uid_t uid); |
| 111 | std::optional<KeyBlobEntry> getBlobEntryIfExists(const std::string& alias, uid_t uid); |
| 112 | LockedKeyBlobEntry getLockedBlobEntryIfExists(const std::string& alias, uid_t uid); |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 113 | /* |
| 114 | * Delete entries owned by userId. If keepUnencryptedEntries is true |
| 115 | * then only encrypted entries will be removed, otherwise all entries will |
| 116 | * be removed. |
| 117 | */ |
| 118 | void resetUser(uid_t userId, bool keepUnenryptedEntries); |
| 119 | bool isEmpty(uid_t userId) const; |
| 120 | |
| 121 | void lock(uid_t userId); |
| 122 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 123 | std::tuple<ResponseCode, Blob, Blob> get(const LockedKeyBlobEntry& blobfile); |
| 124 | ResponseCode put(const LockedKeyBlobEntry& blobfile, Blob keyBlob, Blob characteristicsBlob); |
| 125 | ResponseCode del(const LockedKeyBlobEntry& blobfile); |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 126 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 127 | std::string addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid); |
| 128 | bool removeGrant(const LockedKeyBlobEntry& blobfile, const uid_t granteeUid); |
Janis Danisevskis | 31b44f2 | 2017-09-21 11:29:47 -0700 | [diff] [blame] | 129 | void removeAllGrantsToUid(const uid_t granteeUid); |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 130 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 131 | ResponseCode importKey(const uint8_t* key, size_t keyLen, const LockedKeyBlobEntry& blobfile, |
| 132 | uid_t userId, int32_t flags); |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 133 | |
| 134 | bool isHardwareBacked(const android::String16& keyType) const; |
| 135 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 136 | std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry> |
| 137 | getKeyForName(const android::String8& keyName, const uid_t uid, const BlobType type); |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 138 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 139 | void binderDied(const ::android::wp<IBinder>& who) override; |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 140 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 141 | UserStateDB& getUserStateDB() { return mUserStateDB; } |
| 142 | AuthTokenTable& getAuthTokenTable() { return mAuthTokenTable; } |
| 143 | KeystoreKeymasterEnforcement& getEnforcementPolicy() { return mEnforcementPolicy; } |
| 144 | ConfirmationManager& getConfirmationManager() { return *mConfirmationManager; } |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 145 | |
| 146 | private: |
Shawn Willden | 0329a82 | 2017-12-04 13:55:14 -0700 | [diff] [blame] | 147 | static const char* kOldMasterKey; |
| 148 | static const char* kMetaDataFile; |
| 149 | static const android::String16 kRsaKeyType; |
| 150 | static const android::String16 kEcKeyType; |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 151 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 152 | KeymasterWorkers mKmDevices; |
| 153 | |
Janis Danisevskis | e8ba180 | 2017-01-30 10:49:51 +0000 | [diff] [blame] | 154 | bool mAllowNewFallback; |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 155 | |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 156 | UserStateDB mUserStateDB; |
| 157 | AuthTokenTable mAuthTokenTable; |
| 158 | KeystoreKeymasterEnforcement mEnforcementPolicy; |
| 159 | sp<ConfirmationManager> mConfirmationManager; |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 160 | |
Janis Danisevskis | 6d449e8 | 2017-06-07 18:03:31 -0700 | [diff] [blame] | 161 | ::keystore::GrantStore mGrants; |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 162 | |
Shawn Willden | fa5702f | 2017-12-03 15:14:58 -0700 | [diff] [blame] | 163 | typedef struct { uint32_t version; } keystore_metadata_t; |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 164 | |
| 165 | keystore_metadata_t mMetaData; |
| 166 | |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 167 | /** |
| 168 | * Upgrade the key from the current version to whatever is newest. |
| 169 | */ |
Janis Danisevskis | ff3d7f4 | 2018-10-08 07:15:09 -0700 | [diff] [blame] | 170 | bool upgradeBlob(Blob* blob, const uint8_t oldVersion); |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 171 | |
| 172 | void readMetaData(); |
| 173 | void writeMetaData(); |
| 174 | |
| 175 | bool upgradeKeystore(); |
| 176 | }; |
| 177 | |
Shawn Willden | c67a8aa | 2017-12-03 17:51:29 -0700 | [diff] [blame] | 178 | } // namespace keystore |
| 179 | |
Shawn Willden | c1d1fee | 2016-01-26 22:44:56 -0700 | [diff] [blame] | 180 | #endif // KEYSTORE_KEYSTORE_H_ |