Convert a LUKS2 Keyslot to New PBKDF Settings

cryptsetup luksConvertKey brings a stale LUKS2 keyslot's PBKDF parameters up to date without touching the passphrase or the data itself. You will convert the keyslot, then confirm the result with cryptsetup luksDump.

The installed command here is cryptsetup 2.7.0 from package cryptsetup-bin 2:2.7.0-1ubuntu4.2. Allow 15 to 30 minutes, plus time for a header backup and for the PBKDF benchmark to run. This is a privileged, security-sensitive metadata change. You need a root shell through sudo, a LUKS2 device, its current passphrase, and enough free keyslot space if you want the safer copy-then-remove path. Do not practise on the only copy of a valuable volume.

1. Identify the device and inspect its keyslots

Replace /dev/EXAMPLE with the block device that contains the LUKS2 header. If you use a detached header, pass the header path with --header in each command. First confirm the installed program and inspect the current metadata:

$ cryptsetup --version
cryptsetup 2.7.0 flags: UDEV BLKID KEYRING FIPS KERNEL_CAPI HW_OPAL
$ sudo cryptsetup luksDump /dev/EXAMPLE

Look for the Keyslots: section and record which slot contains the passphrase you intend to convert. The dump also shows each slot's PBKDF, time or iteration cost, memory cost and parallel cost. The slot number is not the same thing as the volume's encryption key.

Checkpoint: write down the device path, detached-header path if applicable, source slot number, and the PBKDF values currently shown. Stop if the device is not LUKS2: this subcommand is for LUKS2 keyslots, and the manual says LUKS1 accepts only PBKDF2.

2. Make and protect a header backup

A header backup contains the LUKS header and keyslot area. It is also sensitive key material: a backup and a passphrase valid when it was made can decrypt the data even after that passphrase is removed from the live header. Store the backup offline with permissions and handling suitable for a secret.

$ sudo cryptsetup luksHeaderBackup \
    --header-backup-file /root/luks-EXAMPLE-header.img \
    /dev/EXAMPLE
$ sudo ls -l /root/luks-EXAMPLE-header.img

The backup command changes no live keyslot, but the file is now a recovery credential. Do not leave it in a shared directory or commit it to a repository. Before proceeding, confirm you can retrieve this file and that its contents will be available if the conversion suffers a media failure.

Warning: luksConvertKey can overwrite a keyslot directly when no free slot is available. A media failure at that point can leave the old parameters wiped and the LUKS container inaccessible. The backup is the recovery path, not a reason to skip testing the backup process.

3. Choose the new PBKDF policy

If you omit PBKDF options, cryptsetup applies the compiled-in LUKS2 defaults. To choose explicitly, use --pbkdf with argon2id, argon2i or pbkdf2. For Argon2, --iter-time is a time target in milliseconds, and cryptsetup benchmarks suitable parameters on the current machine. Memory and parallel costs can also be supplied as limits.

A representative conversion request:

$ sudo cryptsetup luksConvertKey \
    --pbkdf argon2id \
    --iter-time 2000 \
    --key-slot SOURCE_SLOT \
    /dev/EXAMPLE

Replace SOURCE_SLOT with the slot number recorded in step 1. The passphrase prompt is for that existing slot, entered interactively, so it never lands in shell history or the process list. A 2,000 millisecond target is only an example: benchmark on the actual host and choose a value that does not make normal opening unacceptably slow.

Do not use --pbkdf-force-iterations casually. It disables the benchmark and sets the time cost directly. With Argon2, combine it only when you have deliberately selected compatible memory and parallel values: the manual warns that unsuitable fixed values can cause extremely long delays or out-of-memory termination.

4. Confirm the slot-selection behaviour before you press enter

That distinction is the main safety trap. The free-slot route gives the metadata update room to complete before the old parameters are purged; it does not make the operation risk-free, and it does not preserve an old PBKDF copy as a second usable password after success. The direct-overwrite route has the failure mode described in the warning above.

Do not add --batch-mode just to make a script look tidy. It suppresses confirmation questions and, unless passphrase verification is requested, also disables it. Run the first conversion interactively in a maintenance window. If standard input is required for automation, use --key-file - deliberately: cryptsetup reads stdin without stopping at newline characters.

5. Run the conversion and capture its result

Run the command from step 3 as root. Expect a passphrase prompt and a delay while the PBKDF benchmark runs. Do not interrupt it, disconnect the storage, or reboot during the metadata update.

$ sudo cryptsetup luksConvertKey \
    --pbkdf argon2id --iter-time 2000 \
    --key-slot SOURCE_SLOT /dev/EXAMPLE
Enter passphrase for key slot SOURCE_SLOT:

The exact prompt and any progress text can vary. A successful return to the shell with exit status zero is the immediate checkpoint:

$ printf 'conversion status: %s\n' "$?"
conversion status: 0

If the command fails, do not repeatedly guess at passphrases or PBKDF values. Preserve the error text, inspect the device state with sudo cryptsetup luksDump /dev/EXAMPLE, and compare it with the notes from step 1. If the header is no longer usable, stop making changes and restore only from the known-good backup using the separate luksHeaderRestore procedure. Restoration replaces the live header and keyslots, so only passphrases present in that backup will work afterwards.

6. Verify the new parameters and an ordinary open

Read the metadata again and find the converted slot:

$ sudo cryptsetup luksDump /dev/EXAMPLE

Verify that the slot is active and that its PBKDF and cost values match the policy you selected. The final memory and parallel values are measured results and can be lower than requested because of available memory or CPU count. That is expected: record what luksDump reports rather than what you typed.

Then test the normal opening path during the same maintenance window, using the mapping name and mount procedure appropriate to your system. For a read-only passphrase check, cryptsetup provides --test-passphrase as a global option:

$ sudo cryptsetup open --test-passphrase /dev/EXAMPLE
Enter passphrase for /dev/EXAMPLE:

This should return to the shell with status zero when the passphrase works. It does not create a device mapping. Check the status immediately if you need to distinguish a failed test from a successful one:

$ printf 'unlock test status: %s\n' "$?"
unlock test status: 0

Done means