#!/bin/sh
-#
# geninitrd mod: cryptsetup luks
USE_LUKS=${USE_LUKS:-yes}
have_luks=no
# device to use for name for cryptsetup luks
-LUKSDEV=""
+LUKSNAME=""
# setup geninitrd module
# @access public
return 1
fi
- if [ ! -e "$node" ]; then
- warn "is_luks(): node $node doesn't exist!"
- return 1
- fi
-
local dev dm_name=${node#/dev/mapper/}
if [ "$node" = "$dm_name" ]; then
- debug "is_luks: $node is not device mapper name"
+ verbose "is_luks: $node is not device mapper name"
return 1
fi
- dev=$(/sbin/cryptsetup status $dm_name 2>/dev/null | awk '/device:/{print $2}')
+ dev=$(awk -vdm_name="$dm_name" '$1 == dm_name { print $2 }' /etc/crypttab)
if [ "$dev" ]; then
+ dev=$(find_devname "$dev")
/sbin/cryptsetup isLuks $dev
rc=$?
else
fi
if [ $rc = 0 ]; then
- debug "is_luks: $node is cryptsetup luks"
+ verbose "is_luks: $node is cryptsetup luks"
else
- debug "is_luks: $node is not cryptsetup luks"
+ verbose "is_luks: $node is not cryptsetup luks"
fi
return $rc
}
# @access public
find_modules_luks() {
local devpath="$1"
- local dev
+ local dev=""
- local name=${devpath#/dev/mapper/}
- LUKSDEV=$(/sbin/cryptsetup status $name 2>/dev/null | awk '/device:/{print $2}')
- if [ -z "$LUKSDEV" ]; then
- die "Lost cryptsetup device meanwhile?"
- fi
+ LUKSNAME=${devpath#/dev/mapper/}
find_module "dm-crypt"
# TODO: autodetect
- find_module "aes"
- find_module "cbc"
-
- have_luks=yes
+ find_module "-aes"
+ find_module "-cbc"
+ find_module "-cbc(aes)"
+ find_module "-xts(aes)"
+ find_module "-af-alg"
+ find_module "-algif_hash"
+ find_module "-algif_skcipher"
+ find_module "-loop"
# recurse
- find_modules_for_devpath $LUKSDEV
+ dev=$(awk -vLUKSNAME="$LUKSNAME" '$1 == LUKSNAME { print $2 }' /etc/crypttab)
+ if [ -n "$dev" ]; then
+ dev=$(find_devname "$dev")
+ find_modules_for_devpath $dev
+ have_luks=yes
+ else
+ die "Cannot find '$LUKSNAME' in /etc/crypttab"
+ fi
}
inst_d /bin
inst_exec $cryptsetup /bin/cryptsetup
+ inst_d /var/run/cryptsetup
mount_dev
mount_sys
initrd_gen_devices
# TODO: 'udevadm settle' is called by lukssetup, is udev optional?
- debug "luks: process /etc/crypttab $LUKSDEV"
- luks_crypttab $LUKSDEV
+ verbose "luks: process /etc/crypttab $LUKSNAME"
+ luks_crypttab $LUKSNAME
}
# produce cryptsetup from $name from /etc/crypttab
luks_crypttab() {
- local LUKSDEV="$1"
+ local LUKSNAME="$1"
# copy from /etc/rc.d/init.d/cryptsetup
- local dst src key opt mode owner
+ local dst src key opt mode owner failsafe token libdir cryptdir
while read dst src key opt; do
- [ -z "$dst" -o "${dst#\#}" != "$dst" ] && continue
- [ "$src" != "$LUKSDEV" ] && continue
-
- if [ -n "$key" -a "x$key" != "xnone" ]; then
- if test -e "$key" ; then
- mode=$(LC_ALL=C ls -l "$key" | cut -c 5-10)
- owner=$(LC_ALL=C ls -l $key | awk '{ print $3 }')
- if [ "$mode" != "------" ] && ! key_is_random "$key"; then
- die "INSECURE MODE FOR $key"
- fi
- if [ "$owner" != root ]; then
- die "INSECURE OWNER FOR $key"
- fi
- else
- die "Key file for $dst not found"
+ [ "$dst" != "$LUKSNAME" ] && continue
+
+ failsafe=""
+
+ if [ -z "$key" ] || [ "x$key" = "xnone" ] || [ "x$key" = "x-" ]; then
+ failsafe=1
+ key="/etc/cryptsetup-keys.d/$LUKSNAME.key"
+ fi
+
+ if test -e "$key" ; then
+ mode=$(LC_ALL=C ls -l "$key" | cut -c 5-10)
+ owner=$(LC_ALL=C ls -l $key | awk '{ print $3 }')
+ if [ "$mode" != "------" ] && ! key_is_random "$key"; then
+ die "INSECURE MODE FOR $key"
fi
- else
+ if [ "$owner" != root ]; then
+ die "INSECURE OWNER FOR $key"
+ fi
+ elif [ -n "$failsafe" ]; then
key=""
+ else
+ die "Key file for $dst not found"
fi
+ src=$(find_devname "$src")
if /sbin/cryptsetup isLuks "$src" 2>/dev/null; then
if key_is_random "$key"; then
die "$dst: LUKS requires non-random key, skipping"
fi
- if [ -n "$opt" ]; then
- warn "$dst: options are invalid for LUKS partitions, ignoring them"
- fi
if [ "$key" ]; then
keyfile=/etc/.$dst.key
inst $key $keyfile
fi
+ for libdir in $(get_libdir /usr/LIBDIR); do
+ if [ -d $libdir/cryptsetup ]; then
+ cryptdir=$libdir/cryptsetup
+ break
+ fi
+ done
+ if ! is_no "$USE_LUKS_TOKEN" && [ -n "$cryptdir" ]; then
+ for token in $(/sbin/cryptsetup luksDump $src | sed -n -e '/^Tokens:/,/^[^[:space:]]/ { /^[[:space:]]*[[:digit:]]*:/ { s/^[[:space:]]*[[:digit:]]*:[[:space:]]*// p } }'); do
+ verbose "Found cryptsetup token: $token"
+ case "$token" in
+ systemd-fido2)
+ inst_d $cryptdir
+ inst_exec $cryptdir/libcryptsetup-token-$token.so $cryptdir
+ inst_exec $libdir/libfido2.so.1 $libdir
+ ;;
+ systemd-tpm2)
+ inst_d $cryptdir
+ inst_exec $cryptdir/libcryptsetup-token-$token.so $cryptdir
+ inst_exec $libdir/libtss2-esys.so.0 $libdir/libtss2-rc.so.0 $libdir/libtss2-mu.so.0 $libdir
+ ;;
+ *)
+ inst_d $cryptdir
+ inst_exec $cryptdir/libcryptsetup-token-$token.so $cryptdir
+ ;;
+ esac
+ done
+ fi
- debug "+ cryptsetup ${keyfile:+-d $keyfile} luksOpen '$src' '$dst'"
+ crypttab_opt=""
+ old_IFS="$IFS"
+ IFS=","
+ for option in $opt; do
+ case "$option" in
+ discard|allow-discards)
+ crypttab_opt="$crypttab_opt --allow-discards"
+ ;;
+ *)
+ warn "$dst: option \'$opt\' is invalid for LUKS partitions, ignored"
+ ;;
+ esac
+ done
+ IFS="$old_IFS"
+
+ verbose "+ cryptsetup ${keyfile:+-d $keyfile} open $crypttab_opt '$src' '$dst'"
add_linuxrc <<-EOF
- if [ -e "$src" ]; then
- cryptsetup ${keyfile:+-d $keyfile} luksOpen '$src' '$dst' <&1
+ debugshell
+
+ cryptsetup_opt=""
+ if [ "\$DEBUGINITRD" ]; then
+ cryptsetup_opt="--debug"
+ fi
+ # cryptsetup can be called twice and in case on crypt on lvm only second
+ # will succeed because there will be no src device in first cryptsetup call
+ # this can be called multiple times, before lvm and after lvm.
+ luksdev='$src'
+ if [ \${luksdev##/dev/disk/by-uuid/} != \${luksdev} ]; then
+ src_uuid=\${luksdev##/dev/disk/by-uuid/}
+ while read x y z name; do
+ found_uuid=\$(cryptsetup \$cryptsetup_opt luksUUID /dev/\${name} 2>/dev/null)
+ if [ "\$found_uuid" = "\$src_uuid" ]; then
+ luksdev=/dev/\$name
+ break
+ fi
+ done < /proc/partitions
+ fi
+
+ if [ -e "\$luksdev" ]; then
+ crypt_status=\$(cryptsetup \$cryptsetup_opt status '$dst')
+ if [ "\${crypt_status%%is inactive*}" != "\$crypt_status" ]; then
+ # is inactive
+ cryptsetup \$cryptsetup_opt ${keyfile:+-d $keyfile} open $crypttab_opt "\$luksdev" '$dst' <&1
+ fi
fi
debugshell