]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmdhficlass.c
Fix typos
[proxmark3-svn] / client / cmdhficlass.c
index 605793a57ff4028593ea38fe274493ebe30504f9..12a7141ef0f2aba895a9c1b71c5946faa73aa767 100644 (file)
@@ -406,7 +406,7 @@ int CmdHFiClassDecrypt(const char *Cmd) {
        fclose(f);
 
        saveFile(outfilename,"bin", decrypted, blocknum*8);
-
+       free(decrypted);
        return 0;
 }
 
@@ -472,7 +472,7 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v
        UsbCommand resp;
 
        UsbCommand c = {CMD_READER_ICLASS, {0}};
-       c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE| FLAG_ICLASS_READER_CC;
+       c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_CC | FLAG_ICLASS_READER_ONE_TRY;
        if (use_credit_key)
                c.arg[0] |= FLAG_ICLASS_READER_CEDITKEY;
 
@@ -500,7 +500,7 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v
        return true;    
 }
 
-static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool use_credit_key, bool elite, bool verbose) {
+static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool use_credit_key, bool elite, bool rawkey, bool verbose) {
        uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
 
@@ -508,7 +508,11 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u
                return false;
 
        //get div_key
-       HFiClassCalcDivKey(CSN, KEY, div_key, elite);
+       if(rawkey)
+               memcpy(div_key, KEY, 8);
+       else
+               HFiClassCalcDivKey(CSN, KEY, div_key, elite);
+       PrintAndLog("Authing with %s: %02x%02x%02x%02x%02x%02x%02x%02x", rawkey ? "raw key" : "diversified key", div_key[0],div_key[1],div_key[2],div_key[3],div_key[4],div_key[5],div_key[6],div_key[7]);
 
        doMAC(CCNR, div_key, MAC);
        UsbCommand resp;
@@ -530,7 +534,7 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u
 }
 
 int usage_hf_iclass_dump(void) {
-       PrintAndLog("Usage:  hf iclass dump f <fileName> k <Key> c <CreditKey> e\n");
+       PrintAndLog("Usage:  hf iclass dump f <fileName> k <Key> c <CreditKey> e|r\n");
        PrintAndLog("Options:");
        PrintAndLog("  f <filename> : specify a filename to save dump to");
        PrintAndLog("  k <Key>      : *Access Key as 16 hex symbols or 1 hex to select key from memory");
@@ -538,6 +542,7 @@ int usage_hf_iclass_dump(void) {
        PrintAndLog("  e            : If 'e' is specified, the key is interpreted as the 16 byte");
        PrintAndLog("                 Custom Key (KCus), which can be obtained via reader-attack");
        PrintAndLog("                 See 'hf iclass sim 2'. This key should be on iclass-format");
+       PrintAndLog("  r            : If 'r' is specified, the key is interpreted as raw block 3/4");
        PrintAndLog("  NOTE: * = required");
   PrintAndLog("Samples:");
        PrintAndLog("  hf iclass dump k 001122334455667B");
@@ -554,6 +559,8 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
        uint8_t blockno = 0;
        uint8_t numblks = 0;
        uint8_t maxBlk = 31;
+       uint8_t app_areas = 1;
+       uint8_t kb = 2;
        uint8_t KEY[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        uint8_t CreditKEY[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        uint8_t keyNbr = 0;
@@ -565,6 +572,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
        bool have_credit_key = false;
        bool use_credit_key = false;
        bool elite = false;
+       bool rawkey = false;
        bool errors = false;
        uint8_t cmdp = 0;
 
@@ -629,6 +637,11 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
                        }
                        cmdp += 2;
                        break;
+               case 'r':
+               case 'R':
+                       rawkey = true;
+                       cmdp++;
+                       break;
                default:
                        PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
                        errors = true;
@@ -651,6 +664,7 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
        SendCommand(&c);
        if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
                PrintAndLog("Command execute timeout");
+               ul_switch_off_field();
                return 0;
        }
        uint8_t readStatus = resp.arg[0] & 0xff;
@@ -658,42 +672,41 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
 
        if(readStatus == 0){
                PrintAndLog("No tag found...");
+               ul_switch_off_field();
                return 0;
        }
        if( readStatus & (FLAG_ICLASS_READER_CSN|FLAG_ICLASS_READER_CONF|FLAG_ICLASS_READER_CC)){
                memcpy(tag_data, data, 8*3);
                blockno+=2; // 2 to force re-read of block 2 later. (seems to respond differently..)
                numblks = data[8];
-
-               if (data[13] & 0x80) {
-                       // large memory - not able to dump pages currently
-                       maxBlk = 255;
-               }       else {
-                       maxBlk = 31;
-               }
+               getMemConfig(data[13], data[12], &maxBlk, &app_areas, &kb);
+               // large memory - not able to dump pages currently
                if (numblks > maxBlk) numblks = maxBlk;
        }
+       ul_switch_off_field();
        // authenticate debit key and get div_key - later store in dump block 3
-       if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, false)){
+       if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, false)){
                //try twice - for some reason it sometimes fails the first time...
-               if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, false)){
+               if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, false)){
                        ul_switch_off_field();
                        return 0;
                }
        }
        
        // begin dump
