O subsistema Gatekeeper realiza a autenticação de padrão/senha do dispositivo em um ambiente de execução confiável (TEE). O Gatekeeper registra e verifica senhas usando uma chave secreta protegida por hardware. Além disso, o Gatekeeper limita as tentativas consecutivas de verificação com falha e precisa recusar solicitações de serviço com base em um tempo limite e um número de tentativas consecutivas com falha.
Quando os usuários verificam as senhas, o Gatekeeper emite um token de autenticação assinado com uma chave HMAC por inicialização que está disponível apenas para componentes seguros. Esse token é enviado para o Keystore com suporte de hardware. Ou seja, um token de autenticação do Gatekeeper notifica o Keystore de que as chaves vinculadas à autenticação (por exemplo, chaves criadas por apps) podem ser usadas por apps.
Arquitetura
O Gatekeeper envolve três componentes principais:
gatekeeperd
(daemon Gatekeeper): um serviço Binder em C++ no Android que contém lógica independente da plataforma e implementa a interfaceIGateKeeperService
AIDL, com base em uma implementação específica do fornecedor deIGatekeeper
.- Serviço da camada de abstração de hardware (HAL) do Gatekeeper: uma implementação específica do fornecedor da interface AIDL
IGatekeeper
. Esse serviço HAL é executado no Android, mas a funcionalidade principal do Gatekeeper precisa ser executada em um ambiente seguro. Por isso, ele geralmente se comunica com a TA do Gatekeeper. - Aplicativo confiável (TA) do Gatekeeper: uma implementação específica do fornecedor que é executada no TEE e realiza a verificação real de senha ou padrão.
O LockSettingsService
faz uma solicitação (pelo Binder) que
chega ao daemon gatekeeperd
no SO Android. O daemon
gatekeeperd
faz uma solicitação do
serviço HAL IGatekeeper
, que por sua vez alcança o
TA Gatekeeper correspondente no TEE:

