]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhfmfu.c
CHG: missing file extension.
[proxmark3-svn] / client / cmdhfmfu.c
CommitLineData
81740aa5 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//-----------------------------------------------------------------------------
afceaf40 10#include "loclass/des.h"
81740aa5 11#include "cmdhfmfu.h"
12#include "cmdhfmf.h"
13#include "cmdhf14a.h"
5d554ea6 14#include "mifare.h"
2c74558d 15#include "util.h"
95aeb706 16#include "protocols.h"
e7e95088 17#include "data.h"
81740aa5 18
75377d29 19#define MAX_UL_BLOCKS 0x0f
9d87eb66 20#define MAX_ULC_BLOCKS 0x2b
8241872c 21#define MAX_ULEV1a_BLOCKS 0x13
a383f4b7 22#define MAX_ULEV1b_BLOCKS 0x28
23#define MAX_NTAG_203 0x29
24#define MAX_NTAG_210 0x13
25#define MAX_NTAG_212 0x28
75377d29 26#define MAX_NTAG_213 0x2c
27#define MAX_NTAG_215 0x86
28#define MAX_NTAG_216 0xe6
1c6e7f03 29#define MAX_MY_D_NFC 0xff
30#define MAX_MY_D_MOVE 0x25
31#define MAX_MY_D_MOVE_LEAN 0x0f
2c74558d 32
ebd7412d 33#define KEYS_3DES_COUNT 7
34uint8_t default_3des_keys[KEYS_3DES_COUNT][16] = {
a8be77af 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
f168b263 41 { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF } // 11 22 33
75377d29 42};
aebe7790 43
5247c0c1 44#define KEYS_PWD_COUNT 1
ebd7412d 45uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = {
aebe7790 46 {0xFF,0xFF,0xFF,0xFF}, // PACK 0x00,0x00 -- factory default
c585a5cf 47};
48
22e24700 49#define MAX_UL_TYPES 18
0de8e387 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};
833081e3 65
9984b173 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
dd79e03a 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
683180cb 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
9984b173 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<--");
dd79e03a 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<--");
9984b173 148 return;
149}
833081e3 150
81740aa5 151static int CmdHelp(const char *Cmd);
152
1c6e7f03 153// get version nxp product type
8258f409 154char *getProductTypeStr( uint8_t id){
2c74558d 155
75377d29 156 static char buf[20];
2c74558d 157 char *retStr = buf;
158
159 switch(id) {
329f5cf2 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;
2c74558d 163 }
164 return buf;
165}
a8be77af 166
2c74558d 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*/
8258f409 172char *getUlev1CardSizeStr( uint8_t fsize ){
75377d29 173
345fb24a 174 static char buf[40];
2c74558d 175 char *retStr = buf;
2be768af 176 memset(buf, 0, sizeof(buf));
75377d29 177
fce738fc 178 uint16_t usize = 1 << ((fsize >>1) + 1);
179 uint16_t lsize = 1 << (fsize >>1);
180
2c74558d 181 // is LSB set?
75377d29 182 if ( fsize & 1 )
06561c34 183 sprintf(retStr, "%02X, (%u <-> %u bytes)",fsize, usize, lsize);
2c74558d 184 else
329f5cf2 185 sprintf(retStr, "%02X, (%u bytes)", fsize, lsize);
2c74558d 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}};
95aeb706 191 clearCommandBuffer();
a8be77af 192 SendCommand(&c);
2c74558d 193}
a8be77af 194
98cdd568 195void ul_switch_off_field(void) {
2c74558d 196 UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
95aeb706 197 clearCommandBuffer();
2c74558d 198 SendCommand(&c);
a8be77af 199}
200
8297860e 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);
95aeb706 204 clearCommandBuffer();
2c74558d 205 SendCommand(&c);
206 UsbCommand resp;
75377d29 207 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
372a8257 208 if (!resp.arg[0] && responseLength) return -1;
75377d29 209
802319a3 210 uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
aebe7790 211 memcpy(response, resp.d.asBytes, resplen);
212 return resplen;
2c74558d 213}
1ec21089 214
2c74558d 215static int ul_select( iso14a_card_select_t *card ){
75377d29 216
2c74558d 217 ul_switch_on_field();
218
219 UsbCommand resp;
1fa96198 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 }
75377d29 227
228 memcpy(card, resp.d.asBytes, sizeof(iso14a_card_select_t));
c7442b76 229 return 1;
75377d29 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);
75377d29 237 return len;
238}
239
c585a5cf 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};
8258f409 251 ul_send_cmd_raw(cmd, 2+datalen, response, sizeof(response));
c585a5cf 252 // ACK
253 if ( response[0] == 0x0a ) return 0;
254 // NACK
255 return -1;
256}
345fb24a 257
a2e2bb8a 258static int ulc_requestAuthentication( uint8_t *nonce, uint16_t nonceLength ){
75377d29 259
a2e2bb8a 260 uint8_t cmd[] = {MIFARE_ULC_AUTH_1, 0x00};
75377d29 261 int len = ul_send_cmd_raw(cmd, sizeof(cmd), nonce, nonceLength);
75377d29 262 return len;
263}
345fb24a 264
8258f409 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);
95aeb706 269 clearCommandBuffer();
8258f409 270 SendCommand(&c);
271 UsbCommand resp;
9d87eb66 272 if ( !WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) return 0;
273 if ( resp.arg[0] == 1 ) return 1;
8258f409 274
9d87eb66 275 return 0;
8258f409 276}
277
75377d29 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);
75377d29 282 return len;
283}
284
bcf61bd3 285static int ul_auth_select( iso14a_card_select_t *card, TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authenticationkey, uint8_t *pack, uint8_t packSize){
fff69a1e 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) {
8c671cfb 296 if (ulev1_requestAuthentication(authenticationkey, pack, packSize) < 2) {
fff69a1e 297 ul_switch_off_field();
298 PrintAndLog("Error: Authentication Failed UL-EV1/NTAG");
299 return 0;
300 }
301 }
302 }
303 return 1;
304}
305
8297860e 306static int ulev1_getVersion( uint8_t *response, uint16_t responseLength ){
75377d29 307
2c74558d 308 uint8_t cmd[] = {MIFARE_ULEV1_VERSION};
8297860e 309 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
2c74558d 310 return len;
311}
312
8297860e 313static int ulev1_readCounter( uint8_t counter, uint8_t *response, uint16_t responseLength ){
2c74558d 314
315 uint8_t cmd[] = {MIFARE_ULEV1_READ_CNT, counter};
8297860e 316 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
2c74558d 317 return len;
318}
319
98cdd568 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);
98cdd568 324 return len;
325}
326
69a29536 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);
69a29536 331 return len;
332}
333
24344f28 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//
7c8b5e68 346// make sure field is off before calling this function
22e24700 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
a903be43 365static int ul_print_default( uint8_t *data){
75377d29 366
a903be43 367 uint8_t uid[7];
a903be43 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));
46cd801c 377 PrintAndLog(" UID[0] : %02X, %s", uid[0], getTagInfo(uid[0]) );
1c6e7f03 378 if ( uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2 ) { // is infineon and 66RxxP
fce738fc 379 uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU
380 switch (chip){
1c6e7f03 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
fce738fc 384 }
385 }
a903be43 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 )
fce738fc 389 PrintAndLog(" BCC0 : %02X, Ok", data[3]);
a903be43 390 else
fce738fc 391 PrintAndLog(" BCC0 : %02X, crc should be %02X", data[3], crc0);
75377d29 392
a903be43 393 int crc1 = data[4] ^ data[5] ^ data[6] ^data[7];
394 if ( data[8] == crc1 )
fce738fc 395 PrintAndLog(" BCC1 : %02X, Ok", data[8]);
a903be43 396 else
fce738fc 397 PrintAndLog(" BCC1 : %02X, crc should be %02X", data[8], crc1 );
75377d29 398
fce738fc 399 PrintAndLog(" Internal : %02X, %sdefault", data[9], (data[9]==0x48)?"":"not " );
fce738fc 400
7a5d49b5 401 PrintAndLog(" Lock : %s - %s",
402 sprint_hex(data+10, 2),
9984b173 403 sprint_bin(data+10, 2)
7a5d49b5 404 );
405
6fdf42c6 406 PrintAndLog("OneTimePad : %s - %s\n",
407 sprint_hex(data + 12, 4),
9984b173 408 sprint_bin(data+12, 4)
6fdf42c6 409 );
29250969 410
75377d29 411 return 0;
412}
413
a383f4b7 414static int ndef_print_CC(uint8_t *data) {
1c429594 415 // no NDEF message
416 if(data[0] != 0xe1)
417 return -1;
75377d29 418
a383f4b7 419 PrintAndLog("--- NDEF Message");
75377d29 420 PrintAndLog("Capability Container: %s", sprint_hex(data,4) );
1c429594 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);
1c6e7f03 424 if ( data[2] == 0x96 )
425 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 48);
426 else if ( data[2] == 0x12 )
1c429594 427 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 144);
c585a5cf 428 else if ( data[2] == 0x3e )
1c429594 429 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 496);
c585a5cf 430 else if ( data[2] == 0x6d )
1c429594 431 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 872);
432
433 PrintAndLog(" %02X : %s / %s", data[3],
75377d29 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)");
75377d29 436 return 0;
437}
438
c7442b76 439int ul_print_type(uint32_t tagtype, uint8_t spaces){
8ceb6b03 440 char spc[11] = " ";
441 spc[10]=0x00;
442 char *spacer = spc + (10-spaces);
443
75377d29 444 if ( tagtype & UL )
1c429594 445 PrintAndLog("%sTYPE : MIFARE Ultralight (MF0ICU1) %s", spacer, (tagtype & MAGIC) ? "<magic>" : "" );
75377d29 446 else if ( tagtype & UL_C)
1c429594 447 PrintAndLog("%sTYPE : MIFARE Ultralight C (MF0ULC) %s", spacer, (tagtype & MAGIC) ? "<magic>" : "" );
75377d29 448 else if ( tagtype & UL_EV1_48)
8ceb6b03 449 PrintAndLog("%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer);
1c429594 450 else if ( tagtype & UL_EV1_128)
8ceb6b03 451 PrintAndLog("%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer);
a383f4b7 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);
c7442b76 456 else if ( tagtype & NTAG_210 )
1c429594 457 PrintAndLog("%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer);
c7442b76 458 else if ( tagtype & NTAG_212 )
a383f4b7 459 PrintAndLog("%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer);
460 else if ( tagtype & NTAG_213 )
461 PrintAndLog("%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer);
75377d29 462 else if ( tagtype & NTAG_215 )
a383f4b7 463 PrintAndLog("%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer);
75377d29 464 else if ( tagtype & NTAG_216 )
a383f4b7 465 PrintAndLog("%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer);
46fcd738 466 else if ( tagtype & NTAG_I2C_1K )
cd87ee91 467 PrintAndLog("%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer, "\xFD");
46fcd738 468 else if ( tagtype & NTAG_I2C_2K )
cd87ee91 469 PrintAndLog("%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer, "\xFD");
345fb24a 470 else if ( tagtype & MY_D )
22e24700 471 PrintAndLog("%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer);
345fb24a 472 else if ( tagtype & MY_D_NFC )
22e24700 473 PrintAndLog("%sTYPE : INFINEON my-d\x99 NFC (SLE 66RxxP)", spacer);
345fb24a 474 else if ( tagtype & MY_D_MOVE )
22e24700 475 PrintAndLog("%sTYPE : INFINEON my-d\x99 move (SLE 66R01P)", spacer);
345fb24a 476 else if ( tagtype & MY_D_MOVE_NFC )
22e24700 477 PrintAndLog("%sTYPE : INFINEON my-d\x99 move NFC (SLE 66R01P)", spacer);
1c6e7f03 478 else if ( tagtype & MY_D_MOVE_LEAN )
479 PrintAndLog("%sTYPE : INFINEON my-d\x99 move lean (SLE 66R01L)", spacer);
22e24700 480 else if ( tagtype & FUDAN_UL )
481 PrintAndLog("%sTYPE : FUDAN Ultralight Compatible (or other compatible) %s", spacer, (tagtype & MAGIC) ? "<magic>" : "" );
75377d29 482 else
c7442b76 483 PrintAndLog("%sTYPE : Unknown %06x", spacer, tagtype);
75377d29 484 return 0;
485}
486
487static int ulc_print_3deskey( uint8_t *data){
1c429594 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);
2b3af97d 492 PrintAndLog("\n 3des key : %s", sprint_hex(SwapEndian64(data, 16, 8), 16));
75377d29 493 return 0;
494}
495
496static int ulc_print_configuration( uint8_t *data){
497
498 PrintAndLog("--- UL-C Configuration");
9984b173 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));
75377d29 501
502 bool validAuth = (data[8] >= 0x03 && data[8] <= 0x30);
503 if ( validAuth )
1c429594 504 PrintAndLog(" Auth0 [42/0x2A] : %s page %d/0x%02X and above need authentication", sprint_hex(data+8, 4), data[8],data[8] );
75377d29 505 else{
506 if ( data[8] == 0){
1c429594 507 PrintAndLog(" Auth0 [42/0x2A] : %s default", sprint_hex(data+8, 4) );
75377d29 508 } else {
1c429594 509 PrintAndLog(" Auth0 [42/0x2A] : %s auth byte is out-of-range", sprint_hex(data+8, 4) );
f168b263 510 }
75377d29 511 }
1c429594 512 PrintAndLog(" Auth1 [43/0x2B] : %s %s",
75377d29 513 sprint_hex(data+12, 4),
514 (data[12] & 1) ? "write access restricted": "read and write access restricted"
515 );
f168b263 516 return 0;
517}
81740aa5 518
012c0761 519static int ulev1_print_configuration( uint8_t *data, uint8_t startPage){
f168b263 520
a383f4b7 521 PrintAndLog("\n--- Tag Configuration");
75377d29 522
523 bool strg_mod_en = (data[0] & 2);
524 uint8_t authlim = (data[4] & 0x07);
5636ee8c 525 bool nfc_cnf_en = (data[4] & 0x08);
526 bool nfc_cnf_prot_pwd = (data[4] & 0x10);
75377d29 527 bool cfglck = (data[4] & 0x40);
528 bool prot = (data[4] & 0x80);
529 uint8_t vctid = data[5];
530
012c0761 531 PrintAndLog(" cfg0 [%u/0x%02X] : %s", startPage, startPage, sprint_hex(data, 4));
345fb24a 532 if ( data[3] < 0xff )
a2e2bb8a 533 PrintAndLog(" - page %d and above need authentication",data[3]);
345fb24a 534 else
535 PrintAndLog(" - pages don't need authentication");
75377d29 536 PrintAndLog(" - strong modulation mode %s", (strg_mod_en) ? "enabled":"disabled");
012c0761 537 PrintAndLog(" cfg1 [%u/0x%02X] : %s", startPage + 1, startPage + 1, sprint_hex(data+4, 4) );
75377d29 538 if ( authlim == 0)
345fb24a 539 PrintAndLog(" - Unlimited password attempts");
75377d29 540 else
541 PrintAndLog(" - Max number of password attempts is %d", authlim);
5636ee8c 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
75377d29 546 PrintAndLog(" - user configuration %s", cfglck ? "permanently locked":"writeable");
547 PrintAndLog(" - %s access is protected with password", prot ? "read and write":"write");
1c429594 548 PrintAndLog(" - %02X, Virtual Card Type Identifier is %s default", vctid, (vctid==0x05)? "":"not");
012c0761 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));
75377d29 552 return 0;
553}
554
555static int ulev1_print_counters(){
a383f4b7 556 PrintAndLog("--- Tag Counters");
a2e2bb8a 557 uint8_t tear[1] = {0};
75377d29 558 uint8_t counter[3] = {0,0,0};
c7442b76 559 uint16_t len = 0;
75377d29 560 for ( uint8_t i = 0; i<3; ++i) {
a2e2bb8a 561 ulev1_readTearing(i,tear,sizeof(tear));
c7442b76 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 }
75377d29 567 }
c7442b76 568 return len;
75377d29 569}
570
c585a5cf 571static int ulev1_print_signature( uint8_t *data, uint8_t len){
a383f4b7 572 PrintAndLog("\n--- Tag Signature");
06561c34 573 //PrintAndLog("IC signature public key name : NXP NTAG21x 2013"); // don't know if there is other NXP public keys.. :(
c585a5cf 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}
345fb24a 581
582static int ulev1_print_version(uint8_t *data){
a383f4b7 583 PrintAndLog("\n--- Tag Version");
1c429594 584 PrintAndLog(" Raw bytes : %s",sprint_hex(data, 8) );
585 PrintAndLog(" Vendor ID : %02X, %s", data[1], getTagInfo(data[1]));
345fb24a 586 PrintAndLog(" Product type : %s", getProductTypeStr(data[2]));
1c429594 587 PrintAndLog(" Product subtype : %02X, %s", data[3], (data[3]==1) ?"17 pF":"50pF");
345fb24a 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
f04ef473 595/*
c585a5cf 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);
c7442b76 608 if ( !status ){
c585a5cf 609 return UL_ERROR;
610 }
a2e2bb8a 611 status = ulc_requestAuthentication(nonce1, sizeof(nonce1));
c585a5cf 612 if ( status > 0 ) {
a2e2bb8a 613 status = ulc_requestAuthentication(nonce2, sizeof(nonce2));
c585a5cf 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}
f04ef473 621*/
c585a5cf 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;
c7442b76 628 if ( !ul_select(&card) )
c585a5cf 629 return UL_ERROR;
46fcd738 630 int status = ul_comp_write(0, NULL, 0);
c585a5cf 631 ul_switch_off_field();
a2e2bb8a 632 if ( status == 0 )
46fcd738 633 return MAGIC;
634 return 0;
c585a5cf 635}
f04ef473 636
c7442b76 637uint32_t GetHF14AMfU_Type(void){
81740aa5 638
92690507 639 TagTypeUL_t tagtype = UNKNOWN;
640 iso14a_card_select_t card;
75377d29 641 uint8_t version[10] = {0x00};
75377d29 642 int status = 0;
643 int len;
644
c7442b76 645 if (!ul_select(&card)) return UL_ERROR;
646
92690507 647 // Ultralight - ATQA / SAK
abab60ae 648 if ( card.atqa[1] != 0x00 || card.atqa[0] != 0x44 || card.sak != 0x00 ) {
4693c188 649 PrintAndLog("Tag is not Ultralight | NTAG | MY-D [ATQA: %02X %02X SAK: %02X]\n", card.atqa[1], card.atqa[0], card.sak);
75377d29 650 ul_switch_off_field();
651 return UL_ERROR;
652 }
92690507 653
345fb24a 654 if ( card.uid[0] != 0x05) {
75377d29 655
345fb24a 656 len = ulev1_getVersion(version, sizeof(version));
8258f409 657 ul_switch_off_field();
345fb24a 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;
a383f4b7 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 )
345fb24a 671 tagtype = NTAG_213;
a383f4b7 672 else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x11 )
345fb24a 673 tagtype = NTAG_215;
a383f4b7 674 else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x13 )
345fb24a 675 tagtype = NTAG_216;
c7442b76 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;
345fb24a 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;
46fcd738 687 case -1 : tagtype = (UL | UL_C | NTAG_203); break; // could be UL | UL_C magic tags
345fb24a 688 default : tagtype = UNKNOWN; break;
689 }
a383f4b7 690 // UL vs UL-C vs ntag203 test
691 if (tagtype & (UL | UL_C | NTAG_203)) {
c7442b76 692 if ( !ul_select(&card) ) return UL_ERROR;
a383f4b7 693
694 // do UL_C check first...
8258f409 695 uint8_t nonce[11] = {0x00};
696 status = ulc_requestAuthentication(nonce, sizeof(nonce));
8258f409 697 ul_switch_off_field();
a383f4b7 698 if (status > 1) {
699 tagtype = UL_C;
700 } else {
701 // need to re-select after authentication error
c7442b76 702 if ( !ul_select(&card) ) return UL_ERROR;
703
a383f4b7 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)
efd19351 711 status = ul_read(0x30, data, sizeof(data));
a383f4b7 712 if ( status <= 1 ){
713 tagtype = NTAG_203;
714 } else {
715 tagtype = UNKNOWN;
716 }
717 }
718 ul_switch_off_field();
719 }
345fb24a 720 }
22e24700 721 if (tagtype & UL) {
722 tagtype = ul_fudan_check();
723 ul_switch_off_field();
724 }
345fb24a 725 } else {
1c6e7f03 726 ul_switch_off_field();
345fb24a 727 // Infinition MY-D tests Exam high nibble
728 uint8_t nib = (card.uid[1] & 0xf0) >> 4;
729 switch ( nib ){
1c6e7f03 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
75377d29 735 }
f168b263 736 }
75377d29 737
46fcd738 738 tagtype |= ul_magic_test();
739 if (tagtype == (UNKNOWN | MAGIC)) tagtype = (UL_MAGIC);
f168b263 740 return tagtype;
741}
742
743int CmdHF14AMfUInfo(const char *Cmd){
744
c585a5cf 745 uint8_t authlim = 0xff;
f168b263 746 uint8_t data[16] = {0x00};
75377d29 747 iso14a_card_select_t card;
75377d29 748 int status;
a2e2bb8a 749 bool errors = false;
750 bool hasAuthKey = false;
a383f4b7 751 bool locked = false;
06561c34 752 bool swapEndian = false;
a2e2bb8a 753 uint8_t cmdp = 0;
06561c34 754 uint8_t dataLen = 0;
a2e2bb8a 755 uint8_t authenticationkey[16] = {0x00};
06561c34 756 uint8_t *authkeyptr = authenticationkey;
5247c0c1 757 uint8_t pwd[4] = {0,0,0,0};
758 uint8_t *key = pwd;
a2e2bb8a 759 uint8_t pack[4] = {0,0,0,0};
06561c34 760 int len = 0;
761 char tempStr[50];
f168b263 762
a2e2bb8a 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':
06561c34 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");
bcf61bd3 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)) {
fce738fc 826
bcf61bd3 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;
a903be43 837
bcf61bd3 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);
fce738fc 848
bcf61bd3 849 } else {
850 ul_switch_off_field();
851 // if we called info with key, just return
852 if ( hasAuthKey ) return 1;
1ec21089 853
bcf61bd3 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 }
98cdd568 869
bcf61bd3 870 // do counters and signature first (don't neet auth)
2c74558d 871
bcf61bd3 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 }
b9a3c864 879
0de8e387 880 // Read signature
bcf61bd3 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 }
b9a3c864 895
0de8e387 896 // Get Version
bcf61bd3 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);
b9a3c864 906 } else {
bcf61bd3 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;
5247c0c1 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;
dd79e03a 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;
5247c0c1 962
bcf61bd3 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");
b9a3c864 974 }
975 }
bcf61bd3 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;
b9a3c864 981}
982
81740aa5 983//
fff69a1e 984// Write Single Block
81740aa5 985//
986int CmdHF14AMfUWrBl(const char *Cmd){
81740aa5 987
fff69a1e 988 int blockNo = -1;
989 bool errors = false;
990 bool hasAuthKey = false;
991 bool hasPwdKey = false;
992 bool swapEndian = false;
81740aa5 993
fff69a1e 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};
46cd801c 999 uint8_t *authKeyPtr = authenticationkey;
79d7bcbb 1000
fff69a1e 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);
fff69a1e 1032 if (blockNo < 0) {
1033 PrintAndLog("Wrong block number");
fff69a1e 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();
afceaf40 1059 }
fff69a1e 1060
f6059703 1061 if ( blockNo == -1 ) return usage_hf_mfu_wrbl();
24344f28 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 }
79d7bcbb 1075
fff69a1e 1076 // Swap endianness
46cd801c 1077 if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
1078 if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
fff69a1e 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));
81740aa5 1084
fff69a1e 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;
46cd801c 1091 memcpy(c.d.asBytes+4,authKeyPtr,16);
fff69a1e 1092 }
1093 else if ( hasPwdKey ) {
1094 c.arg[1] = 2;
46cd801c 1095 memcpy(c.d.asBytes+4,authKeyPtr,4);
afceaf40 1096 }
81740aa5 1097
95aeb706 1098 clearCommandBuffer();
fff69a1e 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);
81740aa5 1104 } else {
fff69a1e 1105 PrintAndLog("Command execute timeout");
afceaf40 1106 }
fff69a1e 1107
afceaf40 1108 return 0;
81740aa5 1109}
81740aa5 1110//
fff69a1e 1111// Read Single Block
81740aa5 1112//
1113int CmdHF14AMfURdBl(const char *Cmd){
81740aa5 1114
fff69a1e 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};
46cd801c 1124 uint8_t *authKeyPtr = authenticationkey;
c3c241f3 1125
fff69a1e 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);
fff69a1e 1157 if (blockNo < 0) {
1158 PrintAndLog("Wrong block number");
fff69a1e 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();
afceaf40 1175 }
95aeb706 1176
fff69a1e 1177 if ( blockNo == -1 ) return usage_hf_mfu_rdbl();
24344f28 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 }
afceaf40 1191
fff69a1e 1192 // Swap endianness
46cd801c 1193 if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
1194 if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
fff69a1e 1195
1196 //Read Block
afceaf40 1197 UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
fff69a1e 1198 if ( hasAuthKey ){
1199 c.arg[1] = 1;
46cd801c 1200 memcpy(c.d.asBytes,authKeyPtr,16);
fff69a1e 1201 }
1202 else if ( hasPwdKey ) {
1203 c.arg[1] = 2;
46cd801c 1204 memcpy(c.d.asBytes,authKeyPtr,4);
fff69a1e 1205 }
1206
95aeb706 1207 clearCommandBuffer();
afceaf40 1208 SendCommand(&c);
ce432659 1209 UsbCommand resp;
afceaf40 1210 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
aa60d156 1211 uint8_t isOK = resp.arg[0] & 0xff;
1212 if (isOK) {
1213 uint8_t *data = resp.d.asBytes;
95aeb706 1214 PrintAndLog("\nBlock# | Data | Ascii");
1215 PrintAndLog("-----------------------------");
1216 PrintAndLog("%02d/0x%02X | %s| %.4s\n", blockNo, blockNo, sprint_hex(data, 4), data);
aa60d156 1217 }
1218 else {
1219 PrintAndLog("Failed reading block: (%02x)", isOK);
1220 }
81740aa5 1221 } else {
aa60d156 1222 PrintAndLog("Command execute time-out");
afceaf40
MHS
1223 }
1224 return 0;
81740aa5 1225}
1226
fff69a1e 1227int usage_hf_mfu_info(void) {
98cdd568 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");
2491a252 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");
98cdd568 1233 PrintAndLog("my-d, my-d NFC, my-d move, my-d move NFC\n");
2491a252 1234 PrintAndLog("Usage: hf mfu info k <key> l");
98cdd568 1235 PrintAndLog(" Options : ");
2491a252 1236 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1237 PrintAndLog(" l : (optional) swap entered key's endianness");
98cdd568 1238 PrintAndLog("");
1239 PrintAndLog(" sample : hf mfu info");
2491a252 1240 PrintAndLog(" : hf mfu info k 00112233445566778899AABBCCDDEEFF");
1241 PrintAndLog(" : hf mfu info k AABBCCDDD");
98cdd568 1242 return 0;
1243}
1244
fff69a1e 1245int usage_hf_mfu_dump(void) {
1ec21089 1246 PrintAndLog("Reads all pages from Ultralight, Ultralight-C, Ultralight EV1");
2491a252 1247 PrintAndLog("NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216");
1ec21089 1248 PrintAndLog("and saves binary dump into the file `filename.bin` or `cardUID.bin`");
1249 PrintAndLog("It autodetects card type.\n");
8c671cfb 1250 PrintAndLog("Usage: hf mfu dump k <key> l n <filename w/o .bin> p <page#> q <#pages>");
1251 PrintAndLog(" Options :");
2491a252 1252 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1253 PrintAndLog(" l : (optional) swap entered key's endianness");
833081e3 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");
2b03dea7 1257 PrintAndLog("");
1ec21089 1258 PrintAndLog(" sample : hf mfu dump");
2c74558d 1259 PrintAndLog(" : hf mfu dump n myfile");
98cdd568 1260 PrintAndLog(" : hf mfu dump k 00112233445566778899AABBCCDDEEFF");
2491a252 1261 PrintAndLog(" : hf mfu dump k AABBCCDDD\n");
1ec21089 1262 return 0;
1263}
98cdd568 1264
fff69a1e 1265int usage_hf_mfu_rdbl(void) {
1266 PrintAndLog("Read a block and print. It autodetects card type.\n");
2491a252 1267 PrintAndLog("Usage: hf mfu rdbl b <block number> k <key> l\n");
fff69a1e 1268 PrintAndLog(" Options:");
fff69a1e 1269 PrintAndLog(" b <no> : block to read");
2491a252 1270 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1271 PrintAndLog(" l : (optional) swap entered key's endianness");
fff69a1e 1272 PrintAndLog("");
2491a252 1273 PrintAndLog(" sample : hf mfu rdbl b 0");
fff69a1e 1274 PrintAndLog(" : hf mfu rdbl b 0 k 00112233445566778899AABBCCDDEEFF");
2491a252 1275 PrintAndLog(" : hf mfu rdbl b 0 k AABBCCDDD\n");
fff69a1e 1276 return 0;
1277}
1278
1279int usage_hf_mfu_wrbl(void) {
f6059703 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");
2491a252 1282 PrintAndLog(" Options:");
fff69a1e 1283 PrintAndLog(" b <no> : block to write");
2491a252 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");
fff69a1e 1287 PrintAndLog("");
2491a252 1288 PrintAndLog(" sample : hf mfu wrbl b 0 d 01234567");
1289 PrintAndLog(" : hf mfu wrbl b 0 d 01234567 k AABBCCDDD\n");
fff69a1e 1290 return 0;
1291}
1292
24344f28 1293int usage_hf_mfu_eload(void) {
2b1f4228 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");
9332b857 1299 PrintAndLog(" u : UL (required)");
1300 PrintAndLog(" [filename] : without `.eml` (required)");
1301 PrintAndLog(" numblocks : number of blocks to load from eml file (optional)");
24344f28 1302 PrintAndLog("");
2b1f4228 1303 PrintAndLog(" sample: hf mfu eload u filename");
1304 PrintAndLog(" hf mfu eload u filename 57");
9332b857 1305 return 0;
2b1f4228 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>");
9332b857 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)");
2b1f4228 1316 PrintAndLog("\n sample : hf mfu sim t 7");
1317 PrintAndLog(" : hf mfu sim t 7 u 1122344556677\n");
9332b857 1318
24344f28 1319 return 0;
1320}
1321
1d0ccbe0 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
683180cb 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
2b1f4228 1371#define DUMP_PREFIX_LENGTH 48
81740aa5 1372//
1ec21089 1373// Mifare Ultralight / Ultralight-C / Ultralight-EV1
1374// Read and Dump Card Contents, using auto detection of tag size.
81740aa5 1375int CmdHF14AMfUDump(const char *Cmd){
1376
afceaf40 1377 FILE *fout;
81740aa5 1378 char filename[FILE_PATH_SIZE] = {0x00};
92690507 1379 char *fnameptr = filename;
afceaf40
MHS
1380 uint8_t *lockbytes_t = NULL;
1381 uint8_t lockbytes[2] = {0x00};
afceaf40
MHS
1382 uint8_t *lockbytes_t2 = NULL;
1383 uint8_t lockbytes2[2] = {0x00};
afceaf40 1384 bool bit[16] = {0x00};
81740aa5 1385 bool bit2[16] = {0x00};
2c74558d 1386 uint8_t data[1024] = {0x00};
2491a252 1387 bool hasAuthKey = false;
1ec21089 1388 int i = 0;
1389 int Pages = 16;
1390 bool tmplockbit = false;
06561c34 1391 uint8_t dataLen = 0;
1392 uint8_t cmdp = 0;
2491a252 1393 uint8_t authenticationkey[16] = {0x00};
8c671cfb 1394 memset(authenticationkey, 0x00, sizeof(authenticationkey));
06561c34 1395 uint8_t *authKeyPtr = authenticationkey;
2c74558d 1396 size_t fileNlen = 0;
2b03dea7 1397 bool errors = false;
1398 bool swapEndian = false;
833081e3 1399 bool manualPages = false;
1400 uint8_t startPage = 0;
1401 char tempStr[50];
2c74558d 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':
833081e3 1412 dataLen = param_getstr(Cmd, cmdp+1, tempStr);
a7e7cd41 1413 if (dataLen == 32 || dataLen == 8) { //ul-c or ev1/ntag key length
2491a252 1414 errors = param_gethex(tempStr, 0, authenticationkey, dataLen);
a7e7cd41 1415 dataLen /= 2;
1416 } else {
e7e95088 1417 PrintAndLog("\nERROR: Key is incorrect length\n");
1418 errors = true;
833081e3 1419 }
2c74558d 1420 cmdp += 2;
2491a252 1421 hasAuthKey = true;
833081e3 1422 break;
1423 case 'l':
1424 case 'L':
1425 swapEndian = true;
1426 cmdp++;
2c74558d 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;
833081e3 1435 case 'p':
2b1f4228 1436 case 'P': //set start page
833081e3 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;
ebd7412d 1446 break;
2c74558d 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();
75377d29 1457
e869d598 1458 //if we entered a key in little endian and set the swapEndian switch - switch it...
a7e7cd41 1459 if (swapEndian && hasAuthKey)
1460 authKeyPtr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4);
2b03dea7 1461
1ec21089 1462 TagTypeUL_t tagtype = GetHF14AMfU_Type();
1463 if (tagtype == UL_ERROR) return -1;
81740aa5 1464
46cd801c 1465 if (!manualPages) //get number of pages to read
833081e3 1466 for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++)
1467 if (tagtype & UL_TYPES_ARRAY[idx])
46cd801c 1468 Pages = UL_MEMORY_ARRAY[idx]+1; //add one as maxblks starts at 0
833081e3 1469
1470 ul_print_type(tagtype, 0);
1471 PrintAndLog("Reading tag memory...");
e7e95088 1472 UsbCommand c = {CMD_MIFAREU_READCARD, {startPage,Pages}};
06561c34 1473 if ( hasAuthKey ) {
e7e95088 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
a7e7cd41 1479 memcpy(c.d.asBytes, authKeyPtr, dataLen);
833081e3 1480 }
95aeb706 1481
1482 clearCommandBuffer();
afceaf40
MHS
1483 SendCommand(&c);
1484 UsbCommand resp;
cceabb79 1485 if (!WaitForResponseTimeout(CMD_ACK, &resp,1500)) {
aa60d156 1486 PrintAndLog("Command execute time-out");
2c74558d 1487 return 1;
81740aa5 1488 }
e7e95088 1489 if (resp.arg[0] != 1) {
2c74558d 1490 PrintAndLog("Failed reading block: (%02x)", i);
1491 return 1;
1492 }
1493
7444d916 1494 uint32_t startindex = resp.arg[2];
e7e95088 1495 uint32_t bufferSize = resp.arg[1];
1496 if (bufferSize > sizeof(data)) {
1497 PrintAndLog("Data exceeded Buffer size!");
1498 bufferSize = sizeof(data);
1499 }
7444d916 1500 GetFromBigBuf(data, bufferSize, startindex);
e7e95088 1501 WaitForResponse(CMD_ACK,NULL);
1502
1503 Pages = bufferSize/4;
81740aa5 1504 // Load lock bytes.
1505 int j = 0;
92690507 1506
81740aa5 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));
92690507 1512 }
1513
81740aa5 1514 // Load bottom lockbytes if available
05f7accd 1515 // TODO -- FIGURE OUT LOCK BYTES FOR TO EV1 and/or NTAG
81740aa5 1516 if ( Pages == 44 ) {
81740aa5 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
2b1f4228 1525 uint8_t get_pack[] = {0,0};
1526 iso14a_card_select_t card;
2b1f4228 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
e869d598 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));
2b1f4228 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();
e869d598 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
2b1f4228 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));
e869d598 1593 //add regular block read data to dump
2b1f4228 1594 memcpy(dump_file_data+DUMP_PREFIX_LENGTH, data, Pages*4);
1595
e869d598 1596 PrintAndLog("\n*Special* block data:");
2b1f4228 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);
9332b857 1603 PrintAndLog("Pack | %s | | %.2s", sprint_hex(dump_file_data+13, 2), dump_file_data+13);
2b1f4228 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);
95aeb706 1613 PrintAndLog("\nBlock# | Data |lck| Ascii");
46cd801c 1614 PrintAndLog("---------------------------------");
81740aa5 1615 for (i = 0; i < Pages; ++i) {
81740aa5 1616 if ( i < 3 ) {
0e32bf46 1617 PrintAndLog("%02d/0x%02X | %s| | %.4s", i+startPage, i+startPage, sprint_hex(data + i * 4, 4), data + i * 4 );
81740aa5 1618 continue;
1619 }
81740aa5 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:
06561c34 1645 case 27: tmplockbit = bit2[4]; break;
81740aa5 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 }
95aeb706 1664 PrintAndLog("%02d/0x%02X | %s| %d | %.4s", i+startPage, i+startPage, sprint_hex(data + i * 4, 4), tmplockbit, data+i*4);
06561c34 1665 }
46cd801c 1666 PrintAndLog("---------------------------------");
81740aa5 1667
2c74558d 1668 // user supplied filename?
1669 if (fileNlen < 1) {
1670 // UID = data 0-1-2 4-5-6-7 (skips a beat)
afceaf40
MHS
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]);
81740aa5 1673 } else {
2696349f 1674 sprintf(fnameptr + fileNlen,".bin");
81740aa5 1675 }
1676
81740aa5 1677 if ((fout = fopen(filename,"wb")) == NULL) {
1678 PrintAndLog("Could not create file name %s", filename);
06561c34 1679 return 1;
81740aa5 1680 }
2b1f4228 1681 fwrite( dump_file_data, 1, Pages*4 + DUMP_PREFIX_LENGTH, fout );
2dcf60f3 1682 if (fout) {
1683 fclose(fout);
1684 fout = NULL;
1685 }
9332b857 1686 PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages+(DUMP_PREFIX_LENGTH/4), Pages*4 + DUMP_PREFIX_LENGTH, filename);
afceaf40 1687 return 0;
81740aa5 1688}
1689
81740aa5 1690//-------------------------------------------------------------------------------
1691// Ultralight C Methods
1692//-------------------------------------------------------------------------------
1693
1694//
1695// Ultralight C Authentication Demo {currently uses hard-coded key}
1696//
1697int CmdHF14AMfucAuth(const char *Cmd){
afceaf40 1698
9d87eb66 1699 uint8_t keyNo = 3;
afceaf40 1700 bool errors = false;
a8be77af 1701
1702 char cmdp = param_getchar(Cmd, 0);
1703
afceaf40
MHS
1704 //Change key to user defined one
1705 if (cmdp == 'k' || cmdp == 'K'){
1706 keyNo = param_get8(Cmd, 1);
54d89314 1707 if(keyNo >= KEYS_3DES_COUNT)
a8be77af 1708 errors = true;
afceaf40
MHS
1709 }
1710
1d0ccbe0 1711 if (cmdp == 'h' || cmdp == 'H') errors = true;
a8be77af 1712
1d0ccbe0 1713 if (errors) return usage_hf_mfu_ucauth();
afceaf40 1714
a8be77af 1715 uint8_t *key = default_3des_keys[keyNo];
e7e95088 1716 if (ulc_authentication(key, true))
1c1c5f4c 1717 PrintAndLog("Authentication successful. 3des key: %s",sprint_hex(key, 16));
a8be77af 1718 else
1719 PrintAndLog("Authentication failed");
9d87eb66 1720
a8be77af 1721 return 0;
1722}
1723
afceaf40
MHS
1724/**
1725A test function to validate that the polarssl-function works the same
1726was as the openssl-implementation.
1727Commented out, since it requires openssl
1728
1729int CmdTestDES(const char * cmd)
1730{
1731 uint8_t key[16] = {0x00};
1732
1733 memcpy(key,key3_3des_data,16);
1734 DES_cblock RndA, RndB;
1735
1736 PrintAndLog("----------OpenSSL DES implementation----------");
1737 {
1738 uint8_t e_RndB[8] = {0x00};
1739 unsigned char RndARndB[16] = {0x00};
1740
1741 DES_cblock iv = { 0 };
1742 DES_key_schedule ks1,ks2;
1743 DES_cblock key1,key2;
1744
1745 memcpy(key,key3_3des_data,16);
1746 memcpy(key1,key,8);
1747 memcpy(key2,key+8,8);
1748
1749
1750 DES_set_key((DES_cblock *)key1,&ks1);
1751 DES_set_key((DES_cblock *)key2,&ks2);
1752
1753 DES_random_key(&RndA);
1754 PrintAndLog(" RndA:%s",sprint_hex(RndA, 8));
1755 PrintAndLog(" e_RndB:%s",sprint_hex(e_RndB, 8));
1756 //void DES_ede2_cbc_encrypt(const unsigned char *input,
1757 // unsigned char *output, long length, DES_key_schedule *ks1,
1758 // DES_key_schedule *ks2, DES_cblock *ivec, int enc);
1759 DES_ede2_cbc_encrypt(e_RndB,RndB,sizeof(e_RndB),&ks1,&ks2,&iv,0);
1760
1761 PrintAndLog(" RndB:%s",sprint_hex(RndB, 8));
1762 rol(RndB,8);
1763 memcpy(RndARndB,RndA,8);
1764 memcpy(RndARndB+8,RndB,8);
1765 PrintAndLog(" RA+B:%s",sprint_hex(RndARndB, 16));
1766 DES_ede2_cbc_encrypt(RndARndB,RndARndB,sizeof(RndARndB),&ks1,&ks2,&e_RndB,1);
1767 PrintAndLog("enc(RA+B):%s",sprint_hex(RndARndB, 16));
1768
1769 }
1770 PrintAndLog("----------PolarSSL implementation----------");
1771 {
1772 uint8_t random_a[8] = { 0 };
1773 uint8_t enc_random_a[8] = { 0 };
1774 uint8_t random_b[8] = { 0 };
1775 uint8_t enc_random_b[8] = { 0 };
1776 uint8_t random_a_and_b[16] = { 0 };
1777 des3_context ctx = { 0 };
1778
1779 memcpy(random_a, RndA,8);
1780
1781 uint8_t output[8] = { 0 };
1782 uint8_t iv[8] = { 0 };
1783
1784 PrintAndLog(" RndA :%s",sprint_hex(random_a, 8));
1785 PrintAndLog(" e_RndB:%s",sprint_hex(enc_random_b, 8));
1786
1787 des3_set2key_dec(&ctx, key);
1788
1789 des3_crypt_cbc(&ctx // des3_context *ctx
1790 , DES_DECRYPT // int mode
1791 , sizeof(random_b) // size_t length
1792 , iv // unsigned char iv[8]
1793 , enc_random_b // const unsigned char *input
1794 , random_b // unsigned char *output
1795 );
1796
1797 PrintAndLog(" RndB:%s",sprint_hex(random_b, 8));
1798
1799 rol(random_b,8);
1800 memcpy(random_a_and_b ,random_a,8);
1801 memcpy(random_a_and_b+8,random_b,8);
1802
1803 PrintAndLog(" RA+B:%s",sprint_hex(random_a_and_b, 16));
1804
1805 des3_set2key_enc(&ctx, key);
81740aa5 1806
afceaf40
MHS
1807 des3_crypt_cbc(&ctx // des3_context *ctx
1808 , DES_ENCRYPT // int mode
1809 , sizeof(random_a_and_b) // size_t length
1810 , enc_random_b // unsigned char iv[8]
1811 , random_a_and_b // const unsigned char *input
1812 , random_a_and_b // unsigned char *output
1813 );
1814
1815 PrintAndLog("enc(RA+B):%s",sprint_hex(random_a_and_b, 16));
1816 }
1817 return 0;
1818}
1819**/
2c74558d 1820
aa60d156 1821//
1822// Mifare Ultralight C - Set password
1823//
1824int CmdHF14AMfucSetPwd(const char *Cmd){
1825
1ec21089 1826 uint8_t pwd[16] = {0x00};
aa60d156 1827 char cmdp = param_getchar(Cmd, 0);
bcf61bd3 1828
1d0ccbe0 1829 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetpwd();
aa60d156 1830
1831 if (param_gethex(Cmd, 0, pwd, 32)) {
1832 PrintAndLog("Password must include 32 HEX symbols");
1833 return 1;
1834 }
1835
1836 UsbCommand c = {CMD_MIFAREUC_SETPWD};
1837 memcpy( c.d.asBytes, pwd, 16);
95aeb706 1838 clearCommandBuffer();
aa60d156 1839 SendCommand(&c);
1840
1841 UsbCommand resp;
aa60d156 1842 if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
9332b857 1843 if ( (resp.arg[0] & 0xff) == 1) {
aa60d156 1844 PrintAndLog("Ultralight-C new password: %s", sprint_hex(pwd,16));
9332b857 1845 } else {
aa60d156 1846 PrintAndLog("Failed writing at block %d", resp.arg[1] & 0xff);
1847 return 1;
1848 }
9332b857 1849 } else {
aa60d156 1850 PrintAndLog("command execution time out");
1c1c5f4c 1851 return 1;
1d0ccbe0 1852 }
aa60d156 1853 return 0;
1854}
1855
1856//
1ec21089 1857// Magic UL / UL-C tags - Set UID
aa60d156 1858//
1859int CmdHF14AMfucSetUid(const char *Cmd){
1860
5d554ea6 1861 UsbCommand c;
1862 UsbCommand resp;
aa60d156 1863 uint8_t uid[7] = {0x00};
1864 char cmdp = param_getchar(Cmd, 0);
e869d598 1865
1d0ccbe0 1866 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetuid();
1867
aa60d156 1868 if (param_gethex(Cmd, 0, uid, 14)) {
5d554ea6 1869 PrintAndLog("UID must include 14 HEX symbols");
aa60d156 1870 return 1;
1871 }
1872
5d554ea6 1873 // read block2.
1874 c.cmd = CMD_MIFAREU_READBL;
1875 c.arg[0] = 2;
95aeb706 1876 clearCommandBuffer();
aa60d156 1877 SendCommand(&c);
5d554ea6 1878 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1879 PrintAndLog("Command execute timeout");
1880 return 2;
aa60d156 1881 }
bcf61bd3 1882
5d554ea6 1883 // save old block2.
1884 uint8_t oldblock2[4] = {0x00};
1885 memcpy(resp.d.asBytes, oldblock2, 4);
1886
1887 // block 0.
1888 c.cmd = CMD_MIFAREU_WRITEBL;
1889 c.arg[0] = 0;
1890 c.d.asBytes[0] = uid[0];
1891 c.d.asBytes[1] = uid[1];
1892 c.d.asBytes[2] = uid[2];
1893 c.d.asBytes[3] = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
95aeb706 1894 clearCommandBuffer();
5d554ea6 1895 SendCommand(&c);
1896 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1897 PrintAndLog("Command execute timeout");
1898 return 3;
aa60d156 1899 }
bcf61bd3 1900
5d554ea6 1901 // block 1.
1902 c.arg[0] = 1;
1903 c.d.asBytes[0] = uid[3];
1904 c.d.asBytes[1] = uid[4];
1905 c.d.asBytes[2] = uid[5];
1906 c.d.asBytes[3] = uid[6];
95aeb706 1907 clearCommandBuffer();
5d554ea6 1908 SendCommand(&c);
1909 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
1910 PrintAndLog("Command execute timeout");
1911 return 4;
1912 }
1913
1914 // block 2.
1915 c.arg[0] = 2;
1916 c.d.asBytes[0] = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
1917 c.d.asBytes[1] = oldblock2[1];
1918 c.d.asBytes[2] = oldblock2[2];
1919 c.d.asBytes[3] = oldblock2[3];
95aeb706 1920 clearCommandBuffer();
5d554ea6 1921 SendCommand(&c);
1922 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
1923 PrintAndLog("Command execute timeout");
1924 return 5;
1925 }
1926
aa60d156 1927 return 0;
1928}
1929
1930int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
1d0ccbe0 1931
1932 uint8_t uid[4];
1d0ccbe0 1933 char cmdp = param_getchar(Cmd, 0);
1934 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_gendiverse();
1935
1936 if (param_gethex(Cmd, 0, uid, 8)) {
1937 PrintAndLog("UID must include 8 HEX symbols");
1938 return 1;
1939 }
aa60d156 1940
1941 uint8_t iv[8] = { 0x00 };
1d0ccbe0 1942 uint8_t block = 0x01;
aa60d156 1943
395f6a81 1944 uint8_t mifarekeyA[] = { 0xA0,0xA1,0xA2,0xA3,0xA4,0xA5 };
1945 uint8_t mifarekeyB[] = { 0xB0,0xB1,0xB2,0xB3,0xB4,0xB5 };
1946 uint8_t dkeyA[8] = { 0x00 };
1947 uint8_t dkeyB[8] = { 0x00 };
1948
aa60d156 1949 uint8_t masterkey[] = { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff };
1950
1951 uint8_t mix[8] = { 0x00 };
1952 uint8_t divkey[8] = { 0x00 };
1953
395f6a81 1954 memcpy(mix, mifarekeyA, 4);
aa60d156 1955
395f6a81 1956 mix[4] = mifarekeyA[4] ^ uid[0];
1957 mix[5] = mifarekeyA[5] ^ uid[1];
aa60d156 1958 mix[6] = block ^ uid[2];
1959 mix[7] = uid[3];
1960
1961 des3_context ctx = { 0x00 };
1962 des3_set2key_enc(&ctx, masterkey);
1963
f2019c77 1964 des3_crypt_cbc(&ctx // des3_context
1965 , DES_ENCRYPT // int mode
1966 , sizeof(mix) // length
1967 , iv // iv[8]
1968 , mix // input
1969 , divkey // output
aa60d156 1970 );
1971
1d0ccbe0 1972 PrintAndLog("-- 3DES version");
aa60d156 1973 PrintAndLog("Masterkey :\t %s", sprint_hex(masterkey,sizeof(masterkey)));
1974 PrintAndLog("UID :\t %s", sprint_hex(uid, sizeof(uid)));
1d0ccbe0 1975 PrintAndLog("block :\t %0d", block);
395f6a81 1976 PrintAndLog("Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA)));
aa60d156 1977 PrintAndLog("Message :\t %s", sprint_hex(mix, sizeof(mix)));
1978 PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6));
395f6a81 1979
1980 for (int i=0; i < sizeof(mifarekeyA); ++i){
1981 dkeyA[i] = (mifarekeyA[i] << 1) & 0xff;
1982 dkeyA[6] |= ((mifarekeyA[i] >> 7) & 1) << (i+1);
1983 }
1984
1985 for (int i=0; i < sizeof(mifarekeyB); ++i){
1986 dkeyB[1] |= ((mifarekeyB[i] >> 7) & 1) << (i+1);
1987 dkeyB[2+i] = (mifarekeyB[i] << 1) & 0xff;
1988 }
1989
1990 uint8_t zeros[8] = {0x00};
1991 uint8_t newpwd[8] = {0x00};
1992 uint8_t dmkey[24] = {0x00};
1993 memcpy(dmkey, dkeyA, 8);
1994 memcpy(dmkey+8, dkeyB, 8);
1995 memcpy(dmkey+16, dkeyA, 8);
1996 memset(iv, 0x00, 8);
1997
1998 des3_set3key_enc(&ctx, dmkey);
1999
2000 des3_crypt_cbc(&ctx // des3_context
2001 , DES_ENCRYPT // int mode
2002 , sizeof(newpwd) // length
2003 , iv // iv[8]
2004 , zeros // input
2005 , newpwd // output
2006 );
2007
1d0ccbe0 2008 PrintAndLog("\n-- DES version");
395f6a81 2009 PrintAndLog("Mifare dkeyA :\t %s", sprint_hex(dkeyA, sizeof(dkeyA)));
2010 PrintAndLog("Mifare dkeyB :\t %s", sprint_hex(dkeyB, sizeof(dkeyB)));
2011 PrintAndLog("Mifare ABA :\t %s", sprint_hex(dmkey, sizeof(dmkey)));
2012 PrintAndLog("Mifare Pwd :\t %s", sprint_hex(newpwd, sizeof(newpwd)));
2013
1d0ccbe0 2014 // next. from the diversify_key method.
aa60d156 2015 return 0;
2016}
2017
2b1f4228 2018int CmdHF14AMfUeLoad(const char *Cmd) {
24344f28 2019 char ctmp = param_getchar(Cmd, 0);
2b1f4228 2020 if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf_mfu_eload();
2021 return CmdHF14AMfELoad(Cmd);
2022}
24344f28 2023
2b1f4228 2024int CmdHF14AMfUSim(const char *Cmd) {
2025 char ctmp = param_getchar(Cmd, 0);
2026 if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf_mfu_sim();
2027 return CmdHF14ASim(Cmd);
24344f28 2028}
2029
683180cb 2030int CmdHF14AMfuPwdGen(const char *Cmd){
2031 uint8_t uid[7] = {0x00};
2032 char cmdp = param_getchar(Cmd, 0);
2033 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_pwdgen();
2034
2035 if (param_gethex(Cmd, 0, uid, 14)) return usage_hf_mfu_pwdgen();
2036
2037 PrintAndLog(" algo | pwd | pack");
2038 PrintAndLog("------+----------+-----");
2039 PrintAndLog(" EV1 | %08X | %04X", ul_ev1_pwdgenA(uid), ul_ev1_packgenA(uid));
2040 PrintAndLog(" Ami | %08X | %04X", ul_ev1_pwdgenB(uid), ul_ev1_packgenB(uid));
2041 PrintAndLog(" LD | %08X | %04X", ul_ev1_pwdgenC(uid), ul_ev1_packgenC(uid));
2042 return 0;
2043}
2b1f4228 2044//------------------------------------
2045// Menu Stuff
2046//------------------------------------
81740aa5 2047static command_t CommandTable[] =
2048{
1ec21089 2049 {"help", CmdHelp, 1, "This help"},
2050 {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
2051 {"info", CmdHF14AMfUInfo, 0, "Tag information"},
46cd801c 2052 {"dump", CmdHF14AMfUDump, 0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"},
2b1f4228 2053 {"eload", CmdHF14AMfUeLoad, 0, "load Ultralight .eml dump file into emulator memory"},
fff69a1e 2054 {"rdbl", CmdHF14AMfURdBl, 0, "Read block"},
24344f28 2055 {"wrbl", CmdHF14AMfUWrBl, 0, "Write block"},
1ec21089 2056 {"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"},
2b1f4228 2057 {"setpwd", CmdHF14AMfucSetPwd, 0, "Set 3des password - Ultralight-C"},
2058 {"setuid", CmdHF14AMfucSetUid, 0, "Set UID - MAGIC tags only"},
2059 {"sim", CmdHF14AMfUSim, 0, "Simulate Ultralight from emulator memory"},
a8be77af 2060 {"gen", CmdHF14AMfuGenDiverseKeys , 1, "Generate 3des mifare diversified keys"},
683180cb 2061 {"pwdgen", CmdHF14AMfuPwdGen, 1, "Generate pwd from known algos"},
afceaf40 2062 {NULL, NULL, 0, NULL}
81740aa5 2063};
2064
2065int CmdHFMFUltra(const char *Cmd){
28415b5d 2066 clearCommandBuffer();
2067 //WaitForResponseTimeout(CMD_ACK,NULL,100);
afceaf40
MHS
2068 CmdsParse(CommandTable, Cmd);
2069 return 0;
81740aa5 2070}
2071
2072int CmdHelp(const char *Cmd){
afceaf40
MHS
2073 CmdsHelp(CommandTable);
2074 return 0;
2b03dea7 2075}
Impressum, Datenschutz