]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/iso14443a.c
mifare usb update
[proxmark3-svn] / armsrc / iso14443a.c
index d39fbdd4e51600e70903eb3bb721ae57bf376fda..4c04571e88025f0357c96a1a8d071ef58483d672 100644 (file)
@@ -10,6 +10,7 @@
 static BYTE *trace = (BYTE *) BigBuf;\r
 static int traceLen = 0;\r
 static int rsamples = 0;\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
 \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
   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
 // The software UART that receives commands from the reader, and its state\r
 // variables.\r
@@ -1548,7 +1554,7 @@ void ReaderTransmitShort(const BYTE* bt)
   TransmitFor14443a(ToSend, ToSendMax, &samples, &wait);               \r
   \r
   // Store reader command in buffer\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
 \r
 void ReaderTransmitPar(BYTE* frame, int len, DWORD par)\r
@@ -1558,14 +1564,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
   // 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
   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
 \r
 \r
@@ -1579,7 +1584,7 @@ BOOL ReaderReceive(BYTE* receivedAnswer)
 {\r
   int samples = 0;\r
   if (!GetIso14443aAnswerFromTag(receivedAnswer,100,&samples,0)) return FALSE;\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
   return TRUE;\r
 }\r
 \r
@@ -1692,3 +1697,157 @@ void ReaderIso14443a(DWORD parameter)
        DbpIntegers(rsamples, 0xCC, 0xCC);\r
        DbpString("ready..");\r
 }\r
        DbpIntegers(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