/* * 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_USER_STATE_H_ #define KEYSTORE_USER_STATE_H_ #include #include #include #include #include "blob.h" #include "keystore_utils.h" #include #include #include #include #include #include namespace keystore { class UserState; template using LockedUserState = ProxyLock>; class UserState { public: explicit UserState(uid_t userId); bool initialize(); uid_t getUserId() const { return mUserId; } const std::string& getUserDirName() const { return mMasterKeyEntry.user_dir(); } std::string getMasterKeyFileName() const { return mMasterKeyEntry.getKeyBlobPath(); } void setState(State state); State getState() const { return mState; } void zeroizeMasterKeysInMemory(); bool deleteMasterKey(); ResponseCode initialize(const android::String8& pw); ResponseCode copyMasterKey(LockedUserState* src); ResponseCode copyMasterKeyFile(LockedUserState* src); ResponseCode writeMasterKey(const android::String8& pw); ResponseCode readMasterKey(const android::String8& pw); const std::vector& getEncryptionKey() const { return mMasterKey; } bool reset(); bool operator<(const UserState& rhs) const; bool operator<(uid_t userId) const; private: static constexpr int SHA1_DIGEST_SIZE_BYTES = 16; static constexpr int SHA256_DIGEST_SIZE_BYTES = 32; static constexpr int MASTER_KEY_SIZE_BYTES = kAes256KeySizeBytes; static constexpr int MASTER_KEY_SIZE_BITS = MASTER_KEY_SIZE_BYTES * 8; static constexpr size_t SALT_SIZE = 16; void generateKeyFromPassword(std::vector& key, const android::String8& pw, uint8_t* salt); bool generateSalt(); bool generateMasterKey(); void setupMasterKeys(); KeyBlobEntry mMasterKeyEntry; uid_t mUserId; State mState; std::vector mMasterKey; uint8_t mSalt[SALT_SIZE]; }; bool operator<(uid_t userId, const UserState& rhs); class UserStateDB { public: LockedUserState getUserState(uid_t userId); LockedUserState getUserStateByUid(uid_t uid); LockedUserState getUserState(uid_t userId) const; LockedUserState getUserStateByUid(uid_t uid) const; private: mutable std::set locked_state_; mutable std::mutex locked_state_mutex_; mutable std::condition_variable locked_state_mutex_cond_var_; template LockedUserState get(std::unique_lock lock, UserState* entry) const { locked_state_mutex_cond_var_.wait( lock, [&] { return locked_state_.find(entry) == locked_state_.end(); }); locked_state_.insert(entry); return {entry, [&](UserState* entry) { std::unique_lock lock(locked_state_mutex_); locked_state_.erase(entry); lock.unlock(); locked_state_mutex_cond_var_.notify_all(); }}; } std::map mMasterKeys; }; } // namespace keystore #endif // KEYSTORE_USER_STATE_H_