Recursos

Esta página contém informações sobre os recursos criptográficos do Keystore no Android 6.0 e superior.

Primitivas criptográficas

O Keystore fornece as seguintes categorias de operações:

  • Geração de chave
  • Importação e exportação de chaves assimétricas (sem quebra de chave)
  • Importação de chaves simétricas brutas (sem quebra de chave)
  • Criptografia e descriptografia assimétrica com modos de preenchimento apropriados
  • Assinatura e verificação assimétrica com modos de digestão e preenchimento apropriados
  • Criptografia e descriptografia simétrica em modos apropriados, incluindo um modo AEAD
  • Geração e verificação de códigos de autenticação de mensagem simétrica

Elementos de protocolo, como propósito, modo e preenchimento, bem como restrições de controle de acesso , são especificados quando as chaves são geradas ou importadas e são permanentemente vinculadas à chave, garantindo que a chave não possa ser usada de outra forma.

Além da lista acima, há mais um serviço que as implementações do Keymaster fornecem, mas que não é exposto como uma API: Geração de números aleatórios. Isso é usado internamente para geração de chaves, Vetores de Inicialização (IVs), preenchimento aleatório e outros elementos de protocolos seguros que exigem aleatoriedade.

Primitivos necessários

Todas as implementações do Keymaster fornecem:

  • RSA
    • Suporte a chaves de 2048, 3072 e 4096 bits
    • Suporte para expoente público F4 (2^16+1)
    • Modos de preenchimento para assinatura RSA:
      • RSASSA-PSS ( PaddingMode::RSA_PSS )
      • RSASSA-PKCS1-v1_5 ( PaddingMode::RSA_PKCS1_1_5_SIGN )
    • Modos de resumo para assinatura RSA:
      • SHA-256
    • Modos de preenchimento para criptografia/descriptografia RSA:
      • Não acolchoado
      • RSAES-OAEP ( PaddingMode::RSA_OAEP )
      • RSAES-PKCS1-v1_5 ( PaddingMode::RSA_PKCS1_1_5_ENCRYPT )
  • ECDSA
    • Suporte para chaves de 224, 256, 384 e 521 bits são suportados, usando as curvas NIST P-224, P-256, P-384 e P-521, respectivamente
    • Modos de resumo para ECDSA:
      • Nenhum resumo (obsoleto, será removido no futuro)
      • SHA-256
  • AES
    • Chaves de 128 e 256 bits são suportadas
    • CBC , CTR, BCE e GCM. A implementação do GCM não permite o uso de tags menores que 96 bits ou comprimentos nonce diferentes de 96 bits.
    • Modos de preenchimento PaddingMode::NONE e PaddingMode::PKCS7 são suportados para os modos CBC e ECB. Sem preenchimento, a criptografia do modo CBC ou ECB falha se a entrada não for um múltiplo do tamanho do bloco.
  • HMAC SHA-256 , com qualquer tamanho de chave até pelo menos 32 bytes.

SHA1 e os outros membros da família SHA2 (SHA-224, SHA384 e SHA512) são fortemente recomendados para implementações de Keymaster. O Keystore os fornece em software se a implementação do Keymaster de hardware não os fornecer.

Algumas primitivas também são recomendadas para interoperabilidade com outros sistemas:

  • Tamanhos de chave menores para RSA
  • Expoentes públicos arbitrários para RSA

Controle de acesso de chave

As chaves baseadas em hardware que nunca podem ser extraídas do dispositivo não fornecem muita segurança se um invasor puder usá-las à vontade (embora sejam mais seguras do que as chaves que podem ser exfiltradas). Assim, é crucial que o Keystore aplique controles de acesso.

Os controles de acesso são definidos como uma "lista de autorização" de pares tag/valor. As tags de autorização são inteiros de 32 bits e os valores são de vários tipos. Algumas tags podem ser repetidas para especificar vários valores. Se uma tag pode ser repetida é especificado na documentação da tag . Quando uma chave é criada, o chamador especifica uma lista de autorização. A implementação do Keymaster subjacente ao Keystore modifica a lista para especificar algumas informações adicionais, como se a chave tem proteção contra reversão e retornar uma lista de autorização "final", codificada no blob de chaves retornado. Qualquer tentativa de usar a chave para qualquer operação criptográfica falhará se a lista de autorização final for modificada.

Para Keymaster 2 e anteriores, o conjunto de tags possíveis é definido na enumeração keymaster_authorization_tag_t e é fixo permanentemente (embora possa ser estendido). Os nomes foram prefixados com KM_TAG . Os quatro primeiros bits de IDs de tag são usados ​​para indicar o tipo.

Keymaster 3 alterou o prefixo KM_TAG para Tag:: .

Os tipos possíveis incluem:

ENUM : Os valores de muitas tags são definidos em enumerações. Por exemplo, os valores possíveis de TAG::PURPOSE PURPOSE são definidos em enum keymaster_purpose_t .

ENUM_REP : Igual a ENUM , exceto que a tag pode ser repetida em uma lista de autorização. A repetição indica vários valores autorizados. Por exemplo, uma chave de criptografia provavelmente tem KeyPurpose::ENCRYPT ENCRYPT e KeyPurpose::DECRYPT .

UINT : inteiros sem sinal de 32 bits. Exemplo: TAG::KEY_SIZE

UINT_REP : Igual a UINT , exceto que a tag pode ser repetida em uma lista de autorização. A repetição indica vários valores autorizados.

ULONG : inteiros sem sinal de 64 bits. Exemplo: TAG::RSA_PUBLIC_EXPONENT

ULONG_REP : Igual a ULONG , exceto que a tag pode ser repetida em uma lista de autorização. A repetição indica vários valores autorizados.

DATE : valores de data/hora, expressos em milissegundos desde 1º de janeiro de 1970. Exemplo: TAG::PRIVKEY_EXPIRE_DATETIME

BOOL : Verdadeiro ou falso. Uma tag do tipo BOOL é considerada "false" se a tag não estiver presente e "true" se estiver presente. Exemplo: TAG::ROLLBACK_RESISTANT

BIGNUM : Inteiros de comprimento arbitrário, expressos como uma matriz de bytes em ordem big-endian. Exemplo: TAG::RSA_PUBLIC_EXPONENT

BYTES : Uma sequência de bytes. Exemplo: TAG::ROOT_OF_TRUST

Aplicação de hardware versus software

Nem todas as implementações de hardware seguro contêm os mesmos recursos. Para oferecer suporte a uma variedade de abordagens, o Keymaster distingue entre aplicação de controle de acesso mundial seguro e não seguro, ou aplicação de hardware e software, respectivamente.

Todas as implementações:

  • Imponha a correspondência exata (não a execução) de todas as autorizações. As listas de autorização em blobs de chaves correspondem exatamente às autorizações retornadas durante a geração de chaves, incluindo o pedido. Qualquer incompatibilidade causa um diagnóstico de erro.
  • Declare as autorizações cujos valores semânticos são obrigatórios.

O mecanismo da API para declarar autorizações impostas por hardware está na estrutura keymaster_key_characteristics_t . Ele divide a lista de autorização em duas sublistas, hw_enforced e sw_enforced . O hardware seguro é responsável por colocar os valores apropriados em cada um, com base no que ele pode impor.

Além disso, o Keystore implementa a aplicação baseada em software de todas as autorizações, sejam elas impostas pelo hardware seguro ou não.

Por exemplo, considere uma implementação baseada em TrustZone que não oferece suporte à expiração de chave. Uma chave com uma data de expiração ainda pode ser criada. A lista de autorizações dessa chave incluirá a tag TAG::ORIGINATION_EXPIRE_DATETIME com a data de validade. Uma solicitação ao Keystore para as características da chave encontrará essa tag na lista sw_enforced e o hardware seguro não aplicará o requisito de expiração. No entanto, tentativas de usar a chave após a expiração serão rejeitadas pelo Keystore.

Se o dispositivo for atualizado com hardware seguro que suporta expiração, uma solicitação de características de chave encontrará TAG::ORIGINATION_EXPIRE_DATETIME na lista hw_enforced e as tentativas de usar a chave após a expiração falharão, mesmo que o armazenamento de chaves seja de alguma forma subvertido ou ignorado .

Para obter mais informações sobre como determinar se as chaves são suportadas por hardware, consulte Atestado de chave .

Autorizações de construção de mensagens criptográficas

As seguintes tags são usadas para definir as características criptográficas das operações usando a chave associada: TAG::ALGORITHM , TAG::KEY_SIZE , TAG::BLOCK_MODE , TAG::PADDING PADDING , TAG::CALLER_NONCE e TAG::DIGEST

TAG::PADDING , TAG::DIGEST e PaddingMode::BLOCK_MODE são repetíveis, o que significa que vários valores podem ser associados a uma única chave, e o valor a ser usado é especificado no momento da operação.

Propósito

As chaves têm um conjunto associado de propósitos, expressos como uma ou mais entradas de autorização com a tag TAG::PURPOSE , que define como elas podem ser usadas. Os propósitos são:

  • KeyPurpose::ENCRYPT
  • KeyPurpose::DECRYPT
  • KeyPurpose::SIGN
  • KeyPurpose::VERIFY

