]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
MAJOR update, added hitag2 reader, emulation and eavesdropping, lots of new code...
authorroel@libnfc.org <roel@libnfc.org@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Tue, 18 Sep 2012 13:52:50 +0000 (13:52 +0000)
committerroel@libnfc.org <roel@libnfc.org@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Tue, 18 Sep 2012 13:52:50 +0000 (13:52 +0000)
client/Makefile
client/cmdhf14a.c
client/cmdhf14b.c
client/cmdhficlass.c
client/cmdlf.c
client/cmdlfhitag.c [new file with mode: 0644]
client/cmdlfhitag.h [new file with mode: 0644]
client/cmdmain.c
client/data.c
client/data.h
client/nonce2key/nonce2key.h

index ff676f4f91557ae0fbb857eb8d04a69785eeabf9..8ddde4bdb2169dd55031f8a39bf1e744269e5d6a 100644 (file)
@@ -64,6 +64,7 @@ CMDSRCS = \
                        cmdlf.c \
                        cmdlfem4x.c \
                        cmdlfhid.c \
                        cmdlf.c \
                        cmdlfem4x.c \
                        cmdlfhid.c \
+                       cmdlfhitag.c \
                        cmdlfti.c \
                        cmdparser.c \
                        cmdmain.c
                        cmdlfti.c \
                        cmdparser.c \
                        cmdmain.c
