recover_pk.py: replace secp192r1 by prime192v1
[RRG-proxmark3.git] / client / src / cmdlfhitaghts.c
blobd1af178dd18b2d5c553cde1be564882f137017c7
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 S support
17 //-----------------------------------------------------------------------------
19 #include "cmdlfhitaghts.h"
20 #include <ctype.h>
21 #include "cmdparser.h" // command_t
22 #include "comms.h"
23 #include "cmdtrace.h"
24 #include "commonutil.h"
25 #include "hitag.h"
26 #include "fileutils.h" // savefile
27 #include "protocols.h" // defines
28 #include "cliparser.h"
29 #include "crc.h"
30 #include "graph.h" // MAX_GRAPH_TRACE_LEN
31 #include "lfdemod.h"
32 #include "cmddata.h" // setDemodBuff
33 #include "pm3_cmd.h" // return codes
34 #include "hitag2/hitag2_crypto.h"
35 #include "util_posix.h" // msclock
37 static int CmdHelp(const char *Cmd);
39 static const char *hts_get_type_str(uint32_t uid) {
40 // source 1: https://www.scorpio-lk.com/downloads/Tango/HITAG_Classification.pdf
41 // IDE Mark
42 // Each HITAG chip contains an unique Device Identifier (IDE ) so called a Serial Number.
43 // Bit 7 ot 4 of the IDE serve the function of a chip type identification. Example. IDE is 2A 48 E2 16, the IDE mark is "1".
45 // source 2: Hitag S product Specification Revision 3.1
46 // 6.1.1 Product Identifier (PID)
47 // The Product Identifier (PID) for the HITAG S Transponder IC is coded in the UID 3 Byte of the Unique Identifier (UID).
48 // This enables to distinguish between different ICs of the HITAG family
49 // | UID 3 |
50 // msb | PID 1 | PID 0 | lsb
51 // Condition for HITAG S: PID 1 = 0x7 – 0xF and PID 0 ≠ 0x5 – 0x6
53 //uid s/n ********
54 uint8_t pid0 = NIBBLE_LOW(uid);
55 uint8_t pid1 = NIBBLE_HIGH(uid);
56 if (pid1 >= 0x7 && pid1 <= 0xF && pid0 != 0x5 && pid0 != 0x6) {
57 switch (pid1) {
58 case 1:
59 return "PCF 7936";
60 case 2:
61 return "PCF 7946";
62 case 3:
63 return "PCF 7947";
64 case 4:
65 return "PCF 7942/44";
66 case 5:
67 return "PCF 7943";
68 case 6:
69 return "PCF 7941";
70 case 7:
71 return "PCF 7952";
72 case 9:
73 return "PCF 7945";
74 default:
75 return "n/a";
77 } else
78 return "Probably not NXP Hitag S";
81 static bool hts_get_uid(uint32_t *uid) {
82 clearCommandBuffer();
83 SendCommandNG(CMD_LF_HITAGS_UID, NULL, 0);
84 PacketResponseNG resp;
85 if (WaitForResponseTimeout(CMD_LF_HITAGS_UID, &resp, 1500) == false) {
86 PrintAndLogEx(WARNING, "timeout while waiting for reply.");
87 return false;
90 if (resp.status != PM3_SUCCESS) {
91 PrintAndLogEx(DEBUG, "DEBUG: Error - failed getting UID");
92 return false;
95 if (uid) {
96 *uid = bytes_to_num(resp.data.asBytes, HITAG_UID_SIZE);
98 return true;
101 int read_hts_uid(void) {
102 uint32_t uid = 0;
103 if (hts_get_uid(&uid) == false) {
104 return PM3_ESOFT;
107 PrintAndLogEx(SUCCESS, "UID.... " _GREEN_("%08X"), uid);
108 PrintAndLogEx(SUCCESS, "TYPE... " _GREEN_("%s"), hts_get_type_str(uid));
109 return PM3_SUCCESS;
112 static int process_hitags_common_args(CLIParserContext *ctx, lf_hitag_data_t *const packet) {
114 bool use_plain = false;
115 bool use_82xx = arg_get_lit(ctx, 1);
117 bool use_nrar = false;
118 uint8_t nrar[HITAG_NRAR_SIZE];
119 int nrar_len = 0;
121 int res = CLIParamHexToBuf(arg_get_str(ctx, 2), nrar, HITAG_NRAR_SIZE, &nrar_len);
122 if (res != 0) {
123 CLIParserFree(ctx);
124 return PM3_EINVARG;
127 use_nrar = nrar_len > 0;
129 bool use_crypto = arg_get_lit(ctx, 3);
131 uint8_t key[HITAG_CRYPTOKEY_SIZE];
132 int key_len = 0;
134 res = CLIParamHexToBuf(arg_get_str(ctx, 4), key, HITAG_CRYPTOKEY_SIZE, &key_len);
135 if (res != 0) {
136 CLIParserFree(ctx);
137 return PM3_EINVARG;
140 if (key_len != 0 && key_len != HITAG_PASSWORD_SIZE && key_len != HITAG_CRYPTOKEY_SIZE) {
141 PrintAndLogEx(WARNING, "Wrong KEY len expected 0, 4 or 6, got %d", key_len);
142 return PM3_EINVARG;
145 if (nrar_len && nrar_len != HITAG_NRAR_SIZE) {
146 PrintAndLogEx(WARNING, "Wrong NR/AR len expected %d, got %d", HITAG_NRAR_SIZE, nrar_len);
147 return PM3_EINVARG;
150 uint8_t mode = arg_get_int_def(ctx, 5, 3);
152 if (mode > 3) {
153 PrintAndLogEx(WARNING, "Wrong response protocol mode, expected 0, 1, 2 or 3, got %d", mode);
154 return PM3_EINVARG;
157 // complete options
158 switch (key_len) {
159 case HITAG_PASSWORD_SIZE:
160 use_82xx = true;
161 break;
162 case HITAG_CRYPTOKEY_SIZE:
163 use_crypto = true;
164 break;
165 default: // key_len == 0
166 if (use_82xx) {
167 memcpy(key, "\xBB\xDD\x33\x99", 4);
168 key_len = 4;
169 } else if (use_crypto) {
170 memcpy(key, "ONMIKR", 6);
171 key_len = 6;
175 // check coherence
176 uint8_t auth_methods = (use_plain + use_nrar + use_82xx + use_crypto);
177 if (auth_methods > 1) {
178 PrintAndLogEx(WARNING, "Specify only one authentication mode");
179 return PM3_EINVARG;
182 if (auth_methods == 0) {
183 use_plain = true;
186 memset(packet, 0, sizeof(*packet));
188 if (use_plain) {
189 PrintAndLogEx(INFO, "Access " _YELLOW_("Hitag S") " in Plain mode");
190 } else if (use_nrar) {
191 packet->cmd = HTSF_CHALLENGE;
192 memcpy(packet->NrAr, nrar, sizeof(packet->NrAr));
193 PrintAndLogEx(INFO, "Authenticating to " _YELLOW_("Hitag S") " in Challenge mode");
194 } else if (use_82xx) {
195 packet->cmd = HTSF_82xx;
196 memcpy(packet->pwd, key, sizeof(packet->pwd));
197 PrintAndLogEx(INFO, "Authenticating to " _YELLOW_("Hitag S") " in 82xx mode");
198 } else if (use_crypto) {
199 packet->cmd = HTSF_KEY;
200 memcpy(packet->key, key, sizeof(packet->key));
201 PrintAndLogEx(INFO, "Authenticating to " _YELLOW_("Hitag S") " in Crypto mode");
204 switch (mode) {
205 case 0:
206 packet->mode = HITAGS_UID_REQ_STD;
207 break;
208 case 1:
209 packet->mode = HITAGS_UID_REQ_ADV1;
210 break;
211 case 2:
212 packet->mode = HITAGS_UID_REQ_ADV2;
213 break;
214 default:
215 packet->mode = HITAGS_UID_REQ_FADV;
216 break;
219 return PM3_SUCCESS;
222 static void print_error(int8_t reason) {
223 switch (reason) {
224 case -2:
225 PrintAndLogEx(FAILED, "UID Request failed!");
226 break;
227 case -3:
228 PrintAndLogEx(FAILED, "Select UID failed!");
229 break;
230 case -4:
231 PrintAndLogEx(FAILED, "No write access on page " _YELLOW_("64") ". not 82xx?");
232 break;
233 case -5:
234 PrintAndLogEx(FAILED, "Write to page " _YELLOW_("64") " failed! wrong password?");
235 break;
236 case -6:
237 PrintAndLogEx(FAILED, "Error, " _YELLOW_("AUT=1") " This tag is configured in Authentication Mode");
238 break;
239 case -7:
240 PrintAndLogEx(FAILED, "Error, unknown function");
241 break;
242 case -8:
243 PrintAndLogEx(FAILED, "Authenticate failed!");
244 break;
245 case -9:
246 PrintAndLogEx(FAILED, "No write access on page");
247 break;
248 case -10:
249 PrintAndLogEx(FAILED, "Write to page failed!");
250 break;
251 case -11:
252 PrintAndLogEx(FAILED, "Read page failed!");
253 break;
254 default:
255 // PM3_REASON_UNKNOWN
256 PrintAndLogEx(DEBUG, "DEBUG: Error - Hitag S failed");
260 static int CmdLFHitagSRead(const char *Cmd) {
261 CLIParserContext *ctx;
262 CLIParserInit(&ctx, "lf hitag hts rdbl",
263 "Read Hitag S memory.\n\n"
264 " Crypto mode: \n"
265 " - key format ISK high + ISK low\n"
266 " - default key 4F4E4D494B52 (ONMIKR)\n\n"
267 " 8268/8310 password mode: \n"
268 " - default password BBDD3399\n",
269 " lf hitag hts rdbl -p 1 -> Hitag S/8211, plain mode\n"
270 " lf hitag hts rdbl -p 1 --82xx -k BBDD3399 -> 8268/8310, password mode\n"
271 " lf hitag hts rdbl -p 1 --nrar 0102030411223344 -> Hitag S, challenge mode\n"
272 " lf hitag hts rdbl -p 1 --crypto -> Hitag S, crypto mode, def key\n"
273 " lf hitag hts rdbl -p 1 -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n"
276 void *argtable[] = {
277 arg_param_begin,
278 arg_lit0("8", "82xx", "8268/8310 mode"),
279 arg_str0(NULL, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
280 arg_lit0(NULL, "crypto", "crypto mode"),
281 arg_str0("k", "key", "<hex>", "pwd or key, 4 or 6 hex bytes"),
282 arg_int0("m", "mode", "<dec>", "response protocol mode. 0 (Standard 00110), 1 (Advanced 11000), 2 (Advanced 11001), 3 (Fast Advanced 11010) (def: 3)"),
283 arg_int0("p", "page", "<dec>", "page address to read from"),
284 arg_int0("c", "count", "<dec>", "how many pages to read. '0' reads all pages up to the end page (def: 1)"),
285 arg_param_end
287 CLIExecWithReturn(ctx, Cmd, argtable, true);
289 lf_hitag_data_t packet;
291 if (process_hitags_common_args(ctx, &packet) < 0) return PM3_EINVARG;
293 uint32_t page = arg_get_int_def(ctx, 6, 0);
295 if (page > 255) {
296 PrintAndLogEx(WARNING, "Page address Invalid.");
297 return PM3_EINVARG;
300 uint32_t count = arg_get_int_def(ctx, 7, 1);
302 if (count > HITAGS_MAX_PAGES) {
303 PrintAndLogEx(WARNING, "No more than 64 pages can be read at once.");
304 return PM3_EINVARG;
307 CLIParserFree(ctx);
309 packet.page = page;
310 packet.page_count = count;
312 clearCommandBuffer();
313 SendCommandNG(CMD_LF_HITAGS_READ, (uint8_t *) &packet, sizeof(packet));
315 PacketResponseNG resp;
316 if (WaitForResponseTimeout(CMD_LF_HITAGS_READ, &resp, 2000) == false) {
317 PrintAndLogEx(WARNING, "timeout while waiting for reply.");
318 SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
319 return PM3_ETIMEOUT;
322 if (resp.status != PM3_SUCCESS) {
323 print_error(resp.reason);
324 return PM3_ESOFT;
327 lf_hts_read_response_t *card = (lf_hts_read_response_t *)resp.data.asBytes;
329 hitags_config_t config = card->config_page.s;
331 PrintAndLogEx(NORMAL, "");
332 PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
334 hitags_config_print(config);
336 PrintAndLogEx(NORMAL, "");
337 PrintAndLogEx(INFO, "--- " _CYAN_("Tag Data") " ---------------------------");
338 PrintAndLogEx(INFO, " # | 00 01 02 03 | ascii | perm | info");
339 PrintAndLogEx(INFO, "----+-------------+-------+------+------");
341 const int hts_mem_sizes[] = {1, 8, 64, 64};
343 if (count == 0) {
344 count = hts_mem_sizes[config.MEMT] > page ? hts_mem_sizes[config.MEMT] - page : 64;
347 // int page_end = page + count;
348 // page_end = MIN(page_end, 255);
350 for (int i = 0; i < count; ++i) {
351 int page_addr = page + i;
352 if (page_addr > 255) {
353 break;
355 if (card->pages_reason[i] >= 0) {
356 PrintAndLogEx(SUCCESS, "% 3u | %s | " NOLF, page_addr, sprint_hex_ascii(card->pages[i], HITAGS_PAGE_SIZE));
358 // access right
359 if (page_addr == HITAGS_UID_PADR) {
360 PrintAndLogEx(NORMAL, _RED_("RO ")NOLF);
361 } else if (page_addr == HITAGS_CONFIG_PADR) {
362 if (card->config_page.s.LCON)
363 PrintAndLogEx(NORMAL, _YELLOW_("OTP ")NOLF);
364 else
365 PrintAndLogEx(NORMAL, _GREEN_("RW ")NOLF);
366 } else if (2 <= page_addr && page_addr <= 3) {
367 if (card->config_page.s.LKP)
368 if (card->config_page.s.auth)
369 PrintAndLogEx(NORMAL, _RED_("NO ")NOLF);
370 else
371 PrintAndLogEx(NORMAL, _RED_("RO ")NOLF);
372 else
373 PrintAndLogEx(NORMAL, _GREEN_("RW ")NOLF);
374 } else if (4 <= page_addr && page_addr <= 5) {
375 if (card->config_page.s.LCK7)
376 if (card->config_page.s.TTFDR == 2 && page_addr == 5)
377 PrintAndLogEx(NORMAL, _YELLOW_("RO/W")NOLF);
378 else
379 PrintAndLogEx(NORMAL, _RED_("RO ")NOLF);
380 else
381 PrintAndLogEx(NORMAL, _GREEN_("RW ")NOLF);
382 } else if (6 <= page_addr && page_addr <= 7) {
383 if (card->config_page.s.LCK6)
384 PrintAndLogEx(NORMAL, _RED_("RO ")NOLF);
385 else
386 PrintAndLogEx(NORMAL, _GREEN_("RW ")NOLF);
387 } else if (8 <= page_addr && page_addr <= 11) {
388 if (card->config_page.s.LCK5)
389 PrintAndLogEx(NORMAL, _RED_("RO ")NOLF);
390 else
391 PrintAndLogEx(NORMAL, _GREEN_("RW ")NOLF);
392 } else if (12 <= page_addr && page_addr <= 15) {
393 if (card->config_page.s.LCK4)
394 PrintAndLogEx(NORMAL, _RED_("RO ")NOLF);
395 else
396 PrintAndLogEx(NORMAL, _GREEN_("RW ")NOLF);
397 } else if (16 <= page_addr && page_addr <= 23) {
398 if (card->config_page.s.LCK3)
399 PrintAndLogEx(NORMAL, _RED_("RO ")NOLF);
400 else
401 PrintAndLogEx(NORMAL, _GREEN_("RW ")NOLF);
402 } else if (24 <= page_addr && page_addr <= 32) {
403 if (card->config_page.s.LCK2)
404 PrintAndLogEx(NORMAL, _RED_("RO ")NOLF);
405 else
406 PrintAndLogEx(NORMAL, _GREEN_("RW ")NOLF);
407 } else if (32 <= page_addr && page_addr <= 47) {
408 if (card->config_page.s.LCK1)
409 PrintAndLogEx(NORMAL, _RED_("RO ")NOLF);
410 else
411 PrintAndLogEx(NORMAL, _GREEN_("RW ")NOLF);
412 } else if (48 <= page_addr && page_addr <= 63) {
413 if (card->config_page.s.LCK0)
414 PrintAndLogEx(NORMAL, _RED_("RO ")NOLF);
415 else
416 PrintAndLogEx(NORMAL, _GREEN_("RW ")NOLF);
417 } else
418 PrintAndLogEx(NORMAL, _YELLOW_("UNK ") NOLF);
420 PrintAndLogEx(NORMAL, " | " NOLF);
422 // info
423 if (page_addr == HITAGS_UID_PADR) {
424 PrintAndLogEx(NORMAL, "UID");
425 } else if (page_addr == HITAGS_CONFIG_PADR) {
426 PrintAndLogEx(NORMAL, "Config");
427 } else if (page_addr == 2 && card->config_page.s.auth) {
428 PrintAndLogEx(NORMAL, "Pwd/Key");
429 } else if (page_addr == 3 && card->config_page.s.auth) {
430 PrintAndLogEx(NORMAL, "Key");
431 } else
432 PrintAndLogEx(NORMAL, "Data");
433 } else {
434 PrintAndLogEx(INFO, "% 3u | -- -- -- -- | .... | N/A | " NOLF, page_addr);
435 print_error(card->pages_reason[i]);
439 PrintAndLogEx(INFO, "----+-------------+-------+------+------");
440 PrintAndLogEx(INFO, " " _RED_("RO") " = Read Only, " _GREEN_("RW") " = Read Write");
441 PrintAndLogEx(INFO, " " _YELLOW_("OTP") " = One Time Programmable");
442 PrintAndLogEx(INFO, " " _YELLOW_("RO/W") " = Partially Read Write");
443 PrintAndLogEx(INFO, "----------------------------------------");
444 return PM3_SUCCESS;
447 static int CmdLFHitagSWrite(const char *Cmd) {
448 CLIParserContext *ctx;
449 CLIParserInit(&ctx, "lf hitag hts wrbl",
450 "Write a page in Hitag S memory.\n"
451 " Crypto mode: \n"
452 " - key format ISK high + ISK low\n"
453 " - default key 4F4E4D494B52 (ONMIKR)\n\n"
454 " 8268/8310 password mode: \n"
455 " - default password BBDD3399\n",
456 " lf hitag hts wrbl -p 6 -d 01020304 -> Hitag S/8211, plain mode\n"
457 " lf hitag hts wrbl -p 6 -d 01020304 --82xx -k BBDD3399 -> 8268/8310, password mode\n"
458 " lf hitag hts wrbl -p 6 -d 01020304 --nrar 0102030411223344 -> Hitag S, challenge mode\n"
459 " lf hitag hts wrbl -p 6 -d 01020304 --crypto -> Hitag S, crypto mode, default key\n"
460 " lf hitag hts wrbl -p 6 -d 01020304 -k 4F4E4D494B52 -> Hitag S, crypto mode\n\n"
463 void *argtable[] = {
464 arg_param_begin,
465 arg_lit0("8", "82xx", "8268/8310 mode"),
466 arg_str0(NULL, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
467 arg_lit0(NULL, "crypto", "crypto mode"),
468 arg_str0("k", "key", "<hex>", "pwd or key, 4 or 6 hex bytes"),
469 arg_int0("m", "mode", "<dec>", "response protocol mode. 0 (Standard 00110), 1 (Advanced 11000), 2 (Advanced 11001), 3 (Fast Advanced 11010) (def: 3)"),
470 arg_int1("p", "page", "<dec>", "page address to write to"),
471 arg_str1("d", "data", "<hex>", "data, 4 hex bytes"),
472 arg_param_end
474 CLIExecWithReturn(ctx, Cmd, argtable, false);
476 lf_hitag_data_t packet;
478 if (process_hitags_common_args(ctx, &packet) < 0) return PM3_EINVARG;
480 int page = arg_get_int_def(ctx, 6, 0);
482 uint8_t data[HITAGS_PAGE_SIZE];
483 int data_len = 0;
485 int res = CLIParamHexToBuf(arg_get_str(ctx, 7), data, HITAGS_PAGE_SIZE, &data_len);
486 if (res != 0) {
487 CLIParserFree(ctx);
488 return PM3_EINVARG;
491 CLIParserFree(ctx);
493 packet.page = page;
494 memcpy(packet.data, data, sizeof(packet.data));
496 clearCommandBuffer();
497 SendCommandNG(CMD_LF_HITAGS_WRITE, (uint8_t *) &packet, sizeof(packet));
499 PacketResponseNG resp;
500 if (WaitForResponseTimeout(CMD_LF_HITAGS_WRITE, &resp, 4000) == false) {
501 PrintAndLogEx(WARNING, "timeout while waiting for reply.");
502 return PM3_ETIMEOUT;
505 if (resp.status == PM3_ETEAROFF) {
506 PrintAndLogEx(INFO, "Writing tear off triggered");
507 return PM3_SUCCESS;
510 if (resp.status != PM3_SUCCESS) {
511 print_error(resp.reason);
512 return resp.status;
515 PrintAndLogEx(SUCCESS, "Write ( " _GREEN_("ok") " )");
516 return PM3_SUCCESS;
519 static int CmdLFHitagSReader(const char *Cmd) {
520 CLIParserContext *ctx;
521 CLIParserInit(&ctx, "lf hitag hts reader",
522 "Act as a Hitag S reader. Look for Hitag S tags until Enter or the pm3 button is pressed\n",
523 "lf hitag hts reader\n"
524 "lf hitag hts reader -@ -> Continuous mode"
527 void *argtable[] = {
528 arg_param_begin,
529 arg_lit0("@", NULL, "continuous reader mode"),
530 arg_param_end
532 CLIExecWithReturn(ctx, Cmd, argtable, true);
533 bool cm = arg_get_lit(ctx, 1);
534 CLIParserFree(ctx);
536 if (cm) {
537 PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
540 do {
541 // read UID
542 uint32_t uid = 0;
543 if (hts_get_uid(&uid)) {
544 PrintAndLogEx(SUCCESS, "UID.... " _GREEN_("%08X"), uid);
546 } while (cm && kbd_enter_pressed() == false);
548 return PM3_SUCCESS;
551 static int CmdLFHitagSSim(const char *Cmd) {
552 CLIParserContext *ctx;
553 CLIParserInit(&ctx, "lf hitag hts sim",
554 "Simulate Hitag S transponder\n"
555 "You need to `lf hitag hts eload` first",
556 "lf hitag hts sim\n"
557 "lf hitag hts sim --82xx");
559 void *argtable[] = {
560 arg_param_begin,
561 arg_lit0("8", "82xx", "simulate 8268/8310"),
562 arg_param_end
564 CLIExecWithReturn(ctx, Cmd, argtable, true);
566 // bool use_82xx = arg_get_lit(ctx, 1); // not implemented yet
567 CLIParserFree(ctx);
569 clearCommandBuffer();
570 SendCommandMIX(CMD_LF_HITAGS_SIMULATE, false, 0, 0, NULL, 0);
571 return PM3_SUCCESS;
574 static int CmdLFHitagSList(const char *Cmd) {
575 return CmdTraceListAlias(Cmd, "lf hitag hts", "hitags");
578 void hitags_config_print(hitags_config_t config) {
579 PrintAndLogEx(INFO, " Memory type...... " _GREEN_("%s"),
580 (const char *[]) {
581 "Hitag S 32", "Hitag S 256", "Hitag S 2048",
582 "Unknown Hitag S/8211"
583 }[config.MEMT]);
585 PrintAndLogEx(INFO, " Authenticaion.... %s", config.auth ? _YELLOW_("Yes") : "No");
587 PrintAndLogEx(INFO, " TTF coding....... %s",
588 config.RES3 ? "FSK 0=RF/10 1=RF/8" : (const char *[]) {"Manchester", "Biphase"}[config.TTFC]);
590 PrintAndLogEx(INFO, " TTF data rate.... %s",
591 (const char *[]) {
592 "4 kBit", "8 kBit", "2 kBit",
593 "2 kBit and Pigeon Race Standard"
594 }[config.TTFDR]);
596 PrintAndLogEx(INFO, " TTF mode......... %s",
597 (const char *[]) {
598 "TTF Mode disabled (= RTF Mode)",
599 "Page 4, Page 5",
600 "Page 4, Page 5, Page 6, Page 7",
601 "Page 4",
602 "TTF Mode disabled (= RTF Mode)",
603 "Page 4, Page 5, Page 6",
604 "Page 4, Page 5, Page 6, Page 7, Page 8",
605 "Page 4, Page 5, Page 6, Page 7, Page 8, Page 9, Page 10, Page 11",
606 }[config.RES0 << 2 | config.TTFM]);
608 PrintAndLogEx(INFO, " Config locked.... %s", config.LCON ? _RED_("Yes") : _GREEN_("No"));
609 PrintAndLogEx(INFO, " Key/PWD locked... %s", config.LKP ? _RED_("Yes") : _GREEN_("No"));
612 static command_t CommandTable[] = {
613 {"help", CmdHelp, AlwaysAvailable, "This help"},
614 {"list", CmdLFHitagSList, AlwaysAvailable, "List Hitag S trace history"},
615 {"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("General") " ------------------------"},
616 {"reader", CmdLFHitagSReader, IfPm3Hitag, "Act like a Hitag S reader"},
617 {"rdbl", CmdLFHitagSRead, IfPm3Hitag, "Read Hitag S page"},
618 {"wrbl", CmdLFHitagSWrite, IfPm3Hitag, "Write Hitag S page"},
619 {"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("Simulation") " -----------------------"},
620 {"sim", CmdLFHitagSSim, IfPm3Hitag, "Simulate Hitag S transponder"},
621 {NULL, NULL, 0, NULL}
624 static int CmdHelp(const char *Cmd) {
625 (void) Cmd; // Cmd is not used so far
626 CmdsHelp(CommandTable);
627 return PM3_SUCCESS;
630 int CmdLFHitagS(const char *Cmd) {
631 clearCommandBuffer();
632 return CmdsParse(CommandTable, Cmd);