Qualquer chave pode ter qualquer subconjunto dessas finalidades. Observe que algumas combinações criam problemas de segurança. Por exemplo, uma chave RSA que pode ser usada para criptografar e assinar permite que um invasor convença o sistema a descriptografar dados arbitrários para gerar assinaturas.

Importar e exportar

O Keymaster suporta apenas a exportação de chaves públicas, no formato X.509, e a importação de:

  • Pares de chaves públicas e privadas no formato PKCS#8 codificado por DER, sem criptografia baseada em senha
  • Chaves simétricas como bytes brutos

Para garantir que as chaves importadas possam ser diferenciadas das chaves geradas com segurança, TAG::ORIGIN é incluído na lista de autorização de chave apropriada. Por exemplo, se uma chave foi gerada em hardware seguro, TAG::ORIGIN com valor KeyOrigin::GENERATED será encontrado na lista hw_enforced das características da chave, enquanto uma chave importada em hardware seguro terá o valor KeyOrigin::IMPORTED .

Autenticação de usuário

As implementações do Secure Keymaster não implementam a autenticação do usuário, mas dependem de outros aplicativos confiáveis ​​que o fazem. Para a interface que esses aplicativos implementam, consulte a página Gatekeeper .

Os requisitos de autenticação do usuário são especificados por meio de dois conjuntos de tags. O primeiro conjunto indica qual usuário pode usar a chave:

  • TAG::ALL_USERS indica que a chave pode ser usada por todos os usuários. Se presente, TAG::USER_ID e TAG::USER_SECURE_ID não estão presentes.
  • TAG::USER_ID tem um valor numérico que especifica o ID do usuário autorizado. Observe que este é o ID de usuário do Android (para multiusuário), não o UID do aplicativo, e é aplicado apenas por software não seguro. Se presente, TAG::ALL_USERS não está presente.
  • TAG::USER_SECURE_ID tem um valor numérico de 64 bits que especifica o ID de usuário seguro fornecido em um token de autenticação seguro para desbloquear o uso da chave. Se repetida, a chave pode ser usada se algum dos valores for fornecido em um token de autenticação seguro.

O segundo conjunto indica se e quando o usuário precisa ser autenticado. Se nenhuma dessas tags estiver presente, mas TAG::USER_SECURE_ID estiver, a autenticação será necessária para cada uso da chave.

  • NO_AUTHENTICATION_REQUIRED indica que nenhuma autenticação de usuário é necessária, embora a chave ainda possa ser usada apenas por aplicativos executados como os usuários especificados por TAG::USER_ID .
  • TAG::AUTH_TIMEOUT é um valor numérico que especifica, em segundos, quão atualizada a autenticação do usuário precisa ser para autorizar o uso da chave. Isso se aplica apenas a operações de chave privada/secreta. As operações de chave pública não requerem autenticação. Os tempos limite não cruzam as reinicializações; após uma reinicialização, todas as chaves "nunca são autenticadas". O tempo limite pode ser definido como um valor grande para indicar que a autenticação é necessária uma vez por inicialização (2 ^ 32 segundos é ~ 136 anos; presumivelmente, os dispositivos Android são reinicializados com mais frequência do que isso).

Ligação do cliente

A vinculação do cliente, a associação de uma chave com um aplicativo cliente específico, é feita por meio de um ID de cliente opcional e alguns dados de cliente opcionais ( TAG::APPLICATION_ID e TAG::APPLICATION_DATA , respectivamente). O keystore trata esses valores como blobs opacos, garantindo apenas que os mesmos blobs apresentados durante a geração/importação de chave sejam apresentados para cada uso e sejam idênticos byte a byte. Os dados de ligação do cliente não são retornados pelo Keymaster. O chamador precisa saber para usar a chave.

Esse recurso não é exposto aos aplicativos.

Expiração

O armazenamento de chaves oferece suporte à restrição do uso de chaves por data. O início da validade e a expiração da chave podem ser associados a uma chave e o Keymaster se recusa a realizar operações de chave se a data/hora atual estiver fora do intervalo válido. O intervalo de validade da chave é especificado com as tags TAG::ACTIVE_DATETIME , TAG::ORIGINATION_EXPIRE_DATETIME e TAG::USAGE_EXPIRE_DATETIME . A distinção entre "origem" e "uso" é baseada se a chave está sendo usada para "originar" um novo texto cifrado/assinatura/etc., ou para "usar" um texto cifrado/assinatura/etc. Observe que essa distinção não é exposta aos aplicativos.

