O Android 7.0 e versões mais recentes oferecem suporte à criptografia baseada em arquivos (FBE, na sigla em inglês). A criptografia baseada em arquivo permite que diferentes arquivos sejam criptografados com chaves diferentes que podem ser desbloqueadas de forma independente.
Este artigo descreve como ativar a criptografia baseada em arquivos em novos dispositivos e como os apps do sistema podem usar as APIs de inicialização direta para oferecer aos usuários a experiência melhor e mais segura possível.
Todos os dispositivos lançados com o Android 10 e versões mais recentes precisam usar a criptografia baseada em arquivos.
Inicialização direta
A criptografia baseada em arquivos ativa um novo recurso introduzido no Android 7.0 chamado Inicialização direta. A inicialização direta permite que dispositivos criptografados sejam inicializados diretamente para a tela de bloqueio. Anteriormente, em dispositivos criptografados que usavam a criptografia de disco completo (FDE), os usuários precisavam fornecer credenciais antes que os dados pudessem ser acessados, o que impedia o telefone de realizar todas as operações, exceto as mais básicas. Por exemplo, os alarmes não funcionavam, os serviços de acessibilidade estavam indisponíveis e os telefones não recebiam ligações, mas eram limitados a operações básicas de discagem de emergência.
Com a introdução da criptografia baseada em arquivos (FBE) e de novas APIs para tornar os apps compatíveis com a criptografia, é possível que eles funcionem em um contexto limitado. Isso pode acontecer antes que os usuários forneçam as credenciais, protegendo as informações privadas deles.
Em um dispositivo com FBE ativado, cada usuário tem dois locais de armazenamento disponíveis para apps:
- O armazenamento criptografado por credencial (CE), que é o local de armazenamento padrão e só é disponibilizado depois que o usuário desbloqueia o dispositivo.
- Armazenamento criptografado do dispositivo (DE, na sigla em inglês), que é um local de armazenamento disponibilizado durante o modo de inicialização direta e depois que o usuário desbloqueia o dispositivo.
Essa separação torna os perfis de trabalho mais seguros, porque permite que mais de um usuário seja protegido por vez, já que a criptografia não é mais baseada apenas em uma senha de inicialização.
A API Direct Boot permite que apps com reconhecimento de criptografia acessem cada uma dessas áreas. Há mudanças no ciclo de vida do app para acomodar a necessidade de notificar apps quando o armazenamento de CE de um usuário é desbloqueado em resposta à entrada inicial de credenciais na tela de bloqueio ou no caso de um perfil de trabalho que fornece um desafio de trabalho. Os dispositivos com o Android 7.0 precisam oferecer suporte a essas novas APIs e ciclos de vida, independentemente de implementarem ou não o FBE. No entanto, sem FBE, o armazenamento de DE e CE está sempre no estado desbloqueado.
Uma implementação completa da criptografia baseada em arquivos nos sistemas de arquivos Ext4 e F2FS é fornecida no Android Open Source Project (AOSP) e precisa ser ativada apenas em dispositivos que atendam aos requisitos. Os fabricantes que optam por usar a FBE podem explorar maneiras de otimizar o recurso com base no system on chip (SoC) usado.
Todos os pacotes necessários no AOSP foram atualizados para oferecer reconhecimento de inicialização direta. No entanto, quando os fabricantes de dispositivos usam versões personalizadas desses apps, eles querem garantir que haja pelo menos pacotes compatíveis com inicialização direta que ofereçam os seguintes serviços:
- Serviços de telefonia e discador
- Método de entrada para inserir senhas na tela de bloqueio
Exemplos e origem
O Android oferece uma implementação de referência de criptografia baseada em arquivos, em que o vold (system/vold) oferece a funcionalidade para gerenciar dispositivos de armazenamento e volumes no Android. A adição do FBE oferece ao vold vários comandos novos para oferecer suporte ao gerenciamento de chaves para as chaves de CE e DE de vários usuários. Além das mudanças principais para usar os recursos de criptografia baseada em arquivos no kernel, muitos pacotes do sistema, incluindo a tela de bloqueio e o SystemUI, foram modificados para oferecer suporte aos recursos de FBE e Direct Boot. São eles:
- Discador do AOSP (pacotes/apps/discador)
- Relógio de mesa (pacotes/apps/DeskClock)
- LatinIME (packages/inputmethods/LatinIME)*
- App Configurações (packages/apps/Settings)*
- SystemUI (frameworks/base/packages/SystemUI)*
* Apps do sistema que usam o atributo de manifesto
defaultToDeviceProtectedStorage
Mais exemplos de apps e serviços com reconhecimento de criptografia podem ser
encontrados executando o comando mangrep directBootAware
no
diretório de frameworks ou pacotes da árvore de origem
do AOSP.
Dependências
Para usar a implementação do FBE do AOSP com segurança, um dispositivo precisa atender às seguintes dependências:
- Suporte do kernel para criptografia Ext4 ou F2FS.
- Suporte ao Keymaster com a versão 1.0 ou mais recente da HAL. Não há suporte para o Keymaster 0.3 porque ele não fornece os recursos necessários ou garante proteção suficiente para chaves de criptografia.
- O Keymaster/Keystore e o gatekeeper precisam ser implementados em um ambiente de execução confiável (TEE) para proteger as chaves de DE, para que um SO não autorizado (SO personalizado transferido para o dispositivo) não possa simplesmente solicitar as chaves de DE.
- A raiz de confiança de 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, apps como relógios de alarme, telefone e recursos de acessibilidade precisam ser android:directBootAware de acordo com a documentação para desenvolvedores do Direct Boot.
Suporte do kernel
O suporte do kernel à criptografia Ext4 e F2FS está disponível nos kernels comuns do Android, versão 3.18 e mais recentes. Para ativá-lo em um kernel da versão 5.1 ou mais recente, use:
CONFIG_FS_ENCRYPTION=y
Para kernels mais antigos, use CONFIG_EXT4_ENCRYPTION=y
se o sistema de arquivos
userdata
do dispositivo for Ext4 ou use
CONFIG_F2FS_FS_ENCRYPTION=y
se o sistema de arquivos userdata
for F2FS.
Se o dispositivo oferecer suporte a armazenamento adotável ou usar a criptografia de metadados no armazenamento interno, ative também as opções de configuração do kernel necessárias para a criptografia de metadados, conforme descrito na documentação de criptografia de metadados.
Além do suporte funcional à criptografia Ext4 ou F2FS, os fabricantes de dispositivos também precisam ativar 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 de ARMv8 CE (extensões de criptografia) pode ser ativada 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 implementar um hardware de criptografia inline, que criptografa/descriptografa os dados enquanto eles estão a caminho do dispositivo de armazenamento. Os kernels comuns do Android (versão 4.14 e mais recentes) contêm um framework que permite que a criptografia in-line seja usada quando o suporte ao hardware e ao driver do fornecedor estiver disponível. O framework de criptografia inline pode ser ativado 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 dispositivo usa armazenamento baseado em UFS, também ative:
CONFIG_SCSI_UFS_CRYPTO=y
Se o dispositivo usar armazenamento baseado em eMMC, também ative:
CONFIG_MMC_CRYPTO=y
Ativar a criptografia baseada em arquivos
Para ativar a FBE em um dispositivo, é necessário ativá-la no armazenamento interno
(userdata
). Isso também ativa automaticamente a FBE no armazenamento
adotável. No entanto, o formato de criptografia no armazenamento adotável pode ser modificado
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
. Essa 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
. No Android 11 e versões mais recentes, 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 será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 flags separadas pelo caractere+
. As flags a seguir são compatíveis:- A flag
v1
seleciona as políticas de criptografia da versão 1. A flagv2
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 chaves mais segura e flexível. O padrão é v2 se o dispositivo for lançado no Android 11 ou mais recente (conforme determinado porro.product.first_api_level
) ou v1 se o dispositivo for lançado no Android 10 ou versões anteriores. - A flag
inlinecrypt_optimized
seleciona um formato de criptografia otimizado para hardware de criptografia inline que não processa um grande número de chaves de forma eficiente. Isso é feito 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. - A sinalização
emmc_optimized
é semelhante ainlinecrypt_optimized
, mas também seleciona um método de geração de IV que limita os IVs a 32 bits. Essa flag só pode ser usada em hardware de criptografia inline que seja compatível com a especificação JEDEC eMMC v5.2 e, portanto, ofereça suporte apenas a IVs 32 bits. Em outros hardwares de criptografia inline, useinlinecrypt_optimized
. Essa sinalização nunca pode ser usada em armazenamento baseado em UFS. A especificação UFS permite o uso de IVs de 64 bits. - Em dispositivos compatíveis com chaves encapsuladas por hardware, a sinalização
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 a sinalizaçãoinlinecrypt_optimized
ouemmc_optimized
. - A sinalização
dusize_4k
força o tamanho da unidade de dados de criptografia a ser de 4.096 bytes, mesmo quando o tamanho do bloco do sistema de arquivos não é de 4.096 bytes. O tamanho da unidade de dados de criptografia é a granularidade da criptografia do conteúdo do arquivo. Essa flag está disponível desde o Android 15. Essa sinalização só deve ser usada para ativar o uso de hardware de criptografia inline que não oferece suporte a 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.
- A flag
Se você não estiver usando hardware de criptografia inline, a configuração recomendada para a maioria
dos dispositivos é fileencryption=aes-256-xts
. Se você estiver usando hardware de criptografia
inline, a configuração recomendada para a maioria dos dispositivos é
fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized
(ou fileencryption=::inlinecrypt_optimized
equivalente). Em
dispositivos sem nenhuma forma de aceleração AES, o Adiantum pode ser usado em vez de AES
definindo fileencryption=adiantum
.
No Android 14 e versões mais recentes, o AES-HCTR2 é o modo preferido de criptografia de nomes de arquivo
para dispositivos com instruções de criptografia acelerada. No entanto, apenas kernels mais recentes do Android oferecem suporte a
AES-HCTR2. Em uma versão futura do Android, ele vai se tornar o modo padrão para a criptografia de nomes de
arquivos. Se o kernel tiver suporte para AES-HCTR2, ele poderá ser ativado para a criptografia de nomes de arquivos
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 lançados com o Android 10 ou versões anteriores,
fileencryption=ice
também é aceito para especificar o uso do
modo de criptografia de conteúdo de arquivo FSCRYPT_MODE_PRIVATE
. Esse modo não é
implementado pelos kernels comuns do Android, mas pode ser implementado por
fornecedores que usam patches de kernel personalizados. O formato em disco produzido por esse modo
era específico do fornecedor. Em dispositivos lançados com o Android
11 ou versões mais recentes, esse modo não é mais permitido e um
formato de criptografia padrão precisa 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 ter esta aparência:
/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 adaptável podem ser usados juntos.
A especificação da opção fstab fileencryption
para userdata
também ativa automaticamente a FBE e a criptografia de metadados no armazenamento adotável. No entanto, é possível substituir os formatos de criptografia de metadados ou FBE no
armazenamento adaptável definindo propriedades em
PRODUCT_PROPERTY_OVERRIDES
.
Em dispositivos lançados com o Android 11 ou mais recente, 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 fstabfileencryption
e usa os mesmos padrões. Veja as recomendações defileencryption
acima sobre 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 o Android 10 ou versões anteriores, use estas propriedades:
ro.crypto.volume.contents_mode
seleciona o modo de criptografia do 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 o Android 10 ou versões anteriores é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 sobre criptografia de metadados.
Integrar com o Keymaster
A HAL do Keymaster precisa ser iniciada como parte da classe early_hal
.
Isso ocorre porque a FBE exige que o Keymaster esteja pronto para processar solicitações pela
fase de inicialização post-fs-data
, que é quando o vold
configura
as chaves iniciais.
Excluir 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
precisam ser descriptografados, como o diretório que contém a chave DE do sistema
e diretórios que contêm os diretórios CE ou DE do usuário. As chaves de criptografia
são aplicadas recursivamente e não podem ser substituídas por subdiretórios.
No Android 11 e versões mais recentes, a chave que
init
aplica aos diretórios pode ser controlada pelo
argumento encryption=<action>
para o comando mkdir
em scripts init. 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 de 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 modificações desse tipo forem feitas, o fabricante do dispositivo precisará incluir políticas do SELinux que concedem acesso apenas aos apps que precisam usar o diretório não criptografado. Isso deve excluir todos os apps não confiáveis.
O único caso de uso aceitável conhecido para isso é o suporte a recursos legados de OTA.
Suporte à inicialização direta em apps do sistema
Fazer com que os apps reconheçam a inicialização direta
Para facilitar a migração rápida de apps do sistema, há dois novos atributos que
podem ser definidos no nível do app. O
atributo defaultToDeviceProtectedStorage
está disponível apenas para
apps do sistema. O atributo directBootAware
está disponível para todos.
<application android:directBootAware="true" android:defaultToDeviceProtectedStorage="true">
O atributo directBootAware
no nível do app é uma abreviação para marcar
todos os componentes no app como tendo reconhecimento de criptografia.
O atributo defaultToDeviceProtectedStorage
redireciona o local de armazenamento
padrão do app para apontar para o armazenamento do DE em vez de apontar para o armazenamento do CE.
Os apps do sistema que usam essa flag precisam auditar cuidadosamente todos os dados armazenados no
local padrão e mudar os caminhos dos dados sensíveis para usar o armazenamento CE. Os fabricantes
de dispositivos que usam essa opção precisam inspecionar cuidadosamente os dados que estão
armazenando para garantir que eles não contenham informações pessoais.
Quando executadas nesse modo, as APIs do sistema a seguir ficam disponíveis para gerenciar explicitamente um contexto com suporte do armazenamento CE, quando necessário, que são equivalentes às contrapartes protegidas por dispositivo.
Context.createCredentialProtectedStorageContext()
Context.isCredentialProtectedStorage()
Oferecer suporte a vários usuários
Cada usuário em um ambiente multiusuário recebe uma chave de criptografia separada. Cada usuário recebe duas chaves: uma chave DE e uma chave CE. O usuário 0 precisa fazer login no dispositivo primeiro, porque é um usuário especial. Isso é pertinente para usos de administração de dispositivos.
Os apps com reconhecimento de criptografia interagem entre os usuários dessa maneira:
INTERACT_ACROSS_USERS
e INTERACT_ACROSS_USERS_FULL
permitem que um app atue para todos os usuários no dispositivo. No entanto, esses
apps podem acessar apenas diretórios criptografados por CE para usuários que já
estão desbloqueados.
Um app pode interagir livremente entre as áreas de DE, mas um usuário desbloqueado não significa que todos os usuários no dispositivo estão desbloqueados. O app precisa 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.
Processar 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 a 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 é necessário fazer a recuperação para acessar dados na unidade criptografada.
Ao usar uma solução OTA legada, que exige 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 que seja descriptografado. Consulte Como excluir diretórios.
- Crie um diretório no diretório de nível superior para armazenar pacotes OTA.
- Adicione uma regra SELinux e contextos de arquivo para controlar o acesso a esse diretório e ao conteúdo dele. Somente o processo ou os apps que recebem atualizações OTA podem ler e gravar nesse diretório. Nenhum outro app ou processo pode ter acesso a esse diretório.
Validação
Para garantir que a versão implementada do recurso funcione conforme o esperado, primeiro execute vários testes de criptografia do CTS, como DirectBootHostTest e EncryptionTest.
Se o dispositivo estiver executando o Android 11 ou mais recente, 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 a FBE ativada:
- Verifique se
ro.crypto.state
existe.- Verifique se o
ro.crypto.state
está criptografado
- Verifique se o
- Verifique se
ro.crypto.type
existe.- Confira se
ro.crypto.type
está definido comofile
- Confira se
Além disso, os testadores podem verificar se o armazenamento de CE está bloqueado antes que o dispositivo seja
desbloqueado pela primeira vez desde a inicialização. Para fazer isso, use um
build userdebug
ou eng
, 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 headless (a maioria dos dispositivos automotivos), o usuário principal será o 10. Portanto, execute:
adb root; adb shell ls /data/user/10
Em outros dispositivos (a maioria dos não automotivos), o usuário principal é o usuário 0. Portanto, execute:
adb root; adb shell ls /data/user/0
Verifique se os nomes de arquivo listados estão codificados em Base64, indicando que os nomes de arquivo 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 executar os testes upstream do Linux para fscrypt nos dispositivos ou kernels. Esses testes fazem parte do pacote de testes do sistema de arquivos xfstests. No entanto, esses testes upstream não têm suporte oficial do Android.
Detalhes de implementação do AOSP
Esta seção fornece detalhes sobre a implementação do AOSP e descreve como a criptografia baseada em arquivos funciona. Não é necessário que os fabricantes de dispositivos façam nenhuma mudança aqui para usar o FBE e o Direct Boot nos dispositivos.
criptografia fscrypt
A implementação do AOSP usa criptografia "fscrypt" (com suporte de ext4 e f2fs) no kernel e normalmente é configurada para:
- Criptografar conteúdo de arquivos com AES-256 no modo XTS
- Criptografar nomes de arquivos com AES-256 no modo CBC-CTS
A criptografia Adiantum também é compatível. Quando a criptografia Adiantum está ativada, o conteúdo e os nomes dos arquivos são criptografados com o Adiantum.
O fscrypt é compatível com duas versões das políticas de criptografia: versão 1 e versão 2. A versão 1 foi descontinuada, e os requisitos do CDD para dispositivos lançados com o Android 11 e versões mais recentes são compatíveis apenas com a versão 2. As políticas de criptografia da versão 2 usam HKDF-SHA512 para derivar as chaves de criptografia reais das chaves fornecidas pelo espaço do usuário.
Para mais informações sobre o fscrypt, consulte a documentação do kernel upstream.
Classes de armazenamento
A tabela a seguir lista as chaves de FBE e os diretórios que elas protegem com mais detalhes:
Classe de armazenamento | Descrição | Diretórios |
---|---|---|
Não criptografada | Diretórios em /data que não podem ou não precisam ser
protegidos pela 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. |
|
System DE | Dados criptografados no dispositivo não vinculados a um usuário específico |
|
Por inicialização | Arquivos de sistema temporários que não precisam sobreviver a uma reinicialização | /data/per_boot |
CE do usuário (interno) | Dados criptografados por usuário no armazenamento interno |
|
Usuário DE (interno) | Dados criptografados por dispositivo e 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 e por usuário no armazenamento adotável |
|
Armazenamento e proteção de chaves
Todas as chaves FBE são gerenciadas por vold
e armazenadas criptografadas no disco,
exceto a chave de inicialização, que não é armazenada. A tabela a seguir
lista os locais em que as várias chaves de FBE são armazenadas:
Tipo de chave | Local da chave | Classe de armazenamento do local da chave |
---|---|---|
Chave DE do sistema | /data/unencrypted |
Não criptografada |
Chaves de CE (internas) do usuário | /data/misc/vold/user_keys/ce/${user_id} |
Sistema DE |
Chaves de usuário DE (internas) | /data/misc/vold/user_keys/de/${user_id} |
Sistema DE |
Chaves CE (adotáveis) do usuário | /data/misc_ce/${user_id}/vold/volume_keys/${volume_uuid} |
CE do usuário (interno) |
Chaves do usuário DE (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 é armazenada em diretórios que são criptografados por outra chave FBE. As chaves não podem ser desbloqueadas até que a classe de armazenamento que as contém seja desbloqueada.
O vold
também aplica uma camada de criptografia a todas as chaves de FBE. Todas as chaves,
exceto as chaves de CE para armazenamento interno, são criptografadas com AES-256-GCM usando a 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 aplicado pela inicialização verificada. A resistência
à reversão também é solicitada na chave do Keystore, o que permite que as chaves FBE
sejam excluídas com segurança em dispositivos em que o Keymaster oferece suporte à resistência à reversão. Como
substituto 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
ao lado da chave é usado como a tag de ID
do app da chave do 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, na sigla em inglês) do usuário (PIN, padrão ou senha), um token de redefinição de senha segura ou as chaves do lado do cliente e do servidor para uma operação de Retomar na reinicialização. Os tokens de redefinição de senha só podem ser criados para perfis de trabalho e dispositivos totalmente gerenciados.
Para 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 secret criptográfico de alta entropia imutável que é gerado aleatoriamente para cada usuário. LockSettingsService
em
system_server
gerencia a senha sintética e as maneiras como
ela é protegida.
Para proteger a senha sintética com o LSKF,
o 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 Elemento de segurança (SE, na sigla em inglês) ou a limitação de taxa imposta pelo TEE, conforme descrito abaixo.
Se o dispositivo tiver um elemento de segurança (SE), o LockSettingsService
mapeia o LSKF esticado para um segredo aleatório de alta entropia armazenado no SE usando
o HAL do Weaver. O LockSettingsService
, em seguida, criptografa
a senha sintética duas vezes: primeiro com uma chave de software derivada do
LSKF esticado e do segredo Weaver e, em segundo lugar, com uma chave de keystore
não vinculada à autenticação. Isso fornece a limitação de taxa aplicada pelo SE para suposições de LSKF.
Se o dispositivo não tiver um SE, o LockSettingsService
usará o LSKF esticado como uma senha de
Gatekeeper. Em seguida, LockSettingsService
criptografa a senha sintética
duas vezes: primeiro com uma chave de software derivada do LSKF estendido e o hash de
um arquivo secdiscardável, e a segunda com uma chave Keystore vinculada à autenticação para o
registro do Gatekeeper. Isso fornece limitação de taxa de TEE para as tentativas de LSKF.
Quando o LSKF é alterado, LockSettingsService
exclui todas
as informações associadas à vinculação da senha sintética ao LSKF
antigo. Em dispositivos com suporte a chaves do Weaver ou do Keystore resistentes a reversão, isso
garante a exclusão segura da vinculação antiga. Por esse motivo, as proteções
descritas aqui são aplicadas mesmo quando o usuário não tem um LSKF.