From 7bdfa52d934465e2182e2f1c200c4d8581ad5da6 Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Fri, 15 Nov 2013 13:42:56 -0800 Subject: [PATCH] vold: cryptfs: Don't update KDF without validating pwd/key. Prior to this, the Key derivation function would get blindly updated even if the user entered the wrong password. Now, we only attempt to upgrade the KDF if the pwd/key have been verified (i.e. after a successful mount). Bug: 11460197 Change-Id: I0469228cc9b87c47754e8ca3c7146651da177da5 --- cryptfs.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/cryptfs.c b/cryptfs.c index 03d714e..6247014 100644 --- a/cryptfs.c +++ b/cryptfs.c @@ -351,6 +351,9 @@ static void upgrade_crypt_ftr(int fd, struct crypt_mnt_ftr *crypt_ftr, off64_t o if ((crypt_ftr->major_version == 1) && (crypt_ftr->minor_version)) { SLOGW("upgrading crypto footer to 1.2"); + /* But keep the old kdf_type. + * It will get updated later to KDF_SCRYPT after the password has been verified. + */ crypt_ftr->kdf_type = KDF_PBKDF2; get_device_scrypt_params(crypt_ftr); crypt_ftr->minor_version = 2; @@ -922,7 +925,7 @@ static int encrypt_master_key(char *passwd, unsigned char *salt, } } -static int decrypt_master_key(char *passwd, unsigned char *salt, +static int decrypt_master_key_aux(char *passwd, unsigned char *salt, unsigned char *encrypted_master_key, unsigned char *decrypted_master_key, kdf_func kdf, void *kdf_params) @@ -966,7 +969,7 @@ static void get_kdf_func(struct crypt_mnt_ftr *ftr, kdf_func *kdf, void** kdf_pa } } -static int decrypt_master_key_and_upgrade(char *passwd, unsigned char *decrypted_master_key, +static int decrypt_master_key(char *passwd, unsigned char *decrypted_master_key, struct crypt_mnt_ftr *crypt_ftr) { kdf_func kdf; @@ -974,21 +977,10 @@ static int decrypt_master_key_and_upgrade(char *passwd, unsigned char *decrypted int ret; get_kdf_func(crypt_ftr, &kdf, &kdf_params); - ret = decrypt_master_key(passwd, crypt_ftr->salt, crypt_ftr->master_key, decrypted_master_key, kdf, + ret = decrypt_master_key_aux(passwd, crypt_ftr->salt, crypt_ftr->master_key, decrypted_master_key, kdf, kdf_params); if (ret != 0) { SLOGW("failure decrypting master key"); - return ret; - } - - /* - * Upgrade if we're not using the latest KDF. - */ - if (crypt_ftr->kdf_type != KDF_SCRYPT) { - crypt_ftr->kdf_type = KDF_SCRYPT; - encrypt_master_key(passwd, crypt_ftr->salt, decrypted_master_key, crypt_ftr->master_key, - crypt_ftr); - put_crypt_ftr_and_key(crypt_ftr); } return ret; @@ -1230,7 +1222,10 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point, char *label) orig_failed_decrypt_count = crypt_ftr.failed_decrypt_count; if (! (crypt_ftr.flags & CRYPT_MNT_KEY_UNENCRYPTED) ) { - decrypt_master_key_and_upgrade(passwd, decrypted_master_key, &crypt_ftr); + if (decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr)) { + SLOGE("Failed to decrypt master key\n"); + return -1; + } } if (create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, @@ -1280,7 +1275,20 @@ static int test_mount_encrypted_fs(char *passwd, char *mount_point, char *label) memcpy(saved_master_key, decrypted_master_key, KEY_LEN_BYTES); saved_mount_point = strdup(mount_point); master_key_saved = 1; + SLOGD("%s(): Master key saved\n", __FUNCTION__); rc = 0; + /* + * Upgrade if we're not using the latest KDF. + */ + if (crypt_ftr.kdf_type != KDF_SCRYPT) { + crypt_ftr.kdf_type = KDF_SCRYPT; + rc = encrypt_master_key(passwd, crypt_ftr.salt, saved_master_key, crypt_ftr.master_key, + &crypt_ftr); + if (!rc) { + rc = put_crypt_ftr_and_key(&crypt_ftr); + } + SLOGD("Key Derivation Function upgrade: rc=%d\n", rc); + } } return rc; @@ -1383,7 +1391,7 @@ int cryptfs_verify_passwd(char *passwd) /* If the device has no password, then just say the password is valid */ rc = 0; } else { - decrypt_master_key_and_upgrade(passwd, decrypted_master_key, &crypt_ftr); + decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr); if (!memcmp(decrypted_master_key, saved_master_key, crypt_ftr.keysize)) { /* They match, the password is correct */ rc = 0; @@ -1777,7 +1785,7 @@ int cryptfs_enable(char *howarg, char *passwd) save_persistent_data(); } - decrypt_master_key_and_upgrade(passwd, decrypted_master_key, &crypt_ftr); + decrypt_master_key(passwd, decrypted_master_key, &crypt_ftr); create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev, "userdata");