summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-05-28 07:38:33 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-05-28 07:38:33 +0000
commit3b3b89886af38426af83a62ad304c7581c333dcf (patch)
tree65488ef6a3438692c5a618ccf5e9ebe934c7f694
parentccfae9be6fe0b7631b8b18d54d598954a6d24ef3 (diff)
parent0ed642cb8b985b4c345dcc71979bc0ade22b4224 (diff)
downloadsecurity-3b3b89886af38426af83a62ad304c7581c333dcf.tar.gz
release-request-80d7cd88-53c4-4e65-952a-f34bc86a0841-for-git_oc-mr1-release-4050000 snap-temp-L22200000068540971
Change-Id: I7d655fb5fa7ada616da1656ea2e2852b5fa583ea
-rw-r--r--keystore/blob.cpp235
-rw-r--r--keystore/blob.h60
-rw-r--r--keystore/keystore.cpp4
-rw-r--r--keystore/user_state.cpp16
-rw-r--r--keystore/user_state.h6
5 files changed, 209 insertions, 112 deletions
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
index 237d8962..a33334ee 100644
--- a/keystore/blob.cpp
+++ b/keystore/blob.cpp
@@ -28,15 +28,117 @@
#include "keystore_utils.h"
+namespace {
+
+constexpr size_t kGcmIvSizeBytes = 96 / 8;
+
+template <typename T, void (*FreeFunc)(T*)> struct OpenSslObjectDeleter {
+ void operator()(T* p) { FreeFunc(p); }
+};
+
+#define DEFINE_OPENSSL_OBJECT_POINTER(name) \
+ typedef OpenSslObjectDeleter<name, name##_free> name##_Delete; \
+ typedef std::unique_ptr<name, name##_Delete> name##_Ptr;
+
+DEFINE_OPENSSL_OBJECT_POINTER(EVP_CIPHER_CTX);
+
+#if defined(__clang__)
+#define OPTNONE __attribute__((optnone))
+#elif defined(__GNUC__)
+#define OPTNONE __attribute__((optimize("O0")))
+#else
+#error Need a definition for OPTNONE
+#endif
+
+class ArrayEraser {
+ public:
+ ArrayEraser(uint8_t* arr, size_t size) : mArr(arr), mSize(size) {}
+ OPTNONE ~ArrayEraser() { std::fill(mArr, mArr + mSize, 0); }
+
+ private:
+ volatile uint8_t* mArr;
+ size_t mSize;
+};
+
+/*
+ * Encrypt 'len' data at 'in' with AES-GCM, using 128-bit key at 'key', 96-bit IV at 'iv' and write
+ * output to 'out' (which may be the same location as 'in') and 128-bit tag to 'tag'.
+ */
+ResponseCode AES_gcm_encrypt(const uint8_t* in, uint8_t* out, size_t len, const uint8_t* key,
+ const uint8_t* iv, uint8_t* tag) {
+ const EVP_CIPHER* cipher = EVP_aes_128_gcm();
+ EVP_CIPHER_CTX_Ptr ctx(EVP_CIPHER_CTX_new());
+
+ EVP_EncryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key, iv);
+ EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
+
+ std::unique_ptr<uint8_t[]> out_tmp(new uint8_t[len]);
+ uint8_t* out_pos = out_tmp.get();
+ int out_len;
+
+ EVP_EncryptUpdate(ctx.get(), out_pos, &out_len, in, len);
+ out_pos += out_len;
+ EVP_EncryptFinal_ex(ctx.get(), out_pos, &out_len);
+ out_pos += out_len;
+ if (out_pos - out_tmp.get() != static_cast<ssize_t>(len)) {
+ ALOGD("Encrypted ciphertext is the wrong size, expected %zu, got %zd", len,
+ out_pos - out_tmp.get());
+ return ResponseCode::SYSTEM_ERROR;
+ }
+
+ std::copy(out_tmp.get(), out_pos, out);
+ EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, kGcmTagLength, tag);
+
+ return ResponseCode::NO_ERROR;
+}
+
+/*
+ * Decrypt 'len' data at 'in' with AES-GCM, using 128-bit key at 'key', 96-bit IV at 'iv', checking
+ * 128-bit tag at 'tag' and writing plaintext to 'out' (which may be the same location as 'in').
+ */
+ResponseCode AES_gcm_decrypt(const uint8_t* in, uint8_t* out, size_t len, const uint8_t* key,
+ const uint8_t* iv, const uint8_t* tag) {
+ const EVP_CIPHER* cipher = EVP_aes_128_gcm();
+ EVP_CIPHER_CTX_Ptr ctx(EVP_CIPHER_CTX_new());
+
+ EVP_DecryptInit_ex(ctx.get(), cipher, nullptr /* engine */, key, iv);
+ EVP_CIPHER_CTX_set_padding(ctx.get(), 0 /* no padding needed with GCM */);
+ EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, kGcmTagLength, const_cast<uint8_t*>(tag));
+
+ std::unique_ptr<uint8_t[]> out_tmp(new uint8_t[len]);
+ ArrayEraser out_eraser(out_tmp.get(), len);
+ uint8_t* out_pos = out_tmp.get();
+ int out_len;
+
+ EVP_DecryptUpdate(ctx.get(), out_pos, &out_len, in, len);
+ out_pos += out_len;
+ if (!EVP_DecryptFinal_ex(ctx.get(), out_pos, &out_len)) {
+ ALOGD("Failed to decrypt blob; ciphertext or tag is likely corrupted");
+ return ResponseCode::SYSTEM_ERROR;
+ }
+ out_pos += out_len;
+ if (out_pos - out_tmp.get() != static_cast<ssize_t>(len)) {
+ ALOGD("Encrypted plaintext is the wrong size, expected %zu, got %zd", len,
+ out_pos - out_tmp.get());
+ return ResponseCode::SYSTEM_ERROR;
+ }
+
+ std::copy(out_tmp.get(), out_pos, out);
+
+ return ResponseCode::NO_ERROR;
+}
+
+} // namespace
+
Blob::Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_t infoLength,
BlobType type) {
memset(&mBlob, 0, sizeof(mBlob));
- if (valueLength > VALUE_SIZE) {
- valueLength = VALUE_SIZE;
+ if (valueLength > kValueSize) {
+ valueLength = kValueSize;
ALOGW("Provided blob length too large");
}
- if (infoLength + valueLength > VALUE_SIZE) {
- infoLength = VALUE_SIZE - valueLength;
+ if (infoLength + valueLength > kValueSize) {
+ infoLength = kValueSize - valueLength;
ALOGW("Provided info length too large");
}
mBlob.length = valueLength;
@@ -55,7 +157,7 @@ Blob::Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_
}
}
-Blob::Blob(blob b) {
+Blob::Blob(blobv3 b) {
mBlob = b;
}
@@ -103,45 +205,31 @@ void Blob::setFallback(bool fallback) {
}
}
-ResponseCode Blob::writeBlob(const char* filename, AES_KEY* aes_key, State state,
+ResponseCode Blob::writeBlob(const std::string& filename, const uint8_t* aes_key, State state,
Entropy* entropy) {
- ALOGV("writing blob %s", filename);
+ ALOGV("writing blob %s", filename.c_str());
+
+ const size_t dataLength = mBlob.length;
+ mBlob.length = htonl(mBlob.length);
+
if (isEncrypted() || isSuperEncrypted()) {
if (state != STATE_NO_ERROR) {
ALOGD("couldn't insert encrypted blob while not unlocked");
return ResponseCode::LOCKED;
}
- if (!entropy->generate_random_data(mBlob.vector, AES_BLOCK_SIZE)) {
- ALOGW("Could not read random data for: %s", filename);
+ memset(mBlob.initialization_vector, 0, AES_BLOCK_SIZE);
+ if (!entropy->generate_random_data(mBlob.initialization_vector, kGcmIvSizeBytes)) {
+ ALOGW("Could not read random data for: %s", filename.c_str());
return ResponseCode::SYSTEM_ERROR;
}
- }
-
- // data includes the value and the value's length
- size_t dataLength = mBlob.length + sizeof(mBlob.length);
- // pad data to the AES_BLOCK_SIZE
- size_t digestedLength = ((dataLength + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE * AES_BLOCK_SIZE);
- // encrypted data includes the digest value
- size_t encryptedLength = digestedLength + MD5_DIGEST_LENGTH;
- // move info after space for padding
- memmove(&mBlob.encrypted[encryptedLength], &mBlob.value[mBlob.length], mBlob.info);
- // zero padding area
- memset(mBlob.value + mBlob.length, 0, digestedLength - dataLength);
-
- mBlob.length = htonl(mBlob.length);
-
- if (isEncrypted() || isSuperEncrypted()) {
- MD5(mBlob.digested, digestedLength, mBlob.digest);
- uint8_t vector[AES_BLOCK_SIZE];
- memcpy(vector, mBlob.vector, AES_BLOCK_SIZE);
- AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, vector,
- AES_ENCRYPT);
+ auto rc = AES_gcm_encrypt(mBlob.value /* in */, mBlob.value /* out */, dataLength, aes_key,
+ mBlob.initialization_vector, mBlob.aead_tag);
+ if (rc != ResponseCode::NO_ERROR) return rc;
}
- size_t headerLength = (mBlob.encrypted - (uint8_t*)&mBlob);
- size_t fileLength = encryptedLength + headerLength + mBlob.info;
+ size_t fileLength = offsetof(blobv3, value) + dataLength + mBlob.info;
const char* tmpFileName = ".tmp";
int out =
@@ -150,7 +238,8 @@ ResponseCode Blob::writeBlob(const char* filename, AES_KEY* aes_key, State state
ALOGW("could not open file: %s: %s", tmpFileName, strerror(errno));
return ResponseCode::SYSTEM_ERROR;
}
- size_t writtenBytes = writeFully(out, (uint8_t*)&mBlob, fileLength);
+
+ const size_t writtenBytes = writeFully(out, (uint8_t*)&mBlob, fileLength);
if (close(out) != 0) {
return ResponseCode::SYSTEM_ERROR;
}
@@ -159,23 +248,22 @@ ResponseCode Blob::writeBlob(const char* filename, AES_KEY* aes_key, State state
unlink(tmpFileName);
return ResponseCode::SYSTEM_ERROR;
}
- if (rename(tmpFileName, filename) == -1) {
- ALOGW("could not rename blob to %s: %s", filename, strerror(errno));
+ if (rename(tmpFileName, filename.c_str()) == -1) {
+ ALOGW("could not rename blob to %s: %s", filename.c_str(), strerror(errno));
return ResponseCode::SYSTEM_ERROR;
}
return ResponseCode::NO_ERROR;
}
-ResponseCode Blob::readBlob(const char* filename, AES_KEY* aes_key, State state) {
- ALOGV("reading blob %s", filename);
- int in = TEMP_FAILURE_RETRY(open(filename, O_RDONLY));
+ResponseCode Blob::readBlob(const std::string& filename, const uint8_t* aes_key, State state) {
+ ALOGV("reading blob %s", filename.c_str());
+ const int in = TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY));
if (in < 0) {
return (errno == ENOENT) ? ResponseCode::KEY_NOT_FOUND : ResponseCode::SYSTEM_ERROR;
}
- // fileLength may be less than sizeof(mBlob) since the in
- // memory version has extra padding to tolerate rounding up to
- // the AES_BLOCK_SIZE
- size_t fileLength = readFully(in, (uint8_t*)&mBlob, sizeof(mBlob));
+
+ // fileLength may be less than sizeof(mBlob)
+ const size_t fileLength = readFully(in, (uint8_t*)&mBlob, sizeof(mBlob));
if (close(in) != 0) {
return ResponseCode::SYSTEM_ERROR;
}
@@ -188,42 +276,53 @@ ResponseCode Blob::readBlob(const char* filename, AES_KEY* aes_key, State state)
return ResponseCode::LOCKED;
}
- size_t headerLength = (mBlob.encrypted - (uint8_t*)&mBlob);
- if (fileLength < headerLength) {
- return ResponseCode::VALUE_CORRUPTED;
- }
+ if (fileLength < offsetof(blobv3, value)) return ResponseCode::VALUE_CORRUPTED;
- ssize_t encryptedLength = fileLength - (headerLength + mBlob.info);
- if (encryptedLength < 0) {
- return ResponseCode::VALUE_CORRUPTED;
- }
+ if (mBlob.version == 3) {
+ const ssize_t encryptedLength = ntohl(mBlob.length);
- ssize_t digestedLength;
- if (isEncrypted() || isSuperEncrypted()) {
- if (encryptedLength % AES_BLOCK_SIZE != 0) {
- return ResponseCode::VALUE_CORRUPTED;
+ if (isEncrypted() || isSuperEncrypted()) {
+ auto rc = AES_gcm_decrypt(mBlob.value /* in */, mBlob.value /* out */, encryptedLength,
+ aes_key, mBlob.initialization_vector, mBlob.aead_tag);
+ if (rc != ResponseCode::NO_ERROR) return rc;
}
-
- AES_cbc_encrypt(mBlob.encrypted, mBlob.encrypted, encryptedLength, aes_key, mBlob.vector,
- AES_DECRYPT);
- digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
- uint8_t computedDigest[MD5_DIGEST_LENGTH];
- MD5(mBlob.digested, digestedLength, computedDigest);
- if (memcmp(mBlob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
- return ResponseCode::VALUE_CORRUPTED;
+ } else if (mBlob.version < 3) {
+ blobv2& blob = reinterpret_cast<blobv2&>(mBlob);
+ const size_t headerLength = offsetof(blobv2, encrypted);
+ const ssize_t encryptedLength = fileLength - headerLength - blob.info;
+ if (encryptedLength < 0) return ResponseCode::VALUE_CORRUPTED;
+
+ if (isEncrypted() || isSuperEncrypted()) {
+ if (encryptedLength % AES_BLOCK_SIZE != 0) {
+ return ResponseCode::VALUE_CORRUPTED;
+ }
+
+ AES_KEY key;
+ AES_set_decrypt_key(aes_key, kAesKeySize * 8, &key);
+ AES_cbc_encrypt(blob.encrypted, blob.encrypted, encryptedLength, &key, blob.vector,
+ AES_DECRYPT);
+ key = {}; // clear key
+
+ uint8_t computedDigest[MD5_DIGEST_LENGTH];
+ ssize_t digestedLength = encryptedLength - MD5_DIGEST_LENGTH;
+ MD5(blob.digested, digestedLength, computedDigest);
+ if (memcmp(blob.digest, computedDigest, MD5_DIGEST_LENGTH) != 0) {
+ return ResponseCode::VALUE_CORRUPTED;
+ }
}
- } else {
- digestedLength = encryptedLength;
}
- ssize_t maxValueLength = digestedLength - sizeof(mBlob.length);
+ const ssize_t maxValueLength = fileLength - offsetof(blobv3, value) - mBlob.info;
mBlob.length = ntohl(mBlob.length);
- if (mBlob.length < 0 || mBlob.length > maxValueLength) {
+ if (mBlob.length < 0 || mBlob.length > maxValueLength ||
+ mBlob.length + mBlob.info + AES_BLOCK_SIZE > static_cast<ssize_t>(sizeof(mBlob.value))) {
return ResponseCode::VALUE_CORRUPTED;
}
- if (mBlob.info != 0) {
+
+ if (mBlob.info != 0 && mBlob.version < 3) {
// move info from after padding to after data
- memmove(&mBlob.value[mBlob.length], &mBlob.value[maxValueLength], mBlob.info);
+ memmove(mBlob.value + mBlob.length, mBlob.value + maxValueLength, mBlob.info);
}
+
return ResponseCode::NO_ERROR;
}
diff --git a/keystore/blob.h b/keystore/blob.h
index 06f9ea5a..53350379 100644
--- a/keystore/blob.h
+++ b/keystore/blob.h
@@ -24,32 +24,32 @@
#include <keystore/keystore.h>
-#define VALUE_SIZE 32768
+constexpr size_t kValueSize = 32768;
+constexpr size_t kAesKeySize = 128 / 8;
+constexpr size_t kGcmTagLength = 128 / 8;
+constexpr size_t kGcmIvLength = 96 / 8;
/* Here is the file format. There are two parts in blob.value, the secret and
* the description. The secret is stored in ciphertext, and its original size
* can be found in blob.length. The description is stored after the secret in
* plaintext, and its size is specified in blob.info. The total size of the two
- * parts must be no more than VALUE_SIZE bytes. The first field is the version,
+ * parts must be no more than kValueSize bytes. The first field is the version,
* the second is the blob's type, and the third byte is flags. Fields other
* than blob.info, blob.length, and blob.value are modified by encryptBlob()
* and decryptBlob(). Thus they should not be accessed from outside. */
-/* ** Note to future implementors of encryption: **
- * Currently this is the construction:
- * metadata || Enc(MD5(data) || data)
- *
- * This should be the construction used for encrypting if re-implementing:
- *
- * Derive independent keys for encryption and MAC:
- * Kenc = AES_encrypt(masterKey, "Encrypt")
- * Kmac = AES_encrypt(masterKey, "MAC")
- *
- * Store this:
- * metadata || AES_CTR_encrypt(Kenc, rand_IV, data) ||
- * HMAC(Kmac, metadata || Enc(data))
- */
-struct __attribute__((packed)) blob {
+struct __attribute__((packed)) blobv3 {
+ uint8_t version;
+ uint8_t type;
+ uint8_t flags;
+ uint8_t info;
+ uint8_t initialization_vector[AES_BLOCK_SIZE]; // Only 96 bits is used, rest is zeroed.
+ uint8_t aead_tag[kGcmTagLength];
+ int32_t length; // in network byte order, only for backward compatibility
+ uint8_t value[kValueSize + AES_BLOCK_SIZE];
+};
+
+struct __attribute__((packed)) blobv2 {
uint8_t version;
uint8_t type;
uint8_t flags;
@@ -58,11 +58,19 @@ struct __attribute__((packed)) blob {
uint8_t encrypted[0]; // Marks offset to encrypted data.
uint8_t digest[MD5_DIGEST_LENGTH];
uint8_t digested[0]; // Marks offset to digested data.
- int32_t length; // in network byte order when encrypted
- uint8_t value[VALUE_SIZE + AES_BLOCK_SIZE];
+ int32_t length; // in network byte order
+ uint8_t value[kValueSize + AES_BLOCK_SIZE];
};
-static const uint8_t CURRENT_BLOB_VERSION = 2;
+static_assert(sizeof(blobv3) == sizeof(blobv2) &&
+ offsetof(blobv3, initialization_vector) == offsetof(blobv2, vector) &&
+ offsetof(blobv3, aead_tag) == offsetof(blobv2, digest) &&
+ offsetof(blobv3, aead_tag) == offsetof(blobv2, encrypted) &&
+ offsetof(blobv3, length) == offsetof(blobv2, length) &&
+ offsetof(blobv3, value) == offsetof(blobv2, value),
+ "Oops. Blob layout changed.");
+
+static const uint8_t CURRENT_BLOB_VERSION = 3;
typedef enum {
TYPE_ANY = 0, // meta type that matches anything
@@ -79,10 +87,11 @@ class Blob {
public:
Blob(const uint8_t* value, size_t valueLength, const uint8_t* info, uint8_t infoLength,
BlobType type);
- explicit Blob(blob b);
-
+ explicit Blob(blobv3 b);
Blob();
+ ~Blob() { mBlob = {}; }
+
const uint8_t* getValue() const { return mBlob.value; }
int32_t getLength() const { return mBlob.length; }
@@ -108,11 +117,12 @@ class Blob {
BlobType getType() const { return BlobType(mBlob.type); }
void setType(BlobType type) { mBlob.type = uint8_t(type); }
- ResponseCode writeBlob(const char* filename, AES_KEY* aes_key, State state, Entropy* entropy);
- ResponseCode readBlob(const char* filename, AES_KEY* aes_key, State state);
+ ResponseCode writeBlob(const std::string& filename, const uint8_t* aes_key, State state,
+ Entropy* entropy);
+ ResponseCode readBlob(const std::string& filename, const uint8_t* aes_key, State state);
private:
- struct blob mBlob;
+ blobv3 mBlob;
};
#endif // KEYSTORE_BLOB_H_
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index 130a30e6..43bb4bec 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -259,7 +259,7 @@ void KeyStore::lock(uid_t userId) {
ResponseCode KeyStore::get(const char* filename, Blob* keyBlob, const BlobType type, uid_t userId) {
UserState* userState = getUserState(userId);
ResponseCode rc =
- keyBlob->readBlob(filename, userState->getDecryptionKey(), userState->getState());
+ keyBlob->readBlob(filename, userState->getEncryptionKey(), userState->getState());
if (rc != ResponseCode::NO_ERROR) {
return rc;
}
@@ -272,7 +272,7 @@ ResponseCode KeyStore::get(const char* filename, Blob* keyBlob, const BlobType t
*/
if (upgradeBlob(filename, keyBlob, version, type, userId)) {
if ((rc = this->put(filename, keyBlob, userId)) != ResponseCode::NO_ERROR ||
- (rc = keyBlob->readBlob(filename, userState->getDecryptionKey(),
+ (rc = keyBlob->readBlob(filename, userState->getEncryptionKey(),
userState->getState())) != ResponseCode::NO_ERROR) {
return rc;
}
diff --git a/keystore/user_state.cpp b/keystore/user_state.cpp
index bd4f9792..5f9cd5f5 100644
--- a/keystore/user_state.cpp
+++ b/keystore/user_state.cpp
@@ -68,8 +68,6 @@ void UserState::setState(State state) {
void UserState::zeroizeMasterKeysInMemory() {
memset(mMasterKey, 0, sizeof(mMasterKey));
memset(mSalt, 0, sizeof(mSalt));
- memset(&mMasterKeyEncryption, 0, sizeof(mMasterKeyEncryption));
- memset(&mMasterKeyDecryption, 0, sizeof(mMasterKeyDecryption));
}
bool UserState::deleteMasterKey() {
@@ -110,7 +108,7 @@ ResponseCode UserState::copyMasterKeyFile(UserState* src) {
if (in < 0) {
return ResponseCode::SYSTEM_ERROR;
}
- blob rawBlob;
+ blobv3 rawBlob;
size_t length = readFully(in, (uint8_t*)&rawBlob, sizeof(rawBlob));
if (close(in) != 0) {
return ResponseCode::SYSTEM_ERROR;
@@ -135,10 +133,8 @@ ResponseCode UserState::copyMasterKeyFile(UserState* src) {
ResponseCode UserState::writeMasterKey(const android::String8& pw, Entropy* entropy) {
uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, mSalt);
- AES_KEY passwordAesKey;
- AES_set_encrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
Blob masterKeyBlob(mMasterKey, sizeof(mMasterKey), mSalt, sizeof(mSalt), TYPE_MASTER_KEY);
- return masterKeyBlob.writeBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR, entropy);
+ return masterKeyBlob.writeBlob(mMasterKeyFile, passwordKey, STATE_NO_ERROR, entropy);
}
ResponseCode UserState::readMasterKey(const android::String8& pw, Entropy* entropy) {
@@ -149,7 +145,7 @@ ResponseCode UserState::readMasterKey(const android::String8& pw, Entropy* entro
// We read the raw blob to just to get the salt to generate the AES key, then we create the Blob
// to use with decryptBlob
- blob rawBlob;
+ blobv3 rawBlob;
size_t length = readFully(in, (uint8_t*)&rawBlob, sizeof(rawBlob));
if (close(in) != 0) {
return ResponseCode::SYSTEM_ERROR;
@@ -163,10 +159,8 @@ ResponseCode UserState::readMasterKey(const android::String8& pw, Entropy* entro
}
uint8_t passwordKey[MASTER_KEY_SIZE_BYTES];
generateKeyFromPassword(passwordKey, MASTER_KEY_SIZE_BYTES, pw, salt);
- AES_KEY passwordAesKey;
- AES_set_decrypt_key(passwordKey, MASTER_KEY_SIZE_BITS, &passwordAesKey);
Blob masterKeyBlob(rawBlob);
- ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, &passwordAesKey, STATE_NO_ERROR);
+ ResponseCode response = masterKeyBlob.readBlob(mMasterKeyFile, passwordKey, STATE_NO_ERROR);
if (response == ResponseCode::SYSTEM_ERROR) {
return response;
}
@@ -258,7 +252,5 @@ bool UserState::generateMasterKey(Entropy* entropy) {
}
void UserState::setupMasterKeys() {
- AES_set_encrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyEncryption);
- AES_set_decrypt_key(mMasterKey, MASTER_KEY_SIZE_BITS, &mMasterKeyDecryption);
setState(STATE_NO_ERROR);
}
diff --git a/keystore/user_state.h b/keystore/user_state.h
index 902719c2..c28f7b8f 100644
--- a/keystore/user_state.h
+++ b/keystore/user_state.h
@@ -54,8 +54,7 @@ class UserState {
ResponseCode writeMasterKey(const android::String8& pw, Entropy* entropy);
ResponseCode readMasterKey(const android::String8& pw, Entropy* entropy);
- AES_KEY* getEncryptionKey() { return &mMasterKeyEncryption; }
- AES_KEY* getDecryptionKey() { return &mMasterKeyDecryption; }
+ auto& getEncryptionKey() const { return mMasterKey; }
bool reset();
@@ -82,9 +81,6 @@ class UserState {
uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
uint8_t mSalt[SALT_SIZE];
-
- AES_KEY mMasterKeyEncryption;
- AES_KEY mMasterKeyDecryption;
};
#endif // KEYSTORE_USER_STATE_H_