//-----------------------------------------------------------------------------\r
#include <proxmark3.h>\r
#include "apps.h"\r
-#include "../common/iso14443_crc.c"\r
+#include "iso14443crc.h"\r
\r
static BYTE *trace = (BYTE *) BigBuf;\r
static int traceLen = 0;\r
static int rsamples = 0;\r
+static BOOL tracing = TRUE;\r
\r
typedef enum {\r
SEC_D = 1,\r
return TRUE;\r
}\r
\r
+BOOL LogTraceInfo(byte_t* data, size_t len)\r
+{\r
+ return LogTrace(data,len,0,GetParity(data,len),TRUE);\r
+}\r
+\r
//-----------------------------------------------------------------------------\r
// The software UART that receives commands from the reader, and its state\r
// variables.\r
\r
DbpString("COMMAND FINISHED");\r
\r
- DbpIntegers(maxBehindBy, Uart.state, Uart.byteCnt);\r
- DbpIntegers(Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
+ Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);\r
+ Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
\r
done:\r
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;\r
- DbpIntegers(maxBehindBy, Uart.state, Uart.byteCnt);\r
- DbpIntegers(Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
+ Dbprintf("%x %x %x", maxBehindBy, Uart.state, Uart.byteCnt);\r
+ Dbprintf("%x %x %x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);\r
LED_A_OFF();\r
LED_B_OFF();\r
LED_C_OFF();\r
} else if(receivedCmd[0] == 0x30) {\r
// Received a READ\r
resp = resp4; respLen = resp4Len; order = 4; // Do nothing\r
- DbpString("Read request from reader:");\r
- DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
+ Dbprintf("Read request from reader: %x %x %x",\r
+ receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
\r
\r
} else if(receivedCmd[0] == 0x50) {\r
} else if(receivedCmd[0] == 0x60) {\r
// Received an authentication request\r
resp = resp5; respLen = resp5Len; order = 7;\r
- DbpString("Authenticate request from reader:");\r
- DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
+ Dbprintf("Authenticate request from reader: %x %x %x",\r
+ receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
\r
} else if(receivedCmd[0] == 0xE0) {\r
// Received a RATS request\r
resp = resp1; respLen = 0;order = 70;\r
- DbpString("RATS request from reader:");\r
- DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
+ Dbprintf("RATS request from reader: %x %x %x",\r
+ receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
} else {\r
// Never seen this command before\r
- DbpString("Unknown command received from reader:");\r
- DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);\r
- DbpIntegers(receivedCmd[3], receivedCmd[4], receivedCmd[5]);\r
- DbpIntegers(receivedCmd[6], receivedCmd[7], receivedCmd[8]);\r
-\r
+ Dbprintf("Unknown command received from reader: %x %x %x %x %x %x %x %x %x",\r
+ receivedCmd[0], receivedCmd[1], receivedCmd[2],\r
+ receivedCmd[3], receivedCmd[3], receivedCmd[4],\r
+ receivedCmd[5], receivedCmd[6], receivedCmd[7]);\r
// Do not respond\r
resp = resp1; respLen = 0; order = 0;\r
}\r
\r
}\r
\r
- DbpIntegers(happened, happened2, cmdsRecvd);\r
+ Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);\r
LED_A_OFF();\r
}\r
\r
TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); \r
\r
// Store reader command in buffer\r
- LogTrace(bt,1,0,GetParity(bt,1),TRUE);\r
+ if (tracing) LogTrace(bt,1,0,GetParity(bt,1),TRUE);\r
}\r
\r
void ReaderTransmitPar(BYTE* frame, int len, DWORD par)\r
\r
// This is tied to other size changes\r
// BYTE* frame_addr = ((BYTE*)BigBuf) + 2024; \r
- \r
CodeIso14443aAsReaderPar(frame,len,par);\r
\r
// Select the card\r
TransmitFor14443a(ToSend, ToSendMax, &samples, &wait); \r
\r
// Store reader command in buffer\r
- LogTrace(frame,len,0,par,TRUE);\r
+ if (tracing) LogTrace(frame,len,0,par,TRUE);\r
}\r
\r
\r
{\r
int samples = 0;\r
if (!GetIso14443aAnswerFromTag(receivedAnswer,100,&samples,0)) return FALSE;\r
- LogTrace(receivedAnswer,Demod.len,samples,Demod.parityBits,FALSE);\r
+ if (tracing) LogTrace(receivedAnswer,Demod.len,samples,Demod.parityBits,FALSE);\r
return TRUE;\r
}\r
\r
// Thats it...\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
- DbpIntegers(rsamples, 0xCC, 0xCC);\r
+ Dbprintf("%x %x %x", rsamples, 0xCC, 0xCC);\r
DbpString("ready..");\r
}\r
+\r
+//-----------------------------------------------------------------------------\r
+// Read an ISO 14443a tag. Send out commands and store answers.\r
+//\r
+//-----------------------------------------------------------------------------\r
+void ReaderMifare(DWORD parameter)\r
+{\r
+ \r
+ // Anticollision\r
+ BYTE wupa[] = { 0x52 };\r
+ BYTE sel_all[] = { 0x93,0x20 };\r
+ BYTE sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
+ \r
+ // Mifare AUTH\r
+ BYTE mf_auth[] = { 0x60,0x00,0xf5,0x7b };\r
+ BYTE mf_nr_ar[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };\r
+ \r
+ BYTE* receivedAnswer = (((BYTE *)BigBuf) + 3560); // was 3560 - tied to other size changes\r
+ traceLen = 0;\r
+ tracing = false;\r
+ \r
+ // Setup SSC\r
+ FpgaSetupSsc();\r
+ \r
+ // Start from off (no field generated)\r
+ // Signal field is off with the appropriate LED\r
+ LED_D_OFF();\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ SpinDelay(200);\r
+ \r
+ SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
+ FpgaSetupSsc();\r
+ \r
+ // Now give it time to spin up.\r
+ // Signal field is on with the appropriate LED\r
+ LED_D_ON();\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
+ SpinDelay(200);\r
+ \r
+ LED_A_ON();\r
+ LED_B_OFF();\r
+ LED_C_OFF();\r
+ \r
+ // Broadcast for a card, WUPA (0x52) will force response from all cards in the field\r
+ ReaderTransmitShort(wupa);\r
+ // Receive the ATQA\r
+ ReaderReceive(receivedAnswer);\r
+ // Transmit SELECT_ALL\r
+ ReaderTransmit(sel_all,sizeof(sel_all));\r
+ // Receive the UID\r
+ ReaderReceive(receivedAnswer);\r
+ // Construct SELECT UID command\r
+ // First copy the 5 bytes (Mifare Classic) after the 93 70\r
+ memcpy(sel_uid+2,receivedAnswer,5);\r
+ // Secondly compute the two CRC bytes at the end\r
+ AppendCrc14443a(sel_uid,7);\r
+ \r
+ byte_t nt_diff = 0;\r
+ LED_A_OFF();\r
+ byte_t par = 0;\r
+ byte_t par_mask = 0xff;\r
+ byte_t par_low = 0;\r
+ BOOL led_on = TRUE;\r
+ \r
+ tracing = FALSE;\r
+ byte_t nt[4];\r
+ byte_t nt_attacked[4];\r
+ byte_t par_list[8];\r
+ byte_t ks_list[8];\r
+ num_to_bytes(parameter,4,nt_attacked);\r
+\r
+ while(TRUE)\r
+ {\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ SpinDelay(200);\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);\r
+ \r
+ // Broadcast for a card, WUPA (0x52) will force response from all cards in the field\r
+ ReaderTransmitShort(wupa);\r
+ \r
+ // Test if the action was cancelled\r
+ if(BUTTON_PRESS()) {\r
+ break;\r
+ }\r
+ \r
+ // Receive the ATQA\r
+ if (!ReaderReceive(receivedAnswer)) continue;\r
+ \r
+ // Transmit SELECT_ALL\r
+ ReaderTransmit(sel_all,sizeof(sel_all));\r
+ \r
+ // Receive the UID\r
+ if (!ReaderReceive(receivedAnswer)) continue;\r
+ \r
+ // Transmit SELECT_UID\r
+ ReaderTransmit(sel_uid,sizeof(sel_uid));\r
+ \r
+ // Receive the SAK\r
+ if (!ReaderReceive(receivedAnswer)) continue;\r
+ \r
+ // Transmit MIFARE_CLASSIC_AUTH\r
+ ReaderTransmit(mf_auth,sizeof(mf_auth));\r
+ \r
+ // Receive the (16 bit) "random" nonce\r
+ if (!ReaderReceive(receivedAnswer)) continue;\r
+ memcpy(nt,receivedAnswer,4);\r
+\r
+ // Transmit reader nonce and reader answer\r
+ ReaderTransmitPar(mf_nr_ar,sizeof(mf_nr_ar),par);\r
+ \r
+ // Receive 4 bit answer\r
+ if (ReaderReceive(receivedAnswer))\r
+ {\r
+ if (nt_diff == 0) \r
+ {\r
+ LED_A_ON();\r
+ memcpy(nt_attacked,nt,4);\r
+ par_mask = 0xf8;\r
+ par_low = par & 0x07;\r
+ }\r
+\r
+ if (memcmp(nt,nt_attacked,4) != 0) continue;\r
+\r
+ led_on = !led_on;\r
+ if(led_on) LED_B_ON(); else LED_B_OFF();\r
+ par_list[nt_diff] = par;\r
+ ks_list[nt_diff] = receivedAnswer[0]^0x05;\r
+ \r
+ // Test if the information is complete\r
+ if (nt_diff == 0x07) break;\r
+ \r
+ nt_diff = (nt_diff+1) & 0x07;\r
+ mf_nr_ar[3] = nt_diff << 5;\r
+ par = par_low;\r
+ } else {\r
+ if (nt_diff == 0)\r
+ {\r
+ par++;\r
+ } else {\r
+ par = (((par>>3)+1) << 3) | par_low;\r
+ }\r
+ }\r
+ }\r
+ \r
+ LogTraceInfo(sel_uid+2,4);\r
+ LogTraceInfo(nt,4);\r
+ LogTraceInfo(par_list,8);\r
+ LogTraceInfo(ks_list,8);\r
+ \r
+ // Thats it...\r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ LEDsoff();\r
+ tracing = TRUE;\r
+}\r