]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - client/mifarehost.c
ADD: marshmellows new lf command and DetectClock. (works great!)
[proxmark3-svn] / client / mifarehost.c
index 03951e2de071bdbcb6f8133855082566999ec5c9..41ea1030517d7319f166914ea5e3673fa10e9acb 100644 (file)
@@ -26,8 +26,6 @@ int compar_int(const void * a, const void * b) {
        else return -1;\r
 }\r
 \r
-\r
-\r
 // Compare 16 Bits out of cryptostate\r
 int Compare16Bits(const void * a, const void * b) {\r
        if ((*(uint64_t*)b & 0x00ff000000ff0000) == (*(uint64_t*)a & 0x00ff000000ff0000)) return 0;\r
@@ -35,17 +33,16 @@ int Compare16Bits(const void * a, const void * b) {
        else return -1;\r
 }\r
 \r
-\r
 typedef \r
        struct {\r
                union {\r
                        struct Crypto1State *slhead;\r
                        uint64_t *keyhead;\r
-               };\r
+               } head;\r
                union {\r
                        struct Crypto1State *sltail;\r
                        uint64_t *keytail;\r
-               };\r
+               } tail;\r
                uint32_t len;\r
                uint32_t uid;\r
                uint32_t blockNo;\r
@@ -61,24 +58,20 @@ void* nested_worker_thread(void *arg)
        struct Crypto1State *p1;\r
        StateList_t *statelist = arg;\r
 \r
-       statelist->slhead = lfsr_recovery32(statelist->ks1, statelist->nt ^ statelist->uid);\r
-       for (p1 = statelist->slhead; *(uint64_t *)p1 != 0; p1++);\r
-       statelist->len = p1 - statelist->slhead;\r
-       statelist->sltail = --p1;\r
-       qsort(statelist->slhead, statelist->len, sizeof(uint64_t), Compare16Bits);\r
+       statelist->head.slhead = lfsr_recovery32(statelist->ks1, statelist->nt ^ statelist->uid);\r
+       for (p1 = statelist->head.slhead; *(uint64_t *)p1 != 0; p1++);\r
+       statelist->len = p1 - statelist->head.slhead;\r
+       statelist->tail.sltail = --p1;\r
+       qsort(statelist->head.slhead, statelist->len, sizeof(uint64_t), Compare16Bits);\r
        \r
-       return statelist->slhead;\r
+       return statelist->head.slhead;\r
 }\r
 \r
