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 dogenerateKey
para o qual o atestado será criado.attestParams
é uma lista de todos os parâmetros necessários para atestado. Isso incluiTag::ATTESTATION_CHALLENGE
e possivelmenteTag::RESET_SINCE_ID_ROTATION
, além deTag::APPLICATION_ID
eTag::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 dekeyToAttest
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 deTag::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 deTag::APPLICATION_ID
.R
é 1 seTag::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 finalidadeID1...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:
- Nome da marca, conforme retornado por
Build.BRAND
no Android - Nome do dispositivo, conforme retornado por
Build.DEVICE
no Android. - Nome do produto, conforme retornado por
Build.PRODUCT
no Android - Nome do fabricante, conforme retornado por
Build.MANUFACTURER
no Android - Nome do modelo, conforme retornado por
Build.MODEL
no Android. - Número de série
- IMEIs de todos os rádios
- 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.