Atestado de chave e ID

O Keystore oferece um local mais seguro para criar, armazenar e usar as chaves de forma controlada. Quando o armazenamento de chaves protegido por hardware estiver disponível e usada, o material da chave tem mais segurança contra a extração do dispositivo. O Keymaster aplica restrições que são difíceis de subverter.

Isso só é verdade, no entanto, se as chaves do keystore forem conhecidas por estar em hardware. No Keymaster 1, não havia como apps ou servidores remotos para verificar de forma confiável se esse foi o caso. O daemon do keystore carregou a HAL de keymaster disponível e acreditava no que a HAL disse com em relação ao suporte de hardware das chaves.

Para corrigir isso, o Keymaster introduziu o atestado de chaves no Android 7.0 (Keymaster 2) e o código atestado no Android 8.0 (Keymaster 3).

O atestado de chaves tem como objetivo oferecer uma maneira para determinar se um par de chaves assimétricas tem suporte de hardware, quais propriedades da chave e quais restrições são aplicadas ao uso dela.

O atestado de ID permite que o dispositivo comprove os identificadores de hardware, como o número de série ou o IMEI.

Atestado de chaves

Para oferecer suporte ao atestado de chaves, o Android 7.0 introduziu um conjunto de tags, tipos e para a HAL.

Tags

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

Tipo

Keymaster 2 e anteriores

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

Método AttestKey

Keymaster 3 (link em inglês)

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

Keymaster 2 e anteriores

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 é a estrutura do dispositivo keymaster.
  • keyToAttest é o blob de chave retornado do generateKey para o qual o atestado será criado.
  • attestParams é uma lista de todos os parâmetros necessários para atestado. Isso inclui Tag::ATTESTATION_CHALLENGE e possivelmente Tag::RESET_SINCE_ID_ROTATION, além de Tag::APPLICATION_ID e Tag::APPLICATION_DATA. A Os dois últimos são necessários para descriptografar o blob de chaves caso tenham sido especificados durante a geração de chaves.
  • certChain é o parâmetro de saída, que retorna uma matriz de certificados. A entrada 0 é o certificado de atestado, ou seja, certifica a chave de keyToAttest e contém Extensão de atestado.

O método attestKey é considerado uma operação de chave pública no a chave atestada, porque ela pode ser chamada a qualquer momento e não precisa atender restrições de autorização. Por exemplo, se a chave atestada precisar que o do usuário, um atestado pode ser gerado sem que o autenticação.

Certificado de atestado

O certificado de atestado é um certificado X.509 padrão, com um certificado opcional Extensão de atestado que contém uma descrição da chave atestada. A é assinado com uma chave de atestado certificada. A chave de atestado podem usar um algoritmo diferente da chave atestada.

O certificado de atestado contém os campos da tabela abaixo e não pode não podem conter campos adicionais. Alguns campos especificam um valor fixo. CTS os testes validam se o conteúdo do certificado é exatamente conforme definido.

SEQUÊNCIA do certificado

Nome do campo (consulte RFC 5280). Valor
tbsCertificate (em inglês) SEQUÊNCIA DO TBSCertificate
signatureAlgorithm (em inglês) AlgorithmIdentifier do algoritmo usado para assinar a chave:
ECDSA para chaves EC, RSA para chaves RSA.
signatureValue (em inglês) BIT STRING, assinatura calculada em tbsCertificate codificada por DER ASN.1.

SEQUÊNCIA DO Certificado TBSCertificate

Nome do campo (consulte RFC 5280). Valor
version NÚMERO INTEIRO 2 (significa certificado v3)
serialNumber INTEGER 1 (valor fixo: o mesmo em todos os certificados)
signature AlgorithmIdentifier do algoritmo usado para assinar a chave: ECDSA para chaves EC, RSA para chaves RSA.
issuer Igual ao campo de assunto da chave de atestado em lote.
validity SEQUÊNCIA de duas datas, contendo os valores de Tag::ACTIVE_DATETIME e Tag::USAGE_EXPIRE_DATETIME. Esses valores estão em milissegundos desde 1o de janeiro de 1970. Consulte o RFC 5280 para corrigir representações de data em certificados.
Se Tag::ACTIVE_DATETIME não estiver presente, use o valor de Tag::CREATION_DATETIME Se Tag::USAGE_EXPIRE_DATETIME não está presente, use a expiração data do certificado da chave de atestado em lote.
subject CN = "chave do Android Keystore" (valor fixo: o mesmo em todos os certificados)
subjectPublicKeyInfo SubjectPublicKeyInfo que contém a chave pública atestada.
extensions/Key Usage digitalSignature: defina se a chave tiver a finalidade KeyPurpose::SIGN ou KeyPurpose::VERIFY. Todos os outros bits não definidos.
extensions/CRL Distribution Points Valor a definir
extensions/"attestation" O OID é 1.3.6.1.4.1.11129.2.1.17; o conteúdo é definido seção "Extensão de atestado" abaixo. Assim como em todos os extensões de certificado X.509, o conteúdo é representado como uma OCTET_STRING que contém uma codificação DER da SEQUENCE do atestado.

