Fonctions KeyMint

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

Usage abusif 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 générées non sécurisées ou inutilisables. Dans de tels cas, les implémentations KeyMint ne sont pas tenues d'échouer ni d'émettre de diagnostic. 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 but (donc inutiles), etc. ne doivent pas être diagnostiquées par les implémentations.

Il incombe aux applications, au framework et à Android Keystore de s'assurer que les appels aux modules KeyMint sont pertinents 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 IV.

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ériel. Le mélange doit être géré de sorte qu'un pirate informatique qui a le contrôle complet des bits fournis par addRngEntropy ou des bits générés par le matériel (mais pas les deux) n'ait pas un avantage significatif pour prédire les bits générés à partir du pool d'entropie.

Principales caractéristiques

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 en fonction des 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 de clé, elles sont supprimées des caractéristiques renvoyées afin qu'il ne soit 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 de 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 sera plus jamais utilisable.

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

Une clé est protégée contre le 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 est généralement nécessaire de stocker des métadonnées de clé supplémentaires dans un emplacement sécurisé qui ne peut pas être manipulé par un pirate informatique. Sur les appareils mobiles, le mécanisme utilisé est généralement les blocs de mémoire protégés contre la relecture (RPMB). Étant donné que le nombre de clés pouvant être créées est essentiellement illimité et que la taille de l'espace de stockage sécurisé utilisé pour la résistance au rollback peut être limitée, l'implémentation peut échouer lorsque les requêtes de création de clés résistantes au rollback sont envoyées lorsque l'espace de stockage est plein.

begin

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

Une implémentation KeyMint prend en charge au moins 16 opérations simultanées. Le keystore utilise jusqu'à 15 emplacements, en laissant un pour vold à utiliser pour le chiffrement des mots de passe. Lorsque Keystore compte 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 requête pour en démarrer une 16e, il appelle abort() sur l'opération la moins récente pour réduire le nombre d'opérations actives à 14 avant d'appeler begin() pour démarrer l'opération nouvellement 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 clés, les appels à begin() doivent inclure ces balises 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 interrompue et l'objet de liaison 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 est le cas où la clé comporte une ou plusieurs valeurs Tag::USER_SECURE_ID et n'a 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'autorisation 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 à l'Tag::USER_AUTH_TYPE de la clé.
  • Vérifie que le jeton contient la valeur de défi pour l'opération en cours dans le champ de défi.

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

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