Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
HOWTO: LUKS hidden key in MBR. Genkernel.
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks
View previous topic :: View next topic  
Author Message
argideli
n00b
n00b


Joined: 04 May 2015
Posts: 7
Location: Orestiada,Greece

PostPosted: Wed Jun 10, 2015 11:56 am    Post subject: HOWTO: LUKS hidden key in MBR. Genkernel. Reply with quote

Preface
When you are using LUKS encrypted volumes you can use key files to unlock them. Those files can be be saved in a flash drive, but I did not liked the idea of having a key file just sitting there waiting to be erased by mistake, or being read by others. There is a way of hiding your key files inside the empty space that exists between your MBR and your partitions of the flash drive. When you create a DOS partition on your flash drive you will see that the first sector always starts at 2048 this means that a number of KBs are held on reserve for the MBR, the partition entries and boot loaders. How much of that free space you have available depends on your layout and it is there where we will be storing the encryption keys. The flash drive will then used to provide passwordless unlocking of the LUKS volumes at boot time. This is useful if you are using an encrypted root partition and swap partition without a random key (something that disables hibernation). Just plug the flash drive and it opens them automatically.

Dissecting The Flash Drive
IMPORTANT: PLEASE Do not just copy and paste, we will use dd and it can destroy your partition table if not applied correctly. Also the data on your flash drive WILL BE ERASED irrecoverably. Also DO NOT use it if you do not know what you are doing you WILL NOT be able to boot after following the guide with errors.

With the above said lets start. First of all we are going to wipe the flash drive with zeros so we can have an understanding of the free space. You can either wipe it entirely or just some of the first MBs that are of interest. Lets see the device that our flash drive is set by the kernel:
Code:
Spileo-Desktop luks-test #fdisk -l

Disk /dev/sdd: 977.6 MiB, 1025024000 bytes, 2002000 sectors

As you can see my flash drive is listed as /dev/sdd.
Next fill it up with zeroes (note that I am erasing just the first 4 MBs you can remove the count to erase it entirely and ajust the bs but it may take a long time to complete.):
Code:
Spileo-Desktop luks-test #dd if=/dev/zero of=/dev/sdd bs=1 count=4096000

Lets see the result of the above operation by extracting the first 2MBs in a file (named bitextract) and reading the hex file:
Code:
Spileo-Desktop luks-test #dd if=/dev/sdd of=bitextract bs=1 count=2048000
Spileo-Desktop luks-test #hexdump  -C bitextract
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
001f4000

As you can see everything is zero. The partition table has been erased and the partitions does not exist anymore. So we will create the partition table without a partition to see how much space it is going to occupy in the MBR. There are lots of tools that can do that from cfdisk to gparted, I use cfdisk:
Code:
Spileo-Desktop luks-test # cfdisk /dev/sdd

Lets see the changes:
Code:
Spileo-Desktop luks-test # dd if=/dev/sdd of=bitextract bs=1 count=2048000
Spileo-Desktop luks-test # hexdump  -C bitextract
00000000  fa b8 00 10 8e d0 bc 00  b0 b8 00 00 8e d8 8e c0  |................|
00000010  fb be 00 7c bf 00 06 b9  00 02 f3 a4 ea 21 06 00  |...|.........!..|
00000020  00 be be 07 38 04 75 0b  83 c6 10 81 fe fe 07 75  |....8.u........u|
00000030  f3 eb 16 b4 02 b0 01 bb  00 7c b2 80 8a 74 01 8b  |.........|...t..|
00000040  4c 02 cd 13 ea 00 7c 00  00 eb fe 00 00 00 00 00  |L.....|.........|
00000050  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001b0  00 00 00 00 00 00 00 00  d5 e4 50 03 00 00 00 00  |..........P.....|
000001c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
001f4000

Now it is clear that the MBR occupies the first 512 Bytes of the flash disk from 00000000 to 00000200 the rest remain zeros. Next, create a usable partition and format it (fat32 for this howto):
Code:
cfdisk /dev/sdd

