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 /dev/random
.
I’m sorry, but your statement Important note: a LUKS header backup can grant access to most or all data doesn’t make any sense to me.
The header is just a backup of a certain number of bytes at the beginning of the partition/device. If your statement were true, everyone who had access to the physical encrypted disk would be able to access the data thus rendering encryption useless.
Can you please clarify your statement?
Good question. If you have a LUKS header backup or a full backup, then you can grant access to most or all data by brute-forcing the passphrase. It’s just a matter of time NSA cracks your passphrase. It might be hours, it might be years. The amount of time is not important in this case. It’s all about the theoretical possibility. Whether it’s worth spending money and resources on this or not is completely out of the picture.
The point is to ensure nobody has access to a LUKS header backup. If you have no LUKS header backup and the LUKS header on a disk is damaged, nothing can be done to get access to encrypted data. Data is permanently lost.
If you are talking about theoretical possibilities, then it doesn’t matter whether you have the header or not. You could theoretically still brute-force decryption of your data w/o the header.
It would certainly take a lot more time (really huge numbers here) then just brute-forcing the passphrase, but it is still possible – in theory that is.
In cryptoanalysis the terms practicality and complexity of attacks are used. Even with the header the attack would be impractical, although there are people who state that even computationally impractical attacks can be considered breaks…
Interesting, I was under impression that a LUKS header contains a 256 bit salt per key-slot and without that no decryption is possible. Thus erasing the LUKS header would make access to encrypted data infeasible. I am by no means a cryptography expert, so my understanding in this particular case may be slightly wrong. Thanks for your valuable input Tessarek.
You are right, attacking it without the header would be immensly time consuming. I’m talking about a order of magnitude of several billion years, but it is *theoretical* possible.
But since you stated in your first reply that you mentiond it because cracking it with the header is a theoretical possibility, I just wanted to explain that it would also be possible without the header.
Practically both attack vectors are not feasible unless you don’t use a passphrase, but cryptology never has and never will make good for the stupidity of the user.
I was looking from a little bit more practical perspective when talked about theoretical possibilities. If your LUKS encryption passphrase is say “123456789” (Adobe password leak, huh?), then having a LUKS header makes it fairly easy to brute-force the whole thing and you data is accessed in pretty much no time.
On the other hand, if the LUKS header is damaged and no header backup is available, it makes (as you mentioned) the whole decryption process immensely time consuming having no salt values.
I think you get my point now. And again, thanks for your input. Much appreciated.
Very usefull guide. Thank you very much.
Thank you OP
Thank you. It took me a long time to find this. Then had to read through the arguments instead of just a clean how to.
The arguments are certainly valid but I think it just muddies the water here.
This is a good tutorial but can’t we just stick to the process instead of the argument of what if?
We just want to get to the meat of locking out the attacker who is just t a thief etc. My larger danger here is theft by a Crack head. I’m not worried about NSA except for the fact I think they are out of control and need to be reigned in along with the other crooked Three letter agencies run by our now criminal element.
Using this information I now have a script that runs if I just close the lid on my laptop, which will wipe my header with “/dev/urandom.” NOTE: Please do not scream at me about what if I or someone near me just decide to shut the lid. I’m painfully aware of the possibilities. So you can breath easy I keep a monthly image of my laptop drive using DD on another portable disk. The last back up ended today after twenty two hours of running. It’s a pain in the butt but I can rebuild my system to only one month old at the worst case. I also keep hourly, daily, weekly and monthly RSYNC backups of everything important. Yes crontab.
What I need now is a way to have it auto destruct if the luks password is entered wrong in X number of times. Also would be nice to have a way to enter a fake?? password that would run the wipe keys script. Any good ideas on that? Barring a fake password a timer would be good. Either get the password right within X or runs wipe script automatically.
Thanks again,
A pissed off Veteran
Read “Why is there no “Nuke-Option”?” section:
https://gitlab.com/cryptsetup/cryptsetup/wikis/FrequentlyAskedQuestions
Hope this helps.
Thank you for the guide.
After erasing the header as indicated with your sample command:
# head -c 3145728 /dev/zero > /dev/sdb2; sync
is it possible to restore the backup header and continue to access the data?
It is possible to restore the header if you backed it up before erasing, that’s what I always do when creating new LUKS volumes – dump LUKS volume header, erase it and attempt to restore from the backup file. If it works, then I know that I have a valid header backup and can start putting files into the new volume.
I very much appreciate this blog post – a true service to those of us learning how these things work! Thank you no end. – M
You’re welcome.
Thanks
Hi,
“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:”.
I don’t get the 3 MiB. You erase just the first part of the disk entirely right? So when only one key is used 1 MiB, and you remove three. Doesn’t that corrupt your data at least for 2 MiB? Because you erased more than just the key.
Also, the calculation is clear but I wouldn’t know where to get this input. Shouldn’t it be exact and is there a command to determine or static value that is an exact number, that can be used to eras the key or keys and those keys only, nothing more?
You have a header, 8 key slots, and then encrypted data.
This might help to get a better understanding:
https://security.stackexchange.com/questions/227359/how-to-determine-start-and-end-bytes-of-luks-header
So, the total header (including the key slots) are a static length? Even if not more than one slot is used? So it would be safe to remove the first 3MiB as you suggested and try to restore it with the backed-up key?
In addition to above, for example determine the size to erase based on the backed up headers file? Also, if the header-backup-file would be backed up to an unencrypted disk (which I would discourage, but for example before transferring it away) then you should definitely delete it in a secure way after for example using: shred -zvu -n 5 mybackupfile
Hi, thanks for the guide!
I was giving it a try in a test partition and after completing the last part and restoring the header, it resulted in a bad superblock issue.
# mount /dev/mapper/data1 /data
mount: /data: wrong fs type, bad option, bad superblock on /dev/mapper/data1, missing codepage or helper program, or other error.
So I tried to recover following this https://www.cyberciti.biz/tips/surviving-a-linux-filesystem-failures.html
# e2fsck -f -b 32768 /dev/sda10
e2fsck 1.44.5 (15-Dec-2018)
e2fsck: Bad magic number in super-block while trying to open /dev/sda10
The superblock could not be read or does not describe a valid ext2/ext3/ext4
filesystem. If the device is valid and it really contains an ext2/ext3/ext4
filesystem (and not swap or ufs or something else), then the superblock
is corrupt, and you might try running e2fsck with an alternate superblock:
e2fsck -b 8193
or
e2fsck -b 32768
# dumpe2fs /dev/sda10 | grep superblock
dumpe2fs 1.44.5 (15-Dec-2018)
dumpe2fs: Bad magic number in super-block while trying to open /dev/sda10
Couldn’t find valid filesystem superblock.
# mke2fs -n /dev/sda10
mke2fs 1.44.5 (15-Dec-2018)
/dev/sda10 contains a crypto_LUKS file system
Proceed anyway? (y,N) y
Creating filesystem with 58509312 4k blocks and 14630912 inodes
Filesystem UUID: 71fcecd2-6d83-4b5b-8cfc-dd5241c7a561
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208,
4096000, 7962624, 11239424, 20480000, 23887872
Can you give me some hint in how to solve this?
I appreciate, rgds
Hi,
with only a header-backup-file (any password or key file) and encrypted partition is possible to recover the password?
Hi, if you have the header backup file and the encrypted partition, you can recover data provided that you know the password. If you don’t know the password then you cannot recover data.