mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-16 21:29:59 +01:00
Add --keep-key to cryptsetup-reencrypt.
This allows change of LUKS header hash (and iteration count) without the need to reencrypt the whole data area.
This commit is contained in:
@@ -67,6 +67,9 @@ you can destructively shrink device with \-\-reduce-device-size option.
|
||||
.TP
|
||||
.B "\-\-hash, \-h \fI<hash-spec>\fR"
|
||||
Specifies the hash used in the LUKS key setup scheme and volume key digest.
|
||||
|
||||
NOTE: if this parameter is not specified, default hash algorithm is always used
|
||||
for new device header.
|
||||
.TP
|
||||
.B "\-\-iter-time, \-i \fI<milliseconds>\fR"
|
||||
The number of milliseconds to spend with PBKDF2 passphrase processing for the
|
||||
@@ -100,6 +103,12 @@ Read a maximum of \fIvalue\fR bytes from the key file.
|
||||
Default is to read the whole file up to the compiled-in
|
||||
maximum.
|
||||
.TP
|
||||
.B "\-\-keep-key"
|
||||
Do not change encryption key, just reencrypt the LUKS header and keyslots.
|
||||
|
||||
This option can be combined only with \fI\-\-hash\fR or \fI\-\-iter-time\fR
|
||||
options.
|
||||
.TP
|
||||
.B "\-\-tries, \-T"
|
||||
Number of retries for invalid passphrase entry.
|
||||
.TP
|
||||
|
||||
@@ -47,6 +47,7 @@ static int opt_tries = 3;
|
||||
static int opt_key_slot = CRYPT_ANY_SLOT;
|
||||
static int opt_key_size = 0;
|
||||
static int opt_new = 0;
|
||||
static int opt_keep_key = 0;
|
||||
|
||||
static const char *opt_reduce_size_str = NULL;
|
||||
static uint64_t opt_reduce_size = 0;
|
||||
@@ -424,7 +425,8 @@ out:
|
||||
|
||||
static int create_new_header(struct reenc_ctx *rc, const char *cipher,
|
||||
const char *cipher_mode, const char *uuid,
|
||||
int key_size, struct crypt_params_luks1 *params)
|
||||
const char *key, int key_size,
|
||||
struct crypt_params_luks1 *params)
|
||||
{
|
||||
struct crypt_device *cd_new = NULL;
|
||||
int i, r;
|
||||
@@ -441,7 +443,7 @@ static int create_new_header(struct reenc_ctx *rc, const char *cipher,
|
||||
crypt_set_iteration_time(cd_new, opt_iteration_time);
|
||||
|
||||
if ((r = crypt_format(cd_new, CRYPT_LUKS1, cipher, cipher_mode,
|
||||
uuid, NULL, key_size, params)))
|
||||
uuid, key, key_size, params)))
|
||||
goto out;
|
||||
log_verbose(_("New LUKS header for device %s created.\n"), rc->device);
|
||||
|
||||
@@ -464,6 +466,8 @@ static int backup_luks_headers(struct reenc_ctx *rc)
|
||||
struct crypt_device *cd = NULL;
|
||||
struct crypt_params_luks1 params = {0};
|
||||
char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
|
||||
char *old_key = NULL;
|
||||
size_t old_key_size;
|
||||
int r;
|
||||
|
||||
log_dbg("Creating LUKS header backup for device %s.", rc->device);
|
||||
@@ -494,14 +498,30 @@ static int backup_luks_headers(struct reenc_ctx *rc)
|
||||
}
|
||||
}
|
||||
|
||||
if (opt_keep_key) {
|
||||
log_dbg("Keeping key from old header.");
|
||||
old_key_size = crypt_get_volume_key_size(cd);
|
||||
old_key = crypt_safe_alloc(old_key_size);
|
||||
if (!old_key) {
|
||||
r = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
r = crypt_volume_key_get(cd, CRYPT_ANY_SLOT, old_key, &old_key_size,
|
||||
rc->p[rc->keyslot].password, rc->p[rc->keyslot].passwordLen);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = create_new_header(rc,
|
||||
opt_cipher ? cipher : crypt_get_cipher(cd),
|
||||
opt_cipher ? cipher_mode : crypt_get_cipher_mode(cd),
|
||||
crypt_get_uuid(cd),
|
||||
old_key,
|
||||
opt_key_size ? opt_key_size / 8 : crypt_get_volume_key_size(cd),
|
||||
¶ms);
|
||||
out:
|
||||
crypt_free(cd);
|
||||
crypt_safe_free(old_key);
|
||||
if (r)
|
||||
log_err(_("Creation of LUKS backup headers failed.\n"));
|
||||
return r;
|
||||
@@ -559,7 +579,7 @@ static int backup_fake_header(struct reenc_ctx *rc)
|
||||
r = create_new_header(rc,
|
||||
opt_cipher ? cipher : DEFAULT_LUKS1_CIPHER,
|
||||
opt_cipher ? cipher_mode : DEFAULT_LUKS1_MODE,
|
||||
NULL,
|
||||
NULL, NULL,
|
||||
(opt_key_size ? opt_key_size : DEFAULT_LUKS1_KEYBITS) / 8,
|
||||
¶ms);
|
||||
out:
|
||||
@@ -1087,11 +1107,15 @@ static int run_reencrypt(const char *device)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!opt_keep_key) {
|
||||
log_dbg("Running data area reencryption.");
|
||||
if ((r = activate_luks_headers(&rc)))
|
||||
goto out;
|
||||
|
||||
if ((r = copy_data(&rc)))
|
||||
goto out;
|
||||
} else
|
||||
log_dbg("Keeping existing key, skipping data area reencryption.");
|
||||
|
||||
r = restore_luks_header(&rc);
|
||||
out:
|
||||
@@ -1130,6 +1154,7 @@ int main(int argc, const char **argv)
|
||||
{ "cipher", 'c', POPT_ARG_STRING, &opt_cipher, 0, N_("The cipher used to encrypt the disk (see /proc/crypto)"), NULL },
|
||||
{ "key-size", 's', POPT_ARG_INT, &opt_key_size, 0, N_("The size of the encryption key"), N_("BITS") },
|
||||
{ "hash", 'h', POPT_ARG_STRING, &opt_hash, 0, N_("The hash used to create the encryption key from the passphrase"), NULL },
|
||||
{ "keep-key", '\0', POPT_ARG_NONE, &opt_keep_key, 0, N_("Do not change key, no data area reencryption."), NULL },
|
||||
{ "key-file", 'd', POPT_ARG_STRING, &opt_key_file, 0, N_("Read the key from a file."), NULL },
|
||||
{ "iter-time", 'i', POPT_ARG_INT, &opt_iteration_time, 0, N_("PBKDF2 iteration time for LUKS (in ms)"), N_("msecs") },
|
||||
{ "batch-mode", 'q', POPT_ARG_NONE, &opt_batch_mode, 0, N_("Do not ask for confirmation"), NULL },
|
||||
@@ -1235,6 +1260,10 @@ int main(int argc, const char **argv)
|
||||
usage(popt_context, EXIT_FAILURE, _("Option --new must be used together with --reduce-device-size."),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_keep_key && ((!opt_hash && !opt_iteration_time) || opt_cipher || opt_new))
|
||||
usage(popt_context, EXIT_FAILURE, _("Option --keep-key can be used only with --hash or --iter-time."),
|
||||
poptGetInvocationName(popt_context));
|
||||
|
||||
if (opt_debug) {
|
||||
opt_verbose = 1;
|
||||
crypt_set_debug_level(-1);
|
||||
|
||||
@@ -255,5 +255,16 @@ add_scsi_device sector_size=512 physblk_exp=3 dev_size_mb=8
|
||||
simple_scsi_reenc "[4096/512 sector]"
|
||||
echo "[OK]"
|
||||
|
||||
echo "[8] Header only reencryption (hash and iteration time)"
|
||||
echo $PWD1 | $CRYPTSETUP -q luksFormat --hash sha1 $LOOPDEV1 || fail
|
||||
wipe $PWD1
|
||||
check_hash $PWD1 $HASH1
|
||||
echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --hash sha256 --iter-time 1
|
||||
check_hash $PWD1 $HASH1
|
||||
echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --hash sha512
|
||||
check_hash $PWD1 $HASH1
|
||||
echo $PWD1 | $REENC $LOOPDEV1 -q --keep-key --iter-time 1
|
||||
check_hash $PWD1 $HASH1
|
||||
|
||||
remove_mapping
|
||||
exit 0
|
||||
|
||||
Reference in New Issue
Block a user