Merge "Switch *_METHOD to a more future-proof pattern."
am: f3147f209c
Change-Id: I68777f100f68cfdcf36d9a79b0c72433764cc429
diff --git a/keystore-engine/android_engine.cpp b/keystore-engine/android_engine.cpp
index efb1d08..779437d 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
@@ -256,21 +257,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..7dd5aef 100644
--- a/keystore/Android.mk
+++ b/keystore/Android.mk
@@ -43,6 +43,7 @@
operation.cpp \
permissions.cpp \
user_state.cpp \
+ grant_store.cpp \
../../../frameworks/base/core/java/android/security/keymaster/IKeyAttestationApplicationIdProvider.aidl
LOCAL_SHARED_LIBRARIES := \
libbinder \
@@ -57,7 +58,8 @@
libselinux \
libsoftkeymasterdevice \
libkeymaster_messages \
- libkeymaster1 \
+ libkeymaster_portable \
+ libkeymaster_staging \
libhwbinder \
libhidlbase \
libhidltransport \
diff --git a/keystore/IKeystoreService.cpp b/keystore/IKeystoreService.cpp
index 344687b..eee9942 100644
--- a/keystore/IKeystoreService.cpp
+++ b/keystore/IKeystoreService.cpp
@@ -442,7 +442,7 @@
return ResponseCode(reply.readInt32());
}
- KeyStoreServiceReturnCode grant(const String16& name, int32_t granteeUid) override {
+ String16 grant(const String16& name, int32_t granteeUid) override {
Parcel data, reply;
data.writeInterfaceToken(IKeystoreService::getInterfaceDescriptor());
data.writeString16(name);
@@ -450,14 +450,14 @@
status_t status = remote()->transact(BnKeystoreService::GRANT, data, &reply);
if (status != NO_ERROR) {
ALOGD("grant() could not contact remote: %d\n", status);
- return ResponseCode::SYSTEM_ERROR;
+ return String16();
}
int32_t err = reply.readExceptionCode();
if (err < 0) {
ALOGD("grant() caught exception %d\n", err);
- return ResponseCode::SYSTEM_ERROR;
+ return String16();
}
- return ResponseCode(reply.readInt32());
+ return reply.readString16();
}
KeyStoreServiceReturnCode ungrant(const String16& name, int32_t granteeUid) override {
@@ -1112,9 +1112,9 @@
CHECK_INTERFACE(IKeystoreService, data, reply);
String16 name = data.readString16();
int32_t granteeUid = data.readInt32();
- int32_t ret = grant(name, granteeUid);
+ String16 ret = grant(name, granteeUid);
reply->writeNoException();
- reply->writeInt32(ret);
+ reply->writeString16(ret);
return NO_ERROR;
} break;
case UNGRANT: {
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/grant_store.cpp b/keystore/grant_store.cpp
new file mode 100644
index 0000000..9c2e591
--- /dev/null
+++ b/keystore/grant_store.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#include "grant_store.h"
+
+#include <algorithm>
+#include <sstream>
+
+namespace keystore {
+
+static constexpr uint64_t kInvalidGrantNo = std::numeric_limits<uint64_t>::max();
+static const char* kKeystoreGrantInfix = "_KEYSTOREGRANT_";
+static constexpr size_t kKeystoreGrantInfixLength = 15;
+
+Grant::Grant(const std::string& alias, const std::string& key_file, const uint64_t grant_no)
+ : alias_(alias), key_file_(key_file), grant_no_(grant_no) {}
+
+static std::pair<uint64_t, std::string> parseGrantAlias(const std::string& grantAlias) {
+ auto pos = grantAlias.rfind(kKeystoreGrantInfix);
+ if (pos == std::string::npos) return {kInvalidGrantNo, ""};
+ std::stringstream s(grantAlias.substr(pos + kKeystoreGrantInfixLength));
+ std::string wrapped_alias = grantAlias.substr(0, pos);
+ uint64_t grant_no = kInvalidGrantNo;
+ s >> grant_no;
+ if (s.fail() || grant_no == kInvalidGrantNo) return {kInvalidGrantNo, ""};
+ return {grant_no, wrapped_alias};
+}
+
+std::string GrantStore::put(const uid_t uid, const std::string& alias, const std::string& key_file) {
+ std::stringstream s;
+ s << alias << kKeystoreGrantInfix;
+ auto& uid_grant_list = grants_[uid];
+
+ bool success = false;
+ auto iterator = std::find_if(uid_grant_list.begin(), uid_grant_list.end(),
+ [&](auto& entry) {
+ return success = entry.alias_ == alias && entry.key_file_ == key_file;
+ });
+ while (!success) {
+ std::tie(iterator, success) = uid_grant_list.emplace(alias, key_file, std::rand());
+ }
+ s << iterator->grant_no_;
+ return s.str();
+}
+
+const Grant* GrantStore::get(const uid_t uid, const std::string& alias) const {
+ uint64_t grant_no;
+ std::string wrappedAlias;
+ std::tie(grant_no, wrappedAlias) = parseGrantAlias(alias);
+ if (grant_no == kInvalidGrantNo) return nullptr;
+ auto uid_set_iter = grants_.find(uid);
+ if (uid_set_iter == grants_.end()) return nullptr;
+ auto& uid_grant_list = uid_set_iter->second;
+ auto grant = uid_grant_list.find(grant_no);
+ if (grant == uid_grant_list.end()) return nullptr;
+ if (grant->alias_ != wrappedAlias) return nullptr;
+ return &(*grant);
+}
+
+bool GrantStore::removeByFileName(const uid_t uid, const std::string& fileName) {
+ auto& uid_grant_list = grants_.operator[](uid);
+ for (auto i = uid_grant_list.begin(); i != uid_grant_list.end(); ++i) {
+ if (i->key_file_ == fileName) {
+ uid_grant_list.erase(i);
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace keystore
diff --git a/keystore/grant_store.h b/keystore/grant_store.h
new file mode 100644
index 0000000..43e814e
--- /dev/null
+++ b/keystore/grant_store.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 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_GRANT_STORE_H_
+#define KEYSTORE_GRANT_STORE_H_
+
+#include <set>
+#include <string>
+#include <unordered_map>
+
+namespace keystore {
+
+/**
+ * Grant represents a mapping from an alias to a key file.
+ * Normally, key file names are derived from the alias chosen by the client
+ * and the clients UID, to generate a per client name space.
+ * Grants allow assotiating a key file with a new name, thereby making
+ * it visible in another client's - the grantee's - namespace.
+ */
+class Grant {
+public:
+ Grant(const std::string& alias, const std::string& key_file, const uint64_t grant_no);
+ std::string alias_;
+ std::string key_file_;
+ uint64_t grant_no_;
+
+ operator const uint64_t&() const { return grant_no_; }
+};
+
+/**
+ * The GrantStore holds a set of sets of Grants. One set of Grants for each grantee.
+ * The uid parameter to each of the GrantStore function determines the grantee's
+ * name space. The methods put, get, and removeByAlias/ByFileName create, lookup, and
+ * remove a Grant, respectively.
+ * put also returns a new alias for the newly granted key which has to be returned
+ * to the granter. The grantee, and only the grantee, can use the granted key
+ * by this new alias.
+ */
+class GrantStore {
+public:
+ GrantStore() : grants_() {}
+ std::string put(const uid_t uid, const std::string& alias, const std::string& key_file);
+ const Grant* get(const uid_t uid, const std::string& alias) const;
+ bool removeByFileName(const uid_t uid, const std::string& filename);
+
+ // GrantStore is neither copyable nor movable.
+ GrantStore(const GrantStore&) = delete;
+ GrantStore& operator=(const GrantStore&) = delete;
+private:
+ std::unordered_map<uid_t, std::set<Grant, std::less<>>> grants_;
+};
+
+} // namespace keystore
+
+#endif // KEYSTORE_GRANT_STORE_H_
diff --git a/keystore/include/keystore/IKeystoreService.h b/keystore/include/keystore/IKeystoreService.h
index 18bd8eb..a045679 100644
--- a/keystore/include/keystore/IKeystoreService.h
+++ b/keystore/include/keystore/IKeystoreService.h
@@ -166,8 +166,7 @@
virtual ::keystore::KeyStoreServiceReturnCode
get_pubkey(const String16& name, ::keystore::hidl_vec<uint8_t>* pubKey) = 0;
- virtual ::keystore::KeyStoreServiceReturnCode grant(const String16& name,
- int32_t granteeUid) = 0;
+ virtual String16 grant(const String16& name, int32_t granteeUid) = 0;
virtual ::keystore::KeyStoreServiceReturnCode ungrant(const String16& name,
int32_t granteeUid) = 0;
diff --git a/keystore/key_store_service.cpp b/keystore/key_store_service.cpp
index 1f4d385..abd93f1 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(),
@@ -512,22 +512,21 @@
return ResponseCode::NO_ERROR;
}
-KeyStoreServiceReturnCode KeyStoreService::grant(const String16& name, int32_t granteeUid) {
+String16 KeyStoreService::grant(const String16& name, int32_t granteeUid) {
uid_t callingUid = IPCThreadState::self()->getCallingUid();
auto result = checkBinderPermissionAndKeystoreState(P_GRANT);
if (!result.isOk()) {
- return result;
+ return String16();
}
String8 name8(name);
String8 filename(mKeyStore->getKeyNameForUidWithDir(name8, callingUid, ::TYPE_ANY));
if (access(filename.string(), R_OK) == -1) {
- return (errno != ENOENT) ? ResponseCode::SYSTEM_ERROR : ResponseCode::KEY_NOT_FOUND;
+ return String16();
}
- mKeyStore->addGrant(filename.string(), granteeUid);
- return ResponseCode::NO_ERROR;
+ return String16(mKeyStore->addGrant(filename.string(), String8(name).string(), granteeUid).c_str());
}
KeyStoreServiceReturnCode KeyStoreService::ungrant(const String16& name, int32_t granteeUid) {
diff --git a/keystore/key_store_service.h b/keystore/key_store_service.h
index 3b4ef85..4060bd1 100644
--- a/keystore/key_store_service.h
+++ b/keystore/key_store_service.h
@@ -84,7 +84,7 @@
KeyStoreServiceReturnCode get_pubkey(const android::String16& name,
hidl_vec<uint8_t>* pubKey) override;
- KeyStoreServiceReturnCode grant(const android::String16& name, int32_t granteeUid) override;
+ android::String16 grant(const android::String16& name, int32_t granteeUid) override;
KeyStoreServiceReturnCode ungrant(const android::String16& name, int32_t granteeUid) override;
int64_t getmtime(const android::String16& name, int32_t uid) override;
diff --git a/keystore/keystore.cpp b/keystore/keystore.cpp
index bc2e0dc..ab386ad 100644
--- a/keystore/keystore.cpp
+++ b/keystore/keystore.cpp
@@ -48,11 +48,6 @@
}
KeyStore::~KeyStore() {
- for (android::Vector<grant_t*>::iterator it(mGrants.begin()); it != mGrants.end(); it++) {
- delete *it;
- }
- mGrants.clear();
-
for (android::Vector<UserState*>::iterator it(mMasterKeys.begin()); it != mMasterKeys.end();
it++) {
delete *it;
@@ -259,7 +254,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 +267,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;
}
@@ -419,26 +414,12 @@
return ResponseCode::NO_ERROR;
}
-void KeyStore::addGrant(const char* filename, uid_t granteeUid) {
- const grant_t* existing = getGrant(filename, granteeUid);
- if (existing == NULL) {
- grant_t* grant = new grant_t;
- grant->uid = granteeUid;
- grant->filename = reinterpret_cast<const uint8_t*>(strdup(filename));
- mGrants.add(grant);
- }
+std::string KeyStore::addGrant(const char* filename, const char* alias, uid_t granteeUid) {
+ return mGrants.put(granteeUid, alias, filename);
}
bool KeyStore::removeGrant(const char* filename, uid_t granteeUid) {
- for (android::Vector<grant_t*>::iterator it(mGrants.begin()); it != mGrants.end(); it++) {
- grant_t* grant = *it;
- if (grant->uid == granteeUid &&
- !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) {
- mGrants.erase(it);
- return true;
- }
- }
- return false;
+ return mGrants.removeByFileName(granteeUid, filename);
}
ResponseCode KeyStore::importKey(const uint8_t* key, size_t keyLen, const char* filename,
@@ -536,17 +517,9 @@
}
// They might be using a granted key.
- android::String8 filename8 = getKeyName(keyName, type);
- char* end;
- strtoul(filename8.string(), &end, 10);
- if (end[0] != '_' || end[1] == 0) {
- return ResponseCode::KEY_NOT_FOUND;
- }
- filepath8 = android::String8::format("%s/%s", getUserState(userId)->getUserDirName(),
- filename8.string());
- if (!hasGrant(filepath8.string(), uid)) {
- return responseCode;
- }
+ auto grant = mGrants.get(uid, keyName.string());
+ if (!grant) return ResponseCode::KEY_NOT_FOUND;
+ filepath8 = grant->key_file_.c_str();
// It is a granted key. Try to load it.
return get(filepath8.string(), keyBlob, type, userId);
@@ -595,17 +568,6 @@
return getUserState(userId);
}
-const grant_t* KeyStore::getGrant(const char* filename, uid_t uid) const {
- for (android::Vector<grant_t*>::const_iterator it(mGrants.begin()); it != mGrants.end(); it++) {
- grant_t* grant = *it;
- if (grant->uid == uid &&
- !strcmp(reinterpret_cast<const char*>(grant->filename), filename)) {
- return grant;
- }
- }
- return NULL;
-}
-
bool KeyStore::upgradeBlob(const char* filename, Blob* blob, const uint8_t oldVersion,
const BlobType type, uid_t uid) {
bool updated = false;
@@ -647,7 +609,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 +632,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.h b/keystore/keystore.h
index 8ff8899..a08508f 100644
--- a/keystore/keystore.h
+++ b/keystore/keystore.h
@@ -25,11 +25,7 @@
#include "blob.h"
#include "include/keystore/keymaster_tags.h"
-
-typedef struct {
- uint32_t uid;
- const uint8_t* filename;
-} grant_t;
+#include "grant_store.h"
using ::keystore::NullOr;
@@ -91,11 +87,8 @@
ResponseCode list(const android::String8& prefix, android::Vector<android::String16>* matches,
uid_t userId);
- void addGrant(const char* filename, uid_t granteeUid);
+ std::string addGrant(const char* filename, const char* alias, uid_t granteeUid);
bool removeGrant(const char* filename, uid_t granteeUid);
- bool hasGrant(const char* filename, const uid_t uid) const {
- return getGrant(filename, uid) != NULL;
- }
ResponseCode importKey(const uint8_t* key, size_t keyLen, const char* filename, uid_t userId,
int32_t flags);
@@ -137,14 +130,12 @@
android::Vector<UserState*> mMasterKeys;
- android::Vector<grant_t*> mGrants;
+ ::keystore::GrantStore mGrants;
typedef struct { uint32_t version; } keystore_metadata_t;
keystore_metadata_t mMetaData;
- const grant_t* getGrant(const char* filename, uid_t uid) const;
-
/**
* Upgrade the key from the current version to whatever is newest.
*/
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;