O Android 7.0 e superior oferece suporte à criptografia baseada em arquivos (FBE). O FBE permite que diferentes arquivos sejam criptografados com diferentes chaves 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 arquivos, permissões e horários 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 para criptografia de metadados. Com a criptografia de metadados, uma única chave presente no momento da inicialização criptografa qualquer conteúdo que não seja criptografado pelo FBE. Esta chave é protegida pelo Keymaster, que por sua vez é protegido por inicialização verificada.
A criptografia de metadados está sempre habilitada no armazenamento adotável sempre que o FBE estiver habilitado. A criptografia de metadados também pode ser habilitada no armazenamento interno. Dispositivos lançados com Android 11 ou superior devem ter a criptografia de metadados no armazenamento interno habilitada.
Implementação em armazenamento interno
Você pode configurar a criptografia de metadados no armazenamento interno de novos dispositivos configurando o sistema de arquivos metadata
, alterando a sequência de inicialização e habilitando 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 deva mudar.
A criptografia de metadados requer que o módulo dm-default-key
esteja habilitado em seu kernel. No Android 11 e superior, dm-default-key
é compatível com os kernels comuns do Android, versão 4.14 e superior. Esta versão do dm-default-key
usa uma estrutura de criptografia independente de hardware e fornecedor chamada blk-crypto .
Para habilitar dm-default-key
, use:
CONFIG_BLK_INLINE_ENCRYPTION=y CONFIG_FS_ENCRYPTION_INLINE_CRYPT=y CONFIG_DM_DEFAULT_KEY=y
dm-default-key
usa hardware de criptografia em linha (hardware que criptografa/descriptografa dados enquanto eles estão no caminho de/para o dispositivo de armazenamento) quando disponível. Se você não for usar hardware de criptografia em linha, 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 em linha, você também deve ativar qualquer aceleração baseada em CPU disponível, conforme recomendado na documentação do FBE .
No Android 10 e versões anteriores, dm-default-key
não era compatível com o kernel comum do Android. Cabia, portanto, aos fornecedores implementar dm-default-key
.
Configurar sistema de arquivos de metadados
Como nada na partição userdata pode ser lido até que a chave de criptografia de metadados esteja presente, a tabela de partição deve reservar uma partição separada chamada "partição de metadados" para armazenar os blobs keymaster que protegem essa chave. A partição de metadados deve ter 16 MB.
fstab.hardware
deve incluir uma entrada para o sistema de arquivos de metadados que reside naquela partição montada em /metadata
, incluindo o sinalizador 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 usar ext4. Por 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 seguinte linha a BoardConfig-common.mk
:
BOARD_USES_METADATA_PARTITION := true
Mudanças na sequência de inicialização
Quando a criptografia de metadados é usada, vold
deve estar em execução antes de /data
ser montado. Para garantir que ele seja iniciado com antecedência suficiente, inclua a seguinte sub-rotina em init.hardware.rc
:
# We need vold early for metadata encryption on early-fs start vold
O Keymaster deve estar em execução e pronto antes que o init tente montar /data
.
init.hardware.rc
já deve conter uma instrução mount_all
que monta /data
na sub-rotina on late-fs
. Antes desta 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
Ativando a criptografia de metadados
Por fim, adicione keydirectory=/metadata/vold/metadata_encryption
à coluna fs_mgr_flags da entrada fstab
para userdata
. Por exemplo, uma linha fstab completa pode ser semelhante a:
/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. Isso pode ser substituído definindo a opção metadata_encryption
, também na coluna fs_mgr_flags :
- Em dispositivos que não possuem aceleração AES, a criptografia Adiantum pode ser habilitada configurando
metadata_encryption=adiantum
. - Em dispositivos que suportam chaves encapsuladas por hardware , a chave de criptografia de metadados pode ser transformada em encapsulada por hardware definindo
metadata_encryption=aes-256-xts:wrappedkey_v0
(ou equivalentementemetadata_encryption=:wrappedkey_v0
, já queaes-256-xts
é o algoritmo padrão).
Como a interface do kernel para dm-default-key
mudou no Android 11, você também precisa garantir que definiu o valor correto para PRODUCT_SHIPPING_API_LEVEL
em device.mk
. Por exemplo, se o seu dispositivo for iniciado com Android 11 (API de nível 30), device.mk
deverá conter:
PRODUCT_SHIPPING_API_LEVEL := 30
Você também pode definir a seguinte propriedade do sistema para forçar o uso da nova API dm-default-key
independentemente do nível da API de envio:
PRODUCT_PROPERTY_OVERRIDES += \ ro.crypto.dm_default_key.options_format.version=2
Validação
Para verificar se a criptografia de metadados está habilitada e funcionando corretamente, execute os testes descritos abaixo. Também esteja atento aos problemas comuns descritos abaixo.
Testes
Comece executando o seguinte comando para verificar se a criptografia de metadados está habilitada no armazenamento interno:
adb root
adb shell dmctl table userdata
A saída deve ser semelhante a:
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ê substituiu 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 acima. 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 do 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 por metadados, init
executa a ferramenta vdc. A ferramenta vdc se conecta ao vold
over binder
para configurar o dispositivo criptografado por metadados e montar a partição. Durante esta chamada, init
será bloqueado e as tentativas de ler ou definir as propriedades init
serão bloqueadas até que mount_all
termine. Se, nesta fase, qualquer parte do trabalho do vold
for direta ou indiretamente bloqueada na leitura ou definição de uma propriedade, ocorrerá um impasse. É importante garantir que vold
possa concluir o trabalho de leitura das chaves, interagir com o Keymaster e montar o diretório de dados sem interagir mais com init
.
Se o Keymaster não estiver totalmente iniciado quando mount_all
for executado, ele não responderá ao vold
até que tenha lido certas propriedades de init
, resultando exatamente no conflito descrito. Colocar exec_start wait_for_keymaster
acima da invocação mount_all
relevante conforme estabelecido garante que o Keymaster esteja totalmente em execução antecipadamente e, assim, evita esse impasse.
Configuração no armazenamento adotável
Desde o Android 9, uma forma de criptografia de metadados está sempre habilitada no armazenamento adotável sempre que o FBE estiver habilitado, mesmo quando a criptografia de metadados não estiver habilitada no armazenamento interno.
No AOSP, existem duas implementações de criptografia de metadados no armazenamento adotável: uma obsoleta baseada em dm-crypt
e uma mais recente baseada em dm-default-key
. Para garantir que a implementação correta seja selecionada para seu dispositivo, certifique-se de ter definido o valor correto para PRODUCT_SHIPPING_API_LEVEL
em device.mk
. Por exemplo, se o seu dispositivo for iniciado com Android 11 (API de nível 30), device.mk
deverá conter:
PRODUCT_SHIPPING_API_LEVEL := 30
Você também pode definir as seguintes propriedades do sistema para forçar o uso do novo método de criptografia de metadados de volume (e a nova versão padrão da política FBE), independentemente do nível da API de envio:
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 com Android 11 ou superior, a criptografia de metadados no armazenamento adotá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 ativar. Observe que o hardware de criptografia em linha que funciona no armazenamento interno do dispositivo pode estar indisponível no armazenamento adotável e, 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 criptográficos de 4.096 bytes. O algoritmo pode ser substituído configurando a propriedade do sistema ro.crypto.volume.metadata.encryption
. O valor desta propriedade tem a mesma sintaxe que a opção fstab metadata_encryption
descrita acima. Por exemplo, em dispositivos que não possuem aceleração AES, a criptografia Adiantum pode ser habilitada configurando ro.crypto.volume.metadata.encryption=adiantum
.
Método legado
Em dispositivos com Android 10 ou inferior, a criptografia de metadados no armazenamento adotá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 vez com uma chave FBE e uma vez 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, pois 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 no kernel para evitar a criptografia dupla, em particular implementando a opção allow_encrypt_override
que o Android passará para dm-crypt
quando a propriedade do sistema ro.crypto.allow_encrypt_override
for definida como true
. Essas personalizações não são suportadas pelo 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 definindo as seguintes propriedades do sistema (que também são usadas para FDE):
-
ro.crypto.fde_algorithm
seleciona o algoritmo de criptografia de metadados. As opções sãoaes-128-cbc
eadiantum
. Adiantum só pode 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 criptografia Adiantum, use 4096.