Full-disk encryption is the process of encoding all user data on an Android device using anencrypted key. Uma vez que um dispositivo é criptografado, todos os dados criados pelo usuário são criptografados automaticamente antes de submetê-los ao disco e todos os dados são descriptografados automaticamente antes de retornar ao processo de chamada.
Criptografia de disco completo foi introduzida ao Android no 4.4, mas o Android 5.0 introduziu estas novas funcionalidades:
- Criação rápida, que apenas criptografa blocos usados na partição de dados para evitar que o primeiro boot demore muito tempo. Somente sistemas de arquivos ext4 e f2fs suportam atualmente criptografia rápida.
- Adicionado a bandeira
forceencrypt
fstab para encriptar no primeiro arranque. - Adicionado suporte para padrões e criptografia sem senha.
- Adicionado o armazenamento da chave de encriptação com suporte a hardware usando a capacidade de assinatura do Trusted Execution Environment (TEE) (tal como em uma Zona de Confiança). Veja Armazenando a chave criptografada para mais detalhes.
Cautela: Os dispositivos atualizados para o Android 5.0 e depois criptografados podem ser devolvidos a um estado não criptografado por redefinição de dados de fábrica. Os novos dispositivos Android 5.0 criptografados na primeira inicialização não podem ser devolvidos a um estado não criptografado.
- Como funciona a criptografia do disco completo do Android
- Fluxos
- Encryptar um novo dispositivo com forceencrypt
- Criptografar um dispositivo existente
- Iniciar um dispositivo criptografado com criptografia padrão
- Iniciar um dispositivo criptografado sem criptografia padrão
- Failure
- Armazenar a chave encriptada
- Mudando a senha
- Propriedades de encriptação
- Propriedades antigas
- init properties
- Init actions
Como funciona a criptografia do disco completo do Android
A criptografia do disco completo do Android é baseada em dm-crypt
, que é uma característica do kernel que funciona na camada de dispositivo de bloco. Por causa disso, a criptografia funciona com o Embedded MultiMediaCard (eMMC) e dispositivos flash similares que se apresentam ao kernel como dispositivos de bloqueio. A encriptação não é possível com YAFFS, que fala diretamente com um chip flash rawNAND.
O algoritmo de encriptação é 128 Advanced Encryption Standard (AES) withcipher-block chaining (CBC) e ESSIV:SHA256. A chave mestre é criptografada com AES de 128 bits através de chamadas para a biblioteca OpenSSL. Você deve usar 128 bits ou mais para a chave (com 256 sendo opcional).
Nota: OEMs podem usar 128 bits ou mais para criptografar a chave mestre.
No lançamento do Android 5.0, há quatro tipos de estados de criptografia:
>
- valor por defeito
- PIN
- senha
- padrão
Primeiro boot do componente, o dispositivo cria uma chave-mestra de 128 bits gerada aleatoriamente e depois a hashes com uma senha padrão e sal armazenado. A senha padrão é: “default_password” Entretanto, o hash resultante também é assinado através de um TEE (como TrustZone),que usa um hash da assinatura para criptografar a chave mestre.
Você pode encontrar a senha padrão definida no arquivo cryptfs.cppfile.
Quando o usuário define o PIN/pass ou senha no dispositivo, apenas a chave de 128 bits é re-encriptada e armazenada. Note que o dispositivo gerenciado pode estar sujeito ao PIN, padrão ou restrições de senha.
A criptografia é gerenciada por init
e vold
.init
chamadas vold
, e vold define propriedades para acionar eventos no init. Outras partes do sistema também olham para as propriedades para conduzir tarefas como reportar o status, pedir apassword, ou pedir para reiniciar a fábrica no caso de um erro fatal. Para invocar funcionalidades de encriptação em vold
, o sistema usa a ferramenta de linha de comandovdc
‘s cryptfs
comandos: checkpw
,restart
, enablecrypto
, changepw
,cryptocomplete
, verifypw
, setfield
,getfield
, mountdefaultencrypted
, getpwtype
,getpw
, e clearpw
.
Para encriptar, desencriptar ou limpar /data
, /data
não deve ser montado. Entretanto, para mostrar qualquer interface de usuário (IU), o framework deve iniciar e o framework requer /data
para ser executado. Para resolver este enigma, um sistema de arquivos temporário é montado em /data
. Isto permite que o Android solicite senhas, mostre o progresso ou sugira um datawipe conforme necessário. Ele impõe a limitação de que para mudar do sistema de arquivos temporário para o verdadeiro sistema de arquivos /data
, o sistema deve parar cada processo com arquivos abertos no sistema de arquivos temporário e reiniciar os processos no verdadeiro sistema de arquivos /data
. Para fazer isso, todos os serviços devem estar em um dos três grupos: core
, main
, e late_start
.
-
core
: Nunca desligue depois de iniciar. -
main
: Desligar e depois reiniciar após a senha do disco ser inserida. -
late_start
: Só inicia depois de/data
ter sido desencriptado e montado.
: Para activar estas acções, a propriedade vold.decrypt
é definida strings tovarious.Para matar e reiniciar serviços, os comandos init
são:
-
class_reset
: Pára um serviço mas permite que seja reiniciado com class_start. -
class_start
: Reinicia um serviço. -
class_stop
: Pára um serviço e adiciona uma bandeiraSVC_DISABLED
. Serviços parados não respondem aclass_start
.
Fluxos
Há quatro fluxos para um dispositivo criptografado. Um dispositivo é criptografado apenas uma vez e depois segue um fluxo de inicialização normal.
- Encriptar um dispositivo previamente não encriptado:
- Criptografar um novo dispositivo com
forceencrypt
: Encriptação obrigatória na primeira inicialização (começando no Android L). - Criptografar um dispositivo existente: Encriptação iniciada pelo utilizador (Android K e anteriores).
>
- Criptografar um novo dispositivo com
- Bootar um dispositivo criptografado:
- Iniciar um dispositivo criptografado sem senha: Iniciar um dispositivo criptografado que não tenha senha definida (relevante para dispositivos rodando Android 5.0 e posteriores).
- Iniciar um dispositivo encriptado com uma palavra-passe: Arrancar um dispositivo encriptado que tenha uma palavra-passe definida.
Além desses fluxos, o dispositivo também pode falhar em criptografar /data
.Cada um dos fluxos é explicado em detalhes abaixo.
Encryptar um novo dispositivo com forceencrypt
Esta é a primeira inicialização normal para um Android 5.0 device.
- Detect unencrypted filesystem with
forceencrypt
flag/data
is not encrypted but needs to be becauseforceencrypt
Unmount it.Unmount/data
. - Iniciar encriptação
/data
vold.decrypt = "trigger_encryption"
disparainit.rc
,o que fará com quevold
encripte/data
sem senha.(Nenhum está definido porque este deve ser um novo dispositivo.) - monta tmpfs
vold
monta um tmpfs/data
(usando as opções tmpfs dero.crypto.tmpfs_options
) e define a propriedadevold.encrypt_progress
para 0.vold
prepara o tmpfs/data
para inicializar um sistema encriptado e define a propriedadevold.decrypt
para:trigger_restart_min_framework
- Traz o framework para mostrar o progresso
Porque o dispositivo praticamente não tem dados a serem criptografados, a barra de progresso não irá aparecer porque a criptografia acontece tão rapidamente. VejaEncrypt an existing device for moredetails about the progress UI.
- When
/data
is encrypted, take down the frameworkvold
setsvold.decrypt
totrigger_default_encryption
which starts thedefaultcrypto
service. (Isto inicia o fluxo abaixo para montar dados de usuário criptografados adefault.)trigger_default_encryption
verifica o tipo de criptografia para ver se/data
está criptografado com ou sem apassword. Como os dispositivos Android 5.0 são criptografados no primeiro boot, não deve haver nenhuma senha definida; portanto decodificamos e montamos/data
. - Montar
/data
init
e depois montamos/data
em um tmpfs RAMDisk usando parâmetros que ele pega dero.crypto.tmpfs_options
, que está definido eminit.rc
. - Estrutura de arranque
Set
vold
atrigger_restart_framework
, que continua com o processo de arranque habitual.
Criptografar um dispositivo existente
É o que acontece quando você criptografa um K não criptografado do Android ou dispositivo anterior que foi migrado para L.
Este processo é iniciado pelo usuário e é referido como “inplace encryption” no código. Quando um usuário seleciona criptografar um dispositivo, a IU se certifica que a bateria está totalmente carregada e o adaptador AC está conectado para que haja energia suficiente para terminar o processo de criptografia.
Aviso: Se o dispositivo ficar sem energia e se desligar antes de ter terminado a encriptação, os dados do ficheiro são deixados num estado parcialmente encriptado. O dispositivo deve ser reiniciado de fábrica e todos os dados são perdidos.
Para ativar a criptografia no local, vold
inicia um loop para ler o eachsector do dispositivo de bloco real e, em seguida, escrevê-lo no dispositivo de bloco criptográfico. vold
verifica se um setor está em uso antes de lê-lo e escrevê-lo, o que torna a criptografia muito mais rápida em um novo dispositivo que tem pouco ou nenhum dado.
Estado do dispositivo: Defina ro.crypto.state = "unencrypted"
e execute o comando on nonencrypted
init
gatilho para continuar a inicialização.
- Verifique a senha
A IU chama
vold
com o comandocryptfs enablecrypto inplace
ondepasswd
é a senha da tela de bloqueio do usuário. - Anota o framework
vold
verifica se há erros, retorna -1 se não puder criptografar, e imprime um motivo no log. Se conseguir encriptar, define a propriedadevold.decrypt
paratrigger_shutdown_framework
. Isto causainit.rc
serviços tostop nas classeslate_start
emain
. - Criar um rodapé criptográfico
- Criar um ficheiro de migalhas de pão
- Reboot
- Detectar ficheiro de migalhas de pão
- Comece a encriptar
/data
vold
depois configura o mapeamento criptográfico, que cria um bloco criptográfico virtual que desenha os mapas no dispositivo de bloco real, mas codifica cada sector tal como é escrito, e descriptografa cada sector tal como é lido.vold
então cria e escreve os metadados criptográficos. - Enquanto está criptografando, monte tmpfs
vold
monta um tmpfs/data
(usando a opção tmpfssf dero.crypto.tmpfs_options
) e define a propriedadevold.encrypt_progress
para 0.vold
prepara o tmpfs/data
para inicializar um sistema criptografado e define a propriedadevold.decrypt
para:trigger_restart_min_framework
- Traz o framework para mostrar o progresso
trigger_restart_min_framework
causasinit.rc
iniciar a classe de serviçosmain
. Quando o framework vê quevold.encrypt_progress
está configurado em 0, ele traz a barra de progressoUI, que consulta essa propriedade a cada cinco segundos e atualiza uma barra de progresso. O loop de criptografia atualizavold.encrypt_progress
cada vez que criptografa outro percentual da partição. - Quando
/data
está criptografado, atualize o rodapé criptográficoQuando
/data
está criptografado com sucesso,vold
limpe a bandeiraENCRYPTION_IN_PROGRESS
nos metadados.Quando o dispositivo é desbloqueado com sucesso, a senha é então usada para encriptar a chave mestre e o rodapé criptográfico é actualizado.
Se a reinicialização falhar por alguma razão,
vold
define a propriedadevold.encrypt_progress
paraerror_reboot_failed
e a IU deve exibir uma mensagem pedindo ao utilizador para pressionar um botão toreboot. Isto não é esperado.
Iniciar um dispositivo criptografado com criptografia padrão
Isto é o que acontece quando você inicia um dispositivo criptografado sem senha.Como os dispositivos Android 5.0 são criptografados na primeira inicialização, não deve haver nenhuma senha definida e, portanto, este é o estado de criptografia padrão.
- Detectar encriptado
/data
sem palavra-passeDetectar que o dispositivo Android está encriptado porque
/data
não pode ser montado e uma das bandeirasencryptable
ouforceencrypt
está definida.vold
definevold.decrypt
atrigger_default_encryption
, o que inicia o serviçodefaultcrypto
.trigger_default_encryption
verifica o tipo de encriptação para ver se/data
está encriptado com ou sem password. - Decodifica /dados
Cria o dispositivo
dm-crypt
sobre o dispositivo de bloco para que o dispositivo esteja pronto para uso. - Monta /dados
vold
depois monta a partição real decodificada/data
e depois prepara a nova partição. Define a propriedadevold.post_fs_data_done
para 0 e depois definevold.decrypt
paratrigger_post_fs_data
. Isto faz com queinit.rc
execute os comandospost-fs-data
. Eles criarão quaisquer diretórios ou links necessários e então definirávold.post_fs_data_done
para 1.Once
vold
vê o 1 naquela propriedade, ele define a propriedadevold.decrypt
para:trigger_restart_framework.
Estacausainit.rc
para iniciar serviços na classemain
agora e também iniciar serviços na classelate_start
pela primeira vez desde o boot. - Iniciar framework
Agora o framework inicia todos os seus serviços usando o descriptografado
/data
,e o sistema está pronto para uso.
Iniciar um dispositivo criptografado sem criptografia padrão
Isso é o que acontece quando você inicia um dispositivo criptografado que tem uma senha definida. A senha do dispositivo pode ser um pin, padrão ou senha.
- Detectar dispositivo encriptado com uma palavra-passe
Detectar que o dispositivo Android está encriptado porque a bandeira
ro.crypto.state = "encrypted"
vold
definevold.decrypt
atrigger_restart_min_framework
porque/data
está encriptado com uma palavra-passe. - Montar tmpfs
init
define cinco propriedades para guardar as opções iniciais de montagem dadas para/data
com parâmetros passados deinit.rc
.vold
usa estas propriedades para configurar o mapeamento criptográfico:-
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 ASCII de 8 dígitos precedido de 0x)
-
- Iniciar o framework para pedir senha
O framework inicia e vê que
vold.decrypt
está configurado paratrigger_restart_min_framework
. Isto diz ao framework que ele está inicializando em um tmpfs/data
disco e precisa obter a senha do usuário.Primeiro, no entanto, ele precisa ter certeza de que o disco foi criptografado corretamente. Ele envia o comando
cryptfs cryptocomplete
paravold
.vold
retorna 0 se a criptografia foi completada com sucesso, -1 em erro interno, ou-2 se a criptografia não foi completada com sucesso.vold
determina isto ao procurar nos metadados criptografados para aCRYPTO_ENCRYPTION_IN_PROGRESS
flag. Se estiver definido, o processo de encriptação foi interrompido, e há dados nousable no dispositivo. Sevold
retornar um erro, a IU deve exibir uma mensagem ao usuário para reiniciar e resetar o dispositivo na fábrica, e dá ao usuário um botão para pressionar para fazê-lo. - Decriptar dados com senha
Once
cryptfs cryptocomplete
for bem sucedido, o framework exibe uma IU pedindo a senha do disco. A IU verifica a senha enviando o comandocryptfs checkpw
paravold
. Se a senha estiver correta (o que é determinado pela montagem bem sucedida do decriptado/data
em um local temporário, então desmonte-o),vold
salva o nome do dispositivo de bloco decriptado na propriedadero.crypto.fs_crypto_blkdev
e retorna o status 0 para o UI. Se a senha estiver incorreta, ela retorna -1 para o UI. - Parar framework
O UI coloca um gráfico de inicialização criptográfico e então chama
vold
com o comandocryptfs restart
.vold
define a propriedadevold.decrypt
paratrigger_reset_main
, o que faz com queinit.rc
façaclass_reset main
. Isto pára todos os serviços na classe principal, o que permite que os tmpfs/data
sejam desmontados. - Montar
/data
vold
depois monta a partição real desencriptada/data
e prepara a nova partição (que pode nunca ter sido preparada se tiver sido encriptada com a opção wipe, que não é suportada na primeira versão). Ele define a propriedadevold.post_fs_data_done
para 0 e thensetsvold.decrypt
paratrigger_post_fs_data
. Isto faz com queinit.rc
rode seus comandospost-fs-data
. Eles irão criar quaisquer diretórios ou links necessários e então definirvold.post_fs_data_done
para 1. Uma vezvold
vê o 1 naquela propriedade, define a propriedadevold.decrypt
paratrigger_restart_framework
. Isto faz com queinit.rc
inicie serviços na classemain
novamente e também inicie serviços na classelate_start
pela primeira vez desde o boot. - Inicie o framework completo
Agora o framework inicializa todos os seus serviços usando o sistema de arquivos descriptografados
/data
, e o sistema está pronto para uso.
Failure
Um dispositivo que não consegue decifrar pode estar errado por algumas razões. O devicestarts com a série normal de passos para inicialização:
- Detectar dispositivo criptografado com uma senha
- Mount tmpfs
- Start framework para pedir senha
Mas após o framework abrir, o dispositivo pode encontrar alguns erros:
- As palavras-chave coincidem mas não conseguem decifrar dados
- O utilizador introduz a palavra-chave errada 30 vezes
Se estes erros não forem resolvidos, peça ao utilizador para limpar de fábrica:
Se vold
detecta um erro durante o processo de encriptação, e se nenhum dado tiver sido destruído e o framework estiver pronto, vold
configure a propriedade vold.encrypt_progress
para error_not_encrypted
.A IU solicita que o usuário reinicie o processo de criptografia e alerta o usuário sobre o processo de criptografia, nunca iniciado. Se o erro ocorrer após o framework ter sido derrubado, mas antes da barra de progresso da IU estar para cima, vold
irá reinicializar o sistema. Se a reinicialização falhar, ela define vold.encrypt_progress
paraerror_shutting_down
e retorna -1; mas não haverá nada para capturar o erro. Isto não é esperado.
Se vold
detectar um erro durante o processo de encriptação, ele definevold.encrypt_progress
para error_partially_encrypted
e retorna -1. A IU deve então exibir uma mensagem dizendo que a criptografia falhou e fornecer um botão para o usuário reiniciar o dispositivo na fábrica.
Armazenar a chave encriptada
A chave encriptada é armazenada nos metadados criptográficos. O backup do hardware é implementado usando a capacidade de assinatura do Trusted Execution Environment (TEE). Anteriormente, nós criptografávamos a chave mestre com uma chave gerada aplicando scrypt à senha do usuário e ao sal armazenado. A fim de fazer com que a chave ganhe resilientemente ataques off-box, nós estendemos este algoritmo assinando a chave resultante com uma chave TEE armazenada. A assinatura resultante é então transformada em uma chave de comprimento apropriado por mais uma aplicação de scrypt. Esta chave é então usada para encriptar e desencriptar a chave-mestra. Para armazenar esta chave:
- Gerar chave de encriptação aleatória de disco de 16 bytes (DEK) e sal de 16 bytes.
- Aplicar scrypt à password do utilizador e ao sal para produzir a chave intermédia 1 de 32 bytes (IK1).
- Pad IK1 com zero bytes para o tamanho da chave privada ligada ao hardware (HBK): 00 || IK1 || 00…00; um byte zero, 32 IK1 bytes, 223zero bytes.
- Sign almofadado IK1 com HBK para produzir 256 bytes IK2.
- Aplique scrypt em IK2 e sal (mesmo sal do passo 2) para produzir 32 bytes IK3.
- Utilizar os primeiros 16 bytes de IK3 como KEK e os últimos 16 bytes como IV.
- Encrypt DEK com AES_CBC, com chave KEK, e vetor de inicialização IV.
Mudando a senha
Quando um usuário escolhe mudar ou remover sua senha nas configurações, a IU envia o comando cryptfs changepw
para vold
, e vold
re-encripta a chave-mestra do disco com a nova senha.
Propriedades de encriptação
vold
e init
comunicam entre si as propriedades de encriptação. Aqui está uma lista de propriedades disponíveis para encriptação.
Propriedades antigas
Propriedade | Descrição |
---|---|
vold.decrypt trigger_encryption |
Encryptar a unidade sem palavra-passe. |
vold.decrypt trigger_default_encryption |
Verifica a unidade para ver se está encriptada sem palavra-passe. Se estiver, desencripta-a e monta-a, ou então define vold.decrypt para activar_restart_min_framework. |
vold.decrypt trigger_reset_main |
Configurar por vold para desligar a IU pedindo a senha do disco. |
vold.decrypt trigger_post_fs_data |
Configurar por vold para preparar /data com os diretórios necessários, et al. |
vold.decrypt trigger_restart_framework |
Definido por vold para iniciar a estrutura real e todos os serviços. |
vold.decrypt trigger_shutdown_framework
|
Definido por vold para desligar a estrutura completa para iniciar a encriptação. |
vold.decrypt trigger_restart_min_framework |
Definido por vold para iniciar a barra de progresso UI para encriptação ou para pedir senha, dependendo do valor de ro.crypto.state . |
vold.encrypt_progress |
Quando o framework arranca, se esta propriedade estiver definida, enterrar a barra de progresso UI modo. |
vold.encrypt_progress 0 to 100 |
A barra de progresso UI deve mostrar o valor percentual definido. |
vold.encrypt_progress error_partially_encrypted |
A interface da barra de progresso deve exibir uma mensagem dizendo que a criptografia falhou, e dar ao usuário uma opção para reiniciar o dispositivo. |
vold.encrypt_progress error_reboot_failed |
A interface da barra de progresso deve exibir uma mensagem dizendo que a criptografia falhou, e dar ao usuário um botão para reiniciar o dispositivo. Este erro não é esperado. |
vold.encrypt_progress error_not_encrypted |
A interface da barra de progresso deve exibir uma mensagem dizendo que um erro ocorreu, nenhum dado foi criptografado ou perdido, e dar ao usuário um botão para reiniciar o sistema. |
vold.encrypt_progress error_shutting_down |
A interface da barra de progresso não está rodando, então não está claro quem irá responder a este erro. E nunca deve acontecer de qualquer forma. |
vold.post_fs_data_done 0 |
>>Configurado por vold imediatamente antes de definir vold.decrypt > a trigger_post_fs_data . |
vold.post_fs_data_done 1 |
Configurado por init.rc ou init.rc imediatamente após terminar a tarefa post-fs-data . |
init properties
Propriedade | Descrição |
---|---|
ro.crypto.fs_crypto_blkdev |
Configurado pelo comando vold checkpw para uso posterior pelo comando vold >restart . |
ro.crypto.state unencrypted |
Configurado pelo comando init para dizer que este sistema está a correr com um não encriptado /data ro.crypto.state encrypted . Definido por init para dizer que este sistema está rodando com um criptografado /data . |
|
Estas cinco propriedades são definidas por init quando tenta montar /data com parâmetros passados de init.rc . vold Utiliza-as para configurar o mapeamento criptográfico. |
ro.crypto.tmpfs_options |
Configurado por init.rc com as opções init devem ser usadas quando se monta o tmpfs /data filesystem. |