diff options
author | JP Abgrall <jpa@google.com> | 2013-11-15 13:42:56 -0800 |
---|---|---|
committer | JP Abgrall <jpa@google.com> | 2013-11-15 13:42:56 -0800 |
commit | 7bdfa52d934465e2182e2f1c200c4d8581ad5da6 (patch) | |
tree | 222f836136d04c6f9970c09e550cc4e61c822994 | |
parent | 6bcd362edd1f0ad97807276ff7f9f16991df99a4 (diff) | |
download | vold-kitkat-mr1.1-release.tar.gz |
vold: cryptfs: Don't update KDF without validating pwd/key.android-sdk-4.4.2_r1.0.1android-sdk-4.4.2_r1android-4.4.2_r2.0.1android-4.4.2_r2android-4.4.2_r1.0.1android-4.4.2_r1android-4.4.1_r1.0.1android-4.4.1_r1kitkat-mr1.1-releasekitkat-mr1-release
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
-rw-r--r-- | cryptfs.c | 42 |
1 files changed, 25 insertions, 17 deletions
@@ -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"); |