first beta - patch sent to librfid list
[rfid/librfid.git] / gemtag / gemtag.c
index 48dc427..e674d49 100644 (file)
@@ -1,5 +1,6 @@
 /*
- *  (C) 2006 by Frank Zirkelbach <hackbard@hackdaworld.org>
+ *  (C) 2006 by Harald Welte <laforge@gnumonks.org>
+ *              Frank Zirkelbach <hackbard@hackdaworld.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 
 #include "gemtag.h"
 
 int asciidump(unsigned char *data,int len) {
+
        int i;
 
        for(i=0;i<len;i++)
-               if((data[i]>0x19)&&(data[i]<0x7f)) printf("%c",data[i]);
-               else printf("_");
-       //printf("\n");
+               printf("%c",(data[i]>0x19)&&(data[i]<0x7f)?data[i]:'.');
 
        return 0;
 }
 
 int hexdump(unsigned char *data,int len) {
+
        int i;
 
        for(i=0;i<len;i++) printf("%02x ",data[i]);
-       //printf("\n");
 
        return 0;
 }
@@ -181,6 +181,7 @@ int gemtag_transceive(struct gemtag_handle *gh,unsigned char cmd,
 }
 
 struct gemtag_handle *gemtag_open(void) {
+
        struct usb_device *gemtag;
        unsigned int i;
        struct gemtag_handle *gh;
@@ -252,8 +253,33 @@ int gemtag_transform_mifare_key(struct gemtag_handle *gh,
        return 0;
 }
 
+int gemtag_auth_e2(struct gemtag_handle *gh,unsigned char authmode,
+                   int sector,unsigned char *key6) {
+
+       unsigned char buf[32];
+       unsigned int len,ret;
+
+       /* memory layout (sector/block) ? */
+
+       buf[0]=authmode;
+       buf[1]=0;
+       memcpy(buf+2,key6,6);
+       ret=gemtag_transceive(gh,GEMTAG_CMD_PCD_LOAD_KEY_E2,buf,8,buf,&len);
+       if(ret) return -LOAD_E2_FAILED;
+
+       buf[0]=authmode;
+       memcpy(buf+1,gh->serial,4);
+       buf[5]=0;
+       buf[6]=sector;
+       ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_AUTH_E2,buf,7,buf,&len);
+       if(ret) return -AUTH_E2_FAILED;
+
+       return 0;
+
+}
+
 int gemtag_auth_mifare_key(struct gemtag_handle *gh,
-                    unsigned char *key6,int sector) {
+                           unsigned char *key6,int sector) {
 
        unsigned char key12[12];        
        unsigned char buf[32];
@@ -261,7 +287,7 @@ int gemtag_auth_mifare_key(struct gemtag_handle *gh,
 
        gemtag_transform_mifare_key(gh,key6,key12);
                             
-       buf[0]=0x60; /* auth mode */
+       buf[0]=GEMTAG_PICC_AUTHENT1A;   /* auth mode */
        memcpy(buf+1,gh->serial,4);     /* sreial */
        memcpy(buf+5,key12,12);         /* transformed key */
        buf[17]=sector;                 /* sector */
@@ -272,21 +298,32 @@ int gemtag_auth_mifare_key(struct gemtag_handle *gh,
        return 0;
 }
 
-int gemtag_read16(struct gemtag_handle *gh,int sector,
-                  unsigned char *data) {
+int gemtag_read16(struct gemtag_handle *gh,int sector,unsigned char *data) {
 
        unsigned char buf[32];
        int len,ret;
 
        buf[0]=sector;
-       ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_READ,
-                             buf,1,data,&len);
+       ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_READ,buf,1,data,&len);
        if(ret) return -READ_FAILED;
 
        return 0;
 }
 
-int gemtag_pick_picc(struct gemtag_handle *gh) {
+int gemtag_write16(struct gemtag_handle *gh,int sector,unsigned char *data) {
+
+       unsigned char buf[32];
+       int ret,len;
+
+       buf[0]=sector;
+       memcpy(buf+1,data,16);
+       ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_WRITE,buf,17,buf,&len);
+       if(ret) return -WRITE_FAILED;
+
+       return 0;
+}
+
+int gemtag_select_picc(struct gemtag_handle *gh) {
 
        unsigned char buf[16];
        unsigned int len;
@@ -309,28 +346,20 @@ int gemtag_pick_picc(struct gemtag_handle *gh) {
 
        return 0;
 }
-       
+
 int main(int argc, char **argv) {
 
        struct gemtag_handle *gh;
        unsigned char buf[256];
        unsigned char key6[6];
-       int i;
+       int i,ret;
 
        gh=gemtag_open();
 
        gh->caps|=GEMTAG_CAP_CRC;
        //gh->caps|=GEMTAG_CAP_VERB_TRANSMIT;
 
-       /*
-       printf("Device:\n");
-       gemtag_transceive(gh,GEMTAG_CMD_GET_FW_VERSION,
-                         NULL,0,buf,&buflen);
-       asciidump(buf,buflen);
-       printf("\n");
-       */
-
-       if(gemtag_pick_picc(gh)) {
+       if(gemtag_select_picc(gh)) {
                printf("no card found!\n");
                return -NO_PICC;
        }
@@ -338,17 +367,17 @@ int main(int argc, char **argv) {
        memset(key6,0xff,6);
        printf("\nreading sectors ... (serial: %02x %02x %02x %02x)\n\n",
               gh->serial[3],gh->serial[2],gh->serial[1],gh->serial[0]);
-       for(i=0;i<256;i++) {
-               gemtag_auth_mifare_key(gh,key6,i);
-               if(!gemtag_read16(gh,i,buf)) {
-                       printf("%02x: ",i++);
-                       hexdump(buf,16);
-                       printf(" | ");
-                       asciidump(buf,16);
-                       printf("\n");
-               }
-               else return 0;
+       i=0;
+       while(!gemtag_auth_mifare_key(gh,key6,i)) {
+               ret=gemtag_read16(gh,i,buf);
+               printf("%02x: ",i);
+               hexdump(buf,16);
+               printf(" | ");
+               asciidump(buf,16);
+               printf("\n");
+               i+=1;
        }
+       printf("\n");
 
        gemtag_close(gh);