diff --git a/Android.mk b/Android.mk
index 66b8a63..a0aa0e7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -27,6 +27,9 @@
 	MoveTask.cpp \
 	Benchmark.cpp \
 	TrimTask.cpp \
+	Keymaster.cpp \
+	KeyStorage.cpp \
+	ScryptParameters.cpp \
 	secontext.cpp \
 
 common_c_includes := \
@@ -54,15 +57,17 @@
 	libutils \
 	libhardware \
 	libsoftkeymaster \
-	libbase
+	libbase \
+	libkeymaster_messages \
 
 common_static_libraries := \
+	libbootloader_message_writer \
 	libfs_mgr \
 	libfec \
 	libfec_rs \
 	libsquashfs_utils \
 	libscrypt_static \
-	libbatteryservice
+	libbatteryservice \
 
 vold_conlyflags := -std=c11
 vold_cflags := -Werror -Wall -Wno-missing-field-initializers -Wno-unused-variable -Wno-unused-parameter
@@ -85,7 +90,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-LOCAL_MODULE:= vold
+LOCAL_MODULE := vold
 LOCAL_CLANG := true
 LOCAL_SRC_FILES := \
 	main.cpp \
@@ -112,9 +117,9 @@
 
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_CLANG := true
-LOCAL_SRC_FILES:= vdc.cpp
-LOCAL_MODULE:= vdc
-LOCAL_SHARED_LIBRARIES := libcutils
+LOCAL_SRC_FILES := vdc.cpp
+LOCAL_MODULE := vdc
+LOCAL_SHARED_LIBRARIES := libcutils libbase
 LOCAL_CFLAGS := $(vold_cflags)
 LOCAL_CONLYFLAGS := $(vold_conlyflags)
 LOCAL_INIT_RC := vdc.rc
@@ -127,7 +132,7 @@
 LOCAL_CLANG := true
 LOCAL_SRC_FILES:= secdiscard.cpp
 LOCAL_MODULE:= secdiscard
-LOCAL_SHARED_LIBRARIES := liblog libcutils
+LOCAL_SHARED_LIBRARIES := libbase
 LOCAL_CFLAGS := $(vold_cflags)
 LOCAL_CONLYFLAGS := $(vold_conlyflags)
 
diff --git a/AutoCloseFD.h b/AutoCloseFD.h
new file mode 100644
index 0000000..9b68469
--- /dev/null
+++ b/AutoCloseFD.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 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 <string>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <android-base/logging.h>
+
+// File descriptor which is automatically closed when this object is destroyed.
+// Cannot be copied, since that would cause double-closes.
+class AutoCloseFD {
+public:
+    AutoCloseFD(const char *path, int flags = O_RDONLY, int mode = 0):
+        fd{TEMP_FAILURE_RETRY(open(path, flags | O_CLOEXEC, mode))} {}
+    AutoCloseFD(const std::string &path, int flags = O_RDONLY, int mode = 0):
+        AutoCloseFD(path.c_str(), flags, mode) {}
+    ~AutoCloseFD() {
+        if (fd != -1) {
+            int preserve_errno = errno;
+            if (close(fd) == -1) {
+                PLOG(ERROR) << "close(2) failed";
+            };
+            errno = preserve_errno;
+        }
+    }
+    AutoCloseFD(const AutoCloseFD&) = delete;
+    AutoCloseFD& operator=(const AutoCloseFD&) = delete;
+    explicit operator bool() {return fd != -1;}
+    int get() const {return fd;}
+private:
+    const int fd;
+};
+
diff --git a/CommandListener.cpp b/CommandListener.cpp
index 4a8ed75..8780e98 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -15,8 +15,11 @@
  */
 
 #include <stdlib.h>
+#include <sys/mount.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <dirent.h>
@@ -27,12 +30,13 @@
 #include <string.h>
 #include <stdint.h>
 #include <inttypes.h>
+#include <ctype.h>
 
 #define LOG_TAG "VoldCmdListener"
 
+#include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <cutils/fs.h>
-#include <cutils/log.h>
 
 #include <sysutils/SocketClient.h>
 #include <private/android_filesystem_config.h>
@@ -44,12 +48,11 @@
 #include "Process.h"
 #include "Loop.h"
 #include "Devmapper.h"
-#include "Ext4Crypt.h"
-#include "cryptfs.h"
 #include "MoveTask.h"
 #include "TrimTask.h"
 
 #define DUMP_ARGS 0
+#define DEBUG_APPFUSE 0
 
 CommandListener::CommandListener() :
                  FrameworkListener("vold", true) {
@@ -59,6 +62,7 @@
     registerCmd(new ObbCmd());
     registerCmd(new StorageCmd());
     registerCmd(new FstrimCmd());
+    registerCmd(new AppFuseCmd());
 }
 
 #if DUMP_ARGS
@@ -621,3 +625,251 @@
     (new android::vold::TrimTask(flags))->start();
     return sendGenericOkFail(cli, 0);
 }
+
+static size_t kAppFuseMaxMountPointName = 32;
+
+static android::status_t getMountPath(uid_t uid, const std::string& name, std::string* path) {
+    if (name.size() > kAppFuseMaxMountPointName) {
+        LOG(ERROR) << "AppFuse mount name is too long.";
+        return -EINVAL;
+    }
+    for (size_t i = 0; i < name.size(); i++) {
+        if (!isalnum(name[i])) {
+            LOG(ERROR) << "AppFuse mount name contains invalid character.";
+            return -EINVAL;
+        }
+    }
+    *path = android::base::StringPrintf("/mnt/appfuse/%d_%s", uid, name.c_str());
+    return android::OK;
+}
+
+static android::status_t mountInNamespace(uid_t uid, int device_fd, const std::string& path) {
+    // Remove existing mount.
+    android::vold::ForceUnmount(path);
+
+    const auto opts = android::base::StringPrintf(
+            "fd=%i,"
+            "rootmode=40000,"
+            "default_permissions,"
+            "allow_other,"
+            "user_id=%d,group_id=%d,"
+            "context=\"u:object_r:app_fuse_file:s0\","
+            "fscontext=u:object_r:app_fusefs:s0",
+            device_fd,
+            uid,
+            uid);
+
+    const int result = TEMP_FAILURE_RETRY(mount(
+            "/dev/fuse", path.c_str(), "fuse",
+            MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME, opts.c_str()));
+    if (result != 0) {
+        PLOG(ERROR) << "Failed to mount " << path;
+        return -errno;
+    }
+
+    return android::OK;
+}
+
+static android::status_t runCommandInNamespace(const std::string& command,
+                                               uid_t uid,
+                                               pid_t pid,
+                                               const std::string& path,
+                                               int device_fd) {
+    if (DEBUG_APPFUSE) {
+        LOG(DEBUG) << "Run app fuse command " << command << " for the path " << path
+                   << " in namespace " << uid;
+    }
+
+    const android::vold::ScopedDir dir(opendir("/proc"));
+    if (dir.get() == nullptr) {
+        PLOG(ERROR) << "Failed to open /proc";
+        return -errno;
+    }
+
+    // Obtains process file descriptor.
+    const std::string pid_str = android::base::StringPrintf("%d", pid);
+    const android::vold::ScopedFd pid_fd(
+            openat(dirfd(dir.get()), pid_str.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC));
+    if (pid_fd.get() == -1) {
+        PLOG(ERROR) << "Failed to open /proc/" << pid;
+        return -errno;
+    }
+
+    // Check UID of process.
+    {
+        struct stat sb;
+        const int result = fstat(pid_fd.get(), &sb);
+        if (result == -1) {
+            PLOG(ERROR) << "Failed to stat /proc/" << pid;
+            return -errno;
+        }
+        if (sb.st_uid != uid) {
+            LOG(ERROR) << "Mismatch UID expected=" << uid << ", actual=" << sb.st_uid;
+            return -EPERM;
+        }
+    }
+
+    // Matches so far, but refuse to touch if in root namespace
+    {
+        char rootName[PATH_MAX];
+        char pidName[PATH_MAX];
+        const int root_result =
+                android::vold::SaneReadLinkAt(dirfd(dir.get()), "1/ns/mnt", rootName, PATH_MAX);
+        const int pid_result =
+                android::vold::SaneReadLinkAt(pid_fd.get(), "ns/mnt", pidName, PATH_MAX);
+        if (root_result == -1) {
+            LOG(ERROR) << "Failed to readlink for /proc/1/ns/mnt";
+            return -EPERM;
+        }
+        if (pid_result == -1) {
+            LOG(ERROR) << "Failed to readlink for /proc/" << pid << "/ns/mnt";
+            return -EPERM;
+        }
+        if (!strcmp(rootName, pidName)) {
+            LOG(ERROR) << "Don't mount appfuse in root namespace";
+            return -EPERM;
+        }
+    }
+
+    // We purposefully leave the namespace open across the fork
+    android::vold::ScopedFd ns_fd(openat(pid_fd.get(), "ns/mnt", O_RDONLY));
+    if (ns_fd.get() < 0) {
+        PLOG(ERROR) << "Failed to open namespace for /proc/" << pid << "/ns/mnt";
+        return -errno;
+    }
+
+    int child = fork();
+    if (child == 0) {
+        if (setns(ns_fd.get(), CLONE_NEWNS) != 0) {
+            PLOG(ERROR) << "Failed to setns";
+            _exit(-errno);
+        }
+
+        if (command == "mount") {
+            _exit(mountInNamespace(uid, device_fd, path));
+        } else if (command == "unmount") {
+            android::vold::ForceUnmount(path);
+            _exit(android::OK);
+        } else {
+            LOG(ERROR) << "Unknown appfuse command " << command;
+            _exit(-EPERM);
+        }
+    }
+
+    if (child == -1) {
+        PLOG(ERROR) << "Failed to folk child process";
+        return -errno;
+    }
+
+    android::status_t status;
+    TEMP_FAILURE_RETRY(waitpid(child, &status, 0));
+
+    return status;
+}
+
+CommandListener::AppFuseCmd::AppFuseCmd() : VoldCommand("appfuse") {}
+
+int CommandListener::AppFuseCmd::runCommand(SocketClient *cli, int argc, char **argv) {
+    if (argc < 2) {
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
+        return 0;
+    }
+
+    const std::string command(argv[1]);
+
+    if (command == "mount" && argc == 5) {
+        const uid_t uid = atoi(argv[2]);
+        const pid_t pid = atoi(argv[3]);
+        const std::string name(argv[4]);
+
+        // Check mount point name.
+        std::string path;
+        if (getMountPath(uid, name, &path) != android::OK) {
+            return cli->sendMsg(ResponseCode::CommandParameterError,
+                                "Invalid mount point name.",
+                                false);
+        }
+
+        // Create directories.
+        {
+            const android::status_t result = android::vold::PrepareDir(path, 0700, 0, 0);
+            if (result != android::OK) {
+                PLOG(ERROR) << "Failed to prepare directory " << path;
+                return sendGenericOkFail(cli, result);
+            }
+        }
+
+        // Open device FD.
+        android::vold::ScopedFd device_fd(open("/dev/fuse", O_RDWR));
+        if (device_fd.get() == -1) {
+            PLOG(ERROR) << "Failed to open /dev/fuse";
+            return sendGenericOkFail(cli, -errno);
+        }
+
+        // Mount.
+        {
+            const android::status_t result =
+                    runCommandInNamespace(command, uid, pid, path, device_fd.get());
+            if (result != android::OK) {
+                return sendGenericOkFail(cli, result);
+            }
+        }
+
+        return sendFd(cli, device_fd.get());
+    } else if (command == "unmount" && argc == 5) {
+        const uid_t uid = atoi(argv[2]);
+        const uid_t pid = atoi(argv[3]);
+        const std::string name(argv[4]);
+
+        // Check mount point name.
+        std::string path;
+        if (getMountPath(uid, name, &path) != android::OK) {
+            return cli->sendMsg(ResponseCode::CommandParameterError,
+                                "Invalid mount point name.",
+                                false);
+        }
+
+        const android::status_t result =
+                runCommandInNamespace(command, uid, pid, path, -1 /* device_fd */);
+        return sendGenericOkFail(cli, result);
+    }
+
+    return cli->sendMsg(ResponseCode::CommandSyntaxError,  "Unknown appfuse cmd", false);
+}
+
+android::status_t CommandListener::AppFuseCmd::sendFd(SocketClient *cli, int fd) {
+    struct iovec data;
+    char dataBuffer[128];
+    char controlBuffer[CMSG_SPACE(sizeof(int))];
+    struct msghdr message;
+
+    // Message.
+    memset(&message, 0, sizeof(struct msghdr));
+    message.msg_iov = &data;
+    message.msg_iovlen = 1;
+    message.msg_control = controlBuffer;
+    message.msg_controllen = CMSG_SPACE(sizeof(int));
+
+    // Data.
+    data.iov_base = dataBuffer;
+    data.iov_len = snprintf(dataBuffer,
+                            sizeof(dataBuffer),
+                            "200 %d AppFuse command succeeded",
+                            cli->getCmdNum()) + 1;
+
+    // Control.
+    struct cmsghdr* const controlMessage = CMSG_FIRSTHDR(&message);
+    memset(controlBuffer, 0, CMSG_SPACE(sizeof(int)));
+    controlMessage->cmsg_level = SOL_SOCKET;
+    controlMessage->cmsg_type = SCM_RIGHTS;
+    controlMessage->cmsg_len = CMSG_LEN(sizeof(int));
+    *((int *) CMSG_DATA(controlMessage)) = fd;
+
+    const int result = TEMP_FAILURE_RETRY(sendmsg(cli->getSocket(), &message, 0));
+    if (result == -1) {
+        PLOG(ERROR) << "Failed to send FD from vold";
+        return -errno;
+    }
+
+    return android::OK;
+}
diff --git a/CommandListener.h b/CommandListener.h
index 6ed099b..f858ac0 100644
--- a/CommandListener.h
+++ b/CommandListener.h
@@ -73,6 +73,15 @@
         virtual ~FstrimCmd() {}
         int runCommand(SocketClient *c, int argc, char ** argv);
     };
+
+    class AppFuseCmd : public VoldCommand {
+    public:
+        AppFuseCmd();
+        virtual ~AppFuseCmd() {}
+        int runCommand(SocketClient *c, int argc, char ** argv);
+    private:
+        android::status_t sendFd(SocketClient *c, int fd);
+    };
 };
 
 #endif
diff --git a/CryptCommandListener.cpp b/CryptCommandListener.cpp
index 1babef7..02c2701 100644
--- a/CryptCommandListener.cpp
+++ b/CryptCommandListener.cpp
@@ -16,6 +16,7 @@
 
 #include <stdlib.h>
 #include <sys/socket.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -28,9 +29,14 @@
 #include <stdint.h>
 #include <inttypes.h>
 
+#include <algorithm>
+#include <thread>
+
 #define LOG_TAG "VoldCryptCmdListener"
 
+#include <android-base/logging.h>
 #include <android-base/stringprintf.h>
+
 #include <cutils/fs.h>
 #include <cutils/log.h>
 #include <cutils/sockets.h>
@@ -43,6 +49,7 @@
 #include "ResponseCode.h"
 #include "cryptfs.h"
 #include "Ext4Crypt.h"
+#include "Utils.h"
 
 #define DUMP_ARGS 0
 
@@ -83,8 +90,8 @@
 void CryptCommandListener::dumpArgs(int /*argc*/, char ** /*argv*/, int /*argObscure*/) { }
 #endif
 
-int CryptCommandListener::sendGenericOkFail(SocketClient *cli, int cond) {
-    if (!cond) {
+int CryptCommandListener::sendGenericOkFailOnBool(SocketClient *cli, bool success) {
+    if (success) {
         return cli->sendMsg(ResponseCode::CommandOkay, "Command succeeded", false);
     } else {
         return cli->sendMsg(ResponseCode::OperationFailed, "Command failed", false);
@@ -110,6 +117,58 @@
     }
 }
 
+static char* parseNull(char* arg) {
+    if (strcmp(arg, "!") == 0) {
+        return nullptr;
+    } else {
+        return arg;
+    }
+}
+
+static bool check_argc(SocketClient *cli, const std::string &subcommand, int argc,
+        int expected, std::string usage) {
+    assert(expected >= 2);
+    if (expected == 2) {
+        assert(usage.empty());
+    } else {
+        assert(!usage.empty());
+        assert(std::count(usage.begin(), usage.end(), ' ') + 3 == expected);
+    }
+    if (argc == expected) {
+        return true;
+    }
+    auto message = std::string() + "Usage: cryptfs " + subcommand;
+    if (!usage.empty()) {
+        message += " " + usage;
+    }
+    cli->sendMsg(ResponseCode::CommandSyntaxError, message.c_str(), false);
+    return false;
+}
+
+static int do_enablecrypto(char* arg2, char* arg4, int type, bool no_ui) {
+    int rc;
+    int tries;
+    for (tries = 0; tries < 2; ++tries) {
+        if (type == CRYPT_TYPE_DEFAULT) {
+            rc = cryptfs_enable_default(arg2, no_ui);
+        } else {
+            rc = cryptfs_enable(arg2, type, arg4, no_ui);
+        }
+
+        if (rc == 0) {
+            free(arg2);
+            free(arg4);
+            return 0;
+        } else if (tries == 0) {
+            Process::killProcessesWithOpenFiles(DATA_MNT_POINT, SIGKILL);
+        }
+    }
+
+    free(arg2);
+    free(arg4);
+    return -1;
+}
+
 int CryptCommandListener::CryptfsCmd::runCommand(SocketClient *cli,
                                                  int argc, char **argv) {
     if ((cli->getUid() != 0) && (cli->getUid() != AID_SYSTEM)) {
@@ -118,34 +177,29 @@
     }
 
     if (argc < 2) {
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing Argument", false);
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing subcommand", false);
         return 0;
     }
 
     int rc = 0;
 
-    if (!strcmp(argv[1], "checkpw")) {
-        if (argc != 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs checkpw <passwd>", false);
-            return 0;
-        }
+    std::string subcommand(argv[1]);
+    if (subcommand == "checkpw") {
+        if (!check_argc(cli, subcommand, argc, 3, "<passwd>")) return 0;
         dumpArgs(argc, argv, 2);
         rc = cryptfs_check_passwd(argv[2]);
-    } else if (!strcmp(argv[1], "restart")) {
-        if (argc != 2) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs restart", false);
-            return 0;
-        }
+    } else if (subcommand == "restart") {
+        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
         dumpArgs(argc, argv, -1);
-        rc = cryptfs_restart();
-    } else if (!strcmp(argv[1], "cryptocomplete")) {
-        if (argc != 2) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs cryptocomplete", false);
-            return 0;
-        }
+
+        // Spawn as thread so init can issue commands back to vold without
+        // causing deadlock, usually as a result of prep_data_fs.
+        std::thread(&cryptfs_restart).detach();
+    } else if (subcommand == "cryptocomplete") {
+        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
         dumpArgs(argc, argv, -1);
         rc = cryptfs_crypto_complete();
-    } else if (!strcmp(argv[1], "enablecrypto")) {
+    } else if (subcommand == "enablecrypto") {
         const char* syntax = "Usage: cryptfs enablecrypto <wipe|inplace> "
                              "default|password|pin|pattern [passwd] [noui]";
 
@@ -190,40 +244,23 @@
             }
         }
 
-        if (!valid ) {
+        if (!valid) {
             cli->sendMsg(ResponseCode::CommandSyntaxError, syntax, false);
             return 0;
         }
 
         dumpArgs(argc, argv, 4);
 
-        int tries;
-        for (tries = 0; tries < 2; ++tries) {
-            if (type == -1) {
-                cli->sendMsg(ResponseCode::CommandSyntaxError, syntax,
-                             false);
-                return 0;
-            } else if (type == CRYPT_TYPE_DEFAULT) {
-              rc = cryptfs_enable_default(argv[2], no_ui);
-            } else {
-                rc = cryptfs_enable(argv[2], type, argv[4], no_ui);
-            }
-
-            if (rc == 0) {
-                break;
-            } else if (tries == 0) {
-                Process::killProcessesWithOpenFiles(DATA_MNT_POINT, SIGKILL);
-            }
-        }
-    } else if (!strcmp(argv[1], "enablefilecrypto")) {
-        const char* syntax = "Usage: cryptfs enablefilecrypto";
-        if (argc != 2) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, syntax, false);
-            return 0;
-        }
+        // Spawn as thread so init can issue commands back to vold without
+        // causing deadlock, usually as a result of prep_data_fs.
+        char* arg2 = argc > 2 ? strdup(argv[2]) : NULL;
+        char* arg4 = argc > 4 ? strdup(argv[4]) : NULL;
+        std::thread(&do_enablecrypto, arg2, arg4, type, no_ui).detach();
+    } else if (subcommand == "enablefilecrypto") {
+        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
         dumpArgs(argc, argv, -1);
         rc = cryptfs_enable_file();
-    } else if (!strcmp(argv[1], "changepw")) {
+    } else if (subcommand == "changepw") {
         const char* syntax = "Usage: cryptfs changepw "
                              "default|password|pin|pattern [newpasswd]";
         const char* password;
@@ -242,21 +279,15 @@
         }
         SLOGD("cryptfs changepw %s {}", argv[2]);
         rc = cryptfs_changepw(type, password);
-    } else if (!strcmp(argv[1], "verifypw")) {
-        if (argc != 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs verifypw <passwd>", false);
-            return 0;
-        }
+    } else if (subcommand == "verifypw") {
+        if (!check_argc(cli, subcommand, argc, 3, "<passwd>")) return 0;
         SLOGD("cryptfs verifypw {}");
         rc = cryptfs_verify_passwd(argv[2]);
-    } else if (!strcmp(argv[1], "getfield")) {
+    } else if (subcommand == "getfield") {
+        if (!check_argc(cli, subcommand, argc, 3, "<fieldname>")) return 0;
         char *valbuf;
         int valbuf_len = PROPERTY_VALUE_MAX;
 
-        if (argc != 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs getfield <fieldname>", false);
-            return 0;
-        }
         dumpArgs(argc, argv, -1);
 
         // Increase the buffer size until it is big enough for the field value stored.
@@ -277,18 +308,20 @@
             cli->sendMsg(ResponseCode::CryptfsGetfieldResult, valbuf, false);
         }
         free(valbuf);
