Criptografia baseada em arquivo

O Android 7.0 e superior oferece suporte à criptografia baseada em arquivo (FBE). A criptografia baseada em arquivo permite que diferentes arquivos sejam criptografados com diferentes chaves que podem ser desbloqueadas independentemente.

Este artigo descreve como habilitar a criptografia baseada em arquivo em novos dispositivos e como os aplicativos do sistema podem usar as APIs de inicialização direta para oferecer aos usuários a melhor e mais segura experiência possível.

Todos os dispositivos lançados com Android 10 e superior precisam usar criptografia baseada em arquivo.

Inicialização Direta

A criptografia baseada em arquivo habilita um novo recurso introduzido no Android 7.0 chamado Direct Boot . A inicialização direta permite que dispositivos criptografados inicializem diretamente na tela de bloqueio. Anteriormente, em dispositivos criptografados usando criptografia de disco completo (FDE), os usuários precisavam fornecer credenciais antes que qualquer dado pudesse ser acessado, impedindo que o telefone executasse todas as operações, exceto as mais básicas. Por exemplo, os alarmes não podiam operar, os serviços de acessibilidade não estavam disponíveis e os telefones não podiam receber chamadas, mas eram limitados apenas a operações básicas de discagem de emergência.

Com a introdução da criptografia baseada em arquivo (FBE) e novas APIs para tornar os aplicativos cientes da criptografia, é possível que esses aplicativos operem em um contexto limitado. Isso pode acontecer antes que os usuários forneçam suas credenciais enquanto ainda protegem as informações privadas do usuário.

Em um dispositivo habilitado para FBE, cada usuário do dispositivo tem dois locais de armazenamento disponíveis para aplicativos:

  • Armazenamento Credential Encrypted (CE), que é o local de armazenamento padrão e está disponível somente depois que o usuário desbloqueou o dispositivo.
  • Armazenamento criptografado por dispositivo (DE), que é um local de armazenamento disponível durante o modo de inicialização direta e depois que o usuário desbloqueou o dispositivo.

Essa separação torna os perfis de trabalho mais seguros porque permite que mais de um usuário seja protegido por vez, pois a criptografia não é mais baseada apenas em uma senha de inicialização.

A API de inicialização direta permite que aplicativos com reconhecimento de criptografia acessem cada uma dessas áreas. Há mudanças no ciclo de vida do aplicativo para acomodar a necessidade de notificar os aplicativos quando o armazenamento CE de um usuário é desbloqueado em resposta à primeira inserção de credenciais na tela de bloqueio ou no caso de um perfil de trabalho que fornece um desafio de trabalho . Os dispositivos que executam o Android 7.0 devem oferecer suporte a essas novas APIs e ciclos de vida, independentemente de implementarem ou não o FBE. Embora, sem FBE, o armazenamento DE e CE sempre estará no estado desbloqueado.

Uma implementação completa de criptografia baseada em arquivo nos sistemas de arquivos Ext4 e F2FS é fornecida no Android Open Source Project (AOSP) e só precisa ser habilitada em dispositivos que atendam aos requisitos. Os fabricantes que optam por usar o FBE podem querer explorar formas de otimizar o recurso com base no sistema no chip (SoC) usado.

Todos os pacotes necessários no AOSP foram atualizados para serem compatíveis com inicialização direta. No entanto, onde os fabricantes de dispositivos usam versões personalizadas desses aplicativos, eles devem garantir, no mínimo, que haja pacotes de inicialização direta que forneçam os seguintes serviços:

  • Serviços de telefonia e discador
  • Método de entrada para inserir senhas na tela de bloqueio

Exemplos e fonte

O Android fornece uma implementação de referência de criptografia baseada em arquivo, na qual vold ( system/vold ) fornece a funcionalidade para gerenciar dispositivos de armazenamento e volumes no Android. A adição do FBE fornece ao vold vários novos comandos para oferecer suporte ao gerenciamento de chaves para as chaves CE e DE de vários usuários. Além das principais alterações para usar os recursos de criptografia baseados em arquivo no kernel , muitos pacotes do sistema, incluindo a tela de bloqueio e o SystemUI, foram modificados para oferecer suporte aos recursos FBE e inicialização direta. Esses incluem:

  • AOSP Dialer (pacotes/apps/Dialer)
  • Relógio de mesa (pacotes/aplicativos/DeskClock)
  • LatinIME (pacotes/métodos de entrada/LatinIME)*
  • Aplicativo de configurações (pacotes/aplicativos/configurações)*
  • SystemUI (frameworks/base/packages/SystemUI)*

* Aplicativos do sistema que usam o atributo de manifesto defaultToDeviceProtectedStorage

Mais exemplos de aplicativos e serviços com reconhecimento de criptografia podem ser encontrados executando o comando mangrep directBootAware no diretório de estruturas ou pacotes da árvore de origem AOSP.

Dependências

Para usar a implementação AOSP do FBE com segurança, um dispositivo precisa atender às seguintes dependências:

  • Suporte de kernel para criptografia Ext4 ou criptografia F2FS.
  • Suporte Keymaster com HAL versão 1.0 ou superior. Não há suporte para Keymaster 0.3, pois não fornece os recursos necessários ou garante proteção suficiente para chaves de criptografia.
  • Keymaster/ Keystore e Gatekeeper devem ser implementados em um ambiente de execução confiável (TEE) para fornecer proteção para as chaves DE de forma que um sistema operacional não autorizado (SO personalizado instalado no dispositivo) não possa simplesmente solicitar as chaves DE.
  • Hardware Root of Trust e Verified Boot vinculados à inicialização do Keymaster são necessários para garantir que as chaves DE não sejam acessíveis por um sistema operacional não autorizado.

Implementação

Em primeiro lugar, aplicativos como despertadores, telefone e recursos de acessibilidade devem ser feitos android:directBootAware de acordo com a documentação do desenvolvedor do Direct Boot .

Suporte de kernel

O suporte de kernel para criptografia Ext4 e F2FS está disponível nos kernels comuns do Android, versão 3.18 e superior. Para ativá-lo em um kernel com versão 5.1 ou superior, use:

CONFIG_FS_ENCRYPTION=y

Para kernels mais antigos, use CONFIG_EXT4_ENCRYPTION=y se o sistema de arquivos userdata do seu dispositivo for Ext4 ou use CONFIG_F2FS_FS_ENCRYPTION=y se o sistema de arquivos userdata do seu dispositivo for F2FS.

Se o seu dispositivo suportar armazenamento adotável ou usar criptografia de metadados no armazenamento interno, habilite também as opções de configuração do kernel necessárias para criptografia de metadados conforme descrito na documentação de criptografia de metadados .

Além do suporte funcional para criptografia Ext4 ou F2FS, os fabricantes de dispositivos também devem habilitar a aceleração criptográfica para acelerar a criptografia baseada em arquivo e melhorar a experiência do usuário. Por exemplo, em dispositivos baseados em ARM64, a aceleração ARMv8 CE (Cryptography Extensions) pode ser habilitada definindo as seguintes opções de configuração do kernel:

CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y

Para melhorar ainda mais o desempenho e reduzir o uso de energia, os fabricantes de dispositivos também podem considerar a implementação de hardware de criptografia em linha , que criptografa/descriptografa os dados enquanto eles estão no caminho de/para o dispositivo de armazenamento. Os kernels comuns do Android (versão 4.14 e superior) contêm uma estrutura que permite que a criptografia em linha seja usada quando o hardware e o suporte do driver do fornecedor estão disponíveis. A estrutura de criptografia em linha pode ser habilitada definindo as seguintes opções de configuração do kernel:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

Se o seu dispositivo usa armazenamento baseado em UFS, habilite também:

CONFIG_SCSI_UFS_CRYPTO=y

Se o seu dispositivo usa armazenamento baseado em eMMC, habilite também:

CONFIG_MMC_CRYPTO=y

Ativando a criptografia baseada em arquivo

Habilitar o FBE em um dispositivo requer habilitá-lo no armazenamento interno ( userdata ). Isso também ativa automaticamente o FBE no armazenamento adotável; no entanto, o formato de criptografia no armazenamento adotável pode ser substituído, se necessário.

Armazenamento interno

O FBE é ativado adicionando a opção fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] à coluna fs_mgr_flags da linha fstab para userdata . Esta opção define o formato de criptografia no armazenamento interno. Ele contém até três parâmetros separados por dois pontos:

  • O parâmetro contents_encryption_mode define qual algoritmo criptográfico é usado para criptografar o conteúdo do arquivo. Pode ser aes-256-xts ou adiantum . Desde o Android 11, também pode ser deixado em branco para especificar o algoritmo padrão, que é aes-256-xts .
  • O parâmetro filenames_encryption_mode define qual algoritmo criptográfico é usado para criptografar nomes de arquivo. Pode ser aes-256-cts , aes-256-heh , adiantum ou aes-256-hctr2 . Se não for especificado, o padrão será aes-256-cts se contents_encryption_mode for aes-256-xts ou adiantum se contents_encryption_mode for adiantum .
  • O parâmetro flags , novidade no Android 11, é uma lista de flags separados pelo caractere + . As seguintes sinalizações são suportadas:
    • O sinalizador v1 seleciona as políticas de criptografia da versão 1; o sinalizador v2 seleciona as políticas de criptografia da versão 2. As políticas de criptografia da versão 2 usam uma função de derivação de chave mais segura e flexível. O padrão é v2 se o dispositivo foi iniciado no Android 11 ou superior (conforme determinado por ro.product.first_api_level ) ou v1 se o dispositivo foi iniciado no Android 10 ou inferior.
    • O sinalizador inlinecrypt_optimized seleciona um formato de criptografia otimizado para hardware de criptografia em linha que não lida com um grande número de chaves com eficiência. Ele faz isso derivando apenas uma chave de criptografia de conteúdo de arquivo por chave CE ou DE, em vez de uma por arquivo. A geração de IVs (vetores de inicialização) é ajustada de acordo.
    • O sinalizador emmc_optimized é semelhante ao inlinecrypt_optimized , mas também seleciona um método de geração de IV que limita os IVs a 32 bits. Este sinalizador deve ser usado apenas em hardware de criptografia em linha compatível com a especificação JEDEC eMMC v5.2 e, portanto, suporta apenas IVs de 32 bits. Em outro hardware de criptografia em linha, use inlinecrypt_optimized . Este sinalizador nunca deve ser usado em armazenamento baseado em UFS; a especificação UFS permite o uso de IVs de 64 bits.
    • Em dispositivos que oferecem suporte a chaves encapsuladas por hardware , o sinalizador wrappedkey_v0 permite o uso de chaves encapsuladas por hardware para FBE. Isso só pode ser usado em combinação com a opção de montagem inlinecrypt e o sinalizador inlinecrypt_optimized ou emmc_optimized .

Se você não estiver usando hardware de criptografia em linha, a configuração recomendada para a maioria dos dispositivos é fileencryption=aes-256-xts . Se você estiver usando hardware de criptografia em linha, a configuração recomendada para a maioria dos dispositivos é fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized (ou de forma equivalente fileencryption=::inlinecrypt_optimized ). Em dispositivos sem qualquer forma de aceleração AES, Adiantum pode ser usado em vez de AES definindo fileencryption=adiantum .

Desde o Android 14 (AOSP experimental), o AES-HCTR2 é o modo preferido de criptografia de nomes de arquivos para dispositivos com instruções de criptografia acelerada. No entanto, apenas os kernels Android mais recentes suportam AES-HCTR2. Em uma versão futura do Android, está planejado para se tornar o modo padrão para criptografia de nomes de arquivos. Se o seu kernel tiver suporte para AES-HCTR2, ele poderá ser ativado para criptografia de nomes de arquivo definindo filenames_encryption_mode como aes-256-hctr2 . No caso mais simples, isso seria feito com fileencryption=aes-256-xts:aes-256-hctr2 .

Em dispositivos iniciados com Android 10 ou inferior, fileencryption=ice também é aceito para especificar o uso do modo de criptografia de conteúdo de arquivo FSCRYPT_MODE_PRIVATE . Este modo não é implementado pelos kernels comuns do Android, mas pode ser implementado por fornecedores usando patches de kernel personalizados. O formato em disco produzido por este modo era específico do fornecedor. Em dispositivos lançados com Android 11 ou superior, esse modo não é mais permitido e um formato de criptografia padrão deve ser usado.

Por padrão, a criptografia do conteúdo do arquivo é feita usando a API de criptografia do kernel do Linux. Se você quiser usar hardware de criptografia inline, adicione também a opção de montagem inlinecrypt . Por exemplo, uma linha fstab completa pode se parecer com:

