|  | /* | 
|  | * Copyright (C) 2016 The Android Open Source Project | 
|  | * | 
|  | * Licensed under the Apache License, Version 2.0 (the "License"); | 
|  | * you may not use this file except in compliance with the License. | 
|  | * You may obtain a copy of the License at | 
|  | * | 
|  | *      http://www.apache.org/licenses/LICENSE-2.0 | 
|  | * | 
|  | * Unless required by applicable law or agreed to in writing, software | 
|  | * distributed under the License is distributed on an "AS IS" BASIS, | 
|  | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
|  | * See the License for the specific language governing permissions and | 
|  | * limitations under the License. | 
|  | */ | 
|  |  | 
|  | #ifndef KEYSTORE_KEYSTORE_H_ | 
|  | #define KEYSTORE_KEYSTORE_H_ | 
|  |  | 
|  | #include <android/hardware/keymaster/3.0/IKeymasterDevice.h> | 
|  | #include <keymasterV4_1/Keymaster.h> | 
|  | #include <utils/Vector.h> | 
|  |  | 
|  | #include <keystore/keymaster_types.h> | 
|  |  | 
|  | #include "auth_token_table.h" | 
|  | #include "blob.h" | 
|  | #include "confirmation_manager.h" | 
|  | #include "grant_store.h" | 
|  | #include "keymaster_worker.h" | 
|  | #include "keystore_keymaster_enforcement.h" | 
|  | #include "operation.h" | 
|  | #include "user_state.h" | 
|  |  | 
|  | #include <array> | 
|  | #include <optional> | 
|  | #include <tuple> | 
|  |  | 
|  | namespace keystore { | 
|  |  | 
|  | using ::android::sp; | 
|  | using keymaster::support::Keymaster; | 
|  |  | 
|  | template <typename T, size_t count> class Devices : public std::array<T, count> { | 
|  | public: | 
|  | T& operator[](SecurityLevel secLevel) { | 
|  | static_assert(uint32_t(SecurityLevel::SOFTWARE) == 0 && | 
|  | uint32_t(SecurityLevel::TRUSTED_ENVIRONMENT) == 1 && | 
|  | uint32_t(SecurityLevel::STRONGBOX) == 2, | 
|  | "Numeric values of security levels have changed"); | 
|  | return std::array<T, count>::at(static_cast<uint32_t>(secLevel)); | 
|  | } | 
|  | T operator[](SecurityLevel secLevel) const { | 
|  | if (static_cast<uint32_t>(secLevel) > static_cast<uint32_t>(SecurityLevel::STRONGBOX)) { | 
|  | LOG(ERROR) << "Invalid security level requested"; | 
|  | return {}; | 
|  | } | 
|  | return (*const_cast<Devices*>(this))[secLevel]; | 
|  | } | 
|  | }; | 
|  |  | 
|  | }  // namespace keystore | 
|  |  | 
|  | namespace std { | 
|  | template <typename T, size_t N> struct tuple_size<keystore::Devices<T, N>> { | 
|  | public: | 
|  | static constexpr size_t value = std::tuple_size<std::array<T, N>>::value; | 
|  | }; | 
|  | }  // namespace std | 
|  |  | 
|  | namespace keystore { | 
|  |  | 
|  | using KeymasterWorkers = Devices<std::shared_ptr<KeymasterWorker>, 3>; | 
|  | using KeymasterDevices = Devices<sp<Keymaster>, 3>; | 
|  |  | 
|  | class KeyStore : public ::android::IBinder::DeathRecipient { | 
|  | public: | 
|  | KeyStore(const KeymasterDevices& kmDevices, | 
|  | SecurityLevel minimalAllowedSecurityLevelForNewKeys); | 
|  | ~KeyStore(); | 
|  |  | 
|  | std::shared_ptr<KeymasterWorker> getDevice(SecurityLevel securityLevel) const { | 
|  | return mKmDevices[securityLevel]; | 
|  | } | 
|  |  | 
|  | std::shared_ptr<KeymasterWorker> getFallbackDevice() const { | 
|  | // we only return the fallback device if the creation of new fallback key blobs is | 
|  | // allowed. (also see getDevice below) | 
|  | if (mAllowNewFallback) { | 
|  | return mKmDevices[SecurityLevel::SOFTWARE]; | 
|  | } else { | 
|  | return nullptr; | 
|  | } | 
|  | } | 
|  |  | 
|  | std::shared_ptr<KeymasterWorker> getDevice(const Blob& blob) { | 
|  | return mKmDevices[blob.getSecurityLevel()]; | 
|  | } | 
|  |  | 
|  | ResponseCode initialize(); | 
|  |  | 
|  | State getState(uid_t userId) { return mUserStateDB.getUserState(userId)->getState(); } | 
|  |  | 
|  | ResponseCode initializeUser(const android::String8& pw, uid_t userId); | 
|  |  | 
|  | ResponseCode copyMasterKey(uid_t srcUser, uid_t dstUser); | 
|  | ResponseCode writeMasterKey(const android::String8& pw, uid_t userId); | 
|  | ResponseCode readMasterKey(const android::String8& pw, uid_t userId); | 
|  |  | 
|  | LockedKeyBlobEntry getLockedBlobEntryIfNotExists(const std::string& alias, uid_t uid); | 
|  | std::optional<KeyBlobEntry> getBlobEntryIfExists(const std::string& alias, uid_t uid); | 
|  | LockedKeyBlobEntry getLockedBlobEntryIfExists(const std::string& alias, uid_t uid); | 
|  | /* | 
|  | * Delete entries owned by userId. If keepUnencryptedEntries is true | 
|  | * then only encrypted entries will be removed, otherwise all entries will | 
|  | * be removed. | 
|  | */ | 
|  | void resetUser(uid_t userId, bool keepUnenryptedEntries); | 
|  | bool isEmpty(uid_t userId) const; | 
|  |  | 
|  | void lock(uid_t userId); | 
|  |  | 
|  | std::tuple<ResponseCode, Blob, Blob> get(const LockedKeyBlobEntry& blobfile); | 
|  | ResponseCode put(const LockedKeyBlobEntry& blobfile, Blob keyBlob, Blob characteristicsBlob); | 
|  | ResponseCode del(const LockedKeyBlobEntry& blobfile); | 
|  |  | 
|  | std::string addGrant(const LockedKeyBlobEntry& blobfile, uid_t granteeUid); | 
|  | bool removeGrant(const LockedKeyBlobEntry& blobfile, const uid_t granteeUid); | 
|  | void removeAllGrantsToUid(const uid_t granteeUid); | 
|  |  | 
|  | ResponseCode importKey(const uint8_t* key, size_t keyLen, const LockedKeyBlobEntry& blobfile, | 
|  | uid_t userId, int32_t flags); | 
|  |  | 
|  | bool isHardwareBacked(const android::String16& keyType) const; | 
|  |  | 
|  | std::tuple<ResponseCode, Blob, Blob, LockedKeyBlobEntry> | 
|  | getKeyForName(const android::String8& keyName, const uid_t uid, const BlobType type); | 
|  |  | 
|  | void binderDied(const ::android::wp<IBinder>& who) override; | 
|  |  | 
|  | UserStateDB& getUserStateDB() { return mUserStateDB; } | 
|  | AuthTokenTable& getAuthTokenTable() { return mAuthTokenTable; } | 
|  | KeystoreKeymasterEnforcement& getEnforcementPolicy() { return mEnforcementPolicy; } | 
|  | ConfirmationManager& getConfirmationManager() { return *mConfirmationManager; } | 
|  |  | 
|  | void addOperationDevice(sp<IBinder> token, std::shared_ptr<KeymasterWorker> dev) { | 
|  | std::lock_guard<std::mutex> lock(operationDeviceMapMutex_); | 
|  | operationDeviceMap_.emplace(std::move(token), std::move(dev)); | 
|  | } | 
|  | std::shared_ptr<KeymasterWorker> getOperationDevice(const sp<IBinder>& token) { | 
|  | std::lock_guard<std::mutex> lock(operationDeviceMapMutex_); | 
|  | auto it = operationDeviceMap_.find(token); | 
|  | if (it != operationDeviceMap_.end()) { | 
|  | return it->second; | 
|  | } | 
|  | return {}; | 
|  | } | 
|  | void removeOperationDevice(const sp<IBinder>& token) { | 
|  | std::lock_guard<std::mutex> lock(operationDeviceMapMutex_); | 
|  | operationDeviceMap_.erase(token); | 
|  | } | 
|  |  | 
|  | private: | 
|  | static const char* kOldMasterKey; | 
|  | static const char* kMetaDataFile; | 
|  | static const android::String16 kRsaKeyType; | 
|  | static const android::String16 kEcKeyType; | 
|  |  | 
|  | KeymasterWorkers mKmDevices; | 
|  |  | 
|  | bool mAllowNewFallback; | 
|  |  | 
|  | UserStateDB mUserStateDB; | 
|  | AuthTokenTable mAuthTokenTable; | 
|  | KeystoreKeymasterEnforcement mEnforcementPolicy; | 
|  | sp<ConfirmationManager> mConfirmationManager; | 
|  |  | 
|  | ::keystore::GrantStore mGrants; | 
|  |  | 
|  | typedef struct { uint32_t version; } keystore_metadata_t; | 
|  |  | 
|  | keystore_metadata_t mMetaData; | 
|  |  | 
|  | /** | 
|  | * Upgrade the key from the current version to whatever is newest. | 
|  | */ | 
|  | bool upgradeBlob(Blob* blob, const uint8_t oldVersion); | 
|  |  | 
|  | void readMetaData(); | 
|  | void writeMetaData(); | 
|  |  | 
|  | bool upgradeKeystore(); | 
|  |  | 
|  | std::mutex operationDeviceMapMutex_; | 
|  | std::map<sp<IBinder>, std::shared_ptr<KeymasterWorker>> operationDeviceMap_; | 
|  | }; | 
|  |  | 
|  | }  // namespace keystore | 
|  |  | 
|  | #endif  // KEYSTORE_KEYSTORE_H_ |