Inicio verificado

El inicio 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 inicia antes de usarla. 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.

Por lo general, las particiones pequeñas, como boot y dtbo, que se leen solo una vez, se verifican 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, no se cargará Android. 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 de hash en el que la verificación es un proceso continuo que se produce 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 compara con el valor de hash raíz esperado. 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 usan los datos y Android entra en un estado de error. Para obtener más detalles, consulta Daño de dm-verity.

Los hashes esperados suelen almacenarse al final o al principio de cada partición verificada, en una partición dedicada o en ambas. Es fundamental que la raíz de confianza firme estos valores hash (directa o indirectamente). A modo de ejemplo, la implementación de AVB admite ambos enfoques. Consulta Inicio verificado de Android para obtener más información.

Protección contra la reversión

Incluso con un proceso de actualización completamente seguro, es posible que un exploit de kernel de Android no persistente instale, de forma manual, una versión anterior y más vulnerable de Android, se reinicie en la versión vulnerable y, luego, use esa versión de Android para instalar un exploit persistente. Desde allí, el atacante es propietario permanente del dispositivo y puede hacer lo que quiera, incluida la inhabilitación de las actualizaciones.

La protección contra esta clase de ataques se denomina Protección contra reversión. Por lo general, la protección contra la reversión se implementa con el uso de 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 realiza un seguimiento de las versiones por partición.

Para obtener más detalles sobre cómo AVB controla las protecciones de reversión, consulta el archivo README de AVB.

Controla los errores de verificación

La verificación puede fallar en el momento del inicio (por ejemplo, si el hash calculado en la partición boot no coincide con el hash esperado) o en el tiempo de ejecución (por ejemplo, si dm-verity encuentra un error de verificación en la partición boot).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, se debe configurar 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 usar el modo de error de E/S (eio) y permanecer en este modo hasta que se instale una actualización nueva.

Cuando se inicia en el modo eio, el dispositivo muestra una pantalla de error que le informa al usuario que se detectó un daño 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 encuentra un error de verificación. En su lugar, se muestra un error de EIO y la app debe controlar el error.

El objetivo es que se ejecute el actualizador del sistema (para que se pueda instalar un SO nuevo sin errores de corrupción) o que el usuario pueda extraer la mayor cantidad posible de sus datos del dispositivo. Una vez que se instala el SO nuevo, el cargador de arranque advierte el SO recién instalado y vuelve al modo restart.