Pförtner

Das Gatekeeper-Subsystem führt eine Gerätemuster-/Kennwortauthentifizierung 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. Darüber hinaus drosselt Gatekeeper aufeinanderfolgende fehlgeschlagene Verifizierungsversuche und muss Anfragen basierend auf einer bestimmten Zeitüberschreitung und einer bestimmten Anzahl aufeinanderfolgender fehlgeschlagener Versuche ablehnen.

Wenn Benutzer ihre Kennwörter überprüfen, verwendet Gatekeeper das von TEE abgeleitete gemeinsame Geheimnis, um eine Authentifizierungsbescheinigung zu signieren, die an den hardwaregestützten Schlüsselspeicher gesendet wird . Das heißt, eine Gatekeeper-Bescheinigung benachrichtigt Keystore, dass authentifizierungsgebundene Schlüssel (z. B. von Apps erstellte Schlüssel) zur 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 der GateKeeperService -Java-Schnittstelle entspricht.
  • Gatekeeper-Hardware-Abstraktionsschicht (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 einschließlich rein virtueller Funktionen zum Erstellen/Zugreifen auf Schlüssel und 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-Fluss
Abbildung 1. Datenfluss auf hoher Ebene für die Authentifizierung durch GateKeeper

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 wird in einem eigenen Prozess ausgeführt und ist vom Systemserver getrennt.

HAL-Implementierung

Der gatekeeperd -Daemon verwendet die HAL, um mit dem TEE-Gegenstück des gatekeeperd -Daemon für die Kennwortauthentifizierung zu interagieren. Die HAL-Implementierung muss Blobs signieren (registrieren) und verifizieren können. Von allen Implementierungen wird erwartet, dass sie das Standardformat für das Authentifizierungstoken (AuthToken) einhalten, das bei jeder erfolgreichen Kennwortüberprüfung generiert wird. Einzelheiten zu Inhalt und Semantik des AuthToken finden Sie unter AuthToken-Format .

Implementierungen der Header-Datei hardware/libhardware/include/hardware/gatekeeper.h müssen die enroll und verify -Funktionen implementieren:

  • Die enroll Funktion nimmt ein Kennwort-Blob, signiert es und gibt die Signatur als Handle zurück. Das zurückgegebene Blob (von einem Aufruf von enroll ) muss die in system/gatekeeper/include/gatekeeper/password_handle.h gezeigte Struktur haben.
  • Die verify muss die vom bereitgestellten Passwort erzeugte Signatur vergleichen und sicherstellen, dass sie mit dem registrierten Passwort-Handle übereinstimmt.

Der zum Registrieren und Verifizieren verwendete Schlüssel darf sich nie ändern und sollte bei jedem Gerätestart neu ableitbar sein.

Trusty und andere Implementierungen

Das Trusty -Betriebssystem 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 jedes TEE-Betriebssystem verwenden, um Gatekeeper zu implementieren, solange das TEE Zugriff auf einen hardwaregestützten Schlüssel und eine sichere, monotone Uhr hat , die in suspend 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 Bestätigungen für die Kennwortüberprüfung bereitzustellen. Trusty Gatekeeper fordert den Schlüssel für jede Verwendung von Keymaster an und speichert oder speichert den Wert nicht. Es steht Implementierungen frei, dieses Geheimnis auf jede Weise weiterzugeben, die die Sicherheit nicht beeinträchtigt.

Der zum Registrieren und Verifizieren von Passwörtern verwendete HMAC-Schlüssel wird ausschließlich in GateKeeper abgeleitet und gespeichert.

Android bietet eine generische C++-Implementierung von GateKeeper, die nur das Hinzufügen von gerätespezifischen Routinen erfordert, um vollständig zu sein. Um einen TEE-Gatekeeper mit gerätespezifischem Code für Ihren TEE zu implementieren, lesen Sie die Funktionen und Kommentare in system/gatekeeper/include/gatekeeper/gatekeeper.h . Für den TEE GateKeeper gehören zu den Hauptaufgaben einer konformen Implementierung:

  • Einhaltung der Gatekeeper HAL.
  • Zurückgegebene AuthTokens müssen gemäß der AuthToken-Spezifikation formatiert sein (beschrieben in Authentifizierung ).
  • Der TEE Gatekeeper muss in der Lage sein, einen HMAC-Schlüssel mit Keymaster zu teilen, entweder indem er den Schlüssel bei Bedarf über einen TEE IPC anfordert oder jederzeit einen gültigen Cache des Werts verwaltet.

Sichere Benutzer-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 registriert, ohne ein vorheriges anzugeben. Dies wird als nicht vertrauenswürdige erneute Registrierung bezeichnet und wird vom Android-Framework unter normalen Umständen nicht zugelassen. Eine vertrauenswürdige Neuregistrierung erfolgt, wenn ein Benutzer ein gültiges, vorheriges Kennwort bereitstellt; In diesem Fall wird die Benutzer-SID zum neuen Kennwort-Handle migriert, wobei die daran gebundenen Schlüssel erhalten bleiben.

Die Benutzer-SID wird zusammen mit dem Kennwort im Kennwort-Handle HMAC-verarbeitet, wenn das Kennwort 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 Keystore finden Sie unter Authentifizierung ). Da ein nicht vertrauenswürdiger Aufruf der enroll die Benutzer-SID ändert, macht der Aufruf die an dieses Kennwort gebundenen Schlüssel unbrauchbar. Angreifer können das Passwort für das Gerät ändern, wenn sie das Android-Betriebssystem kontrollieren, aber sie zerstören dabei Root-geschützte, sensible Schlüssel.

Drosselung anfordern

GateKeeper muss in der Lage sein, Brute-Force-Versuche auf 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 nicht erneut aufzurufen, bis das Timeout abgelaufen ist; GateKeeper sollte Anfragen nicht bedienen, wenn eine Zeitüberschreitung ansteht.

GateKeeper muss einen Fehlerzähler schreiben, bevor ein Benutzerkennwort überprüft wird. Wenn die Kennwortüberprüfung erfolgreich ist, sollte der Fehlerzähler gelöscht werden. Dadurch werden Angriffe verhindert, die eine Drosselung verhindern, indem sie die eingebettete MMC (eMMC) deaktivieren, nachdem ein verify ausgegeben wurde. 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 wenn der sichere Speicher zu langsam ist, können Implementierungen Replay Protected Memory Block (RPMB) direkt verwenden.