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 seraes-256-xts
ouadiantum
. 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 seraes-256-cts
,aes-256-heh
,adiantum
ouaes-256-hctr2
. Se não for especificado, o padrão éaes-256-cts
secontents_encryption_mode
foraes-256-xts
ouadiantum
secontents_encryption_mode
foradiantum
. - 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 sinalizadorv2
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 porro.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 ainlinecrypt_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, useinlinecrypt_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 montageminlinecrypt
e com o sinalizadorinlinecrypt_optimized
ouemmc_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.
- O sinalizador
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 fstabfileencryption
e usa os mesmos padrões. Veja as recomendações parafileencryption
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 dero.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 dero.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 poraes-256-cts
. -
ro.crypto.fde_algorithm
ero.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
:
- Crie um diretório de nível superior (por exemplo
misc_ne
) na partiçãouserdata
. - Configure esse diretório de nível superior para não ser criptografado (consulte Excluindo diretórios ).
- Crie um diretório dentro do diretório de nível superior para armazenar pacotes OTA.
- 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
- Certifique-se de
- Verifique se
ro.crypto.type
existe- Certifique-se de
ro.crypto.type
esteja definido comofile
- Certifique-se de
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. |
|
Sistema DE | Dados criptografados por dispositivo não vinculados a um usuário específico |
|
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 |
|
Usuário DE (interno) | Dados criptografados por dispositivo por usuário no armazenamento interno |
|
CE do usuário (adotável) | Dados criptografados por credencial por usuário no armazenamento adotável |
|
Usuário DE (adotável) | Dados criptografados por dispositivo por usuário em armazenamento adotável |
|
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.