Gatekeeper

Das Gatekeeper-Subsystem führt die Authentifizierung von Gerätemustern und ‑passwörtern in einer vertrauenswürdigen Ausführungsumgebung (Trusted Execution Environment, TEE) durch. Gatekeeper registriert und verifiziert Passwörter mithilfe eines hardwaregestützten geheimen Schlüssels. Außerdem drosselt Gatekeeper aufeinanderfolgende fehlgeschlagene Bestätigungsversuche und muss Anfragen nach einer bestimmten Zeitüberschreitung und einer bestimmten Anzahl aufeinanderfolgender fehlgeschlagener Versuche ablehnen.

Wenn Nutzer ihre Passwörter bestätigen, gibt Gatekeeper ein Authentifizierungstoken aus, das mit einem HMAC-Schlüssel pro Bootvorgang signiert ist, der nur für sichere Komponenten verfügbar ist. Dieses Token wird an den hardwaregestützten Keystore gesendet. Das heißt, ein Gatekeeper-Authentifizierungstoken benachrichtigt den Keystore, dass authentifizierungsgebundene Schlüssel (z. B. von Apps erstellte Schlüssel) von Apps verwendet werden können.

Architektur

Gatekeeper umfasst drei Hauptkomponenten:

  • gatekeeperd (Gatekeeper-Daemon) – Ein C++-Binder-Dienst in Android, der plattformunabhängige Logik enthält, die die AIDL-Schnittstelle IGateKeeperService basierend auf einer zugrunde liegenden herstellerspezifischen Implementierung von IGatekeeper implementiert.
  • Gatekeeper-HAL-Dienst (Hardwareabstraktionsschicht): Eine anbieterspezifische Implementierung der AIDL-Schnittstelle IGatekeeper. Dieser HAL-Dienst wird in Android ausgeführt, aber die Gatekeeper-Kernfunktionen müssen in einer sicheren Umgebung ausgeführt werden. Daher kommuniziert er in der Regel mit der Gatekeeper-TA.
  • Gatekeeper Trusted Application (TA): Eine herstellerspezifische Implementierung, die in der TEE ausgeführt wird und die eigentliche Passwort- oder Musterüberprüfung durchführt.

Die LockSettingsService stellt eine Anfrage (über Binder), die den gatekeeperd-Daemon im Android-Betriebssystem erreicht. Der Daemon gatekeeperd stellt dann eine Anfrage an den HAL-Dienst IGatekeeper, der wiederum den Gatekeeper-TA in der TEE erreicht:

Gatekeeper-Ablauf

Abbildung 1. Allgemeiner Datenfluss für die Authentifizierung durch GateKeeper.

Der Daemon gatekeeperd ermöglicht den Android-Framework-APIs den Zugriff auf die HAL und ist an der Meldung von Geräteauthentifizierungen an Keystore beteiligt. Der gatekeeperd-Daemon wird in einem eigenen Prozess ausgeführt und ist vom Systemserver getrennt.

HAL-Implementierung

Der gatekeeperd-Daemon verwendet die IGatekeeper-HAL, um mit der zugrunde liegenden Gatekeeper-TA für die Passwortauthentifizierung zu interagieren. Die Gatekeeper-TA-Implementierung muss in der Lage sein, Blobs zu signieren (registrieren) und zu verifizieren. Alle Implementierungen müssen dem Standardformat für das Authentifizierungstoken (HardwareAuthToken) entsprechen, das bei jeder erfolgreichen Passwortbestätigung generiert wird. Weitere Informationen zum Inhalt und zur Semantik von HardwareAuthToken finden Sie in der Definition von HardwareAuthToken.aidl.

Anbieterimplementierungen der IGatekeeper-HAL müssen die Funktionen enroll und verify implementieren:

  • Die Methode enroll akzeptiert ein Passwort-Blob, signiert es und gibt die Signatur als Handle zurück. Das zurückgegebene Blob (aus einem Aufruf von enroll) muss die in system/gatekeeper/include/gatekeeper/password_handle.h gezeigte Struktur haben.
  • Die Funktion verify muss die Signatur, die durch das angegebene Passwort erzeugt wird, mit dem registrierten Passwort-Handle vergleichen und sicherstellen, dass sie übereinstimmen.

Der für die Registrierung und Überprüfung verwendete Schlüssel darf sich nie ändern und sollte bei jedem Gerätestart 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. Gatekeeper kann jedoch von jedem TEE-Betriebssystem implementiert werden, solange das TEE Zugriff auf einen persistenten hardwaregestützten Schlüssel und eine sichere, monotone Uhr hat, die im Ruhezustand weiterläuft.

