Le sous-système Gatekeeper effectue l'authentification du 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 infructueuses consécutives et doit refuser de traiter les requêtes en fonction d'un délai d'inactivité et d'un nombre donné de tentatives infructueuses consécutives.
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. Autrement dit, un jeton d'authentification Gatekeeper informe le 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 comporte 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 AIDLIGateKeeperService, basée sur une implémentation sous-jacente spécifique au fournisseur deIGatekeeper.- 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 le TA 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 à son tour atteint son homologue TA Gatekeeper dans le TEE :
Figure 1. Flux de données de haut niveau pour l'authentification par GateKeeper.
Le gatekeeperd daemon donne aux API du framework Android l'accès
à la HAL et participe à la création de rapports sur les authentifications
d'appareils dans le 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 du TA Gatekeeper doit pouvoir signer (enregistrer) et valider des blobs. Toutes les implémentations doivent respecter le format standard du jeton d'authentification (HardwareAuthToken) généré lors de chaque validation de mot de passe réussie. Pour en savoir plus sur le contenu et la sémantique de HardwareAuthToken, consultez la
HardwareAuthToken.aidl
définition.
Les implémentations de la HAL IGatekeeper par les fournisseurs doivent implémenter les fonctions enroll et verify :
- La méthode
enrollprend 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 danssystem/gatekeeper/include/gatekeeper/password_handle.h. - La fonction
verifydoit comparer la signature produite par le mot de passe fourni et s'assurer qu'elle correspond au handle de 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 à chaque démarrage de l'appareil.
Trusty et autres implémentations
Le système d'exploitation Trusty est le système d'exploitation de confiance Open Source de Google pour les environnements TEE. Il contient une implémentation approuvée de Gatekeeper. Toutefois, n'importe quel système d'exploitation TEE peut implémenter Gatekeeper tant que le TEE a accès à une clé intégrée au matériel persistante et à une horloge sécurisée et monotone 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 (le Trusty Gatekeeper). Ce secret partagé est utilisé pour signer les AuthTokens envoyés au Keystore afin de fournir des attestations de validation de mot de passe. Trusty Gatekeeper demande la clé à KeyMint pour chaque utilisation et ne conserve ni ne met en cache la valeur. Les implémentations sont libres de partager ce secret de toute 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 C++ générique de Gatekeeper 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 cette implémentation. 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 mis en forme conformément à la
HardwareAuthTokenspécification (décrite dans Authentification). - Le Gatekeeper TEE doit pouvoir partager une clé HMAC avec KeyMint, soit en demandant la clé via un IPC TEE à la demande, soit en conservant un cache valide de la valeur à tout moment.
ID sécurisés (SID) utilisateur
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 approuvé 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 approuvé se produit lorsqu'un utilisateur fournit un mot de passe précédent valide, par exemple lorsqu'il change de mot de passe. Dans ce cas, le SID utilisateur est migré vers le nouveau handle de mot de passe, ce qui permet de conserver les clés qui y étaient liées.
Le SID 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 verify()
fonction et associés à toutes les clés Keystore liées à l'authentification (pour en savoir plus
sur le format HardwareAuthToken et le Keystore, consultez
Authentification).
Notez que, comme un appel non approuvé à la fonction enroll() modifie le SID utilisateur, l'appel rend les clés liées à ce mot de passe inutiles. Les pirates 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 la 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 d'inactivité en millisecondes. Le délai d'inactivité informe le client de ne pas rappeler Gatekeeper avant la fin du délai d'inactivité.
Gatekeeper ne doit pas traiter les requêtes s'il existe un délai d'inactivité en attente.
Gatekeeper doit écrire un compteur d'échecs avant de valider le mot de passe d'un utilisateur. Si la validation du mot de passe réussit, le compteur d'échecs doit être effacé. Cela empêche 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 valide également le mot de passe de l'utilisateur (s'il est fourni) et doit être limitée de la même manière.
Si l'appareil le prend en charge, il est fortement recommandé d'écrire le compteur d'échecs dans un espace de stockage sécurisé. Si l'appareil ne prend pas en charge le chiffrement basé sur des fichiers ou si l'espace de stockage sécurisé est trop lent, les implémentations peuvent utiliser directement le bloc de mémoire protégé contre la relecture (RPMB).