Skip to content

Commit b4cc648

Browse files
committed
Dracut TPM1 integration
1 parent a605080 commit b4cc648

File tree

9 files changed

+215
-9
lines changed

9 files changed

+215
-9
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/sh
2+
# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
3+
#
4+
# Copyright (c) 2024 Red Hat, Inc.
5+
# Author: Oldřich Jedlička <oldium.pro@gmail.com>
6+
#
7+
#
8+
# This program is free software: you can redistribute it and/or modify
9+
# it under the terms of the GNU General Public License as published by
10+
# the Free Software Foundation, either version 3 of the License, or
11+
# (at your option) any later version.
12+
#
13+
# This program is distributed in the hope that it will be useful,
14+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
# GNU General Public License for more details.
17+
#
18+
# You should have received a copy of the GNU General Public License
19+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
20+
21+
(
22+
set -eu
23+
. @libexecdir@/clevis-luks-tpm1-functions
24+
stop_tcsd
25+
)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[Unit]
2+
DefaultDependencies=no
3+
4+
[Install]
5+
# Use the default
6+
WantedBy=
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
dracut = dependency('dracut', required: false)
2+
3+
if dracut.found()
4+
dracutdir = dracut.get_pkgconfig_variable('dracutmodulesdir') + '/60' + meson.project_name() + '-pin-tpm1'
5+
6+
configure_file(
7+
input: 'module-setup.sh.in',
8+
output: 'module-setup.sh',
9+
install_dir: dracutdir,
10+
configuration: data,
11+
)
12+
13+
configure_file(
14+
input: 'clevis-hook.sh.in',
15+
output: 'clevis-hook.sh',
16+
install_dir: dracutdir,
17+
configuration: data,
18+
)
19+
20+
install_data('clevis-tcsd.conf', install_dir: dracutdir)
21+
else
22+
warning('Will not install dracut module clevis-pin-tpm2 due to missing dependencies!')
23+
endif
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/bin/bash
2+
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
3+
#
4+
# Copyright (c) 2024 Red Hat, Inc.
5+
# Author: Oldřich Jedlička <oldium.pro@gmail.com>
6+
#
7+
# This program is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU General Public License as published by
9+
# the Free Software Foundation, either version 3 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# This program is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU General Public License
18+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
#
20+
21+
check() {
22+
require_binaries clevis-decrypt-tpm1 tpm_version tpm_unsealdata tcsd stdbuf || return 1
23+
if [[ $hostonly ]]; then
24+
[ -d /var/lib/tpm ] || return 1
25+
else
26+
[ -f /usr/share/trousers/system.data.auth ] || \
27+
[ -f /var/lib/tpm/system.data.auth ] || \
28+
return 1
29+
fi
30+
return 0
31+
}
32+
33+
depends() {
34+
echo clevis network
35+
return 0
36+
}
37+
38+
install() {
39+
if dracut_module_included "systemd"; then
40+
# shellcheck disable=SC2154 # $systemdsystemunitdir is a dracut variable
41+
inst "$systemdsystemunitdir/tcsd.service"
42+
# shellcheck disable=SC2154 # $moddir is a dracut variable
43+
inst "$moddir/clevis-tcsd.conf" "$systemdsystemunitdir/tcsd.service.d/clevis-tcsd.conf"
44+
else
45+
inst_hook cleanup 60 "$moddir/clevis-hook.sh"
46+
inst_multiple \
47+
awk chmod chown mkfifo mktemp ip ps stdbuf \
48+
@libexecdir@/clevis-luks-tpm1-functions
49+
if [ -f /usr/libexec/coreutils/libstdbuf.so ]; then
50+
inst_multiple /usr/libexec/coreutils/libstdbuf.so*
51+
else
52+
inst_libdir_file 'coreutils/libstdbuf.so*'
53+
fi
54+
fi
55+
56+
inst_multiple \
57+
clevis-decrypt-tpm1 \
58+
tcsd \
59+
tpm_version \
60+
tpm_unsealdata
61+
62+
inst_rules 60-tpm-udev.rules
63+
64+
if ! [[ $hostonly ]] || ! dracut_module_included "systemd"; then
65+
# /etc/hosts is installed only in host-only mode with systemd, so
66+
# we need to create our own in order to get tpm tools working.
67+
# The localhost entry is required by tpm tools.
68+
# shellcheck disable=SC2154 # $initdir is a dracut variable
69+
if [ ! -f "$initdir/etc/hosts" ]; then
70+
echo "127.0.0.1 localhost" >> "$initdir/etc/hosts"
71+
echo "::1 localhost ip6-localhost ip6-loopback" >> "$initdir/etc/hosts"
72+
echo "ff02::1 ip6-allnodes" >> "$initdir/etc/hosts"
73+
echo "ff02::2 ip6-allrouters" >> "$initdir/etc/hosts"
74+
fi
75+
fi
76+
77+
if [[ $hostonly ]]; then
78+
inst /etc/tcsd.conf
79+
inst_multiple /var/lib/tpm/*
80+
else
81+
inst_dir /etc
82+
touch "$initdir/etc/tcsd.conf"
83+
chmod 0640 "$initdir/etc/tcsd.conf"
84+
chown root:tss "$initdir/etc/tcsd.conf"
85+
86+
inst_dir /var/lib/tpm
87+
if [ -f /usr/share/trousers/system.data.auth ]; then
88+
inst /usr/share/trousers/system.data.auth /var/lib/tpm/system.data
89+
else
90+
inst /var/lib/tpm/system.data.auth /var/lib/tpm/system.data
91+
fi
92+
fi
93+
94+
chown -R tss:tss "$initdir/var/lib/tpm"
95+
chmod -R u=rwX,go= "$initdir/var/lib/tpm"
96+
}
97+
98+
installkernel() {
99+
hostonly='' instmods '=drivers/char/tpm'
100+
}

src/luks/dracut/clevis/clevis-hook.sh.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#!/bin/sh
2-
set -eu
32
# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
43
#
54
# Copyright (c) 2020-2024 Red Hat, Inc.

src/luks/dracut/clevis/clevis-luks-unlocker renamed to src/luks/dracut/clevis/clevis-luks-unlocker.in

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/bin/sh
1+
#!/bin/bash
22
set -eu
33
# vim: set ts=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
44
#
@@ -37,7 +37,9 @@ while getopts ":l" o; do
3737
done
3838

3939
to_unlock() {
40+
_skip=$*
4041
_devices=''
42+
4143
for _d in $(blkid -t TYPE=crypto_LUKS -o device); do
4244
if ! bindings="$(clevis luks list -d "${_d}" 2>/dev/null)" \
4345
|| [ -z "${bindings}" ]; then
@@ -49,11 +51,56 @@ to_unlock() {
4951
fi
5052
_devices="$(printf '%s\n%s' "${_devices}" "${_d}")"
5153
done
52-
echo "${_devices}" | sed -e 's/^\n$//'
54+
for _d in $(echo "${_devices}" | sed -e 's/^\n$//'); do
55+
case " ${_skip} " in
56+
*" ${_d} "* ) ;;
57+
* ) echo -n "${_d} " ;;
58+
esac
59+
done | sed -e 's/ $/\n/'
5360
}
5461

62+
has_tpm1_pin() {
63+
local dev="$1"
64+
65+
clevis luks list -d "${dev}" | grep -q tpm1
66+
}
67+
68+
do_configure_tpm1() {
69+
local tcsd_output=
70+
local tcsd_result
71+
72+
if ! [ -x @bindir@/clevis-decrypt-tpm1 ] || ! [ -f @libexecdir@/clevis-luks-tpm1-functions ]; then
73+
return
74+
fi
75+
76+
. @libexecdir@/clevis-luks-tpm1-functions
77+
78+
set +e
79+
tcsd_output=$(start_tcsd)
80+
tcsd_result=$?
81+
set -e
82+
83+
if [ $tcsd_result -ne 0 ]; then
84+
if [ -n "$tcsd_output" ]; then
85+
echo "Unable to start TCSD: $tcsd_output" >&2
86+
else
87+
echo "Unable to start TCSD" >&2
88+
fi
89+
fi
90+
}
91+
92+
tpm1cfg_attempted=0
93+
94+
tried=
5595
while true; do
56-
for d in $(to_unlock); do
96+
for d in $(to_unlock $tried); do
97+
tried="${tried} ${d}"
98+
99+
if [ $tpm1cfg_attempted -eq 0 ] && has_tpm1_pin "${d}"; then
100+
tpm1cfg_attempted=1
101+
do_configure_tpm1
102+
fi
103+
57104
uuid="$(cryptsetup luksUUID "${d}")"
58105
if ! clevis luks unlock -d "${d}"; then
59106
echo "Unable to unlock ${d} (UUID=${uuid})" >&2
@@ -63,10 +110,10 @@ while true; do
63110
done
64111

65112
[ "${loop}" != true ] && break
113+
66114
# Checking for pending devices to be unlocked.
67-
if remaining=$(to_unlock) && [ -z "${remaining}" ]; then
68-
break;
69-
fi
115+
remaining=$(to_unlock $tried)
116+
[ -z "${remaining}" ] && break
70117

71118
sleep 0.5
72119
done

src/luks/dracut/clevis/meson.build

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@ if dracut.found()
1717
configuration: data,
1818
)
1919

20-
install_data('clevis-luks-unlocker', install_dir: libexecdir)
20+
configure_file(
21+
input: 'clevis-luks-unlocker.in',
22+
output: 'clevis-luks-unlocker',
23+
install_dir: libexecdir,
24+
configuration: data,
25+
)
2126
else
2227
warning('Will not install dracut module due to missing dependencies!')
2328
endif

src/luks/dracut/clevis/module-setup.sh.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#
2020

2121
depends() {
22-
local __depends=crypt
22+
local __depends="crypt bash"
2323
if dracut_module_included "systemd"; then
2424
__depends=$(printf '%s systemd' "${__depends}")
2525
fi

src/luks/dracut/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
subdir('clevis')
22
subdir('clevis-pin-tang')
3+
subdir('clevis-pin-tpm1')
34
subdir('clevis-pin-tpm2')
45
subdir('clevis-pin-sss')
56
subdir('clevis-pin-null')

0 commit comments

Comments
 (0)