mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Bring hitag2crack tools in main Makefiles
This commit is contained in:
parent
94aa7cde2b
commit
6d33c0b784
21 changed files with 433 additions and 168 deletions
13
Makefile
13
Makefile
|
@ -15,6 +15,8 @@ ifneq (,$(DESTDIR))
|
|||
endif
|
||||
|
||||
all clean install uninstall check: %: client/% bootrom/% armsrc/% recovery/% mfkey/% nonce2key/% mf_nonce_brute/% fpga_compress/%
|
||||
# hitag2crack toolsuite is not yet integrated in "all", it must be called explicitly: "make hitag2crack"
|
||||
#all clean install uninstall check: %: hitag2crack/%
|
||||
|
||||
INSTALLTOOLS=pm3_eml2lower.sh pm3_eml2upper.sh pm3_mfdread.py pm3_mfd2eml.py pm3_eml2mfd.py findbits.py rfidtest.pl xorcheck.py
|
||||
INSTALLSIMFW=sim011.bin sim011.sha512.txt
|
||||
|
@ -103,6 +105,9 @@ client/check: FORCE
|
|||
recovery/check: FORCE
|
||||
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||
hitag2crack/check: FORCE
|
||||
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||
common/check: FORCE
|
||||
$(info [*] CHECK $(patsubst %/check,%,$@))
|
||||
$(Q)$(BASH) tools/pm3_tests.sh $(CHECKARGS) $(patsubst %/check,%,$@)
|
||||
|
@ -135,9 +140,12 @@ recovery/install: bootrom/all armsrc/all
|
|||
recovery/%: FORCE cleanifplatformchanged
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C recovery $(patsubst recovery/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||
hitag2crack/%: FORCE
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C tools/hitag2crack $(patsubst hitag2crack/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
|
||||
|
||||
.PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key mf_nonce_brute style miscchecks release FORCE udev accessrights cleanifplatformchanged
|
||||
.PHONY: all clean install uninstall help _test bootrom fullimage recovery client mfkey nonce2key mf_nonce_brute hitag2crack style miscchecks release FORCE udev accessrights cleanifplatformchanged
|
||||
|
||||
help:
|
||||
@echo "Multi-OS Makefile"
|
||||
|
@ -157,6 +165,7 @@ help:
|
|||
@echo "+ mfkey - Make tools/mfkey"
|
||||
@echo "+ nonce2key - Make tools/nonce2key"
|
||||
@echo "+ mf_nonce_brute - Make tools/mf_nonce_brute"
|
||||
@echo "+ hitag2crack - Make tools/hitag2crack"
|
||||
@echo "+ fpga_compress - Make tools/fpga_compress"
|
||||
@echo
|
||||
@echo "+ style - Apply some automated source code formatting rules"
|
||||
|
@ -193,6 +202,8 @@ mf_nonce_brute: mf_nonce_brute/all
|
|||
|
||||
fpga_compress: fpga_compress/all
|
||||
|
||||
hitag2crack: hitag2crack/all
|
||||
|
||||
newtarbin:
|
||||
$(RM) proxmark3-$(platform)-bin.tar proxmark3-$(platform)-bin.tar.gz
|
||||
@touch proxmark3-$(platform)-bin.tar
|
||||
|
|
|
@ -72,6 +72,10 @@ On some architectures, pthread library is not present:
|
|||
|
||||
* `make client SKIPPTHREAD=1` to skip `-lpthread` at linker stage.
|
||||
|
||||
One tool requires a CUDA compilation environment, it can be skipped as well:
|
||||
|
||||
* `make hitag2crack SKIPGPU=1` to skip ht2crack5gpu tool when compiling the hitag2crack toolsuite.
|
||||
|
||||
Some unittests are available via `make check`, which is actually triggering individual targets as for `make install`.
|
||||
|
||||
`make install` is actually triggering the following individual targets which can be accessed individually:
|
||||
|
|
33
tools/hitag2crack/Makefile
Normal file
33
tools/hitag2crack/Makefile
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Must be called before any Makefile include
|
||||
ROOT_DIR:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
include ../../Makefile.defs
|
||||
|
||||
all clean install uninstall check: %: crack2/% crack3/% crack4/% crack5/%
|
||||
ifneq ($(SKIPGPU),1)
|
||||
all clean install uninstall check: %: crack5gpu/%
|
||||
endif
|
||||
|
||||
crack2/%: FORCE
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C crack2 $(patsubst crack2/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||
|
||||
crack3/%: FORCE
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C crack3 $(patsubst crack3/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||
|
||||
crack4/%: FORCE
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C crack4 $(patsubst crack4/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||
|
||||
crack5/%: FORCE
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C crack5 $(patsubst crack5/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||
|
||||
crack5gpu/%: FORCE
|
||||
$(info [*] MAKE $@)
|
||||
$(Q)$(MAKE) --no-print-directory -C crack5gpu $(patsubst crack5gpu/%,%,$@) DESTDIR=$(MYDESTDIR)
|
||||
|
||||
FORCE: # Dummy target to force remake in the subdirectories, even if files exist (this Makefile doesn't know about the prerequisites)
|
||||
|
||||
.phony: crack2 crack3 crack4 crack5 crack5gpu FORCE
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef HT2CRACKUTILS_H
|
||||
#define HT2CRACKUTILS_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
@ -41,3 +44,5 @@ void buildlfsr(Hitag_State *hstate);
|
|||
#define rev64(X) (rev32(X) + (rev32(X >> 32) << 32))
|
||||
unsigned long hexreversetoulong(char *hex);
|
||||
unsigned long long hexreversetoulonglong(char *hex);
|
||||
|
||||
#endif /* HT2CRACKUTILS_H */
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
CFLAGS?=-Wall -Werror -O3
|
||||
# Linux libs
|
||||
LIBS=-pthread -D_GNU_SOURCE
|
||||
# Mac libs
|
||||
# LIBS=
|
||||
VPATH=../common
|
||||
INC=-I ../common
|
||||
MYSRCPATHS = ../common
|
||||
MYSRCS = ht2crackutils.c hitagcrypto.c
|
||||
MYINCLUDES =-I ../common
|
||||
MYCFLAGS = -D_GNU_SOURCE
|
||||
MYDEFS =
|
||||
MYLDLIBS = -lpthread
|
||||
|
||||
all: ht2crack2buildtable.c ht2crack2search.c ht2crack2gentest.c hitagcrypto.o ht2crackutils.o
|
||||
$(CC) $(CFLAGS) $(INC) -o ht2crack2buildtable ht2crack2buildtable.c hitagcrypto.o ht2crackutils.o $(LIBS)
|
||||
$(CC) $(CFLAGS) $(INC) -o ht2crack2search ht2crack2search.c hitagcrypto.o ht2crackutils.o $(LIBS)
|
||||
$(CC) $(CFLAGS) $(INC) -o ht2crack2gentest ht2crack2gentest.c hitagcrypto.o ht2crackutils.o $(LIBS)
|
||||
BINS = ht2crack2buildtable ht2crack2search ht2crack2gentest
|
||||
INSTALLTOOLS = $(BINS)
|
||||
|
||||
ht2crackutils.o: ht2crackutils.c ht2crackutils.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
include ../../../Makefile.host
|
||||
|
||||
hitagcrypto.o: hitagcrypto.c hitagcrypto.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
# checking platform can be done only after Makefile.host
|
||||
ifneq (,$(findstring MINGW,$(platform)))
|
||||
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
|
||||
# and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1
|
||||
CFLAGS += -D_ISOC99_SOURCE
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -rf *.o ht2crack2buildtable ht2crack2search ht2crack2gentest
|
||||
|
||||
fresh: clean all
|
||||
ht2crack2buildtable : $(OBJDIR)/ht2crack2buildtable.o $(MYOBJS)
|
||||
ht2crack2search : $(OBJDIR)/ht2crack2search.o $(MYOBJS)
|
||||
ht2crack2gentest : $(OBJDIR)/ht2crack2gentest.o $(MYOBJS)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*/
|
||||
|
||||
#include "ht2crackutils.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
// DATAMAX is the size of each bucket (bytes). There are 65536 buckets so choose a value such that
|
||||
// DATAMAX * 65536 < RAM available. For ex, if you want to use 12GB of RAM (for a 16GB machine
|
||||
|
@ -53,63 +53,63 @@ uint64_t d2[48];
|
|||
int nsteps2;
|
||||
|
||||
// create table entry
|
||||
void create_table(struct table *t, int d1, int d2) {
|
||||
if (!t) {
|
||||
static void create_table(struct table *tt, int d_1, int d_2) {
|
||||
if (!tt) {
|
||||
printf("create_table: t is NULL\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create some space
|
||||
t->data = (unsigned char *)malloc(DATAMAX);
|
||||
if (!(t->data)) {
|
||||
tt->data = (unsigned char *)malloc(DATAMAX);
|
||||
if (!(tt->data)) {
|
||||
printf("create_table: cannot malloc data\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// set data ptr to start of data table
|
||||
t->ptr = t->data;
|
||||
tt->ptr = tt->data;
|
||||
|
||||
// init the mutex
|
||||
if (pthread_mutex_init(&(t->mutex), NULL)) {
|
||||
if (pthread_mutex_init(&(tt->mutex), NULL)) {
|
||||
printf("create_table: cannot init mutex\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// create the path
|
||||
// sprintf(t->path, "/Volumes/2tb/%02X/%02X.bin", d1 & 0xff, d2 & 0xff);
|
||||
sprintf(t->path, "table/%02x/%02x.bin", d1 & 0xff, d2 & 0xff);
|
||||
// sprintf(tt->path, "/Volumes/2tb/%02X/%02X.bin", d_1 & 0xff, d_2 & 0xff);
|
||||
sprintf(tt->path, "table/%02x/%02x.bin", d_1 & 0xff, d_2 & 0xff);
|
||||
}
|
||||
|
||||
|
||||
// create all table entries
|
||||
void create_tables(struct table *t) {
|
||||
static void create_tables(struct table *tt) {
|
||||
int i, j;
|
||||
|
||||
if (!t) {
|
||||
if (!tt) {
|
||||
printf("create_tables: t is NULL\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x100; i++) {
|
||||
for (j = 0; j < 0x100; j++) {
|
||||
create_table(t + ((i * 0x100) + j), i, j);
|
||||
create_table(tt + ((i * 0x100) + j), i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// free the table memory
|
||||
void free_tables(struct table *t) {
|
||||
static void free_tables(struct table *tt) {
|
||||
int i;
|
||||
struct table *ttmp;
|
||||
|
||||
if (!t) {
|
||||
if (!tt) {
|
||||
printf("free_tables: t is NULL\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 0; i < 0x10000; i++) {
|
||||
ttmp = t + i;
|
||||
ttmp = tt + i;
|
||||
free(ttmp->data);
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ void free_tables(struct table *t) {
|
|||
|
||||
|
||||
// write (partial) table to file
|
||||
void writetable(struct table *t1) {
|
||||
static void writetable(struct table *t1) {
|
||||
int fd;
|
||||
|
||||
if (debug) printf("writetable %s\n", t1->path);
|
||||
|
@ -142,7 +142,7 @@ void writetable(struct table *t1) {
|
|||
|
||||
|
||||
// store value in table
|
||||
void store(unsigned char *data) {
|
||||
static void store(unsigned char *data) {
|
||||
unsigned char d_1, d_2;
|
||||
int offset;
|
||||
struct table *t1;
|
||||
|
@ -194,7 +194,7 @@ void store(unsigned char *data) {
|
|||
}
|
||||
|
||||
// writes the ks (keystream) and s (state)
|
||||
void write_ks_s(uint32_t ks1, uint32_t ks2, uint64_t shiftreg) {
|
||||
static void write_ks_s(uint32_t ks1, uint32_t ks2, uint64_t shiftreg) {
|
||||
unsigned char buf[16];
|
||||
|
||||
// create buffer
|
||||
|
@ -209,7 +209,7 @@ void write_ks_s(uint32_t ks1, uint32_t ks2, uint64_t shiftreg) {
|
|||
|
||||
|
||||
// builds the di table for jumping
|
||||
void builddi(int steps, int table) {
|
||||
static void builddi(int steps, int table) {
|
||||
uint64_t statemask;
|
||||
int i;
|
||||
Hitag_State mystate;
|
||||
|
@ -241,7 +241,7 @@ void builddi(int steps, int table) {
|
|||
}
|
||||
|
||||
// jump function - quickly jumps a load of steps
|
||||
void jumpnsteps(Hitag_State *hstate, int table) {
|
||||
static void jumpnsteps(Hitag_State *hstate, int table) {
|
||||
uint64_t output = 0;
|
||||
uint64_t bitmask;
|
||||
int i;
|
||||
|
@ -277,14 +277,14 @@ void jumpnsteps(Hitag_State *hstate, int table) {
|
|||
|
||||
|
||||
// thread to build a part of the table
|
||||
void *buildtable(void *d) {
|
||||
static void *buildtable(void *dd) {
|
||||
Hitag_State hstate;
|
||||
Hitag_State hstate2;
|
||||
unsigned long i;
|
||||
unsigned long maxentries = 1;
|
||||
uint32_t ks1;
|
||||
uint32_t ks2;
|
||||
int index = (int)(long)d;
|
||||
int index = (int)(long)dd;
|
||||
int tnum = NUM_BUILD_THREADS;
|
||||
|
||||
/* set random state */
|
||||
|
@ -334,7 +334,7 @@ void *buildtable(void *d) {
|
|||
|
||||
|
||||
// make 'table/' (unsorted) and 'sorted/' dir structures
|
||||
void makedirs() {
|
||||
static void makedirs(void) {
|
||||
char path[32];
|
||||
int i;
|
||||
|
||||
|
@ -368,7 +368,7 @@ static int datacmp(const void *p1, const void *p2, void *dummy) {
|
|||
return memcmp(d_1, d_2, DATASIZE);
|
||||
}
|
||||
|
||||
void *sorttable(void *d) {
|
||||
static void *sorttable(void *dd) {
|
||||
int i, j;
|
||||
int fdin;
|
||||
int fdout;
|
||||
|
@ -378,7 +378,7 @@ void *sorttable(void *d) {
|
|||
struct stat filestat;
|
||||
unsigned char *table = NULL;
|
||||
uint64_t numentries = 0;
|
||||
int index = (int)(long)d;
|
||||
int index = (int)(long)dd;
|
||||
int space = 0x100 / NUM_SORT_THREADS;
|
||||
|
||||
// create table - 50MB should be enough
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "ht2crackutils.h"
|
||||
|
||||
int makerandom(char *hex, unsigned int len, int fd) {
|
||||
static int makerandom(char *hex, unsigned int len, int fd) {
|
||||
unsigned char raw[32];
|
||||
int i;
|
||||
|
||||
|
@ -43,7 +43,7 @@ int main(int argc, char *argv[]) {
|
|||
int urandomfd;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("ht2crack2gentest number\n");
|
||||
printf("%s number\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ static int datacmp(const void *p1, const void *p2) {
|
|||
return memcmp(d1, d2, DATASIZE - 6);
|
||||
}
|
||||
|
||||
int loadrngdata(struct rngdata *r, char *file) {
|
||||
static int loadrngdata(struct rngdata *r, char *file) {
|
||||
int fd;
|
||||
int i, j;
|
||||
int nibble;
|
||||
|
@ -90,7 +90,7 @@ int loadrngdata(struct rngdata *r, char *file) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int makecand(unsigned char *c, struct rngdata *r, int bitoffset) {
|
||||
static int makecand(unsigned char *c, struct rngdata *r, int bitoffset) {
|
||||
int bytenum;
|
||||
int bitnum;
|
||||
int i;
|
||||
|
@ -116,7 +116,7 @@ int makecand(unsigned char *c, struct rngdata *r, int bitoffset) {
|
|||
|
||||
|
||||
// test the candidate against the next or previous rng data
|
||||
int testcand(unsigned char *f, unsigned char *rt, int fwd) {
|
||||
static int testcand(unsigned char *f, unsigned char *rt, int fwd) {
|
||||
Hitag_State hstate;
|
||||
int i;
|
||||
uint32_t ks1;
|
||||
|
@ -154,7 +154,7 @@ int testcand(unsigned char *f, unsigned char *rt, int fwd) {
|
|||
}
|
||||
}
|
||||
|
||||
int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, unsigned char *s) {
|
||||
static int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, unsigned char *s) {
|
||||
int fd;
|
||||
struct stat filestat;
|
||||
char file[64];
|
||||
|
@ -222,7 +222,7 @@ int searchcand(unsigned char *c, unsigned char *rt, int fwd, unsigned char *m, u
|
|||
|
||||
}
|
||||
|
||||
int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstate, int *bitoffset) {
|
||||
static int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstate, int *bitoffset) {
|
||||
int i;
|
||||
int bitlen;
|
||||
unsigned char cand[6];
|
||||
|
@ -276,7 +276,7 @@ int findmatch(struct rngdata *r, unsigned char *outmatch, unsigned char *outstat
|
|||
|
||||
|
||||
|
||||
void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset) {
|
||||
static void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset) {
|
||||
int i;
|
||||
|
||||
if (!s) {
|
||||
|
@ -305,7 +305,7 @@ void rollbackrng(Hitag_State *hstate, unsigned char *s, int offset) {
|
|||
|
||||
}
|
||||
|
||||
uint64_t recoverkey(Hitag_State *hstate, char *uidstr, char *nRstr) {
|
||||
static uint64_t recoverkey(Hitag_State *hstate, char *uidstr, char *nRstr) {
|
||||
uint64_t key;
|
||||
uint64_t keyupper;
|
||||
uint32_t uid;
|
||||
|
@ -368,7 +368,7 @@ int main(int argc, char *argv[]) {
|
|||
int i;
|
||||
|
||||
if (argc < 4) {
|
||||
printf("ht2crack2search rngdatafile UID nR\n");
|
||||
printf("%s rngdatafile UID nR\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
5
tools/hitag2crack/crack3/.gitignore
vendored
5
tools/hitag2crack/crack3/.gitignore
vendored
|
@ -1,6 +1,5 @@
|
|||
ht2crack3
|
||||
ht2test
|
||||
ht2crack3test
|
||||
|
||||
ht2crack3.exe
|
||||
ht2test.exe
|
||||
|
||||
ht2crack3test.exe
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
CFLAGS?=-Wall -Werror -O3
|
||||
LIBS=
|
||||
VPATH=../common
|
||||
INC=-I ../common
|
||||
MYSRCPATHS = ../common
|
||||
MYSRCS = ht2crackutils.c hitagcrypto.c
|
||||
MYINCLUDES =-I ../common
|
||||
MYCFLAGS = -D_GNU_SOURCE
|
||||
MYDEFS =
|
||||
MYLDLIBS = -lpthread
|
||||
|
||||
all: ht2crack3.c ht2test.c hitagcrypto.o ht2crackutils.o
|
||||
$(CC) $(CFLAGS) $(INC) -o ht2crack3 $< hitagcrypto.o ht2crackutils.o -lpthread $(LIBS)
|
||||
$(CC) $(CFLAGS) $(INC) -o ht2test ht2test.c hitagcrypto.o ht2crackutils.o $(LIBS)
|
||||
BINS = ht2crack3 ht2crack3test
|
||||
INSTALLTOOLS = $(BINS)
|
||||
|
||||
ht2crackutils.o: ht2crackutils.c ht2crackutils.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
include ../../../Makefile.host
|
||||
|
||||
hitagcrypto.o: hitagcrypto.c hitagcrypto.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
# checking platform can be done only after Makefile.host
|
||||
ifneq (,$(findstring MINGW,$(platform)))
|
||||
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
|
||||
# and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1
|
||||
CFLAGS += -D_ISOC99_SOURCE
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -rf *.o ht2crack3 ht2test
|
||||
|
||||
fresh: clean all
|
||||
ht2crack3 : $(OBJDIR)/ht2crack3.o $(MYOBJS)
|
||||
ht2crack3test : $(OBJDIR)/ht2crack3test.o $(MYOBJS)
|
||||
|
|
|
@ -31,9 +31,9 @@ Tests
|
|||
|
||||
If you happen to know the key and want to check that all your nR aR values
|
||||
are valid (for high-powered demonstrations only, really) then you can use
|
||||
the ht2test program to check them. It's otherwise massively pointless and a
|
||||
the ht2crack3test program to check them. It's otherwise massively pointless and a
|
||||
complete waste of space.
|
||||
|
||||
```
|
||||
./ht2test NRARFILE KEY UID
|
||||
./ht2crack3test NRARFILE KEY UID
|
||||
```
|
||||
|
|
|
@ -65,7 +65,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) {
|
||||
static 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
|
||||
|
@ -84,7 +84,7 @@ int fnP(uint64_t klowery) {
|
|||
}
|
||||
|
||||
// comparison function for sorting/searching Tklower entries
|
||||
int Tk_cmp(const void *v1, const void *v2) {
|
||||
static int Tk_cmp(const void *v1, const void *v2) {
|
||||
const struct Tklower *Tk1 = (struct Tklower *)v1;
|
||||
const struct Tklower *Tk2 = (struct Tklower *)v2;
|
||||
|
||||
|
@ -98,7 +98,7 @@ int Tk_cmp(const void *v1, const void *v2) {
|
|||
}
|
||||
|
||||
// test for bad guesses of kmiddle
|
||||
int is_kmiddle_badguess(uint64_t z, struct Tklower *Tk, int max, int aR0) {
|
||||
static int is_kmiddle_badguess(uint64_t z, struct Tklower *Tk, int max, int aR0) {
|
||||
|
||||
struct Tklower *result, target;
|
||||
|
||||
|
@ -122,7 +122,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) {
|
||||
static 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;
|
||||
|
@ -178,7 +178,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) {
|
||||
static void *crack(void *d) {
|
||||
struct threaddata *data = (struct threaddata *)d;
|
||||
uint64_t uid;
|
||||
struct nRaR *TnRaR;
|
||||
|
@ -321,7 +321,7 @@ int main(int argc, char *argv[]) {
|
|||
struct threaddata *tdata = NULL;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("ht2crack3 uid nRaRfile\n");
|
||||
printf("%s uid nRaRfile\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ int main(int argc, char *argv[]) {
|
|||
char *uid;
|
||||
|
||||
if (argc < 4) {
|
||||
printf("ht2test nRaRfile KEY UID\n");
|
||||
printf("%s nRaRfile KEY UID\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -1,18 +1,20 @@
|
|||
CFLAGS?=-Wall -Werror -O3
|
||||
LIBS=-lpthread
|
||||
VPATH=../common
|
||||
INC=-I ../common
|
||||
MYSRCPATHS = ../common
|
||||
MYSRCS = ht2crackutils.c hitagcrypto.c
|
||||
MYINCLUDES =-I ../common
|
||||
MYCFLAGS = -D_GNU_SOURCE
|
||||
MYDEFS =
|
||||
MYLDLIBS = -lpthread
|
||||
|
||||
all: ht2crack4.c hitagcrypto.o ht2crackutils.o
|
||||
$(CC) $(CFLAGS) $(INC) -o ht2crack4 $< hitagcrypto.o ht2crackutils.o $(LIBS)
|
||||
BINS = ht2crack4
|
||||
INSTALLTOOLS = $(BINS)
|
||||
|
||||
hitagcrypto.o: hitagcrypto.c hitagcrypto.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
include ../../../Makefile.host
|
||||
|
||||
ht2crackutils.o: ht2crackutils.c ht2crackutils.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
# checking platform can be done only after Makefile.host
|
||||
ifneq (,$(findstring MINGW,$(platform)))
|
||||
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
|
||||
# and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1
|
||||
CFLAGS += -D_ISOC99_SOURCE
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -rf *.o ht2crack4
|
||||
|
||||
fresh: clean all
|
||||
ht2crack4 : $(OBJDIR)/ht2crack4.o $(MYOBJS)
|
||||
|
|
|
@ -93,7 +93,7 @@ uint64_t uid;
|
|||
int maxtablesize = 800000;
|
||||
uint64_t supplied_testkey = 0;
|
||||
|
||||
void usage() {
|
||||
static void usage(void) {
|
||||
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");
|
||||
|
@ -147,6 +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) {
|
||||
uint32_t bitindex;
|
||||
|
||||
|
@ -158,9 +159,10 @@ static uint32_t hitag2_crypt(uint64_t s) {
|
|||
|
||||
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) {
|
||||
static uint64_t ht2crypt(uint64_t s) {
|
||||
uint64_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> pickbits2_2(s, 2, 5)) & 1;
|
||||
|
@ -174,12 +176,13 @@ uint64_t ht2crypt(uint64_t s) {
|
|||
|
||||
|
||||
/* fnL is the feedback function for the reference code */
|
||||
uint64_t fnL(uint64_t x) {
|
||||
/*
|
||||
static 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));
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/* packed_size is an array that maps the number of confirmed bits in a state to
|
||||
* the number of relevant bits.
|
||||
|
@ -193,7 +196,7 @@ unsigned int packed_size[] = { 0, 0, 0, 1, 2, 2, 3, 4, 4, 5, 5, 5, 5
|
|||
|
||||
/* 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) {
|
||||
static uint64_t f20(uint64_t y) {
|
||||
uint64_t bitindex;
|
||||
|
||||
bitindex = (ht2_function4a >> (y & 0xf)) & 1;
|
||||
|
@ -207,7 +210,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) {
|
||||
static uint64_t packstate(uint64_t s) {
|
||||
uint64_t packed;
|
||||
|
||||
packed = pickbits2_2(s, 2, 5);
|
||||
|
@ -221,7 +224,7 @@ uint64_t packstate(uint64_t s) {
|
|||
|
||||
|
||||
/* create_guess_table mallocs the tables */
|
||||
void create_guess_table() {
|
||||
static void create_guess_table(void) {
|
||||
guesses = (struct guess *)malloc(sizeof(struct guess) * maxtablesize);
|
||||
if (!guesses) {
|
||||
printf("cannot malloc guess table\n");
|
||||
|
@ -232,7 +235,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) {
|
||||
static void init_guess_table(char *filename, char *uidstr) {
|
||||
unsigned int i, j;
|
||||
FILE *fp;
|
||||
char *buf = NULL;
|
||||
|
@ -313,7 +316,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) {
|
||||
static double bit_score(uint64_t s, uint64_t size, uint64_t b) {
|
||||
uint64_t packed;
|
||||
uint64_t chopped;
|
||||
unsigned int n;
|
||||
|
@ -396,7 +399,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) {
|
||||
static double score(uint64_t s, unsigned int size, uint64_t ks, unsigned int kssize) {
|
||||
double sc, sc2;
|
||||
|
||||
if ((size == 1) || (kssize == 1)) {
|
||||
|
@ -427,7 +430,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) {
|
||||
static void score_traces(struct guess *g, unsigned int size) {
|
||||
uint64_t lfsr;
|
||||
unsigned int i;
|
||||
double sc;
|
||||
|
@ -481,7 +484,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) {
|
||||
static void *score_some_traces(void *data) {
|
||||
unsigned int i;
|
||||
struct thread_data *tdata = (struct thread_data *)data;
|
||||
|
||||
|
@ -494,7 +497,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) {
|
||||
static void score_all_traces(unsigned int size) {
|
||||
pthread_t threads[NUM_THREADS];
|
||||
void *status;
|
||||
struct thread_data tdata[NUM_THREADS];
|
||||
|
@ -535,7 +538,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) {
|
||||
static int cmp_guess(const void *a, const void *b) {
|
||||
struct guess *a1 = (struct guess *)a;
|
||||
struct guess *b1 = (struct guess *)b;
|
||||
|
||||
|
@ -552,7 +555,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) {
|
||||
static void expand_guesses(unsigned int halfsize, unsigned int size) {
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0; i < halfsize; i++) {
|
||||
|
@ -567,7 +570,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) {
|
||||
static void check_supplied_testkey(unsigned int size) {
|
||||
uint64_t partkey;
|
||||
unsigned int i;
|
||||
|
||||
|
@ -586,7 +589,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) {
|
||||
static void execute_round(unsigned int size) {
|
||||
unsigned int halfsize;
|
||||
|
||||
// score all the current guesses
|
||||
|
@ -614,7 +617,7 @@ void execute_round(unsigned int size) {
|
|||
|
||||
|
||||
/* crack is the main cracking algo; it executes the rounds */
|
||||
void crack() {
|
||||
static void crack(void) {
|
||||
unsigned int i;
|
||||
uint64_t revkey;
|
||||
uint64_t foundkey;
|
||||
|
@ -630,9 +633,9 @@ void crack() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* test function to make sure I know how the LFSR works */
|
||||
void testkey(uint64_t key) {
|
||||
/*
|
||||
static void testkey(uint64_t key) {
|
||||
uint64_t i;
|
||||
uint64_t b0to31 = 0;
|
||||
uint64_t ks = 0;
|
||||
|
@ -689,10 +692,11 @@ void testkey(uint64_t key) {
|
|||
printbin2(lfsr, 48);
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/* test function to generate test data */
|
||||
void gen_bitstreams_testks(struct guess *g, uint64_t key) {
|
||||
/*
|
||||
static void gen_bitstreams_testks(struct guess *g, uint64_t key) {
|
||||
unsigned int i, j;
|
||||
uint64_t nRxorkey, lfsr, ks;
|
||||
|
||||
|
@ -730,10 +734,11 @@ void gen_bitstreams_testks(struct guess *g, uint64_t key) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/* test function */
|
||||
void test() {
|
||||
/*
|
||||
static void test(void) {
|
||||
uint64_t lfsr;
|
||||
uint64_t packed;
|
||||
|
||||
|
@ -751,10 +756,10 @@ void test() {
|
|||
|
||||
printf("test done\n");
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/* 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) {
|
||||
static int check_key(uint64_t key, uint64_t enc_nR, uint64_t ks) {
|
||||
Hitag_State hstate;
|
||||
uint64_t bits;
|
||||
int i;
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
CFLAGS?=-Wall -Werror -O3
|
||||
LIBS=-lpthread
|
||||
VPATH=../common
|
||||
INC=-I ../common
|
||||
MYSRCPATHS = ../common
|
||||
MYSRCS = ht2crackutils.c hitagcrypto.c
|
||||
MYINCLUDES =-I ../common
|
||||
MYCFLAGS =
|
||||
MYDEFS =
|
||||
MYLDLIBS = -lpthread
|
||||
|
||||
all: ht2crack5.c ht2crackutils.o hitagcrypto.o
|
||||
$(CC) $(CFLAGS) $(INC) -O3 $< -o ht2crack5 ht2crackutils.o hitagcrypto.o $(LIBS)
|
||||
BINS = ht2crack5
|
||||
INSTALLTOOLS = $(BINS)
|
||||
|
||||
hitagcrypto.o: hitagcrypto.c hitagcrypto.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
include ../../../Makefile.host
|
||||
|
||||
ht2crackutils.o: ht2crackutils.c ht2crackutils.h
|
||||
$(CC) $(CFLAGS) -c $<
|
||||
# checking platform can be done only after Makefile.host
|
||||
ifneq (,$(findstring MINGW,$(platform)))
|
||||
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
|
||||
# and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1
|
||||
CFLAGS += -D_ISOC99_SOURCE
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -f *.o ht2crack5
|
||||
fresh: clean all
|
||||
ht2crack5 : $(OBJDIR)/ht2crack5.o $(MYOBJS)
|
||||
|
|
|
@ -55,7 +55,7 @@ bitslice_t bs_zeroes, bs_ones;
|
|||
#define get_bit(n, word) ((word >> (n)) & 1)
|
||||
#define get_vector_bit(slice, value) get_bit(slice&0x3f, value.bytes64[slice>>6])
|
||||
|
||||
const uint64_t expand(uint64_t mask, uint64_t value) {
|
||||
static uint64_t expand(uint64_t mask, uint64_t value) {
|
||||
uint64_t fill = 0;
|
||||
for (uint64_t bit_index = 0; bit_index < 48; bit_index++) {
|
||||
if (mask & 1) {
|
||||
|
@ -67,7 +67,7 @@ const uint64_t expand(uint64_t mask, uint64_t value) {
|
|||
return fill;
|
||||
}
|
||||
|
||||
void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) {
|
||||
static void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) {
|
||||
size_t bit_idx;
|
||||
for (bit_idx = 0; bit_idx < bit_len; bit_idx++) {
|
||||
bool bit;
|
||||
|
@ -84,7 +84,7 @@ void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const
|
|||
}
|
||||
}
|
||||
|
||||
const uint64_t unbitslice(const bitslice_t *restrict b, const uint8_t s, const uint8_t n) {
|
||||
static uint64_t unbitslice(const bitslice_t *restrict b, const uint8_t s, const uint8_t n) {
|
||||
uint64_t result = 0;
|
||||
for (uint8_t i = 0; i < n; ++i) {
|
||||
result <<= 1;
|
||||
|
@ -118,7 +118,7 @@ bitslice_t initial_bitslices[48];
|
|||
size_t filter_pos[20] = {4, 7, 9, 13, 16, 18, 22, 24, 27, 30, 32, 35, 45, 47 };
|
||||
size_t thread_count = 8;
|
||||
uint64_t layer_0_found;
|
||||
void *find_state(void *thread_d);
|
||||
static void *find_state(void *thread_d);
|
||||
static void try_state(uint64_t s);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
@ -201,7 +201,7 @@ int main(int argc, char *argv[]) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
void *find_state(void *thread_d) {
|
||||
static void *find_state(void *thread_d) {
|
||||
uint64_t thread = (uint64_t)thread_d;
|
||||
|
||||
for (uint64_t index = thread; index < layer_0_found; index += thread_count) {
|
||||
|
|
|
@ -1,23 +1,27 @@
|
|||
CFLAGS?=-Wall
|
||||
#INCLUDE=-I/usr/local/cuda-7.5/include
|
||||
INCLUDE=-I/opt/nvidia/cuda/include
|
||||
#Linux
|
||||
#LIBS=-L/usr/local/cuda-7.5/lib64 -lOpenCL
|
||||
LIBS=-L/opt/nvidia/cuda/lib64 -lOpenCL
|
||||
#Mac
|
||||
#LIBS=-framework OpenCL
|
||||
VPATH=../common
|
||||
INC=-I ../common
|
||||
MYSRCPATHS = ../common
|
||||
MYSRCS = ht2crackutils.c hitagcrypto.c
|
||||
MYCFLAGS =
|
||||
MYDEFS =
|
||||
ifeq ($(platform),Darwin)
|
||||
MYLDLIBS ?= -framework OpenCL
|
||||
else
|
||||
#MYINCLUDES ?=-I/usr/local/cuda-7.5/include
|
||||
#MYINCLUDES ?=-I/opt/nvidia/cuda/include
|
||||
#MYLDLIBS ?= -L/usr/local/cuda-7.5/lib64 -lOpenCL
|
||||
MYLDLIBS ?= -L/opt/nvidia/cuda/lib64 -lOpenCL
|
||||
endif
|
||||
MYINCLUDES +=-I ../common
|
||||
|
||||
all: ht2crack5.c ht2crackutils.o hitagcrypto.o
|
||||
$(CC) $(CFLAGS) $(INC) -o ht2crack5gpu $< ht2crackutils.o hitagcrypto.o $(LIBS) -lpthread
|
||||
BINS = ht2crack5gpu
|
||||
INSTALLTOOLS = $(BINS)
|
||||
|
||||
hitagcrypto.o: hitagcrypto.c hitagcrypto.h
|
||||
$(CC) $(CFLAGS) $(INCLUDE) -c $<
|
||||
include ../../../Makefile.host
|
||||
|
||||
ht2crackutils.o: ht2crackutils.c ht2crackutils.h
|
||||
$(CC) $(CFLAGS) $(INCLUDE) -c $<
|
||||
# checking platform can be done only after Makefile.host
|
||||
ifneq (,$(findstring MINGW,$(platform)))
|
||||
# Mingw uses by default Microsoft printf, we want the GNU printf (e.g. for %z)
|
||||
# and setting _ISOC99_SOURCE sets internally __USE_MINGW_ANSI_STDIO=1
|
||||
CFLAGS += -D_ISOC99_SOURCE
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -f *.o ht2crack5gpu
|
||||
fresh: clean all
|
||||
ht2crack5gpu : $(OBJDIR)/ht2crack5gpu.o $(MYOBJS)
|
||||
|
|
|
@ -65,7 +65,7 @@ bitslice_t bs_zeroes, bs_ones;
|
|||
state[-2+i+42].value ^ state[-2+i+43].value ^ state[-2+i+46].value ^ state[-2+i+47].value);
|
||||
#define get_bit(n, word) ((word >> (n)) & 1)
|
||||
|
||||
const uint64_t expand(uint64_t mask, uint64_t value) {
|
||||
static uint64_t expand(uint64_t mask, uint64_t value) {
|
||||
uint64_t fill = 0;
|
||||
for (uint64_t bit_index = 0; bit_index < 48; bit_index++) {
|
||||
if (mask & 1) {
|
||||
|
@ -77,7 +77,7 @@ const uint64_t expand(uint64_t mask, uint64_t value) {
|
|||
return fill;
|
||||
}
|
||||
|
||||
void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) {
|
||||
static void bitslice(const uint64_t value, bitslice_t *restrict bitsliced_value, const size_t bit_len, bool reverse) {
|
||||
size_t bit_idx;
|
||||
for (bit_idx = 0; bit_idx < bit_len; bit_idx++) {
|
||||
bool bit;
|
||||
|
@ -123,7 +123,7 @@ struct context {
|
|||
};
|
||||
|
||||
|
||||
void runKernel(struct context *ctx, uint32_t cand_base, uint64_t *matches, uint32_t *matches_found) {
|
||||
static void runKernel(struct context *ctx, uint32_t cand_base, uint64_t *matches, uint32_t *matches_found) {
|
||||
int err;
|
||||
size_t global[2];
|
||||
|
118
tools/hitag2crack/hitag2_gen_nRaR.py
Executable file
118
tools/hitag2crack/hitag2_gen_nRaR.py
Executable file
|
@ -0,0 +1,118 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
"""
|
||||
HITAG2 cipher
|
||||
Implemented by Aram Verstegen
|
||||
"""
|
||||
import random
|
||||
|
||||
def i4(x, a, b, c, d):
|
||||
return (((x >> a) & 1)*8)+((x >> b) & 1)*4+((x >> c) & 1)*2+((x >> d) & 1)
|
||||
|
||||
|
||||
def f20_4(state):
|
||||
return ((0x3c65 >> i4(state,34,43,44,46)) & 1)
|
||||
|
||||
def f20_3(state):
|
||||
return (( 0xee5 >> i4(state,28,29,31,33)) & 1)
|
||||
|
||||
def f20_2(state):
|
||||
return (( 0xee5 >> i4(state,17,21,23,26)) & 1)
|
||||
|
||||
def f20_1(state):
|
||||
return (( 0xee5 >> i4(state, 8,12,14,15)) & 1)
|
||||
|
||||
def f20_0(state):
|
||||
return ((0x3c65 >> i4(state, 2, 3, 5, 6)) & 1)
|
||||
|
||||
def f20_last(s0,s1,s2,s3,s4):
|
||||
return (0xdd3929b >> ((s0 * 16)
|
||||
+ (s1 * 8)
|
||||
+ (s2 * 4)
|
||||
+ (s3 * 2)
|
||||
+ (s4 * 1))) & 1
|
||||
|
||||
def f20(state):
|
||||
return f20_last(f20_0(state), f20_1(state), f20_2(state), f20_3(state), f20_4(state))
|
||||
|
||||
def lfsr_bs(state, i):
|
||||
return (state[i+ 0] ^ state[i+ 2] ^ state[i+ 3] ^ state[i+ 6] ^
|
||||
state[i+ 7] ^ state[i+ 8] ^ state[i+16] ^ state[i+22] ^
|
||||
state[i+23] ^ state[i+26] ^ state[i+30] ^ state[i+41] ^
|
||||
state[i+42] ^ state[i+43] ^ state[i+46] ^ state[i+47])
|
||||
|
||||
def f20a_bs(a,b,c,d):
|
||||
return (~(((a|b)&c)^(a|d)^b)) # 6 ops
|
||||
def f20b_bs(a,b,c,d):
|
||||
return (~(((d|c)&(a^b))^(d|a|b))) # 7 ops
|
||||
def f20c_bs(a,b,c,d,e):
|
||||
return (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) # 13 ops
|
||||
|
||||
def filter_bs(state, i):
|
||||
return (f20c_bs( f20a_bs(state[i+ 2],state[i+ 3],state[i+ 5],state[i+ 6]),
|
||||
f20b_bs(state[i+ 8],state[i+12],state[i+14],state[i+15]),
|
||||
f20b_bs(state[i+17],state[i+21],state[i+23],state[i+26]),
|
||||
f20b_bs(state[i+28],state[i+29],state[i+31],state[i+33]),
|
||||
f20a_bs(state[i+34],state[i+43],state[i+44],state[i+46])))
|
||||
|
||||
def unbitslice(s, n):
|
||||
return int(''.join(map(str,map(int,map(bool,s[n:n+48])))[::-1]),2)
|
||||
|
||||
def hitag2_init(key, uid, nonce):
|
||||
state = 0
|
||||
for i in range(32, 48):
|
||||
state = (state << 1) | ((key >> i) & 1)
|
||||
for i in range(0, 32):
|
||||
state = (state << 1) | ((uid >> i) & 1)
|
||||
#print '%012x' % state
|
||||
#print '%012x' % (int("{0:048b}".format(state)[::-1],2))
|
||||
for i in range(0, 32):
|
||||
nonce_bit = (f20(state) ^ ((nonce >> (31-i)) & 1))
|
||||
#print nonce_bit
|
||||
state = (state >> 1) | (((nonce_bit ^ (key >> (31-i))) & 1) << 47)
|
||||
#print '%012x' % state
|
||||
#print '%012x' % (int("{0:048b}".format(state)[::-1],2))
|
||||
return state
|
||||
|
||||
def lfsr_feedback(state):
|
||||
return (((state >> 0) ^ (state >> 2) ^ (state >> 3)
|
||||
^ (state >> 6) ^ (state >> 7) ^ (state >> 8)
|
||||
^ (state >> 16) ^ (state >> 22) ^ (state >> 23)
|
||||
^ (state >> 26) ^ (state >> 30) ^ (state >> 41)
|
||||
^ (state >> 42) ^ (state >> 43) ^ (state >> 46)
|
||||
^ (state >> 47)) & 1)
|
||||
def lfsr(state):
|
||||
return (state >> 1) + (lfsr_feedback(state) << 47)
|
||||
|
||||
def lfsr_feedback_inv(state):
|
||||
return (((state >> 47) ^ (state >> 1) ^ (state >> 2)
|
||||
^ (state >> 5) ^ (state >> 6) ^ (state >> 7)
|
||||
^ (state >> 15) ^ (state >> 21) ^ (state >> 22)
|
||||
^ (state >> 25) ^ (state >> 29) ^ (state >> 40)
|
||||
^ (state >> 41) ^ (state >> 42) ^ (state >> 45)
|
||||
^ (state >> 46)) & 1)
|
||||
|
||||
def lfsr_inv(state):
|
||||
return ((state << 1) + (lfsr_feedback_inv(state))) & ((1<<48)-1)
|
||||
|
||||
def hitag2(state, length=48):
|
||||
c = 0
|
||||
for i in range(0, length):
|
||||
c = (c << 1) | f20(state)
|
||||
#print '%012x' % state
|
||||
#print '%012x' % (int("{0:048b}".format(state)[::-1],2))
|
||||
state = lfsr(state)
|
||||
return c
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
if len(sys.argv) == 4:
|
||||
key = int(sys.argv[1], 16)
|
||||
uid = int(sys.argv[2], 16)
|
||||
n = int(sys.argv[3])
|
||||
for i in range(n):
|
||||
nonce = random.randrange(2**32)
|
||||
state = hitag2_init(key, uid, nonce)
|
||||
print('%08X %08X' % (nonce, hitag2(state, 32)^0xffffffff))
|
||||
else:
|
||||
print("Usage: python %s <key> <uid> <nr of nRaR to generate>" % sys.argv[0])
|
|
@ -4,10 +4,12 @@ PM3PATH="$(dirname "$0")/.."
|
|||
cd "$PM3PATH" || exit 1
|
||||
|
||||
SLOWTESTS=false
|
||||
GPUTESTS=false
|
||||
TESTALL=true
|
||||
TESTMFKEY=false
|
||||
TESTNONCE2KEY=false
|
||||
TESTMFNONCEBRUTE=false
|
||||
TESTHITAG2CRACK=false
|
||||
TESTFPGACOMPRESS=false
|
||||
TESTBOOTROM=false
|
||||
TESTARMSRC=false
|
||||
|
@ -32,6 +34,10 @@ Usage: $0 [--long] [--clientbin /path/to/proxmark3] [mfkey|nonce2key|mf_nonce_br
|
|||
SLOWTESTS=true
|
||||
shift
|
||||
;;
|
||||
--gpu)
|
||||
GPUTESTS=true
|
||||
shift
|
||||
;;
|
||||
--clientbin)
|
||||
if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then
|
||||
CLIENTBIN=$2
|
||||
|
@ -61,6 +67,11 @@ Usage: $0 [--long] [--clientbin /path/to/proxmark3] [mfkey|nonce2key|mf_nonce_br
|
|||
TESTFPGACOMPRESS=true
|
||||
shift
|
||||
;;
|
||||
hitag2crack)
|
||||
TESTALL=false
|
||||
TESTHITAG2CRACK=true
|
||||
shift
|
||||
;;
|
||||
bootrom)
|
||||
TESTALL=false
|
||||
TESTBOOTROM=true
|
||||
|
@ -122,24 +133,45 @@ function CheckFileExist() {
|
|||
return 1
|
||||
}
|
||||
|
||||
# title, command line, check result, repeat several times if failed, ignore if fail
|
||||
# [slow] [gpu] [retry] [ignore] <title> <command_line> <check_result_regex>
|
||||
# slow: test takes more than ~5s
|
||||
# gpu: test requires GPU presence
|
||||
# retry: test repeated up to 3 times in case of failure
|
||||
# ignore: test failure is not fatal
|
||||
function CheckExecute() {
|
||||
if [ "$1" == "slow" ]; then
|
||||
SLOWTEST=true
|
||||
local SLOWTEST=true
|
||||
shift
|
||||
else
|
||||
SLOWTEST=false
|
||||
local SLOWTEST=false
|
||||
fi
|
||||
if [ "$4" ]; then
|
||||
if [ "$1" == "gpu" ]; then
|
||||
local GPUTEST=true
|
||||
shift
|
||||
else
|
||||
local GPUTEST=false
|
||||
fi
|
||||
if [ "$1" == "retry" ]; then
|
||||
local RETRY="1 2 3 e"
|
||||
shift
|
||||
else
|
||||
local RETRY="e"
|
||||
fi
|
||||
if [ "$1" == "ignore" ]; then
|
||||
local IGNOREFAILURE=true
|
||||
shift
|
||||
else
|
||||
local IGNOREFAILURE=false
|
||||
fi
|
||||
|
||||
if $SLOWTEST && ! $SLOWTESTS; then
|
||||
echo -e "$1 ${C_YELLOW}[SKIPPED]${C_NC} (slow)\n"
|
||||
return 0
|
||||
fi
|
||||
if $GPUTEST && ! $GPUTESTS; then
|
||||
echo -e "$1 ${C_YELLOW}[SKIPPED]${C_NC} (gpu)\n"
|
||||
return 0
|
||||
fi
|
||||
|
||||
for I in $RETRY
|
||||
do
|
||||
|
@ -151,7 +183,7 @@ function CheckExecute() {
|
|||
if [ ! $I == "e" ]; then echo "retry $I"; fi
|
||||
done
|
||||
|
||||
if [ "$5" ]; then
|
||||
if $IGNOREFAILURE; then
|
||||
echo -e "$1 ${C_YELLOW}[Ignored]${C_NC}"
|
||||
return 0
|
||||
fi
|
||||
|
@ -227,6 +259,54 @@ while true; do
|
|||
if ! CheckFileExist "mf_nonce_brute exists" "$MFNONCEBRUTEBIN"; then break; fi
|
||||
if ! CheckExecute slow "mf_nonce_brute test" "$MFNONCEBRUTEBIN 9c599b32 5a920d85 1011 98d76b77 d6c6e870 0000 ca7e0b63 0111 3e709c8a" "Key.*: \[ffffffffffff\]"; then break; fi
|
||||
fi
|
||||
# hitag2crack not yet part of "all"
|
||||
# if $TESTALL || $TESTHITAG2CRACK; then
|
||||
if $TESTHITAG2CRACK; then
|
||||
echo -e "\n${C_BLUE}Testing ht2crack2:${C_NC} ${HT2CRACK2PATH:=./tools/hitag2crack/crack2/}"
|
||||
if ! CheckFileExist "ht2crack2buildtable exists" "$HT2CRACK2PATH/ht2crack2buildtable"; then break; fi
|
||||
if ! CheckFileExist "ht2crack2gentest exists" "$HT2CRACK2PATH/ht2crack2gentest"; then break; fi
|
||||
if ! CheckFileExist "ht2crack2search exists" "$HT2CRACK2PATH/ht2crack2search"; then break; fi
|
||||
# 1.5Tb tables are supposed to be absent, so it's just a fast check without real cracking
|
||||
if ! CheckExecute "ht2crack2 quick test" "cd $HT2CRACK2PATH; ./ht2crack2gentest 1 && ./runalltests.sh; rm keystream*" "searching on bit"; then break; fi
|
||||
|
||||
echo -e "\n${C_BLUE}Testing ht2crack3:${C_NC} ${HT2CRACK3PATH:=./tools/hitag2crack/crack3/}"
|
||||
if ! CheckFileExist "ht2crack3 exists" "$HT2CRACK3PATH/ht2crack3"; then break; fi
|
||||
if ! CheckFileExist "ht2crack3test exists" "$HT2CRACK3PATH/ht2crack3test"; then break; fi
|
||||
HT2CRACK3UID=AABBCCDD
|
||||
# Test fast only for HT2CRACK3KEY in begin of keyspace!
|
||||
HT2CRACK3KEY=000102030405
|
||||
HT2CRACK3N=32
|
||||
HT2CRACK3NRAR=hitag2_${HT2CRACK3UID}_nrar_${HT2CRACK3N}emul.txt
|
||||
if ! CheckExecute "ht2crack3 gen testfile" "cd $HT2CRACK3PATH; python3 ../hitag2_gen_nRaR.py $HT2CRACK3KEY $HT2CRACK3UID $HT2CRACK3N > $HT2CRACK3NRAR && echo SUCCESS" "SUCCESS"; then break; fi
|
||||
if ! CheckExecute "ht2crack3test test" "cd $HT2CRACK3PATH; ./ht2crack3test $HT2CRACK3NRAR $HT2CRACK3KEY $HT2CRACK3UID|grep -v SUCCESS||echo SUCCESS" "SUCCESS"; then break; fi
|
||||
if ! CheckExecute "ht2crack3 test" "cd $HT2CRACK3PATH; ./ht2crack3 $HT2CRACK3UID $HT2CRACK3NRAR |egrep -v '(trying|partial)'" "key = $HT2CRACK3KEY"; then break; fi
|
||||
if ! CheckExecute "ht2crack3 rm testfile" "cd $HT2CRACK3PATH; rm $HT2CRACK3NRAR && echo SUCCESS" "SUCCESS"; then break; fi
|
||||
|
||||
echo -e "\n${C_BLUE}Testing ht2crack4:${C_NC} ${HT2CRACK4PATH:=./tools/hitag2crack/crack4/}"
|
||||
if ! CheckFileExist "ht2crack4 exists" "$HT2CRACK4PATH/ht2crack4"; then break; fi
|
||||
HT2CRACK4UID=12345678
|
||||
HT2CRACK4KEY=AABBCCDDEEFF
|
||||
HT2CRACK4N=32
|
||||
HT2CRACK4NRAR=hitag2_${HT2CRACK4UID}_nrar_${HT2CRACK4N}emul.txt
|
||||
# The success is probabilistic: a fresh random nRaR file is required for each run
|
||||
# Order of magnitude to crack it: ~15s -> tagged as "slow"
|
||||
if ! CheckExecute slow retry ignore "ht2crack4 test" "cd $HT2CRACK4PATH; \
|
||||
python3 ../hitag2_gen_nRaR.py $HT2CRACK4KEY $HT2CRACK4UID $HT2CRACK4N > $HT2CRACK4NRAR; \
|
||||
./ht2crack4 -u $HT2CRACK4UID -n $HT2CRACK4NRAR -N 16 -t 500000 2>&1; \
|
||||
rm $HT2CRACK4NRAR" "key = $HT2CRACK4KEY"; then break; fi
|
||||
|
||||
echo -e "\n${C_BLUE}Testing ht2crack5:${C_NC} ${HT2CRACK5PATH:=./tools/hitag2crack/crack5/}"
|
||||
if ! CheckFileExist "ht2crack5 exists" "$HT2CRACK5PATH/ht2crack5"; then break; fi
|
||||
|
||||
echo -e "\n${C_BLUE}Testing ht2crack5gpu:${C_NC} ${HT2CRACK5GPUPATH:=./tools/hitag2crack/crack5gpu/}"
|
||||
if ! CheckFileExist "ht2crack5gpu exists" "$HT2CRACK5GPUPATH/ht2crack5gpu"; then break; fi
|
||||
HT2CRACK5GPUUID=12345678
|
||||
HT2CRACK5GPUKEY=AABBCCDDEEFF
|
||||
# The speed depends on the nRaR so we'll use two pairs known to work fast
|
||||
HT2CRACK5GPUNRAR="B438220C 944FFD74 942C59E3 3D450B34"
|
||||
# Order of magnitude to crack it: ~15s -> tagged as "slow"
|
||||
if ! CheckExecute slow gpu "ht2crack5gpu test" "cd $HT2CRACK5GPUPATH; ./ht2crack5gpu $HT2CRACK5GPUUID $HT2CRACK5GPUNRAR" "Key: $HT2CRACK5GPUKEY"; then break; fi
|
||||
fi
|
||||
if $TESTALL || $TESTCLIENT; then
|
||||
echo -e "\n${C_BLUE}Testing client:${C_NC} ${CLIENTBIN:=./client/proxmark3}"
|
||||
if ! CheckFileExist "proxmark3 exists" "$CLIENTBIN"; then break; fi
|
||||
|
@ -261,7 +341,7 @@ while true; do
|
|||
|
||||
echo -e "\n${C_BLUE}Testing HF:${C_NC}"
|
||||
if ! CheckExecute "hf mf offline text" "$CLIENTBIN -c 'hf mf'" "at_enc"; then break; fi
|
||||
if ! CheckExecute slow "hf mf hardnested long test" "$CLIENTBIN -c 'hf mf hardnested t 1 000000000000'" "found:" "repeat" "ignore"; then break; fi
|
||||
if ! CheckExecute slow retry ignore "hf mf hardnested long test" "$CLIENTBIN -c 'hf mf hardnested t 1 000000000000'" "found:"; then break; fi
|
||||
if ! CheckExecute slow "hf iclass long test" "$CLIENTBIN -c 'hf iclass loclass t l'" "verified ok"; then break; fi
|
||||
if ! CheckExecute slow "emv long test" "$CLIENTBIN -c 'emv test -l'" "Test(s) \[ OK"; then break; fi
|
||||
if ! $SLOWTESTS; then
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue