mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-10 02:10:01 +01:00
Support VeraCrypt devices (TrueCrypt extension).
Add CRYPT_TCRYPT_VERA_MODES libcryptswtup flag and --veracrypt option. Fixes issue#245.
This commit is contained in:
@@ -405,7 +405,7 @@ struct crypt_params_tcrypt {
|
||||
uint32_t flags; /**< CRYPT_TCRYPT* flags */
|
||||
};
|
||||
|
||||
/** Include legacy modes ehn scannig for header*/
|
||||
/** Include legacy modes for header*/
|
||||
#define CRYPT_TCRYPT_LEGACY_MODES (1 << 0)
|
||||
/** Try to load hidden header (describing hidden device) */
|
||||
#define CRYPT_TCRYPT_HIDDEN_HEADER (1 << 1)
|
||||
@@ -413,6 +413,8 @@ struct crypt_params_tcrypt {
|
||||
#define CRYPT_TCRYPT_BACKUP_HEADER (1 << 2)
|
||||
/** Device contains encrypted system (with boot loader) */
|
||||
#define CRYPT_TCRYPT_SYSTEM_HEADER (1 << 3)
|
||||
/** Include Veracrypt modes for header*/
|
||||
#define CRYPT_TCRYPT_VERA_MODES (1 << 4)
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*
|
||||
* TCRYPT (TrueCrypt-compatible) volume handling
|
||||
* TCRYPT (TrueCrypt-compatible) and VeraCrypt volume handling
|
||||
*
|
||||
* Copyright (C) 2012, Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2012-2014, Milan Broz
|
||||
* Copyright (C) 2012-2015, Milan Broz
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -33,16 +33,23 @@
|
||||
/* TCRYPT PBKDF variants */
|
||||
static struct {
|
||||
unsigned int legacy:1;
|
||||
unsigned int veracrypt:1;
|
||||
const char *name;
|
||||
const char *hash;
|
||||
unsigned int iterations;
|
||||
} tcrypt_kdf[] = {
|
||||
{ 0, "pbkdf2", "ripemd160", 2000 },
|
||||
{ 0, "pbkdf2", "ripemd160", 1000 },
|
||||
{ 0, "pbkdf2", "sha512", 1000 },
|
||||
{ 0, "pbkdf2", "whirlpool", 1000 },
|
||||
{ 1, "pbkdf2", "sha1", 2000 },
|
||||
{ 0, NULL, NULL, 0 }
|
||||
{ 0, 0, "pbkdf2", "ripemd160", 2000 },
|
||||
{ 0, 0, "pbkdf2", "ripemd160", 1000 },
|
||||
{ 0, 0, "pbkdf2", "sha512", 1000 },
|
||||
{ 0, 0, "pbkdf2", "whirlpool", 1000 },
|
||||
{ 1, 0, "pbkdf2", "sha1", 2000 },
|
||||
{ 0, 1, "pbkdf2", "sha512", 500000 },
|
||||
{ 0, 1, "pbkdf2", "whirlpool", 500000 },
|
||||
{ 0, 1, "pbkdf2", "sha256", 500000 }, // VeraCrypt 1.0f
|
||||
{ 0, 1, "pbkdf2", "sha256", 200000 }, // boot only
|
||||
{ 0, 1, "pbkdf2", "ripemd160", 655331 },
|
||||
{ 0, 1, "pbkdf2", "ripemd160", 327661 }, // boot only
|
||||
{ 0, 0, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
struct tcrypt_alg {
|
||||
@@ -196,7 +203,7 @@ static int TCRYPT_hdr_from_disk(struct tcrypt_phdr *hdr,
|
||||
|
||||
/* Convert header to cpu format */
|
||||
hdr->d.version = be16_to_cpu(hdr->d.version);
|
||||
hdr->d.version_tc = le16_to_cpu(hdr->d.version_tc);
|
||||
hdr->d.version_tc = be16_to_cpu(hdr->d.version_tc);
|
||||
|
||||
hdr->d.keys_crc32 = be32_to_cpu(hdr->d.keys_crc32);
|
||||
|
||||
@@ -393,13 +400,13 @@ out:
|
||||
}
|
||||
|
||||
static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
|
||||
const char *key, int legacy_modes)
|
||||
const char *key, uint32_t flags)
|
||||
{
|
||||
struct tcrypt_phdr hdr2;
|
||||
int i, j, r = -EINVAL;
|
||||
|
||||
for (i = 0; tcrypt_cipher[i].chain_count; i++) {
|
||||
if (!legacy_modes && tcrypt_cipher[i].legacy)
|
||||
if (!(flags & CRYPT_TCRYPT_LEGACY_MODES) && tcrypt_cipher[i].legacy)
|
||||
continue;
|
||||
log_dbg("TCRYPT: trying cipher %s-%s",
|
||||
tcrypt_cipher[i].long_name, tcrypt_cipher[i].mode);
|
||||
@@ -431,6 +438,13 @@ static int TCRYPT_decrypt_hdr(struct crypt_device *cd, struct tcrypt_phdr *hdr,
|
||||
r = i;
|
||||
break;
|
||||
}
|
||||
if ((flags & CRYPT_TCRYPT_VERA_MODES) &&
|
||||
!strncmp(hdr2.d.magic, VCRYPT_HDR_MAGIC, TCRYPT_HDR_MAGIC_LEN)) {
|
||||
log_dbg("TCRYPT: Signature magic detected (Veracrypt).");
|
||||
memcpy(&hdr->e, &hdr2.e, TCRYPT_HDR_LEN);
|
||||
r = i;
|
||||
break;
|
||||
}
|
||||
r = -EPERM;
|
||||
}
|
||||
|
||||
@@ -485,7 +499,7 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
size_t passphrase_size;
|
||||
char *key;
|
||||
unsigned int i, skipped = 0;
|
||||
int r = -EPERM, legacy_modes;
|
||||
int r = -EPERM;
|
||||
|
||||
if (posix_memalign((void*)&key, crypt_getpagesize(), TCRYPT_HDR_KEY_LEN))
|
||||
return -ENOMEM;
|
||||
@@ -512,9 +526,10 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
for (i = 0; i < params->passphrase_size; i++)
|
||||
pwd[i] += params->passphrase[i];
|
||||
|
||||
legacy_modes = params->flags & CRYPT_TCRYPT_LEGACY_MODES ? 1 : 0;
|
||||
for (i = 0; tcrypt_kdf[i].name; i++) {
|
||||
if (!legacy_modes && tcrypt_kdf[i].legacy)
|
||||
if (!(params->flags & CRYPT_TCRYPT_LEGACY_MODES) && tcrypt_kdf[i].legacy)
|
||||
continue;
|
||||
if (!(params->flags & CRYPT_TCRYPT_VERA_MODES) && tcrypt_kdf[i].veracrypt)
|
||||
continue;
|
||||
/* Derive header key */
|
||||
log_dbg("TCRYPT: trying KDF: %s-%s-%d.",
|
||||
@@ -533,7 +548,7 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
break;
|
||||
|
||||
/* Decrypt header */
|
||||
r = TCRYPT_decrypt_hdr(cd, hdr, key, legacy_modes);
|
||||
r = TCRYPT_decrypt_hdr(cd, hdr, key, params->flags);
|
||||
if (r == -ENOENT) {
|
||||
skipped++;
|
||||
r = -EPERM;
|
||||
@@ -553,10 +568,11 @@ static int TCRYPT_init_hdr(struct crypt_device *cd,
|
||||
|
||||
r = TCRYPT_hdr_from_disk(hdr, params, i, r);
|
||||
if (!r) {
|
||||
log_dbg("TCRYPT: Header version: %d, req. %d, sector %d"
|
||||
log_dbg("TCRYPT: Magic: %s, Header version: %d, req. %d, sector %d"
|
||||
", mk_offset %" PRIu64 ", hidden_size %" PRIu64
|
||||
", volume size %" PRIu64, (int)hdr->d.version,
|
||||
(int)hdr->d.version_tc, (int)hdr->d.sector_size,
|
||||
", volume size %" PRIu64, tcrypt_kdf[i].veracrypt ?
|
||||
VCRYPT_HDR_MAGIC : TCRYPT_HDR_MAGIC,
|
||||
(int)hdr->d.version, (int)hdr->d.version_tc, (int)hdr->d.sector_size,
|
||||
hdr->d.mk_offset, hdr->d.hidden_volume_size, hdr->d.volume_size);
|
||||
log_dbg("TCRYPT: Header cipher %s-%s, key size %zu",
|
||||
params->cipher, params->mode, params->key_size);
|
||||
@@ -1026,11 +1042,13 @@ int TCRYPT_dump(struct crypt_device *cd,
|
||||
struct tcrypt_phdr *hdr,
|
||||
struct crypt_params_tcrypt *params)
|
||||
{
|
||||
log_std(cd, "TCRYPT header information for %s\n",
|
||||
log_std(cd, "%s header information for %s\n",
|
||||
hdr->d.magic[0] == 'T' ? "TCRYPT" : "VERACRYPT",
|
||||
device_path(crypt_metadata_device(cd)));
|
||||
if (hdr->d.version) {
|
||||
log_std(cd, "Version: \t%d\n", hdr->d.version);
|
||||
log_std(cd, "Driver req.:\t%d\n", hdr->d.version_tc);
|
||||
log_std(cd, "Driver req.:\t%x.%x\n", hdr->d.version_tc >> 8,
|
||||
hdr->d.version_tc & 0xFF);
|
||||
|
||||
log_std(cd, "Sector size:\t%" PRIu32 "\n", hdr->d.sector_size);
|
||||
log_std(cd, "MK offset:\t%" PRIu64 "\n", hdr->d.mk_offset);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#define TCRYPT_HDR_LEN 448
|
||||
#define TCRYPT_HDR_KEY_LEN 192
|
||||
#define TCRYPT_HDR_MAGIC "TRUE"
|
||||
#define VCRYPT_HDR_MAGIC "VERA"
|
||||
#define TCRYPT_HDR_MAGIC_LEN 4
|
||||
|
||||
#define TCRYPT_HDR_HIDDEN_OFFSET_OLD -1536
|
||||
|
||||
@@ -419,8 +419,9 @@ size).
|
||||
.PP
|
||||
See also section 7 of the FAQ and \fBhttp://loop-aes.sourceforge.net\fR
|
||||
for more information regarding loop-AES.
|
||||
.SH TCRYPT (TrueCrypt-compatible) EXTENSION
|
||||
cryptsetup supports mapping of TrueCrypt or tcplay encrypted partition
|
||||
.SH TCRYPT (TrueCrypt-compatible and VeraCrypt) EXTENSION
|
||||
cryptsetup supports mapping of TrueCrypt, tcplay or VeraCrypt
|
||||
(with \fB\-\-veracrypt\fR option) encrypted partition
|
||||
using a native Linux kernel API.
|
||||
Header formatting and TCRYPT header change is not supported, cryptsetup
|
||||
never changes TCRYPT header on-device.
|
||||
@@ -438,6 +439,11 @@ 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.
|
||||
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).
|
||||
|
||||
\fBNOTE:\fR Activation with \fBtcryptOpen\fR is supported only for cipher chains
|
||||
using LRW or XTS encryption modes.
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ static int opt_test_passphrase = 0;
|
||||
static int opt_tcrypt_hidden = 0;
|
||||
static int opt_tcrypt_system = 0;
|
||||
static int opt_tcrypt_backup = 0;
|
||||
static int opt_veracrypt = 0;
|
||||
|
||||
static const char **action_argv;
|
||||
static int action_argc;
|
||||
@@ -288,7 +289,8 @@ static int action_open_tcrypt(void)
|
||||
struct crypt_params_tcrypt params = {
|
||||
.keyfiles = opt_keyfiles,
|
||||
.keyfiles_count = opt_keyfiles_count,
|
||||
.flags = CRYPT_TCRYPT_LEGACY_MODES,
|
||||
.flags = CRYPT_TCRYPT_LEGACY_MODES |
|
||||
(opt_veracrypt ? CRYPT_TCRYPT_VERA_MODES : 0),
|
||||
};
|
||||
const char *activated_name;
|
||||
uint32_t activate_flags = 0;
|
||||
@@ -361,7 +363,8 @@ static int action_tcryptDump(void)
|
||||
struct crypt_params_tcrypt params = {
|
||||
.keyfiles = opt_keyfiles,
|
||||
.keyfiles_count = opt_keyfiles_count,
|
||||
.flags = CRYPT_TCRYPT_LEGACY_MODES,
|
||||
.flags = CRYPT_TCRYPT_LEGACY_MODES |
|
||||
(opt_veracrypt ? CRYPT_TCRYPT_VERA_MODES : 0),
|
||||
};
|
||||
int r;
|
||||
|
||||
@@ -1505,6 +1508,7 @@ int main(int argc, const char **argv)
|
||||
{ "tcrypt-hidden", '\0', POPT_ARG_NONE, &opt_tcrypt_hidden, 0, N_("Use hidden header (hidden TCRYPT device)."), NULL },
|
||||
{ "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 },
|
||||
{ "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 },
|
||||
@@ -1609,6 +1613,8 @@ int main(int argc, const char **argv)
|
||||
} else if (!strcmp(aname, "tcryptOpen")) {
|
||||
aname = "open";
|
||||
opt_type = "tcrypt";
|
||||
} else if (!strcmp(aname, "tcryptDump")) {
|
||||
opt_type = "tcrypt";
|
||||
} else if (!strcmp(aname, "remove") ||
|
||||
!strcmp(aname, "plainClose") ||
|
||||
!strcmp(aname, "luksClose") ||
|
||||
@@ -1724,6 +1730,11 @@ int main(int argc, const char **argv)
|
||||
_("Option --tcrypt-hidden cannot be combined with --allow-discards.\n"),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_veracrypt && strcmp(opt_type, "tcrypt"))
|
||||
usage(popt_context, EXIT_FAILURE,
|
||||
_("Option --veracrypt is supported only for TCRYPT device type.\n"),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_debug) {
|
||||
opt_verbose = 1;
|
||||
crypt_set_debug_level(-1);
|
||||
|
||||
@@ -70,23 +70,23 @@ export LANG=C
|
||||
[ ! -d $TST_DIR ] && tar xjf tcrypt-images.tar.bz2
|
||||
|
||||
echo "HEADER CHECK"
|
||||
for file in $(ls $TST_DIR/tc_*) ; do
|
||||
for file in $(ls $TST_DIR/[tv]c_*) ; do
|
||||
echo -n " $file"
|
||||
echo $PASSWORD | $CRYPTSETUP tcryptDump $file >/dev/null || fail
|
||||
echo $PASSWORD | $CRYPTSETUP tcryptDump --veracrypt $file >/dev/null || fail
|
||||
echo " [OK]"
|
||||
done
|
||||
|
||||
echo "HEADER CHECK (HIDDEN)"
|
||||
for file in $(ls $TST_DIR/tc_*-hidden) ; do
|
||||
for file in $(ls $TST_DIR/[tv]c_*-hidden) ; do
|
||||
echo -n " $file (hidden)"
|
||||
echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptDump --tcrypt-hidden $file >/dev/null || fail
|
||||
echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptDump --tcrypt-hidden --veracrypt $file >/dev/null || fail
|
||||
echo " [OK]"
|
||||
done
|
||||
|
||||
echo "HEADER KEYFILES CHECK"
|
||||
for file in $(ls $TST_DIR/tck_*) ; do
|
||||
for file in $(ls $TST_DIR/[tv]ck_*) ; do
|
||||
echo -n " $file"
|
||||
echo $PASSWORD | $CRYPTSETUP tcryptDump -d $TST_DIR/keyfile1 -d $TST_DIR/keyfile2 $file >/dev/null || fail
|
||||
echo $PASSWORD | $CRYPTSETUP tcryptDump --veracrypt -d $TST_DIR/keyfile1 -d $TST_DIR/keyfile2 $file >/dev/null || fail
|
||||
echo " [OK]"
|
||||
done
|
||||
|
||||
@@ -97,9 +97,9 @@ if [ $(id -u) != 0 ]; then
|
||||
fi
|
||||
|
||||
echo "ACTIVATION FS UUID CHECK"
|
||||
for file in $(ls $TST_DIR/tc_*) ; do
|
||||
for file in $(ls $TST_DIR/[tv]c_*) ; do
|
||||
echo -n " $file"
|
||||
out=$(echo $PASSWORD | $CRYPTSETUP tcryptOpen -r $file $MAP 2>&1)
|
||||
out=$(echo $PASSWORD | $CRYPTSETUP tcryptOpen --veracrypt -r $file $MAP 2>&1)
|
||||
ret=$?
|
||||
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT legacy mode" ) && echo " [N/A]" && continue
|
||||
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT compatible mapping" ) && echo " [N/A]" && continue
|
||||
@@ -113,9 +113,9 @@ for file in $(ls $TST_DIR/tc_*) ; do
|
||||
done
|
||||
|
||||
echo "ACTIVATION FS UUID (HIDDEN) CHECK"
|
||||
for file in $(ls $TST_DIR/tc_*-hidden) ; do
|
||||
for file in $(ls $TST_DIR/[tv]c_*-hidden) ; do
|
||||
echo -n " $file"
|
||||
out=$(echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptOpen -r $file $MAP --tcrypt-hidden 2>&1)
|
||||
out=$(echo $PASSWORD_HIDDEN | $CRYPTSETUP tcryptOpen --veracrypt -r $file $MAP --tcrypt-hidden 2>&1)
|
||||
ret=$?
|
||||
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT legacy mode" ) && echo " [N/A]" && continue
|
||||
[ $ret -eq 1 ] && ( echo "$out" | grep -q -e "TCRYPT compatible mapping" ) && echo " [N/A]" && continue
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user