Wie kann ich Bytes mit dem TPM-Modul eines Computers verschlüsseln?
CryptProtectData
Windows bietet eine (relativ) einfache API zum Verschlüsseln eines Blobs mit dem CryptProtectData
API, mit der wir eine benutzerfreundliche Funktion umschließen können:
public Byte[] ProtectBytes(Byte[] plaintext)
{
//...
}
Die Details von ProtectBytes
sind weniger wichtig als die Idee, dass Sie es ganz einfach verwenden können:
- Hier sind die Bytes, die mit einem geheimen Schlüssel verschlüsselt werden sollen
System
- Gib mir den verschlüsselten Blob zurück
Der zurückgegebene Blob ist nicht dokumentiert Dokumentationsstruktur , die alles enthält, was zum Entschlüsseln und Zurückgeben der Originaldaten erforderlich ist (Hash-Algorithmus, Verschlüsselungsalgorithmus, Salt, HMAC-Signatur usw.).
Der Vollständigkeit halber ist hier die Beispiel-Pseudocode-Implementierung ProtectBytes
, die Crypt API
zum Schutz von Bytes verwendet:
public Byte[] ProtectBytes(Byte[] plaintext)
{
//Setup our n-byte plaintext blob
DATA_BLOB dataIn;
dataIn.cbData = plaintext.Length;
dataIn.pbData = Addr(plaintext[0]);
DATA_BLOB dataOut;
//dataOut = EncryptedFormOf(dataIn)
BOOL bRes = CryptProtectData(
dataIn,
null, //data description (optional PWideChar)
null, //optional entropy (PDATA_BLOB)
null, //reserved
null, //prompt struct
CRYPTPROTECT_UI_FORBIDDEN || CRYPTPROTECT_LOCAL_MACHINE,
ref dataOut);
if (!bRes) then
{
DWORD le = GetLastError();
throw new Win32Error(le, "Error calling CryptProtectData");
}
//Copy ciphertext from dataOut blob into an actual array
bytes[] result;
SetLength(result, dataOut.cbData);
CopyMemory(dataOut.pbData, Addr(result[0]), dataOut.cbData);
//When you have finished using the DATA_BLOB structure, free its pbData member by calling the LocalFree function
LocalFree(HANDLE(dataOut.pbData)); //LocalFree takes a handle, not a pointer. But that's what the SDK says.
}
Wie mache ich dasselbe mit dem TPM?
Der obige Code ist nur zum Verschlüsseln von Daten für den lokalen Computer nützlich. Die Daten werden mit dem System
Konto als Schlüsselgenerator verschlüsselt ( Details sind zwar interessant, aber unwichtig ). Das Endergebnis ist, dass ich Daten (z. B. einen Festplattenverschlüsselungs-Hauptschlüssel) verschlüsseln kann, die nur vom lokalen Computer entschlüsselt werden können.
Jetzt ist es Zeit, noch einen Schritt weiter zu gehen. Ich möchte einige Daten verschlüsseln (z. B. einen Hauptschlüssel für die Festplattenverschlüsselung), die nur vom lokalen TPM entschlüsselt werden können. Mit anderen Worten, ich möchte die TEE (Qualcomm Trusted Execution Environment ) im folgenden Blockdiagramm für Android durch das TPM in Windows ersetzen :
Hinweis : Mir ist klar, dass das TPM keine Datensignatur ausführt (oder wenn dies der Fall ist, garantiert es nicht, dass das Signieren derselben Daten jedes Mal dieselbe Binärausgabe liefert). Aus diesem Grund wäre ich bereit, "RSA-Signatur" durch "Verschlüsselung eines 256-Bit-Blobs mit einem hardwaregebundenen Schlüssel" zu ersetzen. .
Wo ist der Code?
Das Problem ist, dass die TPM-Programmierung auf MSDN vollständig undokumentiert ist . Es ist keine API verfügbar, um Vorgänge auszuführen. Stattdessen müssen Sie sich eine Kopie des Software Stack (auch bekannt als TSS) der Trusted Computing Group suchen , herausfinden, welche Befehle mit Nutzdaten in welcher Reihenfolge an das TPM gesendet werden sollen, und die Tbsip_Submit_Command- Funktion von Window aufrufen , um Befehle direkt zu senden:
TBS_RESULT Tbsip_Submit_Command(
_In_ TBS_HCONTEXT hContext,
_In_ TBS_COMMAND_LOCALITY Locality,
_In_ TBS_COMMAND_PRIORITY Priority,
_In_ const PCBYTE *pabCommand,
_In_ UINT32 cbCommand,
_Out_ PBYTE *pabResult,
_Inout_ UINT32 *pcbOutput
);
Windows verfügt über keine übergeordnete API zum Ausführen von Aktionen.
Dies ist das moralische Äquivalent zum Versuch, eine Textdatei zu erstellen, indem SATA-E / A-Befehle an Ihre Festplatte ausgegeben werden .
Warum nicht einfach Hosen benutzen?
Die Trusted Computing Group (TCG) hat eine eigene API definiert: TCB Software Stack (TSS) . Eine Implementierung dieser API wurde von einigen Personen erstellt und heißt TrouSerS . Ein Mann hat das Projekt dann auf Windows portiert .
Das Problem mit diesem Code ist, dass er nicht in die Windows-Welt portierbar ist. Sie können es beispielsweise nicht in Delphi oder in C # verwenden. Es benötigt:
- OpenSSL
- pThread
Ich möchte nur, dass der Code etwas mit meinem TPM verschlüsselt.
Das Obige CryptProtectData
erfordert nichts anderes als das, was sich im Funktionskörper befindet.
Was ist der entsprechende Code zum Verschlüsseln von Daten mit dem TPM? Wie andere angemerkt haben, müssen Sie wahrscheinlich die drei TPM-Handbücher konsultieren und die Blobs selbst erstellen . Es handelt sich wahrscheinlich um den TPM_seal
Befehl. Obwohl ich denke , dass ich Daten nicht versiegeln möchte , denke ich, dass ich sie binden möchte :
Bindung - verschlüsselt Daten mit dem TPM-Bindeschlüssel, einem eindeutigen RSA-Schlüssel, der von einem Speicherschlüssel abstammt. Versiegeln - verschlüsselt Daten auf ähnliche Weise wie das Binden, gibt jedoch zusätzlich einen Zustand an, in dem sich TPM befinden muss, damit die Daten entschlüsselt (entsiegelt) werden können.
Ich versuche, die drei erforderlichen Bände zu lesen, um die 20 benötigten Codezeilen zu finden:
Aber ich habe keine Ahnung, was ich lese. Wenn es irgendeine Art von Tutorial oder Beispielen gäbe, könnte ich eine Chance haben. Aber ich bin völlig verloren.
Also fragen wir Stackoverflow
Auf die gleiche Weise konnte ich Folgendes bereitstellen:
Byte[] ProtectBytes_Crypt(Byte[] plaintext)
{
//...
CryptProtectData(...);
//...
}
kann jemand das entsprechende Äquivalent liefern:
Byte[] ProtectBytes_TPM(Byte[] plaintext)
{
//...
Tbsip_Submit_Command(...);
Tbsip_Submit_Command(...);
Tbsip_Submit_Command(...);
//...snip...
Tbsip_Submit_Command(...);
//...
}
das macht das gleiche, außer dass ein in System
LSA gesperrter Schlüssel im TPM gesperrt ist?
Beginn der Forschung
Ich weiß nicht genau, was Binden bedeutet. Wenn man sich jedoch TPM Main - Teil 3 Befehle - Spezifikation Version 1.2 ansieht, wird bind erwähnt :
10.3 TPM_UnBind
TPM_UnBind nimmt den Daten-Blob, der das Ergebnis eines Tspi_Data_Bind-Befehls ist, und entschlüsselt ihn für den Export an den Benutzer. Der Anrufer muss die Verwendung des Schlüssels autorisieren, der den eingehenden Blob entschlüsselt. TPM_UnBind arbeitet blockweise und hat keine Ahnung von einer Beziehung zwischen einem Block und einem anderen.
Was verwirrend ist, ist, dass es keinen Tspi_Data_Bind
Befehl gibt.
Forschungsaufwand
Es ist schrecklich, wie niemand sich jemals die Mühe gemacht hat, das TPM oder seinen Betrieb zu dokumentieren. Es ist, als hätten sie ihre ganze Zeit damit verbracht, sich dieses coole Ding auszudenken , mit dem sie spielen wollten, wollten sich aber nicht mit dem schmerzhaften Schritt befassen, es für etwas nutzbar zu machen.
Beginnend mit dem (jetzt) kostenlosen Buch Ein praktischer Leitfaden für TPM 2.0: Verwenden des Trusted Platform-Moduls im neuen Zeitalter der Sicherheit :
Kapitel 3 - Kurzanleitung zu TPM 2.0
Das TPM hat Zugriff auf einen selbst generierten privaten Schlüssel, sodass es Schlüssel mit einem öffentlichen Schlüssel verschlüsseln und den resultierenden Blob dann auf der Festplatte speichern kann. Auf diese Weise kann das TPM eine praktisch unbegrenzte Anzahl von Schlüsseln zur Verwendung bereithalten, ohne jedoch wertvollen internen Speicher zu verschwenden. Auf der Festplatte gespeicherte Schlüssel können gelöscht, aber auch gesichert werden, was den Designern als akzeptabler Kompromiss erschien.
Wie kann ich einen Schlüssel mit dem öffentlichen Schlüssel des TPM verschlüsseln?
Kapitel 4 - Bestehende Anwendungen, die TPMs verwenden
Anwendungen, die das TPM verwenden sollten, dies aber nicht tun
In den letzten Jahren hat die Anzahl der webbasierten Anwendungen zugenommen. Dazu gehören webbasierte Sicherung und Speicherung. Eine große Anzahl von Unternehmen bietet inzwischen solche Dienste an. Soweit uns bekannt ist, lässt jedoch keiner der Clients für diese Dienste den Benutzer den Schlüssel für den Sicherungsdienst für ein TPM sperren. In diesem Fall wäre es sicherlich schön, wenn der TPM-Schlüssel selbst durch Duplizieren auf mehreren Computern gesichert würde. Dies scheint eine Chance für Entwickler zu sein.
Wie sperrt ein Entwickler einen Schlüssel für das TPM?
Kapitel 9 - Erben
GEBRAUCHSFALL: SPEICHERPASSWÖRTER SPEICHERN
In einer typischen Kennwortdatei werden gesalzene Kennwort-Hashes gespeichert. Die Überprüfung besteht darin, ein angegebenes Kennwort zu salzen, zu hashen und mit dem gespeicherten Wert zu vergleichen. Da die Berechnung kein Geheimnis enthält, wird die Kennwortdatei offline angegriffen.
In diesem Anwendungsfall wird ein TPM-generierter HMAC-Schlüssel verwendet. In der Kennwortdatei wird ein HMAC des gesalzenen Kennworts gespeichert. Die Überprüfung besteht darin, das angegebene Passwort zu salzen und zu HMACen und es mit dem gespeicherten Wert zu vergleichen. Da ein Offline-Angreifer nicht über den HMAC-Schlüssel verfügt, kann der Angreifer durch Ausführen der Berechnung keinen Angriff starten.
Das könnte funktionieren. Wenn das TPM einen geheimen HMAC-Schlüssel hat und nur mein TPM den HMAC-Schlüssel kennt, könnte ich "Sign (auch bekannt als TPM-Verschlüsselung mit privatem Schlüssel)" durch "HMAC" ersetzen. Aber dann kehrt er sich in der nächsten Zeile komplett um:
TPM2_Create, Angabe eines HMAC-Schlüssels
Es ist kein TPM-Geheimnis, wenn ich den HMAC-Schlüssel angeben muss. Die Tatsache, dass der HMAC-Schlüssel nicht geheim ist, ist sinnvoll, wenn Sie feststellen, dass dies das Kapitel über kryptografische Dienstprogramme ist, das das TPM bereitstellt. Anstatt SHA2, AES, HMAC oder RSA selbst schreiben zu müssen, können Sie das, was das TPM bereits herumliegen hat, wiederverwenden.
Kapitel 10 - Tasten
Als Sicherheitsgerät ist die Fähigkeit einer Anwendung, Schlüssel zu verwenden und sie gleichzeitig in einem Hardwaregerät zu schützen, die größte Stärke des TPM. Das TPM kann extern generierte Schlüssel sowohl generieren als auch importieren. Es unterstützt sowohl asymmetrische als auch symmetrische Tasten.
Ausgezeichnet! Wie machst du das!?
Schlüsselgenerator
Die wohl größte Stärke des TPM ist seine Fähigkeit, einen kryptografischen Schlüssel zu generieren und sein Geheimnis innerhalb einer Hardwaregrenze zu schützen. Der Schlüsselgenerator basiert auf dem TPM-eigenen Zufallszahlengenerator und ist nicht auf externe Zufallsquellen angewiesen. Dadurch werden Schwachstellen aufgrund schwacher Software mit unzureichender Entropiequelle beseitigt.
Kann das TPM kryptografische Schlüssel generieren und seine Geheimnisse innerhalb einer Hardwaregrenze schützen? Ist so, wie?
Kapitel 12 - Plattformkonfigurationsregister
PCRs zur Autorisierung
GEBRAUCHSFALL: VERSIEGELN EINES SCHLÜSSELSCHEIBENSCHLÜSSELS FÜR DEN PLATTFORMZUSTAND
Verschlüsselungsanwendungen auf der gesamten Festplatte sind weitaus sicherer, wenn ein TPM den Verschlüsselungsschlüssel schützt, als wenn er auf derselben Festplatte gespeichert ist und nur durch ein Kennwort geschützt ist. Erstens verfügt die TPM-Hardware über einen Anti-Hammering-Schutz (eine detaillierte Beschreibung des TPM-Wörterbuch-Angriffsschutzes finden Sie in Kapitel 8), wodurch ein Brute-Force-Angriff auf das Kennwort unpraktisch wird. Ein Schlüssel, der nur durch Software geschützt ist, ist weitaus anfälliger für ein schwaches Passwort. Zweitens ist ein auf der Festplatte gespeicherter Softwareschlüssel viel einfacher zu stehlen. Nehmen Sie die Festplatte (oder ein Backup der Festplatte) und Sie erhalten den Schlüssel. Wenn ein TPM den Schlüssel enthält, muss die gesamte Plattform oder zumindest die Festplatte und das Motherboard gestohlen werden.
Durch das Versiegeln kann der Schlüssel nicht nur durch ein Passwort, sondern auch durch eine Richtlinie geschützt werden. Eine typische Richtlinie sperrt den Schlüssel für PCR-Werte (den Softwarestatus), die zum Zeitpunkt des Versiegelns aktuell sind. Dies setzt voraus, dass der Status beim ersten Start nicht beeinträchtigt wird. Jegliche vorinstallierte Malware, die beim ersten Start vorhanden ist, wird in den PCRs gemessen, und somit wird der Schlüssel für einen gefährdeten Softwarestatus versiegelt. Ein weniger vertrauenswürdiges Unternehmen verfügt möglicherweise über ein Standard-Disk-Image und ein Siegel für PCRs, die dieses Image darstellen. Diese PCR-Werte würden auf einer vermutlich vertrauenswürdigeren Plattform vorberechnet. Ein noch anspruchsvolleres Unternehmen würde TPM2_PolicyAuthorize verwenden und mehrere Tickets bereitstellen, die eine Reihe vertrauenswürdiger PCR-Werte autorisieren. In Kapitel 14 finden Sie eine detaillierte Beschreibung der Richtlinienautorisierung und ihrer Anwendung zur Lösung des PCR-Sprödigkeitsproblems.
Obwohl ein Passwort auch den Schlüssel schützen könnte, gibt es auch ohne ein TPM-Schlüsselpasswort einen Sicherheitsgewinn. Ein Angreifer konnte die Plattform ohne Angabe eines TPMkey-Kennworts starten, sich jedoch nicht ohne den Benutzernamen und das Kennwort des Betriebssystems anmelden. Die OSsecurity schützt die Daten. Der Angreifer kann ein alternatives Betriebssystem starten, z. B. von einer Live-DVD oder einem USB-Stick anstatt von der Festplatte, um die Anmeldesicherheit des Betriebssystems zu umgehen. Diese unterschiedliche Startkonfiguration und Software würde jedoch die PCR-Werte ändern. Da diese neuen PCRs nicht mit den versiegelten Werten übereinstimmen würden, würde das TPM den Entschlüsselungsschlüssel nicht freigeben und die Festplatte könnte nicht entschlüsselt werden.
Ausgezeichnet! Dies ist genau der Anwendungsfall, den ich zufällig möchte. Dies ist auch der Anwendungsfall, für den Microsoft das TPM verwendet. Wie mache ich es!?
Also habe ich das ganze Buch gelesen und es hat nichts Nützliches geliefert. Das ist ziemlich beeindruckend, weil es 375 Seiten umfasst. Sie fragen sich, was das Buch enthielt - und wenn ich zurückblicke, habe ich keine Ahnung.
Deshalb geben wir die endgültige Anleitung zur Programmierung des TPM auf und wenden uns stattdessen einer Dokumentation von Microsoft zu:
Aus dem Microsoft TPM Platform Crypto-Provider Toolkit . Es wird genau erwähnt, was ich tun möchte:
Der Endorsement Key oder EK
Der EK wurde entwickelt, um eine zuverlässige kryptografische Kennung für die Plattform bereitzustellen. Ein Unternehmen verwaltet möglicherweise eine Datenbank der Endorsement Keys, die zu den TPMs aller PCs in seinem Unternehmen gehören, oder ein Rechenzentrums-Fabric-Controller verfügt möglicherweise über eine Datenbank der TPMs in allen Blades. Unter Windows können Sie den im Abschnitt „Platform Crypto Provider in Windows 8“ beschriebenen NCrypt-Anbieter verwenden, um den öffentlichen Teil des EK zu lesen.
Irgendwo im TPM befindet sich ein privater RSA-Schlüssel. Dieser Schlüssel ist dort eingesperrt - von der Außenwelt nie zu sehen. Ich möchte, dass das TPM etwas mit seinem privaten Schlüssel signiert (dh es mit seinem privaten Schlüssel verschlüsselt).
Ich möchte also die grundlegendste Operation, die es möglicherweise geben kann:
Verschlüsseln Sie etwas mit Ihrem privaten Schlüssel. Ich frage (noch) nicht einmal nach den komplizierteren Sachen:
- "Versiegeln" basierend auf dem PCR-Zustand
- Erstellen eines Schlüssels und Speichern in einem flüchtigen oder nichtflüchtigen Speicher
- Erstellen eines symmetrischen Schlüssels und Versuch, ihn in das TPM zu laden
Ich frage nach der grundlegendsten Operation, die ein TPM ausführen kann. Warum ist es unmöglich, Informationen darüber zu erhalten?
Ich kann zufällige Daten bekommen
Ich schätze, ich war glitschig, als ich sagte, dass die RSA-Signierung das grundlegendste ist, was das TPM tun kann. Die meisten grundlegende Sache , die TPM gefragt werden kann , tun , ist mir zufälliges Bytes geben. Dass ich herausgefunden habe, wie es geht:
public Byte[] GetRandomBytesTPM(int desiredBytes)
{
//The maximum random number size is limited to 4,096 bytes per call
Byte[] result = new Byte[desiredBytes];
BCRYPT_ALG_HANDLE hAlgorithm;
BCryptOpenAlgorithmProvider(
out hAlgorithm,
BCRYPT_RNG_ALGORITHM, //AlgorithmID: "RNG"
MS_PLATFORM_CRYPTO_PROVIDER, //Implementation: "Microsoft Platform Crypto Provider" i.e. the TPM
0 //Flags
);
try
{
BCryptGenRandom(hAlgorithm, @result[0], desiredBytes, 0);
}
finally
{
BCryptCloseAlgorithmProvider(hAlgorithm);
}
return result;
}
Die schicke Sache
Mir ist klar, dass die Anzahl der Personen, die das TPM verwenden, sehr gering ist. Deshalb hat niemand auf Stackoverflow eine Antwort. Ich kann also nicht zu gierig werden, um eine Lösung für mein gemeinsames Problem zu finden. Aber das, was ich wirklich tun möchte, ist, einige Daten zu "versiegeln" :
- Präsentieren Sie dem TPM einige Daten (z. B. 32 Byte Schlüsselmaterial).
- Lassen Sie das TPM die Daten verschlüsseln und geben Sie eine undurchsichtige Blob-Struktur zurück
- Bitten Sie später das TPM, den Blob zu entschlüsseln
- Die Entschlüsselung funktioniert nur, wenn die PCR-Register des TPM dieselben sind wie während der Verschlüsselung.
Mit anderen Worten:
Byte[] ProtectBytes_TPM(Byte[] plaintext, Boolean sealToPcr)
{
//...
}
Byte[] UnprotectBytes_TPM(Byte[] protectedBlob)
{
//...
}
Kryptographie Next Gen (Cng, auch bekannt als BCrypt) unterstützt TPM
Die ursprüngliche Kryptographie-API in Windows wurde als Krypto-API bezeichnet.
Ab Windows Vista wurde die Crypto-API durch die Cryptography-API: Next Generation (intern als BestCrypt , abgekürzt als BCrypt , nicht zu verwechseln mit dem Kennwort-Hashing-Algorithmus ) ersetzt.
Windows wird mit zwei BCrypt- Anbietern ausgeliefert :
- Microsoft Primitive Provider (
MS_PRIMITIVE_PROVIDER
) Standard : Standard-Software-Implementierung aller Grundelemente (Hashing, symmetrische Verschlüsselung, digitale Signaturen usw.) - Microsoft Platform Crypto Provider (
MS_PLATFORM_CRYPTO_PROVIDER
): Anbieter, der TPM-Zugriff bietet
Der Platform Crypto- Anbieter ist nicht auf MSDN dokumentiert, verfügt jedoch über Dokumentation von einer Microsoft Research-Website 2012:
TPM Platform Crypto-Provider Toolkit
Der TPM Platform Crypto Provider und das Toolkit enthalten Beispielcode, Dienstprogramme und Dokumentation für die Verwendung von TPM-bezogenen Funktionen in Windows 8. Zu den beschriebenen Subsystemen gehören der TPM-gestützte Crypto-Next-Gen (CNG) -Plattform-Crypto-Provider und die Anbieter von Attestierungsdiensten kann die neuen Windows-Funktionen verwenden. Es werden sowohl TPM1.2- als auch TPM2.0-basierte Systeme unterstützt.
Es scheint, dass Microsoft beabsichtigt, die TPM-Kryptofunktionalität mit dem Microsoft Platform Crypto Provider der Cryptography NG API zu erweitern.
Verschlüsselung mit öffentlichem Schlüssel mit Microsoft BCrypt
Vorausgesetzt, dass:
- Ich möchte eine asymmetrische RSA-Verschlüsselung durchführen (mit dem TPM).
- Microsoft BestCrypt unterstützt die asymmetrische RSA-Verschlüsselung
- Microsoft BestCrypt verfügt über einen TPM-Anbieter
Ein Weg in die Zukunft könnte darin bestehen, herauszufinden, wie das digitale Signieren mithilfe der Microsoft Cryptography Next Gen-API durchgeführt wird .
Mein nächster Schritt wird darin bestehen, den Code für die Verschlüsselung in BCrypt mit einem öffentlichen RSA-Schlüssel unter Verwendung des Standardanbieters ( MS_PRIMITIVE_PROVIDER
) zu erstellen . Z.B:
modulus
: 0xDC 67 FA F4 9E F2 72 1D 45 2C B4 80 79 06 A0 94 27 50 8209 DD 67 CE 57 B8 6C 4A 4F 40 9F D2 D1 69 FB 995D 85 0C 07 A1 F9 47 1B 56 16 6E F6 7F B9 CF 2A 58 36 37 99 29 AA 4F A8 12 E8 4F C7 82 2B 9D 72 2A 9C DE 6F C2 EE 12 6D CF F0 F2 B8 C4 DD 7C 5C 1A C8 17 51 A9 AC DF 08 22 04 9D 2B D7 F9 4B 09 DE 9A EB 5C 51 1A D8 F8 F9 56 9E F8 FB 37 9B 3F D3 74 65 24 0D FF 34 75 57 A4 F5 BF 55publicExponent
: 65537
Wenn dieser Code funktioniert, kann ich möglicherweise zur Verwendung des TPM-Anbieters ( MS_PLATFORM_CRYPTO_PROVIDER
) wechseln .
22.02.2016: Und da Apple gezwungen ist, beim Entschlüsseln von Benutzerdaten zu helfen, besteht erneut Interesse daran, wie das TPM die einfachste Aufgabe ausführen kann, für die es erfunden wurde - etwas zu verschlüsseln.
Es ist ungefähr gleichbedeutend mit jedem, der ein Auto besitzt, aber niemand weiß, wie man eines startet. Es kann wirklich nützliche und coole Dinge tun, wenn wir nur Schritt 1 überwinden könnten .
Bonuslesung
quelle
Antworten:
Grundierung
Alles was folgt ist über TPM 1.2. Beachten Sie, dass Microsoft für alle zukünftigen Windows-Versionen ein TPM 2.0 benötigt. Die 2.0-Generation unterscheidet sich grundlegend von der 1.2
Aufgrund der TPM-Entwurfsprinzipien gibt es keine einzeilige Lösung. Stellen Sie sich das TPM als einen Mikrocontroller mit begrenzten Ressourcen vor. Das Hauptziel des Designs war es, billig und dennoch sicher zu sein. Das TPM wurde also von jeglicher Logik befreit, die für einen sicheren Betrieb nicht erforderlich war. Daher funktioniert ein TPM nur, wenn Sie mindestens eine mehr oder weniger fette Software haben, die viele Befehle in der richtigen Reihenfolge ausgibt. Und diese Befehlssequenzen können sehr komplex werden. Aus diesem Grund hat TCG das TSS mit einer genau definierten API spezifiziert. Wenn Sie den Java-Weg gehen möchten, gibt es sogar eine Java-API auf hoher Ebene . Mir ist kein ähnliches Projekt für C # / .net bekannt
Entwicklung
In Ihrem Fall würde ich vorschlagen, dass Sie sich die IBM-Software TPM ansehen.
Im Paket finden Sie 3 sehr nützliche Komponenten:
Sie benötigen nicht unbedingt den Software-TPM-Emulator, sondern können auch eine Verbindung zum HW-TPM des Geräts herstellen. Sie können jedoch die ausgegebenen Befehle abfangen und die Antworten anzeigen, um zu erfahren, wie sie zusammengesetzt sind und wie sie der Befehlsspezifikation entsprechen.
Hohes Level
Voraussetzungen:
Um einen Blob zu versiegeln, müssen Sie Folgendes tun:
Zum Entsiegeln müssen Sie:
Sie können den Key-Blob in Ihrer Datenstruktur speichern, in der Sie die geschützten Bytes speichern.
Die meisten TPM-Befehle, die Sie benötigen, sind autorisierte Befehle. Daher müssen Sie bei Bedarf Autorisierungssitzungen einrichten. AFAIR das sind meistens OSAP-Sitzungen.
TPM-Befehle
Derzeit kann ich keine Debug-Version ausführen, daher kann ich Ihnen nicht die genaue Reihenfolge mitteilen. Betrachten Sie dies als eine ungeordnete Liste von Befehlen, die Sie verwenden müssen:
TPM_OSAP
TPM_CreateWrapKey
TPM_LoadKey2
TPM_Seal
Wenn Sie auch die aktuellen PCR-Werte lesen möchten:
TPM_PCRRead
quelle
Vertrauenswürdige und verschlüsselte Schlüssel
Vertrauenswürdige und verschlüsselte Schlüssel sind zwei neue Schlüsseltypen, die dem vorhandenen Kernel-Schlüsselringdienst hinzugefügt werden. Diese beiden neuen Typen sind symmetrische Schlüssel mit variabler Länge. In beiden Fällen werden alle Schlüssel im Kernel erstellt, und der Benutzerbereich sieht, speichert und lädt nur verschlüsselte Blobs. Vertrauenswürdige Schlüssel erfordern die Verfügbarkeit eines TPM-Chips (Trusted Platform Module) für mehr Sicherheit, während verschlüsselte Schlüssel auf jedem System verwendet werden können. Alle Blobs auf Benutzerebene werden der Einfachheit halber in hexadezimaler ASCII angezeigt und geladen und auf Integrität überprüft.
Vertrauenswürdige Schlüssel verwenden ein TPM, um die Schlüssel zu generieren und zu versiegeln. Die Schlüssel werden unter einem 2048-Bit-RSA-Schlüssel im TPM versiegelt und optional auf bestimmte PCR-Werte (Integritätsmessung) versiegelt und vom TPM nur entsiegelt, wenn PCRs und Blob-Integritätsprüfungen übereinstimmen. Ein geladener vertrauenswürdiger Schlüssel kann mit neuen (zukünftigen) PCR-Werten aktualisiert werden, sodass Schlüssel leicht auf neue pcr-Werte migriert werden können, z. B. wenn der Kernel und die initramfs aktualisiert werden. Mit demselben Schlüssel können viele Blobs unter verschiedenen PCR-Werten gespeichert werden, sodass mehrere Startvorgänge problemlos unterstützt werden.
Standardmäßig werden vertrauenswürdige Schlüssel unter dem SRK versiegelt, das den Standardautorisierungswert (20 Nullen) hat. Dies kann zum Zeitpunkt des Besitzes mit dem Dienstprogramm der Hose eingestellt werden :
tpm_takeownership -u -z
.keyctl print
Gibt eine ASCII-Hex-Kopie des versiegelten Schlüssels zurück, die im Standardformat TPM_STORED_DATA vorliegt. Die Schlüssellänge für neue Schlüssel wird immer in Byte angegeben. Vertrauenswürdige Schlüssel können 32 - 128 Byte (256 - 1024 Bit) groß sein. Die Obergrenze muss innerhalb der 2048-Bit-SRK-Schlüssellänge (RSA) mit allen erforderlichen Strukturen / Auffüllungen liegen.Verschlüsselte Schlüssel hängen nicht von einem TPM ab und sind schneller, da sie AES zur Ver- / Entschlüsselung verwenden. Neue Schlüssel werden aus vom Kernel generierten Zufallszahlen erstellt und mit einem angegebenen Hauptschlüssel verschlüsselt / entschlüsselt. Der Hauptschlüssel kann entweder ein vertrauenswürdiger Schlüssel oder ein Benutzerschlüsseltyp sein. Der Hauptnachteil von verschlüsselten Schlüsseln besteht darin, dass sie nur so sicher sind, wie der Benutzerschlüssel, der sie verschlüsselt, wenn sie nicht in einem vertrauenswürdigen Schlüssel verwurzelt sind. Der Hauptbenutzerschlüssel sollte daher so sicher wie möglich geladen werden, vorzugsweise zu Beginn des Startvorgangs.
Der entschlüsselte Teil der verschlüsselten Schlüssel kann entweder einen einfachen symmetrischen Schlüssel oder eine komplexere Struktur enthalten. Das Format der komplexeren Struktur ist anwendungsspezifisch und wird durch "Format" gekennzeichnet.
Beispiele für die Verwendung vertrauenswürdiger und verschlüsselter Schlüssel
Erstellen und speichern Sie einen vertrauenswürdigen Schlüssel mit dem Namen "kmk" mit einer Länge von 32 Byte:
Laden Sie einen vertrauenswürdigen Schlüssel aus dem gespeicherten Blob:
Versiegeln Sie einen vertrauenswürdigen Schlüssel unter neuen pcr-Werten erneut:
Der Erstverbraucher vertrauenswürdiger Schlüssel ist EVM, das beim Booten einen hochwertigen symmetrischen Schlüssel für den HMAC-Schutz von Dateimetadaten benötigt. Die Verwendung eines vertrauenswürdigen Schlüssels bietet starke Garantien dafür, dass der EVM-Schlüssel nicht durch ein Problem auf Benutzerebene beeinträchtigt wurde, und schützt vor Boot- und Offline-Angriffen, wenn er an bestimmte Boot-PCR-Werte gebunden ist. Erstellen und speichern Sie einen verschlüsselten Schlüssel "evm" mit dem oben genannten vertrauenswürdigen Schlüssel "kmk":
Option 1: Auslassen des 'Formats'
Option 2: 'Format' explizit als 'Standard' definieren
Laden Sie einen verschlüsselten Schlüssel "evm" aus dem gespeicherten Blob:
Andere Verwendungen für vertrauenswürdige und verschlüsselte Schlüssel, z. B. für die Festplatten- und Dateiverschlüsselung, werden erwartet. Insbesondere wurde das neue Format 'ecryptfs' definiert, um verschlüsselte Schlüssel zum Mounten eines eCryptfs-Dateisystems zu verwenden. Weitere Details zur Verwendung finden Sie in der Datei 'Documentation / security / keys-ecryptfs.txt'.
quelle
Documentation/security/keys-ecryptfs.tx
Hängt von Ihrer Absicht und Ihren Umständen ab:
Jeder dieser Anwendungsfälle (und es gibt mehr) - oder eine Kombination davon - bietet einen anderen Implementierungspfad. Stellen Sie sich das TPM als ein Schweizer Taschenmesser für kryptografische Geräte vor: Es gibt nicht viel, was Sie damit nicht tun können, aber die Benutzerfreundlichkeit leidet unter dieser Vielseitigkeit. Die Frage wechselt ständig zwischen Verschlüsselung, Signatur und Sperrung der Systemkonfiguration. Im Hauptteil dieser Antwort wird jedoch der Befehl Versiegeln berücksichtigt, um die meisten der in der Frage beschriebenen Anforderungen abzudecken.
Dafür ist der Befehl Bind gedacht (ersetzt durch den Befehl Create für TPM 2). Sie laden einen Schlüssel, der von einem TPM-gebundenen Schlüssel abgeleitet ist, und verschlüsseln ihn (oder direkt mit einem hardwaregebundenen Schlüssel). Auf diese Weise können die Daten nur mit Zugriff auf dasselbe TPM entschlüsselt werden.
Ich bin mir nicht sicher, ob es eine gute Idee ist, diesen gesamten Prozess zu replizieren. Zum einen muss an keiner Stelle des Prozesses eine Signaturoperation verwendet werden. Es scheint, dass sich die Keystore-API zum Zeitpunkt der Entwicklung von Android 5 auf Signatur- und Überprüfungsvorgänge beschränkte. Ich vermute, dass das Festplattenverschlüsselungsteam sein Bestes getan hat, um mit dem zu arbeiten, was es hatte, und einen Algorithmus entwickelt hat, bei dem einer der Zwischenschlüssel mit einer Signaturoperation unter Verwendung eines gespeicherten TEE-Schlüssels abgeleitet wurde, wodurch der gesamte Prozess an eine Hardware gebunden wurde. gebundener Schlüssel nur auf der Plattform verfügbar - da dies zu diesem Zeitpunkt nur durch Signieren möglich war. Sie müssen sich jedoch nicht auf diese Weise einschränken, wenn Sie Zugriff auf ein TPM haben, wodurch Sie mehr Funktionen erhalten, als Sie für nötig gehalten haben!
Dies ist falsch. Beide Versionen von TPM unterstützen das Signieren.
Das macht keinen Sinn. Wenn Sie dieselben Daten mit demselben Schlüssel signieren , wird dieselbe Signatur erstellt. Möglicherweise verwechseln Sie den Signiervorgang mit dem Anführungsvorgang, bei dem eine Nonce gemischt wird.
Dies sollte eigentlich die bevorzugte Option sein, obwohl beide mit einem TPM möglich sind. Siehe oben.
Leider gibt es nicht viel zu dokumentieren. Die Win-API ist auf einige TBS-Funktionen beschränkt, die eine Ebene vom Treiber entfernt sind.
Nein, wenn Sie ein TSS hätten, müssten Sie es nicht verwenden
Tbsip_submit_Command()
. Das ist der springende Punkt bei einem TSS - die Details auf niedriger Ebene werden weg abstrahiert.Immer noch wahr für TPM 1, aber für TPM 2 gibt es TSS.MSR .
Richtig.
Es ist nicht klar, dass dies eine unüberwindliche Herausforderung ist. Der Zugriff auf TrouSerS über ein Interop sollte dem Umschreiben des gesamten Datenstrukturierungscodes vorzuziehen sein. Auch gab es
doTSS
zum Zeitpunkt des Schreibens die Frage.Die Frage enthält ein Zitat, das den Unterschied zwischen den beiden Befehlen beschreibt, daher sollte es nicht viel Verwirrung geben. Das Versiegeln ähnelt dem Binden, mit der zusätzlichen Einschränkung, dass der Systemstatus derselbe sein muss, damit die Daten entsiegelt werden.
Zunächst ist darauf hinzuweisen, dass es zwei Hauptversionen von TPM gibt, die untereinander völlig inkompatibel sind. Daher funktioniert praktisch kein Code, den Sie möglicherweise für TPM 1 geschrieben haben, für TPM 2. Die TBS-API ist der einzige gemeinsame Code zwischen beiden, und um Microsoft gegenüber fair zu sein, war dies möglicherweise einer der Gründe, warum diese API nie gewachsen ist. Der Hauptteil der Antwort enthält den Code für TPM 1 aus zwei Gründen:
Zweitens wollen wir die Frage genauer formulieren. Ich interpretiere es wie folgt neu:
Der Seal-Befehl ist hierfür am besten geeignet, da er dieselbe Funktion wie der Bind-Befehl ausführt, wenn die PCR-Auswahlgröße auf Null gesetzt ist. Die PCR-Auswahl kann jedoch leicht geändert werden, um alle gewünschten PCRs einzuschließen. Man wundert sich, warum der Bind-Befehl überhaupt in der Spezifikation enthalten war, und wie bereits erwähnt, wurde er in der TPM 2-Spezifikation entfernt und die beiden wurden in einem Create-Befehl kombiniert.
Hier ist der C # -Code für die Verwendung des TPM 1.2 Seal-Befehls zum Verschlüsseln von Daten nur mit TBS-Funktionen (Hinweis: Dieser Code ist nicht getestet und funktioniert wahrscheinlich nicht ohne Debugging) :
Code-Analyse:
Dies sind einige der wenigen Funktionen, die in Tbs.h verfügbar sind, und die einzigen, die wir hier verwenden werden. Sie ermöglichen es Ihnen grundsätzlich, ein Handle für das Gerät zu öffnen und mit ihm zu kommunizieren, indem Sie Rohbytes senden und empfangen.
TPM ist Big Endian, Windows ist Little Endian. Daher muss die Bytereihenfolge für alle Daten, über die wir senden, umgekehrt werden. Wir müssen uns hier nur darum kümmern, 32-Bit- und 16-Bit-Ints ohne Vorzeichen umzukehren.
Hier verwenden wir Tbsi_Context_Create () , um ein Handle zu öffnen, um mit dem TPM zu sprechen. Der
TBS_CONTEXT_PARAMS
Parameter ist nur eine C-Struktur mit einem vorzeichenlosen 32-Bit-Int-Feld, das auf 1 gesetzt werden muss, um mit einer TPM 1.2-Instanz zu kommunizieren, und auf das, was wir gesetzt haben.Dies wird als Mindestpuffergröße in der TPM PC-Client- Spezifikation angegeben . Es wird mehr als genug für unsere Bedürfnisse hier sein.
In TPM 1.2 Spec Part 3 heißt es:
Wir müssen diesen "geheimen" Parameter mit einer Nonce, die während einer OSAP-Sitzung generiert wurde, XOR-verschlüsseln. Eines der Eingabe-Handles für Seal-Befehle ist auch ein OSAP-Handle:
Wir müssen also zuerst diese OSAP-Sitzung einrichten. OSAP ist in TPM 1.2 Spec Part 1 beschrieben . OSAP oder Object-Specific Authorization Protocol wurde entwickelt, um den Anwendungsfall zu behandeln, bei dem Sie ein TPM-Objekt verwenden möchten, für das eine mehrfache Autorisierung erforderlich ist, das jedoch nicht jedes Mal autorisiert werden soll: Stattdessen wird eine OSAP-Sitzung verwendet, die sich darauf stützt über das Konzept des "geteilten Geheimnisses", das ein HMAC ist , in dem die Objektautorisierungsdaten mit auf jeder Seite generierten Nonces gemischt werden, um Antwortangriffe zu verhindern. Daher ist das "gemeinsame Geheimnis" nur den beiden Seiten in dieser Sitzung bekannt: der Seite, die die Sitzung initiiert hat (Benutzer) und der Seite, die sie akzeptiert hat (TPM); Außerdem müssen beide Seiten dieselben Objektautorisierungsdaten haben, damit das "gemeinsame Geheimnis" identisch ist. Außerdem ist das in einer Sitzung verwendete "gemeinsame Geheimnis" in einer anderen Sitzung ungültig. Dieses Diagramm aus der Spezifikation beschreibt den Prozess:
In diesem speziellen Fall werden nicht mehrere Sitzungen verwendet (tatsächlich wird dieser Parameter mit dem Befehl Seal ignoriert!), Und der Schlüssel, den wir verwenden, erfordert keine Autorisierung, aber leider sind wir immer noch an die Spezifikation gebunden, um ein OSAP einzurichten Session.
TPM_OSAP-Befehlsoperanden sind:
Jeder TPM 1.2-Befehl ist wie folgt aufgebaut:
Das Tag ist ein Zwei-Byte-Wert, der angibt, ob das Folgende entweder eingegeben oder ausgegeben wird und ob nach den Befehlsparametern Authentifizierungsdatenwerte vorhanden sind. Für TPM_OSAP muss das Tag gemäß der Spezifikation TPM_TAG_RQU_COMMAND (0x00C1) sein, was "ein Befehl ohne Berechtigung" bedeutet.
Größe ist ein Vier-Byte-Wert, der die Größe des Befehls in Byte angibt, einschließlich des Tags und der Größe selbst. Wir werden diesen Wert später einstellen, sobald wir ihn berechnet haben.
Befehlscode ist ein Vier-Byte-Wert, den Server als Befehls-ID verwenden: Er teilt dem TPM mit, wie der Rest des Befehls zu interpretieren ist. Unser Befehlscode hier ist TPM_OSAP (0x0000000B).
Die nächsten beiden Dinge, die festgelegt werden müssen, sind Entitätstyp und Entitätswert. Da wir einen Schlüssel verwenden möchten, der bereits im TPM vorhanden ist, verwenden wir den Entitätstyp "SRK" (0x0004). Da wir davon ausgehen, dass das TPM bereits im Besitz ist, können wir davon ausgehen, dass dies der Fall ist Ein SRK, das gemäß der Spezifikation unter dem permanenten Handle 0x40000000 geladen wurde, sodass wir diesen permanenten Handle-Wert für unseren Entitätswert verwenden. (SRK steht für "Storage Root Key" und ist der Root-Schlüssel, von dem die meisten anderen TPM-eigenen Schlüssel abgeleitet sind.)
Schließlich berechnen wir die Befehlsgröße und legen sie fest und senden den Befehl.
Die Daten, die wir vom TPM auf TPM_OSAP zurückerhalten sollen, sind:
Also kommen wir zurück:
Wir extrahieren diese Werte und speichern sie in Variablen.
Dann berechnen wir das "gemeinsame Geheimnis". Gemäß der Spezifikation sind die Werte, die in die Berechnung einfließen, die beiden OSAP-Nonces (eine vom Benutzer und eine vom TPM generiert) und der Berechtigungswert für den Schlüssel, den wir verwenden möchten - das SRK. Konventionell ist der SRK-Authentifizierungswert die "bekannte Authentifizierung": ein auf Null ausgelöster 20-Byte-Puffer. Technisch gesehen könnte man diesen Wert in etwas anderes ändern, wenn man das TPM übernimmt, aber dies wird in der Praxis nicht durchgeführt, so dass wir sicher davon ausgehen können, dass der "bekannte Auth" -Wert gut ist.
Schauen wir uns als nächstes an, was im Befehl TPM_Seal enthalten ist:
Die meisten dieser Parameter sind trivial zu erstellen, mit Ausnahme von zwei:
encAuth
undpubAuth
. Schauen wir sie uns einzeln an.encAuth
ist "Die verschlüsselten AuthData für die versiegelten Daten." Unsere AuthData hier ist die "bekannte Auth" von früher, aber ja, wir müssen sie noch verschlüsseln. Da wir eine OSAP-Sitzung verwenden, wird diese nach ADIP oder Authorization-Data Insertion Protocol verschlüsselt. Aus der Spezifikation: "Das ADIP ermöglicht die Erstellung neuer Entitäten und das sichere Einfügen der neuen Entität AuthData. Die Übertragung der neuen AuthData verwendet die Verschlüsselung mit dem Schlüssel basierend auf dem gemeinsamen Geheimnis einer OSAP-Sitzung." Zusätzlich: "Für den obligatorischen XOR-Verschlüsselungsalgorithmus erstellt der Ersteller einen Verschlüsselungsschlüssel unter Verwendung eines SHA-1-Hash des gemeinsam genutzten OSAP-Geheimnisses und einer Sitzungs-Nonce. Der Ersteller XOR verschlüsselt die neuen AuthData unter Verwendung des Verschlüsselungsschlüssels als einmaliges Pad und sendet diese verschlüsselten Daten zusammen mit der Erstellungsanforderung an das TPM. "Das folgende Diagramm erläutert die Funktionsweise von ADIP:
pubAuth
ist "Der Digest der Autorisierungssitzung für Eingaben und keyHandle". Teil 1 der Spezifikation in "Parameterdeklarationen für OIAP- und OSAP-Beispiele" erläutert die Interpretation der obigen TPM_Seal-Parametertabelle: "In der Spalte HMAC # sind die in der HMAC-Berechnung verwendeten Parameter aufgeführt. Die Parameter 1S, 2S usw. sind verkettet und Hash zu inParamDigest oder outParamDigest, implizit 1H1 und möglicherweise 1H2 genannt, wenn zwei Autorisierungssitzungen vorhanden sind. Für die erste Sitzung werden 1H1, 2H1, 3H1 und 4H1 verkettet und HMAC'ed. Für die zweite Sitzung 1H2, 2H2, 3H2, und 4H2 sind verkettet und HMAC'ed. " Also müssen wir den Klartext, seine Größe, die Größe der PCR-InformationenencAuth
von oben und die TPM_Seal-Ordnungszahl und dann die HMAC, die mit den beiden Nonces und dem Booleschen Wert "Sitzung fortsetzen" unter Verwendung des OSAP "hasht.Alles in einem Diagramm zusammenfassen:
Beachten Sie, wie wir "PCR-Info-Größe" in diesem Code auf Null setzen, da wir die Daten nur verschlüsseln möchten, ohne sie an einen Systemstatus zu binden. Es ist jedoch trivial, bei Bedarf eine "PCR-Info" -Struktur bereitzustellen.
Schließlich konstruieren wir den Befehl und senden ihn.
Wir verwenden die Funktion Tbsip_Context_Close () , um unser Kommunikationshandle zu schließen.
Wir geben die Antwort so wie sie ist zurück. Idealerweise möchten Sie die Bytes erneut umkehren und validieren, indem Sie den
resAuth
Wert neu berechnen, um Man-in-the-Middle-Angriffe zu verhindern.Dies liegt daran, dass Tspi_Data_Bind ein TSS-Befehl und kein TPM-Befehl ist. Der Grund dafür ist, dass keine Geheimnisse erforderlich sind (nur der öffentliche Schlüssel wird verwendet), sodass dies ohne Beteiligung des TPM möglich ist. Dies führte jedoch zu Verwirrung, und selbst die Befehle, für die keine Geheimnisse erforderlich sind, sind jetzt in der TPM 2-Spezifikation enthalten.
Hängt von der TPM-Version ab. Mit dem Befehl TPM_CreateWrapKey für TPM 1.2. Mit dem Befehl TPM2_Create für TPM 2.
Erstellen Sie es entweder im TPM oder verpacken Sie es oder verwenden Sie eine andere der verfügbaren Methoden.
Der Text im Buch ist verwirrend. Sie geben den HMAC-Schlüssel nicht an, sondern geben an , dass Sie einen HMAC-Schlüssel wünschen .
Nein, es macht keinen Sinn. Der Schlüssel ist geheim.
Es gibt Befehle zum Erstellen oder Importieren von Schlüsseln für beide TPM-Versionen. Für TPM 1 gab es nur einen Stammschlüssel - den SRK - aus dem Sie eine Schlüsselhierarchie erstellen konnten, indem Sie umschlossene Schlüssel erstellen. Mit TPM 2 können Sie mehrere Primär- oder Root-Schlüssel haben.
Siehe oben.
Hängt wahrscheinlich vom Typ des Laufwerks ab. Bei Nicht-SED-Laufwerken ist der Laufwerkverschlüsselungsschlüssel wahrscheinlich mit einem TPM-Schlüssel umwickelt. Bei SED-Laufwerken ist das Admin1-Kennwort (oder ein solches Kennwort) mit dem TPM versiegelt.
Der EK ist kein Signaturschlüssel, sondern ein Verschlüsselungsschlüssel. Es handelt sich jedoch nicht um einen allgemeinen Verschlüsselungsschlüssel, sondern kann nur in bestimmten Kontexten verwendet werden .
Siehe oben.
quelle
Wenn es heißt
Dies bedeutet NICHT, dass Sie den HMAC-Schlüssel bereitstellen müssen. Es bedeutet, dass Sie auf den HMAC-Schlüssel zeigen, den Sie verwenden möchten .
TPMs können eine praktisch unbegrenzte Anzahl von HMAC-Schlüsseln verwenden, wie im Buch ausgeführt. Sie müssen dem TPM mitteilen, welches verwendet werden soll.
quelle