Brevet FR2841015A1 — publié le 20031219

CONTRÔLE D'EXECUTION D'UN PROGRAMME La présente invention concerne le contrôle de l'exécution d'un programme, par un processeur exécutant des séries de codes opératoires sur des données. L'invention concerne plus particulièrement un programme utilisé pour l'exécution d'un processus d'authentification, d'autorisation ou analogue. Plus généralement, l'invention s'applique à tout programme pour lequel on souhaite garantir que l'exécution (séquencement) du programme (série d'instructions) ne soit pas modifiée. La présente invention concerne plus particulièrement la protection de l'exécution d'un programme contre des attaques dites de déroutement qui consistent à provoquer un saut inopiné dans la séquence d'exécution, par exemple, en envoyant un pic de courant temporaire sur l'alimentation du processeur pendant un court instant (attaque connue d'après son appellation anglosaxonne "glitch"). Un déroutement de l'exécution d'un programme peut être frauduleux ou accidentel. Les tentatives de déroutement frauduleux apparaissent le plus souvent lorsque le programme s'est mis en boucle ou arrêté sur une instruction de blocage suite à un défaut d'authentification, par exemple, dans une application ou un processeur doit décider si une opération particulière est autorisée (par exemple, dans le cas des cartes bancaires, l'autorisation d'une transaction bancaire après authentification de l'utilisateur). Un autre type d'attaque touchant l'exécution d'un algorithme de cryptographie consiste à faire sauter le compteur de programme afin de provoquer un saut inopiné dans la séquence d'exécution, même si le programme n'est pas arrêté en boucle lors d'une authentification. Par exemple, pour des algorithmes de cryptographie (DSA, RSA, DES, AES, etc.), les clés secrètes peuvent être découvertes grâce à un piratage par provocation de saut d'instruction. Le séquencement des instructions dans un processeur est généralement obtenu au moyen d'un compteur d'instructions (appelé compteur de programme) associé au processeur d'exécution du programme. Classiquement, pour détecter une tentative de déroutement, on double le compteur de programme synchronisant le fonctionnement du processeur. En prévoyant deux compteurs de programme ayant des réalisations différentes et dont les sorties respectives subissent un test câblé de cohérence avant de déclencher l'instruction suivante à exécuter par le processeur, on peut éviter certains déroutements. En effet, lors d'une attaque par impulsion de courant, il y a des chances pour que les résultats donnés par les deux compteurs de programme soient différents. Un inconvénient d'une telle solution est qu'une attaque peut toutefois influencer de la même façon les deux compteurs. La présente invention vise à permettre le contrôle de l'exécution d'instructions d'un programme exécuté par un processeur. L'invention vise plus particulièrement à pallier les inconvénients des solutions connues pour contrer les attaques de type par saut d'instruction du programme. L'invention vise également à proposer une solution qui ne requiert pas de prévoir deux compteurs de programme distincts. L'invention vise également à proposer une solution qui puisse être mise en oeuvre à la fois sous forme logicielle et sous forme matérielle. L'invention vise en outre à proposer une solution qui soit compatible avec un traitement par blocs, d'instructions d'un programme constituant un algorithme d'authentification et d'autorisation. Pour atteindre ces objets et d'autres, la présente invention prévoit un procédé de contrôle de l'exécution d'un programme mettant en oeuvre des instructions successives comprenant chacune au moins l'exécution d'un opérateur, consistant, pendant l'exécution de chaque instruction : à calculer pour chaque opérateur de l'instruction, une signature numérique prenant en compte au moins en partie un code numérique d'identification de l'opérateur et au moins en partie un code numérique identifiant la position de l'opérateur dans le programme, sans prendre en compte les valeurs des opérandes des instructions ; et à comparer la signature calculée à une signature attendue, préalablement stockée dans un élément de mémorisation. Selon un mode de réalisation de la présente invention, ladite signature attendue est calculée, lors de l'installation du programme dans un dispositif chargé de l'exécuter. Selon un mode de réalisation de la présente invention, ladite signature attendue est stockée dans une table. Selon un mode de réalisation de la présente invention, on compare la signature calculée à une signature attendue en fin d'exécution d'un groupe d'instructions comprenant plusieurs opérateurs. Selon un mode de réalisation de la présente invention, ladite signature est calculée par une fonction discriminante, de préférence, une fonction de Hashage. Selon un mode de réalisation de la présente invention, la fonction discriminante combine en outre le code de l'opérateur avec une clé secrète propre au dispositif d'exécution. Selon un mode de réalisation de la présente invention, la taille des groupes d'instructions correspond à la taille de groupes lus dans une mémoire externe à un processeur pour stockage temporaire dans une mémoire cache. L'invention prévoit également un processeur d'exécution d'un programme, associé à un registre de stockage d'une signature courante. Selon un mode de réalisation de la présente invention, le processeur intègre une machine d'états en logique câblée de calcul de ladite signature. Ces objets, caractéristiques et avantages, ainsi que d'autres de la présente invention seront exposés en détail dans la description suivante de modes de réalisation particuliers faite à titre non-limitatif en relation avec les figures jointes parmi lesquelles : la figure 1 illustre, de façon très schématique et sous forme de blocs, un mode de mise en oeuvre du procédé de contrôle d'exécution d'un programme selon la présente invention ; la figure 2 est un organigramme simplifié illustrant un mode de mise en oeuvre d'une étape du procédé de l'invention ; et la figure 3 représente, partiellement et sous forme de blocs, un mode de réalisation d'un processeur d'exécution d'un programme, pourvu de moyens de contrôle d'exécution selon la présente invention. Pour des raisons de clarté, seuls les étapes du procédé et éléments du processeur qui sont utiles à la compréhension de l'invention ont été représentés aux figures et seront décrits par la suite. En particulier, les opérateurs ou instructions concernés par la mise en oeuvre de l'invention n' ont pas été détaillés, l'invention s'applique quel que soit le type d'opérateur. De plus, tous les constituants nécessaires à l'exécution d'un programme, que ce soit au moyen d'une mise en oeuvre logicielle ou au moyen d'une machine d'états en logique câblée, n'ont pas été détaillés, leur réalisation faisant appel à des éléments classiques. Une caractéristique de la présente invention est de calculer, en parallèle à l'exécution d'un programme à contrôler, une signature (mot numérique) dépendant exclusivement du type d'opérateur utilisé par l'instruction et de sa position dans le programme. En d'autres termes, on applique au code numérique identifiant un opérateur en cours d'exécution, une fonction de transformation (par exemple, une fonction connue sous le nom de fonction de Hashage au sens cryptographique) prenant en compte au moins une partie du mot numérique représentant l'opérateur et sa position dans le programme, pour fournir un mot numérique définissant une signature courante de l'exécution du programme. Selon l'invention, on distingue une instruction d'un opérateur, en ce sens qu'une instruction comprend un opérateur et, le plus souvent des opérandes. De façon parfaitement connue, un compteur d'instructions ou compteur de programme séquence le déroulement du programme, chaque instruction nécessitant un nombre de cycles qui dépend de l'opérateur. Selon l'invention, le calcul de signature ne prend pas en compte les valeurs des opérandes ou données traitées par l'algorithme ou le programme, mais exclusivement les codes numériques identifiant les opérateurs. Lors de la création du programme, on calcule également les signatures successives fonction des différents groupes d'opérateurs et de leurs positions relatives dans le programme afin de disposer de valeurs de contrôle (signatures de référence) à comparer aux valeurs courantes lors de l'exécution. Dans le cas où la fonction de calcul de signature prend en compte, en tant que position de l'instruction dans le programme, son adresse dans une mémoire de stockage, le calcul de la signature de référence est effectué lors de l'installation du programme (le code numérique de l'adresse peut être différent d'une mémoire à une autre) . Le mode de réalisation tenant compte de la position relative des opérateurs est préféré, car il permet l'exécution de codes "mobiles", c'est-à-dire dont les adresses ne sont pas figées. Une autre caractéristique de la présente invention est, selon un mode de réalisation préféré, d'effectuer le contrôle de cohérence de la signature calculée par rapport à la signature attendue à la fin de chaque bloc d'instructions d'un programme découpé en blocs. Un tel découpage par blocs sert, par exemple, au chargement du programme depuis une mémoire externe au processeur, vers une mémoire cache qui lui est associée. La figure 1 illustre, sous forme de blocs, un mode de mise en oeuvre du procédé de contrôle d'exécution d'un programme Pg selon la présente invention. Le programme Pg est représenté sous la forme d'une liste d'opérateurs OPEj (j compris entre 1 et m) regroupés par groupes GPi (i compris entre 1 et n) de taille correspondant, par exemple, à la taille de blocs susceptibles d'être transférés depuis une mémoire de stockage du programme vers une mémoire cache. En variante, le groupe d'opérateurs est fixé de façon arbitraire. Au minimum, un groupe d'opérateurs comprend un seul opérateur. Au cours de l'exécution du programme, on applique une fonction f au code numérique représentatif de l'opérateur courant OPEj en tenant compte de sa position dans le programme, c'est-à-dire du groupe GPi auquel il appartient. Cette fonction calcule une signature (bloc 2, SIGNi) courante de l'exécution du programme qui sera, selon l'invention, comparée à une signature attendue. Selon un mode de réalisation préféré, afin de contrôler le séquencement du programme, le calcul de signature (bloc 1) tient également compte de la signature précédemment calculée. La figure 2 illustre, par un organigramme, un mode de mise en oeuvre du contrôle d'exécution exécuté par l'invention. Selon cet exemple de réalisation, les signatures attendues sont stockées dans une table 3, SIGNi où chaque code binaire représentant une signature attendue dépend non seulement de l'instruction OPj mais également du groupe GPi auquel elle appartient. La référence à la position relative de l'opérateur dans le programme sert non seulement à contrôler le séquencement des instructions mais permet de plus de différentier deux signatures alors qu'un même opérateur peut être exécuté plusieurs fois dans un programme donné. Dans le mode de réalisation de la figure 2, à chaque groupe GPi d'instructions, on calcule (bloc 4, COMPUTE f(OPEj, GPi)) pour les opérateurs OPEj successifs la fonction de calcul de signature f(OPEj, GPi). Puis (bloc 5, f(OPEj, GPi) = SIGNi ?), en fin de groupe ou bloc, La signature calculée est comparée à une signature attendue SIGNi, lue dans la table 3. Si les signatures attendues et calculées sont identiques, on passe au groupe suivant (bloc 7, NEXT i). En cas d'incohérence, un programme d'erreur (bloc 6, ERROR) spécifique est mis en oeuvre. Selon un premier mode de mise en oeuvre, les signatures attendues (table 3) sont calculées lors du développement du programme ou de l'algorithme de chiffrement. C'est pourquoi, il est important que ces signatures ne prennent pas en compte les opérandes ou données des instructions et leurs adresses, mais uniquement les codes représentatifs des opérateurs. Dans le cas où les constitutions des groupes ou blocs d'opérateurs dépendent de l'installation du programme dans un processeur particulier, on peut prévoir que les signatures attendues soient calculées lors de cette étape d'installation. La mise en oeuvre de l'invention peut être effectuée de façon logicielle. Dans ce cas, on introduit entre chaque instruction (ou groupe d'instructions) un branchement sur un sous-programme de mise à jour de signature prenant en compte le code de l'opérateur exécuté et le code du groupe. Ce programme met à jour une variable SIGN constituant la signature calculée. La cohérence de la variable calculée avec la variable attendue est vérifiée, a posteriori, par un sous-programme de vérification (par exemple, en environnement sécurisé). La figure 3 représente, sous forme de blocs, un mode de réalisation matériel de la présente invention. Selon ce mode de réalisation, un processeur intégré 10 contient les éléments nécessaires (machine d'états en logique câblée) d'exécution du calcul courant de la signature (bloc 11, f(OPEj, GPi)) qui est stockée dans un registre 12 (SIGN REG). De préférence, chaque état (fin de cycle) de l'automate d'états du processeur est soumis à la fonction de calcul de signature. En variante, l'état n'est pris en compte pour la fonction f, qu'en fin d'instruction, ou d'étapes de chaque instruction. Le calcul par le circuit 11 s'effectue, de préférence, après l'exécution classique de l'opérateur courant OPEj par une unité centrale 13 (CPU) du processeur intégré 10. Cela permet de vérifier non seulement le séquencement du programme mais également l'exécution de chaque instruction. Dans l'exemple représenté, les opérateurs successifs sont lus par groupe GPi dans une mémoire 14 (PGMEN) externe au processeur 10 et sont stockés par groupe dans une mémoire cache 15 (CACHE). Pour la mise en oeuvre de l'invention, la mémoire 14 peut contenir une table particulière (SIGN TABL) lue par le processeur 10 à chaque besoin de vérification de la signature calculée dans le registre 12 par rapport à la signature attendue. Le processeur 10 contient bien entendu les autres éléments habituels d'exécution des programmes. Ceux-ci n'ont pas à être détaillés et ne font pas l'objet de l'invention. Bien entendu, la présente invention est susceptible de diverses variantes et modifications qui apparaîtront à l'homme de l'art. En particulier, tout ou partie du code représentant les opérateurs successifs du programme ou de l'algorithme pourront être repris en compte dans le calcul de signature. De façon similaire, tout ou partie du code représentant la position de chaque opérateur dans le programme pourra être pris en compte dans le calcul de cette signature. De plus, bien que l'invention s'applique plus particulièrement à une vérification automatique de la signature attendue, on peut prévoir un mode de réalisation dans lequel un utilisateur contrôle qu'une signature calculée corresponde à une signature attendue qui lui a été communiquée. En outre, le choix de la fonction de calcul de signature dépend de l'application et d'options que l'on souhaite lui adjoindre. Ce qui a été décrit en relation avec une fonction de Hashage se transpose à toute fonction discriminante, c'est-àdire amplifiant une différence entre deux valeurs d'entrée. Par ailleurs, pour attacher l'exécution du programme au processeur l'exécutant, on pourra prévoir une fonction f réalisant une combinaison de type OU-Exclusif de tout ou partie des bits du code de l'opérateur avec les bits d'une clé numérique propre au processeur. Enfin, la mise en oeuvre de l'invention en utilisant des techniques de programmation et/ou des moyens connus est à la portée de l'homme du métier à partir des indications fonctionnelles données ci-dessus. REVENDICATIONS 1. Procédé de contrôle de l'exécution d'un programme mettant en oeuvre des instructions successives comprenant chacune au moins l'exécution d'un opérateur (OPEj), caractérisé en ce qu'il consiste, pendant l'exécution de chaque instruction : à calculer pour chaque opérateur de l'instruction, une signature numérique (SIGN) prenant en compte au moins en partie un code numérique d'identification de l'opérateur et au moins en partie un code numérique identifiant la position de l'opérateur dans le programme, sans prendre en compte les valeurs des opérandes des instructions ; et à comparer la signature calculée à une signature attendue, préalablement stockée dans un élément de mémorisation. 2. Procédé selon la revendication 1, caractérisé en ce que ladite signature attendue est calculée, lors de l'installation du programme dans un dispositif chargé de l'exécuter. 3. Procédé selon la revendication 1 ou 2, caractérisé en ce que ladite signature attendue est stockée dans une table (3) . 4. Procédé selon l'une quelconque des revendications 1 à 3, caractérisé en ce qu'il consiste à comparer la signature calculée à une signature attendue en fin d'exécution d'un groupe d'instructions (GPi) comprenant plusieurs opérateurs (OPEj). 5. Procédé selon l'une quelconque des revendications 1 à 4, caractérisé en ce que ladite signature est calculée par une fonction (f) discriminante, de préférence, une fonction de Hashage. 6. Procédé selon la revendication 5, caractérisé en ce que la fonction discriminante combine en outre le code de l'opérateur (OPEj) avec une clé secrète propre au dispositif d'exécution. 7. Procédé selon l'une quelconque des revendications 1 à 6, caractérisé en ce que la taille des groupes d'instructions correspond à la taille de groupes lus dans une mémoire (14) externe à un processeur (10) pour stockage temporaire dans une mémoire cache (15). 8. Processeur d'exécution d'un programme, caractérisé en ce qu'il est associé à un registre (12) de stockage d'une signature courante calculée par la mise en oeuvre du procédé selon l'une quelconque des revendications 1 à 7. 9. Processeur selon la revendication 8, caractérisé en ce qu'il intègre une machine d'états en logique câblée (11) de calcul de ladite signature.