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