Skip to content

Commit d2661ad

Browse files
committed
Updated basic TPM1 support for preparation for Dracut integration
1 parent 3da07b0 commit d2661ad

File tree

5 files changed

+128
-47
lines changed

5 files changed

+128
-47
lines changed

src/initramfs-tools/hooks/clevis.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ if [ -x @bindir@/clevis-decrypt-tpm2 ]; then
9898
fi
9999
if [ -x @bindir@/clevis-decrypt-tpm1 ]; then
100100
copy_exec @bindir@/clevis-decrypt-tpm1 || die 1 "@bindir@/clevis-decrypt-tpm1 not found"
101+
copy_exec @libexecdir@/clevis-luks-tpm1-functions || die 1 "@libexecdir@/clevis-luks-tpm1-functions not found"
101102

102103
tcsd_bin=$(find_binary "tcsd")
103104
tpm_version_bin=$(find_binary "tpm_version")

src/initramfs-tools/scripts/local-bottom/clevis.in

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,15 @@ esac
3333

3434
[ -s /run/clevis.pid ] || exit 0
3535

36+
if [ -f @libexecdir@/clevis-luks-tpm1-functions ]; then
37+
. @libexecdir@/clevis-luks-tpm1-functions
38+
stop_tcsd
39+
fi
40+
3641
pid=$(cat /run/clevis.pid)
3742
child_pids=$(ps -o pid,ppid | awk -v pid="$pid" '$2==pid { print $1 }')
3843
for kill_pid in $pid $child_pids; do
39-
kill "$kill_pid"
44+
kill "$kill_pid"
4045
done
4146

4247
# Not really worried about downing extra interfaces: they will come up

src/initramfs-tools/scripts/local-top/clevis.in

Lines changed: 16 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -295,64 +295,34 @@ do_configure_networking() {
295295
}
296296

297297
do_configure_tpm1() {
298-
if ! [ -x @bindir@/clevis-decrypt-tpm1 ]; then
298+
local tcsd_output
299+
local tcsd_result
300+
301+
if ! [ -x @bindir@/clevis-decrypt-tpm1 ] || ! [ -f @libexecdir@/clevis-luks-tpm1-functions ]; then
299302
log_failure_msg "clevis: clevis tpm1 pin is not installed in initramfs image - missing dependency?"
300303
return 1
301304
fi
302305

303-
if ! temp_dir="$(mktemp -d)"; then
304-
log_failure_msg "clevis: Unable to create temporary directory"
305-
return 1
306-
fi
307-
fifo_file="$temp_dir/fifo"
308-
output_file="$temp_dir/output"
306+
. @libexecdir@/clevis-luks-tpm1-functions
309307

310308
log_begin_msg "clevis: Starting TCSD daemon"
311309

312310
wait_for_udev 10
313311

314-
# If we have udev, let the initialization on udev
315-
if ! [ -f /lib/udev/rules.d/60-tpm.rules ]; then
316-
chown tss:tss /dev/tpm0
317-
chmod 600 /dev/tpm0
318-
fi
319-
320-
ip link set lo up || log_failure_msg "Unable to set-up loopback network device"
321-
322-
mkfifo "$fifo_file"
323-
324-
# Start timeout to finish TCSD startup
325-
sleep 10 &
326-
sleep_pid=$!
327-
328-
# The following loop ends when output side of FIFO closes (i.e. TCSD ends)
329-
while IFS= read -r LINE; do
330-
echo "$LINE" >> "$output_file"
331-
case "$LINE" in
332-
*"TCSD up and running"*)
333-
log_success_msg "clevis: TCSD up and running"
334-
kill $sleep_pid 2>/dev/null
335-
;;
336-
esac
337-
done < $fifo_file && kill $sleep_pid 2>/dev/null &
338-
339-
# Start TCSD in foreground mode as background job. Redirected output is
340-
# block-buffered, so in order to see any output we need to set it at to
341-
# line-buffered with stdbuf
342-
stdbuf -oL tcsd -f >$fifo_file 2>&1 &
343-
tcsd_pid=$!
312+
tcsd_output=$(start_tcsd 2>&1)
313+
tcsd_result=$?
344314

345-
wait $sleep_pid 2>/dev/null
346-
347-
ps -o pid | awk -v pid="$tcsd_pid" '$1==pid {found=1} END {exit !found}'
348-
ret=$?
349-
350-
[ $ret -ne 0 ] && [ -s "$output_file" ] && log_failure_msg "Unable to start TCSD: $(< "$output_file")"
315+
if $tcsd_result -eq 0; then
316+
log_success_msg "clevis: TCSD up and running"
317+
else
318+
if [ -n "$tcsd_output" ]; then
319+
log_failure_msg "clevis: Unable to start TCSD: $tcsd_output"
320+
else
321+
log_failure_msg "clevis: Unable to start TCSD"
322+
fi
323+
fi
351324

