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 Hitag support
17 //-----------------------------------------------------------------------------
18 #include "cmdlfhitag.h"
20 #include "cmdparser.h" // command_t
23 #include "commonutil.h"
24 #include "fileutils.h" // savefile
25 #include "protocols.h" // defines
26 #include "cliparser.h"
28 #include "graph.h" // MAX_GRAPH_TRACE_LEN
30 #include "cmddata.h" // setDemodBuff
31 #include "pm3_cmd.h" // return codes
32 #include "hitag2/hitag2_crypto.h"
33 #include "util_posix.h" // msclock
34 #include "cmdlfhitaghts.h"
36 static int CmdHelp(const char *Cmd
);
38 static const char *getHitagTypeStr(uint32_t uid
) {
40 uint8_t type
= (uid
>> 4) & 0xF;
63 uint8_t hitag1_CRC_check(uint8_t *d
, uint32_t nbit
) {
67 return (CRC8Hitag1Bits(d
, nbit
) == 0);
72 static size_t nbytes(size_t nbits) {
73 return (nbits / 8) + ((nbits % 8) > 0);
77 static int CmdLFHitagList(const char *Cmd
) {
78 return CmdTraceListAlias(Cmd
, "lf hitag", "hitag2");
80 uint8_t *got = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
82 PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
86 // Query for the actual size of the trace
87 PacketResponseNG resp;
88 if (!GetFromDevice(BIG_BUF, got, PM3_CMD_DATA_SIZE, 0, NULL, 0, &resp, 2500, false)) {
89 PrintAndLogEx(WARNING, "command execution time out");
94 uint16_t traceLen = resp.arg[2];
95 if (traceLen > PM3_CMD_DATA_SIZE) {
96 uint8_t *p = realloc(got, traceLen);
98 PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
103 if (!GetFromDevice(BIG_BUF, got, traceLen, 0, NULL, 0, NULL, 2500, false)) {
104 PrintAndLogEx(WARNING, "command execution time out");
110 PrintAndLogEx(NORMAL, "recorded activity (TraceLen = %d bytes):");
111 PrintAndLogEx(NORMAL, " ETU :nbits: who bytes");
112 PrintAndLogEx(NORMAL, "---------+-----+----+-----------");
116 int len = strlen(Cmd);
118 char filename[FILE_PATH_SIZE] = { 0x00 };
121 if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
123 memcpy(filename, Cmd, len);
125 if (strlen(filename) > 0) {
126 f = fopen(filename, "wb");
128 PrintAndLogEx(ERR, "Error: Could not open file [%s]", filename);
135 if (i >= traceLen) { break; }
138 int timestamp = *((uint32_t *)(got + i));
139 if (timestamp & 0x80000000) {
140 timestamp &= 0x7fffffff;
146 int parityBits = *((uint32_t *)(got + i + 4));
147 // 4 bytes of additional information...
148 // maximum of 32 additional parity bit information
151 // at each quarter bit period we can send power level (16 levels)
152 // or each half bit period in 256 levels.
154 int bits = got[i + 8];
155 int len = nbytes(got[i + 8]);
160 if (i + len > traceLen) { break;}
162 uint8_t *frame = (got + i + 9);
164 // Break and stick with current result if buffer was not completely full
165 if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
167 char line[1000] = "";
169 for (j = 0; j < len; j++) {
172 //if((parityBits >> (len - j - 1)) & 0x01) {
173 if (isResponse && (oddparity8(frame[j]) != ((parityBits >> (len - j - 1)) & 0x01))) {
174 snprintf(line + offset, sizeof(line) - offset, "%02x! ", frame[j]);
176 snprintf(line + offset, sizeof(line) - offset, "%02x ", frame[j]);
180 PrintAndLogEx(NORMAL, " +%7d: %3d: %s %s",
181 (prev < 0 ? 0 : (timestamp - prev)),
183 (isResponse ? "TAG" : " "),
187 fprintf(f, " +%7d: %3d: %s %s\n",
188 (prev < 0 ? 0 : (timestamp - prev)),
190 (isResponse ? "TAG" : " "),
200 PrintAndLogEx(NORMAL, "Recorded activity successfully written to file: %s", filename);
208 static void print_hitag2_paxton(const uint8_t *data
) {
210 // if the pwd isn't..
211 if (memcmp(data
+ 4, "\xBD\xF5\xE8\x46", 4)) {
216 uint64_t paxton_id
= 0;
218 uint64_t mask
= 0xF80000000000;
220 uint64_t bytes
= bytes_to_num(data
+ 16, 6);
222 for (int j
= 0; j
< 8; j
++) {
228 uint8_t digit
= (num
>> skip
& 0xF);
229 paxton_id
= (paxton_id
* 10) + digit
;
238 const uint8_t isocard = 0x06;
239 const uint8_t fob = 0x03;
240 const uint8_t iso_magstripe = 0x02;
243 // [=] 4/0x04 | 39 04 21 1C | 9.!. | RW | User
244 // [=] 5/0x05 | AC 3F 00 06 | .?.. | RW | User
249 strcat(formfactor
, "isocard");
253 strcat(formfactor
, "fob");
257 strcat(formfactor
, "iso magstripe");
261 snprintf(formfactor
, sizeof(formfactor
), "unk: %02x", data
[23]);
266 PrintAndLogEx(INFO
, "");
267 PrintAndLogEx(INFO
, "--- " _CYAN_("Possible de-scramble patterns") " -------------");
268 PrintAndLogEx(SUCCESS
, "Paxton id... %" PRIu64
" | 0x%" PRIx64
" ( %s )", paxton_id
, paxton_id
, formfactor
);
269 PrintAndLogEx(INFO
, "");
272 static void print_hitag2_configuration(uint32_t uid
, uint8_t config
) {
274 PrintAndLogEx(NORMAL
, "");
275 PrintAndLogEx(INFO
, "--- " _CYAN_("Tag Information") " ---------------------------");
276 PrintAndLogEx(SUCCESS
, "UID...... " _GREEN_("%08X"), uid
);
277 PrintAndLogEx(SUCCESS
, "TYPE..... " _GREEN_("%s"), getHitagTypeStr(uid
));
280 memset(msg
, 0, sizeof(msg
));
282 uint8_t bits
[8 + 1] = {0};
283 num_to_bytebits(config
, 8, bits
);
284 const char *bs
= sprint_bytebits_bin(bits
, 8);
287 // PrintAndLogEx(SUCCESS, "");
288 PrintAndLogEx(SUCCESS
, "Config... " _YELLOW_("0x%02X"), config
);
289 PrintAndLogEx(SUCCESS
, " %s", bs
);
290 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 0, 4, "RFU"));
293 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_YELLOW
, bs
, 8, 4, 1, "Crypto mode"));
295 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 4, 1, "Password mode"));
299 uint8_t foo
= ((config
& 0x6) >> 1);
302 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 5, 2, "Public mode B, Coding: biphase"));
305 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 5, 2, "Public mode A, Coding: manchester"));
308 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 5, 2, "Public mode C, Coding: biphase"));
311 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 5, 2, "Hitag 2"));
317 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 7, 1, "Biphase"));
319 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 7, 1, "Manchester"));
321 PrintAndLogEx(NORMAL
, "");
324 const char *annotation
[] = {
325 "UID", "Pwd", "Key/Pwd", "Config",
326 "User", "User", "User", "User",
327 "User", "User", "User", "User"
330 static void print_hitag2_blocks(uint8_t *d
, uint16_t n
) {
332 PrintAndLogEx(INFO
, "");
333 PrintAndLogEx(INFO
, "----------------------------------------------");
334 PrintAndLogEx(INFO
, " # | data | ascii | lck | Info");
335 PrintAndLogEx(INFO
, "--------+-------------+-------+-----+---------");
337 uint8_t config
= d
[HITAG2_CONFIG_OFFSET
];
338 uint8_t blocks
= (n
/ HITAG_BLOCK_SIZE
);
340 for (uint8_t i
= 0; i
< blocks
; ++i
) {
342 char lckstr
[20] = {0};
343 sprintf(lckstr
, " ");
347 sprintf(lckstr
, "%s", _RED_("L "));
351 sprintf(lckstr
, "%s", _RED_("L "));
353 sprintf(lckstr
, "%s", _GREEN_("RW"));
359 sprintf(lckstr
, "%s", _RED_("L "));
361 sprintf(lckstr
, "%s", _RED_("R "));
364 sprintf(lckstr
, "%s", _GREEN_("RW"));
370 sprintf(lckstr
, "%s", _RED_("R "));
371 //. Configuration byte and password tag " _RED_("FIXED / IRREVERSIBLE"));
373 sprintf(lckstr
, "%s", _GREEN_("RW"));
379 sprintf(lckstr
, "%s", _RED_("R "));
381 sprintf(lckstr
, "%s", _GREEN_("RW"));
387 sprintf(lckstr
, "%s", _RED_("R "));
389 sprintf(lckstr
, "%s", _GREEN_("RW"));
396 PrintAndLogEx(INFO
, "%2d/0x%02X | %s| %s | %s | %s"
399 , sprint_hex(d
+ (i
* HITAG_BLOCK_SIZE
), HITAG_BLOCK_SIZE
)
400 , sprint_ascii(d
+ (i
* HITAG_BLOCK_SIZE
), HITAG_BLOCK_SIZE
)
405 PrintAndLogEx(INFO
, "--------+-------------+-------+-----+---------");
406 PrintAndLogEx(INFO
, " "_RED_("L") " = Locked, "_GREEN_("RW") " = Read Write, R = Read Only");
407 PrintAndLogEx(INFO
, " FI = Fixed / Irreversible");
408 PrintAndLogEx(INFO
, "----------------------------------------------");
411 // Annotate HITAG protocol
412 void annotateHitag1(char *exp
, size_t size
, const uint8_t *cmd
, uint8_t cmdsize
, bool is_response
) {
420 STATE_START_ENCRYPTED
,
424 uint64_t cipher_state
;
431 void annotateHitag2_init(void) {
432 _ht2state
.state
= STATE_HALT
;
434 _ht2state
.cipher_state
= 0;
435 _ht2state
.plainlen
= 0;
436 memset(_ht2state
.plain
, 0, sizeof(_ht2state
.plain
));
439 static void rev_msb_array(uint8_t *d
, uint8_t n
) {
440 for (uint8_t i
= 0 ; i
< n
; i
++) {
441 d
[i
] = reflect8(d
[i
]);
445 // param nrar must be 8 bytes
446 static bool ht2_check_cryptokeys(const uint64_t *keys
, const uint32_t keycount
, const uint8_t *nrar
) {
448 if (keys
== NULL
|| keycount
== 0 || nrar
== NULL
) {
452 uint32_t iv
= REV32((nrar
[3] << 24) + (nrar
[2] << 16) + (nrar
[1] << 8) + nrar
[0]);
453 uint32_t ar
= (nrar
[4] << 24) + (nrar
[5] << 16) + (nrar
[6] << 8) + nrar
[7];
456 for (uint32_t i
= 0; i
< keycount
; i
++) {
458 uint64_t key
= keys
[i
];
463 ht2_hitag2_init_ex(&hs2
, key
, _ht2state
.uid
, iv
);
465 uint32_t tbits
= ht2_hitag2_nstep(&hs2
, 32);
466 if ((ar
^ tbits
) == 0xFFFFFFFF) {
467 _ht2state
.found_key
= true;
476 static int ht2_check_dictionary(uint32_t key_count
, uint8_t *keys
, uint8_t keylen
, uint32_t *found_idx
) {
478 lf_hitag_data_t packet
;
479 memset(&packet
, 0, sizeof(packet
));
481 uint8_t *pkeys
= keys
;
483 while (key_count
--) {
486 packet
.cmd
= RHT2F_PASSWORD
;
487 memcpy(packet
.pwd
, pkeys
, keylen
);
489 packet
.cmd
= RHT2F_CRYPTO
;
490 memcpy(packet
.key
, pkeys
, keylen
);
495 clearCommandBuffer();
496 SendCommandNG(CMD_LF_HITAG_READER
, (uint8_t *)&packet
, sizeof(packet
));
497 PacketResponseNG resp
;
498 if (WaitForResponseTimeout(CMD_LF_HITAG_READER
, &resp
, 2000) == false) {
499 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
500 SendCommandNG(CMD_BREAK_LOOP
, NULL
, 0);
504 if (resp
.status
!= PM3_SUCCESS
) {
505 *found_idx
= *found_idx
+ 1;
514 bool hitag2_get_plain(uint8_t *plain
, uint8_t *plen
) {
515 if (_ht2state
.state
== STATE_ENCRYPTED
|| _ht2state
.state
== STATE_START_ENCRYPTED
) {
516 if (_ht2state
.found_key
) {
517 *plen
= _ht2state
.plainlen
;
518 memcpy(plain
, _ht2state
.plain
, _ht2state
.plainlen
);
526 #define HITAG2_BINSTR_START_AUTH "11000" // get UID and/or start the authentication process
527 #define HITAG2_BINSTR_READ_PAGE "11" // read page after auth
528 #define HITAG2_BINSTR_READ_PAGE_INVERTED "01" // as read page but all bits inverted
529 #define HITAG2_BINSTR_WRITE_PAGE "10" // write page after auth
530 #define HITAG2_BINSTR_HALT "00" // silence currently authenticated tag
532 static uint8_t hitag2_get_page(const char *bs
) {
533 if ((memcmp(bs
+ 2, "000", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "111", 3) == 0)) {
536 if ((memcmp(bs
+ 2, "001", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "110", 3) == 0)) {
539 if ((memcmp(bs
+ 2, "010", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "101", 3) == 0)) {
542 if ((memcmp(bs
+ 2, "011", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "100", 3) == 0)) {
545 if ((memcmp(bs
+ 2, "100", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "011", 3) == 0)) {
548 if ((memcmp(bs
+ 2, "101", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "010", 3) == 0)) {
551 if ((memcmp(bs
+ 2, "110", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "001", 3) == 0)) {
554 if ((memcmp(bs
+ 2, "111", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "000", 3) == 0)) {
560 void hitag2_annotate_plain(char *exp
, size_t size
, const uint8_t *cmd
, uint8_t cmdsize
, uint8_t bits
) {
566 char *binstr
= (char *)calloc((cmdsize
* 8) + 1, sizeof(uint8_t));
567 if (binstr
== NULL
) {
571 bytes_2_binstr(binstr
, cmd
, cmdsize
);
573 size_t bn
= strlen(binstr
);
577 } else if (cmdsize
> 1) {
578 bn
= ((cmdsize
- 1) * 8) + bits
;
584 snprintf(exp
, size
, " ");
588 if (memcmp(binstr
, HITAG2_BINSTR_HALT
, 2) == 0) {
589 snprintf(exp
, size
, " ");
593 uint8_t page
= hitag2_get_page(binstr
);
595 if (memcmp(binstr
, HITAG2_BINSTR_READ_PAGE
, 2) == 0) {
596 snprintf(exp
, size
, "READ PAGE (" _MAGENTA_("%u") ")", page
);
600 if (memcmp(binstr
, HITAG2_BINSTR_READ_PAGE_INVERTED
, 2) == 0) {
601 snprintf(exp
, size
, "READ PAGE INV (" _MAGENTA_("%u") ")", page
);
605 if (memcmp(binstr
, HITAG2_BINSTR_WRITE_PAGE
, 2) == 0) {
606 snprintf(exp
, size
, "WRITE PAGE (" _MAGENTA_("%u") ")", page
);
611 case 32: { // password or data
612 snprintf(exp
, size
, " ");
615 case 64: { // crypto handshake
616 snprintf(exp
, size
, " ");
620 snprintf(exp
, size
, " ");
627 void annotateHitag2(char *exp
, size_t size
, const uint8_t *cmd
, uint8_t cmdsize
, uint8_t bits
, bool is_response
, const uint64_t *keys
, uint32_t keycount
, bool isdecrypted
) {
633 char *binstr
= (char *)calloc((cmdsize
* 8) + 1, sizeof(uint8_t));
634 if (binstr
== NULL
) {
638 bytes_2_binstr(binstr
, cmd
, cmdsize
);
640 size_t bn
= strlen(binstr
);
644 } else if (cmdsize
> 1) {
645 bn
= ((cmdsize
- 1) * 8) + bits
;
649 memcpy(_ht2state
.plain
, cmd
, cmdsize
);
650 _ht2state
.plainlen
= cmdsize
;
652 if (_ht2state
.state
== STATE_ENCRYPTED
|| _ht2state
.state
== STATE_START_ENCRYPTED
) {
654 if (_ht2state
.found_key
&& isdecrypted
== false) {
655 ht2_hitag2_cipher_transcrypt(&_ht2state
.cipher_state
, _ht2state
.plain
, bn
/ 8, bn
% 8);
659 // 11000 AUTH only one with 5 bits. cmdsize 1
662 annotateHitag2_init();
664 if (memcmp(binstr
, HITAG2_BINSTR_START_AUTH
, 5) == 0) {
665 snprintf(exp
, size
, "START AUTH");
666 _ht2state
.state
= STATE_START_AUTH
;
668 snprintf(exp
, size
, "?");
674 if (isdecrypted
== false && _ht2state
.state
== STATE_ENCRYPTED
) {
675 snprintf(exp
, size
, "ENC CMD");
679 if (memcmp(binstr
, HITAG2_BINSTR_HALT
, 2) == 0) {
680 snprintf(exp
, size
, "HALT");
681 _ht2state
.state
= STATE_HALT
;
685 uint8_t page
= hitag2_get_page(binstr
);
687 if (memcmp(binstr
, HITAG2_BINSTR_READ_PAGE
, 2) == 0) {
688 snprintf(exp
, size
, "READ PAGE (" _MAGENTA_("%u") ")", page
);
692 if (memcmp(binstr
, HITAG2_BINSTR_READ_PAGE_INVERTED
, 2) == 0) {
693 snprintf(exp
, size
, "READ PAGE INV (" _MAGENTA_("%u") ")", page
);
697 if (memcmp(binstr
, HITAG2_BINSTR_WRITE_PAGE
, 2) == 0) {
698 snprintf(exp
, size
, "WRITE PAGE (" _MAGENTA_("%u") ")", page
);
704 case 32: { // password or data
705 if (_ht2state
.state
== STATE_START_AUTH
) {
707 snprintf(exp
, size
, "UID");
710 rev_msb_array(uid
, 4);
711 _ht2state
.uid
= MemLeToUint4byte(uid
);
713 snprintf(exp
, size
, "PWD: " _GREEN_("0x%02X%02X%02X%02X"), cmd
[0], cmd
[1], cmd
[2], cmd
[3]);
714 _ht2state
.state
= STATE_AUTH
;
719 if (_ht2state
.state
== STATE_AUTH
) {
720 snprintf(exp
, size
, "DATA");
724 if (_ht2state
.state
== STATE_START_ENCRYPTED
) {
725 snprintf(exp
, size
, "At");
726 _ht2state
.state
= STATE_ENCRYPTED
;
730 if (isdecrypted
== false && _ht2state
.state
== STATE_ENCRYPTED
) {
731 snprintf(exp
, size
, "ENC DATA");
736 case 64: { // crypto handshake
738 if (_ht2state
.state
== STATE_START_AUTH
) {
739 _ht2state
.state
= STATE_START_ENCRYPTED
;
741 // need to be called with filename...
742 if (ht2_check_cryptokeys(keys
, keycount
, cmd
)) {
744 _ht2state
.cipher_state
= ht2_hitag2_init(
747 REV32((cmd
[3] << 24) + (cmd
[2] << 16) + (cmd
[1] << 8) + cmd
[0])
749 ht2_hitag2_cipher_transcrypt(&_ht2state
.cipher_state
, _ht2state
.plain
+ 4, 4, 0);
751 uint64_t key
= REV64(_ht2state
.key
);
753 snprintf(exp
, size
, "Nr Ar " _WHITE_("( ") _GREEN_("%012" PRIx64
) " )", key
);
756 snprintf(exp
, size
, "AUTH: Nr Ar");
759 snprintf(exp
, size
, "AUTH: Nr Ar");
764 snprintf(exp
, size
, "?");
765 _ht2state
.state
= STATE_HALT
;
773 void annotateHitagS(char *exp
, size_t size
, const uint8_t *cmd
, uint8_t cmdsize
, bool is_response
) {
776 static const char *identify_transponder_hitag2(uint32_t uid
) {
780 return "IMMO Key emulator";
792 return "CN3 Tango Key emulator";
797 static bool getHitag2Uid(uint32_t *uid
) {
799 lf_hitag_data_t packet
;
800 memset(&packet
, 0, sizeof(packet
));
801 packet
.cmd
= RHT2F_UID_ONLY
;
803 clearCommandBuffer();
804 SendCommandNG(CMD_LF_HITAG_READER
, (uint8_t *) &packet
, sizeof(packet
));
805 PacketResponseNG resp
;
806 if (WaitForResponseTimeout(CMD_LF_HITAG_READER
, &resp
, 1500) == false) {
807 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
811 if (resp
.status
!= PM3_SUCCESS
) {
812 PrintAndLogEx(DEBUG
, "DEBUG: Error - failed getting UID");
817 *uid
= bytes_to_num(resp
.data
.asBytes
, HITAG_UID_SIZE
);
822 static int CmdLFHitagInfo(const char *Cmd
) {
823 CLIParserContext
*ctx
;
824 CLIParserInit(&ctx
, "lf hitag info",
825 "Hitag 2 tag information",
833 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
838 if (getHitag2Uid(&uid
) == false) {
841 // how to determine Hitag types?
842 // need auth / pwd to get it.
843 // we could try the default key/pwd and print if successful
844 // read block3, get configuration byte.
846 // common configurations.
847 print_hitag2_configuration(uid
, 0x06); // pwd mode enabled / AM
848 // print_hitag2_configuration(uid, 0x0E); // crypto mode enabled / AM
849 // print_hitag2_configuration(uid, 0x02);
850 // print_hitag2_configuration(uid, 0x00);
851 // print_hitag2_configuration(uid, 0x04);
853 PrintAndLogEx(INFO
, "--- " _CYAN_("Fingerprint"));
854 const char *s
= identify_transponder_hitag2(uid
);
856 PrintAndLogEx(SUCCESS
, "Found... " _GREEN_("%s"), s
);
858 PrintAndLogEx(INFO
, _RED_("n/a"));
861 PrintAndLogEx(NORMAL
, "");
865 static int CmdLFHitagReader(const char *Cmd
) {
866 CLIParserContext
*ctx
;
867 CLIParserInit(&ctx
, "lf hitag reader",
868 "Act as a Hitag 2 reader. Look for Hitag 2 tags until Enter or the pm3 button is pressed\n",
870 "lf hitag reader -@ -> Continuous mode"
875 arg_lit0("@", NULL
, "continuous reader mode"),
878 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
879 bool cm
= arg_get_lit(ctx
, 1);
883 PrintAndLogEx(INFO
, "Press " _GREEN_("<Enter>") " to exit");
889 if (getHitag2Uid(&uid
)) {
890 PrintAndLogEx(SUCCESS
, "UID.... " _GREEN_("%08X"), uid
);
892 } while (cm
&& kbd_enter_pressed() == false);
897 static int CmdLFHitagRd(const char *Cmd
) {
899 CLIParserContext
*ctx
;
900 CLIParserInit(&ctx
, "lf hitag read",
901 "Read Hitag memory. It support Hitag S and Hitag 2\n\n"
903 " - default key 4D494B52 (MIKR)\n\n"
905 " - key format ISK high + ISK low\n"
906 " - default key 4F4E4D494B52 (ONMIKR)\n"
908 " lf hitag read --hts -> Hitag S, plain mode\n"
909 " lf hitag read --hts --nrar 0102030411223344 -> Hitag S, challenge mode\n"
910 " lf hitag read --hts --crypto -> Hitag S, crypto mode, def key\n"
911 " lf hitag read --hts -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n"
912 " lf hitag read --ht2 --pwd -> Hitag 2, pwd mode, def key\n"
913 " lf hitag read --ht2 -k 4D494B52 -> Hitag 2, pwd mode\n"
914 " lf hitag read --ht2 --nrar 0102030411223344 -> Hitag 2, challenge mode\n"
915 " lf hitag read --ht2 --crypto -> Hitag 2, crypto mode, def key\n"
916 " lf hitag read --ht2 -k 4F4E4D494B52 -> Hitag 2, crypto mode\n"
921 arg_lit0("s", "hts", "Hitag S"),
922 arg_lit0("2", "ht2", "Hitag 2"),
923 arg_lit0(NULL
, "pwd", "password mode"),
924 arg_str0(NULL
, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
925 arg_lit0(NULL
, "crypto", "crypto mode"),
926 arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
927 // currently pm3 fw reads all the memory anyway
928 // arg_int1("p", "page", "<dec>", "page address to write to"),
931 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
933 bool use_ht1
= false; // not yet implemented
934 bool use_hts
= arg_get_lit(ctx
, 1);
935 bool use_ht2
= arg_get_lit(ctx
, 2);
936 bool use_htm
= false; // not yet implemented
938 bool use_plain
= false;
939 bool use_pwd
= arg_get_lit(ctx
, 3);
942 int res
= CLIParamHexToBuf(arg_get_str(ctx
, 4), nrar
, sizeof(nrar
), &nalen
);
947 bool use_nrar
= nalen
> 0;
948 bool use_crypto
= arg_get_lit(ctx
, 5);
952 res
= CLIParamHexToBuf(arg_get_str(ctx
, 6), key
, sizeof(key
), &keylen
);
957 // uint32_t page = arg_get_u32_def(ctx, 6, 0);
962 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) > 1) {
963 PrintAndLogEx(ERR
, "error, specify only one Hitag type");
966 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) == 0) {
967 PrintAndLogEx(ERR
, "error, specify one Hitag type");
971 if (keylen
!= 0 && keylen
!= 4 && keylen
!= 6) {
972 PrintAndLogEx(WARNING
, "Wrong KEY len expected 0, 4 or 6, got %d", keylen
);
976 if (nalen
!= 0 && nalen
!= 8) {
977 PrintAndLogEx(WARNING
, "Wrong NR/AR len expected 0 or 8, got %d", nalen
);
988 if ((keylen
== 0) && use_pwd
) {
989 memcpy(key
, "MIKR", 4);
992 if ((keylen
== 0) && use_crypto
) {
993 memcpy(key
, "ONMIKR", 6);
998 uint8_t foo
= (use_plain
+ use_pwd
+ use_nrar
+ use_crypto
);
1000 PrintAndLogEx(WARNING
, "Specify only one authentication mode");
1002 } else if (foo
== 0) {
1006 PrintAndLogEx(WARNING
, "Specify one authentication mode");
1011 if (use_hts
&& use_pwd
) { // not sure for the other types...
1012 PrintAndLogEx(WARNING
, "Chosen Hitag type does not have Password mode");
1016 if (use_ht2
&& use_plain
) { // not sure for the other types...
1017 PrintAndLogEx(WARNING
, "Chosen Hitag type does not have Plain mode");
1021 lf_hitag_data_t packet
;
1022 memset(&packet
, 0, sizeof(packet
));
1027 pm3cmd
= CMD_LF_HITAGS_READ
;
1028 } else if (use_hts
&& use_nrar
) {
1029 pm3cmd
= CMD_LF_HITAGS_READ
;
1030 packet
.cmd
= RHTSF_CHALLENGE
;
1031 memcpy(packet
.NrAr
, nrar
, sizeof(packet
.NrAr
));
1033 } else if (use_hts
&& use_crypto
) {
1034 pm3cmd
= CMD_LF_HITAGS_READ
;
1035 packet
.cmd
= RHTSF_KEY
;
1036 memcpy(packet
.key
, key
, sizeof(packet
.key
));
1038 } else if (use_ht2
&& use_pwd
) {
1039 pm3cmd
= CMD_LF_HITAG_READER
;
1040 packet
.cmd
= RHT2F_PASSWORD
;
1041 memcpy(packet
.pwd
, key
, sizeof(packet
.pwd
));
1043 } else if (use_ht2
&& use_nrar
) {
1044 pm3cmd
= CMD_LF_HITAG_READER
;
1045 packet
.cmd
= RHT2F_AUTHENTICATE
;
1046 memcpy(packet
.NrAr
, nrar
, sizeof(packet
.NrAr
));
1047 } else if (use_ht2
&& use_crypto
) {
1049 pm3cmd
= CMD_LF_HITAG_READER
;
1050 packet
.cmd
= RHT2F_CRYPTO
;
1051 memcpy(packet
.key
, key
, sizeof(packet
.key
));
1053 PrintAndLogEx(WARNING
, "Sorry, not yet implemented");
1054 return PM3_ENOTIMPL
;
1057 clearCommandBuffer();
1058 SendCommandNG(pm3cmd
, (uint8_t *)&packet
, sizeof(packet
));
1060 PacketResponseNG resp
;
1061 if (WaitForResponseTimeout(pm3cmd
, &resp
, 2000) == false) {
1062 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
1063 SendCommandNG(CMD_BREAK_LOOP
, NULL
, 0);
1064 return PM3_ETIMEOUT
;
1067 if (resp
.status
!= PM3_SUCCESS
) {
1068 PrintAndLogEx(DEBUG
, "DEBUG: Error - hitag failed");
1076 uint8_t *data
= resp
.data
.asBytes
;
1077 uint32_t uid
= bytes_to_num(data
, HITAG_UID_SIZE
);
1078 print_hitag2_configuration(uid
, data
[HITAG_BLOCK_SIZE
* 3]);
1081 print_hitag2_blocks(data
, HITAG2_MAX_BYTE_SIZE
);
1082 print_hitag2_paxton(data
);
1084 print_hex_break(data
, HITAG_MAX_BYTE_SIZE
, HITAG_BLOCK_SIZE
);
1089 static int CmdLFHitagSCheckChallenges(const char *Cmd
) {
1091 CLIParserContext
*ctx
;
1092 CLIParserInit(&ctx
, "lf hitag cc",
1093 "Check challenges, load a file with saved hitag crypto challenges and test them all.\n"
1094 "The file should be 8 * 60 bytes long, the file extension defaults to " _YELLOW_("`.cc`") " ",
1095 "lf hitag cc -f my_hitag_challenges"
1098 void *argtable
[] = {
1100 arg_str1("f", "file", "<fn>", "filename to load ( w/o ext )"),
1103 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1106 char filename
[FILE_PATH_SIZE
] = {0};
1107 CLIParamStrToBuf(arg_get_str(ctx
, 1), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
1110 uint8_t *data
= NULL
;
1112 int res
= loadFile_safe(filename
, ".cc", (void **)&data
, &datalen
);
1113 if (res
== PM3_SUCCESS
) {
1116 PrintAndLogEx(ERR
, "Error, file length mismatch. Expected multiple of 8, got " _RED_("%zu"), datalen
);
1120 if (datalen
!= (8 * 60)) {
1121 PrintAndLogEx(ERR
, "Error, file length mismatch. Expected 480, got " _RED_("%zu"), datalen
);
1126 clearCommandBuffer();
1127 SendCommandNG(CMD_LF_HITAGS_TEST_TRACES
, data
, datalen
);
1135 static int CmdLFHitag2CheckChallenges(const char *Cmd
) {
1136 CLIParserContext
*ctx
;
1137 CLIParserInit(&ctx
, "lf hitag ta",
1138 "Test recorded authentications (replay?)",
1143 lf_hitag_data_t packet
;
1144 memset(&packet
, 0, sizeof(lf_hitag_data_t
));
1145 packet
.cmd
= RHT2F_TEST_AUTH_ATTEMPTS
;
1147 clearCommandBuffer();
1148 SendCommandNG(CMD_LF_HITAG_READER
, (uint8_t *)&packet
, sizeof(packet
));
1149 PacketResponseNG resp
;
1150 if (WaitForResponseTimeout(CMD_LF_HITAG_READER
, &resp
, 2000) == false) {
1151 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
1152 return PM3_ETIMEOUT
;
1154 if (resp
.status
!= PM3_SUCCESS
) {
1155 PrintAndLogEx(DEBUG
, "DEBUG: Error - hitag failed");
1159 // FIXME: doegox: not sure what this fct does and what it returns...
1163 static int CmdLFHitagWriter(const char *Cmd
) {
1164 CLIParserContext
*ctx
;
1165 CLIParserInit(&ctx
, "lf hitag wrbl",
1166 "Write a page in Hitag memory. It support HitagS and Hitag 2\n"
1168 " - default key 4D494B52 (MIKR)\n\n"
1170 " - key format ISK high + ISK low\n"
1171 " - default key 4F4E4D494B52 (ONMIKR)\n"
1173 " lf hitag wrbl --hts -p 6 -d 01020304 -> HitagS, plain mode\n"
1174 " lf hitag wrbl --hts -p 6 -d 01020304 --nrar 0102030411223344 -> HitagS, challenge mode\n"
1175 " lf hitag wrbl --hts -p 6 -d 01020304 --crypto -> HitagS, crypto mode, def key\n"
1176 " lf hitag wrbl --hts -p 6 -d 01020304 -k 4F4E4D494B52 -> HitagS, crypto mode\n\n"
1177 " lf hitag wrbl --ht2 -p 6 -d 01020304 --pwd -> Hitag 2, pwd mode, def key\n"
1178 " lf hitag wrbl --ht2 -p 6 -d 01020304 -k 4D494B52 -> Hitag 2, pwd mode\n"
1179 " lf hitag wrbl --ht2 -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag 2, challenge mode\n"
1180 " lf hitag wrbl --ht2 -p 6 -d 01020304 --crypto -> Hitag 2, crypto mode, def key\n"
1181 " lf hitag wrbl --ht2 -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag 2, crypto mode\n"
1184 void *argtable
[] = {
1186 arg_lit0("s", "hts", "Hitag S"),
1187 arg_lit0("2", "ht2", "Hitag 2"),
1188 arg_lit0(NULL
, "pwd", "password mode"),
1189 arg_str0(NULL
, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
1190 arg_lit0(NULL
, "crypto", "crypto mode"),
1191 arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
1192 arg_int1("p", "page", "<dec>", "page address to write to"),
1193 arg_str1("d", "data", "<hex>", "data, 4 hex bytes"),
1196 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
1198 bool use_ht1
= false; // not yet implemented
1199 bool use_hts
= arg_get_lit(ctx
, 1);
1200 bool use_ht2
= arg_get_lit(ctx
, 2);
1201 bool use_htm
= false; // not yet implemented
1203 bool use_plain
= false;
1204 bool use_pwd
= arg_get_lit(ctx
, 3);
1207 int res
= CLIParamHexToBuf(arg_get_str(ctx
, 4), nrar
, sizeof(nrar
), &nalen
);
1212 bool use_nrar
= nalen
> 0;
1213 bool use_crypto
= arg_get_lit(ctx
, 5);
1217 res
= CLIParamHexToBuf(arg_get_str(ctx
, 6), key
, sizeof(key
), &keylen
);
1223 int page
= arg_get_int_def(ctx
, 7, 0);
1227 res
= CLIParamHexToBuf(arg_get_str(ctx
, 8), data
, sizeof(data
), &dlen
);
1236 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) > 1) {
1237 PrintAndLogEx(ERR
, "error, specify only one Hitag type");
1240 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) == 0) {
1241 PrintAndLogEx(ERR
, "error, specify one Hitag type");
1245 if (keylen
!= 0 && keylen
!= 4 && keylen
!= 6) {
1246 PrintAndLogEx(WARNING
, "Wrong KEY len expected 0, 4 or 6, got %d", keylen
);
1250 if (dlen
!= sizeof(data
)) {
1251 PrintAndLogEx(WARNING
, "Wrong DATA len expected 4, got %d", dlen
);
1255 if (nalen
!= 0 && nalen
!= 8) {
1256 PrintAndLogEx(WARNING
, "Wrong NR/AR len expected 0 or 8, got %d", nalen
);
1267 if ((keylen
== 0) && use_pwd
) {
1268 memcpy(key
, "MIKR", 4);
1271 if ((keylen
== 0) && use_crypto
) {
1272 memcpy(key
, "ONMIKR", 6);
1277 uint8_t foo
= (use_plain
+ use_pwd
+ use_nrar
+ use_crypto
);
1279 PrintAndLogEx(WARNING
, "Specify only one authentication mode");
1281 } else if (foo
== 0) {
1285 PrintAndLogEx(WARNING
, "Specify one authentication mode");
1290 if (use_hts
&& use_pwd
) { // not sure for the other types...
1291 PrintAndLogEx(WARNING
, "Chosen Hitag type does not have Password mode");
1295 if (use_ht2
&& use_plain
) { // not sure for the other types...
1296 PrintAndLogEx(WARNING
, "Chosen Hitag type does not have Plain mode");
1300 lf_hitag_data_t packet
;
1301 memset(&packet
, 0, sizeof(packet
));
1303 if (use_hts
&& use_plain
) {
1304 packet
.cmd
= WHTSF_PLAIN
;
1306 memcpy(packet
.data
, data
, sizeof(data
));
1308 PrintAndLogEx(INFO
, "Write to " _YELLOW_("Hitag S") " in Plain mode");
1310 } else if (use_hts
&& use_nrar
) {
1311 packet
.cmd
= WHTSF_CHALLENGE
;
1312 memcpy(packet
.NrAr
, nrar
, sizeof(packet
.NrAr
));
1313 memcpy(packet
.data
, data
, sizeof(data
));
1314 // iceman: No page in Hitag S ?
1315 PrintAndLogEx(INFO
, "Authenticating to " _YELLOW_("Hitag S") " in Challenge mode");
1317 } else if (use_hts
&& use_crypto
) {
1318 packet
.cmd
= WHTSF_KEY
;
1319 memcpy(packet
.key
, key
, sizeof(packet
.key
));
1320 memcpy(packet
.data
, data
, sizeof(data
));
1321 // iceman: No page in Hitag S ?
1322 PrintAndLogEx(INFO
, "Authenticating to " _YELLOW_("Hitag S") " in Crypto mode");
1324 } else if (use_ht2
&& use_pwd
) {
1325 packet
.cmd
= WHT2F_PASSWORD
;
1327 memcpy(packet
.pwd
, key
, sizeof(packet
.pwd
));
1328 memcpy(packet
.data
, data
, sizeof(data
));
1329 PrintAndLogEx(INFO
, "Authenticating to " _YELLOW_("Hitag 2") " in Password mode");
1331 } else if (use_ht2
&& use_crypto
) {
1332 packet
.cmd
= WHT2F_CRYPTO
;
1334 memcpy(packet
.key
, key
, sizeof(packet
.key
));
1335 memcpy(packet
.data
, data
, sizeof(data
));
1336 PrintAndLogEx(INFO
, "Authenticating to " _YELLOW_("Hitag 2") " in Crypto mode");
1339 PrintAndLogEx(WARNING
, "Sorry, not yet implemented");
1340 return PM3_ENOTIMPL
;
1343 clearCommandBuffer();
1346 SendCommandNG(CMD_LF_HITAG2_WRITE
, (uint8_t *)&packet
, sizeof(packet
));
1347 PacketResponseNG resp
;
1348 if (WaitForResponseTimeout(CMD_LF_HITAG2_WRITE
, &resp
, 4000) == false) {
1349 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
1350 return PM3_ETIMEOUT
;
1353 if (resp
.status
== PM3_ETEAROFF
) {
1354 PrintAndLogEx(INFO
, "Writing tear off triggered");
1358 if (resp
.status
!= PM3_SUCCESS
) {
1359 PrintAndLogEx(FAILED
, "Write ( " _RED_("fail") " )");
1365 SendCommandNG(CMD_LF_HITAGS_WRITE
, (uint8_t *)&packet
, sizeof(packet
));
1366 PacketResponseNG resp
;
1367 if (WaitForResponseTimeout(CMD_LF_HITAGS_WRITE
, &resp
, 4000) == false) {
1368 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
1369 return PM3_ETIMEOUT
;
1372 if (resp
.status
== PM3_ETEAROFF
) {
1373 PrintAndLogEx(INFO
, "Writing tear off triggered");
1377 if (resp
.status
!= PM3_SUCCESS
) {
1378 PrintAndLogEx(FAILED
, "Write ( " _RED_("fail") " )");
1383 PrintAndLogEx(SUCCESS
, "Write ( " _GREEN_("ok") " )");
1387 static int CmdLFHitag2Dump(const char *Cmd
) {
1389 CLIParserContext
*ctx
;
1390 CLIParserInit(&ctx
, "lf hitag dump",
1391 "Read all Hitag 2 card memory and save to file\n"
1392 "Crypto mode key format: ISK high + ISK low, 4F4E4D494B52 (ONMIKR)\n"
1393 "Password mode, default key 4D494B52 (MIKR)\n",
1394 "lf hitag dump --pwd -> use def pwd\n"
1395 "lf hitag dump -k 4D494B52 -> pwd mode\n"
1396 "lf hitag dump --crypto -> use def crypto\n"
1397 "lf hitag dump -k 4F4E4D494B52 -> crypto mode\n"
1398 "lf hitag dump --nrar 0102030411223344\n"
1401 void *argtable
[] = {
1403 arg_lit0(NULL
, "pwd", "password mode"),
1404 arg_str0(NULL
, "nrar", "<hex>", "nonce / answer reader, 8 hex bytes"),
1405 arg_lit0(NULL
, "crypto", "crypto mode"),
1406 arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
1407 arg_str0("f", "file", "<fn>", "specify file name"),
1408 arg_lit0(NULL
, "ns", "no save to file"),
1411 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
1413 bool use_ht1
= false; // not yet implemented
1414 bool use_hts
= false; // not yet implemented
1415 bool use_ht2
= true;
1416 bool use_htm
= false; // not yet implemented
1418 bool use_plain
= false;
1419 bool use_pwd
= arg_get_lit(ctx
, 1);
1422 int res
= CLIParamHexToBuf(arg_get_str(ctx
, 2), nrar
, sizeof(nrar
), &nalen
);
1427 bool use_nrar
= nalen
> 0;
1428 bool use_crypto
= arg_get_lit(ctx
, 3);
1430 uint8_t key
[HITAG_NRAR_SIZE
];
1432 res
= CLIParamHexToBuf(arg_get_str(ctx
, 4), key
, sizeof(key
), &keylen
);
1439 char filename
[FILE_PATH_SIZE
] = {0};
1440 CLIParamStrToBuf(arg_get_str(ctx
, 5), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
1442 bool nosave
= arg_get_lit(ctx
, 6);
1446 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) > 1) {
1447 PrintAndLogEx(ERR
, "error, specify only one Hitag type");
1450 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) == 0) {
1451 PrintAndLogEx(ERR
, "error, specify one Hitag type");
1456 keylen
!= HITAG_PASSWORD_SIZE
&&
1457 keylen
!= HITAG_CRYPTOKEY_SIZE
&&
1458 keylen
!= HITAG_NRAR_SIZE
) {
1459 PrintAndLogEx(WARNING
, "Wrong KEY len expected (0,4,6,8) got %d", keylen
);
1464 if (keylen
== HITAG_PASSWORD_SIZE
) {
1467 if (keylen
== HITAG_CRYPTOKEY_SIZE
) {
1470 if (keylen
== HITAG_NRAR_SIZE
) {
1472 memcpy(nrar
, key
, sizeof(nrar
));
1475 // Set default key / pwd
1476 if ((keylen
== 0) && use_pwd
) {
1477 memcpy(key
, "MIKR", HITAG_PASSWORD_SIZE
);
1478 keylen
= HITAG_PASSWORD_SIZE
;
1480 if ((keylen
== 0) && use_crypto
) {
1481 memcpy(key
, "ONMIKR", HITAG_CRYPTOKEY_SIZE
);
1482 keylen
= HITAG_CRYPTOKEY_SIZE
;
1486 uint8_t foo
= (use_plain
+ use_pwd
+ use_nrar
+ use_crypto
);
1488 PrintAndLogEx(WARNING
, "Specify only one authentication mode");
1490 } else if (foo
== 0) {
1494 PrintAndLogEx(WARNING
, "Specify one authentication mode");
1499 if (use_hts
&& use_pwd
) { // not sure for the other types...
1500 PrintAndLogEx(WARNING
, "Chosen Hitag type does not have Password mode");
1504 if (use_ht2
&& use_plain
) { // not sure for the other types...
1505 PrintAndLogEx(WARNING
, "Chosen Hitag type does not have Plain mode");
1511 PacketResponseNG resp
;
1512 uint8_t *data
= NULL
;
1514 lf_hitag_data_t packet
;
1515 memset(&packet
, 0, sizeof(packet
));
1517 if (use_ht2
&& use_pwd
) {
1518 packet
.cmd
= RHT2F_PASSWORD
;
1519 memcpy(packet
.pwd
, key
, sizeof(packet
.pwd
));
1520 PrintAndLogEx(INFO
, "Authenticating to " _YELLOW_("Hitag 2") " in Password mode");
1522 } else if (use_ht2
&& use_crypto
) {
1523 packet
.cmd
= RHT2F_CRYPTO
;
1524 memcpy(packet
.key
, key
, sizeof(packet
.key
));
1525 PrintAndLogEx(INFO
, "Authenticating to " _YELLOW_("Hitag 2") " in Crypto mode");
1527 } else if (use_ht2
&& use_nrar
) {
1530 memcpy(packet
.NrAr
, nrar
, sizeof(packet
.NrAr
));
1532 PrintAndLogEx(INFO
, _YELLOW_("Hitag 2") " - Challenge mode (NrAr)");
1534 uint64_t t1
= msclock();
1536 clearCommandBuffer();
1537 SendCommandNG(CMD_LF_HITAG2_CRACK
, (uint8_t *) &packet
, sizeof(packet
));
1540 uint8_t attempt
= 30;
1543 PrintAndLogEx(INPLACE
, "Attack 1 running...");
1546 if (WaitForResponseTimeout(CMD_LF_HITAG2_CRACK
, &resp
, 1000) == false) {
1551 lf_hitag_crack_response_t
*payload
= (lf_hitag_crack_response_t
*)resp
.data
.asBytes
;
1553 if (resp
.status
== PM3_SUCCESS
) {
1554 PrintAndLogEx(NORMAL
, " ( %s )", _GREEN_("ok"));
1555 data
= payload
->data
;
1557 t1
= msclock() - t1
;
1558 PrintAndLogEx(SUCCESS
, "\ntime " _YELLOW_("%.0f") " seconds\n", (float)t1
/ 1000.0);
1563 switch (payload
->status
) {
1565 PrintAndLogEx(NORMAL
, "");
1566 PrintAndLogEx(FAILED
, "Couldn't select tag!");
1570 PrintAndLogEx(NORMAL
, "");
1571 PrintAndLogEx(FAILED
, "Cannot find a valid encrypted command!");
1575 PrintAndLogEx(NORMAL
, "");
1576 PrintAndLogEx(FAILED
, "Cannot find encrypted 'read page0' command!");
1580 PrintAndLogEx(NORMAL
, "");
1581 PrintAndLogEx(FAILED
, "Partial data extraction!");
1589 PrintAndLogEx(NORMAL
, "");
1590 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
1594 t1
= msclock() - t1
;
1595 PrintAndLogEx(SUCCESS
, "\ntime " _YELLOW_("%.0f") " seconds\n", (float)t1
/ 1000.0);
1600 PrintAndLogEx(WARNING
, "Sorry, not yet implemented");
1601 return PM3_ENOTIMPL
;
1604 clearCommandBuffer();
1605 SendCommandNG(CMD_LF_HITAG_READER
, (uint8_t *) &packet
, sizeof(packet
));
1607 if (WaitForResponseTimeout(CMD_LF_HITAG_READER
, &resp
, 5000) == false) {
1608 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
1609 return PM3_ETIMEOUT
;
1611 if (resp
.status
!= PM3_SUCCESS
) {
1612 PrintAndLogEx(DEBUG
, "DEBUG: Error - hitag failed");
1616 data
= resp
.data
.asBytes
;
1622 uid
= bytes_to_num(data
, HITAG_UID_SIZE
);
1625 print_hitag2_configuration(uid
, data
[HITAG_BLOCK_SIZE
* 3]);
1626 print_hitag2_blocks(data
, HITAG2_MAX_BYTE_SIZE
);
1627 print_hitag2_paxton(data
);
1629 PrintAndLogEx(INFO
, "No memory printing available");
1633 PrintAndLogEx(NORMAL
, "");
1634 PrintAndLogEx(INFO
, "Called with no save option");
1635 PrintAndLogEx(NORMAL
, "");
1640 char *fptr
= filename
;
1641 fptr
+= snprintf(filename
, sizeof(filename
), "lf-hitag-");
1642 FillFileNameByUID(fptr
, data
, "-dump", HITAG_UID_SIZE
);
1645 pm3_save_dump(filename
, data
, HITAG2_MAX_BYTE_SIZE
, jsfHitag
);
1649 static int CmdLFHitagView(const char *Cmd
) {
1651 CLIParserContext
*ctx
;
1652 CLIParserInit(&ctx
, "lf hitag view",
1653 "Print a HITAG dump file (bin/eml/json)",
1654 "lf hitag view -f lf-hitag-01020304-dump.bin"
1656 void *argtable
[] = {
1658 arg_str1("f", "file", "<fn>", "Specify a filename for dump file"),
1659 arg_lit0("v", "verbose", "Verbose output"),
1662 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
1664 char filename
[FILE_PATH_SIZE
];
1665 CLIParamStrToBuf(arg_get_str(ctx
, 1), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
1666 bool verbose
= arg_get_lit(ctx
, 2);
1670 uint8_t *dump
= NULL
;
1671 size_t bytes_read
= 0;
1672 int res
= pm3_load_dump(filename
, (void **)&dump
, &bytes_read
, HITAG2_MAX_BYTE_SIZE
);
1673 if (res
!= PM3_SUCCESS
) {
1677 if (bytes_read
< HITAG2_MAX_BYTE_SIZE
) {
1678 PrintAndLogEx(ERR
, "Error, dump file is too small");
1685 uint8_t config
= dump
[HITAG2_CONFIG_OFFSET
];
1686 uint32_t uid
= bytes_to_num(dump
, HITAG_UID_SIZE
);
1687 print_hitag2_configuration(uid
, config
);
1688 print_hitag2_paxton(dump
);
1690 print_hitag2_blocks(dump
, HITAG2_MAX_BYTE_SIZE
);
1695 static int CmdLFHitagEload(const char *Cmd
) {
1696 CLIParserContext
*ctx
;
1697 CLIParserInit(&ctx
, "lf hitag eload",
1698 "Loads hitag tag dump into emulator memory on device",
1699 "lf hitag eload -2 -f lf-hitag-11223344-dump.bin\n"
1701 void *argtable
[] = {
1703 arg_str1("f", "file", "<fn>", "Specify dump filename"),
1704 arg_lit0("1", "ht1", "Card type Hitag 1"),
1705 arg_lit0("2", "ht2", "Card type Hitag 2"),
1706 arg_lit0("s", "hts", "Card type Hitag S"),
1707 arg_lit0("m", "htm", "Card type Hitag \xce\xbc"), // μ
1710 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
1713 char filename
[FILE_PATH_SIZE
] = {0};
1714 CLIParamStrToBuf(arg_get_str(ctx
, 1), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
1716 bool use_ht1
= arg_get_lit(ctx
, 2);
1717 bool use_ht2
= arg_get_lit(ctx
, 3);
1718 bool use_hts
= arg_get_lit(ctx
, 4);
1719 bool use_htm
= arg_get_lit(ctx
, 5);
1722 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) > 1) {
1723 PrintAndLogEx(ERR
, "error, specify only one Hitag type");
1726 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) == 0) {
1727 PrintAndLogEx(ERR
, "error, specify one Hitag type");
1732 uint8_t *dump
= NULL
;
1733 size_t bytes_read
= (4 * 64);
1734 int res
= pm3_load_dump(filename
, (void **)&dump
, &bytes_read
, (4 * 64));
1735 if (res
!= PM3_SUCCESS
) {
1740 if (bytes_read
== HITAG2_MAX_BYTE_SIZE
|| bytes_read
== 4 * 64) {
1742 lf_hitag_t
*payload
= calloc(1, sizeof(lf_hitag_t
) + bytes_read
);
1753 payload
->len
= bytes_read
;
1754 memcpy(payload
->data
, dump
, bytes_read
);
1756 clearCommandBuffer();
1757 SendCommandNG(CMD_LF_HITAG_ELOAD
, (uint8_t *)payload
, 3 + bytes_read
);
1760 PrintAndLogEx(ERR
, "error, wrong dump file size. got %zu", bytes_read
);
1767 static int CmdLFHitagEview(const char *Cmd
) {
1768 CLIParserContext
*ctx
;
1769 CLIParserInit(&ctx
, "lf hitag eview",
1770 "It displays emulator memory",
1773 void *argtable
[] = {
1775 arg_lit0("v", "verbose", "Verbose output"),
1778 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1779 bool verbose
= arg_get_lit(ctx
, 1);
1782 int bytes
= HITAG2_MAX_BYTE_SIZE
;
1785 uint8_t *dump
= calloc(bytes
, sizeof(uint8_t));
1787 PrintAndLogEx(WARNING
, "Fail, cannot allocate memory");
1791 PrintAndLogEx(INFO
, "Downloading " _YELLOW_("%u") " bytes from emulator memory...", bytes
);
1792 if (GetFromDevice(BIG_BUF_EML
, dump
, bytes
, 0, NULL
, 0, NULL
, 2500, false) == false) {
1793 PrintAndLogEx(WARNING
, "Fail, transfer from device time-out");
1795 return PM3_ETIMEOUT
;
1800 uint8_t config
= dump
[HITAG2_CONFIG_OFFSET
];
1801 uint32_t uid
= bytes_to_num(dump
, HITAG_UID_SIZE
);
1802 print_hitag2_configuration(uid
, config
);
1803 print_hitag2_paxton(dump
);
1805 print_hitag2_blocks(dump
, HITAG2_MAX_BYTE_SIZE
);
1810 static int CmdLFHitagSim(const char *Cmd
) {
1811 CLIParserContext
*ctx
;
1812 CLIParserInit(&ctx
, "lf hitag sim",
1813 "Simulate Hitag transponder\n"
1814 "You need to `lf hitag eload` first",
1818 void *argtable
[] = {
1820 arg_lit0("1", "ht1", "simulate Hitag 1"),
1821 arg_lit0("2", "ht2", "simulate Hitag 2"),
1822 arg_lit0("s", "hts", "simulate Hitag S"),
1825 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1827 bool use_ht1
= arg_get_lit(ctx
, 1);
1828 bool use_ht2
= arg_get_lit(ctx
, 2);
1829 bool use_hts
= arg_get_lit(ctx
, 3);
1830 bool use_htm
= false; // not implemented yet
1833 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) > 1) {
1834 PrintAndLogEx(ERR
, "error, specify only one Hitag type");
1837 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) == 0) {
1838 PrintAndLogEx(ERR
, "error, specify one Hitag type");
1842 uint16_t cmd
= CMD_LF_HITAG_SIMULATE
;
1844 // cmd = CMD_LF_HITAG1_SIMULATE;
1847 cmd
= CMD_LF_HITAGS_SIMULATE
;
1849 clearCommandBuffer();
1850 SendCommandMIX(cmd
, 0, 0, 0, NULL
, 0);
1854 static int CmdLFHitagSniff(const char *Cmd
) {
1855 CLIParserContext
*ctx
;
1856 CLIParserInit(&ctx
, "lf hitag sniff",
1857 "Sniff the communication between reader and tag.\n"
1858 "Use `lf hitag list` to view collected data.",
1862 void *argtable
[] = {
1866 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1869 PrintAndLogEx(INFO
, "Press " _GREEN_("pm3 button") " to abort sniffing");
1871 PacketResponseNG resp
;
1872 clearCommandBuffer();
1873 SendCommandNG(CMD_LF_HITAG_SNIFF
, NULL
, 0);
1874 WaitForResponse(CMD_LF_HITAG_SNIFF
, &resp
);
1875 PrintAndLogEx(INFO
, "Done!");
1876 PrintAndLogEx(HINT
, "Try `" _YELLOW_("lf hitag list")"` to view captured tracelog");
1877 PrintAndLogEx(HINT
, "Try `" _YELLOW_("trace save -h") "` to save tracelog for later analysing");
1882 static int CmdLFHitag2PWMDemod(const char *Cmd) {
1884 CLIParserContext *ctx;
1885 CLIParserInit(&ctx, "lf hitag pwmdemod",
1886 "Demodulate the data in the GraphBuffer and output binary\n",
1888 "lf hitag pwmdemod -t 65 --> specify first wave index\n"
1891 void *argtable[] = {
1893 arg_int0("t", "start", "<dec>", "first wave index"),
1894 arg_int0(NULL, "zero", "<dec>", "Zero pulse length"),
1895 arg_int0(NULL, "one", "<dec>", "One pulse length"),
1899 CLIExecWithReturn(ctx, Cmd, argtable, true);
1900 uint32_t start_idx = (uint32_t)arg_get_int_def(ctx, 1, 0);
1901 uint8_t fclow = (uint8_t)arg_get_int_def(ctx, 2, 20);
1902 uint8_t fchigh = (uint8_t)arg_get_int_def(ctx, 3, 29);
1905 uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t));
1907 PrintAndLogEx(INFO, "failed to allocate memory");
1911 size_t size = getFromGraphBuffer(bits);
1913 PrintAndLogEx(DEBUG, "DEBUG: (Hitag2PWM) #samples from graphbuff... %zu", size);
1916 PrintAndLogEx(INFO, "too few samples in buffer");
1922 size = HitagPWMDemod(bits, size, &fchigh, &fclow, &start_idx, g_DemodBitRangeBuffer);
1924 PrintAndLogEx(FAILED, "No wave detected");
1929 PrintAndLogEx(DEBUG, "DEBUG: start_idx... %u size... %zu", start_idx, size);
1931 setDemodBuffBitRange(bits, size, 0, g_DemodBitRangeBuffer);
1932 setClockGrid(32, start_idx);
1935 for (size_t i = 0; i < size; i++) {
1936 total += g_DemodBitRangeBuffer[i];
1937 PrintAndLogEx(DEBUG, "%d", g_DemodBitRangeBuffer[i]);
1939 PrintAndLogEx(DEBUG, "Total... %d", total);
1941 PrintAndLogEx(NORMAL, "");
1942 PrintAndLogEx(INFO, "--- " _CYAN_("HITAG/PWM") " ---------------------------");
1943 printDemodBuff(0, false, false, false);
1944 printDemodBuff(0, false, false, true);
1950 static int CmdLFHitag2Chk(const char *Cmd
) {
1952 CLIParserContext
*ctx
;
1953 CLIParserInit(&ctx
, "lf hitag chk",
1954 "Run dictionary key or password recovery against Hitag card.",
1955 "lf hitag chk\n -> checks for both pwd / crypto keys"
1956 "lf hitag chk --crypto -> use def dictionary\n"
1957 "lf hitag chk --pwd -f my.dic -> pwd mode, custom dictionary"
1960 void *argtable
[] = {
1962 arg_str0("f", "file", "<fn>", "specify dictionary filename"),
1963 arg_lit0(NULL
, "pwd", "password mode"),
1964 arg_lit0(NULL
, "crypto", "crypto mode"),
1968 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1970 char filename
[FILE_PATH_SIZE
] = {0};
1971 CLIParamStrToBuf(arg_get_str(ctx
, 1), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
1973 bool use_pwd
= arg_get_lit(ctx
, 2);
1974 bool use_crypto
= arg_get_lit(ctx
, 3);
1977 if (use_pwd
+ use_crypto
> 1) {
1978 PrintAndLogEx(WARNING
, "Only specify one mode");
1982 // no filename -> use default = ht2_default.dic
1984 snprintf(filename
, sizeof(filename
), HITAG_DICTIONARY
);
1992 uint64_t t1
= msclock();
1994 // just loop twice at max. Starting with 4 or 6.
1995 for (; keylen
< 7; keylen
+= 2) {
1997 uint8_t *keys
= NULL
;
1998 uint32_t key_count
= 0;
1999 int res
= loadFileDICTIONARY_safe(filename
, (void **)&keys
, keylen
, &key_count
);
2000 if (res
!= PM3_SUCCESS
|| key_count
== 0 || keys
== NULL
) {
2001 PrintAndLogEx(WARNING
, "no keys found in file");
2009 uint32_t found_idx
= 0;
2010 int status
= ht2_check_dictionary(key_count
, keys
, keylen
, &found_idx
);
2012 if (status
== PM3_SUCCESS
) {
2014 PrintAndLogEx(NORMAL
, "");
2016 PrintAndLogEx(SUCCESS
, "found valid key [ " _GREEN_("%s") " ]", sprint_hex_inrow(keys
+ (found_idx
* keylen
), keylen
));
2018 PrintAndLogEx(SUCCESS
, "found valid password [ " _GREEN_("%s") " ]", sprint_hex_inrow(keys
+ (found_idx
* keylen
), keylen
));
2026 t1
= msclock() - t1
;
2027 PrintAndLogEx(SUCCESS
, "\ntime in check " _YELLOW_("%.0f") " seconds\n", (float)t1
/ 1000.0);
2031 static int CmdLFHitag2Lookup(const char *Cmd
) {
2033 CLIParserContext
*ctx
;
2034 CLIParserInit(&ctx
, "lf hitag lookup",
2035 "This command take sniffed trace data and try to recovery a Hitag 2 crypto key.\n"
2037 " - verify that NR/AR matches a known crypto key\n"
2038 " - verify if NR/AR matches a known 6 byte crypto key in a dictionary",
2039 "lf hitag lookup --uid 11223344 --nr 73AA5A62 --ar EAB8529C -k 010203040506 -> check key\n"
2040 "lf hitag lookup --uid 11223344 --nr 73AA5A62 --ar EAB8529C -> use def dictionary\n"
2041 "lf hitag lookup --uid 11223344 --nr 73AA5A62 --ar EAB8529C -f my.dic -> use custom dictionary\n"
2042 "lf hitag lookup --uid 11223344 --nrar 73AA5A62EAB8529C"
2045 void *argtable
[] = {
2047 arg_str0("f", "file", "<fn>", "specify dictionary filename"),
2048 arg_str0("k", "key", "<hex>", "specify known cryptokey as 6 bytes"),
2049 arg_str1("u", "uid", "<hex>", "specify UID as 4 hex bytes"),
2050 arg_str0(NULL
, "nr", "<hex>", "specify nonce as 4 hex bytes"),
2051 arg_str0(NULL
, "ar", "<hex>", "specify answer as 4 hex bytes"),
2052 arg_str0(NULL
, "nrar", "<hex>", "specify nonce / answer as 8 hex bytes"),
2056 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
2058 char filename
[FILE_PATH_SIZE
] = {0};
2059 CLIParamStrToBuf(arg_get_str(ctx
, 1), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
2062 uint8_t inkey
[6] = {0};
2063 CLIGetHexWithReturn(ctx
, 2, inkey
, &inkeylen
);
2066 uint8_t uidarr
[4] = {0};
2067 CLIGetHexWithReturn(ctx
, 3, uidarr
, &ulen
);
2070 uint8_t narr
[4] = {0};
2071 CLIGetHexWithReturn(ctx
, 4, narr
, &nlen
);
2074 uint8_t aarr
[4] = {0};
2075 CLIGetHexWithReturn(ctx
, 5, aarr
, &alen
);
2078 uint8_t nrar
[8] = {0};
2079 CLIGetHexWithReturn(ctx
, 6, nrar
, &nalen
);
2084 if (inkeylen
&& inkeylen
!= 6) {
2085 PrintAndLogEx(INFO
, "Key wrong length. expected 6, got %i", inkeylen
);
2089 if (ulen
&& ulen
!= 4) {
2090 PrintAndLogEx(INFO
, "UID wrong length. expected 4, got %i", ulen
);
2094 if (nlen
&& nlen
!= 4) {
2095 PrintAndLogEx(INFO
, "Nr wrong length. expected 4, got %i", nlen
);
2099 if (alen
&& alen
!= 4) {
2100 PrintAndLogEx(INFO
, "Ar wrong length. expected 4, got %i", alen
);
2104 if (nalen
&& nalen
!= 8) {
2105 PrintAndLogEx(INFO
, "NrAr wrong length. expected 8, got %i", nalen
);
2110 // - key, uid and Nr1 is alway dentoed as LSB/LE order
2111 // - Ar1 is NOT. It is in BE/MSB everywhere.
2112 // - At1 is NOT. It is in BE/MSB everywhere.
2113 // - crypto stream generated is in BE/MSB order in Pm3 code.
2114 // - crypto state is in ?
2115 // - lfsr state is in ?
2117 // Different implementations handles internally the state either in MSB or LSB.
2118 // Something to keep an eye for when looking at code.
2121 // cs / hstate.shiftregister / crypto state = same
2122 // lsfr = some implementations mixes cs and lsfr into one and only use the state. Some differentiate between them.
2123 // usually the key recovery functions under /tools/hitag2crack
2124 // IV / Nonce Reader 1 / Nr1 = same (clear text), always 00 00 00 00 in PM3 code when acting as reader.
2125 // Answer Reader 1 / Ar1 = encrypted and BE/MSB, +32, the clear text is always FF FF FF FF.
2126 // Answer Tag 1 / At1 = encrypted and BE/MSB, +32,
2129 When initializer the crypto engine
2132 2. KEY: FFFF143624FF
2133 3. NONCE / IV: 00 00 00 00
2134 3. NONCE / IV: 3B 6F 08 4D
2136 now you have a CS / Shiftregister / state = crypto stream?
2138 Ar1 - first encrypted crypto stream ^ 0xFFFFFFFF
2139 4. Ar1: 96 7A 6F 2A ^ FF FF FF FF == 69 85 90 D5
2142 rev_msb_array(inkey
, sizeof(inkey
));
2143 rev_msb_array(uidarr
, sizeof(uidarr
));
2144 rev_msb_array(narr
, sizeof(narr
));
2145 rev_msb_array(nrar
, 4);
2149 uint64_t knownkey
= MemLeToUint6byte(inkey
);
2150 uint32_t uid
= MemLeToUint4byte(uidarr
);
2157 nr
= MemLeToUint4byte(narr
);
2158 ar
= MemBeToUint4byte(aarr
);
2160 nr
= MemLeToUint4byte(nrar
);
2161 ar
= MemBeToUint4byte(nrar
+ 4);
2163 PrintAndLogEx(INFO
, "No nr or ar was supplied");
2172 PrintAndLogEx(DEBUG
, "UID... %08" PRIx32
, uid
);
2173 PrintAndLogEx(DEBUG
, "IV.... %08" PRIx32
, iv
);
2174 PrintAndLogEx(DEBUG
, "Key... %012" PRIx64
, knownkey
);
2177 hitag_state_t hstate
;
2178 ht2_hitag2_init_ex(&hstate
, knownkey
, uid
, iv
);
2180 // get 32 bits of crypto stream.
2181 uint32_t cbits
= ht2_hitag2_nstep(&hstate
, 32);
2182 bool isok
= (ar
== (cbits
^ 0xFFFFFFFF));
2184 PrintAndLogEx(DEBUG
, "state.shiftreg...... %012" PRIx64
, hstate
.shiftreg
);
2185 PrintAndLogEx(DEBUG
, "state.lfsr.......... %012" PRIx64
, hstate
.lfsr
);
2186 PrintAndLogEx(DEBUG
, "c bits.............. %08x", cbits
);
2187 PrintAndLogEx(DEBUG
, "c-bits ^ FFFFFFFF... %08x", cbits
^ 0xFFFFFFFF);
2188 PrintAndLogEx(DEBUG
, "Ar.................. %08" PRIx32
" ( %s )", ar
, (isok
) ? _GREEN_("ok") : _RED_("fail"));
2190 PrintAndLogEx(INFO
, "Nr/Ar match key ( %s )", (isok
) ? _GREEN_("ok") : _RED_("fail"));
2191 PrintAndLogEx(NORMAL
, "");
2196 snprintf(filename
, sizeof(filename
), HITAG_DICTIONARY
);
2200 uint8_t *keys
= NULL
;
2201 uint32_t key_count
= 0;
2202 int res
= loadFileDICTIONARY_safe(filename
, (void **)&keys
, HITAG_CRYPTOKEY_SIZE
, &key_count
);
2203 if (res
!= PM3_SUCCESS
|| key_count
== 0 || keys
== NULL
) {
2204 PrintAndLogEx(WARNING
, "no keys found in file");
2212 for (uint32_t i
= 0; i
< key_count
; i
++) {
2214 uint8_t *pkey
= keys
+ (i
* HITAG_CRYPTOKEY_SIZE
);
2215 uint64_t mykey
= MemLeToUint6byte(pkey
);
2216 mykey
= REV64(mykey
);
2219 ht2_hitag2_init_ex(&hs2
, mykey
, uid
, iv
);
2221 uint32_t tbits
= ht2_hitag2_nstep(&hs2
, 32);
2222 if ((ar
^ tbits
) == 0xFFFFFFFF) {
2223 PrintAndLogEx(SUCCESS
, "Found valid key [ " _GREEN_("%s")" ]", sprint_hex_inrow(pkey
, HITAG_CRYPTOKEY_SIZE
));
2229 PrintAndLogEx(DEBUG
, " tbits... %08" PRIx32
" Known ar... %08" PRIx32
, tbits
, ar
);
2230 PrintAndLogEx(DEBUG
, " 0xFFFFFFFF ^ tbits... %08" PRIx32
, tbits
^ 0xFFFFFFFF);
2231 PrintAndLogEx(DEBUG
, " 0xFFFFFFFF ^ ar...... %08" PRIx32
, ar
^ 0xFFFFFFFF);
2232 PrintAndLogEx(DEBUG
, " tbits ^ ar........... %08" PRIx32
" ( 0xFFFFFFFF )", ar
^ tbits
);
2238 if (found
== false) {
2239 PrintAndLogEx(WARNING
, "check failed");
2242 PrintAndLogEx(NORMAL
, "");
2246 static int CmdLFHitag2Crack2(const char *Cmd
) {
2247 CLIParserContext
*ctx
;
2248 CLIParserInit(&ctx
, "lf hitag crack2",
2249 "This command tries to recover 2048 bits of Hitag 2 crypto stream data.\n",
2250 "lf hitag crack2 --nrar 73AA5A62EAB8529C"
2253 void *argtable
[] = {
2255 arg_str0(NULL
, "nrar", "<hex>", "specify nonce / answer as 8 hex bytes"),
2259 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
2261 uint8_t nrar
[8] = {0};
2262 CLIGetHexWithReturn(ctx
, 1, nrar
, &nalen
);
2266 if (nalen
&& nalen
!= 8) {
2267 PrintAndLogEx(INFO
, "NrAr wrong length. expected 8, got %i", nalen
);
2271 lf_hitag_data_t packet
;
2272 memset(&packet
, 0, sizeof(packet
));
2273 memcpy(packet
.NrAr
, nrar
, sizeof(packet
.NrAr
));
2275 PrintAndLogEx(INFO
, _YELLOW_("Hitag 2") " - Nonce replay and length extension attack ( Crack2 )");
2277 uint64_t t1
= msclock();
2279 PacketResponseNG resp
;
2280 clearCommandBuffer();
2281 SendCommandNG(CMD_LF_HITAG2_CRACK_2
, (uint8_t *) &packet
, sizeof(packet
));
2284 uint8_t attempt
= 50;
2287 // PrintAndLogEx(INPLACE, "Attack 2 running...");
2290 if (WaitForResponseTimeout(CMD_LF_HITAG2_CRACK_2
, &resp
, 1000) == false) {
2295 if (resp
.status
== PM3_SUCCESS
) {
2297 PrintAndLogEx(SUCCESS
, "--------------------- " _CYAN_("Recovered Keystream") " ----------------------");
2298 lf_hitag_crack_response_t
*payload
= (lf_hitag_crack_response_t
*)resp
.data
.asBytes
;
2300 for (int i
= 0; i
< 256; i
+= 32) {
2301 PrintAndLogEx(SUCCESS
, "%s", sprint_hex_inrow(payload
->data
+ i
, 32));
2303 PrintAndLogEx(NORMAL
, "");
2304 PrintAndLogEx(SUCCESS
, "Nonce replay and length extension attack ( %s )", _GREEN_("ok"));
2305 PrintAndLogEx(HINT
, "try running `tools/hitag2crack/crack2/ht2crack2search <FILE_with_above_bytes>");
2308 PrintAndLogEx(NORMAL
, "");
2309 PrintAndLogEx(FAILED
, "Nonce replay and length extension attack ( %s )", _RED_("fail"));
2316 PrintAndLogEx(NORMAL
, "");
2317 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
2321 t1
= msclock() - t1
;
2322 PrintAndLogEx(SUCCESS
, "\ntime " _YELLOW_("%.0f") " seconds\n", (float)t1
/ 1000.0);
2328 Test data and below information about it comes from
2329 http://www.mikrocontroller.net/attachment/102194/hitag2.c
2330 Written by "I.C. Wiener 2006-2007"
2332 "MIKRON" = O N M I K R
2333 Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key
2334 Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear
2335 Random = 65 6E 45 72 - Random IV, transmitted in clear
2336 ~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream
2338 The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6".
2339 The inverse of the first 4 bytes is sent to the tag to authenticate.
2340 The rest is encrypted by XORing it with the subsequent keystream.
2342 static uint64_t hitag2_benchtest_gen32(void) {
2343 const uint64_t key
= 0x4ad292b272f2;
2344 const uint32_t serial
= 0x96eac292;
2345 const uint32_t initvec
= 0x4ea276a6;
2346 hitag_state_t state
;
2349 ht2_hitag2_init_ex(&state
, key
, serial
, initvec
);
2351 // benchmark: generation of 32 bit stream (excludes initialisation)
2352 uint64_t t1
= usclock();
2354 (void) ht2_hitag2_nstep(&state
, 32);
2356 t1
= usclock() - t1
;
2360 static uint64_t hitag2_benchtest(uint32_t count
) {
2362 const uint64_t key
= 0x4ad292b272f2;
2363 const uint32_t serial
= 0x96eac292;
2364 const uint32_t initvec
= 0x4ea276a6;
2366 hitag_state_t state
;
2369 uint64_t t1
= usclock();
2371 // benchmark: initialise crypto & generate 32 bit authentication
2372 // adding i stops gcc optimizer moving init function call out of loop
2373 for (uint32_t i
= 0; i
< count
; i
++) {
2374 ht2_hitag2_init_ex(&state
, key
, serial
, initvec
+ i
);
2375 (void) ht2_hitag2_nstep(&state
, 32);
2378 t1
= usclock() - t1
;
2382 static uint64_t hitag2_verify_crypto_test(void) {
2384 uint8_t expected
[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 };
2385 // key = 0x4ad292b272f2 after each byte has its bit order reversed
2386 // uid = 0x96eac292 ditto
2387 // initvec = 0x4ea276a6 ditto
2388 const uint64_t key
= REV64(0x524B494D4E4FUL
);
2389 const uint32_t uid
= REV32(0x69574349);
2390 const uint32_t iv
= REV32(0x72456E65);
2392 PrintAndLogEx(DEBUG
, "UID... %08" PRIx32
, uid
);
2393 PrintAndLogEx(DEBUG
, "IV.... %08" PRIx32
, iv
);
2394 PrintAndLogEx(DEBUG
, "Key... %012" PRIx64
, key
);
2397 hitag_state_t state
;
2398 ht2_hitag2_init_ex(&state
, key
, uid
, iv
);
2399 PrintAndLogEx(DEBUG
, "hs shiftreg... %012" PRIx64
, state
.shiftreg
);
2401 for (uint32_t i
= 0; i
< 16; i
++) {
2402 // get 8 bits of keystream
2403 uint8_t x
= (uint8_t) ht2_hitag2_nstep(&state
, 8);
2404 uint8_t y
= expected
[i
];
2406 PrintAndLogEx(DEBUG
, "%02X (%02X)", x
, y
);
2414 static uint64_t hitag2_verify_crypto_test_round(void) {
2416 uint8_t expected
[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 };
2417 const uint64_t key
= REV64(0x524B494D4E4FUL
);
2418 const uint32_t uid
= REV32(0x69574349);
2419 const uint32_t iv
= REV32(0x72456E65);
2421 PrintAndLogEx(DEBUG
, "UID... %08" PRIx32
, uid
);
2422 PrintAndLogEx(DEBUG
, "IV.... %08" PRIx32
, iv
);
2423 PrintAndLogEx(DEBUG
, "Key... %012" PRIx64
, key
);
2426 uint64_t cs
= ht2_hitag2_init(key
, uid
, iv
);
2427 PrintAndLogEx(DEBUG
, "hs shiftreg... %012" PRIx64
, cs
);
2429 for (uint32_t i
= 0; i
< 16; i
++) {
2430 // get 8 bits of keystream
2431 uint8_t x
= (uint8_t) ht2_hitag2_byte(&cs
);
2432 uint8_t y
= expected
[i
];
2434 PrintAndLogEx(DEBUG
, "%02X (%02X)", x
, y
);
2442 static int CmdLFHitag2Selftest(const char *Cmd
) {
2443 CLIParserContext
*ctx
;
2444 CLIParserInit(&ctx
, "lf hitag test",
2445 "Perform self tests of Hitag crypto engine",
2449 void *argtable
[] = {
2453 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
2456 PrintAndLogEx(INFO
, "======== " _CYAN_("Hitag 2 crypto test") " ============================");
2457 uint64_t test
= hitag2_verify_crypto_test();
2458 PrintAndLogEx(INFO
, "Crypto self test ( %s )", test
? _GREEN_("ok") : _RED_("fail"));
2460 test
|= hitag2_verify_crypto_test_round();
2461 PrintAndLogEx(INFO
, "Crypto self test ROUND ( %s )", test
? _GREEN_("ok") : _RED_("fail"));
2463 test
|= hitag2_benchtest(1);
2464 PrintAndLogEx(INFO
, "Hitag 2 crypto, init + gen 32 bits ( us %" PRIu64
" )", test
);
2466 test
|= hitag2_benchtest_gen32();
2467 PrintAndLogEx(INFO
, "Hitag 2 crypto, gen new 32 bits only ( us: %" PRIu64
" )", test
);
2469 test
|= hitag2_benchtest(1000);
2470 PrintAndLogEx(INFO
, "Hitag 2 crypto, init + gen 32 bits, x1000 ( us: %" PRIu64
" )", test
);
2472 PrintAndLogEx(INFO
, "--------------------------------------------------------");
2473 PrintAndLogEx(SUCCESS
, "Tests ( %s )", (test
) ? _GREEN_("ok") : _RED_("fail"));
2474 PrintAndLogEx(NORMAL
, "");
2478 static command_t CommandTable
[] = {
2479 {"help", CmdHelp
, AlwaysAvailable
, "This help"},
2480 {"list", CmdLFHitagList
, AlwaysAvailable
, "List Hitag trace history"},
2481 {"hts", CmdLFHitagS
, AlwaysAvailable
, "{ Hitag S/8211 operations }"},
2482 {"-----------", CmdHelp
, IfPm3Hitag
, "------------------------ " _CYAN_("General") " ------------------------"},
2483 {"info", CmdLFHitagInfo
, IfPm3Hitag
, "Hitag 2 tag information"},
2484 {"reader", CmdLFHitagReader
, IfPm3Hitag
, "Act like a Hitag 2 reader"},
2485 {"test", CmdLFHitag2Selftest
, AlwaysAvailable
, "Perform self tests"},
2486 {"-----------", CmdHelp
, IfPm3Hitag
, "----------------------- " _CYAN_("Operations") " -----------------------"},
2487 // {"demod", CmdLFHitag2PWMDemod, IfPm3Hitag, "PWM Hitag 2 reader message demodulation"},
2488 {"dump", CmdLFHitag2Dump
, IfPm3Hitag
, "Dump Hitag 2 tag"},
2489 {"read", CmdLFHitagRd
, IfPm3Hitag
, "Read Hitag memory"},
2490 {"sniff", CmdLFHitagSniff
, IfPm3Hitag
, "Eavesdrop Hitag communication"},
2491 {"view", CmdLFHitagView
, AlwaysAvailable
, "Display content from tag dump file"},
2492 {"wrbl", CmdLFHitagWriter
, IfPm3Hitag
, "Write a block (page) in Hitag memory"},
2493 {"-----------", CmdHelp
, IfPm3Hitag
, "----------------------- " _CYAN_("Simulation") " -----------------------"},
2494 {"eload", CmdLFHitagEload
, IfPm3Hitag
, "Upload file into emulator memory"},
2495 // {"esave", CmdLFHitagESave, IfPm3Hitag, "Save emulator memory to file"},
2496 {"eview", CmdLFHitagEview
, IfPm3Hitag
, "View emulator memory"},
2497 {"sim", CmdLFHitagSim
, IfPm3Hitag
, "Simulate Hitag transponder"},
2498 {"-----------", CmdHelp
, IfPm3Hitag
, "----------------------- " _CYAN_("Recovery") " -----------------------"},
2499 {"cc", CmdLFHitagSCheckChallenges
, IfPm3Hitag
, "Hitag S: test all provided challenges"},
2500 {"crack2", CmdLFHitag2Crack2
, IfPm3Hitag
, "Recover 2048bits of crypto stream"},
2501 {"chk", CmdLFHitag2Chk
, IfPm3Hitag
, "Check keys"},
2502 {"lookup", CmdLFHitag2Lookup
, AlwaysAvailable
, "Uses authentication trace to check for key in dictionary file"},
2503 {"ta", CmdLFHitag2CheckChallenges
, IfPm3Hitag
, "Hitag 2: test all recorded authentications"},
2504 { NULL
, NULL
, 0, NULL
}
2507 static int CmdHelp(const char *Cmd
) {
2508 (void)Cmd
; // Cmd is not used so far
2509 CmdsHelp(CommandTable
);
2513 int CmdLFHitag(const char *Cmd
) {
2514 clearCommandBuffer();
2515 return CmdsParse(CommandTable
, Cmd
);
2518 int readHitagUid(void) {
2520 if (getHitag2Uid(&uid
) == false) {
2524 PrintAndLogEx(SUCCESS
, "UID.... " _GREEN_("%08X"), uid
);
2525 PrintAndLogEx(SUCCESS
, "TYPE... " _GREEN_("%s"), getHitagTypeStr(uid
));