]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/iso14443a.c
set svn:ignore
[proxmark3-svn] / armsrc / iso14443a.c
index d39fbdd4e51600e70903eb3bb721ae57bf376fda..a7d094591f59c6196ea089c5d0683f4c6d622e0b 100644 (file)
@@ -10,6 +10,7 @@
 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
@@ -92,6 +93,11 @@ BOOL LogTrace(const BYTE * btBytes, int iLen, int iSamples, DWORD dwParity, BOOL
   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
@@ -735,13 +741,13 @@ void SnoopIso14443a(void)
 \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
@@ -1138,8 +1144,8 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
                } 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
@@ -1150,21 +1156,20 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
                } 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
@@ -1228,7 +1233,7 @@ ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
 \r
     }\r
 \r
-       DbpIntegers(happened, happened2, cmdsRecvd);\r
+       Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);\r
        LED_A_OFF();\r
 }\r
 \r
@@ -1548,7 +1553,7 @@ void ReaderTransmitShort(const BYTE* bt)
   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
@@ -1558,14 +1563,13 @@ void ReaderTransmitPar(BYTE* frame, int len, DWORD par)
   \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
@@ -1579,7 +1583,7 @@ BOOL ReaderReceive(BYTE* receivedAnswer)
 {\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
@@ -1689,6 +1693,160 @@ void ReaderIso14443a(DWORD parameter)
   // 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
Impressum, Datenschutz