]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
ADD: LF JABLOTRON functionality. with clone/sim and detection in LF SEARCH.
authoriceman1001 <iceman@iuse.se>
Fri, 29 Jul 2016 09:04:12 +0000 (11:04 +0200)
committericeman1001 <iceman@iuse.se>
Fri, 29 Jul 2016 09:04:12 +0000 (11:04 +0200)
CHG: removed no-existing crc8ja code
FIX: a check in ASKbiphaseDemod to make sure graphbuff is not empty.

12 files changed:
client/Makefile
client/cmdanalyse.c
client/cmddata.c
client/cmdlf.c
client/cmdlf.h
client/cmdlfjablotron.c [new file with mode: 0644]
client/cmdlfjablotron.h [new file with mode: 0644]
client/cmdlfnedap.c
common/crc.c
common/crc.h
common/lfdemod.c
common/lfdemod.h

index 3f1d13ed93836fc7f08fff30c65242b0f0328583..11246a1c6268a3e30cdfe7a60f53731f8fd76d00 100644 (file)
@@ -130,6 +130,7 @@ CMDSRCS =   mifarehost.c \
                        cmdlfpyramid.c \
                        cmdlfguard.c \
                        cmdlfnedap.c \
+                       cmdlfjablotron.c \
                        pm3_binlib.c \
                        scripting.c \
                        cmdscript.c \
index b5f9cb52c2735ae852d57ed7d86a5475ec5a7b51..6a8e5bc07edd916309df3132c1acf335c7382336 100644 (file)
@@ -70,7 +70,7 @@ static uint8_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
                sum += CRUMB(bytes[i], 4);
                sum += CRUMB(bytes[i], 6);
        }
-       sum ^= mask;    
+       sum &= mask;    
     return sum;
 }
 static uint8_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
@@ -82,7 +82,7 @@ static uint8_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
         sum += NIBBLE_LOW(bytes[i]);
                sum += NIBBLE_HIGH(bytes[i]);
        }
-       sum ^= mask;    
+       sum &= mask;    
     return sum;
 }
 static uint8_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
@@ -93,7 +93,7 @@ static uint8_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
     uint8_t sum = 0;
     for (uint8_t i = 0; i < len; i++)
         sum += bytes[i];
-       sum ^= mask;    
+       sum &= mask;    
     return sum;
 }
 // Ones complement
@@ -105,7 +105,7 @@ static uint8_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
     uint8_t sum = 0;
     for (uint8_t i = 0; i < len; i++)
         sum -= bytes[i];
-       sum ^= mask;    
+       sum &= mask;    
     return sum;
 }
 static uint8_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){
@@ -117,7 +117,7 @@ static uint8_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
         sum -= NIBBLE_LOW(bytes[i]);
                sum -= NIBBLE_HIGH(bytes[i]);
        }
-       sum ^= mask;    
+       sum &= mask;    
     return sum;
 }
 static uint8_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) {
@@ -155,8 +155,7 @@ int CmdAnalyseCRC(const char *Cmd) {
        }
        len >>= 1;      
 
-       PrintAndLog("\nTests with '%s' hex bytes", sprint_hex(data, len));
-       PrintAndLog("   JA: CRC8: %X  (0x6C expected)", CRC8ja(data, len) );
+       //PrintAndLog("\nTests with '%s' hex bytes", sprint_hex(data, len));
        
        PrintAndLog("\nTests of reflection. Two current methods in source code");       
        PrintAndLog("   reflect(0x3e23L,3) is %04X == 0x3e26", reflect(0x3e23L,3) );
@@ -170,7 +169,6 @@ int CmdAnalyseCRC(const char *Cmd) {
        uint8_t dataStr[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 };
        uint8_t legic8 = CRC8Legic(dataStr, sizeof(dataStr));
        
-       PrintAndLog("JA: CRC8 : %X (0x28 expected)", CRC8ja(dataStr, sizeof(dataStr)) );
        PrintAndLog("LEGIC: CRC16: %X", CRC16Legic(dataStr, sizeof(dataStr), legic8));
 
        //these below has been tested OK.
index 6570b24370d2796ef71f63ff05791adc81a8c371..18edd33e88ba8a43be3482db3b8c39ee120f0a7a 100644 (file)
@@ -527,7 +527,11 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose)
        sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr);
        
        uint8_t BitStream[MAX_DEMOD_BUF_LEN];
