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 Indala commands
8 // PSK1, rf/32, 64 or 224 bits (known)
9 //-----------------------------------------------------------------------------
11 #include "cmdlfindala.h"
16 #include "cmdparser.h" // command_t
19 #include "cliparser.h"
20 #include "commonutil.h"
21 #include "ui.h" // PrintAndLog
23 #include "lfdemod.h" // parityTest, bitbytes_to_byte
25 #include "cmdlf.h" // lf_read
26 #include "protocols.h" // t55 defines
27 #include "cmdlft55xx.h" // verifywrite
28 #include "cliparser.h"
29 #include "cmdlfem4x05.h" // EM defines
31 #define INDALA_ARR_LEN 64
33 static int CmdHelp(const char *Cmd
);
35 //large 224 bit indala formats (different preamble too...)
36 static uint8_t preamble224
[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
38 // standard 64 bit indala formats including 26 bit 40134 format
39 static uint8_t preamble64
[] = {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
41 #define HEDEN2L_OFFSET 31
42 static void encodeHeden2L(uint8_t *dest
, uint32_t cardnumber
) {
44 uint8_t template[] = {
45 1, 0, 1, 0, 0, 0, 0, 0,
46 0, 0, 0, 0, 0, 0, 0, 0,
47 0, 0, 0, 0, 0, 0, 0, 0,
48 0, 0, 0, 0, 0, 0, 0, 0,
49 1, 0, 0, 0, 1, 0, 0, 0,
50 1, 0, 0, 0, 0, 0, 0, 0,
51 0, 0, 0, 0, 1, 0, 0, 1,
52 0, 0, 0, 0, 0, 0, 1, 0
56 num_to_bytebits(cardnumber
, sizeof(cardbits
), cardbits
);
58 if (cardbits
[31] == 1) template[HEDEN2L_OFFSET
+ 8] = 0x1;
59 if (cardbits
[30] == 1) template[HEDEN2L_OFFSET
+ 10] = 0x1;
60 if (cardbits
[29] == 1) template[HEDEN2L_OFFSET
+ 14] = 0x1;
61 if (cardbits
[28] == 1) template[HEDEN2L_OFFSET
+ 15] = 0x1;
62 if (cardbits
[27] == 1) template[HEDEN2L_OFFSET
+ 12] = 0x1;
63 if (cardbits
[26] == 1) template[HEDEN2L_OFFSET
+ 28] = 0x1;
64 if (cardbits
[25] == 1) template[HEDEN2L_OFFSET
+ 3] = 0x1;
65 if (cardbits
[24] == 1) template[HEDEN2L_OFFSET
+ 11] = 0x1;
66 if (cardbits
[23] == 1) template[HEDEN2L_OFFSET
+ 19] = 0x1;
67 if (cardbits
[22] == 1) template[HEDEN2L_OFFSET
+ 26] = 0x1;
68 if (cardbits
[21] == 1) template[HEDEN2L_OFFSET
+ 17] = 0x1;
69 if (cardbits
[20] == 1) template[HEDEN2L_OFFSET
+ 18] = 0x1;
70 if (cardbits
[19] == 1) template[HEDEN2L_OFFSET
+ 20] = 0x1;
71 if (cardbits
[18] == 1) template[HEDEN2L_OFFSET
+ 13] = 0x1;
72 if (cardbits
[17] == 1) template[HEDEN2L_OFFSET
+ 7] = 0x1;
73 if (cardbits
[16] == 1) template[HEDEN2L_OFFSET
+ 23] = 0x1;
77 for (int i
= 0; i
< sizeof(template) - HEDEN2L_OFFSET
; i
++) {
81 template[63] = (counter
& 0x1);
83 for (int i
= 0; i
< sizeof(template); i
+= 8) {
84 dest
[i
/ 8] = bytebits_to_byte(template + i
, 8);
87 PrintAndLogEx(INFO
, "Heden-2L card number %u", cardnumber
);
90 static void decodeHeden2L(uint8_t *bits
) {
92 uint32_t cardnumber
= 0;
93 uint8_t offset
= HEDEN2L_OFFSET
;
95 if (bits
[offset
+ 8]) cardnumber
+= 1;
96 if (bits
[offset
+ 10]) cardnumber
+= 2;
97 if (bits
[offset
+ 14]) cardnumber
+= 4;
98 if (bits
[offset
+ 15]) cardnumber
+= 8;
99 if (bits
[offset
+ 12]) cardnumber
+= 16;
100 if (bits
[offset
+ 28]) cardnumber
+= 32;
101 if (bits
[offset
+ 3]) cardnumber
+= 64;
102 if (bits
[offset
+ 11]) cardnumber
+= 128;
103 if (bits
[offset
+ 19]) cardnumber
+= 256;
104 if (bits
[offset
+ 26]) cardnumber
+= 512;
105 if (bits
[offset
+ 17]) cardnumber
+= 1024;
106 if (bits
[offset
+ 18]) cardnumber
+= 2048;
107 if (bits
[offset
+ 20]) cardnumber
+= 4096;
108 if (bits
[offset
+ 13]) cardnumber
+= 8192;
109 if (bits
[offset
+ 7]) cardnumber
+= 16384;
110 if (bits
[offset
+ 23]) cardnumber
+= 32768;
112 PrintAndLogEx(SUCCESS
, " Heden-2L | %u", cardnumber
);
115 // Indala 26 bit decode
116 // by marshmellow, martinbeier
117 // optional arguments - same as PSKDemod (clock & invert & maxerr)
118 int demodIndalaEx(int clk
, int invert
, int maxErr
, bool verbose
) {
119 (void) verbose
; // unused so far
120 int ans
= PSKDemod(clk
, invert
, maxErr
, true);
121 if (ans
!= PM3_SUCCESS
) {
122 PrintAndLogEx(DEBUG
, "DEBUG: Error - Indala can't demod signal: %d", ans
);
127 size_t size
= DemodBufferLen
;
128 int idx
= detectIndala(DemodBuffer
, &size
, &inv
);
131 PrintAndLogEx(DEBUG
, "DEBUG: Error - Indala: not enough samples");
133 PrintAndLogEx(DEBUG
, "DEBUG: Error - Indala: only noise found");
135 PrintAndLogEx(DEBUG
, "DEBUG: Error - Indala: preamble not found");
137 PrintAndLogEx(DEBUG
, "DEBUG: Error - Indala: size not correct: %zu", size
);
139 PrintAndLogEx(DEBUG
, "DEBUG: Error - Indala: error demoding psk idx: %d", idx
);
142 setDemodBuff(DemodBuffer
, size
, idx
);
143 setClockGrid(g_DemodClock
, g_DemodStartIdx
+ (idx
* g_DemodClock
));
146 uint32_t uid1
= bytebits_to_byte(DemodBuffer
, 32);
147 uint32_t uid2
= bytebits_to_byte(DemodBuffer
+ 32, 32);
148 // To be checked, what's this internal ID ?
149 // foo is only used for 64b ids and in that case uid1 must be only preamble, plus the following code is wrong as x<<32 & 0x1FFFFFFF is always zero
150 //uint64_t foo = (((uint64_t)uid1 << 32) & 0x1FFFFFFF) | (uid2 & 0x7FFFFFFF);
151 uint64_t foo
= uid2
& 0x7FFFFFFF;
153 if (DemodBufferLen
== 64) {
154 PrintAndLogEx(SUCCESS
, "Indala (len %zu) Raw: " _GREEN_("%x%08x"), DemodBufferLen
, uid1
, uid2
);
157 p1
|= DemodBuffer
[32 + 3] << 8;
158 p1
|= DemodBuffer
[32 + 6] << 5;
159 p1
|= DemodBuffer
[32 + 8] << 4;
160 p1
|= DemodBuffer
[32 + 9] << 3;
161 p1
|= DemodBuffer
[32 + 11] << 1;
162 p1
|= DemodBuffer
[32 + 16] << 6;
163 p1
|= DemodBuffer
[32 + 19] << 7;
164 p1
|= DemodBuffer
[32 + 20] << 10;
165 p1
|= DemodBuffer
[32 + 21] << 2;
166 p1
|= DemodBuffer
[32 + 22] << 0;
167 p1
|= DemodBuffer
[32 + 24] << 9;
170 fc
|= DemodBuffer
[57] << 7; // b8
171 fc
|= DemodBuffer
[49] << 6; // b7
172 fc
|= DemodBuffer
[44] << 5; // b6
173 fc
|= DemodBuffer
[47] << 4; // b5
174 fc
|= DemodBuffer
[48] << 3; // b4
175 fc
|= DemodBuffer
[53] << 2; // b3
176 fc
|= DemodBuffer
[39] << 1; // b2
177 fc
|= DemodBuffer
[58] << 0; // b1
180 csn
|= DemodBuffer
[42] << 15; // b16
181 csn
|= DemodBuffer
[45] << 14; // b15
182 csn
|= DemodBuffer
[43] << 13; // b14
183 csn
|= DemodBuffer
[40] << 12; // b13
184 csn
|= DemodBuffer
[52] << 11; // b12
185 csn
|= DemodBuffer
[36] << 10; // b11
186 csn
|= DemodBuffer
[35] << 9; // b10
187 csn
|= DemodBuffer
[51] << 8; // b9
188 csn
|= DemodBuffer
[46] << 7; // b8
189 csn
|= DemodBuffer
[33] << 6; // b7
190 csn
|= DemodBuffer
[37] << 5; // b6
191 csn
|= DemodBuffer
[54] << 4; // b5
192 csn
|= DemodBuffer
[56] << 3; // b4
193 csn
|= DemodBuffer
[59] << 2; // b3
194 csn
|= DemodBuffer
[50] << 1; // b2
195 csn
|= DemodBuffer
[41] << 0; // b1
197 uint8_t checksum
= 0;
198 checksum
|= DemodBuffer
[62] << 1; // b2
199 checksum
|= DemodBuffer
[63] << 0; // b1
201 PrintAndLogEx(SUCCESS
, "Fmt " _GREEN_("26") " FC: " _GREEN_("%u") " Card: " _GREEN_("%u") " checksum: " _GREEN_("%1d%1d")
204 , checksum
>> 1 & 0x01
208 PrintAndLogEx(SUCCESS
, "Possible de-scramble patterns");
209 PrintAndLogEx(SUCCESS
, " Printed | __%04d__ [0x%X]", p1
, p1
);
210 PrintAndLogEx(SUCCESS
, " Internal ID | %" PRIu64
, foo
);
211 decodeHeden2L(DemodBuffer
);
214 uint32_t uid3
= bytebits_to_byte(DemodBuffer
+ 64, 32);
215 uint32_t uid4
= bytebits_to_byte(DemodBuffer
+ 96, 32);
216 uint32_t uid5
= bytebits_to_byte(DemodBuffer
+ 128, 32);
217 uint32_t uid6
= bytebits_to_byte(DemodBuffer
+ 160, 32);
218 uint32_t uid7
= bytebits_to_byte(DemodBuffer
+ 192, 32);
221 , "Indala (len %zu) Raw: " _GREEN_("%x%08x%08x%08x%08x%08x%08x")
234 PrintAndLogEx(DEBUG
, "DEBUG: Indala - printing demodbuffer");
235 printDemodBuff(0, false, false, false);
240 int demodIndala(bool verbose
) {
241 return demodIndalaEx(0, 0, 100, verbose
);
244 static int CmdIndalaDemod(const char *Cmd
) {
246 CLIParserContext
*ctx
;
247 CLIParserInit(&ctx
, "lf indala demod",
248 "Tries to psk demodulate the graphbuffer as Indala",
250 "lf indala demod --clock 32 -> demod a Indala tag from GraphBuffer using a clock of RF/32\n"
251 "lf indala demod --clock 32 -i -> demod a Indala tag from GraphBuffer using a clock of RF/32 and inverting data\n"
252 "lf indala demod --clock 64 -i --maxerror 0 -> demod a Indala tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"
257 arg_int0(NULL
, "clock", "<dec>", "optional - set clock (as integer), if not set, autodetect."),
258 arg_int0(NULL
, "maxerr", "<dec>", "optional - set maximum allowed errors, default = 100"),
259 arg_lit0("i", "invert", "optional - invert output"),
262 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
263 uint32_t clk
= arg_get_u32_def(ctx
, 1, 32);
264 uint32_t max_err
= arg_get_u32_def(ctx
, 2, 100);
265 bool invert
= arg_get_lit(ctx
, 3);
268 return demodIndalaEx(clk
, invert
, max_err
, true);
271 // older alternative indala demodulate (has some positives and negatives)
272 // returns false positives more often - but runs against more sets of samples
273 // poor psk signal can be difficult to demod this approach might succeed when the other fails
274 // but the other appears to currently be more accurate than this approach most of the time.
275 static int CmdIndalaDemodAlt(const char *Cmd
) {
277 CLIParserContext
*ctx
;
278 CLIParserInit(&ctx
, "lf indala altdemod",
279 "Tries to psk demodulate the graphbuffer as Indala\n"
280 "This is uses a alternative way to demodulate and was used from the beginning in the Pm3 client.\n"
281 "It's now considered obsolete but remains because it has sometimes its advantages.",
282 "lf indala altdemod\n"
283 "lf indala altdemod --long -> demod a Indala tag from GraphBuffer as 224 bit long format"
288 arg_lit0("l", "long", "optional - demod as 224b long format"),
291 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
292 bool is_long
= arg_get_lit(ctx
, 1);
295 // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
300 // worst case with GraphTraceLen=40000 is < 4096
301 // under normal conditions it's < 2048
302 uint8_t data
[MAX_GRAPH_TRACE_LEN
] = {0};
303 size_t datasize
= getFromGraphBuf(data
);
305 uint8_t rawbits
[4096];
307 int worst
= 0, worstPos
= 0;
309 //clear clock grid and demod plot
313 // PrintAndLogEx(NORMAL, "Expecting a bit less than %d raw bits", GraphTraceLen / 32);
314 // loop through raw signal - since we know it is psk1 rf/32 fc/2 skip every other value (+=2)
315 for (i
= 0; i
< datasize
- 1; i
+= 2) {
317 if ((data
[i
] > data
[i
+ 1]) && (state
!= 1)) {
318 // appears redundant - marshmellow
320 for (j
= 0; j
< count
- 8; j
+= 16) {
321 rawbits
[rawbit
++] = 0;
323 if ((abs(count
- j
)) > worst
) {
324 worst
= abs(count
- j
);
330 } else if ((data
[i
] < data
[i
+ 1]) && (state
!= 0)) {
333 for (j
= 0; j
< count
- 8; j
+= 16) {
334 rawbits
[rawbit
++] = 1;
336 if ((abs(count
- j
)) > worst
) {
337 worst
= abs(count
- j
);
347 PrintAndLogEx(INFO
, "Recovered %d raw bits, expected: %zu", rawbit
, GraphTraceLen
/ 32);
348 PrintAndLogEx(INFO
, "worst metric (0=best..7=worst): %d at pos %d", worst
, worstPos
);
353 // Finding the start of a UID
354 int uidlen
, long_wait
;
365 for (start
= 0; start
<= rawbit
- uidlen
; start
++) {
366 first
= rawbits
[start
];
367 for (i
= start
; i
< start
+ long_wait
; i
++) {
368 if (rawbits
[i
] != first
) {
372 if (i
== (start
+ long_wait
)) {
377 if (start
== rawbit
- uidlen
+ 1) {
378 PrintAndLogEx(FAILED
, "nothing to wait for");
382 // Inverting signal if needed
384 for (i
= start
; i
< rawbit
; i
++) {
385 rawbits
[i
] = !rawbits
[i
];
390 uint8_t bits
[224] = {0x00};
391 char showbits
[225] = {0x00};
396 if (uidlen
> rawbit
) {
397 PrintAndLogEx(WARNING
, "Warning: not enough raw bits to get a full UID");
398 for (bit
= 0; bit
< rawbit
; bit
++) {
399 bits
[bit
] = rawbits
[i
++];
400 // As we cannot know the parity, let's use "." and "/"
401 showbits
[bit
] = '.' + bits
[bit
];
403 showbits
[bit
+ 1] = '\0';
404 PrintAndLogEx(SUCCESS
, "Partial UID | %s", showbits
);
407 for (bit
= 0; bit
< uidlen
; bit
++) {
408 bits
[bit
] = rawbits
[i
++];
409 showbits
[bit
] = '0' + bits
[bit
];
420 for (idx
= 0; idx
< 64; idx
++) {
421 if (showbits
[idx
] == '0') {
422 uid1
= (uid1
<< 1) | (uid2
>> 31);
423 uid2
= (uid2
<< 1) | 0;
425 uid1
= (uid1
<< 1) | (uid2
>> 31);
426 uid2
= (uid2
<< 1) | 1;
429 PrintAndLogEx(SUCCESS
, "UID | %s (%x%08x)", showbits
, uid1
, uid2
);
437 for (idx
= 0; idx
< 224; idx
++) {
438 uid1
= (uid1
<< 1) | (uid2
>> 31);
439 uid2
= (uid2
<< 1) | (uid3
>> 31);
440 uid3
= (uid3
<< 1) | (uid4
>> 31);
441 uid4
= (uid4
<< 1) | (uid5
>> 31);
442 uid5
= (uid5
<< 1) | (uid6
>> 31);
443 uid6
= (uid6
<< 1) | (uid7
>> 31);
445 if (showbits
[idx
] == '0')
446 uid7
= (uid7
<< 1) | 0;
448 uid7
= (uid7
<< 1) | 1;
450 PrintAndLogEx(SUCCESS
, "UID | %s (%x%08x%08x%08x%08x%08x%08x)", showbits
, uid1
, uid2
, uid3
, uid4
, uid5
, uid6
, uid7
);
453 // Checking UID against next occurrences
454 for (; i
+ uidlen
<= rawbit
;) {
456 for (bit
= 0; bit
< uidlen
; bit
++) {
457 if (bits
[bit
] != rawbits
[i
++]) {
468 PrintAndLogEx(DEBUG
, "Occurrences: %d (expected %d)", times
, (rawbit
- start
) / uidlen
);
470 // Remodulating for tag cloning
471 // HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod)
472 // since this changes graphbuffer data.
473 GraphTraceLen
= 32 * uidlen
;
476 for (bit
= 0; bit
< uidlen
; bit
++) {
477 if (bits
[bit
] == 0) {
482 for (j
= 0; j
< 32; j
++) {
483 GraphBuffer
[i
++] = phase
;
488 RepaintGraphWindow();
492 // this read is the "normal" read, which download lf signal and tries to demod here.
493 static int CmdIndalaReader(const char *Cmd
) {
494 CLIParserContext
*ctx
;
495 CLIParserInit(&ctx
, "lf indala reader",
497 "lf indala reader -@ -> continuous reader mode"
502 arg_int0(NULL
, "clock", "<dec>", "optional - set clock (as integer), if not set, autodetect."),
503 arg_int0(NULL
, "maxerr", "<dec>", "optional - set maximum allowed errors, default = 100"),
504 arg_lit0("i", "invert", "optional - invert output"),
505 arg_lit0("@", NULL
, "optional - continuous reader mode"),
508 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
509 uint32_t clk
= arg_get_u32_def(ctx
, 1, 32);
510 uint32_t max_err
= arg_get_u32_def(ctx
, 2, 100);
511 bool invert
= arg_get_lit(ctx
, 3);
512 bool cm
= arg_get_lit(ctx
, 4);
516 PrintAndLogEx(INFO
, "Press " _GREEN_("<Enter>") " to exit");
520 lf_read(false, 30000);
521 demodIndalaEx(clk
, invert
, max_err
, !cm
);
522 } while (cm
&& !kbd_enter_pressed());
526 static int CmdIndalaSim(const char *Cmd
) {
528 CLIParserContext
*ctx
;
529 CLIParserInit(&ctx
, "lf indala sim",
530 "Enables simulation of Indala card with specified facility-code and card number.\n"
531 "Simulation runs until the button is pressed or another USB command is issued.",
532 "lf indala sim --heden 888\n"
533 "lf indala sim --raw a0000000a0002021\n"
534 "lf indala sim --raw 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"
539 arg_strx0("r", "raw", "<hex>", "raw bytes"),
540 arg_int0(NULL
, "heden", "<decimal>", "Cardnumber for Heden 2L format"),
543 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
547 uint8_t raw
[(7 * 4) + 1];
548 memset(raw
, 0, sizeof(raw
));
549 CLIGetHexWithReturn(ctx
, 1, raw
, &raw_len
);
551 bool is_long_uid
= (raw_len
== 28);
555 if (is_long_uid
== false) {
558 cardnumber
= arg_get_int_def(ctx
, 2, -1);
559 got_cn
= (cardnumber
!= -1);
565 encodeHeden2L(raw
, cardnumber
);
569 // convert to binarray
571 memset(bs
, 0x00, sizeof(bs
));
574 for (int8_t i
= 0; i
< raw_len
; i
++) {
575 uint8_t tmp
= raw
[i
];
576 bs
[counter
++] = (tmp
>> 7) & 1;
577 bs
[counter
++] = (tmp
>> 6) & 1;
578 bs
[counter
++] = (tmp
>> 5) & 1;
579 bs
[counter
++] = (tmp
>> 4) & 1;
580 bs
[counter
++] = (tmp
>> 3) & 1;
581 bs
[counter
++] = (tmp
>> 2) & 1;
582 bs
[counter
++] = (tmp
>> 1) & 1;
583 bs
[counter
++] = tmp
& 1;
586 // a0 00 00 00 bd 98 9a 11
589 // It has to send either 64bits (8bytes) or 224bits (28bytes). Zero padding needed if not.
590 // lf simpsk -1 -c 32 --fc 2 -d 0102030405060708
592 PrintAndLogEx(SUCCESS
, "Simulating " _YELLOW_("%s") " Indala raw " _YELLOW_("%s")
593 , (is_long_uid
) ? "224 bit" : "64 bit"
594 , sprint_hex_inrow(raw
, raw_len
)
596 PrintAndLogEx(SUCCESS
, "Press pm3-button to abort simulation or run another command");
598 // indala PSK, clock 32, carrier 0
599 lf_psksim_t
*payload
= calloc(1, sizeof(lf_psksim_t
) + sizeof(bs
));
600 payload
->carrier
= 2;
603 memcpy(payload
->data
, bs
, raw_len
* 8);
605 clearCommandBuffer();
606 SendCommandNG(CMD_LF_PSK_SIMULATE
, (uint8_t *)payload
, sizeof(lf_psksim_t
) + (raw_len
* 8));
609 PacketResponseNG resp
;
610 WaitForResponse(CMD_LF_PSK_SIMULATE
, &resp
);
612 PrintAndLogEx(INFO
, "Done");
613 if (resp
.status
!= PM3_EOPABORTED
)
618 static int CmdIndalaClone(const char *Cmd
) {
624 CLIParserContext
*ctx
;
625 CLIParserInit(&ctx
, "lf indala clone",
626 "clone Indala UID to T55x7 or Q5/T5555 tag\n"
627 _RED_("\nWarning, encoding with FC/CN doesn't always work"),
628 "lf indala clone --heden 888\n"
629 "lf indala clone --fc 123 --cn 1337\n"
630 "lf indala clone -r a0000000a0002021\n"
631 "lf indala clone -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5");
635 arg_strx0("r", "raw", "<hex>", "raw bytes"),
636 arg_int0(NULL
, "heden", "<decimal>", "Cardnumber for Heden 2L format"),
637 arg_int0(NULL
, "fc", "<decimal>", "Facility Code (26 bit H10301 format)"),
638 arg_int0(NULL
, "cn", "<decimal>", "Cardnumber (26 bit H10301 format)"),
639 arg_lit0(NULL
, "q5", "optional - specify writing to Q5/T5555 tag"),
640 arg_lit0(NULL
, "em", "optional - specify writing to EM4305/4469 tag"),
643 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
646 uint8_t raw
[(7 * 4) + 1];
647 CLIGetHexWithReturn(ctx
, 1, raw
, &raw_len
);
649 bool is_long_uid
= (raw_len
== 28);
650 bool q5
= arg_get_lit(ctx
, 5);
651 bool em
= arg_get_lit(ctx
, 6);
653 bool got_cn
= false, got_26
= false;
654 if (is_long_uid
== false) {
657 cardnumber
= arg_get_int_def(ctx
, 2, -1);
658 got_cn
= (cardnumber
!= -1);
661 fc
= arg_get_int_def(ctx
, 3, 0);
662 cn
= arg_get_int_def(ctx
, 4, 0);
663 got_26
= (fc
!= 0 && cn
!= 0);
668 PrintAndLogEx(FAILED
, "Can't specify both Q5 and EM4305 at the same time");
673 uint32_t blocks
[8] = {0};
674 char cardtype
[16] = {"T55x7"};
678 blocks
[0] = T55x7_BITRATE_RF_32
| T55x7_MODULATION_PSK2
| (7 << T55x7_MAXBLOCK_SHIFT
);
680 blocks
[0] = T5555_FIXED
| T5555_SET_BITRATE(32) | T5555_MODULATION_PSK2
| (7 << T5555_MAXBLOCK_SHIFT
);
681 snprintf(cardtype
, sizeof(cardtype
), "Q5/T5555");
685 blocks
[0] = EM4305_INDALA_224_CONFIG_BLOCK
;
686 snprintf(cardtype
, sizeof(cardtype
), "EM4305/4469");
689 blocks
[1] = bytes_to_num(raw
, 4);
690 blocks
[2] = bytes_to_num(raw
+ 4, 4);
691 blocks
[3] = bytes_to_num(raw
+ 8, 4);
692 blocks
[4] = bytes_to_num(raw
+ 12, 4);
693 blocks
[5] = bytes_to_num(raw
+ 16, 4);
694 blocks
[6] = bytes_to_num(raw
+ 20, 4);
695 blocks
[7] = bytes_to_num(raw
+ 24, 4);
699 // config for Indala (RF/32;PSK2 with RF/2;Maxblock=7)
700 PrintAndLogEx(INFO
, "Preparing to clone Indala 224bit to " _YELLOW_("%s") " raw " _GREEN_("%s")
702 , sprint_hex_inrow(raw
, raw_len
)
709 encodeHeden2L(raw
, cardnumber
);
713 PrintAndLogEx(INFO
, "Using Indala 26b FC " _GREEN_("%u") " CN " _GREEN_("%u"), fc
, cn
);
715 // Used with the 26bit FC/CSN
716 uint8_t *bits
= calloc(INDALA_ARR_LEN
, sizeof(uint8_t));
718 PrintAndLogEx(WARNING
, "Failed to allocate memory");
722 if (getIndalaBits(fc
, cn
, bits
) != PM3_SUCCESS
) {
723 PrintAndLogEx(ERR
, "Error with tag bitstream generation.");
728 raw
[0] = bytebits_to_byte(bits
, 8);
729 raw
[1] = bytebits_to_byte(bits
+ 8, 8);
730 raw
[2] = bytebits_to_byte(bits
+ 16, 8);
731 raw
[3] = bytebits_to_byte(bits
+ 24, 8);
732 raw
[4] = bytebits_to_byte(bits
+ 32, 8);
733 raw
[5] = bytebits_to_byte(bits
+ 40, 8);
734 raw
[6] = bytebits_to_byte(bits
+ 48, 8);
735 raw
[7] = bytebits_to_byte(bits
+ 56, 8);
741 blocks
[0] = T55x7_BITRATE_RF_32
| T55x7_MODULATION_PSK1
| (2 << T55x7_MAXBLOCK_SHIFT
);
744 blocks
[0] = T5555_FIXED
| T5555_SET_BITRATE(32) | T5555_MODULATION_PSK1
| (2 << T5555_MAXBLOCK_SHIFT
);
745 snprintf(cardtype
, sizeof(cardtype
), "Q5/T5555");
749 blocks
[0] = EM4305_INDALA_64_CONFIG_BLOCK
;
750 snprintf(cardtype
, sizeof(cardtype
), "EM4305/4469");
753 blocks
[1] = bytes_to_num(raw
, 4);
754 blocks
[2] = bytes_to_num(raw
+ 4, 4);
757 // config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2)
758 PrintAndLogEx(INFO
, "Preparing to clone Indala 64bit to " _YELLOW_("%s") " raw " _GREEN_("%s")
760 , sprint_hex_inrow(raw
, raw_len
)
764 print_blocks(blocks
, max
);
768 res
= em4x05_clone_tag(blocks
, ARRAYLEN(blocks
), 0, false);
770 res
= clone_t55xx_tag(blocks
, ARRAYLEN(blocks
));
772 PrintAndLogEx(SUCCESS
, "Done");
773 PrintAndLogEx(HINT
, "Hint: try " _YELLOW_("`lf indala reader`") " to verify");
777 static command_t CommandTable
[] = {
778 {"help", CmdHelp
, AlwaysAvailable
, "this help"},
779 {"demod", CmdIndalaDemod
, AlwaysAvailable
, "demodulate an Indala tag (PSK1) from GraphBuffer"},
780 {"altdemod", CmdIndalaDemodAlt
, AlwaysAvailable
, "alternative method to demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
781 {"reader", CmdIndalaReader
, IfPm3Lf
, "read an Indala tag from the antenna"},
782 {"clone", CmdIndalaClone
, IfPm3Lf
, "clone Indala tag to T55x7 or Q5/T5555"},
783 {"sim", CmdIndalaSim
, IfPm3Lf
, "simulate Indala tag"},
784 {NULL
, NULL
, NULL
, NULL
}
787 static int CmdHelp(const char *Cmd
) {
788 (void)Cmd
; // Cmd is not used so far
789 CmdsHelp(CommandTable
);
793 int CmdLFINDALA(const char *Cmd
) {
794 clearCommandBuffer();
795 return CmdsParse(CommandTable
, Cmd
);
798 int getIndalaBits(uint8_t fc
, uint16_t cn
, uint8_t *bits
) {
800 // is there a preamble?
806 bits
[57] = ((fc
>> 7) & 1); // b8
807 bits
[49] = ((fc
>> 6) & 1); // b7
808 bits
[44] = ((fc
>> 5) & 1); // b6
809 bits
[47] = ((fc
>> 4) & 1); // b5
810 bits
[48] = ((fc
>> 3) & 1); // b4
811 bits
[53] = ((fc
>> 2) & 1); // b3
812 bits
[39] = ((fc
>> 1) & 1); // b2
813 bits
[58] = (fc
& 1); // b1
816 bits
[42] = ((cn
>> 15) & 1); // b16
817 bits
[45] = ((cn
>> 14) & 1); // b15 - c
818 bits
[43] = ((cn
>> 13) & 1); // b14
819 bits
[40] = ((cn
>> 12) & 1); // b13 - c
820 bits
[52] = ((cn
>> 11) & 1); // b12
821 bits
[36] = ((cn
>> 10) & 1); // b11
822 bits
[35] = ((cn
>> 9) & 1); // b10 - c
823 bits
[51] = ((cn
>> 8) & 1); // b9 - c
824 bits
[46] = ((cn
>> 7) & 1); // b8
825 bits
[33] = ((cn
>> 6) & 1); // b7 - c
826 bits
[37] = ((cn
>> 5) & 1); // b6 - c
827 bits
[54] = ((cn
>> 4) & 1); // b5
828 bits
[56] = ((cn
>> 3) & 1); // b4
829 bits
[59] = ((cn
>> 2) & 1); // b3 - c
830 bits
[50] = ((cn
>> 1) & 1); // b2
831 bits
[41] = (cn
& 1); // b1 - c
835 //sum(y2, y4, y7, y8, y10, y11, y14, y16
836 chk
+= ((cn
>> 14) & 1); //y2 == 75 - 30 = 45
837 chk
+= ((cn
>> 12) & 1); //y4 == 70 - 30 = 40
838 chk
+= ((cn
>> 9) & 1); //y7 == 65 - 30 = 35
839 chk
+= ((cn
>> 8) & 1); //y8 == 81 - 30 = 51
840 chk
+= ((cn
>> 6) & 1); //y10 == 63 - 30 = 33
841 chk
+= ((cn
>> 5) & 1); //y11 == 67 - 30 = 37
842 chk
+= ((cn
>> 2) & 1); //y14 == 89 - 30 = 59
843 chk
+= (cn
& 1); //y16 == 71 - 30 = 41
845 if ((chk
& 1) == 0) {
854 bits
[34] = 1; // p1 64 - 30 = 34
855 bits
[38] = 1; // p2 68 - 30 = 38
863 // redesigned by marshmellow adjusted from existing decode functions
864 // indala id decoding
865 int detectIndala(uint8_t *dest
, size_t *size
, uint8_t *invert
) {
867 uint8_t preamble64_i
[] = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
868 uint8_t preamble224_i
[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
870 size_t found_size
= *size
;
873 bool res
= preambleSearch(dest
, preamble64
, sizeof(preamble64
), &found_size
, &idx
);
875 PrintAndLogEx(DEBUG
, "DEBUG: detectindala PSK1 found 64");
880 res
= preambleSearch(dest
, preamble64_i
, sizeof(preamble64_i
), &found_size
, &idx
);
882 PrintAndLogEx(DEBUG
, "DEBUG: detectindala PSK1 found 64 inverted preamble");
889 res = preambleSearch(dest, preamble224, sizeof(preamble224), &found_size, &idx);
891 PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224");
897 res = preambleSearch(dest, preamble224_i, sizeof(preamble224_i), &found_size, &idx);
899 PrintAndLogEx(DEBUG, "DEBUG: detectindala PSK1 found 224 inverted preamble");
905 psk1TOpsk2(dest
, *size
);
906 PrintAndLogEx(DEBUG
, "DEBUG: detectindala Converting PSK1 -> PSK2");
910 res
= preambleSearch(dest
, preamble64
, sizeof(preamble64
), &found_size
, &idx
);
912 PrintAndLogEx(DEBUG
, "DEBUG: detectindala PSK2 found 64 preamble");
918 res
= preambleSearch(dest
, preamble224
, sizeof(preamble224
), &found_size
, &idx
);
920 PrintAndLogEx(DEBUG
, "DEBUG: detectindala PSK2 found 224 preamble");
926 res
= preambleSearch(dest
, preamble64_i
, sizeof(preamble64_i
), &found_size
, &idx
);
928 PrintAndLogEx(DEBUG
, "DEBUG: detectindala PSK2 found 64 inverted preamble");
934 res
= preambleSearch(dest
, preamble224_i
, sizeof(preamble224_i
), &found_size
, &idx
);
936 PrintAndLogEx(DEBUG
, "DEBUG: detectindala PSK2 found 224 inverted preamble");
946 if (*invert
&& idx
> 0) {
947 for (size_t i
= idx
- 1; i
< found_size
+ idx
+ 2; i
++) {
952 PrintAndLogEx(DEBUG
, "DEBUG: Warning - Indala had to invert bits");
958 if (found_size
< 64) {
959 PrintAndLogEx(INFO
, "DEBUG: detectindala | %zu", found_size
);
963 // 224 formats are typically PSK2 (afaik 2017 Marshmellow)
964 // note loses 1 bit at beginning of transformation...