Hardware-verpackte Schlüssel

Wie bei den meisten Festplatten- und Dateiverschlüsselungssoftware bietet die Speicherverschlüsselung von Android sind üblicherweise darauf angewiesen, dass die rohen Verschlüsselungsschlüssel im Systemspeicher damit die Verschlüsselung durchgeführt werden kann. Auch wenn die Verschlüsselung durchgeführt wird nicht durch Software, sondern nur auf dedizierter Hardware, muss Software in der Regel um die Rohverschlüsselungsschlüssel zu verwalten.

Dies wird üblicherweise nicht als Problem angesehen, da die Schlüssel nicht vorhanden sind. während eines Offline-Angriffs – die Hauptart eines Angriffs, die Verschlüsselung vor. Es besteht jedoch der Wunsch, erhöhter Schutz vor anderen Arten von Angriffen, z. B. Kaltstart Angriffe und Onlineangriffe, bei denen Angreifer ohne die Geräte zu beeinträchtigen.

Um dieses Problem zu lösen, wurde in Android 11 die Unterstützung für hardwareverpackte Schlüssel eingeführt, sofern Hardware-Unterstützung vorhanden ist. Hardware-verpackte Schlüssel sind Speicherschlüssel, die nur in Rohform für spezielle Hardware bekannt sind. Software sieht und arbeitet nur mit diesen Schlüsseln in verpackter (verschlüsselter) Form. Diese Hardware muss in der Lage sein, Daten zu generieren und zu importieren sowie die flüchtige und langfristige Verpackung von Speicherschlüsseln, Unterschlüssel direkt in eine Inline-Krypto-Engine programmieren und gibt einen separaten Unterschlüssel an die Software zurück.

Hinweis: Eine Inline-Krypto-Engine (oder Inline-Verschlüsselungshardware) bezieht sich auf Hardware, die Daten verschlüsselt/entschlüsselt, während sie auf dem Weg zum/vom Speichergerät sind. Normalerweise ein UFS- oder eMMC-Host Controller, der die von der entsprechenden JEDEC-Spezifikation.

Design

In diesem Abschnitt wird das Design der Funktion für mit Hardware verpackte Schlüssel beschrieben, einschließlich: welche Hardware-Unterstützung dafür benötigt wird. In diesem Artikel geht es hauptsächlich um die dateibasierte Verschlüsselung (File-based Encryption, FBE). Lösung auf Metadaten Verschlüsselung verwenden.

Um zu vermeiden, dass die unverarbeiteten Verschlüsselungsschlüssel im Systemspeicher erforderlich sind, können Sie nur in den Schlüsselslots einer Inline-Krypto-Engine. Bei diesem Ansatz treten jedoch einige Probleme auf:

  • Die Anzahl der Verschlüsselungsschlüssel überschreitet möglicherweise die Anzahl der Schlüsselslots.
  • Inline-Krypto-Engines können nur zum Ver-/Entschlüsseln vollständiger Daten auf der Festplatte. Bei der FBE muss die Software jedoch weiterhin andere kryptografische Aufgaben ausführen können, z. B. die Verschlüsselung von Dateinamen und die Ableitung von Schlüssel-IDs. Die Software benötigt weiterhin Zugriff auf die FBE-Rohschlüssel, um und diese andere Arbeit machen.

Um diese Probleme zu vermeiden, werden die Speicherschlüssel mit Hardware verpackten Schlüsseln, die nur entpackt und verwendet werden können dedizierte Hardware. So kann eine unbegrenzte Anzahl von Schlüsseln unterstützt werden. Außerdem wird die Schlüsselhierarchie geändert und teilweise auf diese Hardware verschoben. So kann ein Unterschlüssel für Aufgaben, für die keine Inline-Krypto-Engine verwendet werden kann, an die Software zurückgegeben werden.

Schlüsselhierarchie

Schlüssel können mit einem KDF (Key Derivation Function, KDF) von anderen Schlüsseln abgeleitet werden, z. B. HKDF. was zu einer Schlüsselhierarchie führt.

