From 80fe72357062b8c5b22936d84e46e9b2c1e4b6e2 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sun, 18 Jan 2015 20:21:53 +0100 Subject: [PATCH 01/13] Generic trace pt1: Moved arm-side trace functionality into util-package --- armsrc/iso14443a.c | 54 ----------------------------------------- armsrc/util.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 54 deletions(-) diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index d326be2c5..f5348e775 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -199,60 +199,6 @@ void AppendCrc14443a(uint8_t* data, int len) ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1); } -// The function LogTrace() is also used by the iClass implementation in iClass.c -bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) -{ - if (!tracing) return FALSE; - - uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity - 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) { - tracing = FALSE; // don't trace any more - return FALSE; - } - - // Traceformat: - // 32 bits timestamp (little endian) - // 16 bits duration (little endian) - // 16 bits data length (little endian, Highest Bit used as readerToTag flag) - // y Bytes data - // x Bytes parity (one byte per 8 bytes data) - - // timestamp (start) - trace[traceLen++] = ((timestamp_start >> 0) & 0xff); - trace[traceLen++] = ((timestamp_start >> 8) & 0xff); - trace[traceLen++] = ((timestamp_start >> 16) & 0xff); - trace[traceLen++] = ((timestamp_start >> 24) & 0xff); - - // duration - trace[traceLen++] = ((duration >> 0) & 0xff); - trace[traceLen++] = ((duration >> 8) & 0xff); - - // data length - trace[traceLen++] = ((iLen >> 0) & 0xff); - trace[traceLen++] = ((iLen >> 8) & 0xff); - - // readerToTag flag - if (!readerToTag) { - trace[traceLen - 1] |= 0x80; - } - - // data bytes - if (btBytes != NULL && iLen != 0) { - memcpy(trace + traceLen, btBytes, iLen); - } - traceLen += iLen; - - // parity bytes - if (parity != NULL && iLen != 0) { - memcpy(trace + traceLen, parity, num_paritybytes); - } - traceLen += num_paritybytes; - - return TRUE; -} //============================================================================= // ISO 14443 Type A - Miller decoder diff --git a/armsrc/util.c b/armsrc/util.c index 674f1b91f..cce9bed80 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -428,4 +428,64 @@ uint32_t RAMFUNC GetCountSspClk(){ } } +/** + This is a function to store traces. All protocols can use this generic tracer-function. + The traces produced by calling this function can be fetched on the client-side + by 'hf list raw', alternatively 'hf list ' for protocol-specific + annotation of commands/responses. + +**/ +bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) +{ + if (!tracing) return FALSE; + + uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity + 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) { + tracing = FALSE; // don't trace any more + return FALSE; + } + + // Traceformat: + // 32 bits timestamp (little endian) + // 16 bits duration (little endian) + // 16 bits data length (little endian, Highest Bit used as readerToTag flag) + // y Bytes data + // x Bytes parity (one byte per 8 bytes data) + + // timestamp (start) + trace[traceLen++] = ((timestamp_start >> 0) & 0xff); + trace[traceLen++] = ((timestamp_start >> 8) & 0xff); + trace[traceLen++] = ((timestamp_start >> 16) & 0xff); + trace[traceLen++] = ((timestamp_start >> 24) & 0xff); + + // duration + trace[traceLen++] = ((duration >> 0) & 0xff); + trace[traceLen++] = ((duration >> 8) & 0xff); + + // data length + trace[traceLen++] = ((iLen >> 0) & 0xff); + trace[traceLen++] = ((iLen >> 8) & 0xff); + + // readerToTag flag + if (!readerToTag) { + trace[traceLen - 1] |= 0x80; + } + + // data bytes + if (btBytes != NULL && iLen != 0) { + memcpy(trace + traceLen, btBytes, iLen); + } + traceLen += iLen; + + // parity bytes + if (parity != NULL && iLen != 0) { + memcpy(trace + traceLen, parity, num_paritybytes); + } + traceLen += num_paritybytes; + + return TRUE; +} From 355c8b4a7df083c13d82963fb9d14548647e91b1 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sun, 18 Jan 2015 20:23:58 +0100 Subject: [PATCH 02/13] Generic trace pt2: made iso14443b use standard trace format --- armsrc/iso14443.c | 102 ++++++++++++++++++++++++--------------------- armsrc/iso14443a.c | 8 ---- armsrc/iso14443a.h | 3 -- armsrc/util.c | 16 +++++++ armsrc/util.h | 9 ++++ 5 files changed, 80 insertions(+), 58 deletions(-) diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index e9483189d..4d7d4fa8f 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -618,7 +618,7 @@ static RAMFUNC int Handle14443SamplesDemod(int ci, int cq) } /* - * Demodulate the samples we received from the tag + * Demodulate the samples we received from the tag, also log to tracebuffer * weTx: set to 'TRUE' if we behave like a reader * set to 'FALSE' if we behave like a snooper * quiet: set to 'TRUE' to disable debug output @@ -698,6 +698,12 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) } AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; if (!quiet) Dbprintf("%x %x %x", max, gotFrame, Demod.len); + //Tracing + if (tracing && Demod.len > 0) { + uint8_t parity[MAX_PARITY_SIZE]; + GetParity(Demod.output , Demod.len, parity); + LogTrace(Demod.output,Demod.len, 0, 0, parity, FALSE); + } } //----------------------------------------------------------------------------- @@ -853,6 +859,20 @@ void AcquireRawAdcSamplesIso14443(uint32_t parameter) SendRawCommand14443B(sizeof(cmd1),1,1,cmd1); } +/** + Convenience function to encode, transmit and trace iso 14443b comms + **/ +static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) +{ + CodeIso14443bAsReader(cmd, len); + TransmitFor14443(); + if (tracing) { + uint8_t parity[MAX_PARITY_SIZE]; + GetParity(cmd, len, parity); + LogTrace(cmd,len, 0, 0, parity, TRUE); + } +} + //----------------------------------------------------------------------------- // Read a SRI512 ISO 14443 tag. // @@ -864,6 +884,9 @@ void AcquireRawAdcSamplesIso14443(uint32_t parameter) //----------------------------------------------------------------------------- void ReadSTMemoryIso14443(uint32_t dwLast) { + clear_trace(); + set_tracing(TRUE); + uint8_t i = 0x00; FpgaDownloadAndGo(FPGA_BITSTREAM_HF); @@ -885,8 +908,8 @@ void ReadSTMemoryIso14443(uint32_t dwLast) // First command: wake up the tag using the INITIATE command uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b}; - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); + + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); // LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); @@ -903,8 +926,8 @@ void ReadSTMemoryIso14443(uint32_t dwLast) cmd1[0] = 0x0E; // 0x0E is SELECT cmd1[1] = Demod.output[0]; ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); + // LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); @@ -927,8 +950,8 @@ void ReadSTMemoryIso14443(uint32_t dwLast) // First get the tag's UID: cmd1[0] = 0x0B; ComputeCrc14443(CRC_14443_B, cmd1, 1 , &cmd1[1], &cmd1[2]); - CodeIso14443bAsReader(cmd1, 3); // Only first three bytes for this one - TransmitFor14443(); + CodeAndTransmit14443bAsReader(cmd1, 3); // Only first three bytes for this one + // LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); @@ -959,8 +982,8 @@ void ReadSTMemoryIso14443(uint32_t dwLast) } cmd1[1] = i; ComputeCrc14443(CRC_14443_B, cmd1, 2, &cmd1[2], &cmd1[3]); - CodeIso14443bAsReader(cmd1, sizeof(cmd1)); - TransmitFor14443(); + CodeAndTransmit14443bAsReader(cmd1, sizeof(cmd1)); + // LED_A_ON(); GetSamplesFor14443Demod(TRUE, 2000,TRUE); // LED_A_OFF(); @@ -1097,20 +1120,15 @@ void RAMFUNC SnoopIso14443(void) samples += 2; #define HANDLE_BIT_IF_BODY \ - if(triggered) { \ - trace[traceLen++] = ((samples >> 0) & 0xff); \ - trace[traceLen++] = ((samples >> 8) & 0xff); \ - trace[traceLen++] = ((samples >> 16) & 0xff); \ - trace[traceLen++] = ((samples >> 24) & 0xff); \ - trace[traceLen++] = 0; \ - trace[traceLen++] = 0; \ - trace[traceLen++] = 0; \ - trace[traceLen++] = 0; \ - trace[traceLen++] = Uart.byteCnt; \ - memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); \ - traceLen += Uart.byteCnt; \ - if(traceLen > 1000) break; \ - } \ + if(triggered && tracing) {\ + uint8_t parity[MAX_PARITY_SIZE];\ + GetParity(receivedCmd, Uart.byteCnt, parity);\ + LogTrace(receivedCmd,Uart.byteCnt,samples, samples,parity,TRUE);\ + if(!tracing) {\ + DbpString("Reached trace limit");\ + break;\ + }\ + }\ /* And ready to receive another command. */ \ memset(&Uart, 0, sizeof(Uart)); \ Uart.output = receivedCmd; \ @@ -1130,28 +1148,18 @@ void RAMFUNC SnoopIso14443(void) } if(Handle14443SamplesDemod(ci, cq)) { - // timestamp, as a count of samples - trace[traceLen++] = ((samples >> 0) & 0xff); - trace[traceLen++] = ((samples >> 8) & 0xff); - trace[traceLen++] = ((samples >> 16) & 0xff); - trace[traceLen++] = 0x80 | ((samples >> 24) & 0xff); - // correlation metric (~signal strength estimate) - if(Demod.metricN != 0) { - Demod.metric /= Demod.metricN; - } - trace[traceLen++] = ((Demod.metric >> 0) & 0xff); - trace[traceLen++] = ((Demod.metric >> 8) & 0xff); - trace[traceLen++] = ((Demod.metric >> 16) & 0xff); - trace[traceLen++] = ((Demod.metric >> 24) & 0xff); - // length - trace[traceLen++] = Demod.len; - memcpy(trace+traceLen, receivedResponse, Demod.len); - traceLen += Demod.len; - if(traceLen > DEMOD_TRACE_SIZE) { - DbpString("Reached trace limit"); - goto done; - } + //Use samples as a time measurement + if(tracing) + { + uint8_t parity[MAX_PARITY_SIZE]; + GetParity(receivedResponse, Demod.len, parity); + LogTrace(receivedResponse,Demod.len,samples, samples,parity,FALSE); + if(!tracing) { + DbpString("Reached trace limit"); + break; + } + } triggered = TRUE; LED_A_OFF(); LED_B_ON(); @@ -1175,7 +1183,7 @@ done: LED_C_OFF(); 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); @@ -1220,8 +1228,8 @@ void SendRawCommand14443B(uint32_t datalen, uint32_t recv,uint8_t powerfield, ui SpinDelay(200); } - CodeIso14443bAsReader(data, datalen); - TransmitFor14443(); + CodeAndTransmit14443bAsReader(data, datalen); + if(recv) { uint16_t iLen = MIN(Demod.len,USB_CMD_DATA_SIZE); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index f5348e775..d91b24d76 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -148,14 +148,6 @@ void iso14a_set_trigger(bool enable) { trigger = enable; } -void iso14a_clear_trace() { - memset(trace, 0x44, TRACE_SIZE); - traceLen = 0; -} - -void iso14a_set_tracing(bool enable) { - tracing = enable; -} void iso14a_set_timeout(uint32_t timeout) { iso14a_timeout = timeout; diff --git a/armsrc/iso14443a.h b/armsrc/iso14443a.h index c595d5e12..c37103886 100644 --- a/armsrc/iso14443a.h +++ b/armsrc/iso14443a.h @@ -87,7 +87,4 @@ extern int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *resp_da extern void iso14a_set_trigger(bool enable); extern void iso14a_set_timeout(uint32_t timeout); -extern void iso14a_clear_trace(); -extern void iso14a_set_tracing(bool enable); - #endif /* __ISO14443A_H */ diff --git a/armsrc/util.c b/armsrc/util.c index cce9bed80..a4f558794 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -427,6 +427,22 @@ uint32_t RAMFUNC GetCountSspClk(){ return tmp_count; } } +void iso14a_clear_trace() { + clear_trace(); +} + +void iso14a_set_tracing(bool enable) { + set_tracing(enable); +} + +void clear_trace() { + memset(trace, 0x44, TRACE_SIZE); + traceLen = 0; +} + +void set_tracing(bool enable) { + tracing = enable; +} /** This is a function to store traces. All protocols can use this generic tracer-function. diff --git a/armsrc/util.h b/armsrc/util.h index d7eacd705..141d74b9d 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -43,6 +43,15 @@ void LEDsoff(); int BUTTON_CLICKED(int ms); int BUTTON_HELD(int ms); void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information); +// @deprecated +void iso14a_clear_trace(); +// @deprecated +void iso14a_set_tracing(bool enable); +void clear_trace(); +void set_tracing(bool enable); + +// The function LogTrace() is also used by the iClass implementation in iclass.c and both iso14443a, iso14443b and mifare +bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); void StartTickCount(); uint32_t RAMFUNC GetTickCount(); From 9e8255d4e99eb2917df13be92402e75a73417696 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Wed, 21 Jan 2015 23:53:40 +0100 Subject: [PATCH 03/13] Generic tracing pt.3 : reworking how iso14443b-traces are stored in ARM-memory --- armsrc/appmain.c | 2 +- armsrc/iso14443.c | 18 +++++++----------- armsrc/iso14443a.c | 3 --- armsrc/util.c | 9 ++++++++- client/cmdhf.c | 24 ++++++++++++++++-------- 5 files changed, 32 insertions(+), 24 deletions(-) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 530dc39cd..bca31533d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -986,7 +986,7 @@ void UsbPacketReceived(uint8_t *packet, int len) void __attribute__((noreturn)) AppMain(void) { SpinDelay(100); - + clear_trace(); if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) { /* Initialize common area */ memset(&common_area, 0, sizeof(common_area)); diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index 4d7d4fa8f..3c8e1fdda 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -628,30 +628,26 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) int max = 0; int gotFrame = FALSE; -//# define DMA_BUFFER_SIZE 8 - int8_t *dmaBuf; - int lastRxCounter; - int8_t *upTo; int ci, cq; int samples = 0; // Clear out the state of the "UART" that receives from the tag. - memset(BigBuf, 0x00, 400); - Demod.output = (uint8_t *)BigBuf; + memset(Demod.output, 0x00, MAX_FRAME_SIZE); + Demod.output = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; Demod.len = 0; Demod.state = DEMOD_UNSYNCD; // And the UART that receives from the reader - Uart.output = (((uint8_t *)BigBuf) + 1024); - Uart.byteCntMax = 100; + Uart.output = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; + Uart.byteCntMax = MAX_FRAME_SIZE; Uart.state = STATE_UNSYNCD; - // Setup for the DMA. - dmaBuf = (int8_t *)(BigBuf + 32); - upTo = dmaBuf; + // The DMA buffer, used to stream samples from the FPGA + int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET; + int8_t *upTo= dmaBuf; lastRxCounter = DEMOD_DMA_BUFFER_SIZE; FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE); diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index d91b24d76..54c1db407 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -22,10 +22,7 @@ #include "mifareutil.h" static uint32_t iso14a_timeout; -uint8_t *trace = (uint8_t *) BigBuf+TRACE_OFFSET; int rsamples = 0; -int traceLen = 0; -int tracing = TRUE; uint8_t trigger = 0; // the block number for the ISO14443-4 PCB static uint8_t iso14_pcb_blocknum = 0; diff --git a/armsrc/util.c b/armsrc/util.c index a4f558794..38f417507 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -13,6 +13,9 @@ #include "string.h" #include "apps.h" +uint8_t *trace = (uint8_t *) BigBuf+TRACE_OFFSET; +int traceLen = 0; +int tracing = TRUE; void print_result(char *name, uint8_t *buf, size_t len) { @@ -463,7 +466,6 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ tracing = FALSE; // don't trace any more return FALSE; } - // Traceformat: // 32 bits timestamp (little endian) // 16 bits duration (little endian) @@ -502,6 +504,11 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ } traceLen += num_paritybytes; + if(traceLen +4 < TRACE_SIZE) + { //If it hadn't been cleared, for whatever reason.. + memset(trace+traceLen,0x44, 4); + } + return TRUE; } diff --git a/client/cmdhf.c b/client/cmdhf.c index 9acc9825b..373668027 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -413,15 +413,18 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo if (tracepos + data_len + parity_len >= TRACE_SIZE) { return TRACE_SIZE; } - uint8_t *frame = trace + tracepos; tracepos += data_len; uint8_t *parityBytes = trace + tracepos; tracepos += parity_len; + //--- Draw the data column + //char line[16][110]; char line[16][110]; - for (int j = 0; j < data_len; j++) { + + for (int j = 0; j < data_len && j/16 < 16; j++) { + int oddparity = 0x01; int k; @@ -430,11 +433,17 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo } uint8_t parityBits = parityBytes[j>>3]; - if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) { - sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]); + snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]); + } else { - sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]); + snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]); + } + } + if(data_len == 0) + { + if(data_len == 0){ + sprintf(line[0],""); } } //--- Draw the CRC column @@ -479,8 +488,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo annotateIso14443b(explanation,sizeof(explanation),frame,data_len); } - int num_lines = (data_len - 1)/16 + 1; - for (int j = 0; j < num_lines; j++) { + int num_lines = MIN((data_len - 1)/16 + 1, 16); + for (int j = 0; j < num_lines ; j++) { if (j == 0) { PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s", (timestamp - first_timestamp), @@ -573,7 +582,6 @@ int CmdHFList(const char *Cmd) uint16_t tracepos = 0; GetFromBigBuf(trace, TRACE_SIZE, 0); WaitForResponse(CMD_ACK, NULL); - PrintAndLog("Recorded Activity"); PrintAndLog(""); PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer"); From 388c92bde5f597677b3cc34c5ace425e7074bc9e Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 22 Jan 2015 00:19:20 +0100 Subject: [PATCH 04/13] Generic tracing pt.4: Deprecated old 'hf 14b list' command --- client/cmdhf14b.c | 79 ++--------------------------------------------- 1 file changed, 3 insertions(+), 76 deletions(-) diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index e3d0fc230..3aaf45fa8 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -145,82 +145,9 @@ demodError: int CmdHF14BList(const char *Cmd) { - uint8_t got[TRACE_BUFFER_SIZE]; - GetFromBigBuf(got,sizeof(got),0); - WaitForResponse(CMD_ACK,NULL); - - PrintAndLog("recorded activity:"); - PrintAndLog(" time :rssi: who bytes"); - PrintAndLog("---------+----+----+-----------"); - - int i = 0; - int prev = -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 metric = *((uint32_t *)(got+i+4)); - - int len = 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[2] == 0x44 && frame[3] == 0x44) break; - - char line[1000] = ""; - int j; - for(j = 0; j < len; j++) { - sprintf(line+(j*3), "%02x ", frame[j]); - } - - char *crc; - if(len > 2) { - uint8_t b1, b2; - ComputeCrc14443(CRC_14443_B, frame, len-2, &b1, &b2); - if(b1 != frame[len-2] || b2 != frame[len-1]) { - crc = "**FAIL CRC**"; - } else { - crc = ""; - } - } else { - crc = "(SHORT)"; - } - - char metricString[100]; - if(isResponse) { - sprintf(metricString, "%3d", metric); - } else { - strcpy(metricString, " "); - } - - PrintAndLog(" +%7d: %s: %s %s %s", - (prev < 0 ? 0 : timestamp - prev), - metricString, - (isResponse ? "TAG" : " "), line, crc); - - prev = timestamp; - i += (len + 9); - } - return 0; + PrintAndLog("Deprecated command, use 'hf list 14b' instead"); + return 0; } - int CmdHF14BRead(const char *Cmd) { UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443, {strtol(Cmd, NULL, 0), 0, 0}}; @@ -458,7 +385,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"demod", CmdHF14BDemod, 1, "Demodulate ISO14443 Type B from tag"}, - {"list", CmdHF14BList, 0, "List ISO 14443 history"}, + {"list", CmdHF14BList, 0, "[Deprecated] List ISO 14443b history"}, {"read", CmdHF14BRead, 0, "Read HF tag (ISO 14443)"}, {"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"}, {"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"}, From 3fd26a683ddc9e166392f722c23ab21fb618ce08 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Thu, 22 Jan 2015 00:33:49 +0100 Subject: [PATCH 05/13] On another note; a nice udev-rule to have pm3 appear as /dev/pm3-1 (or /dev/pm3-2 if you have multiple) --- driver/77-mm-usb-device-blacklist.rules | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/driver/77-mm-usb-device-blacklist.rules b/driver/77-mm-usb-device-blacklist.rules index 986c94461..80086f49c 100644 --- a/driver/77-mm-usb-device-blacklist.rules +++ b/driver/77-mm-usb-device-blacklist.rules @@ -7,4 +7,12 @@ # # proxmark3 +ACTION!="add|change", GOTO="mm_usb_device_blacklist_end" +SUBSYSTEM!="tty", GOTO="mm_ignore" + +ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" SYMLINK+="pm3-%n" + +LABEL="mm_ignore" ATTRS{idVendor}=="2d2d" ATTRS{idProduct}=="504d", ENV{ID_MM_DEVICE_IGNORE}="1" + +LABEL="mm_usb_device_blacklist_end" From aeadbdb216f3901ffe9d6ae766aebe43ac244853 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 26 Jan 2015 22:10:05 +0100 Subject: [PATCH 06/13] Generic tracing: Some fixes in iso14443b snooping, to how DMA access is performed, sizes and buffers. --- armsrc/iso14443.c | 183 ++++++++++++++++++++++------------------------ 1 file changed, 88 insertions(+), 95 deletions(-) diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index 3c8e1fdda..0a6d2d67f 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -19,11 +19,11 @@ //static void GetSamplesFor14443(int weTx, int n); -#define DEMOD_TRACE_SIZE 4096 +/*#define DEMOD_TRACE_SIZE 4096 #define READER_TAG_BUFFER_SIZE 2048 #define TAG_READER_BUFFER_SIZE 2048 #define DEMOD_DMA_BUFFER_SIZE 1024 - +*/ //============================================================================= // An ISO 14443 Type B tag. We listen for commands from the reader, using // a UART kind of thing that's implemented in software. When we get a @@ -617,6 +617,24 @@ static RAMFUNC int Handle14443SamplesDemod(int ci, int cq) return FALSE; } +static void DemodReset() +{ + // Clear out the state of the "UART" that receives from the tag. + Demod.output = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; + Demod.len = 0; + Demod.state = DEMOD_UNSYNCD; + memset(Demod.output, 0x00, MAX_FRAME_SIZE); + +} + +static void UartReset() +{ + // And the UART that receives from the reader + Uart.output = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; + Uart.byteCntMax = MAX_FRAME_SIZE; + Uart.state = STATE_UNSYNCD; +} + /* * Demodulate the samples we received from the tag, also log to tracebuffer * weTx: set to 'TRUE' if we behave like a reader @@ -634,22 +652,14 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) int samples = 0; - // Clear out the state of the "UART" that receives from the tag. - memset(Demod.output, 0x00, MAX_FRAME_SIZE); - Demod.output = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; - Demod.len = 0; - Demod.state = DEMOD_UNSYNCD; - - // And the UART that receives from the reader - Uart.output = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; - Uart.byteCntMax = MAX_FRAME_SIZE; - Uart.state = STATE_UNSYNCD; + DemodReset(); + UartReset(); // The DMA buffer, used to stream samples from the FPGA int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET; int8_t *upTo= dmaBuf; - lastRxCounter = DEMOD_DMA_BUFFER_SIZE; - FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE); + lastRxCounter = DMA_BUFFER_SIZE; + FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); // Signal field is ON with the appropriate LED: if (weTx) LED_D_ON(); else LED_D_OFF(); @@ -662,20 +672,20 @@ static void GetSamplesFor14443Demod(int weTx, int n, int quiet) int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR; if(behindBy > max) max = behindBy; - while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DEMOD_DMA_BUFFER_SIZE-1)) + while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1)) > 2) { ci = upTo[0]; cq = upTo[1]; upTo += 2; - if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) { - upTo -= DEMOD_DMA_BUFFER_SIZE; + if(upTo - dmaBuf > DMA_BUFFER_SIZE) { + upTo -= DMA_BUFFER_SIZE; AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; - AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; } lastRxCounter -= 2; if(lastRxCounter <= 0) { - lastRxCounter += DEMOD_DMA_BUFFER_SIZE; + lastRxCounter += DMA_BUFFER_SIZE; } samples += 2; @@ -1031,18 +1041,18 @@ void RAMFUNC SnoopIso14443(void) int triggered = TRUE; FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - // The command (reader -> tag) that we're working on receiving. - uint8_t *receivedCmd = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE; - // The response (tag -> reader) that we're working on receiving. - uint8_t *receivedResponse = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_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 = (uint8_t *)BigBuf; - int traceLen = 0; + clear_trace(); + set_tracing(TRUE); + + // The command (reader -> tag) that we're receiving. + uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; + + // The response (tag -> reader) that we're receiving. + uint8_t *receivedResponse = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; // The DMA buffer, used to stream samples from the FPGA. - int8_t *dmaBuf = (int8_t *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE + TAG_READER_BUFFER_SIZE; + int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET; int lastRxCounter; int8_t *upTo; int ci, cq; @@ -1052,30 +1062,20 @@ void RAMFUNC SnoopIso14443(void) // information in the trace buffer. int samples = 0; - // Initialize the trace buffer - memset(trace, 0x44, DEMOD_TRACE_SIZE); - - // Set up the demodulator for tag -> reader responses. - Demod.output = receivedResponse; - Demod.len = 0; - Demod.state = DEMOD_UNSYNCD; - - // And the reader -> tag commands - memset(&Uart, 0, sizeof(Uart)); - Uart.output = receivedCmd; - Uart.byteCntMax = 100; - Uart.state = STATE_UNSYNCD; + DemodReset(); + UartReset(); // Print some debug information about the buffer sizes Dbprintf("Snooping buffers initialized:"); - Dbprintf(" Trace: %i bytes", DEMOD_TRACE_SIZE); - 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); + Dbprintf(" Trace: %i bytes", TRACE_SIZE); + Dbprintf(" Reader -> tag: %i bytes", MAX_FRAME_SIZE); + Dbprintf(" tag -> Reader: %i bytes", MAX_FRAME_SIZE); + Dbprintf(" DMA: %i bytes", DMA_BUFFER_SIZE); - // And put the FPGA in the appropriate mode - // Signal field is off with the appropriate LED - LED_D_OFF(); + // Signal field is off with the appropriate LED + LED_D_OFF(); + + // And put the FPGA in the appropriate mode FpgaWriteConfWord( FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP); @@ -1084,20 +1084,20 @@ void RAMFUNC SnoopIso14443(void) // Setup for the DMA. FpgaSetupSsc(); upTo = dmaBuf; - lastRxCounter = DEMOD_DMA_BUFFER_SIZE; - FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE); - + lastRxCounter = DMA_BUFFER_SIZE; + FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); + uint8_t parity[MAX_PARITY_SIZE]; LED_A_ON(); // And now we loop, receiving samples. for(;;) { int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & - (DEMOD_DMA_BUFFER_SIZE-1); + (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 > (DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not? Dbprintf("blew circular buffer! behindBy=0x%x", behindBy); - goto done; + break; } } if(behindBy < 2) continue; @@ -1106,42 +1106,37 @@ void RAMFUNC SnoopIso14443(void) cq = upTo[1]; upTo += 2; lastRxCounter -= 2; - if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) { - upTo -= DEMOD_DMA_BUFFER_SIZE; - lastRxCounter += DEMOD_DMA_BUFFER_SIZE; + if(upTo - dmaBuf > DMA_BUFFER_SIZE) { + upTo -= DMA_BUFFER_SIZE; + lastRxCounter += DMA_BUFFER_SIZE; AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; - AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE; + AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; } samples += 2; -#define HANDLE_BIT_IF_BODY \ - if(triggered && tracing) {\ - uint8_t parity[MAX_PARITY_SIZE];\ - GetParity(receivedCmd, Uart.byteCnt, parity);\ - LogTrace(receivedCmd,Uart.byteCnt,samples, samples,parity,TRUE);\ - if(!tracing) {\ - DbpString("Reached trace limit");\ - break;\ - }\ - }\ - /* And ready to receive another command. */ \ - memset(&Uart, 0, sizeof(Uart)); \ - Uart.output = receivedCmd; \ - Uart.byteCntMax = 100; \ - Uart.state = STATE_UNSYNCD; \ - /* And also reset the demod code, which might have been */ \ - /* false-triggered by the commands from the reader. */ \ - memset(&Demod, 0, sizeof(Demod)); \ - Demod.output = receivedResponse; \ - Demod.state = DEMOD_UNSYNCD; \ - if(Handle14443UartBit(ci & 1)) { - HANDLE_BIT_IF_BODY - } + if(triggered && tracing) { + GetParity(receivedCmd, Uart.byteCnt, parity); + LogTrace(receivedCmd,Uart.byteCnt,samples, samples,parity,TRUE); + } + /* And ready to receive another command. */ + UartReset(); + /* And also reset the demod code, which might have been */ + /* false-triggered by the commands from the reader. */ + DemodReset(); + } if(Handle14443UartBit(cq & 1)) { - HANDLE_BIT_IF_BODY - } + if(triggered && tracing) { + GetParity(receivedCmd, Uart.byteCnt, parity); + LogTrace(receivedCmd,Uart.byteCnt,samples, samples,parity,TRUE); + } + /* And ready to receive another command. */ + UartReset(); + /* And also reset the demod code, which might have been */ + /* false-triggered by the commands from the reader. */ + DemodReset(); + } if(Handle14443SamplesDemod(ci, cq)) { @@ -1151,33 +1146,31 @@ void RAMFUNC SnoopIso14443(void) uint8_t parity[MAX_PARITY_SIZE]; GetParity(receivedResponse, Demod.len, parity); LogTrace(receivedResponse,Demod.len,samples, samples,parity,FALSE); - if(!tracing) { - DbpString("Reached trace limit"); - break; - } } triggered = TRUE; LED_A_OFF(); LED_B_ON(); // And ready to receive another response. - memset(&Demod, 0, sizeof(Demod)); - Demod.output = receivedResponse; - Demod.state = DEMOD_UNSYNCD; + DemodReset(); } - WDT_HIT(); + WDT_HIT(); + + if(!tracing) { + DbpString("Reached trace limit"); + break; + } if(BUTTON_PRESS()) { DbpString("cancelled"); - goto done; + break; } } - -done: + FpgaDisableSscDma(); 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(" Uart State: %x", Uart.state); From 03dc174036b7258baf1ef2504e810a685163137e Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 27 Jan 2015 09:06:01 +0100 Subject: [PATCH 07/13] Minor refactoring --- armsrc/iso14443.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index 0a6d2d67f..39112fdfc 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -154,7 +154,7 @@ static struct { static int Handle14443UartBit(int bit) { switch(Uart.state) { - case STATE_UNSYNCD: + case STATE_UNSYNCD: LED_A_OFF(); if(!bit) { // we went low, so this could be the beginning @@ -1045,12 +1045,6 @@ void RAMFUNC SnoopIso14443(void) clear_trace(); set_tracing(TRUE); - // The command (reader -> tag) that we're receiving. - uint8_t *receivedCmd = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; - - // The response (tag -> reader) that we're receiving. - uint8_t *receivedResponse = ((uint8_t *)BigBuf) + RECV_RESP_OFFSET; - // The DMA buffer, used to stream samples from the FPGA. int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET; int lastRxCounter; @@ -1117,8 +1111,8 @@ void RAMFUNC SnoopIso14443(void) if(Handle14443UartBit(ci & 1)) { if(triggered && tracing) { - GetParity(receivedCmd, Uart.byteCnt, parity); - LogTrace(receivedCmd,Uart.byteCnt,samples, samples,parity,TRUE); + GetParity(Uart.output, Uart.byteCnt, parity); + LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE); } /* And ready to receive another command. */ UartReset(); @@ -1128,8 +1122,8 @@ void RAMFUNC SnoopIso14443(void) } if(Handle14443UartBit(cq & 1)) { if(triggered && tracing) { - GetParity(receivedCmd, Uart.byteCnt, parity); - LogTrace(receivedCmd,Uart.byteCnt,samples, samples,parity,TRUE); + GetParity(Uart.output, Uart.byteCnt, parity); + LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE); } /* And ready to receive another command. */ UartReset(); @@ -1144,8 +1138,8 @@ void RAMFUNC SnoopIso14443(void) if(tracing) { uint8_t parity[MAX_PARITY_SIZE]; - GetParity(receivedResponse, Demod.len, parity); - LogTrace(receivedResponse,Demod.len,samples, samples,parity,FALSE); + GetParity(Demod.output, Demod.len, parity); + LogTrace(Demod.output,Demod.len,samples, samples,parity,FALSE); } triggered = TRUE; LED_A_OFF(); From 16b75f27c3e688b42c7d277dd1e6e99e32cc38c7 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 27 Jan 2015 16:34:11 +0100 Subject: [PATCH 08/13] Minor tweaks to iso14443b snoop tracing --- armsrc/iso14443.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index 39112fdfc..1191c5bf5 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -633,6 +633,8 @@ static void UartReset() Uart.output = ((uint8_t *)BigBuf) + RECV_CMD_OFFSET; Uart.byteCntMax = MAX_FRAME_SIZE; Uart.state = STATE_UNSYNCD; + Uart.byteCnt = 0; + Uart.bitCnt = 0; } /* @@ -1109,11 +1111,13 @@ void RAMFUNC SnoopIso14443(void) samples += 2; - if(Handle14443UartBit(ci & 1)) { + if(Handle14443UartBit(ci & 1)) { if(triggered && tracing) { GetParity(Uart.output, Uart.byteCnt, parity); LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE); } + if(Uart.byteCnt==0) Dbprintf("[1] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt); + /* And ready to receive another command. */ UartReset(); /* And also reset the demod code, which might have been */ @@ -1125,6 +1129,8 @@ void RAMFUNC SnoopIso14443(void) GetParity(Uart.output, Uart.byteCnt, parity); LogTrace(Uart.output,Uart.byteCnt,samples, samples,parity,TRUE); } + if(Uart.byteCnt==0) Dbprintf("[2] Error, Uart.byteCnt==0, Uart.bitCnt=%d", Uart.bitCnt); + /* And ready to receive another command. */ UartReset(); /* And also reset the demod code, which might have been */ From 08e8317c2168fbdc788afe7b19f4c918bf1e4a6f Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Tue, 27 Jan 2015 16:34:45 +0100 Subject: [PATCH 09/13] More annotations to iso14443b protocol listings --- client/cmdhf.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/client/cmdhf.c b/client/cmdhf.c index 373668027..0f31da4d6 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -158,9 +158,28 @@ NXP/Philips CUSTOM COMMANDS #define MIFARE_ULC_AUTH_1 0x1A #define MIFARE_ULC_AUTH_2 0xAF +/** +06 00 = INITIATE +0E xx = SELECT ID (xx = Chip-ID) +0B = Get UID +08 yy = Read Block (yy = block number) +09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written) +0C = Reset to Inventory +0F = Completion +0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate) +**/ + #define ISO14443B_REQB 0x05 #define ISO14443B_ATTRIB 0x1D #define ISO14443B_HALT 0x50 +#define ISO14443B_INITIATE 0x06 +#define ISO14443B_SELECT 0x0E +#define ISO14443B_GET_UID 0x0B +#define ISO14443B_READ_BLK 0x08 +#define ISO14443B_WRITE_BLK 0x09 +#define ISO14443B_RESET 0x0C +#define ISO14443B_COMPLETION 0x0F +#define ISO14443B_AUTHENTICATE 0x0A //First byte is 26 #define ISO15693_INVENTORY 0x01 @@ -288,13 +307,33 @@ void annotateIso15693(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) } } } + +/** +06 00 = INITIATE +0E xx = SELECT ID (xx = Chip-ID) +0B = Get UID +08 yy = Read Block (yy = block number) +09 yy dd dd dd dd = Write Block (yy = block number; dd dd dd dd = data to be written) +0C = Reset to Inventory +0F = Completion +0A 11 22 33 44 55 66 = Authenticate (11 22 33 44 55 66 = data to authenticate) +**/ + void annotateIso14443b(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize) { switch(cmd[0]){ case ISO14443B_REQB : snprintf(exp,size,"REQB");break; case ISO14443B_ATTRIB : snprintf(exp,size,"ATTRIB");break; case ISO14443B_HALT : snprintf(exp,size,"HALT");break; - default: snprintf(exp,size ,"?");break; + case ISO14443B_INITIATE : snprintf(exp,size,"INITIATE");break; + case ISO14443B_SELECT : snprintf(exp,size,"SELECT(%d)",cmd[1]);break; + case ISO14443B_GET_UID : snprintf(exp,size,"GET UID");break; + case ISO14443B_READ_BLK : snprintf(exp,size,"READ_BLK(%d)", cmd[1]);break; + case ISO14443B_WRITE_BLK : snprintf(exp,size,"WRITE_BLK(%d)",cmd[1]);break; + case ISO14443B_RESET : snprintf(exp,size,"RESET");break; + case ISO14443B_COMPLETION : snprintf(exp,size,"COMPLETION");break; + case ISO14443B_AUTHENTICATE : snprintf(exp,size,"AUTHENTICATE");break; + default : snprintf(exp,size ,"?");break; } } From 3000dc4e7e72dd8661d174f7bcde511ff73eb99f Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sat, 7 Feb 2015 20:49:40 +0100 Subject: [PATCH 10/13] Generic tracing; removed iso14a_XX-functions, removed traceLen as global varible --- armsrc/BigBuf.c | 96 ++++++++++++++++++++++++++++++++++++++++++-- armsrc/BigBuf.h | 5 ++- armsrc/appmain.c | 5 ++- armsrc/apps.h | 3 +- armsrc/hitag2.c | 12 +++--- armsrc/iclass.c | 25 ++++++------ armsrc/iso14443.c | 2 +- armsrc/iso14443a.c | 32 +++++++-------- armsrc/mifarecmd.c | 42 +++++++++---------- armsrc/mifaresniff.c | 8 ++-- armsrc/util.c | 88 ---------------------------------------- armsrc/util.h | 9 ----- 12 files changed, 160 insertions(+), 167 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 7f56e9a01..1b5e54823 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -26,10 +26,9 @@ static uint16_t BigBuf_hi = BIGBUF_SIZE; // 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; - +// trace related variables +static uint16_t traceLen = 0; +int tracing = 1; //Last global one.. todo static? // get the address of BigBuf uint8_t *BigBuf_get_addr(void) @@ -95,3 +94,92 @@ uint16_t BigBuf_max_traceLen(void) { return BigBuf_hi; } + +void clear_trace() { + uint8_t *trace = BigBuf_get_addr(); + uint16_t max_traceLen = BigBuf_max_traceLen(); + memset(trace, 0x44, max_traceLen); + traceLen = 0; +} + +void set_tracing(bool enable) { + tracing = enable; +} + +/** + * Get the number of bytes traced + * @return + */ +uint16_t BigBuf_get_traceLen(void) +{ + return traceLen; +} + +/** + This is a function to store traces. All protocols can use this generic tracer-function. + The traces produced by calling this function can be fetched on the client-side + by 'hf list raw', alternatively 'hf list ' for protocol-specific + annotation of commands/responses. + +**/ +bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) +{ + if (!tracing) return FALSE; + + uint8_t *trace = BigBuf_get_addr(); + + uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity + uint16_t duration = timestamp_end - timestamp_start; + + // Return when trace is full + 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; + } + // Traceformat: + // 32 bits timestamp (little endian) + // 16 bits duration (little endian) + // 16 bits data length (little endian, Highest Bit used as readerToTag flag) + // y Bytes data + // x Bytes parity (one byte per 8 bytes data) + + // timestamp (start) + trace[traceLen++] = ((timestamp_start >> 0) & 0xff); + trace[traceLen++] = ((timestamp_start >> 8) & 0xff); + trace[traceLen++] = ((timestamp_start >> 16) & 0xff); + trace[traceLen++] = ((timestamp_start >> 24) & 0xff); + + // duration + trace[traceLen++] = ((duration >> 0) & 0xff); + trace[traceLen++] = ((duration >> 8) & 0xff); + + // data length + trace[traceLen++] = ((iLen >> 0) & 0xff); + trace[traceLen++] = ((iLen >> 8) & 0xff); + + // readerToTag flag + if (!readerToTag) { + trace[traceLen - 1] |= 0x80; + } + + // data bytes + if (btBytes != NULL && iLen != 0) { + memcpy(trace + traceLen, btBytes, iLen); + } + traceLen += iLen; + + // parity bytes + if (parity != NULL && iLen != 0) { + memcpy(trace + traceLen, parity, num_paritybytes); + } + traceLen += num_paritybytes; + + if(traceLen +4 < max_traceLen) + { //If it hadn't been cleared, for whatever reason.. + memset(trace+traceLen,0x44, 4); + } + + return TRUE; +} diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index 9d89a4f0f..5cca1000f 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -29,6 +29,9 @@ extern uint8_t *BigBuf_malloc(uint16_t); extern void BigBuf_free(void); extern void BigBuf_free_keep_EM(void); -extern uint16_t traceLen; +uint16_t BigBuf_get_traceLen(void); +void clear_trace(); +void set_tracing(bool enable); +bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); #endif /* __BIGBUF_H */ diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 7c50a51ec..bbf772aca 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -24,6 +24,7 @@ #include "legicrf.h" #include #include "lfsampling.h" +#include "BigBuf.h" #ifdef WITH_LCD #include "LCD.h" #endif @@ -916,10 +917,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,traceLen,BigBuf+c->arg[0]+i,len); + cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,BigBuf_get_traceLen(),BigBuf+c->arg[0]+i,len); } // Trigger a finish downloading signal with an ACK frame - cmd_send(CMD_ACK,1,0,traceLen,getSamplingConfig(),sizeof(sample_config)); + cmd_send(CMD_ACK,1,0,BigBuf_get_traceLen(),getSamplingConfig(),sizeof(sample_config)); LED_B_OFF(); break; diff --git a/armsrc/apps.h b/armsrc/apps.h index 58a2a6219..0f7714e7b 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -148,8 +148,7 @@ void ReaderIso14443a(UsbCommand * c); bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *parity); void iso14a_set_trigger(bool enable); -void iso14a_clear_trace(); -void iso14a_set_tracing(bool enable); + void RAMFUNC SniffMifare(uint8_t param); /// epa.h diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 4a2d9d9d4..7ca799305 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -742,8 +742,8 @@ void SnoopHitag(uint32_t type) { memset(auth_table, 0x00, AUTH_TABLE_LENGTH); // Clean up trace and prepare it for storing frames - iso14a_set_tracing(TRUE); - iso14a_clear_trace(); + set_tracing(TRUE); + clear_trace(); DbpString("Starting Hitag2 snoop"); LED_D_ON(); @@ -955,8 +955,8 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) { memset(auth_table, 0x00, AUTH_TABLE_LENGTH); // Clean up trace and prepare it for storing frames - iso14a_set_tracing(TRUE); - iso14a_clear_trace(); + set_tracing(TRUE); + clear_trace(); DbpString("Starting Hitag2 simulation"); LED_D_ON(); @@ -1142,8 +1142,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) { bSuccessful = false; // Clean up trace and prepare it for storing frames - iso14a_set_tracing(TRUE); - iso14a_clear_trace(); + set_tracing(TRUE); + clear_trace(); DbpString("Starting Hitag reader family"); diff --git a/armsrc/iclass.c b/armsrc/iclass.c index 1a3751182..41c9b8b51 100644 --- a/armsrc/iclass.c +++ b/armsrc/iclass.c @@ -652,9 +652,8 @@ void RAMFUNC SnoopIClass(void) // 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(); + set_tracing(TRUE); + clear_trace(); iso14a_set_trigger(FALSE); int lastRxCounter; @@ -805,12 +804,12 @@ void RAMFUNC SnoopIClass(void) DbpString("COMMAND FINISHED"); Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt); - Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]); + Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]); done: AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt); - Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]); + Dbprintf("%x %x %x", Uart.byteCntMax, BigBuf_get_traceLen(), (int)Uart.output[0]); LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); @@ -987,8 +986,8 @@ void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // Enable and clear the trace - iso14a_set_tracing(TRUE); - iso14a_clear_trace(); + set_tracing(TRUE); + clear_trace(); uint8_t csn_crc[] = { 0x03, 0x1f, 0xec, 0x8a, 0xf7, 0xff, 0x12, 0xe0, 0x00, 0x00 }; if(simType == 0) { @@ -1488,8 +1487,8 @@ void setupIclassReader() { FpgaDownloadAndGo(FPGA_BITSTREAM_HF); // Reset trace buffer - iso14a_set_tracing(TRUE); - iso14a_clear_trace(); + set_tracing(TRUE); + clear_trace(); // Setup SSC FpgaSetupSsc(); @@ -1585,14 +1584,14 @@ void ReaderIClass(uint8_t arg0) { int read_status= 0; bool abort_after_read = arg0 & FLAG_ICLASS_READER_ONLY_ONCE; bool get_cc = arg0 & FLAG_ICLASS_READER_GET_CC; - + set_tracing(TRUE); setupIclassReader(); size_t datasize = 0; while(!BUTTON_PRESS()) { - if(traceLen > BigBuf_max_traceLen()) { + if(!tracing) { DbpString("Trace full"); break; } @@ -1658,13 +1657,13 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { uint8_t resp[ICLASS_BUFFER_SIZE]; setupIclassReader(); - + set_tracing(TRUE); while(!BUTTON_PRESS()) { WDT_HIT(); - if(traceLen > BigBuf_max_traceLen()) { + if(!tracing) { DbpString("Trace full"); break; } diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index 92d057820..c7f49f140 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -1192,7 +1192,7 @@ void RAMFUNC SnoopIso14443(void) Dbprintf(" Uart State: %x", Uart.state); Dbprintf(" Uart ByteCnt: %i", Uart.byteCnt); Dbprintf(" Uart ByteCntMax: %i", Uart.byteCntMax); - Dbprintf(" Trace length: %i", traceLen); + Dbprintf(" Trace length: %i", BigBuf_get_traceLen()); } /* diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 336250ede..05ffb9417 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -20,7 +20,7 @@ #include "iso14443a.h" #include "crapto1.h" #include "mifareutil.h" - +#include "BigBuf.h" static uint32_t iso14a_timeout; int rsamples = 0; uint8_t trigger = 0; @@ -549,8 +549,8 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { uint8_t *dmaBuf = BigBuf_malloc(DMA_BUFFER_SIZE); // init trace buffer - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); + clear_trace(); + set_tracing(TRUE); uint8_t *data = dmaBuf; uint8_t previous_data = 0; @@ -674,7 +674,7 @@ void RAMFUNC SnoopIso14443a(uint8_t param) { FpgaDisableSscDma(); Dbprintf("maxDataLen=%d, Uart.state=%x, Uart.len=%d", maxDataLen, Uart.state, Uart.len); - Dbprintf("traceLen=%d, Uart.output[0]=%08x", traceLen, (uint32_t)Uart.output[0]); + Dbprintf("traceLen=%d, Uart.output[0]=%08x", BigBuf_get_traceLen(), (uint32_t)Uart.output[0]); LEDsoff(); } @@ -1010,8 +1010,8 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) free_buffer_pointer = BigBuf_malloc(ALLOCATED_TAG_MODULATION_BUFFER_SIZE); // clear trace - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); + clear_trace(); + 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 @@ -1867,10 +1867,10 @@ void ReaderIso14443a(UsbCommand *c) uint8_t par[MAX_PARITY_SIZE]; if(param & ISO14A_CONNECT) { - iso14a_clear_trace(); + clear_trace(); } - iso14a_set_tracing(TRUE); + set_tracing(TRUE); if(param & ISO14A_REQUEST_TRIGGER) { iso14a_set_trigger(TRUE); @@ -1966,8 +1966,8 @@ void ReaderMifare(bool first_try) // free eventually allocated BigBuf memory. We want all for tracing. BigBuf_free(); - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); + clear_trace(); + set_tracing(TRUE); byte_t nt_diff = 0; uint8_t par[1] = {0}; // maximum 8 Bytes to be sent here, 1 byte parity is therefore enough @@ -2140,7 +2140,7 @@ void ReaderMifare(bool first_try) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - iso14a_set_tracing(FALSE); + set_tracing(FALSE); } /** @@ -2198,8 +2198,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * // free eventually allocated BigBuf memory but keep Emulator Memory BigBuf_free_keep_EM(); // clear trace - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); + clear_trace(); + set_tracing(TRUE); // Authenticate response - nonce uint32_t nonce = bytes_to_num(rAUTH_NT, 4); @@ -2644,7 +2644,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * } } } - if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, traceLen); + if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, BigBuf_get_traceLen()); } @@ -2661,8 +2661,8 @@ void RAMFUNC SniffMifare(uint8_t param) { // C(red) A(yellow) B(green) LEDsoff(); // init trace buffer - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); + clear_trace(); + set_tracing(TRUE); // The command (reader -> tag) that we're receiving. // The length of a received command will in most cases be no more than 18 bytes. diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 4279e63f2..a16cbf166 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -41,7 +41,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) pcs = &mpcs; // clear trace - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); LED_A_ON(); @@ -98,7 +98,7 @@ void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){ LED_B_OFF(); LED_C_OFF(); - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); if(!iso14443a_select_card(uid, NULL, &cuid)) { @@ -162,7 +162,7 @@ void MifareUReadBlock(uint8_t arg0,uint8_t *datain) LED_B_OFF(); LED_C_OFF(); - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); int len = iso14443a_select_card(uid, NULL, &cuid); @@ -213,7 +213,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) pcs = &mpcs; // clear trace - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -276,7 +276,7 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain) if (MF_DBGLEVEL >= MF_DBG_ALL) Dbprintf("Pages %d",Pages); - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); int len = iso14443a_select_card(uid, NULL, &cuid); @@ -350,7 +350,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) pcs = &mpcs; // clear trace - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -411,7 +411,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain) uint8_t uid[10] = {0x00}; uint32_t cuid; - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); LED_A_ON(); @@ -458,7 +458,7 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain) uint8_t uid[10] = {0x00}; uint32_t cuid; - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); LED_A_ON(); @@ -537,8 +537,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat // free eventually allocated BigBuf memory BigBuf_free(); // clear trace - iso14a_clear_trace(); - iso14a_set_tracing(false); + clear_trace(); + set_tracing(false); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -709,7 +709,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - iso14a_set_tracing(TRUE); + set_tracing(TRUE); } //----------------------------------------------------------------------------- @@ -738,8 +738,8 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) MF_DBGLEVEL = MF_DBG_NONE; // clear trace - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); + clear_trace(); + set_tracing(TRUE); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -829,8 +829,8 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai uint8_t uid[10]; // clear trace - iso14a_clear_trace(); - iso14a_set_tracing(false); + clear_trace(); + set_tracing(false); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -931,8 +931,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai LED_B_OFF(); LED_C_OFF(); - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); + clear_trace(); + set_tracing(TRUE); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); } @@ -1049,8 +1049,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai LED_B_OFF(); LED_C_OFF(); - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); + clear_trace(); + set_tracing(TRUE); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); } @@ -1136,7 +1136,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){ uint8_t uid[10] = {0x00}; uint32_t cuid; - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); int len = iso14443a_select_card(uid, NULL, &cuid); @@ -1183,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(); -} +} diff --git a/armsrc/mifaresniff.c b/armsrc/mifaresniff.c index 59e846975..0cc2963bc 100644 --- a/armsrc/mifaresniff.c +++ b/armsrc/mifaresniff.c @@ -139,7 +139,7 @@ bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, ui } bool RAMFUNC MfSniffSend(uint16_t maxTimeoutMs) { - if (traceLen && (GetTickCount() > timerData + maxTimeoutMs)) { + if (BigBuf_get_traceLen() && (GetTickCount() > timerData + maxTimeoutMs)) { return intMfSniffSend(); } return FALSE; @@ -149,7 +149,7 @@ bool RAMFUNC MfSniffSend(uint16_t maxTimeoutMs) { bool intMfSniffSend() { int pckSize = 0; - int pckLen = traceLen; + int pckLen = BigBuf_get_traceLen(); int pckNum = 0; uint8_t *trace = BigBuf_get_addr(); @@ -157,7 +157,7 @@ bool intMfSniffSend() { while (pckLen > 0) { pckSize = MIN(USB_CMD_DATA_SIZE, pckLen); LED_B_ON(); - cmd_send(CMD_ACK, 1, traceLen, pckSize, trace + traceLen - pckLen, pckSize); + cmd_send(CMD_ACK, 1, BigBuf_get_traceLen(), pckSize, trace + BigBuf_get_traceLen() - pckLen, pckSize); LED_B_OFF(); pckLen -= pckSize; @@ -168,7 +168,7 @@ bool intMfSniffSend() { cmd_send(CMD_ACK,2,0,0,0,0); LED_B_OFF(); - iso14a_clear_trace(); + clear_trace(); return TRUE; } diff --git a/armsrc/util.c b/armsrc/util.c index 4948fce8f..889319279 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -14,7 +14,6 @@ #include "apps.h" #include "BigBuf.h" -int tracing = TRUE; void print_result(char *name, uint8_t *buf, size_t len) { @@ -429,91 +428,4 @@ uint32_t RAMFUNC GetCountSspClk(){ return tmp_count; } } -void iso14a_clear_trace() { - clear_trace(); -} - -void iso14a_set_tracing(bool enable) { - set_tracing(enable); -} - -void clear_trace() { - uint8_t *trace = BigBuf_get_addr(); - uint16_t max_traceLen = BigBuf_max_traceLen(); - memset(trace, 0x44, max_traceLen); - traceLen = 0; -} - -void set_tracing(bool enable) { - tracing = enable; -} - -/** - This is a function to store traces. All protocols can use this generic tracer-function. - The traces produced by calling this function can be fetched on the client-side - by 'hf list raw', alternatively 'hf list ' for protocol-specific - annotation of commands/responses. - -**/ -bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) -{ - if (!tracing) return FALSE; - - uint8_t *trace = BigBuf_get_addr(); - - uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity - uint16_t duration = timestamp_end - timestamp_start; - - // Return when trace is full - 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; - } - // Traceformat: - // 32 bits timestamp (little endian) - // 16 bits duration (little endian) - // 16 bits data length (little endian, Highest Bit used as readerToTag flag) - // y Bytes data - // x Bytes parity (one byte per 8 bytes data) - - // timestamp (start) - trace[traceLen++] = ((timestamp_start >> 0) & 0xff); - trace[traceLen++] = ((timestamp_start >> 8) & 0xff); - trace[traceLen++] = ((timestamp_start >> 16) & 0xff); - trace[traceLen++] = ((timestamp_start >> 24) & 0xff); - - // duration - trace[traceLen++] = ((duration >> 0) & 0xff); - trace[traceLen++] = ((duration >> 8) & 0xff); - - // data length - trace[traceLen++] = ((iLen >> 0) & 0xff); - trace[traceLen++] = ((iLen >> 8) & 0xff); - - // readerToTag flag - if (!readerToTag) { - trace[traceLen - 1] |= 0x80; - } - - // data bytes - if (btBytes != NULL && iLen != 0) { - memcpy(trace + traceLen, btBytes, iLen); - } - traceLen += iLen; - - // parity bytes - if (parity != NULL && iLen != 0) { - memcpy(trace + traceLen, parity, num_paritybytes); - } - traceLen += num_paritybytes; - - if(traceLen +4 < max_traceLen) - { //If it hadn't been cleared, for whatever reason.. - memset(trace+traceLen,0x44, 4); - } - - return TRUE; -} diff --git a/armsrc/util.h b/armsrc/util.h index e00663028..bf5d0cc81 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -43,15 +43,6 @@ void LEDsoff(); int BUTTON_CLICKED(int ms); int BUTTON_HELD(int ms); void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information); -// @deprecated -void iso14a_clear_trace(); -// @deprecated -void iso14a_set_tracing(bool enable); -void clear_trace(); -void set_tracing(bool enable); - -// The function LogTrace() is also used by the iClass implementation in iclass.c and both iso14443a, iso14443b and mifare -bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); void StartTickCount(); uint32_t RAMFUNC GetTickCount(); From aabb719dc4e9af383e20c79647612755957bca00 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sat, 7 Feb 2015 20:55:17 +0100 Subject: [PATCH 11/13] Moved LogTraceHitag to BigBuf (no changes to the function ... yet) --- armsrc/BigBuf.c | 26 ++++++++++++++++++++++++++ armsrc/BigBuf.h | 2 +- armsrc/hitag2.c | 27 +-------------------------- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 1b5e54823..18db66f3b 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -183,3 +183,29 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ return TRUE; } +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 + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + nbytes(iBits) > BigBuf_max_traceLen()) return FALSE; + + // Trace the random, i'm curious + rsamples += iSamples; + trace[traceLen++] = ((rsamples >> 0) & 0xff); + trace[traceLen++] = ((rsamples >> 8) & 0xff); + trace[traceLen++] = ((rsamples >> 16) & 0xff); + trace[traceLen++] = ((rsamples >> 24) & 0xff); + if (!bReader) { + trace[traceLen - 1] |= 0x80; + } + trace[traceLen++] = ((dwParity >> 0) & 0xff); + trace[traceLen++] = ((dwParity >> 8) & 0xff); + trace[traceLen++] = ((dwParity >> 16) & 0xff); + trace[traceLen++] = ((dwParity >> 24) & 0xff); + trace[traceLen++] = iBits; + memcpy(trace + traceLen, btBytes, nbytes(iBits)); + traceLen += nbytes(iBits); + return TRUE; +} diff --git a/armsrc/BigBuf.h b/armsrc/BigBuf.h index 5cca1000f..be558979a 100644 --- a/armsrc/BigBuf.h +++ b/armsrc/BigBuf.h @@ -33,5 +33,5 @@ uint16_t BigBuf_get_traceLen(void); void clear_trace(); void set_tracing(bool enable); bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag); - +int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader); #endif /* __BIGBUF_H */ diff --git a/armsrc/hitag2.c b/armsrc/hitag2.c index 7ca799305..4b173d6f2 100644 --- a/armsrc/hitag2.c +++ b/armsrc/hitag2.c @@ -21,6 +21,7 @@ #include "util.h" #include "hitag2.h" #include "string.h" +#include "BigBuf.h" static bool bQuiet; @@ -30,32 +31,6 @@ static bool bPwd; static bool bSuccessful; -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 + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + nbytes(iBits) > BigBuf_max_traceLen()) return FALSE; - - // Trace the random, i'm curious - rsamples += iSamples; - trace[traceLen++] = ((rsamples >> 0) & 0xff); - trace[traceLen++] = ((rsamples >> 8) & 0xff); - trace[traceLen++] = ((rsamples >> 16) & 0xff); - trace[traceLen++] = ((rsamples >> 24) & 0xff); - if (!bReader) { - trace[traceLen - 1] |= 0x80; - } - trace[traceLen++] = ((dwParity >> 0) & 0xff); - trace[traceLen++] = ((dwParity >> 8) & 0xff); - trace[traceLen++] = ((dwParity >> 16) & 0xff); - trace[traceLen++] = ((dwParity >> 24) & 0xff); - trace[traceLen++] = iBits; - memcpy(trace + traceLen, btBytes, nbytes(iBits)); - traceLen += nbytes(iBits); - return TRUE; -} struct hitag2_tag { uint32_t uid; From 665775c844a3f8f1efe055cd25462b3cd7a7441a Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sat, 7 Feb 2015 21:05:14 +0100 Subject: [PATCH 12/13] Some documentation and formatting to LogTraceHitag --- armsrc/BigBuf.c | 25 ++++++++++++++++++------- armsrc/util.c | 2 +- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 18db66f3b..6e99a793f 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -185,27 +185,38 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ } int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader) { - static uint16_t traceLen = 0; + + if (!tracing) return FALSE; + uint8_t *trace = BigBuf_get_addr(); - + uint16_t iLen = nbytes(iBits); // Return when trace is full - if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + nbytes(iBits) > BigBuf_max_traceLen()) return FALSE; + if (traceLen + sizeof(rsamples) + sizeof(dwParity) + sizeof(iBits) + iLen > BigBuf_max_traceLen()) return FALSE; + + //Hitag traces appear to use this traceformat: + // 32 bits timestamp (little endian,Highest Bit used as readerToTag flag) + // 32 bits parity + // 8 bits size (number of bits in the trace entry) + // y Bytes data - // Trace the random, i'm curious rsamples += iSamples; trace[traceLen++] = ((rsamples >> 0) & 0xff); trace[traceLen++] = ((rsamples >> 8) & 0xff); trace[traceLen++] = ((rsamples >> 16) & 0xff); trace[traceLen++] = ((rsamples >> 24) & 0xff); + if (!bReader) { - trace[traceLen - 1] |= 0x80; + trace[traceLen - 1] |= 0x80; } + trace[traceLen++] = ((dwParity >> 0) & 0xff); trace[traceLen++] = ((dwParity >> 8) & 0xff); trace[traceLen++] = ((dwParity >> 16) & 0xff); trace[traceLen++] = ((dwParity >> 24) & 0xff); trace[traceLen++] = iBits; - memcpy(trace + traceLen, btBytes, nbytes(iBits)); - traceLen += nbytes(iBits); + + memcpy(trace + traceLen, btBytes, iLen); + traceLen += iLen; + return TRUE; } diff --git a/armsrc/util.c b/armsrc/util.c index 889319279..74fba94b7 100644 --- a/armsrc/util.c +++ b/armsrc/util.c @@ -35,7 +35,7 @@ void print_result(char *name, uint8_t *buf, size_t len) { } size_t nbytes(size_t nbits) { - return (nbits/8)+((nbits%8)>0); + return (nbits >> 3)+((nbits % 8) > 0); } uint32_t SwapBits(uint32_t value, int nrbits) { From beefe5bc4dd7df83b618f02c25083bd27861942d Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Sat, 7 Feb 2015 21:22:53 +0100 Subject: [PATCH 13/13] Minor dox --- armsrc/BigBuf.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/armsrc/BigBuf.c b/armsrc/BigBuf.c index 6e99a793f..0c666bce8 100644 --- a/armsrc/BigBuf.c +++ b/armsrc/BigBuf.c @@ -183,8 +183,12 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_ return TRUE; } -int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int bReader) +int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag) { + /** + Todo, rewrite the logger to use the generic functionality instead. It should be noted, however, + that this logger takes number of bits as argument, not number of bytes. + **/ if (!tracing) return FALSE; @@ -196,7 +200,7 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP //Hitag traces appear to use this traceformat: // 32 bits timestamp (little endian,Highest Bit used as readerToTag flag) // 32 bits parity - // 8 bits size (number of bits in the trace entry) + // 8 bits size (number of bits in the trace entry, not number of bytes) // y Bytes data rsamples += iSamples; @@ -205,7 +209,7 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP trace[traceLen++] = ((rsamples >> 16) & 0xff); trace[traceLen++] = ((rsamples >> 24) & 0xff); - if (!bReader) { + if (!readerToTag) { trace[traceLen - 1] |= 0x80; }