Fonctions KeyMint

Cette page fournit des informations et des consignes supplémentaires pour aider les développeurs de la couche d'abstraction matérielle (HAL) KeyMint. La documentation principale du HAL est la spécification de l'interface AIDL.

Utilisation abusive de l'API

Les appelants peuvent créer des clés KeyMint avec des autorisations valides en tant que paramètres d'API, mais qui rendent les clés résultantes non sécurisées ou inutilisables. Les implémentations KeyMint ne sont pas tenues d'échouer dans de tels cas ni d'émettre un diagnostic. Les implémentations ne doivent pas diagnostiquer l'utilisation de clés trop petites, la spécification de paramètres d'entrée non pertinents, la réutilisation d'IV ou de nonces, la génération de clés sans objectif (donc inutiles), etc.

Il incombe aux applications, au framework et à Android Keystore de s'assurer que les appels aux modules KeyMint sont judicieux et utiles.

Point d'entrée addRngEntropy

Le point d'entrée addRngEntropy ajoute l'entropie fournie par l'appelant au pool utilisé par l'implémentation KeyMint pour générer des nombres aléatoires, pour les clés et les vecteurs d'initialisation.

Les implémentations KeyMint doivent mélanger de manière sécurisée l'entropie fournie dans leur pool, qui doit également contenir de l'entropie générée en interne à partir d'un générateur de nombres aléatoires matériels. Le mélange doit être géré de sorte qu'un pirate informatique qui contrôle entièrement les bits fournis par addRngEntropy ou les bits générés par le matériel (mais pas les deux) ne dispose pas d'un avantage significatif pour prédire les bits générés à partir du pool d'entropie.

Caractéristiques principales

Chacun des mécanismes (generateKey, importKey et importWrappedKey) qui créent des clés KeyMint renvoie les caractéristiques de la clé nouvellement créée, divisées de manière appropriée en niveaux de sécurité qui appliquent chaque caractéristique. Les caractéristiques renvoyées incluent tous les paramètres spécifiés pour la création de clés, à l'exception de Tag::APPLICATION_ID et Tag::APPLICATION_DATA. Si ces balises sont incluses dans les paramètres clés, elles sont supprimées des caractéristiques renvoyées. Il n'est donc pas possible de trouver leurs valeurs en examinant le keyblob renvoyé. Toutefois, elles sont liées de manière cryptographique au keyblob. Par conséquent, si les valeurs correctes ne sont pas fournies lorsque la clé est utilisée, l'utilisation échoue. De même, Tag::ROOT_OF_TRUST est lié de manière cryptographique à la clé, mais il ne peut pas être spécifié lors de la création ou de l'importation de la clé et n'est jamais renvoyé.

En plus des balises fournies, l'implémentation KeyMint ajoute également Tag::ORIGIN, qui indique la manière dont la clé a été créée (KeyOrigin::GENERATED, KeyOrigin::IMPORTED ou KeyOrigin::SECURELY_IMPORTED).

Résistance au rollback

La résistance au rollback est indiquée par Tag::ROLLBACK_RESISTANCE. Elle signifie qu'une fois qu'une clé est supprimée avec deleteKey ou deleteAllKeys, le matériel sécurisé garantit qu'elle ne pourra plus jamais être utilisée.

Les implémentations KeyMint renvoient le matériel de clé généré ou importé à l'appelant sous la forme d'un keyblob, qui est une forme chiffrée et authentifiée. Lorsque Keystore supprime le keyblob, la clé disparaît, mais un pirate informatique qui a réussi à récupérer le matériel de clé auparavant pourrait potentiellement le restaurer sur l'appareil.

Une clé est résistante au rollback si le matériel sécurisé garantit que les clés supprimées ne peuvent pas être restaurées ultérieurement. Pour ce faire, il faut généralement stocker des métadonnées de clé supplémentaires dans un emplacement fiable qui ne peut pas être manipulé par un pirate informatique. Sur les appareils mobiles, le mécanisme utilisé à cet effet est généralement constitué de blocs de mémoire protégés contre la relecture (RPMB, Replay Protected Memory Blocks). Étant donné que le nombre de clés pouvant être créées est pratiquement illimité et que le stockage sécurisé utilisé pour la protection contre la restauration peut être limité en taille, l'implémentation peut échouer les requêtes de création de clés résistantes à la restauration lorsque le stockage est plein.

begin

Le point d'entrée begin() lance une opération de chiffrement à l'aide de la clé spécifiée, dans le but spécifié et avec les paramètres spécifiés (le cas échéant). Il renvoie un nouvel objet Binder IKeyMintOperation qui est utilisé pour terminer l'opération. De plus, une valeur de challenge est renvoyée et utilisée dans le jeton d'authentification lors des opérations authentifiées.

Une implémentation KeyMint accepte au moins 16 opérations simultanées. Le keystore utilise jusqu'à 15 clés, ce qui en laisse une pour vold afin de chiffrer les mots de passe. Lorsque Keystore a 15 opérations en cours (begin() a été appelé, mais finish ou abort n'ont pas été appelés) et qu'il reçoit une demande pour en commencer une 16e, il appelle abort() sur l'opération la moins récemment utilisée pour réduire le nombre d'opérations actives à 14 avant d'appeler begin() pour démarrer la nouvelle opération demandée.

Si Tag::APPLICATION_ID ou Tag::APPLICATION_DATA ont été spécifiés lors de la génération ou de l'importation de la clé, les appels à begin() doivent inclure ces tags avec les valeurs spécifiées à l'origine dans l'argument params de cette méthode.

Gestion des exceptions

Si une méthode sur un IKeyMintOperation renvoie un code d'erreur autre que ErrorCode::OK, l'opération est abandonnée et l'objet Binder de l'opération est invalidé. Toute utilisation ultérieure de l'objet renvoie ErrorCode::INVALID_OPERATION_HANDLE.

Application des autorisations

L'application de l'autorisation des clés est principalement effectuée dans begin(). La seule exception concerne le cas où la clé comporte une ou plusieurs valeurs Tag::USER_SECURE_ID, mais pas de valeur Tag::AUTH_TIMEOUT.

Dans ce cas, la clé nécessite une autorisation par opération, et les méthodes update() ou finish() reçoivent un jeton d'authentification dans l'argument authToken. Pour s'assurer que le jeton est valide, l'implémentation KeyMint :

  • Vérifie la signature HMAC sur le jeton d'authentification.
  • Vérifie que le jeton contient un ID utilisateur sécurisé correspondant à celui associé à la clé.
  • Vérifie que le type d'authentification du jeton correspond à la valeur Tag::USER_AUTH_TYPE de la clé.
  • Vérifie que le jeton contient la valeur du challenge pour l'opération en cours dans le champ "challenge".

Si ces conditions ne sont pas remplies, KeyMint renvoie ErrorCode::KEY_USER_NOT_AUTHENTICATED.

L'appelant fournit le jeton d'authentification à chaque appel à update() et finish(). L'implémentation ne peut valider le jeton qu'une seule fois.