Re: Opening a LUKS container using a USB drive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Ok, I've managed to solved this issue. The problem was in the decription script, so instead of the 
following: 

    dd if=/dev/usbkey bs=512 skip=100 count=8 | \
    cryptsetup luksOpen /dev/mmcblk0p2 rpi_crypt --key-file=-

it should be just:

    dd if=/dev/usbkey bs=512 skip=100 count=8

Since the output of the script itself is passed to cryptsetup, the piped cryptsetup command isn't 
needed anymore.

Also the initramfs hook is useless, as the keyscript will be copied if it's present in the same 
location pointed by the option. So for instance keyscript=/usr/sbin/unlock-rpi requires the script 
to be under /usr/sbin/unlock-rpi in the encrypted system, and it will be copied automatically to 
initramfs/initrd image.


On 10/11/2021 12.08, Mikhail Morfikov wrote:
> I've been trying to set up an encrypted LUKS container, which could be opened only when a specific 
> USB device was plugged into the USB port. I partially achieved what I wanted, but there's one thing 
> I couldn't figure out.
> 
> When I boot the system, it waits till I plug the right USB device in. When I do so, then it 
> processes the device and decrypts the root files system, and the system boots as usual.
> 
> It starts with:
> 
> 	Begin: Running /scripts/local-top...
> 	Waiting for device...
> 
> After plugging the USB device, I can see the following messages:
> 
> 	sd 0:0:0:0 [sda] No Caching mode page found
> 	sd 0:0:0:0 [sda] Assuming drive cache: write through
> 	8+0 records in
> 	8+0 records out
> 
> It hangs here for a while because it tries to open the LUKS container which is an SD card, and it 
> succeeds. 
> 
> Then I can see the following errors:
> 
> 	Nothing to read on input
> 	cryptsetup: ERROR rpi_crypt: cryptsetup failed, bad password or options?
> 	8+0 records in
> 	8+0 records out
> 	Device rpi_crypt already exists
> 	Nothing to read on input
> 	....
> 	cryptsetup: ERROR rpi_crypt: maximum number of tries exceeded
> 	done
> 	Begin: Running /scripts/local-premount ... done
> 	...
> 	
> After the last cryptsetup error, the system continues to boot without any issue and it works well. 
> So what's wrong with it?
> 
> 
> 
> Here's the full setup.
> 
> I created the LUKSv2 container in the following way:
> 
> 	# cryptsetup luksFormat /dev/mmcblk0p2 \
> 	  --type luks2 \
> 	  --cipher aes-xts-plain64 \
> 	  --key-size 512 \
> 	  --hash sha512 \
> 	  --pbkdf argon2i \
> 	  --pbkdf-force-iterations 4 \
> 	  --pbkdf-memory 524288 \
> 	  --pbkdf-parallel 2 \
> 	  --label rpi \
> 	  --subsystem "" \
> 	  --use-random \
> 	  --verify-passphrase \
> 	  --verbose
> 	  
> And then I created an EXT4 file system:
> 
> 	# cryptsetup luksOpen /dev/mmcblk0p2 rpi_crypt
> 
> 	# mke2fs \
> 		-t ext4 \
> 		-m 0 \
> 		-L rootfs \
> 		-J size=128 \
> 		-O 64bit,has_journal,extents,huge_file,flex_bg,metadata_csum,dir_nlink,extra_isize,^resize_inode,^uninit_bg \
> 		-E lazy_itable_init=0,lazy_journal_init=0 \
> 		/dev/mapper/rpi_crypt
> 
> The SD card looks like this:
> 
> 	# lsblk -o "NAME,SIZE,FSTYPE,TYPE,LABEL,MOUNTPOINT,UUID,PARTUUID" /dev/mmcblk0
> 	NAME           SIZE FSTYPE      TYPE  LABEL  MOUNTPOINT UUID                                 PARTUUID
> 	mmcblk0       28.8G             disk
> 	├─mmcblk0p1    256M vfat        part  boot              B05C-D0C4                            0d03b705-01
> 	└─mmcblk0p2   28.6G crypto_LUKS part  rpi               0b9b66eb-d5ec-4371-80e3-f3a6ae92e0be 0d03b705-02
> 	  └─rpi_crypt 28.6G ext4        crypt rootfs /media/rpi 0ca2062b-142b-4826-bb74-d465ca89b554
> 
> This is the /etc/fstab entry:
> 
> 	UUID=0ca2062b-142b-4826-bb74-d465ca89b554  /   ext4    defaults,lazytime,errors=remount-ro  0 1
> 
> This is the /etc/crypttab entry:
> 
> 	rpi_crypt  UUID=0b9b66eb-d5ec-4371-80e3-f3a6ae92e0be   none  luks,keyscript=/usr/sbin/unlock-rpi,initramfs,keyslot=1
> 
> In the kernel cmdline I added luks.crypttab=no to disable the systemd cryptsetup generator as it 
> doesn't support many crypttab options.
> 
> The LUKS container can be opened at boot without issues when the luks,initramfs options are 
> specified in /etc/crypttab , but in this way I would have to enter the password manually each time I
> boot the system, and my RPI doesn't have a keyboard connected. Instead I wanted to use a USB 
> drive to open the LUKS container. I mean the device is used in this process and not a keyfile 
> that sits inside of the device's file system. That's why I used keyscript=/usr/sbin/unlock-rpi in 
> /etc/crypttab . Here's the content of the script:
> 
> 	#!/bin/sh
> 
> 	dd if=/dev/usbkey bs=512 skip=100 count=8 | \
> 	 cryptsetup luksOpen /dev/mmcblk0p2 rpi_crypt --key-file=-
> 
> To get the /dev/usbkey device, I have the following UDEV rule:
> 
> 	ACTION=="add", KERNEL=="sd?", \
> 	 ENV{ID_SERIAL_SHORT}=="0019E06B9C8ABE41C7A2C3EC", \
> 	 SYMLINK+="usbkey%n"
> 	 
> So the script reads the 4096 bytes starting at certain point of the pendrive, then it hands the 
> data to cryptsetup and the device can be unlocked.
> 
> Both of the files are included in the initramfs/initrd image.
> 
> The keyfile was added to the LUKS header in the following way:
> 
> 	# dd if=/dev/random of=/tmp-ram/keyfile bs=1 count=4096
> 	# cryptsetup luksAddKey /dev/mmcblk0p2 /tmp-ram/keyfile --hash sha512
> 	# cryptsetup luksDump /dev/mmcblk0p2
> 	LUKS header information
> 	...
> 	  1: luks2
> 		Key:        512 bits
> 		Priority:   normal
> 		Cipher:     aes-xts-plain64
> 		Cipher key: 512 bits
> 		PBKDF:      argon2i
> 		Time cost:  4
> 		Memory:     185496
> 		Threads:    4
> 		Salt:       79 04 9f 36 26 2f da 5d 1c c0 a1 be 8a 73 6f c5 
> 					d8 c7 55 97 a0 cf ee 5c ec ae 20 11 06 d0 27 62 
> 		AF stripes: 4000
> 		AF hash:    sha512
> 		Area offset:290816 [bytes]
> 		Area length:258048 [bytes]
> 		Digest ID:  0
> 	...
> 
> Since the keyfile was added to the keyslot number 1, I used also the keyslot=1 option in 
> /etc/crypttab.
> 
> The keyfile was also burned to the pendrive using the following commands:
> 
> 	# dd if=/dev/urandom of=/dev/sda bs=512 count=2047 seek=1
> 	# dd if=/tmp-ram/keyfile of=/dev/sda bs=512 seek=100
> 
> To make all this work, I had to add two things to the initramfs/initrd image: 1) a hook, 2) a 
> script:
> 
> Here's the /etc/initramfs-tools/hooks/unlock-rpi hook, which copies the keyscript to the image:
> 
> 	#!/bin/sh
> 
> 	set -e
> 
> 	PREREQ=""
> 	prereqs()
> 	{
> 	   echo "$PREREQ"
> 	}
> 
> 	case $1 in
> 	prereqs)
> 	   prereqs
> 	   exit 0
> 	   ;;
> 	esac
> 
> 	[ -r /usr/share/initramfs-tools/hook-functions ] || exit 0
> 	. /usr/share/initramfs-tools/hook-functions
> 
> 	copy_exec /usr/local/bin/unlock-rpi /usr/sbin/
> 	chmod +x  /usr/sbin/unlock-rpi
> 
> And here's the /etc/initramfs-tools/scripts/local-top/delay-decrypt' script, which delays the boot 
> process till the right USB device is plugged in (since I created a link to the block device, I had 
> to check for link and not for the block device):
> 
> 	#!/bin/sh
> 
> 	PREREQ="udev"
> 	prereqs()
> 	{
> 	   echo "$PREREQ"
> 	}
> 
> 	case $1 in
> 	prereqs)
> 	   prereqs
> 	   exit 0
> 	   ;;
> 	esac
> 
> 	# source for log_*_msg() functions, see LP: #272301
> 	. /scripts/functions
> 
> 	# Default PATH differs between shells, and is not automatically exported
> 	# by klibc dash.  Make it consistent.
> 	export PATH=/sbin:/usr/sbin:/bin:/usr/bin
> 
> 	DEVICE=/dev/usbkey
> 	if [ ! -L "$DEVICE" ]; then
> 		echo -e "\nWaiting for device..." >&2
> 		until [ -L "$DEVICE" ]; do
> 			sleep 1
> 		done
> 	fi
> 
> 	exit 0
> 
> So what's wrong with this setup, and why it tries to open the LUKS container multiple times even 
> when it succeeds for the very first time after the USB device was plugged in?
> 
_______________________________________________
dm-crypt mailing list -- dm-crypt@xxxxxxxx
To unsubscribe send an email to dm-crypt-leave@xxxxxxxx




[Index of Archives]     [Device Mapper Devel]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]     [Fedora Docs]

  Powered by Linux