From ec07927b55fa83f8a3980ea7b0cc0dd8032927f0 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Sun, 18 Nov 2018 21:13:52 +0100 Subject: [PATCH] Add cryptsetup options for LUKS2 header size settings. Also print these area sizes in dump command. NOTE: since now, the metadata area size in dump command contains mandatory 4k binary section (to be aligned with API definition). --- lib/luks2/luks2_json_metadata.c | 3 ++- man/cryptsetup.8 | 17 ++++++++++++++++- src/cryptsetup.c | 33 +++++++++++++++++++++++++++++++++ tests/compat-test2 | 15 +++++++++++++++ 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c index f5835f55..d614d98a 100644 --- a/lib/luks2/luks2_json_metadata.c +++ b/lib/luks2/luks2_json_metadata.c @@ -1615,7 +1615,8 @@ int LUKS2_hdr_dump(struct crypt_device *cd, struct luks2_hdr *hdr) log_std(cd, "LUKS header information\n"); log_std(cd, "Version: \t%u\n", hdr->version); log_std(cd, "Epoch: \t%" PRIu64 "\n", hdr->seqid); - log_std(cd, "Metadata area: \t%zu bytes\n", hdr->hdr_size - LUKS2_HDR_BIN_LEN); + log_std(cd, "Metadata area: \t%" PRIu64 " [bytes]\n", LUKS2_metadata_size(hdr->jobj)); + log_std(cd, "Keyslots area: \t%" PRIu64 " [bytes]\n", LUKS2_keyslots_size(hdr->jobj)); log_std(cd, "UUID: \t%s\n", *hdr->uuid ? hdr->uuid : "(no UUID)"); log_std(cd, "Label: \t%s\n", *hdr->label ? hdr->label : "(no label)"); log_std(cd, "Subsystem: \t%s\n", *hdr->subsystem ? hdr->subsystem : "(no subsystem)"); diff --git a/man/cryptsetup.8 b/man/cryptsetup.8 index 3fd66afe..bca8484a 100644 --- a/man/cryptsetup.8 +++ b/man/cryptsetup.8 @@ -223,7 +223,8 @@ For LUKS2, additional \fB\fR can be [\-\-integrity, \-\-integrity\-no\-wipe, \-\-sector\-size, \-\-label, \-\-subsystem, \-\-pbkdf, \-\-pbkdf\-memory, \-\-pbkdf\-parallel, -\-\-disable\-locks, \-\-disable\-keyring]. +\-\-disable\-locks, \-\-disable\-keyring. +\-\-luks2\-metadata\-size, \-\-luks2\-keyslots\-size]. \fBWARNING:\fR Doing a luksFormat on an existing LUKS container will make all data the old container permanently irretrievable unless @@ -1185,6 +1186,20 @@ in "Cryptographic API" section (CONFIG_CRYPTO_USER_API_AEAD .config option). For more info, see \fIAUTHENTICATED DISK ENCRYPTION\fR section. .TP +.B "\-\-luks2\-metadata\-size " +This option can be used to enlarge the LUKS2 metadata (JSON) area. +The size includes 4096 bytes for binary metadata (usable JSON area is smaller +of the binary area). +According to LUKS2 specification, only these values are valid: +16, 32, 64, 128, 256, 512, 1024, 2048 and 4096 kB +The can be specified with unit suffix (for example 128k). +.TP +.B "\-\-luks2\-keyslots\-size " +This option can be used to set specific size of the LUKS2 binary keyslot area +(key material is encrypted there). The value must be aligned to multiple +of 4096 bytes with maximum size 128MB. +The can be specified with unit suffix (for example 128k). +.TP .B "\-\-integrity\-no\-journal" Activate device with integrity protection without using data journal (direct write of data and integrity tags). diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 9d6198af..c70b0d56 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -90,6 +90,11 @@ static const char *opt_label = NULL; static const char *opt_subsystem = NULL; static int opt_unbound = 0; +static const char *opt_luks2_metadata_size_str = NULL; +static uint64_t opt_luks2_metadata_size = 0; +static const char *opt_luks2_keyslots_size_str = NULL; +static uint64_t opt_luks2_keyslots_size = 0; + static const char **action_argv; static int action_argc; static const char *null_action_argv[] = {NULL, NULL}; @@ -989,6 +994,11 @@ static int action_luksFormat(void) log_err(_("Integrity option can be used only for LUKS2 format.")); return -EINVAL; } + + if (opt_luks2_keyslots_size || opt_luks2_metadata_size) { + log_err(_("Unsupported LUKS2 metadata size options.")); + return -EINVAL; + } } else return -EINVAL; @@ -1043,6 +1053,14 @@ static int action_luksFormat(void) return r; } + if (opt_luks2_keyslots_size || opt_luks2_metadata_size) { + r = crypt_set_metadata_size(cd, opt_luks2_metadata_size, opt_luks2_keyslots_size); + if (r < 0) { + log_err(_("Unsupported LUKS2 metadata size options.")); + goto out; + } + } + if (opt_offset) { r = crypt_set_data_offset(cd, opt_offset); if (r < 0) @@ -2406,6 +2424,8 @@ int main(int argc, const char **argv) { "subsystem", '\0', POPT_ARG_STRING, &opt_subsystem, 0, N_("Set subsystem label for the LUKS2 device"), NULL }, { "unbound", '\0', POPT_ARG_NONE, &opt_unbound, 0, N_("Create unbound (no assigned data segment) LUKS2 keyslot"), NULL }, { "json-file", '\0', POPT_ARG_STRING, &opt_json_file, 0, N_("Read or write the json from or to a file"), NULL }, + { "luks2-metadata-size",'\0',POPT_ARG_STRING,&opt_luks2_metadata_size_str,0,N_("LUKS2 header metadata area size"), N_("bytes") }, + { "luks2-keyslots-size",'\0',POPT_ARG_STRING,&opt_luks2_keyslots_size_str,0,N_("LUKS2 header keyslots area size"), N_("bytes") }, POPT_TABLEEND }; poptContext popt_context; @@ -2644,6 +2664,19 @@ int main(int argc, const char **argv) usage(popt_context, EXIT_FAILURE, _("Option --align-payload is allowed only for luksFormat."), poptGetInvocationName(popt_context)); + if ((opt_luks2_metadata_size_str || opt_luks2_keyslots_size_str) && strcmp(aname, "luksFormat")) + usage(popt_context, EXIT_FAILURE, _("Options --luks2-metadata-size and --opt-luks2-keyslots-size " + "are allowed only for luksFormat with LUKS2."), + poptGetInvocationName(popt_context)); + if (opt_luks2_metadata_size_str && + tools_string_to_size(NULL, opt_luks2_metadata_size_str, &opt_luks2_metadata_size)) + usage(popt_context, EXIT_FAILURE, _("Invalid LUKS2 metadata size specification."), + poptGetInvocationName(popt_context)); + if (opt_luks2_keyslots_size_str && + tools_string_to_size(NULL, opt_luks2_keyslots_size_str, &opt_luks2_keyslots_size)) + usage(popt_context, EXIT_FAILURE, _("Invalid LUKS2 keyslots size specification."), + poptGetInvocationName(popt_context)); + if (opt_align_payload && opt_offset) usage(popt_context, EXIT_FAILURE, _("Option --align-payload and --offset cannot be combined."), poptGetInvocationName(popt_context)); diff --git a/tests/compat-test2 b/tests/compat-test2 index 69b74b76..502640f5 100755 --- a/tests/compat-test2 +++ b/tests/compat-test2 @@ -881,5 +881,20 @@ for mda in 16 32 64 128 256 512 1024 2048 4096 ; do done echo +prepare "[40] LUKS2 metadata areas" wipe +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks1 $LOOPDEV --luks2-metadata-size=128k --luks2-keyslots-size=128k 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-metadata-size=128k --luks2-keyslots-size=127k 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-metadata-size=127k --luks2-keyslots-size=128k 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-metadata-size=128k --luks2-keyslots-size=128M 2> /dev/null && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-metadata-size=128k --luks2-keyslots-size=128k || fail +$CRYPTSETUP luksDump $LOOPDEV | grep "Metadata area:" | grep -q "131072 \[bytes\]" || fail +$CRYPTSETUP luksDump $LOOPDEV | grep "Keyslots area:" | grep -q "131072 \[bytes\]" || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --key-size 256 --luks2-metadata-size=128k || fail +$CRYPTSETUP luksDump $LOOPDEV | grep "Metadata area:" | grep -q "131072 \[bytes\]" || fail +$CRYPTSETUP luksDump $LOOPDEV | grep "Keyslots area:" | grep -q "4161536 \[bytes\]" || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-keyslots-size=128k || fail +$CRYPTSETUP luksDump $LOOPDEV | grep "Metadata area:" | grep -q "16384 \[bytes\]" || fail +$CRYPTSETUP luksDump $LOOPDEV | grep "Keyslots area:" | grep -q "131072 \[bytes\]" || fail + remove_mapping exit 0