- 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
This commit is contained in:
laforge 2005-10-22 20:20:21 +00:00
parent 073fc3dcce
commit 5fc01ff6f9
17 changed files with 404 additions and 96 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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 {

View File

@ -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 */

View File

@ -76,5 +76,6 @@ enum rfid_protocol_id {
RFID_PROTOCOL_UNKNOWN,
RFID_PROTOCOL_TCL,
RFID_PROTOCOL_MIFARE_UL,
RFID_PROTOCOL_MIFARE_CLASSIC,
};
#endif

View File

@ -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

View File

@ -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);

View File

@ -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;
};

View File

@ -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);

3
rfid.c
View File

@ -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;
}

View File

@ -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,
},
},
};

View File

@ -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) {

View File

@ -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,

144
rfid_proto_mifare_classic.c Normal file
View File

@ -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);
}

View File

@ -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;

View File

@ -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,
},
};