Metadatenverschlüsselung

Android 7.0 und höher unterstützt die dateibasierte Verschlüsselung (File-Based Encryption, FBE). Mit FBE können verschiedene Dateien mit unterschiedlichen Schlüsseln verschlüsselt werden, die unabhängig voneinander entsperrt werden können. Diese Schlüssel werden verwendet, um sowohl Dateiinhalte als auch Dateinamen zu verschlüsseln. Bei Verwendung von FBE werden andere Informationen wie Verzeichnislayouts, Dateigrößen, Berechtigungen und Erstellungs-/Änderungszeiten nicht verschlüsselt. Diese anderen Informationen werden zusammen als Dateisystemmetadaten bezeichnet.

Mit Android 9 wurde die Unterstützung für die Metadatenverschlüsselung eingeführt. Bei der Metadatenverschlüsselung wird ein einzelner Schlüssel, der beim Booten vorhanden ist, verwendet, um alle Inhalte zu verschlüsseln, die nicht von FBE verschlüsselt werden. Dieser Schlüssel wird durch KeyMint (früher Keymaster) geschützt, das wiederum durch Verified Boot geschützt wird.

Die Metadatenverschlüsselung ist auf anpassbarem Speicher immer aktiviert, wenn FBE aktiviert ist. Die Metadatenverschlüsselung kann auch auf dem internen Speicher aktiviert werden. Auf Geräten mit Android 11 oder höher muss die Metadatenverschlüsselung auf dem internen Speicher aktiviert sein.

Implementierung auf dem internen Speicher

Sie können die Metadatenverschlüsselung auf dem internen Speicher neuer Geräte einrichten, indem Sie das Dateisystem metadata einrichten, die Initialisierungssequenz ändern und die Metadatenverschlüsselung in der fstab-Datei des Geräts aktivieren.

Vorbereitung

Die Metadatenverschlüsselung kann nur eingerichtet werden, wenn die Datenpartition zum ersten Mal formatiert wird. Diese Funktion ist daher nur für neue Geräte vorgesehen. Sie sollte nicht durch ein OTA geändert werden.

Für die Metadatenverschlüsselung muss das Modul dm-default-key in Ihrem Kernel aktiviert sein. In Android 11 und höher wird dm-default-key von den gemeinsamen Android-Kerneln der Version 4.14 und höher unterstützt. Diese Version von dm-default-key verwendet ein hardware- und anbieterunabhängiges Verschlüsselungsframework namens blk-crypto.

Verwenden Sie Folgendes, um dm-default-key zu aktivieren:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y
CONFIG_DM_DEFAULT_KEY=y

dm-default-key verwendet, wenn verfügbar, Inline-Verschlüsselungshardware (Hardware, die Daten verschlüsselt/entschlüsselt, während sie zum/vom Speichergerät übertragen werden). Wenn Sie keine Inline-Verschlüsselungshardware verwenden, müssen Sie auch ein Fallback auf die Kryptografie-API des Kernels aktivieren:

CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y

Wenn Sie keine Inline-Verschlüsselungshardware verwenden, sollten Sie auch die verfügbare CPU-basierte Beschleunigung aktivieren, wie in der FBE-Dokumentation empfohlen.

In Android 10 und niedriger wurde dm-default-key nicht vom gemeinsamen Android-Kernel unterstützt. Daher mussten Anbieter dm-default-key implementieren.

Metadaten-Dateisystem einrichten

Da nichts in der Nutzerdatenpartition gelesen werden kann, bis der Schlüssel für die Metadatenverschlüsselung vorhanden ist, muss in der Partitionstabelle eine separate Partition namens Metadatenpartition für die Speicherung der KeyMint-Blobs reserviert werden, die diesen Schlüssel schützen. Die Metadatenpartition sollte 16 MB groß sein.

