From 590c3fb3328a3afdae28051e6662c4d242f85d0f Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 12 Aug 2010 20:41:40 +0800 Subject: Separate the mifare classic related stuff out from the Easycard --- easytool/Makefile | 2 +- easytool/easytool.c | 83 +++++++++++++++++++---------------------------- easytool/mifare_classic.c | 29 +++++++++++++++++ easytool/mifare_classic.h | 16 +++++++++ 4 files changed, 79 insertions(+), 51 deletions(-) create mode 100644 easytool/mifare_classic.c create mode 100644 easytool/mifare_classic.h diff --git a/easytool/Makefile b/easytool/Makefile index fc5a5e1..81b3ae2 100644 --- a/easytool/Makefile +++ b/easytool/Makefile @@ -6,7 +6,7 @@ all: easytool clean: @rm -f *.o easytool -easytool: easytool.o data.o utils.o +easytool: easytool.o data.o utils.o mifare_classic.o $(CC) $(LDFLAGS) -o $@ $^ %.o: %.c diff --git a/easytool/easytool.c b/easytool/easytool.c index b02842d..f8da4e0 100644 --- a/easytool/easytool.c +++ b/easytool/easytool.c @@ -19,8 +19,7 @@ * */ - - +/* System includes */ #include #include #include @@ -31,12 +30,15 @@ #include #include #include - #include +/* libnfc includes */ #include #include +#include "mifare_classic.h" + +/* Easycard specific includes */ #include "easycard.h" struct { @@ -45,50 +47,7 @@ struct { mifare_tag *mft; } global; -#define ABP_C1 0x04 -#define ABP_C2 0x02 -#define ABP_C3 0x01 - -struct acc_bits_parsed { - uint8_t block[4]; -}; - -static void dump_acc_bits(const struct acc_bits_parsed *abp) -{ - uint8_t block; - - for (block = 0; block < 4; block++) { - printf("\tBlock %u: %x (%u %u %u)\n", block, abp->block[block], - abp->block[block] & ABP_C1 ? 1 : 0, - abp->block[block] & ABP_C2 ? 1 : 0, - abp->block[block] & ABP_C3 ? 1 : 0); - } -} - -static void parse_acc_bits(struct acc_bits_parsed *abp, uint8_t *acc_bits) -{ - uint8_t c1, c2, c3; - uint8_t block; - - memset(abp, 0, sizeof(*abp)); - - c1 = acc_bits[1] >> 4; - c2 = acc_bits[2] & 0xf; - c3 = acc_bits[2] >> 4; - - printf("C1 = %x, C2 = %x, C3 = %x\n", c1, c2, c3); - - for (block = 0; block < 4; block++) { - uint8_t testbit = 1 << block; - if (c1 & testbit) - abp->block[block] |= ABP_C1; - if (c2 & testbit) - abp->block[block] |= ABP_C2; - if (c3 & testbit) - abp->block[block] |= ABP_C3; - } -} - +/* Sector 0 of Block 2 seems to contain manufacturing timestamp */ struct easy_block2sec0 { uint8_t unknown[6]; uint8_t timestamp[3]; @@ -109,6 +68,14 @@ struct easy_log_rec { uint8_t unknown3[2]; } __attribute__ ((packed)); +/* Mifare classic VALUE BLOCK */ +struct mfcl_value_block { + uint32_t value; /* value in NTD */ + uint32_t value_inv; /* bit-inverted copy of value in NTD */ + uint32_t value_backup; /* backup copy of value in NTD */ + uint8_t addr[4]; +} __attribute__ ((packed)); + static time_t easy_timestamp2time(const uint8_t *easy_ts) { return (easy_ts[2] << 16 | easy_ts[1] << 8 | easy_ts[0]) << 8; @@ -144,6 +111,18 @@ static void dump_easy_log(const struct easy_log_rec *elr) } } +static void dump_acc_bits(const struct acc_bits_parsed *abp) +{ + uint8_t block; + + for (block = 0; block < 4; block++) { + printf("\tBlock %u: %x (%u %u %u)\n", block, abp->block[block], + abp->block[block] & ABP_C1 ? 1 : 0, + abp->block[block] & ABP_C2 ? 1 : 0, + abp->block[block] & ABP_C3 ? 1 : 0); + } +} + static void dump_mfcl(mifare_tag *mft) { unsigned int sect; @@ -160,7 +139,7 @@ static void dump_mfcl(mifare_tag *mft) printf("Sector %02u (base: 0x%02x) Access bits: 0x%08x\n", sect, sect*4*16, ntohl(*((uint32_t *) access_bits))); - parse_acc_bits(&abp, access_bits); + mfcl_parse_acc_bits(&abp, access_bits); dump_acc_bits(&abp); } } @@ -169,18 +148,22 @@ static void dump_easycard(mifare_tag *mft) { unsigned int sect; mifare_block_manufacturer *manuf = &mft->amb[0].mbm; - struct easy_block2sec0 *b2s0 = mft->amb[4].mbd.abtData; + struct mfcl_value_block *val = + (struct mfcl_value_block *) mft->amb[8].mbd.abtData; + struct easy_block2sec0 *b2s0 = + (struct easy_block2sec0 *) mft->amb[4].mbd.abtData; uint32_t uid = ntohl(*((uint32_t *) manuf->abtUID)); /* dump the header */ printf("EasyCard UID 0x%08x (%u)\n", uid, uid); printf("Date of manufacture: %s\n", easy_asc_timestamp(b2s0->timestamp)); + printf("Current Balance: %5u NTD\n", val->value); + printf("\nTransaction Log:\n"); /* dump the transaction log */ for (sect = 3; sect <=4; sect++) { unsigned int block_base = sect * 4; - uint8_t *access_bits = mft->amb[block_base+3].mbt.abtAccessBits; unsigned int i; for (i = 0; i < 3; i++) { void *data = mft->amb[block_base+i].mbd.abtData; diff --git a/easytool/mifare_classic.c b/easytool/mifare_classic.c new file mode 100644 index 0000000..e516631 --- /dev/null +++ b/easytool/mifare_classic.c @@ -0,0 +1,29 @@ +#include +#include +#include + +#include "mifare_classic.h" + +void mfcl_parse_acc_bits(struct acc_bits_parsed *abp, uint8_t *acc_bits) +{ + uint8_t c1, c2, c3; + uint8_t block; + + memset(abp, 0, sizeof(*abp)); + + c1 = acc_bits[1] >> 4; + c2 = acc_bits[2] & 0xf; + c3 = acc_bits[2] >> 4; + + printf("C1 = %x, C2 = %x, C3 = %x\n", c1, c2, c3); + + for (block = 0; block < 4; block++) { + uint8_t testbit = 1 << block; + if (c1 & testbit) + abp->block[block] |= ABP_C1; + if (c2 & testbit) + abp->block[block] |= ABP_C2; + if (c3 & testbit) + abp->block[block] |= ABP_C3; + } +} diff --git a/easytool/mifare_classic.h b/easytool/mifare_classic.h new file mode 100644 index 0000000..c6ba524 --- /dev/null +++ b/easytool/mifare_classic.h @@ -0,0 +1,16 @@ +#ifndef EASY_MFCL_H +#define EASY_MFCL_H + +#include + +#define ABP_C1 0x04 +#define ABP_C2 0x02 +#define ABP_C3 0x01 + +struct acc_bits_parsed { + uint8_t block[4]; +}; + +void mfcl_parse_acc_bits(struct acc_bits_parsed *abp, uint8_t *acc_bits); + +#endif -- cgit v1.2.3