-       size_t size = getFromGraphBuf(BitStream);         
+       size_t size = getFromGraphBuf(BitStream);       
+       if (size == 0 ) {
+               if (g_debugMode) PrintAndLog("DEBUG: no data in graphbuf");  
+                       return 0;  
+       }
        //invert here inverts the ask raw demoded bits which has no effect on the demod, but we need the pointer
        int errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0);  
        if ( errCnt < 0 || errCnt > maxErr ) {   
index 0ab24dba5338a38a15c6ace04d77f77c52bcbf10..f48a4371024282dee28c66a334072843964abd1a 100644 (file)
@@ -637,115 +637,113 @@ int CmdLFSim(const char *Cmd)
        return 0;
 }
 
-// by marshmellow - sim ask data given clock, fcHigh, fcLow, invert 
+// by marshmellow - sim fsk data given clock, fcHigh, fcLow, invert 
 // - allow pull data from DemodBuffer
 int CmdLFfskSim(const char *Cmd)
 {
        //might be able to autodetect FCs and clock from Graphbuffer if using demod buffer
        // otherwise will need FChigh, FClow, Clock, and bitstream
-  uint8_t fcHigh=0, fcLow=0, clk=0;
-  uint8_t invert=0;
-  bool errors = FALSE;
-  char hexData[32] = {0x00}; // store entered hex data
-  uint8_t data[255] = {0x00}; 
-  int dataLen = 0;
-  uint8_t cmdp = 0;
-  while(param_getchar(Cmd, cmdp) != 0x00)
-  {
-    switch(param_getchar(Cmd, cmdp))
-    {
-    case 'h':
-      return usage_lf_simfsk();
-    case 'i':
-      invert = 1;
-      cmdp++;
-      break;
-    case 'c':
-      errors |= param_getdec(Cmd,cmdp+1,&clk);
-      cmdp+=2;
-      break;
-    case 'H':
-      errors |= param_getdec(Cmd,cmdp+1,&fcHigh);
-      cmdp+=2;
-      break;
-    case 'L':
-      errors |= param_getdec(Cmd,cmdp+1,&fcLow);
-      cmdp+=2;
-      break;
-    //case 's':
-    //  separator=1;
-    //  cmdp++;
-    //  break;
-    case 'd':
-      dataLen = param_getstr(Cmd, cmdp+1, hexData);
-      if (dataLen==0) {
-        errors=TRUE; 
-      } else {
-        dataLen = hextobinarray((char *)data, hexData);
-      }   
-      if (dataLen==0) errors=TRUE; 
-      if (errors) PrintAndLog ("Error getting hex data");
-      cmdp+=2;
-      break;
-    default:
-      PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
-      errors = TRUE;
-      break;
-    }
-    if(errors) break;
-  }
-  if(cmdp == 0 && DemodBufferLen == 0)
-  {
-    errors = TRUE;// No args
-  }
-
-  //Validations
-  if(errors)
-  {
-    return usage_lf_simfsk();
-  }
+       uint8_t fcHigh = 0, fcLow = 0, clk = 0;
+       uint8_t invert = 0;
+       bool errors = FALSE;
+       char hexData[32] = {0x00}; // store entered hex data
+       uint8_t data[255] = {0x00}; 
+       int dataLen = 0;
+       uint8_t cmdp = 0;
+       
+       while(param_getchar(Cmd, cmdp) != 0x00)
+       {
+               switch(param_getchar(Cmd, cmdp))
+               {
+                       case 'h':
+                               return usage_lf_simfsk();
+                       case 'i':
+                               invert = 1;
+                               cmdp++;
+                               break;
+                       case 'c':
+                               errors |= param_getdec(Cmd, cmdp+1, &clk);
+                               cmdp += 2;
+                               break;
+                       case 'H':
+                               errors |= param_getdec(Cmd, cmdp+1, &fcHigh);
+                               cmdp += 2;
+                               break;
+                       case 'L':
+                               errors |= param_getdec(Cmd, cmdp+1, &fcLow);
+                               cmdp += 2;
+                               break;
+                       //case 's':
+                       //  separator = 1;
+                       //  cmdp++;
+                       //  break;
+                       case 'd':
+                               dataLen = param_getstr(Cmd, cmdp+1, hexData);
+                               if (dataLen == 0)
+                                       errors = TRUE; 
+                               else
+                                       dataLen = hextobinarray((char *)data, hexData);
+                                  
+                               if (dataLen == 0) errors = TRUE; 
+                               if (errors) PrintAndLog ("Error getting hex data");
+                               cmdp+=2;
+                               break;
+                       default:
+                               PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+                               errors = TRUE;
+                               break;
+               }
+               if(errors) break;
+       }
+       
+       // No args
+       if(cmdp == 0 && DemodBufferLen == 0)
+               errors = TRUE;
 
-  if (dataLen == 0){ //using DemodBuffer 
-    if (clk==0 || fcHigh==0 || fcLow==0){ //manual settings must set them all
-      uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0);
-      if (ans==0){
-        if (!fcHigh) fcHigh=10;
-        if (!fcLow) fcLow=8;
-        if (!clk) clk=50;
-      }
-    }
-  } else {
-    setDemodBuf(data, dataLen, 0);
-  }
+       //Validations
+       if(errors) return usage_lf_simfsk();
+
+       if (dataLen == 0){ //using DemodBuffer 
+               if (clk == 0 || fcHigh == 0 || fcLow == 0){ //manual settings must set them all
+                       uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0);
+                       if (ans==0){
+                               if (!fcHigh) fcHigh = 10;
+                               if (!fcLow) fcLow = 8;
+                               if (!clk) clk = 50;
+                       }
+               }
+       } else {
+               setDemodBuf(data, dataLen, 0);
+       }
 
        //default if not found
-  if (clk == 0) clk = 50;
-  if (fcHigh == 0) fcHigh = 10;
-  if (fcLow == 0) fcLow = 8;
+       if (clk == 0) clk = 50;
+       if (fcHigh == 0) fcHigh = 10;
+       if (fcLow == 0) fcLow = 8;
 
-  uint16_t arg1, arg2;
-  arg1 = fcHigh << 8 | fcLow;
-  arg2 = invert << 8 | clk;
-  size_t size = DemodBufferLen;
-  if (size > USB_CMD_DATA_SIZE) {
-    PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
-    size = USB_CMD_DATA_SIZE;
-  } 
-  UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}};
+       uint16_t arg1, arg2;
+       arg1 = fcHigh << 8 | fcLow;
+       arg2 = invert << 8 | clk;
+       size_t size = DemodBufferLen;
+       if (size > USB_CMD_DATA_SIZE) {
+               PrintAndLog("DemodBuffer too long for current implementation - length: %d - max: %d", size, USB_CMD_DATA_SIZE);
+               size = USB_CMD_DATA_SIZE;
+       
+       UsbCommand c = {CMD_FSK_SIM_TAG, {arg1, arg2, size}};
 
-  memcpy(c.d.asBytes, DemodBuffer, size);
+       memcpy(c.d.asBytes, DemodBuffer, size);
        clearCommandBuffer();
-  SendCommand(&c);
-  return 0;
+       SendCommand(&c);
+       return 0;
 }
 
 // by marshmellow - sim ask data given clock, invert, manchester or raw, separator 
 // - allow pull data from DemodBuffer
 int CmdLFaskSim(const char *Cmd)
 {
-       //autodetect clock from Graphbuffer if using demod buffer
+       // autodetect clock from Graphbuffer if using demod buffer
        // needs clock, invert, manchester/raw as m or r, separator as s, and bitstream
-       uint8_t encoding = 1, separator = 0, clk=0, invert=0;
+       uint8_t encoding = 1, separator = 0, clk = 0, invert = 0;
        bool errors = FALSE;
        char hexData[32] = {0x00}; 
        uint8_t data[255]= {0x00}; // store entered hex data
@@ -760,35 +758,35 @@ int CmdLFaskSim(const char *Cmd)
                                cmdp++;
                                break;
                        case 'c':
-                               errors |= param_getdec(Cmd,cmdp+1,&clk);
-                               cmdp+=2;
+                               errors |= param_getdec(Cmd, cmdp+1, &clk);
+                               cmdp += 2;
                                break;
                        case 'b':
-                               encoding=2; //biphase
+                               encoding = 2; //biphase
                                cmdp++;
                                break;
                        case 'm':
-                               encoding=1;
+                               encoding = 1; //manchester
                                cmdp++;
                                break;
                        case 'r':
-                               encoding=0;
+                               encoding = 0; //raw
                                cmdp++;
                                break;
                        case 's':
-                               separator=1;
+                               separator = 1;
                                cmdp++;
                                break;
                        case 'd':
                                dataLen = param_getstr(Cmd, cmdp+1, hexData);
-                               if (dataLen==0)
+                               if (dataLen == 0)
                                        errors = TRUE; 
                                else
                                        dataLen = hextobinarray((char *)data, hexData);
                                
-                               if (dataLen==0) errors = TRUE; 
+                               if (dataLen == 0) errors = TRUE; 
                                if (errors) PrintAndLog ("Error getting hex data, datalen: %d", dataLen);
-                               cmdp+=2;
+                               cmdp += 2;
                                break;
                        default:
                                PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
@@ -797,9 +795,10 @@ int CmdLFaskSim(const char *Cmd)
                }
                if(errors) break;
        }