fstab.hardware muss einen Eintrag für das Metadaten-Dateisystem enthalten, das auf dieser Partition vorhanden ist, und es unter /metadata einbinden. Außerdem muss das Flag formattable enthalten sein, damit es beim Booten formatiert wird. Das f2fs-Dateisystem funktioniert nicht auf kleineren Partitionen. Wir empfehlen stattdessen die Verwendung von ext4. Beispiel:

/dev/block/bootdevice/by-name/metadata              /metadata          ext4        noatime,nosuid,nodev,discard                          wait,check,formattable

Fügen Sie der Datei BoardConfig-common.mk die folgende Zeile hinzu, um sicherzustellen, dass der Bereitstellungspunkt /metadata vorhanden ist:

BOARD_USES_METADATA_PARTITION := true

Änderungen an der Initialisierungssequenz

Wenn die Metadatenverschlüsselung verwendet wird, muss vold ausgeführt werden, bevor /data eingebunden wird. Fügen Sie der Datei init.hardware.rc den folgenden Abschnitt hinzu, um sicherzustellen, dass sie früh genug gestartet wird:

# We need vold early for metadata encryption
on early-fs
    start vold

KeyMint muss ausgeführt und bereit sein, bevor versucht wird, /data einzubinden.

init.hardware.rc sollte bereits eine mount_all -Anweisung enthalten, die /data selbst im Abschnitt on late-fs einbindet. Fügen Sie vor dieser Zeile die Anweisung hinzu, um den Dienst wait_for_keymaster auszuführen:

on late-fs
    
    # Wait for Keymaster
    exec_start wait_for_keymaster

    # Mount RW partitions which need run fsck
    mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late

Metadatenverschlüsselung aktivieren

Fügen Sie schließlich keydirectory=/metadata/vold/metadata_encryption zur Spalte fs_mgr_flags des fstab-Eintrags für userdata hinzu. Eine vollständige fstab-Zeile könnte beispielsweise so aussehen:

/dev/block/bootdevice/by-name/userdata              /data              f2fs        noatime,nosuid,nodev,discard,inlinecrypt latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable

Standardmäßig ist der Algorithmus für die Metadatenverschlüsselung auf dem internen Speicher AES-256-XTS. Dies kann durch Festlegen der Option metadata_encryption überschrieben werden, ebenfalls in der Spalte fs_mgr_flags:

  • Auf Geräten ohne AES-Beschleunigung kann die Adiantum-Verschlüsselung durch Festlegen von metadata_encryption=adiantum aktiviert werden.
  • Auf Geräten, die hardwareumschlossene Inline-Verschlüsselungsschlüssel unterstützen, kann der Schlüssel für die Metadatenverschlüsselung hardwareumschlossen werden, indem Sie metadata_encryption=aes-256-xts:wrappedkey oder metadata_encryption=aes-256-xts:wrappedkey_v0 festlegen. wrappedkey ist die moderne Version. wrappedkey_v0 sollte nur auf Geräten verwendet werden, die wrappedkey nicht unterstützen oder bereits mit wrappedkey_v0 auf den Markt gebracht wurden. Weitere Informationen finden Sie unter Umschlossene Schlüssel aktivieren.

    In beiden Fällen kann aes-256-xts weggelassen werden, da es der Standardalgorithmus ist. Beispielsweise ist metadata_encryption=:wrappedkey dasselbe wie metadata_encryption=aes-256-xts:wrappedkey.

Da sich die Kernel-Schnittstelle zu dm-default-key in Android 11 geändert hat, müssen Sie auch sicherstellen, dass Sie in device.mk den richtigen Wert für PRODUCT_SHIPPING_API_LEVEL festgelegt haben. Wenn Ihr Gerät beispielsweise mit Android 11 (API-Level 30) auf den Markt kommt, sollte device.mk Folgendes enthalten:

PRODUCT_SHIPPING_API_LEVEL := 30

