]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmdhfmfu.c
CHG: making sure all outputs follow the same pattern in "hf mfu info"
[proxmark3-svn] / client / cmdhfmfu.c
index 139289156adda9ed649c55d780c3ab4eb1e9d340..482d14ba2fef268d54cd035f2d1097ba2121dbaf 100644 (file)
@@ -18,7 +18,7 @@
 
 #define MAX_UL_BLOCKS          0x0f
 #define MAX_ULC_BLOCKS         0x2b
-#define MAX_ULEV1a_BLOCKS   0x12
+#define MAX_ULEV1a_BLOCKS      0x13
 #define MAX_ULEV1b_BLOCKS      0x28
 #define MAX_NTAG_203           0x29
 #define MAX_NTAG_210           0x13
@@ -71,15 +71,9 @@ char* getProductTypeStr( uint8_t id){
        char *retStr = buf;
 
        switch(id) {
-        case 3:
-               sprintf(retStr, "%02X, %s", id, "Ultralight");
-               break;
-       case 4:
-               sprintf(retStr, "%02X, %s", id, "NTAG");
-               break;
-       default:
-               sprintf(retStr, "%02X, %s", id, "unknown");
-               break;
+               case 3: sprintf(retStr, "%02X, Ultralight", id); break;
+               case 4: sprintf(retStr, "%02X, NTAG", id); break;
+               default: sprintf(retStr, "%02X, unknown", id); break;
        }
        return buf;
 }
@@ -100,9 +94,9 @@ char* getUlev1CardSizeStr( uint8_t fsize ){
 
        // is  LSB set?
        if ( fsize & 1 )
-               sprintf(retStr, "%02X (%u <-> %u bytes)", fsize, usize, lsize);
+               sprintf(retStr, "%02X, (%u <-> %u bytes)", fsize, usize, lsize);
        else 
-               sprintf(retStr, "%02X (%u bytes)", fsize, lsize);               
+               sprintf(retStr, "%02X, (%u bytes)", fsize, lsize);              
        return buf;
 }
 
@@ -150,11 +144,16 @@ static int ul_select( iso14a_card_select_t *card ){
        ul_switch_on_field();
 
        UsbCommand resp;
-       if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1;
-       if (resp.arg[0] < 1) return -1;
+       bool ans = false;
+       ans = WaitForResponseTimeout(CMD_ACK, &resp, 1500);
+       if (!ans || resp.arg[0] < 1) {
+               PrintAndLog("iso14443a card select failed");
+               ul_switch_off_field();
+               return 0;
+       }
        
        memcpy(card, resp.d.asBytes, sizeof(iso14a_card_select_t));
-       return resp.arg[0];
+       return 1;
 }
 
 // This read command will at least return 16bytes.
