]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
mifare firmware update
authorroel@libnfc.org <roel@libnfc.org@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Wed, 30 Dec 2009 00:11:50 +0000 (00:11 +0000)
committerroel@libnfc.org <roel@libnfc.org@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Wed, 30 Dec 2009 00:11:50 +0000 (00:11 +0000)
armsrc/appmain.c
armsrc/apps.h
armsrc/iso14443a.c
armsrc/util.c

index 9026f7217792d2709fe8d70c1b0538fa67974769..11047b1cbdc75820e41ef104c1b3ab7447da05bd 100644 (file)
@@ -593,6 +593,12 @@ void UsbPacketReceived(BYTE *packet, int len)
                        break;\r
 #endif\r
 \r
+#ifdef WITH_ISO14443a\r
+               case CMD_READER_MIFARE:\r
+                       ReaderMifare(c->arg[0]);\r
+                       break;\r
+#endif\r
+      \r
 #ifdef WITH_ISO14443b\r
                case CMD_SNOOP_ISO_14443:\r
                        SnoopIso14443();\r
index d90d595a880cc34b84e1cf9cf217279459096c63..95080eaec7f77d2c4b3e164383948fe02a9cff3c 100644 (file)
@@ -7,6 +7,10 @@
 #ifndef __APPS_H\r
 #define __APPS_H\r
 \r
+#include "stdint.h"\r
+#include "stddef.h"\r
+typedef unsigned char byte_t;\r
+\r
 // The large multi-purpose buffer, typically used to hold A/D samples,\r
 // maybe processed in some way.\r
 DWORD BigBuf[12000];\r
@@ -82,14 +86,15 @@ void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen);
 void SimulateIso14443Tag(void);\r
 void AcquireRawAdcSamplesIso14443(DWORD parameter);\r
 void ReadSRI512Iso14443(DWORD parameter);\r
-void ReadSRIX4KIso14443(DWORD parameter);
-void ReadSTMemoryIso14443(DWORD parameter,DWORD dwLast);
+void ReadSRIX4KIso14443(DWORD parameter);\r
+void ReadSTMemoryIso14443(DWORD parameter,DWORD dwLast);\r
 void SnoopIso14443(void);\r
 \r
 /// iso14443a.h\r
 void SnoopIso14443a(void);\r
 void SimulateIso14443aTag(int tagType, int TagUid);    // ## simulate iso14443a tag\r
 void ReaderIso14443a(DWORD parameter);\r
+void ReaderMifare(DWORD parameter);\r
 \r
 /// iso15693.h\r
 void AcquireRawAdcSamplesIso15693(void);\r
@@ -111,6 +116,9 @@ void *memcpy(void *dest, const void *src, int len);
 void *memset(void *dest, int c, int len);\r
 int memcmp(const void *av, const void *bv, int len);\r
 char *strncat(char *dest, const char *src, unsigned int n);\r
+void num_to_bytes(uint64_t n, size_t len, byte_t* dest);\r
+uint64_t bytes_to_num(byte_t* src, size_t len);\r
+\r
 void SpinDelay(int ms);\r
 void SpinDelayUs(int us);\r
 void LED(int led, int ms);\r
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 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
@@ -1548,7 +1554,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 +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
   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 +1584,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
@@ -1692,3 +1697,157 @@ void ReaderIso14443a(DWORD parameter)
        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
index 3cad25f438928d4ffc464b8b7e29c09777eda665..e6332a7b57615224a547792f6082e694aed6046e 100644 (file)
@@ -64,6 +64,24 @@ char* strncat(char *dest, const char *src, unsigned int n)
        return dest;\r
 }\r
 \r
+void num_to_bytes(uint64_t n, size_t len, byte_t* dest)\r
+{\r
+       while (len--) {\r
+               dest[len] = (byte_t) n;\r
+               n >>= 8;\r
+       }\r
+}\r
+\r
+uint64_t bytes_to_num(byte_t* src, size_t len)\r
+{\r
+       uint64_t num = 0;\r
+       while (len--)\r
+       {\r
+               num = (num << 8) | (*src);\r
+               src++;\r
+       }\r
+       return num;\r
+}\r
 \r
 void LEDsoff()\r
 {\r
Impressum, Datenschutz