Adding e4crypt support

Redirect all crypto calls to e4crypt equivalents if file level encryption
detected. Note this change implements only the ones needed for minimal
functionality.

Requires matching change:
  https://googleplex-android-review.git.corp.google.com/#/c/642778/

Change-Id: I622d1a91704de4b3ab655486e6d38cd6718e6016
diff --git a/CommandListener.cpp b/CommandListener.cpp
index 551a6ce..c66b9d2 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -708,7 +708,7 @@
     } else if (!strcmp(argv[1], "getpw")) {
         SLOGD("cryptfs getpw");
         dumpArgs(argc, argv, -1);
-        char* password = cryptfs_get_password();
+        const char* password = cryptfs_get_password();
         if (password) {
             char* message = 0;
             int size = asprintf(&message, "{{sensitive}} %s", password);
diff --git a/cryptfs.c b/cryptfs.c
index af74d74..1e8f85b 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -53,6 +53,7 @@
 #include "VolumeManager.h"
 #include "VoldUtil.h"
 #include "crypto_scrypt.h"
+#include "ext4_crypt.h"
 #include "ext4_utils.h"
 #include "f2fs_sparseblock.h"
 #include "CheckBattery.h"
@@ -1674,11 +1675,37 @@
 
 int cryptfs_restart(void)
 {
+    SLOGI("cryptfs_restart");
+    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
+        struct fstab_rec* rec;
+        int rc;
+
+        if (e4crypt_restart(DATA_MNT_POINT)) {
+            SLOGE("Can't unmount e4crypt temp volume\n");
+            return -1;
+        }
+
+        rec = fs_mgr_get_entry_for_mount_point(fstab, DATA_MNT_POINT);
+        if (!rec) {
+            SLOGE("Can't get fstab record for %s\n", DATA_MNT_POINT);
+            return -1;
+        }
+
+        rc = fs_mgr_do_mount(fstab, DATA_MNT_POINT, rec->blk_device, 0);
+        if (rc) {
+            SLOGE("Can't mount %s\n", DATA_MNT_POINT);
+            return rc;
+        }
+
+        property_set("vold.decrypt", "trigger_restart_framework");
+        return 0;
+    }
+
     /* Call internal implementation forcing a restart of main service group */
     return cryptfs_restart_internal(1);
 }
 
-static int do_crypto_complete(char *mount_point UNUSED)
+static int do_crypto_complete(char *mount_point)
 {
   struct crypt_mnt_ftr crypt_ftr;
   char encrypted_state[PROPERTY_VALUE_MAX];
@@ -1690,6 +1717,10 @@
     return CRYPTO_COMPLETE_NOT_ENCRYPTED;
   }
 
+  if (e4crypt_crypto_complete(mount_point) == 0) {
+    return CRYPTO_COMPLETE_ENCRYPTED;
+  }
+
   if (get_crypt_ftr_and_key(&crypt_ftr)) {
     fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc));
 
@@ -2012,6 +2043,11 @@
 
 int cryptfs_check_passwd(char *passwd)
 {
+    SLOGI("cryptfs_check_passwd");
+    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
+        return e4crypt_check_passwd(DATA_MNT_POINT, passwd);
+    }
+
     struct crypt_mnt_ftr crypt_ftr;
     int rc;
 
@@ -3302,6 +3338,10 @@
 
 int cryptfs_changepw(int crypt_type, const char *newpw)
 {
+    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
+        return e4crypt_change_password(DATA_MNT_POINT, crypt_type, newpw);
+    }
+
     struct crypt_mnt_ftr crypt_ftr;
 
     /* This is only allowed after we've successfully decrypted the master key */
@@ -3709,6 +3749,10 @@
  */
 int cryptfs_get_password_type(void)
 {
+    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
+        return e4crypt_get_password_type(DATA_MNT_POINT);
+    }
+
     struct crypt_mnt_ftr crypt_ftr;
 
     if (get_crypt_ftr_and_key(&crypt_ftr)) {
@@ -3723,8 +3767,12 @@
     return crypt_ftr.crypt_type;
 }
 
-char* cryptfs_get_password()
+const char* cryptfs_get_password()
 {
+    if (e4crypt_crypto_complete(DATA_MNT_POINT) == 0) {
+        return e4crypt_get_password(DATA_MNT_POINT);
+    }
+
     struct timespec now;
     clock_gettime(CLOCK_BOOTTIME, &now);
     if (now.tv_sec < password_expiry_time) {
diff --git a/cryptfs.h b/cryptfs.h
index bce1dd3..1da6f94 100644
--- a/cryptfs.h
+++ b/cryptfs.h
@@ -243,7 +243,7 @@
   int cryptfs_setfield(const char *fieldname, const char *value);
   int cryptfs_mount_default_encrypted(void);
   int cryptfs_get_password_type(void);
-  char* cryptfs_get_password(void);
+  const char* cryptfs_get_password(void);
   void cryptfs_clear_password(void);
 #ifdef __cplusplus
 }