@@ -259,7 +258,7 @@ static int ul_print_default( uint8_t *data){
        uid[6] = data[7];
 
        PrintAndLog("       UID : %s ", sprint_hex(uid, 7));
-       PrintAndLog("    UID[0] : %02X, Manufacturer: %s",  uid[0], getTagInfo(uid[0]) );
+       PrintAndLog("    UID[0] : %02X, %s",  uid[0], getTagInfo(uid[0]) );
        if ( uid[0] == 0x05 ) {
                uint8_t chip = (data[8] & 0xC7); // 11000111  mask, bit 3,4,5 RFU
                switch (chip){
@@ -303,23 +302,23 @@ static int ndef_print_CC(uint8_t *data) {
 
        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);
-       PrintAndLog("  %02X: Physical Memory Size: %d bytes", data[2], (data[2] + 1) * 8);
+       PrintAndLog("  %02X : NDEF Magic Number", data[0]); 
+       PrintAndLog("  %02X : version %d.%d supported by tag", data[1], (data[1] & 0xF0) >> 4, data[1] & 0x0f);
+       PrintAndLog("  %02X : Physical Memory Size: %d bytes", data[2], (data[2] + 1) * 8);
        if ( data[2] == 0x12 )
-               PrintAndLog("  %02X: NDEF Memory Size: %d bytes", data[2], 144);
+               PrintAndLog("  %02X : NDEF Memory Size: %d bytes", data[2], 144);
        else if ( data[2] == 0x3e )
-               PrintAndLog("  %02X: NDEF Memory Size: %d bytes", data[2], 496);
+               PrintAndLog("  %02X : NDEF Memory Size: %d bytes", data[2], 496);
        else if ( data[2] == 0x6d )
-               PrintAndLog("  %02X: NDEF Memory Size: %d bytes", data[2], 872);
+               PrintAndLog("  %02X : NDEF Memory Size: %d bytes", data[2], 872);
        
-       PrintAndLog("  %02X: %s / %s", data[3], 
+       PrintAndLog("  %02X : %s / %s", data[3], 
                                (data[3] & 0xF0) ? "(RFU)" : "Read access granted without any security", 
                                (data[3] & 0x0F)==0 ? "Write access granted without any security" : (data[3] & 0x0F)==0x0F ? "No write access granted at all" : "(RFU)");
        return 0;                               
 }
 
-int ul_print_type(uint16_t tagtype, uint8_t spaces){
+int ul_print_type(uint32_t tagtype, uint8_t spaces){
        char spc[11] = "          ";
        spc[10]=0x00;
        char *spacer = spc + (10-spaces);
@@ -347,9 +346,9 @@ int ul_print_type(uint16_t tagtype, uint8_t spaces){
        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);
+               PrintAndLog("%sTYPE : NTAG I%sC 888bytes (NT3H1101FHK)", spacer, "\xFD");
        else if ( tagtype & NTAG_I2C_2K )       
-               PrintAndLog("%sTYPE : NTAG i2c 1904bytes (NT3H1201FHK )", spacer);
+               PrintAndLog("%sTYPE : NTAG I%sC 1904bytes (NT3H1201FHK)", spacer, "\xFD");
        else if ( tagtype & MY_D )
                PrintAndLog("%sTYPE : INFINEON my-d\x99", spacer);
        else if ( tagtype & MY_D_NFC )
@@ -364,10 +363,10 @@ int ul_print_type(uint16_t tagtype, uint8_t spaces){
 }
 
 static int ulc_print_3deskey( uint8_t *data){                  
-       PrintAndLog("         deskey1 [44/0x2C]: %s [%.4s]", sprint_hex(data   ,4),data);
-       PrintAndLog("         deskey1 [45/0x2D]: %s [%.4s]", sprint_hex(data+4 ,4),data+4);
-       PrintAndLog("         deskey2 [46/0x2E]: %s [%.4s]", sprint_hex(data+8 ,4),data+8);
-       PrintAndLog("         deskey2 [47/0x2F]: %s [%.4s]", sprint_hex(data+12,4),data+12);
+       PrintAndLog("         deskey1 [44/0x2C] : %s [%.4s]", sprint_hex(data   ,4),data);
+       PrintAndLog("         deskey1 [45/0x2D] : %s [%.4s]", sprint_hex(data+4 ,4),data+4);
+       PrintAndLog("         deskey2 [46/0x2E] : %s [%.4s]", sprint_hex(data+8 ,4),data+8);
+       PrintAndLog("         deskey2 [47/0x2F] : %s [%.4s]", sprint_hex(data+12,4),data+12);
        PrintAndLog("\n 3des key : %s", sprint_hex(SwapEndian64(data, 16, 8), 16));
        return 0;
 }
@@ -375,20 +374,20 @@ static int ulc_print_3deskey( uint8_t *data){
 static int ulc_print_configuration( uint8_t *data){
                
        PrintAndLog("--- UL-C Configuration");
-       PrintAndLog(" Higher Lockbits [40/0x28]: %s - %s", sprint_hex(data, 4), printBits(2, data));
-       PrintAndLog("         Counter [41/0x29]: %s - %s", sprint_hex(data+4, 4), printBits(2, data+4));
+       PrintAndLog(" Higher Lockbits [40/0x28] : %s - %s", sprint_hex(data, 4), printBits(2, data));
+       PrintAndLog("         Counter [41/0x29] : %s - %s", sprint_hex(data+4, 4), printBits(2, data+4));
 
        bool validAuth = (data[8] >= 0x03 && data[8] <= 0x30);
        if ( validAuth )
-               PrintAndLog("           Auth0 [42/0x2A]: %s page %d/0x%02X and above need authentication", sprint_hex(data+8, 4), data[8],data[8] );
+               PrintAndLog("           Auth0 [42/0x2A] : %s page %d/0x%02X and above need authentication", sprint_hex(data+8, 4), data[8],data[8] );
        else{
                if ( data[8] == 0){
-                       PrintAndLog("           Auth0 [42/0x2A]: %s default", sprint_hex(data+8, 4) );
+                       PrintAndLog("           Auth0 [42/0x2A] : %s default", sprint_hex(data+8, 4) );
                } else {
-                       PrintAndLog("           Auth0 [42/0x2A]: %s auth byte is out-of-range", sprint_hex(data+8, 4) );
+                       PrintAndLog("           Auth0 [42/0x2A] : %s auth byte is out-of-range", sprint_hex(data+8, 4) );
                }
        }
-       PrintAndLog("           Auth1 [43/0x2B]: %s %s",
+       PrintAndLog("           Auth1 [43/0x2B] : %s %s",
                        sprint_hex(data+12, 4),
                        (data[12] & 1) ? "write access restricted": "read and write access restricted"
                        );
@@ -428,13 +427,16 @@ static int ulev1_print_counters(){
        PrintAndLog("--- Tag Counters");
        uint8_t tear[1] = {0};
        uint8_t counter[3] = {0,0,0};
+       uint16_t len = 0;
        for ( uint8_t i = 0; i<3; ++i) {
                ulev1_readTearing(i,tear,sizeof(tear));
-               ulev1_readCounter(i,counter, sizeof(counter) );
+               len = ulev1_readCounter(i,counter, sizeof(counter) );
+               if (len == 3) {
                PrintAndLog("       [%0d] : %s", i, sprint_hex(counter,3));
                PrintAndLog("                    - %02X tearing %s", tear[0], ( tear[0]==0xBD)?"Ok":"failure");
        }
-       return 0;
+       }
+       return len;
 }
 
 static int ulev1_print_signature( uint8_t *data, uint8_t len){
@@ -451,7 +453,7 @@ static int ulev1_print_signature( uint8_t *data, uint8_t len){
 static int ulev1_print_version(uint8_t *data){         
        PrintAndLog("\n--- Tag Version");
        PrintAndLog("       Raw bytes : %s", sprint_hex(data, 8) );
-       PrintAndLog("       Vendor ID : %02X, Manufacturer: %s", data[1], getTagInfo(data[1]));
+       PrintAndLog("       Vendor ID : %02X, %s", data[1], getTagInfo(data[1]));
        PrintAndLog("    Product type : %s"             , getProductTypeStr(data[2]));
        PrintAndLog(" Product subtype : %02X, %s"       , data[3], (data[3]==1) ?"17 pF":"50pF");
        PrintAndLog("   Major version : %02X"   , data[4]);
@@ -474,9 +476,7 @@ static int ulc_magic_test(){
        uint8_t nonce1[11] = {0x00};
        uint8_t nonce2[11] = {0x00};
        int status = ul_select(&card);
-       if ( status < 1 ){
-               PrintAndLog("Error: couldn't select ulc_magic_test");
-               ul_switch_off_field();
+       if ( !status ){
                return UL_ERROR;
        }
        status = ulc_requestAuthentication(nonce1, sizeof(nonce1));
@@ -496,17 +496,13 @@ static int ul_magic_test(){
        // 1) take present UID, and try to write it back. OBSOLETE 
        // 2) make a wrong length write to page0, and see if tag answers with ACK/NACK:
        iso14a_card_select_t card;
-       int status = ul_select(&card);
-       if ( status < 1 ){
-               PrintAndLog("iso14443a card select failed");
-               ul_switch_off_field();
+       if ( !ul_select(&card) ) 
                return UL_ERROR;
-       }
-       status = ul_comp_write(0, NULL, 0);
+       int status = ul_comp_write(0, NULL, 0);
        ul_switch_off_field();
        if ( status == 0 ) 
                return MAGIC;
-       return UNKNOWN;
+       return 0;
 }
 
 uint32_t GetHF14AMfU_Type(void){
@@ -517,12 +513,8 @@ uint32_t GetHF14AMfU_Type(void){
        int status = 0;
        int len;
 
-       status = ul_select(&card);
-       if ( status < 1 ){
-               PrintAndLog("iso14443a card select failed");
-               ul_switch_off_field();
-               return UL_ERROR;
-       }
+       if (!ul_select(&card)) return UL_ERROR;
+
        // Ultralight - ATQA / SAK 
        if ( card.atqa[1] != 0x00 || card.atqa[0] != 0x44 || card.sak != 0x00 ) {
                PrintAndLog("Tag is not Ultralight | NTAG | MY-D  [ATQA: %02X %02X SAK: %02X]\n", card.atqa[1], card.atqa[0], card.sak);
@@ -568,12 +560,7 @@ uint32_t GetHF14AMfU_Type(void){
                }
                // 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;
-                       }
+                       if ( !ul_select(&card) ) return UL_ERROR;
 
                        // do UL_C check first...
                        uint8_t nonce[11] = {0x00};
@@ -583,12 +570,8 @@ uint32_t GetHF14AMfU_Type(void){
                                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;
-                               }
+                               if ( !ul_select(&card) ) return UL_ERROR;
+
                                uint8_t data[16] = {0x00};
                                // read page 0x26-0x29 (last valid ntag203 page)
                                status = ul_read(0x26, data, sizeof(data));
@@ -616,8 +599,9 @@ uint32_t GetHF14AMfU_Type(void){
                }
        }
        
-       tagtype = (ul_magic_test() == MAGIC) ? (tagtype | MAGIC) : tagtype;
 
+       tagtype |= ul_magic_test();
+       if (tagtype == (UNKNOWN | MAGIC)) tagtype = (UL_MAGIC);
        return tagtype;
 }      
 
@@ -630,12 +614,13 @@ int CmdHF14AMfUInfo(const char *Cmd){
        int status;     
        bool errors = false;
        bool hasAuthKey = false;
+       bool hasPwdKey = false;
        bool locked = false;
        uint8_t cmdp = 0;
        uint8_t datalen = 0;
        uint8_t authenticationkey[16] = {0x00};
        uint8_t pack[4] = {0,0,0,0};
-       int len=0;
+       int len = 0;
                                
        while(param_getchar(Cmd, cmdp) != 0x00)
        {
@@ -651,7 +636,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
                        if ( !datalen ) {
                                memcpy(authenticationkey, data, 4);
                                cmdp += 2;
-                               hasAuthKey = true;
+                               hasPwdKey = true;
                                break;
                        }
                        // UL-C size key        
@@ -682,28 +667,24 @@ int CmdHF14AMfUInfo(const char *Cmd){
        PrintAndLog("-------------------------------------------------------------");
        ul_print_type(tagtype, 6);
        
+       if (!ul_select(&card)) return 0;
+       
        if ( hasAuthKey && (tagtype & UL_C)) {
                //will select card automatically and close connection on error
                if (!ulc_authentication(authenticationkey, false)) {
-                               PrintAndLog("Error: Authentication Failed UL-C");
-                               return 0;
-                       }
-               } else {
-               status = ul_select(&card);
-               if ( status < 1 ){
-                       PrintAndLog("iso14443a card select failed");
-                       ul_switch_off_field();
-                       return status;
-               }
-               if (hasAuthKey) {
-                       len = ulev1_requestAuthentication(authenticationkey, pack, sizeof(pack));
-                       if (len < 1) {
-                               ul_switch_off_field();
-                               PrintAndLog("Error: Authentication Failed UL-EV1/NTAG");
-                               return 0;
-                       }
+                       PrintAndLog("Error: Authentication Failed UL-C");
+                       return 0;
                }
        }
+       
+       if ( hasPwdKey ) {
+               len = ulev1_requestAuthentication(authenticationkey, pack, sizeof(pack));
+               if (len < 1) {
+                       ul_switch_off_field();
+                       PrintAndLog("Error: Authentication Failed UL-EV1/NTAG");
+                       return 0;
+               } 
+       }
 
        // read pages 0,1,2,3 (should read 4pages)
        status = ul_read(0, data, sizeof(data));
@@ -712,6 +693,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
                PrintAndLog("Error: tag didn't answer to READ");
                return status;
        }
+       
        if (status == 16) {
                ul_print_default(data);
                ndef_print_CC(data+12);
@@ -763,19 +745,19 @@ int CmdHF14AMfUInfo(const char *Cmd){
                                } 
                        }
                        // reselect for future tests (ntag test)
-                       status = ul_select(&card);
-                       if ( status < 1 ){
-                               PrintAndLog("iso14443a card select failed");
-                               ul_switch_off_field();
-                               return status;
-                       }
+                       if ( !ul_select(&card) ) return 0;
                }
        }
 
        // 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))) {
+               if (ulev1_print_counters() != 3) {
+                       // failed - re-select
+                       if ( !ul_select(&card) ) return 0;
+               }
+       }
 
        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};
@@ -786,6 +768,10 @@ int CmdHF14AMfUInfo(const char *Cmd){
                        return status;
                }               
                if (status == 32) ulev1_print_signature( ulev1_signature, sizeof(ulev1_signature));
+               else {
+                       // re-select
+                       if ( !ul_select(&card) ) return 0;
+               }
        }
        
        if ((tagtype & (UL_EV1_48 | UL_EV1_128 | NTAG_210 | NTAG_212 | NTAG_213 | NTAG_215 | NTAG_216 | NTAG_I2C_1K | NTAG_I2C_2K))) {
@@ -806,6 +792,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
                        if (tagtype & UL_TYPES_ARRAY[idx])
                                startconfigblock = UL_MEMORY_ARRAY[idx]-3;
 
+               if (startconfigblock){ // if we know where the config block is...
                status = ul_read(startconfigblock, ulev1_conf, sizeof(ulev1_conf));
                if ( status == -1 ) {
                        PrintAndLog("Error: tag didn't answer to READ EV1");
@@ -815,8 +802,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
                        // save AUTHENTICATION LIMITS for later:
                        authlim = (ulev1_conf[4] & 0x07);
                        ulev1_print_configuration(ulev1_conf);
-               } else {
-                       authlim=7;
+                       }
                }
        
                // AUTHLIMIT, (number of failed authentications)
@@ -833,12 +819,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
                                        PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
                                        break;
                                } else {
-                                       status = ul_select(&card);
-                                       if ( status < 1 ){
-                                               PrintAndLog("iso14443a card select failed - ev1 auth");
-                                               ul_switch_off_field();
-                                               return status;
-                               }
+                                       if ( !ul_select(&card) ) return 0;
                        }
                        }
                        if (len < 1) PrintAndLog("password not known");
Impressum, Datenschutz