Linux Embedded

Le blog des technologies libres et embarquées

Secure boot sur Raspberry Pi 4

  1. Introduction

Dans ce post, nous nous concentrons sur le Secure Boot pour la carte de développement Raspberry Pi 4. On décrit le processus de configuration et de flashage d’une image Buildroot pour n'accepter que les images signées.

  1. Sécurité dans les objets connectés

Avant d'expliquer comment sécuriser le bootloader, il faut examiner pourquoi cela est nécessaire.

Les objets connectés sont de plus en plus présents dans notre vie quotidienne, que ce soit pour contrôler notre maison ou pour contrôler un processus industriel. Cependant, il est important de sécuriser ces objets pour protéger la vie privée, les biens et les réseaux contre les menaces en ligne. 

  1. Importance de sécuriser les objets connectés

Il y a plusieurs raisons pour lesquelles il est important de sécuriser les objets connectés :

  • Protection de la vie privée. Les objets connectés collectent et transmettent des données personnelles, comme l'emplacement, les conversations ou les habitudes de consommation. Si ces objets ne sont pas sécurisés, ces données peuvent être interceptées et utilisées à des fins malveillantes, comme le piratage.
  • Protection des biens. Les objets connectés peuvent être utilisés pour contrôler des appareils électroniques, comme les thermostats, les serrures ou les alarmes. Si ces objets ne sont pas sécurisés, ils peuvent être piratés et utilisés pour causer des dommages matériels ou perturber le fonctionnement des biens.
  • Protection contre les attaques de réseau. Les objets connectés sont souvent connectés à d'autres appareils via un réseau domestique ou une connexion Internet. Si ces objets ne sont pas sécurisés, ils peuvent être utilisés pour lancer des attaques de réseau ou pour accéder à d'autres appareils connectés au réseau.
  1. Secure boot et chain of trust

Un des mécanismes important dans la sécurité de l'appareil est le bootloader (chargeur de démarrage en français). Le bootloader est un programme qui charge le système d'exploitation sur un appareil électronique lors de son démarrage. Ce logiciel peut être utilisé pour vérifier l'intégrité et l'authenticité du système d'exploitation avant de le charger. Pour implémenter ce mécanisme de vérification, il faut mettre en place une chain of trust (chaîne de confiance en français).

La chain of trust est un concept clé dans la sécurisation des objets connectés. Il s'agit d'une stratégie qui relie les différents éléments d'un système de sécurité et garantit que seuls les éléments autorisés ont accès aux données et aux fonctionnalités de l'objet connecté. Cela permet d'authentifier les appareils pour s'assurer qu'ils sont bien ceux qu'ils prétendent être, de protéger contre les logiciels malveillants et de sécuriser les communications entre l'objet connecté, les autres appareils et les services dans le cloud.
Il est possible d’utiliser ce mécanisme avec le bootloader pour s'assurer que seuls les systèmes d'exploitation autorisés peuvent être chargés sur l'appareil. Par exemple, le bootloader peut utiliser une clé publique afin d’en vérifier l’authenticité. Seuls les binaires qui possèdent une signature avec la clé privée peuvent continuer avec le démarrage du système.

Le verrouillage du bootloader permet de protéger l'appareil connecté contre les logiciels malveillants ou altérés qui pourraient compromettre sa sécurité. En sécurisant le bootloader, nous garantissons l'intégrité du système d'exploitation et de l'objet connecté en général. Par exemple, sur une Raspberry Pi, cela empêche de remplacer la carte SD et de faire fonctionner un autre système.

La vérification de la signature avec la clé publique est un processus qui utilise un algorithme de chiffrement asymétrique (basé sur une paire de clés privée/publique). Lorsque l'image est créée, elle est signée en utilisant une clé privée correspondante. La signature est ensuite attachée à l'image. Lorsque l'appareil démarre et charge l'image, il utilise la clé publique stockée en mémoire ROM pour vérifier la signature. Le processus de vérification fonctionne comme suit :

L'appareil calcule une empreinte numérique (ou "hash") de l'image à vérifier
Il utilise la clé publique pour déchiffrer la signature attachée à l'image
Il compare l'empreinte numérique de l'image calculée avec l'empreinte numérique déchiffrée de la signature.

Si les deux empreintes numériques correspondent, cela signifie que l'image n'a pas été altérée et que la signature est valide. Cela garantit que seul le détenteur de la clé privée correspondante peut signer l'image, et que l'image n'a pas été altérée après avoir été signée. Une résumée du processus est décrite dans l'image suivante :

Image signing
  1. Secure boot sur Raspberry Pi 4

