Retomar na reinicialização

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

Embora os parceiros possam combinar esse processo com um recurso do sistema OTA que aplica atualizações quando o dispositivo está ocioso no Android 11, no Android 12 os parceiros não precisam de um recurso adicional do sistema OTA. O processo RoR fornece segurança e conveniência adicionais aos usuários porque as atualizações podem ser feitas durante os tempos de inatividade do dispositivo, enquanto as funcionalidades de atualização multicliente e baseada em servidor 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 ao RoR no Android 11, não é necessário fazer isso para ativar o RoR baseado em servidor no Android 12 e versões posteriores, porque eles não usam o HAL.

Fundo

A partir do Android 7, o Android oferece suporte ao 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 Direct Boot proporcionou aos usuários uma melhor experiência antes que o Lock Screen Knowledge Factor (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 Direct Boot, quando uma reinicialização é iniciada após uma atualização OTA. Este 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 cai nas mãos de um invasor, seja extremamente difícil para o invasor recuperar os dados criptografados por CE do usuário, mesmo se o dispositivo estiver ligado, o armazenamento CE estiver desbloqueado e o dispositivo for desbloqueado por o usuário após receber uma atualização OTA. A resistência a ataques internos 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 possua 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 em Limitações abaixo. (No entanto, tal 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 resistente a violações (por exemplo, um Titan M).
  • Não é possível ler a RAM do dispositivo ativo.
  • Não é possível adivinhar as credenciais do usuário (PIN, padrão, senha) ou fazer com que elas sejam inseridas.

Solução

O sistema de atualização RoR do Android 12 oferece 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 baseado em hardware e em nível de dispositivo:

  • 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 na autenticação criptográfica ( inicialização verificada ).
  • O serviço RoR executado nos servidores do Google protege os dados do CE armazenando um segredo que pode ser recuperado apenas por um período limitado . Isso funciona em todo o ecossistema Android.
  • Uma chave criptográfica, protegida pelo 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 chega a 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, em seguida, envia-o 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 horário 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 denominado repetição 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 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 será armazenado com chaves protegidas pela LSKF. Se o SIM estiver com o PIN habilitado, a interação com o servidor RoR requer uma conexão WiFi para a atualização OTA e RoR baseado em servidor, que garante funcionalidade básica (com conectividade celular) após a reinicialização.

O PIN do SIM é criptografado novamente e armazenado sempre que o usuário o ativa, verifica ou modifica com êxito. O PIN do SIM será descartado se ocorrer alguma 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 pelo RoR e apenas por um período 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 tempos de inatividade convenientes do dispositivo, como durante horas designadas de suspensão.

Para garantir que as atualizações OTA durante esses períodos não interrompam os usuários, use o modo escuro para mitigar as emissões de luz. Para fazer isso, faça com que o bootloader 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 lançando dispositivos Android 12, não precisará 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 existente do Manifesto REBOOT .

 /**
    * 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 ).

Apenas Android 11

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

Em julho de 2020, as implementações de RoR HAL se enquadravam em duas categorias:

  1. Se o hardware SoC suportar persistência de RAM durante as reinicializações, os OEMs poderão usar a implementação padrão no AOSP ( Default RAM Escrow ).
  2. Se o hardware ou SoC do dispositivo suportar um enclave de hardware seguro (um coprocessador de segurança discreto com sua própria RAM e ROM), além disso, ele deverá fazer o seguinte:
    • Ser capaz de detectar uma reinicialização principal da CPU.
    • Tenha uma fonte de temporizador de hardware que persista durante as reinicializações. Ou seja, o enclave deve ser capaz de detectar a reinicialização e expirar um cronômetro definido antes da reinicialização.
    • Suporte ao armazenamento de uma chave garantida na RAM/ROM do enclave de forma que ela não possa ser recuperada com ataques offline. Ele deve armazenar a chave RoR de uma forma que impossibilite que pessoas internas ou invasores a recuperem.

Garantia de RAM padrão

AOSP possui uma implementação do RoR HAL usando persistência RAM. Para que isso funcione, os OEMs devem garantir que seus SoCs suportem persistência de RAM durante as reinicializações. Alguns SoCs não conseguem persistir o conteúdo da RAM durante uma reinicialização, portanto, os OEMs são aconselhados a consultar seus parceiros SoC antes de ativar esse HAL padrão. A referência canônica para isso na seção seguinte.

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 implementado, 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 aplicar a atualização.
  4. O aplicativo cliente OTA chama RecoverySystem#rebootAndApply , o que aciona imediatamente uma reinicialização.

No final deste fluxo, o dispositivo é reinicializado e o mecanismo RoR desbloqueia o armazenamento criptografado de credenciais (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.

Modificar configurações do produto

Um produto marcado como compatível com o recurso RoR no Android 11 deve incluir uma implementação do HAL RebootEscrow 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 garantia 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 garantia de reinicialização padrão

Para usar a implementação padrão, você deve reservar 65.536 (0x10.000) 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 Linux

Na árvore de dispositivos do kernel 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ê possui um novo dispositivo no diretório de blocos com um nome como /dev/block/pmem0 (como pmem1 ou pmem2 ).

Mudanças no Device.mk

Supondo que seu novo dispositivo da etapa anterior seja denominado pmem0 , você deve garantir que as seguintes novas entradas 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 SELinux

Adicione estas 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