Infrastructure to securely allow only one prompt at boot when encrypted

Add a call to vold that says if we decrypted the data partition. Reset the
flag so that it only returns true the first time.

Bug: 12990752
Change-Id: Ib00be87137c00fb8ad29205c85a3ea187764b702
diff --git a/CommandListener.cpp b/CommandListener.cpp
index a91b654..3a327f1 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -646,6 +646,10 @@
             cli->sendMsg(ResponseCode::OpFailedStorageNotFound, "Error", false);
             return 0;
         }
+    } else if (!strcmp(argv[1], "justdecrypted")) {
+        SLOGD("cryptfs justdecrypted");
+        dumpArgs(argc, argv, -1);
+        rc = cryptfs_just_decrypted();
     } else {
         dumpArgs(argc, argv, -1);
         cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown cryptfs cmd", false);
diff --git a/cryptfs.c b/cryptfs.c
index 9c2b4bc..f8d14cf 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -79,6 +79,12 @@
 static int  master_key_saved = 0;
 static struct crypt_persist_data *persist_data = NULL;
 
+/* Set when userdata is successfully decrypted and mounted.
+ * Reset whenever read (via cryptfs_just_decrypted)
+ * (Read by keyguard to avoid a double prompt.)
+ */
+static int just_decrypted = 0;
+
 extern struct fstab *fstab;
 
 static void cryptfs_reboot(int recovery)
@@ -1464,6 +1470,11 @@
 
     rc = test_mount_encrypted_fs(&crypt_ftr, passwd,
                                  DATA_MNT_POINT, "userdata");
+
+    if (rc == 0 && crypt_ftr.crypt_type != CRYPT_TYPE_DEFAULT) {
+        just_decrypted = 1;
+    }
+
     return rc;
 }
 
@@ -2481,3 +2492,10 @@
 
     return crypt_ftr.crypt_type;
 }
+
+int cryptfs_just_decrypted(void)
+{
+    int rc = just_decrypted;
+    just_decrypted = 0;
+    return rc;
+}
diff --git a/cryptfs.h b/cryptfs.h
index caa7617..ac678dc 100644
--- a/cryptfs.h
+++ b/cryptfs.h
@@ -166,6 +166,7 @@
   int cryptfs_setfield(char *fieldname, char *value);
   int cryptfs_mount_default_encrypted(void);
   int cryptfs_get_password_type(void);
+  int cryptfs_just_decrypted(void);
 #ifdef __cplusplus
 }
 #endif