/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized

Armazenamento adotável

Desde o Android 9, o FBE e o armazenamento adotável podem ser usados ​​juntos.

A especificação da opção fileencryption fstab para userdata também ativa automaticamente a criptografia FBE e de metadados no armazenamento adotável. No entanto, você pode substituir o FBE e/ou os formatos de criptografia de metadados no armazenamento adotável definindo as propriedades em PRODUCT_PROPERTY_OVERRIDES .

Em dispositivos lançados com Android 11 ou superior, use as seguintes propriedades:

  • ro.crypto.volume.options (novo no Android 11) seleciona o formato de criptografia FBE no armazenamento adotável. Ele tem a mesma sintaxe do argumento para a opção fileencryption fstab e usa os mesmos padrões. Consulte as recomendações para fileencryption acima para saber o que usar aqui.
  • ro.crypto.volume.metadata.encryption seleciona o formato de criptografia de metadados no armazenamento adotável. Consulte a documentação de criptografia de metadados .

Em dispositivos lançados com Android 10 ou inferior, use as seguintes propriedades:

  • ro.crypto.volume.contents_mode seleciona o modo de criptografia de conteúdo. Isso é equivalente ao primeiro campo separado por dois pontos de ro.crypto.volume.options .
  • ro.crypto.volume.filenames_mode seleciona o modo de criptografia de nomes de arquivo. Isso é equivalente ao segundo campo separado por dois-pontos de ro.crypto.volume.options , exceto que o padrão em dispositivos iniciados com Android 10 ou inferior é aes-256-heh . Na maioria dos dispositivos, isso precisa ser substituído explicitamente por aes-256-cts .
  • ro.crypto.fde_algorithm e ro.crypto.fde_sector_size selecionam o formato de criptografia de metadados no armazenamento adotável. Consulte a documentação de criptografia de metadados .

Integração com o Keymaster

O Keymaster HAL deve ser iniciado como parte da classe early_hal . Isso ocorre porque o FBE exige que o Keymaster esteja pronto para lidar com solicitações na fase de inicialização post-fs-data , que é quando vold configura as chaves iniciais.

Excluindo diretórios

init aplica a chave DE do sistema a todos os diretórios de nível superior de /data , exceto os diretórios que devem ser descriptografados: o diretório que contém a própria chave DE do sistema e os diretórios que contêm os diretórios CE ou DE do usuário. As chaves de criptografia se aplicam recursivamente e não podem ser substituídas por subdiretórios.

No Android 11 e superior, a chave que init aplica aos diretórios pode ser controlada pelo encryption=<action> para o comando mkdir nos scripts init. Os possíveis valores de <action> estão documentados no README para a linguagem de inicialização do Android .

No Android 10, as ações de criptografia init foram codificadas no seguinte local:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

No Android 9 e anteriores, o local era:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

É possível adicionar exceções para impedir que certos diretórios sejam criptografados. Se forem feitas modificações desse tipo, o fabricante do dispositivo deve incluir políticas do SELinux que concedam acesso apenas aos aplicativos que precisam usar o diretório não criptografado. Isso deve excluir todos os aplicativos não confiáveis.

O único caso de uso aceitável conhecido para isso é o suporte a recursos legados de OTA.

Compatível com inicialização direta em aplicativos do sistema

Tornar os aplicativos cientes do Direct Boot

Para facilitar a migração rápida de aplicativos do sistema, há dois novos atributos que podem ser definidos no nível do aplicativo. O atributo defaultToDeviceProtectedStorage está disponível apenas para aplicativos do sistema. O atributo directBootAware está disponível para todos.

<application
    android:directBootAware="true"
    android:defaultToDeviceProtectedStorage="true">

O atributo directBootAware no nível do aplicativo é uma abreviação para marcar todos os componentes no aplicativo como tendo reconhecimento de criptografia.

O atributo defaultToDeviceProtectedStorage redireciona o local de armazenamento do aplicativo padrão para apontar para o armazenamento DE em vez de apontar para o armazenamento CE. Os aplicativos do sistema que usam esse sinalizador devem auditar cuidadosamente todos os dados armazenados no local padrão e alterar os caminhos dos dados confidenciais para usar o armazenamento CE. Os fabricantes de dispositivos que usam essa opção devem inspecionar cuidadosamente os dados que estão armazenando para garantir que não contenham informações pessoais.

Ao executar neste modo, as seguintes APIs do sistema estão disponíveis para gerenciar explicitamente um contexto apoiado pelo armazenamento CE quando necessário, que são equivalentes às suas contrapartes protegidas por dispositivo.

  • Context.createCredentialProtectedStorageContext()
  • Context.isCredentialProtectedStorage()

Suporte a vários usuários

Cada usuário em um ambiente multiusuário obtém uma chave de criptografia separada. Cada usuário recebe duas chaves: uma chave DE e uma chave CE. O usuário 0 deve fazer login no dispositivo primeiro, pois é um usuário especial. Isso é pertinente para usos de administração de dispositivos .

Os aplicativos com reconhecimento de criptografia interagem entre os usuários desta maneira: INTERACT_ACROSS_USERS e INTERACT_ACROSS_USERS_FULL permitem que um aplicativo atue em todos os usuários no dispositivo. No entanto, esses aplicativos poderão acessar apenas diretórios criptografados pela CE para usuários que já estão desbloqueados.

Um aplicativo pode interagir livremente entre as áreas DE, mas um usuário desbloqueado não significa que todos os usuários do dispositivo estejam desbloqueados. O aplicativo deve verificar esse status antes de tentar acessar essas áreas.

Cada ID do usuário do perfil de trabalho também obtém duas chaves: DE e CE. Quando o desafio de trabalho é cumprido, o usuário do perfil é desbloqueado e o Keymaster (em TEE) pode fornecer a chave TEE do perfil.

Manipulando atualizações

A partição de recuperação não consegue acessar o armazenamento protegido por DE na partição de dados do usuário. Os dispositivos que implementam o FBE são altamente recomendados para oferecer suporte a OTA usando atualizações do sistema A/B . Como o OTA pode ser aplicado durante a operação normal, não há necessidade de recuperação para acessar os dados na unidade criptografada.

