/* * 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_0/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 count> struct tuple_size<keystore::Devices<T, count>> { public: static constexpr size_t value = std::tuple_size<std::array<T, count>>::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; } 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(); }; } // namespace keystore #endif // KEYSTORE_KEYSTORE_H_