Keystore fournit un endroit plus sécurisé pour créer, stocker et utiliser des clés cryptographiques de manière contrôlée. Lorsque le stockage de clés basé sur le matériel est disponible et utilisé, le matériel de clé est plus sécurisé contre l'extraction de l'appareil, et Keymaster applique des restrictions difficiles à contourner.
Cependant, cela n'est vrai que si les clés du magasin de clés sont connues pour se trouver dans un stockage sauvegardé sur matériel. Dans Keymaster 1, il n'y avait aucun moyen pour les applications ou les serveurs distants de vérifier de manière fiable si c'était le cas. Le démon du magasin de clés a chargé le keymaster HAL disponible et a cru tout ce que le HAL a dit en ce qui concerne la sauvegarde matérielle des clés.
Pour remédier à cela, Keymaster a introduitl'attestation de clé dans Android 7.0 (Keymaster 2) et l'attestation d'identité dans Android 8.0 (Keymaster 3).
L'attestation de clé vise à fournir un moyen de déterminer avec certitude si une paire de clés asymétriques est basée sur le matériel, quelles sont les propriétés de la clé et quelles contraintes sont appliquées à son utilisation.
L'attestation d'identification permet à l'appareil de fournir la preuve de ses identifiants matériels, tels que le numéro de série ou l'IMEI.
Attestation clé
Pour prendre en charge l'attestation de clé, Android 7.1 a introduit un ensemble de balises, de type et de méthode dans HAL.
Mots clés
-
Tag::ATTESTATION_CHALLENGE
-
Tag::INCLUDE_UNIQUE_ID
-
Tag::RESET_SINCE_ID_ROTATION
Taper
Keymaster 2 et inférieur
typedef struct { keymaster_blob_t* entries; size_t entry_count; } keymaster_cert_chain_t;
Méthode AttestKey
method
Maître des clés 3
attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams) generates(ErrorCode error, vec<vec<uint8_t>> certChain);
Keymaster 2 et inférieur
keymaster_error_t (*attest_key)(const struct keymaster2_device* dev, const keymaster_key_blob_t* key_to_attest, const keymaster_key_param_set_t* attest_params, keymaster_cert_chain_t* cert_chain);
-
dev
est la structure du périphérique keymaster. -
keyToAttest
est le blob de clé renvoyé pargenerateKey
pour lequel l'attestation sera créée. -
attestParams
est une liste de tous les paramètres nécessaires à l'attestation. Cela inclutTag::ATTESTATION_CHALLENGE
et éventuellementTag::RESET_SINCE_ID_ROTATION
, ainsi queTag::APPLICATION_ID
etTag::APPLICATION_DATA
. Les deux derniers sont nécessaires pour déchiffrer le blob de clé s'ils ont été spécifiés lors de la génération de la clé. -
certChain
est le paramètre de sortie, qui renvoie un tableau de certificats. L'entrée 0 est le certificat d'attestation, ce qui signifie qu'il certifie la clé dekeyToAttest
et contient l'extension d'attestation.
La méthode attestKey
est considérée comme une opération de clé publique sur la clé attestée, car elle peut être appelée à tout moment et n'a pas besoin de respecter les contraintes d'autorisation. Par exemple, si la clé attestée nécessite une authentification de l'utilisateur pour être utilisée, une attestation peut être générée sans authentification de l'utilisateur.
Certificat d'attestation
Le certificat d'attestation est un certificat X.509 standard, avec une extension d'attestation facultative qui contient une description de la clé attestée. Le certificat est signé avec une clé d'attestation certifiée. La clé d'attestation peut utiliser un algorithme différent de celui de la clé attestée.
Le certificat d'attestation contient les champs du tableau ci-dessous et ne peut contenir aucun champ supplémentaire. Certains champs spécifient une valeur de champ fixe. Les tests CTS valident que le contenu du certificat est exactement tel que défini.
Certificat SÉQUENCE
Nom du champ (voir RFC 5280 ) | Valeur |
---|---|
tbsCertificat | SÉQUENCE du certificat TBS |
Algorithme de signature | AlgorithmIdentifier de l'algorithme utilisé pour signer la clé : ECDSA pour les clés EC, RSA pour les clés RSA. |
valeur de signature | CHAÎNE BINAIRE, signature calculée sur le certificat tbs encodé ASN.1 DER. |
SÉQUENCE du certificat TBS
Nom du champ (voir RFC 5280 ) | Valeur |
---|---|
version | INTEGER 2 (signifie certificat v3) |
serialNumber | INTEGER 1 (valeur fixe : identique pour tous les certificats) |
signature | AlgorithmIdentifiant de l'algorithme utilisé pour signer la clé : ECDSA pour les clés EC, RSA pour les clés RSA. |
issuer | Identique au champ d'objet de la clé d'attestation de lot. |
validity | SEQUENCE de deux dates, contenant les valeurs de Tag::ACTIVE_DATETIME et Tag::USAGE_EXPIRE_DATETIME . Ces valeurs sont en millisecondes depuis le 1er janvier 1970. Voir RFC 5280 pour les représentations de date correctes dans les certificats. Si Tag::ACTIVE_DATETIME n'est pas présent, utilisez la valeur de Tag::CREATION_DATETIME . Si Tag::USAGE_EXPIRE_DATETIME n'est pas présent, utilisez la date d'expiration du certificat de clé d'attestation de lot. |
subject | CN = "Android Keystore Key" (valeur fixe : identique sur tous les certificats) |
subjectPublicKeyInfo | SubjectPublicKeyInfo contenant la clé publique attestée. |
extensions/Key Usage | digitalSignature : défini si la clé a un but KeyPurpose::SIGN ou KeyPurpose::VERIFY . Tous les autres bits ne sont pas définis. |
extensions/CRL Distribution Points | Valeur à déterminer |
extensions/"attestation" | L'OID est 1.3.6.1.4.1.11129.2.1.17 ; le contenu est défini dans la section Extension d'attestation ci-dessous. Comme pour toutes les extensions de certificat X.509, le contenu est représenté sous la forme d'un OCTET_STRING contenant un codage DER de l'attestation SEQUENCE. |
Extension d'attestation
L'extension attestation
contient une description complète des autorisations de keymaster associées à la clé, dans une structure qui correspond directement aux listes d'autorisation utilisées dans Android et le keymaster HAL. Chaque étiquette dans une liste d'autorisation est représentée par une entrée SEQUENCE
ASN.1, explicitement étiquetée avec le numéro d'étiquette du maître de clé, mais avec le descripteur de type (quatre bits de poids fort) masqué.
Par exemple, dans Keymaster 3, Tag::PURPOSE
est défini dans types.hal comme ENUM_REP | 1
. Pour l'extension d'attestation, la valeur ENUM_REP
est supprimée, laissant la balise 1
. (Pour Keymaster 2 et inférieur, KM_TAG_PURPOSE
est défini dans keymaster_defs.h.)
Les valeurs sont traduites de manière simple en types ASN.1, selon ce tableau :
Type de maître de clé | Type ASN.1 |
---|---|
ENUM | ENTIER |
ENUM_REP | ENSEMBLE d'ENTIERS |
UINT | ENTIER |
UINT_REP | ENSEMBLE d'ENTIERS |
ULONG | ENTIER |
ULONG_REP | ENSEMBLE d'ENTIERS |
DATE | INTEGER (millisecondes depuis le 1er janvier 1970 00:00:00 GMT) |
BOOL | NULL (dans keymaster, tag présent signifie vrai, absent signifie faux. La même sémantique s'applique au codage ASN.1) |
BIGNUM | Non utilisé actuellement, donc aucun mappage n'est défini |
BYTES | OCTET_STRING |
Schéma
Le contenu de l'extension d'attestation est décrit par le schéma ASN.1 suivant.
KeyDescription ::= SEQUENCE { attestationVersion INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3. attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, teeEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), StrongBox (2), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL. digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, # KM4 activeDateTime [400] EXPLICIT INTEGER OPTIONAL originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4 trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4 unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, # KM4 allApplications [600] EXPLICIT NULL OPTIONAL, applicationId [601] EXPLICIT OCTET_STRING OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only. rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3 vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, # KM4 bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, # KM4 } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, # KM4 } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
Champs KeyDescription
Les champs keymasterVersion
et attestationChallenge
sont identifiés par position, plutôt que par balise, de sorte que les balises dans le formulaire codé spécifient uniquement le type de champ. Les champs restants sont tagués implicitement comme spécifié dans le schéma.
Nom de domaine | Taper | Valeur |
---|---|---|
attestationVersion | ENTIER | Version du schéma d'attestation : 1, 2 ou 3. |
attestationSecurity | Niveau de sécurité | Le niveau de sécurité de cette attestation. Il est possible d'obtenir des attestations logicielles de clés matérielles. Ces attestations ne sont pas fiables si le système Android est compromis. |
keymasterVersion | ENTIER | Version de l'appareil keymaster : 0, 1, 2, 3 ou 4. |
keymasterSecurity | Niveau de sécurité | Le niveau de sécurité de l'implémentation du keymaster. |
attestationChallenge | OCTET_STRING | Valeur de Tag::ATTESTATION_CHALLENGE , spécifiée à la demande d'attestation. |
uniqueId | OCTET_STRING | ID unique facultatif, présent si la clé a Tag::INCLUDE_UNIQUE_ID |
softwareEnforced | Liste d'autorisation | Autorisations facultatives de keymaster qui ne sont pas appliquées par le TEE, le cas échéant. |
teeEnforced | Liste d'autorisation | Facultatif, autorisations Keymaster qui sont appliquées par le TEE, le cas échéant. |
Champs AuthorizationList
Les champs AuthorizationList
sont tous facultatifs et sont identifiés par la valeur de la balise keymaster, avec les bits de type masqués. Un balisage explicite est utilisé afin que les champs contiennent également une balise indiquant leur type ASN.1, pour une analyse plus facile.
Pour plus de détails sur les valeurs de chaque champ, voir types.hal
pour Keymaster 3 et keymaster_defs.h
pour Keymaster 2 et inférieur. Les noms de balises Keymaster ont été transformés en noms de champs en omettant le préfixe KM_TAG
et en changeant le reste en casse camel, donc Tag::KEY_SIZE
est devenu keySize
.
Champs RootOfTrust
Les champs RootOfTrust
sont identifiés par position.
Nom de domaine | Taper | Valeur |
---|---|---|
verifiedBootKey | OCTET_STRING | Hachage sécurisé de la clé utilisée pour vérifier l'image système. SHA-256 recommandé. |
deviceLocked | BOOLÉEN | Vrai si le chargeur de démarrage est verrouillé, ce qui signifie que seules les images signées peuvent être flashées et que la vérification du démarrage vérifiée est effectuée. |
verifiedBootState | État de démarrage vérifié | État du démarrage vérifié. |
verifiedBootHash | OCTET_STRING | Un résumé de toutes les données protégées par Verified Boot. Pour les appareils qui utilisent l'implémentation Android Verified Boot de Verified Boot, cette valeur contient le résumé de la structure VBMeta ou la structure de métadonnées Verified Boot. Pour en savoir plus sur le calcul de cette valeur, consultez The VBMeta Digest |
Valeurs VerifiedBootState
Les valeurs de verifiedBootState
ont les significations suivantes :
Valeur | Signification |
---|---|
Verified | Indique une chaîne de confiance complète s'étendant du chargeur de démarrage aux partitions vérifiées, y compris le chargeur de démarrage, la partition de démarrage et toutes les partitions vérifiées. Dans cet état, la verifiedBootKey est le hachage du certificat intégré, c'est-à-dire le certificat non modifiable gravé dans la ROM.Cet état correspond à l'état de démarrage vert , comme documenté dans la documentation du flux de démarrage vérifié . |
SelfSigned | Indique que la partition de démarrage a été vérifiée à l'aide du certificat intégré et que la signature est valide. Le chargeur de démarrage affiche un avertissement et l'empreinte digitale de la clé publique avant d'autoriser la poursuite du processus de démarrage. Dans cet état, la verifiedBootKey est le hachage du certificat auto-signé.Cet état correspond à l'état de démarrage jaune , comme documenté dans la documentation du flux de démarrage vérifié . |
Unverified | Indique qu'un appareil peut être librement modifié. L'intégrité de l'appareil est laissée à l'utilisateur pour vérifier hors bande. Le chargeur de démarrage affiche un avertissement à l'utilisateur avant d'autoriser la poursuite du processus de démarrage. Dans cet état, la valeur verifiedBootKey est vide.Cet état correspond à l'état de démarrage orange , comme documenté dans la documentation du flux de démarrage vérifié . |
Failed | Indique que l'appareil a échoué à la vérification. Aucun certificat d'attestation ne contient réellement cette valeur, car dans cet état, le chargeur de démarrage s'arrête. Il est inclus ici pour être complet. Cet état correspond à l'état de démarrage rouge , comme documenté dans la documentation du flux de démarrage vérifié . |
Valeurs SecurityLevel
Les valeurs de securityLevel
ont les significations suivantes :
Valeur | Signification |
---|---|
Software | Le code qui crée ou gère l'élément pertinent (attestation ou clé) est implémenté dans le système Android et peut être modifié si ce système est compromis. |
TrustedEnvironment | Le code qui crée ou gère l'élément concerné (attestation ou clé) est implémenté dans un environnement d'exécution sécurisé (TEE). Il pourrait être modifié si le TEE est compromis, mais le TEE est très résistant à la compromission à distance et modérément résistant à la compromission par une attaque matérielle directe. |
StrongBox | Le code qui crée ou gère l'élément concerné (attestation ou clé) est implémenté dans un module matériel de sécurité dédié. Il pourrait être modifié si le module de sécurité matériel est compromis, mais il est très résistant à la compromission à distance et très résistant à la compromission par une attaque matérielle directe. |
Identifiant unique
L'identifiant unique est une valeur de 128 bits qui identifie l'appareil, mais uniquement pour une période de temps limitée. La valeur est calculée avec :
HMAC_SHA256(T || C || R, HBK)
Où:
-
T
est la "valeur du compteur temporel", calculée en divisant la valeur deTag::CREATION_DATETIME
par 2592000000, en supprimant tout reste.T
change tous les 30 jours (2592000000 = 30 * 24 * 60 * 60 * 1000). -
C
est la valeur deTag::APPLICATION_ID
-
R
vaut 1 siTag::RESET_SINCE_ID_ROTATION
est présent dans le paramètre attest_params de l'appel attest_key, ou 0 si le tag n'est pas présent. -
HBK
est un secret lié au matériel unique connu de l'environnement d'exécution sécurisé et jamais révélé par celui-ci. Le secret contient au moins 128 bits d'entropie et est propre à l'appareil individuel (l'unicité probabiliste est acceptable compte tenu des 128 bits d'entropie). HBK doit être dérivé du matériel de clé fusionné via HMAC ou AES_CMAC.
Tronquez la sortie HMAC_SHA256 à 128 bits.
Clés d'attestation et certificats
Deux clés, une RSA et une ECDSA, ainsi que les chaînes de certificats correspondantes, sont provisionnées en toute sécurité dans l'appareil.
Android 12 introduit le provisionnement de clé à distance et Android 13 exige que les appareils l'implémentent. Remote Key Provisioning fournit aux appareils sur le terrain des certificats d'attestation ECDSA P256 par application. Ces certificats ont une durée de vie plus courte que les certificats fournis en usine.
Attestation d'identité
Android 8.0 inclut la prise en charge facultative de l'attestation d'identité pour les appareils avec Keymaster 3. L'attestation d'identité permet à l'appareil de fournir une preuve de ses identifiants matériels, tels que le numéro de série ou l'IMEI. Bien qu'il s'agisse d'une fonctionnalité facultative, il est fortement recommandé que toutes les implémentations de Keymaster 3 la prennent en charge, car le fait de pouvoir prouver l'identité de l'appareil permet de sécuriser davantage les cas d'utilisation tels que la véritable configuration à distance sans contact (car le côté distant peut être certain qu'il parle au bon appareil, et non à un appareil usurpant son identité).
L'attestation d'identification fonctionne en créant des copies des identifiants matériels de l'appareil auxquels seul l'environnement d'exécution sécurisé (TEE) peut accéder avant que l'appareil ne quitte l'usine. Un utilisateur peut déverrouiller le chargeur de démarrage de l'appareil et modifier le logiciel système et les identifiants signalés par les frameworks Android. Les copies des identifiants détenues par le TEE ne peuvent pas être manipulées de cette manière, garantissant que l'attestation d'identification de l'appareil attestera uniquement des identifiants matériels d'origine de l'appareil, contrecarrant ainsi les tentatives d'usurpation.
La surface API principale pour l'attestation d'ID s'appuie sur le mécanisme d'attestation de clé existant introduit avec Keymaster 2. Lors de la demande d'un certificat d'attestation pour une clé détenue par keymaster, l'appelant peut demander que les identifiants matériels de l'appareil soient inclus dans les métadonnées du certificat d'attestation. Si la clé est conservée dans le TEE, le certificat reviendra à une racine de confiance connue. Le destinataire d'un tel certificat peut vérifier que le certificat et son contenu, y compris les identifiants matériels, ont été rédigés par le TEE. Lorsqu'on lui demande d'inclure des identifiants matériels dans le certificat d'attestation, le TEE n'atteste que les identifiants conservés dans son stockage, tels qu'ils sont remplis dans l'usine.
Propriétés de stockage
Le stockage qui contient les identifiants de l'appareil doit avoir ces propriétés :
- Les valeurs dérivées des identifiants d'origine de l'appareil sont copiées dans le stockage avant que l'appareil ne quitte l'usine.
- La méthode
destroyAttestationIds()
peut détruire définitivement cette copie des données dérivées de l'identifiant. La destruction permanente signifie que les données sont complètement supprimées, de sorte qu'aucune réinitialisation d'usine ni aucune autre procédure effectuée sur l'appareil ne peut les restaurer. Ceci est particulièrement important pour les appareils sur lesquels un utilisateur a déverrouillé le chargeur de démarrage, modifié le logiciel système et modifié les identifiants renvoyés par les frameworks Android. - Les installations RMA doivent avoir la capacité de générer de nouvelles copies des données dérivées de l'identifiant matériel. De cette façon, un appareil qui passe par RMA peut effectuer à nouveau une attestation d'identité. Le mécanisme utilisé par les installations RMA doit être protégé afin que les utilisateurs ne puissent pas l'invoquer eux-mêmes, car cela leur permettrait d'obtenir des attestations d'identités usurpées.
- Aucun code autre que l'application de confiance Keymaster dans le TEE n'est capable de lire les données dérivées de l'identifiant conservées dans le stockage.
- Le stockage est inviolable : Si le contenu du stockage a été modifié, le TEE le traite comme si les copies du contenu avaient été détruites et refuse toute tentative d'attestation d'identité. Ceci est implémenté en signant ou en MACant le stockage comme décrit ci-dessous .
- Le stockage ne contient pas les identifiants d'origine. L'attestation d'identité impliquant un défi, l'appelant fournit toujours les identifiants à attester. Le TEE n'a qu'à vérifier que ceux-ci correspondent aux valeurs qu'ils avaient à l'origine. Le stockage de hachages sécurisés des valeurs d'origine plutôt que des valeurs permet cette vérification.
Construction
Pour créer une implémentation qui possède les propriétés répertoriées ci-dessus, stockez les valeurs dérivées de l'ID dans la construction S suivante. Ne stockez pas d'autres copies des valeurs d'ID, à l'exception des emplacements normaux du système, qu'un propriétaire d'appareil peut modifier en rootant :
S = D || HMAC(HBK, D)
où:
-
D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
-
HMAC
est la construction HMAC avec un hachage sécurisé approprié (SHA-256 recommandé) -
HBK
est une clé liée au matériel qui n'est utilisée à aucune autre fin -
ID 1 ...ID n
sont les valeurs d'ID d'origine ; l'association d'une valeur particulière à un index particulier dépend de l'implémentation, car différents dispositifs auront différents nombres d'identificateurs -
||
représente la concaténation
Étant donné que les sorties HMAC sont de taille fixe, aucun en-tête ou autre structure n'est requis pour pouvoir trouver des hachages d'ID individuels, ou le HMAC de D. En plus de vérifier les valeurs fournies pour effectuer l'attestation, les implémentations doivent valider S en extrayant D de S , en calculant HMAC(HBK, D) et en le comparant à la valeur dans S pour vérifier qu'aucun ID individuel n'a été modifié/corrompu. De plus, les implémentations doivent utiliser des comparaisons à temps constant pour tous les éléments d'identification individuels et la validation de S. Le temps de comparaison doit être constant quel que soit le nombre d'identifiants fournis et la correspondance correcte de toute partie du test.
Identificateurs matériels
L'attestation d'ID prend en charge les identifiants matériels suivants :
- Nom de la marque, tel que renvoyé par
Build.BRAND
dans Android - Nom de l'appareil, tel que renvoyé par
Build.DEVICE
dans Android - Nom du produit, tel que renvoyé par
Build.PRODUCT
dans Android - Nom du fabricant, tel qu'il est renvoyé par
Build.MANUFACTURER
dans Android - Nom du modèle, tel que renvoyé par
Build.MODEL
dans Android - Numéro de série
- IMEI de toutes les radios
- MEID de toutes les radios
Pour prendre en charge l'attestation d'ID d'appareil, un appareil atteste ces identifiants. Tous les appareils fonctionnant sous Android ont les six premiers et ils sont nécessaires pour que cette fonctionnalité fonctionne. Si l'appareil dispose de radios cellulaires intégrées, l'appareil doit également prendre en charge l'attestation des IMEI et/ou MEID des radios.
L'attestation d'identité est demandée en effectuant une attestation de clé et en incluant les identifiants de l'appareil à attester dans la demande. Les identifiants sont étiquetés comme suit :
-
ATTESTATION_ID_BRAND
-
ATTESTATION_ID_DEVICE
-
ATTESTATION_ID_PRODUCT
-
ATTESTATION_ID_MANUFACTURER
-
ATTESTATION_ID_MODEL
-
ATTESTATION_ID_SERIAL
-
ATTESTATION_ID_IMEI
-
ATTESTATION_ID_MEID
L'identifiant à attester est une chaîne d'octets encodée en UTF-8. Ce format s'applique également aux identifiants numériques. Chaque identifiant à attester est exprimé sous la forme d'une chaîne encodée en UTF-8.
Si l'appareil ne prend pas en charge l'attestation d'ID (ou si destroyAttestationIds()
a été appelé précédemment et que l'appareil ne peut plus attester ses ID), toute demande d'attestation de clé qui inclut une ou plusieurs de ces balises échoue avec ErrorCode::CANNOT_ATTEST_IDS
.
Si l'appareil prend en charge l'attestation d'identification et qu'une ou plusieurs des balises ci-dessus ont été incluses dans une demande d'attestation de clé, le TEE vérifie que l'identifiant fourni avec chacune des balises correspond à sa copie des identifiants matériels. Si un ou plusieurs identifiants ne correspondent pas, l'attestation entière échoue avec ErrorCode::CANNOT_ATTEST_IDS
. Il est valide que la même étiquette soit fournie plusieurs fois. Cela peut être utile, par exemple, lors de l'attestation d'IMEI : un appareil peut avoir plusieurs radios avec plusieurs IMEI. Une demande d'attestation est valide si la valeur fournie avec chaque ATTESTATION_ID_IMEI
correspond à l'une des radios de l'appareil. Il en va de même pour toutes les autres balises.
Si l'attestation est réussie, les ID attestés sont ajoutés à l' extension d'attestation (OID 1.3.6.1.4.1.11129.2.1.17) du certificat d'attestation émis, en utilisant le schéma ci-dessus . Les modifications apportées au schéma d'attestation Keymaster 2 sont en gras , avec des commentaires.
API Java
Cette section est uniquement informative. Les implémenteurs Keymaster n'implémentent ni n'utilisent l'API Java. Ceci est fourni pour aider les implémenteurs à comprendre comment la fonctionnalité est utilisée par les applications. Les composants du système peuvent l'utiliser différemment, c'est pourquoi il est crucial que cette section ne soit pas traitée comme normative.
,Keystore fournit un endroit plus sécurisé pour créer, stocker et utiliser des clés cryptographiques de manière contrôlée. Lorsque le stockage de clés basé sur le matériel est disponible et utilisé, le matériel de clé est plus sécurisé contre l'extraction de l'appareil, et Keymaster applique des restrictions difficiles à contourner.
Cependant, cela n'est vrai que si les clés du magasin de clés sont connues pour se trouver dans un stockage sauvegardé sur matériel. Dans Keymaster 1, il n'y avait aucun moyen pour les applications ou les serveurs distants de vérifier de manière fiable si c'était le cas. Le démon du magasin de clés a chargé le keymaster HAL disponible et a cru tout ce que le HAL a dit en ce qui concerne la sauvegarde matérielle des clés.
Pour remédier à cela, Keymaster a introduitl'attestation de clé dans Android 7.0 (Keymaster 2) et l'attestation d'identité dans Android 8.0 (Keymaster 3).
L'attestation de clé vise à fournir un moyen de déterminer avec certitude si une paire de clés asymétriques est basée sur le matériel, quelles sont les propriétés de la clé et quelles contraintes sont appliquées à son utilisation.
L'attestation d'identification permet à l'appareil de fournir la preuve de ses identifiants matériels, tels que le numéro de série ou l'IMEI.
Attestation clé
Pour prendre en charge l'attestation de clé, Android 7.1 a introduit un ensemble de balises, de type et de méthode dans HAL.
Mots clés
-
Tag::ATTESTATION_CHALLENGE
-
Tag::INCLUDE_UNIQUE_ID
-
Tag::RESET_SINCE_ID_ROTATION
Taper
Keymaster 2 et inférieur
typedef struct { keymaster_blob_t* entries; size_t entry_count; } keymaster_cert_chain_t;
Méthode AttestKey
method
Maître des clés 3
attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams) generates(ErrorCode error, vec<vec<uint8_t>> certChain);
Keymaster 2 et inférieur
keymaster_error_t (*attest_key)(const struct keymaster2_device* dev, const keymaster_key_blob_t* key_to_attest, const keymaster_key_param_set_t* attest_params, keymaster_cert_chain_t* cert_chain);
-
dev
est la structure du périphérique keymaster. -
keyToAttest
est le blob de clé renvoyé pargenerateKey
pour lequel l'attestation sera créée. -
attestParams
est une liste de tous les paramètres nécessaires à l'attestation. Cela inclutTag::ATTESTATION_CHALLENGE
et éventuellementTag::RESET_SINCE_ID_ROTATION
, ainsi queTag::APPLICATION_ID
etTag::APPLICATION_DATA
. Les deux derniers sont nécessaires pour déchiffrer le blob de clé s'ils ont été spécifiés lors de la génération de la clé. -
certChain
est le paramètre de sortie, qui renvoie un tableau de certificats. L'entrée 0 est le certificat d'attestation, ce qui signifie qu'il certifie la clé dekeyToAttest
et contient l'extension d'attestation.
La méthode attestKey
est considérée comme une opération de clé publique sur la clé attestée, car elle peut être appelée à tout moment et n'a pas besoin de respecter les contraintes d'autorisation. Par exemple, si la clé attestée nécessite une authentification de l'utilisateur pour être utilisée, une attestation peut être générée sans authentification de l'utilisateur.
Certificat d'attestation
Le certificat d'attestation est un certificat X.509 standard, avec une extension d'attestation facultative qui contient une description de la clé attestée. Le certificat est signé avec une clé d'attestation certifiée. La clé d'attestation peut utiliser un algorithme différent de celui de la clé attestée.
Le certificat d'attestation contient les champs du tableau ci-dessous et ne peut contenir aucun champ supplémentaire. Certains champs spécifient une valeur de champ fixe. Les tests CTS valident que le contenu du certificat est exactement tel que défini.
Certificat SÉQUENCE
Nom du champ (voir RFC 5280 ) | Valeur |
---|---|
tbsCertificat | SÉQUENCE du certificat TBS |
Algorithme de signature | AlgorithmIdentifier de l'algorithme utilisé pour signer la clé : ECDSA pour les clés EC, RSA pour les clés RSA. |
valeur de signature | CHAÎNE BINAIRE, signature calculée sur le certificat tbs encodé ASN.1 DER. |
SÉQUENCE du certificat TBS
Nom du champ (voir RFC 5280 ) | Valeur |
---|---|
version | INTEGER 2 (signifie certificat v3) |
serialNumber | INTEGER 1 (valeur fixe : identique pour tous les certificats) |
signature | AlgorithmIdentifiant de l'algorithme utilisé pour signer la clé : ECDSA pour les clés EC, RSA pour les clés RSA. |
issuer | Identique au champ d'objet de la clé d'attestation de lot. |
validity | SEQUENCE de deux dates, contenant les valeurs de Tag::ACTIVE_DATETIME et Tag::USAGE_EXPIRE_DATETIME . Ces valeurs sont en millisecondes depuis le 1er janvier 1970. Voir RFC 5280 pour les représentations de date correctes dans les certificats. Si Tag::ACTIVE_DATETIME n'est pas présent, utilisez la valeur de Tag::CREATION_DATETIME . Si Tag::USAGE_EXPIRE_DATETIME n'est pas présent, utilisez la date d'expiration du certificat de clé d'attestation de lot. |
subject | CN = "Android Keystore Key" (valeur fixe : identique sur tous les certificats) |
subjectPublicKeyInfo | SubjectPublicKeyInfo contenant la clé publique attestée. |
extensions/Key Usage | digitalSignature : défini si la clé a un but KeyPurpose::SIGN ou KeyPurpose::VERIFY . Tous les autres bits ne sont pas définis. |
extensions/CRL Distribution Points | Valeur à déterminer |
extensions/"attestation" | L'OID est 1.3.6.1.4.1.11129.2.1.17 ; le contenu est défini dans la section Extension d'attestation ci-dessous. Comme pour toutes les extensions de certificat X.509, le contenu est représenté sous la forme d'un OCTET_STRING contenant un codage DER de l'attestation SEQUENCE. |
Extension d'attestation
L'extension attestation
contient une description complète des autorisations de keymaster associées à la clé, dans une structure qui correspond directement aux listes d'autorisation utilisées dans Android et le keymaster HAL. Chaque étiquette dans une liste d'autorisation est représentée par une entrée SEQUENCE
ASN.1, explicitement étiquetée avec le numéro d'étiquette du maître de clé, mais avec le descripteur de type (quatre bits de poids fort) masqué.
Par exemple, dans Keymaster 3, Tag::PURPOSE
est défini dans types.hal comme ENUM_REP | 1
. Pour l'extension d'attestation, la valeur ENUM_REP
est supprimée, laissant la balise 1
. (Pour Keymaster 2 et inférieur, KM_TAG_PURPOSE
est défini dans keymaster_defs.h.)
Les valeurs sont traduites de manière simple en types ASN.1, selon ce tableau :
Type de maître de clé | Type ASN.1 |
---|---|
ENUM | ENTIER |
ENUM_REP | ENSEMBLE d'ENTIERS |
UINT | ENTIER |
UINT_REP | ENSEMBLE d'ENTIERS |
ULONG | ENTIER |
ULONG_REP | ENSEMBLE d'ENTIERS |
DATE | INTEGER (millisecondes depuis le 1er janvier 1970 00:00:00 GMT) |
BOOL | NULL (dans keymaster, tag présent signifie vrai, absent signifie faux. La même sémantique s'applique au codage ASN.1) |
BIGNUM | Non utilisé actuellement, donc aucun mappage n'est défini |
BYTES | OCTET_STRING |
Schéma
Le contenu de l'extension d'attestation est décrit par le schéma ASN.1 suivant.
KeyDescription ::= SEQUENCE { attestationVersion INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3. attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, teeEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), StrongBox (2), } AuthorizationList ::= SEQUENCE { purpose [1] EXPLICIT SET OF INTEGER OPTIONAL, algorithm [2] EXPLICIT INTEGER OPTIONAL, keySize [3] EXPLICIT INTEGER OPTIONAL. digest [5] EXPLICIT SET OF INTEGER OPTIONAL, padding [6] EXPLICIT SET OF INTEGER OPTIONAL, ecCurve [10] EXPLICIT INTEGER OPTIONAL, rsaPublicExponent [200] EXPLICIT INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, # KM4 activeDateTime [400] EXPLICIT INTEGER OPTIONAL originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL noAuthRequired [503] EXPLICIT NULL OPTIONAL, userAuthType [504] EXPLICIT INTEGER OPTIONAL, authTimeout [505] EXPLICIT INTEGER OPTIONAL, allowWhileOnBody [506] EXPLICIT NULL OPTIONAL, trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4 trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4 unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, # KM4 allApplications [600] EXPLICIT NULL OPTIONAL, applicationId [601] EXPLICIT OCTET_STRING OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only. rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3 attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3 vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, # KM4 bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, # KM4 } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, # KM4 } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
Champs KeyDescription
Les champs keymasterVersion
et attestationChallenge
sont identifiés par position, plutôt que par balise, de sorte que les balises dans le formulaire codé spécifient uniquement le type de champ. Les champs restants sont tagués implicitement comme spécifié dans le schéma.
Nom de domaine | Taper | Valeur |
---|---|---|
attestationVersion | ENTIER | Version du schéma d'attestation : 1, 2 ou 3. |
attestationSecurity | Niveau de sécurité | Le niveau de sécurité de cette attestation. Il est possible d'obtenir des attestations logicielles de clés matérielles. Ces attestations ne sont pas fiables si le système Android est compromis. |
keymasterVersion | ENTIER | Version de l'appareil keymaster : 0, 1, 2, 3 ou 4. |
keymasterSecurity | Niveau de sécurité | Le niveau de sécurité de l'implémentation du keymaster. |
attestationChallenge | OCTET_STRING | Valeur de Tag::ATTESTATION_CHALLENGE , spécifiée à la demande d'attestation. |
uniqueId | OCTET_STRING | ID unique facultatif, présent si la clé a Tag::INCLUDE_UNIQUE_ID |
softwareEnforced | Liste d'autorisation | Autorisations facultatives de keymaster qui ne sont pas appliquées par le TEE, le cas échéant. |
teeEnforced | Liste d'autorisation | Facultatif, autorisations Keymaster qui sont appliquées par le TEE, le cas échéant. |
Champs AuthorizationList
Les champs AuthorizationList
sont tous facultatifs et sont identifiés par la valeur de la balise keymaster, avec les bits de type masqués. Un balisage explicite est utilisé afin que les champs contiennent également une balise indiquant leur type ASN.1, pour une analyse plus facile.
Pour plus de détails sur les valeurs de chaque champ, voir types.hal
pour Keymaster 3 et keymaster_defs.h
pour Keymaster 2 et inférieur. Les noms de balises Keymaster ont été transformés en noms de champs en omettant le préfixe KM_TAG
et en changeant le reste en casse camel, donc Tag::KEY_SIZE
est devenu keySize
.
Champs RootOfTrust
Les champs RootOfTrust
sont identifiés par position.
Nom de domaine | Taper | Valeur |
---|---|---|
verifiedBootKey | OCTET_STRING | Hachage sécurisé de la clé utilisée pour vérifier l'image système. SHA-256 recommandé. |
deviceLocked | BOOLÉEN | Vrai si le chargeur de démarrage est verrouillé, ce qui signifie que seules les images signées peuvent être flashées et que la vérification du démarrage vérifiée est effectuée. |
verifiedBootState | État de démarrage vérifié | État du démarrage vérifié. |
verifiedBootHash | OCTET_STRING | Un résumé de toutes les données protégées par Verified Boot. Pour les appareils qui utilisent l'implémentation Android Verified Boot de Verified Boot, cette valeur contient le résumé de la structure VBMeta ou la structure de métadonnées Verified Boot. Pour en savoir plus sur le calcul de cette valeur, consultez The VBMeta Digest |
Valeurs VerifiedBootState
Les valeurs de verifiedBootState
ont les significations suivantes :
Valeur | Signification |
---|---|
Verified | Indique une chaîne de confiance complète s'étendant du chargeur de démarrage aux partitions vérifiées, y compris le chargeur de démarrage, la partition de démarrage et toutes les partitions vérifiées. Dans cet état, la verifiedBootKey est le hachage du certificat intégré, c'est-à-dire le certificat non modifiable gravé dans la ROM.Cet état correspond à l'état de démarrage vert , comme documenté dans la documentation du flux de démarrage vérifié . |
SelfSigned | Indique que la partition de démarrage a été vérifiée à l'aide du certificat intégré et que la signature est valide. Le chargeur de démarrage affiche un avertissement et l'empreinte digitale de la clé publique avant d'autoriser la poursuite du processus de démarrage. Dans cet état, la verifiedBootKey est le hachage du certificat auto-signé.Cet état correspond à l'état de démarrage jaune , comme documenté dans la documentation du flux de démarrage vérifié . |
Unverified | Indique qu'un appareil peut être librement modifié. L'intégrité de l'appareil est laissée à l'utilisateur pour vérifier hors bande. Le chargeur de démarrage affiche un avertissement à l'utilisateur avant d'autoriser la poursuite du processus de démarrage. Dans cet état, la valeur verifiedBootKey est vide.Cet état correspond à l'état de démarrage orange , comme documenté dans la documentation du flux de démarrage vérifié . |
Failed | Indique que l'appareil a échoué à la vérification. Aucun certificat d'attestation ne contient réellement cette valeur, car dans cet état, le chargeur de démarrage s'arrête. Il est inclus ici pour être complet. Cet état correspond à l'état de démarrage rouge , comme documenté dans la documentation du flux de démarrage vérifié . |
Valeurs SecurityLevel
Les valeurs de securityLevel
ont les significations suivantes :
Valeur | Signification |
---|---|
Software | Le code qui crée ou gère l'élément pertinent (attestation ou clé) est implémenté dans le système Android et peut être modifié si ce système est compromis. |
TrustedEnvironment | Le code qui crée ou gère l'élément concerné (attestation ou clé) est implémenté dans un environnement d'exécution sécurisé (TEE). Il pourrait être modifié si le TEE est compromis, mais le TEE est très résistant à la compromission à distance et modérément résistant à la compromission par une attaque matérielle directe. |
StrongBox | Le code qui crée ou gère l'élément concerné (attestation ou clé) est implémenté dans un module matériel de sécurité dédié. It could be altered if the hardware security module is compromised, but it is highly resistant to remote compromise and highly resistant to compromise by direct hardware attack. |
Unique ID
The Unique ID is a 128-bit value that identifies the device, but only for a limited period of time. The value is computed with:
HMAC_SHA256(T || C || R, HBK)
Where:
-
T
is the "temporal counter value", computed by dividing the value ofTag::CREATION_DATETIME
by 2592000000, dropping any remainder.T
changes every 30 days (2592000000 = 30 * 24 * 60 * 60 * 1000). -
C
is the value ofTag::APPLICATION_ID
-
R
is 1 ifTag::RESET_SINCE_ID_ROTATION
is present in the attest_params parameter to the attest_key call, or 0 if the tag is not present. -
HBK
is a unique hardware-bound secret known to the Trusted Execution Environment and never revealed by it. The secret contains at least 128 bits of entropy and is unique to the individual device (probabilistic uniqueness is acceptable given the 128 bits of entropy). HBK should be derived from fused key material via HMAC or AES_CMAC.
Truncate the HMAC_SHA256 output to 128 bits.
Attestation keys and certificates
Two keys, one RSA and one ECDSA, and the corresponding certificate chains, are securely provisioned into the device.
Android 12 introduces Remote Key Provisioning, and Android 13 requires devices implement it. Remote Key Provisioning provides devices in the field with per-application, ECDSA P256 attestation certificates. These certificates are shorter-lived than the factory-provisioned certificates.
ID attestation
Android 8.0 includes optional support for ID attestation for devices with Keymaster 3. ID attestation allows the device to provide proof of its hardware identifiers, such as serial number or IMEI. Although an optional feature, it is highly recommended that all Keymaster 3 implementations provide support for it because being able to prove the device's identity enables use cases such as true zero-touch remote configuration to be more secure (because the remote side can be certain it is talking to the right device, not a device spoofing its identity).
ID attestation works by creating copies of the device's hardware identifiers that only the Trusted Execution Environment (TEE) can access before the device leaves the factory. A user may unlock the device's bootloader and change the system software and the identifiers reported by the Android frameworks. The copies of the identifiers held by the TEE cannot be manipulated in this way, ensuring that device ID attestation will only ever attest to the device's original hardware identifiers thereby thwarting spoofing attempts.
The main API surface for ID attestation builds on top of the existing key attestation mechanism introduced with Keymaster 2. When requesting an attestation certificate for a key held by keymaster, the caller may request that the device's hardware identifiers be included in the attestation certificate's metadata. If the key is held in the TEE, the certificate will chain back to a known root of trust. The recipient of such a certificate can verify that the certificate and its contents, including the hardware identifiers, were written by the TEE. When asked to include hardware identifiers in the attestation certificate, the TEE attests only to the identifiers held in its storage, as populated on the factory floor.
Storage properties
The storage that holds the device's identifiers needs to have these properties:
- The values derived from the device's original identifiers are copied to the storage before the device leaves the factory.
- The
destroyAttestationIds()
method can permanently destroy this copy of the identifier-derived data. Permanent destruction means the data is completely removed so neither a factory reset nor any other procedure performed on the device can restore it. This is especially important for devices where a user has unlocked the bootloader and changed the system software and modified the identifiers returned by Android frameworks. - RMA facilities should have the ability to generate fresh copies of the hardware identifier-derived data. This way, a device that passes through RMA can perform ID attestation again. The mechanism used by RMA facilities must be protected so that users cannot invoke it themselves, as that would allow them to obtain attestations of spoofed IDs.
- No code other than Keymaster trusted app in the TEE is able to read the identifier-derived data kept in the storage.
- The storage is tamper-evident: If the content of the storage has been modified, the TEE treats it the same as if the copies of the content had been destroyed and refuses all ID attestation attempts. This is implemented by signing or MACing the storage as described below .
- The storage does not hold the original identifiers. Because ID attestation involves a challenge, the caller always supplies the identifiers to be attested. The TEE only needs to verify that these match the values they originally had. Storing secure hashes of the original values rather than the values enables this verification.
Construction
To create an implementation that has the properties listed above, store the ID-derived values in the following construction S. Do not store other copies of the ID values, excepting the normal places in the system, which a device owner may modify by rooting:
S = D || HMAC(HBK, D)
where:
-
D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
-
HMAC
is the HMAC construction with an appropriate secure hash (SHA-256 recommended) -
HBK
is a hardware-bound key not used for any other purpose -
ID 1 ...ID n
are the original ID values; association of a particular value to a particular index is implementation-dependent, as different devices will have different numbers of identifiers -
||
represents concatenation
Because the HMAC outputs are fixed size, no headers or other structure are required to be able to find individual ID hashes, or the HMAC of D. In addition to checking provided values to perform attestation, implementations need to validate S by extracting D from S, computing HMAC(HBK, D) and comparing it to the value in S to verify that no individual IDs were modified/corrupted. Also, implementations must use constant-time comparisons for all individual ID elements and the validation of S. Comparison time must be constant regardless of the number of IDs provided and the correct matching of any part of the test.
Hardware identifiers
ID attestation supports the following hardware identifiers:
- Brand name, as returned by
Build.BRAND
in Android - Device name, as returned by
Build.DEVICE
in Android - Product name, as returned by
Build.PRODUCT
in Android - Manufacturer name, as returned by
Build.MANUFACTURER
in Android - Model name, as returned by
Build.MODEL
in Android - Serial number
- IMEIs of all radios
- MEIDs of all radios
To support device ID attestation, a device attests to these identifiers. All devices running Android have the first six and they are necessary for this feature to work. If the device has any integrated cellular radios, the device must also support attestation for the IMEIs and/or MEIDs of the radios.
ID attestation is requested by performing a key attestation and including the device identifiers to attest in the request. The identifiers are tagged as:
-
ATTESTATION_ID_BRAND
-
ATTESTATION_ID_DEVICE
-
ATTESTATION_ID_PRODUCT
-
ATTESTATION_ID_MANUFACTURER
-
ATTESTATION_ID_MODEL
-
ATTESTATION_ID_SERIAL
-
ATTESTATION_ID_IMEI
-
ATTESTATION_ID_MEID
The identifier to attest is a UTF-8 encoded byte string. This format applies to numerical identifiers, as well. Each identifier to attest is expressed as a UTF-8 encoded string.
If the device does not support ID attestation (or destroyAttestationIds()
was previously called and the device can no longer attest its IDs), any key attestation request that includes one or more of these tags fails with ErrorCode::CANNOT_ATTEST_IDS
.
If the device supports ID attestation and one or more of the above tags have been included in a key attestation request, the TEE verifies the identifier supplied with each of the tags matches its copy of the hardware identifiers. If one or more identifiers do not match, the entire attestation fails with ErrorCode::CANNOT_ATTEST_IDS
. It is valid for the same tag to be supplied multiple times. This can be useful, for example, when attesting IMEIs: A device may have multiple radios with multiple IMEIs. An attestation request is valid if the value supplied with each ATTESTATION_ID_IMEI
matches one of the device's radios. The same applies to all other tags.
If attestation is successful, the attested IDs is added to the attestation extension (OID 1.3.6.1.4.1.11129.2.1.17) of the issued attestation certificate, using the schema from above . Changes from the Keymaster 2 attestation schema are bolded , with comments.
Java API
This section is informational only. Keymaster implementers neither implement nor use the Java API. This is provided to help implementers understand how the feature is used by applications. System components may use it differently, which is why it's crucial this section not be treated as normative.