Sur la dernière version de la carte Raspberry Pi (BCM2711), le démarrage sécurisé par vérification de signature est rendu possible grâce aux registres OTP (One Time Programmable) existants et à l'ajout d'une mémoire EEPROM. 

La Raspberry Pi 4 présente une innovation majeure en intégrant une mémoire EEPROM qui permet de mettre en place un "secure bootloader". Cela implique un changement de paradigme dans le processus de démarrage de la carte. Sur la nouvelle version, le premier bootloader est stocké dans cette mémoire au lieu d'être exécuté directement depuis la carte SD comme sur les versions précédentes. 

Ce changement permet de vérifier l'intégrité du code provenant d'une source externe, comme une carte SD. Il est possible de configurer la mémoire EEPROM en lecture seule, une fois que les registres OTP (One Time Programmable) sont activés, ce qui empêche toute modification de son contenu. Ce point est important, car si un attaquant parvient à modifier l'EEPROM, il peut désactiver la fonction du Secure Boot, ce qui rend l'appareil vulnérable aux logiciels altérés. 

  1. EEPROM dans Raspberry Pi 4

L'EEPROM est un type de mémoire qui peut être lue et modifiée électroniquement et est souvent utilisée pour stocker des données qui doivent être conservées même lorsque l'appareil est éteint. Elle est particulièrement utile dans les applications qui nécessitent des mises à jour fréquentes des données stockées, car elle peut être effacée et réécrite un grand nombre de  fois. 

Le layout officiel de l'image EEPROM n'étant pas disponible en ligne, nous avons pu en déduire un schéma par reverse engineering :

Secure boot schema

Le bootloader code contient les instructions pour exécuter le premier bootloader. Il est fourni par la fondation Raspberry Pi et son code source est propriétaire. La section suivante de l'EEPROM contient la clé publique au format binaire, et enfin, il y a une section pour stocker les configurations du bootloader au format texte. Pour activer le Secure Boot, il est nécessaire d'avoir une clé publique valide et de définir le flag SIGNED_BOOT=1 dans les configurations du bootloader.

Comme mentionné précédemment, pour activer le mode Secure Boot sur une carte Raspberry Pi, il faut mettre le flag SIGNED_BOOT à 1. Il y a deux méthodes pour le faire : la première consiste à modifier la variable SIGNED_BOOT dans la configuration de l'EEPROM, ce qui peut être utile en phase de développement, car on peut activer/désactiver ce flag facilement. La seconde méthode (qui n'a pas été testé dans cet article et on se base dans la documentation officielle) consiste à utiliser les registres OTP de la carte, ce qui rend le flag permanent et empêche tout retour à une version non sécurisée. Afin de mettre SIGNED_BOOT à 1, on peut envisager de le faire sous Linux en utilisant la commande rpi-eeprom-config qui permet de lire et de modifier les configurations de l'EEPROM. Cependant, cette approche n'est pas recommandée car elle ne permet pas d'écrire la clé publique nécessaire pour vérifier la signature au démarrage. Si on active le mode Secure Boot sans écrire cette clé publique, la carte risque de rester bloquée jusqu'à ce que l'EEPROM soit effacée ou réinitialisée aux valeurs par défaut.

Pour mettre à jour le flag et la clé de manière sécurisée, on a choisi de passer par le mode recovery. Ce mode spécial s'active lorsqu'on place un fichier recovery.bin valide sur la carte SD. Ce fichier, fourni par la fondation Raspberry Pi, permet de mettre à jour l'image EEPROM avant que le firmware ne s'exécute, à condition qu'un fichier pieeprom.upd ou pieeprom.bin soit présent sur la carte SD. Si l’on construit une image EEPROM valide, qui contient la clé et le flag, on peut passer rapidement au Secure Boot.

Pour créer un binaire EEPROM valide (pieeprom.bin) avec un layout valide, il faut disposer des éléments suivants :

  • Pieeprom.original.bin : un fichier binaire qui contient le code du bootloader. Il est fourni par la fondation Raspberry Pi et son code source est propriétaire.
  • recovery.bin : un fichier binaire qui contient le mode recovery du bootloader. Également fourni par la fondation Raspberry Pi.
  • Boot.conf : le fichier de configuration au format texte.
  • Un couple de clés (publique/privée). Une clé privée pour signer les images générées avec Buildroot et une clé publique qui sera enregistrée dans l'EEPROM de la carte.
  • Le script rpi-eeprom-config fourni par la fondation Raspberry Pi, qui contient les outils nécessaires pour créer une image EEPROM.
  • Le script rpi-eeprom-digest fourni par la fondation Raspberry Pi, qui contient les outils pour signer une image EEPROM.

