nixos/tests: adopt newest TPM support in test infra

+2 -57
nixos/tests/systemd-credentials-tpm2.nix
···
-
import ./make-test-python.nix ({ lib, pkgs, system, ... }:
-
-
let
-
tpmSocketPath = "/tmp/swtpm-sock";
-
tpmDeviceModels = {
-
x86_64-linux = "tpm-tis";
-
aarch64-linux = "tpm-tis-device";
-
};
-
in
-
+
import ./make-test-python.nix ({ lib, pkgs, ... }:
{
name = "systemd-credentials-tpm2";
···
};
nodes.machine = { pkgs, ... }: {
-
virtualisation = {
-
qemu.options = [
-
"-chardev socket,id=chrtpm,path=${tpmSocketPath}"
-
"-tpmdev emulator,id=tpm_dev_0,chardev=chrtpm"
-
"-device ${tpmDeviceModels.${system}},tpmdev=tpm_dev_0"
-
];
-
};
-
-
boot.initrd.availableKernelModules = [ "tpm_tis" ];
-
+
virtualisation.tpm.enable = true;
environment.systemPackages = with pkgs; [ diffutils ];
};
testScript = ''
-
import subprocess
-
from tempfile import TemporaryDirectory
-
-
# From systemd-initrd-luks-tpm2.nix
-
class Tpm:
-
def __init__(self):
-
self.state_dir = TemporaryDirectory()
-
self.start()
-
-
def start(self):
-
self.proc = subprocess.Popen(["${pkgs.swtpm}/bin/swtpm",
-
"socket",
-
"--tpmstate", f"dir={self.state_dir.name}",
-
"--ctrl", "type=unixio,path=${tpmSocketPath}",
-
"--tpm2",
-
])
-
-
# Check whether starting swtpm failed
-
try:
-
exit_code = self.proc.wait(timeout=0.2)
-
if exit_code is not None and exit_code != 0:
-
raise Exception("failed to start swtpm")
-
except subprocess.TimeoutExpired:
-
pass
-
-
"""Check whether the swtpm process exited due to an error"""
-
def check(self):
-
exit_code = self.proc.poll()
-
if exit_code is not None and exit_code != 0:
-
raise Exception("swtpm process died")
-
CRED_NAME = "testkey"
CRED_RAW_FILE = f"/root/{CRED_NAME}"
CRED_FILE = f"/root/{CRED_NAME}.cred"
···
raise Exception(f"systemd_run failed (status {status})")
machine.log("systemd-run finished successfully")
-
-
tpm = Tpm()
-
-
@polling_condition
-
def swtpm_running():
-
tpm.check()
machine.wait_for_unit("multi-user.target")
+20 -33
nixos/tests/systemd-cryptenroll.nix
···
environment.systemPackages = [ pkgs.cryptsetup ];
virtualisation = {
emptyDiskImages = [ 512 ];
-
qemu.options = [
-
"-chardev socket,id=chrtpm,path=/tmp/swtpm-sock"
-
"-tpmdev emulator,id=tpm0,chardev=chrtpm"
-
"-device tpm-tis,tpmdev=tpm0"
-
];
+
tpm.enable = true;
};
};
testScript = ''
-
import subprocess
-
import tempfile
+
machine.start()
-
def start_swtpm(tpmstate):
-
subprocess.Popen(["${pkgs.swtpm}/bin/swtpm", "socket", "--tpmstate", "dir="+tpmstate, "--ctrl", "type=unixio,path=/tmp/swtpm-sock", "--log", "level=0", "--tpm2"])
+
# Verify the TPM device is available and accessible by systemd-cryptenroll
+
machine.succeed("test -e /dev/tpm0")
+
machine.succeed("test -e /dev/tpmrm0")
+
machine.succeed("systemd-cryptenroll --tpm2-device=list")
-
with tempfile.TemporaryDirectory() as tpmstate:
-
start_swtpm(tpmstate)
-
machine.start()
+
# Create LUKS partition
+
machine.succeed("echo -n lukspass | cryptsetup luksFormat -q /dev/vdb -")
+
# Enroll new LUKS key and bind it to Secure Boot state
+
# For more details on PASSWORD variable, check the following issue:
+
# https://github.com/systemd/systemd/issues/20955
+
machine.succeed("PASSWORD=lukspass systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/vdb")
+
# Add LUKS partition to /etc/crypttab to test auto unlock
+
machine.succeed("echo 'luks /dev/vdb - tpm2-device=auto' >> /etc/crypttab")
-
# Verify the TPM device is available and accessible by systemd-cryptenroll
-
machine.succeed("test -e /dev/tpm0")
-
machine.succeed("test -e /dev/tpmrm0")
-
machine.succeed("systemd-cryptenroll --tpm2-device=list")
-
-
# Create LUKS partition
-
machine.succeed("echo -n lukspass | cryptsetup luksFormat -q /dev/vdb -")
-
# Enroll new LUKS key and bind it to Secure Boot state
-
# For more details on PASSWORD variable, check the following issue:
-
# https://github.com/systemd/systemd/issues/20955
-
machine.succeed("PASSWORD=lukspass systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/vdb")
-
# Add LUKS partition to /etc/crypttab to test auto unlock
-
machine.succeed("echo 'luks /dev/vdb - tpm2-device=auto' >> /etc/crypttab")
-
machine.shutdown()
+
machine.shutdown()
+
machine.start()
-
start_swtpm(tpmstate)
-
machine.start()
-
-
# Test LUKS partition automatic unlock on boot
-
machine.wait_for_unit("systemd-cryptsetup@luks.service")
-
# Wipe TPM2 slot
-
machine.succeed("systemd-cryptenroll --wipe-slot=tpm2 /dev/vdb")
+
# Test LUKS partition automatic unlock on boot
+
machine.wait_for_unit("systemd-cryptsetup@luks.service")
+
# Wipe TPM2 slot
+
machine.succeed("systemd-cryptenroll --wipe-slot=tpm2 /dev/vdb")
'';
})
+1 -26
nixos/tests/systemd-initrd-luks-tpm2.nix
···
# Booting off the TPM2-encrypted device requires an available init script
mountHostNixStore = true;
useEFIBoot = true;
-
qemu.options = ["-chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock -tpmdev emulator,id=tpm0,chardev=chrtpm -device tpm-tis,tpmdev=tpm0"];
+
tpm.enable = true;
};
boot.loader.systemd-boot.enable = true;
···
};
testScript = ''
-
import subprocess
-
import os
-
import time
-
-
-
class Tpm:
-
def __init__(self):
-
os.mkdir("/tmp/mytpm1")
-
self.start()
-
-
def start(self):
-
self.proc = subprocess.Popen(["${pkgs.swtpm}/bin/swtpm", "socket", "--tpmstate", "dir=/tmp/mytpm1", "--ctrl", "type=unixio,path=/tmp/mytpm1/swtpm-sock", "--log", "level=20", "--tpm2"])
-
-
def wait_for_death_then_restart(self):
-
while self.proc.poll() is None:
-
print("waiting for tpm to die")
-
time.sleep(1)
-
assert self.proc.returncode == 0
-
self.start()
-
-
tpm = Tpm()
-
-
# Create encrypted volume
machine.wait_for_unit("multi-user.target")
machine.succeed("echo -n supersecret | cryptsetup luksFormat -q --iter-time=1 /dev/vdb -")
···
machine.succeed("bootctl set-default nixos-generation-1-specialisation-boot-luks.conf")
machine.succeed("sync")
machine.crash()
-
-
tpm.wait_for_death_then_restart()
# Boot and decrypt the disk
machine.wait_for_unit("multi-user.target")