]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - client/cmdlfem4x.c
chg: @marshmellow42 's changes.
[proxmark3-svn] / client / cmdlfem4x.c
index a0cc060bb5f9321a7de3d445ae488f6961c41499..e6db80261a6992277942ee64f96e0d836f738444 100644 (file)
@@ -147,7 +147,8 @@ int CmdEM410xWatch(const char *Cmd)
                }
                
                CmdLFRead("s");
-               getSamples("8201",true); //capture enough to get 2 complete preambles (4096*2+9)        
+               //getSamples("8201",true); //capture enough to get 2 complete preambles (4096*2+9)      
+               getSamples("6144",true);
        } while (!CmdEM410xRead(""));
 
        return 0;
@@ -159,7 +160,7 @@ int CmdEM410xWatchnSpoof(const char *Cmd)
 {
        // loops if the captured ID was in XL-format.
        CmdEM410xWatch(Cmd);
-       PrintAndLog("# Replaying captured ID: %llu", g_em410xid);
+       PrintAndLog("# Replaying captured ID: %" PRIu64 , g_em410xid);
        CmdLFaskSim("");
        return 0;
 }
@@ -225,30 +226,67 @@ int CmdEM410xWrite(const char *Cmd)
 
 bool EM_EndParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t cols, uint8_t pType)
 {
-       if (rows*cols>size) return false;
+       if (rows*cols>size) return FALSE;
        uint8_t colP=0;
        //assume last col is a parity and do not test
        for (uint8_t colNum = 0; colNum < cols-1; colNum++) {
                for (uint8_t rowNum = 0; rowNum < rows; rowNum++) {
                        colP ^= BitStream[(rowNum*cols)+colNum];
                }
-               if (colP != pType) return false;
+               if (colP != pType) return FALSE;
        }
-       return true;
+       return TRUE;
 }
 
 bool EM_ByteParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t cols, uint8_t pType)
 {
-       if (rows*cols>size) return false;
+       if (rows*cols>size) return FALSE;
        uint8_t rowP=0;
        //assume last row is a parity row and do not test
        for (uint8_t rowNum = 0; rowNum < rows-1; rowNum++) {
                for (uint8_t colNum = 0; colNum < cols; colNum++) {
                        rowP ^= BitStream[(rowNum*cols)+colNum];
                }
-               if (rowP != pType) return false;
+               if (rowP != pType) return FALSE;
+       }
+       return TRUE;
+}
+
+// EM word parity test.
+// 9*5 = 45 bits in total
+// 012345678|r1
+// 012345678|r2
+// 012345678|r3
+// 012345678|r4
+// ------------
+//c012345678| 0  
+//            |- must be zero
+
+bool EMwordparitytest(uint8_t *bits){
+
+       // last row/col parity must be 0
+       if (bits[44] != 0 ) return FALSE;
+       
+       // col parity check
+       uint8_t c1 = bytebits_to_byte(bits, 8) ^ bytebits_to_byte(bits+9, 8) ^ bytebits_to_byte(bits+18, 8) ^ bytebits_to_byte(bits+27, 8);
+       uint8_t c2 = bytebits_to_byte(bits+36, 8);
+       if ( c1 != c2 ) return FALSE;
+
+       // row parity check
+       uint8_t rowP = 0;
+       for ( uint8_t i = 0; i < 36; ++i ) {
+
+               rowP ^= bits[i];
+               if ( i>0 && (i % 9) == 0) {
+                       
+                       if ( rowP != EVEN )     
+                               return FALSE;
+
+                       rowP = 0;
+               }
        }
-       return true;
+       // all checks ok.
+       return TRUE;
 }
 
 
@@ -542,7 +580,6 @@ int CmdEM4x50Read(const char *Cmd) {
        if ( ctmp == 'H' || ctmp == 'h' ) return usage_lf_em4x50_read();        
        return EM4x50Read(Cmd, true);
 }
