In vielen aktuellen Rechnern steckt ein Chip, den zwar niemand nutzt, um dessen Sinn sich aber Mythen ranken. Dabei könnte sich das Trusted Platform Module durchaus für sinnvolle Aufgaben eignen, wie erste Beispielanwendungen zeigen. Deren Reifegrad lässt aber Wünsche offen.
Vertrauenswürdige und sichere Computerplattformen sind das vorgebliche Ziel des TPM (Trusted Platform Module, siehe Kasten “Trusted Computing”). Doch bislang verströmt dieser Chip vor allem Verunsicherung. Unabhängig von der Eignung für Kopierschutzmechanismen oder wofür seine Macher die einzelnen Funktionen des TPM auch ersonnen haben: Einige taugen durchaus auch für sinnvolle, friedliche Anwendungen. Die folgenden Seiten zeigen, wie ein TPM SSL-Zertifikate schützt, wie es kryptographische Schlüssel sicher speichert, um mit ihnen den Inhalt der Festplatte zu chiffrieren, und wie es sicheres Booten ermöglicht.
|
Trusted Computing |
|---|
|
Das ebenso viel versprechende wie umstrittene Trusted Computing (TC) soll die Sicherheit von Rechnersystemen erhöhen [10]. TC erlaubt es den Komponenten, sich gegenseitig zu authentisieren und so eine vertrauenswürdige Umgebung aus Hard- und Software zu schaffen. Als Kernelement fungiert ein Hardwarebaustein, den das TCG-Konsortium (Trusted Computing Group, [11]) spezifiziert hat. Sein Name: Trusted Platform Module (TPM). Kritiker leiten aus dem Funktionsumfang des TPM ab, dass sich das Modul vor allem für DRM-Aufgaben eignet (Digital Rights Management, also Kopierschutz) und vermuten darin die wahre Intention der Protagonisten. Die TCG überarbeitet und aktualisiert laufend die Spezifikation und macht den größten Teil öffentlich zugänglich. Erste Versionen der Spec dienen jetzt schon als Grundlage für die millionenfache Produktion von TPM-Chips und deren Integration in entsprechende Systeme. Krypto-Chip mit vielen FunktionenVorangegangene Artikel im Linux-Magazin haben bereits darüber berichtet, welche kryptographischen Verschlüsselungs- und Signaturfunktionalitäten im TPM realisiert sind [12], wie sich die Versionen der Spezifikation unterscheiden und wie Kernel und Userspace das TPM unter Linux ansprechen [10]. Ohne sichere Betriebssysteme laufen die Funktionen des TPM ins Leere, der Chip ist nur in sicherer Umgebung sinnvoll zu nutzen und stellt nur dann dem Anwender nützliche Dienste zur Verfügung. Entgegen der optimistischen Annahmen der ersten Jahre, hat sich vor allem dieser Aspekt als sehr schwierig und bestenfalls langfristig umsetzbar herausgestellt. TC-taugliche Betriebssysteme fehlen nochKomplette Betriebssysteme, die TC unterstützen, sind auch im Jahre 2006 nur am fernen Horizont zu erahnen. Allerdings existieren einige Anwendungsszenarien, in denen Applikationen von einem TPM profitieren. |
Bereits beim Bootprozess entscheidet sich, wie vertrauenswürdig ein System ist. Es muss von Beginn an sicherstellen, dass kein Angreifer die beteiligten Komponenten ausgetauscht oder modifiziert hat. In der wissenschaftlichen Literatur [5] beginnen sich hierfür die Begriffe “Trusted Boot”, “Secure Boot” und “Authenticated Boot” zu etablieren. Trusted Boot meint, dass ein Sicherheitsmodul die relevanten Systemkomponenten lediglich überprüft. Es analysiert und misst das startende System; dieser Vorgang heißt auch Monitoring.
Vorsicht beim Booten
Wie Trusted Boot misst auch ein Secure Boot das System, Letzterer löst aber zusätzlich Aktionen aus, falls der gemessene Ist-Wert und der erwartete Referenzwert differieren (Enforcing). Zum Beispiel bricht er den Bootvorgang ab, löst eine Kernel Panic aus oder meldet die Abweichung auf der Konsole.
Authenticated Boot kennt beim Enforcing nicht nur falsch und richtig, sondern unterscheidet mehrere Szenarien. Der prüfenden Instanz ist eine Menge von Referenzwerten bekannt, die je eine gültige Plattformkonfigurationen darstellen. Jede Konfiguration gilt zum Beispiel nur für eine Betriebssystemversion mit einem bestimmten Patch-Level. Damit kann die prüfende Instanz anhand der gemessenen Ist-Werte entscheiden, welche Plattformkonfigurationen vorliegen und wie weiter zu verfahren ist.
Ab der Wurzel
Sinnvoll ist sicheres Booten nur, wenn es die Integrität der gesamten Plattform vom Systemstart bis in die Anwendungsebene erfasst und überprüft und gegebenenfalls abbricht. Maßgeblich sind dabei der TPM-Chip sowie Teile des Bios. Nur diese beiden Komponenten gelten als vertrauenswürdig, weil ein Angreifer keinen Einfluss auf sie hat. Das Bios dient als unbedingter Vertrauensanker (CRTM, Core Root of Trust for Measurement), der TPM-Chip ist sein kryptographischer Erfüllungsgehilfe.
Mit dem Systemstart übernimmt das Bios die Kontrolle (Abbildung 1), misst mit Hilfe des TPM-Chips relevante Teile des Bios und speichert die ermittelten Hashwerte in volatilen PCRs (Platform Configuration Register). TPM-Chips verfügen nur über wenige PCRs – bei TPM 1.1b typischerweise 16, bei TPM 1.2 mindestens 24. Als Ausweg hat die TCG das so genannte Extending ersonnen: Dieser Algorithmus verknüpft den aktuellen Registerinhalt eines PCR mit einem neuen Messergebnis, das als aktualisierter Hashwert im selben PCR landet.

