Merge "Add OWNERS in system/security" am: aad9ba51cd am: 32e07b318c am: d32de98e00
am: 067111a625
Change-Id: I82a2729806c72c6652b800d6230de86db3cd440a
diff --git a/keystore-engine/android_engine.cpp b/keystore-engine/android_engine.cpp
index 25d426f..b7b8199 100644
--- a/keystore-engine/android_engine.cpp
+++ b/keystore-engine/android_engine.cpp
@@ -21,7 +21,6 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#define LOG_TAG "keystore-engine"
-#include <UniquePtr.h>
#include <pthread.h>
#include <sys/socket.h>
@@ -40,6 +39,8 @@
#include <openssl/rsa.h>
#include <openssl/x509.h>
+#include <memory>
+
#ifndef BACKEND_WIFI_HIDL
#include "keystore_backend_binder.h"
#else
@@ -291,21 +292,21 @@
EVP_PKEY_free(p);
}
};
-typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
+typedef std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
struct RSA_Delete {
void operator()(RSA* p) const {
RSA_free(p);
}
};
-typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
+typedef std::unique_ptr<RSA, RSA_Delete> Unique_RSA;
struct EC_KEY_Delete {
void operator()(EC_KEY* ec) const {
EC_KEY_free(ec);
}
};
-typedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
+typedef std::unique_ptr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
/* wrap_rsa returns an |EVP_PKEY| that contains an RSA key where the public
* part is taken from |public_rsa| and the private operations are forwarded to
diff --git a/keystore-engine/methods.h b/keystore-engine/methods.h
index fb85942..da54ce2 100644
--- a/keystore-engine/methods.h
+++ b/keystore-engine/methods.h
@@ -34,21 +34,21 @@
DSA_free(p);
}
};
-typedef UniquePtr<DSA, struct DSA_Delete> Unique_DSA;
+typedef std::unique_ptr<DSA, struct DSA_Delete> Unique_DSA;
struct EC_KEY_Delete {
void operator()(EC_KEY* p) const {
EC_KEY_free(p);
}
};
-typedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
+typedef std::unique_ptr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
struct RSA_Delete {
void operator()(RSA* p) const {
RSA_free(p);
}
};
-typedef UniquePtr<RSA, struct RSA_Delete> Unique_RSA;
+typedef std::unique_ptr<RSA, struct RSA_Delete> Unique_RSA;
/* Keyhandles for ENGINE metadata */
diff --git a/keystore/Android.mk b/keystore/Android.mk
index f87675d..cef637a 100644
--- a/keystore/Android.mk
+++ b/keystore/Android.mk
@@ -57,7 +57,8 @@
libselinux \
libsoftkeymasterdevice \
libkeymaster_messages \
- libkeymaster1 \
+ libkeymaster_portable \
+ libkeymaster_staging \
libhwbinder \
libhidlbase \
libhidltransport \
diff --git a/keystore/blob.cpp b/keystore/blob.cpp
index 237d896..a33334e 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(blob b) {
+Blob::Blob(blobv3 b) {
mBlob = b;
}
@@ -103,45 +205,31 @@
}
}
-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;
}
+
+ 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;
}
- // 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);
- }
-
- 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 @@
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 @@
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 @@
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;
}
+ } 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;
- 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;
+ 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 06f9ea5..5335037 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 @@
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 @@
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 @@
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/key_store_service.cpp b/keystore/key_store_service.cpp
index 248fa00..5f05e01 100644
--- a/keystore/key_store_service.cpp
+++ b/keystore/key_store_service.cpp
@@ -52,7 +52,7 @@
struct BIGNUM_Delete {
void operator()(BIGNUM* p) const { BN_free(p); }
};
-typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
+typedef std::unique_ptr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
bool containsTag(const hidl_vec<KeyParameter>& params, Tag tag) {
return params.end() != std::find_if(params.begin(), params.end(),
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index bc2e0dc..43bb4be 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -259,7 +259,7 @@
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 @@
*/
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;
}
@@ -647,7 +647,7 @@
struct BIO_Delete {
void operator()(BIO* p) const { BIO_free(p); }
};
-typedef UniquePtr<BIO, BIO_Delete> Unique_BIO;
+typedef std::unique_ptr<BIO, BIO_Delete> Unique_BIO;
ResponseCode KeyStore::importBlobAsKey(Blob* blob, const char* filename, uid_t uid) {
// We won't even write to the blob directly with this BIO, so const_cast is okay.
@@ -670,7 +670,7 @@
return ResponseCode::SYSTEM_ERROR;
}
- UniquePtr<unsigned char[]> pkcs8key(new unsigned char[len]);
+ std::unique_ptr<unsigned char[]> pkcs8key(new unsigned char[len]);
uint8_t* tmp = pkcs8key.get();
if (i2d_PKCS8_PRIV_KEY_INFO(pkcs8.get(), &tmp) != len) {
ALOGE("Couldn't convert to PKCS#8");
diff --git a/keystore/keystore_utils.cpp b/keystore/keystore_utils.cpp
index 0d3f0ec..b1777d0 100644
--- a/keystore/keystore_utils.cpp
+++ b/keystore/keystore_utils.cpp
@@ -25,7 +25,6 @@
#include <cutils/log.h>
#include <private/android_filesystem_config.h>
-#include <keymaster/android_keymaster_utils.h>
#include <keystore/authorization_set.h>
#include <keystore/keystore_client.h>
#include <keystore/IKeystoreService.h>
diff --git a/keystore/keystore_utils.h b/keystore/keystore_utils.h
index 0f7922a..f970559 100644
--- a/keystore/keystore_utils.h
+++ b/keystore/keystore_utils.h
@@ -26,7 +26,7 @@
#include <hardware/keymaster_defs.h>
-#include <UniquePtr.h>
+#include <memory>
#include <keystore/authorization_set.h>
@@ -52,12 +52,12 @@
struct EVP_PKEY_Delete {
void operator()(EVP_PKEY* p) const { EVP_PKEY_free(p); }
};
-typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
+typedef std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
struct PKCS8_PRIV_KEY_INFO_Delete {
void operator()(PKCS8_PRIV_KEY_INFO* p) const { PKCS8_PRIV_KEY_INFO_free(p); }
};
-typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
+typedef std::unique_ptr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
namespace keystore {
diff --git a/keystore/user_state.cpp b/keystore/user_state.cpp
index bd4f979..5f9cd5f 100644
--- a/keystore/user_state.cpp
+++ b/keystore/user_state.cpp
@@ -68,8 +68,6 @@
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 @@
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::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 @@
// 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 @@
}
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 @@
}
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 902719c..c28f7b8 100644
--- a/keystore/user_state.h
+++ b/keystore/user_state.h
@@ -54,8 +54,7 @@
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 @@
uint8_t mMasterKey[MASTER_KEY_SIZE_BYTES];
uint8_t mSalt[SALT_SIZE];
-
- AES_KEY mMasterKeyEncryption;
- AES_KEY mMasterKeyDecryption;
};
#endif // KEYSTORE_USER_STATE_H_
diff --git a/softkeymaster/keymaster_openssl.cpp b/softkeymaster/keymaster_openssl.cpp
index 927b4a6..f4d55bd 100644
--- a/softkeymaster/keymaster_openssl.cpp
+++ b/softkeymaster/keymaster_openssl.cpp
@@ -29,7 +29,7 @@
#include <openssl/err.h>
#include <openssl/x509.h>
-#include <UniquePtr.h>
+#include <memory>
// For debugging
// #define LOG_NDEBUG 0
@@ -40,43 +40,43 @@
struct BIGNUM_Delete {
void operator()(BIGNUM* p) const { BN_free(p); }
};
-typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
+typedef std::unique_ptr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
struct EVP_PKEY_Delete {
void operator()(EVP_PKEY* p) const { EVP_PKEY_free(p); }
};
-typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
+typedef std::unique_ptr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
struct PKCS8_PRIV_KEY_INFO_Delete {
void operator()(PKCS8_PRIV_KEY_INFO* p) const { PKCS8_PRIV_KEY_INFO_free(p); }
};
-typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
+typedef std::unique_ptr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
struct DSA_Delete {
void operator()(DSA* p) const { DSA_free(p); }
};
-typedef UniquePtr<DSA, DSA_Delete> Unique_DSA;
+typedef std::unique_ptr<DSA, DSA_Delete> Unique_DSA;
struct EC_KEY_Delete {
void operator()(EC_KEY* p) const { EC_KEY_free(p); }
};
-typedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
+typedef std::unique_ptr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
struct EC_GROUP_Delete {
void operator()(EC_GROUP* p) const { EC_GROUP_free(p); }
};
-typedef UniquePtr<EC_GROUP, EC_GROUP_Delete> Unique_EC_GROUP;
+typedef std::unique_ptr<EC_GROUP, EC_GROUP_Delete> Unique_EC_GROUP;
struct RSA_Delete {
void operator()(RSA* p) const { RSA_free(p); }
};
-typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
+typedef std::unique_ptr<RSA, RSA_Delete> Unique_RSA;
struct Malloc_Free {
void operator()(void* p) const { free(p); }
};
-typedef UniquePtr<keymaster0_device_t> Unique_keymaster_device_t;
+typedef std::unique_ptr<keymaster0_device_t> Unique_keymaster_device_t;
/**
* Many OpenSSL APIs take ownership of an argument on success but
@@ -85,7 +85,7 @@
* triggering a warning by not using the result of release().
*/
template <typename T, typename Delete_T>
-inline void release_because_ownership_transferred(UniquePtr<T, Delete_T>& p) {
+inline void release_because_ownership_transferred(std::unique_ptr<T, Delete_T>& p) {
T* val __attribute__((unused)) = p.release();
}
@@ -124,7 +124,7 @@
sizeof(privateLen) + publicLen;
// derData will be returned to the caller, so allocate it with malloc.
- UniquePtr<unsigned char, Malloc_Free> derData(
+ std::unique_ptr<unsigned char, Malloc_Free> derData(
static_cast<unsigned char*>(malloc(*keyBlobLength)));
if (derData.get() == NULL) {
ALOGE("could not allocate memory for key blob");
@@ -446,7 +446,7 @@
return -1;
}
- UniquePtr<uint8_t, Malloc_Free> key(static_cast<uint8_t*>(malloc(len)));
+ std::unique_ptr<uint8_t, Malloc_Free> key(static_cast<uint8_t*>(malloc(len)));
if (key.get() == NULL) {
ALOGE("Could not allocate memory for public key data");
return -1;
@@ -479,7 +479,7 @@
}
unsigned int dsaSize = DSA_size(dsa.get());
- UniquePtr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dsaSize)));
+ std::unique_ptr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dsaSize)));
if (signedDataPtr.get() == NULL) {
logOpenSSLError("openssl_sign_dsa");
return -1;
@@ -511,7 +511,7 @@
}
unsigned int ecdsaSize = ECDSA_size(eckey.get());
- UniquePtr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(ecdsaSize)));
+ std::unique_ptr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(ecdsaSize)));
if (signedDataPtr.get() == NULL) {
logOpenSSLError("openssl_sign_ec");
return -1;
@@ -545,7 +545,7 @@
return -1;
}
- UniquePtr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dataLength)));
+ std::unique_ptr<uint8_t, Malloc_Free> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dataLength)));
if (signedDataPtr.get() == NULL) {
logOpenSSLError("openssl_sign_rsa");
return -1;
@@ -667,7 +667,7 @@
return -1;
}
- UniquePtr<uint8_t[]> dataPtr(new uint8_t[signedDataLength]);
+ std::unique_ptr<uint8_t[]> dataPtr(new uint8_t[signedDataLength]);
if (dataPtr.get() == NULL) {
logOpenSSLError("openssl_verify_data");
return -1;