X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/32da0a464e03b39f894ecfe04cee0da114ff0c9a..be67483e63430608982f1c92e02b59d7b4dc65b3:/client/cmdanalyse.c diff --git a/client/cmdanalyse.c b/client/cmdanalyse.c index 3f967ac6..a8deb67f 100644 --- a/client/cmdanalyse.c +++ b/client/cmdanalyse.c @@ -30,9 +30,10 @@ int usage_analyse_checksum(void) { PrintAndLog("The bytes will be added with eachother and than limited with the applied mask"); PrintAndLog("Finally compute ones' complement of the least significant bytes"); PrintAndLog(""); - PrintAndLog("Usage: analyse chksum [h] b m "); + PrintAndLog("Usage: analyse chksum [h] [v] b m "); PrintAndLog("Options:"); PrintAndLog(" h This help"); + PrintAndLog(" v supress header"); PrintAndLog(" b bytes to calc missing XOR in a LCR"); PrintAndLog(" m bit mask to limit the outpuyt"); PrintAndLog(""); @@ -75,7 +76,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 +87,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) { - return ~calcSumCrumbAdd(bytes, len, mask); +static uint16_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { + return (~calcSumCrumbAdd(bytes, len, mask) & 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,27 +99,37 @@ 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){ - return ~calcSumNibbleAdd(bytes, len, mask); +static uint16_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){ + return (~calcSumNibbleAdd(bytes, len, mask) & mask); } -static uint8_t calcSumNibbleXor( 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); + sum ^= CRUMB(bytes[i], 2); + sum ^= CRUMB(bytes[i], 4); + sum ^= CRUMB(bytes[i], 6); + } + sum &= mask; + return sum; +} +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]); sum ^= NIBBLE_HIGH(bytes[i]); } - sum &= 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]; @@ -126,23 +137,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) { - return ~calcSumByteAdd(bytes, len, mask); +static uint16_t calcSumByteAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { + return (~calcSumByteAdd(bytes, len, mask) & 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){ - return ~calcSumByteSub(bytes, len, mask); +static uint16_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){ + return (~calcSumByteSub(bytes, len, mask) & 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]); @@ -151,8 +160,34 @@ 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) { - return ~calcSumNibbleSub(bytes, len, mask); +static uint16_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { + return (~calcSumNibbleSub(bytes, len, mask) & 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 @@ -248,8 +283,9 @@ int CmdAnalyseCHKSUM(const char *Cmd){ uint8_t data[50]; uint8_t cmdp = 0; - uint32_t mask = 0xFF; + uint32_t mask = 0xFFFF; bool errors = false; + bool useHeader = false; int len = 0; memset(data, 0x0, sizeof(data)); @@ -267,6 +303,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(); @@ -280,25 +321,28 @@ int CmdAnalyseCHKSUM(const char *Cmd){ //Validations if(errors) return usage_analyse_checksum(); - PrintAndLog("\nByte Add | 0x%X", calcSumByteAdd(data, len, mask)); - PrintAndLog("Nibble Add | 0x%X", calcSumNibbleAdd(data, len, mask)); - PrintAndLog("Crumb Add | 0x%X", calcSumCrumbAdd(data, len, mask)); - - PrintAndLog("\nByte Subtract | 0x%X", calcSumByteSub(data, len, mask)); - PrintAndLog("Nibble Subtract | 0x%X", calcSumNibbleSub(data, len, mask)); - - PrintAndLog("\nCHECKSUM - One's complement"); - PrintAndLog("Byte Add | 0x%X", calcSumByteAddOnes(data, len, mask)); - PrintAndLog("Nibble Add | 0x%X", calcSumNibbleAddOnes(data, len, mask)); - PrintAndLog("Crumb Add | 0x%X", calcSumCrumbAddOnes(data, len, mask)); - - PrintAndLog("Byte Subtract | 0x%X", calcSumByteSubOnes(data, len, mask)); - PrintAndLog("Nibble Subtract | 0x%X", calcSumNibbleSubOnes(data, len, mask)); - - PrintAndLog("\nXOR"); - PrintAndLog("Byte Xor | 0x%X", calcSumByteXor(data, len, mask)); - PrintAndLog("Nibble Xor | 0x%X", calcSumNibbleXor(data, len, mask)); - + 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) + , calcSumByteSub(data, len, mask) + , calcSumNibbleSub(data, len, mask) + , calcSumByteAddOnes(data, len, mask) + , calcSumNibbleAddOnes(data, len, mask) + , calcSumCrumbAddOnes(data, len, mask) + , calcSumByteSubOnes(data, len, mask) + , calcSumNibbleSubOnes(data, len, mask) + , calcSumByteXor(data, len, mask) + , calcSumNibbleXor(data, len, mask) + , calcSumCrumbXor(data, len, mask) + , calcBSDchecksum8(data, len, mask) + , calcBSDchecksum4(data, len, mask) + ); return 0; } @@ -445,6 +489,9 @@ static void generate(uint8_t *data, uint8_t len) { } int CmdAnalyseHid(const char *Cmd){ + uint8_t key[8] = {0}; + uint8_t key_std_format[8] = {0}; + uint8_t key_iclass_format[8] = {0}; uint8_t data[16] = {0}; bool isReverse = FALSE; int len = 0; @@ -457,12 +504,20 @@ int CmdAnalyseHid(const char *Cmd){ param_gethex_ex(Cmd, 1, data, &len); if ( len%2 ) return usage_analyse_hid(); - len >>= 1; - - if ( isReverse ) + len >>= 1; + + memcpy(key, data, 8); + + if ( isReverse ) { generate_rev(data, len); - else + permutekey_rev(key, key_std_format); + printf(" holiman iclass key | %s \n", sprint_hex(key_std_format, 8)); + } + else { generate(data, len); + permutekey(key, key_iclass_format); + printf(" holiman std key | %s \n", sprint_hex(key_iclass_format, 8)); + } return 0; }