688d3ab299
Keystore's security originally derived from encrypting keys with a key derived from the user's password. To avoid making keystore into a password brute force oracle, keystore cleared itself after five incorrect presentations. All of this has been superseded by moving keystore's security into Keymaster, and by moving password security into Gatekeeper/Weaver, and further by implmenting the synthetic password model. This CL removes the now-useless and occasionally-dangerous keystore self-destruct. Test: Manual Change-Id: Id85c1c39769701bbc0dcfcb76511faf9eeb65496
131 lines
3.9 KiB
C++
131 lines
3.9 KiB
C++
/*
|
|
* 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 <sys/types.h>
|
|
|
|
#include <openssl/aes.h>
|
|
|
|
#include <utils/String8.h>
|
|
|
|
#include <keystore/keystore.h>
|
|
|
|
#include "blob.h"
|
|
#include "keystore_utils.h"
|
|
|
|
#include <android-base/logging.h>
|
|
#include <condition_variable>
|
|
#include <keystore/keystore_concurrency.h>
|
|
#include <mutex>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
namespace keystore {
|
|
|
|
class UserState;
|
|
|
|
template <typename UserState> using LockedUserState = ProxyLock<UnlockProxyLockHelper<UserState>>;
|
|
|
|
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<UserState>* src);
|
|
ResponseCode copyMasterKeyFile(LockedUserState<UserState>* src);
|
|
ResponseCode writeMasterKey(const android::String8& pw);
|
|
ResponseCode readMasterKey(const android::String8& pw);
|
|
|
|
const std::vector<uint8_t>& 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<uint8_t>& key, const android::String8& pw,
|
|
uint8_t* salt);
|
|
bool generateSalt();
|
|
bool generateMasterKey();
|
|
void setupMasterKeys();
|
|
|
|
KeyBlobEntry mMasterKeyEntry;
|
|
|
|
uid_t mUserId;
|
|
State mState;
|
|
|
|
std::vector<uint8_t> mMasterKey;
|
|
uint8_t mSalt[SALT_SIZE];
|
|
};
|
|
|
|
bool operator<(uid_t userId, const UserState& rhs);
|
|
|
|
class UserStateDB {
|
|
public:
|
|
LockedUserState<UserState> getUserState(uid_t userId);
|
|
LockedUserState<UserState> getUserStateByUid(uid_t uid);
|
|
LockedUserState<const UserState> getUserState(uid_t userId) const;
|
|
LockedUserState<const UserState> getUserStateByUid(uid_t uid) const;
|
|
|
|
private:
|
|
mutable std::set<const UserState*> locked_state_;
|
|
mutable std::mutex locked_state_mutex_;
|
|
mutable std::condition_variable locked_state_mutex_cond_var_;
|
|
|
|
template <typename UserState>
|
|
LockedUserState<UserState> get(std::unique_lock<std::mutex> 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<std::mutex> lock(locked_state_mutex_);
|
|
locked_state_.erase(entry);
|
|
lock.unlock();
|
|
locked_state_mutex_cond_var_.notify_all();
|
|
}};
|
|
}
|
|
|
|
std::map<uid_t, UserState> mMasterKeys;
|
|
};
|
|
|
|
} // namespace keystore
|
|
|
|
#endif // KEYSTORE_USER_STATE_H_
|