Skip to content

Commit 7f9e4c2

Browse files
committed
hardnested: reduce disk space for tables (by > 700MBytes) and other minor changes
- compress tables - minor changes to progress reporting - free memory on aborts (@iceman1001)
1 parent 6100040 commit 7f9e4c2

File tree

708 files changed

+246
-682583
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

708 files changed

+246
-682583
lines changed

.gitattributes

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
# prevent binary files from CRLF handling, diff and merge:
33
fpga/fpga.bit -crlf -diff
44
*.bin -crlf -diff
5+
*.z -crlf -diff

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@
1212
*.map
1313
*.bin
1414
!client/hardnested/*.bin
15-
!client/hardnested/tables/*.bin
1615
*.dll
1716
*.moc.cpp
1817
*.z
18+
!client/hardnested/tables/*.z
1919
usb_cmd.lua
2020
version.c
2121
client/ui/ui_overlays.h

client/Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -209,8 +209,8 @@ all-static: LDLIBS:=-static $(LDLIBS)
209209
all-static: proxmark3 flasher fpga_compress
210210
211211
proxmark3: LDLIBS+=$(LUALIB) $(QTLDLIBS)
212-
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) lualibs/usb_cmd.lua
213-
$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(LDLIBS) -o $@
212+
proxmark3: $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) lualibs/usb_cmd.lua
213+
$(LD) $(LDFLAGS) $(OBJDIR)/proxmark3.o $(COREOBJS) $(CMDOBJS) $(QTGUIOBJS) $(MULTIARCHOBJS) $(ZLIBOBJS) $(LDLIBS) -o $@
214214
215215
flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(COREOBJS)
216216
$(LD) $(LDFLAGS) $^ $(LDLIBS) -o $@

client/cmdhfmfhard.c

+76-15
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,15 @@
3333
#include "parity.h"
3434
#include "hardnested/hardnested_bruteforce.h"
3535
#include "hardnested/hardnested_bitarray_core.h"
36+
#include "zlib.h"
3637

3738
#define NUM_CHECK_BITFLIPS_THREADS (num_CPUs())
3839
#define NUM_REDUCTION_WORKING_THREADS (num_CPUs())
3940

4041
#define IGNORE_BITFLIP_THRESHOLD 0.99 // ignore bitflip arrays which have nearly only valid states
4142

4243
#define STATE_FILES_DIRECTORY "hardnested/tables/"
43-
#define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin"
44+
#define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin.z"
4445

4546
#define DEBUG_KEY_ELIMINATION
4647
// #define DEBUG_REDUCTION
@@ -240,12 +241,48 @@ static int compare_count_bitflip_bitarrays(const void *b1, const void *b2)
240241
}
241242

242243

244+
static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size)
245+
{
246+
return malloc(items*size);
247+
}
248+
249+
250+
static void inflate_free(voidpf opaque, voidpf address)
251+
{
252+
free(address);
253+
}
254+
255+
#define OUTPUT_BUFFER_LEN 80
256+
#define INPUT_BUFFER_LEN 80
257+
258+
//----------------------------------------------------------------------------
259+
// Initialize decompression of the respective (HF or LF) FPGA stream
260+
//----------------------------------------------------------------------------
261+
static void init_inflate(z_streamp compressed_stream, uint8_t *input_buffer, uint32_t insize, uint8_t *output_buffer, uint32_t outsize)
262+
{
263+
264+
// initialize z_stream structure for inflate:
265+
compressed_stream->next_in = input_buffer;
266+
compressed_stream->avail_in = insize;
267+
compressed_stream->next_out = output_buffer;
268+
compressed_stream->avail_out = outsize;
269+
compressed_stream->zalloc = &inflate_malloc;
270+
compressed_stream->zfree = &inflate_free;
271+
272+
inflateInit2(compressed_stream, 0);
273+
274+
}
275+
276+
243277
static void init_bitflip_bitarrays(void)
244278
{
245279
#if defined (DEBUG_REDUCTION)
246280
uint8_t line = 0;
247281
#endif
248282

283+
284+
z_stream compressed_stream;
285+
249286
char state_files_path[strlen(get_my_executable_directory()) + strlen(STATE_FILES_DIRECTORY) + strlen(STATE_FILE_TEMPLATE) + 1];
250287
char state_file_name[strlen(STATE_FILE_TEMPLATE)+1];
251288

@@ -262,22 +299,31 @@ static void init_bitflip_bitarrays(void)
262299
if (statesfile == NULL) {
263300
continue;
264301
} else {
265-
uint32_t *bitset = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1<<19));
266-
if (bitset == NULL) {
267-
printf("Out of memory error in init_bitflip_statelists(). Aborting...\n");
268-
fclose(statesfile);
269-
exit(4);
270-
}
271-
size_t bytesread = fread(bitset, 1, sizeof(uint32_t) * (1<<19), statesfile);
272-
if (bytesread != sizeof(uint32_t) * (1<<19)) {
273-
printf("File read error with %s. Aborting...", state_file_name);
302+
fseek(statesfile, 0, SEEK_END);
303+
uint32_t filesize = (uint32_t)ftell(statesfile);
304+
rewind(statesfile);
305+
uint8_t input_buffer[filesize];
306+
size_t bytesread = fread(input_buffer, 1, filesize, statesfile);
307+
if (bytesread != filesize) {
308+
printf("File read error with %s. Aborting...\n", state_file_name);
274309
fclose(statesfile);
275-
free_bitarray(bitset);
310+
inflateEnd(&compressed_stream);
276311
exit(5);
277312
}
278313
fclose(statesfile);
279-
uint32_t count = count_states(bitset);
314+
uint32_t count = 0;
315+
init_inflate(&compressed_stream, input_buffer, filesize, (uint8_t *)&count, sizeof(count));
316+
inflate(&compressed_stream, Z_SYNC_FLUSH);
280317
if ((float)count/(1<<24) < IGNORE_BITFLIP_THRESHOLD) {
318+
uint32_t *bitset = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1<<19));
319+
if (bitset == NULL) {
320+
printf("Out of memory error in init_bitflip_statelists(). Aborting...\n");
321+
inflateEnd(&compressed_stream);
322+
exit(4);
323+
}
324+
compressed_stream.next_out = (uint8_t *)bitset;
325+
compressed_stream.avail_out = sizeof(uint32_t) * (1<<19);
326+
inflate(&compressed_stream, Z_SYNC_FLUSH);
281327
effective_bitflip[odd_even][num_effective_bitflips[odd_even]++] = bitflip;
282328
bitflip_bitarrays[odd_even][bitflip] = bitset;
283329
count_bitflip_bitarrays[odd_even][bitflip] = count;
@@ -289,9 +335,8 @@ static void init_bitflip_bitarrays(void)
289335
line = 0;
290336
}
291337
#endif
292-
} else {
293-
free_bitarray(bitset);
294338
}
339+
inflateEnd(&compressed_stream);
295340
}
296341
}
297342
effective_bitflip[odd_even][num_effective_bitflips[odd_even]] = 0x400; // EndOfList marker
@@ -2549,6 +2594,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
25492594
best_first_bytes[0] = best_first_byte_smallest_bitarray;
25502595
pre_XOR_nonces();
25512596
prepare_bf_test_nonces(nonces, best_first_bytes[0]);
2597+
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0);
25522598
key_found = brute_force();
25532599
free(candidates->states[ODD_STATE]);
25542600
free(candidates->states[EVEN_STATE]);
@@ -2568,6 +2614,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
25682614
// printf("Estimated remaining states: %" PRIu64 " (2^%1.1f)\n", nonces[best_first_bytes[0]].sum_a8_guess[j].num_states, log(nonces[best_first_bytes[0]].sum_a8_guess[j].num_states)/log(2.0));
25692615
generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx);
25702616
// printf("Time for generating key candidates list: %1.0f sec (%1.1f sec CPU)\n", difftime(time(NULL), start_time), (float)(msclock() - start_clock)/1000.0);
2617+
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0);
25712618
key_found = brute_force();
25722619
free_statelist_cache();
25732620
free_candidates_memory(candidates);
@@ -2608,6 +2655,12 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
26082655

26092656
if (nonce_file_read) { // use pre-acquired data from file nonces.bin
26102657
if (read_nonce_file() != 0) {
2658+
free_bitflip_bitarrays();
2659+
free_nonces_memory();
2660+
free_bitarray(all_bitflips_bitarray[ODD_STATE]);
2661+
free_bitarray(all_bitflips_bitarray[EVEN_STATE]);
2662+
free_sum_bitarrays();
2663+
free_part_sum_bitarrays();
26112664
return 3;
26122665
}
26132666
hardnested_stage = CHECK_1ST_BYTES | CHECK_2ND_BYTES;
@@ -2617,6 +2670,12 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
26172670
} else { // acquire nonces.
26182671
uint16_t is_OK = acquire_nonces(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_write, slow);
26192672
if (is_OK != 0) {
2673+
free_bitflip_bitarrays();
2674+
free_nonces_memory();
2675+
free_bitarray(all_bitflips_bitarray[ODD_STATE]);
2676+
free_bitarray(all_bitflips_bitarray[EVEN_STATE]);
2677+
free_sum_bitarrays();
2678+
free_part_sum_bitarrays();
26202679
return is_OK;
26212680
}
26222681
}
@@ -2646,10 +2705,11 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
26462705
for (statelist_t *sl = candidates; sl != NULL; sl = sl->next) {
26472706
maximum_states += (uint64_t)sl->len[ODD_STATE] * sl->len[EVEN_STATE];
26482707
}
2649-
printf("Number of remaining possible keys: %" PRIu64 " (2^%1.1f)\n", maximum_states, log(maximum_states)/log(2.0));
2708+
// printf("Number of remaining possible keys: %" PRIu64 " (2^%1.1f)\n", maximum_states, log(maximum_states)/log(2.0));
26502709
best_first_bytes[0] = best_first_byte_smallest_bitarray;
26512710
pre_XOR_nonces();
26522711
prepare_bf_test_nonces(nonces, best_first_bytes[0]);
2712+
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0);
26532713
key_found = brute_force();
26542714
free(candidates->states[ODD_STATE]);
26552715
free(candidates->states[EVEN_STATE]);
@@ -2669,6 +2729,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
26692729
// printf("Estimated remaining states: %" PRIu64 " (2^%1.1f)\n", nonces[best_first_bytes[0]].sum_a8_guess[j].num_states, log(nonces[best_first_bytes[0]].sum_a8_guess[j].num_states)/log(2.0));
26702730
generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx);
26712731
// printf("Time for generating key candidates list: %1.0f sec (%1.1f sec CPU)\n", difftime(time(NULL), start_time), (float)(msclock() - start_clock)/1000.0);
2732+
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0);
26722733
key_found = brute_force();
26732734
free_statelist_cache();
26742735
free_candidates_memory(candidates);

client/fpga_compress.c

+34-11
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,17 @@
3838
#define COMPRESS_MAX_CHAIN 8192
3939

4040
#define FPGA_INTERLEAVE_SIZE 288 // (the FPGA's internal config frame size is 288 bits. Interleaving with 288 bytes should give best compression)
41-
#define FPGA_CONFIG_SIZE 42336 // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE
41+
#define FPGA_CONFIG_SIZE 42336L // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE
42+
#define HARDNESTED_TABLE_SIZE (sizeof(uint32_t) * ((1L<<19)+1))
4243

4344
static void usage(void)
4445
{
4546
fprintf(stderr, "Usage: fpga_compress <infile1> <infile2> ... <infile_n> <outfile>\n");
4647
fprintf(stderr, " Combine n FPGA bitstream files and compress them into one.\n\n");
4748
fprintf(stderr, " fpga_compress -d <infile> <outfile>");
4849
fprintf(stderr, " Decompress <infile>. Write result to <outfile>");
50+
fprintf(stderr, " fpga_compress -t <infile> <outfile>");
51+
fprintf(stderr, " Compress hardnested table <infile>. Write result to <outfile>");
4952
}
5053

5154

@@ -73,22 +76,29 @@ static bool all_feof(FILE *infile[], uint8_t num_infiles)
7376
}
7477

7578

76-
int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile)
79+
int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, bool hardnested_mode)
7780
{
7881
uint8_t *fpga_config;
7982
uint32_t i;
8083
int32_t ret;
8184
uint8_t c;
8285
z_stream compressed_fpga_stream;
8386

84-
fpga_config = malloc(num_infiles * FPGA_CONFIG_SIZE);
85-
87+
if (hardnested_mode) {
88+
fpga_config = malloc(num_infiles * HARDNESTED_TABLE_SIZE);
89+
} else {
90+
fpga_config = malloc(num_infiles * FPGA_CONFIG_SIZE);
91+
}
8692
// read the input files. Interleave them into fpga_config[]
8793
i = 0;
8894
do {
8995

90-
if (i >= num_infiles * FPGA_CONFIG_SIZE) {
91-
fprintf(stderr, "Input files too big (total > %u bytes). These are probably not PM3 FPGA config files.\n", num_infiles*FPGA_CONFIG_SIZE);
96+
if (i >= num_infiles * (hardnested_mode?HARDNESTED_TABLE_SIZE:FPGA_CONFIG_SIZE)) {
97+
if (hardnested_mode) {
98+
fprintf(stderr, "Input file too big (> %lu bytes). This is probably not a hardnested bitflip state table.\n", HARDNESTED_TABLE_SIZE);
99+
} else {
100+
fprintf(stderr, "Input files too big (total > %lu bytes). These are probably not PM3 FPGA config files.\n", num_infiles*FPGA_CONFIG_SIZE);
101+
}
92102
for(uint16_t j = 0; j < num_infiles; j++) {
93103
fclose(infile[j]);
94104
}
@@ -253,6 +263,7 @@ int main(int argc, char **argv)
253263
}
254264

255265
if (!strcmp(argv[1], "-d")) { // Decompress
266+
256267
infiles = calloc(1, sizeof(FILE*));
257268
if (argc != 4) {
258269
usage();
@@ -272,11 +283,23 @@ int main(int argc, char **argv)
272283

273284
} else { // Compress
274285

275-
infiles = calloc(argc-2, sizeof(FILE*));
276-
for (uint16_t i = 0; i < argc-2; i++) {
277-
infiles[i] = fopen(argv[i+1], "rb");
286+
bool hardnested_mode = false;
287+
int num_input_files = 0;
288+
if (!strcmp(argv[1], "-t")) { // hardnested table
289+
if (argc != 4) {
290+
usage();
291+
return(EXIT_FAILURE);
292+
}
293+
hardnested_mode = true;
294+
num_input_files = 1;
295+
} else {
296+
num_input_files = argc-2;
297+
}
298+
infiles = calloc(num_input_files, sizeof(FILE*));
299+
for (uint16_t i = 0; i < num_input_files; i++) {
300+
infiles[i] = fopen(argv[i+hardnested_mode?2:1], "rb");
278301
if (infiles[i] == NULL) {
279-
fprintf(stderr, "Error. Cannot open input file %s", argv[i+1]);
302+
fprintf(stderr, "Error. Cannot open input file %s", argv[i+hardnested_mode?2:1]);
280303
return(EXIT_FAILURE);
281304
}
282305
}
@@ -285,6 +308,6 @@ int main(int argc, char **argv)
285308
fprintf(stderr, "Error. Cannot open output file %s", argv[argc-1]);
286309
return(EXIT_FAILURE);
287310
}
288-
return zlib_compress(infiles, argc-2, outfile);
311+
return zlib_compress(infiles, num_input_files, outfile, hardnested_mode);
289312
}
290313
}

client/hardnested/hardnested_tables.c

+6-5
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,12 @@ static inline uint32_t count_states(uint32_t *bitset)
176176
}
177177

178178

179-
static void write_bitflips_file(odd_even_t odd_even, uint16_t bitflip, int sum_a0, uint32_t *bitset)
179+
static void write_bitflips_file(odd_even_t odd_even, uint16_t bitflip, int sum_a0, uint32_t *bitset, uint32_t count)
180180
{
181181
char filename[80];
182182
sprintf(filename, "bitflip_%d_%03" PRIx16 "_sum%d_states.bin", odd_even, bitflip, sum_a0);
183183
FILE *outfile = fopen(filename, "wb");
184+
fwrite(&count, 1, sizeof(count), outfile);
184185
fwrite(bitset, 1, sizeof(uint32_t)*(1<<19), outfile);
185186
fclose(outfile);
186187
}
@@ -369,7 +370,7 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
369370
bitflip, (1<<24) - count[odd_even],
370371
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
371372
#ifndef TEST_RUN
372-
write_bitflips_file(odd_even, bitflip, sum_a0, test_bitarray[odd_even]);
373+
write_bitflips_file(odd_even, bitflip, sum_a0, test_bitarray[odd_even], count[odd_even]);
373374
#endif
374375
} else {
375376
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip);
@@ -396,7 +397,7 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
396397
bitflip | BITFLIP_2ND_BYTE, (1<<24) - count[odd_even],
397398
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
398399
#ifndef TEST_RUN
399-
write_bitflips_file(odd_even, bitflip | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd);
400+
write_bitflips_file(odd_even, bitflip | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd, count[odd_even]);
400401
#endif
401402
} else {
402403
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip | BITFLIP_2ND_BYTE);
@@ -481,7 +482,7 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
481482
bitflip|0x100, (1<<24) - count[odd_even],
482483
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
483484
#ifndef TEST_RUN
484-
write_bitflips_file(odd_even, bitflip|0x100, sum_a0, test_not_bitarray[odd_even]);
485+
write_bitflips_file(odd_even, bitflip|0x100, sum_a0, test_not_bitarray[odd_even], count[odd_even]);
485486
#endif
486487
} else {
487488
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip|0x100);
@@ -508,7 +509,7 @@ static void precalculate_bit0_bitflip_bitarrays(uint8_t const bitflip, uint16_t
508509
bitflip | 0x100| BITFLIP_2ND_BYTE, (1<<24) - count[odd_even],
509510
(float)((1<<24) - count[odd_even]) / (1<<24) * 100.0);
510511
#ifndef TEST_RUN
511-
write_bitflips_file(odd_even, bitflip | 0x100 | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd);
512+
write_bitflips_file(odd_even, bitflip | 0x100 | BITFLIP_2ND_BYTE, sum_a0, test_bitarray_2nd, count[odd_even]);
512513
#endif
513514
} else {
514515
printf("All %s states for bitflip property %03x are possible. No file written.\n", odd_even==EVEN_STATE?"even":"odd", bitflip | 0x100 | BITFLIP_2ND_BYTE);

client/hardnested/tables/bitflip_0_001_states.bin

-1
This file was deleted.
Binary file not shown.

client/hardnested/tables/bitflip_0_003_states.bin

-1
This file was deleted.
Binary file not shown.

client/hardnested/tables/bitflip_0_005_states.bin

-1
This file was deleted.
Binary file not shown.

client/hardnested/tables/bitflip_0_007_states.bin

-1
This file was deleted.
Binary file not shown.

client/hardnested/tables/bitflip_0_009_states.bin

-1
This file was deleted.
Binary file not shown.

client/hardnested/tables/bitflip_0_00b_states.bin

-1
This file was deleted.
Binary file not shown.

client/hardnested/tables/bitflip_0_00d_states.bin

-1
This file was deleted.
Binary file not shown.

client/hardnested/tables/bitflip_0_00f_states.bin

-1
This file was deleted.
Binary file not shown.
Binary file not shown.
Binary file not shown.

client/hardnested/tables/bitflip_0_014_states.bin

-1
This file was deleted.
Binary file not shown.

client/hardnested/tables/bitflip_0_01c_states.bin

-1
This file was deleted.
Binary file not shown.

client/hardnested/tables/bitflip_0_021_states.bin

-1
This file was deleted.
Binary file not shown.

client/hardnested/tables/bitflip_0_023_states.bin

-1
This file was deleted.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)