Vérifier le démarrage

Le démarrage sécurisé nécessite de vérifier de manière cryptographique tout le code et toutes les données exécutables qui font partie de la version Android démarrée avant qu'elle ne soit utilisée. Cela inclut le noyau (chargé à partir de la partition boot), l'arborescence des périphériques (chargée à partir de la partition dtbo), la partition system, la partition vendor, etc.

Les petites partitions, telles que boot et dtbo, qui ne sont lues qu'une seule fois sont généralement validées en chargeant l'intégralité du contenu en mémoire, puis en calculant son hachage. Cette valeur de hachage calculée est ensuite comparée à la valeur de hachage attendue. Si la valeur ne correspond pas, Android ne se charge pas. Pour en savoir plus, consultez la section Démarrage.

Les partitions plus grandes qui ne rentrent pas dans la mémoire (comme les systèmes de fichiers) peuvent utiliser un arbre de hachage, où la vérification est un processus continu qui se produit lorsque les données sont chargées dans la mémoire. Dans ce cas, le hachage racine de l'arbre de hachage est calculé au moment de l'exécution et est comparé à la valeur de hachage racine attendue. Android inclut le pilote dm-verity pour valider les partitions plus grandes. Si à un moment donné le hachage racine calculé ne correspond pas à la valeur de hachage racine attendue, les données ne sont pas utilisées et Android passe dans un état d'erreur. Pour en savoir plus, consultez la section Corruption de dm-verity.

Les hachages attendus sont généralement stockés à la fin ou au début de chaque partition validée, dans une partition dédiée ou les deux. Surtout, ces hachages sont signés (directement ou indirectement) par la racine de confiance. Par exemple, l'implémentation AVB est compatible avec les deux approches. Pour en savoir plus, consultez Android Verified Boot.

Protection contre le rollback

Même avec un processus de mise à jour entièrement sécurisé, il est possible qu'un exploit de kernel Android non persistant installe manuellement une ancienne version plus vulnérable d'Android, redémarre dans la version vulnérable, puis utilise cette version d'Android pour installer un exploit persistant. L'attaquant devient alors propriétaire permanent de l'appareil et peut faire tout ce qu'il veut, y compris désactiver les mises à jour.

La protection contre cette classe d'attaques s'appelle la protection contre le rollback. La protection contre le rollback est généralement implémentée à l'aide d'un stockage inviolable pour enregistrer la version la plus récente d'Android et refuser de démarrer Android s'il est inférieur à la version enregistrée. Les versions sont généralement suivies par partition.

Pour en savoir plus sur la façon dont AVB gère les protections contre le rollback, consultez le README d'AVB.

Gérer les erreurs de validation

La vérification peut échouer au démarrage (par exemple, si le hachage calculé sur la partition boot ne correspond pas au hachage attendu) ou au moment de l'exécution (par exemple, si dm-verity rencontre une erreur de vérification sur la partition system). Si la validation échoue au démarrage, l'appareil ne peut pas démarrer et l'utilisateur final doit suivre une procédure pour le récupérer.

Si la validation échoue au moment de l'exécution, le flux est un peu plus compliqué. Si l'appareil utilise dm-verity, il doit être configuré en mode restart. En mode restart, si une erreur de validation se produit, l'appareil redémarre immédiatement avec un indicateur spécifique défini pour indiquer la raison. Le bootloader doit remarquer cet indicateur et passer dm-verity en mode d'erreur d'E/S (eio) et rester dans ce mode jusqu'à ce qu'une nouvelle mise à jour soit installée.

Lors du démarrage en mode eio, l'appareil affiche un écran d'erreur informant l'utilisateur qu'une corruption a été détectée et que l'appareil risque de ne pas fonctionner correctement. L'écran s'affiche jusqu'à ce que l'utilisateur le ferme. En mode eio, le pilote dm-verity ne redémarre pas l'appareil en cas d'erreur de validation. Au lieu de cela, une erreur EIO est renvoyée et l'application doit gérer l'erreur.

L'objectif est que le programme de mise à jour du système s'exécute (afin qu'un nouvel OS sans erreur de corruption puisse être installé) ou que l'utilisateur puisse récupérer autant de données que possible sur l'appareil. Une fois le nouvel OS installé, le bootloader le détecte et revient en mode restart.