Test and unfuck TPM1.X + dracut

Tested on a Toshiba R700
This commit is contained in:
наб 2020-12-07 20:30:35 +01:00
parent f7748a1f23
commit af3e91c77d
No known key found for this signature in database
GPG Key ID: BCFD0B018D2658F1
8 changed files with 78 additions and 49 deletions

View File

@ -62,10 +62,12 @@ $(OUTDIR)man/index.txt : $(MANDIR)index.txt $(patsubst $(MANDIR)%.pp,$(OUTDIR)ma
$(OUTDIR)initramfs-tools/usr/share/initramfs-tools/hooks/tzpfms: $(INITRDDIR)initramfs-tools/hook $(INITRD_HEADERS)
@mkdir -p $(dir $@)
$(AWK) -f pp.awk $< > $@
chmod --reference $< $@
$(OUTDIR)initramfs-tools/usr/share/tzpfms/initramfs-tools-zfs-patch.sh: $(INITRDDIR)initramfs-tools/zfs-patch.sh $(INITRD_HEADERS)
@mkdir -p $(dir $@)
$(AWK) -f pp.awk $< > $@
chmod --reference $< $@
$(OUTDIR)%$(EXE) : $(subst $(SRCDIR),$(OBJDIR),$(subst .cpp,$(OBJ),$(SRCDIR)bin/%.cpp $(COMMON_SOURCES)))
@ -88,3 +90,4 @@ $(OUTDIR)man/%.md : $(MANDIR)%.md.pp $(MANPAGE_HEADERS)
$(OUTDIR)dracut/usr/lib/dracut/modules.d/91tzpfms/% : $(INITRDDIR)dracut/% $(INITRD_HEADERS)
@mkdir -p $(dir $@)
$(AWK) -f pp.awk $< > $@
chmod --reference $< $@

View File

@ -2,6 +2,9 @@
# SPDX-License-Identifier: MIT
#include "../install.h"
_get_backend() {
rootfs="$(awk '$2 == "/" && $3 == "zfs" {print $1; exit 1}' /etc/mtab)"
[ -z "$rootfs" ] && return 1
@ -11,17 +14,20 @@ _get_backend() {
backend="$(zfs-tpm-list -H "$eroot" | awk -F'\t' '{print $2}')"
[ -z "$backend" ] && return 1
[ -n "$backend" ]
return
}
_install_tpm2() {
inst_binary zfs-tpm2-load-key
# shellcheck disable=SC2046
dracut_install zfs-tpm2-load-key $(find /usr/lib -name 'libtss2-tcti*.so*') # TODO: there's got to be a better way™!
inst_library $(find /usr/lib -name 'libtss2-tcti*.so*') # TODO: there's got to be a better way™!
}
_install_tpm1x() {
dracut_install zfs-tpm1x-load-key
command -v tcsd > /dev/null && dracut_install tcsd
inst_binary zfs-tpm1x-load-key
INSTALL_TPM1X{inst_binary tcsd; inst_binary ip; inst_binary ss, initdir, inst_simple, inst_simple, inst_simple, inst_library}
command -v tpm_resetdalock > /dev/null && inst_binary tpm_resetdalock
}
@ -29,16 +35,16 @@ check() {
command -v zfs-tpm-list > /dev/null || return 1
# shellcheck disable=SC2154
if [ -n "$hostonly" ]; then
if [ -n "$hostonly" ]; then
_get_backend || return
[ "$backend" = "TPM2" ] && command -v zfs-tpm2-load-key > /dev/null && return 0
[ "$backend" = "TPM1.X" ] && command -v zfs-tpm1x-load-key > /dev/null && return 0
return 1
fi
fi
return 0
return 0
}
@ -53,7 +59,7 @@ installkernel() {
install() {
dracut_install zfs-tpm-list
inst_binary zfs-tpm-list
if [ -n "${hostonly}" ]; then
_get_backend

View File

@ -17,6 +17,11 @@ root="${root:=$(getarg root=)}"
rootfstype="${rootfstype:=$(getarg rootfstype=)}"
[ "${root##zfs:}" = "$root" ] && [ "${root##ZFS=}" = "$root" ] && [ "$rootfstype" != "zfs" ] && exit 0
TZPFMS_TPM1X="$(getarg TZPFMS_TPM1X=)"
[ -z "$TZPFMS_TPM1X" ] || export TZPFMS_TPM1X
getarg 0 quiet && quiet=y
# There is a race between the zpool import and the pre-mount hooks, so we wait for a pool to be imported
while [ "$(zpool list -H)" = "" ]; do
@ -48,7 +53,7 @@ if [ "$(zpool list -H -o feature@encryption "$(echo "$BOOTFS" | awk -F/ '{print
fi
if command -v zfs-tpm1x-load-key > /dev/null && ! [ "$(zfs-tpm-list -Hub TPM1.X "$ENCRYPTIONROOT")" = "" ]; then
POTENTIALLY_START_TCSD{}
POTENTIALLY_START_TCSD{ss -ltO, > /dev/console 2>&1}
with_promptable_tty zfs-tpm1x-load-key "$ENCRYPTIONROOT"; err="$?"
POTENTIALLY_KILL_TCSD{}
exit "$err"

View File

@ -1,6 +1,10 @@
#!/bin/sh
# SPDX-License-Identifier: MIT
#include "../install.h"
PREREQ="zfs"
[ "$1" = "prereqs" ] && exec echo "$PREREQ"
. /usr/share/initramfs-tools/hook-functions
@ -13,44 +17,12 @@ sed -Ei 's/^decrypt_fs\(\)/__tzpfms__&/' "$DESTDIR/scripts/zfs"
cat /usr/share/tzpfms/initramfs-tools-zfs-patch.sh >> "$DESTDIR/scripts/zfs"
for x in tpm_resetdalock zfs-tpm-list zfs-tpm2-load-key zfs-tpm1x-load-key tcsd $(find /usr/lib -name 'libtss2-tcti*.so*'); do # TODO: there's got to be a better way™!
for x in zfs-tpm-list zfs-tpm2-load-key zfs-tpm1x-load-key tpm_resetdalock tcsd $(find /usr/lib -name 'libtss2-tcti*.so*'); do # TODO: there's got to be a better way™!
xloc="$(command -v "$x")"
[ "$xloc" = "" ] || copy_exec "$xloc"
done
if command -v tcsd > /dev/null; then
# tcsd exits if it doesn't have tss group and user
grep tss /etc/group >> "$DESTDIR/etc/group"
grep tss /etc/passwd >> "$DESTDIR/etc/passwd"
for f in /lib/udev/rules.d/*tpm*; do
copy_file rule $f
done
if [ -e /etc/tcsd.conf ]; then
copy_file config /etc/tcsd.conf
system_ps_file="$(awk -F '[[:space:]]*=[[:space:]]*' '!/^[[:space:]]*#/ && !/^$/ && $1 ~ /system_ps_file$/ {gsub(/[[:space:]]*$/, "", $2); print $2}' /etc/tcsd.conf)"
system_ps_file="${system_ps_file:-/var/lib/tpm/system.data}"
fi
# tcsd can't find SRK if state not present, refuses to start if it doesn't have parent to tss dir
mkdir -p "$DESTDIR/$(dirname "$(dirname "$system_ps_file")")"
[ -f "$system_ps_file" ] && copy_file state "$system_ps_file"
fi
# localhost needs to resolve at the very least
for f in /etc/hosts /etc/resolv.conf /etc/host.conf /etc/gai.conf; do
[ -e $f ] && copy_file config $f
done
if [ -e /etc/nsswitch.conf ]; then
copy_file config /etc/nsswitch.conf
databases="$(awk '/^group|hosts/ {for(i = 2; i <= NF; ++i) print $i}' /etc/nsswitch.conf | sort | uniq)"
for db in $databases; do
for f in /lib/*/"libnss_$db"*; do
copy_exec "$f"
done
done
fi
INSTALL_TPM1X{, DESTDIR, copy_file rule, copy_file config, copy_file state, copy_exec}
copy_modules_dir 'kernel/drivers/char/tpm'

View File

@ -28,7 +28,7 @@ decrypt_fs() {
fi
if command -v zfs-tpm1x-load-key > /dev/null && ! [ "$(zfs-tpm-list -Hub TPM1.X "$ENCRYPTIONROOT")" = "" ]; then
POTENTIALLY_START_TCSD{}
POTENTIALLY_START_TCSD{netstat -lt, }
with_promptable_tty zfs-tpm1x-load-key "$ENCRYPTIONROOT"; err="$?"
POTENTIALLY_KILL_TCSD{}
return "$err"

42
initrd/install.h Normal file
View File

@ -0,0 +1,42 @@
# SPDX-License-Identifier: MIT
#define INSTALL_TPM1X(PREREQ, TARGET_DIR, INST_UDEV, INST_CFG, INST_STATE, INST_LIB)
command -v tcsd > /dev/null && {
PREREQ
# tcsd exits if it doesn't have tss group and user
grep tss /etc/group >> "${TARGET_DIR:-MUST_EXIST}/etc/group"
grep tss /etc/passwd >> "${TARGET_DIR:-MUST_EXIST}/etc/passwd"
for f in /lib/udev/rules.d/*tpm*; do
INST_UDEV "$f"
done
if [ -e /etc/tcsd.conf ]; then
INST_CFG /etc/tcsd.conf
chown tss:tss "${TARGET_DIR:-MUST_EXIST}/etc/tcsd.conf"
system_ps_file="$(awk -F '[[:space:]]*=[[:space:]]*' '!/^[[:space:]]*#/ && !/^$/ && $1 ~ /system_ps_file$/ {gsub(/[[:space:]]*$/, "", $2); print $2}' /etc/tcsd.conf)"
system_ps_file="${system_ps_file:-/var/lib/tpm/system.data}"
fi
# tcsd can't find SRK if state not present, refuses to start if it doesn't have parent to tss dir
mkdir -p "${TARGET_DIR:-MUST_EXIST}/$(dirname "$(dirname "$system_ps_file")")"
[ -f "$system_ps_file" ] && INST_STATE "$system_ps_file"
}
# localhost needs to resolve at the very least
for f in /etc/hosts /etc/resolv.conf /etc/host.conf /etc/gai.conf; do
[ -e "$f" ] && INST_CFG "$f"
done
if [ -e /etc/nsswitch.conf ]; then
INST_CFG /etc/nsswitch.conf
databases="$(awk '/^group|hosts/ {for(i = 2; i <= NF; ++i) print $i}' /etc/nsswitch.conf | sort | uniq)"
for db in $databases; do
for f in /lib/*/"libnss_$db"*; do
INST_LIB "$f"
done
done
fi
#endefine

9
initrd/mount.h Executable file → Normal file
View File

@ -11,7 +11,8 @@
with_promptable_tty() {
if command -v plymouth > /dev/null && plymouth --ping; then
plymouth hide-splash
[ "${quiet:-n}" = "y" ] && printf '\033c'
# shellcheck disable=SC2217
[ "${quiet:-n}" = "y" ] && printf '\033c' REDIREXIONS
"$@" REDIREXIONS; ret="$?"
@ -30,7 +31,7 @@
#endefine
#define POTENTIALLY_START_TCSD()
#define POTENTIALLY_START_TCSD(LISTENING_TCP, REDIREXIONS)
[ -z "$TZPFMS_TPM1X" ] && command -v tcsd > /dev/null && {
ip l | awk -F '[[:space:]]*:[[:space:]]*' '{if($2 == "lo") exit $3 ~ /UP/}'
lo_was_up="$?"
@ -42,10 +43,10 @@
if [ "${quiet:-n}" = "y" ]; then
tcsd -f > /tcsd.log 2>&1 &
else
tcsd -f &
tcsd -f REDIREXIONS &
fi
tcsd_port="$(awk -F '[[:space:]]*=[[:space:]]*' '!/^[[:space:]]*#/ && !/^$/ && $1 ~ /port$/ {gsub(/[[:space:]]/, "", $2); print $2}' /etc/tcsd.conf)"
i=0; while [ "$i" -lt 100 ] && ! netstat -lt | grep -q "${tcsd_port:-30003}"; do sleep 0.1; i="$((i + 1))"; done
i=0; while [ "$i" -lt 100 ] && ! LISTENING_TCP | grep -q "${tcsd_port:-30003}"; do sleep 0.1; i="$((i + 1))"; done
[ "$i" = 100 ] && echo "Couldn't start tcsd!" >&2
}
#endefine

2
pp.awk Executable file → Normal file
View File

@ -41,7 +41,7 @@ function input() {
last = $i ~ /\)$/
sub(/[,\)]/, "", $i)
macro_args[macroname,i - 2] = $i
macro_args[macroname,i - 1] = $i
}
}