Introduction
Imaginez que votre système embarqué soit une boîte de chocolat et que vous soyez dans un monde où des farfadets malicieux se faufilent la nuit pour remplacer vos délicieux chocolats par d’horribles légumes verts. Pour vous assurer que vos chocolats restent intacts et non-altérés par ces satanés farfadets il va falloir voir plus loin qu’un simple emballage : c’est là qu’intervient MCUboot, votre détective privé numérique prêt à scanner chaque chocolat pour détecter toute altération ou remplacement suspect.
Enfilez votre chapeau de détective, armez-vous de votre loupe car dans cet article vous allez découvrir tout ce qu’il faut savoir pour lutter contre les farfadets gourmands au travers de l’univers de Zephyr Project et de MCUboot 🧐.
Qu'est ce que Zephyr Project ?
Nous ne nous attarderons pas sur la présentation du projet Zephyr car il existe déjà un très bon article sur ce sujet, bien qu'un peu daté, réalisé par Geoffrey Le Gourrierrec : Découverte de l’OS Zephyr, 2017 (merci à lui). Nous aborderons donc simplement les grandes lignes du projet Zephyr et citerons quelques chiffres un peu plus actuels.
Le projet Zephyr est un projet Open Source sous licence Apache 2.0 initié en 2015 et passé sous l’égide de la Fondation Linux en 2017. Il permet de créer un OS basé sur un kernel léger respectant des contraintes temps-réel fortes conçu notamment pour des systèmes embarqués à ressources limitées, il est principalement utilisé dans les objets connectés. Cet OS se distingue de part :
Sa forte configurabilité
Sa légèreté
Sa sécurité
Zephyr c’est aussi plus de 600 boards supportées à ce jour, contre 200 à l’époque de Geoffrey Le Gourrierrec, plus de 180 capteurs déjà intégrés, 8 architectures supportées, une large gamme d'options pour l’IoT, etc. Pour faire simple, Zephyr offre tous les outils nécessaires pour réaliser une application IoT dans les meilleures conditions. Nous nous intéresserons par la suite à comment créer une application Zephyr de A à Z.
Zephyr propose également de sécuriser l’amorçage d’applications en exploitant MCUboot en tant que bootloader sécurisé. Ça tombe bien, c’est le sujet de la partie suivante 😉.
Qu’est ce que MCUboot et en quoi joue-t-il un rôle crucial dans la réalisation et la maintenance d’un objet connecté ?
Avant de se plonger dans l'univers de MCUboot il est important de rappeler ce qu’est un bootloader et quelle est son utilité concrètement dans un système embarqué. Le bootloader est le premier programme qui s’exécute après un reset ou une mise en tension du système. Pour faire très simple, il permet de sauter dans l’application qui anime notre système. Il se situe dans la mémoire flash avec le binaire de l’application qu’il doit lancer. Il existe différentes manières de mapper la mémoire flash selon le cas d’utilisation. La mémoire flash est séparée en secteurs : un ou plusieurs secteurs pour le bootloader et plusieurs secteurs pour le programme principal. Il est possible d’allouer un certain nombre de secteurs pour un deuxième slot du programme principal, généralement utilisé pour installer une mise à jour du firmware.
Dans un premier temps, le bootloader initialise les composants matériels du microcontrôleur pour “préparer le terrain” pour un fonctionnement optimal. Ensuite, il vérifie l’intégrité du programme principal dans le but de prévenir toute faille de sécurité. Enfin, il charge le programme principal dans la mémoire.
Mais alors pourquoi est-il si crucial de choisir un bootloader robuste tel que MCUboot dans un objet connecté ?
Tout d’abord, MCUboot empêche l’exécution de logiciels malveillants en vérifiant les signatures des firmwares pour s’assurer qu’ils proviennent bien d’une source de confiance. Il possède plusieurs algorithmes de cryptographie, notamment ECDSA et RSA pour la vérification de signatures.
De plus, MCUboot est conçu pour être agnostique par rapport à la plateforme et peut donc être utilisé avec diverses architectures matérielles et RTOS. Cette flexibilité permet de l’intégrer facilement dans différents projets et environnement matériels.
MCUboot permet de gérer plusieurs images de firmware, facilitant ainsi la mise à jour et le déploiement de versions plus récentes. Il prend en charge diverses fonctionnalités comme par exemple le “rollback” qui permet de revenir sur une version précédente en cas de problème ou encore le “swap” qui permet d’échanger des firmwares dans la flash à l’aide d’une partition appelée “scratch partition”.
Enfin, MCUboot est modulaire et peut être configuré pour inclure uniquement les fonctionnalités nécessaires, ce qui est intéressant sur les appareils ayant des contraintes fortes en termes de mémoire. Il est aussi possible de modifier le mode de mise à niveau d’image, la clé permettant de vérifier les signatures, et bien d’autres options que nous verrons par la suite.
Dans la partie suivante nous allons nous intéresser à la mise en place de MCUboot dans un projet Zephyr.
Mise en place de MCUboot dans une application Zephyr
Tout au long de cet article j’utiliserai la board de découverte IoT B-L475-IOT01A2 de chez ST, appelée disco_l475_iot1 dans les bases de données Zephyr. Si vous souhaitez reproduire ce tutoriel avec une autre cible, assurez-vous que votre cible soit compatible avec MCUboot et modifiez "disco_l475_iot1" par le nom de votre board dans chaque commande shell dans laquel le nom de la board intervient.
Création d’une application Zephyr
Récupérer le projet zephyr et mcuboot
Pour récupérer le projet Zephyr suivez le Getting Started Guide disponible dans la documentation zephyr. Un exemple de compilation et de flashage est disponible à la fin de ce guide, ça vous aidera à prendre un peu la main avec l’environnement.
Une application Zephyr est constituée de différents fichiers nécessaires à la compilation.
- Le fichier CMakeLists.txt permet de spécifier au système de compilation où sont situés les fichiers sources et lie le répertoire de l’application au système de compilation CMake de Zephyr.
- Le fichier app.overlay est un fichier de type device tree qui permet de modifier ou ajouter des composants hardware spécifiques à l’application.
- Le fichier prj.conf est le fichier de configuration de notre application, il permet de configurer les fonctionnalités logicielles utilisées par notre application.
- VERSION est un fichier texte contenant des informations de version. Il permet de gérer le cycle de vie de l’application et d’automatiser la fourniture de la version de l’application lors de la signatures des images d’applications.
- Le dossier src contient le programme principal ainsi que les fichiers sources utiles à la compilation.
Création de l’application
Pour créer une application Zephyr vierge voici les étapes à suivre :
Tout d’abord, créons tous les fichiers nécessaires à l’application.
~/zephyrproject$ mkdir app && cd app
~/zephyrproject/app$ touch CMakeLists.txt | touch app.overlay | touch prj.conf | touch VERSION | mkdir src
~/zephyrproject/app$ cd src/
~/zephyrproject/app/src$ touch main.c
Ensuite créons une application simple.
main.c :
#include <stdio.h>
int main(void)
{
printf("Hello World from %s\n", CONFIG_BOARD_TARGET);
return 0;
}
Modifions le CMakeLists.txt pour spécifier les chemins nécessaires à la compilation.
CMakeLists.txt :
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(app)
target_sources(app PRIVATE src/main.c)
Si votre application ne s’appelle pas app, modifiez le nom de l’application dans project()
Spécifions ensuite la version de l’application.
VERSION (1.0.0+0) :
VERSION_MAJOR = 1
VERSION_MINOR = 0
PATCHLEVEL = 0
VERSION_TWEAK = 0
Les fichiers app.overlay et prj.conf sont laissés vides car nous n’avons pas besoin de rajouter de fonctionnalités spécifiques à notre application pour le moment.
Désormais nous pouvons compiler le projet :
~/zephyrproject/app$ west build -p -b disco_l475_iot1
Si tout se passe bien, un fichier de build devrait avoir été créé.
Et dans celui-ci on devrait retrouver le binaire (ou l’hexa) flashable sur notre cible.
Retournons désormais dans le répertoire de notre application pour flasher l’application sur la board.
~/zephyrproject/app$ west flash
Pour visualiser la sortie de la board dans un autre terminal (vous pouvez utiliser screen, picocom, minicom,...) :
$ screen /dev/ttyACM0 115200
Vous savez maintenant comment créer une application Zephyr “from scratch”. Pour personnaliser votre application vous pouvez vous inspirer des samples situés ici ou vous référer à la documentation présente sur le site de Zephyr.
Intégrer MCUboot à notre application
Compiler et flasher le bootloader
Maintenant que vous êtes familier avec Zephyr, nous allons intégrer MCUboot à notre application. Pour se faire allons dans le répertoire du bootloader :
~/zephyrproject/app$ cd ~/zephyrproject/bootloader/mcuboot/boot/zephyr/
La première manipulation à réaliser est spécifique à la board que j’utilise, il faut modifier le fichier de configuration de la board, situé dans le dossier “bootloader/mcuboot/boot/zephyr/boards”. Les anciennes versions du microcontrôleur de cette board acceptaient 256 secteurs pour l’image, c’est pourquoi dans le fichier de configuration de la board on retrouve "CONFIG_BOOT_MAX_IMG_SECTORS=256". Si on flash le bootloader en l’état, il en résulte une erreur :
Pour résoudre ce problème, on augmente simplement le nombre de secteurs à 512 pour matcher avec la taille de la flash. Je conseille aussi de désactiver le watchdog pour ne pas avoir de reset indésirable. Le fichier de configuration de la board devrait désormais ressembler à ça :
CONFIG_BOOT_MAX_IMG_SECTORS=512
CONFIG_WATCHDOG=n
Une fois ces soucis réglés, on peut compiler le bootloader :
~/zephyrproject/bootloader/mcuboot/boot/zephyr$ west build -p -b disco_l475_iot1
Puis le flasher :
~/zephyrproject/bootloader/mcuboot/boot/zephyr$ west flash
Compiler, signer et flasher l’application
Votre bootloader est maintenant installé sur votre board, super ! Testons maintenant son efficacité en essayant de flasher l’application zephyr créée précédemment.
Plaçons-nous de nouveau dans le répertoire de notre application :
~/zephyrproject/bootloader/mcuboot/boot/zephyr$ cd ~/zephyrproject/app/
Modifions le fichier de configuration de sorte que l’application soit compatible avec MCUboot :
~/zephyrproject/app$ echo "CONFIG_BOOTLOADER_MCUBOOT=y" > prj.conf
Ensuite, on re-compile notre application et on la flash :
~/zephyrproject/bootloader/mcuboot/boot/zephyr$ west build -b disco_l475_iot1
~/zephyrproject/bootloader/mcuboot/boot/zephyr$ west flash
Si vous avez bien suivi, vous ne devriez pas être étonné des logs que nous envoie la board :
En effet, nous avons flashé un binaire non-signé sur une cible protégée par MCUboot, il est donc normal que cette image soit considérée comme non-valide.
Pour rendre cette image valide aux yeux de notre bootloader il faut la signer avec LA clé qui est acceptée par le bootloader. Par défaut cette clé est présente dans le repository de MCUboot et s’intitule “root-rsa-2048.pem”. Si l’application est destinée à de la production il faut impérativement modifier cette clé pour utiliser une clé générée manuellement de sorte que seules les personnes autorisées à installer un nouveau firmware sur la cible la possèdent. Gardez cette clé privée, ne la commitez pas sur Git.
Pour générer une clé, plaçons-nous dans le répertoire de MCUboot :
~/zephyrproject/bootloader/mcuboot/boot/zephyr$ cd ~/zephyrproject/bootloader/mcuboot/
~/zephyrproject/bootloader/mcuboot$ imgtool keygen -k personal-key.pem -t rsa-2048
Notre clé est maintenant créée, nous allons pouvoir l’installer sur notre bootloader, puis signer nos binaires avec celle-ci.
Pour l’installer sur le bootloader, on modifie le fichier de configuration de ce dernier :
~/zephyrproject/bootloader/mcuboot$ cd boot/zephyr/
~/zephyrproject/bootloader/mcuboot/boot/zephyr$ echo 'CONFIG_BOOT_SIGNATURE_KEY_FILE="personal-key.pem"' >> prj.conf
On compile et on flash :
~/zephyrproject/bootloader/mcuboot/boot/zephyr$ west build -b disco_l475_iot1
~/zephyrproject/bootloader/mcuboot/boot/zephyr$ west flash
Dernière étape : signer le binaire de l’application. On retourne maintenant dans le répertoire de notre application
~/zephyrproject/bootloader/mcuboot/boot/zephyr$ cd ~/zephyrproject/app/
Pour signer le binaire il y a deux méthodes :
- Signature manuelle après compilation :
On compile d’abord l’application
~/zephyrproject/app$ west build -b disco_l475_iot1
Comme on l’a vu précédemment, il résulte de cette compilation le fichier binaire ou hexadécimal à flasher sur la cible.
Pour signer le binaire manuellement on fait :
~/zephyrproject/app$ west sign -t imgtool -- --key ../bootloader/mcuboot/personal-key.pem
On flash enfin la version signée :
~/zephyrproject/app$ west flash --hex-file build/zephyr/zephyr.signed.hex
- Signature automatique à la compilation : Il suffit simplement d'ajouter une ligne au fichier de configuration
~/zephyrproject/app$ echo 'CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/personal-key.pem"' >> prj.conf
Puis on re-compile et on flash :
~/zephyrproject/app$ west build -b disco_l475_iot1
~/zephyrproject/app$ west flash
La commande “west flash” va flasher automatiquement le binaire signé
Désormais le binaire est valide et on boot bien l’application ! Vous savez maintenant comment sécuriser vos objets connectés contre des attaquants physiques qui chercheraient à flasher votre système sans posséder la précieuse clé permettant de signer le binaire.
Exemple de mise à jour de firmware OTA avec MCUboot et mcumgr
Désormais intéressons nous à la mise à jour de firmware OTA avec mcumgr et MCUboot. Dans cet exemple on réalisera une mise à jour via bluetooth, mais mcumgr supporte aussi la mise à jour via port série ou UDP (CoAP).
Mais qu'est ce que mcumgr ?
MCU manager est une bibliotèque de gestion de système d'exploitation embarqué. MCU manager est par conception indépendant du système d'exploitation et du matériel. Dans cet exemple nous utiliserons mcumgr pour faire une mise à jour de firmware via bluetooth.
Côté HOST, les outils de mcumgr vont nous permettre d'envoyer le binaire à jour à notre TARGET. La réception du binaire se fait grâce au client mcumgr installé côté TARGET. Ce binaire est ensuite écrit dans le second slot de la mémoire flash et sera testé au prochain reset par MCUboot (vérification de signature et d'intégrité) en remplaçant le slot 0 et le slot 1 à l'aide d'un algorithme de swap. Si le binaire passe les tests avec brio il pourra être confirmé et deviendra par conséquent le programme principal.
Tout d’abord il faut installer les outils mcumgr :
~/zephyrproject$ sudo apt install golang
~/zephyrproject$ go install github.com/apache/mynewt-mcumgr-cli/mcumgr@latest
Une fois que c’est fait, dans le répertoire “/go/bin”, situé dans votre répertoire racine, vous devriez trouver mcumgr.
Plaçons nous maintenant, dans le répertoire mcumgr de Zephyr :
~/zephyrproject$ cd ~/zephyrproject/zephyr/samples/subsys/mgmt/mcumgr/smp_svr/
Nous allons apporter quelques modifications à ce sample. Tout d’abord nous allons régler quelques soucis impliquant des warnings lors de la compilation.
On ajoute ces deux lignes au fichier de configuration zephyr/samples/subsys/mgmt/mcumgr/smp_svr/prj.conf pour régler les warnings:
CONFIG_MCUMGR_MGMT_NOTIFICATION_HOOKS=y
CONFIG_MCUMGR_GRP_FS_FILE_ACCESS_HOOK=y
Puis ces deux lignes pour signer automatiquement le binaire et pour ajouter des commandes MCUboot au shell Zephyr:
CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/personal-key.pem"
CONFIG_MCUBOOT_SHELL=y
Pour accroître la sécurité de la mise à jour, il est possible de chiffrer le binaire lors de la compilation. Ce binaire sera écrit de manière chiffrée dans le deuxième slot de la mémoire flash et sera déchiffré au moment du swap entre le premier slot et le second (scratch algorithm). Le slot 0 sera quant à lui aussi chiffré quand il sera installé dans le slot 1.
Revenons rapidement sur le partitionnement de la mémoire flash, et notamment sur le partitionnement de celle de notre board pour mieux comprendre ces propos. La board disco_l475_iot1 utilise en plus de sa flash interne une flash externe.
Dans le device tree de notre board on retrouve ces deux nodes liés à notre mémoire flash :
Flash interne :
&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 DT_SIZE_K(64)>;
read-only;
};
/*
* The flash starting at offset 0x10000 and ending at
* offset 0x1ffff is reserved for use by the application.
*/
slot0_partition: partition@20000 {
label = "image-0";
reg = <0x00020000 DT_SIZE_K(864)>;
};
scratch_partition: partition@f8000 {
label = "image-scratch";
reg = <0x000F8000 DT_SIZE_K(16)>;
};
};
};
Flash externe :
mx25r6435f: qspi-nor-flash@90000000 {
compatible = "st,stm32-qspi-nor";
reg = <0x90000000 DT_SIZE_M(8)>; /* 64 Mbits */
qspi-max-frequency = <50000000>;
status = "okay";
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
slot1_partition: partition@0 {
label = "image-1";
reg = <0x00000000 DT_SIZE_K(864)>;
};
storage_partition: partition@d8000 {
label = "storage";
reg = <0x000d8000 DT_SIZE_M(7)>;
};
};
};
Voici un schéma équivalent du device tree pour la partie mémoire flash.
Flash interne :
Flash externe :
Le swap se fait donc en remplaçant le slot 0 par le slot 1, secteurs par secteurs, en s’aidant de la partition scratch.
Pour utiliser le chiffrement du binaire à la compilation ainsi que pour pouvoir déchiffrer ce binaire il faut créer une paire de clé et ajouter ces clés à notre bootloader et à notre application.
Plaçons nous dans le répertoire de mcuboot
~/zephyrproject/zephyr/samples/subsys/mgmt/mcumgr/smp_svr$ cd ~/zephyrproject/bootloader/mcuboot/
Création de la paire de clé :
~/zephyrproject/bootloader/mcuboot$ imgtool keygen -k priv-key-rsa-2048.pem -t rsa-2048
Extraction de la clé publique :
~/zephyrproject/bootloader/mcuboot$ imgtool getpub -k priv-key-rsa-2048.pem -e pem > pub-key-rsa-2048.pem
On notera qu’il est indispensable de choisir un mécanisme de chiffrement identique au mécanisme de signature (ici RSA 2048).
Installation de la clé privée sur le bootloader et la clé publique sur le système de compilation :
Ajoutez au fichier de configuration du bootloader :
CONFIG_BOOT_ENCRYPT_IMAGE=y
CONFIG_BOOT_ENCRYPTION_KEY_FILE="priv-key-rsa-2048.pem"
Attention, cette clé est écrite en clair dans le binaire du bootloader, il n'est donc pas impossible pour quelqu'un de mal inténtionné de la récupérer. Pour de la production il faudra penser à s'orienter vers un dispositif de stockage de secret par exemple un SE (Secure Element), un TPM (Trusted Platform Modules) ou encore un TEE (Trusted Execution Environments).
Ajoutez au fichier de configuration du sample zephyr/samples/subsys/mgmt/mcumgr/smp_svr :
CONFIG_MCUBOOT_ENCRYPTION_KEY_FILE="bootloader/mcuboot/pub-key-rsa-2048.pem"
On ajoute ensuite un fichier VERSION au sample car il n’en possède pas :
~/zephyrproject/zephyr/samples/subsys/mgmt/mcumgr/smp_svr$ touch VERSION
Et on ajoute ces lignes :
VERSION_MAJOR = 1
VERSION_MINOR = 0
PATCHLEVEL = 0
VERSION_TWEAK = 0
Maintenant flashons le bootloader puis le sample sur la board :
~/zephyrproject/zephyr$ cd ~/zephyrproject/bootloader/mcuboot/boot/zephyr/
~/zephyrproject/zephyr$ west flash
~/zephyrproject/bootloader/mcuboot/boot/zephyr$ cd ~/zephyrproject/zephyr/samples/subsys/mgmt/mcumgr/smp_svr/
~/zephyrproject/zephyr/samples/subsys/mgmt/mcumgr/smp_svr$ west build -p -b disco_l475_iot1 -- -DCONF_FILE="prj.conf overlay-bt.conf"
~/zephyrproject/zephyr/samples/subsys/mgmt/mcumgr/smp_svr$ west flash
Le sample devrait tourner et si vous tapez mcuboot dans le shell de votre application, voici ce que vous devriez obtenir :
Installation d’un nouveau firmware :
Modifiez le PATCHLEVEL dans le fichier VERSION créé précédemment, PATCHLEVEL = 1 par exemple.
Rebuildez le sample :
/zephyrproject/zephyr/samples/subsys/mgmt/mcumgr/smp_svr$ west build -p -b disco_l475_iot1 -- -DCONF_FILE="prj.conf overlay-bt.conf"
Cette commande a créé un binaire signé et chiffré
Copiez le binaire dans votre dossier où se trouve le serveur mcumgr :
~/zephyrproject/zephyr/samples/subsys/mgmt/mcumgr/smp_svr$ scp build/zephyr/zephyr.signed.encrypted.bin ../../../../../../../go/bin/
Ouvrez un nouveau terminal dans le répertoire du serveur mcumgr et exécutez la commande suivante qui va afficher la liste des images présentes sur votre cible :
~$ cd ~/go/bin/
~/go/bin$ sudo ./mcumgr --conntype ble --connstring 'peer_name=Zephyr' image list
Installons maintenant le nouveau firmware :
~/go/bin$ sudo ./mcumgr --conntype ble --connstring 'peer_name=Zephyr' image upload zephyr.signed.encrypted.bin
Si tout s’est bien passé un nouvelle image devrait apparaître :
La version 1.0.1 a bien été installée, il faut ensuite la tester. Pour la tester on fait un image test avec le hash de cette version (vous devez modifier le hash pour mettre le votre):
~/go/bin$ sudo ./mcumgr --conntype ble --connstring 'peer_name=Zephyr' image test a936106b77aebf771336e8c33e5c7c1892ce7b271398c2d2942452c584714df7
Le flag du slot 1 est désormais en attente, ce qui veut dire qu’au prochain reset le slot 0 et le slot 1 vont s’interchanger et la nouvelle image va être testé (vérification de la signature et déchiffrage). On reset donc la cible :
- Manuellement en appuyant sur le bouton reset de la board
- Via mcumgr :
~/go/bin$ sudo ./mcumgr --conntype ble --connstring 'peer_name=Zephyr' reset
- Via le shell Zephyr :
uart:~$ kernel reboot cold
Après le reset on vérifie qu’on boot bien sur la nouvelle version :
Cette version est toujours en phase de test et n’est pas confirmée (Cf “image ok:unset” et “swap type: revert”). Si vous voulez qu’au prochain reset on reboot sur cette image il faut la confirmer. Elle peut être confirmée de deux manières différentes :
- Via mcumgr :
~/go/bin$ sudo ./mcumgr --conntype ble --connstring 'peer_name=Zephyr' image confirm a936106b77aebf771336e8c33e5c7c1892ce7b271398c2d2942452c584714df7
- Via le shell Zephyr:
uart:~$ mcuboot confirm
Enfin on vérifie que l’image a bien été confirmée…
Et on reset. Voilà, la nouvelle version est bien installée, le tout Over The Air ✈️ !
La plupart des manipulations réalisées précédemment se sont bien goupillées car la cible que nous utilisions a déjà été rendue compatible avec MCUboot. Ce n'est malheureusement pas toujours le cas. Cependant il est possible de partitionner la mémoire flash soi-même pour rendre notre cible compatible avec MCUboot, ce travail pourrait faire l'objet d'un futur article.
Conclusion
La sécurisation des dispositifs IoT est une nécessité dans notre monde de plus en plus connecté. Les solutions open source telles que Zephyr et MCUboot jouent un rôle crucial dans cette mission. Zephyr, en tant que système d'exploitation temps réel, fournit une base solide pour le développement d'applications embarquées sécurisées. MCUboot, de son côté, assure la sécurité des mises à jour logiciel, en s'assurant que seuls les firmwares authentifiés (signés) et intègres peuvent être installés sur notre dispositif IoT.
Ainsi, l'intégration de Zephyr et MCUboot dans des projets IoT permet de renforcer la sécurité à plusieurs niveaux : de la gestion des taches en temps réels à la vérification de l'authenticité des mises à jour. Cette combinaison offre une solution robuste pour protéger les dispositifs IoT.