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;