X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/e5baf1ef79f9e8faab9eb07b9afbfc4cd9c6c780..078e2bd238dfddb39c33de775f5e0a68657c4504:/client/cmdhfmfhard.c diff --git a/client/cmdhfmfhard.c b/client/cmdhfmfhard.c index 01dcc35d..96c3a989 100644 --- a/client/cmdhfmfhard.c +++ b/client/cmdhfmfhard.c @@ -28,10 +28,13 @@ #include "cmdmain.h" #include "ui.h" #include "util.h" +#include "util_posix.h" #include "crapto1/crapto1.h" #include "parity.h" #include "hardnested/hardnested_bruteforce.h" +#include "hardnested/hardnested_bf_core.h" #include "hardnested/hardnested_bitarray_core.h" +#include "zlib.h" #define NUM_CHECK_BITFLIPS_THREADS (num_CPUs()) #define NUM_REDUCTION_WORKING_THREADS (num_CPUs()) @@ -39,7 +42,7 @@ #define IGNORE_BITFLIP_THRESHOLD 0.99 // ignore bitflip arrays which have nearly only valid states #define STATE_FILES_DIRECTORY "hardnested/tables/" -#define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin" +#define STATE_FILE_TEMPLATE "bitflip_%d_%03" PRIx16 "_states.bin.z" #define DEBUG_KEY_ELIMINATION // #define DEBUG_REDUCTION @@ -69,22 +72,32 @@ static float brute_force_per_second; static void get_SIMD_instruction_set(char* instruction_set) { - #if (__GNUC__ >= 5) && (__GNUC__ > 5 || __GNUC_MINOR__ > 2) - if (__builtin_cpu_supports("avx512f")) strcpy(instruction_set, "AVX512F"); - else if (__builtin_cpu_supports("avx2")) strcpy(instruction_set, "AVX2"); - #else - if (__builtin_cpu_supports("avx2")) strcpy(instruction_set, "AVX2"); - #endif - else if (__builtin_cpu_supports("avx")) strcpy(instruction_set, "AVX"); - else if (__builtin_cpu_supports("sse2")) strcpy(instruction_set, "SSE2"); - else if (__builtin_cpu_supports("mmx")) strcpy(instruction_set, "MMX"); - else strcpy(instruction_set, "unsupported"); + switch(GetSIMDInstrAuto()) { + case SIMD_AVX512: + strcpy(instruction_set, "AVX512F"); + break; + case SIMD_AVX2: + strcpy(instruction_set, "AVX2"); + break; + case SIMD_AVX: + strcpy(instruction_set, "AVX"); + break; + case SIMD_SSE2: + strcpy(instruction_set, "SSE2"); + break; + case SIMD_MMX: + strcpy(instruction_set, "MMX"); + break; + default: + strcpy(instruction_set, "no"); + break; + } } static void print_progress_header(void) { char progress_text[80]; - char instr_set[12] = ""; + char instr_set[12] = {0}; get_SIMD_instruction_set(instr_set); sprintf(progress_text, "Start using %d threads and %s SIMD core", num_CPUs(), instr_set); PrintAndLog("\n\n"); @@ -236,14 +249,50 @@ static int compare_count_bitflip_bitarrays(const void *b1, const void *b2) } +static voidpf inflate_malloc(voidpf opaque, uInt items, uInt size) +{ + return malloc(items*size); +} + + +static void inflate_free(voidpf opaque, voidpf address) +{ + free(address); +} + +#define OUTPUT_BUFFER_LEN 80 +#define INPUT_BUFFER_LEN 80 + +//---------------------------------------------------------------------------- +// Initialize decompression of the respective (HF or LF) FPGA stream +//---------------------------------------------------------------------------- +static void init_inflate(z_streamp compressed_stream, uint8_t *input_buffer, uint32_t insize, uint8_t *output_buffer, uint32_t outsize) +{ + + // initialize z_stream structure for inflate: + compressed_stream->next_in = input_buffer; + compressed_stream->avail_in = insize; + compressed_stream->next_out = output_buffer; + compressed_stream->avail_out = outsize; + compressed_stream->zalloc = &inflate_malloc; + compressed_stream->zfree = &inflate_free; + + inflateInit2(compressed_stream, 0); + +} + + static void init_bitflip_bitarrays(void) { #if defined (DEBUG_REDUCTION) uint8_t line = 0; #endif + + z_stream compressed_stream; + char state_files_path[strlen(get_my_executable_directory()) + strlen(STATE_FILES_DIRECTORY) + strlen(STATE_FILE_TEMPLATE) + 1]; - char state_file_name[strlen(STATE_FILE_TEMPLATE)]; + char state_file_name[strlen(STATE_FILE_TEMPLATE)+1]; for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) { num_effective_bitflips[odd_even] = 0; @@ -258,22 +307,31 @@ static void init_bitflip_bitarrays(void) if (statesfile == NULL) { continue; } else { - uint32_t *bitset = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1<<19)); - if (bitset == NULL) { - printf("Out of memory error in init_bitflip_statelists(). Aborting...\n"); - fclose(statesfile); - exit(4); - } - size_t bytesread = fread(bitset, 1, sizeof(uint32_t) * (1<<19), statesfile); - if (bytesread != sizeof(uint32_t) * (1<<19)) { - printf("File read error with %s. Aborting...", state_file_name); + fseek(statesfile, 0, SEEK_END); + uint32_t filesize = (uint32_t)ftell(statesfile); + rewind(statesfile); + uint8_t input_buffer[filesize]; + size_t bytesread = fread(input_buffer, 1, filesize, statesfile); + if (bytesread != filesize) { + printf("File read error with %s. Aborting...\n", state_file_name); fclose(statesfile); - free_bitarray(bitset); + inflateEnd(&compressed_stream); exit(5); } fclose(statesfile); - uint32_t count = count_states(bitset); + uint32_t count = 0; + init_inflate(&compressed_stream, input_buffer, filesize, (uint8_t *)&count, sizeof(count)); + inflate(&compressed_stream, Z_SYNC_FLUSH); if ((float)count/(1<<24) < IGNORE_BITFLIP_THRESHOLD) { + uint32_t *bitset = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1<<19)); + if (bitset == NULL) { + printf("Out of memory error in init_bitflip_statelists(). Aborting...\n"); + inflateEnd(&compressed_stream); + exit(4); + } + compressed_stream.next_out = (uint8_t *)bitset; + compressed_stream.avail_out = sizeof(uint32_t) * (1<<19); + inflate(&compressed_stream, Z_SYNC_FLUSH); effective_bitflip[odd_even][num_effective_bitflips[odd_even]++] = bitflip; bitflip_bitarrays[odd_even][bitflip] = bitset; count_bitflip_bitarrays[odd_even][bitflip] = count; @@ -285,9 +343,8 @@ static void init_bitflip_bitarrays(void) line = 0; } #endif - } else { - free_bitarray(bitset); } + inflateEnd(&compressed_stream); } } effective_bitflip[odd_even][num_effective_bitflips[odd_even]] = 0x400; // EndOfList marker @@ -2477,6 +2534,10 @@ static void set_test_state(uint8_t byte) int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests) { char progress_text[80]; + + char instr_set[12] = {0}; + get_SIMD_instruction_set(instr_set); + PrintAndLog("Using %s SIMD core.", instr_set); srand((unsigned) time(NULL)); brute_force_per_second = brute_force_benchmark(); @@ -2545,6 +2606,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc best_first_bytes[0] = best_first_byte_smallest_bitarray; pre_XOR_nonces(); prepare_bf_test_nonces(nonces, best_first_bytes[0]); + hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0); key_found = brute_force(); free(candidates->states[ODD_STATE]); free(candidates->states[EVEN_STATE]); @@ -2564,6 +2626,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc // 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)); generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx); // 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); + hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0); key_found = brute_force(); free_statelist_cache(); free_candidates_memory(candidates); @@ -2604,6 +2667,12 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc if (nonce_file_read) { // use pre-acquired data from file nonces.bin if (read_nonce_file() != 0) { + free_bitflip_bitarrays(); + free_nonces_memory(); + free_bitarray(all_bitflips_bitarray[ODD_STATE]); + free_bitarray(all_bitflips_bitarray[EVEN_STATE]); + free_sum_bitarrays(); + free_part_sum_bitarrays(); return 3; } hardnested_stage = CHECK_1ST_BYTES | CHECK_2ND_BYTES; @@ -2613,6 +2682,12 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc } else { // acquire nonces. uint16_t is_OK = acquire_nonces(blockNo, keyType, key, trgBlockNo, trgKeyType, nonce_file_write, slow); if (is_OK != 0) { + free_bitflip_bitarrays(); + free_nonces_memory(); + free_bitarray(all_bitflips_bitarray[ODD_STATE]); + free_bitarray(all_bitflips_bitarray[EVEN_STATE]); + free_sum_bitarrays(); + free_part_sum_bitarrays(); return is_OK; } } @@ -2642,10 +2717,11 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc for (statelist_t *sl = candidates; sl != NULL; sl = sl->next) { maximum_states += (uint64_t)sl->len[ODD_STATE] * sl->len[EVEN_STATE]; } - printf("Number of remaining possible keys: %" PRIu64 " (2^%1.1f)\n", maximum_states, log(maximum_states)/log(2.0)); + // printf("Number of remaining possible keys: %" PRIu64 " (2^%1.1f)\n", maximum_states, log(maximum_states)/log(2.0)); best_first_bytes[0] = best_first_byte_smallest_bitarray; pre_XOR_nonces(); prepare_bf_test_nonces(nonces, best_first_bytes[0]); + hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0); key_found = brute_force(); free(candidates->states[ODD_STATE]); free(candidates->states[EVEN_STATE]); @@ -2665,6 +2741,7 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc // 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)); generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx); // 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); + hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0); key_found = brute_force(); free_statelist_cache(); free_candidates_memory(candidates);