Certificación de clave e identificación

Keystore proporciona un lugar más seguro para crear, almacenar y usar claves criptográficas de forma controlada. Cuando el almacenamiento de claves respaldado por hardware está disponible y se utiliza, el material de claves es más seguro contra la extracción del dispositivo, y Keymaster impone restricciones que son difíciles de subvertir.

Sin embargo, esto solo es cierto si se sabe que las claves del almacén de claves están en un almacenamiento respaldado por hardware. En Keymaster 1, no había forma de que las aplicaciones o los servidores remotos verificaran de manera confiable si este era el caso. El demonio del almacén de claves cargó el HAL maestro de claves disponible y creyó todo lo que dijo el HAL con respecto al respaldo de hardware de las claves.

Para remediar esto, Keymaster introdujola atestación de clave en Android 7.0 (Keymaster 2) y la atestación de ID en Android 8.0 (Keymaster 3).

La atestación de clave tiene como objetivo proporcionar una forma de determinar con certeza si un par de claves asimétricas está respaldado por hardware, cuáles son las propiedades de la clave y qué restricciones se aplican a su uso.

La atestación de ID permite que el dispositivo brinde prueba de sus identificadores de hardware, como el número de serie o el IMEI.

Atestación clave

Para admitir la atestación de claves, Android 7.1 introdujo un conjunto de etiquetas, tipos y métodos en la HAL.

Etiquetas

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

Escribe

Keymaster 2 y por debajo

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

Método AttestKey

Maestro de llaves 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

Keymaster 2 y por debajo

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 es la estructura del dispositivo keymaster.
  • keyToAttest es el blob de claves devuelto por generateKey para el que se creará la atestación.
  • attestParams es una lista de los parámetros necesarios para la atestación. Esto incluye Tag::ATTESTATION_CHALLENGE y posiblemente Tag::RESET_SINCE_ID_ROTATION , así como Tag::APPLICATION_ID y Tag::APPLICATION_DATA . Los dos últimos son necesarios para descifrar el blob de claves si se especificaron durante la generación de claves.
  • certChain es el parámetro de salida, que devuelve una matriz de certificados. La entrada 0 es el certificado de atestación, lo que significa que certifica la clave de keyToAttest y contiene la extensión de atestación.

El método attestKey se considera una operación de clave pública en la clave certificada, porque se puede llamar en cualquier momento y no necesita cumplir con las restricciones de autorización. Por ejemplo, si la clave certificada necesita autenticación de usuario para su uso, se puede generar una certificación sin autenticación de usuario.

certificado de atestación

El certificado de atestación es un certificado X.509 estándar, con una extensión de atestación opcional que contiene una descripción de la clave atestada. El certificado se firma con una clave de atestación proporcionada de fábrica que utiliza el mismo algoritmo que la clave que se atestigua (RSA para RSA, EC para EC).

El certificado de atestación contiene los campos de la siguiente tabla y no puede contener campos adicionales. Algunos campos especifican un valor de campo fijo. Las pruebas CTS validan que el contenido del certificado es exactamente como se define.

Certificado SECUENCIA

Nombre de campo (ver RFC 5280 ) Valor
certificado tbs TBSCertificado SECUENCIA
algoritmo de firma AlgorithmIdentifier del algoritmo utilizado para firmar la clave:
ECDSA para claves EC, RSA para claves RSA.
valor de la firma CADENA DE BITS, firma calculada en tbsCertificate con codificación DER ASN.1.

TBSCertificado SECUENCIA

