Brevet FR2898704A1 — publié le 20070921

B7431 - 05-ZV2-484 1 PROTECTION D'UN PROGRAMME CONTRE UN DEROUTEMENT Domaine de l'invention La présente invention concerne de façon générale les circuits électroniques et, plus particulièrement, la vérification d'intégrité de programmes lors de leur exécution par un circuit. Un exemple d'application de la présente invention concerne les cartes à puce. Exposé de l'art antérieur La figure 1 représente de façon très schématique un exemple de carte à puce 1 du type auquel s'applique la présente invention. Une puce 10 de circuit intégré est encartée dans la carte 1 en matière plastique et est reliée à des contacts électriques 3 pour communication avec un lecteur de carte non représenté. La carte peut également être pourvue d'un système de communication sans contact (transpondeur électromagnétique). La figure 2 représente, de façon très schématique et sous forme de blocs, des constituants d'un circuit intégré 10 d'une carte à puce 1 de la figure 1. Le circuit ou la puce 10 comporte une unité centrale de traitement 11 (CPU), un ou plusieurs éléments 12 de mémorisation non volatiles (par exemple de type ROM), un ou plusieurs éléments de mémorisation volatiles 13 (par exemple de type RAM). Les différents constituants de la B7431 - 05-ZV2-484 2 puce 10 communiquent entre eux et avec un dispositif 14 d'entrée/sortie (I/O) relié aux contacts 3 par un ou plusieurs bus 15 de données, d'adresses et de commandes. Le plus souvent, la puce 10 comporte d'autres fonctions 16 (FCT) constituées par exemple de circuits réalisant des opérations cryptographiques. Les programmes stockés, par exemple dans la mémoire 12, sont susceptibles d'être perturbés lors de leur exécution (déroutés) que ce soit accidentellement ou délibérément (tentatives de piratage). Parmi des attaques effectuées par des fraudeurs pour obtenir des données confidentielles de la puce 10, l'invention s'applique aux attaques dites par injection de fautes (DFA ou Differential Fault Analysis) qui consistent à perturber le fonctionnement du circuit 10 par exemple au moyen d'un rayon- nement (laser, infrarouge, rayons X, etc.) ou par d'autres moyens (par exemple en agissant sur l'alimentation du composant). Lors de l'exécution d'un programme par l'unité centrale 11, un déroutement (volontaire ou accidentel) du programme peut conduire à sauter une ou plusieurs instructions d'un calcul cryptographique, d'une vérification d'authenticité, d'une vérification d'intégrité, etc. La figure 3 représente un détail de la figure 2 illustrant le fonctionnement de l'unité centrale 11 en relation avec un programme contenu, par exemple, dans la mémoire morte 12. L'unité centrale 11 envoie une adresse ADD à la mémoire 12 pour en extraire des instructions DATA d'un programme ainsi que d'éventuels arguments de ces instructions pour exécution. En général, un amplificateur 121 constituant un élément de mémoire tampon (BUFFER) est présent en sortie de données de la mémoire 12 pour stocker temporairement les instructions à destination de l'unité centrale. La présence de cet amplificateur 121 repré- sente une faiblesse en terme de protection du système contre d'éventuelles tentatives de déroutement du programme. En effet, si le contenu d'une mémoire non volatile peut être considéré comme sûr car il est difficilement modifiable (notamment dans le B7431 -05-ZV2-484 3 cas d'une ROM fixée à la fabrication), le transfert des données (instructions et arguments) à destination de l'unité centrale 11 pour exécution constitue une étape sensible car ces données peuvent être modifiées en perturbant l'élément de mémorisation temporaire (l'amplificateur 121). Par exemple, une perturbation peut conduire à faire passer le code opératoire à 00 ou FF en hexadécimal. La plupart du temps, de tels codes opératoires correspondent à des instructions particulières. Par exemple, dans certains proces- Beurs, un code 00 correspond à un saut conditionné par l'argument qui suit. Si l'instruction extraite de la mémoire était une instruction de chargement d'une donnée à une adresse particulière, la transformation de cette instruction en 00 provoque un saut en tenant compte des arguments. Selon un autre exemple, le code FF correspond à une instruction de chargement à partir des arguments qui suivent. Une perturbation conduisant à un code FF transforme alors une instruction quelconque en une instruction de chargement utilisant les arguments. Selon d'autres exemples, les codes 00 et FF conduisent à des déplace- ments de caractères ou autres instructions particulières. Dans tous les cas, on obtient un effet non souhaité qui le plus souvent engendre un déroutement du programme. Le même type de perturbation est gênant également si l'instruction est présente dans une mémoire volatile et plus généralement, dès qu'elle est présente dans un élément de mémorisation et/ou entre un plan mémoire volatil ou non et une unité d'exécution. Une solution serait d'éviter les codes opératoires 00 et FF lors de la constitution des programmes. Toutefois, cela ne ferait que transférer le problème à d'autres codes opératoires éventuels. En effet, bien que les codes 00 et FF sont les plus facilement obtenus par une perturbation de l'amplificateur 121, n'importe quel autre état modifié par rapport au code lu dans la mémoire est susceptible d'engendrer un déroutement du programme. B7431 - 05-ZV2-484 4 On connaît également des mécanismes de vérification d'intégrité d'un code exécuté qui exécutent deux fois un même programme et vérifient la concordance entre les résultats obtenus en fin des deux exécutions. Un inconvénient est que de tels mécanismes agissent a posteriori et qu'il reste alors un risque non négligeable que le fraudeur ait pu exploiter, pendant le déroutement, un résultat erroné du programme. D'autres contre-mesures à des tentatives de déroutement consistent à calculer une signature à partir des instructions exécutées du programme pour la comparer à une signature de référence calculée au stockage du programme. Là encore, il s'agit d'un mécanisme a posteriori, la signature n'étant obtenue qu'en fin d'exécution. Résumé de l'invention La présente invention vise à pallier tout ou partie des inconvénients des techniques connues constituant des contre-mesures aux tentatives de déroutement de programmes exécutés par un circuit électronique. L'invention vise plus particulièrement une solution protégeant le contenu d'une ou plusieurs instructions contenues dans une mémoire et/ou dans des composants périphériques de celle-ci, par exemple, un amplificateur de mémorisation tempo-raire après extraction d'une mémoire non volatile. L'invention vise également une solution compatible 25 avec les autres contre-mesures connues contre des tentatives de déroutement. L'invention vise également une solution ne retardant pas de façon notable l'exécution du programme. Pour atteindre tout ou partie de ces objets ainsi que 30 d'autres, la présente invention prévoit un procédé de contrôle de l'exécution, par une unité centrale de traitement, d'un programme stocké dans une mémoire, un code de redondance stocké avec une première donnée courante à une adresse courante étant affecté à une deuxième donnée ultérieure du programme et dépend 35 au moins de cette deuxième donnée. B7431 - 05-ZV2-484 Selon un mode de mise en oeuvre de la présente invention, le code de redondance, affecté à une donnée courante et stocké avec une donnée précédente, dépend de cette donnée courante et d'une donnée précédente. 5 Selon un mode de mise en oeuvre de la présente invention, un code stocké avec une donnée précédente est comparé à un code courant, calculé avec la donnée courante. Selon un mode de mise en oeuvre de la présente invention, l'exécution d'une instruction courante est candi- tionnée à l'identité entre le code courant et le code mémorisé lors de la lecture d'une donnée précédente. Selon un mode de mise en oeuvre de la présente invention, ledit code est un code de type CRC. L'invention prévoit également un procédé de mémo- risation d'un programme en mémoire, comportant une étape de stocker à une adresse courante une instruction ou un argument d'instruction, accompagné d'un code calculé à partir du contenu d'une adresse suivante dans l'exécution du programme. Selon un mode de mise en oeuvre de la présente inven-20 tion, le début du programme ou d'un sous-programme est une instruction d'initialisation des codes de redondance. L'invention prévoit également un circuit électronique d'exécution d'un programme et une carte à puce comportant un tel circuit. 25 Brève description des dessins 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 30 parmi lesquelles : la figure 1 décrite précédemment représente un exemple de carte à puce du type auquel s'applique la présente invention ; la figure 2 décrite précédemment représente partiel-35 lement, de façon très schématique et sous forme de blocs, un B7431 - 05-ZV2-484 6 exemple de circuit électronique du type auquel s'applique la présente invention ; la figure 3 décrite précédemment représente un détail du circuit de la figure 2 ; la figure 4 représente, de façon très schématique et sous forme de blocs, une partie d'un circuit électronique selon un mode de réalisation de la présente invention ; la figure 5 représente un exemple de contenu de données stockées en mémoire non volatile, illustrant un premier 10 mode de mise en oeuvre de la présente invention ; la figure 6 est un organigramme illustrant le premier mode de mise en oeuvre de la présente invention ; la figure 7 représente un exemple de contenu partiel d'une mémoire non volatile illustrant une variante de la 15 présente invention ; et la figure 8 représente un organigramme simplifié illustrant une autre variante de la présente invention. De mêmes éléments ont été désignés par de mêmes références aux différentes figures. Pour des raisons de clarté, 20 seuls les éléments et étapes utiles à la compréhension de l'invention ont été représentés et seront décrits. En particulier, les détails des instructions exécutées par les programmes modifiés par la mise en oeuvre de l'invention n'ont pas été exposés, celle-ci s'appliquant à toute instruction 25 classique. Description détaillée L'invention sera décrite en prenant l'exemple d'un programme contenu dans une mémoire non volatile et susceptible d'être perturbé dans un amplificateur de mémorisation temporaire 30 en sortie de cette mémoire. Elle s'applique toutefois plus généralement que la mémoire soit volatile ou non et quel que soit l'élément sensible à une perturbation entre cette mémoire et l'unité d'exécution de l'instruction. Une caractéristique d'un mode de mise en oeuvre de la 35 présente invention est de stocker, avec les instructions et B7431 - 05-ZV2-484 7 arguments d'instructions d'un programme, un code de contrôle appelé code de redondance sur un ou plusieurs bits qui dépend de l'instruction ou de l'argument qui suit dans l'exécution normale du programme. Un code calculé avant l'exécution d'une instruc- tion est comparé pour vérification avec le code lu en mémoire lors de l'instruction ou argument précédent. La figure 4 représente, de façon très schématique et sous forme de blocs, par une vue à rapprocher de celle de la figure 3, une partie d'un circuit électronique selon un mode de réalisation de la présente invention. Comme précédemment (figure 2), le circuit électronique 10' comporte une unité centrale de traitement, une ou plusieurs mémoires vives, une ou plusieurs mémoires non volatiles, le cas échéant d'autres fonctions, tous ces éléments communiquant par un ou plusieurs bus entre eux et si besoin avec l'extérieur du circuit. Pour simplifier, seules l'unité centrale 11 (CPU) et la mémoire non volatile 12 (ROM) associée à son amplificateur de sortie 121 (BUFFER) ont été représentées en figure 4. L'unité centrale organise l'extraction de lignes de programmes stockées dans la mémoire 12 en lui envoyant les adresses successives contenant les instructions et arguments souhaités. Les données correspondantes (instructions et arguments) sont extraites de la mémoire 12 et sont stockées temporairement dans l'amplificateur 121. Selon un mode de réalisation de l'invention, les données en mémoire non volatile concernant des instructions ou arguments d'instruction d'un programme sont complétées par un code de contrôle (de type CRC ou signature) sur un nombre de bits dits de redondance inférieur au nombre de bits de la donnée elle-même. Par exemple, pour des octets codés en hexadécimal, on prévoit deux bits complémentaires pour un calcul de CRC. Les données DATA et les bits de redondance RB sont extraits de la mémoire 12 pour être traités par l'unité centrale 11. Dans le mode de réalisation de la figure 4, un circuit logique 111 (GLUE) effectue un prétraitement des données et des bits de B7431 - 05-ZV2-484 8 redondance. En variante, ce traitement est directement effectué par l'unité centrale 11. La figure 5 représente un exemple partiel de programme mettant en oeuvre la présente invention. Une première colonne en figure 5 représente l'adresse ADD en mémoire non volatile de la donnée DATA et des bits de redondance présents à cette adresse. Bien entendu, l'adresse peut être convertie entre une adresse virtuelle fournie par l'unité centrale 11 et une adresse physique dans la mémoire 12. Pour simplifier, on considérera le cas où les deux adresses virtuelle et physique sont identiques. Une deuxième colonne représente la donnée DATA, c'est-à-dire l'instruction ou son argument, présente dans la mémoire 12 à l'adresse concernée, et une troisième colonne représente les bits de redondance RB présents à cette adresse. Selon ce mode de mise en oeuvre de la présente invention, les bits de redondance prévus à une adresse donnée d'un programme sont calculés à partir de la donnée de l'adresse suivante dans le séquencement du programme. Dans l'exemple représenté en figure 5, on suppose que les adresses successives X à X+6 contiennent des données respectivement INIT-CHAIN, INST1, ARG1.1 et ARG1.2 représentant les arguments de la première instruction, INST2, ARG2.1 représentant l'argument unique de la deuxième instruction, INST3, etc. Dans cet exemple, les bits de redondance respectifs des adresses X à X+5 sont calculés à partir des données INST1, ARG1.1, ARG1.2, INST2, ARG2.1 et INST3. La figure 5 fait ressortir que pour que la première instruction INST1 d'un programme ou sous-programme soit protégée par la mise en oeuvre de l'invention, on prévoit une première instruction INIT-CHAIN particulière (par exemple une instruction NOP n'effectuant aucune opération) dont les bits de redondance associés concernent ceux de l'instruction suivante (la première instruction effective) et permettant de démarrer une chaîne de redondance. B7431 - 05-ZV2-484 9 Un avantage de calculer les bits de redondance ou plus généralement n'importe quelle signature en fonction d'une ou plusieurs instructions suivantes du programme est que la redondance lie alors toutes les instructions entre-elles. Cela permet de vérifier non seulement que l'instruction elle-même n'a pas été modifiée mais de plus que le séquencement du programme est bien respecté. La figure 6 est un organigramme illustrant le mode de mise en oeuvre de l'invention de la figure 5. A chaque début de programme ou de sous-programme (bloc 21, START), l'unité centrale demande la lecture en mémoire non volatile de la donnée d'adresse X et des bits de redondance stockés à l'adresse X mais calculés à partir de l'instruction d'adresse X+1 (bloc 22, READ DATA(X)+RB(X+1)). L'unité centrale ou le circuit logique 111 associé stocke temporairement (bloc 23, STORE RB(X+1)) les bits de redondance de l'instruction suivante. Puis, l'instruction présente à l'adresse X (bloc 24, INIT-CHAIN), par exemple une instruction d'absence d'opération, est exécutée. Le compteur programme associé à l'unité centrale 11 est incrémenté pour l'instruction suivante (le cas échéant en tenant compte d'un décalage temporel pour préparer les instructions suivantes à exécuter), ce qui revient à incrémenter d'une unité l'adresse du programme (bloc 25, X=X+1). L'unité centrale envoie alors à la mémoire non volatile l'adresse X+1 pour lecture de l'instruction suivante et des bits de redondance présents à cette adresse mais concernant une instruction ultérieure (bloc 26, READ DATA(X)+RB(X+1)). Comme à l'étape 23, l'unité centrale ou le circuit logique associé stocke les bits redondants destinés à l'instruction ultérieure (bloc 27, STORE RB(X+1)). Puis, l'unité centrale calcule des bits de redondance RB' à partir de l'instruction effectivement reçue de l'amplificateur 121 (bloc 28, RB'=f(DATA(X))). La fonction f représente la fonction de calcul des bits de redondance et doit être connue à la fois du circuit électronique exécutant le programme et de celui provoquant son B7431 - 05-ZV2-484 10 enregistrement en mémoire morte (par exemple, la fonction f est connue du développeur). L'unité centrale compare alors les bits de redondance RB' courants aux bits de redondance RB(X) obtenus lors de la lecture de l'instruction précédente (bloc 29, RB'=RB(X)?). En cas d'identité (sortie Y du bloc 29) la donnée présente à l'adresse X est considérée comme valide et l'instruction correspondante est exécutée (bloc 30, EXEC DATA(X)) le cas échéant après réception et vérification de ses arguments. On revient alors en entrée du bloc 25 pour chargement de la ligne suivante du programme et réitération des mêmes étapes de vérification. En cas de différence entre les codes RB et RB' (sortie N du bloc 29), cela signifie une erreur soit dans le séquencement, soit dans l'instruction exécutée. Le traitement d'erreur peut prendre n'importe quelle forme. Par exemple, cela peut conduire à un blocage du circuit (le cas échéant en cas de dépassement d'un nombre d'erreurs considéré comme acceptable), à la transmission d'un signal d'erreur, etc., l'invention étant compatible avec tous les traitements habituels effectués suite à une détection d'erreur. L'ordre des étapes 27 à 30 n'a pas d'importance pourvu que l'étape 29 soit effectuée postérieurement à l'étape 28. L'invention tire profit du fait que les programmes que l'on souhaite surveiller sont le plus souvent inscrits en mémoire non volatile et sont donc connus à l'avance y compris dans leur séquencement. Selon une variante de réalisation, la première instruction d'initialisation de chaîne, qui sert à vérifier l'instruction INST1 du programme, est omise. Toutefois, un avantage de prévoir cette instruction est que cela rend la solution compatible avec un appel dynamique à différents sous- programmes. De préférence, tous les sous-programmes commencent alors par une même instruction particulière INIT-CHAIN (par exemple, une instruction NOP) permettant de démarrer une autre chaîne de redondance, et les appels à des sous-programmes B7431 -05-ZV2-484 11 comportent, comme bits de redondance, les bits calculés pour cette instruction de démarrage. Cela permet des branchements sur des sous-programmes sans avoir besoin de prévoir tous les chemins possibles. De préférence, les adresses de retour possibles dans le programme principal (ou dans d'autres sous-programmes en cas d'imbrication) comportent également l'instruction de démarrage pour que les bits de redondance présents aux adresses des instructions de retour de tous les sous-programmes puissent être identiques indépendamment des sous-programmes. Cela simplifie la conception et la vérification. La figure 7 illustre une variante de l'invention selon laquelle les bits de redondance RB associés aux données sont découpés en au moins deux parties. Une première partie contient le code de l'instruction suivante. Une deuxième partie contient, en cas de saut conditionnel, le code d'une autre instruction et un code fixe RBO sinon. Dans l'exemple représenté, on suppose que la première instruction effective (adresse X+1) est un saut conditionnel (CONDJUMP(X+4,X+6)). Ce mode de mise en oeuvre permet de vérifier le séquencement et l'intégrité du programme que l'instruction suivant la première soit l'instruction INST2 ou l'instruction INST3. Le code fixe RBO est utilisé pour compléter les bits de redondance en l'absence de saut. Les deux modes de mise en oeuvre illustrés précé-demment requièrent que tous les chemins possibles pour le programme soient pré-calculés à l'exception des éventuels appels à des sous-programmes. La figure 8 est un organigramme simplifié illustrant une autre variante, particulièrement adaptée au cas où le retour suite à un appel d'un sous-programme est susceptible de se produire à une adresse conditionnelle non déterminable par l'appel de ce sous-programme, le mot de redondance est alors calculé à partir de l'instruction suivante au retour dans le programme principal. B7431 - 05-ZV2-484 12 Le programme est contenu dans une mémoire, par exemple la mémoire 12 dont les adresses ADD contiennent les instructions et arguments, et les bits de redondance. Pour simplifier, on suppose que chaque adresse contient une instruction INST et un bit de redondance. Selon ce mode de mise en oeuvre, deux éléments (blocs 131) de mémorisation temporaire d'au moins deux RB et PRB bits ou groupes de bits de redondance sont mis à jour en fonction des instructions et branchements éventuels. Avec les notations de la figure 8, les bits RB sont les bits stockés à l'adresse de l'instruction courante pour protéger l'instruction suivante. En fonctionnement normal (à l'intérieur d'un programme ou sous-programme), les bits de redondance RB', calculés pour l'instruction courante sont comparés (test 40, RB' =PRB ?) aux bits PRB contenus dans l'élément 131 comme associés à l'instruc- tion précédente. L'instruction n'est exécutée (bloc 47, EXEC) qu'en cas de concordance, une erreur (FAULT) est générée sinon. Après chaque instruction, l'adresse suivante bloc 48, NEXT ADD) est sélectionnée pour être extraite de la mémoire 12. A chaque nouvelle instruction du programme et avant de comparer des bits de redondance RB' calculés avec cette instruction courante à des bits PRB mémorisés lors d'une instruction précédente, on effectue plusieurs tests pour le cas échéant réorganiser les contenus des éléments 131. Si (test 41, INST = INIT-CHAIN ?), l'instruction cou- rante est une initialisation de chaîne, les bits de redondance IRB correspondant à ce type d'instruction (par exemple un NOP) sont stockés (bloc 42, PRB = ICB). Les bits de redondance lus avec l'instruction INIT-CHAIN (et correspondant à la première instruction du sous-programme) sont stockés comme élément RB. Si (test 43, INST = RETURN)) l'instruction est une instruction de retour dans un programme appelant ou un retour d'interruption, des bits de redondance stockés dans un élément 132 de mémorisation supplémentaire ST (ou une pile de registres) lors de l'appel du sous-programme remplacent (bloc 44, RB B7431 - 05-ZV2-484 13 Si (test 45, INST = CALL OR INTERRUPT ?) l'instruction est un appel d'un sous-programme ou une interruption, les bits de redondance lus avec cette instruction sont placés (bloc 46, ST Ainsi, lors d'un appel d'un sous-programme par un premier programme ou d'une interruption, on stocke les bits de redondance qui serviront, au retour (ou en fin d'interruption) à l'instruction suivante du premier programme. Au début du sous-programme, les bits de redondance particuliers de l'instruction de démarrage sont pris en tant que bit PRB pour l'instruction suivante. En fin de sous-programme, les bits stockés lors de l'appel de ce sous-programme sont rechargés comme bits à prendre en compte pour l'instruction suivant le retour. Un avantage de la présente invention est le contrôle non seulement des contenus des instructions elles-mêmes mais également du séquencement du programme en construisant une chaîne de confiance/redondance. Un autre avantage de la présente invention est que sa mise en oeuvre et notamment la vérification des codes de redondance fait appel à des fonctions simples généralement présentes dans les unités centrales que ce soit sous forme câblée ou non, et ne prend que peu de temps par rapport à la durée d'exécution elle-même du programme. Bien entendu, la présente invention est susceptible de diverses variantes et modifications qui apparaîtront à l'homme de l'art. En particulier, bien que l'invention ait été décrite en relation avec un exemple plus particulièrement destiné aux mémoires mortes, elle s'applique plus généralement aux mémoires volatiles et non volatiles, réinscriptibles ou non. Dans le cas de programmes de mise à jour stockés dans une mémoire non volatile réinscriptible (par exemple, de type EEPROM), on veillera à construire le programme de mise à jour en tenant compte des bits de redondance des instructions du programme principal. Une telle précaution ne pose généralement pas de problème dans la mesure où le concepteur du programme de mise à B7431 - 05-ZV2-484 14 jour connaît l'intégralité du programme principal. De plus, bien que l'invention ait été décrite en relation avec un exemple d'application aux cartes à puce, elle s'applique plus généralement à tout circuit électronique d'exécution d'un pro- gramme, que la mémoire de stockage du programme soit ou non intégrée à l'unité centrale de traitement. En outre, le code de redondance stocké avec une donnée courante (instruction ou argument d'instruction) peut être calculé en tenant compte non seulement de la donnée (instruction ou argument) suivante mais également de la donnée courante. a F REVENDICATIONS 1. Procédé de contrôle de l'exécution, par une unité centrale de traitement (11), d'un programme stocké dans une mémoire (12), caractérisé en ce qu'un code de redondance stocké avec une première donnée courante à une adresse courante est affecté à une deuxième donnée ultérieure du programme et dépend au moins de cette deuxième donnée. 2. Procédé selon la revendication 1, dans lequel le code de redondance, affecté à une donnée courante et stocké avec une donnée précédente, dépend de cette donnée courante et d'une donnée précédente. 3. Procédé selon l'une quelconque des revendications 1 et 2, dans lequel un code stocké avec une donnée précédente est comparé à un code courant, calculé avec la donnée courante. 4. Procédé selon la revendication 3, dans lequel l'exécution d'une instruction courante est conditionnée à l'identité entre le code courant et le code mémorisé lors de la lecture d'une donnée précédente. 5. Procédé selon l'une quelconque des revendications 1 à 4, dans lequel ledit code (RB) est un code de type CRC. 6. Procédé de mémorisation d'un programme en mémoire (12), pour contrôle de son exécution selon l'une quelconque des revendications 1 à 5, caractérisé en ce qu'il comporte les étapes de stocker à une adresse courante une instruction ou un argument d'instruction, accompagné d'un code calculé à partir du contenu d'une adresse suivante dans l'exécution du programme. 7. Procédé selon la revendication 6, dans lequel le début du programme ou d'un sous-programme est une instruction (INIT-CHAIN) d'initialisation des codes de redondance. 8. Circuit électronique d'exécution d'un programme, caractérisé en ce qu'il comporte des moyens pour la mise en oeuvre du procédé conforme à l'une quelconque des revendications 1 à 7. 9. Carte à puce comportant un circuit électronique conforme à la revendication 8. y.