Google 致力于为黑人社区推动种族平等。查看具体举措
Esta página foi traduzida pela API Cloud Translation.
Switch to English

Keystore com suporte de hardware

A disponibilidade de um ambiente de execução confiável em um sistema em um chip (SoC) oferece uma oportunidade para os dispositivos Android fornecerem serviços de segurança robustos com suporte de hardware para o sistema operacional Android, para serviços de plataforma e até mesmo para aplicativos de terceiros. Os desenvolvedores que buscam as extensões específicas do Android devem acessar android.security.keystore .

Antes do Android 6.0, o Android já tinha uma API simples de serviços de criptografia apoiada por hardware, fornecida pelas versões 0.2 e 0.3 do Keymaster Hardware Abstraction Layer (HAL). A Keystore fornecia operações de assinatura e verificação digital, além de geração e importação de pares de chaves de assinatura assimétricas. Isso já está implementado em muitos dispositivos, mas existem muitos objetivos de segurança que não podem ser alcançados facilmente com apenas uma API de assinatura. Keystore no Android 6.0 estende a API Keystore para fornecer uma gama mais ampla de recursos.

No Android 6.0, o Keystore adicionou primitivos criptográficos simétricos , AES e HMAC, e um sistema de controle de acesso para chaves apoiadas por hardware. Os controles de acesso são especificados durante a geração da chave e aplicados durante o tempo de vida da chave. As chaves podem ser restritas para uso somente após a autenticação do usuário e apenas para propósitos específicos ou com parâmetros criptográficos especificados. Para obter mais informações, consulte as páginas Tags e funções de autorização .

Além de expandir a gama de primitivas criptográficas, o Keystore no Android 6.0 adiciona o seguinte:

  • Um esquema de controle de uso para permitir que o uso de chaves seja limitado, para mitigar o risco de comprometimento da segurança devido ao uso indevido de chaves
  • Um esquema de controle de acesso para permitir a restrição de chaves para usuários e clientes especificados e um intervalo de tempo definido

No Android 7.0, o Keymaster 2 adicionou suporte para atestado de chave e vinculação de versão. O atestado de chave fornece certificados de chave pública que contêm uma descrição detalhada da chave e seus controles de acesso, para tornar a existência da chave em hardware seguro e sua configuração verificável remotamente.

A vinculação de versão vincula as chaves ao sistema operacional e à versão do nível do patch. Isso garante que um invasor que descobrir uma fraqueza em uma versão antiga do sistema ou software TEE não possa reverter um dispositivo para a versão vulnerável e usar as chaves criadas com a versão mais recente. Além disso, quando uma chave com uma determinada versão e nível de patch é usada em um dispositivo que foi atualizado para uma versão ou nível de patch mais recente, a chave é atualizada antes de poder ser usada e a versão anterior da chave é invalidada. À medida que o dispositivo é atualizado, as chaves "movem-se" para frente junto com o dispositivo, mas qualquer reversão do dispositivo para uma versão anterior faz com que as teclas fiquem inutilizáveis.

No Android 8.0, o Keymaster 3 fez a transição da antiga estrutura em C Hardware Abstraction Layer (HAL) para a interface C ++ HAL gerada a partir de uma definição na nova Hardware Interface Definition Language (HIDL). Como parte da mudança, muitos dos tipos de argumento mudaram, embora os tipos e métodos tenham uma correspondência de um para um com os tipos antigos e os métodos de estrutura HAL. Consulte a página Funções para obter mais detalhes.

Além dessa revisão da interface, o Android 8.0 estende o recurso de atestado do Keymaster 2 para oferecer suporte ao atestado de ID . O atestado de ID fornece um mecanismo limitado e opcional para atestar fortemente os identificadores de hardware, como número de série do dispositivo, nome do produto e ID do telefone (IMEI / MEID). Para implementar essa adição, altere o esquema de atestado ASN.1 para adicionar atestado de ID. As implementações do Keymaster precisam encontrar uma maneira segura de recuperar os itens de dados relevantes, bem como definir um mecanismo para desativar o recurso de forma segura e permanente.