Ao usar uma solução OTA herdada, que requer recuperação para acessar o arquivo OTA na partição userdata :

  1. Crie um diretório de nível superior (por exemplo misc_ne ) na partição userdata .
  2. Configure esse diretório de nível superior para não ser criptografado (consulte Excluindo diretórios ).
  3. Crie um diretório dentro do diretório de nível superior para manter os pacotes OTA.
  4. Adicione uma regra SELinux e contextos de arquivo para controlar o acesso a este diretório e seu conteúdo. Somente o processo ou aplicativos que recebem atualizações OTA devem ser capazes de ler e gravar neste diretório. Nenhum outro aplicativo ou processo deve ter acesso a esse diretório.

Validação

Para garantir que a versão implementada do recurso funcione conforme pretendido, primeiro execute os muitos testes de criptografia CTS, como DirectBootHostTest e EncryptionTest .

Se o dispositivo estiver executando o Android 11 ou superior, execute também vts_kernel_encryption_test :

atest vts_kernel_encryption_test

ou:

vts-tradefed run vts -m vts_kernel_encryption_test

Além disso, os fabricantes de dispositivos podem realizar os seguintes testes manuais. Em um dispositivo com FBE ativado:

  • Verifique se ro.crypto.state existe
    • Verifique se ro.crypto.state está criptografado
  • Verifique se ro.crypto.type existe
    • Verifique se ro.crypto.type está definido como file

Além disso, os testadores podem inicializar uma instância userdebug com uma tela de bloqueio definida no usuário principal. Em seguida, adb shell no dispositivo e use su para se tornar root. Certifique-se de /data/data contenha nomes de arquivos criptografados; se não, algo está errado.

Os fabricantes de dispositivos também são encorajados a explorar a execução dos testes upstream do Linux para fscrypt em seus dispositivos ou kernels. Esses testes fazem parte do conjunto de testes do sistema de arquivos xfstests. No entanto, esses testes upstream não são oficialmente suportados pelo Android.

Detalhes da implementação do AOSP

Esta seção fornece detalhes sobre a implementação do AOSP e descreve como funciona a criptografia baseada em arquivo. Não deve ser necessário que os fabricantes de dispositivos façam alterações aqui para usar o FBE e o Direct Boot em seus dispositivos.

criptografia fscrypt

A implementação AOSP usa criptografia "fscrypt" (suportada por ext4 e f2fs) no kernel e normalmente é configurada para:

  • Criptografe o conteúdo do arquivo com AES-256 no modo XTS
  • Criptografe nomes de arquivos com AES-256 no modo CBC-CTS

A criptografia Adiantum também é suportada. Quando a criptografia Adiantum está habilitada, o conteúdo e os nomes dos arquivos são criptografados com Adiantum.

fscrypt oferece suporte a duas versões de políticas de criptografia: versão 1 e versão 2. A versão 1 está obsoleta e os requisitos de CDD para dispositivos iniciados com Android 11 e superior são compatíveis apenas com a versão 2. As políticas de criptografia da versão 2 usam HKDF-SHA512 para derivar o real chaves de criptografia das chaves fornecidas pelo espaço do usuário.

Para obter mais informações sobre fscrypt, consulte a documentação do kernel upstream .

Classes de armazenamento

A tabela a seguir lista as chaves FBE e os diretórios que elas protegem com mais detalhes:

classe de armazenamento Descrição Diretórios
Sistema DE Dados criptografados do dispositivo não vinculados a um usuário específico /data/system , /data/app e vários outros subdiretórios de /data
Por inicialização Arquivos de sistema efêmeros que não precisam sobreviver a uma reinicialização /data/per_boot
Usuário CE (interno) Dados criptografados por credencial por usuário no armazenamento interno
  • /data/data (alias de /data/user/0 )
  • /data/media/${user_id}
  • /data/misc_ce/${user_id}
  • /data/system_ce/${user_id}
  • /data/user/${user_id}
  • /data/vendor_ce/${user_id}
Usuário DE (interno) Dados criptografados por dispositivo por usuário no armazenamento interno
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
Usuário CE (adotável) Dados criptografados por credencial por usuário em armazenamento adotável
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
Usuário DE (adotável) Dados criptografados por dispositivo por usuário em armazenamento adotável
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

Armazenamento e proteção de chaves

Todas as chaves FBE são gerenciadas por vold e armazenadas criptografadas em disco, exceto a chave por inicialização que não é armazenada. A tabela a seguir lista os locais nos quais as várias chaves FBE são armazenadas:

Tipo de chave localização chave Classe de armazenamento do local da chave
Tecla DE do sistema /data/unencrypted Não criptografado
Teclas CE do usuário (internas) /data/misc/vold/user_keys/ce/${user_id} Sistema DE
Teclas DE (internas) do usuário /data/misc/vold/user_keys/de/${user_id} Sistema DE
Chaves CE do usuário (adotáveis) /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} Usuário CE (interno)
Chaves DE do usuário (adotáveis) /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} Usuário DE (interno)

Conforme mostrado na tabela anterior, a maioria das chaves FBE são armazenadas em diretórios criptografados por outra chave FBE. As chaves não podem ser desbloqueadas até que a classe de armazenamento que as contém seja desbloqueada.

vold também aplica uma camada de criptografia a todas as chaves FBE. Todas as chaves além das chaves CE para armazenamento interno são criptografadas com AES-256-GCM usando sua própria chave Keystore que não é exposta fora do TEE. Isso garante que as chaves FBE não possam ser desbloqueadas, a menos que um sistema operacional confiável seja inicializado, conforme aplicado pelo Verified Boot . A resistência à reversão também é solicitada na chave Keystore, o que permite que as chaves FBE sejam excluídas com segurança em dispositivos nos quais o Keymaster oferece suporte à resistência à reversão. Como um fallback de melhor esforço para quando a resistência à reversão não estiver disponível, o hash SHA-512 de 16384 bytes aleatórios armazenados no arquivo secdiscardable armazenado junto com a chave é usado como a marca de ID do aplicativo da chave Keystore. Todos esses bytes precisam ser recuperados para recuperar uma chave FBE.

As chaves CE para armazenamento interno recebem um nível mais forte de proteção que garante que elas não possam ser desbloqueadas sem conhecer o fator de conhecimento da tela de bloqueio (LSKF) (PIN, padrão ou senha) do usuário, um token de redefinição de senha segura ou ambos do lado do cliente e chaves do lado do servidor para uma operação Resume-on-Reboot . Tokens de redefinição de senha só podem ser criados para perfis de trabalho e dispositivos totalmente gerenciados .

