Improve detection of incomplete encryption

Bug 3384231 is punted to MR1, but the code to set the flag is already
in the tree, so this CL does 3 things:

1.  Comments out the lines that set the flag
2.  Removes the change to the checkpw that was added in the last change.
3.  Implements a new command to check the flag (which no one is calling
    yet and the flag won't be set anyhow).

When MR1 comes, it will be a simple matter to enable the flag setting
code and start testing it.

The fear is a false positive detection of incomplete encryption could
cause people to be prompted to wipe their data when MR1 comes out and
the flag is checked.  Not setting this for first release, and testing
this more before MR1, will give us confidence that the code will not
detect false positives of encryption failure.

Change-Id: I6dfba11646e291fe5867e8375b71a53c815f3968
This commit is contained in:
Ken Sumrall 2011-02-01 15:46:41 -08:00
parent d33d417e3a
commit 7f7dbaa278
3 changed files with 55 additions and 6 deletions

View file

@ -535,6 +535,13 @@ int CommandListener::CryptfsCmd::runCommand(SocketClient *cli,
} }
dumpArgs(argc, argv, -1); dumpArgs(argc, argv, -1);
rc = cryptfs_restart(); rc = cryptfs_restart();
} else if (!strcmp(argv[1], "cryptocomplete")) {
if (argc != 2) {
cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs cryptocomplete", false);
return 0;
}
dumpArgs(argc, argv, -1);
rc = cryptfs_crypto_complete();
} else if (!strcmp(argv[1], "enablecrypto")) { } else if (!strcmp(argv[1], "enablecrypto")) {
if ( (argc != 4) || (strcmp(argv[2], "wipe") && strcmp(argv[2], "inplace")) ) { if ( (argc != 4) || (strcmp(argv[2], "wipe") && strcmp(argv[2], "inplace")) ) {
cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs enablecrypto <wipe|inplace> <passwd>", false); cli->sendMsg(ResponseCode::CommandSyntaxError, "Usage: cryptfs enablecrypto <wipe|inplace> <passwd>", false);

View file

@ -655,6 +655,43 @@ int cryptfs_restart(void)
return rc; return rc;
} }
static int do_crypto_complete(char *mount_point)
{
struct crypt_mnt_ftr crypt_ftr;
unsigned char encrypted_master_key[32];
unsigned char salt[SALT_LEN];
char real_blkdev[MAXPATHLEN];
char fs_type[32];
char fs_options[256];
unsigned long mnt_flags;
char encrypted_state[32];
property_get("ro.crypto.state", encrypted_state, "");
if (strcmp(encrypted_state, "encrypted") ) {
SLOGE("not running with encryption, aborting");
return 1;
}
if (get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) {
SLOGE("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)) {
SLOGE("Error getting crypt footer and key\n");
return -1;
}
if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) {
SLOGE("Encryption process didn't finish successfully\n");
return -2; /* -2 is the clue to the UI that there is no usable data on the disk,
* and give the user an option to wipe the disk */
}
/* We passed the test! We shall diminish, and return to the west */
return 0;
}
static int test_mount_encrypted_fs(char *passwd, char *mount_point) static int test_mount_encrypted_fs(char *passwd, char *mount_point)
{ {
struct crypt_mnt_ftr crypt_ftr; struct crypt_mnt_ftr crypt_ftr;
@ -687,12 +724,6 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point)
return -1; return -1;
} }
if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) {
SLOGE("Encryption process didn't finish successfully\n");
return -2; /* -2 is the clue to the UI that there is no usable data on the disk,
* and give the user an option to wipe the disk */
}
SLOGD("crypt_ftr->fs_size = %lld\n", crypt_ftr.fs_size); SLOGD("crypt_ftr->fs_size = %lld\n", crypt_ftr.fs_size);
orig_failed_decrypt_count = crypt_ftr.failed_decrypt_count; orig_failed_decrypt_count = crypt_ftr.failed_decrypt_count;
@ -752,6 +783,11 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point)
return rc; return rc;
} }
int cryptfs_crypto_complete(void)
{
return do_crypto_complete("/data");
}
int cryptfs_check_passwd(char *passwd) int cryptfs_check_passwd(char *passwd)
{ {
int rc = -1; int rc = -1;
@ -1002,7 +1038,9 @@ int cryptfs_enable(char *howarg, char *passwd)
/* Initialize a crypt_mnt_ftr for the partition */ /* Initialize a crypt_mnt_ftr for the partition */
cryptfs_init_crypt_mnt_ftr(&crypt_ftr); cryptfs_init_crypt_mnt_ftr(&crypt_ftr);
crypt_ftr.fs_size = nr_sec - (CRYPT_FOOTER_OFFSET / 512); crypt_ftr.fs_size = nr_sec - (CRYPT_FOOTER_OFFSET / 512);
#if 0 /* Disable till MR1, needs more testing */
crypt_ftr.flags |= CRYPT_ENCRYPTION_IN_PROGRESS; crypt_ftr.flags |= CRYPT_ENCRYPTION_IN_PROGRESS;
#endif
strcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256"); strcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256");
/* Make an encrypted master key */ /* Make an encrypted master key */
@ -1032,9 +1070,12 @@ int cryptfs_enable(char *howarg, char *passwd)
if (! rc) { if (! rc) {
/* Success */ /* Success */
#if 0 /* Disable till MR1, needs more testing */
/* Clear the encryption in progres flag in the footer */ /* Clear the encryption in progres flag in the footer */
crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS; crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS;
put_crypt_ftr_and_key(real_blkdev, &crypt_ftr, 0, 0); put_crypt_ftr_and_key(real_blkdev, &crypt_ftr, 0, 0);
#endif
sleep(2); /* Give the UI a change to show 100% progress */ sleep(2); /* Give the UI a change to show 100% progress */
sync(); sync();

View file

@ -61,6 +61,7 @@ struct crypt_mnt_ftr {
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
int cryptfs_crypto_complete(void);
int cryptfs_check_passwd(char *pw); int cryptfs_check_passwd(char *pw);
int cryptfs_restart(void); int cryptfs_restart(void);
int cryptfs_enable(char *flag, char *passwd); int cryptfs_enable(char *flag, char *passwd);