support PIM parameter for VeraCrypt compatible devices

This patch adds the --veracrypt-pim=INT and --veracrypt-query-pim command-
line parameters to support specification of or being queried for a custom
Personal Iteration Multiplier respectively. This affects the number of
iterations for key derivation from the entered password. The manpage is
also updated accordingly.

Fixes Issue #307.
This commit is contained in:
Daniel Reichelt
2017-02-06 22:45:02 +01:00
committed by Milan Broz
parent 36419b25aa
commit 9a798a766e
5 changed files with 85 additions and 2 deletions

View File

@@ -338,6 +338,7 @@ struct crypt_params_tcrypt {
const char *mode; /**< cipher block mode */
size_t key_size; /**< key size in bytes (the whole chain) */
uint32_t flags; /**< CRYPT_TCRYPT* flags */
uint32_t veracrypt_pim; /**< VeraCrypt Personal Iteration Multiplier */
};
/** Include legacy modes when scanning for header */

View File

@@ -82,6 +82,7 @@ struct crypt_device {
char cipher[MAX_CIPHER_LEN];
char cipher_mode[MAX_CIPHER_LEN];
unsigned int key_size;
unsigned int veracrypt_pim;
} none;
} u;
@@ -571,6 +572,7 @@ static int _crypt_load_tcrypt(struct crypt_device *cd, struct crypt_params_tcryp
cd->u.tcrypt.params.passphrase_size = 0;
cd->u.tcrypt.params.keyfiles = NULL;
cd->u.tcrypt.params.keyfiles_count = 0;
cd->u.tcrypt.params.veracrypt_pim = 0;
if (r < 0)
return r;

View File

@@ -531,6 +531,14 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
continue;
if (!(params->flags & CRYPT_TCRYPT_VERA_MODES) && tcrypt_kdf[i].veracrypt)
continue;
if ((params->flags & CRYPT_TCRYPT_VERA_MODES) && params->veracrypt_pim) {
/* adjust iterations to given PIM cmdline parameter */
if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER)
tcrypt_kdf[i].iterations = params->veracrypt_pim * 2048;
else
tcrypt_kdf[i].iterations = 15000 + (params->veracrypt_pim * 1000);
}
/* Derive header key */
log_dbg("TCRYPT: trying KDF: %s-%s-%d.",
tcrypt_kdf[i].name, tcrypt_kdf[i].hash, tcrypt_kdf[i].iterations);

View File

@@ -450,11 +450,22 @@ Cryptsetup should recognize all header variants, except legacy cipher chains
using LRW encryption mode with 64 bits encryption block (namely Blowfish
in LRW mode is not recognized, this is limitation of kernel crypto API).
To recognize VeraCrypt device use \fB\-\-veracrypt\fR option.
To recognize a VeraCrypt device use the \fB\-\-veracrypt\fR option.
VeraCrypt is just extension of TrueCrypt header with increased
iteration count so unlocking can take quite a lot of time (in comparison
with TCRYPT device).
To open a VeraCrypt device with a custom Personal Iteration Multiplier (PIM)
value, \fBadditionally to --veracrypt \fR use either the
\fB--veracrypt-pim=<PIM>\fR option to directly specify the PIM on the command-
line or use \fB--veracrypt-query-pim\fR to be prompted for the PIM.
The PIM value affects the number of iterations applied during key derivation. Please refer to
\fBhttps://veracrypt.codeplex.com/wikipage?title=Personal%20Iterations%20Multiplier%20(PIM)\fR
for more detailed information.
\fBNOTE:\fR Activation with \fBtcryptOpen\fR is supported only for cipher chains
using LRW or XTS encryption modes.

View File

