From cade8201d2810114be987bcbc77c38c1ce1d1830 Mon Sep 17 00:00:00 2001 From: Ondrej Kozina Date: Thu, 7 Oct 2021 15:51:58 +0200 Subject: [PATCH] Enable legacy LUKS1 reencryption in cryptsetup utility. --- src/utils_luks.h | 4 ++++ src/utils_reencrypt.c | 39 ++++++++++++++++++++++++++++++++++--- src/utils_reencrypt_luks1.c | 16 +++++++++++++++ 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/utils_luks.h b/src/utils_luks.h index a45b6ddf..a01109ff 100644 --- a/src/utils_luks.h +++ b/src/utils_luks.h @@ -45,4 +45,8 @@ int luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_password int reencrypt(int action_argc, const char **action_argv); +int reencrypt_luks1(const char *device); + +int reencrypt_luks1_in_progress(const char *device); + #endif /* UTILS_LUKS_H */ diff --git a/src/utils_reencrypt.c b/src/utils_reencrypt.c index 5de21441..a92d6df6 100644 --- a/src/utils_reencrypt.c +++ b/src/utils_reencrypt.c @@ -777,6 +777,12 @@ static enum device_status_info load_luks(struct crypt_device **r_cd, const char if (r == -EBUSY) /* luks2 locking error (message printed by libcryptsetup) */ return DEVICE_INVALID; + if (!type || isLUKS1(type)) + r = reencrypt_luks1_in_progress(uuid_or_device(header_device ?: data_device)); + + if (!r) + return DEVICE_LUKS1_UNUSABLE; + log_err(_("Device %s is not a valid %s device."), uuid_or_device(header_device ?: data_device), type ?: "LUKS"); @@ -955,11 +961,32 @@ static int reencrypt_luks2(struct crypt_device *cd, int action_argc, const char static int encrypt(int action_argc, const char **action_argv) { const char *type = luksType(device_type); + bool luks1_in_reencrypt = false; + + /* explicit request for LUKS2 encryption */ + if (ARG_SET(OPT_HEADER_ID)) { + luks1_in_reencrypt = reencrypt_luks1_in_progress(ARG_STR(OPT_HEADER_ID)) == 0; + if (luks1_in_reencrypt && isLUKS2(type)) { + log_err(_("Device %s already in LUKS1 reencryption."), ARG_STR(OPT_HEADER_ID)); + return -EINVAL; + } + } + + if (!luks1_in_reencrypt) + luks1_in_reencrypt = reencrypt_luks1_in_progress(uuid_or_device(action_argv[0])) == 0; + + /* explicit request for LUKS2 encryption */ + if (luks1_in_reencrypt && isLUKS2(type)) { + log_err(_("Device %s already in LUKS1 reencryption."), action_argv[0]); + return -EINVAL; + } if (!type) type = crypt_get_default_type(); - if (isLUKS2(type)) + if (isLUKS1(type) || luks1_in_reencrypt) + return reencrypt_luks1(action_argv[0]); + else if (isLUKS2(type)) return encrypt_luks2(action_argc, action_argv); return -EINVAL; @@ -979,7 +1006,10 @@ static int decrypt(int action_argc, const char **action_argv) if (dev_st == DEVICE_LUKS2) r = decrypt_luks2(cd, action_argc, action_argv); - else + else if (dev_st == DEVICE_LUKS1 || dev_st == DEVICE_LUKS1_UNUSABLE) { + crypt_free(cd); + return reencrypt_luks1(action_argv[0]); + } else r = -EINVAL; crypt_free(cd); @@ -1000,7 +1030,10 @@ static int _reencrypt(int action_argc, const char **action_argv) if (dev_st == DEVICE_LUKS2) r = reencrypt_luks2(cd, action_argc, action_argv); - else + else if (dev_st == DEVICE_LUKS1 || dev_st == DEVICE_LUKS1_UNUSABLE) { + crypt_free(cd); + return reencrypt_luks1(action_argv[0]); + } else r = -EINVAL; crypt_free(cd); diff --git a/src/utils_reencrypt_luks1.c b/src/utils_reencrypt_luks1.c index 1819ff94..c0cf3f4e 100644 --- a/src/utils_reencrypt_luks1.c +++ b/src/utils_reencrypt_luks1.c @@ -1315,3 +1315,19 @@ out: destroy_context(&rc); return r; } + +int reencrypt_luks1_in_progress(const char *device) +{ + int r; + struct stat st; + struct reenc_ctx dummy = {}; + + if (stat(device, &st) || (size_t)st.st_size < pagesize()) + return -EINVAL; + + r = device_check(&dummy, device, CHECK_UNUSABLE); + + free(dummy.device_uuid); + + return r; +}