after you create the partition format it

mkfs.vfat -n "Thumb Drive" /dev/sdd1

That gives us:
Code:
Spileo-Desktop luks-test # dd if=/dev/sdd of=bitextract bs=1 count=2048000
Spileo-Desktop luks-test # hexdump  -C bitextract
00000000  fa b8 00 10 8e d0 bc 00  b0 b8 00 00 8e d8 8e c0  |................|
...........................
...........................
...........................
000001f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 55 aa  |..............U.|
00000200  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000  eb 58 90 6d 6b 66 73 2e  66 61 74 00 02 08 20 00  |.X.mkfs.fat... .|
...........................
...........................
...........................
001f4000

Meaning that the partition we created start at 00100000 (1048576 bytes) so the space before that until 00000200 is still zeros. This is the dead space that we will use for storing the keys as long as the partition table remains unaltered the keys shall be intact.
Before we continue to make the keys and insert them I want to cover another possibility.Some people may want to use the flash drive as a boot device and install grub on it this will change the free space available:
Code:
Spileo-Desktop luks-test # grub2-install /dev/sdd
Spileo-Desktop luks-test # dd if=/dev/sdd of=bitextract bs=1 count=2048000
Spileo-Desktop luks-test # hexdump  -C bitextract | less
...........................
...........................
...........................
0000c200  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000  eb 58 90 6d 6b 66 73 2e  66 61 74 00 02 08 20 00  |.X.mkfs.fat... .|
00100010  02 00 00 00 00 f8 00 00  3e 00 20 00 00 08 00 00  |........>. .....|
...........................
...........................
...........................

So the free space with grub installed is from 0000c200 to 00100000, about 1 MB.

Creating the Keys
To create the key files we can use the /dev/random or /dev/urandom. The first is too slow but it provides output when the entropy pool is sufficient thus better keys. The next segment will create a file with random data from which we will extract our keys and randomize the zeros that exist in the free space. Note that if you use /dev/random it will take a loooonnngggg time.
Code:
Spileo-Desktop luks-test # dd if=/dev/random of=random.bits bs=1 count=2048000

Extract the keys from the random data,our key size will be 512 bytes and we will create two keys one named root.key and the other swap.key:
Code:
Spileo-Desktop luks-test # dd if=random.bits of=root.key bs=1 count=512
Spileo-Desktop luks-test # dd if=random.bits of=random.bits.new bs=1 skip=512
Spileo-Desktop luks-test # rm random.bits
Spileo-Desktop luks-test # mv random.bits.new random.bits

Spileo-Desktop luks-test # dd if=random.bits of=swap.key bs=1 count=512
Spileo-Desktop luks-test # dd if=random.bits of=random.bits.new bs=1 skip=512
Spileo-Desktop luks-test # rm random.bits
Spileo-Desktop luks-test # mv random.bits.new random.bits

Now that our keys have been generated and are not a subset of our random data we can embed the random data in the free space to make it harder to detect the keys. The space in question is 00100000 - 0000c200 = 1048576 - 49664 = 998.912 bytes. In dd using the seek=x lets us skip the number of bytes we want from the beginning of the target device, I left 4 bytes on zero on purpose (2 at the start and two at the end of the free space) just to be sure the would not be any overwriting:
Code:
Spileo-Desktop luks-test # dd if=random.bits of=/dev/sdd bs=1 seek=49668 count=998910

Embedding the keys is done by the same procedure,I left intentionally some random data between the keys so that they would not be side by side. The root.key will be placed 1024 bytes after the start of the free space and the swap.key 128 bytes after the root.key (root key=49668+1024=50692 , swap key=50692+512+128=51332):
Code:
Spileo-Desktop luks-test # dd if=root.key of=/dev/sdd bs=1 seek=50692 count=512
Spileo-Desktop luks-test # dd if=swap.key of=/dev/sdd bs=1 seek=51332 count=512

