diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2017-05-28 07:38:33 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2017-05-28 07:38:33 +0000 |
commit | 3b3b89886af38426af83a62ad304c7581c333dcf (patch) | |
tree | 65488ef6a3438692c5a618ccf5e9ebe934c7f694 | |
parent | ccfae9be6fe0b7631b8b18d54d598954a6d24ef3 (diff) | |
parent | 0ed642cb8b985b4c345dcc71979bc0ade22b4224 (diff) | |
download | security-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.cpp | 235 | ||||
-rw-r--r-- | keystore/blob.h | 60 | ||||
-rw-r--r-- | keystore/keystore.cpp | 4 | ||||
-rw-r--r-- | keystore/user_state.cpp | 16 | ||||
-rw-r--r-- | keystore/user_state.h | 6 |
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_ |