diff --git a/Android.mk b/Android.mk
index 4ab719f..979ab5e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -27,6 +27,8 @@
 	MoveTask.cpp \
 	Benchmark.cpp \
 	TrimTask.cpp \
+	Keymaster.cpp \
+	KeyStorage.cpp \
 
 common_c_includes := \
 	system/extras/ext4_utils \
@@ -52,7 +54,9 @@
 	libutils \
 	libhardware \
 	libsoftkeymaster \
-	libbase
+	libbase \
+	libkeymaster1 \
+	libkeymaster_messages \
 
 common_static_libraries := \
 	libfs_mgr \
@@ -61,7 +65,7 @@
 	libsquashfs_utils \
 	libscrypt_static \
 	libmincrypt \
-	libbatteryservice
+	libbatteryservice \
 
 vold_conlyflags := -std=c11
 vold_cflags := -Werror -Wall -Wno-missing-field-initializers -Wno-unused-variable -Wno-unused-parameter
diff --git a/Ext4Crypt.cpp b/Ext4Crypt.cpp
index d00a7f7..475c196 100644
--- a/Ext4Crypt.cpp
+++ b/Ext4Crypt.cpp
@@ -16,11 +16,11 @@
 
 #include "Ext4Crypt.h"
 
+#include "KeyStorage.h"
 #include "Utils.h"
 
 #include <iomanip>
 #include <map>
-#include <fstream>
 #include <string>
 #include <sstream>
 
@@ -557,40 +557,20 @@
     return s_ephemeral_user_keys.find(key_path) != s_ephemeral_user_keys.end();
 }
 
