Weblog entry #71 for dkg

resetting passphrases for mapped LUKS volumes
Posted by dkg on Sun 16 Jan 2011 at 19:57
Let's say you set up a machine using an encrypted disk with LUKS (debian-installer's partman makes this wonderfully easy!). You choose an initial passphrase, get the machine working, and it's working great. Then, you need to restart it, and realize that (for whatever reason) you've forgotten or lost the passphrase for the volume. oops! (i'm sure this has never happened to you -- let's just pretend it's your less-fortunate friend).

If your system is still running, and you have superuser access to it, you can actually set a new passphrase for the LUKS volume using information that the dm-crypt kernel module has about the in-use mapping. In my examples, i'll imagine that the source volume is /dev/XXX2 and the exported cleartext volume is known by the device-mapper as XXX2_crypt

In the bigger picture, this should serve as a reminder that even though your disk is encrypted, if someone gets live access to the superuser account on a system with the encryption keys loaded, your data is no longer secret.

Before you do any tweaking, you might want to back up your LUKS header, just in case:

0 root@example:~# umask 077
0 root@example:~# cryptsetup luksHeaderBackup /dev/XXX2 --header-backup-file XXX2.luksheader.backup
0 root@example:~# 
Maybe also copy that off the machine, since a copy of the LUKS header stored within its own volume isn't terribly useful for a backup-recovery situation.

You might also be interested in looking at the contents of the LUKS header:

0 root@example:~# cryptsetup luksDump /dev/XXX2
LUKS header information for /dev/XXX2

Version:       	1
Cipher name:   	aes
Cipher mode:   	cbc-essiv:sha256
Hash spec:     	sha1
Payload offset:	2056
MK bits:       	256
MK digest:      93 51 6c 66 ec ce 32 54 6f 6b 52 d1 27 9b 5a 62 6f 6b 52 d1
MK salt:       	b2 ca 20 49 9f 78 49 c2 fe 15 b4 0f 74 11 23 49
               	64 9e 61 bb f2 82 60 47 a5 76 fa a4 24 0e 5a 7e
MK iterations: 	10
UUID:          	052f1da0-21a1-11e0-ac64-0800200c9a66

Key Slot 0: ENABLED
	Iterations:         	218733
	Salt:               	f2 ae 8c 53 48 a5 f0 bf e1 2c 06 5f 5a bd ff d9
	                      	9a 2e d1 49 3a 63 f8 49 82 ed ae 86 7b 7b 7e 76 
	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
0 root@example:~# 
Now, the fix: We pull the live "master key" from the running device map, and fill a new luksKeySlot from it (this example uses bash's <() syntax for process substitution -- if you use a different shell, i'm sure you can find a different way to do it):
0 root@example:~# cryptsetup --master-key-file <( 
> dmsetup --showkeys table | awk '/^XXX2_crypt: /{ print $6 }' | tr -d '\n' | perl -e 'print pack("H*", <STDIN>);' 
> ) luksAddKey /dev/XXX2
Enter new passphrase for key slot: abc123
Verify passphrase: abc123
2 root@example:~# 
(note that the luksAddKey invocation above returned an error code of 2 even though it succeeded. I think this is a bug in cryptsetup's return code, not a bug in the password resetting -- it should have returned 0 instead of 2).

You can check to see that a new key slot was enabled by re-running cryptsetup luksDump

And if you really want to double-check before you reboot, you can try enabling a third keyslot using the passphrase you just added, since this would not succeed if your new passphrase failed to unlock any of the existing keyslots:

0 root@example:~# cryptsetup luksAddKey /dev/XXX2
Enter any passphrase: abc123
Enter new passphrase for key slot: anotherpassphrase
Verify passphrase: anotherpassphrase
0 root@example:~# 
You can also get rid of the original keyslot (which you don't know the passphrase to) like this:
0 root@example:~# cryptsetup luksKillSlot /dev/XXX2 0
Enter any remaining LUKS passphrase: abc123
0 root@example:~# 
(the above commands were all demonstrated using debian testing, with cryptsetup 2:1.1.3-4 and dmsetup 2:1.02.48-4)


Comments on this Entry

Posted by Fnord23 (2001:0xx:0xx:0xxx:0xxx:0xxx:xx) on Mon 17 Jan 2011 at 09:17
"You can check to see that a new key slot was enabled by re-running cryptsetup luksKeyDump"

I guess 'luksKeyDump' should be 'luksDump'?

[ Parent | Reply to this comment ]

Posted by dkg (67.100.xx.xx) on Mon 17 Jan 2011 at 15:42
[ View dkg's Scratchpad | View Weblogs ]
whoops, yes you're right. i've updated the weblog entry with your correction.

thanks for catching my mistake!

[ Parent | Reply to this comment ]

Posted by Anonymous (195.39.xx.xx) on Sat 26 Feb 2011 at 00:05
if you'd like to change a luks key (without a passphraze..), what would the difference be in the above ?

[ Parent | Reply to this comment ]

Posted by dkg (67.101.xx.xx) on Sun 27 Feb 2011 at 15:21
[ View dkg's Scratchpad | View Weblogs ]
I'm not sure what you're asking, actually. Are you asking about changing the volume master key? I don't think that's doable without re-initializing the entire volume and re-writing the data. Or are you asking about something else?

It occurs to me that you could probably actually reset the master key in place by doing something suitably bizarre and/or dangerous like double-mapping the volume and dd'ing from old to new, but i wouldn't want to encourage that kind of behavior.

[ Parent | Reply to this comment ]

Posted by Anonymous (195.69.xx.xx) on Sat 19 Nov 2011 at 09:43
How to do it on older versions cryptosetup 1.0.6 and 1.0.3 ?
They don't have option --master-key-file

[ Parent | Reply to this comment ]

Posted by dkg (2001:0xx:0xx:0xxx:0xxx:0xxx:xx) on Mon 21 Nov 2011 at 04:27
[ View dkg's Scratchpad | View Weblogs ]
hmm, i don't really know how you would do that, actually. I think you need the newer tools.

cryptsetup 1.1.3 is available in debian squeeze, though, which is stable. Obviously, if you're in this situation, you don't want to upgrade and reboot -- but maybe you could make a more modern chroot, bind-mount /dev into it, and use the newer versions of the tool? This is risky business. It might be wiser to just back everything up and rebuild from backups.

no matter what you do, please make sure you have backups!

[ Parent | Reply to this comment ]

Posted by Anonymous (212.110.xx.xx) on Wed 13 Aug 2014 at 09:20
waht if we have all key slot disabled ?

[ Parent | Reply to this comment ]

Posted by dkg (212.110.xx.xx) on Wed 13 Aug 2014 at 16:18
[ View dkg's Scratchpad | View Weblogs ]
The same approach should still work, as long as the volume is currently mapped (so that the master key is accessible from the kernel). The keyslots are only the places to store passphrases. "DISABLED" means that they aren't storing any passphrases at the moment. By adding a new passphrase, you're making use of one of the disabled keyslots.

[ Parent | Reply to this comment ]