O Keystore fornece um local mais seguro para criar, armazenar e usar chaves criptográficas de forma controlada. Quando o armazenamento de chaves apoiado por hardware está disponível e é usado, o material da chave é mais seguro contra extração do dispositivo, e o Keymaster impõe restrições que são difíceis de subverter.
No entanto, isso só é verdade se as chaves do keystore estiverem em armazenamento com suporte de hardware. No Keymaster 1, não havia como os aplicativos ou servidores remotos verificarem com segurança se esse era o caso. O daemon do keystore carregou o HAL keymaster disponível e acreditou em tudo o que o HAL disse em relação ao suporte de chaves por hardware.
Para remediar isso, a Keymaster introduziu o atestado de chave no Android 7.0 (Keymaster 2) e o atestado de ID no Android 8.0 (Keymaster 3).
O atestado de chave visa fornecer uma maneira de determinar com segurança se um par de chaves assimétricas é suportado por hardware, quais são as propriedades da chave e quais restrições são aplicadas ao seu uso.
O atestado de identificação permite que o dispositivo forneça prova de seus identificadores de hardware, como número de série ou IMEI.
Atestado chave
Para oferecer suporte ao atestado de chave, o Android 7.1 introduziu um conjunto de tags, tipos e métodos para o HAL.
Tag
-
Tag::ATTESTATION_CHALLENGE
-
Tag::INCLUDE_UNIQUE_ID
-
Tag::RESET_SINCE_ID_ROTATION
Tipo
Keymaster 2 e abaixo
typedef struct { keymaster_blob_t* entries; size_t entry_count; } keymaster_cert_chain_t;
Método AttestKey
Mestre-chave 3
attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams) generates(ErrorCode error, vec<vec<uint8_t>> certChain);
Keymaster 2 e abaixo
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 degenerateKey
para o qual o atestado será criado. -
attestParams
é uma lista de quaisquer parâmetros necessários para atestado. Isso incluiTag::ATTESTATION_CHALLENGE
e possivelmenteTag::RESET_SINCE_ID_ROTATION
, bem comoTag::APPLICATION_ID
eTag::APPLICATION_DATA
. Os dois últimos são necessários para descriptografar o blob de chave se tiverem sido especificados durante a geração da chave. -
certChain
é o parâmetro de saída, que retorna uma matriz de certificados. A entrada 0 é o certificado de atestado, o que significa que certifica a chave dekeyToAttest
e contém a extensão de atestado.
O método attestKey
é considerado uma operação de chave pública na chave atestada, porque pode ser chamado a qualquer momento e não precisa atender a restrições de autorização. Por exemplo, se a chave atestada precisar de autenticação do usuário para uso, um atestado poderá ser gerado sem autenticação do usuário.
Certificado de atestado
O certificado de atestado é um certificado X.509 padrão, com uma extensão de atestado opcional que contém uma descrição da chave atestada. O certificado é assinado com uma chave de atestado certificada. A chave de atestado pode usar um algoritmo diferente da chave que está sendo atestada.
O certificado de atestado contém os campos da tabela abaixo e não pode conter campos adicionais. Alguns campos especificam um valor de campo fixo. Os testes CTS validam se o conteúdo do certificado é exatamente como definido.
SEQUÊNCIA DE Certificado
Nome do campo (ver RFC 5280 ) | Valor |
---|---|
tbsCertificado | SEQUÊNCIA DO Certificado TBSCertificado |
assinaturaAlgoritmo | AlgorithmIdentifier do algoritmo usado para assinar a chave: ECDSA para chaves EC, RSA para chaves RSA. |
assinaturaValor | BIT STRING, assinatura calculada em tbsCertificate codificado em ASN.1 DER. |
SEQUÊNCIA DO Certificado TBSCertificado
Nome do campo (ver RFC 5280 ) | Valor |
---|---|
version | INTEGER 2 (significa certificado v3) |
serialNumber | INTEGER 1 (valor fixo: igual em todos os certificados) |
signature | AlgorithmIdentificador 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 1º de janeiro de 1970. Consulte RFC 5280 para obter representações de datas corretas em certificados. Se Tag::ACTIVE_DATETIME não estiver presente, use o valor de Tag::CREATION_DATETIME . Se Tag::USAGE_EXPIRE_DATETIME não estiver presente, use a data de expiração do certificado de chave de atestado em lote. |
subject | CN = "Android Keystore Key" (valor fixo: igual em todos os certificados) |
subjectPublicKeyInfo | SubjectPublicKeyInfo contendo chave pública atestada. |
extensions/Key Usage | digitalSignature: define se a chave tem 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 na seção Extensão de Atestado abaixo. Tal como acontece com todas as extensões de certificado X.509, o conteúdo é representado como um OCTET_STRING contendo uma codificação DER da SEQUÊNCIA de atestado. |
Extensão de atestado
A extensão attestation
contém uma descrição completa das autorizações keymaster associadas à chave, em uma estrutura que corresponde diretamente às listas de autorização usadas no Android e no HAL keymaster. Cada tag em uma lista de autorização é representada por uma entrada ASN.1 SEQUENCE
, explicitamente marcada com o número da tag keymaster, mas com o descritor de tipo (quatro bits de ordem superior) mascarado.
Por exemplo, no Keymaster 3, Tag::PURPOSE
é definido em types.hal como ENUM_REP | 1
. Para a extensão de atestado, o valor ENUM_REP
é removido, deixando a tag 1
. (Para Keymaster 2 e versões anteriores, KM_TAG_PURPOSE
é definido em keymaster_defs.h.)
Os valores são traduzidos de maneira direta para os tipos ASN.1, conforme esta tabela:
Tipo de mestre de chaves | Tipo ASN.1 |
---|---|
ENUM | INTEIRO |
ENUM_REP | CONJUNTO DE INTEIRO |
UINT | INTEIRO |
UINT_REP | CONJUNTO DE INTEIRO |
ULONG | INTEIRO |
ULONG_REP | CONJUNTO DE INTEIRO |
DATE | INTEGER (milissegundos desde 1º de janeiro de 1970 00:00:00 GMT) |
BOOL | NULL (no keymaster, tag presente significa verdadeiro, ausente significa falso. A mesma semântica se aplica à codificação ASN.1) |
BIGNUM | Atualmente não é usado, portanto 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, 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 KeyDescription
Os campos keymasterVersion
e attestationChallenge
são identificados posicionalmente, e não por tag, portanto, as tags no formulário codificado especificam apenas o tipo de campo. Os campos restantes são marcados implicitamente conforme especificado no esquema.
Nome do campo | Tipo | Valor |
---|---|---|
attestationVersion | INTEIRO | Versão do esquema de atestado: 1, 2 ou 3. |
attestationSecurity | Nível de segurança | O nível de segurança deste atestado. É possível obter atestados de software de chaves apoiadas por hardware. Esses atestados não são confiáveis se o sistema Android estiver comprometido. |
keymasterVersion | INTEIRO | Versão do dispositivo keymaster: 0, 1, 2, 3 ou 4. |
keymasterSecurity | Nível de segurança | O nível de segurança da implementação do keymaster. |
attestationChallenge | OCTET_STRING | Valor de Tag::ATTESTATION_CHALLENGE , especificado para solicitação de atestado. |
uniqueId | OCTET_STRING | ID exclusivo opcional, presente se a chave tiver Tag::INCLUDE_UNIQUE_ID |
softwareEnforced | Lista de autorização | Autorizações de keymaster opcionais que não são impostas pelo TEE, se houver. |
teeEnforced | Lista de autorização | Opcional, autorizações Keymaster que são impostas pelo TEE, se houver. |
Campos da lista de autorização
Os campos AuthorizationList
são todos opcionais e são identificados pelo valor da tag keymaster, com os bits de tipo mascarados. A marcação explícita é usada para que os campos também contenham uma tag indicando seu tipo ASN.1, para facilitar a análise.
Para obter detalhes sobre os valores de cada campo, consulte types.hal
para Keymaster 3 e keymaster_defs.h
para Keymaster 2 e abaixo. Os nomes das tags Keymaster foram transformados em nomes de campos omitindo o prefixo KM_TAG
e alterando o restante para camel case, então Tag::KEY_SIZE
tornou-se keySize
.
Campos RootOfTrust
Os campos RootOfTrust
são identificados posicionalmente.
Nome do campo | Tipo | Valor |
---|---|---|
verifiedBootKey | OCTET_STRING | Um hash seguro da chave usada para verificar a imagem do sistema. SHA-256 recomendado. |
deviceLocked | BOLEANO | Verdadeiro se o bootloader estiver bloqueado, o que significa que apenas imagens assinadas podem ser atualizadas e que a verificação de inicialização verificada é feita. |
verifiedBootState | Estado de inicialização verificado | Estado da inicialização verificada. |
verifiedBootHash | OCTET_STRING | Um resumo de todos os dados protegidos pelo Verified Boot. Para dispositivos que usam a implementação do Android Verified Boot do Verified Boot, esse valor contém o resumo da estrutura VBMeta ou a estrutura de metadados do Verified Boot. Para saber mais sobre como calcular esse valor, consulteThe VBMeta Digest |
Valores verificadosBootState
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 às partições verificadas, incluindo o carregador de inicialização, a partição de inicialização e todas as partições verificadas. Nesse estado, o valor verifiedBootKey é o hash do certificado incorporado, ou seja, o certificado imutável gravado na ROM.Este estado corresponde ao estado de inicialização verde , conforme documentado na documentação do fluxo de inicialização verificado . |
SelfSigned | Indica que a partição de inicialização foi verificada usando o certificado incorporado e que a assinatura é válida. O bootloader exibe um aviso e a impressão digital da chave pública antes de permitir que o processo de inicialização continue. Nesse estado, o valor verifiedBootKey é o hash do certificado autoassinado.Este estado corresponde ao estado de inicialização amarelo , conforme documentado na documentação do fluxo de inicialização verificado . |
Unverified | Indica que um dispositivo pode ser modificado livremente. A integridade do dispositivo é deixada para o usuário verificar fora de banda. O bootloader exibe um aviso ao usuário antes de permitir que o processo de inicialização continue. Neste estado, o valor verifiedBootKey está vazio.Este estado corresponde ao estado de inicialização laranja , conforme documentado na documentação do fluxo de inicialização verificado . |
Failed | Indica que o dispositivo falhou na verificação. Na verdade, nenhum certificado de atestado contém esse valor, porque nesse estado o bootloader é interrompido. Está incluído aqui para completar. Este estado corresponde ao estado de inicialização vermelho , conforme documentado na documentação do fluxo de inicialização verificado . |
Valores de nível de segurança
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 pode ser alterado se esse sistema for comprometido. |
TrustedEnvironment | O código que cria ou gerencia o elemento relevante (atestado ou chave) é implementado em um Trusted Execution Environment (TEE). Poderia ser alterado se o TEE fosse comprometido, mas o TEE é altamente resistente ao comprometimento remoto e moderadamente resistente ao comprometimento por ataque direto ao hardware. |
StrongBox | O código que cria ou gerencia o elemento relevante (atestado ou chave) é implementado em um módulo de segurança de hardware dedicado. Ele poderia ser alterado se o módulo de segurança de hardware fosse comprometido, mas é altamente resistente a comprometimento remoto e altamente resistente a comprometimento por ataque direto de hardware. |
ID único
O ID exclusivo é um valor de 128 bits que identifica o dispositivo, mas apenas por um período limitado. O valor é calculado com:
HMAC_SHA256(T || C || R, HBK)
Onde:
-
T
é o "valor do contador temporal", calculado dividindo o valor deTag::CREATION_DATETIME
por 2592000000, eliminando qualquer restante.T
muda a cada 30 dias (2592000000 = 30 * 24 * 60 * 60 * 1000). -
C
é o valor deTag::APPLICATION_ID
-
R
é 1 seTag::RESET_SINCE_ID_ROTATION
estiver presente no parâmetro attest_params para a chamada attest_key ou 0 se a tag não estiver presente. -
HBK
é um segredo exclusivo vinculado ao hardware, conhecido pelo Trusted Execution Environment e nunca revelado por ele. O segredo contém pelo menos 128 bits de entropia e é exclusivo para o dispositivo individual (a exclusividade probabilística é aceitável, dados os 128 bits de entropia). O HBK deve ser derivado de material de chave fundida via HMAC ou AES_CMAC.
Trunque a saída HMAC_SHA256 para 128 bits.
Chaves e certificados de atestado
Duas chaves, uma RSA e uma ECDSA, e as cadeias de certificados correspondentes, são provisionadas com segurança no dispositivo.
O Android 12 introduz o provisionamento remoto de chave, e o Android 13 exige que os dispositivos o implementem. O provisionamento remoto de chave fornece aos dispositivos em campo certificados de atestado ECDSA P256 por aplicativo. Esses certificados têm vida mais curta do que os certificados fornecidos pela fábrica.
Vários IMEIs
O Android 14 adiciona suporte para vários IMEIs no registro Android Key Attestation. Os OEMs podem implementar esse recurso adicionando uma tag KeyMint para um segundo IMEI. Está se tornando cada vez mais comum que os dispositivos tenham vários rádios celulares e os OEMs agora podem oferecer suporte a dispositivos com dois IMEIs.
Os OEMs são obrigados a ter um IMEI secundário, se presente em seus dispositivos, a ser provisionado para a(s) implementação(ões) KeyMint, para que essas implementações possam atestar isso da mesma forma que atestam o primeiro IMEI
Atestado de identidade
O Android 8.0 inclui suporte opcional para atestado de ID para dispositivos com Keymaster 3. O atestado de ID permite que o dispositivo forneça prova de seus identificadores de hardware, como número de série ou IMEI. Embora seja um recurso opcional, é altamente recomendável que todas as implementações do Keymaster 3 forneçam suporte para ele, pois ser capaz de provar a identidade do dispositivo permite que casos de uso como configuração remota sem toque real sejam mais seguros (porque o lado remoto pode ter certeza de que está falando com o dispositivo certo, não com um dispositivo que falsifica sua identidade).
O atestado de ID funciona criando cópias dos identificadores de hardware do dispositivo que somente o Trusted Execution Environment (TEE) pode acessar antes do dispositivo sair da fábrica. Um usuário pode desbloquear o bootloader do dispositivo e alterar o software do sistema e os identificadores relatados pelos frameworks Android. As cópias dos identificadores mantidos pelo TEE não podem ser manipuladas desta forma, garantindo que o atestado de ID do dispositivo atestará apenas os identificadores de hardware originais do dispositivo, frustrando assim as tentativas de falsificação.
A superfície principal da API para atestado de ID baseia-se no mecanismo de atestado de chave existente introduzido com Keymaster 2. Ao solicitar um certificado de atestado para uma chave mantida pelo keymaster, o chamador pode solicitar que os identificadores de hardware do dispositivo sejam incluídos nos metadados do certificado de atestado. Se a chave for mantida no TEE, o certificado será encadeado de volta a uma raiz de confiança conhecida. O destinatário de tal certificado pode verificar se o certificado e seu conteúdo, incluindo os identificadores de hardware, foram escritos pelo TEE. Quando solicitado a incluir identificadores de hardware no certificado de atestado, o TEE atesta apenas os identificadores mantidos em seu armazenamento, conforme preenchidos no chão de 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 do dispositivo sair da fábrica.
- O método
destroyAttestationIds()
pode destruir permanentemente esta cópia dos dados derivados do identificador. A destruição permanente significa que os dados são completamente removidos, de forma que nem uma redefinição de fábrica nem qualquer outro procedimento realizado no dispositivo possa restaurá-los. Isso é especialmente importante para dispositivos em que um usuário desbloqueou o bootloader, alterou o software do sistema e modificou os identificadores retornados pelas estruturas Android. - Os recursos de RMA devem ter a capacidade de gerar novas cópias dos dados derivados do identificador de hardware. Dessa forma, um dispositivo que passa pelo RMA pode realizar novamente o atestado de ID. O mecanismo utilizado pelos recursos de RMA deve ser protegido para que os próprios usuários não possam invocá-lo, pois isso lhes permitiria obter atestados de IDs falsificados.
- Nenhum código diferente do aplicativo confiável Keymaster no TEE é capaz de ler os dados derivados do identificador mantidos no armazenamento.
- O armazenamento é inviolável: Se o conteúdo do armazenamento tiver sido modificado, o TEE trata-o da mesma forma como se as cópias do conteúdo tivessem sido destruídas e recusa todas as tentativas de atestado de identificação. Isso é implementado assinando ou MACing o armazenamento conforme descrito abaixo .
- O armazenamento não contém os identificadores originais. Como o atestado de ID envolve um desafio, o chamador sempre fornece os identificadores a serem atestados. O TEE só precisa verificar se estes correspondem aos valores que tinham originalmente. Armazenar hashes seguros dos valores originais em vez dos valores permite esta verificação.
Construção
Para criar uma implementação que tenha as propriedades listadas acima, armazene os valores derivados de ID na seguinte construção S. Não armazene outras cópias dos valores de ID, exceto os locais normais no sistema, que um proprietário de dispositivo pode modificar fazendo root:
S = D || HMAC(HBK, D)
onde:
-
D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
-
HMAC
é a construção HMAC com um hash seguro apropriado (recomendado SHA-256) -
HBK
é uma chave vinculada a hardware que não é usada para nenhuma outra finalidade -
ID 1 ...ID n
são os valores de ID originais; a associação de um valor específico a um índice específico depende da implementação, pois diferentes dispositivos terão diferentes números de identificadores -
||
representa concatenação
Como as saídas do HMAC têm tamanho fixo, nenhum cabeçalho ou outra estrutura é necessária para encontrar hashes de ID individuais ou o HMAC de D. Além de verificar os valores fornecidos para realizar o atestado, as implementações precisam validar S extraindo D de S , calculando HMAC(HBK, D) e comparando-o com o valor em S para verificar se nenhum ID individual foi modificado/corrompido. Além disso, as implementações devem usar comparações de tempo constante para todos os elementos de ID individuais e a validação de S. O tempo de comparação deve ser constante, independentemente do número de IDs fornecidos e da 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 dar suporte ao atestado de ID do dispositivo, um dispositivo atesta esses identificadores. Todos os dispositivos com Android possuem os seis primeiros e são necessários para que esse recurso funcione. Caso o aparelho possua algum rádio celular integrado, o aparelho também deverá suportar atestado dos IMEIs e/ou MEIDs dos rádios.
O atestado de ID é solicitado realizando um atestado de chave e incluindo os identificadores do dispositivo para atestar 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 atestar é uma sequência de bytes codificada em UTF-8. Este formato também se aplica a identificadores numéricos. Cada identificador a atestar é expresso como uma string codificada em UTF-8.
Se o dispositivo não suportar atestado de ID (ou destroyAttestationIds()
foi chamado anteriormente e o dispositivo não puder mais atestar seus IDs), qualquer solicitação de atestado de chave que inclua uma ou mais dessas tags falhará com ErrorCode::CANNOT_ATTEST_IDS
.
Se o dispositivo suportar atestado de ID e uma ou mais das tags acima tiverem sido incluídas em uma solicitação de atestado de chave, o TEE verificará se o identificador fornecido com cada uma das tags corresponde à sua 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 o mesmo tag seja fornecido diversas vezes. Isto pode ser útil, por exemplo, ao atestar IMEIs: Um dispositivo pode ter vários rádios com vários IMEIs. Uma solicitação de atestado é válida se o valor fornecido com cada ATTESTATION_ID_IMEI
corresponder a 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 . As alterações do esquema de atestado do Keymaster 2 estão em negrito e com comentários.
API Java
Esta seção é apenas informativa. Os implementadores Keymaster não implementam nem usam a API Java. Isso é fornecido para ajudar os implementadores a entender como o recurso é usado pelos aplicativos. Os componentes do sistema podem utilizá-lo de forma diferente, por isso é crucial que esta seção não seja tratada como normativa.