Dans bien des domaines, les cartes à puces jouent un rôle important dès qu'il est question de sécurité. Celles-ci offrent, en effet, des possibilités de contrôle et de vérification pour un coût minime. Le but de cet article est de décrire la manière d'interfacer une application avec un lecteur de carte connecté au port parallèle.
QUELLES CARTES ?
Pour nos expériences, nous nous bornerons à utiliser un seul type de carte. Il s'agit de l'ancienne génération de cartes téléphoniques appelées T1G. Celles-ci sont bien plus simples à mettre en oeuvre que celles de la nouvelle génération (T2G) ou les cartes bancaires, véritables ordinateurs miniaturisés. Faire la différence entre une carte téléphonique de première génération et une autre est un véritable jeu d'enfant : c'est marqué dessus (juste à côté du nombre d'exemplaires produits).
Une carte téléphonique d'ancienne génération est, à peu de chose près, un simple bloc de 256 bits. Dans cette zone mémoire, la partie intéressante est constituée par les 96 premiers bits. Ceux-ci sont uniques pour chaque carte téléphonique et renseignent sur divers éléments comme le type de carte, le numéro de série, le code services, etc... L'ensemble de ces 96 bits est protégé contre l'écriture grâce à un fusible brûlé à l'usine . Le reste des informations dans la zone mémoire concerne les unités débitées. Ceci est sans importance dans notre cas étant donné, qu'en principe, nous ne travaillerons que sur des cartes usagées.
LA PUCE
Nous venons de voir le côté purement théorique de la puce insérée dans le support plastique de la carte. Voyons maintenant la partie physique de celle-ci. Comme le montre notre schéma en figure 1, une puce de carte téléphonique comporte 8 contacts. Nous n'utiliserons que 6 contacts car nous n'avons pas besoin d'écrire dans les cases mémoire.
fig.1
La nomenclature des différents contacts est la suivante :
1 - Vcc, tension d'alimentation
2 - Reset, retour sur le premier bit de la zone mémoire
3 - Horloge, incrémentation d'un bit dans la zone mémoire
4 - Réservé
5 - Masse
6 - Vpp, tension d'écriture
7 - entrée/sortie
8 - Réservé
Pour notre application, nous aurons besoin d'alimenter la puce en courant (1, 4 et 6), de se positionner sur le premier bit (2) et d'incrémenter l'horloge pour avancer dans la zone (3). Le tout étant, bien sûr, relié à la masse (5)
Important : Il existe deux formats de cartes distincts. Ils diffèrent par l'emplacement de la puce sur le support en plastique. La norme ISO définit un placement du composant idem à
celui d'une carte bancaire alors que le format AFNOR place la puce plus haut et... à l'envers ! Reportez vous au schémas en figure 2 pour des explications plus claires.
fig.2
LE MONTAGE
Pour interfacer la carte à puce avec le port parallèle du PC nous n'aurons besoin d'aucun composant électronique. Nous utiliserons simplement des fils et un élément indispensable : le connecteur de carte à puce. Il s'agit du seul élément mécanique du montage. Son but est simplement de placer des contacteurs sur les broches de la puce. Ce genre de connecteurs se trouve facilement dans tous les magasins d'électronique. Par exemple, nous nous sommes fournis chez Selectronic à Lille sous la référence 83.9292 (45 FF TTC). Bien sûr, il est toujours possible d'envisager un bricolage "maison"...
Pour alimenter la puce en courant, nous utiliserons la broche 2 du port parallèle sur les contacts 6 et 1 (Vcc et Vpp) et la broche 5 sur le contact 4 (Réservé, étrange mais nécessaire).
Pour réinitialiser la puce, nous enverrons du courant par la broche 3 sur le contact 2 (Reset).
Il nous suffira alors, de lire l'état de la broche 11 connectée sur le contact 7 pour savoir si le bit est 0 ou 1.
Finalement, pour avancer d'une position dans la zone mémoire, nous enverrons du courant sur le contact 3 via la broche 4 du port parallèle.
Le schéma en figure 3 donne l'ensemble des connexions à effectuer.
fig3
LE LOGICIEL
Le code donné ici n'est qu'un simple exemple. Il permet de lire des 256 bits d'une carte téléphonique de première génération et d'afficher tous les états à l'écran.
#include <stdio.h>
#include <unistd.h>
#include <asm/io.h> // indispensable pour accéder au // port
/* on définit BASEPORT comme l'adresse du port parallèle en hexa */
#define BASEPORT 0x378
int main()
{
unsigned int lu; // la variable lue contiendra // l'octet lu sur le port 0x379
int i=1; // variable pour compter les cases mémoire
/* On demande l'autorisation au système d'accéder au port. Si le système refuse, on arrête le programme avec une erreur */
if(ioperm(BASEPORT,3,1)) {perror("ioperm"); exit(1);}
outb(11,BASEPORT); // on réinitialise la puce en // activant les broches 2, 3 et 5
usleep(10000); // pendant 1/100 de seconde
outb(9,BASEPORT); // puis on continue à alimenter la // puce par les broches 2 et 5
/* On démarre une boucle jusqu'au 256ième bit */
while(i<=256)
{
lu=inb(BASEPORT+1); // on lit le port //parallèle (0x379)
lu=lu & 128; // on extrait le bit de la broche 11
if (lu==128) lu=1; // on le valide
printf("%d \n", lu); // puis on l'affiche
i++; // on incrémente la variable de comptage
outb(13, BASEPORT); // on envoie le signal //d'horloge à la puce (broche 2, 4 et 5)
usleep(10000); // pendant 1/100 de seconde
outb(9,BASEPORT); // et l'on continue d'alimen //ter la puce
}
/* Après l'affichage des 256 bits de la zone mémoire de la puce, nous pouvons couper l'alimentation du montage et quitter le programme */
outb(0,BASEPORT);
exit(0);}
Pour compiler le programme ci-dessus, vous utiliserez la commande suivante :
gcc carte.c -ocarte -O2
Il est impératif d'utiliser un niveau d'optimisation. Dans le cas contraire, un certain nombre d'erreurs s'afficheront et le binaire ne sera pas créé.
Important : Vous devez posséder les privilèges root pour lancer le programme.
Si tout se passe correctement, vous devrez voir appara"tre un à un les bits contenus dans la puce dès le lancement du programme. Si vous obtenez une suite de composés uniquement de 0 (ou de 1), votre montage doit comporter une erreur, ou la carte ne répond pas. Dans les deux cas, vérifiez chaque connexion à l'aide d'un testeur et nettoyez les contacts de la puce.
Voici un exemple du contenu d'une télécarte 120 unités. Le premier paragraphe contient les 96 premiers bits qui nous intéressent.
01000100111110001100101110111000
00111100111011011100110011111010
00111100110011001110111111101100
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000000000
00000000000000000000000000011111
11111111111111111111111111111111
APPLICATION
Notre exemple en C est très simpliste. Pour ce rendre compte des implications d'un tel système, il faut voir beaucoup plus loin.
Si vous êtes en train de mettre en place un système de gestion de connexions InterNet, par exemple, vous pouvez implémenter ce système pour authentifier les utilisateurs. Dans toutes les applications où il est nécessaire de savoir qui essaie d'utiliser une application, cette méthode d'identification peut être utilisée.
En allant encore plus loin, il est possible d'imaginer de totalement remplacer la saisie d'un login et mot de passe, par un programme utilisant la lecture d'une vieille carte téléphonique. Pour quelques dizaines de francs, il est possible de mettre en place une sécurité quasi parfaite dans tout son système.
Je dis bien "quasi parfaite" car il existe des composants électroniques possédant les mêmes capacités qu'une carte téléphonique : les EEPROMs série. Un bon électronicien pourrait vous créer un montage parfaitement à même de simuler le comportement d'une carte téléphonique. Je vous rassure, cela ne fonctionnera pas dans une véritable cabine téléphonique.
Les deux livres de références pour les cartes à puces :
PC et cartes à puces : ISBN 2-85535-239-8
Cartes à puces : ISBN 2-85535-214-2