14.3.4. Note sur la protection en lecture de la mémoire flash¶
À sa sortie d’usine, le micrologiciel d’une OpenMV cam livrée est lisible par quiconque dispose d’un accès physique à l’appareil. Un attaquant ayant la caméra en main peut connecter une sonde SWD au connecteur de débogage, dialoguer avec l’interface de débogage du MCU et vider la mémoire flash – qui contient chaque module Python figé et le contenu de la partition ROMFS. Le micrologiciel OpenMV standard n’active pas la protection en lecture de la mémoire flash par défaut.
Cette page le documente explicitement afin qu’une équipe qui commercialise un produit sache où se situe la responsabilité.
14.3.4.1. Ce que fait la caméra par défaut¶
Le programme d’amorçage et l’environnement d’exécution de la caméra n’activent aucune fonction de protection en lecture du MCU sous-jacent. L’interface de débogage reste ouverte, la mémoire flash reste lisible et la version compilée s’exécute comme elle le ferait sur l’établi d’un développeur. C’est le bon comportement par défaut pour le public du tutoriel – une caméra livrée avec la protection en lecture activée est une caméra qui ne peut pas être reflashée via l’IDE, qui ne peut pas être réimagée après un déploiement raté, et qui ne peut être récupérée que par l’équipe de compilation.
Le compromis change lorsque la caméra passe d”« appareil de développement » à « produit ». Un produit dont la valeur dépend de la confidentialité du code applicatif doit activer lui-même la protection ; le micrologiciel OpenMV ne le fait pas.
14.3.4.2. Ce que fait l’équipe produit¶
Chaque fabricant de MCU propose un mécanisme de protection en lecture. Les détails diffèrent – fusibles au niveau du bit, transitions de cycle de vie à usage unique, images flash signées – mais la forme commune est la suivante :
Un bit spécifique au fabricant (ou un ensemble de bits) est inscrit dans le silicium, généralement à l’aide d’un outil du fabricant qui dialogue une dernière fois avec le port de débogage du MCU.
Après l’inscription, le port de débogage refuse de lire la mémoire flash. La caméra démarre et exécute toujours l’application ; elle n’expose simplement plus son contenu à une sonde.
L’inscription est irréversible. Il n’existe aucun moyen de ramener la caméra à un état déboguable sans la détruire.
La configuration de ceci est spécifique au MCU, et les étapes dépendent du composant à protéger sur la caméra. Le manuel de référence du fabricant fait autorité ; le support du fabricant est le canal pour réussir l’opération sur une ligne de fabrication.
C’est la partie facile.
La partie difficile consiste à fermer chaque autre voie permettant à un attaquant d’exécuter du code sur la caméra ou de lire ce que fait l’application. La protection en lecture empêche seulement une sonde de débogage de vider la mémoire flash. La caméra doit encore fermer :
Le REPL MicroPython. Un REPL accessible via USB accepte du code Python arbitraire. La protection en lecture n’y change rien. Une session REPL peut lire la RAM, appeler des fonctions, exfiltrer tout ce que l’application en cours d’exécution peut voir – en somme, un REPL accessible contourne tout ce que la protection en lecture apporte. La désactivation de l’accès au REPL est une modification de la compilation du micrologiciel qui incombe à l’équipe produit.
Le téléversement de script depuis l’IDE. Le mécanisme « exécuter ce script sur la caméra » de l’IDE emprunte la même surface du protocole USB que le REPL. Fermer le REPL ferme aussi ce mécanisme ; laisser l’un ou l’autre ouvert laisse un canal d’exécution de code arbitraire vers la caméra.
Le détournement du point d’entrée depuis le système de fichiers. Déjà fermé lorsque l’application est livrée via Geler des scripts dans le micrologiciel – l’environnement d’exécution résout les
boot.pyetmain.pyfigés avant toute copie du système de fichiers, de sorte que rien de déposé sur la mémoire flash ou sur la carte SD ne peut les remplacer. Cette protection est gratuite une fois l’application intégrée à la compilation.La mémoire flash externe sur les caméras plus récentes. Les caméras qui stockent l’image applicative en mémoire flash externe placent cette image sur une puce bien visible sur le circuit imprimé ; la puce peut être dessoudée et lue directement avec des outils du commerce, ou lue sur place en sondant le bus. La protéger nécessite d’activer le matériel embarqué qui déchiffre le contenu de la mémoire flash lors des lectures, de générer la clé de chiffrement, de provisionner cette clé sur la caméra et de la graver irréversiblement dans le stockage programmable une fois du MCU. Chacune de ces étapes est une opération distincte à usage unique, et la moindre d’entre elles mal réalisée sur une unité de production rend cette unité inutilisable.
Chaque élément de cette liste représente sa propre pile de travail de compilation du micrologiciel, d’étapes de ligne de fabrication et d’inscriptions irréversibles. Un produit réellement verrouillé est une compilation de micrologiciel personnalisée, un programme d’amorçage personnalisé, un flux de fabrication qui provisionne des clés par unité, et un ensemble de tests qui prouvent que le verrou est effectivement fermé avant que l’unité ne quitte la ligne. C’est des mois de travail, pas des jours, et l’irréversibilité fait que les erreurs coûtent des unités.
Pourquoi le comportement par défaut est ouvert
Cette liste explique aussi pourquoi le micrologiciel OpenMV standard est livré sans protection en lecture activée. Une caméra dont le REPL est fermé, le téléversement de script depuis l’IDE désactivé et le micrologiciel verrouillé est une caméra sur laquelle on ne peut plus du tout développer – le flux de travail qui rend les OpenMV cam utilisables en premier lieu aurait tout simplement disparu. Le comportement par défaut laisse tout ouvert ; l’équipe produit choisit quels éléments fermer sur le chemin vers une unité livrée.
14.3.4.3. Ce que l’accès physique permet malgré tout¶
Même avec la protection en lecture activée, un attaquant qui détient la caméra peut faire pas mal de choses :
Rejouer le trafic réseau de la caméra en interceptant ses sorties.
Observer son comportement visible et déduire comment elle réagit aux entrées.
Dans certains cas, récupérer des secrets via des attaques par injection de fautes ou par canal auxiliaire spécialisées contre le MCU protégé.
La protection en lecture augmente le coût de l’accès au code source de l’application. Elle ne l’élimine pas. « Accès physique = compromission » est l’hypothèse de travail dont une revue de sécurité devrait partir ; le mécanisme de protection décide simplement combien cette compromission coûte en temps et en équipement.
14.3.4.4. Ce avec quoi le micrologiciel OpenMV est livré¶
Un récapitulatif, pour rester concret :
Aucune protection en lecture activée par défaut.
Aucun indicateur de compilation dans le micrologiciel standard qui l’active.
Aucune API au niveau de l’application à appeler depuis MicroPython.
Un produit qui a besoin de la protection est livré avec un micrologiciel personnalisé. Cette personnalisation réside dans le programme d’amorçage de la carte et dans le flux de fabrication, et se situe en dehors de la base de code OpenMV. Les équipes qui font cela pour la première fois devraient le planifier dans le calendrier de développement comme un élément de travail distinct, et non comme quelque chose à ajouter à la fin – l’irréversibilité rend l’option « ajouter plus tard » coûteuse.