Authentication

Android utilise le concept d'authentificateurs utilisateur qui servent à déverrouiller l'appareil et à contrôler l'accès aux clés cryptographiques. Cela implique les composants suivants :

  • Stockage de clés cryptographiques et fournisseur de services : stocke les clés cryptographiques et fournit des routines de chiffrement standards en plus de ces clés. Android est compatible avec Keystore et KeyMint (anciennement Keymaster) avec sauvegarde matérielle pour les services cryptographiques, y compris la cryptographie avec sauvegarde matérielle pour le stockage de clés qui peut inclure un environnement d'exécution sécurisé (TEE) ou un composant sécurisé (SE), tel que StrongBox.
  • Authentificateurs utilisateur : attestent de la présence de l'utilisateur et/ou de la réussite de l'authentification. Android est compatible avec Gatekeeper pour l'authentification par code/schéma/mot de passe et avec Fingerprint pour l'authentification par empreinte digitale. Les appareils livrés avec Android 9 ou une version ultérieure peuvent utiliser BiometricPrompt comme point d'intégration unique pour les empreintes digitales et les données biométriques supplémentaires. Ces composants communiquent leur état d'authentification avec le service keystore via un canal authentifié. Le système Android Keystore au niveau du framework est également soutenu par le service keystore.

Chacun de ces composants est spécifique au fournisseur, mais l'implémentation du fournisseur doit respecter une spécification d'interface couche d'abstraction matérielle (HAL) et réussir les suites de tests VTS (Vendor Test Suite) correspondantes.

Les implémentations des fournisseurs sont généralement divisées en deux parties, connectées par un mécanisme de communication spécifique au fournisseur :

  • Un service HAL s'exécute en tant que processus système Android, recevant des requêtes Binder du système Android.
  • Une application de confiance (TA) s'exécute dans l'environnement sécurisé, en effectuant les opérations sécurisées réelles.

Inscription

Au premier démarrage de l'appareil après un rétablissement de la configuration d'usine, tous les authentificateurs sont prêts à recevoir les enregistrements d'identifiants de l'utilisateur. Un utilisateur doit d'abord enregistrer un code, un schéma ou un mot de passe avec Gatekeeper (ou Weaver, le cas échéant). Cette inscription initiale crée un identifiant sécurisé (SID) utilisateur de 64 bits généré de manière aléatoire qui sert d'identifiant pour l'utilisateur et de jeton de liaison pour son matériel cryptographique. Ce SID utilisateur est lié de manière cryptographique au mot de passe de l'utilisateur. Les authentifications réussies auprès de Gatekeeper génèrent des AuthTokens contenant le SID utilisateur pour ce mot de passe.

Un utilisateur qui souhaite modifier un identifiant existant doit le présenter. Si un identifiant existant est validé, le SID utilisateur associé à l'identifiant existant est transféré au nouvel identifiant, ce qui permet à l'utilisateur de continuer à accéder aux clés après avoir modifié un identifiant.

Dans certaines situations, un administrateur d'appareil peut effectuer une inscription non fiable pour enregistrer un nouvel identifiant sans présenter d'identifiant existant. Cela permet à l'utilisateur d'accéder à l'appareil, mais les clés créées sous l'ancien SID utilisateur sont définitivement perdues.

Authentification

Cette section décrit un flux d'authentification standard, qui implique des interactions entre plusieurs composants dans Android et dans l'environnement sécurisé. Notez que tous les composants sécurisés partagent une clé HMAC secrète (par démarrage) qu'ils utilisent pour s'authentifier mutuellement.

Une fois qu'un utilisateur a configuré un identifiant et qu'un SID utilisateur lui a été attribué, il peut lancer l'authentification, qui commence lorsqu'il fournit un code, un schéma, un mot de passe, une empreinte digitale ou une autre donnée biométrique forte. Flux d'authentification

