You are not logged in.
Hi there,
This is a hook based on the encrypt hook that I use to decrypt multiple dm-crypt LUKS drives on startup for a btrfs raid 1. I thought someone might find it useful. I'd be willing to do some work to include this in the official mkinitcpio package if the developers are happy with it ? Constructive suggestions are welcome
Credit goes to the following:
The author(s) of the mkinitcpio hooks on which this hook is based
Edit: Thanks to frostschutz for pointing out that --keyfile-size and --keyfile-offset use bytes instead of bits. Therefore to use 4096 bit keys, 512 bytes should be specified. I have corrected the examples.
The idea is to have a dm-crypt LUKS password encrypted file /boot/multikeyfile. This file contains multiple 4096 bit keys to be used to decrypt the actual drives.
I created the file and encrypted volumes as follows:
$ dd if=/dev/zero of=multikeyfile bs=3M count=1 # I chose 3M because the LUKS header is around 2M
$ cryptsetup -v --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random luksFormat multikeyfile
# install -m644 -o root -g root multikeyfile /boot
# cryptsetup open --type luks /boot/multikeyfile multikeyfile
# dd if=/dev/zero of=/dev/mapper/multikeyfile
# I wanted keys for two drives (2 * 4096 / 8) = 1024 bytes
# dd iflag=fullblock if=/dev/random of=/dev/mapper/multikeyfile bs=1024 count=1
# Verify enough random content
# hexdump -C /dev/mapper/multikeyfile | less
# Create the containers
# cryptsetup --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random --key-file /dev/mapper/multikeyfile --keyfile-offset 0 --keyfile-size 512 luksFormat /dev/sdXY
# cryptsetup --cipher aes-xts-plain64 --key-size 512 --hash sha512 --iter-time 5000 --use-random --key-file /dev/mapper/multikeyfile --keyfile-offset 512 --keyfile-size 512 luksFormat /dev/sdAB
Next add a kernel parameter to identify the drives in the same sequence as their keys appear in the multikeyfile. I used PARTUUID:
multidecrypt=PARTUUID=<drive1>:PARTUUID=<drive2>
In /etc/mkinitcpio.conf add the multidecrypt hook in the HOOKS field in the same place you would normally place the encrypt hook.
Run mkinitcpio as you normally do to recreate your initramfs.
Here are the actual hook files:
/etc/initcpio/hooks/multidecrypt
#!/usr/bin/ash
run_hook() {
modprobe -a -q dm-crypt >/dev/null 2>&1
modprobe -a -q loop >/dev/null 2>&1
[ "${quiet}" = "y" ] && CSQUIET=">/dev/null"
if [ -z "${multidecrypt}" ]; then
err "No dm-crypt luks devices specified for multidecrypt, aborting..."
exit 1
fi
echo ""
echo "YOU SHALL NOT PASS !!!!!!!"
#loop until we get a real password
while ! eval cryptsetup open --type luks /multikeyfile multikeyfile ${CSQUIET}; do
sleep 2;
done
if [ ! -e "/dev/mapper/multikeyfile" ]; then
err "multikeyfile decryption failed, aborting..."
exit 1
fi
luksdevnum=1
for luksdev in ${multidecrypt//:/ }; do
if resolved=$(resolve_device "${luksdev}" ${rootdelay}); then
eval cryptsetup open --type luks --key-file /dev/mapper/multikeyfile --keyfile-offset $((($luksdevnum-1)*512)) --keyfile-size 512 ${resolved} container${luksdevnum} ${CSQUIET}
if [ ! -e "/dev/mapper/container${luksdevnum}" ]; then
err "container${luksdevnum} creation failed, continuing with other specified devices..."
fi
else
err "Could not resolve ${luksdev}, continuing with other specified devices..."
fi
let luksdevnum++
done
#clean up
cryptsetup close multikeyfile
}
# vim: set ft=sh ts=4 sw=4 et:
/etc/initcpio/install/multidecrypt
#!/bin/bash
build() {
local mod
add_module dm-crypt
if [[ $CRYPTO_MODULES ]]; then
for mod in $CRYPTO_MODULES; do
add_module "$mod"
done
else
add_all_modules '/crypto/'
fi
# add loop module for mounting of keyfile
add_module loop
add_binary "cryptsetup"
add_binary "dmsetup"
add_file "/usr/lib/udev/rules.d/10-dm.rules"
add_file "/usr/lib/udev/rules.d/13-dm-disk.rules"
add_file "/usr/lib/udev/rules.d/95-dm-notify.rules"
add_file "/usr/lib/initcpio/udev/11-dm-initramfs.rules" "/usr/lib/udev/rules.d/11-dm-initramfs.rules"
add_file "/boot/multikeyfile" "/multikeyfile"
add_runscript
}
help() {
cat <<HELPEOF
This hook allows for startup decryption of multiple dm-crypt luks encrypted
devices. Users should specify the devices to be unlocked using:
'multidecrypt=device[[:device]...]'
on the kernel command line, where 'device' is the path to the raw device,
specified using PARTUUID or some other means. Devices will be available as
/dev/mapper/container[1,2,3...] etc.
The hook expects a dm-crypt luks encrypted file called /boot/multikeyfile to
exist. This keyfile contains a concatenation of 4096 bit keys for each
encrypted device in the same order as specified in the multidecrypt kernel
command line argument.
If decryption of one of the devices fails, the hook will attempt to continue
to decrypt any other specified devices. This is useful for btrfs software
raid if a device has failed as an example.
You will be prompted for the password to the multikeyfile container at runtime.
This means you must have a keyboard available to input it, and you may need the
keymap hook as well to ensure that the keyboard is using the layout you expect.
HELPEOF
}
# vim: set ft=sh ts=4 sw=4 et:
Last edited by dude42 (2015-06-06 04:08:06)
Offline
--keyfile-size is not bits but bytes.
If you really set up your encryption the way you described, the key for your first container will be 1024 random bytes followed by zero bytes, and the key of your second container will be 4096 bytes of /dev/zero.
Last edited by frostschutz (2015-05-31 10:30:21)
Online
--keyfile-size is not bits but bytes.
If you really set up your encryption the way you described, the key for your first container will be 1024 random bytes followed by zero bytes, and the key of your second container will be 4096 bytes of /dev/zero.
Thanks frostschutz !
Offline
This appears to be gold.
No scripts that may store the decryption password in swap.
If I am necro-posting, please forgive me. I spent many days trying to determine how to do this. Surely someone else wants to decrypt multiple devices for / on boot for file systems like btrfs.
Offline
Glad you found it useful
Offline
hello, great tools. But i do smth wrong.
How to open cryptdevices after they were created? I tried as usually cryptsetup open /dev/*** device_name but it said wrong pass.
P.s. i try to install arch on two physical volumes via lvm over luks with encrypted root partition. Thanx
root@archiso ~ # cryptsetup open /dev/nvme0n1p7 cryptlvm --key-file /dev/mapper/multikeyfile
No key available with this passphrase.
cryptsetup open /dev/nvme0n1p7 cryptlvm --key-file /dev/mapper/multikeyfile 18.29s user 0.28s system 371% cpu 5.001 total
root@archiso ~ # cryptsetup --key-file /dev/mapper/multikeyfile luksOpen /dev/nvme0n1p7 cryptlvm
No key available with this passphrase.
cryptsetup --key-file /dev/mapper/multikeyfile luksOpen /dev/nvme0n1p7 18.29s user 0.28s system 371% cpu 5.003 total
Last edited by atom63 (2019-07-14 12:27:54)
Offline
you can only use keys you previously added... so did you add any? if so how did you add them...?
the example in this thread has multiple keyfiles rolled in one, so --keyfile-offset and --keyfile-size also have to be used (key added and opened this way), different offset for each container
or you could use the same keyfile for all, that's a matter of choice
for only two LUKS containers this solution might be overkill anyhow. systemd already has a builtin feature to re-use same key (but no idea if employed in systemd sd-encrypt hook) so setting all luks containers to same passphrase works (easy peasy).
or you can just copy the encrypt hook to have a encrypt2 hook as described in the wiki...
Online