]> cvs.zerfleddert.de Git - proxmark3-svn/blame_incremental - client/cmdhfmfu.c
CHG: Syntax suger
[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
122void ul_ev1_pwdgen_selftest(){
123
124 uint8_t uid1[] = {0x04,0x11,0x12,0x11,0x12,0x11,0x10};
125 uint32_t pwd1 = ul_ev1_pwdgenA(uid1);
126 PrintAndLog("UID | %s | %08X | %s", sprint_hex(uid1,7), pwd1, (pwd1 == 0x8432EB17)?"OK":"->8432EB17<-");
127
128 uint8_t uid2[] = {0x04,0x1f,0x98,0xea,0x1e,0x3e,0x81};
129 uint32_t pwd2 = ul_ev1_pwdgenB(uid2);
130 PrintAndLog("UID | %s | %08X | %s", sprint_hex(uid2,7), pwd2, (pwd2 == 0x5fd37eca)?"OK":"->5fd37eca<--");
131
132 uint8_t uid3[] = {0x04,0x62, 0xB6, 0x8A, 0xB4, 0x42, 0x80};
133 uint32_t pwd3 = ul_ev1_pwdgenC(uid3);
134 PrintAndLog("UID | %s | %08X | %s", sprint_hex(uid3,7), pwd3, (pwd3 == 0x5a349515)?"OK":"->5a349515<--");
135 return;
136}
137
138static int CmdHelp(const char *Cmd);
139
140// get version nxp product type
141char *getProductTypeStr( uint8_t id){
142
143 static char buf[20];
144 char *retStr = buf;
145
146 switch(id) {
147 case 3: sprintf(retStr, "%02X, Ultralight", id); break;
148 case 4: sprintf(retStr, "%02X, NTAG", id); break;
149 default: sprintf(retStr, "%02X, unknown", id); break;
150 }
151 return buf;
152}
153
154/*
155 The 7 MSBits (=n) code the storage size itself based on 2^n,
156 the LSBit is set to '0' if the size is exactly 2^n
157 and set to '1' if the storage size is between 2^n and 2^(n+1).
158*/
159char *getUlev1CardSizeStr( uint8_t fsize ){
160
161 static char buf[40];
162 char *retStr = buf;
163 memset(buf, 0, sizeof(buf));
164
165 uint16_t usize = 1 << ((fsize >>1) + 1);
166 uint16_t lsize = 1 << (fsize >>1);
167
168 // is LSB set?
169 if ( fsize & 1 )
170 sprintf(retStr, "%02X, (%u <-> %u bytes)",fsize, usize, lsize);
171 else
172 sprintf(retStr, "%02X, (%u bytes)", fsize, lsize);
173 return buf;
174}
175
176static void ul_switch_on_field(void) {
177 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
178 clearCommandBuffer();
179 SendCommand(&c);
180}
181
182void ul_switch_off_field(void) {
183 UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
184 clearCommandBuffer();
185 SendCommand(&c);
186}
187
188static int ul_send_cmd_raw( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength ) {
189 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_APPEND_CRC, cmdlen, 0}};
190 memcpy(c.d.asBytes, cmd, cmdlen);
191 clearCommandBuffer();
192 SendCommand(&c);
193 UsbCommand resp;
194 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
195 if (!resp.arg[0] && responseLength) return -1;
196
197 uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
198 memcpy(response, resp.d.asBytes, resplen);
199 return resplen;
200}
201
202static int ul_select( iso14a_card_select_t *card ){
203
204 ul_switch_on_field();
205
206 UsbCommand resp;
207 bool ans = false;
208 ans = WaitForResponseTimeout(CMD_ACK, &resp, 1500);
209 if (!ans || resp.arg[0] < 1) {
210 PrintAndLog("iso14443a card select failed");
211 ul_switch_off_field();
212 return 0;
213 }
214
215 memcpy(card, resp.d.asBytes, sizeof(iso14a_card_select_t));
216 return 1;
217}
218
219// This read command will at least return 16bytes.
220static int ul_read( uint8_t page, uint8_t *response, uint16_t responseLength ){
221
222 uint8_t cmd[] = {ISO14443A_CMD_READBLOCK, page};
223 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
224 return len;
225}
226
227static int ul_comp_write( uint8_t page, uint8_t *data, uint8_t datalen ){
228
229 uint8_t cmd[18];
230 memset(cmd, 0x00, sizeof(cmd));
231 datalen = ( datalen > 16) ? 16 : datalen;
232
233 cmd[0] = ISO14443A_CMD_WRITEBLOCK;
234 cmd[1] = page;
235 memcpy(cmd+2, data, datalen);
236
237 uint8_t response[1] = {0xff};
238 ul_send_cmd_raw(cmd, 2+datalen, response, sizeof(response));
239 // ACK
240 if ( response[0] == 0x0a ) return 0;
241 // NACK
242 return -1;
243}
244
245static int ulc_requestAuthentication( uint8_t *nonce, uint16_t nonceLength ){
246
247 uint8_t cmd[] = {MIFARE_ULC_AUTH_1, 0x00};
248 int len = ul_send_cmd_raw(cmd, sizeof(cmd), nonce, nonceLength);
249 return len;
250}
251
252static int ulc_authentication( uint8_t *key, bool switch_off_field ){
253
254 UsbCommand c = {CMD_MIFAREUC_AUTH, {switch_off_field}};
255 memcpy(c.d.asBytes, key, 16);
256 clearCommandBuffer();
257 SendCommand(&c);
258 UsbCommand resp;
259 if ( !WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) return 0;
260 if ( resp.arg[0] == 1 ) return 1;
261
262 return 0;
263}
264
265static int ulev1_requestAuthentication( uint8_t *pwd, uint8_t *pack, uint16_t packLength ){
266
267 uint8_t cmd[] = {MIFARE_ULEV1_AUTH, pwd[0], pwd[1], pwd[2], pwd[3]};
268 int len = ul_send_cmd_raw(cmd, sizeof(cmd), pack, packLength);
269 return len;
270}
271
272static int ul_auth_select( iso14a_card_select_t *card, TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authenticationkey, uint8_t *pack, uint8_t packSize){
273 if ( hasAuthKey && (tagtype & UL_C)) {
274 //will select card automatically and close connection on error
275 if (!ulc_authentication(authenticationkey, false)) {
276 PrintAndLog("Error: Authentication Failed UL-C");
277 return 0;
278 }
279 } else {
280 if ( !ul_select(card) ) return 0;
281
282 if (hasAuthKey) {
283 if (ulev1_requestAuthentication(authenticationkey, pack, packSize) < 2) {
284 ul_switch_off_field();
285 PrintAndLog("Error: Authentication Failed UL-EV1/NTAG");
286 return 0;
287 }
288 }
289 }
290 return 1;
291}
292
293static int ulev1_getVersion( uint8_t *response, uint16_t responseLength ){
294
295 uint8_t cmd[] = {MIFARE_ULEV1_VERSION};
296 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
297 return len;
298}
299
300static int ulev1_readCounter( uint8_t counter, uint8_t *response, uint16_t responseLength ){
301
302 uint8_t cmd[] = {MIFARE_ULEV1_READ_CNT, counter};
303 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
304 return len;
305}
306
307static int ulev1_readTearing( uint8_t counter, uint8_t *response, uint16_t responseLength ){
308
309 uint8_t cmd[] = {MIFARE_ULEV1_CHECKTEAR, counter};
310 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
311 return len;
312}
313
314static int ulev1_readSignature( uint8_t *response, uint16_t responseLength ){
315
316 uint8_t cmd[] = {MIFARE_ULEV1_READSIG, 0x00};
317 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
318 return len;
319}
320
321// Fudan check checks for which error is given for a command with incorrect crc
322// NXP UL chip responds with 01, fudan 00.
323// other possible checks:
324// send a0 + crc
325// UL responds with 00, fudan doesn't respond
326// or
327// send a200 + crc
328// UL doesn't respond, fudan responds with 00
329// or
330// send 300000 + crc (read with extra byte(s))
331// UL responds with read of page 0, fudan doesn't respond.
332//
333// make sure field is off before calling this function
334static int ul_fudan_check( void ){
335 iso14a_card_select_t card;
336 if ( !ul_select(&card) )
337 return UL_ERROR;
338
339 UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT, 4, 0}};
340
341 uint8_t cmd[4] = {0x30,0x00,0x02,0xa7}; //wrong crc on purpose should be 0xa8
342 memcpy(c.d.asBytes, cmd, 4);
343 clearCommandBuffer();
344 SendCommand(&c);
345 UsbCommand resp;
346 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return UL_ERROR;
347 if (resp.arg[0] != 1) return UL_ERROR;
348
349 return (!resp.d.asBytes[0]) ? FUDAN_UL : UL; //if response == 0x00 then Fudan, else Genuine NXP
350}
351
352static int ul_print_default( uint8_t *data){
353
354 uint8_t uid[7];
355 uid[0] = data[0];
356 uid[1] = data[1];
357 uid[2] = data[2];
358 uid[3] = data[4];
359 uid[4] = data[5];
360 uid[5] = data[6];
361 uid[6] = data[7];
362
363 PrintAndLog(" UID : %s ", sprint_hex(uid, 7));
364 PrintAndLog(" UID[0] : %02X, %s", uid[0], getTagInfo(uid[0]) );
365 if ( uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2 ) { // is infineon and 66RxxP
366 uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU
367 switch (chip){
368 case 0xc2: PrintAndLog(" IC type : SLE 66R04P 770 Bytes"); break; //77 pages
369 case 0xc4: PrintAndLog(" IC type : SLE 66R16P 2560 Bytes"); break; //256 pages
370 case 0xc6: PrintAndLog(" IC type : SLE 66R32P 5120 Bytes"); break; //512 pages /2 sectors
371 }
372 }
373 // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
374 int crc0 = 0x88 ^ data[0] ^ data[1] ^data[2];
375 if ( data[3] == crc0 )
376 PrintAndLog(" BCC0 : %02X, Ok", data[3]);
377 else
378 PrintAndLog(" BCC0 : %02X, crc should be %02X", data[3], crc0);
379
380 int crc1 = data[4] ^ data[5] ^ data[6] ^data[7];
381 if ( data[8] == crc1 )
382 PrintAndLog(" BCC1 : %02X, Ok", data[8]);
383 else
384 PrintAndLog(" BCC1 : %02X, crc should be %02X", data[8], crc1 );
385
386 PrintAndLog(" Internal : %02X, %sdefault", data[9], (data[9]==0x48)?"":"not " );
387
388 PrintAndLog(" Lock : %s - %s",
389 sprint_hex(data+10, 2),
390 sprint_bin(data+10, 2)
391 );
392
393 PrintAndLog("OneTimePad : %s - %s\n",
394 sprint_hex(data + 12, 4),
395 sprint_bin(data+12, 4)
396 );
397
398 return 0;
399}
400
401static int ndef_print_CC(uint8_t *data) {
402 // no NDEF message
403 if(data[0] != 0xe1)
404 return -1;
405
406 PrintAndLog("--- NDEF Message");
407 PrintAndLog("Capability Container: %s", sprint_hex(data,4) );
408 PrintAndLog(" %02X : NDEF Magic Number", data[0]);
409 PrintAndLog(" %02X : version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f);
410 PrintAndLog(" %02X : Physical Memory Size: %d bytes", data[2], (data[2] + 1) * 8);
411 if ( data[2] == 0x96 )
412 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 48);
413 else if ( data[2] == 0x12 )
414 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 144);
415 else if ( data[2] == 0x3e )
416 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 496);
417 else if ( data[2] == 0x6d )
418 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 872);
419
420 PrintAndLog(" %02X : %s / %s", data[3],
421 (data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security",
422 (data[3] & 0x0F)==0 ? "Write access granted without any security" : (data[3] & 0x0F)==0x0F ? "No write access granted at all" : "(RFU)");
423 return 0;
424}
425
426int ul_print_type(uint32_t tagtype, uint8_t spaces){
427 char spc[11] = " ";
428 spc[10]=0x00;
429 char *spacer = spc + (10-spaces);
430
431 if ( tagtype & UL )
432 PrintAndLog("%sTYPE : MIFARE Ultralight (MF0ICU1) %s", spacer, (tagtype & MAGIC) ? "<magic>" : "" );
433 else if ( tagtype & UL_C)
434 PrintAndLog("%sTYPE : MIFARE Ultralight C (MF0ULC) %s", spacer, (tagtype & MAGIC) ? "<magic>" : "" );
435 else if ( tagtype & UL_EV1_48)
436 PrintAndLog("%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer);
437 else if ( tagtype & UL_EV1_128)
438 PrintAndLog("%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer);
439 else if ( tagtype & NTAG )
440 PrintAndLog("%sTYPE : NTAG UNKNOWN", spacer);
441 else if ( tagtype & NTAG_203 )
442 PrintAndLog("%sTYPE : NTAG 203 144bytes (NT2H0301F0DT)", spacer);
443 else if ( tagtype & NTAG_210 )
444 PrintAndLog("%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer);
445 else if ( tagtype & NTAG_212 )
446 PrintAndLog("%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer);
447 else if ( tagtype & NTAG_213 )
448 PrintAndLog("%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer);
449 else if ( tagtype & NTAG_215 )
450 PrintAndLog("%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer);
451 else if ( tagtype & NTAG_216 )
452 PrintAndLog("%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer);
453 else if ( tagtype & NTAG_I2C_1K )
454 PrintAndLog("%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer, "\xFD");
455 else if ( tagtype & NTAG_I2C_2K )
456 PrintAndLog("%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer, "\xFD");
457 else if ( tagtype & MY_D )
458 PrintAndLog("%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer);
459 else if ( tagtype & MY_D_NFC )
460 PrintAndLog("%sTYPE : INFINEON my-d\x99 NFC (SLE 66RxxP)", spacer);
461 else if ( tagtype & MY_D_MOVE )
462 PrintAndLog("%sTYPE : INFINEON my-d\x99 move (SLE 66R01P)", spacer);
463 else if ( tagtype & MY_D_MOVE_NFC )
464 PrintAndLog("%sTYPE : INFINEON my-d\x99 move NFC (SLE 66R01P)", spacer);
465 else if ( tagtype & MY_D_MOVE_LEAN )
466 PrintAndLog("%sTYPE : INFINEON my-d\x99 move lean (SLE 66R01L)", spacer);
467 else if ( tagtype & FUDAN_UL )
468 PrintAndLog("%sTYPE : FUDAN Ultralight Compatible (or other compatible) %s", spacer, (tagtype & MAGIC) ? "<magic>" : "" );
469 else
470 PrintAndLog("%sTYPE : Unknown %06x", spacer, tagtype);
471 return 0;
472}
473
474static int ulc_print_3deskey( uint8_t *data){
475 PrintAndLog(" deskey1 [44/0x2C] : %s [%.4s]", sprint_hex(data ,4),data);
476 PrintAndLog(" deskey1 [45/0x2D] : %s [%.4s]", sprint_hex(data+4 ,4),data+4);
477 PrintAndLog(" deskey2 [46/0x2E] : %s [%.4s]", sprint_hex(data+8 ,4),data+8);
478 PrintAndLog(" deskey2 [47/0x2F] : %s [%.4s]", sprint_hex(data+12,4),data+12);
479 PrintAndLog("\n 3des key : %s", sprint_hex(SwapEndian64(data, 16, 8), 16));
480 return 0;
481}
482
483static int ulc_print_configuration( uint8_t *data){
484
485 PrintAndLog("--- UL-C Configuration");
486 PrintAndLog(" Higher Lockbits [40/0x28] : %s - %s", sprint_hex(data, 4), sprint_bin(data, 2));
487 PrintAndLog(" Counter [41/0x29] : %s - %s", sprint_hex(data+4, 4), sprint_bin(data+4, 2));
488
489 bool validAuth = (data[8] >= 0x03 && data[8] <= 0x30);
490 if ( validAuth )
491 PrintAndLog(" Auth0 [42/0x2A] : %s page %d/0x%02X and above need authentication", sprint_hex(data+8, 4), data[8],data[8] );
492 else{
493 if ( data[8] == 0){
494 PrintAndLog(" Auth0 [42/0x2A] : %s default", sprint_hex(data+8, 4) );
495 } else {
496 PrintAndLog(" Auth0 [42/0x2A] : %s auth byte is out-of-range", sprint_hex(data+8, 4) );
497 }
498 }
499 PrintAndLog(" Auth1 [43/0x2B] : %s %s",
500 sprint_hex(data+12, 4),
501 (data[12] & 1) ? "write access restricted": "read and write access restricted"
502 );
503 return 0;
504}
505
506static int ulev1_print_configuration( uint8_t *data, uint8_t startPage){
507
508 PrintAndLog("\n--- Tag Configuration");
509
510 bool strg_mod_en = (data[0] & 2);
511 uint8_t authlim = (data[4] & 0x07);
512 bool nfc_cnf_en = (data[4] & 0x08);
513 bool nfc_cnf_prot_pwd = (data[4] & 0x10);
514 bool cfglck = (data[4] & 0x40);
515 bool prot = (data[4] & 0x80);
516 uint8_t vctid = data[5];
517
518 PrintAndLog(" cfg0 [%u/0x%02X] : %s", startPage, startPage, sprint_hex(data, 4));
519 if ( data[3] < 0xff )
520 PrintAndLog(" - page %d and above need authentication",data[3]);
521 else
522 PrintAndLog(" - pages don't need authentication");
523 PrintAndLog(" - strong modulation mode %s", (strg_mod_en) ? "enabled":"disabled");
524 PrintAndLog(" cfg1 [%u/0x%02X] : %s", startPage + 1, startPage + 1, sprint_hex(data+4, 4) );
525 if ( authlim == 0)
526 PrintAndLog(" - Unlimited password attempts");
527 else
528 PrintAndLog(" - Max number of password attempts is %d", authlim);
529
530 PrintAndLog(" - NFC counter %s", (nfc_cnf_en) ? "enabled":"disabled");
531 PrintAndLog(" - NFC counter %s", (nfc_cnf_prot_pwd) ? "not protected":"password protection enabled");
532
533 PrintAndLog(" - user configuration %s", cfglck ? "permanently locked":"writeable");
534 PrintAndLog(" - %s access is protected with password", prot ? "read and write":"write");
535 PrintAndLog(" - %02X, Virtual Card Type Identifier is %s default", vctid, (vctid==0x05)? "":"not");
536 PrintAndLog(" PWD [%u/0x%02X] : %s- (cannot be read)", startPage + 2, startPage + 2, sprint_hex(data+8, 4));
537 PrintAndLog(" PACK [%u/0x%02X] : %s - (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data+12, 2));
538 PrintAndLog(" RFU [%u/0x%02X] : %s- (cannot be read)", startPage + 3, startPage + 3, sprint_hex(data+12, 2));
539 return 0;
540}
541
542static int ulev1_print_counters(){
543 PrintAndLog("--- Tag Counters");
544 uint8_t tear[1] = {0};
545 uint8_t counter[3] = {0,0,0};
546 uint16_t len = 0;
547 for ( uint8_t i = 0; i<3; ++i) {
548 ulev1_readTearing(i,tear,sizeof(tear));
549 len = ulev1_readCounter(i,counter, sizeof(counter) );
550 if (len == 3) {
551 PrintAndLog(" [%0d] : %s", i, sprint_hex(counter,3));
552 PrintAndLog(" - %02X tearing %s", tear[0], ( tear[0]==0xBD)?"Ok":"failure");
553 }
554 }
555 return len;
556}
557
558static int ulev1_print_signature( uint8_t *data, uint8_t len){
559 PrintAndLog("\n--- Tag Signature");
560 //PrintAndLog("IC signature public key name : NXP NTAG21x 2013"); // don't know if there is other NXP public keys.. :(
561 PrintAndLog("IC signature public key value : 04494e1a386d3d3cfe3dc10e5de68a499b1c202db5b132393e89ed19fe5be8bc61");
562 PrintAndLog(" Elliptic curve parameters : secp128r1");
563 PrintAndLog(" Tag ECC Signature : %s", sprint_hex(data, len));
564 //to do: verify if signature is valid
565 //PrintAndLog("IC signature status: %s valid", (iseccvalid() )?"":"not");
566 return 0;
567}
568
569static int ulev1_print_version(uint8_t *data){
570 PrintAndLog("\n--- Tag Version");
571 PrintAndLog(" Raw bytes : %s",sprint_hex(data, 8) );
572 PrintAndLog(" Vendor ID : %02X, %s", data[1], getTagInfo(data[1]));
573 PrintAndLog(" Product type : %s", getProductTypeStr(data[2]));
574 PrintAndLog(" Product subtype : %02X, %s", data[3], (data[3]==1) ?"17 pF":"50pF");
575 PrintAndLog(" Major version : %02X", data[4]);
576 PrintAndLog(" Minor version : %02X", data[5]);
577 PrintAndLog(" Size : %s", getUlev1CardSizeStr(data[6]));
578 PrintAndLog(" Protocol type : %02X", data[7]);
579 return 0;
580}
581
582/*
583static int ulc_magic_test(){
584 // Magic Ultralight test
585 // Magic UL-C, by observation,
586 // 1) it seems to have a static nonce response to 0x1A command.
587 // 2) the deskey bytes is not-zero:d out on as datasheet states.
588 // 3) UID - changeable, not only, but pages 0-1-2-3.
589 // 4) use the ul_magic_test ! magic tags answers specially!
590 int returnValue = UL_ERROR;
591 iso14a_card_select_t card;
592 uint8_t nonce1[11] = {0x00};
593 uint8_t nonce2[11] = {0x00};
594 int status = ul_select(&card);
595 if ( !status ){
596 return UL_ERROR;
597 }
598 status = ulc_requestAuthentication(nonce1, sizeof(nonce1));
599 if ( status > 0 ) {
600 status = ulc_requestAuthentication(nonce2, sizeof(nonce2));
601 returnValue = ( !memcmp(nonce1, nonce2, 11) ) ? UL_C_MAGIC : UL_C;
602 } else {
603 returnValue = UL;
604 }
605 ul_switch_off_field();
606 return returnValue;
607}
608*/
609static int ul_magic_test(){
610
611 // Magic Ultralight tests
612 // 1) take present UID, and try to write it back. OBSOLETE
613 // 2) make a wrong length write to page0, and see if tag answers with ACK/NACK:
614 iso14a_card_select_t card;
615 if ( !ul_select(&card) )
616 return UL_ERROR;
617 int status = ul_comp_write(0, NULL, 0);
618 ul_switch_off_field();
619 if ( status == 0 )
620 return MAGIC;
621 return 0;
622}
623
624uint32_t GetHF14AMfU_Type(void){
625
626 TagTypeUL_t tagtype = UNKNOWN;
627 iso14a_card_select_t card;
628 uint8_t version[10] = {0x00};
629 int status = 0;
630 int len;
631
632 if (!ul_select(&card)) return UL_ERROR;
633
634 // Ultralight - ATQA / SAK
635 if ( card.atqa[1] != 0x00 || card.atqa[0] != 0x44 || card.sak != 0x00 ) {
636 PrintAndLog("Tag is not Ultralight | NTAG | MY-D [ATQA: %02X %02X SAK: %02X]\n", card.atqa[1], card.atqa[0], card.sak);
637 ul_switch_off_field();
638 return UL_ERROR;
639 }
640
641 if ( card.uid[0] != 0x05) {
642
643 len = ulev1_getVersion(version, sizeof(version));
644 ul_switch_off_field();
645
646 switch (len) {
647 case 0x0A: {
648
649 if ( version[2] == 0x03 && version[6] == 0x0B )
650 tagtype = UL_EV1_48;
651 else if ( version[2] == 0x03 && version[6] != 0x0B )
652 tagtype = UL_EV1_128;
653 else if ( version[2] == 0x04 && version[3] == 0x01 && version[6] == 0x0B )
654 tagtype = NTAG_210;
655 else if ( version[2] == 0x04 && version[3] == 0x01 && version[6] == 0x0E )
656 tagtype = NTAG_212;
657 else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x0F )
658 tagtype = NTAG_213;
659 else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x11 )
660 tagtype = NTAG_215;
661 else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x13 )
662 tagtype = NTAG_216;
663 else if ( version[2] == 0x04 && version[3] == 0x05 && version[6] == 0x13 )
664 tagtype = NTAG_I2C_1K;
665 else if ( version[2] == 0x04 && version[3] == 0x05 && version[6] == 0x15 )
666 tagtype = NTAG_I2C_2K;
667 else if ( version[2] == 0x04 )
668 tagtype = NTAG;
669
670 break;
671 }
672 case 0x01: tagtype = UL_C; break;
673 case 0x00: tagtype = UL; break;
674 case -1 : tagtype = (UL | UL_C | NTAG_203); break; // could be UL | UL_C magic tags
675 default : tagtype = UNKNOWN; break;
676 }
677 // UL vs UL-C vs ntag203 test
678 if (tagtype & (UL | UL_C | NTAG_203)) {
679 if ( !ul_select(&card) ) return UL_ERROR;
680
681 // do UL_C check first...
682 uint8_t nonce[11] = {0x00};
683 status = ulc_requestAuthentication(nonce, sizeof(nonce));
684 ul_switch_off_field();
685 if (status > 1) {
686 tagtype = UL_C;
687 } else {
688 // need to re-select after authentication error
689 if ( !ul_select(&card) ) return UL_ERROR;
690
691 uint8_t data[16] = {0x00};
692 // read page 0x26-0x29 (last valid ntag203 page)
693 status = ul_read(0x26, data, sizeof(data));
694 if ( status <= 1 ) {
695 tagtype = UL;
696 } else {
697 // read page 0x30 (should error if it is a ntag203)
698 status = ul_read(0x30, data, sizeof(data));
699 if ( status <= 1 ){
700 tagtype = NTAG_203;
701 } else {
702 tagtype = UNKNOWN;
703 }
704 }
705 ul_switch_off_field();
706 }
707 }
708 if (tagtype & UL) {
709 tagtype = ul_fudan_check();
710 ul_switch_off_field();
711 }
712 } else {
713 ul_switch_off_field();
714 // Infinition MY-D tests Exam high nibble
715 uint8_t nib = (card.uid[1] & 0xf0) >> 4;
716 switch ( nib ){
717 // case 0: tagtype = SLE66R35E7; break; //or SLE 66R35E7 - mifare compat... should have different sak/atqa for mf 1k
718 case 1: tagtype = MY_D; break; //or SLE 66RxxS ... up to 512 pages of 8 user bytes...
719 case 2: tagtype = (MY_D_NFC); break; //or SLE 66RxxP ... up to 512 pages of 8 user bytes... (or in nfc mode FF pages of 4 bytes)
720 case 3: tagtype = (MY_D_MOVE | MY_D_MOVE_NFC); break; //or SLE 66R01P // 38 pages of 4 bytes //notice: we can not currently distinguish between these two
721 case 7: tagtype = MY_D_MOVE_LEAN; break; //or SLE 66R01L // 16 pages of 4 bytes
722 }
723 }
724
725 tagtype |= ul_magic_test();
726 if (tagtype == (UNKNOWN | MAGIC)) tagtype = (UL_MAGIC);
727 return tagtype;
728}
729
730int CmdHF14AMfUInfo(const char *Cmd){
731
732 uint8_t authlim = 0xff;
733 uint8_t data[16] = {0x00};
734 iso14a_card_select_t card;
735 int status;
736 bool errors = false;
737 bool hasAuthKey = false;
738 bool locked = false;
739 bool swapEndian = false;
740 uint8_t cmdp = 0;
741 uint8_t dataLen = 0;
742 uint8_t authenticationkey[16] = {0x00};
743 uint8_t *authkeyptr = authenticationkey;
744 uint8_t pwd[4] = {0,0,0,0};
745 uint8_t *key = pwd;
746 uint8_t pack[4] = {0,0,0,0};
747 int len = 0;
748 char tempStr[50];
749
750 while(param_getchar(Cmd, cmdp) != 0x00)
751 {
752 switch(param_getchar(Cmd, cmdp))
753 {
754 case 'h':
755 case 'H':
756 return usage_hf_mfu_info();
757 case 'k':
758 case 'K':
759 dataLen = param_getstr(Cmd, cmdp+1, tempStr);
760 if (dataLen == 32 || dataLen == 8) { //ul-c or ev1/ntag key length
761 errors = param_gethex(tempStr, 0, authenticationkey, dataLen);
762 dataLen /= 2; // handled as bytes from now on
763 } else {
764 PrintAndLog("\nERROR: Key is incorrect length\n");
765 errors = true;
766 }
767 cmdp += 2;
768 hasAuthKey = true;
769 break;
770 case 'l':
771 case 'L':
772 swapEndian = true;
773 cmdp++;
774 break;
775 default:
776 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
777 errors = true;
778 break;
779 }
780 if(errors) break;
781 }
782
783 //Validations
784 if(errors) return usage_hf_mfu_info();
785
786 TagTypeUL_t tagtype = GetHF14AMfU_Type();
787 if (tagtype == UL_ERROR) return -1;
788
789 PrintAndLog("\n--- Tag Information ---------");
790 PrintAndLog("-------------------------------------------------------------");
791 ul_print_type(tagtype, 6);
792
793 // Swap endianness
794 if (swapEndian && hasAuthKey) authkeyptr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4 );
795
796 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
797
798 // read pages 0,1,2,3 (should read 4pages)
799 status = ul_read(0, data, sizeof(data));
800 if ( status == -1 ) {
801 ul_switch_off_field();
802 PrintAndLog("Error: tag didn't answer to READ");
803 return status;
804 } else if (status == 16) {
805 ul_print_default(data);
806 ndef_print_CC(data+12);
807 } else {
808 locked = true;
809 }
810
811 // UL_C Specific
812 if ((tagtype & UL_C)) {
813
814 // read pages 0x28, 0x29, 0x2A, 0x2B
815 uint8_t ulc_conf[16] = {0x00};
816 status = ul_read(0x28, ulc_conf, sizeof(ulc_conf));
817 if ( status == -1 ){
818 PrintAndLog("Error: tag didn't answer to READ UL-C");
819 ul_switch_off_field();
820 return status;
821 }
822 if (status == 16) ulc_print_configuration(ulc_conf);
823 else locked = true;
824
825 if ((tagtype & MAGIC)) {
826 //just read key
827 uint8_t ulc_deskey[16] = {0x00};
828 status = ul_read(0x2C, ulc_deskey, sizeof(ulc_deskey));
829 if ( status == -1 ) {
830 ul_switch_off_field();
831 PrintAndLog("Error: tag didn't answer to READ magic");
832 return status;
833 }
834 if (status == 16) ulc_print_3deskey(ulc_deskey);
835
836 } else {
837 ul_switch_off_field();
838 // if we called info with key, just return
839 if ( hasAuthKey ) return 1;
840
841 // also try to diversify default keys.. look into CmdHF14AMfuGenDiverseKeys
842 PrintAndLog("Trying some default 3des keys");
843 for (uint8_t i = 0; i < KEYS_3DES_COUNT; ++i ) {
844 key = default_3des_keys[i];
845 if (ulc_authentication(key, true)) {
846 PrintAndLog("Found default 3des key: ");
847 uint8_t keySwap[16];
848 memcpy(keySwap, SwapEndian64(key,16,8), 16);
849 ulc_print_3deskey(keySwap);
850 return 1;
851 }
852 }
853 return 1;
854 }
855 }
856
857 // do counters and signature first (don't neet auth)
858
859 // ul counters are different than ntag counters
860 if ((tagtype & (UL_EV1_48 | UL_EV1_128))) {
861 if (ulev1_print_counters() != 3) {
862 // failed - re-select
863 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
864 }
865 }
866
867 // Read signature
868 if ((tagtype & (UL_EV1_48 | UL_EV1_128 | NTAG_213 | NTAG_215 | NTAG_216 | NTAG_I2C_1K | NTAG_I2C_2K ))) {
869 uint8_t ulev1_signature[32] = {0x00};
870 status = ulev1_readSignature( ulev1_signature, sizeof(ulev1_signature));
871 if ( status == -1 ) {
872 PrintAndLog("Error: tag didn't answer to READ SIGNATURE");
873 ul_switch_off_field();
874 return status;
875 }
876 if (status == 32) ulev1_print_signature( ulev1_signature, sizeof(ulev1_signature));
877 else {
878 // re-select
879 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
880 }
881 }
882
883 // Get Version
884 if ((tagtype & (UL_EV1_48 | UL_EV1_128 | NTAG_210 | NTAG_212 | NTAG_213 | NTAG_215 | NTAG_216 | NTAG_I2C_1K | NTAG_I2C_2K))) {
885 uint8_t version[10] = {0x00};
886 status = ulev1_getVersion(version, sizeof(version));
887 if ( status == -1 ) {
888 PrintAndLog("Error: tag didn't answer to GETVERSION");
889 ul_switch_off_field();
890 return status;
891 } else if (status == 10) {
892 ulev1_print_version(version);
893 } else {
894 locked = true;
895 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
896 }
897
898 uint8_t startconfigblock = 0;
899 uint8_t ulev1_conf[16] = {0x00};
900 // config blocks always are last 4 pages
901 for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++)
902 if (tagtype & UL_TYPES_ARRAY[idx])
903 startconfigblock = UL_MEMORY_ARRAY[idx]-3;
904
905 if (startconfigblock){ // if we know where the config block is...
906 status = ul_read(startconfigblock, ulev1_conf, sizeof(ulev1_conf));
907 if ( status == -1 ) {
908 PrintAndLog("Error: tag didn't answer to READ EV1");
909 ul_switch_off_field();
910 return status;
911 } else if (status == 16) {
912 // save AUTHENTICATION LIMITS for later:
913 authlim = (ulev1_conf[4] & 0x07);
914 ulev1_print_configuration(ulev1_conf, startconfigblock);
915 }
916 }
917
918 // AUTHLIMIT, (number of failed authentications)
919 // 0 = limitless.
920 // 1-7 = limit. No automatic tries then.
921 // hasAuthKey, if we was called with key, skip test.
922 if ( !authlim && !hasAuthKey ) {
923 PrintAndLog("\n--- Known EV1/NTAG passwords.");
924 len = 0;
925
926 // test pwd gen A
927 num_to_bytes( ul_ev1_pwdgenA(card.uid), 4, key);
928 len = ulev1_requestAuthentication(key, pack, sizeof(pack));
929 if (len >= 1) {
930 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
931 }
932 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
933
934 // test pwd gen B
935 num_to_bytes( ul_ev1_pwdgenB(card.uid), 4, key);
936 len = ulev1_requestAuthentication(key, pack, sizeof(pack));
937 if (len >= 1) {
938 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
939 }
940 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
941
942 // test pwd gen C
943 num_to_bytes( ul_ev1_pwdgenC(card.uid), 4, key);
944 len = ulev1_requestAuthentication(key, pack, sizeof(pack));
945 if (len >= 1) {
946 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
947 }
948 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
949
950 for (uint8_t i = 0; i < KEYS_PWD_COUNT; ++i ) {
951 key = default_pwd_pack[i];
952 len = ulev1_requestAuthentication(key, pack, sizeof(pack));
953 if (len >= 1) {
954 PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
955 break;
956 } else {
957 if (!ul_auth_select( &card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack))) return -1;
958 }
959 }
960 if (len < 1) PrintAndLog("password not known");
961 }
962 }
963
964 ul_switch_off_field();
965 if (locked) PrintAndLog("\nTag appears to be locked, try using the key to get more info");
966 PrintAndLog("");
967 return 1;
968}
969
970//
971// Write Single Block
972//
973int CmdHF14AMfUWrBl(const char *Cmd){
974
975 int blockNo = -1;
976 bool errors = false;
977 bool hasAuthKey = false;
978 bool hasPwdKey = false;
979 bool swapEndian = false;
980
981 uint8_t cmdp = 0;
982 uint8_t keylen = 0;
983 uint8_t blockdata[20] = {0x00};
984 uint8_t data[16] = {0x00};
985 uint8_t authenticationkey[16] = {0x00};
986 uint8_t *authKeyPtr = authenticationkey;
987
988 while(param_getchar(Cmd, cmdp) != 0x00)
989 {
990 switch(param_getchar(Cmd, cmdp))
991 {
992 case 'h':
993 case 'H':
994 return usage_hf_mfu_wrbl();
995 case 'k':
996 case 'K':
997 // EV1/NTAG size key
998 keylen = param_gethex(Cmd, cmdp+1, data, 8);
999 if ( !keylen ) {
1000 memcpy(authenticationkey, data, 4);
1001 cmdp += 2;
1002 hasPwdKey = true;
1003 break;
1004 }
1005 // UL-C size key
1006 keylen = param_gethex(Cmd, cmdp+1, data, 32);
1007 if (!keylen){
1008 memcpy(authenticationkey, data, 16);
1009 cmdp += 2;
1010 hasAuthKey = true;
1011 break;
1012 }
1013 PrintAndLog("\nERROR: Key is incorrect length\n");
1014 errors = true;
1015 break;
1016 case 'b':
1017 case 'B':
1018 blockNo = param_get8(Cmd, cmdp+1);
1019 if (blockNo < 0) {
1020 PrintAndLog("Wrong block number");
1021 errors = true;
1022 }
1023 cmdp += 2;
1024 break;
1025 case 'l':
1026 case 'L':
1027 swapEndian = true;
1028 cmdp++;
1029 break;
1030 case 'd':
1031 case 'D':
1032 if ( param_gethex(Cmd, cmdp+1, blockdata, 8) ) {
1033 PrintAndLog("Block data must include 8 HEX symbols");
1034 errors = true;
1035 break;
1036 }
1037 cmdp += 2;
1038 break;
1039 default:
1040 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
1041 errors = true;
1042 break;
1043 }
1044 //Validations
1045 if(errors) return usage_hf_mfu_wrbl();
1046 }
1047
1048 if ( blockNo == -1 ) return usage_hf_mfu_wrbl();
1049 // starting with getting tagtype
1050 TagTypeUL_t tagtype = GetHF14AMfU_Type();
1051 if (tagtype == UL_ERROR) return -1;
1052
1053 uint8_t maxblockno = 0;
1054 for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++){
1055 if (tagtype & UL_TYPES_ARRAY[idx])
1056 maxblockno = UL_MEMORY_ARRAY[idx];
1057 }
1058 if (blockNo > maxblockno){
1059 PrintAndLog("block number too large. Max block is %u/0x%02X \n", maxblockno,maxblockno);
1060 return usage_hf_mfu_wrbl();
1061 }
1062
1063 // Swap endianness
1064 if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
1065 if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
1066
1067 if ( blockNo <= 3)
1068 PrintAndLog("Special Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4));
1069 else
1070 PrintAndLog("Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4));
1071
1072 //Send write Block
1073 UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}};
1074 memcpy(c.d.asBytes,blockdata,4);
1075
1076 if ( hasAuthKey ){
1077 c.arg[1] = 1;
1078 memcpy(c.d.asBytes+4,authKeyPtr,16);
1079 }
1080 else if ( hasPwdKey ) {
1081 c.arg[1] = 2;
1082 memcpy(c.d.asBytes+4,authKeyPtr,4);
1083 }
1084
1085 clearCommandBuffer();
1086 SendCommand(&c);
1087 UsbCommand resp;
1088 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1089 uint8_t isOK = resp.arg[0] & 0xff;
1090 PrintAndLog("isOk:%02x", isOK);
1091 } else {
1092 PrintAndLog("Command execute timeout");
1093 }
1094
1095 return 0;
1096}
1097//
1098// Read Single Block
1099//
1100int CmdHF14AMfURdBl(const char *Cmd){
1101
1102 int blockNo = -1;
1103 bool errors = false;
1104 bool hasAuthKey = false;
1105 bool hasPwdKey = false;
1106 bool swapEndian = false;
1107 uint8_t cmdp = 0;
1108 uint8_t keylen = 0;
1109 uint8_t data[16] = {0x00};
1110 uint8_t authenticationkey[16] = {0x00};
1111 uint8_t *authKeyPtr = authenticationkey;
1112
1113 while(param_getchar(Cmd, cmdp) != 0x00)
1114 {
1115 switch(param_getchar(Cmd, cmdp))
1116 {
1117 case 'h':
1118 case 'H':
1119 return usage_hf_mfu_rdbl();
1120 case 'k':
1121 case 'K':
1122 // EV1/NTAG size key
1123 keylen = param_gethex(Cmd, cmdp+1, data, 8);
1124 if ( !keylen ) {
1125 memcpy(authenticationkey, data, 4);
1126 cmdp += 2;
1127 hasPwdKey = true;
1128 break;
1129 }
1130 // UL-C size key
1131 keylen = param_gethex(Cmd, cmdp+1, data, 32);
1132 if (!keylen){
1133 memcpy(authenticationkey, data, 16);
1134 cmdp += 2;
1135 hasAuthKey = true;
1136 break;
1137 }
1138 PrintAndLog("\nERROR: Key is incorrect length\n");
1139 errors = true;
1140 break;
1141 case 'b':
1142 case 'B':
1143 blockNo = param_get8(Cmd, cmdp+1);
1144 if (blockNo < 0) {
1145 PrintAndLog("Wrong block number");
1146 errors = true;
1147 }
1148 cmdp += 2;
1149 break;
1150 case 'l':
1151 case 'L':
1152 swapEndian = true;
1153 cmdp++;
1154 break;
1155 default:
1156 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
1157 errors = true;
1158 break;
1159 }
1160 //Validations
1161 if(errors) return usage_hf_mfu_rdbl();
1162 }
1163
1164 if ( blockNo == -1 ) return usage_hf_mfu_rdbl();
1165 // start with getting tagtype
1166 TagTypeUL_t tagtype = GetHF14AMfU_Type();
1167 if (tagtype == UL_ERROR) return -1;
1168
1169 uint8_t maxblockno = 0;
1170 for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++){
1171 if (tagtype & UL_TYPES_ARRAY[idx])
1172 maxblockno = UL_MEMORY_ARRAY[idx];
1173 }
1174 if (blockNo > maxblockno){
1175 PrintAndLog("block number to large. Max block is %u/0x%02X \n", maxblockno,maxblockno);
1176 return usage_hf_mfu_rdbl();
1177 }
1178
1179 // Swap endianness
1180 if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
1181 if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
1182
1183 //Read Block
1184 UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
1185 if ( hasAuthKey ){
1186 c.arg[1] = 1;
1187 memcpy(c.d.asBytes,authKeyPtr,16);
1188 }
1189 else if ( hasPwdKey ) {
1190 c.arg[1] = 2;
1191 memcpy(c.d.asBytes,authKeyPtr,4);
1192 }
1193
1194 clearCommandBuffer();
1195 SendCommand(&c);
1196 UsbCommand resp;
1197 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1198 uint8_t isOK = resp.arg[0] & 0xff;
1199 if (isOK) {
1200 uint8_t *data = resp.d.asBytes;
1201 PrintAndLog("\nBlock# | Data | Ascii");
1202 PrintAndLog("-----------------------------");
1203 PrintAndLog("%02d/0x%02X | %s| %.4s\n", blockNo, blockNo, sprint_hex(data, 4), data);
1204 }
1205 else {
1206 PrintAndLog("Failed reading block: (%02x)", isOK);
1207 }
1208 } else {
1209 PrintAndLog("Command execute time-out");
1210 }
1211 return 0;
1212}
1213
1214int usage_hf_mfu_info(void) {
1215 PrintAndLog("It gathers information about the tag and tries to detect what kind it is.");
1216 PrintAndLog("Sometimes the tags are locked down, and you may need a key to be able to read the information");
1217 PrintAndLog("The following tags can be identified:\n");
1218 PrintAndLog("Ultralight, Ultralight-C, Ultralight EV1, NTAG 203, NTAG 210,");
1219 PrintAndLog("NTAG 212, NTAG 213, NTAG 215, NTAG 216, NTAG I2C 1K & 2K");
1220 PrintAndLog("my-d, my-d NFC, my-d move, my-d move NFC\n");
1221 PrintAndLog("Usage: hf mfu info k <key> l");
1222 PrintAndLog(" Options : ");
1223 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1224 PrintAndLog(" l : (optional) swap entered key's endianness");
1225 PrintAndLog("");
1226 PrintAndLog(" sample : hf mfu info");
1227 PrintAndLog(" : hf mfu info k 00112233445566778899AABBCCDDEEFF");
1228 PrintAndLog(" : hf mfu info k AABBCCDDD");
1229 return 0;
1230}
1231
1232int usage_hf_mfu_dump(void) {
1233 PrintAndLog("Reads all pages from Ultralight, Ultralight-C, Ultralight EV1");
1234 PrintAndLog("NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216");
1235 PrintAndLog("and saves binary dump into the file `filename.bin` or `cardUID.bin`");
1236 PrintAndLog("It autodetects card type.\n");
1237 PrintAndLog("Usage: hf mfu dump k <key> l n <filename w/o .bin> p <page#> q <#pages>");
1238 PrintAndLog(" Options :");
1239 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1240 PrintAndLog(" l : (optional) swap entered key's endianness");
1241 PrintAndLog(" n <FN > : filename w/o .bin to save the dump as");
1242 PrintAndLog(" p <Pg > : starting Page number to manually set a page to start the dump at");
1243 PrintAndLog(" q <qty> : number of Pages to manually set how many pages to dump");
1244 PrintAndLog("");
1245 PrintAndLog(" sample : hf mfu dump");
1246 PrintAndLog(" : hf mfu dump n myfile");
1247 PrintAndLog(" : hf mfu dump k 00112233445566778899AABBCCDDEEFF");
1248 PrintAndLog(" : hf mfu dump k AABBCCDDD\n");
1249 return 0;
1250}
1251
1252int usage_hf_mfu_rdbl(void) {
1253 PrintAndLog("Read a block and print. It autodetects card type.\n");
1254 PrintAndLog("Usage: hf mfu rdbl b <block number> k <key> l\n");
1255 PrintAndLog(" Options:");
1256 PrintAndLog(" b <no> : block to read");
1257 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1258 PrintAndLog(" l : (optional) swap entered key's endianness");
1259 PrintAndLog("");
1260 PrintAndLog(" sample : hf mfu rdbl b 0");
1261 PrintAndLog(" : hf mfu rdbl b 0 k 00112233445566778899AABBCCDDEEFF");
1262 PrintAndLog(" : hf mfu rdbl b 0 k AABBCCDDD\n");
1263 return 0;
1264}
1265
1266int usage_hf_mfu_wrbl(void) {
1267 PrintAndLog("Write a block. It autodetects card type.\n");
1268 PrintAndLog("Usage: hf mfu wrbl b <block number> d <data> k <key> l\n");
1269 PrintAndLog(" Options:");
1270 PrintAndLog(" b <no> : block to write");
1271 PrintAndLog(" d <data> : block data - (8 hex symbols)");
1272 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1273 PrintAndLog(" l : (optional) swap entered key's endianness");
1274 PrintAndLog("");
1275 PrintAndLog(" sample : hf mfu wrbl b 0 d 01234567");
1276 PrintAndLog(" : hf mfu wrbl b 0 d 01234567 k AABBCCDDD\n");
1277 return 0;
1278}
1279
1280int usage_hf_mfu_eload(void) {
1281 PrintAndLog("It loads emul dump from the file `filename.eml`");
1282 PrintAndLog("Hint: See script dumptoemul-mfu.lua to convert the .bin to the eml");
1283 PrintAndLog("Usage: hf mfu eload u <file name w/o `.eml`> [numblocks]");
1284 PrintAndLog(" Options:");
1285 PrintAndLog(" h : this help");
1286 PrintAndLog(" u : UL (required)");
1287 PrintAndLog(" [filename] : without `.eml` (required)");
1288 PrintAndLog(" numblocks : number of blocks to load from eml file (optional)");
1289 PrintAndLog("");
1290 PrintAndLog(" sample: hf mfu eload u filename");
1291 PrintAndLog(" hf mfu eload u filename 57");
1292 return 0;
1293}
1294
1295int usage_hf_mfu_sim(void) {
1296 PrintAndLog("\nEmulating Ultralight tag from emulator memory\n");
1297 PrintAndLog("\nBe sure to load the emulator memory first!\n");
1298 PrintAndLog("Usage: hf mfu sim t 7 u <uid>");
1299 PrintAndLog(" Options:");
1300 PrintAndLog(" h : this help");
1301 PrintAndLog(" t 7 : 7 = NTAG or Ultralight sim (required)");
1302 PrintAndLog(" u <uid> : 4 or 7 byte UID (optional)");
1303 PrintAndLog("\n sample : hf mfu sim t 7");
1304 PrintAndLog(" : hf mfu sim t 7 u 1122344556677\n");
1305
1306 return 0;
1307}
1308
1309int usage_hf_mfu_ucauth(void) {
1310 PrintAndLog("Usage: hf mfu cauth k <key number>");
1311 PrintAndLog(" 0 (default): 3DES standard key");
1312 PrintAndLog(" 1 : all 0x00 key");
1313 PrintAndLog(" 2 : 0x00-0x0F key");
1314 PrintAndLog(" 3 : nfc key");
1315 PrintAndLog(" 4 : all 0x01 key");
1316 PrintAndLog(" 5 : all 0xff key");
1317 PrintAndLog(" 6 : 0x00-0xFF key");
1318 PrintAndLog("\n sample : hf mfu cauth k");
1319 PrintAndLog(" : hf mfu cauth k 3");
1320 return 0;
1321}
1322
1323int usage_hf_mfu_ucsetpwd(void) {
1324 PrintAndLog("Usage: hf mfu setpwd <password (32 hex symbols)>");
1325 PrintAndLog(" [password] - (32 hex symbols)");
1326 PrintAndLog("");
1327 PrintAndLog("sample: hf mfu setpwd 000102030405060708090a0b0c0d0e0f");
1328 PrintAndLog("");
1329 return 0;
1330}
1331
1332int usage_hf_mfu_ucsetuid(void) {
1333 PrintAndLog("Usage: hf mfu setuid <uid (14 hex symbols)>");
1334 PrintAndLog(" [uid] - (14 hex symbols)");
1335 PrintAndLog("\nThis only works for Magic Ultralight tags.");
1336 PrintAndLog("");
1337 PrintAndLog("sample: hf mfu setuid 11223344556677");
1338 PrintAndLog("");
1339 return 0;
1340}
1341
1342int usage_hf_mfu_gendiverse(void){
1343 PrintAndLog("Usage: hf mfu gen <uid (8 hex symbols)>");
1344 PrintAndLog("");
1345 PrintAndLog("sample: hf mfu gen 11223344");
1346 PrintAndLog("");
1347 return 0;
1348}
1349
1350#define DUMP_PREFIX_LENGTH 48
1351//
1352// Mifare Ultralight / Ultralight-C / Ultralight-EV1
1353// Read and Dump Card Contents, using auto detection of tag size.
1354int CmdHF14AMfUDump(const char *Cmd){
1355
1356 FILE *fout;
1357 char filename[FILE_PATH_SIZE] = {0x00};
1358 char *fnameptr = filename;
1359 uint8_t *lockbytes_t = NULL;
1360 uint8_t lockbytes[2] = {0x00};
1361 uint8_t *lockbytes_t2 = NULL;
1362 uint8_t lockbytes2[2] = {0x00};
1363 bool bit[16] = {0x00};
1364 bool bit2[16] = {0x00};
1365 uint8_t data[1024] = {0x00};
1366 bool hasAuthKey = false;
1367 int i = 0;
1368 int Pages = 16;
1369 bool tmplockbit = false;
1370 uint8_t dataLen = 0;
1371 uint8_t cmdp = 0;
1372 uint8_t authenticationkey[16] = {0x00};
1373 memset(authenticationkey, 0x00, sizeof(authenticationkey));
1374 uint8_t *authKeyPtr = authenticationkey;
1375 size_t fileNlen = 0;
1376 bool errors = false;
1377 bool swapEndian = false;
1378 bool manualPages = false;
1379 uint8_t startPage = 0;
1380 char tempStr[50];
1381
1382 while(param_getchar(Cmd, cmdp) != 0x00)
1383 {
1384 switch(param_getchar(Cmd, cmdp))
1385 {
1386 case 'h':
1387 case 'H':
1388 return usage_hf_mfu_dump();
1389 case 'k':
1390 case 'K':
1391 dataLen = param_getstr(Cmd, cmdp+1, tempStr);
1392 if (dataLen == 32 || dataLen == 8) { //ul-c or ev1/ntag key length
1393 errors = param_gethex(tempStr, 0, authenticationkey, dataLen);
1394 dataLen /= 2;
1395 } else {
1396 PrintAndLog("\nERROR: Key is incorrect length\n");
1397 errors = true;
1398 }
1399 cmdp += 2;
1400 hasAuthKey = true;
1401 break;
1402 case 'l':
1403 case 'L':
1404 swapEndian = true;
1405 cmdp++;
1406 break;
1407 case 'n':
1408 case 'N':
1409 fileNlen = param_getstr(Cmd, cmdp+1, filename);
1410 if (!fileNlen) errors = true;
1411 if (fileNlen > FILE_PATH_SIZE-5) fileNlen = FILE_PATH_SIZE-5;
1412 cmdp += 2;
1413 break;
1414 case 'p':
1415 case 'P': //set start page
1416 startPage = param_get8(Cmd, cmdp+1);
1417 manualPages = true;
1418 cmdp += 2;
1419 break;
1420 case 'q':
1421 case 'Q':
1422 Pages = param_get8(Cmd, cmdp+1);
1423 cmdp += 2;
1424 manualPages = true;
1425 break;
1426 default:
1427 PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
1428 errors = true;
1429 break;
1430 }
1431 if(errors) break;
1432 }
1433
1434 //Validations
1435 if(errors) return usage_hf_mfu_dump();
1436
1437 //if we entered a key in little endian and set the swapEndian switch - switch it...
1438 if (swapEndian && hasAuthKey)
1439 authKeyPtr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4);
1440
1441 TagTypeUL_t tagtype = GetHF14AMfU_Type();
1442 if (tagtype == UL_ERROR) return -1;
1443
1444 if (!manualPages) //get number of pages to read
1445 for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++)
1446 if (tagtype & UL_TYPES_ARRAY[idx])
1447 Pages = UL_MEMORY_ARRAY[idx]+1; //add one as maxblks starts at 0
1448
1449 ul_print_type(tagtype, 0);
1450 PrintAndLog("Reading tag memory...");
1451 UsbCommand c = {CMD_MIFAREU_READCARD, {startPage,Pages}};
1452 if ( hasAuthKey ) {
1453 if (tagtype & UL_C)
1454 c.arg[2] = 1; //UL_C auth
1455 else
1456 c.arg[2] = 2; //UL_EV1/NTAG auth
1457
1458 memcpy(c.d.asBytes, authKeyPtr, dataLen);
1459 }
1460
1461 clearCommandBuffer();
1462 SendCommand(&c);
1463 UsbCommand resp;
1464 if (!WaitForResponseTimeout(CMD_ACK, &resp,1500)) {
1465 PrintAndLog("Command execute time-out");
1466 return 1;
1467 }
1468 if (resp.arg[0] != 1) {
1469 PrintAndLog("Failed reading block: (%02x)", i);
1470 return 1;
1471 }
1472
1473 uint32_t startindex = resp.arg[2];
1474 uint32_t bufferSize = resp.arg[1];
1475 if (bufferSize > sizeof(data)) {
1476 PrintAndLog("Data exceeded Buffer size!");
1477 bufferSize = sizeof(data);
1478 }
1479 GetFromBigBuf(data, bufferSize, startindex);
1480 WaitForResponse(CMD_ACK,NULL);
1481
1482 Pages = bufferSize/4;
1483 // Load lock bytes.
1484 int j = 0;
1485
1486 lockbytes_t = data + 8;
1487 lockbytes[0] = lockbytes_t[2];
1488 lockbytes[1] = lockbytes_t[3];
1489 for(j = 0; j < 16; j++){
1490 bit[j] = lockbytes[j/8] & ( 1 <<(7-j%8));
1491 }
1492
1493 // Load bottom lockbytes if available
1494 // TODO -- FIGURE OUT LOCK BYTES FOR TO EV1 and/or NTAG
1495 if ( Pages == 44 ) {
1496 lockbytes_t2 = data + (40*4);
1497 lockbytes2[0] = lockbytes_t2[2];
1498 lockbytes2[1] = lockbytes_t2[3];
1499 for (j = 0; j < 16; j++) {
1500 bit2[j] = lockbytes2[j/8] & ( 1 <<(7-j%8));
1501 }
1502 }
1503
1504 uint8_t get_pack[] = {0,0};
1505 iso14a_card_select_t card;
1506 uint8_t dump_file_data[1024+DUMP_PREFIX_LENGTH] = {0x00};
1507 uint8_t get_version[] = {0,0,0,0,0,0,0,0,0};
1508 uint8_t get_tearing[] = {0,0,0};
1509 uint8_t get_counter[] = {0,0,0};
1510 uint8_t dummy_pack[] = {0,0};
1511 uint8_t get_signature[32];
1512 memset( get_signature, 0, sizeof(get_signature) );
1513
1514 // not ul_c and not std ul then attempt to get deeper info
1515 if (!(tagtype & UL_C || tagtype & UL)) {
1516 //attempt to read pack
1517 if (!ul_auth_select( &card, tagtype, true, authKeyPtr, get_pack, sizeof(get_pack))) {
1518 //reset pack
1519 get_pack[0]=0;
1520 get_pack[1]=0;
1521 }
1522 ul_switch_off_field();
1523 // add pack to block read
1524 memcpy(data + (Pages*4) - 4, get_pack, sizeof(get_pack));
1525 if ( hasAuthKey )
1526 ul_auth_select( &card, tagtype, hasAuthKey, authKeyPtr, dummy_pack, sizeof(dummy_pack));
1527 else
1528 ul_select(&card);
1529
1530 ulev1_getVersion( get_version, sizeof(get_version) );
1531 for ( uint8_t i = 0; i<3; ++i) {
1532 ulev1_readTearing(i, get_tearing+i, 1);
1533 ulev1_readCounter(i, get_counter, sizeof(get_counter) );
1534 }
1535 ul_switch_off_field();
1536 if ( hasAuthKey )
1537 ul_auth_select( &card, tagtype, hasAuthKey, authKeyPtr, dummy_pack, sizeof(dummy_pack));
1538 else
1539 ul_select(&card);
1540 ulev1_readSignature( get_signature, sizeof(get_signature));
1541 ul_switch_off_field();
1542 }
1543
1544 // format and add keys to block dump output
1545 if (hasAuthKey) {
1546 // if we didn't swapendian before - do it now for the sprint_hex call
1547 // NOTE: default entry is bigendian (unless swapped), sprint_hex outputs little endian
1548 // need to swap to keep it the same
1549 if (!swapEndian){
1550 authKeyPtr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4);
1551 } else {
1552 authKeyPtr = authenticationkey;
1553 }
1554
1555 if (tagtype & UL_C){ //add 4 pages
1556 memcpy(data + Pages*4, authKeyPtr, dataLen);
1557 Pages += dataLen/4;
1558 } else { // 2nd page from end
1559 memcpy(data + (Pages*4) - 8, authenticationkey, dataLen);
1560 }
1561 }
1562
1563 //add *special* blocks to dump
1564 //get version
1565 memcpy(dump_file_data, get_version, sizeof(get_version));
1566 //tearing
1567 memcpy(dump_file_data+10, get_tearing, sizeof(get_tearing));
1568 //pack
1569 memcpy(dump_file_data+13, get_pack, sizeof(get_pack));
1570 //signature
1571 memcpy(dump_file_data+16, get_signature, sizeof(get_signature));
1572 //add regular block read data to dump
1573 memcpy(dump_file_data+DUMP_PREFIX_LENGTH, data, Pages*4);
1574
1575 PrintAndLog("\n*Special* block data:");
1576 PrintAndLog("\nDataType| Data | | Ascii");
1577 PrintAndLog("---------------------------------");
1578 PrintAndLog("GetVer-1| %s| | %.4s", sprint_hex(dump_file_data, 4), dump_file_data);
1579 PrintAndLog("GetVer-2| %s| | %.4s", sprint_hex(dump_file_data+4, 4), dump_file_data+4);
1580 PrintAndLog("TBD | 00 00 | | ");
1581 PrintAndLog("Tearing | %s| | %.3s", sprint_hex(dump_file_data+10, 3), dump_file_data+10);
1582 PrintAndLog("Pack | %s | | %.2s", sprint_hex(dump_file_data+13, 2), dump_file_data+13);
1583 PrintAndLog("TBD | 00 | | ");
1584 PrintAndLog("Sig-1 | %s| | %.4s", sprint_hex(dump_file_data+16, 4), dump_file_data+16);
1585 PrintAndLog("Sig-2 | %s| | %.4s", sprint_hex(dump_file_data+20, 4), dump_file_data+20);
1586 PrintAndLog("Sig-3 | %s| | %.4s", sprint_hex(dump_file_data+24, 4), dump_file_data+24);
1587 PrintAndLog("Sig-4 | %s| | %.4s", sprint_hex(dump_file_data+28, 4), dump_file_data+28);
1588 PrintAndLog("Sig-5 | %s| | %.4s", sprint_hex(dump_file_data+32, 4), dump_file_data+32);
1589 PrintAndLog("Sig-6 | %s| | %.4s", sprint_hex(dump_file_data+36, 4), dump_file_data+36);
1590 PrintAndLog("Sig-7 | %s| | %.4s", sprint_hex(dump_file_data+40, 4), dump_file_data+40);
1591 PrintAndLog("Sig-8 | %s| | %.4s", sprint_hex(dump_file_data+44, 4), dump_file_data+44);
1592 PrintAndLog("\nBlock# | Data |lck| Ascii");
1593 PrintAndLog("---------------------------------");
1594 for (i = 0; i < Pages; ++i) {
1595 if ( i < 3 ) {
1596 PrintAndLog("%02d/0x%02X | %s| | ", i+startPage, i+startPage, sprint_hex(data + i * 4, 4));
1597 continue;
1598 }
1599 switch(i){
1600 case 3: tmplockbit = bit[4]; break;
1601 case 4: tmplockbit = bit[3]; break;
1602 case 5: tmplockbit = bit[2]; break;
1603 case 6: tmplockbit = bit[1]; break;
1604 case 7: tmplockbit = bit[0]; break;
1605 case 8: tmplockbit = bit[15]; break;
1606 case 9: tmplockbit = bit[14]; break;
1607 case 10: tmplockbit = bit[13]; break;
1608 case 11: tmplockbit = bit[12]; break;
1609 case 12: tmplockbit = bit[11]; break;
1610 case 13: tmplockbit = bit[10]; break;
1611 case 14: tmplockbit = bit[9]; break;
1612 case 15: tmplockbit = bit[8]; break;
1613 case 16:
1614 case 17:
1615 case 18:
1616 case 19: tmplockbit = bit2[6]; break;
1617 case 20:
1618 case 21:
1619 case 22:
1620 case 23: tmplockbit = bit2[5]; break;
1621 case 24:
1622 case 25:
1623 case 26:
1624 case 27: tmplockbit = bit2[4]; break;
1625 case 28:
1626 case 29:
1627 case 30:
1628 case 31: tmplockbit = bit2[2]; break;
1629 case 32:
1630 case 33:
1631 case 34:
1632 case 35: tmplockbit = bit2[1]; break;
1633 case 36:
1634 case 37:
1635 case 38:
1636 case 39: tmplockbit = bit2[0]; break;
1637 case 40: tmplockbit = bit2[12]; break;
1638 case 41: tmplockbit = bit2[11]; break;
1639 case 42: tmplockbit = bit2[10]; break; //auth0
1640 case 43: tmplockbit = bit2[9]; break; //auth1
1641 default: break;
1642 }
1643 PrintAndLog("%02d/0x%02X | %s| %d | %.4s", i+startPage, i+startPage, sprint_hex(data + i * 4, 4), tmplockbit, data+i*4);
1644 }
1645 PrintAndLog("---------------------------------");
1646
1647 // user supplied filename?
1648 if (fileNlen < 1) {
1649 // UID = data 0-1-2 4-5-6-7 (skips a beat)
1650 sprintf(fnameptr,"%02X%02X%02X%02X%02X%02X%02X.bin",
1651 data[0],data[1], data[2], data[4],data[5],data[6], data[7]);
1652 } else {
1653 sprintf(fnameptr + fileNlen,".bin");
1654 }
1655
1656 if ((fout = fopen(filename,"wb")) == NULL) {
1657 PrintAndLog("Could not create file name %s", filename);
1658 return 1;
1659 }
1660 fwrite( dump_file_data, 1, Pages*4 + DUMP_PREFIX_LENGTH, fout );
1661 fclose(fout);
1662
1663 PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages+(DUMP_PREFIX_LENGTH/4), Pages*4 + DUMP_PREFIX_LENGTH, filename);
1664 return 0;
1665}
1666
1667//-------------------------------------------------------------------------------
1668// Ultralight C Methods
1669//-------------------------------------------------------------------------------
1670
1671//
1672// Ultralight C Authentication Demo {currently uses hard-coded key}
1673//
1674int CmdHF14AMfucAuth(const char *Cmd){
1675
1676 uint8_t keyNo = 3;
1677 bool errors = false;
1678
1679 char cmdp = param_getchar(Cmd, 0);
1680
1681 //Change key to user defined one
1682 if (cmdp == 'k' || cmdp == 'K'){
1683 keyNo = param_get8(Cmd, 1);
1684 if(keyNo > KEYS_3DES_COUNT)
1685 errors = true;
1686 }
1687
1688 if (cmdp == 'h' || cmdp == 'H') errors = true;
1689
1690 if (errors) return usage_hf_mfu_ucauth();
1691
1692 uint8_t *key = default_3des_keys[keyNo];
1693 if (ulc_authentication(key, true))
1694 PrintAndLog("Authentication successful. 3des key: %s",sprint_hex(key, 16));
1695 else
1696 PrintAndLog("Authentication failed");
1697
1698 return 0;
1699}
1700
1701/**
1702A test function to validate that the polarssl-function works the same
1703was as the openssl-implementation.
1704Commented out, since it requires openssl
1705
1706int CmdTestDES(const char * cmd)
1707{
1708 uint8_t key[16] = {0x00};
1709
1710 memcpy(key,key3_3des_data,16);
1711 DES_cblock RndA, RndB;
1712
1713 PrintAndLog("----------OpenSSL DES implementation----------");
1714 {
1715 uint8_t e_RndB[8] = {0x00};
1716 unsigned char RndARndB[16] = {0x00};
1717
1718 DES_cblock iv = { 0 };
1719 DES_key_schedule ks1,ks2;
1720 DES_cblock key1,key2;
1721
1722 memcpy(key,key3_3des_data,16);
1723 memcpy(key1,key,8);
1724 memcpy(key2,key+8,8);
1725
1726
1727 DES_set_key((DES_cblock *)key1,&ks1);
1728 DES_set_key((DES_cblock *)key2,&ks2);
1729
1730 DES_random_key(&RndA);
1731 PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
1732 PrintAndLog(" e_RndB:%s",sprint_hex(e_RndB, 8));
1733 //void DES_ede2_cbc_encrypt(const unsigned char *input,
1734 // unsigned char *output, long length, DES_key_schedule *ks1,
1735 // DES_key_schedule *ks2, DES_cblock *ivec, int enc);
1736 DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
1737
1738 PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
1739 rol(RndB,8);
1740 memcpy(RndARndB,RndA,8);
1741 memcpy(RndARndB+8,RndB,8);
1742 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
1743 DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
1744 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
1745
1746 }
1747 PrintAndLog("----------PolarSSL implementation----------");
1748 {
1749 uint8_t random_a[8] = { 0 };
1750 uint8_t enc_random_a[8] = { 0 };
1751 uint8_t random_b[8] = { 0 };
1752 uint8_t enc_random_b[8] = { 0 };
1753 uint8_t random_a_and_b[16] = { 0 };
1754 des3_context ctx = { 0 };
1755
1756 memcpy(random_a, RndA,8);
1757
1758 uint8_t output[8] = { 0 };
1759 uint8_t iv[8] = { 0 };
1760
1761 PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
1762 PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
1763
1764 des3_set2key_dec(&ctx, key);
1765
1766 des3_crypt_cbc(&ctx // des3_context *ctx
1767 , DES_DECRYPT // int mode
1768 , sizeof(random_b) // size_t length
1769 , iv // unsigned char iv[8]
1770 , enc_random_b // const unsigned char *input
1771 , random_b // unsigned char *output
1772 );
1773
1774 PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
1775
1776 rol(random_b,8);
1777 memcpy(random_a_and_b ,random_a,8);
1778 memcpy(random_a_and_b+8,random_b,8);
1779
1780 PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
1781
1782 des3_set2key_enc(&ctx, key);
1783
1784 des3_crypt_cbc(&ctx // des3_context *ctx
1785 , DES_ENCRYPT // int mode
1786 , sizeof(random_a_and_b) // size_t length
1787 , enc_random_b // unsigned char iv[8]
1788 , random_a_and_b // const unsigned char *input
1789 , random_a_and_b // unsigned char *output
1790 );
1791
1792 PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
1793 }
1794 return 0;
1795}
1796**/
1797
1798//
1799// Mifare Ultralight C - Set password
1800//
1801int CmdHF14AMfucSetPwd(const char *Cmd){
1802
1803 uint8_t pwd[16] = {0x00};
1804 char cmdp = param_getchar(Cmd, 0);
1805
1806 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetpwd();
1807
1808 if (param_gethex(Cmd, 0, pwd, 32)) {
1809 PrintAndLog("Password must include 32 HEX symbols");
1810 return 1;
1811 }
1812
1813 UsbCommand c = {CMD_MIFAREUC_SETPWD};
1814 memcpy( c.d.asBytes, pwd, 16);
1815 clearCommandBuffer();
1816 SendCommand(&c);
1817
1818 UsbCommand resp;
1819 if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
1820 if ( (resp.arg[0] & 0xff) == 1) {
1821 PrintAndLog("Ultralight-C new password: %s", sprint_hex(pwd,16));
1822 } else {
1823 PrintAndLog("Failed writing at block %d", resp.arg[1] & 0xff);
1824 return 1;
1825 }
1826 } else {
1827 PrintAndLog("command execution time out");
1828 return 1;
1829 }
1830 return 0;
1831}
1832
1833//
1834// Magic UL / UL-C tags - Set UID
1835//
1836int CmdHF14AMfucSetUid(const char *Cmd){
1837
1838 UsbCommand c;
1839 UsbCommand resp;
1840 uint8_t uid[7] = {0x00};
1841 char cmdp = param_getchar(Cmd, 0);
1842
1843 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetuid();
1844
1845 if (param_gethex(Cmd, 0, uid, 14)) {
1846 PrintAndLog("UID must include 14 HEX symbols");
1847 return 1;
1848 }
1849
1850 // read block2.
1851 c.cmd = CMD_MIFAREU_READBL;
1852 c.arg[0] = 2;
1853 clearCommandBuffer();
1854 SendCommand(&c);
1855 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1856 PrintAndLog("Command execute timeout");
1857 return 2;
1858 }
1859
1860 // save old block2.
1861 uint8_t oldblock2[4] = {0x00};
1862 memcpy(resp.d.asBytes, oldblock2, 4);
1863
1864 // block 0.
1865 c.cmd = CMD_MIFAREU_WRITEBL;
1866 c.arg[0] = 0;
1867 c.d.asBytes[0] = uid[0];
1868 c.d.asBytes[1] = uid[1];
1869 c.d.asBytes[2] = uid[2];
1870 c.d.asBytes[3] = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
1871 clearCommandBuffer();
1872 SendCommand(&c);
1873 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1874 PrintAndLog("Command execute timeout");
1875 return 3;
1876 }
1877
1878 // block 1.
1879 c.arg[0] = 1;
1880 c.d.asBytes[0] = uid[3];
1881 c.d.asBytes[1] = uid[4];
1882 c.d.asBytes[2] = uid[5];
1883 c.d.asBytes[3] = uid[6];
1884 clearCommandBuffer();
1885 SendCommand(&c);
1886 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
1887 PrintAndLog("Command execute timeout");
1888 return 4;
1889 }
1890
1891 // block 2.
1892 c.arg[0] = 2;
1893 c.d.asBytes[0] = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
1894 c.d.asBytes[1] = oldblock2[1];
1895 c.d.asBytes[2] = oldblock2[2];
1896 c.d.asBytes[3] = oldblock2[3];
1897 clearCommandBuffer();
1898 SendCommand(&c);
1899 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
1900 PrintAndLog("Command execute timeout");
1901 return 5;
1902 }
1903
1904 return 0;
1905}
1906
1907int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
1908
1909 uint8_t uid[4];
1910 char cmdp = param_getchar(Cmd, 0);
1911 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_gendiverse();
1912
1913 if (param_gethex(Cmd, 0, uid, 8)) {
1914 PrintAndLog("UID must include 8 HEX symbols");
1915 return 1;
1916 }
1917
1918 uint8_t iv[8] = { 0x00 };
1919 uint8_t block = 0x01;
1920
1921 uint8_t mifarekeyA[] = { 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5 };
1922 uint8_t mifarekeyB[] = { 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5 };
1923 uint8_t dkeyA[8] = { 0x00 };
1924 uint8_t dkeyB[8] = { 0x00 };
1925
1926 uint8_t masterkey[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
1927
1928 uint8_t mix[8] = { 0x00 };
1929 uint8_t divkey[8] = { 0x00 };
1930
1931 memcpy(mix, mifarekeyA, 4);
1932
1933 mix[4] = mifarekeyA[4] ^ uid[0];
1934 mix[5] = mifarekeyA[5] ^ uid[1];
1935 mix[6] = block ^ uid[2];
1936 mix[7] = uid[3];
1937
1938 des3_context ctx = { 0x00 };
1939 des3_set2key_enc(&ctx, masterkey);
1940
1941 des3_crypt_cbc(&ctx // des3_context
1942 , DES_ENCRYPT // int mode
1943 , sizeof(mix) // length
1944 , iv // iv[8]
1945 , mix // input
1946 , divkey // output
1947 );
1948
1949 PrintAndLog("-- 3DES version");
1950 PrintAndLog("Masterkey :\t %s", sprint_hex(masterkey,sizeof(masterkey)));
1951 PrintAndLog("UID :\t %s", sprint_hex(uid, sizeof(uid)));
1952 PrintAndLog("block :\t %0d", block);
1953 PrintAndLog("Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA)));
1954 PrintAndLog("Message :\t %s", sprint_hex(mix, sizeof(mix)));
1955 PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6));
1956
1957 for (int i=0; i < sizeof(mifarekeyA); ++i){
1958 dkeyA[i] = (mifarekeyA[i] << 1) & 0xff;
1959 dkeyA[6] |= ((mifarekeyA[i] >> 7) & 1) << (i+1);
1960 }
1961
1962 for (int i=0; i < sizeof(mifarekeyB); ++i){
1963 dkeyB[1] |= ((mifarekeyB[i] >> 7) & 1) << (i+1);
1964 dkeyB[2+i] = (mifarekeyB[i] << 1) & 0xff;
1965 }
1966
1967 uint8_t zeros[8] = {0x00};
1968 uint8_t newpwd[8] = {0x00};
1969 uint8_t dmkey[24] = {0x00};
1970 memcpy(dmkey, dkeyA, 8);
1971 memcpy(dmkey+8, dkeyB, 8);
1972 memcpy(dmkey+16, dkeyA, 8);
1973 memset(iv, 0x00, 8);
1974
1975 des3_set3key_enc(&ctx, dmkey);
1976
1977 des3_crypt_cbc(&ctx // des3_context
1978 , DES_ENCRYPT // int mode
1979 , sizeof(newpwd) // length
1980 , iv // iv[8]
1981 , zeros // input
1982 , newpwd // output
1983 );
1984
1985 PrintAndLog("\n-- DES version");
1986 PrintAndLog("Mifare dkeyA :\t %s", sprint_hex(dkeyA, sizeof(dkeyA)));
1987 PrintAndLog("Mifare dkeyB :\t %s", sprint_hex(dkeyB, sizeof(dkeyB)));
1988 PrintAndLog("Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey)));
1989 PrintAndLog("Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd)));
1990
1991 // next. from the diversify_key method.
1992 return 0;
1993}
1994
1995int CmdHF14AMfUeLoad(const char *Cmd) {
1996 char ctmp = param_getchar(Cmd, 0);
1997 if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf_mfu_eload();
1998 return CmdHF14AMfELoad(Cmd);
1999}
2000
2001int CmdHF14AMfUSim(const char *Cmd) {
2002 char ctmp = param_getchar(Cmd, 0);
2003 if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf_mfu_sim();
2004 return CmdHF14ASim(Cmd);
2005}
2006
2007//------------------------------------
2008// Menu Stuff
2009//------------------------------------
2010static command_t CommandTable[] =
2011{
2012 {"help", CmdHelp, 1, "This help"},
2013 {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
2014 {"info", CmdHF14AMfUInfo, 0, "Tag information"},
2015 {"dump", CmdHF14AMfUDump, 0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"},
2016 {"eload", CmdHF14AMfUeLoad, 0, "load Ultralight .eml dump file into emulator memory"},
2017 {"rdbl", CmdHF14AMfURdBl, 0, "Read block"},
2018 {"wrbl", CmdHF14AMfUWrBl, 0, "Write block"},
2019 {"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"},
2020 {"setpwd", CmdHF14AMfucSetPwd, 0, "Set 3des password - Ultralight-C"},
2021 {"setuid", CmdHF14AMfucSetUid, 0, "Set UID - MAGIC tags only"},
2022 {"sim", CmdHF14AMfUSim, 0, "Simulate Ultralight from emulator memory"},
2023 {"gen", CmdHF14AMfuGenDiverseKeys , 1, "Generate 3des mifare diversified keys"},
2024 {NULL, NULL, 0, NULL}
2025};
2026
2027int CmdHFMFUltra(const char *Cmd){
2028 clearCommandBuffer();
2029 //WaitForResponseTimeout(CMD_ACK,NULL,100);
2030 CmdsParse(CommandTable, Cmd);
2031 return 0;
2032}
2033
2034int CmdHelp(const char *Cmd){
2035 CmdsHelp(CommandTable);
2036 return 0;
2037}
Impressum, Datenschutz