summaryrefslogtreecommitdiff
path: root/keystore/user_state.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'keystore/user_state.cpp')
-rw-r--r--keystore/user_state.cpp71
1 files changed, 46 insertions, 25 deletions
diff --git a/keystore/user_state.cpp b/keystore/user_state.cpp
index 5f9cd5f..aab6175 100644
--- a/keystore/user_state.cpp
+++ b/keystore/user_state.cpp
@@ -24,7 +24,9 @@
#include <stdlib.h>
#include <sys/stat.h>
+#include <openssl/digest.h>
#include <openssl/evp.h>
+#include <openssl/rand.h>
#include <cutils/log.h>
@@ -66,7 +68,7 @@ void UserState::setState(State state) {
}
void UserState::zeroizeMasterKeysInMemory() {
- memset(mMasterKey, 0, sizeof(mMasterKey));
+ memset(mMasterKey.data(), 0, mMasterKey.size());
memset(mSalt, 0, sizeof(mSalt));
}
@@ -76,11 +78,11 @@ bool UserState::deleteMasterKey() {
return unlink(mMasterKeyFile) == 0 || errno == ENOENT;
}
-ResponseCode UserState::initialize(const android::String8& pw, Entropy* entropy) {
- if (!generateMasterKey(entropy)) {
+ResponseCode UserState::initialize(const android::String8& pw) {
+ if (!generateMasterKey()) {
return ResponseCode::SYSTEM_ERROR;
}
- ResponseCode response = writeMasterKey(pw, entropy);
+ ResponseCode response = writeMasterKey(pw);
if (response != ResponseCode::NO_ERROR) {
return response;
}
@@ -95,7 +97,7 @@ ResponseCode UserState::copyMasterKey(UserState* src) {
if (src->getState() != STATE_NO_ERROR) {
return ResponseCode::SYSTEM_ERROR;
}
- memcpy(mMasterKey, src->mMasterKey, MASTER_KEY_SIZE_BYTES);
+ mMasterKey = src->mMasterKey;
setupMasterKeys();
return copyMasterKeyFile(src);
}
@@ -130,14 +132,15 @@ ResponseCode UserState::copyMasterKeyFile(UserState* src) {
return ResponseCode::NO_ERROR;
}
-ResponseCode UserState::writeMasterKey(const android::String8& pw, Entropy* entropy) {
- uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
- generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
- Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
- return masterKeyBlob.writeBlob(mMasterKeyFile, passwordKey, STATE_NO_ERROR, entropy);
+ResponseCode UserState::writeMasterKey(const android::String8& pw) {
+ std::vector<uint8_t> passwordKey(MASTER_KEY_SIZE_BYTES);
+ generateKeyFromPassword(passwordKey, pw, mSalt);
+ Blob masterKeyBlob(mMasterKey.data(), mMasterKey.size(), mSalt, sizeof(mSalt),
+ TYPE_MASTER_KEY_AES256);
+ return masterKeyBlob.writeBlob(mMasterKeyFile, passwordKey, STATE_NO_ERROR);
}
-ResponseCode UserState::readMasterKey(const android::String8& pw, Entropy* entropy) {
+ResponseCode UserState::readMasterKey(const android::String8& pw) {
int in = TEMP_FAILURE_RETRY(open(mMasterKeyFile, O_RDONLY));
if (in < 0) {
return ResponseCode::SYSTEM_ERROR;
@@ -157,23 +160,33 @@ ResponseCode UserState::readMasterKey(const android::String8& pw, Entropy* entro
} else {
salt = NULL;
}
- uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
- generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
+
+ size_t masterKeySize = MASTER_KEY_SIZE_BYTES;
+ if (rawBlob.type == TYPE_MASTER_KEY) {
+ masterKeySize = SHA1_DIGEST_SIZE_BYTES;
+ }
+
+ std::vector<uint8_t> passwordKey(masterKeySize);
+ generateKeyFromPassword(passwordKey, pw, salt);
Blob masterKeyBlob(rawBlob);
ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, passwordKey, STATE_NO_ERROR);
if (response == ResponseCode::SYSTEM_ERROR) {
return response;
}
- if (response == ResponseCode::NO_ERROR && masterKeyBlob.getLength() == MASTER_KEY_SIZE_BYTES) {
+
+ size_t masterKeyBlobLength = static_cast<size_t>(masterKeyBlob.getLength());
+
+ if (response == ResponseCode::NO_ERROR && masterKeyBlobLength == masterKeySize) {
// If salt was missing, generate one and write a new master key file with the salt.
if (salt == NULL) {
- if (!generateSalt(entropy)) {
+ if (!generateSalt()) {
return ResponseCode::SYSTEM_ERROR;
}
- response = writeMasterKey(pw, entropy);
+ response = writeMasterKey(pw);
}
if (response == ResponseCode::NO_ERROR) {
- memcpy(mMasterKey, masterKeyBlob.getValue(), MASTER_KEY_SIZE_BYTES);
+ mMasterKey = std::vector<uint8_t>(masterKeyBlob.getValue(),
+ masterKeyBlob.getValue() + masterKeyBlob.getLength());
setupMasterKeys();
}
return response;
@@ -221,7 +234,7 @@ bool UserState::reset() {
return true;
}
-void UserState::generateKeyFromPassword(uint8_t* key, ssize_t keySize, const android::String8& pw,
+void UserState::generateKeyFromPassword(std::vector<uint8_t>& key, const android::String8& pw,
uint8_t* salt) {
size_t saltSize;
if (salt != NULL) {
@@ -233,19 +246,27 @@ void UserState::generateKeyFromPassword(uint8_t* key, ssize_t keySize, const and
saltSize = sizeof("keystore");
}
- PKCS5_PBKDF2_HMAC_SHA1(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, saltSize,
- 8192, keySize, key);
+ const EVP_MD* digest = EVP_sha256();
+
+ // SHA1 was used prior to increasing the key size
+ if (key.size() == SHA1_DIGEST_SIZE_BYTES) {
+ digest = EVP_sha1();
+ }
+
+ PKCS5_PBKDF2_HMAC(reinterpret_cast<const char*>(pw.string()), pw.length(), salt, saltSize, 8192,
+ digest, key.size(), key.data());
}
-bool UserState::generateSalt(Entropy* entropy) {
- return entropy->generate_random_data(mSalt, sizeof(mSalt));
+bool UserState::generateSalt() {
+ return RAND_bytes(mSalt, sizeof(mSalt));
}
-bool UserState::generateMasterKey(Entropy* entropy) {
- if (!entropy->generate_random_data(mMasterKey, sizeof(mMasterKey))) {
+bool UserState::generateMasterKey() {
+ mMasterKey.resize(MASTER_KEY_SIZE_BYTES);
+ if (!RAND_bytes(mMasterKey.data(), mMasterKey.size())) {
return false;
}
- if (!generateSalt(entropy)) {
+ if (!generateSalt()) {
return false;
}
return true;