- add size detection for mifare classic / ultralight
[librfid] / utils / librfid-tool.c
1 /* librfid-tool - a small command-line tool for librfid testing
2  *
3  * (C) 2005-2006 by Harald Welte <laforge@gnumonks.org>
4  *
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
8  *
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.
13  *
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
17  */
18
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <errno.h>
24 #include <libgen.h>
25
26 #define _GNU_SOURCE
27 #include <getopt.h>
28
29 #include <librfid/rfid.h>
30 #include <librfid/rfid_scan.h>
31 #include <librfid/rfid_reader.h>
32 #include <librfid/rfid_layer2.h>
33 #include <librfid/rfid_protocol.h>
34
35 #include <librfid/rfid_protocol_mifare_classic.h>
36 #include <librfid/rfid_protocol_mifare_ul.h>
37
38 #include "librfid-tool.h"
39
40
41 static int select_mf(void)
42 {
43         unsigned char cmd[] = { 0x00, 0xa4, 0x00, 0x00, 0x02, 0x3f, 0x00, 0x00 };
44         unsigned char ret[256];
45         unsigned int rlen = sizeof(ret);
46
47         int rv;
48
49         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
50         if (rv < 0)
51                 return rv;
52
53         printf("%d: [%s]\n", rlen, hexdump(ret, rlen));
54
55         return 0;
56 }
57
58
59 static int iso7816_get_challenge(unsigned char len)
60 {
61         unsigned char cmd[] = { 0x00, 0x84, 0x00, 0x00, 0x08 };
62         unsigned char ret[256];
63         unsigned int rlen = sizeof(ret);
64
65         cmd[4] = len;
66
67         int rv;
68
69         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), ret, &rlen, 0, 0);
70         if (rv < 0)
71                 return rv;
72
73         printf("%d: [%s]\n", rlen, hexdump(ret, rlen));
74
75         return 0;
76 }
77
78 int
79 iso7816_select_application(void)
80 {
81         unsigned char cmd[] = { 0x00, 0xa4, 0x04, 0x0c, 0x07,
82                        0xa0, 0x00, 0x00, 0x02, 0x47, 0x10, 0x01 };
83         unsigned char resp[7];
84         unsigned int rlen = sizeof(resp);
85
86         int rv;
87
88         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
89         if (rv < 0)
90                 return rv;
91
92         /* FIXME: parse response */
93         printf("%s\n", hexdump(resp, rlen));
94
95         return 0;
96 }
97
98 int
99 iso7816_select_ef(u_int16_t fid)
100 {
101         unsigned char cmd[7] = { 0x00, 0xa4, 0x02, 0x0c, 0x02, 0x00, 0x00 };
102         unsigned char resp[7];
103         unsigned int rlen = sizeof(resp);
104
105         int rv;
106
107         cmd[5] = (fid >> 8) & 0xff;
108         cmd[6] = fid & 0xff;
109
110         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
111         if (rv < 0)
112                 return rv;
113
114         /* FIXME: parse response */
115         printf("%s\n", hexdump(resp, rlen));
116
117         return 0;
118 }
119
120 int
121 iso7816_read_binary(unsigned char *buf, unsigned int *len)
122 {
123         unsigned char cmd[] = { 0x00, 0xb0, 0x00, 0x00, 0x00 };
124         unsigned char resp[256];
125         unsigned int rlen = sizeof(resp);
126         
127         int rv;
128
129         rv = rfid_protocol_transceive(ph, cmd, sizeof(cmd), resp, &rlen, 0, 0);
130         if (rv < 0)
131                 return rv;
132
133         printf("%s\n", hexdump(resp, rlen));
134
135         /* FIXME: parse response, determine whether we need additional reads */
136
137         /* FIXME: copy 'len' number of response bytes to 'buf' */
138         return 0;
139 }
140
141 /* wrapper function around SELECT EF and READ BINARY */
142 int
143 iso7816_read_ef(u_int16_t fid, unsigned char *buf, unsigned int *len)
144 {
145         int rv;
146
147         rv = iso7816_select_ef(fid);
148         if (rv < 0)
149                 return rv;
150
151         return iso7816_read_binary(buf, len);
152 }
153
154 /* mifare ultralight helpers */
155 int
156 mifare_ulight_write(struct rfid_protocol_handle *ph)
157 {
158         unsigned char buf[4] = { 0xa1, 0xa2, 0xa3, 0xa4 };
159
160         return rfid_protocol_write(ph, 10, buf, 4);
161 }
162
163 int
164 mifare_ulight_blank(struct rfid_protocol_handle *ph)
165 {
166         unsigned char buf[4] = { 0x00, 0x00, 0x00, 0x00 };
167         int i, ret;
168
169         for (i = 4; i <= MIFARE_UL_PAGE_MAX; i++) {
170                 ret = rfid_protocol_write(ph, i, buf, 4);
171                 if (ret < 0)
172                         return ret;
173         }
174         return 0;
175 }
176
177 static int
178 mifare_ulight_read(struct rfid_protocol_handle *ph)
179 {
180         unsigned char buf[20];
181         unsigned int len = sizeof(buf);
182         int ret;
183         int i;
184
185         for (i = 0; i <= MIFARE_UL_PAGE_MAX; i++) {
186                 ret = rfid_protocol_read(ph, i, buf, &len);
187                 if (ret < 0)
188                         return ret;
189
190                 printf("Page 0x%x: %s\n", i, hexdump(buf, 4));
191         }
192         return 0;
193 }
194
195 /* mifare classic helpers */
196 static int
197 mifare_classic_read_sector(struct rfid_protocol_handle *ph, int sector)
198 {
199         unsigned char buf[20];
200         unsigned int len = sizeof(buf);
201         int ret;
202         int block;
203
204         /* FIXME: make this work for sectors > 31 */
205         printf("Reading sector %u\n", sector);
206
207         for (block = sector*4; block < sector*4+4; block++) {
208                 printf("Reading block %u: ", block);
209                 ret = rfid_protocol_read(ph, block, buf, &len);
210                 if(ret == -ETIMEDOUT)
211                         fprintf(stderr, "TIMEOUT\n");
212                 if (ret < 0) {
213                         printf("Error %d reading\n", ret);
214                         return ret;
215                 }
216
217                 printf("Page 0x%x: %s\n", block, hexdump(buf, len));
218         }
219         return 0;
220 }
221
222 static char *proto_names[] = {
223         [RFID_PROTOCOL_TCL] = "tcl",
224         [RFID_PROTOCOL_MIFARE_UL] = "mifare-ultralight",
225         [RFID_PROTOCOL_MIFARE_CLASSIC] = "mifare-classic",
226 };
227
228 static int proto_by_name(const char *name)
229 {
230         int i;
231
232         for (i = 0; i < ARRAY_SIZE(proto_names); i++) {
233                 if (proto_names[i] == NULL)
234                         continue;
235                 if (!strcasecmp(name, proto_names[i]))
236                         return i;
237         }
238         return -1;
239 }
240
241 static char *l2_names[] = {
242         [RFID_LAYER2_ISO14443A] = "iso14443a",
243         [RFID_LAYER2_ISO14443B] = "iso14443b",
244         [RFID_LAYER2_ISO15693] = "iso15693",
245 };
246
247 static int l2_by_name(const char *name)
248 {
249         int i;
250
251         for (i = 0; i < ARRAY_SIZE(l2_names); i++) {
252                 if (l2_names[i] == NULL)
253                         continue;
254                 if (!strcasecmp(name, l2_names[i]))
255                         return i;
256         }
257         return -1;
258 }
259
260 static void do_scan(void)
261 {
262         int rc;
263         unsigned int size;
264         unsigned int size_len = sizeof(size);
265
266         printf("scanning for RFID token...\n");
267         rc = rfid_scan(rh, &l2h, &ph);
268         if (rc >= 2) {
269                 unsigned char uid_buf[16];
270                 unsigned int uid_len = sizeof(uid_buf);
271                 rfid_layer2_getopt(l2h, RFID_OPT_LAYER2_UID, &uid_buf,
272                                    &uid_len);
273                 printf("Layer 2 success (%s): %s\n", rfid_layer2_name(l2h),
274                         hexdump(uid_buf, uid_len));
275         }
276         if (rc >= 3) {
277                 printf("Protocol success (%s)\n", rfid_protocol_name(ph));
278
279                 if (rfid_protocol_getopt(ph, RFID_OPT_PROTO_SIZE, 
280                                          &size, &size_len) == 0)
281                         printf("Size: %u bytes\n", size);
282         }
283 }
284
285 #define OPTION_OFFSET 256
286
287 static struct option original_opts[] = {
288         { "help", 0, 0, 'h' },
289         { "layer2", 1, 0, 'l' },
290         { "protocol", 1, 0, 'p' },
291         { "scan", 0, 0, 's' },
292         { "scan-loop", 0, 0, 'S' },
293         {0, 0, 0, 0}
294 };
295
296 /* module / option merging code */
297 static struct option *opts = original_opts;
298 static unsigned int global_option_offset = 0;
299
300 static char *program_name;
301 static char *program_version = LIBRFID_TOOL_VERSION;
302
303 static void free_opts(int reset_offset)
304 {
305         if (opts != original_opts) {
306                 free(opts);
307                 opts = original_opts;
308                 if (reset_offset)
309                         global_option_offset = 0;
310         }
311 }
312
313 static struct option *
314 merge_options(struct option *oldopts, const struct option *newopts,
315               unsigned int *option_offset)
316 {
317         unsigned int num_old, num_new, i;
318         struct option *merge;
319
320         for (num_old = 0; oldopts[num_old].name; num_old++);
321         for (num_new = 0; oldopts[num_new].name; num_new++);
322
323         global_option_offset += OPTION_OFFSET;
324         *option_offset = global_option_offset;
325
326         merge = malloc(sizeof(struct option) * (num_new + num_old + 1));
327         memcpy(merge, oldopts, num_old * sizeof(struct option));
328         free_opts(0); /* Release previous options merged if any */
329         for (i = 0; i < num_new; i++) {
330                 merge[num_old + i] = newopts[i];
331                 merge[num_old + i].val += *option_offset;
332         }
333         memset(merge + num_old + num_new, 0, sizeof(struct option));
334
335         return merge;
336 }
337
338 struct rfidtool_module *find_module(const char *name)
339 {
340         return NULL;
341 }
342
343 void register_module(struct rfidtool_module *me)
344 {
345         struct rfidtool_module *old;
346
347         if (strcmp(me->version, program_version) != 0) {
348                 fprintf(stderr, "%s: target `%s' v%s (I'm v%s).\n",
349                         program_name, me->name, me->version, program_version);
350                 exit(1);
351         }
352
353         old = find_module(me->name);
354         if (old) {
355                 fprintf(stderr, "%s: target `%s' already registere.\n",
356                         program_name, me->name);
357                 exit(1);
358         }
359 }
360
361 static void help(void)
362 {
363         printf( " -s    --scan          scan until first RFID tag is found\n"
364                 " -S    --scan-loop     endless scanning loop\n" 
365                 " -p    --protocol      {tcl,mifare-ultralight,mifare-classic}\n"
366                 " -l    --layer2        {iso14443a,iso14443b,iso15693}\n"
367                 " -h    --help\n");
368 }
369
370 int main(int argc, char **argv)
371 {
372         int rc;
373         char buf[0x40];
374         int i, protocol = -1, layer2 = -1;
375
376         program_name = basename(argv[0]);
377         
378         printf("%s - (C) 2006 by Harald Welte\n"
379                "This program is Free Software and has "
380                "ABSOLUTELY NO WARRANTY\n\n", program_name);
381
382         printf("initializing librfid\n");
383         rfid_init();
384
385         while (1) {
386                 int c, option_index = 0;
387                 c = getopt_long(argc, argv, "hp:l:sS", opts, &option_index);
388                 if (c == -1)
389                         break;
390
391                 switch (c) {
392                 case 's':
393                         if (reader_init() < 0)
394                                 exit(1);
395                         do_scan();
396                         exit(0);
397                         break;
398                 case 'S':
399                         if (reader_init() < 0)
400                                 exit(1);
401                         while (1) 
402                                 do_scan();
403                         exit(0);
404                         break;
405                 case 'p':
406                         protocol = proto_by_name(optarg);
407                         if (protocol < 0) {
408                                 fprintf(stderr, "unknown protocol `%s'\n", 
409                                         optarg);
410                                 exit(2);
411                         }
412                         break;
413                 case 'l':
414                         layer2 = l2_by_name(optarg);
415                         if (layer2 < 0) {
416                                 fprintf(stderr, "unknown layer2 `%s'\n",
417                                         optarg);
418                                 exit(2);
419                         }
420                         break;
421                 case 'h':
422                         help();
423                         exit(0);
424                         break;
425                 }
426         }
427
428         switch (protocol) {
429         case RFID_PROTOCOL_MIFARE_UL:
430         case RFID_PROTOCOL_MIFARE_CLASSIC:
431                 layer2 = RFID_LAYER2_ISO14443A;
432                 break;
433         case -1:
434                 fprintf(stderr, "you have to specify --protocol\n");
435                 exit(2);
436         }
437
438         if (layer2 < 0) {
439                 fprintf(stderr, "you have to specify --layer2\n");
440                 exit(2);
441         }
442         
443         if (reader_init() < 0)
444                 exit(1);
445
446         if (l2_init(layer2) < 0)
447                 exit(1);
448
449         if (l3_init(protocol) < 0)
450                 exit(1);
451
452         switch (protocol) {
453                 char buf[32000];
454                 int len = 200;
455
456         case RFID_PROTOCOL_TCL:
457                 printf("Protocol T=CL\n");
458                 /* we've established T=CL at this point */
459                 printf("selecting Master File\n");
460                 rc = select_mf();
461                 if (rc < 0) {
462                         printf("error selecting MF\n");
463                         break;
464                 }
465
466                 printf("Getting random challenge, length 255\n");
467                 rc = iso7816_get_challenge(0xff);
468                 if (rc < 0) {
469                         printf("error getting random challenge\n");
470                         break;
471                 }
472
473                 printf("selecting Passport application\n");
474                 rc = iso7816_select_application();
475                 if (rc < 0) {
476                         printf("error selecting passport application\n");
477                         break;
478                 }
479
480                 printf("selecting EF 0x1e\n");
481                 rc = iso7816_select_ef(0x011e);
482                 if (rc < 0) {
483                         printf("error selecting EF 0x1e\n");
484                         break;
485                 }
486
487                 printf("selecting EF 0x01\n");
488                 rc = iso7816_select_ef(0x0101);
489                 if (rc < 0) {
490                         printf("error selecting EF 0x01\n");
491                         break;
492                 }
493
494                 while (1) {
495                         printf("reading EF1\n");
496                         len = 200;
497                         printf("reading ef\n");
498                         rc = iso7816_read_binary(buf, &len);
499                         if (rc < 0) {
500                                 printf("error reading EF\n");
501                                 break;
502                         }
503                 }
504 #if 0
505                 for (i = 0; i < 4; i++)
506                         iso7816_get_challenge(0xff);
507 #endif
508                 break;
509         case RFID_PROTOCOL_MIFARE_UL:
510                 printf("Protocol Mifare Ultralight\n");
511                 mifare_ulight_read(ph);
512 #if 0
513                 mifare_ulight_blank(ph);
514                 mifare_ulight_write(ph);
515                 mifare_ulight_read(ph);
516 #endif
517                 break;
518         case RFID_PROTOCOL_MIFARE_CLASSIC:
519                 printf("Protocol Mifare Classic\n");
520                 {
521                         int sector;
522                         for (sector = 0; sector < 31; sector++) {
523                                 printf("Authenticating sector %u: ", sector);
524                                 fflush(stdout);
525                                 rc = mfcl_set_key(ph, MIFARE_CL_KEYA_DEFAULT_INFINEON);
526                                 if (rc < 0) {
527                                         printf("key format error\n");
528                                         exit(1);
529                                 }
530                                 rc = mfcl_auth(ph, RFID_CMD_MIFARE_AUTH1A, sector*4);
531                                 if (rc < 0) {
532                                         printf("mifare auth error\n");
533                                         exit(1);
534                                 } else 
535                                         printf("mifare auth succeeded!\n");
536
537                                 mifare_classic_read_sector(ph, sector);
538                         }
539                 }
540                 break;
541         default:
542                 printf("unknown protocol\n");
543                 exit(1);
544                 break;
545         }
546
547         rfid_reader_close(rh);
548         
549         exit(0);
550 }