Re: LUKS2 online reencryption with PAES cipher ?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 17.08.2020 13:44, Ingo Franzki wrote:
> Hi,
> 
> I just played a little bit with the LUKS2 online reencryption feature (using code from current master). 
> Works great (as far as I can tell) for clear key (i.e. AES cipher), but it fails for the wrapped key cipher PAES.
> 
> It fails because it always generates a new volume key by random, regardless which cipher is used. 
> For the PAES cipher, a key generated by random wont work, such a key must be generated by the HSM.
> 
> For 'cryptsetup luksFormat' we use it with a key generated outside of cryptsetup, passing the key via --master-key-file (together with --key-size).
> To make 'cryptsetup reencrypt' work with PAES, we would also need to pass in the new key via --master-key-file (and --key-size).
> Unfortunately, the reencrypt action does not use the master key file option.
> 
> Function action_reencrypt() calls crypt_keyslot_add_by_key() which then calls crypt_keyslot_add_by_key() but passes NULL as volume key.
> Thus a new randomly generated key is used. If the key specified with the master key file options would be passed here, it should work with the PAES cipher also.
> 
> This would not only be beneficial for PAES, but also for clear key AES cipher, allowing to use a specified key as volume key (like with luksFormat).
> 
> If I try to use 'cryptsetup reencrypt' with an existing LUKS2 volume encrypted with PAES it fails as follows:
> 
> # cryptsetup reencrypt /dev/loop0 --debug
> ... snip debug messages ...
> Enter passphrase for key slot 0:
> ... snip debug messages ...
> # Checking if cipher paes-cbc-plain64 is usable.
> # Userspace crypto wrapper cannot use paes-cbc-plain64 (-22).
> Failed to setup dm-crypt key mapping for device /dev/loop0.
> Check that kernel supports paes-cbc-plain64 cipher (check syslog for more info).
> 
> This is because function LUKS2_check_cipher() is called which again generates a new volume key to test the cipher by random. 
> So the code should use 'if (!crypt_cipher_wrapped_key(....))' like it does at other places (e.g. in _crypt_format_luks2() ) to not check the cipher for wrapped key ciphers (PAES is the only such at the moment).
> 
> So I think with a few code changes, it should be possible to make online reencryption also work with the PAES cipher, when the volume key is generated outside of cryptsetup and passed in via --master-key-file.
> 
> What _does_ work, is to reencrypt a LUKS2 PAES volume with a clear key cipher:
> 
> # cryptsetup reencrypt /dev/loop0 --cipher aes-cbc-plain64
> Enter passphrase for key slot 0:
> Finished, time 01:22.875,  984 MiB written, speed  11.9 MiB/s
> 

With this little patch I was able to get it to work:

>From 7090e50a80d09add1418fc7debd254883561fb77 Mon Sep 17 00:00:00 2001
From: Ingo Franzki <ifranzki@xxxxxxxxxxxxx>
Date: Mon, 17 Aug 2020 17:15:05 +0200
Subject: [PATCH] Support online reencryption for PAES cipher

Signed-off-by: Ingo Franzki <ifranzki@xxxxxxxxxxxxx>
---
 lib/luks2/luks2_reencrypt.c | 2 +-
 man/cryptsetup.8            | 2 +-
 src/cryptsetup.c            | 9 ++++++++-
 3 files changed, 10 insertions(+), 3 deletions(-)

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<options>\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..4e46b9e9 100644
--- a/src/cryptsetup.c
+++ b/src/cryptsetup.c
@@ -3089,6 +3089,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 *key = NULL;
 	const char *active_name = NULL;
 	struct keyslot_passwords *kp;
 	struct crypt_params_luks2 luks2_params = {};
@@ -3131,6 +3132,12 @@ static int action_reencrypt_luks2(struct crypt_device *cd)
 	if (!key_size)
 		return -EINVAL;
 
+	if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
+		r = crypt_cli_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, key_size);
+		if (r < 0)
+			return r;
+	}
+
 	r = crypt_keyslot_max(CRYPT_LUKS2);
 	if (r < 0)
 		return r;
@@ -3158,7 +3165,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, key, key_size,
 					kp[i].password, kp[i].passwordLen, CRYPT_VOLUME_KEY_NO_SEGMENT);
 			tools_keyslot_msg(r, CREATED);
 			if (r < 0)
-- 
2.16.2.windows.1


-- 
Ingo Franzki
eMail: ifranzki@xxxxxxxxxxxxx  
Tel: ++49 (0)7031-16-4648
Fax: ++49 (0)7031-16-3456
Linux on IBM Z Development, Schoenaicher Str. 220, 71032 Boeblingen, Germany

IBM Deutschland Research & Development GmbH / Vorsitzender des Aufsichtsrats: Matthias Hartmann
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen / Registergericht: Amtsgericht Stuttgart, HRB 243294
IBM DATA Privacy Statement: https://www.ibm.com/privacy/us/en/
_______________________________________________
dm-crypt mailing list
dm-crypt@xxxxxxxx
https://www.saout.de/mailman/listinfo/dm-crypt




[Index of Archives]     [Device Mapper Devel]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]     [Fedora Docs]

  Powered by Linux