Para conseguir isso, vold criptografa cada chave CE para armazenamento interno usando uma chave AES-256-GCM derivada da senha sintética do usuário. A senha sintética é um segredo criptográfico imutável de alta entropia gerado aleatoriamente para cada usuário. LockSettingsService em system_server gerencia a senha sintética e as formas pelas quais ela é protegida.

Para proteger a senha sintética com o LSKF, LockSettingsService primeiro estende o LSKF passando-o por scrypt , visando um tempo de cerca de 25 ms e um uso de memória de cerca de 2 MiB. Como os LSKFs geralmente são curtos, essa etapa geralmente não oferece muita segurança. A principal camada de segurança é o Secure Element (SE) ou limitação de taxa aplicada por TEE descrita abaixo.

Se o dispositivo tiver um Secure Element (SE), o LockSettingsService mapeia o LSKF estendido para um segredo aleatório de alta entropia armazenado no SE usando o Weaver HAL . LockSettingsService então criptografa a senha sintética duas vezes: primeiro com uma chave de software derivada do LSKF estendido e do segredo do Weaver e, segundo, com uma chave Keystore não vinculada à autenticação. Isso fornece limitação de taxa aplicada por SE de estimativas de LSKF.

Se o dispositivo não tiver um SE, o LockSettingsService usará o LSKF estendido como uma senha do Gatekeeper . LockSettingsService então criptografa a senha sintética duas vezes: primeiro com uma chave de software derivada do LSKF estendido e o hash de um arquivo secdescartável e, segundo, com uma chave Keystore vinculada à inscrição do Gatekeeper. Isso fornece limitação de taxa aplicada por TEE de estimativas de LSKF.

Quando o LSKF é alterado, LockSettingsService exclui todas as informações associadas à vinculação da senha sintética ao antigo LSKF. Em dispositivos que suportam Weaver ou chaves Keystore resistentes à reversão, isso garante a exclusão segura da ligação antiga. Por esse motivo, as proteções descritas aqui são aplicadas mesmo quando o usuário não possui um LSKF.

,

O Android 7.0 e superior oferece suporte à criptografia baseada em arquivo (FBE). A criptografia baseada em arquivo permite que diferentes arquivos sejam criptografados com diferentes chaves que podem ser desbloqueadas independentemente.

Este artigo descreve como habilitar a criptografia baseada em arquivo em novos dispositivos e como os aplicativos do sistema podem usar as APIs de inicialização direta para oferecer aos usuários a melhor e mais segura experiência possível.

Todos os dispositivos lançados com Android 10 e superior precisam usar criptografia baseada em arquivo.

Inicialização Direta

A criptografia baseada em arquivo habilita um novo recurso introduzido no Android 7.0 chamado Direct Boot . A inicialização direta permite que dispositivos criptografados inicializem diretamente na tela de bloqueio. Anteriormente, em dispositivos criptografados usando criptografia de disco completo (FDE), os usuários precisavam fornecer credenciais antes que qualquer dado pudesse ser acessado, impedindo que o telefone executasse todas as operações, exceto as mais básicas. Por exemplo, os alarmes não podiam operar, os serviços de acessibilidade não estavam disponíveis e os telefones não podiam receber chamadas, mas eram limitados apenas a operações básicas de discagem de emergência.

Com a introdução da criptografia baseada em arquivo (FBE) e novas APIs para tornar os aplicativos cientes da criptografia, é possível que esses aplicativos operem em um contexto limitado. Isso pode acontecer antes que os usuários forneçam suas credenciais enquanto ainda protegem as informações privadas do usuário.

Em um dispositivo habilitado para FBE, cada usuário do dispositivo tem dois locais de armazenamento disponíveis para aplicativos:

  • Armazenamento Credential Encrypted (CE), que é o local de armazenamento padrão e está disponível somente depois que o usuário desbloqueou o dispositivo.
  • Armazenamento criptografado por dispositivo (DE), que é um local de armazenamento disponível durante o modo de inicialização direta e depois que o usuário desbloqueou o dispositivo.

Essa separação torna os perfis de trabalho mais seguros porque permite que mais de um usuário seja protegido por vez, pois a criptografia não é mais baseada apenas em uma senha de inicialização.

A API de inicialização direta permite que aplicativos com reconhecimento de criptografia acessem cada uma dessas áreas. Há mudanças no ciclo de vida do aplicativo para acomodar a necessidade de notificar os aplicativos quando o armazenamento CE de um usuário é desbloqueado em resposta à primeira inserção de credenciais na tela de bloqueio ou no caso de perfil de trabalho fornecendo um desafio de trabalho . Os dispositivos que executam o Android 7.0 devem oferecer suporte a essas novas APIs e ciclos de vida, independentemente de implementarem ou não o FBE. Embora, sem FBE, o armazenamento DE e CE sempre estará no estado desbloqueado.

Uma implementação completa de criptografia baseada em arquivo nos sistemas de arquivos Ext4 e F2FS é fornecida no Android Open Source Project (AOSP) e só precisa ser habilitada em dispositivos que atendam aos requisitos. Os fabricantes que optam por usar o FBE podem querer explorar formas de otimizar o recurso com base no sistema no chip (SoC) usado.

Todos os pacotes necessários no AOSP foram atualizados para serem compatíveis com inicialização direta. No entanto, onde os fabricantes de dispositivos usam versões personalizadas desses aplicativos, eles devem garantir, no mínimo, que haja pacotes de inicialização direta que forneçam os seguintes serviços:

  • Serviços de telefonia e discador
  • Método de entrada para inserir senhas na tela de bloqueio

Exemplos e fonte

O Android fornece uma implementação de referência de criptografia baseada em arquivo, na qual vold ( system/vold ) fornece a funcionalidade para gerenciar dispositivos de armazenamento e volumes no Android. A adição do FBE fornece ao vold vários novos comandos para oferecer suporte ao gerenciamento de chaves para as chaves CE e DE de vários usuários. Além das principais alterações para usar os recursos de criptografia baseados em arquivo no kernel , muitos pacotes do sistema, incluindo a tela de bloqueio e o SystemUI, foram modificados para oferecer suporte aos recursos FBE e inicialização direta. Esses incluem:

  • AOSP Dialer (pacotes/apps/Dialer)
  • Relógio de mesa (pacotes/aplicativos/DeskClock)
  • LatinIME (pacotes/métodos de entrada/LatinIME)*
  • Aplicativo de configurações (pacotes/aplicativos/configurações)*
  • SystemUI (frameworks/base/packages/SystemUI)*

