]>
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
){
29 uint8_t bldata
[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
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]={0,0};
177 bool bit
[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
179 uint8_t datatemp
[5]={0,0,0,0,0};
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]={0,0};
334 bool bit
[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
336 uint8_t datatemp
[5]={0,0,0,0,0};
339 uint8_t * data
= NULL
;
343 if ((fout
= fopen("dump_ultralight_data.bin","wb")) == NULL
) {
344 PrintAndLog("Could not create file name dumpdata.bin");
347 PrintAndLog("Dumping Ultralight Card Data...");
349 PrintAndLog("Attempting to Read Ultralight... ");
350 UsbCommand c
= {CMD_MIFAREU_READCARD
, {BlockNo
,Pages
}};
354 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
355 isOK
= resp
.arg
[0] & 0xff;
356 data
= resp
.d
.asBytes
;
357 PrintAndLog("isOk:%02x", isOK
);
359 for (i
= 0; i
< Pages
; i
++) {
363 lockbytes_t
=data
+(i
*4);
364 lockbytes
[0]=lockbytes_t
[2];
365 lockbytes
[1]=lockbytes_t
[3];
366 for(int j
=0; j
<16; j
++){
367 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
369 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
370 memcpy(datatemp
,data
+ i
* 4,4);
371 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
374 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[4]);
375 memcpy(datatemp
,data
+ i
* 4,4);
376 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
379 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[3]);
380 memcpy(datatemp
,data
+ i
* 4,4);
381 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
384 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[2]);
385 memcpy(datatemp
,data
+ i
* 4,4);
386 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
389 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[1]);
390 memcpy(datatemp
,data
+ i
* 4,4);
391 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
394 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[0]);
395 memcpy(datatemp
,data
+ i
* 4,4);
396 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
399 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[15]);
400 memcpy(datatemp
,data
+ i
* 4,4);
401 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
404 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[14]);
405 memcpy(datatemp
,data
+ i
* 4,4);
406 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
409 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[13]);
410 memcpy(datatemp
,data
+ i
* 4,4);
411 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
414 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[12]);
415 memcpy(datatemp
,data
+ i
* 4,4);
416 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
419 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[11]);
420 memcpy(datatemp
,data
+ i
* 4,4);
421 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
424 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[10]);
425 memcpy(datatemp
,data
+ i
* 4,4);
426 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
429 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[9]);
430 memcpy(datatemp
,data
+ i
* 4,4);
431 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
434 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
435 memcpy(datatemp
,data
+ i
* 4,4);
436 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
439 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
440 memcpy(datatemp
,data
+ i
* 4,4);
441 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
446 PrintAndLog("Command1 execute timeout");
448 if (dump
) fclose(fout
);
452 // Needed to Authenticate to Ultralight C tags
453 void rol (uint8_t *data
, const size_t len
){
454 uint8_t first
= data
[0];
455 for (size_t i
= 0; i
< len
-1; i
++) {
461 //-------------------------------------------------------------------------------
462 // Ultralight C Methods
463 //-------------------------------------------------------------------------------
466 // Ultralight C Authentication Demo {currently uses hard-coded key}
468 int CmdHF14AMfucAuth(const char *Cmd
){
470 uint8_t blockNo
= 0, keyNo
=0;
473 unsigned char RndARndB
[16];
475 DES_cblock RndA
, RndB
;
476 DES_cblock iv
={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
477 DES_key_schedule ks1
,ks2
;
478 DES_cblock key1
,key2
;
481 PrintAndLog("Usage: hf mfu auth k <key number>");
482 PrintAndLog(" sample: hf mfu auth k 0");
486 //Change key to user defined one
487 if (strchr(Cmd
,'k') != 0){
489 keyNo
= param_get8(Cmd
, 1);
492 memcpy(key
,key1_blnk_data
,16);
495 memcpy(key
,key2_defa_data
,16);
498 memcpy(key
,key4_nfc_data
,16);
501 memcpy(key
,key5_ones_data
,16);
504 memcpy(key
,key3_3des_data
,16);
508 memcpy(key
,key3_3des_data
,16);
511 memcpy(key2
,key
+8,8);
512 DES_set_key((DES_cblock
*)key1
,&ks1
);
513 DES_set_key((DES_cblock
*)key2
,&ks2
);
516 UsbCommand c
= {CMD_MIFAREUC_AUTH1
, {blockNo
}};
519 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
520 uint8_t isOK
= resp
.arg
[0] & 0xff;
522 uint8_t * data
= resp
.d
.asBytes
;
525 PrintAndLog("enc(RndB):%s", sprint_hex(data
+1, 8));
526 memcpy(e_RndB
,data
+1,8);
529 PrintAndLog("Command execute timeout");
533 DES_random_key(&RndA
);
534 DES_ede2_cbc_encrypt(e_RndB
,RndB
,sizeof(e_RndB
),&ks1
,&ks2
,&iv
,0);
535 PrintAndLog(" RndB:%s",sprint_hex(RndB
, 8));
536 PrintAndLog(" RndA:%s",sprint_hex(RndA
, 8));
538 memcpy(RndARndB
,RndA
,8);
539 memcpy(RndARndB
+8,RndB
,8);
540 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB
, 16));
541 DES_ede2_cbc_encrypt(RndARndB
,RndARndB
,sizeof(RndARndB
),&ks1
,&ks2
,&e_RndB
,1);
542 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB
, 16));
545 UsbCommand d
= {CMD_MIFAREUC_AUTH2
, {cuid
}};
546 memcpy(d
.d
.asBytes
,RndARndB
, 16);
550 if (WaitForResponseTimeout(CMD_ACK
,&respb
,1500)) {
551 uint8_t isOK
= respb
.arg
[0] & 0xff;
552 uint8_t * data2
= respb
.d
.asBytes
;
555 PrintAndLog("enc(RndA'):%s", sprint_hex(data2
+1, 8));
559 PrintAndLog("Command execute timeout");
565 // Ultralight C Read Single Block
567 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]={0,0};
611 uint8_t *lockbytes_t2
=NULL
;
612 uint8_t lockbytes2
[2]={0,0};
613 bool bit
[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
614 bool bit2
[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
616 uint8_t datatemp
[5]={0,0,0,0,0};
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
;
638 //Pages=sizeof(data)/sizeof(data[0]);
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]={0,0};
821 uint8_t *lockbytes_t2
=NULL
;
822 uint8_t lockbytes2
[2]={0,0};
823 bool bit
[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
824 bool bit2
[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
826 uint8_t datatemp
[5]={0,0,0,0,0};
829 uint8_t * data
= NULL
;
833 if ((fout
= fopen("dump_ultralightc_data.bin","wb")) == NULL
) {
834 PrintAndLog("Could not create file name dumpdata.bin");
837 PrintAndLog("Dumping Ultralight C Card Data...");
838 PrintAndLog("Attempting to Read Ultralight C... ");
839 UsbCommand c
= {CMD_MIFAREU_READCARD
, {BlockNo
,Pages
}};
843 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
844 isOK
= resp
.arg
[0] & 0xff;
845 data
= resp
.d
.asBytes
;
846 PrintAndLog("isOk:%02x", isOK
);
848 for (i
= 0; i
< Pages
; i
++) {
852 lockbytes_t
=data
+(i
*4);
853 lockbytes
[0]=lockbytes_t
[2];
854 lockbytes
[1]=lockbytes_t
[3];
855 for(int j
=0; j
<16; j
++){
856 bit
[j
]=lockbytes
[j
/8] & ( 1 <<(7-j
%8));
859 //might as well read bottom lockbytes too
860 lockbytes_t2
=data
+(40*4);
861 lockbytes2
[0]=lockbytes_t2
[2];
862 lockbytes2
[1]=lockbytes_t2
[3];
863 for(int j
=0; j
<16; j
++){
864 bit2
[j
]=lockbytes2
[j
/8] & ( 1 <<(7-j
%8));
867 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 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
[4]);
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
[3]);
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
[2]);
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
[1]);
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
[0]);
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
[15]);
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
[14]);
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
[13]);
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
[12]);
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
[11]);
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
[10]);
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
[9]);
928 memcpy(datatemp
,data
+ i
* 4,4);
929 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
932 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit
[8]);
933 memcpy(datatemp
,data
+ i
* 4,4);
934 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
940 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[6]);
941 memcpy(datatemp
,data
+ i
* 4,4);
942 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
948 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[5]);
949 memcpy(datatemp
,data
+ i
* 4,4);
950 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
956 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[4]);
957 memcpy(datatemp
,data
+ i
* 4,4);
958 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
964 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[2]);
965 memcpy(datatemp
,data
+ i
* 4,4);
966 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
972 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[1]);
973 memcpy(datatemp
,data
+ i
* 4,4);
974 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
980 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[0]);
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
[12]);
986 memcpy(datatemp
,data
+ i
* 4,4);
987 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
990 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[11]);
991 memcpy(datatemp
,data
+ i
* 4,4);
992 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
996 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[10]);
997 memcpy(datatemp
,data
+ i
* 4,4);
998 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
1002 PrintAndLog("Block %02x:%s [%d]", i
,sprint_hex(data
+ i
* 4, 4),bit2
[9]);
1003 memcpy(datatemp
,data
+ i
* 4,4);
1004 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
1007 PrintAndLog("Block %02x:%s ", i
,sprint_hex(data
+ i
* 4, 4));
1008 memcpy(datatemp
,data
+ i
* 4,4);
1009 if (dump
) fwrite ( datatemp
, 1, 4, fout
);
1015 PrintAndLog("Command1 execute timeout");
1017 if (dump
) fclose(fout
);
1022 // Mifare Ultralight C Write Single Block
1024 int CmdHF14AMfUCWrBl(const char *Cmd
){
1026 uint8_t blockNo
= 0;
1027 bool chinese_card
=0;
1028 uint8_t bldata
[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1031 if (strlen(Cmd
)<3) {
1032 PrintAndLog("Usage: hf mfu ucwrbl <block number> <block data (8 hex symbols)> [w]");
1033 PrintAndLog(" sample: hf mfu uwrbl 0 01020304");
1036 blockNo
= param_get8(Cmd
, 0);
1037 if (blockNo
>(MAX_ULTRAC_BLOCKS
+4)){
1038 PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight Cards!");
1041 if (param_gethex(Cmd
, 1, bldata
, 8)) {
1042 PrintAndLog("Block data must include 8 HEX symbols");
1045 if (strchr(Cmd
,'w') != 0) {
1051 PrintAndLog("Access Denied");
1053 PrintAndLog("--specialblock no:%02x", blockNo
);
1054 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1055 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1056 memcpy(d
.d
.asBytes
,bldata
, 4);
1058 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1059 uint8_t isOK
= resp
.arg
[0] & 0xff;
1060 PrintAndLog("isOk:%02x", isOK
);
1062 PrintAndLog("Command execute timeout");
1068 PrintAndLog("Access Denied");
1070 PrintAndLog("--specialblock no:%02x", blockNo
);
1071 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1072 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1073 memcpy(d
.d
.asBytes
,bldata
, 4);
1075 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1076 uint8_t isOK
= resp
.arg
[0] & 0xff;
1077 PrintAndLog("isOk:%02x", isOK
);
1079 PrintAndLog("Command execute timeout");
1085 PrintAndLog("Access Denied");
1087 PrintAndLog("--specialblock no:%02x", blockNo
);
1088 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1089 UsbCommand c
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1090 memcpy(c
.d
.asBytes
, bldata
, 4);
1092 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1093 uint8_t isOK
= resp
.arg
[0] & 0xff;
1094 PrintAndLog("isOk:%02x", isOK
);
1096 PrintAndLog("Command execute timeout");
1101 PrintAndLog("--specialblock no:%02x", blockNo
);
1102 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1103 UsbCommand d
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1104 memcpy(d
.d
.asBytes
,bldata
, 4);
1106 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1107 uint8_t isOK
= resp
.arg
[0] & 0xff;
1108 PrintAndLog("isOk:%02x", isOK
);
1110 PrintAndLog("Command execute timeout");
1114 PrintAndLog("--block no:%02x", blockNo
);
1115 PrintAndLog("--data: %s", sprint_hex(bldata
, 4));
1116 UsbCommand e
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1117 memcpy(e
.d
.asBytes
,bldata
, 4);
1119 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1120 uint8_t isOK
= resp
.arg
[0] & 0xff;
1121 PrintAndLog("isOk:%02x", isOK
);
1123 PrintAndLog("Command execute timeout");
1130 //------------------------------------
1132 //------------------------------------
1133 static command_t CommandTable
[] =
1135 {"help", CmdHelp
, 1,"This help"},
1136 {"dbg", CmdHF14AMfDbg
, 0,"Set default debug mode"},
1137 {"urdbl", CmdHF14AMfURdBl
, 0,"Read MIFARE Ultralight block"},
1138 {"urdcard", CmdHF14AMfURdCard
, 0,"Read MIFARE Ultralight Card"},
1139 {"udump", CmdHF14AMfUDump
, 0,"Dump MIFARE Ultralight tag to binary file"},
1140 {"uwrbl", CmdHF14AMfUWrBl
, 0,"Write MIFARE Ultralight block"},
1141 {"ucrdbl", CmdHF14AMfUCRdBl
, 0,"Read MIFARE Ultralight C block"},
1142 {"ucrdcard",CmdHF14AMfUCRdCard
, 0,"Read MIFARE Ultralight C Card"},
1143 {"ucdump", CmdHF14AMfUCDump
, 0,"Dump MIFARE Ultralight C tag to binary file"},
1144 {"ucwrbl", CmdHF14AMfUCWrBl
, 0,"Write MIFARE Ultralight C block"},
1145 {"auth", CmdHF14AMfucAuth
, 0,"Ultralight C Authentication"},
1146 {NULL
, NULL
, 0, NULL
}
1149 int CmdHFMFUltra(const char *Cmd
){
1151 WaitForResponseTimeout(CMD_ACK
,NULL
,100);
1152 CmdsParse(CommandTable
, Cmd
);
1156 int CmdHelp(const char *Cmd
){
1157 CmdsHelp(CommandTable
);