From 5fc01ff6f98d72219420bc29fb59d2d6eb93e887 Mon Sep 17 00:00:00 2001 From: laforge Date: Sat, 22 Oct 2005 20:20:21 +0000 Subject: - add mifare classic support - move uid/pupi from l2 private data into l2 global data - various cleanups git-svn-id: https://svn.gnumonks.org/trunk/librfid@1555 e0336214-984f-0b4b-a45f-81c69e1f0ede --- Makefile | 2 +- include/rfid/rfid_asic_rc632.h | 72 +++++----- include/rfid/rfid_layer2.h | 2 + include/rfid/rfid_layer2_iso14443a.h | 2 - include/rfid/rfid_layer2_iso14443b.h | 1 - include/rfid/rfid_protocol.h | 1 + include/rfid/rfid_protocol_mifare_classic.h | 11 ++ include/rfid/rfid_protocol_mifare_ul.h | 2 +- include/rfid/rfid_reader.h | 5 + openct-escape.c | 12 +- rfid.c | 3 + rfid_asic_rc632.c | 203 ++++++++++++++++++++++------ rfid_layer2_iso14443a.c | 20 +-- rfid_layer2_iso14443b.c | 8 +- rfid_proto_mifare_classic.c | 144 ++++++++++++++++++++ rfid_proto_tcl.c | 2 +- rfid_reader_cm5121.c | 10 ++ 17 files changed, 404 insertions(+), 96 deletions(-) create mode 100644 include/rfid/rfid_protocol_mifare_classic.h create mode 100644 rfid_proto_mifare_classic.c diff --git a/Makefile b/Makefile index ca53ada..326af8c 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ all: openct-escape openct-escape: openct-escape.o librfid.a $(CC) $(LDFLAGS) -o $@ $^ -librfid.a: rfid_layer2.o rfid_layer2_iso14443a.o rfid_layer2_iso14443b.o rfid_layer2_iso15693.o rfid_asic_rc632.o rfid_reader_cm5121.o rfid.o rfid_protocol.o rfid_proto_tcl.o rfid_proto_mifare_ul.o rfid_iso14443_common.o rfid_reader.o +librfid.a: rfid_layer2.o rfid_layer2_iso14443a.o rfid_layer2_iso14443b.o rfid_layer2_iso15693.o rfid_asic_rc632.o rfid_reader_cm5121.o rfid.o rfid_protocol.o rfid_proto_tcl.o rfid_proto_mifare_ul.o rfid_proto_mifare_classic.o rfid_iso14443_common.o rfid_reader.o ar r $@ $^ %.o: %.c diff --git a/include/rfid/rfid_asic_rc632.h b/include/rfid/rfid_asic_rc632.h index 13279a8..7a984ff 100644 --- a/include/rfid/rfid_asic_rc632.h +++ b/include/rfid/rfid_asic_rc632.h @@ -6,18 +6,18 @@ struct rfid_asic_transport_handle; struct rfid_asic_rc632_transport { struct { int (*reg_write)(struct rfid_asic_transport_handle *rath, - unsigned char reg, - unsigned char value); + u_int8_t reg, + u_int8_t value); int (*reg_read)(struct rfid_asic_transport_handle *rath, - unsigned char reg, - unsigned char *value); + u_int8_t reg, + u_int8_t *value); int (*fifo_write)(struct rfid_asic_transport_handle *rath, - unsigned char len, - const unsigned char *buf, - unsigned char flags); + u_int8_t len, + const u_int8_t *buf, + u_int8_t flags); int (*fifo_read)(struct rfid_asic_transport_handle *rath, - unsigned char len, - unsigned char *buf); + u_int8_t len, + u_int8_t *buf); } fn; }; @@ -33,16 +33,16 @@ struct rfid_asic_rc632 { int (*turn_on_rf)(struct rfid_asic_handle *h); int (*turn_off_rf)(struct rfid_asic_handle *h); int (*transcieve)(struct rfid_asic_handle *h, - const unsigned char *tx_buf, + const u_int32_t *tx_buf, unsigned int tx_len, - unsigned char *rx_buf, + u_int32_t *rx_buf, unsigned int *rx_len, u_int64_t timeout, unsigned int flags); struct { int (*init)(struct rfid_asic_handle *h); int (*transcieve_sf)(struct rfid_asic_handle *h, - unsigned char cmd, + u_int32_t cmd, struct iso14443a_atqa *atqa); int (*transcieve_acf)(struct rfid_asic_handle *h, struct iso14443a_anticol_cmd *cmd, @@ -54,6 +54,11 @@ struct rfid_asic_rc632 { struct { int (*init)(struct rfid_asic_handle *h); } iso15693; + struct { + int (*setkey)(struct rfid_asic_handle *h, unsigned char *key); + int (*auth)(struct rfid_asic_handle *h, u_int8_t cmd, + u_int32_t serno, u_int8_t block); + } mifare_classic; } fn; }; @@ -65,33 +70,34 @@ struct rfid_asic_rc632_handle { struct rc632_transport_handle th; }; +#if 0 int rc632_reg_write(struct rfid_asic_handle *handle, - unsigned char reg, - unsigned char val); + u_int8_t reg, + u_int8_t val); int rc632_reg_read(struct rfid_asic_handle *handle, - unsigned char reg, - unsigned char *val); + u_int8_t reg, + u_int8_t *val); int rc632_fifo_write(struct rfid_asic_handle *handle, - unsigned char len, - const unsigned char *buf, - unsigned char flags); + u_int8_t len, + const u_int32_t *buf, + u_int8_t flags); int rc632_fifo_read(struct rfid_asic_handle *handle, - unsigned char len, - unsigned char *buf); + u_int8_t len, + u_int8_t *buf); int -rc632_set_bits(struct rfid_asic_handle *handle, unsigned char reg, - unsigned char val); +rc632_set_bits(struct rfid_asic_handle *handle, u_int8_t reg, + u_int82_t val); int -rc632_clear_bits(struct rfid_asic_handle *handle, unsigned char reg, - unsigned char val); +rc632_clear_bits(struct rfid_asic_handle *handle, u_int32_t reg, + u_int32_t val); int @@ -113,16 +119,16 @@ rc632_wait_idle(struct rfid_asic_handle *handle, u_int64_t time); int rc632_transmit(struct rfid_asic_handle *handle, - const unsigned char *buf, - unsigned char len, + const u_int32_t *buf, + u_int32_t len, u_int64_t timeout); int rc632_transcieve(struct rfid_asic_handle *handle, - const unsigned char *tx_buf, - unsigned char tx_len, - unsigned char *rx_buf, - unsigned char *rx_len, + const u_int32_t *tx_buf, + u_int32_t tx_len, + u_int32_t *rx_buf, + u_int32_t *rx_len, unsigned int timer, unsigned int toggle); @@ -134,7 +140,7 @@ int rc632_calc_crc16_from(struct rfid_asic_handle *handle); int -rc632_register_dump(struct rfid_asic_handle *handle, unsigned char *buf); +rc632_register_dump(struct rfid_asic_handle *handle, u_int32_t *buf); struct rfid_asic_handle * rc632_open(struct rfid_asic_transport_handle *th); @@ -142,3 +148,5 @@ struct rfid_asic_handle * rc632_open(struct rfid_asic_transport_handle *th); extern struct rfid_asic rc632; #endif + +#endif diff --git a/include/rfid/rfid_layer2.h b/include/rfid/rfid_layer2.h index fb296a2..c87578b 100644 --- a/include/rfid/rfid_layer2.h +++ b/include/rfid/rfid_layer2.h @@ -29,6 +29,8 @@ struct rfid_layer2 { struct rfid_layer2_handle { struct rfid_reader_handle *rh; + unsigned char uid[10]; /* triple size 14443a id is 10 bytes */ + unsigned int uid_len; union { struct iso14443a_handle iso14443a; struct iso14443b_handle iso14443b; diff --git a/include/rfid/rfid_layer2_iso14443a.h b/include/rfid/rfid_layer2_iso14443a.h index 9594abb..400f951 100644 --- a/include/rfid/rfid_layer2_iso14443a.h +++ b/include/rfid/rfid_layer2_iso14443a.h @@ -68,8 +68,6 @@ struct iso14443a_handle { unsigned int state; unsigned int level; unsigned int tcl_capable; - unsigned int uid_len; - unsigned char uid[10]; /* Triple size UID is 10 bytes */ }; enum iso14443a_level { diff --git a/include/rfid/rfid_layer2_iso14443b.h b/include/rfid/rfid_layer2_iso14443b.h index b35a118..6c84c26 100644 --- a/include/rfid/rfid_layer2_iso14443b.h +++ b/include/rfid/rfid_layer2_iso14443b.h @@ -43,7 +43,6 @@ struct iso14443b_attrib_hdr { struct iso14443b_handle { unsigned int tcl_capable; /* do we support T=CL */ - unsigned char pupi[4]; /* Pseudo-Unique PICC Identifier */ unsigned int cid; /* Card ID */ unsigned int fsc; /* max. frame size card */ diff --git a/include/rfid/rfid_protocol.h b/include/rfid/rfid_protocol.h index c232818..1403e83 100644 --- a/include/rfid/rfid_protocol.h +++ b/include/rfid/rfid_protocol.h @@ -76,5 +76,6 @@ enum rfid_protocol_id { RFID_PROTOCOL_UNKNOWN, RFID_PROTOCOL_TCL, RFID_PROTOCOL_MIFARE_UL, + RFID_PROTOCOL_MIFARE_CLASSIC, }; #endif diff --git a/include/rfid/rfid_protocol_mifare_classic.h b/include/rfid/rfid_protocol_mifare_classic.h new file mode 100644 index 0000000..01066f4 --- /dev/null +++ b/include/rfid/rfid_protocol_mifare_classic.h @@ -0,0 +1,11 @@ +#ifndef _MIFARE_CLASSIC_H + +extern struct rfid_protocol rfid_protocol_mfcl; + +#define RFID_CMD_MIFARE_AUTH1A 0x60 +#define RFID_CMD_MIFARE_AUTH1B 0x61 + +#define MIFARE_CLASSIC_KEY_DEFAULT "\xa0\xa1\xa2\xa3\xa4\xa5" + + +#endif diff --git a/include/rfid/rfid_protocol_mifare_ul.h b/include/rfid/rfid_protocol_mifare_ul.h index 729c481..06cf515 100644 --- a/include/rfid/rfid_protocol_mifare_ul.h +++ b/include/rfid/rfid_protocol_mifare_ul.h @@ -13,7 +13,7 @@ #define MIFARE_UL_PAGE_LOCK 2 #define MIFARE_UL_PAGE_OTP 3 -struct rfid_protocol rfid_protocol_mful; +extern struct rfid_protocol rfid_protocol_mful; int rfid_mful_lock_page(struct rfid_protocol_handle *ph, unsigned int page); diff --git a/include/rfid/rfid_reader.h b/include/rfid/rfid_reader.h index 98c03a1..0acd532 100644 --- a/include/rfid/rfid_reader.h +++ b/include/rfid/rfid_reader.h @@ -33,6 +33,11 @@ struct rfid_reader { struct rfid_15693_reader { int (*init)(struct rfid_reader_handle *rh); } iso15693; + struct rfid_mifare_classic_reader { + int (*setkey)(struct rfid_reader_handle *h, unsigned char *key); + int (*auth)(struct rfid_reader_handle *h, u_int8_t cmd, + u_int32_t serno, u_int8_t block); + } mifare_classic; struct rfid_reader *next; }; diff --git a/openct-escape.c b/openct-escape.c index 41eb9c3..b488610 100644 --- a/openct-escape.c +++ b/openct-escape.c @@ -25,6 +25,7 @@ #include #include #include +#include static int slot = 1; static ct_handle *h; @@ -286,6 +287,7 @@ int main(int argc, char **argv) exit(1); protocol = RFID_PROTOCOL_MIFARE_UL; + protocol = RFID_PROTOCOL_MIFARE_CLASSIC; // protocol = RFID_PROTOCOL_TCL; if (l3(protocol) < 0) @@ -315,9 +317,17 @@ int main(int argc, char **argv) mifare_ulight_read(ph); #endif break; + case RFID_PROTOCOL_MIFARE_CLASSIC: + mfcl_set_key(ph, MIFARE_CLASSIC_KEY_DEFAULT); + rc = mfcl_auth(ph, RFID_CMD_MIFARE_AUTH1A, 0); + if (rc < 0) { + printf("mifare auth error\n"); + exit(1); + } else + printf("mifare authe succeeded!\n"); + break; } - rfid_reader_close(rh); exit(0); diff --git a/rfid.c b/rfid.c index 0ca7ef3..be72f12 100644 --- a/rfid.c +++ b/rfid.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include const char * rfid_hexdump(const void *data, unsigned int len) @@ -43,6 +45,7 @@ int rfid_init() rfid_layer2_register(&rfid_layer2_iso14443b); rfid_protocol_register(&rfid_protocol_tcl); rfid_protocol_register(&rfid_protocol_mful); + rfid_protocol_register(&rfid_protocol_mfcl); return 0; } diff --git a/rfid_asic_rc632.c b/rfid_asic_rc632.c index 94fb48f..36cca71 100644 --- a/rfid_asic_rc632.c +++ b/rfid_asic_rc632.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -29,37 +30,40 @@ #include #include #include +#include #include "rfid_iso14443_common.h" #include "rc632.h" //#include "rc632_14443a.h" +#define RC632_TMO_AUTH1 14000 + #define ENTER() DEBUGP("entering\n") struct rfid_asic rc632; /* Register and FIFO Access functions */ int rc632_reg_write(struct rfid_asic_handle *handle, - unsigned char reg, - unsigned char val) + u_int8_t reg, + u_int8_t val) { return handle->rath->rat->priv.rc632.fn.reg_write(handle->rath, reg, val); } int rc632_reg_read(struct rfid_asic_handle *handle, - unsigned char reg, - unsigned char *val) + u_int8_t reg, + u_int8_t *val) { return handle->rath->rat->priv.rc632.fn.reg_read(handle->rath, reg, val); } int rc632_fifo_write(struct rfid_asic_handle *handle, - unsigned char len, - const unsigned char *buf, - unsigned char flags) + u_int8_t len, + const u_int8_t *buf, + u_int8_t flags) { return handle->rath->rat->priv.rc632.fn.fifo_write(handle->rath, len, buf, flags); @@ -67,8 +71,8 @@ rc632_fifo_write(struct rfid_asic_handle *handle, int rc632_fifo_read(struct rfid_asic_handle *handle, - unsigned char len, - unsigned char *buf) + u_int8_t len, + u_int8_t *buf) { return handle->rath->rat->priv.rc632.fn.fifo_read(handle->rath, len, buf); } @@ -76,11 +80,11 @@ rc632_fifo_read(struct rfid_asic_handle *handle, int rc632_set_bits(struct rfid_asic_handle *handle, - unsigned char reg, - unsigned char val) + u_int8_t reg, + u_int8_t val) { int ret; - unsigned char tmp; + u_int8_t tmp; ret = rc632_reg_read(handle, reg, &tmp); if (ret < 0) @@ -95,11 +99,11 @@ rc632_set_bits(struct rfid_asic_handle *handle, int rc632_clear_bits(struct rfid_asic_handle *handle, - unsigned char reg, - unsigned char val) + u_int8_t reg, + u_int8_t val) { int ret; - unsigned char tmp; + u_int8_t tmp; ret = rc632_reg_read(handle, reg, &tmp); if (ret < 0) { @@ -150,7 +154,7 @@ rc632_power_down(struct rfid_asic_handle *handle) int rc632_wait_idle(struct rfid_asic_handle *handle, u_int64_t timeout) { - unsigned char cmd = 0xff; + u_int8_t cmd = 0xff; int ret; while (cmd != 0) { @@ -164,7 +168,7 @@ rc632_wait_idle(struct rfid_asic_handle *handle, u_int64_t timeout) } { - unsigned char foo; + u_int8_t foo; rc632_reg_read(handle, RC632_REG_PRIMARY_STATUS, &foo); if (foo & 0x04) rc632_reg_read(handle, RC632_REG_ERROR_FLAG, &foo); @@ -180,8 +184,8 @@ rc632_wait_idle(struct rfid_asic_handle *handle, u_int64_t timeout) int rc632_transmit(struct rfid_asic_handle *handle, - const unsigned char *buf, - unsigned char len, + const u_int8_t *buf, + u_int8_t len, u_int64_t timeout) { int ret; @@ -206,10 +210,10 @@ tcl_toggle_pcb(struct rfid_asic_handle *handle) int rc632_transcieve(struct rfid_asic_handle *handle, - const unsigned char *tx_buf, - unsigned char tx_len, - unsigned char *rx_buf, - unsigned char *rx_len, + const u_int8_t *tx_buf, + u_int8_t tx_len, + u_int8_t *rx_buf, + u_int8_t *rx_len, unsigned int timer, unsigned int toggle) { @@ -235,7 +239,7 @@ rc632_transcieve(struct rfid_asic_handle *handle, return ret; if (*rx_len == 0) { - unsigned char tmp; + u_int8_t tmp; DEBUGP("rx_len == 0\n"); @@ -251,8 +255,8 @@ rc632_transcieve(struct rfid_asic_handle *handle, int rc632_read_eeprom(struct rfid_asic_handle *handle) { - unsigned char recvbuf[60]; - unsigned char sndbuf[3]; + u_int8_t recvbuf[60]; + u_int8_t sndbuf[3]; int ret; sndbuf[0] = 0x00; @@ -280,8 +284,8 @@ rc632_read_eeprom(struct rfid_asic_handle *handle) int rc632_calc_crc16_from(struct rfid_asic_handle *handle) { - unsigned char sndbuf[2] = { 0x01, 0x02 }; - unsigned char crc_lsb = 0x00 , crc_msb = 0x00; + u_int8_t sndbuf[2] = { 0x01, 0x02 }; + u_int8_t crc_lsb = 0x00 , crc_msb = 0x00; int ret; ret = rc632_reg_write(handle, RC632_REG_CRC_PRESET_LSB, 0x12); @@ -316,10 +320,10 @@ rc632_calc_crc16_from(struct rfid_asic_handle *handle) int -rc632_register_dump(struct rfid_asic_handle *handle, unsigned char *buf) +rc632_register_dump(struct rfid_asic_handle *handle, u_int8_t *buf) { int ret; - unsigned char i; + u_int8_t i; for (i = 0; i <= 0x3f; i++) { ret = rc632_reg_read(handle, i, &buf[i]); @@ -558,12 +562,12 @@ rc632_iso14443a_fini(struct iso14443a_handle *handle_14443) /* issue a 14443-3 A PCD -> PICC command in a short frame, such as REQA, WUPA */ static int rc632_iso14443a_transcieve_sf(struct rfid_asic_handle *handle, - unsigned char cmd, + u_int8_t cmd, struct iso14443a_atqa *atqa) { int ret; - unsigned char tx_buf[1]; - unsigned char rx_len = 2; + u_int8_t tx_buf[1]; + u_int8_t rx_len = 2; memset(atqa, 0, sizeof(atqa)); @@ -593,7 +597,7 @@ rc632_iso14443a_transcieve_sf(struct rfid_asic_handle *handle, return ret; ret = rc632_transcieve(handle, tx_buf, sizeof(tx_buf), - (unsigned char *)atqa, &rx_len, 0x32, 0); + (u_int8_t *)atqa, &rx_len, 0x32, 0); if (ret < 0) { DEBUGP("error during rc632_transcieve()\n"); return ret; @@ -615,12 +619,12 @@ rc632_iso14443a_transcieve_sf(struct rfid_asic_handle *handle, /* transcieve regular frame */ static int rc632_iso14443a_transcieve(struct rfid_asic_handle *handle, - const unsigned char *tx_buf, unsigned int tx_len, - unsigned char *rx_buf, unsigned int *rx_len, + const u_int8_t *tx_buf, unsigned int tx_len, + u_int8_t *rx_buf, unsigned int *rx_len, u_int64_t timeout, unsigned int flags) { int ret; - unsigned char rxl = *rx_len & 0xff; + u_int8_t rxl = *rx_len & 0xff; DEBUGP("entered\n"); memset(rx_buf, 0, *rx_len); @@ -653,11 +657,11 @@ rc632_iso14443a_transcieve_acf(struct rfid_asic_handle *handle, unsigned int *bit_of_col) { int ret; - unsigned char rx_buf[64]; - unsigned char rx_len = sizeof(rx_buf); - unsigned char rx_align = 0, tx_last_bits, tx_bytes; - unsigned char boc; - unsigned char error_flag; + u_int8_t rx_buf[64]; + u_int8_t rx_len = sizeof(rx_buf); + u_int8_t rx_align = 0, tx_last_bits, tx_bytes; + u_int8_t boc; + u_int8_t error_flag; *bit_of_col = ISO14443A_BITOFCOL_NONE; memset(rx_buf, 0, sizeof(rx_buf)); @@ -694,7 +698,7 @@ rc632_iso14443a_transcieve_acf(struct rfid_asic_handle *handle, if (ret < 0) return ret; - ret = rc632_transcieve(handle, (unsigned char *)acf, tx_bytes, + ret = rc632_transcieve(handle, (u_int8_t *)acf, tx_bytes, rx_buf, &rx_len, 0x32, 0); if (ret < 0) return ret; @@ -1082,6 +1086,115 @@ rc632_iso15693_icl_init(struct rfid_asic_handle *h) return 0; } +struct mifare_authcmd { + u_int8_t auth_cmd; + u_int8_t block_address; + u_int32_t serno; /* lsb 1 2 msb */ +} __attribute__ ((packed)); + + +#define RFID_MIFARE_KEY_LEN 6 +#define RFID_MIFARE_KEY_CODED_LEN 12 + +/* Transform crypto1 key from generic 6byte into rc632 specific 12byte */ +static int +rc632_mifare_transform_key(const u_int8_t *key6, u_int8_t *key12) +{ + int i; + u_int8_t ln; + u_int8_t hn; + + for (i = 0; i < RFID_MIFARE_KEY_LEN; i++) { + ln = key6[i] & 0x0f; + hn = key6[i] >> 4; + key12[i * 2 + 1] = (~ln << 4) | ln; + key12[i * 2] = (~hn << 4) | hn; + } + return 0; +} + +static int +rc632_mifare_set_key(struct rfid_asic_handle *h, const u_int8_t *key) +{ + u_int8_t coded_key[RFID_MIFARE_KEY_CODED_LEN]; + int ret; + + ret = rc632_mifare_transform_key(key, coded_key); + if (ret < 0) + return ret; + + ret = rc632_fifo_write(h, RFID_MIFARE_KEY_CODED_LEN, coded_key, 0x03); + if (ret < 0) + return ret; + + ret = rc632_reg_write(h, RC632_REG_COMMAND, RC632_CMD_LOAD_KEY); + if (ret < 0) + return ret; + + ret = rc632_wait_idle(h, RC632_TMO_AUTH1); + if (ret < 0) + return ret; + + return 0; +} + +static int +rc632_mifare_auth(struct rfid_asic_handle *h, u_int8_t cmd, u_int32_t serno, + u_int8_t block) +{ + int ret; + struct mifare_authcmd acmd; + u_int8_t reg; + + if (cmd != RFID_CMD_MIFARE_AUTH1A && cmd != RFID_CMD_MIFARE_AUTH1B) + return -EINVAL; + + /* Initialize acmd */ + acmd.block_address = block & 0xff; + acmd.auth_cmd = cmd; + acmd.serno = serno; + + /* Send Authent1 Command */ + ret = rc632_fifo_write(h, sizeof(acmd), &acmd, 0x03); + if (ret < 0) + return ret; + + ret = rc632_reg_write(h, RC632_REG_COMMAND, RC632_CMD_AUTHENT1); + if (ret < 0) + return ret; + + /* Wait until transmitter is idle */ + ret = rc632_wait_idle(h, RC632_TMO_AUTH1); + if (ret < 0) + return ret; + + /* Clear Rx/Tx CRC */ + ret = rc632_clear_bits(h, RC632_REG_CHANNEL_REDUNDANCY, + RC632_CR_RX_CRC_ENABLE|RC632_CR_TX_CRC_ENABLE); + if (ret < 0) + return ret; + + /* Send Authent2 Command */ + ret = rc632_reg_write(h, RC632_REG_COMMAND, RC632_CMD_AUTHENT2); + if (ret < 0) + return ret; + + /* Wait until transmitter is idle */ + ret = rc632_wait_idle(h, RC632_TMO_AUTH1); + if (ret < 0) + return ret; + + /* Check whether authentication was successful */ + ret = rc632_reg_read(h, RC632_REG_CONTROL, ®); + if (ret < 0) + return ret; + + if (!(reg & RC632_CONTROL_CRYPTO1_ON)) + return -EACCES; + + return 0; + +} struct rfid_asic rc632 = { .name = "Philips CL RC632", @@ -1103,6 +1216,10 @@ struct rfid_asic rc632 = { .fn.iso15693 = { .init = &rc632_iso15693_init, }, + .fn.mifare_classic = { + .setkey = &rc632_mifare_set_key, + .auth = &rc632_mifare_auth, + }, }, }; diff --git a/rfid_layer2_iso14443a.c b/rfid_layer2_iso14443a.c index f8bde7f..7d7c377 100644 --- a/rfid_layer2_iso14443a.c +++ b/rfid_layer2_iso14443a.c @@ -104,7 +104,7 @@ iso14443a_anticol(struct rfid_layer2_handle *handle) unsigned int rx_len = sizeof(sak); char *aqptr = (char *) &atqa; - memset(h->uid, 0, sizeof(h->uid)); + memset(handle->uid, 0, sizeof(handle->uid)); memset(sak, 0, sizeof(sak)); memset(&atqa, 0, sizeof(atqa)); memset(&acf, 0, sizeof(acf)); @@ -170,13 +170,13 @@ cascade: DEBUGP("Cascade bit set, but UID0 != 0x88\n"); return -1; } - memcpy(&h->uid[0], &acf.uid_bits[1], 3); + memcpy(&handle->uid[0], &acf.uid_bits[1], 3); acf.sel_code = ISO14443A_AC_SEL_CODE_CL2; h->level = ISO14443A_LEVEL_CL2; break; case ISO14443A_AC_SEL_CODE_CL2: /* cascading from CL2 to CL3 */ - memcpy(&h->uid[3], &acf.uid_bits[1], 3); + memcpy(&handle->uid[3], &acf.uid_bits[1], 3); acf.sel_code = ISO14443A_AC_SEL_CODE_CL3; h->level = ISO14443A_LEVEL_CL3; break; @@ -192,15 +192,15 @@ cascade: switch (acf.sel_code) { case ISO14443A_AC_SEL_CODE_CL1: /* single size UID (4 bytes) */ - memcpy(&h->uid[0], &acf.uid_bits[0], 4); + memcpy(&handle->uid[0], &acf.uid_bits[0], 4); break; case ISO14443A_AC_SEL_CODE_CL2: /* double size UID (7 bytes) */ - memcpy(&h->uid[3], &acf.uid_bits[0], 4); + memcpy(&handle->uid[3], &acf.uid_bits[0], 4); break; case ISO14443A_AC_SEL_CODE_CL3: /* triple size UID (10 bytes) */ - memcpy(&h->uid[6], &acf.uid_bits[0], 4); + memcpy(&handle->uid[6], &acf.uid_bits[0], 4); break; } } @@ -210,13 +210,13 @@ cascade: { if (uid_size == 1) - h->uid_len = 4; + handle->uid_len = 4; else if (uid_size == 2) - h->uid_len = 7; + handle->uid_len = 7; else - h->uid_len = 10; + handle->uid_len = 10; - DEBUGP("UID %s\n", rfid_hexdump(h->uid, h->uid_len)); + DEBUGP("UID %s\n", rfid_hexdump(handle->uid, handle->uid_len)); } if (sak[0] & 0x20) { diff --git a/rfid_layer2_iso14443b.c b/rfid_layer2_iso14443b.c index 8424fde..c5ff592 100644 --- a/rfid_layer2_iso14443b.c +++ b/rfid_layer2_iso14443b.c @@ -89,8 +89,8 @@ parse_atqb(struct rfid_layer2_handle *h, struct iso14443b_atqb *atqb) /* FIXME: speed capability */ - memcpy(h->priv.iso14443b.pupi, atqb->pupi, - sizeof(h->priv.iso14443b.pupi)); + memcpy(h->uid, atqb->pupi, sizeof(atqb->pupi)); + h->uid_len = sizeof(atqb->pupi); return 0; } @@ -181,7 +181,7 @@ transcieve_attrib(struct rfid_layer2_handle *h, const unsigned char *inf, memcpy((unsigned char *)attrib+sizeof(*attrib), inf, inf_len); attrib->one_d = 0x1d; - memcpy(attrib->identifier, h->priv.iso14443b.pupi, 4); + memcpy(attrib->identifier, h->uid, 4); /* FIXME: do we want to change TR0/TR1 from its default ? */ /* FIXME: do we want to change SOF/EOF from its default ? */ @@ -240,7 +240,7 @@ iso14443b_hltb(struct rfid_layer2_handle *h) unsigned int hltb_len = 1; hltb[0] = 0x50; - memcpy(hltb+1, h->priv.iso14443b.pupi, 4); + memcpy(hltb+1, h->uid, 4); ret = h->rh->reader->transcieve(h->rh, hltb, 5, hltb_resp, &hltb_len, diff --git a/rfid_proto_mifare_classic.c b/rfid_proto_mifare_classic.c new file mode 100644 index 0000000..474f554 --- /dev/null +++ b/rfid_proto_mifare_classic.c @@ -0,0 +1,144 @@ + +/* Mifare Classic implementation, PCD side. + * + * (C) 2005 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 +#include +#include +//#include + +//#include +#include + +#include "rfid_iso14443_common.h" + + +#define MIFARE_UL_CMD_WRITE 0xA2 +#define MIFARE_UL_CMD_READ 0x30 + +/* FIXME */ +#define MIFARE_UL_READ_FWT 100 +#define MIFARE_UL_WRITE_FWT 100 + +static int +mfcl_read(struct rfid_protocol_handle *ph, unsigned int page, + unsigned char *rx_data, unsigned int *rx_len) +{ + unsigned char rx_buf[16]; + unsigned int real_rx_len = sizeof(rx_buf); + unsigned char tx[2]; + int ret; + + if (page > 7) + return -EINVAL; + + tx[0] = MIFARE_UL_CMD_READ; + tx[1] = page & 0xff; + + ret = ph->l2h->l2->fn.transcieve(ph->l2h, tx, sizeof(tx), rx_buf, + &real_rx_len, MIFARE_UL_READ_FWT, 0); + + if (ret < 0) + return ret; + + if (real_rx_len < *rx_len) + *rx_len = real_rx_len; + + memcpy(rx_data, rx_buf, *rx_len); + + return ret; +} + +static int +mfcl_write(struct rfid_protocol_handle *ph, unsigned int page, + unsigned char *tx_data, unsigned int tx_len) +{ + unsigned int i; + unsigned char tx[6]; + unsigned char rx[1]; + unsigned int rx_len; + int ret; + + if (tx_len != 4 || page > 7) + return -EINVAL; + + tx[0] = MIFARE_UL_CMD_WRITE; + tx[1] = page & 0xff; + + for (i = 0; i < 4; i++) + tx[2+i] = tx_data[i]; + + ret = ph->l2h->l2->fn.transcieve(ph->l2h, tx, sizeof(tx), rx, + &rx_len, MIFARE_UL_WRITE_FWT, 0); + + /* FIXME:look at RX, check for ACK/NAK */ + + return ret; +} + +static struct rfid_protocol_handle * +mfcl_init(struct rfid_layer2_handle *l2h) +{ + struct rfid_protocol_handle *ph; + ph = malloc(sizeof(struct rfid_protocol_handle)); + return ph; +} + +static int mfcl_fini(struct rfid_protocol_handle *ph) +{ + free(ph); + return 0; +} + +struct rfid_protocol rfid_protocol_mfcl = { + .id = RFID_PROTOCOL_MIFARE_CLASSIC, + .name = "Mifare Classic", + .fn = { + .init = &mfcl_init, + .read = &mfcl_read, + .write = &mfcl_write, + .fini = &mfcl_fini, + }, +}; + +int mfcl_set_key(struct rfid_protocol_handle *ph, unsigned char *key) +{ + if (!ph->l2h->rh->reader->mifare_classic.setkey) + return -ENODEV; + + return ph->l2h->rh->reader->mifare_classic.setkey(ph->l2h->rh, key); +} + +int mfcl_auth(struct rfid_protocol_handle *ph, u_int8_t cmd, u_int8_t block) +{ + u_int32_t serno = *((u_int32_t *)ph->l2h->uid); + + if (!ph->l2h->rh->reader->mifare_classic.auth) + return -ENODEV; + + return ph->l2h->rh->reader->mifare_classic.auth(ph->l2h->rh, cmd, + serno, block); +} diff --git a/rfid_proto_tcl.c b/rfid_proto_tcl.c index 5b63607..248eea5 100644 --- a/rfid_proto_tcl.c +++ b/rfid_proto_tcl.c @@ -397,7 +397,7 @@ tcl_connect(struct rfid_protocol_handle *h) } /* PUPI will be presented as ATS/historical bytes */ - memcpy(h->priv.tcl.ats, h->l2h->priv.iso14443b.pupi, 4); + memcpy(h->priv.tcl.ats, h->l2h->uid, 4); h->priv.tcl.ats_len = 4; h->priv.tcl.historical_bytes = h->priv.tcl.ats; diff --git a/rfid_reader_cm5121.c b/rfid_reader_cm5121.c index 11e4ee9..e1fc859 100644 --- a/rfid_reader_cm5121.c +++ b/rfid_reader_cm5121.c @@ -225,6 +225,13 @@ cm5121_15693_init(struct rfid_reader_handle *rh) return rh->ah->asic->priv.rc632.fn.iso15693.init(rh->ah); } +static int +cm5121_mifare_auth(struct rfid_reader_handle *rh, u_int8_t cmd, + u_int32_t serno, u_int8_t block) +{ + return rh->ah->asic->priv.rc632.fn.mifare_classic.auth(rh->ah, + cmd, serno, block); +} struct rfid_asic_transport cm5121_ccid = { .name = "CM5121 OpenCT", @@ -313,6 +320,9 @@ struct rfid_reader rfid_reader_cm5121 = { .iso14443b = { .init = &cm5121_14443b_init, }, + .mifare_classic = { + .auth = &cm5121_mifare_auth, + }, }; -- cgit v1.2.3