Sécurisation à la compilation de logiciels contre les attaques en fautes

Un système embarqué est un système électronique souvent dédié à une ou quelques tâches spécifiques, soumis à des contraintes de temps d’exécution, de consommation énergétique, d’espace mémoire et de sécurité. Grâce aux progrès de la miniaturisation et aux faibles coûts des composants électroniques, les systèmes embarqués deviennent de plus en plus accessibles au grand public avec des fonctionnalités de plus en plus complexes. Ces systèmes, tels que les cartes de crédit, les cartes SIM ou encore les passeports biométriques, s’imposent aujourd’hui comme des objets incontournables de notre quotidien. Compte tenu de la nature des données que ces systèmes sont amenés à stocker et à manipuler (données personnelles, confidentielles, critiques, etc.), la sécurité de ces systèmes est devenue un enjeu et une préoccupation majeure pour les industriels, les organisations étatiques et le grand public. Ces systèmes font face à des attaques qui visent leur :
• Confidentialité : accéder frauduleusement à des informations sensibles
• Intégrité : altérer des données sensibles
• Disponibilité : rendre le système non disponible pour les utilisateurs légitimes .

La confidentialité et l’intégrité des données sont aujourd’hui largement traitées par la cryptographie moderne. Il existe, en effet, plusieurs algorithmes et protocoles cryptographiques standardisés et considérés comme sûrs d’un point de vue mathématique, par exemple l’algorithme AES (Advance Encryption Standard) [97] pour le chiffrement, et DSA (Digital Signature Algorithm) [79] pour la signature numériques. La sécurité des algorithmes cryptographiques repose fondamentalement sur le constat que certains problèmes mathématiques sont difficiles à résoudre dans un temps raisonnable. C’est le cas, par exemple, de l’algorithme de chiffrement RSA basé sur le problème de factorisation de grands entiers, et pour lequel, le meilleur algorithme de factorisation connu en 2017 est d’une complexité sous-exponentielle par rapport à la taille de l’entier à factoriser. Cependant, la sécurité de ces algorithmes peut être compromise en exploitant des failles liées au matériel sur lequel ils sont exécutés. Ce type d’attaques est connu sous le nom d’attaques physiques. On dénombre deux grandes classes d’attaques physiques :

1. Les attaques par observation de canaux auxiliaires : elles consistent à collecter des informations sur le composant en cours d’exécution, puis à exploiter ces informations pour remonter aux données manipulées par le composant.
2. Les attaques par perturbations : elles consistent à perturber le fonctionnement normal du composant pendant son exécution, et à tirer parti de cette perturbation pour compromettre le système.

Le secteur le plus concerné par ces attaques est celui de la carte à puce avec ses nombreuses déclinaisons. Eurosmart prévoit une vente de 9 à 10 milliards de cartes à puces en 2017 [47]. Toutefois, l’efficacité de ces attaques a été démontrée dans d’autres secteurs tels que le débridage de produits grand public. Un des exemples les plus notables est le déverrouillage (jailbreak) de certaines fonctionnalités restreintes de l’iPhone 3G réalisé par George Hotz [102]. De nombreuses contre-mesures contre les attaques physiques ont déjà été proposées; certaines visent à détecter une attaque et à réagir en conséquence, d’autres à rendre l’attaque plus difficile à réaliser. Les contre-mesures implémentées en matériel ont l’avantage d’être plus efficaces en temps d’exécution, mais sont susceptibles d’augmenter la taille du composant électronique et ne peuvent pas être mises à jour. Elles sont généralement utilisées dans des composants dédiés à la sécurité comme la carte à puce ou les éléments sécurisés (secure element). En revanche, les contremesures implémentées en logiciel, bien que plus coûteuses en performance, sont plus faciles à déployer et à mettre à jour. Elles sont principalement utilisées pour ajouter de la sécurité sur des composants non sécurisés. Dans la plupart des cas, des contre-mesures matérielles et logicielles sont combinées pour plus d’efficacité.

Attaques physiques 

Attaques par canaux auxiliaires

