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 // pack generation for algo 1-3
123 uint16_t ul_ev1_packgenA(uint8_t* uid
){
124 uint16_t pack
= (uid
[0] ^ uid
[1] ^ uid
[2]) << 8 | (uid
[2] ^ 8);
127 uint16_t ul_ev1_packgenB(uint8_t* uid
){
130 uint16_t ul_ev1_packgenC(uint8_t* uid
){
135 void ul_ev1_pwdgen_selftest(){
137 uint8_t uid1
[] = {0x04,0x11,0x12,0x11,0x12,0x11,0x10};
138 uint32_t pwd1
= ul_ev1_pwdgenA(uid1
);
139 PrintAndLog("UID | %s | %08X | %s", sprint_hex(uid1
,7), pwd1
, (pwd1
== 0x8432EB17)?"OK":"->8432EB17<-");
141 uint8_t uid2
[] = {0x04,0x1f,0x98,0xea,0x1e,0x3e,0x81};
142 uint32_t pwd2
= ul_ev1_pwdgenB(uid2
);
143 PrintAndLog("UID | %s | %08X | %s", sprint_hex(uid2
,7), pwd2
, (pwd2
== 0x5fd37eca)?"OK":"->5fd37eca<--");
145 uint8_t uid3
[] = {0x04,0x62, 0xB6, 0x8A, 0xB4, 0x42, 0x80};
146 uint32_t pwd3
= ul_ev1_pwdgenC(uid3
);
147 PrintAndLog("UID | %s | %08X | %s", sprint_hex(uid3
,7), pwd3
, (pwd3
== 0x5a349515)?"OK":"->5a349515<--");
151 static int CmdHelp(const char *Cmd
);
153 // get version nxp product type
154 char *getProductTypeStr( uint8_t id
){
160 case 3: sprintf(retStr
, "%02X, Ultralight", id
); break;
161 case 4: sprintf(retStr
, "%02X, NTAG", id
); break;
162 default: sprintf(retStr
, "%02X, unknown", id
); break;
168 The 7 MSBits (=n) code the storage size itself based on 2^n,
169 the LSBit is set to '0' if the size is exactly 2^n
170 and set to '1' if the storage size is between 2^n and 2^(n+1).
172 char *getUlev1CardSizeStr( uint8_t fsize
){
176 memset(buf
, 0, sizeof(buf
));
178 uint16_t usize
= 1 << ((fsize
>>1) + 1);
179 uint16_t lsize
= 1 << (fsize
>>1);
183 sprintf(retStr
, "%02X, (%u <-> %u bytes)",fsize
, usize
, lsize
);
185 sprintf(retStr
, "%02X, (%u bytes)", fsize
, lsize
);
189 static void ul_switch_on_field(void) {
190 UsbCommand c
= {CMD_READER_ISO_14443a
, {ISO14A_CONNECT
| ISO14A_NO_DISCONNECT
, 0, 0}};
191 clearCommandBuffer();
195 void ul_switch_off_field(void) {
196 UsbCommand c
= {CMD_READER_ISO_14443a
, {0, 0, 0}};
197 clearCommandBuffer();
201 static int ul_send_cmd_raw( uint8_t *cmd
, uint8_t cmdlen
, uint8_t *response
, uint16_t responseLength
) {
202 UsbCommand c
= {CMD_READER_ISO_14443a
, {ISO14A_RAW
| ISO14A_NO_DISCONNECT
| ISO14A_APPEND_CRC
, cmdlen
, 0}};
203 memcpy(c
.d
.asBytes
, cmd
, cmdlen
);
204 clearCommandBuffer();
207 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 1500)) return -1;
208 if (!resp
.arg
[0] && responseLength
) return -1;
210 uint16_t resplen
= (resp
.arg
[0] < responseLength
) ? resp
.arg
[0] : responseLength
;
211 memcpy(response
, resp
.d
.asBytes
, resplen
);
215 static int ul_select( iso14a_card_select_t
*card
){
217 ul_switch_on_field();
221 ans
= WaitForResponseTimeout(CMD_ACK
, &resp
, 1500);
222 if (!ans
|| resp
.arg
[0] < 1) {
223 PrintAndLog("iso14443a card select failed");
224 ul_switch_off_field();
228 memcpy(card
, resp
.d
.asBytes
, sizeof(iso14a_card_select_t
));
232 // This read command will at least return 16bytes.
233 static int ul_read( uint8_t page
, uint8_t *response
, uint16_t responseLength
){
235 uint8_t cmd
[] = {ISO14443A_CMD_READBLOCK
, page
};
236 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), response
, responseLength
);
240 static int ul_comp_write( uint8_t page
, uint8_t *data
, uint8_t datalen
){
243 memset(cmd
, 0x00, sizeof(cmd
));
244 datalen
= ( datalen
> 16) ? 16 : datalen
;
246 cmd
[0] = ISO14443A_CMD_WRITEBLOCK
;
248 memcpy(cmd
+2, data
, datalen
);
250 uint8_t response
[1] = {0xff};
251 ul_send_cmd_raw(cmd
, 2+datalen
, response
, sizeof(response
));
253 if ( response
[0] == 0x0a ) return 0;
258 static int ulc_requestAuthentication( uint8_t *nonce
, uint16_t nonceLength
){
260 uint8_t cmd
[] = {MIFARE_ULC_AUTH_1
, 0x00};
261 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), nonce
, nonceLength
);
265 static int ulc_authentication( uint8_t *key
, bool switch_off_field
){
267 UsbCommand c
= {CMD_MIFAREUC_AUTH
, {switch_off_field
}};
268 memcpy(c
.d
.asBytes
, key
, 16);
269 clearCommandBuffer();
272 if ( !WaitForResponseTimeout(CMD_ACK
, &resp
, 1500) ) return 0;
273 if ( resp
.arg
[0] == 1 ) return 1;
278 static int ulev1_requestAuthentication( uint8_t *pwd
, uint8_t *pack
, uint16_t packLength
){
280 uint8_t cmd
[] = {MIFARE_ULEV1_AUTH
, pwd
[0], pwd
[1], pwd
[2], pwd
[3]};
281 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), pack
, packLength
);
285 static int ul_auth_select( iso14a_card_select_t
*card
, TagTypeUL_t tagtype
, bool hasAuthKey
, uint8_t *authenticationkey
, uint8_t *pack
, uint8_t packSize
){
286 if ( hasAuthKey
&& (tagtype
& UL_C
)) {
287 //will select card automatically and close connection on error
288 if (!ulc_authentication(authenticationkey
, false)) {
289 PrintAndLog("Error: Authentication Failed UL-C");
293 if ( !ul_select(card
) ) return 0;
296 if (ulev1_requestAuthentication(authenticationkey
, pack
, packSize
) < 2) {
297 ul_switch_off_field();
298 PrintAndLog("Error: Authentication Failed UL-EV1/NTAG");
306 static int ulev1_getVersion( uint8_t *response
, uint16_t responseLength
){
308 uint8_t cmd
[] = {MIFARE_ULEV1_VERSION
};
309 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), response
, responseLength
);
313 static int ulev1_readCounter( uint8_t counter
, uint8_t *response
, uint16_t responseLength
){
315 uint8_t cmd
[] = {MIFARE_ULEV1_READ_CNT
, counter
};
316 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), response
, responseLength
);
320 static int ulev1_readTearing( uint8_t counter
, uint8_t *response
, uint16_t responseLength
){
322 uint8_t cmd
[] = {MIFARE_ULEV1_CHECKTEAR
, counter
};
323 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), response
, responseLength
);
327 static int ulev1_readSignature( uint8_t *response
, uint16_t responseLength
){
329 uint8_t cmd
[] = {MIFARE_ULEV1_READSIG
, 0x00};
330 int len
= ul_send_cmd_raw(cmd
, sizeof(cmd
), response
, responseLength
);
334 // Fudan check checks for which error is given for a command with incorrect crc
335 // NXP UL chip responds with 01, fudan 00.
336 // other possible checks:
338 // UL responds with 00, fudan doesn't respond
341 // UL doesn't respond, fudan responds with 00
343 // send 300000 + crc (read with extra byte(s))
344 // UL responds with read of page 0, fudan doesn't respond.
346 // make sure field is off before calling this function
347 static int ul_fudan_check( void ){
348 iso14a_card_select_t card
;
349 if ( !ul_select(&card
) )
352 UsbCommand c
= {CMD_READER_ISO_14443a
, {ISO14A_RAW
| ISO14A_NO_DISCONNECT
, 4, 0}};
354 uint8_t cmd
[4] = {0x30,0x00,0x02,0xa7}; //wrong crc on purpose should be 0xa8
355 memcpy(c
.d
.asBytes
, cmd
, 4);
356 clearCommandBuffer();
359 if (!WaitForResponseTimeout(CMD_ACK
, &resp
, 1500)) return UL_ERROR
;
360 if (resp
.arg
[0] != 1) return UL_ERROR
;
362 return (!resp
.d
.asBytes
[0]) ? FUDAN_UL
: UL
; //if response == 0x00 then Fudan, else Genuine NXP
365 static int ul_print_default( uint8_t *data
){
376 PrintAndLog(" UID : %s ", sprint_hex(uid
, 7));
377 PrintAndLog(" UID[0] : %02X, %s", uid
[0], getTagInfo(uid
[0]) );
378 if ( uid
[0] == 0x05 && ((uid
[1] & 0xf0) >> 4) == 2 ) { // is infineon and 66RxxP
379 uint8_t chip
= (data
[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU
381 case 0xc2: PrintAndLog(" IC type : SLE 66R04P 770 Bytes"); break; //77 pages
382 case 0xc4: PrintAndLog(" IC type : SLE 66R16P 2560 Bytes"); break; //256 pages
383 case 0xc6: PrintAndLog(" IC type : SLE 66R32P 5120 Bytes"); break; //512 pages /2 sectors
386 // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
387 int crc0
= 0x88 ^ data
[0] ^ data
[1] ^data
[2];
388 if ( data
[3] == crc0
)
389 PrintAndLog(" BCC0 : %02X, Ok", data
[3]);
391 PrintAndLog(" BCC0 : %02X, crc should be %02X", data
[3], crc0
);
393 int crc1
= data
[4] ^ data
[5] ^ data
[6] ^data
[7];
394 if ( data
[8] == crc1
)
395 PrintAndLog(" BCC1 : %02X, Ok", data
[8]);
397 PrintAndLog(" BCC1 : %02X, crc should be %02X", data
[8], crc1
);
399 PrintAndLog(" Internal : %02X, %sdefault", data
[9], (data
[9]==0x48)?"":"not " );
401 PrintAndLog(" Lock : %s - %s",
402 sprint_hex(data
+10, 2),
403 sprint_bin(data
+10, 2)
406 PrintAndLog("OneTimePad : %s - %s\n",
407 sprint_hex(data
+ 12, 4),
408 sprint_bin(data
+12, 4)
414 static int ndef_print_CC(uint8_t *data
) {
419 PrintAndLog("--- NDEF Message");
420 PrintAndLog("Capability Container: %s", sprint_hex(data
,4) );
421 PrintAndLog(" %02X : NDEF Magic Number", data
[0]);
422 PrintAndLog(" %02X : version %d.%d supported by tag", data
[1], (data
[1] & 0xF0) >> 4, data
[1] & 0x0f);
423 PrintAndLog(" %02X : Physical Memory Size: %d bytes", data
[2], (data
[2] + 1) * 8);
424 if ( data
[2] == 0x96 )
425 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data
[2], 48);
426 else if ( data
[2] == 0x12 )
427 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data
[2], 144);
428 else if ( data
[2] == 0x3e )
429 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data
[2], 496);
430 else if ( data
[2] == 0x6d )
431 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data
[2], 872);
433 PrintAndLog(" %02X : %s / %s", data
[3],
434 (data
[3] & 0xF0) ? "(RFU)" : "Read access granted without any security",
435 (data
[3] & 0x0F)==0 ? "Write access granted without any security" : (data
[3] & 0x0F)==0x0F ? "No write access granted at all" : "(RFU)");
439 int ul_print_type(uint32_t tagtype
, uint8_t spaces
){
442 char *spacer
= spc
+ (10-spaces
);
445 PrintAndLog("%sTYPE : MIFARE Ultralight (MF0ICU1) %s", spacer
, (tagtype
& MAGIC
) ? "<magic>" : "" );
446 else if ( tagtype
& UL_C
)
447 PrintAndLog("%sTYPE : MIFARE Ultralight C (MF0ULC) %s", spacer
, (tagtype
& MAGIC
) ? "<magic>" : "" );
448 else if ( tagtype
& UL_EV1_48
)
449 PrintAndLog("%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer
);
450 else if ( tagtype
& UL_EV1_128
)
451 PrintAndLog("%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer
);
452 else if ( tagtype
& NTAG
)
453 PrintAndLog("%sTYPE : NTAG UNKNOWN", spacer
);
454 else if ( tagtype
& NTAG_203
)
455 PrintAndLog("%sTYPE : NTAG 203 144bytes (NT2H0301F0DT)", spacer
);
456 else if ( tagtype
& NTAG_210
)
457 PrintAndLog("%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer
);
458 else if ( tagtype
& NTAG_212
)
459 PrintAndLog("%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer
);
460 else if ( tagtype
& NTAG_213
)
461 PrintAndLog("%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer
);
462 else if ( tagtype
& NTAG_215
)
463 PrintAndLog("%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer
);
464 else if ( tagtype
& NTAG_216
)
465 PrintAndLog("%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer
);
466 else if ( tagtype
& NTAG_I2C_1K
)
467 PrintAndLog("%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer
, "\xFD");
468 else if ( tagtype
& NTAG_I2C_2K
)
469 PrintAndLog("%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer
, "\xFD");
470 else if ( tagtype
& MY_D
)
471 PrintAndLog("%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer
);
472 else if ( tagtype
& MY_D_NFC
)
473 PrintAndLog("%sTYPE : INFINEON my-d\x99 NFC (SLE 66RxxP)", spacer
);
474 else if ( tagtype
& MY_D_MOVE
)
475 PrintAndLog("%sTYPE : INFINEON my-d\x99 move (SLE 66R01P)", spacer
);
476 else if ( tagtype
& MY_D_MOVE_NFC
)
477 PrintAndLog("%sTYPE : INFINEON my-d\x99 move NFC (SLE 66R01P)", spacer
);
478 else if ( tagtype
& MY_D_MOVE_LEAN
)
479 PrintAndLog("%sTYPE : INFINEON my-d\x99 move lean (SLE 66R01L)", spacer
);
480 else if ( tagtype
& FUDAN_UL
)
481 PrintAndLog("%sTYPE : FUDAN Ultralight Compatible (or other compatible) %s", spacer
, (tagtype
& MAGIC
) ? "<magic>" : "" );
483 PrintAndLog("%sTYPE : Unknown %06x", spacer
, tagtype
);
487 static int ulc_print_3deskey( uint8_t *data
){
488 PrintAndLog(" deskey1 [44/0x2C] : %s [s]", sprint_hex(data
,4), sprint_ascii(data
,4) );
489 PrintAndLog(" deskey1 [45/0x2D] : %s [s]", sprint_hex(data
+4 ,4), sprint_ascii(data
+4,4));
490 PrintAndLog(" deskey2 [46/0x2E] : %s [s]", sprint_hex(data
+8 ,4), sprint_ascii(data
+8,4));
491 PrintAndLog(" deskey2 [47/0x2F] : %s [s]", sprint_hex(data
+12,4), sprint_ascii(data
+12,4));
492 PrintAndLog("\n 3des key : %s", sprint_hex(SwapEndian64(data
, 16, 8), 16));
496 static int ulc_print_configuration( uint8_t *data
){
498 PrintAndLog("--- UL-C Configuration");
499 PrintAndLog(" Higher Lockbits [40/0x28] : %s - %s", sprint_hex(data
, 4), sprint_bin(data
, 2));
500 PrintAndLog(" Counter [41/0x29] : %s - %s", sprint_hex(data
+4, 4), sprint_bin(data
+4, 2));
502 bool validAuth
= (data
[8] >= 0x03 && data
[8] <= 0x30);
504 PrintAndLog(" Auth0 [42/0x2A] : %s page %d/0x%02X and above need authentication", sprint_hex(data
+8, 4), data
[8],data
[8] );
507 PrintAndLog(" Auth0 [42/0x2A] : %s default", sprint_hex(data
+8, 4) );
509 PrintAndLog(" Auth0 [42/0x2A] : %s auth byte is out-of-range", sprint_hex(data
+8, 4) );
512 PrintAndLog(" Auth1 [43/0x2B] : %s %s",
513 sprint_hex(data
+12, 4),
514 (data
[12] & 1) ? "write access restricted": "read and write access restricted"
519 static int ulev1_print_configuration( uint8_t *data
, uint8_t startPage
){
521 PrintAndLog("\n--- Tag Configuration");
523 bool strg_mod_en
= (data
[0] & 2);
524 uint8_t authlim
= (data
[4] & 0x07);
525 bool nfc_cnf_en
= (data
[4] & 0x08);
526 bool nfc_cnf_prot_pwd
= (data
[4] & 0x10);
527 bool cfglck
= (data
[4] & 0x40);
528 bool prot
= (data
[4] & 0x80);
529 uint8_t vctid
= data
[5];
531 PrintAndLog(" cfg0 [%u/0x%02X] : %s", startPage
, startPage
, sprint_hex(data
, 4));
532 if ( data
[3] < 0xff )
533 PrintAndLog(" - page %d and above need authentication",data
[3]);
535 PrintAndLog(" - pages don't need authentication");
536 PrintAndLog(" - strong modulation mode %s", (strg_mod_en
) ? "enabled":"disabled");
537 PrintAndLog(" cfg1 [%u/0x%02X] : %s", startPage
+ 1, startPage
+ 1, sprint_hex(data
+4, 4) );
539 PrintAndLog(" - Unlimited password attempts");
541 PrintAndLog(" - Max number of password attempts is %d", authlim
);
543 PrintAndLog(" - NFC counter %s", (nfc_cnf_en
) ? "enabled":"disabled");
544 PrintAndLog(" - NFC counter %s", (nfc_cnf_prot_pwd
) ? "not protected":"password protection enabled");
546 PrintAndLog(" - user configuration %s", cfglck
? "permanently locked":"writeable");
547 PrintAndLog(" - %s access is protected with password", prot
? "read and write":"write");
548 PrintAndLog(" - %02X, Virtual Card Type Identifier is %s default", vctid
, (vctid
==0x05)? "":"not");
549 PrintAndLog(" PWD [%u/0x%02X] : %s- (cannot be read)", startPage
+ 2, startPage
+ 2, sprint_hex(data
+8, 4));
550 PrintAndLog(" PACK [%u/0x%02X] : %s - (cannot be read)", startPage
+ 3, startPage
+ 3, sprint_hex(data
+12, 2));
551 PrintAndLog(" RFU [%u/0x%02X] : %s- (cannot be read)", startPage
+ 3, startPage
+ 3, sprint_hex(data
+12, 2));
555 static int ulev1_print_counters(){
556 PrintAndLog("--- Tag Counters");
557 uint8_t tear
[1] = {0};
558 uint8_t counter
[3] = {0,0,0};
560 for ( uint8_t i
= 0; i
<3; ++i
) {
561 ulev1_readTearing(i
,tear
,sizeof(tear
));
562 len
= ulev1_readCounter(i
,counter
, sizeof(counter
) );
564 PrintAndLog(" [%0d] : %s", i
, sprint_hex(counter
,3));
565 PrintAndLog(" - %02X tearing %s", tear
[0], ( tear
[0]==0xBD)?"Ok":"failure");
571 static int ulev1_print_signature( uint8_t *data
, uint8_t len
){
572 PrintAndLog("\n--- Tag Signature");
573 //PrintAndLog("IC signature public key name : NXP NTAG21x 2013"); // don't know if there is other NXP public keys.. :(
574 PrintAndLog("IC signature public key value : 04494e1a386d3d3cfe3dc10e5de68a499b1c202db5b132393e89ed19fe5be8bc61");
575 PrintAndLog(" Elliptic curve parameters : secp128r1");
576 PrintAndLog(" Tag ECC Signature : %s", sprint_hex(data
, len
));
577 //to do: verify if signature is valid
578 //PrintAndLog("IC signature status: %s valid", (iseccvalid() )?"":"not");
582 static int ulev1_print_version(uint8_t *data
){
583 PrintAndLog("\n--- Tag Version");
584 PrintAndLog(" Raw bytes : %s",sprint_hex(data
, 8) );
585 PrintAndLog(" Vendor ID : %02X, %s", data
[1], getTagInfo(data
[1]));
586 PrintAndLog(" Product type : %s", getProductTypeStr(data
[2]));
587 PrintAndLog(" Product subtype : %02X, %s", data
[3], (data
[3]==1) ?"17 pF":"50pF");
588 PrintAndLog(" Major version : %02X", data
[4]);
589 PrintAndLog(" Minor version : %02X", data
[5]);
590 PrintAndLog(" Size : %s", getUlev1CardSizeStr(data
[6]));
591 PrintAndLog(" Protocol type : %02X", data
[7]);
596 static int ulc_magic_test(){
597 // Magic Ultralight test
598 // Magic UL-C, by observation,
599 // 1) it seems to have a static nonce response to 0x1A command.
600 // 2) the deskey bytes is not-zero:d out on as datasheet states.
601 // 3) UID - changeable, not only, but pages 0-1-2-3.
602 // 4) use the ul_magic_test ! magic tags answers specially!
603 int returnValue = UL_ERROR;
604 iso14a_card_select_t card;
605 uint8_t nonce1[11] = {0x00};
606 uint8_t nonce2[11] = {0x00};
607 int status = ul_select(&card);
611 status = ulc_requestAuthentication(nonce1, sizeof(nonce1));
613 status = ulc_requestAuthentication(nonce2, sizeof(nonce2));
614 returnValue = ( !memcmp(nonce1, nonce2, 11) ) ? UL_C_MAGIC : UL_C;
618 ul_switch_off_field();
622 static int ul_magic_test(){
624 // Magic Ultralight tests
625 // 1) take present UID, and try to write it back. OBSOLETE
626 // 2) make a wrong length write to page0, and see if tag answers with ACK/NACK:
627 iso14a_card_select_t card
;
628 if ( !ul_select(&card
) )
630 int status
= ul_comp_write(0, NULL
, 0);
631 ul_switch_off_field();
637 uint32_t GetHF14AMfU_Type(void){
639 TagTypeUL_t tagtype
= UNKNOWN
;
640 iso14a_card_select_t card
;
641 uint8_t version
[10] = {0x00};
645 if (!ul_select(&card
)) return UL_ERROR
;
647 // Ultralight - ATQA / SAK
648 if ( card
.atqa
[1] != 0x00 || card
.atqa
[0] != 0x44 || card
.sak
!= 0x00 ) {
649 //PrintAndLog("Tag is not Ultralight | NTAG | MY-D [ATQA: %02X %02X SAK: %02X]\n", card.atqa[1], card.atqa[0], card.sak);
650 ul_switch_off_field();
654 if ( card
.uid
[0] != 0x05) {
656 len
= ulev1_getVersion(version
, sizeof(version
));
657 ul_switch_off_field();
662 if ( version
[2] == 0x03 && version
[6] == 0x0B )
664 else if ( version
[2] == 0x03 && version
[6] != 0x0B )
665 tagtype
= UL_EV1_128
;
666 else if ( version
[2] == 0x04 && version
[3] == 0x01 && version
[6] == 0x0B )
668 else if ( version
[2] == 0x04 && version
[3] == 0x01 && version
[6] == 0x0E )
670 else if ( version
[2] == 0x04 && version
[3] == 0x02 && version
[6] == 0x0F )
672 else if ( version
[2] == 0x04 && version
[3] == 0x02 && version
[6] == 0x11 )
674 else if ( version
[2] == 0x04 && version
[3] == 0x02 && version
[6] == 0x13 )
676 else if ( version
[2] == 0x04 && version
[3] == 0x05 && version
[6] == 0x13 )
677 tagtype
= NTAG_I2C_1K
;
678 else if ( version
[2] == 0x04 && version
[3] == 0x05 && version
[6] == 0x15 )
679 tagtype
= NTAG_I2C_2K
;
680 else if ( version
[2] == 0x04 )
685 case 0x01: tagtype
= UL_C
; break;
686 case 0x00: tagtype
= UL
; break;
687 case -1 : tagtype
= (UL
| UL_C
| NTAG_203
); break; // could be UL | UL_C magic tags
688 default : tagtype
= UNKNOWN
; break;
690 // UL vs UL-C vs ntag203 test
691 if (tagtype
& (UL
| UL_C
| NTAG_203
)) {
692 if ( !ul_select(&card
) ) return UL_ERROR
;
694 // do UL_C check first...
695 uint8_t nonce
[11] = {0x00};
696 status
= ulc_requestAuthentication(nonce
, sizeof(nonce
));
697 ul_switch_off_field();
701 // need to re-select after authentication error
702 if ( !ul_select(&card
) ) return UL_ERROR
;
704 uint8_t data
[16] = {0x00};
705 // read page 0x26-0x29 (last valid ntag203 page)
706 status
= ul_read(0x26, data
, sizeof(data
));
710 // read page 0x30 (should error if it is a ntag203)
711 status
= ul_read(0x30, data
, sizeof(data
));
718 ul_switch_off_field();
722 tagtype
= ul_fudan_check();
723 ul_switch_off_field();
726 ul_switch_off_field();
727 // Infinition MY-D tests Exam high nibble
728 uint8_t nib
= (card
.uid
[1] & 0xf0) >> 4;
730 // case 0: tagtype = SLE66R35E7; break; //or SLE 66R35E7 - mifare compat... should have different sak/atqa for mf 1k
731 case 1: tagtype
= MY_D
; break; //or SLE 66RxxS ... up to 512 pages of 8 user bytes...
732 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)
733 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
734 case 7: tagtype
= MY_D_MOVE_LEAN
; break; //or SLE 66R01L // 16 pages of 4 bytes
738 tagtype
|= ul_magic_test();
739 if (tagtype
== (UNKNOWN
| MAGIC
)) tagtype
= (UL_MAGIC
);
743 int CmdHF14AMfUInfo(const char *Cmd
){
745 uint8_t authlim
= 0xff;
746 uint8_t data
[16] = {0x00};
747 iso14a_card_select_t card
;
750 bool hasAuthKey
= false;
752 bool swapEndian
= false;
755 uint8_t authenticationkey
[16] = {0x00};
756 uint8_t *authkeyptr
= authenticationkey
;
757 uint8_t pwd
[4] = {0,0,0,0};
759 uint8_t pack
[4] = {0,0,0,0};
763 while(param_getchar(Cmd
, cmdp
) != 0x00)
765 switch(param_getchar(Cmd
, cmdp
))
769 return usage_hf_mfu_info();
772 dataLen
= param_getstr(Cmd
, cmdp
+1, tempStr
);
773 if (dataLen
== 32 || dataLen
== 8) { //ul-c or ev1/ntag key length
774 errors
= param_gethex(tempStr
, 0, authenticationkey
, dataLen
);
775 dataLen
/= 2; // handled as bytes from now on
777 PrintAndLog("\nERROR: Key is incorrect length\n");
789 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
797 if(errors
) return usage_hf_mfu_info();
799 TagTypeUL_t tagtype
= GetHF14AMfU_Type();
800 if (tagtype
== UL_ERROR
) return -1;
802 PrintAndLog("\n--- Tag Information ---------");
803 PrintAndLog("-------------------------------------------------------------");
804 ul_print_type(tagtype
, 6);
807 if (swapEndian
&& hasAuthKey
) authkeyptr
= SwapEndian64(authenticationkey
, dataLen
, (dataLen
== 16) ? 8 : 4 );
809 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
811 // read pages 0,1,2,3 (should read 4pages)
812 status
= ul_read(0, data
, sizeof(data
));
813 if ( status
== -1 ) {
814 ul_switch_off_field();
815 PrintAndLog("Error: tag didn't answer to READ");
817 } else if (status
== 16) {
818 ul_print_default(data
);
819 ndef_print_CC(data
+12);
825 if ((tagtype
& UL_C
)) {
827 // read pages 0x28, 0x29, 0x2A, 0x2B
828 uint8_t ulc_conf
[16] = {0x00};
829 status
= ul_read(0x28, ulc_conf
, sizeof(ulc_conf
));
831 PrintAndLog("Error: tag didn't answer to READ UL-C");
832 ul_switch_off_field();
835 if (status
== 16) ulc_print_configuration(ulc_conf
);
838 if ((tagtype
& MAGIC
)) {
840 uint8_t ulc_deskey
[16] = {0x00};
841 status
= ul_read(0x2C, ulc_deskey
, sizeof(ulc_deskey
));
842 if ( status
== -1 ) {
843 ul_switch_off_field();
844 PrintAndLog("Error: tag didn't answer to READ magic");
847 if (status
== 16) ulc_print_3deskey(ulc_deskey
);
850 ul_switch_off_field();
851 // if we called info with key, just return
852 if ( hasAuthKey
) return 1;
854 // also try to diversify default keys.. look into CmdHF14AMfuGenDiverseKeys
855 PrintAndLog("Trying some default 3des keys");
856 for (uint8_t i
= 0; i
< KEYS_3DES_COUNT
; ++i
) {
857 key
= default_3des_keys
[i
];
858 if (ulc_authentication(key
, true)) {
859 PrintAndLog("Found default 3des key: ");
861 memcpy(keySwap
, SwapEndian64(key
,16,8), 16);
862 ulc_print_3deskey(keySwap
);
870 // do counters and signature first (don't neet auth)
872 // ul counters are different than ntag counters
873 if ((tagtype
& (UL_EV1_48
| UL_EV1_128
))) {
874 if (ulev1_print_counters() != 3) {
875 // failed - re-select
876 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
881 if ((tagtype
& (UL_EV1_48
| UL_EV1_128
| NTAG_213
| NTAG_215
| NTAG_216
| NTAG_I2C_1K
| NTAG_I2C_2K
))) {
882 uint8_t ulev1_signature
[32] = {0x00};
883 status
= ulev1_readSignature( ulev1_signature
, sizeof(ulev1_signature
));
884 if ( status
== -1 ) {
885 PrintAndLog("Error: tag didn't answer to READ SIGNATURE");
886 ul_switch_off_field();
889 if (status
== 32) ulev1_print_signature( ulev1_signature
, sizeof(ulev1_signature
));
892 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
897 if ((tagtype
& (UL_EV1_48
| UL_EV1_128
| NTAG_210
| NTAG_212
| NTAG_213
| NTAG_215
| NTAG_216
| NTAG_I2C_1K
| NTAG_I2C_2K
))) {
898 uint8_t version
[10] = {0x00};
899 status
= ulev1_getVersion(version
, sizeof(version
));
900 if ( status
== -1 ) {
901 PrintAndLog("Error: tag didn't answer to GETVERSION");
902 ul_switch_off_field();
904 } else if (status
== 10) {
905 ulev1_print_version(version
);
908 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
911 uint8_t startconfigblock
= 0;
912 uint8_t ulev1_conf
[16] = {0x00};
913 // config blocks always are last 4 pages
914 for (uint8_t idx
= 0; idx
< MAX_UL_TYPES
; idx
++)
915 if (tagtype
& UL_TYPES_ARRAY
[idx
])
916 startconfigblock
= UL_MEMORY_ARRAY
[idx
]-3;
918 if (startconfigblock
){ // if we know where the config block is...
919 status
= ul_read(startconfigblock
, ulev1_conf
, sizeof(ulev1_conf
));
920 if ( status
== -1 ) {
921 PrintAndLog("Error: tag didn't answer to READ EV1");
922 ul_switch_off_field();
924 } else if (status
== 16) {
925 // save AUTHENTICATION LIMITS for later:
926 authlim
= (ulev1_conf
[4] & 0x07);
927 ulev1_print_configuration(ulev1_conf
, startconfigblock
);
931 // AUTHLIMIT, (number of failed authentications)
933 // 1-7 = limit. No automatic tries then.
934 // hasAuthKey, if we was called with key, skip test.
935 if ( !authlim
&& !hasAuthKey
) {
936 PrintAndLog("\n--- Known EV1/NTAG passwords.");
940 num_to_bytes( ul_ev1_pwdgenA(card
.uid
), 4, key
);
941 len
= ulev1_requestAuthentication(key
, pack
, sizeof(pack
));
943 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key
, 4), pack
[0], pack
[1]);
945 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
948 num_to_bytes( ul_ev1_pwdgenB(card
.uid
), 4, key
);
949 len
= ulev1_requestAuthentication(key
, pack
, sizeof(pack
));
951 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key
, 4), pack
[0], pack
[1]);
953 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
956 num_to_bytes( ul_ev1_pwdgenC(card
.uid
), 4, key
);
957 len
= ulev1_requestAuthentication(key
, pack
, sizeof(pack
));
959 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key
, 4), pack
[0], pack
[1]);
961 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
963 for (uint8_t i
= 0; i
< KEYS_PWD_COUNT
; ++i
) {
964 key
= default_pwd_pack
[i
];
965 len
= ulev1_requestAuthentication(key
, pack
, sizeof(pack
));
967 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key
, 4), pack
[0], pack
[1]);
970 if (!ul_auth_select( &card
, tagtype
, hasAuthKey
, authkeyptr
, pack
, sizeof(pack
))) return -1;
973 if (len
< 1) PrintAndLog("password not known");
977 ul_switch_off_field();
978 if (locked
) PrintAndLog("\nTag appears to be locked, try using the key to get more info");
984 // Write Single Block
986 int CmdHF14AMfUWrBl(const char *Cmd
){
990 bool hasAuthKey
= false;
991 bool hasPwdKey
= false;
992 bool swapEndian
= false;
996 uint8_t blockdata
[20] = {0x00};
997 uint8_t data
[16] = {0x00};
998 uint8_t authenticationkey
[16] = {0x00};
999 uint8_t *authKeyPtr
= authenticationkey
;
1001 while(param_getchar(Cmd
, cmdp
) != 0x00)
1003 switch(param_getchar(Cmd
, cmdp
))
1007 return usage_hf_mfu_wrbl();
1010 // EV1/NTAG size key
1011 keylen
= param_gethex(Cmd
, cmdp
+1, data
, 8);
1013 memcpy(authenticationkey
, data
, 4);
1019 keylen
= param_gethex(Cmd
, cmdp
+1, data
, 32);
1021 memcpy(authenticationkey
, data
, 16);
1026 PrintAndLog("\nERROR: Key is incorrect length\n");
1031 blockNo
= param_get8(Cmd
, cmdp
+1);
1033 PrintAndLog("Wrong block number");
1045 if ( param_gethex(Cmd
, cmdp
+1, blockdata
, 8) ) {
1046 PrintAndLog("Block data must include 8 HEX symbols");
1053 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
1058 if(errors
) return usage_hf_mfu_wrbl();
1061 if ( blockNo
== -1 ) return usage_hf_mfu_wrbl();
1062 // starting with getting tagtype
1063 TagTypeUL_t tagtype
= GetHF14AMfU_Type();
1064 if (tagtype
== UL_ERROR
) return -1;
1066 uint8_t maxblockno
= 0;
1067 for (uint8_t idx
= 0; idx
< MAX_UL_TYPES
; idx
++){
1068 if (tagtype
& UL_TYPES_ARRAY
[idx
])
1069 maxblockno
= UL_MEMORY_ARRAY
[idx
];
1071 if (blockNo
> maxblockno
){
1072 PrintAndLog("block number too large. Max block is %u/0x%02X \n", maxblockno
,maxblockno
);
1073 return usage_hf_mfu_wrbl();
1077 if (swapEndian
&& hasAuthKey
) authKeyPtr
= SwapEndian64(authenticationkey
, 16, 8);
1078 if (swapEndian
&& hasPwdKey
) authKeyPtr
= SwapEndian64(authenticationkey
, 4, 4);
1081 PrintAndLog("Special Block: %0d (0x%02X) [ %s]", blockNo
, blockNo
, sprint_hex(blockdata
, 4));
1083 PrintAndLog("Block: %0d (0x%02X) [ %s]", blockNo
, blockNo
, sprint_hex(blockdata
, 4));
1086 UsbCommand c
= {CMD_MIFAREU_WRITEBL
, {blockNo
}};
1087 memcpy(c
.d
.asBytes
,blockdata
,4);
1091 memcpy(c
.d
.asBytes
+4,authKeyPtr
,16);
1093 else if ( hasPwdKey
) {
1095 memcpy(c
.d
.asBytes
+4,authKeyPtr
,4);
1098 clearCommandBuffer();
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");
1111 // Read Single Block
1113 int CmdHF14AMfURdBl(const char *Cmd
){
1116 bool errors
= false;
1117 bool hasAuthKey
= false;
1118 bool hasPwdKey
= false;
1119 bool swapEndian
= false;
1122 uint8_t data
[16] = {0x00};
1123 uint8_t authenticationkey
[16] = {0x00};
1124 uint8_t *authKeyPtr
= authenticationkey
;
1126 while(param_getchar(Cmd
, cmdp
) != 0x00)
1128 switch(param_getchar(Cmd
, cmdp
))
1132 return usage_hf_mfu_rdbl();
1135 // EV1/NTAG size key
1136 keylen
= param_gethex(Cmd
, cmdp
+1, data
, 8);
1138 memcpy(authenticationkey
, data
, 4);
1144 keylen
= param_gethex(Cmd
, cmdp
+1, data
, 32);
1146 memcpy(authenticationkey
, data
, 16);
1151 PrintAndLog("\nERROR: Key is incorrect length\n");
1156 blockNo
= param_get8(Cmd
, cmdp
+1);
1158 PrintAndLog("Wrong block number");
1169 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
1174 if(errors
) return usage_hf_mfu_rdbl();
1177 if ( blockNo
== -1 ) return usage_hf_mfu_rdbl();
1178 // start with getting tagtype
1179 TagTypeUL_t tagtype
= GetHF14AMfU_Type();
1180 if (tagtype
== UL_ERROR
) return -1;
1182 uint8_t maxblockno
= 0;
1183 for (uint8_t idx
= 0; idx
< MAX_UL_TYPES
; idx
++){
1184 if (tagtype
& UL_TYPES_ARRAY
[idx
])
1185 maxblockno
= UL_MEMORY_ARRAY
[idx
];
1187 if (blockNo
> maxblockno
){
1188 PrintAndLog("block number to large. Max block is %u/0x%02X \n", maxblockno
,maxblockno
);
1189 return usage_hf_mfu_rdbl();
1193 if (swapEndian
&& hasAuthKey
) authKeyPtr
= SwapEndian64(authenticationkey
, 16, 8);
1194 if (swapEndian
&& hasPwdKey
) authKeyPtr
= SwapEndian64(authenticationkey
, 4, 4);
1197 UsbCommand c
= {CMD_MIFAREU_READBL
, {blockNo
}};
1200 memcpy(c
.d
.asBytes
,authKeyPtr
,16);
1202 else if ( hasPwdKey
) {
1204 memcpy(c
.d
.asBytes
,authKeyPtr
,4);
1207 clearCommandBuffer();
1210 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1211 uint8_t isOK
= resp
.arg
[0] & 0xff;
1213 uint8_t *data
= resp
.d
.asBytes
;
1214 PrintAndLog("\nBlock# | Data | Ascii");
1215 PrintAndLog("-----------------------------");
1216 PrintAndLog("%02d/0x%02X | %s| %s\n", blockNo
, blockNo
, sprint_hex(data
, 4), sprint_ascii(data
,4));
1219 PrintAndLog("Failed reading block: (%02x)", isOK
);
1222 PrintAndLog("Command execute time-out");
1227 int usage_hf_mfu_info(void) {
1228 PrintAndLog("It gathers information about the tag and tries to detect what kind it is.");
1229 PrintAndLog("Sometimes the tags are locked down, and you may need a key to be able to read the information");
1230 PrintAndLog("The following tags can be identified:\n");
1231 PrintAndLog("Ultralight, Ultralight-C, Ultralight EV1, NTAG 203, NTAG 210,");
1232 PrintAndLog("NTAG 212, NTAG 213, NTAG 215, NTAG 216, NTAG I2C 1K & 2K");
1233 PrintAndLog("my-d, my-d NFC, my-d move, my-d move NFC\n");
1234 PrintAndLog("Usage: hf mfu info k <key> l");
1235 PrintAndLog(" Options : ");
1236 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1237 PrintAndLog(" l : (optional) swap entered key's endianness");
1239 PrintAndLog(" sample : hf mfu info");
1240 PrintAndLog(" : hf mfu info k 00112233445566778899AABBCCDDEEFF");
1241 PrintAndLog(" : hf mfu info k AABBCCDDD");
1245 int usage_hf_mfu_dump(void) {
1246 PrintAndLog("Reads all pages from Ultralight, Ultralight-C, Ultralight EV1");
1247 PrintAndLog("NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216");
1248 PrintAndLog("and saves binary dump into the file `filename.bin` or `cardUID.bin`");
1249 PrintAndLog("It autodetects card type.\n");
1250 PrintAndLog("Usage: hf mfu dump k <key> l n <filename w/o .bin> p <page#> q <#pages>");
1251 PrintAndLog(" Options :");
1252 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1253 PrintAndLog(" l : (optional) swap entered key's endianness");
1254 PrintAndLog(" n <FN > : filename w/o .bin to save the dump as");
1255 PrintAndLog(" p <Pg > : starting Page number to manually set a page to start the dump at");
1256 PrintAndLog(" q <qty> : number of Pages to manually set how many pages to dump");
1258 PrintAndLog(" sample : hf mfu dump");
1259 PrintAndLog(" : hf mfu dump n myfile");
1260 PrintAndLog(" : hf mfu dump k 00112233445566778899AABBCCDDEEFF");
1261 PrintAndLog(" : hf mfu dump k AABBCCDDD\n");
1265 int usage_hf_mfu_rdbl(void) {
1266 PrintAndLog("Read a block and print. It autodetects card type.\n");
1267 PrintAndLog("Usage: hf mfu rdbl b <block number> k <key> l\n");
1268 PrintAndLog(" Options:");
1269 PrintAndLog(" b <no> : block to read");
1270 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1271 PrintAndLog(" l : (optional) swap entered key's endianness");
1273 PrintAndLog(" sample : hf mfu rdbl b 0");
1274 PrintAndLog(" : hf mfu rdbl b 0 k 00112233445566778899AABBCCDDEEFF");
1275 PrintAndLog(" : hf mfu rdbl b 0 k AABBCCDDD\n");
1279 int usage_hf_mfu_wrbl(void) {
1280 PrintAndLog("Write a block. It autodetects card type.\n");
1281 PrintAndLog("Usage: hf mfu wrbl b <block number> d <data> k <key> l\n");
1282 PrintAndLog(" Options:");
1283 PrintAndLog(" b <no> : block to write");
1284 PrintAndLog(" d <data> : block data - (8 hex symbols)");
1285 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1286 PrintAndLog(" l : (optional) swap entered key's endianness");
1288 PrintAndLog(" sample : hf mfu wrbl b 0 d 01234567");
1289 PrintAndLog(" : hf mfu wrbl b 0 d 01234567 k AABBCCDDD\n");
1293 int usage_hf_mfu_eload(void) {
1294 PrintAndLog("It loads emul dump from the file `filename.eml`");
1295 PrintAndLog("Hint: See script dumptoemul-mfu.lua to convert the .bin to the eml");
1296 PrintAndLog("Usage: hf mfu eload u <file name w/o `.eml`> [numblocks]");
1297 PrintAndLog(" Options:");
1298 PrintAndLog(" h : this help");
1299 PrintAndLog(" u : UL (required)");
1300 PrintAndLog(" [filename] : without `.eml` (required)");
1301 PrintAndLog(" numblocks : number of blocks to load from eml file (optional)");
1303 PrintAndLog(" sample: hf mfu eload u filename");
1304 PrintAndLog(" hf mfu eload u filename 57");
1308 int usage_hf_mfu_sim(void) {
1309 PrintAndLog("\nEmulating Ultralight tag from emulator memory\n");
1310 PrintAndLog("\nBe sure to load the emulator memory first!\n");
1311 PrintAndLog("Usage: hf mfu sim t 7 u <uid>");
1312 PrintAndLog(" Options:");
1313 PrintAndLog(" h : this help");
1314 PrintAndLog(" t 7 : 7 = NTAG or Ultralight sim (required)");
1315 PrintAndLog(" u <uid> : 4 or 7 byte UID (optional)");
1316 PrintAndLog("\n sample : hf mfu sim t 7");
1317 PrintAndLog(" : hf mfu sim t 7 u 1122344556677\n");
1322 int usage_hf_mfu_ucauth(void) {
1323 PrintAndLog("Usage: hf mfu cauth k <key number>");
1324 PrintAndLog(" 0 (default): 3DES standard key");
1325 PrintAndLog(" 1 : all 0x00 key");
1326 PrintAndLog(" 2 : 0x00-0x0F key");
1327 PrintAndLog(" 3 : nfc key");
1328 PrintAndLog(" 4 : all 0x01 key");
1329 PrintAndLog(" 5 : all 0xff key");
1330 PrintAndLog(" 6 : 0x00-0xFF key");
1331 PrintAndLog("\n sample : hf mfu cauth k");
1332 PrintAndLog(" : hf mfu cauth k 3");
1336 int usage_hf_mfu_ucsetpwd(void) {
1337 PrintAndLog("Usage: hf mfu setpwd <password (32 hex symbols)>");
1338 PrintAndLog(" [password] - (32 hex symbols)");
1340 PrintAndLog("sample: hf mfu setpwd 000102030405060708090a0b0c0d0e0f");
1345 int usage_hf_mfu_ucsetuid(void) {
1346 PrintAndLog("Usage: hf mfu setuid <uid (14 hex symbols)>");
1347 PrintAndLog(" [uid] - (14 hex symbols)");
1348 PrintAndLog("\nThis only works for Magic Ultralight tags.");
1350 PrintAndLog("sample: hf mfu setuid 11223344556677");
1355 int usage_hf_mfu_gendiverse(void){
1356 PrintAndLog("Usage: hf mfu gen <uid (8 hex symbols)>");
1358 PrintAndLog("sample: hf mfu gen 11223344");
1363 int usage_hf_mfu_pwdgen(void){
1364 PrintAndLog("Usage: hf mfu pwdgen <uid (14 hex symbols)>");
1366 PrintAndLog("sample: hf mfu pwdgen 11223344556677");
1371 #define DUMP_PREFIX_LENGTH 48
1373 // Mifare Ultralight / Ultralight-C / Ultralight-EV1
1374 // Read and Dump Card Contents, using auto detection of tag size.
1375 int CmdHF14AMfUDump(const char *Cmd
){
1378 char filename
[FILE_PATH_SIZE
] = {0x00};
1379 char *fnameptr
= filename
;
1380 uint8_t *lockbytes_t
= NULL
;
1381 uint8_t lockbytes
[2] = {0x00};
1382 uint8_t *lockbytes_t2
= NULL
;
1383 uint8_t lockbytes2
[2] = {0x00};
1384 bool bit
[16] = {0x00};
1385 bool bit2
[16] = {0x00};
1386 uint8_t data
[1024] = {0x00};
1387 bool hasAuthKey
= false;
1390 bool tmplockbit
= false;
1391 uint8_t dataLen
= 0;
1393 uint8_t authenticationkey
[16] = {0x00};
1394 memset(authenticationkey
, 0x00, sizeof(authenticationkey
));
1395 uint8_t *authKeyPtr
= authenticationkey
;
1396 size_t fileNlen
= 0;
1397 bool errors
= false;
1398 bool swapEndian
= false;
1399 bool manualPages
= false;
1400 uint8_t startPage
= 0;
1403 while(param_getchar(Cmd
, cmdp
) != 0x00)
1405 switch(param_getchar(Cmd
, cmdp
))
1409 return usage_hf_mfu_dump();
1412 dataLen
= param_getstr(Cmd
, cmdp
+1, tempStr
);
1413 if (dataLen
== 32 || dataLen
== 8) { //ul-c or ev1/ntag key length
1414 errors
= param_gethex(tempStr
, 0, authenticationkey
, dataLen
);
1417 PrintAndLog("\nERROR: Key is incorrect length\n");
1430 fileNlen
= param_getstr(Cmd
, cmdp
+1, filename
);
1431 if (!fileNlen
) errors
= true;
1432 if (fileNlen
> FILE_PATH_SIZE
-5) fileNlen
= FILE_PATH_SIZE
-5;
1436 case 'P': //set start page
1437 startPage
= param_get8(Cmd
, cmdp
+1);
1443 Pages
= param_get8(Cmd
, cmdp
+1);
1448 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd
, cmdp
));
1456 if(errors
) return usage_hf_mfu_dump();
1458 //if we entered a key in little endian and set the swapEndian switch - switch it...
1459 if (swapEndian
&& hasAuthKey
)
1460 authKeyPtr
= SwapEndian64(authenticationkey
, dataLen
, (dataLen
== 16) ? 8 : 4);
1462 TagTypeUL_t tagtype
= GetHF14AMfU_Type();
1463 if (tagtype
== UL_ERROR
) return -1;
1465 if (!manualPages
) //get number of pages to read
1466 for (uint8_t idx
= 0; idx
< MAX_UL_TYPES
; idx
++)
1467 if (tagtype
& UL_TYPES_ARRAY
[idx
])
1468 Pages
= UL_MEMORY_ARRAY
[idx
]+1; //add one as maxblks starts at 0
1470 ul_print_type(tagtype
, 0);
1471 PrintAndLog("Reading tag memory...");
1472 UsbCommand c
= {CMD_MIFAREU_READCARD
, {startPage
,Pages
}};
1475 c
.arg
[2] = 1; //UL_C auth
1477 c
.arg
[2] = 2; //UL_EV1/NTAG auth
1479 memcpy(c
.d
.asBytes
, authKeyPtr
, dataLen
);
1482 clearCommandBuffer();
1485 if (!WaitForResponseTimeout(CMD_ACK
, &resp
,1500)) {
1486 PrintAndLog("Command execute time-out");
1489 if (resp
.arg
[0] != 1) {
1490 PrintAndLog("Failed reading block: (%02x)", i
);
1494 uint32_t startindex
= resp
.arg
[2];
1495 uint32_t bufferSize
= resp
.arg
[1];
1496 if (bufferSize
> sizeof(data
)) {
1497 PrintAndLog("Data exceeded Buffer size!");
1498 bufferSize
= sizeof(data
);
1500 GetFromBigBuf(data
, bufferSize
, startindex
);
1501 WaitForResponse(CMD_ACK
,NULL
);
1503 Pages
= bufferSize
/4;
1507 lockbytes_t
= data
+ 8;
1508 lockbytes
[0] = lockbytes_t
[2];
1509 lockbytes
[1] = lockbytes_t
[3];
1510 for(j
= 0; j
< 16; j
++){
1511 bit
[j
] = lockbytes
[j
/8] & ( 1 <<(7-j
%8));
1514 // Load bottom lockbytes if available
1515 // TODO -- FIGURE OUT LOCK BYTES FOR TO EV1 and/or NTAG
1516 if ( Pages
== 44 ) {
1517 lockbytes_t2
= data
+ (40*4);
1518 lockbytes2
[0] = lockbytes_t2
[2];
1519 lockbytes2
[1] = lockbytes_t2
[3];
1520 for (j
= 0; j
< 16; j
++) {
1521 bit2
[j
] = lockbytes2
[j
/8] & ( 1 <<(7-j
%8));
1525 uint8_t get_pack
[] = {0,0};
1526 iso14a_card_select_t card
;
1527 uint8_t dump_file_data
[1024+DUMP_PREFIX_LENGTH
] = {0x00};
1528 uint8_t get_version
[] = {0,0,0,0,0,0,0,0,0};
1529 uint8_t get_tearing
[] = {0,0,0};
1530 uint8_t get_counter
[] = {0,0,0};
1531 uint8_t dummy_pack
[] = {0,0};
1532 uint8_t get_signature
[32];
1533 memset( get_signature
, 0, sizeof(get_signature
) );
1535 // not ul_c and not std ul then attempt to get deeper info
1536 if (!(tagtype
& UL_C
|| tagtype
& UL
)) {
1537 //attempt to read pack
1538 if (!ul_auth_select( &card
, tagtype
, true, authKeyPtr
, get_pack
, sizeof(get_pack
))) {
1543 ul_switch_off_field();
1544 // add pack to block read
1545 memcpy(data
+ (Pages
*4) - 4, get_pack
, sizeof(get_pack
));
1547 ul_auth_select( &card
, tagtype
, hasAuthKey
, authKeyPtr
, dummy_pack
, sizeof(dummy_pack
));
1551 ulev1_getVersion( get_version
, sizeof(get_version
) );
1552 for ( uint8_t i
= 0; i
<3; ++i
) {
1553 ulev1_readTearing(i
, get_tearing
+i
, 1);
1554 ulev1_readCounter(i
, get_counter
, sizeof(get_counter
) );
1556 ul_switch_off_field();
1558 ul_auth_select( &card
, tagtype
, hasAuthKey
, authKeyPtr
, dummy_pack
, sizeof(dummy_pack
));
1561 ulev1_readSignature( get_signature
, sizeof(get_signature
));
1562 ul_switch_off_field();
1565 // format and add keys to block dump output
1567 // if we didn't swapendian before - do it now for the sprint_hex call
1568 // NOTE: default entry is bigendian (unless swapped), sprint_hex outputs little endian
1569 // need to swap to keep it the same
1571 authKeyPtr
= SwapEndian64(authenticationkey
, dataLen
, (dataLen
== 16) ? 8 : 4);
1573 authKeyPtr
= authenticationkey
;
1576 if (tagtype
& UL_C
){ //add 4 pages
1577 memcpy(data
+ Pages
*4, authKeyPtr
, dataLen
);
1579 } else { // 2nd page from end
1580 memcpy(data
+ (Pages
*4) - 8, authenticationkey
, dataLen
);
1584 //add *special* blocks to dump
1586 memcpy(dump_file_data
, get_version
, sizeof(get_version
));
1588 memcpy(dump_file_data
+10, get_tearing
, sizeof(get_tearing
));
1590 memcpy(dump_file_data
+13, get_pack
, sizeof(get_pack
));
1592 memcpy(dump_file_data
+16, get_signature
, sizeof(get_signature
));
1593 //add regular block read data to dump
1594 memcpy(dump_file_data
+DUMP_PREFIX_LENGTH
, data
, Pages
*4);
1596 PrintAndLog("\n*Special* block data:");
1597 PrintAndLog("\nDataType| Data | | Ascii");
1598 PrintAndLog("---------------------------------");
1599 PrintAndLog("GetVer-1| %s| | %s", sprint_hex(dump_file_data
, 4), sprint_ascii(dump_file_data
, 4));
1600 PrintAndLog("GetVer-2| %s| | %s", sprint_hex(dump_file_data
+4, 4), sprint_ascii(dump_file_data
+4,4));
1601 PrintAndLog("TBD | 00 00 | | ");
1602 PrintAndLog("Tearing | %s| | %s", sprint_hex(dump_file_data
+10, 3), sprint_ascii(dump_file_data
+10,3) );
1603 PrintAndLog("Pack | %s | | %s", sprint_hex(dump_file_data
+13, 2), sprint_ascii(dump_file_data
+13,2) );
1604 PrintAndLog("TBD | 00 | | ");
1605 PrintAndLog("Sig-1 | %s| | %s", sprint_hex(dump_file_data
+16, 4), sprint_ascii(dump_file_data
+16,4));
1606 PrintAndLog("Sig-2 | %s| | %s", sprint_hex(dump_file_data
+20, 4), sprint_ascii(dump_file_data
+20,4));
1607 PrintAndLog("Sig-3 | %s| | %s", sprint_hex(dump_file_data
+24, 4), sprint_ascii(dump_file_data
+24,4));
1608 PrintAndLog("Sig-4 | %s| | %s", sprint_hex(dump_file_data
+28, 4), sprint_ascii(dump_file_data
+28,4));
1609 PrintAndLog("Sig-5 | %s| | %s", sprint_hex(dump_file_data
+32, 4), sprint_ascii(dump_file_data
+32,4));
1610 PrintAndLog("Sig-6 | %s| | %s", sprint_hex(dump_file_data
+36, 4), sprint_ascii(dump_file_data
+36,4));
1611 PrintAndLog("Sig-7 | %s| | %s", sprint_hex(dump_file_data
+40, 4), sprint_ascii(dump_file_data
+40,4));
1612 PrintAndLog("Sig-8 | %s| | %s", sprint_hex(dump_file_data
+44, 4), sprint_ascii(dump_file_data
+44,4));
1613 PrintAndLog("\nBlock# | Data |lck| Ascii");
1614 PrintAndLog("---------------------------------");
1615 for (i
= 0; i
< Pages
; ++i
) {
1617 PrintAndLog("%02d/0x%02X | %s| | %s", i
+startPage
, i
+startPage
, sprint_hex(data
+ i
* 4, 4), sprint_ascii(data
+ i
* 4,4) );
1621 case 3: tmplockbit
= bit
[4]; break;
1622 case 4: tmplockbit
= bit
[3]; break;
1623 case 5: tmplockbit
= bit
[2]; break;
1624 case 6: tmplockbit
= bit
[1]; break;
1625 case 7: tmplockbit
= bit
[0]; break;
1626 case 8: tmplockbit
= bit
[15]; break;
1627 case 9: tmplockbit
= bit
[14]; break;
1628 case 10: tmplockbit
= bit
[13]; break;
1629 case 11: tmplockbit
= bit
[12]; break;
1630 case 12: tmplockbit
= bit
[11]; break;
1631 case 13: tmplockbit
= bit
[10]; break;
1632 case 14: tmplockbit
= bit
[9]; break;
1633 case 15: tmplockbit
= bit
[8]; break;
1637 case 19: tmplockbit
= bit2
[6]; break;
1641 case 23: tmplockbit
= bit2
[5]; break;
1645 case 27: tmplockbit
= bit2
[4]; break;
1649 case 31: tmplockbit
= bit2
[2]; break;
1653 case 35: tmplockbit
= bit2
[1]; break;
1657 case 39: tmplockbit
= bit2
[0]; break;
1658 case 40: tmplockbit
= bit2
[12]; break;
1659 case 41: tmplockbit
= bit2
[11]; break;
1660 case 42: tmplockbit
= bit2
[10]; break; //auth0
1661 case 43: tmplockbit
= bit2
[9]; break; //auth1
1664 PrintAndLog("%02d/0x%02X | %s| %d | %s", i
+startPage
, i
+startPage
, sprint_hex(data
+ i
* 4, 4), tmplockbit
, sprint_ascii(data
+ i
* 4,4));
1666 PrintAndLog("---------------------------------");
1668 // user supplied filename?
1670 // UID = data 0-1-2 4-5-6-7 (skips a beat)
1671 sprintf(fnameptr
,"%02X%02X%02X%02X%02X%02X%02X.bin",
1672 data
[0],data
[1], data
[2], data
[4],data
[5],data
[6], data
[7]);
1674 sprintf(fnameptr
+ fileNlen
,".bin");
1677 if ((fout
= fopen(filename
,"wb")) == NULL
) {
1678 PrintAndLog("Could not create file name %s", filename
);
1681 fwrite( dump_file_data
, 1, Pages
*4 + DUMP_PREFIX_LENGTH
, fout
);
1686 PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages
+(DUMP_PREFIX_LENGTH
/4), Pages
*4 + DUMP_PREFIX_LENGTH
, filename
);
1690 //-------------------------------------------------------------------------------
1691 // Ultralight C Methods
1692 //-------------------------------------------------------------------------------
1695 // Ultralight C Authentication Demo {currently uses hard-coded key}
1697 int CmdHF14AMfucAuth(const char *Cmd
){
1700 bool errors
= false;
1702 char cmdp
= param_getchar(Cmd
, 0);
1704 //Change key to user defined one
1705 if (cmdp
== 'k' || cmdp
== 'K'){
1706 keyNo
= param_get8(Cmd
, 1);
1707 if(keyNo
>= KEYS_3DES_COUNT
)
1711 if (cmdp
== 'h' || cmdp
== 'H') errors
= true;
1713 if (errors
) return usage_hf_mfu_ucauth();
1715 uint8_t *key
= default_3des_keys
[keyNo
];
1716 if (ulc_authentication(key
, true))
1717 PrintAndLog("Authentication successful. 3des key: %s",sprint_hex(key
, 16));
1719 PrintAndLog("Authentication failed");
1725 A test function to validate that the polarssl-function works the same
1726 was as the openssl-implementation.
1727 Commented out, since it requires openssl
1729 int CmdTestDES(const char * cmd)
1731 uint8_t key[16] = {0x00};
1733 memcpy(key,key3_3des_data,16);
1734 DES_cblock RndA, RndB;
1736 PrintAndLog("----------OpenSSL DES implementation----------");
1738 uint8_t e_RndB[8] = {0x00};
1739 unsigned char RndARndB[16] = {0x00};
1741 DES_cblock iv = { 0 };
1742 DES_key_schedule ks1,ks2;
1743 DES_cblock key1,key2;
1745 memcpy(key,key3_3des_data,16);
1747 memcpy(key2,key+8,8);
1750 DES_set_key((DES_cblock *)key1,&ks1);
1751 DES_set_key((DES_cblock *)key2,&ks2);
1753 DES_random_key(&RndA);
1754 PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
1755 PrintAndLog(" e_RndB:%s",sprint_hex(e_RndB, 8));
1756 //void DES_ede2_cbc_encrypt(const unsigned char *input,
1757 // unsigned char *output, long length, DES_key_schedule *ks1,
1758 // DES_key_schedule *ks2, DES_cblock *ivec, int enc);
1759 DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
1761 PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
1763 memcpy(RndARndB,RndA,8);
1764 memcpy(RndARndB+8,RndB,8);
1765 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
1766 DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
1767 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
1770 PrintAndLog("----------PolarSSL implementation----------");
1772 uint8_t random_a[8] = { 0 };
1773 uint8_t enc_random_a[8] = { 0 };
1774 uint8_t random_b[8] = { 0 };
1775 uint8_t enc_random_b[8] = { 0 };
1776 uint8_t random_a_and_b[16] = { 0 };
1777 des3_context ctx = { 0 };
1779 memcpy(random_a, RndA,8);
1781 uint8_t output[8] = { 0 };
1782 uint8_t iv[8] = { 0 };
1784 PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
1785 PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
1787 des3_set2key_dec(&ctx, key);
1789 des3_crypt_cbc(&ctx // des3_context *ctx
1790 , DES_DECRYPT // int mode
1791 , sizeof(random_b) // size_t length
1792 , iv // unsigned char iv[8]
1793 , enc_random_b // const unsigned char *input
1794 , random_b // unsigned char *output
1797 PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
1800 memcpy(random_a_and_b ,random_a,8);
1801 memcpy(random_a_and_b+8,random_b,8);
1803 PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
1805 des3_set2key_enc(&ctx, key);
1807 des3_crypt_cbc(&ctx // des3_context *ctx
1808 , DES_ENCRYPT // int mode
1809 , sizeof(random_a_and_b) // size_t length
1810 , enc_random_b // unsigned char iv[8]
1811 , random_a_and_b // const unsigned char *input
1812 , random_a_and_b // unsigned char *output
1815 PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
1822 // Mifare Ultralight C - Set password
1824 int CmdHF14AMfucSetPwd(const char *Cmd
){
1826 uint8_t pwd
[16] = {0x00};
1827 char cmdp
= param_getchar(Cmd
, 0);
1829 if (strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_mfu_ucsetpwd();
1831 if (param_gethex(Cmd
, 0, pwd
, 32)) {
1832 PrintAndLog("Password must include 32 HEX symbols");
1836 UsbCommand c
= {CMD_MIFAREUC_SETPWD
};
1837 memcpy( c
.d
.asBytes
, pwd
, 16);
1838 clearCommandBuffer();
1842 if (WaitForResponseTimeout(CMD_ACK
,&resp
,1500) ) {
1843 if ( (resp
.arg
[0] & 0xff) == 1) {
1844 PrintAndLog("Ultralight-C new password: %s", sprint_hex(pwd
,16));
1846 PrintAndLog("Failed writing at block %d", resp
.arg
[1] & 0xff);
1850 PrintAndLog("command execution time out");
1857 // Magic UL / UL-C tags - Set UID
1859 int CmdHF14AMfucSetUid(const char *Cmd
){
1863 uint8_t uid
[7] = {0x00};
1864 char cmdp
= param_getchar(Cmd
, 0);
1866 if (strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_mfu_ucsetuid();
1868 if (param_gethex(Cmd
, 0, uid
, 14)) {
1869 PrintAndLog("UID must include 14 HEX symbols");
1874 c
.cmd
= CMD_MIFAREU_READBL
;
1876 clearCommandBuffer();
1878 if (!WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1879 PrintAndLog("Command execute timeout");
1884 uint8_t oldblock2
[4] = {0x00};
1885 memcpy(resp
.d
.asBytes
, oldblock2
, 4);
1888 c
.cmd
= CMD_MIFAREU_WRITEBL
;
1890 c
.d
.asBytes
[0] = uid
[0];
1891 c
.d
.asBytes
[1] = uid
[1];
1892 c
.d
.asBytes
[2] = uid
[2];
1893 c
.d
.asBytes
[3] = 0x88 ^ uid
[0] ^ uid
[1] ^ uid
[2];
1894 clearCommandBuffer();
1896 if (!WaitForResponseTimeout(CMD_ACK
,&resp
,1500)) {
1897 PrintAndLog("Command execute timeout");
1903 c
.d
.asBytes
[0] = uid
[3];
1904 c
.d
.asBytes
[1] = uid
[4];
1905 c
.d
.asBytes
[2] = uid
[5];
1906 c
.d
.asBytes
[3] = uid
[6];
1907 clearCommandBuffer();
1909 if (!WaitForResponseTimeout(CMD_ACK
,&resp
,1500) ) {
1910 PrintAndLog("Command execute timeout");
1916 c
.d
.asBytes
[0] = uid
[3] ^ uid
[4] ^ uid
[5] ^ uid
[6];
1917 c
.d
.asBytes
[1] = oldblock2
[1];
1918 c
.d
.asBytes
[2] = oldblock2
[2];
1919 c
.d
.asBytes
[3] = oldblock2
[3];
1920 clearCommandBuffer();
1922 if (!WaitForResponseTimeout(CMD_ACK
,&resp
,1500) ) {
1923 PrintAndLog("Command execute timeout");
1930 int CmdHF14AMfuGenDiverseKeys(const char *Cmd
){
1933 char cmdp
= param_getchar(Cmd
, 0);
1934 if (strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_mfu_gendiverse();
1936 if (param_gethex(Cmd
, 0, uid
, 8)) {
1937 PrintAndLog("UID must include 8 HEX symbols");
1941 uint8_t iv
[8] = { 0x00 };
1942 uint8_t block
= 0x01;
1944 uint8_t mifarekeyA
[] = { 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5 };
1945 uint8_t mifarekeyB
[] = { 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5 };
1946 uint8_t dkeyA
[8] = { 0x00 };
1947 uint8_t dkeyB
[8] = { 0x00 };
1949 uint8_t masterkey
[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
1951 uint8_t mix
[8] = { 0x00 };
1952 uint8_t divkey
[8] = { 0x00 };
1954 memcpy(mix
, mifarekeyA
, 4);
1956 mix
[4] = mifarekeyA
[4] ^ uid
[0];
1957 mix
[5] = mifarekeyA
[5] ^ uid
[1];
1958 mix
[6] = block
^ uid
[2];
1961 des3_context ctx
= { 0x00 };
1962 des3_set2key_enc(&ctx
, masterkey
);
1964 des3_crypt_cbc(&ctx
// des3_context
1965 , DES_ENCRYPT
// int mode
1966 , sizeof(mix
) // length
1972 PrintAndLog("-- 3DES version");
1973 PrintAndLog("Masterkey :\t %s", sprint_hex(masterkey
,sizeof(masterkey
)));
1974 PrintAndLog("UID :\t %s", sprint_hex(uid
, sizeof(uid
)));
1975 PrintAndLog("block :\t %0d", block
);
1976 PrintAndLog("Mifare key :\t %s", sprint_hex(mifarekeyA
, sizeof(mifarekeyA
)));
1977 PrintAndLog("Message :\t %s", sprint_hex(mix
, sizeof(mix
)));
1978 PrintAndLog("Diversified key: %s", sprint_hex(divkey
+1, 6));
1980 for (int i
=0; i
< sizeof(mifarekeyA
); ++i
){
1981 dkeyA
[i
] = (mifarekeyA
[i
] << 1) & 0xff;
1982 dkeyA
[6] |= ((mifarekeyA
[i
] >> 7) & 1) << (i
+1);
1985 for (int i
=0; i
< sizeof(mifarekeyB
); ++i
){
1986 dkeyB
[1] |= ((mifarekeyB
[i
] >> 7) & 1) << (i
+1);
1987 dkeyB
[2+i
] = (mifarekeyB
[i
] << 1) & 0xff;
1990 uint8_t zeros
[8] = {0x00};
1991 uint8_t newpwd
[8] = {0x00};
1992 uint8_t dmkey
[24] = {0x00};
1993 memcpy(dmkey
, dkeyA
, 8);
1994 memcpy(dmkey
+8, dkeyB
, 8);
1995 memcpy(dmkey
+16, dkeyA
, 8);
1996 memset(iv
, 0x00, 8);
1998 des3_set3key_enc(&ctx
, dmkey
);
2000 des3_crypt_cbc(&ctx
// des3_context
2001 , DES_ENCRYPT
// int mode
2002 , sizeof(newpwd
) // length
2008 PrintAndLog("\n-- DES version");
2009 PrintAndLog("Mifare dkeyA :\t %s", sprint_hex(dkeyA
, sizeof(dkeyA
)));
2010 PrintAndLog("Mifare dkeyB :\t %s", sprint_hex(dkeyB
, sizeof(dkeyB
)));
2011 PrintAndLog("Mifare ABA :\t %s", sprint_hex(dmkey
, sizeof(dmkey
)));
2012 PrintAndLog("Mifare Pwd :\t %s", sprint_hex(newpwd
, sizeof(newpwd
)));
2014 // next. from the diversify_key method.
2018 int CmdHF14AMfUeLoad(const char *Cmd
) {
2019 char ctmp
= param_getchar(Cmd
, 0);
2020 if ( ctmp
== 'h' || ctmp
== 'H' || ctmp
== 0x00) return usage_hf_mfu_eload();
2021 return CmdHF14AMfELoad(Cmd
);
2024 int CmdHF14AMfUSim(const char *Cmd
) {
2025 char ctmp
= param_getchar(Cmd
, 0);
2026 if ( ctmp
== 'h' || ctmp
== 'H' || ctmp
== 0x00) return usage_hf_mfu_sim();
2027 return CmdHF14ASim(Cmd
);
2030 int CmdHF14AMfuPwdGen(const char *Cmd
){
2031 uint8_t uid
[7] = {0x00};
2032 char cmdp
= param_getchar(Cmd
, 0);
2033 if (strlen(Cmd
) == 0 || cmdp
== 'h' || cmdp
== 'H') return usage_hf_mfu_pwdgen();
2035 if (param_gethex(Cmd
, 0, uid
, 14)) return usage_hf_mfu_pwdgen();
2037 PrintAndLog(" algo | pwd | pack");
2038 PrintAndLog("------+----------+-----");
2039 PrintAndLog(" EV1 | %08X | %04X", ul_ev1_pwdgenA(uid
), ul_ev1_packgenA(uid
));
2040 PrintAndLog(" Ami | %08X | %04X", ul_ev1_pwdgenB(uid
), ul_ev1_packgenB(uid
));
2041 PrintAndLog(" LD | %08X | %04X", ul_ev1_pwdgenC(uid
), ul_ev1_packgenC(uid
));
2044 //------------------------------------
2046 //------------------------------------
2047 static command_t CommandTable
[] =
2049 {"help", CmdHelp
, 1, "This help"},
2050 {"dbg", CmdHF14AMfDbg
, 0, "Set default debug mode"},
2051 {"info", CmdHF14AMfUInfo
, 0, "Tag information"},
2052 {"dump", CmdHF14AMfUDump
, 0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"},
2053 {"eload", CmdHF14AMfUeLoad
, 0, "load Ultralight .eml dump file into emulator memory"},
2054 {"rdbl", CmdHF14AMfURdBl
, 0, "Read block"},
2055 {"wrbl", CmdHF14AMfUWrBl
, 0, "Write block"},
2056 {"cauth", CmdHF14AMfucAuth
, 0, "Authentication - Ultralight C"},
2057 {"setpwd", CmdHF14AMfucSetPwd
, 0, "Set 3des password - Ultralight-C"},
2058 {"setuid", CmdHF14AMfucSetUid
, 0, "Set UID - MAGIC tags only"},
2059 {"sim", CmdHF14AMfUSim
, 0, "Simulate Ultralight from emulator memory"},
2060 {"gen", CmdHF14AMfuGenDiverseKeys
, 1, "Generate 3des mifare diversified keys"},
2061 {"pwdgen", CmdHF14AMfuPwdGen
, 1, "Generate pwd from known algos"},
2062 {NULL
, NULL
, 0, NULL
}
2065 int CmdHFMFUltra(const char *Cmd
){
2066 clearCommandBuffer();
2067 //WaitForResponseTimeout(CMD_ACK,NULL,100);
2068 CmdsParse(CommandTable
, Cmd
);
2072 int CmdHelp(const char *Cmd
){
2073 CmdsHelp(CommandTable
);