Criptografia baseada em arquivo

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

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 são obrigados a usar criptografia baseada em arquivo.

Inicialização direta

A criptografia baseada em arquivo permite um novo recurso introduzido no Android 7.0 chamado Direct Boot . O Direct Boot permite que dispositivos criptografados inicializem diretamente na tela de bloqueio. Anteriormente, em dispositivos criptografados que usavam criptografia de disco completo (FDE), os usuários precisavam fornecer credenciais antes que qualquer dado pudesse ser acessado, evitando que o telefone executasse todas as operações, exceto as mais básicas. Por exemplo, os alarmes não funcionavam, os serviços de acessibilidade não estavam disponíveis e os telefones não podiam receber chamadas, limitando-se apenas às operações básicas de marcação de emergência.

Com a introdução da criptografia baseada em arquivos (FBE) e novas APIs para tornar os aplicativos conscientes da criptografia, é possível que esses aplicativos operem dentro de um contexto limitado. Isso pode acontecer antes que os usuários forneçam suas credenciais, ao mesmo tempo que 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 criptografado por credenciais (CE), que é o local de armazenamento padrão e está disponível somente depois que o usuário desbloquear o dispositivo.
  • Armazenamento Device Encrypted (DE), que é um local de armazenamento disponível durante o modo Direct Boot 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 ao mesmo tempo, já que a criptografia não é mais baseada apenas em uma senha de inicialização.

A API Direct Boot permite que aplicativos com reconhecimento de criptografia acessem cada uma dessas áreas. Há alterações 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 fornecer 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 estará sempre no estado desbloqueado.

Uma implementação completa de criptografia baseada em arquivos 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 maneiras 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, quando os fabricantes de dispositivos usam versões personalizadas desses aplicativos, eles desejam garantir, no mínimo, que existam pacotes com reconhecimento 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 arquivos, na qual vold ( system/vold ) fornece a funcionalidade para gerenciar dispositivos e volumes de armazenamento no Android. A adição do FBE fornece ao vold vários novos comandos para suportar o gerenciamento de chaves para as chaves CE e DE de vários usuários. Além das principais mudanças 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 Direct Boot. Esses incluem:

  • Discador AOSP (pacotes/aplicativos/Discador)
  • 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/pacotes/SystemUI)*

* Aplicativos do sistema que usam o atributo de manifesto defaultToDeviceProtectedStorage

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

Dependências

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

  • Suporte do 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 ele não fornece os recursos necessários nem garante proteção suficiente para chaves de criptografia.
  • Keymaster/ Keystore e Gatekeeper devem ser implementados em um Trusted Execution Environment (TEE) para fornecer proteção para as chaves DE, de modo que um sistema operacional não autorizado (sistema operacional personalizado atualizado no dispositivo) não possa simplesmente solicitar as chaves DE.
  • A raiz de confiança do hardware e a inicialização verificada vinculadas à inicialização do Keymaster são necessárias 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 tornados Android:directBootAware de acordo com a documentação do desenvolvedor do Direct Boot .

Suporte ao kernel

O suporte do kernel para criptografia Ext4 e F2FS está disponível nos kernels comuns do Android, versão 3.18 e superior. Para habilitá-lo em um kernel 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 arquivos e melhorar a experiência do usuário. Por exemplo, em dispositivos baseados em ARM64, a aceleração ARMv8 CE (Extensões de Criptografia) 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 inline seja usada quando o suporte de hardware e driver do fornecedor estiver disponível. A estrutura de criptografia embutida 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 usar armazenamento baseado em eMMC, habilite também:

CONFIG_MMC_CRYPTO=y

Habilitando criptografia baseada em arquivo

A ativação do FBE em um dispositivo requer sua ativação no armazenamento interno ( userdata ). Isso também ativa automaticamente o FBE no armazenamento adotável; entretanto, o formato de criptografia no armazenamento adotável pode ser substituído, se necessário.

Armazenamento interno