Sie können auch das folgende Systemattribut festlegen, um die Verwendung der neuen dm-default-key-API unabhängig vom API-Level zu erzwingen:

PRODUCT_PROPERTY_OVERRIDES += \
    ro.crypto.dm_default_key.options_format.version=2

Validierung

Führen Sie die unten beschriebenen Tests aus, um zu prüfen, ob die Metadatenverschlüsselung aktiviert ist und ordnungsgemäß funktioniert. Beachten Sie auch die unten beschriebenen häufigen Probleme.

Tests

Führen Sie zuerst den folgenden Befehl aus, um zu prüfen, ob die Metadatenverschlüsselung auf dem internen Speicher aktiviert ist:

adb root
adb shell dmctl table userdata

Die Ausgabe sollte in etwa so aussehen:

Targets in the device-mapper table for userdata:
0-4194304: default-key, aes-xts-plain64 - 0 252:2 0 3 allow_discards sector_size:4096 iv_large_sectors

Wenn Sie die Standardeinstellungen für die Verschlüsselung überschrieben haben, indem Sie die Option metadata_encryption in der fstab-Datei des Geräts festgelegt haben, weicht die Ausgabe geringfügig von der oben genannten ab. Wenn Sie beispielsweise die Adiantum-Verschlüsselung aktiviert haben, ist das dritte Feld xchacha12,aes-adiantum-plain64 anstelle von aes-xts-plain64.

Führen Sie als Nächstes vts_kernel_encryption_test aus, um die Richtigkeit der Metadatenverschlüsselung und von FBE zu prüfen:

atest vts_kernel_encryption_test

oder:

vts-tradefed run vts -m vts_kernel_encryption_test

Häufige Probleme

Während des Aufrufs von mount_all, mit dem die metadatenverschlüsselte /data-Partition eingebunden wird, führt init das vdc-Tool aus. Das vdc-Tool stellt über binder eine Verbindung zu vold her, um das metadatenverschlüsselte Gerät einzurichten und die Partition einzubinden. Während dieses Aufrufs wird init blockiert und Versuche, init-Attribute zu lesen oder festzulegen, werden blockiert, bis mount_all abgeschlossen ist. Wenn in dieser Phase ein Teil der Arbeit von vold direkt oder indirekt durch das Lesen oder Festlegen eines Attributs blockiert wird, kommt es zu einem Deadlock. Es ist wichtig, dass vold die Arbeit des Lesens der Schlüssel, der Interaktion mit KeyMint und des Einbindens des Datenverzeichnisses abschließen kann, ohne weitere Interaktionen mit init.

Wenn KeyMint nicht vollständig gestartet ist, wenn mount_all ausgeführt wird, antwortet es nicht auf vold, bis bestimmte Attribute aus init gelesen wurden. Dies führt genau zu dem beschriebenen Deadlock. Wenn Sie exec_start wait_for_keymaster über dem entsprechenden mount_all-Aufruf platzieren, wie festgelegt, wird KeyMint im Voraus vollständig ausgeführt und dieser Deadlock wird vermieden.

Konfiguration auf anpassbarem Speicher

Seit Android 9 ist eine Form der Metadatenverschlüsselung auf anpassbarem Speicher immer aktiviert, wenn FBE aktiviert ist, auch wenn die Metadatenverschlüsselung auf dem internen Speicher nicht aktiviert ist.

In AOSP gibt es zwei Implementierungen der Metadatenverschlüsselung auf anpassbarem Speicher: eine veraltete, die auf dm-crypt basiert, und eine neuere, die auf dm-default-key basiert. Um sicherzustellen, dass die richtige Implementierung für Ihr Gerät ausgewählt wird, müssen Sie in device.mk den richtigen Wert für PRODUCT_SHIPPING_API_LEVEL festgelegt haben. Wenn Ihr Gerät beispielsweise mit Android 11 (API-Level 30) auf den Markt kommt, sollte device.mk Folgendes enthalten:

