A camada de abstração de hardware (HAL, na sigla em inglês) do Weaver
(IWeaver.aidl),
introduzida no Android 8.1, oferece uma interface segura para autenticação do usuário
com o fator de conhecimento da tela de bloqueio (LSKF, na sigla em inglês), como PIN, padrão e senha.
O Weaver substitui a funcionalidade de verificação de LSKF do Gatekeeper. No entanto, o Gatekeeper ainda é usado para gerar tokens de autenticação de hardware.
No Android 9 e versões mais recentes, CDD 9.11.2 exige que os dispositivos compatíveis com o StrongBox ofereçam hardware seguro dedicado que ofereça suporte à autenticação segura do usuário. A implementação da HAL do Weaver usando esse hardware seguro atende ao requisito de "autenticação segura do usuário".
Em dispositivos sem um elemento de segurança (SE, na sigla em inglês)dedicado, o Weaver ainda pode ser implementado em um ambiente de execução confiável (TEE, na sigla em inglês), como o Trusty.
Componentes
O Weaver consiste em três componentes:
- Interface AIDL do Weaver (
IWeaver): a especificação formal da HAL. O Android 13 e versões anteriores usavam HIDL em vez de AIDL. - Serviço da camada de abstração de hardware (HAL, na sigla em inglês) do Weaver:
um processo do Android específico do fornecedor que implementa a interface
IWeaver. - Aplicativo confiável (TA, na sigla em inglês) do Weaver: a lógica principal em execução em um ambiente seguro. Ele faz a verificação de LSKF e aplica a limitação de taxa. O serviço HAL se comunica com o TA usando um canal seguro específico da implementação.
Interface
A interface do Weaver apresenta uma matriz de tamanho fixo de slots persistentes, cada um contendo uma chave e um valor de tamanho fixo. Cada slot é identificado pelo ID, um número inteiro no intervalo [0, numSlots - 1]. O valor de um slot só pode ser acessado quando uma chave correspondente à chave armazenada é fornecida.
A interface do Weaver consiste em:
getConfig(): recupera o número de slots, o tamanho da chave e o tamanho do valor com suporte da implementação.write(): substitui o slot especificado por um novo par de chave-valor. Essa operação é atômica e torna os dados anteriores permanentemente irrecuperáveis (exclusão segura).read(): tenta recuperar o valor do slot especificado. Isso só é possível quando o tempo limite de limitação de taxa (aplicado pelo TA) não está ativo e a chave fornecida corresponde exatamente à chave armazenada.
Para a especificação completa da interface, consulte
IWeaver.aidl.
Uso pelo Android
Quando uma implementação do Weaver está disponível, o LockSettingsService no servidor do sistema Android a usa para proteger os dados do usuário. Para cada usuário no dispositivo, o LockSettingsService gerencia um slot do Weaver:
- Chave de slot (
weaverKey): um hash do LSKF do usuário. Se o usuário não tiver um bloqueio de tela, uma string padrão será usada. - Valor do slot (
weaverSecret): um segredo criptográfico de alta entropia, gerado aleatoriamente.
O weaverSecret foi projetado para ser recuperado apenas por:
- Fornecer a
weaverKeycorreta ao TA do Weaver na sua política de limitação de taxa. - Comprometer o ambiente seguro em que o TA do Weaver é executado. Isso é muito difícil.
O LockSettingsService usa weaverKey e weaverSecret para criptografar a senha sintética do usuário. Como a
senha sintética protege o armazenamento criptografado por credenciais (CE, na sigla em inglês) do usuário para
criptografia baseada em arquivos (FBE, na sigla em inglês)
e as
chaves vinculadas à autenticação do usuário no Android Keystore,
os dados permanecem inacessíveis até que o Weaver libere o segredo.
Weaver x Gatekeeper
Historicamente, a
HAL do Gatekeeper
desempenhava duas funções distintas em uma única chamada verify():
- Verificação: verificação do LSKF, com limitação de taxa aplicada pelo TEE.
- Atestado: emissão de um
HardwareAuthTokenpara notificar o KeyMint (anteriormente Keymaster) de que a autenticação de LSKF foi bem-sucedida.
Por que a mudança para o Weaver?
Com a introdução de tokens de redefinição de
senha segura no Android 8.1, a "senha sintética" se tornou o
principal segredo criptográfico. As duas funções descritas acima agora são processadas por
registros separados do Gatekeeper, um para o LSKF em userId + 100000
e outro para a senha sintética em userId.
O Weaver foi introduzido para assumir a primeira função, usando uma interface HAL mais simples com suporte a implementações baseadas em elementos de segurança (SE, na sigla em inglês).
| Recurso | Weaver | Gatekeeper |
|---|---|---|
| Exclusão segura | A exclusão segura é necessária e fácil de implementar porque a interface usa um número fixo de slots de tamanho fixo. | A exclusão segura não é necessária e é difícil de implementar porque a interface oferece suporte a um número ilimitado de registros. |
| Hardware | Otimizado para SEs, mas também funciona em TEEs. | Efetivamente apenas TEE. A implementação em um SE não oferece um benefício de segurança com o design atual. |
| Tratamento de erros | Códigos de erro mais claros | Códigos de erro ambíguos. Como resultado, a tela de bloqueio não diferencia entre LSKFs incorretos e falhas não relacionadas. |
| Atomicidade | O código em LockSettingsService que usa o Weaver executa
mudanças de LSKF de forma atômica. Novos dados são gravados em um novo slot do Weaver, e
o slot antigo é apagado apenas quando é seguro fazer isso. |
O código em LockSettingsService que usa o Gatekeeper
não executa mudanças de LSKF de forma atômica. Todos os dados do usuário podem ser perdidos se
algo der errado enquanto o LSKF estiver sendo alterado. |
Código de referência
O código de referência para implementações do Weaver em elementos seguros compatíveis com ISO/IEC7816-4 está disponível no AOSP:
external/libese/.
Teste
Para validar uma implementação do Weaver, use
VtsHalWeaverTargetTest:
atest VtsHalWeaverTargetTest
ou
vts-tradefed run vts -m VtsHalWeaverTargetTest