You are not logged in.

#1 2015-05-01 00:24:50

dude42
Member
Registered: 2014-11-09
Posts: 12

Decrypt multiple dm-crypt LUKS drives with a single password on start

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 smile

Credit goes to the following:

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

#2 2015-05-31 10:30:12

frostschutz
Member
Registered: 2013-11-15
Posts: 803

Re: Decrypt multiple dm-crypt LUKS drives with a single password on start

--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)

Offline

#3 2015-06-06 04:11:10

dude42
Member
Registered: 2014-11-09
Posts: 12

Re: Decrypt multiple dm-crypt LUKS drives with a single password on start

frostschutz wrote:

--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

#4 2016-03-08 07:01:51

redeemed2011
Member
Registered: 2015-08-22
Posts: 1

Re: Decrypt multiple dm-crypt LUKS drives with a single password on start

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

#5 2016-03-12 06:31:04

dude42
Member
Registered: 2014-11-09
Posts: 12

Re: Decrypt multiple dm-crypt LUKS drives with a single password on start

Glad you found it useful smile

Offline

#6 2019-07-14 12:12:51

atom63
Member
Registered: 2019-07-14
Posts: 1

Re: Decrypt multiple dm-crypt LUKS drives with a single password on start

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

#7 2019-07-14 13:48:28

frostschutz
Member
Registered: 2013-11-15
Posts: 803

Re: Decrypt multiple dm-crypt LUKS drives with a single password on start

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...

Offline

Board footer

Powered by FluxBB