Das folgende Diagramm zeigt eine typische Schlüsselhierarchie für FBE, wenn Hardware-verpackte Schlüssel werden nicht verwendet:

FBE-Schlüsselhierarchie (Standard)
Abbildung 1: FBE-Schlüsselhierarchie (Standard)

Der FBE-Klassenschlüssel ist der Rohverschlüsselungsschlüssel, den Android an das Linux-System übergibt. bestimmte verschlüsselte Verzeichnisse wie das mit Anmeldedaten verschlüsselter Speicher für einen bestimmten Android-Nutzer Im Kernel wird dieser Schlüssel als fscrypt-Masterschlüssel bezeichnet. Von diesem Schlüssel leitet der Kernel folgenden Unterschlüsseln:

  • Die Schlüsselkennung. Dieser wird nicht zur Verschlüsselung verwendet, sondern ein Wert. zur Identifizierung des Schlüssels, mit dem eine bestimmte Datei oder ein bestimmtes Verzeichnis geschützt sind.
  • Verschlüsselungsschlüssel für Dateiinhalte
  • Der Verschlüsselungsschlüssel für Dateinamen

Im Gegensatz dazu zeigt das folgende Diagramm die Schlüsselhierarchie für die FBE, wenn hardwareverpackte Schlüssel verwendet werden:

FBE-Schlüsselhierarchie (mit Hardware-verpacktem Schlüssel)
Abbildung 2: FBE-Schlüsselhierarchie (mit Hardware-verpacktem Schlüssel)

Im Vergleich zum vorherigen Fall wurde der Schlüsselhierarchie eine zusätzliche Ebene hinzugefügt und der Verschlüsselungsschlüssel für den Dateiinhalt wurde verschoben. Der Stammknoten stellt weiterhin den Schlüssel dar, den Android an Linux weitergibt, um eine Reihe verschlüsselter Verzeichnisse zu entsperren. Dieser Schlüssel liegt jedoch ephemerisch verpackt vor und damit er verwendet werden kann, muss er an die entsprechende Hardware übergeben werden. Diese Hardware muss Implementieren Sie zwei Schnittstellen, die einen sitzungsspezifischen Schlüssel verwenden:

  • Eine Schnittstelle, um inline_encryption_key abzuleiten und direkt in einen Schlüsselschlitz der Inline-Krypto-Engine zu programmieren. So können Dateiinhalte verschlüsselt/entschlüsselt werden, ohne dass Software Zugriff auf den Rohschlüssel hat. In den gemeinsamen Android-Kerneln entspricht diese Schnittstelle dem Vorgang blk_crypto_ll_ops::keyslot_program, der vom Speichertreiber implementiert werden muss.
  • Eine Schnittstelle zum Ableiten und Zurückgeben von sw_secret ("Software") geheim“ -- auch als "raw Secret" bezeichnet an manchen Orten), was der Schlüssel ist, Unter Linux werden die Unterschlüssel für alles andere als Dateiinhalte abgeleitet. Verschlüsselung. In den gängigen Kerneln von Android entspricht diese Schnittstelle der blk_crypto_ll_ops::derive_sw_secret-Vorgang, der folgender Wert sein muss: Speichertreiber implementiert wird.

Um inline_encryption_key und sw_secret aus dem Rohspeicherschlüssel abzuleiten, muss die Hardware einen kryptografisch starken KDF verwenden. Dieser KDF Best Practices für Kryptografie einhalten; Die Sicherheitsstufe muss 256 Bit, was für einen später verwendeten Algorithmus ausreicht. Außerdem muss beim Ableiten der einzelnen Arten von Unterschlüsseln ein eindeutiges Label, ein eindeutiger Kontext und ein app-spezifischer Informationsstring verwendet werden, um sicherzustellen, dass die resultierenden Unterschlüssel kryptografisch isoliert sind, d. h., dass das Wissen um einen von ihnen keine anderen preisgibt. Schlüsselerweiterungen sind nicht erforderlich, da der Rohspeicherschlüssel bereits ein ein zufällig zufälliger Schlüssel an.