index 4b405d2b1b0d7db24e051bc0291cec26a88ca98a..be7afc77f26ca7bfbf5366746d3775f217657b84 100644 (file)
@@ -28,7 +28,7 @@ static int CmdHelp(const char *Cmd);
 int CmdHF14AList(const char *Cmd)
 {
   uint8_t got[1920];
 int CmdHF14AList(const char *Cmd)
 {
   uint8_t got[1920];
-  GetFromBigBuf(got, sizeof(got));
+  GetFromBigBuf(got,sizeof(got),0);
 
   PrintAndLog("recorded activity:");
   PrintAndLog(" ETU     :rssi: who bytes");
 
   PrintAndLog("recorded activity:");
   PrintAndLog(" ETU     :rssi: who bytes");
index 79c1b8ed6f689c4e22f2bd46444a80cfd6535ae7..68c7fa68616043d4b68c91df753f409e636ffbea 100644 (file)
@@ -144,7 +144,7 @@ demodError:
 int CmdHF14BList(const char *Cmd)
 {
   uint8_t got[960];
 int CmdHF14BList(const char *Cmd)
 {
   uint8_t got[960];
-  GetFromBigBuf(got, sizeof(got));
+  GetFromBigBuf(got,sizeof(got),0);
 
   PrintAndLog("recorded activity:");
   PrintAndLog(" time  :rssi: who bytes");
 
   PrintAndLog("recorded activity:");
   PrintAndLog(" time  :rssi: who bytes");
index 6064b4e75f118d6d2d01930444c3d792a24f993c..7c31dab39974c3577fa085af87b524e202e6b729 100644 (file)
@@ -26,7 +26,7 @@ static int CmdHelp(const char *Cmd);
 int CmdHFiClassList(const char *Cmd)
 {
   uint8_t got[1920];
 int CmdHFiClassList(const char *Cmd)
 {
   uint8_t got[1920];
-  GetFromBigBuf(got, sizeof(got));
+  GetFromBigBuf(got,sizeof(got),0);
 
   PrintAndLog("recorded activity:");
   PrintAndLog(" ETU     :rssi: who bytes");
 
   PrintAndLog("recorded activity:");
   PrintAndLog(" ETU     :rssi: who bytes");
index 6be555bbaaf2451386debe75d9d48a4bb93e5c94..78e1f98869b919c97f09ee5cbd0bdd550ebc8d79 100644 (file)
@@ -23,6 +23,7 @@
 #include "cmdlfhid.h"
 #include "cmdlfti.h"
 #include "cmdlfem4x.h"
 #include "cmdlfhid.h"
 #include "cmdlfti.h"
 #include "cmdlfem4x.h"
+#include "cmdlfhitag.h"
 
 static int CmdHelp(const char *Cmd);
 
 
 static int CmdHelp(const char *Cmd);
 
@@ -535,6 +536,7 @@ static command_t CommandTable[] =
   {"simbidir",    CmdLFSimBidir,      0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
   {"simman",      CmdLFSimManchester, 0, "<Clock> <Bitstream> [GAP] Simulate arbitrary Manchester LF tag"},
   {"ti",          CmdLFTI,            1, "{ TI RFIDs... }"},
   {"simbidir",    CmdLFSimBidir,      0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
   {"simman",      CmdLFSimManchester, 0, "<Clock> <Bitstream> [GAP] Simulate arbitrary Manchester LF tag"},
   {"ti",          CmdLFTI,            1, "{ TI RFIDs... }"},
+  {"hitag",       CmdLFHitag,         1, "{ Hitag tags and transponders... }"},
   {"vchdemod",    CmdVchDemod,        1, "['clone'] -- Demodulate samples for VeriChip"},
   {NULL, NULL, 0, NULL}
 };
   {"vchdemod",    CmdVchDemod,        1, "['clone'] -- Demodulate samples for VeriChip"},
   {NULL, NULL, 0, NULL}
 };
diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c
new file mode 100644 (file)
index 0000000..703767b
--- /dev/null
@@ -0,0 +1,203 @@
+//-----------------------------------------------------------------------------
+// Copyright (C) 2012 Roel Verdult
+//
+// 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.
+//-----------------------------------------------------------------------------
+// Low frequency Hitag support
+//-----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "data.h"
+#include "proxusb.h"
+#include "ui.h"
+#include "cmdparser.h"
+#include "common.h"
+#include "util.h"
+#include "hitag2.h"
+
+static int CmdHelp(const char *Cmd);
+
+int CmdLFHitagList(const char *Cmd)
+{
+  uint8_t got[3000];
+  GetFromBigBuf(got,sizeof(got),0);
+
+  PrintAndLog("recorded activity:");
+  PrintAndLog(" ETU     :rssi: who bytes");
+  PrintAndLog("---------+----+----+-----------");
+
+  int i = 0;
+  int prev = -1;
+
+  for (;;) {
+    if(i >= 1900) {
+      break;
+    }
+
+    bool isResponse;
+    int timestamp = *((uint32_t *)(got+i));
+    if (timestamp & 0x80000000) {
+      timestamp &= 0x7fffffff;
+      isResponse = 1;
+    } else {
+      isResponse = 0;
+    }
+
+    int metric = 0;
+    int parityBits = *((uint32_t *)(got+i+4));
+    // 4 bytes of additional information...
+    // maximum of 32 additional parity bit information
+    //
+    // TODO:
+    // at each quarter bit period we can send power level (16 levels)
+    // or each half bit period in 256 levels.
+
+    int len = got[i+8];
+
+    if (len > 100) {
+      break;
+    }
+    if (i + len >= 1900) {
+      break;
+    }
+
+    uint8_t *frame = (got+i+9);
+
+    // Break and stick with current result if buffer was not completely full
+    if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
+
+    char line[1000] = "";
+    int j;
+    for (j = 0; j < len; j++) {
+      int oddparity = 0x01;
+      int k;
+
+      for (k=0;k<8;k++) {
+        oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
+      }
+
+      //if((parityBits >> (len - j - 1)) & 0x01) {
+      if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
+        sprintf(line+(j*4), "%02x!  ", frame[j]);
+      }
+      else {
+        sprintf(line+(j*4), "%02x   ", frame[j]);
+      }
+    }
+
+    char metricString[100];
+    if (isResponse) {
+      sprintf(metricString, "%3d", metric);
+    } else {
+      strcpy(metricString, "   ");
+    }
+
+    PrintAndLog(" +%7d: %s: %s %s",
+      (prev < 0 ? 0 : (timestamp - prev)),
+      metricString,
+      (isResponse ? "TAG" : "   "),
+      line);
+
+    prev = timestamp;
+    i += (len + 9);
+  }
+       return 0;
+}
+
+int CmdLFHitagSnoop(const char *Cmd) {
+  UsbCommand c = {CMD_SNOOP_HITAG};
+  SendCommand(&c);
+  return 0;
+}
+
+int CmdLFHitagSim(const char *Cmd) {
+  UsbCommand c = {CMD_SIMULATE_HITAG};
+       char filename[256];
+       FILE* pf;
+       bool tag_mem_supplied;
+
+       param_getstr(Cmd,0,filename);
+       
+       if (strlen(filename) > 0) {
+               if ((pf = fopen(filename,"rb+")) == NULL) {
+                       PrintAndLog("Error: Could not open file [%s]",filename);
+                       return 1;
+               }
+               tag_mem_supplied = true;
+               fread(c.d.asBytes,48,1,pf);
+               fclose(pf);
+       } else {
+               tag_mem_supplied = false;
+       }
+       
+       // Does the tag comes with memory
+       c.arg[0] = (uint32_t)tag_mem_supplied;
+
+  SendCommand(&c);
+  return 0;
+}
+
+int CmdLFHitagReader(const char *Cmd) {
+//  UsbCommand c = {CMD_READER_HITAG};
+       
+//     param_get32ex(Cmd,1,0,16);
+       UsbCommand c = {CMD_READER_HITAG};//, {param_get32ex(Cmd,0,0,10),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),param_get32ex(Cmd,3,0,16)}};
+       hitag_data* htd = (hitag_data*)c.d.asBytes;
+       hitag_function htf = param_get32ex(Cmd,0,0,10);
+       
+       switch (htf) {
+               case RHT2F_PASSWORD: {
+                       num_to_bytes(param_get32ex(Cmd,1,0,16),4,htd->pwd.password);
+               } break;
+               case RHT2F_AUTHENTICATE: {
+                       num_to_bytes(param_get32ex(Cmd,1,0,16),4,htd->auth.NrAr);
+                       num_to_bytes(param_get32ex(Cmd,2,0,16),4,htd->auth.NrAr+4);
+               } break;
+               case RHT2F_TEST_AUTH_ATTEMPTS: {
+                       // No additional parameters needed
+               } break;
+               default: {
+                       PrintAndLog("Error: unkown reader function %d",htf);
+                       PrintAndLog("Hitag reader functions",htf);
+                       PrintAndLog(" HitagS (0*)",htf);
+                       PrintAndLog(" Hitag1 (1*)",htf);
+                       PrintAndLog(" Hitag2 (2*)",htf);
+                       PrintAndLog("  21 <password> (password mode)",htf);
+                       PrintAndLog("  22 <nr> <ar> (authentication)",htf);
+                       PrintAndLog("  25 (test recorded authentications)",htf);
+                       return 1;
+               } break;
+       }
+
+       // Copy the hitag2 function into the first argument
+       c.arg[0] = htf;
+
+  SendCommand(&c);
+  return 0;
+}
+
+static command_t CommandTableHitag[] = 
+{
+  {"help",    CmdHelp,           1, "This help"},
+  {"list",    CmdLFHitagList,    1, "List Hitag trace history"},
+  {"reader",  CmdLFHitagReader,  1, "Act like a Hitag Reader"},
+  {"sim",     CmdLFHitagSim,     1, "Simulate Hitag transponder"},
+  {"snoop",   CmdLFHitagSnoop,   1, "Eavesdrop Hitag communication"},
+               {NULL, NULL, 0, NULL}
+};
+
+int CmdLFHitag(const char *Cmd)
+{
+  CmdsParse(CommandTableHitag, Cmd);
+  return 0;
+}
+
+int CmdHelp(const char *Cmd)
+{
+  CmdsHelp(CommandTableHitag);
+  return 0;
+}
diff --git a/client/cmdlfhitag.h b/client/cmdlfhitag.h
new file mode 100644 (file)
index 0000000..22b6bb0
--- /dev/null
@@ -0,0 +1,21 @@
+//-----------------------------------------------------------------------------
+// Copyright (C) 2012 Roel Verdult
+//
+// 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.
+//-----------------------------------------------------------------------------
+// Low frequency Hitag support
+//-----------------------------------------------------------------------------
+
+#ifndef CMDLFHITAG_H__
+#define CMDLFHITAG_H__
+
+int CmdLFHitag(const char *Cmd);
+
+int CmdLFHitagList(const char *Cmd);
+int CmdLFHitagSnoop(const char *Cmd);
+int CmdLFHitagSim(const char *Cmd);
+int CmdLFHitagReader(const char *Cmd);
+
+#endif
index ff58e0a4b11649d1e6cbe353adc105390d775891..c26f2eb4a1af1d86ce640fc8f9f367cf2fae8bd5 100644 (file)
@@ -98,6 +98,7 @@ void UsbCommandReceived(UsbCommand *UC)
   //   printf("%s(%x) current cmd = %x\n", __FUNCTION__, c->cmd, current_command);
   /* If we recognize a response, return to avoid further processing */
   switch(UC->cmd) {
   //   printf("%s(%x) current cmd = %x\n", __FUNCTION__, c->cmd, current_command);
   /* If we recognize a response, return to avoid further processing */
   switch(UC->cmd) {
+    // First check if we are handling a debug message
     case CMD_DEBUG_PRINT_STRING: {
       char s[100];
       if(UC->arg[0] > 70 || UC->arg[0] < 0) {
     case CMD_DEBUG_PRINT_STRING: {
       char s[100];
       if(UC->arg[0] > 70 || UC->arg[0] < 0) {
@@ -107,11 +108,12 @@ void UsbCommandReceived(UsbCommand *UC)
       s[UC->arg[0]] = '\0';
       PrintAndLog("#db# %s       ", s);
       return;
       s[UC->arg[0]] = '\0';
       PrintAndLog("#db# %s       ", s);
       return;
-    }
+    } break;
 
 
-    case CMD_DEBUG_PRINT_INTEGERS:
+    case CMD_DEBUG_PRINT_INTEGERS: {
       PrintAndLog("#db# %08x, %08x, %08x       \r\n", UC->arg[0], UC->arg[1], UC->arg[2]);
       return;
       PrintAndLog("#db# %08x, %08x, %08x       \r\n", UC->arg[0], UC->arg[1], UC->arg[2]);
       return;
+    } break;
 
     case CMD_MEASURED_ANTENNA_TUNING: {
       int peakv, peakf;
 
     case CMD_MEASURED_ANTENNA_TUNING: {
       int peakv, peakf;
@@ -122,7 +124,6 @@ void UsbCommandReceived(UsbCommand *UC)
       peakf = UC->arg[2] & 0xffff;
       peakv = UC->arg[2] >> 16;
       PrintAndLog("");
       peakf = UC->arg[2] & 0xffff;
       peakv = UC->arg[2] >> 16;
       PrintAndLog("");
-      PrintAndLog("");
       PrintAndLog("# LF antenna: %5.2f V @   125.00 kHz", vLf125/1000.0);
       PrintAndLog("# LF antenna: %5.2f V @   134.00 kHz", vLf134/1000.0);
       PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1));
       PrintAndLog("# LF antenna: %5.2f V @   125.00 kHz", vLf125/1000.0);
       PrintAndLog("# LF antenna: %5.2f V @   134.00 kHz", vLf134/1000.0);
       PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1));
@@ -135,12 +136,32 @@ void UsbCommandReceived(UsbCommand *UC)
         PrintAndLog("# Your HF antenna is unusable.");
       else if (vHf<5000)
         PrintAndLog("# Your HF antenna is marginal.");
         PrintAndLog("# Your HF antenna is unusable.");
       else if (vHf<5000)
         PrintAndLog("# Your HF antenna is marginal.");
-      return;
-    }
-    default:
-      break;
+    } break;
+      
+    default: {
+      // Maybe it's a response
+      switch(current_command) {
+        case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: {
+          if (UC->cmd != CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) {
+            PrintAndLog("unrecognized command %08x\n", UC->cmd);
+            break;
+          }
+          int i;
+          for(i=0; i<48; i++) sample_buf[i] = UC->d.asBytes[i];
+          received_command = UC->cmd;
+        } break;
+
+        default: {
+        } break;
+      }
+      // Store the last received command
+      received_command = UC->cmd;
+      memcpy(&current_response, UC, sizeof(UsbCommand));
+    } break;
   }
   }
-  /* Maybe it's a response: */
+  received_command = UC->cmd;
+/*
+  // Maybe it's a response:
   switch(current_command) {
     case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
       if (UC->cmd != CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) goto unexpected_response;
   switch(current_command) {
     case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
       if (UC->cmd != CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) goto unexpected_response;
@@ -163,4 +184,5 @@ void UsbCommandReceived(UsbCommand *UC)
                memcpy(&current_response, UC, sizeof(UsbCommand));
        received_command = UC->cmd;
   }
                memcpy(&current_response, UC, sizeof(UsbCommand));
        received_command = UC->cmd;
   }
+ */
 }
 }
index 80374c600b826ef40ff5d3554efb0ef7ff7f8e4a..eeae8cc58aab6670497433538fa8a77b8c13bd1e 100644 (file)
 
 uint8_t sample_buf[SAMPLE_BUFFER_SIZE];
 
 
 uint8_t sample_buf[SAMPLE_BUFFER_SIZE];
 
-void GetFromBigBuf(uint8_t *dest, int bytes)
+void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
 {
 {
-  int n = bytes/4;
-
-  if (n % 48 != 0) {
-    PrintAndLog("bad len in GetFromBigBuf");
-    return;
-  }
-
-  for (int i = 0; i < n; i += 12) {
-    UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
-    SendCommand(&c);
-    WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
-    memcpy(dest+(i*4), sample_buf, 48);
-  }
+       start_index = ((start_index/12)*12);
+    int n = (((bytes/4)/48)*48) + start_index;
+    /*
+     if (n % 48 != 0) {
+     PrintAndLog("bad len in GetFromBigBuf");
+     return;
+     }
+     */
+    for (int i = start_index; i < n; i += 12) {
+        UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
+        SendCommand(&c);
+        WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+        memcpy(dest+(i*4), sample_buf, 48);
+    }
 }
 }
index b60ec74dd476dc4535d8e180bac0f905bf914493..e3a4cbdaad8e5622e1370742b90c5efd0a7ef958 100644 (file)
@@ -18,6 +18,6 @@
 extern uint8_t sample_buf[SAMPLE_BUFFER_SIZE];
 #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
 
 extern uint8_t sample_buf[SAMPLE_BUFFER_SIZE];
 #define arraylen(x) (sizeof(x)/sizeof((x)[0]))
 
-void GetFromBigBuf(uint8_t *dest, int bytes);
+void GetFromBigBuf(uint8_t *dest, int bytes, int start_index);
 
 #endif
 
 #endif
index c195d97421e1fc2849da9f3232bc889c839ebf01..0f577cf862e038d3cd67222c7ca7a784ebfd5acb 100644 (file)
@@ -16,8 +16,7 @@
 #include <inttypes.h>
 #include <stdio.h>
 #include "crapto1.h"
 #include <inttypes.h>
 #include <stdio.h>
 #include "crapto1.h"
-
-typedef unsigned char byte_t;
+#include "common.h"
 
 int nonce2key(uint32_t uid, uint32_t nt, uint64_t par_info, uint64_t ks_info, uint64_t * key); 
 
 
 int nonce2key(uint32_t uid, uint32_t nt, uint64_t par_info, uint64_t ks_info, uint64_t * key); 
 
Impressum, Datenschutz