-    } else if (!strcmp(argv[1], "setfield")) {
-        if (argc != 4) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs setfield <fieldname> <value>", false);
-            return 0;
-        }
+    } else if (subcommand == "setfield") {
+        if (!check_argc(cli, subcommand, argc, 4, "<fieldname> <value>")) return 0;
         dumpArgs(argc, argv, -1);
         rc = cryptfs_setfield(argv[2], argv[3]);
-    } else if (!strcmp(argv[1], "mountdefaultencrypted")) {
+    } else if (subcommand == "mountdefaultencrypted") {
+        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
         SLOGD("cryptfs mountdefaultencrypted");
         dumpArgs(argc, argv, -1);
-        rc = cryptfs_mount_default_encrypted();
-    } else if (!strcmp(argv[1], "getpwtype")) {
+
+        // Spawn as thread so init can issue commands back to vold without
+        // causing deadlock, usually as a result of prep_data_fs.
+        std::thread(&cryptfs_mount_default_encrypted).detach();
+    } else if (subcommand == "getpwtype") {
+        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
         SLOGD("cryptfs getpwtype");
         dumpArgs(argc, argv, -1);
         switch(cryptfs_get_password_type()) {
@@ -309,7 +342,8 @@
             cli->sendMsg(ResponseCode::OpFailedStorageNotFound, "Error", false);
             return 0;
         }
-    } else if (!strcmp(argv[1], "getpw")) {
+    } else if (subcommand == "getpw") {
+        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
         SLOGD("cryptfs getpw");
         dumpArgs(argc, argv, -1);
         const char* password = cryptfs_get_password();
@@ -324,43 +358,64 @@
             }
         }
         rc = -1;
-    } else if (!strcmp(argv[1], "clearpw")) {
+    } else if (subcommand == "clearpw") {
+        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
         SLOGD("cryptfs clearpw");
         dumpArgs(argc, argv, -1);
         cryptfs_clear_password();
         rc = 0;
-    } else if (!strcmp(argv[1], "setusercryptopolicies")) {
-        if (argc != 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError,
-                "Usage: cryptfs setusercryptopolicies <path>", false);
-            return 0;
-        }
-        SLOGD("cryptfs setusercryptopolicies");
-        dumpArgs(argc, argv, -1);
-        rc = e4crypt_set_user_crypto_policies(argv[2]);
-    } else if (!strcmp(argv[1], "createnewuserdir")) {
-        if (argc != 4) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError,
-                "Usage: cryptfs createnewuserdir <userHandle> <path>", false);
-            return 0;
-        }
+
+    } else if (subcommand == "isConvertibleToFBE") {
+        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
         // ext4enc:TODO: send a CommandSyntaxError if argv[2] not an integer
-        SLOGD("cryptfs createnewuserdir");
+        SLOGD("cryptfs isConvertibleToFBE");
         dumpArgs(argc, argv, -1);
-        rc = e4crypt_create_new_user_dir(argv[2], argv[3]);
-    } else if (!strcmp(argv[1], "deleteuserkey")) {
-        if (argc != 3) {
-            cli->sendMsg(ResponseCode::CommandSyntaxError,
-                "Usage: cryptfs deleteuserkey <userHandle>", false);
-            return 0;
-        }
-        // ext4enc:TODO: send a CommandSyntaxError if argv[2] not an integer
-        SLOGD("cryptfs deleteuserkey");
-        dumpArgs(argc, argv, -1);
-        rc = e4crypt_delete_user_key(argv[2]);
+        rc = cryptfs_isConvertibleToFBE();
+
+    } else if (subcommand == "init_user0") {
+        if (!check_argc(cli, subcommand, argc, 2, "")) return 0;
+        return sendGenericOkFailOnBool(cli, e4crypt_init_user0());
+
+    } else if (subcommand == "create_user_key") {
+        if (!check_argc(cli, subcommand, argc, 5, "<user> <serial> <ephemeral>")) return 0;
+        return sendGenericOkFailOnBool(cli, e4crypt_vold_create_user_key(
+            atoi(argv[2]), atoi(argv[3]), atoi(argv[4]) != 0));
+
+    } else if (subcommand == "destroy_user_key") {
+        if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
+        return sendGenericOkFailOnBool(cli, e4crypt_destroy_user_key(atoi(argv[2])));
+
+    } else if (subcommand == "add_user_key_auth") {
+        if (!check_argc(cli, subcommand, argc, 6, "<user> <serial> <token> <secret>")) return 0;
+        return sendGenericOkFailOnBool(cli, e4crypt_add_user_key_auth(
+            atoi(argv[2]), atoi(argv[3]), argv[4], argv[5]));
+
+    } else if (subcommand == "fixate_newest_user_key_auth") {
+        if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
+        return sendGenericOkFailOnBool(cli, e4crypt_fixate_newest_user_key_auth(atoi(argv[2])));
+
+    } else if (subcommand == "unlock_user_key") {
+        if (!check_argc(cli, subcommand, argc, 6, "<user> <serial> <token> <secret>")) return 0;
+        return sendGenericOkFailOnBool(cli, e4crypt_unlock_user_key(
+            atoi(argv[2]), atoi(argv[3]), argv[4], argv[5]));
+
+    } else if (subcommand == "lock_user_key") {
+        if (!check_argc(cli, subcommand, argc, 3, "<user>")) return 0;
+        return sendGenericOkFailOnBool(cli, e4crypt_lock_user_key(atoi(argv[2])));
+
+    } else if (subcommand == "prepare_user_storage") {
+        if (!check_argc(cli, subcommand, argc, 6, "<uuid> <user> <serial> <flags>")) return 0;
+        return sendGenericOkFailOnBool(cli, e4crypt_prepare_user_storage(
+            parseNull(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5])));
+
+    } else if (subcommand == "destroy_user_storage") {
+        if (!check_argc(cli, subcommand, argc, 5, "<uuid> <user> <flags>")) return 0;
+        return sendGenericOkFailOnBool(cli,
+                e4crypt_destroy_user_storage(parseNull(argv[2]), atoi(argv[3]), atoi(argv[4])));
+
     } else {
         dumpArgs(argc, argv, -1);
-        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown cryptfs cmd", false);
+        cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown cryptfs subcommand", false);
         return 0;
     }
 
diff --git a/CryptCommandListener.h b/CryptCommandListener.h
index 1653239..478ac02 100644
--- a/CryptCommandListener.h
+++ b/CryptCommandListener.h
@@ -28,7 +28,7 @@
 
 private:
     static void dumpArgs(int argc, char **argv, int argObscure);
-    static int sendGenericOkFail(SocketClient *cli, int cond);
+    static int sendGenericOkFailOnBool(SocketClient *cli, bool success);
 
     class CryptfsCmd : public VoldCommand {
     public:
diff --git a/Disk.cpp b/Disk.cpp
index 920edab..2c2a2da 100644
--- a/Disk.cpp
+++ b/Disk.cpp
@@ -65,6 +65,8 @@
 static const unsigned int kMajorBlockScsiO = 134;
 static const unsigned int kMajorBlockScsiP = 135;
 static const unsigned int kMajorBlockMmc = 179;
+static const unsigned int kMajorBlockExperimentalMin = 240;
+static const unsigned int kMajorBlockExperimentalMax = 254;
 
 static const char* kGptBasicData = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7";
 static const char* kGptAndroidMeta = "19A710A2-B3CA-11E4-B026-10604B889DCF";
@@ -76,6 +78,33 @@
     kGpt,
 };
 
+static bool isVirtioBlkDevice(unsigned int major) {
+    /*
+     * The new emulator's "ranchu" virtual board no longer includes a goldfish
+     * MMC-based SD card device; instead, it emulates SD cards with virtio-blk,
+     * which has been supported by upstream kernel and QEMU for quite a while.
+     * Unfortunately, the virtio-blk block device driver does not use a fixed
+     * major number, but relies on the kernel to assign one from a specific
+     * range of block majors, which are allocated for "LOCAL/EXPERIMENAL USE"
+     * per Documentation/devices.txt. This is true even for the latest Linux
+     * kernel (4.4; see init() in drivers/block/virtio_blk.c).
+     *
+     * This makes it difficult for vold to detect a virtio-blk based SD card.
+     * The current solution checks two conditions (both must be met):
+     *
+     *  a) If the running environment is the emulator;
+     *  b) If the major number is an experimental block device major number (for
+     *     x86/x86_64 3.10 ranchu kernels, virtio-blk always gets major number
+     *     253, but it is safer to match the range than just one value).
+     *
+     * Other conditions could be used, too, e.g. the hardware name should be
+     * "ranchu", the device's sysfs path should end with "/block/vd[d-z]", etc.
+     * But just having a) and b) is enough for now.
+     */
+    return IsRunningInEmulator() && major >= kMajorBlockExperimentalMin
+            && major <= kMajorBlockExperimentalMax;
+}
+
 Disk::Disk(const std::string& eventPath, dev_t device,
         const std::string& nickname, int flags) :
         mDevice(device), mSize(-1), mNickname(nickname), mFlags(flags), mCreated(
@@ -197,7 +226,8 @@
         close(fd);
     }
 
-    switch (major(mDevice)) {
+    unsigned int majorId = major(mDevice);
+    switch (majorId) {
     case kMajorBlockScsiA: case kMajorBlockScsiB: case kMajorBlockScsiC: case kMajorBlockScsiD:
     case kMajorBlockScsiE: case kMajorBlockScsiF: case kMajorBlockScsiG: case kMajorBlockScsiH:
     case kMajorBlockScsiI: case kMajorBlockScsiJ: case kMajorBlockScsiK: case kMajorBlockScsiL:
@@ -231,12 +261,18 @@
         break;
     }
     default: {
-        LOG(WARNING) << "Unsupported block major type" << major(mDevice);
+        if (isVirtioBlkDevice(majorId)) {
+            LOG(DEBUG) << "Recognized experimental block major ID " << majorId
+                    << " as virtio-blk (emulator's virtual SD card device)";
+            mLabel = "Virtual";
+            break;
+        }
+        LOG(WARNING) << "Unsupported block major type " << majorId;
         return -ENOTSUP;
     }
     }
 
-    notifyEvent(ResponseCode::DiskSizeChanged, StringPrintf("%" PRId64, mSize));
+    notifyEvent(ResponseCode::DiskSizeChanged, StringPrintf("%" PRIu64, mSize));
     notifyEvent(ResponseCode::DiskLabelChanged, mLabel);
     notifyEvent(ResponseCode::DiskSysPathChanged, mSysPath);
     return OK;
@@ -490,7 +526,8 @@
 
 int Disk::getMaxMinors() {
     // Figure out maximum partition devices supported
-    switch (major(mDevice)) {
+    unsigned int majorId = major(mDevice);
+    switch (majorId) {
     case kMajorBlockScsiA: case kMajorBlockScsiB: case kMajorBlockScsiC: case kMajorBlockScsiD:
     case kMajorBlockScsiE: case kMajorBlockScsiF: case kMajorBlockScsiG: case kMajorBlockScsiH:
     case kMajorBlockScsiI: case kMajorBlockScsiJ: case kMajorBlockScsiK: case kMajorBlockScsiL:
@@ -507,9 +544,16 @@
         }
         return atoi(tmp.c_str());
     }
+    default: {
+        if (isVirtioBlkDevice(majorId)) {
+            // drivers/block/virtio_blk.c has "#define PART_BITS 4", so max is
+            // 2^4 - 1 = 15
+            return 15;
+        }
+    }
     }
 
-    LOG(ERROR) << "Unsupported block major type " << major(mDevice);
+    LOG(ERROR) << "Unsupported block major type " << majorId;
     return -ENOTSUP;
 }
 
