/*
 * 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/stat.h>
#include <fcntl.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 <openssl/sha.h>
#include <errno.h>
#include <cutils/android_reboot.h>
#include <ext4.h>
#include <linux/kdev_t.h>
#include "cryptfs.h"
#define LOG_TAG "Cryptfs"
#include "cutils/log.h"
#include "cutils/properties.h"
#include "hardware_legacy/power.h"
//#include "VolumeManager.h"

#define DM_CRYPT_BUF_SIZE 4096
#define DATA_MNT_POINT "/data"

#define HASH_COUNT 2000
#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
#define KEY_LEN_BYTES_SAMSUNG (sizeof(edk_t))
#endif
#define KEY_LEN_BYTES 16
#define IV_LEN_BYTES 16

#define KEY_LOC_PROP   "ro.crypto.keyfile.userdata"
#define KEY_IN_FOOTER  "footer"

#define EXT4_FS 1
#define FAT_FS 2

#ifndef EXPAND
#define STRINGIFY(x) #x
#define EXPAND(x) STRINGIFY(x)
#endif

char *me = "cryptfs";

static char *saved_data_blkdev;
static char *saved_mount_point;
static int  master_key_saved = 0;
#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
static int  using_samsung_encryption = 0;
//static edk_t saved_master_key;
static unsigned char saved_master_key[KEY_LEN_BYTES_SAMSUNG];
#else
static unsigned char saved_master_key[KEY_LEN_BYTES];
#endif

int cryptfs_setup_volume(const char *label, const char *real_blkdev, char *crypto_blkdev);


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));
    }
}

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;
}

/* 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(char *real_blk_name, struct crypt_mnt_ftr *crypt_ftr,
                                  unsigned char *key, unsigned char *salt)
{
  // we don't need to update it...
  return 0;
}

static int get_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *crypt_ftr,
                                  unsigned char *key, unsigned char *salt)
{
  int fd;
  unsigned int nr_sec, cnt;
  off64_t off;
  int rc = -1;
  char key_loc[PROPERTY_VALUE_MAX];
  char *fname;
  struct stat statbuf;

  property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER);

  if (!strcmp(key_loc, KEY_IN_FOOTER)) {
    fname = real_blk_name;
    if ( (fd = open(fname, O_RDONLY)) < 0) {
      printf("Cannot open real block device %s\n", fname);
      return -1;
    }

    if ( (nr_sec = get_blkdev_size(fd)) == 0) {
      SLOGE("Cannot get size of block device %s\n", fname);
      goto errout;
    }

    /* 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.
     */
    off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET;

    if (lseek64(fd, off, SEEK_SET) == -1) {
      printf("Cannot seek to real block device footer\n");
      goto errout;
    }
  } else if (key_loc[0] == '/') {
    fname = key_loc;
    if ( (fd = open(fname, O_RDONLY)) < 0) {
      printf("Cannot open footer file %s\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
#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
        && statbuf.st_size != 0x8000
#endif
        )) {
      printf("footer file %s is not the expected size!\n", fname);
      goto errout;
    }
  } else {
    printf("Unexpected value for" KEY_LOC_PROP "\n");
    return -1;;
  }

  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) {
#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
	if (crypt_ftr->magic != CRYPT_MNT_MAGIC_SAMSUNG) {
		printf("Bad magic for real block device %s\n", fname);
		goto errout;
	} else {
		printf("Using Samsung encryption.\n");
		using_samsung_encryption = 1;
		memcpy(key, &crypt_ftr->edk_payload, sizeof(edk_payload_t));

	}
#else
    printf("Bad magic for real block device %s\n", fname);
    goto errout;
#endif
  }

  if (crypt_ftr->major_version != 1) {
    printf("Cannot understand major version %d real block device footer\n",
          crypt_ftr->major_version);
    goto errout;
  }

  if (crypt_ftr->minor_version != 0) {
    printf("Warning: crypto footer minor version %d, expected 0, continuing...\n",
          crypt_ftr->minor_version);
  }

  if (crypt_ftr->ftr_size > sizeof(struct crypt_mnt_ftr)) {
    /* the footer size is bigger than we expected.
     * Skip to it's stated end so we can read the key.
     */
    if (lseek(fd, crypt_ftr->ftr_size - sizeof(struct crypt_mnt_ftr),  SEEK_CUR) == -1) {
      printf("Cannot seek to start of key\n");
      goto errout;
    }
  }

  if (crypt_ftr->keysize != sizeof(saved_master_key)) {
    printf("Keysize of %d bits not supported for real block device %s\n",
          crypt_ftr->keysize * 8, fname);
    goto errout;
  }

  if ( (cnt = read(fd, key, crypt_ftr->keysize)) != crypt_ftr->keysize) {
    printf("Cannot read key for real block device %s\n", fname);
    goto errout;
  }

  if (lseek64(fd, KEY_TO_SALT_PADDING, SEEK_CUR) == -1) {
    printf("Cannot seek to real block device salt\n");
    goto errout;
  }

  if ( (cnt = read(fd, salt, SALT_LEN)) != SALT_LEN) {
    printf("Cannot read salt for real block device %s\n", fname);
    goto errout;
  }

  /* Success! */
  rc = 0;

