2 * (C) 2006 by Harald Welte <laforge@gnumonks.org>
3 * Frank Zirkelbach <hackbard@hackdaworld.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 int asciidump(unsigned char *data,int len) {
33 printf("%c",(data[i]>0x19)&&(data[i]<0x7f)?data[i]:'.');
38 int hexdump(unsigned char *data,int len) {
42 for(i=0;i<len;i++) printf("%02x ",data[i]);
47 struct usb_device *find_device(unsigned short vendor,unsigned short device) {
50 struct usb_device *dev;
56 if(dev->descriptor.idVendor==vendor &&
57 dev->descriptor.idProduct==device)
66 u_int16_t gemtag_calc_crc(unsigned char *data,u_int16_t len) {
68 u_int16_t crc_polynom;
81 crc=(crc>>1)^crc_polynom;
89 int gemtag_transceive(struct gemtag_handle *gh,unsigned char cmd,
90 unsigned char *tx,unsigned int tx_len,
91 unsigned char *rx,unsigned int *rx_len) {
93 unsigned char txbuf[256];
94 unsigned char rxbuf[256];
95 struct gemtag_cmd_hdr *txhdr;
96 struct gemtag_cmd_hdr *rxhdr;
97 u_int16_t crc,*crcptr;
100 txhdr=(struct gemtag_cmd_hdr *)txbuf;
101 rxhdr=(struct gemtag_cmd_hdr *)rxbuf;
104 txhdr->seq=++(gh->seq);
107 size=sizeof(struct gemtag_cmd_hdr);
108 memcpy(txbuf+size,tx,tx_len);
112 if(gh->caps&GEMTAG_CAP_CRC) {
113 crcptr=(u_int16_t *)(txbuf+size);
114 crc=gemtag_calc_crc(txbuf,size);
115 //*crcptr=(crc>>8)|(crc<<8);
121 if(gh->caps&GEMTAG_CAP_VERB_TRANSMIT) {
122 printf("(%02d) -> ",size);
125 ret=usb_interrupt_write(gh->handle,0x02,txbuf,size,0);
127 perror("usb interrupt write");
132 ret=usb_interrupt_read(gh->handle,0x81,rxbuf,32,0);
134 perror("usb interrupt read");
138 if(gh->caps&GEMTAG_CAP_VERB_TRANSMIT)
139 return -SHORT_ANSWER;
142 *rx_len=rxbuf[3]|(rxbuf[4]<<8);
143 size=*rx_len+sizeof(struct gemtag_cmd_hdr);
144 if(gh->caps&GEMTAG_CAP_CRC) size+=2;
149 ret=usb_interrupt_read(gh->handle,0x81,rxbuf+i*32,32,0);
151 perror("usb interrupt read (missing bytes)");
158 if(gh->caps&GEMTAG_CAP_VERB_TRANSMIT) {
159 printf("(%02d) <- ",size);
164 if(gh->caps&GEMTAG_CAP_CRC) {
166 crcptr=(u_int16_t *)(rxbuf+size);
167 crc=gemtag_calc_crc(rxbuf,size);
168 if(((crc>>8)!=rxbuf[size+1])||((crc&0xff)!=rxbuf[size]))
172 /* check sequence number */
173 if(rxhdr->seq!=txhdr->seq) return -SEQ_MISMATCH;
175 /* check return code */
176 if(rxbuf[2]) return -CMD_FAILED;
178 memcpy(rx,rxbuf+sizeof(struct gemtag_cmd_hdr),*rx_len);
183 struct gemtag_handle *gemtag_open(void) {
185 struct usb_device *gemtag;
187 struct gemtag_handle *gh;
194 gemtag=find_device(USB_VENDOR_GEMTAG,USB_DEVICE_X501);
195 if(!gemtag) return NULL;
197 gh=malloc(sizeof(struct gemtag_handle));
200 memset(gh,0,sizeof(struct gemtag_handle));
202 gh->handle=usb_open(gemtag);
207 memset(info,0,sizeof(info));
208 usb_get_string_simple(gh->handle,i,info,sizeof(info));
211 printf("opened successfully\n");
213 if(usb_set_configuration(gh->handle,1)) {
214 perror("set config");
217 printf("set configuration 1, ");
219 if(usb_claim_interface(gh->handle,0)) {
220 perror("claim interface");
223 printf("claimed interface 0\n");
226 if(usb_set_altinterface(gh->handle,0))
227 perror("set alt interface");
228 printf("activated alt setting 0\n");
238 int gemtag_close(struct gemtag_handle *gh) {
240 if(gh->handle) usb_close(gh->handle);
246 int gemtag_transform_mifare_key(struct gemtag_handle *gh,
247 unsigned char *key6,unsigned char *key12) {
251 gemtag_transceive(gh,GEMTAG_CMD_HOST_CODE_KEY,key6,6,key12,&len);
256 int gemtag_auth_e2(struct gemtag_handle *gh,unsigned char authmode,
257 int sector,unsigned char *key6) {
259 unsigned char buf[32];
260 unsigned int len,ret;
262 /* memory layout (sector/block) ? */
266 memcpy(buf+2,key6,6);
267 ret=gemtag_transceive(gh,GEMTAG_CMD_PCD_LOAD_KEY_E2,buf,8,buf,&len);
268 if(ret) return -LOAD_E2_FAILED;
271 memcpy(buf+1,gh->serial,4);
274 ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_AUTH_E2,buf,7,buf,&len);
275 if(ret) return -AUTH_E2_FAILED;
281 int gemtag_auth_mifare_key(struct gemtag_handle *gh,
282 unsigned char *key6,int sector) {
284 unsigned char key12[12];
285 unsigned char buf[32];
286 unsigned int len,ret;
288 gemtag_transform_mifare_key(gh,key6,key12);
290 buf[0]=GEMTAG_PICC_AUTHENT1A; /* auth mode */
291 memcpy(buf+1,gh->serial,4); /* sreial */
292 memcpy(buf+5,key12,12); /* transformed key */
293 buf[17]=sector; /* sector */
294 ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_AUTH_KEY,buf,18,
296 if(ret) return -AUTH_FAILED;
301 int gemtag_read16(struct gemtag_handle *gh,int sector,unsigned char *data) {
303 unsigned char buf[32];
307 ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_READ,buf,1,data,&len);
308 if(ret) return -READ_FAILED;
313 int gemtag_write16(struct gemtag_handle *gh,int sector,unsigned char *data) {
315 unsigned char buf[32];
319 memcpy(buf+1,data,16);
320 ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_WRITE,buf,17,buf,&len);
321 if(ret) return -WRITE_FAILED;
326 int gemtag_select_picc(struct gemtag_handle *gh) {
328 unsigned char buf[16];
332 buf[0]=GEMTAG_PICC_REQIDL;
333 ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_REQUEST,buf,1,buf,&len);
334 if(ret) return -NO_PICC;
336 buf[0]=GEMTAG_PICC_STD_SELECT_CODE;
338 ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_CASC_ANTICOLL,buf,6,buf,&len);
339 if(ret) return -NO_PICC;
340 memcpy(gh->serial,buf,4);
342 buf[0]=GEMTAG_PICC_STD_SELECT_CODE;
343 memcpy(buf+1,gh->serial,4);
344 ret=gemtag_transceive(gh,GEMTAG_CMD_PICC_CASC_SELECT,buf,5,buf,&len);
345 if(ret) return -PICC_SELECT_ERROR;
350 int main(int argc, char **argv) {
352 struct gemtag_handle *gh;
353 unsigned char buf[256];
354 unsigned char key6[6];
359 gh->caps|=GEMTAG_CAP_CRC;
360 //gh->caps|=GEMTAG_CAP_VERB_TRANSMIT;
362 if(gemtag_select_picc(gh)) {
363 printf("no card found!\n");
368 printf("\nreading sectors ... (serial: %02x %02x %02x %02x)\n\n",
369 gh->serial[3],gh->serial[2],gh->serial[1],gh->serial[0]);
371 while(!gemtag_auth_mifare_key(gh,key6,i)) {
372 ret=gemtag_read16(gh,i,buf);