From 19eac239b7a219dd1d44f877f02c8fea7fc99598 Mon Sep 17 00:00:00 2001 From: Ondrej Kozina Date: Fri, 17 May 2019 13:36:52 +0200 Subject: [PATCH] Add --device-size parameter for use in LUKS2 reencryption. Currently it's used only in LUKS2 reencryption code for reencrypting initial part of data device only. It may be used to encrypt/reencrypt only initial part of data device if user is aware that rest of the device is empty. --- man/cryptsetup.8 | 18 ++++++++++++++++-- src/cryptsetup.c | 17 +++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/man/cryptsetup.8 b/man/cryptsetup.8 index 9fd16ceb..01dddea6 100644 --- a/man/cryptsetup.8 +++ b/man/cryptsetup.8 @@ -191,8 +191,9 @@ If the reencryption process was interrupted abruptly (reencryption process crash it may require recovery. The recovery is currently run automatically on next activation (action \fIopen\fR) when needed. -Action supports following additional \fB\fR [\-\-encrypt, \-\-decrypt, \-\-resilience, -\-\-resilience-hash, \-\-hotzone-size, \-\-init\-only, \-\-resume\-only, \-\-reduce\-device\-size]. +Action supports following additional \fB\fR [\-\-encrypt, \-\-decrypt, \-\-device\-size, +\-\-resilience, \-\-resilience-hash, \-\-hotzone-size, \-\-init\-only, \-\-resume\-only, +\-\-reduce\-device\-size]. .SH PLAIN MODE Plain dm-crypt encrypts the device sector-by-sector with a @@ -980,6 +981,19 @@ Hence, if \-\-offset \fIn\fR, and \-\-skip \fIs\fR, sector \fIn\fR (the first sector of the encrypted device) will get a sector number of \fIs\fR for the IV calculation. .TP +.B "\-\-device-size \fIsize[units]\fR" +Instead of real device size, use specified value. + +It means that only specified area (from the start of the device +to the specified size) will be reencrypted. + +If no unit suffix is specified, the size is in bytes. + +Unit suffix can be S for 512 byte sectors, K/M/G/T (or KiB,MiB,GiB,TiB) +for units with 1024 base or KB/MB/GB/TB for 1000 base (SI scale). + +\fBWARNING:\fR This is destructive operation when used with reencrypt command. +.TP .B "\-\-readonly, \-r" set up a read-only mapping. .TP diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 6832e76f..3fe17421 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -110,6 +110,9 @@ static uint64_t opt_reduce_size = 0; static const char *opt_hotzone_size_str = NULL; static uint64_t opt_hotzone_size = 0; +static const char *opt_device_size_str = NULL; +static uint64_t opt_device_size = 0; + /* do not set from command line, use helpers above */ static int64_t opt_data_shift; @@ -2449,6 +2452,7 @@ static int action_reencrypt_load(struct crypt_device *cd) .resilience = opt_resilience_mode, .hash = opt_resilience_hash, .max_hotzone_size = opt_hotzone_size, + .device_size = opt_device_size, .flags = CRYPT_REENCRYPT_RESUME_ONLY }; @@ -2492,6 +2496,7 @@ static int action_encrypt_luks2(struct crypt_device **cd) .resilience = opt_resilience_mode, .hash = opt_resilience_hash, .max_hotzone_size = opt_hotzone_size, + .device_size = opt_device_size, .luks2 = &luks2_params, .flags = CRYPT_REENCRYPT_INITIALIZE_ONLY }; @@ -2653,6 +2658,7 @@ static int action_decrypt_luks2(struct crypt_device *cd) .resilience = opt_data_shift ? "datashift" : opt_resilience_mode, .hash = opt_resilience_hash, .data_shift = imaxabs(opt_data_shift) / SECTOR_SIZE, + .device_size = opt_device_size, .max_hotzone_size = opt_hotzone_size, }; size_t passwordLen; @@ -2698,6 +2704,7 @@ static int action_reencrypt_luks2(struct crypt_device *cd) .hash = opt_resilience_hash, .data_shift = imaxabs(opt_data_shift) / SECTOR_SIZE, .max_hotzone_size = opt_hotzone_size, + .device_size = opt_device_size, .luks2 = &luks2_params, }; @@ -3012,6 +3019,7 @@ int main(int argc, const char **argv) { "new-keyfile-offset",'\0', POPT_ARG_STRING, &popt_tmp, 5, N_("Number of bytes to skip in newly added keyfile"), N_("bytes") }, { "key-slot", 'S', POPT_ARG_INT, &opt_key_slot, 0, N_("Slot number for new key (default is first free)"), NULL }, { "size", 'b', POPT_ARG_STRING, &popt_tmp, 1, N_("The size of the device"), N_("SECTORS") }, + { "device-size", '\0', POPT_ARG_STRING, &opt_device_size_str, 0, N_("Use only specified device size (ignore rest of device). DANGEROUS!"), N_("bytes") }, { "offset", 'o', POPT_ARG_STRING, &popt_tmp, 2, N_("The start offset in the backend device"), N_("SECTORS") }, { "skip", 'p', POPT_ARG_STRING, &popt_tmp, 3, N_("How many sectors of the encrypted data to skip at the beginning"), N_("SECTORS") }, { "readonly", 'r', POPT_ARG_NONE, &opt_readonly, 0, N_("Create a readonly mapping"), NULL }, @@ -3487,6 +3495,11 @@ int main(int argc, const char **argv) usage(popt_context, EXIT_FAILURE, _("Reduce size must be multiple of 512 bytes sector."), poptGetInvocationName(popt_context)); + if (opt_device_size_str && + tools_string_to_size(NULL, opt_device_size_str, &opt_device_size)) + usage(popt_context, EXIT_FAILURE, _("Invalid data size specification."), + poptGetInvocationName(popt_context)); + opt_data_shift = -(int64_t)opt_reduce_size; if (opt_data_shift > 0) usage(popt_context, EXIT_FAILURE, _("Reduce size overflow."), @@ -3496,6 +3509,10 @@ int main(int argc, const char **argv) usage(popt_context, EXIT_FAILURE, _("LUKS2 decryption requires option --header."), poptGetInvocationName(popt_context)); + if (opt_data_shift && opt_device_size) + usage(popt_context, EXIT_FAILURE, _("Options --reduce-device-size and --data-size cannot be combined."), + poptGetInvocationName(popt_context)); + r = run_action(action); poptFreeContext(popt_context); return r;