-static std::string read_user_key(userid_t user_id)
+static bool read_user_key(userid_t user_id, std::string &key)
 {
     const auto key_path = get_key_path(user_id);
     const auto ephemeral_key_it = s_ephemeral_user_keys.find(key_path);
     if (ephemeral_key_it != s_ephemeral_user_keys.end()) {
-        return ephemeral_key_it->second;
+        key = ephemeral_key_it->second;
+        return true;
     }
-
-    std::string content;
-    if (!android::base::ReadFileToString(key_path, &content)) {
-        return "";
+    if (!android::vold::RetrieveKey(key_path, key)) return false;
+    if (key.size() != key_length/8) {
+        LOG(ERROR) << "Wrong size key " << key.size() << " in " << key_path;
+        return false;
     }
-    if (content.size() != key_length/8) {
-        LOG(ERROR) << "Wrong size key " << content.size() << " in " << key_path;
-        return "";
-    }
-    return content;
-}
-
-// ext4enc:TODO this can't be the only place keys are read from /dev/urandom
-// we should unite those places.
-static std::string get_random_string(size_t length) {
-    std::ifstream urandom("/dev/urandom");
-    if (!urandom) {
-        PLOG(ERROR) << "Unable to open /dev/urandom";
-        return "";
-    }
-    std::string res(length, '\0');
-    urandom.read(&res[0], length);
-    if (!urandom) {
-        PLOG(ERROR) << "Unable to read from /dev/urandom";
-        return "";
-    }
-    return res;
+    return true;
 }
 
 static bool create_user_key(userid_t user_id, bool create_ephemeral) {
@@ -599,15 +579,16 @@
         return false;
     }
     const auto key_path = get_key_path(user_id);
-    auto key = get_random_string(key_length / 8);
-    if (key.empty()) {
+    std::string key;
+    if (android::vold::ReadRandomBytes(key_length / 8, key) != 0) {
+        // TODO status_t plays badly with PLOG, fix it.
+        LOG(ERROR) << "Random read failed";
         return false;
     }
     if (create_ephemeral) {
         // If the key should be created as ephemeral, store it in memory only.
         s_ephemeral_user_keys[key_path] = key;
-    } else if (!android::base::WriteStringToFile(key, key_path)) {
-        PLOG(ERROR) << "Unable to write key to " << key_path;
+    } else if (!android::vold::StoreKey(key_path, key)) {
         return false;
     }
     LOG(DEBUG) << "Created key " << key_path;
@@ -627,7 +608,8 @@
 
 int e4crypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral) {
     LOG(DEBUG) << "e4crypt_vold_create_user_key for " << user_id << " serial " << serial;
-    if (!read_user_key(user_id).empty()) {
+    std::string key;
+    if (read_user_key(user_id, key)) {
         LOG(ERROR) << "Already exists, can't e4crypt_vold_create_user_key for "
             << user_id << " serial " << serial;
         // FIXME should we fail the command?
@@ -643,40 +625,34 @@
     return 0;
 }
 
-int e4crypt_destroy_user_key(userid_t user_id) {
-    LOG(DEBUG) << "e4crypt_destroy_user_key(" << user_id << ")";
-    // TODO: destroy second key for user_de data
+static bool evict_user_key(userid_t user_id) {
     auto key_path = get_key_path(user_id);
-    auto key = read_user_key(user_id);
+    std::string key;
+    if (!read_user_key(user_id, key)) return false;
     auto ext4_key = fill_key(key);
     auto ref = keyname(generate_key_ref(ext4_key.raw, ext4_key.size));
     auto key_serial = keyctl_search(e4crypt_keyring(), "logon", ref.c_str(), 0);
-    if (keyctl_revoke(key_serial) == 0) {
-        LOG(DEBUG) << "Revoked key with serial " << key_serial << " ref " << ref;
-    } else {
+    if (keyctl_revoke(key_serial) != 0) {
         PLOG(ERROR) << "Failed to revoke key with serial " << key_serial << " ref " << ref;
+        return false;
     }
+    LOG(DEBUG) << "Revoked key with serial " << key_serial << " ref " << ref;
+    return true;
+}
+
+int e4crypt_destroy_user_key(userid_t user_id) {
+    LOG(DEBUG) << "e4crypt_destroy_user_key(" << user_id << ")";
+    // TODO: destroy second key for user_de data
+    bool evict_success = evict_user_key(user_id);
+    auto key_path = get_key_path(user_id);
     if (e4crypt_is_key_ephemeral(key_path)) {
         s_ephemeral_user_keys.erase(key_path);
-        return 0;
+    } else {
+        if (!android::vold::DestroyKey(key_path)) {
+            return -1;
+        }
     }
-    int pid = fork();
-    if (pid < 0) {
-        PLOG(ERROR) << "Unable to fork";
-        return -1;
-    }
-    if (pid == 0) {
-        LOG(DEBUG) << "Forked for secdiscard";
-        execl("/system/bin/secdiscard",
-            "/system/bin/secdiscard",
-            "--",
-            key_path.c_str(),
-            NULL);
-        PLOG(ERROR) << "Unable to launch secdiscard on " << key_path;
-        exit(-1);
-    }
-    // ext4enc:TODO reap the zombie
-    return 0;
+    return evict_success ? 0 : -1;
 }
 
 static int emulated_lock(const std::string& path) {
@@ -712,8 +688,8 @@
 int e4crypt_unlock_user_key(userid_t user_id, int serial, const char* token) {
     LOG(DEBUG) << "e4crypt_unlock_user_key " << user_id << " " << (token != nullptr);
     if (e4crypt_is_native()) {
-        auto user_key = read_user_key(user_id);
-        if (user_key.empty()) {
+        std::string user_key;
+        if (!read_user_key(user_id, user_key)) {
             // FIXME special case for user 0
             if (user_id != 0) {
                 LOG(ERROR) << "Couldn't read key for " << user_id;
@@ -723,8 +699,7 @@
             if (!create_user_key(user_id, false)) {
                 return -1;
             }
-            user_key = read_user_key(user_id);
-            if (user_key.empty()) {
+            if (!read_user_key(user_id, user_key)) {
                 LOG(ERROR) << "Couldn't read just-created key for " << user_id;
                 return -1;
             }
diff --git a/KeyStorage.cpp b/KeyStorage.cpp
new file mode 100644
index 0000000..d435539
--- /dev/null
+++ b/KeyStorage.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2016 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 "KeyStorage.h"
+
+#include "Keymaster.h"
+#include "Utils.h"
+
+#include <vector>
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <openssl/sha.h>
+
+#include <android-base/file.h>
+#include <android-base/logging.h>
+
+#include <keymaster/authorization_set.h>
+
+namespace android {
+namespace vold {
+
+static constexpr size_t AES_KEY_BYTES = 32;
+static constexpr size_t GCM_NONCE_BYTES = 12;
+static constexpr size_t GCM_MAC_BYTES = 16;
+// FIXME: better name than "secdiscardable" sought!
+static constexpr size_t SECDISCARDABLE_BYTES = 1<<14;
+
+static const char* kRmPath = "/system/bin/rm";
+static const char* kSecdiscardPath = "/system/bin/secdiscard";
+static const char* kFn_keymaster_key_blob = "keymaster_key_blob";
+static const char* kFn_encrypted_key = "encrypted_key";
+static const char* kFn_secdiscardable = "secdiscardable";
+
+static bool CheckSize(const std::string& kind, size_t actual, size_t expected) {
+    if (actual != expected) {
+        LOG(ERROR) << "Wrong number of bytes in " << kind << ", expected " << expected
+            << " got " << actual;
+        return false;
+    }
+    return true;
+}
+
+static std::string HashSecdiscardable(const std::string &secdiscardable) {
+    SHA512_CTX c;
+
+    SHA512_Init(&c);
+    // Personalise the hashing by introducing a fixed prefix.
+    // Hashing applications should use personalization except when there is a
+    // specific reason not to; see section 4.11 of https://www.schneier.com/skein1.3.pdf
+    std::string secdiscardable_hashing_prefix = "Android secdiscardable SHA512";
+    secdiscardable_hashing_prefix.resize(SHA512_CBLOCK);
+    SHA512_Update(&c, secdiscardable_hashing_prefix.data(), secdiscardable_hashing_prefix.size());
+    SHA512_Update(&c, secdiscardable.data(), secdiscardable.size());
+    std::string res(SHA512_DIGEST_LENGTH, '\0');
+    SHA512_Final(reinterpret_cast<uint8_t *>(&res[0]), &c);
+    return res;
+}
+
+static bool GenerateKeymasterKey(Keymaster &keymaster,
+        const keymaster::AuthorizationSet &extra_params,
+        std::string &key) {
+    keymaster::AuthorizationSetBuilder param_builder;
+    param_builder
+        .AesEncryptionKey(AES_KEY_BYTES * 8)
+        .Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_GCM)
+        .Authorization(keymaster::TAG_MIN_MAC_LENGTH, GCM_MAC_BYTES * 8)
+        .Authorization(keymaster::TAG_PADDING, KM_PAD_NONE)
+        .Authorization(keymaster::TAG_NO_AUTH_REQUIRED); // FIXME integrate with gatekeeper
+    auto params = param_builder.build();
+    params.push_back(extra_params);
+    return keymaster.GenerateKey(params, key);
+}
+
+static bool EncryptWithKeymasterKey(
+        Keymaster &keymaster,
+        const std::string &key,
+        const keymaster::AuthorizationSet &extra_params,
+        const std::string &message,
+        std::string &ciphertext) {
+    // FIXME fix repetition
+    keymaster::AuthorizationSetBuilder param_builder;
+    param_builder
+        .Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_GCM)
+        .Authorization(keymaster::TAG_MAC_LENGTH, GCM_MAC_BYTES * 8)
+        .Authorization(keymaster::TAG_PADDING, KM_PAD_NONE);
+    auto params = param_builder.build();
+    params.push_back(extra_params);
+    keymaster::AuthorizationSet out_params;
+    auto op_handle = keymaster.Begin(KM_PURPOSE_ENCRYPT, key, params, out_params);
+    if (!op_handle) return false;
+    keymaster_blob_t nonce_blob;
+    if (!out_params.GetTagValue(keymaster::TAG_NONCE, &nonce_blob)) {
+        LOG(ERROR) << "GCM encryption but no nonce generated";
+        return false;
+    }
+    // nonce_blob here is just a pointer into existing data, must not be freed
+    std::string nonce(reinterpret_cast<const char *>(nonce_blob.data), nonce_blob.data_length);
+    if (!CheckSize("nonce", nonce.size(), GCM_NONCE_BYTES)) return false;
+    std::string body;
+    if (!op_handle.UpdateCompletely(message, body)) return false;
+
+    std::string mac;
+    if (!op_handle.FinishWithOutput(mac)) return false;
+    if (!CheckSize("mac", mac.size(), GCM_MAC_BYTES)) return false;
+    ciphertext = nonce + body + mac;
+    return true;
+}
+
+static bool DecryptWithKeymasterKey(
+        Keymaster &keymaster, const std::string &key,
+        const keymaster::AuthorizationSet &extra_params,
+        const std::string &ciphertext,
+        std::string &message) {
+    auto nonce = ciphertext.substr(0, GCM_NONCE_BYTES);
+    auto body_mac = ciphertext.substr(GCM_NONCE_BYTES);
+    // FIXME fix repetition
+    keymaster::AuthorizationSetBuilder param_builder;
+    param_builder
+        .Authorization(keymaster::TAG_BLOCK_MODE, KM_MODE_GCM)
+        .Authorization(keymaster::TAG_MAC_LENGTH, GCM_MAC_BYTES * 8)
+        .Authorization(keymaster::TAG_PADDING, KM_PAD_NONE);
+    AddStringParam(param_builder, keymaster::TAG_NONCE, nonce);
+    auto params = param_builder.build();
+    params.push_back(extra_params);
+
+    auto op_handle = keymaster.Begin(KM_PURPOSE_DECRYPT, key, params);
+    if (!op_handle) return false;
+    if (!op_handle.UpdateCompletely(body_mac, message)) return false;
+    if (!op_handle.Finish()) return false;
+    return true;
+}
+
+bool StoreKey(const std::string &dir, const std::string &key) {
+    if (TEMP_FAILURE_RETRY(mkdir(dir.c_str(), 0700)) == -1) {
+        PLOG(ERROR) << "key mkdir " << dir;
+        return false;
+    }
+    std::string secdiscardable;
+    if (ReadRandomBytes(SECDISCARDABLE_BYTES, secdiscardable) != 0) {
+        // TODO status_t plays badly with PLOG, fix it.
+        LOG(ERROR) << "Random read failed";
+        return false;
+    }
+    // FIXME create a wrapper around reads and writes which handles error logging
+    if (!android::base::WriteStringToFile(secdiscardable, dir + "/" + kFn_secdiscardable)) {
+         PLOG(ERROR) << "Unable to write secdiscardable to " << dir;
+         return false;
+    }
+    keymaster::AuthorizationSetBuilder param_builder;
+    AddStringParam(param_builder, keymaster::TAG_APPLICATION_ID,
+        HashSecdiscardable(secdiscardable));
+    auto extra_params = param_builder.build();
+    Keymaster keymaster;
+    if (!keymaster) return false;
+    std::string km_key;
+    if (!GenerateKeymasterKey(keymaster, extra_params, km_key)) return false;
+    std::string encrypted_key;
+    if (!EncryptWithKeymasterKey(
+        keymaster, km_key, extra_params, key, encrypted_key)) return false;
+    if (!android::base::WriteStringToFile(km_key, dir + "/" + kFn_keymaster_key_blob)) {
+        PLOG(ERROR) << "Unable to write keymaster_key_blob to " << dir;
+        return false;
+    }
+    if (!android::base::WriteStringToFile(encrypted_key, dir + "/" + kFn_encrypted_key)) {
+        PLOG(ERROR) << "Unable to write encrypted_key to " << dir;
+        return false;
+    }
+    return true;
+}
+
+bool RetrieveKey(const std::string &dir, std::string &key) {
+    std::string secdiscardable;
+    if (!android::base::ReadFileToString(dir + "/" + kFn_secdiscardable, &secdiscardable)) {
+         PLOG(ERROR) << "Unable to read secdiscardable from " << dir;
+         return false;
+    }
+    keymaster::AuthorizationSetBuilder param_builder;
+    AddStringParam(param_builder, keymaster::TAG_APPLICATION_ID,
+        HashSecdiscardable(secdiscardable));
+    auto extra_params = param_builder.build();
+    std::string km_key;
+    if (!android::base::ReadFileToString(dir + "/" + kFn_keymaster_key_blob, &km_key)) {
+         PLOG(ERROR) << "Unable to read keymaster_key_blob from " << dir;
+         return false;
+    }
+    std::string encrypted_message;
+    if (!android::base::ReadFileToString(dir + "/" + kFn_encrypted_key, &encrypted_message)) {
+         PLOG(ERROR) << "Unable to read encrypted_key to " << dir;
+         return false;
+    }
+    Keymaster keymaster;
+    if (!keymaster) return false;
+    return DecryptWithKeymasterKey(keymaster, km_key, extra_params, encrypted_message, key);
+}
+
+static bool DeleteKey(const std::string &dir) {
+    std::string km_key;
+    if (!android::base::ReadFileToString(dir + "/" + kFn_keymaster_key_blob, &km_key)) {
+         PLOG(ERROR) << "Unable to read keymaster_key_blob from " << dir;
+         return false;
+    }
+    Keymaster keymaster;
+    if (!keymaster) return false;
+    if (!keymaster.DeleteKey(km_key)) return false;
+    return true;
+}
+
+static bool SecdiscardSecdiscardable(const std::string &dir) {
+    if (ForkExecvp(std::vector<std::string> {
+            kSecdiscardPath, "--", dir + "/" + kFn_secdiscardable}) != 0) {
+        LOG(ERROR) << "secdiscard failed";
+        return false;
+    }
+    return true;
+}
+
+static bool RecursiveDeleteKey(const std::string &dir) {
+    if (ForkExecvp(std::vector<std::string> {
+            kRmPath, "-rf", dir}) != 0) {
+        LOG(ERROR) << "recursive delete failed";
+        return false;
+    }
+    return true;
+}
+
+bool DestroyKey(const std::string &dir) {
+    bool success = true;
+    // Try each thing, even if previous things failed.
+    success &= DeleteKey(dir);
+    success &= SecdiscardSecdiscardable(dir);
+    success &= RecursiveDeleteKey(dir);
+    return success;
+}
+
+}  // namespace vold
+}  // namespace android
diff --git a/KeyStorage.h b/KeyStorage.h
new file mode 100644
index 0000000..f3b7261
--- /dev/null
+++ b/KeyStorage.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2016 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 ANDROID_VOLD_KEYSTORAGE_H
+#define ANDROID_VOLD_KEYSTORAGE_H
+
+#include <string>
+
+namespace android {
+namespace vold {
+
+// Create a directory at the named path, and store "key" in it,
+// in such a way that it can only be retrieved via Keymaster and
+// can be securely deleted.
+// It's safe to move/rename the directory after creation.
+bool StoreKey(const std::string &target_dir, const std::string &key);
+
+// Retrieve the key from the named directory.
+bool RetrieveKey(const std::string &dir, std::string &key);
+
+// Securely destroy the key stored in the named directory and delete the directory.
+bool DestroyKey(const std::string &dir);
+
+}  // namespace vold
+}  // namespace android
+
+#endif
diff --git a/Keymaster.cpp b/Keymaster.cpp
new file mode 100644
index 0000000..4888fe3
--- /dev/null
+++ b/Keymaster.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2016 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 "Keymaster.h"
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace vold {
+
+bool KeymasterOperation::UpdateCompletely(
+        const std::string &input,
+        std::string &output) {
+    output.clear();
+    auto it = input.begin();
+    while (it != input.end()) {
+        size_t to_read = static_cast<size_t>(input.end() - it);
+        keymaster_blob_t input_blob {reinterpret_cast<const uint8_t *>(&*it),  to_read};
+        keymaster_blob_t output_blob;
+        size_t input_consumed;
+        auto error = device->update(device, op_handle,
+            nullptr, &input_blob, &input_consumed, nullptr, &output_blob);
+        if (error != KM_ERROR_OK) {
+            LOG(ERROR) << "update failed, code " << error;
+            device = nullptr;
+            return false;
+        }
+        output.append(reinterpret_cast<const char *>(output_blob.data), output_blob.data_length);
+        free(const_cast<uint8_t *>(output_blob.data));
+        if (input_consumed > to_read) {
+            LOG(ERROR) << "update reported too much input consumed";
+            device = nullptr;
+            return false;
+        }
+        it += input_consumed;
+    }
+    return true;
+}
+
+bool KeymasterOperation::Finish() {
+    auto error = device->finish(device, op_handle,
+        nullptr, nullptr, nullptr, nullptr);
+    device = nullptr;
+    if (error != KM_ERROR_OK) {
+        LOG(ERROR) << "finish failed, code " << error;
+        return false;
+    }
+    return true;
+}
+
+bool KeymasterOperation::FinishWithOutput(std::string &output) {
+    keymaster_blob_t output_blob;
+    auto error = device->finish(device, op_handle,
+        nullptr, nullptr, nullptr, &output_blob);
+    device = nullptr;
+    if (error != KM_ERROR_OK) {
+        LOG(ERROR) << "finish failed, code " << error;
+        return false;
+    }
+    output.assign(reinterpret_cast<const char *>(output_blob.data), output_blob.data_length);
+    free(const_cast<uint8_t *>(output_blob.data));
+    return true;
+}
+
+Keymaster::Keymaster() {
+    device = nullptr;
+    const hw_module_t *module;
+    int ret = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &module);
+    if (ret != 0) {
+        LOG(ERROR) << "hw_get_module_by_class returned " << ret;
+        return;
+    }
+    // TODO: This will need to be updated to support keymaster2.
+    if (module->module_api_version != KEYMASTER_MODULE_API_VERSION_1_0) {
+        LOG(ERROR) << "module_api_version is " << module->module_api_version;
+        return;
+    }
+    ret = keymaster1_open(module, &device);
+    if (ret != 0) {
+        LOG(ERROR) << "keymaster1_open returned " << ret;
+        device = nullptr;
+        return;
+    }
+}
+
+bool Keymaster::GenerateKey(
+        const keymaster::AuthorizationSet &in_params,
+        std::string &key) {
+    keymaster_key_blob_t key_blob;
+    auto error = device->generate_key(device, &in_params, &key_blob, nullptr);
+    if (error != KM_ERROR_OK) {
+        LOG(ERROR) << "generate_key failed, code " << error;
+        return false;
+    }
+    key.assign(reinterpret_cast<const char *>(key_blob.key_material), key_blob.key_material_size);
+    return true;
+}
+
+bool Keymaster::DeleteKey(const std::string &key) {
+    if (device->delete_key == nullptr) return true;
+    keymaster_key_blob_t key_blob { reinterpret_cast<const uint8_t *>(key.data()), key.size() };
+    auto error = device->delete_key(device, &key_blob);
+    if (error != KM_ERROR_OK) {
+        LOG(ERROR) << "delete_key failed, code " << error;
+        return false;
+    }
+    return true;
+}
+
+KeymasterOperation Keymaster::Begin(
+        keymaster_purpose_t purpose,
+        const std::string &key,
+        const keymaster::AuthorizationSet &in_params,
+        keymaster::AuthorizationSet &out_params) {
+    keymaster_key_blob_t key_blob { reinterpret_cast<const uint8_t *>(key.data()), key.size() };
+    keymaster_operation_handle_t op_handle;
+    keymaster_key_param_set_t out_params_set;
+    auto error = device->begin(device, purpose,
+        &key_blob, &in_params, &out_params_set, &op_handle);
+    if (error != KM_ERROR_OK) {
+        LOG(ERROR) << "begin failed, code " << error;
+        return KeymasterOperation(nullptr, op_handle);
+    }
+    out_params.Clear();
+    out_params.push_back(out_params_set);
+    keymaster_free_param_set(&out_params_set);
+    return KeymasterOperation(device, op_handle);
+}
+
+KeymasterOperation Keymaster::Begin(
+        keymaster_purpose_t purpose,
+        const std::string &key,
+        const keymaster::AuthorizationSet &in_params) {
+    keymaster_key_blob_t key_blob { reinterpret_cast<const uint8_t *>(key.data()), key.size() };
+    keymaster_operation_handle_t op_handle;
+    auto error = device->begin(device, purpose, 
+        &key_blob, &in_params, nullptr, &op_handle);
+    if (error != KM_ERROR_OK) {
+        LOG(ERROR) << "begin failed, code " << error;
+        return KeymasterOperation(nullptr, op_handle);
+    }
+    return KeymasterOperation(device, op_handle);
+}
+
+}  // namespace vold
+}  // namespace android
diff --git a/Keymaster.h b/Keymaster.h
new file mode 100644
index 0000000..cc3104d
--- /dev/null
+++ b/Keymaster.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2016 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 ANDROID_VOLD_KEYMASTER1_H
+#define ANDROID_VOLD_KEYMASTER1_H
+
+#include <string>
+
+#include <hardware/hardware.h>
+#include <hardware/keymaster1.h>
+
+#include <keymaster/authorization_set.h>
+
+namespace android {
+namespace vold {
+
+using namespace keymaster;
+
+// C++ wrappers to the keymaster1 C interface.
+// This is tailored to the needs of KeyStorage, but could be extended to be
+// a more general interface.
+
+
+// Wrapper for a keymaster_operation_handle_t representing an
+// ongoing Keymaster operation.  Aborts the operation
+// in the destructor if it is unfinished. Methods log failures
+// to LOG(ERROR).
+class KeymasterOperation {
+public:
+    ~KeymasterOperation() { if (device) device->abort(device, op_handle); }
+    // Is this instance valid? This is false if creation fails, and becomes
+    // false on finish or if an update fails.
+    explicit operator bool() {return device != nullptr;}
+    // Call "update" repeatedly until all of the input is consumed, and 
+    // concatenate the output. Return true on success.
+    bool UpdateCompletely(const std::string &input, std::string &output);
+    // Finish; pass nullptr for the "output" param. 
+    bool Finish();
+    // Finish and write the output to this string.
+    bool FinishWithOutput(std::string &output);
+    // Move constructor
+    KeymasterOperation(KeymasterOperation&& rhs) {
+        op_handle = rhs.op_handle;
+        device = rhs.device;
+        rhs.device = nullptr;
+    }
+    // Move assignation.
+    KeymasterOperation& operator=(KeymasterOperation&& rhs) {
+        op_handle = rhs.op_handle;
+        device = rhs.device;
+        rhs.device = nullptr;
+        return *this;
+    }
+
+private:
+    KeymasterOperation(keymaster1_device_t *d, keymaster_operation_handle_t h):
+        device {d}, op_handle {h} {}
+    keymaster1_device_t *device;
+    keymaster_operation_handle_t op_handle;
+    DISALLOW_COPY_AND_ASSIGN(KeymasterOperation);
+    friend class Keymaster;
+};
+
+// Wrapper for a keymaster1_device_t representing an open connection
+// to the keymaster, which is closed in the destructor.
+class Keymaster {
+public:
+    Keymaster();
+    ~Keymaster() { if (device) keymaster1_close(device); }
+    // false if we failed to open the keymaster device.
+    explicit operator bool() {return device != nullptr;}
+    // Generate a key in the keymaster from the given params.
+    bool GenerateKey(const AuthorizationSet &in_params, std::string &key);
+    // If the keymaster supports it, permanently delete a key.
+    bool DeleteKey(const std::string &key);
+    // Begin a new cryptographic operation, collecting output parameters.
+    KeymasterOperation Begin(
+            keymaster_purpose_t purpose,
+            const std::string &key,
+            const AuthorizationSet &in_params,
+            AuthorizationSet &out_params);
+    // Begin a new cryptographic operation; don't collect output parameters.
+    KeymasterOperation Begin(
+            keymaster_purpose_t purpose,
+            const std::string &key,
+            const AuthorizationSet &in_params);
+private:
+    keymaster1_device_t *device;
+    DISALLOW_COPY_AND_ASSIGN(Keymaster);
+};
+
+template <keymaster_tag_t Tag>
+inline AuthorizationSetBuilder& AddStringParam(AuthorizationSetBuilder &params,
+        TypedTag<KM_BYTES, Tag> tag, const std::string& val) {
+    return params.Authorization(tag, val.data(), val.size());
+}
+
+}  // namespace vold
+}  // namespace android
+
+#endif
