Retomar na reinicialização

No Android 11, as atualizações OTA podem ser aplicadas usando a atualização A/B ou os mecanismos virtuais de atualização A/B , combinados com os métodos de classe RecoverySystem . Após a reinicialização de um dispositivo para aplicar uma atualização OTA, Resume-on-Reboot (RoR) desbloqueia o armazenamento Credential Encrypted (CE) do dispositivo.

Embora os parceiros possam emparelhar esse processo com um recurso de sistema OTA que aplica atualizações quando o dispositivo deve ficar ocioso no Android 11, no Android 12, os parceiros não precisam de um recurso de sistema OTA adicional. O processo RoR fornece segurança e conveniência adicionais aos usuários porque as atualizações podem ser feitas durante os tempos ociosos do dispositivo, enquanto as funcionalidades de atualização baseada em servidor e multicliente do Android 12 juntas fornecem segurança do tipo de hardware do dispositivo.

Embora você deva fornecer permissão de dispositivo para o recurso android.hardware.reboot_escrow para oferecer suporte a RoR no Android 11, não é necessário fazer isso para habilitar RoR baseado em servidor no Android 12 e superior, porque eles não usam o HAL.

Fundo

A partir do Android 7, o Android suportou o Direct Boot , que permite que os aplicativos em um dispositivo sejam inicializados antes que o armazenamento CE seja desbloqueado pelo usuário. A implementação do suporte de inicialização direta forneceu aos usuários uma experiência melhor antes que o fator de conhecimento da tela de bloqueio (LSKF) precisasse ser inserido após uma inicialização.

O RoR permite que o armazenamento CE de todos os aplicativos em um dispositivo seja desbloqueado, incluindo aqueles que não suportam o Direct Boot, quando uma reinicialização é iniciada após uma atualização OTA. Esse recurso permite que os usuários recebam notificações de todos os aplicativos instalados após a reinicialização.

modelo de ameaça

Uma implementação de RoR deve garantir que, quando um dispositivo cair nas mãos de um invasor, seja extremamente difícil para o invasor recuperar os dados criptografados pelo CE do usuário, mesmo se o dispositivo estiver ligado, o armazenamento CE desbloqueado e o dispositivo desbloqueado por o usuário após receber uma atualização OTA. A resistência ao ataque interno deve ser eficaz mesmo se o invasor obtiver acesso às chaves de assinatura criptográfica de transmissão.

Especificamente, o armazenamento CE não deve ser lido por um invasor que tenha fisicamente o dispositivo e tenha estes recursos e limitações:

Capacidades

  • Pode usar a chave de assinatura de qualquer fornecedor ou empresa para assinar mensagens arbitrárias.
  • Pode fazer com que o dispositivo receba uma atualização OTA.
  • Pode modificar a operação de qualquer hardware (como um processador de aplicativo ou memória flash) - exceto conforme detalhado nas Limitações abaixo. (No entanto, essa modificação envolve um atraso de pelo menos uma hora e um ciclo de energia que destrói o conteúdo da RAM.)

Limitações

  • Não é possível modificar a operação de hardware inviolável (por exemplo, um Titan M).
  • Não é possível ler a RAM do dispositivo ao vivo.
  • Não consegue adivinhar as credenciais do usuário (PIN, padrão, senha) ou fazer com que sejam inseridas.

Solução

O sistema de atualização do Android 12 RoR fornece segurança contra invasores muito sofisticados e faz isso enquanto as senhas e PINs do dispositivo permanecem no dispositivo - eles nunca são enviados ou armazenados nos servidores do Google. Esta é uma visão geral do processo que garante que os níveis de segurança fornecidos sejam semelhantes a um sistema RoR de nível de dispositivo baseado em hardware:

  • O Android aplica proteções criptográficas aos dados armazenados em um dispositivo.
  • Todos os dados são protegidos por chaves armazenadas no ambiente de execução confiável (TEE).
  • O TEE só libera as chaves se o sistema operacional em execução passar pela autenticação criptográfica ( inicialização verificada ).
  • O serviço RoR em execução nos servidores do Google protege os dados do CE armazenando um segredo que pode ser recuperado apenas por um tempo limitado . Isso funciona em todo o ecossistema Android.
  • Uma chave criptográfica, protegida por um PIN do usuário, é usada para desbloquear o dispositivo e descriptografar o armazenamento CE.
    • Quando uma reinicialização noturna é agendada, o Android solicita que o usuário insira seu PIN e calcula uma senha sintética (SP).
    • Em seguida, ele criptografa o SP duas vezes: uma vez com uma chave K_s armazenada na RAM e novamente com uma chave K_k armazenada no TEE.
    • O SP com criptografia dupla é armazenado no disco e o SP é apagado da RAM. Ambas as chaves são geradas recentemente e usadas apenas para uma reinicialização .
  • Quando é hora de reiniciar, o Android confia K_s ao servidor. O recibo com K_k é criptografado antes de ser armazenado no disco.
  • Após a reinicialização, o Android usa K_k para descriptografar o recibo e o envia ao servidor para recuperar K_s .
    • K_k e K_s são usados ​​para descriptografar o SP armazenado no disco.
    • O Android usa o SP para desbloquear o armazenamento CE e permitir a inicialização normal do aplicativo.
    • K_k e K_s são descartados.

As atualizações que mantêm seu telefone seguro podem acontecer em um momento conveniente para você: enquanto você dorme.

Repetição do SIM-PIN

Sob certas condições, o código PIN de um cartão SIM é verificado a partir de um cache, um processo chamado replay SIM-PIN.

Um cartão SIM com um PIN ativado também deve passar por uma verificação contínua do código PIN (uma repetição do SIM-PIN) após uma reinicialização autônoma para restaurar a conectividade celular (necessária para chamadas telefônicas, mensagens SMS e serviços de dados). O PIN do SIM e as informações correspondentes do cartão SIM (o ICCID e o número do slot do SIM) são armazenados juntos com segurança. O PIN armazenado pode ser recuperado e usado para verificação somente após uma reinicialização autônoma bem-sucedida. Se o dispositivo estiver protegido, o PIN do SIM é armazenado com chaves protegidas pelo LSKF. Se o SIM tiver seu PIN ativado, a interação com o servidor RoR requer uma conexão WiFi para a atualização OTA e RoR baseado em servidor, o que garante a funcionalidade básica (com conectividade celular) após a reinicialização.

O PIN do SIM é criptografado novamente e armazenado cada vez que o usuário o habilita, verifica ou modifica com sucesso. O PIN do SIM é descartado se ocorrer uma das seguintes situações:

  • O SIM é removido ou redefinido.
  • O usuário desativa o PIN.
  • Ocorreu uma reinicialização não iniciada por RoR.

O PIN do SIM armazenado só pode ser usado uma vez após a reinicialização iniciada por RoR e apenas por um período de tempo muito curto (20 segundos) - se os detalhes do cartão SIM corresponderem. O PIN do SIM armazenado nunca sai do aplicativo TelephonyManager e não pode ser recuperado por módulos externos.

Diretrizes de implementação

No Android 12, as funções RoR multicliente e baseadas em servidor fornecem uma carga mais leve aos parceiros quando eles enviam atualizações OTA. As atualizações necessárias podem ocorrer durante períodos convenientes de inatividade do dispositivo, como durante as horas designadas de inatividade.

Para garantir que as atualizações OTA durante esses períodos não interrompam os usuários, use o modo escuro para reduzir as emissões de luz. Para fazer isso, faça com que o carregador de inicialização do dispositivo procure a string reason unattended . Se unattended for true , coloque o dispositivo no modo escuro. Observe que é responsabilidade de cada OEM mitigar as emissões de som e luz.