Pour générer la clé privée, il faut utiliser la commande suivante :

$ openssl genrsa -out priv.pem 2048

Une fois la clé privée générée, on peut générer la clé publique avec la commande :

$ openssl rsa -in priv.pem -out pub.pem -outform PEM -pubout

Le script rpi-eeprom-config, avec l'option -c, permet de créer une image EEPROM. Pour ce faire, on peut utiliser la commande suivante : 

$ rpi-eeprom-config -c boot.conf -p mypubkey.pem -o pieeprom.bin pieeprom.original.bin

Bien que ça ne soit pas obligatoire, la documentation officielle recommande de créer une signature pour l'image EEPROM générée en utilisant la commande : 

$ rpi-eeprom-digest -i pieeprom.bin -o pieeprom.sig

Pour résumer, le schéma de création est le suivant :

 

secure boot RPI 4 EEPROM Layout

Pour mettre à jour l'EEPROM et activer le mode Secure Boot, il suffit de préparer une carte SD selon le schéma suivant : 

SD_CARD 

├── pieeprom.bin 

├── pieeprom.sig 

└── recovery.bin

Puis de brancher la carte SD sur la Raspberry Pi et de connecter un câble HDMI à la carte. Si l'écran s'affiche en vert, cela signifie que la mise à jour de l'EEPROM a réussi. En cas d'écran rouge, cela indique qu'une erreur s'est produite.

  1. Image signée

