Das Gatekeeper-Subsystem führt die Authentifizierung des Gerätemusters/Passworts in einer vertrauenswürdigen Ausführungsumgebung (Trusted Execution Environment, TEE) durch. Gatekeeper registriert und verifiziert Passwörter über einen HMAC mit einem hardwaregestützten geheimen Schlüssel. Außerdem drosselt Gatekeeper aufeinanderfolgende fehlgeschlagene Bestätigungsversuche und muss Anfragen basierend auf einem bestimmten Zeitlimit und einer bestimmten Anzahl aufeinanderfolgender fehlgeschlagener Versuche ablehnen.
Wenn Nutzer ihre Passwörter bestätigen, verwendet Gatekeeper das aus dem TEE abgeleitete gemeinsame Geheimnis, um eine Authentifizierungsattestierung zu signieren, die an den hardwaregestützten Schlüsselspeicher gesendet wird. Das heißt, dass eine Gatekeeper-Attestierung den Keystore darüber informiert, dass authentifizierungsgebundene Schlüssel (z. B. von Apps erstellte Schlüssel) für die Verwendung durch Apps freigegeben werden können.
Architektur
Gatekeeper umfasst drei Hauptkomponenten:
gatekeeperd
(Gatekeeper-Daemon). Ein C++-Binderdienst mit platformunabhängiger Logik, der derGateKeeperService
-Java-Schnittstelle entspricht.- Gatekeeper Hardware Abstraction Layer (HAL) Die HAL-Schnittstelle in
hardware/libhardware/include/hardware/gatekeeper.h
und das Implementierungsmodul. - Gatekeeper (TEE) Das TEE-Äquivalent von
gatekeeperd
. Eine TEE-basierte Implementierung von Gatekeeper.
Für Gatekeeper ist die Implementierung der Gatekeeper HAL (insbesondere der Funktionen in hardware/libhardware/include/hardware/gatekeeper.h
) und der TEE-spezifischen Gatekeeper-Komponente erforderlich. Letztere basiert teilweise auf der Headerdatei system/gatekeeper/include/gatekeeper/gatekeeper.h
, die reine virtuelle Funktionen zum Erstellen/Zugreifen auf Schlüssel und zum Berechnen von Signaturen enthält.
Der LockSettingsService
sendet eine Anfrage (über Binder), die den gatekeeperd
-Daemon im Android-Betriebssystem erreicht. Der gatekeeperd
-Daemon stellt dann eine Anfrage, die sein Pendant (Gatekeeper) im TEE erreicht:

Der gatekeeperd
-Daemon gewährt den Android-Framework-APIs Zugriff auf die HAL und trägt zur Meldung von Geräte-Authentifizierungen an den Schlüsselspeicher bei.
Der gatekeeperd
-Daemon wird in einem eigenen Prozess ausgeführt und ist unabhängig vom Systemserver.
HAL-Implementierung
Der gatekeeperd
-Daemon verwendet die HAL, um für die Passwortauthentifizierung mit dem TEE-Pendant des gatekeeperd
-Daemons zu interagieren. Die HAL-Implementierung muss Blobs signieren (registrieren) und verifizieren können. Alle Implementierungen müssen dem Standardformat für das Authentifizierungstoken (AuthToken) entsprechen, das bei jeder erfolgreichen Passwortbestätigung generiert wird. Weitere Informationen zum Inhalt und zur Semantik des AuthTokens finden Sie unter AuthToken-Format.
Implementierungen der hardware/libhardware/include/hardware/gatekeeper.h
-Headerdatei müssen die Funktionen enroll
und verify
implementieren:
- Die Funktion
enroll
nimmt einen Passwort-Blob, signiert ihn und gibt die Signatur als Handle zurück. Der zurückgegebene Blob (von einem Aufruf vonenroll
) muss die insystem/gatekeeper/include/gatekeeper/password_handle.h
gezeigte Struktur haben. - Die Funktion
verify
muss die vom angegebenen Passwort generierte Signatur mit dem registrierten Passwort-Handle vergleichen und dafür sorgen, dass sie übereinstimmt.
Der Schlüssel, der für die Registrierung und Bestätigung verwendet wird, darf sich niemals ändern und sollte bei jedem Start des Geräts neu abgeleitet werden können.
Trusty und andere Implementierungen
Das Betriebssystem Trusty ist das vertrauenswürdige Open-Source-Betriebssystem von Google für TEE-Umgebungen und enthält eine genehmigte Implementierung von GateKeeper. Sie können jedoch beliebige TEE-Betriebssysteme verwenden, um Gatekeeper zu implementieren, solange die TEE Zugriff auf einen hardwaregestützten Schlüssel und eine sichere, monotone Uhr hat, die auch im Ruhemodus weiterläuft.
Trusty verwendet ein internes IPC-System, um ein freigegebenes Secret direkt zwischen Keymaster und der Trusty-Implementierung von Gatekeeper (Trusty Gatekeeper) auszutauschen. Dieses gemeinsame Secret wird zum Signieren von AuthTokens verwendet, die an den Keystore gesendet werden, um Attestierungen zur Passwortbestätigung bereitzustellen. Trusty Gatekeeper fordert den Schlüssel bei jeder Verwendung von Keymaster an und speichert den Wert nicht oder legt ihn nicht im Cache ab. Implementierungen können dieses Secret auf jede Weise freigeben, die die Sicherheit nicht beeinträchtigt.
Der HMAC-Schlüssel, der zum Registrieren und Verifizieren von Passwörtern verwendet wird, wird ausschließlich in GateKeeper abgeleitet und gespeichert.
Android bietet eine generische C++-Implementierung von GateKeeper, die nur durch Hinzufügen von gerätespezifischen Routinen vervollständigt werden muss. Informationen zum Implementieren eines TEE-Gatekeepers mit gerätespezifischem Code für Ihre TEE finden Sie in den Funktionen und Kommentaren in system/gatekeeper/include/gatekeeper/gatekeeper.h
.
Für den TEE GateKeeper gehören zu den wichtigsten Aufgaben einer konformen Implementierung:
- Einhaltung der Gatekeeper HAL
- Zurückgegebene AuthTokens müssen gemäß der AuthToken-Spezifikation formatiert sein (siehe Authentifizierung).
- Der TEE-Gatekeeper muss in der Lage sein, einen HMAC-Schlüssel für Keymaster freizugeben, entweder indem er den Schlüssel bei Bedarf über eine TEE-IPC anfordert oder jederzeit einen gültigen Cache des Werts verwaltet.
Sichere Nutzer-IDs (SIDs)
Eine User-SID ist die TEE-Darstellung eines Nutzers (ohne starke Verbindung zu einer Android-Nutzer-ID). Die SID wird mit einem kryptografischen Pseudozufallszahlengenerator (PRNG) generiert, wenn ein Nutzer ein neues Passwort registriert, ohne ein vorheriges anzugeben. Dies wird als nicht vertrauenswürdige erneute Registrierung bezeichnet und ist im Normalfall nicht vom Android-Framework zulässig. Eine vertrauenswürdige Neuregistrierung erfolgt, wenn ein Nutzer ein gültiges, vorheriges Passwort angibt. In diesem Fall wird die Nutzer-SID zum neuen Passwort-Handle migriert und die damit verknüpften Schlüssel bleiben erhalten.
Die Nutzer-SID wird zusammen mit dem Passwort im Passwort-Handle mit HMAC gehasht, wenn das Passwort registriert wird.
Nutzer-SIDs werden in das AuthToken geschrieben, das von der Funktion verify
zurückgegeben wird, und mit allen authentifizierungsgebundenen Keystore-Schlüsseln verknüpft. Weitere Informationen zum AuthToken-Format und zum Keystore finden Sie unter Authentifizierung. Da ein nicht vertrauenswürdiger Aufruf der Funktion enroll
die Nutzer-SID ändert, werden die mit diesem Passwort verknüpften Schlüssel durch den Aufruf unbrauchbar. Angreifer können das Passwort für das Gerät ändern, wenn sie das Android-Betriebssystem steuern. Dabei werden jedoch root-geschützte, sensible Schlüssel zerstört.
Anfragen drosseln
GateKeeper muss in der Lage sein, Brute-Force-Angriffe auf Nutzeranmeldedaten sicher zu drosseln. Wie in hardware/libhardware/include/hardware/gatekeeper.h
dargestellt, gibt die HAL ein Zeitlimit in Millisekunden zurück. Das Zeitlimit informiert den Client, GateKeeper erst nach Ablauf des Zeitlimits noch einmal aufzurufen. GateKeeper sollte keine Anfragen bearbeiten, wenn ein anstehendes Zeitlimit vorliegt.
GateKeeper muss einen Fehlerzähler schreiben, bevor ein Nutzerpasswort überprüft wird. Wenn die Passwortbestätigung erfolgreich ist, sollte der Fehlerzähler gelöscht werden. So werden Angriffe verhindert, die das Drosseln verhindern, indem die eingebettete MMC (eMMC) nach einem verify
-Aufruf deaktiviert wird. Die Funktion enroll
überprüft auch das Nutzerpasswort (falls angegeben) und muss auf die gleiche Weise gedrosselt werden.
Wenn vom Gerät unterstützt, wird dringend empfohlen, den Fehlerzähler in einen sicheren Speicher zu schreiben. Wenn das Gerät keine dateibasierte Verschlüsselung unterstützt oder der sichere Speicher zu langsam ist, können Implementierungen RPMB (Replay Protected Memory Block) direkt verwenden.