basic stuff implemented, reading out mifare with std key 0xff
authorhackbard <hackbard>
Tue, 7 Mar 2006 15:21:30 +0000 (15:21 +0000)
committerhackbard <hackbard>
Tue, 7 Mar 2006 15:21:30 +0000 (15:21 +0000)
gemtag/gemtag.c
gemtag/gemtag.h

index c2b24d7..48dc427 100644 (file)
@@ -30,7 +30,7 @@ int asciidump(unsigned char *data,int len) {
        for(i=0;i<len;i++)
                if((data[i]>0x19)&&(data[i]<0x7f)) printf("%c",data[i]);
                else printf("_");
-       printf("\n");
+       //printf("\n");
 
        return 0;
 }
@@ -39,7 +39,7 @@ int hexdump(unsigned char *data,int len) {
        int i;
 
        for(i=0;i<len;i++) printf("%02x ",data[i]);
-       printf("\n");
+       //printf("\n");
 
        return 0;
 }
@@ -86,9 +86,9 @@ u_int16_t gemtag_calc_crc(unsigned char *data,u_int16_t len) {
        return crc;
 }
 
-int gemtag_transcieve(struct gemtag_handle *gh,unsigned char cmd,
-                         unsigned char *tx,unsigned int tx_len,
-                         unsigned char *rx,unsigned int *rx_len) {
+int gemtag_transceive(struct gemtag_handle *gh,unsigned char cmd,
+                      unsigned char *tx,unsigned int tx_len,
+                      unsigned char *rx,unsigned int *rx_len) {
 
        unsigned char txbuf[256];
        unsigned char rxbuf[256];
@@ -136,8 +136,7 @@ int gemtag_transcieve(struct gemtag_handle *gh,unsigned char cmd,
        }
        if(ret<5) {
                if(gh->caps&GEMTAG_CAP_VERB_TRANSMIT)
-                       printf("short answer (%d)\n",ret);
-               return -SHORT_ANSWER;
+                       return -SHORT_ANSWER;
        }
 
        *rx_len=rxbuf[3]|(rxbuf[4]<<8);
@@ -166,17 +165,15 @@ int gemtag_transcieve(struct gemtag_handle *gh,unsigned char cmd,
                size-=2;
                crcptr=(u_int16_t *)(rxbuf+size);
                crc=gemtag_calc_crc(rxbuf,size);
-               if(((crc>>8)!=rxbuf[size+1])||((crc&0xff)!=rxbuf[size])) {
-                       printf("bad crc! (%04x)\n",crc);
+               if(((crc>>8)!=rxbuf[size+1])||((crc&0xff)!=rxbuf[size]))
                        return -BAD_CRC;
-               }
        }
 
        /* check sequence number */     
-       if(rxhdr->seq!=txhdr->seq) {
-               puts("transmitted/recieved sequence number do not match");
-               return -SEQ_MISMATCH;
-       }
+       if(rxhdr->seq!=txhdr->seq) return -SEQ_MISMATCH;
+
+       /* check return code */
+       if(rxbuf[2]) return -CMD_FAILED;
 
        memcpy(rx,rxbuf+sizeof(struct gemtag_cmd_hdr),*rx_len);
 
@@ -222,11 +219,13 @@ struct gemtag_handle *gemtag_open(void) {
                perror("claim interface");
                goto out_free;
        }
-       printf("claimed interface 0");
+       printf("claimed interface 0\n");
 
+       /*
        if(usb_set_altinterface(gh->handle,0))
                perror("set alt interface");
        printf("activated alt setting 0\n");
+       */
 
        return gh;
 
@@ -243,49 +242,116 @@ int gemtag_close(struct gemtag_handle *gh) {
        return 0;
 }
 
+int gemtag_transform_mifare_key(struct gemtag_handle *gh,
+                         unsigned char *key6,unsigned char *key12) {
+
+       unsigned int len;
+
+       gemtag_transceive(gh,GEMTAG_CMD_HOST_CODE_KEY,key6,6,key12,&len);
+
+       return 0;
+}
+
+int gemtag_auth_mifare_key(struct gemtag_handle *gh,
+                    unsigned char *key6,int sector) {
+
+       unsigned char key12[12];        
+       unsigned char buf[32];
+       unsigned int len,ret;
+
+       gemtag_transform_mifare_key(gh,key6,key12);
+                            
+       buf[0]=0x60; /* auth mode */
+       memcpy(buf+1,gh->serial,4);     /* sreial */
+       memcpy(buf+5,key12,12);         /* transformed key */
+       buf[17]=sector;                 /* sector */
+       ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_AUTH_KEY,buf,18,
+                             buf,&len);
+       if(ret) return -AUTH_FAILED;
+
+       return 0;
+}
+
+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);
+       if(ret) return -READ_FAILED;
+
+       return 0;
+}
+
+int gemtag_pick_picc(struct gemtag_handle *gh) {
+
+       unsigned char buf[16];
+       unsigned int len;
+       int ret;
+
+       buf[0]=GEMTAG_PICC_REQIDL;
+       ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_REQUEST,buf,1,buf,&len);
+       if(ret) return -NO_PICC;
+
+       buf[0]=GEMTAG_PICC_STD_SELECT_CODE;
+       memset(buf+1,0,5);
+       ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_CASC_ANTICOLL,buf,6,buf,&len);
+       if(ret) return -NO_PICC;
+       memcpy(gh->serial,buf,4);
+
+       buf[0]=GEMTAG_PICC_STD_SELECT_CODE;
+       memcpy(buf+1,gh->serial,4);
+       ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_CASC_SELECT,buf,5,buf,&len);
+       if(ret) return -PICC_SELECT_ERROR;
+
+       return 0;
+}
        
 int main(int argc, char **argv) {
 
        struct gemtag_handle *gh;
        unsigned char buf[256];
-       unsigned int buflen;
+       unsigned char key6[6];
+       int i;
 
        gh=gemtag_open();
 
        gh->caps|=GEMTAG_CAP_CRC;
-       gh->caps|=GEMTAG_CAP_VERB_TRANSMIT;
+       //gh->caps|=GEMTAG_CAP_VERB_TRANSMIT;
 
+       /*
        printf("Device:\n");
-       gemtag_transcieve(gh,GEMTAG_CMD_GET_FW_VERSION,
+       gemtag_transceive(gh,GEMTAG_CMD_GET_FW_VERSION,
                          NULL,0,buf,&buflen);
        asciidump(buf,buflen);
        printf("\n");
+       */
 
-       printf("Serial Number:\n");
-       gemtag_transcieve(gh,GEMTAG_CMD_GET_SERIAL_NUMBER,
-                         NULL,0,buf,&buflen);
-       printf("Snr: %d (%04x)\n",buf[1]<<8|buf[0],buf[1]<<8|buf[0]);
-       printf("\n");
-
-       printf("RC632 Version:\n");
-       gemtag_transcieve(gh,GEMTAG_CMD_GET_RIC_VERSION,
-                         NULL,0,buf,&buflen);
-       printf("\n");
-
-       printf("Switching off the LED!\n");
-       buf[0]=GEMTAG_LED_OFF;
-       gemtag_transcieve(gh,GEMTAG_CMD_SWITCH_LED,
-                         buf,1,buf,&buflen);
-       printf("\n");
+       if(gemtag_pick_picc(gh)) {
+               printf("no card found!\n");
+               return -NO_PICC;
+       }
 
-       printf("Detecting Card ...\n");
-       gemtag_transcieve(gh,GEMTAG_CMD_DETECT_CARD,
-                         NULL,0,buf,&buflen);
-       asciidump(buf,buflen);
-       printf("\n");
+       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;
+       }
 
        gemtag_close(gh);
 
