Following up our LUKS installation, we will go further and explore how to add a backup passphrase as well as how to backup and restore LUKS volume header in case of disaster.
LUKS format uses a metadata header and 8 key-slot areas that are being placed at the beginning of the disk. The passphrases are used to decrypt a single master key that is stored in the anti-forensic stripes.
Multiple key-slots are particularly handy for applications which require several users to have distinct access keys to the same device. Multiple key-slots also allow us to add backup passphrases.
Dump a LUKS Header
We can dump the LUKS header of our existing volume to get information about the key-slots that are in use:
# cryptsetup luksDump /dev/sdb2 LUKS header information for /dev/sdb2 Version: 1 Cipher name: aes Cipher mode: cbc-essiv:sha256 Hash spec: sha1 Payload offset: 4096 MK bits: 256 MK digest: AA 88 07 f2 4b ce 79 21 85 34 f7 a6 e3 0b 6b b2 a7 b8 d5 a1 MK salt: BB dd 95 3d 1e 30 1f 66 d4 5e 31 03 12 a0 61 29 CC ef 34 8e 13 5d 80 76 8b 4a 0a c3 55 02 22 d3 MK iterations: 5750 UUID: e4971160-047b-49ce-8246-b63f1fb67db9 Key Slot 0: ENABLED Iterations: 23233 Salt: ff bc fc 78 98 5d 35 50 97 76 37 b4 70 99 38 44 9f bd a1 b9 02 2d 4d 1d 18 b5 dc f6 4c a0 37 fc Key material offset: 8 AF stripes: 4000 Key Slot 1: DISABLED Key Slot 2: DISABLED Key Slot 3: DISABLED Key Slot 4: DISABLED Key Slot 5: DISABLED Key Slot 6: DISABLED Key Slot 7: DISABLED
As we may see above, only the key-slot 0 is in use as we have only added a single passphrase when creating the volume.
Add a Backup Key
We want to add a backup passphrase to the key-slot 1. This can be achieved by using the luksAddKey parameter:
# cryptsetup luksAddKey --key-slot 1 /dev/sdb2 Enter any passphrase: Enter new passphrase for key slot: Verify passphrase:
Note that the passphrase of the existing key-slot 0 must be supplied in order to add a new one. Let us dump the header again to ensure that the key-slot 1 is enabled:
# cryptsetup luksDump /dev/sdb2 LUKS header information for /dev/sdb2 Version: 1 Cipher name: aes Cipher mode: cbc-essiv:sha256 Hash spec: sha1 Payload offset: 4096 MK bits: 256 MK digest: AA 88 07 f2 4b ce 79 21 85 34 f7 a6 e3 0b 6b b2 a7 b8 d5 a1 MK salt: BB dd 95 3d 1e 30 1f 66 d4 5e 31 03 12 a0 61 29 CC ef 34 8e 13 5d 80 76 8b 4a 0a c3 55 02 22 d3 MK iterations: 5750 UUID: e4971160-047b-49ce-8246-b63f1fb67db9 Key Slot 0: ENABLED Iterations: 23233 Salt: ff bc fc 78 98 5d 35 50 97 76 37 b4 70 99 38 44 9f bd a1 b9 02 2d 4d 1d 18 b5 dc f6 4c a0 37 fc Key material offset: 8 AF stripes: 4000 Key Slot 1: ENABLED Iterations: 23956 Salt: 3a a0 06 83 d3 e0 ba da b0 5c e2 56 cb ed 72 69 76 9a 8a b8 e1 eb e6 90 44 b3 71 7a 2f 96 80 39 Key material offset: 264 AF stripes: 4000 Key Slot 2: DISABLED Key Slot 3: DISABLED Key Slot 4: DISABLED Key Slot 5: DISABLED Key Slot 6: DISABLED Key Slot 7: DISABLED
Good, we have now got two passphrases set up. In case we forget the initial one, we can use the backup one.
Change or Remove a Key
We can remove the supplied passphrase from the LUKS device by issuing the following command:
# cryptsetup luksRemoveKey /dev/sdb2
Note that removing the last passphrase makes the LUKS container permanently inaccessible.
If we want to change an existing passphrase, we can simply remove the one that is no longer required, and add a new one.
Backup and Restore a LUKS Header
Below is an excerpt from the cryptsetup man page.
“If the header of a LUKS volume gets damaged, all data is permanently lost unless you have a header-backup. If a key-slot is damaged, it can only be restored from a header-backup or if another active key-slot with known passphrase is undamaged. Damaging the LUKS header is something people manage to do with surprising frequency. This risk is the result of a trade-off between security and safety, as LUKS is designed for fast and secure wiping by just overwriting header and key-slot area.”
Referencing LUKS FAQ, there are two critical components for decryption: the salt values in the header itself and the key-slots. If the salt values are overwritten or changed, nothing (in the cryptographically strong sense) can be done to access the data, unless there is a backup of the LUKS header. If a key-slot is damaged, the data can still be read with a different key-slot, if there is a remaining undamaged and used key-slot.
We are going to create a LUKS header backup. This can be done by issuing the following command:
# cryptsetup luksHeaderBackup <device> --header-backup-file <file>
Here device is a LUKS volume disk and file is a name of a header backup file to be created. In our case:
# cryptsetup luksHeaderBackup /dev/sdb2 --header-backup-file /root/sdb2-header.backup
Ensure that nobody has access to the header backup file. Storing the header backup file on some encrypted cloud storage wouldn’t be a bad idea.
In case of disaster where our LUKS header gets broken, we can restore it by issuing the following command:
# cryptsetup luksHeaderRestore <device> --header-backup-file <file>
Note that LUKS header restoration procedure will replace all key-slots, therefore only the passphrases from the backup will work afterwards.
Securely Erase a LUKS Header
One of LUKS disadvantages is that it is readily obvious there is encrypted data on our disk. Although in practice it doesn’t really matter, it some cases the fact that we use LUKS can give agencies green light to force us to hand over the keys. LUKS filesystem can be identified by checking its volume header:
# cryptsetup -v isLuks /dev/sdb2 Command successful.
Issuing the same command for partition
/dev/sdb1 would gives us a non-valid LUKS device message:
# cryptsetup -v isLuks /dev/sdb1 Device /dev/sdb1 is not a valid LUKS device. Command failed with code 22: Device /dev/sdb1 is not a valid LUKS device.
The presence of the LUKS header identifies the existence of the LUKS filesystem on the disk, though it is not enough to prove that we have any keys. Erasing the LUKS header makes it impossible to recover any data from the LUKS volume unless a header backup is available.
The default LUKS header (with only one key-slot enabled) takes 1052672 bytes, what is slightly more than 1 MiB. Having 2 key-slots enabled this would extend the header almost twice (key-slots * stripes * keysize + offset bytes). Therefore overwriting the first 3 MiB would do the job for us:
# head -c 3145728 /dev/zero > /dev/sdb2; sync
This would still leave the disk with encrypted data on it, but come to think of it, it might have been an experiment with