Skip to content

Commit 1c21d5b

Browse files
committed
tpm2: added TPM 2 software TPM tests
Signed-off-by: Oldřich Jedlička <[email protected]>
1 parent 537188a commit 1c21d5b

File tree

7 files changed

+229
-79
lines changed

7 files changed

+229
-79
lines changed

.github/workflows/install-dependencies

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ debian:*|ubuntu:*)
2424
build-essential pkg-config libssl-dev libjansson-dev libjose-dev \
2525
luksmeta libluksmeta-dev libpwquality-tools libglib2.0-dev \
2626
libudisks2-dev libaudit-dev systemd opensc pcscd libsofthsm2-dev \
27-
swtpm-tools tpm-tools; do
27+
swtpm-tools tpm-tools tpm2-tools; do
2828
sleep 5
2929
done
3030
;;

src/pins/tpm2/meson.build

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,7 @@ if all
1111
bins += join_paths(meson.current_source_dir(), 'clevis-decrypt-tpm2')
1212
bins += join_paths(meson.current_source_dir(), 'clevis-encrypt-tpm2')
1313
mans += join_paths(meson.current_source_dir(), 'clevis-encrypt-tpm2.1')
14+
subdir('tests')
1415
else
1516
warning('Will not install tpm2 pin due to missing dependencies!')
1617
endif
17-
18-
# Tests.
19-
env = environment()
20-
env.prepend('PATH',
21-
join_paths(meson.source_root(), 'src'),
22-
join_paths(meson.source_root(), 'src', 'luks'),
23-
join_paths(meson.source_root(), 'src', 'luks', 'tests'),
24-
join_paths(meson.source_root(), 'src', 'pins', 'sss'),
25-
join_paths(meson.source_root(), 'src', 'pins', 'tang'),
26-
join_paths(meson.source_root(), 'src', 'pins', 'tpm2'),
27-
join_paths(meson.build_root(), 'src'),
28-
join_paths(meson.build_root(), 'src', 'luks'),
29-
join_paths(meson.build_root(), 'src', 'luks', 'tests'),
30-
join_paths(meson.build_root(), 'src', 'pins', 'sss'),
31-
join_paths(meson.build_root(), 'src', 'pins', 'tang'),
32-
join_paths(meson.build_root(), 'src', 'pins', 'tpm2'),
33-
separator: ':'
34-
)
35-
test('pin-tpm2', find_program('pin-tpm2'), env: env, timeout: 120)

src/pins/tpm2/tests/meson.build

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Tests.
2+
env = environment()
3+
env.prepend('PATH',
4+
join_paths(meson.source_root(), 'src'),
5+
join_paths(meson.source_root(), 'src', 'luks'),
6+
join_paths(meson.source_root(), 'src', 'luks', 'tests'),
7+
join_paths(meson.source_root(), 'src', 'pins', 'sss'),
8+
join_paths(meson.source_root(), 'src', 'pins', 'tang'),
9+
join_paths(meson.source_root(), 'src', 'pins', 'tpm2'),
10+
join_paths(meson.source_root(), 'src', 'pins', 'tpm2', 'tests'),
11+
join_paths(meson.build_root(), 'src'),
12+
join_paths(meson.build_root(), 'src', 'luks'),
13+
join_paths(meson.build_root(), 'src', 'luks', 'tests'),
14+
join_paths(meson.build_root(), 'src', 'pins', 'sss'),
15+
join_paths(meson.build_root(), 'src', 'pins', 'tang'),
16+
join_paths(meson.build_root(), 'src', 'pins', 'tpm2'),
17+
join_paths(meson.build_root(), 'src', 'pins', 'tpm2', 'tests'),
18+
separator: ':'
19+
)
20+
21+
tpm2_data = configuration_data()
22+
tpm2_data.merge_from(data)
23+
24+
socat = find_program('socat', required: false)
25+
swtpm = find_program('swtpm', '/usr/bin/swtpm', required: false)
26+
swtpm_setup = find_program('swtpm_setup', '/usr/bin/swtpm_setup', required: false)
27+
28+
tpm2_data.set('SOCAT_BIN', socat.found() ? socat.path() : '')
29+
tpm2_data.set('SWTPM_BIN', swtpm.found() ? swtpm.path() : '')
30+
tpm2_data.set('SWTPM_SETUP_BIN', swtpm_setup.found() ? swtpm_setup.path() : '')
31+
32+
configure_file(
33+
input: 'tpm2-common-test-functions.in',
34+
output: 'tpm2-common-test-functions',
35+
configuration: tpm2_data,
36+
)
37+
38+
test('pin-tpm2-hw', find_program('pin-tpm2-hw'), env: env, timeout: 120)
39+
test('pin-tpm2-sw', find_program('pin-tpm2-sw'), env: env, timeout: 120)