Nombre de campo (ver RFC 5280 ) Valor
version ENTERO 2 (significa certificado v3)
serialNumber INTEGER 1 (valor fijo: igual en todos los certificados)
signature AlgorithmIdentifier del algoritmo utilizado para firmar la clave: ECDSA para claves EC, RSA para claves RSA.
issuer Igual que el campo de asunto de la clave de atestación de lote.
validity SEQUENCE de dos fechas, que contienen los valores de Tag::ACTIVE_DATETIME y Tag::USAGE_EXPIRE_DATETIME . Esos valores están en milisegundos desde el 1 de enero de 1970. Consulte RFC 5280 para conocer las representaciones de fecha correctas en los certificados.
Si Tag::ACTIVE_DATETIME no está presente, use el valor de Tag::CREATION_DATETIME . Si Tag::USAGE_EXPIRE_DATETIME no está presente, use la fecha de vencimiento del certificado de clave de atestación por lotes.
subject CN = "Clave del almacén de claves de Android" (valor fijo: igual en todos los certificados)
subjectPublicKeyInfo SubjectPublicKeyInfo que contiene la clave pública certificada.
extensions/Key Usage firma digital: establecer si la clave tiene un propósito KeyPurpose::SIGN o KeyPurpose::VERIFY . Todos los demás bits desactivados.
extensions/CRL Distribution Points Valor por determinar
extensions/"attestation" El OID es 1.3.6.1.4.1.11129.2.1.17; el contenido se define en la sección Extensión de atestación a continuación. Al igual que con todas las extensiones de certificado X.509, el contenido se representa como OCTET_STRING que contiene una codificación DER de la SECUENCIA de atestación.

Extensión de atestación

La extensión de attestation contiene una descripción completa de las autorizaciones del maestro de claves asociadas con la clave, en una estructura que se corresponde directamente con las listas de autorizaciones que se usan en Android y el HAL del maestro de claves. Cada etiqueta en una lista de autorizaciones está representada por una entrada de SEQUENCE ASN.1, etiquetada explícitamente con el número de etiqueta del maestro de claves, pero con el descriptor de tipo (cuatro bits de orden superior) oculto.

Por ejemplo, en Keymaster 3, Tag::PURPOSE PROPOSE se define en types.hal como ENUM_REP | 1 . Para la extensión de atestación, se elimina el valor ENUM_REP , dejando la etiqueta 1 . (Para Keymaster 2 y anteriores, KM_TAG_PURPOSE se define en keymaster_defs.h.)

Los valores se traducen de forma sencilla a tipos ASN.1, según esta tabla:

Tipo de maestro de llaves tipo ASN.1
ENUM ENTERO
ENUM_REP CONJUNTO de ENTERO
UINT ENTERO
UINT_REP CONJUNTO de ENTERO
ULONG ENTERO
ULONG_REP CONJUNTO de ENTERO
DATE ENTERO (milisegundos desde el 1 de enero de 1970 00:00:00 GMT)
BOOL NULL (en keymaster, la etiqueta presente significa verdadero, ausente significa falso.
La misma semántica se aplica a la codificación ASN.1)
BIGNUM Actualmente no se utiliza, por lo que no se define ninguna asignación
BYTES OCTET_STRING

Esquema

El contenido de la extensión de atestación se describe mediante el siguiente esquema ASN.1.

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),
}

Campos de descripción clave

Los campos keymasterVersion y attestationChallenge se identifican por posición, en lugar de por etiqueta, por lo que las etiquetas en el formulario codificado solo especifican el tipo de campo. Los campos restantes se etiquetan implícitamente como se especifica en el esquema.

Nombre del campo Escribe Valor
attestationVersion ENTERO Versión del esquema de atestación: 1, 2 o 3.
attestationSecurity Nivel de seguridad El nivel de seguridad de esta atestación. Es posible obtener certificaciones de software de claves respaldadas por hardware. No se puede confiar en dichas certificaciones si el sistema Android está comprometido.
keymasterVersion ENTERO Versión del dispositivo keymaster: 0, 1, 2, 3 o 4.
keymasterSecurity Nivel de seguridad El nivel de seguridad de la implementación del maestro de claves.
attestationChallenge OCTET_STRING Valor de Tag::ATTESTATION_CHALLENGE , especificado para la solicitud de atestación.
uniqueId OCTET_STRING ID único opcional, presente si la clave tiene Tag::INCLUDE_UNIQUE_ID
softwareEnforced Lista de autorizaciones Autorizaciones de keymaster opcionales que no son aplicadas por el TEE, si las hay.
teeEnforced Lista de autorizaciones Opcional, autorizaciones Keymaster que son aplicadas por el TEE, si las hubiere.

Campos de la lista de autorizaciones

Los campos AuthorizationList son todos opcionales y se identifican por el valor de la etiqueta keymaster, con los bits de tipo enmascarados. Se utiliza el etiquetado explícito para que los campos también contengan una etiqueta que indique su tipo ASN.1, para facilitar el análisis.