-\r
-\r
-\r
 int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * resultKey, bool calibrate) \r
 {\r
        uint16_t i, len;\r
        uint32_t uid;\r
        UsbCommand resp;\r
-\r
        \r
        StateList_t statelists[2];\r
        struct Crypto1State *p1, *p2, *p3, *p4;\r
@@ -122,27 +115,27 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
        \r
        // wait for threads to terminate:\r
        for (i = 0; i < 2; i++) {\r
-               pthread_join(thread_id[i], (void*)&statelists[i].slhead);\r
+               pthread_join(thread_id[i], (void*)&statelists[i].head.slhead);\r
        }\r
 \r
 \r
        // the first 16 Bits of the cryptostate already contain part of our key.\r
        // Create the intersection of the two lists based on these 16 Bits and\r
        // roll back the cryptostate\r
-       p1 = p3 = statelists[0].slhead; \r
-       p2 = p4 = statelists[1].slhead;\r
-       while (p1 <= statelists[0].sltail && p2 <= statelists[1].sltail) {\r
+       p1 = p3 = statelists[0].head.slhead; \r
+       p2 = p4 = statelists[1].head.slhead;\r
+       while (p1 <= statelists[0].tail.sltail && p2 <= statelists[1].tail.sltail) {\r
                if (Compare16Bits(p1, p2) == 0) {\r
                        struct Crypto1State savestate, *savep = &savestate;\r
                        savestate = *p1;\r
-                       while(Compare16Bits(p1, savep) == 0 && p1 <= statelists[0].sltail) {\r
+                       while(Compare16Bits(p1, savep) == 0 && p1 <= statelists[0].tail.sltail) {\r
                                *p3 = *p1;\r
                                lfsr_rollback_word(p3, statelists[0].nt ^ statelists[0].uid, 0);\r
                                p3++;\r
                                p1++;\r
                        }\r
                        savestate = *p2;\r
-                       while(Compare16Bits(p2, savep) == 0 && p2 <= statelists[1].sltail) {\r
+                       while(Compare16Bits(p2, savep) == 0 && p2 <= statelists[1].tail.sltail) {\r
                                *p4 = *p2;\r
                                lfsr_rollback_word(p4, statelists[1].nt ^ statelists[1].uid, 0);\r
                                p4++;\r
@@ -156,20 +149,20 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
        }\r
        p3->even = 0; p3->odd = 0;\r
        p4->even = 0; p4->odd = 0;\r
-       statelists[0].len = p3 - statelists[0].slhead;\r
-       statelists[1].len = p4 - statelists[1].slhead;\r
-       statelists[0].sltail=--p3;\r
-       statelists[1].sltail=--p4;\r
+       statelists[0].len = p3 - statelists[0].head.slhead;\r
+       statelists[1].len = p4 - statelists[1].head.slhead;\r
+       statelists[0].tail.sltail=--p3;\r
+       statelists[1].tail.sltail=--p4;\r
 \r
        // the statelists now contain possible keys. The key we are searching for must be in the\r
        // intersection of both lists. Create the intersection:\r
-       qsort(statelists[0].keyhead, statelists[0].len, sizeof(uint64_t), compar_int);\r
-       qsort(statelists[1].keyhead, statelists[1].len, sizeof(uint64_t), compar_int);\r
+       qsort(statelists[0].head.keyhead, statelists[0].len, sizeof(uint64_t), compar_int);\r
+       qsort(statelists[1].head.keyhead, statelists[1].len, sizeof(uint64_t), compar_int);\r
 \r
        uint64_t *p5, *p6, *p7;\r
-       p5 = p7 = statelists[0].keyhead; \r
-       p6 = statelists[1].keyhead;\r
-       while (p5 <= statelists[0].keytail && p6 <= statelists[1].keytail) {\r
+       p5 = p7 = statelists[0].head.keyhead; \r
+       p6 = statelists[1].head.keyhead;\r
+       while (p5 <= statelists[0].tail.keytail && p6 <= statelists[1].tail.keytail) {\r
                if (compar_int(p5, p6) == 0) {\r
                        *p7++ = *p5++;\r
                        p6++;\r
@@ -179,15 +172,15 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
                        while (compar_int(p5, p6) == 1) p6++;\r
                }\r
        }\r
-       statelists[0].len = p7 - statelists[0].keyhead;\r
-       statelists[0].keytail=--p7;\r
+       statelists[0].len = p7 - statelists[0].head.keyhead;\r
+       statelists[0].tail.keytail=--p7;\r
 \r
        memset(resultKey, 0, 6);\r
        // The list may still contain several key candidates. Test each of them with mfCheckKeys\r
        for (i = 0; i < statelists[0].len; i++) {\r
                uint8_t keyBlock[6];\r
                uint64_t key64;\r
-               crypto1_get_lfsr(statelists[0].slhead + i, &key64);\r
+               crypto1_get_lfsr(statelists[0].head.slhead + i, &key64);\r
                num_to_bytes(key64, 6, keyBlock);\r
                key64 = 0;\r
                if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, 1, keyBlock, &key64)) {\r
@@ -196,8 +189,8 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo
                }\r
        }\r
        \r
-       free(statelists[0].slhead);\r
-       free(statelists[1].slhead);\r
+       free(statelists[0].head.slhead);\r
+       free(statelists[1].head.slhead);\r
        \r
        return 0;\r
 }\r
@@ -223,7 +216,7 @@ int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) {
        UsbCommand c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}};\r
        SendCommand(&c);\r
 \r
-  UsbCommand resp;\r
+       UsbCommand resp;\r
        if (!WaitForResponseTimeout(CMD_ACK,&resp,1500)) return 1;\r
        memcpy(data, resp.d.asBytes, blocksCount * 16);\r
        return 0;\r
@@ -238,9 +231,8 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
 \r
 // "MAGIC" CARD\r
 \r
-int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe) {\r
-       uint8_t block0[16];\r
-       memset(block0, 0, 16);\r
+int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) {\r
+       uint8_t block0[16] = {0x00};\r
        memcpy(block0, uid, 4); \r
        block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC\r
        // mifare classic SAK(byte 5) and ATQA(byte 6 and 7)\r
@@ -251,14 +243,14 @@ int mfCSetUID(uint8_t *uid, uint8_t *oldUID, int wantWipe) {
        return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);\r
 }\r
 \r
-int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, int wantWipe, uint8_t params) {\r
-       uint8_t isOK = 0;\r
+int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params) {\r
 \r
+       uint8_t isOK = 0;\r
        UsbCommand c = {CMD_MIFARE_EML_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};\r
        memcpy(c.d.asBytes, data, 16); \r
        SendCommand(&c);\r
 \r
-  UsbCommand resp;\r
+       UsbCommand resp;\r
        if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {\r
                isOK  = resp.arg[0] & 0xff;\r
                if (uid != NULL) memcpy(uid, resp.d.asBytes, 4);\r
@@ -296,7 +288,7 @@ static uint8_t trailerAccessBytes[4] = {0x08, 0x77, 0x8F, 0x00};
 // variables\r
 char logHexFileName[200] = {0x00};\r
 static uint8_t traceCard[4096] = {0x00};\r
-static char traceFileName[20];\r
+static char traceFileName[200] = {0x00};\r
 static int traceState = TRACE_IDLE;\r
 static uint8_t traceCurBlock = 0;\r
 static uint8_t traceCurKey = 0;\r
@@ -310,12 +302,9 @@ uint32_t ks3;
 \r
 uint32_t uid;     // serial number\r
 uint32_t nt;      // tag challenge\r
-uint32_t nt_par; \r
 uint32_t nr_enc;  // encrypted reader challenge\r
 uint32_t ar_enc;  // encrypted reader response\r
-uint32_t nr_ar_par; \r
 uint32_t at_enc;  // encrypted tag response\r
-uint32_t at_par; \r
 \r
 int isTraceCardEmpty(void) {\r
        return ((traceCard[0] == 0) && (traceCard[1] == 0) && (traceCard[2] == 0) && (traceCard[3] == 0));\r
@@ -351,12 +340,14 @@ int loadTraceCard(uint8_t *tuid) {
                memset(buf, 0, sizeof(buf));\r
                if (fgets(buf, sizeof(buf), f) == NULL) {\r
       PrintAndLog("File reading error.");\r
+                       fclose(f);\r
                        return 2;\r
     }\r
 \r
                if (strlen(buf) < 32){\r
                        if (feof(f)) break;\r
                        PrintAndLog("File content error. Block data must include 32 HEX symbols");\r
+                       fclose(f);\r
                        return 2;\r
                }\r
                for (i = 0; i < 32; i += 2)\r
@@ -422,7 +413,7 @@ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool i
 }\r
 \r
 \r
-int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEmlFile) {\r
+int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {\r
        uint8_t data[64];\r
 \r
        if (traceState == TRACE_ERROR) return 1;\r
@@ -449,7 +440,7 @@ int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEm
                }\r
                \r
                // AUTHENTICATION\r
-               if ((len ==4) && ((data[0] == 0x60) || (data[0] == 0x61))) {\r
+               if ((len == 4) && ((data[0] == 0x60) || (data[0] == 0x61))) {\r
                        traceState = TRACE_AUTH1;\r
                        traceCurBlock = data[1];\r
                        traceCurKey = data[0] == 60 ? 1:0;\r
@@ -497,7 +488,7 @@ int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEm
        break;\r
 \r
        case TRACE_WRITE_OK: \r
-               if ((len == 1) && (data[0] = 0x0a)) {\r
+               if ((len == 1) && (data[0] == 0x0a)) {\r
                        traceState = TRACE_WRITE_DATA;\r
 \r
                        return 0;\r
@@ -523,9 +514,7 @@ int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEm
        case TRACE_AUTH1: \r
                if (len == 4) {\r
                        traceState = TRACE_AUTH2;\r
-\r
                        nt = bytes_to_num(data, 4);\r
-                       nt_par = parity;\r
                        return 0;\r
                } else {\r
                        traceState = TRACE_ERROR;\r
@@ -539,7 +528,6 @@ int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEm
 \r
                        nr_enc = bytes_to_num(data, 4);\r
                        ar_enc = bytes_to_num(data + 4, 4);\r
-                       nr_ar_par = parity;\r
                        return 0;\r
                } else {\r
                        traceState = TRACE_ERROR;\r
@@ -552,26 +540,16 @@ int mfTraceDecode(uint8_t *data_src, int len, uint32_t parity, bool wantSaveToEm
                        traceState = TRACE_IDLE;\r
 \r
                        at_enc = bytes_to_num(data, 4);\r
-                       at_par = parity;\r
                        \r
                        //  decode key here)\r
-                       if (!traceCrypto1) {\r
-                               ks2 = ar_enc ^ prng_successor(nt, 64);\r
-                               ks3 = at_enc ^ prng_successor(nt, 96);\r
-                               revstate = lfsr_recovery64(ks2, ks3);\r
-                               lfsr_rollback_word(revstate, 0, 0);\r
-                               lfsr_rollback_word(revstate, 0, 0);\r
-                               lfsr_rollback_word(revstate, nr_enc, 1);\r
-                               lfsr_rollback_word(revstate, uid ^ nt, 0);\r
-                       }else{\r
-                               ks2 = ar_enc ^ prng_successor(nt, 64);\r
-                               ks3 = at_enc ^ prng_successor(nt, 96);\r
-                               revstate = lfsr_recovery64(ks2, ks3);\r
-                               lfsr_rollback_word(revstate, 0, 0);\r
-                               lfsr_rollback_word(revstate, 0, 0);\r
-                               lfsr_rollback_word(revstate, nr_enc, 1);\r
-                               lfsr_rollback_word(revstate, uid ^ nt, 0);\r
-                       }\r
+                       ks2 = ar_enc ^ prng_successor(nt, 64);\r
+                       ks3 = at_enc ^ prng_successor(nt, 96);\r
+                       revstate = lfsr_recovery64(ks2, ks3);\r
+                       lfsr_rollback_word(revstate, 0, 0);\r
+                       lfsr_rollback_word(revstate, 0, 0);\r
+                       lfsr_rollback_word(revstate, nr_enc, 1);\r
+                       lfsr_rollback_word(revstate, uid ^ nt, 0);\r
+\r
                        crypto1_get_lfsr(revstate, &lfsr);\r
                        printf("key> %x%x\n", (unsigned int)((lfsr & 0xFFFFFFFF00000000) >> 32), (unsigned int)(lfsr & 0xFFFFFFFF));\r
                        AddLogUint64(logHexFileName, "key> ", lfsr); \r
Impressum, Datenschutz