Se você estiver atualizando para o Android 12 ou iniciando dispositivos Android 12, não precisa fazer nada para implementar a nova funcionalidade RoR.

Há uma nova chamada no fluxo multicliente, isPreparedForUnattendedUpdate , mostrada abaixo:

@RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
            android.Manifest.permission.REBOOT})
public static boolean isPreparedForUnattendedUpdate(@NonNull Context context)

Você não precisa implementar isso, porque o HAL está obsoleto a partir do Android 12.

Gerenciador de Telefonia

O cliente OTA invoca a API do sistema TelephonyManager quando uma reinicialização é iminente no Android 12. Essa API move todos os códigos PIN armazenados em cache do estado AVAILABLE para o estado REBOOT_READY . A API do sistema TelephonyManager é protegida pela permissão REBOOT Manifest existente.

 /**
    * The unattended reboot was prepared successfully.
    * @hide
    */
   @SystemApi
   public static final int PREPARE_UNATTENDED_REBOOT_SUCCESS = 0;

   /**
    * The unattended reboot was prepared, but the user will need to manually
    * enter the PIN code of at least one SIM card present in the device.
    * @hide
    */
   @SystemApi
   public static final int PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED = 1;

   /**
    * The unattended reboot was not prepared due to generic error.
    * @hide
    */
   @SystemApi
   public static final int PREPARE_UNATTENDED_REBOOT_ERROR = 2;

   /** @hide */
   @Retention(RetentionPolicy.SOURCE)
   @IntDef(prefix = {"PREPARE_UNATTENDED_REBOOT_"},
           value = {
                   PREPARE_UNATTENDED_REBOOT_SUCCESS,
                   PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED,
                   PREPARE_UNATTENDED_REBOOT_ERROR
           })
   public @interface PrepareUnattendedRebootResult {}

   /**
    * Prepare TelephonyManager for an unattended reboot. The reboot is
    * required to be done shortly after the API is invoked.
    *
    * Requires system privileges.
    *
    * <p>Requires Permission:
    *   {@link android.Manifest.permission#REBOOT}
    *
    * @return {@link #PREPARE_UNATTENDED_REBOOT_SUCCESS} in case of success.
    * {@link #PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED} if the device contains
    * at least one SIM card for which the user needs to manually enter the PIN
    * code after the reboot. {@link #PREPARE_UNATTENDED_REBOOT_ERROR} in case
    * of error.
    * @hide
    */
   @SystemApi
   @RequiresPermission(android.Manifest.permission.REBOOT)
   @PrepareUnattendedRebootResult
   public int prepareForUnattendedReboot()

A API do sistema TelephonyManager é usada por APKs privilegiados.

teste

Para testar a nova API, execute este comando:

    adb shell cmd phone unattended-reboot

Este comando só funciona quando o shell está sendo executado como root ( adb root ).

Android 11 apenas

O restante desta página se aplica ao Android 11.

A partir de julho de 2020, as implementações do RoR HAL se enquadram em duas categorias:

  1. Se o hardware SoC oferecer suporte à persistência de RAM entre as reinicializações, os OEMs poderão usar a implementação padrão no AOSP ( Default RAM Escrow ).
  2. Se o hardware do dispositivo ou SoC suportar um enclave de hardware seguro (um coprocessador de segurança discreto com sua própria RAM e ROM), ele também deverá fazer o seguinte:
    • Ser capaz de detectar uma reinicialização da CPU principal.
    • Tenha uma fonte de timer de hardware que persista nas reinicializações. Ou seja, o enclave deve ser capaz de detectar a reinicialização e expirar um cronômetro definido antes da reinicialização.
    • Suporta o armazenamento de uma chave protegida no enclave RAM/ROM de forma que não possa ser recuperada com ataques offline. Ele deve armazenar a chave RoR de forma a impossibilitar sua recuperação por pessoas de dentro ou invasores.

