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 uint8_t ht2_default_keys
[] = {
39 0xBD, 0xF5, 0xE8, 0x46 // PAXTON
42 static const char *getHitagTypeStr(uint32_t uid
) {
44 uint8_t type
= (uid
>> 4) & 0xF;
67 uint8_t hitag1_CRC_check(uint8_t *d
, uint32_t nbit
) {
71 return (CRC8Hitag1Bits(d
, nbit
) == 0);
76 static size_t nbytes(size_t nbits) {
77 return (nbits / 8) + ((nbits % 8) > 0);
81 static int CmdLFHitagList(const char *Cmd
) {
82 return CmdTraceListAlias(Cmd
, "lf hitag", "hitag2");
84 uint8_t *got = calloc(PM3_CMD_DATA_SIZE, sizeof(uint8_t));
86 PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
90 // Query for the actual size of the trace
91 PacketResponseNG resp;
92 if (!GetFromDevice(BIG_BUF, got, PM3_CMD_DATA_SIZE, 0, NULL, 0, &resp, 2500, false)) {
93 PrintAndLogEx(WARNING, "command execution time out");
98 uint16_t traceLen = resp.arg[2];
99 if (traceLen > PM3_CMD_DATA_SIZE) {
100 uint8_t *p = realloc(got, traceLen);
102 PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
107 if (!GetFromDevice(BIG_BUF, got, traceLen, 0, NULL, 0, NULL, 2500, false)) {
108 PrintAndLogEx(WARNING, "command execution time out");
114 PrintAndLogEx(NORMAL, "recorded activity (TraceLen = %d bytes):");
115 PrintAndLogEx(NORMAL, " ETU :nbits: who bytes");
116 PrintAndLogEx(NORMAL, "---------+-----+----+-----------");
120 int len = strlen(Cmd);
122 char filename[FILE_PATH_SIZE] = { 0x00 };
125 if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
127 memcpy(filename, Cmd, len);
129 if (strlen(filename) > 0) {
130 f = fopen(filename, "wb");
132 PrintAndLogEx(ERR, "Error: Could not open file [%s]", filename);
139 if (i >= traceLen) { break; }
142 int timestamp = *((uint32_t *)(got + i));
143 if (timestamp & 0x80000000) {
144 timestamp &= 0x7fffffff;
150 int parityBits = *((uint32_t *)(got + i + 4));
151 // 4 bytes of additional information...
152 // maximum of 32 additional parity bit information
155 // at each quarter bit period we can send power level (16 levels)
156 // or each half bit period in 256 levels.
158 int bits = got[i + 8];
159 int len = nbytes(got[i + 8]);
164 if (i + len > traceLen) { break;}
166 uint8_t *frame = (got + i + 9);
168 // Break and stick with current result if buffer was not completely full
169 if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
171 char line[1000] = "";
173 for (j = 0; j < len; j++) {
176 //if((parityBits >> (len - j - 1)) & 0x01) {
177 if (isResponse && (oddparity8(frame[j]) != ((parityBits >> (len - j - 1)) & 0x01))) {
178 snprintf(line + offset, sizeof(line) - offset, "%02x! ", frame[j]);
180 snprintf(line + offset, sizeof(line) - offset, "%02x ", frame[j]);
184 PrintAndLogEx(NORMAL, " +%7d: %3d: %s %s",
185 (prev < 0 ? 0 : (timestamp - prev)),
187 (isResponse ? "TAG" : " "),
191 fprintf(f, " +%7d: %3d: %s %s\n",
192 (prev < 0 ? 0 : (timestamp - prev)),
194 (isResponse ? "TAG" : " "),
204 PrintAndLogEx(NORMAL, "Recorded activity successfully written to file: %s", filename);
212 static void print_hitag2_paxton(bool show_header
, const uint8_t *data
) {
214 // if the pwd isn't..
215 if (memcmp(data
+ 4, "\xBD\xF5\xE8\x46", 4)) {
220 uint64_t paxton_id
= 0;
222 uint64_t mask
= 0xF80000000000;
224 uint64_t bytes
= bytes_to_num(data
+ 16, 6);
226 for (int j
= 0; j
< 8; j
++) {
232 uint8_t digit
= (num
>> skip
& 0xF);
233 paxton_id
= (paxton_id
* 10) + digit
;
242 const uint8_t isocard = 0x06;
243 const uint8_t fob = 0x03;
244 const uint8_t iso_magstripe = 0x02;
247 // [=] 4/0x04 | 39 04 21 1C | 9.!. | RW | User
248 // [=] 5/0x05 | AC 3F 00 06 | .?.. | RW | User
253 strcat(formfactor
, "isocard");
257 strcat(formfactor
, "fob");
261 strcat(formfactor
, "iso magstripe");
265 snprintf(formfactor
, sizeof(formfactor
), "unk: %02x", data
[23]);
271 PrintAndLogEx(INFO
, "");
272 PrintAndLogEx(INFO
, "--- " _CYAN_("Possible de-scramble patterns") " -------------");
274 PrintAndLogEx(SUCCESS
, "Paxton id... %" PRIu64
" | 0x%" PRIx64
" ( %s )", paxton_id
, paxton_id
, formfactor
);
276 PrintAndLogEx(INFO
, "");
280 static void print_hitag2_configuration(uint32_t uid
, uint8_t config
) {
282 PrintAndLogEx(NORMAL
, "");
283 PrintAndLogEx(INFO
, "--- " _CYAN_("Tag Information") " ---------------------------");
284 PrintAndLogEx(SUCCESS
, "UID...... " _GREEN_("%08X"), uid
);
285 PrintAndLogEx(SUCCESS
, "TYPE..... " _GREEN_("%s"), getHitagTypeStr(uid
));
288 memset(msg
, 0, sizeof(msg
));
290 uint8_t bits
[8 + 1] = {0};
291 num_to_bytebits(config
, 8, bits
);
292 const char *bs
= sprint_bytebits_bin(bits
, 8);
295 // PrintAndLogEx(SUCCESS, "");
296 PrintAndLogEx(SUCCESS
, "Config... " _YELLOW_("0x%02X"), config
);
297 PrintAndLogEx(SUCCESS
, " %s", bs
);
298 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 0, 4, "RFU"));
301 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_YELLOW
, bs
, 8, 4, 1, "Crypto mode"));
303 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 4, 1, "Password mode"));
307 uint8_t foo
= ((config
& 0x6) >> 1);
310 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 5, 2, "Public mode B, Coding: biphase"));
313 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 5, 2, "Public mode A, Coding: manchester"));
316 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 5, 2, "Public mode C, Coding: biphase"));
319 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 5, 2, "Hitag 2"));
325 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 7, 1, "Biphase"));
327 PrintAndLogEx(SUCCESS
, " %s", sprint_breakdown_bin(C_NONE
, bs
, 8, 7, 1, "Manchester"));
329 PrintAndLogEx(NORMAL
, "");
332 const char *annotation
[] = {
333 "UID", "Pwd", "Key/Pwd", "Config",
334 "User", "User", "User", "User",
335 "User", "User", "User", "User"
338 static void print_hitag2_blocks(uint8_t *d
, uint16_t n
) {
340 PrintAndLogEx(INFO
, "");
341 PrintAndLogEx(INFO
, "----------------------------------------------");
342 PrintAndLogEx(INFO
, " # | data | ascii | lck | Info");
343 PrintAndLogEx(INFO
, "--------+-------------+-------+-----+---------");
345 uint8_t config
= d
[HITAG2_CONFIG_OFFSET
];
346 uint8_t blocks
= (n
/ HITAG_BLOCK_SIZE
);
348 for (uint8_t i
= 0; i
< blocks
; ++i
) {
350 char lckstr
[20] = {0};
351 sprintf(lckstr
, " ");
355 sprintf(lckstr
, "%s", _RED_("L "));
359 sprintf(lckstr
, "%s", _RED_("L "));
361 sprintf(lckstr
, "%s", _GREEN_("RW"));
367 sprintf(lckstr
, "%s", _RED_("L "));
369 sprintf(lckstr
, "%s", _RED_("R "));
372 sprintf(lckstr
, "%s", _GREEN_("RW"));
378 sprintf(lckstr
, "%s", _RED_("R "));
379 //. Configuration byte and password tag " _RED_("FIXED / IRREVERSIBLE"));
381 sprintf(lckstr
, "%s", _GREEN_("RW"));
387 sprintf(lckstr
, "%s", _RED_("R "));
389 sprintf(lckstr
, "%s", _GREEN_("RW"));
395 sprintf(lckstr
, "%s", _RED_("R "));
397 sprintf(lckstr
, "%s", _GREEN_("RW"));
404 PrintAndLogEx(INFO
, "%2d/0x%02X | %s| %s | %s | %s"
407 , sprint_hex(d
+ (i
* HITAG_BLOCK_SIZE
), HITAG_BLOCK_SIZE
)
408 , sprint_ascii(d
+ (i
* HITAG_BLOCK_SIZE
), HITAG_BLOCK_SIZE
)
413 PrintAndLogEx(INFO
, "--------+-------------+-------+-----+---------");
414 PrintAndLogEx(INFO
, " "_RED_("L") " = Locked, "_GREEN_("RW") " = Read Write, R = Read Only");
415 PrintAndLogEx(INFO
, " FI = Fixed / Irreversible");
416 PrintAndLogEx(INFO
, "----------------------------------------------");
419 // Annotate HITAG protocol
420 void annotateHitag1(char *exp
, size_t size
, const uint8_t *cmd
, uint8_t cmdsize
, bool is_response
) {
428 STATE_START_ENCRYPTED
,
432 uint64_t cipher_state
;
439 void annotateHitag2_init(void) {
440 _ht2state
.state
= STATE_HALT
;
442 _ht2state
.cipher_state
= 0;
443 _ht2state
.plainlen
= 0;
444 memset(_ht2state
.plain
, 0, sizeof(_ht2state
.plain
));
447 static void rev_msb_array(uint8_t *d
, uint8_t n
) {
448 for (uint8_t i
= 0 ; i
< n
; i
++) {
449 d
[i
] = reflect8(d
[i
]);
453 // param nrar must be 8 bytes
454 static bool ht2_check_cryptokeys(const uint64_t *keys
, const uint32_t keycount
, const uint8_t *nrar
) {
456 if (keys
== NULL
|| keycount
== 0 || nrar
== NULL
) {
460 uint32_t iv
= REV32((nrar
[3] << 24) + (nrar
[2] << 16) + (nrar
[1] << 8) + nrar
[0]);
461 uint32_t ar
= (nrar
[4] << 24) + (nrar
[5] << 16) + (nrar
[6] << 8) + nrar
[7];
464 for (uint32_t i
= 0; i
< keycount
; i
++) {
466 uint64_t key
= keys
[i
];
471 ht2_hitag2_init_ex(&hs2
, key
, _ht2state
.uid
, iv
);
473 uint32_t tbits
= ht2_hitag2_nstep(&hs2
, 32);
474 if ((ar
^ tbits
) == 0xFFFFFFFF) {
475 _ht2state
.found_key
= true;
484 static int ht2_check_dictionary(uint32_t key_count
, uint8_t *keys
, uint8_t keylen
, uint32_t *found_idx
) {
486 lf_hitag_data_t packet
;
487 memset(&packet
, 0, sizeof(packet
));
489 uint8_t *pkeys
= keys
;
491 while (key_count
--) {
494 packet
.cmd
= HT2F_PASSWORD
;
495 memcpy(packet
.pwd
, pkeys
, keylen
);
497 packet
.cmd
= HT2F_CRYPTO
;
498 memcpy(packet
.key
, pkeys
, keylen
);
503 clearCommandBuffer();
504 SendCommandNG(CMD_LF_HITAG_READER
, (uint8_t *)&packet
, sizeof(packet
));
505 PacketResponseNG resp
;
506 if (WaitForResponseTimeout(CMD_LF_HITAG_READER
, &resp
, 2000) == false) {
507 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
508 SendCommandNG(CMD_BREAK_LOOP
, NULL
, 0);
512 if (resp
.status
!= PM3_SUCCESS
) {
513 *found_idx
= *found_idx
+ 1;
522 bool hitag2_get_plain(uint8_t *plain
, uint8_t *plen
) {
523 if (_ht2state
.state
== STATE_ENCRYPTED
|| _ht2state
.state
== STATE_START_ENCRYPTED
) {
524 if (_ht2state
.found_key
) {
525 *plen
= _ht2state
.plainlen
;
526 memcpy(plain
, _ht2state
.plain
, _ht2state
.plainlen
);
534 #define HITAG2_BINSTR_START_AUTH "11000" // get UID and/or start the authentication process
535 #define HITAG2_BINSTR_READ_PAGE "11" // read page after auth
536 #define HITAG2_BINSTR_READ_PAGE_INVERTED "01" // as read page but all bits inverted
537 #define HITAG2_BINSTR_WRITE_PAGE "10" // write page after auth
538 #define HITAG2_BINSTR_HALT "00" // silence currently authenticated tag
540 static uint8_t hitag2_get_page(const char *bs
) {
541 if ((memcmp(bs
+ 2, "000", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "111", 3) == 0)) {
544 if ((memcmp(bs
+ 2, "001", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "110", 3) == 0)) {
547 if ((memcmp(bs
+ 2, "010", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "101", 3) == 0)) {
550 if ((memcmp(bs
+ 2, "011", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "100", 3) == 0)) {
553 if ((memcmp(bs
+ 2, "100", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "011", 3) == 0)) {
556 if ((memcmp(bs
+ 2, "101", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "010", 3) == 0)) {
559 if ((memcmp(bs
+ 2, "110", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "001", 3) == 0)) {
562 if ((memcmp(bs
+ 2, "111", 3) == 0) && (memcmp(bs
+ 2 + 3 + 2, "000", 3) == 0)) {
568 void hitag2_annotate_plain(char *exp
, size_t size
, const uint8_t *cmd
, uint8_t cmdsize
, uint8_t bits
) {
574 char *binstr
= (char *)calloc((cmdsize
* 8) + 1, sizeof(uint8_t));
575 if (binstr
== NULL
) {
579 bytes_2_binstr(binstr
, cmd
, cmdsize
);
581 size_t bn
= strlen(binstr
);
585 } else if (cmdsize
> 1) {
586 bn
= ((cmdsize
- 1) * 8) + bits
;
592 snprintf(exp
, size
, " ");
596 if (memcmp(binstr
, HITAG2_BINSTR_HALT
, 2) == 0) {
597 snprintf(exp
, size
, " ");
601 uint8_t page
= hitag2_get_page(binstr
);
603 if (memcmp(binstr
, HITAG2_BINSTR_READ_PAGE
, 2) == 0) {
604 snprintf(exp
, size
, "READ PAGE (" _MAGENTA_("%u") ")", page
);
608 if (memcmp(binstr
, HITAG2_BINSTR_READ_PAGE_INVERTED
, 2) == 0) {
609 snprintf(exp
, size
, "READ PAGE INV (" _MAGENTA_("%u") ")", page
);
613 if (memcmp(binstr
, HITAG2_BINSTR_WRITE_PAGE
, 2) == 0) {
614 snprintf(exp
, size
, "WRITE PAGE (" _MAGENTA_("%u") ")", page
);
619 case 32: { // password or data
620 snprintf(exp
, size
, " ");
623 case 64: { // crypto handshake
624 snprintf(exp
, size
, " ");
628 snprintf(exp
, size
, " ");
635 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
) {
641 char *binstr
= (char *)calloc((cmdsize
* 8) + 1, sizeof(uint8_t));
642 if (binstr
== NULL
) {
646 bytes_2_binstr(binstr
, cmd
, cmdsize
);
648 size_t bn
= strlen(binstr
);
652 } else if (cmdsize
> 1) {
653 bn
= ((cmdsize
- 1) * 8) + bits
;
657 memcpy(_ht2state
.plain
, cmd
, cmdsize
);
658 _ht2state
.plainlen
= cmdsize
;
660 if (_ht2state
.state
== STATE_ENCRYPTED
|| _ht2state
.state
== STATE_START_ENCRYPTED
) {
662 if (_ht2state
.found_key
&& isdecrypted
== false) {
663 ht2_hitag2_cipher_transcrypt(&_ht2state
.cipher_state
, _ht2state
.plain
, bn
/ 8, bn
% 8);
667 // 11000 AUTH only one with 5 bits. cmdsize 1
670 annotateHitag2_init();
672 if (memcmp(binstr
, HITAG2_BINSTR_START_AUTH
, 5) == 0) {
673 snprintf(exp
, size
, "START AUTH");
674 _ht2state
.state
= STATE_START_AUTH
;
676 snprintf(exp
, size
, "?");
682 if (isdecrypted
== false && _ht2state
.state
== STATE_ENCRYPTED
) {
683 snprintf(exp
, size
, "ENC CMD");
687 if (memcmp(binstr
, HITAG2_BINSTR_HALT
, 2) == 0) {
688 snprintf(exp
, size
, "HALT");
689 _ht2state
.state
= STATE_HALT
;
693 uint8_t page
= hitag2_get_page(binstr
);
695 if (memcmp(binstr
, HITAG2_BINSTR_READ_PAGE
, 2) == 0) {
696 snprintf(exp
, size
, "READ PAGE (" _MAGENTA_("%u") ")", page
);
700 if (memcmp(binstr
, HITAG2_BINSTR_READ_PAGE_INVERTED
, 2) == 0) {
701 snprintf(exp
, size
, "READ PAGE INV (" _MAGENTA_("%u") ")", page
);
705 if (memcmp(binstr
, HITAG2_BINSTR_WRITE_PAGE
, 2) == 0) {
706 snprintf(exp
, size
, "WRITE PAGE (" _MAGENTA_("%u") ")", page
);
712 case 32: { // password or data
713 if (_ht2state
.state
== STATE_START_AUTH
) {
715 snprintf(exp
, size
, "UID");
718 rev_msb_array(uid
, 4);
719 _ht2state
.uid
= MemLeToUint4byte(uid
);
721 snprintf(exp
, size
, "PWD: " _GREEN_("0x%02X%02X%02X%02X"), cmd
[0], cmd
[1], cmd
[2], cmd
[3]);
722 _ht2state
.state
= STATE_AUTH
;
727 if (_ht2state
.state
== STATE_AUTH
) {
728 snprintf(exp
, size
, "DATA");
732 if (_ht2state
.state
== STATE_START_ENCRYPTED
) {
733 snprintf(exp
, size
, "At");
734 _ht2state
.state
= STATE_ENCRYPTED
;
738 if (isdecrypted
== false && _ht2state
.state
== STATE_ENCRYPTED
) {
739 snprintf(exp
, size
, "ENC DATA");
744 case 64: { // crypto handshake
746 if (_ht2state
.state
== STATE_START_AUTH
) {
747 _ht2state
.state
= STATE_START_ENCRYPTED
;
749 // need to be called with filename...
750 if (ht2_check_cryptokeys(keys
, keycount
, cmd
)) {
752 _ht2state
.cipher_state
= ht2_hitag2_init(
755 REV32((cmd
[3] << 24) + (cmd
[2] << 16) + (cmd
[1] << 8) + cmd
[0])
757 ht2_hitag2_cipher_transcrypt(&_ht2state
.cipher_state
, _ht2state
.plain
+ 4, 4, 0);
759 uint64_t key
= REV64(_ht2state
.key
);
761 snprintf(exp
, size
, "Nr Ar " _WHITE_("( ") _GREEN_("%012" PRIx64
) " )", key
);
764 snprintf(exp
, size
, "AUTH: Nr Ar");
767 snprintf(exp
, size
, "AUTH: Nr Ar");
772 snprintf(exp
, size
, "?");
773 _ht2state
.state
= STATE_HALT
;
781 void annotateHitagS(char *exp
, size_t size
, const uint8_t *cmd
, uint8_t cmdsize
, bool is_response
) {
784 static const char *identify_transponder_hitag2(uint32_t uid
) {
788 return "IMMO Key emulator";
800 return "CN3 Tango Key emulator";
805 static bool ht2_get_uid(uint32_t *uid
) {
807 lf_hitag_data_t packet
;
808 memset(&packet
, 0, sizeof(packet
));
809 packet
.cmd
= HT2F_UID_ONLY
;
811 clearCommandBuffer();
812 SendCommandNG(CMD_LF_HITAG_READER
, (uint8_t *) &packet
, sizeof(packet
));
813 PacketResponseNG resp
;
814 if (WaitForResponseTimeout(CMD_LF_HITAG_READER
, &resp
, 1500) == false) {
815 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
819 if (resp
.status
!= PM3_SUCCESS
) {
820 PrintAndLogEx(DEBUG
, "DEBUG: Error - failed getting UID");
825 *uid
= bytes_to_num(resp
.data
.asBytes
, HITAG_UID_SIZE
);
830 static int CmdLFHitagInfo(const char *Cmd
) {
831 CLIParserContext
*ctx
;
832 CLIParserInit(&ctx
, "lf hitag info",
833 "Hitag 2 tag information",
841 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
846 if (ht2_get_uid(&uid
) == false) {
849 // how to determine Hitag types?
850 // need auth / pwd to get it.
851 // we could try the default key/pwd and print if successful
852 // read block3, get configuration byte.
854 // common configurations.
855 print_hitag2_configuration(uid
, 0x06); // pwd mode enabled / AM
856 // print_hitag2_configuration(uid, 0x0E); // crypto mode enabled / AM
857 // print_hitag2_configuration(uid, 0x02);
858 // print_hitag2_configuration(uid, 0x00);
859 // print_hitag2_configuration(uid, 0x04);
861 PrintAndLogEx(INFO
, "--- " _CYAN_("Fingerprint"));
862 const char *s
= identify_transponder_hitag2(uid
);
864 PrintAndLogEx(SUCCESS
, "Found... " _GREEN_("%s"), s
);
866 PrintAndLogEx(INFO
, _RED_("n/a"));
869 PrintAndLogEx(NORMAL
, "");
873 static int CmdLFHitagReader(const char *Cmd
) {
874 CLIParserContext
*ctx
;
875 CLIParserInit(&ctx
, "lf hitag reader",
876 "Act as a Hitag 2 reader. Look for Hitag 2 tags until Enter or the pm3 button is pressed\n",
878 "lf hitag reader -@ -> Continuous mode"
883 arg_lit0("@", NULL
, "continuous reader mode"),
886 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
887 bool cm
= arg_get_lit(ctx
, 1);
891 PrintAndLogEx(INFO
, "Press " _GREEN_("<Enter>") " to exit");
897 if (ht2_get_uid(&uid
)) {
898 PrintAndLogEx(SUCCESS
, "UID.... " _GREEN_("%08X"), uid
);
900 } while (cm
&& kbd_enter_pressed() == false);
905 static int CmdLFHitagRd(const char *Cmd
) {
907 CLIParserContext
*ctx
;
908 CLIParserInit(&ctx
, "lf hitag read",
909 "Read Hitag memory. It support Hitag 2\n\n"
911 " - default key 4D494B52 (MIKR)\n\n"
913 " - key format ISK high + ISK low\n"
914 " - default key 4F4E4D494B52 (ONMIKR)\n"
916 " lf hitag read --ht2 --pwd -> Hitag 2, pwd mode, def key\n"
917 " lf hitag read --ht2 -k 4D494B52 -> Hitag 2, pwd mode\n"
918 " lf hitag read --ht2 --nrar 0102030411223344 -> Hitag 2, challenge mode\n"
919 " lf hitag read --ht2 --crypto -> Hitag 2, crypto mode, def key\n"
920 " lf hitag read --ht2 -k 4F4E4D494B52 -> Hitag 2, crypto mode\n"
925 arg_lit0("2", "ht2", "Hitag 2"),
926 arg_lit0(NULL
, "pwd", "password mode"),
927 arg_str0(NULL
, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
928 arg_lit0(NULL
, "crypto", "crypto mode"),
929 arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
930 // currently pm3 fw reads all the memory anyway
931 // arg_int1("p", "page", "<dec>", "page address to write to"),
934 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
936 bool use_ht1
= false; // not yet implemented
937 bool use_ht2
= arg_get_lit(ctx
, 1);
938 bool use_htm
= false; // not yet implemented
940 bool use_plain
= false;
941 bool use_pwd
= arg_get_lit(ctx
, 2);
944 int res
= CLIParamHexToBuf(arg_get_str(ctx
, 3), nrar
, sizeof(nrar
), &nalen
);
949 bool use_nrar
= nalen
> 0;
950 bool use_crypto
= arg_get_lit(ctx
, 4);
954 res
= CLIParamHexToBuf(arg_get_str(ctx
, 5), key
, sizeof(key
), &keylen
);
959 // uint32_t page = arg_get_u32_def(ctx, 6, 0);
964 if ((use_ht1
+ use_ht2
+ use_htm
) > 1) {
965 PrintAndLogEx(ERR
, "error, specify only one Hitag type");
968 if ((use_ht1
+ use_ht2
+ use_htm
) == 0) {
969 PrintAndLogEx(ERR
, "error, specify one Hitag type");
973 if (keylen
!= 0 && keylen
!= 4 && keylen
!= 6) {
974 PrintAndLogEx(WARNING
, "Wrong KEY len expected 0, 4 or 6, got %d", keylen
);
978 if (nalen
!= 0 && nalen
!= 8) {
979 PrintAndLogEx(WARNING
, "Wrong NR/AR len expected 0 or 8, got %d", nalen
);
990 if ((keylen
== 0) && use_pwd
) {
991 memcpy(key
, "MIKR", 4);
994 if ((keylen
== 0) && use_crypto
) {
995 memcpy(key
, "ONMIKR", 6);
1000 uint8_t foo
= (use_plain
+ use_pwd
+ use_nrar
+ use_crypto
);
1002 PrintAndLogEx(WARNING
, "Specify only one authentication mode");
1004 } else if (foo
== 0) {
1005 PrintAndLogEx(WARNING
, "Specify one authentication mode");
1009 if (use_ht2
&& use_plain
) { // not sure for the other types...
1010 PrintAndLogEx(WARNING
, "Chosen Hitag type does not have Plain mode");
1014 lf_hitag_data_t packet
;
1015 memset(&packet
, 0, sizeof(packet
));
1018 if (use_ht2
&& use_pwd
) {
1019 pm3cmd
= CMD_LF_HITAG_READER
;
1020 packet
.cmd
= HT2F_PASSWORD
;
1021 memcpy(packet
.pwd
, key
, sizeof(packet
.pwd
));
1023 } else if (use_ht2
&& use_nrar
) {
1024 pm3cmd
= CMD_LF_HITAG_READER
;
1025 packet
.cmd
= HT2F_AUTHENTICATE
;
1026 memcpy(packet
.NrAr
, nrar
, sizeof(packet
.NrAr
));
1027 } else if (use_ht2
&& use_crypto
) {
1029 pm3cmd
= CMD_LF_HITAG_READER
;
1030 packet
.cmd
= HT2F_CRYPTO
;
1031 memcpy(packet
.key
, key
, sizeof(packet
.key
));
1033 PrintAndLogEx(WARNING
, "Sorry, not yet implemented");
1034 return PM3_ENOTIMPL
;
1037 clearCommandBuffer();
1038 SendCommandNG(pm3cmd
, (uint8_t *)&packet
, sizeof(packet
));
1040 PacketResponseNG resp
;
1041 if (WaitForResponseTimeout(pm3cmd
, &resp
, 2000) == false) {
1042 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
1043 SendCommandNG(CMD_BREAK_LOOP
, NULL
, 0);
1044 return PM3_ETIMEOUT
;
1047 if (resp
.status
!= PM3_SUCCESS
) {
1048 PrintAndLogEx(DEBUG
, "DEBUG: Error - hitag failed");
1056 uint8_t *data
= resp
.data
.asBytes
;
1057 uint32_t uid
= bytes_to_num(data
, HITAG_UID_SIZE
);
1058 print_hitag2_configuration(uid
, data
[HITAG_BLOCK_SIZE
* 3]);
1061 print_hitag2_blocks(data
, HITAG2_MAX_BYTE_SIZE
);
1062 print_hitag2_paxton(true, data
);
1064 print_hex_break(data
, HITAG_MAX_BYTE_SIZE
, HITAG_BLOCK_SIZE
);
1069 static int CmdLFHitagSCheckChallenges(const char *Cmd
) {
1071 CLIParserContext
*ctx
;
1072 CLIParserInit(&ctx
, "lf hitag cc",
1073 "Check challenges, load a file with saved hitag crypto challenges and test them all.\n"
1074 "The file should be 8 * 60 bytes long, the file extension defaults to " _YELLOW_("`.cc`") " ",
1075 "lf hitag cc -f my_hitag_challenges"
1078 void *argtable
[] = {
1080 arg_str1("f", "file", "<fn>", "filename to load ( w/o ext )"),
1083 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1086 char filename
[FILE_PATH_SIZE
] = {0};
1087 CLIParamStrToBuf(arg_get_str(ctx
, 1), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
1090 uint8_t *data
= NULL
;
1092 int res
= loadFile_safe(filename
, ".cc", (void **)&data
, &datalen
);
1093 if (res
== PM3_SUCCESS
) {
1096 PrintAndLogEx(ERR
, "Error, file length mismatch. Expected multiple of 8, got " _RED_("%zu"), datalen
);
1100 if (datalen
!= (8 * 60)) {
1101 PrintAndLogEx(ERR
, "Error, file length mismatch. Expected 480, got " _RED_("%zu"), datalen
);
1106 clearCommandBuffer();
1107 SendCommandNG(CMD_LF_HITAGS_TEST_TRACES
, data
, datalen
);
1115 static int CmdLFHitag2CheckChallenges(const char *Cmd
) {
1116 CLIParserContext
*ctx
;
1117 CLIParserInit(&ctx
, "lf hitag ta",
1118 "Test recorded authentications (replay?)",
1123 lf_hitag_data_t packet
;
1124 memset(&packet
, 0, sizeof(lf_hitag_data_t
));
1125 packet
.cmd
= HT2F_TEST_AUTH_ATTEMPTS
;
1127 clearCommandBuffer();
1128 SendCommandNG(CMD_LF_HITAG_READER
, (uint8_t *)&packet
, sizeof(packet
));
1129 PacketResponseNG resp
;
1130 if (WaitForResponseTimeout(CMD_LF_HITAG_READER
, &resp
, 2000) == false) {
1131 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
1132 return PM3_ETIMEOUT
;
1134 if (resp
.status
!= PM3_SUCCESS
) {
1135 PrintAndLogEx(DEBUG
, "DEBUG: Error - hitag failed");
1139 // FIXME: doegox: not sure what this fct does and what it returns...
1143 static int CmdLFHitagWriter(const char *Cmd
) {
1144 CLIParserContext
*ctx
;
1145 CLIParserInit(&ctx
, "lf hitag wrbl",
1146 "Write a page in Hitag memory. It support Hitag 2\n"
1148 " - default key 4D494B52 (MIKR)\n\n"
1150 " - key format ISK high + ISK low\n"
1151 " - default key 4F4E4D494B52 (ONMIKR)\n"
1153 " lf hitag wrbl --ht2 -p 6 -d 01020304 --pwd -> Hitag 2, pwd mode, def key\n"
1154 " lf hitag wrbl --ht2 -p 6 -d 01020304 -k 4D494B52 -> Hitag 2, pwd mode\n"
1155 " lf hitag wrbl --ht2 -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag 2, challenge mode\n"
1156 " lf hitag wrbl --ht2 -p 6 -d 01020304 --crypto -> Hitag 2, crypto mode, def key\n"
1157 " lf hitag wrbl --ht2 -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag 2, crypto mode\n"
1160 void *argtable
[] = {
1162 arg_lit0("2", "ht2", "Hitag 2"),
1163 arg_lit0(NULL
, "pwd", "password mode"),
1164 arg_str0(NULL
, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
1165 arg_lit0(NULL
, "crypto", "crypto mode"),
1166 arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
1167 arg_int1("p", "page", "<dec>", "page address to write to"),
1168 arg_str1("d", "data", "<hex>", "data, 4 hex bytes"),
1171 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
1173 bool use_ht1
= false; // not yet implemented
1174 bool use_ht2
= arg_get_lit(ctx
, 1);
1175 bool use_htm
= false; // not yet implemented
1177 bool use_plain
= false;
1178 bool use_pwd
= arg_get_lit(ctx
, 2);
1181 int res
= CLIParamHexToBuf(arg_get_str(ctx
, 3), nrar
, sizeof(nrar
), &nalen
);
1186 bool use_nrar
= nalen
> 0;
1187 bool use_crypto
= arg_get_lit(ctx
, 4);
1191 res
= CLIParamHexToBuf(arg_get_str(ctx
, 5), key
, sizeof(key
), &keylen
);
1197 int page
= arg_get_int_def(ctx
, 6, 0);
1201 res
= CLIParamHexToBuf(arg_get_str(ctx
, 7), data
, sizeof(data
), &dlen
);
1210 if ((use_ht1
+ use_ht2
+ use_htm
) > 1) {
1211 PrintAndLogEx(ERR
, "error, specify only one Hitag type");
1214 if ((use_ht1
+ use_ht2
+ use_htm
) == 0) {
1215 PrintAndLogEx(ERR
, "error, specify one Hitag type");
1219 if (keylen
!= 0 && keylen
!= 4 && keylen
!= 6) {
1220 PrintAndLogEx(WARNING
, "Wrong KEY len expected 0, 4 or 6, got %d", keylen
);
1224 if (dlen
!= sizeof(data
)) {
1225 PrintAndLogEx(WARNING
, "Wrong DATA len expected 4, got %d", dlen
);
1229 if (nalen
!= 0 && nalen
!= 8) {
1230 PrintAndLogEx(WARNING
, "Wrong NR/AR len expected 0 or 8, got %d", nalen
);
1241 if ((keylen
== 0) && use_pwd
) {
1242 memcpy(key
, "MIKR", 4);
1245 if ((keylen
== 0) && use_crypto
) {
1246 memcpy(key
, "ONMIKR", 6);
1251 uint8_t foo
= (use_plain
+ use_pwd
+ use_nrar
+ use_crypto
);
1253 PrintAndLogEx(WARNING
, "Specify only one authentication mode");
1255 } else if (foo
== 0) {
1256 PrintAndLogEx(WARNING
, "Specify one authentication mode");
1260 if (use_ht2
&& use_plain
) { // not sure for the other types...
1261 PrintAndLogEx(WARNING
, "Chosen Hitag type does not have Plain mode");
1265 lf_hitag_data_t packet
;
1266 memset(&packet
, 0, sizeof(packet
));
1268 if (use_ht2
&& use_pwd
) {
1269 packet
.cmd
= HT2F_PASSWORD
;
1271 memcpy(packet
.pwd
, key
, sizeof(packet
.pwd
));
1272 memcpy(packet
.data
, data
, sizeof(data
));
1273 PrintAndLogEx(INFO
, "Authenticating to " _YELLOW_("Hitag 2") " in Password mode");
1275 } else if (use_ht2
&& use_crypto
) {
1276 packet
.cmd
= HT2F_CRYPTO
;
1278 memcpy(packet
.key
, key
, sizeof(packet
.key
));
1279 memcpy(packet
.data
, data
, sizeof(data
));
1280 PrintAndLogEx(INFO
, "Authenticating to " _YELLOW_("Hitag 2") " in Crypto mode");
1283 PrintAndLogEx(WARNING
, "Sorry, not yet implemented");
1284 return PM3_ENOTIMPL
;
1287 clearCommandBuffer();
1290 SendCommandNG(CMD_LF_HITAG2_WRITE
, (uint8_t *)&packet
, sizeof(packet
));
1291 PacketResponseNG resp
;
1292 if (WaitForResponseTimeout(CMD_LF_HITAG2_WRITE
, &resp
, 4000) == false) {
1293 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
1294 return PM3_ETIMEOUT
;
1297 if (resp
.status
== PM3_ETEAROFF
) {
1298 PrintAndLogEx(INFO
, "Writing tear off triggered");
1302 if (resp
.status
!= PM3_SUCCESS
) {
1303 PrintAndLogEx(FAILED
, "Write ( " _RED_("fail") " )");
1309 PrintAndLogEx(SUCCESS
, "Write ( " _GREEN_("ok") " )");
1313 static int CmdLFHitag2Dump(const char *Cmd
) {
1315 CLIParserContext
*ctx
;
1316 CLIParserInit(&ctx
, "lf hitag dump",
1317 "Read all Hitag 2 card memory and save to file\n"
1318 "Crypto mode key format: ISK high + ISK low, 4F4E4D494B52 (ONMIKR)\n"
1319 "Password mode, default key 4D494B52 (MIKR)\n",
1320 "lf hitag dump --pwd -> use def pwd\n"
1321 "lf hitag dump -k 4D494B52 -> pwd mode\n"
1322 "lf hitag dump --crypto -> use def crypto\n"
1323 "lf hitag dump -k 4F4E4D494B52 -> crypto mode\n"
1324 "lf hitag dump --nrar 0102030411223344\n"
1327 void *argtable
[] = {
1329 arg_lit0(NULL
, "pwd", "password mode"),
1330 arg_str0(NULL
, "nrar", "<hex>", "nonce / answer reader, 8 hex bytes"),
1331 arg_lit0(NULL
, "crypto", "crypto mode"),
1332 arg_str0("k", "key", "<hex>", "key, 4 or 6 hex bytes"),
1333 arg_str0("f", "file", "<fn>", "specify file name"),
1334 arg_lit0(NULL
, "ns", "no save to file"),
1337 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
1339 bool use_ht1
= false; // not yet implemented
1340 bool use_hts
= false; // not yet implemented
1341 bool use_ht2
= true;
1342 bool use_htm
= false; // not yet implemented
1344 bool use_plain
= false;
1345 bool use_pwd
= arg_get_lit(ctx
, 1);
1348 int res
= CLIParamHexToBuf(arg_get_str(ctx
, 2), nrar
, sizeof(nrar
), &nalen
);
1353 bool use_nrar
= nalen
> 0;
1354 bool use_crypto
= arg_get_lit(ctx
, 3);
1356 uint8_t key
[HITAG_NRAR_SIZE
];
1358 res
= CLIParamHexToBuf(arg_get_str(ctx
, 4), key
, sizeof(key
), &keylen
);
1365 char filename
[FILE_PATH_SIZE
] = {0};
1366 CLIParamStrToBuf(arg_get_str(ctx
, 5), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
1368 bool nosave
= arg_get_lit(ctx
, 6);
1372 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) > 1) {
1373 PrintAndLogEx(ERR
, "error, specify only one Hitag type");
1376 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) == 0) {
1377 PrintAndLogEx(ERR
, "error, specify one Hitag type");
1382 keylen
!= HITAG_PASSWORD_SIZE
&&
1383 keylen
!= HITAG_CRYPTOKEY_SIZE
&&
1384 keylen
!= HITAG_NRAR_SIZE
) {
1385 PrintAndLogEx(WARNING
, "Wrong KEY len expected (0,4,6,8) got %d", keylen
);
1390 if (keylen
== HITAG_PASSWORD_SIZE
) {
1393 if (keylen
== HITAG_CRYPTOKEY_SIZE
) {
1396 if (keylen
== HITAG_NRAR_SIZE
) {
1398 memcpy(nrar
, key
, sizeof(nrar
));
1401 // Set default key / pwd
1402 if ((keylen
== 0) && use_pwd
) {
1403 memcpy(key
, "MIKR", HITAG_PASSWORD_SIZE
);
1404 keylen
= HITAG_PASSWORD_SIZE
;
1406 if ((keylen
== 0) && use_crypto
) {
1407 memcpy(key
, "ONMIKR", HITAG_CRYPTOKEY_SIZE
);
1408 keylen
= HITAG_CRYPTOKEY_SIZE
;
1412 uint8_t foo
= (use_plain
+ use_pwd
+ use_nrar
+ use_crypto
);
1414 PrintAndLogEx(WARNING
, "Specify only one authentication mode");
1416 } else if (foo
== 0) {
1420 PrintAndLogEx(WARNING
, "Specify one authentication mode");
1425 if (use_hts
&& use_pwd
) { // not sure for the other types...
1426 PrintAndLogEx(WARNING
, "Chosen Hitag type does not have Password mode");
1430 if (use_ht2
&& use_plain
) { // not sure for the other types...
1431 PrintAndLogEx(WARNING
, "Chosen Hitag type does not have Plain mode");
1437 PacketResponseNG resp
;
1438 uint8_t *data
= NULL
;
1440 lf_hitag_data_t packet
;
1441 memset(&packet
, 0, sizeof(packet
));
1443 if (use_ht2
&& use_pwd
) {
1444 packet
.cmd
= HT2F_PASSWORD
;
1445 memcpy(packet
.pwd
, key
, sizeof(packet
.pwd
));
1446 PrintAndLogEx(INFO
, "Authenticating to " _YELLOW_("Hitag 2") " in Password mode");
1448 } else if (use_ht2
&& use_crypto
) {
1449 packet
.cmd
= HT2F_CRYPTO
;
1450 memcpy(packet
.key
, key
, sizeof(packet
.key
));
1451 PrintAndLogEx(INFO
, "Authenticating to " _YELLOW_("Hitag 2") " in Crypto mode");
1453 } else if (use_ht2
&& use_nrar
) {
1456 memcpy(packet
.NrAr
, nrar
, sizeof(packet
.NrAr
));
1458 PrintAndLogEx(INFO
, _YELLOW_("Hitag 2") " - Challenge mode (NrAr)");
1460 uint64_t t1
= msclock();
1462 clearCommandBuffer();
1463 SendCommandNG(CMD_LF_HITAG2_CRACK
, (uint8_t *) &packet
, sizeof(packet
));
1466 uint8_t attempt
= 30;
1469 PrintAndLogEx(INPLACE
, "Attack 1 running...");
1472 if (WaitForResponseTimeout(CMD_LF_HITAG2_CRACK
, &resp
, 1000) == false) {
1477 lf_hitag_crack_response_t
*payload
= (lf_hitag_crack_response_t
*)resp
.data
.asBytes
;
1479 if (resp
.status
== PM3_SUCCESS
) {
1480 PrintAndLogEx(NORMAL
, " ( %s )", _GREEN_("ok"));
1481 data
= payload
->data
;
1483 t1
= msclock() - t1
;
1484 PrintAndLogEx(SUCCESS
, "\ntime " _YELLOW_("%.0f") " seconds\n", (float)t1
/ 1000.0);
1489 switch (payload
->status
) {
1491 PrintAndLogEx(NORMAL
, "");
1492 PrintAndLogEx(FAILED
, "Couldn't select tag!");
1496 PrintAndLogEx(NORMAL
, "");
1497 PrintAndLogEx(FAILED
, "Cannot find a valid encrypted command!");
1501 PrintAndLogEx(NORMAL
, "");
1502 PrintAndLogEx(FAILED
, "Cannot find encrypted 'read page0' command!");
1506 PrintAndLogEx(NORMAL
, "");
1507 PrintAndLogEx(FAILED
, "Partial data extraction!");
1515 PrintAndLogEx(NORMAL
, "");
1516 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
1520 t1
= msclock() - t1
;
1521 PrintAndLogEx(SUCCESS
, "\ntime " _YELLOW_("%.0f") " seconds\n", (float)t1
/ 1000.0);
1526 PrintAndLogEx(WARNING
, "Sorry, not yet implemented");
1527 return PM3_ENOTIMPL
;
1530 clearCommandBuffer();
1531 SendCommandNG(CMD_LF_HITAG_READER
, (uint8_t *) &packet
, sizeof(packet
));
1533 if (WaitForResponseTimeout(CMD_LF_HITAG_READER
, &resp
, 5000) == false) {
1534 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
1535 return PM3_ETIMEOUT
;
1537 if (resp
.status
!= PM3_SUCCESS
) {
1538 PrintAndLogEx(DEBUG
, "DEBUG: Error - hitag failed");
1542 data
= resp
.data
.asBytes
;
1548 uid
= bytes_to_num(data
, HITAG_UID_SIZE
);
1551 print_hitag2_configuration(uid
, data
[HITAG_BLOCK_SIZE
* 3]);
1552 print_hitag2_blocks(data
, HITAG2_MAX_BYTE_SIZE
);
1553 print_hitag2_paxton(true, data
);
1555 PrintAndLogEx(INFO
, "No memory printing available");
1559 PrintAndLogEx(NORMAL
, "");
1560 PrintAndLogEx(INFO
, "Called with no save option");
1561 PrintAndLogEx(NORMAL
, "");
1566 char *fptr
= filename
;
1567 fptr
+= snprintf(filename
, sizeof(filename
), "lf-hitag-");
1568 FillFileNameByUID(fptr
, data
, "-dump", HITAG_UID_SIZE
);
1571 pm3_save_dump(filename
, data
, HITAG2_MAX_BYTE_SIZE
, jsfHitag
);
1575 static int CmdLFHitagView(const char *Cmd
) {
1577 CLIParserContext
*ctx
;
1578 CLIParserInit(&ctx
, "lf hitag view",
1579 "Print a HITAG dump file (bin/eml/json)",
1580 "lf hitag view -f lf-hitag-01020304-dump.bin"
1582 void *argtable
[] = {
1584 arg_str1("f", "file", "<fn>", "Specify a filename for dump file"),
1585 arg_lit0("v", "verbose", "Verbose output"),
1588 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
1590 char filename
[FILE_PATH_SIZE
];
1591 CLIParamStrToBuf(arg_get_str(ctx
, 1), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
1592 bool verbose
= arg_get_lit(ctx
, 2);
1596 uint8_t *dump
= NULL
;
1597 size_t bytes_read
= 0;
1598 int res
= pm3_load_dump(filename
, (void **)&dump
, &bytes_read
, HITAG2_MAX_BYTE_SIZE
);
1599 if (res
!= PM3_SUCCESS
) {
1603 if (bytes_read
< HITAG2_MAX_BYTE_SIZE
) {
1604 PrintAndLogEx(ERR
, "Error, dump file is too small");
1611 uint8_t config
= dump
[HITAG2_CONFIG_OFFSET
];
1612 uint32_t uid
= bytes_to_num(dump
, HITAG_UID_SIZE
);
1613 print_hitag2_configuration(uid
, config
);
1614 print_hitag2_paxton(true, dump
);
1616 print_hitag2_blocks(dump
, HITAG2_MAX_BYTE_SIZE
);
1621 static int CmdLFHitagEload(const char *Cmd
) {
1622 CLIParserContext
*ctx
;
1623 CLIParserInit(&ctx
, "lf hitag eload",
1624 "Loads hitag tag dump into emulator memory on device",
1625 "lf hitag eload -2 -f lf-hitag-11223344-dump.bin\n"
1627 void *argtable
[] = {
1629 arg_str1("f", "file", "<fn>", "Specify dump filename"),
1630 arg_lit0("1", "ht1", "Card type Hitag 1"),
1631 arg_lit0("2", "ht2", "Card type Hitag 2"),
1632 arg_lit0("s", "hts", "Card type Hitag S"),
1633 arg_lit0("m", "htm", "Card type Hitag \xce\xbc"), // μ
1636 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
1639 char filename
[FILE_PATH_SIZE
] = {0};
1640 CLIParamStrToBuf(arg_get_str(ctx
, 1), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
1642 bool use_ht1
= arg_get_lit(ctx
, 2);
1643 bool use_ht2
= arg_get_lit(ctx
, 3);
1644 bool use_hts
= arg_get_lit(ctx
, 4);
1645 bool use_htm
= arg_get_lit(ctx
, 5);
1648 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) > 1) {
1649 PrintAndLogEx(ERR
, "error, specify only one Hitag type");
1652 if ((use_ht1
+ use_ht2
+ use_hts
+ use_htm
) == 0) {
1653 PrintAndLogEx(ERR
, "error, specify one Hitag type");
1658 uint8_t *dump
= NULL
;
1659 size_t bytes_read
= (4 * 64);
1660 int res
= pm3_load_dump(filename
, (void **)&dump
, &bytes_read
, (4 * 64));
1661 if (res
!= PM3_SUCCESS
) {
1666 if (bytes_read
== HITAG2_MAX_BYTE_SIZE
|| bytes_read
== 4 * 64) {
1668 lf_hitag_t
*payload
= calloc(1, sizeof(lf_hitag_t
) + bytes_read
);
1679 payload
->len
= bytes_read
;
1680 memcpy(payload
->data
, dump
, bytes_read
);
1682 clearCommandBuffer();
1683 SendCommandNG(CMD_LF_HITAG_ELOAD
, (uint8_t *)payload
, 3 + bytes_read
);
1686 PrintAndLogEx(ERR
, "error, wrong dump file size. got %zu", bytes_read
);
1693 static int CmdLFHitagEview(const char *Cmd
) {
1694 CLIParserContext
*ctx
;
1695 CLIParserInit(&ctx
, "lf hitag eview",
1696 "It displays emulator memory",
1699 void *argtable
[] = {
1701 arg_lit0("v", "verbose", "Verbose output"),
1704 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1705 bool verbose
= arg_get_lit(ctx
, 1);
1708 int bytes
= HITAG2_MAX_BYTE_SIZE
;
1711 uint8_t *dump
= calloc(bytes
, sizeof(uint8_t));
1713 PrintAndLogEx(WARNING
, "Fail, cannot allocate memory");
1717 PrintAndLogEx(INFO
, "Downloading " _YELLOW_("%u") " bytes from emulator memory...", bytes
);
1718 if (GetFromDevice(BIG_BUF_EML
, dump
, bytes
, 0, NULL
, 0, NULL
, 2500, false) == false) {
1719 PrintAndLogEx(WARNING
, "Fail, transfer from device time-out");
1721 return PM3_ETIMEOUT
;
1726 uint8_t config
= dump
[HITAG2_CONFIG_OFFSET
];
1727 uint32_t uid
= bytes_to_num(dump
, HITAG_UID_SIZE
);
1728 print_hitag2_configuration(uid
, config
);
1729 print_hitag2_paxton(true, dump
);
1731 print_hitag2_blocks(dump
, HITAG2_MAX_BYTE_SIZE
);
1736 static int CmdLFHitagSim(const char *Cmd
) {
1737 CLIParserContext
*ctx
;
1738 CLIParserInit(&ctx
, "lf hitag sim",
1739 "Simulate Hitag transponder\n"
1740 "You need to `lf hitag eload` first",
1744 void *argtable
[] = {
1746 arg_lit0("1", "ht1", "simulate Hitag 1"),
1747 arg_lit0("2", "ht2", "simulate Hitag 2"),
1750 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1752 bool use_ht1
= arg_get_lit(ctx
, 1);
1753 bool use_ht2
= arg_get_lit(ctx
, 2);
1754 bool use_htm
= false; // not implemented yet
1757 if ((use_ht1
+ use_ht2
+ use_htm
) > 1) {
1758 PrintAndLogEx(ERR
, "error, specify only one Hitag type");
1761 if ((use_ht1
+ use_ht2
+ use_htm
) == 0) {
1762 PrintAndLogEx(ERR
, "error, specify one Hitag type");
1766 uint16_t cmd
= CMD_LF_HITAG_SIMULATE
;
1768 // cmd = CMD_LF_HITAG1_SIMULATE;
1770 clearCommandBuffer();
1771 SendCommandMIX(cmd
, 0, 0, 0, NULL
, 0);
1775 static int CmdLFHitagSniff(const char *Cmd
) {
1776 CLIParserContext
*ctx
;
1777 CLIParserInit(&ctx
, "lf hitag sniff",
1778 "Sniff the communication between reader and tag\n"
1779 "Use `lf hitag list` to view collected data.",
1783 void *argtable
[] = {
1787 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1790 PrintAndLogEx(INFO
, "Press " _GREEN_("pm3 button") " to abort sniffing");
1792 PacketResponseNG resp
;
1793 clearCommandBuffer();
1794 SendCommandNG(CMD_LF_HITAG_SNIFF
, NULL
, 0);
1795 WaitForResponse(CMD_LF_HITAG_SNIFF
, &resp
);
1796 PrintAndLogEx(INFO
, "Done!");
1797 PrintAndLogEx(HINT
, "Try `" _YELLOW_("lf hitag list")"` to view captured tracelog");
1798 PrintAndLogEx(HINT
, "Try `" _YELLOW_("trace save -h") "` to save tracelog for later analysing");
1803 static int CmdLFHitag2PWMDemod(const char *Cmd) {
1805 CLIParserContext *ctx;
1806 CLIParserInit(&ctx, "lf hitag pwmdemod",
1807 "Demodulate the data in the GraphBuffer and output binary\n",
1809 "lf hitag pwmdemod -t 65 --> specify first wave index\n"
1812 void *argtable[] = {
1814 arg_int0("t", "start", "<dec>", "first wave index"),
1815 arg_int0(NULL, "zero", "<dec>", "Zero pulse length"),
1816 arg_int0(NULL, "one", "<dec>", "One pulse length"),
1820 CLIExecWithReturn(ctx, Cmd, argtable, true);
1821 uint32_t start_idx = (uint32_t)arg_get_int_def(ctx, 1, 0);
1822 uint8_t fclow = (uint8_t)arg_get_int_def(ctx, 2, 20);
1823 uint8_t fchigh = (uint8_t)arg_get_int_def(ctx, 3, 29);
1826 uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t));
1828 PrintAndLogEx(INFO, "failed to allocate memory");
1832 size_t size = getFromGraphBuffer(bits);
1834 PrintAndLogEx(DEBUG, "DEBUG: (Hitag2PWM) #samples from graphbuff... %zu", size);
1837 PrintAndLogEx(INFO, "too few samples in buffer");
1843 size = HitagPWMDemod(bits, size, &fchigh, &fclow, &start_idx, g_DemodBitRangeBuffer);
1845 PrintAndLogEx(FAILED, "No wave detected");
1850 PrintAndLogEx(DEBUG, "DEBUG: start_idx... %u size... %zu", start_idx, size);
1852 setDemodBuffBitRange(bits, size, 0, g_DemodBitRangeBuffer);
1853 setClockGrid(32, start_idx);
1856 for (size_t i = 0; i < size; i++) {
1857 total += g_DemodBitRangeBuffer[i];
1858 PrintAndLogEx(DEBUG, "%d", g_DemodBitRangeBuffer[i]);
1860 PrintAndLogEx(DEBUG, "Total... %d", total);
1862 PrintAndLogEx(NORMAL, "");
1863 PrintAndLogEx(INFO, "--- " _CYAN_("HITAG/PWM") " ---------------------------");
1864 printDemodBuff(0, false, false, false);
1865 printDemodBuff(0, false, false, true);
1871 static int CmdLFHitag2Chk(const char *Cmd
) {
1873 CLIParserContext
*ctx
;
1874 CLIParserInit(&ctx
, "lf hitag chk",
1875 "Run dictionary key or password recovery against Hitag card.",
1876 "lf hitag chk\n -> checks for both pwd / crypto keys"
1877 "lf hitag chk --crypto -> use def dictionary\n"
1878 "lf hitag chk --pwd -f my.dic -> pwd mode, custom dictionary"
1881 void *argtable
[] = {
1883 arg_str0("f", "file", "<fn>", "specify dictionary filename"),
1884 arg_lit0(NULL
, "pwd", "password mode"),
1885 arg_lit0(NULL
, "crypto", "crypto mode"),
1889 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
1891 char filename
[FILE_PATH_SIZE
] = {0};
1892 CLIParamStrToBuf(arg_get_str(ctx
, 1), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
1894 bool use_pwd
= arg_get_lit(ctx
, 2);
1895 bool use_crypto
= arg_get_lit(ctx
, 3);
1898 if (use_pwd
+ use_crypto
> 1) {
1899 PrintAndLogEx(WARNING
, "Only specify one mode");
1903 // no filename -> use default = ht2_default.dic
1905 snprintf(filename
, sizeof(filename
), HITAG_DICTIONARY
);
1913 uint64_t t1
= msclock();
1915 // just loop twice at max. Starting with 4 or 6.
1916 for (; keylen
< 7; keylen
+= 2) {
1918 uint8_t *keys
= NULL
;
1919 uint32_t key_count
= 0;
1920 int res
= loadFileDICTIONARY_safe(filename
, (void **)&keys
, keylen
, &key_count
);
1921 if (res
!= PM3_SUCCESS
|| key_count
== 0 || keys
== NULL
) {
1922 PrintAndLogEx(WARNING
, "no keys found in file");
1930 uint32_t found_idx
= 0;
1931 int status
= ht2_check_dictionary(key_count
, keys
, keylen
, &found_idx
);
1933 if (status
== PM3_SUCCESS
) {
1935 PrintAndLogEx(NORMAL
, "");
1937 PrintAndLogEx(SUCCESS
, "found valid key [ " _GREEN_("%s") " ]", sprint_hex_inrow(keys
+ (found_idx
* keylen
), keylen
));
1939 PrintAndLogEx(SUCCESS
, "found valid password [ " _GREEN_("%s") " ]", sprint_hex_inrow(keys
+ (found_idx
* keylen
), keylen
));
1947 t1
= msclock() - t1
;
1948 PrintAndLogEx(SUCCESS
, "\ntime in check " _YELLOW_("%.0f") " seconds\n", (float)t1
/ 1000.0);
1952 static int CmdLFHitag2Lookup(const char *Cmd
) {
1954 CLIParserContext
*ctx
;
1955 CLIParserInit(&ctx
, "lf hitag lookup",
1956 "This command take sniffed trace data and try to recovery a Hitag 2 crypto key.\n"
1958 " - verify that NR/AR matches a known crypto key\n"
1959 " - verify if NR/AR matches a known 6 byte crypto key in a dictionary",
1960 "lf hitag lookup --uid 11223344 --nr 73AA5A62 --ar EAB8529C -k 010203040506 -> check key\n"
1961 "lf hitag lookup --uid 11223344 --nr 73AA5A62 --ar EAB8529C -> use def dictionary\n"
1962 "lf hitag lookup --uid 11223344 --nr 73AA5A62 --ar EAB8529C -f my.dic -> use custom dictionary\n"
1963 "lf hitag lookup --uid 11223344 --nrar 73AA5A62EAB8529C"
1966 void *argtable
[] = {
1968 arg_str0("f", "file", "<fn>", "specify dictionary filename"),
1969 arg_str0("k", "key", "<hex>", "specify known cryptokey as 6 bytes"),
1970 arg_str1("u", "uid", "<hex>", "specify UID as 4 hex bytes"),
1971 arg_str0(NULL
, "nr", "<hex>", "specify nonce as 4 hex bytes"),
1972 arg_str0(NULL
, "ar", "<hex>", "specify answer as 4 hex bytes"),
1973 arg_str0(NULL
, "nrar", "<hex>", "specify nonce / answer as 8 hex bytes"),
1977 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
1979 char filename
[FILE_PATH_SIZE
] = {0};
1980 CLIParamStrToBuf(arg_get_str(ctx
, 1), (uint8_t *)filename
, FILE_PATH_SIZE
, &fnlen
);
1983 uint8_t inkey
[6] = {0};
1984 CLIGetHexWithReturn(ctx
, 2, inkey
, &inkeylen
);
1987 uint8_t uidarr
[4] = {0};
1988 CLIGetHexWithReturn(ctx
, 3, uidarr
, &ulen
);
1991 uint8_t narr
[4] = {0};
1992 CLIGetHexWithReturn(ctx
, 4, narr
, &nlen
);
1995 uint8_t aarr
[4] = {0};
1996 CLIGetHexWithReturn(ctx
, 5, aarr
, &alen
);
1999 uint8_t nrar
[8] = {0};
2000 CLIGetHexWithReturn(ctx
, 6, nrar
, &nalen
);
2005 if (inkeylen
&& inkeylen
!= 6) {
2006 PrintAndLogEx(INFO
, "Key wrong length. expected 6, got %i", inkeylen
);
2010 if (ulen
&& ulen
!= 4) {
2011 PrintAndLogEx(INFO
, "UID wrong length. expected 4, got %i", ulen
);
2015 if (nlen
&& nlen
!= 4) {
2016 PrintAndLogEx(INFO
, "Nr wrong length. expected 4, got %i", nlen
);
2020 if (alen
&& alen
!= 4) {
2021 PrintAndLogEx(INFO
, "Ar wrong length. expected 4, got %i", alen
);
2025 if (nalen
&& nalen
!= 8) {
2026 PrintAndLogEx(INFO
, "NrAr wrong length. expected 8, got %i", nalen
);
2031 // - key, uid and Nr1 is alway dentoed as LSB/LE order
2032 // - Ar1 is NOT. It is in BE/MSB everywhere.
2033 // - At1 is NOT. It is in BE/MSB everywhere.
2034 // - crypto stream generated is in BE/MSB order in Pm3 code.
2035 // - crypto state is in ?
2036 // - lfsr state is in ?
2038 // Different implementations handles internally the state either in MSB or LSB.
2039 // Something to keep an eye for when looking at code.
2042 // cs / hstate.shiftregister / crypto state = same
2043 // lsfr = some implementations mixes cs and lsfr into one and only use the state. Some differentiate between them.
2044 // usually the key recovery functions under /tools/hitag2crack
2045 // IV / Nonce Reader 1 / Nr1 = same (clear text), always 00 00 00 00 in PM3 code when acting as reader.
2046 // Answer Reader 1 / Ar1 = encrypted and BE/MSB, +32, the clear text is always FF FF FF FF.
2047 // Answer Tag 1 / At1 = encrypted and BE/MSB, +32,
2050 When initializer the crypto engine
2053 2. KEY: FFFF143624FF
2054 3. NONCE / IV: 00 00 00 00
2055 3. NONCE / IV: 3B 6F 08 4D
2057 now you have a CS / Shiftregister / state = crypto stream?
2059 Ar1 - first encrypted crypto stream ^ 0xFFFFFFFF
2060 4. Ar1: 96 7A 6F 2A ^ FF FF FF FF == 69 85 90 D5
2063 rev_msb_array(inkey
, sizeof(inkey
));
2064 rev_msb_array(uidarr
, sizeof(uidarr
));
2065 rev_msb_array(narr
, sizeof(narr
));
2066 rev_msb_array(nrar
, 4);
2070 uint64_t knownkey
= MemLeToUint6byte(inkey
);
2071 uint32_t uid
= MemLeToUint4byte(uidarr
);
2078 nr
= MemLeToUint4byte(narr
);
2079 ar
= MemBeToUint4byte(aarr
);
2081 nr
= MemLeToUint4byte(nrar
);
2082 ar
= MemBeToUint4byte(nrar
+ 4);
2084 PrintAndLogEx(INFO
, "No nr or ar was supplied");
2093 PrintAndLogEx(DEBUG
, "UID... %08" PRIx32
, uid
);
2094 PrintAndLogEx(DEBUG
, "IV.... %08" PRIx32
, iv
);
2095 PrintAndLogEx(DEBUG
, "Key... %012" PRIx64
, knownkey
);
2098 hitag_state_t hstate
;
2099 ht2_hitag2_init_ex(&hstate
, knownkey
, uid
, iv
);
2101 // get 32 bits of crypto stream.
2102 uint32_t cbits
= ht2_hitag2_nstep(&hstate
, 32);
2103 bool isok
= (ar
== (cbits
^ 0xFFFFFFFF));
2105 PrintAndLogEx(DEBUG
, "state.shiftreg...... %012" PRIx64
, hstate
.shiftreg
);
2106 PrintAndLogEx(DEBUG
, "state.lfsr.......... %012" PRIx64
, hstate
.lfsr
);
2107 PrintAndLogEx(DEBUG
, "c bits.............. %08x", cbits
);
2108 PrintAndLogEx(DEBUG
, "c-bits ^ FFFFFFFF... %08x", cbits
^ 0xFFFFFFFF);
2109 PrintAndLogEx(DEBUG
, "Ar.................. %08" PRIx32
" ( %s )", ar
, (isok
) ? _GREEN_("ok") : _RED_("fail"));
2111 PrintAndLogEx(INFO
, "Nr/Ar match key ( %s )", (isok
) ? _GREEN_("ok") : _RED_("fail"));
2112 PrintAndLogEx(NORMAL
, "");
2117 snprintf(filename
, sizeof(filename
), HITAG_DICTIONARY
);
2121 uint8_t *keys
= NULL
;
2122 uint32_t key_count
= 0;
2123 int res
= loadFileDICTIONARY_safe(filename
, (void **)&keys
, HITAG_CRYPTOKEY_SIZE
, &key_count
);
2124 if (res
!= PM3_SUCCESS
|| key_count
== 0 || keys
== NULL
) {
2125 PrintAndLogEx(WARNING
, "no keys found in file");
2133 for (uint32_t i
= 0; i
< key_count
; i
++) {
2135 uint8_t *pkey
= keys
+ (i
* HITAG_CRYPTOKEY_SIZE
);
2136 uint64_t mykey
= MemLeToUint6byte(pkey
);
2137 mykey
= REV64(mykey
);
2140 ht2_hitag2_init_ex(&hs2
, mykey
, uid
, iv
);
2142 uint32_t tbits
= ht2_hitag2_nstep(&hs2
, 32);
2143 if ((ar
^ tbits
) == 0xFFFFFFFF) {
2144 PrintAndLogEx(SUCCESS
, "Found valid key [ " _GREEN_("%s")" ]", sprint_hex_inrow(pkey
, HITAG_CRYPTOKEY_SIZE
));
2150 PrintAndLogEx(DEBUG
, " tbits... %08" PRIx32
" Known ar... %08" PRIx32
, tbits
, ar
);
2151 PrintAndLogEx(DEBUG
, " 0xFFFFFFFF ^ tbits... %08" PRIx32
, tbits
^ 0xFFFFFFFF);
2152 PrintAndLogEx(DEBUG
, " 0xFFFFFFFF ^ ar...... %08" PRIx32
, ar
^ 0xFFFFFFFF);
2153 PrintAndLogEx(DEBUG
, " tbits ^ ar........... %08" PRIx32
" ( 0xFFFFFFFF )", ar
^ tbits
);
2159 if (found
== false) {
2160 PrintAndLogEx(WARNING
, "check failed");
2163 PrintAndLogEx(NORMAL
, "");
2167 static int CmdLFHitag2Crack2(const char *Cmd
) {
2168 CLIParserContext
*ctx
;
2169 CLIParserInit(&ctx
, "lf hitag crack2",
2170 "This command tries to recover 2048 bits of Hitag 2 crypto stream data.\n",
2171 "lf hitag crack2 --nrar 73AA5A62EAB8529C"
2174 void *argtable
[] = {
2176 arg_str0(NULL
, "nrar", "<hex>", "specify nonce / answer as 8 hex bytes"),
2180 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
2182 uint8_t nrar
[8] = {0};
2183 CLIGetHexWithReturn(ctx
, 1, nrar
, &nalen
);
2187 if (nalen
&& nalen
!= 8) {
2188 PrintAndLogEx(INFO
, "NrAr wrong length. expected 8, got %i", nalen
);
2192 lf_hitag_data_t packet
;
2193 memset(&packet
, 0, sizeof(packet
));
2194 memcpy(packet
.NrAr
, nrar
, sizeof(packet
.NrAr
));
2196 PrintAndLogEx(INFO
, _YELLOW_("Hitag 2") " - Nonce replay and length extension attack ( Crack2 )");
2198 uint64_t t1
= msclock();
2200 PacketResponseNG resp
;
2201 clearCommandBuffer();
2202 SendCommandNG(CMD_LF_HITAG2_CRACK_2
, (uint8_t *) &packet
, sizeof(packet
));
2205 uint8_t attempt
= 50;
2208 // PrintAndLogEx(INPLACE, "Attack 2 running...");
2211 if (WaitForResponseTimeout(CMD_LF_HITAG2_CRACK_2
, &resp
, 1000) == false) {
2216 if (resp
.status
== PM3_SUCCESS
) {
2218 PrintAndLogEx(SUCCESS
, "--------------------- " _CYAN_("Recovered Keystream") " ----------------------");
2219 lf_hitag_crack_response_t
*payload
= (lf_hitag_crack_response_t
*)resp
.data
.asBytes
;
2221 for (int i
= 0; i
< 256; i
+= 32) {
2222 PrintAndLogEx(SUCCESS
, "%s", sprint_hex_inrow(payload
->data
+ i
, 32));
2224 PrintAndLogEx(NORMAL
, "");
2225 PrintAndLogEx(SUCCESS
, "Nonce replay and length extension attack ( %s )", _GREEN_("ok"));
2226 PrintAndLogEx(HINT
, "try running `tools/hitag2crack/crack2/ht2crack2search <FILE_with_above_bytes>");
2229 PrintAndLogEx(NORMAL
, "");
2230 PrintAndLogEx(FAILED
, "Nonce replay and length extension attack ( %s )", _RED_("fail"));
2237 PrintAndLogEx(NORMAL
, "");
2238 PrintAndLogEx(WARNING
, "timeout while waiting for reply.");
2242 t1
= msclock() - t1
;
2243 PrintAndLogEx(SUCCESS
, "\ntime " _YELLOW_("%.0f") " seconds\n", (float)t1
/ 1000.0);
2249 Test data and below information about it comes from
2250 http://www.mikrocontroller.net/attachment/102194/hitag2.c
2251 Written by "I.C. Wiener 2006-2007"
2253 "MIKRON" = O N M I K R
2254 Key = 4F 4E 4D 49 4B 52 - Secret 48-bit key
2255 Serial = 49 43 57 69 - Serial number of the tag, transmitted in clear
2256 Random = 65 6E 45 72 - Random IV, transmitted in clear
2257 ~28~DC~80~31 = D7 23 7F CE - Authenticator value = inverted first 4 bytes of the keystream
2259 The code below must print out "D7 23 7F CE 8C D0 37 A9 57 49 C1 E6 48 00 8A B6".
2260 The inverse of the first 4 bytes is sent to the tag to authenticate.
2261 The rest is encrypted by XORing it with the subsequent keystream.
2263 static uint64_t hitag2_benchtest_gen32(void) {
2264 const uint64_t key
= 0x4ad292b272f2;
2265 const uint32_t serial
= 0x96eac292;
2266 const uint32_t initvec
= 0x4ea276a6;
2267 hitag_state_t state
;
2270 ht2_hitag2_init_ex(&state
, key
, serial
, initvec
);
2272 // benchmark: generation of 32 bit stream (excludes initialisation)
2273 uint64_t t1
= usclock();
2275 (void) ht2_hitag2_nstep(&state
, 32);
2277 t1
= usclock() - t1
;
2281 static uint64_t hitag2_benchtest(uint32_t count
) {
2283 const uint64_t key
= 0x4ad292b272f2;
2284 const uint32_t serial
= 0x96eac292;
2285 const uint32_t initvec
= 0x4ea276a6;
2287 hitag_state_t state
;
2290 uint64_t t1
= usclock();
2292 // benchmark: initialise crypto & generate 32 bit authentication
2293 // adding i stops gcc optimizer moving init function call out of loop
2294 for (uint32_t i
= 0; i
< count
; i
++) {
2295 ht2_hitag2_init_ex(&state
, key
, serial
, initvec
+ i
);
2296 (void) ht2_hitag2_nstep(&state
, 32);
2299 t1
= usclock() - t1
;
2303 static uint64_t hitag2_verify_crypto_test(void) {
2305 uint8_t expected
[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 };
2306 // key = 0x4ad292b272f2 after each byte has its bit order reversed
2307 // uid = 0x96eac292 ditto
2308 // initvec = 0x4ea276a6 ditto
2309 const uint64_t key
= REV64(0x524B494D4E4FUL
);
2310 const uint32_t uid
= REV32(0x69574349);
2311 const uint32_t iv
= REV32(0x72456E65);
2313 PrintAndLogEx(DEBUG
, "UID... %08" PRIx32
, uid
);
2314 PrintAndLogEx(DEBUG
, "IV.... %08" PRIx32
, iv
);
2315 PrintAndLogEx(DEBUG
, "Key... %012" PRIx64
, key
);
2318 hitag_state_t state
;
2319 ht2_hitag2_init_ex(&state
, key
, uid
, iv
);
2320 PrintAndLogEx(DEBUG
, "hs shiftreg... %012" PRIx64
, state
.shiftreg
);
2322 for (uint32_t i
= 0; i
< 16; i
++) {
2323 // get 8 bits of keystream
2324 uint8_t x
= (uint8_t) ht2_hitag2_nstep(&state
, 8);
2325 uint8_t y
= expected
[i
];
2327 PrintAndLogEx(DEBUG
, "%02X (%02X)", x
, y
);
2335 static uint64_t hitag2_verify_crypto_test_round(void) {
2337 uint8_t expected
[16] = { 0xD7, 0x23, 0x7F, 0xCE, 0x8C, 0xD0, 0x37, 0xA9, 0x57, 0x49, 0xC1, 0xE6, 0x48, 0x00, 0x8A, 0xB6 };
2338 const uint64_t key
= REV64(0x524B494D4E4FUL
);
2339 const uint32_t uid
= REV32(0x69574349);
2340 const uint32_t iv
= REV32(0x72456E65);
2342 PrintAndLogEx(DEBUG
, "UID... %08" PRIx32
, uid
);
2343 PrintAndLogEx(DEBUG
, "IV.... %08" PRIx32
, iv
);
2344 PrintAndLogEx(DEBUG
, "Key... %012" PRIx64
, key
);
2347 uint64_t cs
= ht2_hitag2_init(key
, uid
, iv
);
2348 PrintAndLogEx(DEBUG
, "hs shiftreg... %012" PRIx64
, cs
);
2350 for (uint32_t i
= 0; i
< 16; i
++) {
2351 // get 8 bits of keystream
2352 uint8_t x
= (uint8_t) ht2_hitag2_byte(&cs
);
2353 uint8_t y
= expected
[i
];
2355 PrintAndLogEx(DEBUG
, "%02X (%02X)", x
, y
);
2363 static int CmdLFHitag2Selftest(const char *Cmd
) {
2364 CLIParserContext
*ctx
;
2365 CLIParserInit(&ctx
, "lf hitag test",
2366 "Perform self tests of Hitag crypto engine",
2370 void *argtable
[] = {
2374 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
2377 PrintAndLogEx(INFO
, "======== " _CYAN_("Hitag 2 crypto test") " ============================");
2378 uint64_t test
= hitag2_verify_crypto_test();
2379 PrintAndLogEx(INFO
, "Crypto self test ( %s )", test
? _GREEN_("ok") : _RED_("fail"));
2381 test
|= hitag2_verify_crypto_test_round();
2382 PrintAndLogEx(INFO
, "Crypto self test ROUND ( %s )", test
? _GREEN_("ok") : _RED_("fail"));
2384 test
|= hitag2_benchtest(1);
2385 PrintAndLogEx(INFO
, "Hitag 2 crypto, init + gen 32 bits ( us %" PRIu64
" )", test
);
2387 test
|= hitag2_benchtest_gen32();
2388 PrintAndLogEx(INFO
, "Hitag 2 crypto, gen new 32 bits only ( us: %" PRIu64
" )", test
);
2390 test
|= hitag2_benchtest(1000);
2391 PrintAndLogEx(INFO
, "Hitag 2 crypto, init + gen 32 bits, x1000 ( us: %" PRIu64
" )", test
);
2393 PrintAndLogEx(INFO
, "--------------------------------------------------------");
2394 PrintAndLogEx(SUCCESS
, "Tests ( %s )", (test
) ? _GREEN_("ok") : _RED_("fail"));
2395 PrintAndLogEx(NORMAL
, "");
2399 int ht2_read_uid(void) {
2401 if (ht2_get_uid(&uid
) == false) {
2405 PrintAndLogEx(SUCCESS
, "UID.... " _GREEN_("%08X"), uid
);
2406 PrintAndLogEx(SUCCESS
, "TYPE... " _GREEN_("%s"), getHitagTypeStr(uid
));
2410 int ht2_read_paxton(void) {
2412 // read block 4,5,6,7
2414 lf_hitag_data_t packet
;
2415 memset(&packet
, 0, sizeof(packet
));
2417 packet
.cmd
= HT2F_PASSWORD
;
2418 memcpy(packet
.pwd
, ht2_default_keys
, sizeof(packet
.pwd
));
2420 clearCommandBuffer();
2421 SendCommandNG(CMD_LF_HITAG_READER
, (uint8_t *)&packet
, sizeof(packet
));
2423 PacketResponseNG resp
;
2424 if (WaitForResponseTimeout(CMD_LF_HITAG_READER
, &resp
, 2000) == false) {
2425 SendCommandNG(CMD_BREAK_LOOP
, NULL
, 0);
2426 return PM3_ETIMEOUT
;
2429 if (resp
.status
!= PM3_SUCCESS
) {
2430 PrintAndLogEx(DEBUG
, "DEBUG: Error - hitag failed");
2434 uint8_t *data
= resp
.data
.asBytes
;
2435 print_hitag2_paxton(false, data
);
2439 static command_t CommandTable
[] = {
2440 {"help", CmdHelp
, AlwaysAvailable
, "This help"},
2441 {"list", CmdLFHitagList
, AlwaysAvailable
, "List Hitag trace history"},
2442 {"hts", CmdLFHitagS
, AlwaysAvailable
, "{ Hitag S/8211 operations }"},
2443 {"-----------", CmdHelp
, IfPm3Hitag
, "------------------------ " _CYAN_("General") " ------------------------"},
2444 {"info", CmdLFHitagInfo
, IfPm3Hitag
, "Hitag 2 tag information"},
2445 {"reader", CmdLFHitagReader
, IfPm3Hitag
, "Act like a Hitag 2 reader"},
2446 {"test", CmdLFHitag2Selftest
, AlwaysAvailable
, "Perform self tests"},
2447 {"-----------", CmdHelp
, IfPm3Hitag
, "----------------------- " _CYAN_("Operations") " -----------------------"},
2448 // {"demod", CmdLFHitag2PWMDemod, IfPm3Hitag, "PWM Hitag 2 reader message demodulation"},
2449 {"dump", CmdLFHitag2Dump
, IfPm3Hitag
, "Dump Hitag 2 tag"},
2450 {"read", CmdLFHitagRd
, IfPm3Hitag
, "Read Hitag memory"},
2451 {"sniff", CmdLFHitagSniff
, IfPm3Hitag
, "Eavesdrop Hitag communication"},
2452 {"view", CmdLFHitagView
, AlwaysAvailable
, "Display content from tag dump file"},
2453 {"wrbl", CmdLFHitagWriter
, IfPm3Hitag
, "Write a block (page) in Hitag memory"},
2454 {"-----------", CmdHelp
, IfPm3Hitag
, "----------------------- " _CYAN_("Simulation") " -----------------------"},
2455 {"eload", CmdLFHitagEload
, IfPm3Hitag
, "Upload file into emulator memory"},
2456 // {"esave", CmdLFHitagESave, IfPm3Hitag, "Save emulator memory to file"},
2457 {"eview", CmdLFHitagEview
, IfPm3Hitag
, "View emulator memory"},
2458 {"sim", CmdLFHitagSim
, IfPm3Hitag
, "Simulate Hitag transponder"},
2459 {"-----------", CmdHelp
, IfPm3Hitag
, "----------------------- " _CYAN_("Recovery") " -----------------------"},
2460 {"cc", CmdLFHitagSCheckChallenges
, IfPm3Hitag
, "Hitag S: test all provided challenges"},
2461 {"crack2", CmdLFHitag2Crack2
, IfPm3Hitag
, "Recover 2048bits of crypto stream"},
2462 {"chk", CmdLFHitag2Chk
, IfPm3Hitag
, "Check keys"},
2463 {"lookup", CmdLFHitag2Lookup
, AlwaysAvailable
, "Uses authentication trace to check for key in dictionary file"},
2464 {"ta", CmdLFHitag2CheckChallenges
, IfPm3Hitag
, "Hitag 2: test all recorded authentications"},
2465 { NULL
, NULL
, 0, NULL
}
2468 static int CmdHelp(const char *Cmd
) {
2469 (void)Cmd
; // Cmd is not used so far
2470 CmdsHelp(CommandTable
);
2474 int CmdLFHitag(const char *Cmd
) {
2475 clearCommandBuffer();
2476 return CmdsParse(CommandTable
, Cmd
);