PRODUCT_SHIPPING_API_LEVEL := 30

Sie können auch die folgenden Systemattribute festlegen, um die Verwendung der neuen Methode zur Verschlüsselung von Volume-Metadaten (und der neuen Standardversion der FBE-Richtlinie) unabhängig vom API-Level zu erzwingen:

PRODUCT_PROPERTY_OVERRIDES += \
    ro.crypto.volume.metadata.method=dm-default-key \
    ro.crypto.dm_default_key.options_format.version=2 \
    ro.crypto.volume.options=::v2

Aktuelle Methode

Auf Geräten mit Android 11 oder höher wird für die Metadatenverschlüsselung auf anpassbarem Speicher das Kernelmodul dm-default-key verwendet, genau wie auf dem internen Speicher. Informationen zu den zu aktivierenden Kernelkonfigurations optionen finden Sie unter Voraussetzungen. Beachten Sie, dass Inline-Verschlüsselungshardware, die auf dem internen Speicher des Geräts funktioniert, möglicherweise nicht auf anpassbarem Speicher verfügbar ist. Daher ist möglicherweise CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y erforderlich.

Standardmäßig verwendet die Methode zur Verschlüsselung von Volume-Metadaten dm-default-key den AES-256-XTS-Verschlüsselungsalgorithmus mit 4096-Byte-Kryptosektoren. Der Algorithmus kann durch Festlegen des Systemattributs ro.crypto.volume.metadata.encryption überschrieben werden. Der Wert dieses Attributs hat dieselbe Syntax wie die oben beschriebene metadata_encryption-Option für fstab. Auf Geräten ohne AES Beschleunigung kann die Adiantum-Verschlüsselung durch Festlegen von ro.crypto.volume.metadata.encryption=adiantum aktiviert werden.

Veraltete Methode

Auf Geräten mit Android 10 und niedriger wird für die Metadatenverschlüsselung auf anpassbarem Speicher das Kernelmodul dm-crypt anstelle von dm-default-key verwendet:

CONFIG_DM_CRYPT=y

Im Gegensatz zur dm-default-key-Methode werden bei der dm-crypt-Methode Dateiinhalte zweimal verschlüsselt: einmal mit einem FBE-Schlüssel und einmal mit dem Schlüssel für die Metadatenverschlüsselung. Diese doppelte Verschlüsselung beeinträchtigt die Leistung und ist nicht erforderlich, um die Sicherheitsziele der Metadatenverschlüsselung zu erreichen, da Android dafür sorgt, dass FBE-Schlüssel mindestens so schwer zu kompromittieren sind wie der Schlüssel für die Metadatenverschlüsselung. Anbieter können Kernelanpassungen vornehmen, um die doppelte Verschlüsselung zu vermeiden, insbesondere durch Implementieren der allow_encrypt_override Option, die Android an dm-crypt übergibt, wenn das Systemattribut ro.crypto.allow_encrypt_override auf true gesetzt ist. Diese Anpassungen werden vom gemeinsamen Android-Kernel nicht unterstützt.

Standardmäßig verwendet die Methode zur Verschlüsselung von Volume-Metadaten dm-crypt den AES-128-CBC-Verschlüsselungsalgorithmus mit ESSIV und 512-Byte-Kryptosektoren. Dies kann durch Festlegen der folgenden Systemattribute überschrieben werden (die auch für die vollständige Festplattenverschlüsselung verwendet werden):

  • ro.crypto.fde_algorithm wählt den Algorithmus für die Metadatenverschlüsselung aus. Die Optionen sind aes-128-cbc und adiantum. Adiantum kann nur verwendet werden, wenn das Gerät keine AES-Beschleunigung hat.
  • ro.crypto.fde_sector_size wählt die Größe des Kryptosektors aus. Die Optionen sind 512, 1024, 2048 und 4096. Verwenden Sie für die Adiantum-Verschlüsselung 4096.