La disponibilité d'un environnement d'exécution sécurisé (TEE) dans un système sur puce (SoC) permet aux appareils Android de fournir des services de sécurité renforcés et soutenus par du matériel à l'OS Android, aux services de plate-forme et même aux applications tierces (sous la forme d'extensions spécifiques à Android de l'architecture de cryptographie Java standard, voir KeyGenParameterSpec
).
Glossaire
Voici un aperçu des composants de 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 qui s'exécute dans l'espace de processus de l'application.
AndroidKeyStore
répond aux requêtes de l'application concernant le comportement du Keystore en les transmettant au démon Keystore. - daemon keystore
- Un daemon du système Android qui fournit un accès à toutes les fonctionnalités Keystore via une API Binder. Ce démon est responsable du stockage des keyblobs créés par l'implémentation KeyMint (ou Keymaster) sous-jacente, qui contiennent le matériel de clé secrète, chiffré de sorte que Keystore puisse les stocker, mais pas les utiliser ni les révéler.
- Service KeyMint HAL
- Un serveur AIDL qui implémente le HAL
IKeyMintDevice
, fournissant un accès à la TA KeyMint sous-jacente. - Application de confiance KeyMint (TA)
- Logiciel s'exécutant 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 contenu brut de la clé et valide toutes les conditions de contrôle d'accès sur les clés avant d'autoriser leur utilisation.
LockSettingsService
- Composant du système Android responsable de l'authentification de l'utilisateur, par mot de passe et par empreinte digitale. Bien qu'il ne fasse pas partie de Keystore, il est pertinent, car Keystore prend en charge le concept de clés liées à l'authentification : il s'agit de clés qui ne peuvent être utilisées que si l'utilisateur s'est authentifié.
LockSettingsService
interagit avec les TA Gatekeeper et Fingerprint pour obtenir des jetons d'authentification, qu'il fournit au démon du keystore et qui sont utilisés par la TA KeyMint. - TA Gatekeeper
- Composant s'exécutant dans l'environnement sécurisé, responsable de l'authentification des mots de passe des utilisateurs et de la génération des jetons d'authentification utilisés pour prouver à la TA KeyMint qu'une authentification a été effectuée pour un utilisateur spécifique à un moment donné.
- Fingerprint TA
- : composant s'exécutant dans l'environnement sécurisé, responsable de l'authentification des empreintes digitales de l'utilisateur et de la génération des jetons d'authentification utilisés pour prouver à l'autorité de certification KeyMint qu'une authentification a été effectuée pour un utilisateur spécifique à un moment donné.
Architecture
L'API Android Keystore et la HAL KeyMint sous-jacente fournissent un ensemble de primitives cryptographiques de base, mais adéquates, pour permettre l'implémentation de protocoles utilisant des clés matérielles à accès contrôlé.
Le HAL KeyMint est un service fourni par l'OEM et 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. Au lieu de cela, le service KeyMint HAL s'exécutant dans Android délègue les opérations sensibles à une TA s'exécutant dans un environnement sécurisé, généralement en sérialisant et désérialisant les requêtes dans un format filaire défini par l'implémentation.
L'architecture obtenue se présente comme suit :

Figure 1 : Accès à KeyMint.
L'API KeyMint HAL est de bas niveau. Elle est utilisée par les composants internes de la plate-forme et n'est pas 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 matérielles, à 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 Keystore
Pour prendre en charge ce contrôle des accès, les clés sont identifiées dans Keystore à l'aide d'un descripteur de clé. Ce descripteur de clé indique un domaine auquel appartient le descripteur, ainsi qu'une identité au sein de ce domaine.
Les applications Android accèdent à Keystore à l'aide de l'architecture Java Cryptography standard, qui identifie les clés avec un alias de chaîne. Cette méthode d'identification correspond en interne au domaine APP
du Keystore. L'UID de l'appelant est également inclus pour différencier 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 une fois la clé chargée. Cet ID numérique sert d'identifiant pour les 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, il est possible qu'une application accorde l'utilisation d'une clé à une autre application (identifiée par son UID). Cette opération d'autorisation renvoie un identifiant d'autorisation unique, qui est utilisé comme identifiant pour les descripteurs de clé dans le domaine GRANT
. Là encore, le contrôle des accès est toujours effectué : même si une application tierce découvre l'ID d'autorisation pour la clé d'un bénéficiaire, elle ne peut pas l'utiliser.
Keystore accepte également 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 les applications :
- Le domaine
BLOB
indique qu'il n'y a pas d'identifiant pour la clé dans le descripteur de clé. Au lieu de cela, 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 à Keystore avant que la partition de données ne soit montée. - Le domaine
SELINUX
permet aux composants système de partager des clés, dont l'accès est régi par un identifiant numérique correspondant à un libellé SELinux (voir Règle SELinux pour keystore_key).
Règle SELinux pour keystore_key
Les valeurs d'identifiant utilisées pour les descripteurs de clé Domain::SELINUX
sont configurées dans le fichier de règles SELinux keystore2_key_context
.
Chaque ligne de ces fichiers associe un nombre à 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é de super-utilisateur. Utilisé uniquement pour les tests sur les versions userdebug et ingénieur. Non pertinent sur les versions utilisateur. |
1 | shell_key |
N/A | Espace de noms disponible pour le shell. Principalement utilisé 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 Règle SELinux pour keystore_key, le tableau suivant décrit les autres autorisations SELinux requises pour effectuer diverses opérations système et de maintenance :
Autorisation | Signification |
---|---|
add_auth
|
Obligatoire pour ajouter des jetons d'authentification à 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 lors de la désinstallation d'applications. |
list
|
Requis par le système pour énumérer les clés selon différentes propriétés, telles que la propriété ou le fait qu'elles soient liées à l'authentification. Cette autorisation n'est pas requise pour les appelants qui énumèrent leurs propres espaces de noms (couverts par l'autorisation get_info ). |
lock
|
Obligatoire pour informer le keystore que l'appareil a été verrouillé, ce qui supprime les super-clés pour s'assurer que les clés liées à l'authentification ne sont pas disponibles. |
unlock
|
Nécessaire pour informer le Keystore que l'appareil a été déverrouillé, ce qui restaure l'accès aux super-clés qui protègent les clés liées à l'authentification. |
reset
|
Nécessaire pour rétablir la configuration d'usine du Keystore et supprimer toutes les clés qui ne sont pas essentielles au fonctionnement de l'OS Android. |
Historique
Dans Android 5 et versions antérieures, Android disposait d'une API de services cryptographiques simple, soutenue par le matériel, fournie par les versions 0.2 et 0.3 de la couche d'abstraction matérielle (HAL) Keymaster. Opérations de signature et de validation numériques fournies par le Keystore, ainsi que génération et importation de paires de clés de signature asymétriques. 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 API de signature uniquement. Android 6.0 a étendu l'API Keystore pour offrir un plus large éventail 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 soutenues par le matériel. 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écifiques ou avec des paramètres cryptographiques spécifiques.
En plus d'étendre la gamme de primitives cryptographiques, Keystore dans Android 6.0 a ajouté les éléments suivants :
- Un système de contrôle de l'utilisation pour limiter l'utilisation des clés et atténuer le risque de compromission de la sécurité en raison d'une mauvaise utilisation des clés
- Schéma de contrôle des accès permettant de restreindre les clés à des utilisateurs et clients spécifiques, et à une plage de temps définie
Android 7.0
Dans Android 7.0, Keymaster 2 a ajouté la prise en charge de l'attestation de clé et de l'association 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 un matériel sécurisé et sa configuration vérifiables à distance.
L'association de version associe les clés à la version du système d'exploitation et au niveau du correctif. Cela permet de s'assurer qu'un pirate informatique qui découvre une faille dans une ancienne version du système ou du logiciel TEE ne peut pas effectuer un rollback d'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 incrémentées en même temps que l'appareil. Toutefois, si l'appareil est rétabli à une version antérieure, les clés deviennent inutilisables.
Android 8.0
Dans Android 8.0, Keymaster 3 est passé de l'ancienne structure C HAL à 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 cette modification, de nombreux types d'arguments ont changé, bien que les types et les méthodes aient une correspondance un-à-un avec les anciens types et les méthodes de structure 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 pour attester fortement des identifiants matériels, tels que le numéro de série de l'appareil, le nom du produit et l'ID du téléphone (IMEI ou MEID). Pour implémenter cet ajout, 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 que de définir un mécanisme permettant de désactiver la fonctionnalité de manière sécurisée et permanente.
Android 9
Dans Android 9, les mises à jour incluaient :
- Mise à jour vers Keymaster 4
- Compatibilité avec les éléments sécurisés intégrés
- Compatibilité avec l'importation sécurisée de clés
- Compatibilité avec le chiffrement 3DES
- Modifications apportées à l'association de versions afin que
boot.img
etsystem.img
aient des versions définies séparément pour permettre des mises à jour indépendantes
Android 10
Android 10 a introduit la version 4.1 de Keymaster HAL, qui a ajouté les éléments suivants :
- Prise en charge des clés utilisables uniquement lorsque l'appareil est déverrouillé
- Prise en charge des clés qui ne peuvent être utilisées qu'aux premières étapes du démarrage
- Prise en charge facultative des clés de stockage enveloppées dans du matériel
- Prise en charge facultative de l'attestation unique à 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 :
- Compatibilité avec 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 d'utilisations limité
Android 12 inclut également une nouvelle version du démon système keystore, réécrite en Rust et appelée keystore2
.
Android 13
Android 13 a ajouté la version 2 de KeyMint HAL, qui est compatible avec Curve25519 pour la signature et l'accord de clé.