Para obtener detalles sobre los valores de cada campo, consulte types.hal para Keymaster 3 y keymaster_defs.h para Keymaster 2 e inferiores. Los nombres de las etiquetas Keymaster se transformaron en nombres de campo al omitir el prefijo KM_TAG y cambiar el resto a mayúsculas y minúsculas, por lo que Tag::KEY_SIZE se convirtió en keySize .

Campos de RootOfTrust

Los campos RootOfTrust se identifican posicionalmente.

Nombre del campo Escribe Valor
verifiedBootKey OCTET_STRING Un hash seguro de la clave utilizada para verificar la imagen del sistema. Se recomienda SHA-256.
deviceLocked BOOLEANO Verdadero si el gestor de arranque está bloqueado, lo que significa que solo se pueden flashear imágenes firmadas y que se realiza una verificación de arranque verificada.
verifiedBootState Estado de arranque verificado Estado de arranque verificado.
verifiedBootHash OCTET_STRING Un resumen de todos los datos protegidos por Verified Boot. Para los dispositivos que utilizan la implementación de Android Verified Boot de Verified Boot, este valor contiene el resumen de la estructura VBMeta o la estructura de metadatos de Verified Boot. Para obtener más información sobre cómo calcular este valor, consulte The VBMeta Digest

Valores de estado de arranque verificados

Los valores verifiedBootState tienen los siguientes significados:

Valor Sentido
Verified Indica una cadena de confianza completa que se extiende desde el cargador de arranque hasta las particiones verificadas, incluido el cargador de arranque, la partición de arranque y todas las particiones verificadas.
En este estado, el valor verifiedBootKey es el hash del certificado incrustado, lo que significa que el certificado inalterable se graba en la ROM.
SelfSigned Indica que la partición de arranque se ha verificado mediante el certificado incrustado y la firma es válida. El gestor de arranque muestra una advertencia y la huella digital de la clave pública antes de permitir que continúe el proceso de arranque.
En este estado, el valor verifiedBootKey es el hash del certificado autofirmado.
Unverified Indica que un dispositivo se puede modificar libremente. La integridad del dispositivo se deja al usuario para verificar fuera de banda. El gestor de arranque muestra una advertencia al usuario antes de permitir que continúe el proceso de arranque.
En este estado, el valor verifiedBootKey está vacío.
Failed Indica que el dispositivo no ha superado la verificación. Ningún certificado de atestación contiene realmente este valor, porque en este estado se detiene el gestor de arranque. Se incluye aquí para completar.

Valores de nivel de seguridad

Los valores de securityLevel tienen los siguientes significados:

Valor Sentido
Software El código que crea o administra el elemento relevante (certificación o clave) se implementa en el sistema Android y podría modificarse si ese sistema se ve comprometido.
TrustedEnvironment El código que crea o gestiona el elemento relevante (atestación o clave) se implementa en un Trusted Execution Environment (TEE). Podría modificarse si el TEE se ve comprometido, pero el TEE es muy resistente al compromiso remoto y moderadamente resistente al compromiso por un ataque de hardware directo.
StrongBox El código que crea o administra el elemento relevante (certificación o clave) se implementa en un módulo de seguridad de hardware dedicado. Podría modificarse si el módulo de seguridad del hardware se ve comprometido, pero es altamente resistente al compromiso remoto y altamente resistente al compromiso por un ataque directo al hardware.

Identificación única

La ID única es un valor de 128 bits que identifica el dispositivo, pero solo por un período de tiempo limitado. El valor se calcula con:

HMAC_SHA256(T || C || R, HBK)

Donde:

  • T es el "valor del contador temporal", calculado dividiendo el valor de Tag::CREATION_DATETIME por 2592000000, descartando cualquier resto. T cambia cada 30 días (2592000000 = 30 * 24 * 60 * 60 * 1000).
  • C es el valor de Tag::APPLICATION_ID
  • R es 1 si Tag::RESET_SINCE_ID_ROTATION está presente en el parámetro attest_params de la llamada attest_key, o 0 si la etiqueta no está presente.
  • HBK es un secreto exclusivo vinculado al hardware conocido por el entorno de ejecución de confianza y nunca revelado por este. El secreto contiene al menos 128 bits de entropía y es único para el dispositivo individual (la unicidad probabilística es aceptable dados los 128 bits de entropía). HBK debe derivarse del material de clave fusionado a través de HMAC o AES_CMAC.

