mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-20 20:18:17 +08:00
style
This commit is contained in:
parent
b485461fba
commit
c73517b64d
14 changed files with 233 additions and 293 deletions
|
@ -142,7 +142,7 @@ typedef int rtccDate;
|
|||
|
||||
|
||||
#ifndef __PIC32MX__
|
||||
#define __PIC32MX__
|
||||
#define __PIC32MX__
|
||||
#endif
|
||||
|
||||
#define GetSystemClock() (80000000ul)
|
||||
|
@ -322,7 +322,7 @@ typedef int rtccDate;
|
|||
// spi for SD card
|
||||
#define SD_CARD_DET LATFbits.LATF0
|
||||
#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it
|
||||
// (held LOW by default - cut solder bridge to GND to free pin if required)
|
||||
// (held LOW by default - cut solder bridge to GND to free pin if required)
|
||||
#define SPI_SD SPI_CHANNEL1
|
||||
#define SPI_SD_BUFF SPI1BUF
|
||||
#define SPI_SD_STAT SPI1STATbits
|
||||
|
|
|
@ -229,17 +229,16 @@ 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
|
||||
uint32_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08;
|
||||
bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10;
|
||||
|
||||
DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex);
|
||||
|
@ -253,13 +252,12 @@ 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;
|
||||
|
||||
// mix the initialisation vector and highest 32 bits of the shared key
|
||||
initvector ^= (uint32_t) (sharedkey >> 16);
|
||||
initvector ^= (uint32_t)(sharedkey >> 16);
|
||||
|
||||
// move 16 bits from (IV xor Shared Key) to top of uint64_t state
|
||||
// these will be XORed in turn with output of the crypto function
|
||||
|
@ -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,11 +466,10 @@ 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");
|
||||
printf("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL");
|
||||
|
||||
if (pass) {
|
||||
hitag2_benchtest(10000);
|
||||
|
|
|
@ -159,9 +159,9 @@ typedef struct {
|
|||
uint64_t lfsr; // fast lfsr, used to make software faster
|
||||
} Hitag_State;
|
||||
|
||||
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);
|
||||
|
||||
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps);
|
||||
uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps);
|
||||
|
||||
unsigned int hitag2_benchtest_gen32();
|
||||
unsigned int hitag2_benchtest(uint32_t count);
|
||||
|
|
|
@ -34,11 +34,10 @@ struct threaddata {
|
|||
uint64_t klowerrange;
|
||||
};
|
||||
|
||||
void printbin(uint64_t val)
|
||||
{
|
||||
void printbin(uint64_t val) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<64; i++) {
|
||||
for (i = 0; i < 64; i++) {
|
||||
if (val & 0x8000000000000000) {
|
||||
printf("1");
|
||||
} else {
|
||||
|
@ -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,17 +68,16 @@ 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
|
||||
uint32_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08;
|
||||
bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10;
|
||||
|
||||
return (ht2_function5c >> bitindex) & 1;
|
||||
|
@ -89,17 +86,16 @@ 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
|
||||
uint32_t i;
|
||||
|
||||
i = (ht2_function4a >> pickbits2_2 (klowery, 2, 5)) & 1;
|
||||
i |= ((ht2_function4b << 1) >> pickbits1_1_2 (klowery, 8, 12, 14)) & 0x02;
|
||||
i |= ((ht2_function4b << 2) >> pickbits1x4 (klowery, 17, 21, 23, 26)) & 0x04;
|
||||
i |= ((ht2_function4b << 3) >> pickbits2_1_1 (klowery, 28, 31, 33)) & 0x08;
|
||||
i = (ht2_function4a >> pickbits2_2(klowery, 2, 5)) & 1;
|
||||
i |= ((ht2_function4b << 1) >> pickbits1_1_2(klowery, 8, 12, 14)) & 0x02;
|
||||
i |= ((ht2_function4b << 2) >> pickbits1x4(klowery, 17, 21, 23, 26)) & 0x04;
|
||||
i |= ((ht2_function4b << 3) >> pickbits2_1_1(klowery, 28, 31, 33)) & 0x08;
|
||||
|
||||
// modified to use reference implementation approach
|
||||
// orig fc table is 0x7907287B = 0111 1001 0000 0111 0010 1000 0111 1011
|
||||
|
@ -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;
|
||||
|
@ -162,7 +156,7 @@ int testkey(uint64_t *out, uint64_t uid, uint64_t pkey, uint64_t nR, uint64_t aR
|
|||
normaR = ((revaR >> 24) | ((revaR >> 8) & 0xff00) | ((revaR << 8) & 0xff0000) | (revaR << 24));
|
||||
|
||||
// search for remaining 14 bits
|
||||
for (kupper=0; kupper < 0x3fff; kupper++) {
|
||||
for (kupper = 0; kupper < 0x3fff; kupper++) {
|
||||
key = (kupper << 34) | pkey;
|
||||
hitag2_init(&hstate, key, uid, nR);
|
||||
b = hitag2_nstep(&hstate, 32);
|
||||
|
@ -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;
|
||||
|
@ -249,11 +242,11 @@ void *crack(void *d)
|
|||
}
|
||||
|
||||
// find keys
|
||||
for (klower=data->klowerstart; klower < (data->klowerstart + data->klowerrange); klower++) {
|
||||
for (klower = data->klowerstart; klower < (data->klowerstart + data->klowerrange); klower++) {
|
||||
printf("trying klower = 0x%05lx\n", klower);
|
||||
// build table
|
||||
count = 0;
|
||||
for (y=0; y<0x40000; y++) {
|
||||
for (y = 0; y < 0x40000; y++) {
|
||||
// create klowery
|
||||
klowery = (y << 16) | klower;
|
||||
// check for cases where right most bit of fc doesn't matter
|
||||
|
@ -268,9 +261,9 @@ void *crack(void *d)
|
|||
// insert y into shiftreg and extract keystream, reversed order
|
||||
b = 0;
|
||||
ytmp = y;
|
||||
for (j=0; j<2; j++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
hstate.shiftreg = hstate.shiftreg | ((ytmp & 0xffff) << 48);
|
||||
for (i=0; i<16; i++) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
hstate.shiftreg = hstate.shiftreg >> 1;
|
||||
bit = hitag2_crypt(hstate.shiftreg);
|
||||
b = (b >> 1) | (bit << 31);
|
||||
|
@ -295,11 +288,11 @@ void *crack(void *d)
|
|||
qsort(Tk, count, sizeof(struct Tklower), Tk_cmp);
|
||||
|
||||
// look for matches
|
||||
for (kmiddle=0; kmiddle<0x40000; kmiddle++) {
|
||||
for (kmiddle = 0; kmiddle < 0x40000; kmiddle++) {
|
||||
// loop over nRaR pairs
|
||||
badguess = 0;
|
||||
found = 0;
|
||||
for (i=0; (i<numnrar) && (!badguess); i++) {
|
||||
for (i = 0; (i < numnrar) && (!badguess); i++) {
|
||||
z = kmiddle ^ (TnRaR[i].nR & 0x3ffff);
|
||||
ret = is_kmiddle_badguess(z, Tk, count, TnRaR[i].aR & 0x1);
|
||||
if (ret == 1) {
|
||||
|
@ -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];
|
||||
|
@ -401,8 +393,8 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
*buft2 = 0x00;
|
||||
if (!strncmp(buf, "0x", 2)) {
|
||||
TnRaR[numnrar].nR = rev32(hexreversetoulong(buf+2));
|
||||
TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1+2));
|
||||
TnRaR[numnrar].nR = rev32(hexreversetoulong(buf + 2));
|
||||
TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1 + 2));
|
||||
} else {
|
||||
TnRaR[numnrar].nR = rev32(hexreversetoulong(buf));
|
||||
TnRaR[numnrar].aR = rev32(hexreversetoulong(buft1));
|
||||
|
@ -423,7 +415,7 @@ int main(int argc, char *argv[])
|
|||
exit(1);
|
||||
}
|
||||
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
for (i = 0; i < NUM_THREADS; i++) {
|
||||
tdata[i].uid = uid;
|
||||
tdata[i].TnRaR = TnRaR;
|
||||
tdata[i].numnrar = numnrar;
|
||||
|
@ -437,7 +429,7 @@ int main(int argc, char *argv[])
|
|||
crack(tdata);
|
||||
} else {
|
||||
// run full threaded mode
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
for (i = 0; i < NUM_THREADS; i++) {
|
||||
if (pthread_create(&(threads[i]), NULL, crack, (void *)(tdata + i))) {
|
||||
printf("cannot start thread %d\n", i);
|
||||
exit(1);
|
||||
|
@ -446,7 +438,7 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
// wait for threads to finish
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
for (i = 0; i < NUM_THREADS; i++) {
|
||||
if (pthread_join(threads[i], &status)) {
|
||||
printf("cannot join thread %d\n", i);
|
||||
exit(1);
|
||||
|
|
|
@ -9,8 +9,7 @@
|
|||
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int main(int argc, char *argv[]) {
|
||||
Hitag_State hstate;
|
||||
FILE *fp;
|
||||
char *line = NULL;
|
||||
|
@ -51,7 +50,7 @@ int main(int argc, char *argv[])
|
|||
ar = strchr(line, ' ');
|
||||
*ar = 0x00;
|
||||
ar++;
|
||||
ar[strlen(ar)-1] = 0x00;
|
||||
ar[strlen(ar) - 1] = 0x00;
|
||||
if (!strncmp(line, "0x", 2)) {
|
||||
nr = line + 2;
|
||||
} else {
|
||||
|
|
|
@ -142,18 +142,16 @@ 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 ret= 0L;
|
||||
unsigned long hexreversetoulong(BYTE *hex) {
|
||||
unsigned long ret = 0L;
|
||||
unsigned int x;
|
||||
BYTE i;
|
||||
|
||||
if(strlen(hex) != 8)
|
||||
if (strlen(hex) != 8)
|
||||
return 0L;
|
||||
|
||||
for(i= 0 ; i < 4 ; ++i)
|
||||
{
|
||||
if(sscanf(hex, "%2X", &x) != 1)
|
||||
for (i = 0 ; i < 4 ; ++i) {
|
||||
if (sscanf(hex, "%2X", &x) != 1)
|
||||
return 0L;
|
||||
ret += ((unsigned long) x) << i * 8;
|
||||
hex += 2;
|
||||
|
@ -162,18 +160,17 @@ unsigned long hexreversetoulong(BYTE *hex)
|
|||
}
|
||||
|
||||
// convert byte-reversed 12 digit hex to unsigned long
|
||||
unsigned long long hexreversetoulonglong(BYTE *hex)
|
||||
{
|
||||
unsigned long long ret= 0LL;
|
||||
unsigned long long hexreversetoulonglong(BYTE *hex) {
|
||||
unsigned long long ret = 0LL;
|
||||
BYTE tmp[9];
|
||||
|
||||
// this may seem an odd way to do it, but weird compiler issues were
|
||||
// breaking direct conversion!
|
||||
|
||||
tmp[8]= '\0';
|
||||
tmp[8] = '\0';
|
||||
memset(tmp + 4, '0', 4);
|
||||
memcpy(tmp, hex + 8, 4);
|
||||
ret= hexreversetoulong(tmp);
|
||||
ret = hexreversetoulong(tmp);
|
||||
ret <<= 32;
|
||||
memcpy(tmp, hex, 8);
|
||||
ret += hexreversetoulong(tmp);
|
||||
|
|
|
@ -142,7 +142,7 @@ typedef int rtccDate;
|
|||
|
||||
|
||||
#ifndef __PIC32MX__
|
||||
#define __PIC32MX__
|
||||
#define __PIC32MX__
|
||||
#endif
|
||||
|
||||
#define GetSystemClock() (80000000ul)
|
||||
|
@ -322,7 +322,7 @@ typedef int rtccDate;
|
|||
// spi for SD card
|
||||
#define SD_CARD_DET LATFbits.LATF0
|
||||
#define SD_CARD_WE LATFbits.LATF1 // write enable - unused for microsd but allocated anyway as library checks it
|
||||
// (held LOW by default - cut solder bridge to GND to free pin if required)
|
||||
// (held LOW by default - cut solder bridge to GND to free pin if required)
|
||||
#define SPI_SD SPI_CHANNEL1
|
||||
#define SPI_SD_BUFF SPI1BUF
|
||||
#define SPI_SD_STAT SPI1STATbits
|
||||
|
|
|
@ -229,17 +229,16 @@ 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
|
||||
uint32_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> pickbits2_2 (s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08;
|
||||
bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10;
|
||||
|
||||
DEBUG_PRINTF("hitag2_crypt bitindex = %02x\n", bitindex);
|
||||
|
@ -253,13 +252,12 @@ 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;
|
||||
|
||||
// mix the initialisation vector and highest 32 bits of the shared key
|
||||
initvector ^= (uint32_t) (sharedkey >> 16);
|
||||
initvector ^= (uint32_t)(sharedkey >> 16);
|
||||
|
||||
// move 16 bits from (IV xor Shared Key) to top of uint64_t state
|
||||
// these will be XORed in turn with output of the crypto function
|
||||
|
@ -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,11 +466,10 @@ 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");
|
||||
printf("Crypto Verify test = %s\n\n", pass ? "PASS" : "FAIL");
|
||||
|
||||
if (pass) {
|
||||
hitag2_benchtest(10000);
|
||||
|
|
|
@ -159,9 +159,9 @@ typedef struct {
|
|||
uint64_t lfsr; // fast lfsr, used to make software faster
|
||||
} Hitag_State;
|
||||
|
||||
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);
|
||||
|
||||
uint32_t hitag2_nstep(Hitag_State* pstate, uint32_t steps);
|
||||
uint32_t hitag2_nstep(Hitag_State *pstate, uint32_t steps);
|
||||
|
||||
unsigned int hitag2_benchtest_gen32();
|
||||
unsigned int hitag2_benchtest(uint32_t count);
|
||||
|
|
|
@ -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)) {
|
||||
|
@ -28,7 +25,7 @@ void shexdump(unsigned char *data, int data_len)
|
|||
|
||||
printf("Hexdump from %p:\n", data);
|
||||
|
||||
for (i=0; i<data_len; i++) {
|
||||
for (i = 0; i < data_len; i++) {
|
||||
if ((i % HEX_PER_ROW) == 0) {
|
||||
printf("\n0x%04x: ", i);
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -49,9 +45,9 @@ void printbin(unsigned char *c)
|
|||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<6; i++) {
|
||||
for (i = 0; i < 6; i++) {
|
||||
x = c[i];
|
||||
for (j=0; j<8; j++) {
|
||||
for (j = 0; j < 8; j++) {
|
||||
printf("%d", (x & 0x80) >> 7);
|
||||
x = x << 1;
|
||||
}
|
||||
|
@ -60,14 +56,13 @@ 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;
|
||||
|
||||
mask = mask << (size - 1);
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
for (i = 0; i < size; i++) {
|
||||
if (val & mask) {
|
||||
printf("1");
|
||||
} else {
|
||||
|
@ -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,11 +118,10 @@ 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++) {
|
||||
for (i = 0; i < steps; i++) {
|
||||
hstate->shiftreg = ((hstate->shiftreg << 1) & 0xffffffffffff) | fnR(hstate->shiftreg);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
@ -130,46 +129,44 @@ const uint64_t ht2_function5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 011
|
|||
* a known least-sig pattern. first index is num bits in known part, second is the
|
||||
* bit pattern of the known part. */
|
||||
double pfna[][8] = {
|
||||
{0.50000, 0.50000, },
|
||||
{0.50000, 0.50000, 0.50000, 0.50000, },
|
||||
{0.50000, 0.00000, 0.50000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, },
|
||||
{0.50000, 0.50000, },
|
||||
{0.50000, 0.50000, 0.50000, 0.50000, },
|
||||
{0.50000, 0.00000, 0.50000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, },
|
||||
};
|
||||
double pfnb[][8] = {
|
||||
{0.62500, 0.37500, },
|
||||
{0.50000, 0.75000, 0.75000, 0.00000, },
|
||||
{0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 1.00000, 1.00000, 0.00000, },
|
||||
{0.62500, 0.37500, },
|
||||
{0.50000, 0.75000, 0.75000, 0.00000, },
|
||||
{0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 1.00000, 1.00000, 0.00000, },
|
||||
};
|
||||
double pfnc[][16] = {
|
||||
{0.50000, 0.50000, },
|
||||
{0.62500, 0.62500, 0.37500, 0.37500, },
|
||||
{0.75000, 0.50000, 0.25000, 0.75000, 0.50000, 0.75000, 0.50000, 0.00000, },
|
||||
{1.00000, 1.00000, 0.50000, 0.50000, 0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 0.00000, 0.00000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, },
|
||||
{0.50000, 0.50000, },
|
||||
{0.62500, 0.62500, 0.37500, 0.37500, },
|
||||
{0.75000, 0.50000, 0.25000, 0.75000, 0.50000, 0.75000, 0.50000, 0.00000, },
|
||||
{1.00000, 1.00000, 0.50000, 0.50000, 0.50000, 0.50000, 0.50000, 0.00000, 0.50000, 0.00000, 0.00000, 1.00000, 0.50000, 1.00000, 0.50000, 0.00000, },
|
||||
};
|
||||
|
||||
|
||||
/* 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;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 27, 30, 32)) & 0x08;
|
||||
bitindex = (ht2_function4a >> pickbits2_2(s, 1, 4)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 7, 11, 13)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 16, 20, 22, 25)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 27, 30, 32)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 33, 42, 45)) & 0x10;
|
||||
|
||||
return (ht2_function5c >> bitindex) & 1;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2 (s, 8, 12, 14)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4 (s, 17, 21, 23, 26)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1 (s, 28, 31, 33)) & 0x08;
|
||||
bitindex = (ht2_function4a >> pickbits2_2(s, 2, 5)) & 1;
|
||||
bitindex |= ((ht2_function4b << 1) >> pickbits1_1_2(s, 8, 12, 14)) & 0x02;
|
||||
bitindex |= ((ht2_function4b << 2) >> pickbits1x4(s, 17, 21, 23, 26)) & 0x04;
|
||||
bitindex |= ((ht2_function4b << 3) >> pickbits2_1_1(s, 28, 31, 33)) & 0x08;
|
||||
bitindex |= ((ht2_function4a << 4) >> pickbits1_2_1(s, 34, 43, 46)) & 0x10;
|
||||
|
||||
return (ht2_function5c >> bitindex) & 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,14 +207,13 @@ 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);
|
||||
packed |= (pickbits1_1_2 (s, 8, 12, 14) << 4);
|
||||
packed |= (pickbits1x4 (s, 17, 21, 23, 26) << 8);
|
||||
packed |= (pickbits2_1_1 (s, 28, 31, 33) << 12);
|
||||
packed = pickbits2_2(s, 2, 5);
|
||||
packed |= (pickbits1_1_2(s, 8, 12, 14) << 4);
|
||||
packed |= (pickbits1x4(s, 17, 21, 23, 26) << 8);
|
||||
packed |= (pickbits2_1_1(s, 28, 31, 33) << 12);
|
||||
packed |= (pickbits1_2_1(s, 34, 43, 46) << 16);
|
||||
|
||||
return packed;
|
||||
|
@ -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;
|
||||
|
@ -289,8 +282,8 @@ void init_guess_table(char *filename, char *uidstr)
|
|||
}
|
||||
*buft2 = 0x00;
|
||||
if (!strncmp(buf, "0x", 2)) {
|
||||
nonces[num_nRaR].enc_nR = rev32(hexreversetoulong(buf+2));
|
||||
nonces[num_nRaR].ks = rev32(hexreversetoulong(buft1+2)) ^ 0xffffffff;
|
||||
nonces[num_nRaR].enc_nR = rev32(hexreversetoulong(buf + 2));
|
||||
nonces[num_nRaR].ks = rev32(hexreversetoulong(buft1 + 2)) ^ 0xffffffff;
|
||||
} else {
|
||||
nonces[num_nRaR].enc_nR = rev32(hexreversetoulong(buf));
|
||||
nonces[num_nRaR].ks = rev32(hexreversetoulong(buft1)) ^ 0xffffffff;
|
||||
|
@ -305,10 +298,10 @@ void init_guess_table(char *filename, char *uidstr)
|
|||
|
||||
// set key and copy in enc_nR and ks values
|
||||
// set score to -1.0 to distinguish them from 0 scores
|
||||
for (i=0; i<65536; i++) {
|
||||
for (i = 0; i < 65536; i++) {
|
||||
guesses[i].key = i;
|
||||
guesses[i].score = -1.0;
|
||||
for (j=0; j<num_nRaR; j++) {
|
||||
for (j = 0; j < num_nRaR; j++) {
|
||||
guesses[i].b0to31[j] = 0;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -353,7 +345,7 @@ double bit_score(uint64_t s, uint64_t size, uint64_t b)
|
|||
// incomplete first nibble
|
||||
// get probability of getting a 1 from first nibble
|
||||
// and by subtraction from 1, prob of getting a 0
|
||||
nibprob1 = pfna[n-1][packed];
|
||||
nibprob1 = pfna[n - 1][packed];
|
||||
nibprob0 = 1.0 - nibprob1;
|
||||
|
||||
// calc fnc prob as sum of probs of nib 1 producing a 1 and 0
|
||||
|
@ -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;
|
||||
|
@ -448,7 +438,7 @@ void score_traces(struct guess *g, unsigned int size)
|
|||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<num_nRaR; i++) {
|
||||
for (i = 0; i < num_nRaR; i++) {
|
||||
// calc next b
|
||||
// create lfsr - lower 32 bits is uid, upper 16 bits are lower 16 bits of key
|
||||
// then shift by size - 16, insert upper key XOR enc_nonce XOR bitstream,
|
||||
|
@ -491,12 +481,11 @@ 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;
|
||||
|
||||
for (i=tdata->start; i<tdata->end; i++) {
|
||||
for (i = tdata->start; i < tdata->end; i++) {
|
||||
score_traces(&(guesses[i]), tdata->size);
|
||||
}
|
||||
|
||||
|
@ -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];
|
||||
|
@ -516,9 +504,9 @@ void score_all_traces(unsigned int size)
|
|||
chunk_size = num_guesses / NUM_THREADS;
|
||||
|
||||
// create thread data
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
for (i = 0; i < NUM_THREADS; i++) {
|
||||
tdata[i].start = i * chunk_size;
|
||||
tdata[i].end = (i+1) * chunk_size;
|
||||
tdata[i].end = (i + 1) * chunk_size;
|
||||
tdata[i].size = size;
|
||||
}
|
||||
|
||||
|
@ -526,7 +514,7 @@ void score_all_traces(unsigned int size)
|
|||
tdata[NUM_THREADS - 1].end = num_guesses;
|
||||
|
||||
// start the threads
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
for (i = 0; i < NUM_THREADS; i++) {
|
||||
if (pthread_create(&(threads[i]), NULL, score_some_traces, (void *)(tdata + i))) {
|
||||
printf("cannot start thread %d\n", i);
|
||||
exit(1);
|
||||
|
@ -534,7 +522,7 @@ void score_all_traces(unsigned int size)
|
|||
}
|
||||
|
||||
// wait for threads to end
|
||||
for (i=0; i<NUM_THREADS; i++) {
|
||||
for (i = 0; i < NUM_THREADS; i++) {
|
||||
if (pthread_join(threads[i], &status)) {
|
||||
printf("cannot join thread %d\n", i);
|
||||
exit(1);
|
||||
|
@ -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,15 +552,14 @@ 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++) {
|
||||
guesses[i+halfsize].key = guesses[i].key | (1l << size);
|
||||
guesses[i+halfsize].score = guesses[i].score;
|
||||
for (j=0; j<num_nRaR; j++) {
|
||||
guesses[i+halfsize].b0to31[j] = guesses[i].b0to31[j];
|
||||
for (i = 0; i < halfsize; i++) {
|
||||
guesses[i + halfsize].key = guesses[i].key | (1l << size);
|
||||
guesses[i + halfsize].score = guesses[i].score;
|
||||
for (j = 0; j < num_nRaR; j++) {
|
||||
guesses[i + halfsize].b0to31[j] = guesses[i].b0to31[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -581,14 +567,13 @@ 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;
|
||||
|
||||
partkey = supplied_testkey & ((1l << size) - 1);
|
||||
|
||||
for (i=0; i<num_guesses; i++) {
|
||||
for (i = 0; i < num_guesses; i++) {
|
||||
if (guesses[i].key == partkey) {
|
||||
fprintf(stderr, " supplied test key score = %1.10f, position = %d\n", guesses[i].score, i);
|
||||
return;
|
||||
|
@ -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,14 +614,13 @@ 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;
|
||||
|
||||
for (i=16; i<=48; i++) {
|
||||
fprintf(stderr, "round %2d, size=%2d\n", i-16, i);
|
||||
for (i = 16; i <= 48; i++) {
|
||||
fprintf(stderr, "round %2d, size=%2d\n", i - 16, i);
|
||||
execute_round(i);
|
||||
|
||||
// print some metrics
|
||||
|
@ -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;
|
||||
|
@ -663,7 +645,7 @@ void testkey(uint64_t key)
|
|||
printf("after init with key, uid, nR:\n");
|
||||
printstate(&hstate);
|
||||
b0to31 = 0;
|
||||
for (i=0; i<32; i++) {
|
||||
for (i = 0; i < 32; i++) {
|
||||
b0to31 = (b0to31 >> 1) | (hitag2_nstep(&hstate, 1) << 31);
|
||||
}
|
||||
printf("ks = 0x%08" PRIx64 ", enc_aR = 0x%08" PRIx64 ", aR = 0x%08" PRIx64 "\n", b0to31, nonces[0].ks ^ 0xffffffff, nonces[0].ks ^ 0xffffffff ^ b0to31);
|
||||
|
@ -679,7 +661,7 @@ void testkey(uint64_t key)
|
|||
// xor upper part of key with encrypted nonce
|
||||
nRxorkey = nonces[0].enc_nR ^ (key >> 16);
|
||||
// insert keyupper xor encrypted nonce xor ks
|
||||
for (i=0; i<32; i++) {
|
||||
for (i = 0; i < 32; i++) {
|
||||
// store ks - when done, the first ks bit will be bit 0 and the last will be bit 31
|
||||
b0to31 = (b0to31 >> 1) | (ht2crypt(lfsr) << 31);
|
||||
// insert new bit
|
||||
|
@ -693,7 +675,7 @@ void testkey(uint64_t key)
|
|||
printf("\n");
|
||||
|
||||
// iterate lfsr with fnL, extracting ks
|
||||
for (i=0; i<32; i++) {
|
||||
for (i = 0; i < 32; i++) {
|
||||
// store ks - when done, the first ks bit will be bit 0 and the last will be bit 31
|
||||
ks = (ks >> 1) | (ht2crypt(lfsr) << 31);
|
||||
// insert new bit
|
||||
|
@ -710,12 +692,11 @@ 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;
|
||||
|
||||
for (j=0; j<num_nRaR; j++) {
|
||||
for (j = 0; j < num_nRaR; j++) {
|
||||
|
||||
// build initial lfsr
|
||||
lfsr = uid | ((key & 0xffff) << 32);
|
||||
|
@ -723,7 +704,7 @@ void gen_bitstreams_testks(struct guess *g, uint64_t key)
|
|||
// xor upper part of key with encrypted nonce
|
||||
nRxorkey = nonces[j].enc_nR ^ (key >> 16);
|
||||
// insert keyupper xor encrypted nonce xor ks
|
||||
for (i=0; i<32; i++) {
|
||||
for (i = 0; i < 32; i++) {
|
||||
// store ks - when done, the first ks bit will be bit 0 and the last will be bit 31
|
||||
g->b0to31[j] = (g->b0to31[j] >> 1) | (ht2crypt(lfsr) << 31);
|
||||
// insert new bit
|
||||
|
@ -734,7 +715,7 @@ void gen_bitstreams_testks(struct guess *g, uint64_t key)
|
|||
|
||||
ks = 0;
|
||||
// iterate lfsr with fnL, extracting ks
|
||||
for (i=0; i<32; i++) {
|
||||
for (i = 0; i < 32; i++) {
|
||||
// store ks - when done, the first ks bit will be bit 0 and the last will be bit 31
|
||||
ks = (ks >> 1) | (ht2crypt(lfsr) << 31);
|
||||
// insert new bit
|
||||
|
@ -752,15 +733,14 @@ void gen_bitstreams_testks(struct guess *g, uint64_t key)
|
|||
|
||||
|
||||
/* test function */
|
||||
void test()
|
||||
{
|
||||
void test() {
|
||||
uint64_t lfsr;
|
||||
uint64_t packed;
|
||||
|
||||
uint64_t i;
|
||||
|
||||
|
||||
for (i=0; i<1000; i++) {
|
||||
for (i = 0; i < 1000; i++) {
|
||||
lfsr = ((uint64_t)rand() << 32) | rand();
|
||||
packed = packstate(lfsr);
|
||||
|
||||
|
@ -774,15 +754,14 @@ 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;
|
||||
|
||||
hitag2_init(&hstate, key, uid, enc_nR);
|
||||
bits = 0;
|
||||
for (i=0; i<32; i++) {
|
||||
for (i = 0; i < 32; i++) {
|
||||
bits = (bits >> 1) | (hitag2_nstep(&hstate, 1) << 31);
|
||||
}
|
||||
if (ks == bits) {
|
||||
|
@ -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;
|
||||
|
@ -808,7 +786,7 @@ int main(int argc, char *argv[])
|
|||
// exit(0);
|
||||
|
||||
while ((c = getopt(argc, argv, "u:n:N:t:T:h")) != -1) {
|
||||
switch(c) {
|
||||
switch (c) {
|
||||
case 'u':
|
||||
uidstr = optarg;
|
||||
break;
|
||||
|
@ -848,7 +826,7 @@ int main(int argc, char *argv[])
|
|||
crack();
|
||||
|
||||
// test all key guesses and stop if one works
|
||||
for (i=0; i<num_guesses; i++) {
|
||||
for (i = 0; i < num_guesses; i++) {
|
||||
if (check_key(guesses[i].key, nonces[0].enc_nR, nonces[0].ks) &&
|
||||
check_key(guesses[i].key, nonces[1].enc_nR, nonces[1].ks)) {
|
||||
printf("WIN!!! :)\n");
|
||||
|
|
|
@ -142,18 +142,16 @@ 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 ret= 0L;
|
||||
unsigned long hexreversetoulong(BYTE *hex) {
|
||||
unsigned long ret = 0L;
|
||||
unsigned int x;
|
||||
BYTE i;
|
||||
|
||||
if(strlen(hex) != 8)
|
||||
if (strlen(hex) != 8)
|
||||
return 0L;
|
||||
|
||||
for(i= 0 ; i < 4 ; ++i)
|
||||
{
|
||||
if(sscanf(hex, "%2X", &x) != 1)
|
||||
for (i = 0 ; i < 4 ; ++i) {
|
||||
if (sscanf(hex, "%2X", &x) != 1)
|
||||
return 0L;
|
||||
ret += ((unsigned long) x) << i * 8;
|
||||
hex += 2;
|
||||
|
@ -162,18 +160,17 @@ unsigned long hexreversetoulong(BYTE *hex)
|
|||
}
|
||||
|
||||
// convert byte-reversed 12 digit hex to unsigned long
|
||||
unsigned long long hexreversetoulonglong(BYTE *hex)
|
||||
{
|
||||
unsigned long long ret= 0LL;
|
||||
unsigned long long hexreversetoulonglong(BYTE *hex) {
|
||||
unsigned long long ret = 0LL;
|
||||
BYTE tmp[9];
|
||||
|
||||
// this may seem an odd way to do it, but weird compiler issues were
|
||||
// breaking direct conversion!
|
||||
|
||||
tmp[8]= '\0';
|
||||
tmp[8] = '\0';
|
||||
memset(tmp + 4, '0', 4);
|
||||
memcpy(tmp, hex + 8, 4);
|
||||
ret= hexreversetoulong(tmp);
|
||||
ret = hexreversetoulong(tmp);
|
||||
ret <<= 32;
|
||||
memcpy(tmp, hex, 8);
|
||||
ret += hexreversetoulong(tmp);
|
||||
|
|
Loading…
Add table
Reference in a new issue