From 05f7accdbb10255d4c6a0ced07d4e56421410e5f Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Wed, 20 May 2015 19:20:26 +0200 Subject: [PATCH] CHG: @marshmellows changes. ADD: NTAG i2c 1K / NTAG i2c 2K identification. --- client/cmdhfmfu.c | 225 ++++++++++++++++++++++++++-------------------- client/cmdhfmfu.h | 37 ++++---- 2 files changed, 149 insertions(+), 113 deletions(-) diff --git a/client/cmdhfmfu.c b/client/cmdhfmfu.c index dc246de5..9d35db71 100644 --- a/client/cmdhfmfu.c +++ b/client/cmdhfmfu.c @@ -19,8 +19,8 @@ #define MAX_UL_BLOCKS 0x0f #define MAX_ULC_BLOCKS 0x2b #define MAX_ULEV1a_BLOCKS 0x12 -#define MAX_ULEV1b_BLOCKS 0x20 -#define MAX_NTAG_203 0x2c +#define MAX_ULEV1b_BLOCKS 0x28 +#define MAX_NTAG_203 0x29 #define MAX_NTAG_210 0x13 #define MAX_NTAG_212 0x28 #define MAX_NTAG_213 0x2c @@ -35,7 +35,7 @@ uint8_t default_3des_keys[KEYS_3DES_COUNT][16] = { { 0x49,0x45,0x4D,0x4B,0x41,0x45,0x52,0x42,0x21,0x4E,0x41,0x43,0x55,0x4F,0x59,0x46 },// NFC-key { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },// all ones { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF },// all FF - { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF }, // 11 22 33 + { 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF },// 11 22 33 }; #define KEYS_PWD_COUNT 10 @@ -55,14 +55,12 @@ uint8_t default_pwd_pack[KEYS_PWD_COUNT][4] = { }; #define MAX_UL_TYPES 16 -uint16_t UL_TYPES_ARRAY[MAX_UL_TYPES] = {UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128, - NTAG, NTAG_203, NTAG_210, NTAG_212, NTAG_213, NTAG_215, NTAG_216, - MY_D, MY_D_NFC, MY_D_MOVE, MY_D_MOVE_NFC}; -uint8_t UL_MEMORY_ARRAY[MAX_UL_TYPES] = { - MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_ULC_BLOCKS, - MAX_ULEV1a_BLOCKS, MAX_ULEV1b_BLOCKS, - MAX_NTAG_213, MAX_NTAG_203, MAX_NTAG_210, MAX_NTAG_212, MAX_NTAG_213, MAX_NTAG_215, MAX_NTAG_216, - MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_UL_BLOCKS}; +uint16_t UL_TYPES_ARRAY[MAX_UL_TYPES] = {UNKNOWN, UL, UL_C, UL_EV1_48, UL_EV1_128, NTAG, NTAG_203, + NTAG_210, NTAG_212, NTAG_213, NTAG_215, NTAG_216, MY_D, MY_D_NFC, MY_D_MOVE, MY_D_MOVE_NFC}; + +uint8_t UL_MEMORY_ARRAY[MAX_UL_TYPES] = {MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_ULC_BLOCKS, MAX_ULEV1a_BLOCKS, + MAX_ULEV1b_BLOCKS, MAX_NTAG_203, MAX_NTAG_203, MAX_NTAG_210, MAX_NTAG_212, MAX_NTAG_213, + MAX_NTAG_215, MAX_NTAG_216, MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_UL_BLOCKS, MAX_UL_BLOCKS}; static int CmdHelp(const char *Cmd); @@ -299,14 +297,11 @@ static int ul_print_default( uint8_t *data){ } static int ndef_print_CC(uint8_t *data) { + // no NDEF message + if(data[0] != 0xe1) + return -1; - PrintAndLog("\n--- NDEF Message"); - - if(data[0] != 0xe1) { - PrintAndLog("no NDEF message"); - return -1; // no NDEF message - } - + PrintAndLog("--- NDEF Message"); PrintAndLog("Capability Container: %s", sprint_hex(data,4) ); PrintAndLog(" %02X: NDEF Magic Number", data[0]); PrintAndLog(" %02X: version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f); @@ -337,18 +332,24 @@ int ul_print_type(uint16_t tagtype, uint8_t spaces){ PrintAndLog("%sTYPE : MIFARE Ultralight EV1 48bytes (MF0UL1101)", spacer); else if ( tagtype & UL_EV1_128) PrintAndLog("%sTYPE : MIFARE Ultralight EV1 128bytes (MF0UL2101)", spacer); + else if ( tagtype & NTAG ) + PrintAndLog("%sTYPE : NTAG UNKNOWN", spacer); else if ( tagtype & NTAG_203 ) - PrintAndLog("%sTYPE : NTAG 203 144bytes (NT2H0301G0DU)", spacer); + PrintAndLog("%sTYPE : NTAG 203 144bytes (NT2H0301F0DT)", spacer); else if ( tagtype & NTAG_210 ) PrintAndLog("%sTYPE : NTAG 210 48bytes (NT2L1011G0DU)", spacer); - else if ( tagtype & NTAG_212 ) - PrintAndLog("%sTYPE : NTAG 212 1284bytes (NT2L1011G0DU)", spacer); + else if ( tagtype & NTAG_212 ) + PrintAndLog("%sTYPE : NTAG 212 128bytes (NT2L1211G0DU)", spacer); else if ( tagtype & NTAG_213 ) PrintAndLog("%sTYPE : NTAG 213 144bytes (NT2H1311G0DU)", spacer); else if ( tagtype & NTAG_215 ) PrintAndLog("%sTYPE : NTAG 215 504bytes (NT2H1511G0DU)", spacer); else if ( tagtype & NTAG_216 ) PrintAndLog("%sTYPE : NTAG 216 888bytes (NT2H1611G0DU)", spacer); + else if ( tagtype & NTAG_I2C_1K ) + PrintAndLog("%sTYPE : NTAG i2c 888bytes (NT3H1101FHK )", spacer); + else if ( tagtype & NTAG_I2C_2K ) + PrintAndLog("%sTYPE : NTAG i2c 1904bytes (NT3H1201FHK )", spacer); else if ( tagtype & MY_D ) PrintAndLog("%sTYPE : INFINEON my-d\x99", spacer); else if ( tagtype & MY_D_NFC ) @@ -396,7 +397,7 @@ static int ulc_print_configuration( uint8_t *data){ static int ulev1_print_configuration( uint8_t *data){ - PrintAndLog("\n--- UL-EV1 Configuration"); + PrintAndLog("\n--- Tag Configuration"); bool strg_mod_en = (data[0] & 2); uint8_t authlim = (data[4] & 0x07); @@ -424,7 +425,7 @@ static int ulev1_print_configuration( uint8_t *data){ } static int ulev1_print_counters(){ - PrintAndLog("--- UL-EV1 Counters"); + PrintAndLog("--- Tag Counters"); uint8_t tear[1] = {0}; uint8_t counter[3] = {0,0,0}; for ( uint8_t i = 0; i<3; ++i) { @@ -437,8 +438,8 @@ static int ulev1_print_counters(){ } static int ulev1_print_signature( uint8_t *data, uint8_t len){ - PrintAndLog("\n--- UL-EV1 Signature"); - PrintAndLog("IC signature public key name : NXP NTAG21x 2013"); + PrintAndLog("\n--- Tag Signature"); + //PrintAndLog("IC signature public key name : NXP NTAG21x 2013"); // don't know if there is other NXP public keys.. :( PrintAndLog("IC signature public key value : 04494e1a386d3d3cfe3dc10e5de68a499b1c202db5b132393e89ed19fe5be8bc61"); PrintAndLog(" Elliptic curve parameters : secp128r1"); PrintAndLog(" Tag ECC Signature : %s", sprint_hex(data, len)); @@ -448,7 +449,7 @@ static int ulev1_print_signature( uint8_t *data, uint8_t len){ } static int ulev1_print_version(uint8_t *data){ - PrintAndLog("\n--- UL-EV1 / NTAG Version"); + PrintAndLog("\n--- Tag Version"); PrintAndLog(" Raw bytes : %s", sprint_hex(data, 8) ); PrintAndLog(" Vendor ID : %02X, Manufacturer: %s", data[1], getTagInfo(data[1])); PrintAndLog(" Product type : %s" , getProductTypeStr(data[2])); @@ -504,8 +505,8 @@ static int ul_magic_test(){ status = ul_comp_write(0, NULL, 0); ul_switch_off_field(); if ( status == 0 ) - return UL_MAGIC; - return UL; + return MAGIC; + return UNKNOWN; } uint16_t GetHF14AMfU_Type(void){ @@ -541,16 +542,20 @@ uint16_t GetHF14AMfU_Type(void){ tagtype = UL_EV1_48; else if ( version[2] == 0x03 && version[6] != 0x0B ) tagtype = UL_EV1_128; - else if ( version[2] == 0x04 && version[6] == 0x0B ) + else if ( version[2] == 0x04 && version[3] == 0x01 && version[6] == 0x0B ) tagtype = NTAG_210; - else if ( version[2] == 0x04 && version[6] == 0x0E ) + else if ( version[2] == 0x04 && version[3] == 0x01 && version[6] == 0x0E ) tagtype = NTAG_212; - else if ( version[2] == 0x04 && version[6] == 0x0F ) + else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x0F ) tagtype = NTAG_213; - else if ( version[2] == 0x04 && version[6] == 0x11 ) + else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x11 ) tagtype = NTAG_215; - else if ( version[2] == 0x04 && version[6] == 0x13 ) - tagtype = NTAG_216; + else if ( version[2] == 0x04 && version[3] == 0x02 && version[6] == 0x13 ) + tagtype = NTAG_216; + else if ( version[2] == 0x04 && version[3] == 0x05 && version[6] == 0x13 ) + tagtype = NTAG_I2C_1K; + else if ( version[2] == 0x04 && version[3] == 0x05 && version[6] == 0x15 ) + tagtype = NTAG_I2C_2K; else if ( version[2] == 0x04 ) tagtype = NTAG; @@ -558,38 +563,60 @@ uint16_t GetHF14AMfU_Type(void){ } case 0x01: tagtype = UL_C; break; case 0x00: tagtype = UL; break; - case -1 : tagtype = (UL | UL_C); break; //when does this happen? + case -1 : tagtype = (UL | UL_C | NTAG_203); break; //when does this happen? -- if getversion fails, it assumes it is either UL/ULC -- but why? magic tags? default : tagtype = UNKNOWN; break; } - // UL-C test - if (tagtype == (UL | UL_C)) { + // UL vs UL-C vs ntag203 test + if (tagtype & (UL | UL_C | NTAG_203)) { status = ul_select(&card); if ( status < 1 ){ PrintAndLog("iso14443a card select failed (UL-C)"); ul_switch_off_field(); return UL_ERROR; } + + // do UL_C check first... uint8_t nonce[11] = {0x00}; status = ulc_requestAuthentication(nonce, sizeof(nonce)); - tagtype = ( status > 0 ) ? UL_C : UL; - ul_switch_off_field(); + if (status > 1) { + tagtype = UL_C; + } else { + // need to re-select after authentication error + status = ul_select(&card); + if ( status < 1 ){ + PrintAndLog("iso14443a card select failed (UL-C)"); + ul_switch_off_field(); + return UL_ERROR; + } + uint8_t data[16] = {0x00}; + // read page 0x26-0x29 (last valid ntag203 page) + status = ul_read(0x26, data, sizeof(data)); + if ( status <= 1 ) { + tagtype = UL; + } else { + // read page 0x30 (should error if it is a ntag203) + status = ul_read(30, data, sizeof(data)); + if ( status <= 1 ){ + tagtype = NTAG_203; + } else { + tagtype = UNKNOWN; + } + } + ul_switch_off_field(); + } } - - //NTAG203 detection here. - } else { // Infinition MY-D tests Exam high nibble uint8_t nib = (card.uid[1] & 0xf0) >> 4; switch ( nib ){ case 1: tagtype = MY_D; break; - case 2: tagtype = (MY_D | MY_D_NFC); break; - case 3: tagtype = (MY_D_MOVE | MY_D_MOVE_NFC); break; + case 2: tagtype = (MY_D | MY_D_NFC); break; //notice: we can not currently distinguish between these two + case 3: tagtype = (MY_D_MOVE | MY_D_MOVE_NFC); break; //notice: we can not currently distinguish between these two } } - tagtype = (ul_magic_test() == UL_MAGIC) ? (tagtype | MAGIC) : tagtype; - //if ((tagtype & UL)) tagtype = ul_magic_test(); + tagtype = (ul_magic_test() == MAGIC) ? (tagtype | MAGIC) : tagtype; return tagtype; } @@ -603,6 +630,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ int status; bool errors = false; bool hasAuthKey = false; + bool locked = false; uint8_t cmdp = 0; uint8_t datalen = 0; uint8_t authenticationkey[16] = {0x00}; @@ -677,17 +705,22 @@ int CmdHF14AMfUInfo(const char *Cmd){ } } - - // read pages 0,1,2,4 (should read 4pages) + // read pages 0,1,2,3 (should read 4pages) status = ul_read(0, data, sizeof(data)); if ( status == -1 ){ ul_switch_off_field(); PrintAndLog("Error: tag didn't answer to READ"); return status; } + if (status == 16) { + ul_print_default(data); + ndef_print_CC(data+12); + } + else { + locked = true; + } - ul_print_default(data); - + // UL_C Specific if ((tagtype & UL_C)){ // read pages 0x28, 0x29, 0x2A, 0x2B @@ -698,10 +731,11 @@ int CmdHF14AMfUInfo(const char *Cmd){ ul_switch_off_field(); return status; } - ulc_print_configuration(ulc_conf); + if (status == 16) ulc_print_configuration(ulc_conf); + else locked = true; if ((tagtype & MAGIC)){ - + //just read key uint8_t ulc_deskey[16] = {0x00}; status = ul_read(0x2C, ulc_deskey, sizeof(ulc_deskey)); if ( status == -1 ){ @@ -709,7 +743,7 @@ int CmdHF14AMfUInfo(const char *Cmd){ PrintAndLog("Error: tag didn't answer to READ magic"); return status; } - ulc_print_3deskey(ulc_deskey); + if (status == 16) ulc_print_3deskey(ulc_deskey); } else { ul_switch_off_field(); @@ -721,21 +755,29 @@ int CmdHF14AMfUInfo(const char *Cmd){ for (uint8_t i = 0; i < KEYS_3DES_COUNT; ++i ){ key = default_3des_keys[i]; if (ulc_authentication(key, true)){ - PrintAndLog("Found default 3des key: "); //%s", sprint_hex(key,16)); + PrintAndLog("Found default 3des key: "); uint8_t keySwap[16]; memcpy(keySwap, SwapEndian64(key,16,8), 16); ulc_print_3deskey(keySwap); - return 1; - } + break; + } + } + // reselect for future tests (ntag test) + status = ul_select(&card); + if ( status < 1 ){ + PrintAndLog("iso14443a card select failed"); + ul_switch_off_field(); + return status; } - return 1; //return even if key not found (UL_C is done) } } - - if ((tagtype & (UL_EV1_48 | UL_EV1_128))) { - ulev1_print_counters(); - + // do counters and signature first (don't neet auth) + + // ul counters are different than ntag counters + if ((tagtype & (UL_EV1_48 | UL_EV1_128))) ulev1_print_counters(); + + if ((tagtype & (UL_EV1_48 | UL_EV1_128 | NTAG_213 | NTAG_215 | NTAG_216 | NTAG_I2C_1K | NTAG_I2C_2K ))) { uint8_t ulev1_signature[32] = {0x00}; status = ulev1_readSignature( ulev1_signature, sizeof(ulev1_signature)); if ( status == -1 ){ @@ -743,28 +785,10 @@ int CmdHF14AMfUInfo(const char *Cmd){ ul_switch_off_field(); return status; } - ulev1_print_signature( ulev1_signature, sizeof(ulev1_signature)); - - uint8_t startconfigblock = (tagtype & UL_EV1_48) ? 0x10 : 0x25; - uint8_t ulev1_conf[16] = {0x00}; - status = ul_read(startconfigblock, ulev1_conf, sizeof(ulev1_conf)); - if ( status == -1 ){ - PrintAndLog("Error: tag didn't answer to READ EV1"); - ul_switch_off_field(); - return status; - } - // save AUTHENTICATION LIMITS for later: - authlim = (ulev1_conf[4] & 0x07); - bool allZeros = true; - for (uint8_t idx=0; idx<8; idx++) - if (ulev1_conf[idx]) allZeros = false; - - if (allZeros) authlim=7; - ulev1_print_configuration(ulev1_conf); + if (status == 32) ulev1_print_signature( ulev1_signature, sizeof(ulev1_signature)); } - if ((tagtype & (UL_EV1_48 | UL_EV1_128 | NTAG_210 | NTAG_212 | NTAG_213 | NTAG_215 | NTAG_216))) { - + if ((tagtype & (UL_EV1_48 | UL_EV1_128 | NTAG_210 | NTAG_212 | NTAG_213 | NTAG_215 | NTAG_216 | NTAG_I2C_1K | NTAG_I2C_2K))) { uint8_t version[10] = {0x00}; status = ulev1_getVersion(version, sizeof(version)); if ( status == -1 ){ @@ -772,14 +796,34 @@ int CmdHF14AMfUInfo(const char *Cmd){ ul_switch_off_field(); return status; } - ulev1_print_version(version); + if (status == 10) ulev1_print_version(version); + else locked = true; + uint8_t startconfigblock = 0; + uint8_t ulev1_conf[16] = {0x00}; + // config blocks always are last 4 pages + for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++) + if (tagtype & UL_TYPES_ARRAY[idx]) + startconfigblock = UL_MEMORY_ARRAY[idx]-3; + + status = ul_read(startconfigblock, ulev1_conf, sizeof(ulev1_conf)); + if ( status == -1 ) { + PrintAndLog("Error: tag didn't answer to READ EV1"); + ul_switch_off_field(); + return status; + } else if (status == 16) { + // save AUTHENTICATION LIMITS for later: + authlim = (ulev1_conf[4] & 0x07); + ulev1_print_configuration(ulev1_conf); + } else { + authlim=7; + } // AUTHLIMIT, (number of failed authentications) // 0 = limitless. // 1-7 = limit. No automatic tries then. // hasAuthKey, if we was called with key, skip test. - if ( authlim == 0 && !hasAuthKey ){ + if ( !authlim && !hasAuthKey ) { PrintAndLog("\n--- Known EV1/NTAG passwords."); len = 0; for (uint8_t i = 0; i < KEYS_PWD_COUNT; ++i ){ @@ -797,21 +841,12 @@ int CmdHF14AMfUInfo(const char *Cmd){ } } } + if (len < 1) PrintAndLog("password not known"); } } - - // NDEF Message - uint8_t cc[16] = {0x00}; - status = ul_read(3, cc, sizeof(cc)); - if ( status == -1 ){ - PrintAndLog("Error: tag didn't answer to READ NDEF"); - ul_switch_off_field(); - return status; - } - ndef_print_CC(cc); - ul_switch_off_field(); + if (locked) PrintAndLog("\nTag appears to be locked, try using the key to get more info"); PrintAndLog(""); return 1; } @@ -1106,7 +1141,7 @@ int CmdHF14AMfUDump(const char *Cmd){ } // Load bottom lockbytes if available - // HOW DOES THIS APPLY TO EV1 and/or NTAG??? + // TODO -- FIGURE OUT LOCK BYTES FOR TO EV1 and/or NTAG if ( Pages == 44 ) { lockbytes_t2 = data + (40*4); lockbytes2[0] = lockbytes_t2[2]; diff --git a/client/cmdhfmfu.h b/client/cmdhfmfu.h index d9182127..c20aecf1 100644 --- a/client/cmdhfmfu.h +++ b/client/cmdhfmfu.h @@ -18,7 +18,6 @@ int CmdHF14AMfUDump(const char *Cmd); int CmdHF14AMfUInfo(const char *Cmd); uint16_t GetHF14AMfU_Type(void); -//void rol (uint8_t *data, const size_t len); int ul_print_type(uint16_t tagtype, uint8_t spacer); void ul_switch_off_field(void); @@ -28,23 +27,25 @@ int usage_hf_mfu_info(void); int CmdHFMFUltra(const char *Cmd); typedef enum TAGTYPE_UL { - UNKNOWN = 0x0000, - UL = 0x0001, - UL_C = 0x0002, - UL_EV1_48 = 0x0004, - UL_EV1_128 = 0x0008, - NTAG = 0x0010, - NTAG_203 = 0x0020, - NTAG_210 = 0x0040, - NTAG_212 = 0x0080, - NTAG_213 = 0x0100, - NTAG_215 = 0x0200, - NTAG_216 = 0x0400, - MY_D = 0x0800, - MY_D_NFC = 0x1000, - MY_D_MOVE = 0x2000, - MY_D_MOVE_NFC = 0x4000, - MAGIC = 0x8000, + UNKNOWN = 0x000000, + UL = 0x000001, + UL_C = 0x000002, + UL_EV1_48 = 0x000004, + UL_EV1_128 = 0x000008, + NTAG = 0x000010, + NTAG_203 = 0x000020, + NTAG_210 = 0x000040, + NTAG_212 = 0x000080, + NTAG_213 = 0x000100, + NTAG_215 = 0x000200, + NTAG_216 = 0x000400, + MY_D = 0x000800, + MY_D_NFC = 0x001000, + MY_D_MOVE = 0x002000, + MY_D_MOVE_NFC = 0x004000, + NTAG_I2C_1K = 0x008000, + NTAG_I2C_2K = 0x010000, + MAGIC = 0x020000, UL_MAGIC = UL | MAGIC, UL_C_MAGIC = UL_C | MAGIC, UL_ERROR = 0xFFFF, -- 2.39.2