mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-01 10:34:45 +08: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;
|
||||
|
||||
for (;;) {
|
||||
if (check == 1000) {
|
||||
if (BUTTON_PRESS() || data_available())
|
||||
if (check == 4000) {
|
||||
// if (BUTTON_PRESS() || data_available())
|
||||
if (BUTTON_PRESS())
|
||||
return false;
|
||||
|
||||
check = 0;
|
||||
WDT_HIT();
|
||||
}
|
||||
++check;
|
||||
WDT_HIT();
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
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
|
||||
static uint8_t rSAKc2[3] = { 0x00 };
|
||||
// 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
|
||||
static uint8_t rVERSION[10] = { 0x00 };
|
||||
// READ_SIG response for EV1/NTAG
|
||||
static uint8_t rSIGN[34] = { 0x00 };
|
||||
// PPS respoonse
|
||||
static uint8_t rPPS[3] = { 0xD0 };
|
||||
|
||||
switch (tagType) {
|
||||
case 1: { // MIFARE Classic 1k
|
||||
|
@ -1059,12 +1065,19 @@ bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_response_i
|
|||
sak = 0x18;
|
||||
}
|
||||
break;
|
||||
case 9 : { // FM11RF005SH (Shanghai Metro)
|
||||
case 9: { // FM11RF005SH (Shanghai Metro)
|
||||
rATQA[0] = 0x03;
|
||||
rATQA[1] = 0x00;
|
||||
sak = 0x0A;
|
||||
}
|
||||
break;
|
||||
case 10: { // JCOP31/41 Rothult
|
||||
rATQA[0] = 0x42;
|
||||
rATQA[1] = 0x00;
|
||||
sak = 0x00;
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Error: unknown tagtype (%d)", tagType);
|
||||
return false;
|
||||
|
@ -1115,13 +1128,20 @@ bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_response_i
|
|||
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];
|
||||
|
||||
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);
|
||||
|
||||
// Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present,
|
||||
|
@ -1130,22 +1150,26 @@ bool SimulateIso14443aInit(int tagType, int flags, uint8_t *data, tag_response_i
|
|||
// TC(1) = 0x02: CID supported, NAD not supported
|
||||
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] = {
|
||||
{ .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 = rUIDc2, .response_n = sizeof(rUIDc2) }, // Anticollision cascade2 - respond with 2nd half of uid if asked
|
||||
{ .response = rSAKc1, .response_n = sizeof(rSAKc1) }, // Acknowledge select - cascade 1
|
||||
{ .response = rSAKc2, .response_n = sizeof(rSAKc2) }, // Acknowledge select - cascade 2
|
||||
{ .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 = rSIGN, .response_n = sizeof(rSIGN) } // EV1/NTAG READ_SIG response
|
||||
{ .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 = rUIDc2, .response_n = sizeof(rUIDc2) }, // Anticollision cascade2 - respond with 2nd half of uid if asked
|
||||
{ .response = rSAKc1, .response_n = sizeof(rSAKc1) }, // Acknowledge select - cascade 1
|
||||
{ .response = rSAKc2, .response_n = sizeof(rSAKc2) }, // Acknowledge select - cascade 2
|
||||
{ .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 = 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)
|
||||
// 68 * 8 data bits, 68 * 1 parity bits, 8 start bits, 8 stop bits, 8 correction bits -- 636 bytes buffer
|
||||
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 636
|
||||
// 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 675
|
||||
// 576 + 72 + 9 + 9 + 9 == 675
|
||||
|
||||
uint8_t *free_buffer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_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 VERSION 6
|
||||
#define SIGNATURE 7
|
||||
|
||||
#define PPS 8
|
||||
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.
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
||||
|
||||
iso14a_set_timeout(201400); // 106 * 19ms default
|
||||
|
||||
int len = 0;
|
||||
|
||||
// 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_EV1_COMP_WRITE 40
|
||||
#define ORDER_RATS 70
|
||||
uint8_t order = ORDER_NONE;
|
||||
|
||||
uint8_t order = ORDER_NONE;
|
||||
int retval = PM3_SUCCESS;
|
||||
|
||||
// Just to allow some checks
|
||||
|
@ -1257,28 +1283,27 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
|||
|
||||
// compatible write block number
|
||||
uint8_t wrblock = 0;
|
||||
|
||||
bool odd_reply = true;
|
||||
|
||||
clear_trace();
|
||||
set_tracing(true);
|
||||
LED_A_ON();
|
||||
|
||||
// main loop
|
||||
for (;;) {
|
||||
WDT_HIT();
|
||||
|
||||
tag_response_info_t *p_response = NULL;
|
||||
|
||||
// Clean receive command buffer
|
||||
if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) {
|
||||
Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen());
|
||||
if (GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len) == false) {
|
||||
Dbprintf("Emulator stopped. Trace length: %d ", BigBuf_get_traceLen());
|
||||
retval = PM3_EOPABORTED;
|
||||
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!!!
|
||||
//
|
||||
|
||||
if (order == ORDER_EV1_COMP_WRITE && len == 18) {
|
||||
// MIFARE_ULC_COMP_WRITE part 2
|
||||
// 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
|
||||
p_response = NULL;
|
||||
|
||||
//
|
||||
// now check commands in received buffer
|
||||
//
|
||||
|
||||
} else if (receivedCmd[0] == ISO14443A_CMD_REQA && len == 1) { // Received a REQUEST
|
||||
p_response = &responses[ATQA];
|
||||
order = ORDER_REQA;
|
||||
} else if (receivedCmd[0] == ISO14443A_CMD_REQA && len == 1) { // Received a REQUEST, but in HALTED, skip
|
||||
odd_reply = !odd_reply;
|
||||
if (odd_reply)
|
||||
p_response = &responses[ATQA];
|
||||
} else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) { // Received a WAKEUP
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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
|
||||
uint8_t block = receivedCmd[1];
|
||||
// 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);
|
||||
AddCrc14A(emdata, 16);
|
||||
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
|
||||
p_response = NULL;
|
||||
}
|
||||
|
@ -1433,8 +1450,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
|||
p_response = NULL;
|
||||
} else if (receivedCmd[0] == MIFARE_ULC_WRITE && len == 8 && (tagType == 2 || tagType == 7)) { // Received a WRITE
|
||||
// cmd + block + 4 bytes data + 2 bytes crc
|
||||
bool isCrcCorrect = CheckCrc14A(receivedCmd, len);
|
||||
if (isCrcCorrect) {
|
||||
if (CheckCrc14A(receivedCmd, len)) {
|
||||
uint8_t block = receivedCmd[1];
|
||||
if (block > pages) {
|
||||
// send NACK 0x0 == invalid argument
|
||||
|
@ -1452,8 +1468,7 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
|||
p_response = NULL;
|
||||
} else if (receivedCmd[0] == MIFARE_ULC_COMP_WRITE && len == 4 && (tagType == 2 || tagType == 7)) {
|
||||
// cmd + block + 2 bytes crc
|
||||
bool isCrcCorrect = CheckCrc14A(receivedCmd, len);
|
||||
if (isCrcCorrect) {
|
||||
if (CheckCrc14A(receivedCmd, len)) {
|
||||
wrblock = receivedCmd[1];
|
||||
if (wrblock > pages) {
|
||||
// send NACK 0x0 == invalid argument
|
||||
|
@ -1538,7 +1553,6 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
|||
p_response = NULL;
|
||||
} else {
|
||||
p_response = &responses[RATS];
|
||||
order = ORDER_RATS;
|
||||
}
|
||||
} 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);
|
||||
|
@ -1566,73 +1580,103 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
|||
AddCrc14A(cmd, sizeof(cmd) - 2);
|
||||
EmSendCmd(cmd, sizeof(cmd));
|
||||
p_response = NULL;
|
||||
|
||||
} else {
|
||||
// Check for ISO 14443A-4 compliant commands, look at left nibble
|
||||
switch (receivedCmd[0]) {
|
||||
case 0x02:
|
||||
case 0x03: { // IBlock (command no CID)
|
||||
|
||||
// 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;
|
||||
}
|
||||
break;
|
||||
case 0x0B:
|
||||
case 0x0A: { // IBlock (command CID)
|
||||
dynamic_response_info.response[0] = receivedCmd[0];
|
||||
dynamic_response_info.response[1] = 0x00;
|
||||
dynamic_response_info.response[2] = 0x90;
|
||||
dynamic_response_info.response[3] = 0x00;
|
||||
dynamic_response_info.response_n = 4;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
|
||||
case 0x1A:
|
||||
case 0x1B: { // Chaining command
|
||||
dynamic_response_info.response[0] = 0xaa | ((receivedCmd[0]) & 1);
|
||||
dynamic_response_info.response_n = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xAA:
|
||||
case 0xBB: {
|
||||
dynamic_response_info.response[0] = receivedCmd[0] ^ 0x11;
|
||||
dynamic_response_info.response_n = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xBA: { // ping / pong
|
||||
dynamic_response_info.response[0] = 0xAB;
|
||||
dynamic_response_info.response[1] = 0x00;
|
||||
dynamic_response_info.response_n = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xCA:
|
||||
case 0xC2: { // Readers sends deselect command
|
||||
dynamic_response_info.response[0] = 0xCA;
|
||||
dynamic_response_info.response[1] = 0x00;
|
||||
dynamic_response_info.response_n = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
// Never seen this command before
|
||||
LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||
if (DBGLEVEL >= DBG_DEBUG) {
|
||||
Dbprintf("Received unknown command (len=%d):", len);
|
||||
Dbhexdump(len, receivedCmd, false);
|
||||
// Check for ISO 14443A-4 compliant commands, look at left nibble
|
||||
switch (receivedCmd[0]) {
|
||||
case 0x02:
|
||||
case 0x03: { // IBlock (command no CID)
|
||||
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;
|
||||
}
|
||||
// Do not respond
|
||||
dynamic_response_info.response_n = 0;
|
||||
order = ORDER_NONE; // back to work state
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x0B:
|
||||
case 0x0A: { // IBlock (command CID)
|
||||
dynamic_response_info.response[0] = receivedCmd[0];
|
||||
dynamic_response_info.response[1] = 0x00;
|
||||
dynamic_response_info.response[2] = 0x90;
|
||||
dynamic_response_info.response[3] = 0x00;
|
||||
dynamic_response_info.response_n = 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1A:
|
||||
case 0x1B: { // Chaining command
|
||||
dynamic_response_info.response[0] = 0xaa | ((receivedCmd[0]) & 1);
|
||||
dynamic_response_info.response_n = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xAA:
|
||||
case 0xBB: {
|
||||
dynamic_response_info.response[0] = receivedCmd[0] ^ 0x11;
|
||||
dynamic_response_info.response_n = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xBA: { // ping / pong
|
||||
dynamic_response_info.response[0] = 0xAB;
|
||||
dynamic_response_info.response[1] = 0x00;
|
||||
dynamic_response_info.response_n = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xCA:
|
||||
case 0xC2: { // Readers sends deselect command
|
||||
dynamic_response_info.response[0] = 0xCA;
|
||||
dynamic_response_info.response[1] = 0x00;
|
||||
dynamic_response_info.response_n = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
default: {
|
||||
// Never seen this command before
|
||||
LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||
if (DBGLEVEL >= DBG_DEBUG) {
|
||||
Dbprintf("Received unknown command (len=%d):", len);
|
||||
Dbhexdump(len, receivedCmd, false);
|
||||
}
|
||||
// Do not respond
|
||||
dynamic_response_info.response_n = 0;
|
||||
order = ORDER_NONE; // back to work state
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (dynamic_response_info.response_n > 0) {
|
||||
|
||||
// Copy the CID from the reader query
|
||||
dynamic_response_info.response[1] = receivedCmd[1];
|
||||
if (tagType != 10)
|
||||
dynamic_response_info.response[1] = receivedCmd[1];
|
||||
|
||||
// Add CRC bytes, always used in ISO 14443A-4 compliant cards
|
||||
AddCrc14A(dynamic_response_info.response, dynamic_response_info.response_n);
|
||||
|
@ -1648,16 +1692,15 @@ void SimulateIso14443aTag(uint8_t tagType, uint8_t flags, uint8_t *data) {
|
|||
}
|
||||
|
||||
// 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
|
||||
if (order != ORDER_WUPA && lastorder == ORDER_HALTED) { happened2++; }
|
||||
// if (order != ORDER_WUPA && lastorder == ORDER_HALTED) { happened2++; }
|
||||
|
||||
cmdsRecvd++;
|
||||
|
||||
if (p_response != NULL) {
|
||||
EmSendPrecompiledCmd(p_response);
|
||||
}
|
||||
// Send response
|
||||
EmSendPrecompiledCmd(p_response);
|
||||
}
|
||||
|
||||
switch_off();
|
||||
|
@ -1958,7 +2001,7 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
|
|||
volatile uint8_t b;
|
||||
uint16_t i = 0;
|
||||
uint32_t ThisTransferTime;
|
||||
bool correctionNeeded;
|
||||
bool correction_needed;
|
||||
|
||||
// Modulate Manchester
|
||||
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
|
||||
if (Uart.bitCount == 7) {
|
||||
// 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 {
|
||||
// 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
|
||||
i = (correctionNeeded) ? 0 : 1;
|
||||
i = (correction_needed) ? 0 : 1;
|
||||
|
||||
// clear receiving shift register and holding register
|
||||
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
|
||||
b = AT91C_BASE_SSC->SSC_RHR;
|
||||
(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;
|
||||
*/
|
||||
|
||||
// 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
|
||||
|
@ -2000,22 +2045,24 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
|
|||
FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
}
|
||||
|
||||
/*
|
||||
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
|
||||
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
|
||||
(void)b;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again:
|
||||
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)) {
|
||||
AT91C_BASE_SSC->SSC_THR = SEC_F;
|
||||
FpgaSendQueueDelay = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
LastTimeProxToAirStart = ThisTransferTime + (correctionNeeded ? 8 : 0);
|
||||
LastTimeProxToAirStart = ThisTransferTime + (correction_needed ? 8 : 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) {
|
||||
if (p_response == NULL) return 0;
|
||||
int ret = EmSendCmd14443aRaw(p_response->modulation, p_response->modulation_n);
|
||||
// do the tracing for the previous reader request and this tag answer:
|
||||
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, " 8 = MIFARE Classic 4k");
|
||||
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 byte UID");
|
||||
PrintAndLogEx(NORMAL, " x : (Optional) Performs the 'reader attack', nr/ar attack against a reader");
|
||||
|
|
Loading…
Reference in a new issue