Criptografia de disco completo

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ção SVC_DISABLED. Os serviços interrompidos não respondem a class_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).
  • 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.

  1. Detectar sistema de arquivos não criptografado com a sinalização forceencrypt

    O /data não está criptografado, mas precisa ser porque o forceencrypt exige isso. Desconecte /data.

  2. Começar a criptografar /data

    vold.decrypt = "trigger_encryption" aciona init.rc, o que fará com que vold criptografe /data sem senha. Nenhum é definido porque este deve ser um novo dispositivo.

  3. Montar tmpfs

    vold monta um /data de tmpfs (usando as opções de tmpfs de ro.crypto.tmpfs_options) e define a propriedade vold.encrypt_progress como 0. O vold prepara o tmpfs /data para inicializar um sistema criptografado e define os propriedade vold.decrypt como: trigger_restart_min_framework

  4. 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.

  5. Quando /data estiver criptografado, remova o framework

    vold define vold.decrypt como trigger_default_encryption, que inicia o serviço defaultcrypto. (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.

  6. Montar /data

    init então monta /data em um RAMDisk tmpfs usando parâmetros que ele extrai do ro.crypto.tmpfs_options, que é definido em init.rc.

  7. Iniciar framework

    vold define vold.decrypt como trigger_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.

  1. Verificar senha

    A interface chama vold com o comando cryptfs enablecrypto inplace. em que passwd é a senha da tela de bloqueio do usuário.

  2. 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 propriedade vold.decrypt. para trigger_shutdown_framework. Isso faz com que init.rc interromper serviços nas classes late_start e main.

  3. Criar um rodapé de criptografia
  4. Criar um arquivo de navegação estrutural
  5. Reinicializar
  6. Detectar arquivo de navegação estrutural
  7. 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.

  8. Durante a criptografia, ative o tmpfs

    vold monta um /data de tmpfs (usando as opções de tmpfs de ro.crypto.tmpfs_options) e define a propriedade vold.encrypt_progress a 0. vold prepara os tmpfs /data para inicializar um sistema criptografado e define a propriedade vold.decrypt para: trigger_restart_min_framework

  9. Exibir a estrutura para mostrar o progresso

    trigger_restart_min_framework faz com que init.rc iniciar a classe de serviços main. Quando o framework percebe que vold.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 o vold.encrypt_progress sempre que ele criptografa outro percentual da partição.

  10. Quando /data estiver criptografado, atualize o rodapé de criptografia

    Quando /data for criptografado, o vold será apagado a flag ENCRYPTION_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 a error_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.

  1. Detectar /data criptografado sem senha

    Detectar se o dispositivo Android está criptografado porque /data não pode ser montado e uma das flags encryptable ou forceencrypt foi definido.

    vold define vold.decrypt como trigger_default_encryption, que inicia o serviço defaultcrypto. trigger_default_encryption verifica o tipo de criptografia para confirmar se /data está criptografado com ou sem uma senha.

  2. Descriptografar /data

    Cria o dispositivo dm-crypt no dispositivo de transferência por blocos para que ele seja está pronto para uso.

  3. Montar /dados

    Em seguida, vold monta a partição /data real descriptografada. e prepara a nova partição. Ele define a propriedade vold.post_fs_data_done como 0 e, em seguida, define vold.decrypt. para trigger_post_fs_data. Isso faz com que init.rc seja executado aos comandos post-fs-data. Eles vão criar todos os diretórios necessários ou links e, em seguida, defina vold.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 que init.rc inicie serviços na classe main novamente e iniciar os serviços na classe late_start para a primeira desde a inicialização.

  4. 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.

  1. Detectar dispositivo criptografado com uma senha

    Detecta se o dispositivo Android está criptografado porque a flag ro.crypto.state = "encrypted"

    vold define vold.decrypt como trigger_restart_min_framework porque /data é criptografados com uma senha.

  2. Montar tmpfs

    init define cinco propriedades para salvar as opções de montagem iniciais. dado para /data com parâmetros transmitidos de init.rc. vold usa estas propriedades para configurar o mapeamento de criptografia:

    1. ro.crypto.fs_type
    2. ro.crypto.fs_real_blkdev
    3. ro.crypto.fs_mnt_point
    4. ro.crypto.fs_options
    5. ro.crypto.fs_flags (Número hexadecimal de 8 dígitos ASCII precedido por 0x)
  3. Iniciar framework para solicitar senha

    O framework é iniciado e detecta que vold.decrypt está definido como trigger_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 para vold. 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 arquivo CRYPTO_ENCRYPTION_IN_PROGRESS . Se ela estiver definida, o processo de criptografia foi interrompido, e não dados utilizáveis no dispositivo. Se vold 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.

  4. 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 comando cryptfs checkpw para vold. 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 propriedade ro.crypto.fs_crypto_blkdev e retorna o status 0 para a interface. Se o a senha estiver incorreta, ele retornará -1 para a interface.

  5. Interromper framework

    A interface mostra um gráfico de inicialização criptográfica e chama vold com o comando cryptfs restart. vold define a propriedade. vold.decrypt para trigger_reset_main, o que faz init.rc para class_reset main. Esta ação interrompe todos os serviços na classe principal, o que permite que o /data de tmpfs seja desconectado.

  6. 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 propriedade vold.post_fs_data_done como 0 e depois define vold.decrypt como trigger_post_fs_data. Isso faz com que init.rc para executar os comandos post-fs-data. Eles vão criar quaisquer diretórios ou links necessários e, em seguida, definir vold.post_fs_data_done para 1. Assim que vold vir o 1 em essa propriedade, ele define a propriedade vold.decrypt como trigger_restart_framework Isso faz com que o init.rc seja iniciado serviços na classe main novamente e também iniciam serviços na classe late_start pela primeira vez desde a inicialização.

  7. 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:

  1. Detectar dispositivo criptografado com uma senha
  2. Montar tmpfs
  3. 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:

  1. Gere uma chave de criptografia de disco (DEK, na sigla em inglês) aleatória e com um sal de 16 bytes.
  2. Aplique o scrypt à senha do usuário e o sal para produzir um intermediário de 32 bytes chave 1 (IK1).
  3. 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.
  4. Assine o IK1 preenchido com HBK para produzir o IK2 de 256 bytes.
  5. Aplique o scrypt ao IK2 e um sal (o mesmo sal da etapa 2) para produzir o IK3 de 32 bytes.
  6. Usar os primeiros 16 bytes de IK3 como KEK e os últimos 16 bytes como IV.
  7. 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.

ro.crypto.fs_type
ro.crypto.fs_real_blkdev
ro.crypto.fs_mnt_point
ro.crypto.fs_options
ro.crypto.fs_flags

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