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;