From 2da53a43badc7bd578ab5df850648f14807aecd2 Mon Sep 17 00:00:00 2001 From: laforge Date: Tue, 28 Nov 2006 10:06:24 +0000 Subject: - fix mifare write support - make mifare auth more reliable - add mifare permission / access bit en/decoding - some more 15693 bits - add new 'mifare-tool' program git-svn-id: https://svn.gnumonks.org/trunk/librfid@1928 e0336214-984f-0b4b-a45f-81c69e1f0ede --- utils/mifare-tool.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 207 insertions(+) create mode 100644 utils/mifare-tool.c (limited to 'utils/mifare-tool.c') diff --git a/utils/mifare-tool.c b/utils/mifare-tool.c new file mode 100644 index 0000000..f9a6a49 --- /dev/null +++ b/utils/mifare-tool.c @@ -0,0 +1,207 @@ +/* mifare-tool - a small command-line tool for librfid mifare testing + * + * (C) 2006 by Harald Welte + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include + +#define _GNU_SOURCE +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "librfid-tool.h" + +static char *program_name; + +static void help(void) +{ +} + +static struct option mifare_opts[] = { + { "key", 1, 0, 'k' }, + { "read", 1, 0, 'r' }, + { "loop-read", 1, 0, 'l' }, + { "write", 1 ,0, 'w' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } +}; + +static int mifare_cl_auth(unsigned char *key, int page) +{ + int rc; + + rc = mfcl_set_key(ph, key); + if (rc < 0) { + fprintf(stderr, "key format error\n"); + return rc; + } + rc = mfcl_auth(ph, RFID_CMD_MIFARE_AUTH1A, page); + if (rc < 0) { + fprintf(stderr, "mifare auth error\n"); + return rc; + } else + printf("mifare auth succeeded!\n"); + + return 0; +} + +static void mifare_l3(void) +{ + while (l2_init(RFID_LAYER2_ISO14443A) < 0) ; + + printf("ISO14443-3A anticollision succeeded\n"); + + while (l3_init(RFID_PROTOCOL_MIFARE_CLASSIC) < 0) ; + + printf("Mifare card available\n"); +} + +int main(int argc, char **argv) +{ + int len, rc, c, option_index = 0; + unsigned int page; + char key[MIFARE_CL_KEY_LEN]; + char buf[MIFARE_CL_PAGE_SIZE]; + program_name = basename(argv[0]); + + memcpy(key, MIFARE_CL_KEYA_DEFAULT_INFINEON, + sizeof(MIFARE_CL_KEYA_DEFAULT_INFINEON)); + + printf("%s - (C) 2006 by Harald Welte\n" + "This program is Free Software and has " + "ABSOLUTELY NO WARRANTY\n\n", program_name); + + printf("initializing librfid\n"); + rfid_init(); + + if (reader_init() < 0) { + fprintf(stderr, "error opening reader\n"); + exit(1); + } + + while (1) { + c = getopt_long(argc, argv, "k:r:l:w:", mifare_opts, + &option_index); + if (c == -1) + break; + + switch (c) { + case 'k': + hexread(key, optarg, strlen(optarg)); + printf("key: %s\n", hexdump(key, MIFARE_CL_KEY_LEN)); + break; + case 'r': + page = atoi(optarg); + printf("read(key='%s',page=%u):", + hexdump(key, MIFARE_CL_KEY_LEN), page); + len = MIFARE_CL_PAGE_SIZE; + mifare_l3(); + if (mifare_cl_auth(key, page) < 0) + exit(1); + rc = rfid_protocol_read(ph, page, buf, &len); + if (rc < 0) { + printf("\n"); + fprintf(stderr, "error during read\n"); + break; + } + printf("%s\n", hexdump(buf, len)); + + if (page & 0x3 == 0x3) { + struct mfcl_access_sect s; + struct mfcl_access_exp_sect es; + int b; + u_int8_t recreated[4]; + mfcl_parse_access(&s, buf+6); + printf("access b0:%u b1:%u b2:%u b3:%u\n", + s.block[0], s.block[1], + s.block[2], s.block[3]); + mfcl_access_to_exp(&es, &s); + for (b = 0; b < 3; b++) + printf("%u: %s\n", b, mfcl_access_exp_stringify(&es.block[b])); + printf("3: %s\n", mfcl_access_exp_acc_stringify(&es.acc)); +#if 0 + mfcl_compile_access(recreated, &s); + printf("recreated; %s\n", hexdump(recreated,4)); +#endif + } + break; + case 'l': + page = atoi(optarg); + printf("read_loop(key='%s',page=%u):\n", + hexdump(key, MIFARE_CL_KEY_LEN), page); + while (1) { + mifare_l3(); + if (mifare_cl_auth(key, page) < 0) + continue; + rc = rfid_protocol_read(ph, page, buf, &len); + if (rc < 0) { + printf("\n"); + fprintf(stderr, "error during read\n"); + continue; + } + printf("%s\n", hexdump(buf, len)); + } + break; + case 'w': + page = atoi(optarg); + len = strlen(argv[optind]); + len = hexread(buf, argv[optind], len); + printf("write(key='%s',page=%u):", + hexdump(key, MIFARE_CL_KEY_LEN), page); + printf(" '%s'(%u):", hexdump(buf, len), len); + mifare_l3(); + if (mifare_cl_auth(key, page) < 0) + exit(1); + rc = rfid_protocol_write(ph, page, buf, len); + if (rc < 0) { + printf("\n"); + fprintf(stderr, "error during write\n"); + break; + } + printf("success\n"); + break; + case 'h': + default: + help(); + } + } + +#if 0 + rfid_protocol_close(ph); + rfid_protocol_fini(ph); + + rfid_layer2_close(l2h); + rfid_layer2_fini(l2h); +#endif + rfid_reader_close(rh); + exit(0); +} + -- cgit v1.2.3