Experience Embedded

Professionelle Schulungen, Beratung und Projektunterstützung

Linux Secure Boot in der Praxis

Autor: Dipl.-Ing. (FH) Holger Dengler, linutronix GmbH

Beitrag - Embedded Software Engineering Kongress 2017

 

Heutige Embedded Systems sind zunehmend Angriffen aus unterschiedlichen Quellen ausgesetzt. Daher wird es immer wichtiger, dass der auf diesen Systemen ausgeführte Code aus vertrauenswürdigen Quellen kommt. Der Code-Integritätsprüfung während des Boot-Vorgangs kommt hierbei eine zentrale Bedeutung zu, da nahezu alle weiteren Überprüfungen davon abhängen, welcher Bootloader bzw. welcher Linux-Kernel auf dem System ausgeführt wird.

Linux Secured Integrity

Nicht erst seitdem IoT und Industrie 4.0 in aller Munde sind, wachsen die Vernetzungsanforderungen an Embedded Systeme stetig. Die Anwendungsfälle reichen hier vom Bereitstellen und Zusammenführen der Betriebsdaten über einen entfernten Wartungszugang bis hin zu der kompletten Integration einer Steuerungskomponente in eine vernetzte Anlage.

Waren serielle Schnittstellen vor 10 Jahren die einzigen Zugänge zu einem Steuerungssystem, so ist es heute nicht unüblich, dass ein Embedded System über mehr als eine Schnittstelle mit der Außenwelt kommunizieren kann, wie z.B. über Ethernet, Wi-Fi, Bluetooth, CAN, Modbus oder ZigBee. Dabei erhöht jede Schnittstelle auch die Angriffsfläche des Systems.

Wirksame Maßnahmen für den Schutz dieser Schnittstellen bieten mittlerweile viele Betriebssysteme wie z.B. Linux, die auf Embedded Systemen zum Einsatz kommen. Diese greifen aber nur, wenn auch die vom Hersteller zur Verfügung gestellte Software zum Einsatz kommt.

Der Bootvorgang

Der Bootvorgang ist hierbei von zentraler Bedeutung, da hier entschieden wird, welcher Linux-Kernel geladen wird. Da diese Aufgabe wiederum vom Bootloader übernommen wird, ist auch darauf zu achten, welcher Bootloader nach dem Reset eines Systems zum Einsatz kommt.

Auch wenn sich der Bootvorgang im Detail von Plattform zu Plattform leicht unterscheidet, so werden normalerweise die folgenden Schritte durchlaufen:

  1. ROM Code: Initialisierung der CPU

  2. ROM Code: Laden des Bootloaders

  3. Bootloader: Ausführen des Bootloaders

  4. Bootloader: Laden/Konfigurieren des Linux-Kernels

  5. System: Ausführen des Linux-Kernels

  6. System: Ausführen der Applikationen

 

Bootloader und Linux-Kernel werden dazu aus nicht-flüchtigen Speicherbereichen (z.B. NOR- bzw. NAND-Flash) geladen (siehe Abbildung 1, PDF).

Bei diesem Vorgang ist meist einzig die Integrität des ROM-Codes gesichert, da er aus einem read-only Speicher auf dem System-On-Chip (SoC ) selbst kommt. Viele Hersteller von Hardware für Embedded Systeme bieten in diesem ROM Code-Mechanismen an, um schon beim Laden des Bootloaders dessen Integrität mit Hilfe einer kryptographischen Signatur zu überprüfen. Ebenso bieten alle aktuellen Bootloader Funktionen an, auch den Linux-Kernel und -Devicetree mit Hilfe einer solches Signatur zu überprüfen. Damit modifiziert sich der Ablauf beim Start eines Embedded Systems:

  1. ROM Code: Initialisierung der CPU

  2. ROM Code: Laden des Bootloaders

  3. ROM Code: Integritätscheck des Bootloaders (falls Signatur korrekt)

  4. Bootloader: Ausführen des Bootloaders

  5. Bootloader: Laden des Linux-Kernels

  6. Bootloader: Integritäts-Check des Linux-Kernels/Devicetrees

  7. System: Ausführen des Linux-Kernels (falls Signatur korrekt)

 

Mittels kryptographischer Verfahren ist nun neben dem ROM-Code auch die Integrität des Bootloaders sowie des Linux-Kernels/Devicetrees gesichert. Je nach Konfiguration wird das Embedded System den Bootvorgang abbrechen, sobald einer dieser Integritätschecks fehlschlägt (siehe Abbildung 2, PDF).

Integritätsprüfung des Bootloaders

Wie in Abbildung 2 (siehe PDF) dargestellt, wird der Integritätscheck des Bootloaders durch den ROM-Loader sichergestellt. Da der ROM-Code von SoC zu SoC unterschiedlich ist, ist es nun an der Zeit, an einem konkreten Beispiel einer Hardware die Vorgänge und Abläufe darzulegen. Viele aktuelle SoCs bringen diese Features in der einen oder anderen Ausprägung aber ebenfalls mit und eignen sich für die Umsetzung ebenso.

Der i.mx7d von NXP als einer der Vertreter der i.mx-Familie bietet einen sogenannten High Assurance Boot, Version 4 (HABv4), mit dem die Integrität geladener Images schon vor der Ausführung des eigentlichen Bootloaders geprüft werden kann.