Extensão de atestado

A extensão attestation contém uma descrição completa do keymaster. autorizações associadas à chave, em uma estrutura que corresponde diretamente às listas de autorização usadas no Android e na HAL de keymaster. Cada tag em uma lista de autorização é representada por um ASN.1 SEQUENCE entrada, explicitamente marcado com o número da tag keymaster, mas com o descritor do tipo (quatro mascarados.

Por exemplo, no Keymaster 3, Tag::PURPOSE é definido em type.hal como ENUM_REP | 1. Para a extensão de atestado, o valor ENUM_REP é removido, deixando a tag 1. Para o Keymaster 2 e versões anteriores, o KM_TAG_PURPOSE é definido em keymaster_defs.h.)

Os valores são convertidos de maneira direta para tipos ASN.1, de acordo com esta tabela:

Tipo do Keymaster Tipo ASN.1
ENUM INTEIRO
ENUM_REP SET de INTEGER
UINT INTEIRO
UINT_REP SET de INTEGER
ULONG INTEIRO
ULONG_REP SET de INTEGER
DATE INTEGER (milissegundos desde 1o de janeiro de 1970 00:00:00 GMT)
BOOL NULL (no keymaster, a tag presente significa verdadeira, ausente significa falsa).
A mesma semântica se aplica à codificação ASN.1)
BIGNUM Não usado no momento, por isso nenhum mapeamento está definido
BYTES OCTET_STRING

Esquema

O conteúdo da extensão de atestado é descrito pelo esquema ASN.1 a seguir.

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,
  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 KeyDescription

keymasterVersion e attestationChallenge os campos são identificados de maneira posicional, e não por tag. Assim, as tags na forma codificada especificam apenas Tipo de campo. Os campos restantes são implicitamente marcados conforme especificado no esquema.

Nome do campo Tipo Valor
attestationVersion INTEIRO Versão do esquema de atestado: 1, 2 ou 3.
attestationSecurity SecurityLevel O nível de segurança do atestado. É possível adquirir softwares atestados de chaves protegidas por hardware. Esses atestados não são confiáveis se o O sistema Android está comprometido.
keymasterVersion INTEIRO Versão do dispositivo keymaster: 0, 1, 2, 3 ou 4.
keymasterSecurity SecurityLevel O nível de segurança da implementação do keymaster.
attestationChallenge OCTET_STRING Valor de Tag::ATTESTATION_CHALLENGE, especificado para a solicitação de atestado.
uniqueId OCTET_STRING ID exclusivo opcional, presente se a chave tiver Tag::INCLUDE_UNIQUE_ID
softwareEnforced AuthorizationList Autorizações de keymaster opcionais que não são aplicadas pelo TEE, se nenhum.
teeEnforced AuthorizationList Opcional, autorizações do Keymaster que são aplicadas pelo TEE, se houver.

Campos AuthorizationList

Os campos AuthorizationList são todos opcionais e identificados pelo valor da tag keymaster, com os bits de tipo mascarados. A codificação explícita é usada para que os campos também contenham uma tag indicando o tipo ASN.1, para facilitar a análise.

Para ver detalhes sobre os valores de cada campo, consulte types.hal para Keymaster 3 e keymaster_defs.h para o Keymaster 2 e versões anteriores. Nomes de tags do Keymaster foram transformados em nomes de campo omitindo o KM_TAG e altere o restante para letras concatenadas, então Tag::KEY_SIZE tornou-se keySize

.

Campos RootOfTrust

Os campos RootOfTrust são identificados de forma posicional.

