Syntax suger

This commit is contained in:
iceman1001 2016-12-14 23:25:28 +01:00
parent 5daad82660
commit 9945a928c7
2 changed files with 44 additions and 111 deletions
client/loclass

View file

@ -280,7 +280,6 @@ int testReversedBitstream()
return 0; return 0;
} }
int testCipherUtils(void) int testCipherUtils(void)
{ {
prnlog("[+] Testing some internals..."); prnlog("[+] Testing some internals...");

View file

@ -35,10 +35,8 @@
* *
* *
****************************************************************************/ ****************************************************************************/
/** /**
From "Dismantling iclass": From "Dismantling iclass":
This section describes in detail the built-in key diversification algorithm of iClass. This section describes in detail the built-in key diversification algorithm of iClass.
Besides the obvious purpose of deriving a card key from a master key, this Besides the obvious purpose of deriving a card key from a master key, this
@ -58,10 +56,7 @@ From "Dismantling iclass":
similar key bytes, which could produce a strong bias in the cipher. Finally, the similar key bytes, which could produce a strong bias in the cipher. Finally, the
output of hash0 is the diversified card key k = k [0] , . . . , k [7] (F 82 ) 8 . output of hash0 is the diversified card key k = k [0] , . . . , k [7] (F 82 ) 8 .
**/ **/
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
@ -220,9 +215,8 @@ uint64_t check(uint64_t z)
void permute(BitstreamIn *p_in, uint64_t z,int l,int r, BitstreamOut* out) void permute(BitstreamIn *p_in, uint64_t z,int l,int r, BitstreamOut* out)
{ {
if(bitsLeft(p_in) == 0) if(bitsLeft(p_in) == 0)
{
return; return;
}
bool pn = tailBit(p_in); bool pn = tailBit(p_in);
if( pn ) // pn = 1 if( pn ) // pn = 1
{ {
@ -238,10 +232,9 @@ void permute(BitstreamIn *p_in, uint64_t z,int l,int r, BitstreamOut* out)
permute(p_in,z,l,r+1,out); permute(p_in,z,l,r+1,out);
} }
} }
void printbegin() void printbegin() {
{ if (debug_print < 2)
if(debug_print <2) return;
return ;
prnlog(" | x| y|z0|z1|z2|z3|z4|z5|z6|z7|"); prnlog(" | x| y|z0|z1|z2|z3|z4|z5|z6|z7|");
} }
@ -249,17 +242,15 @@ void printbegin()
void printState(char* desc, uint64_t c) void printState(char* desc, uint64_t c)
{ {
if(debug_print < 2) if(debug_print < 2)
return ; return;
printf("%s : ", desc); printf("%s : ", desc);
uint8_t x = (c & 0xFF00000000000000 ) >> 56; uint8_t x = (c & 0xFF00000000000000 ) >> 56;
uint8_t y = (c & 0x00FF000000000000 ) >> 48; uint8_t y = (c & 0x00FF000000000000 ) >> 48;
printf(" %02x %02x", x,y); printf(" %02x %02x", x,y);
int i ; int i;
for(i =0 ; i < 8 ; i++) for(i = 0; i < 8; i++)
{
printf(" %02x", getSixBitByte(c,i)); printf(" %02x", getSixBitByte(c,i));
}
printf("\n"); printf("\n");
} }
@ -299,23 +290,19 @@ void hash0(uint64_t c, uint8_t k[8])
_zn = (zn % (63-n)) + n; _zn = (zn % (63-n)) + n;
_zn4 = (zn4 % (64-n)) + n; _zn4 = (zn4 % (64-n)) + n;
pushbackSixBitByte(&zP, _zn,n); pushbackSixBitByte(&zP, _zn,n);
pushbackSixBitByte(&zP, _zn4,n+4); pushbackSixBitByte(&zP, _zn4,n+4);
} }
printState("0|0|z'",zP); printState("0|0|z'",zP);
uint64_t zCaret = check(zP); uint64_t zCaret = check(zP);
printState("0|0|z^",zP); printState("0|0|z^",zP);
uint8_t p = pi[x % 35]; uint8_t p = pi[x % 35];
if(x & 1) //Check if x7 is 1 if(x & 1) //Check if x7 is 1
{
p = ~p; p = ~p;
}
if(debug_print >= 2) prnlog("p:%02x", p); if(debug_print >= 2) prnlog("p:%02x", p);
@ -336,9 +323,8 @@ void hash0(uint64_t c, uint8_t k[8])
int i; int i;
int zerocounter =0 ; int zerocounter =0 ;
for(i =0 ; i < 8 ; i++) for(i = 0; i < 8; i++)
{ {
// the key on index i is first a bit from y // the key on index i is first a bit from y
// then six bits from z, // then six bits from z,
// then a bit from p // then a bit from p
@ -392,7 +378,6 @@ void hash0(uint64_t c, uint8_t k[8])
*/ */
void diversifyKey(uint8_t csn[8], uint8_t key[8], uint8_t div_key[8]) void diversifyKey(uint8_t csn[8], uint8_t key[8], uint8_t div_key[8])
{ {
// Prepare the DES key // Prepare the DES key
des_setkey_enc( &ctx_enc, key); des_setkey_enc( &ctx_enc, key);
@ -408,13 +393,8 @@ void diversifyKey(uint8_t csn[8], uint8_t key[8], uint8_t div_key[8])
hash0(crypt_csn,div_key); hash0(crypt_csn,div_key);
} }
void testPermute() void testPermute()
{ {
uint64_t x = 0; uint64_t x = 0;
pushbackSixBitByte(&x,0x00,0); pushbackSixBitByte(&x,0x00,0);
pushbackSixBitByte(&x,0x01,1); pushbackSixBitByte(&x,0x01,1);
@ -466,7 +446,6 @@ typedef struct
uint8_t div_key[8]; uint8_t div_key[8];
} Testcase; } Testcase;
int testDES(Testcase testcase, des_context ctx_enc, des_context ctx_dec) int testDES(Testcase testcase, des_context ctx_enc, des_context ctx_dec)
{ {
uint8_t des_encrypted_csn[8] = {0}; uint8_t des_encrypted_csn[8] = {0};
@ -504,7 +483,6 @@ int testDES(Testcase testcase, des_context ctx_enc, des_context ctx_dec)
printarr("hash0 ", div_key, 8); printarr("hash0 ", div_key, 8);
printarr("Expected", testcase.div_key, 8); printarr("Expected", testcase.div_key, 8);
retval = 1; retval = 1;
} }
return retval; return retval;
} }
@ -517,27 +495,20 @@ bool des_getParityBitFromKey(uint8_t key)
return !parity; return !parity;
} }
void des_checkParity(uint8_t* key) {
void des_checkParity(uint8_t* key)
{
int i; int i;
int fails =0; int fails = 0;
for(i =0 ; i < 8 ; i++) for(i = 0; i < 8; i++) {
{
bool parity = des_getParityBitFromKey(key[i]); bool parity = des_getParityBitFromKey(key[i]);
if(parity != (key[i] & 0x1)) if (parity != (key[i] & 0x1)) {
{
fails++; fails++;
prnlog("[+] parity1 fail, byte %d [%02x] was %d, should be %d",i,key[i],(key[i] & 0x1),parity); prnlog("[+] parity1 fail, byte %d [%02x] was %d, should be %d", i, key[i], (key[i] & 0x1), parity);
} }
} }
if(fails) if(fails)
{
prnlog("[+] parity fails: %d", fails); prnlog("[+] parity fails: %d", fails);
}else else
{
prnlog("[+] Key syntax is with parity bits inside each byte"); prnlog("[+] Key syntax is with parity bits inside each byte");
}
} }
Testcase testcases[] ={ Testcase testcases[] ={
@ -611,32 +582,24 @@ Testcase testcases[] ={
{{0},{0},{0}} {{0},{0},{0}}
}; };
int testKeyDiversificationWithMasterkeyTestcases() {
int testKeyDiversificationWithMasterkeyTestcases()
{
int error = 0; int error = 0;
int i; int i;
uint8_t empty[8]={0}; uint8_t empty[8]={0};
prnlog("[+} Testing encryption/decryption"); prnlog("[+} Testing encryption/decryption");
for (i = 0; memcmp(testcases+i,empty,8) ; i++) { for (i = 0; memcmp(testcases+i, empty, 8); i++)
error += testDES(testcases[i],ctx_enc, ctx_dec); error += testDES(testcases[i], ctx_enc, ctx_dec);
}
if(error) if (error)
{
prnlog("[+] %d errors occurred (%d testcases)", error, i); prnlog("[+] %d errors occurred (%d testcases)", error, i);
}else else
{
prnlog("[+] Hashing seems to work (%d testcases)", i); prnlog("[+] Hashing seems to work (%d testcases)", i);
}
return error; return error;
} }
void print64bits(char*name, uint64_t val) {
void print64bits(char*name, uint64_t val)
{
printf("%s%08x%08x\n",name,(uint32_t) (val >> 32) ,(uint32_t) (val & 0xFFFFFFFF)); printf("%s%08x%08x\n",name,(uint32_t) (val >> 32) ,(uint32_t) (val & 0xFFFFFFFF));
} }
@ -655,24 +618,19 @@ uint64_t testCryptedCSN(uint64_t crypted_csn, uint64_t expected)
uint64_t resultbyte = x_bytes_to_num(result,8 ); uint64_t resultbyte = x_bytes_to_num(result,8 );
if(debug_print) print64bits(" hash0 " , resultbyte ); if(debug_print) print64bits(" hash0 " , resultbyte );
if(resultbyte != expected ) if(resultbyte != expected ) {
{
if(debug_print) { if(debug_print) {
prnlog("\n[+] FAIL!"); prnlog("\n[+] FAIL!");
print64bits(" expected " , expected ); print64bits(" expected " , expected );
} }
retval = 1; retval = 1;
} else {
}else if (debug_print) prnlog(" [OK]");
{
if(debug_print) prnlog(" [OK]");
} }
return retval; return retval;
} }
int testDES2(uint64_t csn, uint64_t expected) int testDES2(uint64_t csn, uint64_t expected) {
{
uint8_t result[8] = {0}; uint8_t result[8] = {0};
uint8_t input[8] = {0}; uint8_t input[8] = {0};
@ -685,12 +643,10 @@ int testDES2(uint64_t csn, uint64_t expected)
print64bits(" {csn} ", crypt_csn ); print64bits(" {csn} ", crypt_csn );
print64bits(" expected ", expected ); print64bits(" expected ", expected );
if( expected == crypt_csn ) if( expected == crypt_csn ) {
{
prnlog("[+] OK"); prnlog("[+] OK");
return 0; return 0;
}else } else {
{
return 1; return 1;
} }
} }
@ -700,14 +656,10 @@ int testDES2(uint64_t csn, uint64_t expected)
* @brief doTestsWithKnownInputs * @brief doTestsWithKnownInputs
* @return * @return
*/ */
int doTestsWithKnownInputs() int doTestsWithKnownInputs() {
{
// KSel from http://www.proxmark.org/forum/viewtopic.php?pid=10977#p10977 // KSel from http://www.proxmark.org/forum/viewtopic.php?pid=10977#p10977
int errors = 0; int errors = 0;
prnlog("[+] Testing DES encryption"); prnlog("[+] Testing DES encryption");
// uint8_t key[8] = {0x6c,0x8d,0x44,0xf9,0x2a,0x2d,0x01,0xbf};
prnlog("[+] Testing foo");
uint8_t key[8] = {0x6c,0x8d,0x44,0xf9,0x2a,0x2d,0x01,0xbf}; uint8_t key[8] = {0x6c,0x8d,0x44,0xf9,0x2a,0x2d,0x01,0xbf};
des_setkey_enc( &ctx_enc, key); des_setkey_enc( &ctx_enc, key);
@ -725,29 +677,23 @@ int doTestsWithKnownInputs()
errors += testCryptedCSN(0x21ba6565071f9299,0x34e80f88d5cf39ea); errors += testCryptedCSN(0x21ba6565071f9299,0x34e80f88d5cf39ea);
errors += testCryptedCSN(0x14e2adfc5bb7e134,0x6ac90c6508bd9ea3); errors += testCryptedCSN(0x14e2adfc5bb7e134,0x6ac90c6508bd9ea3);
if(errors) if (errors)
{
prnlog("[+] %d errors occurred (9 testcases)", errors); prnlog("[+] %d errors occurred (9 testcases)", errors);
}else else
{
prnlog("[+] Hashing seems to work (9 testcases)" ); prnlog("[+] Hashing seems to work (9 testcases)" );
}
return errors; return errors;
} }
int readKeyFile(uint8_t key[8]) int readKeyFile(uint8_t key[8]) {
{
FILE *f;
int retval = 1; int retval = 1;
f = fopen("iclass_key.bin", "rb"); FILE *f = fopen("iclass_key.bin", "rb");
if (!f) { if (!f)
return 0; return 0;
}
size_t bytes_read = fread(key, sizeof(uint8_t), 8, f); size_t bytes_read = fread(key, sizeof(uint8_t), 8, f);
if ( bytes_read == 1) { if ( bytes_read == 1)
retval = 0; retval = 0;
}
if (f) { if (f) {
fclose(f); fclose(f);
f = NULL; f = NULL;
@ -762,23 +708,20 @@ int doKeyTests(uint8_t debuglevel)
prnlog("[+] Checking if the master key is present (iclass_key.bin)..."); prnlog("[+] Checking if the master key is present (iclass_key.bin)...");
uint8_t key[8] = {0}; uint8_t key[8] = {0};
if(readKeyFile(key)) { if (readKeyFile(key)) {
prnlog("[+] Master key not present, will not be able to do all testcases"); prnlog("[+] Master key not present, will not be able to do all testcases");
} else { } else {
//Test if it's the right key... //Test if it's the right key...
uint8_t i; uint8_t i;
uint8_t j = 0; uint8_t j = 0;
for(i =0 ; i < sizeof(key) ; i++) for (i = 0; i < sizeof(key); i++)
j += key[i]; j += key[i];
if(j != 185) if (j != 185) {
{
prnlog("[+] A key was loaded, but it does not seem to be the correct one. Aborting these tests"); prnlog("[+] A key was loaded, but it does not seem to be the correct one. Aborting these tests");
}else } else {
{
prnlog("[+] Key present"); prnlog("[+] Key present");
prnlog("[+] Checking key parity..."); prnlog("[+] Checking key parity...");
des_checkParity(key); des_checkParity(key);
des_setkey_enc( &ctx_enc, key); des_setkey_enc( &ctx_enc, key);
@ -866,29 +809,20 @@ void modifyKey_put_parity_allover(uint8_t * key, uint8_t* output)
BitstreamOut out = { output, 0,0}; BitstreamOut out = { output, 0,0};
BitstreamIn in = {key, 0,0}; BitstreamIn in = {key, 0,0};
unsigned int bbyte, bbit; unsigned int bbyte, bbit;
for(bbit =0 ; bbit < 56 ; bbit++) for(bbit =0 ; bbit < 56 ; bbit++) {
{ if( bbit > 0 && bbit % 7 == 0) {
if( bbit > 0 && bbit % 7 == 0)
{
pushBit(&out,!parity); pushBit(&out,!parity);
parity = 0; parity = 0;
} }
bool bit = headBit(&in); bool bit = headBit(&in);
pushBit(&out,bit ); pushBit(&out,bit );
parity ^= bit; parity ^= bit;
} }
pushBit(&out, !parity); pushBit(&out, !parity);
if( des_key_check_key_parity(output)) if( des_key_check_key_parity(output))
{
printf("modifyKey_put_parity_allover fail, DES key invalid parity!"); printf("modifyKey_put_parity_allover fail, DES key invalid parity!");
}
} }
*/ */