Brevet FR2895814A1 — publié le 20070706

PROCÉDÉ DE SÉCURISATION DE L'EXÉCUTION D'UN PROGRAMME D'ORDINATEUR La présente invention concerne le domaine de la sécurisation de l'exécution des programmes d'ordinateur, notamment dans le cadre des cartes à puce, et a plus particulièrement pour objet un procédé de sécurisation de l'exécution d'un tel programme comportant des instructions de branchement insérées dans un flux d'instructions neutres à exécuter les unes à la suite des autres. On sait que les cartes à puce font l'objet de nombreuses tentatives de piratage, notamment par des attaques actives au cours desquelles le pirate potentiel perturbe physiquement le circuit intégré de la puce en vue de modifier le comportement de cette dernière et de dérouter le code logiciel vers un autre type d'exécution. Pour faire échec à ces tentatives, il est bien connu, dans un produit comprenant d'une manière plus générale un ou plusieurs composants électroniques et un logiciel embarqué, d'utiliser des contrôles d'intégrité sur les données et/ou de la redondance de code afin de détecter d'éventuelles perturbations involontaires (spatial) ou volontaire (hacker). Il s'avère toutefois que ces moyens de détection ne sont pas toujours suffisants pour détecter une erreur de séquencement du code : déroutement ou bien encore omission d'une instruction de branchement/saut/retour. La détection de ce type de faute au moyen de mécanismes logiciels est complexe et coûteuse (en termes de performance) à mettre en oeuvre. En effet, le logiciel doit en permanence conserver dans une ou plusieurs variable(s) temporaire(s) une valeur correspondant à l'état dans lequel il se trouve (machine d'état) et vérifier aux moments opportuns qu'il y a bien cohérence entre l'état dans lequel il se trouve et l'état dans lequel il devrait être. La présente invention a pour objet de s'affranchir de cette gestion fastidieuse et pénalisante au niveau logiciel en l'intégrant directement dans l'architecture matérielle (hardware) du composant à protéger. On sait qu'une unité centrale de traitement CPU (central processing unit) a pour mission, dans un composant électronique de type microprocesseur, de décoder et exécuter une à une les instructions qui composent le logiciel (software). Elle est donc au coeur du séquencement du code et, par là même, la mieux placée pour effectuer la vérification de cohérence d'état pour peu que, selon l'invention, on en modifie légèrement le fonctionnement. On rappelle que la CPU lit à l'adresse pointée par le pointeur de programme (PC : program counter), le code opération de l'instruction à exécuter ainsi que les éventuels opérandes associés à cette instruction. On distinguera dans ce qui suit les instructions neutres (qui n'impliquent pas de rupture du programme) des instructions de branchement (qui impliquent une mise à jour du pointeur de programme avec un décalage ou une valeur immédiate). On peut noter, à titre d'exemples d'instructions neutres : les instructions arithmétiques et logiques (ORL, AND ...) ; - les instructions de lecture/écriture en mémoire ou dans des registres (MOV, LD, ...) ; et à titre d'exemple d'instructions de branchements : - les branchements conditionnels ou non (BEQ, BRA ...) ; - les sauts (JMP) ; les sauts dans une sous-routine (JSR) ; les retours de sous-routine (RTS). Afin de pallier les inconvénients mentionnés ci-dessus, l'invention a tout d'abord pour objet un procédé de sécurisation de l'exécution d'un programme d'ordinateur comportant des instructions de branchement insérées dans un flux d'instructions neutres à exécuter les unes à la suite des autres, ledit procédé comprenant les étapes consistant à : - enregistrer dans une mémoire, préalablement à l'exécution dudit programme, respectivement préalablement à l'exécution d'une instruction particulière dudit programme, le nombre d'instructions neutres à exécuter entre chaque instruction de branchement, respectivement entre ladite instruction de branchement particulière et l'instruction de branchement qui la précède ; - lors de l'exécution du programme • lors de l'exécution de chaque instruction neutre o incrémenter un compteur d'instructions ; • et au moins lors de l'exécution de chaque instruction de branchement o lire le contenu dudit compteur d'instructions ; o comparer le contenu dudit compteur d'instructions au nombre enregistré dans ladite mémoire, d'instructions neutres censées avoir été exécutées depuis l'instruction de branchement précédente ; et -si le contenu dudit compteur d'instructions est égal au nombre d'instructions neutres enregistré, initialiser ledit compteur et poursuivre l'exécution dudit programme ; -si le contenu dudit compteur d'instructions n'est pas égal au nombre d'instructions neutres enregistré, générer une interruption. On comprend que ce procédé puisse sécuriser l'exécution du programme contre les tentatives de déroutement. On suppose en effet qu'une perturbation déroute le programme en perturbant par exemple l'adresse d'un branchement. Le compteur d'instructions sera remis à zéro puis le programme sautera à une adresse ADDR quelconque. Si ADDR correspond à une instruction neutre dans une zone de code linéaire, alors, lorsque le programme atteindra l'instruction de branchement suivante, le contenu du compteur sera égal au nombre d'instructions neutres exécutées depuis ADDR et donc nécessairement différent du nombre correspondant préalablement enregistré, et le déroutement sera détecté. On observe que l'enregistrement en mémoire des nombres d'instructions neutres peut s'effectuer soit avant l'exécution du programme pour toutes les instructions de branchement, soit au fur et à mesure de cette exécution lors du passage de chaque instruction de branchement particulière. Par ailleurs, on entend généralement par interruption non seulement une interruption proprement dite de l'exécution du programme, mais également toute mise en état d'alerte. L'invention a également pour objet un programme d'ordinateur pour la sécurisation d'un programme d'application comportant des instructions de branchement insérées dans un flux d'instructions neutres à exécuter les unes à la suite des autres, ce programme étant agencé pour : - lire les instructions dudit programme d'application ; - détecter les instructions de branchement ; - lors de la détection d'une instruction de branchement déterminée • compter le nombre d'instructions neutres à exécuter depuis l'instruction de branchement précédente ; • insérer ledit nombre d'instructions neutres en tant que paramètre de ladite instruction de branchement déterminée. Ce programme peut notamment constituer un compilateur ou un interpréteur selon le langage utilisé pour le programme d'application. Dans un mode de réalisation particulier, ce programme peut en outre être agencé pour, lors de la détection d'une instruction de branchement déterminée, insérer des instructions consistant à : o lire le contenu d'un compteur d'instructions susceptible d'être incrémenté lors de l'exécution de chaque instruction neutre ; o comparer ledit nombre d'instructions neutres au contenu dudit compteur d'instructions ; et - en cas d'égalité entre ledit nombre d'instructions neutres 15 et le contenu dudit compteur, initialiser ledit compteur et exécuter ledit branchement ; - en cas d'inégalité entre ledit nombre d'instructions neutres et le contenu dudit compteur, générer une interruption. 20 On observera que, lorsqu'un programme d'application est ainsi sécurisé lors de sa compilation ou de son interprétation, la mémoire d'enregistrement des nombres d'instructions neutres dont il est question ci-dessus n'est autre alors qu'une partie de la mémoire 25 dans laquelle sont stockées les instructions de ce programme d'application, puisque ces nombres d'instructions apparaissent comme des paramètres des instructions de branchement. Par ailleurs, les instructions consistant à lire le contenu du 30 compteur d'instructions, à comparer ce contenu au nombre d'instructions neutres, à initialiser le compteur, et à générer une interruption peuvent être effectivement insérées dans le programme d'application modifié, ou être réalisées matériellement au niveau de l'unité centrale sur laquelle s'exécute le programme modifié. Dans un mode de mise en oeuvre particulier, ledit programme de sécurisation est agencé pour : - détecter les labels associés à des instructions de branchement ; D lors de la détection d'un tel label, • compter le nombre d'instructions neutres à exécuter depuis l'instruction de branchement précédente ou le label précédent ; • insérer, en amont dudit label, une instruction de contrôle comportant ledit nombre d'instructions neutres en tant que paramètre. Plus particulièrement, le programme de sécurisation peut être agencé pour, lors de la détection d'un tel label, insérer des instructions consistant à : o lire le contenu dudit compteur d'instructions ; o comparer ledit nombre d'instructions neutres au contenu dudit compteur d'instructions ; et en cas d'égalité entre ledit nombre d'instructions neutres et le contenu dudit compteur, initialiser ledit compteur et passer à l'instruction suivante ; - en cas d'inégalité entre ledit nombre d'instructions neutres et le contenu dudit compteur, générer une interruption. L'instruction de contrôle est donc ajoutée juste avant un label correspondant à une instruction de branchement de manière à tenir compte du fait que le programme peut entrer dans le flux 30 d'instructions neutres au niveau du label et non pas au niveau de l'instruction de branchement précédente. Cette instruction de contrôle est gérée par l'unité de traitement comme une instruction de branchement en comparant le contenu de la mémoire du nombre d'instructions neutres au compteur d'instructions. 25 L'invention a également pour objet un programme d'ordinateur sécurisé, comportant des instructions de branchement insérées dans un flux d'instructions neutres à exécuter les unes à la suite des autres, dans lequel lesdites instructions de branchement comprennent, en tant que paramètre, le nombre d'instructions neutres à exécuter depuis l'instruction de branchement précédente. Dans un mode de réalisation particulier, ledit programme sécurisé comprend en outre des instructions consistant, au moins lors de l'exécution de chaque instruction de branchement, à : • lire le contenu d'un compteur d'instructions susceptible d'être incrémenté lors de l'exécution de chaque instruction neutre ; • comparer le contenu dudit compteur d'instructions audit paramètre ; et o si le contenu dudit compteur d'instructions est égal audit paramètre, initialiser ledit compteur et poursuivre l'exécution dudit programme ; o si le contenu dudit compteur d'instructions n'est pas égal audit paramètre, générer une interruption. Également dans un mode de réalisation particulier, ledit programme d'ordinateur comporte des labels associés à des instructions de branchement, et comporte en outre, en amont desdits labels une instruction de contrôle comportant, en tant que paramètre, le nombre d'instructions neutres à exécuter depuis l'instruction de branchement précédente ou le label précédent. Plus particulièrement, ledit programme d'ordinateur peut comporter en outre, en amont desdits labels, des instructions consistant à : o lire le contenu dudit compteur d'instructions ; o comparer ledit nombre d'instructions neutres au contenu dudit compteur d'instructions ; et - en cas d'égalité entre ledit nombre d'instructions neutres et le contenu dudit compteur, initialiser ledit compteur et passer à l'instruction suivante ; - en cas d'inégalité entre ledit nombre d'instructions neutres et le contenu dudit compteur, générer une interruption. L'invention a également pour objet une unité de traitement informatique comprenant des moyens pour exécuter un programme d'ordinateur comportant des instructions de branchement insérées dans un flux d'instructions neutres à exécuter les unes à la suite des autres, respectivement des labels associés à des instructions de branchement, dans laquelle lesdits moyens comprennent : > une mémoire susceptible de contenir le nombre d'instructions neutres à exécuter entre chaque instruction de branchement, respectivement entre chaque label et l'instruction de branchement ou le label précédent, lors de l'exécution dudit programme ; > un compteur d'instructions susceptible d'être incrémenté lors de l'exécution de chaque instruction neutre dudit programme ; > des moyens pour comparer, préalablement à l'exécution d'une instruction de branchement, respectivement lors du passage d'un label, le contenu dudit compteur d'instructions au nombre enregistré dans ladite mémoire d'instructions neutres censées avoir été exécutées depuis l'instruction de branchement ou le label précédent. L'invention a également pour objet un composant électronique comprenant une unité de traitement telle que décrite ci-dessus. L'invention a également pour objet une carte à puce comprenant un composant électronique tel que décrit ci-dessus. On décrira maintenant à titre d'exemple non limitatif des modes de réalisation de l'invention en référence aux dessins annexés dans lesquels : - la figure 1 est un organigramme illustrant le procédé selon l'invention ; - la figure 2 représente schématiquement un programme d'application modifié selon l'invention ; - la figure 3 représente un composant électronique selon l'invention ; et - la figure 4 représente une carte à puce selon l'invention. La figure 1 illustre le procédé selon l'invention tel qu'il peut être mis en oeuvre par la CPU représentée en 1 à la figure 3, et comprenant : - une mémoire 2, contenant les nombres d'instructions neutres à exécuter entre chaque instruction de branchement d'un programme à exécution sécurisée ; -un compteur d'instructions Cl 3 susceptible d'être incrémenté par la CPU lors de l'exécution de chaque instruction neutre du programme ; - un comparateur 4 pour comparer le contenu du compteur 3 au contenu d'un emplacement de la mémoire 2 correspondant à une instruction de branchement déterminée. Avant l'exécution du programme, les nombres d'instructions neutres à exécuter entre chaque instruction de branchement du programme sont enregistrés en 10 dans les emplacements respectifs de la mémoire, par exemple lors de la compilation du programme. On verra ci-après que la mémoire 2 peut n'être autre que des emplacements particuliers de la mémoire contenant la suite des instructions du programme à exécuter, où ces nombres apparaissent sous la forme de paramètres des instructions de branchement. On a vu qu'en variante, l'enregistrement en mémoire des nombres d'instructions neutres peut s'effectuer au fur et à mesure de l'exécution du programme lors du passage de chaque instruction de branchement particulière. Puis, au cours de l'exécution du programme, la CPU lit successivement chaque instruction de façon connue. Pour chaque nouvelle instruction lue, la CPU détermine en 11 s'il s'agit d'une instruction neutre ou d'une instruction de branchement. S'il s'agit d'une instruction neutre, le compteur 3 est incrémenté en 10 12, l'instruction est exécutée en 13, et la CPU passe à l'instruction suivante en 14. S'il s'agit d'une instruction de branchement, la CPU lit le compteur en 15 et compare en 16 son contenu au contenu de la mémoire 15 correspondant à cette instruction de branchement particulière. En cas d'égalité, il n'y a pas eu d'anomalie dans le déroulement du programme, le compteur est remis à zéro en 17 et, comme précédemment, l'instruction est exécutée en 13 et la CPU passe en 14 à l'instruction suivante. En cas d'inégalité, il y a eu une 20 anomalie, et une interruption est générée en 18. La figure 2 montre comment un programme d'application est modifié de sorte d'inclure dans chaque instruction de branchement particulière, un paramètre supplémentaire PNI (Preceding Neutra) 25 Instructions) correspondant au nombre d'instructions neutres présentes dans le programme entre la précédente instruction de branchement (ou le début de la sous-routine, ou du programme) et celle-ci. 30 On constate par exemple en 20 que le programme consiste en x instructions avant d'atteindre une première instruction de branchement (qui inclura donc le paramètre PNI=x). Le code peut alors suivre deux branches qui elles-mêmes consistent en un premier morceau de code linéaire (composé de respectivement yl en 21 et z en 22 instructions neutres), etc... On peut considérer comme autre exemple que l'instruction jsr(toto) n'est pas exécutée en 23 suite à une perturbation. Il en résulte donc que Cl ne sera pas remis à zéro et lorsque le programme atteindra en 24 l'instruction RTS(y2), il y aura incohérence entre Cl = yl+y2 et PNI = y2. Afin de considérer le cas particulier du saut en 25 à un label dans le code (jmp label), il est nécessaire d'introduire en 26 une nouvelle instruction CTL. Cette instruction est insérée dans le code juste avant les labels correspondant à des jmp/branch. L'instruction CTL est gérée par le CPU au même titre qu'une instruction de branchement classique en comparant la valeur de PNI au compteur Cl. Pour être exécutable sur une CPU telle que celle de la figure 3, un logiciel doit subir une opération de transformation afin d'insérer l'instruction CTL aux endroits nécessaires et de générer les bonnes valeurs de PNI pour toutes les instructions de branchement. Il convient de noter le cas particulier des interruptions hardware qui se traduisent par une rupture du séquencement suivie habituellement de l'exécution du code correspondant à l'interruption et de l'instruction finale RTI (ReTurn from Interrupt) qui met fin au code de l'interruption et qui retourne à l'exécution du programme initial là ou il avait été interrompu. Ce type d'évènement peut être géré de deux manières : - durant l'exécution de l'interruption, le mécanisme décrit ci-dessus est débrayé et Cl conserve sa valeur. Le mécanisme est réactivé par l'instruction RTI. Dans ce cas-là, l'exécution de l'interruption est transparente ; par contre elle n'est pas protégée car réalisée en dehors du mécanisme selon l'invention - dans un autre mode de réalisation, la valeur de Cl est sauvegardée lorsque l'interruption apparaît (au même titre que la banque de registres en général et l'adresse de retour dans tous les cas). Cl est remis à zéro de sorte que le mécanisme est toujours actif durant le traitement de l'interruption. La valeur sauvegardée de Cl est restaurée lors de l'exécution de l'instruction RTI. Par ailleurs, l'instruction RTI est considérée comme une instruction de branchement et, comme telle, inclut le paramètre PNI qui sera validé avant son exécution. Si l'on revient à la figure 3, le compteur 3 peut être réalisé sous la forme d'un registre de taille N bytes, permettant de compter jusqu'à 2^8.N. Dans un mode de réalisation de l'invention, on peut prendre N=1 byte. Le paramètre PNI est alors codé dans la mémoire 2 sur le même nombre N de byte que le compteur 3. La figure 3 montre par ailleurs la CPU 1 comme faisant partie d'un 20 composant électronique 30, tandis que la figure 4 montre une carte à puce 31 comportant le composant 30. La présente invention permet de détecter la plupart des erreurs de séquencement liées à une perturbation, avec 25 - un faible coût en taille de code (ajout du paramètre PNI pour toutes les instructions de branchement et de l'instruction CTL aux labels branchables) ; - un faible coût en taille de silicium (ajout d'un compteur Cl et de la gestion par le décodeur d'instruction de la comparaison de 30 Cl à PNI pour les instructions de branchement) ; - un faible coût en temps d'exécution (éventuellement nul car la comparaison et l'incrémentation de Cl peuvent être fait en parallèle avec l'exécution de l'instruction). REVENDICATIONS 1. Procédé de sécurisation de l'exécution d'un programme d'ordinateur comportant des instructions de branchement insérées dans un flux d'instructions neutres à exécuter les unes à la suite des autres, ledit procédé étant caractérisé par le fait qu'il comprend des étapes consistant à : > enregistrer (10) dans une mémoire (2), préalablement à l'exécution dudit programme, respectivement préalablement à l'exécution d'une instruction particulière dudit programme, le nombre d'instructions neutres à exécuter entre chaque instruction de branchement, respectivement entre ladite instruction de branchement particulière et l'instruction de branchement qui la précède ; > lors de l'exécution du programme • lors de l'exécution de chaque instruction neutre o incrémenter (12) un compteur d'instructions (3) ; • et au moins lors de l'exécution de chaque instruction de branchement o lire (15) le contenu dudit compteur d'instructions ; o comparer (16) le contenu dudit compteur d'instructions au nombre enregistré dans ladite mémoire, d'instructions neutres censées avoir été exécutées depuis l'instruction de branchement précédente ; et -si le contenu dudit compteur d'instructions est égal au nombre d'instructions neutres enregistré, initialiser (17) ledit compteur et poursuivre l'exécution dudit programme ; - si le contenu dudit compteur d'instructions n'est pas égal au nombre d'instructions neutres enregistré, générer (18) une interruption. 2. Produit programme d'ordinateur pour la sécurisation d'un programme d'application comportant des instructions de branchementinsérées dans un flux d'instructions neutres à exécuter les unes à la suite des autres, caractérisé par le fait qu'il comprend des instructions pour réaliser, à l'exécution, les étapes suivantes: - lire les instructions dudit programme d'application ; - détecter les instructions de branchement ; - lors de la détection d'une instruction de branchement déterminée • compter le nombre d'instructions neutres à exécuter depuis l'instruction de branchement précédente ; • insérer ledit nombre d'instructions neutres en tant que paramètre de ladite instruction de branchement déterminée. 3. Produit programme d'ordinateur selon la revendication 2, comprenant en outre des instructions pour réaliser, à l'exécution, les étapes suivantes, lors de la détection d'une instruction de branchement déterminée, insérer des instructions consistant à : o lire le contenu d'un compteur d'instructions susceptible d'être incrémenté lors de l'exécution de chaque instruction neutre ; o comparer ledit nombre d'instructions neutres au contenu dudit compteur d'instructions ; et - en cas d'égalité entre ledit nombre d'instructions neutres et le contenu dudit compteur, initialiser ledit compteur et exécuter ledit branchement ; - en cas d'inégalité entre ledit nombre d'instructions neutres et le contenu dudit compteur, générer une interruption. 4. Produit programme d'ordinateur selon l'une quelconque des revendications 2 et 3, comprenant des instructions pour réaliser, à l'exécution, les étapes suivantes: - détecter les labels associés à des instructions de branchement ; - lors de la détection d'un tel label,• compter le nombre d'instructions neutres à exécuter depuis l'instruction de branchement précédente ou le label précédent ; • insérer, en amont dudit label, une instruction de contrôle comportant ledit nombre d'instructions neutres en tant que paramètre. 5. Produit programme d'ordinateur selon la revendication 4, comprenant en outre des instructions pour réaliser, à l'exécution, les étapes suivantes, lors de la détection d'un tel label, insérer des instructions consistant à : o lire le contenu dudit compteur d'instructions ; o comparer ledit nombre d'instructions neutres au contenu dudit compteur d'instructions ; et - en cas d'égalité entre ledit nombre d'instructions neutres et le contenu dudit compteur, initialiser ledit compteur et passer à l'instruction suivante ; - en cas d'inégalité entre ledit nombre d'instructions neutres et le contenu dudit compteur, générer une interruption. 6. Produit programme d'ordinateur sécurisé, comportant des instructions de branchement insérées dans un flux d'instructions neutres à exécuter les unes à la suite des autres caractérisé par le fait que, à l'exécution, lesdites instructions de branchement ont, en tant que paramètre, le nombre d'instructions neutres à exécuter depuis l'instruction de branchement précédente. 7. Produit programme d'ordinateur selon la revendication 6, comprenant en outre des instructions pour, au moins lors de l'exécution de chaque instruction de branchement, réaliser, à l'exécution, les étapes suivantes:• lire le contenu d'un compteur d'instructions susceptible d'être incrémenté lors de l'exécution de chaque instruction neutre • comparer le contenu dudit compteur d'instructions audit paramètre ; et o si le contenu dudit compteur d'instructions est égal audit paramètre, initialiser ledit compteur et poursuivre l'exécution dudit programme ; o si le contenu dudit compteur d'instructions n'est pas égal audit paramètre, générer une interruption. 8. Produit programme d'ordinateur selon l'une quelconque des revendications 6 et 7, comportant des labels associés à des instructions de branchement et comportant en outre, en amont desdits labels une instruction de contrôle comportant, en tant que paramètre, le nombre d'instructions neutres à exécuter depuis l'instruction de branchement précédente ou le label précédent. 9. Produit programme d'ordinateur selon la revendication 8, 20 comportant en outre, en amont desdits labels, des instructions pour réaliser, à l'exécution, les étapes suivantes: o lire le contenu dudit compteur d'instructions ; o comparer ledit nombre d'instructions neutres au contenu dudit compteur d'instructions ; et 25 - en cas d'égalité entre ledit nombre d'instructions neutres et le contenu dudit compteur, initialiser ledit compteur et passer à l'instruction suivante ; - en cas d'inégalité entre ledit nombre d'instructions neutres et le contenu dudit compteur, générer une 30 interruption. 10. Unité de traitement informatique comprenant des moyens pour exécuter un programme d'ordinateur comportant des instructions de branchement insérées dans un flux d'instructions neutres à exécuterles unes à la suite des autres, respectivement des labels associés à des instructions de branchement, caractérisée par le fait que lesdits moyens comprennent : -une mémoire (2) susceptible de contenir le nombre d'instructions neutres à exécuter entre chaque instruction de branchement, respectivement entre chaque label et l'instruction de branchement ou le label précédent, lors de l'exécution dudit programme ; - un compteur d'instructions (3) susceptible d'être incrémenté lors de l'exécution de chaque instruction neutre dudit programme ; - des moyens (4) pour comparer, préalablement à l'exécution d'une instruction de branchement, respectivement lors du passage d'un label, le contenu dudit compteur d'instructions au nombre enregistré dans ladite mémoire d'instructions neutres censées avoir été exécutées depuis l'instruction de branchement ou le label précédent. 11. Composant électronique, caractérisé par le fait qu'il comprend une unité de traitement (1) selon la revendication 10. 12. Carte à puce, caractérisée par le fait qu'elle comprend un composant électronique (30) selon la revendication 11. 13. Carte à puce selon la revendication 12, comprenant une 25 mémoire dans laquelle est enregistré un programme sécurisé selon l'une quelconque des revendications 6 à 9.20