Il sottosistema Gatekeeper esegue l'autenticazione della sequenza/password del dispositivo in un Trusted Execution Environment (TEE). Gatekeeper registra e verifica le password utilizzando una chiave segreta con crittografia hardware. Inoltre, Gatekeeper limita i tentativi di verifica non riusciti consecutivi e deve rifiutare di gestire le richieste di servizio in base a un determinato timeout e a un determinato numero di tentativi non riusciti consecutivi.
Quando gli utenti verificano le proprie password, Gatekeeper emette un token di autenticazione firmato con una chiave HMAC per avvio, disponibile solo per i componenti sicuri. Questo token viene inviato al Keystore con crittografia hardware. In altre parole, un token di autenticazione Gatekeeper comunica a Keystore che le chiavi associate all'autenticazione (ad esempio, le chiavi create dalle app) possono essere utilizzate dalle app.
Architettura
Gatekeeper è composto da tre componenti principali:
gatekeeperd(daemon Gatekeeper): un servizio Binder C++ in Android che contiene una logica indipendente dalla piattaforma che implementa l'interfaccia AIDLIGateKeeperService, basata su un'implementazione sottostante specifica del fornitore diIGatekeeper.- Servizio Hardware Abstraction Layer (HAL) di Gatekeeper: un'implementazione specifica del fornitore dell'interfaccia AIDL
IGatekeeper. Questo servizio HAL viene eseguito in Android, ma la funzionalità di base di Gatekeeper deve essere eseguita in un ambiente sicuro, quindi in genere comunica con il TA di Gatekeeper. - Gatekeeper Trusted Application (TA): un'implementazione specifica del fornitore che viene eseguita nel TEE ed esegue la verifica effettiva della password o della sequenza.
LockSettingsService effettua una richiesta (tramite Binder) che raggiunge il daemon gatekeeperd nel sistema operativo Android. Il daemon gatekeeperd effettua quindi una richiesta al servizio HAL IGatekeeper, che a sua volta raggiunge la sua controparte Gatekeeper TA nel TEE:
Figura 1. Flusso di dati di alto livello per l'autenticazione da parte di GateKeeper.
Il daemon gatekeeperd consente alle API del framework Android di accedere all'HAL e partecipa alla segnalazione delle autenticazioni del dispositivo a Keystore.
Il daemon gatekeeperd viene eseguito nel proprio processo ed è separato dal server di sistema.
Implementazione dell'HAL
Il daemon gatekeeperd utilizza l'HAL IGatekeeper per interagire con l'applicazione attendibile Gatekeeper sottostante per l'autenticazione della password. L'implementazione di Gatekeeper TA deve essere in grado di firmare (registrare) e verificare i blob. Tutte le implementazioni devono rispettare il formato standard del token di autenticazione (HardwareAuthToken) generato a ogni verifica della password riuscita. Per i dettagli sui contenuti e sulla semantica di HardwareAuthToken, consulta la definizione di HardwareAuthToken.aidl.
Le implementazioni del fornitore dell'HAL IGatekeeper devono implementare
le funzioni enroll e verify:
- Il metodo
enrollaccetta un blob di 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
verifydeve confrontare la firma prodotta dalla password fornita e assicurarsi che corrisponda all'handle della password registrata.
La chiave utilizzata per la registrazione e la verifica non deve mai cambiare e deve essere ricalcolabile a ogni avvio del dispositivo.
Trusty e altre implementazioni
Il sistema operativo Trusty è il sistema operativo open source di Google per gli ambienti TEE e contiene un'implementazione approvata di Gatekeeper. Tuttavia, qualsiasi sistema operativo TEE può implementare Gatekeeper, a condizione che il TEE abbia accesso a una chiave con integrazione hardware persistente e a un orologio sicuro e monotonico che funzioni in modalità di sospensione.
Trusty utilizza un sistema IPC interno per comunicare un secret condiviso direttamente tra KeyMint (in precedenza Keymaster) e l'implementazione di Gatekeeper di Trusty (Trusty Gatekeeper). Questo secret condiviso viene utilizzato per firmare i token di autenticazione inviati a Keystore per fornire attestazioni di verifica della password. Trusty Gatekeeper richiede la chiave da KeyMint per ogni utilizzo e non rende persistente 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 derivata 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 completa. L'implementazione di Trusty si basa su questo. Per implementare un Gatekeeper TEE con codice specifico per il dispositivo per il tuo TEE, consulta le funzioni e i commenti in system/gatekeeper/include/gatekeeper/gatekeeper.h. Le responsabilità principali di un'implementazione conforme includono:
- Conformità all'HAL
IGatekeeper. - I token di autenticazione restituiti devono essere formattati in base alla specifica
HardwareAuthToken(descritta inHardwareAuthToken.aidl). - Il Gatekeeper TEE deve essere in grado di condividere una chiave HMAC con KeyMint utilizzando uno dei seguenti metodi:
- Accordo sul secret condiviso: Gatekeeper può partecipare alla negoziazione per avvio della chiave HMAC implementando l'HAL
ISharedSecret. Ciò richiede che Gatekeeper e KeyMint abbiano entrambi accesso a un secret precondiviso comune. - Accesso diretto: Gatekeeper può recuperare la chiave HMAC da KeyMint utilizzando un meccanismo di comunicazione tra processi interno a TEE, on demand o al primo utilizzo (memorizzato nella cache in seguito).
- Accordo sul secret condiviso: Gatekeeper può partecipare alla negoziazione per avvio della chiave HMAC implementando l'HAL
ID sicuri (SID) degli utenti
Un SID utente è la rappresentazione TEE di un utente (senza un forte collegamento a un ID utente Android). Il SID viene generato con un generatore di numeri pseudocasuali (PRNG) crittografico ogni volta che un utente registra una nuova password senza fornire quella precedente. Questa operazione è nota come nuova registrazione non attendibile e normalmente si verifica solo quando un utente imposta per la prima volta una password o una sequenza.
Una nuova registrazione attendibile si verifica quando un utente fornisce una password precedente valida, ad esempio quando cambia la password. In questo caso, il SID utente viene migrato al nuovo handle della password, conservando le chiavi associate.
Il SID dell'utente è incluso nell'autenticazione HMAC insieme alla password nell'handle della password quando la password viene registrata.
I SID utente sono inclusi nel HardwareAuthToken restituito dalla funzione verify() e associati a tutte le chiavi Keystore associate all'autenticazione (per maggiori dettagli sul formato HardwareAuthToken e su Keystore, consulta Autenticazione).
Tieni presente che, poiché una chiamata non attendibile alla funzione enroll() modifica il SID dell'utente, la chiamata rende inutili le chiavi associate alla password. Gli utenti malintenzionati possono modificare la password del dispositivo se controllano il sistema operativo Android, ma nel processo distruggono le chiavi sensibili protette da root.
Limitazione delle richieste
Gatekeeper deve essere in grado di limitare in modo sicuro i tentativi di attacco brute force su una credenziale
utente. Come mostrato in GatekeeperVerifyResponse.aidl, l'HAL prevede la restituzione di un timeout in millisecondi. Il timeout indica al client di non chiamare nuovamente Gatekeeper fino alla scadenza del timeout.
Gatekeeper non deve gestire le richieste di servizio 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 deve essere azzerato. In questo modo si evitano attacchi che impediscono la limitazione disattivando l'MMC (eMMC) incorporato dopo l'esecuzione di una chiamata verify. Anche la funzione enroll verifica la password utente (se fornita) e deve essere limitata nello stesso modo.
Se supportato dal dispositivo, è vivamente consigliato scrivere il contatore degli errori nello 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 possono utilizzare direttamente il Replay Protected Memory Block (RPMB).