]>
cvs.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhfmfu.c
72eb8895fc84402e1f3fb83fb362737a3d7c43c9
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
;
474 DES_cblock iv
[8] = {0x00};
475 DES_key_schedule ks1
,ks2
;
476 DES_cblock key1
,key2
;
479 PrintAndLog("Usage: hf mfu auth k <key number>");
480 PrintAndLog(" sample: hf mfu auth k 0");
484 //Change key to user defined one
485 if (strchr(Cmd
,'k') != 0){
487 keyNo
= param_get8(Cmd
, 1);
490 memcpy(key
,key1_blnk_data
,16);
493 memcpy(key
,key2_defa_data
,16);
496 memcpy(key
,key4_nfc_data
,16);
499 memcpy(key
,key5_ones_data
,16);
502 memcpy(key
,key3_3des_data
,16);
506 memcpy(key
,key3_3des_data
,16);
509 memcpy(key2
,key
+8,8);
510 DES_set_key((DES_cblock
*)key1
,&ks1
);
511 DES_set_key((DES_cblock
*)key2
,&ks2
);
514 UsbCommand c
= {CMD_MIFAREUC_AUTH1
, {blockNo
}};
517 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
518 uint8_t isOK
= resp
.arg
[0] & 0xff;
520 uint8_t * data
= resp
.d
.asBytes
;
523 PrintAndLog("enc(RndB):%s", sprint_hex(data
+1, 8));
524 memcpy(e_RndB
,data
+1,8);
527 PrintAndLog("Command execute timeout");
531 DES_random_key(&RndA
);
532 DES_ede2_cbc_encrypt(e_RndB
,RndB
,sizeof(e_RndB
),&ks1
,&ks2
,&iv
,0);
533 PrintAndLog(" RndB:%s",sprint_hex(RndB
, 8));
534 PrintAndLog(" RndA:%s",sprint_hex(RndA
, 8));
536 memcpy(RndARndB
,RndA
,8);
537 memcpy(RndARndB
+8,RndB
,8);
538 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB
, 16));
539 DES_ede2_cbc_encrypt(RndARndB
,RndARndB
,sizeof(RndARndB
),&ks1
,&ks2
,&e_RndB
,1);
540 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB
, 16));
543 UsbCommand d
= {CMD_MIFAREUC_AUTH2
, {cuid
}};
544 memcpy(d
.d
.asBytes
,RndARndB
, 16);
548 if (WaitForResponseTimeout(CMD_ACK
,&respb
,1500)) {
549 uint8_t isOK
= respb
.arg
[0] & 0xff;
550 uint8_t * data2
= respb
.d
.asBytes
;
553 PrintAndLog("enc(RndA'):%s", sprint_hex(data2
+1, 8));
557 PrintAndLog("Command execute timeout");
563 // Ultralight C Read Single Block
565 int CmdHF14AMfUCRdBl(const char *Cmd
)
570 PrintAndLog("Usage: hf mfu ucrdbl <block number>");
571 PrintAndLog(" sample: hf mfu ucrdbl 0");
575 blockNo
= param_get8(Cmd
, 0);
576 if (blockNo
>MAX_ULTRAC_BLOCKS
){
577 PrintAndLog("Error: Maximum number of readable blocks is 44 for Ultralight Cards!");
580 PrintAndLog("--block no:%02x", (int)blockNo
);
583 UsbCommand e
= {CMD_MIFAREU_READBL
, {blockNo
}};
586 if (WaitForResponseTimeout(CMD_ACK
,&resp_c
,1500)) {
587 uint8_t isOK
= resp_c
.arg
[0] & 0xff;
588 uint8_t * data
= resp_c
.d
.asBytes
;
590 PrintAndLog("isOk:%02x data:%s", isOK
, sprint_hex(data
, 4));
592 PrintAndLog("isOk:%02x", isOK
);
594 PrintAndLog("Command execute timeout");
600 // Ultralight C Read (or Dump) Card Contents
602 int CmdHF14AMfUCRdCard(const char *Cmd
){
606 uint8_t *lockbytes_t
=NULL
;
607 uint8_t lockbytes
[2]={0x00};
608 uint8_t *lockbytes_t2
=NULL
;
609 uint8_t lockbytes2
[2]={0x00};
611 bool bit2
[16]={0x00};
613 uint8_t datatemp
[5]={0x00};
615 uint8_t * data
= NULL
;
618 if (strchr(Cmd
,'x') != 0){
620 if ((fout
= fopen("dump_ultralightc_data.bin","wb")) == NULL
) {
621 PrintAndLog("Could not create file name dumpdata.bin");
624 PrintAndLog("Dumping Ultralight C Card Data...");
626 PrintAndLog("Attempting to Read Ultralight C... ");
627 UsbCommand c
= {CMD_MIFAREUC_READCARD
, {BlockNo
, Pages
}};
631 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
632 isOK
= resp
.arg
[0] & 0xff;
633 data
= resp
.d
.asBytes
;
634 //Pages=sizeof(data)/sizeof(data[0]);
635 PrintAndLog("isOk:%02x", isOK
);
637 for (i
= 0; i
< Pages
; i
++) {
641 lockbytes_t
=data
+(i
*4);
642 lockbytes
[0]=lockbytes_t
[2];
643 lockbytes
[1]=lockbytes_t
[3];
644 for(int j
=0; j
<16; j
++){
645 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
647 //might as well read bottom lockbytes too
648 lockbytes_t2
=data
+(40*4);
649 lockbytes2
[0]=lockbytes_t2
[2];
650 lockbytes2
[1]=lockbytes_t2
[3];
651 for(int j
=0; j
<16; j
++){
652 bit2
[j
]=lockbytes2
[j
/8] & ( 1 <<(7-j
%8));
654 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
655 memcpy(datatemp
,data
+ i
* 4,4);
656 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
659 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[4]);
660 memcpy(datatemp
,data
+ i
* 4,4);
661 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
664 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[3]);
665 memcpy(datatemp
,data
+ i
* 4,4);
666 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
669 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[2]);
670 memcpy(datatemp
,data
+ i
* 4,4);
671 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
674 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[1]);
675 memcpy(datatemp
,data
+ i
* 4,4);
676 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
679 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[0]);
680 memcpy(datatemp
,data
+ i
* 4,4);
681 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
684 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[15]);
685 memcpy(datatemp
,data
+ i
* 4,4);
686 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
689 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[14]);
690 memcpy(datatemp
,data
+ i
* 4,4);
691 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
694 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[13]);
695 memcpy(datatemp
,data
+ i
* 4,4);
696 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
699 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[12]);
700 memcpy(datatemp
,data
+ i
* 4,4);
701 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
704 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[11]);
705 memcpy(datatemp
,data
+ i
* 4,4);
706 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
709 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[10]);
710 memcpy(datatemp
,data
+ i
* 4,4);
711 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
714 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[9]);
715 memcpy(datatemp
,data
+ i
* 4,4);
716 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
719 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
720 memcpy(datatemp
,data
+ i
* 4,4);
721 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
727 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[6]);
728 memcpy(datatemp
,data
+ i
* 4,4);
729 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
735 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[5]);
736 memcpy(datatemp
,data
+ i
* 4,4);
737 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
743 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[4]);
744 memcpy(datatemp
,data
+ i
* 4,4);
745 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
751 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[2]);
752 memcpy(datatemp
,data
+ i
* 4,4);
753 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
759 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[1]);
760 memcpy(datatemp
,data
+ i
* 4,4);
761 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
767 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[0]);
768 memcpy(datatemp
,data
+ i
* 4,4);
769 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
772 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[12]);
773 memcpy(datatemp
,data
+ i
* 4,4);
774 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
777 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[11]);
778 memcpy(datatemp
,data
+ i
* 4,4);
779 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
783 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[10]);
784 memcpy(datatemp
,data
+ i
* 4,4);
785 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
789 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[9]);
790 memcpy(datatemp
,data
+ i
* 4,4);
791 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
794 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
795 memcpy(datatemp
,data
+ i
* 4,4);
796 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
802 PrintAndLog("Command1 execute timeout");
804 if (dump
) fclose(fout
);
809 // Ultralight C Dump Card Contents to file
811 int CmdHF14AMfUCDump(const char *Cmd
){
815 uint8_t *lockbytes_t
=NULL
;
816 uint8_t lockbytes
[2]={0x00};
817 uint8_t *lockbytes_t2
=NULL
;
818 uint8_t lockbytes2
[2]={0x00};
820 bool bit2
[16]={0x00};
822 uint8_t datatemp
[5]={0x00};
825 uint8_t * data
= NULL
;
828 if ((fout
= fopen("dump_ultralightc_data.bin","wb")) == NULL
) {
829 PrintAndLog("Could not create file name dumpdata.bin");
832 PrintAndLog("Dumping Ultralight C Card Data...");
833 PrintAndLog("Attempting to Read Ultralight C... ");
834 UsbCommand c
= {CMD_MIFAREU_READCARD
, {BlockNo
,Pages
}};
838 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
839 isOK
= resp
.arg
[0] & 0xff;
840 data
= resp
.d
.asBytes
;
841 PrintAndLog("isOk:%02x", isOK
);
843 for (i
= 0; i
< Pages
; i
++) {
847 lockbytes_t
=data
+(i
*4);
848 lockbytes
[0]=lockbytes_t
[2];
849 lockbytes
[1]=lockbytes_t
[3];
850 for(int j
=0; j
<16; j
++){
851 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
854 //might as well read bottom lockbytes too
855 lockbytes_t2
=data
+(40*4);
856 lockbytes2
[0]=lockbytes_t2
[2];
857 lockbytes2
[1]=lockbytes_t2
[3];
858 for(int j
=0; j
<16; j
++){
859 bit2
[j
]=lockbytes2
[j
/8] & ( 1 <<(7-j
%8));
862 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
863 memcpy(datatemp
,data
+ i
* 4,4);
864 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
867 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[4]);
868 memcpy(datatemp
,data
+ i
* 4,4);
869 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
872 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[3]);
873 memcpy(datatemp
,data
+ i
* 4,4);
874 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
877 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[2]);
878 memcpy(datatemp
,data
+ i
* 4,4);
879 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
882 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[1]);
883 memcpy(datatemp
,data
+ i
* 4,4);
884 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
887 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[0]);
888 memcpy(datatemp
,data
+ i
* 4,4);
889 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
892 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[15]);
893 memcpy(datatemp
,data
+ i
* 4,4);
894 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
897 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[14]);
898 memcpy(datatemp
,data
+ i
* 4,4);
899 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
902 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[13]);
903 memcpy(datatemp
,data
+ i
* 4,4);
904 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
907 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[12]);
908 memcpy(datatemp
,data
+ i
* 4,4);
909 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
912 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[11]);
913 memcpy(datatemp
,data
+ i
* 4,4);
914 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
917 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[10]);
918 memcpy(datatemp
,data
+ i
* 4,4);
919 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
922 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[9]);
923 memcpy(datatemp
,data
+ i
* 4,4);
924 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
927 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
928 memcpy(datatemp
,data
+ i
* 4,4);
929 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
935 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[6]);
936 memcpy(datatemp
,data
+ i
* 4,4);
937 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
943 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[5]);
944 memcpy(datatemp
,data
+ i
* 4,4);
945 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
951 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[4]);
952 memcpy(datatemp
,data
+ i
* 4,4);
953 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
959 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[2]);
960 memcpy(datatemp
,data
+ i
* 4,4);
961 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
967 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[1]);
968 memcpy(datatemp
,data
+ i
* 4,4);
969 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
975 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[0]);
976 memcpy(datatemp
,data
+ i
* 4,4);
977 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
980 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[12]);
981 memcpy(datatemp
,data
+ i
* 4,4);
982 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
985 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[11]);
986 memcpy(datatemp
,data
+ i
* 4,4);
987 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
991 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[10]);
992 memcpy(datatemp
,data
+ i
* 4,4);
993 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
997 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[9]);
998 memcpy(datatemp
,data
+ i
* 4,4);
999 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
1002 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
1003 memcpy(datatemp
,data
+ i
* 4,4);
1004 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
1010 PrintAndLog("Command1 execute timeout");
1012 if (dump
) fclose(fout
);
1017 // Mifare Ultralight C Write Single Block
1019 int CmdHF14AMfUCWrBl(const char *Cmd
){
1021 uint8_t blockNo
= 0;
1022 bool chinese_card
= 0;
1023 uint8_t bldata
[16] = {0x00};
1026 if (strlen(Cmd
)<3) {
1027 PrintAndLog("Usage: hf mfu ucwrbl <block number> <block data (8 hex symbols)> [w]");
1028 PrintAndLog(" sample: hf mfu uwrbl 0 01020304");
1031 blockNo
= param_get8(Cmd
, 0);
1032 if (blockNo
>(MAX_ULTRAC_BLOCKS
+4)){
1033 PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight Cards!");
1036 if (param_gethex(Cmd
, 1, bldata
, 8)) {
1037 PrintAndLog("Block data must include 8 HEX symbols");
1040 if (strchr(Cmd
,'w') != 0) {
1046 PrintAndLog("Access Denied");
1048 PrintAndLog("--specialblock no:%02x", blockNo
);
1049 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1050 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1051 memcpy(d
.d
.asBytes
,bldata
, 4);
1053 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1054 uint8_t isOK
= resp
.arg
[0] & 0xff;
1055 PrintAndLog("isOk:%02x", isOK
);
1057 PrintAndLog("Command execute timeout");
1063 PrintAndLog("Access Denied");
1065 PrintAndLog("--specialblock no:%02x", blockNo
);
1066 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1067 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1068 memcpy(d
.d
.asBytes
,bldata
, 4);
1070 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1071 uint8_t isOK
= resp
.arg
[0] & 0xff;
1072 PrintAndLog("isOk:%02x", isOK
);
1074 PrintAndLog("Command execute timeout");
1080 PrintAndLog("Access Denied");
1082 PrintAndLog("--specialblock no:%02x", blockNo
);
1083 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1084 UsbCommand c
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1085 memcpy(c
.d
.asBytes
, bldata
, 4);
1087 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1088 uint8_t isOK
= resp
.arg
[0] & 0xff;
1089 PrintAndLog("isOk:%02x", isOK
);
1091 PrintAndLog("Command execute timeout");
1096 PrintAndLog("--specialblock no:%02x", blockNo
);
1097 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1098 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1099 memcpy(d
.d
.asBytes
,bldata
, 4);
1101 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1102 uint8_t isOK
= resp
.arg
[0] & 0xff;
1103 PrintAndLog("isOk:%02x", isOK
);
1105 PrintAndLog("Command execute timeout");
1109 PrintAndLog("--block no:%02x", blockNo
);
1110 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1111 UsbCommand e
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1112 memcpy(e
.d
.asBytes
,bldata
, 4);
1114 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1115 uint8_t isOK
= resp
.arg
[0] & 0xff;
1116 PrintAndLog("isOk:%02x", isOK
);
1118 PrintAndLog("Command execute timeout");
1125 //------------------------------------
1127 //------------------------------------
1128 static command_t CommandTable
[] =
1130 {"help", CmdHelp
, 1,"This help"},
1131 {"dbg", CmdHF14AMfDbg
, 0,"Set default debug mode"},
1132 {"urdbl", CmdHF14AMfURdBl
, 0,"Read MIFARE Ultralight block"},
1133 {"urdcard", CmdHF14AMfURdCard
, 0,"Read MIFARE Ultralight Card"},
1134 {"udump", CmdHF14AMfUDump
, 0,"Dump MIFARE Ultralight tag to binary file"},
1135 {"uwrbl", CmdHF14AMfUWrBl
, 0,"Write MIFARE Ultralight block"},
1136 {"ucrdbl", CmdHF14AMfUCRdBl
, 0,"Read MIFARE Ultralight C block"},
1137 {"ucrdcard",CmdHF14AMfUCRdCard
, 0,"Read MIFARE Ultralight C Card"},
1138 {"ucdump", CmdHF14AMfUCDump
, 0,"Dump MIFARE Ultralight C tag to binary file"},
1139 {"ucwrbl", CmdHF14AMfUCWrBl
, 0,"Write MIFARE Ultralight C block"},
1140 {"auth", CmdHF14AMfucAuth
, 0,"Ultralight C Authentication"},
1141 {NULL
, NULL
, 0, NULL
}
1144 int CmdHFMFUltra(const char *Cmd
){
1146 WaitForResponseTimeout(CMD_ACK
,NULL
,100);
1147 CmdsParse(CommandTable
, Cmd
);
1151 int CmdHelp(const char *Cmd
){
1152 CmdsHelp(CommandTable
);