diff --git a/EmulatedVolume.cpp b/EmulatedVolume.cpp
index 230fa8b..581c322 100644
--- a/EmulatedVolume.cpp
+++ b/EmulatedVolume.cpp
@@ -107,17 +107,21 @@
 }
 
 status_t EmulatedVolume::doUnmount() {
+    // Unmount the storage before we kill the FUSE process. If we kill
+    // the FUSE process first, most file system operations will return
+    // ENOTCONN until the unmount completes. This is an exotic and unusual
+    // error code and might cause broken behaviour in applications.
+    KillProcessesUsingPath(getPath());
+    ForceUnmount(mFuseDefault);
+    ForceUnmount(mFuseRead);
+    ForceUnmount(mFuseWrite);
+
     if (mFusePid > 0) {
         kill(mFusePid, SIGTERM);
         TEMP_FAILURE_RETRY(waitpid(mFusePid, nullptr, 0));
         mFusePid = 0;
     }
 
-    KillProcessesUsingPath(getPath());
-    ForceUnmount(mFuseDefault);
-    ForceUnmount(mFuseRead);
-    ForceUnmount(mFuseWrite);
-
     rmdir(mFuseDefault.c_str());
     rmdir(mFuseRead.c_str());
     rmdir(mFuseWrite.c_str());
diff --git a/Ext4Crypt.cpp b/Ext4Crypt.cpp
index 0807c2c..1158475 100644
--- a/Ext4Crypt.cpp
+++ b/Ext4Crypt.cpp
@@ -1,671 +1,792 @@
+/*
+ * Copyright (C) 2015 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 "Ext4Crypt.h"
 
+#include "KeyStorage.h"
+#include "Utils.h"
+
+#include <algorithm>
 #include <iomanip>
 #include <map>
-#include <fstream>
-#include <string>
+#include <set>
 #include <sstream>
+#include <string>
 
-#include <errno.h>
 #include <dirent.h>
-#include <sys/mount.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <errno.h>
 #include <fcntl.h>
-#include <cutils/properties.h>
+#include <limits.h>
 #include <openssl/sha.h>
+#include <selinux/android.h>
+#include <stdio.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 #include <private/android_filesystem_config.h>
 
-#include "unencrypted_properties.h"
-#include "key_control.h"
 #include "cryptfs.h"
-#include "ext4_crypt_init_extensions.h"
+#include "ext4_crypt.h"
+#include "key_control.h"
 
-#define LOG_TAG "Ext4Crypt"
-#include "cutils/log.h"
-#include <cutils/klog.h>
+#define EMULATED_USES_SELINUX 0
+#define MANAGE_MISC_DIRS 0
+
+#include <cutils/fs.h>
+
 #include <android-base/file.h>
+#include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 
+using android::base::StringPrintf;
+using android::vold::kEmptyAuthentication;
+
+// NOTE: keep in sync with StorageManager
+static constexpr int FLAG_STORAGE_DE = 1 << 0;
+static constexpr int FLAG_STORAGE_CE = 1 << 1;
+
 namespace {
-    // Key length in bits
-    const int key_length = 128;
-    static_assert(key_length % 8 == 0,
-                  "Key length must be multiple of 8 bits");
+const std::string device_key_dir = std::string() + DATA_MNT_POINT + e4crypt_unencrypted_folder;
+const std::string device_key_path = device_key_dir + "/key";
+const std::string device_key_temp = device_key_dir + "/temp";
 
-    // How long do we store passwords for?
-    const int password_max_age_seconds = 60;
+const std::string user_key_dir = std::string() + DATA_MNT_POINT + "/misc/vold/user_keys";
+const std::string user_key_temp = user_key_dir + "/temp";
 
-    // How is device encrypted
-    struct keys {
-        std::string master_key;
-        std::string password;
-        time_t expiry_time;
-    };
-    std::map<std::string, keys> s_key_store;
+bool s_global_de_initialized = false;
 
-    // ext4enc:TODO get these consts from somewhere good
-    const int SHA512_LENGTH = 64;
-    const int EXT4_KEY_DESCRIPTOR_SIZE = 8;
+// Some users are ephemeral, don't try to wipe their keys from disk
+std::set<userid_t> s_ephemeral_users;
 
-    // ext4enc:TODO Include structure from somewhere sensible
-    // MUST be in sync with ext4_crypto.c in kernel
-    const int EXT4_MAX_KEY_SIZE = 64;
-    const int EXT4_ENCRYPTION_MODE_AES_256_XTS = 1;
-    struct ext4_encryption_key {
-        uint32_t mode;
-        char raw[EXT4_MAX_KEY_SIZE];
-        uint32_t size;
-    };
+// Map user ids to key references
+std::map<userid_t, std::string> s_de_key_raw_refs;
+std::map<userid_t, std::string> s_ce_key_raw_refs;
+// TODO abolish this map. Keys should not be long-lived in user memory, only kernel memory.
+// See b/26948053
+std::map<userid_t, std::string> s_ce_keys;
 
-    namespace tag {
-        const char* magic = "magic";
-        const char* major_version = "major_version";
-        const char* minor_version = "minor_version";
-        const char* flags = "flags";
-        const char* crypt_type = "crypt_type";
-        const char* failed_decrypt_count = "failed_decrypt_count";
-        const char* crypto_type_name = "crypto_type_name";
-        const char* master_key = "master_key";
-        const char* salt = "salt";
-        const char* kdf_type = "kdf_type";
-        const char* N_factor = "N_factor";
-        const char* r_factor = "r_factor";
-        const char* p_factor = "p_factor";
-        const char* keymaster_blob = "keymaster_blob";
-        const char* scrypted_intermediate_key = "scrypted_intermediate_key";
-    }
+// ext4enc:TODO get this const from somewhere good
+const int EXT4_KEY_DESCRIPTOR_SIZE = 8;
+
+// ext4enc:TODO Include structure from somewhere sensible
+// MUST be in sync with ext4_crypto.c in kernel
+constexpr int EXT4_ENCRYPTION_MODE_AES_256_XTS = 1;
+constexpr int EXT4_AES_256_XTS_KEY_SIZE = 64;
+constexpr int EXT4_MAX_KEY_SIZE = 64;
+struct ext4_encryption_key {
+    uint32_t mode;
+    char raw[EXT4_MAX_KEY_SIZE];
+    uint32_t size;
+};
 }
 
-static std::string e4crypt_install_key(const std::string &key);
-
-static int put_crypt_ftr_and_key(const crypt_mnt_ftr& crypt_ftr,
-                                 UnencryptedProperties& props)
-{
-    SLOGI("Putting crypt footer");
-
-    bool success = props.Set<int>(tag::magic, crypt_ftr.magic)
-      && props.Set<int>(tag::major_version, crypt_ftr.major_version)
-      && props.Set<int>(tag::minor_version, crypt_ftr.minor_version)
-      && props.Set<int>(tag::flags, crypt_ftr.flags)
-      && props.Set<int>(tag::crypt_type, crypt_ftr.crypt_type)
-      && props.Set<int>(tag::failed_decrypt_count,
-                        crypt_ftr.failed_decrypt_count)
-      && props.Set<std::string>(tag::crypto_type_name,
-                                std::string(reinterpret_cast<const char*>(crypt_ftr.crypto_type_name)))
-      && props.Set<std::string>(tag::master_key,
-                                std::string((const char*) crypt_ftr.master_key,
-                                            crypt_ftr.keysize))
-      && props.Set<std::string>(tag::salt,
-                                std::string((const char*) crypt_ftr.salt,
-                                            SALT_LEN))
-      && props.Set<int>(tag::kdf_type, crypt_ftr.kdf_type)
-      && props.Set<int>(tag::N_factor, crypt_ftr.N_factor)
-      && props.Set<int>(tag::r_factor, crypt_ftr.r_factor)
-      && props.Set<int>(tag::p_factor, crypt_ftr.p_factor)
-      && props.Set<std::string>(tag::keymaster_blob,
-                                std::string((const char*) crypt_ftr.keymaster_blob,
-                                            crypt_ftr.keymaster_blob_size))
-      && props.Set<std::string>(tag::scrypted_intermediate_key,
-                                std::string((const char*) crypt_ftr.scrypted_intermediate_key,
-                                            SCRYPT_LEN));
-    return success ? 0 : -1;
+static bool e4crypt_is_emulated() {
+    return property_get_bool("persist.sys.emulate_fbe", false);
 }
 
-static int get_crypt_ftr_and_key(crypt_mnt_ftr& crypt_ftr,
-                                 const UnencryptedProperties& props)
-{
-    memset(&crypt_ftr, 0, sizeof(crypt_ftr));
-    crypt_ftr.magic = props.Get<int>(tag::magic);
-    crypt_ftr.major_version = props.Get<int>(tag::major_version);
-    crypt_ftr.minor_version = props.Get<int>(tag::minor_version);
-    crypt_ftr.ftr_size = sizeof(crypt_ftr);
-    crypt_ftr.flags = props.Get<int>(tag::flags);
-    crypt_ftr.crypt_type = props.Get<int>(tag::crypt_type);
-    crypt_ftr.failed_decrypt_count = props.Get<int>(tag::failed_decrypt_count);
-    std::string crypto_type_name = props.Get<std::string>(tag::crypto_type_name);
-    strlcpy(reinterpret_cast<char*>(crypt_ftr.crypto_type_name),
-            crypto_type_name.c_str(),
-            sizeof(crypt_ftr.crypto_type_name));
-    std::string master_key = props.Get<std::string>(tag::master_key);
-    crypt_ftr.keysize = master_key.size();
-    if (crypt_ftr.keysize > sizeof(crypt_ftr.master_key)) {
-        SLOGE("Master key size too long");
-        return -1;
-    }
-    memcpy(crypt_ftr.master_key, &master_key[0], crypt_ftr.keysize);
-    std::string salt = props.Get<std::string>(tag::salt);
-    if (salt.size() != SALT_LEN) {
-        SLOGE("Salt wrong length");
-        return -1;
-    }
-    memcpy(crypt_ftr.salt, &salt[0], SALT_LEN);
-    crypt_ftr.kdf_type = props.Get<int>(tag::kdf_type);
-    crypt_ftr.N_factor = props.Get<int>(tag::N_factor);
-    crypt_ftr.r_factor = props.Get<int>(tag::r_factor);
-    crypt_ftr.p_factor = props.Get<int>(tag::p_factor);
-    std::string keymaster_blob = props.Get<std::string>(tag::keymaster_blob);
-    crypt_ftr.keymaster_blob_size = keymaster_blob.size();
-    if (crypt_ftr.keymaster_blob_size > sizeof(crypt_ftr.keymaster_blob)) {
-        SLOGE("Keymaster blob too long");
-        return -1;
-    }
-    memcpy(crypt_ftr.keymaster_blob, &keymaster_blob[0],
-           crypt_ftr.keymaster_blob_size);
-    std::string scrypted_intermediate_key = props.Get<std::string>(tag::scrypted_intermediate_key);
-    if (scrypted_intermediate_key.size() != SCRYPT_LEN) {
-        SLOGE("scrypted intermediate key wrong length");
-        return -1;
-    }
-    memcpy(crypt_ftr.scrypted_intermediate_key, &scrypted_intermediate_key[0],
-           SCRYPT_LEN);
-
-    return 0;
-}
-
-static UnencryptedProperties GetProps(const char* path)
-{
-    return UnencryptedProperties(path);
-}
-
-static UnencryptedProperties GetAltProps(const char* path)
-{
-    return UnencryptedProperties((std::string() + path + "/tmp_mnt").c_str());
-}
-
-static UnencryptedProperties GetPropsOrAltProps(const char* path)
-{
-    UnencryptedProperties props = GetProps(path);
-    if (props.OK()) {
-        return props;
-    }
-    return GetAltProps(path);
-}
-
-int e4crypt_enable(const char* path)
-{
-    // Already enabled?
-    if (s_key_store.find(path) != s_key_store.end()) {
-        return 0;
-    }
-
-    // Not an encryptable device?
-    UnencryptedProperties key_props = GetProps(path).GetChild(properties::key);
-    if (!key_props.OK()) {
-        return 0;
-    }
-
-    if (key_props.Get<std::string>(tag::master_key).empty()) {
-        crypt_mnt_ftr ftr;
-        if (cryptfs_create_default_ftr(&ftr, key_length)) {
-            SLOGE("Failed to create crypto footer");
-            return -1;
-        }
-
-        // Scrub fields not used by ext4enc
-        ftr.persist_data_offset[0] = 0;
-        ftr.persist_data_offset[1] = 0;
-        ftr.persist_data_size = 0;
-
-        if (put_crypt_ftr_and_key(ftr, key_props)) {
-            SLOGE("Failed to write crypto footer");
-            return -1;
-        }
-
-        crypt_mnt_ftr ftr2;
-        if (get_crypt_ftr_and_key(ftr2, key_props)) {
-            SLOGE("Failed to read crypto footer back");
-            return -1;
-        }
-
-        if (memcmp(&ftr, &ftr2, sizeof(ftr)) != 0) {
-            SLOGE("Crypto footer not correctly written");
-            return -1;
-        }
-    }
-
-    if (!UnencryptedProperties(path).Remove(properties::ref)) {
-        SLOGE("Failed to remove key ref");
-        return -1;
-    }
-
-    return e4crypt_check_passwd(path, "");
-}
-
-int e4crypt_change_password(const char* path, int crypt_type,
-                            const char* password)
-{
-    SLOGI("e4crypt_change_password");
-    auto key_props = GetProps(path).GetChild(properties::key);
-
-    crypt_mnt_ftr ftr;
-    if (get_crypt_ftr_and_key(ftr, key_props)) {
-        SLOGE("Failed to read crypto footer back");
-        return -1;
-    }
-
-    auto mki = s_key_store.find(path);
-    if (mki == s_key_store.end()) {
-        SLOGE("No stored master key - can't change password");
-        return -1;
-    }
-
-    const unsigned char* master_key_bytes
-        = reinterpret_cast<const unsigned char*>(&mki->second.master_key[0]);
-
-    if (cryptfs_set_password(&ftr, password, master_key_bytes)) {
-        SLOGE("Failed to set password");
-        return -1;
-    }
-
-    ftr.crypt_type = crypt_type;
-
-    if (put_crypt_ftr_and_key(ftr, key_props)) {
-        SLOGE("Failed to write crypto footer");
-        return -1;
-    }
-
-    if (!UnencryptedProperties(path).Set(properties::is_default,
-                            crypt_type == CRYPT_TYPE_DEFAULT)) {
-        SLOGE("Failed to update default flag");
-        return -1;
-    }
-
-    return 0;
-}
-
-int e4crypt_crypto_complete(const char* path)
-{
-    SLOGI("ext4 crypto complete called on %s", path);
-    auto key_props = GetPropsOrAltProps(path).GetChild(properties::key);
-    if (key_props.Get<std::string>(tag::master_key).empty()) {
-        SLOGI("No master key, so not ext4enc");
-        return -1;
-    }
-
-    return 0;
+static const char* escape_null(const char* value) {
+    return (value == nullptr) ? "null" : value;
 }
 
 // Get raw keyref - used to make keyname and to pass to ioctl
-static std::string generate_key_ref(const char* key, int length)
-{
+static std::string generate_key_ref(const char* key, int length) {
     SHA512_CTX c;
 
     SHA512_Init(&c);
     SHA512_Update(&c, key, length);
-    unsigned char key_ref1[SHA512_LENGTH];
+    unsigned char key_ref1[SHA512_DIGEST_LENGTH];
     SHA512_Final(key_ref1, &c);
 
     SHA512_Init(&c);
-    SHA512_Update(&c, key_ref1, SHA512_LENGTH);
-    unsigned char key_ref2[SHA512_LENGTH];
+    SHA512_Update(&c, key_ref1, SHA512_DIGEST_LENGTH);
+    unsigned char key_ref2[SHA512_DIGEST_LENGTH];
     SHA512_Final(key_ref2, &c);
 
+    static_assert(EXT4_KEY_DESCRIPTOR_SIZE <= SHA512_DIGEST_LENGTH,
+                  "Hash too short for descriptor");
     return std::string((char*)key_ref2, EXT4_KEY_DESCRIPTOR_SIZE);
 }
 
-int e4crypt_check_passwd(const char* path, const char* password)
-{
-    SLOGI("e4crypt_check_password");
-    auto props = GetPropsOrAltProps(path);
-    auto key_props = props.GetChild(properties::key);
-
-    crypt_mnt_ftr ftr;
-    if (get_crypt_ftr_and_key(ftr, key_props)) {
-        SLOGE("Failed to read crypto footer back");
-        return -1;
+static bool fill_key(const std::string& key, ext4_encryption_key* ext4_key) {
+    if (key.size() != EXT4_AES_256_XTS_KEY_SIZE) {
+        LOG(ERROR) << "Wrong size key " << key.size();
+        return false;
     }
-
-    unsigned char master_key_bytes[key_length / 8];
-    if (cryptfs_get_master_key (&ftr, password, master_key_bytes)){
-        SLOGI("Incorrect password");
-        ftr.failed_decrypt_count++;
-        if (put_crypt_ftr_and_key(ftr, key_props)) {
-            SLOGW("Failed to update failed_decrypt_count");
-        }
-        return ftr.failed_decrypt_count;
-    }
-
-    if (ftr.failed_decrypt_count) {
-        ftr.failed_decrypt_count = 0;
-        if (put_crypt_ftr_and_key(ftr, key_props)) {
-            SLOGW("Failed to reset failed_decrypt_count");
-        }
-    }
-    std::string master_key(reinterpret_cast<char*>(master_key_bytes),
-                           sizeof(master_key_bytes));
-
-    struct timespec now;
-    clock_gettime(CLOCK_BOOTTIME, &now);
-    s_key_store[path] = keys{master_key, password,
-                             now.tv_sec + password_max_age_seconds};
-    auto raw_ref = e4crypt_install_key(master_key);
-    if (raw_ref.empty()) {
-        return -1;
-    }
-
-    // Save reference to key so we can set policy later
-    if (!props.Set(properties::ref, raw_ref)) {
-        SLOGE("Cannot save key reference");
-        return -1;
-    }
-
-    return 0;
+    static_assert(EXT4_AES_256_XTS_KEY_SIZE <= sizeof(ext4_key->raw), "Key too long!");
+    ext4_key->mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
+    ext4_key->size = key.size();
+    memset(ext4_key->raw, 0, sizeof(ext4_key->raw));
+    memcpy(ext4_key->raw, key.data(), key.size());
+    return true;
 }
 
-static ext4_encryption_key fill_key(const std::string &key)
-{
-    // ext4enc:TODO Currently raw key is required to be of length
-    // sizeof(ext4_key.raw) == EXT4_MAX_KEY_SIZE, so zero pad to
-    // this length. Change when kernel bug is fixed.
-    ext4_encryption_key ext4_key = {EXT4_ENCRYPTION_MODE_AES_256_XTS,
-                                    {0},
-                                    sizeof(ext4_key.raw)};
-    memset(ext4_key.raw, 0, sizeof(ext4_key.raw));
-    static_assert(key_length / 8 <= sizeof(ext4_key.raw),
-                  "Key too long!");
-    memcpy(ext4_key.raw, &key[0], key.size());
-    return ext4_key;
-}
-
-static std::string keyname(const std::string &raw_ref)
-{
+static std::string keyname(const std::string& raw_ref) {
     std::ostringstream o;
     o << "ext4:";
-    for (auto i = raw_ref.begin(); i != raw_ref.end(); ++i) {
-        o << std::hex << std::setw(2) << std::setfill('0') << (int)*i;
+    for (auto i : raw_ref) {
+        o << std::hex << std::setw(2) << std::setfill('0') << (int)i;
     }
     return o.str();
 }
 
 // Get the keyring we store all keys in
-static key_serial_t e4crypt_keyring()
-{
-    return keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring", "e4crypt", 0);
-}
-
-static int e4crypt_install_key(const ext4_encryption_key &ext4_key, const std::string &ref)
-{
-    key_serial_t device_keyring = e4crypt_keyring();
-    SLOGI("Found device_keyring - id is %d", device_keyring);
-    key_serial_t key_id = add_key("logon", ref.c_str(),
-                                  (void*)&ext4_key, sizeof(ext4_key),
-                                  device_keyring);
-    if (key_id == -1) {
-        SLOGE("Failed to insert key into keyring with error %s",
-              strerror(errno));
-        return -1;
-    }
-    SLOGI("Added key %d (%s) to keyring %d in process %d",
-          key_id, ref.c_str(), device_keyring, getpid());
-    return 0;
-}
-
-// Install password into global keyring
-// Return raw key reference for use in policy
-static std::string e4crypt_install_key(const std::string &key)
-{
-    auto ext4_key = fill_key(key);
-    auto raw_ref = generate_key_ref(ext4_key.raw, ext4_key.size);
-    auto ref = keyname(raw_ref);
-    if (e4crypt_install_key(ext4_key, ref) == -1) {
-        return "";
-    }
-    return raw_ref;
-}
-
-int e4crypt_restart(const char* path)
-{
-    SLOGI("e4crypt_restart");
-
-    int rc = 0;
-
-    SLOGI("ext4 restart called on %s", path);
-    property_set("vold.decrypt", "trigger_reset_main");
-    SLOGI("Just asked init to shut down class main");
-    sleep(2);
-
-    std::string tmp_path = std::string() + path + "/tmp_mnt";
-
-    rc = wait_and_unmount(tmp_path.c_str(), true);
-    if (rc) {
-        SLOGE("umount %s failed with rc %d, msg %s",
-              tmp_path.c_str(), rc, strerror(errno));
-        return rc;
-    }
-
-    rc = wait_and_unmount(path, true);
-    if (rc) {
-        SLOGE("umount %s failed with rc %d, msg %s",
-              path, rc, strerror(errno));
-        return rc;
-    }
-
-    return 0;
-}
-
-int e4crypt_get_password_type(const char* path)
-{
-    SLOGI("e4crypt_get_password_type");
-    return GetPropsOrAltProps(path).GetChild(properties::key)
-      .Get<int>(tag::crypt_type, CRYPT_TYPE_DEFAULT);
-}
-
-const char* e4crypt_get_password(const char* path)
-{
-    SLOGI("e4crypt_get_password");
-
-    auto i = s_key_store.find(path);
-    if (i == s_key_store.end()) {
-        return 0;
-    }
-
-    struct timespec now;
-    clock_gettime(CLOCK_BOOTTIME, &now);
-    if (i->second.expiry_time < now.tv_sec) {
-        e4crypt_clear_password(path);
-        return 0;
-    }
-
-    return i->second.password.c_str();
-}
-
-void e4crypt_clear_password(const char* path)
-{
-    SLOGI("e4crypt_clear_password");
-
-    auto i = s_key_store.find(path);
-    if (i == s_key_store.end()) {
-        return;
-    }
-
-    memset(&i->second.password[0], 0, i->second.password.size());
-    i->second.password = std::string();
-}
-
-int e4crypt_get_field(const char* path, const char* fieldname,
-                      char* value, size_t len)
-{
-    auto v = GetPropsOrAltProps(path).GetChild(properties::props)
-      .Get<std::string>(fieldname);
-
-    if (v == "") {
-        return CRYPTO_GETFIELD_ERROR_NO_FIELD;
-    }
-
-    if (v.length() >= len) {
-        return CRYPTO_GETFIELD_ERROR_BUF_TOO_SMALL;
-    }
-
-    strlcpy(value, v.c_str(), len);
-    return 0;
-}
-
-int e4crypt_set_field(const char* path, const char* fieldname,
-                      const char* value)
-{
-    return GetPropsOrAltProps(path).GetChild(properties::props)
-        .Set(fieldname, std::string(value)) ? 0 : -1;
-}
-
-static std::string get_key_path(
-    const char *mount_path,
-    const char *user_handle)
-{
-    // ext4enc:TODO get the path properly
-    auto key_dir = android::base::StringPrintf("%s/misc/vold/user_keys",
-        mount_path);
-    if (mkdir(key_dir.c_str(), 0700) < 0 && errno != EEXIST) {
-        SLOGE("Unable to create %s (%s)", key_dir.c_str(), strerror(errno));
-        return "";
-    }
-    return key_dir + "/" + user_handle;
-}
-
-// ext4enc:TODO this can't be the only place keys are read from /dev/urandom
-// we should unite those places.
-static std::string e4crypt_get_key(
-    const std::string &key_path,
-    bool create_if_absent)
-{
-    std::string content;
-    if (android::base::ReadFileToString(key_path, &content)) {
-        if (content.size() != key_length/8) {
-            SLOGE("Wrong size key %zu in  %s", content.size(), key_path.c_str());
-            return "";
-        }
-        return content;
-    }
-    if (!create_if_absent) {
-        SLOGE("No key found in %s", key_path.c_str());
-        return "";
-    }
-    std::ifstream urandom("/dev/urandom");
-    if (!urandom) {
-        SLOGE("Unable to open /dev/urandom (%s)", strerror(errno));
-        return "";
-    }
-    char key_bytes[key_length / 8];
-    errno = 0;
-    urandom.read(key_bytes, sizeof(key_bytes));
-    if (!urandom) {
-        SLOGE("Unable to read key from /dev/urandom (%s)", strerror(errno));
-        return "";
-    }
-    std::string key(key_bytes, sizeof(key_bytes));
-    if (!android::base::WriteStringToFile(key, key_path)) {
-        SLOGE("Unable to write key to %s (%s)",
-                key_path.c_str(), strerror(errno));
-        return "";
-    }
-    return key;
-}
-
-static int e4crypt_set_user_policy(const char *mount_path, const char *user_handle,
-                            const char *path, bool create_if_absent)
-{
-    SLOGD("e4crypt_set_user_policy for %s", user_handle);
-    auto user_key = e4crypt_get_key(
-        get_key_path(mount_path, user_handle),
-        create_if_absent);
-    if (user_key.empty()) {
-        return -1;
-    }
-    auto raw_ref = e4crypt_install_key(user_key);
-    if (raw_ref.empty()) {
-        return -1;
-    }
-    return do_policy_set(path, raw_ref.c_str(), raw_ref.size());
-}
-
-int e4crypt_create_new_user_dir(const char *user_handle, const char *path) {
-    SLOGD("e4crypt_create_new_user_dir(\"%s\", \"%s\")", user_handle, path);
-    if (mkdir(path, S_IRWXU | S_IRWXG | S_IXOTH) < 0) {
-        return -1;
-    }
-    if (chmod(path, S_IRWXU | S_IRWXG | S_IXOTH) < 0) {
-        return -1;
-    }
-    if (chown(path, AID_SYSTEM, AID_SYSTEM) < 0) {
-        return -1;
-    }
-    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
-        // ext4enc:TODO handle errors from this.
-        e4crypt_set_user_policy(DATA_MNT_POINT, user_handle, path, true);
-    }
-    return 0;
-}
-
-static bool is_numeric(const char *name) {
-    for (const char *p = name; *p != '\0'; p++) {
-        if (!isdigit(*p))
-            return false;
+static bool e4crypt_keyring(key_serial_t* device_keyring) {
+    *device_keyring = keyctl_search(KEY_SPEC_SESSION_KEYRING, "keyring", "e4crypt", 0);
+    if (*device_keyring == -1) {
+        PLOG(ERROR) << "Unable to find device keyring";
+        return false;
     }
     return true;
 }
 
-int e4crypt_set_user_crypto_policies(const char *dir)
-{
-    if (e4crypt_crypto_complete(DATA_MNT_POINT) != 0) {
-        return 0;
+// Install password into global keyring
+// Return raw key reference for use in policy
+static bool install_key(const std::string& key, std::string* raw_ref) {
+    ext4_encryption_key ext4_key;
+    if (!fill_key(key, &ext4_key)) return false;
+    *raw_ref = generate_key_ref(ext4_key.raw, ext4_key.size);
+    auto ref = keyname(*raw_ref);
+    key_serial_t device_keyring;
+    if (!e4crypt_keyring(&device_keyring)) return false;
+    key_serial_t key_id =
+        add_key("logon", ref.c_str(), (void*)&ext4_key, sizeof(ext4_key), device_keyring);
+    if (key_id == -1) {
+        PLOG(ERROR) << "Failed to insert key into keyring " << device_keyring;
+        return false;
     }
-    SLOGD("e4crypt_set_user_crypto_policies");
-    std::unique_ptr<DIR, int(*)(DIR*)> dirp(opendir(dir), closedir);
-    if (!dirp) {
-        SLOGE("Unable to read directory %s, error %s\n",
-            dir, strerror(errno));
-        return -1;
-    }
-    for (;;) {
-        struct dirent *result = readdir(dirp.get());
-        if (!result) {
-            // ext4enc:TODO check errno
-            break;
-        }
-        if (result->d_type != DT_DIR || !is_numeric(result->d_name)) {
-            continue; // skips user 0, which is a symlink
-        }
-        auto user_dir = std::string() + dir + "/" + result->d_name;
-        // ext4enc:TODO don't hardcode /data
-        if (e4crypt_set_user_policy("/data", result->d_name,
-                user_dir.c_str(), false)) {
-            // ext4enc:TODO If this function fails, stop the boot: we must
-            // deliver on promised encryption.
-            SLOGE("Unable to set policy on %s\n", user_dir.c_str());
-        }
-    }
-    return 0;
+    LOG(DEBUG) << "Added key " << key_id << " (" << ref << ") to keyring " << device_keyring
+               << " in process " << getpid();
+    return true;
 }
 
-int e4crypt_delete_user_key(const char *user_handle) {
-    SLOGD("e4crypt_delete_user_key(\"%s\")", user_handle);
-    auto key_path = get_key_path(DATA_MNT_POINT, user_handle);
-    auto key = e4crypt_get_key(key_path, 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) {
-        SLOGD("Revoked key with serial %ld ref %s\n", key_serial, ref.c_str());
+static std::string get_de_key_path(userid_t user_id) {
+    return StringPrintf("%s/de/%d", user_key_dir.c_str(), user_id);
+}
+
+static std::string get_ce_key_directory_path(userid_t user_id) {
+    return StringPrintf("%s/ce/%d", user_key_dir.c_str(), user_id);
+}
+
+// Returns the keys newest first
+static std::vector<std::string> get_ce_key_paths(const std::string& directory_path) {
+    auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(directory_path.c_str()), closedir);
+    if (!dirp) {
+        PLOG(ERROR) << "Unable to open ce key directory: " + directory_path;
+        return std::vector<std::string>();
+    }
+    std::vector<std::string> result;
+    for (;;) {
+        errno = 0;
+        auto const entry = readdir(dirp.get());
+        if (!entry) {
+            if (errno) {
+                PLOG(ERROR) << "Unable to read ce key directory: " + directory_path;
+                return std::vector<std::string>();
+            }
+            break;
+        }
+        if (entry->d_type != DT_DIR || entry->d_name[0] != 'c') {
+            LOG(DEBUG) << "Skipping non-key " << entry->d_name;
+            continue;
+        }
+        result.emplace_back(directory_path + "/" + entry->d_name);
+    }
+    std::sort(result.begin(), result.end());
+    std::reverse(result.begin(), result.end());
+    return result;
+}
+
+static std::string get_ce_key_current_path(const std::string& directory_path) {
+    return directory_path + "/current";
+}
+
+static bool get_ce_key_new_path(const std::string& directory_path,
+                                const std::vector<std::string>& paths,
+                                std::string *ce_key_path) {
+    if (paths.empty()) {
+        *ce_key_path = get_ce_key_current_path(directory_path);
+        return true;
+    }
+    for (unsigned int i = 0; i < UINT_MAX; i++) {
+        auto const candidate = StringPrintf("%s/cx%010u", directory_path.c_str(), i);
+        if (paths[0] < candidate) {
+            *ce_key_path = candidate;
+            return true;
+        }
+    }
+    return false;
+}
+
+// Discard all keys but the named one; rename it to canonical name.
+// No point in acting on errors in this; ignore them.
+static void fixate_user_ce_key(const std::string& directory_path, const std::string &to_fix,
+                               const std::vector<std::string>& paths) {
+    for (auto const other_path: paths) {
+        if (other_path != to_fix) {
+            android::vold::destroyKey(other_path);
+        }
+    }
+    auto const current_path = get_ce_key_current_path(directory_path);
+    if (to_fix != current_path) {
+        LOG(DEBUG) << "Renaming " << to_fix << " to " << current_path;
+        if (rename(to_fix.c_str(), current_path.c_str()) != 0) {
+            PLOG(WARNING) << "Unable to rename " << to_fix << " to " << current_path;
+        }
+    }
+}
+
+static bool read_and_fixate_user_ce_key(userid_t user_id,
+                                        const android::vold::KeyAuthentication& auth,
+                                        std::string *ce_key) {
+    auto const directory_path = get_ce_key_directory_path(user_id);
+    auto const paths = get_ce_key_paths(directory_path);
+    for (auto const ce_key_path: paths) {
+        LOG(DEBUG) << "Trying user CE key " << ce_key_path;
+        if (android::vold::retrieveKey(ce_key_path, auth, ce_key)) {
+            LOG(DEBUG) << "Successfully retrieved key";
+            fixate_user_ce_key(directory_path, ce_key_path, paths);
+            return true;
+        }
+    }
+    LOG(ERROR) << "Failed to find working ce key for user " << user_id;
+    return false;
+}
+
+static bool read_and_install_user_ce_key(userid_t user_id,
+                                         const android::vold::KeyAuthentication& auth) {
+    if (s_ce_key_raw_refs.count(user_id) != 0) return true;
+    std::string ce_key;
+    if (!read_and_fixate_user_ce_key(user_id, auth, &ce_key)) return false;
+    std::string ce_raw_ref;
+    if (!install_key(ce_key, &ce_raw_ref)) return false;
+    s_ce_keys[user_id] = ce_key;
+    s_ce_key_raw_refs[user_id] = ce_raw_ref;
+    LOG(DEBUG) << "Installed ce key for user " << user_id;
+    return true;
+}
+
+static bool prepare_dir(const std::string& dir, mode_t mode, uid_t uid, gid_t gid) {
+    LOG(DEBUG) << "Preparing: " << dir;
+    if (fs_prepare_dir(dir.c_str(), mode, uid, gid) != 0) {
+        PLOG(ERROR) << "Failed to prepare " << dir;
+        return false;
+    }
+    return true;
+}
+
+static bool destroy_dir(const std::string& dir) {
+    LOG(DEBUG) << "Destroying: " << dir;
+    if (rmdir(dir.c_str()) != 0 && errno != ENOENT) {
+        PLOG(ERROR) << "Failed to destroy " << dir;
+        return false;
+    }
+    return true;
+}
+
+static bool random_key(std::string* key) {
+    if (android::vold::ReadRandomBytes(EXT4_AES_256_XTS_KEY_SIZE, *key) != 0) {
+        // TODO status_t plays badly with PLOG, fix it.
+        LOG(ERROR) << "Random read failed";
+        return false;
+    }
+    return true;
+}
+
+static bool path_exists(const std::string& path) {
+    return access(path.c_str(), F_OK) == 0;
+}
+
+// NB this assumes that there is only one thread listening for crypt commands, because
+// it creates keys in a fixed location.
+static bool store_key(const std::string& key_path, const std::string& tmp_path,
+                      const android::vold::KeyAuthentication& auth, const std::string& key) {
+    if (path_exists(key_path)) {
+        LOG(ERROR) << "Already exists, cannot create key at: " << key_path;
+        return false;
+    }
+    if (path_exists(tmp_path)) {
+        android::vold::destroyKey(tmp_path);  // May be partially created so ignore errors
+    }
+    if (!android::vold::storeKey(tmp_path, auth, key)) return false;
+    if (rename(tmp_path.c_str(), key_path.c_str()) != 0) {
+        PLOG(ERROR) << "Unable to move new key to location: " << key_path;
+        return false;
+    }
+    LOG(DEBUG) << "Created key " << key_path;
+    return true;
+}
+
+static bool create_and_install_user_keys(userid_t user_id, bool create_ephemeral) {
+    std::string de_key, ce_key;
+    if (!random_key(&de_key)) return false;
+    if (!random_key(&ce_key)) return false;
+    if (create_ephemeral) {
+        // If the key should be created as ephemeral, don't store it.
+        s_ephemeral_users.insert(user_id);
     } else {
-        SLOGE("Failed to revoke key with serial %ld ref %s: %s\n",
-            key_serial, ref.c_str(), strerror(errno));
+        auto const directory_path = get_ce_key_directory_path(user_id);
+        if (!prepare_dir(directory_path, 0700, AID_ROOT, AID_ROOT)) return false;
+        auto const paths = get_ce_key_paths(directory_path);
+        std::string ce_key_path;
+        if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
+        if (!store_key(ce_key_path, user_key_temp,
+                kEmptyAuthentication, ce_key)) return false;
+        fixate_user_ce_key(directory_path, ce_key_path, paths);
+        // Write DE key second; once this is written, all is good.
+        if (!store_key(get_de_key_path(user_id), user_key_temp,
+                kEmptyAuthentication, de_key)) return false;
     }
-    int pid = fork();
-    if (pid < 0) {
-        SLOGE("Unable to fork: %s", strerror(errno));
-        return -1;
+    std::string de_raw_ref;
+    if (!install_key(de_key, &de_raw_ref)) return false;
+    s_de_key_raw_refs[user_id] = de_raw_ref;
+    std::string ce_raw_ref;
+    if (!install_key(ce_key, &ce_raw_ref)) return false;
+    s_ce_keys[user_id] = ce_key;
+    s_ce_key_raw_refs[user_id] = ce_raw_ref;
+    LOG(DEBUG) << "Created keys for user " << user_id;
+    return true;
+}
+
+static bool lookup_key_ref(const std::map<userid_t, std::string>& key_map, userid_t user_id,
+                           std::string* raw_ref) {
+    auto refi = key_map.find(user_id);
+    if (refi == key_map.end()) {
+        LOG(ERROR) << "Cannot find key for " << user_id;
+        return false;
     }
-    if (pid == 0) {
-        SLOGD("Forked for secdiscard");
-        execl("/system/bin/secdiscard",
-            "/system/bin/secdiscard",
-            key_path.c_str(),
-            NULL);
-        SLOGE("Unable to launch secdiscard on %s: %s\n", key_path.c_str(),
-            strerror(errno));
-        exit(-1);
+    *raw_ref = refi->second;
+    return true;
+}
+
+static bool ensure_policy(const std::string& raw_ref, const std::string& path) {
+    if (e4crypt_policy_ensure(path.c_str(), raw_ref.data(), raw_ref.size()) != 0) {
+        LOG(ERROR) << "Failed to set policy on: " << path;
+        return false;
     }
-    // ext4enc:TODO reap the zombie
-    return 0;
+    return true;
+}
+
+static bool is_numeric(const char* name) {
+    for (const char* p = name; *p != '\0'; p++) {
+        if (!isdigit(*p)) return false;
+    }
+    return true;
+}
+
+static bool load_all_de_keys() {
+    auto de_dir = user_key_dir + "/de";
+    auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(de_dir.c_str()), closedir);
+    if (!dirp) {
+        PLOG(ERROR) << "Unable to read de key directory";
+        return false;
+    }
+    for (;;) {
+        errno = 0;
+        auto entry = readdir(dirp.get());
+        if (!entry) {
+            if (errno) {
+                PLOG(ERROR) << "Unable to read de key directory";
+                return false;
+            }
+            break;
+        }
+        if (entry->d_type != DT_DIR || !is_numeric(entry->d_name)) {
+            LOG(DEBUG) << "Skipping non-de-key " << entry->d_name;
+            continue;
+        }
+        userid_t user_id = atoi(entry->d_name);
+        if (s_de_key_raw_refs.count(user_id) == 0) {
+            auto key_path = de_dir + "/" + entry->d_name;
+            std::string key;
+            if (!android::vold::retrieveKey(key_path, kEmptyAuthentication, &key)) return false;
+            std::string raw_ref;
+            if (!install_key(key, &raw_ref)) return false;
+            s_de_key_raw_refs[user_id] = raw_ref;
+            LOG(DEBUG) << "Installed de key for user " << user_id;
+        }
+    }
+    // ext4enc:TODO: go through all DE directories, ensure that all user dirs have the
+    // correct policy set on them, and that no rogue ones exist.
+    return true;
+}
+
+bool e4crypt_initialize_global_de() {
+    LOG(INFO) << "e4crypt_initialize_global_de";
+
+    if (s_global_de_initialized) {
+        LOG(INFO) << "Already initialized";
+        return true;
+    }
+
+    std::string device_key;
+    if (path_exists(device_key_path)) {
+        if (!android::vold::retrieveKey(device_key_path,
+                kEmptyAuthentication, &device_key)) return false;
+    } else {
+        LOG(INFO) << "Creating new key";
+        if (!random_key(&device_key)) return false;
+        if (!store_key(device_key_path, device_key_temp,
+                kEmptyAuthentication, device_key)) return false;
+    }
+
+    std::string device_key_ref;
+    if (!install_key(device_key, &device_key_ref)) {
+        LOG(ERROR) << "Failed to install device key";
+        return false;
+    }
+
+    std::string ref_filename = std::string("/data") + e4crypt_key_ref;
+    if (!android::base::WriteStringToFile(device_key_ref, ref_filename)) {
+        PLOG(ERROR) << "Cannot save key reference";
+        return false;
+    }
+
+    s_global_de_initialized = true;
+    return true;
+}
+
+bool e4crypt_init_user0() {
+    LOG(DEBUG) << "e4crypt_init_user0";
+    if (e4crypt_is_native()) {
+        if (!prepare_dir(user_key_dir, 0700, AID_ROOT, AID_ROOT)) return false;
+        if (!prepare_dir(user_key_dir + "/ce", 0700, AID_ROOT, AID_ROOT)) return false;
+        if (!prepare_dir(user_key_dir + "/de", 0700, AID_ROOT, AID_ROOT)) return false;
+        if (!path_exists(get_de_key_path(0))) {
+            if (!create_and_install_user_keys(0, false)) return false;
+        }
+        // TODO: switch to loading only DE_0 here once framework makes
+        // explicit calls to install DE keys for secondary users
+        if (!load_all_de_keys()) return false;
+    }
+    // We can only safely prepare DE storage here, since CE keys are probably
+    // entangled with user credentials.  The framework will always prepare CE
+    // storage once CE keys are installed.
+    if (!e4crypt_prepare_user_storage(nullptr, 0, 0, FLAG_STORAGE_DE)) {
+        LOG(ERROR) << "Failed to prepare user 0 storage";
+        return false;
+    }
+
+    // If this is a non-FBE device that recently left an emulated mode,
+    // restore user data directories to known-good state.
+    if (!e4crypt_is_native() && !e4crypt_is_emulated()) {
+        e4crypt_unlock_user_key(0, 0, "!", "!");
+    }
+
+    return true;
+}
+
+bool 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 (!e4crypt_is_native()) {
+        return true;
+    }
+    // FIXME test for existence of key that is not loaded yet
+    if (s_ce_key_raw_refs.count(user_id) != 0) {
+        LOG(ERROR) << "Already exists, can't e4crypt_vold_create_user_key for " << user_id
+                   << " serial " << serial;
+        // FIXME should we fail the command?
+        return true;
+    }
+    if (!create_and_install_user_keys(user_id, ephemeral)) {
+        return false;
+    }
+    return true;
+}
+
+static bool evict_key(const std::string& raw_ref) {
+    auto ref = keyname(raw_ref);
+    key_serial_t device_keyring;
+    if (!e4crypt_keyring(&device_keyring)) return false;
+    auto key_serial = keyctl_search(device_keyring, "logon", ref.c_str(), 0);
+    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;
+}
+
+bool e4crypt_destroy_user_key(userid_t user_id) {
+    LOG(DEBUG) << "e4crypt_destroy_user_key(" << user_id << ")";
+    if (!e4crypt_is_native()) {
+        return true;
+    }
+    bool success = true;
+    s_ce_keys.erase(user_id);
+    std::string raw_ref;
+    // If we haven't loaded the CE key, no need to evict it.
+    if (lookup_key_ref(s_ce_key_raw_refs, user_id, &raw_ref)) {
+        success &= evict_key(raw_ref);
+    }
+    s_ce_key_raw_refs.erase(user_id);
+    success &= lookup_key_ref(s_de_key_raw_refs, user_id, &raw_ref) && evict_key(raw_ref);
+    s_de_key_raw_refs.erase(user_id);
+    auto it = s_ephemeral_users.find(user_id);
+    if (it != s_ephemeral_users.end()) {
+        s_ephemeral_users.erase(it);
+    } else {
+        for (auto const path: get_ce_key_paths(get_ce_key_directory_path(user_id))) {
+            success &= android::vold::destroyKey(path);
+        }
+        success &= android::vold::destroyKey(get_de_key_path(user_id));
+    }
+    return success;
+}
+
+static bool emulated_lock(const std::string& path) {
+    if (chmod(path.c_str(), 0000) != 0) {
+        PLOG(ERROR) << "Failed to chmod " << path;
+        return false;
+    }
+#if EMULATED_USES_SELINUX
+    if (setfilecon(path.c_str(), "u:object_r:storage_stub_file:s0") != 0) {
+        PLOG(WARNING) << "Failed to setfilecon " << path;
+        return false;
+    }
+#endif
+    return true;
+}
+
+static bool emulated_unlock(const std::string& path, mode_t mode) {
+    if (chmod(path.c_str(), mode) != 0) {
+        PLOG(ERROR) << "Failed to chmod " << path;
+        // FIXME temporary workaround for b/26713622
+        if (e4crypt_is_emulated()) return false;
+    }
+#if EMULATED_USES_SELINUX
+    if (selinux_android_restorecon(path.c_str(), SELINUX_ANDROID_RESTORECON_FORCE) != 0) {
+        PLOG(WARNING) << "Failed to restorecon " << path;
+        // FIXME temporary workaround for b/26713622
+        if (e4crypt_is_emulated()) return false;
+    }
+#endif
+    return true;
+}
+
+static bool parse_hex(const char* hex, std::string* result) {
+    if (strcmp("!", hex) == 0) {
+        *result = "";
+        return true;
+    }
+    if (android::vold::HexToStr(hex, *result) != 0) {
+        LOG(ERROR) << "Invalid FBE hex string";  // Don't log the string for security reasons
+        return false;
+    }
+    return true;
+}
+
+bool e4crypt_add_user_key_auth(userid_t user_id, int serial, const char* token_hex,
+                          const char* secret_hex) {
+    LOG(DEBUG) << "e4crypt_add_user_key_auth " << user_id << " serial=" << serial
+               << " token_present=" << (strcmp(token_hex, "!") != 0);
+    if (!e4crypt_is_native()) return true;
+    if (s_ephemeral_users.count(user_id) != 0) return true;
+    std::string token, secret;
+    if (!parse_hex(token_hex, &token)) return false;
+    if (!parse_hex(secret_hex, &secret)) return false;
+    auto auth = secret.empty() ? kEmptyAuthentication
+                                   : android::vold::KeyAuthentication(token, secret);
+    auto it = s_ce_keys.find(user_id);
+    if (it == s_ce_keys.end()) {
+        LOG(ERROR) << "Key not loaded into memory, can't change for user " << user_id;
+        return false;
+    }
+    auto ce_key = it->second;
+    auto const directory_path = get_ce_key_directory_path(user_id);
+    auto const paths = get_ce_key_paths(directory_path);
+    std::string ce_key_path;
+    if (!get_ce_key_new_path(directory_path, paths, &ce_key_path)) return false;
+    if (!store_key(ce_key_path, user_key_temp, auth, ce_key)) return false;
+    return true;
+}
+
+bool e4crypt_fixate_newest_user_key_auth(userid_t user_id) {
+    LOG(DEBUG) << "e4crypt_fixate_newest_user_key_auth " << user_id;
+    if (!e4crypt_is_native()) return true;
+    auto const directory_path = get_ce_key_directory_path(user_id);
+    auto const paths = get_ce_key_paths(directory_path);
+    if (paths.empty()) {
+        LOG(ERROR) << "No ce keys present, cannot fixate for user " << user_id;
+        return false;
+    }
+    fixate_user_ce_key(directory_path, paths[0], paths);
+    return true;
+}
+
+// TODO: rename to 'install' for consistency, and take flags to know which keys to install
+bool e4crypt_unlock_user_key(userid_t user_id, int serial, const char* token_hex,
+                             const char* secret_hex) {
+    LOG(DEBUG) << "e4crypt_unlock_user_key " << user_id << " serial=" << serial
+               << " token_present=" << (strcmp(token_hex, "!") != 0);
+    if (e4crypt_is_native()) {
+        if (s_ce_key_raw_refs.count(user_id) != 0) {
+            LOG(WARNING) << "Tried to unlock already-unlocked key for user " << user_id;
+            return true;
+        }
+        std::string token, secret;
+        if (!parse_hex(token_hex, &token)) return false;
+        if (!parse_hex(secret_hex, &secret)) return false;
+        android::vold::KeyAuthentication auth(token, secret);
+        if (!read_and_install_user_ce_key(user_id, auth)) {
+            LOG(ERROR) << "Couldn't read key for " << user_id;
+            return false;
+        }
+    } else {
+        // When in emulation mode, we just use chmod. However, we also
+        // unlock directories when not in emulation mode, to bring devices
+        // back into a known-good state.
+        if (!emulated_unlock(android::vold::BuildDataSystemCePath(user_id), 0771) ||
+            !emulated_unlock(android::vold::BuildDataMiscCePath(user_id), 01771) ||
+            !emulated_unlock(android::vold::BuildDataMediaCePath(nullptr, user_id), 0770) ||
+            !emulated_unlock(android::vold::BuildDataUserCePath(nullptr, user_id), 0771)) {
+            LOG(ERROR) << "Failed to unlock user " << user_id;
+            return false;
+        }
+    }
+    return true;
+}
+
+// TODO: rename to 'evict' for consistency
+bool e4crypt_lock_user_key(userid_t user_id) {
+    if (e4crypt_is_native()) {
+        // TODO: remove from kernel keyring
+    } else if (e4crypt_is_emulated()) {
+        // When in emulation mode, we just use chmod
+        if (!emulated_lock(android::vold::BuildDataSystemCePath(user_id)) ||
+            !emulated_lock(android::vold::BuildDataMiscCePath(user_id)) ||
+            !emulated_lock(android::vold::BuildDataMediaCePath(nullptr, user_id)) ||
+            !emulated_lock(android::vold::BuildDataUserCePath(nullptr, user_id))) {
+            LOG(ERROR) << "Failed to lock user " << user_id;
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool e4crypt_prepare_user_storage(const char* volume_uuid, userid_t user_id, int serial,
+        int flags) {
+    LOG(DEBUG) << "e4crypt_prepare_user_storage for volume " << escape_null(volume_uuid)
+               << ", user " << user_id << ", serial " << serial << ", flags " << flags;
+
+    if (flags & FLAG_STORAGE_DE) {
+        // DE_sys key
+        auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
+        auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
+        auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
+        auto foreign_de_path = android::vold::BuildDataProfilesForeignDexDePath(user_id);
+
+        // DE_n key
+        auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
+        auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
+        auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
+
+        if (!prepare_dir(system_legacy_path, 0700, AID_SYSTEM, AID_SYSTEM)) return false;
+#if MANAGE_MISC_DIRS
+        if (!prepare_dir(misc_legacy_path, 0750, multiuser_get_uid(user_id, AID_SYSTEM),
+                multiuser_get_uid(user_id, AID_EVERYBODY))) return false;
+#endif
+        if (!prepare_dir(profiles_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
+        if (!prepare_dir(foreign_de_path, 0773, AID_SYSTEM, AID_SYSTEM)) return false;
+
+        if (!prepare_dir(system_de_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
+        if (!prepare_dir(misc_de_path, 01771, AID_SYSTEM, AID_MISC)) return false;
+        if (!prepare_dir(user_de_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
+
+        // For now, FBE is only supported on internal storage
+        if (e4crypt_is_native() && volume_uuid == nullptr) {
+            std::string de_raw_ref;
+            if (!lookup_key_ref(s_de_key_raw_refs, user_id, &de_raw_ref)) return false;
+            if (!ensure_policy(de_raw_ref, system_de_path)) return false;
+            if (!ensure_policy(de_raw_ref, misc_de_path)) return false;
+            if (!ensure_policy(de_raw_ref, user_de_path)) return false;
+        }
+    }
+
+    if (flags & FLAG_STORAGE_CE) {
+        // CE_n key
+        auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
+        auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
+        auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
+        auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
+
+        if (!prepare_dir(system_ce_path, 0770, AID_SYSTEM, AID_SYSTEM)) return false;
+        if (!prepare_dir(misc_ce_path, 01771, AID_SYSTEM, AID_MISC)) return false;
+        if (!prepare_dir(media_ce_path, 0770, AID_MEDIA_RW, AID_MEDIA_RW)) return false;
+        if (!prepare_dir(user_ce_path, 0771, AID_SYSTEM, AID_SYSTEM)) return false;
+
+        // For now, FBE is only supported on internal storage
+        if (e4crypt_is_native() && volume_uuid == nullptr) {
+            std::string ce_raw_ref;
+            if (!lookup_key_ref(s_ce_key_raw_refs, user_id, &ce_raw_ref)) return false;
+            if (!ensure_policy(ce_raw_ref, system_ce_path)) return false;
+            if (!ensure_policy(ce_raw_ref, misc_ce_path)) return false;
+            if (!ensure_policy(ce_raw_ref, media_ce_path)) return false;
+            if (!ensure_policy(ce_raw_ref, user_ce_path)) return false;
+        }
+    }
+
+    return true;
+}
+
+bool e4crypt_destroy_user_storage(const char* volume_uuid, userid_t user_id, int flags) {
+    LOG(DEBUG) << "e4crypt_destroy_user_storage for volume " << escape_null(volume_uuid)
+               << ", user " << user_id << ", flags " << flags;
+    bool res = true;
+
+    if (flags & FLAG_STORAGE_DE) {
+        // DE_sys key
+        auto system_legacy_path = android::vold::BuildDataSystemLegacyPath(user_id);
+        auto misc_legacy_path = android::vold::BuildDataMiscLegacyPath(user_id);
+        auto profiles_de_path = android::vold::BuildDataProfilesDePath(user_id);
+        auto foreign_de_path = android::vold::BuildDataProfilesForeignDexDePath(user_id);
+
+        // DE_n key
+        auto system_de_path = android::vold::BuildDataSystemDePath(user_id);
+        auto misc_de_path = android::vold::BuildDataMiscDePath(user_id);
+        auto user_de_path = android::vold::BuildDataUserDePath(volume_uuid, user_id);
+
+        if (volume_uuid == nullptr) {
+            res &= destroy_dir(system_legacy_path);
+#if MANAGE_MISC_DIRS
+            res &= destroy_dir(misc_legacy_path);
+#endif
+            res &= destroy_dir(profiles_de_path);
+            res &= destroy_dir(foreign_de_path);
+            res &= destroy_dir(system_de_path);
+            res &= destroy_dir(misc_de_path);
+        }
+        res &= destroy_dir(user_de_path);
+    }
+
+    if (flags & FLAG_STORAGE_CE) {
+        // CE_n key
+        auto system_ce_path = android::vold::BuildDataSystemCePath(user_id);
+        auto misc_ce_path = android::vold::BuildDataMiscCePath(user_id);
+        auto media_ce_path = android::vold::BuildDataMediaCePath(volume_uuid, user_id);
+        auto user_ce_path = android::vold::BuildDataUserCePath(volume_uuid, user_id);
+
+        if (volume_uuid == nullptr) {
+            res &= destroy_dir(system_ce_path);
+            res &= destroy_dir(misc_ce_path);
+        }
+        res &= destroy_dir(media_ce_path);
+        res &= destroy_dir(user_ce_path);
+    }
+
+    return res;
 }
diff --git a/Ext4Crypt.h b/Ext4Crypt.h
index f5c2871..2dcc197 100644
--- a/Ext4Crypt.h
+++ b/Ext4Crypt.h
@@ -1,25 +1,41 @@
-#include <stddef.h>
+/*
+ * Copyright (C) 2015 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 <stdbool.h>
 #include <sys/cdefs.h>
 
+#include <cutils/multiuser.h>
+
 __BEGIN_DECLS
 
 // General functions
-int e4crypt_enable(const char* path);
-int e4crypt_main(int argc, char* argv[]);
-int e4crypt_change_password(const char* path, int crypt_type,
-                            const char* password);
-int e4crypt_crypto_complete(const char* path);
-int e4crypt_check_passwd(const char* path, const char* password);
-int e4crypt_get_password_type(const char* path);
-const char* e4crypt_get_password(const char* path);
-void e4crypt_clear_password(const char* path);
-int e4crypt_restart(const char* path);
-int e4crypt_get_field(const char* path, const char* fieldname,
-                      char* value, size_t len);
-int e4crypt_set_field(const char* path, const char* fieldname,
-                      const char* value);
-int e4crypt_set_user_crypto_policies(const char *path);
-int e4crypt_create_new_user_dir(const char *user_handle, const char *path);
-int e4crypt_delete_user_key(const char *user_handle);
+bool e4crypt_is_native();
+bool e4crypt_initialize_global_de();
+
+bool e4crypt_init_user0();
+bool e4crypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral);
+bool e4crypt_destroy_user_key(userid_t user_id);
+bool e4crypt_add_user_key_auth(userid_t user_id, int serial, const char* token,
+                               const char* secret);
+bool e4crypt_fixate_newest_user_key_auth(userid_t user_id);
+
+bool e4crypt_unlock_user_key(userid_t user_id, int serial, const char* token, const char* secret);
+bool e4crypt_lock_user_key(userid_t user_id);
+
+bool e4crypt_prepare_user_storage(const char* volume_uuid, userid_t user_id, int serial, int flags);
+bool e4crypt_destroy_user_storage(const char* volume_uuid, userid_t user_id, int flags);
 
 __END_DECLS
diff --git a/KeyStorage.cpp b/KeyStorage.cpp
new file mode 100644
index 0000000..5234c56
--- /dev/null
+++ b/KeyStorage.cpp
@@ -0,0 +1,344 @@
+/*
+ * 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 "ScryptParameters.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 <cutils/properties.h>
+
+#include <hardware/hw_auth_token.h>
+
+#include <keymaster/authorization_set.h>
+
+extern "C" {
+
+#include "crypto_scrypt.h"
+}
+
+namespace android {
+namespace vold {
+
+const KeyAuthentication kEmptyAuthentication{"", ""};
+
+static constexpr size_t AES_KEY_BYTES = 32;
+static constexpr size_t GCM_NONCE_BYTES = 12;
+static constexpr size_t GCM_MAC_BYTES = 16;
+static constexpr size_t SALT_BYTES = 1 << 4;
+static constexpr size_t SECDISCARDABLE_BYTES = 1 << 14;
+static constexpr size_t STRETCHED_BYTES = 1 << 6;
+
+static constexpr uint32_t AUTH_TIMEOUT = 30; // Seconds
+
+static const char* kCurrentVersion = "1";
+static const char* kRmPath = "/system/bin/rm";
+static const char* kSecdiscardPath = "/system/bin/secdiscard";
+static const char* kStretch_none = "none";
+static const char* kStretch_nopassword = "nopassword";
+static const std::string kStretchPrefix_scrypt = "scrypt ";
+static const char* kFn_encrypted_key = "encrypted_key";
+static const char* kFn_keymaster_key_blob = "keymaster_key_blob";
+static const char* kFn_salt = "salt";
+static const char* kFn_secdiscardable = "secdiscardable";
+static const char* kFn_stretching = "stretching";
+static const char* kFn_version = "version";
+
+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 secdiscardableHashingPrefix = "Android secdiscardable SHA512";
+    secdiscardableHashingPrefix.resize(SHA512_CBLOCK);
+    SHA512_Update(&c, secdiscardableHashingPrefix.data(), secdiscardableHashingPrefix.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 KeyAuthentication& auth,
+                                 const std::string& appId, std::string* key) {
+    auto paramBuilder = keymaster::AuthorizationSetBuilder()
+                            .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);
+    addStringParam(&paramBuilder, keymaster::TAG_APPLICATION_ID, appId);
+    if (auth.token.empty()) {
+        LOG(DEBUG) << "Creating key that doesn't need auth token";
+        paramBuilder.Authorization(keymaster::TAG_NO_AUTH_REQUIRED);
+    } else {
+        LOG(DEBUG) << "Auth token required for key";
+        if (auth.token.size() != sizeof(hw_auth_token_t)) {
+            LOG(ERROR) << "Auth token should be " << sizeof(hw_auth_token_t) << " bytes, was "
+                       << auth.token.size() << " bytes";
+            return false;
+        }
+        const hw_auth_token_t* at = reinterpret_cast<const hw_auth_token_t*>(auth.token.data());
+        paramBuilder.Authorization(keymaster::TAG_USER_SECURE_ID, at->user_id);
+        paramBuilder.Authorization(keymaster::TAG_USER_AUTH_TYPE, HW_AUTH_PASSWORD);
+        paramBuilder.Authorization(keymaster::TAG_AUTH_TIMEOUT, AUTH_TIMEOUT);
+    }
+    return keymaster.generateKey(paramBuilder.build(), key);
+}
+
+static keymaster::AuthorizationSetBuilder beginParams(const KeyAuthentication& auth,
+                                                      const std::string& appId) {
+    auto paramBuilder = keymaster::AuthorizationSetBuilder()
+                            .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(&paramBuilder, keymaster::TAG_APPLICATION_ID, appId);
+    if (!auth.token.empty()) {
+        LOG(DEBUG) << "Supplying auth token to Keymaster";
+        addStringParam(&paramBuilder, keymaster::TAG_AUTH_TOKEN, auth.token);
+    }
+    return paramBuilder;
+}
+
+static bool encryptWithKeymasterKey(Keymaster& keymaster, const std::string& key,
+                                    const KeyAuthentication& auth, const std::string& appId,
+                                    const std::string& message, std::string* ciphertext) {
+    auto params = beginParams(auth, appId).build();
+    keymaster::AuthorizationSet outParams;
+    auto opHandle = keymaster.begin(KM_PURPOSE_ENCRYPT, key, params, &outParams);
+    if (!opHandle) return false;
+    keymaster_blob_t nonceBlob;
+    if (!outParams.GetTagValue(keymaster::TAG_NONCE, &nonceBlob)) {
+        LOG(ERROR) << "GCM encryption but no nonce generated";
+        return false;
+    }
+    // nonceBlob here is just a pointer into existing data, must not be freed
+    std::string nonce(reinterpret_cast<const char*>(nonceBlob.data), nonceBlob.data_length);
+    if (!checkSize("nonce", nonce.size(), GCM_NONCE_BYTES)) return false;
+    std::string body;
+    if (!opHandle.updateCompletely(message, &body)) return false;
+
+    std::string mac;
+    if (!opHandle.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 KeyAuthentication& auth, const std::string& appId,
+                                    const std::string& ciphertext, std::string* message) {
+    auto nonce = ciphertext.substr(0, GCM_NONCE_BYTES);
+    auto bodyAndMac = ciphertext.substr(GCM_NONCE_BYTES);
+    auto params = addStringParam(beginParams(auth, appId), keymaster::TAG_NONCE, nonce).build();
+    auto opHandle = keymaster.begin(KM_PURPOSE_DECRYPT, key, params);
+    if (!opHandle) return false;
+    if (!opHandle.updateCompletely(bodyAndMac, message)) return false;
+    if (!opHandle.finish()) return false;
+    return true;
+}
+
+static bool readFileToString(const std::string& filename, std::string* result) {
+    if (!android::base::ReadFileToString(filename, result)) {
+        PLOG(ERROR) << "Failed to read from " << filename;
+        return false;
+    }
+    return true;
+}
+
+static bool writeStringToFile(const std::string& payload, const std::string& filename) {
+    if (!android::base::WriteStringToFile(payload, filename)) {
+        PLOG(ERROR) << "Failed to write to " << filename;
+        return false;
+    }
+    return true;
+}
+
+static std::string getStretching() {
+    char paramstr[PROPERTY_VALUE_MAX];
+
+    property_get(SCRYPT_PROP, paramstr, SCRYPT_DEFAULTS);
+    return std::string() + kStretchPrefix_scrypt + paramstr;
+}
+
+static bool stretchingNeedsSalt(const std::string& stretching) {
+    return stretching != kStretch_nopassword && stretching != kStretch_none;
+}
+
+static bool stretchSecret(const std::string& stretching, const std::string& secret,
+                          const std::string& salt, std::string* stretched) {
+    if (stretching == kStretch_nopassword) {
+        if (!secret.empty()) {
+            LOG(WARNING) << "Password present but stretching is nopassword";
+            // Continue anyway
+        }
+        stretched->clear();
+    } else if (stretching == kStretch_none) {
+        *stretched = secret;
+    } else if (std::equal(kStretchPrefix_scrypt.begin(), kStretchPrefix_scrypt.end(),
+                          stretching.begin())) {
+        int Nf, rf, pf;
+        if (!parse_scrypt_parameters(stretching.substr(kStretchPrefix_scrypt.size()).c_str(), &Nf,
+                                     &rf, &pf)) {
+            LOG(ERROR) << "Unable to parse scrypt params in stretching: " << stretching;
+            return false;
+        }
+        stretched->assign(STRETCHED_BYTES, '\0');
+        if (crypto_scrypt(reinterpret_cast<const uint8_t*>(secret.data()), secret.size(),
+                          reinterpret_cast<const uint8_t*>(salt.data()), salt.size(),
+                          1 << Nf, 1 << rf, 1 << pf,
+                          reinterpret_cast<uint8_t*>(&(*stretched)[0]), stretched->size()) != 0) {
+            LOG(ERROR) << "scrypt failed with params: " << stretching;
+            return false;
+        }
+    } else {
+        LOG(ERROR) << "Unknown stretching type: " << stretching;
+        return false;
+    }
+    return true;
+}
+
+static bool generateAppId(const KeyAuthentication& auth, const std::string& stretching,
+                          const std::string& salt, const std::string& secdiscardable,
+                          std::string* appId) {
+    std::string stretched;
+    if (!stretchSecret(stretching, auth.secret, salt, &stretched)) return false;
+    *appId = hashSecdiscardable(secdiscardable) + stretched;
+    return true;
+}
+
+bool storeKey(const std::string& dir, const KeyAuthentication& auth, const std::string& key) {
+    if (TEMP_FAILURE_RETRY(mkdir(dir.c_str(), 0700)) == -1) {
+        PLOG(ERROR) << "key mkdir " << dir;
+        return false;
+    }
+    if (!writeStringToFile(kCurrentVersion, dir + "/" + kFn_version)) return false;
+    std::string secdiscardable;
+    if (ReadRandomBytes(SECDISCARDABLE_BYTES, secdiscardable) != OK) {
+        // TODO status_t plays badly with PLOG, fix it.
+        LOG(ERROR) << "Random read failed";
+        return false;
+    }
+    if (!writeStringToFile(secdiscardable, dir + "/" + kFn_secdiscardable)) return false;
+    std::string stretching = auth.secret.empty() ? kStretch_nopassword : getStretching();
+    if (!writeStringToFile(stretching, dir + "/" + kFn_stretching)) return false;
+    std::string salt;
+    if (stretchingNeedsSalt(stretching)) {
+        if (ReadRandomBytes(SALT_BYTES, salt) != OK) {
+            LOG(ERROR) << "Random read failed";
+            return false;
+        }
+        if (!writeStringToFile(salt, dir + "/" + kFn_salt)) return false;
+    }
+    std::string appId;
+    if (!generateAppId(auth, stretching, salt, secdiscardable, &appId)) return false;
+    Keymaster keymaster;
+    if (!keymaster) return false;
+    std::string kmKey;
+    if (!generateKeymasterKey(keymaster, auth, appId, &kmKey)) return false;
+    if (!writeStringToFile(kmKey, dir + "/" + kFn_keymaster_key_blob)) return false;
+    std::string encryptedKey;
+    if (!encryptWithKeymasterKey(keymaster, kmKey, auth, appId, key, &encryptedKey)) return false;
+    if (!writeStringToFile(encryptedKey, dir + "/" + kFn_encrypted_key)) return false;
+    return true;
+}
+
+bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, std::string* key) {
+    std::string version;
+    if (!readFileToString(dir + "/" + kFn_version, &version)) return false;
+    if (version != kCurrentVersion) {
+        LOG(ERROR) << "Version mismatch, expected " << kCurrentVersion << " got " << version;
+        return false;
+    }
+    std::string secdiscardable;
+    if (!readFileToString(dir + "/" + kFn_secdiscardable, &secdiscardable)) return false;
+    std::string stretching;
+    if (!readFileToString(dir + "/" + kFn_stretching, &stretching)) return false;
+    std::string salt;
+    if (stretchingNeedsSalt(stretching)) {
+        if (!readFileToString(dir + "/" + kFn_salt, &salt)) return false;
+    }
+    std::string appId;
+    if (!generateAppId(auth, stretching, salt, secdiscardable, &appId)) return false;
+    std::string kmKey;
+    if (!readFileToString(dir + "/" + kFn_keymaster_key_blob, &kmKey)) return false;
+    std::string encryptedMessage;
+    if (!readFileToString(dir + "/" + kFn_encrypted_key, &encryptedMessage)) return false;
+    Keymaster keymaster;
+    if (!keymaster) return false;
+    return decryptWithKeymasterKey(keymaster, kmKey, auth, appId, encryptedMessage, key);
+}
+
+static bool deleteKey(const std::string& dir) {
+    std::string kmKey;
+    if (!readFileToString(dir + "/" + kFn_keymaster_key_blob, &kmKey)) return false;
+    Keymaster keymaster;
+    if (!keymaster) return false;
+    if (!keymaster.deleteKey(kmKey)) 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..10ed789
--- /dev/null
+++ b/KeyStorage.h
@@ -0,0 +1,53 @@
+/*
+ * 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 {
+
+// Represents the information needed to decrypt a disk encryption key.
+// If "token" is nonempty, it is passed in as a required Gatekeeper auth token.
+// If "secret" is nonempty, it is appended to the application-specific
+// binary needed to unlock.
+class KeyAuthentication {
+  public:
+    KeyAuthentication(std::string t, std::string s) : token{t}, secret{s} {};
+    const std::string token;
+    const std::string secret;
+};
+
+extern const KeyAuthentication kEmptyAuthentication;
+
+// 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& dir, const KeyAuthentication& auth, const std::string& key);
+
+// Retrieve the key from the named directory.
+bool retrieveKey(const std::string& dir, const KeyAuthentication& auth, 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..d271b6a
--- /dev/null
+++ b/Keymaster.cpp
@@ -0,0 +1,250 @@
+/*
+ * 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>
+#include <hardware/hardware.h>
+#include <hardware/keymaster1.h>
+#include <hardware/keymaster2.h>
+
+namespace android {
+namespace vold {
+
+class IKeymasterDevice {
+  public:
+    IKeymasterDevice() {}
+    virtual ~IKeymasterDevice() {}
+    virtual keymaster_error_t generate_key(const keymaster_key_param_set_t* params,
+                                           keymaster_key_blob_t* key_blob) const = 0;
+    virtual keymaster_error_t delete_key(const keymaster_key_blob_t* key) const = 0;
+    virtual keymaster_error_t begin(keymaster_purpose_t purpose, const keymaster_key_blob_t* key,
+                                    const keymaster_key_param_set_t* in_params,
+                                    keymaster_key_param_set_t* out_params,
+                                    keymaster_operation_handle_t* operation_handle) const = 0;
+    virtual keymaster_error_t update(keymaster_operation_handle_t operation_handle,
+                                     const keymaster_key_param_set_t* in_params,
+                                     const keymaster_blob_t* input, size_t* input_consumed,
+                                     keymaster_key_param_set_t* out_params,
+                                     keymaster_blob_t* output) const = 0;
+    virtual keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
+                                     const keymaster_key_param_set_t* in_params,
+                                     const keymaster_blob_t* signature,
+                                     keymaster_key_param_set_t* out_params,
+                                     keymaster_blob_t* output) const = 0;
+    virtual keymaster_error_t abort(keymaster_operation_handle_t operation_handle) const = 0;
+
+  protected:
+    DISALLOW_COPY_AND_ASSIGN(IKeymasterDevice);
+};
+
+template <typename T> class KeymasterDevice : public IKeymasterDevice {
+  public:
+    KeymasterDevice(T* d) : mDevice{d} {}
+    keymaster_error_t generate_key(const keymaster_key_param_set_t* params,
+                                   keymaster_key_blob_t* key_blob) const override final {
+        return mDevice->generate_key(mDevice, params, key_blob, nullptr);
+    }
+    keymaster_error_t delete_key(const keymaster_key_blob_t* key) const override final {
+        if (mDevice->delete_key == nullptr) return KM_ERROR_OK;
+        return mDevice->delete_key(mDevice, key);
+    }
+    keymaster_error_t begin(keymaster_purpose_t purpose, const keymaster_key_blob_t* key,
+                            const keymaster_key_param_set_t* in_params,
+                            keymaster_key_param_set_t* out_params,
+                            keymaster_operation_handle_t* operation_handle) const override final {
+        return mDevice->begin(mDevice, purpose, key, in_params, out_params, operation_handle);
+    }
+    keymaster_error_t update(keymaster_operation_handle_t operation_handle,
+                             const keymaster_key_param_set_t* in_params,
+                             const keymaster_blob_t* input, size_t* input_consumed,
+                             keymaster_key_param_set_t* out_params,
+                             keymaster_blob_t* output) const override final {
+        return mDevice->update(mDevice, operation_handle, in_params, input, input_consumed,
+                               out_params, output);
+    }
+    keymaster_error_t abort(keymaster_operation_handle_t operation_handle) const override final {
+        return mDevice->abort(mDevice, operation_handle);
+    }
+
+  protected:
+    T* const mDevice;
+};
+
+class Keymaster1Device : public KeymasterDevice<keymaster1_device_t> {
+  public:
+    Keymaster1Device(keymaster1_device_t* d) : KeymasterDevice<keymaster1_device_t>{d} {}
+    ~Keymaster1Device() override final { keymaster1_close(mDevice); }
+    keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
+                             const keymaster_key_param_set_t* in_params,
+                             const keymaster_blob_t* signature,
+                             keymaster_key_param_set_t* out_params,
+                             keymaster_blob_t* output) const override final {
+        return mDevice->finish(mDevice, operation_handle, in_params, signature, out_params, output);
+    }
+};
+
+class Keymaster2Device : public KeymasterDevice<keymaster2_device_t> {
+  public:
+    Keymaster2Device(keymaster2_device_t* d) : KeymasterDevice<keymaster2_device_t>{d} {}
+    ~Keymaster2Device() override final { keymaster2_close(mDevice); }
+    keymaster_error_t finish(keymaster_operation_handle_t operation_handle,
+                             const keymaster_key_param_set_t* in_params,
+                             const keymaster_blob_t* signature,
+                             keymaster_key_param_set_t* out_params,
+                             keymaster_blob_t* output) const override final {
+        return mDevice->finish(mDevice, operation_handle, in_params, nullptr, signature, out_params,
+                               output);
+    }
+};
+
+KeymasterOperation::~KeymasterOperation() {
+    if (mDevice) mDevice->abort(mOpHandle);
+}
+
+bool KeymasterOperation::updateCompletely(const std::string& input, std::string* output) {
+    output->clear();
+    auto it = input.begin();
+    while (it != input.end()) {
+        size_t toRead = static_cast<size_t>(input.end() - it);
+        keymaster_blob_t inputBlob{reinterpret_cast<const uint8_t*>(&*it), toRead};
+        keymaster_blob_t outputBlob;
+        size_t inputConsumed;
+        auto error =
+            mDevice->update(mOpHandle, nullptr, &inputBlob, &inputConsumed, nullptr, &outputBlob);
+        if (error != KM_ERROR_OK) {
+            LOG(ERROR) << "update failed, code " << error;
+            mDevice = nullptr;
+            return false;
+        }
+        output->append(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
+        free(const_cast<uint8_t*>(outputBlob.data));
+        if (inputConsumed > toRead) {
+            LOG(ERROR) << "update reported too much input consumed";
+            mDevice = nullptr;
+            return false;
+        }
+        it += inputConsumed;
+    }
+    return true;
+}
+
+bool KeymasterOperation::finish() {
+    auto error = mDevice->finish(mOpHandle, nullptr, nullptr, nullptr, nullptr);
+    mDevice = 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 outputBlob;
+    auto error = mDevice->finish(mOpHandle, nullptr, nullptr, nullptr, &outputBlob);
+    mDevice = nullptr;
+    if (error != KM_ERROR_OK) {
+        LOG(ERROR) << "finish failed, code " << error;
+        return false;
+    }
+    output->assign(reinterpret_cast<const char*>(outputBlob.data), outputBlob.data_length);
+    free(const_cast<uint8_t*>(outputBlob.data));
+    return true;
+}
+
+Keymaster::Keymaster() {
+    mDevice = 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;
+    }
+    if (module->module_api_version == KEYMASTER_MODULE_API_VERSION_1_0) {
+        keymaster1_device_t* device;
+        ret = keymaster1_open(module, &device);
+        if (ret != 0) {
+            LOG(ERROR) << "keymaster1_open returned " << ret;
+            return;
+        }
+        mDevice = std::make_shared<Keymaster1Device>(device);
+    } else if (module->module_api_version == KEYMASTER_MODULE_API_VERSION_2_0) {
+        keymaster2_device_t* device;
+        ret = keymaster2_open(module, &device);
+        if (ret != 0) {
+            LOG(ERROR) << "keymaster2_open returned " << ret;
+            return;
+        }
+        mDevice = std::make_shared<Keymaster2Device>(device);
+    } else {
+        LOG(ERROR) << "module_api_version is " << module->module_api_version;
+        return;
+    }
+}
+
+bool Keymaster::generateKey(const keymaster::AuthorizationSet& inParams, std::string* key) {
+    keymaster_key_blob_t keyBlob;
+    auto error = mDevice->generate_key(&inParams, &keyBlob);
+    if (error != KM_ERROR_OK) {
+        LOG(ERROR) << "generate_key failed, code " << error;
+        return false;
+    }
+    key->assign(reinterpret_cast<const char*>(keyBlob.key_material), keyBlob.key_material_size);
+    free(const_cast<uint8_t*>(keyBlob.key_material));
+    return true;
+}
+
+bool Keymaster::deleteKey(const std::string& key) {
+    keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
+    auto error = mDevice->delete_key(&keyBlob);
+    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& inParams,
+                                    keymaster::AuthorizationSet* outParams) {
+    keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
+    keymaster_operation_handle_t mOpHandle;
+    keymaster_key_param_set_t outParams_set;
+    auto error = mDevice->begin(purpose, &keyBlob, &inParams, &outParams_set, &mOpHandle);
+    if (error != KM_ERROR_OK) {
+        LOG(ERROR) << "begin failed, code " << error;
+        return KeymasterOperation(nullptr, mOpHandle);
+    }
+    outParams->Clear();
+    outParams->push_back(outParams_set);
+    keymaster_free_param_set(&outParams_set);
+    return KeymasterOperation(mDevice, mOpHandle);
+}
+
+KeymasterOperation Keymaster::begin(keymaster_purpose_t purpose, const std::string& key,
+                                    const keymaster::AuthorizationSet& inParams) {
+    keymaster_key_blob_t keyBlob{reinterpret_cast<const uint8_t*>(key.data()), key.size()};
+    keymaster_operation_handle_t mOpHandle;
+    auto error = mDevice->begin(purpose, &keyBlob, &inParams, nullptr, &mOpHandle);
+    if (error != KM_ERROR_OK) {
+        LOG(ERROR) << "begin failed, code " << error;
+        return KeymasterOperation(nullptr, mOpHandle);
+    }
+    return KeymasterOperation(mDevice, mOpHandle);
+}
+
+}  // namespace vold
+}  // namespace android
diff --git a/Keymaster.h b/Keymaster.h
new file mode 100644
index 0000000..412110c
--- /dev/null
+++ b/Keymaster.h
@@ -0,0 +1,110 @@
+/*
+ * 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_KEYMASTER_H
+#define ANDROID_VOLD_KEYMASTER_H
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include <keymaster/authorization_set.h>
+
+namespace android {
+namespace vold {
+
+using namespace keymaster;
+
+// C++ wrappers to the Keymaster C interface.
+// This is tailored to the needs of KeyStorage, but could be extended to be
+// a more general interface.
+
+// Class that wraps a keymaster1_device_t or keymaster2_device_t and provides methods
+// they have in common. Also closes the device on destruction.
+class IKeymasterDevice;
+
+// 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();
+    // Is this instance valid? This is false if creation fails, and becomes
+    // false on finish or if an update fails.
+    explicit operator bool() { return mDevice != 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) {
+        mOpHandle = std::move(rhs.mOpHandle);
+        mDevice = std::move(rhs.mDevice);
+    }
+
+  private:
+    KeymasterOperation(std::shared_ptr<IKeymasterDevice> d, keymaster_operation_handle_t h)
+        : mDevice{d}, mOpHandle{h} {}
+    std::shared_ptr<IKeymasterDevice> mDevice;
+    keymaster_operation_handle_t mOpHandle;
+    DISALLOW_COPY_AND_ASSIGN(KeymasterOperation);
+    friend class Keymaster;
+};
+
+// Wrapper for a Keymaster device for methods that start a KeymasterOperation or are not
+// part of one.
+class Keymaster {
+  public:
+    Keymaster();
+    // false if we failed to open the keymaster device.
+    explicit operator bool() { return mDevice != nullptr; }
+    // Generate a key in the keymaster from the given params.
+    bool generateKey(const AuthorizationSet& inParams, 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& inParams, AuthorizationSet* outParams);
+    // Begin a new cryptographic operation; don't collect output parameters.
+    KeymasterOperation begin(keymaster_purpose_t purpose, const std::string& key,
+                             const AuthorizationSet& inParams);
+
+  private:
+    std::shared_ptr<IKeymasterDevice> mDevice;
+    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());
+}
+
+template <keymaster_tag_t Tag>
+inline void addStringParam(AuthorizationSetBuilder* params, TypedTag<KM_BYTES, Tag> tag,
+                           const std::string& val) {
+    params->Authorization(tag, val.data(), val.size());
+}
+
+}  // namespace vold
+}  // namespace android
+
+#endif
diff --git a/PrivateVolume.cpp b/PrivateVolume.cpp
index a106481..21746b2 100644
--- a/PrivateVolume.cpp
+++ b/PrivateVolume.cpp
@@ -158,6 +158,7 @@
     // Verify that common directories are ready to roll
     if (PrepareDir(mPath + "/app", 0771, AID_SYSTEM, AID_SYSTEM) ||
             PrepareDir(mPath + "/user", 0711, AID_SYSTEM, AID_SYSTEM) ||
+            PrepareDir(mPath + "/user_de", 0711, AID_SYSTEM, AID_SYSTEM) ||
             PrepareDir(mPath + "/media", 0770, AID_MEDIA_RW, AID_MEDIA_RW) ||
             PrepareDir(mPath + "/media/0", 0770, AID_MEDIA_RW, AID_MEDIA_RW) ||
             PrepareDir(mPath + "/local", 0751, AID_ROOT, AID_ROOT) ||
diff --git a/PublicVolume.cpp b/PublicVolume.cpp
index 8580da9..893f928 100644
--- a/PublicVolume.cpp
+++ b/PublicVolume.cpp
@@ -194,11 +194,11 @@
 }
 
 status_t PublicVolume::doUnmount() {
-    if (mFusePid > 0) {
-        kill(mFusePid, SIGTERM);
-        TEMP_FAILURE_RETRY(waitpid(mFusePid, nullptr, 0));
-        mFusePid = 0;
-    }
+    // Unmount the storage before we kill the FUSE process. If we kill
+    // the FUSE process first, most file system operations will return
+    // ENOTCONN until the unmount completes. This is an exotic and unusual
+    // error code and might cause broken behaviour in applications.
+    KillProcessesUsingPath(getPath());
 
     ForceUnmount(kAsecPath);
 
@@ -207,6 +207,12 @@
     ForceUnmount(mFuseWrite);
     ForceUnmount(mRawPath);
 
+    if (mFusePid > 0) {
+        kill(mFusePid, SIGTERM);
+        TEMP_FAILURE_RETRY(waitpid(mFusePid, nullptr, 0));
+        mFusePid = 0;
+    }
+
     rmdir(mFuseDefault.c_str());
     rmdir(mFuseRead.c_str());
     rmdir(mFuseWrite.c_str());
diff --git a/ScryptParameters.cpp b/ScryptParameters.cpp
new file mode 100644
index 0000000..669809b
--- /dev/null
+++ b/ScryptParameters.cpp
@@ -0,0 +1,50 @@
+/*
+ * 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 "ScryptParameters.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+bool parse_scrypt_parameters(const char* paramstr, int *Nf, int *rf, int *pf) {
+    int params[3];
+    char *token;
+    char *saveptr;
+    int i;
+
+    /*
+     * The token we're looking for should be three integers separated by
+     * colons (e.g., "12:8:1"). Scan the property to make sure it matches.
+     */
+    for (i = 0, token = strtok_r(const_cast<char *>(paramstr), ":", &saveptr);
+            token != nullptr && i < 3;
+            i++, token = strtok_r(nullptr, ":", &saveptr)) {
+        char *endptr;
+        params[i] = strtol(token, &endptr, 10);
+
+        /*
+         * Check that there was a valid number and it's 8-bit.
+         */
+        if ((*token == '\0') || (*endptr != '\0') || params[i] < 0 || params[i] > 255) {
+            return false;
+        }
+    }
+    if (token != nullptr) {
+        return false;
+    }
+    *Nf = params[0]; *rf = params[1]; *pf = params[2];
+    return true;
+}
diff --git a/ScryptParameters.h b/ScryptParameters.h
new file mode 100644
index 0000000..1b43ea5
--- /dev/null
+++ b/ScryptParameters.h
@@ -0,0 +1,32 @@
+/*
+ * 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_SCRYPT_PARAMETERS_H
+#define ANDROID_VOLD_SCRYPT_PARAMETERS_H
+
+#include <stdbool.h>
+#include <sys/cdefs.h>
+
+#define SCRYPT_PROP "ro.crypto.scrypt_params"
+#define SCRYPT_DEFAULTS "15:3:1"
+
+__BEGIN_DECLS
+
+bool parse_scrypt_parameters(const char* paramstr, int *Nf, int *rf, int *pf);
+
+__END_DECLS
+
+#endif
diff --git a/Utils.cpp b/Utils.cpp
index a9bddfa..c287797 100644
--- a/Utils.cpp
+++ b/Utils.cpp
@@ -547,10 +547,89 @@
     return res;
 }
 
+static bool isValidFilename(const std::string& name) {
+    if (name.empty() || (name == ".") || (name == "..")
+            || (name.find('/') != std::string::npos)) {
+        return false;
+    } else {
+        return true;
+    }
+}
+
 std::string BuildKeyPath(const std::string& partGuid) {
     return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str());
 }
 
+std::string BuildDataSystemLegacyPath(userid_t userId) {
+    return StringPrintf("%s/system/users/%u", BuildDataPath(nullptr).c_str(), userId);
+}
+
+std::string BuildDataSystemCePath(userid_t userId) {
+    return StringPrintf("%s/system_ce/%u", BuildDataPath(nullptr).c_str(), userId);
+}
+
+std::string BuildDataSystemDePath(userid_t userId) {
+    return StringPrintf("%s/system_de/%u", BuildDataPath(nullptr).c_str(), userId);
+}
+
+std::string BuildDataMiscLegacyPath(userid_t userId) {
+    return StringPrintf("%s/misc/user/%u", BuildDataPath(nullptr).c_str(), userId);
+}
+
+std::string BuildDataMiscCePath(userid_t userId) {
+    return StringPrintf("%s/misc_ce/%u", BuildDataPath(nullptr).c_str(), userId);
+}
+
+std::string BuildDataMiscDePath(userid_t userId) {
+    return StringPrintf("%s/misc_de/%u", BuildDataPath(nullptr).c_str(), userId);
+}
+
+// Keep in sync with installd (frameworks/native/cmds/installd/utils.h)
+std::string BuildDataProfilesDePath(userid_t userId) {
+    return StringPrintf("%s/misc/profiles/cur/%u", BuildDataPath(nullptr).c_str(), userId);
+}
+
+std::string BuildDataProfilesForeignDexDePath(userid_t userId) {
+    std::string profiles_path = BuildDataProfilesDePath(userId);
+    return StringPrintf("%s/foreign-dex", profiles_path.c_str());
+}
+
+std::string BuildDataPath(const char* volumeUuid) {
+    // TODO: unify with installd path generation logic
+    if (volumeUuid == nullptr) {
+        return "/data";
+    } else {
+        CHECK(isValidFilename(volumeUuid));
+        return StringPrintf("/mnt/expand/%s", volumeUuid);
+    }
+}
+
+std::string BuildDataMediaCePath(const char* volumeUuid, userid_t userId) {
+    // TODO: unify with installd path generation logic
+    std::string data(BuildDataPath(volumeUuid));
+    return StringPrintf("%s/media/%u", data.c_str(), userId);
+}
+
+std::string BuildDataUserCePath(const char* volumeUuid, userid_t userId) {
+    // TODO: unify with installd path generation logic
+    std::string data(BuildDataPath(volumeUuid));
+    if (volumeUuid == nullptr) {
+        if (userId == 0) {
+            return StringPrintf("%s/data", data.c_str());
+        } else {
+            return StringPrintf("%s/user/%u", data.c_str(), userId);
+        }
+    } else {
+        return StringPrintf("%s/user/%u", data.c_str(), userId);
+    }
+}
+
+std::string BuildDataUserDePath(const char* volumeUuid, userid_t userId) {
+    // TODO: unify with installd path generation logic
+    std::string data(BuildDataPath(volumeUuid));
+    return StringPrintf("%s/user_de/%u", data.c_str(), userId);
+}
+
 dev_t GetDevice(const std::string& path) {
     struct stat sb;
     if (stat(path.c_str(), &sb)) {
@@ -567,5 +646,35 @@
     return StringPrintf("/fstab.%s", hardware);
 }
 
+status_t SaneReadLinkAt(int dirfd, const char* path, char* buf, size_t bufsiz) {
+    ssize_t len = readlinkat(dirfd, path, buf, bufsiz);
+    if (len < 0) {
+        return -1;
+    } else if (len == (ssize_t) bufsiz) {
+        return -1;
+    } else {
+        buf[len] = '\0';
+        return 0;
+    }
+}
+
+ScopedFd::ScopedFd(int fd) : fd_(fd) {}
+
+ScopedFd::~ScopedFd() {
+    close(fd_);
+}
+
+ScopedDir::ScopedDir(DIR* dir) : dir_(dir) {}
+
+ScopedDir::~ScopedDir() {
+    if (dir_ != nullptr) {
+        closedir(dir_);
+    }
+}
+
+bool IsRunningInEmulator() {
+    return property_get_bool("ro.kernel.qemu", 0);
+}
+
 }  // namespace vold
 }  // namespace android
diff --git a/Utils.h b/Utils.h
index 228727a..9abd322 100644
--- a/Utils.h
+++ b/Utils.h
@@ -18,6 +18,7 @@
 #define ANDROID_VOLD_UTILS_H
 
 #include <utils/Errors.h>
+#include <cutils/multiuser.h>
 #include <selinux/selinux.h>
 
 #include <vector>
@@ -31,6 +32,8 @@
     void operator=(const TypeName&) = delete
 #endif
 
+struct DIR;
+
 namespace android {
 namespace vold {
 
@@ -93,10 +96,49 @@
 
 std::string BuildKeyPath(const std::string& partGuid);
 
+std::string BuildDataSystemLegacyPath(userid_t userid);
+std::string BuildDataSystemCePath(userid_t userid);
+std::string BuildDataSystemDePath(userid_t userid);
+std::string BuildDataMiscLegacyPath(userid_t userid);
+std::string BuildDataMiscCePath(userid_t userid);
+std::string BuildDataMiscDePath(userid_t userid);
+std::string BuildDataProfilesDePath(userid_t userid);
+std::string BuildDataProfilesForeignDexDePath(userid_t userid);
+
+std::string BuildDataPath(const char* volumeUuid);
+std::string BuildDataMediaCePath(const char* volumeUuid, userid_t userid);
+std::string BuildDataUserCePath(const char* volumeUuid, userid_t userid);
+std::string BuildDataUserDePath(const char* volumeUuid, userid_t userid);
+
 dev_t GetDevice(const std::string& path);
 
 std::string DefaultFstabPath();
 
+status_t SaneReadLinkAt(int dirfd, const char* path, char* buf, size_t bufsiz);
+
+class ScopedFd {
+    const int fd_;
+public:
+    ScopedFd(int fd);
+    ~ScopedFd();
+    int get() const { return fd_; }
+
+    DISALLOW_COPY_AND_ASSIGN(ScopedFd);
+};
+
+class ScopedDir {
+    DIR* const dir_;
+public:
+    ScopedDir(DIR* dir);
+    ~ScopedDir();
+    DIR* get() const { return dir_; }
+
+    DISALLOW_COPY_AND_ASSIGN(ScopedDir);
+};
+
+/* Checks if Android is running in QEMU */
+bool IsRunningInEmulator();
+
 }  // namespace vold
 }  // namespace android
 
diff --git a/VolumeManager.cpp b/VolumeManager.cpp
old mode 100755
new mode 100644
index 57b8753..e1ee96c
--- a/VolumeManager.cpp
+++ b/VolumeManager.cpp
@@ -91,6 +91,8 @@
 static const char* kUserMountPath = "/mnt/user";
 
 static const unsigned int kMajorBlockMmc = 179;
+static const unsigned int kMajorBlockExperimentalMin = 240;
+static const unsigned int kMajorBlockExperimentalMax = 254;
 
 /* writes superblock at end of file or device given by name */
 static int writeSuperBlock(const char* name, struct asec_superblock *sb, unsigned int numImgSectors) {
@@ -296,10 +298,14 @@
     case NetlinkEvent::Action::kAdd: {
         for (auto source : mDiskSources) {
             if (source->matches(eventPath)) {
-                // For now, assume that MMC devices are SD, and that
-                // everything else is USB
+                // For now, assume that MMC and virtio-blk (the latter is
+                // emulator-specific; see Disk.cpp for details) devices are SD,
+                // and that everything else is USB
                 int flags = source->getFlags();
-                if (major == kMajorBlockMmc) {
+                if (major == kMajorBlockMmc
+                    || (android::vold::IsRunningInEmulator()
+                    && major >= (int) kMajorBlockExperimentalMin
+                    && major <= (int) kMajorBlockExperimentalMax)) {
                     flags |= android::vold::Disk::Flags::kSd;
                 } else {
                     flags |= android::vold::Disk::Flags::kUsb;
@@ -471,18 +477,6 @@
     return 0;
 }
 
-static int sane_readlinkat(int dirfd, const char* path, char* buf, size_t bufsiz) {
-    ssize_t len = readlinkat(dirfd, path, buf, bufsiz);
-    if (len < 0) {
-        return -1;
-    } else if (len == (ssize_t) bufsiz) {
-        return -1;
-    } else {
-        buf[len] = '\0';
-        return 0;
-    }
-}
-
 static int unmount_tree(const char* path) {
     size_t path_len = strlen(path);
 
@@ -529,7 +523,7 @@
     }
 
     // Figure out root namespace to compare against below
-    if (sane_readlinkat(dirfd(dir), "1/ns/mnt", rootName, PATH_MAX) == -1) {
+    if (android::vold::SaneReadLinkAt(dirfd(dir), "1/ns/mnt", rootName, PATH_MAX) == -1) {
         PLOG(ERROR) << "Failed to readlink";
         closedir(dir);
         return -1;
@@ -554,7 +548,7 @@
 
         // Matches so far, but refuse to touch if in root namespace
         LOG(DEBUG) << "Found matching PID " << de->d_name;
-        if (sane_readlinkat(pidFd, "ns/mnt", pidName, PATH_MAX) == -1) {
+        if (android::vold::SaneReadLinkAt(pidFd, "ns/mnt", pidName, PATH_MAX) == -1) {
             PLOG(WARNING) << "Failed to read namespace for " << de->d_name;
             goto next;
         }
diff --git a/cryptfs.c b/cryptfs.c
index 7ca05b0..eb9a8ed 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -52,16 +52,17 @@
 #include "cutils/android_reboot.h"
 #include "hardware_legacy/power.h"
 #include <logwrap/logwrap.h>
+#include "ScryptParameters.h"
 #include "VolumeManager.h"
 #include "VoldUtil.h"
 #include "crypto_scrypt.h"
 #include "Ext4Crypt.h"
-#include "ext4_crypt_init_extensions.h"
 #include "ext4_utils.h"
 #include "f2fs_sparseblock.h"
 #include "CheckBattery.h"
 #include "Process.h"
 
+#include <bootloader_message_writer.h>
 #include <hardware/keymaster0.h>
 #include <hardware/keymaster1.h>
 
@@ -83,6 +84,10 @@
 
 #define DEFAULT_PASSWORD "default_password"
 
+#define CRYPTO_BLOCK_DEVICE "userdata"
+
+#define BREADCRUMB_FILE "/data/misc/vold/convert_fde"
+
 #define EXT4_FS 1
 #define F2FS_FS 2
 
@@ -160,6 +165,11 @@
         goto out;
     }
 
+    if (!keymaster0_dev || !keymaster0_dev->common.module) {
+        rc = -1;
+        goto out;
+    }
+
     // TODO(swillden): Check to see if there's any reason to require v0.3.  I think v0.1 and v0.2
     // should work.
     if (keymaster0_dev->common.module->module_api_version
@@ -190,6 +200,11 @@
     keymaster0_device_t *keymaster0_dev = 0;
     keymaster1_device_t *keymaster1_dev = 0;
 
+    if (ftr->keymaster_blob_size) {
+        SLOGI("Already have key");
+        return 0;
+    }
+
     if (keymaster_init(&keymaster0_dev, &keymaster1_dev)) {
         SLOGE("Failed to init keymaster");
         return -1;
@@ -467,48 +482,17 @@
  * given device.
  */
 static void get_device_scrypt_params(struct crypt_mnt_ftr *ftr) {
-    const int default_params[] = SCRYPT_DEFAULTS;
-    int params[] = SCRYPT_DEFAULTS;
     char paramstr[PROPERTY_VALUE_MAX];
-    char *token;
-    char *saveptr;
-    int i;
+    int Nf, rf, pf;
 
-    property_get(SCRYPT_PROP, paramstr, "");
-    if (paramstr[0] != '\0') {
-        /*
-         * The token we're looking for should be three integers separated by
-         * colons (e.g., "12:8:1"). Scan the property to make sure it matches.
-         */
-        for (i = 0, token = strtok_r(paramstr, ":", &saveptr);
-                token != NULL && i < 3;
-                i++, token = strtok_r(NULL, ":", &saveptr)) {
-            char *endptr;
-            params[i] = strtol(token, &endptr, 10);
-
-            /*
-             * Check that there was a valid number and it's 8-bit. If not,
-             * break out and the end check will take the default values.
-             */
-            if ((*token == '\0') || (*endptr != '\0') || params[i] < 0 || params[i] > 255) {
-                break;
-            }
-        }
-
-        /*
-         * If there were not enough tokens or a token was malformed (not an
-         * integer), it will end up here and the default parameters can be
-         * taken.
-         */
-        if ((i != 3) || (token != NULL)) {
-            SLOGW("bad scrypt parameters '%s' should be like '12:8:1'; using defaults", paramstr);
-            memcpy(params, default_params, sizeof(params));
-        }
+    property_get(SCRYPT_PROP, paramstr, SCRYPT_DEFAULTS);
+    if (!parse_scrypt_parameters(paramstr, &Nf, &rf, &pf)) {
+        SLOGW("bad scrypt parameters '%s' should be like '12:8:1'; using defaults", paramstr);
+        parse_scrypt_parameters(SCRYPT_DEFAULTS, &Nf, &rf, &pf);
     }
-
-    ftr->N_factor = params[0];
-    ftr->r_factor = params[1];
-    ftr->p_factor = params[2];
+    ftr->N_factor = Nf;
+    ftr->r_factor = rf;
+    ftr->p_factor = pf;
 }
 
 static unsigned int get_fs_size(char *dev)
@@ -599,6 +583,16 @@
   return rc;
 }
 
+/* Set sha256 checksum in structure */
+static void set_ftr_sha(struct crypt_mnt_ftr *crypt_ftr)
+{
+    SHA256_CTX c;
+    SHA256_Init(&c);
+    memset(crypt_ftr->sha256, 0, sizeof(crypt_ftr->sha256));
+    SHA256_Update(&c, crypt_ftr, sizeof(*crypt_ftr));
+    SHA256_Final(crypt_ftr->sha256, &c);
+}
+
 /* key or salt can be NULL, in which case just skip writing that value.  Useful to
  * update the failed mount count but not change the key.
  */
@@ -614,6 +608,8 @@
   char *fname = NULL;
   struct stat statbuf;
 
+  set_ftr_sha(crypt_ftr);
+
   if (get_crypt_ftr_info(&fname, &starting_off)) {
     SLOGE("Unable to get crypt_ftr_info\n");
     return -1;
@@ -656,6 +652,14 @@
 
 }
 
+static bool check_ftr_sha(const struct crypt_mnt_ftr *crypt_ftr)
+{
+    struct crypt_mnt_ftr copy;
+    memcpy(&copy, crypt_ftr, sizeof(copy));
+    set_ftr_sha(&copy);
+    return memcmp(copy.sha256, crypt_ftr->sha256, sizeof(copy.sha256)) == 0;
+}
+
 static inline int unix_read(int  fd, void*  buff, int  len)
 {
     return TEMP_FAILURE_RETRY(read(fd, buff, len));
@@ -891,12 +895,10 @@
         return -1;
     }
 
-    if (persist_data == NULL) {
-        pdata = malloc(crypt_ftr.persist_data_size);
-        if (pdata == NULL) {
-            SLOGE("Cannot allocate memory for persistent data");
-            goto err;
-        }
+    pdata = malloc(crypt_ftr.persist_data_size);
+    if (pdata == NULL) {
+        SLOGE("Cannot allocate memory for persistent data");
+        goto err;
     }
 
     for (i = 0; i < 2; i++) {
@@ -1156,6 +1158,7 @@
   struct dm_ioctl *io;
   unsigned int minor;
   int fd=0;
+  int err;
   int retval = -1;
   int version[3];
   char *extra_params;
@@ -1169,8 +1172,9 @@
   io = (struct dm_ioctl *) buffer;
 
   ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
-  if (ioctl(fd, DM_DEV_CREATE, io)) {
-    SLOGE("Cannot create dm-crypt device\n");
+  err = ioctl(fd, DM_DEV_CREATE, io);
+  if (err) {
+    SLOGE("Cannot create dm-crypt device %s: %s\n", name, strerror(errno));
     goto errout;
   }
 
@@ -1553,6 +1557,9 @@
 {
     int i;
 
+    // NOTE: post_fs_data results in init calling back around to vold, so all
+    // callers to this method must be async
+
     /* Do the prep of the /data filesystem */
     property_set("vold.post_fs_data_done", "0");
     property_set("vold.decrypt", "trigger_post_fs_data");
@@ -1750,29 +1757,9 @@
 int cryptfs_restart(void)
 {
     SLOGI("cryptfs_restart");
-    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
-        struct fstab_rec* rec;
-        int rc;
-
-        if (e4crypt_restart(DATA_MNT_POINT)) {
-            SLOGE("Can't unmount e4crypt temp volume\n");
-            return -1;
-        }
-
-        rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT);
-        if (!rec) {
-            SLOGE("Can't get fstab record for %s\n", DATA_MNT_POINT);
-            return -1;
-        }
-
-        rc = fs_mgr_do_mount(fstab, DATA_MNT_POINT, rec->blk_device, 0);
-        if (rc) {
-            SLOGE("Can't mount %s\n", DATA_MNT_POINT);
-            return rc;
-        }
-
-        property_set("vold.decrypt", "trigger_restart_framework");
-        return 0;
+    if (e4crypt_is_native()) {
+        SLOGE("cryptfs_restart not valid for file encryption:");
+        return -1;
     }
 
     /* Call internal implementation forcing a restart of main service group */
@@ -1791,8 +1778,9 @@
     return CRYPTO_COMPLETE_NOT_ENCRYPTED;
   }
 
-  if (e4crypt_crypto_complete(mount_point) == 0) {
-    return CRYPTO_COMPLETE_ENCRYPTED;
+  // crypto_complete is full disk encrypted status
+  if (e4crypt_is_native()) {
+    return CRYPTO_COMPLETE_NOT_ENCRYPTED;
   }
 
   if (get_crypt_ftr_and_key(&crypt_ftr)) {
@@ -2044,21 +2032,50 @@
 int cryptfs_check_passwd(char *passwd)
 {
     SLOGI("cryptfs_check_passwd");
-    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
-        return e4crypt_check_passwd(DATA_MNT_POINT, passwd);
+    if (e4crypt_is_native()) {
+        SLOGE("cryptfs_check_passwd not valid for file encryption");
+        return -1;
     }
 
     struct crypt_mnt_ftr crypt_ftr;
     int rc;
 
     rc = check_unmounted_and_get_ftr(&crypt_ftr);
-    if (rc)
+    if (rc) {
+        SLOGE("Could not get footer");
         return rc;
+    }
 
     rc = test_mount_encrypted_fs(&crypt_ftr, passwd,
-                                 DATA_MNT_POINT, "userdata");
+                                 DATA_MNT_POINT, CRYPTO_BLOCK_DEVICE);
+    if (rc) {
+        SLOGE("Password did not match");
+        return rc;
+    }
 
-    if (rc == 0 && crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) {
+    if (crypt_ftr.flags & CRYPT_FORCE_COMPLETE) {
+        // Here we have a default actual password but a real password
+        // we must test against the scrypted value
+        // First, we must delete the crypto block device that
+        // test_mount_encrypted_fs leaves behind as a side effect
+        delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE);
+        rc = test_mount_encrypted_fs(&crypt_ftr, DEFAULT_PASSWORD,
+                                     DATA_MNT_POINT, CRYPTO_BLOCK_DEVICE);
+        if (rc) {
+            SLOGE("Default password did not match on reboot encryption");
+            return rc;
+        }
+
+        crypt_ftr.flags &= ~CRYPT_FORCE_COMPLETE;
+        put_crypt_ftr_and_key(&crypt_ftr);
+        rc = cryptfs_changepw(crypt_ftr.crypt_type, passwd);
+        if (rc) {
+            SLOGE("Could not change password on reboot encryption");
+            return rc;
+        }
+    }
+
+    if (crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) {
         cryptfs_clear_password();
         password = strdup(passwd);
         struct timespec now;
@@ -2931,6 +2948,7 @@
     char key_loc[PROPERTY_VALUE_MAX];
     int num_vols;
     off64_t previously_encrypted_upto = 0;
+    bool rebootEncryption = false;
 
     if (!strcmp(howarg, "wipe")) {
       how = CRYPTO_ENABLE_WIPE;
@@ -2941,21 +2959,33 @@
       goto error_unencrypted;
     }
 
-    /* See if an encryption was underway and interrupted */
     if (how == CRYPTO_ENABLE_INPLACE
-          && get_crypt_ftr_and_key(&crypt_ftr) == 0
-          && (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS)) {
-        previously_encrypted_upto = crypt_ftr.encrypted_upto;
-        crypt_ftr.encrypted_upto = 0;
-        crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS;
+          && get_crypt_ftr_and_key(&crypt_ftr) == 0) {
+        if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) {
+            /* An encryption was underway and was interrupted */
+            previously_encrypted_upto = crypt_ftr.encrypted_upto;
+            crypt_ftr.encrypted_upto = 0;
+            crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS;
 
-        /* At this point, we are in an inconsistent state. Until we successfully
-           complete encryption, a reboot will leave us broken. So mark the
-           encryption failed in case that happens.
-           On successfully completing encryption, remove this flag */
-        crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
+            /* At this point, we are in an inconsistent state. Until we successfully
+               complete encryption, a reboot will leave us broken. So mark the
+               encryption failed in case that happens.
+               On successfully completing encryption, remove this flag */
+            crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
 
-        put_crypt_ftr_and_key(&crypt_ftr);
+            put_crypt_ftr_and_key(&crypt_ftr);
+        } else if (crypt_ftr.flags & CRYPT_FORCE_ENCRYPTION) {
+            if (!check_ftr_sha(&crypt_ftr)) {
+                memset(&crypt_ftr, 0, sizeof(crypt_ftr));
+                put_crypt_ftr_and_key(&crypt_ftr);
+                goto error_unencrypted;
+            }
+
+            /* Doing a reboot-encryption*/
+            crypt_ftr.flags &= ~CRYPT_FORCE_ENCRYPTION;
+            crypt_ftr.flags |= CRYPT_FORCE_COMPLETE;
+            rebootEncryption = true;
+        }
     }
 
     property_get("ro.crypto.state", encrypted_state, "");
@@ -3015,13 +3045,23 @@
         SLOGE("Failed to unmount all vold managed devices");
     }
 
-    /* Now unmount the /data partition. */
-    if (wait_and_unmount(DATA_MNT_POINT, false)) {
-        goto error_unencrypted;
+    /* no_ui means we are being called from init, not settings.
+       Now we always reboot from settings, so !no_ui means reboot
+     */
+    bool onlyCreateHeader = false;
+    if (!no_ui) {
+        /* Try fallback, which is to reboot and try there */
+        onlyCreateHeader = true;
+        FILE* breadcrumb = fopen(BREADCRUMB_FILE, "we");
+        if (breadcrumb == 0) {
+            SLOGE("Failed to create breadcrumb file");
+            goto error_shutting_down;
+        }
+        fclose(breadcrumb);
     }
 
     /* Do extra work for a better UX when doing the long inplace encryption */
-    if (how == CRYPTO_ENABLE_INPLACE) {
+    if (how == CRYPTO_ENABLE_INPLACE && !onlyCreateHeader) {
         /* Now that /data is unmounted, we need to mount a tmpfs
          * /data, set a property saying we're doing inplace encryption,
          * and restart the framework.
@@ -3048,7 +3088,7 @@
 
     /* Start the actual work of making an encrypted filesystem */
     /* Initialize a crypt_mnt_ftr for the partition */
-    if (previously_encrypted_upto == 0) {
+    if (previously_encrypted_upto == 0 && !rebootEncryption) {
         if (cryptfs_init_crypt_mnt_ftr(&crypt_ftr)) {
             goto error_shutting_down;
         }
@@ -3063,7 +3103,11 @@
            complete encryption, a reboot will leave us broken. So mark the
            encryption failed in case that happens.
            On successfully completing encryption, remove this flag */
-        crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
+        if (onlyCreateHeader) {
+            crypt_ftr.flags |= CRYPT_FORCE_ENCRYPTION;
+        } else {
+            crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
+        }
         crypt_ftr.crypt_type = crypt_type;
 #ifndef CONFIG_HW_DISK_ENCRYPTION
         strlcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256", MAX_CRYPTO_TYPE_NAME_LEN);
@@ -3084,11 +3128,21 @@
 #endif
 
         /* Make an encrypted master key */
-        if (create_encrypted_random_key(passwd, crypt_ftr.master_key, crypt_ftr.salt, &crypt_ftr)) {
+        if (create_encrypted_random_key(onlyCreateHeader ? DEFAULT_PASSWORD : passwd,
+                                        crypt_ftr.master_key, crypt_ftr.salt, &crypt_ftr)) {
             SLOGE("Cannot create encrypted master key\n");
             goto error_shutting_down;
         }
 
+        /* Replace scrypted intermediate key if we are preparing for a reboot */
+        if (onlyCreateHeader) {
+            unsigned char fake_master_key[KEY_LEN_BYTES];
+            unsigned char encrypted_fake_master_key[KEY_LEN_BYTES];
+            memset(fake_master_key, 0, sizeof(fake_master_key));
+            encrypt_master_key(passwd, crypt_ftr.salt, fake_master_key,
+                               encrypted_fake_master_key, &crypt_ftr);
+        }
+
         /* Write the key to the end of the partition */
         put_crypt_ftr_and_key(&crypt_ftr);
 
@@ -3107,7 +3161,12 @@
         }
     }
 
-    if (how == CRYPTO_ENABLE_INPLACE && !no_ui) {
+    if (onlyCreateHeader) {
+        sleep(2);
+        cryptfs_reboot(reboot);
+    }
+
+    if (how == CRYPTO_ENABLE_INPLACE && (!no_ui || rebootEncryption)) {
         /* startup service classes main and late_start */
         property_set("vold.decrypt", "trigger_restart_min_framework");
         SLOGD("Just triggered restart_min_framework\n");
@@ -3121,7 +3180,7 @@
 
     decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
     create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev,
-                          "userdata");
+                          CRYPTO_BLOCK_DEVICE);
 
     /* If we are continuing, check checksums match */
     rc = 0;
@@ -3154,7 +3213,7 @@
     }
 
     /* Undo the dm-crypt mapping whether we succeed or not */
-    delete_crypto_blk_dev("userdata");
+    delete_crypto_blk_dev(CRYPTO_BLOCK_DEVICE);
 
     if (! rc) {
         /* Success */
@@ -3176,9 +3235,18 @@
           if (!strcmp(value, "")) {
             /* default encryption - continue first boot sequence */
             property_set("ro.crypto.state", "encrypted");
+            property_set("ro.crypto.type", "block");
             release_wake_lock(lockid);
-            cryptfs_check_passwd(DEFAULT_PASSWORD);
-            cryptfs_restart_internal(1);
+            if (rebootEncryption && crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) {
+                // Bring up cryptkeeper that will check the password and set it
+                property_set("vold.decrypt", "trigger_shutdown_framework");
+                sleep(2);
+                property_set("vold.encrypt_progress", "");
+                cryptfs_trigger_restart_min_framework();
+            } else {
+                cryptfs_check_passwd(DEFAULT_PASSWORD);
+                cryptfs_restart_internal(1);
+            }
             return 0;
           } else {
             sleep(2); /* Give the UI a chance to show 100% progress */
@@ -3195,14 +3263,8 @@
         if (!strcmp(value, "1")) {
             /* wipe data if encryption failed */
             SLOGE("encryption failed - rebooting into recovery to wipe data\n");
-            mkdir("/cache/recovery", 0700);
-            int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC|O_CLOEXEC, 0600);
-            if (fd >= 0) {
-                write(fd, "--wipe_data\n", strlen("--wipe_data\n") + 1);
-                write(fd, "--reason=cryptfs_enable_internal\n", strlen("--reason=cryptfs_enable_internal\n") + 1);
-                close(fd);
-            } else {
-                SLOGE("could not open /cache/recovery/command\n");
+            if (!write_bootloader_message("--wipe_data\n--reason=cryptfs_enable_internal\n")) {
+                SLOGE("could not write bootloader message\n");
             }
             cryptfs_reboot(recovery);
         } else {
@@ -3257,10 +3319,9 @@
 
 int cryptfs_changepw(int crypt_type, const char *newpw)
 {
-    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
-        return e4crypt_change_password(DATA_MNT_POINT, crypt_type,
-                    crypt_type == CRYPT_TYPE_DEFAULT ? DEFAULT_PASSWORD
-                                                     : newpw);
+    if (e4crypt_is_native()) {
+        SLOGE("cryptfs_changepw not valid for file encryption");
+        return -1;
     }
 
     struct crypt_mnt_ftr crypt_ftr;
@@ -3484,8 +3545,9 @@
 /* Return the value of the specified field. */
 int cryptfs_getfield(const char *fieldname, char *value, int len)
 {
-    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
-        return e4crypt_get_field(DATA_MNT_POINT, fieldname, value, len);
+    if (e4crypt_is_native()) {
+        SLOGE("Cannot get field when file encrypted");
+        return -1;
     }
 
     char temp_value[PROPERTY_VALUE_MAX];
@@ -3549,8 +3611,9 @@
 /* Set the value of the specified field. */
 int cryptfs_setfield(const char *fieldname, const char *value)
 {
-    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
-        return e4crypt_set_field(DATA_MNT_POINT, fieldname, value);
+    if (e4crypt_is_native()) {
+        SLOGE("Cannot set field when file encrypted");
+        return -1;
     }
 
     char encrypted_state[PROPERTY_VALUE_MAX];
@@ -3642,26 +3705,20 @@
  */
 int cryptfs_mount_default_encrypted(void)
 {
-    char decrypt_state[PROPERTY_VALUE_MAX];
-    property_get("vold.decrypt", decrypt_state, "0");
-    if (!strcmp(decrypt_state, "0")) {
-        SLOGE("Not encrypted - should not call here");
+    int crypt_type = cryptfs_get_password_type();
+    if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
+        SLOGE("Bad crypt type - error");
+    } else if (crypt_type != CRYPT_TYPE_DEFAULT) {
+        SLOGD("Password is not default - "
+              "starting min framework to prompt");
+        property_set("vold.decrypt", "trigger_restart_min_framework");
+        return 0;
+    } else if (cryptfs_check_passwd(DEFAULT_PASSWORD) == 0) {
+        SLOGD("Password is default - restarting filesystem");
+        cryptfs_restart_internal(0);
+        return 0;
     } else {
-        int crypt_type = cryptfs_get_password_type();
-        if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
-            SLOGE("Bad crypt type - error");
-        } else if (crypt_type != CRYPT_TYPE_DEFAULT) {
-            SLOGD("Password is not default - "
-                  "starting min framework to prompt");
-            property_set("vold.decrypt", "trigger_restart_min_framework");
-            return 0;
-        } else if (cryptfs_check_passwd(DEFAULT_PASSWORD) == 0) {
-            SLOGD("Password is default - restarting filesystem");
-            cryptfs_restart_internal(0);
-            return 0;
-        } else {
-            SLOGE("Encrypted, default crypt type but can't decrypt");
-        }
+        SLOGE("Encrypted, default crypt type but can't decrypt");
     }
 
     /** Corrupt. Allow us to boot into framework, which will detect bad
@@ -3675,8 +3732,9 @@
  */
 int cryptfs_get_password_type(void)
 {
-    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
-        return e4crypt_get_password_type(DATA_MNT_POINT);
+    if (e4crypt_is_native()) {
+        SLOGE("cryptfs_get_password_type not valid for file encryption");
+        return -1;
     }
 
     struct crypt_mnt_ftr crypt_ftr;
@@ -3695,8 +3753,9 @@
 
 const char* cryptfs_get_password()
 {
-    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
-        return e4crypt_get_password(DATA_MNT_POINT);
+    if (e4crypt_is_native()) {
+        SLOGE("cryptfs_get_password not valid for file encryption");
+        return 0;
     }
 
     struct timespec now;
@@ -3711,10 +3770,6 @@
 
 void cryptfs_clear_password()
 {
-    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
-        e4crypt_clear_password(DATA_MNT_POINT);
-    }
-
     if (password) {
         size_t len = strlen(password);
         memset(password, 0, len);
@@ -3726,7 +3781,13 @@
 
 int cryptfs_enable_file()
 {
-    return e4crypt_enable(DATA_MNT_POINT);
+    return e4crypt_initialize_global_de();
+}
+
+int cryptfs_isConvertibleToFBE()
+{
+    struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT);
+    return fs_mgr_is_convertible_to_fbe(rec) ? 1 : 0;
 }
 
 int cryptfs_create_default_ftr(struct crypt_mnt_ftr* crypt_ftr, __attribute__((unused))int key_length)
@@ -3761,6 +3822,11 @@
     rc = decrypt_master_key(password, master_key, ftr, &intermediate_key,
                             &intermediate_key_size);
 
+    if (rc) {
+        SLOGE("Can't calculate intermediate key");
+        return rc;
+    }
+
     int N = 1 << ftr->N_factor;
     int r = 1 << ftr->r_factor;
     int p = 1 << ftr->p_factor;
@@ -3775,7 +3841,7 @@
     free(intermediate_key);
 
     if (rc) {
-        SLOGE("Can't calculate intermediate key");
+        SLOGE("Can't scrypt intermediate key");
         return rc;
     }
 
diff --git a/cryptfs.h b/cryptfs.h
index 3754018..c713067 100644
--- a/cryptfs.h
+++ b/cryptfs.h
@@ -52,6 +52,16 @@
                                         correctly marked partial encryption */
 #define CRYPT_DATA_CORRUPT 0x8 /* Set when encryption is fine, but the
                                   underlying volume is corrupt */
+#define CRYPT_FORCE_ENCRYPTION 0x10 /* Set when it is time to encrypt this
+                                       volume on boot. Everything in this
+                                       structure is set up correctly as
+                                       though device is encrypted except
+                                       that the master key is encrypted with the
+                                       default password. */
+#define CRYPT_FORCE_COMPLETE 0x20 /* Set when the above encryption cycle is
+                                     complete. On next cryptkeeper entry, match
+                                     the password. If it matches fix the master
+                                     key and remove this flag. */
 
 /* Allowed values for type in the structure below */
 #define CRYPT_TYPE_PASSWORD 0 /* master_key is encrypted with a password
@@ -66,9 +76,6 @@
 #define CRYPT_MNT_MAGIC 0xD0B5B1C4
 #define PERSIST_DATA_MAGIC 0xE950CD44
 
-#define SCRYPT_PROP "ro.crypto.scrypt_params"
-#define SCRYPT_DEFAULTS { 15, 3, 1 }
-
 /* Key Derivation Function algorithms */
 #define KDF_PBKDF2 1
 #define KDF_SCRYPT 2
@@ -94,7 +101,7 @@
   __le32 keysize;       /* in bytes */
   __le32 crypt_type;    /* how master_key is encrypted. Must be a
                          * CRYPT_TYPE_XXX value */
-  __le64 fs_size;	/* Size of the encrypted fs, in 512 byte sectors */
+  __le64 fs_size;       /* Size of the encrypted fs, in 512 byte sectors */
   __le32 failed_decrypt_count; /* count of # of failed attempts to decrypt and
                                   mount, set to 0 on successful mount */
   unsigned char crypto_type_name[MAX_CRYPTO_TYPE_NAME_LEN]; /* The type of encryption
@@ -145,6 +152,12 @@
      then we will be OK.
    */
   unsigned char scrypted_intermediate_key[SCRYPT_LEN];
+
+  /* sha of this structure with this element set to zero
+     Used when encrypting on reboot to validate structure before doing something
+     fatal
+   */
+  unsigned char sha256[SHA256_DIGEST_LENGTH];
 };
 
 /* Persistant data that should be available before decryption.
@@ -231,6 +244,7 @@
   int cryptfs_get_password_type(void);
   const char* cryptfs_get_password(void);
   void cryptfs_clear_password(void);
+  int cryptfs_isConvertibleToFBE(void);
 
   // Functions for file encryption to use to inherit our encryption logic
   int cryptfs_create_default_ftr(struct crypt_mnt_ftr* ftr, int key_length);
@@ -238,6 +252,7 @@
                              unsigned char* master_key);
   int cryptfs_set_password(struct crypt_mnt_ftr* ftr, const char* password,
                            const unsigned char* master_key);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/fs/F2fs.cpp b/fs/F2fs.cpp
index 84d27c4..0d12b07 100644
--- a/fs/F2fs.cpp
+++ b/fs/F2fs.cpp
@@ -43,7 +43,7 @@
 status_t Check(const std::string& source) {
     std::vector<std::string> cmd;
     cmd.push_back(kFsckPath);
-    cmd.push_back("-f");
+    cmd.push_back("-a");
     cmd.push_back(source);
 
     // f2fs devices are currently always trusted
diff --git a/secdiscard.cpp b/secdiscard.cpp
index 3f4ab2e..5c12cdd 100644
--- a/secdiscard.cpp
+++ b/secdiscard.cpp
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
+#include <memory>
 #include <string>
+#include <vector>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -24,213 +26,184 @@
 #include <fcntl.h>
 #include <linux/fs.h>
 #include <linux/fiemap.h>
+#include <mntent.h>
 
-#define LOG_TAG "secdiscard"
-#include "cutils/log.h"
+#include <android-base/logging.h>
 
-// Deliberately limit ourselves to wiping small files.
-#define MAX_WIPE_LENGTH 4096
-#define INIT_BUFFER_SIZE 2048
+#include <AutoCloseFD.h>
 
-static void usage(char *progname);
-static void destroy_key(const std::string &path);
-static int file_device_range(const std::string &path, uint64_t range[2]);
-static int open_block_device_for_path(const std::string &path);
-static int read_file_as_string_atomically(const std::string &path, std::string &contents);
-static int find_block_device_for_path(
-    const std::string &mounts,
-    const std::string &path,
-    std::string &block_device);
+namespace {
 
-int main(int argc, char **argv) {
-    if (argc != 2 || argv[1][0] != '/') {
+struct Options {
+    std::vector<std::string> targets;
+    bool unlink{true};
+};
+
+constexpr uint32_t max_extents = 32;
+
+bool read_command_line(int argc, const char * const argv[], Options &options);
+void usage(const char *progname);
+int secdiscard_path(const std::string &path);
+std::unique_ptr<struct fiemap> path_fiemap(const std::string &path, uint32_t extent_count);
+bool check_fiemap(const struct fiemap &fiemap, const std::string &path);
+std::unique_ptr<struct fiemap> alloc_fiemap(uint32_t extent_count);
+std::string block_device_for_path(const std::string &path);
+
+}
+
+int main(int argc, const char * const argv[]) {
+    android::base::InitLogging(const_cast<char **>(argv));
+    Options options;
+    if (!read_command_line(argc, argv, options)) {
         usage(argv[0]);
         return -1;
     }
-    SLOGD("Running: %s %s", argv[0], argv[1]);
-    std::string target(argv[1]);
-    destroy_key(target);
-    if (unlink(argv[1]) != 0 && errno != ENOENT) {
-        SLOGE("Unable to delete %s: %s",
-            argv[1], strerror(errno));
-        return -1;
+    for (auto target: options.targets) {
+        LOG(DEBUG) << "Securely discarding '" << target << "' unlink=" << options.unlink;
+        secdiscard_path(target);
+        if (options.unlink) {
+            if (unlink(target.c_str()) != 0 && errno != ENOENT) {
+                PLOG(ERROR) << "Unable to unlink: " << target;
+            }
+        }
+        LOG(DEBUG) << "Discarded: " << target;
     }
     return 0;
 }
 
-static void usage(char *progname) {
-    fprintf(stderr, "Usage: %s <absolute path>\n", progname);
+namespace {
+
+bool read_command_line(int argc, const char * const argv[], Options &options) {
+    for (int i = 1; i < argc; i++) {
+        if (!strcmp("--no-unlink", argv[i])) {
+            options.unlink = false;
+        } else if (!strcmp("--", argv[i])) {
+            for (int j = i+1; j < argc; j++) {
+                if (argv[j][0] != '/') return false; // Must be absolute path
+                options.targets.emplace_back(argv[j]);
+            }
+            return options.targets.size() > 0;
+        } else {
+            return false; // Unknown option
+        }
+    }
+    return false; // "--" not found
+}
+
+void usage(const char *progname) {
+    fprintf(stderr, "Usage: %s [--no-unlink] -- <absolute path> ...\n", progname);
 }
 
 // BLKSECDISCARD all content in "path", if it's small enough.
-static void destroy_key(const std::string &path) {
-    uint64_t range[2];
-    if (file_device_range(path, range) < 0) {
-        return;
+int secdiscard_path(const std::string &path) {
+    auto fiemap = path_fiemap(path, max_extents);
+    if (!fiemap || !check_fiemap(*fiemap, path)) {
+        return -1;
     }
-    int fs_fd = open_block_device_for_path(path);
-    if (fs_fd < 0) {
-        return;
+    auto block_device = block_device_for_path(path);
+    if (block_device.empty()) {
+        return -1;
     }
-    if (ioctl(fs_fd, BLKSECDISCARD, range) != 0) {
-        SLOGE("Unable to BLKSECDISCARD %s: %s", path.c_str(), strerror(errno));
-        close(fs_fd);
-        return;
+    AutoCloseFD fs_fd(block_device, O_RDWR | O_LARGEFILE);
+    if (!fs_fd) {
+        PLOG(ERROR) << "Failed to open device " << block_device;
+        return -1;
     }
-    close(fs_fd);
-    SLOGD("Discarded %s", path.c_str());
-}
-
-// Find a short range that completely covers the file.
-// If there isn't one, return -1, otherwise 0.
-static int file_device_range(const std::string &path, uint64_t range[2])
-{
-    int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
-    if (fd < 0) {
-        if (errno == ENOENT) {
-            SLOGD("Unable to open %s: %s", path.c_str(), strerror(errno));
-        } else {
-            SLOGE("Unable to open %s: %s", path.c_str(), strerror(errno));
+    for (uint32_t i = 0; i < fiemap->fm_mapped_extents; i++) {
+        uint64_t range[2];
+        range[0] = fiemap->fm_extents[i].fe_physical;
+        range[1] = fiemap->fm_extents[i].fe_length;
+        if (ioctl(fs_fd.get(), BLKSECDISCARD, range) == -1) {
+            PLOG(ERROR) << "Unable to BLKSECDISCARD " << path;
+            return -1;
         }
-        return -1;
     }
-    alignas(struct fiemap) char fiemap_buffer[offsetof(struct fiemap, fm_extents[1])];
-    memset(fiemap_buffer, 0, sizeof(fiemap_buffer));
-    struct fiemap *fiemap = (struct fiemap *)fiemap_buffer;
-    fiemap->fm_start = 0;
-    fiemap->fm_length = UINT64_MAX;
-    fiemap->fm_flags = 0;
-    fiemap->fm_extent_count = 1;
-    fiemap->fm_mapped_extents = 0;
-    if (ioctl(fd, FS_IOC_FIEMAP, fiemap) != 0) {
-        SLOGE("Unable to FIEMAP %s: %s", path.c_str(), strerror(errno));
-        close(fd);
-        return -1;
-    }
-    close(fd);
-    if (fiemap->fm_mapped_extents != 1) {
-        SLOGE("Expecting one extent, got %d in %s", fiemap->fm_mapped_extents, path.c_str());
-        return -1;
-    }
-    struct fiemap_extent *extent = &fiemap->fm_extents[0];
-    if (!(extent->fe_flags & FIEMAP_EXTENT_LAST)) {
-        SLOGE("First extent was not the last in %s", path.c_str());
-        return -1;
-    }
-    if (extent->fe_flags &
-            (FIEMAP_EXTENT_UNKNOWN | FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_NOT_ALIGNED)) {
-        SLOGE("Extent has unexpected flags %ulx: %s", extent->fe_flags, path.c_str());
-        return -1;
-    }
-    if (extent->fe_length > MAX_WIPE_LENGTH) {
-        SLOGE("Extent too big, %llu bytes in %s", extent->fe_length, path.c_str());
-        return -1;
-    }
-    range[0] = extent->fe_physical;
-    range[1] = extent->fe_length;
     return 0;
 }
 
-// Given a file path, look for the corresponding
-// block device in /proc/mounts and open it.
-static int open_block_device_for_path(const std::string &path)
+// Read the file's FIEMAP
+std::unique_ptr<struct fiemap> path_fiemap(const std::string &path, uint32_t extent_count)
 {
-    std::string mountsfile("/proc/mounts");
-    std::string mounts;
-    if (read_file_as_string_atomically(mountsfile, mounts) < 0) {
-        return -1;
+    AutoCloseFD fd(path);
+    if (!fd) {
+        if (errno == ENOENT) {
+            PLOG(DEBUG) << "Unable to open " << path;
+        } else {
+            PLOG(ERROR) << "Unable to open " << path;
+        }
+        return nullptr;
     }
-    std::string block_device;
-    if (find_block_device_for_path(mounts, path, block_device) < 0) {
-        return -1;
+    auto fiemap = alloc_fiemap(extent_count);
+    if (ioctl(fd.get(), FS_IOC_FIEMAP, fiemap.get()) != 0) {
+        PLOG(ERROR) << "Unable to FIEMAP " << path;
+        return nullptr;
     }
-    SLOGD("For path %s block device is %s", path.c_str(), block_device.c_str());
-    int res = open(block_device.c_str(), O_RDWR | O_LARGEFILE | O_CLOEXEC);
-    if (res < 0) {
-        SLOGE("Failed to open device %s: %s", block_device.c_str(), strerror(errno));
-        return -1;
+    auto mapped = fiemap->fm_mapped_extents;
+    if (mapped < 1 || mapped > extent_count) {
+        LOG(ERROR) << "Extent count not in bounds 1 <= " << mapped << " <= " << extent_count
+            << " in " << path;
+        return nullptr;
     }
+    return fiemap;
+}
+
+// Ensure that the FIEMAP covers the file and is OK to discard
+bool check_fiemap(const struct fiemap &fiemap, const std::string &path) {
+    auto mapped = fiemap.fm_mapped_extents;
+    if (!(fiemap.fm_extents[mapped - 1].fe_flags & FIEMAP_EXTENT_LAST)) {
+        LOG(ERROR) << "Extent " << mapped -1 << " was not the last in " << path;
+        return false;
+    }
+    for (uint32_t i = 0; i < mapped; i++) {
+        auto flags = fiemap.fm_extents[i].fe_flags;
+        if (flags & (FIEMAP_EXTENT_UNKNOWN | FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_NOT_ALIGNED)) {
+            LOG(ERROR) << "Extent " << i << " has unexpected flags " << flags << ": " << path;
+            return false;
+        }
+    }
+    return true;
+}
+
+std::unique_ptr<struct fiemap> alloc_fiemap(uint32_t extent_count)
+{
+    size_t allocsize = offsetof(struct fiemap, fm_extents[extent_count]);
+    std::unique_ptr<struct fiemap> res(new (::operator new (allocsize)) struct fiemap);
+    memset(res.get(), 0, allocsize);
+    res->fm_start = 0;
+    res->fm_length = UINT64_MAX;
+    res->fm_flags = 0;
+    res->fm_extent_count = extent_count;
+    res->fm_mapped_extents = 0;
     return res;
 }
 
-// Read a file into a buffer in a single gulp, for atomicity.
-// Null-terminate the buffer.
-// Retry until the buffer is big enough.
-static int read_file_as_string_atomically(const std::string &path, std::string &contents)
+// Given a file path, look for the corresponding block device in /proc/mount
+std::string block_device_for_path(const std::string &path)
 {
-    ssize_t buffer_size = INIT_BUFFER_SIZE;
-    while (true) {
-        int fd = open(path.c_str(), O_RDONLY | O_CLOEXEC);
-        if (fd < 0) {
-            SLOGE("Failed to open %s: %s", path.c_str(), strerror(errno));
-            return -1;
-        }
-        contents.resize(buffer_size);
-        ssize_t read_size = read(fd, &contents[0], buffer_size);
-        if (read_size < 0) {
-            SLOGE("Failed to read from %s: %s", path.c_str(), strerror(errno));
-            close(fd);
-            return -1;
-        }
-        close(fd);
-        if (read_size < buffer_size) {
-            contents.resize(read_size);
-            return 0;
-        }
-        SLOGD("%s too big for buffer of size %zu", path.c_str(), buffer_size);
-        buffer_size <<= 1;
+    std::unique_ptr<FILE, int(*)(FILE*)> mnts(setmntent("/proc/mounts", "re"), endmntent);
+    if (!mnts) {
+        PLOG(ERROR) << "Unable to open /proc/mounts";
+        return "";
     }
+    std::string result;
+    size_t best_length = 0;
+    struct mntent *mnt; // getmntent returns a thread local, so it's safe.
+    while ((mnt = getmntent(mnts.get())) != nullptr) {
+        auto l = strlen(mnt->mnt_dir);
+        if (l > best_length &&
+            path.size() > l &&
+            path[l] == '/' &&
+            path.compare(0, l, mnt->mnt_dir) == 0) {
+                result = mnt->mnt_fsname;
+                best_length = l;
+        }
+    }
+    if (result.empty()) {
+        LOG(ERROR) <<"Didn't find a mountpoint to match path " << path;
+        return "";
+    }
+    LOG(DEBUG) << "For path " << path << " block device is " << result;
+    return result;
 }
 
-// Search a string representing the contents of /proc/mounts
-// for the mount point of a particular file by prefix matching
-// and return the corresponding block device.
-static int find_block_device_for_path(
-    const std::string &mounts,
-    const std::string &path,
-    std::string &block_device)
-{
-    auto line_begin = mounts.begin();
-    size_t best_prefix = 0;
-    std::string::const_iterator line_end;
-    while (line_begin != mounts.end()) {
-        line_end = std::find(line_begin, mounts.end(), '\n');
-        if (line_end == mounts.end()) {
-            break;
-        }
-        auto device_end = std::find(line_begin, line_end, ' ');
-        if (device_end == line_end) {
-            break;
-        }
-        auto mountpoint_begin = device_end + 1;
-        auto mountpoint_end = std::find(mountpoint_begin, line_end, ' ');
-        if (mountpoint_end == line_end) {
-            break;
-        }
-        if (std::find(line_begin, mountpoint_end, '\\') != mountpoint_end) {
-            // We don't correctly handle escape sequences, and we don't expect
-            // to encounter any, so fail if we do.
-            break;
-        }
-        size_t mountpoint_len = mountpoint_end - mountpoint_begin;
-        if (mountpoint_len > best_prefix &&
-                mountpoint_len < path.length() &&
-                path[mountpoint_len] == '/' &&
-                std::equal(mountpoint_begin, mountpoint_end, path.begin())) {
-            block_device = std::string(line_begin, device_end);
-            best_prefix = mountpoint_len;
-        }
-        line_begin = line_end + 1;
-    }
-    // All of the "break"s above are fatal parse errors.
-    if (line_begin != mounts.end()) {
-        auto bad_line = std::string(line_begin, line_end);
-        SLOGE("Unable to parse line in %s: %s", path.c_str(), bad_line.c_str());
-        return -1;
-    }
-    if (best_prefix == 0) {
-        SLOGE("No prefix found for path: %s", path.c_str());
-        return -1;
-    }
-    return 0;
 }
diff --git a/vdc.cpp b/vdc.cpp
index d8476b7..4eb26cd 100644
--- a/vdc.cpp
+++ b/vdc.cpp
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <stdlib.h>
+#include <poll.h>
 
 #include <sys/socket.h>
 #include <sys/select.h>
@@ -29,6 +30,8 @@
 #include <sys/types.h>
 #include <sys/un.h>
 
+#include <android-base/stringprintf.h>
+
 #include <cutils/sockets.h>
 #include <private/android_filesystem_config.h>
 
@@ -36,6 +39,8 @@
 static int do_monitor(int sock, int stop_after_cmd);
 static int do_cmd(int sock, int argc, char **argv);
 
+static constexpr int kCommandTimeoutMs = 20 * 1000;
+
 int main(int argc, char **argv) {
     int sock;
     int wait_for_socket;
@@ -44,12 +49,12 @@
     progname = argv[0];
 
     wait_for_socket = argc > 1 && strcmp(argv[1], "--wait") == 0;
-    if(wait_for_socket) {
+    if (wait_for_socket) {
         argv++;
         argc--;
     }
 
-    if(argc < 2) {
+    if (argc < 2) {
         usage(progname);
         exit(5);
     }
@@ -62,8 +67,8 @@
     while ((sock = socket_local_client(sockname,
                                  ANDROID_SOCKET_NAMESPACE_RESERVED,
                                  SOCK_STREAM)) < 0) {
-        if(!wait_for_socket) {
-            fprintf(stderr, "Error connecting (%s)\n", strerror(errno));
+        if (!wait_for_socket) {
+            fprintf(stdout, "Error connecting to %s: %s\n", sockname, strerror(errno));
             exit(4);
         } else {
             usleep(10000);
@@ -78,97 +83,92 @@
 }
 
 static int do_cmd(int sock, int argc, char **argv) {
-    char final_cmd[255] = "0 "; /* 0 is a (now required) sequence number */
+    int seq = getpid();
 
-    int i;
-    size_t ret;
+    std::string cmd(android::base::StringPrintf("%d ", seq));
+    for (int i = 1; i < argc; i++) {
+        if (!strchr(argv[i], ' ')) {
+            cmd.append(argv[i]);
+        } else {
+            cmd.push_back('\"');
+            cmd.append(argv[i]);
+            cmd.push_back('\"');
+        }
 
-    for (i = 1; i < argc; i++) {
-        char *cmp;
-
-        if (!strchr(argv[i], ' '))
-            asprintf(&cmp, "%s%s", argv[i], (i == (argc -1)) ? "" : " ");
-        else
-            asprintf(&cmp, "\"%s\"%s", argv[i], (i == (argc -1)) ? "" : " ");
-
-        ret = strlcat(final_cmd, cmp, sizeof(final_cmd));
-        if (ret >= sizeof(final_cmd))
-            abort();
-        free(cmp);
+        if (i < argc - 1) {
+            cmd.push_back(' ');
+        }
     }
 
-    if (write(sock, final_cmd, strlen(final_cmd) + 1) < 0) {
-        perror("write");
+    if (TEMP_FAILURE_RETRY(write(sock, cmd.c_str(), cmd.length() + 1)) < 0) {
+        fprintf(stderr, "Failed to write command: %s\n", strerror(errno));
         return errno;
     }
 
-    return do_monitor(sock, 1);
+    return do_monitor(sock, seq);
 }
 
-static int do_monitor(int sock, int stop_after_cmd) {
-    char *buffer = (char *) malloc(4096);
+static int do_monitor(int sock, int stop_after_seq) {
+    char buffer[4096];
+    int timeout = kCommandTimeoutMs;
 
-    if (!stop_after_cmd)
-        printf("[Connected to Vold]\n");
+    if (stop_after_seq == 0) {
+        fprintf(stderr, "Connected to vold\n");
+        timeout = -1;
+    }
 
-    while(1) {
-        fd_set read_fds;
-        struct timeval to;
-        int rc = 0;
-
-        to.tv_sec = 10;
-        to.tv_usec = 0;
-
-        FD_ZERO(&read_fds);
-        FD_SET(sock, &read_fds);
-
-        if ((rc = select(sock +1, &read_fds, NULL, NULL, &to)) < 0) {
-            fprintf(stderr, "Error in select (%s)\n", strerror(errno));
-            free(buffer);
-            return errno;
-        } else if (!rc) {
-            continue;
-            fprintf(stderr, "[TIMEOUT]\n");
+    while (1) {
+        struct pollfd poll_sock = { sock, POLLIN, 0 };
+        int rc = TEMP_FAILURE_RETRY(poll(&poll_sock, 1, timeout));
+        if (rc == 0) {
+            fprintf(stderr, "Timeout waiting for %d\n", stop_after_seq);
             return ETIMEDOUT;
-        } else if (FD_ISSET(sock, &read_fds)) {
-            memset(buffer, 0, 4096);
-            if ((rc = read(sock, buffer, 4096)) <= 0) {
-                if (rc == 0)
-                    fprintf(stderr, "Lost connection to Vold - did it crash?\n");
-                else
-                    fprintf(stderr, "Error reading data (%s)\n", strerror(errno));
-                free(buffer);
-                if (rc == 0)
-                    return ECONNRESET;
-                return errno;
-            }
+        } else if (rc < 0) {
+            fprintf(stderr, "Failed during poll: %s\n", strerror(errno));
+            return errno;
+        }
 
-            int offset = 0;
-            int i = 0;
+        if (!(poll_sock.revents & POLLIN)) {
+            fprintf(stderr, "No data; trying again\n");
+            continue;
+        }
 
-            for (i = 0; i < rc; i++) {
-                if (buffer[i] == '\0') {
-                    int code;
-                    char tmp[4];
+        memset(buffer, 0, sizeof(buffer));
+        rc = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer)));
+        if (rc == 0) {
+            fprintf(stderr, "Lost connection, did vold crash?\n");
+            return ECONNRESET;
+        } else if (rc < 0) {
+            fprintf(stderr, "Error reading data: %s\n", strerror(errno));
+            return errno;
+        }
 
-                    strlcpy(tmp, buffer + offset, sizeof(tmp));
-                    code = atoi(tmp);
+        int offset = 0;
+        for (int i = 0; i < rc; i++) {
+            if (buffer[i] == '\0') {
+                char* res = buffer + offset;
+                fprintf(stdout, "%s\n", res);
 
-                    printf("%s\n", buffer + offset);
-                    if (stop_after_cmd) {
-                        if (code >= 200 && code < 600)
+                int code = atoi(strtok(res, " "));
+                if (code >= 200 && code < 600) {
+                    int seq = atoi(strtok(nullptr, " "));
+                    if (seq == stop_after_seq) {
+                        if (code == 200) {
                             return 0;
+                        } else {
+                            return code;
+                        }
                     }
-                    offset = i + 1;
                 }
+
+                offset = i + 1;
             }
         }
     }
-    free(buffer);
-    return 0;
+    return EIO;
 }
 
 static void usage(char *progname) {
     fprintf(stderr,
             "Usage: %s [--wait] <monitor>|<cmd> [arg1] [arg2...]\n", progname);
- }
+}
diff --git a/vdc.rc b/vdc.rc
index d5483d0..4d51ced 100644
--- a/vdc.rc
+++ b/vdc.rc
@@ -1,13 +1,12 @@
 # One shot invocation to deal with encrypted volume.
-service defaultcrypto /system/bin/vdc --wait cryptfs mountdefaultencrypted
-    disabled
-    oneshot
+on defaultcrypto
+    exec - root -- /system/bin/vdc --wait cryptfs mountdefaultencrypted
     # vold will set vold.decrypt to trigger_restart_framework (default
     # encryption) or trigger_restart_min_framework (other encryption)
 
 # One shot invocation to encrypt unencrypted volumes
-service encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace default noui
-    disabled
-    oneshot
+on encrypt
+    start surfaceflinger
+    exec - root -- /system/bin/vdc --wait cryptfs enablecrypto inplace default noui
     # vold will set vold.decrypt to trigger_restart_framework (default
     # encryption)
diff --git a/vold.rc b/vold.rc
index 7719e0b..53ea7fc 100644
--- a/vold.rc
+++ b/vold.rc
@@ -5,3 +5,4 @@
     socket vold stream 0660 root mount
     socket cryptd stream 0660 root mount
     ioprio be 2
+    writepid /dev/cpuset/foreground/tasks
