chg: 'analyse hid' moved to 'hf iclass permute' un/permute function is moved.

This commit is contained in:
iceman1001 2018-02-04 17:19:08 +01:00
parent 7c89a191ef
commit debf4e3327
3 changed files with 235 additions and 139 deletions

View file

@ -53,20 +53,7 @@ int usage_analyse_crc(void){
PrintAndLog(" analyse crc 137AF00A0A0D");
return 0;
}
int usage_analyse_hid(void){
PrintAndLog("Permute function from 'heart of darkness' paper.");
PrintAndLog("");
PrintAndLog("Usage: analyse hid [h] <r|f> <bytes>");
PrintAndLog("Options:");
PrintAndLog(" h This help");
PrintAndLog(" r reverse permuted key");
PrintAndLog(" f permute key");
PrintAndLog(" <bytes> input bytes");
PrintAndLog("");
PrintAndLog("Samples:");
PrintAndLog(" analyse hid r 0123456789abcdef");
return 0;
}
int usage_analyse_nuid(void){
PrintAndLog("Generate 4byte NUID from 7byte UID");
PrintAndLog("");
@ -452,9 +439,29 @@ int CmdAnalyseTEASelfTest(const char *Cmd){
return 0;
}
char* pb(uint32_t b) {
static char buf1[33] = {0};
static char buf2[33] = {0};
static char *s;
if (s != buf1)
s = buf1;
else
s = buf2;
memset(s, 0, sizeof(buf1));
uint32_t mask = 0x80000000;
for (uint8_t i=0; i<32;i++) {
s[i] = (mask & b)?'1':'0';
mask >>= 1;
}
return s;
}
int CmdAnalyseA(const char *Cmd){
uint8_t syncBit = 99;
//uint8_t syncBit = 99;
// The start bit is one ore more Sequence Y followed by a Sequence Z (... 11111111 00x11111). We need to distinguish from
// Sequence X followed by Sequence Y followed by Sequence Z (111100x1 11111111 00x11111)
// we therefore look for a ...xx1111 11111111 00x11111xxxxxx... pattern
@ -462,29 +469,102 @@ int CmdAnalyseA(const char *Cmd){
# define SYNC_16BIT 0x4DB2
#define FELICA_STARTBIT_MASK 0x07FFEF80 // mask is 00000111 11111111 11101111 10000000
uint32_t shiftReg = SYNC_16BIT;
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 0)));
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 1)));
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 2)));
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 3)));
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 4)));
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 5)));
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 6)));
printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 7)));
// uint32_t shiftReg = SYNC_16BIT;
// printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 0)));
// printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 1)));
// printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 2)));
// printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 3)));
// printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 4)));
// printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 5)));
// printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 6)));
// printf("reg %04x \n",(shiftReg & (SYNC_16BIT >> 7)));
for ( uint8_t i=0; i<32; i++){
if ((shiftReg & (SYNC_16BIT >> 0)) == SYNC_16BIT >> 0) syncBit = 7;
else if ((shiftReg & (SYNC_16BIT >> 1)) == SYNC_16BIT >> 1) syncBit = 6;
else if ((shiftReg & (SYNC_16BIT >> 2)) == SYNC_16BIT >> 2) syncBit = 5;
else if ((shiftReg & (SYNC_16BIT >> 3)) == SYNC_16BIT >> 3) syncBit = 4;
else if ((shiftReg & (SYNC_16BIT >> 4)) == SYNC_16BIT >> 4) syncBit = 3;
else if ((shiftReg & (SYNC_16BIT >> 5)) == SYNC_16BIT >> 5) syncBit = 2;
else if ((shiftReg & (SYNC_16BIT >> 6)) == SYNC_16BIT >> 6) syncBit = 1;
else if ((shiftReg & (SYNC_16BIT >> 7)) == SYNC_16BIT >> 7) syncBit = 0;
// for ( uint8_t i=0; i<32; i++){
// if ((shiftReg & (SYNC_16BIT >> 0)) == SYNC_16BIT >> 0) syncBit = 7;
// else if ((shiftReg & (SYNC_16BIT >> 1)) == SYNC_16BIT >> 1) syncBit = 6;
// else if ((shiftReg & (SYNC_16BIT >> 2)) == SYNC_16BIT >> 2) syncBit = 5;
// else if ((shiftReg & (SYNC_16BIT >> 3)) == SYNC_16BIT >> 3) syncBit = 4;
// else if ((shiftReg & (SYNC_16BIT >> 4)) == SYNC_16BIT >> 4) syncBit = 3;
// else if ((shiftReg & (SYNC_16BIT >> 5)) == SYNC_16BIT >> 5) syncBit = 2;
// else if ((shiftReg & (SYNC_16BIT >> 6)) == SYNC_16BIT >> 6) syncBit = 1;
// else if ((shiftReg & (SYNC_16BIT >> 7)) == SYNC_16BIT >> 7) syncBit = 0;
printf("ShiftReg is [%04x] | SyncBit is [%u]\n", shiftReg, syncBit);
shiftReg = shiftReg << 1 | ( shiftReg & 0x8000 ) >> 15;
// printf("ShiftReg is [%04x] | SyncBit is [%u]\n", shiftReg, syncBit);
// shiftReg = shiftReg << 1 | ( shiftReg & 0x8000 ) >> 15;
// }
uint8_t a = 0x4D, b = 0;
printf("%X \n", (0xFF >> 2));
//shift in remaining byte, slowly...
// this reverses the input...
for (uint8_t i=0; i<8; i++) {
printf("%u | %02X %s| %02X %s |\n", i, a, pb(a), b, pb(b));
b = (b << 1) | (a & 1);
a >>= 1;
}
uint16_t sync = 0x4DB2;
uint32_t shift = 0x1FFF4D; // typical start pattern.
uint8_t bt = 0x4D; //incoming byte ( b10110010) reflected = b 01001101 == 4D.. So, 4DB2 is opposite.. hm.
// shift in byte.
shift = shift << 8 | reflect8(bt);
// sync position
uint8_t sync_pos = 0;
// finding sync_pos
for ( uint8_t i=0; i<32; i++) {
if ((shift & (sync >> 0)) == sync >> 0) sync_pos = 7;
else if ((shift & (sync >> 1)) == sync >> 1) sync_pos = 6;
else if ((shift & (sync >> 2)) == sync >> 2) sync_pos = 5;
else if ((shift & (sync >> 3)) == sync >> 3) sync_pos = 4;
else if ((shift & (sync >> 4)) == sync >> 4) sync_pos = 3;
else if ((shift & (sync >> 5)) == sync >> 5) sync_pos = 2;
else if ((shift & (sync >> 6)) == sync >> 6) sync_pos = 1;
else if ((shift & (sync >> 7)) == sync >> 7) sync_pos = 0;
printf("shift [%04x] | sync_pos [%u]\n", shift, sync_pos);
shift <<= 1;
}
// shift = 0x1FF4DB;
// shift = 0x3FE9B6;
// printf("%s | %s %c\n", pb((shift & (sync >> 0))), pb(sync >> 0), ((shift & (sync >> 0)) == sync >> 0) ?'Y':'N' );
// printf("%s | %s %c\n", pb((shift & (sync >> 1))), pb(sync >> 1), ((shift & (sync >> 1)) == sync >> 1) ?'Y':'N' );
// printf("%s | %s %c\n", pb((shift & (sync >> 2))), pb(sync >> 2), ((shift & (sync >> 2)) == sync >> 2) ?'Y':'N' );
// printf("%s | %s %c\n", pb((shift & (sync >> 3))), pb(sync >> 3), ((shift & (sync >> 3)) == sync >> 3) ?'Y':'N' );
// printf("%s | %s %c\n", pb((shift & (sync >> 4))), pb(sync >> 4), ((shift & (sync >> 4)) == sync >> 4) ?'Y':'N' );
// printf("%s | %s %c\n", pb((shift & (sync >> 5))), pb(sync >> 5), ((shift & (sync >> 5)) == sync >> 5)?'Y':'N' );
// printf("%s | %s %c\n", pb((shift & (sync >> 6))), pb(sync >> 6), ((shift & (sync >> 6)) == sync >> 6) ?'Y':'N' );
// printf("%s | %s %c\n", pb((shift & (sync >> 7))), pb(sync >> 7), ((shift & (sync >> 7)) == sync >> 7) ?'Y':'N');
// split byte into two parts.
uint8_t offset = 3, n0 = 0, n1 = 0;
uint8_t rev = reflect8(bt);
rev = 0xB2;
for (uint8_t m=0; m<8; m++) {
offset = m;
n0 = (rev & (uint8_t)(~(0xFF >> (8-offset)))) >> offset;
n1 = (n1 << offset) | (rev & (uint8_t)(~(0xFF << offset)));
printf("rev %02X | %02X %s | %02X %s |\n", rev, n0, pb(n0), n1, pb(n1) );
n0 = 0, n1 = 0;
// printf(" (0xFF >> offset) == %s |\n", pb( (0xFF >> offset)) );
//printf("~(0xFF >> (8-offset)) == %s |\n", pb( (uint8_t)(~(0xFF >> (8-offset))) ) );
//printf(" rev & xxx == %s\n\n", pb( (rev & (uint8_t)(~(0xFF << offset))) ));
}
return 0;
// from A -- x bits into B and the rest into C.
for ( uint8_t i=0; i<8; i++){
printf("%u | %02X %s | %02X %s |\n", i, a, pb(a), b, pb(b) );
b = a & (a & (0xFF >> (8-i)));
a >>=1;
}
/*
pm3 --> da hex2bin 4db2 0100110110110010
pm3 --> da hex2bin 926d9 10010010011011011001
@ -717,108 +797,6 @@ uint64_t d2[] = {0x6e442129, 0x8f699195, 0x0000004, 0, 0x00040f0f0305030e};
return 0;
}
static void permute(uint8_t *data, uint8_t len, uint8_t *output){
#define KEY_SIZE 8
if ( len > KEY_SIZE ) {
for(uint8_t m = 0; m < len; m += KEY_SIZE){
permute(data+m, KEY_SIZE, output+m);
}
return;
}
if ( len != KEY_SIZE ) {
printf("wrong key size\n");
return;
}
uint8_t i,j,p, mask;
for( i=0; i < KEY_SIZE; ++i){
p = 0;
mask = 0x80 >> i;
for( j=0; j < KEY_SIZE; ++j){
p >>= 1;
if (data[j] & mask)
p |= 0x80;
}
output[i] = p;
}
}
static void permute_rev(uint8_t *data, uint8_t len, uint8_t *output){
permute(data, len, output);
permute(output, len, data);
permute(data, len, output);
}
static void simple_crc(uint8_t *data, uint8_t len, uint8_t *output){
uint8_t crc = 0;
for( uint8_t i=0; i < len; ++i){
// seventh byte contains the crc.
if ( (i & 0x7) == 0x7 ) {
output[i] = crc ^ 0xFF;
crc = 0;
} else {
output[i] = data[i];
crc ^= data[i];
}
}
}
// DES doesn't use the MSB.
static void shave(uint8_t *data, uint8_t len){
for (uint8_t i=0; i<len; ++i)
data[i] &= 0xFE;
}
static void generate_rev(uint8_t *data, uint8_t len) {
uint8_t *key = calloc(len,1);
printf("input permuted key | %s \n", sprint_hex(data, len));
permute_rev(data, len, key);
printf(" unpermuted key | %s \n", sprint_hex(key, len));
shave(key, len);
printf(" key | %s \n", sprint_hex(key, len));
free(key);
}
static void generate(uint8_t *data, uint8_t len) {
uint8_t *key = calloc(len,1);
uint8_t *pkey = calloc(len,1);
printf(" input key | %s \n", sprint_hex(data, len));
permute(data, len, pkey);
printf(" permuted key | %s \n", sprint_hex(pkey, len));
simple_crc(pkey, len, key );
printf(" CRC'ed key | %s \n", sprint_hex(key, len));
free(key);
free(pkey);
}
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;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0|| cmdp == 'h' || cmdp == 'H') return usage_analyse_hid();
if ( cmdp == 'r' || cmdp == 'R' )
isReverse = true;
param_gethex_ex(Cmd, 1, data, &len);
if ( len%2 ) return usage_analyse_hid();
len >>= 1;
memcpy(key, data, 8);
if ( isReverse ) {
generate_rev(data, len);
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;
}
void generate4bNUID(uint8_t *uid, uint8_t *nuid){
uint16_t crc;
uint8_t b1, b2;
@ -875,7 +853,6 @@ static command_t CommandTable[] = {
{"tea", CmdAnalyseTEASelfTest, 1, "Crypto TEA test"},
{"lfsr", CmdAnalyseLfsr, 1, "LFSR tests"},
{"a", CmdAnalyseA, 1, "num bits test"},
{"hid", CmdAnalyseHid, 1, "Permute function from 'heart of darkness' paper"},
{"nuid", CmdAnalyseNuid, 1, "create NUID from 7byte UID"},
{NULL, NULL, 0, NULL}
};

View file

@ -245,6 +245,20 @@ int usage_hf_iclass_lookup(void) {
PrintAndLog(" hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f default_iclass_keys.dic e");
return 0;
}
int usage_hf_iclass_permutekey(void){
PrintAndLog("Permute function from 'heart of darkness' paper.");
PrintAndLog("");
PrintAndLog("Usage: hf iclass permute [h] <r|f> <bytes>");
PrintAndLog("Options:");
PrintAndLog(" h This help");
PrintAndLog(" r reverse permuted key");
PrintAndLog(" f permute key");
PrintAndLog(" <bytes> input bytes");
PrintAndLog("");
PrintAndLog("Samples:");
PrintAndLog(" hf iclass permute r 0123456789abcdef");
return 0;
}
int xorbits_8(uint8_t val) {
uint8_t res = val ^ (val >> 1); //1st pass
@ -2334,6 +2348,108 @@ void PrintPreCalc(iclass_prekey_t* list, int itemcnt) {
}
}
static void permute(uint8_t *data, uint8_t len, uint8_t *output){
#define KEY_SIZE 8
if ( len > KEY_SIZE ) {
for(uint8_t m = 0; m < len; m += KEY_SIZE){
permute(data+m, KEY_SIZE, output+m);
}
return;
}
if ( len != KEY_SIZE ) {
printf("[!] wrong key size\n");
return;
}
uint8_t i,j,p, mask;
for( i=0; i < KEY_SIZE; ++i){
p = 0;
mask = 0x80 >> i;
for( j=0; j < KEY_SIZE; ++j){
p >>= 1;
if (data[j] & mask)
p |= 0x80;
}
output[i] = p;
}
}
static void permute_rev(uint8_t *data, uint8_t len, uint8_t *output){
permute(data, len, output);
permute(output, len, data);
permute(data, len, output);
}
static void simple_crc(uint8_t *data, uint8_t len, uint8_t *output){
uint8_t crc = 0;
for( uint8_t i=0; i < len; ++i){
// seventh byte contains the crc.
if ( (i & 0x7) == 0x7 ) {
output[i] = crc ^ 0xFF;
crc = 0;
} else {
output[i] = data[i];
crc ^= data[i];
}
}
}
// DES doesn't use the MSB.
static void shave(uint8_t *data, uint8_t len){
for (uint8_t i=0; i<len; ++i)
data[i] &= 0xFE;
}
static void generate_rev(uint8_t *data, uint8_t len) {
uint8_t *key = calloc(len,1);
printf("[+] input permuted key | %s \n", sprint_hex(data, len));
permute_rev(data, len, key);
printf("[+] unpermuted key | %s \n", sprint_hex(key, len));
shave(key, len);
printf("[+] key | %s \n", sprint_hex(key, len));
free(key);
}
static void generate(uint8_t *data, uint8_t len) {
uint8_t *key = calloc(len,1);
uint8_t *pkey = calloc(len,1);
printf("[+] input key | %s \n", sprint_hex(data, len));
permute(data, len, pkey);
printf("[+] permuted key | %s \n", sprint_hex(pkey, len));
simple_crc(pkey, len, key );
printf("[+] CRC'ed key | %s \n", sprint_hex(key, len));
free(key);
free(pkey);
}
int CmdHFiClassPermuteKey(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;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0|| cmdp == 'h' || cmdp == 'H') return usage_hf_iclass_permutekey();
isReverse = ( cmdp == 'r' || cmdp == 'R' );
param_gethex_ex(Cmd, 1, data, &len);
if ( len%2 ) return usage_hf_iclass_permutekey();
len >>= 1;
memcpy(key, data, 8);
if ( isReverse ) {
generate_rev(data, len);
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;
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"calcnewkey", CmdHFiClassCalcNewKey, 1, "[options..] Calc Diversified keys (blocks 3 & 4) to write new keys"},
@ -2347,6 +2463,7 @@ static command_t CommandTable[] = {
{"loclass", CmdHFiClass_loclass, 1, "[options..] Use loclass to perform bruteforce of reader attack dump"},
{"lookup", CmdHFiClassLookUp, 0, "[options..] Uses authentication trace to check for key in dictionary file"},
{"managekeys", CmdHFiClassManageKeys, 1, "[options..] Manage the keys to use with iClass"},
{"permutekey", CmdHFiClassPermuteKey, 0, " Permute function from 'heart of darkness' paper"},
{"readblk", CmdHFiClass_ReadBlock, 0, "[options..] Authenticate and Read iClass block"},
{"reader", CmdHFiClassReader, 0, " Act like an iClass reader"},
{"readtagfile", CmdHFiClassReadTagFile, 1, "[options..] Display Content from tagfile"},

View file

@ -73,7 +73,9 @@ extern int CmdHFiClassSniff(const char *Cmd);
extern int CmdHFiClassSim(const char *Cmd);
extern int CmdHFiClassWriteKeyFile(const char *Cmd);
extern int CmdHFiClass_WriteBlock(const char *Cmd);
extern int CmdHF14AMfChk(const char *Cmd);
extern int CmdHFiClassCheckKeys(const char *Cmd);
extern int CmdHFiClassLookUp(const char *Cmd);
extern int CmdHFiClassPermuteKey(const char *Cmd);
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize);
void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite);