A criptografia de disco completo é o processo de codificação de todos os dados do usuário em um dispositivo Android usando uma chave criptografada. Uma vez que um dispositivo é criptografado, todos os dados criados pelo usuário são criptografados automaticamente antes de carregá-lo no disco e em todas as leituras automaticamente descriptografar os dados antes de retorná-los ao processo de chamada.
A criptografia de disco completo foi introduzida no Android na versão 4.4, mas no Android 5.0, estes novos recursos:
- Criou uma criptografia rápida, que criptografa apenas os blocos usados na partição de dados. para evitar que a primeira inicialização demore muito tempo. Somente sistemas de arquivos ext4 e f2fs oferecem suporte à criptografia rápida.
- Adição de
forceencrypt
flag fstab para criptografar na primeira inicialização. - Foi adicionado suporte a padrões e criptografia sem uma senha.
- Adição de armazenamento protegido por hardware da chave de criptografia usando Confiável Capacidade de assinatura do ambiente de execução (TEE), como em um TrustZone. Consulte Como armazenar a chave criptografada para mais informações detalhes.
Cuidado:dispositivos que fizeram upgrade para o Android 5.0 e, em seguida, criptografados podem voltar a um estado não criptografado após a redefinição para a configuração original. Novo Android 5.0 dispositivos criptografados na primeira inicialização não podem retornar a um estado não criptografado.
Como funciona a criptografia de disco completo do Android
A criptografia de disco completo do Android é baseada em dm-crypt
, que é um kernel
que funciona na camada de dispositivos de blocos. Devido ao
isso, a criptografia funciona com o Embedded MultiMediaCard (eMMC) e
dispositivos flash semelhantes que se apresentam ao kernel como blocos
dispositivos. A criptografia não é possível com o YAFFS, que se comunica diretamente com um
flash chip NAND.
O algoritmo de criptografia usa o Padrão de criptografia avançada 128 (AES) com cifra de bloco encadeada (CBC) e ESSIV:SHA256. A chave mestra é criptografada com AES de 128 bits por chamadas para a biblioteca OpenSSL. Você deve usar 128 bits ou mais para a chave (com 256 opcional).
Observação:OEMs podem usar 128 bits ou mais recente para criptografar a chave mestra.
Na versão Android 5.0, há quatro tipos de estados de criptografia:
- padrão
- PIN
- senha
- padrão
Na primeira inicialização, o dispositivo cria uma chave mestra de 128 bits gerada aleatoriamente e gera um hash com uma senha padrão e um sal armazenado. A senha padrão é: "default_password" No entanto, o hash resultante também é assinado por um TEE (como o TrustZone), que usa um hash da assinatura para criptografar a chave mestra.
É possível encontrar a senha padrão definida no arquivo cryptfs.cpp do Android Open Source Project .
Quando o usuário define um PIN/senha ou senha no dispositivo, apenas a chave de 128 bits são recriptografados e armazenados. (ou seja, alterações de PIN/senha/padrão de usuário NÃO causam uma nova criptografia dos dados do usuário.) Observe que dispositivo gerenciado podem estar sujeitos a restrições de PIN, padrão ou senha.
A criptografia é gerenciada por init
e vold
.
O init
chama vold
, e o vold define as propriedades para acionar.
eventos no init. Outras partes do sistema
analise também as propriedades para realizar tarefas como o status do relatório, peça uma
senha ou solicitação de redefinição de fábrica no caso de um erro fatal. Para invocar
recursos de criptografia em vold
, o sistema usa a ferramenta de linha de comando
Comandos cryptfs
de vdc
: checkpw
,
restart
, enablecrypto
, changepw
,
cryptocomplete
, verifypw
e setfield
,
getfield
, mountdefaultencrypted
, getpwtype
getpw
e clearpw
.
Para criptografar, descriptografar ou excluir permanentemente /data
, /data
não pode ser montado. No entanto, para mostrar qualquer interface do usuário (UI), a
O framework precisa ser iniciado, e o framework exige que /data
seja executado. Para
resolver esse enigma, um sistema de arquivos temporário é montado em /data
.
Isso permite que o Android solicite senhas, mostre o progresso ou sugira dados
se necessário. No entanto, ele impõe a limitação de que, para mudar da
temporário para o sistema de arquivos /data
verdadeiro, o sistema deve
interromper todos os processos com arquivos abertos no sistema de arquivos temporário e reiniciar esses
processos no sistema de arquivos /data
real. Para isso, todos os serviços
precisa estar em um destes três grupos: core
, main
e
late_start
core
: nunca desligue depois de iniciar.main
: encerre e reinicie após inserir a senha do disco.late_start
: não é iniciado até que/data
seja descriptografado e ativado.
Para acionar essas ações, a propriedade vold.decrypt
é definida como
várias strings.
Para encerrar e reiniciar os serviços, os comandos init
são:
class_reset
: interrompe um serviço, mas permite que ele seja reiniciado com class_start.class_start
: reinicia um serviço.class_stop
: interrompe um serviço e adiciona uma sinalizaçãoSVC_DISABLED
. Os serviços interrompidos não respondem aclass_start
.
Fluxos
Existem quatro fluxos para um dispositivo criptografado. Um dispositivo é criptografado apenas uma vez e segue um fluxo de inicialização normal.
- Criptografe um dispositivo não criptografado anteriormente:
- Criptografar um novo dispositivo com
forceencrypt
: criptografia obrigatória na primeira inicialização (a partir do Android L). - Criptografar um dispositivo existente: criptografia iniciada pelo usuário (Android K e versões anteriores).
- Criptografar um novo dispositivo com
- Inicialize um dispositivo criptografado:
- Inicializar um dispositivo criptografado sem senha: inicializar um dispositivo criptografado que não tenha uma senha definida (relevante para dispositivos com Android 5.0 ou superior).
- Inicializar um dispositivo criptografado com uma senha: inicializar um dispositivo criptografado que tem uma senha definida.
Além desses fluxos, o dispositivo também pode falhar ao criptografar /data
.
Cada um dos fluxos é explicado em detalhes abaixo.
Criptografar um novo dispositivo com forceencrypt
Esta é a primeira inicialização normal de um dispositivo Android 5.0.
- Detectar sistema de arquivos não criptografado com a sinalização
forceencrypt
O
/data
não está criptografado, mas precisa ser porque oforceencrypt
exige isso. Desconecte/data
. - Começar a criptografar
/data
vold.decrypt = "trigger_encryption"
acionainit.rc
, o que fará com quevold
criptografe/data
sem senha. Nenhum é definido porque este deve ser um novo dispositivo. - Montar tmpfs
vold
monta um/data
de tmpfs (usando as opções de tmpfs dero.crypto.tmpfs_options
) e define a propriedadevold.encrypt_progress
como 0. Ovold
prepara o tmpfs/data
para inicializar um sistema criptografado e define os propriedadevold.decrypt
como:trigger_restart_min_framework
- Exibir a estrutura para mostrar o progresso
Como o dispositivo praticamente não tem dados para criptografar, a barra de progresso muitas vezes não aparecem porque a criptografia acontece muito rapidamente. Consulte Criptografar um dispositivo existente para mais detalhes sobre a interface de progresso.
- Quando
/data
estiver criptografado, remova o frameworkvold
definevold.decrypt
comotrigger_default_encryption
, que inicia o serviçodefaultcrypto
. (Isso inicia o fluxo abaixo para a montagem de um os dados do usuário criptografados padrão).trigger_default_encryption
verifica tipo de criptografia para saber se/data
está criptografado com ou sem um senha. Como os dispositivos Android 5.0 são criptografados na primeira inicialização, não deve não pode ser definida; Portanto, descriptografamos e ativamos/data
. - Montar
/data
init
então monta/data
em um RAMDisk tmpfs usando parâmetros que ele extrai doro.crypto.tmpfs_options
, que é definido eminit.rc
. - Iniciar framework
vold
definevold.decrypt
comotrigger_restart_framework
, que continua a inicialização normal de desenvolvimento de software.
Criptografar um dispositivo existente
Isso é o que acontece quando você criptografa um dispositivo Android K ou anterior que foi migrado para L.
Esse processo é iniciado pelo usuário e é chamado de "criptografia no local" o código. Quando um usuário seleciona para criptografar um dispositivo, a interface garante que o a bateria está totalmente carregada e o carregador está conectado, de energia para concluir o processo de criptografia.
Aviso:se o dispositivo ficar sem energia e for desligado antes de terminar durante a criptografia, os dados dos arquivos são deixados em um estado parcialmente criptografado. O dispositivo deve para a configuração original e todos os dados serão perdidos.
Para ativar a criptografia no local, o vold
inicia uma repetição para ler cada
específico do dispositivo em bloco real e gravá-lo
ao dispositivo de bloqueio de criptografia. O vold
verifica se um setor está em
antes de ler e gravar, o que facilita
a criptografia de dados muito mais rápido em um novo dispositivo com pouco ou nenhum dado.
Estado do dispositivo: defina ro.crypto.state = "unencrypted"
.
e execute o gatilho on nonencrypted
init
para continuar a inicialização.
- Verificar senha
A interface chama
vold
com o comandocryptfs enablecrypto inplace
. em quepasswd
é a senha da tela de bloqueio do usuário. - Remover a estrutura
vold
verifica se há erros, retorna -1 se não for possível criptografar e retorna. imprime um motivo no registro. Se puder criptografar, ele definirá a propriedadevold.decrypt
. paratrigger_shutdown_framework
. Isso faz com queinit.rc
interromper serviços nas classeslate_start
emain
. - Criar um rodapé de criptografia
- Criar um arquivo de navegação estrutural
- Reinicializar
- Detectar arquivo de navegação estrutural
- Começar a criptografar
/data
Em seguida, o
vold
configura o mapeamento de criptografia, que cria um dispositivo de bloco de criptografia virtual. mapeado para o dispositivo de bloco real, mas criptografa cada setor conforme escrito, e descriptografa cada setor à medida que é lido. Em seguida,vold
cria e grava os metadados de criptografia. - Durante a criptografia, ative o tmpfs
vold
monta um/data
de tmpfs (usando as opções de tmpfs dero.crypto.tmpfs_options
) e define a propriedadevold.encrypt_progress
a 0.vold
prepara os tmpfs/data
para inicializar um sistema criptografado e define a propriedadevold.decrypt
para:trigger_restart_min_framework
- Exibir a estrutura para mostrar o progresso
trigger_restart_min_framework
faz com queinit.rc
iniciar a classe de serviçosmain
. Quando o framework percebe quevold.encrypt_progress
é definido como 0, e a barra de progresso é mostrada. UI, que consulta essa propriedade a cada cinco segundos e atualiza uma barra de progresso. O loop de criptografia atualiza ovold.encrypt_progress
sempre que ele criptografa outro percentual da partição. - Quando
/data
estiver criptografado, atualize o rodapé de criptografiaQuando
/data
for criptografado, ovold
será apagado a flagENCRYPTION_IN_PROGRESS
nos metadados.Quando o dispositivo é desbloqueado, a senha é usada para criptografar a chave mestra, e o rodapé de criptografia será atualizado.
Se a reinicialização falhar por algum motivo, o
vold
vai definir a propriedade.vold.encrypt_progress
aerror_reboot_failed
e a interface deve exibir uma mensagem pedindo que o usuário pressione um botão para reiniciar o dispositivo. Isso não deve acontecer em nenhum momento.
Como iniciar um dispositivo criptografado com criptografia padrão
Isso é o que acontece quando você inicializa um dispositivo criptografado sem senha. Como os dispositivos Android 5.0 são criptografados na primeira inicialização, não deve haver senha. Portanto, esse é o estado de criptografia padrão.
- Detectar
/data
criptografado sem senhaDetectar se o dispositivo Android está criptografado porque
/data
não pode ser montado e uma das flagsencryptable
ouforceencrypt
foi definido.vold
definevold.decrypt
comotrigger_default_encryption
, que inicia o serviçodefaultcrypto
.trigger_default_encryption
verifica o tipo de criptografia para confirmar se/data
está criptografado com ou sem uma senha. - Descriptografar /data
Cria o dispositivo
dm-crypt
no dispositivo de transferência por blocos para que ele seja está pronto para uso. - Montar /dados
Em seguida,
vold
monta a partição/data
real descriptografada. e prepara a nova partição. Ele define a propriedadevold.post_fs_data_done
como 0 e, em seguida, definevold.decrypt
. paratrigger_post_fs_data
. Isso faz com queinit.rc
seja executado aos comandospost-fs-data
. Eles vão criar todos os diretórios necessários ou links e, em seguida, definavold.post_fs_data_done
como 1.Depois que
vold
encontra "1" nessa propriedade, ele define a propriedade.vold.decrypt
para:trigger_restart_framework.
Isso faz com queinit.rc
inicie serviços na classemain
novamente e iniciar os serviços na classelate_start
para a primeira desde a inicialização. - Iniciar framework
Agora, o framework inicializa todos os serviços usando a
/data
descriptografada. e o sistema está pronto para uso.
Como iniciar um dispositivo criptografado sem a criptografia padrão
Isso é o que acontece quando você inicializa um dispositivo criptografado que tem senha. A senha do dispositivo pode ser um PIN, um padrão ou uma senha.
- Detectar dispositivo criptografado com uma senha
Detecta se o dispositivo Android está criptografado porque a flag
ro.crypto.state = "encrypted"
vold
definevold.decrypt
comotrigger_restart_min_framework
porque/data
é criptografados com uma senha. - Montar tmpfs
init
define cinco propriedades para salvar as opções de montagem iniciais. dado para/data
com parâmetros transmitidos deinit.rc
.vold
usa estas propriedades para configurar o mapeamento de criptografia:ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags
(Número hexadecimal de 8 dígitos ASCII precedido por 0x)
- Iniciar framework para solicitar senha
O framework é iniciado e detecta que
vold.decrypt
está definido comotrigger_restart_min_framework
. Isso diz à estrutura que é inicializando em um disco/data
tmpfs e ele precisa da senha do usuário.Primeiro, no entanto, ele precisa verificar se o disco foi devidamente criptografado. Ela envia o comando
cryptfs cryptocomplete
paravold
.vold
retorna 0 se a criptografia tiver sido concluída, -1 em caso de erro interno ou -2 se a criptografia não for concluída.vold
determina isso procurando nos metadados de criptografia do arquivoCRYPTO_ENCRYPTION_IN_PROGRESS
. Se ela estiver definida, o processo de criptografia foi interrompido, e não dados utilizáveis no dispositivo. Sevold
retornar um erro, a interface deverá exibirá uma mensagem ao usuário para reinicializar e redefinir o dispositivo para a configuração original e conceder ao usuário um botão para pressionar. - Descriptografar dados com senha
Quando
cryptfs cryptocomplete
for bem-sucedido, o framework exibe uma IU solicitando a senha do disco. A interface verifica a senha enviando o comandocryptfs checkpw
paravold
. Se o a senha está correta (o que é determinado pela montagem bem-sucedida do descriptografou/data
em um local temporário e o desconectou),vold
salva o nome do dispositivo de bloco descriptografado na propriedadero.crypto.fs_crypto_blkdev
e retorna o status 0 para a interface. Se o a senha estiver incorreta, ele retornará -1 para a interface. - Interromper framework
A interface mostra um gráfico de inicialização criptográfica e chama
vold
com o comandocryptfs restart
.vold
define a propriedade.vold.decrypt
paratrigger_reset_main
, o que fazinit.rc
paraclass_reset main
. Esta ação interrompe todos os serviços na classe principal, o que permite que o/data
de tmpfs seja desconectado. - Montar
/data
Em seguida,
vold
monta a partição/data
real descriptografada. e prepara a nova partição (que pode nunca ter sido preparada se ela foi criptografada com a opção "Limpar", que não é aceita nas lançamento). Ele define a propriedadevold.post_fs_data_done
como 0 e depois definevold.decrypt
comotrigger_post_fs_data
. Isso faz com queinit.rc
para executar os comandospost-fs-data
. Eles vão criar quaisquer diretórios ou links necessários e, em seguida, definirvold.post_fs_data_done
para 1. Assim quevold
vir o 1 em essa propriedade, ele define a propriedadevold.decrypt
comotrigger_restart_framework
Isso faz com que oinit.rc
seja iniciado serviços na classemain
novamente e também iniciam serviços na classelate_start
pela primeira vez desde a inicialização. - Iniciar o framework completo
Agora, o framework inicializa todos os serviços usando a
/data
descriptografada. do sistema e ele está pronto para uso.
Falha
Um dispositivo que não é descriptografado pode estar errado por alguns motivos. O dispositivo começa com a série normal de etapas de inicialização:
- Detectar dispositivo criptografado com uma senha
- Montar tmpfs
- Iniciar framework para solicitar senha
No entanto, depois que o framework é aberto, o dispositivo pode encontrar alguns erros:
- A senha corresponde, mas não é possível descriptografar os dados
- O usuário digita a senha incorreta 30 vezes
Se esses erros não forem resolvidos, solicite que o usuário faça a exclusão permanente para a configuração original:
Se o vold
detectar um erro durante o processo de criptografia e se
nenhum dado foi destruído ainda e o framework está ativo, vold
define
a propriedade vold.encrypt_progress
para error_not_encrypted
.
A interface solicita que o usuário reinicie e informa o processo de criptografia
nunca começou. Se o erro ocorrer depois que a estrutura for desativada, mas
antes de a interface da barra de progresso ser ativada, o vold
vai reinicializar o sistema. Se
a reinicialização falhar, ela definirá vold.encrypt_progress
como
error_shutting_down
e retorna -1; mas não haverá nada
para detectar o erro. Isso não é esperado.
Se o vold
detectar um erro durante o processo de criptografia, ele definirá
De vold.encrypt_progress
a error_partially_encrypted
e retorna -1. A interface vai mostrar uma mensagem informando que a criptografia
falhou e forneça um botão para o usuário redefinir o dispositivo para a configuração original.
Como armazenar a chave criptografada
A chave criptografada é armazenada nos metadados de criptografia. O suporte de hardware é implementado usando a capacidade de assinatura do ambiente de execução confiável (TEE). Antes, criptografamos a chave mestra com uma chave gerada aplicando scrypt à senha do usuário e ao sal armazenado. Para tornar a chave resiliente contra ataques prontos para uso, estendemos esse algoritmo assinando a chave resultante com uma chave TEE armazenada. A assinatura resultante é, então, transformada em um de comprimento por mais uma aplicação de scrypt. Essa chave é usada para criptografar e descriptografar a chave mestra. Para armazenar essa chave:
- Gere uma chave de criptografia de disco (DEK, na sigla em inglês) aleatória e com um sal de 16 bytes.
- Aplique o scrypt à senha do usuário e o sal para produzir um intermediário de 32 bytes chave 1 (IK1).
- Preencha o IK1 com zero bytes para o tamanho da chave privada vinculada a hardware (HBK). Especificamente, preenchemos como: 00 || IK1 || 00..00; um byte zero, 32 IK1 bytes, 223 de zero bytes.
- Assine o IK1 preenchido com HBK para produzir o IK2 de 256 bytes.
- Aplique o scrypt ao IK2 e um sal (o mesmo sal da etapa 2) para produzir o IK3 de 32 bytes.
- Usar os primeiros 16 bytes de IK3 como KEK e os últimos 16 bytes como IV.
- Criptografar DEK com AES_CBC, chave KEK e vetor de inicialização IV.
Como alterar a senha
Quando um usuário decide alterar ou remover a senha nas configurações, a interface envia
o comando cryptfs changepw
para vold
;
vold
recriptografa a chave mestra do disco com a nova senha.
Propriedades de criptografia
vold
e init
se comunicam entre si pela
de configuração do Terraform. Confira uma lista de propriedades disponíveis para criptografia.
Propriedades do Vold
Propriedade | Descrição |
---|---|
vold.decrypt trigger_encryption |
Criptografar o drive sem senha. |
vold.decrypt trigger_default_encryption |
Verifique se o drive está criptografado sem senha.
Se estiver, descriptografe e ative
Caso contrário, defina vold.decrypt como trigger_restart_min_framework. |
vold.decrypt trigger_reset_main |
Definido por vold para encerrar a interface solicitando a senha do disco. |
vold.decrypt trigger_post_fs_data |
Definido pelo vold para preparar /data com os diretórios necessários etc. |
vold.decrypt trigger_restart_framework |
Definido por vold para iniciar o framework real e todos os serviços. |
vold.decrypt trigger_shutdown_framework |
Definido por vold para encerrar o framework completo e iniciar a criptografia. |
vold.decrypt trigger_restart_min_framework |
Definido pelo vold para iniciar o
da barra de progresso para criptografia ou
solicitação de senha, dependendo
o valor de ro.crypto.state . |
vold.encrypt_progress |
Quando o framework iniciar, Se esta propriedade estiver definida, insira o modo de interface da barra de progresso. |
vold.encrypt_progress 0 to 100 |
A interface da barra de progresso deve exibirá o valor percentual definido. |
vold.encrypt_progress error_partially_encrypted |
A interface da barra de progresso vai mostrar uma mensagem informando que a criptografia falhou. dar ao usuário a opção de redefinir o dispositivo para a configuração original. |
vold.encrypt_progress error_reboot_failed |
A interface da barra de progresso mostra uma mensagem informando a criptografia concluído e dê ao usuário um botão para reinicializar o dispositivo. Este erro não é esperado que aconteça. |
vold.encrypt_progress error_not_encrypted |
A interface da barra de progresso deve exibir uma mensagem informando um erro ocorreu, nenhum dado foi criptografado perdidos e dar ao usuário um botão para reinicializar o sistema. |
vold.encrypt_progress error_shutting_down |
A interface da barra de progresso não está em execução, então não está claro quem vai responder para este erro. E isso nunca deveria acontecer de qualquer maneira. |
vold.post_fs_data_done 0 |
Definido por vold pouco antes de definir vold.decrypt
para trigger_post_fs_data . |
vold.post_fs_data_done 1 |
Definido por init.rc ou
init.rc logo após a conclusão da tarefa post-fs-data . |
propriedades init
Propriedade | Descrição |
---|---|
ro.crypto.fs_crypto_blkdev |
Definido pelo comando vold checkpw para uso posterior
pelo comando vold restart . |
ro.crypto.state unencrypted |
Definido por init para informar que este sistema está sendo executado com uma
/data ro.crypto.state encrypted . Definido por init para informar
Este sistema está sendo executado com um /data criptografado. |
|
Essas cinco propriedades são definidas
init quando tenta montar /data com parâmetros transmitidos da
init.rc O vold usa isso para configurar o mapeamento de criptografia. |
ro.crypto.tmpfs_options |
Definido por init.rc com as opções que o init precisa usar ao
montar o sistema de arquivos tmpfs /data . |
Ações de inicialização
on post-fs-data on nonencrypted on property:vold.decrypt=trigger_reset_main on property:vold.decrypt=trigger_post_fs_data on property:vold.decrypt=trigger_restart_min_framework on property:vold.decrypt=trigger_restart_framework on property:vold.decrypt=trigger_shutdown_framework on property:vold.decrypt=trigger_encryption on property:vold.decrypt=trigger_default_encryption