errout:
  close(fd);
  return rc;
}

/* Convert a binary key of specified length into an ascii hex string equivalent,
 * without the leading 0x and with null termination
 */
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 create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key,
                                    const 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 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_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);

  /* Load the mapping table for this device */
  tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];

  ioctl_init(io, 4096, 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", crypt_ftr->crypto_type_name,
          master_key_ascii, real_blk_name);
  //printf("cryptsetup params: '%s'\n", crypt_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;

  if (ioctl(fd, DM_TABLE_LOAD, io)) {
      printf("Cannot load dm-crypt mapping table.\n");
      goto errout;
  }

  /* Resume this device to activate it */
  ioctl_init(io, 4096, 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(const 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 void pbkdf2(char *passwd, unsigned char *salt, unsigned char *ikey)
{
    /* Turn the password into a key and IV that can decrypt the master key */
    PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), salt, SALT_LEN,
                           HASH_COUNT, KEY_LEN_BYTES+IV_LEN_BYTES, ikey);
}

static int decrypt_master_key(char *passwd, unsigned char *salt,
                              unsigned char *encrypted_master_key,
                              unsigned char *decrypted_master_key)
{
#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
    if (using_samsung_encryption) {
		property_set("rw.km_fips_status", "ready");
		return decrypt_EDK((dek_t*)decrypted_master_key, (edk_payload_t*)encrypted_master_key, passwd);
	}
#endif

  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 a key and IV that can decrypt the master key */
  pbkdf2(passwd, salt, ikey);

  /* 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;
  } else {
    return 0;
  }
}

static int get_orig_mount_parms(
        const char *mount_point, char *fs_type, char *real_blkdev,
        unsigned long *mnt_flags, char *fs_options)
{
  char mount_point2[PROPERTY_VALUE_MAX];
  char fs_flags[PROPERTY_VALUE_MAX];

  property_get("ro.crypto.fs_type", fs_type, "");
  property_get("ro.crypto.fs_real_blkdev", real_blkdev, "");
  property_get("ro.crypto.fs_mnt_point", mount_point2, "");
  property_get("ro.crypto.fs_options", fs_options, "");
  property_get("ro.crypto.fs_flags", fs_flags, "");
  *mnt_flags = strtol(fs_flags, 0, 0);

  if (strcmp(mount_point, mount_point2)) {
    /* Consistency check.  These should match. If not, something odd happened. */
    return -1;
  }

  return 0;
}

static int get_orig_mount_parms_sd(
        const char *mount_point, char *fs_type, char *real_blkdev)
{
    char mount_point2[PROPERTY_VALUE_MAX];

    property_get("ro.crypto.sd_fs_type", fs_type, "");
    property_get("ro.crypto.sd_fs_real_blkdev", real_blkdev, "");
    property_get("ro.crypto.sd_fs_mnt_point", mount_point2, "");

    if (strcmp(mount_point, mount_point2)) {
        /* Consistency check.  These should match. If not, something odd happened. */
        return -1;
    }

    return 0;
}