@@ -65,6 +65,8 @@ static int opt_tcrypt_hidden = 0;
static int opt_tcrypt_system = 0;
static int opt_tcrypt_backup = 0;
static int opt_veracrypt = 0;
static int opt_veracrypt_pim = -1;
static int opt_veracrypt_query_pim = 0;
static const char **action_argv;
static int action_argc;
@@ -249,6 +251,38 @@ static int tcrypt_load(struct crypt_device *cd, struct crypt_params_tcrypt *para
if (r < 0)
continue;
if (opt_veracrypt_query_pim) {
char *tmp_pim_nptr = NULL;
char *tmp_pim_end = " ";
size_t tmp_pim_size = 0;
unsigned long int tmp_pim_ul = 0;
r = tools_get_key(_("Enter VeraCrypt PIM: "),
CONST_CAST(char**)&tmp_pim_nptr,
&tmp_pim_size, 0, 0, opt_keyfile_stdin, opt_timeout,
_verify_passphrase(0), 0, cd);
if (r < 0)
continue;
tmp_pim_ul = strtoul(tmp_pim_nptr, &tmp_pim_end, 10);
if (*tmp_pim_nptr == '\0' || *tmp_pim_end != '\0') {
log_err(_("Invalid PIM value: parse error\n"));
r = -EINVAL;
} else if (tmp_pim_ul == 0) {
log_err(_("Invalid PIM value: 0\n"));
r = -EINVAL;
} else if (tmp_pim_ul > ((1L << (CHAR_BIT * sizeof(params->veracrypt_pim))) - 1)) {
log_err(_("Invalid PIM value: outside of range\n"));
r = -ERANGE;
}
crypt_safe_free(CONST_CAST(char*)tmp_pim_nptr);
if (r < 0)
continue;
params->veracrypt_pim = tmp_pim_ul;
tmp_pim_ul= 0;
}
if (opt_tcrypt_hidden)
params->flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
@@ -271,7 +305,7 @@ static int tcrypt_load(struct crypt_device *cd, struct crypt_params_tcrypt *para
params->passphrase_size = 0;
}
check_signal(&r);
} while (r == -EPERM && (--tries > 0));
} while ((r == -EPERM || r == -EINVAL || r == -ERANGE) && (--tries > 0));
/* Report wrong passphrase if at least one try failed */
if (eperm && r == -EPIPE)
@@ -288,6 +322,7 @@ static int action_open_tcrypt(void)
.keyfiles_count = opt_keyfiles_count,
.flags = CRYPT_TCRYPT_LEGACY_MODES |
(opt_veracrypt ? CRYPT_TCRYPT_VERA_MODES : 0),
.veracrypt_pim = (opt_veracrypt_pim > 0) ? opt_veracrypt_pim : 0,
};
const char *activated_name;
uint32_t activate_flags = 0;
@@ -1524,6 +1559,8 @@ int main(int argc, const char **argv)
{ "tcrypt-system", '\0', POPT_ARG_NONE, &opt_tcrypt_system, 0, N_("Device is system TCRYPT drive (with bootloader)."), NULL },
{ "tcrypt-backup", '\0', POPT_ARG_NONE, &opt_tcrypt_backup, 0, N_("Use backup (secondary) TCRYPT header."), NULL },
{ "veracrypt", '\0', POPT_ARG_NONE, &opt_veracrypt, 0, N_("Scan also for VeraCrypt compatible device."), NULL },
{ "veracrypt-pim", '\0', POPT_ARG_INT, &opt_veracrypt_pim, 0, N_("Personal Iteration Multiplier for for VeraCrypt compatible device."), NULL },
{ "veracrypt-query-pim", '\0', POPT_ARG_NONE, &opt_veracrypt_query_pim, 0, N_("Query Personal Iteration Multiplier for for VeraCrypt compatible device."), NULL },
{ "type", 'M', POPT_ARG_STRING, &opt_type, 0, N_("Type of device metadata: luks, plain, loopaes, tcrypt."), NULL },
{ "force-password", '\0', POPT_ARG_NONE, &opt_force_password, 0, N_("Disable password quality check (if enabled)."), NULL },
{ "perf-same_cpu_crypt",'\0', POPT_ARG_NONE, &opt_perf_same_cpu_crypt, 0, N_("Use dm-crypt same_cpu_crypt performance compatibility option."), NULL },
@@ -1755,6 +1792,30 @@ int main(int argc, const char **argv)
_("Option --veracrypt is supported only for TCRYPT device type.\n"),
poptGetInvocationName(popt_context));
if (opt_veracrypt_pim != -1) {
if (opt_veracrypt_pim < -1) {
usage(popt_context, EXIT_FAILURE,
_("Invalid argument for parameter --veracrypt-pim supplied.\n"),
poptGetInvocationName(popt_context));
} else if (!opt_veracrypt) {
usage(popt_context, EXIT_FAILURE,
_("Option --veracrypt-pim is supported only for VeraCrypt compatible devices.\n"),
poptGetInvocationName(popt_context));
}
}
if (opt_veracrypt_query_pim) {
if (!opt_veracrypt) {
usage(popt_context, EXIT_FAILURE,
_("Option --veracrypt-query-pim is supported only for VeraCrypt compatible devices.\n"),
poptGetInvocationName(popt_context));
} else if (opt_veracrypt_pim != -1) {
usage(popt_context, EXIT_FAILURE,
_("The options --veracrypt-pim and --veracrypt-query-pim are mutually exclusive.\n"),
poptGetInvocationName(popt_context));
}
}
if (opt_debug) {
opt_verbose = 1;
crypt_set_debug_level(-1);