X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/e30c654b196a87a13ae7f7d4ced930b296c038ec..4df3eb3f739af80b6fdc8f737fc906d254ebd0b5:/armsrc/iso14443.c diff --git a/armsrc/iso14443.c b/armsrc/iso14443.c index 4ec3f0aa..9452ae83 100644 --- a/armsrc/iso14443.c +++ b/armsrc/iso14443.c @@ -1,20 +1,28 @@ //----------------------------------------------------------------------------- +// Jonathan Westhues, split Nov 2006 +// +// This code is licensed to you under the terms of the GNU GPL, version 2 or, +// at your option, any later version. See the LICENSE.txt file for the text of +// the license. +//----------------------------------------------------------------------------- // Routines to support ISO 14443. This includes both the reader software and // the `fake tag' modes. At the moment only the Type B modulation is // supported. -// Jonathan Westhues, split Nov 2006 //----------------------------------------------------------------------------- + #include "proxmark3.h" #include "apps.h" -#include "iso14443crc.h" +#include "util.h" +#include "string.h" +#include "iso14443crc.h" -//static void GetSamplesFor14443(BOOL weTx, int n); +//static void GetSamplesFor14443(int weTx, int n); #define DEMOD_TRACE_SIZE 4096 #define READER_TAG_BUFFER_SIZE 2048 #define TAG_READER_BUFFER_SIZE 2048 -#define DMA_BUFFER_SIZE 1024 +#define DEMOD_DMA_BUFFER_SIZE 1024 //============================================================================= // An ISO 14443 Type B tag. We listen for commands from the reader, using @@ -29,7 +37,7 @@ // that here) so that they can be transmitted to the reader. Doesn't transmit // them yet, just leaves them ready to send in ToSend[]. //----------------------------------------------------------------------------- -static void CodeIso14443bAsTag(const BYTE *cmd, int len) +static void CodeIso14443bAsTag(const uint8_t *cmd, int len) { int i; @@ -62,7 +70,7 @@ static void CodeIso14443bAsTag(const BYTE *cmd, int len) for(i = 0; i < len; i++) { int j; - BYTE b = cmd[i]; + uint8_t b = cmd[i]; // Start bit ToSendStuffBit(0); @@ -126,12 +134,12 @@ static struct { STATE_RECEIVING_DATA, STATE_ERROR_WAIT } state; - WORD shiftReg; + uint16_t shiftReg; int bitCnt; int byteCnt; int byteCntMax; int posCnt; - BYTE *output; + uint8_t *output; } Uart; /* Receive & handle a bit coming from the reader. @@ -143,7 +151,7 @@ static struct { * Returns: true if we received a EOF * false if we are still waiting for some more */ -static BOOL Handle14443UartBit(int bit) +static int Handle14443UartBit(int bit) { switch(Uart.state) { case STATE_UNSYNCD: @@ -275,9 +283,9 @@ static BOOL Handle14443UartBit(int bit) // Assume that we're called with the SSC (to the FPGA) and ADC path set // correctly. //----------------------------------------------------------------------------- -static BOOL GetIso14443CommandFromReader(BYTE *received, int *len, int maxLen) +static int GetIso14443CommandFromReader(uint8_t *received, int *len, int maxLen) { - BYTE mask; + uint8_t mask; int i, bit; // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen @@ -302,7 +310,7 @@ static BOOL GetIso14443CommandFromReader(BYTE *received, int *len, int maxLen) AT91C_BASE_SSC->SSC_THR = 0x00; } if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - BYTE b = (BYTE)AT91C_BASE_SSC->SSC_RHR; + uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; mask = 0x80; for(i = 0; i < 8; i++, mask >>= 1) { @@ -322,19 +330,19 @@ static BOOL GetIso14443CommandFromReader(BYTE *received, int *len, int maxLen) //----------------------------------------------------------------------------- void SimulateIso14443Tag(void) { - static const BYTE cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; - static const BYTE response1[] = { + static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; + static const uint8_t response1[] = { 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, 0x22, 0x00, 0x21, 0x85, 0x5e, 0xd7 }; - BYTE *resp; + uint8_t *resp; int respLen; - BYTE *resp1 = (((BYTE *)BigBuf) + 800); + uint8_t *resp1 = (((uint8_t *)BigBuf) + 800); int resp1Len; - BYTE *receivedCmd = (BYTE *)BigBuf; + uint8_t *receivedCmd = (uint8_t *)BigBuf; int len; int i; @@ -353,7 +361,7 @@ void SimulateIso14443Tag(void) cmdsRecvd = 0; for(;;) { - BYTE b1, b2; + uint8_t b1, b2; if(!GetIso14443CommandFromReader(receivedCmd, &len, 100)) { Dbprintf("button pressed, received %d commands", cmdsRecvd); @@ -400,7 +408,7 @@ void SimulateIso14443Tag(void) i = 0; for(;;) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - BYTE b = resp[i]; + uint8_t b = resp[i]; AT91C_BASE_SSC->SSC_THR = b; @@ -410,7 +418,7 @@ void SimulateIso14443Tag(void) } } if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - volatile BYTE b = (BYTE)AT91C_BASE_SSC->SSC_RHR; + volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; (void)b; } } @@ -439,8 +447,8 @@ static struct { int thisBit; int metric; int metricN; - WORD shiftReg; - BYTE *output; + uint16_t shiftReg; + uint8_t *output; int len; int sumI; int sumQ; @@ -457,7 +465,7 @@ static struct { * false if we are still waiting for some more * */ -static BOOL Handle14443SamplesDemod(int ci, int cq) +static RAMFUNC int Handle14443SamplesDemod(int ci, int cq) { int v; @@ -581,9 +589,9 @@ static BOOL Handle14443SamplesDemod(int ci, int cq) Demod.bitCount++; if(Demod.bitCount == 10) { - WORD s = Demod.shiftReg; + uint16_t s = Demod.shiftReg; if((s & 0x200) && !(s & 0x001)) { - BYTE b = (s >> 1); + uint8_t b = (s >> 1); Demod.output[Demod.len] = b; Demod.len++; Demod.state = DEMOD_AWAITING_START_BIT; @@ -615,16 +623,16 @@ static BOOL Handle14443SamplesDemod(int ci, int cq) * set to 'FALSE' if we behave like a snooper * quiet: set to 'TRUE' to disable debug output */ -static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet) +static void GetSamplesFor14443Demod(int weTx, int n, int quiet) { int max = 0; - BOOL gotFrame = FALSE; + int gotFrame = FALSE; //# define DMA_BUFFER_SIZE 8 - SBYTE *dmaBuf; + int8_t *dmaBuf; int lastRxCounter; - SBYTE *upTo; + int8_t *upTo; int ci, cq; @@ -632,20 +640,20 @@ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet) // Clear out the state of the "UART" that receives from the tag. memset(BigBuf, 0x44, 400); - Demod.output = (BYTE *)BigBuf; + Demod.output = (uint8_t *)BigBuf; Demod.len = 0; Demod.state = DEMOD_UNSYNCD; // And the UART that receives from the reader - Uart.output = (((BYTE *)BigBuf) + 1024); + Uart.output = (((uint8_t *)BigBuf) + 1024); Uart.byteCntMax = 100; Uart.state = STATE_UNSYNCD; // Setup for the DMA. - dmaBuf = (SBYTE *)(BigBuf + 32); + dmaBuf = (int8_t *)(BigBuf + 32); upTo = dmaBuf; - lastRxCounter = DMA_BUFFER_SIZE; - FpgaSetupSscDma((BYTE *)dmaBuf, DMA_BUFFER_SIZE); + lastRxCounter = DEMOD_DMA_BUFFER_SIZE; + FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE); // Signal field is ON with the appropriate LED: if (weTx) LED_D_ON(); else LED_D_OFF(); @@ -658,20 +666,20 @@ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet) int behindBy = lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR; if(behindBy > max) max = behindBy; - while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DMA_BUFFER_SIZE-1)) + while(((lastRxCounter-AT91C_BASE_PDC_SSC->PDC_RCR) & (DEMOD_DMA_BUFFER_SIZE-1)) > 2) { ci = upTo[0]; cq = upTo[1]; upTo += 2; - if(upTo - dmaBuf > DMA_BUFFER_SIZE) { - upTo -= DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (DWORD)upTo; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; + if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) { + upTo -= DEMOD_DMA_BUFFER_SIZE; + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; + AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE; } lastRxCounter -= 2; if(lastRxCounter <= 0) { - lastRxCounter += DMA_BUFFER_SIZE; + lastRxCounter += DEMOD_DMA_BUFFER_SIZE; } samples += 2; @@ -697,9 +705,9 @@ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet) // samples from the FPGA, which we will later do some signal processing on, // to get the bits. //----------------------------------------------------------------------------- -/*static void GetSamplesFor14443(BOOL weTx, int n) +/*static void GetSamplesFor14443(int weTx, int n) { - BYTE *dest = (BYTE *)BigBuf; + uint8_t *dest = (uint8_t *)BigBuf; int c; FpgaWriteConfWord( @@ -712,10 +720,10 @@ static void GetSamplesFor14443Demod(BOOL weTx, int n, BOOL quiet) AT91C_BASE_SSC->SSC_THR = 0x43; } if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - SBYTE b; - b = (SBYTE)AT91C_BASE_SSC->SSC_RHR; + int8_t b; + b = (int8_t)AT91C_BASE_SSC->SSC_RHR; - dest[c++] = (BYTE)b; + dest[c++] = (uint8_t)b; if(c >= n) { break; @@ -750,7 +758,7 @@ static void TransmitFor14443(void) c++; } if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - volatile DWORD r = AT91C_BASE_SSC->SSC_RHR; + volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; (void)r; } WDT_HIT(); @@ -766,7 +774,7 @@ static void TransmitFor14443(void) } } if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - volatile DWORD r = AT91C_BASE_SSC->SSC_RHR; + volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR; (void)r; } WDT_HIT(); @@ -778,10 +786,10 @@ static void TransmitFor14443(void) // Code a layer 2 command (string of octets, including CRC) into ToSend[], // so that it is ready to transmit to the tag using TransmitFor14443(). //----------------------------------------------------------------------------- -void CodeIso14443bAsReader(const BYTE *cmd, int len) +void CodeIso14443bAsReader(const uint8_t *cmd, int len) { int i, j; - BYTE b; + uint8_t b; ToSendReset(); @@ -836,9 +844,9 @@ void CodeIso14443bAsReader(const BYTE *cmd, int len) // The command name is misleading, it actually decodes the reponse in HEX // into the output buffer (read the result using hexsamples, not hisamples) //----------------------------------------------------------------------------- -void AcquireRawAdcSamplesIso14443(DWORD parameter) +void AcquireRawAdcSamplesIso14443(uint32_t parameter) { - BYTE cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; + uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 }; // Make sure that we start from off, since the tags are stateful; // confusing things will happen if we don't reset them between reads. @@ -872,18 +880,18 @@ void AcquireRawAdcSamplesIso14443(DWORD parameter) // // I tried to be systematic and check every answer of the tag, every CRC, etc... //----------------------------------------------------------------------------- -void ReadSRI512Iso14443(DWORD parameter) +void ReadSRI512Iso14443(uint32_t parameter) { ReadSTMemoryIso14443(parameter,0x0F); } -void ReadSRIX4KIso14443(DWORD parameter) +void ReadSRIX4KIso14443(uint32_t parameter) { ReadSTMemoryIso14443(parameter,0x7F); } -void ReadSTMemoryIso14443(DWORD parameter,DWORD dwLast) +void ReadSTMemoryIso14443(uint32_t parameter,uint32_t dwLast) { - BYTE i = 0x00; + uint8_t i = 0x00; // Make sure that we start from off, since the tags are stateful; // confusing things will happen if we don't reset them between reads. @@ -902,7 +910,7 @@ void ReadSTMemoryIso14443(DWORD parameter,DWORD dwLast) SpinDelay(200); // First command: wake up the tag using the INITIATE command - BYTE cmd1[] = { 0x06, 0x00, 0x97, 0x5b}; + uint8_t cmd1[] = { 0x06, 0x00, 0x97, 0x5b}; CodeIso14443bAsReader(cmd1, sizeof(cmd1)); TransmitFor14443(); // LED_A_ON(); @@ -1020,29 +1028,29 @@ void ReadSTMemoryIso14443(DWORD parameter,DWORD dwLast) * 0-4095 : Demodulated samples receive (4096 bytes) - DEMOD_TRACE_SIZE * 4096-6143 : Last Received command, 2048 bytes (reader->tag) - READER_TAG_BUFFER_SIZE * 6144-8191 : Last Received command, 2048 bytes(tag->reader) - TAG_READER_BUFFER_SIZE - * 8192-9215 : DMA Buffer, 1024 bytes (samples) - DMA_BUFFER_SIZE + * 8192-9215 : DMA Buffer, 1024 bytes (samples) - DEMOD_DMA_BUFFER_SIZE */ -void SnoopIso14443(void) +void RAMFUNC SnoopIso14443(void) { // 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 // response from the tag. - BOOL triggered = FALSE; + int triggered = TRUE; // The command (reader -> tag) that we're working on receiving. - BYTE *receivedCmd = (BYTE *)(BigBuf) + DEMOD_TRACE_SIZE; + uint8_t *receivedCmd = (uint8_t *)(BigBuf) + DEMOD_TRACE_SIZE; // The response (tag -> reader) that we're working on receiving. - BYTE *receivedResponse = (BYTE *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE; + 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. - BYTE *trace = (BYTE *)BigBuf; + uint8_t *trace = (uint8_t *)BigBuf; int traceLen = 0; // The DMA buffer, used to stream samples from the FPGA. - SBYTE *dmaBuf = (SBYTE *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE + TAG_READER_BUFFER_SIZE; + int8_t *dmaBuf = (int8_t *)(BigBuf) + DEMOD_TRACE_SIZE + READER_TAG_BUFFER_SIZE + TAG_READER_BUFFER_SIZE; int lastRxCounter; - SBYTE *upTo; + int8_t *upTo; int ci, cq; int maxBehindBy = 0; @@ -1069,11 +1077,8 @@ void SnoopIso14443(void) 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", DMA_BUFFER_SIZE); + Dbprintf(" DMA: %i bytes", DEMOD_DMA_BUFFER_SIZE); - // Use a counter for blinking the LED - long ledCount=0; - long ledFlashAt=200000; // And put the FPGA in the appropriate mode // Signal field is off with the appropriate LED @@ -1086,26 +1091,19 @@ void SnoopIso14443(void) // Setup for the DMA. FpgaSetupSsc(); upTo = dmaBuf; - lastRxCounter = DMA_BUFFER_SIZE; - FpgaSetupSscDma((BYTE *)dmaBuf, DMA_BUFFER_SIZE); + lastRxCounter = DEMOD_DMA_BUFFER_SIZE; + FpgaSetupSscDma((uint8_t *)dmaBuf, DEMOD_DMA_BUFFER_SIZE); + + LED_A_ON(); + // And now we loop, receiving samples. for(;;) { - // Blink the LED while Snooping - ledCount++; - if (ledCount == ledFlashAt) { - LED_D_ON(); - } - if (ledCount >= 2*ledFlashAt) { - LED_D_OFF(); - ledCount=0; - } - int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) & - (DMA_BUFFER_SIZE-1); + (DEMOD_DMA_BUFFER_SIZE-1); if(behindBy > maxBehindBy) { maxBehindBy = behindBy; - if(behindBy > (DMA_BUFFER_SIZE-2)) { // TODO: understand whether we can increase/decrease as we want or not? - Dbprintf("blew circular buffer! behindBy=%x", behindBy); + if(behindBy > (DEMOD_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; } } @@ -1115,18 +1113,17 @@ void SnoopIso14443(void) cq = upTo[1]; upTo += 2; lastRxCounter -= 2; - if(upTo - dmaBuf > DMA_BUFFER_SIZE) { - upTo -= DMA_BUFFER_SIZE; - lastRxCounter += DMA_BUFFER_SIZE; - AT91C_BASE_PDC_SSC->PDC_RNPR = (DWORD) upTo; - AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; + if(upTo - dmaBuf > DEMOD_DMA_BUFFER_SIZE) { + upTo -= DEMOD_DMA_BUFFER_SIZE; + lastRxCounter += DEMOD_DMA_BUFFER_SIZE; + AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo; + AT91C_BASE_PDC_SSC->PDC_RNCR = DEMOD_DMA_BUFFER_SIZE; } samples += 2; #define HANDLE_BIT_IF_BODY \ if(triggered) { \ - ledFlashAt=30000; \ trace[traceLen++] = ((samples >> 0) & 0xff); \ trace[traceLen++] = ((samples >> 8) & 0xff); \ trace[traceLen++] = ((samples >> 16) & 0xff); \ @@ -1182,6 +1179,8 @@ void SnoopIso14443(void) } triggered = TRUE; + LED_A_OFF(); + LED_B_ON(); // And ready to receive another response. memset(&Demod, 0, sizeof(Demod)); @@ -1197,10 +1196,12 @@ void SnoopIso14443(void) } done: - LED_D_OFF(); - AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS; + LED_A_OFF(); + LED_B_OFF(); + 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);