Figura 1. Fluxo de dados de alto nível para autenticação pelo GateKeeper.
O daemon gatekeeperd
dá às APIs do framework Android acesso
à HAL e participa da geração de relatórios de autenticações
de dispositivos para o Keystore.
O daemon gatekeeperd
é executado em um processo próprio e separado do
servidor do sistema.
Implementação da HAL
O daemon gatekeeperd
usa a HAL IGatekeeper
para
interagir com a TA do Gatekeeper subjacente para autenticação de senha. A implementação da TA do Gatekeeper precisa ser capaz de assinar (registrar) e verificar blobs. Espera-se que todas as implementações sigam o formato padrão do token de autenticação (HardwareAuthToken
) gerado em cada verificação de senha bem-sucedida. Para detalhes sobre o conteúdo e a semântica do HardwareAuthToken
, consulte a definição de
HardwareAuthToken.aidl
.
As implementações do fornecedor do HAL IGatekeeper
precisam implementar as funções enroll
e verify
:
- O método
enroll
usa um blob de senha, assina e retorna a assinatura como um identificador. O blob retornado (de uma chamada paraenroll
) precisa ter a estrutura mostrada emsystem/gatekeeper/include/gatekeeper/password_handle.h
. - A função
verify
precisa comparar a assinatura produzida pela senha fornecida e garantir que ela corresponda ao identificador de senha registrada.
A chave usada para inscrição e verificação nunca pode mudar e precisa ser derivada novamente a cada inicialização do dispositivo.
Trusty e outras implementações
O sistema operacional Trusty é o SO confiável de código aberto do Google para ambientes TEE e contém uma implementação aprovada do Gatekeeper. No entanto, qualquer SO TEE pode implementar o Gatekeeper, desde que o TEE tenha acesso a uma chave persistente com suporte de hardware e um relógio seguro e monotônico que funcione em suspensão.
O Trusty usa um sistema IPC interno para comunicar um segredo compartilhado diretamente entre o KeyMint (antes Keymaster) e a implementação do Gatekeeper no Trusty (o Trusty Gatekeeper). Essa chave secreta compartilhada é usada para assinar AuthTokens enviados ao Keystore para fornecer atestados de verificação de senha. O Trusty Gatekeeper solicita a chave do KeyMint para cada uso e não persiste nem armazena em cache o valor. As implementações podem compartilhar esse secret de qualquer maneira que não comprometa a segurança.
A chave HMAC usada para registrar e verificar senhas é derivada e mantida apenas no Gatekeeper.
O Android oferece uma implementação genérica do Gatekeeper em C++ que exige apenas a adição de rotinas específicas do dispositivo para ser concluída. A implementação do Trusty é baseada nisso. Para implementar um Gatekeeper de TEE com
código específico do dispositivo para seu TEE, consulte as funções e os comentários
em system/gatekeeper/include/gatekeeper/gatekeeper.h
. As principais responsabilidades de uma implementação em conformidade incluem:
- Obediência à HAL
IGatekeeper
. - Os tokens de autenticação retornados precisam ser formatados de acordo com a especificação
HardwareAuthToken
(descrita em Autenticação). - O Gatekeeper do TEE precisa compartilhar uma chave HMAC com o KeyMint, solicitando a chave por um IPC do TEE sob demanda ou mantendo um cache válido do valor em todos os momentos.
IDs de segurança do usuário (SIDs)
Um SID de usuário é a representação de um usuário no TEE (sem conexão forte com um ID de usuário do Android). O SID é gerado com um gerador de números pseudorrandômicos (PRNG) criptográfico sempre que um usuário registra uma nova senha sem informar uma anterior. Isso é conhecido como um novo registro não confiável e normalmente acontece apenas quando um usuário define uma senha ou um padrão pela primeira vez.
Um novo registro confiável ocorre quando um usuário fornece uma senha válida e anterior, como ao mudar a senha. Nesse caso, o SID do usuário é migrado para o novo identificador de senha, conservando as chaves vinculadas a ele.
O SID do usuário é incluído na autenticação HMAC com a senha no identificador de senha quando a senha é registrada.
Os SIDs de usuário são incluídos no HardwareAuthToken
retornado pela função verify()
e associados a todas as chaves do Keystore vinculadas à autenticação. Para mais detalhes sobre o formato HardwareAuthToken
e o Keystore, consulte Autenticação.
Como uma chamada não confiável para a função enroll()
muda o SID do usuário, a chamada torna as chaves vinculadas a essa senha
inúteis. Os invasores podem mudar a senha do dispositivo se controlarem o sistema operacional Android, mas destroem as chaves sensíveis protegidas por root no processo.
Limitação de solicitações
O Gatekeeper precisa ser capaz de limitar com segurança as tentativas de força bruta em uma credencial de usuário. Como mostrado
em GatekeeperVerifyResponse.aidl
,
a HAL permite retornar um tempo limite em milissegundos. O tempo limite informa
ao cliente para não chamar o Gatekeeper novamente até que o tempo limite tenha decorrido.
O Gatekeeper não deve atender solicitações se houver um tempo limite pendente.
O Gatekeeper precisa gravar um contador de falhas antes de verificar a senha de um usuário. Se a verificação de senha for bem-sucedida, o contador de falhas será limpo. Isso evita ataques que impedem a limitação ao desativar o MMC incorporado (eMMC) após emitir uma chamada verify
. A função enroll
também verifica a senha do usuário (se fornecida) e precisa ser limitada da mesma forma.
Se o dispositivo for compatível, é altamente recomendável que o contador de falhas seja gravado no armazenamento seguro. Se o dispositivo não for compatível com criptografia baseada em arquivo ou se o armazenamento seguro for muito lento, as implementações poderão usar o bloco de memória protegida contra repetição (RPMB, na sigla em inglês) diretamente.