mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-18 14:20:09 +01:00
Allow device in reencryption to be activated by volume keys in files.
Allow to use up to two --volume-key-file options (paired with two --key-size options) for device in-reencryption activation.
This commit is contained in:
@@ -543,7 +543,10 @@ current volume key. Also, it is used when new unbound keyslot is created by
|
||||
specifying --unbound parameter.
|
||||
endif::[]
|
||||
ifdef::ACTION_OPEN[]
|
||||
This option can be used for _plain_ device type only.
|
||||
This option can be used for _plain_ and _luks_ devices. For LUKS2 devices
|
||||
in reencryption you may use the parameter twice to specify both old and new volume key
|
||||
sizes. Each --key-size option corresponds to the respective --volume-key-file parameter
|
||||
(also allowed to be used up to two times).
|
||||
endif::[]
|
||||
ifndef::ACTION_REENCRYPT,ACTION_OPEN,ACTION_LUKSADDKEY[]
|
||||
This option can be used for _open --type plain_ or _luksFormat_. All
|
||||
@@ -1313,6 +1316,9 @@ It may be also used when no keyslot is active.
|
||||
endif::[]
|
||||
ifdef::ACTION_OPEN[]
|
||||
This allows one to open _luks_ and _bitlk_ device types without giving a passphrase. +
|
||||
For devices in reencryption the option may be used twice to specify both old and new volume keys.
|
||||
When using the option twice make sure you pair each --volume-key-file option with respective
|
||||
--key-size parameter as well.
|
||||
endif::[]
|
||||
ifdef::ACTION_REENCRYPT[]
|
||||
Use (set) new volume key stored in a file. +
|
||||
@@ -1330,7 +1336,8 @@ Use a volume key stored in a keyring.
|
||||
This allows one to open _luks_ and _plain_ device types without giving a passphrase.
|
||||
+
|
||||
For LUKS, the key and associated type has to be readable from userspace so that volume
|
||||
key digest may be verified in before activation.
|
||||
key digest may be verified in before activation. For devices in reencryption the option may be
|
||||
used twice to specify both old and new volume keys.
|
||||
+
|
||||
For PLAIN type, the user must ensure that the key in the keyring is unchanged since activation.
|
||||
Otherwise, reloading the key can cause data corruption after an unexpected key change.
|
||||
|
||||
@@ -17,11 +17,15 @@
|
||||
static char *keyfiles[MAX_KEYFILES];
|
||||
static char *keyring_links[MAX_KEYRING_LINKS];
|
||||
static char *vks_in_keyring[MAX_VK_IN_KEYRING];
|
||||
static char *vk_files[2];
|
||||
static char *keyfile_stdin = NULL;
|
||||
static uint32_t key_sizes[2];
|
||||
|
||||
static int keyfiles_count = 0;
|
||||
static int keyring_links_count = 0;
|
||||
static int vks_in_keyring_count = 0;
|
||||
static int vk_files_count = 0;
|
||||
static int key_sizes_count = 0;
|
||||
int64_t data_shift = 0;
|
||||
|
||||
const char *device_type = "luks";
|
||||
@@ -52,6 +56,8 @@ void tools_cleanup(void)
|
||||
free(keyring_links[--keyring_links_count]);
|
||||
while (vks_in_keyring_count)
|
||||
free(vks_in_keyring[--vks_in_keyring_count]);
|
||||
while (vk_files_count)
|
||||
free(vk_files[--vk_files_count]);
|
||||
|
||||
total_keyfiles = 0;
|
||||
}
|
||||
@@ -1784,27 +1790,37 @@ static int action_open_luks(void)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* When activating device in-reencryption with --volume-key-file or --volume-key-keyring
|
||||
* the ordering of parameters does not matter. This applies also if any parameter is used
|
||||
* twice. The library internal code tests both passed keys if they match old or new
|
||||
* volume key digests and assign them respectively.
|
||||
*/
|
||||
if (ARG_SET(OPT_VOLUME_KEY_FILE_ID) || ARG_SET(OPT_VOLUME_KEY_KEYRING_ID)) {
|
||||
if (ARG_SET(OPT_VOLUME_KEY_FILE_ID)) {
|
||||
keysize = crypt_get_volume_key_size(cd);
|
||||
if (!keysize && !ARG_SET(OPT_KEY_SIZE_ID)) {
|
||||
if (vk_files[0] && !vk_files[1]) {
|
||||
keysize = key_sizes[0] / 8;
|
||||
if (!keysize)
|
||||
keysize = crypt_get_volume_key_size(cd);
|
||||
if (!keysize) /* only in LUKS2 decryption or with no keyslots */
|
||||
keysize = crypt_get_old_volume_key_size(cd);
|
||||
|
||||
if (!keysize) {
|
||||
log_err(_("Cannot determine volume key size for LUKS without keyslots, please use --key-size option."));
|
||||
r = -EINVAL;
|
||||
goto out;
|
||||
} else if (!keysize)
|
||||
keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
|
||||
}
|
||||
}
|
||||
} else if (vk_files[0] && vk_files[1])
|
||||
keysize = key_sizes[0] / 8;
|
||||
|
||||
r = luks_init_keyslot_contexts_by_volume_keys(cd, ARG_STR(OPT_VOLUME_KEY_FILE_ID),
|
||||
NULL /* unused */,
|
||||
keysize,
|
||||
0 /* unused */,
|
||||
r = luks_init_keyslot_contexts_by_volume_keys(cd, vk_files[0], vk_files[1],
|
||||
keysize, key_sizes[1] / 8,
|
||||
vks_in_keyring[0],
|
||||
vks_in_keyring[1],
|
||||
&kc1, &kc2);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
/* The ordering of kc1 or kc2 does not matter */
|
||||
r = crypt_activate_by_keyslot_context(cd, activated_name, CRYPT_ANY_SLOT,
|
||||
kc1, CRYPT_ANY_SLOT, kc2, activate_flags);
|
||||
if (r == -EPERM)
|
||||
@@ -3314,6 +3330,9 @@ static const char *verify_open(void)
|
||||
ARG_SET(OPT_VOLUME_KEY_FILE_ID)) && !strcmp_or_null(device_type, "plain"))
|
||||
return _("Option --volume-key-keyring cannot be combined with --hash or --volume-key-file.");
|
||||
|
||||
if (vk_files[1] && !key_sizes[1])
|
||||
return _("Both --volume-key-file options must be paired with respective --key-size options.");
|
||||
|
||||
/* "open --type tcrypt" and "tcryptDump" checks are identical */
|
||||
return verify_tcryptdump();
|
||||
}
|
||||
@@ -3628,6 +3647,14 @@ static void basic_options_cb(poptContext popt_context,
|
||||
usage(popt_context, EXIT_FAILURE,
|
||||
_("Key size must be a multiple of 8 bits"),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (key_sizes_count < 2)
|
||||
key_sizes[key_sizes_count++] = ARG_UINT32(OPT_KEY_SIZE_ID);
|
||||
else {
|
||||
usage(popt_context, EXIT_FAILURE,
|
||||
_("At most 2 key size specifications can be supplied."),
|
||||
poptGetInvocationName(popt_context));
|
||||
}
|
||||
break;
|
||||
case OPT_INTEGRITY_KEY_SIZE_ID:
|
||||
if (ARG_UINT32(OPT_INTEGRITY_KEY_SIZE_ID) == 0)
|
||||
@@ -3650,6 +3677,17 @@ static void basic_options_cb(poptContext popt_context,
|
||||
_("Key size must be a multiple of 8 bits"),
|
||||
poptGetInvocationName(popt_context));
|
||||
break;
|
||||
case OPT_VOLUME_KEY_FILE_ID:
|
||||
if (vk_files_count < 2)
|
||||
vk_files[vk_files_count++] = strdup(ARG_STR(OPT_VOLUME_KEY_FILE_ID));
|
||||
else {
|
||||
if (snprintf(buf, sizeof(buf), _("At most %d volume key specifications can be supplied."), 2) < 0)
|
||||
buf[0] = '\0';
|
||||
usage(popt_context, EXIT_FAILURE,
|
||||
buf,
|
||||
poptGetInvocationName(popt_context));
|
||||
}
|
||||
break;
|
||||
case OPT_VOLUME_KEY_KEYRING_ID:
|
||||
if (vks_in_keyring_count < MAX_VK_IN_KEYRING)
|
||||
vks_in_keyring[vks_in_keyring_count++] = strdup(ARG_STR(OPT_VOLUME_KEY_KEYRING_ID));
|
||||
|
||||
Reference in New Issue
Block a user