Accueil Articles Un aperçu de la sécurité des microcontrôleurs

Un aperçu de la sécurité des microcontrôleurs

microcontrôleur

La sécurité devient de plus en plus importante pour les systèmes embarqués à mesure qu'ils évoluent d'applications autonomes à des applications connectées qui stockent, reçoivent et transmettent des données, se mettent à jour avec les derniers logiciels, surveillent à distance, etc. Ces exigences sont réparties même sur les plus petites implémentations, malgré des ressources de mémoire et une puissance de calcul limitées.

La plupart des développeurs embarqués peuvent percevoir tout cela comme trop complexe à utiliser, à commencer par les problèmes liés à la cryptographie. Mais en fait, les aspects liés à la sécurité englobent de nombreux aspects de l'architecture des puces et des logiciels qui doivent être spécifiquement conçus et fonctionner ensemble de manière transparente pour atteindre leurs objectifs. Cet article passe en revue les aspects les plus pertinents à prendre en compte en ce qui concerne les implémentations de sécurité des microcontrôleurs pour ces petits systèmes embarqués.

L'une des premières étapes pour garantir l'accès à un actif de valeur consiste à le rendre disponible dans le cadre d'une politique d'utilisation spécifique. Une telle politique pourrait, par exemple, restreindre la partie du logiciel de l'application qui peut l'utiliser et forcer son utilisation via une interface fonctionnelle définie qui ne peut être contournée, idéalement implémentée dans le matériel.

La technologie ARM TrustZone fournit un exemple d'une telle capacité d'isolation, permettant à l'application utilisateur d'être séparée en un environnement dit "sécurisé" et "non sécurisé" dans le contexte du CPU. Mais où la politique s'applique-t-elle? A une "étape" dédiée, avant qu'une transaction mémoire ne soit propagée au bus interne (nous en reparlerons plus tard). En cas de violation, une exception est levée, selon la figure 1 :

zone de confiance
Figure 1. Politique d'accès TrustZone.

L'application peut décider de manière réactive d'entreprendre une action appropriée, telle que le redémarrage d'un service, la journalisation de l'événement, le signalement d'un défaut, etc.

En regardant la figure 1, il est facile de voir que les logiciels non sécurisés ne peuvent accéder qu'aux ressources non sécurisées ; Comment les deux mondes peuvent-ils communiquer entre eux ? Heureusement, il existe un mécanisme pour le faire. Pour exécuter une fonction sécurisée, la CPU peut changer son état en sécurisé via une instruction spéciale appelée "passerelle sécurisée" (SG). Une instruction SG est combinée avec un branchement immédiatement après (c'est-à-dire un "saut") vers l'adresse de fonction sûre souhaitée. Lorsque la fonction de sécurité revient, l'état du processeur repasse en mode non sécurisé.

La figure 2 fournit un exemple d'allocation de ressources entre un environnement sécurisé et non sécurisé :

appel de fonction non sécurisé
Figure 2. Appels de fonction non sécurisés.

Les paires 'SG + adresse' sont affectées à une zone spéciale définie comme appelable non sécurisée ; Tous les paramètres tels que les pointeurs de mémoire passés par des fonctions appelables non sécurisées peuvent utiliser une instruction "cible de test" spécialisée pour s'assurer qu'un tampon mémoire se trouve dans une mémoire non sécurisée et ne chevauche pas la mémoire sécurisée, afin d'éviter les fuites de données.

En mode sans échec, il peut être nécessaire de rappeler une fonction non sécurisée, par exemple, pour informer la fonction appelante de l'état de la demande, émettre des notifications liées au RTOS, etc. Le compilateur générera l'instruction de branche spéciale qui change l'état en non sécurisé avant l'appel et envoie l'adresse de retour à la pile sécurisée.

Les systèmes embarqués sont fortement pilotés par les interruptions ; lorsqu'une interruption non sécurisée se produit alors que la CPU est en mode sans échec, les registres sont empilés sur la pile sécurisée par défaut et leur contenu est automatiquement effacé. Ceci afin d'empêcher la fuite involontaire d'informations de la zone sécurisée. Le partitionnement des exceptions au sein de chaque environnement est pris en charge via une table de vecteurs d'interruption dédiée à chacun. De même, il existe une implémentation distincte des pointeurs de pile, des minuteries système, etc.

Tout cela a l'air génial, mais comment définissez-vous ces zones et limites de mémoire sûres ? Deux unités sont interrogées en parallèle : la SAU (Security Allocation Unit) et l'IDAU (Implementation Defined Allocation Unit). A chaque accès au CPU, les deux répondront avec l'attribut de sécurité associé à cette adresse. Votre réponse combinée définit l'attribut d'adresse final, le plus restrictif des deux "gagnants" (une région sécurisée ne peut pas être "écrasée" par un attribut moins sécurisé). Enfin, le résultat est évalué par rapport à la politique définie comme dans le tableau 1. Si l'accès est légitime, vous pouvez continuer ; sinon, il est bloqué et une exception sûre est levée.

