diff --git a/crypto/lollipop/Android.mk b/crypto/lollipop/Android.mk
new file mode 100644
index 0000000..cce070b
--- /dev/null
+++ b/crypto/lollipop/Android.mk
@@ -0,0 +1,52 @@
+LOCAL_PATH := $(call my-dir)
+ifeq ($(TW_INCLUDE_L_CRYPTO), true)
+include $(CLEAR_VARS)
+
+common_c_includes := \
+	system/extras/ext4_utils \
+	system/extras/f2fs_utils \
+	external/openssl/include \
+	external/stlport/stlport \
+	bionic \
+	external/scrypt/lib/crypto \
+	frameworks/native/include \
+	system/security/keystore \
+	hardware/libhardware/include/hardware \
+	system/security/softkeymaster/include/keymaster
+
+common_shared_libraries := \
+	libsysutils \
+	libstlport \
+	libbinder \
+	libcutils \
+	liblog \
+	libdiskconfig \
+	libhardware_legacy \
+	liblogwrap \
+	libext4_utils \
+	libf2fs_sparseblock \
+	libcrypto \
+	libselinux \
+	libutils \
+	libhardware \
+	libsoftkeymaster
+
+LOCAL_MODULE := libcryptfslollipop
+LOCAL_MODULE_TAGS := eng optional
+LOCAL_CFLAGS :=
+LOCAL_SRC_FILES = cryptfs.c
+#LOCAL_C_INCLUDES += \
+#    system/extras/ext4_utils \
+#    external/openssl/include \
+#    system/extras/f2fs_utils \
+#    external/scrypt/lib/crypto \
+#    system/security/keystore \
+#    hardware/libhardware/include/hardware \
+#	system/security/softkeymaster/include/keymaster
+#LOCAL_SHARED_LIBRARIES += libc liblog libcutils libcrypto libext4_utils
+LOCAL_SHARED_LIBRARIES := $(common_shared_libraries)
+LOCAL_C_INCLUDES := external/openssl/include $(common_c_includes)
+LOCAL_STATIC_LIBRARIES += libfs_mgr libscrypt_static liblogwrap libmincrypttwrp
+
+include $(BUILD_SHARED_LIBRARY)
+endif
diff --git a/crypto/lollipop/cryptfs.c b/crypto/lollipop/cryptfs.c
new file mode 100644
index 0000000..630fb0e
--- /dev/null
+++ b/crypto/lollipop/cryptfs.c
@@ -0,0 +1,3620 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+/* TO DO:
+ *   1.  Perhaps keep several copies of the encrypted key, in case something
+ *       goes horribly wrong?
+ *
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <linux/dm-ioctl.h>
+#include <libgen.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <string.h>
+#include <sys/mount.h>
+#include <openssl/evp.h>
+#include <errno.h>
+#include <ext4.h>
+#include <linux/kdev_t.h>
+#include <fs_mgr.h>
+#include <time.h>
+#include "cryptfs.h"
+#define LOG_TAG "Cryptfs"
+#include "cutils/log.h"
+#include "cutils/properties.h"
+#include "cutils/android_reboot.h"
+#include "hardware_legacy/power.h"
+#include <logwrap/logwrap.h>
+//#include "VolumeManager.h"
+//#include "VoldUtil.h"
+#include "crypto_scrypt.h"
+#include "ext4_utils.h"
+#include "f2fs_sparseblock.h"
+//#include "CheckBattery.h"
+//#include "Process.h"
+
+#include <hardware/keymaster.h>
+
+#define UNUSED __attribute__((unused))
+
+#define UNUSED __attribute__((unused))
+
+#define DM_CRYPT_BUF_SIZE 4096
+
+#define HASH_COUNT 2000
+#define KEY_LEN_BYTES 16
+#define IV_LEN_BYTES 16
+
+#define KEY_IN_FOOTER  "footer"
+
+// "default_password" encoded into hex (d=0x64 etc)
+#define DEFAULT_PASSWORD "64656661756c745f70617373776f7264"
+
+#define EXT4_FS 1
+#define F2FS_FS 2
+
+#define TABLE_LOAD_RETRIES 10
+
+#define RSA_KEY_SIZE 2048
+#define RSA_KEY_SIZE_BYTES (RSA_KEY_SIZE / 8)
+#define RSA_EXPONENT 0x10001
+
+#define RETRY_MOUNT_ATTEMPTS 10
+#define RETRY_MOUNT_DELAY_SECONDS 1
+
+char *me = "cryptfs";
+
+static unsigned char saved_master_key[KEY_LEN_BYTES];
+static char *saved_mount_point;
+static int  master_key_saved = 0;
+static struct crypt_persist_data *persist_data = NULL;
+
+static int keymaster_init(keymaster_device_t **keymaster_dev)
+{
+    int rc;
+
+    const hw_module_t* mod;
+    rc = hw_get_module_by_class(KEYSTORE_HARDWARE_MODULE_ID, NULL, &mod);
+    if (rc) {
+        printf("could not find any keystore module\n");
+        goto out;
+    }
+
+    rc = keymaster_open(mod, keymaster_dev);
+    if (rc) {
+        printf("could not open keymaster device in %s (%s)\n",
+            KEYSTORE_HARDWARE_MODULE_ID, strerror(-rc));
+        goto out;
+    }
+
+    return 0;
+
+out:
+    *keymaster_dev = NULL;
+    return rc;
+}
+
+/* Should we use keymaster? */
+static int keymaster_check_compatibility()
+{
+    keymaster_device_t *keymaster_dev = 0;
+    int rc = 0;
+
+    if (keymaster_init(&keymaster_dev)) {
+        printf("Failed to init keymaster\n");
+        rc = -1;
+        goto out;
+    }
+
+    printf("keymaster version is %d\n", keymaster_dev->common.module->module_api_version);
+
+    if (keymaster_dev->common.module->module_api_version
+            < KEYMASTER_MODULE_API_VERSION_0_3) {
+        rc = 0;
+        goto out;
+    }
+
+    if (keymaster_dev->flags & KEYMASTER_BLOBS_ARE_STANDALONE) {
+        rc = 1;
+    }
+
+out:
+    keymaster_close(keymaster_dev);
+    return rc;
+}
+
+/* Create a new keymaster key and store it in this footer */
+static int keymaster_create_key(struct crypt_mnt_ftr *ftr)
+{
+    uint8_t* key = 0;
+    keymaster_device_t *keymaster_dev = 0;
+
+    if (keymaster_init(&keymaster_dev)) {
+        printf("Failed to init keymaster\n");
+        return -1;
+    }
+
+    int rc = 0;
+
+    keymaster_rsa_keygen_params_t params;
+    memset(&params, '\0', sizeof(params));
+    params.public_exponent = RSA_EXPONENT;
+    params.modulus_size = RSA_KEY_SIZE;
+
+    size_t key_size;
+    if (keymaster_dev->generate_keypair(keymaster_dev, TYPE_RSA, &params,
+                                        &key, &key_size)) {
+        printf("Failed to generate keypair\n");
+        rc = -1;
+        goto out;
+    }
+
+    if (key_size > KEYMASTER_BLOB_SIZE) {
+        printf("Keymaster key too large for crypto footer\n");
+        rc = -1;
+        goto out;
+    }
+
+    memcpy(ftr->keymaster_blob, key, key_size);
+    ftr->keymaster_blob_size = key_size;
+
+out:
+    keymaster_close(keymaster_dev);
+    free(key);
+    return rc;
+}
+
+/* This signs the given object using the keymaster key. */
+static int keymaster_sign_object(struct crypt_mnt_ftr *ftr,
+                                 const unsigned char *object,
+                                 const size_t object_size,
+                                 unsigned char **signature,
+                                 size_t *signature_size)
+{
+    int rc = 0;
+    keymaster_device_t *keymaster_dev = 0;
+    if (keymaster_init(&keymaster_dev)) {
+        printf("Failed to init keymaster\n");
+        return -1;
+    }
+
+    /* We currently set the digest type to DIGEST_NONE because it's the
+     * only supported value for keymaster. A similar issue exists with
+     * PADDING_NONE. Long term both of these should likely change.
+     */
+    keymaster_rsa_sign_params_t params;
+    params.digest_type = DIGEST_NONE;
+    params.padding_type = PADDING_NONE;
+
+    unsigned char to_sign[RSA_KEY_SIZE_BYTES];
+    size_t to_sign_size = sizeof(to_sign);
+    memset(to_sign, 0, RSA_KEY_SIZE_BYTES);
+
+    // To sign a message with RSA, the message must satisfy two
+    // constraints:
+    //
+    // 1. The message, when interpreted as a big-endian numeric value, must
+    //    be strictly less than the public modulus of the RSA key.  Note
+    //    that because the most significant bit of the public modulus is
+    //    guaranteed to be 1 (else it's an (n-1)-bit key, not an n-bit
+    //    key), an n-bit message with most significant bit 0 always
+    //    satisfies this requirement.
+    //
+    // 2. The message must have the same length in bits as the public
+    //    modulus of the RSA key.  This requirement isn't mathematically
+    //    necessary, but is necessary to ensure consistency in
+    //    implementations.
+    switch (ftr->kdf_type) {
+        case KDF_SCRYPT_KEYMASTER_UNPADDED:
+            // This is broken: It produces a message which is shorter than
+            // the public modulus, failing criterion 2.
+            memcpy(to_sign, object, object_size);
+            to_sign_size = object_size;
+            printf("Signing unpadded object\n");
+            break;
+        case KDF_SCRYPT_KEYMASTER_BADLY_PADDED:
+            // This is broken: Since the value of object is uniformly
+            // distributed, it produces a message that is larger than the
+            // public modulus with probability 0.25.
+            memcpy(to_sign, object, min(RSA_KEY_SIZE_BYTES, object_size));
+            printf("Signing end-padded object\n");
+            break;
+        case KDF_SCRYPT_KEYMASTER:
+            // This ensures the most significant byte of the signed message
+            // is zero.  We could have zero-padded to the left instead, but
+            // this approach is slightly more robust against changes in
+            // object size.  However, it's still broken (but not unusably
+            // so) because we really should be using a proper RSA padding
+            // function, such as OAEP.
+            //
+            // TODO(paullawrence): When keymaster 0.4 is available, change
+            // this to use the padding options it provides.
+            memcpy(to_sign + 1, object, min(RSA_KEY_SIZE_BYTES - 1, object_size));
+            printf("Signing safely-padded object\n");
+            break;
+        default:
+            printf("Unknown KDF type %d\n", ftr->kdf_type);
+            return -1;
+    }
+
+    rc = keymaster_dev->sign_data(keymaster_dev,
+                                  &params,
+                                  ftr->keymaster_blob,
+                                  ftr->keymaster_blob_size,
+                                  to_sign,
+                                  to_sign_size,
+                                  signature,
+                                  signature_size);
+
+    keymaster_close(keymaster_dev);
+    return rc;
+}
+
+/* Store password when userdata is successfully decrypted and mounted.
+ * Cleared by cryptfs_clear_password
+ *
+ * To avoid a double prompt at boot, we need to store the CryptKeeper
+ * password and pass it to KeyGuard, which uses it to unlock KeyStore.
+ * Since the entire framework is torn down and rebuilt after encryption,
+ * we have to use a daemon or similar to store the password. Since vold
+ * is secured against IPC except from system processes, it seems a reasonable
+ * place to store this.
+ *
+ * password should be cleared once it has been used.
+ *
+ * password is aged out after password_max_age_seconds seconds.
+ */
+static char* password = 0;
+static int password_expiry_time = 0;
+static const int password_max_age_seconds = 60;
+
+struct fstab *fstab;
+
+enum RebootType {reboot, recovery, shutdown};
+static void cryptfs_reboot(enum RebootType rt)
+{
+  switch(rt) {
+      case reboot:
+          property_set(ANDROID_RB_PROPERTY, "reboot");
+          break;
+
+      case recovery:
+          property_set(ANDROID_RB_PROPERTY, "reboot,recovery");
+          break;
+
+      case shutdown:
+          property_set(ANDROID_RB_PROPERTY, "shutdown");
+          break;
+    }
+
+    sleep(20);
+
+    /* Shouldn't get here, reboot should happen before sleep times out */
+    return;
+}
+
+static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags)
+{
+    memset(io, 0, dataSize);
+    io->data_size = dataSize;
+    io->data_start = sizeof(struct dm_ioctl);
+    io->version[0] = 4;
+    io->version[1] = 0;
+    io->version[2] = 0;
+    io->flags = flags;
+    if (name) {
+        strncpy(io->name, name, sizeof(io->name));
+    }
+}
+
+/**
+ * Gets the default device scrypt parameters for key derivation time tuning.
+ * The parameters should lead to about one second derivation time for the
+ * 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;
+
+    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)) {
+            printf("bad scrypt parameters '%s' should be like '12:8:1'; using defaults", paramstr);
+            memcpy(params, default_params, sizeof(params));
+        }
+    }
+
+    ftr->N_factor = params[0];
+    ftr->r_factor = params[1];
+    ftr->p_factor = params[2];
+}
+
+static unsigned int get_fs_size(char *dev)
+{
+    int fd, block_size;
+    struct ext4_super_block sb;
+    off64_t len;
+
+    if ((fd = open(dev, O_RDONLY)) < 0) {
+        printf("Cannot open device to get filesystem size ");
+        return 0;
+    }
+
+    if (lseek64(fd, 1024, SEEK_SET) < 0) {
+        printf("Cannot seek to superblock");
+        return 0;
+    }
+
+    if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) {
+        printf("Cannot read superblock");
+        return 0;
+    }
+
+    close(fd);
+
+    if (le32_to_cpu(sb.s_magic) != EXT4_SUPER_MAGIC) {
+        printf("Not a valid ext4 superblock");
+        return 0;
+    }
+    block_size = 1024 << sb.s_log_block_size;
+    /* compute length in bytes */
+    len = ( ((off64_t)sb.s_blocks_count_hi << 32) + sb.s_blocks_count_lo) * block_size;
+
+    /* return length in sectors */
+    return (unsigned int) (len / 512);
+}
+
+static unsigned int get_blkdev_size(int fd)
+{
+  unsigned int nr_sec;
+
+  if ( (ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
+    nr_sec = 0;
+  }
+
+  return nr_sec;
+}
+
+static int get_crypt_ftr_info(char **metadata_fname, off64_t *off)
+{
+  static int cached_data = 0;
+  static off64_t cached_off = 0;
+  static char cached_metadata_fname[PROPERTY_VALUE_MAX] = "";
+  int fd;
+  char key_loc[PROPERTY_VALUE_MAX];
+  char real_blkdev[PROPERTY_VALUE_MAX];
+  unsigned int nr_sec;
+  int rc = -1;
+
+  if (!cached_data) {
+    fs_mgr_get_crypt_info(fstab, key_loc, real_blkdev, sizeof(key_loc));
+    printf("get_crypt_ftr_info crypto key location: '%s'\n", key_loc);
+    if (!strcmp(key_loc, KEY_IN_FOOTER)) {
+      if ( (fd = open(real_blkdev, O_RDWR)) < 0) {
+        printf("Cannot open real block device %s\n", real_blkdev);
+        return -1;
+      }
+
+      if ((nr_sec = get_blkdev_size(fd))) {
+        /* If it's an encrypted Android partition, the last 16 Kbytes contain the
+         * encryption info footer and key, and plenty of bytes to spare for future
+         * growth.
+         */
+        strlcpy(cached_metadata_fname, real_blkdev, sizeof(cached_metadata_fname));
+        cached_off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET;
+        cached_data = 1;
+      } else {
+        printf("Cannot get size of block device %s\n", real_blkdev);
+      }
+      close(fd);
+    } else {
+      strlcpy(cached_metadata_fname, key_loc, sizeof(cached_metadata_fname));
+      cached_off = 0;
+      cached_data = 1;
+    }
+  }
+
+  if (cached_data) {
+    if (metadata_fname) {
+        *metadata_fname = cached_metadata_fname;
+    }
+    if (off) {
+        *off = cached_off;
+    }
+    rc = 0;
+  }
+
+  return rc;
+}
+
+/* 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.
+ */
+static int put_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr)
+{
+  printf("TWRP NOT putting crypt footer and key\n");
+  return 0;
+  int fd;
+  unsigned int nr_sec, cnt;
+  /* starting_off is set to the SEEK_SET offset
+   * where the crypto structure starts
+   */
+  off64_t starting_off;
+  int rc = -1;
+  char *fname = NULL;
+  struct stat statbuf;
+
+  if (get_crypt_ftr_info(&fname, &starting_off)) {
+    printf("Unable to get crypt_ftr_info\n");
+    return -1;
+  }
+  if (fname[0] != '/') {
+    printf("Unexpected value for crypto key location\n");
+    return -1;
+  }
+  if ( (fd = open(fname, O_RDWR | O_CREAT, 0600)) < 0) {
+    printf("Cannot open footer file %s for put\n", fname);
+    return -1;
+  }
+
+  /* Seek to the start of the crypt footer */
+  if (lseek64(fd, starting_off, SEEK_SET) == -1) {
+    printf("Cannot seek to real block device footer\n");
+    goto errout;
+  }
+
+  if ((cnt = write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
+    printf("Cannot write real block device footer\n");
+    goto errout;
+  }
+
+  fstat(fd, &statbuf);
+  /* If the keys are kept on a raw block device, do not try to truncate it. */
+  if (S_ISREG(statbuf.st_mode)) {
+    if (ftruncate(fd, 0x4000)) {
+      printf("Cannot set footer file size\n");
+      goto errout;
+    }
+  }
+
+  /* Success! */
+  rc = 0;
+
+errout:
+  close(fd);
+  return rc;
+
+}
+
+static inline int unix_read(int  fd, void*  buff, int  len)
+{
+    return TEMP_FAILURE_RETRY(read(fd, buff, len));
+}
+
+static inline int unix_write(int  fd, const void*  buff, int  len)
+{
+    return TEMP_FAILURE_RETRY(write(fd, buff, len));
+}
+
+static void init_empty_persist_data(struct crypt_persist_data *pdata, int len)
+{
+    memset(pdata, 0, len);
+    pdata->persist_magic = PERSIST_DATA_MAGIC;
+    pdata->persist_valid_entries = 0;
+}
+
+/* A routine to update the passed in crypt_ftr to the lastest version.
+ * fd is open read/write on the device that holds the crypto footer and persistent
+ * data, crypt_ftr is a pointer to the struct to be updated, and offset is the
+ * absolute offset to the start of the crypt_mnt_ftr on the passed in fd.
+ */
+static void upgrade_crypt_ftr(int fd, struct crypt_mnt_ftr *crypt_ftr, off64_t offset)
+{
+    int orig_major = crypt_ftr->major_version;
+    int orig_minor = crypt_ftr->minor_version;
+printf("TWRP NOT upgrading crypto footer\n");
+return; // do not upgrade in recovery
+    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 0)) {
+        struct crypt_persist_data *pdata;
+        off64_t pdata_offset = offset + CRYPT_FOOTER_TO_PERSIST_OFFSET;
+
+        printf("upgrading crypto footer to 1.1");
+
+        pdata = malloc(CRYPT_PERSIST_DATA_SIZE);
+        if (pdata == NULL) {
+            printf("Cannot allocate persisent data\n");
+            return;
+        }
+        memset(pdata, 0, CRYPT_PERSIST_DATA_SIZE);
+
+        /* Need to initialize the persistent data area */
+        if (lseek64(fd, pdata_offset, SEEK_SET) == -1) {
+            printf("Cannot seek to persisent data offset\n");
+            return;
+        }
+        /* Write all zeros to the first copy, making it invalid */
+        unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE);
+
+        /* Write a valid but empty structure to the second copy */
+        init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
+        unix_write(fd, pdata, CRYPT_PERSIST_DATA_SIZE);
+
+        /* Update the footer */
+        crypt_ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE;
+        crypt_ftr->persist_data_offset[0] = pdata_offset;
+        crypt_ftr->persist_data_offset[1] = pdata_offset + CRYPT_PERSIST_DATA_SIZE;
+        crypt_ftr->minor_version = 1;
+    }
+
+    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 1)) {
+        printf("upgrading crypto footer to 1.2");
+        /* But keep the old kdf_type.
+         * It will get updated later to KDF_SCRYPT after the password has been verified.
+         */
+        crypt_ftr->kdf_type = KDF_PBKDF2;
+        get_device_scrypt_params(crypt_ftr);
+        crypt_ftr->minor_version = 2;
+    }
+
+    if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version == 2)) {
+        printf("upgrading crypto footer to 1.3");
+        crypt_ftr->crypt_type = CRYPT_TYPE_PASSWORD;
+        crypt_ftr->minor_version = 3;
+    }
+
+    if ((orig_major != crypt_ftr->major_version) || (orig_minor != crypt_ftr->minor_version)) {
+        if (lseek64(fd, offset, SEEK_SET) == -1) {
+            printf("Cannot seek to crypt footer\n");
+            return;
+        }
+        unix_write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr));
+    }
+}
+
+
+static int get_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr)
+{
+  int fd;
+  unsigned int nr_sec, cnt;
+  off64_t starting_off;
+  int rc = -1;
+  char *fname = NULL;
+  struct stat statbuf;
+
+  if (get_crypt_ftr_info(&fname, &starting_off)) {
+    printf("Unable to get crypt_ftr_info\n");
+    return -1;
+  }
+  if (fname[0] != '/') {
+    printf("Unexpected value for crypto key location\n");
+    return -1;
+  }
+  if ( (fd = open(fname, O_RDWR)) < 0) {
+    printf("Cannot open footer file %s for get\n", fname);
+    return -1;
+  }
+
+  /* Make sure it's 16 Kbytes in length */
+  fstat(fd, &statbuf);
+  if (S_ISREG(statbuf.st_mode) && (statbuf.st_size != 0x4000)) {
+    printf("footer file %s is not the expected size!\n", fname);
+    goto errout;
+  }
+
+  /* Seek to the start of the crypt footer */
+  if (lseek64(fd, starting_off, SEEK_SET) == -1) {
+    printf("Cannot seek to real block device footer\n");
+    goto errout;
+  }
+
+  if ( (cnt = read(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
+    printf("Cannot read real block device footer\n");
+    goto errout;
+  }
+
+  if (crypt_ftr->magic != CRYPT_MNT_MAGIC) {
+    printf("Bad magic for real block device %s\n", fname);
+    goto errout;
+  }
+
+  if (crypt_ftr->major_version != CURRENT_MAJOR_VERSION) {
+    printf("Cannot understand major version %d real block device footer; expected %d\n",
+          crypt_ftr->major_version, CURRENT_MAJOR_VERSION);
+    goto errout;
+  }
+
+  if (crypt_ftr->minor_version > CURRENT_MINOR_VERSION) {
+    printf("Warning: crypto footer minor version %d, expected <= %d, continuing...\n",
+          crypt_ftr->minor_version, CURRENT_MINOR_VERSION);
+  }
+
+  /* If this is a verion 1.0 crypt_ftr, make it a 1.1 crypt footer, and update the
+   * copy on disk before returning.
+   */
+  if (crypt_ftr->minor_version < CURRENT_MINOR_VERSION) {
+    upgrade_crypt_ftr(fd, crypt_ftr, starting_off);
+  }
+
+  /* Success! */
+  rc = 0;
+
+errout:
+  close(fd);
+  return rc;
+}
+
+static int validate_persistent_data_storage(struct crypt_mnt_ftr *crypt_ftr)
+{
+    if (crypt_ftr->persist_data_offset[0] + crypt_ftr->persist_data_size >
+        crypt_ftr->persist_data_offset[1]) {
+        printf("Crypt_ftr persist data regions overlap");
+        return -1;
+    }
+
+    if (crypt_ftr->persist_data_offset[0] >= crypt_ftr->persist_data_offset[1]) {
+        printf("Crypt_ftr persist data region 0 starts after region 1");
+        return -1;
+    }
+
+    if (((crypt_ftr->persist_data_offset[1] + crypt_ftr->persist_data_size) -
+        (crypt_ftr->persist_data_offset[0] - CRYPT_FOOTER_TO_PERSIST_OFFSET)) >
+        CRYPT_FOOTER_OFFSET) {
+        printf("Persistent data extends past crypto footer");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int load_persistent_data(void)
+{
+    struct crypt_mnt_ftr crypt_ftr;
+    struct crypt_persist_data *pdata = NULL;
+    char encrypted_state[PROPERTY_VALUE_MAX];
+    char *fname;
+    int found = 0;
+    int fd;
+    int ret;
+    int i;
+
+    if (persist_data) {
+        /* Nothing to do, we've already loaded or initialized it */
+        return 0;
+    }
+
+
+    /* If not encrypted, just allocate an empty table and initialize it */
+    property_get("ro.crypto.state", encrypted_state, "");
+    if (strcmp(encrypted_state, "encrypted") ) {
+        pdata = malloc(CRYPT_PERSIST_DATA_SIZE);
+        if (pdata) {
+            init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
+            persist_data = pdata;
+            return 0;
+        }
+        return -1;
+    }
+
+    if(get_crypt_ftr_and_key(&crypt_ftr)) {
+        return -1;
+    }
+
+    if ((crypt_ftr.major_version < 1)
+        || (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) {
+        printf("Crypt_ftr version doesn't support persistent data");
+        return -1;
+    }
+
+    if (get_crypt_ftr_info(&fname, NULL)) {
+        return -1;
+    }
+
+    ret = validate_persistent_data_storage(&crypt_ftr);
+    if (ret) {
+        return -1;
+    }
+
+    fd = open(fname, O_RDONLY);
+    if (fd < 0) {
+        printf("Cannot open %s metadata file", fname);
+        return -1;
+    }
+
+    if (persist_data == NULL) {
+        pdata = malloc(crypt_ftr.persist_data_size);
+        if (pdata == NULL) {
+            printf("Cannot allocate memory for persistent data");
+            goto err;
+        }
+    }
+
+    for (i = 0; i < 2; i++) {
+        if (lseek64(fd, crypt_ftr.persist_data_offset[i], SEEK_SET) < 0) {
+            printf("Cannot seek to read persistent data on %s", fname);
+            goto err2;
+        }
+        if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0){
+            printf("Error reading persistent data on iteration %d", i);
+            goto err2;
+        }
+        if (pdata->persist_magic == PERSIST_DATA_MAGIC) {
+            found = 1;
+            break;
+        }
+    }
+
+    if (!found) {
+        printf("Could not find valid persistent data, creating");
+        init_empty_persist_data(pdata, crypt_ftr.persist_data_size);
+    }
+
+    /* Success */
+    persist_data = pdata;
+    close(fd);
+    return 0;
+
+err2:
+    free(pdata);
+
+err:
+    close(fd);
+    return -1;
+}
+
+static int save_persistent_data(void)
+{
+    struct crypt_mnt_ftr crypt_ftr;
+    struct crypt_persist_data *pdata;
+    char *fname;
+    off64_t write_offset;
+    off64_t erase_offset;
+    int found = 0;
+    int fd;
+    int ret;
+
+    if (persist_data == NULL) {
+        printf("No persistent data to save");
+        return -1;
+    }
+
+    if(get_crypt_ftr_and_key(&crypt_ftr)) {
+        return -1;
+    }
+
+    if ((crypt_ftr.major_version < 1)
+        || (crypt_ftr.major_version == 1 && crypt_ftr.minor_version < 1)) {
+        printf("Crypt_ftr version doesn't support persistent data");
+        return -1;
+    }
+
+    ret = validate_persistent_data_storage(&crypt_ftr);
+    if (ret) {
+        return -1;
+    }
+
+    if (get_crypt_ftr_info(&fname, NULL)) {
+        return -1;
+    }
+
+    fd = open(fname, O_RDWR);
+    if (fd < 0) {
+        printf("Cannot open %s metadata file", fname);
+        return -1;
+    }
+
+    pdata = malloc(crypt_ftr.persist_data_size);
+    if (pdata == NULL) {
+        printf("Cannot allocate persistant data");
+        goto err;
+    }
+
+    if (lseek64(fd, crypt_ftr.persist_data_offset[0], SEEK_SET) < 0) {
+        printf("Cannot seek to read persistent data on %s", fname);
+        goto err2;
+    }
+
+    if (unix_read(fd, pdata, crypt_ftr.persist_data_size) < 0) {
+            printf("Error reading persistent data before save");
+            goto err2;
+    }
+
+    if (pdata->persist_magic == PERSIST_DATA_MAGIC) {
+        /* The first copy is the curent valid copy, so write to
+         * the second copy and erase this one */
+       write_offset = crypt_ftr.persist_data_offset[1];
+       erase_offset = crypt_ftr.persist_data_offset[0];
+    } else {
+        /* The second copy must be the valid copy, so write to
+         * the first copy, and erase the second */
+       write_offset = crypt_ftr.persist_data_offset[0];
+       erase_offset = crypt_ftr.persist_data_offset[1];
+    }
+
+    /* Write the new copy first, if successful, then erase the old copy */
+    if (lseek(fd, write_offset, SEEK_SET) < 0) {
+        printf("Cannot seek to write persistent data");
+        goto err2;
+    }
+    if (unix_write(fd, persist_data, crypt_ftr.persist_data_size) ==
+        (int) crypt_ftr.persist_data_size) {
+        if (lseek(fd, erase_offset, SEEK_SET) < 0) {
+            printf("Cannot seek to erase previous persistent data");
+            goto err2;
+        }
+        fsync(fd);
+        memset(pdata, 0, crypt_ftr.persist_data_size);
+        if (unix_write(fd, pdata, crypt_ftr.persist_data_size) !=
+            (int) crypt_ftr.persist_data_size) {
+            printf("Cannot write to erase previous persistent data");
+            goto err2;
+        }
+        fsync(fd);
+    } else {
+        printf("Cannot write to save persistent data");
+        goto err2;
+    }
+
+    /* Success */
+    free(pdata);
+    close(fd);
+    return 0;
+
+err2:
+    free(pdata);
+err:
+    close(fd);
+    return -1;
+}
+
+static int hexdigit (char c)
+{
+    if (c >= '0' && c <= '9') return c - '0';
+    c = tolower(c);
+    if (c >= 'a' && c <= 'f') return c - 'a' + 10;
+    return -1;
+}
+
+static unsigned char* convert_hex_ascii_to_key(const char* master_key_ascii,
+                                               unsigned int* out_keysize)
+{
+    unsigned int i;
+    *out_keysize = 0;
+
+    size_t size = strlen (master_key_ascii);
+    if (size % 2) {
+        printf("Trying to convert ascii string of odd length");
+        return NULL;
+    }
+
+    unsigned char* master_key = (unsigned char*) malloc(size / 2);
+    if (master_key == 0) {
+        printf("Cannot allocate");
+        return NULL;
+    }
+
+    for (i = 0; i < size; i += 2) {
+        int high_nibble = hexdigit (master_key_ascii[i]);
+        int low_nibble = hexdigit (master_key_ascii[i + 1]);
+
+        if(high_nibble < 0 || low_nibble < 0) {
+            printf("Invalid hex string");
+            free (master_key);
+            return NULL;
+        }
+
+        master_key[*out_keysize] = high_nibble * 16 + low_nibble;
+        (*out_keysize)++;
+    }
+
+    return master_key;
+}
+
+/* Convert a binary key of specified length into an ascii hex string equivalent,
+ * without the leading 0x and with null termination
+ */
+static void convert_key_to_hex_ascii(unsigned char *master_key, unsigned int keysize,
+                              char *master_key_ascii)
+{
+  unsigned int i, a;
+  unsigned char nibble;
+
+  for (i=0, a=0; i<keysize; i++, a+=2) {
+    /* For each byte, write out two ascii hex digits */
+    nibble = (master_key[i] >> 4) & 0xf;
+    master_key_ascii[a] = nibble + (nibble > 9 ? 0x37 : 0x30);
+
+    nibble = master_key[i] & 0xf;
+    master_key_ascii[a+1] = nibble + (nibble > 9 ? 0x37 : 0x30);
+  }
+
+  /* Add the null termination */
+  master_key_ascii[a] = '\0';
+
+}
+
+static int load_crypto_mapping_table(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key,
+                                     char *real_blk_name, const char *name, int fd,
+                                     char *extra_params)
+{
+  char buffer[DM_CRYPT_BUF_SIZE];
+  struct dm_ioctl *io;
+  struct dm_target_spec *tgt;
+  char *crypt_params;
+  char master_key_ascii[129]; /* Large enough to hold 512 bit key and null */
+  int i;
+
+  io = (struct dm_ioctl *) buffer;
+
+  /* Load the mapping table for this device */
+  tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
+
+  ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
+  io->target_count = 1;
+  tgt->status = 0;
+  tgt->sector_start = 0;
+  tgt->length = crypt_ftr->fs_size;
+  strcpy(tgt->target_type, "crypt");
+
+  crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
+  convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
+  sprintf(crypt_params, "%s %s 0 %s 0 %s", crypt_ftr->crypto_type_name,
+          master_key_ascii, real_blk_name, extra_params);
+  crypt_params += strlen(crypt_params) + 1;
+  crypt_params = (char *) (((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */
+  tgt->next = crypt_params - buffer;
+
+  for (i = 0; i < TABLE_LOAD_RETRIES; i++) {
+    if (! ioctl(fd, DM_TABLE_LOAD, io)) {
+      break;
+    }
+    usleep(500000);
+  }
+
+  if (i == TABLE_LOAD_RETRIES) {
+    /* We failed to load the table, return an error */
+    return -1;
+  } else {
+    return i + 1;
+  }
+}
+
+
+static int get_dm_crypt_version(int fd, const char *name,  int *version)
+{
+    char buffer[DM_CRYPT_BUF_SIZE];
+    struct dm_ioctl *io;
+    struct dm_target_versions *v;
+    int i;
+
+    io = (struct dm_ioctl *) buffer;
+
+    ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
+
+    if (ioctl(fd, DM_LIST_VERSIONS, io)) {
+        return -1;
+    }
+
+    /* Iterate over the returned versions, looking for name of "crypt".
+     * When found, get and return the version.
+     */
+    v = (struct dm_target_versions *) &buffer[sizeof(struct dm_ioctl)];
+    while (v->next) {
+        if (! strcmp(v->name, "crypt")) {
+            /* We found the crypt driver, return the version, and get out */
+            version[0] = v->version[0];
+            version[1] = v->version[1];
+            version[2] = v->version[2];
+            return 0;
+        }
+        v = (struct dm_target_versions *)(((char *)v) + v->next);
+    }
+
+    return -1;
+}
+
+static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key,
+                                    char *real_blk_name, char *crypto_blk_name, const char *name)
+{
+  char buffer[DM_CRYPT_BUF_SIZE];
+  char master_key_ascii[129]; /* Large enough to hold 512 bit key and null */
+  char *crypt_params;
+  struct dm_ioctl *io;
+  struct dm_target_spec *tgt;
+  unsigned int minor;
+  int fd;
+  int i;
+  int retval = -1;
+  int version[3];
+  char *extra_params;
+  int load_count;
+
+  if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
+    printf("Cannot open device-mapper\n");
+    goto errout;
+  }
+
+  io = (struct dm_ioctl *) buffer;
+
+  ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
+  if (ioctl(fd, DM_DEV_CREATE, io)) {
+    printf("Cannot create dm-crypt device\n");
+    goto errout;
+  }
+
+  /* Get the device status, in particular, the name of it's device file */
+  ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
+  if (ioctl(fd, DM_DEV_STATUS, io)) {
+    printf("Cannot retrieve dm-crypt device status\n");
+    goto errout;
+  }
+  minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
+  snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor);
+
+  extra_params = "";
+  if (! get_dm_crypt_version(fd, name, version)) {
+      /* Support for allow_discards was added in version 1.11.0 */
+      if ((version[0] >= 2) ||
+          ((version[0] == 1) && (version[1] >= 11))) {
+          extra_params = "1 allow_discards";
+          printf("Enabling support for allow_discards in dmcrypt.\n");
+      }
+  }
+
+  load_count = load_crypto_mapping_table(crypt_ftr, master_key, real_blk_name, name,
+                                         fd, extra_params);
+  if (load_count < 0) {
+      printf("Cannot load dm-crypt mapping table.\n");
+      goto errout;
+  } else if (load_count > 1) {
+      printf("Took %d tries to load dmcrypt table.\n", load_count);
+  }
+
+  /* Resume this device to activate it */
+  ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
+
+  if (ioctl(fd, DM_DEV_SUSPEND, io)) {
+    printf("Cannot resume the dm-crypt device\n");
+    goto errout;
+  }
+
+  /* We made it here with no errors.  Woot! */
+  retval = 0;
+
+errout:
+  close(fd);   /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
+
+  return retval;
+}
+
+static int delete_crypto_blk_dev(char *name)
+{
+  int fd;
+  char buffer[DM_CRYPT_BUF_SIZE];
+  struct dm_ioctl *io;
+  int retval = -1;
+
+  if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
+    printf("Cannot open device-mapper\n");
+    goto errout;
+  }
+
+  io = (struct dm_ioctl *) buffer;
+
+  ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
+  if (ioctl(fd, DM_DEV_REMOVE, io)) {
+    printf("Cannot remove dm-crypt device\n");
+    goto errout;
+  }
+
+  /* We made it here with no errors.  Woot! */
+  retval = 0;
+
+errout:
+  close(fd);    /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
+
+  return retval;
+
+}
+
+static int pbkdf2(const char *passwd, const unsigned char *salt,
+                  unsigned char *ikey, void *params UNUSED)
+{
+    printf("Using pbkdf2 for cryptfs KDF");
+
+    /* Turn the password into a key and IV that can decrypt the master key */
+    unsigned int keysize;
+    char* master_key = (char*)convert_hex_ascii_to_key(passwd, &keysize);
+    if (!master_key) return -1;
+    PKCS5_PBKDF2_HMAC_SHA1(master_key, keysize, salt, SALT_LEN,
+                           HASH_COUNT, KEY_LEN_BYTES+IV_LEN_BYTES, ikey);
+
+    memset(master_key, 0, keysize);
+    free (master_key);
+    return 0;
+}
+
+static int scrypt(const char *passwd, const unsigned char *salt,
+                  unsigned char *ikey, void *params)
+{
+    printf("Using scrypt for cryptfs KDF\n");
+
+    struct crypt_mnt_ftr *ftr = (struct crypt_mnt_ftr *) params;
+
+    int N = 1 << ftr->N_factor;
+    int r = 1 << ftr->r_factor;
+    int p = 1 << ftr->p_factor;
+
+    /* Turn the password into a key and IV that can decrypt the master key */
+    unsigned int keysize;
+    unsigned char* master_key = convert_hex_ascii_to_key(passwd, &keysize);
+    if (!master_key) return -1;
+    crypto_scrypt(master_key, keysize, salt, SALT_LEN, N, r, p, ikey,
+            KEY_LEN_BYTES + IV_LEN_BYTES);
+
+    memset(master_key, 0, keysize);
+    free (master_key);
+    return 0;
+}
+
+static int scrypt_keymaster(const char *passwd, const unsigned char *salt,
+                            unsigned char *ikey, void *params)
+{
+    printf("Using scrypt with keymaster for cryptfs KDF\n");
+
+    int rc;
+    unsigned int key_size;
+    size_t signature_size;
+    unsigned char* signature;
+    struct crypt_mnt_ftr *ftr = (struct crypt_mnt_ftr *) params;
+
+    int N = 1 << ftr->N_factor;
+    int r = 1 << ftr->r_factor;
+    int p = 1 << ftr->p_factor;
+
+    unsigned char* master_key = convert_hex_ascii_to_key(passwd, &key_size);
+    if (!master_key) {
+        printf("Failed to convert passwd from hex");
+        return -1;
+    }
+
+    rc = crypto_scrypt(master_key, key_size, salt, SALT_LEN,
+                       N, r, p, ikey, KEY_LEN_BYTES + IV_LEN_BYTES);
+    memset(master_key, 0, key_size);
+    free(master_key);
+
+    if (rc) {
+        printf("scrypt failed");
+        return -1;
+    }
+
+    if (keymaster_sign_object(ftr, ikey, KEY_LEN_BYTES + IV_LEN_BYTES,
+                              &signature, &signature_size)) {
+        printf("Signing failed");
+        return -1;
+    }
+
+    rc = crypto_scrypt(signature, signature_size, salt, SALT_LEN,
+                       N, r, p, ikey, KEY_LEN_BYTES + IV_LEN_BYTES);
+    free(signature);
+
+    if (rc) {
+        printf("scrypt failed");
+        return -1;
+    }
+
+    return 0;
+}
+
+static int encrypt_master_key(const char *passwd, const unsigned char *salt,
+                              const unsigned char *decrypted_master_key,
+                              unsigned char *encrypted_master_key,
+                              struct crypt_mnt_ftr *crypt_ftr)
+{
+    unsigned char ikey[32+32] = { 0 }; /* Big enough to hold a 256 bit key and 256 bit IV */
+    EVP_CIPHER_CTX e_ctx;
+    int encrypted_len, final_len;
+    int rc = 0;
+
+    /* Turn the password into an intermediate key and IV that can decrypt the master key */
+    get_device_scrypt_params(crypt_ftr);
+
+    switch (crypt_ftr->kdf_type) {
+    case KDF_SCRYPT_KEYMASTER_UNPADDED:
+    case KDF_SCRYPT_KEYMASTER_BADLY_PADDED:
+    case KDF_SCRYPT_KEYMASTER:
+        if (keymaster_create_key(crypt_ftr)) {
+            printf("keymaster_create_key failed");
+            return -1;
+        }
+
+        if (scrypt_keymaster(passwd, salt, ikey, crypt_ftr)) {
+            printf("scrypt failed");
+            return -1;
+        }
+        break;
+
+    case KDF_SCRYPT:
+        if (scrypt(passwd, salt, ikey, crypt_ftr)) {
+            printf("scrypt failed");
+            return -1;
+        }
+        break;
+
+    default:
+        printf("Invalid kdf_type");
+        return -1;
+    }
+
+    /* Initialize the decryption engine */
+    if (! EVP_EncryptInit(&e_ctx, EVP_aes_128_cbc(), ikey, ikey+KEY_LEN_BYTES)) {
+        printf("EVP_EncryptInit failed\n");
+        return -1;
+    }
+    EVP_CIPHER_CTX_set_padding(&e_ctx, 0); /* Turn off padding as our data is block aligned */
+
+    /* Encrypt the master key */
+    if (! EVP_EncryptUpdate(&e_ctx, encrypted_master_key, &encrypted_len,
+                              decrypted_master_key, KEY_LEN_BYTES)) {
+        printf("EVP_EncryptUpdate failed\n");
+        return -1;
+    }
+    if (! EVP_EncryptFinal(&e_ctx, encrypted_master_key + encrypted_len, &final_len)) {
+        printf("EVP_EncryptFinal failed\n");
+        return -1;
+    }
+
+    if (encrypted_len + final_len != KEY_LEN_BYTES) {
+        printf("EVP_Encryption length check failed with %d, %d bytes\n", encrypted_len, final_len);
+        return -1;
+    }
+
+    /* Store the scrypt of the intermediate key, so we can validate if it's a
+       password error or mount error when things go wrong.
+       Note there's no need to check for errors, since if this is incorrect, we
+       simply won't wipe userdata, which is the correct default behavior
+    */
+    int N = 1 << crypt_ftr->N_factor;
+    int r = 1 << crypt_ftr->r_factor;
+    int p = 1 << crypt_ftr->p_factor;
+
+    rc = crypto_scrypt(ikey, KEY_LEN_BYTES,
+                       crypt_ftr->salt, sizeof(crypt_ftr->salt), N, r, p,
+                       crypt_ftr->scrypted_intermediate_key,
+                       sizeof(crypt_ftr->scrypted_intermediate_key));
+
+    if (rc) {
+      printf("encrypt_master_key: crypto_scrypt failed");
+    }
+
+    return 0;
+}
+
+static int decrypt_master_key_aux(char *passwd, unsigned char *salt,
+                                  unsigned char *encrypted_master_key,
+                                  unsigned char *decrypted_master_key,
+                                  kdf_func kdf, void *kdf_params,
+                                  unsigned char** intermediate_key,
+                                  size_t* intermediate_key_size)
+{
+  unsigned char ikey[32+32] = { 0 }; /* Big enough to hold a 256 bit key and 256 bit IV */
+  EVP_CIPHER_CTX d_ctx;
+  int decrypted_len, final_len;
+
+  /* Turn the password into an intermediate key and IV that can decrypt the
+     master key */
+  if (kdf(passwd, salt, ikey, kdf_params)) {
+    printf("kdf failed");
+    return -1;
+  }
+
+  /* Initialize the decryption engine */
+  if (! EVP_DecryptInit(&d_ctx, EVP_aes_128_cbc(), ikey, ikey+KEY_LEN_BYTES)) {
+    return -1;
+  }
+  EVP_CIPHER_CTX_set_padding(&d_ctx, 0); /* Turn off padding as our data is block aligned */
+  /* Decrypt the master key */
+  if (! EVP_DecryptUpdate(&d_ctx, decrypted_master_key, &decrypted_len,
+                            encrypted_master_key, KEY_LEN_BYTES)) {
+    return -1;
+  }
+  if (! EVP_DecryptFinal(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) {
+    return -1;
+  }
+
+  if (decrypted_len + final_len != KEY_LEN_BYTES) {
+    return -1;
+  }
+
+  /* Copy intermediate key if needed by params */
+  if (intermediate_key && intermediate_key_size) {
+    *intermediate_key = (unsigned char*) malloc(KEY_LEN_BYTES);
+    if (intermediate_key) {
+      memcpy(*intermediate_key, ikey, KEY_LEN_BYTES);
+      *intermediate_key_size = KEY_LEN_BYTES;
+    }
+  }
+
+  return 0;
+}
+
+static void get_kdf_func(struct crypt_mnt_ftr *ftr, kdf_func *kdf, void** kdf_params)
+{
+    if (ftr->kdf_type == KDF_SCRYPT_KEYMASTER_UNPADDED ||
+        ftr->kdf_type == KDF_SCRYPT_KEYMASTER_BADLY_PADDED ||
+        ftr->kdf_type == KDF_SCRYPT_KEYMASTER) {
+        *kdf = scrypt_keymaster;
+        *kdf_params = ftr;
+    } else if (ftr->kdf_type == KDF_SCRYPT) {
+        *kdf = scrypt;
+        *kdf_params = ftr;
+    } else {
+        *kdf = pbkdf2;
+        *kdf_params = NULL;
+    }
+}
+
+static int decrypt_master_key(char *passwd, unsigned char *decrypted_master_key,
+                              struct crypt_mnt_ftr *crypt_ftr,
+                              unsigned char** intermediate_key,
+                              size_t* intermediate_key_size)
+{
+    kdf_func kdf;
+    void *kdf_params;
+    int ret;
+
+    get_kdf_func(crypt_ftr, &kdf, &kdf_params);
+    ret = decrypt_master_key_aux(passwd, crypt_ftr->salt, crypt_ftr->master_key,
+                                 decrypted_master_key, kdf, kdf_params,
+                                 intermediate_key, intermediate_key_size);
+    if (ret != 0) {
+        printf("failure decrypting master key");
+    }
+
+    return ret;
+}
+
+static int create_encrypted_random_key(char *passwd, unsigned char *master_key, unsigned char *salt,
+        struct crypt_mnt_ftr *crypt_ftr) {
+    int fd;
+    unsigned char key_buf[KEY_LEN_BYTES];
+    EVP_CIPHER_CTX e_ctx;
+    int encrypted_len, final_len;
+
+    /* Get some random bits for a key */
+    fd = open("/dev/urandom", O_RDONLY);
+    read(fd, key_buf, sizeof(key_buf));
+    read(fd, salt, SALT_LEN);
+    close(fd);
+
+    /* Now encrypt it with the password */
+    return encrypt_master_key(passwd, salt, key_buf, master_key, crypt_ftr);
+}
+
+static int wait_and_unmount(char *mountpoint, bool kill)
+{
+    int i, err, rc;
+#define WAIT_UNMOUNT_COUNT 20
+
+    /*  Now umount the tmpfs filesystem */
+    for (i=0; i<WAIT_UNMOUNT_COUNT; i++) {
+        if (umount(mountpoint) == 0) {
+            break;
+        }
+
+        if (errno == EINVAL) {
+            /* EINVAL is returned if the directory is not a mountpoint,
+             * i.e. there is no filesystem mounted there.  So just get out.
+             */
+            break;
+        }
+
+        err = errno;
+
+        /* If allowed, be increasingly aggressive before the last two retries */
+        if (kill) {
+            if (i == (WAIT_UNMOUNT_COUNT - 3)) {
+                printf("sending SIGHUP to processes with open files\n");
+                //vold_killProcessesWithOpenFiles(mountpoint, 1);
+            } else if (i == (WAIT_UNMOUNT_COUNT - 2)) {
+                printf("sending SIGKILL to processes with open files\n");
+                //vold_killProcessesWithOpenFiles(mountpoint, 2);
+            }
+        }
+
+        sleep(1);
+    }
+
+    if (i < WAIT_UNMOUNT_COUNT) {
+      printf("unmounting %s succeeded\n", mountpoint);
+      rc = 0;
+    } else {
+      //vold_killProcessesWithOpenFiles(mountpoint, 0);
+      printf("unmounting %s failed: %s\n", mountpoint, strerror(err));
+      rc = -1;
+    }
+
+    return rc;
+}
+
+#define DATA_PREP_TIMEOUT 200
+static int prep_data_fs(void)
+{
+    int i;
+
+    /* Do the prep of the /data filesystem */
+    property_set("vold.post_fs_data_done", "0");
+    property_set("vold.decrypt", "trigger_post_fs_data");
+    printf("Just triggered post_fs_data\n");
+
+    /* Wait a max of 50 seconds, hopefully it takes much less */
+    for (i=0; i<DATA_PREP_TIMEOUT; i++) {
+        char p[PROPERTY_VALUE_MAX];
+
+        property_get("vold.post_fs_data_done", p, "0");
+        if (*p == '1') {
+            break;
+        } else {
+            usleep(250000);
+        }
+    }
+    if (i == DATA_PREP_TIMEOUT) {
+        /* Ugh, we failed to prep /data in time.  Bail. */
+        printf("post_fs_data timed out!\n");
+        return -1;
+    } else {
+        printf("post_fs_data done\n");
+        return 0;
+    }
+}
+
+static void cryptfs_set_corrupt()
+{
+    // Mark the footer as bad
+    struct crypt_mnt_ftr crypt_ftr;
+    if (get_crypt_ftr_and_key(&crypt_ftr)) {
+        printf("Failed to get crypto footer - panic");
+        return;
+    }
+
+    crypt_ftr.flags |= CRYPT_DATA_CORRUPT;
+    if (put_crypt_ftr_and_key(&crypt_ftr)) {
+        printf("Failed to set crypto footer - panic");
+        return;
+    }
+}
+
+static void cryptfs_trigger_restart_min_framework()
+{
+    if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) {
+      printf("Failed to mount tmpfs on data - panic");
+      return;
+    }
+
+    if (property_set("vold.decrypt", "trigger_post_fs_data")) {
+        printf("Failed to trigger post fs data - panic");
+        return;
+    }
+
+    if (property_set("vold.decrypt", "trigger_restart_min_framework")) {
+        printf("Failed to trigger restart min framework - panic");
+        return;
+    }
+}
+
+/* returns < 0 on failure */
+static int cryptfs_restart_internal(int restart_main)
+{
+    char fs_type[32];
+    char real_blkdev[MAXPATHLEN];
+    char crypto_blkdev[MAXPATHLEN];
+    char fs_options[256];
+    unsigned long mnt_flags;
+    struct stat statbuf;
+    int rc = -1, i;
+    static int restart_successful = 0;
+
+    /* Validate that it's OK to call this routine */
+    if (! master_key_saved) {
+        printf("Encrypted filesystem not validated, aborting");
+        return -1;
+    }
+
+    if (restart_successful) {
+        printf("System already restarted with encrypted disk, aborting");
+        return -1;
+    }
+
+    if (restart_main) {
+        /* Here is where we shut down the framework.  The init scripts
+         * start all services in one of three classes: core, main or late_start.
+         * On boot, we start core and main.  Now, we stop main, but not core,
+         * as core includes vold and a few other really important things that
+         * we need to keep running.  Once main has stopped, we should be able
+         * to umount the tmpfs /data, then mount the encrypted /data.
+         * We then restart the class main, and also the class late_start.
+         * At the moment, I've only put a few things in late_start that I know
+         * are not needed to bring up the framework, and that also cause problems
+         * with unmounting the tmpfs /data, but I hope to add add more services
+         * to the late_start class as we optimize this to decrease the delay
+         * till the user is asked for the password to the filesystem.
+         */
+
+        /* The init files are setup to stop the class main when vold.decrypt is
+         * set to trigger_reset_main.
+         */
+        property_set("vold.decrypt", "trigger_reset_main");
+        printf("Just asked init to shut down class main\n");
+
+        /* Ugh, shutting down the framework is not synchronous, so until it
+         * can be fixed, this horrible hack will wait a moment for it all to
+         * shut down before proceeding.  Without it, some devices cannot
+         * restart the graphics services.
+         */
+        sleep(2);
+    }
+
+    /* Now that the framework is shutdown, we should be able to umount()
+     * the tmpfs filesystem, and mount the real one.
+     */
+
+    property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "");
+    if (strlen(crypto_blkdev) == 0) {
+        printf("fs_crypto_blkdev not set\n");
+        return -1;
+    }
+
+    if (! (rc = wait_and_unmount(DATA_MNT_POINT, true)) ) {
+        /* If ro.crypto.readonly is set to 1, mount the decrypted
+         * filesystem readonly.  This is used when /data is mounted by
+         * recovery mode.
+         */
+        char ro_prop[PROPERTY_VALUE_MAX];
+        property_get("ro.crypto.readonly", ro_prop, "");
+        if (strlen(ro_prop) > 0 && atoi(ro_prop)) {
+            struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT);
+            rec->flags |= MS_RDONLY;
+        }
+
+        /* If that succeeded, then mount the decrypted filesystem */
+        int retries = RETRY_MOUNT_ATTEMPTS;
+        int mount_rc;
+        while ((mount_rc = fs_mgr_do_mount(fstab, DATA_MNT_POINT,
+                                           crypto_blkdev, 0))
+               != 0) {
+            if (mount_rc == FS_MGR_DOMNT_BUSY) {
+                /* TODO: invoke something similar to
+                   Process::killProcessWithOpenFiles(DATA_MNT_POINT,
+                                   retries > RETRY_MOUNT_ATTEMPT/2 ? 1 : 2 ) */
+                printf("Failed to mount %s because it is busy - waiting",
+                      crypto_blkdev);
+                if (--retries) {
+                    sleep(RETRY_MOUNT_DELAY_SECONDS);
+                } else {
+                    /* Let's hope that a reboot clears away whatever is keeping
+                       the mount busy */
+                    cryptfs_reboot(reboot);
+                }
+            } else {
+                printf("Failed to mount decrypted data");
+                cryptfs_set_corrupt();
+                cryptfs_trigger_restart_min_framework();
+                printf("Started framework to offer wipe");
+                return -1;
+            }
+        }
+
+        property_set("vold.decrypt", "trigger_load_persist_props");
+        /* Create necessary paths on /data */
+        if (prep_data_fs()) {
+            return -1;
+        }
+
+        /* startup service classes main and late_start */
+        property_set("vold.decrypt", "trigger_restart_framework");
+        printf("Just triggered restart_framework\n");
+
+        /* Give it a few moments to get started */
+        sleep(1);
+    }
+
+    if (rc == 0) {
+        restart_successful = 1;
+    }
+
+    return rc;
+}
+
+int cryptfs_restart(void)
+{
+    /* Call internal implementation forcing a restart of main service group */
+    return cryptfs_restart_internal(1);
+}
+
+static int do_crypto_complete(char *mount_point UNUSED)
+{
+  struct crypt_mnt_ftr crypt_ftr;
+  char encrypted_state[PROPERTY_VALUE_MAX];
+  char key_loc[PROPERTY_VALUE_MAX];
+
+  property_get("ro.crypto.state", encrypted_state, "");
+  if (strcmp(encrypted_state, "encrypted") ) {
+    printf("not running with encryption, aborting");
+    return CRYPTO_COMPLETE_NOT_ENCRYPTED;
+  }
+
+  if (get_crypt_ftr_and_key(&crypt_ftr)) {
+    fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc));
+
+    /*
+     * Only report this error if key_loc is a file and it exists.
+     * If the device was never encrypted, and /data is not mountable for
+     * some reason, returning 1 should prevent the UI from presenting the
+     * a "enter password" screen, or worse, a "press button to wipe the
+     * device" screen.
+     */
+    if ((key_loc[0] == '/') && (access("key_loc", F_OK) == -1)) {
+      printf("master key file does not exist, aborting");
+      return CRYPTO_COMPLETE_NOT_ENCRYPTED;
+    } else {
+      printf("Error getting crypt footer and key\n");
+      return CRYPTO_COMPLETE_BAD_METADATA;
+    }
+  }
+
+  // Test for possible error flags
+  if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS){
+    printf("Encryption process is partway completed\n");
+    return CRYPTO_COMPLETE_PARTIAL;
+  }
+
+  if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE){
+    printf("Encryption process was interrupted but cannot continue\n");
+    return CRYPTO_COMPLETE_INCONSISTENT;
+  }
+
+  if (crypt_ftr.flags & CRYPT_DATA_CORRUPT){
+    printf("Encryption is successful but data is corrupt\n");
+    return CRYPTO_COMPLETE_CORRUPT;
+  }
+
+  /* We passed the test! We shall diminish, and return to the west */
+  return CRYPTO_COMPLETE_ENCRYPTED;
+}
+
+static int test_mount_encrypted_fs(struct crypt_mnt_ftr* crypt_ftr,
+                                   char *passwd, char *mount_point, char *label)
+{
+  /* Allocate enough space for a 256 bit key, but we may use less */
+  unsigned char decrypted_master_key[32];
+  char crypto_blkdev[MAXPATHLEN];
+  char real_blkdev[MAXPATHLEN];
+  char tmp_mount_point[64];
+  unsigned int orig_failed_decrypt_count;
+  int rc;
+  kdf_func kdf;
+  void *kdf_params;
+  int use_keymaster = 0;
+  int upgrade = 0;
+  unsigned char* intermediate_key = 0;
+  size_t intermediate_key_size = 0;
+
+  printf("crypt_ftr->fs_size = %lld\n", crypt_ftr->fs_size);
+  orig_failed_decrypt_count = crypt_ftr->failed_decrypt_count;
+
+  if (! (crypt_ftr->flags & CRYPT_MNT_KEY_UNENCRYPTED) ) {
+    if (decrypt_master_key(passwd, decrypted_master_key, crypt_ftr,
+                           &intermediate_key, &intermediate_key_size)) {
+      printf("Failed to decrypt master key\n");
+      rc = -1;
+      goto errout;
+    }
+  }
+
+  fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
+
+  // Create crypto block device - all (non fatal) code paths
+  // need it
+  if (create_crypto_blk_dev(crypt_ftr, decrypted_master_key,
+                            real_blkdev, crypto_blkdev, label)) {
+     printf("Error creating decrypted block device\n");
+     rc = -1;
+     goto errout;
+  }
+
+  /* Work out if the problem is the password or the data */
+  unsigned char scrypted_intermediate_key[sizeof(crypt_ftr->
+                                                 scrypted_intermediate_key)];
+  int N = 1 << crypt_ftr->N_factor;
+  int r = 1 << crypt_ftr->r_factor;
+  int p = 1 << crypt_ftr->p_factor;
+
+  rc = crypto_scrypt(intermediate_key, intermediate_key_size,
+                     crypt_ftr->salt, sizeof(crypt_ftr->salt),
+                     N, r, p, scrypted_intermediate_key,
+                     sizeof(scrypted_intermediate_key));
+
+  // Does the key match the crypto footer?
+  if (rc == 0 && memcmp(scrypted_intermediate_key,
+                        crypt_ftr->scrypted_intermediate_key,
+                        sizeof(scrypted_intermediate_key)) == 0) {
+    printf("Password matches\n");
+    rc = 0;
+  } else {
+    /* Try mounting the file system anyway, just in case the problem's with
+     * the footer, not the key. */
+    sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point);
+    mkdir(tmp_mount_point, 0755);
+    if (fs_mgr_do_mount(fstab, DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) {
+      printf("Error temp mounting decrypted block device '%s'\n", crypto_blkdev);
+      delete_crypto_blk_dev(label);
+
+      rc = ++crypt_ftr->failed_decrypt_count;
+      //put_crypt_ftr_and_key(crypt_ftr); // Do not penalize for attempting to decrypt in recovery
+    } else {
+      /* Success! */
+      printf("Password did not match but decrypted drive mounted - continue\n");
+      umount(tmp_mount_point);
+      rc = 0;
+    }
+  }
+
+  if (rc == 0) {
+    /*crypt_ftr->failed_decrypt_count = 0;
+    if (orig_failed_decrypt_count != 0) {
+      put_crypt_ftr_and_key(crypt_ftr);
+    }*/
+
+    /* Save the name of the crypto block device
+     * so we can mount it when restarting the framework. */
+    property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev);
+
+    /* Also save a the master key so we can reencrypted the key
+     * the key when we want to change the password on it. */
+    /*memcpy(saved_master_key, decrypted_master_key, KEY_LEN_BYTES);
+    saved_mount_point = strdup(mount_point);
+    master_key_saved = 1;
+    printf("%s(): Master key saved\n", __FUNCTION__);*/
+    rc = 0;
+
+    // Upgrade if we're not using the latest KDF.
+    /*use_keymaster = keymaster_check_compatibility();
+    if (crypt_ftr->kdf_type == KDF_SCRYPT_KEYMASTER) {
+        // Don't allow downgrade
+    } else if (use_keymaster == 1 && crypt_ftr->kdf_type != KDF_SCRYPT_KEYMASTER) {
+        crypt_ftr->kdf_type = KDF_SCRYPT_KEYMASTER;
+        upgrade = 1;
+    } else if (use_keymaster == 0 && crypt_ftr->kdf_type != KDF_SCRYPT) {
+        crypt_ftr->kdf_type = KDF_SCRYPT;
+        upgrade = 1;
+    }
+
+    if (upgrade) {
+        rc = encrypt_master_key(passwd, crypt_ftr->salt, saved_master_key,
+                                crypt_ftr->master_key, crypt_ftr);
+        if (!rc) {
+            rc = put_crypt_ftr_and_key(crypt_ftr);
+        }
+        printf("Key Derivation Function upgrade: rc=%d\n", rc);
+
+        // Do not fail even if upgrade failed - machine is bootable
+        // Note that if this code is ever hit, there is a *serious* problem
+        // since KDFs should never fail. You *must* fix the kdf before
+        // proceeding!
+        if (rc) {
+          printf("Upgrade failed with error %d,"
+                " but continuing with previous state\n",
+                rc);
+          rc = 0;
+        }
+    }*/
+  }
+
+ errout:
+  if (intermediate_key) {
+    memset(intermediate_key, 0, intermediate_key_size);
+    free(intermediate_key);
+  }
+  return rc;
+}
+
+/* Called by vold when it wants to undo the crypto mapping of a volume it
+ * manages.  This is usually in response to a factory reset, when we want
+ * to undo the crypto mapping so the volume is formatted in the clear.
+ */
+int cryptfs_revert_volume(const char *label)
+{
+    return delete_crypto_blk_dev((char *)label);
+}
+
+/*
+ * Called by vold when it's asked to mount an encrypted, nonremovable volume.
+ * Setup a dm-crypt mapping, use the saved master key from
+ * setting up the /data mapping, and return the new device path.
+ */
+int cryptfs_setup_volume(const char *label, int major, int minor,
+                         char *crypto_sys_path, unsigned int max_path,
+                         int *new_major, int *new_minor)
+{
+    char real_blkdev[MAXPATHLEN], crypto_blkdev[MAXPATHLEN];
+    struct crypt_mnt_ftr sd_crypt_ftr;
+    struct stat statbuf;
+    int nr_sec, fd;
+
+    sprintf(real_blkdev, "/dev/block/vold/%d:%d", major, minor);
+
+    get_crypt_ftr_and_key(&sd_crypt_ftr);
+
+    /* Update the fs_size field to be the size of the volume */
+    fd = open(real_blkdev, O_RDONLY);
+    nr_sec = get_blkdev_size(fd);
+    close(fd);
+    if (nr_sec == 0) {
+        printf("Cannot get size of volume %s\n", real_blkdev);
+        return -1;
+    }
+
+    sd_crypt_ftr.fs_size = nr_sec;
+    create_crypto_blk_dev(&sd_crypt_ftr, saved_master_key, real_blkdev, 
+                          crypto_blkdev, label);
+
+    stat(crypto_blkdev, &statbuf);
+    *new_major = MAJOR(statbuf.st_rdev);
+    *new_minor = MINOR(statbuf.st_rdev);
+
+    /* Create path to sys entry for this block device */
+    snprintf(crypto_sys_path, max_path, "/devices/virtual/block/%s", strrchr(crypto_blkdev, '/')+1);
+
+    return 0;
+}
+
+int cryptfs_crypto_complete(void)
+{
+  return do_crypto_complete("/data");
+}
+
+int check_unmounted_and_get_ftr(struct crypt_mnt_ftr* crypt_ftr)
+{
+    char encrypted_state[PROPERTY_VALUE_MAX];
+    property_get("ro.crypto.state", encrypted_state, "");
+    if ( master_key_saved || strcmp(encrypted_state, "encrypted") ) {
+        printf("encrypted fs already validated or not running with encryption,"
+              " aborting");
+        return -1;
+    }
+
+    if (get_crypt_ftr_and_key(crypt_ftr)) {
+        printf("Error getting crypt footer and key");
+        return -1;
+    }
+
+    return 0;
+}
+
+/*
+ * TODO - transition patterns to new format in calling code
+ *        and remove this vile hack, and the use of hex in
+ *        the password passing code.
+ *
+ * Patterns are passed in zero based (i.e. the top left dot
+ * is represented by zero, the top middle one etc), but we want
+ * to store them '1' based.
+ * This is to allow us to migrate the calling code to use this
+ * convention. It also solves a nasty problem whereby scrypt ignores
+ * trailing zeros, so patterns ending at the top left could be
+ * truncated, and similarly, you could add the top left to any
+ * pattern and still match.
+ * adjust_passwd is a hack function that returns the alternate representation
+ * if the password appears to be a pattern (hex numbers all less than 09)
+ * If it succeeds we need to try both, and in particular try the alternate
+ * first. If the original matches, then we need to update the footer
+ * with the alternate.
+ * All code that accepts passwords must adjust them first. Since
+ * cryptfs_check_passwd is always the first function called after a migration
+ * (and indeed on any boot) we only need to do the double try in this
+ * function.
+ */
+char* adjust_passwd(const char* passwd)
+{
+    size_t index, length;
+
+    if (!passwd) {
+        return 0;
+    }
+
+    // Check even length. Hex encoded passwords are always
+    // an even length, since each character encodes to two characters.
+    length = strlen(passwd);
+    if (length % 2) {
+        printf("Password not correctly hex encoded.");
+        return 0;
+    }
+
+    // Check password is old-style pattern - a collection of hex
+    // encoded bytes less than 9 (00 through 08)
+    for (index = 0; index < length; index +=2) {
+        if (passwd[index] != '0'
+            || passwd[index + 1] < '0' || passwd[index + 1] > '8') {
+            return 0;
+        }
+    }
+
+    // Allocate room for adjusted passwd and null terminate
+    char* adjusted = malloc(length + 1);
+    adjusted[length] = 0;
+
+    // Add 0x31 ('1') to each character
+    for (index = 0; index < length; index += 2) {
+        // output is 31 through 39 so set first byte to three, second to src + 1
+        adjusted[index] = '3';
+        adjusted[index + 1] = passwd[index + 1] + 1;
+    }
+
+    return adjusted;
+}
+
+/*
+ * Passwords in L get passed from Android to cryptfs in hex, so a '1'
+ * gets converted to '31' where 31 is 0x31 which is the ascii character
+ * code in hex of the character '1'. This function will convert the
+ * regular character codes to their hexadecimal representation to make
+ * decrypt work properly with Android 5.0 lollipop decryption.
+ */
+char* hexadj_passwd(const char* passwd)
+{
+    size_t index, length;
+    char* ptr = passwd;
+
+    if (!passwd) {
+        return 0;
+    }
+
+    length = strlen(passwd);
+
+    // Allocate room for hex passwd and null terminate
+    char* hex = malloc((length * 2) + 1);
+    hex[length * 2] = 0;
+
+    // Convert to hex
+    for (index = 0; index < length; index++) {
+        sprintf(hex + (index * 2), "%02X", *ptr);
+        ptr++;
+    }
+
+    return hex;
+}
+
+#define FSTAB_PREFIX "/fstab."
+
+int cryptfs_check_footer(void)
+{
+    int rc = -1;
+    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
+    char propbuf[PROPERTY_VALUE_MAX];
+    struct crypt_mnt_ftr crypt_ftr;
+
+    property_get("ro.hardware", propbuf, "");
+    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
+
+    fstab = fs_mgr_read_fstab(fstab_filename);
+    if (!fstab) {
+        printf("failed to open %s\n", fstab_filename);
+        return -1;
+    }
+
+    rc = get_crypt_ftr_and_key(&crypt_ftr);
+
+    return rc;
+}
+
+int cryptfs_check_passwd(char *passwd)
+{
+    struct crypt_mnt_ftr crypt_ftr;
+    int rc;
+    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
+    char propbuf[PROPERTY_VALUE_MAX];
+
+    property_get("ro.hardware", propbuf, "");
+    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
+
+    fstab = fs_mgr_read_fstab(fstab_filename);
+    if (!fstab) {
+        printf("failed to open %s\n", fstab_filename);
+        return -1;
+    }
+
+    rc = check_unmounted_and_get_ftr(&crypt_ftr);
+    if (rc)
+        return rc;
+
+    char* adjusted_passwd = adjust_passwd(passwd);
+    char* hex_passwd = hexadj_passwd(passwd);
+
+    if (adjusted_passwd) {
+        int failed_decrypt_count = crypt_ftr.failed_decrypt_count;
+        rc = test_mount_encrypted_fs(&crypt_ftr, adjusted_passwd,
+                                     DATA_MNT_POINT, "userdata");
+
+        // Maybe the original one still works?
+        if (rc) {
+            // Don't double count this failure
+            crypt_ftr.failed_decrypt_count = failed_decrypt_count;
+            rc = test_mount_encrypted_fs(&crypt_ftr, passwd,
+                                         DATA_MNT_POINT, "userdata");
+            if (!rc) {
+                // cryptfs_changepw also adjusts so pass original
+                // Note that adjust_passwd only recognises patterns
+                // so we can safely use CRYPT_TYPE_PATTERN
+                printf("TWRP NOT Updating pattern to new format");
+                //cryptfs_changepw(CRYPT_TYPE_PATTERN, passwd);
+            } else if (hex_passwd) {
+                rc = test_mount_encrypted_fs(&crypt_ftr, hex_passwd,
+                                         DATA_MNT_POINT, "userdata");
+            }
+        }
+        free(adjusted_passwd);
+    } else {
+        rc = test_mount_encrypted_fs(&crypt_ftr, passwd,
+                                     DATA_MNT_POINT, "userdata");
+        if (rc && hex_passwd) {
+            rc = test_mount_encrypted_fs(&crypt_ftr, hex_passwd,
+                                     DATA_MNT_POINT, "userdata");
+        }
+    }
+
+    if (hex_passwd)
+        free(hex_passwd);
+
+    /*if (rc == 0 && crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) {
+		printf("cryptfs_check_passwd update expiry time?\n");
+        cryptfs_clear_password();
+        password = strdup(passwd);
+        struct timespec now;
+        clock_gettime(CLOCK_BOOTTIME, &now);
+        password_expiry_time = now.tv_sec + password_max_age_seconds;
+    }*/
+
+    return rc;
+}
+
+int cryptfs_verify_passwd(char *passwd)
+{
+    struct crypt_mnt_ftr crypt_ftr;
+    /* Allocate enough space for a 256 bit key, but we may use less */
+    unsigned char decrypted_master_key[32];
+    char encrypted_state[PROPERTY_VALUE_MAX];
+    int rc;
+
+    property_get("ro.crypto.state", encrypted_state, "");
+    if (strcmp(encrypted_state, "encrypted") ) {
+        printf("device not encrypted, aborting");
+        return -2;
+    }
+
+    if (!master_key_saved) {
+        printf("encrypted fs not yet mounted, aborting");
+        return -1;
+    }
+
+    if (!saved_mount_point) {
+        printf("encrypted fs failed to save mount point, aborting");
+        return -1;
+    }
+
+    if (get_crypt_ftr_and_key(&crypt_ftr)) {
+        printf("Error getting crypt footer and key\n");
+        return -1;
+    }
+
+    if (crypt_ftr.flags & CRYPT_MNT_KEY_UNENCRYPTED) {
+        /* If the device has no password, then just say the password is valid */
+        rc = 0;
+    } else {
+        char* adjusted_passwd = adjust_passwd(passwd);
+        if (adjusted_passwd) {
+            passwd = adjusted_passwd;
+        }
+
+        decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr, 0, 0);
+        if (!memcmp(decrypted_master_key, saved_master_key, crypt_ftr.keysize)) {
+            /* They match, the password is correct */
+            rc = 0;
+        } else {
+            /* If incorrect, sleep for a bit to prevent dictionary attacks */
+            sleep(1);
+            rc = 1;
+        }
+
+        free(adjusted_passwd);
+    }
+
+    return rc;
+}
+
+/* Initialize a crypt_mnt_ftr structure.  The keysize is
+ * defaulted to 16 bytes, and the filesystem size to 0.
+ * Presumably, at a minimum, the caller will update the
+ * filesystem size and crypto_type_name after calling this function.
+ */
+static int cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr *ftr)
+{
+    off64_t off;
+
+    memset(ftr, 0, sizeof(struct crypt_mnt_ftr));
+    ftr->magic = CRYPT_MNT_MAGIC;
+    ftr->major_version = CURRENT_MAJOR_VERSION;
+    ftr->minor_version = CURRENT_MINOR_VERSION;
+    ftr->ftr_size = sizeof(struct crypt_mnt_ftr);
+    ftr->keysize = KEY_LEN_BYTES;
+
+    switch (keymaster_check_compatibility()) {
+    case 1:
+        ftr->kdf_type = KDF_SCRYPT_KEYMASTER;
+        break;
+
+    case 0:
+        ftr->kdf_type = KDF_SCRYPT;
+        break;
+
+    default:
+        printf("keymaster_check_compatibility failed");
+        return -1;
+    }
+
+    get_device_scrypt_params(ftr);
+
+    ftr->persist_data_size = CRYPT_PERSIST_DATA_SIZE;
+    if (get_crypt_ftr_info(NULL, &off) == 0) {
+        ftr->persist_data_offset[0] = off + CRYPT_FOOTER_TO_PERSIST_OFFSET;
+        ftr->persist_data_offset[1] = off + CRYPT_FOOTER_TO_PERSIST_OFFSET +
+                                    ftr->persist_data_size;
+    }
+
+    return 0;
+}
+
+static int cryptfs_enable_wipe(char *crypto_blkdev, off64_t size, int type)
+{
+    const char *args[10];
+    char size_str[32]; /* Must be large enough to hold a %lld and null byte */
+    int num_args;
+    int status;
+    int tmp;
+    int rc = -1;
+
+    if (type == EXT4_FS) {
+        args[0] = "/system/bin/make_ext4fs";
+        args[1] = "-a";
+        args[2] = "/data";
+        args[3] = "-l";
+        snprintf(size_str, sizeof(size_str), "%" PRId64, size * 512);
+        args[4] = size_str;
+        args[5] = crypto_blkdev;
+        num_args = 6;
+        printf("Making empty filesystem with command %s %s %s %s %s %s\n",
+              args[0], args[1], args[2], args[3], args[4], args[5]);
+    } else if (type == F2FS_FS) {
+        args[0] = "/system/bin/mkfs.f2fs";
+        args[1] = "-t";
+        args[2] = "-d1";
+        args[3] = crypto_blkdev;
+        snprintf(size_str, sizeof(size_str), "%" PRId64, size);
+        args[4] = size_str;
+        num_args = 5;
+        printf("Making empty filesystem with command %s %s %s %s %s\n",
+              args[0], args[1], args[2], args[3], args[4]);
+    } else {
+        printf("cryptfs_enable_wipe(): unknown filesystem type %d\n", type);
+        return -1;
+    }
+
+    tmp = android_fork_execvp(num_args, (char **)args, &status, false, true);
+
+    if (tmp != 0) {
+      printf("Error creating empty filesystem on %s due to logwrap error\n", crypto_blkdev);
+    } else {
+        if (WIFEXITED(status)) {
+            if (WEXITSTATUS(status)) {
+                printf("Error creating filesystem on %s, exit status %d ",
+                      crypto_blkdev, WEXITSTATUS(status));
+            } else {
+                printf("Successfully created filesystem on %s\n", crypto_blkdev);
+                rc = 0;
+            }
+        } else {
+            printf("Error creating filesystem on %s, did not exit normally\n", crypto_blkdev);
+       }
+    }
+
+    return rc;
+}
+
+#define CRYPT_INPLACE_BUFSIZE 4096
+#define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / CRYPT_SECTOR_SIZE)
+#define CRYPT_SECTOR_SIZE 512
+
+/* aligned 32K writes tends to make flash happy.
+ * SD card association recommends it.
+ */
+#define BLOCKS_AT_A_TIME 8
+
+struct encryptGroupsData
+{
+    int realfd;
+    int cryptofd;
+    off64_t numblocks;
+    off64_t one_pct, cur_pct, new_pct;
+    off64_t blocks_already_done, tot_numblocks;
+    off64_t used_blocks_already_done, tot_used_blocks;
+    char* real_blkdev, * crypto_blkdev;
+    int count;
+    off64_t offset;
+    char* buffer;
+    off64_t last_written_sector;
+    int completed;
+    time_t time_started;
+    int remaining_time;
+};
+
+static void update_progress(struct encryptGroupsData* data, int is_used)
+{
+    data->blocks_already_done++;
+
+    if (is_used) {
+        data->used_blocks_already_done++;
+    }
+    if (data->tot_used_blocks) {
+        data->new_pct = data->used_blocks_already_done / data->one_pct;
+    } else {
+        data->new_pct = data->blocks_already_done / data->one_pct;
+    }
+
+    if (data->new_pct > data->cur_pct) {
+        char buf[8];
+        data->cur_pct = data->new_pct;
+        snprintf(buf, sizeof(buf), "%" PRId64, data->cur_pct);
+        property_set("vold.encrypt_progress", buf);
+    }
+
+    if (data->cur_pct >= 5) {
+        struct timespec time_now;
+        if (clock_gettime(CLOCK_MONOTONIC, &time_now)) {
+            printf("Error getting time");
+        } else {
+            double elapsed_time = difftime(time_now.tv_sec, data->time_started);
+            off64_t remaining_blocks = data->tot_used_blocks
+                                       - data->used_blocks_already_done;
+            int remaining_time = (int)(elapsed_time * remaining_blocks
+                                       / data->used_blocks_already_done);
+
+            // Change time only if not yet set, lower, or a lot higher for
+            // best user experience
+            if (data->remaining_time == -1
+                || remaining_time < data->remaining_time
+                || remaining_time > data->remaining_time + 60) {
+                char buf[8];
+                snprintf(buf, sizeof(buf), "%d", remaining_time);
+                property_set("vold.encrypt_time_remaining", buf);
+                data->remaining_time = remaining_time;
+            }
+        }
+    }
+}
+
+static void log_progress(struct encryptGroupsData const* data, bool completed)
+{
+    // Precondition - if completed data = 0 else data != 0
+
+    // Track progress so we can skip logging blocks
+    static off64_t offset = -1;
+
+    // Need to close existing 'Encrypting from' log?
+    if (completed || (offset != -1 && data->offset != offset)) {
+        printf("Encrypted to sector %" PRId64,
+              offset / info.block_size * CRYPT_SECTOR_SIZE);
+        offset = -1;
+    }
+
+    // Need to start new 'Encrypting from' log?
+    if (!completed && offset != data->offset) {
+        printf("Encrypting from sector %" PRId64,
+              data->offset / info.block_size * CRYPT_SECTOR_SIZE);
+    }
+
+    // Update offset
+    if (!completed) {
+        offset = data->offset + (off64_t)data->count * info.block_size;
+    }
+}
+
+static int flush_outstanding_data(struct encryptGroupsData* data)
+{
+    if (data->count == 0) {
+        return 0;
+    }
+
+    printf("Copying %d blocks at offset %" PRIx64, data->count, data->offset);
+
+    if (pread64(data->realfd, data->buffer,
+                info.block_size * data->count, data->offset)
+        <= 0) {
+        printf("Error reading real_blkdev %s for inplace encrypt",
+              data->real_blkdev);
+        return -1;
+    }
+
+    if (pwrite64(data->cryptofd, data->buffer,
+                 info.block_size * data->count, data->offset)
+        <= 0) {
+        printf("Error writing crypto_blkdev %s for inplace encrypt",
+              data->crypto_blkdev);
+        return -1;
+    } else {
+      log_progress(data, false);
+    }
+
+    data->count = 0;
+    data->last_written_sector = (data->offset + data->count)
+                                / info.block_size * CRYPT_SECTOR_SIZE - 1;
+    return 0;
+}
+
+static int encrypt_groups(struct encryptGroupsData* data)
+{
+    unsigned int i;
+    u8 *block_bitmap = 0;
+    unsigned int block;
+    off64_t ret;
+    int rc = -1;
+
+    data->buffer = malloc(info.block_size * BLOCKS_AT_A_TIME);
+    if (!data->buffer) {
+        printf("Failed to allocate crypto buffer");
+        goto errout;
+    }
+
+    block_bitmap = malloc(info.block_size);
+    if (!block_bitmap) {
+        printf("failed to allocate block bitmap");
+        goto errout;
+    }
+
+    for (i = 0; i < aux_info.groups; ++i) {
+        printf("Encrypting group %d", i);
+
+        u32 first_block = aux_info.first_data_block + i * info.blocks_per_group;
+        u32 block_count = min(info.blocks_per_group,
+                             aux_info.len_blocks - first_block);
+
+        off64_t offset = (u64)info.block_size
+                         * aux_info.bg_desc[i].bg_block_bitmap;
+
+        ret = pread64(data->realfd, block_bitmap, info.block_size, offset);
+        if (ret != (int)info.block_size) {
+            printf("failed to read all of block group bitmap %d", i);
+            goto errout;
+        }
+
+        offset = (u64)info.block_size * first_block;
+
+        data->count = 0;
+
+        for (block = 0; block < block_count; block++) {
+            int used = bitmap_get_bit(block_bitmap, block);
+            update_progress(data, used);
+            if (used) {
+                if (data->count == 0) {
+                    data->offset = offset;
+                }
+                data->count++;
+            } else {
+                if (flush_outstanding_data(data)) {
+                    goto errout;
+                }
+            }
+
+            offset += info.block_size;
+
+            /* Write data if we are aligned or buffer size reached */
+            if (offset % (info.block_size * BLOCKS_AT_A_TIME) == 0
+                || data->count == BLOCKS_AT_A_TIME) {
+                if (flush_outstanding_data(data)) {
+                    goto errout;
+                }
+            }
+
+            if (1) {
+                printf("Stopping encryption due to low battery");
+                rc = 0;
+                goto errout;
+            }
+
+        }
+        if (flush_outstanding_data(data)) {
+            goto errout;
+        }
+    }
+
+    data->completed = 1;
+    rc = 0;
+
+errout:
+    log_progress(0, true);
+    free(data->buffer);
+    free(block_bitmap);
+    return rc;
+}
+
+static int cryptfs_enable_inplace_ext4(char *crypto_blkdev,
+                                       char *real_blkdev,
+                                       off64_t size,
+                                       off64_t *size_already_done,
+                                       off64_t tot_size,
+                                       off64_t previously_encrypted_upto)
+{
+    u32 i;
+    struct encryptGroupsData data;
+    int rc; // Can't initialize without causing warning -Wclobbered
+
+    if (previously_encrypted_upto > *size_already_done) {
+        printf("Not fast encrypting since resuming part way through");
+        return -1;
+    }
+
+    memset(&data, 0, sizeof(data));
+    data.real_blkdev = real_blkdev;
+    data.crypto_blkdev = crypto_blkdev;
+
+    if ( (data.realfd = open(real_blkdev, O_RDWR)) < 0) {
+        printf("Error opening real_blkdev %s for inplace encrypt. err=%d(%s)\n",
+              real_blkdev, errno, strerror(errno));
+        rc = -1;
+        goto errout;
+    }
+
+    if ( (data.cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) {
+        printf("Error opening crypto_blkdev %s for ext4 inplace encrypt. err=%d(%s)\n",
+              crypto_blkdev, errno, strerror(errno));
+        rc = ENABLE_INPLACE_ERR_DEV;
+        goto errout;
+    }
+
+    if (setjmp(setjmp_env)) {
+        printf("Reading ext4 extent caused an exception\n");
+        rc = -1;
+        goto errout;
+    }
+
+    if (read_ext(data.realfd, 0) != 0) {
+        printf("Failed to read ext4 extent\n");
+        rc = -1;
+        goto errout;
+    }
+
+    data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
+    data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
+    data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
+
+    printf("Encrypting ext4 filesystem in place...");
+
+    data.tot_used_blocks = data.numblocks;
+    for (i = 0; i < aux_info.groups; ++i) {
+      data.tot_used_blocks -= aux_info.bg_desc[i].bg_free_blocks_count;
+    }
+
+    data.one_pct = data.tot_used_blocks / 100;
+    data.cur_pct = 0;
+
+    struct timespec time_started = {0};
+    if (clock_gettime(CLOCK_MONOTONIC, &time_started)) {
+        printf("Error getting time at start");
+        // Note - continue anyway - we'll run with 0
+    }
+    data.time_started = time_started.tv_sec;
+    data.remaining_time = -1;
+
+    rc = encrypt_groups(&data);
+    if (rc) {
+        printf("Error encrypting groups");
+        goto errout;
+    }
+
+    *size_already_done += data.completed ? size : data.last_written_sector;
+    rc = 0;
+
+errout:
+    close(data.realfd);
+    close(data.cryptofd);
+
+    return rc;
+}
+
+static void log_progress_f2fs(u64 block, bool completed)
+{
+    // Precondition - if completed data = 0 else data != 0
+
+    // Track progress so we can skip logging blocks
+    static u64 last_block = (u64)-1;
+
+    // Need to close existing 'Encrypting from' log?
+    if (completed || (last_block != (u64)-1 && block != last_block + 1)) {
+        printf("Encrypted to block %" PRId64, last_block);
+        last_block = -1;
+    }
+
+    // Need to start new 'Encrypting from' log?
+    if (!completed && (last_block == (u64)-1 || block != last_block + 1)) {
+        printf("Encrypting from block %" PRId64, block);
+    }
+
+    // Update offset
+    if (!completed) {
+        last_block = block;
+    }
+}
+
+static int encrypt_one_block_f2fs(u64 pos, void *data)
+{
+    struct encryptGroupsData *priv_dat = (struct encryptGroupsData *)data;
+
+    priv_dat->blocks_already_done = pos - 1;
+    update_progress(priv_dat, 1);
+
+    off64_t offset = pos * CRYPT_INPLACE_BUFSIZE;
+
+    if (pread64(priv_dat->realfd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
+        printf("Error reading real_blkdev %s for f2fs inplace encrypt", priv_dat->crypto_blkdev);
+        return -1;
+    }
+
+    if (pwrite64(priv_dat->cryptofd, priv_dat->buffer, CRYPT_INPLACE_BUFSIZE, offset) <= 0) {
+        printf("Error writing crypto_blkdev %s for f2fs inplace encrypt", priv_dat->crypto_blkdev);
+        return -1;
+    } else {
+        log_progress_f2fs(pos, false);
+    }
+
+    return 0;
+}
+
+static int cryptfs_enable_inplace_f2fs(char *crypto_blkdev,
+                                       char *real_blkdev,
+                                       off64_t size,
+                                       off64_t *size_already_done,
+                                       off64_t tot_size,
+                                       off64_t previously_encrypted_upto)
+{
+    u32 i;
+    struct encryptGroupsData data;
+    struct f2fs_info *f2fs_info = NULL;
+    int rc = ENABLE_INPLACE_ERR_OTHER;
+    if (previously_encrypted_upto > *size_already_done) {
+        printf("Not fast encrypting since resuming part way through");
+        return ENABLE_INPLACE_ERR_OTHER;
+    }
+    memset(&data, 0, sizeof(data));
+    data.real_blkdev = real_blkdev;
+    data.crypto_blkdev = crypto_blkdev;
+    data.realfd = -1;
+    data.cryptofd = -1;
+    if ( (data.realfd = open64(real_blkdev, O_RDWR)) < 0) {
+        printf("Error opening real_blkdev %s for f2fs inplace encrypt\n",
+              real_blkdev);
+        goto errout;
+    }
+    if ( (data.cryptofd = open64(crypto_blkdev, O_WRONLY)) < 0) {
+        printf("Error opening crypto_blkdev %s for f2fs inplace encrypt. err=%d(%s)\n",
+              crypto_blkdev, errno, strerror(errno));
+        rc = ENABLE_INPLACE_ERR_DEV;
+        goto errout;
+    }
+
+    f2fs_info = generate_f2fs_info(data.realfd);
+    if (!f2fs_info)
+      goto errout;
+
+    data.numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
+    data.tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
+    data.blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
+
+    data.tot_used_blocks = get_num_blocks_used(f2fs_info);
+
+    data.one_pct = data.tot_used_blocks / 100;
+    data.cur_pct = 0;
+    data.time_started = time(NULL);
+    data.remaining_time = -1;
+
+    data.buffer = malloc(f2fs_info->block_size);
+    if (!data.buffer) {
+        printf("Failed to allocate crypto buffer");
+        goto errout;
+    }
+
+    data.count = 0;
+
+    /* Currently, this either runs to completion, or hits a nonrecoverable error */
+    rc = run_on_used_blocks(data.blocks_already_done, f2fs_info, &encrypt_one_block_f2fs, &data);
+
+    if (rc) {
+        printf("Error in running over f2fs blocks");
+        rc = ENABLE_INPLACE_ERR_OTHER;
+        goto errout;
+    }
+
+    *size_already_done += size;
+    rc = 0;
+
+errout:
+    if (rc)
+        printf("Failed to encrypt f2fs filesystem on %s", real_blkdev);
+
+    log_progress_f2fs(0, true);
+    free(f2fs_info);
+    free(data.buffer);
+    close(data.realfd);
+    close(data.cryptofd);
+
+    return rc;
+}
+
+static int cryptfs_enable_inplace_full(char *crypto_blkdev, char *real_blkdev,
+                                       off64_t size, off64_t *size_already_done,
+                                       off64_t tot_size,
+                                       off64_t previously_encrypted_upto)
+{
+    int realfd, cryptofd;
+    char *buf[CRYPT_INPLACE_BUFSIZE];
+    int rc = ENABLE_INPLACE_ERR_OTHER;
+    off64_t numblocks, i, remainder;
+    off64_t one_pct, cur_pct, new_pct;
+    off64_t blocks_already_done, tot_numblocks;
+
+    if ( (realfd = open(real_blkdev, O_RDONLY)) < 0) { 
+        printf("Error opening real_blkdev %s for inplace encrypt\n", real_blkdev);
+        return ENABLE_INPLACE_ERR_OTHER;
+    }
+
+    if ( (cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) { 
+        printf("Error opening crypto_blkdev %s for inplace encrypt. err=%d(%s)\n",
+              crypto_blkdev, errno, strerror(errno));
+        close(realfd);
+        return ENABLE_INPLACE_ERR_DEV;
+    }
+
+    /* This is pretty much a simple loop of reading 4K, and writing 4K.
+     * The size passed in is the number of 512 byte sectors in the filesystem.
+     * So compute the number of whole 4K blocks we should read/write,
+     * and the remainder.
+     */
+    numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
+    remainder = size % CRYPT_SECTORS_PER_BUFSIZE;
+    tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
+    blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
+
+    printf("Encrypting filesystem in place...");
+
+    i = previously_encrypted_upto + 1 - *size_already_done;
+
+    if (lseek64(realfd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) {
+        printf("Cannot seek to previously encrypted point on %s", real_blkdev);
+        goto errout;
+    }
+
+    if (lseek64(cryptofd, i * CRYPT_SECTOR_SIZE, SEEK_SET) < 0) {
+        printf("Cannot seek to previously encrypted point on %s", crypto_blkdev);
+        goto errout;
+    }
+
+    for (;i < size && i % CRYPT_SECTORS_PER_BUFSIZE != 0; ++i) {
+        if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
+            printf("Error reading initial sectors from real_blkdev %s for "
+                  "inplace encrypt\n", crypto_blkdev);
+            goto errout;
+        }
+        if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) {
+            printf("Error writing initial sectors to crypto_blkdev %s for "
+                  "inplace encrypt\n", crypto_blkdev);
+            goto errout;
+        } else {
+            printf("Encrypted 1 block at %" PRId64, i);
+        }
+    }
+
+    one_pct = tot_numblocks / 100;
+    cur_pct = 0;
+    /* process the majority of the filesystem in blocks */
+    for (i/=CRYPT_SECTORS_PER_BUFSIZE; i<numblocks; i++) {
+        new_pct = (i + blocks_already_done) / one_pct;
+        if (new_pct > cur_pct) {
+            char buf[8];
+
+            cur_pct = new_pct;
+            snprintf(buf, sizeof(buf), "%" PRId64, cur_pct);
+            property_set("vold.encrypt_progress", buf);
+        }
+        if (unix_read(realfd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
+            printf("Error reading real_blkdev %s for inplace encrypt", crypto_blkdev);
+            goto errout;
+        }
+        if (unix_write(cryptofd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
+            printf("Error writing crypto_blkdev %s for inplace encrypt", crypto_blkdev);
+            goto errout;
+        } else {
+            printf("Encrypted %d block at %" PRId64,
+                  CRYPT_SECTORS_PER_BUFSIZE,
+                  i * CRYPT_SECTORS_PER_BUFSIZE);
+        }
+
+       if (1) {
+            printf("Stopping encryption due to low battery");
+            *size_already_done += (i + 1) * CRYPT_SECTORS_PER_BUFSIZE - 1;
+            rc = 0;
+            goto errout;
+        }
+    }
+
+    /* Do any remaining sectors */
+    for (i=0; i<remainder; i++) {
+        if (unix_read(realfd, buf, CRYPT_SECTOR_SIZE) <= 0) {
+            printf("Error reading final sectors from real_blkdev %s for inplace encrypt", crypto_blkdev);
+            goto errout;
+        }
+        if (unix_write(cryptofd, buf, CRYPT_SECTOR_SIZE) <= 0) {
+            printf("Error writing final sectors to crypto_blkdev %s for inplace encrypt", crypto_blkdev);
+            goto errout;
+        } else {
+            printf("Encrypted 1 block at next location");
+        }
+    }
+
+    *size_already_done += size;
+    rc = 0;
+
+errout:
+    close(realfd);
+    close(cryptofd);
+
+    return rc;
+}
+
+/* returns on of the ENABLE_INPLACE_* return codes */
+static int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev,
+                                  off64_t size, off64_t *size_already_done,
+                                  off64_t tot_size,
+                                  off64_t previously_encrypted_upto)
+{
+    int rc_ext4, rc_f2fs, rc_full;
+    if (previously_encrypted_upto) {
+        printf("Continuing encryption from %" PRId64, previously_encrypted_upto);
+    }
+
+    if (*size_already_done + size < previously_encrypted_upto) {
+        *size_already_done += size;
+        return 0;
+    }
+
+    /* TODO: identify filesystem type.
+     * As is, cryptfs_enable_inplace_ext4 will fail on an f2fs partition, and
+     * then we will drop down to cryptfs_enable_inplace_f2fs.
+     * */
+    if ((rc_ext4 = cryptfs_enable_inplace_ext4(crypto_blkdev, real_blkdev,
+                                size, size_already_done,
+                                tot_size, previously_encrypted_upto)) == 0) {
+      return 0;
+    }
+    printf("cryptfs_enable_inplace_ext4()=%d\n", rc_ext4);
+
+    if ((rc_f2fs = cryptfs_enable_inplace_f2fs(crypto_blkdev, real_blkdev,
+                                size, size_already_done,
+                                tot_size, previously_encrypted_upto)) == 0) {
+      return 0;
+    }
+    printf("cryptfs_enable_inplace_f2fs()=%d\n", rc_f2fs);
+
+    rc_full = cryptfs_enable_inplace_full(crypto_blkdev, real_blkdev,
+                                       size, size_already_done, tot_size,
+                                       previously_encrypted_upto);
+    printf("cryptfs_enable_inplace_full()=%d\n", rc_full);
+
+    /* Hack for b/17898962, the following is the symptom... */
+    if (rc_ext4 == ENABLE_INPLACE_ERR_DEV
+        && rc_f2fs == ENABLE_INPLACE_ERR_DEV
+        && rc_full == ENABLE_INPLACE_ERR_DEV) {
+            return ENABLE_INPLACE_ERR_DEV;
+    }
+    return rc_full;
+}
+
+#define CRYPTO_ENABLE_WIPE 1
+#define CRYPTO_ENABLE_INPLACE 2
+
+#define FRAMEWORK_BOOT_WAIT 60
+
+static inline int should_encrypt(struct volume_info *volume)
+{
+    return (volume->flags & (VOL_ENCRYPTABLE | VOL_NONREMOVABLE)) ==
+            (VOL_ENCRYPTABLE | VOL_NONREMOVABLE);
+}
+
+static int cryptfs_SHA256_fileblock(const char* filename, __le8* buf)
+{
+    int fd = open(filename, O_RDONLY);
+    if (fd == -1) {
+        printf("Error opening file %s", filename);
+        return -1;
+    }
+
+    char block[CRYPT_INPLACE_BUFSIZE];
+    memset(block, 0, sizeof(block));
+    if (unix_read(fd, block, sizeof(block)) < 0) {
+        printf("Error reading file %s", filename);
+        close(fd);
+        return -1;
+    }
+
+    close(fd);
+
+    SHA256_CTX c;
+    SHA256_Init(&c);
+    SHA256_Update(&c, block, sizeof(block));
+    SHA256_Final(buf, &c);
+
+    return 0;
+}
+
+static int get_fs_type(struct fstab_rec *rec)
+{
+    if (!strcmp(rec->fs_type, "ext4")) {
+        return EXT4_FS;
+    } else if (!strcmp(rec->fs_type, "f2fs")) {
+        return F2FS_FS;
+    } else {
+        return -1;
+    }
+}
+
+static int cryptfs_enable_all_volumes(struct crypt_mnt_ftr *crypt_ftr, int how,
+                                      char *crypto_blkdev, char *real_blkdev,
+                                      int previously_encrypted_upto)
+{
+    off64_t cur_encryption_done=0, tot_encryption_size=0;
+    int i, rc = -1;
+
+    if (1) {
+        printf("Not starting encryption due to low battery");
+        return 0;
+    }
+
+    /* The size of the userdata partition, and add in the vold volumes below */
+    tot_encryption_size = crypt_ftr->fs_size;
+
+    if (how == CRYPTO_ENABLE_WIPE) {
+        struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT);
+        int fs_type = get_fs_type(rec);
+        if (fs_type < 0) {
+            printf("cryptfs_enable: unsupported fs type %s\n", rec->fs_type);
+            return -1;
+        }
+        rc = cryptfs_enable_wipe(crypto_blkdev, crypt_ftr->fs_size, fs_type);
+    } else if (how == CRYPTO_ENABLE_INPLACE) {
+        rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev,
+                                    crypt_ftr->fs_size, &cur_encryption_done,
+                                    tot_encryption_size,
+                                    previously_encrypted_upto);
+
+        if (rc == ENABLE_INPLACE_ERR_DEV) {
+            /* Hack for b/17898962 */
+            printf("cryptfs_enable: crypto block dev failure. Must reboot...\n");
+            cryptfs_reboot(reboot);
+        }
+
+        if (!rc) {
+            crypt_ftr->encrypted_upto = cur_encryption_done;
+        }
+
+        if (!rc && crypt_ftr->encrypted_upto == crypt_ftr->fs_size) {
+            /* The inplace routine never actually sets the progress to 100% due
+             * to the round down nature of integer division, so set it here */
+            property_set("vold.encrypt_progress", "100");
+        }
+    } else {
+        /* Shouldn't happen */
+        printf("cryptfs_enable: internal error, unknown option\n");
+        rc = -1;
+    }
+
+    return rc;
+}
+
+int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
+                            int allow_reboot)
+{
+    int how = 0;
+    char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN];
+    unsigned long nr_sec;
+    unsigned char decrypted_master_key[KEY_LEN_BYTES];
+    int rc=-1, fd, i, ret;
+    struct crypt_mnt_ftr crypt_ftr;
+    struct crypt_persist_data *pdata;
+    char encrypted_state[PROPERTY_VALUE_MAX];
+    char lockid[32] = { 0 };
+    char key_loc[PROPERTY_VALUE_MAX];
+    char fuse_sdcard[PROPERTY_VALUE_MAX];
+    char *sd_mnt_point;
+    int num_vols;
+    struct volume_info *vol_list = 0;
+    off64_t previously_encrypted_upto = 0;
+printf("cryptfs_enable_internal disabled by TWRP\n");
+return -1;
+    if (!strcmp(howarg, "wipe")) {
+      how = CRYPTO_ENABLE_WIPE;
+    } else if (! strcmp(howarg, "inplace")) {
+      how = CRYPTO_ENABLE_INPLACE;
+    } else {
+      /* Shouldn't happen, as CommandListener vets the args */
+      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;
+
+        /* 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);
+    }
+
+    property_get("ro.crypto.state", encrypted_state, "");
+    if (!strcmp(encrypted_state, "encrypted") && !previously_encrypted_upto) {
+        printf("Device is already running encrypted, aborting");
+        goto error_unencrypted;
+    }
+
+    // TODO refactor fs_mgr_get_crypt_info to get both in one call
+    fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc));
+    fs_mgr_get_crypt_info(fstab, 0, real_blkdev, sizeof(real_blkdev));
+
+    /* Get the size of the real block device */
+    fd = open(real_blkdev, O_RDONLY);
+    if ( (nr_sec = get_blkdev_size(fd)) == 0) {
+        printf("Cannot get size of block device %s\n", real_blkdev);
+        goto error_unencrypted;
+    }
+    close(fd);
+
+    /* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */
+    if ((how == CRYPTO_ENABLE_INPLACE) && (!strcmp(key_loc, KEY_IN_FOOTER))) {
+        unsigned int fs_size_sec, max_fs_size_sec;
+        fs_size_sec = get_fs_size(real_blkdev);
+        if (fs_size_sec == 0)
+            fs_size_sec = get_f2fs_filesystem_size_sec(real_blkdev);
+
+        max_fs_size_sec = nr_sec - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
+
+        if (fs_size_sec > max_fs_size_sec) {
+            printf("Orig filesystem overlaps crypto footer region.  Cannot encrypt in place.");
+            goto error_unencrypted;
+        }
+    }
+
+    /* Get a wakelock as this may take a while, and we don't want the
+     * device to sleep on us.  We'll grab a partial wakelock, and if the UI
+     * wants to keep the screen on, it can grab a full wakelock.
+     */
+    snprintf(lockid, sizeof(lockid), "enablecrypto%d", (int) getpid());
+    acquire_wake_lock(PARTIAL_WAKE_LOCK, lockid);
+
+    /* Get the sdcard mount point */
+    sd_mnt_point = getenv("EMULATED_STORAGE_SOURCE");
+    if (!sd_mnt_point) {
+       sd_mnt_point = getenv("EXTERNAL_STORAGE");
+    }
+    if (!sd_mnt_point) {
+        sd_mnt_point = "/mnt/sdcard";
+    }
+
+    /* TODO
+     * Currently do not have test devices with multiple encryptable volumes.
+     * When we acquire some, re-add support.
+     */
+    num_vols=0/*vold_getNumDirectVolumes()*/;
+    vol_list = malloc(sizeof(struct volume_info) * num_vols);
+    //vold_getDirectVolumeList(vol_list);
+
+    for (i=0; i<num_vols; i++) {
+        if (should_encrypt(&vol_list[i])) {
+            printf("Cannot encrypt if there are multiple encryptable volumes"
+                  "%s\n", vol_list[i].label);
+            goto error_unencrypted;
+        }
+    }
+
+    /* The init files are setup to stop the class main and late start when
+     * vold sets trigger_shutdown_framework.
+     */
+    property_set("vold.decrypt", "trigger_shutdown_framework");
+    printf("Just asked init to shut down class main\n");
+
+    if (1 /*vold_unmountAllAsecs()*/) {
+        /* Just report the error.  If any are left mounted,
+         * umounting /data below will fail and handle the error.
+         */
+        printf("Error unmounting internal asecs");
+    }
+
+    property_get("ro.crypto.fuse_sdcard", fuse_sdcard, "");
+    if (!strcmp(fuse_sdcard, "true")) {
+        /* This is a device using the fuse layer to emulate the sdcard semantics
+         * on top of the userdata partition.  vold does not manage it, it is managed
+         * by the sdcard service.  The sdcard service was killed by the property trigger
+         * above, so just unmount it now.  We must do this _AFTER_ killing the framework,
+         * unlike the case for vold managed devices above.
+         */
+        if (wait_and_unmount(sd_mnt_point, false)) {
+            goto error_shutting_down;
+        }
+    }
+
+    /* Now unmount the /data partition. */
+    if (wait_and_unmount(DATA_MNT_POINT, false)) {
+        if (allow_reboot) {
+            goto error_shutting_down;
+        } else {
+            goto error_unencrypted;
+        }
+    }
+
+    /* Do extra work for a better UX when doing the long inplace encryption */
+    if (how == CRYPTO_ENABLE_INPLACE) {
+        /* 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.
+         */
+        if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) {
+            goto error_shutting_down;
+        }
+        /* Tells the framework that inplace encryption is starting */
+        property_set("vold.encrypt_progress", "0");
+
+        /* restart the framework. */
+        /* Create necessary paths on /data */
+        if (prep_data_fs()) {
+            goto error_shutting_down;
+        }
+
+        /* Ugh, shutting down the framework is not synchronous, so until it
+         * can be fixed, this horrible hack will wait a moment for it all to
+         * shut down before proceeding.  Without it, some devices cannot
+         * restart the graphics services.
+         */
+        sleep(2);
+
+        /* startup service classes main and late_start */
+        property_set("vold.decrypt", "trigger_restart_min_framework");
+        printf("Just triggered restart_min_framework\n");
+
+        /* OK, the framework is restarted and will soon be showing a
+         * progress bar.  Time to setup an encrypted mapping, and
+         * either write a new filesystem, or encrypt in place updating
+         * the progress bar as we work.
+         */
+    }
+
+    /* Start the actual work of making an encrypted filesystem */
+    /* Initialize a crypt_mnt_ftr for the partition */
+    if (previously_encrypted_upto == 0) {
+        if (cryptfs_init_crypt_mnt_ftr(&crypt_ftr)) {
+            goto error_shutting_down;
+        }
+
+        if (!strcmp(key_loc, KEY_IN_FOOTER)) {
+            crypt_ftr.fs_size = nr_sec
+              - (CRYPT_FOOTER_OFFSET / CRYPT_SECTOR_SIZE);
+        } else {
+            crypt_ftr.fs_size = nr_sec;
+        }
+        /* 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;
+        crypt_ftr.crypt_type = crypt_type;
+        strcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256");
+
+        /* Make an encrypted master key */
+        if (create_encrypted_random_key(passwd, crypt_ftr.master_key, crypt_ftr.salt, &crypt_ftr)) {
+            printf("Cannot create encrypted master key\n");
+            goto error_shutting_down;
+        }
+
+        /* Write the key to the end of the partition */
+        put_crypt_ftr_and_key(&crypt_ftr);
+
+        /* If any persistent data has been remembered, save it.
+         * If none, create a valid empty table and save that.
+         */
+        if (!persist_data) {
+           pdata = malloc(CRYPT_PERSIST_DATA_SIZE);
+           if (pdata) {
+               init_empty_persist_data(pdata, CRYPT_PERSIST_DATA_SIZE);
+               persist_data = pdata;
+           }
+        }
+        if (persist_data) {
+            save_persistent_data();
+        }
+    }
+
+    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");
+
+    /* If we are continuing, check checksums match */
+    rc = 0;
+    if (previously_encrypted_upto) {
+        __le8 hash_first_block[SHA256_DIGEST_LENGTH];
+        rc = cryptfs_SHA256_fileblock(crypto_blkdev, hash_first_block);
+
+        if (!rc && memcmp(hash_first_block, crypt_ftr.hash_first_block,
+                          sizeof(hash_first_block)) != 0) {
+            printf("Checksums do not match - trigger wipe");
+            rc = -1;
+        }
+    }
+
+    if (!rc) {
+        rc = cryptfs_enable_all_volumes(&crypt_ftr, how,
+                                        crypto_blkdev, real_blkdev,
+                                        previously_encrypted_upto);
+    }
+
+    /* Calculate checksum if we are not finished */
+    if (!rc && crypt_ftr.encrypted_upto != crypt_ftr.fs_size) {
+        rc = cryptfs_SHA256_fileblock(crypto_blkdev,
+                                      crypt_ftr.hash_first_block);
+        if (rc) {
+            printf("Error calculating checksum for continuing encryption");
+            rc = -1;
+        }
+    }
+
+    /* Undo the dm-crypt mapping whether we succeed or not */
+    delete_crypto_blk_dev("userdata");
+
+    free(vol_list);
+
+    if (! rc) {
+        /* Success */
+        crypt_ftr.flags &= ~CRYPT_INCONSISTENT_STATE;
+
+        if (crypt_ftr.encrypted_upto != crypt_ftr.fs_size) {
+            printf("Encrypted up to sector %lld - will continue after reboot",
+                  crypt_ftr.encrypted_upto);
+            crypt_ftr.flags |= CRYPT_ENCRYPTION_IN_PROGRESS;
+        }
+
+        put_crypt_ftr_and_key(&crypt_ftr);
+
+        if (crypt_ftr.encrypted_upto == crypt_ftr.fs_size) {
+          char value[PROPERTY_VALUE_MAX];
+          property_get("ro.crypto.state", value, "");
+          if (!strcmp(value, "")) {
+            /* default encryption - continue first boot sequence */
+            property_set("ro.crypto.state", "encrypted");
+            release_wake_lock(lockid);
+            cryptfs_check_passwd(DEFAULT_PASSWORD);
+            cryptfs_restart_internal(1);
+            return 0;
+          } else {
+            sleep(2); /* Give the UI a chance to show 100% progress */
+            cryptfs_reboot(reboot);
+          }
+        } else {
+            sleep(2); /* Partially encrypted, ensure writes flushed to ssd */
+            cryptfs_reboot(shutdown);
+        }
+    } else {
+        char value[PROPERTY_VALUE_MAX];
+
+        property_get("ro.vold.wipe_on_crypt_fail", value, "0");
+        if (!strcmp(value, "1")) {
+            /* wipe data if encryption failed */
+            printf("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, 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 {
+                printf("could not open /cache/recovery/command\n");
+            }
+            cryptfs_reboot(recovery);
+        } else {
+            /* set property to trigger dialog */
+            property_set("vold.encrypt_progress", "error_partially_encrypted");
+            release_wake_lock(lockid);
+        }
+        return -1;
+    }
+
+    /* hrm, the encrypt step claims success, but the reboot failed.
+     * This should not happen.
+     * Set the property and return.  Hope the framework can deal with it.
+     */
+    property_set("vold.encrypt_progress", "error_reboot_failed");
+    release_wake_lock(lockid);
+    return rc;
+
+error_unencrypted:
+    free(vol_list);
+    property_set("vold.encrypt_progress", "error_not_encrypted");
+    if (lockid[0]) {
+        release_wake_lock(lockid);
+    }
+    return -1;
+
+error_shutting_down:
+    /* we failed, and have not encrypted anthing, so the users's data is still intact,
+     * but the framework is stopped and not restarted to show the error, so it's up to
+     * vold to restart the system.
+     */
+    printf("Error enabling encryption after framework is shutdown, no data changed, restarting system");
+    cryptfs_reboot(reboot);
+
+    /* shouldn't get here */
+    property_set("vold.encrypt_progress", "error_shutting_down");
+    free(vol_list);
+    if (lockid[0]) {
+        release_wake_lock(lockid);
+    }
+    return -1;
+}
+
+int cryptfs_enable(char *howarg, int type, char *passwd, int allow_reboot)
+{
+    char* adjusted_passwd = adjust_passwd(passwd);
+    if (adjusted_passwd) {
+        passwd = adjusted_passwd;
+    }
+
+    int rc = cryptfs_enable_internal(howarg, type, passwd, allow_reboot);
+
+    free(adjusted_passwd);
+    return rc;
+}
+
+int cryptfs_enable_default(char *howarg, int allow_reboot)
+{
+    return cryptfs_enable_internal(howarg, CRYPT_TYPE_DEFAULT,
+                          DEFAULT_PASSWORD, allow_reboot);
+}
+
+int cryptfs_changepw(int crypt_type, const char *newpw)
+{
+    struct crypt_mnt_ftr crypt_ftr;
+    unsigned char decrypted_master_key[KEY_LEN_BYTES];
+
+    /* This is only allowed after we've successfully decrypted the master key */
+    if (!master_key_saved) {
+        printf("Key not saved, aborting");
+        return -1;
+    }
+
+    if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
+        printf("Invalid crypt_type %d", crypt_type);
+        return -1;
+    }
+
+    /* get key */
+    if (get_crypt_ftr_and_key(&crypt_ftr)) {
+        printf("Error getting crypt footer and key");
+        return -1;
+    }
+
+    crypt_ftr.crypt_type = crypt_type;
+
+    char* adjusted_passwd = adjust_passwd(newpw);
+    if (adjusted_passwd) {
+        newpw = adjusted_passwd;
+    }
+
+    encrypt_master_key(crypt_type == CRYPT_TYPE_DEFAULT ? DEFAULT_PASSWORD
+                                                        : newpw,
+                       crypt_ftr.salt,
+                       saved_master_key,
+                       crypt_ftr.master_key,
+                       &crypt_ftr);
+
+    /* save the key */
+    put_crypt_ftr_and_key(&crypt_ftr);
+
+    free(adjusted_passwd);
+    return 0;
+}
+
+static int persist_get_key(char *fieldname, char *value)
+{
+    unsigned int i;
+
+    if (persist_data == NULL) {
+        return -1;
+    }
+    for (i = 0; i < persist_data->persist_valid_entries; i++) {
+        if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) {
+            /* We found it! */
+            strlcpy(value, persist_data->persist_entry[i].val, PROPERTY_VALUE_MAX);
+            return 0;
+        }
+    }
+
+    return -1;
+}
+
+static int persist_set_key(char *fieldname, char *value, int encrypted)
+{
+    unsigned int i;
+    unsigned int num;
+    struct crypt_mnt_ftr crypt_ftr;
+    unsigned int max_persistent_entries;
+    unsigned int dsize;
+
+    if (persist_data == NULL) {
+        return -1;
+    }
+
+    /* If encrypted, use the values from the crypt_ftr, otherwise
+     * use the values for the current spec.
+     */
+    if (encrypted) {
+        if(get_crypt_ftr_and_key(&crypt_ftr)) {
+            return -1;
+        }
+        dsize = crypt_ftr.persist_data_size;
+    } else {
+        dsize = CRYPT_PERSIST_DATA_SIZE;
+    }
+    max_persistent_entries = (dsize - sizeof(struct crypt_persist_data)) /
+                             sizeof(struct crypt_persist_entry);
+
+    num = persist_data->persist_valid_entries;
+
+    for (i = 0; i < num; i++) {
+        if (!strncmp(persist_data->persist_entry[i].key, fieldname, PROPERTY_KEY_MAX)) {
+            /* We found an existing entry, update it! */
+            memset(persist_data->persist_entry[i].val, 0, PROPERTY_VALUE_MAX);
+            strlcpy(persist_data->persist_entry[i].val, value, PROPERTY_VALUE_MAX);
+            return 0;
+        }
+    }
+
+    /* We didn't find it, add it to the end, if there is room */
+    if (persist_data->persist_valid_entries < max_persistent_entries) {
+        memset(&persist_data->persist_entry[num], 0, sizeof(struct crypt_persist_entry));
+        strlcpy(persist_data->persist_entry[num].key, fieldname, PROPERTY_KEY_MAX);
+        strlcpy(persist_data->persist_entry[num].val, value, PROPERTY_VALUE_MAX);
+        persist_data->persist_valid_entries++;
+        return 0;
+    }
+
+    return -1;
+}
+
+/* Return the value of the specified field. */
+int cryptfs_getfield(char *fieldname, char *value, int len)
+{
+    char temp_value[PROPERTY_VALUE_MAX];
+    char real_blkdev[MAXPATHLEN];
+    /* 0 is success, 1 is not encrypted,
+     * -1 is value not set, -2 is any other error
+     */
+    int rc = -2;
+
+    if (persist_data == NULL) {
+        load_persistent_data();
+        if (persist_data == NULL) {
+            printf("Getfield error, cannot load persistent data");
+            goto out;
+        }
+    }
+
+    if (!persist_get_key(fieldname, temp_value)) {
+        /* We found it, copy it to the caller's buffer and return */
+        strlcpy(value, temp_value, len);
+        rc = 0;
+    } else {
+        /* Sadness, it's not there.  Return the error */
+        rc = -1;
+    }
+
+out:
+    return rc;
+}
+
+/* Set the value of the specified field. */
+int cryptfs_setfield(char *fieldname, char *value)
+{
+    struct crypt_persist_data stored_pdata;
+    struct crypt_persist_data *pdata_p;
+    struct crypt_mnt_ftr crypt_ftr;
+    char encrypted_state[PROPERTY_VALUE_MAX];
+    /* 0 is success, -1 is an error */
+    int rc = -1;
+    int encrypted = 0;
+
+    if (persist_data == NULL) {
+        load_persistent_data();
+        if (persist_data == NULL) {
+            printf("Setfield error, cannot load persistent data");
+            goto out;
+        }
+    }
+
+    property_get("ro.crypto.state", encrypted_state, "");
+    if (!strcmp(encrypted_state, "encrypted") ) {
+        encrypted = 1;
+    }
+
+    if (persist_set_key(fieldname, value, encrypted)) {
+        goto out;
+    }
+
+    /* If we are running encrypted, save the persistent data now */
+    if (encrypted) {
+        if (save_persistent_data()) {
+            printf("Setfield error, cannot save persistent data");
+            goto out;
+        }
+    }
+
+    rc = 0;
+
+out:
+    return rc;
+}
+
+/* Checks userdata. Attempt to mount the volume if default-
+ * encrypted.
+ * On success trigger next init phase and return 0.
+ * Currently do not handle failure - see TODO below.
+ */
+int cryptfs_mount_default_encrypted(void)
+{
+    char decrypt_state[PROPERTY_VALUE_MAX];
+    property_get("vold.decrypt", decrypt_state, "0");
+    if (!strcmp(decrypt_state, "0")) {
+        printf("Not encrypted - should not call here");
+    } else {
+        int crypt_type = cryptfs_get_password_type();
+        if (crypt_type < 0 || crypt_type > CRYPT_TYPE_MAX_TYPE) {
+            printf("Bad crypt type - error");
+        } else if (crypt_type != CRYPT_TYPE_DEFAULT) {
+            printf("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) {
+            printf("Password is default - restarting filesystem");
+            cryptfs_restart_internal(0);
+            return 0;
+        } else {
+            printf("Encrypted, default crypt type but can't decrypt");
+        }
+    }
+
+    /** Corrupt. Allow us to boot into framework, which will detect bad
+        crypto when it calls do_crypto_complete, then do a factory reset
+     */
+    property_set("vold.decrypt", "trigger_restart_min_framework");
+    return 0;
+}
+
+/* Returns type of the password, default, pattern, pin or password.
+ */
+int cryptfs_get_password_type(void)
+{
+    struct crypt_mnt_ftr crypt_ftr;
+    char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
+    char propbuf[PROPERTY_VALUE_MAX];
+
+    property_get("ro.hardware", propbuf, "");
+    snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
+
+    fstab = fs_mgr_read_fstab(fstab_filename);
+    if (!fstab) {
+        printf("failed to open %s\n", fstab_filename);
+        return -1;
+    }
+
+    if (get_crypt_ftr_and_key(&crypt_ftr)) {
+        printf("Error getting crypt footer and key\n");
+        return -1;
+    }
+
+    if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE) {
+        return -1;
+    }
+
+    return crypt_ftr.crypt_type;
+}
+
+char* cryptfs_get_password()
+{
+    struct timespec now;
+    clock_gettime(CLOCK_MONOTONIC, &now);
+    if (now.tv_sec < password_expiry_time) {
+        return password;
+    } else {
+        cryptfs_clear_password();
+        return 0;
+    }
+}
+
+void cryptfs_clear_password()
+{
+    if (password) {
+        size_t len = strlen(password);
+        memset(password, 0, len);
+        free(password);
+        password = 0;
+        password_expiry_time = 0;
+    }
+}
diff --git a/crypto/lollipop/cryptfs.h b/crypto/lollipop/cryptfs.h
new file mode 100644
index 0000000..b95a290
--- /dev/null
+++ b/crypto/lollipop/cryptfs.h
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+/* This structure starts 16,384 bytes before the end of a hardware
+ * partition that is encrypted, or in a separate partition.  It's location
+ * is specified by a property set in init.<device>.rc.
+ * The structure allocates 48 bytes for a key, but the real key size is
+ * specified in the struct.  Currently, the code is hardcoded to use 128
+ * bit keys.
+ * The fields after salt are only valid in rev 1.1 and later stuctures.
+ * Obviously, the filesystem does not include the last 16 kbytes
+ * of the partition if the crypt_mnt_ftr lives at the end of the
+ * partition.
+ */
+
+#include <cutils/properties.h>
+#include "openssl/sha.h"
+
+/* The current cryptfs version */
+#define CURRENT_MAJOR_VERSION 1
+#define CURRENT_MINOR_VERSION 3
+
+#define CRYPT_FOOTER_OFFSET 0x4000
+#define CRYPT_FOOTER_TO_PERSIST_OFFSET 0x1000
+#define CRYPT_PERSIST_DATA_SIZE 0x1000
+
+#define MAX_CRYPTO_TYPE_NAME_LEN 64
+
+#define MAX_KEY_LEN 48
+#define SALT_LEN 16
+#define SCRYPT_LEN 32
+
+/* definitions of flags in the structure below */
+#define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */
+#define CRYPT_ENCRYPTION_IN_PROGRESS 0x2 /* Encryption partially completed,
+                                            encrypted_upto valid*/
+#define CRYPT_INCONSISTENT_STATE 0x4 /* Set when starting encryption, clear when
+                                        exit cleanly, either through success or
+                                        correctly marked partial encryption */
+#define CRYPT_DATA_CORRUPT 0x8 /* Set when encryption is fine, but the
+                                  underlying volume is corrupt */
+
+/* Allowed values for type in the structure below */
+#define CRYPT_TYPE_PASSWORD 0 /* master_key is encrypted with a password
+                               * Must be zero to be compatible with pre-L
+                               * devices where type is always password.*/
+#define CRYPT_TYPE_DEFAULT  1 /* master_key is encrypted with default
+                               * password */
+#define CRYPT_TYPE_PATTERN  2 /* master_key is encrypted with a pattern */
+#define CRYPT_TYPE_PIN      3 /* master_key is encrypted with a pin */
+#define CRYPT_TYPE_MAX_TYPE 3 /* type cannot be larger than this value */
+
+#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
+/* TODO(paullawrence): Remove KDF_SCRYPT_KEYMASTER_UNPADDED and KDF_SCRYPT_KEYMASTER_BADLY_PADDED
+ * when it is safe to do so. */
+#define KDF_SCRYPT_KEYMASTER_UNPADDED 3
+#define KDF_SCRYPT_KEYMASTER_BADLY_PADDED 4
+#define KDF_SCRYPT_KEYMASTER 5
+
+/* Maximum allowed keymaster blob size. */
+#define KEYMASTER_BLOB_SIZE 2048
+
+/* __le32 and __le16 defined in system/extras/ext4_utils/ext4_utils.h */
+#define __le8  unsigned char
+
+struct crypt_mnt_ftr {
+  __le32 magic;         /* See above */
+  __le16 major_version;
+  __le16 minor_version;
+  __le32 ftr_size;      /* in bytes, not including key following */
+  __le32 flags;         /* See above */
+  __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 */
+  __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
+                                                               needed to decrypt this
+                                                               partition, null terminated */
+  __le32 spare2;        /* ignored */
+  unsigned char master_key[MAX_KEY_LEN]; /* The encrypted key for decrypting the filesystem */
+  unsigned char salt[SALT_LEN];   /* The salt used for this encryption */
+  __le64 persist_data_offset[2];  /* Absolute offset to both copies of crypt_persist_data
+                                   * on device with that info, either the footer of the
+                                   * real_blkdevice or the metadata partition. */
+
+  __le32 persist_data_size;       /* The number of bytes allocated to each copy of the
+                                   * persistent data table*/
+
+  __le8  kdf_type; /* The key derivation function used. */
+
+  /* scrypt parameters. See www.tarsnap.com/scrypt/scrypt.pdf */
+  __le8  N_factor; /* (1 << N) */
+  __le8  r_factor; /* (1 << r) */
+  __le8  p_factor; /* (1 << p) */
+  __le64 encrypted_upto; /* If we are in state CRYPT_ENCRYPTION_IN_PROGRESS and
+                            we have to stop (e.g. power low) this is the last
+                            encrypted 512 byte sector.*/
+  __le8  hash_first_block[SHA256_DIGEST_LENGTH]; /* When CRYPT_ENCRYPTION_IN_PROGRESS
+                                                    set, hash of first block, used
+                                                    to validate before continuing*/
+
+  /* key_master key, used to sign the derived key which is then used to generate
+   * the intermediate key
+   * This key should be used for no other purposes! We use this key to sign unpadded 
+   * data, which is acceptable but only if the key is not reused elsewhere. */
+  __le8 keymaster_blob[KEYMASTER_BLOB_SIZE];
+  __le32 keymaster_blob_size;
+
+  /* Store scrypt of salted intermediate key. When decryption fails, we can
+     check if this matches, and if it does, we know that the problem is with the
+     drive, and there is no point in asking the user for more passwords.
+
+     Note that if any part of this structure is corrupt, this will not match and
+     we will continue to believe the user entered the wrong password. In that
+     case the only solution is for the user to enter a password enough times to
+     force a wipe.
+
+     Note also that there is no need to worry about migration. If this data is
+     wrong, we simply won't recognise a right password, and will continue to
+     prompt. On the first password change, this value will be populated and
+     then we will be OK.
+   */
+  unsigned char scrypted_intermediate_key[SCRYPT_LEN];
+};
+
+/* Persistant data that should be available before decryption.
+ * Things like airplane mode, locale and timezone are kept
+ * here and can be retrieved by the CryptKeeper UI to properly
+ * configure the phone before asking for the password
+ * This is only valid if the major and minor version above
+ * is set to 1.1 or higher.
+ *
+ * This is a 4K structure.  There are 2 copies, and the code alternates
+ * writing one and then clearing the previous one.  The reading
+ * code reads the first valid copy it finds, based on the magic number.
+ * The absolute offset to the first of the two copies is kept in rev 1.1
+ * and higher crypt_mnt_ftr structures.
+ */
+struct crypt_persist_entry {
+  char key[PROPERTY_KEY_MAX];
+  char val[PROPERTY_VALUE_MAX];
+};
+
+/* Should be exactly 4K in size */
+struct crypt_persist_data {
+  __le32 persist_magic;
+  __le32 persist_valid_entries;
+  __le32 persist_spare[30];
+  struct crypt_persist_entry persist_entry[0];
+};
+
+struct volume_info {
+   unsigned int size;
+   unsigned int flags;
+   struct crypt_mnt_ftr crypt_ftr;
+   char mnt_point[256];
+   char blk_dev[256];
+   char crypto_blkdev[256];
+   char label[256];
+};
+#define VOL_NONREMOVABLE   0x1
+#define VOL_ENCRYPTABLE    0x2
+#define VOL_PRIMARY        0x4
+#define VOL_PROVIDES_ASEC  0x8
+
+#define DATA_MNT_POINT "/data"
+
+/* Return values for cryptfs_crypto_complete */
+#define CRYPTO_COMPLETE_NOT_ENCRYPTED  1
+#define CRYPTO_COMPLETE_ENCRYPTED      0
+#define CRYPTO_COMPLETE_BAD_METADATA  -1
+#define CRYPTO_COMPLETE_PARTIAL       -2
+#define CRYPTO_COMPLETE_INCONSISTENT  -3
+#define CRYPTO_COMPLETE_CORRUPT       -4
+
+/* Return values for cryptfs_enable_inplace*() */
+#define ENABLE_INPLACE_OK 0
+#define ENABLE_INPLACE_ERR_OTHER -1
+#define ENABLE_INPLACE_ERR_DEV -2  /* crypto_blkdev issue */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+  typedef int (*kdf_func)(const char *passwd, const unsigned char *salt,
+                          unsigned char *ikey, void *params);
+
+  int cryptfs_crypto_complete(void);
+  int cryptfs_check_footer(void);
+  int cryptfs_check_passwd(char *pw);
+  int cryptfs_verify_passwd(char *newpw);
+  int cryptfs_restart(void);
+  int cryptfs_enable(char *flag, int type, char *passwd, int allow_reboot);
+  int cryptfs_changepw(int type, const char *newpw);
+  int cryptfs_enable_default(char *flag, int allow_reboot);
+  int cryptfs_setup_volume(const char *label, int major, int minor,
+                           char *crypto_dev_path, unsigned int max_pathlen,
+                           int *new_major, int *new_minor);
+  int cryptfs_revert_volume(const char *label);
+  int cryptfs_getfield(char *fieldname, char *value, int len);
+  int cryptfs_setfield(char *fieldname, char *value);
+  int cryptfs_mount_default_encrypted(void);
+  int cryptfs_get_password_type(void);
+  char* cryptfs_get_password(void);
+  void cryptfs_clear_password(void);
+#ifdef __cplusplus
+}
+#endif
