summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaforge <laforge@e0336214-984f-0b4b-a45f-81c69e1f0ede>2005-10-22 20:20:21 +0000
committerlaforge <laforge@e0336214-984f-0b4b-a45f-81c69e1f0ede>2005-10-22 20:20:21 +0000
commit5fc01ff6f98d72219420bc29fb59d2d6eb93e887 (patch)
tree1cf64c994346c29e0a143bacf6ce69d8ae3bc2be
parent073fc3dcce216782501b12113704b6256d15670c (diff)
- 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
-rw-r--r--Makefile2
-rw-r--r--include/rfid/rfid_asic_rc632.h72
-rw-r--r--include/rfid/rfid_layer2.h2
-rw-r--r--include/rfid/rfid_layer2_iso14443a.h2
-rw-r--r--include/rfid/rfid_layer2_iso14443b.h1
-rw-r--r--include/rfid/rfid_protocol.h1
-rw-r--r--include/rfid/rfid_protocol_mifare_classic.h11
-rw-r--r--include/rfid/rfid_protocol_mifare_ul.h2
-rw-r--r--include/rfid/rfid_reader.h5
-rw-r--r--openct-escape.c12
-rw-r--r--rfid.c3
-rw-r--r--rfid_asic_rc632.c203
-rw-r--r--rfid_layer2_iso14443a.c20
-rw-r--r--rfid_layer2_iso14443b.c8
-rw-r--r--rfid_proto_mifare_classic.c144
-rw-r--r--rfid_proto_tcl.c2
-rw-r--r--rfid_reader_cm5121.c10
17 files changed, 404 insertions, 96 deletions
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 <rfid/rfid_layer2.h>
#include <rfid/rfid_protocol.h>
#include <rfid/rfid_reader_cm5121.h>
+#include <rfid/rfid_protocol_mifare_classic.h>
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 <rfid/rfid_reader_cm5121.h>
#include <rfid/rfid_protocol.h>
#include <rfid/rfid_protocol_tcl.h>
+#include <rfid/rfid_protocol_mifare_ul.h>
+#include <rfid/rfid_protocol_mifare_classic.h>
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 <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <errno.h>
#include <sys/types.h>
#include <rfid/rfid.h>
@@ -29,37 +30,40 @@
#include <rfid/rfid_asic_rc632.h>
#include <rfid/rfid_reader_cm5121.h>
#include <rfid/rfid_layer2_iso14443a.h>
+#include <rfid/rfid_protocol_mifare_classic.h>
#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, &reg);
+ 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 <laforge@gnumonks.org>
+ *
+ */
+
+/*
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rfid/rfid.h>
+#include <rfid/rfid_protocol.h>
+#include <rfid/rfid_layer2.h>
+//#include <rfid/rfid_layer2_iso14443b.h>
+
+//#include <rfid/rfid_asic.h>
+#include <rfid/rfid_reader.h>
+
+#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,
+ },
};
personal git repositories of Harald Welte. Your mileage may vary