X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/15c4dc5ace24e6081d1597b011148f156cdd599e..6c45a008f5a216f29492004140ac8914a1378941:/armsrc/iso14443a.c?ds=sidebyside diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index ce653f29..c3696254 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1,27 +1,41 @@ //----------------------------------------------------------------------------- -// Routines to support ISO 14443 type A. -// // Gerhard de Koning Gans - May 2008 +// +// 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 type A. //----------------------------------------------------------------------------- -#include + +#include "proxmark3.h" #include "apps.h" +#include "util.h" +#include "string.h" + #include "iso14443crc.h" -static BYTE *trace = (BYTE *) BigBuf; +static uint8_t *trace = (uint8_t *) BigBuf; static int traceLen = 0; static int rsamples = 0; -static BOOL tracing = TRUE; - -typedef enum { - SEC_D = 1, - SEC_E = 2, - SEC_F = 3, - SEC_X = 4, - SEC_Y = 5, - SEC_Z = 6 -} SecType; - -static const BYTE OddByteParity[256] = { +static int tracing = TRUE; + +// CARD TO READER +// Sequence D: 11110000 modulation with subcarrier during first half +// Sequence E: 00001111 modulation with subcarrier during second half +// Sequence F: 00000000 no modulation with subcarrier +// READER TO CARD +// Sequence X: 00001100 drop after half a period +// Sequence Y: 00000000 no drop +// Sequence Z: 11000000 drop at start +#define SEC_D 0xf0 +#define SEC_E 0x0f +#define SEC_F 0x00 +#define SEC_X 0x0c +#define SEC_Y 0x00 +#define SEC_Z 0xc0 + +static const uint8_t OddByteParity[256] = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, @@ -49,13 +63,13 @@ static const BYTE OddByteParity[256] = { //----------------------------------------------------------------------------- // Generate the parity value for a byte sequence -// +// //----------------------------------------------------------------------------- -DWORD GetParity(const BYTE * pbtCmd, int iLen) +uint32_t GetParity(const uint8_t * pbtCmd, int iLen) { int i; - DWORD dwPar = 0; - + uint32_t dwPar = 0; + // Generate the encrypted data for (i = 0; i < iLen; i++) { // Save the encrypted parity bit @@ -64,16 +78,16 @@ DWORD GetParity(const BYTE * pbtCmd, int iLen) return dwPar; } -static void AppendCrc14443a(BYTE* data, int len) +static void AppendCrc14443a(uint8_t* data, int len) { ComputeCrc14443(CRC_14443_A,data,len,data+len,data+len+1); } -BOOL LogTrace(const BYTE * btBytes, int iLen, int iSamples, DWORD dwParity, BOOL bReader) +int LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity, int bReader) { // Return when trace is full if (traceLen >= TRACE_LENGTH) return FALSE; - + // Trace the random, i'm curious rsamples += iSamples; trace[traceLen++] = ((rsamples >> 0) & 0xff); @@ -93,11 +107,6 @@ BOOL LogTrace(const BYTE * btBytes, int iLen, int iSamples, DWORD dwParity, BOOL return TRUE; } -BOOL LogTraceInfo(byte_t* data, size_t len) -{ - return LogTrace(data,len,0,GetParity(data,len),TRUE); -} - //----------------------------------------------------------------------------- // The software UART that receives commands from the reader, and its state // variables. @@ -111,7 +120,7 @@ static struct { STATE_MILLER_Z, STATE_ERROR_WAIT } state; - WORD shiftReg; + uint16_t shiftReg; int bitCnt; int byteCnt; int byteCntMax; @@ -126,10 +135,10 @@ static struct { DROP_FIRST_HALF, DROP_SECOND_HALF } drop; - BYTE *output; + uint8_t *output; } Uart; -static BOOL MillerDecoding(int bit) +static int MillerDecoding(int bit) { int error = 0; int bitright; @@ -143,7 +152,7 @@ static BOOL MillerDecoding(int bit) Uart.bitBuffer ^= bit; } - BOOL EOC = FALSE; + int EOC = FALSE; if(Uart.state != STATE_UNSYNCD) { Uart.posCnt++; @@ -380,7 +389,7 @@ static struct { int posCount; int syncBit; int parityBits; - WORD shiftReg; + uint16_t shiftReg; int buffer; int buff; int samples; @@ -390,10 +399,10 @@ static struct { SUB_FIRST_HALF, SUB_SECOND_HALF } sub; - BYTE *output; + uint8_t *output; } Demod; -static BOOL ManchesterDecoding(int v) +static int ManchesterDecoding(int v) { int bit; int modulation; @@ -600,24 +609,24 @@ void SnoopIso14443a(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 = TRUE; // FALSE to wait first for card + int triggered = TRUE; // FALSE to wait first for card // The command (reader -> tag) that we're receiving. // The length of a received command will in most cases be no more than 18 bytes. // So 32 should be enough! - BYTE *receivedCmd = (((BYTE *)BigBuf) + RECV_CMD_OFFSET); + uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET); // The response (tag -> reader) that we're receiving. - BYTE *receivedResponse = (((BYTE *)BigBuf) + RECV_RES_OFFSET); + uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET); // 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) + DMA_BUFFER_OFFSET; + int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET; int lastRxCounter; - SBYTE *upTo; + int8_t *upTo; int smpl; int maxBehindBy = 0; @@ -649,7 +658,7 @@ void SnoopIso14443a(void) FpgaSetupSsc(); upTo = dmaBuf; lastRxCounter = DMA_BUFFER_SIZE; - FpgaSetupSscDma((BYTE *)dmaBuf, DMA_BUFFER_SIZE); + FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE); LED_A_ON(); @@ -673,37 +682,34 @@ void SnoopIso14443a(void) 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_RNPR = (uint32_t) upTo; AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE; } samples += 4; -#define HANDLE_BIT_IF_BODY \ - LED_C_ON(); \ - if(triggered) { \ - trace[traceLen++] = ((rsamples >> 0) & 0xff); \ - trace[traceLen++] = ((rsamples >> 8) & 0xff); \ - trace[traceLen++] = ((rsamples >> 16) & 0xff); \ - trace[traceLen++] = ((rsamples >> 24) & 0xff); \ - trace[traceLen++] = ((Uart.parityBits >> 0) & 0xff); \ - trace[traceLen++] = ((Uart.parityBits >> 8) & 0xff); \ - trace[traceLen++] = ((Uart.parityBits >> 16) & 0xff); \ - trace[traceLen++] = ((Uart.parityBits >> 24) & 0xff); \ - trace[traceLen++] = Uart.byteCnt; \ - memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); \ - traceLen += Uart.byteCnt; \ - if(traceLen > TRACE_LENGTH) break; \ - } \ - /* And ready to receive another command. */ \ - Uart.state = STATE_UNSYNCD; \ - /* And also reset the demod code, which might have been */ \ - /* false-triggered by the commands from the reader. */ \ - Demod.state = DEMOD_UNSYNCD; \ - LED_B_OFF(); \ - if(MillerDecoding((smpl & 0xF0) >> 4)) { rsamples = samples - Uart.samples; - HANDLE_BIT_IF_BODY + LED_C_ON(); + if(triggered) { + trace[traceLen++] = ((rsamples >> 0) & 0xff); + trace[traceLen++] = ((rsamples >> 8) & 0xff); + trace[traceLen++] = ((rsamples >> 16) & 0xff); + trace[traceLen++] = ((rsamples >> 24) & 0xff); + trace[traceLen++] = ((Uart.parityBits >> 0) & 0xff); + trace[traceLen++] = ((Uart.parityBits >> 8) & 0xff); + trace[traceLen++] = ((Uart.parityBits >> 16) & 0xff); + trace[traceLen++] = ((Uart.parityBits >> 24) & 0xff); + trace[traceLen++] = Uart.byteCnt; + memcpy(trace+traceLen, receivedCmd, Uart.byteCnt); + traceLen += Uart.byteCnt; + if(traceLen > TRACE_LENGTH) break; + } + /* And ready to receive another command. */ + Uart.state = STATE_UNSYNCD; + /* And also reset the demod code, which might have been */ + /* false-triggered by the commands from the reader. */ + Demod.state = DEMOD_UNSYNCD; + LED_B_OFF(); } if(ManchesterDecoding(smpl & 0x0F)) { rsamples = samples - Demod.samples; @@ -754,51 +760,10 @@ done: LED_D_OFF(); } -// Prepare communication bits to send to FPGA -void Sequence(SecType seq) -{ - ToSendMax++; - switch(seq) { - // CARD TO READER - case SEC_D: - // Sequence D: 11110000 - // modulation with subcarrier during first half - ToSend[ToSendMax] = 0xf0; - break; - case SEC_E: - // Sequence E: 00001111 - // modulation with subcarrier during second half - ToSend[ToSendMax] = 0x0f; - break; - case SEC_F: - // Sequence F: 00000000 - // no modulation with subcarrier - ToSend[ToSendMax] = 0x00; - break; - // READER TO CARD - case SEC_X: - // Sequence X: 00001100 - // drop after half a period - ToSend[ToSendMax] = 0x0c; - break; - case SEC_Y: - default: - // Sequence Y: 00000000 - // no drop - ToSend[ToSendMax] = 0x00; - break; - case SEC_Z: - // Sequence Z: 11000000 - // drop at start - ToSend[ToSendMax] = 0xc0; - break; - } -} - //----------------------------------------------------------------------------- // Prepare tag messages //----------------------------------------------------------------------------- -static void CodeIso14443aAsTag(const BYTE *cmd, int len) +static void CodeIso14443aAsTag(const uint8_t *cmd, int len) { int i; int oddparity; @@ -816,38 +781,38 @@ static void CodeIso14443aAsTag(const BYTE *cmd, int len) ToSendStuffBit(0); // Send startbit - Sequence(SEC_D); + ToSend[++ToSendMax] = SEC_D; for(i = 0; i < len; i++) { int j; - BYTE b = cmd[i]; + uint8_t b = cmd[i]; // Data bits oddparity = 0x01; for(j = 0; j < 8; j++) { oddparity ^= (b & 1); if(b & 1) { - Sequence(SEC_D); + ToSend[++ToSendMax] = SEC_D; } else { - Sequence(SEC_E); + ToSend[++ToSendMax] = SEC_E; } b >>= 1; } // Parity bit if(oddparity) { - Sequence(SEC_D); + ToSend[++ToSendMax] = SEC_D; } else { - Sequence(SEC_E); + ToSend[++ToSendMax] = SEC_E; } } // Send stopbit - Sequence(SEC_F); + ToSend[++ToSendMax] = SEC_F; // Flush the buffer in FPGA!! for(i = 0; i < 5; i++) { - Sequence(SEC_F); + ToSend[++ToSendMax] = SEC_F; } // Convert from last byte pos to length @@ -879,23 +844,23 @@ static void CodeStrangeAnswer() ToSendStuffBit(0); // Send startbit - Sequence(SEC_D); + ToSend[++ToSendMax] = SEC_D; // 0 - Sequence(SEC_E); + ToSend[++ToSendMax] = SEC_E; // 0 - Sequence(SEC_E); + ToSend[++ToSendMax] = SEC_E; // 1 - Sequence(SEC_D); + ToSend[++ToSendMax] = SEC_D; // Send stopbit - Sequence(SEC_F); + ToSend[++ToSendMax] = SEC_F; // Flush the buffer in FPGA!! for(i = 0; i < 5; i++) { - Sequence(SEC_F); + ToSend[++ToSendMax] = SEC_F; } // Convert from last byte pos to length @@ -912,7 +877,7 @@ static void CodeStrangeAnswer() // Stop when button is pressed // Or return TRUE when command is captured //----------------------------------------------------------------------------- -static BOOL GetIso14443aCommandFromReader(BYTE *received, int *len, int maxLen) +static int GetIso14443aCommandFromReader(uint8_t *received, int *len, int maxLen) { // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen // only, since we are receiving, not transmitting). @@ -934,7 +899,7 @@ static BOOL GetIso14443aCommandFromReader(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; if(MillerDecoding((b & 0xf0) >> 4)) { *len = Uart.byteCnt; return TRUE; @@ -956,40 +921,37 @@ void SimulateIso14443aTag(int tagType, int TagUid) // This function contains the tag emulation // Prepare protocol messages - // static const BYTE cmd1[] = { 0x26 }; -// static const BYTE response1[] = { 0x02, 0x00 }; // Says: I am Mifare 4k - original line - greg + // static const uint8_t cmd1[] = { 0x26 }; +// static const uint8_t response1[] = { 0x02, 0x00 }; // Says: I am Mifare 4k - original line - greg // - static const BYTE response1[] = { 0x44, 0x03 }; // Says: I am a DESFire Tag, ph33r me -// static const BYTE response1[] = { 0x44, 0x00 }; // Says: I am a ULTRALITE Tag, 0wn me + static const uint8_t response1[] = { 0x44, 0x03 }; // Says: I am a DESFire Tag, ph33r me +// static const uint8_t response1[] = { 0x44, 0x00 }; // Says: I am a ULTRALITE Tag, 0wn me // UID response - // static const BYTE cmd2[] = { 0x93, 0x20 }; - //static const BYTE response2[] = { 0x9a, 0xe5, 0xe4, 0x43, 0xd8 }; // original value - greg - - + // static const uint8_t cmd2[] = { 0x93, 0x20 }; + //static const uint8_t response2[] = { 0x9a, 0xe5, 0xe4, 0x43, 0xd8 }; // original value - greg // my desfire - static const BYTE response2[] = { 0x88, 0x04, 0x21, 0x3f, 0x4d }; // known uid - note cascade (0x88), 2nd byte (0x04) = NXP/Phillips + static const uint8_t response2[] = { 0x88, 0x04, 0x21, 0x3f, 0x4d }; // known uid - note cascade (0x88), 2nd byte (0x04) = NXP/Phillips // When reader selects us during cascade1 it will send cmd3 -//BYTE response3[] = { 0x04, 0x00, 0x00 }; // SAK Select (cascade1) successful response (ULTRALITE) -BYTE response3[] = { 0x24, 0x00, 0x00 }; // SAK Select (cascade1) successful response (DESFire) +//uint8_t response3[] = { 0x04, 0x00, 0x00 }; // SAK Select (cascade1) successful response (ULTRALITE) +uint8_t response3[] = { 0x24, 0x00, 0x00 }; // SAK Select (cascade1) successful response (DESFire) ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]); // send cascade2 2nd half of UID -static const BYTE response2a[] = { 0x51, 0x48, 0x1d, 0x80, 0x84 }; // uid - cascade2 - 2nd half (4 bytes) of UID+ BCCheck +static const uint8_t response2a[] = { 0x51, 0x48, 0x1d, 0x80, 0x84 }; // uid - cascade2 - 2nd half (4 bytes) of UID+ BCCheck // NOTE : THE CRC on the above may be wrong as I have obfuscated the actual UID - // When reader selects us during cascade2 it will send cmd3a -//BYTE response3a[] = { 0x00, 0x00, 0x00 }; // SAK Select (cascade2) successful response (ULTRALITE) -BYTE response3a[] = { 0x20, 0x00, 0x00 }; // SAK Select (cascade2) successful response (DESFire) +//uint8_t response3a[] = { 0x00, 0x00, 0x00 }; // SAK Select (cascade2) successful response (ULTRALITE) +uint8_t response3a[] = { 0x20, 0x00, 0x00 }; // SAK Select (cascade2) successful response (DESFire) ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); - static const BYTE response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce + static const uint8_t response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce - BYTE *resp; + uint8_t *resp; int respLen; // Longest possible response will be 16 bytes + 2 CRC = 18 bytes @@ -1005,42 +967,41 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); // 166 bytes, since every bit that needs to be send costs us a byte // - // Respond with card type - BYTE *resp1 = (((BYTE *)BigBuf) + 800); + uint8_t *resp1 = (((uint8_t *)BigBuf) + 800); int resp1Len; // Anticollision cascade1 - respond with uid - BYTE *resp2 = (((BYTE *)BigBuf) + 970); + uint8_t *resp2 = (((uint8_t *)BigBuf) + 970); int resp2Len; // Anticollision cascade2 - respond with 2nd half of uid if asked // we're only going to be asked if we set the 1st byte of the UID (during cascade1) to 0x88 - BYTE *resp2a = (((BYTE *)BigBuf) + 1140); + uint8_t *resp2a = (((uint8_t *)BigBuf) + 1140); int resp2aLen; // Acknowledge select - cascade 1 - BYTE *resp3 = (((BYTE *)BigBuf) + 1310); + uint8_t *resp3 = (((uint8_t *)BigBuf) + 1310); int resp3Len; // Acknowledge select - cascade 2 - BYTE *resp3a = (((BYTE *)BigBuf) + 1480); + uint8_t *resp3a = (((uint8_t *)BigBuf) + 1480); int resp3aLen; // Response to a read request - not implemented atm - BYTE *resp4 = (((BYTE *)BigBuf) + 1550); + uint8_t *resp4 = (((uint8_t *)BigBuf) + 1550); int resp4Len; // Authenticate response - nonce - BYTE *resp5 = (((BYTE *)BigBuf) + 1720); + uint8_t *resp5 = (((uint8_t *)BigBuf) + 1720); int resp5Len; - BYTE *receivedCmd = (BYTE *)BigBuf; + uint8_t *receivedCmd = (uint8_t *)BigBuf; int len; int i; int u; - BYTE b; + uint8_t b; // To control where we are in the protocol int order = 0; @@ -1052,7 +1013,7 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); int cmdsRecvd = 0; - BOOL fdt_indicator; + int fdt_indicator; memset(receivedCmd, 0x44, 400); @@ -1209,7 +1170,7 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); fdt_indicator = FALSE; for(;;) { 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; } if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { @@ -1240,28 +1201,28 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]); //----------------------------------------------------------------------------- // Transmit the command (to the tag) that was placed in ToSend[]. //----------------------------------------------------------------------------- -static void TransmitFor14443a(const BYTE *cmd, int len, int *samples, int *wait) +static void TransmitFor14443a(const uint8_t *cmd, int len, int *samples, int *wait) { int c; - + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); - + if (wait) if(*wait < 10) *wait = 10; - + for(c = 0; c < *wait;) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { AT91C_BASE_SSC->SSC_THR = 0x00; // For exact timing! 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(); } - + c = 0; for(;;) { if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { @@ -1272,7 +1233,7 @@ static void TransmitFor14443a(const BYTE *cmd, int len, int *samples, int *wait) } } 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(); @@ -1280,116 +1241,36 @@ static void TransmitFor14443a(const BYTE *cmd, int len, int *samples, int *wait) if (samples) *samples = (c + *wait) << 3; } -//----------------------------------------------------------------------------- -// To generate an arbitrary stream from reader -// -//----------------------------------------------------------------------------- -void ArbitraryFromReader(const BYTE *cmd, int parity, int len) -{ - int i; - int j; - int last; - BYTE b; - - ToSendReset(); - - // Start of Communication (Seq. Z) - Sequence(SEC_Z); - last = 0; - - for(i = 0; i < len; i++) { - // Data bits - b = cmd[i]; - for(j = 0; j < 8; j++) { - if(b & 1) { - // Sequence X - Sequence(SEC_X); - last = 1; - } else { - if(last == 0) { - // Sequence Z - Sequence(SEC_Z); - } - else { - // Sequence Y - Sequence(SEC_Y); - last = 0; - } - } - b >>= 1; - - } - - // Predefined parity bit, the flipper flips when needed, because of flips in byte sent - if(((parity >> (len - i - 1)) & 1)) { - // Sequence X - Sequence(SEC_X); - last = 1; - } else { - if(last == 0) { - // Sequence Z - Sequence(SEC_Z); - } - else { - // Sequence Y - Sequence(SEC_Y); - last = 0; - } - } - } - - // End of Communication - if(last == 0) { - // Sequence Z - Sequence(SEC_Z); - } - else { - // Sequence Y - Sequence(SEC_Y); - last = 0; - } - // Sequence Y - Sequence(SEC_Y); - - // Just to be sure! - Sequence(SEC_Y); - Sequence(SEC_Y); - Sequence(SEC_Y); - - // Convert from last character reference to length - ToSendMax++; -} - //----------------------------------------------------------------------------- // Code a 7-bit command without parity bit // This is especially for 0x26 and 0x52 (REQA and WUPA) //----------------------------------------------------------------------------- -void ShortFrameFromReader(const BYTE bt) +void ShortFrameFromReader(const uint8_t bt) { int j; int last; - BYTE b; + uint8_t b; ToSendReset(); // Start of Communication (Seq. Z) - Sequence(SEC_Z); + ToSend[++ToSendMax] = SEC_Z; last = 0; b = bt; for(j = 0; j < 7; j++) { if(b & 1) { // Sequence X - Sequence(SEC_X); + ToSend[++ToSendMax] = SEC_X; last = 1; } else { if(last == 0) { // Sequence Z - Sequence(SEC_Z); + ToSend[++ToSendMax] = SEC_Z; } else { // Sequence Y - Sequence(SEC_Y); + ToSend[++ToSendMax] = SEC_Y; last = 0; } } @@ -1399,20 +1280,20 @@ void ShortFrameFromReader(const BYTE bt) // End of Communication if(last == 0) { // Sequence Z - Sequence(SEC_Z); + ToSend[++ToSendMax] = SEC_Z; } else { // Sequence Y - Sequence(SEC_Y); + ToSend[++ToSendMax] = SEC_Y; last = 0; } // Sequence Y - Sequence(SEC_Y); + ToSend[++ToSendMax] = SEC_Y; // Just to be sure! - Sequence(SEC_Y); - Sequence(SEC_Y); - Sequence(SEC_Y); + ToSend[++ToSendMax] = SEC_Y; + ToSend[++ToSendMax] = SEC_Y; + ToSend[++ToSendMax] = SEC_Y; // Convert from last character reference to length ToSendMax++; @@ -1420,77 +1301,77 @@ void ShortFrameFromReader(const BYTE bt) //----------------------------------------------------------------------------- // Prepare reader command to send to FPGA -// +// //----------------------------------------------------------------------------- -void CodeIso14443aAsReaderPar(const BYTE * cmd, int len, DWORD dwParity) +void CodeIso14443aAsReaderPar(const uint8_t * cmd, int len, uint32_t dwParity) { int i, j; int last; - BYTE b; - + uint8_t b; + ToSendReset(); - + // Start of Communication (Seq. Z) - Sequence(SEC_Z); + ToSend[++ToSendMax] = SEC_Z; last = 0; - + // Generate send structure for the data bits for (i = 0; i < len; i++) { // Get the current byte to send b = cmd[i]; - + for (j = 0; j < 8; j++) { if (b & 1) { // Sequence X - Sequence(SEC_X); + ToSend[++ToSendMax] = SEC_X; last = 1; } else { if (last == 0) { // Sequence Z - Sequence(SEC_Z); + ToSend[++ToSendMax] = SEC_Z; } else { // Sequence Y - Sequence(SEC_Y); + ToSend[++ToSendMax] = SEC_Y; last = 0; } } b >>= 1; } - + // Get the parity bit if ((dwParity >> i) & 0x01) { // Sequence X - Sequence(SEC_X); + ToSend[++ToSendMax] = SEC_X; last = 1; } else { if (last == 0) { // Sequence Z - Sequence(SEC_Z); + ToSend[++ToSendMax] = SEC_Z; } else { // Sequence Y - Sequence(SEC_Y); + ToSend[++ToSendMax] = SEC_Y; last = 0; } } } - + // End of Communication if (last == 0) { // Sequence Z - Sequence(SEC_Z); + ToSend[++ToSendMax] = SEC_Z; } else { // Sequence Y - Sequence(SEC_Y); + ToSend[++ToSendMax] = SEC_Y; last = 0; } // Sequence Y - Sequence(SEC_Y); - + ToSend[++ToSendMax] = SEC_Y; + // Just to be sure! - Sequence(SEC_Y); - Sequence(SEC_Y); - Sequence(SEC_Y); - + ToSend[++ToSendMax] = SEC_Y; + ToSend[++ToSendMax] = SEC_Y; + ToSend[++ToSendMax] = SEC_Y; + // Convert from last character reference to length ToSendMax++; } @@ -1500,7 +1381,7 @@ void CodeIso14443aAsReaderPar(const BYTE * cmd, int len, DWORD dwParity) // If a response is captured return TRUE // If it takes to long return FALSE //----------------------------------------------------------------------------- -static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *samples, int *elapsed) //BYTE *buffer +static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed) //uint8_t *buffer { // buffer needs to be 512 bytes int c; @@ -1516,7 +1397,7 @@ static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *s Demod.len = 0; Demod.state = DEMOD_UNSYNCD; - BYTE b; + uint8_t b; if (elapsed) *elapsed = 0; c = 0; @@ -1529,8 +1410,8 @@ static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *s } if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { if(c < 512) { c++; } else { return FALSE; } - b = (BYTE)AT91C_BASE_SSC->SSC_RHR; - if(ManchesterDecoding((b & 0xf0) >> 4)) { + b = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + if(ManchesterDecoding((b>>4) & 0xf)) { *samples = ((c - 1) << 3) + 4; return TRUE; } @@ -1542,44 +1423,44 @@ static BOOL GetIso14443aAnswerFromTag(BYTE *receivedResponse, int maxLen, int *s } } -void ReaderTransmitShort(const BYTE* bt) +void ReaderTransmitShort(const uint8_t* bt) { int wait = 0; int samples = 0; ShortFrameFromReader(*bt); - + // Select the card - TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); - + TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); + // Store reader command in buffer if (tracing) LogTrace(bt,1,0,GetParity(bt,1),TRUE); } -void ReaderTransmitPar(BYTE* frame, int len, DWORD par) +void ReaderTransmitPar(uint8_t* frame, int len, uint32_t par) { int wait = 0; int samples = 0; - + // This is tied to other size changes - // BYTE* frame_addr = ((BYTE*)BigBuf) + 2024; + // uint8_t* frame_addr = ((uint8_t*)BigBuf) + 2024; CodeIso14443aAsReaderPar(frame,len,par); - + // Select the card - TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); - + TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); + // Store reader command in buffer if (tracing) LogTrace(frame,len,0,par,TRUE); } -void ReaderTransmit(BYTE* frame, int len) +void ReaderTransmit(uint8_t* frame, int len) { // Generate parity and redirect ReaderTransmitPar(frame,len,GetParity(frame,len)); } -BOOL ReaderReceive(BYTE* receivedAnswer) +int ReaderReceive(uint8_t* receivedAnswer) { int samples = 0; if (!GetIso14443aAnswerFromTag(receivedAnswer,100,&samples,0)) return FALSE; @@ -1591,20 +1472,20 @@ BOOL ReaderReceive(BYTE* receivedAnswer) // Read an ISO 14443a tag. Send out commands and store answers. // //----------------------------------------------------------------------------- -void ReaderIso14443a(DWORD parameter) +void ReaderIso14443a(uint32_t parameter) { // Anticollision - BYTE wupa[] = { 0x52 }; - BYTE sel_all[] = { 0x93,0x20 }; - BYTE sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - BYTE sel_all_c2[] = { 0x95,0x20 }; - BYTE sel_uid_c2[] = { 0x95,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + uint8_t wupa[] = { 0x52 }; + uint8_t sel_all[] = { 0x93,0x20 }; + uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + uint8_t sel_all_c2[] = { 0x95,0x20 }; + uint8_t sel_uid_c2[] = { 0x95,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; // Mifare AUTH - BYTE mf_auth[] = { 0x60,0x00,0xf5,0x7b }; -// BYTE mf_nr_ar[] = { 0x00,0x00,0x00,0x00 }; - - BYTE* receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes + uint8_t mf_auth[] = { 0x60,0x00,0xf5,0x7b }; +// uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00 }; + + uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes traceLen = 0; // Setup SSC @@ -1617,7 +1498,6 @@ void ReaderIso14443a(DWORD parameter) SpinDelay(200); SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(); // Now give it time to spin up. // Signal field is on with the appropriate LED @@ -1633,12 +1513,12 @@ void ReaderIso14443a(DWORD parameter) { // Broadcast for a card, WUPA (0x52) will force response from all cards in the field ReaderTransmitShort(wupa); - + // Test if the action was cancelled if(BUTTON_PRESS()) { break; } - + // Receive the ATQA if (!ReaderReceive(receivedAnswer)) continue; @@ -1647,7 +1527,7 @@ void ReaderIso14443a(DWORD parameter) // Receive the UID if (!ReaderReceive(receivedAnswer)) continue; - + // Construct SELECT UID command // First copy the 5 bytes (Mifare Classic) after the 93 70 memcpy(sel_uid+2,receivedAnswer,5); @@ -1656,29 +1536,29 @@ void ReaderIso14443a(DWORD parameter) // Transmit SELECT_UID ReaderTransmit(sel_uid,sizeof(sel_uid)); - + // Receive the SAK if (!ReaderReceive(receivedAnswer)) continue; // OK we have selected at least at cascade 1, lets see if first byte of UID was 0x88 in // which case we need to make a cascade 2 request and select - this is a long UID - // When the UID is not complete, the 3nd bit (from the right) is set in the SAK. + // When the UID is not complete, the 3nd bit (from the right) is set in the SAK. if (receivedAnswer[0] &= 0x04) { // Transmit SELECT_ALL ReaderTransmit(sel_all_c2,sizeof(sel_all_c2)); - + // Receive the UID if (!ReaderReceive(receivedAnswer)) continue; - + // Construct SELECT UID command memcpy(sel_uid_c2+2,receivedAnswer,5); // Secondly compute the two CRC bytes at the end AppendCrc14443a(sel_uid_c2,7); - + // Transmit SELECT_UID ReaderTransmit(sel_uid_c2,sizeof(sel_uid_c2)); - + // Receive the SAK if (!ReaderReceive(receivedAnswer)) continue; } @@ -1701,44 +1581,43 @@ void ReaderIso14443a(DWORD parameter) // Read an ISO 14443a tag. Send out commands and store answers. // //----------------------------------------------------------------------------- -void ReaderMifare(DWORD parameter) +void ReaderMifare(uint32_t parameter) { - + // Anticollision - BYTE wupa[] = { 0x52 }; - BYTE sel_all[] = { 0x93,0x20 }; - BYTE sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - + uint8_t wupa[] = { 0x52 }; + uint8_t sel_all[] = { 0x93,0x20 }; + uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + // Mifare AUTH - BYTE mf_auth[] = { 0x60,0x00,0xf5,0x7b }; - BYTE mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; - - BYTE* receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes + uint8_t mf_auth[] = { 0x60,0x00,0xf5,0x7b }; + uint8_t mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }; + + uint8_t* receivedAnswer = (((uint8_t *)BigBuf) + 3560); // was 3560 - tied to other size changes traceLen = 0; tracing = false; - + // Setup SSC FpgaSetupSsc(); - + // Start from off (no field generated) // Signal field is off with the appropriate LED LED_D_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(200); - + SetAdcMuxFor(GPIO_MUXSEL_HIPKD); - FpgaSetupSsc(); - + // Now give it time to spin up. // Signal field is on with the appropriate LED LED_D_ON(); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); SpinDelay(200); - + LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - + // Broadcast for a card, WUPA (0x52) will force response from all cards in the field ReaderTransmitShort(wupa); // Receive the ATQA @@ -1752,14 +1631,14 @@ void ReaderMifare(DWORD parameter) memcpy(sel_uid+2,receivedAnswer,5); // Secondly compute the two CRC bytes at the end AppendCrc14443a(sel_uid,7); - + byte_t nt_diff = 0; LED_A_OFF(); byte_t par = 0; byte_t par_mask = 0xff; byte_t par_low = 0; - BOOL led_on = TRUE; - + int led_on = TRUE; + tracing = FALSE; byte_t nt[4]; byte_t nt_attacked[4]; @@ -1772,44 +1651,44 @@ void ReaderMifare(DWORD parameter) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(200); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); - + // Broadcast for a card, WUPA (0x52) will force response from all cards in the field ReaderTransmitShort(wupa); - + // Test if the action was cancelled if(BUTTON_PRESS()) { break; } - + // Receive the ATQA if (!ReaderReceive(receivedAnswer)) continue; - + // Transmit SELECT_ALL ReaderTransmit(sel_all,sizeof(sel_all)); - + // Receive the UID if (!ReaderReceive(receivedAnswer)) continue; - + // Transmit SELECT_UID ReaderTransmit(sel_uid,sizeof(sel_uid)); - + // Receive the SAK if (!ReaderReceive(receivedAnswer)) continue; - + // Transmit MIFARE_CLASSIC_AUTH ReaderTransmit(mf_auth,sizeof(mf_auth)); - + // Receive the (16 bit) "random" nonce if (!ReaderReceive(receivedAnswer)) continue; memcpy(nt,receivedAnswer,4); // Transmit reader nonce and reader answer ReaderTransmitPar(mf_nr_ar,sizeof(mf_nr_ar),par); - + // Receive 4 bit answer if (ReaderReceive(receivedAnswer)) { - if (nt_diff == 0) + if (nt_diff == 0) { LED_A_ON(); memcpy(nt_attacked,nt,4); @@ -1823,10 +1702,10 @@ void ReaderMifare(DWORD parameter) if(led_on) LED_B_ON(); else LED_B_OFF(); par_list[nt_diff] = par; ks_list[nt_diff] = receivedAnswer[0]^0x05; - + // Test if the information is complete if (nt_diff == 0x07) break; - + nt_diff = (nt_diff+1) & 0x07; mf_nr_ar[3] = nt_diff << 5; par = par_low; @@ -1839,12 +1718,12 @@ void ReaderMifare(DWORD parameter) } } } - - LogTraceInfo(sel_uid+2,4); - LogTraceInfo(nt,4); - LogTraceInfo(par_list,8); - LogTraceInfo(ks_list,8); - + + LogTrace(sel_uid+2,4,0,GetParity(sel_uid+2,4),TRUE); + LogTrace(nt,4,0,GetParity(nt,4),TRUE); + LogTrace(par_list,8,0,GetParity(par_list,8),TRUE); + LogTrace(ks_list,8,0,GetParity(ks_list,8),TRUE); + // Thats it... FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff();