From: marshmellow42 Date: Wed, 29 Mar 2017 14:02:29 +0000 (-0400) Subject: fix/update removeParity & fix securakey detection X-Git-Tag: v3.0.0~25^2 X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/f2ea55fb3c9946cb36620586b30dd3f302cfed26 fix/update removeParity & fix securakey detection --- diff --git a/client/cmdlfsecurakey.c b/client/cmdlfsecurakey.c index 1d55faf9..1e3899db 100644 --- a/client/cmdlfsecurakey.c +++ b/client/cmdlfsecurakey.c @@ -83,33 +83,37 @@ int CmdSecurakeyDemod(const char *Cmd) { // y = card # // standard wiegand parities. // unknown checksum 11 bits? at the end - uint8_t bits_no_spacer[86]; - memcpy(bits_no_spacer, DemodBuffer + 10, 86); + uint8_t bits_no_spacer[85]; + memcpy(bits_no_spacer, DemodBuffer + 11, 85); // remove marker bits (0's every 9th digit after preamble) (pType = 3 (always 0s)) - size = removeParity(bits_no_spacer, 0, 9, 3, 86); - if ( size != 86-10 ) { + size = removeParity(bits_no_spacer, 0, 9, 3, 85); + if ( size != 85-9 ) { if (g_debugMode) PrintAndLog("DEBUG: Error removeParity: %d", size); return 0; } - uint8_t bitLen = (uint8_t)bytebits_to_byte(DemodBuffer+2, 6); + uint8_t bitLen = (uint8_t)bytebits_to_byte(bits_no_spacer+2, 6); uint32_t fc=0, lWiegand=0, rWiegand=0; - // get FC + if (bitLen > 40) { //securakey's max bitlen is 40 bits... + if (g_debugMode) PrintAndLog("DEBUG: Error bitLen too long: %u", bitLen); + return 0; + } // get left 1/2 wiegand & right 1/2 wiegand (for parity test and wiegand print) - lWiegand = bytebits_to_byte(DemodBuffer + 48 - bitLen, bitLen/2); - rWiegand = bytebits_to_byte(DemodBuffer + 48 - bitLen + bitLen/2, bitLen/2); - fc = bytebits_to_byte(DemodBuffer+49-bitLen, bitLen-2-16); + lWiegand = bytebits_to_byte(bits_no_spacer + 48 - bitLen, bitLen/2); + rWiegand = bytebits_to_byte(bits_no_spacer + 48 - bitLen + bitLen/2, bitLen/2); + // get FC + fc = bytebits_to_byte(bits_no_spacer+49-bitLen, bitLen-2-16); // test bitLen if (bitLen != 26 && bitLen != 32) PrintAndLog("***unknown securakey bitLen - share with forum***"); - uint32_t cardid = bytebits_to_byte(DemodBuffer+8+23, 16); - // test parities - bool parity = evenparity32(lWiegand) && oddparity32(rWiegand); + uint32_t cardid = bytebits_to_byte(bits_no_spacer+8+23, 16); + // test parities - evenparity32 looks to add an even parity returns 0 if already even... + bool parity = !evenparity32(lWiegand) && !oddparity32(rWiegand); - PrintAndLog("Securakey Tag Found--BitLen: %u, Card ID: %u, FC: %X, Raw: %08X%08X%08X", bitLen, cardid, fc, raw1 ,raw2, raw3); + PrintAndLog("Securakey Tag Found--BitLen: %u, Card ID: %u, FC: 0x%X, Raw: %08X%08X%08X", bitLen, cardid, fc, raw1 ,raw2, raw3); if (bitLen <= 32) PrintAndLog("Wiegand: %08X, Parity: %s", (lWiegand<<(bitLen/2)) | rWiegand, parity ? "Passed" : "Failed"); PrintAndLog("\nHow the FC translates to printed FC is unknown"); diff --git a/common/lfdemod.c b/common/lfdemod.c index eb84203e..c56301c0 100644 --- a/common/lfdemod.c +++ b/common/lfdemod.c @@ -35,6 +35,7 @@ #include // for memset, memcmp and size_t #include // for uint_32+ #include // for bool +#include "parity.h" // for parity test //********************************************************************************************** //---------------------------------Utilities Section-------------------------------------------- @@ -82,40 +83,35 @@ int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi // by marshmellow // pass bits to be tested in bits, length bits passed in bitLen, and parity type (even=0 | odd=1) in pType // returns 1 if passed -uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType) { - uint8_t ans = 0; - for (uint8_t i = 0; i < bitLen; i++){ - ans ^= ((bits >> i) & 1); - } - if (g_debugMode) prnt("DEBUG: ans: %d, ptype: %d, bits: %08X",ans,pType,bits); - return (ans == pType); +bool parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType) { + return oddparity32(bits) ^ pType; } // by marshmellow -// takes a array of binary values, start position, length of bits per parity (includes parity bit), -// Parity Type (1 for odd; 0 for even; 2 for Always 1's; 3 for Always 0's), and binary Length (length to run) +// takes a array of binary values, start position, length of bits per parity (includes parity bit - MAX 32), +// Parity Type (1 for odd; 0 for even; 2 for Always 1's; 3 for Always 0's), and binary Length (length to run) size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen) { uint32_t parityWd = 0; - size_t j = 0, bitCnt = 0; + size_t bitCnt = 0; for (int word = 0; word < (bLen); word+=pLen) { for (int bit=0; bit < pLen; bit++) { + if (word+bit >= bLen) break; parityWd = (parityWd << 1) | BitStream[startIdx+word+bit]; - BitStream[j++] = (BitStream[startIdx+word+bit]); + BitStream[bitCnt++] = (BitStream[startIdx+word+bit]); } if (word+pLen > bLen) break; - j--; // overwrite parity with next data + bitCnt--; // overwrite parity with next data // if parity fails then return 0 switch (pType) { - case 3: if (BitStream[j]==1) {return 0;} break; //should be 0 spacer bit - case 2: if (BitStream[j]==0) {return 0;} break; //should be 1 spacer bit + case 3: if (BitStream[bitCnt]==1) {return 0;} break; //should be 0 spacer bit + case 2: if (BitStream[bitCnt]==0) {return 0;} break; //should be 1 spacer bit default: if (parityTest(parityWd, pLen, pType) == 0) {return 0;} break; //test parity } - bitCnt+=(pLen-1); parityWd = 0; } // if we got here then all the parities passed - //return ID start index and size + //return size return bitCnt; } @@ -1687,6 +1683,7 @@ uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_ *hi = (bytebits_to_byte(BitStream, 24)); *lo = ((uint64_t)(bytebits_to_byte(BitStream + 24, 32)) << 32) | (bytebits_to_byte(BitStream + 24 + 32, 32)); } else { + if (g_debugMode) prnt("Error removing parity: %u", *size); return 0; } return 1;