From f71f4deb8f8f1e932c81f3e62e6ab67012e07b33 Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Tue, 27 Jan 2015 08:34:48 +0100 Subject: [PATCH 1/1] BigBuf and tracing rework: allow much longer traces in in hf commands - provided a BigBuf_malloc() function to dynamically allocate parts of BigBuf e.g. for DMA-Buffers, Frame-Buffers, Emulator-Memory - the whole rest of BigBuf is now available for traces (instead of a small fixed amount) - send actual traceLen together with trace data - changed client side to cope with varying traceLen - changed small buffers to automatic variables instead of parts of BigBuf --- armsrc/BigBuf.c | 59 +++++++++---- armsrc/BigBuf.h | 22 ++--- armsrc/appmain.c | 11 ++- armsrc/hitag2.c | 110 ++++++++++++------------ armsrc/iclass.c | 41 +++++---- armsrc/iso14443.c | 21 ++--- armsrc/iso14443a.c | 114 ++++++++++++++----------- armsrc/lfops.c | 24 +++--- armsrc/mifarecmd.c | 18 ++-- armsrc/mifaresniff.c | 2 +- armsrc/mifareutil.c | 75 +++++++--------- armsrc/mifareutil.h | 6 -- client/cmddata.c | 18 ++-- client/cmddata.h | 2 + client/cmdhf.c | 50 +++++++---- client/cmdhf14b.c | 29 +++++-- client/cmdhfmf.c | 59 ++++++++----- client/cmdlfhitag.c | 197 +++++++++++++++++++++++-------------------- client/cmdmain.c | 1 - client/data.c | 2 - client/data.h | 4 - include/hitag2.h | 6 +- 22 files changed, 478 insertions(+), 393 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 987fee7d..7f56e9a0 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -14,22 +14,38 @@ #include "apps.h" #include "string.h" -// The large multi-purpose buffer, typically used to hold A/D samples or traces, -// may be processed in some way. Also used to hold various smaller buffers. -static uint8_t BigBuf[BIGBUF_SIZE]; +// BigBuf is the large multi-purpose buffer, typically used to hold A/D samples or traces. +// Also used to hold various smaller buffers and the Mifare Emulator Memory. + +// declare it as uint32_t to achieve alignment to 4 Byte boundary +static uint32_t BigBuf[BIGBUF_SIZE/sizeof(uint32_t)]; // High memory mark static uint16_t BigBuf_hi = BIGBUF_SIZE; -// trace related global variables. Change to function calls? -//uint8_t *trace = BigBuf; -uint16_t traceLen; +// pointer to the emulator memory. +static uint8_t *emulator_memory = NULL; + +// trace related global variables +// (only one left). ToDo: make this static as well? +uint16_t traceLen = 0; // get the address of BigBuf uint8_t *BigBuf_get_addr(void) { - return BigBuf; + return (uint8_t *)BigBuf; +} + + +// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done +uint8_t *BigBuf_get_EM_addr(void) +{ + if (emulator_memory == NULL) { // not yet allocated + emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE); + } + + return emulator_memory; } @@ -41,28 +57,41 @@ void BigBuf_Clear(void) } -// allocate a chunk of memory from BigBuf. We allocate high memory first. Low memory -// is always for traces/samples +// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory +// at the beginning of BigBuf is always for traces/samples uint8_t *BigBuf_malloc(uint16_t chunksize) { if (BigBuf_hi - chunksize < 0) { - return NULL; // no memory left + return NULL; // no memory left } else { - BigBuf_hi -= chunksize; // aligned to 4 Byte boundary - return BigBuf + BigBuf_hi; + chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4 + BigBuf_hi -= chunksize; // aligned to 4 Byte boundary + return (uint8_t *)BigBuf + BigBuf_hi; } } -// free ALL allocated chunks. The whole BigBuf is available for traces again. +// free ALL allocated chunks. The whole BigBuf is available for traces or samples again. void BigBuf_free(void) { BigBuf_hi = BIGBUF_SIZE; + emulator_memory = NULL; +} + + +// free allocated chunks EXCEPT the emulator memory +void BigBuf_free_keep_EM(void) +{ + if (emulator_memory != NULL) { + BigBuf_hi = emulator_memory - (uint8_t *)BigBuf; + } else { + BigBuf_hi = BIGBUF_SIZE; + } } // return the maximum trace length (i.e. the unallocated size of BigBuf) -uint16_t BigBuf_max_trace_len(void) +uint16_t BigBuf_max_traceLen(void) { return BigBuf_hi; -} \ No newline at end of file +} diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index 07535277..9d89a4f0 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -14,26 +14,20 @@ #define BIGBUF_SIZE 40000 -#define TRACE_OFFSET 0 -#define TRACE_SIZE 3000 -#define RECV_CMD_OFFSET (TRACE_OFFSET + TRACE_SIZE) -#define MAX_FRAME_SIZE 256 -#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 1)/ 8) -#define RECV_CMD_PAR_OFFSET (RECV_CMD_OFFSET + MAX_FRAME_SIZE) -#define RECV_RESP_OFFSET (RECV_CMD_PAR_OFFSET + MAX_PARITY_SIZE) -#define RECV_RESP_PAR_OFFSET (RECV_RESP_OFFSET + MAX_FRAME_SIZE) -#define CARD_MEMORY_OFFSET (RECV_RESP_PAR_OFFSET + MAX_PARITY_SIZE) +#define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame +#define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8) +#define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC +#define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these #define CARD_MEMORY_SIZE 4096 -#define DMA_BUFFER_OFFSET CARD_MEMORY_OFFSET -#define DMA_BUFFER_SIZE CARD_MEMORY_SIZE -#define FREE_BUFFER_OFFSET (CARD_MEMORY_OFFSET + CARD_MEMORY_SIZE) -#define FREE_BUFFER_SIZE (BIGBUF_SIZE - FREE_BUFFER_OFFSET - 1) +#define DMA_BUFFER_SIZE 128 extern uint8_t *BigBuf_get_addr(void); -extern uint16_t BigBuf_max_trace_len(void); +extern uint8_t *BigBuf_get_EM_addr(void); +extern uint16_t BigBuf_max_traceLen(void); void BigBuf_Clear(void); extern uint8_t *BigBuf_malloc(uint16_t); extern void BigBuf_free(void); +extern void BigBuf_free_keep_EM(void); extern uint16_t traceLen; diff --git a/armsrc/appmain.c b/armsrc/appmain.c index a4d9c335..791ad4f8 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -240,7 +240,10 @@ void MeasureAntennaTuningHf(void) void SimulateTagHfListen(void) { - uint8_t *dest = BigBuf_get_addr() + FREE_BUFFER_OFFSET; + // ToDo: historically this used the free buffer, which was 2744 Bytes long. + // There might be a better size to be defined: + #define HF_14B_SNOOP_BUFFER_SIZE 2744 + uint8_t *dest = BigBuf_malloc(HF_14B_SNOOP_BUFFER_SIZE); uint8_t v = 0; int i; int p = 0; @@ -275,7 +278,7 @@ void SimulateTagHfListen(void) p = 0; i++; - if(i >= FREE_BUFFER_SIZE) { + if(i >= HF_14B_SNOOP_BUFFER_SIZE) { break; } } @@ -912,10 +915,10 @@ void UsbPacketReceived(uint8_t *packet, int len) uint8_t *BigBuf = BigBuf_get_addr(); for(size_t i=0; iarg[1]; i += USB_CMD_DATA_SIZE) { size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE); - cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,0,BigBuf+c->arg[0]+i,len); + cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,traceLen,BigBuf+c->arg[0]+i,len); } // Trigger a finish downloading signal with an ACK frame - cmd_send(CMD_ACK,0,0,0,0,0); + cmd_send(CMD_ACK,0,0,traceLen,0,0); LED_B_OFF(); break; diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 68916748..4a2d9d9d 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -24,19 +24,19 @@ static bool bQuiet; -bool bCrypto; -bool bAuthenticating; -bool bPwd; -bool bSuccessful; +static bool bCrypto; +static bool bAuthenticating; +static bool bPwd; +static bool bSuccessful; -int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader) +static int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader) { static uint16_t traceLen = 0; uint8_t *trace = BigBuf_get_addr(); // Return when trace is full - if (traceLen >= TRACE_SIZE) return FALSE; + if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + nbytes(iBits) > BigBuf_max_traceLen()) return FALSE; // Trace the random, i'm curious rsamples += iSamples; @@ -89,20 +89,17 @@ static struct hitag2_tag tag = { }, }; -//#define TRACE_LENGTH 3000 -//uint8_t *trace = (uint8_t *) BigBuf; -//int traceLen = 0; -//int rsamples = 0; +// ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces. +// Historically it used to be FREE_BUFFER_SIZE, which was 2744. +#define AUTH_TABLE_LENGTH 2744 +static byte_t* auth_table; +static size_t auth_table_pos = 0; +static size_t auth_table_len = AUTH_TABLE_LENGTH; -#define AUTH_TABLE_OFFSET FREE_BUFFER_OFFSET -#define AUTH_TABLE_LENGTH FREE_BUFFER_SIZE -size_t auth_table_pos = 0; -size_t auth_table_len = AUTH_TABLE_LENGTH; - -byte_t password[4]; -byte_t NrAr[8]; -byte_t key[8]; -uint64_t cipher_state; +static byte_t password[4]; +static byte_t NrAr[8]; +static byte_t key[8]; +static uint64_t cipher_state; /* Following is a modified version of cryptolib.com/ciphers/hitag2/ */ // Software optimized 48-bit Philips/NXP Mifare Hitag2 PCF7936/46/47/52 stream cipher algorithm by I.C. Wiener 2006-2007. @@ -180,14 +177,14 @@ static u32 _hitag2_byte (u64 * x) return c; } -int hitag2_reset(void) +static int hitag2_reset(void) { tag.state = TAG_STATE_RESET; tag.crypto_active = 0; return 0; } -int hitag2_init(void) +static int hitag2_init(void) { // memcpy(&tag, &resetdata, sizeof(tag)); hitag2_reset(); @@ -303,10 +300,9 @@ static void hitag_send_frame(const byte_t* frame, size_t frame_len) LOW(GPIO_SSC_DOUT); } -void hitag2_handle_reader_command(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) + +static void hitag2_handle_reader_command(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) { - byte_t* auth_table; - auth_table = (byte_t *)BigBuf_get_addr() + AUTH_TABLE_OFFSET; byte_t rx_air[HITAG_FRAME_LEN]; // Copy the (original) received frame how it is send over the air @@ -462,6 +458,7 @@ static void hitag_reader_send_bit(int bit) { LED_A_OFF(); } + static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len) { // Send the content of the frame @@ -480,7 +477,7 @@ static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len) size_t blocknr; -bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) { +static bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) { // Reset the transmission frame length *txlen = 0; @@ -535,7 +532,7 @@ bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) return true; } -bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) { +static bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) { // Reset the transmission frame length *txlen = 0; @@ -628,7 +625,7 @@ bool hitag2_crypto(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) { } -bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) { +static bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) { // Reset the transmission frame length *txlen = 0; @@ -668,10 +665,8 @@ bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txl return true; } -bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) { - byte_t* auth_table; - auth_table = (byte_t *)BigBuf_get_addr() + AUTH_TABLE_OFFSET; +static bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) { // Reset the transmission frame length *txlen = 0; @@ -684,17 +679,17 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_ if (bCrypto) { Dbprintf("auth: %02x%02x%02x%02x%02x%02x%02x%02x Failed, removed entry!",NrAr[0],NrAr[1],NrAr[2],NrAr[3],NrAr[4],NrAr[5],NrAr[6],NrAr[7]); - // Removing failed entry from authentiations table - memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8); - auth_table_len -= 8; + // Removing failed entry from authentiations table + memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8); + auth_table_len -= 8; - // Return if we reached the end of the authentiactions table + // Return if we reached the end of the authentications table bCrypto = false; if (auth_table_pos == auth_table_len) { return false; } - - // Copy the next authentication attempt in row (at the same position, b/c we removed last failed entry) + + // Copy the next authentication attempt in row (at the same position, b/c we removed last failed entry) memcpy(NrAr,auth_table+auth_table_pos,8); } *txlen = 5; @@ -727,6 +722,7 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_ return true; } + void SnoopHitag(uint32_t type) { int frame_count; int response; @@ -739,15 +735,15 @@ void SnoopHitag(uint32_t type) { byte_t rx[HITAG_FRAME_LEN]; size_t rxlen=0; - // Clean up trace and prepare it for storing frames - iso14a_set_tracing(TRUE); - iso14a_clear_trace(); - auth_table_len = 0; auth_table_pos = 0; - byte_t* auth_table; - auth_table = (byte_t *)BigBuf_get_addr() + AUTH_TABLE_OFFSET; + BigBuf_free(); + auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH); memset(auth_table, 0x00, AUTH_TABLE_LENGTH); + + // Clean up trace and prepare it for storing frames + iso14a_set_tracing(TRUE); + iso14a_clear_trace(); DbpString("Starting Hitag2 snoop"); LED_D_ON(); @@ -771,7 +767,7 @@ void SnoopHitag(uint32_t type) { AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; - // Disable timer during configuration + // Disable timer during configuration AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; // Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, @@ -951,15 +947,17 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) { bool bQuitTraceFull = false; bQuiet = false; - // Clean up trace and prepare it for storing frames - iso14a_set_tracing(TRUE); - iso14a_clear_trace(); auth_table_len = 0; auth_table_pos = 0; byte_t* auth_table; - auth_table = (byte_t *)BigBuf_get_addr() + AUTH_TABLE_OFFSET; + BigBuf_free(); + auth_table = (byte_t *)BigBuf_malloc(AUTH_TABLE_LENGTH); memset(auth_table, 0x00, AUTH_TABLE_LENGTH); + // Clean up trace and prepare it for storing frames + iso14a_set_tracing(TRUE); + iso14a_clear_trace(); + DbpString("Starting Hitag2 simulation"); LED_D_ON(); hitag2_init(); @@ -1139,22 +1137,20 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { bool bStop; bool bQuitTraceFull = false; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - // Reset the return status - bSuccessful = false; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + // Reset the return status + bSuccessful = false; // Clean up trace and prepare it for storing frames iso14a_set_tracing(TRUE); iso14a_clear_trace(); - byte_t* auth_table; - auth_table = (byte_t *)BigBuf_get_addr() + AUTH_TABLE_OFFSET; DbpString("Starting Hitag reader family"); // Check configuration switch(htf) { case RHT2F_PASSWORD: { - Dbprintf("List identifier in password mode"); + Dbprintf("List identifier in password mode"); memcpy(password,htd->pwd.password,4); blocknr = 0; bQuitTraceFull = false; @@ -1168,7 +1164,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { Dbhexdump(8,NrAr,false); bQuiet = false; bCrypto = false; - bAuthenticating = false; + bAuthenticating = false; bQuitTraceFull = true; } break; @@ -1176,17 +1172,17 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { DbpString("Authenticating using key:"); memcpy(key,htd->crypto.key,4); //HACK; 4 or 6?? I read both in the code. Dbhexdump(6,key,false); - blocknr = 0; + blocknr = 0; bQuiet = false; bCrypto = false; - bAuthenticating = false; + bAuthenticating = false; bQuitTraceFull = true; } break; case RHT2F_TEST_AUTH_ATTEMPTS: { Dbprintf("Testing %d authentication attempts",(auth_table_len/8)); auth_table_pos = 0; - memcpy(NrAr,auth_table,8); + memcpy(NrAr, auth_table, 8); bQuitTraceFull = false; bQuiet = false; bCrypto = false; diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 334eb362..4436602c 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -640,20 +640,24 @@ void RAMFUNC SnoopIClass(void) // The command (reader -> tag) that we're receiving. // The length of a received command will in most cases be no more than 18 bytes. // So 32 should be enough! - uint8_t *readerToTagCmd = BigBuf_get_addr() + RECV_CMD_OFFSET; + #define ICLASS_BUFFER_SIZE 32 + uint8_t readerToTagCmd[ICLASS_BUFFER_SIZE]; // The response (tag -> reader) that we're receiving. - uint8_t *tagToReaderResponse = BigBuf_get_addr() + RECV_RESP_OFFSET; + uint8_t tagToReaderResponse[ICLASS_BUFFER_SIZE]; FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // reset traceLen to 0 + // free all BigBuf memory + BigBuf_free(); + // The DMA buffer, used to stream samples from the FPGA + uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); + + // reset traceLen to 0 iso14a_set_tracing(TRUE); iso14a_clear_trace(); iso14a_set_trigger(FALSE); - // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = BigBuf_get_addr() + DMA_BUFFER_OFFSET; - int lastRxCounter; + int lastRxCounter; uint8_t *upTo; int smpl; int maxBehindBy = 0; @@ -703,7 +707,7 @@ void RAMFUNC SnoopIClass(void) (DMA_BUFFER_SIZE-1); if(behindBy > maxBehindBy) { maxBehindBy = behindBy; - if(behindBy > 400) { + if(behindBy > (9 * DMA_BUFFER_SIZE / 10)) { Dbprintf("blew circular buffer! behindBy=0x%x", behindBy); goto done; } @@ -1064,27 +1068,28 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader int trace_data_size = 0; //uint8_t sof = 0x0f; + // free eventually allocated BigBuf memory + BigBuf_free(); // Respond SOF -- takes 1 bytes - uint8_t *resp1 = (BigBuf_get_addr() + FREE_BUFFER_OFFSET); + uint8_t *resp1 = BigBuf_malloc(2); int resp1Len; // Anticollision CSN (rotated CSN) // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte) - uint8_t *resp2 = (BigBuf_get_addr() + FREE_BUFFER_OFFSET + 2); + uint8_t *resp2 = BigBuf_malloc(28); int resp2Len; // CSN // 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte) - uint8_t *resp3 = (BigBuf_get_addr() + FREE_BUFFER_OFFSET + 30); + uint8_t *resp3 = BigBuf_malloc(30); int resp3Len; // e-Purse - // 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/byte) - uint8_t *resp4 = (BigBuf_get_addr() + FREE_BUFFER_OFFSET + 60); + // 144: Takes 16 bytes for SOF/EOF and 8 * 16 = 128 bytes (2 bytes/bit) + uint8_t *resp4 = BigBuf_malloc(150); int resp4Len; - // + 1720.. - uint8_t *receivedCmd = BigBuf_get_addr() + RECV_CMD_OFFSET; + uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); memset(receivedCmd, 0x44, MAX_FRAME_SIZE); int len; @@ -1529,7 +1534,7 @@ uint8_t handshakeIclassTag(uint8_t *card_data) static uint8_t identify[] = { 0x0c }; static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static uint8_t readcheck_cc[]= { 0x88, 0x02 }; - uint8_t *resp = BigBuf_get_addr() + RECV_RESP_OFFSET; + uint8_t resp[ICLASS_BUFFER_SIZE]; uint8_t read_status = 0; @@ -1587,7 +1592,7 @@ void ReaderIClass(uint8_t arg0) { while(!BUTTON_PRESS()) { - if(traceLen > TRACE_SIZE) { + if(traceLen > BigBuf_max_traceLen()) { DbpString("Trace full"); break; } @@ -1650,7 +1655,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { int keyaccess; } memory; - uint8_t* resp = BigBuf_get_addr() + RECV_RESP_OFFSET; + uint8_t resp[ICLASS_BUFFER_SIZE]; setupIclassReader(); @@ -1659,7 +1664,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { WDT_HIT(); - if(traceLen > TRACE_SIZE) { + if(traceLen > BigBuf_max_traceLen()) { DbpString("Trace full"); break; } diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index e94a8ec2..6a2e4d6a 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -1013,18 +1013,19 @@ void RAMFUNC SnoopIso14443(void) int triggered = TRUE; FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + BigBuf_free(); // The command (reader -> tag) that we're working on receiving. - uint8_t *receivedCmd = BigBuf_get_addr() + DEMOD_TRACE_SIZE; + uint8_t *receivedCmd = BigBuf_malloc(READER_TAG_BUFFER_SIZE); // The response (tag -> reader) that we're working on receiving. - uint8_t *receivedResponse = BigBuf_get_addr() + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE; + uint8_t *receivedResponse = BigBuf_malloc(TAG_READER_BUFFER_SIZE); // As we receive stuff, we copy it from receivedCmd or receivedResponse // into trace, along with its length and other annotations. uint8_t *trace = BigBuf_get_addr(); - int traceLen = 0; + traceLen = 0; // The DMA buffer, used to stream samples from the FPGA. - uint8_t *dmaBuf = BigBuf_get_addr() + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE + TAG_READER_BUFFER_SIZE; + uint8_t *dmaBuf = BigBuf_malloc(DEMOD_DMA_BUFFER_SIZE); int lastRxCounter; uint8_t *upTo; int ci, cq; @@ -1035,7 +1036,7 @@ void RAMFUNC SnoopIso14443(void) int samples = 0; // Initialize the trace buffer - memset(trace, 0x44, DEMOD_TRACE_SIZE); + memset(trace, 0x44, BigBuf_max_traceLen()); // Set up the demodulator for tag -> reader responses. Demod.output = receivedResponse; @@ -1050,7 +1051,7 @@ void RAMFUNC SnoopIso14443(void) // Print some debug information about the buffer sizes Dbprintf("Snooping buffers initialized:"); - Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE); + Dbprintf(" Trace: %i bytes", BigBuf_max_traceLen()); Dbprintf(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE); Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE); Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE); @@ -1077,7 +1078,7 @@ void RAMFUNC SnoopIso14443(void) (DEMOD_DMA_BUFFER_SIZE-1); if(behindBy > maxBehindBy) { maxBehindBy = behindBy; - if(behindBy > (DEMOD_DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not? + if(behindBy > (9*DEMOD_DMA_BUFFER_SIZE/10)) { // TODO: understand whether we can increase/decrease as we want or not? Dbprintf("blew circular buffer! behindBy=0x%x", behindBy); goto done; } @@ -1148,7 +1149,7 @@ void RAMFUNC SnoopIso14443(void) trace[traceLen++] = Demod.len; memcpy(trace+traceLen, receivedResponse, Demod.len); traceLen += Demod.len; - if(traceLen > DEMOD_TRACE_SIZE) { + if(traceLen > BigBuf_max_traceLen()) { DbpString("Reached trace limit"); goto done; } @@ -1174,9 +1175,9 @@ done: LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; + AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; DbpString("Snoop statistics:"); - Dbprintf(" Max behind by: %i", maxBehindBy); + Dbprintf(" Max behind by: %i", maxBehindBy); Dbprintf(" Uart State: %x", Uart.state); Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt); Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index f43c59a1..b1639a88 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -148,7 +148,8 @@ void iso14a_set_trigger(bool enable) { void iso14a_clear_trace() { uint8_t *trace = BigBuf_get_addr(); - memset(trace, 0x44, TRACE_SIZE); + uint16_t max_traceLen = BigBuf_max_traceLen(); + memset(trace, 0x44, max_traceLen); traceLen = 0; } @@ -208,7 +209,8 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ uint16_t duration = timestamp_end - timestamp_start; // Return when trace is full - if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= TRACE_SIZE) { + uint16_t max_traceLen = BigBuf_max_traceLen(); + if (traceLen + sizeof(iLen) + sizeof(timestamp_start) + sizeof(duration) + num_paritybytes + iLen >= max_traceLen) { tracing = FALSE; // don't trace any more return FALSE; } @@ -591,9 +593,6 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { // bit 1 - trigger from first reader 7-bit request LEDsoff(); - // init trace buffer - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); // We won't start recording the frames that we acquire until we trigger; // a good trigger condition to get started is probably when we see a @@ -601,22 +600,25 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { // triggered == FALSE -- to wait first for card bool triggered = !(param & 0x03); + // Allocate memory from BigBuf for some buffers + // free all previous allocations first + BigBuf_free(); + // The command (reader -> tag) that we're receiving. - // The length of a received command will in most cases be no more than 18 bytes. - // So 32 should be enough! - uint8_t *receivedCmd = BigBuf_get_addr() + RECV_CMD_OFFSET; - uint8_t *receivedCmdPar = BigBuf_get_addr() + RECV_CMD_PAR_OFFSET; + uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); // The response (tag -> reader) that we're receiving. - uint8_t *receivedResponse = BigBuf_get_addr() + RECV_RESP_OFFSET; - uint8_t *receivedResponsePar = BigBuf_get_addr() + RECV_RESP_PAR_OFFSET; - - // As we receive stuff, we copy it from receivedCmd or receivedResponse - // into trace, along with its length and other annotations. - //uint8_t *trace = (uint8_t *)BigBuf; + uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedResponsePar = BigBuf_malloc(MAX_PARITY_SIZE); // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = BigBuf_get_addr() + DMA_BUFFER_OFFSET; + uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); + + // init trace buffer + iso14a_clear_trace(); + iso14a_set_tracing(TRUE); + uint8_t *data = dmaBuf; uint8_t previous_data = 0; int maxDataLen = 0; @@ -656,7 +658,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { // test for length of buffer if(dataLen > maxDataLen) { maxDataLen = dataLen; - if(dataLen > 400) { + if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) { Dbprintf("blew circular buffer! dataLen=%d", dataLen); break; } @@ -895,10 +897,6 @@ typedef struct { uint32_t ProxToAirDuration; } tag_response_info_t; -void reset_free_buffer() { - free_buffer_pointer = BigBuf_get_addr() + FREE_BUFFER_OFFSET; -} - bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffer_size) { // Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes // This will need the following byte array for a modulation sequence @@ -910,7 +908,8 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe // ----------- + // 166 bytes, since every bit that needs to be send costs us a byte // - + + // Prepare the tag modulation bits from the message CodeIso14443aAsTag(response_info->response,response_info->response_n); @@ -931,15 +930,22 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe 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 +#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 273 + bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) { // Retrieve and store the current buffer index response_info->modulation = free_buffer_pointer; // Determine the maximum size we can use from our buffer - size_t max_buffer_size = BigBuf_get_addr() + FREE_BUFFER_OFFSET + FREE_BUFFER_SIZE - free_buffer_pointer; + size_t max_buffer_size = ALLOCATED_TAG_MODULATION_BUFFER_SIZE; // Forward the prepare tag modulation function to the inner function - if (prepare_tag_modulation(response_info,max_buffer_size)) { + if (prepare_tag_modulation(response_info, max_buffer_size)) { // Update the free buffer offset free_buffer_pointer += ToSendMax; return true; @@ -954,10 +960,6 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) { //----------------------------------------------------------------------------- void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) { - // Enable and clear the trace - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); - uint8_t sak; // The first response contains the ATQA (note: bytes are transmitted in reverse order). @@ -1067,9 +1069,17 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) .modulation_n = 0 }; - // Reset the offset pointer of the free buffer - reset_free_buffer(); - + BigBuf_free_keep_EM(); + + // allocate buffers: + uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE); + uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE); + free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE); + + // clear trace + iso14a_clear_trace(); + iso14a_set_tracing(TRUE); + // Prepare the responses of the anticollision phase // there will be not enough time to do this at the moment the reader sends it REQA for (size_t i=0; i tag) that we're receiving. // The length of a received command will in most cases be no more than 18 bytes. // So 32 should be enough! - uint8_t *receivedCmd = BigBuf_get_addr() + RECV_CMD_OFFSET; - uint8_t *receivedCmdPar = BigBuf_get_addr() + RECV_CMD_PAR_OFFSET; + uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE]; // The response (tag -> reader) that we're receiving. - uint8_t *receivedResponse = BigBuf_get_addr() + RECV_RESP_OFFSET; - uint8_t *receivedResponsePar = BigBuf_get_addr() + RECV_RESP_PAR_OFFSET; + uint8_t receivedResponse[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedResponsePar[MAX_MIFARE_PARITY_SIZE]; // As we receive stuff, we copy it from receivedCmd or receivedResponse // into trace, along with its length and other annotations. //uint8_t *trace = (uint8_t *)BigBuf; - // The DMA buffer, used to stream samples from the FPGA - uint8_t *dmaBuf = BigBuf_get_addr() + DMA_BUFFER_OFFSET; + // free eventually allocated BigBuf memory + BigBuf_free(); + // allocate the DMA buffer, used to stream samples from the FPGA + uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); uint8_t *data = dmaBuf; uint8_t previous_data = 0; int maxDataLen = 0; @@ -2792,7 +2806,7 @@ void RAMFUNC SniffMifare(uint8_t param) { // test for length of buffer if(dataLen > maxDataLen) { // we are more behind than ever... maxDataLen = dataLen; - if(dataLen > 400) { + if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) { Dbprintf("blew circular buffer! dataLen=0x%x", dataLen); break; } diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 201a52f2..31ee6358 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -26,7 +26,7 @@ void DoAcquisition125k_internal(int trigger_threshold,bool silent) { uint8_t *dest = BigBuf_get_addr(); - int n = BigBuf_max_trace_len(); + int n = BigBuf_max_traceLen(); int i; memset(dest, 0, n); @@ -178,7 +178,7 @@ void ReadTItag(void) #define FREQHI 134200 signed char *dest = (signed char *)BigBuf_get_addr(); - uint16_t n = BigBuf_max_trace_len(); + uint16_t n = BigBuf_max_traceLen(); // 128 bit shift register [shift3:shift2:shift1:shift0] uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; @@ -331,7 +331,7 @@ void AcquireTiType(void) // clear buffer uint32_t *BigBuf = (uint32_t *)BigBuf_get_addr(); - memset(BigBuf,0,BigBuf_max_trace_len()/sizeof(uint32_t)); + memset(BigBuf,0,BigBuf_max_traceLen()/sizeof(uint32_t)); // Set up the synchronous serial port AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; @@ -634,7 +634,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { uint8_t *dest = BigBuf_get_addr(); - size_t size=sizeof(BigBuf); + size_t size = BigBuf_max_traceLen(); uint32_t hi2=0, hi=0, lo=0; int idx=0; // Configure to go in 125Khz listen mode @@ -647,10 +647,6 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) DoAcquisition125k_internal(-1,true); // FSK demodulator - idx = HIDdemodFSK(dest, BigBuf_max_trace_len(), &hi2, &hi, &lo); - WDT_HIT(); - size = sizeof(BigBuf); - idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo); if (idx>0 && lo>0){ @@ -736,7 +732,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) if (ledcontrol) LED_A_ON(); DoAcquisition125k_internal(-1,true); - size = BigBuf_max_trace_len(); + size = BigBuf_max_traceLen(); //Dbprintf("DEBUG: Buffer got"); //askdemod and manchester decode errCnt = askmandemod(dest, &size, &clk, &invert); @@ -789,7 +785,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) DoAcquisition125k_internal(-1,true); //fskdemod and get start index WDT_HIT(); - idx = IOdemodFSK(dest, BigBuf_max_trace_len()); + idx = IOdemodFSK(dest, BigBuf_max_traceLen()); if (idx>0){ //valid tag found @@ -965,7 +961,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) //int m=0, i=0; //enio adjustment 12/10/14 uint32_t m=0, i=0; FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = BigBuf_max_trace_len(); + m = BigBuf_max_traceLen(); // Clear destination buffer before sending the command memset(dest, 128, m); // Connect the A/D to the peak-detected low-frequency path. @@ -1030,7 +1026,7 @@ void T55xxReadTrace(void){ int m=0, i=0; FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - m = BigBuf_max_trace_len(); + m = BigBuf_max_traceLen(); // Clear destination buffer before sending the command memset(dest, 128, m); // Connect the A/D to the peak-detected low-frequency path. @@ -1381,7 +1377,7 @@ int DemodPCF7931(uint8_t **outBlocks) { uint8_t BitStream[256]; uint8_t Blocks[8][16]; uint8_t *GraphBuffer = BigBuf_get_addr(); - int GraphTraceLen = BigBuf_max_trace_len(); + int GraphTraceLen = BigBuf_max_traceLen(); int i, j, lastval, bitidx, half_switch; int clock = 64; int tolerance = clock / 8; @@ -1808,7 +1804,7 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); fwd_bit_count += Prepare_Addr( Address ); - m = BigBuf_max_trace_len(); + m = BigBuf_max_traceLen(); // Clear destination buffer before sending the command memset(dest, 128, m); // Connect the A/D to the peak-detected low-frequency path. diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index a96164fc..4279e63f 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -529,11 +529,13 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; pcs = &mpcs; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint32_t auth1_time, auth2_time; static uint16_t delta_time; + // free eventually allocated BigBuf memory + BigBuf_free(); // clear trace iso14a_clear_trace(); iso14a_set_tracing(false); @@ -920,8 +922,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai uint8_t d_block[18] = {0x00}; uint32_t cuid; - uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; // reset FPGA and LED if (workFlags & 0x08) { @@ -1039,8 +1041,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai uint8_t data[18] = {0x00}; uint32_t cuid = 0; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; if (workFlags & 0x08) { LED_A_ON(); @@ -1104,8 +1106,8 @@ void MifareCIdent(){ // variables byte_t isOK = 1; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; ReaderTransmitBitsPar(wupC1,7,0, NULL); if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { @@ -1181,4 +1183,4 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){ cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout)); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); -} \ No newline at end of file +} diff --git a/armsrc/mifaresniff.c b/armsrc/mifaresniff.c index 69138811..59e84697 100644 --- a/armsrc/mifaresniff.c +++ b/armsrc/mifaresniff.c @@ -157,7 +157,7 @@ bool intMfSniffSend() { while (pckLen > 0) { pckSize = MIN(USB_CMD_DATA_SIZE, pckLen); LED_B_ON(); - cmd_send(CMD_ACK, 1, pckSize, pckNum, trace + traceLen - pckLen, pckSize); + cmd_send(CMD_ACK, 1, traceLen, pckSize, trace + traceLen - pckLen, pckSize); LED_B_OFF(); pckLen -= pckSize; diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index 1de4819e..f79c2ede 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -21,17 +21,6 @@ int MF_DBGLEVEL = MF_DBG_ALL; -// memory management -uint8_t* get_bigbufptr_recvrespbuf(void) { - return BigBuf_get_addr() + RECV_RESP_OFFSET; -} -uint8_t* get_bigbufptr_recvcmdbuf(void) { - return BigBuf_get_addr() + RECV_CMD_OFFSET; -} -uint8_t* get_bigbufptr_emlcardmem(void) { - return BigBuf_get_addr() + CARD_MEMORY_OFFSET; -} - // crypto1 helpers void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){ uint8_t bt = 0; @@ -186,8 +175,8 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN uint32_t nt, ntpp; // Supplied tag nonce uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; // Transmit MIFARE_CLASSIC_AUTH len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing); @@ -273,8 +262,8 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo int len; uint8_t bt[2]; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; // command MIFARE_CLASSIC_READBLOCK len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL); @@ -302,8 +291,8 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){ uint16_t len; - uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL); if (len == 1) { @@ -327,8 +316,8 @@ int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){ int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){ uint16_t len; - uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL); if (len == 1) { @@ -353,8 +342,8 @@ int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) { uint16_t len; uint8_t bt[2]; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; // command MIFARE_CLASSIC_READBLOCK @@ -392,8 +381,8 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl byte_t res; uint8_t d_block[18], d_block_enc[18]; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; // command MIFARE_CLASSIC_WRITEBLOCK len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); @@ -435,8 +424,8 @@ int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) uint16_t len; uint8_t par[3] = {0}; // enough for 18 parity bits uint8_t d_block[18] = {0x00}; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; // command MIFARE_CLASSIC_WRITEBLOCK len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); @@ -466,8 +455,8 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc { uint16_t len; uint8_t d_block[8] = {0x00}; - uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; // command MIFARE_CLASSIC_WRITEBLOCK d_block[0]= blockNo; @@ -487,8 +476,8 @@ int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *bloc int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) { uint16_t len; - uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL); if (len != 0) { @@ -503,8 +492,8 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) int mifare_ultra_halt(uint32_t uid) { uint16_t len; - uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL); if (len != 0) { @@ -538,22 +527,22 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo) // work with emulator memory void emlSetMem(uint8_t *data, int blockNum, int blocksCount) { - uint8_t* emCARD = get_bigbufptr_emlcardmem(); + uint8_t* emCARD = BigBuf_get_EM_addr(); memcpy(emCARD + blockNum * 16, data, blocksCount * 16); } void emlGetMem(uint8_t *data, int blockNum, int blocksCount) { - uint8_t* emCARD = get_bigbufptr_emlcardmem(); + uint8_t* emCARD = BigBuf_get_EM_addr(); memcpy(data, emCARD + blockNum * 16, blocksCount * 16); } void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) { - uint8_t* emCARD = get_bigbufptr_emlcardmem(); + uint8_t* emCARD = BigBuf_get_EM_addr(); memcpy(data, emCARD + bytePtr, byteCount); } int emlCheckValBl(int blockNum) { - uint8_t* emCARD = get_bigbufptr_emlcardmem(); + uint8_t* emCARD = BigBuf_get_EM_addr(); uint8_t* data = emCARD + blockNum * 16; if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) || @@ -568,7 +557,7 @@ int emlCheckValBl(int blockNum) { } int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) { - uint8_t* emCARD = get_bigbufptr_emlcardmem(); + uint8_t* emCARD = BigBuf_get_EM_addr(); uint8_t* data = emCARD + blockNum * 16; if (emlCheckValBl(blockNum)) { @@ -581,7 +570,7 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) { } int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) { - uint8_t* emCARD = get_bigbufptr_emlcardmem(); + uint8_t* emCARD = BigBuf_get_EM_addr(); uint8_t* data = emCARD + blockNum * 16; memcpy(data + 0, &blReg, 4); @@ -599,7 +588,7 @@ int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) { uint64_t emlGetKey(int sectorNum, int keyType) { uint8_t key[6]; - uint8_t* emCARD = get_bigbufptr_emlcardmem(); + uint8_t* emCARD = BigBuf_get_EM_addr(); memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6); return bytes_to_num(key, 6); @@ -610,7 +599,7 @@ void emlClearMem(void) { const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04}; - uint8_t* emCARD = get_bigbufptr_emlcardmem(); + uint8_t* emCARD = BigBuf_get_EM_addr(); memset(emCARD, 0, CARD_MEMORY_SIZE); @@ -665,8 +654,8 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){ int len; // load key, keynumber uint8_t data[2]={0x0a, 0x00}; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL); if (len == 1) { @@ -695,8 +684,8 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){ data[0] = 0xAF; memcpy(data+1,key,16); - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar ,NULL); diff --git a/armsrc/mifareutil.h b/armsrc/mifareutil.h index 2770a442..195afa53 100644 --- a/armsrc/mifareutil.h +++ b/armsrc/mifareutil.h @@ -53,7 +53,6 @@ extern int MF_DBGLEVEL; #define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF(); //functions -uint8_t* mifare_get_bigbufptr(void); int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing); @@ -83,11 +82,6 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *receivedCmd, int len) void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par); uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data); -// memory management -uint8_t* get_bigbufptr_recvrespbuf(void); -uint8_t* get_bigbufptr_recvcmdbuf(void); -uint8_t* get_bigbufptr_emlcardmem(void); - // Mifare memory structure uint8_t NumBlocksPerSector(uint8_t sectorNo); uint8_t FirstBlockOfSector(uint8_t sectorNo); diff --git a/client/cmddata.c b/client/cmddata.c index 79ff93be..8c91f0e1 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -1426,7 +1426,7 @@ int CmdHexsamples(const char *Cmd) int offset = 0; char string_buf[25]; char* string_ptr = string_buf; - uint8_t got[40000]; + uint8_t got[BIGBUF_SIZE]; sscanf(Cmd, "%i %i", &requested, &offset); @@ -1435,7 +1435,7 @@ int CmdHexsamples(const char *Cmd) requested = 8; } if (offset + requested > sizeof(got)) { - PrintAndLog("Tried to read past end of buffer, + > 40000"); + PrintAndLog("Tried to read past end of buffer, + > %d", BIGBUF_SIZE); return 0; } @@ -1485,7 +1485,7 @@ int CmdHpf(const char *Cmd) int CmdSamples(const char *Cmd) { - uint8_t got[40000] = {0x00}; + uint8_t got[BIGBUF_SIZE] = {0x00}; int n = strtol(Cmd, NULL, 0); if (n == 0) @@ -1495,14 +1495,14 @@ int CmdSamples(const char *Cmd) n = sizeof(got); PrintAndLog("Reading %d samples from device memory\n", n); - GetFromBigBuf(got,n,0); - WaitForResponse(CMD_ACK,NULL); + GetFromBigBuf(got,n,0); + WaitForResponse(CMD_ACK,NULL); for (int j = 0; j < n; j++) { GraphBuffer[j] = ((int)got[j]) - 128; - } - GraphTraceLen = n; - RepaintGraphWindow(); - return 0; + } + GraphTraceLen = n; + RepaintGraphWindow(); + return 0; } int CmdTuneSamples(const char *Cmd) diff --git a/client/cmddata.h b/client/cmddata.h index d87c8b82..514be3a2 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -60,4 +60,6 @@ int CmdIndalaDecode(const char *Cmd); extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; extern int DemodBufferLen; +#define BIGBUF_SIZE 40000 + #endif diff --git a/client/cmdhf.c b/client/cmdhf.c index fbc2d7b2..1dae1d9b 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -32,8 +32,6 @@ int CmdHFTune(const char *Cmd) SendCommand(&c); return 0; } -// for the time being. Need better Bigbuf handling. -#define TRACE_SIZE 3000 //The following data is taken from http://www.proxmark.org/forum/viewtopic.php?pid=13501#p13501 /* @@ -384,18 +382,18 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len) } } -uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, bool showWaitCycles) +uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles) { bool isResponse; - uint16_t duration, data_len,parity_len; + uint16_t duration, data_len, parity_len; uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp; char explanation[30] = {0}; + if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen; + first_timestamp = *((uint32_t *)(trace)); timestamp = *((uint32_t *)(trace + tracepos)); - // Break and stick with current result if buffer was not completely full - if (timestamp == 0x44444444) return TRACE_SIZE; tracepos += 4; duration = *((uint16_t *)(trace + tracepos)); @@ -411,8 +409,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo } parity_len = (data_len-1)/8 + 1; - if (tracepos + data_len + parity_len >= TRACE_SIZE) { - return TRACE_SIZE; + if (tracepos + data_len + parity_len > traceLen) { + return traceLen; } uint8_t *frame = trace + tracepos; @@ -498,6 +496,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo } } + if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen; + bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000; if (showWaitCycles && !isResponse && next_isResponse) { @@ -510,9 +510,11 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo (next_timestamp - EndOfTransmissionTimestamp)); } } + return tracepos; } + int CmdHFList(const char *Cmd) { bool showWaitCycles = false; @@ -570,12 +572,28 @@ int CmdHFList(const char *Cmd) } - uint8_t trace[TRACE_SIZE]; + uint8_t *trace; uint16_t tracepos = 0; - GetFromBigBuf(trace, TRACE_SIZE, 0); - WaitForResponse(CMD_ACK, NULL); - - PrintAndLog("Recorded Activity"); + trace = malloc(USB_CMD_DATA_SIZE); + + // Query for the size of the trace + UsbCommand response; + GetFromBigBuf(trace, USB_CMD_DATA_SIZE, 0); + WaitForResponse(CMD_ACK, &response); + uint16_t traceLen = response.arg[2]; + if (traceLen > USB_CMD_DATA_SIZE) { + uint8_t *p = realloc(trace, traceLen); + if (p == NULL) { + PrintAndLog("Cannot allocate memory for trace"); + free(trace); + return 2; + } + trace = p; + GetFromBigBuf(trace, traceLen, 0); + WaitForResponse(CMD_ACK, NULL); + } + + PrintAndLog("Recorded Activity (TraceLen = %d bytes)", traceLen); PrintAndLog(""); PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)"); @@ -584,10 +602,12 @@ int CmdHFList(const char *Cmd) PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |"); PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|"); - while(tracepos < TRACE_SIZE) + while(tracepos < traceLen) { - tracepos = printTraceLine(tracepos, trace, protocol, showWaitCycles); + tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles); } + + free(trace); return 0; } diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index ea07b894..cf865875 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -145,11 +145,25 @@ demodError: int CmdHF14BList(const char *Cmd) { - uint8_t got[TRACE_BUFFER_SIZE]; - GetFromBigBuf(got,sizeof(got),0); - WaitForResponse(CMD_ACK,NULL); - - PrintAndLog("recorded activity:"); + uint8_t *got = malloc(USB_CMD_DATA_SIZE); + + // Query for the actual size of the trace + UsbCommand response; + GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0); + WaitForResponse(CMD_ACK, &response); + uint16_t traceLen = response.arg[2]; + if (traceLen > USB_CMD_DATA_SIZE) { + uint8_t *p = realloc(got, traceLen); + if (p == NULL) { + PrintAndLog("Cannot allocate memory for trace"); + free(got); + return 2; + } + got = p; + GetFromBigBuf(got, traceLen, 0); + WaitForResponse(CMD_ACK,NULL); + } + PrintAndLog("recorded activity: (TraceLen = %d bytes)", traceLen); PrintAndLog(" time :rssi: who bytes"); PrintAndLog("---------+----+----+-----------"); @@ -158,7 +172,7 @@ int CmdHF14BList(const char *Cmd) for(;;) { - if(i >= TRACE_BUFFER_SIZE) { break; } + if(i >= traceLen) { break; } bool isResponse; int timestamp = *((uint32_t *)(got+i)); @@ -175,7 +189,7 @@ int CmdHF14BList(const char *Cmd) if(len > 100) { break; } - if(i + len >= TRACE_BUFFER_SIZE) { + if(i + len >= traceLen) { break; } @@ -218,6 +232,7 @@ int CmdHF14BList(const char *Cmd) prev = timestamp; i += (len + 9); } + free(got); return 0; } diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 24d04dc2..f225359d 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -1765,15 +1765,16 @@ int CmdHF14AMfSniff(const char *Cmd){ int res = 0; int len = 0; int blockLen = 0; - int num = 0; int pckNum = 0; - uint8_t uid[7] = {0x00}; + int num = 0; + uint8_t uid[7]; uint8_t uid_len; uint8_t atqa[2] = {0x00}; uint8_t sak; bool isTag; - uint8_t buf[3000] = {0x00}; - uint8_t * bufPtr = buf; + uint8_t *buf = NULL; + uint16_t bufsize = 0; + uint8_t *bufPtr = NULL; char ctmp = param_getchar(Cmd, 0); if ( ctmp == 'h' || ctmp == 'H' ) { @@ -1816,32 +1817,47 @@ int CmdHF14AMfSniff(const char *Cmd){ break; } - UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) { + UsbCommand resp; + if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) { res = resp.arg[0] & 0xff; - len = resp.arg[1]; - num = resp.arg[2]; - - if (res == 0) return 0; - if (res == 1) { - if (num ==0) { + uint16_t traceLen = resp.arg[1]; + len = resp.arg[2]; + + if (res == 0) return 0; // we are done + + if (res == 1) { // there is (more) data to be transferred + if (pckNum == 0) { // first packet, (re)allocate necessary buffer + if (traceLen > bufsize) { + uint8_t *p; + if (buf == NULL) { // not yet allocated + p = malloc(traceLen); + } else { // need more memory + p = realloc(buf, traceLen); + } + if (p == NULL) { + PrintAndLog("Cannot allocate memory for trace"); + free(buf); + return 2; + } + buf = p; + } bufPtr = buf; - memset(buf, 0x00, 3000); + bufsize = traceLen; + memset(buf, 0x00, traceLen); } memcpy(bufPtr, resp.d.asBytes, len); bufPtr += len; pckNum++; } - if (res == 2) { + + if (res == 2) { // received all data, start displaying blockLen = bufPtr - buf; bufPtr = buf; printf(">\n"); PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum); - num = 0; while (bufPtr - buf < blockLen) { - bufPtr += 6; + bufPtr += 6; // skip (void) timing information len = *((uint16_t *)bufPtr); - if(len & 0x8000) { isTag = true; len &= 0x7fff; @@ -1850,12 +1866,10 @@ int CmdHF14AMfSniff(const char *Cmd){ } bufPtr += 2; if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) { - memcpy(uid, bufPtr + 2, 7); memcpy(atqa, bufPtr + 2 + 7, 2); uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4; sak = bufPtr[11]; - PrintAndLog("tag select uid:%s atqa:0x%02x%02x sak:0x%02x", sprint_hex(uid + (7 - uid_len), uid_len), atqa[1], @@ -1873,18 +1887,21 @@ int CmdHF14AMfSniff(const char *Cmd){ AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len); if (wantDecrypt) mfTraceDecode(bufPtr, len, wantSaveToEmlFile); + num++; } bufPtr += len; bufPtr += ((len-1)/8+1); // ignore parity - num++; } + pckNum = 0; } } // resp not NULL } // while (true) - + + free(buf); return 0; } + static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 549c427c..fe5ba587 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -29,110 +29,125 @@ size_t nbytes(size_t nbits) { int CmdLFHitagList(const char *Cmd) { - uint8_t got[TRACE_BUFFER_SIZE]; - GetFromBigBuf(got,sizeof(got),0); - WaitForResponse(CMD_ACK,NULL); - - PrintAndLog("recorded activity:"); - PrintAndLog(" ETU :nbits: who bytes"); - PrintAndLog("---------+-----+----+-----------"); + uint8_t *got = malloc(USB_CMD_DATA_SIZE); + + // Query for the actual size of the trace + UsbCommand response; + GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0); + WaitForResponse(CMD_ACK, &response); + uint16_t traceLen = response.arg[2]; + if (traceLen > USB_CMD_DATA_SIZE) { + uint8_t *p = realloc(got, traceLen); + if (p == NULL) { + PrintAndLog("Cannot allocate memory for trace"); + free(got); + return 2; + } + got = p; + GetFromBigBuf(got, traceLen, 0); + WaitForResponse(CMD_ACK,NULL); + } + + PrintAndLog("recorded activity (TraceLen = %d bytes):"); + PrintAndLog(" ETU :nbits: who bytes"); + PrintAndLog("---------+-----+----+-----------"); - int i = 0; - int prev = -1; - int len = strlen(Cmd); + int i = 0; + int prev = -1; + int len = strlen(Cmd); - char filename[FILE_PATH_SIZE] = { 0x00 }; - FILE* pf = NULL; + char filename[FILE_PATH_SIZE] = { 0x00 }; + FILE* pf = NULL; - if (len > FILE_PATH_SIZE) - len = FILE_PATH_SIZE; - memcpy(filename, Cmd, len); + if (len > FILE_PATH_SIZE) + len = FILE_PATH_SIZE; + memcpy(filename, Cmd, len); - if (strlen(filename) > 0) { - if ((pf = fopen(filename,"wb")) == NULL) { - PrintAndLog("Error: Could not open file [%s]",filename); - return 1; + if (strlen(filename) > 0) { + if ((pf = fopen(filename,"wb")) == NULL) { + PrintAndLog("Error: Could not open file [%s]",filename); + return 1; + } } - } - for (;;) { + for (;;) { - if(i >= TRACE_BUFFER_SIZE) { break; } - - bool isResponse; - int timestamp = *((uint32_t *)(got+i)); - if (timestamp & 0x80000000) { - timestamp &= 0x7fffffff; - isResponse = 1; - } else { - isResponse = 0; - } - - int parityBits = *((uint32_t *)(got+i+4)); - // 4 bytes of additional information... - // maximum of 32 additional parity bit information - // - // TODO: - // at each quarter bit period we can send power level (16 levels) - // or each half bit period in 256 levels. - - int bits = got[i+8]; - int len = nbytes(got[i+8]); - - if (len > 100) { - break; - } - if (i + len >= TRACE_BUFFER_SIZE) { break;} - - uint8_t *frame = (got+i+9); - - // Break and stick with current result if buffer was not completely full - if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; } - - char line[1000] = ""; - int j; - for (j = 0; j < len; j++) { - int oddparity = 0x01; - int k; + if(i > traceLen) { break; } + + bool isResponse; + int timestamp = *((uint32_t *)(got+i)); + if (timestamp & 0x80000000) { + timestamp &= 0x7fffffff; + isResponse = 1; + } else { + isResponse = 0; + } - for (k=0;k<8;k++) { - oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01); - } + int parityBits = *((uint32_t *)(got+i+4)); + // 4 bytes of additional information... + // maximum of 32 additional parity bit information + // + // TODO: + // at each quarter bit period we can send power level (16 levels) + // or each half bit period in 256 levels. - //if((parityBits >> (len - j - 1)) & 0x01) { - if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) { - sprintf(line+(j*4), "%02x! ", frame[j]); - } - else { - sprintf(line+(j*4), "%02x ", frame[j]); - } - } - - PrintAndLog(" +%7d: %3d: %s %s", - (prev < 0 ? 0 : (timestamp - prev)), - bits, - (isResponse ? "TAG" : " "), - line); + int bits = got[i+8]; + int len = nbytes(got[i+8]); + if (len > 100) { + break; + } + if (i + len > traceLen) { break;} + + uint8_t *frame = (got+i+9); + + // Break and stick with current result if buffer was not completely full + if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; } + + char line[1000] = ""; + int j; + for (j = 0; j < len; j++) { + int oddparity = 0x01; + int k; + + for (k=0;k<8;k++) { + oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01); + } + + //if((parityBits >> (len - j - 1)) & 0x01) { + if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) { + sprintf(line+(j*4), "%02x! ", frame[j]); + } + else { + sprintf(line+(j*4), "%02x ", frame[j]); + } + } - if (pf) { - fprintf(pf," +%7d: %3d: %s %s\n", - (prev < 0 ? 0 : (timestamp - prev)), - bits, - (isResponse ? "TAG" : " "), - line); - } - - prev = timestamp; - i += (len + 9); - } + PrintAndLog(" +%7d: %3d: %s %s", + (prev < 0 ? 0 : (timestamp - prev)), + bits, + (isResponse ? "TAG" : " "), + line); + + if (pf) { + fprintf(pf," +%7d: %3d: %s %s\n", + (prev < 0 ? 0 : (timestamp - prev)), + bits, + (isResponse ? "TAG" : " "), + line); + } + + prev = timestamp; + i += (len + 9); + } - if (pf) { - fclose(pf); - PrintAndLog("Recorded activity succesfully written to file: %s", filename); - } + if (pf) { + fclose(pf); + PrintAndLog("Recorded activity succesfully written to file: %s", filename); + } - return 0; + free(got); + return 0; } int CmdLFHitagSnoop(const char *Cmd) { diff --git a/client/cmdmain.c b/client/cmdmain.c index 15cb3f98..512aa13c 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -188,7 +188,6 @@ void UsbCommandReceived(UsbCommand *UC) } break; case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: { - sample_buf_len += UC->arg[1]; memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]); } break; diff --git a/client/data.c b/client/data.c index 3f019326..4d7d1e41 100644 --- a/client/data.c +++ b/client/data.c @@ -16,11 +16,9 @@ #include "cmdmain.h" uint8_t* sample_buf; -size_t sample_buf_len; void GetFromBigBuf(uint8_t *dest, int bytes, int start_index) { - sample_buf_len = 0; sample_buf = dest; UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}}; SendCommand(&c); diff --git a/client/data.h b/client/data.h index 41bd9a41..7d85e1f1 100644 --- a/client/data.h +++ b/client/data.h @@ -13,13 +13,9 @@ #include -//trace buffer size as defined in armsrc/apps.h TRACE_SIZE -#define TRACE_BUFFER_SIZE 4096 #define FILE_PATH_SIZE 1000 -#define SAMPLE_BUFFER_SIZE 64 extern uint8_t* sample_buf; -extern size_t sample_buf_len; #define arraylen(x) (sizeof(x)/sizeof((x)[0])) void GetFromBigBuf(uint8_t *dest, int bytes, int start_index); diff --git a/include/hitag2.h b/include/hitag2.h index 713c2cb8..ca15d81d 100644 --- a/include/hitag2.h +++ b/include/hitag2.h @@ -14,8 +14,8 @@ typedef enum { RHT2F_PASSWORD = 21, RHT2F_AUTHENTICATE = 22, - RHT2F_CRYPTO = 23, - RHT2F_TEST_AUTH_ATTEMPTS = 25, + RHT2F_CRYPTO = 23, + RHT2F_TEST_AUTH_ATTEMPTS = 25, } hitag_function; typedef struct { @@ -33,7 +33,7 @@ typedef struct { typedef union { rht2d_password pwd; rht2d_authenticate auth; - rht2d_crypto crypto; + rht2d_crypto crypto; } hitag_data; #endif -- 2.39.5