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
This commit is contained in:
pwpiwi 2015-01-27 08:34:48 +01:00
parent 117d9ec25c
commit f71f4deb8f
22 changed files with 485 additions and 400 deletions

View file

@ -14,22 +14,38 @@
#include "apps.h" #include "apps.h"
#include "string.h" #include "string.h"
// The large multi-purpose buffer, typically used to hold A/D samples or traces, // BigBuf is 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. // Also used to hold various smaller buffers and the Mifare Emulator Memory.
static uint8_t BigBuf[BIGBUF_SIZE];
// declare it as uint32_t to achieve alignment to 4 Byte boundary
static uint32_t BigBuf[BIGBUF_SIZE/sizeof(uint32_t)];
// High memory mark // High memory mark
static uint16_t BigBuf_hi = BIGBUF_SIZE; static uint16_t BigBuf_hi = BIGBUF_SIZE;
// trace related global variables. Change to function calls? // pointer to the emulator memory.
//uint8_t *trace = BigBuf; static uint8_t *emulator_memory = NULL;
uint16_t traceLen;
// trace related global variables
// (only one left). ToDo: make this static as well?
uint16_t traceLen = 0;
// get the address of BigBuf // get the address of BigBuf
uint8_t *BigBuf_get_addr(void) 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 // allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
// is always for traces/samples // at the beginning of BigBuf is always for traces/samples
uint8_t *BigBuf_malloc(uint16_t chunksize) uint8_t *BigBuf_malloc(uint16_t chunksize)
{ {
if (BigBuf_hi - chunksize < 0) { if (BigBuf_hi - chunksize < 0) {
return NULL; // no memory left return NULL; // no memory left
} else { } else {
BigBuf_hi -= chunksize; // aligned to 4 Byte boundary chunksize = (chunksize + 3) & 0xfffc; // round to next multiple of 4
return BigBuf + BigBuf_hi; 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) void BigBuf_free(void)
{ {
BigBuf_hi = BIGBUF_SIZE; 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) // 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; return BigBuf_hi;
} }

View file

@ -14,26 +14,20 @@
#define BIGBUF_SIZE 40000 #define BIGBUF_SIZE 40000
#define TRACE_OFFSET 0 #define MAX_FRAME_SIZE 256 // maximum allowed ISO14443 frame
#define TRACE_SIZE 3000 #define MAX_PARITY_SIZE ((MAX_FRAME_SIZE + 7) / 8)
#define RECV_CMD_OFFSET (TRACE_OFFSET + TRACE_SIZE) #define MAX_MIFARE_FRAME_SIZE 18 // biggest Mifare frame is answer to a read (one block = 16 Bytes) + 2 Bytes CRC
#define MAX_FRAME_SIZE 256 #define MAX_MIFARE_PARITY_SIZE 3 // need 18 parity bits for the 18 Byte above. 3 Bytes are enough to store these
#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 CARD_MEMORY_SIZE 4096 #define CARD_MEMORY_SIZE 4096
#define DMA_BUFFER_OFFSET CARD_MEMORY_OFFSET #define DMA_BUFFER_SIZE 128
#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)
extern uint8_t *BigBuf_get_addr(void); 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); void BigBuf_Clear(void);
extern uint8_t *BigBuf_malloc(uint16_t); extern uint8_t *BigBuf_malloc(uint16_t);
extern void BigBuf_free(void); extern void BigBuf_free(void);
extern void BigBuf_free_keep_EM(void);
extern uint16_t traceLen; extern uint16_t traceLen;

View file

@ -240,7 +240,10 @@ void MeasureAntennaTuningHf(void)
void SimulateTagHfListen(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; uint8_t v = 0;
int i; int i;
int p = 0; int p = 0;
@ -275,7 +278,7 @@ void SimulateTagHfListen(void)
p = 0; p = 0;
i++; i++;
if(i >= FREE_BUFFER_SIZE) { if(i >= HF_14B_SNOOP_BUFFER_SIZE) {
break; break;
} }
} }
@ -912,10 +915,10 @@ void UsbPacketReceived(uint8_t *packet, int len)
uint8_t *BigBuf = BigBuf_get_addr(); uint8_t *BigBuf = BigBuf_get_addr();
for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) { for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
size_t len = MIN((c->arg[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 // 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(); LED_B_OFF();
break; break;

View file

@ -24,19 +24,19 @@
static bool bQuiet; static bool bQuiet;
bool bCrypto; static bool bCrypto;
bool bAuthenticating; static bool bAuthenticating;
bool bPwd; static bool bPwd;
bool bSuccessful; 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; static uint16_t traceLen = 0;
uint8_t *trace = BigBuf_get_addr(); uint8_t *trace = BigBuf_get_addr();
// Return when trace is full // 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 // Trace the random, i'm curious
rsamples += iSamples; rsamples += iSamples;
@ -89,20 +89,17 @@ static struct hitag2_tag tag = {
}, },
}; };
//#define TRACE_LENGTH 3000 // ToDo: define a meaningful maximum size for auth_table. The bigger this is, the lower will be the available memory for traces.
//uint8_t *trace = (uint8_t *) BigBuf; // Historically it used to be FREE_BUFFER_SIZE, which was 2744.
//int traceLen = 0; #define AUTH_TABLE_LENGTH 2744
//int rsamples = 0; 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 static byte_t password[4];
#define AUTH_TABLE_LENGTH FREE_BUFFER_SIZE static byte_t NrAr[8];
size_t auth_table_pos = 0; static byte_t key[8];
size_t auth_table_len = AUTH_TABLE_LENGTH; static uint64_t cipher_state;
byte_t password[4];
byte_t NrAr[8];
byte_t key[8];
uint64_t cipher_state;
/* Following is a modified version of cryptolib.com/ciphers/hitag2/ */ /* 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. // 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; return c;
} }
int hitag2_reset(void) static int hitag2_reset(void)
{ {
tag.state = TAG_STATE_RESET; tag.state = TAG_STATE_RESET;
tag.crypto_active = 0; tag.crypto_active = 0;
return 0; return 0;
} }
int hitag2_init(void) static int hitag2_init(void)
{ {
// memcpy(&tag, &resetdata, sizeof(tag)); // memcpy(&tag, &resetdata, sizeof(tag));
hitag2_reset(); hitag2_reset();
@ -303,10 +300,9 @@ static void hitag_send_frame(const byte_t* frame, size_t frame_len)
LOW(GPIO_SSC_DOUT); 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]; byte_t rx_air[HITAG_FRAME_LEN];
// Copy the (original) received frame how it is send over the air // 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(); LED_A_OFF();
} }
static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len) static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len)
{ {
// Send the content of the frame // 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; 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 // Reset the transmission frame length
*txlen = 0; *txlen = 0;
@ -535,7 +532,7 @@ bool hitag2_password(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen)
return true; 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 // Reset the transmission frame length
*txlen = 0; *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 // Reset the transmission frame length
*txlen = 0; *txlen = 0;
@ -668,10 +665,8 @@ bool hitag2_authenticate(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txl
return true; return true;
} }
bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
byte_t* auth_table; static bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_t* txlen) {
auth_table = (byte_t *)BigBuf_get_addr() + AUTH_TABLE_OFFSET;
// Reset the transmission frame length // Reset the transmission frame length
*txlen = 0; *txlen = 0;
@ -684,17 +679,17 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_
if (bCrypto) { 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]); 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 // Removing failed entry from authentiations table
memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8); memcpy(auth_table+auth_table_pos,auth_table+auth_table_pos+8,8);
auth_table_len -= 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; bCrypto = false;
if (auth_table_pos == auth_table_len) { if (auth_table_pos == auth_table_len) {
return false; 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); memcpy(NrAr,auth_table+auth_table_pos,8);
} }
*txlen = 5; *txlen = 5;
@ -727,6 +722,7 @@ bool hitag2_test_auth_attempts(byte_t* rx, const size_t rxlen, byte_t* tx, size_
return true; return true;
} }
void SnoopHitag(uint32_t type) { void SnoopHitag(uint32_t type) {
int frame_count; int frame_count;
int response; int response;
@ -739,15 +735,15 @@ void SnoopHitag(uint32_t type) {
byte_t rx[HITAG_FRAME_LEN]; byte_t rx[HITAG_FRAME_LEN];
size_t rxlen=0; size_t rxlen=0;
auth_table_len = 0;
auth_table_pos = 0;
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 // Clean up trace and prepare it for storing frames
iso14a_set_tracing(TRUE); iso14a_set_tracing(TRUE);
iso14a_clear_trace(); 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;
memset(auth_table, 0x00, AUTH_TABLE_LENGTH);
DbpString("Starting Hitag2 snoop"); DbpString("Starting Hitag2 snoop");
LED_D_ON(); LED_D_ON();
@ -771,7 +767,7 @@ void SnoopHitag(uint32_t type) {
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1); AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME; AT91C_BASE_PIOA->PIO_BSR = GPIO_SSC_FRAME;
// Disable timer during configuration // Disable timer during configuration
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
// Capture mode, defaul timer source = MCK/2 (TIMER_CLOCK1), TIOA is external trigger, // 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; bool bQuitTraceFull = false;
bQuiet = 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_len = 0;
auth_table_pos = 0; auth_table_pos = 0;
byte_t* auth_table; 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); 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"); DbpString("Starting Hitag2 simulation");
LED_D_ON(); LED_D_ON();
hitag2_init(); hitag2_init();
@ -1139,22 +1137,20 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
bool bStop; bool bStop;
bool bQuitTraceFull = false; bool bQuitTraceFull = false;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// Reset the return status // Reset the return status
bSuccessful = false; bSuccessful = false;
// Clean up trace and prepare it for storing frames // Clean up trace and prepare it for storing frames
iso14a_set_tracing(TRUE); iso14a_set_tracing(TRUE);
iso14a_clear_trace(); iso14a_clear_trace();
byte_t* auth_table;
auth_table = (byte_t *)BigBuf_get_addr() + AUTH_TABLE_OFFSET;
DbpString("Starting Hitag reader family"); DbpString("Starting Hitag reader family");
// Check configuration // Check configuration
switch(htf) { switch(htf) {
case RHT2F_PASSWORD: { case RHT2F_PASSWORD: {
Dbprintf("List identifier in password mode"); Dbprintf("List identifier in password mode");
memcpy(password,htd->pwd.password,4); memcpy(password,htd->pwd.password,4);
blocknr = 0; blocknr = 0;
bQuitTraceFull = false; bQuitTraceFull = false;
@ -1168,7 +1164,7 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
Dbhexdump(8,NrAr,false); Dbhexdump(8,NrAr,false);
bQuiet = false; bQuiet = false;
bCrypto = false; bCrypto = false;
bAuthenticating = false; bAuthenticating = false;
bQuitTraceFull = true; bQuitTraceFull = true;
} break; } break;
@ -1176,17 +1172,17 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
DbpString("Authenticating using key:"); DbpString("Authenticating using key:");
memcpy(key,htd->crypto.key,4); //HACK; 4 or 6?? I read both in the code. memcpy(key,htd->crypto.key,4); //HACK; 4 or 6?? I read both in the code.
Dbhexdump(6,key,false); Dbhexdump(6,key,false);
blocknr = 0; blocknr = 0;
bQuiet = false; bQuiet = false;
bCrypto = false; bCrypto = false;
bAuthenticating = false; bAuthenticating = false;
bQuitTraceFull = true; bQuitTraceFull = true;
} break; } break;
case RHT2F_TEST_AUTH_ATTEMPTS: { case RHT2F_TEST_AUTH_ATTEMPTS: {
Dbprintf("Testing %d authentication attempts",(auth_table_len/8)); Dbprintf("Testing %d authentication attempts",(auth_table_len/8));
auth_table_pos = 0; auth_table_pos = 0;
memcpy(NrAr,auth_table,8); memcpy(NrAr, auth_table, 8);
bQuitTraceFull = false; bQuitTraceFull = false;
bQuiet = false; bQuiet = false;
bCrypto = false; bCrypto = false;

View file

@ -640,20 +640,24 @@ void RAMFUNC SnoopIClass(void)
// The command (reader -> tag) that we're receiving. // The command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes. // The length of a received command will in most cases be no more than 18 bytes.
// So 32 should be enough! // 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. // 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); 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_set_tracing(TRUE);
iso14a_clear_trace(); iso14a_clear_trace();
iso14a_set_trigger(FALSE); iso14a_set_trigger(FALSE);
// The DMA buffer, used to stream samples from the FPGA int lastRxCounter;
uint8_t *dmaBuf = BigBuf_get_addr() + DMA_BUFFER_OFFSET;
int lastRxCounter;
uint8_t *upTo; uint8_t *upTo;
int smpl; int smpl;
int maxBehindBy = 0; int maxBehindBy = 0;
@ -703,7 +707,7 @@ void RAMFUNC SnoopIClass(void)
(DMA_BUFFER_SIZE-1); (DMA_BUFFER_SIZE-1);
if(behindBy > maxBehindBy) { if(behindBy > maxBehindBy) {
maxBehindBy = behindBy; maxBehindBy = behindBy;
if(behindBy > 400) { if(behindBy > (9 * DMA_BUFFER_SIZE / 10)) {
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy); Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
goto done; goto done;
} }
@ -1064,27 +1068,28 @@ int doIClassSimulation(uint8_t csn[], int breakAfterMacReceived, uint8_t *reader
int trace_data_size = 0; int trace_data_size = 0;
//uint8_t sof = 0x0f; //uint8_t sof = 0x0f;
// free eventually allocated BigBuf memory
BigBuf_free();
// Respond SOF -- takes 1 bytes // Respond SOF -- takes 1 bytes
uint8_t *resp1 = (BigBuf_get_addr() + FREE_BUFFER_OFFSET); uint8_t *resp1 = BigBuf_malloc(2);
int resp1Len; int resp1Len;
// Anticollision CSN (rotated CSN) // Anticollision CSN (rotated CSN)
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte) // 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; int resp2Len;
// CSN // CSN
// 22: Takes 2 bytes for SOF/EOF and 10 * 2 = 20 bytes (2 bytes/byte) // 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; int resp3Len;
// e-Purse // e-Purse
// 18: Takes 2 bytes for SOF/EOF and 8 * 2 = 16 bytes (2 bytes/byte) // 144: Takes 16 bytes for SOF/EOF and 8 * 16 = 128 bytes (2 bytes/bit)
uint8_t *resp4 = (BigBuf_get_addr() + FREE_BUFFER_OFFSET + 60); uint8_t *resp4 = BigBuf_malloc(150);
int resp4Len; int resp4Len;
// + 1720.. uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
uint8_t *receivedCmd = BigBuf_get_addr() + RECV_CMD_OFFSET;
memset(receivedCmd, 0x44, MAX_FRAME_SIZE); memset(receivedCmd, 0x44, MAX_FRAME_SIZE);
int len; int len;
@ -1529,7 +1534,7 @@ uint8_t handshakeIclassTag(uint8_t *card_data)
static uint8_t identify[] = { 0x0c }; static uint8_t identify[] = { 0x0c };
static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; static uint8_t select[] = { 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
static uint8_t readcheck_cc[]= { 0x88, 0x02 }; 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; uint8_t read_status = 0;
@ -1587,7 +1592,7 @@ void ReaderIClass(uint8_t arg0) {
while(!BUTTON_PRESS()) while(!BUTTON_PRESS())
{ {
if(traceLen > TRACE_SIZE) { if(traceLen > BigBuf_max_traceLen()) {
DbpString("Trace full"); DbpString("Trace full");
break; break;
} }
@ -1650,7 +1655,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
int keyaccess; int keyaccess;
} memory; } memory;
uint8_t* resp = BigBuf_get_addr() + RECV_RESP_OFFSET; uint8_t resp[ICLASS_BUFFER_SIZE];
setupIclassReader(); setupIclassReader();
@ -1659,7 +1664,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
WDT_HIT(); WDT_HIT();
if(traceLen > TRACE_SIZE) { if(traceLen > BigBuf_max_traceLen()) {
DbpString("Trace full"); DbpString("Trace full");
break; break;
} }

View file

@ -1013,18 +1013,19 @@ void RAMFUNC SnoopIso14443(void)
int triggered = TRUE; int triggered = TRUE;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
BigBuf_free();
// The command (reader -> tag) that we're working on receiving. // 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. // 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 // As we receive stuff, we copy it from receivedCmd or receivedResponse
// into trace, along with its length and other annotations. // into trace, along with its length and other annotations.
uint8_t *trace = BigBuf_get_addr(); uint8_t *trace = BigBuf_get_addr();
int traceLen = 0; traceLen = 0;
// The DMA buffer, used to stream samples from the FPGA. // 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; int lastRxCounter;
uint8_t *upTo; uint8_t *upTo;
int ci, cq; int ci, cq;
@ -1035,7 +1036,7 @@ void RAMFUNC SnoopIso14443(void)
int samples = 0; int samples = 0;
// Initialize the trace buffer // Initialize the trace buffer
memset(trace, 0x44, DEMOD_TRACE_SIZE); memset(trace, 0x44, BigBuf_max_traceLen());
// Set up the demodulator for tag -> reader responses. // Set up the demodulator for tag -> reader responses.
Demod.output = receivedResponse; Demod.output = receivedResponse;
@ -1050,7 +1051,7 @@ void RAMFUNC SnoopIso14443(void)
// Print some debug information about the buffer sizes // Print some debug information about the buffer sizes
Dbprintf("Snooping buffers initialized:"); 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(" Reader -> tag: %i bytes", READER_TAG_BUFFER_SIZE);
Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE); Dbprintf(" tag -> Reader: %i bytes", TAG_READER_BUFFER_SIZE);
Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE); Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE);
@ -1077,7 +1078,7 @@ void RAMFUNC SnoopIso14443(void)
(DEMOD_DMA_BUFFER_SIZE-1); (DEMOD_DMA_BUFFER_SIZE-1);
if(behindBy > maxBehindBy) { if(behindBy > maxBehindBy) {
maxBehindBy = behindBy; 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); Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
goto done; goto done;
} }
@ -1148,7 +1149,7 @@ void RAMFUNC SnoopIso14443(void)
trace[traceLen++] = Demod.len; trace[traceLen++] = Demod.len;
memcpy(trace+traceLen, receivedResponse, Demod.len); memcpy(trace+traceLen, receivedResponse, Demod.len);
traceLen += Demod.len; traceLen += Demod.len;
if(traceLen > DEMOD_TRACE_SIZE) { if(traceLen > BigBuf_max_traceLen()) {
DbpString("Reached trace limit"); DbpString("Reached trace limit");
goto done; goto done;
} }
@ -1174,9 +1175,9 @@ done:
LED_A_OFF(); LED_A_OFF();
LED_B_OFF(); LED_B_OFF();
LED_C_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:"); DbpString("Snoop statistics:");
Dbprintf(" Max behind by: %i", maxBehindBy); Dbprintf(" Max behind by: %i", maxBehindBy);
Dbprintf(" Uart State: %x", Uart.state); Dbprintf(" Uart State: %x", Uart.state);
Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt); Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt);
Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax); Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax);

View file

@ -148,7 +148,8 @@ void iso14a_set_trigger(bool enable) {
void iso14a_clear_trace() { void iso14a_clear_trace() {
uint8_t *trace = BigBuf_get_addr(); 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; 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; uint16_t duration = timestamp_end - timestamp_start;
// Return when trace is full // 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 tracing = FALSE; // don't trace any more
return FALSE; return FALSE;
} }
@ -591,9 +593,6 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
// bit 1 - trigger from first reader 7-bit request // bit 1 - trigger from first reader 7-bit request
LEDsoff(); LEDsoff();
// init trace buffer
iso14a_clear_trace();
iso14a_set_tracing(TRUE);
// We won't start recording the frames that we acquire until we trigger; // 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 // 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 // triggered == FALSE -- to wait first for card
bool triggered = !(param & 0x03); 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 command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes. uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
// So 32 should be enough! uint8_t *receivedCmdPar = BigBuf_malloc(MAX_PARITY_SIZE);
uint8_t *receivedCmd = BigBuf_get_addr() + RECV_CMD_OFFSET;
uint8_t *receivedCmdPar = BigBuf_get_addr() + RECV_CMD_PAR_OFFSET;
// The response (tag -> reader) that we're receiving. // The response (tag -> reader) that we're receiving.
uint8_t *receivedResponse = BigBuf_get_addr() + RECV_RESP_OFFSET; uint8_t *receivedResponse = BigBuf_malloc(MAX_FRAME_SIZE);
uint8_t *receivedResponsePar = BigBuf_get_addr() + RECV_RESP_PAR_OFFSET; uint8_t *receivedResponsePar = BigBuf_malloc(MAX_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 // 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 *data = dmaBuf;
uint8_t previous_data = 0; uint8_t previous_data = 0;
int maxDataLen = 0; int maxDataLen = 0;
@ -656,7 +658,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) {
// test for length of buffer // test for length of buffer
if(dataLen > maxDataLen) { if(dataLen > maxDataLen) {
maxDataLen = dataLen; maxDataLen = dataLen;
if(dataLen > 400) { if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
Dbprintf("blew circular buffer! dataLen=%d", dataLen); Dbprintf("blew circular buffer! dataLen=%d", dataLen);
break; break;
} }
@ -895,10 +897,6 @@ typedef struct {
uint32_t ProxToAirDuration; uint32_t ProxToAirDuration;
} tag_response_info_t; } 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) { 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 // 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 // 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 // 166 bytes, since every bit that needs to be send costs us a byte
// //
// Prepare the tag modulation bits from the message // Prepare the tag modulation bits from the message
CodeIso14443aAsTag(response_info->response,response_info->response_n); 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; 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) { bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) {
// Retrieve and store the current buffer index // Retrieve and store the current buffer index
response_info->modulation = free_buffer_pointer; response_info->modulation = free_buffer_pointer;
// Determine the maximum size we can use from our buffer // 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 // 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 // Update the free buffer offset
free_buffer_pointer += ToSendMax; free_buffer_pointer += ToSendMax;
return true; 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) 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; uint8_t sak;
// 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).
@ -1067,9 +1069,17 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
.modulation_n = 0 .modulation_n = 0
}; };
// Reset the offset pointer of the free buffer BigBuf_free_keep_EM();
reset_free_buffer();
// 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 // Prepare the responses of the anticollision phase
// there will be not enough time to do this at the moment the reader sends it REQA // there will be not enough time to do this at the moment the reader sends it REQA
for (size_t i=0; i<TAG_RESPONSE_COUNT; i++) { for (size_t i=0; i<TAG_RESPONSE_COUNT; i++) {
@ -1090,10 +1100,6 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
// We need to listen to the high-frequency, peak-detected path. // We need to listen to the high-frequency, peak-detected path.
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
// buffers used on software Uart:
uint8_t *receivedCmd = BigBuf_get_addr() + RECV_CMD_OFFSET;
uint8_t *receivedCmdPar = BigBuf_get_addr() + RECV_CMD_PAR_OFFSET;
cmdsRecvd = 0; cmdsRecvd = 0;
tag_response_info_t* p_response; tag_response_info_t* p_response;
@ -1254,6 +1260,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
Dbprintf("%x %x %x", happened, happened2, cmdsRecvd); Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);
LED_A_OFF(); LED_A_OFF();
BigBuf_free_keep_EM();
} }
@ -1727,8 +1734,8 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
uint8_t sel_all[] = { 0x93,0x20 }; uint8_t sel_all[] = { 0x93,0x20 };
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0 uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
uint8_t *resp = BigBuf_get_addr() + RECV_RESP_OFFSET; uint8_t resp[MAX_FRAME_SIZE]; // theoretically. A usual RATS will be much smaller
uint8_t *resp_par = BigBuf_get_addr() + RECV_RESP_PAR_OFFSET; uint8_t resp_par[MAX_PARITY_SIZE];
byte_t uid_resp[4]; byte_t uid_resp[4];
size_t uid_resp_len; size_t uid_resp_len;
@ -2020,9 +2027,12 @@ void ReaderMifare(bool first_try)
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
static uint8_t mf_nr_ar3; static uint8_t mf_nr_ar3;
uint8_t* receivedAnswer = BigBuf_get_addr() + RECV_RESP_OFFSET; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t* receivedAnswerPar = BigBuf_get_addr() + RECV_RESP_PAR_OFFSET; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// free eventually allocated BigBuf memory. We want all for tracing.
BigBuf_free();
iso14a_clear_trace(); iso14a_clear_trace();
iso14a_set_tracing(TRUE); iso14a_set_tracing(TRUE);
@ -2232,10 +2242,10 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
struct Crypto1State *pcs; struct Crypto1State *pcs;
pcs = &mpcs; pcs = &mpcs;
uint32_t numReads = 0;//Counts numer of times reader read a block uint32_t numReads = 0;//Counts numer of times reader read a block
uint8_t* receivedCmd = get_bigbufptr_recvcmdbuf(); uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE];
uint8_t* receivedCmd_par = receivedCmd + MAX_FRAME_SIZE; uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE];
uint8_t* response = get_bigbufptr_recvrespbuf(); uint8_t response[MAX_MIFARE_FRAME_SIZE];
uint8_t* response_par = response + MAX_FRAME_SIZE; uint8_t response_par[MAX_MIFARE_PARITY_SIZE];
uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID uint8_t rATQA[] = {0x04, 0x00}; // Mifare classic 1k 4BUID
uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62}; uint8_t rUIDBCC1[] = {0xde, 0xad, 0xbe, 0xaf, 0x62};
@ -2252,6 +2262,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0}; uint32_t ar_nr_responses[] = {0,0,0,0,0,0,0,0};
uint8_t ar_nr_collected = 0; uint8_t ar_nr_collected = 0;
// free eventually allocated BigBuf memory but keep Emulator Memory
BigBuf_free_keep_EM();
// clear trace // clear trace
iso14a_clear_trace(); iso14a_clear_trace();
iso14a_set_tracing(TRUE); iso14a_set_tracing(TRUE);
@ -2722,18 +2734,20 @@ void RAMFUNC SniffMifare(uint8_t param) {
// The command (reader -> tag) that we're receiving. // The command (reader -> tag) that we're receiving.
// The length of a received command will in most cases be no more than 18 bytes. // The length of a received command will in most cases be no more than 18 bytes.
// So 32 should be enough! // So 32 should be enough!
uint8_t *receivedCmd = BigBuf_get_addr() + RECV_CMD_OFFSET; uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedCmdPar = BigBuf_get_addr() + RECV_CMD_PAR_OFFSET; uint8_t receivedCmdPar[MAX_MIFARE_PARITY_SIZE];
// The response (tag -> reader) that we're receiving. // The response (tag -> reader) that we're receiving.
uint8_t *receivedResponse = BigBuf_get_addr() + RECV_RESP_OFFSET; uint8_t receivedResponse[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedResponsePar = BigBuf_get_addr() + RECV_RESP_PAR_OFFSET; uint8_t receivedResponsePar[MAX_MIFARE_PARITY_SIZE];
// As we receive stuff, we copy it from receivedCmd or receivedResponse // As we receive stuff, we copy it from receivedCmd or receivedResponse
// into trace, along with its length and other annotations. // into trace, along with its length and other annotations.
//uint8_t *trace = (uint8_t *)BigBuf; //uint8_t *trace = (uint8_t *)BigBuf;
// The DMA buffer, used to stream samples from the FPGA // free eventually allocated BigBuf memory
uint8_t *dmaBuf = BigBuf_get_addr() + DMA_BUFFER_OFFSET; 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 *data = dmaBuf;
uint8_t previous_data = 0; uint8_t previous_data = 0;
int maxDataLen = 0; int maxDataLen = 0;
@ -2792,7 +2806,7 @@ void RAMFUNC SniffMifare(uint8_t param) {
// test for length of buffer // test for length of buffer
if(dataLen > maxDataLen) { // we are more behind than ever... if(dataLen > maxDataLen) { // we are more behind than ever...
maxDataLen = dataLen; maxDataLen = dataLen;
if(dataLen > 400) { if(dataLen > (9 * DMA_BUFFER_SIZE / 10)) {
Dbprintf("blew circular buffer! dataLen=0x%x", dataLen); Dbprintf("blew circular buffer! dataLen=0x%x", dataLen);
break; break;
} }

View file

@ -26,7 +26,7 @@
void DoAcquisition125k_internal(int trigger_threshold,bool silent) void DoAcquisition125k_internal(int trigger_threshold,bool silent)
{ {
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
int n = BigBuf_max_trace_len(); int n = BigBuf_max_traceLen();
int i; int i;
memset(dest, 0, n); memset(dest, 0, n);
@ -178,7 +178,7 @@ void ReadTItag(void)
#define FREQHI 134200 #define FREQHI 134200
signed char *dest = (signed char *)BigBuf_get_addr(); 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] // 128 bit shift register [shift3:shift2:shift1:shift0]
uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0; uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0;
@ -331,7 +331,7 @@ void AcquireTiType(void)
// clear buffer // clear buffer
uint32_t *BigBuf = (uint32_t *)BigBuf_get_addr(); 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 // Set up the synchronous serial port
AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; 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(); 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; uint32_t hi2=0, hi=0, lo=0;
int idx=0; int idx=0;
// Configure to go in 125Khz listen mode // 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); DoAcquisition125k_internal(-1,true);
// FSK demodulator // FSK demodulator
idx = HIDdemodFSK(dest, BigBuf_max_trace_len(), &hi2, &hi, &lo);
WDT_HIT();
size = sizeof(BigBuf);
idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo); idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
if (idx>0 && lo>0){ if (idx>0 && lo>0){
@ -736,7 +732,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
if (ledcontrol) LED_A_ON(); if (ledcontrol) LED_A_ON();
DoAcquisition125k_internal(-1,true); DoAcquisition125k_internal(-1,true);
size = BigBuf_max_trace_len(); size = BigBuf_max_traceLen();
//Dbprintf("DEBUG: Buffer got"); //Dbprintf("DEBUG: Buffer got");
//askdemod and manchester decode //askdemod and manchester decode
errCnt = askmandemod(dest, &size, &clk, &invert); errCnt = askmandemod(dest, &size, &clk, &invert);
@ -789,7 +785,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
DoAcquisition125k_internal(-1,true); DoAcquisition125k_internal(-1,true);
//fskdemod and get start index //fskdemod and get start index
WDT_HIT(); WDT_HIT();
idx = IOdemodFSK(dest, BigBuf_max_trace_len()); idx = IOdemodFSK(dest, BigBuf_max_traceLen());
if (idx>0){ if (idx>0){
//valid tag found //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 //int m=0, i=0; //enio adjustment 12/10/14
uint32_t m=0, i=0; uint32_t m=0, i=0;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
m = BigBuf_max_trace_len(); m = BigBuf_max_traceLen();
// Clear destination buffer before sending the command // Clear destination buffer before sending the command
memset(dest, 128, m); memset(dest, 128, m);
// Connect the A/D to the peak-detected low-frequency path. // Connect the A/D to the peak-detected low-frequency path.
@ -1030,7 +1026,7 @@ void T55xxReadTrace(void){
int m=0, i=0; int m=0, i=0;
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
m = BigBuf_max_trace_len(); m = BigBuf_max_traceLen();
// Clear destination buffer before sending the command // Clear destination buffer before sending the command
memset(dest, 128, m); memset(dest, 128, m);
// Connect the A/D to the peak-detected low-frequency path. // 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 BitStream[256];
uint8_t Blocks[8][16]; uint8_t Blocks[8][16];
uint8_t *GraphBuffer = BigBuf_get_addr(); 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 i, j, lastval, bitidx, half_switch;
int clock = 64; int clock = 64;
int tolerance = clock / 8; 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_Cmd( FWD_CMD_READ );
fwd_bit_count += Prepare_Addr( Address ); fwd_bit_count += Prepare_Addr( Address );
m = BigBuf_max_trace_len(); m = BigBuf_max_traceLen();
// Clear destination buffer before sending the command // Clear destination buffer before sending the command
memset(dest, 128, m); memset(dest, 128, m);
// Connect the A/D to the peak-detected low-frequency path. // Connect the A/D to the peak-detected low-frequency path.

View file

@ -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 mpcs = {0, 0};
struct Crypto1State *pcs; struct Crypto1State *pcs;
pcs = &mpcs; pcs = &mpcs;
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint32_t auth1_time, auth2_time; uint32_t auth1_time, auth2_time;
static uint16_t delta_time; static uint16_t delta_time;
// free eventually allocated BigBuf memory
BigBuf_free();
// clear trace // clear trace
iso14a_clear_trace(); iso14a_clear_trace();
iso14a_set_tracing(false); 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}; uint8_t d_block[18] = {0x00};
uint32_t cuid; uint32_t cuid;
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// reset FPGA and LED // reset FPGA and LED
if (workFlags & 0x08) { 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}; uint8_t data[18] = {0x00};
uint32_t cuid = 0; uint32_t cuid = 0;
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
if (workFlags & 0x08) { if (workFlags & 0x08) {
LED_A_ON(); LED_A_ON();
@ -1104,8 +1106,8 @@ void MifareCIdent(){
// variables // variables
byte_t isOK = 1; byte_t isOK = 1;
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
ReaderTransmitBitsPar(wupC1,7,0, NULL); ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { 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)); cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout));
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
} }

View file

@ -157,7 +157,7 @@ bool intMfSniffSend() {
while (pckLen > 0) { while (pckLen > 0) {
pckSize = MIN(USB_CMD_DATA_SIZE, pckLen); pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
LED_B_ON(); 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(); LED_B_OFF();
pckLen -= pckSize; pckLen -= pckSize;

View file

@ -21,17 +21,6 @@
int MF_DBGLEVEL = MF_DBG_ALL; 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 // crypto1 helpers
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){
uint8_t bt = 0; 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 uint32_t nt, ntpp; // Supplied tag nonce
uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// Transmit MIFARE_CLASSIC_AUTH // Transmit MIFARE_CLASSIC_AUTH
len = mifare_sendcmd_short(pcs, isNested, 0x60 + (keyType & 0x01), blockNo, receivedAnswer, receivedAnswerPar, timing); 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; int len;
uint8_t bt[2]; uint8_t bt[2];
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// command MIFARE_CLASSIC_READBLOCK // command MIFARE_CLASSIC_READBLOCK
len = mifare_sendcmd_short(pcs, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL); 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){ int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){
uint16_t len; uint16_t len;
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL); len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL);
if (len == 1) { 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){ int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
uint16_t len; uint16_t len;
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL); len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) { if (len == 1) {
@ -353,8 +342,8 @@ int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{ {
uint16_t len; uint16_t len;
uint8_t bt[2]; uint8_t bt[2];
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// command MIFARE_CLASSIC_READBLOCK // command MIFARE_CLASSIC_READBLOCK
@ -392,8 +381,8 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
byte_t res; byte_t res;
uint8_t d_block[18], d_block_enc[18]; uint8_t d_block[18], d_block_enc[18];
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// command MIFARE_CLASSIC_WRITEBLOCK // command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(pcs, 1, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); 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; uint16_t len;
uint8_t par[3] = {0}; // enough for 18 parity bits uint8_t par[3] = {0}; // enough for 18 parity bits
uint8_t d_block[18] = {0x00}; uint8_t d_block[18] = {0x00};
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// command MIFARE_CLASSIC_WRITEBLOCK // command MIFARE_CLASSIC_WRITEBLOCK
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL); 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; uint16_t len;
uint8_t d_block[8] = {0x00}; uint8_t d_block[8] = {0x00};
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// command MIFARE_CLASSIC_WRITEBLOCK // command MIFARE_CLASSIC_WRITEBLOCK
d_block[0]= blockNo; 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) int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
{ {
uint16_t len; uint16_t len;
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL); len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
if (len != 0) { if (len != 0) {
@ -503,8 +492,8 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
int mifare_ultra_halt(uint32_t uid) int mifare_ultra_halt(uint32_t uid)
{ {
uint16_t len; uint16_t len;
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL); len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
if (len != 0) { if (len != 0) {
@ -538,22 +527,22 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo)
// work with emulator memory // work with emulator memory
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) { 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); memcpy(emCARD + blockNum * 16, data, blocksCount * 16);
} }
void emlGetMem(uint8_t *data, int blockNum, int blocksCount) { 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); memcpy(data, emCARD + blockNum * 16, blocksCount * 16);
} }
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) { 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); memcpy(data, emCARD + bytePtr, byteCount);
} }
int emlCheckValBl(int blockNum) { int emlCheckValBl(int blockNum) {
uint8_t* emCARD = get_bigbufptr_emlcardmem(); uint8_t* emCARD = BigBuf_get_EM_addr();
uint8_t* data = emCARD + blockNum * 16; uint8_t* data = emCARD + blockNum * 16;
if ((data[0] != (data[4] ^ 0xff)) || (data[0] != data[8]) || 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) { 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; uint8_t* data = emCARD + blockNum * 16;
if (emlCheckValBl(blockNum)) { 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) { 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; uint8_t* data = emCARD + blockNum * 16;
memcpy(data + 0, &blReg, 4); 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) { uint64_t emlGetKey(int sectorNum, int keyType) {
uint8_t key[6]; 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); memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
return bytes_to_num(key, 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 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}; 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); memset(emCARD, 0, CARD_MEMORY_SIZE);
@ -665,8 +654,8 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){
int len; int len;
// load key, keynumber // load key, keynumber
uint8_t data[2]={0x0a, 0x00}; uint8_t data[2]={0x0a, 0x00};
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL); len = mifare_sendcmd_special(NULL, 1, 0x02, data, receivedAnswer,receivedAnswerPar,NULL);
if (len == 1) { if (len == 1) {
@ -695,8 +684,8 @@ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){
data[0] = 0xAF; data[0] = 0xAF;
memcpy(data+1,key,16); memcpy(data+1,key,16);
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar ,NULL); len = mifare_sendcmd_special2(NULL, 1, 0x03, data, receivedAnswer, receivedAnswerPar ,NULL);

View file

@ -53,7 +53,6 @@ extern int MF_DBGLEVEL;
#define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF(); #define cardSTATE_TO_IDLE() cardSTATE = MFEMUL_IDLE; LED_B_OFF(); LED_C_OFF();
//functions //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(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); 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); 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); 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 // Mifare memory structure
uint8_t NumBlocksPerSector(uint8_t sectorNo); uint8_t NumBlocksPerSector(uint8_t sectorNo);
uint8_t FirstBlockOfSector(uint8_t sectorNo); uint8_t FirstBlockOfSector(uint8_t sectorNo);

View file

@ -1426,7 +1426,7 @@ int CmdHexsamples(const char *Cmd)
int offset = 0; int offset = 0;
char string_buf[25]; char string_buf[25];
char* string_ptr = string_buf; char* string_ptr = string_buf;
uint8_t got[40000]; uint8_t got[BIGBUF_SIZE];
sscanf(Cmd, "%i %i", &requested, &offset); sscanf(Cmd, "%i %i", &requested, &offset);
@ -1435,7 +1435,7 @@ int CmdHexsamples(const char *Cmd)
requested = 8; requested = 8;
} }
if (offset + requested > sizeof(got)) { if (offset + requested > sizeof(got)) {
PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000"); PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > %d", BIGBUF_SIZE);
return 0; return 0;
} }
@ -1485,7 +1485,7 @@ int CmdHpf(const char *Cmd)
int CmdSamples(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); int n = strtol(Cmd, NULL, 0);
if (n == 0) if (n == 0)
@ -1495,14 +1495,14 @@ int CmdSamples(const char *Cmd)
n = sizeof(got); n = sizeof(got);
PrintAndLog("Reading %d samples from device memory\n", n); PrintAndLog("Reading %d samples from device memory\n", n);
GetFromBigBuf(got,n,0); GetFromBigBuf(got,n,0);
WaitForResponse(CMD_ACK,NULL); WaitForResponse(CMD_ACK,NULL);
for (int j = 0; j < n; j++) { for (int j = 0; j < n; j++) {
GraphBuffer[j] = ((int)got[j]) - 128; GraphBuffer[j] = ((int)got[j]) - 128;
} }
GraphTraceLen = n; GraphTraceLen = n;
RepaintGraphWindow(); RepaintGraphWindow();
return 0; return 0;
} }
int CmdTuneSamples(const char *Cmd) int CmdTuneSamples(const char *Cmd)

View file

@ -60,4 +60,6 @@ int CmdIndalaDecode(const char *Cmd);
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN]; extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
extern int DemodBufferLen; extern int DemodBufferLen;
#define BIGBUF_SIZE 40000
#endif #endif

View file

@ -32,8 +32,6 @@ int CmdHFTune(const char *Cmd)
SendCommand(&c); SendCommand(&c);
return 0; 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 //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; bool isResponse;
uint16_t duration, data_len,parity_len; uint16_t duration, data_len, parity_len;
uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp; uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp;
char explanation[30] = {0}; char explanation[30] = {0};
if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
first_timestamp = *((uint32_t *)(trace)); first_timestamp = *((uint32_t *)(trace));
timestamp = *((uint32_t *)(trace + tracepos)); 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; tracepos += 4;
duration = *((uint16_t *)(trace + tracepos)); 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; parity_len = (data_len-1)/8 + 1;
if (tracepos + data_len + parity_len >= TRACE_SIZE) { if (tracepos + data_len + parity_len > traceLen) {
return TRACE_SIZE; return traceLen;
} }
uint8_t *frame = trace + tracepos; 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; bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
if (showWaitCycles && !isResponse && next_isResponse) { 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)); (next_timestamp - EndOfTransmissionTimestamp));
} }
} }
return tracepos; return tracepos;
} }
int CmdHFList(const char *Cmd) int CmdHFList(const char *Cmd)
{ {
bool showWaitCycles = false; bool showWaitCycles = false;
@ -570,12 +572,28 @@ int CmdHFList(const char *Cmd)
} }
uint8_t trace[TRACE_SIZE]; uint8_t *trace;
uint16_t tracepos = 0; uint16_t tracepos = 0;
GetFromBigBuf(trace, TRACE_SIZE, 0); trace = malloc(USB_CMD_DATA_SIZE);
WaitForResponse(CMD_ACK, NULL);
PrintAndLog("Recorded Activity"); // 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("");
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); 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)"); 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(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |");
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|"); 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; return 0;
} }

View file

@ -145,11 +145,25 @@ demodError:
int CmdHF14BList(const char *Cmd) int CmdHF14BList(const char *Cmd)
{ {
uint8_t got[TRACE_BUFFER_SIZE]; uint8_t *got = malloc(USB_CMD_DATA_SIZE);
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
PrintAndLog("recorded activity:"); // 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(" time :rssi: who bytes");
PrintAndLog("---------+----+----+-----------"); PrintAndLog("---------+----+----+-----------");
@ -158,7 +172,7 @@ int CmdHF14BList(const char *Cmd)
for(;;) { for(;;) {
if(i >= TRACE_BUFFER_SIZE) { break; } if(i >= traceLen) { break; }
bool isResponse; bool isResponse;
int timestamp = *((uint32_t *)(got+i)); int timestamp = *((uint32_t *)(got+i));
@ -175,7 +189,7 @@ int CmdHF14BList(const char *Cmd)
if(len > 100) { if(len > 100) {
break; break;
} }
if(i + len >= TRACE_BUFFER_SIZE) { if(i + len >= traceLen) {
break; break;
} }
@ -218,6 +232,7 @@ int CmdHF14BList(const char *Cmd)
prev = timestamp; prev = timestamp;
i += (len + 9); i += (len + 9);
} }
free(got);
return 0; return 0;
} }

View file

@ -1765,15 +1765,16 @@ int CmdHF14AMfSniff(const char *Cmd){
int res = 0; int res = 0;
int len = 0; int len = 0;
int blockLen = 0; int blockLen = 0;
int num = 0;
int pckNum = 0; int pckNum = 0;
uint8_t uid[7] = {0x00}; int num = 0;
uint8_t uid[7];
uint8_t uid_len; uint8_t uid_len;
uint8_t atqa[2] = {0x00}; uint8_t atqa[2] = {0x00};
uint8_t sak; uint8_t sak;
bool isTag; bool isTag;
uint8_t buf[3000] = {0x00}; uint8_t *buf = NULL;
uint8_t * bufPtr = buf; uint16_t bufsize = 0;
uint8_t *bufPtr = NULL;
char ctmp = param_getchar(Cmd, 0); char ctmp = param_getchar(Cmd, 0);
if ( ctmp == 'h' || ctmp == 'H' ) { if ( ctmp == 'h' || ctmp == 'H' ) {
@ -1816,32 +1817,47 @@ int CmdHF14AMfSniff(const char *Cmd){
break; break;
} }
UsbCommand resp; UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) { if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
res = resp.arg[0] & 0xff; res = resp.arg[0] & 0xff;
len = resp.arg[1]; uint16_t traceLen = resp.arg[1];
num = resp.arg[2]; len = resp.arg[2];
if (res == 0) return 0; if (res == 0) return 0; // we are done
if (res == 1) {
if (num ==0) { 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; bufPtr = buf;
memset(buf, 0x00, 3000); bufsize = traceLen;
memset(buf, 0x00, traceLen);
} }
memcpy(bufPtr, resp.d.asBytes, len); memcpy(bufPtr, resp.d.asBytes, len);
bufPtr += len; bufPtr += len;
pckNum++; pckNum++;
} }
if (res == 2) {
if (res == 2) { // received all data, start displaying
blockLen = bufPtr - buf; blockLen = bufPtr - buf;
bufPtr = buf; bufPtr = buf;
printf(">\n"); printf(">\n");
PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum); PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);
num = 0;
while (bufPtr - buf < blockLen) { while (bufPtr - buf < blockLen) {
bufPtr += 6; bufPtr += 6; // skip (void) timing information
len = *((uint16_t *)bufPtr); len = *((uint16_t *)bufPtr);
if(len & 0x8000) { if(len & 0x8000) {
isTag = true; isTag = true;
len &= 0x7fff; len &= 0x7fff;
@ -1850,12 +1866,10 @@ int CmdHF14AMfSniff(const char *Cmd){
} }
bufPtr += 2; bufPtr += 2;
if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) { if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) {
memcpy(uid, bufPtr + 2, 7); memcpy(uid, bufPtr + 2, 7);
memcpy(atqa, bufPtr + 2 + 7, 2); memcpy(atqa, bufPtr + 2 + 7, 2);
uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4; uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4;
sak = bufPtr[11]; sak = bufPtr[11];
PrintAndLog("tag select uid:%s atqa:0x%02x%02x sak:0x%02x", PrintAndLog("tag select uid:%s atqa:0x%02x%02x sak:0x%02x",
sprint_hex(uid + (7 - uid_len), uid_len), sprint_hex(uid + (7 - uid_len), uid_len),
atqa[1], atqa[1],
@ -1873,18 +1887,21 @@ int CmdHF14AMfSniff(const char *Cmd){
AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len); AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);
if (wantDecrypt) if (wantDecrypt)
mfTraceDecode(bufPtr, len, wantSaveToEmlFile); mfTraceDecode(bufPtr, len, wantSaveToEmlFile);
num++;
} }
bufPtr += len; bufPtr += len;
bufPtr += ((len-1)/8+1); // ignore parity bufPtr += ((len-1)/8+1); // ignore parity
num++;
} }
pckNum = 0;
} }
} // resp not NULL } // resp not NULL
} // while (true) } // while (true)
free(buf);
return 0; return 0;
} }
static command_t CommandTable[] = static command_t CommandTable[] =
{ {
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},

View file

@ -29,110 +29,125 @@ size_t nbytes(size_t nbits) {
int CmdLFHitagList(const char *Cmd) int CmdLFHitagList(const char *Cmd)
{ {
uint8_t got[TRACE_BUFFER_SIZE]; uint8_t *got = malloc(USB_CMD_DATA_SIZE);
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
PrintAndLog("recorded activity:"); // Query for the actual size of the trace
PrintAndLog(" ETU :nbits: who bytes"); UsbCommand response;
PrintAndLog("---------+-----+----+-----------"); GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
WaitForResponse(CMD_ACK, &response);
int i = 0; uint16_t traceLen = response.arg[2];
int prev = -1; if (traceLen > USB_CMD_DATA_SIZE) {
int len = strlen(Cmd); uint8_t *p = realloc(got, traceLen);
if (p == NULL) {
char filename[FILE_PATH_SIZE] = { 0x00 }; PrintAndLog("Cannot allocate memory for trace");
FILE* pf = NULL; free(got);
return 2;
if (len > FILE_PATH_SIZE) }
len = FILE_PATH_SIZE; got = p;
memcpy(filename, Cmd, len); GetFromBigBuf(got, traceLen, 0);
WaitForResponse(CMD_ACK,NULL);
if (strlen(filename) > 0) {
if ((pf = fopen(filename,"wb")) == NULL) {
PrintAndLog("Error: Could not open file [%s]",filename);
return 1;
} }
}
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;
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]);
}
}
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; PrintAndLog("recorded activity (TraceLen = %d bytes):");
i += (len + 9); PrintAndLog(" ETU :nbits: who bytes");
} PrintAndLog("---------+-----+----+-----------");
if (pf) {
fclose(pf);
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
}
return 0; int i = 0;
int prev = -1;
int len = strlen(Cmd);
char filename[FILE_PATH_SIZE] = { 0x00 };
FILE* pf = NULL;
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;
}
}
for (;;) {
if(i > traceLen) { 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 > 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]);
}
}
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);
}
free(got);
return 0;
} }
int CmdLFHitagSnoop(const char *Cmd) { int CmdLFHitagSnoop(const char *Cmd) {

View file

@ -188,7 +188,6 @@ void UsbCommandReceived(UsbCommand *UC)
} break; } break;
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: { 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]); memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
} break; } break;

View file

@ -16,11 +16,9 @@
#include "cmdmain.h" #include "cmdmain.h"
uint8_t* sample_buf; uint8_t* sample_buf;
size_t sample_buf_len;
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index) void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
{ {
sample_buf_len = 0;
sample_buf = dest; sample_buf = dest;
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}}; UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
SendCommand(&c); SendCommand(&c);

View file

@ -13,13 +13,9 @@
#include <stdint.h> #include <stdint.h>
//trace buffer size as defined in armsrc/apps.h TRACE_SIZE
#define TRACE_BUFFER_SIZE 4096
#define FILE_PATH_SIZE 1000 #define FILE_PATH_SIZE 1000
#define SAMPLE_BUFFER_SIZE 64
extern uint8_t* sample_buf; extern uint8_t* sample_buf;
extern size_t sample_buf_len;
#define arraylen(x) (sizeof(x)/sizeof((x)[0])) #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index); void GetFromBigBuf(uint8_t *dest, int bytes, int start_index);

View file

@ -14,8 +14,8 @@
typedef enum { typedef enum {
RHT2F_PASSWORD = 21, RHT2F_PASSWORD = 21,
RHT2F_AUTHENTICATE = 22, RHT2F_AUTHENTICATE = 22,
RHT2F_CRYPTO = 23, RHT2F_CRYPTO = 23,
RHT2F_TEST_AUTH_ATTEMPTS = 25, RHT2F_TEST_AUTH_ATTEMPTS = 25,
} hitag_function; } hitag_function;
typedef struct { typedef struct {
@ -33,7 +33,7 @@ typedef struct {
typedef union { typedef union {
rht2d_password pwd; rht2d_password pwd;
rht2d_authenticate auth; rht2d_authenticate auth;
rht2d_crypto crypto; rht2d_crypto crypto;
} hitag_data; } hitag_data;
#endif #endif