Abbildung 1: Sicheres Booten beginnt bei einem Vertrauensanker (CRTM, Core Root of Trust for Measurement) und setzt sich über den Bios-Code und den Master Boot Record (MBR) zum Bootloader fort (etwa Grub), der wiederum seine Konfiguration sowie den Kernel prüft.
Mit diesem Trick gelingt es, eine Vielzahl von Einzelmessungen auf die begrenzte Zahl von PCRs abzubilden. Die TCG-Spezifikation [1] gibt beispielsweise vor, dass das Bios in PCR 0 bis 3 diverse Bios-Parameter und die Motherboard-Konfiguration speichert (Tabelle 2). In PCR 4 misst das Bios den IPL-Code (Initial Program Loader). Der beginnt üblicherweise im Master Boot Record (MBR) eines passenden Bootdevice und umfasst den kompletten Bootloader, etwa Lilo oder Grub.
|
Tabelle 1: |
|
|---|---|
|
CA |
Certification Authority |
|
CRTM |
Core Root of Trust for Measurement |
|
CSR |
Certificate Signing Request |
|
DIR |
Data Integrity Register |
|
DRM |
Digital Rights Management |
|
EK |
Endorsement Key |
|
EMSCB |
European Multilaterally Secure Computing Base |
|
IPL |
Initial Program Loader |
|
MBR |
Master Boot Record |
|
PCR |
Platform Configuration Register |
|
RPC |
Remote Procedure Call |
|
SRK |
Storage Root Key |
|
SSL |
Secure Sockets Layer |
|
TCG |
Trusted Computing Group |
|
TCPA |
Trusted Computing Platform Alliance |
|
TCS |
TSS Core Service |
|
TC |
Trusted Computing |
|
TDDL |
TCPA Device Driver Library |
|
TPM |
Trusted Platform Module |
|
TSPI |
TSP Interface |
|
TSP |
TSS Service Provider |
|
TSS |
TCG Software Stack |
|
Tabelle 2: Platform |
|
|---|---|
|
PCR |
Verwendung bei TPM-Chips der Version 1.1b |
|
CRTM, Bios and Platform Extensions |
|
|
1 |
Platform Configuration |
|
2 |
Option ROM Code |
|
3 |
Option ROM Configuration and Data |
|
4 |
IPL Code (usually the MBR) |
|
5 |
IPL Code Configuration and Data (for use by the IPL code) |
|
6 |
State Transition and Wake Events |
|
7 |
Reserved for future usage |
|
8-15 |
For application usage |
In die Grube
Das Bios übergibt die Kontrolle an den Bootloader. Falls dieser TCG-tauglich ausgestattet ist, fährt er mit den Messungen fort und sammelt sie per Extending in PCR 5. Geeignete Messobjekte sind die Bootloader-Konfigurationsdatei, die initiale RAM-Disk, der Linux-Kernel oder beliebige Dateien des Root-Dateisystems. Bis in die Applikationsebene konsequent angewendet, führt dies konzeptionell zu einer durchgängigen Vertrauenskette (Chain of Trust), die sich auf die Messwerte des TPM-Chips stützt.
Jedes Glied der Kette muss das Vertrauen stützen, indem es seinen Nachfolger misst, die Resultate mit Referenz-Hashwerten vergleicht und entsprechend agiert. Das Bios darf die Kontrolle an den Bootloader nur übergeben, wenn der Inhalt von PCR 4 mit einem definierten Referenzwert übereinstimmt. Der Bootloader darf seinerseits den Linux-Kernel nur starten, wenn etwa der Inhalt von PCR 5 einem Referenzwert entspricht.
Bedingt praxistauglich
Die Konzepte in die Praxis umzusetzen ist alles andere als trivial, sodass es bislang nur wenige Implementierungen gibt. Immerhin entwickelt IBM im Rahmen der Integrity Measurement Architecture [6] entsprechende Software, zudem existieren TCG-Patches für Grub vom EMSCB-Projekt [7] sowie von den IBM-Labs aus Japan [2]. Diese Patches decken aber höchstens ein Secure-Boot-Szenario ab.
Fürs eigene Experimentieren bietet sich IBMs Grub TCG Patch an. Mit dieser Erweiterung nimmt Grub beim Booten Messungen des Systems mit Hilfe des TPM-Chips vor. Unter [2] gibt es ein ausführliches Howto sowie Patches für die Grub-Versionen 0.94 bis 0.97 [3]. Bisher beherrscht der TCG-fähige Grub nur Messungen; eine Auswertung der Ergebnisse oder gar Enforcing sind gar nicht vorgesehen.
Vereinfacht dargestellt misst Grub Stage 1 den Code von Grub Stage 2. Letzterer prüft die Konfigurationsdatei »grub.conf«. Die Grub-Konfigurationsdatei darf beliebige Dateien des Linux-Systems spezifizieren (Listing 1, Zeile 2), die Grub Stage 2 ebenfalls misst. Danach übergibt Grub die Kontrolle an den Linux-Kernel und der Bootvorgang läuft seinen gewohnten Gang.
|
Listing 1: |
|---|
01 title Suse Linux 10.0 (Trusted Boot with TPM support) 02 measure (hd0,2)/Pfad/Dateiname 9 03 kernel --pcr=8 (hd0,0)/vmlinuz root=/dev/hda3 04 initrd --pcr=8 (hd0,0)/initrd |
Geänderter Grub
Das Howto beschreibt die Vorgehensweise. Sowohl das Patchen als auch das Kompilieren von Grub verlaufen problemlos. Es empfiehlt sich, die aktuelle Bootpartition auf einen USB-Memorystick zu kopieren und den gepatchten Grub auf dem Stick zu installieren. Damit bleibt das Linux-System unverändert; beim nächsten Reboot kann vom Memorystick gebootet werden.
Bei richtiger Konfiguration von »grub.conf« und »device.map« versieht der gepatchte Bootloader seinen Dienst wie gewohnt und misst nun zusätzlich die spezifizierten Dateien. Dazu muss allerdings der TPM-Chip im Bios aktiviert sein. Die TPM-Anwendung Trusted Grub zeigt sich für den Benutzer eher unspektakulär: Er kann sich die Hashwerte der einzelnen PCRs an der Grub-Kommandozeile ausgegeben lassen; mehr geht nicht.
Zu aufwändig
Die durchgehende Vertrauenskette vom Systemstart bis in die Anwendungsebene verlangt einen immensen Aufwand. Die bisher bekannten technischen Implementierungen setzen daher auch nur einen kleinen Teil der Konzepte um und sind in der Praxis nicht besonders hilfreich. Der konzeptionelle Knackpunkt ist das Management der Referenzwerte für eine große Zahl von individuellen Plattformen.
Eine noch zu bestimmende Instanz muss die korrekten Referenzwerte ermitteln, auf der Plattform hinterlegen und bei Bedarf (zum Beispiel Bios-Update, Security Patches des Kernels) aktualisieren. Es gibt bisher kaum Ansätze, die brauchbare Antworten zum Beispiel auf folgende Fragen geben:
- Wer kann auf welche Weise eine initiale Vertrauenskette
erzeugen? - Wie sind autorisierte und unautorisierte Änderungen sicher
voneinander unterscheidbar? - Was ist erforderlich, damit autorisierte Änderungen als
atomare Vorgänge ablaufen? - Muss der Plattform-Eigentümer in den Änderungsprozess
eingebunden werden?
Auch wenn Windows Vista ein Secure Bootstrapping anbieten soll und Microsoft damit wieder Bewegung in den Markt bringt: Es ist zu erwarten, dass sich sicheres Booten auf PCs in absehbarer Zeit nicht etabliert. Vorstellbar ist bisher nur, dass einige Hersteller diese Konzepte in Plattformen mit geringer Änderungshäufigkeit und niedrigem Individualisierungsgrad umsetzen, also zum Beispiel in PDAs, Mobiltelefonen und Embedded Systems.
Keep it simple
Viel mehr Erfolg auf Standard-PCs verspricht, den TPM-Chip als sicheren Schlüsselspeicher und als Krypto-Modul einzusetzen – ganz wie eine fest integrierte Smartcard. Das Betriebssystem und die Anwendungen auf einem System greifen aber nicht direkt über die Hardwaretreiber auf das TPM zu. Die Interface-Spezifikation des TCG Software Stack (TSS) legt fest, dass alles über einen zentralen Dienst abläuft. Nur dieser Dienst kommuniziert über den TPM-Gerätetreiber mit dem Kryptochip. Die primären Designziele des TSS sind:
- Den alleinigen, zentralen Zugangspunkt zu den Funktionen des
TPM bereitstellen (durch das TSS Service Provider Interface) - Der synchronisierte Zugriff aufs TPM (durch den TPM Request
Manager) - Das transparente Handling von Interna, etwa das Byte Ordering
und das Alignment (intern durch den TSS) - Das Verwalten der TPM-Ressourcen (durch den TSS Core
Service)
Der TSS ist in vier unabhängige Subsysteme unterteilt, die über spezifizierte Interfaces kommunizieren:
- TSS Service Provider (TSP)
- TSS Core Service (TCS)
- TCPA Device Driver Library (TDDL)
- TPM Device Driver
Seit Version 2.6.12 enthält der Standardkernel bereits TPM Device Driver. Die anderen drei Subsysteme sind beim Trousers-Projekt [4] verfügbar. Dessen Software untersteht der CPL (Common Public License von IBM). Trousers implementiert den TSS Core Service als Unix-Dienst »tcsd« und die TCG Service Provider als Shared Libraries. Zusätzlich kümmert es sich um die persistente Speicherung von Daten und um den Remote-Zugriff auf den »tcsd«. Ein früherer Artikel [10] hat bereits die Installation von Trousers und der zugehörigen TPM-Tools beschrieben (Abbildung 2).

