]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlfjablotron.c
9c69099edbdfb651a6aed4a5db90303502032f17
   1 //----------------------------------------------------------------------------- 
   3 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   4 // at your option, any later version. See the LICENSE.txt file for the text of 
   6 //----------------------------------------------------------------------------- 
   7 // Low frequency jablotron tag commands 
   8 // Differential Biphase, RF/64, 64 bits long (complete) 
   9 //----------------------------------------------------------------------------- 
  11 #include "cmdlfjablotron.h" 
  15 #include "proxmark3.h" 
  19 #include "cmdparser.h" 
  23 #include "protocols.h"  // for T55xx config register definitions 
  24 #include "lfdemod.h"    // parityTest 
  26 static int CmdHelp(const char *Cmd
); 
  28 int usage_lf_jablotron_clone(void) { 
  29         PrintAndLog("clone a Jablotron tag to a T55x7 tag."); 
  30         PrintAndLog("Usage: lf jablotron clone [h] <card ID> <Q5>"); 
  31         PrintAndLog("Options:"); 
  32         PrintAndLog("      h          : This help"); 
  33         PrintAndLog("      <card ID>  : jablotron card ID"); 
  34         PrintAndLog("      <Q5>       : specify write to Q5 (t5555 instead of t55x7)"); 
  36         PrintAndLog("Sample: lf jablotron clone 112233"); 
  40 int usage_lf_jablotron_sim(void) { 
  41         PrintAndLog("Enables simulation of jablotron card with specified card number."); 
  42         PrintAndLog("Simulation runs until the button is pressed or another USB command is issued."); 
  44         PrintAndLog("Usage:  lf jablotron sim [h] <card ID>"); 
  45         PrintAndLog("Options:"); 
  46         PrintAndLog("      h          : This help"); 
  47         PrintAndLog("      <card ID>  : jablotron card ID"); 
  49         PrintAndLog("Sample: lf jablotron sim 112233"); 
  53 static uint8_t jablontron_chksum(uint8_t *bits
) { 
  55         for (int i
=16; i 
< 56; i 
+= 8) { 
  56                 chksum 
+= bytebits_to_byte(bits
+i
,8); 
  62 int getJablotronBits(uint64_t fullcode
, uint8_t *bits
) {         
  64         num_to_bytebits(0xFFFF, 16, bits
); 
  67         num_to_bytebits(fullcode
, 40, bits
+16); 
  70         uint8_t chksum 
= jablontron_chksum(bits
); 
  71         num_to_bytebits(chksum
, 8, bits
+56); 
  75 // ASK/Diphase fc/64 (inverted Biphase) 
  76 // Note: this is not a demod, this is only a detection 
  77 // the parameter *bits needs to be demoded before call 
  78 // 0xFFFF preamble, 64bits 
  79 int JablotronDetect(uint8_t *bits
, size_t *size
) { 
  80         if (*size 
< 64*2) return -1; //make sure buffer has enough data 
  82         uint8_t preamble
[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0}; 
  83         if (preambleSearch(bits
, preamble
, sizeof(preamble
), size
, &startIdx
) == 0) 
  84                 return -2; //preamble not found 
  85         if (*size 
!= 64) return -3; // wrong demoded size 
  87         uint8_t checkchksum 
= jablontron_chksum(bits
+startIdx
); 
  88         uint8_t crc 
= bytebits_to_byte(bits
+startIdx
+56, 8); 
  89         if ( checkchksum 
!= crc 
) return -5; 
  93 //see ASKDemod for what args are accepted 
  94 int CmdJablotronDemod(const char *Cmd
) { 
  96         //Differential Biphase / di-phase (inverted biphase) 
  97         //get binary from ask wave 
  98         if (!ASKbiphaseDemod("0 64 1 0", false)) { 
  99                 if (g_debugMode
) PrintAndLog("DEBUG: Error - Jablotron ASKbiphaseDemod failed"); 
 102         size_t size 
= DemodBufferLen
; 
 103         int ans 
= JablotronDetect(DemodBuffer
, &size
); 
 107                                 PrintAndLog("DEBUG: Error - Jablotron too few bits found"); 
 109                                 PrintAndLog("DEBUG: Error - Jablotron preamble not found"); 
 111                                 PrintAndLog("DEBUG: Error - Jablotron size not correct: %d", size
); 
 113                                 PrintAndLog("DEBUG: Error - Jablotron checksum failed"); 
 115                                 PrintAndLog("DEBUG: Error - Jablotron ans: %d", ans
); 
 120         setDemodBuf(DemodBuffer
, 64, ans
); 
 121         setClockGrid(g_DemodClock
, g_DemodStartIdx 
+ (ans
*g_DemodClock
)); 
 124         uint32_t raw1 
= bytebits_to_byte(DemodBuffer
, 32); 
 125         uint32_t raw2 
= bytebits_to_byte(DemodBuffer
+32, 32); 
 127         uint64_t id 
= (( (uint64_t)bytebits_to_byte(DemodBuffer
+16, 8) )<< 32) | bytebits_to_byte(DemodBuffer
+24,32); 
 129         PrintAndLog("Jablotron Tag Found: Card ID: %"PRIx64
" :: Raw: %08X%08X", id
, raw1
, raw2
); 
 131         uint8_t chksum 
= raw2 
& 0xFF; 
 132         PrintAndLog("Checksum: %02X [OK]", chksum
); 
 134         // Printed format: 1410-nn-nnnn-nnnn     
 135         PrintAndLog("Printed: 1410-%02X-%04X-%04X", 
 136                 (uint8_t)(id 
>> 32) & 0xFF, 
 137                 (uint16_t)(id 
>> 16) & 0xFFFF, 
 138                 (uint16_t)id 
& 0xFFFF 
 143 int CmdJablotronRead(const char *Cmd
) { 
 144         lf_read(true, 10000); 
 145         return CmdJablotronDemod(Cmd
); 
 148 int CmdJablotronClone(const char *Cmd
) { 
 150         uint64_t fullcode 
= 0; 
 151         uint32_t blocks
[3] = {T55x7_MODULATION_DIPHASE 
| T55x7_BITRATE_RF_64 
| 2 << T55x7_MAXBLOCK_SHIFT
, 0, 0}; 
 155         memset(bs
, 0, sizeof(bits
)); 
 157         char cmdp 
= param_getchar(Cmd
, 0); 
 158         if (strlen(Cmd
) == 0 || cmdp 
== 'h' || cmdp 
== 'H') return usage_lf_jablotron_clone(); 
 160         fullcode 
= param_get64ex(Cmd
, 0, 0, 16); 
 163         if (param_getchar(Cmd
, 1) == 'Q' || param_getchar(Cmd
, 1) == 'q') { 
 164                 //t5555 (Q5) BITRATE = (RF-2)/2 (iceman) 
 165                 blocks
[0] = T5555_MODULATION_BIPHASE 
| T5555_INVERT_OUTPUT 
| ((64-2)>>1) << T5555_BITRATE_SHIFT 
| 2 << T5555_MAXBLOCK_SHIFT
; 
 168         // clearing the topbit needed for the preambl detection.  
 169         if ((fullcode 
& 0x7FFFFFFFFF) != fullcode
) { 
 170                 fullcode 
&= 0x7FFFFFFFFF; 
 171                 PrintAndLog("Card Number Truncated to 39bits: %"PRIx64
, fullcode
); 
 174         if ( !getJablotronBits(fullcode
, bs
)) { 
 175                 PrintAndLog("Error with tag bitstream generation."); 
 179         blocks
[1] = bytebits_to_byte(bs
,32); 
 180         blocks
[2] = bytebits_to_byte(bs
+32,32); 
 182         PrintAndLog("Preparing to clone Jablotron to T55x7 with FullCode: %"PRIx64
, fullcode
); 
 183         PrintAndLog("Blk | Data "); 
 184         PrintAndLog("----+------------"); 
 185         PrintAndLog(" 00 | 0x%08x", blocks
[0]); 
 186         PrintAndLog(" 01 | 0x%08x", blocks
[1]); 
 187         PrintAndLog(" 02 | 0x%08x", blocks
[2]); 
 190         UsbCommand c 
= {CMD_T55XX_WRITE_BLOCK
, {0,0,0}}; 
 192         for (int i 
= 2; i 
>= 0; --i
) { 
 193                 c
.arg
[0] = blocks
[i
]; 
 195                 clearCommandBuffer(); 
 197                 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, T55XX_WRITE_TIMEOUT
)) { 
 198                         PrintAndLog("Error occurred, device did not respond during write operation."); 
 205 int CmdJablotronSim(const char *Cmd
) { 
 206         uint64_t fullcode 
= 0; 
 208         char cmdp 
= param_getchar(Cmd
, 0); 
 209         if (strlen(Cmd
) == 0 || cmdp 
== 'h' || cmdp 
== 'H') return usage_lf_jablotron_sim(); 
 211         fullcode 
= param_get64ex(Cmd
, 0, 0, 16); 
 213         // clearing the topbit needed for the preambl detection.  
 214         if ((fullcode 
& 0x7FFFFFFFFF) != fullcode
) { 
 215                 fullcode 
&= 0x7FFFFFFFFF; 
 216                 PrintAndLog("Card Number Truncated to 39bits: %"PRIx64
, fullcode
); 
 219         uint8_t clk 
= 64, encoding 
= 2, separator 
= 0, invert 
= 1; 
 222         arg1 
= clk 
<< 8 | encoding
; 
 223         arg2 
= invert 
<< 8 | separator
; 
 225         PrintAndLog("Simulating Jablotron - FullCode: %"PRIx64
, fullcode
); 
 227         UsbCommand c 
= {CMD_ASK_SIM_TAG
, {arg1
, arg2
, size
}}; 
 228         getJablotronBits(fullcode
, c
.d
.asBytes
); 
 229         clearCommandBuffer(); 
 234 static command_t CommandTable
[] = { 
 235         {"help",  CmdHelp
,           1, "This help"}, 
 236         {"demod", CmdJablotronDemod
, 1, "Attempt to read and extract tag data from the GraphBuffer"}, 
 237         {"read",  CmdJablotronRead
,  0, "Attempt to read and extract tag data from the antenna"}, 
 238         {"clone", CmdJablotronClone
, 0, "clone jablotron tag"}, 
 239         {"sim",   CmdJablotronSim
,   0, "simulate jablotron tag"}, 
 240         {NULL
, NULL
, 0, NULL
} 
 243 int CmdLFJablotron(const char *Cmd
) { 
 244         clearCommandBuffer(); 
 245         CmdsParse(CommandTable
, Cmd
); 
 249 int CmdHelp(const char *Cmd
) { 
 250         CmdsHelp(CommandTable
);