Caução de RAM padrão

AOSP tem uma implementação do RoR HAL usando persistência de RAM. Para que isso funcione, os OEMs devem garantir que seus SoCs ofereçam suporte à persistência de RAM nas reinicializações. Alguns SoCs não conseguem manter o conteúdo da RAM durante uma reinicialização, portanto, os OEMs são aconselhados a consultar seus parceiros SoC antes de habilitar esse HAL padrão. A referência canônica para isso na seção a seguir.

Fluxo de atualização OTA usando RoR

O aplicativo cliente OTA no telefone deve ter as permissões Manifest.permission.REBOOT e Manifest.permission.RECOVERY para chamar os métodos necessários para implementar RoR. Com esse pré-requisito em vigor, o fluxo de uma atualização segue estas etapas:

  1. O aplicativo cliente OTA baixa a atualização.
  2. O aplicativo cliente OTA chama RecoverySystem#prepareForUnattendedUpdate , que faz com que o usuário seja solicitado a fornecer seu PIN, padrão ou senha na tela de bloqueio durante o próximo desbloqueio.
  3. O usuário desbloqueia o dispositivo na tela de bloqueio e o dispositivo está pronto para receber a atualização.
  4. O aplicativo cliente OTA chama RecoverySystem#rebootAndApply , que aciona imediatamente uma reinicialização.

Ao final desse fluxo, o dispositivo é reinicializado e o mecanismo RoR desbloqueia o armazenamento de credenciais criptografadas (CE). Para os aplicativos, isso aparece como um desbloqueio normal do usuário, para que eles recebam todos os sinais, como ACTION_LOCKED_BOOT_COMPLETED e ACTION_BOOT_COMPLETED que normalmente recebem.

Modifique as configurações do produto

Um produto marcado como compatível com o recurso RoR no Android 11 deve incluir uma implementação do RebootEscrow HAL e incluir o arquivo XML do marcador de recurso. A implementação padrão funciona bem em dispositivos que usam reinicialização a quente (quando a energia da DRAM permanece ligada durante a reinicialização).

Marcador de recurso de depósito de reinicialização

O marcador de recurso também deve estar presente:

PRODUCT_COPY_FILES += \
    frameworks/native/data/etc/android.hardware.reboot_escrow.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.reboot_escrow.xml

Implementação HAL de custódia de reinicialização padrão

Para usar a implementação padrão, você deve reservar 65536 (0x10000) bytes. Nunca grave esses bytes em armazenamento não volátil para garantir que as propriedades de segurança persistam.

Mudanças na árvore de dispositivos do kernel do Linux

Na árvore de dispositivos do kernel do Linux, você deve reservar memória para uma região pmem . O exemplo a seguir mostra 0x50000000 sendo reservado:

  reserved-memory {
    my_reservation@0x50000000 {
      no-map;
      reg = <0x50000000 0x10000>;
    }
  }

  reboot_escrow@0 {
    compatible = "pmem-region";
    reg = <0x50000000 0x10000>;
  };

Verifique se você tem um novo dispositivo no diretório do bloco com um nome como /dev/block/pmem0 (como pmem1 ou pmem2 ).

Alterações no Device.mk

Supondo que seu novo dispositivo da etapa anterior seja denominado pmem0 , você deve garantir que as novas entradas a seguir sejam adicionadas a vendor/<oem>/<product>/device.mk :

# Resume on Reboot support
PRODUCT_PROPERTY_OVERRIDES += \
    ro.rebootescrow.device=/dev/block/pmem0
PRODUCT_PACKAGES += \
    android.hardware.rebootescrow-service.default
regras do SELinux

Adicione essas novas entradas ao file_contexts do dispositivo:

/dev/block/pmem0  u:object_r:rebootescrow_device:s0
/vendor/bin/hw/android\.hardware\.rebootescrow-service\.default  u:object_r:hal_rebootescrow_default_exec:s0