-       UsbCommand w = {CMD_ICLASS_DUMP, {blockno, numblks-blockno+1, 0x88}};
+       UsbCommand w = {CMD_ICLASS_DUMP, {blockno, numblks-blockno+1}};
        clearCommandBuffer();
        SendCommand(&w);
        if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
                PrintAndLog("Command execute time-out 1");
+               ul_switch_off_field();
                return 1;
        }
        uint32_t blocksRead = resp.arg[1];
        uint8_t isOK = resp.arg[0] & 0xff;
        if (!isOK && !blocksRead) {
                PrintAndLog("Read Block Failed");
+               ul_switch_off_field();
                return 0;
        }
        uint32_t startindex = resp.arg[2];
@@ -712,9 +725,9 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
                ul_switch_off_field();
                memset(MAC,0,4);
                // AA2 authenticate credit key and git c_div_key - later store in dump block 4
-               if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false)){
+               if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false, false)){
                        //try twice - for some reason it sometimes fails the first time...
-                       if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false)){
+                       if (!select_and_auth(CreditKEY, MAC, c_div_key, true, false, false, false)){
                                ul_switch_off_field();
                                return 0;
                        }
@@ -724,17 +737,18 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
                        // setup dump and start
                        w.arg[0] = blockno + blocksRead;
                        w.arg[1] = maxBlk - (blockno + blocksRead);
-                       w.arg[2] = 0x18;
                        clearCommandBuffer();
                        SendCommand(&w);
                        if (!WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
                                PrintAndLog("Command execute timeout 2");
+                               ul_switch_off_field();
                                return 0;
                        }
                        uint8_t isOK = resp.arg[0] & 0xff;
                        blocksRead = resp.arg[1];
                        if (!isOK && !blocksRead) {
                                PrintAndLog("Read Block Failed 2");
+                               ul_switch_off_field();
                                return 0;
                        }               
 
@@ -773,19 +787,18 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
        return 1;
 }
 
-static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool verbose) {
+static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool verbose) {
        uint8_t MAC[4]={0x00,0x00,0x00,0x00};
        uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
-       uint8_t keyType = (use_credit_key) ? 0x18 : 0x88;
-       if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, verbose))
+       if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose))
                return 0;
 
        UsbCommand resp;
 
        Calc_wb_mac(blockno,bldata,div_key,MAC);
-       UsbCommand w = {CMD_ICLASS_WRITEBLOCK, {blockno, keyType}};
+       UsbCommand w = {CMD_ICLASS_WRITEBLOCK, {blockno}};
        memcpy(w.d.asBytes, bldata, 8);
-       memcpy(w.d.asBytes + 8,MAC, 4);
+       memcpy(w.d.asBytes + 8, MAC, 4);
        
        clearCommandBuffer();
        SendCommand(&w);
@@ -800,7 +813,6 @@ static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_c
                return 0;
        }
        PrintAndLog("Write Block Successful");
-
        return 1;
 }
 
