O Android 7.0 e versões mais recentes oferecem suporte à criptografia baseada em arquivos (FBE). A FBE permite que arquivos diferentes sejam criptografados com chaves diferentes, que podem ser desbloqueadas de forma independente. Essas chaves são usadas para criptografar o conteúdo e os nomes dos arquivos. Quando o FBE é usado, outras informações, como layouts de diretório, tamanhos de arquivo, permissões e tempos de criação/modificação, não são criptografadas. Coletivamente, essas outras informações são conhecidas como metadados do sistema de arquivos.
O Android 9 introduziu suporte à criptografia de metadados. Com a criptografia de metadados, uma única chave presente no momento da inicialização criptografa qualquer conteúdo não criptografado pela FBE. Essa chave é protegida pelo Keymaster, que, por sua vez, é protegido pela inicialização verificada.
A criptografia de metadados é sempre ativada no armazenamento adotável quando a FBE está ativada. A criptografia de metadados também pode ser ativada no armazenamento interno. Os dispositivos iniciados com o Android 11 ou versões mais recentes precisam ter a criptografia de metadados no armazenamento interno ativada.
Implementação no armazenamento interno
É possível configurar a criptografia de metadados no armazenamento interno de novos dispositivos
configurando o sistema de arquivos metadata
, mudando a sequência de inicialização e
ativando a criptografia de metadados no arquivo fstab do dispositivo.
Pré-requisitos
A criptografia de metadados só pode ser configurada quando a partição de dados é formatada pela primeira vez. Como resultado, esse recurso é apenas para novos dispositivos. Isso não é algo que uma OTA precisa mudar.
A criptografia de metadados exige que o módulo dm-default-key
seja
ativado no kernel. No Android 11 e versões mais recentes,
a dm-default-key
tem suporte dos kernels comuns do Android, versão
4.14 e mais recentes. Essa versão de dm-default-key
usa um hardware e
um framework de criptografia independente do fornecedor chamado blk-crypto.
Para ativar o dm-default-key
, use:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
O dm-default-key
usa um hardware de criptografia inline (hardware que
criptografa/descriptografa dados enquanto estão a caminho do/para o dispositivo de armazenamento) quando
disponível. Se você não usar hardware de criptografia inline, também será
necessário ativar um substituto para a API de criptografia do kernel:
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
Quando não estiver usando hardware de criptografia inline, também ative qualquer aceleração baseada em CPU disponível, conforme recomendado na documentação do FBE.
No Android 10 e versões anteriores, o dm-default-key
não era compatível com o kernel comum do Android. Portanto, cabe aos fornecedores
implementar dm-default-key
.
Configurar o sistema de arquivos de metadados
Como nada na partição de dados do usuário pode ser lido até que a chave de criptografia de metadados esteja presente, a tabela de partições precisa reservar uma partição separada, chamada de "partição de metadados", para armazenar os blobs de keymaster que protegem essa chave. A partição de metadados precisa ter 16 MB.
fstab.hardware
precisa incluir uma entrada para o sistema de arquivos de metadados
que reside nessa partição que o monta em /metadata
, incluindo
a sinalização formattable
para garantir que ele seja formatado no momento da inicialização. O
sistema de arquivos f2fs não funciona em partições menores. Recomendamos o uso do ext4. Exemplo:
/dev/block/bootdevice/by-name/metadata /metadata ext4 noatime,nosuid,nodev,discard wait,check,formattable
Para garantir que o ponto de montagem /metadata
exista, adicione a linha
a seguir a BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
Mudanças na sequência de inicialização
Quando a criptografia de metadados é usada, vold
precisa estar em execução antes que
/data
seja ativado. Para garantir que ele comece cedo o suficiente, adicione
a seguinte estrofe a init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
O Keymaster precisa estar em execução e pronto antes que o init tente ativar
/data
.
init.hardware.rc
já precisa conter uma instrução mount_all
que monta o próprio /data
na estrofe on
late-fs
. Antes dessa linha, adicione a diretiva para executar o serviço wait_for_keymaster
:
on late-fs … # Wait for keymaster exec_start wait_for_keymaster # Mount RW partitions which need run fsck mount_all /vendor/etc/fstab.${ro.boot.hardware.platform} --late
Ativar a criptografia de metadados
Por fim, adicione keydirectory=/metadata/vold/metadata_encryption
à coluna fs_mgr_flags da entrada fstab
de userdata
. Por exemplo, uma linha fstab completa pode ter esta aparência:
/dev/block/bootdevice/by-name/userdata /data f2fs noatime,nosuid,nodev,discard,inlinecrypt latemount,wait,check,fileencryption=aes-256-xts:aes-256-cts:inlinecrypt_optimized,keydirectory=/metadata/vold/metadata_encryption,quota,formattable
Por padrão, o algoritmo de criptografia de metadados no armazenamento interno é
AES-256-XTS. Para modificar essa configuração, defina a opção metadata_encryption
, também na coluna fs_mgr_flags:
- Em dispositivos sem aceleração AES, a criptografia Adiantum pode ser
ativada definindo
metadata_encryption=adiantum
. - Em dispositivos compatíveis com chaves encapsuladas por hardware,
a chave de criptografia de metadados pode ser encapsulada por hardware configurando
metadata_encryption=aes-256-xts:wrappedkey_v0
(ou equivalentemetadata_encryption=:wrappedkey_v0
, já queaes-256-xts
é o algoritmo padrão).
Como a interface do kernel para dm-default-key
mudou no Android
11, também é necessário definir o
valor correto para PRODUCT_SHIPPING_API_LEVEL
em
device.mk
. Por exemplo, se o dispositivo for lançado com o Android
11 (nível 30 da API), device.mk
precisará
conter:
PRODUCT_SHIPPING_API_LEVEL := 30
Também é possível definir a seguinte propriedade do sistema para forçar o uso da nova API dm-default-key
, independentemente do nível da API de frete:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.dm_default_key.options_format.version=2
Validação
Para verificar se a criptografia de metadados está ativada e funcionando corretamente, execute os testes descritos abaixo. Além disso, observe os problemas comuns descritos abaixo.
Testes
Comece executando o seguinte comando para verificar se a criptografia de metadados está ativada no armazenamento interno:
adb root
adb shell dmctl table userdata
A resposta precisa ser semelhante a esta:
Targets in the device-mapper table for userdata: 0-4194304: default-key, aes-xts-plain64 - 0 252:2 0 3 allow_discards sector_size:4096 iv_large_sectors
Se você substituir as configurações de criptografia padrão definindo a
opção metadata_encryption
no fstab
do dispositivo, a
saída será um pouco diferente da anterior. Por exemplo, se você ativou a criptografia Adiantum, o terceiro
campo será xchacha12,aes-adiantum-plain64
em vez de
aes-xts-plain64
.
Em seguida, execute vts_kernel_encryption_test para verificar a exatidão da criptografia de metadados e da FBE:
atest vts_kernel_encryption_test
ou:
vts-tradefed run vts -m vts_kernel_encryption_test
Problemas comuns
Durante a chamada para mount_all
, que monta a partição /data
criptografada com metadados, init
executa a ferramenta vdc. A ferramenta vdc
se conecta a vold
por binder
para configurar o
dispositivo criptografado com metadados e montar a partição. Durante essa
chamada, init
fica bloqueado e tenta ler ou definir o
bloco de propriedades init
até que mount_all
seja concluído.
Se, nessa fase, qualquer parte do trabalho de vold
for bloqueada direta ou
indiretamente na leitura ou configuração de uma propriedade, o deadlock vai ocorrer. É
importante garantir que vold
possa concluir o trabalho de leitura das
chaves, interagir com o Keymaster e ativar o diretório de dados sem
interagir mais com init
.
Se o Keymaster não for totalmente iniciado quando mount_all
for executado, ele não
vai responder a vold
até ler determinadas propriedades de
init
, resultando exatamente no deadlock descrito. Colocar
exec_start wait_for_keymaster
acima da invocação
mount_all
relevante conforme definido garante que o Keymaster esteja totalmente
em execução com antecedência e, assim, evite esse impasse.
Configuração no armazenamento adotável
Desde o Android 9, uma forma de criptografia de metadados é sempre ativada no armazenamento adotável sempre que a FBE está ativada, mesmo quando a criptografia de metadados não está ativada no armazenamento interno.
No AOSP, há duas implementações de criptografia de metadados no armazenamento
adotável: uma descontinuada, com base em dm-crypt
, e outra mais recente, baseada
em dm-default-key
. Para garantir que a implementação correta seja
selecionada para seu dispositivo, defina o valor correto para
PRODUCT_SHIPPING_API_LEVEL
em device.mk
. Por exemplo,
se o dispositivo for lançado com o Android 11 (nível 30 da API),
device.mk
precisará conter:
PRODUCT_SHIPPING_API_LEVEL := 30
Também é possível definir as seguintes propriedades do sistema para forçar o uso do novo método de criptografia de metadados de volume (e da nova versão da política FBE padrão), independente do nível da API de frete:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.volume.metadata.method=dm-default-key \ ro.crypto.dm_default_key.options_format.version=2 \ ro.crypto.volume.options=::v2
Método atual
Em dispositivos lançados com o Android 11 ou versões mais recentes,
a criptografia de metadados no armazenamento adaptável usa o módulo do kernel
dm-default-key
, assim como no armazenamento interno. Consulte os pré-requisitos acima para saber quais opções de configuração
do kernel serão ativadas. O hardware de criptografia inline que funciona no
armazenamento interno do dispositivo pode não estar disponível no armazenamento adaptável. Portanto,
CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK=y
pode ser necessário.
Por padrão, o método de criptografia de metadados de volume dm-default-key
usa o algoritmo de criptografia AES-256-XTS com setores de criptografia de 4.096 bytes. O
algoritmo pode ser substituído definindo a
propriedade do sistema ro.crypto.volume.metadata.encryption
. O valor dessa propriedade tem a mesma sintaxe da opção fstab metadata_encryption
descrita acima. Por exemplo, em dispositivos sem aceleração AES, a
criptografia Adiantum
pode ser ativada definindo
ro.crypto.volume.metadata.encryption=adiantum
.
Método legado
Em dispositivos lançados com o Android 10 ou versões anteriores, a criptografia
de metadados no armazenamento adaptável usa o módulo do kernel dm-crypt
em vez de dm-default-key
:
CONFIG_DM_CRYPT=y
Ao contrário do método dm-default-key
, o método dm-crypt
faz com que o conteúdo do arquivo seja criptografado duas vezes: uma com uma chave FBE e outra com
a chave de criptografia de metadados. Essa criptografia dupla reduz o desempenho e
não é necessária para atingir as metas de segurança da criptografia de metadados, já que o Android
garante que as chaves FBE sejam pelo menos tão difíceis de comprometer quanto a
chave de criptografia de metadados. Os fornecedores podem fazer personalizações do kernel para evitar a criptografia
dupla, principalmente implementando a
opção allow_encrypt_override
que o Android transmite para
dm-crypt
quando a propriedade do sistema
ro.crypto.allow_encrypt_override
está definida como true
.
Essas personalizações não têm suporte do kernel comum do Android.
Por padrão, o método de criptografia de metadados de volume dm-crypt
usa o
algoritmo de criptografia AES-128-CBC com ESSIV e setores criptográficos de 512 bytes. Isso
pode ser substituído pela configuração das propriedades do sistema abaixo, que também são
usadas para o FDE:
ro.crypto.fde_algorithm
seleciona o algoritmo de criptografia de metadados. As opções sãoaes-128-cbc
eadiantum
. O Adiantum só poderá ser usado se o dispositivo não tiver aceleração AES.ro.crypto.fde_sector_size
seleciona o tamanho do setor criptográfico. As opções são 512, 1024, 2048 e 4096. Para a criptografia Adiantum, use 4096.