1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // Low frequency Farpoint / Pyramid tag commands
17 // FSK2a, rf/50, 128 bits (complete)
18 //-----------------------------------------------------------------------------
19 #include "cmdlfpyramid.h"
25 #include "commonutil.h" // ARRAYLEN
26 #include "cmdparser.h" // command_t
32 #include "protocols.h" // for T55xx config register definitions
33 #include "lfdemod.h" // parityTest
35 #include "cmdlft55xx.h" // verifywrite
36 #include "cliparser.h"
37 #include "cmdlfem4x05.h" // EM Defines
39 static int CmdHelp(const char *Cmd
);
41 //Pyramid Prox demod - FSK RF/50 with preamble of 0000000000000001 (always a 128 bit data stream)
42 //print full Farpointe Data/Pyramid Prox ID and some bit format details if found
43 int demodPyramid(bool verbose
) {
44 (void) verbose
; // unused so far
45 //raw fsk demod no manchester decoding no start bit finding just get binary from wave
46 uint8_t *bits
= calloc(MAX_GRAPH_TRACE_LEN
, sizeof(uint8_t));
48 PrintAndLogEx(FAILED
, "failed to allocate memory");
51 size_t size
= getFromGraphBuffer(bits
);
53 PrintAndLogEx(DEBUG
, "DEBUG: Error - Pyramid not enough samples");
57 //get binary from fsk wave
59 int idx
= detectPyramid(bits
, &size
, &waveIdx
);
62 PrintAndLogEx(DEBUG
, "DEBUG: Error - Pyramid: not enough samples");
64 PrintAndLogEx(DEBUG
, "DEBUG: Error - Pyramid: only noise found");
66 PrintAndLogEx(DEBUG
, "DEBUG: Error - Pyramid: problem during FSK demod");
68 PrintAndLogEx(DEBUG
, "DEBUG: Error - Pyramid: preamble not found");
70 PrintAndLogEx(DEBUG
, "DEBUG: Error - Pyramid: size not correct: %zu", size
);
72 PrintAndLogEx(DEBUG
, "DEBUG: Error - Pyramid: error demoding fsk idx: %d", idx
);
76 setDemodBuff(bits
, size
, idx
);
77 setClockGrid(50, waveIdx
+ (idx
* 50));
80 // 0 10 20 30 40 50 60
82 // 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3
83 // -----------------------------------------------------------------------------
84 // 0000000 0 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1
85 // premable xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o
87 // 64 70 80 90 100 110 120
89 // 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7
90 // -----------------------------------------------------------------------------
91 // 0000000 1 0000000 1 0000000 1 0110111 0 0011000 1 0000001 0 0001100 1 1001010 0
92 // xxxxxxx o xxxxxxx o xxxxxxx o xswffff o ffffccc o ccccccc o ccccccw o ppppppp o
93 // |---115---||---------71---------|
94 // s = format start bit, o = odd parity of last 7 bits
95 // f = facility code, c = card number
96 // w = wiegand parity, x = extra space for other formats
97 // p = CRC8maxim checksum
98 // (26 bit format shown)
100 //get bytes for checksum calc
101 uint8_t checksum
= bytebits_to_byte(bits
+ idx
+ 120, 8);
102 uint8_t csBuff
[14] = {0x00};
103 for (uint8_t i
= 0; i
< 13; i
++) {
104 csBuff
[i
] = bytebits_to_byte(bits
+ idx
+ 16 + (i
* 8), 8);
106 //check checksum calc
107 //checksum calc thanks to ICEMAN!!
108 uint32_t checkCS
= CRC8Maxim(csBuff
, 13);
110 //get raw ID before removing parities
111 uint32_t rawLo
= bytebits_to_byte(bits
+ idx
+ 96, 32);
112 uint32_t rawHi
= bytebits_to_byte(bits
+ idx
+ 64, 32);
113 uint32_t rawHi2
= bytebits_to_byte(bits
+ idx
+ 32, 32);
114 uint32_t rawHi3
= bytebits_to_byte(bits
+ idx
, 32);
116 size
= removeParity(bits
, idx
+ 8, 8, 1, 120);
119 PrintAndLogEx(DEBUG
, "DEBUG: Error - Pyramid: parity check failed - IDX: %d, hi3: %08X", idx
, rawHi3
);
121 PrintAndLogEx(DEBUG
, "DEBUG: Error - Pyramid: at parity check - tag size does not match Pyramid format, SIZE: %zu, IDX: %d, hi3: %08X", size
, idx
, rawHi3
);
126 // ok valid card found!
129 // 0 10 20 30 40 50 60 70
131 // 01234567890123456789012345678901234567890123456789012345678901234567890
132 // -----------------------------------------------------------------------
133 // 00000000000000000000000000000000000000000000000000000000000000000000000
134 // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
138 // 1 2 34567890 1234567890123456 7 8901234
139 // ---------------------------------------
140 // 1 1 01110011 0000000001000110 0 1001010
141 // s w ffffffff cccccccccccccccc w ppppppp
142 // |--115-| |------71------|
143 // s = format start bit, o = odd parity of last 7 bits
144 // f = facility code, c = card number
145 // w = wiegand parity, x = extra space for other formats
146 // p = CRC8-Maxim checksum
147 // (26 bit format shown)
149 //find start bit to get fmtLen
151 for (j
= 0; j
< size
; ++j
) {
155 uint8_t fmtLen
= size
- j
- 8;
158 uint32_t fc
= bytebits_to_byte(bits
+ 73, 8);
159 uint32_t cardnum
= bytebits_to_byte(bits
+ 81, 16);
160 uint32_t code1
= bytebits_to_byte(bits
+ 72, fmtLen
);
161 PrintAndLogEx(SUCCESS
, "Pyramid - len: " _GREEN_("%d") ", FC: " _GREEN_("%d") " Card: " _GREEN_("%d") " - Wiegand: " _GREEN_("%x")", Raw: %08x%08x%08x%08x", fmtLen
, fc
, cardnum
, code1
, rawHi3
, rawHi2
, rawHi
, rawLo
);
162 } else if (fmtLen
== 45) {
163 fmtLen
= 42; //end = 10 bits not 7 like 26 bit fmt
164 uint32_t fc
= bytebits_to_byte(bits
+ 53, 10);
165 uint32_t cardnum
= bytebits_to_byte(bits
+ 63, 32);
166 PrintAndLogEx(SUCCESS
, "Pyramid - len: " _GREEN_("%d") ", FC: " _GREEN_("%d") " Card: " _GREEN_("%d") ", Raw: %08x%08x%08x%08x", fmtLen
, fc
, cardnum
, rawHi3
, rawHi2
, rawHi
, rawLo
);
168 } else if (fmtLen > 32) {
169 uint32_t cardnum = bytebits_to_byte(bits + 81, 16);
170 //uint32_t code1 = bytebits_to_byte(bits+(size-fmtLen),fmtLen-32);
171 //code2 = bytebits_to_byte(bits+(size-32),32);
172 PrintAndLogEx(SUCCESS, "Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
175 uint32_t cardnum
= bytebits_to_byte(bits
+ 81, 16);
176 //uint32_t code1 = bytebits_to_byte(bits+(size-fmtLen),fmtLen);
177 PrintAndLogEx(SUCCESS
, "Pyramid - len: " _GREEN_("%d") " -unknown- Card: " _GREEN_("%d") ", Raw: %08x%08x%08x%08x", fmtLen
, cardnum
, rawHi3
, rawHi2
, rawHi
, rawLo
);
180 PrintAndLogEx(DEBUG
, "DEBUG: Pyramid: checksum : 0x%02X - 0x%02X ( %s )"
183 , (checksum
== checkCS
) ? _GREEN_("ok") : _RED_("fail")
186 PrintAndLogEx(DEBUG
, "DEBUG: Pyramid: idx: %d, Len: %d, Printing DemodBuffer:", idx
, 128);
188 printDemodBuff(0, false, false, false);
195 static int CmdPyramidDemod(const char *Cmd
) {
196 CLIParserContext
*ctx
;
197 CLIParserInit(&ctx
, "lf pyramid demod",
198 "Try to find Farpoint/Pyramid preamble, if found decode / descramble data",
206 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
208 return demodPyramid(true);
211 static int CmdPyramidReader(const char *Cmd
) {
212 CLIParserContext
*ctx
;
213 CLIParserInit(&ctx
, "lf pyramid reader",
214 "read a Farpointe/Pyramid tag",
215 "lf pyramid reader -@ -> continuous reader mode"
220 arg_lit0("@", NULL
, "optional - continuous reader mode"),
223 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
224 bool cm
= arg_get_lit(ctx
, 1);
228 PrintAndLogEx(INFO
, "Press " _GREEN_("<Enter>") " to exit");
232 lf_read(false, 15000);
234 } while (cm
&& !kbd_enter_pressed());
239 static int CmdPyramidClone(const char *Cmd
) {
241 CLIParserContext
*ctx
;
242 CLIParserInit(&ctx
, "lf pyramid clone",
243 "clone a Farpointe/Pyramid tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
244 "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.\n"
245 "Currently only works on 26bit",
246 "lf pyramid clone --fc 123 --cn 11223 -> encode for T55x7 tag\n"
247 "lf pyramid clone --raw 0001010101010101010440013223921c -> idem, raw mode\n"
248 "lf pyramid clone --fc 123 --cn 11223 --q5 -> encode for Q5/T5555 tag\n"
249 "lf pyramid clone --fc 123 --cn 11223 --em -> encode for EM4305/4469\n"
254 arg_u64_0(NULL
, "fc", "<dec>", "8-bit value facility code"),
255 arg_u64_0(NULL
, "cn", "<dec>", "16-bit value card number"),
256 arg_lit0(NULL
, "q5", "optional - specify writing to Q5/T5555 tag"),
257 arg_lit0(NULL
, "em", "optional - specify writing to EM4305/4469 tag"),
258 arg_str0("r", "raw", "<hex>", "raw hex data. 16 bytes"),
261 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
263 uint32_t fc
= arg_get_u32_def(ctx
, 1, -1);
264 uint32_t cn
= arg_get_u32_def(ctx
, 2, -1);
265 bool q5
= arg_get_lit(ctx
, 3);
266 bool em
= arg_get_lit(ctx
, 4);
269 // skip first block, 4*4 = 16 bytes left
270 uint8_t raw
[16] = {0};
271 int res
= CLIParamHexToBuf(arg_get_str(ctx
, 5), raw
, sizeof raw
, &raw_len
);
280 PrintAndLogEx(FAILED
, "Can't specify both Q5 and EM4305 at the same time");
284 bool use_raw
= (raw_len
> 0);
286 if (fc
== -1 && cn
== -1) {
287 if (use_raw
== false) {
288 PrintAndLogEx(FAILED
, "Must specify either raw data to clone, or fc/cn");
292 // --raw and --fc/cn are mutually exclusive
294 PrintAndLogEx(FAILED
, "Can't specify both raw and fc/cn at the same time");
301 for (uint8_t i
= 1; i
< ARRAYLEN(blocks
); i
++) {
302 blocks
[i
] = bytes_to_num(raw
+ ((i
- 1) * 4), sizeof(uint32_t));
306 uint8_t *bs
= calloc(128, sizeof(uint8_t));
311 uint32_t facilitycode
= (fc
& 0x000000FF);
312 uint32_t cardnumber
= (cn
& 0x0000FFFF);
314 if (getPyramidBits(facilitycode
, cardnumber
, bs
) != PM3_SUCCESS
) {
315 PrintAndLogEx(ERR
, "Error with tag bitstream generation.");
319 blocks
[1] = bytebits_to_byte(bs
, 32);
320 blocks
[2] = bytebits_to_byte(bs
+ 32, 32);
321 blocks
[3] = bytebits_to_byte(bs
+ 64, 32);
322 blocks
[4] = bytebits_to_byte(bs
+ 96, 32);
327 //Pyramid - compat mode, FSK2a, data rate 50, 4 data blocks
328 blocks
[0] = T55x7_MODULATION_FSK2a
| T55x7_BITRATE_RF_50
| 4 << T55x7_MAXBLOCK_SHIFT
;
329 char cardtype
[16] = {"T55x7"};
333 blocks
[0] = T5555_FIXED
| T5555_MODULATION_FSK2
| T5555_INVERT_OUTPUT
| T5555_SET_BITRATE(50) | 4 << T5555_MAXBLOCK_SHIFT
;
334 snprintf(cardtype
, sizeof(cardtype
), "Q5/T5555");
338 PrintAndLogEx(WARNING
, "Beware some EM4305 tags don't support FSK and datarate = RF/50, check your tag copy!");
339 blocks
[0] = EM4305_PYRAMID_CONFIG_BLOCK
;
341 for (uint8_t i
= 1; i
< ARRAYLEN(blocks
) ; i
++) {
342 blocks
[i
] = blocks
[i
] ^ 0xFFFFFFFF;
344 snprintf(cardtype
, sizeof(cardtype
), "EM4305/4469");
347 PrintAndLogEx(INFO
, "Preparing to clone Farpointe/Pyramid to " _YELLOW_("%s") " from %s.",
349 use_raw
? "raw hex" : "specified data"
351 print_blocks(blocks
, ARRAYLEN(blocks
));
354 res
= em4x05_clone_tag(blocks
, ARRAYLEN(blocks
), 0, false);
356 res
= clone_t55xx_tag(blocks
, ARRAYLEN(blocks
));
358 PrintAndLogEx(SUCCESS
, "Done");
359 PrintAndLogEx(HINT
, "Hint: try " _YELLOW_("`lf pyramid reader`") " to verify");
363 static int CmdPyramidSim(const char *Cmd
) {
364 CLIParserContext
*ctx
;
365 CLIParserInit(&ctx
, "lf pyramid sim",
366 "Enables simulation of Farpointe/Pyramid card with specified card number.\n"
367 "Simulation runs until the button is pressed or another USB command is issued.\n"
368 "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.\n"
369 "Currently work only on 26bit",
370 "lf pyramid sim --fc 123 --cn 1337\n"
371 "lf pyramid sim --raw 0001010101010101010440013223921c"
376 arg_u64_0(NULL
, "fc", "<dec>", "8-bit value facility code"),
377 arg_u64_0(NULL
, "cn", "<dec>", "16-bit value card number"),
378 arg_str0("r", "raw", "<hex>", "raw hex data. 16 bytes"),
381 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
382 uint32_t fc
= arg_get_u32_def(ctx
, 1, -1);
383 uint32_t cn
= arg_get_u32_def(ctx
, 2, -1);
386 // skip first block, 4*4 = 16 bytes left
387 uint8_t raw
[16] = {0};
388 int res
= CLIParamHexToBuf(arg_get_str(ctx
, 3), raw
, sizeof raw
, &raw_len
);
396 bool use_raw
= (raw_len
> 0);
398 if (fc
== -1 && cn
== -1) {
399 if (use_raw
== false) {
400 PrintAndLogEx(FAILED
, "Must specify either raw data to clone, or fc/cn");
404 // --raw and --fc/cn are mutually exclusive
406 PrintAndLogEx(FAILED
, "Can't specify both raw and fc/cn at the same time");
411 uint8_t bs
[sizeof(raw
) * 8];
412 memset(bs
, 0x00, sizeof(bs
));
414 if (use_raw
== false) {
415 uint32_t facilitycode
= (fc
& 0x000000FF);
416 uint32_t cardnumber
= (cn
& 0x0000FFFF);
418 if (getPyramidBits(facilitycode
, cardnumber
, bs
) != PM3_SUCCESS
) {
419 PrintAndLogEx(ERR
, "Error with tag bitstream generation.");
422 PrintAndLogEx(SUCCESS
, "Simulating Farpointe/Pyramid - Facility Code: " _YELLOW_("%u") ", CardNumber: " _YELLOW_("%u"), facilitycode
, cardnumber
);
424 PrintAndLogEx(SUCCESS
, "Simulating Farpointe/Pyramid - raw " _YELLOW_("%s"), sprint_hex_inrow(raw
, sizeof(raw
)));
425 bytes_to_bytebits(raw
, sizeof(raw
), bs
);
428 // Pyramid uses: fcHigh: 10, fcLow: 8, clk: 50, invert: 0
429 lf_fsksim_t
*payload
= calloc(1, sizeof(lf_fsksim_t
) + sizeof(bs
));
430 payload
->fchigh
= 10;
432 payload
->separator
= 0;
434 memcpy(payload
->data
, bs
, sizeof(bs
));
436 clearCommandBuffer();
437 SendCommandNG(CMD_LF_FSK_SIMULATE
, (uint8_t *)payload
, sizeof(lf_fsksim_t
) + sizeof(bs
));
440 return lfsim_wait_check(CMD_LF_FSK_SIMULATE
);
443 static command_t CommandTable
[] = {
444 {"help", CmdHelp
, AlwaysAvailable
, "this help"},
445 {"demod", CmdPyramidDemod
, AlwaysAvailable
, "demodulate a Pyramid FSK tag from the GraphBuffer"},
446 {"reader", CmdPyramidReader
, IfPm3Lf
, "attempt to read and extract tag data"},
447 {"clone", CmdPyramidClone
, IfPm3Lf
, "clone pyramid tag to T55x7, Q5/T5555 or EM4305/4469"},
448 {"sim", CmdPyramidSim
, IfPm3Lf
, "simulate pyramid tag"},
449 {NULL
, NULL
, NULL
, NULL
}
452 int CmdLFPyramid(const char *Cmd
) {
453 clearCommandBuffer();
454 return CmdsParse(CommandTable
, Cmd
);
457 int CmdHelp(const char *Cmd
) {
458 (void)Cmd
; // Cmd is not used so far
459 CmdsHelp(CommandTable
);
464 int getPyramidBits(uint32_t fc
, uint32_t cn
, uint8_t *pyramidBits
) {
467 memset(pre
, 0x00, sizeof(pre
));
472 // Get 26 wiegand from FacilityCode, CardNumber
474 memset(wiegand
, 0x00, sizeof(wiegand
));
475 num_to_bytebits(fc
, 8, wiegand
);
476 num_to_bytebits(cn
, 16, wiegand
+ 8);
478 // add wiegand parity bits (dest, source, len)
479 wiegand_add_parity(pre
+ 80, wiegand
, 24);
481 // add paritybits (bitsource, dest, sourcelen, paritylen, parityType (odd, even,)
482 addParity(pre
+ 8, pyramidBits
+ 8, 102, 8, 1);
486 for (uint8_t i
= 0; i
< 13; i
++)
487 csBuff
[i
] = bytebits_to_byte(pyramidBits
+ 16 + (i
* 8), 8);
489 uint32_t crc
= CRC8Maxim(csBuff
, 13);
490 num_to_bytebits(crc
, 8, pyramidBits
+ 120);
494 // FSK Demod then try to locate a Farpointe Data (pyramid) ID
495 int detectPyramid(uint8_t *dest
, size_t *size
, int *waveStartIdx
) {
496 //make sure buffer has data
497 if (*size
< 128 * 50) return -1;
499 //test samples are not just noise
500 if (getSignalProperties()->isnoise
) return -2;
502 // FSK demodulator RF/50 FSK 10,8
503 *size
= fskdemod(dest
, *size
, 50, 1, 10, 8, waveStartIdx
); // pyramid fsk2
505 //did we get a good demod?
506 if (*size
< 128) return -3;
509 uint8_t preamble
[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1};
510 if (!preambleSearch(dest
, preamble
, sizeof(preamble
), size
, &startIdx
))
511 return -4; //preamble not found
513 // wrong size? (between to preambles)
514 if (*size
< 128) return -5;
516 return (int)startIdx
;