From 703902400df2eced5374ab396ff5199f29a5db96 Mon Sep 17 00:00:00 2001 From: Klaus Zipfel <30482165+systemofapwne@users.noreply.github.com> Date: Sat, 6 May 2023 22:55:05 +0200 Subject: [PATCH] crypttab: Support for VeraCrypt PIM and detached headers for TrueCrypt/VeraCrypt (#27548) * Added veracrypt-pim= LUKS option for crypttab --- man/crypttab.xml | 28 +++++++++++++++++++++++----- src/cryptsetup/cryptsetup.c | 23 ++++++++++++++++++++--- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/man/crypttab.xml b/man/crypttab.xml index d587f85289..f977fd694d 100644 --- a/man/crypttab.xml +++ b/man/crypttab.xml @@ -172,12 +172,11 @@ - Use a detached (separated) metadata device or - file where the LUKS header is stored. This option is only - relevant for LUKS devices. See + Use a detached (separated) metadata device or file + where the header containing the master key(s) is stored. This + option is only relevant for LUKS and TrueCrypt/VeraCrypt devices. See cryptsetup8 - for possible values and the default value of this - option. + for possible values and the default value of this option. Optionally, the path may be followed by : and an /etc/fstab device specification (e.g. starting with UUID= or @@ -483,6 +482,25 @@ option implies . + + + + Specifies a custom Personal Iteration Multiplier (PIM) + value, which can range from 0..2147468 for standard veracrypt volumes + and 0..65535 for veracrypt system volumes. A value of 0 will imply the + VeraCrypt default. + + This option is only effective when is + set. + + Note that VeraCrypt enforces a minimal allowed PIM value depending on the + password strength and the hash algorithm used for key derivation, however + is not checked against these bounds. + See + documentation for more information. + + + diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 9105b662ce..d94cb00e69 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -81,6 +81,7 @@ static bool arg_no_write_workqueue = false; static bool arg_tcrypt_hidden = false; static bool arg_tcrypt_system = false; static bool arg_tcrypt_veracrypt = false; +static uint32_t arg_tcrypt_veracrypt_pim = 0; static char **arg_tcrypt_keyfiles = NULL; static uint64_t arg_offset = 0; static uint64_t arg_skip = 0; @@ -233,7 +234,8 @@ static int parse_one_option(const char *option) { return log_oom(); } else if ((val = startswith(option, "header="))) { - arg_type = ANY_LUKS; + if (!STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT)) + arg_type = ANY_LUKS; if (!path_is_absolute(val)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), @@ -298,6 +300,13 @@ static int parse_one_option(const char *option) { } else if (STR_IN_SET(option, "tcrypt-veracrypt", "veracrypt")) { arg_type = CRYPT_TCRYPT; arg_tcrypt_veracrypt = true; + } else if ((val = startswith(option, "veracrypt-pim="))) { + + r = safe_atou32(val, &arg_tcrypt_veracrypt_pim); + if (r < 0) { + log_warning_errno(r, "Failed to parse %s, ignoring: %m", option); + return 0; + } } else if (STR_IN_SET(option, "plain", "swap", "tmp") || startswith(option, "tmp=")) arg_type = CRYPT_PLAIN; @@ -981,6 +990,9 @@ static int attach_tcrypt( if (arg_tcrypt_veracrypt) params.flags |= CRYPT_TCRYPT_VERA_MODES; + + if (arg_tcrypt_veracrypt && arg_tcrypt_veracrypt_pim != 0) + params.veracrypt_pim = arg_tcrypt_veracrypt_pim; if (key_data) { params.passphrase = key_data; @@ -2157,8 +2169,13 @@ static int run(int argc, char *argv[]) { destroy_key_file = key_file; /* let's get this baby erased when we leave */ if (arg_header) { - log_debug("LUKS header: %s", arg_header); - r = crypt_init(&cd, arg_header); + if (streq_ptr(arg_type, CRYPT_TCRYPT)){ + log_debug("tcrypt header: %s", arg_header); + r = crypt_init_data_device(&cd, arg_header, source); + } else { + log_debug("LUKS header: %s", arg_header); + r = crypt_init(&cd, arg_header); + } } else r = crypt_init(&cd, source); if (r < 0)