La présente invention concerne un système d'exécution d'applications d'une carte à puce, un procédé d'exécution d'applications chargées dans une carte à puce ainsi qu'un programme permettant audit système d'exécution d'applications d'exécuter ledit procédé.
Une carte à puce est une carte qui est utilisée avec un lecteur de carte approprié de manière à mener à bien une transaction, par exemple pour le paiement d'articles, etc. Une telle carte est pourvue d'un système d'exécution d'applications qui assure le déroulement des échanges d'informations entre elle et le lecteur de carte, le traitement des informations échangées, tel qu'un traitement de validation de mot de passe, un traitement de cryptographie, etc. Diverses technologies peuvent être utilisées. Dans la suite de la description, cependant, il sera question de l'une d'entre elles, donnée à titre d'exemple, la technologie qui est dite Java Card, notamment du fait qu'elle est une adaptation de la technologie Java aux cartes à puce. Les applications, dites aussi applets dans la technologie Java Card, qui sont susceptibles d'être exécutées sur une carte à puce sont écrites dans un langage de haut niveau, généralement Java Card, puis sont converties, par un programme appelé compilateur, sous forme de fichiers qui contient une représentation binaire exécutable (dit byte code) de toutes les classes qui constituent l'application considérée. En technologie Java Card, ces fichiers contenant les classes constituant lesdites applets sont dits des fichiers CAP (Converted Applets). Un programme d'installation, en dehors de la carte elle-même ou au contraire embarquée comme dans les générations récentes de carte à puce, est prévu pour transmettre, via un dispositif d'acceptation de carte (CAD : Card Acceptance Device), le code exécutable contenu dans le fichier CAP à un installateur résidant dans la carte.
Une fois chargée et installée sur la carte, l'application, sous la forme d'un fichier CAP incorporant le byte code, peut être exécutée par un interpréteur que celle-ci contient. Cet interpréteur est parfois appelé, par abus de langage, machine virtuelle, ou en technologie Java Card, JCVM, bien que celle-ci, si elle incorpore bien l'interpréteur, inclut également le compilateur.
L'exécution d'une application (ou applet) passe par la création d'une instance de celle-ci et son enregistrement auprès de l'environnement d'exécution (en technologie Java Card, cet environnement est dit JCRE). Seule l'applet en instance est exécutée. L'applet en instance est exécutée par invocation de méthodes. Une méthode invoquée est exécutée par l'environnement d'exécution, notamment l'interpréteur, instructions après instructions. En même temps qu'une méthode est invoquée, une trame (appelée "frame" en technologie Java Card) est créée qui comporte plusieurs files d'attente dernier entré - premier sorti (LIFO : Last-in-first-out) encore appelées "piles" dans lesquelles sont stockées des données concernant la méthode invoquée de l'applet en instance. Parmi les piles de ce système d'exécution, existe la pile d'opérandes. Dans la présente description, on appelle "système d'exécution" l'environnement d'exécution JCRE avec son interpréteur associé à la trame et ses piles, notamment la pile d'opérandes.
Diverses instructions peuvent être exécutées par l'environnement d'exécution. Les instructions qui nous intéressent ici sont les instructions dites ici de chargement qui sont prévues pour empiler une donnée en haut de ladite pile d'opérandes ainsi que les instructions dites ici d'opération qui dépilent lesdites données de la pile d'opérandes en tant qu'opérandes d'une opération à exécuter, exécutent ladite opération et empilent le résultat de cette exécution en haut de ladite pile d'opérandes. Dans la technologie Java Card, tout objet est typé soit en tant que type "numérique", soit en tant que type "référence". Le premier type inclut les types "byte", "short", "int", "long", "char", etc. Le second type inclut les types "class", "array", "interface". La distinction entre type "numérique" et type "référence" concerne non seulement l'objet en tant que tel mais aussi les instructions mises en oeuvre par une méthode de cet objet ainsi que les valeurs qui sont manipulées par ces instructions. Ainsi, chaque instruction de chargement et chaque instruction d'opération sont typées pour manipuler des données d'un type spécifique, "numérique" ou "référence". Le système d'exécution d'applications d'une carte à puce qui est représenté à la Fig. 1 comprend essentiellement une mémoire d'applications 10 dans laquelle sont stockés les codes dits "byte code" des applications, encore appelées "applets", qui y sont chargées. Chaque code en question est écrit dans la mémoire d'applications sous la forme d'une suite d'instructions à exécuter. Une unité de traitement 20, encore appelée "interpréteur", lit séquentiellement chaque instruction de la mémoire d'applications 10, l'interprète et l'exécute. Lors de l'exécution d'applications, l'unité de traitement 20 peut être amenée à stocker temporairement des données et à lire des données qui ont été stockées temporairement. A cet effet, des files d'attente dernier entré - premier sorti (LIFO : last input - first output) 30, encore appelées "piles" peuvent être prévues. Une pile particulière est la pile d'opérandes 31 qui est prévue pour stocker temporairement des données qui seront ensuite utilisées par des instructions relatives à des opérations à effectuer en tant qu'opérandes desdites opérations. Le fonctionnement du système d'exécution d'applications d'une carte à puce qui est représenté à la Fig. 1 est donné, à titre d'exemple, pour l'addition de deux entiers N et M de type "short", en relation avec les Figs. 2a à 2d. A la Fig. 2a, l'instruction interprétée par l'unité de traitement 20 est spush M (push type "short") qui a pour fonction de stocker la valeur M sur le haut de la pile d'opérandes 31. A la Fig. 2b, l'instruction interprétée par l'unité de traitement 20 est spush N qui a pour fonction de stocker la valeur N sur le haut de la pile d'opérandes 31. A la Fig. 2c, l'instruction interprétée par l'unité de traitement 20 est sadd (add type "short") qui a pour fonction de lire, dans un premier temps, les deux opérandes N et M respectivement stockées dans la pile d'opérandes 31. Dans un second temps (Fig. 2d), l'unité de traitement 20 additionne les opérandes N et M lues et place le résultat de cette addition sur le haut de la pile d'opérandes 31. Les cartes à puce peuvent faire l'objet d'attaques qui ont généralement pour but final de récupérer les données confidentielles, telles qu'une clef de cryptographie, que celles-ci stockent. Ces attaques peuvent être physiques ou logiques. Les attaques logiques consistent à faire exécuter par le système d'exécution des instructions ou groupes d'instructions malveillantes, c'est-à-dire des instructions ou groupes d'instruction qui ne respectent pas les règles du langage de programmation et dont le compilateur ou le dispositif d'acception de carte CAD ne détecte pas ce non-respect. Pour que cette exécution soit possible, il est nécessaire que le code (byte code) correspondant à ces instructions soit chargé, selon la procédure décrite ci-dessus, dans la carte à puce, ce qui suppose, cela ne va pas de soi, que l'attaquant puisse le faire, hypothèse dans laquelle la présente description se place. Parmi ces attaques logiques, il en est une qui consiste à exploiter une confusion entre deux types, par exemple confusion entre le type "référence" et le type "numérique". Pour donner un exemple d'une telle attaque, en reprenant l'exemple ci- dessus d'addition de deux entiers, la première instruction de chargement qui était spush N est remplacée par une instruction de chargement aload 0 qui empile une référence à l'indice 0 (voir Fig. 3a). Aux Figs. 3b et 3c, les processus sont les mêmes que ceux des Figs. 2b et 2c. A la Fig. 3d, la pile d'opérandes 31, après l'instruction d'addition sadd, contient une référence particulière obtenue comme étant la somme de la référence à l'indice 0 et d'un entier M. Ainsi, en faisant prendre à M toutes les valeurs possibles, toutes les références possibles sont balayées, ce qui permet d'accéder à des zones mémoires réservées au système et normalement interdites aux applications. De manière générale, le but final d'une attaque logique par confusion de types est de créer une référence mémoire arbitraire que l'environnement d'exécution JCRE, en l'occurrence l'interpréteur, traite comme étant une référence valide créée par le compilateur. Ainsi, en cas de succès, une telle attaque peut permettre à une application d'accéder à des zones mémoires non autorisées, en lecture comme en écriture. Ces attaques logiques peuvent également être combinées à des attaques physiques, notamment des attaques par injection de fautes. Un exemple d'attaque par confusion de type est donné dans l'article de 011i Vertanen intitulé "Java Type Confusion and Fat& Attacks", publié en 2006 dans L. Brevegleri et al., FDTC 2006, LNCS 4236 pp. 237-251. Le but de la présente invention est de proposer un système d'exécution d'applications d'une carte à puce qui rende une attaque logique par confusion de types plus difficile, voire impossible, à mettre en oeuvre. Pour ce faire, la présente invention concerne un système d'exécution d'applications d'une carte à puce, chaque application chargée dans ladite carte à puce comportant des instructions de chargement et des instructions d'opération, ledit système d'exécution d'applications comportant une pile d'opérandes dans laquelle chaque instruction de chargement empile une donnée en haut de ladite pile d'opérandes et chaque instruction d'opération dépile lesdites données de la pile d'opérandes en tant qu'opérandes d'une opération à exécuter et empile le résultat de l'exécution de ladite opération en haut de ladite pile d'opérandes, chaque instruction de chargement et chaque instruction d'opération étant typées pour manipuler des données d'un type spécifique. Selon une caractéristique de l'invention, ledit système est caractérisé en ce qu'il comporte en outre une pile de type, chaque instruction de chargement étant prévue pour empiler en haut de ladite pile de type une donnée de type relative à son type, chaque instruction d'opération relative à une opération à exécuter étant prévue pour dépiler les données de type correspondant aux opérandes de ladite opération à exécuter et lancer l'exécution de ladite instruction d'opération que lorsque toutes les données de type dépilées sont relatives à un même type. Selon un exemple de réalisation, lesdites instructions de chargement et d'opération sont soit de type référence, soit de type numérique.
L'invention concerne également un procédé d'exécution d'applications chargées dans une carte à puce, chaque application ainsi chargée comportant des instructions de chargement et des instructions d'opération, chaque instruction de chargement et chaque instruction d'opération étant typées pour manipuler des données d'un type spécifique, ledit procédé comprenant, respectivement mises en oeuvre par des instructions de chargement successives lors de leurs exécutions, des étapes d'empilement pour empiler une donnée en haut d'une pile d'opérandes et, mises en oeuvre par une instruction d'opération lors de son exécution, une étape de dépilement pour dépiler lesdites données de la pile d'opérandes en tant qu'opérandes d'une opération à exécuter et une étape d'empilement pour empiler le résultat de l'exécution de ladite opération en haut de ladite pile d'opérandes. Selon l'invention, ce procédé est caractérisé en ce qu'il comporte en outre une étape d'empilement mise en oeuvre par chaque instruction de chargement pour empiler en haut d'une pile de type une donnée de type relative au type de ladite instruction et, mises en oeuvre par chaque instruction d'opération relative à une opération à exécuter, une étape de dépilement pour dépiler les données de type correspondant aux opérandes de ladite opération à exécuter et une étape de lancement de l'exécution de ladite instruction d'opération que lorsque toutes les données de type dépilées sont relatives à un même type. Selon un mode de réalisation, lesdites instructions de chargement et d'opération sont soit de type référence, soit de type numérique. Enfin, la présente invention concerne également un programme inscrit dans une mémoire d'une unité de traitement d'un système d'exécution d'applications d'une carte à puce tel qu'il vient d'être décrit et comportant des instructions pour implémenter les étapes d'un procédé d'exécution d'applications chargées dans une carte à puce tel qu'il vient d'être décrit. Les caractéristiques de l'invention mentionnées ci-dessus ainsi que d'autres, apparaîtront plus clairement à la lecture de la description suivante d'un exemple de réalisation, ladite description étant faite en relation avec les dessins joints parmi lesquels: La Fig. 1 est une vue schématique d'un système d'exécution d'applications d'une carte à puce selon l'état de la technique, Les Figs. 2a à 2d sont des vues schématiques d'un système d'exécution d'applications d'une carte à puce selon l'état de la technique illustrant le fonctionnement correct d'un tel système, Les Figs. 3a à 3d sont des vues schématiques d'un système d'exécution d'applications d'une carte à puce selon l'état de la technique illustrant un fonctionnement incorrect d'un tel système, La Fig. 4 est une vue schématique d'un système d'exécution d'applications d'une carte à puce selon la présente invention, Les Figs. 5a à 5d sont des vues schématiques d'un système d'exécution d'applications d'une carte à puce selon la présente invention illustrant le fonctionnement d'un tel système, et, La Fig. 6 est un schéma synoptique d'une unité de traitement d'un système d'exécution d'applications d'une carte à puce selon la présente invention. Le système d'exécution d'applications d'une carte à puce selon l'invention qui est représenté à la Fig. 4 est identique à celui de la Fig. 1 à la différence près qu'il comprend en outre une pile de type 32 qui sera décrite ultérieurement. Par rapport à ce qui est appelé dans la littérature l'environnement d'exécution (en technologie Java Card : JCRE), le système d'exécution de la présente invention incorpore en plus les différentes piles 30, et essentiellement la pile d'opérandes 31 et la pile de type 32. Parmi les instructions du jeu d'instructions que l'unité de traitement 20 peut exécuter, il y a des instructions, dites ici instructions de chargement, qui sont prévues pour empiler une donnée en haut de ladite pile d'opérandes. Il peut s'agir des instructions spush, aload, bspush, sconst, baload, etc. Il y aussi des instructions, dites ici instructions d'opérations, qui sont prévues pour dépiler lesdites données de la pile d'opérandes en tant qu'opérandes d'une opération à exécuter et empile le résultat de l'exécution de ladite opération en haut de ladite pile d'opérandes. Il peut s'agir des instructions sadd, sand, ssub, smul, etc. Chaque instruction de chargement et chaque instruction d'opération sont amenées à manipuler des données d'un type spécifique, par exemple soit de type "numérique", soit de type "référence". Le premier type inclut les types "byte", "short", "int", "long", "char", etc. Le second type inclut les types "class", "array", "interface".
Ainsi, chaque instruction de chargement et chaque instruction d'opération sont typées pour manipuler des données d'un type spécifique, "numérique" ou "référence". Selon l'invention, chaque instruction de chargement est prévue pour empiler en haut de ladite pile de type une donnée de type relative à son type et chaque instruction d'opération relative à une opération à exécuter est prévue pour dépiler les données de type correspondant aux opérandes de ladite opération à exécuter. De plus, chaque instruction d'opération est prévue pour ne lancer l'exécution de ladite instruction d'opération que lorsque toutes les données de type dépilées sont relatives à un même type.
Les Figs. 5a à 5d illustrent un exemple de mise en oeuvre de la présente invention. A la Fig. 5a, l'instruction interprétée par l'unité de traitement 20 est spush M qui a pour fonction de stocker la valeur M sur le haut de la pile d'opérandes 31. Selon l'invention, elle a également pour fonction de stocker sur le haut de la pile de type 32, une donnée Tm représentative du type de la valeur stockée en haut de la pile d'opérandes 31 et donc du type de l'instruction spush, en l'occurrence "short". A la Fig. Sb, l'instruction interprétée par l'unité de traitement 20 est spush N qui a pour fonction de stocker dans la valeur N sur le haut de la pile d'opérandes 31 et, sur le haut de la pile de type 32, une donnée TN représentative ici du type "short". A la Fig. Sc, l'instruction interprétée par l'unité de traitement 20 est sadd qui a pour fonction de lire, dans un premier temps, les deux opérandes N et M respectivement stockées dans la pile d'opérandes ainsi que les valeurs de type TN et Tm correspondant à ces opérandes N et M respectivement stockées dans la pile de type 32. Dans un second temps, l'unité de traitement 20 vérifie que les valeurs types TN et Tm sont identiques et, si tel est le cas, elle additionne les opérandes N et M lues et place le résultat de cette addition sur le haut de la pile d'opérandes 31. En même temps, elle stocke une valeur de type TR sur le haut de la pile de type 32, en l'occurrence "short". Si les valeurs de type TN et Tm n'étaient pas identiques, l'instruction n'est pas menée à son terme et la carte à puce est mise dans un état de sécurité, par exemple, dans un état où elle est rendue muette. La Fig. 6 représente une unité de traitement 20 selon un mode de réalisation de la présente invention. Elle est constituée d'une unité de commande 21 qui est pilotée par un programme qui est inscrit dans une mémoire 22.
L'unité de commande 21 est prévue pour lire dans une mémoire de programme 10 l'instruction à exécuter et pour exécuter l'instruction ainsi lue. Si l'instruction lue est une instruction de chargement, l'unité de commande 21 empile une donnée en haut d'une pile d'opérandes 31 ainsi qu'une donnée de type en haut d'une pile de type 32. Si l'instruction lue est une instruction d'opération, l'unité de commande 21 dépile les données contenues dans la pile d'opérandes 31 en tant qu'opérandes d'une opération à exécuter et empile le résultat de l'exécution de ladite opération en haut de ladite pile d'opérandes 31. De plus, selon l'invention, dans ce cas, elle est prévue pour dépiler les données de type correspondant aux opérandes de ladite opération à exécuter et ne lancer l'exécution de ladite instruction d'opération que lorsque toutes les données de type dépilées sont relatives à un même type. La présente invention concerne également un programme inscrit dans une mémoire 22 d'une unité de traitement 20, susceptible d'être mis en oeuvre au sein d'une unité de commande 21 que comporte l'unité de traitement 20 d'un système d'exécution d'applications d'une carte à puce, comprenant des instructions pour le fonctionnement de ladite unité de commande 21 comme il vient d'être exposé.