@@ -811,6 +823,7 @@ int usage_hf_iclass_writeblock(void) {
        PrintAndLog("  k <Key>   : Access Key as 16 hex symbols or 1 hex to select key from memory");
   PrintAndLog("  c         : If 'c' is specified, the key set is assumed to be the credit key\n");
   PrintAndLog("  e         : If 'e' is specified, elite computations applied to key");
+  PrintAndLog("  r         : If 'r' is specified, no computations applied to key");
   PrintAndLog("Samples:");
        PrintAndLog("  hf iclass writeblk b 0A d AAAAAAAAAAAAAAAA k 001122334455667B");
        PrintAndLog("  hf iclass writeblk b 1B d AAAAAAAAAAAAAAAA k 001122334455667B c");
@@ -820,13 +833,14 @@ int usage_hf_iclass_writeblock(void) {
 
 int CmdHFiClass_WriteBlock(const char *Cmd) {
        uint8_t blockno=0;
-       uint8_t bldata[8]={0};
+       uint8_t bldata[8]={0,0,0,0,0,0,0,0};
        uint8_t KEY[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
        uint8_t keyNbr = 0;
        uint8_t dataLen = 0;
        char tempStr[50] = {0};
        bool use_credit_key = false;
        bool elite = false;
+       bool rawkey= false;
        bool errors = false;
        uint8_t cmdp = 0;
        while(param_getchar(Cmd, cmdp) != 0x00)
@@ -882,6 +896,11 @@ int CmdHFiClass_WriteBlock(const char *Cmd) {
                        }
                        cmdp += 2;
                        break;
+               case 'r':
+               case 'R':
+                       rawkey = true;
+                       cmdp++;
+                       break;
                default:
                        PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
                        errors = true;
@@ -891,12 +910,13 @@ int CmdHFiClass_WriteBlock(const char *Cmd) {
        }
 
        if (cmdp < 6) return usage_hf_iclass_writeblock();
-
-       return WriteBlock(blockno, bldata, KEY, use_credit_key, elite, true);
+       int ans = WriteBlock(blockno, bldata, KEY, use_credit_key, elite, rawkey, true);
+       ul_switch_off_field();
+       return ans;
 }
 
 int usage_hf_iclass_clone(void) {
-       PrintAndLog("Usage:  hf iclass clone f <tagfile.bin> b <first block> l <last block> k <KEY> e c");
+       PrintAndLog("Usage:  hf iclass clone f <tagfile.bin> b <first block> l <last block> k <KEY> c e|r");
        PrintAndLog("Options:");
        PrintAndLog("  f <filename>: specify a filename to clone from");
        PrintAndLog("  b <Block>   : The first block to clone as 2 hex symbols");
@@ -904,6 +924,7 @@ int usage_hf_iclass_clone(void) {
        PrintAndLog("  k <Key>     : Access Key as 16 hex symbols or 1 hex to select key from memory");
        PrintAndLog("  c           : If 'c' is specified, the key set is assumed to be the credit key\n");
        PrintAndLog("  e           : If 'e' is specified, elite computations applied to key");
+       PrintAndLog("  r           : If 'r' is specified, no computations applied to key");
        PrintAndLog("Samples:");
        PrintAndLog("  hf iclass clone f iclass_tagdump-121345.bin b 06 l 1A k 1122334455667788 e");
        PrintAndLog("  hf iclass clone f iclass_tagdump-121345.bin b 05 l 19 k 0");
@@ -922,6 +943,7 @@ int CmdHFiClassCloneTag(const char *Cmd) {
        uint8_t dataLen = 0;
        bool use_credit_key = false;
        bool elite = false;
+       bool rawkey = false;
        bool errors = false;
        uint8_t cmdp = 0;
        while(param_getchar(Cmd, cmdp) != 0x00)
@@ -985,6 +1007,11 @@ int CmdHFiClassCloneTag(const char *Cmd) {
                        }
                        cmdp += 2;
                        break;
+               case 'r':
+               case 'R':
+                       rawkey = true;
+                       cmdp++;
+                       break;
                default:
                        PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
                        errors = true;
@@ -1024,10 +1051,10 @@ int CmdHFiClassCloneTag(const char *Cmd) {
        uint8_t MAC[4]={0x00,0x00,0x00,0x00};
        uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
 
-       if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, true))
+       if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, true))
                return 0;
 
-       UsbCommand w = {CMD_ICLASS_CLONE,{startblock,endblock,((use_credit_key) ? 0x18 : 0x88)}};
+       UsbCommand w = {CMD_ICLASS_CLONE,{startblock,endblock}};
        uint8_t *ptr;
        // calculate all mac for every the block we will write
        for (i = startblock; i <= endblock; i++){
@@ -1057,15 +1084,15 @@ int CmdHFiClassCloneTag(const char *Cmd) {
        return 1;
 }
 
-static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool verbose) {
+static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose) {
        uint8_t MAC[4]={0x00,0x00,0x00,0x00};
        uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
 
-       if (!select_and_auth(KEY, MAC, div_key, (keyType==0x18), elite, verbose))
+       if (!select_and_auth(KEY, MAC, div_key, (keyType==0x18), elite, rawkey, verbose))
                return 0;
 
        UsbCommand resp;
-       UsbCommand w = {CMD_ICLASS_READBLOCK, {blockno, keyType}};
+       UsbCommand w = {CMD_ICLASS_READBLOCK, {blockno}};
        clearCommandBuffer();
        SendCommand(&w);
        if (!WaitForResponseTimeout(CMD_ACK,&resp,4500))
@@ -1084,12 +1111,13 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite,
 }
 
 int usage_hf_iclass_readblock(void) {
-       PrintAndLog("Usage:  hf iclass readblk b <Block> k <Key> c e\n");
+       PrintAndLog("Usage:  hf iclass readblk b <Block> k <Key> c e|r\n");
        PrintAndLog("Options:");
   PrintAndLog("  b <Block> : The block number as 2 hex symbols");
        PrintAndLog("  k <Key>   : Access Key as 16 hex symbols or 1 hex to select key from memory");
   PrintAndLog("  c         : If 'c' is specified, the key set is assumed to be the credit key\n");
   PrintAndLog("  e         : If 'e' is specified, elite computations applied to key");
+  PrintAndLog("  r         : If 'r' is specified, no computations applied to key");
   PrintAndLog("Samples:");
        PrintAndLog("  hf iclass readblk b 06 k 0011223344556677");
        PrintAndLog("  hf iclass readblk b 1B k 0011223344556677 c");
@@ -1105,6 +1133,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
        uint8_t dataLen = 0;
        char tempStr[50] = {0};
        bool elite = false;
+       bool rawkey = false;
        bool errors = false;
        uint8_t cmdp = 0;
        while(param_getchar(Cmd, cmdp) != 0x00)
@@ -1151,6 +1180,11 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
                        }
                        cmdp += 2;
                        break;
+               case 'r':
+               case 'R':
+                       rawkey = true;
+                       cmdp++;
+                       break;
                default:
                        PrintAndLog("Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
                        errors = true;
@@ -1161,7 +1195,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
 
        if (cmdp < 4) return usage_hf_iclass_readblock();
 
-       return ReadBlock(KEY, blockno, keyType, elite, true);
+       return ReadBlock(KEY, blockno, keyType, elite, rawkey, true);
 }
 
 int CmdHFiClass_loclass(const char *Cmd) {
@@ -1175,7 +1209,7 @@ int CmdHFiClass_loclass(const char *Cmd) {
                PrintAndLog("f <filename>  Bruteforce iclass dumpfile");
                PrintAndLog("                   An iclass dumpfile is assumed to consist of an arbitrary number of");
                PrintAndLog("                   malicious CSNs, and their protocol responses");
-               PrintAndLog("                   The the binary format of the file is expected to be as follows: ");
+               PrintAndLog("                   The binary format of the file is expected to be as follows: ");
                PrintAndLog("                   <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
                PrintAndLog("                   <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
                PrintAndLog("                   <8 byte CSN><8 byte CC><4 byte NR><4 byte MAC>");
Impressum, Datenschutz