Une image signée pour tester le démarrage sécurisé doit être générée une fois que le Secure Boot est activé sur votre Raspberry Pi. Plusieurs façons de créer une image Linux pour Raspberry Pi et de la signer existent, mais un "fork" de buildroot disponible sur GitHub a été choisi (https://github.com/raspberrypi/buildroot/tree/raspberrypi-signed-boot). Le projet "signed-boot" pour Raspberry Pi fournit un exemple de configuration de carte et de paquets d'aide qui montrent comment créer une image de démarrage signée pour Raspberry Pi.

Pour utiliser ce projet, vous devez d'abord cloner le référentiel GitHub sur votre ordinateur. Ensuite, la variable "BR2_PACKAGE_RPI_EEPROM_PRIVATE_KEY" dans le fichier configs/raspberrypi-signed-boot_defconfig doit être modifiée avec le chemin vers votre clé privée. Une fois cette modification effectuée, les commandes suivantes doivent être exécutées pour compiler tous les modules et l'image Linux finale pour votre Raspberry Pi :

$ make raspberrypi-signed-boot_defconfig 
$ make all

La compilation de Buildroot va générer une image appelée "sdcard.img" qui contiendra à l'intérieur les fichiers "boot.img" (image à demarrer) et "boot.sig" (signature de boot.img). L'image pour la carte SD se trouve dans le dossier output/images. Cette image signée peut maintenant être utilisée pour tester le démarrage sécurisé sur votre Raspberry Pi.

Pour flasher l'image "sdcard.img" sur la carte SD de la Raspberry Pi, vous pouvez utiliser l'outil de flashage préféré, comme BalenaEtcher (ou la commande dd). Suivez les instructions de l'outil pour flasher l'image sur la carte SD.

Une fois le flash terminé, insérez la carte SD dans la Raspberry Pi et allumez-la. Vous devriez voir les messages suivants s'afficher sur la console série :

…
secure-boot
Loading boot.img ...
SIG boot.sig 4ab3359546d58beb2a998b00d15840c41d50c5b2f966d326fcc851c7d2f8c3ba 1671723548
 …

Ce message indique que le Secure Boot est en train de charger l'image de démarrage "boot.img" et que cette image est signée avec une clé de signature valide. Si vous voyez ce message, cela signifie que le Secure Boot est fonctionnel et que l'image de démarrage est valide.

Si tout se passe bien, vous devriez également voir le noyau Linux initialiser et afficher les messages suivants :

… 
RSA verify
rsa-verify pass (0x0)
MBR: 0x00000000, 0 type: 0x00
…

Ces messages indiquent que le noyau Linux est en train de démarrer et de vérifier les partitions de la carte SD. Si vous voyez ces messages, cela signifie que le noyau Linux a été lancé correctement et que la carte SD est prête à être utilisée. Si vous ne voyez pas ces messages ou si vous constatez des erreurs, cela peut être dû à un problème avec l'image flashée ou avec la configuration de la mémoire EEPROM.

  1. Tests

    1. Test avec image non signée

Il est possible de tester le Secure Boot en essayant de démarrer la Raspberry Pi avec une image de démarrage non signée. Si le Secure Boot est activé, la carte devrait refuser de démarrer avec cette image et afficher un message d'erreur indiquant que l'image de démarrage n'est pas valide. Nous avons testé cette fonctionnalité en utilisant Raspbian, le système d'exploitation par défaut de la Raspberry Pi, et lors du démarrage, nous avons obtenu la trace suivante :

…
Secure-boot
Loading boot.img...
Error 6 loading boot.img
…

Cela indique que le Secure Boot empêche le démarrage de l'appareil si l'image de démarrage n'a pas de signature valide.

  1. Test avec image modifiée

Il est également possible de tester le Secure Boot en modifiant une image de démarrage avant de la lancer sur la Raspberry Pi. Pour ce faire, on peut copier l'image finale qui se trouve sur la carte SD, puis utiliser un outil hexadécimal pour modifier un octet ou une chaîne de caractères de l'image. Par exemple, nous avons changé la chaîne "errors" en "HACKED" et nous avons obtenu le log suivant :

…
Secure-boot
Loading boot.img...
SIG boot.sig 879c5f0a611e14d6e994e17d7932325f614c353f519d7877a6053acf56ddce03 1672664645
Verifying
Bad signature boot.img
Error 12 loading boot.img
…

Cela signifie que l'image ne provient pas de la personne qui détient la clé privée associée à la clé publique enregistrée dans l'EEPROM de notre Raspberry Pi.

  1. Travaux à faire

Le Secure Boot est une fonctionnalité importante pour renforcer la sécurité de la plateforme. Cependant, il y a encore des opportunités pour améliorer son implémentation et son utilisation. 

Un élément qui n'a pas encore été testé sont les enregistrements OTP (One-Time Programmable). Ces cellules de mémoire ne peuvent être programmées qu'une seule fois et sont souvent utilisées pour stocker des informations sensibles, comme des clés de chiffrement ou le hachage de ces clés, qui ne doivent pas être divulguées ou modifiées. 

En l'absence de matériel, nous avons décidé de reporter le test de cette fonctionnalité à une date ultérieure. Cela signifie que des questions intéressantes restent sans réponse : comment le mode "recovery" fonctionne-t-il une fois que les OTP sont activées ? Que se passerait-il si l'on ne procédait pas à l'ajout d'un hachage de la clé publique aux OTP (One-Time Passwords) ? L'utilisation d'un hash de la clé publique permet de garantir l'authenticité de cette dernière. En l'absence de vérification de ce hash, il serait possible d'insérer n'importe quelle clé publique dans l'EEPROM, et le bootloader l'accepterait comme valide ?

Il y a de nombreuses autres questions auxquelles il serait intéressant de répondre afin de mieux comprendre le comportement de cette fonctionnalité et de s'assurer de sa fiabilité.

  1. Conclusion

Le Secure Boot est une fonctionnalité cruciale pour assurer la sécurité des systèmes embarqués, et il est maintenant possible de l'activer et de l'utiliser sur une Raspberry Pi 4. Cependant, il reste encore du travail à faire pour améliorer l'implémentation, notamment en testant l'utilisation des OTP. 

Même avec le Secure Boot activé, il est important de ne pas sous-estimer les risques de sécurité et de continuer à mettre en place d'autres mesures de protection, telles que la mise à jour régulière du système et la mise en place de stratégies de gestion des vulnérabilités. En fin de compte, le Secure Boot est une protection précieuse, mais n'est pas infaillible. C'est pourquoi il est essentiel de continuer à travailler pour améliorer l'implémentation et étendre son utilisation dans les systèmes embarqués.

Il est important de comprendre que le Secure Boot ne vise pas à protéger les données de l'image contre un pirate informatique qui voudrait les copier, mais plutôt à protéger le dispositif contre l'utilisation d'une "mauvaise image" qui pourrait compromettre la sécurité du système. Cette technique ne crypte pas l'image et elle peut donc être lue par un tiers. Il est donc important de comprendre que Secure Boot est une technique de sécurité supplémentaire qui vient renforcer la sécurité globale d'un système, mais qui ne doit pas être utilisée comme une solution unique pour protéger les données.

Pour ceux qui souhaitent en savoir plus sur cette implémentation, un projet Buildroot avec tout le nécessaire pour générer des images Secure Boot et EEPROM est disponible sur le lien suivant (https://github.com/Openwide-Ingenierie/raspberry-pi4-secure-boot) . N'hésitez pas à le consulter et à contribuer à l'amélioration de cette fonctionnalité sur la Raspberry Pi 4.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.