static int test_mount_encrypted_fs(
        char *passwd, char *mount_point, char *label, char *crypto_blkdev)
{
  struct crypt_mnt_ftr crypt_ftr;
  /* Allocate enough space for a 256 bit key, but we may use less */
  unsigned char encrypted_master_key[256], decrypted_master_key[32];
  unsigned char salt[SALT_LEN];
  char real_blkdev[MAXPATHLEN];
  char fs_type[PROPERTY_VALUE_MAX];
  char fs_options[PROPERTY_VALUE_MAX];
  char tmp_mount_point[MAXPATHLEN];
  unsigned long mnt_flags;
  unsigned int orig_failed_decrypt_count;
  char encrypted_state[PROPERTY_VALUE_MAX];
  int rc;

  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 %s\n", encrypted_state);
    return -1;
  }

  if (get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) {
    printf("Error reading original mount parms for mount point %s\n", mount_point);
    return -1;
  }

  if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) {
    printf("Error getting crypt footer and key\n");
    return -1;
  }

  //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) ) {
    decrypt_master_key(passwd, salt, encrypted_master_key, decrypted_master_key);
  }

  if (create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev,
                    crypto_blkdev, label)) {
    printf("Error creating decrypted block device\n");
    return -1;
  }

  /* If init detects an encrypted filesystme, it writes a file for each such
   * encrypted fs into the tmpfs /data filesystem, and then the framework finds those
   * files and passes that data to me */
  /* Create a tmp mount point to try mounting the decryptd fs
   * Since we're here, the mount_point should be a tmpfs filesystem, so make
   * a directory in it to test mount the decrypted filesystem.
   */
  sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point);
  mkdir(tmp_mount_point, 0755);
  if ( mount(crypto_blkdev, tmp_mount_point, fs_type, MS_RDONLY, "") ) {
    printf("Error temp mounting decrypted block device\n");
    delete_crypto_blk_dev(label);
    crypt_ftr.failed_decrypt_count++;
  } else {
    /* Success, so just umount and we'll mount it properly when we restart
     * the framework.
     */
    umount(tmp_mount_point);
    crypt_ftr.failed_decrypt_count  = 0;
  }

  rmdir(tmp_mount_point);

  if (crypt_ftr.failed_decrypt_count) {
    /* We failed to mount the device, so return an error */
    rc = crypt_ftr.failed_decrypt_count;

  } else {
    /* Woot!  Success!  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, sizeof(saved_master_key));
    saved_data_blkdev = strdup(real_blkdev);
    saved_mount_point = strdup(mount_point);
    master_key_saved = 1;
    rc = 0;
  }

  return rc;
}

static int test_mount_encrypted_fs_sd(
        const char *passwd, const char *mount_point, const char *label)
{
    char real_blkdev[MAXPATHLEN];
    char crypto_blkdev[MAXPATHLEN];
    char tmp_mount_point[MAXPATHLEN];
    char encrypted_state[PROPERTY_VALUE_MAX];
    char fs_type[PROPERTY_VALUE_MAX];
    int rc;

    property_get("ro.crypto.state", encrypted_state, "");
    if ( !master_key_saved || strcmp(encrypted_state, "encrypted") ) {
        printf("encrypted fs not yet validated or not running with encryption, aborting\n");
        return -1;
    }

    if (get_orig_mount_parms_sd(mount_point, fs_type, real_blkdev)) {
        printf("Error reading original mount parms for mount point %s\n", mount_point);
        return -1;
    }

    rc = cryptfs_setup_volume(label, real_blkdev, crypto_blkdev);
    if(rc){
        printf("Error setting up cryptfs volume %s\n", real_blkdev);
        return -1;
    }

    sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point);
    mkdir(tmp_mount_point, 0755);
    if ( mount(crypto_blkdev, tmp_mount_point, fs_type, MS_RDONLY, "") ) {
        printf("Error temp mounting decrypted block device\n");
        delete_crypto_blk_dev(label);
    } else {
        /* Success, so just umount and we'll mount it properly when we restart
        * the framework.
        */
        umount(tmp_mount_point);

        property_set("ro.crypto.sd_fs_crypto_blkdev", crypto_blkdev);
    }

    rmdir(tmp_mount_point);

    return rc;
}