Nome do campo Tipo Valor
verifiedBootKey OCTET_STRING Um hash seguro da chave usado para verificar a imagem do sistema. SHA-256 recomendado.
deviceLocked BOOLEANO Verdadeiro se o carregador de inicialização estiver bloqueado, o que significa que apenas imagens assinadas podem atualizado e a verificação da Inicialização verificada estará concluída.
verifiedBootState VerifiedBootState Estado da inicialização verificada.
verifiedBootHash OCTET_STRING Um resumo de todos os dados protegidos pela Inicialização verificada. Para dispositivos que usam a implementação da Inicialização verificada do Android, esse valor contém o resumo do struct VBMeta ou da Inicialização verificada estrutura de metadados. Para saber mais sobre como calcular esse valor, consulte Resumo do VBMeta

Valores de VerifiedBootState

Os valores de verifiedBootState têm os seguintes significados:

Valor Significado
Verified Indica uma cadeia completa de confiança que se estende do carregador de inicialização até a verificação partições diferentes, como o carregador, a partição de inicialização e todas partições diferentes.
Nesse estado, o valor verifiedBootKey é o hash do código que é um certificado imutável gravado na ROM.
Esse estado corresponde ao estado de inicialização verde, conforme documentado na do fluxo de inicialização verificada.
SelfSigned Indica que a partição de inicialização foi verificada usando o e a assinatura é válida. O carregador de inicialização exibe um aviso a impressão digital da chave pública antes de permitir que o processo de inicialização continue.
Neste estado, o valor verifiedBootKey é o hash da assinatura certificado.
Esse estado corresponde ao estado de inicialização amarelo, conforme documentado no do fluxo de inicialização verificada.
Unverified Indica que um dispositivo pode ser modificado livremente. A integridade do dispositivo é deixada para o usuário fazer a verificação fora de banda. O carregador de inicialização exibe um aviso ao usuário. antes de permitir que o processo de inicialização continue.
Nesse estado, o valor verifiedBootKey está vazio.
Esse estado corresponde ao estado de inicialização laranja, conforme documentado na do fluxo de inicialização verificada.
Failed Indica que a verificação do dispositivo falhou. Nenhum certificado de atestado contém esse valor porque, nesse estado, o carregador de inicialização é interrompido. Está incluídos aqui para fins de integridade.
Esse estado corresponde ao estado de inicialização vermelho, conforme documentado na do fluxo de inicialização verificada.

Valores de SecurityLevel

Os valores de securityLevel têm os seguintes significados:

Valor Significado
Software O código que cria ou gerencia o elemento relevante (atestado ou chave) é implementado no sistema Android e poderá ser alterado se esse sistema for comprometido.
TrustedEnvironment O código que cria ou gerencia o elemento relevante (atestado ou chave) é implementado em um ambiente de execução confiável (TEE). Pode ser alterado se o TEE for comprometido, mas é altamente resistente ao e moderadamente resistentes a ataques diretos de hardware.
StrongBox O código que cria ou gerencia o elemento relevante (atestado ou é implementado em um módulo de segurança de hardware dedicado. Pode ser alterado se o módulo de segurança de hardware for comprometido, mas estará altamente resistente a comprometimentos remotos e altamente resistente a comprometimentos de um ataque de hardware.

ID exclusivo

O ID exclusivo é um valor de 128 bits que identifica o dispositivo, mas apenas para um por um período limitado. O valor é calculado com:

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

Em que:

  • T é o "valor do contador temporal", calculado dividindo-se o de Tag::CREATION_DATETIME em 2.592.000.000, caindo qualquer restantes. T muda a cada 30 dias (259.2000.000 = 30 * 24 * 60) * 60 * 1.000).
  • C é o valor de Tag::APPLICATION_ID.
  • R é 1 se Tag::RESET_SINCE_ID_ROTATION for presente no parâmetro attest_params para a chamada attest_key, ou 0 se o a tag não está presente.
  • HBK é um segredo exclusivo de hardware conhecido pelo ambiente de execução e nunca revelado por ele. O secret contém pelo menos 128 bits de entropia e é exclusivo do dispositivo individual (probabilístico a exclusividade é aceitável dados os 128 bits de entropia). O HBK deve ser derivados de material de chave fundido via HMAC ou AES_CMAC.

Truncar a saída HMAC_SHA256 para 128 bits.

Chaves de atestado e certificados

Duas chaves, uma RSA e uma ECDSA, e as cadeias de certificados correspondentes, são provisionada com segurança no dispositivo.

