This commit is contained in:
iceman1001 2020-03-09 16:44:07 +01:00
parent b485461fba
commit c73517b64d
14 changed files with 233 additions and 293 deletions

View file

@ -229,8 +229,7 @@ static uint32_t hitag2_crypt(uint64_t x);
((S >> (C - 3)) & 8) )
static uint32_t hitag2_crypt(uint64_t s)
{
static uint32_t hitag2_crypt(uint64_t s) {
const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
@ -253,8 +252,7 @@ static uint32_t hitag2_crypt(uint64_t s)
* uint32_t serialnum - 32 bit tag serial number
* uint32_t initvector - 32 bit random IV from reader, part of tag authentication
*/
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector)
{
void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) {
// init state, from serial number and lowest 16 bits of shared key
uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum;
@ -338,8 +336,7 @@ void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, ui
* Hitag_State* pstate - in/out, internal cipher state after initialisation
* uint32_t steps - number of bits requested, (capped at 32)
*/
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps)
{
uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) {
uint64_t state = pstate->shiftreg;
uint32_t result = 0;
uint64_t lfsr = pstate->lfsr;
@ -469,8 +466,7 @@ unsigned hitag2_verifytest()
#ifdef UNIT_TEST
int main(int argc, char* argv[])
{
int main(int argc, char *argv[]) {
unsigned pass = hitag2_verifytest();
printf("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL");

View file

@ -34,8 +34,7 @@ struct threaddata {
uint64_t klowerrange;
};
void printbin(uint64_t val)
{
void printbin(uint64_t val) {
int i;
for (i = 0; i < 64; i++) {
@ -48,8 +47,7 @@ void printbin(uint64_t val)
}
}
void printstate(Hitag_State *hstate)
{
void printstate(Hitag_State *hstate) {
printf("shiftreg =\t");
printbin(hstate->shiftreg);
printf("\n");
@ -70,8 +68,7 @@ void printstate(Hitag_State *hstate)
((S >> (C - 3)) & 8) )
static uint32_t hitag2_crypt(uint64_t s)
{
static uint32_t hitag2_crypt(uint64_t s) {
const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
@ -89,8 +86,7 @@ static uint32_t hitag2_crypt(uint64_t s)
// this function is a modification of the filter function f, based heavily
// on the hitag2_crypt function in Rfidler
int fnP(uint64_t klowery)
{
int fnP(uint64_t klowery) {
const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
const uint32_t ht2_function4p = 0xAE83; // 1010 1110 1000 0011
@ -109,8 +105,7 @@ int fnP(uint64_t klowery)
}
// comparison function for sorting/searching Tklower entries
int Tk_cmp(const void *v1, const void *v2)
{
int Tk_cmp(const void *v1, const void *v2) {
const struct Tklower *Tk1 = (struct Tklower *)v1;
const struct Tklower *Tk2 = (struct Tklower *)v2;
@ -148,8 +143,7 @@ int is_kmiddle_badguess(uint64_t z, struct Tklower *Tk, int max, int aR0) {
}
// function to test if a partial key is valid
int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR)
{
int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR) {
uint64_t kupper;
uint64_t key;
Hitag_State hstate;
@ -205,8 +199,7 @@ int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR
// effectively work out candidates for the lower 34 bits of the key.
void *crack(void *d)
{
void *crack(void *d) {
struct threaddata *data = (struct threaddata *)d;
uint64_t uid;
struct nRaR *TnRaR;
@ -331,8 +324,7 @@ void *crack(void *d)
return NULL;
}
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
FILE *fp;
int i;
pthread_t threads[NUM_THREADS];

View file

@ -9,8 +9,7 @@
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
Hitag_State hstate;
FILE *fp;
char *line = NULL;

View file

@ -142,8 +142,7 @@ rtccTime RTC_time; // time structure
rtccDate RTC_date; // date structure
// convert byte-reversed 8 digit hex to unsigned long
unsigned long hexreversetoulong(BYTE *hex)
{
unsigned long hexreversetoulong(BYTE *hex) {
unsigned long ret = 0L;
unsigned int x;
BYTE i;
@ -151,8 +150,7 @@ unsigned long hexreversetoulong(BYTE *hex)
if (strlen(hex) != 8)
return 0L;
for(i= 0 ; i < 4 ; ++i)
{
for (i = 0 ; i < 4 ; ++i) {
if (sscanf(hex, "%2X", &x) != 1)
return 0L;
ret += ((unsigned long) x) << i * 8;
@ -162,8 +160,7 @@ unsigned long hexreversetoulong(BYTE *hex)
}
// convert byte-reversed 12 digit hex to unsigned long
unsigned long long hexreversetoulonglong(BYTE *hex)
{
unsigned long long hexreversetoulonglong(BYTE *hex) {
unsigned long long ret = 0LL;
BYTE tmp[9];

View file

@ -229,8 +229,7 @@ static uint32_t hitag2_crypt(uint64_t x);
((S >> (C - 3)) & 8) )
static uint32_t hitag2_crypt(uint64_t s)
{
static uint32_t hitag2_crypt(uint64_t s) {
const uint32_t ht2_function4a = 0x2C79; // 0010 1100 0111 1001
const uint32_t ht2_function4b = 0x6671; // 0110 0110 0111 0001
const uint32_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0111 1011
@ -253,8 +252,7 @@ static uint32_t hitag2_crypt(uint64_t s)
* uint32_t serialnum - 32 bit tag serial number
* uint32_t initvector - 32 bit random IV from reader, part of tag authentication
*/
void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector)
{
void hitag2_init(Hitag_State *pstate, uint64_t sharedkey, uint32_t serialnum, uint32_t initvector) {
// init state, from serial number and lowest 16 bits of shared key
uint64_t state = ((sharedkey & 0xFFFF) << 32) | serialnum;
@ -338,8 +336,7 @@ void hitag2_init(Hitag_State* pstate, uint64_t sharedkey, uint32_t serialnum, ui
* Hitag_State* pstate - in/out, internal cipher state after initialisation
* uint32_t steps - number of bits requested, (capped at 32)
*/
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps)
{
uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps) {
uint64_t state = pstate->shiftreg;
uint32_t result = 0;
uint64_t lfsr = pstate->lfsr;
@ -469,8 +466,7 @@ unsigned hitag2_verifytest()
#ifdef UNIT_TEST
int main(int argc, char* argv[])
{
int main(int argc, char *argv[]) {
unsigned pass = hitag2_verifytest();
printf("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL");

View file

@ -1,13 +1,11 @@
#include "ht2crack2utils.h"
// writes a value into a buffer as a series of bytes
void writebuf(unsigned char *buf, uint64_t val, unsigned int len)
{
void writebuf(unsigned char *buf, uint64_t val, unsigned int len) {
int i;
char c;
for (i=len-1; i>=0; i--)
{
for (i = len - 1; i >= 0; i--) {
c = val & 0xff;
buf[i] = c;
val = val >> 8;
@ -17,8 +15,7 @@ void writebuf(unsigned char *buf, uint64_t val, unsigned int len)
/* simple hexdump for testing purposes */
void shexdump(unsigned char *data, int data_len)
{
void shexdump(unsigned char *data, int data_len) {
int i;
if (!data || (data_len <= 0)) {
@ -39,8 +36,7 @@ void shexdump(unsigned char *data, int data_len)
void printbin(unsigned char *c)
{
void printbin(unsigned char *c) {
int i, j;
unsigned char x;
@ -60,8 +56,7 @@ void printbin(unsigned char *c)
}
void printbin2(uint64_t val, unsigned int size)
{
void printbin2(uint64_t val, unsigned int size) {
int i;
uint64_t mask = 1;
@ -78,8 +73,7 @@ void printbin2(uint64_t val, unsigned int size)
}
void printstate(Hitag_State *hstate)
{
void printstate(Hitag_State *hstate) {
printf("shiftreg =\t");
printbin2(hstate->shiftreg, 48);
printf("\n");
@ -89,8 +83,7 @@ void printstate(Hitag_State *hstate)
// convert hex char to binary
unsigned char hex2bin(unsigned char c)
{
unsigned char hex2bin(unsigned char c) {
if ((c >= '0') && (c <= '9')) {
return (c - '0');
} else if ((c >= 'a') && (c <= 'f')) {
@ -103,8 +96,7 @@ unsigned char hex2bin(unsigned char c)
}
// return a single bit from a value
int bitn(uint64_t x, int bit)
{
int bitn(uint64_t x, int bit) {
uint64_t bitmask = 1;
bitmask = bitmask << bit;
@ -118,8 +110,7 @@ int bitn(uint64_t x, int bit)
// the sub-function R that rollback depends upon
int fnR(uint64_t x)
{
int fnR(uint64_t x) {
// renumbered bits because my state is 0-47, not 1-48
return (bitn(x, 1) ^ bitn(x, 2) ^ bitn(x, 5) ^ bitn(x, 6) ^ bitn(x, 7) ^
bitn(x, 15) ^ bitn(x, 21) ^ bitn(x, 22) ^ bitn(x, 25) ^ bitn(x, 29) ^ bitn(x, 40) ^
@ -127,8 +118,7 @@ int fnR(uint64_t x)
}
// the rollback function that lets us go backwards in time
void rollback(Hitag_State *hstate, unsigned int steps)
{
void rollback(Hitag_State *hstate, unsigned int steps) {
int i;
for (i = 0; i < steps; i++) {
@ -139,24 +129,20 @@ void rollback(Hitag_State *hstate, unsigned int steps)
// the three filter sub-functions that feed fnf
int fa(unsigned int i)
{
int fa(unsigned int i) {
return bitn(0x2C79, i);
}
int fb(unsigned int i)
{
int fb(unsigned int i) {
return bitn(0x6671, i);
}
int fc(unsigned int i)
{
int fc(unsigned int i) {
return bitn(0x7907287B, i);
}
// the filter function that generates a bit of output from the prng state
int fnf(uint64_t s)
{
int fnf(uint64_t s) {
unsigned int x1, x2, x3, x4, x5, x6;
x1 = (bitn(s, 2) << 0) | (bitn(s, 3) << 1) | (bitn(s, 5) << 2) | (bitn(s, 6) << 3);
@ -171,8 +157,7 @@ int fnf(uint64_t s)
}
// builds the lfsr for the prng (quick calcs for hitag2_nstep())
void buildlfsr(Hitag_State *hstate)
{
void buildlfsr(Hitag_State *hstate) {
uint64_t state = hstate->shiftreg;
uint64_t temp;

View file

@ -93,8 +93,7 @@ uint64_t uid;
int maxtablesize = 800000;
uint64_t supplied_testkey = 0;
void usage()
{
void usage() {
printf("ht2crack4 - K Sheldrake, based on the work of Garcia et al\n\n");
printf("Cracks a HiTag2 key using a small number (4 to 16) of encrypted\n");
printf("nonce and challenge response pairs, using a fast correlation\n");
@ -148,8 +147,7 @@ double pfnc[][16] = {
/* hitag2_crypt works on the post-shifted form of the lfsr; this is the ref in rfidler code */
static uint32_t hitag2_crypt(uint64_t s)
{
static uint32_t hitag2_crypt(uint64_t s) {
uint32_t bitindex;
bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1;
@ -162,8 +160,7 @@ static uint32_t hitag2_crypt(uint64_t s)
}
/* ht2crypt works on the pre-shifted form of the lfsr; this is the ref in the paper */
uint64_t ht2crypt(uint64_t s)
{
uint64_t ht2crypt(uint64_t s) {
uint64_t bitindex;
bitindex = (ht2_function4a >> pickbits2_2(s, 2, 5)) & 1;
@ -177,8 +174,7 @@ uint64_t ht2crypt(uint64_t s)
/* fnL is the feedback function for the reference code */
uint64_t fnL(uint64_t x)
{
uint64_t fnL(uint64_t x) {
return (bitn(x, 0) ^ bitn(x, 2) ^ bitn(x, 3) ^ bitn(x, 6) ^ bitn(x, 7) ^ bitn(x, 8) ^
bitn(x, 16) ^ bitn(x, 22) ^ bitn(x, 23) ^ bitn(x, 26) ^ bitn(x, 30) ^ bitn(x, 41) ^
bitn(x, 42) ^ bitn(x, 43) ^ bitn(x, 46) ^ bitn(x, 47));
@ -191,13 +187,13 @@ uint64_t fnL(uint64_t x)
* this is for pre-shifted lfsr */
unsigned int packed_size[] = { 0, 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,
8, 9, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 13, 14, 14, 15,
15, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 20, 20 };
15, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 19, 19, 20, 20
};
/* f20 is the same as hitag2_crypt except it works on the packed version
* of the state where all 20 relevant bits are squashed together */
uint64_t f20(uint64_t y)
{
uint64_t f20(uint64_t y) {
uint64_t bitindex;
bitindex = (ht2_function4a >> (y & 0xf)) & 1;
@ -211,8 +207,7 @@ uint64_t f20(uint64_t y)
/* packstate packs the relevant bits from LFSR state into 20 bits for pre-shifted lfsr */
uint64_t packstate(uint64_t s)
{
uint64_t packstate(uint64_t s) {
uint64_t packed;
packed = pickbits2_2(s, 2, 5);
@ -226,8 +221,7 @@ uint64_t packstate(uint64_t s)
/* create_guess_table mallocs the tables */
void create_guess_table()
{
void create_guess_table() {
guesses = (struct guess *)malloc(sizeof(struct guess) * maxtablesize);
if (!guesses) {
printf("cannot malloc guess table\n");
@ -238,8 +232,7 @@ void create_guess_table()
/* init the guess table by reading in the encrypted nR,aR values and
* setting the first 2^16 key guesses */
void init_guess_table(char *filename, char *uidstr)
{
void init_guess_table(char *filename, char *uidstr) {
unsigned int i, j;
FILE *fp;
char *buf = NULL;
@ -320,8 +313,7 @@ void init_guess_table(char *filename, char *uidstr)
/* bit_score calculates the ratio of partial states that could generate
* the resulting bit b to all possible states
* size is the number of confirmed bits in the state */
double bit_score(uint64_t s, uint64_t size, uint64_t b)
{
double bit_score(uint64_t s, uint64_t size, uint64_t b) {
uint64_t packed;
uint64_t chopped;
unsigned int n;
@ -404,8 +396,7 @@ double bit_score(uint64_t s, uint64_t size, uint64_t b)
* bit_scores together until no bits remain. bit_scores are
* multiplied by the number of relevant bits in the scored state
* to give weight to more complete states. */
double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize)
{
double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize) {
double sc, sc2;
if ((size == 1) || (kssize == 1)) {
@ -436,8 +427,7 @@ double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize)
/* score_traces runs score for each encrypted nonce */
void score_traces(struct guess *g, unsigned int size)
{
void score_traces(struct guess *g, unsigned int size) {
uint64_t lfsr;
unsigned int i;
double sc;
@ -491,8 +481,7 @@ void score_all_traces(unsigned int size)
*/
/* score_some_traces runs score_traces for every key guess in a section of the table */
void *score_some_traces(void *data)
{
void *score_some_traces(void *data) {
unsigned int i;
struct thread_data *tdata = (struct thread_data *)data;
@ -505,8 +494,7 @@ void *score_some_traces(void *data)
/* score_all_traces runs score_traces for every key guess in the table */
void score_all_traces(unsigned int size)
{
void score_all_traces(unsigned int size) {
pthread_t threads[NUM_THREADS];
void *status;
struct thread_data tdata[NUM_THREADS];
@ -547,8 +535,7 @@ void score_all_traces(unsigned int size)
/* cmp_guess is the comparison function for qsorting the guess table */
int cmp_guess(const void *a, const void *b)
{
int cmp_guess(const void *a, const void *b) {
struct guess *a1 = (struct guess *)a;
struct guess *b1 = (struct guess *)b;
@ -565,8 +552,7 @@ int cmp_guess(const void *a, const void *b)
/* expand all guesses in first half of (sorted) table by
* copying them into the second half and extending the copied
* ones with an extra 1, leaving the first half with an extra 0 */
void expand_guesses(unsigned int halfsize, unsigned int size)
{
void expand_guesses(unsigned int halfsize, unsigned int size) {
unsigned int i, j;
for (i = 0; i < halfsize; i++) {
@ -581,8 +567,7 @@ void expand_guesses(unsigned int halfsize, unsigned int size)
/* checks if the supplied test key is still in the table, which
* is useful when testing different scoring methods */
void check_supplied_testkey(unsigned int size)
{
void check_supplied_testkey(unsigned int size) {
uint64_t partkey;
unsigned int i;
@ -601,8 +586,7 @@ void check_supplied_testkey(unsigned int size)
/* execute_round scores the guesses, sorts them and expands the good half */
void execute_round(unsigned int size)
{
void execute_round(unsigned int size) {
unsigned int halfsize;
// score all the current guesses
@ -630,8 +614,7 @@ void execute_round(unsigned int size)
/* crack is the main cracking algo; it executes the rounds */
void crack()
{
void crack() {
unsigned int i;
uint64_t revkey;
uint64_t foundkey;
@ -649,8 +632,7 @@ void crack()
/* test function to make sure I know how the LFSR works */
void testkey(uint64_t key)
{
void testkey(uint64_t key) {
uint64_t i;
uint64_t b0to31 = 0;
uint64_t ks = 0;
@ -710,8 +692,7 @@ void testkey(uint64_t key)
/* test function to generate test data */
void gen_bitstreams_testks(struct guess *g, uint64_t key)
{
void gen_bitstreams_testks(struct guess *g, uint64_t key) {
unsigned int i, j;
uint64_t nRxorkey, lfsr, ks;
@ -752,8 +733,7 @@ void gen_bitstreams_testks(struct guess *g, uint64_t key)
/* test function */
void test()
{
void test() {
uint64_t lfsr;
uint64_t packed;
@ -774,8 +754,7 @@ void test()
/* check_key tests the potential key against an encrypted nonce, ks pair */
int check_key(uint64_t key, uint64_t enc_nR, uint64_t ks)
{
int check_key(uint64_t key, uint64_t enc_nR, uint64_t ks) {
Hitag_State hstate;
uint64_t bits;
int i;
@ -794,8 +773,7 @@ int check_key(uint64_t key, uint64_t enc_nR, uint64_t ks)
/* start up */
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
unsigned int i;
uint64_t revkey;
uint64_t foundkey;

View file

@ -142,8 +142,7 @@ rtccTime RTC_time; // time structure
rtccDate RTC_date; // date structure
// convert byte-reversed 8 digit hex to unsigned long
unsigned long hexreversetoulong(BYTE *hex)
{
unsigned long hexreversetoulong(BYTE *hex) {
unsigned long ret = 0L;
unsigned int x;
BYTE i;
@ -151,8 +150,7 @@ unsigned long hexreversetoulong(BYTE *hex)
if (strlen(hex) != 8)
return 0L;
for(i= 0 ; i < 4 ; ++i)
{
for (i = 0 ; i < 4 ; ++i) {
if (sscanf(hex, "%2X", &x) != 1)
return 0L;
ret += ((unsigned long) x) << i * 8;
@ -162,8 +160,7 @@ unsigned long hexreversetoulong(BYTE *hex)
}
// convert byte-reversed 12 digit hex to unsigned long
unsigned long long hexreversetoulonglong(BYTE *hex)
{
unsigned long long hexreversetoulonglong(BYTE *hex) {
unsigned long long ret = 0LL;
BYTE tmp[9];