Trunca la salida HMAC_SHA256 a 128 bits.

Certificados y claves de atestación

Dos claves, una RSA y una ECDSA, y las cadenas de certificados correspondientes, se aprovisionan de forma segura en el dispositivo.

atestación de identidad

Android 8.0 incluye soporte opcional para la atestación de ID para dispositivos con Keymaster 3. La atestación de ID permite que el dispositivo proporcione pruebas de sus identificadores de hardware, como el número de serie o el IMEI. Aunque es una función opcional, se recomienda encarecidamente que todas las implementaciones de Keymaster 3 la admitan, ya que la capacidad de probar la identidad del dispositivo permite que casos de uso, como la configuración remota real sin contacto, sean más seguros (porque el lado remoto puede estar seguro de que está hablando con el dispositivo correcto, no con un dispositivo falsificando su identidad).

La atestación de ID funciona mediante la creación de copias de los identificadores de hardware del dispositivo a las que solo puede acceder el entorno de ejecución de confianza (TEE) antes de que el dispositivo salga de fábrica. Un usuario puede desbloquear el gestor de arranque del dispositivo y cambiar el software del sistema y los identificadores informados por los marcos de trabajo de Android. Las copias de los identificadores en poder del TEE no se pueden manipular de esta manera, lo que garantiza que la atestación de ID del dispositivo solo certifique los identificadores de hardware originales del dispositivo, lo que frustrará los intentos de suplantación de identidad.

La superficie API principal para la atestación de ID se basa en el mecanismo de atestación de clave existente introducido con Keymaster 2. Al solicitar un certificado de atestación para una clave en poder de keymaster, la persona que llama puede solicitar que los identificadores de hardware del dispositivo se incluyan en los metadatos del certificado de atestación. Si la clave se encuentra en el TEE, el certificado se encadenará a una raíz de confianza conocida. El destinatario de dicho certificado puede verificar que el certificado y su contenido, incluidos los identificadores de hardware, fueron escritos por el TEE. Cuando se le pide que incluya identificadores de hardware en el certificado de atestación, el TEE da fe solo de los identificadores guardados en su almacenamiento, tal como se encuentran en la planta de producción.

Propiedades de almacenamiento

El almacenamiento que contiene los identificadores del dispositivo debe tener estas propiedades:

  • Los valores derivados de los identificadores originales del dispositivo se copian en el almacenamiento antes de que el dispositivo salga de fábrica.
  • El método destroyAttestationIds() puede destruir permanentemente esta copia de los datos derivados del identificador. La destrucción permanente significa que los datos se eliminan por completo, por lo que ni un restablecimiento de fábrica ni ningún otro procedimiento realizado en el dispositivo pueden restaurarlos. Esto es especialmente importante para los dispositivos en los que un usuario ha desbloqueado el cargador de arranque, ha cambiado el software del sistema y ha modificado los identificadores devueltos por los marcos de trabajo de Android.
  • Las instalaciones de RMA deben tener la capacidad de generar copias nuevas de los datos derivados del identificador de hardware. De esta forma, un dispositivo que pasa por RMA puede volver a realizar la atestación de ID. El mecanismo utilizado por las instalaciones de RMA debe protegerse para que los usuarios no puedan invocarlo por sí mismos, ya que eso les permitiría obtener certificaciones de identificaciones falsificadas.
  • Ningún código que no sea la aplicación de confianza Keymaster en el TEE puede leer los datos derivados del identificador guardados en el almacenamiento.
  • El almacenamiento es a prueba de manipulaciones: si el contenido del almacenamiento ha sido modificado, el TEE lo trata como si las copias del contenido hubieran sido destruidas y rechaza todos los intentos de atestación de identidad. Esto se implementa firmando o MACing el almacenamiento como se describe a continuación .
  • El almacenamiento no conserva los identificadores originales. Debido a que la atestación de ID implica un desafío, la persona que llama siempre proporciona los identificadores para ser atestiguados. El TEE solo necesita verificar que estos coincidan con los valores que tenían originalmente. Almacenar hashes seguros de los valores originales en lugar de los valores permite esta verificación.

Construcción

Para crear una implementación que tenga las propiedades enumeradas anteriormente, almacene los valores derivados de ID en la siguiente construcción S. No almacene otras copias de los valores de ID, excepto los lugares normales en el sistema, que el propietario de un dispositivo puede modificar mediante el enrutamiento:

S = D || HMAC(HBK, D)

donde:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC es la construcción HMAC con un hash seguro apropiado (se recomienda SHA-256)
  • HBK es una clave vinculada al hardware que no se utiliza para ningún otro propósito
  • ID 1 ...ID n son los valores de ID originales; la asociación de un valor particular a un índice particular depende de la implementación, ya que diferentes dispositivos tendrán diferentes números de identificadores
  • || representa la concatenación

Debido a que las salidas de HMAC tienen un tamaño fijo, no se requieren encabezados u otra estructura para poder encontrar hashes de ID individuales o el HMAC de D. Además de verificar los valores proporcionados para realizar la atestación, las implementaciones deben validar S extrayendo D de S , calculando HMAC(HBK, D) y comparándolo con el valor en S para verificar que no se modificaron ni corrompieron ID individuales. Además, las implementaciones deben usar comparaciones en tiempo constante para todos los elementos de identificación individuales y la validación de S. El tiempo de comparación debe ser constante independientemente de la cantidad de identificaciones proporcionadas y la coincidencia correcta de cualquier parte de la prueba.

Identificadores de hardware

La atestación de ID admite los siguientes identificadores de hardware:

  1. Nombre de la marca, tal como lo devuelve Build.BRAND en Android
  2. Nombre del dispositivo, tal como lo devuelve Build.DEVICE en Android
  3. Nombre del producto, tal como lo devuelve Build.PRODUCT en Android
  4. Nombre del fabricante, tal como lo devuelve Build.MANUFACTURER en Android
  5. Nombre del modelo, tal como lo devuelve Build.MODEL en Android
  6. Número de serie
  7. IMEIs de todas las radios
  8. MEID de todas las radios

Para admitir la certificación de ID de dispositivo, un dispositivo certifica estos identificadores. Todos los dispositivos que ejecutan Android tienen los primeros seis y son necesarios para que esta función funcione. Si el dispositivo tiene radios celulares integradas, el dispositivo también debe admitir la certificación de los IMEI y/o MEID de las radios.

La atestación de ID se solicita realizando una atestación de clave e incluyendo los identificadores de dispositivos para atestiguar en la solicitud. Los identificadores están etiquetados como:

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

El identificador para certificar es una cadena de bytes codificada en UTF-8. Este formato también se aplica a los identificadores numéricos. Cada identificador para certificar se expresa como una cadena codificada en UTF-8.

Si el dispositivo no admite la atestación de ID (o se llamó previamente a destroyAttestationIds() y el dispositivo ya no puede atestar sus ID), cualquier solicitud de atestación de clave que incluya una o más de estas etiquetas falla con ErrorCode::CANNOT_ATTEST_IDS .

Si el dispositivo admite la atestación de ID y una o más de las etiquetas anteriores se incluyeron en una solicitud de atestación de clave, el TEE verifica que el identificador proporcionado con cada una de las etiquetas coincida con su copia de los identificadores de hardware. Si uno o más identificadores no coinciden, la atestación completa falla con ErrorCode::CANNOT_ATTEST_IDS . Es válido que la misma etiqueta se proporcione varias veces. Esto puede ser útil, por ejemplo, al certificar IMEI: un dispositivo puede tener múltiples radios con múltiples IMEI. Una solicitud de atestación es válida si el valor proporcionado con cada ATTESTATION_ID_IMEI coincide con una de las radios del dispositivo. Lo mismo se aplica a todas las demás etiquetas.

Si la atestación es exitosa, los ID atestiguados se agregan a la extensión de atestación (OID 1.3.6.1.4.1.11129.2.1.17) del certificado de atestación emitido, utilizando el esquema anterior . Los cambios del esquema de atestación de Keymaster 2 están en negrita , con comentarios.

API de Java

Esta sección es solo informativa. Los implementadores de Keymaster no implementan ni usan la API de Java. Esto se proporciona para ayudar a los implementadores a comprender cómo las aplicaciones utilizan la característica. Los componentes del sistema pueden usarlo de manera diferente, por lo que es crucial que esta sección no se trate como normativa.