Brevet FR3071633A1 — publié le 20190329

PROCÉDÉ D'EXÉCUTION D'UN CODE MACHINE D'UNE FONCTION SÉCURISÉE [001] L'invention concerne un procédé d'exécution d'un code machine d'une fonction sécurisée par un microprocesseur ainsi qu'un code binaire comportant le 5 code machine de cette fonction sécurisée. L'invention concerne également : - un support d'enregistrement d'informations et un appareil pour la mise en oeuvre de ce procédé d'exécution, et - un compilateur pour générer ce code binaire. [2] Pour obtenir des informations sur un code binaire ou provoquer un 10 fonctionnement inattendu du code binaire, il est connu de le soumettre à des attaques connues sous le terme d'« injection de fautes » ou « fault attack » en anglais. Ces attaques consistent à perturber le fonctionnement du microprocesseur lors de l'exécution du code machine par divers moyens physiques comme des modifications des tensions d'alimentation, des modifications du signal d'horloge, l'exposition du 15 microprocesseur à des ondes électromagnétiques et autres. [3] À l'aide de telles perturbations, un attaquant peut altérer l'intégrité des instructions machines ou des données pour, par exemple, retrouver une clé secrète d'un système cryptographique, contourner des mécanismes de sécurité tels que la vérification d'un code PIN lors d'une authentification ou simplement empêcher 20 l'exécution d'une fonction essentielle pour la sécurité d'un système critique. [4] Une attaque par injection de fautes peut provoquer : - une altération transitoire ou permanente du contenu de la mémoire et donc des données ou du code du programme, ou - une altération du fonctionnement du microprocesseur, par exemple, par des 25 modifications des valeurs des registres de données, des instructions en cours d'exécution par l'unité arithmétique et logique, du fonctionnement de l'unité arithmétique et logique, de l'état des registres de statut et de contrôle ou autres. Suivant la nature de la faute, on peut considérer trois types d'altérations qui auront un effet sur le programme exécuté : 30 1) une altération des instructions du code machine exécuté telle qu'une altération de la mémoire ou une altération de l'état du processeur au moment du traitement de l'instruction fautée, 2) une altération des valeurs stockées dans des variables ou des registres, et 3) une altération du flot de contrôle du code machine, par exemple, par modification 35 de la mémoire programme ou par modification du compteur ordinal ou par modification des registres de statut dans le cas d'un branchement conditionnel. [005] Le flot de contrôle correspond au chemin d'exécution suivi lors de l'exécution du code machine. Le flot de contrôle est classiquement représenté sous la forme d'un graphe orienté connu sous le terme de graphe de flot de contrôle ou « control flow 40 graph » en anglais. 2 [6] Lorsque l'altération empêche seulement l'exécution d'une ou plusieurs des instructions du code machine ou lorsque l'altération a un effet sur le processeur équivalent au fait de ne pas exécuter l'instruction perturbée, on parle alors de saut d'instructions. Lorsque l'altération remplace une ou plusieurs des instructions du code machine par d'autres instructions exécutables par le microprocesseur, on parle alors de remplacement d'instructions. [7] Lorsque l'altération modifie une instruction de branchement ou lorsque l'altération consiste à sauter une instruction de branchement, on observe un effet de détournement du flot de contrôle. L'effet de détournement du flot de contrôle peut être observé quand une instruction de branchement est altérée ou quand la condition impliquée dans un branchement conditionnel est modifiée ou quand l'adresse de retour d'une fonction est modifiée ou encore quand le compteur ordinal du microprocesseur est modifié. [8] Le code machine d'une fonction peut être instrumenté pour permettre la détection et le signalement des fautes provoquées par l'injection de fautes. Lorsque le code machine d'une fonction est ainsi instrumenté, ce code machine est qualifié de « code machine d'une fonction sécurisée ». En effet, contrairement au code machine d'une fonction non-sécurisée, ce code machine est apte à permettre le signalement des fautes typiquement rencontrées en cas d'attaque par injection de fautes. [009] Par exemple, des procédés connus d'exécution d'un code machine d'une fonction sécurisée par un microprocesseur comporte : a) la fourniture du code machine enregistré dans une mémoire principale, ce code machine étant formé par une succession de blocs de base dans lesquels : - chaque bloc de base comporte une succession d'instructions systématiquement 25 exécutées les unes après les autres lors de l'exécution du code machine par le microprocesseur, parmi ces instructions, au moins certaines d'entre elles étant des instructions à protéger, - chaque bloc de base débute à une adresse de branchement et se termine par une instruction de branchement vers une adresse de branchement d'un autre bloc de 30 base, le bloc de base qui débute à l'adresse de branchement étant appelé bloc de base suivant et le bloc de base qui se termine par une instruction de branchement vers cette adresse de branchement étant appelé bloc de base précédent, b) lors de l'exécution du code machine par le microprocesseur, le procédé comporte les opérations suivantes : 35 1) le microprocesseur charge puis décode les instructions des blocs de base précédent et suivant du code machine, puis chaque instruction décodée est exécutée par une unité arithmétique et logique du microprocesseur, 2) à chaque fois qu'une instruction à protéger du bloc de base précédent est chargée, un module matériel de sécurisation du microprocesseur construit, en 40 appliquant une fonction Fcs() préprogrammée, une nouvelle valeur d'une 3 signature à partir de la valeur de cette instruction à protéger et de la précédente valeur de la signature, cette signature étant ainsi fonction des valeurs des différentes instructions à protéger du bloc de base précédent, 3) le microprocesseur charge un vecteur d'initialisation contenu dans le code 5 machine et le module matériel de sécurisation calcule, à partir de ce vecteur d'initialisation chargé et en appliquant une fonction Fvs() préprogrammée, une valeur attendue pour la signature du bloc de base précédent, 4) en réponse au chargement d'une instruction prédéterminée, le module matériel de sécurisation compare la valeur construite de la signature à la 10 valeur attendue de cette signature calculée à partir du vecteur d'initialisation chargé, et 5) seulement si ces valeurs ne correspondent pas, le module matériel de sécurisation déclenche le signalement d'une faute lors de l'exécution de ce code machine et, dans le cas contraire, inhibe un tel signalement. 15 [0010] Par exemple, un tel procédé d'exécution est décrit dans l'article suivant : Ruan de Clercq et AL : « SOFIA : Software and Control Flow Integrity Architecture », Elsevier, Computers & Security, Volume 68,07/2017, Pages 16-35. [0011] Ce procédé connu est intéressant car il permet à la fois de contrôler l'intégrité des blocs de base et du flot de contrôle. Pour contrôler l'intégrité des blocs de base, 20 chaque bloc de base débute par des instructions qui définissent la valeur attendue de la signature de ce bloc de base. Ensuite, lors de l'exécution des instructions à protéger de ce bloc de base, une valeur est construite, à partir des instructions exécutées, pour la signature de ce bloc de base. Si la valeur construite de la signature correspond à la valeur attendue, alors l'intégrité du bloc de base est confirmée. [0012] Pour contrôler l'intégrité du flot de contrôle, le procédé connu propose de chiffrer chaque instruction à protéger du bloc de base avec une valeur fonction de la valeur actuelle du compteur ordinal et de sa précédente valeur. Ainsi, si le flot de contrôle est modifié, la valeur précédente ou actuelle du compteur ordinal ne correspond pas à la valeur attendue et le déchiffrement correct des instructions à protéger devient impossible. [0013] L'invention vise à contrôler à la fois l'intégrité des blocs de base et l'intégrité du flot de contrôle mais de façon plus simple que dans les procédés connus. Elle a donc pour objet un tel procédé d'exécution dans lequel le vecteur d'initialisation est 35 seulement contenu dans le bloc de base suivant. [0014] Les modes de réalisation de ce procédé d'exécution peuvent comporter une ou plusieurs des caractéristiques suivantes : ^ le bloc de base suivant est aussi un bloc de base précédent pour un autre bloc de base du code machine de sorte que les opérations 1) à 5) sont aussi 40 réalisées pour le bloc de base suivant, et lors de l'exécution du bloc de base 4 suivant, le module matériel de sécurisation initialise la valeur construite de la signature du bloc de base suivant à partir du même vecteur d'initialisation que celui utilisé pour calculer la valeur attendue de la signature du bloc de base précédent, de sorte que valeur construite de la signature du bloc de base 5 suivant dépend aussi de ce vecteur d'initialisation ; ^ - lors de l'opération 3), le module matériel de sécurisation calcule la valeur attendue de la signature du bloc de base précédent, en plus, à partir de la valeur chargée d'un paramètre y de sorte que la valeur attendue de la signature du bloc de base précédent varie en fonction de cette valeur chargée 10 du paramètre y ou, lors de l'opération 2), le module matériel de sécurisation construit la nouvelle valeur de la signature du bloc de base précédent, en plus, à partir de la valeur chargée d'un paramètre y de sorte que la valeur construite de la signature du bloc de base précédent varie en fonction de cette valeur chargée du paramètre v, et 15 - le bloc de base précédent comporte une instruction prédéterminée qui, lorsqu'elle est exécutée par le microprocesseur, provoque le chargement de la valeur du paramètre v, cette valeur du paramètre y étant contenue dans ce bloc de base précédent et tel que, en absence de modification des instructions à protéger du bloc de base précédent, la valeur attendue calculée lors de 20 l'opération 3) correspond à la valeur construite de la signature de ce bloc de base précédent ; ^ - l'opération a) comporte la fourniture d'un bloc de base précédent se terminant par une instruction de branchement conditionnelle qui, lorsqu'une condition est vérifiée provoque, lorsqu'elle est exécutée par le microprocesseur, un 25 branchement vers un premier bloc de base suivant et, en alternance, lorsque la condition n'est pas vérifiée, provoque, lorsqu'elle est exécutée par le microprocesseur, un branchement vers un second bloc de base suivant différent du premier bloc de base suivant, et - lors de l'opération 3), le module matériel de sécurisation calcule la valeur 30 attendue de la signature du bloc de base précédent, en plus, à partir d'une valeur contenue dans un registre, cette valeur n'étant pas la même selon que la condition est vérifiée ou pas, de sorte que la valeur attendue de la signature du bloc de base précédent varie en fonction de cette valeur contenue dans ce registre ou, lors de l'opération 2), le module matériel de sécurisation construit la nouvelle valeur de la signature du bloc de base précédent, en plus, à partir de la valeur contenue dans ce registre de sorte que la valeur construite de la signature du bloc de base précédent varie en fonction de cette valeur contenue dans ce registre ; ^ lors de l'opération 2), la fonction préprogrammée FcsO mise en oeuvre est une fonction de chiffrement à l'aide d'une clef secrète stockée dans une mémoire 5 sécurisée du microprocesseur, cette mémoire sécurisée étant uniquement accessible par des composants internes du microprocesseur ; ^ lors de l'opération 2), la fonction préprogrammée Fcs() est un homomorphisme algébrique ; 5 - - les fonctions préprogrammées Fcs() et FvsQ mettent en oeuvre, respectivement, une fonction de chiffrement asymétrique à l'aide d'une clé publique et une fonction de déchiffrement à l'aide d'une clé privée correspond à la clé publique, ou - les fonctions préprogrammées FcsO et FvsO mettent en oeuvre, 10 respectivement, une fonction de déchiffrement asymétrique à l'aide d'une clé privée et une fonction de chiffrement à l'aide d'une clé publique correspond à la clé privée ; se la fonction FvsQ est la fonction identité. [0015] L'invention a également pour objet un code binaire comportant un code 15 machine d'une fonction sécurisée pour la mise en oeuvre du procédé revendiqué, dans lequel le code machine comprend : - une succession de blocs de base dans lesquels : - chaque bloc de base comporte une succession d'instructions systématiquement exécutées les unes après les autres lors de l'exécution du 20 code machine par le microprocesseur, parmi ces instructions, au moins certaines d'entre elles étant des instructions à protéger, - chaque bloc de base débute à une adresse de branchement et se termine par une instruction de branchement vers une adresse de branchement d'un autre bloc de base, le bloc de base qui débute à l'adresse de branchement 25 étant appelé « bloc de base suivant » et le bloc de base qui se termine par une instruction de branchement vers cette adresse de branchement étant appelé « bloc de base précédent », - pour chaque bloc de base, le code machine contient : - un vecteur d'initialisation à partir duquel le module matériel de sécurisation 30 est apte à calculer, à l'aide d'une fonction FvsQ préprogrammée, une valeur attendue pour la signature du bloc de base précédent, - une instruction prédéterminée apte à déclencher la comparaison, par le module matériel de sécurisation, d'une valeur construite de la signature du bloc de base précédent à la valeur attendue de cette signature calculée à partir du vecteur 35 d'initialisation chargé, dans lequel le vecteur d'initialisation est seulement contenu dans le bloc de base suivant. [0016] L'invention a également pour objet un support d'enregistrement d'informations lisible par un microprocesseur, ce support d'enregistrement d'informations contenant 40 le code binaire revendiqué. 6 [0017] L'invention a également pour objet un appareil électronique comportant : - une mémoire dans laquelle est enregistré un code machine d'une fonction sécurisée, ce code machine comprenant une succession de blocs de base dans lesquels : 5 - chaque bloc de base comporte une succession d'instructions systématiquement exécutées les unes après les autres lors de l'exécution du code machine par un microprocesseur, parmi ces instructions, au moins certaines d'entre elles étant des instructions à protéger, - chaque bloc de base débute à une adresse de branchement et se termine 10 par une instruction de branchement vers une adresse de branchement d'un autre bloc de base, le bloc de base qui débute à l'adresse de branchement étant appelé « bloc de base suivant » et le bloc de base qui se termine par une instruction de branchement vers cette adresse de branchement étant appelé « bloc de base précédent », 15 - le microprocesseur comportant une unité arithmétique et logique et un module matériel de sécurisation, ce microprocesseur étant apte à exécuter le code machine enregistré dans la mémoire, ce microprocesseur étant apte, lors de l'exécution du code machine, à charger puis à décoder les instructions des blocs de base précédent et suivant du code machine, et l'unité arithmétique et logique est apte à exécuter 20 chaque instruction décodée, - le module matériel de sécurisation est apte, lors de l'exécution du code machine, à réaliser les opérations suivantes : - à chaque fois qu'une instruction à protéger du bloc de base précédent est chargée, le module matériel de sécurisation du microprocesseur construit, à 25 l'aide d'une fonction Fcs() préprogrammée, une nouvelle valeur d'une signature à partir de la valeur de cette instruction à protéger et de la précédente valeur de la signature, cette signature étant ainsi fonction des valeurs des différentes instructions à protéger du bloc de base précédent, - à chaque fois que le microprocesseur charge un vecteur d'initialisation 30 contenu dans le code machine, le module matériel de sécurisation calcule, à partir de ce vecteur d'initialisation chargé et à l'aide d'une fonction Fvs() préprogrammée, une valeur attendue pour la signature du bloc de base précédent, - en réponse au chargement d'une instruction prédéterminée, le module 35 matériel de sécurisation compare la valeur construite de la signature à la valeur attendue de cette signature calculée à partir du vecteur d'initialisation chargé, et - seulement si ces valeurs ne correspondent pas, le module matériel de sécurisation déclenche le signalement d'une faute lors de l'exécution de ce 40 code machine et, dans le cas contraire, inhibe un tel signalement, 7 dans lequel le vecteur d'initialisation est seulement contenu dans le bloc de base suivant. [0018] Enfin, l'invention a également pour objet un compilateur apte à transformer automatiquement un code source d'un programme contenant une fonction sécurisée 5 en un code binaire comportant un code machine d'une fonction sécurisée, dans lequel le compilateur est apte à transformer automatiquement le code source en un code binaire objet de l'invention. [0019] L'invention sera mieux comprise à la lecture de la description qui va suivre, donnée uniquement à titre d'exemple non limitatif et faite en se référant aux dessins 10 sur lesquels : - la figure 1 est une illustration schématique de l'architecture d'un appareil électronique apte à exécuter un code machine d'une fonction sécurisée ; - les figures 2 et 3 sont des illustrations schématiques de différentes portions d'un code machine d'une fonction sécurisée susceptible d'être exécutée par l'appareil de 15 la figure 1 ; - la figure 4 est un organigramme d'un procédé d'exécution du code machine d'une fonction sécurisée ; - la figure 5 est une illustration schématique d'un compilateur apte à générer le code machine exécuté par l'appareil de la figure 1. 20 [0020] Notations et définitions : [0021] Dans ces figures, les mêmes références sont utilisées pour désigner les mêmes éléments. Dans la suite de cette description, les caractéristiques et fonctions bien connues de l'homme du métier ne sont pas décrites en détails. [0022] Dans cette description, les définitions suivantes sont adoptées. 25 [0023] Un « programme » désigne un ensemble d'une ou de plusieurs fonctions prédéterminées que l'on souhaite faire exécuter par un microprocesseur. [0024] Un « code source » est une représentation du programme dans un langage informatique, n'étant pas directement exécutable par un microprocesseur et étant destiné à être transformé par un compilateur en un code machine directement 30 exécutable par le microprocesseur. [0025] Un programme ou un code est dit être « directement exécutable » lorsqu'il est apte à être exécuté par un microprocesseur sans que ce microprocesseur n'ait besoin au préalable de le compiler au moyen d'un compilateur ou de l'interpréter au moyen d'un interpréteur. 35 [0026] Une « instruction » désigne une instruction machine exécutable par un microprocesseur. Une telle instruction est constituée : - d'un opcode, ou code d'opération, codant la nature de l'opération à exécuter, et -d'un ou plusieurs opérandes définissant la ou les valeurs des paramètres de cette opération. 8 [0027] La « valeur d'une instruction » est une valeur numérique obtenue, à l'aide d'une fonction bijective, à partir de la succession de « 0 » et de « 1 » qui code, en langage machine, cette instruction. Cette fonction bijective peut être la fonction identité. 5 [0028] Un « code machine » est un ensemble d'instructions machines. Il s'agit typiquement d'un fichier contenant une succession de bits portant la valeur « 0 » ou « 1 », ces bits codant les instructions à exécuter par le microprocesseur. Le code machine est directement exécutable par le microprocesseur, c'est-à-dire sans nécessiter une compilation ou une interprétation préalable. 10 [0029] Un « code binaire » est un fichier contenant une succession de bits portant la valeur « 0 » ou « 1 ». Ces bits codent des données et des instructions à exécuter par le microprocesseur. Ainsi, le code binaire comprend au moins un code machine et en plus, généralement, des données numériques traitées par ce code machine. [0030] Un « flot d'instructions » est une succession d'instructions classées les unes 15 après les autres et qui forme, dans le code machine, une suite ordonnée de bits. Le flot d'instructions débute par une instruction initiale et se termine par une instruction finale. Par rapport à une instruction donnée du flot d'instructions, les instructions situées du côté de l'instruction initiale sont appelées « instructions précédentes » et les instructions situées du côté de l'instruction finale, sont appelées « instructions 20 suivantes ». Dans ce texte, ce flot d'instructions en mémoire est découpé en une succession de blocs de base immédiatement consécutifs ou séparés par des blocs de données. [0031] Dans ce texte, un « bloc de base » est un groupe d'instructions successives du flot d'instructions qui débute à une adresse de branchement et qui se termine par 25 une seule instruction de branchement explicite ou implicite. Une instruction de branchement explicite se caractérise par la présence explicite d'un opcode dans le code machine qui code l'instruction de branchement. Une instruction de branchement implicite correspond au cas où l'exécution d'un bloc de base précédent se poursuit systématiquement par l'exécution d'un bloc de base suivant situé, dans le code 30 machine, immédiatement après le bloc de base précédent. Dans ce cas, étant donné qu'en absence d'instruction de branchement explicite, les instructions du code machine sont exécutées dans l'ordre les unes après les autres, il n'est pas nécessaire d'introduire à la fin du bloc de base précédent une instruction de branchement explicite vers le bloc de base suivant. Dans cette description, on dit que dans ce cas, 35 le bloc de base précédent se termine par une instruction de branchement implicite car elle n'est pas explicitement codée dans le code machine. Dans ce cas, le bloc de base précédent se termine juste avant l'adresse de branchement du bloc de base suivant. Dans cette demande, l'expression « instruction de branchement » désigne une instruction de branchement explicite à défaut de mention contraire. Ainsi, 40 l'exécution d'un bloc de base débute systématiquement par l'exécution de l'instruction 9 située à son adresse de branchement et se termine systématiquement par l'exécution de l'instruction de branchement qui termine ce bloc de base. Un bloc de base ne comporte pas d'autres instructions de branchement que celle située à la fin de ce bloc de base. Ainsi, les instructions d'un bloc de base sont systématiquement toutes lues 5 par le microprocesseur les unes après les autres dans l'ordre où elles sont présentes dans ce bloc de base. L'instruction de branchement peut diriger, lorsqu'elle est exécutée, le flot de contrôle systématiquement vers la même adresse de branchement ou, en alternance, vers différentes adresses de branchement. Ce dernier cas de figure se rencontre, par exemple, lorsqu'à la fin du bloc de base 10 exécuté, le flot de contrôle peut se poursuivre vers un premier et, en alternance, vers un deuxième bloc de base. [0032] Une « instruction de branchement » est une instruction qui, lorsqu'elle est exécutée par le microprocesseur, déclenche un saut vers l'adresse de branchement d'un autre bloc de base. Cette instruction de branchement comporte donc au moins 15 comme paramètre l'adresse de branchement de cet autre bloc de base. Typiquement, à cet effet, cette instruction remplace la valeur actuelle du compteur ordinal par la valeur de l'adresse de branchement. On rappelle que le compteur ordinal contient l'adresse de la prochaine instruction à exécuter par le microprocesseur. En absence d'instruction de branchement, à chaque fois qu'une instruction est exécutée, le 20 compteur ordinal est incrémenté de la taille de l'instruction actuellement exécutée. En absence d'instruction de branchement, les instructions sont systématiquement exécutées séquentiellement les unes après les autres dans l'ordre où elles sont enregistrées dans une mémoire principale. L'instruction de branchement peut être inconditionnelle, c'est à dire que le saut vers l'adresse de branchement est 25 systématiquement réalisé dès que cette instruction est exécutée. Une instruction de branchement inconditionnel est par exemple l'instruction « JMP » en langage assembleur pour les microprocesseurs de la série x86. L'instruction de branchement peut aussi être conditionnelle, c'est-à-dire que le saut vers l'adresse de branchement est déclenché lors de son exécution uniquement si une condition particulière est 30 vérifiée. Par exemple, une instruction de branchement conditionnel est une instruction « JE », « JA » ou « JNE » en assembleur. L'instruction de branchement peut aussi bien être un appel à une fonction. Dans ce texte, le terme « instruction de branchement » désigne aussi bien les instructions de branchement direct qu'indirect. Une instruction de branchement direct est une instruction de branchement qui 35 contient directement la valeur numérique de l'adresse de branchement. Une instruction de branchement indirect, est une instruction de branchement vers une adresse de branchement contenue dans une mémoire ou un registre du microprocesseur. Ainsi, contrairement à une instruction de branchement direct, une instruction de branchement indirect ne contient pas directement la valeur numérique 40 de l'adresse de branchement. 10 [0033] Une « adresse de branchement » est l'adresse dans la mémoire principale à laquelle se trouve la première instruction exécutée d'un bloc de base. Par la suite, on parle d'adresse de branchement même pour les blocs de base dont la première instruction est exécutée suite à l'exécution d'une instruction de branchement implicite. 5 [0034] On parlera d'exécution d'une fonction pour désigner l'exécution des instructions réalisant cette fonction. [0035] Dans un souci de simplification, dans cette description et dans les figures, les instructions ne sont pas représentées sous forme binaire, mais plutôt sous une forme symbolique exprimée dans un langage évolué de plus haut niveau. 10 [0036] Description d'un mode de réalisation : [0037] La figure 1 représente un appareil électronique 1 comportant un microprocesseur 2, une mémoire principale 4 et un support 6 de stockage de masse. Par exemple, l'appareil 1 est un ordinateur, un smartphone, une tablette électronique, une carte à puce ou similaire. 15 [0038] Le microprocesseur 2 comporte ici : - une unité arithmétique et logique 10 ; - un ensemble 12 de registres ; - un module de commande 14 ; - une interface 16 d'entrée/sortie de données, 20 - un chargeur 18 d'instructions comportant un compteur ordinal 26, - une file 22 d'instructions à exécuter, et - un module matériel 28 de sécurisation. [0039] La mémoire 4 est configurée pour stocker des instructions d'un code binaire 30 d'un programme devant être exécuté par le microprocesseur 2. La mémoire 4 est 25 une mémoire à accès aléatoire. Typiquement, la mémoire 4 est une mémoire volatile. La mémoire 4 peut être une mémoire externe au microprocesseur 2 comme représenté sur la figure 1. Dans ce cas, la mémoire 4 est, par exemple, réalisée sur un substrat mécaniquement séparé du substrat sur lequel sont réalisés les différents éléments du microprocesseur 2 comme l'unité 10. 30 [0040] Dans cet exemple de réalisation le code binaire 30 comporte notamment le code machine 32 d'une fonction sécurisée. [0041] A titre d'illustration, le microprocesseur 2 est conforme à l'architecture ARM (« Advanced Risk Machine ») version 7 et supporte les jeux d'instructions tels que Thumbl et/ou Thumb2. 35 [0042] Le chargeur 18 charge dans la file 22 la prochaine instruction à exécuter par l'unité 10 à partir de la mémoire 4. Plus précisément, le chargeur 18 charge l'instruction sur laquelle pointe le compteur ordinal 26. Le chargeur 18 charge dans la file 22 systématiquement et à chaque fois un mot complet de N bits, où N est un entier constant généralement supérieur ou égale à 8, 16, 32 ou 64. N est donc la taille 40 de chargement utilisée par le microprocesseur 2. Par exemple, ici, N est égal à 32. 11 [0043] L'unité 10 est notamment configurée pour exécuter les unes après les autres les instructions chargées dans la file 22. Les instructions chargées dans la file 22 sont généralement systématiquement exécutées dans l'ordre où ces instructions ont été enregistrées dans cette file 22. L'unité 10 est aussi capable d'enregistrer le résultat de 5 ces instructions exécutées dans un ou plusieurs des registres de l'ensemble 12. [0044] Dans cette description, on utilisera comme synonymes « exécution par le microprocesseur 2 » et « exécution par l'unité 10 ». [0045] Le module 14 est configuré pour déplacer des données entre l'ensemble 12 de registres et l'interface 16. L'interface 16 est notamment apte à acquérir des 10 données et des instructions, par exemple depuis la mémoire 4 et/ou le support 6 extérieurs au microprocesseur 2. [0046] Le module 28 est capable d'exécuter automatiquement les opérations suivantes à la place de l'unité arithmétique et logique 10 : 1) en réponse au chargement, par le chargeur 18, d'une instruction à protéger du bloc 15 de base en cours d'exécution, le module 28 construit une valeur Ck d'une signature de ce bloc de base, 2) en réponse au chargement, par le chargeur 18, d'une instruction de branchement : - le module 28 compare la valeur construite Ck à une valeur attendue Fk pour la signature de ce bloc de base et seulement si ces valeurs ne sont pas identiques, 20 déclenche le signalement d'une faute d'exécution, et - le module 28 initialise la construction d'une valeur Ck+1 d'une signature du bloc de base suivant. [0047] Pour réaliser l'opération 1) ci-dessus, le module 28 implémente et exécute une fonction pré-programmée Fcs(i,, Ck) et pour réaliser l'opération 2) ci-dessus le 25 module 28 implémente et exécute une fonction pré-programmée Fvs(v, IVk). Ces fonctions sont des fonctions secrètes. A cet effet, il n'existe pas de code machine pour exécuter ces fonctions dans une mémoire située en dehors du microprocesseur 2. Typiquement, elles sont implémentées sous forme matérielle à l'intérieur du module 28 ou leur code est enregistré dans une mémoire non-volatile sécurisée 29 à 30 l'intérieur du microprocesseur 2. [0048] Dans ce mode de réalisation, le module 28 construit la valeur de la signature d'un bloc de base au fur et à mesure que des instructions à protéger de ce bloc de base sont chargées dans la file 22. Plus précisément, à chaque fois qu'une instruction i, à protéger du bloc de base est chargée dans la file 22, le module 28 construit la 35 nouvelle valeur Ck de la signature du bloc de base en exécutant l'opération suivante : Ck:= Fcs(ii, CO, où les valeurs Ck à gauche et à droite du signe égale sont, respectivement, la nouvelle valeur et l'ancienne valeur de la signature du bloc de base. Puisque la valeur Ck est construite de façon itérative à partir de sa précédente valeur, il est nécessaire d'initialiser la première valeur Ck à utiliser. Cette première 40 valeur est par la suite appelée « vecteur d'initialisation » est notée IVk. 12 [0049] Par exemple, ici, la fonction Fcs(ii, Ck) est la fonction suivante Fki(liil$Ck), où : - est la valeur numérique de l'instruction chargée, - CD est l'opération « OU exclusif », - Ck est la valeur actuelle de la signature en cours de construction, 5 - Fki() est une fonction de chiffrement symétrique du nombre contenu entre parenthèses avec une clé secrète k1. [0050] La valeur numérique est obtenue, par exemple, à l'aide de la relation suivante : 1i11 = Fvi(ii), où Fviest une fonction bijective qui à partir de la suite de « 0 » et de « 1 » qui code l'instruction retourne une valeur numérique. Dans ce mode de 10 réalisation, pour simplifier, la fonction Fvi() est la fonction identité. [0051] La clé k1 est enregistrée dans la mémoire sécurisée 29 du microprocesseur 2. Ici, il s'agit d'une mémoire qui peut être lue et/ou écrite uniquement par le module 28. Aucun accès à cette mémoire 29 sans passer par l'intermédiaire du module 28 n'est prévu. 15 [0052] La fonction Fvs(v, IVk) est une fonction qui retourne, lorsqu'elle est exécutée par le module 28, une valeur attendue Fk_i pour la signature d'un bloc de base précédent BBk_i, à partir de la valeur d'un paramètre v et d'un vecteur d'initialisation IVk présent au début d'un bloc de base suivant BBk. La fonction Fvs(v, IVk) est telle que, connaissant la valeur Fk_i attendue pour la signature du bloc BBk_i et le vecteur 20 d'initialisation IVk, il est possible de déterminer la valeur du paramètre v qui satisfait la relation suivante : = Fvs(v, IVk). A titre d'illustration, ici, la fonction Fvs(v, IVk) est la fonction suivante Fki(vCDIVk), où les symboles utilisés ont déjà été définis ci-dessus. Ainsi, dans cet exemple, les fonctions Fcs(ii, Ck) et Fvs(v, IVk) sont les mêmes et seuls leurs arguments changent. Dans ce cas particulier, la valeur du paramètre v qui 25 permet de satisfaire la relation Fk_i = Fvs(v, IVk) est donnée par la relation suivante : :=Fkil(Fk_i)CDIVk, où Fk11() est la fonction inverse de la fonction Fkiel, c'est-à-dire ici la fonction de déchiffrement. [0053] Dans cet exemple de réalisation, l'ensemble 12 comporte des registres généraux utilisables pour stocker tout type de données et des registres dédiés. 30 Contrairement aux registres généraux, les registres dédiés sont dédiés au stockage de données particulières généralement automatiquement générées par le microprocesseur 2. [0054] Le microprocesseur 2 comporte ici un bus d'échange de données 24 qui relie les différents composants du microprocesseur 2 entre eux. 35 [0055] Le support 6 est typiquement une mémoire non volatile. Par exemple, il s'agit d'une mémoire du type EEPROM ou Flash. Il contient ici une copie 40 de sauvegarde du code binaire 30. Typiquement, c'est cette copie 40 qui est automatiquement recopiée dans la mémoire 4 pour restaurer le code 30, par exemple, après une coupure de courant ou similaire ou juste avant que débute l'exécution du code 30. 13 [0056] Le code machine 32 se compose d'une succession de blocs de base qui doivent être exécutés les uns après les autres. [0057] La figure 2 représente un premier agencement de deux blocs de base 50 et 52 du code machine 32. Dans ce premier agencement, les blocs de base 50 et 52 5 sont systématiquement exécutés l'un après l'autre. Dans l'ordre d'exécution, le bloc de base 50 précède le bloc de base 52. Dans cette figure et les figures suivantes : - l'ordre d'exécution des blocs de base est représenté par une flèche qui pointe du bloc de base précédent vers le bloc de base suivant, - une flèche en pointillés qui pointe sur un bloc de base représenté indique que le ou 10 les blocs de base qui précèdent ce bloc de base n'ont pas été représentés pour simplifier la figure, - une flèche en pointillés qui pointe dans le vide depuis un bloc de base représenté indique que le ou les blocs de base suivant ce bloc de base représenté n'ont pas été représentés pour simplifier la figure. 15 [0058] Chaque bloc de base débute par une adresse de branchement et se termine par une instruction de branchement. Sur la figure 2, les symboles « ©1 » et « ©2 » à côté de la première instruction de chaque bloc de base désignent les adresses de branchement, respectivement, des blocs de base 50 et 52. Le symbole « ©3 » désigne l'adresse de branchement d'un autre bloc de base non représenté sur la 20 figure 2. [0059] L'instruction « Branch » suivie d'une adresse de branchement telle que ©2 ou ©3 est une instruction de branchement inconditionnel vers cette adresse de branchement. [0060] Les premières instructions « IV1 » et « IV2 », respectivement, des blocs 50 et 25 52 sont les vecteurs d'initialisation utilisés pour initialiser la construction des valeurs C1 et C2 des signatures, respectivement, des blocs 50 et 52 à l'aide de la fonction Fcs(i,, CO. Ces vecteurs d'initialisation sont codés sur N bits, c'est-à-dire sur le même nombre de bits qu'une instruction. Toutefois, contrairement à une instruction, leur valeur peut être quelconque. En particulier, leur valeur n'a pas à correspondre à celle 30 d'une instruction du jeu d'instructions du microprocesseur 2. Ces vecteurs d'initialisation sont des constantes choisies lors de la génération du code machine 32. Une valeur constante est une valeur qui ne peut pas être modifiée lors de l'exécution du code machine 32 sauf accidentellement comme, par exemple, en cas d'injection de fautes. 35 [0061] Dans les figures et dans la description, le symbole IVk est utilisé pour désigner de façon générale le vecteur d'initialisation d'un bloc de base BBk , où l'indice k est un numéro d'ordre qui identifie sans ambiguïté ce bloc de base parmi l'ensemble des blocs de base de la fonction 32. De plus, dans les cas simples comme celui représenté sur la figure 2 où deux blocs de base se suivent dans l'ordre 40 d'exécution de la fonction 32, l'indice k est aussi utilisé pour indiquer l'ordre dans 14 lequel ces blocs de base sont exécutés. Par exemple, la notation BBk_i est, dans ces cas simples, utilisée pour désigner le bloc de base qui est systématiquement exécuté immédiatement avant le bloc de base BBk. [0062] Ici, le vecteur d'initialisation de chaque bloc de base est choisi de manière à 5 ce que la valeur attendue de la signature de ce bloc de base soit unique pour chaque bloc de base du code machine 32. Par « unique pour chaque bloc de base», on désigne le fait que la probabilité que deux blocs de base du code machine 32 aient la même valeur attendue pour leur signature respective est inférieure à 1 chance sur 100 ou sur 1000. En pratique, la probabilité que deux blocs de base aient la même 10 valeur attendue est généralement beaucoup plus petite. Par exemple, de préférence, cette probabilité est inférieure à Nva/2c-1 ou Nva/2c, OÙ Nva est le nombre de valeurs attendues utilisées dans le code machine, « c » est le nombre de bits utilisés pour coder la valeur maximale des vecteurs d'initialisation en binaire. En particulier, l'expression « unique pour chaque bloc de base» couvre donc le cas où les valeurs 15 attendues des signatures de tous les blocs de base sont systématiquement différentes les unes des autres. Ici, « c » est égal à N. Par exemple, dans une mode réalisation simple, lors de la génération du code 32, les vecteurs d'initialisation de chaque bloc de base sont tirées de façon aléatoire ou pseudo-aléatoire dans l'ensemble {1 ; ...;2"}. 20 [0063] Dans ce mode de réalisation, chaque bloc de base comporte une instruction spécifique désignée dans les figures et dans ce texte par le symbole « Update(v) ». Pour simplifier les figures, cette instruction spécifique est uniquement représentée dans la figure 2 dans le cas du bloc 50. L'instruction « Update(v) » est une instruction du jeu d'instructions du microprocesseur 2. Lorsqu'elle est exécutée par le 25 microprocesseur 2 elle provoque le remplacement de la valeur actuelle du paramètre par une nouvelle valeur. De préférence, la valeur du paramètre v est enregistrée dans la mémoire 29. Ici, la nouvelle valeur est directement contenue dans le code machine à l'intérieur du bloc de base. Comme le vecteur d'initialisation, cette nouvelle valeur est une constante choisie lors de la génération du code machine. Plus 30 précisément, lors de la génération du code 32, la valeur du paramètre v est choisie pour vérifier la relation suivante : Fk_i = Fve, IVk) [0064] Chaque bloc de base comporte au moins une instruction à protéger. Sur la figure 2 et dans ce texte, chaque instruction à protéger est désignée par le symbole i,, où l'indice i désigne le numéro d'ordre de l'instruction à protéger à l'intérieur du bloc 35 de base. L'instruction i, peut être n'importe quelle instruction valable du jeu d'instructions du microprocesseur 2. [0065] Dans ce mode de réalisation, toutes les instructions de tous les blocs de base du code machine 32 sont considérées comme étant des instructions à protéger. Pour simplifier les figures, la présence de ces autres instructions à protéger dans chaque 40 bloc de base est représentée par le symbole « ». En particulier, dans ce mode de 15 réalisation, l'instruction « Udpate(v) » et l'instruction de branchement située à la fin du bloc de base sont aussi des instructions à protéger. [0066] La figure 3 représente un autre agencement possible de plusieurs blocs de base du code 32. Cet agencement est utilisé pour montrer l'intérêt du paramètre v. 5 Ceci est ici illustré dans le cas particulier de deux blocs de base précédents 60 et 62 et d'un bloc de base suivant 64. Ici, les blocs 60 et 64 sont, par exemple, identiques, respectivement, aux blocs 50 et 52. Le bloc 62 est construit comme décrit plus en détail pour le bloc 50 mais la valeur attendue F62 de sa signature est différente de la valeur attendue F60 pour la signature du bloc 60. Dans le cas d'un tel agencement et 10 si le paramètre v n'était pas utilisé, alors il faudrait que les valeurs attendues F60 et F62 vérifient la relation suivante : F6o = F62 = Fvs(IV2), où IV2 est le vecteur d'initialisation du bloc 64. Une telle égalité entre les valeurs attendues F60 et F62 ne peut généralement être obtenue qu'en choisissant de façon appropriée les vecteurs d'initialisation IV1 et IV3. Grâce à l'utilisation du paramètre v dont la valeur est mise à 15 jour lors de l'exécution des blocs 60 et 62, les valeurs attendues F6o et F62 peuvent être différentes tout en restant capable de construire la valeur attendue correcte à partir du même vecteur d'initialisation IV2. Ainsi, l'utilisation du paramètre v relâche les contraintes imposées sur le choix des vecteurs d'initialisation IV1 et IV3. Cela simplifie donc la génération du code 32. 20 [0067] La figure 4 représente un procédé d'exécution du code binaire 30 par le microprocesseur 2. [0068] Le procédé débute par une étape 150 de fourniture du code binaire 30 dans la mémoire 4. Pour cela, par exemple, le microprocesseur 2 recopie la copie 40 à l'intérieur de la mémoire 4 pour obtenir le code binaire 30 enregistré dans la mémoire 25 4. [0069] Ensuite, lors d'une phase 152, le microprocesseur 2 exécute le code binaire 30 et, en particulier, le code machine 32. [0070] Pour cela, lors d'une étape 154, le chargeur 18 charge les instructions à exécuter les unes après les autres dans la file 22. 30 [0071] Ensuite, si l'instruction chargée ne suit pas immédiatement une instruction de branchement, alors, lors d'une étape 156, cette instruction est décodée puis l'unité 10 l'exécute. Dès lors, lorsqu'une instruction « Update(v) » est chargée, celle-ci est exécutée et la valeur actuelle de paramètre v dans la mémoire 29 est remplacée par une nouvelle valeur. 35 [0072] En parallèle de l'étape 156, lors d'une étape 157, à chaque fois qu'une instruction à protéger est chargée dans la file 22, le module 28 construit la nouvelle valeur Ck de la signature du bloc de base en cours d'exécution. Pour cela, il met en oeuvre la relation Ck := Ck), c'est-à-dire dans le cas particulier décrit ici, la relation Ck:=Fki(Iiii3OCk), où les différents symboles ont été définis précédemment. 40 Ainsi, la valeur Ck de la signature du bloc BBk se construit au fur et à mesure que les 16 instructions de ce bloc de base sont exécutées par le microprocesseur 2. Typiquement, l'étape 157 est exécutée avant que l'instruction chargée soit exécutée par l'unité 10. Par exemple, elle est exécutée avant que l'instruction chargée soit décodée. 5 [0073] Lorsque l'instruction chargée est l'instruction de branchement qui délimite la fin du bloc de base précédent, alors en réponse : - lors d'une étape 158, le module 28 vérifie l'intégrité du bloc de base précédent, puis, - lors d'une étape 160, le module 28 initialise la construction de la signature du bloc de base suivant. 10 [0074] Par la suite, on note BBk_i et BBk, respectivement, le bloc de base précédent et le bloc de base suivant. [0075] L'étape 158 débute par une opération 162 lors de laquelle le microprocesseur 2 charge le vecteur d'initialisation IVk qui se trouve à l'adresse de branchement du bloc BBk comme s'il s'agissait d'une instruction à exécuter par l'unité 10. Toutefois, 15 après l'exécution d'une instruction de branchement, l'instruction chargée est transmise au module 28 et non pas à l'unité 10. [0076] En réponse, lors d'une opération 164, le module 28 calcule la valeur attendue Fk_i à l'aide de la relation suivante : Fk_i:= Fvs(v, IVk), c'est-à-dire ici à l'aide de la relation Fk_i:=Fki(vCDIVk), où « v » est la valeur actuelle du paramètre v chargée lors 20 de l'exécution de l'instruction « Update(v) » contenue dans le bloc BBk_i. [0077] Ensuite, lors d'une opération 166, le module 28 compare la valeur construite Ck-1 de la signature du bloc BBk_i à la valeur attendue Fk_i calculée pour ce même bloc. Si ces valeurs correspondent, c'est-à-dire ici si elles sont identiques, alors l'intégrité du bloc BBk_i est confirmée. De plus, étant donné que pour calculer la valeur attendue 25 Fk_i, la valeur du vecteur IVk contenue dans le bloc BBk est utilisée, la valeur Fk-1 calculée ne peut correspondre à la valeur Ck_i que si l'intégrité du flot de contrôle n'a pas été altérée. Par conséquent, lors de l'opération 166, le module vérifie, en même temps et en seule opération de comparaison, l'intégrité du flot de contrôle et l'intégrité du bloc BBk_i. 30 [0078] Si l'intégrité du bloc BBk_i et l'intégrité du flot de contrôle sont confirmées, l'étape 158 s'achève et le procédé se poursuit par l'exécution de l'étape 160. Dans le cas contraire, le procédé se poursuit par une étape 170 de signalement, par le microprocesseur 2, d'une faute d'exécution. [0079] Lors de l'étape 160, le module 28 initialise la construction de la valeur Ck de 35 la signature du bloc BBk avec le vecteur IVk. Autrement ici, le module 28 réalise l'opération suivante : Ck.= IVk. [0080] Lors de l'exécution du code machine 32, si des attaques conduisent à altérer une instruction à protéger ou à modifier le flot de contrôle, le microprocesseur 2 signale, lors de l'étape 170, une faute dans l'exécution du code machine 32. En 40 réponse à un tel signalement, lors d'une étape 172, par exemple, le microprocesseur 17 2 met en oeuvre une ou plusieurs contre-mesures. De très nombreuses contre-mesures sont possibles. Les contre-mesures mises en oeuvre peuvent avoir des degrés de sévérité très différents. Par exemple, les contre-mesures mises en oeuvre peuvent aller d'un simple affichage d'un message d'erreur sans interrompre 5 l'exécution normale du code machine 32 jusqu'à une mise hors service définitive du microprocesseur 2. Le microprocesseur 2 est considéré comme étant hors service lorsqu'il est définitivement placé dans un état où il est incapable d'exécuter un quelconque code machine. Entre ces degrés de sévérité extrêmes, il existe de nombreuses autres contre-mesures possibles telles que : 10 - l'indication par l'intermédiaire d'une interface homme-machine de la détection des fautes, - l'interruption immédiate de l'exécution du code machine 32 et/ou sa réinitialisation, et - la suppression du code machine 32 de la mémoire 4 et/ou la suppression de la 15 copie 40 de sauvegarde et/ou la suppression des données secrètes. [0081] La figure 5 représente un compilateur 190 apte à générer automatiquement le code machine 32 à partir d'un code source 192. À cet effet, le compilateur 190 comporte typiquement un microprocesseur 194 programmable et une mémoire 196. La mémoire 196 contient les instructions et les données nécessaires pour, 20 lorsqu'elles sont exécutées par le microprocesseur 194, générer automatiquement le code machine 32 à partir d'un code source 192. En particulier, lors de la compilation du code source 192, le microprocesseur 194 introduit automatiquement les instructions « Update(v) » et les vecteurs d'initialisation IVk appropriés dans le code machine 32. La conception et la réalisation d'un tel compilateur sont à la portée de 25 l'homme du métier à partir des explications données dans cette description. [0082] Variantes du code binaire : [0083] Il est possible de garantir l'unicité de la valeur attendue Fk pour chaque bloc de base par d'autres moyens qu'un simple tirage aléatoire. Par exemple, lors de la génération du code machine, la valeur attendue de la signature de chaque bloc de 30 base est établie en fonction des valeurs attendues déjà utilisées pour d'autres blocs de base. Pour cela, à titre d'illustration, lors de la génération du code machine les opérations suivantes sont exécutées dans l'ordre : a) La valeur attendue pour le bloc de base actuellement traité est d'abord construite en tirant aléatoirement le vecteur d'initialisation. 35 b) La valeur attendue de la signature du bloc de base actuellement traité est calculée puis comparée aux valeurs attendues construites et mémorisées pour les blocs de base déjà traités. c) Si la valeur attendue du bloc de base actuellement traité est égale à l'une des valeurs attendues déjà construites et mémorisées, les opérations a) à c) sont 18 réitérées. Dans le cas contraire, la valeur attendue construite pour ce bloc de base actuellement traité est mémorisée. La réitération des opérations a) à c) conduit à tirer de façon aléatoire un nouveau vecteur d'initialisation pour le bloc de base traité. Plutôt que de tirer aléatoirement un 5 nouveau vecteur d'initialisation, il est aussi possible de modifier la valeur du paramètre v ou de modifier certaines instructions de ce bloc de base sans en modifier le fonctionnement. Par exemple, il est possible de changer les registres utilisés, ou d'introduire une opération qui ne fait rien lorsqu'elle est exécutée, ou de réexprimer une séquence d'instructions en une nouvelle séquence d'instructions différente mais 10 sémantiquement équivalente, c'est-à-dire produisant le même résultat. [0084] Dans une variante simplifiée, le vecteur d'initialisation a la même valeur et cela quel que soit le bloc de base à l'intérieur duquel elle se situe. Il suffit alors que les blocs de base ne comportent pas toujours les mêmes instructions à protéger pour que les valeurs attendues des signatures de différents blocs de base soient 15 différentes. Dès lors, cela permet toujours de détecter un grand nombre de fautes d'exécution. [0085] Variantes de l'appareil : [0086] La mémoire 4 peut aussi être une mémoire non volatile. Dans ce cas, il n'est pas nécessaire de copier le code binaire 30 à l'intérieur de cette mémoire avant le 20 lancement de son exécution puisqu'il s'y trouve déjà. [0087] En variante, la mémoire 4 peut aussi être une mémoire interne intégrée à l'intérieur du microprocesseur 2. Dans ce dernier cas, elle est réalisée sur le même substrat que les autres éléments du microprocesseur 2. Enfin, dans d'autres configurations, la mémoire 4 se compose de plusieurs mémoires dont certaines sont 25 des mémoires internes et d'autres des mémoires externes. [0088] Variantes de construction de la signature : [0089] En variante, seules certaines instructions de chaque bloc de base sont des instructions à protéger. Dans ce cas, la valeur Ck de la signature est construite sans prendre en compte toutes les valeurs de toutes les instructions du bloc de base mais 30 seulement certaines de ces instructions. Ainsi, selon une première alternative, la valeur Ck est construite en prenant en compte uniquement les instructions dont le numéro d'ordre, dans le bloc de base BBk, est pair. [0090] Selon une deuxième alternative, seules les instructions du bloc de base BBk dont l'opcode comporte un bit ou un groupe de bits ayant une valeur spécifique sont 35 utilisées pour construire la valeur Ck de la signature de ce bloc. Les autres instructions de ce bloc, pour lesquels le bit ou le groupe de bits de l'opcode a une valeur différente de cette valeur spécifique, ne sont pas prises en compte pour la construction de la valeur Ck. Par exemple, le jeu d'instruction du microprocesseur est modifié pour y ajouter un bit supplémentaire qui, lorsqu'il prend la valeur « 1 », 40 indique que cette instruction est une instruction à protéger qui doit être prise en 19 compte pour la construction de la valeur Ck. À l'inverse, si ce bit supplémentaire prend la valeur « 0 », cette instruction n'est pas une instruction à protéger et ne doit donc pas être prise en compte pour la construction de la valeur Ck de la signature. [0091] Selon une troisième alternative, une instruction spécifique est ajoutée au jeu 5 d'instructions du microprocesseur 2. Lorsque cette instruction spécifique est exécutée par ce microprocesseur, elle indique au microprocesseur que les M prochaines instructions du bloc de base ne sont pas des instructions à protéger et ne doivent donc pas être prises en compte pour la construction de la valeur Ck de la signature. Typiquement, M est un nombre entier supérieur ou égal à 1. 10 [0092] Selon une quatrième alternative, c'est un bit spécifique d'un registre de statut ou de contrôle du microprocesseur qui indique si l'instruction chargée est ou non une instruction à protéger. Plus précisément, lorsque ce bit spécifique prend une valeur prédéterminée, l'instruction chargée est prise en compte pour la construction de la valeur Ck de la signature. Si ce bit spécifique prend une valeur différente de cette 15 valeur prédéterminée, alors l'instruction chargée n'est pas prise en compte pour la construction de la valeur Ckde la signature. [0093] D'autres fonctions Fcs0 peuvent être utilisées. En particulier, la fonction Fcs() n'est pas nécessairement une fonction de chiffrement mettant en oeuvre une clé kl secrète. Ainsi, dans un autre mode de réalisation, la fonction Fcs() est une simple 20 opération logique ou modulaire entre les valeurs 1i11 et Ck. Par exemple, dans un mode de réalisation particulièrement simple, la fonction Fcs() est une simple opération « OU exclusif ». La valeur Ck est alors construite en utilisant la relation suivante : Ck:= 1i,1 (DCk. [0094] Dans un autre exemple de réalisation intéressant, la fonction Fcs0 est un 25 homomorphisme entre deux ensembles algébriques A et B. L'ensemble A est doté d'une opération notée « + » et l'ensemble B est doté d'une opération notée « * ». Cet homomorphisme est tel que FOE (x+y) = Fcs (x)*Fcs (y), où x et y sont des nombres appartenant à l'ensemble A. De plus, cette fonction homomorphe FOE est injective et les opérations « + » et « * » sont des opérations commutatives et inversibles. Lorsque 30 la fonction Fcs() est un homomorphisme, la valeur Ck-1 de la signature est par exemple construite de la façon suivante : Co, := Fcs (1Vk_1), C1, k-1 Fcs (1101) * CO, k-1, 02, k-1.= FCS I * C1, k-1, 35 - - - Cn, Fcs I in * k-1 où - k-1 désigne la valeur Ck-1 au cours de la j-ième itération de l'opération de construction de la valeur C k-1, - Ck-1 est égal à C0,1,1. 20 [0095] À cause du fait que la fonction FcsO est un homomorphisme, la valeur Ck-1 construite peut aussi s'écrire sous la forme suivante : Ck_1:= Fcs (IVk-1 + I io I + I il I + + I in I ). Par ailleurs, la fonction Fvs() est identique à la fonction Fcs() et le calcul de la valeur Fk_i est réalisé à l'aide de la relation suivante : Fcs(V + IVk). Dès lors, la 5 valeur du paramètre v peut être calculée de la façon suivante : v:= + I io + I il + ... I in I - IVk, où le symbole « - » désigne l'inverse de l'opération « + ». Par conséquent, la valeur du paramètre v peut être déterminée sans qu'il soit nécessaire d'inverser la fonction Fcs(). De façon similaire, si la valeur du paramètre v est imposée, le vecteur d'initialisation est déterminé à l'aide de la relation suivante : IVk:= 10 + I io I + I i1 I + in I - y. Autrement dit, lorsque la fonction Fcs() est un homomorphisme, la fonction Fcs n'a pas besoin d'être inversible. De plus, la même fonction Fcs() est utilisée pour construire la valeur Ck-1 et pour calculer la valeur attendue Fk-1. Ce qui a été expliqué ici est valable pour n'importe quelles opérations « + » et « * » et n'est pas limité, par exemple, aux opérations d'addition et de 15 multiplication. En particulier, ce mode de réalisation permet d'utiliser en tant que fonction Fcs0 des fonctions non inversibles telles que certaines fonctions de hachage hash function » en anglais) ou certaines fonctions de chiffrement asymétrique pour lesquelles seule la clé publique ou seule la clé privée est connue. À titre d'illustration, les fonctions qui suivent sont des homomorphismes qui conviennent pour réaliser la 20 fonction Fcs() : - la fonction exponentielle « e » car ex+Y = ex * eY, où « + » et « * » sont, respectivement, les opérations d'addition et de multiplication, - la fonction logarithme « log » car log(x * y) = log (x) + log (y), où « + » et « * » sont, respectivement, les opérations d'addition et de multiplication, 25 - la fonction « E » de chiffrement de Pallier car E (x) * E (y) = E (x+y mod(N)), où « + » et «* » sont, respectivement, les opérations d'addition modulaire (modulo N) et de multiplication, - la fonction « E » de chiffrement connu sous le terme « Unpadded RSA » avec une clé publique k exprimée avec un modulo m est une exponentiation « e » telle que 30 e(x) = xe mod m, car E (x) * E (y) = E (x*y), où « * » est l'opération de multiplication, - la fonction « E » de chiffrement de Goldwasser-Micali car E (x) * E (y) = E (x CD y), où « CD » et « * » sont, respectivement, les opérations « ou exclusif » et la multiplication, - les fonctions de chiffrement homomorphes. [0096] Dans le cas où la fonction Fcs() est un homomorphisme, avantageusement, le 35 vecteur d'initialisation IVk-1 enregistré au début du bloc BBk_i est remplacé par un vecteur d'initialisation Fcs(IN/k_i), c'est-à-dire par la valeur Co,k-1. Dans ce cas, la construction de la valeur Ck-1 débute directement par l'opération C1,k_1:= Fcs( I lo ) * Co,k-i, et non plus par l'opération Co,k_1:= Fcs(lVk_i). Cela limite donc le nombre d'opérations à réaliser pour construire la valeur Ck-1. De plus, lorsque la fonction Fcs() 40 est une fonction de chiffrement asymétrique, cela peut être utilisé pour garantir soit 21 l'authenticité du code binaire exécuté soit pour garantir l'authenticité du module 28. Plus précisément, une première possibilité consiste à utiliser une clé publique kp pour construire la valeur Ck. Dans ce cas, la valeur Ck est construite à l'aide de la relation suivante : Ck Ck), où FkpQ est la fonction de chiffrement asymétrique 5 paramétrée avec la clé publique kp. Dans ce cas, le vecteur d'initialisation placé au début du bloc BBk+i est la valeur Co,k+1, c'est-à-dire la valeur Fkp(IVk+1). Pour calculer la valeur attendue Fk, le module 28 déchiffre la valeur Co,k+i à l'aide de la fonction de déchiffrement Dks() correspondant à la fonction Fkp(). La fonction Dks() est paramétrée par une clé secrète ks connue seulement du module 28. Le module 28 obtient ainsi le 10 vecteur IVk+1. Puis, le module calcule la valeur Fk, par exemple comme précédemment décrit, c'est-à-dire à l'aide de l'opération Fk = Fvs(v, IVk+1). Par conséquent, la vérification de l'intégrité du code machine ne peut être réalisée que par un module 28 muni de la clé ks alors que le code machine peut être généré par tout compilateur ayant accès à la clé publique kp. A l'inverse, la valeur Ck peut être construite à l'aide 15 de la relation suivante : Ck:= Dks(ii, Ck). Dans ce cas, le vecteur d'initialisation placé au début du bloc BBien est la valeur Co,k+i égale à Dks(IVk+1). Pour calculer la valeur attendue Fk, le module 28 chiffre avec la clé publique kp la valeur Co,k+i. Il obtient ainsi la valeur du vecteur IVk+1. Puis, le module 28 calcule la valeur Fk à l'aide de l'opération Fk = Fvs(v, IVk+1). Par conséquent, dans ce dernier mode de réalisation, la vérification 20 de l'intégrité du code machine peut être réalisée par tout module 28 muni de la clé kp alors que le code machine peut être généré uniquement par un compilateur muni de la clé privée ks. [0097] Dans une autre variante la fonction Fv,() est une fonction bijective différente de l'identité qui à chaque code d'une instruction en langage machine associe une 25 valeur numérique respective. Par exemple, choisir une fonction Fv,() différente de l'identité peut avoir un intérêt lorsque les instructions du jeu d'instructions ont des tailles différentes. Dans ce cas, une fonction Fv,O, différente de l'identité, est utilisée pour associer à chaque instruction de ce jeu d'instruction, une valeur numérique choisie dans un ensemble où toutes les valeurs numériques ont la même taille. 30 [00981 Variantes de la fonction Fvs0 : [0099] En variante, la fonction Fvs() est différente de la fonction FcsQ. Par exemple, dans une variante simplifiée, la fonction Fvs() est la fonction identité. Dans ce cas, le vecteur d'initialisation IVk situé au début du bloc BBk est égal à la valeur attendue Fk-1 du bloc BBk_i. De plus, lorsque ce vecteur d'initialisation IVk est utilisé pour initialiser la 35 construction de la signature du bloc BBk, en absence de faute d'exécution, cela revient à initialiser la construction de la valeur Ck avec la valeur Ck-1. Ainsi, la construction de la valeur de la signature n'est pas ré-initialisée après l'exécution d'une instruction de branchement. [00100] Dans tous les modes de réalisation décrits ici, la fonction Fvs() peut être 40 remplacée par une fonction Fvs() qui n'a qu'un seul argument à savoir le vecteur 22 d'initialisation IVk. On a alors Fk-1 Fvs(IVk). Dans ce cas, pour relâcher les contraintes sur le choix des vecteurs d'initialisation IVk, la valeur Ck-1 est construite à partir des valeurs des instructions à protéger du bloc BBk_i et à partir du paramètre v. Par exemple, la valeur Ck_i_ est construite comme décrit précédemment sauf qu'on 5 ajoute l'opération supplémentaire suivante : Ck_i Fcs(Ck_i, v). L'exécution de cette opération supplémentaire est par exemple déclenchée lorsque l'instruction de branchement du bloc BBk_i est chargée par le microprocesseur 2. Dans ce mode de réalisation, la fonction Fvs() peut être la fonction identité. [00101] Le paramètre v peut être omis. Par exemple, c'est le cas si chaque bloc de 10 base a au plus un seul prédécesseur et un seul bloc de base suivant. [00102] Une autre possibilité pour ne pas utiliser le paramètre v tout en relâchant les contraintes sur le choix des vecteurs d'initialisation consiste, lors de l'opération 166, à comparer la valeur Ck-1 aux différentes valeurs attendues possibles pour les blocs de base précédents. Par exemple, dans le cas de l'agencement de la figure 3, après 15 l'exécution de l'instruction de branchement vers le bloc 64, lors de l'opération 166, le module 28 compare successivement la valeur Ck-1 à la valeur attendue F60 de la signature du bloc 60 puis à la valeur attendue F62 de la signature du bloc 62. Si la valeur Ck-1 construite ne correspond à aucune des valeurs F60 et F62, l'étape 170 est exécutée. Si, au contraire, la valeur Ck-1 est égale à l'une des valeurs F60 et F62, alors 20 l'étape 160 est exécutée. Lors de l'opération 164, le module 28 calcule les valeurs F60 et F62 à partir, respectivement, de vecteurs d'initialisation IV21 et IV22 situés tous les deux au début du bloc 64. Par exemple, le vecteur d'initialisation IV21 est enregistré à l'adresse ©2 et le vecteur d'initialisation IV22 est enregistré à l'adresse immédiatement suivante. Dans ce cas, le nombre N,v de lignes consacrées au 25 stockage du ou des vecteurs d'initialisation au début de chaque bloc de base est constant. Ainsi, le microprocesseur peut déterminer simplement où débutent les instructions à exécuter dans chacun des blocs de base. Alternativement, le nombre N,v peut aussi être un paramètre réglable du fonctionnement du microprocesseur. [00103] En variante, la construction de la valeur Ck est initialisée non pas directement 30 avec le vecteur IVk mais avec une valeur g(IVk) où g est une fonction prédéterminée connue du module 28 et différente de la fonction identité. Par exemple, la fonction g peut être un « ou exclusif » entre le vecteur d'initialisation IVk et une constante connue seulement du module 28 et enregistrée dans la mémoire 29. [00104] Variantes de l'instruction « Update(v) » : 35 [00105] L'instruction « Update(v) » peut être remplacée par une instruction « Update(reg) >>, où « reg » est l'adresse d'un registre. Lorsque le microprocesseur exécute l'instruction « Update(reg) », il remplace la valeur actuelle du paramètre par la valeur contenue dans le registre situé à l'adresse « reg ». [00106] L'instruction « Update(v) » peut aussi être remplacée par une instruction 40 Update (©off) où ©off est une valeur d'offset par rapport à une adresse fixe 23 prédéterminée gnit. Lorsque le microprocesseur 2 exécute l'instruction « Update(©off) », il remplace la valeur actuelle du paramètre v par la valeur contenue dans un mot machine situé à l'adresse ©nt + ©off. [00107] L'instruction « Update(v) » peut aussi être remplacée par deux instructions 5 « Update(v,') » et « Update(vhigh) ». Lorsque le microprocesseur exécute l'instruction « Update(v10W) », il remplace les bits de poids faible de la valeur actuelle du paramètre - par la valeur v10W. Lorsque le microprocesseur exécute l'instruction « Update(vhigh) », il remplace les bits de poids fort de la valeur actuelle du paramètre v par la valeur Vhigh- 10 [00108] Ces différents modes de réalisation de l'instruction « Update(v) » sont en particulier utiles si la valeur du paramètre v est codée sur le même nombre de bits que les instructions du microprocesseur. Dans ce cas, il n'est pas possible de coder directement la nouvelle valeur du paramètre v dans cette instruction. [00109] Dans une autre variante, la valeur du paramètre v n'est pas directement 15 contenue à l'intérieur du bloc de base mais déduite d'une valeur v* contenue dans ce bloc de base. Par exemple, la valeur v* est un cryptogramme de la valeur du paramètre v obtenu en chiffrant cette valeur du paramètre v à l'aide d'une fonction de chiffrement, par exemple symétrique. Dans un mode de réalisation simplifié, la valeur v* est égale à Fkl(v). Dans ce cas, lorsque l'instruction « Update(v) » est chargée, la 20 valeur v* est transmise au module 28 qui la déchiffre à l'aide de la clef k1 et de la fonction Fia-1 pour obtenir la nouvelle valeur du paramètre v. Ensuite, cette nouvelle valeur du paramètre v est stockée dans la mémoire 29 à la place de la précédente. [00110] Un bloc de base précédent peut se terminer par une instruction de branchement conditionnelle vers un premier bloc de base si la condition est vérifiée 25 et, en alternance, vers un second bloc de base sinon. Dans ce cas les premier et second blocs de base suivants peuvent comporter à leurs adresses de branchement respectives le même vecteur d'initialisation. Ainsi, ce qui a été décrit ici s'applique sans aucune modification supplémentaire pour gérer ce type d'agencement des blocs de base du code 32. Alternativement, s'il est souhaitable que les vecteurs 30 d'initialisation des premier et second blocs de base suivants soient différents, alors une instruction « Update(v1) » et une instruction « Update(v2) » sont introduites dans le bloc de base précédent. Ces instructions sont alors paramétrées par une condition telle que l'instruction « Update(v1) » est exécutée uniquement si le bloc de base suivant est le premier bloc de base et l'instruction « Update (v2) » est exécutée 35 uniquement si le bloc de base suivant est le second bloc de base suivant. Le choix des valeurs v1 et v2 du paramètre v est alors réalisé comme décrit précédemment de manière à vérifier la condition Fk_i = Fvs (v1, IV]) = Fvs(v2, IV2) où IV1 et IV2 sont les vecteurs d'initialisation, respectivement, des premier et second blocs suivants. Ce mode de réalisation est utilisable avec les microprocesseurs capables d'exécuter des 40 instructions de façon conditionnelle, c'est-à-dire uniquement si une condition 24 paramétrable est satisfaite. Dans le cas contraire, le microprocesseur n'exécute pas cette instruction. De préférence, la condition testée est la même que celle testée par l'instruction de branchement conditionnelle. De plus, grâce à cela, il est possible de déclencher le signalement d'une faute d'exécution si le flot d'instructions est détourné 5 vers le premier bloc de base alors que la condition n'est pas vérifiée. [00111] 11 existe encore d'autre alternative au mode de réalisation du paragraphe précédent. Par exemple, l'ensemble 12 peut contenir un registre dédié qui contient une valeur qui varie en fonction de la condition d'un branchement conditionnel. Plus précisément, sa valeur n'est pas la même selon que cette condition est vérifiée ou 10 non. Ce registre dédié est souvent appelé « registre de statut ». Dans une architecture ARM, ce registre dédié est connu sous l'acronyme CPSR (« Current Program Statut Register »). Le CPSR contient notamment les bits suivants : - le bit N qui prend la valeur « 1 » si le résultat de la condition est négatif et la valeur « 0 » sinon, 15 - le bit Z qui prend la valeur « 1 » si le résultat de la condition est nul et « 0 » sinon, - le bit C qui prend la valeur « 1 » si le résultat de la condition a une retenue et sinon la valeur « 0 », - le bit V qui prend la valeur « 1 » si le résultat de la condition a débordé et sinon la valeur « 0 ». 20 [00112] Ici, la valeur de ces quatre bits N, Z, C et V est collectivement désignée par le terme « valeur NZCV ». Selon la condition à vérifier, seule une partie des bits de la valeur NZCV est utile et les valeurs des autres bits doivent être ignorées. Pour cela, la valeur d'un masque M identifiant la position des bits utiles est chargée dans un registre du microprocesseur 2 avant l'exécution de l'instruction de branchement 25 conditionnelle. Le bloc de base précédent comporte donc à cet effet une instruction de chargement de ce masque M. Ce masque M, comme la valeur NZCV attendue, est déterminé lors de la génération du code machine. Ici, le masque M comporte quatre bits. Un bit du masque M prend la valeur « 1 » pour indiquer la position d'un bit utile dans la valeur NZCV. Dans ce cas, la valeur du paramètre y est calculée à l'aide 30 de la relation suivante : v:= h(v1, c, M), où : - v1 est une valeur chargée par une instruction « update(vi) » contenue dans le bloc de base précédent, - « c » est la valeur NZCV, - « M » est la valeur du masque M. 35 Par exemple, la fonction h(v1, c, M) est la suivante : h(v1, c, M) = v1 CD extend(c A M), où - le symbole « A » désigne l'opération « ET » logique, et - extend(...) est une fonction qui renvoie un nombre codée sur N bits à partir du nombre c A M codé sur quatre bits. 25 Dans ce mode de réalisation, la valeur du paramètre v n'est donc pas la même si la condition de l'instruction du branchement conditionnelle est vérifiée ou non. Ainsi, selon que l'exécution du code machine se poursuit par l'exécution du premier ou du second bloc de base, la valeur du paramètre v n'est pas la même. 5 [00113] Variantes du déclenchement du contrôle d'intégrité : [00114] Il n'est pas indispensable que le contrôle de l'intégrité du bloc de base précédent et du flot de contrôle soit déclenché systématiquement et immédiatement après l'exécution d'une instruction de branchement. Par exemple, en variante, la vérification de l'intégrité n'est pas déclenchée par une instruction de branchement 10 mais par une instruction spécifique appelée ici « Verify ». Lorsque le microprocesseur rencontre dans le code machine l'instruction « Verify », il exécute alors les opérations suivantes : 1) Il lit la valeur de l'instruction qui suit immédiatement l'instruction « Verify ». Cette valeur lue est un vecteur d'initialisation qui a été construit lors de la génération du 15 code machine pour vérifier, comme décrit précédemment, l'intégrité du bloc de base et l'intégrité du flot de contrôle. 2) Ensuite, le microprocesseur compare la valeur construite Ck de la signature à la valeur Fk attendue calculée à partir de la valeur du paramètre v et du vecteur d'initialisation 'Vien comme précédemment décrit. 20 3) Ensuite, la valeur Ck+1 de la signature est initialisée à l'aide du vecteur IVk+1 comme décrit précédemment. 4) Enfin, le compteur ordinal est incrémenté pour pointer sur l'instruction située immédiatement après le vecteur IVk+1. [00115] Une telle instruction « Verify » peut être placée à n'importe quel endroit à 25 l'intérieur du bloc de base BI3k,1 et non pas seulement au début de ce bloc de base. Dès lors, la valeur construite de la signature peut être fonction des instructions à protéger présentes entre cette occurrence de l'instruction « Verify » et la précédente instruction « Verify » exécutée. Dans ce cas, la valeur Ck peut dépendre à la fois d'instructions à protéger contenues dans le bloc de base précédent et d'instructions à 30 protéger également contenues dans le bloc de base suivant. Typiquement, l'instruction « Verify » est une instruction supplémentaire ajoutée au jeu d'instructions du microprocesseur 2. [00116] Dans le même mode de réalisation, il est aussi possible de déclencher le contrôle d'intégrité à la fois en réponse au chargement d'une instruction de 35 branchement et en réponse à l'exécution d'une instruction « verify ». [00117] Dans un autre mode de réalisation, c'est une valeur spécifique d'un bit ou d'un groupe de bits des opcodes du jeu d'instructions du microprocesseur 2 qui déclenche la vérification de l'intégrité et l'initialisation du calcul de la signature du bloc de base suivant. Par exemple, à cet effet, le jeu d'instructions du microprocesseur 2 40 est modifié pour que chaque opcode comporte un bit supplémentaire ou un groupe de 26 bits supplémentaires. Typiquement, si le microprocesseur détecte que la valeur de ce bit supplémentaire dans l'opcode chargé est égale à « 1 », alors il déclenche la vérification de l'intégrité et l'initialisation de la signature du bloc de base suivant avant d'exécuter cette instruction. Si au contraire, la valeur du bit supplémentaire de 5 l'opcode chargé est égale à 0, le microprocesseur 2 ne déclenche pas ces opérations de vérification de l'intégrité et d'initialisation de la signature du bloc de base suivant. [00118] Dans les modes de réalisation où la vérification de la valeur construite est déclenchée par une instruction spécifique, telle que l'instruction « verify », ou par une valeur spécifique d'un bit ou d'un groupe de bits des opcodes, les instructions de 10 branchement à la fin des blocs de base peuvent être des instructions de branchement implicites. [00119] L'initialisation de la valeur Ck du bloc de base suivant et le contrôle d'intégrité ont été décrits jusqu'à présent comme étant déclenchés par la même instruction du code machine. Toutefois, l'initialisation de la valeur Ck et le déclenchement du 15 contrôle de l'intégrité peuvent être déclenchés par des instructions différentes du code machine. Dans ce cas, ces deux opérations ne sont alors pas nécessairement réalisées immédiatement l'une après l'autre. Par exemple, l'initialisation de la signature du bloc de base suivant peut être déclenchée en réponse à l'exécution d'une instruction de branchement et la vérification de l'intégrité peut être déclenchée 20 seulement lorsqu'une instruction « Verify » est rencontrée dans le bloc de base en cours d'exécution. [001201Autres variantes : [00121] Dans tous les modes de réalisation, les combinaisons de deux valeurs, tels que la valeur actuelle du paramètre v avec le vecteur d'initialisation IVk, n'est pas 25 nécessairement réalisée avec un « ou exclusif ». Par exemple, en variante, le « ou exclusif » est remplacé par une opération d'arithmétique modulaire. [00122] Ici, le vecteur d'initialisation IVk est d'abord choisi puis la valeur du paramètre est déterminée pour que, en absence de faute d'exécution, les valeurs Ck et Fk correspondent. Toutefois, tous les modes de réalisation décrit ici peuvent être 30 adaptés pour faire l'inverse, c'est-à-dire fixer d'abord la valeur du paramètre v, puis calculer le vecteur d'initialisation IVk pour que, en absence de faute d'exécution, les valeurs Ck et Fk correspondent. [00123] Il est possible d'ajouter automatiquement des instructions supplémentaires de branchement inconditionnel au milieu d'un bloc de base pour le diviser en plusieurs 35 blocs de base successifs. Cela permet notamment de déclencher plus fréquemment la vérification de l'intégrité du code machine. [00124] Dans une autre variante, la valeur Ck n'est pas initialisée à partir du vecteur d'initialisation IVk mais à partir d'un autre vecteur d'initialisation IVKbis. Le vecteur IVKbis est indépendant du vecteur IVk. Comme le vecteur IVk, le vecteur IVkb,s est enregistré 40 dans le code du bloc de base BBk. Par exemple, le vecteur IVkbis est 27 systématiquement enregistré après le vecteur IVk et chargé dans la mémoire 29 immédiatement après le chargement du vecteur IVk. Dans ce cas, les opérations de vérification de la valeur Ck-1 et d'initialisation de la valeur Ck ne sont pas systématiquement réalisées en même temps et en utilisant le même vecteur 5 d'initialisation. Par exemple, l'initialisation de la valeur Ck peut être déclenchée par une instruction spécifique au milieu du bloc de base BBk et non pas nécessairement située au début de ce bloc de base BBk. La vecteur IVkbis est alors de préférence choisi pour être unique pour chaque bloc de base. Par exemple, il est tiré de façon aléatoire ou pseudo-aléatoire lors de la compilation du code machine. 10 [00125] Dans une autre variante, le code machine et en particulier les blocs de base sont instrumentés pour qu'une erreur d'exécution dans un branchement conditionnel puisse être détectée. Pour cela, le code machine est modifié comme décrit en référence aux figures 5 et 6 de la demande de brevet déposée par le présent déposant le 11 avril 2017 sous le n°FR1753175. 15 [00126] Il est possible d'ajouter dans le code machine des instructions d'activation et de désactivation d'un mode sécurisé lorsqu'elles sont exécutées par le microprocesseur. Dans le mode sécurisé, l'intégrité des blocs de base et du flot de contrôle est vérifiée comme décrit ici. Lorsque le mode sécurisé est désactivé, l'intégrité des blocs de base et du flot de contrôle n'est pas vérifiée. Ainsi, des 20 portions du code machine peuvent être sécurisées tandis que d'autres portions ne le sont pas. [00127] Les différents modes de réalisation décrits ici peuvent être combinés ensemble. [001281Avantages des modes de réalisation décrits ici : 25 [00129] Le module 28 compare la valeur construite Ck-1 à la valeur Fk_i. La valeur Fk_i est déterminée lors de la génération du code machine 32. Ainsi, si une instruction à protéger du bloc BBk-1 est modifiée lors de l'exécution du code machine, le module 28 est capable de détecter et signaler cette faute. [00130] De plus, la valeur attendue Fk_i peut seulement être calculée à partir d'un 30 vecteur d'initialisation IVk qui se trouve dans le bloc de base suivant BBk. Dès lors, si le flot de contrôle est modifié lors de l'exécution du code machine 32 et que le bloc de base suivant BBk est remplacé par un autre bloc de base BBI différent, le vecteur d'initialisation IVt chargé à partir du bloc BBt est différent du vecteur d'initialisation IVk. Dès lors, la valeur attendue Ft calculée pour la signature du bloc BBk-1 à partir du 35 vecteur IVt est différente de la valeur initialement attendue Fk_i. Il est alors très peu probable que la valeur Ck-1 corresponde à la valeur Ft. Ainsi, le module 28 est aussi capable de détecter une modification du flot de contrôle. Pour faire cela, on notera que ce sont les mêmes données, c'est-à-dire les vecteurs d'initialisation contenus dans les blocs de base, qui sont utilisées pour faire ces deux vérifications. À cause de 40 cela, les procédés décrits ici sont plus simples que les procédés connus tout en 28 restant capables de vérifier à la fois l'intégrité du code machine et l'intégrité du flot de contrôle. En particulier, la vérification de l'intégrité du flot de contrôle ne nécessite pas de modifications supplémentaires du code machine en plus de celles déjà nécessaires pour vérifier l'intégrité du code machine. La vérification de l'intégrité du 5 flot de contrôle ne nécessite pas non plus l'exécution par le module 28 de traitement supplémentaire qui ne serait pas utile si seule l'intégrité du code machine était vérifiée. [00131] Le fait d'utiliser le même vecteur d'initialisation à la fois pour calculer la valeur Fk-1 et pour initialiser la valeur Ck renforce la sécurité du procédé. En effet, un 10 attaquant peut essayer de modifier les instructions à protéger du bloc BBk-1 et le vecteur d'initialisation IVk, contenu dans le bloc BBk, de manière à ce que le module 28 ne détecte pas ces modifications et ne signale pas une faute d'exécution. Toutefois, en faisant cela, l'attaquant modifie nécessairement aussi la valeur construite Ck de la signature du bloc BBk. Dès lors, le module 28 signalera quand 15 même une faute au moment de la vérification de l'intégrité du bloc BBk. [00132] Le fait d'utiliser la valeur du paramètre v pour calculer la valeur attendue ou la valeur construite de la signature du bloc de base précédent et de charger la valeur de ce paramètre lors de l'exécution du bloc de base précédent permet de faire fonctionner le procédé décrit ici même dans le cas où il existe plusieurs blocs de base 20 précédents pour un même bloc de base suivant. De plus, l'utilisation du paramètre relâche les contraintes sur le choix des vecteurs d'initialisation des blocs de base précédents. Cela simplifie donc la génération du code machine. [00133] Le fait de calculer la valeur attendue ou la valeur construite en fonction de la condition de l'instruction de branchement conditionnelle qui termine le bloc de base 25 précédent permet de déclencher le signalement d'une faute d'exécution en cas d'erreur d'aiguillage dans le flot d'instructions. Par exemple, cela permet de déclencher le signalement d'une faute d'exécution si le premier bloc de base est exécuté alors que la condition n'est pas vérifiée. [00134] Le fait d'utiliser une fonction de chiffrement pour construire la valeur attendue 30 Fk-i à partir du vecteur IVk accroît la sécurité car il est alors très difficile de retrouver la valeur attendue Fk_i en connaissant seulement le vecteur IVk. Par exemple, cela rend plus difficile les attaques dans lesquelles l'attaquant essaie de remplacer le bloc BBk_i par un autre bloc de base qui aurait la même signature. En effet, dans ce cas, la valeur attendue Fkt n'est pas facile à déterminer. 35 [00135] Le fait d'utiliser un homomorphisme pour construire la valeur de la signature permet de déterminer la valeur du paramètre v qui devra être utilisée sans qu'il soit nécessaire que cette fonction préprogrammée soit inversible. [00136] Le fait d'utiliser pour la réalisation des fonctions Fcs() et Fvs() des fonctions de chiffrement et de déchiffrement asymétrique permet de garantir en plus soit 40 l'authenticité du module 28 soit l'authenticité du code machine. 29 [00137] REVENDICATIONS1. Procédé d'exécution d'un code machine d'une fonction sécurisée par un microprocesseur, ce procédé comportant : a) la fourniture (150) du code machine, ce code machine comprenant une succession de blocs de base dans lesquels : - chaque bloc de base comporte une succession d'instructions systématiquement exécutées les unes après les autres lors de l'exécution du code machine par le microprocesseur, parmi ces instructions, au moins certaines d'entre elles étant des 10 instructions à protéger, - chaque bloc de base débute à une adresse de branchement et se termine par une instruction de branchement vers une adresse de branchement d'un autre bloc de base, le bloc de base qui débute à l'adresse de branchement étant appelé « bloc de base suivant » et le bloc de base qui se termine par une instruction de branchement 15 vers cette adresse de branchement étant appelé « bloc de base précédent », b) lors de l'exécution (152) du code machine par le microprocesseur, le procédé comporte les opérations suivantes : 1) le microprocesseur charge (154) puis décode (156) les instructions des blocs de base précédent et suivant du code machine, puis chaque instruction 20 décodée est exécutée par une unité arithmétique et logique du microprocesseur, 2) à chaque fois qu'une instruction à protéger du bloc de base précédent est chargée, un module matériel de sécurisation du microprocesseur construit (157), à l'aide d'une fonction Fcsia préprogrammée, une nouvelle valeur d'une 25 signature à partir de la valeur de cette instruction à protéger et de la précédente valeur de la signature, cette signature étant ainsi fonction des valeurs des différentes instructions à protéger du bloc de base précédent, 3) le microprocesseur charge (162) un vecteur d'initialisation contenu dans le code machine et le module matériel de sécurisation calcule (164), à partir de 30 ce vecteur d'initialisation chargé et à l'aide d'une fonction FvsQ préprogrammée, une valeur attendue pour la signature du bloc de base précédent, 4) en réponse au chargement d'une instruction prédéterminée, le module matériel de sécurisation compare (166) la valeur construite de la signature à la 35 valeur attendue de cette signature calculée à partir du vecteur d'initialisation chargé, et 5) seulement si ces valeurs ne correspondent pas, le module matériel de sécurisation déclenche (170) le signalement d'une faute lors de l'exécution de ce code machine et, dans le cas contraire, inhibe un tel signalement, 31 caractérisé en ce que le vecteur d'initialisation est seulement contenu dans le bloc de base suivant. 2. Procédé selon la revendication 1, dans lequel : 5 - le bloc de base suivant est aussi un bloc de base précédent pour un autre bloc de base du code machine de sorte que les opérations 1) à 5) sont aussi réalisées pour le bloc de base suivant, et - lors de l'exécution du bloc de base suivant, le module matériel de sécurisation initialise (160) la valeur construite de la signature du bloc de base suivant à partir du même vecteur d'initialisation que celui utilisé pour calculer la valeur attendue de la signature du bloc de base précédent, de sorte que valeur construite de la signature du bloc de base suivant dépend aussi de ce vecteur d'initialisation. 3. Procédé selon l'une quelconque des revendications précédentes, dans lequel : - lors de l'opération 3), le module matériel de sécurisation calcule (164) la valeur attendue de la signature du bloc de base précédent, en plus, à partir de la valeur chargée d'un paramètre y de sorte que la valeur attendue de la signature du bloc de base précédent varie en fonction de cette valeur chargée du paramètre y ou, lors de l'opération 2), le module matériel de sécurisation construit la nouvelle valeur de la signature du bloc de base précédent, en plus, à partir de la valeur chargée d'un paramètre y de sorte que la valeur construite de la signature du bloc de base précédent varie en fonction de cette valeur chargée du paramètre v, et - le bloc de base précédent comporte une instruction prédéterminée qui, lorsqu'elle est exécutée par le microprocesseur, provoque le chargement de la valeur du paramètre v, cette valeur du paramètre y étant contenue dans ce bloc de base précédent et tel que, en absence de modification des instructions à protéger du bloc de base précédent, la valeur attendue calculée lors de l'opération 3) correspond à la valeur construite de la signature de ce bloc de base précédent. 4. Procédé selon l'une quelconque des revendications précédentes, dans lequel : - l'opération a) comporte la fourniture d'un bloc de base précédent se terminant par une instruction de branchement conditionnelle qui, lorsqu'une condition est vérifiée provoque, lorsqu'elle est exécutée par le microprocesseur, un branchement vers un premier bloc de base suivant et, en alternance, lorsque la condition n'est pas vérifiée, provoque, lorsqu'elle est exécutée par le microprocesseur, un branchement vers un second bloc de base suivant différent du premier bloc de base suivant, et - lors de l'opération 3), le module matériel de sécurisation calcule la valeur attendue de la signature du bloc de base précédent, en plus, à partir d'une valeur contenue dans un registre, cette valeur n'étant pas la même selon que la condition est vérifiée 40 ou pas, de sorte que la valeur attendue de la signature du bloc de base précédent 32 varie en fonction de cette valeur contenue dans ce registre ou, lors de l'opération 2), le module matériel de sécurisation construit la nouvelle valeur de la signature du bloc de base précédent, en plus, à partir de la valeur contenue dans ce registre de sorte que la valeur construite de la signature du bloc de base précédent varie en fonction 5 de cette valeur contenue dans ce registre. 5. Procédé selon l'une quelconque des revendications précédentes, dans lequel lors de l'opération 2), la fonction préprogrammée FcsO mise en oeuvre est une fonction de chiffrement à l'aide d'une clef secrète stockée dans une mémoire sécurisée du 10 microprocesseur, cette mémoire sécurisée étant uniquement accessible par des composants internes du microprocesseur. 6. Procédé selon l'une quelconque des revendications précédentes, dans lequel lors de l'opération 2), la fonction préprogrammée FcsO est un homomorphisme algébrique. 15 7. Procédé selon la revendication 6, dans lequel : - les fonctions préprogrammées FIS() et Fvs() mettent en oeuvre, respectivement, une fonction de chiffrement asymétrique à l'aide d'une clé publique et une fonction de déchiffrement à l'aide d'une clé privée correspond à la clé publique, ou 20 - les fonctions préprogrammées Fcs() et Fvs0 mettent en oeuvre, respectivement, une fonction de déchiffrement asymétrique à l'aide d'une clé privée et une fonction de chiffrement à l'aide d'une clé publique correspond à la clé privée. 8. Procédé selon l'une quelconque des revendications 1 à 7, dans lequel la fonction 25 FvsO est la fonction identité. 9. Code binaire (30) comportant un code machine (32) d'une fonction sécurisée pour la mise en oeuvre d'un procédé d'exécution conforme à l'une quelconque des revendications précédentes, dans lequel le code machine (32) comprend : 30 - une succession de blocs de base dans lesquels : - chaque bloc de base comporte une succession d'instructions systématiquement exécutées les unes après les autres lors de l'exécution du code machine par le microprocesseur, parmi ces instructions, au moins certaines d'entre elles étant des instructions à protéger, 35 - chaque bloc de base débute à une adresse de branchement et se termine par une instruction de branchement vers une adresse de branchement d'un autre bloc de base, le bloc de base qui débute à l'adresse de branchement étant appelé « bloc de base suivant » et le bloc de base qui se termine par une instruction de branchement vers cette adresse de branchement étant appelé « bloc de base précédent », 33 - pour chaque bloc de base, le code machine contient : - un vecteur d'initialisation à partir duquel le module matériel de sécurisation est apte à calculer, à l'aide d'une fonction Fvs() préprogrammée, une valeur attendue pour la signature du bloc de base précédent, 5 - une instruction prédéterminée apte à déclencher la comparaison, par le module matériel de sécurisation, d'une valeur construite de la signature du bloc de base précédent à la valeur attendue de cette signature calculée à partir du vecteur d'initialisation chargé, caractérisé en ce que le vecteur d'initialisation est seulement contenu dans le bloc de 10 base suivant. 10. Support (4) d'enregistrement d'informations lisible par un microprocesseur, caractérisé en ce qu'il comporte un code binaire (30) conforme à la revendication 9. 15 11. Appareil électronique (1) comportant : - une mémoire (4) dans laquelle est enregistré un code machine d'une fonction sécurisée, ce code machine comprenant une succession de blocs de base dans lesquels : - chaque bloc de base comporte une succession d'instructions 20 systématiquement exécutées les unes après les autres lors de l'exécution du code machine par un microprocesseur, parmi ces instructions, au moins certaines d'entre elles étant des instructions à protéger, - chaque bloc de base débute à une adresse de branchement et se termine par une instruction de branchement vers une adresse de branchement d'un 25 autre bloc de base, le bloc de base qui débute à l'adresse de branchement étant appelé « bloc de base suivant » et le bloc de base qui se termine par une instruction de branchement vers cette adresse de branchement étant appelé « bloc de base précédent », - le microprocesseur (2) comportant une unité (10) arithmétique et logique et un 30 module matériel (28) de sécurisation, ce microprocesseur étant apte à exécuter le code machine enregistré dans la mémoire (4), ce microprocesseur étant apte, lors de l'exécution du code machine, à charger puis à décoder les instructions des blocs de base précédent et suivant du code machine, et l'unité arithmétique et logique est apte à exécuter chaque instruction décodée, 35 - le module matériel (28) de sécurisation est apte, lors de l'exécution du code machine, à réaliser les opérations suivantes : - à chaque fois qu'une instruction à protéger du bloc de base précédent est chargée, le module matériel de sécurisation du microprocesseur construit, à l'aide d'une fonction Fcs0 préprogrammée, une nouvelle valeur d'une signature 40 à partir de la valeur de cette instruction à protéger et de la précédente valeur 34 de la signature, cette signature étant ainsi fonction des valeurs des différentes instructions à protéger du bloc de base précédent, - à chaque fois que le microprocesseur charge un vecteur d'initialisation contenu dans le code machine, le module matériel de sécurisation calcule, à 5 partir de ce vecteur d'initialisation chargé et à l'aide d'une fonction Fvs() préprogrammée, une valeur attendue pour la signature du bloc de base précédent, - en réponse au chargement d'une instruction prédéterminée, le module matériel de sécurisation compare la valeur construite de la signature à la 10 valeur attendue de cette signature calculée à partir du vecteur d'initialisation chargé, et - seulement si ces valeurs ne correspondent pas, le module matériel de sécurisation déclenche le signalement d'une faute lors de l'exécution de ce code machine et, dans le cas contraire, inhibe un tel signalement, 15 caractérisé en ce que le vecteur d'initialisation est seulement contenu dans le bloc de base suivant. 12. Compilateur (190) apte à transformer automatiquement un code source (192) d'un programme contenant une fonction sécurisée en un code binaire (30) 20 comportant un code machine (32) d'une fonction sécurisée, caractérisé en ce que le compilateur est apte à transformer automatiquement le code source (192) en un code binaire (30) conforme à la revendication 9.