O Android 12 introduz o provisionamento de chaves remotas, e o Android 13 exige dispositivos implementá-los. Com o provisionamento de chaves remotas, os dispositivos em campo têm certificados de atestado ECDSA P256 por aplicativo. Esses certificados são mais curta do que os provisionados pela fábrica.

Vários IMEIs

O Android 14 adiciona suporte a vários IMEIs no Registro do atestado de chaves do Android. Os OEMs podem implementar esse recurso adicionando uma tag do KeyMint para um segundo IMEI. É cada vez mais comum que dispositivos tenham vários rádios celulares e OEMs agora aceitam dispositivos com dois IMEIs.

Os OEMs precisam ter um IMEI secundário, se houver nos dispositivos, para ser provisionadas à(s) implementação(ões) do KeyMint para que elas possam atestem isso da mesma maneira que declaram o primeiro IMEI

Atestado de ID

O Android 8.0 inclui suporte opcional para atestados de ID para dispositivos com Keymaster 3. O atestado de ID permite que o dispositivo comprove o hardware dele identificadores, como número de série ou IMEI. Embora seja um recurso opcional, é altamente recomendável que todas as implementações do Keymaster 3 ofereçam suporte a ele. porque a possibilidade de provar a identidade do dispositivo permite casos de uso como configuração remota sem toque para aumentar a segurança, já que o lado remoto pode ter certeza de que está se comunicando com o dispositivo certo, não fazendo spoofing de identidade).

O atestado de ID funciona criando cópias dos identificadores de hardware do dispositivo que apenas o ambiente de execução confiável (TEE) pode acessar antes que o dispositivo sai da fábrica. Um usuário pode desbloquear o carregador de inicialização do dispositivo e alterar a e os identificadores relatados pelos frameworks do Android. A cópias dos identificadores mantidos pelo TEE não podem ser manipuladas dessa forma, garantindo que a confirmação do ID do dispositivo só atesta a segurança identificadores de hardware originais, o que frustra as tentativas de spoofing.

A superfície da API principal para atestados de ID se baseia na chave atual mecanismo de atestado introduzido com o Keymaster 2. Ao solicitar uma certificado de atestado para uma chave mantida pelo keymaster, o autor da chamada poderá solicitar que os identificadores de hardware do dispositivo sejam incluídos no atestado. metadados do certificado. Se a chave for mantida no TEE, o certificado a uma raiz conhecida de confiança. O destinatário desse certificado pode confirmar que o certificado e seu conteúdo, incluindo o hardware e identificadores, foram escritos pelo TEE. Quando for solicitada a inclusão de hardware identificadores no certificado de atestado, o TEE atesta apenas às identificadores mantidos no armazenamento, conforme preenchidos na fábrica.

Propriedades de armazenamento

O armazenamento que contém os identificadores do dispositivo precisa ter estas propriedades:

  • Os valores derivados dos identificadores originais do dispositivo são copiados para o armazenamento antes que o dispositivo saia da fábrica.
  • O método destroyAttestationIds() pode destruir permanentemente cópia dos dados derivados do identificador. Destruição permanente significa que os dados são completamente removidos, de modo que a redefinição para a configuração original procedimento executado no dispositivo pode restaurá-lo. Isso é especialmente importante para dispositivos em que o usuário desbloqueou o carregador de inicialização e alterou o software do sistema e modificou os identificadores retornados pelo Android frameworks.
  • As instalações de ADM precisam gerar cópias novas dos dados derivados do identificador de hardware. Dessa forma, dispositivo que passar pela ADM poderá realizar o atestado de ID novamente. A mecanismo usado pelas instalações de ADM precisa ser protegido para que os usuários não possam invocá-lo por conta própria, porque isso lhes permitiria obter atestados de IDs falsificados.
  • Nenhum outro código além do app confiável do Keymaster no TEE consegue ler o derivados do identificador são mantidos no armazenamento.
  • O armazenamento é inviolável: se o conteúdo do armazenamento modificado, o TEE o trata da mesma forma que se as cópias do conteúdo tivessem foi destruída e recusa todas as tentativas de atestado de ID. Isso foi implementado assine ou use MACing no armazenamento conforme descrito abaixo.
  • O armazenamento não contém os identificadores originais. Como o atestado do ID envolve um desafio, o autor da chamada sempre fornece os identificadores atestadas. O TEE só precisa verificar se eles correspondem aos valores tinham originalmente. Armazenar hashes seguros dos valores originais, em vez dos ativa essa verificação.

