mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
hf 14a sim t 10 - possibility to simulate IKEA rothult locks
This commit is contained in:
parent
a785d7ea77
commit
420b29c7bf
2 changed files with 169 additions and 120 deletions
|
@ -899,13 +899,15 @@ bool GetIso14443aCommandFromReader(uint8_t *received, uint8_t *par, int *len) {
|
||||||
uint16_t check = 0;
|
uint16_t check = 0;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (check == 1000) {
|
if (check == 4000) {
|
||||||
if (BUTTON_PRESS() || data_available())
|
// if (BUTTON_PRESS() || data_available())
|
||||||
|
if (BUTTON_PRESS())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
check = 0;
|
check = 0;
|
||||||
|
WDT_HIT();
|
||||||
}
|
}
|
||||||
++check;
|
++check;
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||||
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
|
@ -981,11 +983,15 @@ bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_response_i
|
||||||
// Prepare the optional second SAK (for 7 byte UID), drop the cascade bit
|
// Prepare the optional second SAK (for 7 byte UID), drop the cascade bit
|
||||||
static uint8_t rSAKc2[3] = { 0x00 };
|
static uint8_t rSAKc2[3] = { 0x00 };
|
||||||
// dummy ATS (pseudo-ATR), answer to RATS
|
// dummy ATS (pseudo-ATR), answer to RATS
|
||||||
static uint8_t rRATS[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 };
|
// static uint8_t rRATS[] = { 0x04, 0x58, 0x80, 0x02, 0x00, 0x00 };
|
||||||
|
static uint8_t rRATS[] = { 0x05, 0x75, 0x80, 0x60, 0x02, 0x00, 0x00 };
|
||||||
|
|
||||||
// GET_VERSION response for EV1/NTAG
|
// GET_VERSION response for EV1/NTAG
|
||||||
static uint8_t rVERSION[10] = { 0x00 };
|
static uint8_t rVERSION[10] = { 0x00 };
|
||||||
// READ_SIG response for EV1/NTAG
|
// READ_SIG response for EV1/NTAG
|
||||||
static uint8_t rSIGN[34] = { 0x00 };
|
static uint8_t rSIGN[34] = { 0x00 };
|
||||||
|
// PPS respoonse
|
||||||
|
static uint8_t rPPS[3] = { 0xD0 };
|
||||||
|
|
||||||
switch (tagType) {
|
switch (tagType) {
|
||||||
case 1: { // MIFARE Classic 1k
|
case 1: { // MIFARE Classic 1k
|
||||||
|
@ -1059,12 +1065,19 @@ bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_response_i
|
||||||
sak = 0x18;
|
sak = 0x18;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 9 : { // FM11RF005SH (Shanghai Metro)
|
case 9: { // FM11RF005SH (Shanghai Metro)
|
||||||
rATQA[0] = 0x03;
|
rATQA[0] = 0x03;
|
||||||
rATQA[1] = 0x00;
|
rATQA[1] = 0x00;
|
||||||
sak = 0x0A;
|
sak = 0x0A;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 10: { // JCOP31/41 Rothult
|
||||||
|
rATQA[0] = 0x42;
|
||||||
|
rATQA[1] = 0x00;
|
||||||
|
sak = 0x00;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Error: unknown tagtype (%d)", tagType);
|
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Error: unknown tagtype (%d)", tagType);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1115,13 +1128,20 @@ bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_response_i
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the BitCountCheck (BCC) for the first 4 bytes of the UID.
|
// Calculate BCC for the first 4 bytes of the UID.
|
||||||
rUIDc1[4] = rUIDc1[0] ^ rUIDc1[1] ^ rUIDc1[2] ^ rUIDc1[3];
|
rUIDc1[4] = rUIDc1[0] ^ rUIDc1[1] ^ rUIDc1[2] ^ rUIDc1[3];
|
||||||
|
|
||||||
rSAKc1[0] = sak;
|
|
||||||
AddCrc14A(rSAKc1, sizeof(rSAKc1) - 2);
|
|
||||||
|
|
||||||
|
if (tagType == 10) {
|
||||||
|
rSAKc1[0] = 0x04;
|
||||||
|
rSAKc2[0] = 0x20;
|
||||||
|
} else {
|
||||||
|
rSAKc1[0] = sak;
|
||||||
rSAKc2[0] = sak & 0xFB;
|
rSAKc2[0] = sak & 0xFB;
|
||||||
|
}
|
||||||
|
|
||||||
|
// crc
|
||||||
|
AddCrc14A(rSAKc1, sizeof(rSAKc1) - 2);
|
||||||
AddCrc14A(rSAKc2, sizeof(rSAKc2) - 2);
|
AddCrc14A(rSAKc2, sizeof(rSAKc2) - 2);
|
||||||
|
|
||||||
// Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present,
|
// Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present,
|
||||||
|
@ -1130,7 +1150,9 @@ bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_response_i
|
||||||
// TC(1) = 0x02: CID supported, NAD not supported
|
// TC(1) = 0x02: CID supported, NAD not supported
|
||||||
AddCrc14A(rRATS, sizeof(rRATS) - 2);
|
AddCrc14A(rRATS, sizeof(rRATS) - 2);
|
||||||
|
|
||||||
#define TAG_RESPONSE_COUNT 8
|
AddCrc14A(rPPS, sizeof(rPPS) - 2);
|
||||||
|
|
||||||
|
#define TAG_RESPONSE_COUNT 9
|
||||||
static tag_response_info_t responses_init[TAG_RESPONSE_COUNT] = {
|
static tag_response_info_t responses_init[TAG_RESPONSE_COUNT] = {
|
||||||
{ .response = rATQA, .response_n = sizeof(rATQA) }, // Answer to request - respond with card type
|
{ .response = rATQA, .response_n = sizeof(rATQA) }, // Answer to request - respond with card type
|
||||||
{ .response = rUIDc1, .response_n = sizeof(rUIDc1) }, // Anticollision cascade1 - respond with uid
|
{ .response = rUIDc1, .response_n = sizeof(rUIDc1) }, // Anticollision cascade1 - respond with uid
|
||||||
|
@ -1139,13 +1161,15 @@ bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_response_i
|
||||||
{ .response = rSAKc2, .response_n = sizeof(rSAKc2) }, // Acknowledge select - cascade 2
|
{ .response = rSAKc2, .response_n = sizeof(rSAKc2) }, // Acknowledge select - cascade 2
|
||||||
{ .response = rRATS, .response_n = sizeof(rRATS) }, // dummy ATS (pseudo-ATR), answer to RATS
|
{ .response = rRATS, .response_n = sizeof(rRATS) }, // dummy ATS (pseudo-ATR), answer to RATS
|
||||||
{ .response = rVERSION, .response_n = sizeof(rVERSION) }, // EV1/NTAG GET_VERSION response
|
{ .response = rVERSION, .response_n = sizeof(rVERSION) }, // EV1/NTAG GET_VERSION response
|
||||||
{ .response = rSIGN, .response_n = sizeof(rSIGN) } // EV1/NTAG READ_SIG response
|
{ .response = rSIGN, .response_n = sizeof(rSIGN) }, // EV1/NTAG READ_SIG response
|
||||||
|
{ .response = rPPS, .response_n = sizeof(rPPS) } // PPS response
|
||||||
};
|
};
|
||||||
|
|
||||||
// "precompile" responses. There are 8 predefined responses with a total of 68 bytes data to transmit.
|
// "precompile" responses. There are 9 predefined responses with a total of 72 bytes data to transmit.
|
||||||
// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
|
// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
|
||||||
// 68 * 8 data bits, 68 * 1 parity bits, 8 start bits, 8 stop bits, 8 correction bits -- 636 bytes buffer
|
// 72 * 8 data bits, 72 * 1 parity bits, 9 start bits, 9 stop bits, 9 correction bits -- 677 bytes buffer
|
||||||
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 636
|
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 675
|
||||||
|
// 576 + 72 + 9 + 9 + 9 == 675
|
||||||
|
|
||||||
uint8_t *free_buffer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
|
uint8_t *free_buffer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
|
||||||
// modulation buffer pointer and current buffer free space size
|
// modulation buffer pointer and current buffer free space size
|
||||||
|
@ -1173,7 +1197,7 @@ bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_response_i
|
||||||
#define RATS 5
|
#define RATS 5
|
||||||
#define VERSION 6
|
#define VERSION 6
|
||||||
#define SIGNATURE 7
|
#define SIGNATURE 7
|
||||||
|
#define PPS 8
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1232,6 +1256,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
// We need to listen to the high-frequency, peak-detected path.
|
// We need to listen to the high-frequency, peak-detected path.
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
||||||
|
|
||||||
|
iso14a_set_timeout(201400); // 106 * 19ms default
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
// To control where we are in the protocol
|
// To control where we are in the protocol
|
||||||
|
@ -1246,8 +1272,8 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
#define ORDER_SELECT_CL2 30
|
#define ORDER_SELECT_CL2 30
|
||||||
#define ORDER_EV1_COMP_WRITE 40
|
#define ORDER_EV1_COMP_WRITE 40
|
||||||
#define ORDER_RATS 70
|
#define ORDER_RATS 70
|
||||||
uint8_t order = ORDER_NONE;
|
|
||||||
|
|
||||||
|
uint8_t order = ORDER_NONE;
|
||||||
int retval = PM3_SUCCESS;
|
int retval = PM3_SUCCESS;
|
||||||
|
|
||||||
// Just to allow some checks
|
// Just to allow some checks
|
||||||
|
@ -1258,27 +1284,26 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
// compatible write block number
|
// compatible write block number
|
||||||
uint8_t wrblock = 0;
|
uint8_t wrblock = 0;
|
||||||
|
|
||||||
|
bool odd_reply = true;
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
|
// main loop
|
||||||
for (;;) {
|
for (;;) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
|
tag_response_info_t *p_response = NULL;
|
||||||
|
|
||||||
// Clean receive command buffer
|
// Clean receive command buffer
|
||||||
if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
|
if (GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len) == false) {
|
||||||
Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen());
|
Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen());
|
||||||
retval = PM3_EOPABORTED;
|
retval = PM3_EOPABORTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tag_response_info_t *p_response = NULL;
|
|
||||||
|
|
||||||
// Okay, look at the command now.
|
|
||||||
int lastorder = order;
|
|
||||||
|
|
||||||
//
|
|
||||||
// we need to check "ordered" states before, because received data may be same to any command - is wrong!!!
|
// we need to check "ordered" states before, because received data may be same to any command - is wrong!!!
|
||||||
//
|
|
||||||
|
|
||||||
if (order == ORDER_EV1_COMP_WRITE && len == 18) {
|
if (order == ORDER_EV1_COMP_WRITE && len == 18) {
|
||||||
// MIFARE_ULC_COMP_WRITE part 2
|
// MIFARE_ULC_COMP_WRITE part 2
|
||||||
// 16 bytes data + 2 bytes crc, only least significant 4 bytes are written
|
// 16 bytes data + 2 bytes crc, only least significant 4 bytes are written
|
||||||
|
@ -1361,28 +1386,22 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
order = ORDER_NONE; // back to work state
|
order = ORDER_NONE; // back to work state
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
|
|
||||||
//
|
} else if (receivedCmd[0] == ISO14443A_CMD_REQA && len == 1) { // Received a REQUEST, but in HALTED, skip
|
||||||
// now check commands in received buffer
|
odd_reply = !odd_reply;
|
||||||
//
|
if (odd_reply)
|
||||||
|
|
||||||
} else if (receivedCmd[0] == ISO14443A_CMD_REQA && len == 1) { // Received a REQUEST
|
|
||||||
p_response = &responses[ATQA];
|
p_response = &responses[ATQA];
|
||||||
order = ORDER_REQA;
|
|
||||||
} else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) { // Received a WAKEUP
|
} else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) { // Received a WAKEUP
|
||||||
p_response = &responses[ATQA];
|
p_response = &responses[ATQA];
|
||||||
order = ORDER_WUPA;
|
|
||||||
} else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 2) { // Received request for UID (cascade 1)
|
} else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 2) { // Received request for UID (cascade 1)
|
||||||
p_response = &responses[UIDC1];
|
p_response = &responses[UIDC1];
|
||||||
order = ORDER_SELECT_ALL_CL1;
|
|
||||||
} else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && len == 2) { // Received request for UID (cascade 2)
|
} else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && len == 2) { // Received request for UID (cascade 2)
|
||||||
p_response = &responses[UIDC2];
|
p_response = &responses[UIDC2];
|
||||||
order = ORDER_SELECT_ALL_CL2;
|
|
||||||
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 9) { // Received a SELECT (cascade 1)
|
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 9) { // Received a SELECT (cascade 1)
|
||||||
p_response = &responses[SAKC1];
|
p_response = &responses[SAKC1];
|
||||||
order = ORDER_SELECT_CL1;
|
|
||||||
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && len == 9) { // Received a SELECT (cascade 2)
|
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2 && len == 9) { // Received a SELECT (cascade 2)
|
||||||
p_response = &responses[SAKC2];
|
p_response = &responses[SAKC2];
|
||||||
order = ORDER_SELECT_CL2;
|
} else if (receivedCmd[0] == ISO14443A_CMD_PPS) {
|
||||||
|
p_response = &responses[PPS];
|
||||||
} else if (receivedCmd[0] == ISO14443A_CMD_READBLOCK && len == 4) { // Received a (plain) READ
|
} else if (receivedCmd[0] == ISO14443A_CMD_READBLOCK && len == 4) { // Received a (plain) READ
|
||||||
uint8_t block = receivedCmd[1];
|
uint8_t block = receivedCmd[1];
|
||||||
// if Ultralight or NTAG (4 byte blocks)
|
// if Ultralight or NTAG (4 byte blocks)
|
||||||
|
@ -1410,8 +1429,6 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
emlGetMemBt(emdata, block, 16);
|
emlGetMemBt(emdata, block, 16);
|
||||||
AddCrc14A(emdata, 16);
|
AddCrc14A(emdata, 16);
|
||||||
EmSendCmd(emdata, sizeof(emdata));
|
EmSendCmd(emdata, sizeof(emdata));
|
||||||
// EmSendCmd(data+(4*receivedCmd[1]),16);
|
|
||||||
// Dbprintf("Read request from reader: %x %x",receivedCmd[0],receivedCmd[1]);
|
|
||||||
// We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below
|
// We already responded, do not send anything with the EmSendCmd14443aRaw() that is called below
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1433,8 +1450,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
} else if (receivedCmd[0] == MIFARE_ULC_WRITE && len == 8 && (tagType == 2 || tagType == 7)) { // Received a WRITE
|
} else if (receivedCmd[0] == MIFARE_ULC_WRITE && len == 8 && (tagType == 2 || tagType == 7)) { // Received a WRITE
|
||||||
// cmd + block + 4 bytes data + 2 bytes crc
|
// cmd + block + 4 bytes data + 2 bytes crc
|
||||||
bool isCrcCorrect = CheckCrc14A(receivedCmd, len);
|
if (CheckCrc14A(receivedCmd, len)) {
|
||||||
if (isCrcCorrect) {
|
|
||||||
uint8_t block = receivedCmd[1];
|
uint8_t block = receivedCmd[1];
|
||||||
if (block > pages) {
|
if (block > pages) {
|
||||||
// send NACK 0x0 == invalid argument
|
// send NACK 0x0 == invalid argument
|
||||||
|
@ -1452,8 +1468,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
} else if (receivedCmd[0] == MIFARE_ULC_COMP_WRITE && len == 4 && (tagType == 2 || tagType == 7)) {
|
} else if (receivedCmd[0] == MIFARE_ULC_COMP_WRITE && len == 4 && (tagType == 2 || tagType == 7)) {
|
||||||
// cmd + block + 2 bytes crc
|
// cmd + block + 2 bytes crc
|
||||||
bool isCrcCorrect = CheckCrc14A(receivedCmd, len);
|
if (CheckCrc14A(receivedCmd, len)) {
|
||||||
if (isCrcCorrect) {
|
|
||||||
wrblock = receivedCmd[1];
|
wrblock = receivedCmd[1];
|
||||||
if (wrblock > pages) {
|
if (wrblock > pages) {
|
||||||
// send NACK 0x0 == invalid argument
|
// send NACK 0x0 == invalid argument
|
||||||
|
@ -1538,7 +1553,6 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
} else {
|
} else {
|
||||||
p_response = &responses[RATS];
|
p_response = &responses[RATS];
|
||||||
order = ORDER_RATS;
|
|
||||||
}
|
}
|
||||||
} else if (receivedCmd[0] == MIFARE_ULC_AUTH_1) { // ULC authentication, or Desfire Authentication
|
} else if (receivedCmd[0] == MIFARE_ULC_AUTH_1) { // ULC authentication, or Desfire Authentication
|
||||||
LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
|
@ -1566,7 +1580,34 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
AddCrc14A(cmd, sizeof(cmd) - 2);
|
AddCrc14A(cmd, sizeof(cmd) - 2);
|
||||||
EmSendCmd(cmd, sizeof(cmd));
|
EmSendCmd(cmd, sizeof(cmd));
|
||||||
p_response = NULL;
|
p_response = NULL;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// clear old dynamic responses
|
||||||
|
dynamic_response_info.response_n = 0;
|
||||||
|
dynamic_response_info.modulation_n = 0;
|
||||||
|
|
||||||
|
// ST25TA512B IKEA Rothult
|
||||||
|
if (tagType == 10) {
|
||||||
|
// we replay 90 00 for all commands but the read bin and we deny the verify cmd.
|
||||||
|
|
||||||
|
if (memcmp("\x02\xa2\xb0\x00\x00\x1d\x51\x69", receivedCmd, 8) == 0) {
|
||||||
|
dynamic_response_info.response[0] = receivedCmd[0];
|
||||||
|
memcpy(dynamic_response_info.response + 1, "\x00\x1b\xd1\x01\x17\x54\x02\x7a\x68\xa2\x34\xcb\xd0\xe2\x03\xc7\x3e\x62\x0b\xe8\xc6\x3c\x85\x2c\xc5\x31\x31\x31\x32\x90\x00", 31);
|
||||||
|
dynamic_response_info.response_n = 32;
|
||||||
|
} else if (memcmp("\x02\x00\x20\x00\x01\x00\x6e\xa9", receivedCmd, 8) == 0) {
|
||||||
|
dynamic_response_info.response[0] = receivedCmd[0];
|
||||||
|
dynamic_response_info.response[1] = 0x63;
|
||||||
|
dynamic_response_info.response[2] = 0x00;
|
||||||
|
dynamic_response_info.response_n = 3;
|
||||||
|
} else {
|
||||||
|
dynamic_response_info.response[0] = receivedCmd[0];
|
||||||
|
dynamic_response_info.response[1] = 0x90;
|
||||||
|
dynamic_response_info.response[2] = 0x00;
|
||||||
|
dynamic_response_info.response_n = 3;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
// Check for ISO 14443A-4 compliant commands, look at left nibble
|
// Check for ISO 14443A-4 compliant commands, look at left nibble
|
||||||
switch (receivedCmd[0]) {
|
switch (receivedCmd[0]) {
|
||||||
case 0x02:
|
case 0x02:
|
||||||
|
@ -1630,8 +1671,11 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
if (dynamic_response_info.response_n > 0) {
|
if (dynamic_response_info.response_n > 0) {
|
||||||
|
|
||||||
// Copy the CID from the reader query
|
// Copy the CID from the reader query
|
||||||
|
if (tagType != 10)
|
||||||
dynamic_response_info.response[1] = receivedCmd[1];
|
dynamic_response_info.response[1] = receivedCmd[1];
|
||||||
|
|
||||||
// Add CRC bytes, always used in ISO 14443A-4 compliant cards
|
// Add CRC bytes, always used in ISO 14443A-4 compliant cards
|
||||||
|
@ -1648,17 +1692,16 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count number of wakeups received after a halt
|
// Count number of wakeups received after a halt
|
||||||
if (order == ORDER_WUPA && lastorder == ORDER_HALTED) { happened++; }
|
// if (order == ORDER_WUPA && lastorder == ORDER_HALTED) { happened++; }
|
||||||
|
|
||||||
// Count number of other messages after a halt
|
// Count number of other messages after a halt
|
||||||
if (order != ORDER_WUPA && lastorder == ORDER_HALTED) { happened2++; }
|
// if (order != ORDER_WUPA && lastorder == ORDER_HALTED) { happened2++; }
|
||||||
|
|
||||||
cmdsRecvd++;
|
cmdsRecvd++;
|
||||||
|
|
||||||
if (p_response != NULL) {
|
// Send response
|
||||||
EmSendPrecompiledCmd(p_response);
|
EmSendPrecompiledCmd(p_response);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
switch_off();
|
switch_off();
|
||||||
|
|
||||||
|
@ -1958,7 +2001,7 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
|
||||||
volatile uint8_t b;
|
volatile uint8_t b;
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
uint32_t ThisTransferTime;
|
uint32_t ThisTransferTime;
|
||||||
bool correctionNeeded;
|
bool correction_needed;
|
||||||
|
|
||||||
// Modulate Manchester
|
// Modulate Manchester
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);
|
||||||
|
@ -1966,21 +2009,23 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
|
||||||
// Include correction bit if necessary
|
// Include correction bit if necessary
|
||||||
if (Uart.bitCount == 7) {
|
if (Uart.bitCount == 7) {
|
||||||
// Short tags (7 bits) don't have parity, determine the correct value from MSB
|
// Short tags (7 bits) don't have parity, determine the correct value from MSB
|
||||||
correctionNeeded = Uart.output[0] & 0x40;
|
correction_needed = Uart.output[0] & 0x40;
|
||||||
} else {
|
} else {
|
||||||
// The parity bits are left-aligned
|
// The parity bits are left-aligned
|
||||||
correctionNeeded = Uart.parity[(Uart.len - 1) / 8] & (0x80 >> ((Uart.len - 1) & 7));
|
correction_needed = Uart.parity[(Uart.len - 1) / 8] & (0x80 >> ((Uart.len - 1) & 7));
|
||||||
}
|
}
|
||||||
// 1236, so correction bit needed
|
// 1236, so correction bit needed
|
||||||
i = (correctionNeeded) ? 0 : 1;
|
i = (correction_needed) ? 0 : 1;
|
||||||
|
|
||||||
// clear receiving shift register and holding register
|
// clear receiving shift register and holding register
|
||||||
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
|
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
|
||||||
b = AT91C_BASE_SSC->SSC_RHR;
|
b = AT91C_BASE_SSC->SSC_RHR;
|
||||||
(void) b;
|
(void) b;
|
||||||
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
|
/*
|
||||||
b = AT91C_BASE_SSC->SSC_RHR;
|
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY));
|
||||||
|
b = AT91C_BASE_SSC->SSC_THR;
|
||||||
(void) b;
|
(void) b;
|
||||||
|
*/
|
||||||
|
|
||||||
// wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line)
|
// wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line)
|
||||||
for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never
|
for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never
|
||||||
|
@ -2000,22 +2045,24 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
|
||||||
FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||||
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
||||||
(void)b;
|
(void)b;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again:
|
// Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again:
|
||||||
uint8_t fpga_queued_bits = FpgaSendQueueDelay >> 3;
|
uint8_t fpga_queued_bits = FpgaSendQueueDelay >> 3;
|
||||||
for (i = 0; i <= fpga_queued_bits / 8 + 1;) {
|
for (i = 0; i <= (fpga_queued_bits >> 3) + 1;) {
|
||||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
|
||||||
AT91C_BASE_SSC->SSC_THR = SEC_F;
|
AT91C_BASE_SSC->SSC_THR = SEC_F;
|
||||||
FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LastTimeProxToAirStart = ThisTransferTime + (correctionNeeded ? 8 : 0);
|
LastTimeProxToAirStart = ThisTransferTime + (correction_needed ? 8 : 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2069,6 +2116,7 @@ int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool collision) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int EmSendPrecompiledCmd(tag_response_info_t *p_response) {
|
int EmSendPrecompiledCmd(tag_response_info_t *p_response) {
|
||||||
|
if (p_response == NULL) return 0;
|
||||||
int ret = EmSendCmd14443aRaw(p_response->modulation, p_response->modulation_n);
|
int ret = EmSendCmd14443aRaw(p_response->modulation, p_response->modulation_n);
|
||||||
// do the tracing for the previous reader request and this tag answer:
|
// do the tracing for the previous reader request and this tag answer:
|
||||||
uint8_t par[MAX_PARITY_SIZE] = {0x00};
|
uint8_t par[MAX_PARITY_SIZE] = {0x00};
|
||||||
|
|
|
@ -201,6 +201,7 @@ static int usage_hf_14a_sim(void) {
|
||||||
PrintAndLogEx(NORMAL, " 7 = AMIIBO (NTAG 215), pack 0x8080");
|
PrintAndLogEx(NORMAL, " 7 = AMIIBO (NTAG 215), pack 0x8080");
|
||||||
PrintAndLogEx(NORMAL, " 8 = MIFARE Classic 4k");
|
PrintAndLogEx(NORMAL, " 8 = MIFARE Classic 4k");
|
||||||
PrintAndLogEx(NORMAL, " 9 = FM11RF005SH Shanghai Metro");
|
PrintAndLogEx(NORMAL, " 9 = FM11RF005SH Shanghai Metro");
|
||||||
|
PrintAndLogEx(NORMAL, " 10 = JCOP 31/41 Rothult");
|
||||||
// PrintAndLogEx(NORMAL, " u : 4, 7 or 10 byte UID");
|
// PrintAndLogEx(NORMAL, " u : 4, 7 or 10 byte UID");
|
||||||
PrintAndLogEx(NORMAL, " u : 4, 7 byte UID");
|
PrintAndLogEx(NORMAL, " u : 4, 7 byte UID");
|
||||||
PrintAndLogEx(NORMAL, " x : (Optional) Performs the 'reader attack', nr/ar attack against a reader");
|
PrintAndLogEx(NORMAL, " x : (Optional) Performs the 'reader attack', nr/ar attack against a reader");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue