From 62dc7d4a6f72effa3ad22fadbd5c199f496e9471 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Thu, 16 Feb 2017 09:53:47 +0100 Subject: [PATCH] CHG: @marshmellow42 's em4x50 changes ADD: 'analys chksum' - added a BSD styled 4 and 8 bit shift checksum --- client/cmdanalyse.c | 75 ++++++++++++++++++++++++++++++++------------ client/cmdlfem4x.c | 76 +++++++++++++++++++++++++++------------------ 2 files changed, 101 insertions(+), 50 deletions(-) diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 36ef3aa7..3cb1eb71 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -75,7 +75,7 @@ static uint8_t calculateLRC( uint8_t* bytes, uint8_t len) { return LRC; } -static uint8_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { +static uint16_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { uint8_t sum = 0; for (uint8_t i = 0; i < len; i++) { sum += CRUMB(bytes[i], 0); @@ -86,10 +86,10 @@ static uint8_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { sum &= mask; return sum; } -static uint8_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { +static uint16_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { return ~calcSumCrumbAdd(bytes, len, mask); } -static uint8_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { +static uint16_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { uint8_t sum = 0; for (uint8_t i = 0; i < len; i++) { sum += NIBBLE_LOW(bytes[i]); @@ -98,10 +98,10 @@ static uint8_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { sum &= mask; return sum; } -static uint8_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){ +static uint16_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){ return ~calcSumNibbleAdd(bytes, len, mask); } -static uint8_t calcSumCrumbXor( uint8_t* bytes, uint8_t len, uint32_t mask) { +static uint16_t calcSumCrumbXor( uint8_t* bytes, uint8_t len, uint32_t mask) { uint8_t sum = 0; for (uint8_t i = 0; i < len; i++) { sum ^= CRUMB(bytes[i], 0); @@ -112,7 +112,7 @@ static uint8_t calcSumCrumbXor( uint8_t* bytes, uint8_t len, uint32_t mask) { sum &= mask; return sum; } -static uint8_t calcSumNibbleXor( uint8_t* bytes, uint8_t len, uint32_t mask) { +static uint16_t calcSumNibbleXor( uint8_t* bytes, uint8_t len, uint32_t mask) { uint8_t sum = 0; for (uint8_t i = 0; i < len; i++) { sum ^= NIBBLE_LOW(bytes[i]); @@ -121,15 +121,14 @@ static uint8_t calcSumNibbleXor( uint8_t* bytes, uint8_t len, uint32_t mask) { sum &= mask; return sum; } -static uint8_t calcSumByteXor( uint8_t* bytes, uint8_t len, uint32_t mask) { +static uint16_t calcSumByteXor( uint8_t* bytes, uint8_t len, uint32_t mask) { uint8_t sum = 0; for (uint8_t i = 0; i < len; i++) sum ^= bytes[i]; sum &= mask; return sum; } - -static uint8_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { +static uint16_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { uint8_t sum = 0; for (uint8_t i = 0; i < len; i++) sum += bytes[i]; @@ -137,23 +136,21 @@ static uint8_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { return sum; } // Ones complement -static uint8_t calcSumByteAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { +static uint16_t calcSumByteAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { return ~calcSumByteAdd(bytes, len, mask); } - - -static uint8_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) { +static uint16_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) { uint8_t sum = 0; for (uint8_t i = 0; i < len; i++) sum -= bytes[i]; sum &= mask; return sum; } -static uint8_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){ +static uint16_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){ return ~calcSumByteSub(bytes, len, mask); } -static uint8_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) { +static uint16_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) { uint8_t sum = 0; for (uint8_t i = 0; i < len; i++) { sum -= NIBBLE_LOW(bytes[i]); @@ -162,10 +159,38 @@ static uint8_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) { sum &= mask; return sum; } -static uint8_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { +static uint16_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { return ~calcSumNibbleSub(bytes, len, mask); } +// BSD shift checksum 8bit version +static uint16_t calcBSDchecksum8( uint8_t* bytes, uint8_t len, uint32_t mask){ + uint16_t sum = 0; + for(uint8_t i = 0; i < len; i++){ + sum = ((sum & 0xFF) >> 1) | ((sum & 0x1) << 7); // rotate accumulator + sum += bytes[i]; // add next byte + sum &= 0xFF; // + } + sum &= mask; + return sum; +} +// BSD shift checksum 4bit version +static uint16_t calcBSDchecksum4( uint8_t* bytes, uint8_t len, uint32_t mask){ + uint16_t sum = 0; + for(uint8_t i = 0; i < len; i++){ + sum = ((sum & 0xF) >> 1) | ((sum & 0x1) << 3); // rotate accumulator + sum += NIBBLE_HIGH(bytes[i]); // add high nibble + sum &= 0xF; // + sum = ((sum & 0xF) >> 1) | ((sum & 0x1) << 3); // rotate accumulator + sum += NIBBLE_LOW(bytes[i]); // add low nibble + sum &= 0xF; // + } + sum &= mask; + return sum; +} + + + // measuring LFSR maximum length int CmdAnalyseLfsr(const char *Cmd){ @@ -261,6 +286,7 @@ int CmdAnalyseCHKSUM(const char *Cmd){ uint8_t cmdp = 0; uint32_t mask = 0xFFFF; bool errors = false; + bool useHeader = false; int len = 0; memset(data, 0x0, sizeof(data)); @@ -278,6 +304,11 @@ int CmdAnalyseCHKSUM(const char *Cmd){ mask = param_get32ex(Cmd, cmdp+1, 0, 16); cmdp += 2; break; + case 'v': + case 'V': + useHeader = true; + cmdp++; + break; case 'h': case 'H': return usage_analyse_checksum(); @@ -291,10 +322,12 @@ int CmdAnalyseCHKSUM(const char *Cmd){ //Validations if(errors) return usage_analyse_checksum(); - PrintAndLog(" add | sub | add 1's compl | sub 1's compl | xor"); - PrintAndLog("byte nibble crumb | byte nibble | byte nibble cumb | byte nibble | byte nibble cumb"); - PrintAndLog("------------------+-------------+------------------+-----------------+--------------------"); - PrintAndLog("0x%02X 0x%02X 0x%02X | 0x%02X 0x%02X | 0x%02X 0x%02X 0x%02X | 0x%02X 0x%02X | 0x%02X 0x%02X 0x%02X", + if (useHeader) { + PrintAndLog(" add | sub | add 1's compl | sub 1's compl | xor"); + PrintAndLog("byte nibble crumb | byte nibble | byte nibble cumb | byte nibble | byte nibble cumb | BSD"); + PrintAndLog("------------------+-------------+------------------+-----------------+--------------------"); + } + PrintAndLog("0x%X 0x%X 0x%X | 0x%X 0x%X | 0x%X 0x%X 0x%X | 0x%X 0x%X | 0x%X 0x%X 0x%X | 0x%X 0x%X\n", calcSumByteAdd(data, len, mask) , calcSumNibbleAdd(data, len, mask) , calcSumCrumbAdd(data, len, mask) @@ -308,6 +341,8 @@ int CmdAnalyseCHKSUM(const char *Cmd){ , calcSumByteXor(data, len, mask) , calcSumNibbleXor(data, len, mask) , calcSumCrumbXor(data, len, mask) + , calcBSDchecksum8(data, len, mask) + , calcBSDchecksum4(data, len, mask) ); return 0; } diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 2cc03430..839ad57c 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -533,6 +533,9 @@ uint8_t EMpreambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, siz return 0; } +// FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE +// should cover 90% of known used configs +// the rest will need to be manually demoded for now... int demodEM4x05resp(uint8_t bitsNeeded) { int ans = 0; bool demodFound = false; @@ -546,7 +549,6 @@ int demodEM4x05resp(uint8_t bitsNeeded) { ans = FSKrawDemod("0 0", false); if (!ans) { if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: FSK Demod failed"); - //return -1; } else { // set size to 10 to only test first 4 positions for the preamble size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10; @@ -557,7 +559,6 @@ int demodEM4x05resp(uint8_t bitsNeeded) { uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx); if ( errChk == 0) { if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx); - //return -1; } else { //can't test size because the preamble doesn't repeat :( //meaning chances of false positives are high. @@ -565,11 +566,38 @@ int demodEM4x05resp(uint8_t bitsNeeded) { } } } - + // PSK clocks should be easy to detect ( but difficult to demod a non-repeating pattern... ) + if (!demodFound) { ans = GetPskClock("", FALSE, FALSE); if (ans>0) { PrintAndLog("PSK response possibly found, run `data rawd p1` to attempt to demod"); } + } + + // more common than biphase + if (!demodFound) { + DemodBufferLen = 0x00; + // try manchester - NOTE: ST only applies to T55x7 tags. + ans = ASKDemod_ext("0,0,1", false, false, 1, false); + if (!ans) { + if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/Manchester Demod failed"); + } else { + // set size to 10 to only test first 4 positions for the preamble + size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10; + size_t startIdx = 0; + + if (g_debugMode) PrintAndLog("ANS: %d | %u | %u", ans, startIdx, size); + + uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx); + if ( errChk == 0) { + if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx); + } else { + //can't test size because the preamble doesn't repeat :( + //meaning chances of false positives are high. + demodFound = true; + } + } + } if (!demodFound) { DemodBufferLen = 0x00; @@ -599,11 +627,10 @@ int demodEM4x05resp(uint8_t bitsNeeded) { if (!demodFound) { DemodBufferLen = 0x00; - // try manchester - NOTE: ST only applies to T55x7 tags. - ans = ASKDemod_ext("0,0,1", false, false, 1, false); + //try diphase (differential biphase or inverted) + ans = ASKbiphaseDemod("0 1 1", FALSE); if (!ans) { - if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/Manchester Demod failed"); - //return -1; + if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/biphase Demod failed"); } else { // set size to 10 to only test first 4 positions for the preamble size_t size = (10 > DemodBufferLen) ? DemodBufferLen : 10; @@ -614,7 +641,6 @@ int demodEM4x05resp(uint8_t bitsNeeded) { uint8_t errChk = !EMpreambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx); if ( errChk == 0) { if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx); - //return -1; } else { //can't test size because the preamble doesn't repeat :( //meaning chances of false positives are high. @@ -624,8 +650,10 @@ int demodEM4x05resp(uint8_t bitsNeeded) { } if (demodFound && bitsNeeded < DemodBufferLen) { + if (bitsNeeded > 0) { setDemodBuf(DemodBuffer + ans + sizeof(preamble), bitsNeeded, 0); CmdPrintDemodBuff("x"); + } return 1; } return -1; @@ -673,10 +701,9 @@ int CmdReadWord(const char *Cmd) { return -1; } - //need 32 bits for read word - demodEM4x05resp(32); - - return 1; + //attempt demod: + //need 32 bits from a read word + return demodEM4x05resp(32); } int usage_lf_em_write(void) { @@ -739,26 +766,15 @@ int CmdWriteWord(const char *Cmd) { } setGraphBuf(got, sizeof(got)); - int ans = 0; - //bool ST = true; - DemodBufferLen = 0x00; - - //ans = ASKDemod_ext("0 0 1", FALSE, FALSE, 1, &ST); - ans = ASKbiphaseDemod("0 0 1", FALSE); - if (!ans) { - if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305: ASK/Manchester Demod failed"); - return -3; - } + //todo: check response for 00001010 then write data for write confirmation! - //todo: check response for 00001010 then write data for write confirmation! - size_t startIdx = 0, size = DemodBufferLen; - - uint8_t preamble[8] = {0,0,0,0,1,0,1,0}; - if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)){ - if (g_debugMode) PrintAndLog("DEBUG: Error - EM4305 preamble not found :: %d", startIdx); - return -4; + //attempt demod: + //need 0 bits demoded (after preamble) to verify write cmd + int result = demodEM4x05resp(0); + if (result == 1) { + PrintAndLog("Write Verified"); } - PrintAndLog("Write OK"); + return result; return 0; } -- 2.39.2