* Aplicativos do sistema que usam o atributo de manifesto defaultToDeviceProtectedStorage

Mais exemplos de aplicativos e serviços com reconhecimento de criptografia podem ser encontrados executando o comando mangrep directBootAware no diretório de estruturas ou pacotes da árvore de origem AOSP.

Dependências

Para usar a implementação AOSP do FBE com segurança, um dispositivo precisa atender às seguintes dependências:

  • Suporte de kernel para criptografia Ext4 ou criptografia F2FS.
  • Suporte Keymaster com HAL versão 1.0 ou superior. Não há suporte para Keymaster 0.3, pois não fornece os recursos necessários ou garante proteção suficiente para chaves de criptografia.
  • Keymaster/ Keystore e Gatekeeper devem ser implementados em um ambiente de execução confiável (TEE) para fornecer proteção para as chaves DE de forma que um sistema operacional não autorizado (SO personalizado instalado no dispositivo) não possa simplesmente solicitar as chaves DE.
  • Hardware Root of Trust e Verified Boot vinculados à inicialização do Keymaster são necessários para garantir que as chaves DE não sejam acessíveis por um sistema operacional não autorizado.

Implementação

Em primeiro lugar, aplicativos como despertadores, telefone e recursos de acessibilidade devem ser feitos android:directBootAware de acordo com a documentação do desenvolvedor do Direct Boot .

Suporte de kernel

O suporte de kernel para criptografia Ext4 e F2FS está disponível nos kernels comuns do Android, versão 3.18 e superior. Para ativá-lo em um kernel com versão 5.1 ou superior, use:

CONFIG_FS_ENCRYPTION=y

Para kernels mais antigos, use CONFIG_EXT4_ENCRYPTION=y se o sistema de arquivos userdata do seu dispositivo for Ext4 ou use CONFIG_F2FS_FS_ENCRYPTION=y se o sistema de arquivos userdata do seu dispositivo for F2FS.

Se o seu dispositivo suportar armazenamento adotável ou usar criptografia de metadados no armazenamento interno, habilite também as opções de configuração do kernel necessárias para criptografia de metadados, conforme descrito na documentação de criptografia de metadados .

Além do suporte funcional para criptografia Ext4 ou F2FS, os fabricantes de dispositivos também devem habilitar a aceleração criptográfica para acelerar a criptografia baseada em arquivo e melhorar a experiência do usuário. Por exemplo, em dispositivos baseados em ARM64, a aceleração ARMv8 CE (Cryptography Extensions) pode ser habilitada definindo as seguintes opções de configuração do kernel:

CONFIG_CRYPTO_AES_ARM64_CE_BLK=y
CONFIG_CRYPTO_SHA2_ARM64_CE=y

To further improve performance and reduce power usage, device manufacturers may also consider implementing inline encryption hardware , which encrypts/decrypts the data while it is on the way to/from the storage device. The Android common kernels (version 4.14 and higher) contain a framework that allows inline encryption to be used when hardware and vendor driver support is available. The inline encryption framework can be enabled by setting the following kernel configuration options:

CONFIG_BLK_INLINE_ENCRYPTION=y
CONFIG_FS_ENCRYPTION=y
CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y

If your device uses UFS-based storage, also enable:

CONFIG_SCSI_UFS_CRYPTO=y

If your device uses eMMC-based storage, also enable:

CONFIG_MMC_CRYPTO=y

Enabling file-based encryption

Enabling FBE on a device requires enabling it on the internal storage ( userdata ). This also automatically enables FBE on adoptable storage; however, the encryption format on adoptable storage may be overridden if necessary.

Internal storage

FBE is enabled by adding the option fileencryption=contents_encryption_mode[:filenames_encryption_mode[:flags]] to the fs_mgr_flags column of the fstab line for userdata . This option defines the encryption format on internal storage. It contains up to three colon-separated parameters:

  • The contents_encryption_mode parameter defines which cryptographic algorithm is used to encrypt file contents. It can be either aes-256-xts or adiantum . Since Android 11 it can also be left empty to specify the default algorithm, which is aes-256-xts .
  • The filenames_encryption_mode parameter defines which cryptographic algorithm is used to encrypt file names. It can be either aes-256-cts , aes-256-heh , adiantum , or aes-256-hctr2 . If not specified, it defaults to aes-256-cts if contents_encryption_mode is aes-256-xts , or to adiantum if contents_encryption_mode is adiantum .
  • The flags parameter, new in Android 11, is a list of flags separated by the + character. The following flags are supported:
    • The v1 flag selects version 1 encryption policies; the v2 flag selects version 2 encryption policies. Version 2 encryption policies use a more secure and flexible key derivation function . The default is v2 if the device launched on Android 11 or higher (as determined by ro.product.first_api_level ), or v1 if the device launched on Android 10 or lower.
    • The inlinecrypt_optimized flag selects an encryption format that is optimized for inline encryption hardware that doesn't handle large numbers of keys efficiently. It does this by deriving just one file contents encryption key per CE or DE key, rather than one per file. The generation of IVs (initialization vectors) is adjusted accordingly.
    • The emmc_optimized flag is similar to inlinecrypt_optimized , but it also selects an IV generation method that limits IVs to 32 bits. This flag should only be used on inline encryption hardware that is compliant with the JEDEC eMMC v5.2 specification and therefore supports only 32-bit IVs. On other inline encryption hardware, use inlinecrypt_optimized instead. This flag should never be used on UFS-based storage; the UFS specification allows the use of 64-bit IVs.
    • On devices that support hardware-wrapped keys , the wrappedkey_v0 flag enables the use of hardware-wrapped keys for FBE. This can only be used in combination with the inlinecrypt mount option, and either the inlinecrypt_optimized or emmc_optimized flag.

If you aren't using inline encryption hardware the recommended setting for most devices is fileencryption=aes-256-xts . If you are using inline encryption hardware the recommended setting for most devices is fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized (or equivalently fileencryption=::inlinecrypt_optimized ). On devices without any form of AES acceleration, Adiantum may be used instead of AES by setting fileencryption=adiantum .

