You are not logged in.
I'm trying to implement "two-factor" authentication (possession of a keyfile and knowledge of a passphrase required) using dm-crypt in order to open an encrypted root filesystem. In the past I used gpg and later openssl to decrypt a keyfile using a passphrase, which then was used by cryptsetup using --key-file to decrypt the actual data device. I'd like to ditch gpg/openssl and use only cryptsetup.
So the idea is to create a luksFormatted key file (loop device) which, when opened using a passphrase, will be used as the key (using --key-file) to open a luksFormatted hard drive partition.
To illustrate:
# create and luksFormat the key container file
dd if=/dev/urandom of=key_container bs=1M count=4
cryptsetup luksFormat key_container
# open the container and create a random "key" by directly writing pseudo random data to it
cryptsetup luksOpen key_container key_device
dd if=/dev/urandom of=/dev/mapper/key_device
# luksFormat the data device using the random data from the luks key device
cryptsetup -d /dev/mapper/key luksFormat /dev/sda1
# later, to open /dev/sda1
cryptsetup -d /dev/mapper/key_device luksOpen /dev/sda1 encryptedfs
My questions:
1. Is this a valid approach or am I making a mistake/do you see a problem somewhere?
2. How much data from the loop device will cryptsetup use as key to format/open the data device? Everything? Is there a limit?
3. Is there a difference between doing a
cat /dev/mapper/key | cryptsetup -d -
and
cryptsetup -d /dev/mapper/key?
3. Assuming that the answer to 1 is "no mistake/problem" and 2 is "everything there is" or even "the first x bytes", is it possible that the actual contents of the loop device may change in the future because of different loop device implementations or somethings else I didn't think of? I'd like to avoid bad surprises in the future..
4. What would you recommend as size for the key container file, knowing that the luks header requires some space too?
Any feedback appreciated.
Cheers,
fabriceb
Offline
1. You're missing a few steps, have a read of this article
2. As much as you allocated with
-s <keysize>
3. I'm sure there's a lower level difference but from this perspective not really
3. 2(?) Once the file is created, it's created. Read the article for the best way to store the keyfile sensibly.
4. 4096 bytes is more than plenty.
Useless shit wot I do | "A very witty and relatable quote." -- A wise man
Offline
I do the same ( https://wiki.gentoo.org/wiki/Custom_Ini … ed_Keyfile ).
--key-file=- should be equivalent, but it's meant for grabbing a key from gpg output or whatever; since you can specify it directly here, no need to involve anything else like cat etc.
without --key-file=- it would stop reading at newlines or something. this behaviour is quite dangerous as it may cause people who believe they're using a long random key, to use only a very short (or even empty) key instead. one way to avoid such ambiguousness is to make sure there are no newline bytes in your keyfile, so it would use the whole thing in either interpretation.
as for the key length, a key is essentially a passphrase. So it does not have to be very long at all; 8 truly random bytes would require up to 256^8 tries to break after all and with LUKS, each try takes ~1 second per physical CPU... but the smallest unit that LUKS allows is 512 bytes (1 sector) so you could just as well use the whole thing. If you use 4096 bytes, you're confusing bytes with bits somewhere... and as for bits, even 128bit AES is still considered secure...
You could save some bytes in the initrd.gz if you initialize the container file with zeroes instead of random, so it can be compressed. The key will still be random as the random cipher key will turn the zeroes to something else after all...
Online
Thank you for your input. I noticed something strange. If I luksFormat a file of 4194304 bytes and then luksOpen it, fdisk -l /dev/mapper/mydevice only reports the size of the device as 2097152 bytes which is exactly half of the file. Can it be that the luks header requires 2MB, so the data part "only" gets the other 2MB? Then again, when I do a luksHeaderBackup on the file, I get a header file of size 1048576 bytes. I don't really understand why. Any insights on that?
Last edited by fabriceb (2014-02-06 18:17:33)
Offline
I guess the anwer related to the data offset like described in the luks FAQ:
"
LUKS does place data at an offset, which is 2MiB per default and will not break alignment. See also Item 6.12 of this FAQ for more details. Note that if your partition or filesystem is misaligned, dm-crypt can make the effect worse though.
"
From section 6.12 of the FAQ:
"
Due to 2MiB default alignment, start of the data area for cryptsetup 1.3 and later is at 2MiB, i.e. at 0x200000. For older versions, it is at 0x101000, i.e. at 1'052'672 bytes, i.e. at 1MiB + 4096 bytes from the start of the partition. Incidentally, "luksHeaderBackup" for a LUKS container created with default parameters dumps exactly the first 2MiB (or 1'052'672 bytes for headers created with cryptsetup versions < 1.3) to file and "luksHeaderRestore" restores them.
"
Still that doesn't explain why my luksHeaderBackup file only is 1049600bytes instead of 2M using cryptsetup 1.6.2.
Offline
As the alignment space is empty/unused, it's not included in the header backup.
On luksFormat use --align-payload=1 to make LUKS stop adding MB of alignment. (You should only do this for loop image files, not HDD media which need the data to be aligned)
Last edited by frostschutz (2014-02-06 20:37:24)
Online