/*
 * 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, const char *real_blkdev, char *crypto_blkdev)
{
    struct crypt_mnt_ftr sd_crypt_ftr;
    unsigned char key[256], salt[32];
    struct stat statbuf;
    int nr_sec, fd, rc;

    /* Just want the footer, but gotta get it all */
    get_crypt_ftr_and_key(saved_data_blkdev, &sd_crypt_ftr, key, salt);

    /* 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) {
        SLOGE("Cannot get size of volume %s\n", real_blkdev);
        return -1;
    }

#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
    if(using_samsung_encryption) {
        if(!access("/efs/essiv", R_OK)){
            strcpy(sd_crypt_ftr.crypto_type_name, "aes-cbc-plain:sha1");
        }
        else if(!access("/efs/cryptprop_essiv", R_OK)){
            strcpy(sd_crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256");
        }
    }
#endif

    sd_crypt_ftr.fs_size = nr_sec;
    rc = create_crypto_blk_dev(
            &sd_crypt_ftr, saved_master_key, real_blkdev, crypto_blkdev, label);

    stat(crypto_blkdev, &statbuf);

    return rc;
}

int cryptfs_crypto_complete(void)
{
  return -1;
}

int cryptfs_check_passwd(const char *passwd)
{
    char pwbuf[256];
    char crypto_blkdev_data[MAXPATHLEN];
    int rc = -1;

    strcpy(pwbuf, passwd);
    rc = test_mount_encrypted_fs(pwbuf, DATA_MNT_POINT, "userdata", crypto_blkdev_data);

#ifdef TW_INCLUDE_CRYPTO_SAMSUNG
    if(using_samsung_encryption) {

        int rc2 = 1;
#ifndef RECOVERY_SDCARD_ON_DATA
#ifdef TW_INTERNAL_STORAGE_PATH
		// internal storage for non data/media devices
        if(!rc) {
            strcpy(pwbuf, passwd);
            rc2 = test_mount_encrypted_fs_sd(
                    pwbuf, EXPAND(TW_INTERNAL_STORAGE_PATH),
                    EXPAND(TW_INTERNAL_STORAGE_MOUNT_POINT));
        }
#endif
#endif
#ifdef TW_EXTERNAL_STORAGE_PATH
		printf("Temp mounting /data\n");
		// mount data so mount_ecryptfs_drive can access edk in /data/system/
		rc2 = mount(crypto_blkdev_data, DATA_MNT_POINT, CRYPTO_FS_TYPE, MS_RDONLY, "");
        // external sd
		char decrypt_external[256], external_blkdev[256];
		property_get("ro.crypto.external_encrypted", decrypt_external, "0");
		// Mount the external storage as ecryptfs so that ecryptfs can act as a pass-through
		if (!rc2 && strcmp(decrypt_external, "1") == 0) {
			printf("Mounting external with ecryptfs...\n");
            strcpy(pwbuf, passwd);
            rc2 = mount_ecryptfs_drive(
                    pwbuf, EXPAND(TW_EXTERNAL_STORAGE_PATH),
                    EXPAND(TW_EXTERNAL_STORAGE_PATH), 0);
			if (rc2 == 0)
				property_set("ro.crypto.external_use_ecryptfs", "1");
			else
				property_set("ro.crypto.external_use_ecryptfs", "0");
        } else {
			printf("Unable to mount external storage with ecryptfs.\n");
			umount(EXPAND(TW_EXTERNAL_STORAGE_PATH));
		}
        umount(DATA_MNT_POINT);
    }
#endif // #ifdef TW_EXTERNAL_STORAGE_PATH
#endif // #ifdef TW_INCLUDE_CRYPTO_SAMSUNG
    return rc;
}