O FBE é habilitado 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 arquivos. Pode ser aes-256-cts , aes-256-heh , adiantum ou aes-256-hctr2 . Se não for especificado, o padrão é aes-256-cts se contents_encryption_mode for aes-256-xts ou adiantum se contents_encryption_mode for adiantum .
  • O parâmetro flags , novo no Android 11, é uma lista de sinalizadores separados pelo caractere + . Os seguintes sinalizadores são suportados:
    • O sinalizador v1 seleciona políticas de criptografia da versão 1; o sinalizador v2 seleciona 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 for iniciado no Android 11 ou superior (conforme determinado por ro.product.first_api_level ) ou v1 se o dispositivo for 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 de forma eficiente. 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 a inlinecrypt_optimized , mas também seleciona um método de geração de IV que limita IVs a 32 bits. Este sinalizador só deve ser usado em hardware de criptografia em linha que seja compatível com a especificação JEDEC eMMC v5.2 e, portanto, suporte 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 suportam 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 com o sinalizador inlinecrypt_optimized ou emmc_optimized .
    • O sinalizador dusize_4k força o tamanho da unidade de dados de criptografia a ser 4.096 bytes, mesmo quando o tamanho do bloco do sistema de arquivos não é 4.096 bytes. O tamanho da unidade de dados criptografados é a granularidade da criptografia do conteúdo do arquivo. Este sinalizador está disponível desde o Android 15 (AOSP experimental). Este sinalizador deve ser usado apenas para permitir o uso de hardware de criptografia em linha que não suporta unidades de dados maiores que 4.096 bytes, em um dispositivo que usa um tamanho de página maior que 4.096 bytes e que usa o sistema de arquivos f2fs.

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 equivalentemente fileencryption=::inlinecrypt_optimized ). Em dispositivos sem qualquer forma de aceleração AES, Adiantum pode ser usado em vez de AES configurando fileencryption=adiantum .

Desde o Android 14, o AES-HCTR2 é o modo preferido de criptografia de nomes de arquivos para dispositivos com instruções de criptografia aceleradas. 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 AES-HCTR2, ele poderá ser habilitado para criptografia de nomes de arquivos configurando filenames_encryption_mode como aes-256-hctr2 . No caso mais simples, isso seria feito com fileencryption=aes-256-xts:aes-256-hctr2 .

Em dispositivos lançados com Android 10 ou inferior, fileencryption=ice também é aceito para especificar o uso do modo de criptografia de conteúdo do 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 com Android 11 ou superior, este 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 Linux. Se você quiser usar hardware de criptografia em linha, adicione também a opção de montagem inlinecrypt . Por exemplo, uma linha fstab completa pode ser semelhante a:

/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.

Especificar a 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 os formatos de criptografia FBE e/ou de metadados no armazenamento adotável definindo 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 da opção fstab fileencryption e usa os mesmos padrões. Veja 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 sobre 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 arquivos. 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 explicitamente substituído 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 .

Integrando com 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 para diretórios que devem ser descriptografados, como o diretório que contém a própria chave DE do sistema e diretórios que contêm diretórios CE ou DE do usuário. As chaves de criptografia aplicam-se recursivamente e não podem ser substituídas por subdiretórios.

No Android 11 e versões posteriores, a chave que init aplica aos diretórios pode ser controlada pelo argumento encryption=<action> do comando mkdir nos scripts de inicialização. Os valores possíveis de <action> estão documentados no README da 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 versões anteriores, o local era:

/system/extras/ext4_utils/ext4_crypt_init_extensions.cpp

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

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

Suporte para inicialização direta em aplicativos do sistema

Tornando os aplicativos conscientes 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 do aplicativo como compatíveis com 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 utilizam esta 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()

Suportando 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 primeiro fazer login no dispositivo, pois é um usuário especial. Isto é 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 entre todos os usuários no dispositivo. No entanto, esses aplicativos poderão acessar apenas diretórios criptografados por CE para usuários que já estão desbloqueados.

Um aplicativo pode interagir livremente nas áreas DE, mas um usuário desbloqueado não significa que todos os usuários do dispositivo estejam desbloqueados. A aplicação deverá verificar esse status antes de tentar acessar essas áreas.

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

Lidando com atualizações

A partição de recuperação não consegue acessar o armazenamento protegido por DE na partição userdata. Dispositivos que implementam FBE são fortemente recomendados para suportar OTA usando atualizações de 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 armazenar 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 este diretório.

Validação

Para garantir que a versão implementada do recurso funcione conforme o esperado, primeiro execute os vários 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
    • Certifique-se de ro.crypto.state esteja criptografado
  • Verifique se ro.crypto.type existe
    • Certifique-se de ro.crypto.type esteja definido como file

