Sur Secure Code Warrior, nous cherchons toujours à étendre notre couverture de formation. Pour permettre aux développeurs de systèmes embarqués et aux responsables de la sécurité de construire des systèmes embarqués sûrs, nous nous appuyons sur le monde de la sécurité des systèmes embarqués. Dans ce billet, nous partagerons les éléments clés que les développeurs et les architectes doivent connaître pour construire des systèmes embarqués sécurisés.
Un dispositif embarqué est une unité informatique indépendante, dotée de son propre matériel et logiciel à base de microprocesseur. Ils sont généralement utilisés pour exécuter des fonctions spécifiques, soit de manière indépendante, soit en tant que parties de systèmes plus importants.
Qu'est-ce qu'un dispositif et un système embarqués ?
Les dispositifs intégrés sont des systèmes informatiques conçus à cet effet, dotés d'un matériel et d'un logiciel minimalistes, programmés pour exécuter des fonctions spécifiques. La complexité des dispositifs embarqués varie en fonction de leur objectif.
Si un système embarqué doit effectuer des opérations compliquées et gourmandes en ressources, son matériel peut comprendre plusieurs processeurs, avec divers périphériques interconnectés. En revanche, s'il est conçu pour effectuer une tâche simple, il peut ne contenir qu'un seul microcontrôleur.
Certains systèmes embarqués sont des boîtes noires sans interface utilisateur, tandis que d'autres peuvent être dotés d'interfaces utilisateur graphiques détaillées.
Exemples de dispositifs embarqués
Les dispositifs intégrés trouvent des applications dans de nombreux secteurs, de l'aérospatiale à l'informatique, en passant par les appareils ménagers et les soins de santé. En voici quelques exemples :
- Un thermostat dans un climatiseur.
- Un tracker de fitness, avec de petits composants électriques fonctionnant avec un minuscule système d'exploitation, qui ne peut rien faire de plus que d'enregistrer et de synchroniser vos statistiques de santé.
- Systèmes numériques de contrôle de la température.
- Systèmes de navigation à l'intérieur d'un avion.
- Montres numériques.
- Dispositifs GPS.
- Composants Wi-Fi dans les fours à micro-ondes et autres appareils électroniques grand public.
- Moniteurs de tension artérielle et de rythme cardiaque.
- Composant de mise en réseau d'un appareil d'IRM qui envoie des données au nuage.
Un ordinateur portable est-il un dispositif embarqué ?
Réponse courte : Réponse longue :
Par définition, un dispositif embarqué encapsule tous les logiciels et le matériel dont il a besoin pour remplir ses fonctions. Un ordinateur portable renferme en effet divers composants matériels dans un boîtier métallique et englobe tous les logiciels dont il a besoin pour offrir son ensemble de fonctionnalités.
Cependant, contrairement aux systèmes intégrés typiques, qui ont un ensemble de fonctions minimal et prédéfini, un ordinateur portable est plus polyvalent et peut être utilisé pour un large éventail d'activités.
Dispositifs intégrés dans l'internet des objets
Les systèmes intégrés sont au cœur de l'IdO. Votre réfrigérateur intelligent peut être contrôlé par votre appareil mobile grâce à un dispositif intégré. C'est un dispositif intégré à votre système de sécurité qui vous permet de visionner des images de vidéosurveillance à des milliers de kilomètres de distance. Et lorsque vous appuyez sur un bouton pour mettre votre voiture en pilote automatique, en coulisses, c'est un dispositif intégré qui fait toute la magie.
Cycle de développement des logiciels embarqués
Le cycle de développement d'un logiciel typique pour un appareil embarqué comprend les étapes suivantes :
Étape 1 : Objectif et exigences
Un dispositif embarqué possède un ensemble de fonctionnalités distinctes et précises. C'est pourquoi il est très important d'énoncer explicitement son objectif et ses exigences avant de commencer le développement. Il est recommandé de créer un document de conception détaillé pour le système. Répondez à des questions telles que :
- Quelles sont les fonctions de l'appareil ?
- Sera-t-il intégré à une autre machine ou fonctionnera-t-il de manière autonome ?
- L'appareil doit-il être doté d'une interface utilisateur ? Si oui, une ligne de commande suffit-elle ou une interface graphique est-elle nécessaire ?
- Quelles sont les limites de taille, de coût ou de consommation d'énergie que l'appareil doit respecter ?
- Existe-t-il des critères de performance ? Par exemple, le dispositif doit-il réagir en temps réel ou dans certaines limites ?
Étape 2 : Architecture du système
Une fois que nous avons identifié les exigences uniques du système, nous sommes prêts à concevoir l'architecture du système. Répondez à des questions telles que :
- Quels sont les composants matériels nécessaires au développement de l'appareil ? Il s'agit d'identifier les circuits, les puces de processeur et les microcontrôleurs, ainsi que tous les périphériques internes et externes nécessaires.
- Quelle est la puissance nécessaire aux composants ?
- L'appareil sera-t-il connecté à l'internet ?
- Quelles interfaces doivent être ajoutées/développées pour permettre à l'appareil de se connecter à d'autres appareils ou à la machine dans son ensemble ?
- Comment allez-vous mettre en œuvre le cryptage ? (pensez aux algorithmes, au stockage des clés, etc.)
- Comment allez-vous identifier et éviter les vulnérabilités potentielles, les exploits et les logiciels malveillants ?
Étape 3 : Sélectionnez le système d'exploitation
Le choix du système d'exploitation détermine souvent l'efficacité de vos applications embarquées. Windows pour l'IdO peut obtenir de bons résultats en matière de graphisme, mais il ne prend pas en charge le matériel. Linux embarqué et Android sont gratuits, tandis que VxWorks et Windows pour l'IdO ont des coûts de licence.
Avec les systèmes à code source ouvert comme Linux et Android, vos développeurs ont plus de contrôle sur le noyau. En revanche, avec les systèmes propriétaires, l'ensemble des fonctionnalités par défaut du noyau est tout ce avec quoi vous pouvez travailler.
Il est également important de prendre en compte les implications en matière de sécurité lors du choix d'un système d'exploitation. Les correctifs de sécurité sont-ils publiés rapidement, au cas où des vulnérabilités seraient découvertes ? Existe-t-il une protection intégrée contre les attaques de cybersécurité les plus courantes ?
Étape 4 : Les outils de développement
Les différents langages et cadres de programmation présentent des avantages et des inconvénients. En fonction de vos exigences en matière de fonctionnalités, de vitesse et de fiabilité, vous pouvez choisir un langage ou un cadre plutôt qu'un autre.
Si votre application est basée sur le web et que vous souhaitez des performances élevées, optez pour Java.
En revanche, si vous souhaitez obtenir le débit le plus rapide, optez pour C/C++. Si vous souhaitez bénéficier de la meilleure prise en charge des bibliothèques tierces, optez pour Python.
Étape 5 : Coder, remanier, tester, coder encore
Une fois que vous avez choisi la plate-forme de développement, vous êtes prêt à commencer à coder. N'oubliez pas que les systèmes embarqués sont des dispositifs sensibles dont les ressources matérielles et logicielles sont limitées. Il est donc essentiel de garder à l'esprit les meilleures pratiques en matière de sécurité et de performance des applications.
Les revues de code permettent d'optimiser le code et d'identifier les bogues potentiels. Vous devez également procéder à des tests aussi rigoureux que possible. Veillez à dresser une liste exhaustive de tous les cas de test que le dispositif peut rencontrer lorsqu'il est utilisé en production.
Étape 6 : Maintenance et soutien
Comme pour toute autre application/appareil, le cycle de vie ne se termine pas lorsque l'appareil embarqué a été livré et installé. Au fur et à mesure que l'appareil est utilisé en production, de nouveaux cas d'utilisation sont identifiés, ce qui nécessite l'ajout de nouvelles fonctionnalités. Les bogues signalés peuvent également nécessiter la publication de nouvelles mises à jour du micrologiciel.
Principaux langages de programmation embarqués
De nombreuses organisations réputées, telles que l'IEEE et la TIOBE, classent les langages de programmation en fonction de leur popularité et de leur utilisation. Cependant, que vous consultiez l'index TIOBE ou le Spectre IEEE, vous remarquerez un thème commun.
Les trois premiers langages sont toujours C, Python et Java. L'indice TIOBE de juillet 2021 classe le C en première position, Java en deuxième position et Python en troisième position. Selon le classement de IEEE Spectrum pour les langages de programmation embarqués, l'ordre est le suivant : Python, Java, puis C.
Quelles sont les différences entre les microprogrammes écrits en Java, en C ou en Python ?
Les différents langages gèrent la mémoire, les interactions avec le système d'exploitation et le temps d'exécution de différentes manières. Par exemple, les applications Java s'exécutent dans un environnement d'exécution spécialisé connu sous le nom de machine virtuelle Java (JVM).
La gestion de la mémoire en C/C++ est manuelle, mais en Java ou en Python, vous n'avez pas à vous préoccuper de la gestion de la mémoire, le langage le fait pour vous. De plus, en C, vous devez collecter vous-même vos déchets, c'est-à-dire que si vous allouez dynamiquement une partie de la mémoire, vous devez la libérer explicitement. Si vous ne le faites pas, cela entraînera une fuite de mémoire. En Java ou en Python, le ramassage des ordures se fait automatiquement. Cependant, le langage C est intrinsèquement beaucoup plus rapide que Java ou Python.
Une chose qui manque à C et Java (mais surtout à C) par rapport à Python est la disponibilité de bibliothèques tierces. Python dispose d'une base de données de bibliothèques plus riche, ce qui permet aux développeurs d'ajouter plus facilement certaines fonctionnalités.
Dans l'ensemble, choisissez C si :
- Vous souhaitez une interface de bas niveau avec le système d'exploitation et le matériel.
- Vous souhaitez obtenir les meilleures performances possibles.
- Vos développeurs sont compétents en C/C++.
- Vous n'avez pas besoin d'un soutien trop important de la part d'un tiers ou de l'extérieur.
Utilisez Python si :
- Vous souhaitez mettre en œuvre des algorithmes de science des données ou d'apprentissage automatique.
- Vous voulez un support riche en bibliothèques tierces.
- Vous êtes prêt à sacrifier la vitesse à la facilité d'utilisation.
- Vous avez une expérience limitée en matière de développement embarqué.
- Vous n'avez pas besoin d'une interface de bas niveau avec le système d'exploitation ou le matériel.
Optez pour Java si :
- Vous créez des applications web.
- Vous souhaitez une plus grande facilité de développement que le C, mais vous voulez plus de performance que Python.
- Vous n'avez pas besoin d'un soutien trop important de la part d'un tiers ou de l'extérieur.
Le langage C cessera-t-il lentement d'être un choix de premier ordre pour le développement embarqué ?
Les langages de haut niveau facilitent le codage en faisant abstraction des complexités qui ne peuvent tout simplement pas être évitées en C. Cependant, pendant des décennies, malgré l'apparition de langages et de cadres plus sophistiqués, le C est resté un choix de premier ordre pour le développement embarqué.
En effet, la vitesse, les performances et la fiabilité qu'il offre sont encore inégalées. Le fait que Python et une grande partie de l'écosystème Java (y compris le moteur d'exécution, le langage et le compilateur) soient écrits en C en dit long sur l'efficacité et la durabilité du langage.
Cela dit, le C est indéniablement plus difficile à apprendre pour les nouveaux développeurs, qui préfèrent la simplicité de langages comme Python. Cela entraîne une diminution sensible de la taille de la communauté des développeurs C. L'augmentation du développement d'applications d'IA et de ML pousse également les gens à choisir Python plutôt que C, simplement parce qu'il offre un plus grand support de bibliothèque.
Il est important de se rappeler que Python n'est entré que récemment dans le débat sur les principaux langages de programmation embarqués . Oui, son adoption peut continuer à augmenter dans les années à venir, mais nous ne nous attendons pas à ce que le langage C cesse jamais d'être un choix de premier plan pour le développement embarqué.
Pourquoi le codage sécurisé est-il important en C/C++ ?
Beaucoup de choses peuvent mal tourner lorsque vous écrivez du code en C/C++. L'accès à une adresse mémoire qui ne pointe plus vers des données valides, ou le partage incorrect de données entre les fils d'exécution, peuvent entraîner le plantage de toute votre application.
Pour les dispositifs intégrés, ces implications sont bien plus importantes, car un accident à l'intérieur de ces dispositifs peut entraîner l'arrêt du fonctionnement d'une machine beaucoup plus grande. Par exemple, si le module de pilotage automatique d'une voiture s'arrête, la voiture ne sera plus en mesure d'éviter les obstacles.
Voici d'autres raisons pour lesquelles le codage sécurisé des applications C/C++ est si important :
- Une gestion non sécurisée de la mémoire (pointeurs nuls, corruption de la mémoire, débordements de la pile, débordements de la mémoire tampon et du tas) entraîne le plantage de l'application entière.
- Les pointeurs font partie intégrante des langages C et C++. Leur manipulation nécessite une grande attention et une connaissance approfondie des concepts sous-jacents.
- Le ramassage des ordures est manuel. Il est donc obligatoire pour les programmeurs de supprimer explicitement toute mémoire allouée dynamiquement. Une mémoire non libérée ou incorrectement libérée peut entraîner des fuites ou une corruption de la mémoire.
- Il n'existe pas d'API normalisées pour les structures de données avancées (tables de hachage, ensembles, etc.), ce qui oblige les développeurs à réinventer la roue.
Il est absolument essentiel que les développeurs soient formés au codage sécurisé pour les applications C/C++. Secure Code Warrior propose un site personnalisé learning platform avec des défis interactifs, courses, et des évaluations qui peuvent permettre aux développeurs d'écrire du code C/C++ sécurisé. Il s'agit ici d'un contenu spécifique à la langue et au cadre, et non d'une simple adaptation de la formation conceptuelle générale.
Découvrez comment nous aidons les industries de l'automobile et du transport. Ou essayez dès aujourd'hui un défi de codage axé sur l'embarqué pour découvrir comment nous permettons aux développeurs d'écrire des applications embarquées sécurisées!