src/pins/tpm2/tests/pin-tpm2-hw

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#!/bin/bash -x
2+
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
3+
#
4+
# Copyright (c) 2019 Red Hat, Inc.
5+
# Author: Sergio Correia <[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+
. tpm2-common-test-functions
22+
23+
tpm2_hw_available || skip_test
24+
tpm2_version || skip_test
25+
26+
. pin-tpm2-tests

src/pins/tpm2/tests/pin-tpm2-sw

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/bin/bash -x
2+
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
3+
#
4+
# Copyright (c) 2019 Red Hat, Inc.
5+
# Author: Sergio Correia <[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+
. tpm2-common-test-functions
22+
23+
tpm2_sw_check_preconditions
24+
tpm2_version || skip_test
25+
tpm2_start_emulation
26+
27+
. pin-tpm2-tests

src/pins/tpm2/pin-tpm2 renamed to src/pins/tpm2/tests/pin-tpm2-tests

Lines changed: 2 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -20,43 +20,6 @@
2020

2121
TEST=$(basename "${0}")
2222

23-
# Code to return to mark test as skipped.
24-
SKIP_RET_CODE=77
25-
26-
tpm2_available() {
27-
# Old environment variables for tpm2-tools 3.0
28-
export TPM2TOOLS_TCTI_NAME=device
29-
export TPM2TOOLS_DEVICE_FILE=
30-
for dev in /dev/tpmrm?; do
31-
[ -e "${dev}" ] || continue
32-
TPM2TOOLS_DEVICE_FILE="${dev}"
33-
break
34-
done
35-
36-
# New environment variable for tpm2-tools >= 3.1
37-
export TPM2TOOLS_TCTI="${TPM2TOOLS_TCTI_NAME}:${TPM2TOOLS_DEVICE_FILE}"
38-
39-
if [ -z "${TPM2TOOLS_DEVICE_FILE}" ]; then
40-
echo "A TPM2 device with the in-kernel resource manager is needed!" >&2
41-
return 1
42-
fi
43-
44-
if ! [[ -r "${TPM2TOOLS_DEVICE_FILE}" \
45-
&& -w "${TPM2TOOLS_DEVICE_FILE}" ]]; then
46-
echo "The ${TPM2TOOLS_DEVICE_FILE} device must be readable and writable!" >&2
47-
return 1
48-
fi
49-
50-
local _tpm2tools_info="$(tpm2_createprimary -v)"
51-
local _match='version="(.)\.'
52-
[[ ${_tpm2tools_info} =~ ${_match} ]] && TPM2TOOLS_VERSION="${BASH_REMATCH[1]}"
53-
if [[ $TPM2TOOLS_VERSION -lt 3 ]] || [[ $TPM2TOOLS_VERSION -gt 5 ]]; then
54-
echo "The tpm2 pin requires a tpm2-tools version between 3 and 5" >&2
55-
return 1
56-
fi
57-
export TPM2TOOLS_VERSION
58-
}
59-
6023
validate_pcrs() {
6124
local _pcr_bank="${1}"
6225
local _pcrs="${2}"
@@ -77,11 +40,6 @@ validate_pcrs() {
7740
return 0
7841
}
7942

80-
# Checking if we can run this test.
81-
if ! tpm2_available; then
82-
exit ${SKIP_RET_CODE}
83-
fi
84-
8543
decode_jwe() {
8644
local jwe="${1}"
8745

@@ -160,32 +118,17 @@ else
160118
fi
161119

162120
# Test with policies if we have the PIN rewrite available
163-
if ! $(which clevis-pin-tpm2 >/dev/null 2>&1);
121+
if ! command -v clevis-pin-tpm2 >/dev/null 2>&1;
164122
then
165123
echo "No PIN rewrite available"
166124
exit 0
167125
fi
168-
if ! $(which clevis-pin-tpm2-signtool >/dev/null 2>&1);
126+
if ! command -v clevis-pin-tpm2-signtool >/dev/null 2>&1;
169127
then
170128
echo "No policy signtool available"
171129
exit 0
172130
fi
173131

174-
function on_exit() {
175-
popd
176-
if [ ! -d "$TMP" ] || ! rm -rf "$TMP"; then
177-
echo "Delete temporary files failed!" >&2
178-
echo "You need to clean up: $TMP" >&2
179-
exit 1
180-
fi
181-
}
182-
if ! TMP="$(mktemp -d)"; then
183-
echo "Creating a temporary dir for TPM files failed!" >&2
184-
exit 1
185-
fi
186-
trap 'on_exit' EXIT
187-
pushd $TMP
188-
189132
clevis-pin-tpm2-signtool >policy_working.json << EOP
190133
---
191134
- policy_ref:
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#!/bin/bash -x
2+
# vim: set tabstop=8 shiftwidth=4 softtabstop=4 expandtab smarttab colorcolumn=80:
3+
#
4+
# Copyright (c) 2019 Red Hat, Inc.
5+
# Author: Sergio Correia <[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+
. tests-common-functions
22+
23+
SOCAT_BIN="@SOCAT_BIN@"
24+
SWTPM_BIN="@SWTPM_BIN@"
25+
SWTPM_SETUP_BIN="@SWTPM_SETUP_BIN@"
26+
27+
SWTPM_SOCKET_PID=
28+
29+
function on_exit() {
30+
popd || error "Unable to change directory"
31+
if [ ! -d "$TESTDIR" ] || ! rm -rf "$TESTDIR"; then
32+
echo "Delete temporary files failed!" >&2
33+
echo "You need to clean up: $TESTDIR" >&2
34+
exit 1
35+
fi
36+
37+
# Cleanup sw emulation
38+
if [ -n "$SWTPM_SOCKET_PID" ]; then
39+
kill $SWTPM_SOCKET_PID >/dev/null 2>&1
40+
sleep .5
41+
# swtpm does not always terminate gracefully, so kill it
42+
kill -9 $SWTPM_SOCKET_PID >/dev/null 2>&1
43+
fi
44+
}
45+
if ! TESTDIR="$(mktemp -d)"; then
46+
echo "Creating a temporary dir for TPM files failed!" >&2
47+
exit 1
48+
fi
49+
trap 'on_exit' EXIT
50+
pushd "$TESTDIR" || error "Unable to change directory"
51+
52+
53+
tpm2_hw_available() {
54+
# Old environment variables for tpm2-tools 3.0
55+
export TPM2TOOLS_TCTI_NAME=device
56+
export TPM2TOOLS_DEVICE_FILE=
57+
for dev in /dev/tpmrm?; do
58+
[ -e "${dev}" ] || continue
59+
TPM2TOOLS_DEVICE_FILE="${dev}"
60+
break
61+
done
62+
63+
# New environment variable for tpm2-tools >= 3.1
64+
export TPM2TOOLS_TCTI="${TPM2TOOLS_TCTI_NAME}:${TPM2TOOLS_DEVICE_FILE}"
65+
66+
if [ -z "${TPM2TOOLS_DEVICE_FILE}" ]; then
67+
echo "A TPM2 device with the in-kernel resource manager is needed!" >&2
68+
return 1
69+
fi
70+
71+
if ! [[ -r "${TPM2TOOLS_DEVICE_FILE}" \
72+
&& -w "${TPM2TOOLS_DEVICE_FILE}" ]]; then
73+
echo "The ${TPM2TOOLS_DEVICE_FILE} device must be readable and writable!" >&2
74+
return 1
75+
fi
76+
return 0
77+
}
78+
79+
tpm2_version() {
80+
local _tpm2tools_info
81+
local _match='version="(.)\.'
82+
_tpm2tools_info="$(tpm2_createprimary -v)"
83+
[[ ${_tpm2tools_info} =~ ${_match} ]] && TPM2TOOLS_VERSION="${BASH_REMATCH[1]}"
84+
if [[ $TPM2TOOLS_VERSION -lt 3 ]] || [[ $TPM2TOOLS_VERSION -gt 5 ]]; then
85+
echo "The tpm2 pin requires a tpm2-tools version between 3 and 5" >&2
86+
return 1
87+
fi
88+
export TPM2TOOLS_VERSION
89+
}
90+
91+
tpm2_sw_check_preconditions() {
92+
[ -x "${SOCAT_BIN}" ] || skip_test "Skipping TPM2 test with software emulation, socat not found"
93+
[ -x "${SWTPM_BIN}" ] || skip_test "Skipping TPM2 test with software emulation, swtpm not found"
94+
[ -x "${SWTPM_SETUP_BIN}" ] || skip_test "Skipping TPM2 test with software emulation, swtpm_setup not found"
95+
96+
if ! "${SWTPM_BIN}" socket --print-capabilities | jq -e '(.version | test("^0\\.[0-6](\\..*)?$")) or (.features | index("tpm-2.0"))' >/dev/null 2>&1; then
97+
skip_test "Skipping TPM2 test with software emulation, no support for TPM 2.0 in swtpm"
98+
fi
99+
}
100+
101+
tpm2_start_emulation() {
102+
local socket_wait
103+
local server_sock
104+
local control_sock
105+
106+
echo "Starting TPM 2 emulation" >&2
107+
108+
# Setup TPM 2 data
109+
"${SWTPM_SETUP_BIN}" --tpm-state "$TESTDIR" --tpm2 --create-platform-cert --lock-nvram --display >&2 || error "Unable to setup TPM 2 emulation"
110+
111+
# Start emulation over socket
112+
server_sock="$TESTDIR"/swtpm.sock
113+
control_sock="$TESTDIR"/swtpm.sock.ctrl
114+
"${SWTPM_BIN}" socket --tpmstate dir="$TESTDIR" --tpm2 --ctrl type=unixio,path="$control_sock" --server type=unixio,path="$server_sock" --flags startup-clear >&2 &
115+
SWTPM_SOCKET_PID=$!
116+
117+
socket_wait=1
118+
while [ $socket_wait -le 100 ]; do
119+
[ -S "$server_sock" ] && break
120+
socket_wait=$((socket_wait + 1))
121+
sleep 0.1
122+
done
123+
[ "$socket_wait" -gt 100 ] && error "Unable to start TPM 2 emulation"
124+
125+
# Use swtpm in tpm2-tools
126+
export TPM2TOOLS_TCTI="swtpm:path=$server_sock"
127+
128+
# Test if socket communication is supported
129+
if ! tpm2_getcap pcrs >/dev/null 2>&1; then
130+
# Old libtss2 compatibility - use socat
131+
export TPM2TOOLS_TCTI="cmd:\"$SOCAT_BIN\" - \"UNIX-CONNECT:$server_sock\""
132+
fi
133+
}

0 commit comments

Comments
 (0)