No Android 9, as atualizações incluem:

  • Atualização para Keymaster 4
  • Suporte para elementos seguros incorporados
  • Suporte para importação de chave segura
  • Suporte para criptografia 3DES
  • Alterações na vinculação de versão para que boot.img e system.img tenham versões definidas separadamente para permitir atualizações independentes

Glossário

Aqui está uma visão geral rápida dos componentes do Keystore e seus relacionamentos.

AndroidKeystore é a API do Android Framework e o componente usado por aplicativos para acessar a funcionalidade Keystore. Ele é implementado como uma extensão das APIs de arquitetura de criptografia Java padrão e consiste em código Java que é executado no próprio espaço de processo do aplicativo. AndroidKeystore atende às solicitações de aplicativos para comportamento de armazenamento de chaves, encaminhando-os ao daemon de armazenamento de chaves.

O daemon do keystore é um daemon do sistema Android que fornece acesso a todas as funcionalidades do Keystore por meio de uma API Binder . É responsável por armazenar "blobs de chaves", que contêm o material da chave secreta real, criptografado para que o Keystore possa armazená-lo, mas não usá-lo ou revelá-lo.

keymasterd é um servidor HIDL que fornece acesso ao Keymaster TA. (Este nome não é padronizado e serve para fins conceituais.)

Keymaster TA (aplicativo confiável) é o software em execução em um contexto seguro, na maioria das vezes em TrustZone em um ARM SoC, que fornece todas as operações seguras do Keystore, tem acesso à matéria-prima da chave, valida todas as condições de controle de acesso nas chaves etc.

LockSettingsService é o componente do sistema Android responsável pela autenticação do usuário, tanto por senha quanto por impressão digital. Não faz parte do Keystore, mas é relevante porque muitas operações de chave do Keystore exigem autenticação do usuário. LockSettingsService interage com o Gatekeeper TA e o Fingerprint TA para obter tokens de autenticação, os quais são fornecidos ao daemon de armazenamento de chaves e que são, em última instância, consumidos pelo aplicativo Keymaster TA.

Gatekeeper TA (aplicativo confiável) é outro componente em execução no contexto seguro, que é responsável por autenticar senhas de usuários e gerar tokens de autenticação usados ​​para provar ao Keymaster TA que uma autenticação foi feita para um determinado usuário em um determinado momento.

A impressão digital TA (aplicativo confiável) é outro componente em execução no contexto seguro que é responsável por autenticar as impressões digitais do usuário e gerar tokens de autenticação usados ​​para provar ao Keymaster TA que uma autenticação foi feita para um determinado usuário em um determinado momento.

Arquitetura

A Android Keystore API e o Keymaster HAL subjacente fornecem um conjunto básico, mas adequado, de primitivas criptográficas para permitir a implementação de protocolos usando chaves de hardware controladas por acesso.

O Keymaster HAL é uma biblioteca carregável dinamicamente fornecida pelo OEM usada pelo serviço Keystore para fornecer serviços criptográficos suportados por hardware. Para manter as coisas seguras, as implementações HAL não executam nenhuma operação sensível no espaço do usuário, ou mesmo no espaço do kernel. Operações confidenciais são delegadas a um processador seguro alcançado por meio de alguma interface do kernel. A arquitetura resultante é semelhante a esta:

Acesso ao Keymaster

Figura 1. Acesso ao Keymaster

Em um dispositivo Android, o "cliente" do Keymaster HAL consiste em várias camadas (por exemplo, aplicativo, estrutura, daemon de armazenamento de chave), mas isso pode ser ignorado para os fins deste documento. Isso significa que a API Keymaster HAL descrita é de baixo nível, usada por componentes internos da plataforma e não é exposta a desenvolvedores de aplicativos. A API de nível superior é descrita no site Android Developer .

O objetivo do Keymaster HAL não é implementar os algoritmos sensíveis à segurança, mas apenas para empacotar e desempacotar solicitações para o mundo seguro. O formato do fio é definido pela implementação.

Compatibilidade com versões anteriores

