grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v12 20/20] tests: Add tpm2_test


From: Stefan Berger
Subject: Re: [PATCH v12 20/20] tests: Add tpm2_test
Date: Fri, 19 Apr 2024 09:12:00 -0400
User-agent: Mozilla Thunderbird



On 4/19/24 04:31, Gary Lin via Grub-devel wrote:
For the tpm2 module, the TCG2 command submission function is the only
difference between the a QEMU instance and grub-emu. To test TPM key
unsealing with a QEMU instance, it requires an extra OS image to invoke
grub-protect to seal the LUKS key, rather than a simple grub-shell rescue
CD image. On the other hand, grub-emu can share the emulated TPM device
with the host, so that we can seal the LUKS key on host and test key
unsealing with grub-emu.

This test script firstly creates a simple LUKS image to be loaded as a
loopback device in grub-emu. Then an emulated TPM device is created by
swtpm_cuse and PCR 0 and 1 are extended.

There are several test cases in the script to test various settings. Each
test case uses grub-protect or tpm2-tools to seal the LUKS password
against PCR 0 and PCR 1. Then grub-emu is launched to load the LUKS image,
try to mount the image with tpm2_key_protector_init and cryptomount, and
verify the result.

Based on the idea from Michael Chang.

Cc: Michael Chang <mchang@suse.com>
Cc: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Gary Lin <glin@suse.com>
---
  Makefile.util.def        |   6 +
  tests/tpm2_test.in       | 311 +++++++++++++++++++++++++++++++++++++++
  tests/util/grub-shell.in |   6 +-
  3 files changed, 322 insertions(+), 1 deletion(-)
  create mode 100644 tests/tpm2_test.in

diff --git a/Makefile.util.def b/Makefile.util.def
index 40bfe713d..8d4c53a03 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -1281,6 +1281,12 @@ script = {
    common = tests/asn1_test.in;
  };
+script = {
+  testcase = native;
+  name = tpm2_test;
+  common = tests/tpm2_test.in;
+};
+
  program = {
    testcase = native;
    name = example_unit_test;
diff --git a/tests/tpm2_test.in b/tests/tpm2_test.in
new file mode 100644
index 000000000..697319c75
--- /dev/null
+++ b/tests/tpm2_test.in
@@ -0,0 +1,311 @@
+#! @BUILD_SHEBANG@ -e
+
+# Test GRUBs ability to unseal a LUKS key with TPM 2.0
+# Copyright (C) 2024  Free Software Foundation, Inc.
+#
+# GRUB 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.
+#
+# GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+
+grubshell=@builddir@/grub-shell
+
+. "@builddir@/grub-core/modinfo.sh"
+
+if [ x$grub_modinfo_platform != xemu ]; then
+  exit 77
+fi
+
+builddir="@builddir@"
+
+# Force build directory components
+PATH="${builddir}:$PATH"
+export PATH
+
+if [ "x$EUID" = "x" ] ; then
+  EUID=`id -u`
+fi
+
+if [ "$EUID" != 0 ] ; then
+   echo "not root; cannot test tpm2."
+   exit 99
+fi
+
+if ! which cryptsetup >/dev/null 2>&1; then
+   echo "cryptsetup not installed; cannot test tpm2."
+   exit 99
+fi
+
+if ! grep -q tpm_vtpm_proxy /proc/modules && ! modprobe tpm_vtpm_proxy; then
+   echo "no tpm_vtpm_proxy support; cannot test tpm2."
+   exit 99
+fi
+
+if ! which swtpm >/dev/null 2>&1; then
+   echo "swtpm not installed; cannot test tpm2."
+   exit 99
+fi
+
+if ! which tpm2_startup >/dev/null 2>&1; then
+   echo "tpm2-tools not installed; cannot test tpm2."
+   exit 99
+fi
+
+tpm2testdir="`mktemp -d "${TMPDIR:-/tmp}/$(basename "$0").XXXXXXXXXX"`" || 
exit 20
+
+disksize=20M
+
+luksfile=$tpm2testdir/luks.disk
+lukskeyfile=${tpm2testdir}/password.txt
+
+# Choose a low iteration number to reduce the time to decrypt the disk
+csopt="--type luks2 --pbkdf pbkdf2 --iter-time 1000"
+
+tpm2statedir=${tpm2testdir}/tpm
+tpm2ctrl=${tpm2statedir}/ctrl
+tpm2log=${tpm2statedir}/logfile
+
+sealedkey=${tpm2testdir}/sealed.tpm
+
+timeout=20
+
+testoutput=$tpm2testdir/testoutput
+
+vtext="TEST VERIFIED"
+
+# Create the password file
+echo -n "top secret" > ${lukskeyfile}
+
+# Setup LUKS2 image
+truncate -s ${disksize} ${luksfile} || exit 21
+cryptsetup luksFormat -q ${csopt} ${luksfile} ${lukskeyfile} || exit 22
+
+# Shutdown the swtpm instance on exit
+cleanup() {
+    RET=$?
+    if [ -e "$tpm2ctrl" ]; then
+        swtpm_ioctl -s --unix ${tpm2ctrl}
+    fi
+    if [ "${RET}" -eq 0 ]; then
+        rm -rf "$tpm2testdir" || :
+    fi
+}
+trap cleanup EXIT INT TERM KILL QUIT
+
+mkdir -p ${tpm2statedir}
+
+# Create the swtpm chardev instannce

instance

+swtpm chardev --vtpm-proxy --tpmstate dir=${tpm2statedir} \
+       --tpm2 --ctrl type=unixio,path=${tpm2ctrl} \
+       --flags startup-clear --daemon > ${tpm2log}
+ret=$?
+if [ "$ret" -ne 0 ]; then
+    exit $ret
+fi
+
+tpm2dev=$(grep "New TPM device" ${tpm2log} | cut -d' ' -f 4)

I would add this into the loop below because timing-wise swtpm would have to be fast to have shown this output.

+if [ -z "${tpm2dev}" ]; then
+    exit QUIT
+fi
+
+# Wait for tpm2 chardev
+wait=3
+while [ "${wait}" -gt 0 ]; do
+    if [ -c "${tpm2dev}" ]; then
+        break;
+    fi
+    sleep 1
+    ((wait--))
+done
+if [ "$wait" -le 0 ]; then

echo "TPM device did not appear"




reply via email to

[Prev in Thread] Current Thread [Next in Thread]