Merge "Don't try to encrypt in place a filesystem that is too large and return proper errors" into honeycomb
diff --git a/CommandListener.cpp b/CommandListener.cpp
index 4459981..daee95d 100644
--- a/CommandListener.cpp
+++ b/CommandListener.cpp
@@ -543,12 +543,12 @@
dumpArgs(argc, argv, 3);
rc = cryptfs_enable(argv[2], argv[3]);
} else if (!strcmp(argv[1], "changepw")) {
- if (argc != 4) {
- cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs changepw <oldpasswd> <newpasswd>", false);
+ if (argc != 3) {
+ cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs changepw <newpasswd>", false);
return 0;
}
- SLOGD("cryptfs changepw {} {}");
- rc = cryptfs_changepw(argv[2], argv[3]);
+ SLOGD("cryptfs changepw {}");
+ rc = cryptfs_changepw(argv[2]);
} else {
dumpArgs(argc, argv, -1);
cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown cryptfs cmd", false);
diff --git a/cryptfs.c b/cryptfs.c
index 5b3a504..afba726 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -45,10 +45,14 @@
#define DM_CRYPT_BUF_SIZE 4096
#define DATA_MNT_POINT "/data"
+#define HASH_COUNT 2000
+#define KEY_LEN_BYTES 16
+#define IV_LEN_BYTES 16
+
char *me = "cryptfs";
-static unsigned char saved_key_sha1[20] = { '\0' };
-static int key_sha1_saved = 0;
+static unsigned char saved_master_key[KEY_LEN_BYTES];
+static int master_key_saved = 0;
static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags)
{
@@ -144,7 +148,7 @@
}
if (key) {
- if (crypt_ftr->keysize != 16) {
+ if (crypt_ftr->keysize != KEY_LEN_BYTES) {
SLOGE("Keysize of %d bits not supported for real block device %s\n",
crypt_ftr->keysize * 8, real_blk_name);
goto errout;
@@ -242,7 +246,7 @@
}
}
- if (crypt_ftr->keysize != 16) {
+ if (crypt_ftr->keysize != KEY_LEN_BYTES) {
SLOGE("Keysize of %d bits not supported for real block device %s\n",
crypt_ftr->keysize * 8, real_blk_name);
goto errout;
@@ -400,10 +404,6 @@
}
-#define HASH_COUNT 2000
-#define KEY_LEN_BYTES 16
-#define IV_LEN_BYTES 16
-
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 */
@@ -586,7 +586,7 @@
static int restart_successful = 0;
/* Validate that it's OK to call this routine */
- if (! key_sha1_saved) {
+ if (! master_key_saved) {
SLOGE("Encrypted filesystem not validated, aborting");
return -1;
}
@@ -671,7 +671,7 @@
int rc;
property_get("ro.crypto.state", encrypted_state, "");
- if ( key_sha1_saved || strcmp(encrypted_state, "encrypted") ) {
+ if ( master_key_saved || strcmp(encrypted_state, "encrypted") ) {
SLOGE("encrypted fs already validated or not running with encryption, aborting");
return -1;
}
@@ -732,12 +732,12 @@
* so we can mount it when restarting the framework.
*/
property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev);
- /* Also save a SHA1 of the master key so we can know if we
- * successfully decrypted the key when we want to change the
- * password on it.
+
+ /* Also save a the master key so we can reencrypted the key
+ * the key when we want to change the password on it.
*/
- SHA1(decrypted_master_key, KEY_LEN_BYTES, saved_key_sha1);
- key_sha1_saved = 1;
+ memcpy(saved_master_key, decrypted_master_key, KEY_LEN_BYTES);
+ master_key_saved = 1;
rc = 0;
}
@@ -765,7 +765,7 @@
ftr->minor_version = 0;
ftr->ftr_size = sizeof(struct crypt_mnt_ftr);
ftr->flags = 0;
- ftr->keysize = 16;
+ ftr->keysize = KEY_LEN_BYTES;
ftr->spare1 = 0;
ftr->fs_size = 0;
ftr->failed_decrypt_count = 0;
@@ -891,7 +891,7 @@
char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN];
char fs_type[32], fs_options[256], mount_point[32];
unsigned long mnt_flags, nr_sec;
- unsigned char master_key[16], decrypted_master_key[16];
+ unsigned char master_key[KEY_LEN_BYTES], decrypted_master_key[KEY_LEN_BYTES];
unsigned char salt[SALT_LEN];
int rc=-1, fd, i;
struct crypt_mnt_ftr crypt_ftr;
@@ -1048,16 +1048,15 @@
return -1;
}
-int cryptfs_changepw(char *oldpw, char *newpw)
+int cryptfs_changepw(char *newpw)
{
struct crypt_mnt_ftr crypt_ftr;
- unsigned char encrypted_master_key[32], decrypted_master_key[32];
+ unsigned char encrypted_master_key[KEY_LEN_BYTES], decrypted_master_key[KEY_LEN_BYTES];
unsigned char salt[SALT_LEN];
- unsigned char new_key_sha1[20];
char real_blkdev[MAXPATHLEN];
/* This is only allowed after we've successfully decrypted the master key */
- if (! key_sha1_saved) {
+ if (! master_key_saved) {
SLOGE("Key not saved, aborting");
return -1;
}
@@ -1074,24 +1073,10 @@
return -1;
}
- /* decrypt key with old passwd */
- decrypt_master_key(oldpw, salt, encrypted_master_key, decrypted_master_key);
+ encrypt_master_key(newpw, salt, saved_master_key, encrypted_master_key);
- /* compute sha1 of decrypted key */
- SHA1(decrypted_master_key, KEY_LEN_BYTES, new_key_sha1);
-
- /* If computed sha1 and saved sha1 match, encrypt key with new passwd */
- if (! memcmp(saved_key_sha1, new_key_sha1, sizeof(saved_key_sha1))) {
- /* they match, it's safe to re-encrypt the key */
- encrypt_master_key(newpw, salt, decrypted_master_key, encrypted_master_key);
-
- /* save the key */
- put_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, 0);
- } else {
- SLOGE("SHA1 mismatch");
- return -1;
- }
+ /* save the key */
+ put_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt);
return 0;
}
-
diff --git a/cryptfs.h b/cryptfs.h
index 432450c..ca3cc95 100644
--- a/cryptfs.h
+++ b/cryptfs.h
@@ -62,7 +62,7 @@
int cryptfs_check_passwd(char *pw);
int cryptfs_restart(void);
int cryptfs_enable(char *flag, char *passwd);
- int cryptfs_changepw(char *oldpw, char *newpw);
+ int cryptfs_changepw(char *newpw);
#ifdef __cplusplus
}
#endif