Skip to content

Commit

Permalink
Added TPM 1.2 support for Dracut
Browse files Browse the repository at this point in the history
Signed-off-by: Oldřich Jedlička <[email protected]>
  • Loading branch information
oldium committed Jun 23, 2024
1 parent eca718c commit e83e669
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/luks/dracut/clevis-pin-tpm1/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
dracut = dependency('dracut', required: false)

if dracut.found()
dracutdir = dracut.get_pkgconfig_variable('dracutmodulesdir') + '/60' + meson.project_name() + '-pin-tpm1'

configure_file(
input: 'module-setup.sh.in',
output: 'module-setup.sh',
install_dir: dracutdir,
configuration: data,
)
else
warning('Will not install dracut module clevis-pin-tpm2 due to missing dependencies!')
endif
106 changes: 106 additions & 0 deletions src/luks/dracut/clevis-pin-tpm1/module-setup.sh.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#!/bin/bash
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
#
# Copyright (c) 2024 Oldřich Jedlička
#
# Author: Oldřich Jedlička <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

check() {
require_binaries clevis-decrypt-tpm1 tpm_version tpm_unsealdata tcsd stdbuf || return 1
if [[ $hostonly ]]; then
[ -d /var/lib/tpm ] || return 1
else
[ -f /usr/share/trousers/system.data.auth ] || \
[ -f /var/lib/tpm/system.data.auth ] || \
return 1
fi
if dracut_module_included "systemd"; then
# shellcheck disable=SC2154 # $systemdsystemunitdir is a dracut variable
[ -f "$systemdsystemunitdir"/tcsd.service ] || \
[ -f "$systemdsystemunitdir"/tcsd.service.d/clevis-tcsd.conf ] || \
return 1
fi
return 0
}

depends() {
echo clevis network
return 0
}

install() {
if dracut_module_included "systemd"; then
inst_multiple \
"$systemdsystemunitdir/tcsd.service" \
"$systemdsystemunitdir/tcsd.service.d/clevis-tcsd.conf"
# shellcheck disable=SC2154 # $initdir is a dracut variable
systemctl -q --root "$initdir" add-wants cryptsetup.target tcsd.service
else
inst_multiple \
awk chmod chown mkfifo mktemp ip ps stdbuf \
@libexecdir@/clevis-luks-tpm1-functions
if [ -f /usr/libexec/coreutils/libstdbuf.so ]; then
inst_multiple /usr/libexec/coreutils/libstdbuf.so*
else
inst_libdir_file 'coreutils/libstdbuf.so*'
fi
fi

inst_multiple \
clevis-decrypt-tpm1 \
tcsd \
tpm_version \
tpm_unsealdata

inst_rules 60-tpm-udev.rules

if ! [[ $hostonly ]] || ! dracut_module_included "systemd"; then
# /etc/hosts is installed only in host-only mode with systemd, so
# we need to create our own in order to get tpm tools working.
# The localhost entry is required by tpm tools.
if [ ! -f "$initdir/etc/hosts" ]; then
echo "127.0.0.1 localhost" >> "$initdir/etc/hosts"
echo "::1 localhost ip6-localhost ip6-loopback" >> "$initdir/etc/hosts"
echo "ff02::1 ip6-allnodes" >> "$initdir/etc/hosts"
echo "ff02::2 ip6-allrouters" >> "$initdir/etc/hosts"
fi
fi

if [[ $hostonly ]]; then
inst /etc/tcsd.conf
inst_multiple /var/lib/tpm/*
else
inst_dir /etc
touch "$initdir/etc/tcsd.conf"
chmod 0640 "$initdir/etc/tcsd.conf"
chown root:tss "$initdir/etc/tcsd.conf"

inst_dir /var/lib/tpm
if [ -f /usr/share/trousers/system.data.auth ]; then
inst /usr/share/trousers/system.data.auth /var/lib/tpm/system.data
else
inst /var/lib/tpm/system.data.auth /var/lib/tpm/system.data
fi
fi

chown -R tss:tss "$initdir/var/lib/tpm"
chmod -R u=rwX,go= "$initdir/var/lib/tpm"
}

installkernel() {
hostonly='' instmods '=drivers/char/tpm'
}
5 changes: 5 additions & 0 deletions src/luks/dracut/clevis/clevis-cleanup-hook.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
(
[ -s /run/clevis.pid ] || exit 0

if [ -f @libexecdir@/clevis-luks-tpm1-functions ]; then
. @libexecdir@/clevis-luks-tpm1-functions
stop_tcsd
fi

pid=$(cat /run/clevis.pid)
child_pids=$(ps -A -o pid,ppid | awk -v pid="$pid" '$2==pid { print $1 }')
for kill_pid in $pid $child_pids; do
Expand Down
25 changes: 25 additions & 0 deletions src/luks/dracut/clevis/clevis-password-unlocker.in
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ clevisloop() {
local askpass_info
local sleep_time
local OLD_CRYPTTAB_SOURCE=""
local tpm1cfg_attempted=0

while true; do
# Re-get the askpass PID in case there are multiple encrypted devices
Expand All @@ -132,6 +133,11 @@ EOM
[ "$CRYPTTAB_SOURCE" = "$OLD_CRYPTTAB_SOURCE" ] && continue
OLD_CRYPTTAB_SOURCE="$CRYPTTAB_SOURCE"

if [[ " $pins " == *" tpm1 "* ]] && [ $tpm1cfg_attempted -eq 0 ]; then
tpm1cfg_attempted=1
do_configure_tpm1
fi

if luks_decrypt "${CRYPTTAB_SOURCE}" "${PASSFIFO}"; then
info "Unlocked ${CRYPTTAB_SOURCE} with clevis"

Expand All @@ -147,6 +153,25 @@ EOM
done
}

do_configure_tpm1() {
local tcsd_output=
local tcsd_result

Check warning

Code scanning / shellcheck

tcsd_result appears unused. Verify use (or export if used externally). Warning

tcsd_result appears unused. Verify use (or export if used externally).

[ -x @bindir@/clevis-decrypt-tpm1 ] && [ -f @libexecdir@/clevis-luks-tpm1-functions ] || return

. @libexecdir@/clevis-luks-tpm1-functions

info "Starting TCSD daemon"

if ! tcsd_output=$(start_tcsd 2>&1); then
if [ -n "$tcsd_output" ]; then
echo "Unable to start TCSD: $tcsd_output" | vwarn
else
warn "Unable to start TCSD"
fi
fi
}

mkdir -p -m 0755 /var/cache

Check warning

Code scanning / shellcheck

When used with -p, -m only applies to the deepest directory. Warning

When used with -p, -m only applies to the deepest directory.
mkdir -p -m 0700 /var/cache/clevis-disks

Check warning

Code scanning / shellcheck

When used with -p, -m only applies to the deepest directory. Warning

When used with -p, -m only applies to the deepest directory.

Expand Down
1 change: 1 addition & 0 deletions src/luks/dracut/meson.build
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
subdir('clevis')
subdir('clevis-pin-tang')
subdir('clevis-pin-tpm1')
subdir('clevis-pin-tpm2')
subdir('clevis-pin-sss')
subdir('clevis-pin-null')

0 comments on commit e83e669

Please sign in to comment.