Abbildung 2: Vom Trousers-Projekt stammt neben dem TCG Software Stack auch eine Sammlung von Kommandozeilenwerkzeugen, die zum Beispiel die Version des TPM-Chips ermitteln oder den Public Endorsement Key ausgeben.
Einer für alle
Programme, die das TPM verwenden möchten, müssen einen so genannten TCG Service Provider nutzen. Jede Applikation erhält einen eigenen TSP, der in ihrem Prozesskontext läuft. Die TSPs kommunizieren mit dem TSS Core Service des Betriebssystems (bei Trousers ist dies »tcsd«), der ihnen die gewünschten Funktionen zur Verfügung stellt. Die TPM Device Driver Library (TDDL) sorgt zwischen dem TCS und dem TPM-Gerätetreiber für die Abstraktion verschiedener Implementierungen der Hardware (Abbildung 3).

Abbildung 3: Lokale Prozesse dürfen nur über ihr TSP-Interface (Service Provider) auf den zentralen TCS (Core Service) zugreifen. Nur dieser Dienst darf per TDDL (Device Driver Library) das Trusted Platform Module nutzen und über RPC (Remote Procedure Call) mit fernen Plattformen kommunizieren.
Für die Anpassung an individuelle Anforderungen sorgt die Konfigurationsdatei »tcsd.conf«. Sie ist sehr verständlich aufgebaut, zusätzlich gibt es eine Manpage. Die Datei erlaubt unter anderem das Einstellen diverser Logfiles und Angaben darüber, welche Werte der TCS-Daemon in den verschiedenen PCRs ablegt. Aus Sicherheitsgründen ist eine interessante Funktion per Default deaktiviert: Der TCS-Daemon reagiert auf Wunsch auch auf Anfragen aus dem Netzwerk. Die jeweils lokalen TCS-Dienste zweier Systemen kommunizieren dazu über eine RPC-Schnittstelle.
PCR auslesen
Trousers ergänzt also alle Komponenten, die ein Linux-Programm braucht, um die Funktionalitäten des TPM-Chips vom Userspace aus zu nutzen. Listing 2 illustriert dies anhand eines C-Programms, das die grundlegenden Eigenschaften des TPM-Chips nacheinander ausliest und diese Werte ausgibt.
|
Listing 2: |
|---|
001 #include "tpm_tspi.h"
002
003 int main(int argc, char **args){
004 BYTE *rgbPcrValue, *rgbNumPcrs, *pNumSlots,
005 *pNumDIRs, *pManufacturer;
006 UINT32 respDataLength;
007
008 TSS_HCONTEXT hContext;
009 TSS_HTPM hTPM;
010 TSS_RESULT result;
011 UINT32 exitCode, numPcrs, subCap, i, j;
012
013 // Create Context
014 result = Tspi_Context_Create(&hContext);
015 if (result != TSS_SUCCESS) {
016 exit(result);
017 }
018
019 // Connect to Context
020 result = Tspi_Context_Connect(hContext, NULL);
021 if (result != TSS_SUCCESS) {
022 Tspi_Context_FreeMemory(hContext, NULL);
023 Tspi_Context_Close(hContext);
024 exit(result);
025 }
026
027 // Retrieve TPM object of context
028 result = Tspi_Context_GetTpmObject(hContext, &hTPM);
029 if (result != TSS_SUCCESS) {
030 Tspi_Context_FreeMemory(hContext, NULL);
031 Tspi_Context_Close(hContext);
032 exit(result);
033 }
034
035 // Define sub capability
036 subCap = TSS_TPMCAP_PROP_MANUFACTURER;
037
038 // Retrieve manufacturer info
039 result = Tspi_TPM_GetCapability(hTPM,
040 TSS_TPMCAP_PROPERTY, sizeof(UINT32),
041 (BYTE *)&subCap, &respDataLength, &pManufacturer);
042 if (result != TSS_SUCCESS) {
043 Tspi_Context_FreeMemory(hContext, NULL);
044 Tspi_Context_Close(hContext);
045 exit(result);
046 }
047 fprintf(stdout, "This TPM Chip was manufactured by: ");
048 for (i = 0; i < respDataLength; i++) {
049 fprintf(stdout, "%c", pManufacturer[i]);
050 }
051 fprintf(stdout, "n");
052
053 // Redefine sub capability
054 subCap = TSS_TPMCAP_PROP_SLOTS;
055
056 // Retrieve number of RSA slots
057 result = Tspi_TPM_GetCapability(hTPM,
058 TSS_TPMCAP_PROPERTY, sizeof(UINT32),
059 (BYTE *)&subCap, &respDataLength, &pNumSlots);
060 if (result != TSS_SUCCESS) {
061 Tspi_Context_FreeMemory(hContext, NULL);
062 Tspi_Context_Close(hContext);
063 exit(result);
064 }
065 fprintf(stdout, "This TPM Chip provides %u RSA slots.n",
066 *pNumSlots);
067
068 // Redefine sub capability
069 subCap = TSS_TPMCAP_PROP_DIR;
070
071 // Retrieve number of DIR registers
072 result = Tspi_TPM_GetCapability(hTPM,
073 TSS_TPMCAP_PROPERTY, sizeof(UINT32),
074 (BYTE *)&subCap, &respDataLength, &pNumDIRs);
075 if (result != TSS_SUCCESS) {
076 Tspi_Context_FreeMemory(hContext, NULL);
077 Tspi_Context_Close(hContext);
078 exit(result);
079 }
080 fprintf(stdout, "This TPM Chip provides %u DIR registers.n",
081 *pNumDIRs);
082
083 // Redefine sub capability
084 subCap = TSS_TPMCAP_PROP_PCR;
085
086 // Retrieve number of PCR's
087 result = Tspi_TPM_GetCapability(hTPM,
088 TSS_TPMCAP_PROPERTY, sizeof(UINT32),
089 (BYTE *)&subCap, &respDataLength, &rgbNumPcrs);
090 if (result != TSS_SUCCESS) {
091 Tspi_Context_FreeMemory(hContext, NULL);
092 Tspi_Context_Close(hContext);
093 exit(result);
094 }
095 if (respDataLength != sizeof(UINT32)) {
096 Tspi_Context_FreeMemory(hContext, NULL);
097 Tspi_Context_Close(hContext);
098 exit(result);
099 }
100 numPcrs = *(UINT32 *)rgbNumPcrs;
101 fprintf(stdout, "This TPM Chip provides %i PCR register. Current values are:n", numPcrs);
102
103 for (i = 0; i < numPcrs; i++) {
104 result = Tspi_TPM_PcrRead(hTPM, i, &respDataLength, &rgbPcrValue);
105 fprintf(stdout, "PCR#%02u: ", i);
106 for (j = 0; j < respDataLength; j++) {
107 fprintf(stdout, "%02x ", rgbPcrValue[j] & 0xff);
108 }
109 fprintf(stdout, "n");
110 }
111
112 if (result != TSS_SUCCESS) {
113 fprintf(stderr, "Failed to read PCR.n");
114 exitCode = 1;
115 }
116 else {
117 fprintf(stdout, "Success.n");
118 exitCode = 0;
119 }
120
121 Tspi_Context_FreeMemory(hContext, NULL);
122 Tspi_Context_Close(hContext);
123 exit(exitCode);
124 }
|
Der erste Schritt eines Programms in Richtung TSS-API-Nutzung erzeugt einen so genannten TSPI-Kontext (Zeilen 13 bis 17), an den es sich im nächsten Schritt bindet (Zeilen 19 bis 25) und ein TPM-Objekt anfordert (Zeilen 27 bis 33). Über dieses Objekt laufen die weiteren Anfragen, zum Beispiel nach den Fähigkeiten des Moduls mit »Tspi_TPM_GetCapability«. Damit ermittelt das Tool den Hersteller (Zeilen 35 bis 51), die Anzahl der RSA-Slots (Zeilen 53 bis 66), die Anzahl der DIRs (Data Integrity Register, Zeilen 68 bis 81) sowie die Anzahl und den Inhalt der PCRs (Platform Configuration Register, Zeilen 83 bis 119).
Es bietet sich an, das Programm in der von den TPM-Tools angebotenen Entwicklungsumgebung zu übersetzen. Dazu wird der Quellcode unter dem Namen »tpm_readProperties.c« ins Verzeichnis »src/cmds« der TPM-Tools kopiert und in die Automake-Konfigurationsdatei »Makefile.am« aufgenommen. Als Vorbild eignet sich das Trousers-Programm »tpm_sealdata.c«. Listing 3 zeigt die zu ergänzenden Zeilen.
|
Listing 3: Makefile |
|---|
01 bin_PROGRAMS = tpm_sealdata tpm_readProperties 02 AM_CPPFLAGS = -I$(top_builddir)/include -D_LINUX 03 LDADD = $(top_builddir)/lib/libtpm_tspi.la -ltspi 04 05 tpm_sealdata_SOURCES = tpm_sealdata.c 06 tpm_readProperties_SOURCES = tpm_readProperties.c |
Ein anschließendes »make check« integriert den Code in die Autoconf-Umgebung und kompiliert das Programm. Der Aufruf »tpm_readProperties« gibt dann die grundlegenden Eigenschaften des TPM-Chips aus (Abbildung 4) – vorausgesetzt, dass der Daemon »tcsd« bereits läuft. Die PCR-Werte sind besonders interessant, wenn Trusted Grub während des Bootvorgangs Messungen vorgenommen und dort abgelegt hat.

