1

Cryptsetup/LUKS2 destroyed my data when I tried to remove encryption, Why?

I'm Using Cryptsetup 2.3.3. I was experimenting with LUKS (in a VM, thankfully) and had an ext4 filesystem on a LUKS2 encrypted partition. I decided to test out LUKS's ability to non-destructively remove encryption from a block device I ran cryptsetup reencrypt --decrypt and got an error I must pass in a header. Since I do not use a detached header, I passed in the device so it can read the header off of it. The decryption gave a "standard" warning:

WARNING!
========
Unable to decide if device /tmp/file is activated or not.
Are you sure you want to proceed with reencryption in offline mode?
It may lead to data corruption if the device is actually activated.
To run reencryption in online mode, use --active-name parameter instead.

and then procceded to decrypt without reporting any error... then the data was lost.

What I expected is for the ext4 system formerly inside the LUKS2 device to become visible to the OS, just as if I'd formatted the partition with ext4 to begin with. But blkid still detected the partition as TYPE="crypto_LUKS". I then tried to open the partition with luks, thinking it may have actually done nothing, and the data was still there. But after entering the passphrase I got the error

Keyslot open failed.
No usable keyslot is available.

and luksDumps showed no active keyslots.

Why did cryptsetup destroy my data?

1

cryptsetup's decryption of LUKS2 device is badly documented and includes several incredibly bad design choices which help you destroy your data.

For the problem descirbed in OP, the issue is that it cryptsetup assumes you're using a detached header, but doesn't clearly state it anywhere. It doesn't include any basic sanity checks to stop you from making this error and their tests don't cover this scenario.

If you check, the tests for this all use a device created with a detached header. It also looks like they only test online decryption, even though the command allows offline decryption.

I've tested decryption for LUKS2 device with detached header and it worked. After decryption, the partition was detected as being formatted with an ext4 filesystem.

Note that it would be trivial for cryptsetup to check that the device already has a header and at least warn the user that's the case. In the offline case, it could also easily determine that the encrypted block device was also passed in as the --header argument and either handle this gracefully, or refuse to proceed. But it does neither.

Decryption (possible only in offline mode) works for LUKS1,but for that you don't use cryptsetup reencrypt --decrypt (which is confusing usage in itself), but instead need to use a separate command called cryptsetup-reencrypt. This command supports LUKS1, but not LUKS2, naturally. To make things worse, at least on fedora this command isn't packaged as part of cryptsetup, but as a separate package cryptsetup-reencrypt which isn't installed by default.

In summary:

  • As of 2.3.3, you can't directly decrypt a LUKS2 drive unless you use a detached header. Passing a device that has a header as the --header argument raise no error, and cryptsetup will then proceed to quietly destroy your data.
  • You could probably convert from luks2 to luks1, and then use the seperate cryptsetup-reencrypt command to decrypt. I haven't tested this, but it should work.

I tried reporting this issue upstream, but gitlab prevents users who try to register with some anonnymity.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.