Ca y est ! J'ai reçu mon programmateur de cartes à puce InfinityUSB Unlimited. Finalement, il n'aura mis que 2 semaines pour venir de Chine.
J'avais un peu peur qu'il ne soit pas fonctionnel car il est censé être le même que le modèle vendu en France 90€ alors qu'Ali Baba le vend 20€.
La boite est identique à l'original : elle comprend l'appareil, son câble USB et le mini-CDROM contenant le driver Windows et le soft. Eh oui, bad news pour moi mais je le savais déjà, c'est sous Windows que la programmation de ma Silvercard va se passer.
L'appareil en lui-même est vraiment rikiki : environ 3cm sur 7cm, poids vraiment plume. A se demander s'il y a vraiment de l'électronique là-dedans.
J'ai installé d'abord le pilote et le logiciel, et ensuite branché l'appareil. Sa led s'est mise à clignoter rouge pendant un moment, puis elle est devenue définitivement bleue (les branchements suivants donnent du bleu directement).
Le logiciel est des plus simples : on choisit la carte à programmer (Silvercard pour moi), le fichier hex à envoyer dans le PIC, éventuellement le fichier hex à envoyer dans l'EEPROM externe au PIC et on clique sur "Write". La programmation dure environ 5 secondes, la led clignotant verte à ce seul moment. Dans le cas où un fichier hex est à envoyer dans l'EEPROM externe, le logiciel commence par charger dans le PIC un loader maison, s'adresse à lui comme intermédiaire pour écrire dans l'EEPROM, et ensuite seulement écrit le PIC avec le fichier hex du PIC.
Inutile de dire que j'avais un fichier hex réfléchi tout prêt à injecter dans le PIC. C'est là que les ennuis ont commencé. L'injection s'est très bien passé, par contre gscriptor sous Linux voyait ma carte comme "non alimentée" (donc quasi morte pour lui). Aucune communication ne s'établissait avec la carte.
J'ai donc carrément injecté dans la Silvercard le fichier hex brut de fonderie original duquel j'avais tiré les routines SEND et RECEIVE en ISO7816. C'était un fichier d'un vieux programme de piratage des cartes SECA MEDIAGUARD du début des années 2000. Après tout, c'est peut-être moi qui avait mal extrait les routines. Même topo avec ce fichier, carte non alimentée.
Là j'ai commencé à me dire que j'étais mal, parce qu'il faut absolument que je parte d'un programme dans lequel les routines SEND et RECEIVE fonctionnent, car c'est de l'horlogerie, quasi impossible à écrire soit-même. Me voilà donc condamné à chercher sur le net un programme pour Silvercard dans lequel les routines SEND et RECEIVE au format ISO7816 fonctionnent bien. Difficile à trouver car maintenant tout le monde utilise des MIFARE ou autres cartes NFC.
Eh bien j'ai trouvé un vieux programme de déplombage de la chaine de TV italienne RAI qui date de 2004 et qui, une fois injecté dans ma Silvercard a envoyé un ATR à gscriptor, et avec lequel je pouvais envoyer des APDU. Certes il répondait à chaque fois que l'APDU correspondait à une classe non implémentée, mais la communication se faisait. Pour la première fois je communiquais avec ma Silvercard!
Je reprennais espoir car, quand on a un programme qui marche tout est différent. On a un angle d'attaque. Problème tout de même : mon programme RAI fait 13 Ko compilé. Chercher les routines SEND et RECEIVE là-dedans revient à chercher une aiguille dans une meule de foin.
Bon, j'exagère un peu car, par définition, SEND et RECEIVE manipulent le bit 7 du registre PORTB (car c'est sur ce bit que se fait la communication extérieure). En faisant une recherche sur ce critère, j'ai assez vite isolé les 2 routines et je les ai extraites.
Je les ai reprises dans un programme simple de mon cru, une espèce de "hello world" pour les cartes à puce : ce programme envoie le même ATR que la carte RAI puis passe dans une boucle infinie qui lit 5 octets (ie 1 APDU : CLA INS P1 P2 Le) et renvoie systématiquement 90 00, quel que soit l'APDU reçu. On ne peut pas faire plus simple comme programme.
Pour être franc, j'étais sûr que cela ne marcherait pas, ou du moins pas du premier coup. Sauf que BINGO !!! mon programme marche parfaitement bien. Voici un petit échange entre mon programme et gscriptor.
Voici donc mon programme. C'est du brut de fonderie, le premier programme qui marche. A partir de lui, je vais petit à petit monter une vraie application carte à puce.
LIST P=16F876, F=INHX8M
include "P16F876.INC"
__CONFIG _BODEN_OFF & _CP_OFF & _WRT_ENABLE_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC & _DEBUG_OFF & _CPD_OFF & _LVP_OFF
ORG 0x60
IODATA RES 1
BIT_COUNT RES 1
PARITY RES 1
TEMPO RES 1
ORG 0x0000
GOTO INIT
ORG 0x0004
RETFIE
SEND MOVWF IODATA
MOVLW 0x32
CALL WAIT2
BCF 0x6,7
MOVLW 0x7f
BSF STATUS,RP0
MOVWF TRISB
BCF STATUS,RP0
CLRF PARITY
MOVLW 0x8
MOVWF BIT_COUNT
BOUCLE_SEND
CALL WAIT1
RRF IODATA,F
RRF IODATA,W
ANDLW 0x80
XORWF PARITY,F
XORWF 0x6,W
XORWF 0x6,F
DECFSZ BIT_COUNT,F
GOTO BOUCLE_SEND
CALL WAIT1
MOVF PARITY,W
XORWF 0x6,W
XORWF 0x6,F
CALL WAIT1
MOVLW 0xff
BSF STATUS,RP0
MOVWF TRISB
BCF STATUS,RP0
MOVLW 0x3e
GOTO WAIT2
RECEIVE BTFSC 0x6,7
GOTO RECEIVE
MOVLW 0x2d
CALL WAIT2
MOVLW 0x9
MOVWF BIT_COUNT
BOUCLE_RECEIVE
BCF 0x3,0
BTFSC 0x6,7
BSF 0x3,0
RRF IODATA,F
CALL WAIT1
NOP
NOP
DECFSZ BIT_COUNT,F
GOTO BOUCLE_RECEIVE
RLF IODATA,F
MOVLW 0x1d
CALL WAIT2
MOVF IODATA,W
RETURN
WAIT1 MOVLW 0x1a
WAIT2 MOVWF TEMPO
BWAIT DECFSZ TEMPO,F
GOTO BWAIT
RETLW 0x0
INIT
BSF STATUS,RP0 ; select bank1
BCF OPTION_REG,7 ; enable pull-ups
BCF STATUS,RP0
CALL WAIT1
MOVLW 0x3B ; ATR 3B F7 11 00 01 40 96 54 30 04 0E 6C B6 D6
CALL SEND
MOVLW 0xF7
CALL SEND
MOVLW 0x11
CALL SEND
MOVLW 0x00
CALL SEND
MOVLW 0x01
CALL SEND
MOVLW 0x40
CALL SEND
MOVLW 0x96
CALL SEND
MOVLW 0x54
CALL SEND
MOVLW 0x30
CALL SEND
MOVLW 0x04
CALL SEND
MOVLW 0x0E
CALL SEND
MOVLW 0x6C
CALL SEND
MOVLW 0xB6
CALL SEND
MOVLW 0xD6
CALL SEND
BOUCLE CALL RECEIVE
CALL RECEIVE
CALL RECEIVE
CALL RECEIVE
CALL RECEIVE
MOVLW 0x90
CALL SEND
MOVLW 0x00
CALL SEND
END
include "P16F876.INC"
__CONFIG _BODEN_OFF & _CP_OFF & _WRT_ENABLE_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC & _DEBUG_OFF & _CPD_OFF & _LVP_OFF
ORG 0x60
IODATA RES 1
BIT_COUNT RES 1
PARITY RES 1
TEMPO RES 1
ORG 0x0000
GOTO INIT
ORG 0x0004
RETFIE
SEND MOVWF IODATA
MOVLW 0x32
CALL WAIT2
BCF 0x6,7
MOVLW 0x7f
BSF STATUS,RP0
MOVWF TRISB
BCF STATUS,RP0
CLRF PARITY
MOVLW 0x8
MOVWF BIT_COUNT
BOUCLE_SEND
CALL WAIT1
RRF IODATA,F
RRF IODATA,W
ANDLW 0x80
XORWF PARITY,F
XORWF 0x6,W
XORWF 0x6,F
DECFSZ BIT_COUNT,F
GOTO BOUCLE_SEND
CALL WAIT1
MOVF PARITY,W
XORWF 0x6,W
XORWF 0x6,F
CALL WAIT1
MOVLW 0xff
BSF STATUS,RP0
MOVWF TRISB
BCF STATUS,RP0
MOVLW 0x3e
GOTO WAIT2
RECEIVE BTFSC 0x6,7
GOTO RECEIVE
MOVLW 0x2d
CALL WAIT2
MOVLW 0x9
MOVWF BIT_COUNT
BOUCLE_RECEIVE
BCF 0x3,0
BTFSC 0x6,7
BSF 0x3,0
RRF IODATA,F
CALL WAIT1
NOP
NOP
DECFSZ BIT_COUNT,F
GOTO BOUCLE_RECEIVE
RLF IODATA,F
MOVLW 0x1d
CALL WAIT2
MOVF IODATA,W
RETURN
WAIT1 MOVLW 0x1a
WAIT2 MOVWF TEMPO
BWAIT DECFSZ TEMPO,F
GOTO BWAIT
RETLW 0x0
INIT
BSF STATUS,RP0 ; select bank1
BCF OPTION_REG,7 ; enable pull-ups
BCF STATUS,RP0
CALL WAIT1
MOVLW 0x3B ; ATR 3B F7 11 00 01 40 96 54 30 04 0E 6C B6 D6
CALL SEND
MOVLW 0xF7
CALL SEND
MOVLW 0x11
CALL SEND
MOVLW 0x00
CALL SEND
MOVLW 0x01
CALL SEND
MOVLW 0x40
CALL SEND
MOVLW 0x96
CALL SEND
MOVLW 0x54
CALL SEND
MOVLW 0x30
CALL SEND
MOVLW 0x04
CALL SEND
MOVLW 0x0E
CALL SEND
MOVLW 0x6C
CALL SEND
MOVLW 0xB6
CALL SEND
MOVLW 0xD6
CALL SEND
BOUCLE CALL RECEIVE
CALL RECEIVE
CALL RECEIVE
CALL RECEIVE
CALL RECEIVE
MOVLW 0x90
CALL SEND
MOVLW 0x00
CALL SEND
END
Aucun commentaire:
Enregistrer un commentaire