- 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:
parent
073fc3dcce
commit
5fc01ff6f9
2
Makefile
2
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -76,5 +76,6 @@ enum rfid_protocol_id {
|
|||
RFID_PROTOCOL_UNKNOWN,
|
||||
RFID_PROTOCOL_TCL,
|
||||
RFID_PROTOCOL_MIFARE_UL,
|
||||
RFID_PROTOCOL_MIFARE_CLASSIC,
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
3
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;
|
||||
}
|
||||
|
|
|
@ -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, ®);
|
||||
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,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue