Le sous-système Gatekeeper effectue l'authentification par modèle de périphérique/mot de passe dans un environnement d'exécution sécurisé (TEE). Gatekeeper inscrit et vérifie les mots de passe via un HMAC avec une clé secrète sauvegardée sur le matériel. De plus, Gatekeeper limite les tentatives de vérification infructueuses consécutives et doit refuser de traiter les demandes en fonction d'un délai d'attente donné et d'un nombre donné de tentatives infructueuses consécutives.
Lorsque les utilisateurs vérifient leurs mots de passe, Gatekeeper utilise le secret partagé dérivé de 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 que les applications ont créées) peuvent être libérées pour être utilisées par les applications.
Architecture
Gatekeeper implique trois composants principaux :
-
gatekeeperd
(démon Gatekeeper). Un service de classeur C++ contenant une logique indépendante de la plate-forme et correspondant à l'interface JavaGateKeeperService
. - Couche d'abstraction matérielle Gatekeeper (HAL) . L'interface HAL dans
hardware/libhardware/include/hardware/gatekeeper.h
et le module d'implémentation. - Gardien (TEE) . L'homologue TEE de
gatekeeperd
. Une implémentation basée sur TEE de Gatekeeper.
Gatekeeper nécessite l'implémentation de Gatekeeper HAL (en particulier les fonctions dans hardware/libhardware/include/hardware/gatekeeper.h
) et du composant Gatekeeper spécifique à TEE (basé en partie sur le fichier d'en-tête system/gatekeeper/include/gatekeeper/gatekeeper.h
incluant des fonctions virtuelles pures de création/d'accès aux clés et de calcul des signatures).
Le LockSettingsService
fait une demande (via Binder) qui atteint le démon gatekeeperd
dans le système d'exploitation Android. Le démon gatekeeperd
fait alors une requête qui parvient à son homologue (Gatekeeper) dans le TEE :

Le démon gatekeeperd
donne aux API du framework Android l'accès à HAL et participe à la notification des authentifications d'appareils à Keystore. Le démon gatekeeperd
s'exécute dans son propre processus et est séparé du serveur système.
Implémentation HAL
Le démon gatekeeperd
utilise HAL pour interagir avec l'homologue TEE du démon gatekeeperd
pour l'authentification par mot de passe. L'implémentation HAL doit pouvoir signer (inscrire) et vérifier les blobs. Toutes les implémentations doivent respecter le format standard du jeton d'authentification (AuthToken) généré à chaque vérification de mot de passe réussie. Pour plus de détails sur le contenu et la sémantique de AuthToken, consultez format AuthToken .
Les implémentations du fichier d'en-tête hardware/libhardware/include/hardware/gatekeeper.h
doivent implémenter les fonctions d' enroll
et de verify
:
- La fonction d'
enroll
prend un blob de mot de passe, le signe et renvoie la signature sous forme de descripteur. Le blob renvoyé (à partir d'un appel àenroll
) doit avoir la structure indiquée danssystem/gatekeeper/include/gatekeeper/password_handle.h
. - La fonction de
verify
doit comparer la signature produite par le mot de passe fourni et s'assurer qu'elle correspond au descripteur de mot de passe inscrit.
La clé utilisée pour l'inscription et la vérification 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 et contient une implémentation approuvée de GateKeeper. Cependant, vous pouvez utiliser n'importe quel système d'exploitation 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 suspend .
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 à Keystore afin de fournir des attestations de vérification de mot de passe. Trusty Gatekeeper demande la clé à Keymaster pour chaque utilisation et ne conserve pas ou ne cache pas la valeur. Les implémentations sont libres de partager ce secret d'une manière qui ne compromet pas la sécurité.
La clé HMAC utilisée pour enregistrer et vérifier 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. Pour implémenter un TEE Gatekeeper avec un code spécifique à l'appareil pour votre TEE, reportez-vous aux fonctions et aux commentaires dans system/gatekeeper/include/gatekeeper/gatekeeper.h
. Pour le TEE GateKeeper, les principales responsabilités d'une implémentation conforme incluent :
- Adhésion au Gatekeeper HAL.
- Les AuthTokens renvoyés doivent être formatés conformément à la spécification AuthToken (décrite dans Authentication ).
- Le TEE Gatekeeper doit être en mesure de partager une clé HMAC avec Keymaster, soit en demandant la clé via un TEE IPC à la demande, soit en conservant un cache valide de la valeur à tout moment.
Identifiants sécurisés de l'utilisateur (SID)
Un SID utilisateur est la représentation TEE d'un utilisateur (sans connexion forte à un ID utilisateur Android). Le SID est généré avec un générateur de nombres pseudo-aléatoires cryptographiques (PRNG) chaque fois qu'un utilisateur inscrit un nouveau mot de passe sans en fournir un précédent. Ceci est connu comme une réinscription non approuvée et n'est pas autorisé par le cadre 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 descripteur de mot de passe, en conservant les clés qui lui étaient liées.
Le SID utilisateur est HMAC avec le mot de passe dans le descripteur de mot de passe lorsque le mot de passe est inscrit.
Les SID utilisateur sont écrits dans le AuthToken renvoyé par la fonction de verify
et associés à toutes les clés de magasin de clés liées à l'authentification (pour plus de détails sur le format AuthToken et le magasin de clés, voir Authentification ). Comme un appel non fiable à la fonction d' enroll
modifiera le SID de l'utilisateur, l'appel rendra les clés liées à ce mot de passe inutiles. Les attaquants peuvent modifier le mot de passe de l'appareil s'ils contrôlent le système d'exploitation Android, mais ils détruiront les clés sensibles protégées par la racine au cours du processus.
Limitation des demandes
GateKeeper doit être en mesure de limiter en toute sécurité les tentatives de force brute sur un identifiant utilisateur. Comme indiqué dans hardware/libhardware/include/hardware/gatekeeper.h
, HAL permet de renvoyer un délai d'attente en millisecondes. Le délai d'attente informe le client de ne plus appeler GateKeeper tant que le délai d'attente ne s'est pas écoulé ; GateKeeper ne doit pas traiter les demandes s'il y a un délai d'attente en attente.
GateKeeper doit écrire un compteur d'échecs avant de vérifier un mot de passe utilisateur. Si la vérification 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 MMC intégrée (eMMC) après l'émission d'un appel de verify
. La fonction d' enroll
vérifie également le mot de passe de l'utilisateur (si fourni) et doit être limitée de la même manière.
S'il est pris en charge par l'appareil, il est fortement recommandé d'écrire le compteur d'échecs dans un stockage sécurisé. Si l'appareil ne prend pas en charge le chiffrement basé sur les fichiers ou si le stockage sécurisé est trop lent, les implémentations peuvent utiliser directement le bloc de mémoire protégée par relecture (RPMB).