]>
cvs.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
);
164 PrintAndLog("Command execute timeout");
170 // Mifare Ultralight Read (Dump) Card Contents
172 int CmdHF14AMfURdCard(const char *Cmd
){
176 uint8_t *lockbytes_t
=NULL
;
177 uint8_t lockbytes
[2]={0x00};
180 uint8_t datatemp
[7]= {0x00};
183 uint8_t * data
= NULL
;
186 if (strchr(Cmd
,'x') != 0){
188 if ((fout
= fopen("dump_ultralight_data.bin","wb")) == NULL
) {
189 PrintAndLog("Could not create file name dumpdata.bin");
192 PrintAndLog("Dumping Ultralight Card Data...");
194 PrintAndLog("Attempting to Read Ultralight... ");
195 UsbCommand c
= {CMD_MIFAREU_READCARD
, {BlockNo
, pages
}};
199 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
200 isOK
= resp
.arg
[0] & 0xff;
201 data
= resp
.d
.asBytes
;
202 PrintAndLog("isOk:%02x", isOK
);
206 memcpy( datatemp
, data
,3);
207 memcpy( datatemp
+3, data
+4, 4);
208 PrintAndLog(" UID :%s ", sprint_hex(datatemp
, 7));
210 // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
211 int crc0
= 0x88 ^ data
[0] ^ data
[1] ^data
[2];
212 if ( data
[3] == crc0
) {
213 PrintAndLog(" BCC0 :%02x - Ok", data
[3]);
216 PrintAndLog(" BCC0 :%02x - crc should be %02x", data
[3], crc0
);
219 int crc1
= data
[4] ^ data
[5] ^ data
[6] ^data
[7];
220 if ( data
[8] == crc1
){
221 PrintAndLog(" BCC1 :%02x - Ok", data
[8]);
224 PrintAndLog(" BCC1 :%02x - crc should be %02x", data
[8], crc1
);
227 PrintAndLog(" Internal :%s ", sprint_hex(data
+ 9, 1));
229 memcpy(datatemp
, data
+10, 2);
230 PrintAndLog(" Lock :%s - %s", sprint_hex(datatemp
, 2),printBits( 2, &datatemp
) );
232 PrintAndLog(" OneTimePad :%s ", sprint_hex(data
+ 3*4, 4));
235 for (i
= 0; i
< pages
; i
++) {
239 lockbytes_t
=data
+(i
*4);
240 lockbytes
[0]=lockbytes_t
[2];
241 lockbytes
[1]=lockbytes_t
[3];
242 for(int j
=0; j
<16; j
++){
243 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
245 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
246 memcpy(datatemp
,data
+ i
* 4,4);
247 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
250 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[4]);
251 memcpy(datatemp
,data
+ i
* 4,4);
252 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
255 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[3]);
256 memcpy(datatemp
,data
+ i
* 4,4);
257 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
260 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[2]);
261 memcpy(datatemp
,data
+ i
* 4,4);
262 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
265 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[1]);
266 memcpy(datatemp
,data
+ i
* 4,4);
267 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
270 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[0]);
271 memcpy(datatemp
,data
+ i
* 4,4);
272 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
275 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[15]);
276 memcpy(datatemp
,data
+ i
* 4,4);
277 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
280 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[14]);
281 memcpy(datatemp
,data
+ i
* 4,4);
282 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
285 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[13]);
286 memcpy(datatemp
,data
+ i
* 4,4);
287 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
290 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[12]);
291 memcpy(datatemp
,data
+ i
* 4,4);
292 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
295 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[11]);
296 memcpy(datatemp
,data
+ i
* 4,4);
297 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
300 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[10]);
301 memcpy(datatemp
,data
+ i
* 4,4);
302 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
305 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[9]);
306 memcpy(datatemp
,data
+ i
* 4,4);
307 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
310 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
311 memcpy(datatemp
,data
+ i
* 4,4);
312 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
315 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
316 memcpy(datatemp
,data
+ i
* 4,4);
317 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
323 PrintAndLog("Command1 execute timeout");
325 if (dump
) fclose(fout
);
329 int CmdHF14AMfUDump(const char *Cmd
){
333 uint8_t *lockbytes_t
= NULL
;
334 uint8_t lockbytes
[2] = {0x00};
335 bool bit
[16] = {0x00};
336 uint8_t datatemp
[5] = {0x00};
339 uint8_t * data
= NULL
;
342 if ((fout
= fopen("dump_ultralight_data.bin","wb")) == NULL
) {
343 PrintAndLog("Could not create file name dumpdata.bin");
346 PrintAndLog("Dumping Ultralight Card Data...");
348 PrintAndLog("Attempting to Read Ultralight... ");
349 UsbCommand c
= {CMD_MIFAREU_READCARD
, {BlockNo
,Pages
}};
353 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
354 isOK
= resp
.arg
[0] & 0xff;
355 data
= resp
.d
.asBytes
;
356 PrintAndLog("isOk:%02x", isOK
);
358 for (i
= 0; i
< Pages
; i
++) {
362 lockbytes_t
=data
+(i
*4);
363 lockbytes
[0]=lockbytes_t
[2];
364 lockbytes
[1]=lockbytes_t
[3];
365 for(int j
=0; j
<16; j
++){
366 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
368 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
369 memcpy(datatemp
,data
+ i
* 4,4);
370 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
373 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[4]);
374 memcpy(datatemp
,data
+ i
* 4,4);
375 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
378 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[3]);
379 memcpy(datatemp
,data
+ i
* 4,4);
380 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
383 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[2]);
384 memcpy(datatemp
,data
+ i
* 4,4);
385 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
388 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[1]);
389 memcpy(datatemp
,data
+ i
* 4,4);
390 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
393 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[0]);
394 memcpy(datatemp
,data
+ i
* 4,4);
395 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
398 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[15]);
399 memcpy(datatemp
,data
+ i
* 4,4);
400 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
403 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[14]);
404 memcpy(datatemp
,data
+ i
* 4,4);
405 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
408 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[13]);
409 memcpy(datatemp
,data
+ i
* 4,4);
410 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
413 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[12]);
414 memcpy(datatemp
,data
+ i
* 4,4);
415 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
418 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[11]);
419 memcpy(datatemp
,data
+ i
* 4,4);
420 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
423 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[10]);
424 memcpy(datatemp
,data
+ i
* 4,4);
425 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
428 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[9]);
429 memcpy(datatemp
,data
+ i
* 4,4);
430 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
433 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
434 memcpy(datatemp
,data
+ i
* 4,4);
435 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
438 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
439 memcpy(datatemp
,data
+ i
* 4,4);
440 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
445 PrintAndLog("Command1 execute timeout");
447 if (dump
) fclose(fout
);
451 // Needed to Authenticate to Ultralight C tags
452 void rol (uint8_t *data
, const size_t len
){
453 uint8_t first
= data
[0];
454 for (size_t i
= 0; i
< len
-1; i
++) {
460 //-------------------------------------------------------------------------------
461 // Ultralight C Methods
462 //-------------------------------------------------------------------------------
465 // Ultralight C Authentication Demo {currently uses hard-coded key}
467 int CmdHF14AMfucAuth(const char *Cmd
){
469 uint8_t blockNo
= 0, keyNo
=0;
470 uint8_t e_RndB
[8] = {0x00};
472 unsigned char RndARndB
[16] = {0x00};
473 uint8_t key
[16] = {0x00};
474 DES_cblock RndA
, RndB
;
476 DES_key_schedule ks1
,ks2
;
477 DES_cblock key1
,key2
;
483 PrintAndLog("Usage: hf mfu auth k <key number>");
484 PrintAndLog(" sample: hf mfu auth k 0");
488 //Change key to user defined one
489 if (strchr(Cmd
,'k') != 0){
491 keyNo
= param_get8(Cmd
, 1);
494 memcpy(key
,key1_blnk_data
,16);
497 memcpy(key
,key2_defa_data
,16);
500 memcpy(key
,key4_nfc_data
,16);
503 memcpy(key
,key5_ones_data
,16);
506 memcpy(key
,key3_3des_data
,16);
510 memcpy(key
,key3_3des_data
,16);
513 memcpy(key2
,key
+8,8);
514 DES_set_key((DES_cblock
*)key1
,&ks1
);
515 DES_set_key((DES_cblock
*)key2
,&ks2
);
518 UsbCommand c
= {CMD_MIFAREUC_AUTH1
, {blockNo
}};
521 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
522 uint8_t isOK
= resp
.arg
[0] & 0xff;
524 uint8_t * data
= resp
.d
.asBytes
;
527 PrintAndLog("enc(RndB):%s", sprint_hex(data
+1, 8));
528 memcpy(e_RndB
,data
+1,8);
531 PrintAndLog("Command execute timeout");
535 DES_random_key(&RndA
);
536 DES_ede2_cbc_encrypt(e_RndB
,RndB
,sizeof(e_RndB
),&ks1
,&ks2
,&iv
,0);
537 PrintAndLog(" RndB:%s",sprint_hex(RndB
, 8));
538 PrintAndLog(" RndA:%s",sprint_hex(RndA
, 8));
540 memcpy(RndARndB
,RndA
,8);
541 memcpy(RndARndB
+8,RndB
,8);
542 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB
, 16));
543 DES_ede2_cbc_encrypt(RndARndB
,RndARndB
,sizeof(RndARndB
),&ks1
,&ks2
,&e_RndB
,1);
544 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB
, 16));
547 UsbCommand d
= {CMD_MIFAREUC_AUTH2
, {cuid
}};
548 memcpy(d
.d
.asBytes
,RndARndB
, 16);
552 if (WaitForResponseTimeout(CMD_ACK
,&respb
,1500)) {
553 uint8_t isOK
= respb
.arg
[0] & 0xff;
554 uint8_t * data2
= respb
.d
.asBytes
;
557 PrintAndLog("enc(RndA'):%s", sprint_hex(data2
+1, 8));
561 PrintAndLog("Command execute timeout");
567 // Ultralight C Read Single Block
569 int CmdHF14AMfUCRdBl(const char *Cmd
)
574 PrintAndLog("Usage: hf mfu ucrdbl <block number>");
575 PrintAndLog(" sample: hf mfu ucrdbl 0");
579 blockNo
= param_get8(Cmd
, 0);
580 if (blockNo
>MAX_ULTRAC_BLOCKS
){
581 PrintAndLog("Error: Maximum number of readable blocks is 44 for Ultralight Cards!");
584 PrintAndLog("--block no:%02x", (int)blockNo
);
587 UsbCommand e
= {CMD_MIFAREU_READBL
, {blockNo
}};
590 if (WaitForResponseTimeout(CMD_ACK
,&resp_c
,1500)) {
591 uint8_t isOK
= resp_c
.arg
[0] & 0xff;
592 uint8_t * data
= resp_c
.d
.asBytes
;
594 PrintAndLog("isOk:%02x data:%s", isOK
, sprint_hex(data
, 4));
596 PrintAndLog("isOk:%02x", isOK
);
598 PrintAndLog("Command execute timeout");
604 // Ultralight C Read (or Dump) Card Contents
606 int CmdHF14AMfUCRdCard(const char *Cmd
){
610 uint8_t *lockbytes_t
=NULL
;
611 uint8_t lockbytes
[2]={0x00};
612 uint8_t *lockbytes_t2
=NULL
;
613 uint8_t lockbytes2
[2]={0x00};
615 bool bit2
[16]={0x00};
617 uint8_t datatemp
[5]={0x00};
619 uint8_t * data
= NULL
;
622 if (strchr(Cmd
,'x') != 0){
624 if ((fout
= fopen("dump_ultralightc_data.bin","wb")) == NULL
) {
625 PrintAndLog("Could not create file name dumpdata.bin");
628 PrintAndLog("Dumping Ultralight C Card Data...");
630 PrintAndLog("Attempting to Read Ultralight C... ");
631 UsbCommand c
= {CMD_MIFAREUC_READCARD
, {BlockNo
, Pages
}};
635 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
636 isOK
= resp
.arg
[0] & 0xff;
637 data
= resp
.d
.asBytes
;
639 PrintAndLog("isOk:%02x", isOK
);
641 for (i
= 0; i
< Pages
; i
++) {
645 lockbytes_t
=data
+(i
*4);
646 lockbytes
[0]=lockbytes_t
[2];
647 lockbytes
[1]=lockbytes_t
[3];
648 for(int j
=0; j
<16; j
++){
649 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
651 //might as well read bottom lockbytes too
652 lockbytes_t2
=data
+(40*4);
653 lockbytes2
[0]=lockbytes_t2
[2];
654 lockbytes2
[1]=lockbytes_t2
[3];
655 for(int j
=0; j
<16; j
++){
656 bit2
[j
]=lockbytes2
[j
/8] & ( 1 <<(7-j
%8));
658 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
659 memcpy(datatemp
,data
+ i
* 4,4);
660 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
663 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[4]);
664 memcpy(datatemp
,data
+ i
* 4,4);
665 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
668 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[3]);
669 memcpy(datatemp
,data
+ i
* 4,4);
670 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
673 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[2]);
674 memcpy(datatemp
,data
+ i
* 4,4);
675 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
678 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[1]);
679 memcpy(datatemp
,data
+ i
* 4,4);
680 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
683 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[0]);
684 memcpy(datatemp
,data
+ i
* 4,4);
685 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
688 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[15]);
689 memcpy(datatemp
,data
+ i
* 4,4);
690 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
693 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[14]);
694 memcpy(datatemp
,data
+ i
* 4,4);
695 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
698 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[13]);
699 memcpy(datatemp
,data
+ i
* 4,4);
700 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
703 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[12]);
704 memcpy(datatemp
,data
+ i
* 4,4);
705 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
708 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[11]);
709 memcpy(datatemp
,data
+ i
* 4,4);
710 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
713 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[10]);
714 memcpy(datatemp
,data
+ i
* 4,4);
715 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
718 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[9]);
719 memcpy(datatemp
,data
+ i
* 4,4);
720 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
723 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
724 memcpy(datatemp
,data
+ i
* 4,4);
725 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
731 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[6]);
732 memcpy(datatemp
,data
+ i
* 4,4);
733 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
739 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[5]);
740 memcpy(datatemp
,data
+ i
* 4,4);
741 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
747 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[4]);
748 memcpy(datatemp
,data
+ i
* 4,4);
749 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
755 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[2]);
756 memcpy(datatemp
,data
+ i
* 4,4);
757 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
763 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[1]);
764 memcpy(datatemp
,data
+ i
* 4,4);
765 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
771 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[0]);
772 memcpy(datatemp
,data
+ i
* 4,4);
773 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
776 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[12]);
777 memcpy(datatemp
,data
+ i
* 4,4);
778 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
781 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[11]);
782 memcpy(datatemp
,data
+ i
* 4,4);
783 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
787 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[10]);
788 memcpy(datatemp
,data
+ i
* 4,4);
789 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
793 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[9]);
794 memcpy(datatemp
,data
+ i
* 4,4);
795 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
798 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
799 memcpy(datatemp
,data
+ i
* 4,4);
800 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
806 PrintAndLog("Command1 execute timeout");
808 if (dump
) fclose(fout
);
813 // Ultralight C Dump Card Contents to file
815 int CmdHF14AMfUCDump(const char *Cmd
){
819 uint8_t *lockbytes_t
=NULL
;
820 uint8_t lockbytes
[2]={0x00};
821 uint8_t *lockbytes_t2
=NULL
;
822 uint8_t lockbytes2
[2]={0x00};
824 bool bit2
[16]={0x00};
826 uint8_t datatemp
[5]={0x00};
829 uint8_t * data
= NULL
;
832 if ((fout
= fopen("dump_ultralightc_data.bin","wb")) == NULL
) {
833 PrintAndLog("Could not create file name dumpdata.bin");
836 PrintAndLog("Dumping Ultralight C Card Data...");
837 PrintAndLog("Attempting to Read Ultralight C... ");
838 UsbCommand c
= {CMD_MIFAREU_READCARD
, {BlockNo
,Pages
}};
842 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
843 isOK
= resp
.arg
[0] & 0xff;
844 data
= resp
.d
.asBytes
;
845 PrintAndLog("isOk:%02x", isOK
);
847 for (i
= 0; i
< Pages
; i
++) {
851 lockbytes_t
=data
+(i
*4);
852 lockbytes
[0]=lockbytes_t
[2];
853 lockbytes
[1]=lockbytes_t
[3];
854 for(int j
=0; j
<16; j
++){
855 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
858 //might as well read bottom lockbytes too
859 lockbytes_t2
=data
+(40*4);
860 lockbytes2
[0]=lockbytes_t2
[2];
861 lockbytes2
[1]=lockbytes_t2
[3];
862 for(int j
=0; j
<16; j
++){
863 bit2
[j
]=lockbytes2
[j
/8] & ( 1 <<(7-j
%8));
866 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
867 memcpy(datatemp
,data
+ i
* 4,4);
868 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
871 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[4]);
872 memcpy(datatemp
,data
+ i
* 4,4);
873 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
876 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[3]);
877 memcpy(datatemp
,data
+ i
* 4,4);
878 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
881 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[2]);
882 memcpy(datatemp
,data
+ i
* 4,4);
883 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
886 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[1]);
887 memcpy(datatemp
,data
+ i
* 4,4);
888 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
891 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[0]);
892 memcpy(datatemp
,data
+ i
* 4,4);
893 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
896 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[15]);
897 memcpy(datatemp
,data
+ i
* 4,4);
898 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
901 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[14]);
902 memcpy(datatemp
,data
+ i
* 4,4);
903 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
906 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[13]);
907 memcpy(datatemp
,data
+ i
* 4,4);
908 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
911 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[12]);
912 memcpy(datatemp
,data
+ i
* 4,4);
913 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
916 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[11]);
917 memcpy(datatemp
,data
+ i
* 4,4);
918 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
921 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[10]);
922 memcpy(datatemp
,data
+ i
* 4,4);
923 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
926 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[9]);
927 memcpy(datatemp
,data
+ i
* 4,4);
928 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
931 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
932 memcpy(datatemp
,data
+ i
* 4,4);
933 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
939 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[6]);
940 memcpy(datatemp
,data
+ i
* 4,4);
941 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
947 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[5]);
948 memcpy(datatemp
,data
+ i
* 4,4);
949 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
955 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[4]);
956 memcpy(datatemp
,data
+ i
* 4,4);
957 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
963 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[2]);
964 memcpy(datatemp
,data
+ i
* 4,4);
965 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
971 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[1]);
972 memcpy(datatemp
,data
+ i
* 4,4);
973 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
979 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[0]);
980 memcpy(datatemp
,data
+ i
* 4,4);
981 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
984 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[12]);
985 memcpy(datatemp
,data
+ i
* 4,4);
986 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
989 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[11]);
990 memcpy(datatemp
,data
+ i
* 4,4);
991 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
995 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[10]);
996 memcpy(datatemp
,data
+ i
* 4,4);
997 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
1001 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[9]);
1002 memcpy(datatemp
,data
+ i
* 4,4);
1003 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
1006 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
1007 memcpy(datatemp
,data
+ i
* 4,4);
1008 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
1014 PrintAndLog("Command1 execute timeout");
1016 if (dump
) fclose(fout
);
1021 // Mifare Ultralight C Write Single Block
1023 int CmdHF14AMfUCWrBl(const char *Cmd
){
1025 uint8_t blockNo
= 0;
1026 bool chinese_card
= 0;
1027 uint8_t bldata
[16] = {0x00};
1030 if (strlen(Cmd
)<3) {
1031 PrintAndLog("Usage: hf mfu ucwrbl <block number> <block data (8 hex symbols)> [w]");
1032 PrintAndLog(" sample: hf mfu uwrbl 0 01020304");
1035 blockNo
= param_get8(Cmd
, 0);
1036 if (blockNo
>(MAX_ULTRAC_BLOCKS
+4)){
1037 PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight Cards!");
1040 if (param_gethex(Cmd
, 1, bldata
, 8)) {
1041 PrintAndLog("Block data must include 8 HEX symbols");
1044 if (strchr(Cmd
,'w') != 0) {
1050 PrintAndLog("Access Denied");
1052 PrintAndLog("--specialblock no:%02x", blockNo
);
1053 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1054 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1055 memcpy(d
.d
.asBytes
,bldata
, 4);
1057 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1058 uint8_t isOK
= resp
.arg
[0] & 0xff;
1059 PrintAndLog("isOk:%02x", isOK
);
1061 PrintAndLog("Command execute timeout");
1067 PrintAndLog("Access Denied");
1069 PrintAndLog("--specialblock no:%02x", blockNo
);
1070 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1071 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1072 memcpy(d
.d
.asBytes
,bldata
, 4);
1074 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1075 uint8_t isOK
= resp
.arg
[0] & 0xff;
1076 PrintAndLog("isOk:%02x", isOK
);
1078 PrintAndLog("Command execute timeout");
1084 PrintAndLog("Access Denied");
1086 PrintAndLog("--specialblock no:%02x", blockNo
);
1087 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1088 UsbCommand c
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1089 memcpy(c
.d
.asBytes
, bldata
, 4);
1091 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1092 uint8_t isOK
= resp
.arg
[0] & 0xff;
1093 PrintAndLog("isOk:%02x", isOK
);
1095 PrintAndLog("Command execute timeout");
1100 PrintAndLog("--specialblock no:%02x", blockNo
);
1101 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1102 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1103 memcpy(d
.d
.asBytes
,bldata
, 4);
1105 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1106 uint8_t isOK
= resp
.arg
[0] & 0xff;
1107 PrintAndLog("isOk:%02x", isOK
);
1109 PrintAndLog("Command execute timeout");
1113 PrintAndLog("--block no:%02x", blockNo
);
1114 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1115 UsbCommand e
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1116 memcpy(e
.d
.asBytes
,bldata
, 4);
1118 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1119 uint8_t isOK
= resp
.arg
[0] & 0xff;
1120 PrintAndLog("isOk:%02x", isOK
);
1122 PrintAndLog("Command execute timeout");
1129 //------------------------------------
1131 //------------------------------------
1132 static command_t CommandTable
[] =
1134 {"help", CmdHelp
, 1,"This help"},
1135 {"dbg", CmdHF14AMfDbg
, 0,"Set default debug mode"},
1136 {"urdbl", CmdHF14AMfURdBl
, 0,"Read MIFARE Ultralight block"},
1137 {"urdcard", CmdHF14AMfURdCard
, 0,"Read MIFARE Ultralight Card"},
1138 {"udump", CmdHF14AMfUDump
, 0,"Dump MIFARE Ultralight tag to binary file"},
1139 {"uwrbl", CmdHF14AMfUWrBl
, 0,"Write MIFARE Ultralight block"},
1140 {"ucrdbl", CmdHF14AMfUCRdBl
, 0,"Read MIFARE Ultralight C block"},
1141 {"ucrdcard",CmdHF14AMfUCRdCard
, 0,"Read MIFARE Ultralight C Card"},
1142 {"ucdump", CmdHF14AMfUCDump
, 0,"Dump MIFARE Ultralight C tag to binary file"},
1143 {"ucwrbl", CmdHF14AMfUCWrBl
, 0,"Write MIFARE Ultralight C block"},
1144 {"auth", CmdHF14AMfucAuth
, 0,"Ultralight C Authentication"},
1145 {NULL
, NULL
, 0, NULL
}
1148 int CmdHFMFUltra(const char *Cmd
){
1149 WaitForResponseTimeout(CMD_ACK
,NULL
,100);
1150 CmdsParse(CommandTable
, Cmd
);
1154 int CmdHelp(const char *Cmd
){
1155 CmdsHelp(CommandTable
);