Notamment, la configuration du SAU (combien de régions sont prises en charge, paramètres par défaut, etc.) peut être définie au moment de la conception, et la mise en œuvre de l'IDAU est définie, c'est-à-dire laissée au fabricant de l'appareil.

Les unités de protection de la mémoire (MPU) de chaque domaine protégeront les threads individuels les uns des autres, améliorant ainsi la robustesse globale du logiciel. La figure 3 montre un exemple de partition sur un microcontrôleur compatible TrustZone :

mpu zone de confiance
Figure 3. TrustZone et partition MPU.

Avons-nous atteint des objectifs liés à la sécurité jusqu'à présent ? En fait, pas encore. TrustZone peut isoler en toute sécurité les threads non sécurisés de votre application, mais il ne fournit aucune "sécurité" en soi et ne peut pas imposer un accès légitime ; il empêche plutôt une utilisation indésirable ou un accès direct.

Le développeur doit décider quelles parties de l'application seront isolées ; TustZone peut être utile et ne peut pas être contourné dans un logiciel (par rapport à un MPU classique), donc les routines liées aux opérations cryptographiques sont un bon candidat. Dans les deux cas, le système appliquera les paramètres de TrustZone dès le début de l'exécution et évitera de toucher à ces limites (par exemple, en les stockant dans une zone mémoire que le CPU ne peut pas modifier directement).

Les bonnes pratiques suggèrent de réduire au minimum la quantité de fonctionnalités mises en œuvre dans l'environnement sécurisé. Cela réduit la possibilité de bogues, d'erreurs d'exécution et d'exploitation malveillante de tout défaut logiciel. Comme effet secondaire, la validation des fonctionnalités devient beaucoup plus légère lors du débogage et des tests.

Quelles ressources cryptographiques doivent être fournies par un MCU ? Cela dépend de la complexité de l'application; pour une solution d'entrée de gamme, une routine purement logicielle peut suffire. Mais la prise en charge matérielle des algorithmes cryptographiques réduit la consommation d'énergie et la taille du code, à une vitesse d'exécution plus élevée.

Cela étant dit, le premier bloc de construction de la plupart des protocoles cryptographiques est un TRNG (véritable générateur de nombres aléatoires), qui doit être validé et testé pour ses propriétés d'entropie et sa qualité d'aléatoire (puisqu'un RNG mal construit peut gâcher la sécurité de tout algorithme ). utilise le).

Pour le stockage local, la prise en charge d'algorithmes symétriques comme AES avec plusieurs modes de fonctionnement est presque obligatoire pour chiffrer et déchiffrer la plupart des données. En combinaison avec des algorithmes de hachage ("sommes de contrôle cryptographiquement sécurisées") tels que SHA-2 ou SHA-3, l'application peut effectuer de simples contrôles d'authentification et vérifier que le contenu des données n'a pas été modifié.

Pour une connectivité avancée, des algorithmes de chiffrement asymétriques tels que RSA ou ECC peuvent prendre en charge la vérification d'identité sur les connexions client/serveur, aider à obtenir des clés de session éphémères ou vérifier l'origine et la légitimité d'une mise à jour du micrologiciel. De tels accélérateurs pourront également générer des clés sur la puce, pour une utilisation locale.

Mais le problème vraiment difficile est la gestion des clés, car les clés doivent être gardées confidentielles, entières et disponibles. De nombreux scénarios doivent être envisagés : quand la clé est injectée (stockée) dans le MCU, comment la transporter, comment la charger dans le matériel cryptographique et comment la protéger des fuites.

Idéalement, l'application ne traitera jamais le matériel clé en format clair, pour éviter une exposition dangereuse. Un moyen simple de contourner ce problème consiste à le gérer dans la zone sécurisée de la TrustZone, mais le mieux est dans un sous-système isolé dédié sur la puce. Une fois que les clés sont stockées dans une mémoire non volatile, des techniques telles que le "wrapping" de clé (chiffrement de clé) aident à protéger la confidentialité. Le fait de rendre les données compressées uniques à chaque microcontrôleur atténue davantage les principaux risques de fuite et élimine les menaces de clonage. Pour un tel mécanisme, une "racine de confiance" pour le stockage est nécessaire, sous la forme d'une "clé de chiffrement de clé" unique pour chaque MCU, pour garantir qu'aucun appareil spécifique n'est compromis et permettre une attaque de "classe" sur toutes les unités similaires .

Les attaques DPA et SPA enregistrent et analysent les traces de consommation d'énergie pour rétroconcevoir la valeur clé. Celles-ci deviennent moins chères et plus rapides à mettre en œuvre, même pour les attaquants peu qualifiés avec des ressources limitées. Si l'accès physique à l'appareil est un problème, sans autre moyen de contrôle d'accès dans le système, des contre-mesures contre ces menaces sont nécessaires dans les moteurs de chiffrement. En outre, toute surveillance des signaux connectés au boîtier de l'équipement, qui peut notifier le MCU et éventuellement prendre un horodatage de l'événement de sabotage, sera hautement souhaitable.

Le sous-système isolé permettra à un utilisateur de fournir les clés choisies sur l'appareil et de les faire emballer et stocker en toute sécurité, prêtes pour une utilisation ultérieure de l'application. Le MCU doit prendre en charge une interface pour ce faire à la fois sur le terrain et en usine, permettant une production initiale facile et une mise à niveau ultérieure sur le terrain. Ces passages doivent être sécurisés et n'exposer aucun contenu clé pendant le transit.

moteur de chiffrement sécurisé
Figure 4. Moteur de chiffrement sécurisé

Dans les microcontrôleurs modernes, d'autres entités fonctionnelles peuvent transférer de manière autonome des données vers et depuis la mémoire ou les périphériques, afin d'améliorer les performances et d'utiliser efficacement la bande passante disponible. Quelques exemples sont les moteurs DMA, les pilotes graphiques, les pilotes Ethernet, etc. Il est d'une importance vitale que le MCU puisse définir les attributs de sécurité de ces agents et implémenter des "filtres d'accès" spécifiques sur les points de communication, tels que les mémoires et les périphériques mappés en mémoire.

Tout processeur est inutile sans capacité d'entrée et de sortie de signal. La protection de ces interfaces contre une mauvaise utilisation est une exigence fondamentale pour empêcher toute altération, car c'est la manière naturelle d'interagir avec le MCU. Le concepteur prudent doit vérifier que le microcontrôleur peut restreindre l'accès aux ports d'E/S et aux périphériques sécurisés, empêchant ainsi les logiciels de « prendre le relais », d'interférer ou d'espionner de manière malveillante les communications, tout en isolant les ports et les périphériques les uns des autres.

Pendant le développement, pour tester le logiciel, un débogueur basé sur Jtag est presque obligatoire. Une telle interface peut accéder à la plupart des ressources sur puce et constitue donc une porte dérobée critique pour toute application déployée sur le terrain. Les cas d'utilisation de la sécurisation de Jtag sont très différents : bloquez-le de manière permanente ou maintenez la capacité de débogage sur le terrain, pour protéger l'accès. Quelle que soit la stratégie choisie, la protection ne permettra pas de la contourner, en imposant une autorisation appropriée via une clé d'authentification et en n'accordant l'accès qu'après avoir terminé avec succès un protocole de défi-réponse. Enfin, l'appareil doit prendre en charge et sécuriser le mécanisme de retour de l'appareil à l'usine en cas d'analyse de défaut, en effaçant éventuellement tout actif secret stocké tout en gardant l'interface sécurisée jusqu'à sa destination.

L'image finale de l'application, une fois déployée sur le terrain, peut devoir être rendue immuable en partie, pour s'assurer qu'elle est dans un état connu à tout moment. Pour prendre en charge cette exigence, le microcontrôleur doit avoir la capacité de protéger en permanence les portions de mémoire non volatile définies par l'utilisateur contre toute modification.

Enfin et surtout, chaque microcontrôleur subit un long processus de test avant expédition ; bon nombre de ces résultats de test (valeurs de réglage, données spécifiques à la production, etc.) et d'autres paramètres sont stockés sur l'appareil. Ce mode de test spécial, bien que non significatif pour un utilisateur final, peut accéder, contrôler et potentiellement modifier toutes les ressources de la puce. Le fabricant doit s'assurer qu'une telle porte dérobée potentielle ne peut pas être ouverte par malveillance ou par erreur une fois que l'appareil quitte l'usine et se trouve entre les mains du client.

La recherche d'un microcontrôleur qui prend en charge les exigences ci-dessus peut être une tâche ardue. Heureusement, Renesas a conçu la série RA de microcontrôleurs avec exactement ces objectifs. Les séries RA6 et RA4 incluent des appareils avec un processeur ARM Cortex-M33 avec TrustZone et des MPU sécurisés. Ils permettent de programmer facilement et simplement des limites de sécurité pour tous les types de mémoire embarquée. Ils intègrent Secure Crypto Engine, un sous-système cryptographique (Figure 4) qui fournit une fonctionnalité d'élément sécurisé avec des performances plus élevées et un coût de matériel inférieur. Le SCE comprend des accélérateurs cryptographiques de pointe, un TRNG, prend en charge la génération de clés, l'injection de clés met en œuvre des contre-mesures SPA/DPA et une clé matérielle unique en tant que racine de confiance. Ses contrôleurs DMA, maîtres de bus, périphériques, ports d'E/S ont des attributs de sécurité dédiés et une fonctionnalité de détection de sabotage est implémentée. La gestion intégrée du cycle de vie des appareils gère le débogage sécurisé/non sécurisé, la planification, prend en charge les procédures de retour de matériel et le mode de test sécurisé. Les mémoires non volatiles peuvent être bloquées en permanence au choix de l'utilisateur. Pour plus d'informations sur les fonctionnalités de sécurité de la famille RA, visitez le site Web de Renesas.

Auteur : Giancarlo Parodi, ingénieur principal, Renesas Electronics