Gatekeeper

Le sous-système Gatekeeper effectue l'authentification par schéma/mot de passe de l'appareil dans un environnement d'exécution sécurisé (TEE). Gatekeeper enregistre et valide les mots de passe à l'aide d'une clé secrète intégrée au matériel. De plus, Gatekeeper limite les tentatives de validation consécutives ayant échoué et doit refuser de traiter les demandes de service en fonction d'un délai avant expiration donné et d'un nombre donné de tentatives consécutives ayant échoué.

Lorsque les utilisateurs valident leur mot de passe, Gatekeeper émet un jeton d'authentification signé avec une clé HMAC par démarrage, qui n'est disponible que pour les composants sécurisés. Ce jeton est envoyé au Keystore intégré au matériel. En d'autres termes, un jeton d'authentification Gatekeeper indique à Keystore que les clés liées à l'authentification (par exemple, les clés créées par les applications) peuvent être utilisées par les applications.

Architecture

Gatekeeper comprend trois composants principaux :

  • gatekeeperd (daemon Gatekeeper) : service Binder C++ dans Android qui contient une logique indépendante de la plate-forme implémentant l'interface AIDL IGateKeeperService, basée sur une implémentation sous-jacente de IGatekeeper spécifique au fournisseur.
  • Service de couche d'abstraction matérielle (HAL) Gatekeeper : implémentation spécifique au fournisseur de l'interface AIDL IGatekeeper. Ce service HAL s'exécute dans Android, mais la fonctionnalité principale de Gatekeeper doit s'exécuter dans un environnement sécurisé. Il communique donc généralement avec l'application de confiance Gatekeeper.
  • Application de confiance (TA) Gatekeeper : implémentation spécifique au fournisseur qui s'exécute dans le TEE et effectue la validation réelle du mot de passe ou du schéma.

LockSettingsService envoie une requête (via Binder) qui atteint le daemon gatekeeperd dans l'OS Android. Le daemon gatekeeperd envoie ensuite une requête au service HAL IGatekeeper, qui atteint à son tour son équivalent Gatekeeper TA dans le TEE :

Flux du contrôleur d'accès

Figure 1. Flux de données de haut niveau pour l'authentification par GateKeeper.

Le daemon gatekeeperd permet aux API du framework Android d'accéder à la HAL et participe au signalement des authentifications de l'appareil à Keystore. Le daemon gatekeeperd s'exécute dans son propre processus et est distinct du serveur système.

Implémentation de la HAL

Le daemon gatekeeperd utilise la HAL IGatekeeper pour interagir avec le TA Gatekeeper sous-jacent pour l'authentification par mot de passe. L'implémentation de l'AT Gatekeeper doit pouvoir signer (enregistrer) et valider les blobs. Toutes les implémentations doivent respecter le format standard du jeton d'authentification (HardwareAuthToken) généré à chaque validation de mot de passe réussie. Pour en savoir plus sur le contenu et la sémantique de HardwareAuthToken, consultez la définition de HardwareAuthToken.aidl.