-
 int CmdEM4x50Write(const char *Cmd){
        uint8_t ctmp = param_getchar(Cmd, 0);
        if ( ctmp == 'H' || ctmp == 'h' ) return usage_lf_em4x50_write();
@@ -557,8 +594,7 @@ int CmdEM4x50Dump(const char *Cmd){
 }
 
 #define EM_PREAMBLE_LEN 6
-// download samples from device
-// and copy them to Graphbuffer
+// download samples from device and copy to Graphbuffer
 bool downloadSamplesEM(){
        
        // 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples)
@@ -571,7 +607,8 @@ bool downloadSamplesEM(){
        setGraphBuf(got, sizeof(got));
        return TRUE;
 }
-//search for given preamble in given BitStream and return success=1 or fail=0 and startIndex
+
+// em_demod 
 bool doPreambleSearch(size_t *startIdx){
        
        // sanity check
@@ -579,26 +616,14 @@ bool doPreambleSearch(size_t *startIdx){
                if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 demodbuffer too small");
                return FALSE;
        }
-       
-       // skip first two 0 bits as they might have been missed in the demod 
-       uint8_t preamble[EM_PREAMBLE_LEN] = {0,0,1,0,1,0};
-       
-       // set size to 15 to only test first 4 positions for the preamble
-       size_t size = (15 > DemodBufferLen) ? DemodBufferLen : 15;
+
+       // set size to 20 to only test first 14 positions for the preamble
+       size_t size = (20 > DemodBufferLen) ? DemodBufferLen : 20;
        *startIdx = 0; 
-       uint8_t found = 0;
-       
-       // em only sends preamble once, so look for it once in the first x bits
-       for (int idx = 0; idx < size - EM_PREAMBLE_LEN; idx++){
-               if (memcmp(DemodBuffer+idx, preamble, EM_PREAMBLE_LEN) == 0){
-                       //first index found
-                       *startIdx = idx;
-                       found = 1;
-                       break;
-               }
-       }
+       // skip first two 0 bits as they might have been missed in the demod
+       uint8_t preamble[EM_PREAMBLE_LEN] = {0,0,1,0,1,0};
        
-       if ( !found) {
+       if ( !preambleSearchEx(DemodBuffer, preamble, EM_PREAMBLE_LEN, &size, startIdx, TRUE)) {
                if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", *startIdx);
                return FALSE;
        } 
@@ -671,30 +696,20 @@ bool detectASK_BI(){
 bool setDemodBufferEM(uint32_t *word, size_t idx){
 
        //test for even parity bits.
-       size_t size = removeParity(DemodBuffer, idx + EM_PREAMBLE_LEN, 9, 0, 44);
-       if (!size) {
-               if (g_debugMode) PrintAndLog("DEBUG: Error -EM Parity not detected");
+       uint8_t parity[45] = {0};
+       memcpy( parity, DemodBuffer, 45);
+       if (!EMwordparitytest(parity) ){
+               PrintAndLog("DEBUG: Error - EM Parity tests failed");
+               return FALSE;
+       }
+       
+       if (!removeParity(DemodBuffer, idx + EM_PREAMBLE_LEN, 9, 0, 44)) {
+               if (g_debugMode) PrintAndLog("DEBUG: Error - EM, failed removing parity");
                return FALSE;
        }
-
-       //todo test last 8 bits for even parity || (xor)
        setDemodBuf(DemodBuffer, 40, 0);
-
        *word = bytebits_to_byteLSBF(DemodBuffer, 32);
-
-       uint8_t lo  = (uint8_t) bytebits_to_byteLSBF(DemodBuffer     , 8);
-       uint8_t lo2 = (uint8_t) bytebits_to_byteLSBF(DemodBuffer +  8, 8);
-       uint8_t hi  = (uint8_t) bytebits_to_byteLSBF(DemodBuffer + 16, 8);
-       uint8_t hi2 = (uint8_t) bytebits_to_byteLSBF(DemodBuffer + 24, 8);
-       uint8_t cs  = (uint8_t) bytebits_to_byteLSBF(DemodBuffer + 32, 8);
-       uint8_t cs2 = lo ^ lo2 ^ hi ^ hi2;
-       if (g_debugMode) PrintAndLog("EM4x05/4x69 : %08X CS: %02X %s"
-                                               , *word
-                                               , cs
-                                               , (cs2==cs) ? "Passed" : "Failed"
-                                       );
-
-       return (cs2==cs);
+       return TRUE;
 }
 
 // FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE 
@@ -766,7 +781,7 @@ int usage_lf_em4x05_write(void) {
 
 int CmdEM4x05Dump(const char *Cmd) {
        uint8_t addr = 0;
-       uint32_t pwd;
+       uint32_t pwd = 0;
        bool usePwd = false;
        uint8_t ctmp = param_getchar(Cmd, 0);
        if ( ctmp == 'H' || ctmp == 'h' ) return usage_lf_em4x05_dump();
@@ -778,12 +793,14 @@ int CmdEM4x05Dump(const char *Cmd) {
                usePwd = true;
 
        int success = 1;
+       PrintAndLog("Addr | data   | ascii");
+       PrintAndLog("-----+--------+------");
        for (; addr < 16; addr++) {
                if (addr == 2) {
                        if (usePwd) {
-                               PrintAndLog("PWD Address %02u | %08X", addr, pwd);
+                               PrintAndLog(" %02u | %08X", addr, pwd);
                        } else {
-                               PrintAndLog("PWD Address 02 | cannot read");
+                               PrintAndLog(" 02 | cannot read");
                        }
                } else {
                        //success &= EM4x05Read(addr, pwd, usePwd);
@@ -880,8 +897,7 @@ int CmdEM4x05Write(const char *Cmd) {
        if (!downloadSamplesEM())
                return -1;
 
-       //todo: check response for 00001010 then write data for write confirmation!
-       
+
        //attempt demod:
        //need 0 bits demoded (after preamble) to verify write cmd
        uint32_t dummy = 0;
Impressum, Datenschutz