El Arranque Verificado requiere la verificación criptográfica de todo el código y los datos ejecutables que forman parte de la versión de Android que se está iniciando antes de que se usen. Esto incluye el kernel (cargado desde la partición boot
), el árbol de dispositivos (cargado desde la partición dtbo
), la partición system
, la partición vendor
, etcétera.
Las particiones pequeñas, como boot
y dtbo
, que se leen solo una vez, suelen verificarse cargando todo el contenido en la memoria y, luego, calculando su hash. Luego, este valor de hash calculado se compara con el valor de hash esperado. Si el valor no coincide, Android no se cargará.
Para obtener más información, consulta Flujo de inicio.
Las particiones más grandes que no caben en la memoria (como los sistemas de archivos) pueden usar un árbol hash en el que la verificación es un proceso continuo que ocurre a medida que los datos se cargan en la memoria. En este caso, el hash raíz del árbol de hash se calcula durante el tiempo de ejecución y se verifica con el valor esperado del hash raíz. Android incluye el controlador dm-verity para verificar particiones más grandes. Si, en algún momento, el hash raíz calculado no coincide con el valor de hash raíz esperado, no se utilizan los datos y Android entra en un estado de error. Para obtener más detalles, consulta Corrupción de dm-verity.
Por lo general, los hashes esperados se almacenan al final o al principio de cada partición verificada, en una partición dedicada o en ambos lugares. Es fundamental que estas funciones hash estén firmadas (directa o indirectamente) por la raíz de confianza. Por ejemplo, la implementación de AVB admite ambos enfoques. Consulta Inicio verificado de Android para obtener más detalles.
Protección contra reversiones
Incluso con un proceso de actualización completamente seguro, es posible que un exploit del kernel de Android no persistente instale manualmente una versión anterior y más vulnerable de Android, reinicie el dispositivo en la versión vulnerable y, luego, use esa versión de Android para instalar un exploit persistente. A partir de ese momento, el atacante es propietario permanente del dispositivo y puede hacer lo que quiera, incluso inhabilitar las actualizaciones.
La protección contra esta clase de ataques se denomina Rollback Protection. Por lo general, la protección contra reversiones se implementa con almacenamiento a prueba de manipulaciones para registrar la versión más reciente de Android y rechazar el inicio de Android si es inferior a la versión registrada. Por lo general, se hace un seguimiento de las versiones por partición.
Para obtener más detalles sobre cómo AVB controla las protecciones contra reversiones, consulta el archivo README de AVB.
Cómo controlar errores de verificación
La verificación puede fallar durante el inicio (por ejemplo, si el hash calculado en la partición boot
no coincide con el hash esperado) o durante el tiempo de ejecución (por ejemplo, si dm-verity detecta un error de verificación en la partición system
). Si la verificación falla durante el inicio, el dispositivo no se puede iniciar y el usuario final debe seguir los pasos para recuperarlo.
Si la verificación falla durante el tiempo de ejecución, el flujo es un poco más complicado. Si el dispositivo usa dm-verity, debe configurarse en el modo restart
. En el modo restart
, si se produce un error de verificación, el dispositivo se reinicia de inmediato con una marca específica establecida para indicar el motivo. El cargador de arranque debería detectar esta marca y cambiar dm-verity para que use el modo de error de E/S (eio
) y permanecer en este modo hasta que se instale una nueva actualización.
Cuando se inicia en el modo eio
, el dispositivo muestra una pantalla de error que informa al usuario que se detectó corrupción y que es posible que el dispositivo no funcione correctamente. La pantalla se muestra hasta que el usuario la descarta. En el modo eio
, el controlador dm-verity no reiniciará el dispositivo si se produce un error de verificación. En cambio, se devolverá un error EIO y la app deberá controlar el error.
La intención es que se ejecute el actualizador del sistema (para que se pueda instalar un nuevo SO sin errores de corrupción) o que el usuario pueda extraer del dispositivo la mayor cantidad posible de sus datos. Una vez que se haya instalado el nuevo SO, el cargador de arranque notará el SO recién instalado y volverá al modo restart
.