From 60ff2351ba48d6ce0fb4f3a9aa4e926e9e560c03 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 9 Oct 2023 12:47:00 +0200 Subject: [PATCH] text --- armsrc/Standalone/hf_msdsal.c | 121 +++++++++++++++++----------------- armsrc/iso14443a.c | 49 +++++++++----- 2 files changed, 92 insertions(+), 78 deletions(-) diff --git a/armsrc/Standalone/hf_msdsal.c b/armsrc/Standalone/hf_msdsal.c index f97a2e57f..4ce074cf9 100644 --- a/armsrc/Standalone/hf_msdsal.c +++ b/armsrc/Standalone/hf_msdsal.c @@ -30,7 +30,7 @@ #include "cmd.h" 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. @@ -132,9 +132,15 @@ static uint8_t treatPDOL(const uint8_t *apdu) { void RunMod(void) { 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); + // 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 iso14a_card_select_t card_a_info; @@ -161,7 +167,6 @@ void RunMod(void) { bool existpdol; - // - MSD token card format - // //Card number: 4412 3456 0578 1234 @@ -175,34 +180,31 @@ void RunMod(void) { char token[19] = {0x00}; 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) uint8_t flags = FLAG_4B_UID_IN_DATA; // in case there is a read command received we shouldn't break 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); // to initialize the emulation - uint8_t tagType = 11; // 11 = ISO/IEC 14443-4 - javacard (JCOP) tag_response_info_t *responses; + uint32_t cuid = 0; - uint32_t counters[3] = { 0x00, 0x00, 0x00 }; - uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd }; - uint8_t pages = 0; // command buffers uint8_t receivedCmd[MAX_FRAME_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 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 if (chktoken == true && token[0] != 0x00) { state = STATE_EMU; - DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]")); - DbpString("\n"_YELLOW_("!!") "Waiting for a card reader..."); + DbpString("Initialized [ " _BLUE_("emulation mode") " ]"); + DbpString("Waiting for a card reader..."); } else { - DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]")); - DbpString("\n"_YELLOW_("!!") "Waiting for a Visa card..."); + DbpString("Initialized [ " _YELLOW_("reading mode") " ]"); + DbpString("Waiting for a VISA card..."); } for (;;) { @@ -240,20 +242,20 @@ void RunMod(void) { int button_pressed = BUTTON_HELD(1000); - if (button_pressed == BUTTON_HOLD) + if (button_pressed == BUTTON_HOLD) { break; - else if (button_pressed == BUTTON_SINGLE_CLICK) { + } else if (button_pressed == BUTTON_SINGLE_CLICK) { // pressing one time change between reading & emulation if (state == STATE_READ) { if (chktoken == true && token[0] != 0x00) { // only change to emulation if it saved a track 2 in memory state = STATE_EMU; - DbpString(_YELLOW_("[ ") "In emulation mode" _YELLOW_(" ]")); + DbpString("[ " _BLUE_("Emulation mode") " ]"); } else - DbpString(_YELLOW_("!!") "Nothing in memory to emulate"); + DbpString(_YELLOW_("Nothing in memory to emulate")); } else { state = STATE_READ; - DbpString(_YELLOW_("[ ") "In reading mode" _YELLOW_(" ]")); + DbpString("[ " _YELLOW_("Reading mode") " ]"); } } @@ -261,15 +263,14 @@ void RunMod(void) { if (state == STATE_READ) { LED_A_ON(); - if (chktoken) + if (chktoken) { LED_C_ON(); + } iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); 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++) { chktoken = false; LED_C_OFF(); @@ -277,11 +278,11 @@ void RunMod(void) { uint8_t apdulen = iso14_apdu(apdus[i], (uint16_t) apduslen[i], false, apdubuffer, NULL); if (apdulen > 0) { - DbpString(_YELLOW_("[ ") "Proxmark command" _YELLOW_(" ]")); + DbpString("[ " _YELLOW_("Proxmark command") " ]"); Dbhexdump(apduslen[i], apdus[i], false); - DbpString(_GREEN_("[ ") "Card answer" _GREEN_(" ]")); + DbpString("[ " _GREEN_( "Card answer") " ]"); Dbhexdump(apdulen - 2, apdubuffer, false); - DbpString("----"); + DbpString("-------------------------------"); for (uint8_t u = 0; u < apdulen; u++) { if (i == 1) { @@ -309,25 +310,27 @@ void RunMod(void) { } if (i == 1) { - DbpString(_GREEN_("[ ") "Challenge generated" _GREEN_(" ]")); + DbpString("[ "_GREEN_("Challenge generated") " ]"); Dbhexdump(plen, existpdol ? ppdol : processing, false); } } else { - DbpString(_YELLOW_("!!") "Error reading the card"); + DbpString(_RED_("Error reading the card")); } LED_B_OFF(); } if (chktoken) { - DbpString(_RED_("[ ") "Track 2" _RED_(" ]")); + DbpString("[ " _GREEN_("Track 2") " ]"); Dbhexdump(19, (uint8_t *)token, false); - DbpString(_YELLOW_("!!") "Card number"); + DbpString("[ " _GREEN_("Card Number") " ]"); Dbhexdump(8, (uint8_t *)token, false); - DbpString("---"); + DbpString("-------------------------------"); + DbpString(""); + DbpString(""); LED_C_ON(); state = STATE_EMU; - DbpString(_YELLOW_("[ ") "Initialized emulation mode" _YELLOW_(" ]")); - DbpString("\n"_YELLOW_("!!") "Waiting for a card reader..."); + DbpString("Initialized [ " _BLUE_("emulation mode") " ]"); + DbpString("Waiting for a card reader..."); } } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -340,14 +343,15 @@ void RunMod(void) { // free eventually allocated BigBuf memory but keep Emulator Memory 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(); 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); state = STATE_READ; - DbpString(_YELLOW_("[ ") "Initialized reading mode" _YELLOW_(" ]")); - DbpString("\n" _YELLOW_("!!") "Waiting for a Visa card..."); + DbpString("Initialized [ "_YELLOW_("reading mode") " ]"); + DbpString("Waiting for a VISA card..."); continue; } @@ -366,11 +370,12 @@ void RunMod(void) { for (;;) { LED_B_OFF(); // clean receive command buffer - if (!GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len)) { - DbpString(_YELLOW_("!!") "Emulator stopped"); + if (GetIso14443aCommandFromReader(receivedCmd, receivedCmdPar, &len) == false) { + DbpString("Emulator stopped"); retval = PM3_EOPABORTED; break; } + tag_response_info_t *p_response = NULL; LED_B_ON(); @@ -387,41 +392,33 @@ void RunMod(void) { // received a HALT } else if (receivedCmd[0] == ISO14443A_CMD_HALT && len == 4) { - //DbpString(_YELLOW_("+") "Received a HALT"); p_response = NULL; // received a WAKEUP } else if (receivedCmd[0] == ISO14443A_CMD_WUPA && len == 1) { - //DbpString(_YELLOW_("+") "WAKEUP Received"); prevCmd = 0; p_response = &responses[RESP_INDEX_ATQA]; // received request for UID (cascade 1) } 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]; // received a SELECT (cascade 1) } 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]; // received a RATS request } else if (receivedCmd[0] == ISO14443A_CMD_RATS && len == 4) { - DbpString(_YELLOW_("+") "Request for RATS"); prevCmd = 0; - //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); + p_response = &responses[RESP_INDEX_RATS]; } else { - DbpString(_YELLOW_("[ ") "Card reader command" _YELLOW_(" ]")); - Dbhexdump(len, receivedCmd, false); + if (g_dbglevel == DBG_DEBUG ) { + DbpString("[ "_YELLOW_("Card reader command") " ]"); + 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) { dynamic_response_info.response[0] = receivedCmd[0]; @@ -480,7 +477,7 @@ void RunMod(void) { } } } else { - DbpString(_YELLOW_("!!") "Received unknown command!"); + DbpString(_RED_("Received unknown command!")); if (prevCmd < 4) { memcpy(dynamic_response_info.response, receivedCmd, len); dynamic_response_info.response_n = len; @@ -491,7 +488,7 @@ void RunMod(void) { } 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); DbpString("----"); @@ -501,7 +498,7 @@ void RunMod(void) { if (prepare_tag_modulation(&dynamic_response_info, DYNAMIC_MODULATION_BUFFER_SIZE) == false) { SpinDelay(500); - DbpString(_YELLOW_("!!") "Error preparing Proxmark to answer!"); + DbpString(_RED_("Error preparing Proxmark to answer!")); continue; } p_response = &dynamic_response_info; @@ -518,6 +515,8 @@ void RunMod(void) { reply_ng(CMD_HF_MIFARE_SIMULATE, retval, NULL, 0); } } - DbpString(_YELLOW_("[=]") "exiting"); + DbpString("Exit standalone mode!"); + DbpString(""); + SpinErr(15, 200, 3); LEDsoff(); } diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 346669398..d1b63264e 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -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; // The first response contains the ATQA (note: bytes are transmitted in reverse order). 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 static uint8_t rSAKc3[3] = { 0x00 }; // 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[] = { 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 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; sak = 0x20; memcpy(rRATS, "\x06\x75\x77\x81\x02\x80\x00\x00", 8); + rRATS_len = 8; break; } 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; 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; sak = 0x20; break; @@ -1266,11 +1276,7 @@ bool SimulateIso14443aInit(uint8_t tagType, uint16_t flags, uint8_t *data, tag_r return false; } - // 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 - AddCrc14A(rRATS, sizeof(rRATS) - 2); + AddCrc14A(rRATS, rRATS_len - 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 }; - // "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) // 85 * 8 data bits, 85 * 1 parity bits, 12 start bits, 12 stop bits, 12 correction bits // 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 uint8_t *free_buffer_pointer = free_buffer; 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; - 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 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 // 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[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 = { .response = dynamic_response_buffer, .response_n = 0, @@ -1375,9 +1393,6 @@ void SimulateIso14443aTag(uint8_t tagType, uint16_t flags, uint8_t *data, uint8_ .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) { BigBuf_free_keep_EM(); reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);