Authentification

Android utilise le concept de clés cryptographiques sécurisées par authentification utilisateur qui nécessite les composants suivants :

  • Fournisseur de services et de stockage de clés cryptographiques. Stocke les clés cryptographiques et fournit des routines de chiffrement standard en plus de ces clés. Android prend en charge un Keystore et un Keymaster basés sur le matériel pour les services cryptographiques, y compris la cryptographie matérielle pour le stockage des clés qui peut inclure un environnement d'exécution de confiance (TEE) ou un élément sécurisé (SE), tel que Strongbox.
  • Authentificateurs d'utilisateurs. Attester de la présence de l'utilisateur et/ou de l'authentification réussie. Android prend en charge Gatekeeper pour l'authentification par code PIN/modèle/mot de passe et Fingerprint pour l'authentification par empreinte digitale. Les appareils livrés avec Android 9 et versions ultérieures 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.)

Les composants Gatekeeper, Fingerprint et Biometric fonctionnent avec Keystore et d'autres composants pour prendre en charge l'utilisation de jetons d'authentification matériels (AuthTokens).

Inscription

Au premier démarrage de l'appareil après une réinitialisation d'usine, tous les authentificateurs sont prêts à recevoir les inscriptions d'informations d'identification de l'utilisateur. Un utilisateur doit initialement enregistrer un code PIN/modèle/mot de passe auprès de Gatekeeper. Cette inscription initiale crée un identifiant sécurisé utilisateur (SID) de 64 bits généré aléatoirement qui sert d'identifiant pour l'utilisateur et de jeton de liaison pour le matériel cryptographique de l'utilisateur. Ce SID utilisateur est lié cryptographiquement au mot de passe de l'utilisateur ; les authentifications réussies auprès de Gatekeeper génèrent des AuthTokens qui contiennent le SID utilisateur pour ce mot de passe.

Un utilisateur qui souhaite modifier un identifiant doit présenter un identifiant existant. Si un identifiant existant est vérifié avec succès, le SID utilisateur associé à l'identifiant existant est transféré au nouveau identifiant, permettant à l'utilisateur de continuer à accéder aux clés après avoir modifié un identifiant. Si un utilisateur ne présente pas d'identifiant existant, le nouveau identifiant est inscrit avec un SID utilisateur entièrement aléatoire. L'utilisateur peut accéder à l'appareil, mais les clés créées sous l'ancien SID utilisateur sont définitivement perdues. C'est ce qu'on appelle une inscription non fiable .

Dans des circonstances normales, le framework Android n'autorise pas les inscriptions non fiables. La plupart des utilisateurs ne verront donc jamais cette fonctionnalité. Cependant, une réinitialisation forcée du mot de passe, soit par un administrateur de périphérique, soit par un attaquant, peut provoquer ce problème.

Authentification

Une fois qu'un utilisateur a configuré ses informations d'identification et reçu un SID utilisateur, il peut démarrer l'authentification, qui commence lorsqu'un utilisateur fournit un code PIN, un schéma, un mot de passe ou une empreinte digitale. Tous les composants TEE partagent une clé secrète qu'ils utilisent pour authentifier les messages de chacun.

Flux d'authentification
Figure 1. Flux d'authentification
  1. Un utilisateur fournit une méthode d'authentification et le service associé adresse une requête au démon associé.
    • Pour le code PIN, le modèle ou le mot de passe, LockSettingsService envoie une demande à gatekeeperd .
    • Les flux d'authentification basés sur la biométrie dépendent de la version d'Android. Sur les appareils exécutant Android 8.x et versions antérieures, FingerprintService envoie une demande à fingerprintd ). Sur les appareils exécutant Android 9 et versions ultérieures, 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 Biometric Manager appropriée, telle que FingerprintManager ou FaceManager . Quelle que soit la version, l'authentification biométrique se produit de manière asynchrone après l'envoi de la demande.
  2. Le démon envoie des données à son homologue, qui génère un AuthToken :
    • Pour l'authentification par code PIN/modèle/mot de passe, gatekeeperd envoie le code PIN, le modèle ou le hachage du mot de passe à Gatekeeper dans le TEE. Si l'authentification dans le TEE réussit, le Gatekeeper du TEE envoie un AuthToken contenant le SID de l'utilisateur correspondant (signé avec la clé AuthToken HMAC) à son homologue dans le système d'exploitation Android.
    • Pour l'authentification par empreinte digitale, fingerprintd écoute les événements d'empreinte digitale et envoie les données à Fingerprint dans le TEE. Si l'authentification dans le TEE réussit, l'empreinte digitale dans le TEE envoie un AuthToken (signé avec la clé AuthToken HMAC) à son homologue dans le système d'exploitation Android.
    • Pour d'autres authentifications biométriques, le démon biométrique approprié écoute l'événement biométrique et l'envoie au composant TEE biométrique approprié.
  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 informe également le service de magasin de clés lorsque l'appareil est reverrouillé et lorsque le mot de passe de l'appareil change.)
  4. Le service keystore transmet les AuthTokens à Keymaster et les vérifie à l’aide de la clé partagée avec Gatekeeper et du composant TEE biométrique pris en charge. Keymaster fait confiance à l'horodatage du jeton comme heure de la dernière authentification et fonde une décision de libération de clé (pour permettre à une application d'utiliser la clé) sur l'horodatage.

Format du jeton d'authentification

Pour garantir le partage de jetons et la compatibilité entre les langages et les composants, le format AuthToken est décrit dans hw_auth_token.h . Le format est un protocole de sérialisation simple avec des champs de taille fixe.

Champ Taper Requis Description
Version du jeton d'authentification 1 octet Oui Balise de groupe pour tous les champs ci-dessous.
Défi Entier non signé de 64 bits Non Un entier aléatoire pour empêcher les attaques par relecture. Généralement l'ID d'une opération de chiffrement demandée. Actuellement utilisé par les autorisations transactionnelles d’empreintes digitales. S'il est présent, l'AuthToken n'est valide que pour les opérations de chiffrement contenant le même défi.
ID utilisateur Entier non signé de 64 bits Oui Identifiant utilisateur non répétitif lié cryptographiquement à toutes les clés associées à l’authentification de l’appareil. Pour plus de détails, voir Gardien d'accès .
ID d'authentificateur (ASID) Entier non signé de 64 bits dans l'ordre du réseau Non Identifiant utilisé pour se lier à une stratégie d’authentification spécifique. Tous les authentifiants ont leur propre valeur d'ASID qu'ils peuvent modifier selon leurs propres besoins.
Type d'authentificateur Entier non signé de 32 bits dans l'ordre du réseau Oui
  • 0x00 est le gardien.
  • 0x01 est une empreinte digitale.
Horodatage Entier non signé de 64 bits dans l'ordre du réseau Oui Temps (en millisecondes) depuis le dernier démarrage du système.
Jeton d'authentification HMAC (SHA-256) Objet blob de 256 bits Oui Clé SHA-256 MAC de tous les champs à l'exception du champ HMAC.

Flux de démarrage de l'appareil

À chaque démarrage d'un appareil, la clé AuthToken HMAC doit être générée et partagée avec tous les composants TEE (Gatekeeper, Keymaster et trustlets biométriques pris en charge). Ainsi, pour une protection supplémentaire contre les attaques par relecture, la clé HMAC doit être générée aléatoirement à chaque redémarrage de l'appareil.

Le protocole de partage de cette clé HMAC avec tous les composants est une fonctionnalité d'implémentation dépendant de la plate-forme. La clé ne doit jamais être mise à disposition en dehors du TEE. Si un système d'exploitation TEE ne dispose pas d'un mécanisme de communication interprocessus interne (IPC) et doit transférer les données via le système d'exploitation non fiable, le transfert doit être effectué via un protocole d'échange de clés sécurisé.

Le système d'exploitation Trusty , qui fonctionne à 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 Keymaster et Gatekeeper ou le trustlet biométrique approprié. La clé HMAC est conservée uniquement dans Keymaster ; Fingerprint et Gatekeeper demandent la clé à Keymaster pour chaque utilisation et ne conservent pas et ne mettent pas en cache la valeur.

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