Figure 1. Flux d'authentification

  1. Un utilisateur fournit une méthode d'authentification et le service associé envoie une requête au service HAL.
    • Pour un code, un schéma ou un mot de passe, LockSettingsService envoie une requête à gatekeeperd.
    • Les flux d'authentification basés sur les données biométriques dépendent de la version d'Android. Sur les appareils exécutant Android 8.x ou une version antérieure, FingerprintService envoie une requête à fingerprintd). Sur les appareils exécutant Android 9 ou une version ultérieure, BiometricPrompt envoie une requête au démon biométrique approprié (par exemple, fingerprintd pour les empreintes digitales ou faced pour le visage) à l'aide de la classe BiometricManager appropriée, telle que FingerprintManager ou FaceManager. Quelle que soit la version, l'authentification biométrique a lieu de manière asynchrone après l'envoi de la requête.
  2. Le service HAL envoie des données à son homologue TA, qui génère un AuthToken:
    • Pour l'authentification par code/schéma/mot de passe, gatekeeperd envoie le code, le schéma ou le hachage du mot de passe au Gatekeeper TA dans le TEE, via le service Gatekeeper HAL. Si l'authentification dans le TEE réussit, le Gatekeeper TA émet un AuthToken contenant le SID utilisateur correspondant (signé avec la clé HMAC partagée).
    • Pour l'authentification par empreinte digitale, fingerprintd écoute les événements d'empreinte digitale et envoie les données au Fingerprint TA dans le TEE, via le Fingerprint HAL. Si l'authentification dans le TEE réussit, le Fingerprint TA émet un AuthToken (signé avec la clé HMAC AuthToken).
    • Pour les autres authentifications biométriques, le démon biométrique approprié écoute l'événement biométrique et l'envoie au service et au TA HAL biométriques appropriés.
  3. Le démon reçoit un AuthToken signé et le transmet au service keystore via une extension de l'interface Binder du service keystore. (gatekeeperd avertit également le service keystore lorsque l'appareil est verrouillé et lorsque le mot de passe de l'appareil est modifié.)
  4. Le service Keystore transmet les AuthTokens à KeyMint et les valide à l'aide de la clé partagée avec le composant Gatekeeper et le composant biométrique TEE compatible. KeyMint considère l'horodatage du jeton comme la dernière heure d'authentification et base une décision de publication de clé (pour autoriser une application à utiliser la clé) sur l'horodatage.

Le flux d'authentification ne nécessite pas de communication directe entre les TA dans l'environnement sécurisé : les AuthTokens circulent du TA de l'authentificateur vers le service keystore2 dans Android, qui les transmet à son tour au TA KeyMint. Cela permet également au service keystore2 de refuser rapidement les requêtes qui sont vouées à l'échec, car il connaît les AuthTokens disponibles dans le système, ce qui permet d'économiser un IPC potentiellement coûteux dans le TEE.

Format AuthToken

Le format de l'AuthToken est donné par la spécification AIDL dans HardwareAuthToken.aidl.

Flux de démarrage de l'appareil

À chaque démarrage d'un appareil, la clé HMAC AuthToken doit être générée et partagée avec tous les composants TEE (Gatekeeper, KeyMint et les trustlets biométriques compatibles). Ainsi, pour une protection accrue contre les attaques par relecture, la clé HMAC doit être générée de manière aléatoire chaque fois que l'appareil redémarre.

Il existe deux façons courantes pour les TA d'accéder à cette clé HMAC partagée :

  • Accord de secret partagé : le service keystore2 exécute un protocole d'accord de clé multidirectionnel au démarrage de l'appareil, ce qui permet une dérivation sécurisée de la clé HMAC entre les TA participants. Toutefois, les TA participants doivent avoir accès à un secret commun prépartagé secret.
  • Accès direct : les TA qui résident dans le même environnement sécurisé peuvent utiliser un mécanisme de communication inter-processus interne (qui dépend de la plate-forme) pour partager la clé HMAC.

Dans les deux cas, la clé HMAC ne doit jamais être mise à disposition en dehors du TEE.

Le système d'exploitation Trusty, qui s'exécute à côté d'Android, est un exemple de TEE, mais d'autres TEE peuvent être utilisés à la place. Trusty utilise un système IPC interne pour communiquer directement entre KeyMint et Gatekeeper ou le trustlet biométrique approprié. La clé HMAC est conservée uniquement dans KeyMint. Fingerprint et Gatekeeper demandent la clé à KeyMint pour chaque utilisation et ne conservent ni ne mettent en cache la valeur.

Comme certains TEE ne disposent pas d'infrastructure IPC, aucune communication n'a lieu entre les applets du TEE. Cela permet également au service keystore de refuser rapidement les requêtes qui sont vouées à l'échec, car il connaît la table d'authentification dans le système, ce qui permet d'économiser un IPC potentiellement coûteux dans le TEE.