This commit is contained in:
iceman1001 2023-10-09 12:47:00 +02:00
commit 60ff2351ba
2 changed files with 92 additions and 78 deletions

View file

@ -30,7 +30,7 @@
#include "cmd.h" #include "cmd.h"
void ModInfo(void) { void ModInfo(void) {
DbpString(" HF - Reading Visa cards & Emulating a Visa MSD Transaction(ISO14443) - (Salvador Mendoza)"); DbpString(" HF - Reading VISA cards & Emulating a VISA MSD Transaction(ISO14443) - (Salvador Mendoza)");
} }
/* This standalone implements two different modes: reading and emulating. /* This standalone implements two different modes: reading and emulating.
@ -132,9 +132,15 @@ static uint8_t treatPDOL(const uint8_t *apdu) {
void RunMod(void) { void RunMod(void) {
StandAloneMode(); StandAloneMode();
DbpString(_YELLOW_(">>") "Reading Visa cards & Emulating a Visa MSD Transaction a.k.a. MSDSal Started " _YELLOW_("<<")); DbpString("");
DbpString(_YELLOW_(">>>") " Reading VISA cards & Emulating a VISA MSD Transaction a.k.a. MSDSal Started " _YELLOW_("<<<"));
DbpString("");
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// free eventually allocated BigBuf memory but keep Emulator Memory
// also sets HIGH pointer of BigBuf enabling us to malloc w/o fiddling w the reserved emulator memory
BigBuf_free_keep_EM();
//For reading process //For reading process
iso14a_card_select_t card_a_info; iso14a_card_select_t card_a_info;
@ -161,7 +167,6 @@ void RunMod(void) {
bool existpdol; bool existpdol;
// - MSD token card format - // - MSD token card format -
// //
//Card number: 4412 3456 0578 1234 //Card number: 4412 3456 0578 1234
@ -175,34 +180,31 @@ void RunMod(void) {
char token[19] = {0x00}; char token[19] = {0x00};
bool chktoken = false; bool chktoken = false;
// 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
#define DYNAMIC_RESPONSE_BUFFER_SIZE 64
#define DYNAMIC_MODULATION_BUFFER_SIZE 512
// UID 4 bytes(could be 7 bytes if needed it) // UID 4 bytes(could be 7 bytes if needed it)
uint8_t flags = FLAG_4B_UID_IN_DATA; uint8_t flags = FLAG_4B_UID_IN_DATA;
// in case there is a read command received we shouldn't break // in case there is a read command received we shouldn't break
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00}; uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
uint8_t visauid[7] = {0x01, 0x02, 0x03, 0x04}; uint8_t visauid[7] = {0x04, 0x02, 0x03, 0x04};
memcpy(data, visauid, 4); memcpy(data, visauid, 4);
// to initialize the emulation // to initialize the emulation
uint8_t tagType = 11; // 11 = ISO/IEC 14443-4 - javacard (JCOP)
tag_response_info_t *responses; tag_response_info_t *responses;
uint32_t cuid = 0; uint32_t cuid = 0;
uint32_t counters[3] = { 0x00, 0x00, 0x00 };
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
uint8_t pages = 0;
// command buffers // command buffers
uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 }; uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 };
uint8_t receivedCmdPar[MAX_PARITY_SIZE] = { 0x00 }; uint8_t receivedCmdPar[MAX_PARITY_SIZE] = { 0x00 };
uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE] = {0};
uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE] = {0};
// 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
#define DYNAMIC_RESPONSE_BUFFER_SIZE 64
#define DYNAMIC_MODULATION_BUFFER_SIZE 512
uint8_t *dynamic_response_buffer = BigBuf_calloc(DYNAMIC_RESPONSE_BUFFER_SIZE);
uint8_t *dynamic_modulation_buffer = BigBuf_calloc(DYNAMIC_MODULATION_BUFFER_SIZE);
// to know the transaction status // to know the transaction status
uint8_t prevCmd = 0; uint8_t prevCmd = 0;
@ -223,11 +225,11 @@ void RunMod(void) {
// Checking if the user wants to go directly to emulation mode using a hardcoded track 2 // Checking if the user wants to go directly to emulation mode using a hardcoded track 2
if (chktoken == true && token[0] != 0x00) { if (chktoken == true && token[0] != 0x00) {
state = STATE_EMU; state = STATE_EMU;
DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]")); DbpString("Initialized [ " _BLUE_("emulation mode") " ]");
DbpString("\n"_YELLOW_("!!") "Waiting for a card reader..."); DbpString("Waiting for a card reader...");
} else { } else {
DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]")); DbpString("Initialized [ " _YELLOW_("reading mode") " ]");
DbpString("\n"_YELLOW_("!!") "Waiting for a Visa card..."); DbpString("Waiting for a VISA card...");
} }
for (;;) { for (;;) {
@ -240,20 +242,20 @@ void RunMod(void) {
int button_pressed = BUTTON_HELD(1000); int button_pressed = BUTTON_HELD(1000);
if (button_pressed == BUTTON_HOLD) if (button_pressed == BUTTON_HOLD) {
break; break;
else if (button_pressed == BUTTON_SINGLE_CLICK) { } else if (button_pressed == BUTTON_SINGLE_CLICK) {
// pressing one time change between reading & emulation // pressing one time change between reading & emulation
if (state == STATE_READ) { if (state == STATE_READ) {
if (chktoken == true && token[0] != 0x00) { if (chktoken == true && token[0] != 0x00) {
// only change to emulation if it saved a track 2 in memory // only change to emulation if it saved a track 2 in memory
state = STATE_EMU; state = STATE_EMU;
DbpString(_YELLOW_("[ ") "In emulation mode" _YELLOW_(" ]")); DbpString("[ " _BLUE_("Emulation mode") " ]");
} else } else
DbpString(_YELLOW_("!!") "Nothing in memory to emulate"); DbpString(_YELLOW_("Nothing in memory to emulate"));
} else { } else {
state = STATE_READ; state = STATE_READ;
DbpString(_YELLOW_("[ ") "In reading mode" _YELLOW_(" ]")); DbpString("[ " _YELLOW_("Reading mode") " ]");
} }
} }
@ -261,15 +263,14 @@ void RunMod(void) {
if (state == STATE_READ) { if (state == STATE_READ) {
LED_A_ON(); LED_A_ON();
if (chktoken) if (chktoken) {
LED_C_ON(); LED_C_ON();
}
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) { if (iso14443a_select_card(NULL, &card_a_info, NULL, true, 0, false)) {
DbpString(_YELLOW_("+") "Found ISO 14443 Type A!");
for (uint8_t i = 0; i < 4; i++) { for (uint8_t i = 0; i < 4; i++) {
chktoken = false; chktoken = false;
LED_C_OFF(); LED_C_OFF();
@ -277,11 +278,11 @@ void RunMod(void) {
uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apduslen[i], false, apdubuffer, NULL); uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apduslen[i], false, apdubuffer, NULL);
if (apdulen > 0) { if (apdulen > 0) {
DbpString(_YELLOW_("[ ") "Proxmark command" _YELLOW_(" ]")); DbpString("[ " _YELLOW_("Proxmark command") " ]");
Dbhexdump(apduslen[i], apdus[i], false); Dbhexdump(apduslen[i], apdus[i], false);
DbpString(_GREEN_("[ ") "Card answer" _GREEN_(" ]")); DbpString("[ " _GREEN_( "Card answer") " ]");
Dbhexdump(apdulen - 2, apdubuffer, false); Dbhexdump(apdulen - 2, apdubuffer, false);
DbpString("----"); DbpString("-------------------------------");
for (uint8_t u = 0; u < apdulen; u++) { for (uint8_t u = 0; u < apdulen; u++) {
if (i == 1) { if (i == 1) {
@ -309,25 +310,27 @@ void RunMod(void) {
} }
if (i == 1) { if (i == 1) {
DbpString(_GREEN_("[ ") "Challenge generated" _GREEN_(" ]")); DbpString("[ "_GREEN_("Challenge generated") " ]");
Dbhexdump(plen, existpdol ? ppdol : processing, false); Dbhexdump(plen, existpdol ? ppdol : processing, false);
} }
} else { } else {
DbpString(_YELLOW_("!!") "Error reading the card"); DbpString(_RED_("Error reading the card"));
} }
LED_B_OFF(); LED_B_OFF();
} }
if (chktoken) { if (chktoken) {
DbpString(_RED_("[ ") "Track 2" _RED_(" ]")); DbpString("[ " _GREEN_("Track 2") " ]");
Dbhexdump(19, (uint8_t *)token, false); Dbhexdump(19, (uint8_t *)token, false);
DbpString(_YELLOW_("!!") "Card number"); DbpString("[ " _GREEN_("Card Number") " ]");
Dbhexdump(8, (uint8_t *)token, false); Dbhexdump(8, (uint8_t *)token, false);
DbpString("---"); DbpString("-------------------------------");
DbpString("");
DbpString("");
LED_C_ON(); LED_C_ON();
state = STATE_EMU; state = STATE_EMU;
DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]")); DbpString("Initialized [ " _BLUE_("emulation mode") " ]");
DbpString("\n"_YELLOW_("!!") "Waiting for a card reader..."); DbpString("Waiting for a card reader...");
} }
} }
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -340,14 +343,15 @@ void RunMod(void) {
// free eventually allocated BigBuf memory but keep Emulator Memory // free eventually allocated BigBuf memory but keep Emulator Memory
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
if (SimulateIso14443aInit(tagType, flags, data, &responses, &cuid, counters, tearings, &pages) == false) { // tag type: 11 = ISO/IEC 14443-4 - javacard (JCOP)
if (SimulateIso14443aInit(11, flags, data, &responses, &cuid, NULL, NULL, NULL) == false) {
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
DbpString(_YELLOW_("!!") "Error initializing the emulation process!"); DbpString(_RED_("Error initializing the emulation process!"));
SpinDelay(500); SpinDelay(500);
state = STATE_READ; state = STATE_READ;
DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]")); DbpString("Initialized [ "_YELLOW_("reading mode") " ]");
DbpString("\n" _YELLOW_("!!") "Waiting for a Visa card..."); DbpString("Waiting for a VISA card...");
continue; continue;
} }
@ -366,11 +370,12 @@ void RunMod(void) {
for (;;) { for (;;) {
LED_B_OFF(); LED_B_OFF();
// clean receive command buffer // clean receive command buffer
if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) { if (GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len) == false) {
DbpString(_YELLOW_("!!") "Emulator stopped"); DbpString("Emulator stopped");
retval = PM3_EOPABORTED; retval = PM3_EOPABORTED;
break; break;
} }
tag_response_info_t *p_response = NULL; tag_response_info_t *p_response = NULL;
LED_B_ON(); LED_B_ON();
@ -387,41 +392,33 @@ void RunMod(void) {
// received a HALT // received a HALT
} else if (receivedCmd[0] == ISO14443A_CMD_HALT && len == 4) { } else if (receivedCmd[0] == ISO14443A_CMD_HALT && len == 4) {
//DbpString(_YELLOW_("+") "Received a HALT");
p_response = NULL; p_response = NULL;
// received a WAKEUP // received a WAKEUP
} else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) { } else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) {
//DbpString(_YELLOW_("+") "WAKEUP Received");
prevCmd = 0; prevCmd = 0;
p_response = &responses[RESP_INDEX_ATQA]; p_response = &responses[RESP_INDEX_ATQA];
// received request for UID (cascade 1) // received request for UID (cascade 1)
} else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 2) { } else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 2) {
//DbpString(_YELLOW_("+") "Request for UID C1");
p_response = &responses[RESP_INDEX_UIDC1]; p_response = &responses[RESP_INDEX_UIDC1];
// received a SELECT (cascade 1) // received a SELECT (cascade 1)
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 9) { } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT && len == 9) {
//DbpString(_YELLOW_("+") "Request for SELECT S1");
p_response = &responses[RESP_INDEX_SAKC1]; p_response = &responses[RESP_INDEX_SAKC1];
// received a RATS request // received a RATS request
} else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { } else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) {
DbpString(_YELLOW_("+") "Request for RATS");
prevCmd = 0; prevCmd = 0;
//p_response = &responses[RESP_INDEX_RATS]; p_response = &responses[RESP_INDEX_RATS];
static uint8_t rRATS[] = { 0x13, 0x78, 0x80, 0x72, 0x02, 0x80, 0x31, 0x80, 0x66, 0xb1, 0x84, 0x0c, 0x01, 0x6e, 0x01, 0x83, 0x00, 0x90, 0x00 };
memcpy(&dynamic_response_info.response[0], rRATS, sizeof(rRATS));
dynamic_response_info.response_n = sizeof(rRATS);
} else { } else {
DbpString(_YELLOW_("[ ") "Card reader command" _YELLOW_(" ]")); if (g_dbglevel == DBG_DEBUG ) {
DbpString("[ "_YELLOW_("Card reader command") " ]");
Dbhexdump(len, receivedCmd, false); Dbhexdump(len, receivedCmd, false);
}
// emulate a Visa MSD(Magnetic stripe data) card // emulate a Visa MSD (Magnetic stripe data) card
if (receivedCmd[0] == 0x02 || receivedCmd[0] == 0x03) { if (receivedCmd[0] == 0x02 || receivedCmd[0] == 0x03) {
dynamic_response_info.response[0] = receivedCmd[0]; dynamic_response_info.response[0] = receivedCmd[0];
@ -480,7 +477,7 @@ void RunMod(void) {
} }
} }
} else { } else {
DbpString(_YELLOW_("!!") "Received unknown command!"); DbpString(_RED_("Received unknown command!"));
if (prevCmd < 4) { if (prevCmd < 4) {
memcpy(dynamic_response_info.response, receivedCmd, len); memcpy(dynamic_response_info.response, receivedCmd, len);
dynamic_response_info.response_n = len; dynamic_response_info.response_n = len;
@ -491,7 +488,7 @@ void RunMod(void) {
} }
if (dynamic_response_info.response_n > 0) { if (dynamic_response_info.response_n > 0) {
DbpString(_GREEN_("[ ") "Proxmark3 answer" _GREEN_(" ]")); DbpString("[ " _GREEN_("Proxmark3 answer") " ]");
Dbhexdump(dynamic_response_info.response_n, dynamic_response_info.response, false); Dbhexdump(dynamic_response_info.response_n, dynamic_response_info.response, false);
DbpString("----"); DbpString("----");
@ -501,7 +498,7 @@ void RunMod(void) {
if (prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE) == false) { if (prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE) == false) {
SpinDelay(500); SpinDelay(500);
DbpString(_YELLOW_("!!") "Error preparing Proxmark to answer!"); DbpString(_RED_("Error preparing Proxmark to answer!"));
continue; continue;
} }
p_response = &dynamic_response_info; p_response = &dynamic_response_info;
@ -518,6 +515,8 @@ void RunMod(void) {
reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0); reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0);
} }
} }
DbpString(_YELLOW_("[=]") "exiting"); DbpString("Exit standalone mode!");
DbpString("");
SpinErr(15, 200, 3);
LEDsoff(); LEDsoff();
} }

View file

@ -1021,7 +1021,8 @@ bool prepare_allocated_tag_modulation(tag_response_info_t *response_info, uint8_
} }
} }
bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_response_info_t **responses, uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages) { bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_response_info_t **responses,
uint32_t *cuid, uint32_t counters[3], uint8_t tearings[3], uint8_t *pages) {
uint8_t sak = 0; uint8_t sak = 0;
// The first response contains the ATQA (note: bytes are transmitted in reverse order). // The first response contains the ATQA (note: bytes are transmitted in reverse order).
static uint8_t rATQA[2] = { 0x00 }; static uint8_t rATQA[2] = { 0x00 };
@ -1038,8 +1039,13 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r
// Prepare the optional third SAK (for 10 byte UID), drop the cascade bit // Prepare the optional third SAK (for 10 byte UID), drop the cascade bit
static uint8_t rSAKc3[3] = { 0x00 }; static uint8_t rSAKc3[3] = { 0x00 };
// dummy ATS (pseudo-ATR), answer to RATS // dummy ATS (pseudo-ATR), answer to RATS
// Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present,
// TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1
// TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us)
// TC(1) = 0x02: CID supported, NAD not supported
// 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, 0x00 }; static uint8_t rRATS[40] = { 0x05, 0x75, 0x80, 0x60, 0x02, 0x00, 0x00, 0x00 };
uint8_t rRATS_len = 8;
// GET_VERSION response for EV1/NTAG // GET_VERSION response for EV1/NTAG
static uint8_t rVERSION[10] = { 0x00 }; static uint8_t rVERSION[10] = { 0x00 };
@ -1092,6 +1098,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r
rATQA[1] = 0x03; rATQA[1] = 0x03;
sak = 0x20; sak = 0x20;
memcpy(rRATS, "\x06\x75\x77\x81\x02\x80\x00\x00", 8); memcpy(rRATS, "\x06\x75\x77\x81\x02\x80\x00\x00", 8);
rRATS_len = 8;
break; break;
} }
case 4: { // ISO/IEC 14443-4 - javacard (JCOP) case 4: { // ISO/IEC 14443-4 - javacard (JCOP)
@ -1158,7 +1165,10 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r
sak = 0x20; sak = 0x20;
break; break;
} }
case 11: { // ISO/IEC 14443-4 - javacard (JCOP) case 11: { // ISO/IEC 14443-4 - javacard (JCOP) / EMV
memcpy(rRATS, "\x13\x78\x80\x72\x02\x80\x31\x80\x66\xb1\x84\x0c\x01\x6e\x01\x83\x00\x90\x00", 19);
rRATS_len = 19;
rATQA[0] = 0x04; rATQA[0] = 0x04;
sak = 0x20; sak = 0x20;
break; break;
@ -1266,11 +1276,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r
return false; return false;
} }
// Format byte = 0x58: FSCI=0x08 (FSC=256), TA(1) and TC(1) present, AddCrc14A(rRATS, rRATS_len - 2);
// TA(1) = 0x80: different divisors not supported, DR = 1, DS = 1
// TB(1) = not present. Defaults: FWI = 4 (FWT = 256 * 16 * 2^4 * 1/fc = 4833us), SFGI = 0 (SFG = 256 * 16 * 2^0 * 1/fc = 302us)
// TC(1) = 0x02: CID supported, NAD not supported
AddCrc14A(rRATS, sizeof(rRATS) - 2);
AddCrc14A(rPPS, sizeof(rPPS) - 2); AddCrc14A(rPPS, sizeof(rPPS) - 2);
@ -1305,14 +1311,23 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r
{ .response = rPACK, .response_n = sizeof(rPACK) } // PACK response { .response = rPACK, .response_n = sizeof(rPACK) } // PACK response
}; };
// "precompile" responses. There are 12 predefined responses with a total of 84 bytes data to transmit. // since rats len is variable now.
responses_init[RESP_INDEX_RATS].response_n = rRATS_len;
// "precompiled" responses.
// These exist for speed reasons. There are no time in the anti collision phase to calculate responses.
// There are 12 predefined responses with a total of 84 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)
// 85 * 8 data bits, 85 * 1 parity bits, 12 start bits, 12 stop bits, 12 correction bits // 85 * 8 data bits, 85 * 1 parity bits, 12 start bits, 12 stop bits, 12 correction bits
// 85 * 8 + 85 + 12 + 12 + 12 == 801 // 85 * 8 + 85 + 12 + 12 + 12 == 801
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 801 // CHG:
// 85 bytes normally (rats = 8 bytes)
// 77 bytes + ratslen,
uint8_t *free_buffer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE); #define ALLOCATED_TAG_MODULATION_BUFFER_SIZE ( ((77 + rRATS_len) * 8) + 77 + rRATS_len + 12 + 12 + 12)
uint8_t *free_buffer = BigBuf_calloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE);
// modulation buffer pointer and current buffer free space size // modulation buffer pointer and current buffer free space size
uint8_t *free_buffer_pointer = free_buffer; 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;
@ -1328,7 +1343,6 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r
} }
*responses = responses_init; *responses = responses_init;
return true; return true;
} }
@ -1362,12 +1376,16 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_
uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 }; uint8_t receivedCmd[MAX_FRAME_SIZE] = { 0x00 };
uint8_t receivedCmdPar[MAX_PARITY_SIZE] = { 0x00 }; uint8_t receivedCmdPar[MAX_PARITY_SIZE] = { 0x00 };
// free eventually allocated BigBuf memory but keep Emulator Memory
BigBuf_free_keep_EM();
// 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
#define DYNAMIC_RESPONSE_BUFFER_SIZE 64 #define DYNAMIC_RESPONSE_BUFFER_SIZE 64
#define DYNAMIC_MODULATION_BUFFER_SIZE 512 #define DYNAMIC_MODULATION_BUFFER_SIZE 512
uint8_t dynamic_response_buffer[DYNAMIC_RESPONSE_BUFFER_SIZE] = {0};
uint8_t dynamic_modulation_buffer[DYNAMIC_MODULATION_BUFFER_SIZE] = {0}; uint8_t *dynamic_response_buffer = BigBuf_calloc(DYNAMIC_RESPONSE_BUFFER_SIZE);
uint8_t *dynamic_modulation_buffer = BigBuf_calloc(DYNAMIC_MODULATION_BUFFER_SIZE);
tag_response_info_t dynamic_response_info = { tag_response_info_t dynamic_response_info = {
.response = dynamic_response_buffer, .response = dynamic_response_buffer,
.response_n = 0, .response_n = 0,
@ -1375,9 +1393,6 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_
.modulation_n = 0 .modulation_n = 0
}; };
// free eventually allocated BigBuf memory but keep Emulator Memory
BigBuf_free_keep_EM();
if (SimulateIso14443aInit(tagType, flags, data, &responses, &cuid, counters, tearings, &pages) == false) { if (SimulateIso14443aInit(tagType, flags, data, &responses, &cuid, counters, tearings, &pages) == false) {
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);