tcrypt: Support --hash and --cipher options to limit opening time.

If user knows which particular PBKDF2 hash or cipher is used for
True/VeraCrypt container, using --hash of --cipher option in tcryptDump
and tcryptOpen can scan only these variants.
Note for the cipher it means substring (all cipher chains containing
the cipher are tried).

For example, you can use
  cryptsetup tcryptDump --hash sha512 <container>

Note: for speed up, usually the hash option matters, cipher variants
are scanned very quickly.
Use witch care, in a script it can reveal some sensitive attribute
of the container.

Fixes #608.
This commit is contained in:
Milan Broz
2020-12-29 15:05:12 +01:00
parent eddc3b0381
commit 3c886ccff8
4 changed files with 24 additions and 7 deletions

View File

@@ -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;

View File

@@ -716,12 +716,16 @@ a mapping <name>.
\fB<options>\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<options>\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.

View File

@@ -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]);

View File

@@ -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