]> git.zerfleddert.de Git - proxmark3-svn/blame - client/cmdhfmfu.c
Merge branch 'master' of https://github.com/iceman1001/proxmark3
[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
9984b173 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<--");
dd79e03a 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<--");
9984b173 135 return;
136}
833081e3 137
81740aa5 138static int CmdHelp(const char *Cmd);
139
1c6e7f03 140// get version nxp product type
8258f409 141char *getProductTypeStr( uint8_t id){
2c74558d 142
75377d29 143 static char buf[20];
2c74558d 144 char *retStr = buf;
145
146 switch(id) {
329f5cf2 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;
2c74558d 150 }
151 return buf;
152}
a8be77af 153
2c74558d 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*/
8258f409 159char *getUlev1CardSizeStr( uint8_t fsize ){
75377d29 160
345fb24a 161 static char buf[40];
2c74558d 162 char *retStr = buf;
2be768af 163 memset(buf, 0, sizeof(buf));
75377d29 164
fce738fc 165 uint16_t usize = 1 << ((fsize >>1) + 1);
166 uint16_t lsize = 1 << (fsize >>1);
167
2c74558d 168 // is LSB set?
75377d29 169 if ( fsize & 1 )
06561c34 170 sprintf(retStr, "%02X, (%u <-> %u bytes)",fsize, usize, lsize);
2c74558d 171 else
329f5cf2 172 sprintf(retStr, "%02X, (%u bytes)", fsize, lsize);
2c74558d 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}};
95aeb706 178 clearCommandBuffer();
a8be77af 179 SendCommand(&c);
2c74558d 180}
a8be77af 181
98cdd568 182void ul_switch_off_field(void) {
2c74558d 183 UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
95aeb706 184 clearCommandBuffer();
2c74558d 185 SendCommand(&c);
a8be77af 186}
187
8297860e 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);
95aeb706 191 clearCommandBuffer();
2c74558d 192 SendCommand(&c);
193 UsbCommand resp;
75377d29 194 if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
372a8257 195 if (!resp.arg[0] && responseLength) return -1;
75377d29 196
802319a3 197 uint16_t resplen = (resp.arg[0] < responseLength) ? resp.arg[0] : responseLength;
aebe7790 198 memcpy(response, resp.d.asBytes, resplen);
199 return resplen;
2c74558d 200}
1ec21089 201
2c74558d 202static int ul_select( iso14a_card_select_t *card ){
75377d29 203
2c74558d 204 ul_switch_on_field();
205
206 UsbCommand resp;
1fa96198 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 }
75377d29 214
215 memcpy(card, resp.d.asBytes, sizeof(iso14a_card_select_t));
c7442b76 216 return 1;
75377d29 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);
75377d29 224 return len;
225}
226
c585a5cf 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};
8258f409 238 ul_send_cmd_raw(cmd, 2+datalen, response, sizeof(response));
c585a5cf 239 // ACK
240 if ( response[0] == 0x0a ) return 0;
241 // NACK
242 return -1;
243}
345fb24a 244
a2e2bb8a 245static int ulc_requestAuthentication( uint8_t *nonce, uint16_t nonceLength ){
75377d29 246
a2e2bb8a 247 uint8_t cmd[] = {MIFARE_ULC_AUTH_1, 0x00};
75377d29 248 int len = ul_send_cmd_raw(cmd, sizeof(cmd), nonce, nonceLength);
75377d29 249 return len;
250}
345fb24a 251
8258f409 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);
95aeb706 256 clearCommandBuffer();
8258f409 257 SendCommand(&c);
258 UsbCommand resp;
9d87eb66 259 if ( !WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) return 0;
260 if ( resp.arg[0] == 1 ) return 1;
8258f409 261
9d87eb66 262 return 0;
8258f409 263}
264
75377d29 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);
75377d29 269 return len;
270}
271
bcf61bd3 272static int ul_auth_select( iso14a_card_select_t *card, TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authenticationkey, uint8_t *pack, uint8_t packSize){
fff69a1e 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) {
8c671cfb 283 if (ulev1_requestAuthentication(authenticationkey, pack, packSize) < 2) {
fff69a1e 284 ul_switch_off_field();
285 PrintAndLog("Error: Authentication Failed UL-EV1/NTAG");
286 return 0;
287 }
288 }
289 }
290 return 1;
291}
292
8297860e 293static int ulev1_getVersion( uint8_t *response, uint16_t responseLength ){
75377d29 294
2c74558d 295 uint8_t cmd[] = {MIFARE_ULEV1_VERSION};
8297860e 296 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
2c74558d 297 return len;
298}
299
8297860e 300static int ulev1_readCounter( uint8_t counter, uint8_t *response, uint16_t responseLength ){
2c74558d 301
302 uint8_t cmd[] = {MIFARE_ULEV1_READ_CNT, counter};
8297860e 303 int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
2c74558d 304 return len;
305}
306
98cdd568 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);
98cdd568 311 return len;
312}
313
69a29536 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);
69a29536 318 return len;
319}
320
24344f28 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//
7c8b5e68 333// make sure field is off before calling this function
22e24700 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
a903be43 352static int ul_print_default( uint8_t *data){
75377d29 353
a903be43 354 uint8_t uid[7];
a903be43 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));
46cd801c 364 PrintAndLog(" UID[0] : %02X, %s", uid[0], getTagInfo(uid[0]) );
1c6e7f03 365 if ( uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2 ) { // is infineon and 66RxxP
fce738fc 366 uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU
367 switch (chip){
1c6e7f03 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
fce738fc 371 }
372 }
a903be43 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 )
fce738fc 376 PrintAndLog(" BCC0 : %02X, Ok", data[3]);
a903be43 377 else
fce738fc 378 PrintAndLog(" BCC0 : %02X, crc should be %02X", data[3], crc0);
75377d29 379
a903be43 380 int crc1 = data[4] ^ data[5] ^ data[6] ^data[7];
381 if ( data[8] == crc1 )
fce738fc 382 PrintAndLog(" BCC1 : %02X, Ok", data[8]);
a903be43 383 else
fce738fc 384 PrintAndLog(" BCC1 : %02X, crc should be %02X", data[8], crc1 );
75377d29 385
fce738fc 386 PrintAndLog(" Internal : %02X, %sdefault", data[9], (data[9]==0x48)?"":"not " );
fce738fc 387
7a5d49b5 388 PrintAndLog(" Lock : %s - %s",
389 sprint_hex(data+10, 2),
9984b173 390 sprint_bin(data+10, 2)
7a5d49b5 391 );
392
6fdf42c6 393 PrintAndLog("OneTimePad : %s - %s\n",
394 sprint_hex(data + 12, 4),
9984b173 395 sprint_bin(data+12, 4)
6fdf42c6 396 );
29250969 397
75377d29 398 return 0;
399}
400
a383f4b7 401static int ndef_print_CC(uint8_t *data) {
1c429594 402 // no NDEF message
403 if(data[0] != 0xe1)
404 return -1;
75377d29 405
a383f4b7 406 PrintAndLog("--- NDEF Message");
75377d29 407 PrintAndLog("Capability Container: %s", sprint_hex(data,4) );
1c429594 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);
1c6e7f03 411 if ( data[2] == 0x96 )
412 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 48);
413 else if ( data[2] == 0x12 )
1c429594 414 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 144);
c585a5cf 415 else if ( data[2] == 0x3e )
1c429594 416 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 496);
c585a5cf 417 else if ( data[2] == 0x6d )
1c429594 418 PrintAndLog(" %02X : NDEF Memory Size: %d bytes", data[2], 872);
419
420 PrintAndLog(" %02X : %s / %s", data[3],
75377d29 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)");
75377d29 423 return 0;
424}
425
c7442b76 426int ul_print_type(uint32_t tagtype, uint8_t spaces){
8ceb6b03 427 char spc[11] = " ";
428 spc[10]=0x00;
429 char *spacer = spc + (10-spaces);
430
75377d29 431 if ( tagtype & UL )
1c429594 432 PrintAndLog("%sTYPE : MIFARE Ultralight (MF0ICU1) %s", spacer, (tagtype & MAGIC) ? "<magic>" : "" );
75377d29 433 else if ( tagtype & UL_C)
1c429594 434 PrintAndLog("%sTYPE : MIFARE Ultralight C (MF0ULC) %s", spacer, (tagtype & MAGIC) ? "<magic>" : "" );
75377d29 435 else if ( tagtype & UL_EV1_48)
8ceb6b03 436 PrintAndLog("%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer);
1c429594 437 else if ( tagtype & UL_EV1_128)
8ceb6b03 438 PrintAndLog("%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer);
a383f4b7 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);
c7442b76 443 else if ( tagtype & NTAG_210 )
1c429594 444 PrintAndLog("%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer);
c7442b76 445 else if ( tagtype & NTAG_212 )
a383f4b7 446 PrintAndLog("%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer);
447 else if ( tagtype & NTAG_213 )
448 PrintAndLog("%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer);
75377d29 449 else if ( tagtype & NTAG_215 )
a383f4b7 450 PrintAndLog("%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer);
75377d29 451 else if ( tagtype & NTAG_216 )
a383f4b7 452 PrintAndLog("%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer);
46fcd738 453 else if ( tagtype & NTAG_I2C_1K )
cd87ee91 454 PrintAndLog("%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer, "\xFD");
46fcd738 455 else if ( tagtype & NTAG_I2C_2K )
cd87ee91 456 PrintAndLog("%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer, "\xFD");
345fb24a 457 else if ( tagtype & MY_D )
22e24700 458 PrintAndLog("%sTYPE : INFINEON my-d\x99 (SLE 66RxxS)", spacer);
345fb24a 459 else if ( tagtype & MY_D_NFC )
22e24700 460 PrintAndLog("%sTYPE : INFINEON my-d\x99 NFC (SLE 66RxxP)", spacer);
345fb24a 461 else if ( tagtype & MY_D_MOVE )
22e24700 462 PrintAndLog("%sTYPE : INFINEON my-d\x99 move (SLE 66R01P)", spacer);
345fb24a 463 else if ( tagtype & MY_D_MOVE_NFC )
22e24700 464 PrintAndLog("%sTYPE : INFINEON my-d\x99 move NFC (SLE 66R01P)", spacer);
1c6e7f03 465 else if ( tagtype & MY_D_MOVE_LEAN )
466 PrintAndLog("%sTYPE : INFINEON my-d\x99 move lean (SLE 66R01L)", spacer);
22e24700 467 else if ( tagtype & FUDAN_UL )
468 PrintAndLog("%sTYPE : FUDAN Ultralight Compatible (or other compatible) %s", spacer, (tagtype & MAGIC) ? "<magic>" : "" );
75377d29 469 else
c7442b76 470 PrintAndLog("%sTYPE : Unknown %06x", spacer, tagtype);
75377d29 471 return 0;
472}
473
474static int ulc_print_3deskey( uint8_t *data){
1c429594 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);
2b3af97d 479 PrintAndLog("\n 3des key : %s", sprint_hex(SwapEndian64(data, 16, 8), 16));
75377d29 480 return 0;
481}
482
483static int ulc_print_configuration( uint8_t *data){
484
485 PrintAndLog("--- UL-C Configuration");
9984b173 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));
75377d29 488
489 bool validAuth = (data[8] >= 0x03 && data[8] <= 0x30);
490 if ( validAuth )
1c429594 491 PrintAndLog(" Auth0 [42/0x2A] : %s page %d/0x%02X and above need authentication", sprint_hex(data+8, 4), data[8],data[8] );
75377d29 492 else{
493 if ( data[8] == 0){
1c429594 494 PrintAndLog(" Auth0 [42/0x2A] : %s default", sprint_hex(data+8, 4) );
75377d29 495 } else {
1c429594 496 PrintAndLog(" Auth0 [42/0x2A] : %s auth byte is out-of-range", sprint_hex(data+8, 4) );
f168b263 497 }
75377d29 498 }
1c429594 499 PrintAndLog(" Auth1 [43/0x2B] : %s %s",
75377d29 500 sprint_hex(data+12, 4),
501 (data[12] & 1) ? "write access restricted": "read and write access restricted"
502 );
f168b263 503 return 0;
504}
81740aa5 505
012c0761 506static int ulev1_print_configuration( uint8_t *data, uint8_t startPage){
f168b263 507
a383f4b7 508 PrintAndLog("\n--- Tag Configuration");
75377d29 509
510 bool strg_mod_en = (data[0] & 2);
511 uint8_t authlim = (data[4] & 0x07);
5636ee8c 512 bool nfc_cnf_en = (data[4] & 0x08);
513 bool nfc_cnf_prot_pwd = (data[4] & 0x10);
75377d29 514 bool cfglck = (data[4] & 0x40);
515 bool prot = (data[4] & 0x80);
516 uint8_t vctid = data[5];
517
012c0761 518 PrintAndLog(" cfg0 [%u/0x%02X] : %s", startPage, startPage, sprint_hex(data, 4));
345fb24a 519 if ( data[3] < 0xff )
a2e2bb8a 520 PrintAndLog(" - page %d and above need authentication",data[3]);
345fb24a 521 else
522 PrintAndLog(" - pages don't need authentication");
75377d29 523 PrintAndLog(" - strong modulation mode %s", (strg_mod_en) ? "enabled":"disabled");
012c0761 524 PrintAndLog(" cfg1 [%u/0x%02X] : %s", startPage + 1, startPage + 1, sprint_hex(data+4, 4) );
75377d29 525 if ( authlim == 0)
345fb24a 526 PrintAndLog(" - Unlimited password attempts");
75377d29 527 else
528 PrintAndLog(" - Max number of password attempts is %d", authlim);
5636ee8c 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
75377d29 533 PrintAndLog(" - user configuration %s", cfglck ? "permanently locked":"writeable");
534 PrintAndLog(" - %s access is protected with password", prot ? "read and write":"write");
1c429594 535 PrintAndLog(" - %02X, Virtual Card Type Identifier is %s default", vctid, (vctid==0x05)? "":"not");
012c0761 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));
75377d29 539 return 0;
540}
541
542static int ulev1_print_counters(){
a383f4b7 543 PrintAndLog("--- Tag Counters");
a2e2bb8a 544 uint8_t tear[1] = {0};
75377d29 545 uint8_t counter[3] = {0,0,0};
c7442b76 546 uint16_t len = 0;
75377d29 547 for ( uint8_t i = 0; i<3; ++i) {
a2e2bb8a 548 ulev1_readTearing(i,tear,sizeof(tear));
c7442b76 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 }
75377d29 554 }
c7442b76 555 return len;
75377d29 556}
557
c585a5cf 558static int ulev1_print_signature( uint8_t *data, uint8_t len){
a383f4b7 559 PrintAndLog("\n--- Tag Signature");
06561c34 560 //PrintAndLog("IC signature public key name : NXP NTAG21x 2013"); // don't know if there is other NXP public keys.. :(
c585a5cf 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}
345fb24a 568
569static int ulev1_print_version(uint8_t *data){
a383f4b7 570 PrintAndLog("\n--- Tag Version");
1c429594 571 PrintAndLog(" Raw bytes : %s",sprint_hex(data, 8) );
572 PrintAndLog(" Vendor ID : %02X, %s", data[1], getTagInfo(data[1]));
345fb24a 573 PrintAndLog(" Product type : %s", getProductTypeStr(data[2]));
1c429594 574 PrintAndLog(" Product subtype : %02X, %s", data[3], (data[3]==1) ?"17 pF":"50pF");
345fb24a 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
f04ef473 582/*
c585a5cf 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);
c7442b76 595 if ( !status ){
c585a5cf 596 return UL_ERROR;
597 }
a2e2bb8a 598 status = ulc_requestAuthentication(nonce1, sizeof(nonce1));
c585a5cf 599 if ( status > 0 ) {
a2e2bb8a 600 status = ulc_requestAuthentication(nonce2, sizeof(nonce2));
c585a5cf 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}
f04ef473 608*/
c585a5cf 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;
c7442b76 615 if ( !ul_select(&card) )
c585a5cf 616 return UL_ERROR;
46fcd738 617 int status = ul_comp_write(0, NULL, 0);
c585a5cf 618 ul_switch_off_field();
a2e2bb8a 619 if ( status == 0 )
46fcd738 620 return MAGIC;
621 return 0;
c585a5cf 622}
f04ef473 623
c7442b76 624uint32_t GetHF14AMfU_Type(void){
81740aa5 625
92690507 626 TagTypeUL_t tagtype = UNKNOWN;
627 iso14a_card_select_t card;
75377d29 628 uint8_t version[10] = {0x00};
75377d29 629 int status = 0;
630 int len;
631
c7442b76 632 if (!ul_select(&card)) return UL_ERROR;
633
92690507 634 // Ultralight - ATQA / SAK
abab60ae 635 if ( card.atqa[1] != 0x00 || card.atqa[0] != 0x44 || card.sak != 0x00 ) {
4693c188 636 PrintAndLog("Tag is not Ultralight | NTAG | MY-D [ATQA: %02X %02X SAK: %02X]\n", card.atqa[1], card.atqa[0], card.sak);
75377d29 637 ul_switch_off_field();
638 return UL_ERROR;
639 }
92690507 640
345fb24a 641 if ( card.uid[0] != 0x05) {
75377d29 642
345fb24a 643 len = ulev1_getVersion(version, sizeof(version));
8258f409 644 ul_switch_off_field();
345fb24a 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;
a383f4b7 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 )
345fb24a 658 tagtype = NTAG_213;
a383f4b7 659 else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x11 )
345fb24a 660 tagtype = NTAG_215;
a383f4b7 661 else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x13 )
345fb24a 662 tagtype = NTAG_216;
c7442b76 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;
345fb24a 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;
46fcd738 674 case -1 : tagtype = (UL | UL_C | NTAG_203); break; // could be UL | UL_C magic tags
345fb24a 675 default : tagtype = UNKNOWN; break;
676 }
a383f4b7 677 // UL vs UL-C vs ntag203 test
678 if (tagtype & (UL | UL_C | NTAG_203)) {
c7442b76 679 if ( !ul_select(&card) ) return UL_ERROR;
a383f4b7 680
681 // do UL_C check first...
8258f409 682 uint8_t nonce[11] = {0x00};
683 status = ulc_requestAuthentication(nonce, sizeof(nonce));
8258f409 684 ul_switch_off_field();
a383f4b7 685 if (status > 1) {
686 tagtype = UL_C;
687 } else {
688 // need to re-select after authentication error
c7442b76 689 if ( !ul_select(&card) ) return UL_ERROR;
690
a383f4b7 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)
efd19351 698 status = ul_read(0x30, data, sizeof(data));
a383f4b7 699 if ( status <= 1 ){
700 tagtype = NTAG_203;
701 } else {
702 tagtype = UNKNOWN;
703 }
704 }
705 ul_switch_off_field();
706 }
345fb24a 707 }
22e24700 708 if (tagtype & UL) {
709 tagtype = ul_fudan_check();
710 ul_switch_off_field();
711 }
345fb24a 712 } else {
1c6e7f03 713 ul_switch_off_field();
345fb24a 714 // Infinition MY-D tests Exam high nibble
715 uint8_t nib = (card.uid[1] & 0xf0) >> 4;
716 switch ( nib ){
1c6e7f03 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
75377d29 722 }
f168b263 723 }
75377d29 724
46fcd738 725 tagtype |= ul_magic_test();
726 if (tagtype == (UNKNOWN | MAGIC)) tagtype = (UL_MAGIC);
f168b263 727 return tagtype;
728}
729
730int CmdHF14AMfUInfo(const char *Cmd){
731
c585a5cf 732 uint8_t authlim = 0xff;
f168b263 733 uint8_t data[16] = {0x00};
75377d29 734 iso14a_card_select_t card;
75377d29 735 int status;
a2e2bb8a 736 bool errors = false;
737 bool hasAuthKey = false;
a383f4b7 738 bool locked = false;
06561c34 739 bool swapEndian = false;
a2e2bb8a 740 uint8_t cmdp = 0;
06561c34 741 uint8_t dataLen = 0;
a2e2bb8a 742 uint8_t authenticationkey[16] = {0x00};
06561c34 743 uint8_t *authkeyptr = authenticationkey;
5247c0c1 744 uint8_t pwd[4] = {0,0,0,0};
745 uint8_t *key = pwd;
a2e2bb8a 746 uint8_t pack[4] = {0,0,0,0};
06561c34 747 int len = 0;
748 char tempStr[50];
f168b263 749
a2e2bb8a 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':
06561c34 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");
bcf61bd3 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)) {
fce738fc 813
bcf61bd3 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;
a903be43 824
bcf61bd3 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);
fce738fc 835
bcf61bd3 836 } else {
837 ul_switch_off_field();
838 // if we called info with key, just return
839 if ( hasAuthKey ) return 1;
1ec21089 840
bcf61bd3 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 }
98cdd568 856
bcf61bd3 857 // do counters and signature first (don't neet auth)
2c74558d 858
bcf61bd3 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 }
b9a3c864 866
0de8e387 867 // Read signature
bcf61bd3 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 }
b9a3c864 882
0de8e387 883 // Get Version
bcf61bd3 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);
b9a3c864 893 } else {
bcf61bd3 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;
5247c0c1 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;
dd79e03a 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;
5247c0c1 949
bcf61bd3 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");
b9a3c864 961 }
962 }
bcf61bd3 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;
b9a3c864 968}
969
81740aa5 970//
fff69a1e 971// Write Single Block
81740aa5 972//
973int CmdHF14AMfUWrBl(const char *Cmd){
81740aa5 974
fff69a1e 975 int blockNo = -1;
976 bool errors = false;
977 bool hasAuthKey = false;
978 bool hasPwdKey = false;
979 bool swapEndian = false;
81740aa5 980
fff69a1e 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};
46cd801c 986 uint8_t *authKeyPtr = authenticationkey;
79d7bcbb 987
fff69a1e 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);
fff69a1e 1019 if (blockNo < 0) {
1020 PrintAndLog("Wrong block number");
fff69a1e 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();
afceaf40 1046 }
fff69a1e 1047
f6059703 1048 if ( blockNo == -1 ) return usage_hf_mfu_wrbl();
24344f28 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 }
79d7bcbb 1062
fff69a1e 1063 // Swap endianness
46cd801c 1064 if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
1065 if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
fff69a1e 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));
81740aa5 1071
fff69a1e 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;
46cd801c 1078 memcpy(c.d.asBytes+4,authKeyPtr,16);
fff69a1e 1079 }
1080 else if ( hasPwdKey ) {
1081 c.arg[1] = 2;
46cd801c 1082 memcpy(c.d.asBytes+4,authKeyPtr,4);
afceaf40 1083 }
81740aa5 1084
95aeb706 1085 clearCommandBuffer();
fff69a1e 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);
81740aa5 1091 } else {
fff69a1e 1092 PrintAndLog("Command execute timeout");
afceaf40 1093 }
fff69a1e 1094
afceaf40 1095 return 0;
81740aa5 1096}
81740aa5 1097//
fff69a1e 1098// Read Single Block
81740aa5 1099//
1100int CmdHF14AMfURdBl(const char *Cmd){
81740aa5 1101
fff69a1e 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};
46cd801c 1111 uint8_t *authKeyPtr = authenticationkey;
c3c241f3 1112
fff69a1e 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);
fff69a1e 1144 if (blockNo < 0) {
1145 PrintAndLog("Wrong block number");
fff69a1e 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();
afceaf40 1162 }
95aeb706 1163
fff69a1e 1164 if ( blockNo == -1 ) return usage_hf_mfu_rdbl();
24344f28 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 }
afceaf40 1178
fff69a1e 1179 // Swap endianness
46cd801c 1180 if (swapEndian && hasAuthKey) authKeyPtr = SwapEndian64(authenticationkey, 16, 8);
1181 if (swapEndian && hasPwdKey) authKeyPtr = SwapEndian64(authenticationkey, 4, 4);
fff69a1e 1182
1183 //Read Block
afceaf40 1184 UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
fff69a1e 1185 if ( hasAuthKey ){
1186 c.arg[1] = 1;
46cd801c 1187 memcpy(c.d.asBytes,authKeyPtr,16);
fff69a1e 1188 }
1189 else if ( hasPwdKey ) {
1190 c.arg[1] = 2;
46cd801c 1191 memcpy(c.d.asBytes,authKeyPtr,4);
fff69a1e 1192 }
1193
95aeb706 1194 clearCommandBuffer();
afceaf40 1195 SendCommand(&c);
ce432659 1196 UsbCommand resp;
afceaf40 1197 if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
aa60d156 1198 uint8_t isOK = resp.arg[0] & 0xff;
1199 if (isOK) {
1200 uint8_t *data = resp.d.asBytes;
95aeb706 1201 PrintAndLog("\nBlock# | Data | Ascii");
1202 PrintAndLog("-----------------------------");
1203 PrintAndLog("%02d/0x%02X | %s| %.4s\n", blockNo, blockNo, sprint_hex(data, 4), data);
aa60d156 1204 }
1205 else {
1206 PrintAndLog("Failed reading block: (%02x)", isOK);
1207 }
81740aa5 1208 } else {
aa60d156 1209 PrintAndLog("Command execute time-out");
afceaf40
MHS
1210 }
1211 return 0;
81740aa5 1212}
1213
fff69a1e 1214int usage_hf_mfu_info(void) {
98cdd568 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");
2491a252 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");
98cdd568 1220 PrintAndLog("my-d, my-d NFC, my-d move, my-d move NFC\n");
2491a252 1221 PrintAndLog("Usage: hf mfu info k <key> l");
98cdd568 1222 PrintAndLog(" Options : ");
2491a252 1223 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1224 PrintAndLog(" l : (optional) swap entered key's endianness");
98cdd568 1225 PrintAndLog("");
1226 PrintAndLog(" sample : hf mfu info");
2491a252 1227 PrintAndLog(" : hf mfu info k 00112233445566778899AABBCCDDEEFF");
1228 PrintAndLog(" : hf mfu info k AABBCCDDD");
98cdd568 1229 return 0;
1230}
1231
fff69a1e 1232int usage_hf_mfu_dump(void) {
1ec21089 1233 PrintAndLog("Reads all pages from Ultralight, Ultralight-C, Ultralight EV1");
2491a252 1234 PrintAndLog("NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216");
1ec21089 1235 PrintAndLog("and saves binary dump into the file `filename.bin` or `cardUID.bin`");
1236 PrintAndLog("It autodetects card type.\n");
8c671cfb 1237 PrintAndLog("Usage: hf mfu dump k <key> l n <filename w/o .bin> p <page#> q <#pages>");
1238 PrintAndLog(" Options :");
2491a252 1239 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1240 PrintAndLog(" l : (optional) swap entered key's endianness");
833081e3 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");
2b03dea7 1244 PrintAndLog("");
1ec21089 1245 PrintAndLog(" sample : hf mfu dump");
2c74558d 1246 PrintAndLog(" : hf mfu dump n myfile");
98cdd568 1247 PrintAndLog(" : hf mfu dump k 00112233445566778899AABBCCDDEEFF");
2491a252 1248 PrintAndLog(" : hf mfu dump k AABBCCDDD\n");
1ec21089 1249 return 0;
1250}
98cdd568 1251
fff69a1e 1252int usage_hf_mfu_rdbl(void) {
1253 PrintAndLog("Read a block and print. It autodetects card type.\n");
2491a252 1254 PrintAndLog("Usage: hf mfu rdbl b <block number> k <key> l\n");
fff69a1e 1255 PrintAndLog(" Options:");
fff69a1e 1256 PrintAndLog(" b <no> : block to read");
2491a252 1257 PrintAndLog(" k <key> : (optional) key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
1258 PrintAndLog(" l : (optional) swap entered key's endianness");
fff69a1e 1259 PrintAndLog("");
2491a252 1260 PrintAndLog(" sample : hf mfu rdbl b 0");
fff69a1e 1261 PrintAndLog(" : hf mfu rdbl b 0 k 00112233445566778899AABBCCDDEEFF");
2491a252 1262 PrintAndLog(" : hf mfu rdbl b 0 k AABBCCDDD\n");
fff69a1e 1263 return 0;
1264}
1265
1266int usage_hf_mfu_wrbl(void) {
f6059703 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");
2491a252 1269 PrintAndLog(" Options:");
fff69a1e 1270 PrintAndLog(" b <no> : block to write");
2491a252 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");
fff69a1e 1274 PrintAndLog("");
2491a252 1275 PrintAndLog(" sample : hf mfu wrbl b 0 d 01234567");
1276 PrintAndLog(" : hf mfu wrbl b 0 d 01234567 k AABBCCDDD\n");
fff69a1e 1277 return 0;
1278}
1279
24344f28 1280int usage_hf_mfu_eload(void) {
2b1f4228 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");
9332b857 1286 PrintAndLog(" u : UL (required)");
1287 PrintAndLog(" [filename] : without `.eml` (required)");
1288 PrintAndLog(" numblocks : number of blocks to load from eml file (optional)");
24344f28 1289 PrintAndLog("");
2b1f4228 1290 PrintAndLog(" sample: hf mfu eload u filename");
1291 PrintAndLog(" hf mfu eload u filename 57");
9332b857 1292 return 0;
2b1f4228 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>");
9332b857 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)");
2b1f4228 1303 PrintAndLog("\n sample : hf mfu sim t 7");
1304 PrintAndLog(" : hf mfu sim t 7 u 1122344556677\n");
9332b857 1305
24344f28 1306 return 0;
1307}
1308
1d0ccbe0 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
2b1f4228 1350#define DUMP_PREFIX_LENGTH 48
81740aa5 1351//
1ec21089 1352// Mifare Ultralight / Ultralight-C / Ultralight-EV1
1353// Read and Dump Card Contents, using auto detection of tag size.
81740aa5 1354int CmdHF14AMfUDump(const char *Cmd){
1355
afceaf40 1356 FILE *fout;
81740aa5 1357 char filename[FILE_PATH_SIZE] = {0x00};
92690507 1358 char *fnameptr = filename;
afceaf40
MHS
1359 uint8_t *lockbytes_t = NULL;
1360 uint8_t lockbytes[2] = {0x00};
afceaf40
MHS
1361 uint8_t *lockbytes_t2 = NULL;
1362 uint8_t lockbytes2[2] = {0x00};
afceaf40 1363 bool bit[16] = {0x00};
81740aa5 1364 bool bit2[16] = {0x00};
2c74558d 1365 uint8_t data[1024] = {0x00};
2491a252 1366 bool hasAuthKey = false;
1ec21089 1367 int i = 0;
1368 int Pages = 16;
1369 bool tmplockbit = false;
06561c34 1370 uint8_t dataLen = 0;
1371 uint8_t cmdp = 0;
2491a252 1372 uint8_t authenticationkey[16] = {0x00};
8c671cfb 1373 memset(authenticationkey, 0x00, sizeof(authenticationkey));
06561c34 1374 uint8_t *authKeyPtr = authenticationkey;
2c74558d 1375 size_t fileNlen = 0;
2b03dea7 1376 bool errors = false;
1377 bool swapEndian = false;
833081e3 1378 bool manualPages = false;
1379 uint8_t startPage = 0;
1380 char tempStr[50];
2c74558d 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':
833081e3 1391 dataLen = param_getstr(Cmd, cmdp+1, tempStr);
a7e7cd41 1392 if (dataLen == 32 || dataLen == 8) { //ul-c or ev1/ntag key length
2491a252 1393 errors = param_gethex(tempStr, 0, authenticationkey, dataLen);
a7e7cd41 1394 dataLen /= 2;
1395 } else {
e7e95088 1396 PrintAndLog("\nERROR: Key is incorrect length\n");
1397 errors = true;
833081e3 1398 }
2c74558d 1399 cmdp += 2;
2491a252 1400 hasAuthKey = true;
833081e3 1401 break;
1402 case 'l':
1403 case 'L':
1404 swapEndian = true;
1405 cmdp++;
2c74558d 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;
833081e3 1414 case 'p':
2b1f4228 1415 case 'P': //set start page
833081e3 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;
ebd7412d 1425 break;
2c74558d 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();
75377d29 1436
e869d598 1437 //if we entered a key in little endian and set the swapEndian switch - switch it...
a7e7cd41 1438 if (swapEndian && hasAuthKey)
1439 authKeyPtr = SwapEndian64(authenticationkey, dataLen, (dataLen == 16) ? 8 : 4);
2b03dea7 1440
1ec21089 1441 TagTypeUL_t tagtype = GetHF14AMfU_Type();
1442 if (tagtype == UL_ERROR) return -1;
81740aa5 1443
46cd801c 1444 if (!manualPages) //get number of pages to read
833081e3 1445 for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++)
1446 if (tagtype & UL_TYPES_ARRAY[idx])
46cd801c 1447 Pages = UL_MEMORY_ARRAY[idx]+1; //add one as maxblks starts at 0
833081e3 1448
1449 ul_print_type(tagtype, 0);
1450 PrintAndLog("Reading tag memory...");
e7e95088 1451 UsbCommand c = {CMD_MIFAREU_READCARD, {startPage,Pages}};
06561c34 1452 if ( hasAuthKey ) {
e7e95088 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
a7e7cd41 1458 memcpy(c.d.asBytes, authKeyPtr, dataLen);
833081e3 1459 }
95aeb706 1460
1461 clearCommandBuffer();
afceaf40
MHS
1462 SendCommand(&c);
1463 UsbCommand resp;
cceabb79 1464 if (!WaitForResponseTimeout(CMD_ACK, &resp,1500)) {
aa60d156 1465 PrintAndLog("Command execute time-out");
2c74558d 1466 return 1;
81740aa5 1467 }
e7e95088 1468 if (resp.arg[0] != 1) {
2c74558d 1469 PrintAndLog("Failed reading block: (%02x)", i);
1470 return 1;
1471 }
1472
7444d916 1473 uint32_t startindex = resp.arg[2];
e7e95088 1474 uint32_t bufferSize = resp.arg[1];
1475 if (bufferSize > sizeof(data)) {
1476 PrintAndLog("Data exceeded Buffer size!");
1477 bufferSize = sizeof(data);
1478 }
7444d916 1479 GetFromBigBuf(data, bufferSize, startindex);
e7e95088 1480 WaitForResponse(CMD_ACK,NULL);
1481
1482 Pages = bufferSize/4;
81740aa5 1483 // Load lock bytes.
1484 int j = 0;
92690507 1485
81740aa5 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));
92690507 1491 }
1492
81740aa5 1493 // Load bottom lockbytes if available
05f7accd 1494 // TODO -- FIGURE OUT LOCK BYTES FOR TO EV1 and/or NTAG
81740aa5 1495 if ( Pages == 44 ) {
81740aa5 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
2b1f4228 1504 uint8_t get_pack[] = {0,0};
1505 iso14a_card_select_t card;
2b1f4228 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
e869d598 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));
2b1f4228 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();
e869d598 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
2b1f4228 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));
e869d598 1572 //add regular block read data to dump
2b1f4228 1573 memcpy(dump_file_data+DUMP_PREFIX_LENGTH, data, Pages*4);
1574
e869d598 1575 PrintAndLog("\n*Special* block data:");
2b1f4228 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);
9332b857 1582 PrintAndLog("Pack | %s | | %.2s", sprint_hex(dump_file_data+13, 2), dump_file_data+13);
2b1f4228 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);
95aeb706 1592 PrintAndLog("\nBlock# | Data |lck| Ascii");
46cd801c 1593 PrintAndLog("---------------------------------");
81740aa5 1594 for (i = 0; i < Pages; ++i) {
81740aa5 1595 if ( i < 3 ) {
95aeb706 1596 PrintAndLog("%02d/0x%02X | %s| | ", i+startPage, i+startPage, sprint_hex(data + i * 4, 4));
81740aa5 1597 continue;
1598 }
81740aa5 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:
06561c34 1624 case 27: tmplockbit = bit2[4]; break;
81740aa5 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 }
95aeb706 1643 PrintAndLog("%02d/0x%02X | %s| %d | %.4s", i+startPage, i+startPage, sprint_hex(data + i * 4, 4), tmplockbit, data+i*4);
06561c34 1644 }
46cd801c 1645 PrintAndLog("---------------------------------");
81740aa5 1646
2c74558d 1647 // user supplied filename?
1648 if (fileNlen < 1) {
1649 // UID = data 0-1-2 4-5-6-7 (skips a beat)
afceaf40
MHS
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]);
81740aa5 1652 } else {
2696349f 1653 sprintf(fnameptr + fileNlen,".bin");
81740aa5 1654 }
1655
81740aa5 1656 if ((fout = fopen(filename,"wb")) == NULL) {
1657 PrintAndLog("Could not create file name %s", filename);
06561c34 1658 return 1;
81740aa5 1659 }
2b1f4228 1660 fwrite( dump_file_data, 1, Pages*4 + DUMP_PREFIX_LENGTH, fout );
81740aa5 1661 fclose(fout);
1662
9332b857 1663 PrintAndLog("Dumped %d pages, wrote %d bytes to %s", Pages+(DUMP_PREFIX_LENGTH/4), Pages*4 + DUMP_PREFIX_LENGTH, filename);
afceaf40 1664 return 0;
81740aa5 1665}
1666
81740aa5 1667//-------------------------------------------------------------------------------
1668// Ultralight C Methods
1669//-------------------------------------------------------------------------------
1670
1671//
1672// Ultralight C Authentication Demo {currently uses hard-coded key}
1673//
1674int CmdHF14AMfucAuth(const char *Cmd){
afceaf40 1675
9d87eb66 1676 uint8_t keyNo = 3;
afceaf40 1677 bool errors = false;
a8be77af 1678
1679 char cmdp = param_getchar(Cmd, 0);
1680
afceaf40
MHS
1681 //Change key to user defined one
1682 if (cmdp == 'k' || cmdp == 'K'){
1683 keyNo = param_get8(Cmd, 1);
ebd7412d 1684 if(keyNo > KEYS_3DES_COUNT)
a8be77af 1685 errors = true;
afceaf40
MHS
1686 }
1687
1d0ccbe0 1688 if (cmdp == 'h' || cmdp == 'H') errors = true;
a8be77af 1689
1d0ccbe0 1690 if (errors) return usage_hf_mfu_ucauth();
afceaf40 1691
a8be77af 1692 uint8_t *key = default_3des_keys[keyNo];
e7e95088 1693 if (ulc_authentication(key, true))
1c1c5f4c 1694 PrintAndLog("Authentication successful. 3des key: %s",sprint_hex(key, 16));
a8be77af 1695 else
1696 PrintAndLog("Authentication failed");
9d87eb66 1697
a8be77af 1698 return 0;
1699}
1700
afceaf40
MHS
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);
81740aa5 1783
afceaf40
MHS
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**/
2c74558d 1797
aa60d156 1798//
1799// Mifare Ultralight C - Set password
1800//
1801int CmdHF14AMfucSetPwd(const char *Cmd){
1802
1ec21089 1803 uint8_t pwd[16] = {0x00};
aa60d156 1804 char cmdp = param_getchar(Cmd, 0);
bcf61bd3 1805
1d0ccbe0 1806 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetpwd();
aa60d156 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);
95aeb706 1815 clearCommandBuffer();
aa60d156 1816 SendCommand(&c);
1817
1818 UsbCommand resp;
aa60d156 1819 if (WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
9332b857 1820 if ( (resp.arg[0] & 0xff) == 1) {
aa60d156 1821 PrintAndLog("Ultralight-C new password: %s", sprint_hex(pwd,16));
9332b857 1822 } else {
aa60d156 1823 PrintAndLog("Failed writing at block %d", resp.arg[1] & 0xff);
1824 return 1;
1825 }
9332b857 1826 } else {
aa60d156 1827 PrintAndLog("command execution time out");
1c1c5f4c 1828 return 1;
1d0ccbe0 1829 }
aa60d156 1830 return 0;
1831}
1832
1833//
1ec21089 1834// Magic UL / UL-C tags - Set UID
aa60d156 1835//
1836int CmdHF14AMfucSetUid(const char *Cmd){
1837
5d554ea6 1838 UsbCommand c;
1839 UsbCommand resp;
aa60d156 1840 uint8_t uid[7] = {0x00};
1841 char cmdp = param_getchar(Cmd, 0);
e869d598 1842
1d0ccbe0 1843 if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_hf_mfu_ucsetuid();
1844
aa60d156 1845 if (param_gethex(Cmd, 0, uid, 14)) {
5d554ea6 1846 PrintAndLog("UID must include 14 HEX symbols");
aa60d156 1847 return 1;
1848 }
1849
5d554ea6 1850 // read block2.
1851 c.cmd = CMD_MIFAREU_READBL;
1852 c.arg[0] = 2;
95aeb706 1853 clearCommandBuffer();
aa60d156 1854 SendCommand(&c);
5d554ea6 1855 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1856 PrintAndLog("Command execute timeout");
1857 return 2;
aa60d156 1858 }
bcf61bd3 1859
5d554ea6 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];
95aeb706 1871 clearCommandBuffer();
5d554ea6 1872 SendCommand(&c);
1873 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
1874 PrintAndLog("Command execute timeout");
1875 return 3;
aa60d156 1876 }
bcf61bd3 1877
5d554ea6 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];
95aeb706 1884 clearCommandBuffer();
5d554ea6 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];
95aeb706 1897 clearCommandBuffer();
5d554ea6 1898 SendCommand(&c);
1899 if (!WaitForResponseTimeout(CMD_ACK,&resp,1500) ) {
1900 PrintAndLog("Command execute timeout");
1901 return 5;
1902 }
1903
aa60d156 1904 return 0;
1905}
1906
1907int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
1d0ccbe0 1908
1909 uint8_t uid[4];
1d0ccbe0 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 }
aa60d156 1917
1918 uint8_t iv[8] = { 0x00 };
1d0ccbe0 1919 uint8_t block = 0x01;
aa60d156 1920
395f6a81 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
aa60d156 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
395f6a81 1931 memcpy(mix, mifarekeyA, 4);
aa60d156 1932
395f6a81 1933 mix[4] = mifarekeyA[4] ^ uid[0];
1934 mix[5] = mifarekeyA[5] ^ uid[1];
aa60d156 1935 mix[6] = block ^ uid[2];
1936 mix[7] = uid[3];
1937
1938 des3_context ctx = { 0x00 };
1939 des3_set2key_enc(&ctx, masterkey);
1940
f2019c77 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
aa60d156 1947 );
1948
1d0ccbe0 1949 PrintAndLog("-- 3DES version");
aa60d156 1950 PrintAndLog("Masterkey :\t %s", sprint_hex(masterkey,sizeof(masterkey)));
1951 PrintAndLog("UID :\t %s", sprint_hex(uid, sizeof(uid)));
1d0ccbe0 1952 PrintAndLog("block :\t %0d", block);
395f6a81 1953 PrintAndLog("Mifare key :\t %s", sprint_hex(mifarekeyA, sizeof(mifarekeyA)));
aa60d156 1954 PrintAndLog("Message :\t %s", sprint_hex(mix, sizeof(mix)));
1955 PrintAndLog("Diversified key: %s", sprint_hex(divkey+1, 6));
395f6a81 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
1d0ccbe0 1985 PrintAndLog("\n-- DES version");
395f6a81 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
1d0ccbe0 1991 // next. from the diversify_key method.
aa60d156 1992 return 0;
1993}
1994
2b1f4228 1995int CmdHF14AMfUeLoad(const char *Cmd) {
24344f28 1996 char ctmp = param_getchar(Cmd, 0);
2b1f4228 1997 if ( ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) return usage_hf_mfu_eload();
1998 return CmdHF14AMfELoad(Cmd);
1999}
24344f28 2000
2b1f4228 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);
24344f28 2005}
2006
2b1f4228 2007//------------------------------------
2008// Menu Stuff
2009//------------------------------------
81740aa5 2010static command_t CommandTable[] =
2011{
1ec21089 2012 {"help", CmdHelp, 1, "This help"},
2013 {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
2014 {"info", CmdHF14AMfUInfo, 0, "Tag information"},
46cd801c 2015 {"dump", CmdHF14AMfUDump, 0, "Dump Ultralight / Ultralight-C / NTAG tag to binary file"},
2b1f4228 2016 {"eload", CmdHF14AMfUeLoad, 0, "load Ultralight .eml dump file into emulator memory"},
fff69a1e 2017 {"rdbl", CmdHF14AMfURdBl, 0, "Read block"},
24344f28 2018 {"wrbl", CmdHF14AMfUWrBl, 0, "Write block"},
1ec21089 2019 {"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"},
2b1f4228 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"},
a8be77af 2023 {"gen", CmdHF14AMfuGenDiverseKeys , 1, "Generate 3des mifare diversified keys"},
afceaf40 2024 {NULL, NULL, 0, NULL}
81740aa5 2025};
2026
2027int CmdHFMFUltra(const char *Cmd){
afceaf40
MHS
2028 WaitForResponseTimeout(CMD_ACK,NULL,100);
2029 CmdsParse(CommandTable, Cmd);
2030 return 0;
81740aa5 2031}
2032
2033int CmdHelp(const char *Cmd){
afceaf40
MHS
2034 CmdsHelp(CommandTable);
2035 return 0;
2b03dea7 2036}
Impressum, Datenschutz