Il sottosistema Gatekeeper esegue l'autenticazione tramite pattern/password del dispositivo in un Trusted Execution Environment (TEE). Gatekeeper registra e verifica le password tramite un HMAC con una chiave segreta basata sull'hardware. Inoltre, Gatekeeper limita i tentativi di verifica consecutivi non riusciti e deve rifiutarsi di gestire le richieste in base a un determinato timeout e a un determinato numero di tentativi consecutivi non riusciti.
Quando gli utenti verificano le loro password, Gatekeeper utilizza il segreto condiviso derivato dal TEE per firmare un'attestazione di autenticazione da inviare al Keystore basato su hardware. In altre parole, un'attestazione Gatekeeper comunica a Keystore che le chiavi legate all'autenticazione (ad esempio le chiavi create dalle app) possono essere rilasciate per l'utilizzo da parte delle app.
Architettura
Gatekeeper prevede tre componenti principali:
gatekeeperd
(demone Gatekeeper). Un servizio di binder C++ contenente logica indipendente dalla piattaforma e corrispondente all'GateKeeperService
interfaccia Java.- Livello di astrazione hardware (HAL) del gatekeeper. L'interfaccia HAL in
hardware/libhardware/include/hardware/gatekeeper.h
e il modulo di implementazione. - Gatekeeper (TEE). La controparte TEE di
gatekeeperd
. Un'implementazione di Gatekeeper basata su TEE.
Gatekeeper richiede l'implementazione dell'HAL Gatekeeper (in particolare le funzioni in hardware/libhardware/include/hardware/gatekeeper.h
) e del componente Gatekeeper specifico per il TEE (basato in parte sul file di intestazione system/gatekeeper/include/gatekeeper/gatekeeper.h
che include funzioni virtuali pure per la creazione/l'accesso alle chiavi e il calcolo delle firme).
LockSettingsService
invia una richiesta (tramite Binder) che raggiunge il daemon gatekeeperd
nel sistema operativo Android. Il daemon gatekeeperd
invia quindi una richiesta che raggiunge la sua controparte (Gatekeeper) nel TEE:

Il daemon gatekeeperd
concede alle API del framework Android l'accesso all'HAL e partecipa alla generazione di report sulle autenticazioni del dispositivo nell'archivio chiavi.
Il daemon gatekeeperd
viene eseguito in un processo separato e distinto dal server di sistema.
Implementazione HAL
Il daemon gatekeeperd
utilizza l'HAL per interagire con la controparte TEE del daemon gatekeeperd
per l'autenticazione tramite password. L'implementazione HAL deve essere in grado di firmare (registrare)
e verificare i blob. Tutte le implementazioni devono rispettare il formato standard per il token di autenticazione (AuthToken) generato a ogni verifica della password andata a buon fine. Per informazioni dettagliate sui contenuti e sulla semantica di AuthToken, consulta Formato AuthToken.
Le implementazioni del
file intestazione hardware/libhardware/include/hardware/gatekeeper.h
devono implementare le funzioni enroll
e verify
:
- La funzione
enroll
prende un blob della password, lo firma e restituisce la firma come handle. Il blob restituito (da una chiamata aenroll
) deve avere la struttura mostrata insystem/gatekeeper/include/gatekeeper/password_handle.h
. - La funzione
verify
deve confrontare la firma prodotta dalla password fornita e assicurarsi che corrisponda all'handle della password registrato.
La chiave utilizzata per la registrazione e la verifica non deve mai cambiare e deve essere ricavabile nuovamente a ogni avvio del dispositivo.
Trusty e altre implementazioni
Il sistema operativo Trusty è il sistema operativo attendibile open source di Google per gli ambienti TEE e contiene un'implementazione approvata di GateKeeper. Tuttavia, puoi utilizzare qualsiasi sistema operativo TEE per implementare Gatekeeper, a condizione che il TEE abbia accesso a una chiave basata su hardware e a un orologio monotonico sicuro che fa tic tac in sospensione.
Trusty utilizza un sistema IPC interno per comunicare una chiave segreta condivisa direttamente tra Keymaster e l'implementazione di Gatekeeper in Trusty (Trusty Gatekeeper). Questo segreto condiviso viene utilizzato per firmare gli AuthToken inviati al Keystore per fornire attestazioni di verifica della password. Trusty Gatekeeper richiede la chiave a Keymaster per ogni utilizzo e non mantiene o memorizza nella cache il valore. Le implementazioni sono libere di condividere questo secret in qualsiasi modo che non comprometta la sicurezza.
La chiave HMAC utilizzata per registrare e verificare le password viene ricavata e conservata esclusivamente in GateKeeper.
Android fornisce un'implementazione generica di GateKeeper in C++ che richiede solo l'aggiunta di routine specifiche per il dispositivo per essere completata. Per implementare un TEE Gatekeeper con codice specifico per il dispositivo per il tuo TEE, consulta le funzioni e i commenti in system/gatekeeper/include/gatekeeper/gatekeeper.h
.
Per TEE GateKeeper, le responsabilità principali di un'implementazione conforme includono:
- Conformità all'HAL di Gatekeeper.
- Gli AuthToken restituiti devono essere formattati in base alla specifica AuthToken (descritta in Autenticazione).
- Il TEE Gatekeeper deve essere in grado di condividere una chiave HMAC con Keymaster, richiedendo la chiave tramite un IPC TEE on demand o mantenendo sempre una cache valida del valore.
ID utente sicuri (SID)
Un SID utente è la rappresentazione TEE di un utente (senza una connessione stretta con un ID utente Android). L'SID viene generato con un generatore di numeri pseudocasuali (PRNG) ogni volta che un utente registra una nuova password senza fornirne una precedente. Si tratta di una ricollocazione non attendibile e non è consentita dal framework Android in circostanze normali. Una nuova registrazione attendibile avviene quando un utente fornisce una password precedente valida. In questo caso, viene eseguita la migrazione dell'SID utente al nuovo handle della password, conservando le chiavi associate.
L'SID utente viene sottoposto ad HMAC insieme alla password nell'handle della password quando la password viene registrata.
Gli SID utente vengono scritti nell'AuthToken restituito dalla funzione verify
e associati a tutte le chiavi del Keystore associate all'autenticazione (per dettagli
sul formato AuthToken e sul Keystore, consulta
Autenticazione). Poiché una chiamata non attendibile alla funzione enroll
modificherà l'SID utente, la chiamata renderà inutili le chiavi associate a quella password. Gli utenti malintenzionati possono cambiare la password del dispositivo se controllano il sistema operativo Android, ma durante la procedura distruggeranno le chiavi sensibili protette dal root.
Limitazione delle richieste
GateKeeper deve essere in grado di limitare in modo sicuro i tentativi di forza bruta su una credenziale dell'utente. Come mostrato in
hardware/libhardware/include/hardware/gatekeeper.h
, l'HAL
prevede il ritorno di un timeout in millisecondi. Il timeout informa il client
di non chiamare di nuovo GateKeeper fino al termine del timeout. GateKeeper
non deve gestire le richieste se è presente un timeout in attesa.
GateKeeper deve scrivere un contatore degli errori prima di verificare la password di un utente. Se la verifica della password va a buon fine, il contatore degli errori dovrebbe essere azzerato. In questo modo, si impediscono gli attacchi che impediscono il throttling disattivando l'MMC integrata (eMMC) dopo l'emissione di una chiamata verify
. La funzione enroll
verifica anche la password dell'utente (se fornita) e deve essere limitata nello stesso modo.
Se supportato dal dispositivo, è vivamente consigliato scrivere il contatore degli errori in uno spazio di archiviazione sicuro. Se il dispositivo non supporta la crittografia basata su file o se lo spazio di archiviazione sicuro è troppo lento, le implementazioni potrebbero utilizzare direttamente il blocco di memoria protetto da replay (RPMB).