-       return 1;
+       return 0;
 }
 
index be203d4..d1bef96 100644 (file)
@@ -25,7 +25,7 @@ struct gemtag_handle {
        struct usb_dev_handle *handle;
        unsigned char seq;
        unsigned char caps;
-       unsigned char snr[4];
+       unsigned char serial[4];
 };
 
 #define GEMTAG_CAP_CRC                 0x01
@@ -41,32 +41,14 @@ struct gemtag_cmd_hdr {
 #define BAD_CRC                                0x01
 #define SEQ_MISMATCH                   0x02
 #define SHORT_ANSWER                   0x03
+#define CMD_FAILED                     0x04
+#define AUTH_FAILED                    0x05
+#define READ_FAILED                    0x06
+#define NO_PICC                                0x07
+#define PICC_SELECT_ERROR              0x08
 
 /* gemtag commands */
 
-#define GEMTAG_CMD_GET_FW_VERSION      0x63
-#define GEMTAG_CMD_GET_RIC_VERSION     0x64
-
-#define GEMTAG_CMD_SET_CPU_TIMEOUT     0x88
-
-
-#define GEMTAG_CMD_PICC_EXCHANGE_BLOCK 0x48
-
-
-
-#define GEMTAG_CMD_PICC_ACTIVATE_IDLE  0x43
-#define GEMTAG_CMD_PICC_ACTIVATE_WAKEUP        0x44
-
-#define GEMTAG_CMD_PICC_REQUEST                0x40
-#define GEMTAG_PICC_REQALL             0x52
-#define GEMTAG_PICC_REQIDL             0x26
-
-#define GEMTAG_CMD_PICC_CASC_ANTICOLL  0x41
-#define GEMTAG_CMD_PICC_CASC_SELECT    0x42
-#define GEMTAG_PICC_STD_SELECT_CODE    0x93
-#define GEMTAG_PICC_CASC_LEVEL1                0x95
-#define GEMTAG_PICC_CASC_LEVEL2                0x97
-
 #define GEMTAG_CMD_PCD_CONFIG          0x10
 #define GEMTAG_CMD_PICC_ANTICOLL       0x12
 #define GEMTAG_CMD_PICC_SELECT         0x13
@@ -83,42 +65,51 @@ struct gemtag_cmd_hdr {
 #define GEMTAG_CMD_PICC_WRITE          0x1a
 #define GEMTAG_CMD_PICC_VALUE          0x1b
 #define GEMTAG_CMD_PICC_VALUE_DEBIT    0x1c
-#define GEMTAG_PICC_INCREMENT          
-#define GEMTAG_PICC_DECREMENT          
-#define GEMTAG_PICC_RESTORE
 #define GEMTAG_CMD_PICC_HALT           0x1d
 #define GEMTAG_CMD_PICC_WRITE4         0x1e
 #define GEMTAG_CMD_COMMON_WRITE                0x1f
-#define GEMTAG_PICC_WRITE16
-#define GEMTAG_PICC_WRITE4
-
 #define GEMTAG_CMD_PCD_RF_RESET                0x20
-
 #define GEMTAG_CMD_GET_SERIAL_NUMBER   0x22
-
 #define GEMTAG_CMD_PCD_READ_E2         0x23
 #define GEMTAG_CMD_PCD_WRITE_E2                0x24
-
-#define GEMTAG_CMD_PCD_SET_TMO         0x27
-
 #define GEMTAG_CMD_PICC_COMMON_READ    0x28
+#define GEMTAG_PICC_DECREMENT          
+#define GEMTAG_PICC_INCREMENT          
 #define GEMTAG_PICC_READ16
+#define GEMTAG_PICC_RESTORE
+#define GEMTAG_PICC_WRITE16
+#define GEMTAG_PICC_WRITE4
 
-#define GEMTAG_CMD_SET_ATTRIBUTES      0x46
-#define GEMTAG_CMD_SET_DFLT_ATTRIBUTES 0x45
+#define GEMTAG_CMD_PICC_REQUEST                0x40
+#define GEMTAG_PICC_REQIDL             0x26
+#define GEMTAG_CMD_PCD_SET_TMO         0x27
 
-#define GEMTAG_CMD_PPS_REQUEST         0xa0
-#define GEMTAG_CMD_DESELECT            0xa1
+#define GEMTAG_CMD_PICC_CASC_ANTICOLL  0x41
+#define GEMTAG_CMD_PICC_CASC_SELECT    0x42
+#define GEMTAG_PICC_STD_SELECT_CODE    0x93
+#define GEMTAG_PICC_CASC_LEVEL1                0x95
+#define GEMTAG_PICC_CASC_LEVEL2                0x97
 
-#define GEMTAG_CMD_SET_DEFAULT_BAUDRATE        0x81
-#define GEMTAG_CMD_SET_ONLINE_BAUDRATE 0x82
+#define GEMTAG_CMD_PICC_ACTIVATE_IDLE  0x43
+#define GEMTAG_CMD_PICC_ACTIVATE_WAKEUP        0x44
+#define GEMTAG_CMD_SET_DFLT_ATTRIBUTES 0x45
+#define GEMTAG_CMD_SET_ATTRIBUTES      0x46
+#define GEMTAG_CMD_PICC_EXCHANGE_BLOCK 0x48
+#define GEMTAG_PICC_REQALL             0x52
 
 #define GEMTAG_CMD_SWITCH_LED          0x60
 #define GEMTAG_LED_OFF                 0x00
 #define GEMTAG_LED_ON                  0x01
 
+#define GEMTAG_CMD_GET_FW_VERSION      0x63
+#define GEMTAG_CMD_GET_RIC_VERSION     0x64
+#define GEMTAG_CMD_SET_DEFAULT_BAUDRATE        0x81
+#define GEMTAG_CMD_SET_ONLINE_BAUDRATE 0x82
+#define GEMTAG_CMD_SET_CPU_TIMEOUT     0x88
+
 #define GEMTAG_CMD_DETECT_CARD         0x92
 #define GEMTAG_CMD_DETECT_ISO15693_CARD        0x93
-
+#define GEMTAG_CMD_PPS_REQUEST         0xa0
+#define GEMTAG_CMD_DESELECT            0xa1
 
 #endif