Les attaques par canaux auxiliaires ou attaques par canaux cachés consistent à collecter des informations sur le composant (cible) en cours de fonctionnement, puis à exploiter ces informations pour révéler les données manipulées par ce composant. Ces informations, appelées grandeurs physiques mesurables ou des observables, peuvent être la consommation électrique [57], le temps d’exécution [56], le rayonnement électromagnétique [85] ou le signal acoustique [95]. Lorsque l’information sur une donnée manipulée par le programme est obtenue à partir des observables du circuit, on dit que cette donnée fuit. Ces attaques fonctionnent parce qu’il existe une corrélation entre les opérations réalisées à l’intérieur d’un circuit électronique et les observables.

Contre-mesures

L’objectif des contre-mesures est de rompre ou de rendre inexploitable la corrélation entre les données manipulées par un composant et ses observables. Plusieurs schémas de contre-mesures ont été proposés, ces schémas peuvent être regroupés en deux concepts : concept de dissimulation et concept de masquage.

Concept de dissimulation (Hiding)
Il s’agit de dissimuler les données sensibles d’un programme dans les observables du circuit [68]. Parmi les techniques de dissimulation, on peut citer :

Ajout du bruit : Cette technique consiste à diminuer le rapport signal sur bruit (SNR) dans les observables du circuit. Cela peut se faire en insérant des opérations factices qui ne modifient pas la fonctionnalité du programme. En effet, l’exécution des instructions des lignes 2, 3 et 4 de la figure 2.1b n’interagit pas avec la fonctionnalité du programme.

Ordonnancement aléatoire des exécutions : L’ordonnancement aléatoire ou shuffling consiste à changer aléatoirement l’ordre d’exécution des opérations. Cette technique fonctionne mieux lorsque le programme comporte des opérations indépendantes [16, 70]. Cette technique vise à faire varier l’instant de fuite des données sensibles dans les observables.

Codes polymorphes : Un code polymorphe est un code capable de changer une partie de son implémentation tout en conservant sa fonctionnalité [2, 31]. Parmi les techniques de polymorphisme il y a la substitution qui consiste à substituer une opération par une autre, différente mais sémantiquement équivalente à la première. Par exemple : l’opération a ⊕ b peut être substituée par (a ∨ b) ⊕ (a ∧ b).

Équilibrage de la consommation : Cette technique vise à rendre constante la consommation électrique d’une opération quelles que soient les données manipulées. Une des méthodes utilisées consiste à calculer le complément de chacune des variables. Ce principe a été décliné à tous les niveaux d’abstraction, du niveau logiciel au niveau transistor. La logique double rail (dual-rail), couramment utilisée dans la littérature scientifique, consiste à utiliser deux fils pour encoder une valeur binaire. Un exemple de codage est qu’un des deux fils prenne la valeur 1 pour encoder une donnée à 1 et l’autre la valeur 1 pour encoder la donnée à 0. Plusieurs exemples de la logique double rail sont présentés par Guilley et al. [52, 51] et Danger et al. [36]. Une implémentation logicielle est proposée par Hoogvorst et al. [54].

Concept de masquage (Masking) 

Le masquage vise à rendre les informations observables du circuit statistiquement indépendantes des données manipulées [20, 90]. L’une des techniques utilisées consiste à appliquer un masque aléatoire sur les données sensibles avant de les manipuler. Il existe plusieurs types de masquage, parmi lesquels le masquage booléen qui se définit comme une fonction f tel que : f(x) = x⊕r, où x est la valeur secrète et le maque r est une valeur aléatoire [29]. Pour illustrer ce concept, supposons que nous souhaitons calculer l’opération c = m ⊕ k, où k est une donnée sensible et m peut être connu de l’attaquant. Pour éviter que l’information sur k ne fuite lors du calcul de c, on masque au préalable k en k’ = k ⊕ r, puis on calcule c’ = m ⊕ k’ à la place. Ainsi, la fuite sera corrélée avec k’ et non k. Pour retrouver c, on effectue c = c’ ⊕ r.

