]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmfu.c
1 //-----------------------------------------------------------------------------
2 // Ultralight Code (c) 2013,2014 Midnitesnake & Andy Davies of Pentura
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
8 // High frequency MIFARE ULTRALIGHT (C) commands
9 //-----------------------------------------------------------------------------
10 #include <openssl/des.h>
13 uint8_t MAX_ULTRA_BLOCKS
= 0x0f;
14 uint8_t MAX_ULTRAC_BLOCKS
= 0x2c;
15 uint8_t key1_blnk_data
[16] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 };
16 uint8_t key2_defa_data
[16] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f };
17 uint8_t key3_3des_data
[16] = { 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 };
18 uint8_t key4_nfc_data
[16] = { 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 };
19 uint8_t key5_ones_data
[16] = { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 };
21 static int CmdHelp(const char *Cmd
);
24 // Mifare Ultralight Write Single Block
26 int CmdHF14AMfUWrBl(const char *Cmd
){
28 bool chinese_card
= 0;
29 uint8_t bldata
[16] = {0x00};
33 PrintAndLog("Usage: hf mfu uwrbl <block number> <block data (8 hex symbols)> [w]");
34 PrintAndLog(" sample: hf mfu uwrbl 0 01020304");
37 blockNo
= param_get8(Cmd
, 0);
38 if (blockNo
>MAX_ULTRA_BLOCKS
){
39 PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
42 if (param_gethex(Cmd
, 1, bldata
, 8)) {
43 PrintAndLog("Block data must include 8 HEX symbols");
46 if (strchr(Cmd
,'w') != 0) {
52 PrintAndLog("Access Denied");
54 PrintAndLog("--specialblock no:%02x", blockNo
);
55 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
56 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
57 memcpy(d
.d
.asBytes
,bldata
, 4);
59 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
60 uint8_t isOK
= resp
.arg
[0] & 0xff;
61 PrintAndLog("isOk:%02x", isOK
);
63 PrintAndLog("Command execute timeout");
69 PrintAndLog("Access Denied");
71 PrintAndLog("--specialblock no:%02x", blockNo
);
72 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
73 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
74 memcpy(d
.d
.asBytes
,bldata
, 4);
76 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
77 uint8_t isOK
= resp
.arg
[0] & 0xff;
78 PrintAndLog("isOk:%02x", isOK
);
80 PrintAndLog("Command execute timeout");
86 PrintAndLog("Access Denied");
88 PrintAndLog("--specialblock no:%02x", blockNo
);
89 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
90 UsbCommand c
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
91 memcpy(c
.d
.asBytes
, bldata
, 4);
93 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
94 uint8_t isOK
= resp
.arg
[0] & 0xff;
95 PrintAndLog("isOk:%02x", isOK
);
97 PrintAndLog("Command execute timeout");
102 PrintAndLog("--specialblock no:%02x", blockNo
);
103 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
104 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
105 memcpy(d
.d
.asBytes
,bldata
, 4);
107 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
108 uint8_t isOK
= resp
.arg
[0] & 0xff;
109 PrintAndLog("isOk:%02x", isOK
);
111 PrintAndLog("Command execute timeout");
115 PrintAndLog("--block no:%02x", blockNo
);
116 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
117 UsbCommand e
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
118 memcpy(e
.d
.asBytes
,bldata
, 4);
120 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
121 uint8_t isOK
= resp
.arg
[0] & 0xff;
122 PrintAndLog("isOk:%02x", isOK
);
124 PrintAndLog("Command execute timeout");
132 // Mifare Ultralight Read Single Block
134 int CmdHF14AMfURdBl(const char *Cmd
){
139 PrintAndLog("Usage: hf mfu urdbl <block number>");
140 PrintAndLog(" sample: hfu mfu urdbl 0");
144 blockNo
= param_get8(Cmd
, 0);
145 // if (blockNo>MAX_ULTRA_BLOCKS){
146 // PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
149 PrintAndLog("--block no:%02x", (int)blockNo
);
150 UsbCommand c
= {CMD_MIFAREU_READBL
, {blockNo
}};
154 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
155 uint8_t isOK
= resp
.arg
[0] & 0xff;
156 uint8_t * data
= resp
.d
.asBytes
;
159 PrintAndLog("isOk:%02x data:%s", isOK
, sprint_hex(data
, 4));
161 PrintAndLog("isOk:%02x", isOK
);
163 PrintAndLog("Command execute timeout");
169 // Mifare Ultralight Read (Dump) Card Contents
171 int CmdHF14AMfURdCard(const char *Cmd
){
175 uint8_t *lockbytes_t
=NULL
;
176 uint8_t lockbytes
[2]={0x00};
179 uint8_t datatemp
[7]= {0x00};
182 uint8_t * data
= NULL
;
185 if (strchr(Cmd
,'x') != 0){
187 if ((fout
= fopen("dump_ultralight_data.bin","wb")) == NULL
) {
188 PrintAndLog("Could not create file name dumpdata.bin");
191 PrintAndLog("Dumping Ultralight Card Data...");
193 PrintAndLog("Attempting to Read Ultralight... ");
194 UsbCommand c
= {CMD_MIFAREU_READCARD
, {BlockNo
, Pages
}};
198 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
199 isOK
= resp
.arg
[0] & 0xff;
200 data
= resp
.d
.asBytes
;
201 PrintAndLog("isOk:%02x", isOK
);
205 memcpy( datatemp
, data
,3);
206 memcpy( datatemp
+3, data
+4, 4);
207 PrintAndLog(" UID :%s ", sprint_hex(datatemp
, 7));
209 // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
210 int crc0
= 0x88 ^ data
[0] ^ data
[1] ^data
[2];
211 if ( data
[3] == crc0
) {
212 PrintAndLog(" BCC0 :%02x - Ok", data
[3]);
215 PrintAndLog(" BCC0 :%02x - crc should be %02x", data
[3], crc0
);
218 int crc1
= data
[4] ^ data
[5] ^ data
[6] ^data
[7];
219 if ( data
[8] == crc1
){
220 PrintAndLog(" BCC1 :%02x - Ok", data
[8]);
223 PrintAndLog(" BCC1 :%02x - crc should be %02x", data
[8], crc1
);
226 PrintAndLog(" Internal :%s ", sprint_hex(data
+ 9, 1));
228 memcpy(datatemp
, data
+10, 2);
229 PrintAndLog(" Lock :%s - %s", sprint_hex(datatemp
, 2),printBits( 2, &datatemp
) );
231 PrintAndLog(" OneTimePad :%s ", sprint_hex(data
+ 3*4, 4));
234 for (i
= 0; i
< Pages
; i
++) {
238 lockbytes_t
=data
+(i
*4);
239 lockbytes
[0]=lockbytes_t
[2];
240 lockbytes
[1]=lockbytes_t
[3];
241 for(int j
=0; j
<16; j
++){
242 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
244 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
245 memcpy(datatemp
,data
+ i
* 4,4);
246 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
249 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[4]);
250 memcpy(datatemp
,data
+ i
* 4,4);
251 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
254 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[3]);
255 memcpy(datatemp
,data
+ i
* 4,4);
256 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
259 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[2]);
260 memcpy(datatemp
,data
+ i
* 4,4);
261 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
264 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[1]);
265 memcpy(datatemp
,data
+ i
* 4,4);
266 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
269 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[0]);
270 memcpy(datatemp
,data
+ i
* 4,4);
271 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
274 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[15]);
275 memcpy(datatemp
,data
+ i
* 4,4);
276 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
279 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[14]);
280 memcpy(datatemp
,data
+ i
* 4,4);
281 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
284 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[13]);
285 memcpy(datatemp
,data
+ i
* 4,4);
286 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
289 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[12]);
290 memcpy(datatemp
,data
+ i
* 4,4);
291 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
294 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[11]);
295 memcpy(datatemp
,data
+ i
* 4,4);
296 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
299 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[10]);
300 memcpy(datatemp
,data
+ i
* 4,4);
301 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
304 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[9]);
305 memcpy(datatemp
,data
+ i
* 4,4);
306 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
309 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
310 memcpy(datatemp
,data
+ i
* 4,4);
311 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
314 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
315 memcpy(datatemp
,data
+ i
* 4,4);
316 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
322 PrintAndLog("Command1 execute timeout");
324 if (dump
) fclose(fout
);
328 int CmdHF14AMfUDump(const char *Cmd
){
332 uint8_t *lockbytes_t
= NULL
;
333 uint8_t lockbytes
[2] = {0x00};
334 bool bit
[16] = {0x00};
335 uint8_t datatemp
[5] = {0x00};
338 uint8_t * data
= NULL
;
341 if ((fout
= fopen("dump_ultralight_data.bin","wb")) == NULL
) {
342 PrintAndLog("Could not create file name dumpdata.bin");
345 PrintAndLog("Dumping Ultralight Card Data...");
347 PrintAndLog("Attempting to Read Ultralight... ");
348 UsbCommand c
= {CMD_MIFAREU_READCARD
, {BlockNo
,Pages
}};
352 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
353 isOK
= resp
.arg
[0] & 0xff;
354 data
= resp
.d
.asBytes
;
355 PrintAndLog("isOk:%02x", isOK
);
357 for (i
= 0; i
< Pages
; i
++) {
361 lockbytes_t
=data
+(i
*4);
362 lockbytes
[0]=lockbytes_t
[2];
363 lockbytes
[1]=lockbytes_t
[3];
364 for(int j
=0; j
<16; j
++){
365 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
367 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
368 memcpy(datatemp
,data
+ i
* 4,4);
369 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
372 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[4]);
373 memcpy(datatemp
,data
+ i
* 4,4);
374 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
377 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[3]);
378 memcpy(datatemp
,data
+ i
* 4,4);
379 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
382 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[2]);
383 memcpy(datatemp
,data
+ i
* 4,4);
384 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
387 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[1]);
388 memcpy(datatemp
,data
+ i
* 4,4);
389 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
392 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[0]);
393 memcpy(datatemp
,data
+ i
* 4,4);
394 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
397 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[15]);
398 memcpy(datatemp
,data
+ i
* 4,4);
399 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
402 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[14]);
403 memcpy(datatemp
,data
+ i
* 4,4);
404 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
407 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[13]);
408 memcpy(datatemp
,data
+ i
* 4,4);
409 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
412 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[12]);
413 memcpy(datatemp
,data
+ i
* 4,4);
414 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
417 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[11]);
418 memcpy(datatemp
,data
+ i
* 4,4);
419 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
422 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[10]);
423 memcpy(datatemp
,data
+ i
* 4,4);
424 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
427 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[9]);
428 memcpy(datatemp
,data
+ i
* 4,4);
429 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
432 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
433 memcpy(datatemp
,data
+ i
* 4,4);
434 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
437 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
438 memcpy(datatemp
,data
+ i
* 4,4);
439 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
444 PrintAndLog("Command1 execute timeout");
446 if (dump
) fclose(fout
);
450 // Needed to Authenticate to Ultralight C tags
451 void rol (uint8_t *data
, const size_t len
){
452 uint8_t first
= data
[0];
453 for (size_t i
= 0; i
< len
-1; i
++) {
459 //-------------------------------------------------------------------------------
460 // Ultralight C Methods
461 //-------------------------------------------------------------------------------
464 // Ultralight C Authentication Demo {currently uses hard-coded key}
466 int CmdHF14AMfucAuth(const char *Cmd
){
468 uint8_t blockNo
= 0, keyNo
=0;
469 uint8_t e_RndB
[8] = {0x00};
471 unsigned char RndARndB
[16] = {0x00};
472 uint8_t key
[16] = {0x00};
473 DES_cblock RndA
, RndB
;
475 DES_key_schedule ks1
,ks2
;
476 DES_cblock key1
,key2
;
482 PrintAndLog("Usage: hf mfu auth k <key number>");
483 PrintAndLog(" sample: hf mfu auth k 0");
487 //Change key to user defined one
488 if (strchr(Cmd
,'k') != 0){
490 keyNo
= param_get8(Cmd
, 1);
493 memcpy(key
,key1_blnk_data
,16);
496 memcpy(key
,key2_defa_data
,16);
499 memcpy(key
,key4_nfc_data
,16);
502 memcpy(key
,key5_ones_data
,16);
505 memcpy(key
,key3_3des_data
,16);
509 memcpy(key
,key3_3des_data
,16);
512 memcpy(key2
,key
+8,8);
513 DES_set_key((DES_cblock
*)key1
,&ks1
);
514 DES_set_key((DES_cblock
*)key2
,&ks2
);
517 UsbCommand c
= {CMD_MIFAREUC_AUTH1
, {blockNo
}};
520 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
521 uint8_t isOK
= resp
.arg
[0] & 0xff;
523 uint8_t * data
= resp
.d
.asBytes
;
526 PrintAndLog("enc(RndB):%s", sprint_hex(data
+1, 8));
527 memcpy(e_RndB
,data
+1,8);
530 PrintAndLog("Command execute timeout");
534 DES_random_key(&RndA
);
535 DES_ede2_cbc_encrypt(e_RndB
,RndB
,sizeof(e_RndB
),&ks1
,&ks2
,&iv
,0);
536 PrintAndLog(" RndB:%s",sprint_hex(RndB
, 8));
537 PrintAndLog(" RndA:%s",sprint_hex(RndA
, 8));
539 memcpy(RndARndB
,RndA
,8);
540 memcpy(RndARndB
+8,RndB
,8);
541 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB
, 16));
542 DES_ede2_cbc_encrypt(RndARndB
,RndARndB
,sizeof(RndARndB
),&ks1
,&ks2
,&e_RndB
,1);
543 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB
, 16));
546 UsbCommand d
= {CMD_MIFAREUC_AUTH2
, {cuid
}};
547 memcpy(d
.d
.asBytes
,RndARndB
, 16);
551 if (WaitForResponseTimeout(CMD_ACK
,&respb
,1500)) {
552 uint8_t isOK
= respb
.arg
[0] & 0xff;
553 uint8_t * data2
= respb
.d
.asBytes
;
556 PrintAndLog("enc(RndA'):%s", sprint_hex(data2
+1, 8));
560 PrintAndLog("Command execute timeout");
566 // Ultralight C Read Single Block
568 int CmdHF14AMfUCRdBl(const char *Cmd
)
573 PrintAndLog("Usage: hf mfu ucrdbl <block number>");
574 PrintAndLog(" sample: hf mfu ucrdbl 0");
578 blockNo
= param_get8(Cmd
, 0);
579 if (blockNo
>MAX_ULTRAC_BLOCKS
){
580 PrintAndLog("Error: Maximum number of readable blocks is 44 for Ultralight Cards!");
583 PrintAndLog("--block no:%02x", (int)blockNo
);
586 UsbCommand e
= {CMD_MIFAREU_READBL
, {blockNo
}};
589 if (WaitForResponseTimeout(CMD_ACK
,&resp_c
,1500)) {
590 uint8_t isOK
= resp_c
.arg
[0] & 0xff;
591 uint8_t * data
= resp_c
.d
.asBytes
;
593 PrintAndLog("isOk:%02x data:%s", isOK
, sprint_hex(data
, 4));
595 PrintAndLog("isOk:%02x", isOK
);
597 PrintAndLog("Command execute timeout");
603 // Ultralight C Read (or Dump) Card Contents
605 int CmdHF14AMfUCRdCard(const char *Cmd
){
609 uint8_t *lockbytes_t
=NULL
;
610 uint8_t lockbytes
[2]={0x00};
611 uint8_t *lockbytes_t2
=NULL
;
612 uint8_t lockbytes2
[2]={0x00};
614 bool bit2
[16]={0x00};
616 uint8_t datatemp
[5]={0x00};
618 uint8_t * data
= NULL
;
621 if (strchr(Cmd
,'x') != 0){
623 if ((fout
= fopen("dump_ultralightc_data.bin","wb")) == NULL
) {
624 PrintAndLog("Could not create file name dumpdata.bin");
627 PrintAndLog("Dumping Ultralight C Card Data...");
629 PrintAndLog("Attempting to Read Ultralight C... ");
630 UsbCommand c
= {CMD_MIFAREUC_READCARD
, {BlockNo
, Pages
}};
634 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
635 isOK
= resp
.arg
[0] & 0xff;
636 data
= resp
.d
.asBytes
;
637 //Pages=sizeof(data)/sizeof(data[0]);
638 PrintAndLog("isOk:%02x", isOK
);
640 for (i
= 0; i
< Pages
; i
++) {
644 lockbytes_t
=data
+(i
*4);
645 lockbytes
[0]=lockbytes_t
[2];
646 lockbytes
[1]=lockbytes_t
[3];
647 for(int j
=0; j
<16; j
++){
648 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
650 //might as well read bottom lockbytes too
651 lockbytes_t2
=data
+(40*4);
652 lockbytes2
[0]=lockbytes_t2
[2];
653 lockbytes2
[1]=lockbytes_t2
[3];
654 for(int j
=0; j
<16; j
++){
655 bit2
[j
]=lockbytes2
[j
/8] & ( 1 <<(7-j
%8));
657 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
658 memcpy(datatemp
,data
+ i
* 4,4);
659 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
662 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[4]);
663 memcpy(datatemp
,data
+ i
* 4,4);
664 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
667 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[3]);
668 memcpy(datatemp
,data
+ i
* 4,4);
669 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
672 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[2]);
673 memcpy(datatemp
,data
+ i
* 4,4);
674 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
677 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[1]);
678 memcpy(datatemp
,data
+ i
* 4,4);
679 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
682 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[0]);
683 memcpy(datatemp
,data
+ i
* 4,4);
684 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
687 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[15]);
688 memcpy(datatemp
,data
+ i
* 4,4);
689 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
692 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[14]);
693 memcpy(datatemp
,data
+ i
* 4,4);
694 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
697 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[13]);
698 memcpy(datatemp
,data
+ i
* 4,4);
699 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
702 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[12]);
703 memcpy(datatemp
,data
+ i
* 4,4);
704 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
707 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[11]);
708 memcpy(datatemp
,data
+ i
* 4,4);
709 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
712 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[10]);
713 memcpy(datatemp
,data
+ i
* 4,4);
714 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
717 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[9]);
718 memcpy(datatemp
,data
+ i
* 4,4);
719 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
722 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
723 memcpy(datatemp
,data
+ i
* 4,4);
724 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
730 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[6]);
731 memcpy(datatemp
,data
+ i
* 4,4);
732 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
738 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[5]);
739 memcpy(datatemp
,data
+ i
* 4,4);
740 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
746 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[4]);
747 memcpy(datatemp
,data
+ i
* 4,4);
748 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
754 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[2]);
755 memcpy(datatemp
,data
+ i
* 4,4);
756 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
762 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[1]);
763 memcpy(datatemp
,data
+ i
* 4,4);
764 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
770 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[0]);
771 memcpy(datatemp
,data
+ i
* 4,4);
772 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
775 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[12]);
776 memcpy(datatemp
,data
+ i
* 4,4);
777 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
780 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[11]);
781 memcpy(datatemp
,data
+ i
* 4,4);
782 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
786 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[10]);
787 memcpy(datatemp
,data
+ i
* 4,4);
788 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
792 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[9]);
793 memcpy(datatemp
,data
+ i
* 4,4);
794 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
797 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
798 memcpy(datatemp
,data
+ i
* 4,4);
799 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
805 PrintAndLog("Command1 execute timeout");
807 if (dump
) fclose(fout
);
812 // Ultralight C Dump Card Contents to file
814 int CmdHF14AMfUCDump(const char *Cmd
){
818 uint8_t *lockbytes_t
=NULL
;
819 uint8_t lockbytes
[2]={0x00};
820 uint8_t *lockbytes_t2
=NULL
;
821 uint8_t lockbytes2
[2]={0x00};
823 bool bit2
[16]={0x00};
825 uint8_t datatemp
[5]={0x00};
828 uint8_t * data
= NULL
;
831 if ((fout
= fopen("dump_ultralightc_data.bin","wb")) == NULL
) {
832 PrintAndLog("Could not create file name dumpdata.bin");
835 PrintAndLog("Dumping Ultralight C Card Data...");
836 PrintAndLog("Attempting to Read Ultralight C... ");
837 UsbCommand c
= {CMD_MIFAREU_READCARD
, {BlockNo
,Pages
}};
841 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
842 isOK
= resp
.arg
[0] & 0xff;
843 data
= resp
.d
.asBytes
;
844 PrintAndLog("isOk:%02x", isOK
);
846 for (i
= 0; i
< Pages
; i
++) {
850 lockbytes_t
=data
+(i
*4);
851 lockbytes
[0]=lockbytes_t
[2];
852 lockbytes
[1]=lockbytes_t
[3];
853 for(int j
=0; j
<16; j
++){
854 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
857 //might as well read bottom lockbytes too
858 lockbytes_t2
=data
+(40*4);
859 lockbytes2
[0]=lockbytes_t2
[2];
860 lockbytes2
[1]=lockbytes_t2
[3];
861 for(int j
=0; j
<16; j
++){
862 bit2
[j
]=lockbytes2
[j
/8] & ( 1 <<(7-j
%8));
865 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
866 memcpy(datatemp
,data
+ i
* 4,4);
867 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
870 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[4]);
871 memcpy(datatemp
,data
+ i
* 4,4);
872 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
875 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[3]);
876 memcpy(datatemp
,data
+ i
* 4,4);
877 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
880 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[2]);
881 memcpy(datatemp
,data
+ i
* 4,4);
882 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
885 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[1]);
886 memcpy(datatemp
,data
+ i
* 4,4);
887 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
890 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[0]);
891 memcpy(datatemp
,data
+ i
* 4,4);
892 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
895 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[15]);
896 memcpy(datatemp
,data
+ i
* 4,4);
897 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
900 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[14]);
901 memcpy(datatemp
,data
+ i
* 4,4);
902 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
905 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[13]);
906 memcpy(datatemp
,data
+ i
* 4,4);
907 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
910 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[12]);
911 memcpy(datatemp
,data
+ i
* 4,4);
912 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
915 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[11]);
916 memcpy(datatemp
,data
+ i
* 4,4);
917 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
920 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[10]);
921 memcpy(datatemp
,data
+ i
* 4,4);
922 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
925 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[9]);
926 memcpy(datatemp
,data
+ i
* 4,4);
927 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
930 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
931 memcpy(datatemp
,data
+ i
* 4,4);
932 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
938 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[6]);
939 memcpy(datatemp
,data
+ i
* 4,4);
940 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
946 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[5]);
947 memcpy(datatemp
,data
+ i
* 4,4);
948 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
954 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[4]);
955 memcpy(datatemp
,data
+ i
* 4,4);
956 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
962 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[2]);
963 memcpy(datatemp
,data
+ i
* 4,4);
964 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
970 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[1]);
971 memcpy(datatemp
,data
+ i
* 4,4);
972 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
978 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[0]);
979 memcpy(datatemp
,data
+ i
* 4,4);
980 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
983 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[12]);
984 memcpy(datatemp
,data
+ i
* 4,4);
985 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
988 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[11]);
989 memcpy(datatemp
,data
+ i
* 4,4);
990 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
994 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[10]);
995 memcpy(datatemp
,data
+ i
* 4,4);
996 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
1000 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[9]);
1001 memcpy(datatemp
,data
+ i
* 4,4);
1002 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
1005 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
1006 memcpy(datatemp
,data
+ i
* 4,4);
1007 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
1013 PrintAndLog("Command1 execute timeout");
1015 if (dump
) fclose(fout
);
1020 // Mifare Ultralight C Write Single Block
1022 int CmdHF14AMfUCWrBl(const char *Cmd
){
1024 uint8_t blockNo
= 0;
1025 bool chinese_card
= 0;
1026 uint8_t bldata
[16] = {0x00};
1029 if (strlen(Cmd
)<3) {
1030 PrintAndLog("Usage: hf mfu ucwrbl <block number> <block data (8 hex symbols)> [w]");
1031 PrintAndLog(" sample: hf mfu uwrbl 0 01020304");
1034 blockNo
= param_get8(Cmd
, 0);
1035 if (blockNo
>(MAX_ULTRAC_BLOCKS
+4)){
1036 PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight Cards!");
1039 if (param_gethex(Cmd
, 1, bldata
, 8)) {
1040 PrintAndLog("Block data must include 8 HEX symbols");
1043 if (strchr(Cmd
,'w') != 0) {
1049 PrintAndLog("Access Denied");
1051 PrintAndLog("--specialblock no:%02x", blockNo
);
1052 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1053 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1054 memcpy(d
.d
.asBytes
,bldata
, 4);
1056 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1057 uint8_t isOK
= resp
.arg
[0] & 0xff;
1058 PrintAndLog("isOk:%02x", isOK
);
1060 PrintAndLog("Command execute timeout");
1066 PrintAndLog("Access Denied");
1068 PrintAndLog("--specialblock no:%02x", blockNo
);
1069 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1070 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1071 memcpy(d
.d
.asBytes
,bldata
, 4);
1073 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1074 uint8_t isOK
= resp
.arg
[0] & 0xff;
1075 PrintAndLog("isOk:%02x", isOK
);
1077 PrintAndLog("Command execute timeout");
1083 PrintAndLog("Access Denied");
1085 PrintAndLog("--specialblock no:%02x", blockNo
);
1086 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1087 UsbCommand c
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1088 memcpy(c
.d
.asBytes
, bldata
, 4);
1090 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1091 uint8_t isOK
= resp
.arg
[0] & 0xff;
1092 PrintAndLog("isOk:%02x", isOK
);
1094 PrintAndLog("Command execute timeout");
1099 PrintAndLog("--specialblock no:%02x", blockNo
);
1100 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1101 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1102 memcpy(d
.d
.asBytes
,bldata
, 4);
1104 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1105 uint8_t isOK
= resp
.arg
[0] & 0xff;
1106 PrintAndLog("isOk:%02x", isOK
);
1108 PrintAndLog("Command execute timeout");
1112 PrintAndLog("--block no:%02x", blockNo
);
1113 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1114 UsbCommand e
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1115 memcpy(e
.d
.asBytes
,bldata
, 4);
1117 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1118 uint8_t isOK
= resp
.arg
[0] & 0xff;
1119 PrintAndLog("isOk:%02x", isOK
);
1121 PrintAndLog("Command execute timeout");
1128 //------------------------------------
1130 //------------------------------------
1131 static command_t CommandTable
[] =
1133 {"help", CmdHelp
, 1,"This help"},
1134 {"dbg", CmdHF14AMfDbg
, 0,"Set default debug mode"},
1135 {"urdbl", CmdHF14AMfURdBl
, 0,"Read MIFARE Ultralight block"},
1136 {"urdcard", CmdHF14AMfURdCard
, 0,"Read MIFARE Ultralight Card"},
1137 {"udump", CmdHF14AMfUDump
, 0,"Dump MIFARE Ultralight tag to binary file"},
1138 {"uwrbl", CmdHF14AMfUWrBl
, 0,"Write MIFARE Ultralight block"},
1139 {"ucrdbl", CmdHF14AMfUCRdBl
, 0,"Read MIFARE Ultralight C block"},
1140 {"ucrdcard",CmdHF14AMfUCRdCard
, 0,"Read MIFARE Ultralight C Card"},
1141 {"ucdump", CmdHF14AMfUCDump
, 0,"Dump MIFARE Ultralight C tag to binary file"},
1142 {"ucwrbl", CmdHF14AMfUCWrBl
, 0,"Write MIFARE Ultralight C block"},
1143 {"auth", CmdHF14AMfucAuth
, 0,"Ultralight C Authentication"},
1144 {NULL
, NULL
, 0, NULL
}
1147 int CmdHFMFUltra(const char *Cmd
){
1149 WaitForResponseTimeout(CMD_ACK
,NULL
,100);
1150 CmdsParse(CommandTable
, Cmd
);
1154 int CmdHelp(const char *Cmd
){
1155 CmdsHelp(CommandTable
);