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: e5 88 07 f2 4b ce 79 21 85 34 f7 a6 e3 0b 6b b2 a7 b8 d5 a1 MK salt: 0c dd 95 3d 1e 30 1f 66 d4 5e 31 03 12 a0 61 29 e5 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 “0” key-slot is in use as we have only added a single passphrase when creating the volume.
Add a Backup Key
We would like to add a backup passphrase to the 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 an existing key-slot must be supplied first in order to add a new one. Let’s dump the header again to ensure that the “1” key-slot 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: e5 88 07 f2 4b ce 79 21 85 34 f7 a6 e3 0b 6b b2 a7 b8 d5 a1 MK salt: 0c dd 95 3d 1e 30 1f 66 d4 5e 31 03 12 a0 61 29 e5 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
Perfect, we have now got two passphrases set up on our encrypted volume. In case we forget the initial one, we can use a backup one.
Change or Remove a Key
We can remove the supplied passphrase from the LUKS device by issuing:
# cryptsetup luksRemoveKey /dev/sdb2
WARNING: removing the last passphrase makes the LUKS container permanently inaccessible!
If we want to change one of our existing passphrases, we can simply remove the unneeded one and add a new one to its place instead.
Backup and Restore a LUKS Header
From the cryptsetup man page:
“LUKS header: 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.
Making the long story short, if our LUKS header gets damaged, all data is gone. To prevent this from happening, we need to create a header backup. This can be done by issuing the following command:
# cryptsetup luksHeaderBackup <device> --header-backup-file <file>
Where <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
Important note: a LUKS header backup can grant access to most or all data, therefore we need to make sure that nobody has access to it or at least reduce the possibility for that to happen. Storing a LUKS header backup file on an encrypted cloud storage (such as Spideroak) 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>
WARNING: LUKS header restoration procedure will replace all key-slots, therefore only the passphrases from the backup will work afterwards!
Securely Erase a LUKS Header
In case you’re wondering why would we want to do this, here is the reason: 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, in some countries men in black can easily identify we’re using LUKS and 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 another disk (/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 our disk, though it’s not enough to prove that we have any keys. However, the suspicion is enough, men in black don’t have to prove anything. Therefore erasing the LUKS header makes it impossible to recover any data from the LUKS volume having no header backup available (although I bet NSA would disagree with me).
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 that might have been an experiment with /dev/random, for example. Anyhow, it’s as impossible to prove we have encrypted data of the disk as the other way round. The outcome: if they want to lock us up, they will do.