Verify the presence of the keys,if they are the same cmp will have no output:
Code:
Spileo-Desktop luks-test # dd if=/dev/sdd of=root.key.extract bs=1 skip=50692 count=512
Spileo-Desktop luks-test # cmp -l root.key root.key.extrac

Spileo-Desktop luks-test # dd if=/dev/sdd of=swap.key.extract bs=1 skip=51332 count=512
Spileo-Desktop luks-test # cmp -l swap.key swap.key.extract

Lastly add them to your LUKS volumes:
Code:
Spileo-Desktop luks-test # cryptsetup luksAddKey /dev/volgroup/Root root.key
Spileo-Desktop luks-test # cryptsetup luksAddKey /dev/volgroup/Swap swap.key


Using the Key Drive
Before Gentoo I used Arch Linux, their initramfs had the ability to extract a key like those above from a block device. I wanted to have that in Gentoo so I modified genkernel's initscripts to do it. I have been using it and testing it for a a month now with no problems.

Patch:
Code:
Spileo-Desktop luks-test # mkdir -p /etc/portage/patches/sys-kernel/genkernel
Spileo-Desktop luks-test # wget https://www.dropbox.com/s/b39dqbakv5ehob0/initrd.scripts-luks.patch -O /etc/portage/patches/sys-kernel/genkernel/initrd.scripts-luks.patch
Spileo-Desktop luks-test # emerge --ask genkernel


OR manual edit:
edit /usr/share/genkernel/defaults/initrd.scripts
removing the functions openLUKS() and startLUKS() (only those two!) replacing them with the following: http://pastebin.com/TtWEUTeP


Now that this is done we need to edit the grub command line so it includes our crypt devices and key devices. The arguments work like that:
crypt_dev=LUKS_Device:LUKS_Map:cryptsetup_arguments
LUKS_Device can be, a kernel device (/dev/sda2 or lvm etc.), a UUID, or a LABEL
LUKS_Map is the desired mapping for the device when it is unlocked
cryptsetup_arguments are used when unlocking the device so far I have only used --allow-discards for TRIM support
Caution: DO NOT use UUID for an LVM device that you will create snapshots, the snapshot will have the same UUID and you will end up loading the snapshot instead of the real device

crypt_key=LUKS_Map:Key_Device:Key_Type:Key_Location
LUKS_Map is the mapping of the LUKS device that the key will unlock
Key_Device is the device containing the key (kernel device, UUID or LABEL)
Key_Type is the type of the key, PASS to not use a key but password, BLK to extract from a block device, FILE for file
Key_Location can be empty when using PASS, startByte-KeySize (50692-512) when using BLK, absolute path when using FILE (/luks/root.key)

Example 1:
Code:
crypt_dev=/dev/volgroup-ssd/Root:Root crypt_key=Root:UUID=ba8a09e2-68d9-4a8c-b00c-d800b62ba6a3:BLK:50692-512

Example 2:
Code:
crypt_dev=UUID=ba8a09e2-68d9-4a8c-b00c-4a8cv62ba6a3:Root crypt_key=Root:LABEL='Thumb Drive':FILE:/luks/root.key

You can have as many device-key pairs you want as long you set them correctly they will get opened. If the device is not present the boot process will wait for 10s for it to get connected, otherwise it will ask for password.

Last thing to do is generate the initramfs and update grub (note that I am using LVM and excluding zfs for my system):
Code:
Spileo-Desktop luks-test # genkernel --no-zfs --lvm  --luks --disklabel  --install initramfs
Spileo-Desktop luks-test # grub2-mkconfig -o /boot/grub/grub.cfg


All done now you can use your digital key! But you must be carefull when you update the genkernel package the edited sections may be changed if you chose to do it manually, so you will have to edit them once again.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Documentation, Tips & Tricks All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum