Das Gatekeeper-Subsystem führt die Gerätemuster-/Passwortauthentifizierung in einer Trusted Execution Environment (TEE) durch. Gatekeeper registriert und überprüft Passwörter über einen HMAC mit einem hardwaregestützten geheimen Schlüssel. Darüber hinaus drosselt Gatekeeper aufeinanderfolgende fehlgeschlagene Verifizierungsversuche und muss die Bearbeitung von Anfragen basierend auf einem bestimmten Zeitlimit und einer bestimmten Anzahl aufeinanderfolgender fehlgeschlagener Versuche ablehnen.
Wenn Benutzer ihre Passwörter überprüfen, verwendet Gatekeeper das von TEE abgeleitete gemeinsame Geheimnis, um eine Authentifizierungsbescheinigung zu signieren, die an den hardwaregestützten Keystore gesendet wird. Das heißt, eine Gatekeeper-Bescheinigung benachrichtigt Keystore darüber, dass an die Authentifizierung gebundene Schlüssel (z. B. von Apps erstellte Schlüssel) für die Verwendung durch Apps freigegeben werden können.
Die Architektur
Gatekeeper umfasst drei Hauptkomponenten:
-
gatekeeperd
(Gatekeeper-Daemon). Ein C++-Binderdienst, der plattformunabhängige Logik enthält und derGateKeeperService
Java-Schnittstelle entspricht. - Gatekeeper Hardware Abstraction Layer (HAL) . Die HAL-Schnittstelle in
hardware/libhardware/include/hardware/gatekeeper.h
und das implementierende Modul. - Pförtner (TEE) . Das TEE-Gegenstück von
gatekeeperd
. Eine TEE-basierte Implementierung von Gatekeeper.
Gatekeeper erfordert die Implementierung der Gatekeeper-HAL (insbesondere der Funktionen in hardware/libhardware/include/hardware/gatekeeper.h
) und der TEE-spezifischen Gatekeeper-Komponente (teilweise basierend auf der Header-Datei system/gatekeeper/include/gatekeeper/gatekeeper.h
Dazu gehören rein virtuelle Funktionen zum Erstellen/Zugreifen auf Schlüssel und zum Berechnen von Signaturen.
Der LockSettingsService
stellt eine Anfrage (über Binder), die den gatekeeperd
Daemon im Android-Betriebssystem erreicht. Der gatekeeperd
Daemon stellt dann eine Anfrage, die sein Gegenstück (Gatekeeper) im TEE erreicht:
![Gatekeeper-Flow](https://source.android.google.cn/static/docs/security/images/gatekeeper-flow.png?authuser=6&hl=de)
Der gatekeeperd
Daemon gewährt den Android-Framework-APIs Zugriff auf die HAL und beteiligt sich an der Meldung von Geräteauthentifizierungen an Keystore. Der gatekeeperd
Daemon läuft in einem eigenen Prozess und ist vom Systemserver getrennt.
HAL-Implementierung
Der gatekeeperd
Daemon verwendet die HAL, um mit dem TEE-Gegenstück des gatekeeperd
Daemons zur Passwortauthentifizierung zu interagieren. Die HAL-Implementierung muss in der Lage sein, Blobs zu signieren (registrieren) und zu überprüfen. Von allen Implementierungen wird erwartet, dass sie dem Standardformat für das Authentifizierungstoken (AuthToken) entsprechen, das bei jeder erfolgreichen Passwortüberprüfung generiert wird. Einzelheiten zum Inhalt und zur Semantik des AuthToken finden Sie unter AuthToken-Format .
Implementierungen der Headerdatei hardware/libhardware/include/hardware/gatekeeper.h
müssen die enroll
und verify
implementieren:
- Die
enroll
Funktion 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
verify
muss die durch das bereitgestellte Passwort erzeugte Signatur vergleichen und sicherstellen, dass sie mit dem registrierten Passwort-Handle übereinstimmt.
Der zur Registrierung und Überprüfung verwendete Schlüssel darf sich niemals ändern und sollte bei jedem Gerätestart erneut ableitbar sein.
Trusty und andere Implementierungen
Das Trusty- Betriebssystem ist Googles vertrauenswürdiges Open-Source-Betriebssystem für TEE-Umgebungen und enthält eine genehmigte Implementierung von GateKeeper. Sie können jedoch jedes TEE-Betriebssystem zum Implementieren von Gatekeeper verwenden, solange das TEE Zugriff auf einen hardwaregestützten Schlüssel und eine sichere, monotone Uhr hat , die im Suspend-Modus tickt .
Trusty verwendet ein internes IPC-System, um ein gemeinsames Geheimnis direkt zwischen Keymaster und der Trusty-Implementierung von Gatekeeper (dem Trusty Gatekeeper ) zu kommunizieren. Dieses gemeinsame Geheimnis wird zum Signieren von AuthTokens verwendet, die an Keystore gesendet werden, um Bescheinigungen für die Passwortüberprüfung bereitzustellen. Trusty Gatekeeper fordert den Schlüssel für jede Verwendung von Keymaster an und speichert den Wert nicht dauerhaft oder zwischenspeichert ihn. Den Implementierungen steht es frei, dieses Geheimnis auf jede Art und Weise weiterzugeben, die die Sicherheit nicht gefährdet.
Der HMAC-Schlüssel, der zum Registrieren und Überprüfen von Passwörtern verwendet wird, wird ausschließlich in GateKeeper abgeleitet und gespeichert.
Android bietet eine generische C++-Implementierung von GateKeeper, die lediglich das Hinzufügen gerätespezifischer Routinen erfordert, um vollständig zu sein. Informationen zum Implementieren eines TEE-Gatekeepers mit gerätespezifischem Code für Ihr TEE finden Sie in den Funktionen und Kommentaren in system/gatekeeper/include/gatekeeper/gatekeeper.h
. Für den TEE GateKeeper gehören zu den Hauptaufgaben einer konformen Implementierung:
- Einhaltung des Gatekeeper HAL.
- Zurückgegebene AuthTokens müssen gemäß der AuthToken-Spezifikation formatiert sein (beschrieben unter Authentifizierung ).
- Der TEE-Gatekeeper muss in der Lage sein, einen HMAC-Schlüssel mit Keymaster zu teilen, indem er entweder den Schlüssel bei Bedarf über einen TEE-IPC anfordert oder jederzeit einen gültigen Cache des Werts verwaltet.
Benutzersichere IDs (SIDs)
Eine Benutzer-SID ist die TEE-Darstellung eines Benutzers (ohne starke Verbindung zu einer Android-Benutzer-ID). Die SID wird mit einem kryptografischen Pseudozufallszahlengenerator (PRNG) generiert, wenn ein Benutzer ein neues Passwort eingibt, ohne ein vorheriges anzugeben. Dies wird als nicht vertrauenswürdige erneute Registrierung bezeichnet und ist vom Android-Framework unter normalen Umständen nicht zulässig. Eine vertrauenswürdige Neuregistrierung erfolgt, wenn ein Benutzer ein gültiges, vorheriges Passwort angibt; In diesem Fall wird die Benutzer-SID auf das neue Passwort-Handle migriert, wobei die daran gebundenen Schlüssel erhalten bleiben.
Die Benutzer-SID wird zusammen mit dem Passwort im Passwort-Handle HMAC-verschlüsselt, wenn das Passwort registriert wird.
Benutzer-SIDs werden in das von der verify
zurückgegebene AuthToken geschrieben und allen authentifizierungsgebundenen Keystore-Schlüsseln zugeordnet (Einzelheiten zum AuthToken-Format und zum Keystore finden Sie unter Authentifizierung ). Da ein nicht vertrauenswürdiger Aufruf der enroll
die Benutzer-SID ändert, werden die an dieses Kennwort gebundenen Schlüssel durch den Aufruf unbrauchbar. Angreifer können das Passwort für das Gerät ändern, wenn sie das Android-Betriebssystem kontrollieren, zerstören dabei aber root-geschützte, sensible Schlüssel.
Drosselung anfordern
GateKeeper muss in der Lage sein, Brute-Force-Versuche an Benutzeranmeldeinformationen sicher zu drosseln. Wie in hardware/libhardware/include/hardware/gatekeeper.h
gezeigt, sorgt die HAL für die Rückgabe eines Timeouts in Millisekunden. Das Timeout informiert den Client, GateKeeper erst nach Ablauf des Timeouts erneut aufzurufen; GateKeeper sollte Anfragen nicht bearbeiten, wenn eine Zeitüberschreitung ansteht.
GateKeeper muss einen Fehlerzähler schreiben, bevor ein Benutzerkennwort überprüft wird. Wenn die Passwortüberprüfung erfolgreich ist, sollte der Fehlerzähler gelöscht werden. Dies verhindert Angriffe, die eine Drosselung verhindern, indem die eingebettete MMC (eMMC) nach dem Ausgeben eines verify
deaktiviert wird. Die enroll
überprüft auch das Benutzerkennwort (falls angegeben) und muss auf die gleiche Weise gedrosselt werden.
Sofern 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 direkt Replay Protected Memory Block (RPMB) verwenden.