Skip to content

Commit a13d426

Browse files
committed
Dracut TPM1 integration
1 parent a605080 commit a13d426

File tree

9 files changed

+212
-9
lines changed

9 files changed

+212
-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 <[email protected]>
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: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
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 <[email protected]>
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+
inst "$systemdsystemunitdir/tcsd.service"
41+
inst "$moddir/clevis-tcsd.conf" "$systemdsystemunitdir/tcsd.service.d/clevis-tcsd.conf"
42+
else
43+
inst_hook cleanup 60 "$moddir/clevis-hook.sh"
44+
inst_multiple \
45+
awk chmod chown mkfifo mktemp ip ps stdbuf \
46+
@libexecdir@/clevis-luks-tpm1-functions
47+
if [ -f /usr/libexec/coreutils/libstdbuf.so ]; then
48+
inst_multiple /usr/libexec/coreutils/libstdbuf.so*
49+
else
50+
inst_libdir_file 'coreutils/libstdbuf.so*'
51+
fi
52+
fi
53+
54+
inst_multiple \
55+
clevis-decrypt-tpm1 \
56+
tcsd \
57+
tpm_version \
58+
tpm_unsealdata
59+
60+
inst_rules 60-tpm-udev.rules
61+
62+
if ! [[ $hostonly ]] || ! dracut_module_included "systemd"; then
63+
# /etc/hosts is installed only in host-only mode with systemd, so
64+
# we need to create our own in order to get tpm tools working.
65+
# The localhost entry is required by tpm tools.
66+
if [ ! -f "$initdir/etc/hosts" ]; then
67+
echo "127.0.0.1 localhost" >> "$initdir/etc/hosts"
68+
echo "::1 localhost ip6-localhost ip6-loopback" >> "$initdir/etc/hosts"
69+
echo "ff02::1 ip6-allnodes" >> "$initdir/etc/hosts"
70+
echo "ff02::2 ip6-allrouters" >> "$initdir/etc/hosts"
71+
fi
72+
fi
73+
74+
if [[ $hostonly ]]; then
75+
inst /etc/tcsd.conf
76+
inst_multiple /var/lib/tpm/*
77+
else
78+
inst_dir /etc
79+
touch "$initdir/etc/tcsd.conf"
80+
chmod 0640 "$initdir/etc/tcsd.conf"
81+
chown root:tss "$initdir/etc/tcsd.conf"
82+
83+
inst_dir /var/lib/tpm
84+
if [ -f /usr/share/trousers/system.data.auth ]; then
85+
inst /usr/share/trousers/system.data.auth /var/lib/tpm/system.data
86+
else
87+
inst /var/lib/tpm/system.data.auth /var/lib/tpm/system.data
88+
fi
89+
fi
90+
91+
chown -R tss:tss "$initdir/var/lib/tpm"
92+
chmod -R u=rwX,go= "$initdir/var/lib/tpm"
93+
}
94+
95+
installkernel() {
96+
hostonly='' instmods '=drivers/char/tpm'
97+
}

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)