mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
'hf mf sim' + 'hf 14a sim' now back to stable
This commit is contained in:
parent
8c4f8eaeca
commit
249352a1e7
4 changed files with 91 additions and 122 deletions
|
@ -19,7 +19,6 @@ int rsamples = 0;
|
||||||
uint8_t trigger = 0;
|
uint8_t trigger = 0;
|
||||||
// the block number for the ISO14443-4 PCB
|
// the block number for the ISO14443-4 PCB
|
||||||
static uint8_t iso14_pcb_blocknum = 0;
|
static uint8_t iso14_pcb_blocknum = 0;
|
||||||
static uint8_t *free_buffer_pointer;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// ISO14443 timing:
|
// ISO14443 timing:
|
||||||
|
@ -740,34 +739,6 @@ static void Code4bitAnswerAsTag(uint8_t cmd) {
|
||||||
ToSendMax++;
|
ToSendMax++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t *LastReaderTraceTime = NULL;
|
|
||||||
|
|
||||||
void EmLogTraceReader(void) {
|
|
||||||
// remember last reader trace start to fix timing info later
|
|
||||||
LastReaderTraceTime = BigBuf_get_addr() + BigBuf_get_traceLen();
|
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FixLastReaderTraceTime(uint32_t tag_StartTime) {
|
|
||||||
uint32_t reader_EndTime = Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG;
|
|
||||||
uint32_t reader_StartTime = Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG;
|
|
||||||
uint16_t reader_modlen = reader_EndTime - reader_StartTime;
|
|
||||||
uint16_t approx_fdt = tag_StartTime - reader_EndTime;
|
|
||||||
uint16_t exact_fdt = (approx_fdt - 20 + 32) / 64 * 64 + 20;
|
|
||||||
reader_StartTime = tag_StartTime - exact_fdt - reader_modlen;
|
|
||||||
LastReaderTraceTime[0] = (reader_StartTime >> 0) & 0xff;
|
|
||||||
LastReaderTraceTime[1] = (reader_StartTime >> 8) & 0xff;
|
|
||||||
LastReaderTraceTime[2] = (reader_StartTime >> 16) & 0xff;
|
|
||||||
LastReaderTraceTime[3] = (reader_StartTime >> 24) & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void EmLogTraceTag(uint8_t *tag_data, uint16_t tag_len, uint8_t *tag_Parity, uint32_t ProxToAirDuration) {
|
|
||||||
uint32_t tag_StartTime = LastTimeProxToAirStart * 16 + DELAY_ARM2AIR_AS_TAG;
|
|
||||||
uint32_t tag_EndTime = (LastTimeProxToAirStart + ProxToAirDuration) * 16 + DELAY_ARM2AIR_AS_TAG;
|
|
||||||
LogTrace(tag_data, tag_len, tag_StartTime, tag_EndTime, tag_Parity, false);
|
|
||||||
FixLastReaderTraceTime(tag_StartTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Wait for commands from reader
|
// Wait for commands from reader
|
||||||
// stop when button is pressed
|
// stop when button is pressed
|
||||||
|
@ -793,7 +764,6 @@ static int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *par, int *l
|
||||||
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
if (MillerDecoding(b, 0)) {
|
if (MillerDecoding(b, 0)) {
|
||||||
*len = Uart.len;
|
*len = Uart.len;
|
||||||
EmLogTraceReader();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -831,14 +801,6 @@ static bool prepare_tag_modulation(tag_response_info_t *response_info, size_t ma
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// "precompile" responses. There are 7 predefined responses with a total of 28 bytes data to transmit.
|
|
||||||
// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
|
|
||||||
// 28 * 8 data bits, 28 * 1 parity bits, 7 start bits, 7 stop bits, 7 correction bits
|
|
||||||
// -> need 273 bytes buffer
|
|
||||||
// 44 * 8 data bits, 44 * 1 parity bits, 9 start bits, 9 stop bits, 9 correction bits --370
|
|
||||||
// 47 * 8 data bits, 47 * 1 parity bits, 10 start bits, 10 stop bits, 10 correction bits
|
|
||||||
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 453
|
|
||||||
|
|
||||||
bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_t **buffer, size_t *max_buffer_size) {
|
bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_t **buffer, size_t *max_buffer_size) {
|
||||||
|
|
||||||
// Retrieve and store the current buffer index
|
// Retrieve and store the current buffer index
|
||||||
|
@ -1013,7 +975,7 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) {
|
||||||
// Prepare CHK_TEARING
|
// Prepare CHK_TEARING
|
||||||
// uint8_t response9[] = {0xBD,0x90,0x3f};
|
// uint8_t response9[] = {0xBD,0x90,0x3f};
|
||||||
|
|
||||||
#define TAG_RESPONSE_COUNT 10
|
#define TAG_RESPONSE_COUNT 8
|
||||||
tag_response_info_t responses[TAG_RESPONSE_COUNT] = {
|
tag_response_info_t responses[TAG_RESPONSE_COUNT] = {
|
||||||
{ .response = response1, .response_n = sizeof(response1) }, // Answer to request - respond with card type
|
{ .response = response1, .response_n = sizeof(response1) }, // Answer to request - respond with card type
|
||||||
{ .response = response2, .response_n = sizeof(response2) }, // Anticollision cascade1 - respond with uid
|
{ .response = response2, .response_n = sizeof(response2) }, // Anticollision cascade1 - respond with uid
|
||||||
|
@ -1028,6 +990,13 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) {
|
||||||
// { .response = response7_NTAG, .response_n = sizeof(response7_NTAG)}, // EV1/NTAG GET_VERSION response
|
// { .response = response7_NTAG, .response_n = sizeof(response7_NTAG)}, // EV1/NTAG GET_VERSION response
|
||||||
// { .response = response9, .response_n = sizeof(response9) } // EV1/NTAG CHK_TEAR response
|
// { .response = response9, .response_n = sizeof(response9) } // EV1/NTAG CHK_TEAR response
|
||||||
|
|
||||||
|
// "precompile" responses. There are 8 predefined responses with a total of 32 bytes data to transmit.
|
||||||
|
// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
|
||||||
|
// 32 * 8 data bits, 32 * 1 parity bits, 8 start bits, 8 stop bits, 8 correction bits
|
||||||
|
// -> need 312 bytes buffer
|
||||||
|
// 42 * 8 data bits, 42 * 1 parity bits, 9 start bits, 9 stop bits, 9 correction bits --405
|
||||||
|
// 45 * 8 data bits, 45 * 1 parity bits, 10 start bits, 10 stop bits, 10 correction bits --435
|
||||||
|
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 453
|
||||||
|
|
||||||
// Allocate 512 bytes for the dynamic modulation, created when the reader queries for it
|
// Allocate 512 bytes for the dynamic modulation, created when the reader queries for it
|
||||||
// Such a response is less time critical, so we can prepare them on the fly
|
// Such a response is less time critical, so we can prepare them on the fly
|
||||||
|
@ -1042,23 +1011,29 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) {
|
||||||
.modulation_n = 0
|
.modulation_n = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// We need to listen to the high-frequency, peak-detected path.
|
// free eventually allocated BigBuf memory but keep Emulator Memory
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
|
||||||
|
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
clear_trace();
|
|
||||||
set_tracing(true);
|
|
||||||
|
|
||||||
// allocate buffers:
|
// allocate buffers:
|
||||||
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
|
||||||
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
|
||||||
//free_buffer_pointer = 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
|
||||||
|
uint8_t *free_buffer_pointer = free_buffer;
|
||||||
size_t free_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE;
|
size_t free_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE;
|
||||||
|
|
||||||
// Prepare the responses of the anticollision phase
|
// Prepare the responses of the anticollision phase
|
||||||
// there will be not enough time to do this at the moment the reader sends it REQA
|
// there will be not enough time to do this at the moment the reader sends it REQA
|
||||||
for (size_t i = 0; i < TAG_RESPONSE_COUNT; i++)
|
for (size_t i = 0; i < TAG_RESPONSE_COUNT; i++) {
|
||||||
prepare_allocated_tag_modulation(&responses[i], &free_buffer_pointer, &free_buffer_size);
|
if (prepare_allocated_tag_modulation(&responses[i], &free_buffer_pointer, &free_buffer_size) == false) {
|
||||||
|
BigBuf_free_keep_EM();
|
||||||
|
Dbprintf("Not enough modulation buffer size, exit after %d elements", i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to listen to the high-frequency, peak-detected path.
|
||||||
|
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
|
||||||
|
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
|
@ -1072,6 +1047,8 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) {
|
||||||
int cmdsRecvd = 0;
|
int cmdsRecvd = 0;
|
||||||
tag_response_info_t *p_response;
|
tag_response_info_t *p_response;
|
||||||
|
|
||||||
|
clear_trace();
|
||||||
|
set_tracing(true);
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -1409,27 +1386,14 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t *data) {
|
||||||
cmdsRecvd++;
|
cmdsRecvd++;
|
||||||
|
|
||||||
if (p_response != NULL) {
|
if (p_response != NULL) {
|
||||||
EmSendCmd14443aRaw(p_response->modulation, p_response->modulation_n);
|
EmSendPrecompiledCmd(p_response);
|
||||||
// do the tracing for the previous reader request and this tag answer:
|
|
||||||
uint8_t par[MAX_PARITY_SIZE] = {0x00};
|
|
||||||
GetParity(p_response->response, p_response->response_n, par);
|
|
||||||
|
|
||||||
EmLogTrace(Uart.output,
|
|
||||||
Uart.len,
|
|
||||||
Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG,
|
|
||||||
Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG,
|
|
||||||
Uart.parity,
|
|
||||||
p_response->response,
|
|
||||||
p_response->response_n,
|
|
||||||
LastTimeProxToAirStart * 16 + DELAY_ARM2AIR_AS_TAG,
|
|
||||||
(LastTimeProxToAirStart + p_response->ProxToAirDuration) * 16 + DELAY_ARM2AIR_AS_TAG,
|
|
||||||
par);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||||
switch_off();
|
switch_off();
|
||||||
|
|
||||||
|
set_tracing(false);
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
|
|
||||||
if (MF_DBGLEVEL >= 4) {
|
if (MF_DBGLEVEL >= 4) {
|
||||||
|
@ -1663,7 +1627,6 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par) {
|
||||||
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||||
if (MillerDecoding(b, 0)) {
|
if (MillerDecoding(b, 0)) {
|
||||||
*len = Uart.len;
|
*len = Uart.len;
|
||||||
EmLogTraceReader();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1782,17 +1745,27 @@ int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool collision) {
|
||||||
return EmSendCmdParEx(resp, respLen, par, collision);
|
return EmSendCmdParEx(resp, respLen, par, collision);
|
||||||
}
|
}
|
||||||
|
|
||||||
int EmSendPrecompiledCmd(tag_response_info_t *response_info) {
|
int EmSendPrecompiledCmd(tag_response_info_t *p_response) {
|
||||||
int ret = EmSendCmd14443aRaw(response_info->modulation, response_info->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:
|
||||||
EmLogTraceTag(response_info->response, response_info->response_n,
|
uint8_t par[MAX_PARITY_SIZE] = {0x00};
|
||||||
&(response_info->par), response_info->ProxToAirDuration);
|
GetParity(p_response->response, p_response->response_n, par);
|
||||||
|
|
||||||
|
EmLogTrace(Uart.output,
|
||||||
|
Uart.len,
|
||||||
|
Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG,
|
||||||
|
Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG,
|
||||||
|
Uart.parity,
|
||||||
|
p_response->response,
|
||||||
|
p_response->response_n,
|
||||||
|
LastTimeProxToAirStart * 16 + DELAY_ARM2AIR_AS_TAG,
|
||||||
|
(LastTimeProxToAirStart + p_response->ProxToAirDuration) * 16 + DELAY_ARM2AIR_AS_TAG,
|
||||||
|
par);
|
||||||
|
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) {
|
||||||
Dbprintf("response_info->response %02X", response_info->response);
|
Dbprintf("response_info->response %02X", p_response->response);
|
||||||
Dbprintf("response_info->response_n %02X", response_info->response_n);
|
Dbprintf("response_info->response_n %02X", p_response->response_n);
|
||||||
Dbprintf("response_info->par %02X", &(response_info->par));
|
Dbprintf("response_info->par %02X", &(p_response->par));
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -133,7 +133,6 @@ int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32
|
||||||
int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades);
|
int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades);
|
||||||
void iso14a_set_trigger(bool enable);
|
void iso14a_set_trigger(bool enable);
|
||||||
|
|
||||||
int EmSendPrecompiledCmd(tag_response_info_t *response_info);
|
|
||||||
int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen);
|
int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen);
|
||||||
int EmSend4bit(uint8_t resp);
|
int EmSend4bit(uint8_t resp);
|
||||||
int EmSendCmd(uint8_t *resp, uint16_t respLen);
|
int EmSendCmd(uint8_t *resp, uint16_t respLen);
|
||||||
|
@ -141,9 +140,7 @@ int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool collision);
|
||||||
int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par);
|
int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *par);
|
||||||
int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par);
|
int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par);
|
||||||
int EmSendCmdParEx(uint8_t *resp, uint16_t respLen, uint8_t *par, bool collision);
|
int EmSendCmdParEx(uint8_t *resp, uint16_t respLen, uint8_t *par, bool collision);
|
||||||
int EmSendPrecompiledCmd(tag_response_info_t *response_info);
|
int EmSendPrecompiledCmd(tag_response_info_t *p_response);
|
||||||
|
|
||||||
void EmLogTraceReader(void);
|
|
||||||
|
|
||||||
bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_t **buffer, size_t *max_buffer_size);
|
bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_t **buffer, size_t *max_buffer_size);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Merlok - June 2011, 2012
|
// Merlok - June 2011, 2012
|
||||||
// Gerhard de Koning Gans - May 2008
|
// Gerhard de Koning Gans - May 2008
|
||||||
// Hagen Fritsch - June 2010
|
// Hagen Fritsch - June 2010
|
||||||
|
@ -152,7 +152,7 @@ static bool IsAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len) {
|
static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t **responses, uint32_t *cuid, uint8_t *uid_len) {
|
||||||
|
|
||||||
// SPEC: https://www.nxp.com/docs/en/application-note/AN10833.pdf
|
// SPEC: https://www.nxp.com/docs/en/application-note/AN10833.pdf
|
||||||
// ATQA
|
// ATQA
|
||||||
|
@ -323,8 +323,9 @@ static void MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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 = rUIDBCC1, .response_n = sizeof(rUIDBCC1) }, // Anticollision cascade1 - respond with first part of uid
|
{ .response = rUIDBCC1, .response_n = sizeof(rUIDBCC1) }, // Anticollision cascade1 - respond with first part of uid
|
||||||
{ .response = rUIDBCC2, .response_n = sizeof(rUIDBCC2) }, // Anticollision cascade2 - respond with 2nd part of uid
|
{ .response = rUIDBCC2, .response_n = sizeof(rUIDBCC2) }, // Anticollision cascade2 - respond with 2nd part of uid
|
||||||
{ .response = rUIDBCC3, .response_n = sizeof(rUIDBCC3) }, // Anticollision cascade3 - respond with 3th part of uid
|
{ .response = rUIDBCC3, .response_n = sizeof(rUIDBCC3) }, // Anticollision cascade3 - respond with 3th part of uid
|
||||||
|
@ -335,15 +336,23 @@ static void MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
||||||
{ .response = rSAK1, .response_n = sizeof(rSAK1) } // Acknowledge select - Need another cascades
|
{ .response = rSAK1, .response_n = sizeof(rSAK1) } // Acknowledge select - Need another cascades
|
||||||
};
|
};
|
||||||
|
|
||||||
// Prepare ("precompile") the responses of the anticollision phase. There will be not enough time to do this at the moment the reader sends its REQA or SELECT
|
// Prepare ("precompile") the responses of the anticollision phase.
|
||||||
// There are 7 predefined responses with a total of 18 bytes data to transmit. Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
|
// There will be not enough time to do this at the moment the reader sends its REQA or SELECT
|
||||||
// 18 * 8 data bits, 18 * 1 parity bits, 5 start bits, 5 stop bits, 5 correction bits -> need 177 bytes buffer
|
// There are 9 predefined responses with a total of 32 bytes data to transmit.
|
||||||
|
// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
|
||||||
|
// 32 * 8 data bits, 32 * 1 parity bits, 9 start bits, 9 stop bits, 9 correction bits -> need 315 bytes buffer
|
||||||
|
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 512
|
||||||
|
|
||||||
uint8_t *free_buffer_pointer = 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
|
||||||
|
uint8_t *free_buffer_pointer = free_buffer;
|
||||||
size_t free_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE;
|
size_t free_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE;
|
||||||
|
|
||||||
for (size_t i = 0; i < TAG_RESPONSE_COUNT; i++) {
|
for (size_t i = 0; i < TAG_RESPONSE_COUNT; i++) {
|
||||||
prepare_allocated_tag_modulation(&responses_init[i], &free_buffer_pointer, &free_buffer_size);
|
if (prepare_allocated_tag_modulation(&responses_init[i], &free_buffer_pointer, &free_buffer_size) == false) {
|
||||||
|
Dbprintf("Not enough modulation buffer size, exit after %d elements", i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*responses = responses_init;
|
*responses = responses_init;
|
||||||
|
@ -359,6 +368,7 @@ static void MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
||||||
#define SAK_4 7
|
#define SAK_4 7
|
||||||
#define SAK1 8
|
#define SAK1 8
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HasValidCRC(uint8_t *receivedCmd, uint16_t receivedCmd_len) {
|
static bool HasValidCRC(uint8_t *receivedCmd, uint16_t receivedCmd_len) {
|
||||||
|
@ -459,13 +469,17 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
Dbprintf("Mifare 4K");
|
Dbprintf("Mifare 4K");
|
||||||
}
|
}
|
||||||
|
|
||||||
MifareSimInit(flags, datain, &responses, &cuid, &uid_len);
|
// free eventually allocated BigBuf memory but keep Emulator Memory
|
||||||
|
BigBuf_free_keep_EM();
|
||||||
|
|
||||||
|
if (MifareSimInit(flags, datain, &responses, &cuid, &uid_len) == false) {
|
||||||
|
BigBuf_free_keep_EM();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
// free eventually allocated BigBuf memory but keep Emulator Memory
|
|
||||||
BigBuf_free_keep_EM();
|
|
||||||
// clear trace
|
// clear trace
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
@ -742,13 +756,6 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
|
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Enter in case");
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Enter in case");
|
||||||
|
|
||||||
if (receivedCmd_len != 4) {
|
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
|
||||||
mf_crypto1_decryptEx(pcs, receivedCmd, receivedCmd_len, receivedCmd_dec);
|
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] All commands must have exactly 4 bytes: receivedCmd_len=%d - Cmd: %02X", receivedCmd_len, receivedCmd_dec);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (receivedCmd_len == 0) {
|
if (receivedCmd_len == 0) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received");
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received");
|
||||||
break;
|
break;
|
||||||
|
@ -824,8 +831,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
}
|
}
|
||||||
|
|
||||||
cardSTATE = MFEMUL_AUTH1;
|
cardSTATE = MFEMUL_AUTH1;
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_AUTH1 - rAUTH_AT: %02X", rAUTH_AT);
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_AUTH1 - rAUTH_NT: %02X", rAUTH_NT);
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// rule 13 of 7.5.3. in ISO 14443-4. chaining shall be continued
|
// rule 13 of 7.5.3. in ISO 14443-4. chaining shall be continued
|
||||||
|
@ -841,25 +848,26 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (!encrypted_data) { // all other commands must be encrypted (authenticated)
|
|
||||||
// if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Commands must be encrypted (authenticated)");
|
|
||||||
// break;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// case MFEMUL_WORK => if Cmd is Read, Write, Inc, Dec, Restore, Transfert
|
// case MFEMUL_WORK => if Cmd is Read, Write, Inc, Dec, Restore, Transfert
|
||||||
if (receivedCmd_dec[0] == ISO14443A_CMD_READBLOCK
|
if (receivedCmd_len == 4 && (receivedCmd_dec[0] == ISO14443A_CMD_READBLOCK
|
||||||
|| receivedCmd_dec[0] == ISO14443A_CMD_WRITEBLOCK
|
|| receivedCmd_dec[0] == ISO14443A_CMD_WRITEBLOCK
|
||||||
|| receivedCmd_dec[0] == MIFARE_CMD_INC
|
|| receivedCmd_dec[0] == MIFARE_CMD_INC
|
||||||
|| receivedCmd_dec[0] == MIFARE_CMD_DEC
|
|| receivedCmd_dec[0] == MIFARE_CMD_DEC
|
||||||
|| receivedCmd_dec[0] == MIFARE_CMD_RESTORE
|
|| receivedCmd_dec[0] == MIFARE_CMD_RESTORE
|
||||||
|| receivedCmd_dec[0] == MIFARE_CMD_TRANSFER) {
|
|| receivedCmd_dec[0] == MIFARE_CMD_TRANSFER)) {
|
||||||
|
// all other commands must be encrypted (authenticated)
|
||||||
|
if (!encrypted_data) {
|
||||||
|
EmSend4bit(CARD_NACK_NA);
|
||||||
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Commands must be encrypted (authenticated)");
|
||||||
|
break;
|
||||||
|
}
|
||||||
// Check if Block num is not too far
|
// Check if Block num is not too far
|
||||||
if (receivedCmd_dec[1] > MIFARE_4K_MAXBLOCK) {
|
if (receivedCmd_dec[1] > MIFARE_4K_MAXBLOCK) {
|
||||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], receivedCmd_dec[1]);
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], receivedCmd_dec[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (receivedCmd_dec[1] / 4 != cardAUTHSC) {
|
if (MifareBlockToSector(receivedCmd_dec[1]) != cardAUTHSC) {
|
||||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on block (0x%02x) not authenticated for (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], cardAUTHSC);
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on block (0x%02x) not authenticated for (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], cardAUTHSC);
|
||||||
break;
|
break;
|
||||||
|
@ -867,7 +875,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// case MFEMUL_WORK => CMD READ block
|
// case MFEMUL_WORK => CMD READ block
|
||||||
if (receivedCmd_dec[0] == ISO14443A_CMD_READBLOCK) {
|
if (receivedCmd_len == 4 && receivedCmd_dec[0] == ISO14443A_CMD_READBLOCK) {
|
||||||
blockNo = receivedCmd_dec[1];
|
blockNo = receivedCmd_dec[1];
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Reader reading block %d (0x%02x)", blockNo, blockNo);
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Reader reading block %d (0x%02x)", blockNo, blockNo);
|
||||||
emlGetMem(response, blockNo, 1);
|
emlGetMem(response, blockNo, 1);
|
||||||
|
@ -933,7 +941,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
} // End receivedCmd_dec[0] == ISO14443A_CMD_READBLOCK
|
} // End receivedCmd_dec[0] == ISO14443A_CMD_READBLOCK
|
||||||
|
|
||||||
// case MFEMUL_WORK => CMD WRITEBLOCK
|
// case MFEMUL_WORK => CMD WRITEBLOCK
|
||||||
if (receivedCmd_dec[0] == ISO14443A_CMD_WRITEBLOCK) {
|
if (receivedCmd_len == 4 && receivedCmd_dec[0] == ISO14443A_CMD_WRITEBLOCK) {
|
||||||
blockNo = receivedCmd_dec[1];
|
blockNo = receivedCmd_dec[1];
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RECV 0xA0 write block %d (%02x)", blockNo, blockNo);
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RECV 0xA0 write block %d (%02x)", blockNo, blockNo);
|
||||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK));
|
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK));
|
||||||
|
@ -944,7 +952,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// case MFEMUL_WORK => CMD INC/DEC/REST
|
// case MFEMUL_WORK => CMD INC/DEC/REST
|
||||||
if (receivedCmd_dec[0] == MIFARE_CMD_INC || receivedCmd_dec[0] == MIFARE_CMD_DEC || receivedCmd_dec[0] == MIFARE_CMD_RESTORE) {
|
if (receivedCmd_len == 4 && (receivedCmd_dec[0] == MIFARE_CMD_INC || receivedCmd_dec[0] == MIFARE_CMD_DEC || receivedCmd_dec[0] == MIFARE_CMD_RESTORE)) {
|
||||||
blockNo = receivedCmd_dec[1];
|
blockNo = receivedCmd_dec[1];
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RECV 0x%02x inc(0xC1)/dec(0xC0)/restore(0xC2) block %d (%02x)", receivedCmd_dec[0], blockNo, blockNo);
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RECV 0x%02x inc(0xC1)/dec(0xC0)/restore(0xC2) block %d (%02x)", receivedCmd_dec[0], blockNo, blockNo);
|
||||||
if (emlCheckValBl(blockNo)) {
|
if (emlCheckValBl(blockNo)) {
|
||||||
|
@ -978,7 +986,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
|
|
||||||
|
|
||||||
// case MFEMUL_WORK => CMD TRANSFER
|
// case MFEMUL_WORK => CMD TRANSFER
|
||||||
if (receivedCmd_dec[0] == MIFARE_CMD_TRANSFER) {
|
if (receivedCmd_len == 4 && receivedCmd_dec[0] == MIFARE_CMD_TRANSFER) {
|
||||||
blockNo = receivedCmd_dec[1];
|
blockNo = receivedCmd_dec[1];
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RECV 0x%02x transfer block %d (%02x)", receivedCmd_dec[0], blockNo, blockNo);
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RECV 0x%02x transfer block %d (%02x)", receivedCmd_dec[0], blockNo, blockNo);
|
||||||
if (emlSetValBl(cardINTREG, cardINTBLOCK, receivedCmd_dec[1]))
|
if (emlSetValBl(cardINTREG, cardINTBLOCK, receivedCmd_dec[1]))
|
||||||
|
@ -989,17 +997,18 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
}
|
}
|
||||||
|
|
||||||
// case MFEMUL_WORK => CMD HALT
|
// case MFEMUL_WORK => CMD HALT
|
||||||
if (receivedCmd_dec[0] == ISO14443A_CMD_HALT && receivedCmd[1] == 0x00) {
|
if (receivedCmd_len > 1 && receivedCmd_dec[0] == ISO14443A_CMD_HALT && receivedCmd_dec[1] == 0x00) {
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
LogTrace(Uart.output, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
cardSTATE = MFEMUL_HALTED;
|
cardSTATE = MFEMUL_HALTED;
|
||||||
|
cardAUTHKEY = AUTHKEYNONE;
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_HALTED");
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_HALTED");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// case MFEMUL_WORK => CMD RATS
|
// case MFEMUL_WORK => CMD RATS
|
||||||
if (receivedCmd[0] == ISO14443A_CMD_RATS) {
|
if (receivedCmd_dec[0] == ISO14443A_CMD_RATS) {
|
||||||
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
|
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV RATS => NACK");
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV RATS => NACK");
|
||||||
break;
|
break;
|
||||||
|
@ -1015,7 +1024,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
case MFEMUL_AUTH1: {
|
case MFEMUL_AUTH1: {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_AUTH1] Enter case");
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("[MFEMUL_AUTH1] Enter case");
|
||||||
|
|
||||||
if (receivedCmd_len != 4) {
|
if (receivedCmd_len != 8) {
|
||||||
cardSTATE_TO_IDLE();
|
cardSTATE_TO_IDLE();
|
||||||
LogTrace(Uart.output, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
LogTrace(Uart.output, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("MFEMUL_AUTH1: receivedCmd_len != 8 (%d) => cardSTATE_TO_IDLE())", receivedCmd_len);
|
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("MFEMUL_AUTH1: receivedCmd_len != 8 (%d) => cardSTATE_TO_IDLE())", receivedCmd_len);
|
||||||
|
@ -1101,8 +1110,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
cardAUTHKEY = AUTHKEYNONE; // not authenticated
|
cardAUTHKEY = AUTHKEYNONE; // not authenticated
|
||||||
// LogTrace(Uart.output, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
|
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
||||||
EmSend4bit(CARD_NACK_NA);
|
|
||||||
cardSTATE_TO_IDLE();
|
cardSTATE_TO_IDLE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1261,5 +1269,5 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
|
BigBuf_free_keep_EM();
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,13 +36,4 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t
|
||||||
#define AUTHKEYB 1
|
#define AUTHKEYB 1
|
||||||
#define AUTHKEYNONE 0xff
|
#define AUTHKEYNONE 0xff
|
||||||
|
|
||||||
#define TAG_RESPONSE_COUNT 9 // number of precompiled responses
|
|
||||||
|
|
||||||
// Prepare ("precompile") the responses of the anticollision phase.
|
|
||||||
// There will be not enough time to do this at the moment the reader sends its REQA or SELECT
|
|
||||||
// There are 7 predefined responses with a total of 18 bytes data to transmit.
|
|
||||||
// Coded responses need one byte per bit to transfer (data, parity, start, stop, correction)
|
|
||||||
// 18 * 8 data bits, 18 * 1 parity bits, 5 start bits, 5 stop bits, 5 correction bits -> need 177 bytes buffer
|
|
||||||
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 512 // number of bytes required for precompiled response
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue