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 via un HMAC avec une clé secrète intégrée au matériel. De plus, Gatekeeper limite les tentatives de validation consécutives infructueuses et doit refuser de traiter les requêtes en fonction d'un délai avant expiration donné et d'un nombre donné de tentatives consécutives infructueuses.
Lorsque les utilisateurs valident leurs mots de passe, Gatekeeper utilise le secret partagé dérivé du TEE pour signer une attestation d'authentification à envoyer au Keystore basé sur le matériel. Autrement dit, une attestation Gatekeeper informe Keystore que les clés liées à l'authentification (par exemple, les clés créées par les applications) peuvent être publiées pour être utilisées par les applications.
Architecture
Gatekeeper comprend trois composants principaux:
gatekeeperd
(daemon Gatekeeper) Service de liaison C++ contenant une logique indépendante de la plate-forme et correspondant à l'interface JavaGateKeeperService
.- Couche d'abstraction matérielle (HAL) Gatekeeper. L'interface HAL dans
hardware/libhardware/include/hardware/gatekeeper.h
et le module d'implémentation - Gatekeeper (TEE) Équivalent TEE de
gatekeeperd
. Implémentation de Gatekeeper basée sur le TEE.
Gatekeeper nécessite l'implémentation du HAL Gatekeeper (en particulier les fonctions de hardware/libhardware/include/hardware/gatekeeper.h
) et du composant Gatekeeper spécifique au TEE (basé en partie sur le fichier d'en-tête system/gatekeeper/include/gatekeeper/gatekeeper.h
qui inclut des fonctions virtuelles pures pour créer/accéder aux clés et calculer les signatures).
LockSettingsService
envoie une requête (via Binder) qui atteint le daemon gatekeeperd
dans l'OS Android. Le daemon gatekeeperd
envoie ensuite une requête qui atteint son homologue (Gatekeeper) dans le TEE:

Le daemon gatekeeperd
permet aux API du framework Android d'accéder au HAL et participe au signalement des authentifications de l'appareil au keystore.
Le daemon gatekeeperd
s'exécute dans son propre processus et est distinct du serveur système.
Implémentation du HAL
Le daemon gatekeeperd
utilise le HAL pour interagir avec l'homologue TEE du daemon gatekeeperd
pour l'authentification par mot de passe. L'implémentation HAL doit pouvoir signer (enregistrer) et vérifier les blobs. Toutes les implémentations doivent respecter le format standard pour le jeton d'authentification (AuthToken) généré à chaque validation de mot de passe réussie. Pour en savoir plus sur le contenu et la sémantique de l'AuthToken, consultez la section Format AuthToken.
Les implémentations du fichier d'en-tête hardware/libhardware/include/hardware/gatekeeper.h
doivent implémenter les fonctions enroll
et verify
:
- La fonction
enroll
reçoit un blob de mot de passe, le signe et renvoie la signature en tant que poignée. Le blob renvoyé (à partir d'un appel àenroll
) doit avoir la structure illustrée danssystem/gatekeeper/include/gatekeeper/password_handle.h
. - La fonction
verify
doit comparer la signature générée par le mot de passe fourni et s'assurer qu'elle correspond au gestionnaire 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 à nouveau à chaque démarrage de l'appareil.
Trusty et autres implémentations
Le système d'exploitation Trusty est l'OS Open Source de confiance de Google pour les environnements TEE et contient une implémentation approuvée de GateKeeper. Toutefois, vous pouvez utiliser n'importe quel OS TEE pour implémenter Gatekeeper tant que le TEE a accès à une clé matérielle 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 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 du mot de passe. Trusty Gatekeeper demande la clé à Keymaster pour chaque utilisation et ne conserve ni ne met en cache la valeur. Les implémentations sont libres de partager ce secret de quelque manière que ce soit sans compromettre 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 générique de GateKeeper en C++ qui ne nécessite que l'ajout de routines spécifiques à l'appareil. Pour implémenter un TEE Gatekeeper avec du code spécifique à l'appareil pour votre TEE, consultez les fonctions et les commentaires dans system/gatekeeper/include/gatekeeper/gatekeeper.h
.
Pour le TEE GateKeeper, les principales responsabilités d'une implémentation conforme sont les suivantes:
- Respect de la HAL Gatekeeper.
- Les AuthTokens renvoyés doivent être mis en forme conformément aux spécifications AuthToken (décrites dans la section Authentification).
- Le TEE Gatekeeper doit pouvoir partager une clé HMAC avec Keymaster, soit en demandant la clé via un IPC TEE à la demande, soit en conservant un cache valide de la valeur en permanence.
ID utilisateur sécurisés (SID)
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é à l'aide d'un générateur de nombres pseudo-aléatoires (PRNG) chaque fois qu'un utilisateur enregistre un nouveau mot de passe sans en fournir un précédent. Il s'agit d'une réinscription non approuvée, qui n'est pas autorisée par le framework Android dans des circonstances normales. Une réinscription de confiance se produit lorsqu'un utilisateur fournit un ancien mot de passe valide. Dans ce cas, le SID utilisateur est migré vers le nouveau gestionnaire de mots de passe, en conservant les clés qui y étaient associées.
Le SID utilisateur est haché HMAC avec le mot de passe dans le gestionnaire de mots de passe lors de l'enregistrement du mot de passe.
Les SID utilisateur sont écrits dans l'AuthToken renvoyé par la fonction verify
et associés à toutes les clés Keystore liées à l'authentification (pour en savoir plus sur le format AuthToken et Keystore, consultez la section Authentification). Étant donné qu'un appel non approuvé à la fonction enroll
modifie le SID utilisateur, l'appel rend les clés associées à ce mot de passe inutilisables. 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 root au cours du processus.
Limiter les requêtes
GateKeeper doit pouvoir limiter de manière sécurisée les tentatives de force brute sur des identifiants utilisateur. Comme indiqué dans hardware/libhardware/include/hardware/gatekeeper.h
, le HAL permet de renvoyer un délai avant expiration en millisecondes. Le délai avant expiration informe le client de ne pas appeler GateKeeper à nouveau tant que le délai avant expiration n'est pas écoulé. GateKeeper ne doit pas traiter les requêtes si un délai avant expiration est 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 le débit régulé en désactivant la MMC intégrée (eMMC) après avoir émis un appel verify
. La fonction enroll
vérifie également le mot de passe de l'utilisateur (le cas échéant) 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'erreurs dans un 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).