]> cvs.zerfleddert.de Git - proxmark3-svn/blame_incremental - client/cmdhfmfu.c
CHG: Now it prints the correct UID bytes etc.
[proxmark3-svn] / client / cmdhfmfu.c
... / ...
CommitLineData
1//-----------------------------------------------------------------------------
2// Ultralight Code (c) 2013,2014 Midnitesnake & Andy Davies of Pentura
3//
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
6// the license.
7//-----------------------------------------------------------------------------
8// High frequency MIFARE ULTRALIGHT (C) commands
9//-----------------------------------------------------------------------------
10#include "loclass/des.h"
11#include "cmdhfmfu.h"
12#include "cmdhfmf.h"
13#include "cmdhf14a.h"
14#include "mifare.h"
15#include "util.h"
16#include "protocols.h"
17#include "data.h"
18
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
32
33#define KEYS_3DES_COUNT 7
34uint8_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
42};
43
44#define KEYS_PWD_COUNT 1
45uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = {
46 {0xFF,0xFF,0xFF,0xFF}, // PACK 0x00,0x00 -- factory default
47};
48
49#define MAX_UL_TYPES 18
50uint32_t UL_TYPES_ARRAY[MAX_UL_TYPES] = {
51 UNKNOWN, UL, UL_C,
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};
57
58uint8_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};
65
66// Certain pwd generation algo nickname A.
67uint32_t ul_ev1_pwdgenA(uint8_t* uid) {
68
69 uint8_t pos = (uid[3] ^ uid[4] ^ uid[5] ^ uid[6]) % 32;
70
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
76 };
77
78 uint8_t entry[] = {0x00,0x00,0x00,0x00};
79 uint8_t pwd[] = {0x00,0x00,0x00,0x00};
80
81 num_to_bytes( xortable[pos], 4, entry);
82
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];
87
88 return (uint32_t)bytes_to_num(pwd, 4);
89}
90
91// Certain pwd generation algo nickname B. (very simple)
92uint32_t ul_ev1_pwdgenB(uint8_t* uid) {
93
94 uint8_t pwd[] = {0x00,0x00,0x00,0x00};
95
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);
101}
102
103// Certain pwd generation algo nickname C.
104uint32_t ul_ev1_pwdgenC(uint8_t* uid){
105 uint32_t pwd = 0;
106 uint8_t base[] = {
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
111 };
112
113 memcpy(base, uid, 7);
114
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;
118 }
119 return BSWAP_32(pwd);
120}
121
122// pack generation for algo 1-3
123uint16_t ul_ev1_packgenA(uint8_t* uid){
124 uint16_t pack = (uid[0] ^ uid[1] ^ uid[2]) << 8 | (uid[2] ^ 8);
125 return pack;
126}
127uint16_t ul_ev1_packgenB(uint8_t* uid){
128 return 0x8080;
129}
130uint16_t ul_ev1_packgenC(uint8_t* uid){
131 return 0xaa55;
132}
133
134
135void ul_ev1_pwdgen_selftest(){
136
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<-");
140
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<--");
144
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<--");
148 return;
149}
150
151static int CmdHelp(const char *Cmd);
152
153// get version nxp product type
154char *getProductTypeStr( uint8_t id){
155
156 static char buf[20];
157 char *retStr = buf;
158
159 switch(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;
163 }
164 return buf;
165}
166
167/*
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).
171*/
172char *getUlev1CardSizeStr( uint8_t fsize ){
173
174 static char buf[40];
175 char *retStr = buf;
176 memset(buf, 0, sizeof(buf));
177
178 uint16_t usize = 1 << ((fsize >>1) + 1);
179 uint16_t lsize = 1 << (fsize >>1);
180
181 // is LSB set?
182 if ( fsize & 1 )
183 sprintf(retStr, "%02X, (%u <-> %u bytes)",fsize, usize, lsize);
184 else
185 sprintf(retStr, "%02X, (%u bytes)", fsize, lsize);
186 return buf;
187}
188
189static void ul_switch_on_field(void) {
190 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
191 clearCommandBuffer();
192 SendCommand(&c);
193}
194
195void ul_switch_off_field(void) {
196 UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
197 clearCommandBuffer();
198 SendCommand(&c);
199}
200
201static 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();
205 SendCommand(&c);
206 UsbCommand resp;
207 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
208 if (!resp.arg[0] && responseLength) return -1;
209
210 uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
211 memcpy(response, resp.d.asBytes, resplen);
212 return resplen;
213}
214
215static int ul_select( iso14a_card_select_t *card ){
216
217 ul_switch_on_field();
218
219 UsbCommand resp;
220 bool ans = false;
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();
225 return 0;
226 }
227
228 memcpy(card, resp.d.asBytes, sizeof(iso14a_card_select_t));
229 return 1;
230}
231
232// This read command will at least return 16bytes.
233static int ul_read( uint8_t page, uint8_t *response, uint16_t responseLength ){
234
235 uint8_t cmd[] = {ISO14443A_CMD_READBLOCK, page};
236 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
237 return len;
238}
239
240static int ul_comp_write( uint8_t page, uint8_t *data, uint8_t datalen ){
241
242 uint8_t cmd[18];
243 memset(cmd, 0x00, sizeof(cmd));
244 datalen = ( datalen > 16) ? 16 : datalen;
245
246 cmd[0] = ISO14443A_CMD_WRITEBLOCK;
247 cmd[1] = page;
248 memcpy(cmd+2, data, datalen);
249
250 uint8_t response[1] = {0xff};
251 ul_send_cmd_raw(cmd, 2+datalen, response, sizeof(response));
252 // ACK
253 if ( response[0] == 0x0a ) return 0;
254 // NACK
255 return -1;
256}
257
258static int ulc_requestAuthentication( uint8_t *nonce, uint16_t nonceLength ){
259
260 uint8_t cmd[] = {MIFARE_ULC_AUTH_1, 0x00};
261 int len = ul_send_cmd_raw(cmd, sizeof(cmd), nonce, nonceLength);
262 return len;
263}
264
265static int ulc_authentication( uint8_t *key, bool switch_off_field ){
266
267 UsbCommand c = {CMD_MIFAREUC_AUTH, {switch_off_field}};
268 memcpy(c.d.asBytes, key, 16);
269 clearCommandBuffer();
270 SendCommand(&c);
271 UsbCommand resp;
272 if ( !WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) return 0;
273 if ( resp.arg[0] == 1 ) return 1;
274
275 return 0;
276}
277
278static int ulev1_requestAuthentication( uint8_t *pwd, uint8_t *pack, uint16_t packLength ){
279
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);
282 return len;
283}
284
285static 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");
290 return 0;
291 }
292 } else {
293 if ( !ul_select(card) ) return 0;
294
295 if (hasAuthKey) {
296 if (ulev1_requestAuthentication(authenticationkey, pack, packSize) < 2) {
297 ul_switch_off_field();
298 PrintAndLog("Error: Authentication Failed UL-EV1/NTAG");
299 return 0;
300 }
301 }
302 }
303 return 1;
304}
305
306static int ulev1_getVersion( uint8_t *response, uint16_t responseLength ){
307
308 uint8_t cmd[] = {MIFARE_ULEV1_VERSION};
309 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
310 return len;
311}
312
313static int ulev1_readCounter( uint8_t counter, uint8_t *response, uint16_t responseLength ){
314
315 uint8_t cmd[] = {MIFARE_ULEV1_READ_CNT, counter};
316 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
317 return len;
318}
319
320static int ulev1_readTearing( uint8_t counter, uint8_t *response, uint16_t responseLength ){
321
322 uint8_t cmd[] = {MIFARE_ULEV1_CHECKTEAR, counter};
323 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
324 return len;
325}
326
327static int ulev1_readSignature( uint8_t *response, uint16_t responseLength ){
328
329 uint8_t cmd[] = {MIFARE_ULEV1_READSIG, 0x00};
330 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
331 return len;
332}
333
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:
337// send a0 + crc
338// UL responds with 00, fudan doesn't respond
339// or
340// send a200 + crc
341// UL doesn't respond, fudan responds with 00
342// or
343// send 300000 + crc (read with extra byte(s))
344// UL responds with read of page 0, fudan doesn't respond.
345//
346// make sure field is off before calling this function
347static int ul_fudan_check( void ){
348 iso14a_card_select_t card;
349 if ( !ul_select(&card) )
350 return UL_ERROR;
351
352 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT, 4, 0}};
353
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();
357 SendCommand(&c);
358 UsbCommand resp;
359 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return UL_ERROR;
360 if (resp.arg[0] != 1) return UL_ERROR;
361
362 return (!resp.d.asBytes[0]) ? FUDAN_UL : UL; //if response == 0x00 then Fudan, else Genuine NXP
363}
364
365static int ul_print_default( uint8_t *data){
366
367 uint8_t uid[7];
368 uid[0] = data[0];
369 uid[1] = data[1];
370 uid[2] = data[2];
371 uid[3] = data[4];
372 uid[4] = data[5];
373 uid[5] = data[6];
374 uid[6] = data[7];
375
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
380 switch (chip){
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
384 }
385 }
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]);
390 else
391 PrintAndLog(" BCC0 : %02X, crc should be %02X", data[3], crc0);
392
393 int crc1 = data[4] ^ data[5] ^ data[6] ^data[7];
394 if ( data[8] == crc1 )
395 PrintAndLog(" BCC1 : %02X, Ok", data[8]);
396 else
397 PrintAndLog(" BCC1 : %02X, crc should be %02X", data[8], crc1 );
398
399 PrintAndLog(" Internal : %02X, %sdefault", data[9], (data[9]==0x48)?"":"not " );
400
401 PrintAndLog(" Lock : %s - %s",
402 sprint_hex(data+10, 2),
403 sprint_bin(data+10, 2)
404 );
405
406 PrintAndLog("OneTimePad : %s - %s\n",
407 sprint_hex(data + 12, 4),
408 sprint_bin(data+12, 4)
409 );
410
411 return 0;
412}
413
414static int ndef_print_CC(uint8_t *data) {
415 // no NDEF message
416 if(data[0] != 0xe1)
417 return -1;
418
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);
432
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)");
436 return 0;
437}
438
439int ul_print_type(uint32_t tagtype, uint8_t spaces){
440 char spc[11] = " ";
441 spc[10]=0x00;
442 char *spacer = spc + (10-spaces);
443
444 if ( tagtype & UL )
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>" : "" );
482 else
483 PrintAndLog("%sTYPE : Unknown %06x", spacer, tagtype);
484 return 0;
485}
486
487static int ulc_print_3deskey( uint8_t *data){
488 PrintAndLog(" deskey1 [44/0x2C] : %s [%.4s]", sprint_hex(data ,4),data);
489 PrintAndLog(" deskey1 [45/0x2D] : %s [%.4s]", sprint_hex(data+4 ,4),data+4);
490 PrintAndLog(" deskey2 [46/0x2E] : %s [%.4s]", sprint_hex(data+8 ,4),data+8);
491 PrintAndLog(" deskey2 [47/0x2F] : %s [%.4s]", sprint_hex(data+12,4),data+12);
492 PrintAndLog("\n 3des key : %s", sprint_hex(SwapEndian64(data, 16, 8), 16));
493 return 0;
494}
495
496static int ulc_print_configuration( uint8_t *data){
497
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));
501
502 bool validAuth = (data[8] >= 0x03 && data[8] <= 0x30);
503 if ( validAuth )
504 PrintAndLog(" Auth0 [42/0x2A] : %s page %d/0x%02X and above need authentication", sprint_hex(data+8, 4), data[8],data[8] );
505 else{
506 if ( data[8] == 0){
507 PrintAndLog(" Auth0 [42/0x2A] : %s default", sprint_hex(data+8, 4) );
508 } else {
509 PrintAndLog(" Auth0 [42/0x2A] : %s auth byte is out-of-range", sprint_hex(data+8, 4) );
510 }
511 }
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"
515 );
516 return 0;
517}
518
519static int ulev1_print_configuration( uint8_t *data, uint8_t startPage){
520
521 PrintAndLog("\n--- Tag Configuration");
522
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];
530
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]);
534 else
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) );
538 if ( authlim == 0)
539 PrintAndLog(" - Unlimited password attempts");
540 else
541 PrintAndLog(" - Max number of password attempts is %d", authlim);
542
543 PrintAndLog(" - NFC counter %s", (nfc_cnf_en) ? "enabled":"disabled");
544 PrintAndLog(" - NFC counter %s", (nfc_cnf_prot_pwd) ? "not protected":"password protection enabled");
545
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));
552 return 0;
553}
554
555static int ulev1_print_counters(){
556 PrintAndLog("--- Tag Counters");
557 uint8_t tear[1] = {0};
558 uint8_t counter[3] = {0,0,0};
559 uint16_t len = 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) );
563 if (len == 3) {
564 PrintAndLog(" [%0d] : %s", i, sprint_hex(counter,3));
565 PrintAndLog(" - %02X tearing %s", tear[0], ( tear[0]==0xBD)?"Ok":"failure");
566 }
567 }
568 return len;
569}
570
571static 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");
579 return 0;
580}
581
582static 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]);
592 return 0;
593}
594
595/*
596static 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);
608 if ( !status ){
609 return UL_ERROR;
610 }
611 status = ulc_requestAuthentication(nonce1, sizeof(nonce1));
612 if ( status > 0 ) {
613 status = ulc_requestAuthentication(nonce2, sizeof(nonce2));
614 returnValue = ( !memcmp(nonce1, nonce2, 11) ) ? UL_C_MAGIC : UL_C;
615 } else {
616 returnValue = UL;
617 }
618 ul_switch_off_field();
619 return returnValue;
620}
621*/
622static int ul_magic_test(){
623
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) )
629 return UL_ERROR;
630 int status = ul_comp_write(0, NULL, 0);
631 ul_switch_off_field();
632 if ( status == 0 )
633 return MAGIC;
634 return 0;
635}
636
637uint32_t GetHF14AMfU_Type(void){
638
639 TagTypeUL_t tagtype = UNKNOWN;
640 iso14a_card_select_t card;
641 uint8_t version[10] = {0x00};
642 int status = 0;
643 int len;
644
645 if (!ul_select(&card)) return UL_ERROR;
646
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();
651 return UL_ERROR;
652 }
653
654 if ( card.uid[0] != 0x05) {
655
656 len = ulev1_getVersion(version, sizeof(version));
657 ul_switch_off_field();
658
659 switch (len) {
660 case 0x0A: {
661
662 if ( version[2] == 0x03 && version[6] == 0x0B )
663 tagtype = UL_EV1_48;
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 )
667 tagtype = NTAG_210;
668 else if ( version[2] == 0x04 && version[3] == 0x01 && version[6] == 0x0E )
669 tagtype = NTAG_212;
670 else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x0F )
671 tagtype = NTAG_213;
672 else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x11 )
673 tagtype = NTAG_215;
674 else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x13 )
675 tagtype = NTAG_216;
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 )
681 tagtype = NTAG;
682
683 break;
684 }
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;
689 }
690 // UL vs UL-C vs ntag203 test
691 if (tagtype & (UL | UL_C | NTAG_203)) {
692 if ( !ul_select(&card) ) return UL_ERROR;
693
694 // do UL_C check first...
695 uint8_t nonce[11] = {0x00};
696 status = ulc_requestAuthentication(nonce, sizeof(nonce));
697 ul_switch_off_field();
698 if (status > 1) {
699 tagtype = UL_C;
700 } else {
701 // need to re-select after authentication error
702 if ( !ul_select(&card) ) return UL_ERROR;
703
704 uint8_t data[16] = {0x00};
705 // read page 0x26-0x29 (last valid ntag203 page)
706 status = ul_read(0x26, data, sizeof(data));
707 if ( status <= 1 ) {
708 tagtype = UL;
709 } else {
710 // read page 0x30 (should error if it is a ntag203)
711 status = ul_read(0x30, data, sizeof(data));
712 if ( status <= 1 ){
713 tagtype = NTAG_203;
714 } else {
715 tagtype = UNKNOWN;
716 }
717 }
718 ul_switch_off_field();
719 }
720 }
721 if (tagtype & UL) {
722 tagtype = ul_fudan_check();
723 ul_switch_off_field();
724 }
725 } else {
726 ul_switch_off_field();
727 // Infinition MY-D tests Exam high nibble
728 uint8_t nib = (card.uid[1] & 0xf0) >> 4;
729 switch ( nib ){
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
735 }
736 }
737
738 tagtype |= ul_magic_test();
739 if (tagtype == (UNKNOWN | MAGIC)) tagtype = (UL_MAGIC);
740 return tagtype;
741}
742
743int CmdHF14AMfUInfo(const char *Cmd){
744
745 uint8_t authlim = 0xff;
746 uint8_t data[16] = {0x00};
747 iso14a_card_select_t card;
748 int status;
749 bool errors = false;
750 bool hasAuthKey = false;
751 bool locked = false;
752 bool swapEndian = false;
753 uint8_t cmdp = 0;
754 uint8_t dataLen = 0;
755 uint8_t authenticationkey[16] = {0x00};
756 uint8_t *authkeyptr = authenticationkey;
757 uint8_t pwd[4] = {0,0,0,0};
758 uint8_t *key = pwd;
759 uint8_t pack[4] = {0,0,0,0};
760 int len = 0;
761 char tempStr[50];
762
763 while(param_getchar(Cmd, cmdp) != 0x00)
764 {
765 switch(param_getchar(Cmd, cmdp))
766 {
767 case 'h':
768 case 'H':
769 return usage_hf_mfu_info();
770 case 'k':
771 case 'K':
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
776 } else {
777 PrintAndLog("\nERROR: Key is incorrect length\n");
778 errors = true;
779 }
780 cmdp += 2;
781 hasAuthKey = true;
782 break;
783 case 'l':
784 case 'L':
785 swapEndian = true;
786 cmdp++;
787 break;
788 default:
789 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
790 errors = true;
791 break;
792 }
793 if(errors) break;
794 }
795
796 //Validations
797 if(errors) return usage_hf_mfu_info();
798
799 TagTypeUL_t tagtype = GetHF14AMfU_Type();
800 if (tagtype == UL_ERROR) return -1;
801
802 PrintAndLog("\n--- Tag Information ---------");
803 PrintAndLog("-------------------------------------------------------------");
804 ul_print_type(tagtype, 6);
805
806 // Swap endianness
807 if (swapEndian && hasAuthKey) authkeyptr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4 );
808
809 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
810
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");
816 return status;
817 } else if (status == 16) {
818 ul_print_default(data);
819 ndef_print_CC(data+12);
820 } else {
821 locked = true;
822 }
823
824 // UL_C Specific
825 if ((tagtype & UL_C)) {
826
827 // read pages 0x28, 0x29, 0x2A, 0x2B
828 uint8_t ulc_conf[16] = {0x00};
829 status = ul_read(0x28, ulc_conf, sizeof(ulc_conf));
830 if ( status == -1 ){
831 PrintAndLog("Error: tag didn't answer to READ UL-C");
832 ul_switch_off_field();
833 return status;
834 }
835 if (status == 16) ulc_print_configuration(ulc_conf);
836 else locked = true;
837
838 if ((tagtype & MAGIC)) {
839 //just read key
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");
845 return status;
846 }
847 if (status == 16) ulc_print_3deskey(ulc_deskey);
848
849 } else {
850 ul_switch_off_field();
851 // if we called info with key, just return
852 if ( hasAuthKey ) return 1;
853
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: ");
860 uint8_t keySwap[16];
861 memcpy(keySwap, SwapEndian64(key,16,8), 16);
862 ulc_print_3deskey(keySwap);
863 return 1;
864 }
865 }
866 return 1;
867 }
868 }
869
870 // do counters and signature first (don't neet auth)
871
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;
877 }
878 }
879
880 // Read signature
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();
887 return status;
888 }
889 if (status == 32) ulev1_print_signature( ulev1_signature, sizeof(ulev1_signature));
890 else {
891 // re-select
892 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
893 }
894 }
895
896 // Get Version
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();
903 return status;
904 } else if (status == 10) {
905 ulev1_print_version(version);
906 } else {
907 locked = true;
908 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
909 }
910
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;
917
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();
923 return status;
924 } else if (status == 16) {
925 // save AUTHENTICATION LIMITS for later:
926 authlim = (ulev1_conf[4] & 0x07);
927 ulev1_print_configuration(ulev1_conf, startconfigblock);
928 }
929 }
930
931 // AUTHLIMIT, (number of failed authentications)
932 // 0 = limitless.
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.");
937 len = 0;
938
939 // test pwd gen A
940 num_to_bytes( ul_ev1_pwdgenA(card.uid), 4, key);
941 len = ulev1_requestAuthentication(key, pack, sizeof(pack));
942 if (len >= 1) {
943 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
944 }
945 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
946
947 // test pwd gen B
948 num_to_bytes( ul_ev1_pwdgenB(card.uid), 4, key);
949 len = ulev1_requestAuthentication(key, pack, sizeof(pack));
950 if (len >= 1) {
951 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
952 }
953 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
954
955 // test pwd gen C
956 num_to_bytes( ul_ev1_pwdgenC(card.uid), 4, key);
957 len = ulev1_requestAuthentication(key, pack, sizeof(pack));
958 if (len >= 1) {
959 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
960 }
961 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
962
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));
966 if (len >= 1) {
967 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
968 break;
969 } else {
970 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
971 }
972 }
973 if (len < 1) PrintAndLog("password not known");
974 }
975 }
976
977 ul_switch_off_field();
978 if (locked) PrintAndLog("\nTag appears to be locked, try using the key to get more info");
979 PrintAndLog("");
980 return 1;
981}
982
983//
984// Write Single Block
985//
986int CmdHF14AMfUWrBl(const char *Cmd){
987
988 int blockNo = -1;
989 bool errors = false;
990 bool hasAuthKey = false;
991 bool hasPwdKey = false;
992 bool swapEndian = false;
993
994 uint8_t cmdp = 0;
995 uint8_t keylen = 0;
996 uint8_t blockdata[20] = {0x00};
997 uint8_t data[16] = {0x00};
998 uint8_t authenticationkey[16] = {0x00};
999 uint8_t *authKeyPtr = authenticationkey;
1000
1001 while(param_getchar(Cmd, cmdp) != 0x00)
1002 {
1003 switch(param_getchar(Cmd, cmdp))
1004 {
1005 case 'h':
1006 case 'H':
1007 return usage_hf_mfu_wrbl();
1008 case 'k':
1009 case 'K':
1010 // EV1/NTAG size key
1011 keylen = param_gethex(Cmd, cmdp+1, data, 8);
1012 if ( !keylen ) {
1013 memcpy(authenticationkey, data, 4);
1014 cmdp += 2;
1015 hasPwdKey = true;
1016 break;
1017 }
1018 // UL-C size key
1019 keylen = param_gethex(Cmd, cmdp+1, data, 32);
1020 if (!keylen){
1021 memcpy(authenticationkey, data, 16);
1022 cmdp += 2;
1023 hasAuthKey = true;
1024 break;
1025 }
1026 PrintAndLog("\nERROR: Key is incorrect length\n");
1027 errors = true;
1028 break;
1029 case 'b':
1030 case 'B':
1031 blockNo = param_get8(Cmd, cmdp+1);
1032 if (blockNo < 0) {
1033 PrintAndLog("Wrong block number");
1034 errors = true;
1035 }
1036 cmdp += 2;
1037 break;
1038 case 'l':
1039 case 'L':
1040 swapEndian = true;
1041 cmdp++;
1042 break;
1043 case 'd':
1044 case 'D':
1045 if ( param_gethex(Cmd, cmdp+1, blockdata, 8) ) {
1046 PrintAndLog("Block data must include 8 HEX symbols");
1047 errors = true;
1048 break;
1049 }
1050 cmdp += 2;
1051 break;
1052 default:
1053 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
1054 errors = true;
1055 break;
1056 }
1057 //Validations
1058 if(errors) return usage_hf_mfu_wrbl();
1059 }
1060
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;
1065
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];
1070 }
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();
1074 }
1075
1076 // Swap endianness
1077 if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
1078 if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
1079
1080 if ( blockNo <= 3)
1081 PrintAndLog("Special Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4));
1082 else
1083 PrintAndLog("Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4));
1084
1085 //Send write Block
1086 UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}};
1087 memcpy(c.d.asBytes,blockdata,4);
1088
1089 if ( hasAuthKey ){
1090 c.arg[1] = 1;
1091 memcpy(c.d.asBytes+4,authKeyPtr,16);
1092 }
1093 else if ( hasPwdKey ) {
1094 c.arg[1] = 2;
1095 memcpy(c.d.asBytes+4,authKeyPtr,4);
1096 }
1097
1098 clearCommandBuffer();
1099 SendCommand(&c);
1100 UsbCommand resp;
1101 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1102 uint8_t isOK = resp.arg[0] & 0xff;
1103 PrintAndLog("isOk:%02x", isOK);
1104 } else {
1105 PrintAndLog("Command execute timeout");
1106 }
1107
1108 return 0;
1109}
1110//
1111// Read Single Block
1112//
1113int CmdHF14AMfURdBl(const char *Cmd){
1114
1115 int blockNo = -1;
1116 bool errors = false;
1117 bool hasAuthKey = false;
1118 bool hasPwdKey = false;
1119 bool swapEndian = false;
1120 uint8_t cmdp = 0;
1121 uint8_t keylen = 0;
1122 uint8_t data[16] = {0x00};
1123 uint8_t authenticationkey[16] = {0x00};
1124 uint8_t *authKeyPtr = authenticationkey;
1125
1126 while(param_getchar(Cmd, cmdp) != 0x00)
1127 {
1128 switch(param_getchar(Cmd, cmdp))
1129 {
1130 case 'h':
1131 case 'H':
1132 return usage_hf_mfu_rdbl();
1133 case 'k':
1134 case 'K':
1135 // EV1/NTAG size key
1136 keylen = param_gethex(Cmd, cmdp+1, data, 8);
1137 if ( !keylen ) {
1138 memcpy(authenticationkey, data, 4);
1139 cmdp += 2;
1140 hasPwdKey = true;
1141 break;
1142 }
1143 // UL-C size key
1144 keylen = param_gethex(Cmd, cmdp+1, data, 32);
1145 if (!keylen){
1146 memcpy(authenticationkey, data, 16);
1147 cmdp += 2;
1148 hasAuthKey = true;
1149 break;
1150 }
1151 PrintAndLog("\nERROR: Key is incorrect length\n");
1152 errors = true;
1153 break;
1154 case 'b':
1155 case 'B':
1156 blockNo = param_get8(Cmd, cmdp+1);
1157 if (blockNo < 0) {
1158 PrintAndLog("Wrong block number");
1159 errors = true;
1160 }
1161 cmdp += 2;
1162 break;
1163 case 'l':
1164 case 'L':
1165 swapEndian = true;
1166 cmdp++;
1167 break;
1168 default:
1169 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
1170 errors = true;
1171 break;
1172 }
1173 //Validations
1174 if(errors) return usage_hf_mfu_rdbl();
1175 }
1176
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;
1181
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];
1186 }
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();
1190 }
1191
1192 // Swap endianness
1193 if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
1194 if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
1195
1196 //Read Block
1197 UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
1198 if ( hasAuthKey ){
1199 c.arg[1] = 1;
1200 memcpy(c.d.asBytes,authKeyPtr,16);
1201 }
1202 else if ( hasPwdKey ) {
1203 c.arg[1] = 2;
1204 memcpy(c.d.asBytes,authKeyPtr,4);
1205 }
1206
1207 clearCommandBuffer();
1208 SendCommand(&c);
1209 UsbCommand resp;
1210 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1211 uint8_t isOK = resp.arg[0] & 0xff;
1212 if (isOK) {
1213 uint8_t *data = resp.d.asBytes;
1214 PrintAndLog("\nBlock# | Data | Ascii");
1215 PrintAndLog("-----------------------------");
1216 PrintAndLog("%02d/0x%02X | %s| %.4s\n", blockNo, blockNo, sprint_hex(data, 4), data);
1217 }
1218 else {
1219 PrintAndLog("Failed reading block: (%02x)", isOK);
1220 }
1221 } else {
1222 PrintAndLog("Command execute time-out");
1223 }
1224 return 0;
1225}
1226
1227int 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");
1238 PrintAndLog("");
1239 PrintAndLog(" sample : hf mfu info");
1240 PrintAndLog(" : hf mfu info k 00112233445566778899AABBCCDDEEFF");
1241 PrintAndLog(" : hf mfu info k AABBCCDDD");
1242 return 0;
1243}
1244
1245int 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");
1257 PrintAndLog("");
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");
1262 return 0;
1263}
1264
1265int 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");
1272 PrintAndLog("");
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");
1276 return 0;
1277}
1278
1279int 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");
1287 PrintAndLog("");
1288 PrintAndLog(" sample : hf mfu wrbl b 0 d 01234567");
1289 PrintAndLog(" : hf mfu wrbl b 0 d 01234567 k AABBCCDDD\n");
1290 return 0;
1291}
1292
1293int 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)");
1302 PrintAndLog("");
1303 PrintAndLog(" sample: hf mfu eload u filename");
1304 PrintAndLog(" hf mfu eload u filename 57");
1305 return 0;
1306}
1307
1308int 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");
1318
1319 return 0;
1320}
1321
1322int 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");
1333 return 0;
1334}
1335
1336int usage_hf_mfu_ucsetpwd(void) {
1337 PrintAndLog("Usage: hf mfu setpwd <password (32 hex symbols)>");
1338 PrintAndLog(" [password] - (32 hex symbols)");
1339 PrintAndLog("");
1340 PrintAndLog("sample: hf mfu setpwd 000102030405060708090a0b0c0d0e0f");
1341 PrintAndLog("");
1342 return 0;
1343}
1344
1345int 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.");
1349 PrintAndLog("");
1350 PrintAndLog("sample: hf mfu setuid 11223344556677");
1351 PrintAndLog("");
1352 return 0;
1353}
1354
1355int usage_hf_mfu_gendiverse(void){
1356 PrintAndLog("Usage: hf mfu gen <uid (8 hex symbols)>");
1357 PrintAndLog("");
1358 PrintAndLog("sample: hf mfu gen 11223344");
1359 PrintAndLog("");
1360 return 0;
1361}
1362
1363int usage_hf_mfu_pwdgen(void){
1364 PrintAndLog("Usage: hf mfu pwdgen <uid (14 hex symbols)>");
1365 PrintAndLog("");
1366 PrintAndLog("sample: hf mfu pwdgen 11223344556677");
1367 PrintAndLog("");
1368 return 0;
1369}
1370
1371#define DUMP_PREFIX_LENGTH 48
1372//
1373// Mifare Ultralight / Ultralight-C / Ultralight-EV1
1374// Read and Dump Card Contents, using auto detection of tag size.
1375int CmdHF14AMfUDump(const char *Cmd){
1376
1377 FILE *fout;
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;
1388 int i = 0;
1389 int Pages = 16;
1390 bool tmplockbit = false;
1391 uint8_t dataLen = 0;
1392 uint8_t cmdp = 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;
1401 char tempStr[50];
1402
1403 while(param_getchar(Cmd, cmdp) != 0x00)
1404 {
1405 switch(param_getchar(Cmd, cmdp))
1406 {
1407 case 'h':
1408 case 'H':
1409 return usage_hf_mfu_dump();
1410 case 'k':
1411 case 'K':
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);
1415 dataLen /= 2;
1416 } else {
1417 PrintAndLog("\nERROR: Key is incorrect length\n");
1418 errors = true;
1419 }
1420 cmdp += 2;
1421 hasAuthKey = true;
1422 break;
1423 case 'l':
1424 case 'L':
1425 swapEndian = true;
1426 cmdp++;
1427 break;
1428 case 'n':
1429 case '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;
1433 cmdp += 2;
1434 break;
1435 case 'p':
1436 case 'P': //set start page
1437 startPage = param_get8(Cmd, cmdp+1);
1438 manualPages = true;
1439 cmdp += 2;
1440 break;
1441 case 'q':
1442 case 'Q':
1443 Pages = param_get8(Cmd, cmdp+1);
1444 cmdp += 2;
1445 manualPages = true;
1446 break;
1447 default:
1448 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
1449 errors = true;
1450 break;
1451 }
1452 if(errors) break;
1453 }
1454
1455 //Validations
1456 if(errors) return usage_hf_mfu_dump();
1457
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);
1461
1462 TagTypeUL_t tagtype = GetHF14AMfU_Type();
1463 if (tagtype == UL_ERROR) return -1;
1464
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
1469
1470 ul_print_type(tagtype, 0);
1471 PrintAndLog("Reading tag memory...");
1472 UsbCommand c = {CMD_MIFAREU_READCARD, {startPage,Pages}};
1473 if ( hasAuthKey ) {
1474 if (tagtype & UL_C)
1475 c.arg[2] = 1; //UL_C auth
1476 else
1477 c.arg[2] = 2; //UL_EV1/NTAG auth
1478
1479 memcpy(c.d.asBytes, authKeyPtr, dataLen);
1480 }
1481
1482 clearCommandBuffer();
1483 SendCommand(&c);
1484 UsbCommand resp;
1485 if (!WaitForResponseTimeout(CMD_ACK, &resp,1500)) {
1486 PrintAndLog("Command execute time-out");
1487 return 1;
1488 }
1489 if (resp.arg[0] != 1) {
1490 PrintAndLog("Failed reading block: (%02x)", i);
1491 return 1;
1492 }
1493
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);
1499 }
1500 GetFromBigBuf(data, bufferSize, startindex);
1501 WaitForResponse(CMD_ACK,NULL);
1502
1503 Pages = bufferSize/4;
1504 // Load lock bytes.
1505 int j = 0;
1506
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));
1512 }
1513
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));
1522 }
1523 }
1524
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) );
1534
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))) {
1539 //reset pack
1540 get_pack[0]=0;
1541 get_pack[1]=0;
1542 }
1543 ul_switch_off_field();
1544 // add pack to block read
1545 memcpy(data + (Pages*4) - 4, get_pack, sizeof(get_pack));
1546 if ( hasAuthKey )
1547 ul_auth_select( &card, tagtype, hasAuthKey, authKeyPtr, dummy_pack, sizeof(dummy_pack));
1548 else
1549 ul_select(&card);
1550
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) );
1555 }
1556 ul_switch_off_field();
1557 if ( hasAuthKey )
1558 ul_auth_select( &card, tagtype, hasAuthKey, authKeyPtr, dummy_pack, sizeof(dummy_pack));
1559 else
1560 ul_select(&card);
1561 ulev1_readSignature( get_signature, sizeof(get_signature));
1562 ul_switch_off_field();
1563 }
1564
1565 // format and add keys to block dump output
1566 if (hasAuthKey) {
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
1570 if (!swapEndian){
1571 authKeyPtr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4);
1572 } else {
1573 authKeyPtr = authenticationkey;
1574 }
1575
1576 if (tagtype & UL_C){ //add 4 pages
1577 memcpy(data + Pages*4, authKeyPtr, dataLen);
1578 Pages += dataLen/4;
1579 } else { // 2nd page from end
1580 memcpy(data + (Pages*4) - 8, authenticationkey, dataLen);
1581 }
1582 }
1583
1584 //add *special* blocks to dump
1585 //get version
1586 memcpy(dump_file_data, get_version, sizeof(get_version));
1587 //tearing
1588 memcpy(dump_file_data+10, get_tearing, sizeof(get_tearing));
1589 //pack
1590 memcpy(dump_file_data+13, get_pack, sizeof(get_pack));
1591 //signature
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);
1595
1596 PrintAndLog("\n*Special* block data:");
1597 PrintAndLog("\nDataType| Data | | Ascii");
1598 PrintAndLog("---------------------------------");
1599 PrintAndLog("GetVer-1| %s| | %.4s", sprint_hex(dump_file_data, 4), dump_file_data);
1600 PrintAndLog("GetVer-2| %s| | %.4s", sprint_hex(dump_file_data+4, 4), dump_file_data+4);
1601 PrintAndLog("TBD | 00 00 | | ");
1602 PrintAndLog("Tearing | %s| | %.3s", sprint_hex(dump_file_data+10, 3), dump_file_data+10);
1603 PrintAndLog("Pack | %s | | %.2s", sprint_hex(dump_file_data+13, 2), dump_file_data+13);
1604 PrintAndLog("TBD | 00 | | ");
1605 PrintAndLog("Sig-1 | %s| | %.4s", sprint_hex(dump_file_data+16, 4), dump_file_data+16);
1606 PrintAndLog("Sig-2 | %s| | %.4s", sprint_hex(dump_file_data+20, 4), dump_file_data+20);
1607 PrintAndLog("Sig-3 | %s| | %.4s", sprint_hex(dump_file_data+24, 4), dump_file_data+24);
1608 PrintAndLog("Sig-4 | %s| | %.4s", sprint_hex(dump_file_data+28, 4), dump_file_data+28);
1609 PrintAndLog("Sig-5 | %s| | %.4s", sprint_hex(dump_file_data+32, 4), dump_file_data+32);
1610 PrintAndLog("Sig-6 | %s| | %.4s", sprint_hex(dump_file_data+36, 4), dump_file_data+36);
1611 PrintAndLog("Sig-7 | %s| | %.4s", sprint_hex(dump_file_data+40, 4), dump_file_data+40);
1612 PrintAndLog("Sig-8 | %s| | %.4s", sprint_hex(dump_file_data+44, 4), dump_file_data+44);
1613 PrintAndLog("\nBlock# | Data |lck| Ascii");
1614 PrintAndLog("---------------------------------");
1615 for (i = 0; i < Pages; ++i) {
1616 if ( i < 3 ) {
1617 PrintAndLog("%02d/0x%02X | %s| | %.4s", i+startPage, i+startPage, sprint_hex(data + i * 4, 4), data + i * 4 );
1618 continue;
1619 }
1620 switch(i){
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;
1634 case 16:
1635 case 17:
1636 case 18:
1637 case 19: tmplockbit = bit2[6]; break;
1638 case 20:
1639 case 21:
1640 case 22:
1641 case 23: tmplockbit = bit2[5]; break;
1642 case 24:
1643 case 25:
1644 case 26:
1645 case 27: tmplockbit = bit2[4]; break;
1646 case 28:
1647 case 29:
1648 case 30:
1649 case 31: tmplockbit = bit2[2]; break;
1650 case 32:
1651 case 33:
1652 case 34:
1653 case 35: tmplockbit = bit2[1]; break;
1654 case 36:
1655 case 37:
1656 case 38:
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
1662 default: break;
1663 }
1664 PrintAndLog("%02d/0x%02X | %s| %d | %.4s", i+startPage, i+startPage, sprint_hex(data + i * 4, 4), tmplockbit, data+i*4);
1665 }
1666 PrintAndLog("---------------------------------");
1667
1668 // user supplied filename?
1669 if (fileNlen < 1) {
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]);
1673 } else {
1674 sprintf(fnameptr + fileNlen,".bin");
1675 }
1676
1677 if ((fout = fopen(filename,"wb")) == NULL) {
1678 PrintAndLog("Could not create file name %s", filename);
1679 return 1;
1680 }
1681 fwrite( dump_file_data, 1, Pages*4 + DUMP_PREFIX_LENGTH, fout );
1682 fclose(fout);
1683
1684 PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages+(DUMP_PREFIX_LENGTH/4), Pages*4 + DUMP_PREFIX_LENGTH, filename);
1685 return 0;
1686}
1687
1688//-------------------------------------------------------------------------------
1689// Ultralight C Methods
1690//-------------------------------------------------------------------------------
1691
1692//
1693// Ultralight C Authentication Demo {currently uses hard-coded key}
1694//
1695int CmdHF14AMfucAuth(const char *Cmd){
1696
1697 uint8_t keyNo = 3;
1698 bool errors = false;
1699
1700 char cmdp = param_getchar(Cmd, 0);
1701
1702 //Change key to user defined one
1703 if (cmdp == 'k' || cmdp == 'K'){
1704 keyNo = param_get8(Cmd, 1);
1705 if(keyNo >= KEYS_3DES_COUNT)
1706 errors = true;
1707 }
1708
1709 if (cmdp == 'h' || cmdp == 'H') errors = true;
1710
1711 if (errors) return usage_hf_mfu_ucauth();
1712
1713 uint8_t *key = default_3des_keys[keyNo];
1714 if (ulc_authentication(key, true))
1715 PrintAndLog("Authentication successful. 3des key: %s",sprint_hex(key, 16));
1716 else
1717 PrintAndLog("Authentication failed");
1718
1719 return 0;
1720}
1721
1722/**
1723A test function to validate that the polarssl-function works the same
1724was as the openssl-implementation.
1725Commented out, since it requires openssl
1726
1727int CmdTestDES(const char * cmd)
1728{
1729 uint8_t key[16] = {0x00};
1730
1731 memcpy(key,key3_3des_data,16);
1732 DES_cblock RndA, RndB;
1733
1734 PrintAndLog("----------OpenSSL DES implementation----------");
1735 {
1736 uint8_t e_RndB[8] = {0x00};
1737 unsigned char RndARndB[16] = {0x00};
1738
1739 DES_cblock iv = { 0 };
1740 DES_key_schedule ks1,ks2;
1741 DES_cblock key1,key2;
1742
1743 memcpy(key,key3_3des_data,16);
1744 memcpy(key1,key,8);
1745 memcpy(key2,key+8,8);
1746
1747
1748 DES_set_key((DES_cblock *)key1,&ks1);
1749 DES_set_key((DES_cblock *)key2,&ks2);
1750
1751 DES_random_key(&RndA);
1752 PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
1753 PrintAndLog(" e_RndB:%s",sprint_hex(e_RndB, 8));
1754 //void DES_ede2_cbc_encrypt(const unsigned char *input,
1755 // unsigned char *output, long length, DES_key_schedule *ks1,
1756 // DES_key_schedule *ks2, DES_cblock *ivec, int enc);
1757 DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
1758
1759 PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
1760 rol(RndB,8);
1761 memcpy(RndARndB,RndA,8);
1762 memcpy(RndARndB+8,RndB,8);
1763 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
1764 DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
1765 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
1766
1767 }
1768 PrintAndLog("----------PolarSSL implementation----------");
1769 {
1770 uint8_t random_a[8] = { 0 };
1771 uint8_t enc_random_a[8] = { 0 };
1772 uint8_t random_b[8] = { 0 };
1773 uint8_t enc_random_b[8] = { 0 };
1774 uint8_t random_a_and_b[16] = { 0 };
1775 des3_context ctx = { 0 };
1776
1777 memcpy(random_a, RndA,8);
1778
1779 uint8_t output[8] = { 0 };
1780 uint8_t iv[8] = { 0 };
1781
1782 PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
1783 PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
1784
1785 des3_set2key_dec(&ctx, key);
1786
1787 des3_crypt_cbc(&ctx // des3_context *ctx
1788 , DES_DECRYPT // int mode
1789 , sizeof(random_b) // size_t length
1790 , iv // unsigned char iv[8]
1791 , enc_random_b // const unsigned char *input
1792 , random_b // unsigned char *output
1793 );
1794
1795 PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
1796
1797 rol(random_b,8);
1798 memcpy(random_a_and_b ,random_a,8);
1799 memcpy(random_a_and_b+8,random_b,8);
1800
1801 PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
1802
1803 des3_set2key_enc(&ctx, key);
1804
1805 des3_crypt_cbc(&ctx // des3_context *ctx
1806 , DES_ENCRYPT // int mode
1807 , sizeof(random_a_and_b) // size_t length
1808 , enc_random_b // unsigned char iv[8]
1809 , random_a_and_b // const unsigned char *input
1810 , random_a_and_b // unsigned char *output
1811 );
1812
1813 PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
1814 }
1815 return 0;
1816}
1817**/
1818
1819//
1820// Mifare Ultralight C - Set password
1821//
1822int CmdHF14AMfucSetPwd(const char *Cmd){
1823
1824 uint8_t pwd[16] = {0x00};
1825 char cmdp = param_getchar(Cmd, 0);
1826
1827 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetpwd();
1828
1829 if (param_gethex(Cmd, 0, pwd, 32)) {
1830 PrintAndLog("Password must include 32 HEX symbols");
1831 return 1;
1832 }
1833
1834 UsbCommand c = {CMD_MIFAREUC_SETPWD};
1835 memcpy( c.d.asBytes, pwd, 16);
1836 clearCommandBuffer();
1837 SendCommand(&c);
1838
1839 UsbCommand resp;
1840 if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
1841 if ( (resp.arg[0] & 0xff) == 1) {
1842 PrintAndLog("Ultralight-C new password: %s", sprint_hex(pwd,16));
1843 } else {
1844 PrintAndLog("Failed writing at block %d", resp.arg[1] & 0xff);
1845 return 1;
1846 }
1847 } else {
1848 PrintAndLog("command execution time out");
1849 return 1;
1850 }
1851 return 0;
1852}
1853
1854//
1855// Magic UL / UL-C tags - Set UID
1856//
1857int CmdHF14AMfucSetUid(const char *Cmd){
1858
1859 UsbCommand c;
1860 UsbCommand resp;
1861 uint8_t uid[7] = {0x00};
1862 char cmdp = param_getchar(Cmd, 0);
1863
1864 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetuid();
1865
1866 if (param_gethex(Cmd, 0, uid, 14)) {
1867 PrintAndLog("UID must include 14 HEX symbols");
1868 return 1;
1869 }
1870
1871 // read block2.
1872 c.cmd = CMD_MIFAREU_READBL;
1873 c.arg[0] = 2;
1874 clearCommandBuffer();
1875 SendCommand(&c);
1876 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1877 PrintAndLog("Command execute timeout");
1878 return 2;
1879 }
1880
1881 // save old block2.
1882 uint8_t oldblock2[4] = {0x00};
1883 memcpy(resp.d.asBytes, oldblock2, 4);
1884
1885 // block 0.
1886 c.cmd = CMD_MIFAREU_WRITEBL;
1887 c.arg[0] = 0;
1888 c.d.asBytes[0] = uid[0];
1889 c.d.asBytes[1] = uid[1];
1890 c.d.asBytes[2] = uid[2];
1891 c.d.asBytes[3] = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
1892 clearCommandBuffer();
1893 SendCommand(&c);
1894 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1895 PrintAndLog("Command execute timeout");
1896 return 3;
1897 }
1898
1899 // block 1.
1900 c.arg[0] = 1;
1901 c.d.asBytes[0] = uid[3];
1902 c.d.asBytes[1] = uid[4];
1903 c.d.asBytes[2] = uid[5];
1904 c.d.asBytes[3] = uid[6];
1905 clearCommandBuffer();
1906 SendCommand(&c);
1907 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
1908 PrintAndLog("Command execute timeout");
1909 return 4;
1910 }
1911
1912 // block 2.
1913 c.arg[0] = 2;
1914 c.d.asBytes[0] = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
1915 c.d.asBytes[1] = oldblock2[1];
1916 c.d.asBytes[2] = oldblock2[2];
1917 c.d.asBytes[3] = oldblock2[3];
1918 clearCommandBuffer();
1919 SendCommand(&c);
1920 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
1921 PrintAndLog("Command execute timeout");
1922 return 5;
1923 }
1924
1925 return 0;
1926}
1927
1928int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
1929
1930 uint8_t uid[4];
1931 char cmdp = param_getchar(Cmd, 0);
1932 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_gendiverse();
1933
1934 if (param_gethex(Cmd, 0, uid, 8)) {
1935 PrintAndLog("UID must include 8 HEX symbols");
1936 return 1;
1937 }
1938
1939 uint8_t iv[8] = { 0x00 };
1940 uint8_t block = 0x01;
1941
1942 uint8_t mifarekeyA[] = { 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5 };
1943 uint8_t mifarekeyB[] = { 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5 };
1944 uint8_t dkeyA[8] = { 0x00 };
1945 uint8_t dkeyB[8] = { 0x00 };
1946
1947 uint8_t masterkey[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
1948
1949 uint8_t mix[8] = { 0x00 };
1950 uint8_t divkey[8] = { 0x00 };
1951
1952 memcpy(mix, mifarekeyA, 4);
1953
1954 mix[4] = mifarekeyA[4] ^ uid[0];
1955 mix[5] = mifarekeyA[5] ^ uid[1];
1956 mix[6] = block ^ uid[2];
1957 mix[7] = uid[3];
1958
1959 des3_context ctx = { 0x00 };
1960 des3_set2key_enc(&ctx, masterkey);
1961
1962 des3_crypt_cbc(&ctx // des3_context
1963 , DES_ENCRYPT // int mode
1964 , sizeof(mix) // length
1965 , iv // iv[8]
1966 , mix // input
1967 , divkey // output
1968 );
1969
1970 PrintAndLog("-- 3DES version");
1971 PrintAndLog("Masterkey :\t %s", sprint_hex(masterkey,sizeof(masterkey)));
1972 PrintAndLog("UID :\t %s", sprint_hex(uid, sizeof(uid)));
1973 PrintAndLog("block :\t %0d", block);
1974 PrintAndLog("Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA)));
1975 PrintAndLog("Message :\t %s", sprint_hex(mix, sizeof(mix)));
1976 PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6));
1977
1978 for (int i=0; i < sizeof(mifarekeyA); ++i){
1979 dkeyA[i] = (mifarekeyA[i] << 1) & 0xff;
1980 dkeyA[6] |= ((mifarekeyA[i] >> 7) & 1) << (i+1);
1981 }
1982
1983 for (int i=0; i < sizeof(mifarekeyB); ++i){
1984 dkeyB[1] |= ((mifarekeyB[i] >> 7) & 1) << (i+1);
1985 dkeyB[2+i] = (mifarekeyB[i] << 1) & 0xff;
1986 }
1987
1988 uint8_t zeros[8] = {0x00};
1989 uint8_t newpwd[8] = {0x00};
1990 uint8_t dmkey[24] = {0x00};
1991 memcpy(dmkey, dkeyA, 8);
1992 memcpy(dmkey+8, dkeyB, 8);
1993 memcpy(dmkey+16, dkeyA, 8);
1994 memset(iv, 0x00, 8);
1995
1996 des3_set3key_enc(&ctx, dmkey);
1997
1998 des3_crypt_cbc(&ctx // des3_context
1999 , DES_ENCRYPT // int mode
2000 , sizeof(newpwd) // length
2001 , iv // iv[8]
2002 , zeros // input
2003 , newpwd // output
2004 );
2005
2006 PrintAndLog("\n-- DES version");
2007 PrintAndLog("Mifare dkeyA :\t %s", sprint_hex(dkeyA, sizeof(dkeyA)));
2008 PrintAndLog("Mifare dkeyB :\t %s", sprint_hex(dkeyB, sizeof(dkeyB)));
2009 PrintAndLog("Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey)));
2010 PrintAndLog("Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd)));
2011
2012 // next. from the diversify_key method.
2013 return 0;
2014}
2015
2016int CmdHF14AMfUeLoad(const char *Cmd) {
2017 char ctmp = param_getchar(Cmd, 0);
2018 if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf_mfu_eload();
2019 return CmdHF14AMfELoad(Cmd);
2020}
2021
2022int CmdHF14AMfUSim(const char *Cmd) {
2023 char ctmp = param_getchar(Cmd, 0);
2024 if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf_mfu_sim();
2025 return CmdHF14ASim(Cmd);
2026}
2027
2028int CmdHF14AMfuPwdGen(const char *Cmd){
2029 uint8_t uid[7] = {0x00};
2030 char cmdp = param_getchar(Cmd, 0);
2031 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_pwdgen();
2032
2033 if (param_gethex(Cmd, 0, uid, 14)) return usage_hf_mfu_pwdgen();
2034
2035 PrintAndLog(" algo | pwd | pack");
2036 PrintAndLog("------+----------+-----");
2037 PrintAndLog(" EV1 | %08X | %04X", ul_ev1_pwdgenA(uid), ul_ev1_packgenA(uid));
2038 PrintAndLog(" Ami | %08X | %04X", ul_ev1_pwdgenB(uid), ul_ev1_packgenB(uid));
2039 PrintAndLog(" LD | %08X | %04X", ul_ev1_pwdgenC(uid), ul_ev1_packgenC(uid));
2040 return 0;
2041}
2042//------------------------------------
2043// Menu Stuff
2044//------------------------------------
2045static command_t CommandTable[] =
2046{
2047 {"help", CmdHelp, 1, "This help"},
2048 {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
2049 {"info", CmdHF14AMfUInfo, 0, "Tag information"},
2050 {"dump", CmdHF14AMfUDump, 0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"},
2051 {"eload", CmdHF14AMfUeLoad, 0, "load Ultralight .eml dump file into emulator memory"},
2052 {"rdbl", CmdHF14AMfURdBl, 0, "Read block"},
2053 {"wrbl", CmdHF14AMfUWrBl, 0, "Write block"},
2054 {"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"},
2055 {"setpwd", CmdHF14AMfucSetPwd, 0, "Set 3des password - Ultralight-C"},
2056 {"setuid", CmdHF14AMfucSetUid, 0, "Set UID - MAGIC tags only"},
2057 {"sim", CmdHF14AMfUSim, 0, "Simulate Ultralight from emulator memory"},
2058 {"gen", CmdHF14AMfuGenDiverseKeys , 1, "Generate 3des mifare diversified keys"},
2059 {"pwdgen", CmdHF14AMfuPwdGen, 1, "Generate pwd from known algos"},
2060 {NULL, NULL, 0, NULL}
2061};
2062
2063int CmdHFMFUltra(const char *Cmd){
2064 clearCommandBuffer();
2065 //WaitForResponseTimeout(CMD_ACK,NULL,100);
2066 CmdsParse(CommandTable, Cmd);
2067 return 0;
2068}
2069
2070int CmdHelp(const char *Cmd){
2071 CmdsHelp(CommandTable);
2072 return 0;
2073}
Impressum, Datenschutz