From 4eb7193a279582485c20c8dd910b145279bbebc9 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Fri, 15 May 2020 10:37:33 +0200 Subject: [PATCH] Support large IV count option for plain device The iv_large_sector option is supported in dm-crypt since introduction of larger sectors encryption. It counts Initialization Vector (IV) in larger sector size (if set) instead of 512 bytes sectors. This option does not have any performance or security impact, but it can be used for accessing incompatible existing disk images from other systems. (It is used internally in BitLocker compatibily code). This patch allows it to be used for plain type device, so users can manually map foreign disk images. Only open action with plain device and sector size > 512 bytes is supported. --- man/cryptsetup.8 | 9 +++++++++ src/cryptsetup.c | 12 ++++++++++++ tests/device-test | 9 +++++++++ 3 files changed, 30 insertions(+) diff --git a/man/cryptsetup.8 b/man/cryptsetup.8 index 46ffad50..bc3fff61 100644 --- a/man/cryptsetup.8 +++ b/man/cryptsetup.8 @@ -1305,6 +1305,15 @@ Increasing sector size from 512 bytes to 4096 bytes can provide better performance on most of the modern storage devices and also with some hw encryption accelerators. .TP +.B "\-\-iv-large-sectors" +Count Initialization Vector (IV) in larger sector size (if set) instead +of 512 bytes sectors. This option can be used only for \fIopen\fR command +and \fIplain\fR encryption type. + +\fBNOTE:\fR This option does not have any performance or security impact, +use it only for accessing incompatible existing disk images from other systems +that require this option. +.TP .B "\-\-persistent" If used with LUKS2 devices and activation commands like \fIopen\fR or \fIrefresh\fR, the specified activation flags are persistently written into metadata diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 129d64a8..955f01fc 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -88,6 +88,7 @@ static int opt_integrity_no_wipe = 0; static int opt_integrity_legacy_padding = 0; static const char *opt_key_description = NULL; static int opt_sector_size = 0; +static int opt_iv_large_sectors = 0; static int opt_persistent = 0; static const char *opt_label = NULL; static const char *opt_subsystem = NULL; @@ -194,6 +195,10 @@ static void _set_activation_flags(uint32_t *flags) if (opt_serialize_memory_hard_pbkdf) *flags |= CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF; + + /* Only for plain */ + if (opt_iv_large_sectors) + *flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS; } static void _set_reencryption_flags(uint32_t *flags) @@ -3540,6 +3545,7 @@ int main(int argc, const char **argv) { "token-id", '\0', POPT_ARG_INT, &opt_token, 0, N_("Token number (default: any)"), NULL }, { "key-description", '\0', POPT_ARG_STRING, &opt_key_description, 0, N_("Key description"), NULL }, { "sector-size", '\0', POPT_ARG_INT, &opt_sector_size, 0, N_("Encryption sector size (default: 512 bytes)"), NULL }, + { "iv-large-sectors", '\0', POPT_ARG_NONE, &opt_iv_large_sectors, 0, N_("Use IV counted in sector size (not in 512 bytes)"), NULL }, { "persistent", '\0', POPT_ARG_NONE, &opt_persistent, 0, N_("Set activation flags persistent for device"), NULL }, { "label", '\0', POPT_ARG_STRING, &opt_label, 0, N_("Set label for the LUKS2 device"), NULL }, { "subsystem", '\0', POPT_ARG_STRING, &opt_subsystem, 0, N_("Set subsystem label for the LUKS2 device"), NULL }, @@ -3917,6 +3923,12 @@ int main(int argc, const char **argv) _("Unsupported encryption sector size."), poptGetInvocationName(popt_context)); + if (opt_iv_large_sectors && (strcmp(aname, "open") || strcmp_or_null(opt_type, "plain") || + opt_sector_size <= SECTOR_SIZE)) + usage(popt_context, EXIT_FAILURE, + _("Large IV sectors option is supported only for opening plain type device with sector size larger than 512 bytes."), + poptGetInvocationName(popt_context)); + if (opt_unbound && !opt_key_size && !strcmp(aname, "luksAddKey")) usage(popt_context, EXIT_FAILURE, _("Key size is required with --unbound option."), diff --git a/tests/device-test b/tests/device-test index d4be6703..0898b455 100755 --- a/tests/device-test +++ b/tests/device-test @@ -239,6 +239,15 @@ else check_sector_size $S $CRYPTSETUP close $DEV_NAME || fail done + + echo -e "$PWD1" | $CRYPTSETUP open --type plain --hash sha256 $DEV $DEV_NAME --iv-large-sectors >/dev/null 2>&1 && fail + for S in 1024 2048 4096; do + echo -n "[$S/IV]" + echo -e "$PWD1" | $CRYPTSETUP open -q --type plain --hash sha256 $DEV $DEV_NAME --sector-size $S --iv-large-sectors || fail + check_sector_size $S + dmsetup table $DEV_NAME | grep -q "iv_large_sectors" || fail + $CRYPTSETUP close $DEV_NAME || fail + done echo echo -n "LUKS2 sector size:"