As TAG::ACTIVE_DATETIME , TAG::ORIGINATION_EXPIRE_DATETIME e TAG::USAGE_EXPIRE_DATETIME são opcionais. Se as tags estiverem ausentes, assume-se que a chave em questão sempre pode ser usada para descriptografar/verificar mensagens.

Como a hora do relógio de parede é fornecida pelo mundo não seguro, é improvável que as tags relacionadas à expiração estejam na lista imposta por hardware. A imposição de expiração de hardware exigiria que o mundo seguro de alguma forma obtivesse tempo e dados confiáveis, por exemplo, por meio de um protocolo de resposta de desafio com um servidor de tempo remoto confiável.

Raiz de vinculação de confiança

O armazenamento de chaves exige que as chaves sejam vinculadas a uma raiz de confiança, que é uma cadeia de bits fornecida ao hardware seguro do Keymaster durante a inicialização, preferencialmente pelo carregador de inicialização. Este bitstring é criptograficamente vinculado a todas as chaves gerenciadas pelo Keymaster.

A raiz de confiança consiste na chave pública usada para verificar a assinatura na imagem de inicialização e o estado de bloqueio do dispositivo. Se a chave pública for alterada para permitir que uma imagem de sistema diferente seja usada ou se o estado de bloqueio for alterado, nenhuma das chaves protegidas por Keymaster criadas pelo sistema anterior poderá ser usada, a menos que a raiz de confiança anterior seja restaurada e um sistema que é assinado por essa chave é inicializado. O objetivo é aumentar o valor dos controles de acesso de chave impostos por software, impossibilitando que um sistema operacional instalado por um invasor use chaves Keymaster.

Teclas independentes

Alguns hardwares seguros do Keymaster podem optar por armazenar material de chave internamente e retornar identificadores em vez de material de chave criptografado. Ou pode haver outros casos em que as chaves não podem ser usadas até que algum outro componente do sistema mundial não seguro ou seguro esteja disponível. O Keymaster HAL permite que o chamador solicite que uma chave seja "independente", por meio da tag TAG::STANDALONE , o que significa que não são necessários outros recursos além do blob e do sistema Keymaster em execução. As tags associadas a uma chave podem ser inspecionadas para ver se uma chave é independente. Atualmente, apenas dois valores são definidos:

  • KeyBlobUsageRequirements::STANDALONE
  • KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM

Esse recurso não é exposto aos aplicativos.

Velocidade

Quando é criado, a velocidade máxima de uso pode ser especificada com TAG::MIN_SECONDS_BETWEEN_OPS . As implementações do TrustZone se recusam a realizar operações criptográficas com essa chave se uma operação foi executada menos de TAG::MIN_SECONDS_BETWEEN_OPS segundos antes.

A abordagem simples para implementar limites de velocidade é uma tabela de IDs-chave e carimbos de data/hora do último uso. Esta tabela provavelmente será de tamanho limitado, mas acomoda pelo menos 16 entradas. No caso de a tabela estar cheia e nenhuma entrada puder ser atualizada ou descartada, as implementações de hardware seguro são "à prova de falhas", preferindo recusar todas as operações de chave com velocidade limitada até que uma das entradas expire. É aceitável que todas as entradas expirem na reinicialização.

As chaves também podem ser limitadas a n usos por inicialização com TAG::MAX_USES_PER_BOOT . Isso também requer uma mesa de rastreamento, que acomoda pelo menos quatro chaves e também à prova de falhas. Observe que os aplicativos não poderão criar chaves limitadas por inicialização. Esse recurso não é exposto por meio do Keystore e é reservado para operações do sistema.

Esse recurso não é exposto aos aplicativos.

Re-semeadura do gerador de números aleatórios

Como o hardware seguro gera números aleatórios para material de chave e Vetores de Inicialização (IVs), e como os geradores de números aleatórios de hardware nem sempre são totalmente confiáveis, o Keymaster HAL fornece uma interface para permitir que o cliente forneça entropia adicional que será números gerados.

Use um gerador de números aleatórios de hardware como a fonte primária de semente. Os dados de semente fornecidos por meio da API externa não podem ser a única fonte de aleatoriedade usada para geração de números. Além disso, a operação de mistura usada precisa garantir que a saída aleatória seja imprevisível se qualquer uma das fontes de sementes for imprevisível.

Esse recurso não é exposto aos aplicativos, mas é usado pela estrutura, que fornece regularmente entropia adicional, recuperada de uma instância Java SecureRandom, para o hardware seguro.