En Android 11, las actualizaciones inalámbricas se pueden aplicar con los mecanismos de actualización A/B o de actualización A/B virtual, combinados con los métodos de clase RecoverySystem. Después de que un dispositivo se reinicia para aplicar una actualización inalámbrica, la función de reanudación en el reinicio (RoR) desbloquea el almacenamiento encriptado con credenciales (CE) del dispositivo.
Si bien los socios pueden combinar este proceso con una función del sistema inalámbrica que aplica actualizaciones cuando se espera que el dispositivo esté inactivo en Android 11, en Android 12 los socios no necesitan una función del sistema inalámbrica adicional. El proceso de RoR proporciona seguridad y conveniencia adicional a los usuarios, ya que las actualizaciones se pueden realizar durante los tiempos de inactividad del dispositivo, mientras que las funciones de actualización de varios clientes y basadas en el servidor de Android 12 brindan seguridad del tipo de nivel de hardware del dispositivo.
Si bien debes proporcionar permiso del dispositivo para que la función android.hardware.reboot_escrow admita RoR en Android 11, no es necesario que lo hagas para habilitar RoR basado en el servidor en Android 12 y versiones posteriores, ya que no usan HAL.
Fondo
A partir de Android 7, Android admitió el inicio directo, lo que permite que las apps de un dispositivo se inicien antes de que el usuario desbloquee el almacenamiento CE. La implementación de la compatibilidad con el inicio directo proporcionó a los usuarios una mejor experiencia antes de que se ingresara el factor de conocimiento de la pantalla de bloqueo (LSKF) después de un inicio.
RoR permite desbloquear el almacenamiento CE de todas las apps de un dispositivo, incluidas las que no admiten el inicio directo, cuando se inicia un reinicio después de una actualización inalámbrica. Esta función permite que los usuarios reciban notificaciones de todas las apps instaladas después del reinicio.
Modelo de amenaza
Una implementación de RoR debe garantizar que, cuando un dispositivo cae en manos de un atacante, sea extremadamente difícil para el atacante recuperar los datos encriptados con CE del usuario, incluso si el dispositivo está encendido, el almacenamiento CE está desbloqueado y el usuario desbloquea el dispositivo después de recibir una actualización inalámbrica. La resistencia al ataque interno debe ser efectiva incluso si el atacante obtiene acceso a las claves de firma criptográfica de transmisión.
En particular, un atacante que tiene el dispositivo físicamente no debe leer el almacenamiento CE y debe tener estas capacidades y limitaciones:
Funciones
- Puede usar la clave de firma de cualquier proveedor o empresa para firmar mensajes arbitrarios.
- Puede hacer que el dispositivo reciba una actualización inalámbrica.
- Puede modificar el funcionamiento de cualquier hardware (como un procesador de aplicaciones, o una memoria flash), excepto como se detalla en Limitaciones a continuación. (Sin embargo, dicha modificación implica una demora de al menos una hora y un ciclo de energía que destruye el contenido de la RAM).
Limitaciones
- No puede modificar el funcionamiento del hardware resistente a la manipulación (por ejemplo, un Titan M).
- No puede leer la RAM del dispositivo activo.
- No puede adivinar las credenciales del usuario (PIN, patrón, contraseña) ni hacer que se ingresen de otra manera.
Solución
El sistema de actualización de RoR de Android 12 proporciona seguridad contra atacantes muy sofisticados y lo hace mientras las contraseñas y los PIN integrados en el dispositivo permanecen en él. Nunca se envían ni se almacenan en los servidores de Google. Esta es una descripción general del proceso que garantiza que los niveles de seguridad proporcionados sean similares a un sistema RoR basado en hardware y a nivel del dispositivo:
- Android aplica protecciones criptográficas a los datos almacenados en un dispositivo.
- Todos los datos están protegidos por claves almacenadas en el entorno de ejecución confiable (TEE).
- El TEE solo libera las claves si el sistema operativo en ejecución pasa la autenticación criptográfica (inicio verificado).
- El servicio RoR que se ejecuta en los servidores de Google protege los datos CE almacenando un secreto que se puede recuperar solo por un tiempo limitado. Esto funciona en todo el ecosistema de Android.
- Se usa una clave criptográfica, protegida por el PIN de un usuario, para desbloquear el dispositivo y desencriptar el almacenamiento CE.
- Cuando se programa un reinicio durante la noche, Android le solicita al usuario que ingrese su PIN y, luego, calcula una contraseña sintética (SP).
- Luego, encripta la SP dos veces: una con una clave
K_salmacenada en la RAM y otra con una claveK_kalmacenada en el TEE. - La SP encriptada dos veces se almacena en el disco y se borra de la RAM. Ambas claves se generan recientemente y se usan solo para un reinicio.
- Cuando llega el momento de reiniciar, Android le confía
K_sal servidor. El recibo conK_kse encripta antes de almacenarse en el disco. - Después del reinicio, Android usa
K_kpara desencriptar el recibo y, luego, lo envía al servidor para recuperarK_s.K_kyK_sse usan para desencriptar la SP almacenada en el disco.- Android usa la SP para desbloquear el almacenamiento CE y permitir el inicio normal de la app.
- Se descartan
K_kyK_s.
Las actualizaciones que protegen tu teléfono pueden ocurrir en un momento conveniente para ti: mientras duermes.
Reproducción del PIN de la SIM
En determinadas condiciones, el código PIN de una tarjeta SIM se verifica desde una caché, un proceso llamado reproducción del PIN de la SIM.
Una tarjeta SIM con un PIN habilitado también debe someterse a una verificación fluida del código PIN (una reproducción del PIN de la SIM) después de un reinicio desatendido para restablecer la conectividad celular (necesaria para llamadas telefónicas, mensajes SMS y servicios de datos). El PIN de la SIM y la información correspondiente de la tarjeta SIM (el ICCID y el número de ranura de la SIM) se almacenan de forma segura juntos. El PIN almacenado se puede recuperar y usar para la verificación solo después de un reinicio desatendido exitoso. Si el dispositivo está protegido, el PIN de la SIM se almacena con claves protegidas por el LSKF. Si la SIM tiene habilitado su PIN, la interacción con el servidor RoR requiere una conexión Wi-Fi para la actualización inalámbrica y RoR basado en el servidor, lo que garantiza la funcionalidad básica (con conectividad celular) después del reinicio.
El PIN de la SIM se vuelve a encriptar y se almacena cada vez que el usuario lo habilita, verifica o modifica correctamente. El PIN de la SIM se descarta si ocurre alguna de las siguientes situaciones:
- Se quita o restablece la SIM.
- El usuario inhabilita el PIN.
- Se produjo un reinicio no iniciado por RoR.
El PIN de la SIM almacenado solo se puede usar una vez después del reinicio iniciado por RoR y solo por un período muy corto (20 segundos),si coinciden los detalles de la tarjeta SIM. El PIN de la SIM almacenado nunca abandona la app de TelephonyManager y los módulos externos no pueden recuperarlo.
Lineamientos de implementación
En Android 12, las funciones de RoR de varios clientes y basadas en el servidor proporcionan una carga más ligera a los socios cuando envían actualizaciones inalámbricas. Las actualizaciones necesarias pueden ocurrir durante los tiempos de inactividad convenientes del dispositivo, como durante las horas de sueño designadas.
Para garantizar que las actualizaciones inalámbricas durante esos períodos no interrumpan a los usuarios, usa el modo oscuro para mitigar las emisiones de luz. Para ello, haz que el cargador de arranque del dispositivo busque la cadena de motivo unattended. Si unattended es true, pon el dispositivo en modo oscuro. Ten en cuenta que es responsabilidad de cada OEM mitigar las emisiones de sonido y luz.
Si actualizas a Android 12 o lanzas dispositivos Android 12, no necesitas hacer nada para implementar la nueva funcionalidad de RoR.
Hay una nueva llamada en el flujo de varios clientes, isPreparedForUnattendedUpdate, que se muestra a continuación:
@RequiresPermission(anyOf = {android.Manifest.permission.RECOVERY,
android.Manifest.permission.REBOOT})
public static boolean isPreparedForUnattendedUpdate(@NonNull Context context)
No es necesario que implementes esto, ya que HAL dejó de estar disponible a partir de Android 12.
TelephonyManager
El cliente inalámbrico invoca la API del sistema TelephonyManager cuando un reinicio es inminente en Android 12. Esta API mueve todos los códigos PIN almacenados en caché del estado AVAILABLE al estado REBOOT_READY. La API del sistema TelephonyManager
está protegida por el permiso de manifiesto REBOOT
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()
Las APK con privilegios usan la API del sistema TelephonyManager.
Prueba
Para probar la nueva API, ejecuta este comando:
adb shell cmd phone unattended-rebootEste comando solo funciona cuando el shell se ejecuta como raíz (adb root).
Solo Android 11
El resto de esta página se aplica a Android 11.
A partir de julio de 2020, las implementaciones de RoR HAL se dividen en dos categorías:
- Si el hardware del SoC admite la persistencia de RAM en los reinicios, los OEMs pueden usar la implementación predeterminada en AOSP (RAM Escrow predeterminada).
- Si el hardware del dispositivo o el SoC admiten un enclave de hardware seguro (un coprocesador de seguridad discreto con su propia RAM y ROM), además, debe hacer lo siguiente:
- Poder detectar un reinicio de la CPU principal
- Tener una fuente de temporizador de hardware que persista en los reinicios (es decir, el enclave debe poder detectar el reinicio y hacer que venza un temporizador configurado antes del reinicio)
- Admitir el almacenamiento de una clave en depósito en la RAM/ROM del enclave de modo que no se pueda recuperar con ataques sin conexión (debe almacenar la clave RoR de una manera que impida que los usuarios internos o los atacantes la recuperen)
RAM Escrow predeterminada
AOSP tiene una implementación de RoR HAL con persistencia de RAM. Para que esto funcione, los OEMs deben asegurarse de que sus SoCs admitan la persistencia de RAM en los reinicios. Algunos SoCs no pueden conservar el contenido de la RAM en un reinicio, por lo que se recomienda a los OEMs que consulten a sus socios de SoC antes de habilitar este HAL predeterminado. La referencia canónica para esto en la siguiente sección.
Flujo de actualización inalámbrica con RoR
La app cliente inalámbrica del teléfono debe tener los
permisos Manifest.permission.REBOOT
y Manifest.permission.RECOVERY para llamar a los métodos necesarios para
implementar RoR. Con ese requisito previo, el flujo de una actualización sigue estos pasos:
- La app cliente inalámbrica descarga la actualización.
- La app cliente inalámbrica llama a
RecoverySystem#prepareForUnattendedUpdate, lo que hace que se le solicite al usuario su PIN, patrón o contraseña en la pantalla de bloqueo durante el próximo desbloqueo. - El usuario desbloquea el dispositivo en la pantalla de bloqueo, y el dispositivo está listo para que se aplique la actualización.
- La app cliente inalámbrica llama a
RecoverySystem#rebootAndApply, lo que activa un reinicio de inmediato.
Al final de este flujo, el dispositivo se reinicia y el mecanismo RoR desbloquea el almacenamiento encriptado con credenciales (CE). Para las apps, esto aparece como un desbloqueo normal del usuario, por lo que reciben todos los indicadores, como ACTION_LOCKED_BOOT_COMPLETED y ACTION_BOOT_COMPLETED que normalmente hacen.
Modifica las configuraciones del producto
Un producto marcado como compatible con la función RoR en Android 11 debe incluir una implementación de RebootEscrow HAL y el archivo XML del marcador de funciones. La implementación predeterminada funciona bien en dispositivos que usan el reinicio en caliente (cuando la energía de la DRAM permanece encendida durante el reinicio).
Marcador de funciones de Reboot Escrow
El marcador de funciones también debe 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
Implementación predeterminada de Reboot Escrow HAL
Para usar la implementación predeterminada, debes reservar 65536 (0x10000) bytes. Nunca escribas estos bytes en el almacenamiento no volátil para garantizar que persistan las propiedades de seguridad.
Cambios en el árbol de dispositivos del kernel de Linux
En el árbol de dispositivos del kernel de Linux, debes reservar memoria para una región pmem.
En el siguiente ejemplo, se muestra 0x50000000 reservado:
reserved-memory {
my_reservation@0x50000000 {
no-map;
reg = <0x50000000 0x10000>;
}
}
reboot_escrow@0 {
compatible = "pmem-region";
reg = <0x50000000 0x10000>;
};
Verifica que tengas un dispositivo nuevo en el directorio de bloques con un nombre como /dev/block/pmem0 (como pmem1 o pmem2).
Cambios en Device.mk
Si suponemos que tu dispositivo nuevo del paso anterior se llama pmem0, debes
asegurarte de que se agreguen las siguientes entradas nuevas 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
Reglas de SELinux
Agrega estas entradas nuevas a file_contexts del 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