Trusty verwendet ein internes IPC-System, um ein gemeinsames Secret direkt zwischen KeyMint (früher Keymaster) und der Trusty-Implementierung von Gatekeeper (Trusty Gatekeeper) zu übertragen. Dieses gemeinsame Secret wird zum Signieren von Authentifizierungstokens verwendet, die an den Keystore gesendet werden, um Bestätigungen der Passwortüberprüfung bereitzustellen. Trusty Gatekeeper fordert den Schlüssel bei jeder Verwendung von KeyMint an und speichert den Wert nicht dauerhaft oder im Cache. Implementierungen können dieses Secret auf jede Weise teilen, die die Sicherheit nicht gefährdet.

Der HMAC-Schlüssel, der zum Registrieren und Bestätigen von Passwörtern verwendet wird, wird ausschließlich in Gatekeeper abgeleitet und aufbewahrt.

Android bietet eine generische C++-Gatekeeper-Implementierung, die nur durch gerätespezifische Routinen ergänzt werden muss. Die Trusty-Implementierung basiert darauf. 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. Zu den Hauptaufgaben einer konformen Implementierung gehören:

  • Einhaltung des IGatekeeper-HAL.
  • Zurückgegebene Authentifizierungstokens müssen gemäß der HardwareAuthToken-Spezifikation formatiert sein (beschrieben in HardwareAuthToken.aidl).
  • Der TEE-Gatekeeper muss einen HMAC-Schlüssel mit KeyMint teilen können. Dazu muss eine der folgenden Optionen verwendet werden:
    • Vereinbarung über einen gemeinsamen geheimen Schlüssel: Gatekeeper kann an der Aushandlung des HMAC-Schlüssels pro Bootvorgang teilnehmen, indem die HAL ISharedSecret implementiert wird. Dazu müssen Gatekeeper und KeyMint Zugriff auf ein gemeinsames vorinstalliertes Secret haben.
    • Direkter Zugriff: Gatekeeper kann den HMAC-Schlüssel über einen TEE-internen Interprocess Communication-Mechanismus von KeyMint abrufen, entweder bei Bedarf oder bei der ersten Verwendung (danach im Cache gespeichert).

Sicherheits-IDs (SIDs) von Nutzern

Eine Nutzer-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 Neuregistrierung bezeichnet und tritt normalerweise nur auf, wenn ein Nutzer zum ersten Mal ein Passwort oder Muster festlegt.

Eine vertrauenswürdige Neuregistrierung erfolgt, wenn ein Nutzer ein gültiges, vorheriges Passwort angibt, z. B. beim Ändern des Passworts. In diesem Fall wird die Nutzer-SID zum neuen Passwort-Handle migriert, wobei die daran gebundenen Schlüssel beibehalten werden.

Die Nutzer-SID ist zusammen mit dem Passwort im Passwort-Handle in der HMAC-Authentifizierung enthalten, wenn das Passwort registriert wird.

Nutzer-SIDs sind in der HardwareAuthToken enthalten, die von der Funktion verify() zurückgegeben wird, und sind mit allen authentifizierungsgebundenen Keystore-Schlüsseln verknüpft. Weitere Informationen zum HardwareAuthToken-Format und zum Keystore finden Sie unter Authentifizierung.

Beachten Sie, dass ein nicht vertrauenswürdiger Aufruf der Funktion enroll() die Nutzer-SID ändert und die an dieses Passwort gebundenen Schlüssel unbrauchbar macht. Angreifer können das Passwort für das Gerät ändern, wenn sie das Android-Betriebssystem kontrollieren, zerstören dabei aber die durch Root-Zugriff geschützten, sensiblen Schlüssel.

Anfragedrosselung

Gatekeeper muss in der Lage sein, Brute-Force-Angriffe auf Nutzeranmeldedaten sicher zu drosseln. Wie in GatekeeperVerifyResponse.aidl gezeigt, ermöglicht die HAL die Rückgabe eines Zeitlimits in Millisekunden. Das Zeitlimit informiert den Client, Gatekeeper erst nach Ablauf des Zeitlimits wieder aufzurufen. Gatekeeper sollte keine Anfragen verarbeiten, wenn ein Zeitlimit aussteht.

Gatekeeper muss einen Fehlerzähler schreiben, bevor ein Nutzerpasswort überprüft wird. Wenn die Passwortüberprüfung erfolgreich ist, sollte der Fehlerzähler gelöscht werden. Dadurch werden Angriffe verhindert, die die Drosselung verhindern, indem die eingebettete MMC (eMMC) nach dem Ausführen eines verify-Aufrufs deaktiviert wird. Die Funktion enroll überprüft auch das Nutzerpasswort (falls angegeben) und muss auf dieselbe Weise gedrosselt werden.

Wenn das Gerät dies 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 den Replay Protected Memory Block (RPMB) direkt verwenden.