Hardwarebasierter Schlüsselspeicher

Die Verfügbarkeit einer vertrauenswürdigen Ausführungsumgebung (Trusted Execution Environment, TEE) in einem System-on-Chip (SoC) bietet Android-Geräten die Möglichkeit, hardwaregestützte, starke Sicherheitsdienste für das Android-Betriebssystem, für Plattformdienste und sogar für Drittanbieter-Apps bereitzustellen (in Form von Android-spezifischen Erweiterungen der Standard Java Cryptography Architecture, siehe KeyGenParameterSpec).

Glossar

Hier finden Sie eine kurze Übersicht über die Keystore-Komponenten und ihre Beziehungen.

AndroidKeyStore
Die Android Framework API und -Komponente, die von Apps für den Zugriff auf die Keystore-Funktionalität verwendet wird. Es handelt sich um eine Implementierung der Standard-Java Cryptography Architecture APIs, die jedoch auch Android-spezifische Erweiterungen hinzufügt und aus Java-Code besteht, der im eigenen Prozess Raum der App ausgeführt wird. AndroidKeyStore erfüllt App-Anfragen zum Keystore-Verhalten , indem sie an den Keystore-Daemon weitergeleitet werden.
Keystore-Daemon
Ein Android-System-Daemon, der über eine Binder API Zugriff auf alle Keystore-Funktionen bietet. Dieser Daemon ist für die Speicherung von Keyblobs verantwortlich, die von der zugrunde liegenden KeyMint- (oder Keymaster-)Implementierung erstellt wurden. Sie enthalten das geheime Schlüsselmaterial, das verschlüsselt ist, damit Keystore es speichern, aber nicht verwenden oder offenlegen kann.
KeyMint-HAL-Dienst
Ein AIDL-Server, der die IKeyMintDevice HAL implementiert und Zugriff auf die zugrunde liegende KeyMint-TA bietet.
Vertrauenswürdige KeyMint-App (Trusted App, TA)
Software, die in einem sicheren Kontext ausgeführt wird, meist in TrustZone auf einem ARM-SoC, und alle sicheren kryptografischen Vorgänge ausführt. Diese App hat Zugriff auf das Rohschlüsselmaterial und validiert alle Zugriffssteuerungsbedingungen für Schlüssel, bevor sie deren Verwendung zulässt.
LockSettingsService
Die Android-Systemkomponente, die für die Nutzerauthentifizierung verantwortlich ist, sowohl für Passwörter als auch für Fingerabdrücke. Sie ist nicht Teil von Keystore, aber relevant, da Keystore das Konzept der authentifizierungsgebundenen Schlüssel unterstützt: Schlüssel, die nur verwendet werden können, wenn der Nutzer authentifiziert wurde. LockSettingsService interagiert mit der Gatekeeper-TA und der Fingerprint-TA, um Authentifizierungstokens zu erhalten, die an den Keystore-Daemon weitergegeben werden und von der KeyMint-TA verwendet werden.
Gatekeeper-TA
Die Komponente, die in der sicheren Umgebung ausgeführt wird und für die Authentifizierung von Nutzer Passwörtern und die Generierung von Authentifizierungstokens verantwortlich ist. Diese Tokens werden verwendet, um der KeyMint-TA nachzuweisen, dass eine Authentifizierung für einen bestimmten Nutzer zu einem bestimmten Zeitpunkt durchgeführt wurde.
Fingerprint-TA
Die Komponente, die in der sicheren Umgebung ausgeführt wird und für die Authentifizierung von Nutzer fingerabdrücken und die Generierung von Authentifizierungstokens verantwortlich ist. Diese Tokens werden verwendet, um der KeyMint-TA nachzuweisen, dass eine Authentifizierung für einen bestimmten Nutzer zu einem bestimmten Zeitpunkt durchgeführt wurde.

Architektur

Die Android Keystore API und die zugrunde liegende KeyMint-HAL bieten eine grundlegende, aber angemessene Reihe kryptografischer Primitiven, um die Implementierung von Protokollen mit zugriffskontrollierten, hardwaregestützten Schlüsseln zu ermöglichen.

Die KeyMint-HAL ist ein vom OEM bereitgestellter Dienst, der vom Keystore-Dienst verwendet wird, um hardwaregestützte kryptografische Dienste bereitzustellen. Um das private Schlüsselmaterial zu schützen, werden bei HAL-Implementierungen keine sensiblen Vorgänge im Nutzerbereich oder sogar im Kernelbereich ausgeführt. Stattdessen delegiert der KeyMint-HAL-Dienst, der unter Android ausgeführt wird, sensible Vorgänge an eine TA, die in einer sicheren Umgebung ausgeführt wird. Dies geschieht in der Regel durch Marshalling und Unmarshalling von Anfragen in einem implementierungsdefinierten Wire-Format.

Die resultierende Architektur sieht so aus:

Zugriff auf KeyMint

Abbildung 1 : Zugriff auf KeyMint.

Die KeyMint-HAL-API ist eine Low-Level-API, die von plattforminternen Komponenten verwendet wird und App-Entwicklern nicht zur Verfügung steht. Die Java API auf höherer Ebene, die für Apps verfügbar ist, wird auf der Android Entwicklerwebsite beschrieben.

Zugriffssteuerung

Android Keystore bietet eine zentrale Komponente für die Speicherung und Verwendung von hardwaregestützten kryptografischen Schlüsseln, sowohl für Apps als auch für andere Systemkomponenten. Daher ist der Zugriff auf einen einzelnen Schlüssel normalerweise auf die App oder Systemkomponente beschränkt, die den Schlüssel erstellt hat.

Keystore-Domains

Zur Unterstützung dieser Zugriffskontrolle werden Schlüssel für Keystore mit einem Schlüsseldeskriptor identifiziert. Dieser Schlüsseldeskriptor gibt eine Domain an, zu der der Deskriptor gehört, zusammen mit einer Identität innerhalb dieser Domain.

Android-Apps greifen über die Standard-Java Cryptography Architecture auf Keystore zu, die Schlüssel mit einem String-Alias identifiziert. Diese Identifizierungsmethode wird intern der Keystore-Domain APP zugeordnet. Die UID des Aufrufers ist ebenfalls enthalten, um Schlüssel von verschiedenen Apps zu unterscheiden und zu verhindern, dass eine App auf die Schlüssel einer anderen App zugreift.

Intern erhält der Framework-Code auch eine eindeutige numerische Schlüssel-ID, nachdem ein Schlüssel geladen wurde. Diese numerische ID wird als Kennung für Schlüsseldeskriptoren in der Domain KEY_ID verwendet. Die Zugriffskontrolle wird jedoch weiterhin durchgeführt: Selbst wenn eine App eine Schlüssel-ID für den Schlüssel einer anderen App findet, kann sie sie unter normalen Umständen nicht verwenden.

Es ist jedoch möglich, dass eine App einer anderen App (identifiziert durch UID) die Verwendung eines Schlüssels gewährt. Dieser Vorgang gibt eine eindeutige Berechtigungs-ID zurück, die als Kennung für Schlüsseldeskriptoren in der Domain GRANT verwendet wird. Auch hier wird die Zugriffskontrolle weiterhin durchgeführt: Selbst wenn eine Drittanbieter-App die Berechtigungs-ID für den Schlüssel eines Berechtigten findet, kann sie sie nicht verwenden.

Keystore unterstützt auch zwei weitere Domains für Schlüsseldeskriptoren, die für andere Systemkomponenten verwendet werden und nicht für von Apps erstellte Schlüssel verfügbar sind:

  • Die BLOB Domain gibt an, dass im Schlüsseldeskriptor keine Kennung für den Schlüssel vorhanden ist. Stattdessen enthält der Schlüsseldeskriptor den Keyblob selbst und der Client verwaltet die Speicherung des Keyblobs. Dies wird von Clients (z. B. vold) verwendet, die auf Keystore zugreifen müssen, bevor die Daten partition eingebunden wird.
  • Die SELINUX Domain ermöglicht es Systemkomponenten, Schlüssel gemeinsam zu nutzen, Der Zugriff wird durch eine numerische Kennung gesteuert, die einem SELinux Label entspricht (siehe SELinux-Richtlinie für keystore_key).

SELinux-Richtlinie für keystore_key

Die für Domain::SELINUX-Schlüsseldeskriptoren verwendeten Kennungswerte werden in der SELinux-Richtliniendatei keystore2_key_context konfiguriert. Jede Zeile in diesen Dateien ordnet eine Zahl einem SELinux-Label zu, z. B.:

# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and
# Settings to share Keystore keys.
102            u:object_r:wifi_key:s0

Eine Komponente, die Zugriff auf den Schlüssel mit der ID 102 in der Domain SELINUX benötigt, muss die entsprechende SELinux-Richtlinie haben. Wenn Sie beispielsweise zulassen möchten, dass wpa_supplicant diese Schlüssel abruft und verwendet, fügen Sie hal_wifi_supplicant.te die folgende Zeile hinzu:

allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };

Die numerischen Kennungen für Domain::SELINUX-Schlüssel sind in Bereiche unterteilt, um verschiedene Partitionen ohne Konflikte zu unterstützen:

Partition Bereich Konfigurationsdateien
System 0 ... 9.999 /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
Erweitertes System 10.000 ... 19.999 /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
Produkt 20.000 ... 29.999 /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
Vendor 30.000 ... 39.999 /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts

Für die Systempartition wurden die folgenden spezifischen Werte definiert:

Namespace-ID SEPolicy-Label UID Beschreibung
0 su_key – Superuser-Schlüssel. Wird nur für Tests in Userdebug- und Eng-Builds verwendet. In Nutzer-Builds nicht relevant.
1 shell_key – Namespace für die Shell verfügbar. Wird hauptsächlich für Tests verwendet, kann aber auch in Nutzer-Builds über die Befehlszeile verwendet werden.
100 vold_key – Für die Verwendung durch „vold“ vorgesehen.
101 odsign_key – Wird vom On-Device-Signatur-Daemon verwendet.
102 wifi_key AID_WIFI(1010) Wird vom WLAN-Subsystem von Android verwendet, einschließlich wpa_supplicant.
103 locksettings_key – Wird von LockSettingsService verwendet.
120 resume_on_reboot_key AID_SYSTEM(1000) Wird vom Systemserver von Android verwendet, um das Fortsetzen nach dem Neustart zu unterstützen.

Zugriffsvektoren

Keystore ermöglicht die Steuerung, welche Vorgänge für einen Schlüssel ausgeführt werden können, zusätzlich zur Steuerung des allgemeinen Zugriffs auf einen Schlüssel. Die keystore2_key Berechtigungen werden in der KeyPermission.aidl Datei beschrieben.

Systemberechtigungen

Zusätzlich zu den Zugriffskontrollen pro Schlüssel, die in der SELinux-Richtlinie für keystore_key beschrieben sind, werden in der folgenden Tabelle weitere SELinux-Berechtigungen beschrieben, die für die Ausführung verschiedener System- und Wartungsvorgänge erforderlich sind:

Berechtigung Bedeutung
add_auth Erforderlich, um Authentifizierungstokens zu Keystore hinzuzufügen. Wird von Authentifizierungsanbietern wie Gatekeeper oder BiometricManager verwendet.
clear_ns Erforderlich, um alle Schlüssel in einem bestimmten Namespace zu löschen. Wird als Wartungsvorgang verwendet, wenn Apps deinstalliert werden.
list Erforderlich, damit das System Schlüssel nach verschiedenen Eigenschaften auflisten kann, z. B. nach Eigentümer oder danach, ob sie an die Authentifizierung gebunden sind. Diese Berechtigung ist für Aufrufer nicht erforderlich, die ihre eigenen Namespaces auflisten (durch die Berechtigung get_info abgedeckt).
lock Erforderlich, um Keystore zu benachrichtigen, dass das Gerät gesperrt wurde. Dadurch werden Super-Schlüssel entfernt, um sicherzustellen, dass authentifizierungsgebundene Schlüssel nicht verfügbar sind.
unlock Erforderlich, um Keystore zu benachrichtigen, dass das Gerät entsperrt wurde. Dadurch wird der Zugriff auf die Super-Schlüssel wiederhergestellt, die authentifizierungsgebundene Schlüssel schützen.
reset Erforderlich, um Keystore auf die Werkseinstellungen zurückzusetzen und alle Schlüssel zu löschen, die für die Funktion des Android-Betriebssystems nicht unbedingt erforderlich sind.

Verlauf

In Android 5 und niedriger gab es eine einfache, hardwaregestützte API für kryptografische Dienste, die von den Versionen 0.2 und 0.3 der Keymaster-Hardwareabstraktionsschicht (HAL) bereitgestellt wurde. Keystore bot Vorgänge für digitale Signaturen und Überprüfungen sowie die Generierung und den Import von asymmetrischen Signaturschlüsselpaaren. Dies ist bereits auf vielen Geräten implementiert, aber es gibt viele Sicherheitsziele, die mit einer reinen Signatur-API nicht einfach erreicht werden können. In Android 6.0 wurde die Keystore API erweitert, um ein breiteres Spektrum an Funktionen zu bieten.

Android 6.0

In Android 6.0 wurden mit Keymaster 1.0 symmetrische kryptografische Primitive, AES und HMAC, sowie ein Zugriffskontrollsystem für hardwaregestützte Schlüssel hinzugefügt. Zugriffskontrollen werden bei der Schlüsselerstellung angegeben und für die gesamte Lebensdauer des Schlüssels erzwungen. Schlüssel können so eingeschränkt werden, dass sie nur verwendet werden können, nachdem der Nutzer authentifiziert wurde, und nur für bestimmte Zwecke oder mit bestimmten kryptografischen Parametern.

Neben der Erweiterung des Spektrums an kryptografischen Primitiven wurden in Keystore in Android 6.0 die folgenden Funktionen hinzugefügt:

  • Ein Nutzungssteuerungsschema, mit dem die Schlüsselnutzung eingeschränkt werden kann, um das Risiko von Sicherheitsverstößen durch Missbrauch von Schlüsseln zu verringern
  • Ein Zugriffssteuerungsschema, mit dem Schlüssel auf bestimmte Nutzer, Clients und einen definierten Zeitraum beschränkt werden können

Android 7.0

In Android 7.0 wurde mit Keymaster 2 Unterstützung für die Schlüsselattestierung und die Versionsbindung hinzugefügt.

Die Schlüsselattestierung bietet Public-Key-Zertifikate, die eine detaillierte Beschreibung des Schlüssels und seiner Zugriffskontrollen enthalten, um die Existenz des Schlüssels in sicherer Hardware und seine Konfiguration aus der Ferne überprüfbar zu machen.

Versionsbindung bindet Schlüssel an die Betriebssystem- und Patchebeneversion. So wird verhindert, dass ein Angreifer, der eine Schwachstelle in einer alten Version des Systems oder der TEE-Software entdeckt, ein Gerät auf die anfällige Version zurücksetzen und Schlüssel verwenden kann, die mit der neueren Version erstellt wurden. Wenn ein Schlüssel mit einer bestimmten Version und Patchebene auf einem Gerät verwendet wird, das auf eine neuere Version oder Patchebene aktualisiert wurde, wird der Schlüssel aktualisiert, bevor er verwendet werden kann, und die vorherige Version des Schlüssels wird ungültig gemacht. Wenn das Gerät aktualisiert wird, werden auch die Schlüssel aktualisiert. Wenn das Gerät jedoch auf eine frühere Version zurückgesetzt wird, können die Schlüssel nicht mehr verwendet werden.

Android 8.0

In Android 8.0 wurde Keymaster 3 von der alten C-Struktur-HAL auf die C++-HAL-Schnittstelle umgestellt, die aus einer Definition in der neuen Hardware Interface Definition Language (HIDL) generiert wurde. Im Rahmen der Umstellung wurden viele Argumenttypen geändert. Die Typen und Methoden haben jedoch eine Eins-zu-eins-Entsprechung zu den alten Typen und den HAL-Strukturmethoden.

Zusätzlich zu dieser Schnittstellenüberarbeitung wurde in Android 8.0 die Attestierungsfunktion von Keymaster 2 erweitert, um die ID-Attestierung zu unterstützen. Die ID-Attestierung bietet einen eingeschränkten und optionalen Mechanismus, um Hardwarekennungen wie die Seriennummer des Geräts, den Produktnamen und die Telefon-ID (IMEI oder MEID) stark zu attestieren. Um diese Erweiterung zu implementieren, wurde in Android 8.0 das ASN.1-Attestierungsschema geändert, um die ID-Attestierung hinzuzufügen. Keymaster-Implementierungen müssen eine sichere Möglichkeit finden, die relevanten Datenelemente abzurufen, sowie einen Mechanismus definieren, um die Funktion sicher und dauerhaft zu deaktivieren.

Android 9

In Android 9 gab es folgende Updates:

  • Update auf Keymaster 4
  • Unterstützung für eingebettete Secure Elements
  • Unterstützung für den sicheren Import von Schlüsseln
  • Unterstützung für die 3DES-Verschlüsselung
  • Änderungen an der Versionsbindung, sodass boot.img und system.img separat festgelegte Versionen vorhanden sind, um unabhängige Updates zu ermöglichen

Android 10

In Android 10 wurde Version 4.1 der Keymaster-HAL eingeführt, die Folgendes hinzugefügt hat:

  • Unterstützung für Schlüssel, die nur verwendet werden können, wenn das Gerät entsperrt ist
  • Unterstützung für Schlüssel, die nur in frühen Startphasen verwendet werden können
  • Optionale Unterstützung für hardwareumschlossene Speicherschlüssel Schlüssel
  • Optionale Unterstützung für die gerätespezifische Attestierung in StrongBox

Android 12

In Android 12 wurde die neue KeyMint-HAL eingeführt, die die Keymaster-HAL ersetzt, aber ähnliche Funktionen bietet. Zusätzlich zu allen oben genannten Funktionen umfasst die KeyMint-HAL auch:

  • Unterstützung für die ECDH-Schlüsselvereinbarung
  • Unterstützung für nutzerspezifische Attestierungsschlüssel
  • Unterstützung für Schlüssel mit einer begrenzten Anzahl von Verwendungen

Android 12 enthält auch eine neue Version des Keystore-System-Daemons, der in Rust neu geschrieben wurde und als keystore2 bezeichnet wird.

Android 13

In Android 13 wurde die Version 2 der KeyMint-HAL hinzugefügt, die Unterstützung für Curve25519 sowohl für die Signierung als auch für die Schlüsselvereinbarung bietet.