Die Basis der Integritätsprüfung ist dabei einer von bis zu vier SystemRoot-Keys (SRK), welche mit dem Image geladen werden. Damit dem Prozess nicht beliebige SRKs als "Root of Trust" untergeschoben werden können, gibt es auf dem Chip eine One-Time Programmable Area (OTP), in der der Hash der für dieses Gerät gültigen SRKs abgelegt wird. Die Konfiguration dieser Hashes in den OTP-Fuses obliegt dem Hersteller. Er legt damit fest, mit welchen Schlüsseln gültige Code-Signaturen für dieses Gerät erzeugt werden können (siehe Abbildung 3, PDF).

Im weiteren Verlauf werden nun ein CommandSequenceFileKey-Zertifikat (CSFK) und ein ImageKey-Zertifikat (IMGK) geladen. Beide Zertifikate müssen eine gültige Unterschrift des verwendeten SRKs haben.

Der HABv4 lässt sich über ein Command-Sequence-File (CSF) parametrieren. Die darin enthaltenen Sequenzschritte sind durchaus sicherheitsrelevant, weshalb auch die Integrität dieses CSF geschützt werden muss. Dazu wird der HAB die Signatur des CSF vor der Ausführung mit dem CSFK-Zertifikat prüfen (siehe Abbildung 4, PDF).

Das Bootloader-Image wird durch den Hersteller ebenfalls signiert. Nach dem Laden des Images wird der HAB die Integrität des Bootloader-Images mit dem IMGK-Zertifikat prüfen, bevor er die Kontrolle als letzten Schritt an den Bootloader übergibt (siehe Abbildung 5, PDF).

Integritätsprüfung des Kernels

Durch die drei Prüfschritte des HAB (SRK-Check, CSF-Ceck und Image-Check) ist nun die Code-Integrität des Bootloaders sichergestellt. Dieser kann nun im weiteren Verlauf des Bootvorgangs die Integrität von Linux-Kernel und Devicetree prüfen und damit sicherstellen. Das Verfahren hierzu wurde bereits im Beitrag "Linux Secured Integrity schützt vor Angriffen aus dem Netz" (ESE-Kongress 2013, Holger Dengler) vorgestellt.

Schlüsselräume und "Root of Trust"

Wie Abbildung 3 (siehe PDF) zeigt, nutzt der HAB einen der zur Verfügung stehenden SRK als "Root of Trust". Mithilfe dieser Basis müssen sich alle weiteren Zertifikate verifizieren lassen. Das heißt im Umkehrschluss, der Eigentümer der SRKs muss die Zertifikate für CSFK und IMGK signieren und gibt damit deren Verwendung im Ablauf des Boot-Prozesses frei.

Im Bootloader (z.B. u-boot) wird die Integrität des Linux-Kernels ebenfalls mithilfe eines Zertifikats bzw. des darin enthaltenen Public Keys geprüft. Dieses Zertifikat muss nicht zwingend vom SRK oder den darunterliegenden CFSK oder IMGK signiert werden. Da der Public Key bei der Erzeugung des u-boot-Images ins Image integriert wird, kann dieses Zertifikat auch aus einem anderen Schlüsselraum stammen.

Äquivalent dazu verwendet auch der Linux-Kernel für Integritätschecks von Modules und ggf. Teilen des Rootfilesystems einen eigenen Schlüssel als "Root of Trust". Wie beim Bootloader kann auch dieser Schlüssel aus einem anderen Schlüsselraum stammen, da seine Integrität mit der Integrität des gesamten Kernel-Images gewährleistet wird.

Das mag auf den ersten Blick verwirrend sein, bietet aber die maximale Flexibilität bei der Erstellung einer Trust Chain und der dazu notwendigen Public-Key-Infrastruktur. Wer diese Freiheit nicht nicht nutzen möchte bzw. eine einfachere Struktur der Übersichtlichkeit halber vorzieht, kann durch Verwendung z.B. des IMGK im Bootloader und im Kernel-Image diese Komplexität drastisch reduzieren (siehe Abbildung 6, PDF).

Fazit

Das High Assurance Boot-Konzept von NXP und die Integritätsprüfungen von Bootloader (u-boot) und Linux-Kernel greifen Hand in Hand und ermöglichen eine lückenlose Integritätsprüfung vom Reset bis in den Linux-Userspace. Die dabei verwendeten Schlüsselräume können hierbei den jeweiligen Anforderungen und Gegebenheiten angepasst werden. Sollen Board-Hersteller, System-Anbieter und Endkunde getrennte Schlüssel nutzen können, so bietet dieses Konzept die notwendigen Freiräume. Soll zur Reduzierung der Komplexität das Setup auf einen Schlüsselraum eingeschränkt werden, so ist auch das ohne Probleme umsetzbar.

Die Integritätsprüfung des Codes während des Bootvorgangs wird somit zum belastbaren, sicheren Rückgrat aller weiteren Security-Bemühungen im Embedded System.

 

Beitrag als PDF downloaden


Open Source - unsere Trainings & Coachings

Wollen Sie sich auf den aktuellen Stand der Technik bringen?

Dann informieren Sie sich hier zu Schulungen/ Seminaren/ Trainings/ Workshops und individuellen Coachings von MircoConsult zum Thema Open Source / Embedded Software Engineering.

 

Training & Coaching zu den weiteren Themen unseren Portfolios finden Sie hier.


Open Source - Fachwissen

Wertvolles Fachwissen zum Thema Open Source / Embedded Software Engineering steht hier für Sie zum kostenfreien Download bereit.

Zu den Fachinformationen

 
Fachwissen zu weiteren Themen unseren Portfolios finden Sie hier.