tests: check whether disabled secure boot relaxes hash checks

This commit is contained in:
Julian Stecklina 2023-02-02 14:38:34 +01:00
parent 8b00b748f2
commit 0963ba83dd
1 changed files with 59 additions and 26 deletions

View File

@ -6,7 +6,7 @@
let let
inherit (pkgs) lib; inherit (pkgs) lib;
mkSecureBootTest = { name, machine ? { }, testScript }: testPkgs.nixosTest { mkSecureBootTest = { name, machine ? { }, useSecureBoot ? true, testScript }: testPkgs.nixosTest {
inherit name testScript; inherit name testScript;
nodes.machine = { lib, ... }: { nodes.machine = { lib, ... }: {
imports = [ imports = [
@ -17,7 +17,8 @@ let
virtualisation = { virtualisation = {
useBootLoader = true; useBootLoader = true;
useEFIBoot = true; useEFIBoot = true;
useSecureBoot = true;
inherit useSecureBoot;
}; };
boot.loader.efi = { boot.loader.efi = {
@ -31,14 +32,18 @@ let
}; };
}; };
# Execute a SB test that is expected to fail because of a hash mismatch. # Execute a boot test that has an intentionally broken secure boot
# chain. This test is expected to fail with Secure Boot and should
# succeed without.
# #
# Takes a set `path` consisting of a `src` and a `dst` attribute. The file at # Takes a set `path` consisting of a `src` and a `dst` attribute. The file at
# `src` is copied to `dst` inside th VM. Optionally append some random data # `src` is copied to `dst` inside th VM. Optionally append some random data
# ("crap") to the end of the file at `dst`. This is useful to easily change # ("crap") to the end of the file at `dst`. This is useful to easily change
# the hash of a file and produce a hash mismatch when booting the stub. # the hash of a file and produce a hash mismatch when booting the stub.
mkHashMismatchTest = { name, path, appendCrap ? false }: mkSecureBootTest { mkHashMismatchTest = { name, path, appendCrap ? false, useSecureBoot ? true }: mkSecureBootTest {
inherit name; inherit name;
inherit useSecureBoot;
testScript = '' testScript = ''
import json import json
import os.path import os.path
@ -62,9 +67,40 @@ let
machine.succeed("sync") machine.succeed("sync")
machine.crash() machine.crash()
machine.start() machine.start()
'' + (if useSecureBoot then ''
machine.wait_for_console_text("Hash mismatch") machine.wait_for_console_text("Hash mismatch")
''; '' else ''
# Just check that the system came up.
print(machine.succeed("bootctl", timeout=120))
'');
}; };
# The initrd is not directly signed. Its hash is embedded into
# lanzaboote. To make integrity verification fail, we actually have
# to modify the initrd. Appending crap to the end is a harmless way
# that would make the kernel still accept it.
mkModifiedInitrdTest = { name, useSecureBoot }: mkHashMismatchTest {
inherit name useSecureBoot;
path = {
src = "bootspec.get('initrd')";
dst = "convert_to_esp(bootspec.get('initrd'))";
};
appendCrap = true;
};
mkModifiedKernelTest = { name, useSecureBoot }: mkHashMismatchTest {
inherit name useSecureBoot;
path = {
src = "bootspec.get('kernel')";
dst = "convert_to_esp(bootspec.get('kernel'))";
};
appendCrap = true;
};
in in
{ {
# TODO: user mode: OK # TODO: user mode: OK
@ -109,31 +145,28 @@ in
''; '';
}; };
# The initrd is not directly signed. Its hash is embedded modified-initrd-doesnt-boot-with-secure-boot = mkModifiedInitrdTest {
# into the UKI. To make integrity verification fail, we name = "modified-initrd-doesnt-boot-with-secure-boot";
# actually have to modify the initrd. Appending crap to the useSecureBoot = true;
# end is a harmless way that would make the kernel still
# accept it.
secured-initrd = mkHashMismatchTest {
name = "lanzaboote-secured-initrd";
path = {
src = "bootspec.get('initrd')";
dst = "convert_to_esp(bootspec.get('initrd'))";
};
appendCrap = true;
}; };
secured-kernel = mkHashMismatchTest { modified-initrd-boots-without-secure-boot = mkModifiedInitrdTest {
name = "lanzaboote-secured-kernel"; name = "modified-initrd-boots-without-secure-boot";
path = { useSecureBoot = false;
src = "bootspec.get('kernel')";
dst = "convert_to_esp(bootspec.get('kernel'))";
};
appendCrap = true;
}; };
specialisation = mkSecureBootTest { modified-kernel-doesnt-boot-with-secure-boot = mkModifiedKernelTest {
name = "lanzaboote-specialisation"; name = "modified-kernel-doesnt-boot-with-secure-boot";
useSecureBoot = true;
};
modified-kernel-boots-without-secure-boot = mkModifiedKernelTest {
name = "modified-kernel-boots-without-secure-boot";
useSecureBoot = false;
};
specialisation-works = mkSecureBootTest {
name = "specialisation-still-boot-under-secureboot";
machine = { pkgs, ... }: { machine = { pkgs, ... }: {
specialisation.variant.configuration = { specialisation.variant.configuration = {
environment.systemPackages = [ environment.systemPackages = [