From 725720dfc31ff26c4a60089a478fe5e882925ef3 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Wed, 14 Aug 2019 12:31:40 +0200 Subject: [PATCH] Fix volume key file if no LUKS2 keyslots are present. If all keyslots are removed, LUKS2 has no longer information about the volume key size (there is only key digest present). If user wants to open or add new keyslot, it must get information about key size externally. We do not want to guess key size from the file size (it does not work for block devices for example), so require explicit --keyfil option in these cases. Fixes #470. --- src/cryptsetup.c | 18 ++++++++++++++++-- tests/compat-test2 | 7 ++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/cryptsetup.c b/src/cryptsetup.c index cea4d874..60f461d0 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -1387,6 +1387,13 @@ static int action_open_luks(void) if (opt_master_key_file) { keysize = crypt_get_volume_key_size(cd); + if (!keysize && !opt_key_size) { + log_err(_("Cannot dermine volume key size for LUKS without keyslots, please use --key-size option.")); + r = -EINVAL; + goto out; + } else if (!keysize) + keysize = opt_key_size / 8; + r = tools_read_mk(opt_master_key_file, &key, keysize); if (r < 0) goto out; @@ -1691,6 +1698,13 @@ static int action_luksAddKey(void) } if (opt_master_key_file) { + if (!keysize && !opt_key_size) { + log_err(_("Cannot dermine volume key size for LUKS without keyslots, please use --key-size option.")); + r = -EINVAL; + goto out; + } else if (!keysize) + keysize = opt_key_size / 8; + r = tools_read_mk(opt_master_key_file, &key, keysize); if (r < 0) goto out; @@ -3587,9 +3601,9 @@ int main(int argc, const char **argv) strcmp(aname, "luksFormat") && strcmp(aname, "open") && strcmp(aname, "benchmark") && - (strcmp(aname, "luksAddKey") || !opt_unbound)) + strcmp(aname, "luksAddKey")) usage(popt_context, EXIT_FAILURE, - _("Option --key-size is allowed only for luksFormat, luksAddKey (with --unbound),\n" + _("Option --key-size is allowed only for luksFormat, luksAddKey,\n" "open and benchmark actions. To limit read from keyfile use --keyfile-size=(bytes)."), poptGetInvocationName(popt_context)); diff --git a/tests/compat-test2 b/tests/compat-test2 index 44daeaf1..04312291 100755 --- a/tests/compat-test2 +++ b/tests/compat-test2 @@ -503,7 +503,7 @@ echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME2 2>/dev/null && fail $CRYPTSETUP luksClose $DEV_NAME || fail prepare "[21] luksDump" wipe -echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --uuid $TEST_UUID --type luks2 $LOOPDEV $KEY1 || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --key-size 256 $FAST_PBKDF_OPT --uuid $TEST_UUID --type luks2 $LOOPDEV $KEY1 || fail echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV -d $KEY1 || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q "0: luks2" || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q $TEST_UUID || fail @@ -513,6 +513,11 @@ $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key -d $KEY1 | grep -q "MK dump:" echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file $VK_FILE >/dev/null || fail echo $PWD1 | $CRYPTSETUP luksDump -q $LOOPDEV --dump-master-key --master-key-file $VK_FILE 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --master-key-file $VK_FILE $LOOPDEV || fail +# Use volume key file without keyslots +$CRYPTSETUP luksErase -q $LOOPDEV || fail +$CRYPTSETUP luksOpen --master-key-file $VK_FILE --key-size 256 --test-passphrase $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT --master-key-file $VK_FILE --key-size 256 $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP luksOpen --test-passphrase $LOOPDEV || fail prepare "[22] remove disappeared device" wipe dmsetup create $DEV_NAME --table "0 39998 linear $LOOPDEV 2" || fail