diff --git a/lib/tcrypt/tcrypt.c b/lib/tcrypt/tcrypt.c index 037244ee..a8f9aada 100644 --- a/lib/tcrypt/tcrypt.c +++ b/lib/tcrypt/tcrypt.c @@ -425,13 +425,15 @@ out: } static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr, - const char *key, uint32_t flags) + const char *key, struct crypt_params_tcrypt *params) { struct tcrypt_phdr hdr2; int i, j, r = -EINVAL; for (i = 0; tcrypt_cipher[i].chain_count; i++) { - if (!(flags & CRYPT_TCRYPT_LEGACY_MODES) && tcrypt_cipher[i].legacy) + if (params->cipher && !strstr(tcrypt_cipher[i].long_name, params->cipher)) + continue; + if (!(params->flags & CRYPT_TCRYPT_LEGACY_MODES) && tcrypt_cipher[i].legacy) continue; log_dbg(cd, "TCRYPT: trying cipher %s-%s", tcrypt_cipher[i].long_name, tcrypt_cipher[i].mode); @@ -463,7 +465,7 @@ static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr, r = i; break; } - if ((flags & CRYPT_TCRYPT_VERA_MODES) && + if ((params->flags & CRYPT_TCRYPT_VERA_MODES) && !strncmp(hdr2.d.magic, VCRYPT_HDR_MAGIC, TCRYPT_HDR_MAGIC_LEN)) { log_dbg(cd, "TCRYPT: Signature magic detected (Veracrypt)."); memcpy(&hdr->e, &hdr2.e, TCRYPT_HDR_LEN); @@ -568,6 +570,8 @@ static int TCRYPT_init_hdr(struct crypt_device *cd, pwd[i] += params->passphrase[i]; for (i = 0; tcrypt_kdf[i].name; i++) { + if (params->hash_name && strcmp(params->hash_name, tcrypt_kdf[i].hash)) + continue; if (!(params->flags & CRYPT_TCRYPT_LEGACY_MODES) && tcrypt_kdf[i].legacy) continue; if (!(params->flags & CRYPT_TCRYPT_VERA_MODES) && tcrypt_kdf[i].veracrypt) @@ -598,7 +602,7 @@ static int TCRYPT_init_hdr(struct crypt_device *cd, } /* Decrypt header */ - r = TCRYPT_decrypt_hdr(cd, hdr, key, params->flags); + r = TCRYPT_decrypt_hdr(cd, hdr, key, params); if (r == -ENOENT) { skipped++; r = -EPERM; diff --git a/man/cryptsetup.8 b/man/cryptsetup.8 index 58d7519a..137265c7 100644 --- a/man/cryptsetup.8 +++ b/man/cryptsetup.8 @@ -716,12 +716,16 @@ a mapping . \fB\fR can be [\-\-key\-file, \-\-tcrypt\-hidden, \-\-tcrypt\-system, \-\-tcrypt\-backup, \-\-readonly, \-\-test\-passphrase, \-\-allow-discards, \-\-veracrypt, \-\-veracrypt\-pim, \-\-veracrypt\-query\-pim, -\-\-header]. +\-\-header, \-\-cipher, \-\-hash]. The keyfile parameter allows a combination of file content with the passphrase and can be repeated. Note that using keyfiles is compatible with TCRYPT and is different from LUKS keyfile logic. +If \fB\-\-\cipher\fR or \fB\-\-hash\fR options are used, only cipher chains or +PBKDF2 variants with the specified hash algoprithms are checked. This could speed +up opening of the device (but also it reveals some information about the container). + \fBWARNING:\fR Option \fB\-\-allow\-discards\fR cannot be combined with option \fB\-\-tcrypt\-hidden\fR. For normal mapping, it can cause the \fBdestruction of hidden volume\fR (hidden volume appears as unused space @@ -741,7 +745,7 @@ This means that if the master key is compromised, the whole device has to be erased to prevent further access. Use this option carefully. \fB\fR can be [\-\-dump\-master\-key, \-\-key\-file, -\-\-tcrypt\-hidden, \-\-tcrypt\-system, \-\-tcrypt\-backup]. +\-\-tcrypt\-hidden, \-\-tcrypt\-system, \-\-tcrypt\-backup, \-\-cipher, \-\-hash]. The keyfile parameter allows a combination of file content with the passphrase and can be repeated. diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 3bc0cd26..bef44fdb 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -453,6 +453,8 @@ static int action_open_tcrypt(void) .flags = CRYPT_TCRYPT_LEGACY_MODES | (ARG_SET(OPT_VERACRYPT_ID) ? CRYPT_TCRYPT_VERA_MODES : 0), .veracrypt_pim = ARG_UINT32(OPT_VERACRYPT_PIM_ID), + .hash_name = ARG_STR(OPT_HASH_ID), + .cipher = ARG_STR(OPT_CIPHER_ID), }; const char *activated_name; uint32_t activate_flags = 0; @@ -588,7 +590,9 @@ static int action_tcryptDump(void) .keyfiles_count = keyfiles_count, .flags = CRYPT_TCRYPT_LEGACY_MODES | (ARG_SET(OPT_VERACRYPT_ID) ? CRYPT_TCRYPT_VERA_MODES : 0), - .veracrypt_pim = ARG_UINT32(OPT_VERACRYPT_PIM_ID) + .veracrypt_pim = ARG_UINT32(OPT_VERACRYPT_PIM_ID), + .hash_name = ARG_STR(OPT_HASH_ID), + .cipher = ARG_STR(OPT_CIPHER_ID), }; int r; r = crypt_init_data_device(&cd, ARG_STR(OPT_HEADER_ID) ?: action_argv[0], action_argv[0]); diff --git a/tests/tcrypt-compat-test b/tests/tcrypt-compat-test index e706427b..7ad79b8e 100755 --- a/tests/tcrypt-compat-test +++ b/tests/tcrypt-compat-test @@ -111,6 +111,11 @@ for file in $(ls $TST_DIR/[tv]c_* $TST_DIR/vcpim_* $TST_DIR/sys_[tv]c_*) ; do SYS_OPT="" [[ $file =~ sys_.* ]] && SYS_OPT="--tcrypt-system" echo $PASSWORD | $CRYPTSETUP tcryptDump --veracrypt $SYS_OPT $PIM_OPT $file >/dev/null || fail + if [[ $file =~ .*-sha512-xts-aes$ ]] ; then + echo $PASSWORD | $CRYPTSETUP tcryptDump --veracrypt $SYS_OPT $PIM_OPT -h sha512 -c aes $file >/dev/null || fail + echo $PASSWORD | $CRYPTSETUP tcryptDump --veracrypt $SYS_OPT $PIM_OPT -h xxxx $file 2>/dev/null && fail + echo $PASSWORD | $CRYPTSETUP tcryptDump --veracrypt $SYS_OPT $PIM_OPT -h sha512 -c xxx $file 2>/dev/null && fail + fi echo " [OK]" done