Abbildung 4: Das C-Programm aus dem Listing 2 nutzt das TSPI, um nach Informationen im TPM-Chip zu fahnden. Seine Erkenntnisse gibt das Programm auf der Konsole aus: Den Hersteller, die Anzahl der RSA-Slots sowie der DIR- und OCR-Register. Letztere enthalten zum Beispiel die Messwerte eines Trusted Grub.
Dieses einfache Beispiel mag interessierten Programmierern als Ausgangsbasis dienen, um die Möglichkeiten des TPM-Chips zu erforschen und eigene Applikationen zu entwickeln.
TPM-Engine für OpenSSL
Beispiel für eine anspruchsvolle Anwendung ist eine TPM-Engine [4] für OpenSSL. Sie stammt ebenfalls vom Trousers-Projekt und nutzt die Möglichkeit von OpenSSL, kryptographische Funktionen an externe Module (so genannte Engines) zu delegieren, statt die eigene Software-Implementierung zu verwenden. Diese Engines sind typischerweise Hardware-basiert, etwa Smartcards oder TPM-Chips. Das Beispiel baut eine Root-CA auf und schützt deren privaten Schlüssel per TPM-Chip. Das Verfahren bindet den privaten Schlüssel und mit ihm die Root-CA direkt an den Rechner. Offline-Angriffe auf die CA werden nahezu unmöglich – selbst wenn jemand die Festplatte klaut, findet er dort den privaten Schlüssel nicht.
Um das Zusammenspiel von OpenSSL mit dem TPM-Chip zu testen, ist OpenSSL in der Version 0.9.8 erforderlich. Wer die Quellen selber übersetzt, sollte beim Configure-Aufruf die Optionen »–prefix« und »–openssldir« geeignet belegen. Damit legt er seine neu entstehende OpenSSL-Version in ein eigenes Verzeichnis und schont vorhandene Installationen. Beim Übersetzen der TPM-Engine [4] empfiehlt es sich, im »./configure«-Aufruf die Option »–with-openssl« auf den Pfad der soeben installierten OpenSSL-Version zu setzen. Die TPM-Bibliothek »libtpm« landet dann im Verzeichnis »lib/engines« des OpenSSL-Installationspfads.
Neuer Schlüssel
Außerdem entsteht beim Übersetzen das Programm »create_tpm_key«. Mit dessen Hilfe ist es möglich, den privaten Schlüssel der Root-CA zu erzeugen. Der Aufruf »create_tpm_key TPM_ROOT_CA.key« generiert – unter Nutzung des TSS-API – ein RSA-Objekt im TPM-Chip, das den privaten und öffentlichen Schlüssel der Root-CA repräsentiert. Alle kryptographischen Operationen mit dem privaten Schlüssel laufen nur innerhalb des TPM ab, der Schlüssel muss dazu das TPM nicht verlassen.
Dummerweise sind die RSA-Slots im TPM-Chip volatil, also flüchtig. Ihr Inhalt geht beim Ausschalten des Rechners verloren. Es gilt daher, das RSA-Objekt persistent zu speichern. Das Programm »create_tpm_key« exportiert dazu das RSA-Objekt aus dem TPM-Chip, allerdings nur chiffriert, und zwar mit dem öffentlichen Schlüssel des Storage Root Key (SRK, Abbildung 5). Den SRK hat das TP-Modul beim »TPM_TakeOwnership» selbst erzeugt und hält den privaten Teil geheim.

