diff --git a/src/utils_reencrypt.c b/src/utils_reencrypt.c index 5443d559..2987bb3d 100644 --- a/src/utils_reencrypt.c +++ b/src/utils_reencrypt.c @@ -236,12 +236,11 @@ static enum device_status_info load_luks(struct crypt_device **r_cd, const char static int action_encrypt_luks2(struct crypt_device **cd, const char *data_device, const char *device_name) { - char *tmp; const char *type; int keyslot, r, fd; uuid_t uuid; size_t passwordLen; - char *msg, uuid_str[37], header_file[PATH_MAX] = { 0 }, *password = NULL; + char *tmp, uuid_str[37], header_file[PATH_MAX] = { 0 }, *password = NULL; uint32_t activate_flags = 0; const struct crypt_params_luks2 luks2_params = { .sector_size = ARG_UINT32(OPT_SECTOR_SIZE_ID) ?: SECTOR_SIZE @@ -301,23 +300,6 @@ static int action_encrypt_luks2(struct crypt_device **cd, const char *data_devic ARG_SET_STR(OPT_UUID_ID, tmp); } - /* Check the data device is not LUKS device already */ - if ((r = crypt_init(cd, data_device))) - return r; - r = crypt_load(*cd, CRYPT_LUKS, NULL); - crypt_free(*cd); - *cd = NULL; - if (!r && !ARG_SET(OPT_BATCH_MODE_ID)) { - r = asprintf(&msg, _("Detected LUKS device on %s. Do you want to encrypt that LUKS device again?"), data_device); - if (r == -1) - return -ENOMEM; - - r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL; - free(msg); - if (r < 0) - return r; - } - if (!ARG_SET(OPT_HEADER_ID)) { r = snprintf(header_file, sizeof(header_file), "LUKS2-temp-%s.new", ARG_STR(OPT_UUID_ID)); if (r < 0 || (size_t)r >= sizeof(header_file)) @@ -1022,33 +1004,75 @@ out: static int _encrypt(int action_argc, const char **action_argv) { + enum device_status_info hdr_st, dev_st; + struct stat st; const char *type = luksType(device_type); - bool luks1_in_reencrypt = false; + struct crypt_device *check_cd = NULL; + + dev_st = load_luks(&check_cd, CRYPT_LUKS, NULL, uuid_or_device(action_argv[0])); + crypt_free(check_cd); + check_cd = NULL; + + if (dev_st == DEVICE_INVALID) + return -EINVAL; + + if (dev_st == DEVICE_LUKS2 || dev_st == DEVICE_LUKS1) { + log_err(_("Device %s is already LUKS device."), uuid_or_device(action_argv[0])); + return -EINVAL; + } /* 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)); + if (stat(ARG_STR(OPT_HEADER_ID), &st) < 0 && errno == ENOENT) + hdr_st = DEVICE_NOT_LUKS; + else { + hdr_st = load_luks(&check_cd, CRYPT_LUKS, NULL, ARG_STR(OPT_HEADER_ID)); + + crypt_free(check_cd); + + if (hdr_st == DEVICE_INVALID) + return -EINVAL; + + if (hdr_st == DEVICE_LUKS1_UNUSABLE && isLUKS2(type)) { + log_err(_("Device %s is already in LUKS1 reencryption."), ARG_STR(OPT_HEADER_ID)); + return -EINVAL; + } + + if (hdr_st == DEVICE_LUKS2_REENCRYPT && isLUKS1(type)) { + log_err(_("Device %s is already in LUKS2 reencryption."), ARG_STR(OPT_HEADER_ID)); + return -EINVAL; + } + + if (hdr_st == DEVICE_LUKS2 || hdr_st == DEVICE_LUKS1) { + log_err(_("Device %s is already LUKS device."), ARG_STR(OPT_HEADER_ID)); + return -EINVAL; + } + } + + if (dev_st == DEVICE_LUKS2_REENCRYPT || dev_st == DEVICE_LUKS1_UNUSABLE) { + log_err(_("Data device %s is already in LUKS reencryption."), uuid_or_device(action_argv[0])); return -EINVAL; } - } - if (!luks1_in_reencrypt) - luks1_in_reencrypt = reencrypt_luks1_in_progress(uuid_or_device(action_argv[0])) == 0; + dev_st = hdr_st; + } else { + if (dev_st == DEVICE_LUKS1_UNUSABLE && isLUKS2(type)) { + log_err(_("Device %s is already in LUKS1 reencryption."), ARG_STR(OPT_HEADER_ID)); + return -EINVAL; + } - /* 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 (dev_st == DEVICE_LUKS2_REENCRYPT && isLUKS1(type)) { + log_err(_("Device %s already in LUKS2 reencryption."), ARG_STR(OPT_HEADER_ID)); + return -EINVAL; + } } if (!type) type = crypt_get_default_type(); - if (isLUKS1(type) || luks1_in_reencrypt) + if (isLUKS1(type) || dev_st == DEVICE_LUKS1_UNUSABLE) { return reencrypt_luks1(action_argv[0]); - else if (isLUKS2(type)) + } else if (isLUKS2(type) || dev_st == DEVICE_LUKS2_REENCRYPT) return encrypt_luks2(action_argc, action_argv); return -EINVAL; diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test index 73818b5d..4fc8cc7b 100755 --- a/tests/luks2-reencryption-test +++ b/tests/luks2-reencryption-test @@ -433,6 +433,8 @@ function encrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest echo $PWD1 | $CRYPTSETUP reencrypt $DEV --header $4 --resilience $2 --sector-size $1 -q $FAST_PBKDF_ARGON || fail check_hash $PWD1 $3 $4 + [ -f $4 ] && rm -f $4 + echo "[OK]" } @@ -463,6 +465,8 @@ function encrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 $CRYPTSETUP close $DEV_NAME || fail + [ -f $4 ] && rm -f $4 + echo "[OK]" } @@ -487,6 +491,8 @@ function decrypt_recover_detached() { # $1 sector size, $2 resilience, $3 digest check_hash_dev $DEV $3 + [ -f $4 ] && rm -f $4 + echo "[OK]" } @@ -517,6 +523,8 @@ function decrypt_recover_detached_online() { # $1 sector size, $2 resilience, $3 $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 && fail check_hash_dev $DEV $3 + [ -f $4 ] && rm -f $4 + echo "[OK]" } @@ -565,6 +573,7 @@ function encrypt_offline_fixed_size() { wipe_dev $DEV echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -q $FAST_PBKDF_ARGON $DEV --header $7 --sector-size $1 --device-size $2s --resilience $4 || fail check_hash_head $PWD1 $2 $3 $7 + [ -f $7 ] && rm -f $7 # try to reencrypt device size + 1 encryption sector size wipe_dev $DEV @@ -574,12 +583,15 @@ function encrypt_offline_fixed_size() { # misaligned reencryption size if [ $_esz -gt 1 ]; then + [ -f $7 ] && rm -f $7 echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -q $FAST_PBKDF_ARGON $DEV --header $7 --sector-size $1 --init-only || fail echo $PWD1 | $CRYPTSETUP reencrypt -q $DEV --header $7 --device-size $(($2+_esz-1))s --resilience $4 2>/dev/null && fail $CRYPTSETUP luksDump $7 | grep -q "2: crypt" || fail $CRYPTSETUP luksDump $7 | grep -q "3: crypt" && fail check_hash $PWD1 $6 $7 fi + + [ -f $7 ] && rm -f $7 } # sector size (bytes) @@ -905,14 +917,18 @@ wipe_dev $DEV echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail check_hash $PWD1 $HASH3 $IMG_HDR wipe_dev $DEV +rm -f $IMG_HDR echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --resilience journal --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail check_hash $PWD1 $HASH3 $IMG_HDR wipe_dev $DEV +rm -f $IMG_HDR echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -c twofish-cbc-essiv:sha256 -s 128 --resilience none --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail check_hash $PWD1 $HASH3 $IMG_HDR wipe_dev $DEV +rm -f $IMG_HDR echo $PWD1 | $CRYPTSETUP reencrypt --encrypt -c serpent-xts-plain --resilience checksum --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail check_hash $PWD1 $HASH3 $IMG_HDR +rm -f $IMG_HDR # Device activation after encryption initialization wipe_dev $DEV @@ -924,12 +940,14 @@ check_hash_dev /dev/mapper/$DEV_NAME $HASH3 echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt -c aes-cbc-essiv:sha256 -s 128 --reduce-device-size 8M -q $FAST_PBKDF_ARGON $DEV_NAME 2>/dev/null && fail $CRYPTSETUP close $DEV_NAME check_hash $PWD1 $HASH3 $IMG_HDR +rm -f $IMG_HDR # Device encryption with data offset set in detached header wipe_dev $DEV dd if=/dev/urandom of=$DEV bs=512 count=32768 >/dev/null 2>&1 echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --header $IMG_HDR --offset 32768 -q $FAST_PBKDF_ARGON $DEV || fail check_hash $PWD1 $HASH9 $IMG_HDR +rm -f $IMG_HDR # Device activation using key file wipe_dev $DEV @@ -1616,11 +1634,12 @@ echo $PWD1 | $CRYPTSETUP -q luksFormat -S5 --header $IMG_HDR --type luks2 $FAST_ echo -e "$PWD1\n$PWD1" | $CRYPTSETUP luksAddKey --unbound -s80 -S0 $FAST_PBKDF_ARGON $IMG_HDR || fail echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --init-only --header $IMG_HDR $DEV || fail echo $PWD1 | $CRYPTSETUP open --test-passphrase $IMG_HDR || fail +rm -f $IMG_HDR +wipe_dev_head $DEV 1 echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --init-only --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail echo $PWD1 | $CRYPTSETUP open --test-passphrase $IMG_HDR || fail -wipe_dev_head $DEV 1 echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 8M $FAST_PBKDF_ARGON $DEV || fail echo $PWD1 | $CRYPTSETUP open --test-passphrase $DEV || fail