O Keymaster 1 HAL é completamente incompatível com os HALs lançados anteriormente, por exemplo, Keymaster 0.2 e 0.3. Para facilitar a interoperabilidade em dispositivos que executam Android 5.0 e anteriores lançados com os HALs Keymaster mais antigos, o Keystore fornece um adaptador que implementa o HAL Keymaster 1 com chamadas para a biblioteca de hardware existente. O resultado não pode fornecer toda a gama de funcionalidades do Keymaster 1 HAL. Em particular, ele suporta apenas algoritmos RSA e ECDSA, e toda a aplicação de autorização de chave é executada pelo adaptador, no mundo não seguro.

O Keymaster 2 simplificou ainda mais a interface HAL removendo os métodos get_supported_* e permitindo que o método finish() aceitasse a entrada. Isso reduz o número de viagens de ida e volta ao TEE nos casos em que a entrada está disponível de uma só vez e simplifica a implementação da descriptografia AEAD.

No Android 8.0, o Keymaster 3 fez a transição da HAL de estrutura C de estilo antigo para a interface HAL C ++ gerada a partir de uma definição na nova linguagem de definição de interface de hardware (HIDL). Uma implementação de HAL de novo estilo é criada criando uma subclasse da classe IKeymasterDevice gerada e implementando os métodos virtuais puros. Como parte da mudança, muitos dos tipos de argumento foram alterados, embora os tipos e métodos tenham uma correspondência de um para um com os tipos antigos e os métodos de estrutura HAL.

Visão geral do HIDL

O Hardware Interface Definition Language (HIDL) fornece um mecanismo independente de linguagem de implementação para especificar interfaces de hardware. O conjunto de ferramentas HIDL atualmente oferece suporte à geração de interfaces C ++ e Java. Espera-se que a maioria dos implementadores de Trusted Execution Environment (TEE) ache o conjunto de ferramentas C ++ mais conveniente, portanto, este documento discute apenas a representação C ++.

As interfaces HIDL consistem em um conjunto de métodos, expressos como:

  methodName(INPUT ARGUMENTS) generates (RESULT ARGUMENTS);

Existem vários tipos predefinidos e os HALs podem definir novos tipos enumerados e de estrutura. Para obter mais detalhes sobre HIDL, consulte a seção Referência .

Um exemplo de método do Keymaster 3 IKeymasterDevice.hal é:

generateKey(vec<KeyParameter> keyParams)
        generates(ErrorCode error, vec<uint8_t> keyBlob,
                  KeyCharacteristics keyCharacteristics);

Isso é o equivalente ao seguinte do HAL keymaster2:

keymaster_error_t (*generate_key)(
        const struct keymaster2_device* dev,
        const keymaster_key_param_set_t* params,
        keymaster_key_blob_t* key_blob,
        keymaster_key_characteristics_t* characteristics);

Na versão HIDL, o argumento dev é removido, porque está implícito. O argumento params não é mais uma estrutura contendo um ponteiro que faz referência a uma matriz de objetos key_parameter_t , mas um vec (vetor) contendo objetos KeyParameter . Os valores de retorno são listados na cláusula " generates ", incluindo um vetor de valores uint8_t para o blob de chave.

O método virtual C ++ gerado pelo compilador HIDL é:

Return<void> generateKey(const hidl_vec<KeyParameter>& keyParams,
                         generateKey_cb _hidl_cb) override;

Onde generate_cb é um ponteiro de função definido como:

std::function<void(ErrorCode error, const hidl_vec<uint8_t>& keyBlob,
                   const KeyCharacteristics& keyCharacteristics)>

Ou seja, generate_cb é uma função que obtém os valores de retorno listados na cláusula generate. A classe de implementação HAL substitui este método generateKey e chama o ponteiro de função generate_cb para retornar o resultado da operação ao chamador. Observe que a chamada do ponteiro de função é síncrona . O chamador chama generateKey e generateKey chama o ponteiro de função fornecido, que é executado até a conclusão, retornando o controle para a implementação generateKey , que então retorna ao chamador.

Para obter um exemplo detalhado, consulte a implementação padrão em hardware/interfaces/keymaster/3.0/default/KeymasterDevice.cpp . A implementação padrão fornece compatibilidade com versões anteriores para dispositivos com HALS keymaster0, keymaster1 ou keymaster2 de estilo antigo.