Since Android 14 (AOSP experimental), AES-HCTR2 is the preferred mode of filenames encryption for devices with accelerated cryptography instructions. However, only newer Android kernels support AES-HCTR2. In a future Android release, it is planned to become the default mode for filenames encryption. If your kernel has AES-HCTR2 support, it can be enabled for filenames encryption by setting filenames_encryption_mode to aes-256-hctr2 . In the simplest case this would be done with fileencryption=aes-256-xts:aes-256-hctr2 .

On devices that launched with Android 10 or lower, fileencryption=ice is also accepted to specify the use of the FSCRYPT_MODE_PRIVATE file contents encryption mode. This mode is unimplemented by the Android common kernels, but it could be implemented by vendors using custom kernel patches. The on-disk format produced by this mode was vendor-specific. On devices launching with Android 11 or higher, this mode is no longer allowed and a standard encryption format must be used instead.

By default, file contents encryption is done using the Linux kernel's cryptography API. If you want to use inline encryption hardware instead, also add the inlinecrypt mount option. For example, a full fstab line might look like:

/dev/block/by-name/userdata /data f2fs nodev,noatime,nosuid,errors=panic,inlinecrypt wait,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized

Adoptable storage

Since Android 9, FBE and adoptable storage can be used together.

Specifying the fileencryption fstab option for userdata also automatically enables both FBE and metadata encryption on adoptable storage. However, you may override the FBE and/or metadata encryption formats on adoptable storage by setting properties in PRODUCT_PROPERTY_OVERRIDES .

On devices that launched with Android 11 or higher, use the following properties:

  • ro.crypto.volume.options (new in Android 11) selects the FBE encryption format on adoptable storage. It has the same syntax as the argument to the fileencryption fstab option, and it uses the same defaults. See the recommendations for fileencryption above for what to use here.
  • ro.crypto.volume.metadata.encryption selects the metadata encryption format on adoptable storage. See the metadata encryption documentation .

On devices that launched with Android 10 or lower, use the following properties:

  • ro.crypto.volume.contents_mode selects the contents encryption mode. This is equivalent to the first colon-separated field of ro.crypto.volume.options .
  • ro.crypto.volume.filenames_mode selects the filenames encryption mode. This is equivalent to the second colon-separated field of ro.crypto.volume.options , except that the default on devices that launched with Android 10 or lower is aes-256-heh . On most devices, this needs to be explicitly overridden to aes-256-cts .
  • ro.crypto.fde_algorithm and ro.crypto.fde_sector_size select the metadata encryption format on adoptable storage. See the metadata encryption documentation .

Integrating with Keymaster

The Keymaster HAL should be started as part of the early_hal class. This is because FBE requires that Keymaster be ready to handle requests by the post-fs-data boot phase, which is when vold sets up the initial keys.

Excluding directories

init applies the system DE key to all top-level directories of /data , except for directories that must be unencrypted: the directory that contains the system DE key itself, and directories that contain user CE or DE directories. Encryption keys apply recursively and cannot be overridden by subdirectories.

In Android 11 and higher, the key that init applies to directories can be controlled by the encryption=<action> argument to the mkdir command in init scripts. The possible values of <action> are documented in the README for the Android init language .

In Android 10, the init encryption actions were hardcoded into the following location:

/system/extras/libfscrypt/fscrypt_init_extensions.cpp

In Android 9 and earlier, the location was:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

It is possible to add exceptions to prevent certain directories from being encrypted at all. If modifications of this sort are made then the device manufacturer should include SELinux policies that only grant access to the applications that need to use the unencrypted directory. This should exclude all untrusted applications.

The only known acceptable use case for this is in support of legacy OTA capabilities.

Supporting Direct Boot in system applications

Making applications Direct Boot aware

To facilitate rapid migration of system apps, there are two new attributes that can be set at the application level. The defaultToDeviceProtectedStorage attribute is available only to system apps. The directBootAware attribute is available to all.

<application
    android:directBootAware="true"
    android:defaultToDeviceProtectedStorage="true">

The directBootAware attribute at the application level is shorthand for marking all components in the app as being encryption aware.

The defaultToDeviceProtectedStorage attribute redirects the default app storage location to point at DE storage instead of pointing at CE storage. System apps using this flag must carefully audit all data stored in the default location, and change the paths of sensitive data to use CE storage. Device manufactures using this option should carefully inspect the data that they are storing to ensure that it contains no personal information.

When running in this mode, the following System APIs are available to explicitly manage a Context backed by CE storage when needed, which are equivalent to their Device Protected counterparts.

  • Context.createCredentialProtectedStorageContext()
  • Context.isCredentialProtectedStorage()

Supporting multiple users

Each user in a multi-user environment gets a separate encryption key. Every user gets two keys: a DE and a CE key. User 0 must log into the device first as it is a special user. This is pertinent for Device Administration uses.

Crypto-aware applications interact across users in this manner: INTERACT_ACROSS_USERS and INTERACT_ACROSS_USERS_FULL allow an application to act across all the users on the device. However, those apps will be able to access only CE-encrypted directories for users that are already unlocked.

An application may be able to interact freely across the DE areas, but one user unlocked does not mean that all the users on the device are unlocked. The application should check this status before trying to access these areas.

Each work profile user ID also gets two keys: DE and CE. When the work challenge is met, the profile user is unlocked and the Keymaster (in TEE) can provide the profile's TEE key.

Handling updates

The recovery partition is unable to access the DE-protected storage on the userdata partition. Devices implementing FBE are strongly recommended to support OTA using A/B system updates . As the OTA can be applied during normal operation there is no need for recovery to access data on the encrypted drive.

When using a legacy OTA solution, which requires recovery to access the OTA file on the userdata partition:

  1. Create a top-level directory (for example misc_ne ) in the userdata partition.
  2. Configure this top-level directory to be unencrypted (see Excluding directories ).
  3. Create a directory within the top-level directory to hold OTA packages.
  4. Add an SELinux rule and file contexts to control access to this directory and it contents. Only the process or applications receiving OTA updates should be able to read and write to this directory. No other application or process should have access to this directory.

Validação

To ensure the implemented version of the feature works as intended, first run the many CTS encryption tests, such as DirectBootHostTest and EncryptionTest .

If the device is running Android 11 or higher, also run vts_kernel_encryption_test :

atest vts_kernel_encryption_test

or:

vts-tradefed run vts -m vts_kernel_encryption_test

In addition, device manufacturers may perform the following manual tests. On a device with FBE enabled:

  • Check that ro.crypto.state exists
    • Ensure ro.crypto.state is encrypted
  • Check that ro.crypto.type exists
    • Ensure ro.crypto.type is set to file

Additionally, testers can boot a userdebug instance with a lockscreen set on the primary user. Then adb shell into the device and use su to become root. Make sure /data/data contains encrypted filenames; if it does not, something is wrong.

Device manufacturers are also encouraged to explore running the upstream Linux tests for fscrypt on their devices or kernels. These tests are part of the xfstests filesystem test suite. However, these upstream tests are not offically supported by Android.

AOSP implementation details

This section provides details on the AOSP implementation and describes how file-based encryption works. It should not be necessary for device manufacturers to make any changes here to use FBE and Direct Boot on their devices.

fscrypt encryption

The AOSP implementation uses "fscrypt" encryption (supported by ext4 and f2fs) in the kernel and normally is configured to:

  • Encrypt file contents with AES-256 in XTS mode
  • Encrypt file names with AES-256 in CBC-CTS mode

Adiantum encryption is also supported. When Adiantum encryption is enabled, both file contents and file names are encrypted with Adiantum.

fscrypt supports two versions of encryption policies: version 1 and version 2. Version 1 is deprecated, and the CDD requirements for devices launching with Android 11 and higher are only compatible with version 2. Version 2 encryption policies use HKDF-SHA512 to derive the actual encryption keys from the userspace-supplied keys.

For more information about fscrypt, see the upstream kernel documentation .

Storage classes

The following table lists the FBE keys and the directories they protect in more detail:

Storage class Descrição Directories
System DE Device-encrypted data not tied to a particular user /data/system , /data/app , and various other subdirectories of /data
Per-boot Ephemeral system files that don't need to survive a reboot /data/per_boot
User CE (internal) Per-user credential-encrypted data on internal storage
  • /data/data (alias of /data/user/0 )
  • /data/media/${user_id}
  • /data/misc_ce/${user_id}
  • /data/system_ce/${user_id}
  • /data/user/${user_id}
  • /data/vendor_ce/${user_id}
User DE (internal) Per-user device-encrypted data on internal storage
  • /data/misc_de/${user_id}
  • /data/system_de/${user_id}
  • /data/user_de/${user_id}
  • /data/vendor_de/${user_id}
User CE (adoptable) Per-user credential-encrypted data on adoptable storage
  • /mnt/expand/${volume_uuid}/media/${user_id}
  • /mnt/expand/${volume_uuid}/misc_ce/${user_id}
  • /mnt/expand/${volume_uuid}/user/${user_id}
User DE (adoptable) Per-user device-encrypted data on adoptable storage
  • /mnt/expand/${volume_uuid}/misc_de/${user_id}
  • /mnt/expand/${volume_uuid}/user_de/${user_id}

Key storage and protection

All FBE keys are managed by vold and are stored encrypted on-disk, except for the per-boot key which is not stored at all. The following table lists the locations in which the various FBE keys are stored:

Key type Key location Storage class of key location
System DE key /data/unencrypted Unencrypted
User CE (internal) keys /data/misc/vold/user_keys/ce/${user_id} System DE
User DE (internal) keys /data/misc/vold/user_keys/de/${user_id} System DE
User CE (adoptable) keys /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} User CE (internal)
User DE (adoptable) keys /data/misc_de/${user_id}/vold/volume_keys/${volume_uuid} User DE (internal)

As shown in the preceding table, most FBE keys are stored in directories that are encrypted by another FBE key. Keys cannot be unlocked until the storage class that contains them has been unlocked.

vold also applies a layer of encryption to all FBE keys. Every key besides CE keys for internal storage is encrypted with AES-256-GCM using its own Keystore key that is not exposed outside the TEE. This ensures that FBE keys cannot be unlocked unless a trusted operating system has booted, as enforced by Verified Boot . Rollback resistance is also requested on the Keystore key, which allows FBE keys to be securely deleted on devices where Keymaster supports rollback resistance. As a best-effort fallback for when rollback resistance is unavailable, the SHA-512 hash of 16384 random bytes stored in the secdiscardable file stored alongside the key is used as the application ID tag of the Keystore key. All these bytes need to be recovered to recover an FBE key.

CE keys for internal storage receive a stronger level of protection that ensures they cannot be unlocked without knowing either the user's Lock Screen Knowledge Factor (LSKF) (PIN, pattern, or password), a secure passcode reset token , or both the client-side and server-side keys for a Resume-on-Reboot operation. Passcode reset tokens are only allowed to be created for work profiles and fully managed devices .

To achieve this, vold encrypts each CE key for internal storage using an AES-256-GCM key derived from the user's synthetic password . The synthetic password is an immutable high-entropy cryptographic secret that is randomly generated for each user. LockSettingsService in system_server manages the synthetic password and the ways in which it is protected.

To protect the synthetic password with the LSKF, LockSettingsService first stretches the LSKF by passing it through scrypt , targeting a time of about 25 ms and a memory usage of about 2 MiB. Since LSKFs are usually short, this step usually does not provide much security. The main layer of security is the Secure Element (SE) or TEE-enforced ratelimiting described below.

If the device has a Secure Element (SE), then LockSettingsService maps the stretched LSKF to a high-entropy random secret stored in the SE using the Weaver HAL . LockSettingsService then encrypts the synthetic password twice: first with a software key derived from the stretched LSKF and the Weaver secret, and second with a non-auth-bound Keystore key. This provides SE-enforced ratelimiting of LSKF guesses.

If the device doesn't have a SE, then LockSettingsService instead uses the stretched LSKF as a Gatekeeper password. LockSettingsService then encrypts the synthetic password twice: first with a software key derived from the stretched LSKF and the hash of a secdiscardable file, and second with a Keystore key that is auth-bound to the Gatekeeper enrollment. This provides TEE-enforced ratelimiting of LSKF guesses.

When the LSKF is changed, LockSettingsService deletes all information associated with the binding of the synthetic password to the old LSKF. On devices that support Weaver or rollback resistant Keystore keys, this guarantees secure deletion of the old binding. For this reason, the protections described here are applied even when the user does not have an LSKF.