352-
rm -rf "$temp_dir"
353325
log_end_msg
354-
355-
return $ret
356326
}
357327

358328
clevisloop &
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/bin/sh
2+
#
3+
# Copyright (c) 2024 Red Hat, Inc.
4+
# Author: Oldřich Jedlička <oldium.pro@gmail.com>
5+
#
6+
# This program is free software: you can redistribute it and/or modify
7+
# it under the terms of the GNU General Public License as published by
8+
# the Free Software Foundation, either version 3 of the License, or
9+
# (at your option) any later version.
10+
#
11+
# This program is distributed in the hope that it will be useful,
12+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
# GNU General Public License for more details.
15+
#
16+
# You should have received a copy of the GNU General Public License
17+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
#
19+
20+
start_tcsd() {
21+
local temp_dir
22+
local fifo_file
23+
local output_file
24+
local sleep_pid
25+
local tcsd_pid
26+
local ret
27+
28+
[ -s /run/tcsd.pid ] && return 0
29+
30+
if ! ip link show up dev lo | grep -qw UP; then
31+
ip link set dev lo up && echo "lo" > /tmp/tcsd.if || :
32+
if ! ip link show up dev lo | grep -qw UP; then
33+
echo "Unable to set-up loopback network device"
34+
return 1
35+
fi
36+
fi
37+
38+
if ! temp_dir="$(mktemp -d)"; then
39+
echo "Unable to create temporary directory"
40+
return 1
41+
fi
42+
43+
fifo_file="$temp_dir/fifo"
44+
output_file="$temp_dir/output"
45+
46+
# If we have udev, let the initialization on udev
47+
if ! [ -f /lib/udev/rules.d/60-tpm-udev.rules ]; then
48+
chown tss: /dev/tpm0
49+
chmod 660 /dev/tpm0
50+
fi
51+
52+
mkfifo "$fifo_file"
53+
54+
# Start timeout to finish TCSD startup
55+
sleep 10 &
56+
sleep_pid=$!
57+
58+
# The following loop ends when output side of FIFO closes (i.e. TCSD ends)
59+
{ while IFS= read -r LINE; do
60+
echo "$LINE"
61+
case "$LINE" in
62+
*"TCSD up and running"*)
63+
kill $sleep_pid 2>/dev/null
64+
;;
65+
esac
66+
done < $fifo_file && kill $sleep_pid; } >> "$output_file" 2>&1 &
67+
68+
# TCSD in background mode logs into syslogd, so we would not have any logs
69+
# available for debugging, so start TCSD in foreground mode, but as a
70+
# background job. Unfortunatelly the redirected output to pipe is
71+
# block-buffered (see `man 3 setbuf`), so in order to see any output we
72+
# need to set it to line-buffered with stdbuf tool
73+
stdbuf -oL tcsd -f >$fifo_file 2>&1 &
74+
tcsd_pid=$!
75+
76+
wait $sleep_pid 2>/dev/null
77+
78+
if ps -A -o pid | awk -v pid="$tcsd_pid" '$1==pid {found=1} END {exit !found}'; then
79+
ret=0
80+
echo $tcsd_pid > /run/tcsd.pid
81+
else
82+
ret=1
83+
[ -s "$output_file" ] && cat "$output_file"
84+
fi
85+
86+
rm -rf "$temp_dir"
87+
88+
return $ret
89+
}
90+
91+
stop_tcsd() {
92+
[ -s /run/tcsd.pid ] && {
93+
pid=$(cat /run/tcsd.pid)
94+
kill $pid >/dev/null 2>&1 || :
95+
rm -f /run/tcsd.pid
96+
}
97+
98+
[ -s /tmp/tcsd.if ] && {
99+
ip link set dev lo down || :
100+
ip addr flush dev lo || :
101+
rm -f /tmp/tcsd.if
102+
}
103+
}

src/luks/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ if libcryptsetup.found() and luksmeta.found()
6666

6767
bins += join_paths(meson.current_source_dir(), 'clevis-luks-pass')
6868
mans += join_paths(meson.current_source_dir(), 'clevis-luks-pass.1')
69+
70+
install_data('clevis-luks-tpm1-functions', install_dir: libexecdir)
6971
else
7072
warning('Will not install LUKS support due to missing dependencies!')
7173
endif

0 commit comments

Comments
 (0)