Arch Linux: Bootvorgang mittels TPM2 & TOTP messen und Vertrauenswürdigkeit überprüfen (Measured-Boot)

Leider ist das Konzept von Verified-/Trusted-Boot unter Linux, im Gegensatz zu z.B. Android, Chromium OS, MacOS und Windows, immer noch nicht wirklich präsent (siehe bspw. The Strange State of Authenticated Boot and Disk Encryption on Generic Linux Distributions). Während sich Secure-Boot auch im Linux-Umfeld einigermaßen etabliert hat, tut sich im Bereich Measured-Boot noch nicht allzu viel. Eine Möglichkeit den gemessenen Bootvorgang manuell auf Vertrauenswürdigkeit hin zu überprüfen, ist die Verwendung von tpm2-totp. Wie genau das funktioniert, erläutere ich in folgendem Beitrag.

Folgende Geräte bzw. Software wurde verwendet:
  • Notebook mit TPM2-Chip
  • Arch Linux
  • tpm2-totp v0.3.0

Verified-Boot, Trusted-Boot, Secure-Boot & Measured-Boot

Da es etwas aufwendig wäre hier alle Konzepte bzw. Begriffe detailliert zu erklären, verweise ich auf folgende Seiten, die das bereits ganz gut aufbereitet haben:

Funktionsweise von tpm2-totp

Während des Bootvorgangs werden in den PCRs (flüchtiger Speicher) innerhalb des TPM-Chips (Trusted-Platform-Module) diverse Informationen des Bootvorgangs - repräsentiert durch Hashes - gespeichert. Die einzelnen Register sind bspw. innerhalb der Doku von systemd-cryptenroll aufgeführt. Bzgl. der Funktionsweise der PCRs siehe Arch-Linux-Wiki: TPM - Accessing PCR registers.

Mithilfe von tpm2-totp kann nun unter der Vorbedingung, dass das System in einem vertrauenswürdigen Zustand ist, ein OTP-Secret erzeugt werden, das dann im persistenten Speicher des TPM-Chips gespeichert wird. Diesbzgl. wird das OTP-Secret unter Berücksichtigung der zu verwendenden PCRs bzw. deren aktuellen Werten versiegelt. Während des Bootvorgangs gibt der TPM-Chip das OTP-Secret nur frei, wenn die entsprechenden PCR-Werte den Werten, die bei der Generierung des OTP-Secret vorlagen, entsprechen. Während der Generierung zeigt tpm2-totp im Terminal sowohl das generierte OTP-Secret sowie einen dazu passenden QR-Code an. Wie bei einer 2-Faktor-Authentifizierung mittels (T)OTP könnt ihr das OTP-Secret nun in eurer bevorzugten OTP-App oder auf eurem Harware-Security-Token, wie z.B. YubiKey, speichern.

Während des Bootvorgangs könnt ihr dann vor der Entschlüsselung eures vollverschlüsselten Systems den angezeigten OTP-Code eures Linux-Systems mit dem OTP-Code eurer OTP-App vergleichen. Wenn beide identisch sind, dann kann das System im Normallfall als vertrauenswürdig angesehen werden. Grundsätzlich ergibt das Ganze aber nur wirklich Sinn, wenn ihr Measured-Boot in Verbindung mit aktiviertem Secure-Boot und im besten Fall eigenen Secure-Boot-Keys einsetzt. Weitere Einschränkungen siehe Abschnitt "Limitations": Readme: tpm2-totp

tpm2-totp installieren und einrichten

Zum Installieren reicht folgender Befehl unter Arch-Linux:

sudo pacman -S tpm2-totp
Terminal / Konsole

Als nächstes erfolgt die Generierung des OTP-Secrets. Optional lässt sich ein Passwort angeben, mit dem später der QR-Code bzw. das OTP-Secret im Notfall wiederhergestellt werden kann. Zudem kann das OTP-Secret bei Bedarf so nachträglich gegen andere PCRs versiegelt werden. Standardmäßig wird das OTP-Secret gegen die PCRs 0,2 und 4 versiegelt, was sich optional aber auch anpassen lässt. Für mich reicht bspw. PCR 7, weil das der PCR für Secure-Boot ist, welches ich mit eigenen Secure-Boot-Keys verwende. Das OTP-Secret lässt sich dabei wie folgt generieren:

sudo tpm2-totp -P 123456 -p 7 generate
Terminal / Konsole
Warnung Passwort innerhalb Befehl eingeben

Aus Sicherheitsgründen sollten Passwörter eigentlich nicht innerhalb eines Terminal-Befehls direkt angegeben werden, weil sie sonst z.B. in der Shell-History landen. Für Bash gibt es hier z.B. die Einstellung HISTCONTROL mit der konfiguriert werden kann, dass Befehle, die mit einem Leerzeichen anfangen, nicht in der History landen.

Im Master-/Main-Branch von tpm2-totp (siehe GitHub) gibt es eine entsprechende Option, so dass das Passwort per Standard-Input angegeben werden kann.

tpm2-totp: OTP-Secret erzeugen

Speichert euch das angezeigte OTP-Secret in eurer OTP-App weg. Anschließend ist es sinnvoll, sicherzustellen, dass tpm2-totp nun auf Basis des im TPM-Chip gespeicherten OTP-Secrets den gleichen OTP-Code, wie eure OTP-App generiert. Hierfür könnt ihr den folgenden Befehl verwenden:

sudo tpm2-totp -t calculate
2022-06-08 15:48:02 302122
Terminal / Konsole

In eurer OTP-App sollte der gleiche OTP-Code angezeigt werden, wenn alles richtig funktioniert. Sollten die OTP-Codes nicht übereinstimmen, dann überprüft, ob auf beiden Geräten die Uhrzeit korrekt ist.

tpm2-totp-initramfs-Hook unter Arch-Linux einrichten

Damit nun beim Booten ein OTP-Code erzeugt und angezeigt wird, muss das initramfs entsprechend angepasst werden. Unter Arch-Linux ist dazu die HOOKS=()-Zeile in mkinitcpio.conf anzupassen. Wenn ihr keine systemd-Hooks und auch kein Plymouth verwendet, dann würde es reichen tpm2-totp hinzuzufügen:

[...]
HOOKS=(base udev autodetect keyboard keymap consolefont modconf block tpm2-totp encrypt lvm2 filesystems fsck)
[...]
Datei: /etc/mkinitcpio.conf

Wenn ihr nun euren Rechner neustartet, dann sollte an der Stelle, an der ihr bei einem vollverschlüselten System nach eurer LUKS-Passphrase oder z.B. eurer TPM2-PIN gefragt werden, auch ein OTP-Code angezeigt werden. Alle 30 Sekunden wird dieser zudem aktualisiert bzw. ein neuer angezeigt.

Fazit

Solange es keine brauchbare bzw. alltagstaugliche Lösung für Verified-/Trusted-Boot unter Linux gibt, ist tpm2-totp eine simple Möglichkeit, um nebst Secure-Boot mittels Measured-Boot sicherzustellen, dass sich das eigene System nach dem Booten in einem vetrauenswürdigen Zustand befindet.

Feedback

Für Feedback zum Beitrag, seien es Fragen, Korrigierungen und/oder Anregungen, könnt ihr mir gerne eine Nachricht per E-Mail oder Mastodon schreiben (siehe Kontakt).