Authentication

Android ha il concetto di autenticatori utente che vengono utilizzati per sbloccare il dispositivo e per controllare l'accesso alle chiavi crittografiche. Sono coinvolti i seguenti componenti:

  • Fornitore di servizi e archiviazione delle chiavi di crittografia. Archivia le chiavi crittografiche e fornisce routine di crittografia standard in base a queste chiavi. Android supporta un Keystore supportato dall'hardware e KeyMint (in precedenza Keymaster) per i servizi crittografici, inclusa la crittografia supportata dall'hardware per l'archiviazione delle chiavi che potrebbe includere un Trusted Execution Environment (TEE) o un Secure Element (SE), come StrongBox.
  • Autenticatori utente. Attestare la presenza dell'utente e/o l'autenticazione riuscita. Android supporta Gatekeeper per l'autenticazione con PIN/sequenza/password e Fingerprint per l'autenticazione con l'impronta. I dispositivi forniti con Android 9 e versioni successive possono utilizzare BiometricPrompt come unico punto di integrazione per l'impronta e altre funzionalità biometriche. Questi componenti comunicano il proprio stato di autenticazione con il servizio keystore tramite un canale autenticato. Anche il sistema Android Keystore a livello di framework è supportato dal servizio keystore.

Ciascuno di questi componenti è specifico del fornitore, ma l'implementazione del fornitore è necessaria per soddisfare una specifica dell'interfaccia Hardware Abstraction Layer (HAL) e per superare i test della suite di test del fornitore (VTS) corrispondente.

Anche le implementazioni dei fornitori sono in genere divise in due parti, collegate da un meccanismo di comunicazione specifico del fornitore :

  • Un servizio HAL viene eseguito come processo di sistema Android, ricevendo richieste Binder dal sistema Android.
  • Un'applicazione attendibile (TA) viene eseguita nell'ambiente sicuro, eseguendo le operazioni sicure effettive.

Registrazione

Al primo avvio del dispositivo dopo un ripristino dei dati di fabbrica, tutti gli autenticatori sono pronti a ricevere le registrazioni delle credenziali da parte dell'utente. Un utente deve inizialmente registrare un PIN, una sequenza o una password con Gatekeeper (o Weaver, se disponibile). Questa registrazione iniziale crea un identificatore di sicurezza utente (SID) a 64 bit generato in modo casuale che funge da identificatore per l'utente e da token di binding per il materiale crittografico dell'utente. Questo SID utente è associato in modo crittografico alla password dell'utente; le autenticazioni riuscite a Gatekeeper generano AuthToken che contengono il SID utente per quella password.

Un utente che vuole modificare una credenziale esistente deve presentarla. Se una credenziale esistente viene verificata correttamente, l'SID utente associato alla credenziale esistente viene trasferito alla nuova credenziale, consentendo all'utente di continuare ad accedere alle chiavi dopo aver modificato una credenziale.

In alcune situazioni, un amministratore del dispositivo può eseguire una registrazione non attendibile per registrare una nuova credenziale senza presentare una credenziale esistente. In questo modo, l'utente può accedere al dispositivo, ma le chiavi create con il vecchio SID utente vengono perse definitivamente.

Autenticazione

Questa sezione descrive un flusso di autenticazione tipico, che prevede interazioni tra più componenti sia in Android sia nell'ambiente protetto. Tieni presente che tutti i componenti sicuri condividono una chiave HMAC segreta (per avvio) che utilizzano per autenticare i messaggi reciproci.

Dopo aver configurato una credenziale e aver ricevuto un SID utente, l'utente può avviare l'autenticazione, che inizia quando fornisce un PIN, una sequenza, una password, un'impronta o un altro dato biometrico avanzato. Flusso di autenticazione

Figura 1. Flusso di autenticazione

  1. Un utente fornisce un metodo di autenticazione e il servizio associato effettua una richiesta al servizio HAL.
    • Per PIN, sequenza o password, LockSettingsService invia una richiesta a gatekeeperd.
    • I flussi di autenticazione basati sulla biometria dipendono dalla versione di Android. Sui dispositivi con Android 8.x e versioni precedenti, FingerprintService invia una richiesta a fingerprintd. Sui dispositivi con Android 9 e versioni successive, BiometricPrompt invia una richiesta al daemon biometrico appropriato (ad esempio, fingerprintd per le impronte o faced per il volto) utilizzando la classe BiometricManager appropriata, ad esempio FingerprintManager o FaceManager. Indipendentemente dalla versione, l'autenticazione biometrica avviene in modo asincrono dopo l'invio della richiesta.
  2. Il servizio HAL invia i dati alla TA corrispondente, che genera un AuthToken:
    • Per l'autenticazione con PIN/sequenza/password, gatekeeperd invia l'hash del PIN, della sequenza o della password al TA Gatekeeper nel TEE, tramite il servizio HAL Gatekeeper. Se l'autenticazione nel TEE ha esito positivo, il TA Gatekeeper emette un AuthToken contenente l'SID utente corrispondente (firmato con la chiave HMAC condivisa).
    • Per l'autenticazione tramite impronta, fingerprintd ascolta gli eventi dell'impronta e invia i dati al TA dell'impronta nell'TEE tramite l'HAL dell'impronta. Se l'autenticazione nel TEE ha esito positivo, il TA dell'impronta emette un AuthToken (firmato con la chiave HMAC di AuthToken).
    • Per altre autenticazioni biometriche, il daemon biometrico appropriato ascolta l'evento biometrico e lo invia al servizio HAL biometrico e alla TA appropriati.
  3. Il daemon riceve un AuthToken firmato e lo passa al servizio keystore tramite un'estensione dell'interfaccia Binder del servizio keystore. (gatekeeperd invia una notifica anche al servizio keystore quando il dispositivo viene nuovamente bloccato e quando la password del dispositivo cambia.)
  4. Il servizio Keystore trasmette gli AuthToken a KeyMint e li verifica utilizzando la chiave condivisa con il componente TEE biometrico supportato e Gatekeeper. KeyMint considera il timestamp nel token come l'ultima ora di autenticazione e basa una decisione di rilascio della chiave (per consentire a un'app di utilizzare la chiave) sul timestamp.

Il flusso di autenticazione non richiede la comunicazione diretta tra i TA nell'ambiente sicuro: gli AuthToken vengono trasferiti dal TA autenticatore al servizio keystore2 in Android, che a sua volta li trasmette al TA KeyMint. Ciò consente inoltre al servizio keystore2 di negare rapidamente le richieste destinate a non riuscire, in quanto conosce gli AuthToken disponibili nel sistema, risparmiando un IPC potenzialmente costoso nel TEE.

Formato AuthToken

Il formato dell'AuthToken è specificato da AIDL in HardwareAuthToken.aidl.

Flusso di avvio del dispositivo

A ogni avvio di un dispositivo, la chiave HMAC AuthToken deve essere generata e condivisa con tutti i componenti TEE (Gatekeeper, KeyMint e trustlet biometriche supportate). Pertanto, per una maggiore protezione contro gli attacchi di replay, la chiave HMAC deve essere generata in modo casuale ogni volta che il dispositivo viene riavviato.

Esistono due modi comuni in cui i TA acquisiscono l'accesso a questa chiave HMAC condivisa:

  • Accordo sul segreto condiviso:il servizio keystore2 esegue un protocollo di accordo sulla chiave multidirezionale all'avvio del dispositivo, consentendo la derivazione sicura della chiave HMAC tra le TA partecipanti. Tuttavia, le TA partecipanti devono avere accesso a un segreto condiviso comune.
  • Accesso diretto:i TA che si trovano nello stesso ambiente sicuro possono utilizzare un meccanismo di comunicazione interprocesso interno (che dipende dalla piattaforma) per condividere la chiave HMAC.

In entrambi i casi, la chiave HMAC non deve mai essere resa disponibile al di fuori del TEE.

Il sistema operativo Trusty, che viene eseguito accanto ad Android, è un esempio di TEE, ma possono essere usati anche altri TEE. Trusty utilizza un sistema IPC interno per comunicare direttamente tra KeyMint e Gatekeeper o il trustlet biometrico appropriato. La chiave HMAC viene conservata esclusivamente in KeyMint; Fingerprint e Gatekeeper richiedono la chiave a KeyMint per ogni utilizzo e non ne conservano né memorizzano nella cache il valore.

Poiché alcuni TEE non dispongono di un'infrastruttura IPC, non si verifica alcuna comunicazione tra gli applet nel TEE. Inoltre, il servizio keystore può negare rapidamente le richieste destinate a non riuscire, in quanto conosce la tabella di autenticazione nel sistema, risparmiando un IPC potenzialmente costoso nel TEE.