Abbildung 5: Die OpenSSL-TPM-Engine verwendet ein Schlüsselpaar, das nur im TPM-Chip funktioniert. Bei einem Export (für dauerhaftes Speichern) sorgt der SRK (Storage Root Key) dafür, dass das geschützte Objekt nur im Original-TPM-Chip entschlüsselbar ist.
Root-CA-Schlüssel sichern
Die bei »create_tpm_key« angegebene Datei »TPM_ROOT_CA.key« enthält in Binärform das RSA-Objekt der Root-CA, das durch den SRK geschützt ist. Mit dabei sind der öffentliche Anteil des RSA-Schlüsselpaars sowie Modulus, Exponent und Koeffizient, obwohl diese nicht schützenswert wären. Der Import der Key-Datei in eine andere TPM-Plattform würde scheitern, da deren Chip einen anderen SRK hätte und somit die Datei nicht korrekt entschlüsseln könnte.
Die folgenden Befehlssequenzen sind relativ zum gewählten OpenSSL-Installationspfad. Um die Root-CA anzulegen, muss die Umgebungsvariable »OPENSSL_CONF« auf die gewünschte Datei »openssl.cnf« zeigen. Dort hinterlegt der künftige CA-Betreiber die für die Root-CA gültigen Parameter, zum Beispiel den Distinguished Name (DN), und ruft das Skript »misc/CA.sh -newca« auf. Das Skript importiert den vorhandenen privaten Schlüssel »TPM_ROOT_CA.key« (auf richtigen Pfad achten), kopiert ihn in die gängige CA-Verzeichnisstruktur und nennt ihn in »cakey.pem« um.
Nun fehlt nur noch ein selbst signiertes Root-Zertifikat. Um es zu erzeugen, nutzt OpenSSL den vom TPM-Chip gesicherten privaten Schlüssel. Die Kommandozeile lautet:
./bin/openssl req -keyform engine -engine tpm -key ./demoCA/private/cakey.pem -new -x509 -out demoCA/TPM_ROOT_CA.crt
OpenSSL delegiert über die beiden Parameter »-keyform« und »-engine« die Handhabung des privaten Schlüssels der Root-CA an die TPM-Engine. OpenSSL verknüpft dann den öffentlichen Schlüssel der Root-CA mit dem Distinguished Name der Root-CA, berechnet einen Hash, lässt ihn vom TPM mit dem privaten Schlüssel des RSA-Objekts signieren und speichert das Resultat zusammen mit dem Distinguished Name und dem öffentlichen Schlüssel der Root-CA als X.509-Zertifikat in der Datei »./demoCA/TPM_ROOT_CA.crt«.
Zertifikate erzeugen
Damit diese CA neue Zertifikate erzeugen kann, verlangt sie einen Certificate Signing Request (CSR). In realen Anwendungen stammt der Request von einer Registration Authority, die vom Benutzer einen öffentlichen Schlüssel erhält und im Gegenzug seine Identität prüft. Im einfachsten Fall kümmert sich OpenSSL aber selbst um die Schlüsselerzeugung, das klappt auch ohne Mitwirkung des TPM-Chips:
./bin/openssl req -new -keyout ./demoCA/cert1.key -days 365 -nodes -out ./demoCA/cert1.req
Um diesen CSR mit dem privaten Schlüssel der Root-CA zu signieren, ist aber wieder der Einsatz der TPM-Engine erforderlich:
./bin/openssl ca -keyform engine -engine tpm -keyfile ./demoCA/private/cakey.pem -in ./demoCA/cert1.req -out ./demoCA/cert1.crt -cert ./demoCA/TPM_ROOT_CA.crt
Alle weiteren operativen Tätigkeiten der Root-CA (Widerrufen von Zertifikaten, Erzeugen von Revocation Lists und mehr) laufen ebenso ab.
Gut für die CA
Die TPM-Engine ermöglicht erstmals eine sinnvolle Nutzung des TPM-Chips. Die Integration in OpenSSL vereinfacht die Handhabung von TPM-geschützten Zertifikaten deutlich. Neben der vorgestellten Root-CA gibt es weitere Einsatzszenarien: Man könnte beispielsweise einen SSL-Webserver mit einem TPM-gesicherten X.509-Zertifikat ausstatten. Der private RSA-Key bleibt dabei im TPM-Chip und dort sogar vor einem Angreifer verborgen, der den kompletten Hauptspeicher durchsucht [9].
Gegen den Einsatz in SSL-Webservern spricht die niedrige Geschwindigkeit von RSA-Operationen im TPM. Zudem bleiben alle Sitzungsschlüssel im Hauptspeicher, sie sind also für Angreifer weiterhin erreichbar.
Dateien verschlüsseln
Verschlüsselte Dateien und Dateisysteme sind ein prädestiniertes Einsatzgebiet für das TPM. So verwundert es nicht, dass das Trousers-Projekt in seinen TPM-Tools auch ein Programm »tpm_sealdata« mitliefert, das immerhin einzelne Dateien mit Hilfe des TPM-Chips verschlüsselt (Data Binding) und auf Wunsch auch an eine spezielle Plattformkonfiguration bindet (Data Sealing). Das File lässt sich dann nur noch auf dieser unveränderten Plattform entschlüsseln.
Ein Programm für das Entschlüsseln fehlt allerdings. Immerhin ist eine Bibliothek »libtpm_unseal« vorhanden. Sie enthält eine Funktion »tpmUnsealFile«, die verschlüsselte Dateien dechiffriert. Das in Listing 4 skizzierte Programm »tpm_unseal.c« nutzt diese Funktion. Es lässt sich wie für Listing 2 beschrieben in die TPM-Tools-Entwicklungsumgebung integrieren. Um »tpm_unseal.c« gegen die vorhandene Bibliothek »libtpm_unseal« zu linken, ist im »Makefile.am« bei dem Parameter »LDADD« zusätzlich »-ltpm_unseal« anzugeben.
|
Listing 4: Datei |
|---|
01 #include "tpm_tspi.h"
02 #include "tpm_unseal.h"
03
04 int main(int argc, char **args){
05 unsigned char* plaintext_data;
06 int plaintext_size;
07 FILE* plaintext_file;
08
09 if (argc != 2) {
10 fprintf(stderr, "Usage: tpm_unseal <file>n");
11 return 3;
12 }
13
14 fprintf(stdout, "Trying to decode %sn", args[1]);
15 int result = tpmUnsealFile(args[1], &plaintext_data, &plaintext_size);
16 if (result != 0) {
17 char* errMsg = tpmUnsealStrerror(result);
18 fprintf(stdout, "Decoding failed: %sn", errMsg);
19 return 2;
20 }
21
22 if ((plaintext_file = fopen(strcat(args[1], ".decoded"), "w")) == NULL) {
23 fprintf(stderr, "Cannot open %s for writingn", args[1]);
24 return 1;
25 }
26
27 int i;
28 for (i=0; i<plaintext_size; i++) {
29 fputc(plaintext_data[i], plaintext_file);
30 }
31
32 fclose(plaintext_file);
33 fprintf(stdout, "Success! Decoded to %sn", args[1]);
34 return 0;
35 }
|
Beim Verschlüsseln von Dateien geht »tpm_sealdata« in mehreren Schritten vor. Zunächst lässt es den Zufallszahlengenerator des TPM-Chips einen symmetrischen AES-Schlüssel mit einer Länge von 256 Bit erzeugen. Mit diesem symmetrischen Schlüssel chiffriert das Programm den Klartext der Datei. Die Verschlüsselung erfolgt nicht durch den TPM-Chip – der hat gar keine AES-Funktionalität -, sondern durch die Kryptobibliotheken von OpenSSL.
Der TPM-Chip kommt erst wieder zum Einsatz, um den symmetrischen Schlüssel zu schützen. Dies geschieht völlig analog zu dem bereits vorgestellten Beispiel der Root-CA: Der TPM-Chip erzeugt ein neues RSA-Objekt, mit dem er den symmetrischen AES-Schlüssel chiffriert. Um das RSA-Objekt zu speichern, schützt der Chip das Objekt mit seinem SRK und exportiert das Resultat an »tpm_sealdata«.
Vertrauenskette
Dadurch entsteht eine Vertrauenskette: Die Wurzel des Vertrauens ist der SRK, dessen privater Schlüssel im TPM-Chip liegt und ihn nie verlässt. Nur mit diesem SRK lässt sich das RSA-Objekt entschlüsseln und nur dieses RSA-Objekt kann den symmetrischen AES-Schlüssel dechiffrieren und nur mit diesem symmetrischen Schlüssel kommt ein Programm an den Klartext der Daten (siehe Abbildung 6).

