Commit a22a24bc authored by Milan Broz's avatar Milan Broz

Support detached header for cryptsetup-reencrypt.

This patch allows encryption/decryption of the whole device,
IOW add encryption later with detached header.

This operation can be dangerous, there is no fixed bindings between
the specific LUKS header and data device (encrypted data device
contains no magic signatures).
parent b7c24658
...@@ -35,14 +35,14 @@ To start (or continue) re-encryption for <device> use: ...@@ -35,14 +35,14 @@ To start (or continue) re-encryption for <device> use:
\fIcryptsetup-reencrypt\fR <device> \fIcryptsetup-reencrypt\fR <device>
\fB<options>\fR can be [\-\-batch-mode, \-\-block-size, \-\-cipher | \-\-keep-key, \fB<options>\fR can be [\-\-batch-mode, \-\-block-size, \-\-cipher | \-\-keep-key,
\-\-debug, \-\-device-size, \-\-hash, \-\-iter-time | \-\-pbkdf\-force\-iterations, \-\-debug, \-\-device-size, \-\-hash, \-\-header, \-\-iter-time | \-\-pbkdf\-force\-iterations,
\-\-key-file, \-\-key-size, \-\-key-slot, \-\-keyfile-offset, \-\-keyfile-size, \-\-key-file, \-\-key-size, \-\-key-slot, \-\-keyfile-offset, \-\-keyfile-size,
\-\-tries, \-\-pbkdf, \-\-pbkdf\-memory, \-\-pbkdf\-parallel, \-\-progress-frequency, \-\-tries, \-\-pbkdf, \-\-pbkdf\-memory, \-\-pbkdf\-parallel, \-\-progress-frequency,
\-\-use-directio, \-\-use-random | \-\-use-urandom, \-\-use-fsync, \-\-uuid, \-\-use-directio, \-\-use-random | \-\-use-urandom, \-\-use-fsync, \-\-uuid,
\-\-verbose, \-\-write-log] \-\-verbose, \-\-write-log]
To encrypt data on (not yet encrypted) device, use \fI\-\-new\fR with combination To encrypt data on (not yet encrypted) device, use \fI\-\-new\fR with combination
with \fI\-\-reduce-device-size\fR. with \fI\-\-reduce-device-size\fR or with \fI\-\-header\fR option for detached header.
To remove encryption from device, use \fI\-\-decrypt\fR. To remove encryption from device, use \fI\-\-decrypt\fR.
...@@ -89,7 +89,17 @@ Specifies the hash used in the LUKS1 key setup scheme and volume key digest. ...@@ -89,7 +89,17 @@ Specifies the hash used in the LUKS1 key setup scheme and volume key digest.
for new LUKS1 device header. for new LUKS1 device header.
\fBNOTE:\fR with LUKS2 format this option is only relevant when new keyslot pbkdf algorithm \fBNOTE:\fR with LUKS2 format this option is only relevant when new keyslot pbkdf algorithm
is set to PBKDF2 (see \fI\-\-pbkdf). is set to PBKDF2 (see \fI\-\-pbkdf\fR).
.TP
.B "\-\-header\fR \fI<LUKS header file>\fR"
Use a detached (separated) metadata device or file where the
LUKS header is stored. This option allows one to store ciphertext
and LUKS header on different devices.
\fBWARNING:\fR There is no check whether the ciphertext device specified
actually belongs to the header given.
If used with \fI\-\-new\fR option, the header file will created (or overwritten).
Use with care.
.TP .TP
.B "\-\-iter-time, \-i \fI<milliseconds>\fR" .B "\-\-iter-time, \-i \fI<milliseconds>\fR"
The number of milliseconds to spend with PBKDF2 passphrase processing for the The number of milliseconds to spend with PBKDF2 passphrase processing for the
......
...@@ -55,6 +55,7 @@ static int opt_key_size = 0; ...@@ -55,6 +55,7 @@ static int opt_key_size = 0;
static int opt_new = 0; static int opt_new = 0;
static int opt_keep_key = 0; static int opt_keep_key = 0;
static int opt_decrypt = 0; static int opt_decrypt = 0;
static const char *opt_header_device = NULL;
static const char *opt_reduce_size_str = NULL; static const char *opt_reduce_size_str = NULL;
static uint64_t opt_reduce_size = 0; static uint64_t opt_reduce_size = 0;
...@@ -68,6 +69,7 @@ static const char **action_argv; ...@@ -68,6 +69,7 @@ static const char **action_argv;
#define MAX_TOKEN 32 #define MAX_TOKEN 32
struct reenc_ctx { struct reenc_ctx {
char *device; char *device;
char *device_header;
char *device_uuid; char *device_uuid;
const char *type; const char *type;
uint64_t device_size; /* overridden by parameter */ uint64_t device_size; /* overridden by parameter */
...@@ -147,6 +149,11 @@ static const char *luksType(const char *type) ...@@ -147,6 +149,11 @@ static const char *luksType(const char *type)
return NULL; return NULL;
} }
static const char *hdr_device(const struct reenc_ctx *rc)
{
return rc->device_header ?: rc->device;
}
static int set_reencrypt_requirement(const struct reenc_ctx *rc) static int set_reencrypt_requirement(const struct reenc_ctx *rc)
{ {
uint32_t reqs; uint32_t reqs;
...@@ -154,7 +161,7 @@ static int set_reencrypt_requirement(const struct reenc_ctx *rc) ...@@ -154,7 +161,7 @@ static int set_reencrypt_requirement(const struct reenc_ctx *rc)
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_params_integrity ip = { 0 }; struct crypt_params_integrity ip = { 0 };
if (crypt_init(&cd, rc->device) || if (crypt_init(&cd, hdr_device(rc)) ||
crypt_load(cd, CRYPT_LUKS2, NULL) || crypt_load(cd, CRYPT_LUKS2, NULL) ||
crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &reqs)) crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &reqs))
goto out; goto out;
...@@ -179,7 +186,7 @@ out: ...@@ -179,7 +186,7 @@ out:
} }
/* Depends on the first two fields of LUKS1 header format, magic and version */ /* Depends on the first two fields of LUKS1 header format, magic and version */
static int device_check(struct reenc_ctx *rc, header_magic set_magic) static int device_check(struct reenc_ctx *rc, const char *device, header_magic set_magic)
{ {
char *buf = NULL; char *buf = NULL;
int r, devfd; int r, devfd;
...@@ -187,14 +194,14 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic) ...@@ -187,14 +194,14 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic)
uint16_t version; uint16_t version;
size_t buf_size = pagesize(); size_t buf_size = pagesize();
devfd = open(rc->device, O_RDWR | O_EXCL | O_DIRECT); devfd = open(device, O_RDWR | O_EXCL | O_DIRECT);
if (devfd == -1) { if (devfd == -1) {
if (errno == EBUSY) { if (errno == EBUSY) {
log_err(_("Cannot exclusively open %s, device in use.\n"), log_err(_("Cannot exclusively open %s, device in use.\n"),
rc->device); device);
return -EBUSY; return -EBUSY;
} }
log_err(_("Cannot open device %s.\n"), rc->device); log_err(_("Cannot open device %s.\n"), device);
return -EINVAL; return -EINVAL;
} }
...@@ -211,7 +218,7 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic) ...@@ -211,7 +218,7 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic)
s = read(devfd, buf, buf_size); s = read(devfd, buf, buf_size);
if (s < 0 || s != (ssize_t)buf_size) { if (s < 0 || s != (ssize_t)buf_size) {
log_err(_("Cannot read device %s.\n"), rc->device); log_err(_("Cannot read device %s.\n"), device);
r = -EIO; r = -EIO;
goto out; goto out;
} }
...@@ -222,11 +229,11 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic) ...@@ -222,11 +229,11 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic)
if (set_magic == MAKE_UNUSABLE && !memcmp(buf, MAGIC, MAGIC_L) && if (set_magic == MAKE_UNUSABLE && !memcmp(buf, MAGIC, MAGIC_L) &&
version == 1) { version == 1) {
log_verbose(_("Marking LUKS1 device %s unusable.\n"), rc->device); log_verbose(_("Marking LUKS1 device %s unusable.\n"), device);
memcpy(buf, NOMAGIC, MAGIC_L); memcpy(buf, NOMAGIC, MAGIC_L);
r = 0; r = 0;
} else if (set_magic == MAKE_UNUSABLE && version == 2) { } else if (set_magic == MAKE_UNUSABLE && version == 2) {
log_verbose(_("Setting LUKS2 offline reencrypt flag on device %s.\n"), rc->device); log_verbose(_("Setting LUKS2 offline reencrypt flag on device %s.\n"), device);
r = set_reencrypt_requirement(rc); r = set_reencrypt_requirement(rc);
if (!r) if (!r)
rc->stained = 1; rc->stained = 1;
...@@ -243,14 +250,14 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic) ...@@ -243,14 +250,14 @@ static int device_check(struct reenc_ctx *rc, header_magic set_magic)
goto out; goto out;
s = write(devfd, buf, buf_size); s = write(devfd, buf, buf_size);
if (s < 0 || s != (ssize_t)buf_size) { if (s < 0 || s != (ssize_t)buf_size) {
log_err(_("Cannot write device %s.\n"), rc->device); log_err(_("Cannot write device %s.\n"), device);
r = -EIO; r = -EIO;
} }
if (s > 0 && set_magic == MAKE_UNUSABLE) if (s > 0 && set_magic == MAKE_UNUSABLE)
rc->stained = 1; rc->stained = 1;
} }
if (r) if (r)
log_dbg("LUKS signature check failed for %s.", rc->device); log_dbg("LUKS signature check failed for %s.", device);
out: out:
if (buf) if (buf)
memset(buf, 0, buf_size); memset(buf, 0, buf_size);
...@@ -284,7 +291,7 @@ static int create_empty_header(const char *new_file, const char *old_file, ...@@ -284,7 +291,7 @@ static int create_empty_header(const char *new_file, const char *old_file,
* if requesting key size change, try to use offset * if requesting key size change, try to use offset
* here can be enough space to fit new key. * here can be enough space to fit new key.
*/ */
if (opt_key_size) if (opt_key_size && data_sector)
size = data_sector * SECTOR_SIZE; size = data_sector * SECTOR_SIZE;
/* if reducing size, be sure we have enough space */ /* if reducing size, be sure we have enough space */
...@@ -663,9 +670,9 @@ static int backup_luks_headers(struct reenc_ctx *rc) ...@@ -663,9 +670,9 @@ static int backup_luks_headers(struct reenc_ctx *rc)
size_t old_key_size; size_t old_key_size;
int r; int r;
log_dbg("Creating LUKS header backup for device %s.", rc->device); log_dbg("Creating LUKS header backup for device %s.", hdr_device(rc));
if ((r = crypt_init(&cd, rc->device)) || if ((r = crypt_init(&cd, hdr_device(rc))) ||
(r = crypt_load(cd, CRYPT_LUKS, NULL))) (r = crypt_load(cd, CRYPT_LUKS, NULL)))
goto out; goto out;
...@@ -834,21 +841,42 @@ static void remove_headers(struct reenc_ctx *rc) ...@@ -834,21 +841,42 @@ static void remove_headers(struct reenc_ctx *rc)
static int restore_luks_header(struct reenc_ctx *rc) static int restore_luks_header(struct reenc_ctx *rc)
{ {
struct stat st;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r; int fd, r;
log_dbg("Restoring header for %s from %s.", rc->device, rc->header_file_new); log_dbg("Restoring header for %s from %s.", hdr_device(rc), rc->header_file_new);
r = crypt_init(&cd, rc->device); /*
* For new encryption and new detached header in file just move it.
* For existing file try to ensure we have prealocated space for restore.
*/
if (opt_new && rc->device_header) {
r = stat(rc->device_header, &st);
if (r == -1) {
r = rename(rc->header_file_new, rc->device_header);
goto out;
} else if ((st.st_mode & S_IFMT) == S_IFREG &&
stat(rc->header_file_new, &st) != -1) {
fd = open(rc->device_header, O_WRONLY);
if (fd != -1) {
posix_fallocate(fd, 0, st.st_size);
close(fd);
}
}
}
r = crypt_init(&cd, hdr_device(rc));
if (r == 0) { if (r == 0) {
r = crypt_header_restore(cd, rc->type, rc->header_file_new); r = crypt_header_restore(cd, rc->type, rc->header_file_new);
} }
crypt_free(cd); crypt_free(cd);
out:
if (r) if (r)
log_err(_("Cannot restore %s header on device %s.\n"), rc->device, isLUKS2(rc->type) ? "LUKS2" : "LUKS1"); log_err(_("Cannot restore %s header on device %s.\n"), hdr_device(rc), isLUKS2(rc->type) ? "LUKS2" : "LUKS1");
else { else {
log_verbose(_("%s header on device %s restored.\n"), rc->device, isLUKS2(rc->type) ? "LUKS2" : "LUKS1"); log_verbose(_("%s header on device %s restored.\n"), hdr_device(rc), isLUKS2(rc->type) ? "LUKS2" : "LUKS1");
rc->stained = 0; rc->stained = 0;
} }
return r; return r;
...@@ -1140,7 +1168,7 @@ static int initialize_uuid(struct reenc_ctx *rc) ...@@ -1140,7 +1168,7 @@ static int initialize_uuid(struct reenc_ctx *rc)
} }
/* Try to load LUKS from device */ /* Try to load LUKS from device */
if ((r = crypt_init(&cd, rc->device))) if ((r = crypt_init(&cd, hdr_device(rc))))
return r; return r;
crypt_set_log_callback(cd, _quiet_log, NULL); crypt_set_log_callback(cd, _quiet_log, NULL);
r = crypt_load(cd, CRYPT_LUKS, NULL); r = crypt_load(cd, CRYPT_LUKS, NULL);
...@@ -1148,7 +1176,7 @@ static int initialize_uuid(struct reenc_ctx *rc) ...@@ -1148,7 +1176,7 @@ static int initialize_uuid(struct reenc_ctx *rc)
rc->device_uuid = strdup(crypt_get_uuid(cd)); rc->device_uuid = strdup(crypt_get_uuid(cd));
else else
/* Reencryption already in progress - magic header? */ /* Reencryption already in progress - magic header? */
r = device_check(rc, CHECK_UNUSABLE); r = device_check(rc, hdr_device(rc), CHECK_UNUSABLE);
if (!r) if (!r)
rc->type = isLUKS2(crypt_get_type(cd)) ? CRYPT_LUKS2 : CRYPT_LUKS1; rc->type = isLUKS2(crypt_get_type(cd)) ? CRYPT_LUKS2 : CRYPT_LUKS1;
...@@ -1309,7 +1337,10 @@ static int initialize_context(struct reenc_ctx *rc, const char *device) ...@@ -1309,7 +1337,10 @@ static int initialize_context(struct reenc_ctx *rc, const char *device)
if (!(rc->device = strndup(device, PATH_MAX))) if (!(rc->device = strndup(device, PATH_MAX)))
return -ENOMEM; return -ENOMEM;
if (device_check(rc, CHECK_OPEN) < 0) if (opt_header_device && !(rc->device_header = strndup(opt_header_device, PATH_MAX)))
return -ENOMEM;
if (device_check(rc, rc->device, CHECK_OPEN) < 0)
return -EINVAL; return -EINVAL;
if (initialize_uuid(rc)) { if (initialize_uuid(rc)) {
...@@ -1397,6 +1428,7 @@ static void destroy_context(struct reenc_ctx *rc) ...@@ -1397,6 +1428,7 @@ static void destroy_context(struct reenc_ctx *rc)
crypt_safe_free(rc->p[i].password); crypt_safe_free(rc->p[i].password);
free(rc->device); free(rc->device);
free(rc->device_header);
free(rc->device_uuid); free(rc->device_uuid);
} }
...@@ -1405,10 +1437,10 @@ static int luks2_change_pbkdf_params(struct reenc_ctx *rc) ...@@ -1405,10 +1437,10 @@ static int luks2_change_pbkdf_params(struct reenc_ctx *rc)
int i, r; int i, r;
struct crypt_device *cd; struct crypt_device *cd;
if ((r = initialize_passphrase(rc, rc->device))) if ((r = initialize_passphrase(rc, hdr_device(rc))))
return r; return r;
if (crypt_init(&cd, rc->device) || if (crypt_init(&cd, hdr_device(rc)) ||
crypt_load(cd, CRYPT_LUKS2, NULL)) crypt_load(cd, CRYPT_LUKS2, NULL))
return -EINVAL; return -EINVAL;
...@@ -1461,7 +1493,7 @@ static int run_reencrypt(const char *device) ...@@ -1461,7 +1493,7 @@ static int run_reencrypt(const char *device)
log_dbg("Running reencryption."); log_dbg("Running reencryption.");
if (!rc.in_progress) { if (!rc.in_progress) {
if ((r = initialize_passphrase(&rc, rc.device))) if ((r = initialize_passphrase(&rc, hdr_device(&rc))))
goto out; goto out;
if (rc.reencrypt_mode == ENCRYPT) { if (rc.reencrypt_mode == ENCRYPT) {
...@@ -1475,7 +1507,7 @@ static int run_reencrypt(const char *device) ...@@ -1475,7 +1507,7 @@ static int run_reencrypt(const char *device)
if (rc.reencrypt_mode == DECRYPT && if (rc.reencrypt_mode == DECRYPT &&
(r = backup_fake_header(&rc))) (r = backup_fake_header(&rc)))
goto out; goto out;
if ((r = device_check(&rc, MAKE_UNUSABLE))) if ((r = device_check(&rc, hdr_device(&rc), MAKE_UNUSABLE)))
goto out; goto out;
} }
} else { } else {
...@@ -1558,6 +1590,7 @@ int main(int argc, const char **argv) ...@@ -1558,6 +1590,7 @@ int main(int argc, const char **argv)
{ "pbkdf-memory", '\0', POPT_ARG_LONG, &opt_pbkdf_memory, 0, N_("PBKDF memory cost limit"), N_("kilobytes") }, { "pbkdf-memory", '\0', POPT_ARG_LONG, &opt_pbkdf_memory, 0, N_("PBKDF memory cost limit"), N_("kilobytes") },
{ "pbkdf-parallel", '\0', POPT_ARG_LONG, &opt_pbkdf_parallel, 0, N_("PBKDF parallel cost "), N_("threads") }, { "pbkdf-parallel", '\0', POPT_ARG_LONG, &opt_pbkdf_parallel, 0, N_("PBKDF parallel cost "), N_("threads") },
{ "pbkdf-force-iterations",'\0',POPT_ARG_LONG, &opt_pbkdf_iterations, 0, N_("PBKDF iterations cost (forced, disables benchmark)"), NULL }, { "pbkdf-force-iterations",'\0',POPT_ARG_LONG, &opt_pbkdf_iterations, 0, N_("PBKDF iterations cost (forced, disables benchmark)"), NULL },
{ "header", '\0', POPT_ARG_STRING, &opt_header_device, 0, N_("Device or file with separated LUKS header."), NULL },
POPT_TABLEEND POPT_TABLEEND
}; };
poptContext popt_context; poptContext popt_context;
...@@ -1656,8 +1689,8 @@ int main(int argc, const char **argv) ...@@ -1656,8 +1689,8 @@ int main(int argc, const char **argv)
usage(popt_context, EXIT_FAILURE, _("Reduce size must be multiple of 512 bytes sector."), usage(popt_context, EXIT_FAILURE, _("Reduce size must be multiple of 512 bytes sector."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_new && !opt_reduce_size) if (opt_new && (!opt_reduce_size && !opt_header_device))
usage(popt_context, EXIT_FAILURE, _("Option --new must be used together with --reduce-device-size."), usage(popt_context, EXIT_FAILURE, _("Option --new must be used together with --reduce-device-size or --header."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_keep_key && ((!opt_hash && !opt_iteration_time && !opt_pbkdf_iterations) || opt_cipher || opt_new)) if (opt_keep_key && ((!opt_hash && !opt_iteration_time && !opt_pbkdf_iterations) || opt_cipher || opt_new))
......
...@@ -7,6 +7,7 @@ FAST_PBKDF="--pbkdf-force-iterations 1000" ...@@ -7,6 +7,7 @@ FAST_PBKDF="--pbkdf-force-iterations 1000"
DEV_NAME=reenc9768 DEV_NAME=reenc9768
DEV_NAME2=reenc1273 DEV_NAME2=reenc1273
IMG=reenc-data IMG=reenc-data
IMG_HDR=$IMG.hdr
ORIG_IMG=reenc-data-orig ORIG_IMG=reenc-data-orig
KEY1=key1 KEY1=key1
PWD1="93R4P4pIqAH8" PWD1="93R4P4pIqAH8"
...@@ -27,7 +28,7 @@ function remove_mapping() ...@@ -27,7 +28,7 @@ function remove_mapping()
[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2 [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
[ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1 [ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1
rm -f $IMG $ORIG_IMG $KEY1 >/dev/null 2>&1 rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 >/dev/null 2>&1
umount $MNT_DIR > /dev/null 2>&1 umount $MNT_DIR > /dev/null 2>&1
rmdir $MNT_DIR > /dev/null 2>&1 rmdir $MNT_DIR > /dev/null 2>&1
LOOPDEV1="" LOOPDEV1=""
...@@ -62,9 +63,11 @@ function add_scsi_device() { ...@@ -62,9 +63,11 @@ function add_scsi_device() {
[ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV." [ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV."
} }
function open_crypt() function open_crypt() # $1 pwd, $2 hdr
{ {
if [ -n "$1" ] ; then if [ -n "$2" ] ; then
echo "$1" | $CRYPTSETUP luksOpen $LOOPDEV1 $DEV_NAME --header $2 || fail
elif [ -n "$1" ] ; then
echo "$1" | $CRYPTSETUP luksOpen $LOOPDEV1 $DEV_NAME || fail echo "$1" | $CRYPTSETUP luksOpen $LOOPDEV1 $DEV_NAME || fail
else else
$CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV1 $DEV_NAME || fail $CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV1 $DEV_NAME || fail
...@@ -104,9 +107,9 @@ function check_hash_dev() # $1 dev, $2 hash ...@@ -104,9 +107,9 @@ function check_hash_dev() # $1 dev, $2 hash
[ $HASH != "$2" ] && fail "HASH differs ($HASH)" [ $HASH != "$2" ] && fail "HASH differs ($HASH)"
} }
function check_hash() # $1 pwd, $2 hash function check_hash() # $1 pwd, $2 hash, $3 hdr
{ {
open_crypt $1 open_crypt $1 $3
check_hash_dev /dev/mapper/$DEV_NAME $2 check_hash_dev /dev/mapper/$DEV_NAME $2
$CRYPTSETUP remove $DEV_NAME || fail $CRYPTSETUP remove $DEV_NAME || fail
} }
...@@ -336,5 +339,21 @@ check_hash $PWD1 $HASH1 ...@@ -336,5 +339,21 @@ check_hash $PWD1 $HASH1
echo $PWD1 | $REENC $LOOPDEV1 -q --decrypt echo $PWD1 | $REENC $LOOPDEV1 -q --decrypt
check_hash_dev $LOOPDEV1 $HASH4 check_hash_dev $LOOPDEV1 $HASH4
echo "[11] Detached header - adding encryption/reencryption/decryption"
prepare 8192
check_hash_dev $IMG $HASH4
echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --header $IMG_HDR --new
check_hash $PWD1 $HASH4 $IMG_HDR
echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --header $IMG_HDR
check_hash $PWD1 $HASH4 $IMG_HDR
echo $PWD1 | $REENC $LOOPDEV1 -q --header $IMG_HDR --decrypt
check_hash_dev $IMG $HASH4
# existing header of zero size
cat /dev/null >$IMG_HDR
echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --header $IMG_HDR --new
check_hash $PWD1 $HASH4 $IMG_HDR
$CRYPTSETUP isLuks $LOOPDEV1 && fail
$CRYPTSETUP isLuks $IMG_HDR || fail
remove_mapping remove_mapping
exit 0 exit 0
...@@ -8,6 +8,7 @@ DEFAULT_ARGON="argon2i" ...@@ -8,6 +8,7 @@ DEFAULT_ARGON="argon2i"
DEV_NAME=reenc9768 DEV_NAME=reenc9768
DEV_NAME2=reenc1273 DEV_NAME2=reenc1273
IMG=reenc-data IMG=reenc-data
IMG_HDR=$IMG.hdr
ORIG_IMG=reenc-data-orig ORIG_IMG=reenc-data-orig
KEY1=key1 KEY1=key1
PWD1="93R4P4pIqAH8" PWD1="93R4P4pIqAH8"
...@@ -43,7 +44,7 @@ function remove_mapping() ...@@ -43,7 +44,7 @@ function remove_mapping()
[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2 [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2
[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
[ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1 [ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1
rm -f $IMG $ORIG_IMG $KEY1 >/dev/null 2>&1 rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 >/dev/null 2>&1
umount $MNT_DIR > /dev/null 2>&1 umount $MNT_DIR > /dev/null 2>&1
rmdir $MNT_DIR > /dev/null 2>&1 rmdir $MNT_DIR > /dev/null 2>&1
LOOPDEV1="" LOOPDEV1=""
...@@ -78,9 +79,11 @@ function add_scsi_device() { ...@@ -78,9 +79,11 @@ function add_scsi_device() {
[ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV." [ -b $SCSI_DEV ] || fail "Cannot find $SCSI_DEV."
} }
function open_crypt() function open_crypt() # $1 pwd, $2 hdr
{ {
if [ -n "$1" ] ; then if [ -n "$2" ] ; then
echo "$1" | $CRYPTSETUP luksOpen $LOOPDEV1 $DEV_NAME --header $2 || fail
elif [ -n "$1" ] ; then
echo "$1" | $CRYPTSETUP luksOpen $LOOPDEV1 $DEV_NAME || fail echo "$1" | $CRYPTSETUP luksOpen $LOOPDEV1 $DEV_NAME || fail
else else
$CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV1 $DEV_NAME || fail $CRYPTSETUP luksOpen -d $KEY1 $LOOPDEV1 $DEV_NAME || fail
...@@ -120,9 +123,9 @@ function check_hash_dev() # $1 dev, $2 hash ...@@ -120,9 +123,9 @@ function check_hash_dev() # $1 dev, $2 hash
[ $HASH != "$2" ] && fail "HASH differs ($HASH)" [ $HASH != "$2" ] && fail "HASH differs ($HASH)"
} }
function check_hash() # $1 pwd, $2 hash function check_hash() # $1 pwd, $2 hash, $hdr
{ {
open_crypt $1 open_crypt $1 $3
check_hash_dev /dev/mapper/$DEV_NAME $2 check_hash_dev /dev/mapper/$DEV_NAME $2
$CRYPTSETUP remove $DEV_NAME || fail $CRYPTSETUP remove $DEV_NAME || fail
} }
...@@ -386,5 +389,22 @@ if [ -n "$ALLOW_DISCARDS" ]; then ...@@ -386,5 +389,22 @@ if [ -n "$ALLOW_DISCARDS" ]; then
$CRYPTSETUP luksDump $LOOPDEV1 | grep -m1 Flags: | grep allow-discards > /dev/null || fail $CRYPTSETUP luksDump $LOOPDEV1 | grep -m1 Flags: | grep allow-discards > /dev/null || fail
fi fi
echo "[13] Detached header - adding encryption/reencryption/decryption"
prepare 8192
check_hash_dev $IMG $HASH4
echo $PWD1 | $REENC --type luks2 $LOOPDEV1 -q $FAST_PBKDF --header $IMG_HDR --new
check_hash $PWD1 $HASH4 $IMG_HDR
echo $PWD1 | $REENC $LOOPDEV1 -q $FAST_PBKDF --header $IMG_HDR
check_hash $PWD1 $HASH4 $IMG_HDR
echo $PWD1 | $REENC $LOOPDEV1 -q --header $IMG_HDR --decrypt
check_hash_dev $IMG $HASH4
# existing header of zero size
cat /dev/null >$IMG_HDR
echo $PWD1 | $REENC --type luks2 $LOOPDEV1 -q $FAST_PBKDF --header $IMG_HDR --new
check_hash $PWD1 $HASH4 $IMG_HDR
$CRYPTSETUP isLuks $LOOPDEV1 && fail
$CRYPTSETUP isLuks $IMG_HDR || fail
$CRYPTSETUP luksDump $IMG_HDR | grep -q "0: luks2" || fail
remove_mapping remove_mapping
exit 0 exit 0
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment