Keystore intégré au matériel

La disponibilité d'un environnement d'exécution sécurisé dans un système sur une puce (SoC) permet aux appareils Android de fournir des services de sécurité performants et basés sur du matériel à l'OS Android, aux services de plate-forme et même aux applications tierces (sous la forme d'extensions Android spécifiques à l'architecture de cryptographie Java standard, consultez la section KeyGenParameterSpec).

Glossaire

Voici une brève présentation des composants du Keystore et de leurs relations.

AndroidKeyStore
API et composant du framework Android utilisés par les applications pour accéder à la fonctionnalité Keystore. Il s'agit d'une implémentation des API Java Cryptography Architecture standards, mais il ajoute également des extensions spécifiques à Android et se compose de code Java exécuté dans l'espace de processus de l'application. AndroidKeyStore répond aux requêtes d'application concernant le comportement du keystore en les transmettant au daemon du keystore.
daemon keystore
Un daemon système Android qui permet d'accéder à toutes les fonctionnalités Keystore via une API Binder. Ce daemon est chargé de stocker les keyblobs créés par l'implémentation KeyMint (ou Keymaster) sous-jacente, qui contiennent le matériel de clé secrète, chiffré afin que Keystore puisse les stocker, mais pas les utiliser ni les révéler.
Service HAL KeyMint
Un serveur AIDL qui implémente le HAL IKeyMintDevice, qui permet d'accéder au TA KeyMint sous-jacent.
Application sécurisée (TA) KeyMint
Logiciel exécuté dans un contexte sécurisé, le plus souvent dans TrustZone sur un SoC ARM, qui fournit toutes les opérations cryptographiques sécurisées. Cette application a accès au matériel de clé brut et valide toutes les conditions de contrôle des accès sur les clés avant de les autoriser à être utilisées.
LockSettingsService
Composant du système Android responsable de l'authentification des utilisateurs, à la fois par mot de passe et empreinte digitale. Il ne fait pas partie de Keystore, mais est pertinent, car Keystore prend en charge le concept de clés liées à l'authentification: clés qui ne peuvent être utilisées que si l'utilisateur s'est authentifié. LockSettingsService interagit avec le TA Gatekeeper et le TA Fingerprint pour obtenir des jetons d'authentification, qu'il fournit au daemon du keystore et qui sont consommés par le TA KeyMint.
Assistance technique Gatekeeper
Composant exécuté dans l'environnement sécurisé, chargé d'authentifier les mots de passe des utilisateurs et de générer des jetons d'authentification utilisés pour prouver à l'agent de confiance KeyMint qu'une authentification a été effectuée pour un utilisateur particulier à un moment donné.
TA d'empreinte digitale
Composant exécuté dans l'environnement sécurisé, chargé d'authentifier les empreintes digitales des utilisateurs et de générer des jetons d'authentification utilisés pour prouver à l'agent de confiance KeyMint qu'une authentification a été effectuée pour un utilisateur particulier à un moment donné.

Architecture

L'API Android Keystore et le HAL KeyMint sous-jacent fournissent un ensemble de primitives cryptographiques de base, mais adapté, pour permettre l'implémentation de protocoles à l'aide de clés matérielles contrôlées par accès.

Le HAL KeyMint est un service fourni par l'OEM utilisé par le service Keystore pour fournir des services cryptographiques avec support matériel. Pour assurer la sécurité du matériel de clé privée, les implémentations HAL n'effectuent aucune opération sensible dans l'espace utilisateur, ni même dans l'espace du noyau. À la place, le service HAL KeyMint exécuté dans Android délègue les opérations sensibles à un TA exécuté dans un environnement sécurisé, généralement en marshallant et en démarshallant les requêtes dans un format de transmission défini par l'implémentation.

L'architecture obtenue se présente comme suit:

Accès à KeyMint

Figure 1 : Accès à KeyMint.

L'API HAL KeyMint est de bas niveau, utilisée par les composants internes à la plate-forme et non exposée aux développeurs d'applications. L'API Java de niveau supérieur disponible pour les applications est décrite sur le site pour les développeurs Android.

Contrôle des accès

Android Keystore fournit un composant central pour le stockage et l'utilisation de clés cryptographiques basées sur du matériel, à la fois pour les applications et pour d'autres composants système. Par conséquent, l'accès à une clé individuelle est normalement limité à l'application ou au composant système qui l'a créée.

Domaines de keystore

Pour prendre en charge ce contrôle des accès, les clés sont identifiées à Keystore à l'aide d'un descripteur de clé. Ce descripteur de clé indique un domaine auquel le descripteur appartient, ainsi qu'une identité dans ce domaine.

Les applications Android accèdent à Keystore à l'aide de l'architecture Java Cryptography standard, qui identifie les clés à l'aide d'un alias de chaîne. Cette méthode d'identification se mappe en interne sur le domaine APP du Keystore. L'UID de l'appelant est également inclus pour distinguer les clés de différentes applications, ce qui empêche une application d'accéder aux clés d'une autre.

En interne, le code des frameworks reçoit également un ID de clé numérique unique après le chargement d'une clé. Cet ID numérique est utilisé comme identifiant des descripteurs de clé dans le domaine KEY_ID. Toutefois, le contrôle des accès est toujours effectué: même si une application découvre un ID de clé pour la clé d'une autre application, elle ne peut pas l'utiliser dans des circonstances normales.

Toutefois, une application peut autoriser l'utilisation d'une clé par une autre application (identifiée par l'UID). Cette opération d'octroi renvoie un identifiant d'octroi unique, qui est utilisé comme identifiant des descripteurs de clé dans le domaine GRANT. Encore une fois, le contrôle des accès est toujours effectué: même si une troisième application découvre l'ID d'octroi de la clé d'un bénéficiaire, elle ne peut pas l'utiliser.

Keystore prend également en charge deux autres domaines pour les descripteurs de clés, qui sont utilisés pour d'autres composants système et ne sont pas disponibles pour les clés créées par l'application:

  • Le domaine BLOB indique qu'il n'y a pas d'identifiant pour la clé dans le descripteur de clé. À la place, le descripteur de clé contient le keyblob lui-même, et le client gère le stockage du keyblob. Il est utilisé par les clients (par exemple, vold) qui doivent accéder au Keystore avant le montage de la partition de données.
  • Le domaine SELINUX permet aux composants système de partager des clés, avec un accès régi par un identifiant numérique correspondant à un libellé SELinux (voir la règle SELinux pour keystore_key).

Règle SELinux pour keystore_key

Les valeurs d'identifiant utilisées pour les descripteurs de clés Domain::SELINUX sont configurées dans le fichier de règles SELinux keystore2_key_context. Chaque ligne de ces fichiers met en correspondance un nombre avec un libellé SELinux, par exemple:

# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and
# Settings to share keystore keys.
102            u:object_r:wifi_key:s0

Un composant qui a besoin d'accéder à la clé avec l'ID 102 dans le domaine SELINUX doit disposer de la règle SELinux correspondante. Par exemple, pour autoriser wpa_supplicant à obtenir et à utiliser ces clés, ajoutez la ligne suivante à hal_wifi_supplicant.te:

allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };

Les identifiants numériques des clés Domain::SELINUX sont divisés en plages pour prendre en charge différentes partitions sans collision:

Partition Plage Fichiers de configuration
Système 0 à 9 999 /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
Système étendu 10 000 à 19 999 /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
Produit 20 000 à 29 999 /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
Fournisseur 30 000 à 39 999 /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts

Les valeurs spécifiques suivantes ont été définies pour la partition système:

ID de l'espace de noms Libellé SEPolicy UID Description
0 su_key N/A Clé super-utilisateur. Utilisé uniquement pour les tests sur les builds userdebug et eng. Non pertinent pour les builds utilisateur.
1 shell_key N/A Espace de noms disponible pour le shell. Utilisé principalement pour les tests, mais peut également être utilisé sur les builds utilisateur à partir de la ligne de commande.
100 vold_key N/A Destiné à être utilisé par vold.
101 odsign_key N/A Utilisé par le daemon de signature sur l'appareil.
102 wifi_key AID_WIFI(1010) Utilisé par le sous-système Wi-Fi d'Android, y compris wpa_supplicant.
103 locksettings_key N/A Utilisé par LockSettingsService
120 resume_on_reboot_key AID_SYSTEM(1000) Utilisé par le serveur système d'Android pour prendre en charge la reprise au redémarrage.

Vecteurs d'accès

Le keystore permet de contrôler les opérations pouvant être effectuées sur une clé, en plus de contrôler l'accès global à une clé. Les autorisations keystore2_key sont décrites dans le fichier KeyPermission.aidl.

Autorisations système

En plus des contrôles d'accès par clé décrits dans la section Règle SELinux pour keystore_key, le tableau suivant décrit d'autres autorisations SELinux requises pour effectuer diverses opérations de système et de maintenance:

Autorisation Signification
add_auth Obligatoire pour ajouter des jetons d'authentification au Keystore. Utilisé par les fournisseurs d'authentification tels que Gatekeeper ou BiometricManager.
clear_ns Obligatoire pour supprimer toutes les clés d'un espace de noms spécifique. Utilisé comme opération de maintenance lorsque des applications sont désinstallées.
list Nécessaire au système pour énumérer les clés en fonction de diverses propriétés, telles que la propriété ou si elles sont liées à l'authentification. Cette autorisation n'est pas requise par les appelants énumérant leurs propres espaces de noms (couverts par l'autorisation get_info).
lock Nécessaire pour informer le keystore que l'appareil a été verrouillé, ce qui à son tour supprime les super-clés pour s'assurer que les clés liées à l'authentification ne sont pas disponibles.
unlock Obligatoire pour informer le keystore que l'appareil a été déverrouillé, rétablissant l'accès aux super-clés qui protègent les clés liées à l'authentification.
reset Obligatoire pour rétablir la configuration d'usine du Keystore, en supprimant toutes les clés qui ne sont pas essentielles au fonctionnement de l'OS Android.

Historique

Sous Android 5 et versions antérieures, Android disposait d'une API de services cryptographiques simple, basée sur le matériel, fournie par les versions 0.2 et 0.3 de la couche d'abstraction matérielle (HAL) Keymaster. Le keystore fournissait des opérations de signature et de validation numériques, ainsi que la génération et l'importation de paires de clés de signature asymétrique. Cette fonctionnalité est déjà implémentée sur de nombreux appareils, mais de nombreux objectifs de sécurité ne peuvent pas être facilement atteints avec une seule API de signature. Android 6.0 a étendu l'API Keystore pour fournir un plus grand nombre de fonctionnalités.

Android 6.0

Dans Android 6.0, Keymaster 1.0 a ajouté des primitives cryptographiques symétriques, AES et HMAC, ainsi qu'un système de contrôle des accès pour les clés matérielles. Les contrôles d'accès sont spécifiés lors de la génération de la clé et appliqués pendant toute sa durée de vie. Les clés peuvent être limitées à une utilisation uniquement après l'authentification de l'utilisateur, et uniquement à des fins spécifiées ou avec des paramètres cryptographiques spécifiés.

En plus d'étendre la gamme de primitives cryptographiques, Keystore dans Android 6.0 a ajouté les éléments suivants:

  • Un schéma de contrôle de l'utilisation permettant de limiter l'utilisation des clés afin de réduire le risque de compromission de la sécurité en raison d'une utilisation abusive des clés
  • Un schéma de contrôle des accès permettant de limiter les clés à des utilisateurs, des clients et une période définis

Android 7.0

Dans Android 7.0, Keymaster 2 a ajouté la prise en charge de l'attestation de clé et de la liaison de version.

L'attestation de clé fournit des certificats de clé publique contenant une description détaillée de la clé et de ses contrôles d'accès, afin de rendre l'existence de la clé dans du matériel sécurisé et sa configuration vérifiables à distance.

La liaison de version lie les clés au système d'exploitation et au niveau du correctif. Cela garantit qu'un pirate informatique qui découvre une faille dans une ancienne version du système ou du logiciel TEE ne peut pas rétablir un appareil vers la version vulnérable et utiliser les clés créées avec la version plus récente. De plus, lorsqu'une clé avec une version et un niveau de correctif donnés est utilisée sur un appareil qui a été mis à niveau vers une version ou un niveau de correctif plus récents, la clé est mise à niveau avant de pouvoir être utilisée, et la version précédente de la clé est invalidée. Lorsque l'appareil est mis à niveau, les clés sont mises à jour avec l'appareil, mais toute réversion de l'appareil vers une version précédente rend les clés inutilisables.

Android 8.0

Dans Android 8.0, Keymaster 3 est passé de l'ancienne structure HAL C à l'interface HAL C++ générée à partir d'une définition dans le nouveau langage de définition d'interface matérielle (HIDL). Dans le cadre de ce changement, de nombreux types d'arguments ont changé, bien que les types et les méthodes correspondent de manière individuelle aux anciens types et aux méthodes de struct HAL.

En plus de cette révision de l'interface, Android 8.0 a étendu la fonctionnalité d'attestation de Keymaster 2 pour prendre en charge l'attestation d'identité. L'attestation d'identité fournit un mécanisme limité et facultatif permettant d'attester de manière forte des identifiants matériels, tels que le numéro de série de l'appareil, le nom du produit et l'ID de téléphone (IMEI ou MEID). Pour implémenter cette addition, Android 8.0 a modifié le schéma d'attestation ASN.1 afin d'ajouter l'attestation d'identité. Les implémentations Keymaster doivent trouver un moyen sécurisé de récupérer les éléments de données pertinents, ainsi qu'un mécanisme permettant de désactiver de manière sécurisée et permanente la fonctionnalité.

Android 9

Dans Android 9, les mises à jour incluaient les éléments suivants:

  • Mise à jour vers Keymaster 4
  • Compatibilité avec les éléments sécurisés intégrés
  • Prise en charge de l'importation de clés sécurisée
  • Compatibilité avec le chiffrement 3DES
  • Modifications apportées à la liaison de version afin que boot.img et system.img disposent de versions définies séparément pour permettre des mises à jour indépendantes

Android 10

Android 10 a introduit la version 4.1 de la HAL Keymaster, qui a ajouté les éléments suivants:

  • Prise en charge des clés qui ne sont utilisables que lorsque l'appareil est déverrouillé
  • Prise en charge des clés qui ne peuvent être utilisées que lors des premières étapes de démarrage
  • Prise en charge facultative des clés de stockage encapsulées par matériel
  • Prise en charge facultative de l'attestation propre à l'appareil dans StrongBox

Android 12

Android 12 a introduit le nouveau HAL Keymint, qui remplace le HAL Keymaster, mais offre des fonctionnalités similaires. En plus de toutes les fonctionnalités ci-dessus, le HAL KeyMint inclut également les éléments suivants:

  • Prise en charge de la clé-contrat ECDH
  • Prise en charge des clés d'attestation spécifiées par l'utilisateur
  • Prise en charge des clés avec un nombre limité d'utilisations

Android 12 inclut également une nouvelle version du daemon système du keystore, réécrite en Rust et appelée keystore2.

Android 13

Android 13 a ajouté la version 2 de l'HAL KeyMint, qui est compatible avec Curve25519 pour la signature et l'accord de clé.