Attaques par injection de fautes

Les fautes sur les circuits électroniques ont été étudiées dès les années 70, suite à l’observation de l’effet d’une particule radioactive sur un circuit électronique [10]. Il a été observé que lorsqu’une particule radioactive entre en contact avec la surface d’un circuit électronique, tel qu’une mémoire volatile, elle génère une charge électrique qui peut modifier la valeur d’un ou de plusieurs bits. Les attaques par injection de fautes consistent à perturber de manière volontaire le fonctionnement normal du circuit dans le but d’extraire des données sensibles, par exemple une clé de chiffrement. L’utilisation des fautes pour attaquer un système a été introduite pour la première fois par Dan Boneh, Richard DeMillo et Richard Lipton en 1997 [21]. Dans cet article, les auteurs ont présenté une attaque par injection de fautes permettant de retrouver la clé de chiffrement sur une implémentation de l’algorithme RSA.

Moyens d’injection de fautes

Perturbation de la tension d’alimentation

Cette technique, communément appelée Power Glitch, consiste à faire varier pendant un court instant la tension d’alimentation d’un circuit. Une telle perturbation va avoir un effet sur la vitesse de transfert des données et des instructions entre le processeur et la mémoire principale. Elle peut notamment induire le processeur à mal interpréter des données ou à sauter des instructions .

Augmentation de la fréquence d’horloge

De manière analogue au Power Glitch, la perturbation du signal d’horloge ou Clock Glitch consiste à augmenter pendant un court instant la fréquence d’horloge [3]. Or, la fréquence maximale d’un circuit synchrone étant définie en fonction de la durée de transfert des données entre ses blocs logiques, pousser cette fréquence au-delà de cette limite engendre des dysfonctionnements dans les opérations du circuit.

Le rapport de stage ou le pfe est un document d’analyse, de synthèse et d’évaluation de votre apprentissage, c’est pour cela chatpfe.com propose le téléchargement des modèles complet de projet de fin d’étude, rapport de stage, mémoire, pfe, thèse, pour connaître la méthodologie à avoir et savoir comment construire les parties d’un projet de fin d’étude.

Table des matières

I Introduction générale
1 Introduction
1.1 Contexte et motivations
1.2 Problématiques
1.3 Contributions
1.4 Plan du manuscrit
II État de l’art
2 Attaques physiques
2.1 Attaques par canaux auxiliaires
2.2 Attaques par injection de fautes
2.3 Schéma de contre-mesures contre les attaques en fautes
2.4 Exemples d’implémentations logicielles
2.5 Conclusion
3 Compilation
3.1 Principes généraux
3.2 Le compilateur LLVM
3.3 Compilation pour la sécurité
3.4 Conclusion
III Contributions
4 Simulateur de fautes
4.1 Fonctionnement
4.2 Modèles de fautes supportés
4.3 Architecture interne
4.4 Utilisation
5 Compilation d’un schéma de tolérance aux fautes
5.1 Modèle de fautes
5.2 Mise en œuvre du schéma de protection
5.3 Expérimentations
5.4 Conclusion
6 Généralisation du schéma de tolérance au saut d’instructions
6.1 Modèles de fautes
6.2 Description du schéma de protections
6.3 Mise en œuvre
6.4 Expérimentations
6.5 Conclusion
7 Combinaison du schéma de tolérance avec du CFI
7.1 Modèles de fautes
7.2 Notations
7.3 Description du schéma CFI
7.4 Mise en œuvre
7.5 Illustrations
7.6 Expérimentations
7.7 Conclusion
8 Conception et mise en œuvre du schéma CCFI
8.1 Modèles de fautes
8.2 Principe de fonctionnement du schéma CCFI
8.3 Mise en œuvre
8.4 Expérimentations
8.5 Conclusion
9 Conclusion et perspectives
9.1 Conclusion
9.2 Perspectives
IV Conclusion
A Description des passes de compilation du schéma CCFI
A.1 Détails d’implémentation
Bibliographie

Lire le rapport complet

Télécharger aussi :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *