diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c index f9815d86..4429f532 100644 --- a/lib/luks2/luks2_reencrypt.c +++ b/lib/luks2/luks2_reencrypt.c @@ -2988,7 +2988,7 @@ static int reencrypt_init_by_passphrase(struct crypt_device *cd, if (flags & CRYPT_REENCRYPT_RECOVERY) return reencrypt_recovery_by_passphrase(cd, hdr, keyslot_old, keyslot_new, passphrase, passphrase_size); - if (cipher) { + if (cipher && !crypt_cipher_wrapped_key(cipher, cipher_mode)) { r = crypt_keyslot_get_key_size(cd, keyslot_new); if (r < 0) return r; diff --git a/man/cryptsetup.8 b/man/cryptsetup.8 index bc3fff61..3154d479 100644 --- a/man/cryptsetup.8 +++ b/man/cryptsetup.8 @@ -199,7 +199,7 @@ as soon as possible and mounted (used) before full data area encryption is compl Action supports following additional \fB\fR [\-\-encrypt, \-\-decrypt, \-\-device\-size, \-\-resilience, \-\-resilience-hash, \-\-hotzone-size, \-\-init\-only, \-\-resume\-only, -\-\-reduce\-device\-size]. +\-\-reduce\-device\-size, \-\-master\-key\-file, \-\-key\-size]. .SH PLAIN MODE Plain dm-crypt encrypts the device sector-by-sector with a diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 4fb962c8..b1e7c947 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -3088,7 +3088,7 @@ static int action_reencrypt_luks2(struct crypt_device *cd) { size_t i, vk_size, kp_size; int r, keyslot_old = CRYPT_ANY_SLOT, keyslot_new = CRYPT_ANY_SLOT, key_size; - char dm_name[PATH_MAX], cipher [MAX_CIPHER_LEN], mode[MAX_CIPHER_LEN], *vk; + char dm_name[PATH_MAX], cipher [MAX_CIPHER_LEN], mode[MAX_CIPHER_LEN], *vk = NULL; const char *active_name = NULL; struct keyslot_passwords *kp; struct crypt_params_luks2 luks2_params = {}; @@ -3130,6 +3130,7 @@ static int action_reencrypt_luks2(struct crypt_device *cd) if (!key_size) return -EINVAL; + vk_size = key_size; r = crypt_keyslot_max(CRYPT_LUKS2); if (r < 0) @@ -3144,11 +3145,10 @@ static int action_reencrypt_luks2(struct crypt_device *cd) if (r) goto err; - vk_size = key_size; - vk = crypt_safe_alloc(vk_size); - if (!vk) { - r = -ENOMEM; - goto err; + if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) { + r = crypt_cli_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &vk, key_size); + if (r < 0) + goto err; } r = -ENOENT; @@ -3158,7 +3158,7 @@ static int action_reencrypt_luks2(struct crypt_device *cd) r = set_keyslot_params(cd, i); if (r < 0) break; - r = crypt_keyslot_add_by_key(cd, CRYPT_ANY_SLOT, NULL, key_size, + r = crypt_keyslot_add_by_key(cd, CRYPT_ANY_SLOT, vk, key_size, kp[i].password, kp[i].passwordLen, CRYPT_VOLUME_KEY_NO_SEGMENT); tools_keyslot_msg(r, CREATED); if (r < 0) @@ -3167,9 +3167,17 @@ static int action_reencrypt_luks2(struct crypt_device *cd) kp[i].new = r; keyslot_new = r; keyslot_old = i; - r = crypt_volume_key_get(cd, keyslot_new, vk, &vk_size, kp[i].password, kp[i].passwordLen); - if (r < 0) - break; + if (!vk) { + /* key generated in crypt_keyslot_add_by_key() call above */ + vk = crypt_safe_alloc(key_size); + if (!vk) { + r = -ENOMEM; + break; + } + r = crypt_volume_key_get(cd, keyslot_new, vk, &vk_size, kp[i].password, kp[i].passwordLen); + if (r < 0) + break; + } r = assign_tokens(cd, i, r); if (r < 0) break; @@ -3189,8 +3197,6 @@ static int action_reencrypt_luks2(struct crypt_device *cd) } } - crypt_safe_free(vk); - if (r < 0) goto err; @@ -3210,6 +3216,7 @@ static int action_reencrypt_luks2(struct crypt_device *cd) kp[keyslot_old].passwordLen, keyslot_old, kp[keyslot_old].new, cipher, mode, ¶ms); err: + crypt_safe_free(vk); for (i = 0; i < kp_size; i++) { crypt_safe_free(kp[i].password); if (r < 0 && kp[i].new >= 0 &&