]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdlfpyramid.c
366889f3f9ea2a68a0256ca95437f807b1b806ca
   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 Farpoint / Pyramid tag commands 
   8 // FSK2a, rf/50, 128 bits (complete) 
   9 //----------------------------------------------------------------------------- 
  13 #include "cmdlfpyramid.h" 
  14 #include "proxmark3.h" 
  18 #include "cmdparser.h" 
  19 #include "cmddata.h"    // setDemodBuf + 
  22 #include "protocols.h"  // for T55xx config register definitions 
  23 #include "lfdemod.h"    // parityTest 
  26 static int CmdHelp(const char *Cmd
); 
  28 int usage_lf_pyramid_clone(void){ 
  29         PrintAndLog("clone a Farpointe/Pyramid tag to a T55x7 tag."); 
  30         PrintAndLog("The facility-code is 8-bit and the card number is 16-bit.  Larger values are truncated. "); 
  31         PrintAndLog("Currently only works on 26bit"); 
  33         PrintAndLog("Usage: lf pyramid clone <Facility-Code> <Card-Number>"); 
  34         PrintAndLog("Options :"); 
  35         PrintAndLog("  <Facility-Code> :  8-bit value facility code"); 
  36         PrintAndLog("  <Card Number>   : 16-bit value card number"); 
  37         PrintAndLog("  Q5              : optional - clone to Q5 (T5555) instead of T55x7 chip"); 
  39         PrintAndLog("Sample  : lf pyramid clone 123 11223"); 
  43 int usage_lf_pyramid_sim(void) { 
  44         PrintAndLog("Enables simulation of Farpointe/Pyramid card with specified card number."); 
  45         PrintAndLog("Simulation runs until the button is pressed or another USB command is issued."); 
  46         PrintAndLog("The facility-code is 8-bit and the card number is 16-bit.  Larger values are truncated."); 
  47         PrintAndLog("Currently work only on 26bit"); 
  49         PrintAndLog("Usage:  lf pyramid sim <Card-Number>"); 
  50         PrintAndLog("Options :"); 
  51         PrintAndLog("  <Facility-Code> :  8-bit value facility code"); 
  52         PrintAndLog("  <Card Number>   : 16-bit value card number"); 
  54         PrintAndLog("Sample  : lf pyramid sim 123 11223"); 
  59 int GetPyramidBits(uint32_t fc
, uint32_t cn
, uint8_t *pyramidBits
) { 
  62         memset(pre
, 0x00, sizeof(pre
)); 
  67         // Get 26 wiegand from FacilityCode, CardNumber  
  69         memset(wiegand
, 0x00, sizeof(wiegand
)); 
  70         num_to_bytebits(fc
, 8, wiegand
); 
  71         num_to_bytebits(cn
, 16, wiegand
+8); 
  73         // add wiegand parity bits (dest, source, len) 
  74         wiegand_add_parity(pre
+80, wiegand
, 24); 
  76         // add paritybits       (bitsource, dest, sourcelen, paritylen, parityType (odd, even,) 
  77         addParity(pre
+8, pyramidBits
+8, 102, 8, 1); 
  81         for (uint8_t i 
= 0; i 
< 13; i
++) 
  82                 csBuff
[i
] = bytebits_to_byte(pyramidBits 
+ 16 + (i
*8), 8); 
  84         uint32_t crc 
= CRC8Maxim(csBuff
, 13); 
  85         num_to_bytebits(crc
, 8, pyramidBits
+120); 
  90 //Pyramid Prox demod - FSK RF/50 with preamble of 0000000000000001  (always a 128 bit data stream) 
  91 //print full Farpointe Data/Pyramid Prox ID and some bit format details if found 
  92 int CmdFSKdemodPyramid(const char *Cmd
) 
  94         //raw fsk demod no manchester decoding no start bit finding just get binary from wave 
  95         uint8_t BitStream
[MAX_GRAPH_TRACE_LEN
]={0}; 
  96         size_t size 
= getFromGraphBuf(BitStream
); 
  97         if (size
==0) return 0; 
 100         //get binary from fsk wave 
 101         int idx 
= PyramiddemodFSK(BitStream
, &size
, &waveIdx
); 
 105                                 PrintAndLog("DEBUG: Error - not enough samples"); 
 107                                 PrintAndLog("DEBUG: Error - only noise found"); 
 109                                 PrintAndLog("DEBUG: Error - problem during FSK demod"); 
 111                                 PrintAndLog("DEBUG: Error - Size not correct: %d", size
); 
 113                                 PrintAndLog("DEBUG: Error - Pyramid preamble not found"); 
 115                                 PrintAndLog("DEBUG: Error - idx: %d",idx
); 
 120         // 0           10          20          30            40          50          60 
 122         // 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 
 123         // ----------------------------------------------------------------------------- 
 124         // 0000000 0 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 
 125         // premable  xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o 
 127         // 64    70            80          90          100         110           120 
 129         // 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 
 130         // ----------------------------------------------------------------------------- 
 131         // 0000000 1 0000000 1 0000000 1 0110111 0 0011000 1 0000001 0 0001100 1 1001010 0 
 132         // xxxxxxx o xxxxxxx o xxxxxxx o xswffff o ffffccc o ccccccc o ccccccw o ppppppp o 
 133         //                                  |---115---||---------71---------| 
 134         // s = format start bit, o = odd parity of last 7 bits 
 135         // f = facility code, c = card number 
 136         // w = wiegand parity, x = extra space for other formats 
 137         // p = unknown checksum 
 138         // (26 bit format shown) 
 140         //get bytes for checksum calc 
 141         uint8_t checksum 
= bytebits_to_byte(BitStream 
+ idx 
+ 120, 8); 
 142         uint8_t csBuff
[14] = {0x00}; 
 143         for (uint8_t i 
= 0; i 
< 13; i
++){ 
 144                 csBuff
[i
] = bytebits_to_byte(BitStream 
+ idx 
+ 16 + (i
*8), 8); 
 146         //check checksum calc 
 147         //checksum calc thanks to ICEMAN!! 
 148         uint32_t checkCS 
=  CRC8Maxim(csBuff
,13); 
 150         //get raw ID before removing parities 
 151         uint32_t rawLo 
= bytebits_to_byte(BitStream
+idx
+96,32); 
 152         uint32_t rawHi 
= bytebits_to_byte(BitStream
+idx
+64,32); 
 153         uint32_t rawHi2 
= bytebits_to_byte(BitStream
+idx
+32,32); 
 154         uint32_t rawHi3 
= bytebits_to_byte(BitStream
+idx
,32); 
 155         setDemodBuf(BitStream
,128,idx
); 
 156         setClockGrid(50, waveIdx 
+ (idx
*50)); 
 158         size 
= removeParity(BitStream
, idx
+8, 8, 1, 120); 
 161                         PrintAndLog("DEBUG: Error at parity check - tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size
, idx
, rawHi3
); 
 165         // ok valid card found! 
 168         // 0         10        20        30        40        50        60        70 
 170         // 01234567890123456789012345678901234567890123456789012345678901234567890 
 171         // ----------------------------------------------------------------------- 
 172         // 00000000000000000000000000000000000000000000000000000000000000000000000 
 173         // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
 177         // 1 2 34567890 1234567890123456 7 8901234 
 178         // --------------------------------------- 
 179         // 1 1 01110011 0000000001000110 0 1001010 
 180         // s w ffffffff cccccccccccccccc w ppppppp 
 181         //     |--115-| |------71------| 
 182         // s = format start bit, o = odd parity of last 7 bits 
 183         // f = facility code, c = card number 
 184         // w = wiegand parity, x = extra space for other formats 
 185         // p = unknown checksum 
 186         // (26 bit format shown) 
 188         //find start bit to get fmtLen 
 190         for (j
=0; j
<size
; j
++){ 
 191                 if(BitStream
[j
]) break; 
 193         uint8_t fmtLen 
= size
-j
-8; 
 195         uint32_t cardnum 
= 0; 
 198                 fc 
= bytebits_to_byte(BitStream
+73, 8); 
 199                 cardnum 
= bytebits_to_byte(BitStream
+81, 16); 
 200                 code1 
= bytebits_to_byte(BitStream
+72,fmtLen
); 
 201                 PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x%08x", fmtLen
, fc
, cardnum
, code1
, rawHi3
, rawHi2
, rawHi
, rawLo
); 
 202         } else if (fmtLen
==45){ 
 203                 fmtLen
=42; //end = 10 bits not 7 like 26 bit fmt 
 204                 fc 
= bytebits_to_byte(BitStream
+53, 10); 
 205                 cardnum 
= bytebits_to_byte(BitStream
+63, 32); 
 206                 PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Raw: %08x%08x%08x%08x", fmtLen
, fc
, cardnum
, rawHi3
, rawHi2
, rawHi
, rawLo
); 
 208                 cardnum 
= bytebits_to_byte(BitStream
+81, 16); 
 210                         //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen-32); 
 211                         //code2 = bytebits_to_byte(BitStream+(size-32),32); 
 212                         PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen
, cardnum
, rawHi3
, rawHi2
, rawHi
, rawLo
); 
 214                         //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen); 
 215                         PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen
, cardnum
, rawHi3
, rawHi2
, rawHi
, rawLo
); 
 218         if (checksum 
== checkCS
) 
 219                 PrintAndLog("Checksum %02x passed", checksum
); 
 221                 PrintAndLog("Checksum %02x failed - should have been %02x", checksum
, checkCS
); 
 224                 PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx
, 128); 
 230 int CmdPyramidRead(const char *Cmd
) { 
 231         lf_read(true, 15000); 
 232         return CmdFSKdemodPyramid(""); 
 235 int CmdPyramidClone(const char *Cmd
) { 
 237         char cmdp 
= param_getchar(Cmd
, 0); 
 238         if (strlen(Cmd
) == 0 || cmdp 
== 'h' || cmdp 
== 'H') return usage_lf_pyramid_clone(); 
 240         uint32_t facilitycode
=0, cardnumber
=0, fc 
= 0, cn 
= 0; 
 244         memset(bs
, 0x00, sizeof(bs
)); 
 246         if (sscanf(Cmd
, "%u %u", &fc
, &cn 
) != 2) return usage_lf_pyramid_clone(); 
 248         facilitycode 
= (fc 
& 0x000000FF); 
 249         cardnumber 
= (cn 
& 0x0000FFFF); 
 251         if ( !GetPyramidBits(facilitycode
, cardnumber
, bs
)) { 
 252                 PrintAndLog("Error with tag bitstream generation."); 
 256         //Pyramid - compat mode, FSK2a, data rate 50, 4 data blocks 
 257         blocks
[0] = T55x7_MODULATION_FSK2a 
| T55x7_BITRATE_RF_50 
| 4<<T55x7_MAXBLOCK_SHIFT
; 
 259         if (param_getchar(Cmd
, 3) == 'Q' || param_getchar(Cmd
, 3) == 'q') 
 260                 blocks
[0] = T5555_MODULATION_FSK2 
| T5555_INVERT_OUTPUT 
| 50<<T5555_BITRATE_SHIFT 
| 4<<T5555_MAXBLOCK_SHIFT
; 
 262         blocks
[1] = bytebits_to_byte(bs
,32); 
 263         blocks
[2] = bytebits_to_byte(bs
+32,32); 
 264         blocks
[3] = bytebits_to_byte(bs
+64,32); 
 265         blocks
[4] = bytebits_to_byte(bs
+96,32); 
 267         PrintAndLog("Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u", facilitycode
, cardnumber
); 
 268         PrintAndLog("Blk | Data "); 
 269         PrintAndLog("----+------------"); 
 270         for ( i 
= 0; i
<5; ++i 
) 
 271                 PrintAndLog(" %02d | %08" PRIx32
, i
, blocks
[i
]); 
 274         UsbCommand c 
= {CMD_T55XX_WRITE_BLOCK
, {0,0,0}}; 
 276         for ( i 
= 0; i
<5; ++i 
) { 
 277                 c
.arg
[0] = blocks
[i
]; 
 279                 clearCommandBuffer(); 
 281                 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 1000)){ 
 282                         PrintAndLog("Error occurred, device did not respond during write operation."); 
 289 int CmdPyramidSim(const char *Cmd
) { 
 291         char cmdp 
= param_getchar(Cmd
, 0); 
 292         if (strlen(Cmd
) == 0 || cmdp 
== 'h' || cmdp 
== 'H') return usage_lf_pyramid_sim(); 
 294         uint32_t facilitycode 
= 0, cardnumber 
= 0, fc 
= 0, cn 
= 0; 
 297         size_t size 
= sizeof(bs
); 
 298         memset(bs
, 0x00, size
); 
 300         // Pyramid uses:  fcHigh: 10, fcLow: 8, clk: 50, invert: 0 
 302         arg1 
= (10 << 8) + 8; 
 305         if (sscanf(Cmd
, "%u %u", &fc
, &cn 
) != 2) return usage_lf_pyramid_sim(); 
 307         facilitycode 
= (fc 
& 0x000000FF); 
 308         cardnumber 
= (cn 
& 0x0000FFFF); 
 310         if ( !GetPyramidBits(facilitycode
, cardnumber
, bs
)) { 
 311                 PrintAndLog("Error with tag bitstream generation."); 
 315         PrintAndLog("Simulating Farpointe/Pyramid - Facility Code: %u, CardNumber: %u", facilitycode
, cardnumber 
); 
 317         UsbCommand c 
= {CMD_FSK_SIM_TAG
, {arg1
, arg2
, size
}}; 
 318         memcpy(c
.d
.asBytes
, bs
, size
); 
 319         clearCommandBuffer(); 
 324 static command_t CommandTable
[] = { 
 325         {"help",  CmdHelp
,            1, "This help"}, 
 326         {"demod", CmdFSKdemodPyramid
, 1, "Demodulate a Pyramid FSK tag from the GraphBuffer"}, 
 327         {"read",  CmdPyramidRead
,     0, "Attempt to read and extract tag data"}, 
 328         {"clone", CmdPyramidClone
,    0, "<Facility-Code> <Card Number>  clone pyramid tag"}, 
 329         {"sim",   CmdPyramidSim
,      0, "<Facility-Code> <Card Number>  simulate pyramid tag"}, 
 330         {NULL
, NULL
, 0, NULL
} 
 333 int CmdLFPyramid(const char *Cmd
) { 
 334         clearCommandBuffer(); 
 335         CmdsParse(CommandTable
, Cmd
); 
 339 int CmdHelp(const char *Cmd
) { 
 340         CmdsHelp(CommandTable
);