-  
+
+       // No args
        if(cmdp == 0 && DemodBufferLen == 0)
-               errors = TRUE;// No args
+               errors = TRUE;
 
        //Validations
        if(errors) return usage_lf_simask();
@@ -1050,75 +1049,69 @@ int CmdLFfind(const char *Cmd) {
 
        ans=CmdFSKdemodIO("");
        if (ans>0) {
-       PrintAndLog("\nValid IO Prox ID Found!");
-       return 1;
+               PrintAndLog("\nValid IO Prox ID Found!");
+               return 1;
        }
-
        ans=CmdFSKdemodPyramid("");
        if (ans>0) {
-       PrintAndLog("\nValid Pyramid ID Found!");
-       return 1;
+               PrintAndLog("\nValid Pyramid ID Found!");
+               return 1;
        }
-
        ans=CmdFSKdemodParadox("");
        if (ans>0) {
-       PrintAndLog("\nValid Paradox ID Found!");
-       return 1;
+               PrintAndLog("\nValid Paradox ID Found!");
+               return 1;
        }
-
        ans=CmdFSKdemodAWID("");
        if (ans>0) {
-       PrintAndLog("\nValid AWID ID Found!");
-       return 1;
+               PrintAndLog("\nValid AWID ID Found!");
+               return 1;
        }
-
        ans=CmdFSKdemodHID("");
        if (ans>0) {
-       PrintAndLog("\nValid HID Prox ID Found!");
-       return 1;
+               PrintAndLog("\nValid HID Prox ID Found!");
+               return 1;
        }
-
        ans=CmdAskEM410xDemod("");
        if (ans>0) {
-       PrintAndLog("\nValid EM410x ID Found!");
-       return 1;
+               PrintAndLog("\nValid EM410x ID Found!");
+               return 1;
        }
-
        ans=CmdG_Prox_II_Demod("");
        if (ans>0) {
-       PrintAndLog("\nValid Guardall G-Prox II ID Found!");
-       return 1;
+               PrintAndLog("\nValid Guardall G-Prox II ID Found!");
+               return 1;
        }
-
        ans=CmdFDXBdemodBI("");
        if (ans>0) {
                PrintAndLog("\nValid FDX-B ID Found!");
                return 1;
        }
-
        ans=EM4x50Read("", false);
        if (ans>0) {
                PrintAndLog("\nValid EM4x50 ID Found!");
                return 1;
        }       
-
        ans=CmdVikingDemod("");
        if (ans>0) {
                PrintAndLog("\nValid Viking ID Found!");
                return 1;
        }       
-
        ans=CmdIndalaDecode("");
        if (ans>0) {
                PrintAndLog("\nValid Indala ID Found!");
                return 1;
        }
-
        ans=CmdPSKNexWatch("");
        if (ans>0) {
                PrintAndLog("\nValid NexWatch ID Found!");
                return 1;
        }
+       ans=CmdJablotronDemod("");
+       if (ans>0) {
+               PrintAndLog("\nValid Jablotron ID Found!");
+               return 1;
+       }
        ans=CmdLFNedapDemod("");
        if (ans>0) {
                PrintAndLog("\nValid NEDAP ID Found!");
@@ -1197,6 +1190,7 @@ static command_t CommandTable[] =
        {"hid",         CmdLFHID,           1, "{ HID RFIDs... }"},
        {"hitag",       CmdLFHitag,         1, "{ HITAG RFIDs... }"},
        {"io",                  CmdLFIO,                        1, "{ IOPROX RFIDs... }"},
+       {"jablotron",   CmdLFJablotron,         1, "{ JABLOTRON RFIDs... }"},
        {"nedap",               CmdLFNedap,                     1, "{ NEDAP RFIDs... }"},
        {"pcf7931",     CmdLFPCF7931,       1, "{ PCF7931 RFIDs... }"},
        {"presco",      CmdLFPresco,        1, "{ Presco RFIDs... }"},
index d04f96793a9c4485173b73efa5b44163f5162108..9b9c495f992ef0b979128be0c6340ff645d6d4b6 100644 (file)
 #include "proxmark3.h"
 #include "lfdemod.h"
                        
-#include "util.h"        // for parsing cli command utils
-#include "ui.h"          // for show graph controls
-#include "graph.h"       // for graph data
-#include "cmdparser.h"   // for getting cli commands included in cmdmain.h
-#include "cmdmain.h"     // for sending cmds to device
-#include "data.h"        // for GetFromBigBuf
-#include "cmddata.h"     // for `lf search`
-#include "cmdlfawid.h"   // for awid menu
-#include "cmdlfem4x.h"   // for em4x menu
-#include "cmdlfhid.h"    // for hid menu
-#include "cmdlfhitag.h"  // for hitag menu
-#include "cmdlfio.h"     // for ioprox menu
-#include "cmdlft55xx.h"  // for t55xx menu
-#include "cmdlfti.h"     // for ti menu
-#include "cmdlfpresco.h" // for presco menu
-#include "cmdlfpcf7931.h"// for pcf7931 menu
-#include "cmdlfpyramid.h"// for pyramid menu
-#include "cmdlfviking.h" // for viking menu
-#include "cmdlfguard.h"  // for GuardAll menu
-#include "cmdlfnedap.h"  // for NEDAP menu
+#include "util.h"                      // for parsing cli command utils
+#include "ui.h"                                // for show graph controls
+#include "graph.h"                     // for graph data
+#include "cmdparser.h"         // for getting cli commands included in cmdmain.h
+#include "cmdmain.h"           // for sending cmds to device
+#include "data.h"                      // for GetFromBigBuf
+#include "cmddata.h"           // for `lf search`
+#include "cmdlfawid.h"         // for awid menu
+#include "cmdlfem4x.h"         // for em4x menu
+#include "cmdlfhid.h"          // for hid menu
+#include "cmdlfhitag.h"                // for hitag menu
+#include "cmdlfio.h"           // for ioprox menu
+#include "cmdlft55xx.h"                // for t55xx menu
+#include "cmdlfti.h"           // for ti menu
+#include "cmdlfpresco.h"       // for presco menu
+#include "cmdlfpcf7931.h"      // for pcf7931 menu
+#include "cmdlfpyramid.h"      // for pyramid menu
+#include "cmdlfviking.h"       // for viking menu
+#include "cmdlfguard.h"                // for GuardAll menu
+#include "cmdlfnedap.h"                // for NEDAP menu
+#include "cmdlfjablotron.h"    // for JABLOTRON menu
 
 int CmdLF(const char *Cmd);
 
diff --git a/client/cmdlfjablotron.c b/client/cmdlfjablotron.c
new file mode 100644 (file)
index 0000000..a97bb77
--- /dev/null
@@ -0,0 +1,206 @@
+//-----------------------------------------------------------------------------
+//
+// 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 Presco tag commands
+//-----------------------------------------------------------------------------
+#include "cmdlfjablotron.h"
+
+static int CmdHelp(const char *Cmd);
+
+int usage_lf_jablotron_clone(void){
+       PrintAndLog("clone a Jablotron tag to a T55x7 tag.");
+       PrintAndLog("Usage: lf jablotron clone d <Card-ID> <Q5>");
+       PrintAndLog("Options :");
+       PrintAndLog("  d <Card-ID>   : jablotron card ID");
+       PrintAndLog("  <Q5>          : specify write to Q5 (t5555 instead of t55x7)");
+       PrintAndLog("");
+       PrintAndLog("Sample  : lf jablotron clone d 123456789");
+       return 0;
+}
+
+int usage_lf_jablotron_sim(void) {
+       PrintAndLog("Enables simulation of jablotron card with specified card number.");
+       PrintAndLog("Simulation runs until the button is pressed or another USB command is issued.");
+       PrintAndLog("Per jablotron format, the card number is 9 digit number and can contain *# chars. Larger values are truncated.");
+       PrintAndLog("");
+       PrintAndLog("Usage:  lf jablotron sim d <Card-ID> or H <hex-ID>");
+       PrintAndLog("Options :");
+       PrintAndLog("  d <Card-ID>   : jablotron card number");
+//     PrintAndLog("  H <hex-ID>    : 8 digit hex card number");
+       PrintAndLog("");
+       PrintAndLog("Sample  : lf jablotron sim d 123456789");
+       return 0;
+}
+
+int getJablotronBits(uint64_t fullcode, uint8_t *bits) {       
+       //preamp
+       num_to_bytebits(0xFFFF, 16, bits);
+
+       //fullcode
+       num_to_bytebits(fullcode, 40, bits+16);
+
+       //chksum byte
+       uint8_t crc = 0;
+       for (int i=16; i < 56; i += 8) {
+               crc += bytebits_to_byte(bits+i,8);
+       }
+       crc ^= 0x3A;
+       num_to_bytebits(crc, 8, bits+56);
+               
+       return 1;
+}
+
+//see ASKDemod for what args are accepted
+int CmdJablotronDemod(const char *Cmd) {
+
+       //Differential Biphase / di-phase (inverted biphase)
+       //get binary from ask wave
+       if (!ASKbiphaseDemod("0 64 1 0", FALSE)) {
+               if (g_debugMode) PrintAndLog("Error Jablotron: ASKbiphaseDemod failed");
+               return 0;
+       }
+       size_t size = DemodBufferLen;
+       int ans = JablotronDemod(DemodBuffer, &size);
+       if (ans < 0){
+               if (g_debugMode){
+                       // if (ans == -5)
+                               // PrintAndLog("DEBUG: Error - not enough samples");
+                       // else if (ans == -1)
+                               // PrintAndLog("DEBUG: Error - only noise found");
+                       // else if (ans == -2)
+                               // PrintAndLog("DEBUG: Error - problem during ASK/Biphase demod");
+                       if (ans == -3)
+                               PrintAndLog("DEBUG: Error - Size not correct: %d", size);
+                       else if (ans == -4)
+                               PrintAndLog("DEBUG: Error - Jablotron preamble not found");
+                       else
+                               PrintAndLog("DEBUG: Error - ans: %d", ans);
+               }
+               return 0;
+       }
+       //got a good demod
+       uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans, 32);
+       uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32);
+       uint64_t cardid = (raw1 & 0x0000FFFF);
+       cardid <<= 32;
+       cardid |= (raw2 >> 8);
+       
+       PrintAndLog("Jablotron Tag Found: Card ID %12X", cardid);
+       PrintAndLog("Raw: %08X%08X", raw1 ,raw2);
+
+       setDemodBuf(DemodBuffer+ans, 64, 0);
+       
+       //PrintAndLog("1410-%u-%u-%08X-%02X", fullcode);        
+       return 1;
+}
+
+int CmdJablotronRead(const char *Cmd) {
+       // read lf silently
+       CmdLFRead("s");
+       // get samples silently
+       getSamples("30000",false);
+       // demod and output Presco ID   
+       return CmdJablotronDemod(Cmd);
+}
+
+int CmdJablotronClone(const char *Cmd) {
+
+       uint64_t fullcode = 0;
+       uint32_t blocks[3] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_64 | 2<<T55x7_MAXBLOCK_SHIFT, 0, 0};
+
+       uint8_t bits[64];
+       uint8_t *bs = bits;
+       memset(bs, 0, sizeof(bits));
+       
+       char cmdp = param_getchar(Cmd, 0);
+       if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_jablotron_clone();
+
+       fullcode = param_get64ex(Cmd, 1, 0, 16);
+       
+       //Q5
+       if (param_getchar(Cmd, 2) == 'Q' || param_getchar(Cmd, 2) == 'q') {
+               //t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
+               blocks[0] = T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | 64<<T5555_BITRATE_SHIFT | 2<<T5555_MAXBLOCK_SHIFT;
+       }
+       
+       if ((fullcode & 0xFFFFFFFFFFFF) != fullcode) {
+               fullcode &= 0xFFFFFFFFFFFF;
+               PrintAndLog("Card Number Truncated to 40-bits: %u", fullcode);
+       }
+
+       if ( !getJablotronBits(fullcode, bs)) {
+               PrintAndLog("Error with tag bitstream generation.");
+               return 1;
+       }       
+       
+       // 
+       blocks[1] = bytebits_to_byte(bs,32);
+       blocks[2] = bytebits_to_byte(bs+32,32);
+
+       PrintAndLog("Preparing to clone Jablotron to T55x7 with FullCode: %12X", fullcode);
+       PrintAndLog("Blk | Data ");
+       PrintAndLog("----+------------");
+       PrintAndLog(" 00 | 0x%08x", blocks[0]);
+       PrintAndLog(" 01 | 0x%08x", blocks[1]);
+       PrintAndLog(" 02 | 0x%08x", blocks[2]);
+       
+       UsbCommand resp;
+       UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}};
+
+       for (int i=4; i>=0; i--) {
+               c.arg[0] = blocks[i];
+               c.arg[1] = i;
+               clearCommandBuffer();
+               SendCommand(&c);
+               if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
+                       PrintAndLog("Error occurred, device did not respond during write operation.");
+                       return -1;
+               }
+       }
+    return 0;
+}
+
+int CmdJablotronSim(const char *Cmd) {
+       uint64_t fullcode = 0;
+
+       char cmdp = param_getchar(Cmd, 0);
+       if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_jablotron_sim();
+
+       fullcode = param_get64ex(Cmd, 1, 0, 16);
+       
+       uint8_t clk = 64, encoding = 2, separator = 0, invert = 1;
+       uint16_t arg1, arg2;
+       size_t size = 64;
+       arg1 = clk << 8 | encoding;
+       arg2 = invert << 8 | separator;
+
+       PrintAndLog("Simulating Jablotron - FullCode: %12X", fullcode);
+
+       UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}};
+       getJablotronBits(fullcode, c.d.asBytes);
+       clearCommandBuffer();
+       SendCommand(&c);
+       return 0;
+}
+
+static command_t CommandTable[] = {
+    {"help",   CmdHelp,                        1, "This help"},
+       {"read",        CmdJablotronRead,       0, "Attempt to read and Extract tag data"},
+       {"clone",       CmdJablotronClone,      0, "h <hex> [Q5] clone jablotron tag"},
+       {"sim",         CmdJablotronSim,        0, "h <hex> simulate jablotron tag"},
+    {NULL, NULL, 0, NULL}
+};
+
+int CmdLFJablotron(const char *Cmd) {
+       clearCommandBuffer();
+    CmdsParse(CommandTable, Cmd);
+    return 0;
+}
+
+int CmdHelp(const char *Cmd) {
+    CmdsHelp(CommandTable);
+    return 0;
+}
diff --git a/client/cmdlfjablotron.h b/client/cmdlfjablotron.h
new file mode 100644 (file)
index 0000000..5e76df1
--- /dev/null
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------------
+//
+// 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 T55xx commands
+//-----------------------------------------------------------------------------
+#ifndef CMDLFJABLOTRON_H__
+#define CMDLFJABLOTRON_H__
+#include <string.h>
+#include <inttypes.h>
+#include "proxmark3.h"
+#include "ui.h"
+#include "util.h"
+#include "graph.h"
+#include "cmdparser.h"
+#include "cmddata.h"
+#include "cmdmain.h"
+#include "cmdlf.h"
+#include "protocols.h"  // for T55xx config register definitions
+#include "lfdemod.h"    // parityTest
+int CmdLFJablotron(const char *Cmd);
+int CmdJablotronClone(const char *Cmd);
+int CmdJablotronSim(const char *Cmd);
+int CmdJablotronRead(const char *Cmd);
+int CmdJablotronDemod(const char *Cmd);
+
+int getJablotronBits(uint64_t fullcode, uint8_t *bits);
+
+int usage_lf_jablotron_clone(void);
+int usage_lf_jablotron_sim(void);
+int usage_lf_jablotron_read(void);
+int usage_lf_jablotron_demod(void);
+#endif
+
index 2aaae5dbb2115fbfea7f0eb50c8bcbe61c18896b..9e6a624bf07e7da3fc80ec15dd446a756f6c0c9e 100644 (file)
@@ -82,16 +82,11 @@ int GetNedapBits(uint32_t cn, uint8_t *nedapBits) {
 
 int CmdLFNedapDemod(const char *Cmd) {
        //raw ask demod no start bit finding just get binary from wave
-       uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
-       size_t size = getFromGraphBuf(BitStream);
-       if (size==0) return 0;
-
-       //get binary from ask wave
        if (!ASKbiphaseDemod("0 64 0 0", FALSE)) {
                if (g_debugMode) PrintAndLog("Error NEDAP: ASKbiphaseDemod failed");
                return 0;
        }
-       size = DemodBufferLen;
+       size_t size = DemodBufferLen;
        int idx = NedapDemod(DemodBuffer, &size);
        if (idx < 0){
                if (g_debugMode){
@@ -143,13 +138,13 @@ int CmdLFNedapDemod(const char *Cmd) {
        uint8_t firstParity = GetParity( DemodBuffer, EVEN, 63);
        if ( firstParity != DemodBuffer[63]  ) {
                PrintAndLog("1st 64bit parity check failed:  %d|%d ", DemodBuffer[63], firstParity);
-               //return 0;
+               return 0;
        }
 
        uint8_t secondParity = GetParity( DemodBuffer+64, EVEN, 63);
        if ( secondParity != DemodBuffer[127]  ) {
                PrintAndLog("2st 64bit parity check failed:  %d|%d ", DemodBuffer[127], secondParity);
-               //return 0;
+               return 0;
        }
 
        // ok valid card found!
index 451282bf5d7196fd8b01f612c03b3612235edfc3..311a676c47eb617dde16cda2767795ec398d3b9d 100644 (file)
@@ -94,17 +94,6 @@ uint32_t CRC8Legic(uint8_t *buff, size_t size) {
        return reflect(crc_finish(&crc), 8);
 }
 
-// credits to marshmellow
-// width=8  poly=0xA3, reversed poly=0x8B,  init=0xB0  refin=true  refout=true  xorout=0x00  check=0x28  name="CRC-8/JA"
-uint32_t CRC8ja(uint8_t *buff, size_t size) {
-       crc_t crc;
-       crc_init_ref(&crc, 8, 0xA3, 0x42, 0x00, TRUE, TRUE);
-       for ( int i=0; i < size; ++i)
-               crc_update(&crc, buff[i], 8);
-       return crc_finish(&crc);
-       //return reflect(crc_finish(&crc), 8);
-}
-
 // This CRC-16 is used in Legic Advant systems. 
 // width=8  poly=0xB400, reversed poly=0x  init=depends  refin=true  refout=true  xorout=0x0000  check=  name="CRC-16/LEGIC"
 uint32_t CRC16Legic(uint8_t *buff, size_t size, uint8_t uidcrc) {
index 957226a4e2f3d8ba68d90dea5d88f963b65cda9d..5a9bcfa725199598585bd1f7354bcdf025c911d4 100644 (file)
@@ -65,9 +65,6 @@ uint32_t CRC8Legic(uint8_t *buff, size_t size);
 // ie:  uidcrc = 0x78  then initial_value == 0x7878
 uint32_t CRC16Legic(uint8_t *buff, size_t size, uint8_t uidcrc);
 
-// Calculate CRC-8/ja checksum
-uint32_t CRC8ja(uint8_t *buff, size_t size);
-
 // test crc 16.
 uint32_t CRC16_DNP(uint8_t *buff, size_t size);
 uint32_t CRC16_CCITT(uint8_t *buff, size_t size);
index 8b31f1a4c10a751cd447d2667aa89f7a57a7e22e..2f376e5f2f02438c8f4f55a3b2fdff1e11febcf6 100644 (file)
@@ -723,6 +723,33 @@ int FDXBdemodBI(uint8_t *dest, size_t *size)
        return (int)startIdx;
 }
 
+// ASK/Diphase fc/64 (inverted Biphase)
+// Note: this i s not a demod, this is only a detection
+// the parameter *dest needs to be demoded before call
+int JablotronDemod(uint8_t *dest, size_t *size){
+       //make sure buffer has enough data
+       if (*size < 64) return -1;
+
+       size_t startIdx = 0;
+       // 0xFFFF preamble, 64bits
+       uint8_t preamble[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
+
+       uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx);
+       if (errChk == 0) return -4; //preamble not found
+       
+       uint8_t checkCalc = 0;
+       for (int i=16; i < 56; i += 8) {
+               checkCalc += bytebits_to_byte(dest+startIdx+i,8);
+       }
+       checkCalc ^= 0x3A;
+
+       uint8_t crc = bytebits_to_byte(dest+startIdx+56,8);
+       
+       if ( checkCalc != crc ) return -5;      
+       if (*size != 64) return -6;
+       return (int)startIdx;
+}
+
 // by marshmellow
 // FSK Demod then try to locate an AWID ID
 int AWIDdemodFSK(uint8_t *dest, size_t *size)
index 9895434c98167755c0d03925399b7cce1a44f8d7..aefdadb8707ca055e918e4b3364108519b19370a 100644 (file)
@@ -56,4 +56,5 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size);
 int VikingDemod_AM(uint8_t *dest, size_t *size);
 int PrescoDemod(uint8_t *dest, size_t *size);
 int NedapDemod(uint8_t *dest, size_t *size);
+int JablotronDemod(uint8_t *dest, size_t *size);
 #endif
Impressum, Datenschutz