Construção

Para criar uma implementação com as propriedades listadas acima, armazene o valores derivados de ID na construção S a seguir. Não armazene outras cópias de os valores de ID, exceto os locais normais no sistema, que o proprietário do dispositivo pode modificar com o acesso root:

S = D || HMAC(HBK, D)

em que:

  • D = HMAC(HBK, ID1) || HMAC(HBK, ID2) || ... || HMAC(HBK, IDn)
  • HMAC é a construção de HMAC com um hash seguro apropriado. (SHA-256 recomendado)
  • HBK é uma chave vinculada a hardware que não é usada para nenhuma outra finalidade
  • ID1...IDn são os valores originais do ID; associação de um determinado valor para um determinado índice depende da implementação, já que dispositivos diferentes terão números diferentes de identificadores
  • || representa a concatenação;

Como as saídas HMAC são de tamanho fixo, nenhum cabeçalho ou outra estrutura é necessário para encontrar hashes de ID individuais ou o HMAC de D. Além disso, à verificação dos valores fornecidos para realizar o atestado, as implementações precisam validar S extraindo D de S, computando HMAC(HBK, D) e comparando-o o valor em S para verificar se nenhum ID individual foi modificado/corrompido. Além disso, implementações precisam usar comparações de tempo constante para todos os IDs individuais e a validação de S. O tempo de comparação precisa ser constante, independentemente o número de IDs fornecidos e a correspondência correta de qualquer parte do teste.

Identificadores de hardware

O atestado de ID oferece suporte aos seguintes identificadores de hardware:

  1. Nome da marca, conforme retornado por Build.BRAND no Android
  2. Nome do dispositivo, conforme retornado por Build.DEVICE no Android.
  3. Nome do produto, conforme retornado por Build.PRODUCT no Android
  4. Nome do fabricante, conforme retornado por Build.MANUFACTURER no Android
  5. Nome do modelo, conforme retornado por Build.MODEL no Android.
  6. Número de série
  7. IMEIs de todos os rádios
  8. MEIDs de todos os rádios

Para oferecer suporte ao atestado de ID do dispositivo, um dispositivo atesta esses identificadores. Todos dispositivos com Android têm os seis primeiros e são necessários para essa para funcionar. Se o dispositivo tiver rádio celular integrado, também precisa oferecer suporte ao atestado dos IMEIs e/ou MEIDs dos rádios.

O atestado de ID é solicitado executando um atestado de chaves e incluindo o identificadores de dispositivo que precisam ser atestados na solicitação. Os identificadores são marcados 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

O identificador a ser atestado é uma string de bytes codificada em UTF-8. Esse formato se aplica a e também identificadores numéricos. Cada identificador a ser atestado é expresso como um String codificada em UTF-8.

Se o dispositivo não oferecer suporte ao atestado de ID (ou destroyAttestationIds() já foi chamado, e o dispositivo não pode mais atestar seus IDs), qualquer solicitação de atestado de chaves que inclua um ou mais dos dessas tags vai falhar com ErrorCode::CANNOT_ATTEST_IDS.

Se o dispositivo for compatível com o atestado de ID e uma ou mais das tags acima tiverem incluído em uma solicitação de atestado de chaves, o TEE verifica o identificador fornecido com cada uma das tags corresponde à cópia dos identificadores de hardware. Se um ou mais identificadores não corresponderem, todo o atestado falhará com ErrorCode::CANNOT_ATTEST_IDS: É válido que a mesma tag seja fornecida várias vezes. Isso pode ser útil, por exemplo, ao atestar IMEIs: Um dispositivo pode ter vários rádios com diversos IMEIs. Uma solicitação de atestado válido se o valor fornecido com cada ATTESTATION_ID_IMEI corresponder um dos rádios do dispositivo. O mesmo se aplica a todas as outras tags.

Se o atestado for bem-sucedido, os IDs atestados serão adicionados à extensão de atestado (OID 1.3.6.1.4.1.11129.2.1.17) do certificado de atestado emitido; usando o esquema acima. Mudanças do Keymaster 2 esquema de atestado estão em negrito com comentários.

API Java

Esta seção é apenas informativa. Os implementadores do Keymaster nem implementar nem usar a API Java. Isso ajuda os implementadores a entender como o recurso é usado pelos aplicativos. Componentes do sistema podem usar de maneira diferente. Por isso, é crucial que essa seção não seja tratada como regulatória.