Les implémentations de la HAL IGatekeeper par le fournisseur doivent implémenter les fonctions enroll et verify :

  • La méthode enroll prend un blob de mot de passe, le signe et renvoie la signature en tant que handle. Le blob renvoyé (à partir d'un appel à enroll) doit avoir la structure indiquée dans system/gatekeeper/include/gatekeeper/password_handle.h.
  • La fonction verify doit comparer la signature produite par le mot de passe fourni et s'assurer qu'elle correspond au handle du mot de passe enregistré.

La clé utilisée pour l'enregistrement et la validation ne doit jamais changer et doit pouvoir être dérivée à nouveau à chaque démarrage de l'appareil.

Trusty et autres implémentations

Le système d'exploitation Trusty est l'OS de confiance Open Source de Google pour les environnements TEE. Il contient une implémentation approuvée de Gatekeeper. Cependant, tout OS TEE peut implémenter Gatekeeper tant que le TEE a accès à une clé intégrée au matériel persistante et à une horloge monotone sécurisée qui fonctionne en mode veille.

Trusty utilise un système IPC interne pour communiquer un secret partagé directement entre KeyMint (anciennement Keymaster) et l'implémentation Trusty de Gatekeeper (Trusty Gatekeeper). Ce secret partagé est utilisé pour signer les jetons d'authentification envoyés au Keystore afin de fournir des attestations de validation du mot de passe. Trusty Gatekeeper demande la clé à KeyMint pour chaque utilisation, et ne conserve pas ni ne met en cache la valeur. Les implémentations sont libres de partager ce secret de n'importe quelle manière qui ne compromet pas la sécurité.

La clé HMAC utilisée pour enregistrer et valider les mots de passe est dérivée et conservée uniquement dans Gatekeeper.

Android fournit une implémentation Gatekeeper C++ générique qui ne nécessite que l'ajout de routines spécifiques à l'appareil pour être complète. L'implémentation Trusty est basée sur ce principe. Pour implémenter un Gatekeeper TEE avec du code spécifique à l'appareil pour votre TEE, reportez-vous aux fonctions et aux commentaires dans system/gatekeeper/include/gatekeeper/gatekeeper.h. Les principales responsabilités d'une implémentation conforme sont les suivantes :

  • Respect de la HAL IGatekeeper.
  • Les jetons d'authentification renvoyés doivent être formatés conformément à la spécification HardwareAuthToken (décrite dans HardwareAuthToken.aidl).
  • Le Gatekeeper TEE doit pouvoir partager une clé HMAC avec KeyMint, à l'aide de l'un des éléments suivants :
    • Accord de secret partagé : Gatekeeper peut participer à la négociation par démarrage de la clé HMAC en mettant en œuvre la HAL ISharedSecret. Pour cela, Gatekeeper et KeyMint doivent tous deux avoir accès à un secret prépartagé commun.
    • Accès direct : Gatekeeper peut récupérer la clé HMAC à partir de KeyMint à l'aide d'un mécanisme de communication inter-processus interne à l'environnement d'exécution de confiance (TEE), soit à la demande, soit lors de la première utilisation (mise en cache par la suite).

ID sécurisés (SID) des utilisateurs

Un SID utilisateur est la représentation TEE d'un utilisateur (sans lien fort avec un ID utilisateur Android). Le SID est généré avec un générateur de nombres pseudo-aléatoires (PRNG) cryptographique chaque fois qu'un utilisateur enregistre un nouveau mot de passe sans en fournir un précédent. Il s'agit d'un réenregistrement non fiable, qui ne se produit normalement que lorsqu'un utilisateur définit un mot de passe ou un schéma pour la première fois.

Un réenregistrement de confiance se produit lorsqu'un utilisateur fournit un mot de passe valide et précédent, par exemple lors d'un changement de mot de passe. Dans ce cas, le SID de l'utilisateur est migré vers le nouveau handle de mot de passe, en conservant les clés qui lui étaient associées.

Le SID de l'utilisateur est inclus dans l'authentification HMAC avec le mot de passe dans le handle de mot de passe lorsque le mot de passe est enregistré.

Les SID utilisateur sont inclus dans le HardwareAuthToken renvoyé par la fonction verify() et associés à toutes les clés Keystore liées à l'authentification (pour en savoir plus sur le format HardwareAuthToken et Keystore, consultez Authentification).

Notez qu'un appel non fiable à la fonction enroll() modifie le SID de l'utilisateur, ce qui rend les clés liées à ce mot de passe inutiles. Les pirates informatiques peuvent modifier le mot de passe de l'appareil s'ils contrôlent l'OS Android, mais ils détruisent les clés sensibles protégées par l'accès racine au cours du processus.

Limitation des requêtes

Gatekeeper doit pouvoir limiter de manière sécurisée les tentatives d'attaque par force brute sur les identifiants d'un utilisateur. Comme indiqué dans GatekeeperVerifyResponse.aidl, la HAL permet de renvoyer un délai avant expiration en millisecondes. Le délai avant expiration indique au client de ne pas appeler Gatekeeper à nouveau avant l'expiration du délai. Gatekeeper ne doit pas traiter les demandes de service si un délai d'expiration est en attente.

Gatekeeper doit écrire un compteur d'échecs avant de valider un mot de passe utilisateur. Si la validation du mot de passe réussit, le compteur d'échecs doit être effacé. Cela permet d'éviter les attaques qui empêchent la limitation en désactivant la carte MMC intégrée (eMMC) après l'émission d'un appel verify. La fonction enroll vérifie également le mot de passe de l'utilisateur (si fourni) et doit être limitée de la même manière.

Si l'appareil le permet, il est vivement recommandé d'écrire le compteur d'échecs dans un espace de stockage sécurisé. Si l'appareil n'est pas compatible avec le chiffrement basé sur les fichiers ou si le stockage sécurisé est trop lent, les implémentations peuvent utiliser directement le RPMB (Replay Protected Memory Block).