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 "loclass/des.h"
16 #include "protocols.h"
19 #define MAX_UL_BLOCKS 0x0f
20 #define MAX_ULC_BLOCKS 0x2b
21 #define MAX_ULEV1a_BLOCKS 0x13
22 #define MAX_ULEV1b_BLOCKS 0x28
23 #define MAX_NTAG_203 0x29
24 #define MAX_NTAG_210 0x13
25 #define MAX_NTAG_212 0x28
26 #define MAX_NTAG_213 0x2c
27 #define MAX_NTAG_215 0x86
28 #define MAX_NTAG_216 0xe6
29 #define MAX_MY_D_NFC 0xff
30 #define MAX_MY_D_MOVE 0x25
31 #define MAX_MY_D_MOVE_LEAN 0x0f
33 #define KEYS_3DES_COUNT 7
34 uint8_t default_3des_keys
[KEYS_3DES_COUNT
][16] = {
35 { 0x42,0x52,0x45,0x41,0x4b,0x4d,0x45,0x49,0x46,0x59,0x4f,0x55,0x43,0x41,0x4e,0x21 },// 3des std key
36 { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },// all zeroes
37 { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f },// 0x00-0x0F
38 { 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 },// NFC-key
39 { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },// all ones
40 { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF },// all FF
41 { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF } // 11 22 33
44 #define KEYS_PWD_COUNT 1
45 uint8_t default_pwd_pack
[KEYS_PWD_COUNT
][4] = {
46 {0xFF,0xFF,0xFF,0xFF}, // PACK 0x00,0x00 -- factory default
49 #define MAX_UL_TYPES 18
50 uint32_t UL_TYPES_ARRAY
[MAX_UL_TYPES
] = {
52 UL_EV1_48
, UL_EV1_128
, NTAG
,
53 NTAG_203
, NTAG_210
, NTAG_212
,
54 NTAG_213
, NTAG_215
, NTAG_216
,
55 MY_D
, MY_D_NFC
, MY_D_MOVE
,
56 MY_D_MOVE_NFC
, MY_D_MOVE_LEAN
, FUDAN_UL
};
58 uint8_t UL_MEMORY_ARRAY
[MAX_UL_TYPES
] = {
59 MAX_UL_BLOCKS
, MAX_UL_BLOCKS
, MAX_ULC_BLOCKS
,
60 MAX_ULEV1a_BLOCKS
, MAX_ULEV1b_BLOCKS
, MAX_NTAG_203
,
61 MAX_NTAG_203
, MAX_NTAG_210
, MAX_NTAG_212
,
62 MAX_NTAG_213
, MAX_NTAG_215
, MAX_NTAG_216
,
63 MAX_UL_BLOCKS
, MAX_MY_D_NFC
, MAX_MY_D_MOVE
,
64 MAX_MY_D_MOVE
, MAX_MY_D_MOVE_LEAN
, MAX_UL_BLOCKS
};
66 // Certain pwd generation algo nickname A.
67 uint32_t ul_ev1_pwdgenA(uint8_t* uid
) {
69 uint8_t pos
= (uid
[3] ^ uid
[4] ^ uid
[5] ^ uid
[6]) % 32;
71 uint32_t xortable
[] = {
72 0x4f2711c1, 0x07D7BB83, 0x9636EF07, 0xB5F4460E, 0xF271141C, 0x7D7BB038, 0x636EF871, 0x5F4468E3,
73 0x271149C7, 0xD7BB0B8F, 0x36EF8F1E, 0xF446863D, 0x7114947A, 0x7BB0B0F5, 0x6EF8F9EB, 0x44686BD7,
74 0x11494fAF, 0xBB0B075F, 0xEF8F96BE, 0x4686B57C, 0x1494F2F9, 0xB0B07DF3, 0xF8F963E6, 0x686B5FCC,
75 0x494F2799, 0x0B07D733, 0x8F963667, 0x86B5F4CE, 0x94F2719C, 0xB07D7B38, 0xF9636E70, 0x6B5F44E0
78 uint8_t entry
[] = {0x00,0x00,0x00,0x00};
79 uint8_t pwd
[] = {0x00,0x00,0x00,0x00};
81 num_to_bytes( xortable
[pos
], 4, entry
);
83 pwd
[0] = entry
[0] ^ uid
[1] ^ uid
[2] ^ uid
[3];
84 pwd
[1] = entry
[1] ^ uid
[0] ^ uid
[2] ^ uid
[4];
85 pwd
[2] = entry
[2] ^ uid
[0] ^ uid
[1] ^ uid
[5];
86 pwd
[3] = entry
[3] ^ uid
[6];
88 return (uint32_t)bytes_to_num(pwd
, 4);
91 // Certain pwd generation algo nickname B. (very simple)
92 uint32_t ul_ev1_pwdgenB(uint8_t* uid
) {
94 uint8_t pwd
[] = {0x00,0x00,0x00,0x00};
96 pwd
[0] = uid
[1] ^ uid
[3] ^ 0xAA;
97 pwd
[1] = uid
[2] ^ uid
[4] ^ 0x55;
98 pwd
[2] = uid
[3] ^ uid
[5] ^ 0xAA;
99 pwd
[3] = uid
[4] ^ uid
[6] ^ 0x55;
100 return (uint32_t)bytes_to_num(pwd
, 4);
103 // Certain pwd generation algo nickname C.
104 uint32_t ul_ev1_pwdgenC(uint8_t* uid
){
107 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x28,
108 0x63, 0x29, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72,
109 0x69, 0x67, 0x68, 0x74, 0x20, 0x4c, 0x45, 0x47,
110 0x4f, 0x20, 0x32, 0x30, 0x31, 0x34, 0xaa, 0xaa
113 memcpy(base
, uid
, 7);
115 for (int i
= 0; i
< 32; i
+= 4) {
116 uint32_t b
= *(uint32_t *)(base
+ i
);
117 pwd
= b
+ ROTR(pwd
, 25) + ROTR(pwd
, 10) - pwd
;
119 return BSWAP_32(pwd
);
122 void ul_ev1_pwdgen_selftest(){
124 uint8_t uid1
[] = {0x04,0x11,0x12,0x11,0x12,0x11,0x10};
125 uint32_t pwd1
= ul_ev1_pwdgenA(uid1
);
126 PrintAndLog("UID | %s | %08X | %s", sprint_hex(uid1
,7), pwd1
, (pwd1
== 0x8432EB17)?"OK":"->8432EB17<-");
128 uint8_t uid2
[] = {0x04,0x1f,0x98,0xea,0x1e,0x3e,0x81};
129 uint32_t pwd2
= ul_ev1_pwdgenB(uid2
);
130 PrintAndLog("UID | %s | %08X | %s", sprint_hex(uid2
,7), pwd2
, (pwd2
== 0x5fd37eca)?"OK":"->5fd37eca<--");
132 uint8_t uid3
[] = {0x04,0x62, 0xB6, 0x8A, 0xB4, 0x42, 0x80};
133 uint32_t pwd3
= ul_ev1_pwdgenC(uid3
);
134 PrintAndLog("UID | %s | %08X | %s", sprint_hex(uid3
,7), pwd3
, (pwd3
== 0x5a349515)?"OK":"->5a349515<--");
138 static int CmdHelp(const char *Cmd
);
140 // get version nxp product type
141 char *getProductTypeStr( uint8_t id
){
147 case 3: sprintf(retStr
, "%02X, Ultralight", id
); break;
148 case 4: sprintf(retStr
, "%02X, NTAG", id
); break;
149 default: sprintf(retStr
, "%02X, unknown", id
); break;
155 The 7 MSBits (=n) code the storage size itself based on 2^n,
156 the LSBit is set to '0' if the size is exactly 2^n
157 and set to '1' if the storage size is between 2^n and 2^(n+1).
159 char *getUlev1CardSizeStr( uint8_t fsize
){
163 memset(buf
, 0, sizeof(buf
));
165 uint16_t usize
= 1 << ((fsize
>>1) + 1);
166 uint16_t lsize
= 1 << (fsize
>>1);
170 sprintf(retStr
, "%02X, (%u <-> %u bytes)",fsize
, usize
, lsize
);
172 sprintf(retStr
, "%02X, (%u bytes)", fsize
, lsize
);
176 static void ul_switch_on_field(void) {
177 UsbCommand c
= {CMD_READER_ISO_14443a
, {ISO14A_CONNECT
| ISO14A_NO_DISCONNECT
, 0, 0}};
178 clearCommandBuffer();
182 void ul_switch_off_field(void) {
183 UsbCommand c
= {CMD_READER_ISO_14443a
, {0, 0, 0}};
184 clearCommandBuffer();
188 static int ul_send_cmd_raw( uint8_t *cmd
, uint8_t cmdlen
, uint8_t *response
, uint16_t responseLength
) {
189 UsbCommand c
= {CMD_READER_ISO_14443a
, {ISO14A_RAW
| ISO14A_NO_DISCONNECT
| ISO14A_APPEND_CRC
, cmdlen
, 0}};
190 memcpy(c
.d
.asBytes
, cmd
, cmdlen
);
191 clearCommandBuffer();
194 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 1500)) return -1;
195 if (!resp
.arg
[0] && responseLength
) return -1;
197 uint16_t resplen
= (resp
.arg
[0] < responseLength
) ? resp
.arg
[0] : responseLength
;
198 memcpy(response
, resp
.d
.asBytes
, resplen
);
202 static int ul_select( iso14a_card_select_t
*card
){
204 ul_switch_on_field();
208 ans
= WaitForResponseTimeout(CMD_ACK
, &resp
, 1500);
209 if (!ans
|| resp
.arg
[0] < 1) {
210 PrintAndLog("iso14443a card select failed");
211 ul_switch_off_field();
215 memcpy(card
, resp
.d
.asBytes
, sizeof(iso14a_card_select_t
));
219 // This read command will at least return 16bytes.
220 static int ul_read( uint8_t page
, uint8_t *response
, uint16_t responseLength
){
222 uint8_t cmd
[] = {ISO14443A_CMD_READBLOCK
, page
};
223 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), response
, responseLength
);
227 static int ul_comp_write( uint8_t page
, uint8_t *data
, uint8_t datalen
){
230 memset(cmd
, 0x00, sizeof(cmd
));
231 datalen
= ( datalen
> 16) ? 16 : datalen
;
233 cmd
[0] = ISO14443A_CMD_WRITEBLOCK
;
235 memcpy(cmd
+2, data
, datalen
);
237 uint8_t response
[1] = {0xff};
238 ul_send_cmd_raw(cmd
, 2+datalen
, response
, sizeof(response
));
240 if ( response
[0] == 0x0a ) return 0;
245 static int ulc_requestAuthentication( uint8_t *nonce
, uint16_t nonceLength
){
247 uint8_t cmd
[] = {MIFARE_ULC_AUTH_1
, 0x00};
248 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), nonce
, nonceLength
);
252 static int ulc_authentication( uint8_t *key
, bool switch_off_field
){
254 UsbCommand c
= {CMD_MIFAREUC_AUTH
, {switch_off_field
}};
255 memcpy(c
.d
.asBytes
, key
, 16);
256 clearCommandBuffer();
259 if ( !WaitForResponseTimeout(CMD_ACK
, &resp
, 1500) ) return 0;
260 if ( resp
.arg
[0] == 1 ) return 1;
265 static int ulev1_requestAuthentication( uint8_t *pwd
, uint8_t *pack
, uint16_t packLength
){
267 uint8_t cmd
[] = {MIFARE_ULEV1_AUTH
, pwd
[0], pwd
[1], pwd
[2], pwd
[3]};
268 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), pack
, packLength
);
272 static int ul_auth_select( iso14a_card_select_t
*card
, TagTypeUL_t tagtype
, bool hasAuthKey
, uint8_t *authenticationkey
, uint8_t *pack
, uint8_t packSize
){
273 if ( hasAuthKey
&& (tagtype
& UL_C
)) {
274 //will select card automatically and close connection on error
275 if (!ulc_authentication(authenticationkey
, false)) {
276 PrintAndLog("Error: Authentication Failed UL-C");
280 if ( !ul_select(card
) ) return 0;
283 if (ulev1_requestAuthentication(authenticationkey
, pack
, packSize
) < 2) {
284 ul_switch_off_field();
285 PrintAndLog("Error: Authentication Failed UL-EV1/NTAG");
293 static int ulev1_getVersion( uint8_t *response
, uint16_t responseLength
){
295 uint8_t cmd
[] = {MIFARE_ULEV1_VERSION
};
296 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), response
, responseLength
);
300 static int ulev1_readCounter( uint8_t counter
, uint8_t *response
, uint16_t responseLength
){
302 uint8_t cmd
[] = {MIFARE_ULEV1_READ_CNT
, counter
};
303 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), response
, responseLength
);
307 static int ulev1_readTearing( uint8_t counter
, uint8_t *response
, uint16_t responseLength
){
309 uint8_t cmd
[] = {MIFARE_ULEV1_CHECKTEAR
, counter
};
310 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), response
, responseLength
);
314 static int ulev1_readSignature( uint8_t *response
, uint16_t responseLength
){
316 uint8_t cmd
[] = {MIFARE_ULEV1_READSIG
, 0x00};
317 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), response
, responseLength
);
321 // Fudan check checks for which error is given for a command with incorrect crc
322 // NXP UL chip responds with 01, fudan 00.
323 // other possible checks:
325 // UL responds with 00, fudan doesn't respond
328 // UL doesn't respond, fudan responds with 00
330 // send 300000 + crc (read with extra byte(s))
331 // UL responds with read of page 0, fudan doesn't respond.
333 // make sure field is off before calling this function
334 static int ul_fudan_check( void ){
335 iso14a_card_select_t card
;
336 if ( !ul_select(&card
) )
339 UsbCommand c
= {CMD_READER_ISO_14443a
, {ISO14A_RAW
| ISO14A_NO_DISCONNECT
, 4, 0}};
341 uint8_t cmd
[4] = {0x30,0x00,0x02,0xa7}; //wrong crc on purpose should be 0xa8
342 memcpy(c
.d
.asBytes
, cmd
, 4);
343 clearCommandBuffer();
346 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 1500)) return UL_ERROR
;
347 if (resp
.arg
[0] != 1) return UL_ERROR
;
349 return (!resp
.d
.asBytes
[0]) ? FUDAN_UL
: UL
; //if response == 0x00 then Fudan, else Genuine NXP
352 static int ul_print_default( uint8_t *data
){
363 PrintAndLog(" UID : %s ", sprint_hex(uid
, 7));
364 PrintAndLog(" UID[0] : %02X, %s", uid
[0], getTagInfo(uid
[0]) );
365 if ( uid
[0] == 0x05 && ((uid
[1] & 0xf0) >> 4) == 2 ) { // is infineon and 66RxxP
366 uint8_t chip
= (data
[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU
368 case 0xc2: PrintAndLog(" IC type : SLE 66R04P 770 Bytes"); break; //77 pages
369 case 0xc4: PrintAndLog(" IC type : SLE 66R16P 2560 Bytes"); break; //256 pages
370 case 0xc6: PrintAndLog(" IC type : SLE 66R32P 5120 Bytes"); break; //512 pages /2 sectors
373 // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
374 int crc0
= 0x88 ^ data
[0] ^ data
[1] ^data
[2];
375 if ( data
[3] == crc0
)
376 PrintAndLog(" BCC0 : %02X, Ok", data
[3]);
378 PrintAndLog(" BCC0 : %02X, crc should be %02X", data
[3], crc0
);
380 int crc1
= data
[4] ^ data
[5] ^ data
[6] ^data
[7];
381 if ( data
[8] == crc1
)
382 PrintAndLog(" BCC1 : %02X, Ok", data
[8]);
384 PrintAndLog(" BCC1 : %02X, crc should be %02X", data
[8], crc1
);
386 PrintAndLog(" Internal : %02X, %sdefault", data
[9], (data
[9]==0x48)?"":"not " );
388 PrintAndLog(" Lock : %s - %s",
389 sprint_hex(data
+10, 2),
390 sprint_bin(data
+10, 2)
393 PrintAndLog("OneTimePad : %s - %s\n",
394 sprint_hex(data
+ 12, 4),
395 sprint_bin(data
+12, 4)
401 static int ndef_print_CC(uint8_t *data
) {
406 PrintAndLog("--- NDEF Message");
407 PrintAndLog("Capability Container: %s", sprint_hex(data
,4) );
408 PrintAndLog(" %02X : NDEF Magic Number", data
[0]);
409 PrintAndLog(" %02X : version %d.%d supported by tag", data
[1], (data
[1] & 0xF0) >> 4, data
[1] & 0x0f);
410 PrintAndLog(" %02X : Physical Memory Size: %d bytes", data
[2], (data
[2] + 1) * 8);
411 if ( data
[2] == 0x96 )
412 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data
[2], 48);
413 else if ( data
[2] == 0x12 )
414 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data
[2], 144);
415 else if ( data
[2] == 0x3e )
416 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data
[2], 496);
417 else if ( data
[2] == 0x6d )
418 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data
[2], 872);
420 PrintAndLog(" %02X : %s / %s", data
[3],
421 (data
[3] & 0xF0) ? "(RFU)" : "Read access granted without any security",
422 (data
[3] & 0x0F)==0 ? "Write access granted without any security" : (data
[3] & 0x0F)==0x0F ? "No write access granted at all" : "(RFU)");
426 int ul_print_type(uint32_t tagtype
, uint8_t spaces
){
429 char *spacer
= spc
+ (10-spaces
);
432 PrintAndLog("%sTYPE : MIFARE Ultralight (MF0ICU1) %s", spacer
, (tagtype
& MAGIC
) ? "<magic>" : "" );
433 else if ( tagtype
& UL_C
)
434 PrintAndLog("%sTYPE : MIFARE Ultralight C (MF0ULC) %s", spacer
, (tagtype
& MAGIC
) ? "<magic>" : "" );
435 else if ( tagtype
& UL_EV1_48
)
436 PrintAndLog("%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer
);
437 else if ( tagtype
& UL_EV1_128
)
438 PrintAndLog("%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer
);
439 else if ( tagtype
& NTAG
)
440 PrintAndLog("%sTYPE : NTAG UNKNOWN", spacer
);
441 else if ( tagtype
& NTAG_203
)
442 PrintAndLog("%sTYPE : NTAG 203 144bytes (NT2H0301F0DT)", spacer
);
443 else if ( tagtype
& NTAG_210
)
444 PrintAndLog("%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer
);
445 else if ( tagtype
& NTAG_212
)
446 PrintAndLog("%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer
);
447 else if ( tagtype
& NTAG_213
)
448 PrintAndLog("%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer
);
449 else if ( tagtype
& NTAG_215
)
450 PrintAndLog("%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer
);
451 else if ( tagtype
& NTAG_216
)
452 PrintAndLog("%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer
);
453 else if ( tagtype
& NTAG_I2C_1K
)
454 PrintAndLog("%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer
, "\xFD");
455 else if ( tagtype
& NTAG_I2C_2K
)
456 PrintAndLog("%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer
, "\xFD");
457 else if ( tagtype
& MY_D
)
458 PrintAndLog("%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer
);
459 else if ( tagtype
& MY_D_NFC
)
460 PrintAndLog("%sTYPE : INFINEON my-d\x99 NFC (SLE 66RxxP)", spacer
);
461 else if ( tagtype
& MY_D_MOVE
)
462 PrintAndLog("%sTYPE : INFINEON my-d\x99 move (SLE 66R01P)", spacer
);
463 else if ( tagtype
& MY_D_MOVE_NFC
)
464 PrintAndLog("%sTYPE : INFINEON my-d\x99 move NFC (SLE 66R01P)", spacer
);
465 else if ( tagtype
& MY_D_MOVE_LEAN
)
466 PrintAndLog("%sTYPE : INFINEON my-d\x99 move lean (SLE 66R01L)", spacer
);
467 else if ( tagtype
& FUDAN_UL
)
468 PrintAndLog("%sTYPE : FUDAN Ultralight Compatible (or other compatible) %s", spacer
, (tagtype
& MAGIC
) ? "<magic>" : "" );
470 PrintAndLog("%sTYPE : Unknown %06x", spacer
, tagtype
);
474 static int ulc_print_3deskey( uint8_t *data
){
475 PrintAndLog(" deskey1 [44/0x2C] : %s [%.4s]", sprint_hex(data
,4),data
);
476 PrintAndLog(" deskey1 [45/0x2D] : %s [%.4s]", sprint_hex(data
+4 ,4),data
+4);
477 PrintAndLog(" deskey2 [46/0x2E] : %s [%.4s]", sprint_hex(data
+8 ,4),data
+8);
478 PrintAndLog(" deskey2 [47/0x2F] : %s [%.4s]", sprint_hex(data
+12,4),data
+12);
479 PrintAndLog("\n 3des key : %s", sprint_hex(SwapEndian64(data
, 16, 8), 16));
483 static int ulc_print_configuration( uint8_t *data
){
485 PrintAndLog("--- UL-C Configuration");
486 PrintAndLog(" Higher Lockbits [40/0x28] : %s - %s", sprint_hex(data
, 4), sprint_bin(data
, 2));
487 PrintAndLog(" Counter [41/0x29] : %s - %s", sprint_hex(data
+4, 4), sprint_bin(data
+4, 2));
489 bool validAuth
= (data
[8] >= 0x03 && data
[8] <= 0x30);
491 PrintAndLog(" Auth0 [42/0x2A] : %s page %d/0x%02X and above need authentication", sprint_hex(data
+8, 4), data
[8],data
[8] );
494 PrintAndLog(" Auth0 [42/0x2A] : %s default", sprint_hex(data
+8, 4) );
496 PrintAndLog(" Auth0 [42/0x2A] : %s auth byte is out-of-range", sprint_hex(data
+8, 4) );
499 PrintAndLog(" Auth1 [43/0x2B] : %s %s",
500 sprint_hex(data
+12, 4),
501 (data
[12] & 1) ? "write access restricted": "read and write access restricted"
506 static int ulev1_print_configuration( uint8_t *data
, uint8_t startPage
){
508 PrintAndLog("\n--- Tag Configuration");
510 bool strg_mod_en
= (data
[0] & 2);
511 uint8_t authlim
= (data
[4] & 0x07);
512 bool nfc_cnf_en
= (data
[4] & 0x08);
513 bool nfc_cnf_prot_pwd
= (data
[4] & 0x10);
514 bool cfglck
= (data
[4] & 0x40);
515 bool prot
= (data
[4] & 0x80);
516 uint8_t vctid
= data
[5];
518 PrintAndLog(" cfg0 [%u/0x%02X] : %s", startPage
, startPage
, sprint_hex(data
, 4));
519 if ( data
[3] < 0xff )
520 PrintAndLog(" - page %d and above need authentication",data
[3]);
522 PrintAndLog(" - pages don't need authentication");
523 PrintAndLog(" - strong modulation mode %s", (strg_mod_en
) ? "enabled":"disabled");
524 PrintAndLog(" cfg1 [%u/0x%02X] : %s", startPage
+ 1, startPage
+ 1, sprint_hex(data
+4, 4) );
526 PrintAndLog(" - Unlimited password attempts");
528 PrintAndLog(" - Max number of password attempts is %d", authlim
);
530 PrintAndLog(" - NFC counter %s", (nfc_cnf_en
) ? "enabled":"disabled");
531 PrintAndLog(" - NFC counter %s", (nfc_cnf_prot_pwd
) ? "not protected":"password protection enabled");
533 PrintAndLog(" - user configuration %s", cfglck
? "permanently locked":"writeable");
534 PrintAndLog(" - %s access is protected with password", prot
? "read and write":"write");
535 PrintAndLog(" - %02X, Virtual Card Type Identifier is %s default", vctid
, (vctid
==0x05)? "":"not");
536 PrintAndLog(" PWD [%u/0x%02X] : %s- (cannot be read)", startPage
+ 2, startPage
+ 2, sprint_hex(data
+8, 4));
537 PrintAndLog(" PACK [%u/0x%02X] : %s - (cannot be read)", startPage
+ 3, startPage
+ 3, sprint_hex(data
+12, 2));
538 PrintAndLog(" RFU [%u/0x%02X] : %s- (cannot be read)", startPage
+ 3, startPage
+ 3, sprint_hex(data
+12, 2));
542 static int ulev1_print_counters(){
543 PrintAndLog("--- Tag Counters");
544 uint8_t tear
[1] = {0};
545 uint8_t counter
[3] = {0,0,0};
547 for ( uint8_t i
= 0; i
<3; ++i
) {
548 ulev1_readTearing(i
,tear
,sizeof(tear
));
549 len
= ulev1_readCounter(i
,counter
, sizeof(counter
) );
551 PrintAndLog(" [%0d] : %s", i
, sprint_hex(counter
,3));
552 PrintAndLog(" - %02X tearing %s", tear
[0], ( tear
[0]==0xBD)?"Ok":"failure");
558 static int ulev1_print_signature( uint8_t *data
, uint8_t len
){
559 PrintAndLog("\n--- Tag Signature");
560 //PrintAndLog("IC signature public key name : NXP NTAG21x 2013"); // don't know if there is other NXP public keys.. :(
561 PrintAndLog("IC signature public key value : 04494e1a386d3d3cfe3dc10e5de68a499b1c202db5b132393e89ed19fe5be8bc61");
562 PrintAndLog(" Elliptic curve parameters : secp128r1");
563 PrintAndLog(" Tag ECC Signature : %s", sprint_hex(data
, len
));
564 //to do: verify if signature is valid
565 //PrintAndLog("IC signature status: %s valid", (iseccvalid() )?"":"not");
569 static int ulev1_print_version(uint8_t *data
){
570 PrintAndLog("\n--- Tag Version");
571 PrintAndLog(" Raw bytes : %s",sprint_hex(data
, 8) );
572 PrintAndLog(" Vendor ID : %02X, %s", data
[1], getTagInfo(data
[1]));
573 PrintAndLog(" Product type : %s", getProductTypeStr(data
[2]));
574 PrintAndLog(" Product subtype : %02X, %s", data
[3], (data
[3]==1) ?"17 pF":"50pF");
575 PrintAndLog(" Major version : %02X", data
[4]);
576 PrintAndLog(" Minor version : %02X", data
[5]);
577 PrintAndLog(" Size : %s", getUlev1CardSizeStr(data
[6]));
578 PrintAndLog(" Protocol type : %02X", data
[7]);
583 static int ulc_magic_test(){
584 // Magic Ultralight test
585 // Magic UL-C, by observation,
586 // 1) it seems to have a static nonce response to 0x1A command.
587 // 2) the deskey bytes is not-zero:d out on as datasheet states.
588 // 3) UID - changeable, not only, but pages 0-1-2-3.
589 // 4) use the ul_magic_test ! magic tags answers specially!
590 int returnValue = UL_ERROR;
591 iso14a_card_select_t card;
592 uint8_t nonce1[11] = {0x00};
593 uint8_t nonce2[11] = {0x00};
594 int status = ul_select(&card);
598 status = ulc_requestAuthentication(nonce1, sizeof(nonce1));
600 status = ulc_requestAuthentication(nonce2, sizeof(nonce2));
601 returnValue = ( !memcmp(nonce1, nonce2, 11) ) ? UL_C_MAGIC : UL_C;
605 ul_switch_off_field();
609 static int ul_magic_test(){
611 // Magic Ultralight tests
612 // 1) take present UID, and try to write it back. OBSOLETE
613 // 2) make a wrong length write to page0, and see if tag answers with ACK/NACK:
614 iso14a_card_select_t card
;
615 if ( !ul_select(&card
) )
617 int status
= ul_comp_write(0, NULL
, 0);
618 ul_switch_off_field();
624 uint32_t GetHF14AMfU_Type(void){
626 TagTypeUL_t tagtype
= UNKNOWN
;
627 iso14a_card_select_t card
;
628 uint8_t version
[10] = {0x00};
632 if (!ul_select(&card
)) return UL_ERROR
;
634 // Ultralight - ATQA / SAK
635 if ( card
.atqa
[1] != 0x00 || card
.atqa
[0] != 0x44 || card
.sak
!= 0x00 ) {
636 PrintAndLog("Tag is not Ultralight | NTAG | MY-D [ATQA: %02X %02X SAK: %02X]\n", card
.atqa
[1], card
.atqa
[0], card
.sak
);
637 ul_switch_off_field();
641 if ( card
.uid
[0] != 0x05) {
643 len
= ulev1_getVersion(version
, sizeof(version
));
644 ul_switch_off_field();
649 if ( version
[2] == 0x03 && version
[6] == 0x0B )
651 else if ( version
[2] == 0x03 && version
[6] != 0x0B )
652 tagtype
= UL_EV1_128
;
653 else if ( version
[2] == 0x04 && version
[3] == 0x01 && version
[6] == 0x0B )
655 else if ( version
[2] == 0x04 && version
[3] == 0x01 && version
[6] == 0x0E )
657 else if ( version
[2] == 0x04 && version
[3] == 0x02 && version
[6] == 0x0F )
659 else if ( version
[2] == 0x04 && version
[3] == 0x02 && version
[6] == 0x11 )
661 else if ( version
[2] == 0x04 && version
[3] == 0x02 && version
[6] == 0x13 )
663 else if ( version
[2] == 0x04 && version
[3] == 0x05 && version
[6] == 0x13 )
664 tagtype
= NTAG_I2C_1K
;
665 else if ( version
[2] == 0x04 && version
[3] == 0x05 && version
[6] == 0x15 )
666 tagtype
= NTAG_I2C_2K
;
667 else if ( version
[2] == 0x04 )
672 case 0x01: tagtype
= UL_C
; break;
673 case 0x00: tagtype
= UL
; break;
674 case -1 : tagtype
= (UL
| UL_C
| NTAG_203
); break; // could be UL | UL_C magic tags
675 default : tagtype
= UNKNOWN
; break;
677 // UL vs UL-C vs ntag203 test
678 if (tagtype
& (UL
| UL_C
| NTAG_203
)) {
679 if ( !ul_select(&card
) ) return UL_ERROR
;
681 // do UL_C check first...
682 uint8_t nonce
[11] = {0x00};
683 status
= ulc_requestAuthentication(nonce
, sizeof(nonce
));
684 ul_switch_off_field();
688 // need to re-select after authentication error
689 if ( !ul_select(&card
) ) return UL_ERROR
;
691 uint8_t data
[16] = {0x00};
692 // read page 0x26-0x29 (last valid ntag203 page)
693 status
= ul_read(0x26, data
, sizeof(data
));
697 // read page 0x30 (should error if it is a ntag203)
698 status
= ul_read(0x30, data
, sizeof(data
));
705 ul_switch_off_field();
709 tagtype
= ul_fudan_check();
710 ul_switch_off_field();
713 ul_switch_off_field();
714 // Infinition MY-D tests Exam high nibble
715 uint8_t nib
= (card
.uid
[1] & 0xf0) >> 4;
717 // case 0: tagtype = SLE66R35E7; break; //or SLE 66R35E7 - mifare compat... should have different sak/atqa for mf 1k
718 case 1: tagtype
= MY_D
; break; //or SLE 66RxxS ... up to 512 pages of 8 user bytes...
719 case 2: tagtype
= (MY_D_NFC
); break; //or SLE 66RxxP ... up to 512 pages of 8 user bytes... (or in nfc mode FF pages of 4 bytes)
720 case 3: tagtype
= (MY_D_MOVE
| MY_D_MOVE_NFC
); break; //or SLE 66R01P // 38 pages of 4 bytes //notice: we can not currently distinguish between these two
721 case 7: tagtype
= MY_D_MOVE_LEAN
; break; //or SLE 66R01L // 16 pages of 4 bytes
725 tagtype
|= ul_magic_test();
726 if (tagtype
== (UNKNOWN
| MAGIC
)) tagtype
= (UL_MAGIC
);
730 int CmdHF14AMfUInfo(const char *Cmd
){
732 uint8_t authlim
= 0xff;
733 uint8_t data
[16] = {0x00};
734 iso14a_card_select_t card
;
737 bool hasAuthKey
= false;
739 bool swapEndian
= false;
742 uint8_t authenticationkey
[16] = {0x00};
743 uint8_t *authkeyptr
= authenticationkey
;
744 uint8_t pwd
[4] = {0,0,0,0};
746 uint8_t pack
[4] = {0,0,0,0};
750 while(param_getchar(Cmd
, cmdp
) != 0x00)
752 switch(param_getchar(Cmd
, cmdp
))
756 return usage_hf_mfu_info();
759 dataLen
= param_getstr(Cmd
, cmdp
+1, tempStr
);
760 if (dataLen
== 32 || dataLen
== 8) { //ul-c or ev1/ntag key length
761 errors
= param_gethex(tempStr
, 0, authenticationkey
, dataLen
);
762 dataLen
/= 2; // handled as bytes from now on
764 PrintAndLog("\nERROR: Key is incorrect length\n");
776 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
784 if(errors
) return usage_hf_mfu_info();
786 TagTypeUL_t tagtype
= GetHF14AMfU_Type();
787 if (tagtype
== UL_ERROR
) return -1;
789 PrintAndLog("\n--- Tag Information ---------");
790 PrintAndLog("-------------------------------------------------------------");
791 ul_print_type(tagtype
, 6);
794 if (swapEndian
&& hasAuthKey
) authkeyptr
= SwapEndian64(authenticationkey
, dataLen
, (dataLen
== 16) ? 8 : 4 );
796 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
798 // read pages 0,1,2,3 (should read 4pages)
799 status
= ul_read(0, data
, sizeof(data
));
800 if ( status
== -1 ) {
801 ul_switch_off_field();
802 PrintAndLog("Error: tag didn't answer to READ");
804 } else if (status
== 16) {
805 ul_print_default(data
);
806 ndef_print_CC(data
+12);
812 if ((tagtype
& UL_C
)) {
814 // read pages 0x28, 0x29, 0x2A, 0x2B
815 uint8_t ulc_conf
[16] = {0x00};
816 status
= ul_read(0x28, ulc_conf
, sizeof(ulc_conf
));
818 PrintAndLog("Error: tag didn't answer to READ UL-C");
819 ul_switch_off_field();
822 if (status
== 16) ulc_print_configuration(ulc_conf
);
825 if ((tagtype
& MAGIC
)) {
827 uint8_t ulc_deskey
[16] = {0x00};
828 status
= ul_read(0x2C, ulc_deskey
, sizeof(ulc_deskey
));
829 if ( status
== -1 ) {
830 ul_switch_off_field();
831 PrintAndLog("Error: tag didn't answer to READ magic");
834 if (status
== 16) ulc_print_3deskey(ulc_deskey
);
837 ul_switch_off_field();
838 // if we called info with key, just return
839 if ( hasAuthKey
) return 1;
841 // also try to diversify default keys.. look into CmdHF14AMfuGenDiverseKeys
842 PrintAndLog("Trying some default 3des keys");
843 for (uint8_t i
= 0; i
< KEYS_3DES_COUNT
; ++i
) {
844 key
= default_3des_keys
[i
];
845 if (ulc_authentication(key
, true)) {
846 PrintAndLog("Found default 3des key: ");
848 memcpy(keySwap
, SwapEndian64(key
,16,8), 16);
849 ulc_print_3deskey(keySwap
);
857 // do counters and signature first (don't neet auth)
859 // ul counters are different than ntag counters
860 if ((tagtype
& (UL_EV1_48
| UL_EV1_128
))) {
861 if (ulev1_print_counters() != 3) {
862 // failed - re-select
863 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
868 if ((tagtype
& (UL_EV1_48
| UL_EV1_128
| NTAG_213
| NTAG_215
| NTAG_216
| NTAG_I2C_1K
| NTAG_I2C_2K
))) {
869 uint8_t ulev1_signature
[32] = {0x00};
870 status
= ulev1_readSignature( ulev1_signature
, sizeof(ulev1_signature
));
871 if ( status
== -1 ) {
872 PrintAndLog("Error: tag didn't answer to READ SIGNATURE");
873 ul_switch_off_field();
876 if (status
== 32) ulev1_print_signature( ulev1_signature
, sizeof(ulev1_signature
));
879 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
884 if ((tagtype
& (UL_EV1_48
| UL_EV1_128
| NTAG_210
| NTAG_212
| NTAG_213
| NTAG_215
| NTAG_216
| NTAG_I2C_1K
| NTAG_I2C_2K
))) {
885 uint8_t version
[10] = {0x00};
886 status
= ulev1_getVersion(version
, sizeof(version
));
887 if ( status
== -1 ) {
888 PrintAndLog("Error: tag didn't answer to GETVERSION");
889 ul_switch_off_field();
891 } else if (status
== 10) {
892 ulev1_print_version(version
);
895 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
898 uint8_t startconfigblock
= 0;
899 uint8_t ulev1_conf
[16] = {0x00};
900 // config blocks always are last 4 pages
901 for (uint8_t idx
= 0; idx
< MAX_UL_TYPES
; idx
++)
902 if (tagtype
& UL_TYPES_ARRAY
[idx
])
903 startconfigblock
= UL_MEMORY_ARRAY
[idx
]-3;
905 if (startconfigblock
){ // if we know where the config block is...
906 status
= ul_read(startconfigblock
, ulev1_conf
, sizeof(ulev1_conf
));
907 if ( status
== -1 ) {
908 PrintAndLog("Error: tag didn't answer to READ EV1");
909 ul_switch_off_field();
911 } else if (status
== 16) {
912 // save AUTHENTICATION LIMITS for later:
913 authlim
= (ulev1_conf
[4] & 0x07);
914 ulev1_print_configuration(ulev1_conf
, startconfigblock
);
918 // AUTHLIMIT, (number of failed authentications)
920 // 1-7 = limit. No automatic tries then.
921 // hasAuthKey, if we was called with key, skip test.
922 if ( !authlim
&& !hasAuthKey
) {
923 PrintAndLog("\n--- Known EV1/NTAG passwords.");
927 num_to_bytes( ul_ev1_pwdgenA(card
.uid
), 4, key
);
928 len
= ulev1_requestAuthentication(key
, pack
, sizeof(pack
));
930 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key
, 4), pack
[0], pack
[1]);
932 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
935 num_to_bytes( ul_ev1_pwdgenB(card
.uid
), 4, key
);
936 len
= ulev1_requestAuthentication(key
, pack
, sizeof(pack
));
938 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key
, 4), pack
[0], pack
[1]);
940 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
943 num_to_bytes( ul_ev1_pwdgenC(card
.uid
), 4, key
);
944 len
= ulev1_requestAuthentication(key
, pack
, sizeof(pack
));
946 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key
, 4), pack
[0], pack
[1]);
948 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
950 for (uint8_t i
= 0; i
< KEYS_PWD_COUNT
; ++i
) {
951 key
= default_pwd_pack
[i
];
952 len
= ulev1_requestAuthentication(key
, pack
, sizeof(pack
));
954 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key
, 4), pack
[0], pack
[1]);
957 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
960 if (len
< 1) PrintAndLog("password not known");
964 ul_switch_off_field();
965 if (locked
) PrintAndLog("\nTag appears to be locked, try using the key to get more info");
971 // Write Single Block
973 int CmdHF14AMfUWrBl(const char *Cmd
){
977 bool hasAuthKey
= false;
978 bool hasPwdKey
= false;
979 bool swapEndian
= false;
983 uint8_t blockdata
[20] = {0x00};
984 uint8_t data
[16] = {0x00};
985 uint8_t authenticationkey
[16] = {0x00};
986 uint8_t *authKeyPtr
= authenticationkey
;
988 while(param_getchar(Cmd
, cmdp
) != 0x00)
990 switch(param_getchar(Cmd
, cmdp
))
994 return usage_hf_mfu_wrbl();
998 keylen
= param_gethex(Cmd
, cmdp
+1, data
, 8);
1000 memcpy(authenticationkey
, data
, 4);
1006 keylen
= param_gethex(Cmd
, cmdp
+1, data
, 32);
1008 memcpy(authenticationkey
, data
, 16);
1013 PrintAndLog("\nERROR: Key is incorrect length\n");
1018 blockNo
= param_get8(Cmd
, cmdp
+1);
1020 PrintAndLog("Wrong block number");
1032 if ( param_gethex(Cmd
, cmdp
+1, blockdata
, 8) ) {
1033 PrintAndLog("Block data must include 8 HEX symbols");
1040 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
1045 if(errors
) return usage_hf_mfu_wrbl();
1048 if ( blockNo
== -1 ) return usage_hf_mfu_wrbl();
1049 // starting with getting tagtype
1050 TagTypeUL_t tagtype
= GetHF14AMfU_Type();
1051 if (tagtype
== UL_ERROR
) return -1;
1053 uint8_t maxblockno
= 0;
1054 for (uint8_t idx
= 0; idx
< MAX_UL_TYPES
; idx
++){
1055 if (tagtype
& UL_TYPES_ARRAY
[idx
])
1056 maxblockno
= UL_MEMORY_ARRAY
[idx
];
1058 if (blockNo
> maxblockno
){
1059 PrintAndLog("block number too large. Max block is %u/0x%02X \n", maxblockno
,maxblockno
);
1060 return usage_hf_mfu_wrbl();
1064 if (swapEndian
&& hasAuthKey
) authKeyPtr
= SwapEndian64(authenticationkey
, 16, 8);
1065 if (swapEndian
&& hasPwdKey
) authKeyPtr
= SwapEndian64(authenticationkey
, 4, 4);
1068 PrintAndLog("Special Block: %0d (0x%02X) [ %s]", blockNo
, blockNo
, sprint_hex(blockdata
, 4));
1070 PrintAndLog("Block: %0d (0x%02X) [ %s]", blockNo
, blockNo
, sprint_hex(blockdata
, 4));
1073 UsbCommand c
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1074 memcpy(c
.d
.asBytes
,blockdata
,4);
1078 memcpy(c
.d
.asBytes
+4,authKeyPtr
,16);
1080 else if ( hasPwdKey
) {
1082 memcpy(c
.d
.asBytes
+4,authKeyPtr
,4);
1085 clearCommandBuffer();
1088 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1089 uint8_t isOK
= resp
.arg
[0] & 0xff;
1090 PrintAndLog("isOk:%02x", isOK
);
1092 PrintAndLog("Command execute timeout");
1098 // Read Single Block
1100 int CmdHF14AMfURdBl(const char *Cmd
){
1103 bool errors
= false;
1104 bool hasAuthKey
= false;
1105 bool hasPwdKey
= false;
1106 bool swapEndian
= false;
1109 uint8_t data
[16] = {0x00};
1110 uint8_t authenticationkey
[16] = {0x00};
1111 uint8_t *authKeyPtr
= authenticationkey
;
1113 while(param_getchar(Cmd
, cmdp
) != 0x00)
1115 switch(param_getchar(Cmd
, cmdp
))
1119 return usage_hf_mfu_rdbl();
1122 // EV1/NTAG size key
1123 keylen
= param_gethex(Cmd
, cmdp
+1, data
, 8);
1125 memcpy(authenticationkey
, data
, 4);
1131 keylen
= param_gethex(Cmd
, cmdp
+1, data
, 32);
1133 memcpy(authenticationkey
, data
, 16);
1138 PrintAndLog("\nERROR: Key is incorrect length\n");
1143 blockNo
= param_get8(Cmd
, cmdp
+1);
1145 PrintAndLog("Wrong block number");
1156 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
1161 if(errors
) return usage_hf_mfu_rdbl();
1164 if ( blockNo
== -1 ) return usage_hf_mfu_rdbl();
1165 // start with getting tagtype
1166 TagTypeUL_t tagtype
= GetHF14AMfU_Type();
1167 if (tagtype
== UL_ERROR
) return -1;
1169 uint8_t maxblockno
= 0;
1170 for (uint8_t idx
= 0; idx
< MAX_UL_TYPES
; idx
++){
1171 if (tagtype
& UL_TYPES_ARRAY
[idx
])
1172 maxblockno
= UL_MEMORY_ARRAY
[idx
];
1174 if (blockNo
> maxblockno
){
1175 PrintAndLog("block number to large. Max block is %u/0x%02X \n", maxblockno
,maxblockno
);
1176 return usage_hf_mfu_rdbl();
1180 if (swapEndian
&& hasAuthKey
) authKeyPtr
= SwapEndian64(authenticationkey
, 16, 8);
1181 if (swapEndian
&& hasPwdKey
) authKeyPtr
= SwapEndian64(authenticationkey
, 4, 4);
1184 UsbCommand c
= {CMD_MIFAREU_READBL
, {blockNo
}};
1187 memcpy(c
.d
.asBytes
,authKeyPtr
,16);
1189 else if ( hasPwdKey
) {
1191 memcpy(c
.d
.asBytes
,authKeyPtr
,4);
1194 clearCommandBuffer();
1197 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1198 uint8_t isOK
= resp
.arg
[0] & 0xff;
1200 uint8_t *data
= resp
.d
.asBytes
;
1201 PrintAndLog("\nBlock# | Data | Ascii");
1202 PrintAndLog("-----------------------------");
1203 PrintAndLog("%02d/0x%02X | %s| %.4s\n", blockNo
, blockNo
, sprint_hex(data
, 4), data
);
1206 PrintAndLog("Failed reading block: (%02x)", isOK
);
1209 PrintAndLog("Command execute time-out");
1214 int usage_hf_mfu_info(void) {
1215 PrintAndLog("It gathers information about the tag and tries to detect what kind it is.");
1216 PrintAndLog("Sometimes the tags are locked down, and you may need a key to be able to read the information");
1217 PrintAndLog("The following tags can be identified:\n");
1218 PrintAndLog("Ultralight, Ultralight-C, Ultralight EV1, NTAG 203, NTAG 210,");
1219 PrintAndLog("NTAG 212, NTAG 213, NTAG 215, NTAG 216, NTAG I2C 1K & 2K");
1220 PrintAndLog("my-d, my-d NFC, my-d move, my-d move NFC\n");
1221 PrintAndLog("Usage: hf mfu info k <key> l");
1222 PrintAndLog(" Options : ");
1223 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1224 PrintAndLog(" l : (optional) swap entered key's endianness");
1226 PrintAndLog(" sample : hf mfu info");
1227 PrintAndLog(" : hf mfu info k 00112233445566778899AABBCCDDEEFF");
1228 PrintAndLog(" : hf mfu info k AABBCCDDD");
1232 int usage_hf_mfu_dump(void) {
1233 PrintAndLog("Reads all pages from Ultralight, Ultralight-C, Ultralight EV1");
1234 PrintAndLog("NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216");
1235 PrintAndLog("and saves binary dump into the file `filename.bin` or `cardUID.bin`");
1236 PrintAndLog("It autodetects card type.\n");
1237 PrintAndLog("Usage: hf mfu dump k <key> l n <filename w/o .bin> p <page#> q <#pages>");
1238 PrintAndLog(" Options :");
1239 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1240 PrintAndLog(" l : (optional) swap entered key's endianness");
1241 PrintAndLog(" n <FN > : filename w/o .bin to save the dump as");
1242 PrintAndLog(" p <Pg > : starting Page number to manually set a page to start the dump at");
1243 PrintAndLog(" q <qty> : number of Pages to manually set how many pages to dump");
1245 PrintAndLog(" sample : hf mfu dump");
1246 PrintAndLog(" : hf mfu dump n myfile");
1247 PrintAndLog(" : hf mfu dump k 00112233445566778899AABBCCDDEEFF");
1248 PrintAndLog(" : hf mfu dump k AABBCCDDD\n");
1252 int usage_hf_mfu_rdbl(void) {
1253 PrintAndLog("Read a block and print. It autodetects card type.\n");
1254 PrintAndLog("Usage: hf mfu rdbl b <block number> k <key> l\n");
1255 PrintAndLog(" Options:");
1256 PrintAndLog(" b <no> : block to read");
1257 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1258 PrintAndLog(" l : (optional) swap entered key's endianness");
1260 PrintAndLog(" sample : hf mfu rdbl b 0");
1261 PrintAndLog(" : hf mfu rdbl b 0 k 00112233445566778899AABBCCDDEEFF");
1262 PrintAndLog(" : hf mfu rdbl b 0 k AABBCCDDD\n");
1266 int usage_hf_mfu_wrbl(void) {
1267 PrintAndLog("Write a block. It autodetects card type.\n");
1268 PrintAndLog("Usage: hf mfu wrbl b <block number> d <data> k <key> l\n");
1269 PrintAndLog(" Options:");
1270 PrintAndLog(" b <no> : block to write");
1271 PrintAndLog(" d <data> : block data - (8 hex symbols)");
1272 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1273 PrintAndLog(" l : (optional) swap entered key's endianness");
1275 PrintAndLog(" sample : hf mfu wrbl b 0 d 01234567");
1276 PrintAndLog(" : hf mfu wrbl b 0 d 01234567 k AABBCCDDD\n");
1280 int usage_hf_mfu_eload(void) {
1281 PrintAndLog("It loads emul dump from the file `filename.eml`");
1282 PrintAndLog("Hint: See script dumptoemul-mfu.lua to convert the .bin to the eml");
1283 PrintAndLog("Usage: hf mfu eload u <file name w/o `.eml`> [numblocks]");
1284 PrintAndLog(" Options:");
1285 PrintAndLog(" h : this help");
1286 PrintAndLog(" u : UL (required)");
1287 PrintAndLog(" [filename] : without `.eml` (required)");
1288 PrintAndLog(" numblocks : number of blocks to load from eml file (optional)");
1290 PrintAndLog(" sample: hf mfu eload u filename");
1291 PrintAndLog(" hf mfu eload u filename 57");
1295 int usage_hf_mfu_sim(void) {
1296 PrintAndLog("\nEmulating Ultralight tag from emulator memory\n");
1297 PrintAndLog("\nBe sure to load the emulator memory first!\n");
1298 PrintAndLog("Usage: hf mfu sim t 7 u <uid>");
1299 PrintAndLog(" Options:");
1300 PrintAndLog(" h : this help");
1301 PrintAndLog(" t 7 : 7 = NTAG or Ultralight sim (required)");
1302 PrintAndLog(" u <uid> : 4 or 7 byte UID (optional)");
1303 PrintAndLog("\n sample : hf mfu sim t 7");
1304 PrintAndLog(" : hf mfu sim t 7 u 1122344556677\n");
1309 int usage_hf_mfu_ucauth(void) {
1310 PrintAndLog("Usage: hf mfu cauth k <key number>");
1311 PrintAndLog(" 0 (default): 3DES standard key");
1312 PrintAndLog(" 1 : all 0x00 key");
1313 PrintAndLog(" 2 : 0x00-0x0F key");
1314 PrintAndLog(" 3 : nfc key");
1315 PrintAndLog(" 4 : all 0x01 key");
1316 PrintAndLog(" 5 : all 0xff key");
1317 PrintAndLog(" 6 : 0x00-0xFF key");
1318 PrintAndLog("\n sample : hf mfu cauth k");
1319 PrintAndLog(" : hf mfu cauth k 3");
1323 int usage_hf_mfu_ucsetpwd(void) {
1324 PrintAndLog("Usage: hf mfu setpwd <password (32 hex symbols)>");
1325 PrintAndLog(" [password] - (32 hex symbols)");
1327 PrintAndLog("sample: hf mfu setpwd 000102030405060708090a0b0c0d0e0f");
1332 int usage_hf_mfu_ucsetuid(void) {
1333 PrintAndLog("Usage: hf mfu setuid <uid (14 hex symbols)>");
1334 PrintAndLog(" [uid] - (14 hex symbols)");
1335 PrintAndLog("\nThis only works for Magic Ultralight tags.");
1337 PrintAndLog("sample: hf mfu setuid 11223344556677");
1342 int usage_hf_mfu_gendiverse(void){
1343 PrintAndLog("Usage: hf mfu gen <uid (8 hex symbols)>");
1345 PrintAndLog("sample: hf mfu gen 11223344");
1350 #define DUMP_PREFIX_LENGTH 48
1352 // Mifare Ultralight / Ultralight-C / Ultralight-EV1
1353 // Read and Dump Card Contents, using auto detection of tag size.
1354 int CmdHF14AMfUDump(const char *Cmd
){
1357 char filename
[FILE_PATH_SIZE
] = {0x00};
1358 char *fnameptr
= filename
;
1359 uint8_t *lockbytes_t
= NULL
;
1360 uint8_t lockbytes
[2] = {0x00};
1361 uint8_t *lockbytes_t2
= NULL
;
1362 uint8_t lockbytes2
[2] = {0x00};
1363 bool bit
[16] = {0x00};
1364 bool bit2
[16] = {0x00};
1365 uint8_t data
[1024] = {0x00};
1366 bool hasAuthKey
= false;
1369 bool tmplockbit
= false;
1370 uint8_t dataLen
= 0;
1372 uint8_t authenticationkey
[16] = {0x00};
1373 memset(authenticationkey
, 0x00, sizeof(authenticationkey
));
1374 uint8_t *authKeyPtr
= authenticationkey
;
1375 size_t fileNlen
= 0;
1376 bool errors
= false;
1377 bool swapEndian
= false;
1378 bool manualPages
= false;
1379 uint8_t startPage
= 0;
1382 while(param_getchar(Cmd
, cmdp
) != 0x00)
1384 switch(param_getchar(Cmd
, cmdp
))
1388 return usage_hf_mfu_dump();
1391 dataLen
= param_getstr(Cmd
, cmdp
+1, tempStr
);
1392 if (dataLen
== 32 || dataLen
== 8) { //ul-c or ev1/ntag key length
1393 errors
= param_gethex(tempStr
, 0, authenticationkey
, dataLen
);
1396 PrintAndLog("\nERROR: Key is incorrect length\n");
1409 fileNlen
= param_getstr(Cmd
, cmdp
+1, filename
);
1410 if (!fileNlen
) errors
= true;
1411 if (fileNlen
> FILE_PATH_SIZE
-5) fileNlen
= FILE_PATH_SIZE
-5;
1415 case 'P': //set start page
1416 startPage
= param_get8(Cmd
, cmdp
+1);
1422 Pages
= param_get8(Cmd
, cmdp
+1);
1427 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
1435 if(errors
) return usage_hf_mfu_dump();
1437 //if we entered a key in little endian and set the swapEndian switch - switch it...
1438 if (swapEndian
&& hasAuthKey
)
1439 authKeyPtr
= SwapEndian64(authenticationkey
, dataLen
, (dataLen
== 16) ? 8 : 4);
1441 TagTypeUL_t tagtype
= GetHF14AMfU_Type();
1442 if (tagtype
== UL_ERROR
) return -1;
1444 if (!manualPages
) //get number of pages to read
1445 for (uint8_t idx
= 0; idx
< MAX_UL_TYPES
; idx
++)
1446 if (tagtype
& UL_TYPES_ARRAY
[idx
])
1447 Pages
= UL_MEMORY_ARRAY
[idx
]+1; //add one as maxblks starts at 0
1449 ul_print_type(tagtype
, 0);
1450 PrintAndLog("Reading tag memory...");
1451 UsbCommand c
= {CMD_MIFAREU_READCARD
, {startPage
,Pages
}};
1454 c
.arg
[2] = 1; //UL_C auth
1456 c
.arg
[2] = 2; //UL_EV1/NTAG auth
1458 memcpy(c
.d
.asBytes
, authKeyPtr
, dataLen
);
1461 clearCommandBuffer();
1464 if (!WaitForResponseTimeout(CMD_ACK
, &resp
,1500)) {
1465 PrintAndLog("Command execute time-out");
1468 if (resp
.arg
[0] != 1) {
1469 PrintAndLog("Failed reading block: (%02x)", i
);
1473 uint32_t startindex
= resp
.arg
[2];
1474 uint32_t bufferSize
= resp
.arg
[1];
1475 if (bufferSize
> sizeof(data
)) {
1476 PrintAndLog("Data exceeded Buffer size!");
1477 bufferSize
= sizeof(data
);
1479 GetFromBigBuf(data
, bufferSize
, startindex
);
1480 WaitForResponse(CMD_ACK
,NULL
);
1482 Pages
= bufferSize
/4;
1486 lockbytes_t
= data
+ 8;
1487 lockbytes
[0] = lockbytes_t
[2];
1488 lockbytes
[1] = lockbytes_t
[3];
1489 for(j
= 0; j
< 16; j
++){
1490 bit
[j
] = lockbytes
[j
/8] & ( 1 <<(7-j
%8));
1493 // Load bottom lockbytes if available
1494 // TODO -- FIGURE OUT LOCK BYTES FOR TO EV1 and/or NTAG
1495 if ( Pages
== 44 ) {
1496 lockbytes_t2
= data
+ (40*4);
1497 lockbytes2
[0] = lockbytes_t2
[2];
1498 lockbytes2
[1] = lockbytes_t2
[3];
1499 for (j
= 0; j
< 16; j
++) {
1500 bit2
[j
] = lockbytes2
[j
/8] & ( 1 <<(7-j
%8));
1504 uint8_t get_pack
[] = {0,0};
1505 iso14a_card_select_t card
;
1506 uint8_t dump_file_data
[1024+DUMP_PREFIX_LENGTH
] = {0x00};
1507 uint8_t get_version
[] = {0,0,0,0,0,0,0,0,0};
1508 uint8_t get_tearing
[] = {0,0,0};
1509 uint8_t get_counter
[] = {0,0,0};
1510 uint8_t dummy_pack
[] = {0,0};
1511 uint8_t get_signature
[32];
1512 memset( get_signature
, 0, sizeof(get_signature
) );
1514 // not ul_c and not std ul then attempt to get deeper info
1515 if (!(tagtype
& UL_C
|| tagtype
& UL
)) {
1516 //attempt to read pack
1517 if (!ul_auth_select( &card
, tagtype
, true, authKeyPtr
, get_pack
, sizeof(get_pack
))) {
1522 ul_switch_off_field();
1523 // add pack to block read
1524 memcpy(data
+ (Pages
*4) - 4, get_pack
, sizeof(get_pack
));
1526 ul_auth_select( &card
, tagtype
, hasAuthKey
, authKeyPtr
, dummy_pack
, sizeof(dummy_pack
));
1530 ulev1_getVersion( get_version
, sizeof(get_version
) );
1531 for ( uint8_t i
= 0; i
<3; ++i
) {
1532 ulev1_readTearing(i
, get_tearing
+i
, 1);
1533 ulev1_readCounter(i
, get_counter
, sizeof(get_counter
) );
1535 ul_switch_off_field();
1537 ul_auth_select( &card
, tagtype
, hasAuthKey
, authKeyPtr
, dummy_pack
, sizeof(dummy_pack
));
1540 ulev1_readSignature( get_signature
, sizeof(get_signature
));
1541 ul_switch_off_field();
1544 // format and add keys to block dump output
1546 // if we didn't swapendian before - do it now for the sprint_hex call
1547 // NOTE: default entry is bigendian (unless swapped), sprint_hex outputs little endian
1548 // need to swap to keep it the same
1550 authKeyPtr
= SwapEndian64(authenticationkey
, dataLen
, (dataLen
== 16) ? 8 : 4);
1552 authKeyPtr
= authenticationkey
;
1555 if (tagtype
& UL_C
){ //add 4 pages
1556 memcpy(data
+ Pages
*4, authKeyPtr
, dataLen
);
1558 } else { // 2nd page from end
1559 memcpy(data
+ (Pages
*4) - 8, authenticationkey
, dataLen
);
1563 //add *special* blocks to dump
1565 memcpy(dump_file_data
, get_version
, sizeof(get_version
));
1567 memcpy(dump_file_data
+10, get_tearing
, sizeof(get_tearing
));
1569 memcpy(dump_file_data
+13, get_pack
, sizeof(get_pack
));
1571 memcpy(dump_file_data
+16, get_signature
, sizeof(get_signature
));
1572 //add regular block read data to dump
1573 memcpy(dump_file_data
+DUMP_PREFIX_LENGTH
, data
, Pages
*4);
1575 PrintAndLog("\n*Special* block data:");
1576 PrintAndLog("\nDataType| Data | | Ascii");
1577 PrintAndLog("---------------------------------");
1578 PrintAndLog("GetVer-1| %s| | %.4s", sprint_hex(dump_file_data
, 4), dump_file_data
);
1579 PrintAndLog("GetVer-2| %s| | %.4s", sprint_hex(dump_file_data
+4, 4), dump_file_data
+4);
1580 PrintAndLog("TBD | 00 00 | | ");
1581 PrintAndLog("Tearing | %s| | %.3s", sprint_hex(dump_file_data
+10, 3), dump_file_data
+10);
1582 PrintAndLog("Pack | %s | | %.2s", sprint_hex(dump_file_data
+13, 2), dump_file_data
+13);
1583 PrintAndLog("TBD | 00 | | ");
1584 PrintAndLog("Sig-1 | %s| | %.4s", sprint_hex(dump_file_data
+16, 4), dump_file_data
+16);
1585 PrintAndLog("Sig-2 | %s| | %.4s", sprint_hex(dump_file_data
+20, 4), dump_file_data
+20);
1586 PrintAndLog("Sig-3 | %s| | %.4s", sprint_hex(dump_file_data
+24, 4), dump_file_data
+24);
1587 PrintAndLog("Sig-4 | %s| | %.4s", sprint_hex(dump_file_data
+28, 4), dump_file_data
+28);
1588 PrintAndLog("Sig-5 | %s| | %.4s", sprint_hex(dump_file_data
+32, 4), dump_file_data
+32);
1589 PrintAndLog("Sig-6 | %s| | %.4s", sprint_hex(dump_file_data
+36, 4), dump_file_data
+36);
1590 PrintAndLog("Sig-7 | %s| | %.4s", sprint_hex(dump_file_data
+40, 4), dump_file_data
+40);
1591 PrintAndLog("Sig-8 | %s| | %.4s", sprint_hex(dump_file_data
+44, 4), dump_file_data
+44);
1592 PrintAndLog("\nBlock# | Data |lck| Ascii");
1593 PrintAndLog("---------------------------------");
1594 for (i
= 0; i
< Pages
; ++i
) {
1596 PrintAndLog("%02d/0x%02X | %s| | ", i
+startPage
, i
+startPage
, sprint_hex(data
+ i
* 4, 4));
1600 case 3: tmplockbit
= bit
[4]; break;
1601 case 4: tmplockbit
= bit
[3]; break;
1602 case 5: tmplockbit
= bit
[2]; break;
1603 case 6: tmplockbit
= bit
[1]; break;
1604 case 7: tmplockbit
= bit
[0]; break;
1605 case 8: tmplockbit
= bit
[15]; break;
1606 case 9: tmplockbit
= bit
[14]; break;
1607 case 10: tmplockbit
= bit
[13]; break;
1608 case 11: tmplockbit
= bit
[12]; break;
1609 case 12: tmplockbit
= bit
[11]; break;
1610 case 13: tmplockbit
= bit
[10]; break;
1611 case 14: tmplockbit
= bit
[9]; break;
1612 case 15: tmplockbit
= bit
[8]; break;
1616 case 19: tmplockbit
= bit2
[6]; break;
1620 case 23: tmplockbit
= bit2
[5]; break;
1624 case 27: tmplockbit
= bit2
[4]; break;
1628 case 31: tmplockbit
= bit2
[2]; break;
1632 case 35: tmplockbit
= bit2
[1]; break;
1636 case 39: tmplockbit
= bit2
[0]; break;
1637 case 40: tmplockbit
= bit2
[12]; break;
1638 case 41: tmplockbit
= bit2
[11]; break;
1639 case 42: tmplockbit
= bit2
[10]; break; //auth0
1640 case 43: tmplockbit
= bit2
[9]; break; //auth1
1643 PrintAndLog("%02d/0x%02X | %s| %d | %.4s", i
+startPage
, i
+startPage
, sprint_hex(data
+ i
* 4, 4), tmplockbit
, data
+i
*4);
1645 PrintAndLog("---------------------------------");
1647 // user supplied filename?
1649 // UID = data 0-1-2 4-5-6-7 (skips a beat)
1650 sprintf(fnameptr
,"%02X%02X%02X%02X%02X%02X%02X.bin",
1651 data
[0],data
[1], data
[2], data
[4],data
[5],data
[6], data
[7]);
1653 sprintf(fnameptr
+ fileNlen
,".bin");
1656 if ((fout
= fopen(filename
,"wb")) == NULL
) {
1657 PrintAndLog("Could not create file name %s", filename
);
1660 fwrite( dump_file_data
, 1, Pages
*4 + DUMP_PREFIX_LENGTH
, fout
);
1663 PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages
+(DUMP_PREFIX_LENGTH
/4), Pages
*4 + DUMP_PREFIX_LENGTH
, filename
);
1667 //-------------------------------------------------------------------------------
1668 // Ultralight C Methods
1669 //-------------------------------------------------------------------------------
1672 // Ultralight C Authentication Demo {currently uses hard-coded key}
1674 int CmdHF14AMfucAuth(const char *Cmd
){
1677 bool errors
= false;
1679 char cmdp
= param_getchar(Cmd
, 0);
1681 //Change key to user defined one
1682 if (cmdp
== 'k' || cmdp
== 'K'){
1683 keyNo
= param_get8(Cmd
, 1);
1684 if(keyNo
> KEYS_3DES_COUNT
)
1688 if (cmdp
== 'h' || cmdp
== 'H') errors
= true;
1690 if (errors
) return usage_hf_mfu_ucauth();
1692 uint8_t *key
= default_3des_keys
[keyNo
];
1693 if (ulc_authentication(key
, true))
1694 PrintAndLog("Authentication successful. 3des key: %s",sprint_hex(key
, 16));
1696 PrintAndLog("Authentication failed");
1702 A test function to validate that the polarssl-function works the same
1703 was as the openssl-implementation.
1704 Commented out, since it requires openssl
1706 int CmdTestDES(const char * cmd)
1708 uint8_t key[16] = {0x00};
1710 memcpy(key,key3_3des_data,16);
1711 DES_cblock RndA, RndB;
1713 PrintAndLog("----------OpenSSL DES implementation----------");
1715 uint8_t e_RndB[8] = {0x00};
1716 unsigned char RndARndB[16] = {0x00};
1718 DES_cblock iv = { 0 };
1719 DES_key_schedule ks1,ks2;
1720 DES_cblock key1,key2;
1722 memcpy(key,key3_3des_data,16);
1724 memcpy(key2,key+8,8);
1727 DES_set_key((DES_cblock *)key1,&ks1);
1728 DES_set_key((DES_cblock *)key2,&ks2);
1730 DES_random_key(&RndA);
1731 PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
1732 PrintAndLog(" e_RndB:%s",sprint_hex(e_RndB, 8));
1733 //void DES_ede2_cbc_encrypt(const unsigned char *input,
1734 // unsigned char *output, long length, DES_key_schedule *ks1,
1735 // DES_key_schedule *ks2, DES_cblock *ivec, int enc);
1736 DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
1738 PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
1740 memcpy(RndARndB,RndA,8);
1741 memcpy(RndARndB+8,RndB,8);
1742 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
1743 DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
1744 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
1747 PrintAndLog("----------PolarSSL implementation----------");
1749 uint8_t random_a[8] = { 0 };
1750 uint8_t enc_random_a[8] = { 0 };
1751 uint8_t random_b[8] = { 0 };
1752 uint8_t enc_random_b[8] = { 0 };
1753 uint8_t random_a_and_b[16] = { 0 };
1754 des3_context ctx = { 0 };
1756 memcpy(random_a, RndA,8);
1758 uint8_t output[8] = { 0 };
1759 uint8_t iv[8] = { 0 };
1761 PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
1762 PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
1764 des3_set2key_dec(&ctx, key);
1766 des3_crypt_cbc(&ctx // des3_context *ctx
1767 , DES_DECRYPT // int mode
1768 , sizeof(random_b) // size_t length
1769 , iv // unsigned char iv[8]
1770 , enc_random_b // const unsigned char *input
1771 , random_b // unsigned char *output
1774 PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
1777 memcpy(random_a_and_b ,random_a,8);
1778 memcpy(random_a_and_b+8,random_b,8);
1780 PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
1782 des3_set2key_enc(&ctx, key);
1784 des3_crypt_cbc(&ctx // des3_context *ctx
1785 , DES_ENCRYPT // int mode
1786 , sizeof(random_a_and_b) // size_t length
1787 , enc_random_b // unsigned char iv[8]
1788 , random_a_and_b // const unsigned char *input
1789 , random_a_and_b // unsigned char *output
1792 PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
1799 // Mifare Ultralight C - Set password
1801 int CmdHF14AMfucSetPwd(const char *Cmd
){
1803 uint8_t pwd
[16] = {0x00};
1804 char cmdp
= param_getchar(Cmd
, 0);
1806 if (strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_mfu_ucsetpwd();
1808 if (param_gethex(Cmd
, 0, pwd
, 32)) {
1809 PrintAndLog("Password must include 32 HEX symbols");
1813 UsbCommand c
= {CMD_MIFAREUC_SETPWD
};
1814 memcpy( c
.d
.asBytes
, pwd
, 16);
1815 clearCommandBuffer();
1819 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500) ) {
1820 if ( (resp
.arg
[0] & 0xff) == 1) {
1821 PrintAndLog("Ultralight-C new password: %s", sprint_hex(pwd
,16));
1823 PrintAndLog("Failed writing at block %d", resp
.arg
[1] & 0xff);
1827 PrintAndLog("command execution time out");
1834 // Magic UL / UL-C tags - Set UID
1836 int CmdHF14AMfucSetUid(const char *Cmd
){
1840 uint8_t uid
[7] = {0x00};
1841 char cmdp
= param_getchar(Cmd
, 0);
1843 if (strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_mfu_ucsetuid();
1845 if (param_gethex(Cmd
, 0, uid
, 14)) {
1846 PrintAndLog("UID must include 14 HEX symbols");
1851 c
.cmd
= CMD_MIFAREU_READBL
;
1853 clearCommandBuffer();
1855 if (!WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1856 PrintAndLog("Command execute timeout");
1861 uint8_t oldblock2
[4] = {0x00};
1862 memcpy(resp
.d
.asBytes
, oldblock2
, 4);
1865 c
.cmd
= CMD_MIFAREU_WRITEBL
;
1867 c
.d
.asBytes
[0] = uid
[0];
1868 c
.d
.asBytes
[1] = uid
[1];
1869 c
.d
.asBytes
[2] = uid
[2];
1870 c
.d
.asBytes
[3] = 0x88 ^ uid
[0] ^ uid
[1] ^ uid
[2];
1871 clearCommandBuffer();
1873 if (!WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1874 PrintAndLog("Command execute timeout");
1880 c
.d
.asBytes
[0] = uid
[3];
1881 c
.d
.asBytes
[1] = uid
[4];
1882 c
.d
.asBytes
[2] = uid
[5];
1883 c
.d
.asBytes
[3] = uid
[6];
1884 clearCommandBuffer();
1886 if (!WaitForResponseTimeout(CMD_ACK
,&resp
,1500) ) {
1887 PrintAndLog("Command execute timeout");
1893 c
.d
.asBytes
[0] = uid
[3] ^ uid
[4] ^ uid
[5] ^ uid
[6];
1894 c
.d
.asBytes
[1] = oldblock2
[1];
1895 c
.d
.asBytes
[2] = oldblock2
[2];
1896 c
.d
.asBytes
[3] = oldblock2
[3];
1897 clearCommandBuffer();
1899 if (!WaitForResponseTimeout(CMD_ACK
,&resp
,1500) ) {
1900 PrintAndLog("Command execute timeout");
1907 int CmdHF14AMfuGenDiverseKeys(const char *Cmd
){
1910 char cmdp
= param_getchar(Cmd
, 0);
1911 if (strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_mfu_gendiverse();
1913 if (param_gethex(Cmd
, 0, uid
, 8)) {
1914 PrintAndLog("UID must include 8 HEX symbols");
1918 uint8_t iv
[8] = { 0x00 };
1919 uint8_t block
= 0x01;
1921 uint8_t mifarekeyA
[] = { 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5 };
1922 uint8_t mifarekeyB
[] = { 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5 };
1923 uint8_t dkeyA
[8] = { 0x00 };
1924 uint8_t dkeyB
[8] = { 0x00 };
1926 uint8_t masterkey
[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
1928 uint8_t mix
[8] = { 0x00 };
1929 uint8_t divkey
[8] = { 0x00 };
1931 memcpy(mix
, mifarekeyA
, 4);
1933 mix
[4] = mifarekeyA
[4] ^ uid
[0];
1934 mix
[5] = mifarekeyA
[5] ^ uid
[1];
1935 mix
[6] = block
^ uid
[2];
1938 des3_context ctx
= { 0x00 };
1939 des3_set2key_enc(&ctx
, masterkey
);
1941 des3_crypt_cbc(&ctx
// des3_context
1942 , DES_ENCRYPT
// int mode
1943 , sizeof(mix
) // length
1949 PrintAndLog("-- 3DES version");
1950 PrintAndLog("Masterkey :\t %s", sprint_hex(masterkey
,sizeof(masterkey
)));
1951 PrintAndLog("UID :\t %s", sprint_hex(uid
, sizeof(uid
)));
1952 PrintAndLog("block :\t %0d", block
);
1953 PrintAndLog("Mifare key :\t %s", sprint_hex(mifarekeyA
, sizeof(mifarekeyA
)));
1954 PrintAndLog("Message :\t %s", sprint_hex(mix
, sizeof(mix
)));
1955 PrintAndLog("Diversified key: %s", sprint_hex(divkey
+1, 6));
1957 for (int i
=0; i
< sizeof(mifarekeyA
); ++i
){
1958 dkeyA
[i
] = (mifarekeyA
[i
] << 1) & 0xff;
1959 dkeyA
[6] |= ((mifarekeyA
[i
] >> 7) & 1) << (i
+1);
1962 for (int i
=0; i
< sizeof(mifarekeyB
); ++i
){
1963 dkeyB
[1] |= ((mifarekeyB
[i
] >> 7) & 1) << (i
+1);
1964 dkeyB
[2+i
] = (mifarekeyB
[i
] << 1) & 0xff;
1967 uint8_t zeros
[8] = {0x00};
1968 uint8_t newpwd
[8] = {0x00};
1969 uint8_t dmkey
[24] = {0x00};
1970 memcpy(dmkey
, dkeyA
, 8);
1971 memcpy(dmkey
+8, dkeyB
, 8);
1972 memcpy(dmkey
+16, dkeyA
, 8);
1973 memset(iv
, 0x00, 8);
1975 des3_set3key_enc(&ctx
, dmkey
);
1977 des3_crypt_cbc(&ctx
// des3_context
1978 , DES_ENCRYPT
// int mode
1979 , sizeof(newpwd
) // length
1985 PrintAndLog("\n-- DES version");
1986 PrintAndLog("Mifare dkeyA :\t %s", sprint_hex(dkeyA
, sizeof(dkeyA
)));
1987 PrintAndLog("Mifare dkeyB :\t %s", sprint_hex(dkeyB
, sizeof(dkeyB
)));
1988 PrintAndLog("Mifare ABA :\t %s", sprint_hex(dmkey
, sizeof(dmkey
)));
1989 PrintAndLog("Mifare Pwd :\t %s", sprint_hex(newpwd
, sizeof(newpwd
)));
1991 // next. from the diversify_key method.
1995 int CmdHF14AMfUeLoad(const char *Cmd
) {
1996 char ctmp
= param_getchar(Cmd
, 0);
1997 if ( ctmp
== 'h' || ctmp
== 'H' || ctmp
== 0x00) return usage_hf_mfu_eload();
1998 return CmdHF14AMfELoad(Cmd
);
2001 int CmdHF14AMfUSim(const char *Cmd
) {
2002 char ctmp
= param_getchar(Cmd
, 0);
2003 if ( ctmp
== 'h' || ctmp
== 'H' || ctmp
== 0x00) return usage_hf_mfu_sim();
2004 return CmdHF14ASim(Cmd
);
2007 //------------------------------------
2009 //------------------------------------
2010 static command_t CommandTable
[] =
2012 {"help", CmdHelp
, 1, "This help"},
2013 {"dbg", CmdHF14AMfDbg
, 0, "Set default debug mode"},
2014 {"info", CmdHF14AMfUInfo
, 0, "Tag information"},
2015 {"dump", CmdHF14AMfUDump
, 0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"},
2016 {"eload", CmdHF14AMfUeLoad
, 0, "load Ultralight .eml dump file into emulator memory"},
2017 {"rdbl", CmdHF14AMfURdBl
, 0, "Read block"},
2018 {"wrbl", CmdHF14AMfUWrBl
, 0, "Write block"},
2019 {"cauth", CmdHF14AMfucAuth
, 0, "Authentication - Ultralight C"},
2020 {"setpwd", CmdHF14AMfucSetPwd
, 0, "Set 3des password - Ultralight-C"},
2021 {"setuid", CmdHF14AMfucSetUid
, 0, "Set UID - MAGIC tags only"},
2022 {"sim", CmdHF14AMfUSim
, 0, "Simulate Ultralight from emulator memory"},
2023 {"gen", CmdHF14AMfuGenDiverseKeys
, 1, "Generate 3des mifare diversified keys"},
2024 {NULL
, NULL
, 0, NULL
}
2027 int CmdHFMFUltra(const char *Cmd
){
2028 clearCommandBuffer();
2029 //WaitForResponseTimeout(CMD_ACK,NULL,100);
2030 CmdsParse(CommandTable
, Cmd
);
2034 int CmdHelp(const char *Cmd
){
2035 CmdsHelp(CommandTable
);