Além disso, os testadores podem verificar se o armazenamento do CE está bloqueado antes que o dispositivo seja desbloqueado pela primeira vez desde a inicialização. Para fazer isso, use um userdebug ou eng build, defina um PIN, padrão ou senha no usuário principal e reinicie o dispositivo. Antes de desbloquear o dispositivo, execute o seguinte comando para verificar o armazenamento CE do usuário principal. Se o dispositivo usar o modo de usuário do sistema sem cabeça (a maioria dos dispositivos automotivos), o usuário principal será o usuário 10, então execute:

adb root; adb shell ls /data/user/10

Em outros dispositivos (a maioria dos dispositivos não automotivos), o usuário principal é o usuário 0, então execute:

adb root; adb shell ls /data/user/0

Verifique se os nomes de arquivos listados são codificados em Base64, indicando que os nomes de arquivos estão criptografados e a chave para descriptografá-los ainda não está disponível. Se os nomes dos arquivos estiverem listados em texto simples, algo está errado.

Os fabricantes de dispositivos também são incentivados a explorar a execução de 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 de 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 deveria ser necessário que os fabricantes de dispositivos fizessem quaisquer alterações aqui para usar FBE e 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, tanto o conteúdo quanto 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 lançados 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 o 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
Não criptografado Diretórios em /data que não podem ou não precisam ser protegidos pelo FBE. Em dispositivos que usam criptografia de metadados , esses diretórios não são realmente descriptografados, mas são protegidos pela chave de criptografia de metadados que é equivalente ao System DE.
  • /data/apex , excluindo /data/apex/decompressed e /data/apex/ota_reserved que são DE do sistema
  • /data/lost+found
  • /data/preloads
  • /data/unencrypted
  • Todos os diretórios cujos subdiretórios usam chaves FBE diferentes. Por exemplo, como cada diretório /data/user/${user_id} usa uma chave por usuário, /data/user não usa nenhuma chave.
Sistema DE Dados criptografados por dispositivo não vinculados a um usuário específico
  • /data/apex/decompressed
  • /data/apex/ota_reserved
  • /data/app
  • /data/misc
  • /data/system
  • /data/vendor
  • Todos os outros subdiretórios de /data que esta tabela não menciona como tendo uma classe diferente
Por inicialização Arquivos de sistema efêmeros que não precisam sobreviver a uma reinicialização /data/per_boot
CE do usuário (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}
CE do usuário (adotável) Dados criptografados por credencial por usuário no 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 pelo vold e armazenadas criptografadas no disco, exceto a chave por inicialização, que não é armazenada. A tabela a seguir lista os locais nos quais as diversas chaves FBE são armazenadas:

Tipo de chave Localização chave Classe de armazenamento de localização chave
Chave DE do sistema /data/unencrypted Não criptografado
Chaves CE do usuário (internas) /data/misc/vold/user_keys/ce/${user_id} Sistema DE
Chaves DE do usuário (internas) /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} CE do usuário (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. Cada chave além das chaves CE para armazenamento interno é criptografada 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 tenha sido inicializado, conforme imposto 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 onde o Keymaster oferece suporte à resistência à reversão. Como alternativa de melhor esforço para quando a resistência à reversão não estiver disponível, o hash SHA-512 de 16.384 bytes aleatórios armazenados no arquivo secdiscardable armazenado junto com a chave é usado como a etiqueta 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 de proteção mais forte que garante que não possam ser desbloqueadas sem conhecer o fator de conhecimento da tela de bloqueio (LSKF) do usuário (PIN, padrão ou senha), um token de redefinição de senha seguro ou ambos do lado do cliente e chaves do lado do servidor para uma operação Resume-on-Reboot . Os 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 como 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 são geralmente curtos, esta etapa geralmente não oferece muita segurança. A principal camada de segurança é o Secure Element (SE) ou limite de taxa imposto por TEE descrito abaixo.

Se o dispositivo tiver um Elemento Seguro (SE), então LockSettingsService mapeia o LSKF esticado 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 imposta por SE de suposições LSKF.

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

Quando o LSKF é alterado, LockSettingsService exclui todas as informações associadas à ligaçã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 este motivo, as proteções aqui descritas são aplicadas mesmo quando o usuário não possui LSKF.