Abbildung 6: Das Programm »tpm_sealdata« verschlüsselt Dateien mit einem AES-Key. Den chiffriert es mit einem RSA-Schlüssel, der seinerseits vom SRK (Storage Root Key) des TPM-Chips geschützt ist. Der SRK bleibt im TPM.
Eine Datei nach dieser Verschlüsselung ist exemplarisch in Abbildung 7 zu sehen. Die einzelnen Segmente sind in einer Base-64-kodierten Datei mit TSS-Headern und -Footern zusammengefasst. Hinter dem Header »TSS Key« verbirgt sich das mit dem SRK verschlüsselte RSA-Objekt. Auf »ENC KEY« folgt der mit dem RSA-Objekt verschlüsselte AES-Schlüssel. Erst hinter »ENC DAT« stehen die verschlüsselten Daten.

Abbildung 7: Die mit TPM-Unterstützung verschlüsselte Datei enthält zu Beginn den SRK-geschützten RSA-Schlüssel, danach folgt der RSA-verschlüsselte AES-Key, am Ende stehen die Nutzdaten, die mit AES chiffriert sind.
Beim Aufruf von »tpm_sealdata« dürfen laut Manpages keine Passwörter für den so genannten Owner und den SRK vergeben sein. Falls diese bereits bei der Übernahme des TPM-Chips gesetzt worden sein sollten, ändert der TPM-Tools-Befehl »tpm_changeownerauth« diese Werte. Dann funktioniert auch das Entschlüsseln einer Datei mit dem Programm »tpm_unseal« problemlos.
Nur ein Beispiel
Das Verschlüsseln von Daten mit Unterstützung des TPM-Chips ist in der vorhandenen Implementierung ein gelungenes Proof of Concept – mehr aber nicht. Daten mit dieser Methode zu schützen ist wenig praktikabel. Dazu dauern das Erzeugen der Zufallszahlen für den AES-Schlüssel und das Generieren der RSA-Objekte im TPM-Chip zu lange. Einzelne Dateien zu verschlüsseln bringt in der Regel ebenfalls keinen signifikanten Sicherheitsgewinn: Beim Entschlüsseln landen die Daten wieder auf der Festplatte und hinterlassen dort ihre Spuren. Interessanter wäre es, ganze Dateisysteme zu chiffrieren und den dabei verwendeten symmetrischen Key mit Hilfe des TPM-Chips zu sichern.
Bei den meisten Szenarien darf man getrost darüber philosophieren, ob sie tatsächlich einen merklichen Gewinn an Sicherheit erreichen. Auf der Negativseite stehen neue Risiken, zum Beispiel wenn der TPM-Chip eines Tages seinen Dienst versagt. Daher ist auch die TPM-Engine für OpenSSL eher eine nette Demonstration der technischen Möglichkeiten als ein praktikables Werkzeug.
Festzuhalten bleibt, dass es erste Ansätze gibt, die Konzepte rund um Trusted Computing auch in die Praxis umsetzen. Mit den TPM-Tools steht ein Werkzeug zum Verschlüsseln von Daten bereit und die OpenSSL-Engine erlaubt es, eine TPM-geschützte Root-CA aufzubauen. Trusted Booting steckt noch in den Anfängen. Es könnte jedoch in Virtualisierungsprojekten helfen, bei denen ein Gastsystem sicher wissen will, auf welcher Hardware es gerade läuft.
Auf viele Fragen gibt es noch keine zufrieden stellenden Antworten. So etwa bei der Migration einzelner Schlüssel oder gar dem SRK im Falle eines Problems mit dem TPM, hier liegt noch vieles im Argen. Folglich bleibt es meist bei interessanten TPM-Konzeptstudien – wirkliche Praxistauglichkeit hat noch kein Projekt erreicht. (fjl)
|
Infos |
|---|
|
[1] Trusted Computing Group, “PC Client Specifications”: [https://www.trustedcomputinggroup.org/specs/PCClient] [2] TCG-Patch für Grub als Teil eines Trusted Boot: [http://trousers.sourceforge.net/grub.html] [3] Grub-Quellen: [ftp://alpha.gnu.org/gnu/grub/] [4] Trousers-Quellcode: [http://sourceforge.net/project/showfiles.php?group_id=126012] [5] Sean W. Smith, “Trusted Computing Platforms – Design and Applications”: Springer Verlag, 2005, ISBN 0-387-23916-2 [6] IBM Research, “Integrity Measurement Architecture”: [http://domino.research.ibm.com/comm/research_projects.nsf/pages/ssd_ima.index.html] [7] Applied Data Security Group an der Ruhr-Universität Bochum, “Trusted Grub”: [http://www.prosec.ruhr-uni-bochum.de/trusted_grub.html] [8] Trusted Computing Group, “TPM Software Stack (TSS)”: [https://www.trustedcomputinggroup.org/groups/software/] [9] Trapkit, “SSL Key/Certificate Finder”: [http://www.trapkit.de/research/sslkeyfinder/] [10] Wilhelm Dolle, Christoph Wegener, “Trusted Computing für Linux – Stand der Dinge”: Linux-Magazin 04/06, S. 100 [11] TCG, Trusted Computing Group: [http://www.trustedcomputinggroup.org] [12] Wilhelm Dolle, “In Chips We Trust – das Trusted Platform Module der TCPA”: Sonderheft Linux-Magazin 02/04, S. 26 |
|
Die Autoren |
|---|
|
Wilhelm Dolle ist CISSP (Certified Information System Security Professional) und BSI-IT-Grundschutz-Auditor. Er arbeitet als Senior Security Consultant für die Hi-Solutions AG in Berlin. Dr. Michael Nerb arbeitet bei T-Systems in München als IT-Architekt im Bereich Security und Open Source/Linux. Er ist Lehrbeauftragter an der Ludwig-Maximilians-Universität München. Dr. Christoph Wegener ist freier Berater mit den Schwerpunkten IT-Sicherheit und Linux/Open Source und Leiter des Bereichs Business Development bei der Gits AG in Bochum. |





