Skip to content

Commit

Permalink
Dracut TPM1 integration
Browse files Browse the repository at this point in the history
  • Loading branch information
oldium committed Jun 18, 2024
1 parent a605080 commit a13d426
Show file tree
Hide file tree
Showing 9 changed files with 212 additions and 9 deletions.
25 changes: 25 additions & 0 deletions src/luks/dracut/clevis-pin-tpm1/clevis-hook.sh.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/sh
# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
#
# Copyright (c) 2024 Red Hat, Inc.
# 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/>.

(
set -eu
. @libexecdir@/clevis-luks-tpm1-functions
stop_tcsd
)
6 changes: 6 additions & 0 deletions src/luks/dracut/clevis-pin-tpm1/clevis-tcsd.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[Unit]
DefaultDependencies=no

[Install]
# Use the default
WantedBy=
23 changes: 23 additions & 0 deletions src/luks/dracut/clevis-pin-tpm1/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
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,
)

configure_file(
input: 'clevis-hook.sh.in',
output: 'clevis-hook.sh',
install_dir: dracutdir,
configuration: data,
)

install_data('clevis-tcsd.conf', install_dir: dracutdir)
else
warning('Will not install dracut module clevis-pin-tpm2 due to missing dependencies!')
endif
97 changes: 97 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,97 @@
#!/bin/bash
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
#
# Copyright (c) 2024 Red Hat, Inc.
# 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
return 0
}

depends() {
echo clevis network
return 0
}

install() {
if dracut_module_included "systemd"; then
inst "$systemdsystemunitdir/tcsd.service"

Check warning

Code scanning / shellcheck

systemdsystemunitdir is referenced but not assigned. Warning

systemdsystemunitdir is referenced but not assigned.
inst "$moddir/clevis-tcsd.conf" "$systemdsystemunitdir/tcsd.service.d/clevis-tcsd.conf"

Check warning

Code scanning / shellcheck

moddir is referenced but not assigned. Warning

moddir is referenced but not assigned.
else
inst_hook cleanup 60 "$moddir/clevis-hook.sh"
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

Check warning

Code scanning / shellcheck

initdir is referenced but not assigned. Warning

initdir is referenced but not assigned.
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'
}
1 change: 0 additions & 1 deletion src/luks/dracut/clevis/clevis-hook.sh.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/bin/sh
set -eu
# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
#
# Copyright (c) 2020-2024 Red Hat, Inc.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
set -eu
# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
#
Expand Down Expand Up @@ -37,7 +37,9 @@ while getopts ":l" o; do
done

to_unlock() {
_skip=$@

Check warning

Code scanning / shellcheck

Assigning an array to a string! Assign as array, or use * instead of @ to concatenate. Warning

Assigning an array to a string! Assign as array, or use * instead of @ to concatenate.
_devices=''

for _d in $(blkid -t TYPE=crypto_LUKS -o device); do
if ! bindings="$(clevis luks list -d "${_d}" 2>/dev/null)" \
|| [ -z "${bindings}" ]; then
Expand All @@ -49,11 +51,56 @@ to_unlock() {
fi
_devices="$(printf '%s\n%s' "${_devices}" "${_d}")"
done
echo "${_devices}" | sed -e 's/^\n$//'
for _d in $(echo "${_devices}" | sed -e 's/^\n$//'); do
case " ${_skip} " in
*" ${_d} "* ) ;;
* ) echo -n "${_d} " ;;
esac
done | sed -e 's/ $/\n/'
}

has_tpm1_pin() {
local dev="$1"

clevis luks list -d "${dev}" | grep -q tpm1
}

do_configure_tpm1() {
local tcsd_output=
local tcsd_result

if ! [ -x @bindir@/clevis-decrypt-tpm1 ] || ! [ -f @libexecdir@/clevis-luks-tpm1-functions ]; then
return
fi

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

set +e
tcsd_output=$(start_tcsd)
tcsd_result=$?
set -e

if [ $tcsd_result -ne 0 ]; then
if [ -n "$tcsd_output" ]; then
echo "Unable to start TCSD: $tcsd_output" >&2
else
echo "Unable to start TCSD" >&2
fi
fi
}

tpm1cfg_attempted=0

tried=
while true; do
for d in $(to_unlock); do
for d in $(to_unlock $tried); do
tried="${tried} ${d}"

if [ $tpm1cfg_attempted -eq 0 ] && has_tpm1_pin "${d}"; then
tpm1cfg_attempted=1
do_configure_tpm1
fi

uuid="$(cryptsetup luksUUID "${d}")"
if ! clevis luks unlock -d "${d}"; then
echo "Unable to unlock ${d} (UUID=${uuid})" >&2
Expand All @@ -63,10 +110,10 @@ while true; do
done

[ "${loop}" != true ] && break

# Checking for pending devices to be unlocked.
if remaining=$(to_unlock) && [ -z "${remaining}" ]; then
break;
fi
remaining=$(to_unlock $tried)
[ -z "${remaining}" ] && break

sleep 0.5
done
7 changes: 6 additions & 1 deletion src/luks/dracut/clevis/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ if dracut.found()
configuration: data,
)

install_data('clevis-luks-unlocker', install_dir: libexecdir)
configure_file(
input: 'clevis-luks-unlocker.in',
output: 'clevis-luks-unlocker',
install_dir: libexecdir,
configuration: data,
)
else
warning('Will not install dracut module due to missing dependencies!')
endif
2 changes: 1 addition & 1 deletion src/luks/dracut/clevis/module-setup.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#

depends() {
local __depends=crypt
local __depends="crypt bash"
if dracut_module_included "systemd"; then
__depends=$(printf '%s systemd' "${__depends}")
fi
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 a13d426

Please sign in to comment.