1 //-----------------------------------------------------------------------------
3 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>, Hagen Fritsch
5 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 // at your option, any later version. See the LICENSE.txt file for the text of
8 //-----------------------------------------------------------------------------
9 // High frequency ISO14443A commands
10 //-----------------------------------------------------------------------------
18 #include "iso14443crc.h"
22 #include "cmdparser.h"
26 #include "nonce2key/nonce2key.h"
27 #include "nonce2key/crapto1.h"
28 #include "mifarehost.h"
30 static int CmdHelp(const char *Cmd
);
32 int CmdHF14AList(const char *Cmd
)
35 GetFromBigBuf(got
, sizeof(got
));
37 PrintAndLog("recorded activity:");
38 PrintAndLog(" ETU :rssi: who bytes");
39 PrintAndLog("---------+----+----+-----------");
50 int timestamp
= *((uint32_t *)(got
+i
));
51 if (timestamp
& 0x80000000) {
52 timestamp
&= 0x7fffffff;
59 int parityBits
= *((uint32_t *)(got
+i
+4));
60 // 4 bytes of additional information...
61 // maximum of 32 additional parity bit information
64 // at each quarter bit period we can send power level (16 levels)
65 // or each half bit period in 256 levels.
73 if (i
+ len
>= 1900) {
77 uint8_t *frame
= (got
+i
+9);
79 // Break and stick with current result if buffer was not completely full
80 if (frame
[0] == 0x44 && frame
[1] == 0x44 && frame
[3] == 0x44) { break; }
84 for (j
= 0; j
< len
; j
++) {
89 oddparity
^= (((frame
[j
] & 0xFF) >> k
) & 0x01);
92 //if((parityBits >> (len - j - 1)) & 0x01) {
93 if (isResponse
&& (oddparity
!= ((parityBits
>> (len
- j
- 1)) & 0x01))) {
94 sprintf(line
+(j
*4), "%02x! ", frame
[j
]);
97 sprintf(line
+(j
*4), "%02x ", frame
[j
]);
105 for (j
= 0; j
< (len
- 1); j
++) {
106 // gives problems... search for the reason..
107 /*if(frame[j] == 0xAA) {
110 crc = "[1] Two drops close after each other";
113 crc = "[2] Potential SOC with a drop in second half of bitperiod";
116 crc = "[3] Segment Z after segment X is not possible";
119 crc = "[4] Parity bit of a fully received byte was wrong";
122 crc = "[?] Unknown error";
129 if (strlen(crc
)==0) {
130 ComputeCrc14443(CRC_14443_A
, frame
, len
-2, &b1
, &b2
);
131 if (b1
!= frame
[len
-2] || b2
!= frame
[len
-1]) {
132 crc
= (isResponse
& (len
< 6)) ? "" : " !crc";
141 char metricString
[100];
143 sprintf(metricString
, "%3d", metric
);
145 strcpy(metricString
, " ");
148 PrintAndLog(" +%7d: %s: %s %s %s",
149 (prev
< 0 ? 0 : (timestamp
- prev
)),
151 (isResponse
? "TAG" : " "), line
, crc
);
159 void iso14a_set_timeout(uint32_t timeout
) {
160 UsbCommand c
= {CMD_READER_ISO_14443a
, {ISO14A_SET_TIMEOUT
, 0, timeout
}};
164 int CmdHF14AMifare(const char *Cmd
)
168 uint64_t par_list
= 0, ks_list
= 0, r_key
= 0;
170 uint8_t keyBlock
[6] = {0,0,0,0,0,0};
172 if (param_getchar(Cmd
, 0) && param_gethex(Cmd
, 0, keyBlock
, 8)) {
173 PrintAndLog("Nt must include 8 HEX symbols");
177 UsbCommand c
= {CMD_READER_MIFARE
, {(uint32_t)bytes_to_num(keyBlock
, 4), 0, 0}};
181 while (ukbhit()) getchar();
184 printf("-------------------------------------------------------------------------\n");
185 printf("Executing command. It may take up to 30 min.\n");
186 printf("Press the key on proxmark3 device to abort proxmark3.\n");
187 printf("Press the key on the proxmark3 device to abort both proxmark3 and client.\n");
188 printf("-------------------------------------------------------------------------\n");
195 printf("\naborted via keyboard!\n");
199 UsbCommand
* resp
= WaitForResponseTimeout(CMD_ACK
, 2000);
201 isOK
= resp
->arg
[0] & 0xff;
203 uid
= (uint32_t)bytes_to_num(resp
->d
.asBytes
+ 0, 4);
204 nt
= (uint32_t)bytes_to_num(resp
->d
.asBytes
+ 4, 4);
205 par_list
= bytes_to_num(resp
->d
.asBytes
+ 8, 8);
206 ks_list
= bytes_to_num(resp
->d
.asBytes
+ 16, 8);
209 PrintAndLog("isOk:%02x", isOK
);
210 if (!isOK
) PrintAndLog("Proxmark can't get statistic info. Execution aborted.\n");
217 if (isOK
!= 1) return 1;
219 // execute original function from util nonce2key
220 if (nonce2key(uid
, nt
, par_list
, ks_list
, &r_key
)) return 2;
221 printf("------------------------------------------------------------------\n");
222 PrintAndLog("Key found:%012llx \n", r_key
);
224 num_to_bytes(r_key
, 6, keyBlock
);
225 isOK
= mfCheckKeys(0, 0, 1, keyBlock
, &r_key
);
227 PrintAndLog("Found valid key:%012llx", r_key
);
229 PrintAndLog("Found invalid key. (");
235 int CmdHF14AMfWrBl(const char *Cmd
)
239 uint8_t key
[6] = {0, 0, 0, 0, 0, 0};
240 uint8_t bldata
[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
245 PrintAndLog("Usage: hf 14 mfwrbl <block number> <key A/B> <key (12 hex symbols)> <block data (32 hex symbols)>");
246 PrintAndLog(" sample: hf 14a mfwrbl 0 A FFFFFFFFFFFF 000102030405060708090A0B0C0D0E0F");
250 blockNo
= param_get8(Cmd
, 0);
251 cmdp
= param_getchar(Cmd
, 1);
253 PrintAndLog("Key type must be A or B");
256 if (cmdp
!= 'A' && cmdp
!= 'a') keyType
= 1;
257 if (param_gethex(Cmd
, 2, key
, 12)) {
258 PrintAndLog("Key must include 12 HEX symbols");
261 if (param_gethex(Cmd
, 3, bldata
, 32)) {
262 PrintAndLog("Block data must include 32 HEX symbols");
265 PrintAndLog("--block no:%02x key type:%02x key:%s", blockNo
, keyType
, sprint_hex(key
, 6));
266 PrintAndLog("--data: %s", sprint_hex(bldata
, 16));
268 UsbCommand c
= {CMD_MIFARE_WRITEBL
, {blockNo
, keyType
, 0}};
269 memcpy(c
.d
.asBytes
, key
, 6);
270 memcpy(c
.d
.asBytes
+ 10, bldata
, 16);
272 UsbCommand
* resp
= WaitForResponseTimeout(CMD_ACK
, 1500);
275 uint8_t isOK
= resp
->arg
[0] & 0xff;
277 PrintAndLog("isOk:%02x", isOK
);
279 PrintAndLog("Command execute timeout");
285 int CmdHF14AMfRdBl(const char *Cmd
)
289 uint8_t key
[6] = {0, 0, 0, 0, 0, 0};
295 PrintAndLog("Usage: hf 14 mfrdbl <block number> <key A/B> <key (12 hex symbols)>");
296 PrintAndLog(" sample: hf 14a mfrdbl 0 A FFFFFFFFFFFF ");
300 blockNo
= param_get8(Cmd
, 0);
301 cmdp
= param_getchar(Cmd
, 1);
303 PrintAndLog("Key type must be A or B");
306 if (cmdp
!= 'A' && cmdp
!= 'a') keyType
= 1;
307 if (param_gethex(Cmd
, 2, key
, 12)) {
308 PrintAndLog("Key must include 12 HEX symbols");
311 PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo
, keyType
, sprint_hex(key
, 6));
313 UsbCommand c
= {CMD_MIFARE_READBL
, {blockNo
, keyType
, 0}};
314 memcpy(c
.d
.asBytes
, key
, 6);
316 UsbCommand
* resp
= WaitForResponseTimeout(CMD_ACK
, 1500);
319 uint8_t isOK
= resp
->arg
[0] & 0xff;
320 uint8_t * data
= resp
->d
.asBytes
;
323 PrintAndLog("isOk:%02x data:%s", isOK
, sprint_hex(data
, 16));
325 PrintAndLog("isOk:%02x", isOK
);
327 PrintAndLog("Command execute timeout");
333 int CmdHF14AMfRdSc(const char *Cmd
)
336 uint8_t sectorNo
= 0;
338 uint8_t key
[6] = {0, 0, 0, 0, 0, 0};
341 uint8_t * data
= NULL
;
346 PrintAndLog("Usage: hf 14 mfrdsc <sector number> <key A/B> <key (12 hex symbols)>");
347 PrintAndLog(" sample: hf 14a mfrdsc 0 A FFFFFFFFFFFF ");
351 sectorNo
= param_get8(Cmd
, 0);
353 PrintAndLog("Sector number must be less than 64");
356 cmdp
= param_getchar(Cmd
, 1);
358 PrintAndLog("Key type must be A or B");
361 if (cmdp
!= 'A' && cmdp
!= 'a') keyType
= 1;
362 if (param_gethex(Cmd
, 2, key
, 12)) {
363 PrintAndLog("Key must include 12 HEX symbols");
366 PrintAndLog("--sector no:%02x key type:%02x key:%s ", sectorNo
, keyType
, sprint_hex(key
, 6));
368 UsbCommand c
= {CMD_MIFARE_READSC
, {sectorNo
, keyType
, 0}};
369 memcpy(c
.d
.asBytes
, key
, 6);
371 UsbCommand
* resp
= WaitForResponseTimeout(CMD_ACK
, 1500);
375 isOK
= resp
->arg
[0] & 0xff;
376 data
= resp
->d
.asBytes
;
378 PrintAndLog("isOk:%02x", isOK
);
380 for (i
= 0; i
< 2; i
++) {
381 PrintAndLog("data:%s", sprint_hex(data
+ i
* 16, 16));
384 PrintAndLog("Command1 execute timeout");
388 resp
= WaitForResponseTimeout(CMD_ACK
, 500);
392 isOK
= resp
->arg
[0] & 0xff;
393 data
= resp
->d
.asBytes
;
396 for (i
= 0; i
< 2; i
++) {
397 PrintAndLog("data:%s", sprint_hex(data
+ i
* 16, 16));
400 PrintAndLog("Command2 execute timeout");
406 int CmdHF14AMfNested(const char *Cmd
)
408 int i
, j
, res
, iterations
;
409 sector
* e_sector
= NULL
;
412 uint8_t trgBlockNo
= 0;
413 uint8_t trgKeyType
= 0;
416 uint8_t key
[6] = {0, 0, 0, 0, 0, 0};
417 uint8_t keyBlock
[16 * 6];
423 PrintAndLog("Usage:");
424 PrintAndLog(" all sectors: hf 14a nested <card memory> <block number> <key A/B> <key (12 hex symbols)>");
425 PrintAndLog(" one sector: hf 14a nested o <block number> <key A/B> <key (12 hex symbols)>");
426 PrintAndLog(" <target block number> <target key A/B>");
427 PrintAndLog("card memory - 1 - 1K, 2 - 2K, 4 - 4K, <other> - 1K");
429 PrintAndLog(" sample1: hf 14a nested 1 0 A FFFFFFFFFFFF ");
430 PrintAndLog(" sample2: hf 14a nested o 0 A FFFFFFFFFFFF 4 A");
434 cmdp
= param_getchar(Cmd
, 0);
435 blockNo
= param_get8(Cmd
, 1);
436 ctmp
= param_getchar(Cmd
, 2);
438 PrintAndLog("Key type must be A or B");
441 if (ctmp
!= 'A' && ctmp
!= 'a') keyType
= 1;
442 if (param_gethex(Cmd
, 3, key
, 12)) {
443 PrintAndLog("Key must include 12 HEX symbols");
447 if (cmdp
=='o' || cmdp
== 'O') {
449 trgBlockNo
= param_get8(Cmd
, 4);
450 ctmp
= param_getchar(Cmd
, 5);
452 PrintAndLog("Target key type must be A or B");
455 if (ctmp
!= 'A' && ctmp
!= 'a') trgKeyType
= 1;
458 case '1': SectorsCnt
= 16; break;
459 case '2': SectorsCnt
= 32; break;
460 case '4': SectorsCnt
= 64; break;
461 default: SectorsCnt
= 16;
465 PrintAndLog("--block no:%02x key type:%02x key:%s ", blockNo
, keyType
, sprint_hex(key
, 6));
467 PrintAndLog("--target block no:%02x target key type:%02x ", trgBlockNo
, trgKeyType
);
470 if (mfnested(blockNo
, keyType
, key
, trgBlockNo
, trgKeyType
, keyBlock
)) {
471 PrintAndLog("Nested error.");
475 for (i
= 0; i
< 16; i
++) {
476 PrintAndLog("cnt=%d key= %s", i
, sprint_hex(keyBlock
+ i
* 6, 6));
480 res
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, keyBlock
, &key64
);
482 res
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, &keyBlock
[6 * 8], &key64
);
484 PrintAndLog("Found valid key:%012llx", key64
);
486 PrintAndLog("No valid key found");
487 } else // ------------------------------------ multiple sectors working
489 blDiff
= blockNo
% 4;
490 PrintAndLog("Block shift=%d", blDiff
);
491 e_sector
= calloc(SectorsCnt
, sizeof(sector
));
492 if (e_sector
== NULL
) return 1;
494 //test current key 4 sectors
495 memcpy(keyBlock
, key
, 6);
496 num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock
+ 1 * 6));
497 num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock
+ 2 * 6));
498 num_to_bytes(0xffffffffffff, 6, (uint8_t*)(keyBlock
+ 3 * 6));
499 num_to_bytes(0x000000000000, 6, (uint8_t*)(keyBlock
+ 4 * 6));
500 num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock
+ 5 * 6));
502 PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt
);
503 for (i
= 0; i
< SectorsCnt
; i
++) {
504 for (j
= 0; j
< 2; j
++) {
505 if (e_sector
[i
].foundKey
[j
]) continue;
507 res
= mfCheckKeys(i
* 4 + blDiff
, j
, 6, keyBlock
, &key64
);
510 e_sector
[i
].Key
[j
] = key64
;
511 e_sector
[i
].foundKey
[j
] = 1;
519 PrintAndLog("nested...");
520 for (i
= 0; i
< NESTED_SECTOR_RETRY
; i
++) {
521 for (trgBlockNo
= blDiff
; trgBlockNo
< SectorsCnt
* 4; trgBlockNo
= trgBlockNo
+ 4)
522 for (trgKeyType
= 0; trgKeyType
< 2; trgKeyType
++) {
523 if (e_sector
[trgBlockNo
/ 4].foundKey
[trgKeyType
]) continue;
524 if (mfnested(blockNo
, keyType
, key
, trgBlockNo
, trgKeyType
, keyBlock
)) continue;
528 //try keys from nested
529 res
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, keyBlock
, &key64
);
531 res
= mfCheckKeys(trgBlockNo
, trgKeyType
, 8, &keyBlock
[6 * 8], &key64
);
533 PrintAndLog("Found valid key:%012llx", key64
);
534 e_sector
[trgBlockNo
/ 4].foundKey
[trgKeyType
] = 1;
535 e_sector
[trgBlockNo
/ 4].Key
[trgKeyType
] = key64
;
540 PrintAndLog("Iterations count: %d", iterations
);
542 PrintAndLog("|---|----------------|---|----------------|---|");
543 PrintAndLog("|blk|key A |res|key B |res|");
544 PrintAndLog("|---|----------------|---|----------------|---|");
545 for (i
= 0; i
< SectorsCnt
; i
++) {
546 PrintAndLog("|%03d| %012llx | %d | %012llx | %d |", i
,
547 e_sector
[i
].Key
[0], e_sector
[i
].foundKey
[0], e_sector
[i
].Key
[1], e_sector
[i
].foundKey
[1]);
549 PrintAndLog("|---|----------------|---|----------------|---|");
557 int CmdHF14AMfChk(const char *Cmd
)
564 uint8_t keyBlock
[8 * 6];
567 memset(keyBlock
, 0x00, sizeof(keyBlock
));
570 PrintAndLog("Usage: hf 14a chk <block number> <key A/B> [<key (12 hex symbols)>]");
571 PrintAndLog(" sample: hf 14a chk 0 A FFFFFFFFFFFF a0a1a2a3a4a5 b01b2b3b4b5 ");
575 blockNo
= param_get8(Cmd
, 0);
576 ctmp
= param_getchar(Cmd
, 1);
578 PrintAndLog("Key type must be A or B");
581 if (ctmp
!= 'A' && ctmp
!= 'a') keyType
= 1;
583 for (i
= 0; i
< 6; i
++) {
584 if (!isxdigit(param_getchar(Cmd
, 2 + i
))) break;
586 if (param_gethex(Cmd
, 2 + i
, keyBlock
+ 6 * i
, 12)) {
587 PrintAndLog("Key[%d] must include 12 HEX symbols", i
);
594 PrintAndLog("There is must be at least one key");
598 PrintAndLog("--block no:%02x key type:%02x key count:%d ", blockNo
, keyType
, keycnt
);
600 res
= mfCheckKeys(blockNo
, keyType
, keycnt
, keyBlock
, &key64
);
603 PrintAndLog("isOk:%02x valid key:%012llx", 1, key64
);
605 PrintAndLog("isOk:%02x", 0);
607 PrintAndLog("Command execute timeout");
613 int CmdHF14AMf1kSim(const char *Cmd
)
616 uint8_t uid
[4] = {0, 0, 0, 0};
618 const char *cmdp
= Cmd
;
622 PrintAndLog("Usage: hf 14a mfsim <uid (8 hex symbols)>");
623 PrintAndLog(" sample: hf 14a mfsim 0a0a0a0a ");
628 while (*cmdp
==' ' || *cmdp
=='\t') cmdp
++;
630 if (strlen(cmdp
) != 8) {
631 PrintAndLog("Length of UID must be 8 hex symbols");
635 for(i
= 0; i
< 4; i
++) {
636 sscanf((char[]){cmdp
[0],cmdp
[1],0},"%X",&temp
);
637 uid
[i
] = temp
& 0xff;
641 PrintAndLog(" uid:%s ", sprint_hex(uid
, 4));
643 UsbCommand c
= {CMD_SIMULATE_MIFARE_CARD
, {0, 0, 0}};
644 memcpy(c
.d
.asBytes
, uid
, 6);
651 int CmdHF14AReader(const char *Cmd
)
653 UsbCommand c
= {CMD_READER_ISO_14443a
, {ISO14A_CONNECT
, 0, 0}};
655 UsbCommand
* resp
= WaitForResponse(CMD_ACK
);
656 uint8_t * uid
= resp
->d
.asBytes
;
657 iso14a_card_select_t
* card
= uid
+ 12;
659 if(resp
->arg
[0] == 0) {
660 PrintAndLog("iso14443a card select failed");
664 PrintAndLog("ATQA : %02x %02x", card
->atqa
[0], card
->atqa
[1]);
665 PrintAndLog(" UID : %s", sprint_hex(uid
, 12));
666 PrintAndLog(" SAK : %02x [%d]", card
->sak
, resp
->arg
[0]);
667 if(resp
->arg
[0] == 1)
668 PrintAndLog(" ATS : %s", sprint_hex(card
->ats
, card
->ats_len
));
670 PrintAndLog("proprietary non-iso14443a card found, RATS not supported");
675 // ## simulate iso14443a tag
676 // ## greg - added ability to specify tag UID
677 int CmdHF14ASim(const char *Cmd
)
680 unsigned int hi
= 0, lo
= 0;
682 while (sscanf(&Cmd
[i
++], "%1x", &n
) == 1) {
683 hi
= (hi
<< 4) | (lo
>> 28);
684 lo
= (lo
<< 4) | (n
& 0xf);
687 // c.arg should be set to *Cmd or convert *Cmd to the correct format for a uid
688 UsbCommand c
= {CMD_SIMULATE_TAG_ISO_14443a
, {hi
, lo
, 0}};
689 PrintAndLog("Emulating 14443A TAG with UID %x%16x", hi
, lo
);
694 int CmdHF14ASnoop(const char *Cmd
)
696 UsbCommand c
= {CMD_SNOOP_ISO_14443a
};
701 static command_t CommandTable
[] =
703 {"help", CmdHelp
, 1, "This help"},
704 {"list", CmdHF14AList
, 0, "List ISO 14443a history"},
705 {"mifare", CmdHF14AMifare
, 0, "Read out sector 0 parity error messages. param - <used card nonce>"},
706 {"mfrdbl", CmdHF14AMfRdBl
, 0, "Read MIFARE classic block"},
707 {"mfrdsc", CmdHF14AMfRdSc
, 0, "Read MIFARE classic sector"},
708 {"mfwrbl", CmdHF14AMfWrBl
, 0, "Write MIFARE classic block"},
709 {"nested", CmdHF14AMfNested
, 0, "Test nested authentication"},
710 {"chk", CmdHF14AMfChk
, 0, "Test block up to 8 keys"},
711 {"mfsim", CmdHF14AMf1kSim
, 0, "Simulate MIFARE 1k card - NOT WORKING!!!"},
712 {"reader", CmdHF14AReader
, 0, "Act like an ISO14443 Type A reader"},
713 {"sim", CmdHF14ASim
, 0, "<UID> -- Fake ISO 14443a tag"},
714 {"snoop", CmdHF14ASnoop
, 0, "Eavesdrop ISO 14443 Type A"},
715 {NULL
, NULL
, 0, NULL
}
718 int CmdHF14A(const char *Cmd
)
721 while (WaitForResponseTimeout(CMD_ACK
, 500) != NULL
) ;
724 CmdsParse(CommandTable
, Cmd
);
728 int CmdHelp(const char *Cmd
)
730 CmdsHelp(CommandTable
);