style
[RRG-proxmark3.git] / client / src / cmdlfhitag.c
blob0c8956d7514b1d18d019c15e2b0298cb692ec2ed
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
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.
8 //
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"
19 #include <ctype.h>
20 #include "cmdparser.h" // command_t
21 #include "comms.h"
22 #include "cmdtrace.h"
23 #include "commonutil.h"
24 #include "fileutils.h" // savefile
25 #include "protocols.h" // defines
26 #include "cliparser.h"
27 #include "crc.h"
28 #include "graph.h" // MAX_GRAPH_TRACE_LEN
29 #include "lfdemod.h"
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) {
43 //uid s/n ********
44 uint8_t type = (uid >> 4) & 0xF;
45 switch (type) {
46 case 1:
47 return "PCF 7936";
48 case 2:
49 return "PCF 7946";
50 case 3:
51 return "PCF 7947";
52 case 4:
53 return "PCF 7942/44";
54 case 5:
55 return "PCF 7943";
56 case 6:
57 return "PCF 7941";
58 case 7:
59 return "PCF 7952";
60 case 9:
61 return "PCF 7945";
62 default:
63 return "";
67 uint8_t hitag1_CRC_check(uint8_t *d, uint32_t nbit) {
68 if (nbit < 9) {
69 return 2;
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));
85 if (!got) {
86 PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
87 return PM3_EMALLOC;
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");
94 free(got);
95 return PM3_ETIMEOUT;
98 uint16_t traceLen = resp.arg[2];
99 if (traceLen > PM3_CMD_DATA_SIZE) {
100 uint8_t *p = realloc(got, traceLen);
101 if (p == NULL) {
102 PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
103 free(got);
104 return PM3_EMALLOC;
106 got = p;
107 if (!GetFromDevice(BIG_BUF, got, traceLen, 0, NULL, 0, NULL, 2500, false)) {
108 PrintAndLogEx(WARNING, "command execution time out");
109 free(got);
110 return PM3_ETIMEOUT;
114 PrintAndLogEx(NORMAL, "recorded activity (TraceLen = %d bytes):");
115 PrintAndLogEx(NORMAL, " ETU :nbits: who bytes");
116 PrintAndLogEx(NORMAL, "---------+-----+----+-----------");
118 int i = 0;
119 int prev = -1;
120 int len = strlen(Cmd);
122 char filename[FILE_PATH_SIZE] = { 0x00 };
123 FILE *f = NULL;
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");
131 if (!f) {
132 PrintAndLogEx(ERR, "Error: Could not open file [%s]", filename);
133 return PM3_EFILE;
137 for (;;) {
139 if (i >= traceLen) { break; }
141 bool isResponse;
142 int timestamp = *((uint32_t *)(got + i));
143 if (timestamp & 0x80000000) {
144 timestamp &= 0x7fffffff;
145 isResponse = 1;
146 } else {
147 isResponse = 0;
150 int parityBits = *((uint32_t *)(got + i + 4));
151 // 4 bytes of additional information...
152 // maximum of 32 additional parity bit information
154 // TODO:
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]);
161 if (len > 100) {
162 break;
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] = "";
172 int j;
173 for (j = 0; j < len; j++) {
175 int offset = j * 4;
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]);
179 } else {
180 snprintf(line + offset, sizeof(line) - offset, "%02x ", frame[j]);
184 PrintAndLogEx(NORMAL, " +%7d: %3d: %s %s",
185 (prev < 0 ? 0 : (timestamp - prev)),
186 bits,
187 (isResponse ? "TAG" : " "),
188 line);
190 if (f) {
191 fprintf(f, " +%7d: %3d: %s %s\n",
192 (prev < 0 ? 0 : (timestamp - prev)),
193 bits,
194 (isResponse ? "TAG" : " "),
195 line);
198 prev = timestamp;
199 i += (len + 9);
202 if (f) {
203 fclose(f);
204 PrintAndLogEx(NORMAL, "Recorded activity successfully written to file: %s", filename);
207 free(got);
208 return PM3_SUCCES;
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)) {
216 return;
219 uint64_t num = 0;
220 uint64_t paxton_id = 0;
221 uint16_t skip = 48;
222 uint64_t mask = 0xF80000000000;
224 uint64_t bytes = bytes_to_num(data + 16, 6);
226 for (int j = 0; j < 8; j++) {
228 num = bytes & mask;
229 skip -= 5;
230 mask >>= 5;
232 uint8_t digit = (num >> skip & 0xF);
233 paxton_id = (paxton_id * 10) + digit;
235 if (j == 5) {
236 skip -= 2;
237 mask >>= 2;
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
250 char formfactor[16];
251 switch (data[23]) {
252 case 0x06: {
253 strcat(formfactor, "isocard");
254 break;
256 case 0x03: {
257 strcat(formfactor, "fob");
258 break;
260 case 0x02: {
261 strcat(formfactor, "iso magstripe");
262 break;
264 default: {
265 snprintf(formfactor, sizeof(formfactor), "unk: %02x", data[23]);
266 break;
270 if (show_header) {
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);
275 if (show_header) {
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));
287 char msg[100];
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);
294 //configuration byte
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"));
300 if (config & 0x8) {
301 PrintAndLogEx(SUCCESS, " %s", sprint_breakdown_bin(C_YELLOW, bs, 8, 4, 1, "Crypto mode"));
302 } else {
303 PrintAndLogEx(SUCCESS, " %s", sprint_breakdown_bin(C_NONE, bs, 8, 4, 1, "Password mode"));
306 // version
307 uint8_t foo = ((config & 0x6) >> 1);
308 switch (foo) {
309 case 0:
310 PrintAndLogEx(SUCCESS, " %s", sprint_breakdown_bin(C_NONE, bs, 8, 5, 2, "Public mode B, Coding: biphase"));
311 break;
312 case 1:
313 PrintAndLogEx(SUCCESS, " %s", sprint_breakdown_bin(C_NONE, bs, 8, 5, 2, "Public mode A, Coding: manchester"));
314 break;
315 case 2:
316 PrintAndLogEx(SUCCESS, " %s", sprint_breakdown_bin(C_NONE, bs, 8, 5, 2, "Public mode C, Coding: biphase"));
317 break;
318 case 3:
319 PrintAndLogEx(SUCCESS, " %s", sprint_breakdown_bin(C_NONE, bs, 8, 5, 2, "Hitag 2"));
320 break;
323 // encoding
324 if (config & 0x01) {
325 PrintAndLogEx(SUCCESS, " %s", sprint_breakdown_bin(C_NONE, bs, 8, 7, 1, "Biphase"));
326 } else {
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, " ");
353 switch (i) {
354 case 0:
355 sprintf(lckstr, "%s", _RED_("L "));
356 break;
357 case 1:
358 if (config & 0x80) {
359 sprintf(lckstr, "%s", _RED_("L "));
360 } else {
361 sprintf(lckstr, "%s", _GREEN_("RW"));
363 break;
364 case 2:
365 if (config & 0x80) {
366 if (config & 0x8) {
367 sprintf(lckstr, "%s", _RED_("L "));
368 } else {
369 sprintf(lckstr, "%s", _RED_("R "));
371 } else {
372 sprintf(lckstr, "%s", _GREEN_("RW"));
374 break;
375 case 3:
376 // OTP Page 3.
377 if (config & 0x40) {
378 sprintf(lckstr, "%s", _RED_("R "));
379 //. Configuration byte and password tag " _RED_("FIXED / IRREVERSIBLE"));
380 } else {
381 sprintf(lckstr, "%s", _GREEN_("RW"));
383 break;
384 case 4:
385 case 5:
386 if (config & 0x20) {
387 sprintf(lckstr, "%s", _RED_("R "));
388 } else {
389 sprintf(lckstr, "%s", _GREEN_("RW"));
391 break;
392 case 6:
393 case 7:
394 if (config & 0x10) {
395 sprintf(lckstr, "%s", _RED_("R "));
396 } else {
397 sprintf(lckstr, "%s", _GREEN_("RW"));
399 break;
400 default:
401 break;
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)
409 , lckstr
410 , annotation[i]
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) {
423 static struct {
424 enum {
425 STATE_HALT,
426 STATE_START_AUTH,
427 STATE_AUTH,
428 STATE_START_ENCRYPTED,
429 STATE_ENCRYPTED,
430 } state;
431 uint32_t uid;
432 uint64_t cipher_state;
433 uint8_t plainlen;
434 uint8_t plain[30];
435 bool found_key;
436 uint64_t key;
437 } _ht2state;
439 void annotateHitag2_init(void) {
440 _ht2state.state = STATE_HALT;
441 _ht2state.uid = 0;
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) {
457 return false;
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];
463 bool found = false;
464 for (uint32_t i = 0; i < keycount; i++) {
466 uint64_t key = keys[i];
467 key = BSWAP_48(key);
468 key = REV64(key);
470 hitag_state_t hs2;
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;
476 _ht2state.key = key;
477 found = true;
478 break;
481 return found;
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--) {
493 if (keylen == 4) {
494 packet.cmd = HT2F_PASSWORD;
495 memcpy(packet.pwd, pkeys, keylen);
496 } else {
497 packet.cmd = HT2F_CRYPTO;
498 memcpy(packet.key, pkeys, keylen);
501 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);
509 return PM3_ETIMEOUT;
512 if (resp.status != PM3_SUCCESS) {
513 *found_idx = *found_idx + 1;
514 continue;
516 return PM3_SUCCESS;
518 return PM3_ESOFT;
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);
527 return true;
530 return false;
533 // HITAG 2 commands
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)) {
542 return 0;
544 if ((memcmp(bs + 2, "001", 3) == 0) && (memcmp(bs + 2 + 3 + 2, "110", 3) == 0)) {
545 return 1;
547 if ((memcmp(bs + 2, "010", 3) == 0) && (memcmp(bs + 2 + 3 + 2, "101", 3) == 0)) {
548 return 2;
550 if ((memcmp(bs + 2, "011", 3) == 0) && (memcmp(bs + 2 + 3 + 2, "100", 3) == 0)) {
551 return 3;
553 if ((memcmp(bs + 2, "100", 3) == 0) && (memcmp(bs + 2 + 3 + 2, "011", 3) == 0)) {
554 return 4;
556 if ((memcmp(bs + 2, "101", 3) == 0) && (memcmp(bs + 2 + 3 + 2, "010", 3) == 0)) {
557 return 5;
559 if ((memcmp(bs + 2, "110", 3) == 0) && (memcmp(bs + 2 + 3 + 2, "001", 3) == 0)) {
560 return 6;
562 if ((memcmp(bs + 2, "111", 3) == 0) && (memcmp(bs + 2 + 3 + 2, "000", 3) == 0)) {
563 return 7;
565 return 255;
568 void hitag2_annotate_plain(char *exp, size_t size, const uint8_t *cmd, uint8_t cmdsize, uint8_t bits) {
570 if (cmdsize == 0) {
571 return;
574 char *binstr = (char *)calloc((cmdsize * 8) + 1, sizeof(uint8_t));
575 if (binstr == NULL) {
576 return;
579 bytes_2_binstr(binstr, cmd, cmdsize);
581 size_t bn = strlen(binstr);
582 if (bits) {
583 if (cmdsize == 1) {
584 bn = bits;
585 } else if (cmdsize > 1) {
586 bn = ((cmdsize - 1) * 8) + bits;
590 switch (bn) {
591 case 5: {
592 snprintf(exp, size, " ");
593 break;
595 case 10: {
596 if (memcmp(binstr, HITAG2_BINSTR_HALT, 2) == 0) {
597 snprintf(exp, size, " ");
598 break;
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);
605 break;
608 if (memcmp(binstr, HITAG2_BINSTR_READ_PAGE_INVERTED, 2) == 0) {
609 snprintf(exp, size, "READ PAGE INV (" _MAGENTA_("%u") ")", page);
610 break;
613 if (memcmp(binstr, HITAG2_BINSTR_WRITE_PAGE, 2) == 0) {
614 snprintf(exp, size, "WRITE PAGE (" _MAGENTA_("%u") ")", page);
615 break;
617 break;
619 case 32: { // password or data
620 snprintf(exp, size, " ");
621 break;
623 case 64: { // crypto handshake
624 snprintf(exp, size, " ");
625 break;
627 default: {
628 snprintf(exp, size, " ");
629 break;
632 free(binstr);
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) {
637 if (cmdsize == 0) {
638 return;
641 char *binstr = (char *)calloc((cmdsize * 8) + 1, sizeof(uint8_t));
642 if (binstr == NULL) {
643 return;
646 bytes_2_binstr(binstr, cmd, cmdsize);
648 size_t bn = strlen(binstr);
649 if (bits) {
650 if (cmdsize == 1) {
651 bn = bits;
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
668 switch (bn) {
669 case 5: {
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;
675 } else {
676 snprintf(exp, size, "?");
678 break;
680 case 10: {
682 if (isdecrypted == false && _ht2state.state == STATE_ENCRYPTED) {
683 snprintf(exp, size, "ENC CMD");
684 break;
687 if (memcmp(binstr, HITAG2_BINSTR_HALT, 2) == 0) {
688 snprintf(exp, size, "HALT");
689 _ht2state.state = STATE_HALT;
690 break;
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);
697 break;
700 if (memcmp(binstr, HITAG2_BINSTR_READ_PAGE_INVERTED, 2) == 0) {
701 snprintf(exp, size, "READ PAGE INV (" _MAGENTA_("%u") ")", page);
702 break;
705 if (memcmp(binstr, HITAG2_BINSTR_WRITE_PAGE, 2) == 0) {
706 snprintf(exp, size, "WRITE PAGE (" _MAGENTA_("%u") ")", page);
707 break;
709 break;
712 case 32: { // password or data
713 if (_ht2state.state == STATE_START_AUTH) {
714 if (is_response) {
715 snprintf(exp, size, "UID");
716 uint8_t uid[4];
717 memcpy(uid, cmd, 4);
718 rev_msb_array(uid, 4);
719 _ht2state.uid = MemLeToUint4byte(uid);
720 } else {
721 snprintf(exp, size, "PWD: " _GREEN_("0x%02X%02X%02X%02X"), cmd[0], cmd[1], cmd[2], cmd[3]);
722 _ht2state.state = STATE_AUTH;
724 break;
727 if (_ht2state.state == STATE_AUTH) {
728 snprintf(exp, size, "DATA");
729 break;
732 if (_ht2state.state == STATE_START_ENCRYPTED) {
733 snprintf(exp, size, "At");
734 _ht2state.state = STATE_ENCRYPTED;
735 break;
738 if (isdecrypted == false && _ht2state.state == STATE_ENCRYPTED) {
739 snprintf(exp, size, "ENC DATA");
741 break;
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(
753 _ht2state.key,
754 _ht2state.uid,
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);
760 key = BSWAP_48(key);
761 snprintf(exp, size, "Nr Ar " _WHITE_("( ") _GREEN_("%012" PRIx64) " )", key);
763 } else {
764 snprintf(exp, size, "AUTH: Nr Ar");
766 } else {
767 snprintf(exp, size, "AUTH: Nr Ar");
769 break;
771 default: {
772 snprintf(exp, size, "?");
773 _ht2state.state = STATE_HALT;
774 break;
778 free(binstr);
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) {
786 switch (uid) {
787 case 0x53505910:
788 return "IMMO Key emulator";
789 break;
790 case 0x5accc811:
791 case 0x5accc821:
792 case 0x5accc831:
793 case 0x5accc841:
794 case 0x5accc851:
795 case 0x5accc861:
796 case 0x5accc871:
797 case 0x5accc881:
798 case 0x5accc891:
799 case 0x5accc8B1:
800 return "CN3 Tango Key emulator";
802 return "";
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.");
816 return false;
819 if (resp.status != PM3_SUCCESS) {
820 PrintAndLogEx(DEBUG, "DEBUG: Error - failed getting UID");
821 return false;
824 if (uid) {
825 *uid = bytes_to_num(resp.data.asBytes, HITAG_UID_SIZE);
827 return true;
830 static int CmdLFHitagInfo(const char *Cmd) {
831 CLIParserContext *ctx;
832 CLIParserInit(&ctx, "lf hitag info",
833 "Hitag 2 tag information",
834 "lf hitag info"
837 void *argtable[] = {
838 arg_param_begin,
839 arg_param_end
841 CLIExecWithReturn(ctx, Cmd, argtable, true);
842 CLIParserFree(ctx);
844 // read UID
845 uint32_t uid = 0;
846 if (ht2_get_uid(&uid) == false) {
847 return PM3_ESOFT;
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);
863 if (strlen(s)) {
864 PrintAndLogEx(SUCCESS, "Found... " _GREEN_("%s"), s);
865 } else {
866 PrintAndLogEx(INFO, _RED_("n/a"));
869 PrintAndLogEx(NORMAL, "");
870 return PM3_SUCCESS;
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",
877 "lf hitag reader\n"
878 "lf hitag reader -@ -> Continuous mode"
881 void *argtable[] = {
882 arg_param_begin,
883 arg_lit0("@", NULL, "continuous reader mode"),
884 arg_param_end
886 CLIExecWithReturn(ctx, Cmd, argtable, true);
887 bool cm = arg_get_lit(ctx, 1);
888 CLIParserFree(ctx);
890 if (cm) {
891 PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
894 do {
895 // read UID
896 uint32_t uid = 0;
897 if (ht2_get_uid(&uid)) {
898 PrintAndLogEx(SUCCESS, "UID.... " _GREEN_("%08X"), uid);
900 } while (cm && kbd_enter_pressed() == false);
902 return PM3_SUCCESS;
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"
910 " Password mode:\n"
911 " - default key 4D494B52 (MIKR)\n\n"
912 " Crypto mode: \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"
923 void *argtable[] = {
924 arg_param_begin,
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"),
932 arg_param_end
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);
942 uint8_t nrar[8];
943 int nalen = 0;
944 int res = CLIParamHexToBuf(arg_get_str(ctx, 3), nrar, sizeof(nrar), &nalen);
945 if (res != 0) {
946 CLIParserFree(ctx);
947 return PM3_EINVARG;
949 bool use_nrar = nalen > 0;
950 bool use_crypto = arg_get_lit(ctx, 4);
952 uint8_t key[6];
953 int keylen = 0;
954 res = CLIParamHexToBuf(arg_get_str(ctx, 5), key, sizeof(key), &keylen);
955 if (res != 0) {
956 CLIParserFree(ctx);
957 return PM3_EINVARG;
959 // uint32_t page = arg_get_u32_def(ctx, 6, 0);
961 CLIParserFree(ctx);
963 // sanity checks
964 if ((use_ht1 + use_ht2 + use_htm) > 1) {
965 PrintAndLogEx(ERR, "error, specify only one Hitag type");
966 return PM3_EINVARG;
968 if ((use_ht1 + use_ht2 + use_htm) == 0) {
969 PrintAndLogEx(ERR, "error, specify one Hitag type");
970 return PM3_EINVARG;
973 if (keylen != 0 && keylen != 4 && keylen != 6) {
974 PrintAndLogEx(WARNING, "Wrong KEY len expected 0, 4 or 6, got %d", keylen);
975 return PM3_EINVARG;
978 if (nalen != 0 && nalen != 8) {
979 PrintAndLogEx(WARNING, "Wrong NR/AR len expected 0 or 8, got %d", nalen);
980 return PM3_EINVARG;
983 // complete options
984 if (keylen == 4) {
985 use_pwd = true;
987 if (keylen == 6) {
988 use_crypto = true;
990 if ((keylen == 0) && use_pwd) {
991 memcpy(key, "MIKR", 4);
992 keylen = 4;
994 if ((keylen == 0) && use_crypto) {
995 memcpy(key, "ONMIKR", 6);
996 keylen = 6;
999 // check coherence
1000 uint8_t foo = (use_plain + use_pwd + use_nrar + use_crypto);
1001 if (foo > 1) {
1002 PrintAndLogEx(WARNING, "Specify only one authentication mode");
1003 return PM3_EINVARG;
1004 } else if (foo == 0) {
1005 PrintAndLogEx(WARNING, "Specify one authentication mode");
1006 return PM3_EINVARG;
1009 if (use_ht2 && use_plain) { // not sure for the other types...
1010 PrintAndLogEx(WARNING, "Chosen Hitag type does not have Plain mode");
1011 return PM3_EINVARG;
1014 lf_hitag_data_t packet;
1015 memset(&packet, 0, sizeof(packet));
1017 int pm3cmd;
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));
1032 } else {
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");
1049 return PM3_ESOFT;
1052 if (use_nrar) {
1053 return PM3_SUCCESS;
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]);
1060 if (use_ht2) {
1061 print_hitag2_blocks(data, HITAG2_MAX_BYTE_SIZE);
1062 print_hitag2_paxton(true, data);
1063 } else {
1064 print_hex_break(data, HITAG_MAX_BYTE_SIZE, HITAG_BLOCK_SIZE);
1066 return PM3_SUCCESS;
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[] = {
1079 arg_param_begin,
1080 arg_str1("f", "file", "<fn>", "filename to load ( w/o ext )"),
1081 arg_param_end
1083 CLIExecWithReturn(ctx, Cmd, argtable, true);
1085 int fnlen = 0;
1086 char filename[FILE_PATH_SIZE] = {0};
1087 CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
1088 CLIParserFree(ctx);
1090 uint8_t *data = NULL;
1091 size_t datalen = 0;
1092 int res = loadFile_safe(filename, ".cc", (void **)&data, &datalen);
1093 if (res == PM3_SUCCESS) {
1095 if (datalen % 8) {
1096 PrintAndLogEx(ERR, "Error, file length mismatch. Expected multiple of 8, got " _RED_("%zu"), datalen);
1097 free(data);
1098 return PM3_EINVARG;
1100 if (datalen != (8 * 60)) {
1101 PrintAndLogEx(ERR, "Error, file length mismatch. Expected 480, got " _RED_("%zu"), datalen);
1102 free(data);
1103 return PM3_EINVARG;
1106 clearCommandBuffer();
1107 SendCommandNG(CMD_LF_HITAGS_TEST_TRACES, data, datalen);
1109 if (data) {
1110 free(data);
1112 return PM3_SUCCESS;
1115 static int CmdLFHitag2CheckChallenges(const char *Cmd) {
1116 CLIParserContext *ctx;
1117 CLIParserInit(&ctx, "lf hitag ta",
1118 "Test recorded authentications (replay?)",
1119 "lf hitag ta"
1121 CLIParserFree(ctx);
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");
1136 return PM3_ESOFT;
1139 // FIXME: doegox: not sure what this fct does and what it returns...
1140 return PM3_SUCCESS;
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"
1147 " Password mode:\n"
1148 " - default key 4D494B52 (MIKR)\n\n"
1149 " Crypto mode: \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[] = {
1161 arg_param_begin,
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"),
1169 arg_param_end
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);
1179 uint8_t nrar[8];
1180 int nalen = 0;
1181 int res = CLIParamHexToBuf(arg_get_str(ctx, 3), nrar, sizeof(nrar), &nalen);
1182 if (res != 0) {
1183 CLIParserFree(ctx);
1184 return PM3_EINVARG;
1186 bool use_nrar = nalen > 0;
1187 bool use_crypto = arg_get_lit(ctx, 4);
1189 uint8_t key[6];
1190 int keylen = 0;
1191 res = CLIParamHexToBuf(arg_get_str(ctx, 5), key, sizeof(key), &keylen);
1192 if (res != 0) {
1193 CLIParserFree(ctx);
1194 return PM3_EINVARG;
1197 int page = arg_get_int_def(ctx, 6, 0);
1199 uint8_t data[4];
1200 int dlen = 0;
1201 res = CLIParamHexToBuf(arg_get_str(ctx, 7), data, sizeof(data), &dlen);
1202 if (res != 0) {
1203 CLIParserFree(ctx);
1204 return PM3_EINVARG;
1207 CLIParserFree(ctx);
1209 // sanity checks
1210 if ((use_ht1 + use_ht2 + use_htm) > 1) {
1211 PrintAndLogEx(ERR, "error, specify only one Hitag type");
1212 return PM3_EINVARG;
1214 if ((use_ht1 + use_ht2 + use_htm) == 0) {
1215 PrintAndLogEx(ERR, "error, specify one Hitag type");
1216 return PM3_EINVARG;
1219 if (keylen != 0 && keylen != 4 && keylen != 6) {
1220 PrintAndLogEx(WARNING, "Wrong KEY len expected 0, 4 or 6, got %d", keylen);
1221 return PM3_EINVARG;
1224 if (dlen != sizeof(data)) {
1225 PrintAndLogEx(WARNING, "Wrong DATA len expected 4, got %d", dlen);
1226 return PM3_EINVARG;
1229 if (nalen != 0 && nalen != 8) {
1230 PrintAndLogEx(WARNING, "Wrong NR/AR len expected 0 or 8, got %d", nalen);
1231 return PM3_EINVARG;
1234 // complete options
1235 if (keylen == 4) {
1236 use_pwd = true;
1238 if (keylen == 6) {
1239 use_crypto = true;
1241 if ((keylen == 0) && use_pwd) {
1242 memcpy(key, "MIKR", 4);
1243 keylen = 4;
1245 if ((keylen == 0) && use_crypto) {
1246 memcpy(key, "ONMIKR", 6);
1247 keylen = 6;
1250 // check coherence
1251 uint8_t foo = (use_plain + use_pwd + use_nrar + use_crypto);
1252 if (foo > 1) {
1253 PrintAndLogEx(WARNING, "Specify only one authentication mode");
1254 return PM3_EINVARG;
1255 } else if (foo == 0) {
1256 PrintAndLogEx(WARNING, "Specify one authentication mode");
1257 return PM3_EINVARG;
1260 if (use_ht2 && use_plain) { // not sure for the other types...
1261 PrintAndLogEx(WARNING, "Chosen Hitag type does not have Plain mode");
1262 return PM3_EINVARG;
1265 lf_hitag_data_t packet;
1266 memset(&packet, 0, sizeof(packet));
1268 if (use_ht2 && use_pwd) {
1269 packet.cmd = HT2F_PASSWORD;
1270 packet.page = page;
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;
1277 packet.page = page;
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");
1282 } else {
1283 PrintAndLogEx(WARNING, "Sorry, not yet implemented");
1284 return PM3_ENOTIMPL;
1287 clearCommandBuffer();
1289 if (use_ht2) {
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");
1299 return PM3_SUCCESS;
1302 if (resp.status != PM3_SUCCESS) {
1303 PrintAndLogEx(FAILED, "Write ( " _RED_("fail") " )");
1304 return resp.status;
1309 PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )");
1310 return PM3_SUCCESS;
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[] = {
1328 arg_param_begin,
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"),
1335 arg_param_end
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);
1346 uint8_t nrar[8];
1347 int nalen = 0;
1348 int res = CLIParamHexToBuf(arg_get_str(ctx, 2), nrar, sizeof(nrar), &nalen);
1349 if (res != 0) {
1350 CLIParserFree(ctx);
1351 return PM3_EINVARG;
1353 bool use_nrar = nalen > 0;
1354 bool use_crypto = arg_get_lit(ctx, 3);
1356 uint8_t key[HITAG_NRAR_SIZE];
1357 int keylen = 0;
1358 res = CLIParamHexToBuf(arg_get_str(ctx, 4), key, sizeof(key), &keylen);
1359 if (res != 0) {
1360 CLIParserFree(ctx);
1361 return PM3_EINVARG;
1364 int fnlen = 0;
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);
1369 CLIParserFree(ctx);
1371 // sanity checks
1372 if ((use_ht1 + use_ht2 + use_hts + use_htm) > 1) {
1373 PrintAndLogEx(ERR, "error, specify only one Hitag type");
1374 return PM3_EINVARG;
1376 if ((use_ht1 + use_ht2 + use_hts + use_htm) == 0) {
1377 PrintAndLogEx(ERR, "error, specify one Hitag type");
1378 return PM3_EINVARG;
1381 if (keylen != 0 &&
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);
1386 return PM3_EINVARG;
1389 // complete options
1390 if (keylen == HITAG_PASSWORD_SIZE) {
1391 use_pwd = true;
1393 if (keylen == HITAG_CRYPTOKEY_SIZE) {
1394 use_crypto = true;
1396 if (keylen == HITAG_NRAR_SIZE) {
1397 use_nrar = true;
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;
1411 // check coherence
1412 uint8_t foo = (use_plain + use_pwd + use_nrar + use_crypto);
1413 if (foo > 1) {
1414 PrintAndLogEx(WARNING, "Specify only one authentication mode");
1415 return PM3_EINVARG;
1416 } else if (foo == 0) {
1417 if (use_hts) {
1418 use_plain = true;
1419 } else {
1420 PrintAndLogEx(WARNING, "Specify one authentication mode");
1421 return PM3_EINVARG;
1425 if (use_hts && use_pwd) { // not sure for the other types...
1426 PrintAndLogEx(WARNING, "Chosen Hitag type does not have Password mode");
1427 return PM3_EINVARG;
1430 if (use_ht2 && use_plain) { // not sure for the other types...
1431 PrintAndLogEx(WARNING, "Chosen Hitag type does not have Plain mode");
1432 return PM3_EINVARG;
1435 uint32_t uid = 0;
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));
1465 // loop
1466 uint8_t attempt = 30;
1467 do {
1469 PrintAndLogEx(INPLACE, "Attack 1 running...");
1470 fflush(stdout);
1472 if (WaitForResponseTimeout(CMD_LF_HITAG2_CRACK, &resp, 1000) == false) {
1473 attempt--;
1474 continue;
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);
1485 goto out;
1488 // error codes
1489 switch (payload->status) {
1490 case -1: {
1491 PrintAndLogEx(NORMAL, "");
1492 PrintAndLogEx(FAILED, "Couldn't select tag!");
1493 return PM3_ESOFT;
1495 case -2: {
1496 PrintAndLogEx(NORMAL, "");
1497 PrintAndLogEx(FAILED, "Cannot find a valid encrypted command!");
1498 return PM3_ESOFT;
1500 case -3: {
1501 PrintAndLogEx(NORMAL, "");
1502 PrintAndLogEx(FAILED, "Cannot find encrypted 'read page0' command!");
1503 return PM3_ESOFT;
1505 case -4: {
1506 PrintAndLogEx(NORMAL, "");
1507 PrintAndLogEx(FAILED, "Partial data extraction!");
1508 continue;
1512 } while (attempt);
1514 if (attempt == 0) {
1515 PrintAndLogEx(NORMAL, "");
1516 PrintAndLogEx(WARNING, "timeout while waiting for reply.");
1517 return PM3_ESOFT;
1520 t1 = msclock() - t1;
1521 PrintAndLogEx(SUCCESS, "\ntime " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0);
1523 goto out;
1525 } else {
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");
1539 return resp.status;
1542 data = resp.data.asBytes;
1544 out:
1547 // block3, 1 byte
1548 uid = bytes_to_num(data, HITAG_UID_SIZE);
1550 if (use_ht2) {
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);
1554 } else {
1555 PrintAndLogEx(INFO, "No memory printing available");
1558 if (nosave) {
1559 PrintAndLogEx(NORMAL, "");
1560 PrintAndLogEx(INFO, "Called with no save option");
1561 PrintAndLogEx(NORMAL, "");
1562 return PM3_SUCCESS;
1565 if (fnlen < 1) {
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);
1572 return PM3_SUCCESS;
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[] = {
1583 arg_param_begin,
1584 arg_str1("f", "file", "<fn>", "Specify a filename for dump file"),
1585 arg_lit0("v", "verbose", "Verbose output"),
1586 arg_param_end
1588 CLIExecWithReturn(ctx, Cmd, argtable, false);
1589 int fnlen = 0;
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);
1593 CLIParserFree(ctx);
1595 // read dump file
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) {
1600 return res;
1603 if (bytes_read < HITAG2_MAX_BYTE_SIZE) {
1604 PrintAndLogEx(ERR, "Error, dump file is too small");
1605 free(dump);
1606 return PM3_ESOFT;
1609 if (verbose) {
1610 // block3, 1 byte
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);
1617 free(dump);
1618 return PM3_SUCCESS;
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[] = {
1628 arg_param_begin,
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"), // μ
1634 arg_param_end
1636 CLIExecWithReturn(ctx, Cmd, argtable, false);
1638 int fnlen = 0;
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);
1646 CLIParserFree(ctx);
1648 if ((use_ht1 + use_ht2 + use_hts + use_htm) > 1) {
1649 PrintAndLogEx(ERR, "error, specify only one Hitag type");
1650 return PM3_EINVARG;
1652 if ((use_ht1 + use_ht2 + use_hts + use_htm) == 0) {
1653 PrintAndLogEx(ERR, "error, specify one Hitag type");
1654 return PM3_EINVARG;
1657 // read dump file
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) {
1662 return res;
1665 // check dump len..
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);
1670 if (use_ht1)
1671 payload->type = 1;
1672 if (use_ht2)
1673 payload->type = 2;
1674 if (use_hts)
1675 payload->type = 3;
1676 if (use_htm)
1677 payload->type = 4;
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);
1684 free(payload);
1685 } else {
1686 PrintAndLogEx(ERR, "error, wrong dump file size. got %zu", bytes_read);
1689 free(dump);
1690 return PM3_SUCCESS;
1693 static int CmdLFHitagEview(const char *Cmd) {
1694 CLIParserContext *ctx;
1695 CLIParserInit(&ctx, "lf hitag eview",
1696 "It displays emulator memory",
1697 "lf hitag eview\n"
1699 void *argtable[] = {
1700 arg_param_begin,
1701 arg_lit0("v", "verbose", "Verbose output"),
1702 arg_param_end
1704 CLIExecWithReturn(ctx, Cmd, argtable, true);
1705 bool verbose = arg_get_lit(ctx, 1);
1706 CLIParserFree(ctx);
1708 int bytes = HITAG2_MAX_BYTE_SIZE;
1710 // reserve memory
1711 uint8_t *dump = calloc(bytes, sizeof(uint8_t));
1712 if (dump == NULL) {
1713 PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
1714 return PM3_EMALLOC;
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");
1720 free(dump);
1721 return PM3_ETIMEOUT;
1724 if (verbose) {
1725 // block3, 1 byte
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);
1732 free(dump);
1733 return PM3_SUCCESS;
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",
1741 "lf hitag sim -2"
1744 void *argtable[] = {
1745 arg_param_begin,
1746 arg_lit0("1", "ht1", "simulate Hitag 1"),
1747 arg_lit0("2", "ht2", "simulate Hitag 2"),
1748 arg_param_end
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
1755 CLIParserFree(ctx);
1757 if ((use_ht1 + use_ht2 + use_htm) > 1) {
1758 PrintAndLogEx(ERR, "error, specify only one Hitag type");
1759 return PM3_EINVARG;
1761 if ((use_ht1 + use_ht2 + use_htm) == 0) {
1762 PrintAndLogEx(ERR, "error, specify one Hitag type");
1763 return PM3_EINVARG;
1766 uint16_t cmd = CMD_LF_HITAG_SIMULATE;
1767 // if (use_ht1)
1768 // cmd = CMD_LF_HITAG1_SIMULATE;
1770 clearCommandBuffer();
1771 SendCommandMIX(cmd, 0, 0, 0, NULL, 0);
1772 return PM3_SUCCESS;
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.",
1780 " lf hitag sniff"
1783 void *argtable[] = {
1784 arg_param_begin,
1785 arg_param_end
1787 CLIExecWithReturn(ctx, Cmd, argtable, true);
1788 CLIParserFree(ctx);
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");
1799 return PM3_SUCCESS;
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",
1808 "lf hitag pwmdemod"
1809 "lf hitag pwmdemod -t 65 --> specify first wave index\n"
1812 void *argtable[] = {
1813 arg_param_begin,
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"),
1817 arg_param_end
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);
1824 CLIParserFree(ctx);
1826 uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t));
1827 if (bits == NULL) {
1828 PrintAndLogEx(INFO, "failed to allocate memory");
1829 return PM3_EMALLOC;
1832 size_t size = getFromGraphBuffer(bits);
1834 PrintAndLogEx(DEBUG, "DEBUG: (Hitag2PWM) #samples from graphbuff... %zu", size);
1836 if (size < 255) {
1837 PrintAndLogEx(INFO, "too few samples in buffer");
1838 free(bits);
1839 return PM3_ESOFT;
1842 // TODO autodetect
1843 size = HitagPWMDemod(bits, size, &fchigh, &fclow, &start_idx, g_DemodBitRangeBuffer);
1844 if (size == 0) {
1845 PrintAndLogEx(FAILED, "No wave detected");
1846 free(bits);
1847 return PM3_ESOFT;
1850 PrintAndLogEx(DEBUG, "DEBUG: start_idx... %u size... %zu", start_idx, size);
1852 setDemodBuffBitRange(bits, size, 0, g_DemodBitRangeBuffer);
1853 setClockGrid(32, start_idx);
1855 uint32_t total = 0;
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);
1866 free(bits);
1867 return PM3_SUCCESS;
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[] = {
1882 arg_param_begin,
1883 arg_str0("f", "file", "<fn>", "specify dictionary filename"),
1884 arg_lit0(NULL, "pwd", "password mode"),
1885 arg_lit0(NULL, "crypto", "crypto mode"),
1886 arg_param_end
1889 CLIExecWithReturn(ctx, Cmd, argtable, true);
1890 int fnlen = 0;
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);
1896 CLIParserFree(ctx);
1898 if (use_pwd + use_crypto > 1) {
1899 PrintAndLogEx(WARNING, "Only specify one mode");
1900 return PM3_EINVARG;
1903 // no filename -> use default = ht2_default.dic
1904 if (fnlen == 0) {
1905 snprintf(filename, sizeof(filename), HITAG_DICTIONARY);
1908 uint8_t keylen = 4;
1909 if (use_crypto) {
1910 keylen = 6;
1913 uint64_t t1 = msclock();
1915 // just loop twice at max. Starting with 4 or 6.
1916 for (; keylen < 7; keylen += 2) {
1917 // load keys
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");
1923 if (keys != NULL) {
1924 free(keys);
1926 return res;
1929 // Main loop
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, "");
1936 if (keylen == 6) {
1937 PrintAndLogEx(SUCCESS, "found valid key [ " _GREEN_("%s") " ]", sprint_hex_inrow(keys + (found_idx * keylen), keylen));
1938 } else {
1939 PrintAndLogEx(SUCCESS, "found valid password [ " _GREEN_("%s") " ]", sprint_hex_inrow(keys + (found_idx * keylen), keylen));
1941 free(keys);
1942 break;
1944 free(keys);
1947 t1 = msclock() - t1;
1948 PrintAndLogEx(SUCCESS, "\ntime in check " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0);
1949 return PM3_SUCCESS;
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"
1957 " You can either\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[] = {
1967 arg_param_begin,
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"),
1974 arg_param_end
1977 CLIExecWithReturn(ctx, Cmd, argtable, false);
1978 int fnlen = 0;
1979 char filename[FILE_PATH_SIZE] = {0};
1980 CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
1982 int inkeylen = 0;
1983 uint8_t inkey[6] = {0};
1984 CLIGetHexWithReturn(ctx, 2, inkey, &inkeylen);
1986 int ulen = 0;
1987 uint8_t uidarr[4] = {0};
1988 CLIGetHexWithReturn(ctx, 3, uidarr, &ulen);
1990 int nlen = 0;
1991 uint8_t narr[4] = {0};
1992 CLIGetHexWithReturn(ctx, 4, narr, &nlen);
1994 int alen = 0;
1995 uint8_t aarr[4] = {0};
1996 CLIGetHexWithReturn(ctx, 5, aarr, &alen);
1998 int nalen = 0;
1999 uint8_t nrar[8] = {0};
2000 CLIGetHexWithReturn(ctx, 6, nrar, &nalen);
2002 CLIParserFree(ctx);
2004 // sanity checks
2005 if (inkeylen && inkeylen != 6) {
2006 PrintAndLogEx(INFO, "Key wrong length. expected 6, got %i", inkeylen);
2007 return PM3_EINVARG;
2010 if (ulen && ulen != 4) {
2011 PrintAndLogEx(INFO, "UID wrong length. expected 4, got %i", ulen);
2012 return PM3_EINVARG;
2015 if (nlen && nlen != 4) {
2016 PrintAndLogEx(INFO, "Nr wrong length. expected 4, got %i", nlen);
2017 return PM3_EINVARG;
2020 if (alen && alen != 4) {
2021 PrintAndLogEx(INFO, "Ar wrong length. expected 4, got %i", alen);
2022 return PM3_EINVARG;
2025 if (nalen && nalen != 8) {
2026 PrintAndLogEx(INFO, "NrAr wrong length. expected 8, got %i", nalen);
2027 return PM3_EINVARG;
2030 // Iceman note:
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.
2041 // Termology:
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
2052 1. UID: 11223344
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);
2069 // Little Endian
2070 uint64_t knownkey = MemLeToUint6byte(inkey);
2071 uint32_t uid = MemLeToUint4byte(uidarr);
2073 uint32_t nr;
2074 // Big Endian
2075 uint32_t ar;
2077 if (nlen && alen) {
2078 nr = MemLeToUint4byte(narr);
2079 ar = MemBeToUint4byte(aarr);
2080 } else if (nalen) {
2081 nr = MemLeToUint4byte(nrar);
2082 ar = MemBeToUint4byte(nrar + 4);
2083 } else {
2084 PrintAndLogEx(INFO, "No nr or ar was supplied");
2085 return PM3_EINVARG;
2088 uint32_t iv = nr;
2091 if (inkeylen) {
2093 PrintAndLogEx(DEBUG, "UID... %08" PRIx32, uid);
2094 PrintAndLogEx(DEBUG, "IV.... %08" PRIx32, iv);
2095 PrintAndLogEx(DEBUG, "Key... %012" PRIx64, knownkey);
2097 // initialize state
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, "");
2113 return PM3_SUCCESS;
2116 if (fnlen == 0) {
2117 snprintf(filename, sizeof(filename), HITAG_DICTIONARY);
2120 // load keys
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");
2126 if (keys != NULL) {
2127 free(keys);
2129 return res;
2132 bool found = false;
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);
2139 hitag_state_t hs2;
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));
2145 found = true;
2146 break;
2149 if (g_debugMode) {
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);
2157 free(keys);
2159 if (found == false) {
2160 PrintAndLogEx(WARNING, "check failed");
2163 PrintAndLogEx(NORMAL, "");
2164 return PM3_SUCCESS;
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[] = {
2175 arg_param_begin,
2176 arg_str0(NULL, "nrar", "<hex>", "specify nonce / answer as 8 hex bytes"),
2177 arg_param_end
2180 CLIExecWithReturn(ctx, Cmd, argtable, false);
2181 int nalen = 0;
2182 uint8_t nrar[8] = {0};
2183 CLIGetHexWithReturn(ctx, 1, nrar, &nalen);
2184 CLIParserFree(ctx);
2186 // sanity checks
2187 if (nalen && nalen != 8) {
2188 PrintAndLogEx(INFO, "NrAr wrong length. expected 8, got %i", nalen);
2189 return PM3_EINVARG;
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));
2204 // loop
2205 uint8_t attempt = 50;
2206 do {
2208 // PrintAndLogEx(INPLACE, "Attack 2 running...");
2209 // fflush(stdout);
2211 if (WaitForResponseTimeout(CMD_LF_HITAG2_CRACK_2, &resp, 1000) == false) {
2212 attempt--;
2213 continue;
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>");
2227 break;
2228 } else {
2229 PrintAndLogEx(NORMAL, "");
2230 PrintAndLogEx(FAILED, "Nonce replay and length extension attack ( %s )", _RED_("fail"));
2231 break;
2234 } while (attempt);
2236 if (attempt == 0) {
2237 PrintAndLogEx(NORMAL, "");
2238 PrintAndLogEx(WARNING, "timeout while waiting for reply.");
2239 return PM3_ESOFT;
2242 t1 = msclock() - t1;
2243 PrintAndLogEx(SUCCESS, "\ntime " _YELLOW_("%.0f") " seconds\n", (float)t1 / 1000.0);
2244 return PM3_SUCCESS;
2247 /* Test code
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;
2269 // init crypto
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;
2278 return 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;
2289 // start timer
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;
2300 return 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);
2317 // initialise
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);
2328 if (x != y) {
2329 return 0;
2332 return 1;
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);
2346 // initialise
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);
2356 if (x != y) {
2357 return 0;
2360 return 1;
2363 static int CmdLFHitag2Selftest(const char *Cmd) {
2364 CLIParserContext *ctx;
2365 CLIParserInit(&ctx, "lf hitag test",
2366 "Perform self tests of Hitag crypto engine",
2367 "lf hitag test\n"
2370 void *argtable[] = {
2371 arg_param_begin,
2372 arg_param_end
2374 CLIExecWithReturn(ctx, Cmd, argtable, true);
2375 CLIParserFree(ctx);
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, "");
2396 return PM3_SUCCESS;
2399 int ht2_read_uid(void) {
2400 uint32_t uid = 0;
2401 if (ht2_get_uid(&uid) == false) {
2402 return PM3_ESOFT;
2405 PrintAndLogEx(SUCCESS, "UID.... " _GREEN_("%08X"), uid);
2406 PrintAndLogEx(SUCCESS, "TYPE... " _GREEN_("%s"), getHitagTypeStr(uid));
2407 return PM3_SUCCESS;
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");
2431 return PM3_ESOFT;
2434 uint8_t *data = resp.data.asBytes;
2435 print_hitag2_paxton(false, data);
2436 return PM3_SUCCESS;
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);
2471 return PM3_SUCCESS;
2474 int CmdLFHitag(const char *Cmd) {
2475 clearCommandBuffer();
2476 return CmdsParse(CommandTable, Cmd);