Technisch gesehen kann jeder KDF verwendet werden, der die Sicherheitsanforderungen erfüllt. Zu Testzwecken ist es jedoch notwendig, denselben KDF in und testen Sie den Code. Derzeit wurde ein KDF geprüft und implementiert. Es befindet sich im Quellcode für vts_kernel_encryption_test. Für die Hardware wird dieser KDF empfohlen, der NIST SP 800-108 „KDF in Counter Mode“ mit AES-256-CMAC als PRF verwendet. Hinweis: Für die Kompatibilität müssen alle Teile des Algorithmus identisch sein, einschließlich der Auswahl der KDF-Kontexte und Labels für jeden Unterschlüssel.

Key-Wrapping

Um die Sicherheitsziele von hardwareverpackten Schlüsseln zu erreichen, sind zwei Arten der Schlüsselverschlüsselung definiert:

  • Sitzungsspezifisches Wrapping: Die Hardware verschlüsselt den Rohschlüssel mit einem Schlüssel. die bei jedem Start zufällig generiert und nicht direkt bereitgestellt wird, außerhalb der Hardware.
  • Langfristige Verschlüsselung: Die Hardware verschlüsselt den Rohschlüssel mit einem eindeutigen, persistenten Schlüssel, der in die Hardware integriert ist und nicht direkt außerhalb der Hardware freigegeben wird.

Alle Schlüssel, die zum Entsperren des Speichers an den Linux-Kernel übergeben werden, werden mit flüchtigem Wrapping. So wird sichergestellt, dass ein Angreifer, der einen verwendeten Schlüssel aus dem Systemspeicher extrahiert, diesen Schlüssel nicht nur außerhalb des Geräts, sondern auch auf dem Gerät nach einem Neustart nicht verwenden kann.

Gleichzeitig muss Android eine verschlüsselte Version speichern können. der Schlüssel auf der Festplatte, damit sie überhaupt entriegelt werden können. Die Rohfassung Schlüssel wären für diesen Zweck geeignet. Es ist jedoch wünschenswert, niemals die unbearbeiteten Schlüssel überhaupt im Systemspeicher vorhanden sind, sodass sie nie extrahiert werden können, kann außerhalb des Geräts verwendet werden, auch wenn es beim Start des Geräts extrahiert wurde. Aus diesem Grund wurde das Konzept des langfristigen Wrappers definiert.

Damit die Verwaltung von Schlüsseln auf diese beiden Arten unterstützt werden kann, muss die Hardware die folgenden Schnittstellen implementieren:

  • Schnittstellen zum Generieren und Importieren von Speicherschlüsseln, die in verpackter Form für die Langzeitspeicherung zurückgegeben werden. Auf diese Schnittstellen wird indirekt über KeyMint zugegriffen und sie entsprechen dem TAG_STORAGE_KEY KeyMint-Tag. Die Funktion „generieren“ wird von vold verwendet, um neue Speicherschlüssel für die Verwendung unter Android zu generieren. Die Funktion „importieren“ wird von vts_kernel_encryption_test verwendet, um Testschlüssel zu importieren.
  • Eine Schnittstelle zum Konvertieren eines langfristig verpackten Speicherschlüssels in einen sitzungsspezifisch verpackten Speicherschlüssel. Dies entspricht der convertStorageKeyToEphemeral-KeyMint-Methode. Diese Methode wird verwendet, der Reihe nach von vold und vts_kernel_encryption_test um den Speicher freizuschalten.

Der Key-Wrapping-Algorithmus ist ein Implementierungsdetail, sollte jedoch einen starken AEAD wie AES-256-GCM mit zufälligen IVs aus.

Erforderliche Softwareänderungen

AOSP verfügt bereits über ein grundlegendes Framework zur Unterstützung von mit Hardware verpackten Schlüsseln. Dazu gehören die Unterstützung in Userspace-Komponenten wie vold sowie die Linux-Kernel-Unterstützung in blk-crypto, fscrypt und dm-default-key.

Es sind jedoch einige implementierungsspezifische Änderungen erforderlich.

Änderungen bei KeyMint

Die KeyMint-Implementierung des Geräts muss so geändert werden, dass TAG_STORAGE_KEY unterstützt und die Methode convertStorageKeyToEphemeral implementiert wird.

In Keymaster wurde exportKey anstelle von convertStorageKeyToEphemeral.

Änderungen am Linux-Kernel

Der Linux-Kernel-Treiber für die Inline-Krypto-Engine des Geräts muss so geändert werden, dass er hardwareverpackte Schlüssel unterstützt.

Für android14 und höhere Kernel: BLK_CRYPTO_KEY_TYPE_HW_WRAPPED festlegen in blk_crypto_profile::key_types_supported, machen blk_crypto_ll_ops::keyslot_program und blk_crypto_ll_ops::keyslot_evict unterstützen das Programmieren/Entfernen von hardwareverpackten Schlüsseln, und blk_crypto_ll_ops::derive_sw_secret implementieren.

Für android12- und android13-Kernel: BLK_CRYPTO_FEATURE_WRAPPED_KEYS festlegen in blk_keyslot_manager::features, machen blk_ksm_ll_ops::keyslot_program und blk_ksm_ll_ops::keyslot_evict unterstützen das Programmieren/Entfernen von hardwareverpackten Schlüsseln, und blk_ksm_ll_ops::derive_raw_secret implementieren.

Für android11-Kernel: BLK_CRYPTO_FEATURE_WRAPPED_KEYS festlegen in keyslot_manager::features, machen keyslot_mgmt_ll_ops::keyslot_program und keyslot_mgmt_ll_ops::keyslot_evict unterstützen das Programmieren/Entfernen von hardwareverpackten Schlüsseln, und keyslot_mgmt_ll_ops::derive_raw_secret implementieren.

Testen

Die Verschlüsselung mit hardwareverpackten Schlüsseln ist zwar schwieriger zu testen als die Verschlüsselung mit Standardschlüsseln, aber es ist trotzdem möglich, sie zu testen, indem Sie einen Testschlüssel importieren und die Schlüsselableitung der Hardware neu implementieren. Dies ist in vts_kernel_encryption_test implementiert. Führen Sie zum Ausführen dieses Tests Folgendes aus:

atest -v vts_kernel_encryption_test

Lesen Sie das Testprotokoll und prüfen Sie, ob die Testfälle für hardwareverpackte Schlüssel (z. B. FBEPolicyTest.TestAesInlineCryptOptimizedHwWrappedKeyPolicy und DmDefaultKeyTest.TestHwWrappedKey) nicht übersprungen wurden, weil die Unterstützung für hardwareverpackte Schlüssel nicht erkannt wurde, da die Testergebnisse in diesem Fall weiterhin als „bestanden“ gelten.

Tasten aktivieren

Sobald die Unterstützung für hardwareverpackte Schlüssel des Geräts ordnungsgemäß funktioniert, können Sie die folgenden Änderungen an der fstab-Datei des Geräts vornehmen, damit Android sie für die FBE- und Metadatenverschlüsselung verwendet:

  • FBE: Fügen Sie das Flag wrappedkey_v0 zum fileencryption-Parameter. Verwenden Sie beispielsweise fileencryption=::inlinecrypt_optimized+wrappedkey_v0 Weitere Informationen finden Sie in der FBE-Dokumentation.
  • Metadatenverschlüsselung: Fügen Sie das Flag wrappedkey_v0 zum metadata_encryption-Parameter. Verwenden Sie beispielsweise metadata_encryption=:wrappedkey_v0 Weitere Informationen finden Sie in der Dokumentation zur Verschlüsselung von Metadaten.